# /task

> Create well-scoped ClickUp tasks for the ACME Agency team.


# /task — ClickUp task creator for ACME Agency

## Purpose

Every task created by ACME Agency should contain everything the assignee needs to start work — **no pinging colleagues, no Slack archaeology, no Drive hunting**. If information is known, it goes into the task. If information is missing, the task names what's missing and who to ask, and the gap is flagged explicitly rather than hidden.

This skill enforces that standard across three input modes and four role templates, and writes the task(s) directly to ClickUp.

## When to trigger

- `/task ...` invocation
- User says: "create a task for X", "napravi task za X", "make a ClickUp task", "add a task", "open a ticket for Y"
- User pastes a Fathom meeting summary or action-item list and asks to turn it into tasks
- User pastes a Fathom onboarding-call summary and says "onboard this client" / "set up the new client tasks"

Do **not** trigger for:
- "Add me a todo" for personal work (not a team task)
- Generic reminders that don't need to live in ClickUp

### Fathom summaries only — never raw transcripts

Work **only** from Fathom's AI summary + action items. Never ask for, process, or read a raw transcript. Fathom's summaries are already tight, role-tagged, and structured — that's all the signal we need. If a raw transcript is pasted, pull only the "Summary" / "Action items" sections and ignore the rest. Do not say "full transcript" in user-facing replies or in task bodies.

## Input modes

### Mode A — Single brief
User describes one task in free text.
Example: *"Task for a teammate, launch new Meta leads campaign for ACME Agency, 50€/day, 25-55 male, lokacija Hrvatska, briefing u Drive-u."*

Extract: assignee, client, platform, budget, audience, deadline (if mentioned). Fill in the role-matched template, flag any missing blocks.

### Mode B — Meeting summary / action-item list
User pastes a Fathom-style summary (or bullet list) with multiple action items.

**Approval gate — Mode B never writes tasks directly.** Flow:

1. Parse action items. For each line that reads like an action item, detect whom it belongs to (role keywords: "campaign"/"ads"/"budget" → a teammate; "copy"/"headline"/"landing page text" → a teammate; "design"/"visual"/"cut" → a teammate; "schedule"/"kickoff"/"unblock" → a teammate; fallback = a teammate).
2. Build a structured proposal — one entry per task, with assignee, proposed title, 1-line brief, client (if detected), deadline (if detected).
3. **Post the proposal to `#your-channel`** (resolved via `<id>()` in `scripts/lib/meeting_proposals.mjs`) as a single parent message titled `Proposed tasks — <meeting title or source URL>`. List every proposed task with its index number so approvers can reference them (`1.`, `2.`, …). Pin the source link at the top.
4. Persist the structured proposal to `ACME Agency/tmp/task-proposals/<thread_ts>.json` via `saveProposal()`. This is the state file — it holds the exact task specs that will be submitted on approval.
5. **Stop. Do not create any ClickUp tasks.** Reply to the user with the proposal message URL and tell them: "Awaiting approval in #your-channel."

### Mode C — Onboarding-call Fathom summary
Same approval gate as Mode B. Flow:

1. Extract basic client info (vertical, market, target audience, budget, offer, pain points) from the Fathom summary.
2. Load the onboarding process library at `process-library/onboarding.md`.
3. For each task in the library, fill in what the summary gave you; leave explicit `TBD — ask client` placeholders where info is missing.
4. Build the same structured proposal (one entry per task).
5. **Post to `#your-channel`** with the title `Proposed onboarding tasks — <ClientName>`.
6. Persist to `ACME Agency/tmp/task-proposals/<thread_ts>.json`.
7. Stop. Reply with the proposal URL. No ClickUp writes yet.

### Approval / edit cycle (applies to Mode B & C)

The proposal lives in `#your-channel` until someone replies in its thread. The Slack bridge forwards thread replies to Claude, which acts based on intent:

