@codihaus/claude-skills 1.6.20 → 1.6.22
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/bin/cli.js +1 -0
- package/knowledge/stacks/_index.md +29 -3
- package/package.json +1 -1
- package/skills/_registry.md +23 -0
- package/skills/debrief/SKILL.md +89 -413
- package/skills/debrief/references/codes.md +135 -0
- package/skills/debrief/references/research.md +227 -0
- package/skills/debrief/references/templates/brd-references.md +80 -0
- package/skills/debrief/references/templates/feature-references.md +98 -0
- package/skills/debrief/references/templates/use-case.md +31 -0
- package/skills/debrief/references/workflow.md +315 -0
- package/skills/dev-coding/SKILL.md +6 -0
- package/src/commands/init.js +7 -2
- package/src/utils/skills.js +153 -6
- package/skills/debrief/references/file-patterns.md +0 -173
- package/skills/debrief/references/group-codes.md +0 -72
- package/skills/debrief/references/research-queries.md +0 -106
- package/skills/debrief/references/use-case-template.md +0 -141
- /package/skills/debrief/references/{change-request-template.md → templates/change-request.md} +0 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
# Workflow Principles
|
|
2
|
+
|
|
3
|
+
**Mindset**: Business analyst. Focus on WHAT and WHY, defer HOW to /dev-specs.
|
|
4
|
+
|
|
5
|
+
**Methodology**: Mode detection → Context gathering → Research → Document → Questionnaire
|
|
6
|
+
|
|
7
|
+
**Expected Outcome**: Market-validated BRD with tiered features, lean use cases, customer questionnaire.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Mode Detection
|
|
12
|
+
|
|
13
|
+
**Principle**: Behavior changes based on context.
|
|
14
|
+
|
|
15
|
+
**Detection**:
|
|
16
|
+
- `--answers {file}` → Process Answers mode
|
|
17
|
+
- `--questionnaire-only` → Questionnaire Only mode
|
|
18
|
+
- No `plans/brd/` → New Project mode
|
|
19
|
+
- `plans/brd/` exists → Add Feature mode
|
|
20
|
+
- Modifying confirmed UC → Change Request mode
|
|
21
|
+
|
|
22
|
+
**Action**: Execute appropriate workflow for detected mode.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## New Project Mode
|
|
27
|
+
|
|
28
|
+
**Goal**: Create initial BRD with market-validated features.
|
|
29
|
+
|
|
30
|
+
**Mindset**: Discovery mode. Understand context, research market, validate with customer.
|
|
31
|
+
|
|
32
|
+
### Context Gathering
|
|
33
|
+
|
|
34
|
+
**Ask 5 questions** (AskUserQuestion):
|
|
35
|
+
1. Project type (new/existing codebase)
|
|
36
|
+
2. Industry (SaaS/E-commerce/Marketplace/etc.)
|
|
37
|
+
3. Target users (B2B/B2C/Internal)
|
|
38
|
+
4. Constraints (timeline/budget/compliance/integrations)
|
|
39
|
+
5. Scope tier (Core/Standard/Full)
|
|
40
|
+
|
|
41
|
+
**If existing codebase**: Scan for docs + features (Glob, Read)
|
|
42
|
+
|
|
43
|
+
**Output**: Context understanding, scope alignment
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
### Market Research
|
|
48
|
+
|
|
49
|
+
**Methodology**: See `research.md` for full process.
|
|
50
|
+
|
|
51
|
+
**Comparison-first**:
|
|
52
|
+
- Find 2-3 comparison/alternative pages
|
|
53
|
+
- Extract feature matrix
|
|
54
|
+
- Initial tier hypothesis
|
|
55
|
+
|
|
56
|
+
**Deep validation**:
|
|
57
|
+
- Per feature: cross-validate with ecosystem + user signals
|
|
58
|
+
- Classify tier (MVP/Standard/Advanced)
|
|
59
|
+
- Collect evidence
|
|
60
|
+
|
|
61
|
+
**Output**: Features with tier classification and evidence
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### Feature Sequencing
|
|
66
|
+
|
|
67
|
+
**Principle**: Order by dependencies within each tier.
|
|
68
|
+
|
|
69
|
+
**Common patterns**:
|
|
70
|
+
- Create before operate (signup before login)
|
|
71
|
+
- Auth before features (login before projects)
|
|
72
|
+
- Basic before advanced (CRUD before bulk operations)
|
|
73
|
+
- Data before analytics (tracking before dashboards)
|
|
74
|
+
- Core before extensions (email before templates)
|
|
75
|
+
|
|
76
|
+
**Validation**: No forward dependencies (UC-001 doesn't depend on UC-002)
|
|
77
|
+
|
|
78
|
+
**Output**: Sequenced feature list (UC-001, UC-002, UC-003...)
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### Use Case Generation
|
|
83
|
+
|
|
84
|
+
**Principle**: Lean 80/20 format (~30 lines).
|
|
85
|
+
|
|
86
|
+
**Include (20%)**:
|
|
87
|
+
- Story (1 line)
|
|
88
|
+
- Critical acceptance criteria (3-5 bullets)
|
|
89
|
+
- Key business rules (constraints, limits)
|
|
90
|
+
- Open questions (blockers)
|
|
91
|
+
|
|
92
|
+
**Defer to /dev-specs (80%)**:
|
|
93
|
+
- Detailed flows, integrations, edge cases, UI/UX
|
|
94
|
+
|
|
95
|
+
**Template**: `templates/use-case.md`
|
|
96
|
+
|
|
97
|
+
**Output**: Lean use cases in `brd/use-cases/{feature}/UC-{GROUP}-{NNN}-{slug}.md`
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
### BRD Structure
|
|
102
|
+
|
|
103
|
+
**Project-wide** (`brd/`):
|
|
104
|
+
- README.md (all features index)
|
|
105
|
+
- context.md (stakeholders, users, constraints)
|
|
106
|
+
- references.md (industry, compliance, competitor overview)
|
|
107
|
+
- changelog.md
|
|
108
|
+
|
|
109
|
+
**Feature-specific** (`features/{feature}/`):
|
|
110
|
+
- README.md (feature overview)
|
|
111
|
+
- references.md (market research, tier evidence)
|
|
112
|
+
- questionnaire-{date}.xlsx
|
|
113
|
+
|
|
114
|
+
**Templates**: `templates/brd-references.md`, `templates/feature-references.md`
|
|
115
|
+
|
|
116
|
+
**Output**: Organized BRD structure with scope separation
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### Questionnaire
|
|
121
|
+
|
|
122
|
+
**Principle**: Always generate. Validate assumptions + fill gaps.
|
|
123
|
+
|
|
124
|
+
**Include**:
|
|
125
|
+
- **Validation questions**: "We found 9/10 competitors offer SSO. Confirm?"
|
|
126
|
+
- **Open questions**: "What's max team size per account?"
|
|
127
|
+
|
|
128
|
+
**Categories**: Validation, Business, Requirements, Constraints, Integration
|
|
129
|
+
|
|
130
|
+
**Output**: `features/{feature}/questionnaire-{date}.xlsx`
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### Summary
|
|
135
|
+
|
|
136
|
+
**Provide**:
|
|
137
|
+
- Files created (brd/, features/)
|
|
138
|
+
- Use case count (lean format)
|
|
139
|
+
- Research summary (comparison pages, evidence sources)
|
|
140
|
+
- Tier distribution (MVP: X, Standard: Y, Advanced: Z)
|
|
141
|
+
- Questionnaire location and question count
|
|
142
|
+
|
|
143
|
+
**Next steps**:
|
|
144
|
+
- Review BRD with stakeholders
|
|
145
|
+
- Send questionnaire to customer
|
|
146
|
+
- Process with `/debrief --answers {path}`
|
|
147
|
+
- Then `/dev-specs {feature}` for implementation
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Add Feature Mode
|
|
152
|
+
|
|
153
|
+
**Goal**: Extend existing BRD with new feature.
|
|
154
|
+
|
|
155
|
+
**Mindset**: Continuity mode. Check duplicates, maintain consistency.
|
|
156
|
+
|
|
157
|
+
### Context Gathering
|
|
158
|
+
|
|
159
|
+
**Ask 2 questions**:
|
|
160
|
+
1. Feature name
|
|
161
|
+
2. Scope tier (Core/Standard/Full)
|
|
162
|
+
|
|
163
|
+
**Duplicate check**: Read `docs-graph.json` if exists, warn if similar feature found
|
|
164
|
+
|
|
165
|
+
**Output**: Feature to add, scope confirmed
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
### Research & Document
|
|
170
|
+
|
|
171
|
+
**Same as New Project**:
|
|
172
|
+
- Market research (comparison-first, see `research.md`)
|
|
173
|
+
- Feature sequencing (dependencies)
|
|
174
|
+
- Lean use cases (templates/use-case.md)
|
|
175
|
+
|
|
176
|
+
**Update**:
|
|
177
|
+
- `brd/README.md` (add to index)
|
|
178
|
+
- `brd/changelog.md` (log addition)
|
|
179
|
+
- Create `features/{feature}/` folder
|
|
180
|
+
|
|
181
|
+
**Questionnaire**: Always generate (validation + open questions)
|
|
182
|
+
|
|
183
|
+
**Output**: Feature added to BRD with research and questionnaire
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Process Answers Mode
|
|
188
|
+
|
|
189
|
+
**Goal**: Update BRD with customer responses.
|
|
190
|
+
|
|
191
|
+
**Mindset**: Integration mode. Incorporate feedback, resolve gaps.
|
|
192
|
+
|
|
193
|
+
### Process
|
|
194
|
+
|
|
195
|
+
**Read questionnaire** (Excel file):
|
|
196
|
+
- Extract answers from "Answer" column
|
|
197
|
+
- Match to source use cases via "Context/Source"
|
|
198
|
+
|
|
199
|
+
**Update use cases**:
|
|
200
|
+
- Remove questions from "Open Questions" section
|
|
201
|
+
- Add answers to relevant sections (Acceptance Criteria, Business Rules)
|
|
202
|
+
|
|
203
|
+
**Update feature README**:
|
|
204
|
+
- Log questionnaire as processed
|
|
205
|
+
- Track history
|
|
206
|
+
|
|
207
|
+
**Check completeness**:
|
|
208
|
+
- If gaps remain → generate new questionnaire (new date)
|
|
209
|
+
- If complete → update UC status to "Confirmed"
|
|
210
|
+
|
|
211
|
+
**Output**: Updated use cases, questionnaire history, completion status
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Change Request Mode
|
|
216
|
+
|
|
217
|
+
**Goal**: Track modifications to confirmed BRD.
|
|
218
|
+
|
|
219
|
+
**Mindset**: Traceability mode. Document change rationale and impact.
|
|
220
|
+
|
|
221
|
+
### Process
|
|
222
|
+
|
|
223
|
+
**Create CR** (`brd/changes/CR-{NNN}-{slug}.md`):
|
|
224
|
+
- Change description
|
|
225
|
+
- Reason for change
|
|
226
|
+
- Impact analysis (affected UCs)
|
|
227
|
+
|
|
228
|
+
**If gaps introduced**: Generate questionnaire at `brd/changes/CR-{NNN}-questionnaire-{date}.xlsx`
|
|
229
|
+
|
|
230
|
+
**Update**: Affected use cases, references, changelog
|
|
231
|
+
|
|
232
|
+
**Output**: CR document with impact analysis
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Questionnaire Only Mode
|
|
237
|
+
|
|
238
|
+
**Goal**: Generate questions without creating BRD.
|
|
239
|
+
|
|
240
|
+
**Mindset**: Quick mode. Capture questions for customer.
|
|
241
|
+
|
|
242
|
+
### Process
|
|
243
|
+
|
|
244
|
+
**Ask**:
|
|
245
|
+
- Topic/feature name
|
|
246
|
+
- Custom questions (user provides)
|
|
247
|
+
|
|
248
|
+
**Generate**: `questionnaire-{date}.xlsx` in current directory
|
|
249
|
+
|
|
250
|
+
**Output**: Excel file ready to send
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## File Organization Principles
|
|
255
|
+
|
|
256
|
+
**Scope-based placement**:
|
|
257
|
+
|
|
258
|
+
**Project-wide** (applies to entire product):
|
|
259
|
+
- Industry landscape → `brd/references.md`
|
|
260
|
+
- Compliance (GDPR, PCI) → `brd/references.md`
|
|
261
|
+
- Competitor companies → `brd/references.md`
|
|
262
|
+
- Use cases → `brd/use-cases/{feature}/`
|
|
263
|
+
|
|
264
|
+
**Feature-specific** (applies to one feature):
|
|
265
|
+
- Market research → `features/{feature}/references.md`
|
|
266
|
+
- Tier evidence → `features/{feature}/references.md`
|
|
267
|
+
- Questionnaire → `features/{feature}/questionnaire-{date}.xlsx`
|
|
268
|
+
|
|
269
|
+
**Cross-reference**: Files can link to each other
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Use Case Principles
|
|
274
|
+
|
|
275
|
+
**Lean format** (80/20 rule):
|
|
276
|
+
- ~30 lines max
|
|
277
|
+
- Scannable in 30 seconds
|
|
278
|
+
- Business focus only (no technical details)
|
|
279
|
+
|
|
280
|
+
**Sequencing**:
|
|
281
|
+
- Dependencies first (create before validate)
|
|
282
|
+
- Logical user journey
|
|
283
|
+
- No forward references
|
|
284
|
+
|
|
285
|
+
**Wikilinks**: Use [[node-id]] for docs-graph traceability
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Research Principles
|
|
290
|
+
|
|
291
|
+
**See**: `research.md` for full methodology.
|
|
292
|
+
|
|
293
|
+
**Key principles**:
|
|
294
|
+
- Comparison-first (fast feature extraction)
|
|
295
|
+
- Evidence-based (multiple source types)
|
|
296
|
+
- Tier validation (MVP/Standard/Advanced rules)
|
|
297
|
+
- Always questionnaire (validation + open questions)
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Summary
|
|
302
|
+
|
|
303
|
+
**Workflow adapts to mode**:
|
|
304
|
+
- New Project: Full discovery and research
|
|
305
|
+
- Add Feature: Focused research, duplicate check
|
|
306
|
+
- Process Answers: Integration and validation
|
|
307
|
+
- Change Request: Impact tracking
|
|
308
|
+
- Questionnaire Only: Quick question generation
|
|
309
|
+
|
|
310
|
+
**Consistent principles**:
|
|
311
|
+
- Business focus (WHAT and WHY)
|
|
312
|
+
- Evidence-based validation
|
|
313
|
+
- Lean documentation (80/20)
|
|
314
|
+
- Scope-based organization
|
|
315
|
+
- Customer validation (questionnaire)
|
|
@@ -73,6 +73,12 @@ You have three layers of knowledge to apply:
|
|
|
73
73
|
- "Nuxt" → `knowledge/stacks/nuxt/_index.md`
|
|
74
74
|
- "Directus" → `knowledge/stacks/directus/_index.md`
|
|
75
75
|
|
|
76
|
+
**Deep knowledge loading (for complex features):**
|
|
77
|
+
- First read `knowledge/_knowledge.json` to discover available reference files
|
|
78
|
+
- Load additional references when needed: `knowledge/stacks/{stack}/references/*.md`
|
|
79
|
+
- Example: For performance-critical features, load `references/performance.md`
|
|
80
|
+
- Example: For complex patterns, load `references/patterns.md`
|
|
81
|
+
|
|
76
82
|
**If you skip this step**, you'll implement using generic patterns instead of framework-specific best practices (e.g., using fetch instead of Server Actions in Next.js).
|
|
77
83
|
|
|
78
84
|
## Expected Outcome
|
package/src/commands/init.js
CHANGED
|
@@ -186,17 +186,22 @@ export async function init(options) {
|
|
|
186
186
|
const knowledgeSpinner = ora('Installing knowledge base...').start();
|
|
187
187
|
|
|
188
188
|
try {
|
|
189
|
-
const { copied: knowledgeCopied, errors: knowledgeErrors } = await copyKnowledgeToProject(
|
|
189
|
+
const { copied: knowledgeCopied, errors: knowledgeErrors } = await copyKnowledgeToProject(
|
|
190
|
+
projectPath,
|
|
191
|
+
options.knowledge // Custom knowledge path if provided
|
|
192
|
+
);
|
|
190
193
|
|
|
191
194
|
if (knowledgeErrors.length > 0) {
|
|
192
195
|
knowledgeSpinner.warn(`Installed ${knowledgeCopied.length} knowledge folders with ${knowledgeErrors.length} errors`);
|
|
193
196
|
} else if (knowledgeCopied.length > 0) {
|
|
194
|
-
|
|
197
|
+
const source = options.knowledge ? ` from ${options.knowledge}` : '';
|
|
198
|
+
knowledgeSpinner.succeed(`Installed knowledge${source}: ${knowledgeCopied.join(', ')}`);
|
|
195
199
|
} else {
|
|
196
200
|
knowledgeSpinner.info('No knowledge to install');
|
|
197
201
|
}
|
|
198
202
|
} catch (e) {
|
|
199
203
|
knowledgeSpinner.warn('Failed to install knowledge');
|
|
204
|
+
console.error(chalk.gray(` ${e.message}`));
|
|
200
205
|
}
|
|
201
206
|
|
|
202
207
|
// Step 6: Copy scripts (graph.py, etc.)
|
package/src/utils/skills.js
CHANGED
|
@@ -272,13 +272,24 @@ export async function checkForUpdates(projectPath) {
|
|
|
272
272
|
|
|
273
273
|
/**
|
|
274
274
|
* Copy knowledge (stacks, domains) to project
|
|
275
|
+
* @param {string} projectPath - Target project path
|
|
276
|
+
* @param {string} customSource - Optional custom knowledge source path
|
|
275
277
|
*/
|
|
276
|
-
export async function copyKnowledgeToProject(projectPath) {
|
|
278
|
+
export async function copyKnowledgeToProject(projectPath, customSource = null) {
|
|
277
279
|
const targetPath = path.join(projectPath, '.claude', 'knowledge');
|
|
280
|
+
const sourcePath = customSource
|
|
281
|
+
? path.resolve(customSource)
|
|
282
|
+
: KNOWLEDGE_SOURCE;
|
|
278
283
|
|
|
279
284
|
// Check if source exists
|
|
280
|
-
if (!await fs.pathExists(
|
|
281
|
-
return {
|
|
285
|
+
if (!await fs.pathExists(sourcePath)) {
|
|
286
|
+
return {
|
|
287
|
+
copied: [],
|
|
288
|
+
errors: [{
|
|
289
|
+
name: 'knowledge',
|
|
290
|
+
error: `Source not found: ${sourcePath}`
|
|
291
|
+
}]
|
|
292
|
+
};
|
|
282
293
|
}
|
|
283
294
|
|
|
284
295
|
// Remove existing and copy fresh
|
|
@@ -289,22 +300,27 @@ export async function copyKnowledgeToProject(projectPath) {
|
|
|
289
300
|
const errors = [];
|
|
290
301
|
|
|
291
302
|
try {
|
|
292
|
-
const items = await fs.readdir(
|
|
303
|
+
const items = await fs.readdir(sourcePath);
|
|
293
304
|
|
|
294
305
|
for (const item of items) {
|
|
295
306
|
// Skip hidden files
|
|
296
307
|
if (item.startsWith('.')) continue;
|
|
297
308
|
|
|
298
|
-
const
|
|
309
|
+
const itemSourcePath = path.join(sourcePath, item);
|
|
299
310
|
const targetItemPath = path.join(targetPath, item);
|
|
300
311
|
|
|
301
312
|
try {
|
|
302
|
-
await fs.copy(
|
|
313
|
+
await fs.copy(itemSourcePath, targetItemPath);
|
|
303
314
|
copied.push(item);
|
|
304
315
|
} catch (e) {
|
|
305
316
|
errors.push({ name: item, error: e.message });
|
|
306
317
|
}
|
|
307
318
|
}
|
|
319
|
+
|
|
320
|
+
// Generate knowledge declaration file
|
|
321
|
+
if (copied.length > 0) {
|
|
322
|
+
await generateKnowledgeDeclare(targetPath);
|
|
323
|
+
}
|
|
308
324
|
} catch (e) {
|
|
309
325
|
errors.push({ name: 'knowledge', error: e.message });
|
|
310
326
|
}
|
|
@@ -312,6 +328,137 @@ export async function copyKnowledgeToProject(projectPath) {
|
|
|
312
328
|
return { copied, errors };
|
|
313
329
|
}
|
|
314
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Generate knowledge declaration file
|
|
333
|
+
* Creates _knowledge.json that maps stacks/domains to their available files
|
|
334
|
+
*/
|
|
335
|
+
async function generateKnowledgeDeclare(knowledgePath) {
|
|
336
|
+
const declaration = {
|
|
337
|
+
stacks: {},
|
|
338
|
+
domains: {},
|
|
339
|
+
generated: new Date().toISOString()
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
// Scan stacks
|
|
343
|
+
const stacksPath = path.join(knowledgePath, 'stacks');
|
|
344
|
+
if (await fs.pathExists(stacksPath)) {
|
|
345
|
+
const stacks = await fs.readdir(stacksPath);
|
|
346
|
+
|
|
347
|
+
for (const stack of stacks) {
|
|
348
|
+
if (stack.startsWith('.') || stack === '_index.md') continue;
|
|
349
|
+
|
|
350
|
+
const stackPath = path.join(stacksPath, stack);
|
|
351
|
+
const stat = await fs.stat(stackPath);
|
|
352
|
+
|
|
353
|
+
if (stat.isDirectory()) {
|
|
354
|
+
// Scan files in stack folder
|
|
355
|
+
const files = await scanKnowledgeFiles(stackPath);
|
|
356
|
+
if (files.length > 0) {
|
|
357
|
+
declaration.stacks[stack] = files;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Scan domains
|
|
364
|
+
const domainsPath = path.join(knowledgePath, 'domains');
|
|
365
|
+
if (await fs.pathExists(domainsPath)) {
|
|
366
|
+
const domains = await fs.readdir(domainsPath);
|
|
367
|
+
|
|
368
|
+
for (const domain of domains) {
|
|
369
|
+
if (domain.startsWith('.') || domain === '_index.md') continue;
|
|
370
|
+
|
|
371
|
+
const domainPath = path.join(domainsPath, domain);
|
|
372
|
+
const stat = await fs.stat(domainPath);
|
|
373
|
+
|
|
374
|
+
if (stat.isDirectory()) {
|
|
375
|
+
// Scan files in domain folder
|
|
376
|
+
const files = await scanKnowledgeFiles(domainPath);
|
|
377
|
+
if (files.length > 0) {
|
|
378
|
+
declaration.domains[domain] = files;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Write declaration file
|
|
385
|
+
const declarePath = path.join(knowledgePath, '_knowledge.json');
|
|
386
|
+
await fs.writeJson(declarePath, declaration, { spaces: 2 });
|
|
387
|
+
|
|
388
|
+
// Also create a markdown version for easy reading
|
|
389
|
+
await generateKnowledgeDeclareMd(knowledgePath, declaration);
|
|
390
|
+
|
|
391
|
+
return declaration;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Scan knowledge folder and return list of files with metadata
|
|
396
|
+
*/
|
|
397
|
+
async function scanKnowledgeFiles(folderPath) {
|
|
398
|
+
const files = [];
|
|
399
|
+
|
|
400
|
+
async function scan(dir, relativePath = '') {
|
|
401
|
+
const items = await fs.readdir(dir);
|
|
402
|
+
|
|
403
|
+
for (const item of items) {
|
|
404
|
+
if (item.startsWith('.')) continue;
|
|
405
|
+
|
|
406
|
+
const itemPath = path.join(dir, item);
|
|
407
|
+
const stat = await fs.stat(itemPath);
|
|
408
|
+
const relPath = relativePath ? `${relativePath}/${item}` : item;
|
|
409
|
+
|
|
410
|
+
if (stat.isFile() && item.endsWith('.md')) {
|
|
411
|
+
files.push({
|
|
412
|
+
path: relPath,
|
|
413
|
+
name: item,
|
|
414
|
+
size: stat.size
|
|
415
|
+
});
|
|
416
|
+
} else if (stat.isDirectory()) {
|
|
417
|
+
await scan(itemPath, relPath);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
await scan(folderPath);
|
|
423
|
+
return files;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Generate markdown version of knowledge declaration
|
|
428
|
+
*/
|
|
429
|
+
async function generateKnowledgeDeclareMd(knowledgePath, declaration) {
|
|
430
|
+
let content = '# Knowledge Base Index\n\n';
|
|
431
|
+
content += `Generated: ${new Date().toLocaleString()}\n\n`;
|
|
432
|
+
content += 'This file is auto-generated. It lists all available knowledge files in this project.\n\n';
|
|
433
|
+
|
|
434
|
+
// Stacks
|
|
435
|
+
if (Object.keys(declaration.stacks).length > 0) {
|
|
436
|
+
content += '## Stacks\n\n';
|
|
437
|
+
for (const [stack, files] of Object.entries(declaration.stacks)) {
|
|
438
|
+
content += `### ${stack}\n\n`;
|
|
439
|
+
for (const file of files) {
|
|
440
|
+
content += `- \`${file.path}\`\n`;
|
|
441
|
+
}
|
|
442
|
+
content += '\n';
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Domains
|
|
447
|
+
if (Object.keys(declaration.domains).length > 0) {
|
|
448
|
+
content += '## Domains\n\n';
|
|
449
|
+
for (const [domain, files] of Object.entries(declaration.domains)) {
|
|
450
|
+
content += `### ${domain}\n\n`;
|
|
451
|
+
for (const file of files) {
|
|
452
|
+
content += `- \`${file.path}\`\n`;
|
|
453
|
+
}
|
|
454
|
+
content += '\n';
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const declarePath = path.join(knowledgePath, '_knowledge.md');
|
|
459
|
+
await fs.writeFile(declarePath, content);
|
|
460
|
+
}
|
|
461
|
+
|
|
315
462
|
/**
|
|
316
463
|
* Copy scripts (graph.py, etc.) to project
|
|
317
464
|
*/
|