draht-claude 2026.4.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.claude-plugin/plugin.json +21 -0
  2. package/CHANGELOG.md +8 -0
  3. package/LICENSE +22 -0
  4. package/README.md +199 -0
  5. package/agents/architect.md +45 -0
  6. package/agents/debugger.md +57 -0
  7. package/agents/git-committer.md +52 -0
  8. package/agents/implementer.md +35 -0
  9. package/agents/reviewer.md +57 -0
  10. package/agents/security-auditor.md +109 -0
  11. package/agents/verifier.md +44 -0
  12. package/bin/draht-tools.cjs +1067 -0
  13. package/cli.mjs +348 -0
  14. package/commands/atomic-commit.md +61 -0
  15. package/commands/discuss-phase.md +54 -0
  16. package/commands/execute-phase.md +111 -0
  17. package/commands/fix.md +50 -0
  18. package/commands/init-project.md +65 -0
  19. package/commands/map-codebase.md +52 -0
  20. package/commands/new-project.md +73 -0
  21. package/commands/next-milestone.md +49 -0
  22. package/commands/orchestrate.md +58 -0
  23. package/commands/pause-work.md +38 -0
  24. package/commands/plan-phase.md +107 -0
  25. package/commands/progress.md +30 -0
  26. package/commands/quick.md +50 -0
  27. package/commands/resume-work.md +35 -0
  28. package/commands/review.md +55 -0
  29. package/commands/verify-work.md +72 -0
  30. package/hooks/hooks.json +26 -0
  31. package/package.json +50 -0
  32. package/scripts/gsd-post-phase.cjs +133 -0
  33. package/scripts/gsd-post-task.cjs +165 -0
  34. package/scripts/gsd-pre-execute.cjs +146 -0
  35. package/scripts/gsd-quality-gate.cjs +252 -0
  36. package/scripts/prompt-context.cjs +36 -0
  37. package/scripts/session-start.cjs +52 -0
  38. package/skills/ddd-workflow/SKILL.md +108 -0
  39. package/skills/gsd-workflow/SKILL.md +111 -0
  40. package/skills/tdd-workflow/SKILL.md +115 -0
