agileflow 2.61.0 → 2.62.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/README.md +9 -9
- package/package.json +1 -1
- package/scripts/lib/counter.js +103 -0
- package/src/core/commands/auto.md +1 -0
- package/src/core/commands/babysit.md +170 -29
- package/src/core/commands/board.md +1 -0
- package/src/core/commands/ci.md +1 -0
- package/src/core/commands/compress.md +1 -0
- package/src/core/commands/deploy.md +1 -0
- package/src/core/commands/help.md +1 -0
- package/src/core/commands/research.md +1 -0
- package/src/core/commands/skill/create.md +566 -0
- package/src/core/commands/skill/delete.md +189 -0
- package/src/core/commands/skill/edit.md +245 -0
- package/src/core/commands/skill/list.md +155 -0
- package/src/core/commands/skill/test.md +249 -0
- package/src/core/commands/template.md +1 -0
- package/src/core/commands/tests.md +1 -0
- package/src/core/commands/update.md +1 -0
- package/src/core/commands/velocity.md +1 -0
- package/src/core/experts/refactor/expertise.yaml +17 -12
- package/src/core/templates/claude-settings.advanced.example.json +1 -1
- package/src/core/templates/claude-settings.example.json +1 -1
- package/tools/cli/commands/list.js +8 -13
- package/tools/cli/installers/core/installer.js +20 -19
- package/tools/cli/installers/ide/_base-ide.js +18 -4
- package/tools/cli/installers/ide/claude-code.js +4 -15
- package/tools/cli/installers/ide/codex.js +9 -13
- package/tools/cli/lib/content-injector.js +162 -31
- package/tools/cli/lib/utils.js +87 -0
- package/src/core/skills/acceptance-criteria-generator/SKILL.md +0 -46
- package/src/core/skills/adr-template/SKILL.md +0 -62
- package/src/core/skills/agileflow-acceptance-criteria/SKILL.md +0 -156
- package/src/core/skills/agileflow-adr/SKILL.md +0 -147
- package/src/core/skills/agileflow-adr/examples/database-choice-example.md +0 -122
- package/src/core/skills/agileflow-adr/templates/adr-template.md +0 -69
- package/src/core/skills/agileflow-commit-messages/SKILL.md +0 -130
- package/src/core/skills/agileflow-commit-messages/reference/bad-examples.md +0 -168
- package/src/core/skills/agileflow-commit-messages/reference/good-examples.md +0 -120
- package/src/core/skills/agileflow-commit-messages/scripts/check-attribution.sh +0 -15
- package/src/core/skills/agileflow-epic-planner/SKILL.md +0 -184
- package/src/core/skills/agileflow-retro-facilitator/SKILL.md +0 -119
- package/src/core/skills/agileflow-retro-facilitator/cookbook/4ls.md +0 -86
- package/src/core/skills/agileflow-retro-facilitator/cookbook/glad-sad-mad.md +0 -79
- package/src/core/skills/agileflow-retro-facilitator/cookbook/start-stop-continue.md +0 -142
- package/src/core/skills/agileflow-retro-facilitator/prompts/action-items.md +0 -83
- package/src/core/skills/agileflow-sprint-planner/SKILL.md +0 -212
- package/src/core/skills/agileflow-story-writer/SKILL.md +0 -163
- package/src/core/skills/agileflow-story-writer/examples/good-story-example.md +0 -63
- package/src/core/skills/agileflow-story-writer/templates/story-template.md +0 -44
- package/src/core/skills/agileflow-tech-debt/SKILL.md +0 -215
- package/src/core/skills/api-documentation-generator/SKILL.md +0 -65
- package/src/core/skills/changelog-entry/SKILL.md +0 -55
- package/src/core/skills/commit-message-formatter/SKILL.md +0 -50
- package/src/core/skills/deployment-guide-generator/SKILL.md +0 -84
- package/src/core/skills/diagram-generator/SKILL.md +0 -65
- package/src/core/skills/error-handler-template/SKILL.md +0 -78
- package/src/core/skills/migration-checklist/SKILL.md +0 -82
- package/src/core/skills/pr-description/SKILL.md +0 -65
- package/src/core/skills/sql-schema-generator/SKILL.md +0 -69
- package/src/core/skills/story-skeleton/SKILL.md +0 -34
- package/src/core/skills/test-case-generator/SKILL.md +0 -63
- package/src/core/skills/type-definitions/SKILL.md +0 -65
- package/src/core/skills/validation-schema-generator/SKILL.md +0 -64
- package/src/core/skills/writing-skills/SKILL.md +0 -352
- package/src/core/skills/writing-skills/testing-skills-with-subagents.md +0 -232
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Verify a skill works correctly by testing its activation and functionality
|
|
3
|
+
argument-hint: [SKILL_NAME] (optional)
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /agileflow:skill:test
|
|
7
|
+
|
|
8
|
+
Test a skill to verify it activates correctly and produces expected results.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
### STEP 1: Select skill to test
|
|
15
|
+
|
|
16
|
+
If SKILL_NAME not provided, list available skills:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
ls -d .claude/skills/*/ 2>/dev/null | xargs -I {} basename {}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Then ask user:
|
|
23
|
+
|
|
24
|
+
```xml
|
|
25
|
+
<invoke name="AskUserQuestion">
|
|
26
|
+
<parameter name="questions">[{
|
|
27
|
+
"question": "Which skill would you like to test?",
|
|
28
|
+
"header": "Select Skill",
|
|
29
|
+
"multiSelect": false,
|
|
30
|
+
"options": [
|
|
31
|
+
{"label": "<skill-1>", "description": "<description from frontmatter>"},
|
|
32
|
+
{"label": "<skill-2>", "description": "<description from frontmatter>"},
|
|
33
|
+
{"label": "<skill-3>", "description": "<description from frontmatter>"}
|
|
34
|
+
]
|
|
35
|
+
}]</parameter>
|
|
36
|
+
</invoke>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### STEP 2: Read skill metadata
|
|
40
|
+
|
|
41
|
+
Read SKILL.md and extract:
|
|
42
|
+
- Name and description
|
|
43
|
+
- "When to Use" section (activation triggers)
|
|
44
|
+
- Cookbook entries (if any)
|
|
45
|
+
- Quick reference section
|
|
46
|
+
|
|
47
|
+
### STEP 3: Run validation checks
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
🧪 Testing: supabase-swift
|
|
51
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
52
|
+
|
|
53
|
+
Structure Validation:
|
|
54
|
+
✅ SKILL.md exists
|
|
55
|
+
✅ Frontmatter has name and description
|
|
56
|
+
✅ references.md exists
|
|
57
|
+
✅ cookbook/ directory found (2 entries)
|
|
58
|
+
⚠️ No .mcp.json (MCP not configured)
|
|
59
|
+
|
|
60
|
+
Content Validation:
|
|
61
|
+
✅ "When to Use" section present
|
|
62
|
+
✅ Description under 1024 characters
|
|
63
|
+
✅ SKILL.md under 500 lines (current: 287)
|
|
64
|
+
✅ All cookbook files referenced in SKILL.md
|
|
65
|
+
|
|
66
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### STEP 4: Test activation (optional)
|
|
70
|
+
|
|
71
|
+
```xml
|
|
72
|
+
<invoke name="AskUserQuestion">
|
|
73
|
+
<parameter name="questions">[{
|
|
74
|
+
"question": "Would you like to test skill activation with a sample prompt?",
|
|
75
|
+
"header": "Activation Test",
|
|
76
|
+
"multiSelect": false,
|
|
77
|
+
"options": [
|
|
78
|
+
{"label": "Yes, test activation (Recommended)", "description": "I'll simulate using the skill"},
|
|
79
|
+
{"label": "Skip activation test", "description": "Structure validation is enough"},
|
|
80
|
+
{"label": "View SKILL.md content", "description": "Read the full skill instructions"}
|
|
81
|
+
]
|
|
82
|
+
}]</parameter>
|
|
83
|
+
</invoke>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
If user wants activation test:
|
|
87
|
+
|
|
88
|
+
1. **Extract sample triggers** from "When to Use" section
|
|
89
|
+
2. **Present test prompts** based on triggers:
|
|
90
|
+
```
|
|
91
|
+
Sample prompts that should activate this skill:
|
|
92
|
+
|
|
93
|
+
1. "Help me set up Supabase authentication in Swift"
|
|
94
|
+
2. "Create CRUD operations for my database"
|
|
95
|
+
3. "How do I query Supabase from iOS?"
|
|
96
|
+
```
|
|
97
|
+
3. **Ask user to pick one** or provide custom prompt
|
|
98
|
+
4. **Execute the skill** by reading SKILL.md and following instructions
|
|
99
|
+
5. **Report results**
|
|
100
|
+
|
|
101
|
+
### STEP 5: Show test results
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
🧪 Test Results: supabase-swift
|
|
105
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
106
|
+
|
|
107
|
+
Structure: ✅ PASS (5/5 checks)
|
|
108
|
+
Content: ✅ PASS (4/4 checks)
|
|
109
|
+
Activation: ✅ PASS (skill triggered correctly)
|
|
110
|
+
MCP Config: ⚠️ NOT CONFIGURED
|
|
111
|
+
|
|
112
|
+
Overall: ✅ SKILL IS FUNCTIONAL
|
|
113
|
+
|
|
114
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### STEP 6: Offer next actions
|
|
118
|
+
|
|
119
|
+
```xml
|
|
120
|
+
<invoke name="AskUserQuestion">
|
|
121
|
+
<parameter name="questions">[{
|
|
122
|
+
"question": "What would you like to do?",
|
|
123
|
+
"header": "Next Action",
|
|
124
|
+
"multiSelect": false,
|
|
125
|
+
"options": [
|
|
126
|
+
{"label": "Test another skill", "description": "Validate a different skill"},
|
|
127
|
+
{"label": "Edit this skill", "description": "Fix issues or improve"},
|
|
128
|
+
{"label": "Use this skill now", "description": "Start working with it"},
|
|
129
|
+
{"label": "Done", "description": "Exit skill testing"}
|
|
130
|
+
]
|
|
131
|
+
}]</parameter>
|
|
132
|
+
</invoke>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Validation Checks
|
|
138
|
+
|
|
139
|
+
### Structure Checks
|
|
140
|
+
|
|
141
|
+
| Check | Pass Condition |
|
|
142
|
+
|-------|----------------|
|
|
143
|
+
| SKILL.md exists | File present in skill directory |
|
|
144
|
+
| Frontmatter valid | Has `name:` and `description:` |
|
|
145
|
+
| references.md | File exists (optional but recommended) |
|
|
146
|
+
| cookbook/ | Directory exists if referenced in SKILL.md |
|
|
147
|
+
| .mcp.json | Valid JSON if present |
|
|
148
|
+
|
|
149
|
+
### Content Checks
|
|
150
|
+
|
|
151
|
+
| Check | Pass Condition |
|
|
152
|
+
|-------|----------------|
|
|
153
|
+
| When to Use | Section present with activation triggers |
|
|
154
|
+
| Description length | Under 1024 characters |
|
|
155
|
+
| SKILL.md size | Under 500 lines |
|
|
156
|
+
| Cookbook references | All referenced files exist |
|
|
157
|
+
| No broken links | All local file references valid |
|
|
158
|
+
|
|
159
|
+
### MCP Checks (if .mcp.json exists)
|
|
160
|
+
|
|
161
|
+
| Check | Pass Condition |
|
|
162
|
+
|-------|----------------|
|
|
163
|
+
| Valid JSON | Parses without errors |
|
|
164
|
+
| Has mcpServers | Contains mcpServers object |
|
|
165
|
+
| Command exists | Command is npx or valid executable |
|
|
166
|
+
| Env vars documented | Any ${VAR} has comments |
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Test Report Format
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
🧪 Skill Test Report: <skill-name>
|
|
174
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
175
|
+
|
|
176
|
+
STRUCTURE VALIDATION
|
|
177
|
+
[✅|❌] SKILL.md exists
|
|
178
|
+
[✅|❌] Frontmatter valid (name, description)
|
|
179
|
+
[✅|⚠️] references.md exists
|
|
180
|
+
[✅|⚠️] cookbook/ directory
|
|
181
|
+
[✅|⚠️] .mcp.json present
|
|
182
|
+
|
|
183
|
+
CONTENT VALIDATION
|
|
184
|
+
[✅|❌] "When to Use" section
|
|
185
|
+
[✅|❌] Description < 1024 chars (<current> chars)
|
|
186
|
+
[✅|❌] SKILL.md < 500 lines (<current> lines)
|
|
187
|
+
[✅|❌] All cookbook files exist
|
|
188
|
+
|
|
189
|
+
ACTIVATION TEST
|
|
190
|
+
[✅|❌] Skill triggered on test prompt
|
|
191
|
+
[✅|❌] Produced expected output format
|
|
192
|
+
|
|
193
|
+
ISSUES FOUND
|
|
194
|
+
- <issue 1>
|
|
195
|
+
- <issue 2>
|
|
196
|
+
|
|
197
|
+
RECOMMENDATIONS
|
|
198
|
+
- <suggestion 1>
|
|
199
|
+
- <suggestion 2>
|
|
200
|
+
|
|
201
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
202
|
+
Overall: [✅ PASS | ⚠️ WARNINGS | ❌ FAIL]
|
|
203
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Error Handling
|
|
209
|
+
|
|
210
|
+
### Skill Not Found
|
|
211
|
+
```
|
|
212
|
+
❌ Skill "<name>" not found.
|
|
213
|
+
|
|
214
|
+
Available skills:
|
|
215
|
+
- ui-components
|
|
216
|
+
- api-integration
|
|
217
|
+
|
|
218
|
+
Use /agileflow:skill:list to see all skills.
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### No Skills Installed
|
|
222
|
+
```
|
|
223
|
+
❌ No skills to test.
|
|
224
|
+
|
|
225
|
+
Create a skill first: /agileflow:skill:create
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Validation Failed
|
|
229
|
+
```
|
|
230
|
+
❌ Skill "<name>" has issues:
|
|
231
|
+
|
|
232
|
+
❌ Missing SKILL.md frontmatter
|
|
233
|
+
❌ Description exceeds 1024 characters (1523)
|
|
234
|
+
⚠️ No "When to Use" section
|
|
235
|
+
|
|
236
|
+
Fix with: /agileflow:skill:edit <name>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Usage
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
# Interactive mode
|
|
245
|
+
/agileflow:skill:test
|
|
246
|
+
|
|
247
|
+
# Test specific skill
|
|
248
|
+
/agileflow:skill:test supabase-swift
|
|
249
|
+
```
|
|
@@ -26,22 +26,22 @@ files:
|
|
|
26
26
|
core_content:
|
|
27
27
|
- path: packages/cli/src/core/commands/
|
|
28
28
|
purpose: Slash command markdown files
|
|
29
|
-
count:
|
|
29
|
+
count: "{{COMMAND_COUNT}}"
|
|
30
30
|
pattern: "<command>.md with frontmatter"
|
|
31
31
|
|
|
32
32
|
- path: packages/cli/src/core/agents/
|
|
33
33
|
purpose: Agent prompt markdown files
|
|
34
|
-
count:
|
|
34
|
+
count: "{{AGENT_COUNT}}"
|
|
35
35
|
pattern: "<agent>.md with frontmatter (name, description, tools, model)"
|
|
36
36
|
|
|
37
37
|
- path: packages/cli/src/core/experts/
|
|
38
38
|
purpose: Expert knowledge files
|
|
39
|
-
count:
|
|
39
|
+
count: "{{SKILL_COUNT}}"
|
|
40
40
|
pattern: "<domain>/expertise.yaml, question.md, self-improve.md, workflow.md"
|
|
41
41
|
|
|
42
42
|
- path: packages/cli/src/core/skills/
|
|
43
43
|
purpose: Auto-activating skills
|
|
44
|
-
count:
|
|
44
|
+
count: "{{SKILL_COUNT}}"
|
|
45
45
|
pattern: "<skill>/SKILL.md"
|
|
46
46
|
|
|
47
47
|
scripts:
|
|
@@ -67,10 +67,10 @@ relationships:
|
|
|
67
67
|
|
|
68
68
|
- name: content_structure
|
|
69
69
|
locations:
|
|
70
|
-
- "commands/ -
|
|
71
|
-
- "agents/ -
|
|
72
|
-
- "experts/ -
|
|
73
|
-
- "skills/ -
|
|
70
|
+
- "commands/ - {{COMMAND_COUNT}} .md files"
|
|
71
|
+
- "agents/ - {{AGENT_COUNT}} .md files"
|
|
72
|
+
- "experts/ - {{SKILL_COUNT}} directories"
|
|
73
|
+
- "skills/ - {{SKILL_COUNT}} directories"
|
|
74
74
|
observation: "Consistent patterns across all content types"
|
|
75
75
|
|
|
76
76
|
patterns:
|
|
@@ -78,9 +78,14 @@ patterns:
|
|
|
78
78
|
description: "Placeholders replaced at install time"
|
|
79
79
|
location: "lib/content-injector.js"
|
|
80
80
|
placeholders:
|
|
81
|
-
- "
|
|
82
|
-
- "
|
|
83
|
-
|
|
81
|
+
- "{{COMMAND_COUNT}} - Number of commands"
|
|
82
|
+
- "{{AGENT_COUNT}} - Number of agents"
|
|
83
|
+
- "{{SKILL_COUNT}} - Number of skills"
|
|
84
|
+
- "{{VERSION}} - AgileFlow version"
|
|
85
|
+
- "{{INSTALL_DATE}} - Installation date"
|
|
86
|
+
- "<!-- {{AGENT_LIST}} --> - Full agent list"
|
|
87
|
+
- "<!-- {{COMMAND_LIST}} --> - Full command list"
|
|
88
|
+
benefit: "Zero maintenance for lists and counts"
|
|
84
89
|
|
|
85
90
|
- name: IDE-Specific Installers
|
|
86
91
|
description: "Separate installer per IDE"
|
|
@@ -116,7 +121,7 @@ learnings:
|
|
|
116
121
|
|
|
117
122
|
- date: 2025-12-21
|
|
118
123
|
context: "Analyzed content structure"
|
|
119
|
-
insight: "Consistent patterns:
|
|
124
|
+
insight: "Consistent patterns: {{COMMAND_COUNT}} commands, {{AGENT_COUNT}} agents, {{SKILL_COUNT}} experts, {{SKILL_COUNT}} skills - all use frontmatter markdown"
|
|
120
125
|
source: "packages/cli/src/core/"
|
|
121
126
|
|
|
122
127
|
- date: 2025-12-21
|
|
@@ -10,6 +10,7 @@ const fs = require('fs-extra');
|
|
|
10
10
|
const yaml = require('js-yaml');
|
|
11
11
|
const { Installer } = require('../installers/core/installer');
|
|
12
12
|
const { displayLogo, displaySection, success, warning, info } = require('../lib/ui');
|
|
13
|
+
const { parseFrontmatter: parseYamlFrontmatter } = require('../../../scripts/lib/frontmatter-parser');
|
|
13
14
|
|
|
14
15
|
const installer = new Installer();
|
|
15
16
|
|
|
@@ -255,23 +256,17 @@ async function listExperts(agileflowPath) {
|
|
|
255
256
|
}
|
|
256
257
|
|
|
257
258
|
/**
|
|
258
|
-
* Parse YAML frontmatter from markdown
|
|
259
|
+
* Parse YAML frontmatter from markdown (wrapper for shared parser)
|
|
259
260
|
* @param {string} content - File content
|
|
260
261
|
* @returns {{ frontmatter: Object|null, content: string }}
|
|
261
262
|
*/
|
|
262
263
|
function parseFrontmatter(content) {
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
try {
|
|
270
|
-
const frontmatter = yaml.load(match[1]);
|
|
271
|
-
return { frontmatter, content: match[2] };
|
|
272
|
-
} catch {
|
|
273
|
-
return { frontmatter: null, content };
|
|
274
|
-
}
|
|
264
|
+
const frontmatter = parseYamlFrontmatter(content);
|
|
265
|
+
const body = content.replace(/^---\n[\s\S]*?\n---\n?/, '');
|
|
266
|
+
return {
|
|
267
|
+
frontmatter: Object.keys(frontmatter).length > 0 ? frontmatter : null,
|
|
268
|
+
content: body,
|
|
269
|
+
};
|
|
275
270
|
}
|
|
276
271
|
|
|
277
272
|
/**
|
|
@@ -5,26 +5,15 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const path = require('node:path');
|
|
8
|
-
const crypto = require('node:crypto');
|
|
9
8
|
const fs = require('fs-extra');
|
|
10
9
|
const chalk = require('chalk');
|
|
11
10
|
const ora = require('ora');
|
|
12
11
|
const yaml = require('js-yaml');
|
|
12
|
+
const { injectContent } = require('../../lib/content-injector');
|
|
13
|
+
const { sha256Hex, toPosixPath, safeTimestampForPath } = require('../../lib/utils');
|
|
13
14
|
|
|
14
15
|
const TEXT_EXTENSIONS = new Set(['.md', '.yaml', '.yml', '.txt', '.json']);
|
|
15
16
|
|
|
16
|
-
function sha256Hex(data) {
|
|
17
|
-
return crypto.createHash('sha256').update(data).digest('hex');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function toPosixPath(filePath) {
|
|
21
|
-
return filePath.split(path.sep).join('/');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function safeTimestampForPath(date = new Date()) {
|
|
25
|
-
return date.toISOString().replace(/[:.]/g, '-');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
17
|
/**
|
|
29
18
|
* Get the source path for AgileFlow content
|
|
30
19
|
* @returns {string} Path to src directory
|
|
@@ -48,6 +37,11 @@ class Installer {
|
|
|
48
37
|
constructor() {
|
|
49
38
|
this.sourcePath = getSourcePath();
|
|
50
39
|
this.packageRoot = getPackageRoot();
|
|
40
|
+
this.coreDir = path.join(this.sourcePath, 'core');
|
|
41
|
+
|
|
42
|
+
// Load version from package.json
|
|
43
|
+
const packageJson = require(path.join(this.packageRoot, 'package.json'));
|
|
44
|
+
this.version = packageJson.version;
|
|
51
45
|
}
|
|
52
46
|
|
|
53
47
|
/**
|
|
@@ -260,7 +254,7 @@ class Installer {
|
|
|
260
254
|
}
|
|
261
255
|
|
|
262
256
|
/**
|
|
263
|
-
* Copy a file with placeholder replacements
|
|
257
|
+
* Copy a file with placeholder replacements using content injector
|
|
264
258
|
* @param {string} source - Source file path
|
|
265
259
|
* @param {string} dest - Destination file path
|
|
266
260
|
* @param {string} agileflowFolder - AgileFlow folder name
|
|
@@ -271,9 +265,12 @@ class Installer {
|
|
|
271
265
|
if (TEXT_EXTENSIONS.has(ext)) {
|
|
272
266
|
let content = await fs.readFile(source, 'utf8');
|
|
273
267
|
|
|
274
|
-
//
|
|
275
|
-
content = content
|
|
276
|
-
|
|
268
|
+
// Use content injector for all placeholder replacements
|
|
269
|
+
content = injectContent(content, {
|
|
270
|
+
coreDir: this.coreDir,
|
|
271
|
+
agileflowFolder,
|
|
272
|
+
version: this.version,
|
|
273
|
+
});
|
|
277
274
|
|
|
278
275
|
await fs.writeFile(dest, content, 'utf8');
|
|
279
276
|
} else {
|
|
@@ -304,8 +301,12 @@ class Installer {
|
|
|
304
301
|
let newContent;
|
|
305
302
|
if (isText) {
|
|
306
303
|
let content = await fs.readFile(source, 'utf8');
|
|
307
|
-
|
|
308
|
-
content = content
|
|
304
|
+
// Use content injector for all placeholder replacements
|
|
305
|
+
content = injectContent(content, {
|
|
306
|
+
coreDir: this.coreDir,
|
|
307
|
+
agileflowFolder,
|
|
308
|
+
version: this.version,
|
|
309
|
+
});
|
|
309
310
|
newContent = content;
|
|
310
311
|
} else {
|
|
311
312
|
newContent = await fs.readFile(source);
|
|
@@ -68,11 +68,25 @@ class BaseIdeSetup {
|
|
|
68
68
|
injectDynamicContent(content, agileflowDir) {
|
|
69
69
|
const { injectContent } = require('../../lib/content-injector');
|
|
70
70
|
// agileflowDir is the user's .agileflow installation directory
|
|
71
|
-
// which has agents
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
// which has agents/, commands/, skills/ at the root level
|
|
72
|
+
return injectContent(content, {
|
|
73
|
+
coreDir: agileflowDir,
|
|
74
|
+
agileflowFolder: this.agileflowFolder,
|
|
75
|
+
version: this.getVersion(),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
74
78
|
|
|
75
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Get the current AgileFlow version
|
|
81
|
+
* @returns {string} Version string
|
|
82
|
+
*/
|
|
83
|
+
getVersion() {
|
|
84
|
+
try {
|
|
85
|
+
const packageJson = require('../../../../package.json');
|
|
86
|
+
return packageJson.version || 'unknown';
|
|
87
|
+
} catch {
|
|
88
|
+
return 'unknown';
|
|
89
|
+
}
|
|
76
90
|
}
|
|
77
91
|
|
|
78
92
|
/**
|
|
@@ -63,22 +63,11 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
|
|
63
63
|
await this.installCommandsRecursive(agentsSource, spawnableAgentsDir, agileflowDir, false);
|
|
64
64
|
console.log(chalk.dim(` - Spawnable agents: .claude/agents/agileflow/`));
|
|
65
65
|
|
|
66
|
-
//
|
|
67
|
-
|
|
66
|
+
// Create skills directory for user-generated skills (.claude/skills/)
|
|
67
|
+
// AgileFlow no longer ships static skills - users generate them via /agileflow:skill:create
|
|
68
68
|
const skillsTargetDir = path.join(claudeDir, 'skills');
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const skillResult = await this.installCommandsRecursive(
|
|
72
|
-
skillsSource,
|
|
73
|
-
skillsTargetDir,
|
|
74
|
-
agileflowDir,
|
|
75
|
-
false
|
|
76
|
-
);
|
|
77
|
-
skillCount = skillResult.commands + skillResult.subdirs;
|
|
78
|
-
if (skillCount > 0) {
|
|
79
|
-
console.log(chalk.dim(` - Skills: .claude/skills/`));
|
|
80
|
-
}
|
|
81
|
-
}
|
|
69
|
+
await this.ensureDir(skillsTargetDir);
|
|
70
|
+
console.log(chalk.dim(` - Skills directory: .claude/skills/ (for user-generated skills)`));
|
|
82
71
|
|
|
83
72
|
const totalCommands = commandResult.commands + agentResult.commands;
|
|
84
73
|
const totalSubdirs =
|
|
@@ -16,6 +16,7 @@ const fs = require('fs-extra');
|
|
|
16
16
|
const chalk = require('chalk');
|
|
17
17
|
const yaml = require('js-yaml');
|
|
18
18
|
const { BaseIdeSetup } = require('./_base-ide');
|
|
19
|
+
const { parseFrontmatter } = require('../../../../scripts/lib/frontmatter-parser');
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* OpenAI Codex CLI setup handler
|
|
@@ -59,22 +60,17 @@ class CodexSetup extends BaseIdeSetup {
|
|
|
59
60
|
* @returns {string} Codex SKILL.md content
|
|
60
61
|
*/
|
|
61
62
|
convertAgentToSkill(content, agentName) {
|
|
62
|
-
// Extract frontmatter
|
|
63
|
+
// Extract frontmatter using shared parser
|
|
63
64
|
let description = `AgileFlow ${agentName} agent`;
|
|
64
65
|
let model = 'default';
|
|
65
66
|
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (frontmatter.model) {
|
|
74
|
-
model = frontmatter.model;
|
|
75
|
-
}
|
|
76
|
-
} catch (e) {
|
|
77
|
-
// Ignore YAML parse errors
|
|
67
|
+
const frontmatter = parseFrontmatter(content);
|
|
68
|
+
if (frontmatter && Object.keys(frontmatter).length > 0) {
|
|
69
|
+
if (frontmatter.description) {
|
|
70
|
+
description = frontmatter.description;
|
|
71
|
+
}
|
|
72
|
+
if (frontmatter.model) {
|
|
73
|
+
model = frontmatter.model;
|
|
78
74
|
}
|
|
79
75
|
}
|
|
80
76
|
|