murmur8 4.1.1 → 4.3.0
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.
- package/.blueprint/agents/AGENT_SPECIFICATION_ALEX.md +33 -3
- package/.blueprint/features/feature_config-factory/FEATURE_SPEC.md +138 -0
- package/.blueprint/features/feature_config-factory/IMPLEMENTATION_PLAN.md +187 -0
- package/.blueprint/features/feature_config-factory/handoff-nigel.md +57 -0
- package/.blueprint/features/feature_export-history/FEATURE_SPEC.md +215 -0
- package/.blueprint/features/feature_export-history/IMPLEMENTATION_PLAN.md +48 -0
- package/.blueprint/features/feature_export-history/story-basic-export.md +48 -0
- package/.blueprint/features/feature_export-history/story-date-filter.md +42 -0
- package/.blueprint/features/feature_export-history/story-feature-filter.md +42 -0
- package/.blueprint/features/feature_export-history/story-file-output.md +48 -0
- package/.blueprint/features/feature_export-history/story-status-filter.md +42 -0
- package/.blueprint/features/feature_extract-prompt-util/FEATURE_SPEC.md +42 -0
- package/.blueprint/features/feature_fix-status-icons/FEATURE_SPEC.md +37 -0
- package/.blueprint/features/feature_murm-subagent/FEATURE_SPEC.md +137 -0
- package/.blueprint/features/feature_murm-subagent/SKILL_CHANGES.md +345 -0
- package/.blueprint/features/feature_split-cli-commands/FEATURE_SPEC.md +125 -0
- package/.blueprint/features/feature_split-cli-commands/IMPLEMENTATION_PLAN.md +119 -0
- package/.blueprint/features/feature_split-cli-commands/handoff-nigel.md +45 -0
- package/.blueprint/features/feature_theme-adoption/FEATURE_SPEC.md +143 -0
- package/.blueprint/features/feature_theme-adoption/IMPLEMENTATION_PLAN.md +68 -0
- package/.blueprint/features/feature_theme-adoption/handoff-nigel.md +35 -0
- package/.blueprint/templates/BACKLOG_TEMPLATE.md +46 -0
- package/README.md +26 -10
- package/SKILL.md +377 -3
- package/bin/cli.js +20 -384
- package/package.json +1 -1
- package/src/commands/feedback-config.js +32 -0
- package/src/commands/help.js +81 -0
- package/src/commands/history.js +42 -0
- package/src/commands/init.js +12 -0
- package/src/commands/insights.js +23 -0
- package/src/commands/murm-config.js +52 -0
- package/src/commands/murm.js +109 -0
- package/src/commands/queue.js +19 -0
- package/src/commands/retry-config.js +28 -0
- package/src/commands/stack-config.js +32 -0
- package/src/commands/update.js +12 -0
- package/src/commands/utils.js +24 -0
- package/src/commands/validate.js +15 -0
- package/src/config-factory.js +190 -0
- package/src/feedback.js +5 -2
- package/src/history.js +92 -1
- package/src/init.js +1 -15
- package/src/insights.js +19 -16
- package/src/retry.js +5 -2
- package/src/stack.js +4 -1
- package/src/theme.js +4 -4
- package/src/update.js +2 -15
- package/src/utils.js +26 -0
- package/src/validate.js +5 -12
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# SKILL.md Changes for Multi-Feature Support
|
|
2
|
+
|
|
3
|
+
This document outlines the changes needed to support parallel feature execution via Task sub-agents.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Update Invocation Section (replace lines 28-39)
|
|
8
|
+
|
|
9
|
+
```markdown
|
|
10
|
+
## Invocation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# Single feature (existing)
|
|
14
|
+
/implement-feature # Interactive slug prompt
|
|
15
|
+
/implement-feature "user-auth" # New feature
|
|
16
|
+
/implement-feature "user-auth" --interactive # Force interactive spec creation
|
|
17
|
+
/implement-feature "user-auth" --pause-after=alex|cass|nigel|codey-plan
|
|
18
|
+
/implement-feature "user-auth" --no-commit
|
|
19
|
+
/implement-feature "user-auth" --no-feedback
|
|
20
|
+
/implement-feature "user-auth" --no-validate
|
|
21
|
+
/implement-feature "user-auth" --no-history
|
|
22
|
+
|
|
23
|
+
# Multiple features — parallel execution (NEW)
|
|
24
|
+
/implement-feature feat-a feat-b feat-c # Run 3 features in parallel
|
|
25
|
+
/implement-feature feat-a feat-b --max-concurrency=2 # Limit parallelism
|
|
26
|
+
/implement-feature feat-a feat-b --sequential # Run one at a time (no worktrees)
|
|
27
|
+
```
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 2. Add Multi-Feature Paths (insert after line 27)
|
|
33
|
+
|
|
34
|
+
```markdown
|
|
35
|
+
## Multi-Feature Paths (Murmuration Mode)
|
|
36
|
+
|
|
37
|
+
| Var | Path |
|
|
38
|
+
|-----|------|
|
|
39
|
+
| `{WORKTREE_DIR}` | `.claude/worktrees` |
|
|
40
|
+
| `{WORKTREE_slug}` | `{WORKTREE_DIR}/feat-{slug}` |
|
|
41
|
+
| `{MURM_QUEUE}` | `.claude/murm-queue.json` |
|
|
42
|
+
| `{MURM_LOCK}` | `.claude/murm.lock` |
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 3. Add Multi-Feature Pipeline Overview (insert after line 65)
|
|
48
|
+
|
|
49
|
+
```markdown
|
|
50
|
+
## Multi-Feature Pipeline Overview
|
|
51
|
+
|
|
52
|
+
When multiple slugs are provided, the pipeline uses worktree isolation and parallel Task sub-agents:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
/implement-feature slug-a slug-b slug-c
|
|
56
|
+
│
|
|
57
|
+
▼
|
|
58
|
+
┌─────────────────────────────────────────────────────┐
|
|
59
|
+
│ M0. Detect multi-feature mode │
|
|
60
|
+
│ M1. Pre-flight validation for ALL features │
|
|
61
|
+
│ M2. Check for file overlap conflicts │
|
|
62
|
+
│ M3. Create git worktrees (one per feature) │
|
|
63
|
+
└─────────────────────────────────────────────────────┘
|
|
64
|
+
│
|
|
65
|
+
▼
|
|
66
|
+
┌─────────────────────────────────────────────────────┐
|
|
67
|
+
│ M4. Spawn PARALLEL Task sub-agents │
|
|
68
|
+
│ │
|
|
69
|
+
│ Task(slug-a) ─┐ │
|
|
70
|
+
│ Task(slug-b) ─┼─► Run concurrently │
|
|
71
|
+
│ Task(slug-c) ─┘ │
|
|
72
|
+
│ │
|
|
73
|
+
│ Each Task runs full pipeline in its worktree: │
|
|
74
|
+
│ Alex → [Cass] → Nigel → Codey │
|
|
75
|
+
└─────────────────────────────────────────────────────┘
|
|
76
|
+
│
|
|
77
|
+
▼
|
|
78
|
+
┌─────────────────────────────────────────────────────┐
|
|
79
|
+
│ M5. Collect results as sub-agents complete │
|
|
80
|
+
│ M6. Merge successful features to main │
|
|
81
|
+
│ M7. Report conflicts/failures │
|
|
82
|
+
│ M8. Cleanup worktrees │
|
|
83
|
+
└─────────────────────────────────────────────────────┘
|
|
84
|
+
```
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 4. Add Step M0-M3: Multi-Feature Setup (new section after Step 0)
|
|
90
|
+
|
|
91
|
+
```markdown
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Step M0: Multi-Feature Detection
|
|
95
|
+
|
|
96
|
+
**Trigger:** More than one slug provided in arguments.
|
|
97
|
+
|
|
98
|
+
Parse all slugs from arguments:
|
|
99
|
+
```
|
|
100
|
+
/implement-feature feat-a feat-b feat-c --no-commit
|
|
101
|
+
→ slugs = ["feat-a", "feat-b", "feat-c"]
|
|
102
|
+
→ flags = { noCommit: true }
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If `slugs.length > 1`: Enter murmuration mode (Steps M1-M8)
|
|
106
|
+
If `slugs.length === 1`: Continue to Step 1 (single-feature mode)
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Step M1: Multi-Feature Pre-flight Validation
|
|
111
|
+
|
|
112
|
+
For EACH slug, verify:
|
|
113
|
+
1. Feature spec exists at `.blueprint/features/feature_{slug}/FEATURE_SPEC.md`
|
|
114
|
+
2. Spec has required sections (Intent, Scope, Actors)
|
|
115
|
+
|
|
116
|
+
**Display validation table:**
|
|
117
|
+
```
|
|
118
|
+
Pre-flight Validation
|
|
119
|
+
=====================
|
|
120
|
+
|
|
121
|
+
✓ feat-a: Spec complete, 3 stories
|
|
122
|
+
✓ feat-b: Spec complete, 2 stories
|
|
123
|
+
✗ feat-c: Missing FEATURE_SPEC.md
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**On any failure:**
|
|
127
|
+
- Show which features are not ready
|
|
128
|
+
- Suggest: `/implement-feature "feat-c" --pause-after=alex` to create spec
|
|
129
|
+
- Ask: "Continue with ready features only?" or "Abort"
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Step M2: Conflict Detection
|
|
134
|
+
|
|
135
|
+
Scan implementation plans (if they exist) for file overlap:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# For each feature with IMPLEMENTATION_PLAN.md, extract "Files to Create/Modify"
|
|
139
|
+
grep -h "src/\|lib/\|bin/" .blueprint/features/feature_*/IMPLEMENTATION_PLAN.md
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Display if conflicts found:**
|
|
143
|
+
```
|
|
144
|
+
Conflict Analysis
|
|
145
|
+
=================
|
|
146
|
+
|
|
147
|
+
⚠ File overlap detected:
|
|
148
|
+
• src/utils.js: feat-a, feat-b both modify
|
|
149
|
+
|
|
150
|
+
Recommendation: Run feat-a and feat-b sequentially, or resolve manually.
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**On conflict:** Ask user to confirm or adjust feature list.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Step M3: Create Worktrees
|
|
158
|
+
|
|
159
|
+
For each validated slug, create an isolated git worktree:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Ensure clean working tree
|
|
163
|
+
git status --porcelain
|
|
164
|
+
|
|
165
|
+
# Create worktrees
|
|
166
|
+
git worktree add .claude/worktrees/feat-{slug-a} -b feature/{slug-a}
|
|
167
|
+
git worktree add .claude/worktrees/feat-{slug-b} -b feature/{slug-b}
|
|
168
|
+
git worktree add .claude/worktrees/feat-{slug-c} -b feature/{slug-c}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Announce:**
|
|
172
|
+
```
|
|
173
|
+
Creating worktrees...
|
|
174
|
+
✓ .claude/worktrees/feat-a → branch feature/feat-a
|
|
175
|
+
✓ .claude/worktrees/feat-b → branch feature/feat-b
|
|
176
|
+
✓ .claude/worktrees/feat-c → branch feature/feat-c
|
|
177
|
+
```
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 5. Add Step M4: Parallel Pipeline Execution (the key change)
|
|
183
|
+
|
|
184
|
+
```markdown
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Step M4: Spawn Parallel Feature Pipelines
|
|
188
|
+
|
|
189
|
+
**CRITICAL:** Use multiple Task tool calls IN THE SAME MESSAGE to run concurrently.
|
|
190
|
+
|
|
191
|
+
For each feature, spawn a Task sub-agent that runs the COMPLETE pipeline in its worktree.
|
|
192
|
+
|
|
193
|
+
**Spawn all Task sub-agents in parallel:**
|
|
194
|
+
|
|
195
|
+
### Task for {slug-a}:
|
|
196
|
+
Use the Task tool with `subagent_type="general-purpose"`:
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
You are running the implement-feature pipeline for "{slug-a}".
|
|
200
|
+
|
|
201
|
+
## Working Directory
|
|
202
|
+
All file operations must be relative to: .claude/worktrees/feat-{slug-a}
|
|
203
|
+
|
|
204
|
+
## Task
|
|
205
|
+
Run the complete feature pipeline:
|
|
206
|
+
|
|
207
|
+
1. **Alex** — Read feature spec, create/verify handoff summary
|
|
208
|
+
- Input: .claude/worktrees/feat-{slug-a}/.blueprint/features/feature_{slug-a}/FEATURE_SPEC.md
|
|
209
|
+
- Output: handoff-alex.md (if missing)
|
|
210
|
+
|
|
211
|
+
2. **Classify** — Determine if technical or user-facing
|
|
212
|
+
- Technical (refactoring, optimization, infra): Skip to Nigel
|
|
213
|
+
- User-facing: Continue to Cass
|
|
214
|
+
|
|
215
|
+
3. **Cass** (if user-facing) — Write user stories
|
|
216
|
+
- Output: story-*.md files, handoff-cass.md
|
|
217
|
+
|
|
218
|
+
4. **Nigel** — Create tests
|
|
219
|
+
- Output: test/artifacts/feature_{slug-a}/test-spec.md
|
|
220
|
+
- Output: test/feature_{slug-a}.test.js
|
|
221
|
+
- Output: handoff-nigel.md
|
|
222
|
+
|
|
223
|
+
5. **Codey Plan** — Create implementation plan
|
|
224
|
+
- Output: IMPLEMENTATION_PLAN.md
|
|
225
|
+
|
|
226
|
+
6. **Codey Implement** — Write code to pass tests
|
|
227
|
+
- Run tests: node --test test/feature_{slug-a}.test.js
|
|
228
|
+
- Iterate until tests pass
|
|
229
|
+
|
|
230
|
+
## Rules
|
|
231
|
+
- Work ONLY in .claude/worktrees/feat-{slug-a}
|
|
232
|
+
- Do NOT commit changes
|
|
233
|
+
- Do NOT modify files outside the worktree
|
|
234
|
+
- Report final status: success/failed + summary
|
|
235
|
+
|
|
236
|
+
## Completion
|
|
237
|
+
Return JSON status:
|
|
238
|
+
{"slug": "{slug-a}", "status": "success|failed", "tests": "X/Y passing", "files": ["list"]}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Task for {slug-b}:
|
|
242
|
+
(Same prompt structure, different slug and worktree path)
|
|
243
|
+
|
|
244
|
+
### Task for {slug-c}:
|
|
245
|
+
(Same prompt structure, different slug and worktree path)
|
|
246
|
+
|
|
247
|
+
**Key:** All three Task tool calls are made in a SINGLE assistant message, enabling concurrent execution.
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 6. Add Step M5-M8: Results & Cleanup (new section)
|
|
253
|
+
|
|
254
|
+
```markdown
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Step M5: Collect Results
|
|
258
|
+
|
|
259
|
+
As each Task sub-agent completes, collect its status:
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
results = [
|
|
263
|
+
{ slug: "feat-a", status: "success", tests: "5/5", files: [...] },
|
|
264
|
+
{ slug: "feat-b", status: "success", tests: "3/3", files: [...] },
|
|
265
|
+
{ slug: "feat-c", status: "failed", error: "Nigel tests failed" }
|
|
266
|
+
]
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Step M6: Merge Successful Features
|
|
272
|
+
|
|
273
|
+
For each feature with `status: "success"`:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# Switch to main
|
|
277
|
+
git checkout main
|
|
278
|
+
|
|
279
|
+
# Merge feature branch
|
|
280
|
+
git merge feature/{slug} --no-edit
|
|
281
|
+
|
|
282
|
+
# On success: record merge
|
|
283
|
+
# On conflict: preserve branch for manual resolution
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Handle merge conflicts:**
|
|
287
|
+
- Do NOT force or abort
|
|
288
|
+
- Record conflict: `{ slug, status: "conflict", branch: "feature/{slug}" }`
|
|
289
|
+
- Worktree preserved for manual resolution
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Step M7: Report Summary
|
|
294
|
+
|
|
295
|
+
**Display murmuration summary:**
|
|
296
|
+
```
|
|
297
|
+
--- Murmuration Complete ---
|
|
298
|
+
|
|
299
|
+
## Landed (merged to main)
|
|
300
|
+
✓ feat-a: 5 tests, 3 files
|
|
301
|
+
✓ feat-b: 3 tests, 2 files
|
|
302
|
+
|
|
303
|
+
## Turbulence (merge conflicts)
|
|
304
|
+
⚠ (none)
|
|
305
|
+
|
|
306
|
+
## Lost Formation (failed)
|
|
307
|
+
✗ feat-c: Nigel tests failed
|
|
308
|
+
Worktree preserved: .claude/worktrees/feat-c
|
|
309
|
+
To retry: cd .claude/worktrees/feat-c && /implement-feature feat-c
|
|
310
|
+
|
|
311
|
+
## Next Steps
|
|
312
|
+
- Run `node --test` to verify all tests pass
|
|
313
|
+
- Review any preserved worktrees
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Step M8: Cleanup Worktrees
|
|
319
|
+
|
|
320
|
+
For successfully merged features:
|
|
321
|
+
```bash
|
|
322
|
+
git worktree remove .claude/worktrees/feat-{slug} --force
|
|
323
|
+
git branch -d feature/{slug}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Preserve worktrees for:
|
|
327
|
+
- Failed features (for debugging)
|
|
328
|
+
- Merge conflicts (for manual resolution)
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Summary of Changes
|
|
334
|
+
|
|
335
|
+
| Section | Change Type | Description |
|
|
336
|
+
|---------|-------------|-------------|
|
|
337
|
+
| Invocation | Modify | Add multi-slug syntax |
|
|
338
|
+
| Paths | Add | Worktree path variables |
|
|
339
|
+
| Pipeline Overview | Add | Multi-feature flow diagram |
|
|
340
|
+
| Step M0 | Add | Multi-feature detection |
|
|
341
|
+
| Step M1 | Add | Batch pre-flight validation |
|
|
342
|
+
| Step M2 | Add | Conflict detection |
|
|
343
|
+
| Step M3 | Add | Worktree creation |
|
|
344
|
+
| Step M4 | Add | **Parallel Task spawning** |
|
|
345
|
+
| Step M5-M8 | Add | Results, merge, cleanup |
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Feature Specification — Split CLI Commands
|
|
2
|
+
|
|
3
|
+
## 1. Feature Intent
|
|
4
|
+
**Why this feature exists.**
|
|
5
|
+
|
|
6
|
+
- `bin/cli.js` is 437 lines and growing — difficult to navigate and maintain
|
|
7
|
+
- Command logic is mixed with routing, flag parsing, and help text
|
|
8
|
+
- Adding new commands requires editing one large file
|
|
9
|
+
- Supports modular architecture and separation of concerns
|
|
10
|
+
|
|
11
|
+
> Technical refactoring feature — no user-facing behaviour change.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Scope
|
|
16
|
+
### In Scope
|
|
17
|
+
- Extract each command handler to `src/commands/<command>.js`
|
|
18
|
+
- Reduce `bin/cli.js` to a thin router (~50-80 lines)
|
|
19
|
+
- Preserve all existing CLI behaviour exactly
|
|
20
|
+
- Maintain backward compatibility with all command aliases
|
|
21
|
+
|
|
22
|
+
### Out of Scope
|
|
23
|
+
- Adding new commands
|
|
24
|
+
- Changing command syntax or flags
|
|
25
|
+
- Modifying help text content (only moving it)
|
|
26
|
+
- Performance optimizations
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 3. Actors Involved
|
|
31
|
+
**Who interacts with this feature.**
|
|
32
|
+
|
|
33
|
+
- **Developer**: Edits individual command files instead of monolithic cli.js
|
|
34
|
+
- **CLI User**: No change in experience — all commands work identically
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 4. Behaviour Overview
|
|
39
|
+
**What the feature does, conceptually.**
|
|
40
|
+
|
|
41
|
+
- `bin/cli.js` becomes a router that:
|
|
42
|
+
1. Parses the command name from `process.argv`
|
|
43
|
+
2. Dynamically loads the appropriate handler from `src/commands/`
|
|
44
|
+
3. Passes args and invokes the handler
|
|
45
|
+
4. Handles errors and exit codes
|
|
46
|
+
|
|
47
|
+
- Each `src/commands/<name>.js` exports:
|
|
48
|
+
- `run(args)` — the command handler
|
|
49
|
+
- `description` — short description for help
|
|
50
|
+
- `help()` — detailed help text (optional)
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 5. State & Lifecycle Interactions
|
|
55
|
+
**How this feature touches the system lifecycle.**
|
|
56
|
+
|
|
57
|
+
- No state changes — pure refactoring
|
|
58
|
+
- File system structure changes only
|
|
59
|
+
- No runtime behaviour differences
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 6. Rules & Decision Logic
|
|
64
|
+
**New or exercised rules.**
|
|
65
|
+
|
|
66
|
+
| Rule | Description |
|
|
67
|
+
|------|-------------|
|
|
68
|
+
| Command mapping | Command name maps to `src/commands/<name>.js` |
|
|
69
|
+
| Alias resolution | Aliases (murm/parallel/murmuration) resolve before loading |
|
|
70
|
+
| Flag parsing | Remains in individual command handlers, not centralized |
|
|
71
|
+
| Error handling | Each command handles its own errors; router catches unhandled |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 7. Dependencies
|
|
76
|
+
**What this feature relies on.**
|
|
77
|
+
|
|
78
|
+
- Node.js `require()` for dynamic loading
|
|
79
|
+
- Existing module structure in `src/`
|
|
80
|
+
- No external dependencies added
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 8. Non-Functional Considerations
|
|
85
|
+
|
|
86
|
+
- **Startup time**: Lazy loading commands means faster startup for simple commands
|
|
87
|
+
- **Testability**: Individual command files are easier to unit test
|
|
88
|
+
- **Maintainability**: Clear ownership of each command
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 9. Assumptions & Open Questions
|
|
93
|
+
|
|
94
|
+
**Assumptions:**
|
|
95
|
+
- All commands can be cleanly extracted without shared state
|
|
96
|
+
- The `parseFlags()` helper can remain in cli.js or move to a utility
|
|
97
|
+
|
|
98
|
+
**Open Questions:**
|
|
99
|
+
- Should `parseFlags()` move to `src/utils.js` or stay in cli.js?
|
|
100
|
+
- Should command files include their own validation or use a shared validator?
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 10. Impact on System Specification
|
|
105
|
+
|
|
106
|
+
- No impact — internal refactoring only
|
|
107
|
+
- Does not change system boundaries or behaviour
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 11. Handover to BA (Cass)
|
|
112
|
+
|
|
113
|
+
**Skip Cass stage** — this is a technical refactoring feature with no user stories needed.
|
|
114
|
+
|
|
115
|
+
Direct handover to Nigel for test creation:
|
|
116
|
+
- Tests should verify all commands still work after extraction
|
|
117
|
+
- Tests should verify help output is unchanged
|
|
118
|
+
- Tests should verify error handling is preserved
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 12. Change Log (Feature-Level)
|
|
123
|
+
| Date | Change | Reason | Raised By |
|
|
124
|
+
|------|--------|--------|-----------|
|
|
125
|
+
| 2026-03-03 | Initial spec | Technical debt reduction | Alex |
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Implementation Plan: Split CLI Commands
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Extract command handlers from `bin/cli.js` (437 lines) into `src/commands/` directory, leaving a thin router (~50-80 lines).
|
|
5
|
+
|
|
6
|
+
## Phase 1: Create Directory Structure
|
|
7
|
+
- Create `src/commands/` directory
|
|
8
|
+
- Create `src/commands/utils.js` for shared utilities (parseFlags)
|
|
9
|
+
|
|
10
|
+
## Phase 2: Extract Commands (in order of complexity)
|
|
11
|
+
|
|
12
|
+
### Simple Commands (no subcommands)
|
|
13
|
+
1. **init.js** - Direct passthrough to `src/init.js`
|
|
14
|
+
2. **update.js** - Direct passthrough to `src/update.js`
|
|
15
|
+
3. **help.js** - Contains showHelp() function
|
|
16
|
+
|
|
17
|
+
### Commands with Flags
|
|
18
|
+
4. **validate.js** - Calls validate(), formats output, sets exit code
|
|
19
|
+
5. **insights.js** - Handles --bottlenecks, --failures, --json, --feedback flags
|
|
20
|
+
|
|
21
|
+
### Commands with Subcommands
|
|
22
|
+
6. **queue.js** - Handles `reset` subcommand
|
|
23
|
+
7. **history.js** - Handles `clear`, `export`, --stats, --all flags
|
|
24
|
+
8. **retry-config.js** - Handles `set`, `reset` subcommands
|
|
25
|
+
9. **feedback-config.js** - Handles `set`, `reset` subcommands
|
|
26
|
+
10. **stack-config.js** - Handles `set`, `reset` subcommands
|
|
27
|
+
11. **murm-config.js** - Handles `set`, `reset` subcommands (with aliases)
|
|
28
|
+
|
|
29
|
+
### Complex Commands
|
|
30
|
+
12. **murm.js** - Handles status, rollback, cleanup, abort subcommands + main execution (with aliases)
|
|
31
|
+
|
|
32
|
+
## Phase 3: Refactor Router
|
|
33
|
+
- Replace inline handlers with dynamic loading from `src/commands/`
|
|
34
|
+
- Handle aliases in router (murm/parallel/murmuration, murm-config/parallel-config)
|
|
35
|
+
- Keep under 100 lines
|
|
36
|
+
|
|
37
|
+
## File Structure After Refactoring
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
src/commands/
|
|
41
|
+
init.js
|
|
42
|
+
update.js
|
|
43
|
+
queue.js
|
|
44
|
+
validate.js
|
|
45
|
+
history.js
|
|
46
|
+
insights.js
|
|
47
|
+
retry-config.js
|
|
48
|
+
feedback-config.js
|
|
49
|
+
stack-config.js
|
|
50
|
+
murm-config.js
|
|
51
|
+
murm.js
|
|
52
|
+
help.js
|
|
53
|
+
utils.js # parseFlags helper
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Command Module Template
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
// src/commands/<name>.js
|
|
60
|
+
const description = 'Short description for help';
|
|
61
|
+
|
|
62
|
+
async function run(args) {
|
|
63
|
+
// Command implementation
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = { run, description };
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Router Template (bin/cli.js)
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
#!/usr/bin/env node
|
|
73
|
+
const path = require('path');
|
|
74
|
+
|
|
75
|
+
const args = process.argv.slice(2);
|
|
76
|
+
const command = args[0];
|
|
77
|
+
|
|
78
|
+
// Alias resolution
|
|
79
|
+
const aliases = {
|
|
80
|
+
'parallel': 'murm',
|
|
81
|
+
'murmuration': 'murm',
|
|
82
|
+
'parallel-config': 'murm-config'
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const resolvedCommand = aliases[command] || command;
|
|
86
|
+
|
|
87
|
+
// Dynamic loading
|
|
88
|
+
async function main() {
|
|
89
|
+
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
90
|
+
const help = require('../src/commands/help');
|
|
91
|
+
help.run(args);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const cmdPath = path.join(__dirname, '../src/commands', `${resolvedCommand}.js`);
|
|
96
|
+
try {
|
|
97
|
+
const cmd = require(cmdPath);
|
|
98
|
+
await cmd.run(args);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
if (err.code === 'MODULE_NOT_FOUND') {
|
|
101
|
+
console.error(`Unknown command: ${command}`);
|
|
102
|
+
console.error('Run "agent-workflow help" for usage information.');
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
main().catch(err => {
|
|
110
|
+
console.error(`Error: ${err.message}`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Test Command
|
|
116
|
+
```bash
|
|
117
|
+
cd /workspaces/agent-workflow/.claude/worktrees/feat-split-cli-commands
|
|
118
|
+
node --test test/feature_split-cli-commands.test.js
|
|
119
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Handoff: Nigel -> Codey
|
|
2
|
+
|
|
3
|
+
## Feature: split-cli-commands
|
|
4
|
+
|
|
5
|
+
## Test Summary
|
|
6
|
+
- **Test file**: `test/feature_split-cli-commands.test.js`
|
|
7
|
+
- **Test count**: 26 test cases
|
|
8
|
+
- **Coverage**: Module structure, aliases, router constraints, command descriptions
|
|
9
|
+
|
|
10
|
+
## Key Test Requirements
|
|
11
|
+
|
|
12
|
+
1. **Directory structure**: `src/commands/` must exist with 12 command modules
|
|
13
|
+
2. **Module interface**: Each command exports `run(args)` function and `description` string
|
|
14
|
+
3. **Router constraint**: `bin/cli.js` must be <= 100 lines (thin router)
|
|
15
|
+
4. **Aliases**: murm/parallel/murmuration and murm-config/parallel-config must work
|
|
16
|
+
|
|
17
|
+
## Commands to Extract
|
|
18
|
+
|
|
19
|
+
| Command | Source Lines (approx) |
|
|
20
|
+
|---------|----------------------|
|
|
21
|
+
| init | 3 lines |
|
|
22
|
+
| update | 3 lines |
|
|
23
|
+
| queue | 8 lines |
|
|
24
|
+
| validate | 8 lines |
|
|
25
|
+
| history | 28 lines |
|
|
26
|
+
| insights | 12 lines |
|
|
27
|
+
| retry-config | 16 lines |
|
|
28
|
+
| feedback-config | 16 lines |
|
|
29
|
+
| stack-config | 16 lines |
|
|
30
|
+
| murm-config | 34 lines |
|
|
31
|
+
| murm (parallel) | 86 lines |
|
|
32
|
+
| help | 68 lines |
|
|
33
|
+
|
|
34
|
+
## Implementation Notes
|
|
35
|
+
|
|
36
|
+
- `parseFlags()` helper can stay in cli.js or move to `src/commands/utils.js`
|
|
37
|
+
- Aliases should be handled in the router, not in individual commands
|
|
38
|
+
- Each command file should be self-contained with its imports
|
|
39
|
+
- Help text for each command should match current output exactly
|
|
40
|
+
|
|
41
|
+
## Run Tests
|
|
42
|
+
```bash
|
|
43
|
+
cd /workspaces/agent-workflow/.claude/worktrees/feat-split-cli-commands
|
|
44
|
+
node --test test/feature_split-cli-commands.test.js
|
|
45
|
+
```
|