specweave 0.23.10 → 0.23.12
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/.claude-plugin/marketplace.json +7 -7
- package/CLAUDE.md +384 -1449
- package/dist/src/cli/commands/cleanup-cache.d.ts +14 -0
- package/dist/src/cli/commands/cleanup-cache.d.ts.map +1 -0
- package/dist/src/cli/commands/cleanup-cache.js +63 -0
- package/dist/src/cli/commands/cleanup-cache.js.map +1 -0
- package/dist/src/cli/commands/init.js +40 -0
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/async-project-loader.d.ts +148 -0
- package/dist/src/cli/helpers/async-project-loader.d.ts.map +1 -0
- package/dist/src/cli/helpers/async-project-loader.js +351 -0
- package/dist/src/cli/helpers/async-project-loader.js.map +1 -0
- package/dist/src/cli/helpers/cancelation-handler.d.ts +123 -0
- package/dist/src/cli/helpers/cancelation-handler.d.ts.map +1 -0
- package/dist/src/cli/helpers/cancelation-handler.js +187 -0
- package/dist/src/cli/helpers/cancelation-handler.js.map +1 -0
- package/dist/src/cli/helpers/import-strategy-prompter.d.ts +43 -0
- package/dist/src/cli/helpers/import-strategy-prompter.d.ts.map +1 -0
- package/dist/src/cli/helpers/import-strategy-prompter.js +136 -0
- package/dist/src/cli/helpers/import-strategy-prompter.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts +5 -2
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/ado.js +90 -40
- package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts +2 -1
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.js +120 -35
- package/dist/src/cli/helpers/issue-tracker/jira.js.map +1 -1
- package/dist/src/cli/helpers/progress-tracker.d.ts +121 -0
- package/dist/src/cli/helpers/progress-tracker.d.ts.map +1 -0
- package/dist/src/cli/helpers/progress-tracker.js +202 -0
- package/dist/src/cli/helpers/progress-tracker.js.map +1 -0
- package/dist/src/cli/helpers/project-count-fetcher.d.ts +69 -0
- package/dist/src/cli/helpers/project-count-fetcher.d.ts.map +1 -0
- package/dist/src/cli/helpers/project-count-fetcher.js +173 -0
- package/dist/src/cli/helpers/project-count-fetcher.js.map +1 -0
- package/dist/src/config/types.d.ts +14 -14
- package/dist/src/core/cache/cache-manager.d.ts +119 -0
- package/dist/src/core/cache/cache-manager.d.ts.map +1 -0
- package/dist/src/core/cache/cache-manager.js +304 -0
- package/dist/src/core/cache/cache-manager.js.map +1 -0
- package/dist/src/core/cache/rate-limit-checker.d.ts +92 -0
- package/dist/src/core/cache/rate-limit-checker.d.ts.map +1 -0
- package/dist/src/core/cache/rate-limit-checker.js +160 -0
- package/dist/src/core/cache/rate-limit-checker.js.map +1 -0
- package/dist/src/core/progress/cancelation-handler.d.ts +79 -0
- package/dist/src/core/progress/cancelation-handler.d.ts.map +1 -0
- package/dist/src/core/progress/cancelation-handler.js +111 -0
- package/dist/src/core/progress/cancelation-handler.js.map +1 -0
- package/dist/src/core/progress/import-state.d.ts +71 -0
- package/dist/src/core/progress/import-state.d.ts.map +1 -0
- package/dist/src/core/progress/import-state.js +96 -0
- package/dist/src/core/progress/import-state.js.map +1 -0
- package/dist/src/core/progress/progress-tracker.d.ts +139 -0
- package/dist/src/core/progress/progress-tracker.d.ts.map +1 -0
- package/dist/src/core/progress/progress-tracker.js +223 -0
- package/dist/src/core/progress/progress-tracker.js.map +1 -0
- package/dist/src/init/architecture/types.d.ts +6 -6
- package/dist/src/integrations/ado/ado-client.d.ts +25 -0
- package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
- package/dist/src/integrations/ado/ado-client.js +67 -0
- package/dist/src/integrations/ado/ado-client.js.map +1 -1
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts +99 -0
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts.map +1 -0
- package/dist/src/integrations/ado/ado-dependency-loader.js +207 -0
- package/dist/src/integrations/ado/ado-dependency-loader.js.map +1 -0
- package/dist/src/integrations/jira/jira-client.d.ts +32 -0
- package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-client.js +81 -0
- package/dist/src/integrations/jira/jira-client.js.map +1 -1
- package/dist/src/integrations/jira/jira-dependency-loader.d.ts +101 -0
- package/dist/src/integrations/jira/jira-dependency-loader.d.ts.map +1 -0
- package/dist/src/integrations/jira/jira-dependency-loader.js +200 -0
- package/dist/src/integrations/jira/jira-dependency-loader.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +20 -0
- package/plugins/specweave/agents/architect/AGENT.md +100 -602
- package/plugins/specweave/agents/pm/AGENT.md +96 -597
- package/plugins/specweave/agents/pm/AGENT.md.bak +1893 -0
- package/plugins/specweave/agents/pm/AGENT.md.bak2 +1754 -0
- package/plugins/specweave/commands/check-hooks.md +257 -0
- package/plugins/specweave/hooks/post-edit-spec.sh +202 -31
- package/plugins/specweave/hooks/post-task-completion.sh +225 -228
- package/plugins/specweave/hooks/post-write-spec.sh +207 -31
- package/plugins/specweave/hooks/pre-edit-spec.sh +151 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +5 -7
- package/plugins/specweave/hooks/pre-write-spec.sh +151 -0
- package/plugins/specweave/hooks/test-pretooluse-env.sh +72 -0
- package/plugins/specweave/skills/compliance-architecture/SKILL.md +374 -0
- package/plugins/specweave/skills/external-sync-wizard/SKILL.md +610 -0
- package/plugins/specweave/skills/pm-closure-validation/SKILL.md +541 -0
- package/plugins/specweave/skills/roadmap-planner/SKILL.md +473 -0
- package/plugins/specweave-ado/commands/refresh-cache.js +25 -0
- package/plugins/specweave-ado/commands/refresh-cache.ts +40 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh +1 -1
- package/plugins/specweave-github/hooks/post-task-completion.sh +1 -1
- package/plugins/specweave-jira/commands/refresh-cache.js +25 -0
- package/plugins/specweave-jira/commands/refresh-cache.ts +40 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh +1 -1
- package/plugins/specweave-kafka-streams/commands/topology.md +437 -0
- package/plugins/specweave-n8n/commands/workflow-template.md +262 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +228 -6465
package/CLAUDE.md
CHANGED
|
@@ -10,1749 +10,684 @@ For **contributors to SpecWeave itself** (not users).
|
|
|
10
10
|
|
|
11
11
|
## 🚨 CRITICAL SAFETY RULES
|
|
12
12
|
|
|
13
|
-
### 0.
|
|
13
|
+
### 0. Think-Then-Act Discipline (META RULE!)
|
|
14
14
|
|
|
15
|
-
**
|
|
15
|
+
**NEVER run commands you know will fail.** Act on reasoning BEFORE execution.
|
|
16
16
|
|
|
17
|
-
**
|
|
17
|
+
**Common patterns:**
|
|
18
|
+
- Running code before compilation → `npm run rebuild` FIRST
|
|
19
|
+
- Database queries before migrations/setup
|
|
20
|
+
- File ops before directory creation
|
|
18
21
|
|
|
19
22
|
```typescript
|
|
20
|
-
// ❌ WRONG: Attempt →
|
|
21
|
-
node -e "require('./dist/file.js')" //
|
|
22
|
-
npm run rebuild
|
|
23
|
+
// ❌ WRONG: Attempt → Fail → Fix
|
|
24
|
+
node -e "require('./dist/file.js')" // You knew this would fail!
|
|
25
|
+
npm run rebuild
|
|
23
26
|
|
|
24
|
-
// ✅ CORRECT:
|
|
25
|
-
npm run rebuild
|
|
26
|
-
node -e "require('./dist/file.js')"
|
|
27
|
+
// ✅ CORRECT: Fix → Attempt
|
|
28
|
+
npm run rebuild
|
|
29
|
+
node -e "require('./dist/file.js')"
|
|
27
30
|
```
|
|
28
31
|
|
|
29
|
-
**Why**: Wastes time, creates confusion, makes execution harder to follow.
|
|
30
|
-
|
|
31
|
-
**How to avoid**:
|
|
32
|
-
1. **Read your own thinking process** - What dependencies did you identify?
|
|
33
|
-
2. **Order operations logically** - Prerequisites BEFORE dependent operations
|
|
34
|
-
3. **Catch predictable failures** - If you know it will fail, don't run it yet
|
|
35
|
-
|
|
36
|
-
**Example patterns to watch for**:
|
|
37
|
-
- Running code before compilation (`tsc`, `npm run build`)
|
|
38
|
-
- Database queries before migrations/setup
|
|
39
|
-
- API calls before authentication
|
|
40
|
-
- File operations before directory creation
|
|
41
|
-
|
|
42
32
|
---
|
|
43
33
|
|
|
44
34
|
### 1. Local Development Setup
|
|
45
35
|
|
|
46
|
-
**
|
|
47
|
-
|
|
48
|
-
#### Quick Start (Recommended - All Platforms)
|
|
36
|
+
**Standard Workflow** (Cross-platform):
|
|
49
37
|
|
|
50
38
|
```bash
|
|
51
|
-
#
|
|
39
|
+
# Setup
|
|
52
40
|
git clone https://github.com/YOUR_USERNAME/specweave.git
|
|
53
|
-
cd specweave
|
|
54
|
-
npm install
|
|
55
|
-
|
|
56
|
-
# 2. Build TypeScript
|
|
57
|
-
npm run rebuild
|
|
58
|
-
|
|
59
|
-
# 3. That's it! Claude Code auto-installs from GitHub marketplace
|
|
60
|
-
# Hooks execute from: ~/.claude/plugins/marketplaces/specweave/
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
#### Development Workflow
|
|
41
|
+
cd specweave && npm install && npm run rebuild
|
|
64
42
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
# 1. Make changes in local repo
|
|
43
|
+
# Development Cycle
|
|
69
44
|
vim src/core/task-parser.ts
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
npm run rebuild
|
|
73
|
-
|
|
74
|
-
# 3. Test locally
|
|
75
|
-
npm test
|
|
76
|
-
|
|
77
|
-
# 4. Commit and push to your branch
|
|
78
|
-
git add . && git commit -m "feat: new feature"
|
|
79
|
-
git push origin develop
|
|
80
|
-
|
|
81
|
-
# 5. Wait 5-10 seconds → Claude Code auto-updates marketplace
|
|
82
|
-
|
|
83
|
-
# 6. Test in Claude Code
|
|
84
|
-
/specweave:increment "test feature"
|
|
85
|
-
# Your latest hooks now execute automatically!
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
**For hook-only changes** (no TypeScript build needed):
|
|
89
|
-
```bash
|
|
90
|
-
vim plugins/specweave/hooks/post-task-completion.sh
|
|
91
|
-
git add . && git commit -m "fix: improve hook logic"
|
|
45
|
+
npm run rebuild && npm test
|
|
46
|
+
git add . && git commit -m "feat: feature"
|
|
92
47
|
git push origin develop
|
|
93
|
-
# Wait 5-
|
|
48
|
+
# Wait 5-10s → Claude Code auto-updates marketplace
|
|
94
49
|
```
|
|
95
50
|
|
|
96
|
-
**
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
- ✅ **Team-friendly** (everyone gets updates automatically)
|
|
51
|
+
**Testing Unpushed Changes:**
|
|
52
|
+
- **Option 1**: Temp branch → push → test → delete
|
|
53
|
+
- **Option 2**: Fork-based (`claude plugin marketplace add github:YOUR_USERNAME/specweave`)
|
|
54
|
+
- **Option 3**: Symlink (Unix-only, see `.specweave/docs/internal/advanced/symlink-dev-mode.md`)
|
|
101
55
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
**Option 1: Temporary Branch** (Recommended)
|
|
105
|
-
```bash
|
|
106
|
-
# Create throwaway test branch
|
|
107
|
-
git checkout -b temp-test-$(date +%s)
|
|
108
|
-
git add . && git commit -m "temp: testing unpushed changes"
|
|
109
|
-
git push origin temp-test-1234567890
|
|
110
|
-
|
|
111
|
-
# Claude Code pulls from your test branch (5-10 seconds)
|
|
112
|
-
# Test your changes...
|
|
113
|
-
|
|
114
|
-
# Clean up when done
|
|
115
|
-
git push origin --delete temp-test-1234567890
|
|
116
|
-
git checkout develop && git branch -D temp-test-1234567890
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
**Option 2: Fork-Based Development**
|
|
120
|
-
```bash
|
|
121
|
-
# One-time: Point Claude Code to your fork
|
|
122
|
-
claude plugin marketplace remove specweave
|
|
123
|
-
claude plugin marketplace add github:YOUR_USERNAME/specweave
|
|
124
|
-
|
|
125
|
-
# Now push to your fork's branch
|
|
126
|
-
git push origin develop
|
|
127
|
-
# Claude Code pulls from YOUR fork, not upstream
|
|
128
|
-
```
|
|
56
|
+
---
|
|
129
57
|
|
|
130
|
-
|
|
131
|
-
If you need **instant updates** without pushing (e.g., rapid hook iteration):
|
|
132
|
-
- See: `.specweave/docs/internal/advanced/symlink-dev-mode.md`
|
|
133
|
-
- ⚠️ **Warning**: Only works on macOS/Linux, not Windows
|
|
134
|
-
- ⚠️ Requires bash scripts, registry manipulation, ongoing maintenance
|
|
58
|
+
### 2. Increment Folder Structure
|
|
135
59
|
|
|
136
|
-
|
|
60
|
+
**ONLY 4 files in `.specweave/increments/####/` root**: `spec.md`, `plan.md`, `tasks.md`, `metadata.json`
|
|
137
61
|
|
|
138
|
-
|
|
62
|
+
**Everything else → subfolders**: `reports/`, `scripts/`, `logs/`
|
|
139
63
|
|
|
140
64
|
```bash
|
|
141
|
-
#
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
# 2. Test in fresh directory
|
|
145
|
-
cd /tmp && mkdir test-project && cd test-project
|
|
146
|
-
specweave init .
|
|
147
|
-
# ... test end-user workflows ...
|
|
148
|
-
|
|
149
|
-
# 3. Resume development
|
|
150
|
-
cd /path/to/specweave/repo
|
|
151
|
-
# Claude Code automatically switches back to marketplace mode
|
|
65
|
+
# ❌ WRONG: .specweave/increments/0046/analysis-report.md
|
|
66
|
+
# ✅ CORRECT: .specweave/increments/0046/reports/analysis-report.md
|
|
152
67
|
```
|
|
153
68
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
**ONLY 4 files allowed in `.specweave/increments/####/` root**:
|
|
157
|
-
- `spec.md`, `plan.md`, `tasks.md`, `metadata.json`
|
|
158
|
-
|
|
159
|
-
**Everything else → subfolders**:
|
|
160
|
-
- `reports/` - Analysis, completion reports, validation
|
|
161
|
-
- `scripts/` - Helper scripts, automation
|
|
162
|
-
- `logs/` - Execution logs, debug output
|
|
163
|
-
|
|
164
|
-
**Examples**:
|
|
165
|
-
```bash
|
|
166
|
-
# ❌ WRONG
|
|
167
|
-
.specweave/increments/0046/analysis-report.md
|
|
168
|
-
|
|
169
|
-
# ✅ CORRECT
|
|
170
|
-
.specweave/increments/0046/reports/analysis-report.md
|
|
171
|
-
|
|
172
|
-
# Fix before committing:
|
|
173
|
-
mkdir -p .specweave/increments/0046/reports
|
|
174
|
-
mv .specweave/increments/0046/*.md .specweave/increments/0046/reports/
|
|
175
|
-
git restore .specweave/increments/0046/{spec,plan,tasks}.md
|
|
176
|
-
```
|
|
69
|
+
---
|
|
177
70
|
|
|
178
|
-
### 3.
|
|
71
|
+
### 3. Protected Directories
|
|
179
72
|
|
|
180
|
-
**
|
|
73
|
+
**Never delete**: `.specweave/docs/`, `.specweave/increments/`
|
|
181
74
|
|
|
182
|
-
**Pre-commit hook blocks**:
|
|
183
|
-
- `rm -rf .specweave/docs` or `rm -rf .specweave/increments`
|
|
184
|
-
- Deletion of 50+ files at once in these directories
|
|
75
|
+
**Pre-commit hook blocks**: Deletion of 50+ files, `rm -rf` on protected dirs
|
|
185
76
|
|
|
186
|
-
**
|
|
187
|
-
```bash
|
|
188
|
-
git restore .specweave/
|
|
189
|
-
```
|
|
77
|
+
**Recovery**: `git restore .specweave/`
|
|
190
78
|
|
|
191
|
-
|
|
79
|
+
---
|
|
192
80
|
|
|
193
|
-
|
|
81
|
+
### 4. Test Cleanup Safety
|
|
194
82
|
|
|
195
|
-
**REQUIRED
|
|
83
|
+
**REQUIRED before `rm -rf`**:
|
|
196
84
|
1. Verify `pwd` (MUST be project root)
|
|
197
85
|
2. Dry-run with `-print` (NO deletion)
|
|
198
|
-
3. Count files
|
|
199
|
-
4. Manual confirmation
|
|
200
|
-
5. Execute
|
|
201
|
-
6. Verify results
|
|
202
|
-
7. Run tests
|
|
86
|
+
3. Count files to delete
|
|
87
|
+
4. Manual confirmation
|
|
88
|
+
5. Execute → Verify → Run tests
|
|
203
89
|
|
|
204
|
-
|
|
90
|
+
---
|
|
205
91
|
|
|
206
92
|
### 5. NEVER Use `specweave init . --force`
|
|
207
93
|
|
|
208
|
-
**Danger**: Deletes ALL increments
|
|
94
|
+
**Danger**: Deletes ALL increments/docs without backup
|
|
209
95
|
|
|
210
|
-
**
|
|
211
|
-
```bash
|
|
212
|
-
specweave init . # Interactive, never deletes without confirmation
|
|
213
|
-
```
|
|
96
|
+
**Use**: `specweave init .` (interactive, safe)
|
|
214
97
|
|
|
215
|
-
|
|
98
|
+
---
|
|
216
99
|
|
|
217
|
-
|
|
218
|
-
1. All acceptance criteria checked (`- [x] **AC-...`)
|
|
219
|
-
2. All tasks completed
|
|
220
|
-
3. All tests passing
|
|
221
|
-
4. Coverage target met
|
|
100
|
+
### 6. Increment Completion
|
|
222
101
|
|
|
223
|
-
**Always use**: `/specweave:done 0043` (validates
|
|
224
|
-
**Never**: Manual `metadata.json` edit (blocked by pre-commit hook)
|
|
102
|
+
**Always use**: `/specweave:done 0043` (validates ACs, tasks, tests, coverage)
|
|
225
103
|
|
|
226
|
-
|
|
104
|
+
**Never**: Manual `metadata.json` edit (blocked by pre-commit hook)
|
|
227
105
|
|
|
228
|
-
|
|
229
|
-
1. **tasks.md** - Task completion status (`[x]` checkboxes)
|
|
230
|
-
2. **spec.md** - Acceptance criteria status (`[x]` checkboxes)
|
|
106
|
+
---
|
|
231
107
|
|
|
232
|
-
|
|
108
|
+
### 7. Source of Truth: tasks.md + spec.md (CRITICAL!)
|
|
233
109
|
|
|
234
|
-
|
|
235
|
-
For EVERY task marked complete in internal TODO:
|
|
236
|
-
1. ✅ Mark task as completed in internal TODO
|
|
237
|
-
2. ⚠️ IMMEDIATELY update tasks.md checkbox: `[ ] pending` → `[x] completed`
|
|
238
|
-
3. ⚠️ IMMEDIATELY update spec.md AC checkbox: `[ ]` → `[x]`
|
|
239
|
-
4. ✅ Verify both files updated BEFORE moving to next task
|
|
240
|
-
```
|
|
110
|
+
**THE MOST CRITICAL RULE**: Internal TODO is ephemeral. **tasks.md + spec.md are SOURCE OF TRUTH.**
|
|
241
111
|
|
|
242
|
-
**
|
|
112
|
+
**MANDATORY workflow:**
|
|
243
113
|
```typescript
|
|
244
|
-
//
|
|
114
|
+
// 1. Complete work
|
|
245
115
|
await createIntegrationTest();
|
|
246
116
|
|
|
247
|
-
//
|
|
117
|
+
// 2. Update internal TODO
|
|
248
118
|
TodoWrite([{task: "T-013", status: "completed"}]);
|
|
249
119
|
|
|
250
|
-
//
|
|
120
|
+
// 3. IMMEDIATELY update tasks.md (NEVER skip!)
|
|
251
121
|
Edit("tasks.md", "**Status**: [ ] pending", "**Status**: [x] completed");
|
|
252
122
|
|
|
253
|
-
//
|
|
123
|
+
// 4. IMMEDIATELY update spec.md ACs
|
|
254
124
|
Edit("spec.md", "- [ ] **AC-US1-01**", "- [x] **AC-US1-01**");
|
|
255
|
-
|
|
256
|
-
// Step 5: Move to next task
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
**❌ CRITICAL ERROR - Never Do This**:
|
|
260
|
-
```typescript
|
|
261
|
-
// ❌ WRONG: Marking TODO as complete WITHOUT updating source files
|
|
262
|
-
TodoWrite([
|
|
263
|
-
{task: "T-013", status: "completed"}, // ❌ Only internal tracking
|
|
264
|
-
{task: "T-014", status: "completed"}, // ❌ Only internal tracking
|
|
265
|
-
{task: "T-015", status: "completed"} // ❌ Only internal tracking
|
|
266
|
-
]);
|
|
267
|
-
// tasks.md still shows `[ ] pending` → DESYNC!
|
|
268
|
-
// This is a CRITICAL VIOLATION!
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
**Pre-Closure Validation** (MANDATORY before `/specweave:done`):
|
|
272
|
-
```bash
|
|
273
|
-
# 1. Verify ALL tasks marked in tasks.md
|
|
274
|
-
grep "^\*\*Status\*\*:" tasks.md | grep -c "\[x\] completed"
|
|
275
|
-
# Output MUST equal total_tasks in frontmatter
|
|
276
|
-
|
|
277
|
-
# 2. Verify ALL ACs checked in spec.md
|
|
278
|
-
grep -c "^- \[x\] \*\*AC-" spec.md
|
|
279
|
-
# Output MUST equal total ACs
|
|
280
|
-
|
|
281
|
-
# 3. Only then close increment
|
|
282
|
-
/specweave:done 0044
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
**Why This Matters**:
|
|
286
|
-
- Internal TODO is ephemeral (lost between sessions)
|
|
287
|
-
- tasks.md is permanent source of truth
|
|
288
|
-
- spec.md is contract with stakeholders
|
|
289
|
-
- Desync = broken promises to users/team
|
|
290
|
-
|
|
291
|
-
**Incident Reference**: 2025-11-19 - Increment 0044 was incorrectly closed with tasks.md showing `[ ] pending` while internal TODO showed "completed". This violated SpecWeave's core principle. See `.specweave/increments/0044-integration-testing-status-hooks/reports/INCIDENT-SOURCE-OF-TRUTH-VIOLATION.md` for full post-mortem.
|
|
292
|
-
|
|
293
|
-
### 7a. Status Line Synchronization (AUTOMATIC & ENFORCED!)
|
|
294
|
-
|
|
295
|
-
**CRITICAL**: Status line MUST ALWAYS reflect current task completion status.
|
|
296
|
-
|
|
297
|
-
**How It Works** (Automatic):
|
|
298
|
-
1. Every TodoWrite call → `post-task-completion.sh` hook fires
|
|
299
|
-
2. Hook calls `update-status-line.sh` → cache updates
|
|
300
|
-
3. Status line displays updated progress immediately
|
|
301
|
-
|
|
302
|
-
**The ONLY Way to Complete Tasks**:
|
|
303
|
-
```
|
|
304
|
-
ALWAYS use TodoWrite when working on increment tasks!
|
|
305
|
-
- TodoWrite triggers hooks automatically
|
|
306
|
-
- Hooks update status line cache
|
|
307
|
-
- Status line stays synchronized
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
**❌ NEVER Complete Tasks Without TodoWrite**:
|
|
311
|
-
```typescript
|
|
312
|
-
// ❌ WRONG: Direct Edit without TodoWrite
|
|
313
|
-
Edit("tasks.md", "**Status**: [ ] pending", "**Status**: [x] completed");
|
|
314
|
-
// Status line will NOT update! Hook never fires!
|
|
315
|
-
|
|
316
|
-
// ✅ CORRECT: TodoWrite triggers automatic update
|
|
317
|
-
TodoWrite([{task: "T-001", status: "in_progress"}]);
|
|
318
|
-
// ... do the work ...
|
|
319
|
-
TodoWrite([{task: "T-001", status: "completed"}]);
|
|
320
|
-
Edit("tasks.md", "**Status**: [ ] pending", "**Status**: [x] completed");
|
|
321
|
-
// Hook fires → status line updates automatically!
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
**Validation Commands**:
|
|
325
|
-
```bash
|
|
326
|
-
# Check if status line is in sync
|
|
327
|
-
/specweave:validate-status
|
|
328
|
-
|
|
329
|
-
# Manual update (emergency only)
|
|
330
|
-
bash plugins/specweave/hooks/lib/update-status-line.sh
|
|
331
|
-
|
|
332
|
-
# Validate all increments
|
|
333
|
-
npx tsx src/core/status-line-validator.ts
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
**Detection & Recovery**:
|
|
337
|
-
- Pre-commit hook validates sync (blocks commit if desync detected)
|
|
338
|
-
- `/specweave:done` validates before closing (blocks if desync)
|
|
339
|
-
- Automatic tests verify hook fires correctly
|
|
340
|
-
|
|
341
|
-
**Why This Matters**:
|
|
342
|
-
- Status line is visible to user at ALL times
|
|
343
|
-
- Stale status = broken trust
|
|
344
|
-
- Hooks ensure atomic updates (task complete → status updates together)
|
|
345
|
-
|
|
346
|
-
**Incident Reference**: 2025-11-20 - Status line showed 21/52 tasks when actually 26/52 were complete (10% desync). Root cause: Tasks marked complete without using TodoWrite, so hooks never fired. Added validation layer and tests to prevent future occurrences.
|
|
347
|
-
|
|
348
|
-
### 7b. GitHub Duplicate Prevention (CRITICAL!)
|
|
349
|
-
|
|
350
|
-
**CRITICAL**: External tool items (GitHub issues, JIRA tickets, ADO work items) MUST NEVER be duplicated.
|
|
351
|
-
|
|
352
|
-
**Rule**: ALWAYS use DuplicateDetector for GitHub issue creation.
|
|
353
|
-
|
|
354
|
-
**Why This Matters**:
|
|
355
|
-
- GitHub search has eventual consistency (2-5 second lag)
|
|
356
|
-
- Race conditions can create duplicates if sync runs multiple times quickly
|
|
357
|
-
- Manual search with `--limit 1` hides duplicates
|
|
358
|
-
|
|
359
|
-
**The ONLY Way to Create GitHub Issues**:
|
|
360
|
-
```typescript
|
|
361
|
-
import { DuplicateDetector } from './duplicate-detector.js';
|
|
362
|
-
|
|
363
|
-
// ✅ CORRECT: Use DuplicateDetector.createWithProtection()
|
|
364
|
-
const titlePattern = `[${featureId}][${userStory.id}]`; // e.g., "[FS-047][US-001]"
|
|
365
|
-
const result = await DuplicateDetector.createWithProtection({
|
|
366
|
-
title: issueContent.title,
|
|
367
|
-
body: issueContent.body,
|
|
368
|
-
titlePattern,
|
|
369
|
-
labels: issueContent.labels,
|
|
370
|
-
milestone: milestoneTitle,
|
|
371
|
-
repo: `${owner}/${repo}`
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
// Provides automatic:
|
|
375
|
-
// ✅ Phase 1 (Detection): Search for existing before create
|
|
376
|
-
// ✅ Phase 2 (Verification): Count-check after creation
|
|
377
|
-
// ✅ Phase 3 (Reflection): Auto-close duplicates, keep oldest
|
|
378
|
-
|
|
379
|
-
// ❌ WRONG: Manual gh issue create (no duplicate protection!)
|
|
380
|
-
execSync('gh issue create --title "..." --body "..."');
|
|
381
125
|
```
|
|
382
126
|
|
|
383
|
-
**
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
**Search Limits** (CRITICAL!):
|
|
389
|
-
```typescript
|
|
390
|
-
// ❌ WRONG: --limit 1 hides duplicates!
|
|
391
|
-
gh issue list --search "[FS-047][US-001] in:title" --limit 1
|
|
392
|
-
// Returns ONLY 1 result even if 10 duplicates exist!
|
|
127
|
+
**Status Line Sync (Automatic):**
|
|
128
|
+
- TodoWrite → `post-task-completion.sh` hook → status line cache updates
|
|
129
|
+
- **NEVER** edit tasks.md without TodoWrite (hook won't fire → desync)
|
|
130
|
+
- Validation: `/specweave:validate-status`
|
|
393
131
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
132
|
+
**GitHub Duplicate Prevention:**
|
|
133
|
+
- **ALWAYS** use `DuplicateDetector.createWithProtection()` for GitHub issues
|
|
134
|
+
- 3-phase: Detection → Verification → Reflection (auto-close duplicates)
|
|
135
|
+
- **NEVER** use `--limit 1` in gh searches (hides duplicates, use `--limit 50`)
|
|
136
|
+
- Cleanup: `bash scripts/cleanup-duplicate-github-issues.sh --dry-run`
|
|
398
137
|
|
|
399
|
-
**
|
|
138
|
+
**Pre-closure validation:**
|
|
400
139
|
```bash
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
# Actually close duplicates (keeps oldest):
|
|
405
|
-
bash scripts/cleanup-duplicate-github-issues.sh
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
**Validation**:
|
|
409
|
-
```bash
|
|
410
|
-
# Check for duplicates:
|
|
411
|
-
gh issue list --json title,createdAt --limit 100 | \
|
|
412
|
-
jq -r '.[] | .title' | sort | uniq -d
|
|
413
|
-
|
|
414
|
-
# If output is empty → No duplicates! ✅
|
|
415
|
-
# If output shows titles → Duplicates exist, investigate!
|
|
140
|
+
grep "^\*\*Status\*\*:" tasks.md | grep -c "\[x\] completed" # Must equal total_tasks
|
|
141
|
+
grep -c "^- \[x\] \*\*AC-" spec.md # Must equal total ACs
|
|
142
|
+
/specweave:done 0044
|
|
416
143
|
```
|
|
417
144
|
|
|
418
|
-
**
|
|
419
|
-
-
|
|
420
|
-
-
|
|
421
|
-
-
|
|
422
|
-
- Root Cause #3: No post-create verification
|
|
423
|
-
- **Fix**: DuplicateDetector integration (github-feature-sync.ts:149-227)
|
|
145
|
+
**Incidents**:
|
|
146
|
+
- 2025-11-19 (0044): Internal TODO "completed" while tasks.md showed `[ ] pending`
|
|
147
|
+
- 2025-11-20: Status line 10% desync (tasks marked without TodoWrite)
|
|
148
|
+
- 2025-11-20: 10+ duplicate GitHub issues (race conditions, --limit 1 bug)
|
|
424
149
|
|
|
425
|
-
|
|
426
|
-
- `plugins/specweave-github/lib/github-feature-sync.ts` - Uses DuplicateDetector
|
|
427
|
-
- `plugins/specweave-github/lib/duplicate-detector.ts` - 3-phase protection
|
|
428
|
-
- `plugins/specweave-github/lib/github-client-v2.ts` - Fixed --limit 50
|
|
429
|
-
|
|
430
|
-
**Incident Reference**: 2025-11-20 - Duplicate GitHub issues for User Stories ([SP-US-006], [SP-US-007], etc.). Root cause: Race conditions + --limit 1 bug + missing DuplicateDetector integration. Fixed by implementing 3-phase protection. See `.specweave/increments/0047-us-task-linkage/reports/DUPLICATE-GITHUB-ISSUES-ROOT-CAUSE.md`.
|
|
431
|
-
|
|
432
|
-
### 8. NEVER Use `console.*` in Production Code
|
|
150
|
+
---
|
|
433
151
|
|
|
434
|
-
|
|
152
|
+
### 8. Logger Abstraction (NEVER `console.*`)
|
|
435
153
|
|
|
436
|
-
**
|
|
154
|
+
**Rule**: ALL `src/` code uses logger injection, NEVER `console.log/error/warn`
|
|
437
155
|
|
|
438
|
-
**Use logger injection**:
|
|
439
156
|
```typescript
|
|
440
157
|
import { Logger, consoleLogger } from '../../utils/logger.js';
|
|
441
158
|
|
|
442
159
|
export class MyClass {
|
|
443
|
-
private logger: Logger;
|
|
444
|
-
|
|
445
160
|
constructor(options: { logger?: Logger } = {}) {
|
|
446
161
|
this.logger = options.logger ?? consoleLogger;
|
|
447
162
|
}
|
|
448
|
-
|
|
449
|
-
doSomething() {
|
|
450
|
-
this.logger.log('Info message');
|
|
451
|
-
this.logger.error('Error message', error);
|
|
452
|
-
}
|
|
453
163
|
}
|
|
164
|
+
// In tests: new MyClass({ logger: silentLogger });
|
|
454
165
|
```
|
|
455
166
|
|
|
456
|
-
**
|
|
167
|
+
**Exception - CLI Commands**: `src/cli/commands/*.ts` may use `console.*` with comment:
|
|
457
168
|
```typescript
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
const instance = new MyClass({ logger: silentLogger });
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
**Protection**: Code review + search before commit:
|
|
464
|
-
```bash
|
|
465
|
-
# Check for console.* in src/ before committing:
|
|
466
|
-
git diff --cached --name-only | grep '^src/.*\.ts$' | xargs grep -n 'console\.' 2>/dev/null
|
|
169
|
+
// NOTE: This CLI command is primarily user-facing output (console.log/console.error).
|
|
170
|
+
// All console.* calls are legitimate user-facing exceptions as defined in CONTRIBUTING.md.
|
|
467
171
|
```
|
|
468
172
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
CLI commands in `src/cli/commands/*.ts` are 99% user-facing output (colored messages, progress indicators, confirmations). These files may keep `console.*` calls with proper documentation:
|
|
472
|
-
|
|
473
|
-
```typescript
|
|
474
|
-
export async function myCommand(options: CommandOptions = {}) {
|
|
475
|
-
// Initialize logger (injectable for testing)
|
|
476
|
-
const logger = options.logger ?? consoleLogger;
|
|
477
|
-
|
|
478
|
-
// NOTE: This CLI command is primarily user-facing output (console.log/console.error).
|
|
479
|
-
// All console.* calls in this file are legitimate user-facing exceptions
|
|
480
|
-
// as defined in CONTRIBUTING.md (colored messages, confirmations, formatted output).
|
|
481
|
-
// Logger infrastructure available for future internal debug logs if needed.
|
|
482
|
-
|
|
483
|
-
// User-facing output (keeps console.log)
|
|
484
|
-
console.log(chalk.green('✅ Operation successful!'));
|
|
485
|
-
|
|
486
|
-
// Internal debug logs (use logger)
|
|
487
|
-
logger.log('Internal state updated');
|
|
488
|
-
}
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
**Pre-commit hook allows files with documentation marker**:
|
|
492
|
-
- Files with comment `"user-facing output"` or `"legitimate user-facing exceptions"` bypass console.* check
|
|
493
|
-
- Pre-commit hook: `scripts/pre-commit-console-check.sh`
|
|
494
|
-
- See: `.specweave/increments/0046-console-elimination/` for migration pattern
|
|
495
|
-
|
|
496
|
-
### 8a. NEVER Use `fs-extra` (Native fs Migration)
|
|
497
|
-
|
|
498
|
-
**Rule**: ALL code MUST use native Node.js `fs` module, NEVER `fs-extra`.
|
|
499
|
-
|
|
500
|
-
**Why**: `fs-extra` causes hook failures when not installed. Native fs is faster, smaller, and always available.
|
|
501
|
-
|
|
502
|
-
**Migration completed**: 2025-11-20 - All hooks converted to native fs
|
|
173
|
+
---
|
|
503
174
|
|
|
504
|
-
|
|
505
|
-
```typescript
|
|
506
|
-
// ✅ CORRECT - Native fs (sync operations)
|
|
507
|
-
import { existsSync, readFileSync, statSync } from 'fs';
|
|
175
|
+
### 8a. Native fs (NEVER `fs-extra`)
|
|
508
176
|
|
|
509
|
-
|
|
510
|
-
const content = readFileSync(configPath, 'utf-8');
|
|
511
|
-
const stats = statSync(configPath);
|
|
512
|
-
}
|
|
513
|
-
```
|
|
177
|
+
**Rule**: Use native Node.js `fs`, NEVER `fs-extra`
|
|
514
178
|
|
|
515
179
|
```typescript
|
|
516
|
-
// ✅ CORRECT - Native fs
|
|
180
|
+
// ✅ CORRECT - Native fs
|
|
181
|
+
import { existsSync, readFileSync } from 'fs';
|
|
517
182
|
import { promises as fs } from 'fs';
|
|
183
|
+
import { mkdirpSync, writeJsonSync } from '../utils/fs-native.js';
|
|
518
184
|
|
|
519
|
-
|
|
520
|
-
await fs.mkdir(dir, { recursive: true });
|
|
521
|
-
await fs.writeFile(filePath, content, 'utf-8');
|
|
185
|
+
// ❌ WRONG: import fs from 'fs-extra';
|
|
522
186
|
```
|
|
523
187
|
|
|
524
|
-
|
|
525
|
-
// ✅ CORRECT - Custom utilities (from utils/fs-native.js)
|
|
526
|
-
import { mkdirpSync, writeJsonSync, readJsonSync } from '../utils/fs-native.js';
|
|
527
|
-
|
|
528
|
-
mkdirpSync(dir); // Create directory recursively
|
|
529
|
-
writeJsonSync(path, data); // Write JSON file
|
|
530
|
-
const config = readJsonSync(configPath); // Read JSON file
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
**Migration guide (fs-extra → native fs)**:
|
|
534
|
-
```typescript
|
|
535
|
-
// ❌ WRONG (fs-extra)
|
|
536
|
-
import fs from 'fs-extra';
|
|
537
|
-
|
|
538
|
-
fs.existsSync(path); → existsSync(path)
|
|
539
|
-
fs.readFileSync(path, 'utf-8'); → readFileSync(path, 'utf-8')
|
|
540
|
-
fs.statSync(path); → statSync(path)
|
|
541
|
-
await fs.readFile(path, 'utf-8'); → await fs.readFile(path, 'utf-8')
|
|
542
|
-
await fs.ensureDir(dir); → await fs.mkdir(dir, { recursive: true })
|
|
543
|
-
OR mkdirpSync(dir) for sync
|
|
544
|
-
await fs.writeFile(path, content); → await fs.writeFile(path, content, 'utf-8')
|
|
545
|
-
fs.removeSync(path); → removeSync(path) from fs-native.js
|
|
546
|
-
await fs.copy(src, dest); → await fs.cp(src, dest, { recursive: true })
|
|
547
|
-
```
|
|
188
|
+
**Migration**: `fs.existsSync → existsSync`, `fs.ensureDir → fs.mkdir(dir, {recursive: true})`, `fs.removeSync → removeSync`
|
|
548
189
|
|
|
549
|
-
**Prevention**:
|
|
550
|
-
1. **Pre-commit hook**: `scripts/pre-commit-fs-extra-check.sh` blocks fs-extra imports
|
|
551
|
-
2. **Installation**: Hook installed automatically via `bash scripts/install-git-hooks.sh`
|
|
552
|
-
3. **Legacy marker**: Add `// legacy fs-extra` comment to bypass check (temporary only)
|
|
190
|
+
**Prevention**: Pre-commit hook blocks fs-extra imports (bypass: `// legacy fs-extra`)
|
|
553
191
|
|
|
554
|
-
|
|
555
|
-
```bash
|
|
556
|
-
# Verify no fs-extra in hooks
|
|
557
|
-
grep -r "from 'fs-extra'" plugins/*/lib/hooks/*.js
|
|
558
|
-
|
|
559
|
-
# Should return nothing (empty output)
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
**Incident Reference**: 2025-11-20 - Hook failures due to fs-extra dependency. All hooks converted to native fs. Pre-commit hook added to prevent regression.
|
|
192
|
+
---
|
|
563
193
|
|
|
564
194
|
### 9. Coding Standards
|
|
565
195
|
|
|
566
|
-
**
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
196
|
+
**Critical rules (enforced)**:
|
|
197
|
+
1. ✅ NEVER `console.*` (use logger)
|
|
198
|
+
2. ✅ ALWAYS `.js` extensions in imports
|
|
199
|
+
3. ✅ Test files: `.test.ts` (NEVER `.spec.ts`)
|
|
200
|
+
4. Avoid `any` type
|
|
201
|
+
5. Functions < 100 lines
|
|
202
|
+
6. Custom error types
|
|
203
|
+
7. Comment "why" not "what"
|
|
204
|
+
8. No hardcoded secrets
|
|
205
|
+
9. No N+1 queries
|
|
206
|
+
10. Naming: camelCase (vars), PascalCase (classes), UPPER_SNAKE_CASE (constants)
|
|
570
207
|
|
|
571
|
-
|
|
572
|
-
2. ✅ **ALWAYS import with `.js` extensions** - Required for ESM (already enforced in Build section)
|
|
573
|
-
3. ✅ **Test files MUST use `.test.ts`** suffix, never `.spec.ts` (already enforced in Testing section)
|
|
574
|
-
4. **Avoid `any` type** - Use specific types or generics
|
|
575
|
-
5. **Functions < 50 lines** (ideal), < 100 lines (max)
|
|
576
|
-
6. **Use custom error types**, not generic Error
|
|
577
|
-
7. **Comment "why" not "what"**
|
|
578
|
-
8. **No hardcoded secrets** - Use environment variables
|
|
579
|
-
9. **No N+1 queries** - Batch database operations
|
|
580
|
-
10. **Naming**: camelCase (vars), PascalCase (classes), UPPER_SNAKE_CASE (constants)
|
|
208
|
+
**Auto-discovery**: `/specweave:analyze-standards`
|
|
581
209
|
|
|
582
|
-
|
|
583
|
-
- **Brownfield projects**: Standards auto-detected during project analysis
|
|
584
|
-
- **Manual analysis**: `/specweave:analyze-standards` - Generate comprehensive standards report
|
|
585
|
-
- **Drift detection**: `/specweave:analyze-standards --drift` - Check compliance with declared standards
|
|
586
|
-
- **Update standards**: `/specweave:analyze-standards --update` - Update official standards from analysis
|
|
587
|
-
|
|
588
|
-
**How it works**:
|
|
589
|
-
1. Scans codebase (src/**/*.ts) for naming patterns, import styles, function characteristics
|
|
590
|
-
2. Parses ESLint, Prettier, TypeScript configs for enforced rules
|
|
591
|
-
3. Analyzes existing CLAUDE.md, CONTRIBUTING.md for declared standards
|
|
592
|
-
4. Generates evidence-based standards with confidence levels (90%+ = HIGH confidence)
|
|
593
|
-
5. Detects anti-patterns: hardcoded secrets, large files (>500 lines), missing error handling
|
|
594
|
-
6. Outputs to `.specweave/docs/internal/governance/coding-standards-analysis.md`
|
|
595
|
-
|
|
596
|
-
**Note**: Most standards are enforced by ESLint/Prettier. This list focuses on SpecWeave-specific rules and patterns that can't be auto-fixed by linters.
|
|
210
|
+
---
|
|
597
211
|
|
|
598
|
-
### 10. GitHub Issue Format
|
|
212
|
+
### 10. GitHub Issue Format (v0.24.0+)
|
|
599
213
|
|
|
600
|
-
**CRITICAL**:
|
|
214
|
+
**CRITICAL**: GitHub issues are ONLY created for User Stories, NEVER for Features!
|
|
601
215
|
|
|
602
|
-
**ONLY Correct Format**:
|
|
603
|
-
```
|
|
604
|
-
[FS-XXX][US-YYY] User Story Title
|
|
605
|
-
```
|
|
216
|
+
**ONLY Correct Format**: `[FS-XXX][US-YYY] User Story Title`
|
|
606
217
|
|
|
607
218
|
**Examples**:
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
- ❌ `[SP-FS-047-specweave]` (SP prefix, project name)
|
|
615
|
-
- ❌ `[INC-0047]` (Increment-only)
|
|
616
|
-
|
|
617
|
-
**How to Create Issues**:
|
|
618
|
-
```bash
|
|
619
|
-
# CORRECT way (creates [FS-XXX][US-YYY] issues)
|
|
620
|
-
node -e "
|
|
621
|
-
const { GitHubFeatureSync } = require('./dist/plugins/specweave-github/lib/github-feature-sync.js');
|
|
622
|
-
const { GitHubClientV2 } = require('./dist/plugins/specweave-github/lib/github-client-v2.js');
|
|
623
|
-
|
|
624
|
-
const client = GitHubClientV2.fromRepo('anton-abyzov', 'specweave');
|
|
625
|
-
const sync = new GitHubFeatureSync(client, '.specweave/docs/internal/specs', process.cwd());
|
|
626
|
-
sync.syncFeatureToGitHub('FS-047').then(console.log).catch(console.error);
|
|
627
|
-
"
|
|
628
|
-
|
|
629
|
-
# WRONG way (deprecated, creates [FS-XXX] issues)
|
|
630
|
-
/specweave:increment "feature" # ← This no longer creates GitHub issues
|
|
219
|
+
```
|
|
220
|
+
✅ [FS-048][US-001] Smart Pagination During Init
|
|
221
|
+
✅ [FS-048][US-002] CLI-First Defaults
|
|
222
|
+
❌ [FS-048] (Feature-only - USE MILESTONE!)
|
|
223
|
+
❌ [SP-FS-048-specweave] (SP prefix - DEPRECATED!)
|
|
224
|
+
❌ [FS-048-specweave] (Project suffix - README.md ONLY, NOT GitHub!)
|
|
631
225
|
```
|
|
632
226
|
|
|
633
|
-
**
|
|
634
|
-
- **Features** are tracked via GitHub **Milestones** (not Issues)
|
|
635
|
-
- **User Stories** are tracked via GitHub **Issues**
|
|
636
|
-
- **Tasks** are tracked as **checkboxes** in User Story issue body
|
|
637
|
-
|
|
638
|
-
**Architecture**:
|
|
227
|
+
**Architecture** (ADR-0032 Universal Hierarchy Mapping):
|
|
639
228
|
```
|
|
640
|
-
Feature
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
└─ User Story (US-003) → GitHub Issue #640: [FS-047][US-003] Title
|
|
229
|
+
Feature FS-048 → GitHub Milestone "FS-048: Feature Title"
|
|
230
|
+
├─ User Story US-001 → Issue #XXX: [FS-048][US-001] US Title
|
|
231
|
+
├─ User Story US-002 → Issue #YYY: [FS-048][US-002] US Title
|
|
232
|
+
└─ User Story US-003 → Issue #ZZZ: [FS-048][US-003] US Title
|
|
645
233
|
```
|
|
646
234
|
|
|
647
|
-
**
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
-
|
|
235
|
+
**Create issues**:
|
|
236
|
+
```bash
|
|
237
|
+
# ✅ CORRECT: Creates User Story issues
|
|
238
|
+
/specweave-github:sync FS-048
|
|
651
239
|
|
|
652
|
-
|
|
240
|
+
# ❌ WRONG: /specweave:increment does NOT create GitHub issues
|
|
241
|
+
```
|
|
653
242
|
|
|
654
|
-
**
|
|
655
|
-
|
|
656
|
-
|
|
243
|
+
**If you see Feature-level issues** (`[FS-XXX]` without `[US-YYY]`):
|
|
244
|
+
1. Close them immediately with comment explaining the violation
|
|
245
|
+
2. Delete any duplicate Feature folders (e.g., FS-050 when FS-048 exists)
|
|
246
|
+
3. Use `/specweave-github:sync FS-XXX` to create correct User Story issues
|
|
247
|
+
4. **REPORT THE BUG** - this should never happen!
|
|
657
248
|
|
|
658
|
-
**See
|
|
659
|
-
- `.specweave/increments/0047-us-task-linkage/reports/GITHUB-
|
|
660
|
-
-
|
|
249
|
+
**See**:
|
|
250
|
+
- `.specweave/increments/0047-us-task-linkage/reports/FEATURE-LEVEL-GITHUB-SYNC-REMOVAL-PLAN.md`
|
|
251
|
+
- `.specweave/increments/0050-*/reports/GITHUB-ISSUE-BUG-ANALYSIS-2025-11-22.md`
|
|
661
252
|
|
|
662
|
-
|
|
253
|
+
---
|
|
663
254
|
|
|
664
|
-
|
|
255
|
+
### 11. Task Format with US Linkage (v0.23.0+)
|
|
665
256
|
|
|
666
|
-
**
|
|
257
|
+
**Required fields**:
|
|
667
258
|
```markdown
|
|
668
259
|
### T-001: Task Title
|
|
669
|
-
|
|
670
|
-
**
|
|
671
|
-
**Satisfies ACs**: AC-US1-01, AC-US1-02 ← MANDATORY: AC coverage mapping
|
|
260
|
+
**User Story**: US-001 ← MANDATORY
|
|
261
|
+
**Satisfies ACs**: AC-US1-01, AC-US1-02 ← MANDATORY
|
|
672
262
|
**Status**: [x] completed
|
|
673
|
-
**Priority**: P0 (Critical)
|
|
674
|
-
**Estimated Effort**: 6 hours
|
|
675
|
-
|
|
676
|
-
**Description**: Detailed task description...
|
|
677
|
-
|
|
678
|
-
**Implementation Steps**:
|
|
679
|
-
1. Step one
|
|
680
|
-
2. Step two
|
|
681
|
-
|
|
682
|
-
**Test Plan**:
|
|
683
|
-
- **File**: `tests/unit/component.test.ts`
|
|
684
|
-
- **Tests**: TC-001, TC-002
|
|
685
|
-
|
|
686
|
-
**Files Affected**:
|
|
687
|
-
- `src/path/to/file.ts`
|
|
688
|
-
```
|
|
689
|
-
|
|
690
|
-
**Why This Matters**:
|
|
691
|
-
- **Traceability**: Navigate Task ↔ User Story ↔ Acceptance Criteria ↔ Feature
|
|
692
|
-
- **Living Docs Sync**: Automatic task list updates in living docs US files
|
|
693
|
-
- **AC Coverage**: Validation ensures all acceptance criteria have implementing tasks
|
|
694
|
-
- **Progress Tracking**: Show per-US completion (e.g., "US-001: 8/11 tasks, 73%")
|
|
695
|
-
|
|
696
|
-
**Hierarchical Structure**:
|
|
697
|
-
```markdown
|
|
698
|
-
## User Story: US-001 - User Authentication
|
|
699
|
-
|
|
700
|
-
**Linked ACs**: AC-US1-01, AC-US1-02, AC-US1-03
|
|
701
|
-
**Tasks**: 11 total, 8 completed
|
|
702
|
-
|
|
703
|
-
### T-001: Implement login API
|
|
704
|
-
**User Story**: US-001
|
|
705
|
-
**Satisfies ACs**: AC-US1-01, AC-US1-02
|
|
706
|
-
...
|
|
707
|
-
|
|
708
|
-
### T-002: Add JWT token generation
|
|
709
|
-
**User Story**: US-001
|
|
710
|
-
**Satisfies ACs**: AC-US1-02, AC-US1-03
|
|
711
|
-
...
|
|
712
263
|
```
|
|
713
264
|
|
|
714
|
-
**
|
|
715
|
-
1. `userStory` field MUST reference valid US-ID from spec.md (format: `US-XXX`)
|
|
716
|
-
2. `satisfiesACs` field MUST list valid AC-IDs from spec.md (format: `AC-USXX-YY`)
|
|
717
|
-
3. AC-IDs MUST belong to correct User Story (AC-US1-XX belongs to US-001)
|
|
718
|
-
4. Tasks without US linkage trigger warnings during `/specweave:validate`
|
|
719
|
-
5. `/specweave:done` blocks closure if orphan tasks exist (no AC coverage)
|
|
265
|
+
**Why**: Traceability (Task ↔ User Story ↔ AC ↔ Feature), Living docs auto-sync, AC coverage validation
|
|
720
266
|
|
|
721
|
-
**
|
|
722
|
-
When task marked completed in tasks.md:
|
|
723
|
-
1. Hook detects change via `post-task-completion.sh`
|
|
724
|
-
2. `sync-living-docs.js` parses tasks with `parseTasksWithUSLinks()`
|
|
725
|
-
3. Updates living docs US file:
|
|
726
|
-
- Task list: `- [x] [T-001](link): Task title`
|
|
727
|
-
- AC checkboxes: `- [x] **AC-US1-01**` (if all tasks complete)
|
|
267
|
+
**Validation**: Tasks without linkage → warnings, orphan tasks → `/specweave:done` blocks closure
|
|
728
268
|
|
|
729
|
-
|
|
730
|
-
- Old increments (0001-0046) work without US linkage
|
|
731
|
-
- Parser supports both formats (graceful degradation)
|
|
732
|
-
- Migration tool available: `npx tsx scripts/migrate-task-linkage.ts <increment-id>`
|
|
269
|
+
---
|
|
733
270
|
|
|
734
|
-
|
|
735
|
-
- Implementation: `.specweave/increments/0047-us-task-linkage/`
|
|
736
|
-
- Proposal: `.specweave/increments/0046-console-elimination/reports/US-TASK-LINKAGE-PROPOSAL.md`
|
|
737
|
-
- Living Docs: `.specweave/docs/public/guides/bidirectional-linking.md`
|
|
271
|
+
### 12. ADR Naming Convention
|
|
738
272
|
|
|
739
|
-
|
|
273
|
+
**Correct format**: `XXXX-decision-title.md` (4-digit, kebab-case, NO `adr-` prefix)
|
|
740
274
|
|
|
741
|
-
**
|
|
275
|
+
**Header**: `# ADR-XXXX: Decision Title`
|
|
742
276
|
|
|
743
|
-
**
|
|
744
|
-
- **Filename**: `XXXX-decision-title.md` (4-digit number, kebab-case, NO `adr-` prefix)
|
|
745
|
-
- **Header**: `# ADR-XXXX: Decision Title` (includes `ADR-` prefix for document clarity)
|
|
746
|
-
- **Location**: `.specweave/docs/internal/architecture/adr/`
|
|
277
|
+
**Location**: `.specweave/docs/internal/architecture/adr/`
|
|
747
278
|
|
|
748
|
-
**Examples**:
|
|
749
279
|
```
|
|
750
|
-
✅
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
✅ CORRECT:
|
|
755
|
-
Filename: 0032-universal-hierarchy-mapping.md
|
|
756
|
-
Header: # ADR-0032: Universal Hierarchy Mapping
|
|
757
|
-
|
|
758
|
-
❌ WRONG:
|
|
759
|
-
Filename: adr-0007-github-first-task-sync.md (NO adr- prefix!)
|
|
760
|
-
Reason: Redundant (already in /adr/ directory)
|
|
761
|
-
|
|
762
|
-
❌ WRONG:
|
|
763
|
-
Filename: ADR-0007-github-first-task-sync.md (uppercase)
|
|
764
|
-
Reason: Filenames must be lowercase
|
|
765
|
-
|
|
766
|
-
❌ WRONG:
|
|
767
|
-
Filename: 007-github-first-task-sync.md (3-digit)
|
|
768
|
-
Reason: MUST be 4-digit (0001-9999)
|
|
280
|
+
✅ Filename: 0007-github-first-task-sync.md, Header: # ADR-0007: ...
|
|
281
|
+
❌ adr-0007-github-first-task-sync.md (redundant adr- prefix)
|
|
282
|
+
❌ 007-github-first-task-sync.md (3-digit)
|
|
769
283
|
```
|
|
770
284
|
|
|
771
|
-
**
|
|
772
|
-
- **Consistency**: All ADRs follow same pattern (sortable, predictable)
|
|
773
|
-
- **Clarity**: File location indicates type (in `/adr/` directory)
|
|
774
|
-
- **Tooling**: Scripts expect 4-digit format for auto-numbering
|
|
775
|
-
- **Cross-references**: Links use `adr/XXXX-name.md` format
|
|
776
|
-
|
|
777
|
-
**Enforcement**:
|
|
778
|
-
- Architect agent validates format before creating ADRs
|
|
779
|
-
- Pre-commit hook checks for `adr-XXXX-*.md` pattern and rejects
|
|
780
|
-
- `/specweave:validate` command verifies ADR naming
|
|
781
|
-
|
|
782
|
-
**Common Mistakes**:
|
|
783
|
-
1. Adding `adr-` prefix to filename (copying from header)
|
|
784
|
-
2. Using 3-digit numbers instead of 4-digit (001 vs 0001)
|
|
785
|
-
3. Uppercase filenames (ADR-0007 vs 0007)
|
|
786
|
-
4. Missing kebab-case (spaces or underscores instead of hyphens)
|
|
787
|
-
|
|
788
|
-
**Auto-Numbering**:
|
|
789
|
-
To find next available ADR number (handles duplicates correctly):
|
|
285
|
+
**Auto-numbering**:
|
|
790
286
|
```bash
|
|
791
|
-
ls .specweave/docs/internal/architecture/adr/*.md | \
|
|
792
|
-
|
|
793
|
-
sed 's/.*\/\([0-9][0-9][0-9][0-9]\)-.*/\1/' | \
|
|
794
|
-
sort -u | \
|
|
795
|
-
tail -1 | \
|
|
287
|
+
ls .specweave/docs/internal/architecture/adr/*.md | grep -E '/[0-9]{4}-' | \
|
|
288
|
+
sed 's/.*\/\([0-9][0-9][0-9][0-9]\)-.*/\1/' | sort -u | tail -1 | \
|
|
796
289
|
awk '{printf "Next ADR: %04d\n", $1 + 1}'
|
|
797
|
-
# Output: Next ADR: 0049
|
|
798
|
-
# (Extracts unique numbers only, finds max, adds 1)
|
|
799
290
|
```
|
|
800
291
|
|
|
801
|
-
|
|
292
|
+
---
|
|
802
293
|
|
|
803
|
-
|
|
294
|
+
### 13. Structured Data Matching
|
|
804
295
|
|
|
805
|
-
|
|
296
|
+
**NEVER use string search for frontmatter/IDs**:
|
|
806
297
|
|
|
807
298
|
```typescript
|
|
808
|
-
// ❌ WRONG: Matches ANYWHERE
|
|
809
|
-
|
|
810
|
-
if (content.includes('FS-039')) {
|
|
811
|
-
// This matches:
|
|
812
|
-
// - feature_id: FS-039 ✓ (correct)
|
|
813
|
-
// - "See FS-039 for details" ✗ (FALSE POSITIVE!)
|
|
814
|
-
// - [Related](FS-039) ✗ (FALSE POSITIVE!)
|
|
815
|
-
}
|
|
299
|
+
// ❌ WRONG: Matches ANYWHERE (false positives!)
|
|
300
|
+
content.includes('FS-039') // Matches "See FS-039" in docs!
|
|
816
301
|
|
|
817
302
|
// ✅ CORRECT: Parse frontmatter explicitly
|
|
818
|
-
const
|
|
819
|
-
if (
|
|
820
|
-
// Only matches actual frontmatter field
|
|
821
|
-
}
|
|
822
|
-
```
|
|
823
|
-
|
|
824
|
-
#### Anti-Pattern #2: Substring Matching for IDs
|
|
303
|
+
const match = content.match(/^feature_id:\s*["']?([^"'\n]+)["']?$/m);
|
|
304
|
+
if (match && match[1].trim() === 'FS-039') { /* ... */ }
|
|
825
305
|
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
const isArchived = archivedList.some(item => item.includes(searchId));
|
|
829
|
-
// "0039-ultra-smart-v2".includes("0039-ultra-smart") → TRUE (WRONG!)
|
|
306
|
+
// ❌ WRONG: Substring matching
|
|
307
|
+
archivedList.some(item => item.includes(searchId))
|
|
830
308
|
|
|
831
309
|
// ✅ CORRECT: Exact equality
|
|
832
|
-
|
|
310
|
+
archivedList.some(item => item === searchId)
|
|
833
311
|
```
|
|
834
312
|
|
|
835
|
-
**
|
|
836
|
-
- **Incident 2025-11-20**: String search caused 11 features to be incorrectly archived
|
|
837
|
-
- Features that merely REFERENCED another feature appeared to BELONG to it
|
|
838
|
-
- Substring matching confused similar IDs as identical
|
|
839
|
-
|
|
840
|
-
**Prevention**:
|
|
841
|
-
1. Always parse structured data (YAML frontmatter, JSON) explicitly
|
|
842
|
-
2. Use exact equality (`===`) for ID matching, never `.includes()`
|
|
843
|
-
3. Add comprehensive logging to show matching decisions
|
|
844
|
-
4. Test with edge cases: references, links, partial matches
|
|
845
|
-
|
|
846
|
-
**See Also**: `.specweave/increments/0047-us-task-linkage/reports/CRITICAL-ARCHIVING-BUGS-FIX.md`
|
|
847
|
-
|
|
848
|
-
### 14. Marketplace Plugin Completeness (CRITICAL!)
|
|
849
|
-
|
|
850
|
-
**NEVER add incomplete plugins to `.claude-plugin/marketplace.json`**
|
|
851
|
-
|
|
852
|
-
**Rule**: ONLY plugins with complete implementation (agents/, commands/, or lib/) may be listed in marketplace.json.
|
|
853
|
-
|
|
854
|
-
**Why This Matters**:
|
|
855
|
-
When users install `npm i -g specweave`, Claude Code loads ALL plugins listed in marketplace.json. Incomplete plugins (skeleton-only with just skills/) cause loading errors that confuse users and damage the framework's reputation.
|
|
856
|
-
|
|
857
|
-
**Incomplete Plugin Definition**:
|
|
858
|
-
A plugin is considered INCOMPLETE if it ONLY has:
|
|
859
|
-
- `.claude-plugin/` directory
|
|
860
|
-
- `skills/` directory
|
|
861
|
-
|
|
862
|
-
A plugin is COMPLETE if it has ANY of:
|
|
863
|
-
- `agents/` directory (specialized Claude Code agents)
|
|
864
|
-
- `commands/` directory (slash commands)
|
|
865
|
-
- `lib/` directory (shared utilities, TypeScript implementations)
|
|
866
|
-
|
|
867
|
-
**Validation Process** (MANDATORY before ANY marketplace.json changes):
|
|
868
|
-
|
|
869
|
-
```bash
|
|
870
|
-
# 1. Run validation script
|
|
871
|
-
bash scripts/validate-marketplace-plugins.sh
|
|
313
|
+
**Incident**: 2025-11-20 - 11 features incorrectly archived (string search false positives)
|
|
872
314
|
|
|
873
|
-
|
|
874
|
-
# If FAILED: Remove incomplete plugins from marketplace.json
|
|
875
|
-
```
|
|
876
|
-
|
|
877
|
-
**Examples**:
|
|
878
|
-
|
|
879
|
-
```bash
|
|
880
|
-
# ✅ COMPLETE plugins (may be listed in marketplace.json):
|
|
881
|
-
plugins/specweave-github/
|
|
882
|
-
├── .claude-plugin/
|
|
883
|
-
├── agents/ ← Has agents
|
|
884
|
-
├── commands/ ← Has commands
|
|
885
|
-
├── lib/ ← Has lib
|
|
886
|
-
└── skills/
|
|
887
|
-
|
|
888
|
-
plugins/specweave-kafka/
|
|
889
|
-
├── .claude-plugin/
|
|
890
|
-
├── agents/ ← Has agents
|
|
891
|
-
├── lib/ ← Has lib
|
|
892
|
-
└── skills/
|
|
893
|
-
|
|
894
|
-
# ✗ INCOMPLETE plugins (MUST NOT be listed in marketplace.json):
|
|
895
|
-
plugins/specweave-cost-optimizer/
|
|
896
|
-
├── .claude-plugin/
|
|
897
|
-
└── skills/ ← ONLY skills!
|
|
898
|
-
|
|
899
|
-
plugins/specweave-figma/
|
|
900
|
-
├── .claude-plugin/
|
|
901
|
-
└── skills/ ← ONLY skills!
|
|
902
|
-
```
|
|
903
|
-
|
|
904
|
-
**Adding New Plugins**:
|
|
905
|
-
|
|
906
|
-
```bash
|
|
907
|
-
# 1. Create plugin with COMPLETE structure
|
|
908
|
-
mkdir -p plugins/specweave-newplugin/{.claude-plugin,agents,skills}
|
|
909
|
-
|
|
910
|
-
# 2. Implement at least ONE of: agents/, commands/, or lib/
|
|
911
|
-
# (Don't just create empty directories!)
|
|
912
|
-
|
|
913
|
-
# 3. Add to marketplace.json
|
|
914
|
-
vim .claude-plugin/marketplace.json
|
|
315
|
+
---
|
|
915
316
|
|
|
916
|
-
|
|
917
|
-
bash scripts/validate-marketplace-plugins.sh
|
|
317
|
+
### 14. Marketplace Plugin Completeness
|
|
918
318
|
|
|
919
|
-
|
|
920
|
-
vim bin/fix-marketplace-errors.sh
|
|
921
|
-
# Add "specweave-newplugin" to plugins=(...) array
|
|
319
|
+
**NEVER add incomplete plugins to marketplace.json**
|
|
922
320
|
|
|
923
|
-
|
|
924
|
-
git add .claude-plugin/marketplace.json bin/fix-marketplace-errors.sh
|
|
925
|
-
git commit -m "feat: add specweave-newplugin to marketplace"
|
|
926
|
-
```
|
|
321
|
+
**Complete plugin requires**: `agents/`, `commands/`, OR `lib/` (not just `.claude-plugin/` + `skills/`)
|
|
927
322
|
|
|
928
|
-
**
|
|
323
|
+
**MANDATORY validation**:
|
|
929
324
|
```bash
|
|
930
|
-
|
|
931
|
-
bash scripts/validate-marketplace-plugins.sh
|
|
932
|
-
# Block commit if validation fails
|
|
325
|
+
bash scripts/validate-marketplace-plugins.sh # Must see "✅ VALIDATION PASSED!"
|
|
933
326
|
```
|
|
934
327
|
|
|
935
|
-
**
|
|
936
|
-
|
|
328
|
+
**Adding new plugin**:
|
|
329
|
+
1. Create with agents/commands/lib (NOT empty dirs!)
|
|
330
|
+
2. Add to marketplace.json
|
|
331
|
+
3. **VALIDATE** (critical!)
|
|
332
|
+
4. Update `bin/fix-marketplace-errors.sh`
|
|
333
|
+
5. Test: `npm pack && npm i -g ./specweave-*.tgz`
|
|
937
334
|
|
|
938
|
-
**
|
|
939
|
-
1. Run `bash scripts/validate-marketplace-plugins.sh` before EVERY marketplace.json change
|
|
940
|
-
2. NEVER add plugins to marketplace.json until they have agents/, commands/, or lib/
|
|
941
|
-
3. Update bin/fix-marketplace-errors.sh whenever marketplace.json changes
|
|
942
|
-
4. Test global npm install (`npm pack && npm i -g ./specweave-*.tgz`) before releases
|
|
335
|
+
**Incident**: 2025-11-20 - 8 incomplete plugins failed loading on global install
|
|
943
336
|
|
|
944
|
-
|
|
945
|
-
- Validation script: `scripts/validate-marketplace-plugins.sh`
|
|
946
|
-
- Fix script: `bin/fix-marketplace-errors.sh`
|
|
947
|
-
|
|
948
|
-
### 15. Skills vs Agents: Understanding the Distinction (CRITICAL!)
|
|
949
|
-
|
|
950
|
-
**NEVER confuse skills with agents** - They are different components with different invocation methods.
|
|
337
|
+
---
|
|
951
338
|
|
|
952
|
-
|
|
953
|
-
Empty agent directories cause "Agent type not found" errors when someone tries to invoke them. This happened with `specweave:increment-quality-judge-v2` which existed as a skill but had an empty agent directory.
|
|
339
|
+
### 15. Skills vs Agents
|
|
954
340
|
|
|
955
341
|
**Key Differences**:
|
|
956
342
|
|
|
957
343
|
| Aspect | Skills | Agents |
|
|
958
344
|
|--------|--------|--------|
|
|
959
345
|
| **Location** | `plugins/*/skills/name/SKILL.md` | `plugins/*/agents/name/AGENT.md` |
|
|
960
|
-
| **Invocation** | Skill
|
|
961
|
-
| **Activation** | Automatic (
|
|
962
|
-
| **
|
|
963
|
-
| **Purpose** | Expand context with knowledge | Execute multi-step tasks |
|
|
346
|
+
| **Invocation** | `Skill()` or `/command` | `Task()` with `subagent_type` |
|
|
347
|
+
| **Activation** | Automatic (keywords) | Explicit call |
|
|
348
|
+
| **File** | `SKILL.md` (YAML frontmatter) | `AGENT.md` |
|
|
964
349
|
|
|
965
|
-
**
|
|
350
|
+
**Agent naming**: `{plugin}:{directory}:{yaml-name}`
|
|
966
351
|
|
|
967
352
|
```typescript
|
|
968
|
-
// ✅ CORRECT:
|
|
969
|
-
Skill({ skill: "increment-quality-judge-v2" });
|
|
970
|
-
// OR use slash command:
|
|
971
|
-
/specweave:qa 0047
|
|
972
|
-
|
|
973
|
-
// ✅ CORRECT: Invoking an agent
|
|
974
|
-
Task({
|
|
975
|
-
subagent_type: "specweave:qa-lead:qa-lead",
|
|
976
|
-
prompt: "Create test plan for increment 0047"
|
|
977
|
-
});
|
|
978
|
-
|
|
979
|
-
// ❌ WRONG: Trying to invoke skill as agent
|
|
980
|
-
Task({
|
|
981
|
-
subagent_type: "specweave:increment-quality-judge-v2", // ERROR!
|
|
982
|
-
prompt: "Quality assessment"
|
|
983
|
-
});
|
|
984
|
-
```
|
|
985
|
-
|
|
986
|
-
**Agent Naming Convention** (CRITICAL!):
|
|
987
|
-
|
|
988
|
-
Claude Code agents follow a strict naming pattern for `subagent_type`:
|
|
989
|
-
|
|
990
|
-
**Directory-based agents**: `{plugin-name}:{directory-name}:{name-from-yaml}`
|
|
991
|
-
|
|
992
|
-
Examples:
|
|
993
|
-
- Agent at `plugins/specweave/agents/qa-lead/AGENT.md` with `name: qa-lead`
|
|
994
|
-
→ Invoke as: `specweave:qa-lead:qa-lead`
|
|
995
|
-
- Agent at `plugins/specweave/agents/pm/AGENT.md` with `name: pm`
|
|
996
|
-
→ Invoke as: `specweave:pm:pm`
|
|
997
|
-
- Agent at `plugins/specweave/agents/architect/AGENT.md` with `name: architect`
|
|
998
|
-
→ Invoke as: `specweave:architect:architect`
|
|
999
|
-
|
|
1000
|
-
**Why the "duplication"?**
|
|
1001
|
-
The pattern is `{plugin}:{directory}:{yaml-name}`. When the directory name matches the YAML `name` field (best practice), it creates the appearance of duplication: `qa-lead:qa-lead`.
|
|
1002
|
-
|
|
1003
|
-
**File-based agents** (legacy pattern):
|
|
1004
|
-
- Agent at `plugins/specweave/agents/code-reviewer.md`
|
|
1005
|
-
→ Invoke as: `specweave:code-reviewer` (no duplication)
|
|
1006
|
-
|
|
1007
|
-
**How to find the correct agent type**:
|
|
1008
|
-
```bash
|
|
1009
|
-
# List all available agents
|
|
1010
|
-
ls -la plugins/specweave/agents/
|
|
353
|
+
// ✅ CORRECT: Skill
|
|
354
|
+
Skill({ skill: "increment-quality-judge-v2" }); // or /specweave:qa
|
|
1011
355
|
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
# Output: name: qa-lead
|
|
356
|
+
// ✅ CORRECT: Agent
|
|
357
|
+
Task({ subagent_type: "specweave:qa-lead:qa-lead", prompt: "..." });
|
|
1015
358
|
|
|
1016
|
-
|
|
359
|
+
// ❌ WRONG: Skill as agent
|
|
360
|
+
Task({ subagent_type: "specweave:increment-quality-judge-v2" }); // ERROR!
|
|
1017
361
|
```
|
|
1018
362
|
|
|
1019
|
-
**
|
|
1020
|
-
```typescript
|
|
1021
|
-
// ❌ WRONG: Missing the directory/name duplication
|
|
1022
|
-
Task({ subagent_type: "specweave:qa-lead", ... });
|
|
1023
|
-
// Error: Agent type 'specweave:qa-lead' not found
|
|
1024
|
-
|
|
1025
|
-
// ✅ CORRECT: Full pattern with duplication
|
|
1026
|
-
Task({ subagent_type: "specweave:qa-lead:qa-lead", ... });
|
|
1027
|
-
```
|
|
1028
|
-
|
|
1029
|
-
**Directory Structure Requirements**:
|
|
1030
|
-
|
|
1031
|
-
```bash
|
|
1032
|
-
# ✅ CORRECT: Skill with SKILL.md
|
|
1033
|
-
plugins/specweave/skills/increment-quality-judge-v2/
|
|
1034
|
-
└── SKILL.md (with YAML frontmatter)
|
|
363
|
+
**Validation**: `bash scripts/validate-plugin-directories.sh --fix`
|
|
1035
364
|
|
|
1036
|
-
|
|
1037
|
-
plugins/specweave/agents/qa-lead/
|
|
1038
|
-
└── AGENT.md
|
|
365
|
+
**Incident**: 2025-11-20 - Empty agent directory caused "Agent not found" error
|
|
1039
366
|
|
|
1040
|
-
# ❌ WRONG: Empty agent directory
|
|
1041
|
-
plugins/specweave/agents/increment-quality-judge-v2/
|
|
1042
|
-
(empty - no AGENT.md!)
|
|
1043
|
-
|
|
1044
|
-
# ❌ WRONG: Skill missing SKILL.md
|
|
1045
|
-
plugins/specweave/skills/my-skill/
|
|
1046
|
-
└── some-file.txt (not SKILL.md!)
|
|
1047
|
-
```
|
|
1048
|
-
|
|
1049
|
-
**SKILL.md Format** (MANDATORY):
|
|
1050
|
-
```yaml
|
|
1051
|
-
---
|
|
1052
|
-
name: skill-name
|
|
1053
|
-
description: What it does AND trigger keywords. Include all variations.
|
|
1054
367
|
---
|
|
1055
368
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
Your skill documentation here...
|
|
1059
|
-
```
|
|
1060
|
-
|
|
1061
|
-
**Validation** (MANDATORY before commits):
|
|
1062
|
-
|
|
1063
|
-
```bash
|
|
1064
|
-
# Check for empty/invalid directories
|
|
1065
|
-
bash scripts/validate-plugin-directories.sh
|
|
1066
|
-
|
|
1067
|
-
# Auto-fix empty directories
|
|
1068
|
-
bash scripts/validate-plugin-directories.sh --fix
|
|
1069
|
-
|
|
1070
|
-
# This catches:
|
|
1071
|
-
# - Empty agent/skill directories
|
|
1072
|
-
# - Missing SKILL.md files
|
|
1073
|
-
# - Missing YAML frontmatter
|
|
1074
|
-
# - Invalid plugin structures
|
|
1075
|
-
```
|
|
369
|
+
### 16. YAML Frontmatter Validation
|
|
1076
370
|
|
|
1077
|
-
**
|
|
1078
|
-
|
|
1079
|
-
1. **Creating empty agent directories during scaffolding**
|
|
1080
|
-
```bash
|
|
1081
|
-
# ❌ WRONG
|
|
1082
|
-
mkdir -p plugins/specweave/agents/new-agent
|
|
1083
|
-
git add . && git commit # Empty directory!
|
|
1084
|
-
|
|
1085
|
-
# ✅ CORRECT
|
|
1086
|
-
mkdir -p plugins/specweave/agents/new-agent
|
|
1087
|
-
echo "---" > plugins/specweave/agents/new-agent/AGENT.md
|
|
1088
|
-
# ... add agent content ...
|
|
1089
|
-
git add . && git commit
|
|
1090
|
-
```
|
|
1091
|
-
|
|
1092
|
-
2. **Copying skill as agent without changing structure**
|
|
1093
|
-
- Skills need `SKILL.md` with YAML
|
|
1094
|
-
- Agents need `AGENT.md` or config
|
|
1095
|
-
- Don't copy-paste between them!
|
|
1096
|
-
|
|
1097
|
-
3. **Using wrong invocation method**
|
|
1098
|
-
- Check available skills: Skills list in context
|
|
1099
|
-
- Check available agents: Error message shows all agents
|
|
1100
|
-
- Skills → Skill tool or slash commands
|
|
1101
|
-
- Agents → Task tool
|
|
1102
|
-
|
|
1103
|
-
**When to Use Skills vs Agents**:
|
|
1104
|
-
|
|
1105
|
-
**Use Skills when**:
|
|
1106
|
-
- Providing domain knowledge (e.g., Kafka best practices)
|
|
1107
|
-
- Expanding Claude's context with project-specific info
|
|
1108
|
-
- Explaining concepts, patterns, frameworks
|
|
1109
|
-
- Want automatic activation based on keywords
|
|
1110
|
-
|
|
1111
|
-
**Use Agents when**:
|
|
1112
|
-
- Need multi-step task execution (e.g., generate docs)
|
|
1113
|
-
- Require specialized sub-agent capabilities
|
|
1114
|
-
- Building complex workflows with tools
|
|
1115
|
-
- Want explicit control over when they run
|
|
1116
|
-
|
|
1117
|
-
**Incident History**:
|
|
1118
|
-
- **2025-11-20**: `specweave:increment-quality-judge-v2` agent invocation failed because only skill existed. Empty agent directory caused "Agent type not found" error. Fixed by removing empty directory and documenting distinction.
|
|
1119
|
-
|
|
1120
|
-
**Prevention**:
|
|
1121
|
-
1. Run `bash scripts/validate-plugin-directories.sh` before commits
|
|
1122
|
-
2. Never create empty agent/skill directories
|
|
1123
|
-
3. Always include required files (SKILL.md, AGENT.md)
|
|
1124
|
-
4. Test invocation method matches component type
|
|
1125
|
-
5. Use pre-commit hook (blocks invalid structures)
|
|
1126
|
-
|
|
1127
|
-
**See Also**:
|
|
1128
|
-
- Validation script: `scripts/validate-plugin-directories.sh`
|
|
1129
|
-
- Skills index: `plugins/specweave/skills/SKILLS-INDEX.md`
|
|
1130
|
-
- Claude Code Skills docs: `~/CLAUDE.md` (Personal skills reference)
|
|
1131
|
-
|
|
1132
|
-
### 16. YAML Frontmatter Validation (CRITICAL!)
|
|
1133
|
-
|
|
1134
|
-
**Rule**: ALL spec.md files MUST have valid YAML frontmatter with required fields.
|
|
1135
|
-
|
|
1136
|
-
**Required Format**:
|
|
371
|
+
**Required format**:
|
|
1137
372
|
```yaml
|
|
1138
373
|
---
|
|
1139
|
-
increment: 0001-feature-name # REQUIRED: 4-digit
|
|
1140
|
-
title: Feature Title # OPTIONAL
|
|
1141
|
-
feature_id: FS-001 # OPTIONAL
|
|
374
|
+
increment: 0001-feature-name # REQUIRED: 4-digit + kebab-case
|
|
375
|
+
title: Feature Title # OPTIONAL
|
|
376
|
+
feature_id: FS-001 # OPTIONAL
|
|
1142
377
|
---
|
|
1143
378
|
```
|
|
1144
379
|
|
|
1145
|
-
**Common
|
|
380
|
+
**Common mistakes**: Unclosed brackets/quotes, invalid objects, missing `increment`, uppercase in ID
|
|
1146
381
|
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
data: [unclosed
|
|
1152
|
-
---
|
|
1153
|
-
|
|
1154
|
-
# ❌ WRONG: Unclosed quote
|
|
1155
|
-
---
|
|
1156
|
-
increment: 0001-test
|
|
1157
|
-
title: "unclosed string
|
|
1158
|
-
---
|
|
1159
|
-
|
|
1160
|
-
# ❌ WRONG: Invalid YAML object
|
|
1161
|
-
---
|
|
1162
|
-
increment: 0001-test
|
|
1163
|
-
config: {key: value, broken
|
|
1164
|
-
---
|
|
1165
|
-
|
|
1166
|
-
# ❌ WRONG: Invalid increment ID format
|
|
1167
|
-
---
|
|
1168
|
-
increment: 1-test # Missing leading zeros
|
|
1169
|
-
---
|
|
1170
|
-
|
|
1171
|
-
# ❌ WRONG: Invalid increment ID format (uppercase)
|
|
1172
|
-
---
|
|
1173
|
-
increment: 0001-Test-Feature # Uppercase letters not allowed
|
|
1174
|
-
---
|
|
1175
|
-
|
|
1176
|
-
# ❌ WRONG: Missing required field
|
|
1177
|
-
---
|
|
1178
|
-
title: Feature Title # Missing increment field!
|
|
1179
|
-
---
|
|
1180
|
-
|
|
1181
|
-
# ✅ CORRECT: Minimal valid frontmatter
|
|
1182
|
-
---
|
|
1183
|
-
increment: 0001-feature-name
|
|
1184
|
-
---
|
|
1185
|
-
|
|
1186
|
-
# ✅ CORRECT: Full frontmatter
|
|
1187
|
-
---
|
|
1188
|
-
increment: 0042-bug-fix
|
|
1189
|
-
title: Critical Bug Fix
|
|
1190
|
-
feature_id: FS-013
|
|
1191
|
-
---
|
|
1192
|
-
```
|
|
1193
|
-
|
|
1194
|
-
**Prevention Layers**:
|
|
1195
|
-
|
|
1196
|
-
1. **Pre-commit hook** - Validates YAML before commits (blocks malformed frontmatter)
|
|
1197
|
-
```bash
|
|
1198
|
-
# Runs automatically on git commit
|
|
1199
|
-
scripts/pre-commit-yaml-validation.sh
|
|
1200
|
-
```
|
|
1201
|
-
|
|
1202
|
-
2. **Spec parser** - Uses `js-yaml` library (detects errors at runtime)
|
|
1203
|
-
- Provides descriptive error messages
|
|
1204
|
-
- Shows line numbers for YAML errors
|
|
1205
|
-
- Suggests common fixes
|
|
1206
|
-
|
|
1207
|
-
3. **Command validation** - `/specweave:validate` checks YAML syntax
|
|
1208
|
-
```bash
|
|
1209
|
-
/specweave:validate 0001
|
|
1210
|
-
```
|
|
1211
|
-
|
|
1212
|
-
**Manual YAML Testing**:
|
|
382
|
+
**Validation layers**:
|
|
383
|
+
1. Pre-commit hook: `scripts/pre-commit-yaml-validation.sh`
|
|
384
|
+
2. Spec parser (uses `js-yaml`, provides line numbers)
|
|
385
|
+
3. `/specweave:validate 0001`
|
|
1213
386
|
|
|
387
|
+
**Manual test**:
|
|
1214
388
|
```bash
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
const
|
|
1218
|
-
|
|
1219
|
-
const content = fs.readFileSync('.specweave/increments/0001-test/spec.md', 'utf-8');
|
|
1220
|
-
const frontmatter = content.match(/^---\n([\s\S]*?)\n---/);
|
|
1221
|
-
if (!frontmatter) throw new Error('No frontmatter found');
|
|
1222
|
-
const parsed = yaml.load(frontmatter[1]);
|
|
1223
|
-
console.log('✅ Valid YAML:', JSON.stringify(parsed, null, 2));
|
|
1224
|
-
"
|
|
1225
|
-
```
|
|
1226
|
-
|
|
1227
|
-
**Error Messages**:
|
|
1228
|
-
|
|
1229
|
-
When YAML validation fails, you'll see descriptive errors:
|
|
1230
|
-
|
|
1231
|
-
```
|
|
1232
|
-
ERROR: Malformed YAML syntax in frontmatter
|
|
1233
|
-
DETAILS: Unexpected end of stream
|
|
1234
|
-
LOCATION: Lines 2-5
|
|
1235
|
-
HINT: Common mistakes:
|
|
1236
|
-
- Unclosed brackets: [unclosed
|
|
1237
|
-
- Unclosed quotes: "unclosed
|
|
1238
|
-
- Invalid YAML object: {key: value, broken
|
|
389
|
+
node -e "const yaml = require('js-yaml'); const fs = require('fs'); \
|
|
390
|
+
const content = fs.readFileSync('.specweave/increments/0001-test/spec.md', 'utf-8'); \
|
|
391
|
+
const fm = content.match(/^---\n([\s\S]*?)\n---/); \
|
|
392
|
+
console.log('✅ Valid:', JSON.stringify(yaml.load(fm[1]), null, 2));"
|
|
1239
393
|
```
|
|
1240
394
|
|
|
1241
|
-
**Why This Matters**:
|
|
1242
|
-
- **Silent failures**: Malformed YAML can cause missing/incorrect metadata
|
|
1243
|
-
- **Sync issues**: Invalid increment IDs break living docs sync
|
|
1244
|
-
- **GitHub sync**: Broken frontmatter prevents issue creation
|
|
1245
|
-
- **Validation failures**: Tasks/ACs can't be parsed without valid metadata
|
|
1246
|
-
|
|
1247
|
-
**Incident History**:
|
|
1248
|
-
- **Test case**: `tests/integration/commands/plan-command.integration.test.ts:626` tests malformed YAML handling
|
|
1249
|
-
- **Root cause**: Regex-based parsing was tolerant but unreliable
|
|
1250
|
-
- **Solution**: Multi-layered YAML validation with `js-yaml` library
|
|
1251
|
-
|
|
1252
|
-
**See Also**:
|
|
1253
|
-
- Pre-commit hook: `scripts/pre-commit-yaml-validation.sh`
|
|
1254
|
-
- Spec parser: `src/generators/spec/spec-parser.ts` (uses js-yaml)
|
|
1255
|
-
- Test suite: `tests/integration/commands/plan-command.integration.test.ts`
|
|
1256
|
-
|
|
1257
395
|
---
|
|
1258
396
|
|
|
1259
397
|
## Project Structure
|
|
1260
398
|
|
|
1261
399
|
```
|
|
1262
|
-
src/ # TypeScript
|
|
1263
|
-
plugins/ #
|
|
400
|
+
src/ # TypeScript (compiled to dist/)
|
|
401
|
+
plugins/ # Skills, agents, commands, hooks
|
|
1264
402
|
├── specweave/ # Core plugin
|
|
1265
|
-
└── specweave-*/ # Optional plugins
|
|
1266
|
-
.specweave/ #
|
|
403
|
+
└── specweave-*/ # Optional plugins
|
|
404
|
+
.specweave/ # Increments, docs, logs
|
|
1267
405
|
```
|
|
1268
406
|
|
|
1269
|
-
**Rules**:
|
|
1270
|
-
- `src/` = TypeScript ONLY
|
|
1271
|
-
- ALL skills/agents/commands/hooks = `plugins/`
|
|
1272
|
-
- Marketplace = GLOBAL via CLI
|
|
1273
|
-
- NEVER mix `*.ts` and `SKILL.md` in same directory
|
|
1274
|
-
- NEVER create files in project root
|
|
407
|
+
**Rules**: `src/` = TS only, ALL components = `plugins/`, NEVER mix `.ts` + `SKILL.md`, NEVER root files
|
|
1275
408
|
|
|
1276
409
|
---
|
|
1277
410
|
|
|
1278
|
-
## Plugin Hook Registration
|
|
1279
|
-
|
|
1280
|
-
**When**: Adding or modifying hooks that respond to Claude Code tool events
|
|
1281
|
-
|
|
1282
|
-
**Hook Schema Rules** (v0.22.14+):
|
|
1283
|
-
1. ✅ **ONLY use valid Claude Code hook events** (e.g., PostToolUse, PreToolUse, SessionStart)
|
|
1284
|
-
2. ❌ **NEVER use custom hook names** (e.g., "TodoWrite") as hook events
|
|
1285
|
-
3. ✅ **Use matchers** to filter which tool calls trigger the hook
|
|
1286
|
-
|
|
1287
|
-
### Valid Claude Code Hook Events
|
|
411
|
+
## Plugin Hook Registration
|
|
1288
412
|
|
|
1289
|
-
|
|
1290
|
-
- `PostToolUse` - After a tool completes (use this for TodoWrite, Write, Edit, etc.)
|
|
1291
|
-
- `PreToolUse` - Before a tool executes
|
|
1292
|
-
- `PermissionRequest` - When permission dialogs appear
|
|
1293
|
-
- `Notification` - When notifications are sent
|
|
1294
|
-
- `UserPromptSubmit` - When users submit prompts
|
|
1295
|
-
- `Stop` - When the main agent finishes
|
|
1296
|
-
- `SubagentStop` - When subagents finish
|
|
1297
|
-
- `PreCompact` - Before compaction operations
|
|
1298
|
-
- `SessionStart` - At session initialization
|
|
1299
|
-
- `SessionEnd` - When sessions terminate
|
|
1300
|
-
|
|
1301
|
-
### Correct Hook Registration Format
|
|
1302
|
-
|
|
1303
|
-
**File**: `plugins/*/. claude-plugin/plugin.json`
|
|
413
|
+
**Valid hook events** (10 total): `PostToolUse`, `PreToolUse`, `PermissionRequest`, `Notification`, `UserPromptSubmit`, `Stop`, `SubagentStop`, `PreCompact`, `SessionStart`, `SessionEnd`
|
|
1304
414
|
|
|
415
|
+
**Format** (`plugins/*/.claude-plugin/plugin.json`):
|
|
1305
416
|
```json
|
|
1306
417
|
{
|
|
1307
|
-
"name": "specweave",
|
|
1308
|
-
"version": "0.22.14",
|
|
1309
418
|
"hooks": {
|
|
1310
419
|
"PostToolUse": [
|
|
1311
420
|
{
|
|
1312
421
|
"matcher": "TodoWrite",
|
|
1313
|
-
"hooks": [
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
}
|
|
1319
|
-
]
|
|
422
|
+
"hooks": [{
|
|
423
|
+
"type": "command",
|
|
424
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-task-completion.sh",
|
|
425
|
+
"timeout": 10
|
|
426
|
+
}]
|
|
1320
427
|
}
|
|
1321
428
|
]
|
|
1322
429
|
}
|
|
1323
430
|
}
|
|
1324
431
|
```
|
|
1325
432
|
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|-------|------|---------|
|
|
1329
|
-
| `PostToolUse` | array | Hook event (one of 10 valid events above) |
|
|
1330
|
-
| `matcher` | string | Tool name pattern (e.g., "TodoWrite", "Write\|Edit") |
|
|
1331
|
-
| `type` | string | Always "command" for shell scripts |
|
|
1332
|
-
| `command` | string | Script path (use `${CLAUDE_PLUGIN_ROOT}` for plugin directory) |
|
|
1333
|
-
| `timeout` | number | Seconds before timeout (default: 30) |
|
|
1334
|
-
|
|
1335
|
-
### Common Mistakes (v0.22.13 Bug)
|
|
1336
|
-
|
|
1337
|
-
❌ **WRONG** (Invalid hook event):
|
|
1338
|
-
```json
|
|
1339
|
-
{
|
|
1340
|
-
"hooks": {
|
|
1341
|
-
"TodoWrite": {
|
|
1342
|
-
"post": "./hooks/post-task-completion.sh"
|
|
1343
|
-
}
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
```
|
|
1347
|
-
**Error**: `"TodoWrite"` is not a valid Claude Code hook event
|
|
1348
|
-
|
|
1349
|
-
✅ **CORRECT** (Use PostToolUse with matcher):
|
|
1350
|
-
```json
|
|
1351
|
-
{
|
|
1352
|
-
"hooks": {
|
|
1353
|
-
"PostToolUse": [
|
|
1354
|
-
{
|
|
1355
|
-
"matcher": "TodoWrite",
|
|
1356
|
-
"hooks": [{"type": "command", "command": "..."}]
|
|
1357
|
-
}
|
|
1358
|
-
]
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
```
|
|
1362
|
-
|
|
1363
|
-
### Testing Hook Registration
|
|
1364
|
-
|
|
1365
|
-
```bash
|
|
1366
|
-
# 1. Update plugin.json with correct schema
|
|
1367
|
-
vim plugins/specweave/.claude-plugin/plugin.json
|
|
1368
|
-
|
|
1369
|
-
# 2. Commit and push
|
|
1370
|
-
git add plugins/specweave/.claude-plugin/plugin.json
|
|
1371
|
-
git commit -m "fix: correct hook registration schema"
|
|
1372
|
-
git push origin develop
|
|
1373
|
-
|
|
1374
|
-
# 3. Wait 5-10 seconds for marketplace auto-update
|
|
1375
|
-
|
|
1376
|
-
# 4. Force refresh marketplace (if needed)
|
|
1377
|
-
cd ~/.claude/plugins/marketplaces
|
|
1378
|
-
rm -rf specweave
|
|
1379
|
-
git clone https://github.com/YOUR_USERNAME/specweave.git
|
|
1380
|
-
|
|
1381
|
-
# 5. Restart Claude Code
|
|
1382
|
-
|
|
1383
|
-
# 6. Verify no plugin loading errors
|
|
1384
|
-
# Should NOT see: "hooks: Invalid input" error
|
|
1385
|
-
```
|
|
1386
|
-
|
|
1387
|
-
### Documentation References
|
|
1388
|
-
|
|
1389
|
-
- **Claude Code Plugin Hooks**: https://code.claude.com/docs/en/hooks.md
|
|
1390
|
-
- **Hooks Reference**: https://code.claude.com/docs/en/hooks-reference.md
|
|
1391
|
-
- **Fix History**: See CHANGELOG.md v0.22.14 for the hook schema bug fix
|
|
433
|
+
**❌ WRONG**: `"TodoWrite": {...}` (invalid event)
|
|
434
|
+
**✅ CORRECT**: `"PostToolUse"` with `"matcher": "TodoWrite"`
|
|
1392
435
|
|
|
1393
436
|
---
|
|
1394
437
|
|
|
1395
|
-
##
|
|
1396
|
-
|
|
1397
|
-
### Core Commands
|
|
1398
|
-
|
|
1399
|
-
```bash
|
|
1400
|
-
# Primary workflow
|
|
1401
|
-
/specweave:increment "feature" # Plan new work
|
|
1402
|
-
/specweave:do # Execute tasks
|
|
1403
|
-
/specweave:progress # Check status
|
|
1404
|
-
/specweave:done # Close (validates ACs, tasks, tests)
|
|
1405
|
-
|
|
1406
|
-
# State management
|
|
1407
|
-
/specweave:pause 0002 --reason="..."
|
|
1408
|
-
/specweave:resume 0002
|
|
1409
|
-
/specweave:abandon 0002
|
|
1410
|
-
|
|
1411
|
-
# Quality
|
|
1412
|
-
/specweave:validate 0001
|
|
1413
|
-
/specweave:qa 0001
|
|
1414
|
-
|
|
1415
|
-
# Documentation
|
|
1416
|
-
/specweave:sync-docs update
|
|
1417
|
-
/specweave:sync-tasks
|
|
1418
|
-
```
|
|
1419
|
-
|
|
1420
|
-
### Local Development Setup
|
|
1421
|
-
|
|
1422
|
-
```bash
|
|
1423
|
-
# 1. Clone and install
|
|
1424
|
-
git clone https://github.com/YOUR_USERNAME/specweave.git
|
|
1425
|
-
cd specweave
|
|
1426
|
-
npm install
|
|
438
|
+
## 9a. Hook Performance & Safety (CRITICAL - v0.24.3)
|
|
1427
439
|
|
|
1428
|
-
|
|
1429
|
-
mkdir -p ~/.claude/plugins/marketplaces
|
|
1430
|
-
rm -rf ~/.claude/plugins/marketplaces/specweave
|
|
1431
|
-
ln -s "$(pwd)" ~/.claude/plugins/marketplaces/specweave
|
|
440
|
+
**Critical incidents**: 2025-11-22 - Multiple Claude Code crashes due to hook overhead
|
|
1432
441
|
|
|
1433
|
-
|
|
1434
|
-
bash .specweave/increments/0043-spec-md-desync-fix/scripts/verify-dev-setup.sh
|
|
442
|
+
**Root cause**: Process exhaustion from spawning 6+ Node.js processes per task completion
|
|
1435
443
|
|
|
1436
|
-
|
|
1437
|
-
bash scripts/install-git-hooks.sh
|
|
1438
|
-
```
|
|
444
|
+
**Emergency fixes implemented (v0.24.3)**:
|
|
1439
445
|
|
|
1440
|
-
|
|
446
|
+
### 1. Emergency Kill Switch
|
|
1441
447
|
```bash
|
|
1442
|
-
|
|
1443
|
-
|
|
448
|
+
# INSTANT disable of ALL hooks
|
|
449
|
+
export SPECWEAVE_DISABLE_HOOKS=1
|
|
1444
450
|
```
|
|
1445
451
|
|
|
1446
|
-
|
|
452
|
+
### 2. Circuit Breaker (Auto-Protection)
|
|
453
|
+
- **Threshold**: 3 consecutive failures → auto-disable hooks
|
|
454
|
+
- **File**: `.specweave/state/.hook-circuit-breaker`
|
|
455
|
+
- **Recovery**: `rm .specweave/state/.hook-circuit-breaker`
|
|
1447
456
|
|
|
1448
|
-
|
|
457
|
+
### 3. File Locking (Prevents Concurrent Execution)
|
|
458
|
+
- **Max instances**: 1 per hook type
|
|
459
|
+
- **Timeout**: 5-10 seconds with stale lock cleanup
|
|
460
|
+
- **Mechanism**: Directory-based mutex
|
|
1449
461
|
|
|
1450
|
-
###
|
|
462
|
+
### 4. Aggressive Debouncing
|
|
463
|
+
- **Window**: 5 seconds (increased from 1s)
|
|
464
|
+
- **Effect**: Batches rapid operations
|
|
465
|
+
- **Trade-off**: 5s staleness acceptable for UX
|
|
1451
466
|
|
|
467
|
+
### 5. Complete Error Isolation
|
|
1452
468
|
```bash
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
npm run clean # Remove dist/
|
|
469
|
+
set +e # NEVER use set -e in hooks
|
|
470
|
+
exit 0 # ALWAYS exit 0, never block workflow
|
|
1456
471
|
```
|
|
1457
472
|
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
4. `copy:hook-deps` **NEW**: Copies hook dependencies to vendor/
|
|
473
|
+
### 6. Consolidated Background Work
|
|
474
|
+
- **Before**: 6+ Node.js spawns per task (exhaustion!)
|
|
475
|
+
- **After**: 1 consolidated background job
|
|
476
|
+
- **Reduction**: 85% fewer processes
|
|
1463
477
|
|
|
1464
|
-
|
|
1465
|
-
- Problem: Hooks imported from `../../../../dist/src/...` (failed in marketplace)
|
|
1466
|
-
- Solution: Copy compiled files to `plugins/*/lib/vendor/`
|
|
1467
|
-
- Hooks now import from `../vendor/...` (self-contained)
|
|
1468
|
-
- Script: `scripts/copy-hook-dependencies.js`
|
|
1469
|
-
- Auto-detect deps: `scripts/find-hook-dependencies.js`
|
|
478
|
+
### Hook Safety Checklist (MANDATORY)
|
|
1470
479
|
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
480
|
+
**✅ EVERY hook MUST have**:
|
|
481
|
+
1. Kill switch check (`SPECWEAVE_DISABLE_HOOKS`)
|
|
482
|
+
2. Circuit breaker check (3 failure threshold)
|
|
483
|
+
3. File locking (prevent concurrent runs)
|
|
484
|
+
4. Debouncing (5s minimum)
|
|
485
|
+
5. Error isolation (`set +e`, `exit 0`)
|
|
486
|
+
6. Background work wrapped in subshell
|
|
487
|
+
7. Circuit breaker updates on success/failure
|
|
1475
488
|
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
489
|
+
**❌ NEVER in hooks**:
|
|
490
|
+
- `set -e` (causes crashes)
|
|
491
|
+
- Synchronous Node.js spawns
|
|
492
|
+
- Multiple separate background jobs
|
|
493
|
+
- Error propagation to Claude Code
|
|
494
|
+
- Missing `exit 0` at end
|
|
1479
495
|
|
|
1480
|
-
|
|
496
|
+
### Performance Targets
|
|
1481
497
|
|
|
1482
|
-
|
|
498
|
+
| Metric | Target | Warning | Critical |
|
|
499
|
+
|--------|--------|---------|----------|
|
|
500
|
+
| Hook execution | <100ms | 100-500ms | >500ms |
|
|
501
|
+
| Background processes | 0-2 | 3-5 | 6+ |
|
|
502
|
+
| Circuit breaker count | 0 | 1-2 | 3 (open) |
|
|
1483
503
|
|
|
1484
|
-
|
|
504
|
+
### Emergency Recovery
|
|
1485
505
|
|
|
506
|
+
**If Claude Code crashes**:
|
|
1486
507
|
```bash
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
npm run test:integration # Integration tests
|
|
1490
|
-
npm run test:e2e # E2E tests (Playwright)
|
|
1491
|
-
npm run test:all # All tests
|
|
1492
|
-
npm run test:coverage # Coverage report
|
|
1493
|
-
```
|
|
1494
|
-
|
|
1495
|
-
**Test structure**:
|
|
1496
|
-
- `tests/unit/` - Pure logic (no I/O)
|
|
1497
|
-
- `tests/integration/` - Organized by: `core/`, `external-tools/`, `generators/`, `features/`
|
|
1498
|
-
- `tests/e2e/` - Full user scenarios
|
|
1499
|
-
|
|
1500
|
-
**Naming**: ALL tests use `.test.ts` (NEVER `.spec.ts`)
|
|
1501
|
-
|
|
1502
|
-
### Writing Tests
|
|
1503
|
-
|
|
1504
|
-
```typescript
|
|
1505
|
-
// ✅ CORRECT
|
|
1506
|
-
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
1507
|
-
import fs from 'fs-extra';
|
|
1508
|
-
|
|
1509
|
-
vi.mock('fs-extra');
|
|
1510
|
-
|
|
1511
|
-
const mockReadFile = vi.mocked(fs.readFile);
|
|
508
|
+
# 1. Immediate kill switch
|
|
509
|
+
export SPECWEAVE_DISABLE_HOOKS=1
|
|
1512
510
|
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
mockReadFile.mockResolvedValue('content');
|
|
1516
|
-
});
|
|
1517
|
-
```
|
|
1518
|
-
|
|
1519
|
-
**Critical anti-patterns**:
|
|
1520
|
-
```typescript
|
|
1521
|
-
// ❌ NEVER use jest APIs
|
|
1522
|
-
jest.fn() // Use: vi.fn()
|
|
1523
|
-
jest.mock() // Use: vi.mock()
|
|
1524
|
-
|
|
1525
|
-
// ❌ NEVER use project root in tests
|
|
1526
|
-
const testRoot = path.join(process.cwd(), '.test-something');
|
|
1527
|
-
|
|
1528
|
-
// ✅ ALWAYS use temp directory
|
|
1529
|
-
const testRoot = path.join(os.tmpdir(), 'test-' + Date.now());
|
|
1530
|
-
```
|
|
511
|
+
# 2. Reset circuit breaker
|
|
512
|
+
rm -f .specweave/state/.hook-circuit-breaker
|
|
1531
513
|
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
import { createIsolatedTestDir } from '../test-utils/isolated-test-dir';
|
|
514
|
+
# 3. Clear locks
|
|
515
|
+
rm -rf .specweave/state/.hook-*.lock
|
|
1535
516
|
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
// Test code here
|
|
1539
|
-
} finally {
|
|
1540
|
-
await cleanup(); // ALWAYS cleanup
|
|
1541
|
-
}
|
|
517
|
+
# 4. Rebuild
|
|
518
|
+
npm run rebuild
|
|
1542
519
|
```
|
|
1543
520
|
|
|
1544
|
-
|
|
521
|
+
**See**:
|
|
522
|
+
- `.specweave/docs/internal/emergency-procedures/HOOK-CRASH-RECOVERY.md` (Complete recovery guide)
|
|
523
|
+
- ADR-0060 (Three-tier optimization architecture)
|
|
524
|
+
- `.specweave/increments/0050-*/reports/hook-crash-analysis.md` (Incident analysis)
|
|
1545
525
|
|
|
1546
|
-
|
|
1547
|
-
- `tsc`: `src/` → `dist/src/` (source files)
|
|
1548
|
-
- `esbuild`: `plugins/**/lib/hooks/*.ts` → in-place `.js` (hooks only)
|
|
526
|
+
---
|
|
1549
527
|
|
|
1550
|
-
|
|
1551
|
-
```typescript
|
|
1552
|
-
#!/usr/bin/env node
|
|
1553
|
-
import { ACStatusManager } from '../../../../dist/src/core/...'; // Use dist/
|
|
1554
|
-
```
|
|
528
|
+
## Development Workflow
|
|
1555
529
|
|
|
1556
|
-
**
|
|
1557
|
-
```
|
|
1558
|
-
|
|
1559
|
-
|
|
530
|
+
**Core commands**:
|
|
531
|
+
```bash
|
|
532
|
+
/specweave:increment "feature" # Plan
|
|
533
|
+
/specweave:do # Execute
|
|
534
|
+
/specweave:progress # Status
|
|
535
|
+
/specweave:done 0002 # Close (validates)
|
|
536
|
+
/specweave:validate 0001 # Validate
|
|
537
|
+
/specweave:qa 0001 # Quality check
|
|
538
|
+
/specweave:pause/resume/abandon # State management
|
|
1560
539
|
```
|
|
1561
540
|
|
|
1562
|
-
**
|
|
541
|
+
**Local setup**:
|
|
1563
542
|
```bash
|
|
1564
|
-
|
|
543
|
+
git clone https://github.com/YOUR_USERNAME/specweave.git
|
|
544
|
+
cd specweave && npm install
|
|
545
|
+
mkdir -p ~/.claude/plugins/marketplaces
|
|
546
|
+
ln -s "$(pwd)" ~/.claude/plugins/marketplaces/specweave
|
|
547
|
+
bash scripts/install-git-hooks.sh
|
|
1565
548
|
```
|
|
1566
549
|
|
|
1567
|
-
### Coverage
|
|
1568
|
-
|
|
1569
|
-
- Critical paths: 90%+
|
|
1570
|
-
- Overall: 80%+
|
|
1571
|
-
|
|
1572
550
|
---
|
|
1573
551
|
|
|
1574
|
-
##
|
|
1575
|
-
|
|
1576
|
-
### Adding Components
|
|
552
|
+
## Build & Test
|
|
1577
553
|
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
554
|
+
**Build**:
|
|
555
|
+
```bash
|
|
556
|
+
npm run rebuild # Clean + build (development)
|
|
557
|
+
npm run build # Compile TS + copy deps
|
|
558
|
+
```
|
|
1582
559
|
|
|
1583
|
-
|
|
560
|
+
**Architecture**: `tsc` → `dist/src/`, esbuild → plugin hooks, copy deps → `plugins/*/lib/vendor/`
|
|
1584
561
|
|
|
1585
|
-
|
|
562
|
+
**CRITICAL**: Always `.js` extensions (`import { foo } from './bar.js'`)
|
|
1586
563
|
|
|
564
|
+
**Test**:
|
|
1587
565
|
```bash
|
|
1588
|
-
#
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
#
|
|
1592
|
-
|
|
566
|
+
npm test # Smoke
|
|
567
|
+
npm run test:unit # Unit
|
|
568
|
+
npm run test:integration # Integration
|
|
569
|
+
npm run test:all # All
|
|
570
|
+
npm run test:coverage # Coverage (80%+ required)
|
|
1593
571
|
```
|
|
1594
572
|
|
|
1595
|
-
|
|
573
|
+
**Test rules**:
|
|
574
|
+
- Use `vi.fn()` (NOT `jest.fn()`)
|
|
575
|
+
- Use `os.tmpdir()` (NOT `process.cwd()`)
|
|
576
|
+
- ALL tests = `.test.ts` (NEVER `.spec.ts`)
|
|
577
|
+
- Use `createIsolatedTestDir()` helper
|
|
1596
578
|
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
**Architecture**:
|
|
1600
|
-
- **Secrets** (tokens, passwords) → `.env` (gitignored, NEVER commit)
|
|
1601
|
-
- **Configuration** (domains, strategies, settings) → `.specweave/config.json` (committed to git)
|
|
579
|
+
---
|
|
1602
580
|
|
|
1603
|
-
|
|
1604
|
-
- ✅ Team shares configuration via git
|
|
1605
|
-
- ✅ Secrets stay local (12-Factor App pattern)
|
|
1606
|
-
- ✅ Onboarding: `cp .env.example .env` (fill in your tokens)
|
|
1607
|
-
- ✅ Type-safe configuration with validation
|
|
581
|
+
## Configuration Management (v0.24.0+)
|
|
1608
582
|
|
|
1609
|
-
**
|
|
583
|
+
**Secrets** (.env, gitignored) vs **Config** (.specweave/config.json, committed)
|
|
1610
584
|
|
|
1611
585
|
```typescript
|
|
1612
586
|
import { getConfigManager } from '../core/config/index.js';
|
|
1613
587
|
|
|
1614
|
-
// Read configuration
|
|
1615
588
|
const configManager = getConfigManager(projectRoot);
|
|
1616
589
|
const config = await configManager.read();
|
|
590
|
+
await configManager.update({ issueTracker: { provider: 'jira', domain: 'example.atlassian.net' }});
|
|
591
|
+
```
|
|
1617
592
|
|
|
1618
|
-
|
|
1619
|
-
const domain = await configManager.get('issueTracker.domain');
|
|
1620
|
-
|
|
1621
|
-
// Update configuration
|
|
1622
|
-
await configManager.update({
|
|
1623
|
-
issueTracker: {
|
|
1624
|
-
provider: 'jira',
|
|
1625
|
-
domain: 'example.atlassian.net',
|
|
1626
|
-
strategy: 'project-per-team'
|
|
1627
|
-
}
|
|
1628
|
-
});
|
|
1629
|
-
|
|
1630
|
-
// Write entire config (validates before writing)
|
|
1631
|
-
await configManager.write(newConfig);
|
|
593
|
+
**What goes where**:
|
|
1632
594
|
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
595
|
+
| Type | Location | Example | Committed? |
|
|
596
|
+
|------|----------|---------|------------|
|
|
597
|
+
| Tokens/Emails | `.env` | `JIRA_API_TOKEN=xyz` | ❌ |
|
|
598
|
+
| Domains/Strategies | `config.json` | `"domain": "example.atlassian.net"` | ✅ |
|
|
1636
599
|
|
|
1637
|
-
**
|
|
600
|
+
**Migration**: `node -e "require('./dist/src/cli/commands/migrate-config.js').migrateConfig({ dryRun: true })"`
|
|
1638
601
|
|
|
1639
|
-
|
|
1640
|
-
// Step 1: Save secrets to .env (gitignored)
|
|
1641
|
-
const secretEnvVars = getJiraEnvVars(credentials); // ONLY tokens/emails
|
|
1642
|
-
saveCredentialsToEnv(projectPath, 'jira', secretEnvVars);
|
|
602
|
+
**See**: ADR-0050, `src/core/config/config-manager.ts`
|
|
1643
603
|
|
|
1644
|
-
|
|
1645
|
-
const configManager = getConfigManager(projectPath);
|
|
1646
|
-
const jiraConfig = getJiraConfig(credentials); // domain, strategy, projects
|
|
1647
|
-
await configManager.update(jiraConfig);
|
|
604
|
+
---
|
|
1648
605
|
|
|
1649
|
-
|
|
1650
|
-
generateEnvExample(projectPath, 'jira');
|
|
1651
|
-
```
|
|
606
|
+
## Cache Management (v0.24.0+)
|
|
1652
607
|
|
|
1653
|
-
**
|
|
608
|
+
**Smart Caching with 24-Hour TTL**: Reduces API calls by 90% during init and sync operations.
|
|
1654
609
|
|
|
1655
|
-
|
|
1656
|
-
|-----------|----------|---------|------------|
|
|
1657
|
-
| API Tokens | `.env` | `JIRA_API_TOKEN=xyz` | ❌ Never |
|
|
1658
|
-
| Emails | `.env` | `JIRA_EMAIL=user@example.com` | ❌ Never |
|
|
1659
|
-
| Domains | `config.json` | `"domain": "example.atlassian.net"` | ✅ Yes |
|
|
1660
|
-
| Strategies | `config.json` | `"strategy": "project-per-team"` | ✅ Yes |
|
|
1661
|
-
| Project Keys | `config.json` | `"projects": [{"key": "PROJ1"}]` | ✅ Yes |
|
|
1662
|
-
| Sync Settings | `config.json` | `"includeStatus": true` | ✅ Yes |
|
|
610
|
+
### Cache Architecture
|
|
1663
611
|
|
|
1664
|
-
**
|
|
612
|
+
**Location**: `.specweave/cache/`
|
|
613
|
+
**TTL**: 24 hours (configurable)
|
|
614
|
+
**Format**: JSON with timestamps
|
|
1665
615
|
|
|
1666
|
-
|
|
616
|
+
### Cached Data
|
|
1667
617
|
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
// path: 'issueTracker.provider',
|
|
1675
|
-
// message: 'Invalid provider. Must be one of: none, jira, github, ado',
|
|
1676
|
-
// value: 'invalid-provider'
|
|
1677
|
-
// }
|
|
1678
|
-
}
|
|
1679
|
-
```
|
|
618
|
+
| Cache Key | Data | Use Case |
|
|
619
|
+
|-----------|------|----------|
|
|
620
|
+
| `jira-projects-{domain}` | Project list | JIRA init (auto-discovery) |
|
|
621
|
+
| `ado-config` | Org/project/teams | ADO init (manual entry) |
|
|
622
|
+
| `jira-{PROJECT}-deps` | Boards, components, versions | On-demand dependency loading |
|
|
623
|
+
| `ado-{PROJECT}-deps` | Area paths, teams | ADO dependency loading |
|
|
1680
624
|
|
|
1681
|
-
|
|
625
|
+
### Cache Operations
|
|
1682
626
|
|
|
1683
|
-
|
|
627
|
+
**Automatic caching** (during init):
|
|
628
|
+
- JIRA: `promptJiraCredentials()` caches selected projects
|
|
629
|
+
- ADO: `promptAzureDevOpsCredentials()` caches org/project config
|
|
1684
630
|
|
|
631
|
+
**Manual cache management**:
|
|
1685
632
|
```bash
|
|
1686
|
-
#
|
|
1687
|
-
|
|
633
|
+
# Refresh cache (bypass TTL)
|
|
634
|
+
/specweave-jira:refresh-cache --all
|
|
635
|
+
/specweave-ado:refresh-cache --all
|
|
1688
636
|
|
|
1689
|
-
#
|
|
1690
|
-
|
|
637
|
+
# Clean old caches
|
|
638
|
+
/specweave:cleanup-cache --older-than 7d
|
|
1691
639
|
|
|
1692
|
-
#
|
|
1693
|
-
|
|
640
|
+
# View cache statistics
|
|
641
|
+
/specweave:cache-stats
|
|
1694
642
|
```
|
|
1695
643
|
|
|
1696
|
-
|
|
1697
|
-
1. ✅ Analyzes `.env` file and classifies variables
|
|
1698
|
-
2. ✅ Creates backup: `.env.backup.TIMESTAMP`
|
|
1699
|
-
3. ✅ Updates `.env` (keeps only secrets)
|
|
1700
|
-
4. ✅ Creates/updates `.specweave/config.json` (adds config)
|
|
1701
|
-
5. ✅ Generates `.env.example` for team onboarding
|
|
644
|
+
### Cache Security
|
|
1702
645
|
|
|
1703
|
-
**
|
|
1704
|
-
|
|
1705
|
-
|
|
646
|
+
**Never cached**: API tokens, PATs, passwords (secrets stay in `.env`)
|
|
647
|
+
**Always cached**: Non-sensitive config (domains, project keys, org names)
|
|
648
|
+
**Atomic writes**: Temp file → rename pattern prevents corruption
|
|
649
|
+
**Auto-recovery**: Corrupted cache auto-deleted, fallback to API
|
|
1706
650
|
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
- `src/
|
|
1711
|
-
- `
|
|
651
|
+
### Integration
|
|
652
|
+
|
|
653
|
+
**CLI Helpers**:
|
|
654
|
+
- `src/cli/helpers/issue-tracker/jira.ts`: JIRA project caching
|
|
655
|
+
- `src/cli/helpers/issue-tracker/ado.ts`: ADO config caching
|
|
656
|
+
|
|
657
|
+
**Core Module**:
|
|
658
|
+
- `src/core/cache/cache-manager.ts`: TTL validation, atomic writes, corruption handling
|
|
659
|
+
|
|
660
|
+
**Tests**:
|
|
661
|
+
- `tests/integration/cli/helpers/cache-integration.test.ts`: 85%+ coverage
|
|
662
|
+
|
|
663
|
+
**See**: ADR-0051 (Smart Caching with TTL), `src/core/cache/rate-limit-checker.ts`
|
|
1712
664
|
|
|
1713
665
|
---
|
|
1714
666
|
|
|
1715
667
|
## Troubleshooting
|
|
1716
668
|
|
|
1717
|
-
**Skills not activating**: Check YAML frontmatter, restart Claude Code
|
|
1718
|
-
**Commands not working**: Verify plugin installed, restart
|
|
1719
|
-
**Tests failing**:
|
|
1720
|
-
**Root
|
|
1721
|
-
**Hooks failing**:
|
|
669
|
+
- **Skills not activating**: Check YAML frontmatter, restart Claude Code
|
|
670
|
+
- **Commands not working**: Verify plugin installed, restart
|
|
671
|
+
- **Tests failing**: `npm run rebuild`
|
|
672
|
+
- **Root polluted**: Move to `.specweave/increments/####/reports/`
|
|
673
|
+
- **Hooks failing**: Push to GitHub (auto-updates 5-10s)
|
|
1722
674
|
|
|
1723
675
|
---
|
|
1724
676
|
|
|
1725
677
|
## Quick Reference
|
|
1726
678
|
|
|
1727
|
-
**Commands**:
|
|
1728
|
-
- `/specweave:increment "feature"` - Plan
|
|
1729
|
-
- `/specweave:do` - Execute
|
|
1730
|
-
- `/specweave:done 0002` - Close (validates)
|
|
1731
|
-
- `/specweave:status` - Show status
|
|
1732
|
-
- `/specweave:progress` - Check progress
|
|
1733
|
-
- `/specweave:validate 0002` - Validate
|
|
1734
|
-
- `/specweave:qa 0002` - Quality check
|
|
1735
|
-
- `/specweave:pause/resume/abandon` - State management
|
|
1736
|
-
- `/specweave:archive/restore` - Archiving (manual only)
|
|
1737
|
-
- `/specweave:sync-docs update` - Sync living docs
|
|
679
|
+
**Commands**: `/specweave:increment`, `/specweave:do`, `/specweave:done`, `/specweave:progress`, `/specweave:validate`, `/specweave:qa`
|
|
1738
680
|
|
|
1739
|
-
**Build**:
|
|
1740
|
-
- `npm run rebuild` - Clean + build
|
|
1741
|
-
- `npm test` - Smoke tests
|
|
1742
|
-
- `npm run test:all` - All tests
|
|
1743
|
-
- `npm run test:coverage` - Coverage
|
|
681
|
+
**Build**: `npm run rebuild`, `npm test`, `npm run test:all`
|
|
1744
682
|
|
|
1745
|
-
**
|
|
1746
|
-
- Source: `src/` (TypeScript), `plugins/` (skills/agents/commands/hooks)
|
|
1747
|
-
- Increments: `.specweave/increments/`
|
|
1748
|
-
- Docs: `.specweave/docs/internal/`, `.specweave/docs/public/`
|
|
1749
|
-
- Tests: `tests/` (unit, integration, E2E)
|
|
683
|
+
**Structure**: `src/` (TS), `plugins/` (components), `.specweave/` (data), `tests/` (tests)
|
|
1750
684
|
|
|
1751
685
|
**Remember**:
|
|
1752
|
-
1. Push
|
|
1753
|
-
2. Keep root clean
|
|
1754
|
-
3. Test before
|
|
1755
|
-
4.
|
|
1756
|
-
5. Use `/specweave:done` (
|
|
686
|
+
1. Push → GitHub → Claude Code auto-updates (5-10s)
|
|
687
|
+
2. Keep root clean
|
|
688
|
+
3. Test before commit
|
|
689
|
+
4. NEVER delete `.specweave/`
|
|
690
|
+
5. Use `/specweave:done` (not manual edits)
|
|
691
|
+
|
|
692
|
+
**See**: `.github/CONTRIBUTING.md`, https://spec-weave.com
|
|
1757
693
|
|
|
1758
|
-
**See also**: `.github/CONTRIBUTING.md`, https://spec-weave.com
|