Skip to content
Agentmart
Submit a tool

add-task

Add a new task to any of your local projects.

Skill by tbeack

IndexedMIT★ 8
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/tbeack-add-task

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Add a new task to any of your local projects. Auto-detects the current project from the working directory and conforms to that project's conventions — prefix, numbering, todo-file layout, task-file template. Reads conventions from `${CLAUDE_PLUGIN_ROOT}/skills/add-task/add-task-projects.yaml`. Use when the user wants to add a task, capture a TODO, or track a new idea in a local project.

Use cases: productivity

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/add-task

What's inside

Skill name
add-task
Description
Add a new task to any of your local projects. Auto-detects the current project from the working directory and conforms to that project's conventions — prefix, numbering, todo-file layout, task-file template. Reads conventions from `${CLAUDE_PLUGIN_ROOT}/skills/add-task/add-task-projects.yaml`. Use when the user wants to add a task, capture a TODO, or track a new idea in a local project.
License
MIT
Instructions
231 lines in SKILL.md · view on GitHub

Agent Skills spec issues

  • name: missing

Files (2)

  • SKILL.md
  • add-task-projects.yaml

SKILL.md (first lines)

# fsad-harness:add-task — multi-project task adder

You add a new task entry (and, where the project warrants it, a per-task detail file) in whichever local project the user is currently working in. Project-specific conventions are defined in `${CLAUDE_PLUGIN_ROOT}/skills/add-task/add-task-projects.yaml` — always read that file before doing anything else.

`$ARGUMENTS` (if present) is the brief task title.

