@champpaba/claude-agent-kit 3.2.0 → 3.4.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.
@@ -50,117 +50,117 @@
50
50
 
51
51
  ### STEP 1: Detect Change Context
52
52
 
53
- ```typescript
54
- // Detect current change ID
55
- const changesDir = 'openspec/changes/'
56
- const changeId = detectCurrentChange() // or from command arg
53
+ 1. Determine the change ID:
54
+ - Check if user provided a change ID as command argument
55
+ - If not provided, search for the active change in `openspec/changes/`
56
+ - Look for the most recently modified change directory
57
57
 
58
- if (!changeId) {
59
- error("No active change found. Run after OpenSpec generates proposal.md")
60
- return
61
- }
62
-
63
- const outputPath = `openspec/changes/${changeId}/page-plan.md`
58
+ **If no change ID found:**
59
+ ```
60
+ ❌ No active change found. Run after OpenSpec generates proposal.md
64
61
  ```
62
+ → STOP
63
+
64
+ 2. Set the output path:
65
+ - Output file: `openspec/changes/{changeId}/page-plan.md`
66
+
67
+ → Continue to STEP 2
65
68
 
66
69
  ### STEP 2: Read Context Files
67
70
 
68
- ```typescript
69
- // Only read files user specified with @
70
- const userFiles = extractMentionedFiles(userMessage) // @prd.md, @brief.md
71
-
72
- // Always read (if exists)
73
- const proposalPath = `openspec/changes/${changeId}/proposal.md`
74
- const tokensPath = `design-system/data.yaml` // Design tokens + psychology
75
- // data.yaml contains all design information - single source of truth
76
-
77
- const contextFiles = [
78
- ...userFiles,
79
- proposalPath
80
- ].filter(fileExists)
81
-
82
- // Read all context
83
- let context = contextFiles.map(readFile).join('\n\n---\n\n')
84
-
85
- // 🆕 Extract individual content for buyer avatar analysis (STEP 3.5)
86
- let proposalContent = ''
87
- let briefContent = ''
88
- let tasksContent = ''
89
-
90
- // Read proposal separately if exists
91
- if (fileExists(proposalPath)) {
92
- proposalContent = Read(proposalPath)
93
- }
94
-
95
- // Read tasks.md if exists (for marketing page detection)
96
- const tasksPath = `openspec/changes/${changeId}/tasks.md`
97
- if (fileExists(tasksPath)) {
98
- tasksContent = Read(tasksPath)
99
- }
100
-
101
- // 🆕 v2.6.0: Read phases.md if exists (for phase info, UI detection)
102
- const phasesPath = `openspec/changes/${changeId}/.claude/phases.md`
103
- let phasesContent = ''
104
- if (fileExists(phasesPath)) {
105
- phasesContent = Read(phasesPath)
106
- output(`✅ phases.md Found - reading phase information`)
107
-
108
- // Extract UI phases from phases.md
109
- const uiPhaseMatch = phasesContent.match(/uxui-frontend|frontend-mockup|Frontend Mockup/gi)
110
- if (uiPhaseMatch) {
111
- output(` - UI phases detected: ${uiPhaseMatch.length}`)
112
- }
113
- } else {
114
- output(`ℹ️ phases.md not found - run /csetup first if you want phase-aware planning`)
115
- }
116
-
117
- // Extract brief from user files
118
- const briefFile = userFiles.find(f => f.toLowerCase().includes('brief'))
119
- if (briefFile && fileExists(briefFile)) {
120
- briefContent = Read(briefFile)
121
- }
122
-
123
- // 🆕 Load design tokens (lightweight)
124
- if (fileExists(tokensPath)) {
125
- const tokens = JSON.parse(Read(tokensPath))
126
- context += `\n\n---\n\n# Design Tokens (data.yaml)\n\n`
127
- context += `Primary Color: ${tokens.tokens.colors.primary.DEFAULT}\n`
128
- context += `Spacing Scale: ${tokens.tokens.spacing.scale.join(', ')}px\n`
129
- context += `Component Library: ${tokens.component_library.name}\n`
130
- context += `Shadows: ${Object.keys(tokens.tokens.shadows).join(', ')}\n`
131
- }
132
-
133
- // Validate data.yaml exists
134
- if (!fileExists(tokensPath)) {
135
- warn(`⚠️ No data.yaml found - run /designsetup first`)
136
- }
137
-
138
- // Total context: ~1.5K tokens (data.yaml is lightweight)
71
+ 1. Extract user-mentioned files:
72
+ - Scan the user message for files mentioned with `@` prefix
73
+ - Example: `@prd.md`, `@brief.md`, `@project_brief.md`
74
+ - Store these as user files list
75
+
76
+ 2. Define required file paths:
77
+ - Proposal: `openspec/changes/{changeId}/proposal.md`
78
+ - Tasks: `openspec/changes/{changeId}/tasks.md`
79
+ - Phases: `openspec/changes/{changeId}/.claude/phases.md`
80
+ - Design tokens: `design-system/data.yaml`
81
+
82
+ 3. Build context files list:
83
+ - Start with user-mentioned files
84
+ - Add proposal.md path
85
+ - Filter to only files that exist on disk
86
+
87
+ 4. Read all context files:
88
+ - Read each file in the context files list
89
+ - Join content with separator: `\n\n---\n\n`
90
+ - Store as base context
91
+
92
+ 5. Read proposal.md separately (if exists):
93
+ - Used for individual analysis later
94
+ - Store as `proposalContent`
95
+
96
+ 6. Read tasks.md (if exists):
97
+ - Used for page type detection (marketing vs dashboard)
98
+ - Store as `tasksContent`
99
+
100
+ 7. Read phases.md (if exists):
101
+ - Check path: `openspec/changes/{changeId}/.claude/phases.md`
102
+ - Store as `phasesContent`
103
+
104
+ **If phases.md found:**
139
105
  ```
106
+ ✅ phases.md Found - reading phase information
107
+ ```
108
+ - Search for UI phase keywords: `uxui-frontend`, `frontend-mockup`, `Frontend Mockup`
109
+ - Count matches and report: `- UI phases detected: {count}`
140
110
 
