@champpaba/claude-agent-kit 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,39 +40,69 @@ Run: /csetup {change-id}
40
40
 
41
41
  ### Step 2: Read Current Phase
42
42
 
43
- ```typescript
44
- const flags = JSON.parse(Read('openspec/changes/{change-id}/.claude/flags.json'))
45
- const currentPhase = flags.current_phase
46
- const phaseData = flags.phases[currentPhase]
43
+ ---
44
+
45
+ #### ขั้นตอนที่ 1: อ่าน flags.json
46
+
47
+ อ่านไฟล์ `openspec/changes/{change-id}/.claude/flags.json`
48
+
49
+ จดข้อมูลต่อไปนี้:
50
+ - `current_phase`: ชื่อ phase ปัจจุบัน
51
+ - `phases[current_phase].status`: สถานะของ phase
52
+ - `phases[current_phase].agent`: agent ที่ต้องใช้
53
+
54
+ ---
55
+
56
+ #### ขั้นตอนที่ 2: ตรวจสอบสถานะ phase
57
+
58
+ **ถ้า status = "completed":**
59
+ - หา phase ถัดไปจาก phases.md
60
+ - อัพเดต current_phase เป็น phase ถัดไป
61
+
62
+ **ถ้า status = "pending" หรือ "in_progress":**
63
+ - ใช้ phase ปัจจุบัน
64
+
65
+ ---
47
66
 
48
- if (phaseData.status === 'completed') {
49
- // Move to next phase
50
- currentPhase = getNextPhase(flags)
51
- }
67
+ #### ขั้นตอนที่ 3: Report สถานะ
68
+
69
+ ```
70
+ 📍 Current Phase: {phase_number} - {phase_name}
71
+ Agent: {agent}
72
+ Status: {status}
52
73
  ```
53
74
 
75
+ ---
76
+
54
77
  ### Step 3: Check Phase Type
55
78
 
56
- ```typescript
57
- const agent = phaseData.agent
79
+ ---
58
80
 
59
- if (agent === 'user') {
60
- // Manual action required
61
- output(`🛑 Phase ${phaseData.phase_number} requires manual action`)
62
- output(`Instructions: ${getInstructions(currentPhase)}`)
63
- output(`When done: /cdev ${changeId} --continue`)
64
- return
65
- }
81
+ #### ตรวจสอบว่า phase ต้องการ manual action หรือไม่
66
82
 
67
- if (agent.includes('+')) {
68
- // Multiple agents (parallel)
69
- agents = agent.split('+').map(a => a.trim())
70
- invokeMultipleAgents(agents, changeId, currentPhase)
71
- } else {
72
- // Single agent
73
- invokeAgent(agent, changeId, currentPhase)
74
- }
83
+ **ถ้า agent = "user":**
75
84
  ```
85
+ 🛑 Phase {phase_number} requires manual action
86
+
87
+ Instructions:
88
+ {instructions from phases.md}
89
+
90
+ When done: /cdev {change-id} --continue
91
+ ```
92
+ → หยุดทำงาน รอ user ทำเสร็จแล้ว run /cdev ใหม่
93
+
94
+ ---
95
+
96
+ #### ตรวจสอบว่ามี agent หลายตัวหรือไม่
97
+
98
+ **ถ้า agent มีเครื่องหมาย "+" (เช่น "backend + database"):**
99
+ - แยก agents ออกมาเป็น list
100
+ - Invoke agents พร้อมกัน (parallel)
101
+ - รอทุก agent เสร็จก่อนไปต่อ
102
+
103
+ **ถ้ามี agent ตัวเดียว:**
104
+ - Invoke agent ตัวนั้น
105
+ - รอเสร็จแล้วไป Step 4
76
106
 
77
107
  ### Step 4: Invoke Agent with Retry & Validation
78
108
 
@@ -84,283 +114,251 @@ See: `.claude/lib/agent-executor.md` for full implementation
84
114
 
85
115
  1. **Calculate Context Size** (for model selection)
86
116
  2. **Select Model** (haiku vs sonnet based on complexity)
87
- 3. **Execute Agent with Retry** (automatic retry on failure)
88
- 4. **Validate Pre-Work** (enforce mandatory checklist)
89
- 5. **Validate Output Quality** (check completeness)
90
- 6. **Handle Errors** (retry or escalate)
117
+ 3. **Pre-Flight Design Check** (for visual agents) ← NEW v3.3.0
118
+ 4. **Execute Agent with Retry** (automatic retry on failure)
119
+ 5. **Validate Pre-Work** (enforce mandatory checklist)
120
+ 6. **Validate Output Quality** (check completeness)
121
+ 7. **Handle Errors** (retry or escalate)
122
+
123
+ ### Step 4.0: Pre-Flight Design Check (v3.3.0)
91
124
 
92
- **Implementation:**
125
+ **Full Protocol:** `.claude/lib/design-validator.md` (Part 2)
93
126
 
94
- ```typescript
95
- // Step 4: Invoke Agent with Retry & Validation
127
+ **เมื่อไหร่ต้องทำ:** ก่อน invoke uxui-frontend หรือ frontend agent ทุกครั้ง
96
128
 
97
- // 4.1: Build agent prompt (with design reference + best practices - v2.1.2)
98
- function buildAgentPrompt(phase, changeContext) {
99
- let prompt = `
100
- # Phase ${phase.phase_number}: ${phase.name}
129
+ ---
101
130
 
102
- ## Change Context
103
- ${changeContext.proposal}
131
+ #### ขั้นตอนที่ 1: ตรวจสอบว่าเป็น visual agent หรือไม่
104
132
 
105
- ## Tasks
106
- ${changeContext.tasks}
133
+ ดู phase.agent ว่าเป็น `uxui-frontend` หรือ `frontend` หรือไม่
107
134
 