**What "done" means for a task-creation run:**
- The new task ID is unique in the todo file — verified with a re-grep, not assumed from arithmetic alone.
- The new bullet matches the formatting of its sibling entries (`cfg.todo_entry_template`, or the file's actual format if it has drifted from the cfg).
- Every acceptance criterion in the generated task-detail file (when one is created) is falsifiable — a future reader can check it against the codebase and get a clear pass/fail, not a vague judgment call.

The steps below exist to satisfy these criteria, not just to move mechanically from prefix to written bullet.

## Asking the user

This rule covers every question this skill asks the user: a confirmation, a choice, a missing value, a numbered decision list, or a stop-and-ask. It applies even where a later step says "ask the user" or "ask exactly once". The user may watch the decisions pane rather than the chat, so a question that only goes to chat can go unanswered.

- **When `mcp__decision-tracker__decision` is in your tool list** (loaded, or named as a deferred tool; load a deferred one with `ToolSearch` first), log each question before you ask it:
  1. Call it with `action: "open"`, the question (ending in `?`), and `options` when the answers are a closed set. Set `required: false` when the work can go on without an answer. A numbered list of questions opens one decision per item. Keep each returned `id`.
  2. Ask the question in chat as this skill says. The open call does not replace the chat question.
  3. When the user answers, in chat or as a `Decision Dn: <answer>` message from the plugin, call the tool with `action: "close"`, the `id` and the answer.
  4. When the change the answer asked for is in place, call it with `action: "implement"`, the `id` and a `path:line`.
- **When the tool is absent**, ask in chat only.
- An `AskUserQuestion` call is logged on its own. Do not open it again.
- This rule changes where a question is logged. It does not change when this skill asks, or how many times.

## Step 0 — Detect the project

1. Determine the current working directory.
2. Read `${CLAUDE_PLUGIN_ROOT}/skills/add-task/add-task-projects.yaml`.
3. Match cwd against each project's `match_paths` (expand `~`). The cwd may be a descendant of a match path. If multiple match, prefer the longest (most specific) match.
4. If a project matches, refer to its entry as `cfg` and proceed.
5. If **no** project matches in `add-task-projects.yaml`:
   - Tell the user the project is not registered.
   - Show the values you'd use from the `default` block.
   - Ask whether to (a) proceed using the defaults this once, (b) register the project now, or (c) abort.
   - If (b), collect the following fields one at a time, showing the suggested default for each:
     - `name` — project key in the YAML (e.g. `my_project`)
     - `match_paths` — root path (default: current working directory)
     - `prefix` — task identifier prefix (e.g. `MYP`)
     - `number_digits` — zero-pad width (default: `3`)
     - `todo_file` — relative path to the todo file (default: `planning/to do/todo.md`)
     - `task_dir` — relative path to the task detail directory (default: `planning/to do`)
     - `use_full_template` — whether to create per-task detail files (default: `true`)
     - `version_scheme` — versioning convention: `semver`, `integer`, `calver`, or `none` (default: `semver`)
     - `version_files` — file(s) that carry the version string (default: `README.md`; user may specify `package.json` or others)
   - Write all collected fields as a new entry under `projects:` in the YAML before continuing.

## Step 0.4 — Skill routing

Resolve which skill should actually handle this task-creation run for `cfg`'s project:

1. `desired_skill` = `cfg.skills.add_task` (if set) → else the YAML's top-level `defaults.skills.add_task` (if set) → else `"fsad-harness:add-task"`.
2. If `desired_skill` differs from `"fsad-harness:add-task"`: invoke the `Skill` tool with that skill name, passing `$ARGUMENTS` unchanged, and **stop** — none of this skill's remaining steps run in this invocation.
3. Otherwise continue to Step 1.

## Step 1 — Compute the next number

**Success criteria for this step:** the computed `ID` must be numerically correct (the highest existing number for `{prefix}` in the todo file, plus one) regardless of whether `{prefix}` itself contains a hyphen (e.g. `KHB-Todo`), and must be verified as unique in the todo file — not merely assumed — before it is ever written. Uniqueness is protected two ways: **mutual exclusion** (Step 1.0's lock — only one `add-task` invocation can be computing/writing an ID at a time) and **detection** (Step 1.6's pre-write check and Step 3's post-write re-grep, which catch stale arithmetic if the lock is ever bypassed or a lock file is manually removed).

### Step 1.0 — Acquire the allocation lock

Before touching the todo file, acquire an exclusive lock so two concurrent `add-task` invocations (two CLI sessions, an autonomous agent running alongside an interactive one, etc.) can never compute the same `ID` at once — this closes the race that Step 1.6/Step 3's checks can only detect after the fact.

1. Lock path: `{lock_dir} = "{dirname(todo_file_path)}/.add-task.lock"` — the lock lives next to the project's `todo_file`, so it's naturally scoped per-project; two different projects' `add-task` runs never contend for the same lock.
2. Attempt `mkdir "{lock_dir}"` and check the exit code. `mkdir` is atomic on POSIX filesystems — if the directory already exists, the command fails, so exactly one concurrent caller can ever succeed.
   - **Exit 0 (acquired)** — continue to Step 1.1.
   - **Nonzero (lock already held)**:
     a. Check the lock directory's age: `find "{lock_dir}" -maxdepth 0 -mmin +1`.
        - **Non-empty output (older than 60s, stale)** — a prior run crashed or was killed before releasing its lock. Remove it (`rmdir "{lock_dir}"`) and retry `mkdir` once. If that retry also fails, treat the lock as fresh and fall through to (b).
        - **Empty output (60s or newer, fresh)** — another `add-task` invocation is genuinely in progress; go to (b).
     b. **Fresh lock — poll and retry.** Wait ~2s, retry `mkdir`, up to 5 attempts (~10s total). If still unacquired after 5 attempts, stop and tell the user another `add-task` run appears to be in progress; ask whether to keep waiting (repeat the poll) or abort. **Do not `rmdir` the lock on this abort path** — this invocation never acquired it, so it isn't this invocation's to release; the directory the retries were failing against belongs to whichever session is still holding it. Do not proceed to Step 1.1 without the lock.
3. **Release discipline.** The lock must be released on *every* exit path where **this invocation held it** — never left held by this invocation when control leaves Steps 1–3, whether by success or by a stop-and-ask. The specific release points are called out inline at each exit below: the happy-path release after Step 3's post-write re-grep, and a release immediately before the two stop-and-asks that can only be reached after this invocation has the lock (Step 1.6's second collision, Step 3's retry-fails). The poll-timeout abort above is the one exit path with nothing to release, precisely because the lock was never acquired.

### Step 1.1 — Find every existing ID

Do **not** read the full todo file. Use targeted Bash commands instead:

```bash
grep -oE '{prefix}-[0-9]+' "{todo_file_path}"
```
Substitute the literal prefix (e.g. `CBP`, `TBS`, `KHB-Todo`, `FSD_Train`) for `{prefix}` and the resolved absolute path for `{todo_file_path}`. Quote the path to handle spaces. If the output is empty, no tasks exist yet — start at 1 and skip to Step 1.3.

### Step 1.2 — Parse the numeric suffix yourself — do not pipe through `sort`

`sort -t- -k2 -n | tail -1` assumes the number always lands in field 2 when splitting on `-`. That assumption breaks the moment the prefix itself contains a hyphen: for `KHB-Todo-0010`, splitting on `-` gives fields `KHB` / `Todo` / `0010`, so field 2 is the literal string `"Todo"` on every matched line — `sort -n` can't numerically order a constant string, and `tail -1` just returns whichever line happens to sort last (effectively grep/file order), not the actual highest number. Instead, for each line grep returned, split on the **last** `-` (not a fixed field position) to isolate the trailing digits regardless of how many hyphens the prefix contains, parse each as an integer, and take the max. This is you reasoning over the grep output directly — not another shell pipeline.

### Step 1.3 — Clean up empty placeholder entries

```bash
grep -nE '^- \[ \] `{prefix}-[0-9]+`\s*$' "{todo_file_path}"
```
If any lines are returned, remove each with `Edit` using the exact line text as `old_string`. If the only entry removed was the last real line, treat the file as empty and start numbering from 1.

### Step 1.4 — Increment

Increment the highest-seen number by 1; zero-pad to `cfg.number_digits` digits → `nnn`.

### Step 1.5 — Build the ID

- `ID = "{prefix}-{nnn}"` (e.g. `CBP-031`, `KHB-Todo-0010`, `FSD_Train-012`).
- `prefix_lower` = `cfg.prefix_in_filename` if set, otherwise the prefix lowercased.
- `slug` (only if the filename template uses it) = title lowercased, non-alphanumerics → `_`, collapsed runs of `_`, trimmed.

### Step 1.6 — Pre-write uniqueness check

Before `ID` is used anywhere else, derive a format-agnostic match string from `cfg.todo_entry_template` rather than assuming a backtick wrapper. The template varies per project — most backtick-wrap the ID (`` `{ID}` ``), but e.g. `KHB`'s bolds it instead (`**{ID}**`) — and a hardcoded backtick produces a false "0 hits" (spurious retry, or a silently-skipped uniqueness check) on every run for any project whose format differs. Take the substring of `cfg.todo_entry_template` from its start through the delimiter(s) that immediately close `{ID}` (e.g. `` - [ ] `{ID}` `` for a backtick template, `- [ ] **{ID}**` for a bold template), substitute `{ID}` with the literal `ID`, and grep for that exact literal string:
```bash
grep -cF "{id_pattern}" "{todo_file_path}"
```
- **0 hits** — `ID` is confirmed unique; continue to Step 2.
- **≥1 hit** — a collision (stale arithmetic, or the lock was bypassed). Increment `nnn` by 1, rebuild `ID`, and re-run the check exactly once more.
- **Second collision** — release the lock (`rmdir "{lock_dir}"`), then stop and ask the user how to proceed. Do not keep incrementing and guessing.

## Step 2 — Get the title

If `$ARGUMENTS` is non-empty, use it. Otherwise ask:
> What's the task title? (one-liner — I'll prompt for details next.)

From tbeack/fsad_playbook, MIT.

More from tbeack/fsad_playbook

Signals

Stars
8
Forks
4
Open issues
0
Last commit (this folder)
Oct 7, 2026 (21 days ago)
Last release
May 18, 2026 (5 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from tbeack

Cite this page

add-task skill. Agent Mart. https://agentmart.dev/skills/tbeack-add-task (last updated 2026-10-24)