package/cli.mjs ADDED
@@ -0,0 +1,348 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * draht-claude CLI — installs this package as a Claude Code plugin via a local marketplace.
4
+ *
5
+ * Architecture:
6
+ * 1. Copy plugin files into a local marketplace at ~/.draht/claude-marketplace/
7
+ * 2. Write marketplace.json listing draht-claude as an available plugin
8
+ * 3. Shell out to `claude plugin marketplace add` and `claude plugin install`
9
+ * 4. Claude Code tracks the plugin in its own registries and enables it
10
+ *
11
+ * The install is reversible via `draht-claude uninstall`.
12
+ *
13
+ * Usage:
14
+ * npx draht-claude install [--path <dir>] [--force]
15
+ * npx draht-claude uninstall [--path <dir>]
16
+ * npx draht-claude update [--path <dir>]
17
+ * npx draht-claude status [--path <dir>]
18
+ * npx draht-claude --help
19
+ */
20
+
21
+ import { execSync, spawnSync } from "node:child_process";
22
+ import * as fs from "node:fs";
23
+ import * as os from "node:os";
24
+ import * as path from "node:path";
25
+ import { fileURLToPath } from "node:url";
26
+
27
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
28
+ const PACKAGE_ROOT = __dirname;
29
+
30
+ // Marketplace and plugin names
31
+ const MARKETPLACE_NAME = "draht";
32
+ const PLUGIN_NAME = "draht";
33
+
34
+ // Default location for the local marketplace we generate
35
+ const DEFAULT_MARKETPLACE_DIR = path.join(os.homedir(), ".draht", "claude-marketplace");
36
+
37
+ // Files in the npm package that must NOT be copied into the plugin tree
38
+ const IGNORE = new Set([
39
+ "node_modules",
40
+ "package.json",
41
+ "cli.mjs",
42
+ ".npmignore",
43
+ ".DS_Store",
44
+ "CHANGELOG.md",
45
+ ]);
46
+
47
+ // ─── args ───────────────────────────────────────────────────────────────────
48
+
49
+ function parseArgs(argv) {
50
+ const args = argv.slice(2);
51
+ const command = args[0];
52
+ const flags = { path: null, force: false, help: false };
53
+ for (let i = 1; i < args.length; i++) {
54
+ const a = args[i];
55
+ if (a === "--path" || a === "-p") {
56
+ flags.path = args[++i];
57
+ } else if (a === "--force" || a === "-f") {
58
+ flags.force = true;
59
+ } else if (a === "--help" || a === "-h") {
60
+ flags.help = true;
61
+ }
62
+ }
63
+ if (!command || command === "--help" || command === "-h") flags.help = true;
64
+ return { command, flags };
65
+ }
66
+
67
+ function printHelp() {
68
+ console.log(`draht-claude — install the draht Claude Code plugin
69
+
70
+ Usage:
71
+ npx draht-claude install Install as a Claude Code plugin
72
+ npx draht-claude install --force Reinstall even if already present
73
+ npx draht-claude install --path DIR Custom marketplace directory
74
+ npx draht-claude uninstall Remove the plugin and marketplace
75
+ npx draht-claude update Reinstall (same as install --force)
76
+ npx draht-claude status Show install + enabled state
77
+
78
+ Options:
79
+ -p, --path <dir> Custom local marketplace directory
80
+ -f, --force Overwrite existing install
81
+ -h, --help Show this help
82
+
83
+ What this installs:
84
+ • Local Claude Code marketplace named "${MARKETPLACE_NAME}" at ~/.draht/claude-marketplace/
85
+ • Plugin "${PLUGIN_NAME}" inside that marketplace, registered and enabled
86
+ • 16 slash commands (/new-project, /plan-phase, /execute-phase, /orchestrate, ...)
87
+ • 7 specialist subagents (architect, implementer, reviewer, debugger, ...)
88
+ • 3 workflow skills (gsd-workflow, tdd-workflow, ddd-workflow)
89
+ • Workflow hook scripts (pre-execute, post-task, post-phase, quality-gate)
90
+ • Claude Code lifecycle hooks (SessionStart, UserPromptSubmit)
91
+ • Self-contained draht-tools CLI
92
+
93
+ After install, restart Claude Code. Commands appear in the slash command picker.
94
+
95
+ Docs: https://draht.dev
96
+ `);
97
+ }
98
+
99
+ // ─── helpers ────────────────────────────────────────────────────────────────
100
+
101
+ function log(msg) {
102
+ console.log(msg);
103
+ }
104
+
105
+ function err(msg) {
106
+ console.error(`error: ${msg}`);
107
+ }
108
+
109
+ function readPluginManifest() {
110
+ const manifestPath = path.join(PACKAGE_ROOT, ".claude-plugin", "plugin.json");
111
+ if (!fs.existsSync(manifestPath)) {
112
+ err(`Plugin manifest not found at ${manifestPath}`);
113
+ err("This usually means the package was installed incorrectly. Reinstall via 'npx draht-claude@latest install'.");
114
+ process.exit(1);
115
+ }
116
+ return JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
117
+ }
118
+
119
+ function copyRecursive(src, dest) {
120
+ const stat = fs.statSync(src);
121
+ if (stat.isDirectory()) {
122
+ fs.mkdirSync(dest, { recursive: true });
123
+ for (const entry of fs.readdirSync(src)) {
124
+ if (IGNORE.has(entry)) continue;
125
+ copyRecursive(path.join(src, entry), path.join(dest, entry));
126
+ }
127
+ } else {
128
+ fs.copyFileSync(src, dest);
129
+ // Preserve executable bit on bin/ and scripts/
130
+ const parentDir = path.basename(path.dirname(src));
131
+ if ((parentDir === "bin" || parentDir === "scripts") && (stat.mode & 0o111) !== 0) {
132
+ fs.chmodSync(dest, 0o755);
133
+ }
134
+ }
135
+ }
136
+
137
+ function removeRecursive(target) {
138
+ if (!fs.existsSync(target)) return;
139
+ fs.rmSync(target, { recursive: true, force: true });
140
+ }
141
+
142
+ function hasClaudeCli() {
143
+ const which = spawnSync(process.platform === "win32" ? "where" : "which", ["claude"], { encoding: "utf-8" });
144
+ return which.status === 0 && which.stdout.trim().length > 0;
145
+ }
146
+
147
+ function runClaude(args, { allowFail = false } = {}) {
148
+ log(` $ claude ${args.join(" ")}`);
149
+ const res = spawnSync("claude", args, { stdio: "inherit" });
150
+ if (res.status !== 0 && !allowFail) {
151
+ err(`claude ${args[0]} ${args[1] || ""} failed with exit code ${res.status}`);
152
+ process.exit(1);
153
+ }
154
+ return res.status === 0;
155
+ }
156
+
157
+ function writeMarketplaceManifest(marketplaceDir, pluginManifest) {
158
+ const manifest = {
159
+ $schema: "https://anthropic.com/claude-code/marketplace.schema.json",
160
+ name: MARKETPLACE_NAME,
161
+ description: "Local marketplace for draht-claude. Managed by the draht-claude CLI.",
162
+ owner: {
163
+ name: pluginManifest.author?.name || "draht",
164
+ url: pluginManifest.homepage || "https://draht.dev",
165
+ },
166
+ plugins: [
167
+ {
168
+ name: PLUGIN_NAME,
169
+ description: pluginManifest.description || "Draht GSD, multi-agent, TDD and DDD workflows as a Claude Code plugin",
170
+ source: `./plugins/${PLUGIN_NAME}`,
171
+ category: "workflow",
172
+ homepage: pluginManifest.homepage || "https://draht.dev",
173
+ },
174
+ ],
175
+ };
176
+ const manifestDir = path.join(marketplaceDir, ".claude-plugin");
177
+ fs.mkdirSync(manifestDir, { recursive: true });
178
+ fs.writeFileSync(path.join(manifestDir, "marketplace.json"), `${JSON.stringify(manifest, null, 2)}\n`);
179
+ }
180
+
181
+ // ─── commands ───────────────────────────────────────────────────────────────
182
+
183
+ function cmdInstall(flags) {
184
+ const marketplaceDir = flags.path || DEFAULT_MARKETPLACE_DIR;
185
+ const pluginDir = path.join(marketplaceDir, "plugins", PLUGIN_NAME);
186
+ const manifest = readPluginManifest();
187
+
188
+ log("draht-claude installer");
189
+ log(` plugin: ${manifest.name} v${manifest.version}`);
190
+ log(` source: ${PACKAGE_ROOT}`);
191
+ log(` marketplace: ${marketplaceDir}`);
192
+ log(` plugin dir: ${pluginDir}`);
193
+ log("");
194
+
195
+ // Check prerequisites
196
+ if (!hasClaudeCli()) {
197
+ err("claude CLI not found in PATH");
198
+ err("Install Claude Code first: https://claude.com/claude-code");
199
+ process.exit(1);
200
+ }
201
+
202
+ // Bail early if already installed and not forcing
203
+ if (fs.existsSync(pluginDir) && !flags.force) {
204
+ err(`plugin already installed at ${pluginDir}`);
205
+ err("use --force to reinstall, or 'draht-claude update' to refresh");
206
+ process.exit(1);
207
+ }
208
+
209
+ // Copy plugin files into marketplace dir
210
+ log("Copying plugin files...");
211
+ if (flags.force && fs.existsSync(pluginDir)) {
212
+ removeRecursive(pluginDir);
213
+ }
214
+ fs.mkdirSync(pluginDir, { recursive: true });
215
+ copyRecursive(PACKAGE_ROOT, pluginDir);
216
+
217
+ // Write marketplace manifest
218
+ log("Writing marketplace.json...");
219
+ writeMarketplaceManifest(marketplaceDir, manifest);
220
+
221
+ // Validate marketplace + plugin before registering
222
+ log("Validating manifest...");
223
+ runClaude(["plugin", "validate", pluginDir], { allowFail: true });
224
+
225
+ // Add marketplace to Claude Code (idempotent — will error if already added, so allow fail)
226
+ log("Registering marketplace with Claude Code...");
227
+ runClaude(["plugin", "marketplace", "add", marketplaceDir], { allowFail: true });
228
+
229
+ // Update marketplace so Claude Code picks up any changes to our plugin files on reinstall
230
+ runClaude(["plugin", "marketplace", "update", MARKETPLACE_NAME], { allowFail: true });
231
+
232
+ // Install the plugin
233
+ log("Installing plugin...");
234
+ const pluginSpec = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
235
+ runClaude(["plugin", "install", pluginSpec, "--scope", "user"]);
236
+
237
+ // Enable explicitly — install usually enables automatically, but be safe
238
+ runClaude(["plugin", "enable", pluginSpec], { allowFail: true });
239
+
240
+ log("");
241
+ log(`✓ installed ${PLUGIN_NAME}@${MARKETPLACE_NAME} v${manifest.version}`);
242
+ log("");
243
+ log("Next steps:");
244
+ log(" 1. Restart Claude Code so it picks up the plugin");
245
+ log(" 2. Check that commands appear: run `claude plugin list`");
246
+ log(" 3. Try /new-project or /orchestrate inside Claude Code");
247
+ log("");
248
+ log("Docs: https://draht.dev");
249
+ }
250
+
251
+ function cmdUninstall(flags) {
252
+ const marketplaceDir = flags.path || DEFAULT_MARKETPLACE_DIR;
253
+ const pluginDir = path.join(marketplaceDir, "plugins", PLUGIN_NAME);
254
+ const pluginSpec = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
255
+
256
+ log("draht-claude uninstaller");
257
+ log(` marketplace: ${marketplaceDir}`);
258
+ log(` plugin: ${pluginSpec}`);
259
+ log("");
260
+
261
+ // Try to uninstall via claude CLI first (removes from settings.json + registries)
262
+ if (hasClaudeCli()) {
263
+ log("Disabling plugin in Claude Code...");
264
+ runClaude(["plugin", "disable", pluginSpec], { allowFail: true });
265
+ log("Uninstalling plugin...");
266
+ runClaude(["plugin", "uninstall", pluginSpec], { allowFail: true });
267
+ log("Removing marketplace...");
268
+ runClaude(["plugin", "marketplace", "remove", MARKETPLACE_NAME], { allowFail: true });
269
+ } else {
270
+ log("(claude CLI not found — skipping registry cleanup)");
271
+ }
272
+
273
+ // Remove local marketplace files
274
+ if (fs.existsSync(marketplaceDir)) {
275
+ log(`Removing ${marketplaceDir}...`);
276
+ removeRecursive(marketplaceDir);
277
+ }
278
+
279
+ log("");
280
+ log("✓ uninstalled");
281
+ }
282
+
283
+ function cmdUpdate(flags) {
284
+ cmdInstall({ ...flags, force: true });
285
+ }
286
+
287
+ function cmdStatus(flags) {
288
+ const marketplaceDir = flags.path || DEFAULT_MARKETPLACE_DIR;
289
+ const pluginDir = path.join(marketplaceDir, "plugins", PLUGIN_NAME);
290
+ const pluginManifestPath = path.join(pluginDir, ".claude-plugin", "plugin.json");
291
+
292
+ log(`marketplace dir: ${marketplaceDir}`);
293
+
294
+ if (!fs.existsSync(pluginManifestPath)) {
295
+ log("status: not installed");
296
+ return;
297
+ }
298
+ try {
299
+ const manifest = JSON.parse(fs.readFileSync(pluginManifestPath, "utf-8"));
300
+ log("status: files present");
301
+ log(`plugin: ${manifest.name} v${manifest.version}`);
302
+ log(`description: ${manifest.description || "(none)"}`);
303
+ } catch (e) {
304
+ log(`status: files present (manifest unreadable: ${e.message})`);
305
+ }
306
+
307
+ // Show claude's view if available
308
+ if (hasClaudeCli()) {
309
+ log("");
310
+ log("Claude Code plugin list:");
311
+ try {
312
+ const out = execSync("claude plugin list", { encoding: "utf-8" });
313
+ process.stdout.write(out);
314
+ } catch {
315
+ log(" (failed to run `claude plugin list`)");
316
+ }
317
+ }
318
+ }
319
+
320
+ // ─── main ───────────────────────────────────────────────────────────────────
321
+
322
+ const { command, flags } = parseArgs(process.argv);
323
+
324
+ if (flags.help) {
325
+ printHelp();
326
+ process.exit(0);
327
+ }
328
+
329
+ switch (command) {
330
+ case "install":
331
+ cmdInstall(flags);
332
+ break;
333
+ case "uninstall":
334
+ case "remove":
335
+ cmdUninstall(flags);
336
+ break;
337
+ case "update":
338
+ case "upgrade":
339
+ cmdUpdate(flags);
340
+ break;
341
+ case "status":
342
+ cmdStatus(flags);
343
+ break;
344
+ default:
345
+ err(`unknown command: ${command}`);
346
+ err("run 'draht-claude --help' for usage");
347
+ process.exit(1);
348
+ }
@@ -0,0 +1,61 @@
1
+ ---
2
+ description: Analyze uncommitted changes and create atomic conventional commits (one logical change per commit)
3
+ allowed-tools: Bash, Read, Task
4
+ ---
5
+
6
+ # /atomic-commit
7
+
8
+ Analyze changes and create atomic commits.
9
+
10
+ ## Atomic Reasoning
11
+
12
+ Before creating commits, decompose changes into atomic reasoning units:
13
+
14
+ **For each file change:**
15
+ 1. **State the logical component** — What does this change do? What is its purpose? Does it complete a thought?
16
+ 2. **Validate independence** — Can this change be applied independently? Does it depend on other changes? Does it break the build alone?
17
+ 3. **Verify correctness** — Is this change logically complete? Does it mix concerns? Should it be split further?
18
+
19
+ **Synthesize commit strategy:**
20
+ - Group changes by logical concern (one commit = one idea)
21
+ - Order commits so each builds successfully
22
+ - Write clear commit messages that explain WHY, not just WHAT
23
+ - Ensure each commit is self-contained and reviewable
24
+
25
+ ## Gathering Current State
26
+
27
+ First, gather the current state:
28
+
29
+ 1. Run `git status` to see what changed
30
+ 2. Run `git diff` to see unstaged changes
31
+ 3. Run `git diff --cached` to see staged changes
32
+
33
+ ## Strategy
34
+
35
+ Based on the changes, analyze and group them into logical, ATOMIC commits. Each commit should:
36
+
37
+ 1. Contain ONE logical change only
38
+ 2. Be self-contained and complete
39
+ 3. Not break the build if applied independently
40
+
41
+ You may delegate this work to the `git-committer` subagent via the **Task tool** with `subagent_type: "git-committer"` if the change set is large or spans multiple areas. The git-committer will review diffs, group changes, and create commits with conventional commit messages.
42
+
43
+ For each group of changes you identify:
44
+ - List the specific files that belong together
45
+ - Generate a clear, descriptive commit message following conventional commits format
46
+ - Explain WHY these changes belong in one commit
47
+
48
+ Then execute the `git add <specific-files>` and `git commit` commands for each atomic commit in the order they should be applied.
49
+
50
+ Format each commit message as:
51
+ ```
52
+ type(scope): brief description
53
+ ```
54
+
55
+ Common types: feat, fix, refactor, docs, test, chore, style, perf. For strict TDD cycles, also use `red:`, `green:`, `refactor:`.
56
+
57
+ ## Rules
58
+ - NEVER use `git add -A` or `git add .` — always stage specific files
59
+ - NEVER use `git commit --no-verify`
60
+ - NEVER force push
61
+ - Review diffs before committing to ensure nothing unexpected is staged
@@ -0,0 +1,54 @@
1
+ ---
2
+ description: Capture implementation decisions before planning a phase
3
+ argument-hint: "<phase-number>"
4
+ allowed-tools: Bash, Read, Write, Edit
5
+ ---
6
+
7
+ # /discuss-phase
8
+
9
+ Capture implementation decisions before planning a phase.
10
+
11
+ Phase: $1
12
+
13
+ > **Tool note**: Invoke `draht-tools <subcommand>` as `node "${CLAUDE_PLUGIN_ROOT}/bin/draht-tools.cjs" <subcommand>` via the Bash tool.
14
+
15
+ ## Atomic Reasoning
16
+
17
+ Before questioning, decompose this phase scope into atomic reasoning units:
18
+
19
+ **For each implementation decision:**
20
+ 1. **State the logical component** — What gray area exists? What choice needs to be made? Why does this matter?
21
+ 2. **Validate independence** — Can this decision be made independently, or does it depend on other choices? What downstream impacts does it have?
22
+ 3. **Verify correctness** — What criteria determine the right answer? What trade-offs exist? What domain terms need clarification?
23
+
24
+ **Synthesize discussion strategy:**
25
+ - Identify critical decisions that block planning
26
+ - Group related decisions (e.g., all API decisions together)
27
+ - Sequence questions from foundational to detailed
28
+ - Ensure domain language is established first
29
+
30
+ ## Steps
31
+ 1. Run `draht-tools phase-info $1` to load phase context
32
+ 2. Identify gray areas based on what's being built
33
+ 3. Present 1-2 questions at a time about preferences
34
+ 4. If `.planning/DOMAIN.md` exists, load it and validate discovered terms against the glossary. Add any new domain terms found during discussion.
35
+ 5. Record decisions with `draht-tools save-context $1`
36
+ 6. Commit: `draht-tools commit-docs "capture phase $1 context"`
37
+
38
+ ## Workflow
39
+ This is one step in the per-phase cycle. Use fresh sessions (`/clear`) between steps:
40
+
41
+ ```
42
+ /discuss-phase N → /plan-phase N → /execute-phase N → /verify-work N → /discuss-phase N+1 → ...
43
+ ```
44
+
45
+ After completing this command, tell the user to start a fresh session and run `/plan-phase $1`. Do NOT suggest `/next-milestone` — that is only after ALL phases in the milestone are verified.
46
+
47
+ ## Gray Area Categories
48
+ - **Visual features** → Layout, density, interactions, empty states
49
+ - **APIs/CLIs** → Response format, error handling, auth
50
+ - **Data models** → Schema, relationships, validation
51
+ - **Content** → Structure, tone, depth, flow
52
+ - **Refactoring** → Grouping, naming, migration strategy
53
+ - **Testability** → What needs testing, test framework preference, coverage goals, integration vs unit boundaries
54
+ - **Domain boundaries** → What are the bounded contexts in play? Are there existing domain terms to respect? What aggregates/entities are involved?
@@ -0,0 +1,111 @@
1
+ ---
2
+ description: Execute all plans in a phase with atomic commits (parallel implementer subagents + TDD cycle)
3
+ argument-hint: "<phase-number> [--gaps-only]"
4
+ allowed-tools: Bash, Read, Write, Edit, Task
5
+ ---
6
+
7
+ # /execute-phase
8
+
9
+ Execute all plans in a phase with atomic commits, parallelizing independent plans via subagents.
10
+
11
+ Phase: $1
12
+ Arguments: $ARGUMENTS
13
+
14
+ > **Tool note**: Invoke `draht-tools <subcommand>` as `node "${CLAUDE_PLUGIN_ROOT}/bin/draht-tools.cjs" <subcommand>`. For subagent delegation, use the **Task tool** with `subagent_type: "implementer"`. Dispatch multiple parallel tasks in a single assistant turn by making multiple Task tool calls at once.
15
+
16
+ ## Atomic Reasoning
17
+
18
+ Before executing, decompose this phase execution into atomic reasoning units:
19
+
20
+ **For each plan in the phase:**
21
+ 1. **State the logical component** — What is this plan's singular purpose? What observable outcome does it produce?
22
+ 2. **Validate independence** — Can this plan execute in parallel with others, or does it depend on their outputs? Which files does it touch?
23
+ 3. **Verify correctness** — What tests will prove this plan works? What failure modes exist?
24
+
25
+ **Synthesize execution strategy:**
26
+ - Identify parallel execution groups (plans with no shared files/dependencies)
27
+ - Order dependent plans (plan B depends on plan A's outputs)
28
+ - Map each plan to a subagent task with clear success criteria
29
+
30
+ ## Steps
31
+ 0. Run the pre-execute check:
32
+ ```bash
33
+ node "${CLAUDE_PLUGIN_ROOT}/scripts/gsd-pre-execute.cjs" $1
34
+ ```
35
+ If it exits non-zero, STOP and report errors to the user. Do not proceed.
36
+
37
+ 1. Run `draht-tools discover-plans $1` to find and order plans
38
+ 2. Read each plan file yourself (from `.planning/phases/`) and analyze dependencies to identify which plans can run in parallel vs sequential
39
+
40
+ 3. **Delegate execution to subagents via the Task tool:**
41
+ - For **independent plans** (no shared files, no dependency chain): dispatch multiple `Task` tool calls in parallel (single assistant turn), each with `subagent_type: "implementer"`, one per plan.
42
+ - For **dependent plans**: dispatch sequentially — one `Task` call at a time, waiting for the previous to complete before starting the next.
43
+ - Each implementer prompt must include:
44
+ - The full plan content (paste it inline — the subagent cannot run draht-tools)
45
+ - The TDD cycle instructions (see template below)
46
+ - Instructions to commit with `git add <files> && git commit -m "description"`
47
+
48
+ 4. After all subagents complete, collect results and check for failures
49
+ 5. For each completed task, run the post-task hook (record results + type check + test run):
50
+ ```bash
51
+ node "${CLAUDE_PLUGIN_ROOT}/scripts/gsd-post-task.cjs" <phase> <plan> <task-num> <status> <commit-hash>
52
+ ```
53
+ 6. Run `draht-tools verify-phase $1` yourself (not the subagent)
54
+ 7. Run the post-phase hook to generate the phase report:
55
+ ```bash
56
+ node "${CLAUDE_PLUGIN_ROOT}/scripts/gsd-post-phase.cjs" $1
57
+ ```
58
+ 8. Run `draht-tools update-state` yourself
59
+ 9. Final commit: `draht-tools commit-docs "complete phase $1 execution"`
60
+ 10. Tell the user to start a fresh session (`/clear`) and run `/verify-work $1`
61
+
62
+ ## Subagent Task Template
63
+
64
+ Each implementer Task call receives a prompt like:
65
+
66
+ ```
67
+ Execute this plan. Here is the full plan content:
68
+
69
+ <paste full plan XML here>
70
+
71
+ For each <task> in the plan, follow this TDD cycle:
72
+ 1. RED — Write failing tests from <test>. Run the test runner, confirm they FAIL. Commit with: git add <test-files> && git commit -m "red: <description>"
73
+ 2. GREEN — Write minimal implementation from <action> to make tests pass. Run tests, confirm PASS. Commit with: git add <files> && git commit -m "green: <task name>"
74
+ 3. REFACTOR — Apply <refactor> improvements if any. Tests must stay green after each change. Commit with: git add <files> && git commit -m "refactor: <description>"
75
+ 4. VERIFY — Run the <verify> step, confirm <done> criteria are met.
76
+
77
+ Domain rules: Use ubiquitous language from .planning/DOMAIN.md (read it). Do not import across bounded context boundaries.
78
+
79
+ Checkpoint handling:
80
+ - type="auto" → execute silently.
81
+ - type="checkpoint:human-verify" → stop and report back what was built.
82
+ - type="checkpoint:decision" → stop and report the options.
83
+ ```
84
+
85
+ ## Parallelization Rules
86
+ - Plans sharing no files and having no dependency edges can run in parallel
87
+ - If plan B depends on output of plan A, plan B must wait for A to complete
88
+ - If a parallel subagent fails, report which plan failed and continue with independent plans
89
+
90
+ ## TDD Rules
91
+ - Never write implementation before a failing test exists
92
+ - If a test passes immediately after being written, it is not testing the right thing — fix it
93
+ - Red → Green → Refactor is not optional; skipping steps invalidates the safety net
94
+ - Each TDD phase gets its own commit so the history is auditable
95
+
96
+ ## Domain Rules
97
+ - All identifiers (class names, method names, variables) must use the ubiquitous language from `.planning/DOMAIN.md`
98
+ - Do not import across bounded context boundaries directly — use domain events or ACL adapters
99
+ - If implementation reveals a missing domain term, stop and update DOMAIN.md before continuing
100
+
101
+ ## Workflow
102
+ This is one step in the per-phase cycle:
103
+
104
+ ```
105
+ /discuss-phase N → /plan-phase N → /execute-phase N → /verify-work N
106
+ ```
107
+
108
+ After completing this command, tell the user to start a fresh session (`/clear`) and run `/verify-work $1`. Do NOT suggest `/next-milestone`.
109
+
110
+ ## Flags
111
+ - `--gaps-only` → only execute FIX-PLAN.md files from failed verification
@@ -0,0 +1,50 @@
1
+ ---
2
+ description: Diagnose and fix a bug with TDD discipline (debugger subagent → reproducing test → minimal fix)
3
+ argument-hint: "<description of what's broken>"
4
+ allowed-tools: Bash, Read, Write, Edit, Task
5
+ ---
6
+
7
+ # /fix
8
+
9
+ Diagnose and fix a specific bug or failing task with TDD discipline, using a subagent for diagnosis.
10
+
11
+ Issue: $ARGUMENTS
12
+
13
+ > **Tool note**: Invoke `draht-tools <subcommand>` as `node "${CLAUDE_PLUGIN_ROOT}/bin/draht-tools.cjs" <subcommand>`. For subagents, use the **Task tool** with `subagent_type: "debugger"` or `"implementer"`.
14
+
15
+ ## Atomic Reasoning
16
+
17
+ Before diagnosing, decompose this bug into atomic reasoning units:
18
+
19
+ 1. **State the logical component** — What is the observed failure? What should happen vs what actually happens?
20
+ 2. **Validate independence** — Which components/files are involved? Can we isolate the failure? Are there related bugs that should be fixed separately?
21
+ 3. **Verify correctness** — What test will reproduce this bug reliably? What would prove it's fixed? What regressions could the fix introduce?
22
+
23
+ **Synthesize fix strategy:**
24
+ - Trace the failure to root cause
25
+ - Write a minimal reproducing test
26
+ - Identify the smallest change that makes the test pass
27
+ - Plan regression checks
28
+
29
+ ## Steps
30
+ 1. **Diagnose via Task tool** with `subagent_type: "debugger"` and prompt:
31
+ "Diagnose this issue: $ARGUMENTS. Reproduce the bug by running the relevant test or command. Trace the root cause by reading the code. Identify the exact files and lines involved. Do NOT fix it yet — only report the diagnosis with: root cause, affected files, and a recommended fix approach."
32
+
33
+ 2. **Write a reproducing test**: Based on the diagnosis, write a test that demonstrates the bug (it must fail)
34
+ - Commit: `git add <test-files> && git commit -m "red: reproduce <bug description>"`
35
+
36
+ 3. **Minimal fix**: Write the smallest change that makes the test pass
37
+ - Do not refactor or add features — just fix the bug
38
+ - Run the full test suite to check for regressions
39
+ - Commit: `git add <files> && git commit -m "green: fix <bug description>"`
40
+
41
+ 4. **Refactor** (if needed): Clean up without changing behavior
42
+ - Tests must stay green after every change
43
+ - Commit: `git add <files> && git commit -m "refactor: <description>"`
44
+
45
+ 5. **Update state**: `draht-tools update-state`
46
+
47
+ ## Rules
48
+ - Always reproduce before fixing — a fix without a test is a guess
49
+ - One bug, one fix, one commit series. Do not bundle unrelated changes.
50
+ - If the root cause spans multiple files, explain the chain in the commit message body