Best for
- Use when logging cross-session follow-ups, confirming a project slug, or mirroring a GitHub issue.
laurigates/claude-plugins/taskwarrior-plugin/skills/task-add/SKILL.md
File a taskwarrior task with a verified project slug and blueprint/GitHub linkage. Use when logging cross-session follow-ups, confirming a project slug, or mirroring a GitHub issue.
Decision brief
File a coordination task. When a GitHub remote is present, offer optional linkage so GitHub stays the system of record and taskwarrior stays the parallel-safe query layer.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/laurigates/claude-plugins --skill "taskwarrior-plugin/skills/task-add"Inspect the Agent Skill "task-add" from https://github.com/laurigates/claude-plugins/blob/c056e44b978db58648ad20440dc1515cb09af09d/taskwarrior-plugin/skills/task-add/SKILL.md at commit c056e44b978db58648ad20440dc1515cb09af09d. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
The canonical 10-UDA set (5 linkage: bpid / bpdoc / bpms / ghid / ghpr; 5 identity: agent / pid / host / branch / worktree) lives in one place — the shared ensure-udas.sh script. Check for missing UDAs:
GitHub mode is active when all of:
If bpid: was given, run parallel-safe and constrain to the resolved project so a matching bpid in another repo's queue is not surfaced as a false-positive duplicate:
When GitHub mode is active and either ghid: is set or the description looks like an issue reference:
Compose the taskwarrior add command from the collected inputs. Always include project: (the resolved project from Parameters) unless the user passed --no-project. Quote every field; tags use the +tag form:
Permission review
The documentation asks the agent to run terminal commands or scripts.
bash "${CLAUDE_SKILL_DIR}/../../scripts/ensure-udas.sh" --checkThe documentation asks the agent to run terminal commands or scripts.
bash "${CLAUDE_SKILL_DIR}/../../scripts/ensure-udas.sh"Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 93/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 54 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
File a coordination task. When a GitHub remote is present, offer optional linkage so GitHub stays the system of record and taskwarrior stays the parallel-safe query layer.
| Use this skill when... | Use task-status / task-coordinate / task-done instead when... |
|---|---|
Filing a brand-new coordination task with bpid: / bpdoc: linkage | Auditing existing queue health — use task-status |
Mirroring a GitHub issue into the local queue via ghid: | Picking the next-N candidates for a parallel wave — use task-coordinate |
Pre-filling a task body from gh issue view output | Closing an in-flight task and draining its tracker — use task-done |
task --versionfind . -maxdepth 1 -name '.git' -print -quitgh auth statustask _udastask _projectsGit probes (git rev-parse --show-toplevel, git remote) write to stderr
in a no-git cwd, and stderr from a Context backtick aborts the skill
before its body runs. Project / remote resolution is done in the body
(Step 2 below), where 2>/dev/null and exit-code handling are available.
Parse $ARGUMENTS:
project:<name> to override the auto-detected project.--no-project to file the task without any project (cross-cutting work).bpid:WO-012 / bpdoc:docs/wo/012.md / bpms:M6 / ghid:145 / ghpr:99 fields.+blocked* bookkeeping):
due:<date> — deadline. Feeds urgency and surfaces the task as +DUE / +OVERDUE in task-coordinate / task-status. Set it only for real deadlines — the queue is a queue, not a calendar.scheduled:<date> — earliest start. The task only becomes +READY once this date passes, so future work stays out of dispatch candidates.wait:<date> — hide the task entirely until the date. Use for "blocked on merge until X" instead of a hand-managed +blocked_on_merge tag — taskwarrior auto-unhides it.recur:<freq> (e.g. weekly, monthly) with a due: — repeating maintenance chores. Requires due:.until:<date> — auto-delete the task on that date. Use for short-lived trackers that should expire if not actioned.today, eow, eom, monday, due-4d, ISO 2026-07-01).+wo, +prp, +fr, +re, +gh, +pr_ready, +needs_review, +blocked_on_merge, +blocked.Tag naming gotcha — hyphens silently break tags. Taskwarrior parses
-mid-token as exclude-filter syntax, even inside a+tagargument.+blocked-on-mergeis parsed as+blockedAND-on-merge, so the tag never lands and the literal+blocked-on-mergestring ends up appended to the description as plain text (urgency does not tick up). Single- quoting ('+blocked-on-merge') does not help — this is a taskwarrior parser quirk, not a shell issue. Use underscores or camelCase instead:+blocked_on_mergeor+blockedOnMerge. The same applies to any tag name containing a hyphen.
By default every task is filed under the current repo's project so
/taskwarrior:task-status and /taskwarrior:task-coordinate only see
tasks relevant to where the agent is working. Resolve the project in
this order:
project:<name> in $ARGUMENTS.--no-project → file with no project (rare; cross-cutting work).git rev-parse --show-toplevel 2>/dev/null, run via the
Bash tool (where stderr suppression and non-zero exits are tolerated).Cross-check the resolved name against Known projects and reuse the
exact spelling when it matches (case-insensitive) — taskwarrior treats
MyRepo and myrepo as different projects.
project: is a PREFIX match — a populated result does not prove the slugtask project:comfyui list returns every task in comfyui-nodes,
comfyui-touch-connect, and any other project starting with that string.
Nothing in the output says so. A slug you just invented therefore looks
verified the moment a sibling shares its prefix, which is the whole trap:
the confirming evidence and a false positive are byte-identical.
Observed twice (2026-08-08, comfyui-nodes). A commit titled "point the backlog at
project:comfyui, the slug that exists" moved the documented slug to the one project that was nearly empty — 60 tasks sat undercomfyui-nodes, 1 undercomfyui— becausetask project:comfyui listshowed all 60. A later session read that doc, filed four follow-ups into the near-empty sibling, and only caught it when a survey script printed the per-project counts side by side.
To check a slug is real, read the exact value — never a filter that matches its own prefix:
task export | jq -r '[.[].project] | group_by(.) | map({p:.[0], n:length}) | sort_by(-.n)[]'
Corollaries: prefer task <uuid> modify project:<slug> when consolidating
(numeric ids shift); and a new project slug is silently created on first
add, so a typo never errors — it just starts a parallel backlog that the
prefix match then hides.
Execute this workflow:
The canonical 10-UDA set (5 linkage: bpid / bpdoc / bpms / ghid /
ghpr; 5 identity: agent / pid / host / branch / worktree) lives in
one place — the shared ensure-udas.sh script. Check for missing UDAs:
bash "${CLAUDE_SKILL_DIR}/../../scripts/ensure-udas.sh" --check
If it reports UDAS_MISSING greater than 0, confirm with the user (declarations
persist in ~/.taskrc), then install them on first run per host:
bash "${CLAUDE_SKILL_DIR}/../../scripts/ensure-udas.sh"
Identity UDAs are not set by task-add itself — /taskwarrior:task-claim
stamps them when an agent picks the task up. The same script backs the
SessionStart drift-probe, so the install logic is single-sourced.
If task errors with "Cannot proceed without rc file":
mkdir -p ~/.local/share/task
echo "data.location=~/.local/share/task" > ~/.taskrc
GitHub mode is active when all of:
git config --get remote.origin.url is non-emptygh auth status exits 0If either fails, skip GitHub-related branches in later steps.
If bpid: was given, run parallel-safe and constrain to the resolved
project so a matching bpid in another repo's queue is not surfaced as
a false-positive duplicate:
task project:myrepo bpid:"$BPID" export | jq '.[] | {id, description, status}'
Never use task bpid:"$BPID" list — it exits 1 on empty result and cancels sibling tool calls in parallel batches (see .claude/rules/parallel-safe-queries.md).
If a matching open task exists, report the ID and ask whether to update instead of re-add.
When GitHub mode is active and either ghid: is set or the description looks like an issue reference:
gh issue view "$GHID" --json number,title,body,labels,state
Offer to copy title into description, map labels to tags, and capture the issue number into the ghid UDA.
If the user wants a new issue created, use:
gh issue create --title "$TITLE" --body "$BODY"
…then capture the returned issue number into ghid. Skip this branch entirely in local-only mode.
Compose the taskwarrior add command from the collected inputs. Always
include project: (the resolved project from Parameters) unless the
user passed --no-project. Quote every field; tags use the +tag form:
task add "$DESCRIPTION" \
project:myrepo \
bpid:"$BPID" \
bpdoc:"$BPDOC" \
bpms:"$BPMS" \
ghid:"$GHID" \
ghpr:"$GHPR" \
due:"$DUE" \
scheduled:"$SCHEDULED" \
wait:"$WAIT" \
+wo +gh
Run with only the fields that were provided; omit empty UDAs and empty date
fields entirely rather than passing uda:"" / due:"". For a recurring chore,
pass recur:weekly due:monday (recurrence requires a due:); for a
self-expiring tracker, add until:eom.
After task add succeeds, resolve the new task's UUID via the
+LATEST virtual tag as a separate Bash call — never chain it to
task add with &&:
task +LATEST uuids
# d14a6e5e-1c60-4cfd-9dd0-8a9fe7659b74
Use
task +LATEST uuids(ortask +LATEST export | jq -r '.[0].uuid'), nottask +LATEST _get uuid._getis a DOM accessor that takes an<id>.<attribute>reference (task _get 141.uuid); given a tag filter it silently returns empty (exit 0), capturing no UUID — which silently reverted the #1417 drift fix until corrected.
Numeric IDs shift; UUIDs do not. A numeric ID is a display index over pending tasks — completing any other task (often in a parallel session) shifts every higher ID down by one, so
task 141 annotate ...run minutes after the add can silently hit a different task. Capture the immutable UUID at create time and address the task by UUID for later annotate / modify / done. See.claude/rules/task-id-stability.md.
depends: for ordered chainsFor work orders that must land in sequence (e.g., WO-058 → 059 → 060),
set depends: on each downstream task pointing to its predecessor's
taskwarrior numeric ID. When the predecessor closes with task done,
taskwarrior automatically unblocks all dependents — no manual
intervention needed (see docs/task-tracking.md § Lifecycle):
# WO-059 waits for WO-058 (taskwarrior ID 51)
task add "WO-059: ..." bpid:WO-059 +wo project:myrepo depends:51
# WO-060 waits for both
task add "WO-060: ..." bpid:WO-060 +wo project:myrepo depends:51,52
Print:
--no-project)/taskwarrior:task-status, /taskwarrior:task-coordinate, or /taskwarrior:task-claim if the user is about to start)| Context | Command |
|---|---|
| Capture stable UUID after add | task +LATEST uuids |
| Duplicate check by bpid | task bpid:WO-012 export | jq '.[] | {id, status}' |
| Pre-fill from issue | gh issue view 145 --json number,title,body,labels |
| Next ready (unblocked + scheduled-due) | task status:pending +READY export | jq '.[:3]' |
| Skip empty filter exit | Always use export | jq, never list |
| Flag / field | Purpose |
|---|---|
project: | Project (defaults to repo basename) |
--no-project | File without a project (cross-cutting) |
bpid: | Blueprint ID link |
bpdoc: | Blueprint doc path |
bpms: | Milestone |
ghid: | GitHub issue number |
ghpr: | GitHub PR number |
due: | Deadline — feeds urgency, surfaces +DUE/+OVERDUE |
scheduled: | Earliest start — gates +READY |
wait: | Hide until date (auto-unhides) — prefer over +blocked_on_merge |
recur: | Repeat frequency (needs due:) |
until: | Auto-delete date |
+wo | Work order |
+prp | PRP |
+fr | Feature request |
+re | Research |
+gh | Linked to GitHub |
+pr_ready | Open PR waiting |
+blocked_on_merge | Waiting on another PR |
/taskwarrior:task-status — see current queue/taskwarrior:task-claim — claim a task and stamp identity UDAs/taskwarrior:task-done — close an open task (fires auto-unblock for depends: chains)/taskwarrior:task-coordinate — next-agent candidates for a wave.claude/rules/parallel-safe-queries.md — why export | jq, never list.claude/rules/task-id-stability.md — why the captured UUID must be used for later annotate/modify/doneblueprint-plugin:feature-tracking — FR/WO IDs that bpid points attaskwarrior-plugin/docs/task-tracking.md — full lifecycle including depends: + auto-unblock patternFrequently asked questions
File a coordination task. When a GitHub remote is present, offer optional linkage so GitHub stays the system of record and taskwarrior stays the parallel-safe query layer.
The source record exposes this install command: npx skills add https://github.com/laurigates/claude-plugins --skill "taskwarrior-plugin/skills/task-add". Inspect the command and pinned source before running it.
Static rules flagged exec-script in the source; the page lists the matching lines and excerpts.