agentleFS
stylusnexusstylusnexus/work-plan-toolkit/skills/work-plan/SKILL.md

work-plan

Skill1 starsChanged 5 months agoMITView on GitHub

Use when starting or ending a work session across many GitHub issues, switching between parallel agent sessions on different workstreams, re-orienting on what to do next, sweeping for stale tracking state, or bootstrapping a new repo into a daily-planning system.

  • Commits and pushes

6 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use research.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • NVIDIASkill

    research

    Before designing a feature, research how comparable libraries solve the problem, check best practices, known pitfalls, and upstream changes. Use when starting a new feature, investigating an unfamiliar area, or the user asks to research something.

    Also in 3 projects that use this

The file

We split this skill into the rules it gives an agent

8 rules. 0 are common, 4 are distinctive, and 4 are very specific to this project.

  • 0

    Common

    Most of the 6 edited versions we read keep these.

  • 4

    Distinctive

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    All subcommands route through the Python CLI.

    line 45
  2. Distinctive:

    Run via Bash. Don't reimplement the logic in chat.

    line 56
  3. Distinctive:

    Read the output (open issues, last session log, priority, milestone).

    line 68
  4. Distinctive:

    All three follow the same pattern:

    line 77
  5. Distinctive:

    You: read the issues, output the requested JSON, save via Write tool to the path the CLI printed.

    line 80
  6. Very specific:

    Routing logic (automatic): if a repo has a registered local: path that is a valid git repo, new tracks go into .work-plan/ by default.

    line 101
  7. Very specific:

    When zero commits attribute to the track but the repo has activity in the same window, the handoff renders a soft signal (0 attributed / N …

    line 154
  8. Very specific:

    Run ./install.sh (macOS / Linux / WSL) or .\install.ps1 (Windows) from the toolkit root.

    line 158

“Common” is measured: kept by at least 6 in 10 of the 6 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Work Plan

Track-aware daily planner. Each "track" is a YAML-frontmattered markdown file that references GitHub issues by ID; the CLI derives state live from gh/git. Composes with /repo-activity-summary for the global multi-repo view.

Subcommand reference

SubcommandWhen
/work-plan briefStarting work or after a gap. Multi-track snapshot.
/work-plan handoff [track] [--auto-next | --set-next 1,2,3]Wrapping up a work block. Captures touched + next + blockers; writes session log. Add --auto-next to suggest a priority-sorted next_up list from open issues (interactive: apply / edit / skip). Tracks with next_up_auto: true in frontmatter get the auto-derived list surfaced in brief automatically.
/work-plan orient [track] (alias where-was-i)Re-orienting. With a track: ~15-line track paste-block. Without: cwd snapshot (branch, recent commits, modified files) for non-track work. Add --pick for the interactive track picker.
/work-plan hygiene [--repo=<key>]Weekly all-in-one cleanup. Five steps in sequence: ① refresh-md --all — pull live GitHub state into every active track's status table (same as "Sync Issue States from GitHub" but for all tracks); ② reconcile --all — sync track frontmatter membership against GitHub labels; ③ dedupe-tiers — report private track copies that a shared twin supersedes (report-only); ④ milestone-drift — report next_up entries that are already closed, ranked above a later-milestone issue, or ranked with no milestone (report-only); ⑤ duplicates — flag likely-duplicate issues for consolidation. Run once a week to keep status icons, labels, and dedup state honest. --repo=<key> scopes steps ①–④ to one repo; step ⑤ is skipped in scoped mode (it needs a single explicit repo to be unambiguous).
/work-plan doctor [--json] [--fix]Config drifted — a renamed local folder or GitHub repo, config.yml no longer matches. Run right after any rename/move. --fix corrects the safe subset and re-scans. Also runs a read-only preflight of the machine (Python 3.9+, git, gh + sign-in, mikefarah/yq, config, notes_root, plan-branch worktrees); text mode exits 0 healthy / 1 warning / 2 blocking.
/work-plan slot <issue-num> [track]A new GitHub issue should belong to a track. If the issue is already listed in another active track's frontmatter, you'll be prompted to move it (remove from source) instead of duplicating.
/work-plan close [track]Track is done (shipped) / paused (parked) / won't ship (abandoned).
/work-plan mark-cleanup <track> [--reason=<text>] [--clear]Earmark a track for cleanup — a reversible cleanup_candidate flag hygiene surfaces. Triggers: "mark this track for cleanup / retirement". Non-destructive.
/work-plan archive-track <track> / unarchive-track <track>Set a track aside reversibly into archive/parked/ (out of active views, kept), or restore it. Distinct from close (terminal). Triggers: "archive / park / set aside this track", "bring back that archived track".
/work-plan delete-track <track>DESTRUCTIVE — remove a track's .md. Never touches GitHub issues (they outlive the track). Private: undoable notes-vcs commit; shared: staged git rm. Triggers: "delete / remove this track for good". Prefer archive-track if reversible is fine.
/work-plan refresh-md <track> | --all | --repo=<key>Pull live GitHub state into a track's status table. Run this after closing or merging issues — it re-fetches each issue's open/closed state from GitHub and rewrites the status cells in the track body, which refreshes the dependency graph and next_up display. --all sweeps every active track; --repo=<key> scopes to one repo. In VS Code: right-click a track → Sync Issue States from GitHub.
/work-plan list [--all]List active tracks (or all including parked/archived).
/work-plan init <path>Add frontmatter to a new track .md file.
/work-plan init-repo <key> [--github=<slug>] [--local=<path>]Bootstrap a new repo: create <notes_root>/<key>/archive/{shipped,abandoned}/ and add the repo block to your config.
/work-plan suggest-priorities --repo=<key>Two-step AI label backfill (one-time migration).
/work-plan group [--milestone=X] [--label=Y] [--repo=Z]Two-step AI clustering: turn a flat list of issues into thematic track files. Powerful for a new milestone or repo re-org — fetches issues, prints a clustering prompt, you save the JSON answer, then --apply creates the track files.
/work-plan auto-triage [--repo=<key>]Two-step AI assignment: assign untracked open issues to existing tracks. Use after coverage shows a gap. Prints a prompt listing untracked issues + active tracks; save AI's JSON answer; re-run with --apply.
/work-plan coverage [--repo=<key>] [--list]Report how many open issues are not in any track (per repo), split into issues already labelled for an active track (fix: reconcile --all) and genuinely unassigned ones. --list shows titles. Read-only. Run before auto-triage or group to measure the gap.
/work-plan reconcile <track> | --all [--draft]Sync track frontmatter with GitHub labels (read-only on GitHub). Matches track/<slug> always, plus any labels in github.labels (extra labels add to the default, never replace it). Add --draft to preview proposed ADDs/FLAGs without prompting or writing.
/work-plan duplicates [--min-similarity=0.7]Find likely-duplicate issues by title similarity (stdlib difflib).
/work-plan plan-status [--repo=<key>] [--stamp [--draft]] [--type=plan|spec]Doc/plan liveness. "Which of my plan/spec docs actually shipped, half-shipped, or died?" Correlates each plan's declared file-manifest (Create/Modify/Test paths) against git + filesystem — not the unreliable checkboxes. Reports ✅ shipped / 🟡 partial / 💀 dead / 👻 manifest-less. Read-only by default; --stamp writes an idempotent status header into each doc (--draft previews, writes nothing). Natural-language triggers: "what's done vs unfinished in <repo>", "stamp the plan statuses", "which plans are stale/dead".
/work-plan plan-confirm --repo=<key> --verdict=shipped|partial|dead [--clear] -- <rel>Affirm a human verdict on one plan doc by writing verdict_override into its frontmatter only (never body/checkboxes/manifest). plan-status then pins that verdict and silences the "shipped but boxes unchecked" lie-gap. Use when a genuinely-shipped plan is flagged red only because nobody ticked its phase checkboxes — confirm it instead of hand-ticking boxes. Public-repo gated (prints needs_confirm + token; re-run with --confirm=<token>). Natural-language triggers: "that plan really did ship, stop flagging it", "mark <plan> as shipped/dead".
/work-plan plan-archive --repo=<key> [--draft] -- <rel>Archive a shipped plan. Moves a doc whose effective verdict is shipped into archive/shipped/ — a staged git mv for a tracked doc (commit & push to share), or a plain filesystem move for a gitignored/untracked one (#399). Refuses non-shipped; skips collisions. Natural-language triggers: "archive this finished plan", "file away the shipped plans". Bulk: plan-status --archive-shipped.
/work-plan plan-unarchive --repo=<key> -- <rel>Restore an archived plan back to the live set — the inverse of plan-archive (#388). Moves a doc out of archive/<kind>/; refuses a collision with a live doc. Triggers: "un-archive / restore this plan", "I archived that plan by mistake". In VS Code: right-click a doc in the 📦 Archived folder → Restore to Live.
/work-plan plan-ack --repo=<key> [--clear] -- <rel>Durably acknowledge one plan doc by writing acknowledged: true into its frontmatter only — a "stop flagging this" that's committed + shared (vs the viewer's per-machine ack). plan-status reads it back and demotes the doc. Public-repo gated. Natural-language triggers: "stop flagging this plan for everyone", "acknowledge <plan> for good".
/work-plan plan-baseline --repo=<key> [--clear] -- <rel>Stamp a drift baseline on one plan doc by writing its current computed verdict to verdict_baseline in frontmatter only. plan-status then flags drift when the live verdict diverges — catching a once-shipped plan that silently regressed (files deleted/moved). Distinct from plan-confirm (human pin); an override suppresses drift. Public-repo gated. Natural-language triggers: "watch this plan for regressions", "alert me if <plan> stops being shipped".

How to invoke

All subcommands route through the Python CLI. Prefer the work-plan launcher (on PATH as a plugin, and installed by install.sh): work-plan <subcommand>. It resolves work_plan.py relative to itself, then via ${CLAUDE_PLUGIN_ROOT} / ${PLUGIN_ROOT} / ~/.claude / ~/.agents. If the launcher isn't on PATH, call the CLI directly, first match wins:

  1. ${CLAUDE_PLUGIN_ROOT}/skills/work-plan/work_plan.py (Claude plugin; Codex sets this too)
  2. ${PLUGIN_ROOT}/skills/work-plan/work_plan.py (Codex plugin)
  3. ~/.claude/skills/work-plan/work_plan.py (install.sh → Claude Code)
  4. ~/.agents/skills/work-plan/work_plan.py (install.sh → Codex)

Run via Bash. Don't reimplement the logic in chat.

Verbatim relay (orientation subcommands)

For brief, handoff, orient (where-was-i), and hygiene, the Python output IS the deliverable. After running the Bash command, reproduce the full Python output verbatim in a fenced code block in your chat reply. Don't summarize, paraphrase, or truncate — users copy-paste from chat into other terminals/sessions, so any rewording loses information.

plan-status is also verbatim-relay, with one exception: its report can run to hundreds of docs. If the output is large, relay the headline line (counts + lie-gap) and the actionable 🟡 partial bucket verbatim, then offer the full report rather than flooding the chat. The --stamp/--draft summary line (stamped N doc(s) / would stamp N doc(s)) is always relayed verbatim.

Handoff: Claude-driven next_up

After running handoff:

  1. Read the output (open issues, last session log, priority, milestone).
  2. Survey the user's project memory (e.g., a MEMORY.md index in their working directory or ~/.claude/projects/.../memory/) for related signals — deploy gates, blocked items, in-flight clusters.
  3. Pick a "next" — single ticket OR tight cluster (2-4 issues) — based on track priority, milestone, what's gating other work, what cluster naturally goes together.
  4. Justify the pick in chat (1-2 sentences).
  5. Persist via python3 <skill-path>/work_plan.py handoff <track> --set-next <comma-list> (e.g. --set-next 4167,4148,4149).
  6. Show the user what was set so they can override.

Two-step AI subcommands (suggest-priorities, group, auto-triage)

All three follow the same pattern:

  1. CLI fetches issues + writes prompt to terminal (saved to ~/.claude/work-plan/cache/).
  2. You read the issues, output the requested JSON, save via Write tool to the path the CLI printed.
  3. Re-run with --apply to commit changes.

Show the proposed labels/clusters/assignments BEFORE applying. The user may want to override.

auto-triage answers — write atomically and copy the batch_id. The VS Code viewer watches the answers file and reads suggestions live (#241), so a half-written file would be read mid-write. Write to a .tmp sibling and then rename it onto the final auto_triage.<repo>.answers.json path the CLI printed (the Write tool's create-then-replace is fine; never append). Use the v2 answers shape — {"version": 2, "batch_id": "<copy from the scan output>", "suggestions": [...]} — and copy the batch_id the scan printed so the viewer can tell fresh suggestions from a stale older scan. Prefer "verdict": "abstain" for issues with no clear home: most untracked issues genuinely have none, and a wrong suggestion a human rubber-stamps is worse than silence.

Which one to use:

  • group — issues need to be clustered into new track files (run once per milestone or after a re-org)
  • auto-triage — untracked issues need to be assigned to existing tracks (run after coverage shows a gap)
  • suggest-priorities — issues need priority/PN labels backfilled (one-time migration)

Two-tier track storage (shared vs private)

Track files live in one of two places:

TierPathWho sees it
Shared<local-clone>/.work-plan/<slug>.mdEveryone with repo access (committed + pushed)
Private<notes_root>/<folder>/<slug>.mdLocal only (never committed)

Routing logic (automatic): if a repo has a registered local: path that is a valid git repo, new tracks go into .work-plan/ by default. Pass --private to group or new-track to route to notes_root instead; every other command rejects the flag with exit 2.

Local history for the private tier (opt-in): the shared tier already gets version control from its repo. For the private tier, /work-plan notes-vcs init git-inits notes_root as a personal, never-pushed repo and turns on auto-commit — every track-mutating command then writes an undoable commit to notes_root. notes-vcs status reports the state; enable/disable toggle it. Off until you run it.

Setup shared tracks for a repo:

/work-plan init-repo myproject --github=org/myproject --local=/path/to/clone

Syncing shared tracks: git pull pulls teammates' track changes; git add .work-plan/ && git commit && git push shares your own. The CLI never auto-pushes.

Disambiguation when the same track slug exists in two repos:

/work-plan slot 4234 auth-flow@myproject   # @repo qualifier
/work-plan close auth-flow --repo=myproject  # --repo=<key> flag

Both forms work on: slot, close, handoff, canonicalize, refresh-md, reconcile, set.

Track ↔ GitHub label mapping

By default, reconcile and the brief new-issue suggester look for the label track/<slug> on GitHub issues. If your repo uses a different scheme (flat labels like storytelling, namespaced labels like area/maps, or no track/* namespace at all), declare the labels per-track in the markdown frontmatter:

---
track: storytelling-enhancements
status: active
github:
  repo: your-org/your-repo
  labels: [storytelling, campaigns]   # OR semantics — issue matches if ANY label is present;
                                       # `track/storytelling-enhancements` always matches too
  issues: [4296, 4290, ...]
---

This is read-only on GitHub: the skill never adds, removes, or rewrites labels on the remote — it only reads them to know which issues belong to a track. The only writes are to your local markdown frontmatter, gated behind interactive confirmation. If github.labels is omitted, the default track/<slug> pattern is used (existing setups keep working unchanged).

Track ↔ commit attribution

handoff shows commits attributed to a track since the last handoff. Attribution rules (in order):

  1. Explicit branches — if frontmatter has github.branches: [feature/x, ...], only commits on those branches count. Path globs do not apply.
  2. Issue mention OR path glob — otherwise, scan all branches and keep commits whose message (subject OR body) mentions an issue in github.issues, OR whose changed paths match any glob in github.paths (fnmatch syntax — *, ?, **, [seq]). Scanning the body matters for squash-merged PRs whose subjects follow Conventional Commits (e.g. feat(scope): description) and carry the issue ref in the body (Closes #1234).
github:
  repo: your-org/your-repo
  issues: [4148, 4149, ...]
  paths:
    - "apps/web/src/components/ux/**"
    - "**/useToast*"

When zero commits attribute to the track but the repo has activity in the same window, the handoff renders a soft signal (0 attributed / N repo-wide since last handoff) so the silence isn't mistaken for "nothing happened."

Setup

Run ./install.sh (macOS / Linux / WSL) or .\install.ps1 (Windows) from the toolkit root. Then /work-plan init-repo <key> --github=<org/repo> to bootstrap your first repo. See the toolkit README for full setup, requirements, and platform-specific install commands.

Common mistakes

MistakeFix
Calling gh directly to check issue statebrief / orient already do it, with track context.
Editing track frontmatter manuallyPrefer handoff or slot — they update timestamps and dedupe.
Forgetting to label issues with priority/PNbrief sorts by priority; without labels everything looks the same.
Setting local: in config to a path that doesn't existIn-progress detection silently no-ops. Verify path.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.