108
- ## Design Decisions (from design.md)
109
- ${changeContext.design || '(no design.md found)'}
135
+ **ถ้าไม่ใช่:** ข้าม Step 4.0 ไปเลย
110
136
 
111
- ${phase.instructions}
137
+ **ถ้าใช่:** ทำขั้นตอนถัดไป
112
138
 
113
139
  ---
114
140
 
115
- ## 📦 Library Requirements
141
+ #### ขั้นตอนที่ 2: ตรวจสอบว่ามี design system หรือไม่
116
142
 
117
- **Scan for required libraries before implementation:**
143
+ อ่านไฟล์ `design-system/data.yaml`
118
144
 
119
- 1. **Review tasks.md above** for these patterns:
120
- - "Install X and dependencies" → Use library X
121
- - "Configure X with Y adapter" → Use X with adapter Y
122
- - Backtick packages like \`better-auth\` → Required dependency
145
+ **ถ้ามีไฟล์:**
146
+ ```
147
+ Design system found: design-system/data.yaml
148
+ ```
149
+ → ไปขั้นตอนที่ 3
123
150
 
124
- 2. **Review "Design Decisions" section above** for:
125
- - "### D1: Use X Library" → Decision to use X
126
- - "**Decision:** Use X" Chosen library
127
- - Specific configurations (e.g., "JWT 15min", "Redis refresh token 30d")
128
- - Architecture decisions (e.g., "Hybrid Session Strategy")
151
+ **ถ้าไม่มีไฟล์:**
152
+ ```
153
+ ⚠️ WARNING: No design system found!
154
+ Path: design-system/data.yaml (not found)
129
155
 
130
- 3. **Use the specified libraries**
131
- - WHY: The team chose these for compatibility, features, or constraints
132
- - Custom implementations duplicate effort and miss edge cases the library handles
156
+ Options:
157
+ 1. Run /designsetup first (recommended)
158
+ 2. Continue with fallback design principles
133
159
 