- **Approval** — reply contains one of: `approved`, `ok`, `odobreno`, `odobravam`, `idemo`, `create`, `potvrđujem`, `✅`, thumbs-up reaction on the parent message. On approval:
  1. Load the JSON from `tmp/task-proposals/<thread_ts>.json`.
  2. For each task entry, call `task_create.mjs --from-proposal <thread_ts> --index <n>` (or do the equivalent inline: the script supports both).
  3. Post a single threaded reply in `#your-channel`: `Created N tasks:` followed by task URLs, one per line.
  4. Mark the proposal `status: "approved"` in the JSON and stop reading it.

- **Edit request** — reply that is not approval. Examples: "izmijeni task 2, budget 30€/day", "change task 4 to a teammate instead of a teammate", "drop task 3", "add a task for a teammate to run /meta-ads-analyze on ACME Agency".
  1. Load the JSON.
  2. Apply the edit in-memory (modify/drop/add task entries).
  3. **Re-post the revised proposal** as a new threaded reply — do not edit the original parent message. Post a short note naming the change ("Revidiran prijedlog — task 2 updated").
  4. Save the modified JSON back to disk (same `thread_ts`).
  5. Wait for approval on the revised version. The most recent revision in the thread is the one that gets created on approval.

- **Cancellation** — reply contains `cancel`, `otkaži`, `skip`. Mark `status: "cancelled"`, post a confirmation in thread, stop.

The approver is not formally restricted to one person — any team member (Faris, a teammate, a teammate, a teammate, a teammate) can approve. The team-convention is that a teammate or Faris approves onboarding proposals; media-buying task proposals can be approved by a teammate. This is social, not enforced in code.

**Why the gate exists:** Fathom summaries produce long proposal lists (5–15 tasks). Creating all of them directly in ClickUp without a human ACME Agencyw step means bad extractions go straight into a teammate/a teammate/a teammate's inboxes. The `#your-channel` channel becomes the ACME Agencyw layer. Mode A (single brief) does not gate — the user already typed exactly what they want.

## Flow

