bmad-module-skill-forge 0.8.3 → 0.9.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 -4
- package/docs/bmad-synergy.md +183 -0
- package/docs/concepts.md +60 -2
- package/docs/examples.md +70 -17
- package/docs/getting-started.md +23 -1
- package/docs/how-it-works.md +143 -29
- package/docs/index.md +1 -1
- package/docs/workflows.md +45 -5
- package/package.json +1 -1
- package/src/README.md +47 -0
- package/src/agents/forger.agent.yaml +9 -0
- package/src/knowledge/agentskills-spec.md +3 -0
- package/src/knowledge/overview.md +1 -0
- package/src/knowledge/provenance-tracking.md +3 -0
- package/src/knowledge/skf-knowledge-index.csv +1 -0
- package/src/knowledge/skill-lifecycle.md +19 -7
- package/src/knowledge/version-paths.md +243 -0
- package/src/module-help.csv +2 -0
- package/src/workflows/README.md +9 -1
- package/src/workflows/analyze-source/data/skill-brief-schema.md +4 -0
- package/src/workflows/audit-skill/steps-c/step-01-init.md +10 -6
- package/src/workflows/audit-skill/steps-c/step-02-re-index.md +1 -1
- package/src/workflows/audit-skill/steps-c/step-03-structural-diff.md +1 -1
- package/src/workflows/audit-skill/steps-c/step-04-semantic-diff.md +1 -1
- package/src/workflows/audit-skill/steps-c/step-05-severity-classify.md +1 -1
- package/src/workflows/audit-skill/steps-c/step-06-report.md +1 -1
- package/src/workflows/brief-skill/data/skill-brief-schema.md +11 -0
- package/src/workflows/brief-skill/steps-c/step-01-gather-intent.md +28 -4
- package/src/workflows/brief-skill/steps-c/step-02-analyze-target.md +10 -0
- package/src/workflows/brief-skill/steps-c/step-04-confirm-brief.md +9 -0
- package/src/workflows/brief-skill/steps-c/step-05-write-brief.md +14 -1
- package/src/workflows/create-skill/data/skill-sections.md +2 -0
- package/src/workflows/create-skill/data/source-resolution-protocols.md +40 -4
- package/src/workflows/create-skill/steps-c/step-03-extract.md +1 -1
- package/src/workflows/create-skill/steps-c/step-05-compile.md +1 -0
- package/src/workflows/create-skill/steps-c/step-07-generate-artifacts.md +48 -32
- package/src/workflows/create-skill/steps-c/step-08-report.md +8 -7
- package/src/workflows/create-stack-skill/data/compose-mode-rules.md +12 -6
- package/src/workflows/create-stack-skill/steps-c/step-01-init.md +4 -1
- package/src/workflows/create-stack-skill/steps-c/step-02-detect-manifests.md +11 -5
- package/src/workflows/create-stack-skill/steps-c/step-04-parallel-extract.md +1 -1
- package/src/workflows/create-stack-skill/steps-c/step-05-detect-integrations.md +1 -1
- package/src/workflows/create-stack-skill/steps-c/step-07-generate-output.md +40 -23
- package/src/workflows/create-stack-skill/steps-c/step-08-validate.md +6 -3
- package/src/workflows/create-stack-skill/steps-c/step-09-report.md +5 -3
- package/src/workflows/drop-skill/steps-c/step-01-select.md +298 -0
- package/src/workflows/drop-skill/steps-c/step-02-execute.md +290 -0
- package/src/workflows/drop-skill/steps-c/step-03-report.md +135 -0
- package/src/workflows/drop-skill/workflow.md +63 -0
- package/src/workflows/export-skill/data/managed-section-format.md +33 -8
- package/src/workflows/export-skill/data/snippet-format.md +16 -4
- package/src/workflows/export-skill/steps-c/step-01-load-skill.md +46 -7
- package/src/workflows/export-skill/steps-c/step-02-package.md +2 -2
- package/src/workflows/export-skill/steps-c/step-03-generate-snippet.md +39 -7
- package/src/workflows/export-skill/steps-c/step-04-update-context.md +185 -13
- package/src/workflows/export-skill/steps-c/step-05-token-report.md +2 -2
- package/src/workflows/export-skill/steps-c/step-06-summary.md +26 -7
- package/src/workflows/quick-skill/steps-c/step-01-resolve-target.md +10 -0
- package/src/workflows/quick-skill/steps-c/step-03-quick-extract.md +2 -0
- package/src/workflows/quick-skill/steps-c/step-05-validate.md +1 -1
- package/src/workflows/quick-skill/steps-c/step-06-write.md +30 -14
- package/src/workflows/refine-architecture/steps-c/step-01-init.md +8 -3
- package/src/workflows/rename-skill/steps-c/step-01-select.md +281 -0
- package/src/workflows/rename-skill/steps-c/step-02-execute.md +391 -0
- package/src/workflows/rename-skill/steps-c/step-03-report.md +132 -0
- package/src/workflows/rename-skill/workflow.md +64 -0
- package/src/workflows/test-skill/steps-c/step-01-init.md +17 -11
- package/src/workflows/test-skill/steps-c/step-02-detect-mode.md +1 -1
- package/src/workflows/update-skill/data/remote-source-resolution.md +18 -4
- package/src/workflows/update-skill/steps-c/step-01-init.md +15 -8
- package/src/workflows/update-skill/steps-c/step-06-write.md +43 -13
- package/src/workflows/update-skill/steps-c/step-07-report.md +7 -5
- package/src/workflows/verify-stack/steps-c/step-01-init.md +8 -3
- package/tools/cli/lib/installer.js +1 -0
- package/tools/cli/lib/ui.js +24 -2
|
@@ -6,21 +6,35 @@ If `source_root` (from metadata.json) is a remote URL (GitHub URL or owner/repo
|
|
|
6
6
|
|
|
7
7
|
1. **Check `git` availability:** Verify `git` is functional (`git --version`). If `git` is not available, skip to the fallback warning below.
|
|
8
8
|
|
|
9
|
-
2. **
|
|
9
|
+
2. **Resolve source ref:** Read `source_ref` from the existing `metadata.json`. If the user provided a new `target_version`, resolve its tag first (using the Tag Resolution algorithm in `create-skill/data/source-resolution-protocols.md`).
|
|
10
|
+
|
|
11
|
+
3. **Ephemeral sparse clone:** Clone only the changed files from the change manifest to a system temp path. Note: at this point in the flow, `{source_root}` is known to be a remote URL (the local-path case was already handled above).
|
|
10
12
|
|
|
11
13
|
```
|
|
12
14
|
temp_path = {system_temp}/skf-ephemeral-{skill-name}-{timestamp}/
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
If `source_ref` exists and is not `HEAD`/null/`"local"`:
|
|
18
|
+
```
|
|
19
|
+
git clone --depth 1 --branch {source_ref} --single-branch --filter=blob:none --sparse {source_root} {temp_path}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
If `source_ref` is `HEAD`/null/`"local"` (or absent):
|
|
23
|
+
```
|
|
13
24
|
git clone --depth 1 --single-branch --filter=blob:none --sparse {source_root} {temp_path}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```
|
|
14
28
|
git -C {temp_path} sparse-checkout set --skip-checks {changed_files_from_manifest}
|
|
15
29
|
```
|
|
16
30
|
|
|
17
31
|
**Note:** `--skip-checks` is required because `changed_files_from_manifest` contains individual file paths (e.g., `src/core/parser.py`), not directories. Without this flag, `git sparse-checkout set` rejects non-directory entries.
|
|
18
32
|
|
|
19
|
-
|
|
33
|
+
When `source_ref` is a tag (e.g., `v0.5.0`), the clone targets that specific tag to ensure update-skill extracts from the same source version as the original create-skill run. When `source_ref` is `HEAD`, null, or `"local"`, no `--branch` flag is used — the clone targets the remote's default branch. This scopes the clone to only the files identified in step-02's change manifest, avoiding a full repository download.
|
|
20
34
|
|
|
21
|
-
|
|
35
|
+
4. **If clone succeeds:** Update the working source path to `{temp_path}` for all subsequent AST operations in this step. Proceed with the **Forge tier** extraction strategy below. Mark `ephemeral_clone_active = true` for cleanup.
|
|
22
36
|
|
|
23
|
-
|
|
37
|
+
5. **If clone fails (network error, auth failure, timeout):**
|
|
24
38
|
|
|
25
39
|
Warning message: "Ephemeral clone of `{source_root}` failed: {error}. Degrading to source reading (T1-low) for this run. For T1 (AST-verified) confidence, clone the repository locally and re-run [CS] Create Skill with the local path, then re-run this update."
|
|
26
40
|
|
|
@@ -60,25 +60,32 @@ Load the existing skill and all its provenance data, detect whether this is an i
|
|
|
60
60
|
"**Which skill would you like to update?**
|
|
61
61
|
|
|
62
62
|
Provide either:
|
|
63
|
-
- A skill name (resolves
|
|
63
|
+
- A skill name (resolves via version-aware path resolution — see [knowledge/version-paths.md](../../../knowledge/version-paths.md))
|
|
64
64
|
- A full path to the skill folder
|
|
65
65
|
- A skill name with `--from-test-report` to use the test report's gap findings instead of source drift detection
|
|
66
66
|
|
|
67
67
|
**Skill:** {user provides path or name}"
|
|
68
68
|
|
|
69
|
+
**Version-Aware Path Resolution:**
|
|
70
|
+
1. Read `{skills_output_folder}/.export-manifest.json` and look up the skill name in `exports` to get `active_version`
|
|
71
|
+
2. If found: resolve to `{skill_package}` = `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/`
|
|
72
|
+
3. If not in manifest: check for `active` symlink at `{skills_output_folder}/{skill-name}/active` — resolve to `{skill_group}/active/{skill-name}/`
|
|
73
|
+
4. If neither: fall back to flat path `{skills_output_folder}/{skill-name}/`. If SKILL.md exists at the flat path, auto-migrate per `knowledge/version-paths.md` migration rules
|
|
74
|
+
5. Store the resolved path as `{resolved_skill_package}` for all subsequent artifact loading
|
|
75
|
+
|
|
69
76
|
Resolve the path to an absolute skill folder location.
|
|
70
77
|
|
|
71
78
|
**If `--from-test-report` was provided (or user references a test report):**
|
|
72
|
-
Search for the test report at `{forge_data_folder}/{skill_name}/test-report-{skill_name}.md`. If found, set `test_report_path` in context and `update_mode: gap-driven`. If not found, warn and continue with normal source drift mode.
|
|
79
|
+
Search for the test report at `{forge_data_folder}/{skill_name}/{active_version}/test-report-{skill_name}.md` (i.e., `{forge_version}/test-report-{skill_name}.md`). If not found at the versioned path, fall back to `{forge_data_folder}/{skill_name}/test-report-{skill_name}.md`. If found, set `test_report_path` in context and `update_mode: gap-driven`. If not found at either path, warn and continue with normal source drift mode.
|
|
73
80
|
|
|
74
81
|
### 2. Validate Required Artifacts
|
|
75
82
|
|
|
76
83
|
**Check SKILL.md exists:**
|
|
77
|
-
- Load `{
|
|
78
|
-
- If missing: **ABORT** — "No SKILL.md found at `{
|
|
84
|
+
- Load `{resolved_skill_package}/SKILL.md`
|
|
85
|
+
- If missing: **ABORT** — "No SKILL.md found at `{resolved_skill_package}`. Run create-skill first."
|
|
79
86
|
|
|
80
87
|
**Check metadata.json exists:**
|
|
81
|
-
- Load `{
|
|
88
|
+
- Load `{resolved_skill_package}/metadata.json`
|
|
82
89
|
- Extract: `name`, `skill_type` (single or stack), `version`, `generation_date`, `confidence_tier`, `source_root`
|
|
83
90
|
- If missing: **ABORT** — "No metadata.json found. This skill may have been created manually. Run create-skill to generate provenance data."
|
|
84
91
|
|
|
@@ -102,13 +109,13 @@ Search for the test report at `{forge_data_folder}/{skill_name}/test-report-{ski
|
|
|
102
109
|
|
|
103
110
|
### 4. Load Provenance Map
|
|
104
111
|
|
|
105
|
-
**Load `{forge_data_folder}/{skill_name}/provenance-map.json
|
|
112
|
+
**Load `{forge_data_folder}/{skill_name}/{active_version}/provenance-map.json`** (i.e., `{forge_version}/provenance-map.json`). If not found at the versioned path, fall back to `{forge_data_folder}/{skill_name}/provenance-map.json`:
|
|
106
113
|
- Extract: export list, file mappings, extraction timestamps, confidence tiers
|
|
107
114
|
- Calculate provenance age (days since last extraction)
|
|
108
115
|
|
|
109
|
-
**If provenance map missing:**
|
|
116
|
+
**If provenance map missing at both paths:**
|
|
110
117
|
|
|
111
|
-
"**WARNING:** No provenance map found at `{
|
|
118
|
+
"**WARNING:** No provenance map found at `{forge_version}/provenance-map.json` or flat fallback.
|
|
112
119
|
|
|
113
120
|
Without a provenance map, update-skill cannot perform targeted change detection. Options:
|
|
114
121
|
|
|
@@ -49,6 +49,7 @@ Write all updated skill artifacts to disk: the merged SKILL.md, updated provenan
|
|
|
49
49
|
- Focus: file I/O operations — write and verify
|
|
50
50
|
- Limits: write only to skill output and forge data directories
|
|
51
51
|
- Dependencies: steps 02-05 must all be complete
|
|
52
|
+
- Path resolution: See `knowledge/version-paths.md` for canonical path templates (`{skill_package}`, `{skill_group}`, `{forge_version}`, `{forge_group}`)
|
|
52
53
|
|
|
53
54
|
## MANDATORY SEQUENCE
|
|
54
55
|
|
|
@@ -56,14 +57,16 @@ Write all updated skill artifacts to disk: the merged SKILL.md, updated provenan
|
|
|
56
57
|
|
|
57
58
|
### 1. Write Updated SKILL.md
|
|
58
59
|
|
|
59
|
-
Write the merged SKILL.md content to `{
|
|
60
|
+
Write the merged SKILL.md content to `{skill_package}/SKILL.md`:
|
|
60
61
|
- Overwrite the existing file with merged content
|
|
61
62
|
- Preserve file encoding (UTF-8)
|
|
62
63
|
- Verify write by reading back and confirming [MANUAL] section count matches expected
|
|
63
64
|
|
|
65
|
+
If the version changed (source version differs from the previous metadata version), write to the new `{skill_package}` (creating the version directory if needed). The previous version's directory is preserved on disk.
|
|
66
|
+
|
|
64
67
|
### 2. Write Updated metadata.json
|
|
65
68
|
|
|
66
|
-
Update `{
|
|
69
|
+
Update `{skill_package}/metadata.json`:
|
|
67
70
|
- Update `version`: if a source version was detected during re-extraction and differs from the current metadata version, use the source version; otherwise increment patch version
|
|
68
71
|
- Update `generation_date` timestamp to current ISO-8601 date
|
|
69
72
|
- Update `exports` array to reflect current export list
|
|
@@ -81,7 +84,7 @@ Update `{skills_output_folder}/{skill_name}/metadata.json`:
|
|
|
81
84
|
|
|
82
85
|
### 3. Write Updated provenance-map.json
|
|
83
86
|
|
|
84
|
-
Write to `{
|
|
87
|
+
Write to `{forge_version}/provenance-map.json`:
|
|
85
88
|
|
|
86
89
|
**For each export in the updated skill:**
|
|
87
90
|
- Update `export_name` if renamed
|
|
@@ -117,7 +120,7 @@ Write to `{forge_data_folder}/{skill_name}/provenance-map.json`:
|
|
|
117
120
|
|
|
118
121
|
### 4. Write Updated evidence-report.md
|
|
119
122
|
|
|
120
|
-
Append update operation section to `{
|
|
123
|
+
Append update operation section to `{forge_version}/evidence-report.md` (create the file with a standard header if it does not yet exist):
|
|
121
124
|
|
|
122
125
|
```markdown
|
|
123
126
|
## Update Operation — {current_date}
|
|
@@ -146,17 +149,43 @@ Append update operation section to `{forge_data_folder}/{skill_name}/evidence-re
|
|
|
146
149
|
- Provenance: {PASS/WARN/FAIL}
|
|
147
150
|
```
|
|
148
151
|
|
|
149
|
-
### 5. Write Stack Skill Reference Files (Conditional)
|
|
152
|
+
### 5. Write Stack Skill Reference Files (Conditional) and Regenerate context-snippet.md
|
|
150
153
|
|
|
151
154
|
**ONLY if skill_type == "stack":**
|
|
152
155
|
|
|
153
156
|
For each affected reference file from the merge:
|
|
154
157
|
- Write updated `references/{library}.md` files
|
|
155
158
|
- Write updated `references/integrations/{pair}.md` files
|
|
156
|
-
- Regenerate `context-snippet.md` with updated export summaries
|
|
157
159
|
- Verify [MANUAL] sections preserved in each reference file
|
|
158
160
|
|
|
159
|
-
**
|
|
161
|
+
**For all skills (both single and stack) — regenerate `context-snippet.md`:**
|
|
162
|
+
|
|
163
|
+
Per `knowledge/version-paths.md` "Writing Workflows (CS, QS, SS, US)", update-skill is a writing workflow that MUST write all deliverables to `{skill_package}`. `context-snippet.md` is one of those deliverables and goes stale whenever exports, version, or gotchas change.
|
|
164
|
+
|
|
165
|
+
Regenerate the snippet using the format from the matching template file:
|
|
166
|
+
|
|
167
|
+
- For single skills: `create-skill/data/skill-sections.md` (pipe-delimited indexed format)
|
|
168
|
+
- For stack skills: `create-stack-skill/data/stack-skill-template.md`
|
|
169
|
+
|
|
170
|
+
Use the **flat legacy form** for the `root:` path in the draft snippet: `root: skills/{skill-name}/`. The platform-specific prefix (`.claude/skills/`, `.cursor/skills/`, `.agents/skills/`) is applied later by `export-skill` step-03 when the skill is exported. Do not choose a platform prefix in update-skill — that is an export-time decision that depends on config.yaml.
|
|
171
|
+
|
|
172
|
+
Pull values for the regenerated snippet from the updated metadata.json (version, top exports), the merged SKILL.md (section anchors, inline summaries), and the evidence report (new gotchas). If gotchas cannot be derived from the updated evidence but the prior snippet has a `|gotchas:` line, carry forward the prior line with the `[CARRIED]` marker — see `export-skill/steps-c/step-03-generate-snippet.md` for the carry-forward protocol (one-cycle limit).
|
|
173
|
+
|
|
174
|
+
Write the regenerated snippet to `{skill_package}/context-snippet.md`, preserving file permissions.
|
|
175
|
+
|
|
176
|
+
**If skill_type == "stack"**, also verify that the reference file updates from the first half of this section have been applied before writing the snippet so the stack snippet reflects the newest integration list.
|
|
177
|
+
|
|
178
|
+
### 5b. Update Active Symlink (If Version Changed)
|
|
179
|
+
|
|
180
|
+
If the version was incremented or changed in section 2 (metadata.json update):
|
|
181
|
+
- Create or update the `active` symlink at `{skill_group}/active` pointing to the new `{version}`
|
|
182
|
+
- If the symlink already exists, remove it first and recreate
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
{skill_group}/active -> {version}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
If the version did not change, the existing symlink already points to the correct version -- no action needed.
|
|
160
189
|
|
|
161
190
|
### 6. Verify All Writes
|
|
162
191
|
|
|
@@ -183,11 +212,11 @@ For each file written:
|
|
|
183
212
|
External tool checks deferred from step-05 now run against the written files:
|
|
184
213
|
|
|
185
214
|
**If skill-check available:**
|
|
186
|
-
- Run: `npx skill-check check {
|
|
215
|
+
- Run: `npx skill-check check {skill_package} --fix --format json --no-security-scan`
|
|
187
216
|
- **Context sync after --fix:** If `fixed[]` is non-empty (i.e., `--fix` modified files on disk), re-read the modified SKILL.md to update the in-context copy. This prevents silent divergence between the in-context SKILL.md and the on-disk version that step-07-report will reference.
|
|
188
|
-
- If `body.max_lines` reported, prefer selective split — extract only the largest Tier 2 section(s) to `references/`, keeping Tier 1 inline (inline passive context achieves 100% task accuracy vs 79% for on-demand retrieval). Fall back to `npx skill-check split-body {
|
|
217
|
+
- If `body.max_lines` reported, prefer selective split — extract only the largest Tier 2 section(s) to `references/`, keeping Tier 1 inline (inline passive context achieves 100% task accuracy vs 79% for on-demand retrieval). Fall back to `npx skill-check split-body {skill_package} --write` if not feasible. Verify anchors resolve after split.
|
|
189
218
|
- Run: `npx skill-check diff` if original version was preserved
|
|
190
|
-
- Run: `npx skill-check check {
|
|
219
|
+
- Run: `npx skill-check check {skill_package} --format json` for security scan
|
|
191
220
|
|
|
192
221
|
Record findings in the evidence report (section 4). These are advisory — do not block on warnings.
|
|
193
222
|
|
|
@@ -216,11 +245,12 @@ ONLY WHEN all files have been written and verified will you load {nextStepFile}
|
|
|
216
245
|
|
|
217
246
|
### ✅ SUCCESS:
|
|
218
247
|
|
|
219
|
-
- SKILL.md written with all merged content and [MANUAL] sections intact
|
|
248
|
+
- SKILL.md written to {skill_package} with all merged content and [MANUAL] sections intact
|
|
220
249
|
- metadata.json updated with new version, timestamp, export counts
|
|
221
|
-
- provenance-map.json updated with current file:line references and timestamps
|
|
222
|
-
- evidence-report.md appended with update operation record
|
|
250
|
+
- provenance-map.json updated at {forge_version} with current file:line references and timestamps
|
|
251
|
+
- evidence-report.md appended at {forge_version} with update operation record
|
|
223
252
|
- Stack reference files updated if applicable
|
|
253
|
+
- Active symlink updated at {skill_group}/active -> {version} if version changed
|
|
224
254
|
- All writes verified by read-back confirmation
|
|
225
255
|
|
|
226
256
|
### ❌ SYSTEM FAILURE:
|
|
@@ -142,11 +142,13 @@ Source code matches provenance map exactly. The skill `{skill_name}` is current
|
|
|
142
142
|
|
|
143
143
|
| File | Status |
|
|
144
144
|
|------|--------|
|
|
145
|
-
| `{
|
|
146
|
-
| `{
|
|
147
|
-
| `{
|
|
148
|
-
| `{
|
|
149
|
-
| {stack reference files if applicable} | Updated |
|
|
145
|
+
| `{resolved_skill_package}/SKILL.md` | Updated |
|
|
146
|
+
| `{resolved_skill_package}/metadata.json` | Updated |
|
|
147
|
+
| `{forge_version}/provenance-map.json` | Updated |
|
|
148
|
+
| `{forge_version}/evidence-report.md` | Appended |
|
|
149
|
+
| {stack reference files if applicable} | Updated |
|
|
150
|
+
|
|
151
|
+
Where `{resolved_skill_package}` = `{skills_output_folder}/{skill_name}/{version}/{skill_name}/` and `{forge_version}` = `{forge_data_folder}/{skill_name}/{version}/` — see [knowledge/version-paths.md](../../../knowledge/version-paths.md)."
|
|
150
152
|
|
|
151
153
|
### 5. Workflow Chaining Recommendations
|
|
152
154
|
|
|
@@ -81,9 +81,14 @@ Wait for user input.
|
|
|
81
81
|
|
|
82
82
|
### 2. Scan Skills Folder
|
|
83
83
|
|
|
84
|
-
Read the `{skills_output_folder}` directory.
|
|
84
|
+
Read the `{skills_output_folder}` directory. Skills use a version-nested directory structure (see [knowledge/version-paths.md](../../../knowledge/version-paths.md)).
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
**Version-aware skill discovery:**
|
|
87
|
+
1. Read `{skills_output_folder}/.export-manifest.json` if it exists. For each skill in `exports`, use `active_version` to resolve `{skill_package}` = `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/`
|
|
88
|
+
2. For any subdirectory not covered by the manifest, check for an `active` symlink at `{skills_output_folder}/{dir_name}/active` — resolve to `{skill_group}/active/{dir_name}/`
|
|
89
|
+
3. Fall back to flat path `{skills_output_folder}/{dir_name}/` for unmigrated skills
|
|
90
|
+
|
|
91
|
+
For each resolved skill package, check for the presence of `SKILL.md` and `metadata.json`.
|
|
87
92
|
|
|
88
93
|
**For each valid skill directory, extract from metadata.json:**
|
|
89
94
|
- `name` — skill name
|
|
@@ -94,7 +99,7 @@ For each subdirectory, check for the presence of `SKILL.md` and `metadata.json`.
|
|
|
94
99
|
|
|
95
100
|
**Build a skill inventory** as an internal list of all loaded skills with the fields above.
|
|
96
101
|
|
|
97
|
-
**If a
|
|
102
|
+
**If a resolved skill package lacks SKILL.md or metadata.json:**
|
|
98
103
|
- Log: "Skipping `{dir_name}` — missing SKILL.md or metadata.json"
|
|
99
104
|
- Do not include in inventory
|
|
100
105
|
|
|
@@ -238,6 +238,7 @@ class Installer {
|
|
|
238
238
|
document_output_language: 'en',
|
|
239
239
|
skills_output_folder: config.skills_output_folder || 'skills',
|
|
240
240
|
forge_data_folder: config.forge_data_folder || 'forge-data',
|
|
241
|
+
sidecar_path: '_bmad/_memory/forger-sidecar',
|
|
241
242
|
skf_folder: config.skfFolder,
|
|
242
243
|
ides: config.ides || [],
|
|
243
244
|
};
|
package/tools/cli/lib/ui.js
CHANGED
|
@@ -15,6 +15,8 @@ const figlet = require('figlet');
|
|
|
15
15
|
const path = require('node:path');
|
|
16
16
|
const fs = require('fs-extra');
|
|
17
17
|
const yaml = require('js-yaml');
|
|
18
|
+
const { readManifest } = require('./manifest');
|
|
19
|
+
const { compareVersions } = require('./version-check');
|
|
18
20
|
|
|
19
21
|
const SKF_FOLDER = '_bmad/skf';
|
|
20
22
|
|
|
@@ -94,12 +96,32 @@ class UI {
|
|
|
94
96
|
let action = 'fresh';
|
|
95
97
|
|
|
96
98
|
if (detection.type === 'existing') {
|
|
97
|
-
|
|
99
|
+
const existingManifest = await readManifest(projectDir);
|
|
100
|
+
const installedVersion = existingManifest?.version || null;
|
|
101
|
+
const incomingVersion = require('../../../package.json').version;
|
|
102
|
+
|
|
103
|
+
let versionLabel;
|
|
104
|
+
let updateOptionLabel;
|
|
105
|
+
if (!installedVersion) {
|
|
106
|
+
versionLabel = `version unknown → v${incomingVersion}`;
|
|
107
|
+
updateOptionLabel = `Update — Install v${incomingVersion}, keep config.yaml`;
|
|
108
|
+
} else if (installedVersion === incomingVersion) {
|
|
109
|
+
versionLabel = `v${installedVersion} — already at this version`;
|
|
110
|
+
updateOptionLabel = `Update — Reinstall v${incomingVersion}, keep config.yaml`;
|
|
111
|
+
} else if (compareVersions(installedVersion, incomingVersion)) {
|
|
112
|
+
versionLabel = `v${installedVersion} → v${incomingVersion} available`;
|
|
113
|
+
updateOptionLabel = `Update — Upgrade from v${installedVersion} to v${incomingVersion}, keep config.yaml`;
|
|
114
|
+
} else {
|
|
115
|
+
versionLabel = `v${installedVersion} → v${incomingVersion}, DOWNGRADE`;
|
|
116
|
+
updateOptionLabel = `Update — Downgrade to v${incomingVersion}, keep config.yaml`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
log.warn(`Found existing installation at ${chalk.white(SKF_FOLDER + '/')} (${versionLabel})`);
|
|
98
120
|
|
|
99
121
|
const choice = await select({
|
|
100
122
|
message: 'What would you like to do?',
|
|
101
123
|
options: [
|
|
102
|
-
{ label:
|
|
124
|
+
{ label: updateOptionLabel, value: 'update' },
|
|
103
125
|
{ label: 'Fresh install — Remove everything and start over', value: 'fresh' },
|
|
104
126
|
{ label: 'Cancel', value: 'cancel' },
|
|
105
127
|
],
|