141
- ### STEP 3: Search Existing Components
111
+ **If phases.md NOT found:**
112
+ ```
113
+ ℹ️ phases.md not found - run /csetup first if you want phase-aware planning
114
+ ```
142
115
 
143
- ```typescript
144
- // Search for common shared components
145
- const searchPatterns = [
146
- '**/{Navbar,Navigation}*.{tsx,jsx,vue}',
147
- '**/{Footer}*.{tsx,jsx,vue}',
148
- '**/{Sidebar,Drawer}*.{tsx,jsx,vue}',
149
- '**/{Header}*.{tsx,jsx,vue}',
150
- ]
151
-
152
- const foundComponents = []
153
- for (const pattern of searchPatterns) {
154
- const matches = glob(pattern)
155
- if (matches.length > 0) {
156
- foundComponents.push({
157
- name: extractComponentName(matches[0]),
158
- path: matches[0],
159
- exports: grepExports(matches[0])
160
- })
161
- }
162
- }
116
+ 8. Extract brief content:
117
+ - Search user files for filename containing "brief"
118
+ - If found and exists, read it
119
+ - Store as `briefContent`
120
+
121
+ 9. Load design tokens from data.yaml (if exists):
122
+ - Read `design-system/data.yaml`
123
+ - Parse as YAML
124
+ - Extract key design information:
125
+ - Primary color: `tokens.colors.primary.DEFAULT`
126
+ - Spacing scale: `tokens.spacing.scale` (array)
127
+ - Component library: `component_library.name`
128
+ - Shadows: Object keys from `tokens.shadows`
129
+ - Append to context with header: `# Design Tokens (data.yaml)`
130
+ - Include extracted values in readable format
131
+
132
+ **If data.yaml NOT found:**
163
133
  ```
134
+ ⚠️ No data.yaml found - run /designsetup first
135
+ ```
136
+
137
+ **Context size estimate:** ~1.5K tokens (data.yaml is lightweight)
138
+
139
+ → Continue to STEP 3
140
+
141
+ ### STEP 3: Search Existing Components
142
+
143
+ 1. Define search patterns for common shared components:
144
+ - Navbar/Navigation: `**/{Navbar,Navigation}*.{tsx,jsx,vue}`
145
+ - Footer: `**/{Footer}*.{tsx,jsx,vue}`
146
+ - Sidebar/Drawer: `**/{Sidebar,Drawer}*.{tsx,jsx,vue}`
147
+ - Header: `**/{Header}*.{tsx,jsx,vue}`
148
+
149
+ 2. For each search pattern:
150
+ - Run glob search to find matching files
151
+ - If matches found (length > 0):
152
+ - Extract component name from the first match file path
153
+ - Store component information:
154
+ - `name`: Component name (e.g., "Navbar")
155
+ - `path`: Full file path
156
+ - `exports`: Use grep to find exported functions/components
157
+ - Add to found components list
158
+
159
+ 3. Build the found components list:
160
+ - Each entry contains: name, path, exports
161
+ - This list will be used to generate the "Reuse Components" section
162
+
163
+ → Continue to STEP 4
164
164
 