1. **Parse arguments** — detect input mode, extract any explicit flags.
2. **Load team registry** — read `ACME Agency/team.json`. Resolve assignee via `alias_index` (name) or `role_index` (role keyword). If ambiguous, ask the user via `AskUserQuestion`.
3. **Load client context** (if a client is mentioned) via the 3-step cascade from `ACME Agency/CLAUDE.md`:
   - `clients/clients.json` first
   - Google Sheet registry (`readClientRegistry`) if missing
   - API discovery only as last resort (rarely needed at task-creation time — if we can't find the client, say so and ask)
4. **Load the role template** for the assignee from `templates/<role>.md`. Role is derived from `team.json → core[assignee].role`.
5. **Fill the template**:
   - Substitute every `{{placeholder}}` from known context (client, Drive link, ad account, budget, etc.)
   - Where context is missing, replace with `TBD — <what to do next>` (e.g. `TBD — confirm with Faris`, `TBD — a teammate to set`)
   - Never leave an empty `{{placeholder}}` — every block is either filled or explicitly flagged.
6. **Create the task in ClickUp** via `createTask()` in `ACME Agency/scripts/lib/clickup.mjs`:
   - `name` — short, imperative, format: `[Client] — [Action]` (e.g. `ACME Agency — Launch Meta Leads Campaign #3`)
   - `markdown_description` — the filled template (ClickUp v2 supports markdown via `markdown_content` field; use that)
   - `assignees` — `[clickup_id]` from team registry
   - `due_date` — epoch ms if known, else omit
   - `time_estimate` — epoch ms (1h30m etc.) if a default is defined for the template
   - `tags` — `['auto-created']` + the role short name (e.g. `media-buyer`)
   - `priority` — default `3` (normal), bump to `2` (high) if the brief contains words like "urgent", "hitno", "ASAP", or a tight deadline
7. **Add checklists** (if the template has checklist blocks) via `addChecklist()` + `addChecklistItem()` loops.
8. **Post a Slack confirmation** to the client's Slack channel (if a client was resolved) OR to the #your-channel fallback — short, one-line, with the task URL. Format: `New task for <Assignee>: <Task Name> → <url>`. No emojis, single-asterisk bold (per `SLACK_REPORT_STANDARD.md`).
9. **Report back to the user** with task URL(s) and a bullet list of anything marked `TBD`.

## Quality gate (before calling `createTask`)

Every task, before it's submitted, must pass this check:

- [ ] Assignee has everything they need to start work without asking follow-up questions, OR every missing item is explicitly flagged with `TBD` and a named person to ask
- [ ] Drive link is included (task-specific folder, not Drive root) when the task involves assets
- [ ] Client name + vertical + market are in the task body (so the assignee has instant context)
- [ ] Deadline is set OR explicitly marked `TBD — a teammate to schedule`
- [ ] Task name is imperative and under 60 characters
- [ ] Description is no longer than ~400 words. If longer, split into checklist items or link out to a brief doc.

If a task fails the gate, fix it before submitting. Do not submit tasks with empty placeholders.

## Role templates

Templates live in `.claude/skills/task/templates/`:

- `media-buyer.md` — for a teammate (Meta, Google, tracking, campaign ops)
- `copywriter.md` — for a teammate (copy, scripts, landing page text)
- `designer.md` — for a teammate (visuals, cuts, creative production)
- `manager.md` — for a teammate (coordination, unblocking, client chase-ups)

When a task doesn't match any of these cleanly (e.g. a strategic decision task for Faris), use the `manager.md` template as the scaffold — it's the most general.

## Process library

`.claude/skills/task/process-library/` contains predefined task trees for recurring workflows:

- `onboarding.md` — full new-client kickoff (used by Mode C)
- (more to be added as processes stabilize — monthly ACME Agencyw, campaign launch, client offboarding, etc.)

To add a new process: create `<process-name>.md` in `process-library/` with a numbered list of tasks. Each task block follows the same shape (role, title, template fields). The skill will read these on demand.

## ClickUp list selection

The task needs a home list. Selection order:

1. If `--list LIST_ID` flag is passed → use it.
2. If a client is resolved AND `clients.json` has `clickup_list_id` → use it.
3. Otherwise → use the ACME Agency "Team Tasks" or "Operations" list. If unknown, ask the user once via `AskUserQuestion` and cache the answer by printing a reminder at the end: *"Add `default_list_id` to `ACME Agency/team.json._meta` to skip this question next time."*

## Non-goals

- This skill does **not** create recurring tasks via the API. ClickUp's v2 API doesn't expose recurrence cleanly — if the user wants a recurring task, create it once, then print instructions for the user to enable native recurrence in the ClickUp UI (see the Daily Paid Ads ACME Agencyw task for precedent).
- This skill does **not** mark tasks complete, change status, or edit existing tasks. Those are manual in ClickUp or happen via the existing `clickup_executor.mjs` flow.
- This skill does **not** write copy, generate images, or launch ads. It only creates the task that asks a team member to do one of those things.

## Executor script

`ACME Agency/scripts/task_create.mjs` is the CLI entry point. It takes the same arguments as the skill and implements the flow above. Claude reads this SKILL.md for behavior, but the deterministic ClickUp/Slack calls happen in the script.

Usage examples:

```
node ACME Agency/scripts/task_create.mjs \
  --brief "Launch new Meta leads campaign for ACME Agency, 50€/day, Hrvatska 25-55 M" \
  --assignee a teammate \
  --client "ACME Agency" \
  --deadline 2026-04-18

node ACME Agency/scripts/task_create.mjs \
  --meeting ACME Agency/tmp/fathom_ACME Agency_2026-04-14.md

node ACME Agency/scripts/task_create.mjs \
  --onboarding ACME Agency/tmp/kickoff_new-client.md \
  --client "New Client Name"
```