@champpaba/claude-agent-kit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +561 -0
- package/bin/cli.js +61 -0
- package/lib/init.js +52 -0
- package/lib/update.js +73 -0
- package/package.json +47 -0
- package/template/.claude/CHANGELOG-v1.1.1.md +259 -0
- package/template/.claude/CLAUDE.md +329 -0
- package/template/.claude/agents/01-integration.md +797 -0
- package/template/.claude/agents/02-uxui-frontend.md +899 -0
- package/template/.claude/agents/03-test-debug.md +759 -0
- package/template/.claude/agents/04-frontend.md +1099 -0
- package/template/.claude/agents/05-backend.md +1217 -0
- package/template/.claude/agents/06-database.md +969 -0
- package/template/.claude/commands/agentsetup.md +1464 -0
- package/template/.claude/commands/cdev.md +327 -0
- package/template/.claude/commands/csetup.md +447 -0
- package/template/.claude/commands/cstatus.md +60 -0
- package/template/.claude/commands/cview.md +364 -0
- package/template/.claude/commands/psetup.md +101 -0
- package/template/.claude/contexts/design/accessibility.md +611 -0
- package/template/.claude/contexts/design/box-thinking.md +553 -0
- package/template/.claude/contexts/design/color-theory.md +498 -0
- package/template/.claude/contexts/design/index.md +247 -0
- package/template/.claude/contexts/design/layout.md +400 -0
- package/template/.claude/contexts/design/responsive.md +551 -0
- package/template/.claude/contexts/design/shadows.md +522 -0
- package/template/.claude/contexts/design/spacing.md +428 -0
- package/template/.claude/contexts/design/typography.md +465 -0
- package/template/.claude/contexts/domain/README.md +164 -0
- package/template/.claude/contexts/patterns/agent-coordination.md +388 -0
- package/template/.claude/contexts/patterns/agent-discovery.md +182 -0
- package/template/.claude/contexts/patterns/change-workflow.md +538 -0
- package/template/.claude/contexts/patterns/code-standards.md +515 -0
- package/template/.claude/contexts/patterns/development-principles.md +513 -0
- package/template/.claude/contexts/patterns/error-handling.md +478 -0
- package/template/.claude/contexts/patterns/error-recovery.md +365 -0
- package/template/.claude/contexts/patterns/frontend-component-strategy.md +365 -0
- package/template/.claude/contexts/patterns/git-workflow.md +207 -0
- package/template/.claude/contexts/patterns/logging.md +424 -0
- package/template/.claude/contexts/patterns/task-breakdown.md +452 -0
- package/template/.claude/contexts/patterns/task-classification.md +523 -0
- package/template/.claude/contexts/patterns/tdd-classification.md +516 -0
- package/template/.claude/contexts/patterns/testing.md +413 -0
- package/template/.claude/contexts/patterns/ui-component-consistency.md +304 -0
- package/template/.claude/contexts/patterns/validation-framework.md +776 -0
- package/template/.claude/lib/README.md +39 -0
- package/template/.claude/lib/agent-executor.md +258 -0
- package/template/.claude/lib/agent-router.md +572 -0
- package/template/.claude/lib/flags-updater.md +469 -0
- package/template/.claude/lib/tdd-classifier.md +345 -0
- package/template/.claude/lib/validation-gates.md +484 -0
- package/template/.claude/settings.local.json +42 -0
- package/template/.claude/templates/context-template.md +45 -0
- package/template/.claude/templates/flags-template.json +42 -0
- package/template/.claude/templates/phase-templates.json +124 -0
- package/template/.claude/templates/phases-sections/accessibility-test.md +17 -0
- package/template/.claude/templates/phases-sections/api-design.md +37 -0
- package/template/.claude/templates/phases-sections/backend-tests.md +16 -0
- package/template/.claude/templates/phases-sections/backend.md +37 -0
- package/template/.claude/templates/phases-sections/business-logic-validation.md +16 -0
- package/template/.claude/templates/phases-sections/component-tests.md +17 -0
- package/template/.claude/templates/phases-sections/contract-backend.md +16 -0
- package/template/.claude/templates/phases-sections/contract-frontend.md +16 -0
- package/template/.claude/templates/phases-sections/database.md +35 -0
- package/template/.claude/templates/phases-sections/documentation.md +17 -0
- package/template/.claude/templates/phases-sections/e2e-tests.md +16 -0
- package/template/.claude/templates/phases-sections/fix-implementation.md +17 -0
- package/template/.claude/templates/phases-sections/frontend-integration.md +18 -0
- package/template/.claude/templates/phases-sections/frontend-mockup.md +123 -0
- package/template/.claude/templates/phases-sections/manual-flow-test.md +15 -0
- package/template/.claude/templates/phases-sections/manual-ux-test.md +16 -0
- package/template/.claude/templates/phases-sections/refactor-implementation.md +17 -0
- package/template/.claude/templates/phases-sections/refactor.md +16 -0
- package/template/.claude/templates/phases-sections/regression-tests.md +15 -0
- package/template/.claude/templates/phases-sections/report.md +16 -0
- package/template/.claude/templates/phases-sections/responsive-test.md +16 -0
- package/template/.claude/templates/phases-sections/script-implementation.md +43 -0
- package/template/.claude/templates/phases-sections/test-coverage.md +16 -0
- package/template/.claude/templates/phases-sections/user-approval.md +14 -0
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
# Flags.json Update Protocol
|
|
2
|
+
|
|
3
|
+
> **WHO:** Main Claude (orchestrator)
|
|
4
|
+
> **WHEN:** Immediately after sub-agent completes phase
|
|
5
|
+
> **HOW:** Follow this exact flow
|
|
6
|
+
> **PURPOSE:** Ensure real-time progress tracking for users
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## šÆ Core Principle
|
|
11
|
+
|
|
12
|
+
**Main Claude is ALWAYS responsible for updating flags.json**
|
|
13
|
+
|
|
14
|
+
- ā NOT sub-agents (they don't have direct access)
|
|
15
|
+
- ā NOT user (they shouldn't have to)
|
|
16
|
+
- ā
Main Claude after EVERY phase completion
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## š Update Flow
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Step 1: Sub-agent responds with completion message
|
|
24
|
+
ā
|
|
25
|
+
Step 2: Main Claude validates response quality
|
|
26
|
+
ā
|
|
27
|
+
Step 3: Main Claude updates flags.json (MANDATORY - THIS STEP!)
|
|
28
|
+
ā
|
|
29
|
+
Step 4: Main Claude reports progress to user
|
|
30
|
+
ā
|
|
31
|
+
Step 5: Main Claude asks to continue (or auto-continue)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**ā ļø CRITICAL:** Step 3 CANNOT be skipped. Ever.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## š Update Implementation
|
|
39
|
+
|
|
40
|
+
### Function Specification
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
/**
|
|
44
|
+
* Updates flags.json after a phase completes
|
|
45
|
+
*
|
|
46
|
+
* WHEN TO CALL: Immediately after sub-agent responds successfully
|
|
47
|
+
* WHERE: In /cdev command, Step 5 (Post-Execution)
|
|
48
|
+
*/
|
|
49
|
+
function updateFlagsAfterPhase(
|
|
50
|
+
changeId: string,
|
|
51
|
+
phaseName: string,
|
|
52
|
+
agentResponse: string
|
|
53
|
+
): void {
|
|
54
|
+
|
|
55
|
+
// 1. Read current flags
|
|
56
|
+
const flagsPath = `openspec/changes/${changeId}/.claude/flags.json`
|
|
57
|
+
|
|
58
|
+
if (!fileExists(flagsPath)) {
|
|
59
|
+
throw new Error(`flags.json not found at ${flagsPath}`)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const flags = JSON.parse(Read(flagsPath))
|
|
63
|
+
|
|
64
|
+
// 2. Extract information from agent response
|
|
65
|
+
const filesCreated = extractFilesCreated(agentResponse)
|
|
66
|
+
const filesModified = extractFilesModified(agentResponse)
|
|
67
|
+
const tasksCompleted = extractTaskIds(agentResponse)
|
|
68
|
+
const notes = extractSummary(agentResponse)
|
|
69
|
+
|
|
70
|
+
// Calculate duration
|
|
71
|
+
const startedAt = flags.phases[phaseName].started_at
|
|
72
|
+
const completedAt = new Date().toISOString()
|
|
73
|
+
const actualMinutes = calculateMinutes(startedAt, completedAt)
|
|
74
|
+
|
|
75
|
+
// 3. Update phase status
|
|
76
|
+
flags.phases[phaseName] = {
|
|
77
|
+
...flags.phases[phaseName],
|
|
78
|
+
status: 'completed',
|
|
79
|
+
completed_at: completedAt,
|
|
80
|
+
actual_minutes: actualMinutes,
|
|
81
|
+
files_created: filesCreated,
|
|
82
|
+
files_modified: filesModified,
|
|
83
|
+
tasks_completed: tasksCompleted,
|
|
84
|
+
notes: notes.substring(0, 200) // Limit to 200 chars
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 4. Update meta statistics
|
|
88
|
+
flags.meta.completed_phases++
|
|
89
|
+
flags.meta.pending_phases--
|
|
90
|
+
flags.meta.in_progress_phases = 0 // Reset in-progress
|
|
91
|
+
flags.meta.progress_percentage = Math.round(
|
|
92
|
+
(flags.meta.completed_phases / flags.meta.total_phases) * 100
|
|
93
|
+
)
|
|
94
|
+
flags.meta.total_actual_minutes += actualMinutes
|
|
95
|
+
flags.meta.time_remaining_estimate = calculateTimeRemaining(flags)
|
|
96
|
+
|
|
97
|
+
// Update file counts
|
|
98
|
+
flags.meta.files_created += filesCreated.length
|
|
99
|
+
flags.meta.files_modified += filesModified.length
|
|
100
|
+
|
|
101
|
+
// 5. Move to next phase
|
|
102
|
+
const nextPhase = getNextPhaseName(flags)
|
|
103
|
+
flags.current_phase = nextPhase
|
|
104
|
+
|
|
105
|
+
if (nextPhase && flags.phases[nextPhase]) {
|
|
106
|
+
flags.phases[nextPhase].status = 'pending'
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 6. Check if all complete
|
|
110
|
+
if (flags.meta.completed_phases === flags.meta.total_phases) {
|
|
111
|
+
flags.ready_to_archive = true
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 7. Update timestamp
|
|
115
|
+
flags.updated_at = new Date().toISOString()
|
|
116
|
+
|
|
117
|
+
// 8. Add to history
|
|
118
|
+
flags.history.push({
|
|
119
|
+
timestamp: completedAt,
|
|
120
|
+
action: 'phase_completed',
|
|
121
|
+
phase: phaseName,
|
|
122
|
+
duration_minutes: actualMinutes
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
// 9. Write back to file
|
|
126
|
+
Write(flagsPath, JSON.stringify(flags, null, 2))
|
|
127
|
+
|
|
128
|
+
// 10. Report success (to terminal, visible to user)
|
|
129
|
+
output(`\nš Progress Updated:`)
|
|
130
|
+
output(` ā
Phase "${phaseName}" marked complete`)
|
|
131
|
+
output(` ā±ļø Duration: ${actualMinutes} min (estimated: ${flags.phases[phaseName].estimated_minutes} min)`)
|
|
132
|
+
output(` š Files: ${filesCreated.length} created, ${filesModified.length} modified`)
|
|
133
|
+
output(` š Progress: ${flags.meta.progress_percentage}% (${flags.meta.completed_phases}/${flags.meta.total_phases})`)
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## š Helper Functions
|
|
140
|
+
|
|
141
|
+
### extractFilesCreated()
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
function extractFilesCreated(response: string): string[] {
|
|
145
|
+
const patterns = [
|
|
146
|
+
/(?:Created|created|Created:)\s*(.+)/gi,
|
|
147
|
+
/š\s*(?:Created|created):\s*(.+)/gi,
|
|
148
|
+
/ā
\s*Created\s+file:\s*(.+)/gi,
|
|
149
|
+
/new file:\s*(.+)/gi
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
const files: string[] = []
|
|
153
|
+
|
|
154
|
+
for (const pattern of patterns) {
|
|
155
|
+
const matches = response.matchAll(pattern)
|
|
156
|
+
for (const match of matches) {
|
|
157
|
+
// Extract file paths (one per line or comma-separated)
|
|
158
|
+
const paths = match[1].split(/[,\n]/).map(p => p.trim())
|
|
159
|
+
files.push(...paths.filter(p => p.length > 0))
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Remove duplicates
|
|
164
|
+
return [...new Set(files)]
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### extractFilesModified()
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
function extractFilesModified(response: string): string[] {
|
|
172
|
+
const patterns = [
|
|
173
|
+
/(?:Modified|modified|Updated|updated):\s*(.+)/gi,
|
|
174
|
+
/š\s*(?:Modified|updated):\s*(.+)/gi,
|
|
175
|
+
/āļø\s*Updated\s+file:\s*(.+)/gi
|
|
176
|
+
]
|
|
177
|
+
|
|
178
|
+
const files: string[] = []
|
|
179
|
+
|
|
180
|
+
for (const pattern of patterns) {
|
|
181
|
+
const matches = response.matchAll(pattern)
|
|
182
|
+
for (const match of matches) {
|
|
183
|
+
const paths = match[1].split(/[,\n]/).map(p => p.trim())
|
|
184
|
+
files.push(...paths.filter(p => p.length > 0))
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return [...new Set(files)]
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### extractTaskIds()
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
function extractTaskIds(response: string): string[] {
|
|
196
|
+
// Look for task IDs like "1.1", "1.2", "2.1"
|
|
197
|
+
const pattern = /(?:task|Task)\s*(?:ID|id)?:?\s*([\d\.]+)/gi
|
|
198
|
+
const matches = response.matchAll(pattern)
|
|
199
|
+
|
|
200
|
+
const taskIds: string[] = []
|
|
201
|
+
for (const match of matches) {
|
|
202
|
+
taskIds.push(match[1])
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return taskIds
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### extractSummary()
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
function extractSummary(response: string): string {
|
|
213
|
+
// Look for summary section
|
|
214
|
+
const summaryPatterns = [
|
|
215
|
+
/(?:Summary|SUMMARY):\s*(.+?)(?:\n\n|\n#|$)/si,
|
|
216
|
+
/(?:Notes|NOTES):\s*(.+?)(?:\n\n|\n#|$)/si,
|
|
217
|
+
/(?:Completed|COMPLETED):\s*(.+?)(?:\n\n|\n#|$)/si
|
|
218
|
+
]
|
|
219
|
+
|
|
220
|
+
for (const pattern of summaryPatterns) {
|
|
221
|
+
const match = response.match(pattern)
|
|
222
|
+
if (match) {
|
|
223
|
+
return match[1].trim()
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Fallback: First 200 chars of response
|
|
228
|
+
return response.substring(0, 200).trim()
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### calculateMinutes()
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
function calculateMinutes(startISO: string, endISO: string): number {
|
|
236
|
+
const start = new Date(startISO)
|
|
237
|
+
const end = new Date(endISO)
|
|
238
|
+
const diffMs = end - start
|
|
239
|
+
return Math.round(diffMs / 1000 / 60) // Convert to minutes
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### getNextPhaseName()
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
function getNextPhaseName(flags: Flags): string | null {
|
|
247
|
+
// Get all phase names in order
|
|
248
|
+
const phaseNames = Object.keys(flags.phases).sort((a, b) => {
|
|
249
|
+
return flags.phases[a].phase_number - flags.phases[b].phase_number
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
// Find first pending phase
|
|
253
|
+
for (const name of phaseNames) {
|
|
254
|
+
if (flags.phases[name].status === 'pending') {
|
|
255
|
+
return name
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// All phases complete
|
|
260
|
+
return null
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### calculateTimeRemaining()
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
function calculateTimeRemaining(flags: Flags): number {
|
|
268
|
+
let remaining = 0
|
|
269
|
+
|
|
270
|
+
for (const [name, phase] of Object.entries(flags.phases)) {
|
|
271
|
+
if (phase.status === 'pending' || phase.status === 'in_progress') {
|
|
272
|
+
remaining += phase.estimated_minutes || 0
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return remaining
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## ā ļø CRITICAL RULES
|
|
283
|
+
|
|
284
|
+
### Rule 1: NEVER Skip This Step
|
|
285
|
+
|
|
286
|
+
```markdown
|
|
287
|
+
ā WRONG:
|
|
288
|
+
Sub-agent completes ā Main Claude asks user to continue
|
|
289
|
+
(flags.json not updated)
|
|
290
|
+
|
|
291
|
+
ā
CORRECT:
|
|
292
|
+
Sub-agent completes ā Main Claude updates flags.json ā Main Claude reports progress ā Main Claude asks user to continue
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Rule 2: Update IMMEDIATELY After Sub-Agent Responds
|
|
296
|
+
|
|
297
|
+
```markdown
|
|
298
|
+
Don't wait for:
|
|
299
|
+
- ā User confirmation
|
|
300
|
+
- ā Next phase to start
|
|
301
|
+
- ā Batch multiple updates
|
|
302
|
+
|
|
303
|
+
Update:
|
|
304
|
+
- ā
As soon as sub-agent returns success
|
|
305
|
+
- ā
Before asking user anything
|
|
306
|
+
- ā
After EACH individual phase
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Rule 3: Validate Before Update
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
// Check 1: flags.json exists
|
|
313
|
+
if (!fileExists(flagsPath)) {
|
|
314
|
+
output(`ā Error: flags.json not found`)
|
|
315
|
+
output(`Run: /csetup ${changeId}`)
|
|
316
|
+
return
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Check 2: Phase exists in flags
|
|
320
|
+
if (!flags.phases[phaseName]) {
|
|
321
|
+
output(`ā Error: Phase "${phaseName}" not found in flags.json`)
|
|
322
|
+
return
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Check 3: Sub-agent actually completed work
|
|
326
|
+
if (!agentResponse.includes('ā
') && !agentResponse.includes('Complete')) {
|
|
327
|
+
output(`ā ļø Warning: Agent response does not confirm completion`)
|
|
328
|
+
output(`Proceed with caution`)
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Rule 4: Always Report to User
|
|
333
|
+
|
|
334
|
+
```markdown
|
|
335
|
+
After updating flags.json, ALWAYS show:
|
|
336
|
+
|
|
337
|
+
š Progress Updated:
|
|
338
|
+
ā
Phase "frontend-mockup" marked complete
|
|
339
|
+
ā±ļø Duration: 95 min (estimated: 90 min)
|
|
340
|
+
š Files: 4 created, 0 modified
|
|
341
|
+
š Progress: 9% (1/11)
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## š Error Handling
|
|
347
|
+
|
|
348
|
+
### Scenario 1: flags.json Not Found
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
if (!fileExists(flagsPath)) {
|
|
352
|
+
output(`ā Error: flags.json not found`)
|
|
353
|
+
output(`Expected at: ${flagsPath}`)
|
|
354
|
+
output(`\nPlease run: /csetup ${changeId}`)
|
|
355
|
+
throw new Error('flags.json not found')
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Scenario 2: Invalid JSON
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
try {
|
|
363
|
+
const flags = JSON.parse(Read(flagsPath))
|
|
364
|
+
} catch (error) {
|
|
365
|
+
output(`ā Error: flags.json is corrupted (invalid JSON)`)
|
|
366
|
+
output(`\nOptions:`)
|
|
367
|
+
output(`1. Restore from backup`)
|
|
368
|
+
output(`2. Re-run: /csetup ${changeId} (will overwrite)`)
|
|
369
|
+
throw new Error('Invalid flags.json')
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Scenario 3: Phase Not Found
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
if (!flags.phases[phaseName]) {
|
|
377
|
+
output(`ā Error: Phase "${phaseName}" not found in flags.json`)
|
|
378
|
+
output(`\nAvailable phases:`)
|
|
379
|
+
Object.keys(flags.phases).forEach(name => {
|
|
380
|
+
output(` - ${name}`)
|
|
381
|
+
})
|
|
382
|
+
throw new Error('Phase not found')
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Scenario 4: Cannot Extract Files
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
const filesCreated = extractFilesCreated(agentResponse)
|
|
390
|
+
|
|
391
|
+
if (filesCreated.length === 0) {
|
|
392
|
+
output(`ā ļø Warning: Could not extract created files from agent response`)
|
|
393
|
+
output(`\nPlease manually specify files (comma-separated, or press Enter to skip):`)
|
|
394
|
+
const userInput = await getUserInput()
|
|
395
|
+
if (userInput.trim()) {
|
|
396
|
+
filesCreated = userInput.split(',').map(f => f.trim())
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## š Success Indicators
|
|
404
|
+
|
|
405
|
+
After implementing this protocol, you should see:
|
|
406
|
+
|
|
407
|
+
1. **100% Update Rate**
|
|
408
|
+
- Every phase completion ā flags.json updated
|
|
409
|
+
- No manual intervention needed
|
|
410
|
+
|
|
411
|
+
2. **Real-Time Progress**
|
|
412
|
+
- User sees progress after every phase
|
|
413
|
+
- `/cstatus` shows accurate data
|
|
414
|
+
|
|
415
|
+
3. **Accurate Time Tracking**
|
|
416
|
+
- Actual vs estimated time recorded
|
|
417
|
+
- Efficiency metrics available
|
|
418
|
+
|
|
419
|
+
4. **Complete Audit Trail**
|
|
420
|
+
- History log in flags.json
|
|
421
|
+
- Can reconstruct entire workflow
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## š Integration Points
|
|
426
|
+
|
|
427
|
+
**This protocol is used by:**
|
|
428
|
+
- `/cdev` command (Step 5: Post-Execution)
|
|
429
|
+
- `/cstatus` command (reads updated flags)
|
|
430
|
+
- `/cview` command (reads updated flags)
|
|
431
|
+
|
|
432
|
+
**This protocol depends on:**
|
|
433
|
+
- `flags-template.json` (initial structure)
|
|
434
|
+
- `/csetup` command (creates flags.json)
|
|
435
|
+
- Sub-agents (provide completion responses)
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## šÆ Quick Reference
|
|
440
|
+
|
|
441
|
+
**Main Claude, after sub-agent completes:**
|
|
442
|
+
|
|
443
|
+
```typescript
|
|
444
|
+
// 1. Validate response
|
|
445
|
+
if (!validateAgentResponse(agentResponse)) {
|
|
446
|
+
// Handle retry or escalation
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// 2. Update flags.json (MANDATORY)
|
|
450
|
+
updateFlagsAfterPhase(changeId, currentPhase, agentResponse)
|
|
451
|
+
|
|
452
|
+
// 3. Read updated flags
|
|
453
|
+
const flags = JSON.parse(Read(`openspec/changes/${changeId}/.claude/flags.json`))
|
|
454
|
+
|
|
455
|
+
// 4. Report to user
|
|
456
|
+
output(`\nš Progress: ${flags.meta.progress_percentage}%`)
|
|
457
|
+
|
|
458
|
+
// 5. Ask to continue
|
|
459
|
+
if (flags.ready_to_archive) {
|
|
460
|
+
output('ā
All phases complete!')
|
|
461
|
+
} else {
|
|
462
|
+
output(`\nš Next: Phase ${flags.phases[flags.current_phase].phase_number}`)
|
|
463
|
+
output('Continue? (yes/no)')
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
**š” Remember:** Main Claude updates flags.json. Always. No exceptions.
|