134
- 4. **Implement according to Design Spec (not library defaults)**
135
- - If design.md specifies "JWT 15min + Redis refresh 30d" → Configure library with these values
136
- - If design.md specifies custom endpoints → Implement those endpoints
137
- - Library defaults are starting points, not final implementation
138
- - WHY: Design decisions were made for specific project requirements
160
+ Proceeding with fallback...
161
+ ```
162
+ ไปขั้นตอนที่ 4 โดยไม่ inject instruction
139
163
 
140
- **Example:**
141
- \`\`\`
142
- design.md says:
143
- "Hybrid Session Strategy: JWT 15min + Redis refresh 30d"
164
+ ---
144
165
 
145
- Use better-auth library (from tasks.md)
146
- → Configure JWT plugin with 15min expiry
147
- → Configure refresh token with 30d in Redis
148
- → Implement /api/auth/refresh endpoint
166
+ #### ขั้นตอนที่ 3: บอก agent ให้อ่าน design system
149
167
 
150
- WHY not defaults? Design spec has project-specific security requirements
151
- that differ from library defaults.
152
- \`\`\`
168
+ เมื่อ invoke agent ต้องบอกใน prompt ว่า:
153
169
 
154
- **Report in validation:**
155
- \`\`\`
156
- Libraries: better-auth, @better-auth/drizzle, ioredis
157
- Design Spec Implementation:
158
- - [x] JWT access token: 15min (design.md D1)
159
- - [x] Redis refresh token: 30d (design.md D2)
160
- - [x] /api/auth/refresh endpoint (design.md D3)
161
- \`\`\`
170
+ ```
171
+ MANDATORY: Read design-system/data.yaml before writing any CSS/Tailwind.
172
+ Report the tokens you loaded before starting implementation.
173
+
174
+ You must report:
175
+ - Colors: primary=#xxx, secondary=#xxx, etc.
176
+ - Spacing scale: 4, 8, 12, 16, 24, 32, 48, 64
177
+ - Animation durations: 150ms, 300ms, 500ms ONLY
178
+
179
+ DO NOT use:
180
+ - Hardcoded colors (#3b82f6, rgb())
181
+ - Arbitrary spacing (p-5, gap-7)
182
+ - Random durations (duration-200, duration-250)
183
+ ```
162
184
 
163
185
  ---
164
- `
165
186
 
166
- // v3.1.0: Add Level 1 Universal Patterns (development-principles.md) for ALL agents
167
- // Source: context-loading-protocol.md - Level 1 patterns apply to ALL agents
168
- const devPrinciplesPath = '.claude/contexts/patterns/development-principles.md'
169
- if (fileExists(devPrinciplesPath)) {
170
- prompt += `
187
+ #### ขั้นตอนที่ 4: Verify agent compliance หลัง agent ตอบกลับ
171
188
 
172
- ---
173
-
174
- ## 🏛️ Development Principles (Level 1 - ALL Agents)
189
+ ตรวจสอบว่า agent output มี report นี้หรือไม่:
175
190
 
176
- **REQUIRED READING:** @${devPrinciplesPath}
191
+ ```
192
+ ✅ Design System Loaded (STEP 0.5)
193
+ - Source: design-system/data.yaml
194
+ - Colors: [list]
195
+ - Spacing: [list]
196
+ - Animation: [list]
197
+ ```
177
198
 
178
- These principles apply to ALL code written by ALL agents:
199
+ **ถ้ามี report:** ผ่าน ไปต่อได้
179
200
 
180
- **Quick Reference:**
181
- | Principle | Summary |
182
- |-----------|---------|
183
- | **KISS** | Choose simple solutions over complex ones |
184
- | **YAGNI** | Build only what you need now |
185
- | **SRP** | One responsibility per module |
186
- | **DRY** | Single source of truth for all knowledge |
187
- | **Fail Fast** | Detect and raise errors immediately |
188
- | **Observability** | Log everything that matters |
189
-
190
- **Report format:**
191
- \`\`\`
192
- ✅ Development Principles Applied
193
- - KISS ✓ (simple implementation)
194
- - DRY ✓ (no duplication)
195
- - Separation of Concerns ✓
196
- \`\`\`
197
-
198
- ---
199
- `
200
- }
201
-
202
- // Add best-practices reference for ALL agents
203
- const bpDir = '.claude/contexts/domain/project/best-practices/'
204
- if (fileExists(bpDir)) {
205
- const bpFiles = listFiles(bpDir).filter(f => f.endsWith('.md') && f !== 'index.md')
206
-
207
- // Map agent type to relevant best-practices
208
- const agentBpMapping = {
209
- 'uxui-frontend': ['react', 'nextjs', 'vue', 'tailwind'],
210
- 'frontend': ['react', 'nextjs', 'vue', 'typescript'],
211
- 'backend': ['express', 'fastapi', 'django', 'prisma', 'drizzle'],
212
- 'database': ['prisma', 'drizzle', 'postgres', 'mongodb'],
213
- 'test-debug': ['vitest', 'jest', 'playwright'],
214
- 'integration': ['typescript'], // minimal
215
- 'ux-tester': [] // No best practices needed - uses Chrome DevTools
216
- }
217
-
218
- const relevantTechs = agentBpMapping[phase.agent] || []
219
- const relevantFiles = bpFiles.filter(f =>
220
- relevantTechs.some(tech => f.toLowerCase().includes(tech))
221
- )
222
-
223
- if (relevantFiles.length > 0) {
224
- prompt += `
201
+ **ถ้าไม่มี report:** ถาม agent ว่าอ่าน design system หรือยัง
225
202
 
226
203
  ---
227
204
 
228
- ## 📚 Best Practices (STEP 0)
205
+ ### Step 4.1: Build Agent Prompt
229
206
 
230
- Read these files before implementation for quality output:
207
+ **สร้าง prompt สำหรับ agent โดยประกอบด้วย:**
231
208
 
232
- ${relevantFiles.map(f => `- Read: ${bpDir}${f}`).join('\n')}
209
+ ---
233
210
 
234
- **Report format:**
235
- \`\`\`
236
- ✅ Best Practices Loaded
237
- ${relevantFiles.map(f => `- ${f.replace('.md', '')} ✓`).join('\n ')}
238
- \`\`\`
211
+ #### ส่วนที่ 1: Change Context
239
212
 
240
- WHY: Best practices ensure consistency with project patterns.
213
+ ประกอบข้อมูลจาก:
214
+ - `proposal.md` - What we're building and why
215
+ - `tasks.md` - Tasks for this phase
216
+ - `design.md` - Design decisions (if exists)
217
+ - `phases.md` - Phase instructions
241
218
 
242
219
  ---
243
- `
244
- }
245
- }
246
220
 
247
- // Add design reference for uxui-frontend agent (not full content!)
248
- if (phase.agent === 'uxui-frontend') {
249
- const tokensPath = 'design-system/data.yaml'
250
- const dataYamlPath = 'design-system/data.yaml'
251
- const hasTokens = fileExists(tokensPath)
221
+ #### ส่วนที่ 2: Library Requirements (v2.1.2)
252
222
 
253
- if (hasTokens) {
254
- prompt += `
223
+ เพิ่มคำสั่งให้ agent:
224
+ 1. Scan tasks.md หา patterns: "Install X", "Configure X"
225
+ 2. Scan design.md หา: "D1: Use X Library", "Decision: Use X"
226
+ 3. ใช้ libraries ที่ระบุ ไม่ใช่ custom implementation
227
+ 4. Implement ตาม design spec ไม่ใช่ library defaults
255
228
 
256
229
  ---
257
230
 
258
- ## 🎨 Design System (STEP 0.5)
231
+ #### ส่วนที่ 3: Development Principles (v3.1.0 - ALL agents)
259
232
 
260
- **Files to read:**
233
+ **ถ้ามีไฟล์** `.claude/contexts/patterns/development-principles.md`:
261
234
 
262
- ${hasTokens ? `- design-system/data.yaml (~500 tokens) - Colors, spacing, typography, psychology` : ''}
235
+ เพิ่มใน prompt:
236
+ ```
237
+ ## 🏛️ Development Principles (Level 1 - ALL Agents)
263
238
 
264
- **Style Guidelines:**
239
+ REQUIRED READING: @.claude/contexts/patterns/development-principles.md
265
240
 
266
- | Instead of | Use | WHY |
267
- |------------|-----|-----|
268
- | text-gray-500, #64748b | text-foreground/70, bg-muted | Theme-aware |
269
- | p-5, gap-7 | p-4, p-6, gap-8 | Spacing scale |
270
- | mixing shadow-sm/lg | consistent shadow-md | Visual consistency |
241
+ Quick Reference:
242
+ | Principle | Summary |
243
+ |-----------|---------|
244
+ | KISS | Choose simple solutions |
245
+ | YAGNI | Build only what you need now |
246
+ | SRP | One responsibility per module |
247
+ | DRY | Single source of truth |
248
+ | Fail Fast | Detect errors immediately |
249
+ ```
271
250
 
272
- **Report format:**
273
- \`\`\`
274
- ✅ Design System Loaded
275
- - data.yaml ✓
276
- - Design Tokens Extracted: [list key tokens]
277
- \`\`\`
251
+ ---
278
252
 
279
- WHY: Design tokens ensure visual consistency across components.
253
+ #### ส่วนที่ 4: Best Practices (agent-specific)
280
254
 
281
- ---
282
- `
283
- } else {
284
- prompt += `
255
+ **ถ้ามี directory** `.claude/contexts/domain/project/best-practices/`:
256
+
257
+ หา best-practices files ที่ตรงกับ agent:
258
+
259
+ | Agent | Relevant Topics |
260
+ |-------|-----------------|
261
+ | uxui-frontend | react, nextjs, vue, tailwind |
262
+ | frontend | react, nextjs, vue, typescript |
263
+ | backend | express, fastapi, django, prisma, drizzle |
264
+ | database | prisma, drizzle, postgres, mongodb |
265
+ | test-debug | vitest, jest, playwright |
266
+ | integration | typescript |
267
+ | ux-tester | (none) |
268
+
269
+ เพิ่มใน prompt:
270
+ ```
271
+ ## 📚 Best Practices (STEP 0)
272
+
273
+ Read these files before implementation:
274
+ - Read: .claude/contexts/domain/project/best-practices/{relevant-file}.md
275
+ ```
285
276
 
286
277
  ---
287
278
 
288
- ⚠️ **WARNING:** No design system found!
289
- Using fallback: .claude/contexts/design/*.md (universal principles)
279
+ #### ส่วนที่ 5: Design System (uxui-frontend only)
280
+
281
+ **ถ้า agent = uxui-frontend:**
282
+
283
+ **ถ้ามี** `design-system/data.yaml`:
284
+ ```
285
+ ## 🎨 Design System (STEP 0.5)
286
+
287
+ Files to read:
288
+ - design-system/data.yaml
289
+
290
+ Style Guidelines:
291
+ | Instead of | Use |
292
+ |------------|-----|
293
+ | text-gray-500, #64748b | text-foreground, bg-muted |
294
+ | p-5, gap-7 | p-4, p-6, gap-8 |
295
+ | mixing shadow-sm/lg | consistent shadow-md |
296
+ ```
290
297
 
291
- Run \`/designsetup\` to generate project-specific design system.
298
+ **ถ้าไม่มี:**
299
+ ```
300
+ ⚠️ WARNING: No design system found!
301
+ Using fallback: .claude/contexts/design/*.md
302
+ ```
292
303
 
293
304
  ---
294
- `
295
- }
296
- }
297
305
 
298
- return prompt
299
- }
306
+ ### Step 4.2: Execute Agent with Retry
300
307
 
301
- const prompt = buildAgentPrompt(phase, changeContext)
308
+ ---
302
309
 
303
- // 4.2: Execute agent with retry & validation
304
- output(`\n🚀 Invoking ${phase.agent} agent (model: opus)...`)
310
+ #### การ invoke agent
305
311
 
306
- const result = await executeAgentWithRetry(
307
- phase.agent,
308
- phase,
309
- changeContext,
310
- {
311
- max_retries: 2,
312
- retry_delay: 5000,
313
- timeout: 600000, // 10 minutes
314
- validate_output: true
315
- }
316
- )
312
+ Report ก่อน invoke:
313
+ ```
314
+ 🚀 Invoking {agent} agent (model: opus)...
315
+ ```
317
316
 
318
- // 4.3: Handle result
319
- if (result.success) {
320
- output(`\n✅ Phase ${phase.phase_number} completed successfully!`)
321
- output(`⏱️ Execution time: ${(result.execution_time / 1000).toFixed(1)}s`)
322
- output(`🔄 Retries used: ${result.retries_used}`)
323
- output(`✅ Validation: ${result.validation_passed ? 'PASSED' : 'SKIPPED'}`)
317
+ Invoke agent ด้วย:
318
+ - Model: opus (fixed)
319
+ - Timeout: 10 นาที
320
+ - Max retries: 2 ครั้ง
324
321
 
325
- // Continue to Step 5: Post-Execution
326
- } else {
327
- output(`\n❌ Phase ${phase.phase_number} failed`)
328
- output(`Error: ${result.error}`)
329
- output(`Retries used: ${result.retries_used}`)
322
+ ---
330
323
 
331
- // Escalate to user
332
- const action = await escalateToUser(phase.agent, phase, result)
324
+ #### Handle Result
333
325
 
334
- switch (action) {
335
- case 'retry':
336
- output(`Retrying Phase ${phase.phase_number}...`)
337
- // Restart Step 4
338
- return executePhaseAgain(changeId, phase)
326
+ **ถ้าสำเร็จ:**
327
+ ```
328
+ Phase {phase_number} completed successfully!
329
+ ⏱️ Execution time: {time}s
330
+ 🔄 Retries used: {retries}
331
+ ✅ Validation: PASSED
332
+ ```
333
+ → ไป Step 5
339
334
 
340
- case 'skip':
341
- output(`⚠️ Skipping Phase ${phase.phase_number}`)
342
- await markPhaseAsSkipped(changeId, phase, result.error)
343
- // Continue to next phase
344
- break
335
+ **ถ้าล้มเหลว:**
336
+ ```
337
+ Phase {phase_number} failed
338
+ Error: {error}
339
+ Retries used: {retries}
340
+ ```
345
341
 
346
- case 'abort':
347
- output(`🛑 Workflow aborted`)
348
- output(`Resume with: /cdev ${changeId}`)
349
- return
350
- }
351
- }
342
+ ถาม user:
343
+ ```
344
+ Options:
345
+ [retry] - ลองใหม่
346
+ [skip] - ข้าม phase นี้
347
+ [abort] - หยุดทำงาน
352
348
  ```
353
349
 
354
- **Helper Functions Used:**
350
+ ---
351
+
352
+ **Helper Functions:**
355
353
 
356
- 1. **buildAgentPrompt()**: See `.claude/lib/agent-executor.md`
357
- 2. **executeAgentWithRetry()**: See `.claude/lib/agent-executor.md`
358
- 3. **escalateToUser()**: See `.claude/lib/agent-executor.md`
354
+ See `.claude/lib/agent-executor.md` for:
355
+ - buildAgentPrompt()
356
+ - executeAgentWithRetry()
357
+ - escalateToUser()
359
358
 
360
359
  **Model Strategy:**
361
360
  - All agents use `model: opus` (fixed)
362
361
  - Opus 4.5 is the latest Claude model with best performance
363
- - Quality maintained through comprehensive validation framework
364
362
 
365
363
  ---
366
364
 
@@ -389,26 +387,32 @@ See `.claude/contexts/patterns/validation-framework.md` for complete checklist p
389
387
 
390
388
  ### Step 4.6: Approval Gate Handling (v2.7.0)
391
389
 
392
- **NEW:** Handle phases with `requires_approval: true` (e.g., ux-tester Phase 1.5)
390
+ **สำหรับ phases ที่มี** `requires_approval: true` (เช่น ux-tester Phase 1.5)
391
+
392
+ ---
393
+
394
+ #### ขั้นตอนที่ 1: ตรวจสอบว่า phase ต้องการ approval หรือไม่
393
395
 
394
- ```typescript
395
- // Check if this phase requires user approval
396
- const isApprovalGate = phase.requires_approval === true ||
397
- phase.metadata?.includes('approval-gate')
396
+ ดูใน phases.md ว่า phase ปัจจุบันมี:
397
+ - `requires_approval: true`
398
+ - หรือ metadata มีคำว่า `approval-gate`
398
399
 
399
- if (isApprovalGate && result.success) {
400
- // Read all phases for loop back logic
401
- const phasesPath = `openspec/changes/${changeId}/.claude/phases.md`
402
- const allPhases = parsePhasesFromMd(Read(phasesPath))
400
+ **ถ้าไม่ต้องการ approval:** ข้าม Step 4.6 ไปเลย
403
401
 
404
- output(`
402
+ **ถ้าต้องการ approval:** ทำขั้นตอนถัดไป
403
+
404
+ ---
405
+
406
+ #### ขั้นตอนที่ 2: แสดงผลและรอ user ตัดสินใจ
407
+
408
+ ```
405
409
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
406
- 🧪 ${phase.name} Complete - Awaiting Approval
410
+ 🧪 {phase_name} Complete - Awaiting Approval
407
411
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
408
412
 
409
- ${result.summary || 'Report generated successfully'}
413
+ {result_summary}
410
414
 
411
- 📄 Full report: ${result.reportPath || `openspec/changes/${changeId}/ux-test-report.md`}
415
+ 📄 Full report: openspec/changes/{change-id}/ux-test-report.md
412
416
 
413
417
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
414
418
 
@@ -418,280 +422,249 @@ ${result.summary || 'Report generated successfully'}
418
422
  ❌ "reject [feedback]" → กลับแก้ไข Phase ก่อนหน้า
419
423
 
420
424
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
421
- `)
422
-
423
- // PAUSE - Main Claude waits for user's next message
424
- // User responds with "approve" or "reject [feedback]"
425
- return { status: 'awaiting_approval', phase, changeId }
426
- }
427
-
428
- // When user responds (in next message):
429
- function handleUserApprovalResponse(userResponse: string, phase: Phase, changeId: string, allPhases: Phase[]) {
430
- const normalized = userResponse.trim().toLowerCase()
431
-
432
- // Handle APPROVE
433
- if (normalized.match(/^(approve|approved|ok|yes|ใช่|อนุมัติ|ผ่าน|ลุย|ได้|ดี)$/)) {
434
- output(`✅ ${phase.name} approved! Continuing to next phase...`)
435
- updateFlags(changeId, {
436
- [`phase_${phase.phase_number}`]: {
437
- status: 'approved',
438
- approved_at: new Date().toISOString()
439
- }
440
- })
441
- // Continue to Step 5
442
- return { action: 'continue' }
443
- }
444
-
445
- // Handle REJECT
446
- if (normalized.startsWith('reject') || normalized.startsWith('ไม่') ||
447
- normalized.startsWith('แก้') || normalized.startsWith('no')) {
448
-
449
- const feedback = userResponse.replace(/^(reject|ไม่อนุมัติ|แก้ไข|no)\s*/i, '').trim()
450
-
451
- // Find the phase to loop back to
452
- const loopBackPhase = allPhases.find(p => p.agent === 'uxui-frontend') || allPhases[0]
453
-
454
- output(`
455
- 🔄 ${phase.name} rejected
456
-
457
- 📝 Feedback: ${feedback || 'None provided'}
458
- 🔙 Looping back to: Phase ${loopBackPhase.phase_number} - ${loopBackPhase.name}
459
-
460
- ${loopBackPhase.agent} agent จะได้รับ feedback นี้เพื่อแก้ไข
461
- `)
462
-
463
- // Update flags for rejection
464
- updateFlags(changeId, {
465
- [`phase_${phase.phase_number}`]: {
466
- status: 'rejected',
467
- rejected_at: new Date().toISOString(),
468
- rejection_feedback: feedback
469
- },
470
- [`phase_${loopBackPhase.phase_number}`]: {
471
- status: 'pending',
472
- rerun_reason: `Rejected from UX Testing: ${feedback}`
473
- }
474
- })
475
-
476
- // Loop back to uxui-frontend phase
477
- output(`\n🔄 Restarting Phase ${loopBackPhase.phase_number}: ${loopBackPhase.name}`)
478
- return {
479
- action: 'loop_back',
480
- loopBackPhase,
481
- feedback
482
- }
483
- }
484
-
485
- // Unknown response - ask again
486
- output(`⚠️ ไม่เข้าใจคำตอบ กรุณาตอบ "approve" หรือ "reject [feedback]"`)
487
- return { action: 'ask_again' }
488
- }
489
425
  ```
490
426
 
427
+ → หยุดรอ user ตอบ
428
+
429
+ ---
430
+
431
+ #### ขั้นตอนที่ 3: Handle user response
432
+
433
+ **ถ้า user ตอบ approve:**
434
+ - คำที่ยอมรับ: approve, approved, ok, yes, ใช่, อนุมัติ, ผ่าน, ลุย, ได้, ดี
435
+ - Output: `✅ {phase_name} approved! Continuing to next phase...`
436
+ - อัพเดต flags.json: status = "approved"
437
+ - ไป Step 5
438
+
439
+ **ถ้า user ตอบ reject:**
440
+ - คำที่ยอมรับ: reject, ไม่, แก้, no (ตามด้วย feedback)
441
+ - ดึง feedback จาก message
442
+ - หา phase ที่ต้องกลับไปแก้ (uxui-frontend)
443
+ - Output:
444
+ ```
445
+ 🔄 {phase_name} rejected
446
+
447
+ 📝 Feedback: {feedback}
448
+ 🔙 Looping back to: Phase {X} - {phase_name}
449
+
450
+ {agent} agent จะได้รับ feedback นี้เพื่อแก้ไข
451
+ ```
452
+ - อัพเดต flags.json: status = "rejected"
453
+ - กลับไป run phase ที่ต้องแก้ไข
454
+
455
+ **ถ้าไม่เข้าใจคำตอบ:**
456
+ ```
457
+ ⚠️ ไม่เข้าใจคำตอบ กรุณาตอบ "approve" หรือ "reject [feedback]"
458
+ ```
459
+ → ถาม user อีกครั้ง
460
+
461
+ ---
462
+
491
463
  **See:** `.claude/lib/agent-executor.md` → "Approval Gate Execution" section for complete flow
492
464
 
493
465
  ---
494
466
 
495
467
  ### Step 4.7: Validate Page Plan Compliance (uxui-frontend only)
496
468
 
497
- **Only runs for uxui-frontend agent when page-plan.md exists:**
498
-
499
- **Purpose:** Verify agent implemented ALL sections from page-plan.md, not a subset.
500
-
501
- ```typescript
502
- // Check if page-plan.md exists
503
- const pagePlanPath = `openspec/changes/${changeId}/page-plan.md`
504
- const hasPagePlan = fileExists(pagePlanPath)
505
-
506
- if (phase.agent === 'uxui-frontend' && hasPagePlan) {
507
- output(`\n🔍 Validating page-plan.md compliance...`)
508
-
509
- // Extract sections from page-plan.md Section 2 (Page Structure)
510
- const pagePlan = Read(pagePlanPath)
511
- const section2Match = pagePlan.match(/## 2\. Page Structure[\s\S]*?(?=## 3\.|## 2\.5|## 2\.6|$)/)
512
-
513
- if (section2Match) {
514
- // Count expected sections (extract component names from JSX)
515
- const componentMatches = section2Match[0].match(/<([A-Z]\w+)/g) || []
516
- const expectedComponents = componentMatches
517
- .map(m => m.replace('<', ''))
518
- .filter(name => name !== 'Layout' && name !== 'div') // Exclude wrappers
519
-
520
- const uniqueComponents = [...new Set(expectedComponents)] // Remove duplicates
521
-
522
- output(`\n📋 Page Plan Analysis:`)
523
- output(` Expected sections: ${uniqueComponents.length}`)
524
- output(` Components: ${uniqueComponents.join(', ')}`)
525
-
526
- // Prompt user to verify agent compliance
527
- output(`\n⚠️ VALIDATION REQUIRED:`)
528
- output(`\nDid the agent implement ALL ${uniqueComponents.length} sections?`)
529
- output(`\nPlease verify the implementation includes:`)
530
- uniqueComponents.forEach(c => output(` - ${c}`))
531
-
532
- output(`\nOptions:`)
533
- output(` [yes] - All sections implemented ✓`)
534
- output(` [retry] - Agent skipped sections, retry with strict enforcement`)
535
- output(` [skip] - Skip validation (not recommended)`)
536
-
537
- const answer = await askUser(`\nConfirm all sections implemented?`)
538
-
539
- if (answer === 'retry') {
540
- output(`\n🔄 Retrying phase with enhanced enforcement...`)
541
- output(`Agent will be explicitly instructed to implement all ${uniqueComponents.length} sections`)
542
-
543
- // Restart phase with enhanced prompt
544
- return executePhaseAgain(changeId, phase, {
545
- enforce_page_plan: true,
546
- required_sections: uniqueComponents
547
- })
548
- } else if (answer === 'skip') {
549
- warn(`\n⚠️ Skipping validation - proceed with caution`)
550
- warn(` This may result in incomplete implementation`)
551
- } else {
552
- output(`\n✅ Page plan compliance confirmed`)
553
- output(` All ${uniqueComponents.length} sections implemented`)
554
- }
555
- } else {
556
- warn(`\n⚠️ Could not parse page-plan.md Section 2`)
557
- warn(` Skipping compliance validation`)
558
- }
559
- } else {
560
- // Not uxui-frontend or no page-plan.md - skip validation
561
- output(`\nℹ️ Page plan validation: N/A (agent: ${phase.agent}, has plan: ${hasPagePlan})`)
562
- }
469
+ **เฉพาะ uxui-frontend agent เมื่อมี page-plan.md**
470
+
471
+ **Purpose:** ตรวจสอบว่า agent implement ครบทุก section ตาม page-plan.md
472
+
473
+ ---
474
+
475
+ #### ขั้นตอนที่ 1: ตรวจสอบเงื่อนไข
476
+
477
+ **ถ้า agent ไม่ใช่ uxui-frontend หรือไม่มี page-plan.md:**
563
478
  ```
479
+ ℹ️ Page plan validation: N/A (agent: {agent}, has plan: {true/false})
480
+ ```
481
+ → ข้าม Step 4.7 ไปเลย
482
+
483
+ **ถ้า agent = uxui-frontend และมี page-plan.md:**
484
+ → ทำขั้นตอนถัดไป
485
+
486
+ ---
487
+
488
+ #### ขั้นตอนที่ 2: วิเคราะห์ page-plan.md
489
+
490
+ อ่าน `openspec/changes/{change-id}/page-plan.md`
491
+
492
+ หา Section 2 (Page Structure) และนับจำนวน components:
493
+ - ดู JSX elements ที่ขึ้นต้นด้วยตัวใหญ่ (เช่น `<HeroSection>`, `<PricingTable>`)
494
+ - ไม่นับ Layout, div (wrapper elements)
495
+ - Remove duplicates
496
+
497
+ Report:
498
+ ```
499
+ 📋 Page Plan Analysis:
500
+ Expected sections: {count}
501
+ Components: {list}
502
+ ```
503
+
504
+ ---
505
+
506
+ #### ขั้นตอนที่ 3: ถาม user ยืนยัน
507
+
508
+ ```
509
+ ⚠️ VALIDATION REQUIRED:
510
+
511
+ Did the agent implement ALL {count} sections?
512
+
513
+ Please verify the implementation includes:
514
+ - {Component1}
515
+ - {Component2}
516
+ - ...
517
+
518
+ Options:
519
+ [yes] - All sections implemented ✓
520
+ [retry] - Agent skipped sections, retry with strict enforcement
521
+ [skip] - Skip validation (not recommended)
522
+ ```
523
+
524
+ ---
525
+
526
+ #### ขั้นตอนที่ 4: Handle user response
527
+
528
+ **ถ้า user ตอบ yes:**
529
+ ```
530
+ ✅ Page plan compliance confirmed
531
+ All {count} sections implemented
532
+ ```
533
+ → ไป Step 5
534
+
535
+ **ถ้า user ตอบ retry:**
536
+ ```
537
+ 🔄 Retrying phase with enhanced enforcement...
538
+ Agent will be explicitly instructed to implement all {count} sections
539
+ ```
540
+ → กลับไป run phase อีกครั้งพร้อม enhanced prompt
541
+
542
+ **ถ้า user ตอบ skip:**
543
+ ```
544
+ ⚠️ Skipping validation - proceed with caution
545
+ This may result in incomplete implementation
546
+ ```
547
+ → ไป Step 5
548
+
549
+ ---
564
550
 
565
551
  **When to use:**
566
- - Agent: uxui-frontend
567
- - page-plan.md exists
568
- - Phase completed successfully
552
+ - Agent: uxui-frontend
553
+ - page-plan.md exists
554
+ - Phase completed successfully
569
555
 
570
556
  **Common issues caught:**
571
557
  - Agent implemented 5/10 sections (missing ProblemSection, ComparisonTable, etc.)
572
558
  - Agent followed tasks.md ("4-5 components") instead of page-plan.md (10 sections)
573
559
  - Agent skipped sections they thought were "optional"
574
560
 
575
- **Remediation:**
576
- - If validation fails → Retry with `enforce_page_plan: true`
577
- - Agent will receive enhanced prompt with explicit section list
578
- - Validation runs again after retry
579
-
580
561
  ---
581
562
 
582
563
  ### Step 5: Post-Execution (Flags Update)
583
564
 
584
- **Main Claude updates flags.json after each phase completion.**
565
+ **Main Claude อัพเดต flags.json หลังจบแต่ละ phase**
585
566
 
586
567
  → See: `.claude/lib/flags-updater.md` for complete protocol
587
568
 
588
569
  WHY: Immediate updates ensure /cstatus shows accurate progress.
589
570
 
590
- **Execution Order:**
591
-
592
- ```typescript
593
- // 1. Update flags.json
594
- output(`\n🔄 Updating progress tracking...`)
595
-
596
- // See flags-updater.md for updateFlagsAfterPhase() implementation
597
- updateFlagsAfterPhase(changeId, currentPhase, agentResponse)
598
-
599
- // This function:
600
- // - Marks phase as completed
601
- // - Records actual duration
602
- // - Extracts files created/modified
603
- // - Updates meta statistics (progress %, time remaining)
604
- // - Moves current_phase to next phase
605
- // - Writes back to flags.json
606
- // - Reports progress to user
607
-
608
- // 2. Read updated flags
609
- const flagsPath = `openspec/changes/${changeId}/.claude/flags.json`
610
- const flags = JSON.parse(Read(flagsPath))
611
-
612
- // 3. Report progress to user
613
- output(`\n📊 Progress Update:`)
614
- output(` ✅ ${flags.meta.completed_phases}/${flags.meta.total_phases} phases complete`)
615
- output(` 📈 ${flags.meta.progress_percentage}% progress`)
616
- output(` ⏱️ ${formatDuration(flags.meta.total_actual_minutes)} spent`)
617
- output(` ⏱️ ${formatDuration(flags.meta.time_remaining_estimate)} remaining`)
618
-
619
- // 4. Check next phase
620
- if (flags.ready_to_archive) {
621
- // 🆕 v1.2.0: Verbose Summary Output (replaces documentation/report phases)
622
- output(`\n`)
623
- output(`╔════════════════════════════════════════════════════════════╗`)
624
- output(`║ ✅ CHANGE COMPLETED SUCCESSFULLY ║`)
625
- output(`╚════════════════════════════════════════════════════════════╝`)
626
- output(``)
627
- output(`📦 Change: ${changeId}`)
628
- output(`📋 Template: ${flags.template} (${flags.meta.total_phases} phases)`)
629
- output(``)
630
- output(`═══════════════════════════════════════════════════════════════`)
631
- output(`📊 EXECUTION SUMMARY`)
632
- output(`═══════════════════════════════════════════════════════════════`)
633
- output(``)
634
- output(`⏱️ Time:`)
635
- output(` • Estimated: ${formatDuration(flags.meta.total_estimated_minutes)}`)
636
- output(` • Actual: ${formatDuration(flags.meta.total_actual_minutes)}`)
637
- output(` • Variance: ${calculateVariance(flags.meta)}`)
638
- output(``)
639
- output(`📈 Phases Completed: ${flags.meta.completed_phases}/${flags.meta.total_phases}`)
640
-
641
- // List all phases with status
642
- Object.entries(flags.phases).forEach(([phaseId, phase]) => {
643
- const status = phase.status === 'completed' ? '✅' :
644
- phase.status === 'skipped' ? '⏭️' : '❌'
645
- const time = phase.actual_minutes ? `(${phase.actual_minutes}m)` : ''
646
- output(` ${status} ${phase.phase_number}. ${phaseId} ${time}`)
647
- })
648
-
649
- output(``)
650
- output(`═══════════════════════════════════════════════════════════════`)
651
- output(`📁 FILES CREATED/MODIFIED`)
652
- output(`═══════════════════════════════════════════════════════════════`)
653
-
654
- // Collect all files from phase outputs
655
- const allFiles = collectFilesFromPhases(flags.phases)
656
- if (allFiles.created.length > 0) {
657
- output(``)
658
- output(`✨ Created (${allFiles.created.length}):`)
659
- allFiles.created.forEach(f => output(` • ${f}`))
660
- }
661
- if (allFiles.modified.length > 0) {
662
- output(``)
663
- output(`📝 Modified (${allFiles.modified.length}):`)
664
- allFiles.modified.forEach(f => output(` • ${f}`))
665
- }
666
-
667
- output(``)
668
- output(`═══════════════════════════════════════════════════════════════`)
669
- output(`🚀 NEXT STEPS`)
670
- output(`═══════════════════════════════════════════════════════════════`)
671
- output(``)
672
- output(`1. Review changes: /cview ${changeId}`)
673
- output(`2. Test manually: Verify the implementation works`)
674
- output(`3. Mark complete: Update tasks.md (mark all [x])`)
675
- output(`4. Archive: openspec archive ${changeId}`)
676
- output(``)
677
- output(`💡 Note: flags.json contains full execution history`)
678
- output(` Path: openspec/changes/${changeId}/.claude/flags.json`)
679
- output(``)
680
- } else {
681
- const nextPhase = flags.phases[flags.current_phase]
682
-
683
- output(`\n📍 Next: Phase ${nextPhase.phase_number}: ${flags.current_phase}`)
684
- output(` Agent: ${nextPhase.agent}`)
685
- output(` Estimated: ${nextPhase.estimated_minutes} min`)
686
-
687
- if (nextPhase.agent === 'user') {
688
- output('\n🛑 Next phase requires your action')
689
- output(`When done: /cdev ${changeId} --continue`)
690
- } else {
691
- output('\nContinue? (yes/no)')
692
- }
693
- }
571
+ ---
572
+
573
+ #### ขั้นตอนที่ 1: อัพเดต flags.json
574
+
575
+ ```
576
+ 🔄 Updating progress tracking...
577
+ ```
578
+
579
+ อัพเดตข้อมูลต่อไปนี้:
580
+ - Mark phase as completed
581
+ - Record actual duration
582
+ - Extract files created/modified
583
+ - Update meta statistics (progress %, time remaining)
584
+ - Move current_phase to next phase
585
+
586
+ ---
587
+
588
+ #### ขั้นตอนที่ 2: Report Progress
589
+
694
590
  ```
591
+ 📊 Progress Update:
592
+ ✅ {completed}/{total} phases complete
593
+ 📈 {percentage}% progress
594
+ ⏱️ {time_spent} spent
595
+ ⏱️ {time_remaining} remaining
596
+ ```
597
+
598
+ ---
599
+
600
+ #### ขั้นตอนที่ 3: Check next phase
601
+
602
+ **ถ้าทุก phases เสร็จหมดแล้ว (ready_to_archive):**
603
+
604
+ ```
605
+ ╔════════════════════════════════════════════════════════════╗
606
+ ║ ✅ CHANGE COMPLETED SUCCESSFULLY ║
607
+ ╚════════════════════════════════════════════════════════════╝
608
+
609
+ 📦 Change: {change-id}
610
+ 📋 Template: {template} ({total_phases} phases)
611
+
612
+ ═══════════════════════════════════════════════════════════════
613
+ 📊 EXECUTION SUMMARY
614
+ ═══════════════════════════════════════════════════════════════
615
+
616
+ ⏱️ Time:
617
+ • Estimated: {estimated}
618
+ • Actual: {actual}
619
+ • Variance: {variance}
620
+
621
+ 📈 Phases Completed: {completed}/{total}
622
+ ✅ 1. phase-name (Xm)
623
+ ✅ 2. phase-name (Xm)
624
+ ...
625
+
626
+ ═══════════════════════════════════════════════════════════════
627
+ 📁 FILES CREATED/MODIFIED
628
+ ═══════════════════════════════════════════════════════════════
629
+
630
+ ✨ Created ({count}):
631
+ • {file1}
632
+ • {file2}
633
+
634
+ 📝 Modified ({count}):
635
+ • {file1}
636
+ • {file2}
637
+
638
+ ═══════════════════════════════════════════════════════════════
639
+ 🚀 NEXT STEPS
640
+ ═══════════════════════════════════════════════════════════════
641
+
642
+ 1. Review changes: /cview {change-id}
643
+ 2. Test manually: Verify the implementation works
644
+ 3. Mark complete: Update tasks.md (mark all [x])
645
+ 4. Archive: openspec archive {change-id}
646
+ ```
647
+
648
+ **ถ้ายังมี phases ที่ยังไม่เสร็จ:**
649
+
650
+ ```
651
+ 📍 Next: Phase {X}: {phase_name}
652
+ Agent: {agent}
653
+ Estimated: {X} min
654
+ ```
655
+
656
+ **ถ้า next phase ต้องการ manual action:**
657
+ ```
658
+ 🛑 Next phase requires your action
659
+ When done: /cdev {change-id} --continue
660
+ ```
661
+
662
+ **ถ้า next phase เป็น agent:**
663
+ ```
664
+ Continue? (yes/no)
665
+ ```
666
+
667
+ ---
695
668
 
696
669
  **Key points:**
697
670
  - Main Claude updates flags.json (sub-agents don't have access)