165
165
  ### STEP 4: Analyze & Generate Plan
166
166
 
@@ -343,15 +343,13 @@ Based on context + found components, generate:
343
343
  - Code: `disabled:opacity-70` + spinner component
344
344
 
345
345
  **Full Example:**
346
- ```tsx
347
- <button className="px-6 py-3 bg-primary text-primary-foreground rounded-md
348
- transition-all duration-150
349
- hover:scale-105 hover:shadow-lg
350
- active:scale-95
351
- disabled:opacity-70">
352
- Get Started
353
- </button>
354
- ```
346
+ Primary CTA button should include these Tailwind classes:
347
+ - Base styles: `px-6 py-3 bg-primary text-primary-foreground rounded-md`
348
+ - Transition: `transition-all duration-150`
349
+ - Hover effects: `hover:scale-105 hover:shadow-lg`
350
+ - Active state: `active:scale-95`
351
+ - Disabled state: `disabled:opacity-70`
352
+ - Button text: "Get Started" (or context-appropriate CTA)
355
353
 
356
354
  #### Secondary Button
357
355
  **Hover State:**
@@ -376,13 +374,11 @@ Based on context + found components, generate:
376
374
  - Code: `hover:border-primary/50`
377
375
 
378
376
  **Full Example:**
379
- ```tsx
380
- <div className="p-6 bg-card border border-border rounded-lg
381
- transition-shadow duration-300
382
- hover:shadow-xl hover:border-primary/50">
383
- {/* Card content */}
384
- </div>
385
- ```
377
+ Feature/product card container should include:
378
+ - Base styles: `p-6 bg-card border border-border rounded-lg`
379
+ - Transition: `transition-shadow duration-300`
380
+ - Hover effects: `hover:shadow-xl hover:border-primary/50`
381
+ - Content: Card content elements go inside container
386
382
 
387
383
  #### Interactive Card (Clickable)
388
384
  **Hover State:**
@@ -411,12 +407,11 @@ Based on context + found components, generate:
411
407
  - Code: `border-destructive` (static) or `animate-shake` (if shake defined)
412
408
 
413
409
  **Full Example:**
414
- ```tsx
415
- <input className="w-full px-3 py-2 border border-input rounded-md
416
- transition-all duration-200
417
- focus:ring-2 focus:ring-primary focus:border-primary
418
- placeholder:text-muted-foreground" />
419
- ```
410
+ Text input field should include:
411
+ - Base styles: `w-full px-3 py-2 border border-input rounded-md`
412
+ - Transition: `transition-all duration-200`
413
+ - Focus effects: `focus:ring-2 focus:ring-primary focus:border-primary`
414
+ - Placeholder styling: `placeholder:text-muted-foreground`
420
415
 
