Problem Statement
When developing or updating a skill, the skill-writer agent needs to run isolated subagents to observe failures and verify compliance. Today there is no scripted way to do this — the agent must manually manage git worktrees, session continuity, and output capture, which is error-prone and not reproducible.
Solution
A skill-writer zsh script with three subcommands (test, ask, clean) that automates the lifecycle of a test scope: creating an isolated environment, running a fresh subagent, continuing the conversation for diagnosis, and cleaning up when done.
User Stories
- As a skill-writer agent, I want to run a fresh subagent in an isolated worktree with a named scope, so I can observe failure firsthand during RED phase.
- As a skill-writer agent, I want each
test call to start with a fresh subagent (no inherited context, no memory of previous runs), so previous iterations don't contaminate the baseline.
- As a skill-writer agent, I want to inject a skill file into the subagent's prompt via
--skill, so the subagent receives the exact skill content without relying on path resolution.
- As a skill-writer agent, I want all subagent output recorded in
history.jsonl, so I have a source of truth for what happened in the scope.
- As a skill-writer agent, I want to continue the conversation with the subagent from the last
test run, so I can ask it why it didn't follow the skill.
- As a skill-writer agent, I want
ask output appended to history.jsonl, so the full interaction history (test + follow-up questions) is in one place.
- As a skill-writer agent, I want the scope path to be predictable from the scope name, so I don't need to parse script output to find the worktree or history.
- As a skill-writer agent, I want
test to recreate the scope cleanly if it already exists, so I can rerun without manually cleaning up first.
- As a skill-writer agent, I want to clean up a scope explicitly when done, so the worktree, branch, and scope directory are fully removed.
- As a skill-writer agent, I want the worktree created from a specific repo (
--dir), so tests run against the right codebase.
- As a skill-writer agent, I want the script to clean up the worktree automatically if
test crashes, so no orphaned worktrees accumulate.
- As a user, I want the SKILL.md to reference the correct
--scope flag and updated paths, so the instructions remain accurate.
- As a skill-writer agent, I want no model specified, so
test and ask use the same default model and reason consistently.
- As a skill-writer agent, I want the subagent to run without
--bare, so the test reflects real usage conditions (CLAUDE.md loaded, hooks active).
Implementation Decisions
-
Single zsh script at config/ai/claude/claudecode/skills/skill-writer/skill-writer, with three subcommands dispatched internally.
-
Scope directory structure:
~/local/tmp/claude/skill-writer/<scope>/
worktree/ ← git worktree (isolated repo)
history.jsonl ← stream-json output, created by test, appended by ask
-
Git branch name: skill-writer/<scope> — namespaced to avoid collisions.
-
skill-writer test behavior:
- If
~/local/tmp/claude/skill-writer/<scope>/ exists: clean it (worktree remove, branch delete, rm -rf) before recreating.
- Create
~/local/tmp/claude/skill-writer/<scope>/worktree/ as a git worktree from --dir (default: cwd), branch skill-writer/<scope>.
- If
--skill <path>: build prompt as @/absolute/path/to/SKILL.md\n\n<prompt>. The @filepath syntax is processed by the claude CLI and injects the file content. Validated: works in --print mode.
- Run
claude --dangerously-skip-permissions --print --output-format stream-json "<prompt>" in the worktree.
- Write stdout to
history.jsonl (create/overwrite).
- Trap on EXIT/INT/TERM to clean up the worktree if the script crashes.
- No output on stdout — the parent agent derives the history path from the scope name.
-
skill-writer ask behavior:
- Run
claude --dangerously-skip-permissions --continue --print --output-format stream-json "<prompt>" in the worktree.
- Append stdout to
history.jsonl.
- No output on stdout.
-
skill-writer clean behavior:
git worktree remove --force ~/local/tmp/claude/skill-writer/<scope>/worktree/
git -C <dir> branch -D skill-writer/<scope>
rm -rf ~/local/tmp/claude/skill-writer/<scope>/
-
Shared internal function _run_claude handles the common claude invocation + redirect. test passes no --continue; ask passes --continue.
-
No --model flag on either test or ask — uses the configured default so both subcommands reason with the same model.
-
No --bare flag — tests run under real conditions (CLAUDE.md loaded, hooks active).
-
SKILL.md update: replace --name with --scope, fix worktree path from ~/local/tmp/claude/skill-writer/<name> to ~/local/tmp/claude/skill-writer/<scope>/worktree/, update all command references.
Testing Decisions
No automated tests. The skill-writer script is itself validated through the TDD cycle it enables — if it works correctly, the RED/GREEN/PRESSURE loop produces reliable results.
Out of Scope
--output-format stream-json parsing or pretty-printing — the parent agent reads history.jsonl as-is.
- Interactive mode — always non-interactive.
- Multi-repo support —
--dir targets a single repo per scope.
- Listing active scopes — the parent agent can
ls ~/local/tmp/claude/skill-writer/ directly.
Further Notes
@filepath syntax in --print mode was validated: claude --print "@/path/to/file\n\nprompt" correctly injects file content. No need to embed skill content manually.
--continue targets the most recent session in the worktree directory. Since each scope has its own worktree, there is no ambiguity.
- Domain glossary:
config/ai/claude/claudecode/skills/skill-writer/CONTEXT.md
Problem Statement
When developing or updating a skill, the skill-writer agent needs to run isolated subagents to observe failures and verify compliance. Today there is no scripted way to do this — the agent must manually manage git worktrees, session continuity, and output capture, which is error-prone and not reproducible.
Solution
A
skill-writerzsh script with three subcommands (test,ask,clean) that automates the lifecycle of a test scope: creating an isolated environment, running a fresh subagent, continuing the conversation for diagnosis, and cleaning up when done.User Stories
testcall to start with a fresh subagent (no inherited context, no memory of previous runs), so previous iterations don't contaminate the baseline.--skill, so the subagent receives the exact skill content without relying on path resolution.history.jsonl, so I have a source of truth for what happened in the scope.testrun, so I can ask it why it didn't follow the skill.askoutput appended tohistory.jsonl, so the full interaction history (test + follow-up questions) is in one place.testto recreate the scope cleanly if it already exists, so I can rerun without manually cleaning up first.--dir), so tests run against the right codebase.testcrashes, so no orphaned worktrees accumulate.--scopeflag and updated paths, so the instructions remain accurate.testandaskuse the same default model and reason consistently.--bare, so the test reflects real usage conditions (CLAUDE.md loaded, hooks active).Implementation Decisions
Single zsh script at
config/ai/claude/claudecode/skills/skill-writer/skill-writer, with three subcommands dispatched internally.Scope directory structure:
Git branch name:
skill-writer/<scope>— namespaced to avoid collisions.skill-writer testbehavior:~/local/tmp/claude/skill-writer/<scope>/exists: clean it (worktree remove, branch delete, rm -rf) before recreating.~/local/tmp/claude/skill-writer/<scope>/worktree/as a git worktree from--dir(default: cwd), branchskill-writer/<scope>.--skill <path>: build prompt as@/absolute/path/to/SKILL.md\n\n<prompt>. The@filepathsyntax is processed by the claude CLI and injects the file content. Validated: works in--printmode.claude --dangerously-skip-permissions --print --output-format stream-json "<prompt>"in the worktree.history.jsonl(create/overwrite).skill-writer askbehavior:claude --dangerously-skip-permissions --continue --print --output-format stream-json "<prompt>"in the worktree.history.jsonl.skill-writer cleanbehavior:git worktree remove --force ~/local/tmp/claude/skill-writer/<scope>/worktree/git -C <dir> branch -D skill-writer/<scope>rm -rf ~/local/tmp/claude/skill-writer/<scope>/Shared internal function
_run_claudehandles the common claude invocation + redirect.testpasses no--continue;askpasses--continue.No
--modelflag on eithertestorask— uses the configured default so both subcommands reason with the same model.No
--bareflag — tests run under real conditions (CLAUDE.md loaded, hooks active).SKILL.md update: replace
--namewith--scope, fix worktree path from~/local/tmp/claude/skill-writer/<name>to~/local/tmp/claude/skill-writer/<scope>/worktree/, update all command references.Testing Decisions
No automated tests. The
skill-writerscript is itself validated through the TDD cycle it enables — if it works correctly, the RED/GREEN/PRESSURE loop produces reliable results.Out of Scope
--output-format stream-jsonparsing or pretty-printing — the parent agent readshistory.jsonlas-is.--dirtargets a single repo per scope.ls ~/local/tmp/claude/skill-writer/directly.Further Notes
@filepathsyntax in--printmode was validated:claude --print "@/path/to/file\n\nprompt"correctly injects file content. No need to embed skill content manually.--continuetargets the most recent session in the worktree directory. Since each scope has its own worktree, there is no ambiguity.config/ai/claude/claudecode/skills/skill-writer/CONTEXT.md