421
416
  ---
422
417
 
@@ -436,15 +431,13 @@ Based on context + found components, generate:
436
431
  - Library: Framer Motion or Tailwind transition
437
432
 
438
433
  **Example (Framer Motion):**
439
- ```tsx
440
- <motion.div
441
- initial={{ x: "-100%" }}
442
- animate={{ x: 0 }}
443
- exit={{ x: "-100%" }}
444
- transition={{ duration: 0.3, ease: [0.4, 0, 0.2, 1] }}>
445
- {/* Sidebar content */}
446
- </motion.div>
447
- ```
434
+ Mobile sidebar with slide-in animation:
435
+ - Component: motion.div wrapper
436
+ - Initial state: `x: "-100%"` (off-screen left)
437
+ - Animate state: `x: 0` (slide to visible position)
438
+ - Exit state: `x: "-100%"` (slide back off-screen)
439
+ - Transition settings: `duration: 0.3`, `ease: [0.4, 0, 0.2, 1]`
440
+ - Content: Sidebar navigation elements inside wrapper
448
441
 
449
442
  ---
450
443
 
@@ -494,13 +487,13 @@ Based on context + found components, generate:
494
487
  - `font-size` (causes text reflow)
495
488
 
496
489
  **Example:**
497
- ```tsx
498
- // WRONG (causes reflow)
499
- className="hover:w-full hover:h-auto"
490
+ Wrong approach (causes reflow):
491
+ - Using `className="hover:w-full hover:h-auto"` triggers layout recalculation
492
+ - CPU-intensive, janky on mobile
500
493
 
501
- // CORRECT (GPU-accelerated)
502
- className="hover:scale-105 transform"
503
- ```
494
+ Correct approach (GPU-accelerated):
495
+ - Use `className="hover:scale-105 transform"` instead
496
+ - Smooth 60fps animations on all devices
504
497
 
505
498
  ---
506
499
 
@@ -740,31 +733,40 @@ Disabled (offline mode):
740
733
 
741
734
  ### STEP 5: Write Output & Report
742
735
 
743
- ```typescript
744
- // Write page-plan.md
745
- writeFile(outputPath, pagePlanContent)
736
+ 1. Write the page plan file:
737
+ - Path: `openspec/changes/{changeId}/page-plan.md`
738
+ - Content: The generated page plan from STEP 4
746
739
 
747
- // Report to user
748
- console.log(`
740
+ 2. Count summary metrics:
741
+ - Found components: Count of reusable components found
742
+ - New shared components: Count of new shared components to create
743
+ - New specific components: Count of page-specific components to create
744
+ - Assets needed: Count of images/icons in checklist
745
+ - Content sections: Count of content sections generated
746
+
747
+ 3. Report to user:
748
+
749
+ ```
749
750
  ✅ Page plan generated!
750
751
 
751
- 📄 Output: ${outputPath}
752
+ 📄 Output: openspec/changes/{changeId}/page-plan.md
752
753
 
753
754
  📊 Summary:
754
- - Found components: ${foundComponents.length} (reuse)
755
- - New shared: ${newSharedComponents.length}
756
- - New specific: ${newSpecificComponents.length}
757
- - Assets needed: ${assetsCount}
758
- - Content sections: ${contentSections.length}
755
+ - Found components: {count} (reuse)
756
+ - New shared: {count}
757
+ - New specific: {count}
758
+ - Assets needed: {count}
759
+ - Content sections: {count}
759
760
 
760
761
  📝 Next Steps:
761
- 1. Review content in ${outputPath}
762
+ 1. Review content in page-plan.md
762
763
  2. Edit as needed (tone, messaging)
763
764
  3. Prepare assets per checklist
764
- 4. Run: /csetup ${changeId}
765
- `)
765
+ 4. Run: /csetup {changeId}
766
766
  ```
767
767
 
768
+ → Done
769
+
768
770
  ---
769
771
 
770
772
  ## Example Scenarios