bmad-module-skill-forge 1.1.0 → 1.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +6 -4
- package/docs/_data/pinned.yaml +1 -1
- package/docs/bmad-synergy.md +2 -2
- package/docs/getting-started.md +1 -1
- package/docs/skill-model.md +26 -32
- package/docs/troubleshooting.md +13 -1
- package/docs/why-skf.md +5 -4
- package/docs/workflows.md +53 -0
- package/package.json +2 -2
- package/src/knowledge/ccc-bridge.md +1 -1
- package/src/shared/references/output-contract-schema.md +10 -0
- package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +134 -0
- package/src/shared/scripts/skf-detect-tools.py +359 -0
- package/src/shared/scripts/skf-emit-result-envelope.py +419 -0
- package/src/shared/scripts/skf-extract-public-api.py +505 -0
- package/src/shared/scripts/skf-forge-tier-rw.py +413 -0
- package/src/shared/scripts/skf-merge-ccc-exclusions.py +324 -0
- package/src/shared/scripts/skf-preflight.py +14 -4
- package/src/shared/scripts/skf-qmd-classify-collections.py +212 -0
- package/src/shared/scripts/skf-render-quick-metadata.py +192 -0
- package/src/shared/scripts/skf-resolve-package.py +264 -0
- package/src/shared/scripts/skf-validate-frontmatter.py +9 -3
- package/src/shared/scripts/skf-validate-output.py +24 -7
- package/src/skf-create-skill/steps-c/step-06-validate.md +1 -1
- package/src/skf-quick-skill/SKILL.md +178 -10
- package/src/skf-quick-skill/assets/skill-template.md +5 -1
- package/src/skf-quick-skill/references/registry-resolution.md +2 -0
- package/src/skf-quick-skill/steps-c/step-01-resolve-target.md +84 -16
- package/src/skf-quick-skill/steps-c/step-02-ecosystem-check.md +3 -3
- package/src/skf-quick-skill/steps-c/step-03-quick-extract.md +86 -43
- package/src/skf-quick-skill/steps-c/step-04-compile.md +49 -56
- package/src/skf-quick-skill/steps-c/step-05-write-and-validate.md +164 -0
- package/src/skf-quick-skill/steps-c/{step-06-write.md → step-06-finalize.md} +15 -7
- package/src/skf-quick-skill/steps-c/step-07-health-check.md +5 -3
- package/src/skf-setup/SKILL.md +25 -10
- package/src/skf-setup/references/tier-rules.md +2 -2
- package/src/skf-setup/steps-c/step-01-detect-and-tier.md +58 -71
- package/src/skf-setup/steps-c/step-01b-ccc-index.md +49 -66
- package/src/skf-setup/steps-c/step-02-write-config.md +59 -86
- package/src/skf-setup/steps-c/step-03-auto-index.md +73 -91
- package/src/skf-setup/steps-c/step-04-report.md +135 -11
- package/src/skf-setup/steps-c/step-05-health-check.md +4 -2
- package/src/skf-test-skill/steps-c/step-01-init.md +4 -4
- package/src/skf-quick-skill/steps-c/step-05-validate.md +0 -193
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: './step-05-validate.md'
|
|
2
|
+
nextStepFile: './step-05-write-and-validate.md'
|
|
3
3
|
skillTemplateData: 'assets/skill-template.md'
|
|
4
|
+
quickMetadataRendererProbeOrder:
|
|
5
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-render-quick-metadata.py'
|
|
6
|
+
- '{project-root}/src/shared/scripts/skf-render-quick-metadata.py'
|
|
4
7
|
---
|
|
5
8
|
|
|
6
9
|
# Step 4: Compile
|
|
7
10
|
|
|
11
|
+
Communicate with the user in `{communication_language}`. Compile generated content (descriptions, usage notes, summaries) in `{document_output_language}`.
|
|
12
|
+
|
|
8
13
|
## STEP GOAL:
|
|
9
14
|
|
|
10
15
|
To assemble the best-effort SKILL.md document, context-snippet.md in Vercel-aligned indexed format, and metadata.json with `source_authority: community` from the extraction inventory. Present compiled output for review before validation.
|
|
@@ -17,8 +22,6 @@ To assemble the best-effort SKILL.md document, context-snippet.md in Vercel-alig
|
|
|
17
22
|
|
|
18
23
|
## MANDATORY SEQUENCE
|
|
19
24
|
|
|
20
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
21
|
-
|
|
22
25
|
### 1. Load Skill Template
|
|
23
26
|
|
|
24
27
|
Load {skillTemplateData} to understand:
|
|
@@ -50,8 +53,8 @@ description: >
|
|
|
50
53
|
|
|
51
54
|
**Required sections (after frontmatter):**
|
|
52
55
|
- **Overview:** Package name, repository, language, source authority, generation date
|
|
53
|
-
- **Description:** From extraction_inventory.description (README-derived)
|
|
54
|
-
- **Key Exports:** From extraction_inventory.exports — list each with name, type, brief description
|
|
56
|
+
- **Description:** From `{overrides.description}` if set (subject to the same length/voice checks as extracted descriptions); otherwise from extraction_inventory.description (README-derived)
|
|
57
|
+
- **Key Exports:** From `{overrides.exports}` if set (comma-separated names parsed and trimmed; empty items skipped); otherwise from extraction_inventory.exports — list each with name, type, brief description
|
|
55
58
|
- **Usage Patterns:** From extraction_inventory.usage_patterns (README examples)
|
|
56
59
|
|
|
57
60
|
**Optional sections (include when data available):**
|
|
@@ -65,7 +68,9 @@ description: >
|
|
|
65
68
|
|
|
66
69
|
### 3. Generate Context Snippet
|
|
67
70
|
|
|
68
|
-
|
|
71
|
+
**If `{overrides.skip_snippet}` is true** — skip generation and note in the §5 preview: "context-snippet.md skipped per `--skip-snippet` override." Step-05 §2 will skip the corresponding write; step-05 §5 advisory snippet validation will report a "skipped" entry.
|
|
72
|
+
|
|
73
|
+
Otherwise, create context-snippet.md in Vercel-aligned indexed format (~80-120 tokens):
|
|
69
74
|
|
|
70
75
|
```
|
|
71
76
|
[{skill_name} v{version}]|root: skills/{skill_name}/
|
|
@@ -82,53 +87,37 @@ Create context-snippet.md in Vercel-aligned indexed format (~80-120 tokens):
|
|
|
82
87
|
|
|
83
88
|
### 4. Generate Metadata JSON
|
|
84
89
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"generation_date": "{current ISO date}",
|
|
101
|
-
"confidence_tier": "Quick",
|
|
102
|
-
"spec_version": "1.3",
|
|
103
|
-
"exports": ["{export_1}", "{export_2}"],
|
|
104
|
-
"confidence_distribution": {
|
|
105
|
-
"t1": 0,
|
|
106
|
-
"t1_low": "{number of exports found — must be integer, not string}",
|
|
107
|
-
"t2": 0,
|
|
108
|
-
"t3": 0
|
|
109
|
-
},
|
|
110
|
-
"tool_versions": {
|
|
111
|
-
"ast_grep": null,
|
|
112
|
-
"qmd": null,
|
|
113
|
-
"skf": "{skf_version}" // Resolution chain: _bmad/skf/package.json → npm require → _bmad/skf/VERSION → "unknown"
|
|
114
|
-
},
|
|
115
|
-
"stats": {
|
|
116
|
-
"exports_documented": "{number of exports found}",
|
|
117
|
-
"exports_public_api": "{number of exports found}",
|
|
118
|
-
"exports_internal": 0,
|
|
119
|
-
"exports_total": "{number of exports found}",
|
|
120
|
-
"public_api_coverage": 1.0,
|
|
121
|
-
"total_coverage": 1.0,
|
|
122
|
-
"scripts_count": 0,
|
|
123
|
-
"assets_count": 0
|
|
124
|
-
},
|
|
125
|
-
"dependencies": [],
|
|
126
|
-
"compatibility": "{semver-range or null}"
|
|
127
|
-
}
|
|
90
|
+
Run the shared renderer against the assembled state. The helper applies the constants, echoes input-derived fields, computes export counts and the ISO 8601 UTC timestamp, and emits the canonical envelope per `{skillTemplateData}` § "metadata.json Format".
|
|
91
|
+
|
|
92
|
+
**Resolve `{quickMetadataRenderer}`** from `{quickMetadataRendererProbeOrder}`; first existing path wins. If no candidate exists, fall back to in-prompt rendering using the constants + input-derived rules previously documented in this section (the helper replaces but does not eliminate those rules — they live in the helper now).
|
|
93
|
+
|
|
94
|
+
**Probe `tool_versions.skf` first** (the helper expects it as input — the filesystem walk stays here because the helper does no I/O):
|
|
95
|
+
|
|
96
|
+
1. Read `{project-root}/_bmad/skf/package.json` → take `version`
|
|
97
|
+
2. If absent, read `{project-root}/_bmad/skf/VERSION`
|
|
98
|
+
3. If absent, set to `"unknown"`
|
|
99
|
+
|
|
100
|
+
Build the input payload from the extraction inventory + step-01 resolution + the probed `tool_versions.skf` and pipe it to the renderer:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
echo '{"name":"<name>","version":"<v>","description":"<desc>","language":"<lang>","source_repo":"<url>","source_root":"<path or empty>","source_commit":"<source_ref or empty>","source_package":"<package or name>","exports":[{"name":"...","type":"..."}],"dependencies":["..."],"compatibility":"<semver-range or empty>","language_hint":<hint or null>,"scope_hint":<hint or null>,"skf_version":"<probed>"}' \
|
|
104
|
+
| python3 {quickMetadataRenderer}
|
|
128
105
|
```
|
|
129
106
|
|
|
107
|
+
The renderer emits the rendered metadata.json on stdout. Capture the output as `metadata` for the §5 preview and step-05 §2's deliverable write.
|
|
108
|
+
|
|
109
|
+
**Schema is canonical in the renderer.** When `{skillTemplateData}` adds a field, the renderer is updated to populate it (constants gain a row; input-derived fields gain a payload key). Do not hand-edit the rendered envelope here — the helper is the single source of truth for the population logic.
|
|
110
|
+
|
|
130
111
|
### 5. Present Compiled Output for Review
|
|
131
112
|
|
|
113
|
+
**If `{headless_mode}` is true** — skip the inline preview (no human reviewer reads it) and emit a one-line summary instead:
|
|
114
|
+
|
|
115
|
+
"Compiled: SKILL.md ({section_count} sections, {export_count} exports), context-snippet.md (~{snippet_token_count} tokens), metadata.json (version {version}, confidence {confidence}). Auto-approving [C]."
|
|
116
|
+
|
|
117
|
+
Then proceed directly to §6 — the GATE default action takes over.
|
|
118
|
+
|
|
119
|
+
**Otherwise (interactive mode):**
|
|
120
|
+
|
|
132
121
|
"**Compilation complete. Review before validation:**
|
|
133
122
|
|
|
134
123
|
---
|
|
@@ -154,25 +143,29 @@ Generate metadata.json following the exact structure defined in {skillTemplateDa
|
|
|
154
143
|
**Extraction confidence:** {confidence}
|
|
155
144
|
**Exports documented:** {count}
|
|
156
145
|
|
|
157
|
-
Review the output above
|
|
146
|
+
Review the output above, then choose: [C] continue to validation, [E] edit the description, [S] adjust scope and re-extract, or [Q] quit without writing."
|
|
158
147
|
|
|
159
148
|
### 6. Present MENU OPTIONS
|
|
160
149
|
|
|
161
|
-
Display: **Select:** [C] Continue to Validation
|
|
150
|
+
Display: **Select:** [C] Continue to Validation · [E] Edit description · [S] Adjust scope and re-extract · [Q] Quit without writing
|
|
162
151
|
|
|
163
152
|
#### Menu Handling Logic:
|
|
164
153
|
|
|
165
|
-
- IF C
|
|
166
|
-
- IF
|
|
154
|
+
- **IF C** — Load, read entire file, then execute {nextStepFile}.
|
|
155
|
+
- **IF E** — Ask the user for a replacement description ("New description (1–1024 chars):"). Update SKILL.md frontmatter `description` and `metadata.json.description` in the in-memory compiled output, then re-render the §5 preview and redisplay this menu. Do not re-run extraction.
|
|
156
|
+
- **IF S** — Ask the user for an adjusted `scope_hint` ("New scope (e.g. `src/server/`, `packages/core/`):") and optionally a `language_hint`. Update the extraction context with the new hints, then load `./step-03-quick-extract.md` to re-extract. The new extraction returns to §1 of this step on completion. Discards the prior compiled output.
|
|
157
|
+
- **IF Q** — HARD HALT with **exit code 6 (compile-cancelled)** per the SKILL.md exit-code map: "Compilation cancelled. No files written." Before exiting, emit the error result contract per SKILL.md "Result Contract on HARD HALT" (`phase: "compile"`, `error.code: "compile-cancelled"`, `skill_package: null`). Do not proceed to validation; do not write any artifacts.
|
|
158
|
+
- **IF Any other** — Help the user adjust the compiled output (treated as a free-form revision request), then redisplay the menu.
|
|
167
159
|
|
|
168
160
|
#### EXECUTION RULES:
|
|
169
161
|
|
|
170
162
|
- ALWAYS halt and wait for user input after presenting compiled output
|
|
171
163
|
- **GATE [default: C]** — If `{headless_mode}`: auto-proceed with [C] Continue, log: "headless: auto-approve compiled output"
|
|
172
|
-
- ONLY proceed to validation when user selects 'C'
|
|
173
|
-
-
|
|
164
|
+
- ONLY proceed to validation when the user selects 'C' (or headless auto-approve)
|
|
165
|
+
- [E] is local: re-renders the preview without re-running extraction
|
|
166
|
+
- [S] is the heavy option: it discards the compiled output and re-runs step-03 with new hints
|
|
174
167
|
|
|
175
168
|
## CRITICAL STEP COMPLETION NOTE
|
|
176
169
|
|
|
177
|
-
ONLY WHEN the user reviews the compiled output and selects 'C' will you load and read fully `{nextStepFile}` to execute validation.
|
|
170
|
+
ONLY WHEN the user reviews the compiled output and selects 'C' (or [Q] HALTs / [S] re-runs / [E] redisplays) will you load and read fully `{nextStepFile}` to execute validation.
|
|
178
171
|
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
nextStepFile: './step-06-finalize.md'
|
|
3
|
+
frontmatterValidatorProbeOrder:
|
|
4
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-validate-frontmatter.py'
|
|
5
|
+
- '{project-root}/src/shared/scripts/skf-validate-frontmatter.py'
|
|
6
|
+
outputValidatorProbeOrder:
|
|
7
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-validate-output.py'
|
|
8
|
+
- '{project-root}/src/shared/scripts/skf-validate-output.py'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Step 5: Write & Validate
|
|
12
|
+
|
|
13
|
+
Communicate with the user in `{communication_language}`. Validation reports are user-facing — render their narrative content in `{document_output_language}`.
|
|
14
|
+
|
|
15
|
+
## STEP GOAL:
|
|
16
|
+
|
|
17
|
+
To write the compiled SKILL.md, context-snippet.md, and metadata.json to the versioned skill package, then validate them on disk against the agentskills.io specification at community tier. Writing happens here (before step-06 finalization) because `skill-check` is a file-based CLI — it reads artifacts from disk — so the files must exist before validation runs. Report any gaps or issues. Validation is advisory — issues are reported but do not block the workflow.
|
|
18
|
+
|
|
19
|
+
## Rules
|
|
20
|
+
|
|
21
|
+
- Write exactly what was compiled — do not modify content during writing
|
|
22
|
+
- Validation is advisory — report issues but never block output
|
|
23
|
+
- Do not modify compiled content post-validation — report only
|
|
24
|
+
- Community-tier validation (lighter than official requirements)
|
|
25
|
+
|
|
26
|
+
## MANDATORY SEQUENCE
|
|
27
|
+
|
|
28
|
+
### 1. Create Output Directory
|
|
29
|
+
|
|
30
|
+
Resolve `{version}` from the extraction inventory's detected version, defaulting to `1.0.0` if not detected. Create the skill output directories:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
{skill_group} # {skills_output_folder}/{repo_name}/
|
|
34
|
+
{skill_package} # {skills_output_folder}/{repo_name}/{version}/{repo_name}/
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
If `{skill_package}` already exists, confirm with user before overwriting:
|
|
38
|
+
|
|
39
|
+
"**Directory `{skill_package}` already exists.** Overwrite will replace the prior compiled output; validation results, result contracts, and any manual tweaks from the previous run will not be preserved. Overwrite existing files? [Y/N]"
|
|
40
|
+
|
|
41
|
+
- **If user selects Y:** Proceed to section 2.
|
|
42
|
+
- **If user selects N:** HARD HALT with **exit code 5 (overwrite-cancelled)** per the SKILL.md exit-code map: "Overwrite cancelled. Existing skill preserved. Run [QS] with a different skill name or remove the existing directory manually." Before exiting, emit the error result contract per SKILL.md "Result Contract on HARD HALT" (`phase: "write-and-validate"`, `error.code: "overwrite-cancelled"`, `skill_package` set to the existing path that was preserved). Disk write of the `-latest.json` envelope is REQUIRED here since `{skill_package}` is known.
|
|
43
|
+
|
|
44
|
+
**GATE [default: Y]** — If `{headless_mode}` is true, auto-proceed with Y and log: "headless: overwriting existing `{skill_package}`".
|
|
45
|
+
|
|
46
|
+
### 2. Write Deliverables
|
|
47
|
+
|
|
48
|
+
Write the three compiled artifacts to the skill package so that validation in sections 3–7 has files on disk to read:
|
|
49
|
+
|
|
50
|
+
**File 1:** `{skill_package}/SKILL.md` — the compiled skill document
|
|
51
|
+
**File 2:** `{skill_package}/context-snippet.md` — the compressed context snippet. **Skip this write** if `{overrides.skip_snippet}` was set; the artifact is omitted from `outputs`.
|
|
52
|
+
**File 3:** `{skill_package}/metadata.json` — the machine-readable metadata
|
|
53
|
+
|
|
54
|
+
Confirm after each write: "Written: SKILL.md" / "Written: context-snippet.md" / "Written: metadata.json". When `--skip-snippet` is active, log "Skipped: context-snippet.md (--skip-snippet)" instead of the snippet write confirmation.
|
|
55
|
+
|
|
56
|
+
**If any write fails — HARD HALT (exit code 4, write-failure):** Before exiting, emit the error result contract per SKILL.md "Result Contract on HARD HALT" (`phase: "write-and-validate"`, `error.code: "write-failure"`, `error.details: {failed_path: <path>, error: <details>}`, `skill_package` set, `outputs` listing any files that did write successfully before the failure).
|
|
57
|
+
|
|
58
|
+
"**Write failed:** Could not write to `{file_path}`.
|
|
59
|
+
|
|
60
|
+
Error: {error details}
|
|
61
|
+
|
|
62
|
+
Check:
|
|
63
|
+
- Does the output directory exist and is it writable?
|
|
64
|
+
- Is there sufficient disk space?
|
|
65
|
+
- Are there permission issues?"
|
|
66
|
+
|
|
67
|
+
### 3. Check Tool Availability
|
|
68
|
+
|
|
69
|
+
Run: `npx skill-check -h`
|
|
70
|
+
|
|
71
|
+
- If succeeds (returns usage information): Continue to automated validation (section 4)
|
|
72
|
+
- If fails (command not found or error): Skip to manual fallback in section 4
|
|
73
|
+
|
|
74
|
+
**Important:** Use the verification command. Do not assume availability — empirical check required.
|
|
75
|
+
|
|
76
|
+
### 4. Validate SKILL.md via skill-check (if available)
|
|
77
|
+
|
|
78
|
+
**If `npx skill-check` is available**, run automated validation + security scan in one invocation against the skill package written in section 2 (security scan is enabled by default when `--no-security-scan` is omitted, so the same call covers §6 and avoids paying the npx startup cost twice):
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npx skill-check check {skill_package} --fix --format json
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This validates frontmatter, description, body limits, links, and formatting; runs the security scan; and auto-fixes deterministic issues (field ordering, slug format, required fields, trailing newlines).
|
|
85
|
+
|
|
86
|
+
**Parse JSON output** to extract:
|
|
87
|
+
- `qualityScore` — overall score (0-100)
|
|
88
|
+
- `diagnostics[]` — remaining issues after auto-fix
|
|
89
|
+
- `fixed[]` — issues automatically corrected
|
|
90
|
+
- `security[]` (when present) — security findings, recorded as advisory warnings (security issues do not block output)
|
|
91
|
+
|
|
92
|
+
Record quality score, remaining diagnostics, and security findings as validation issues.
|
|
93
|
+
|
|
94
|
+
**If skill-check is NOT available**, run the shared frontmatter validator instead of an LLM-walked checklist. Resolve `{frontmatterValidator}` from `{frontmatterValidatorProbeOrder}`; first existing path wins. If no candidate exists, log a high-severity issue ("frontmatter validator unavailable — both `npx skill-check` and `skf-validate-frontmatter.py` missing") and skip frontmatter validation.
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
python3 {frontmatterValidator} {skill_package}/SKILL.md --skill-dir-name {repo_name}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The validator emits JSON with `status` (`pass`/`fail`), `issues[]` (each with `severity`, `code`, `message`), and `frontmatter` (the parsed name/description). It checks frontmatter delimiters, name format (Unicode letters + digits + hyphens, no consecutive/trailing hyphens), name-directory match, description presence and length, and unknown fields against the agentskills.io spec — the same shape this step would otherwise hand-walk. Record each `issues[]` entry as a validation issue with its reported severity. Missing frontmatter or missing required fields are high-severity — skills without valid frontmatter will fail `npx skills add` and `npx skill-check check`.
|
|
101
|
+
|
|
102
|
+
### 5. Validate Body, Snippet, and Metadata via skf-validate-output.py
|
|
103
|
+
|
|
104
|
+
Run the shared output validator against the on-disk skill package — it performs the body-structure, snippet-format, and metadata-shape checks that this step previously walked by hand. Pass `--skip-frontmatter` since §4 has already covered frontmatter.
|
|
105
|
+
|
|
106
|
+
**Resolve `{outputValidator}`:** probe `{outputValidatorProbeOrder}` (installed first, dev fallback); first existing path wins. If neither candidate exists, log a high-severity issue ("output validator unavailable — `skf-validate-output.py` missing") and skip body/snippet/metadata validation.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
python3 {outputValidator} {skill_package} --generated-by quick-skill --skip-frontmatter
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The validator emits JSON with `result` (PASS/FAIL), `validation.skill_md.body[]`, `validation.context_snippet.issues[]`, `validation.metadata.issues[]`, and a severity-bucketed `summary`. Record each issue as a validation issue at its reported severity.
|
|
113
|
+
|
|
114
|
+
Coverage replaces these former hand-walked checklists:
|
|
115
|
+
|
|
116
|
+
- **Body structure** — Overview, Description, Key Exports, Usage sections present (medium when missing)
|
|
117
|
+
- **Context snippet** — `[{name} v{version}]|root: ...` first line, `|IMPORTANT:` second line, ~80–120-token length
|
|
118
|
+
- **Metadata** — required string fields (`name`, `version`, `source_authority`, `language`, `generation_date`), `source_repo`, `generated_by`, `confidence_tier`, and `stats` numerics (`exports_documented`, `exports_public_api`, `exports_total`, `public_api_coverage`, `total_coverage`)
|
|
119
|
+
|
|
120
|
+
### 6. Security Scan (covered by §4)
|
|
121
|
+
|
|
122
|
+
Security findings are already collected from the §4 invocation (no separate `npx` round trip needed — `skill-check check ... --fix --format json` runs the security scan by default). If skill-check was unavailable in §3, log "security scan skipped — skill-check unavailable" in validation results.
|
|
123
|
+
|
|
124
|
+
### 7. Report Validation Results
|
|
125
|
+
|
|
126
|
+
"**Validation complete:**
|
|
127
|
+
|
|
128
|
+
**SKILL.md:** {pass/issues found} (quality score: {score}/100 if skill-check was available)
|
|
129
|
+
{list any issues}
|
|
130
|
+
{list any auto-fixed issues}
|
|
131
|
+
|
|
132
|
+
**context-snippet.md:** {pass/issues found}
|
|
133
|
+
{list any issues}
|
|
134
|
+
|
|
135
|
+
**metadata.json:** {pass/issues found}
|
|
136
|
+
{list any issues}
|
|
137
|
+
|
|
138
|
+
**Security:** {pass/warn/skipped}
|
|
139
|
+
{list any security findings}
|
|
140
|
+
|
|
141
|
+
**Overall:** {pass / N issues found}
|
|
142
|
+
|
|
143
|
+
{If issues found:}
|
|
144
|
+
These issues are advisory for community-tier skills. You can proceed to finalize or go back to adjust.
|
|
145
|
+
|
|
146
|
+
**Proceeding to finalize...**"
|
|
147
|
+
|
|
148
|
+
Set `validation_result` with pass/fail status, quality score, and issues list.
|
|
149
|
+
|
|
150
|
+
### 8. Auto-Proceed to Finalize
|
|
151
|
+
|
|
152
|
+
#### Menu Handling Logic:
|
|
153
|
+
|
|
154
|
+
- After validation report, immediately load, read entire file, then execute {nextStepFile}
|
|
155
|
+
|
|
156
|
+
#### EXECUTION RULES:
|
|
157
|
+
|
|
158
|
+
- This is an auto-proceed step — validation is advisory
|
|
159
|
+
- Proceed directly to finalize step after reporting results
|
|
160
|
+
|
|
161
|
+
## CRITICAL STEP COMPLETION NOTE
|
|
162
|
+
|
|
163
|
+
ONLY WHEN deliverables have been written to `{skill_package}` and validation checks are complete and results reported will you load and read fully `{nextStepFile}` to execute finalization.
|
|
164
|
+
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
nextStepFile: './step-07-health-check.md'
|
|
3
|
+
atomicWriteProbeOrder:
|
|
4
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-atomic-write.py'
|
|
5
|
+
- '{project-root}/src/shared/scripts/skf-atomic-write.py'
|
|
3
6
|
---
|
|
4
7
|
|
|
5
8
|
# Step 6: Finalize
|
|
6
9
|
|
|
10
|
+
Communicate with the user in `{communication_language}`. Render the user-facing completion summary content in `{document_output_language}`.
|
|
11
|
+
|
|
7
12
|
## STEP GOAL:
|
|
8
13
|
|
|
9
14
|
To finalize the skill by creating the active-version pointer, displaying the completion summary, and writing the result contract. Deliverables (SKILL.md, context-snippet.md, metadata.json) were already written in step-05 so that validation could run against files on disk; this step only performs the post-write finalization.
|
|
@@ -16,21 +21,23 @@ To finalize the skill by creating the active-version pointer, displaying the com
|
|
|
16
21
|
|
|
17
22
|
## MANDATORY SEQUENCE
|
|
18
23
|
|
|
19
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
20
|
-
|
|
21
24
|
### 1. Create Active Pointer (atomic flip, Windows-safe)
|
|
22
25
|
|
|
26
|
+
**If `{overrides.no_active_pointer}` is true** — skip the helper invocation entirely. Log: "Active pointer: skipped per `--no-active-pointer` override." Do not update `{skill_group}/active`. Proceed to §2 with the active-pointer line omitted from the completion summary and the outputs payload.
|
|
27
|
+
|
|
23
28
|
`{skill_group}` and `{skill_package}` were computed in step-05 §1 from `{skills_output_folder}`, `{repo_name}`, and `{version}`; `{version}` was resolved from the extraction inventory. Reuse the same values here — do not recompute.
|
|
24
29
|
|
|
25
30
|
Create or update the `active` pointer at `{skill_group}/active` pointing to `{version}` using the shared atomic-flip helper. The helper acquires an `flock` on `{skill_group}/active.skf-lock`, refuses to replace a non-link at `{skill_group}/active` (protecting against accidental `rm -rf` of a real directory), and uses a rename-over-symlink pattern so the update is atomic from a concurrent reader's perspective. On Windows the helper automatically falls back to a directory junction (`mklink /J`) when `os.symlink` fails with `PRIVILEGE_NOT_HELD` / `ACCESS_DENIED` — junctions require no admin elevation and resolve identically for `skf-skill-inventory`'s consumers:
|
|
26
31
|
|
|
32
|
+
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins. HALT if no candidate exists — the active-pointer flip MUST go through the atomic helper.
|
|
33
|
+
|
|
27
34
|
```bash
|
|
28
|
-
python3 {
|
|
35
|
+
python3 {atomicWriteHelper} flip-link \
|
|
29
36
|
--link {skill_group}/active \
|
|
30
37
|
--target {version}
|
|
31
38
|
```
|
|
32
39
|
|
|
33
|
-
The helper returns non-zero (exit 2) if `{skill_group}/active` already exists as a real directory or file rather than a link — in that case,
|
|
40
|
+
The helper returns non-zero (helper exit 2) if `{skill_group}/active` already exists as a real directory or file rather than a link — in that case, HARD HALT the workflow with **exit code 7 (finalize-blocked)** per the SKILL.md exit-code map: "Refusing to flip `{skill_group}/active` — existing path is not a symlink or junction. Investigate manually; expected a link pointing at a version directory." Before exiting, emit the error result contract per SKILL.md "Result Contract on HARD HALT" (`phase: "finalize"`, `error.code: "finalize-blocked"`, `skill_package` set, `outputs` listing the deliverables already on disk from step-05). A common cause on Windows is a prior run that executed `ln -s` under git-bash without Developer Mode enabled, which silently wrote a full directory copy; remove that copy and retry.
|
|
34
41
|
|
|
35
42
|
**Never `rm` + `ln -s` the active pointer manually.** The bare-rm pattern has two failure modes: (1) a concurrent reader sees a missing `active` mid-flip, and (2) a bug or typo that replaces `{skill_group}/active` with a plain directory turns the next manual `rm -rf {skill_group}/active` into data loss. The helper encapsulates both guards and the Windows junction fallback.
|
|
36
43
|
|
|
@@ -45,12 +52,13 @@ Confirm: "Active pointer: {skill_group}/active -> {version} ({kind})" where `{ki
|
|
|
45
52
|
**Source:** {resolved_url}
|
|
46
53
|
**Authority:** community
|
|
47
54
|
**Confidence:** {extraction confidence}
|
|
55
|
+
{If `scope_hint` is non-empty, add:} **Scope:** {scope_hint}
|
|
48
56
|
|
|
49
57
|
**Files written:**
|
|
50
58
|
- `{skill_package}/SKILL.md`
|
|
51
|
-
- `{skill_package}/context-snippet.md`
|
|
59
|
+
- `{skill_package}/context-snippet.md` (omit this line when `--skip-snippet` was set)
|
|
52
60
|
- `{skill_package}/metadata.json`
|
|
53
|
-
- `{skill_group}/active` -> `{version}`
|
|
61
|
+
- `{skill_group}/active` -> `{version}` (omit this line when `--no-active-pointer` was set)
|
|
54
62
|
|
|
55
63
|
**Exports documented:** {count}
|
|
56
64
|
**Validation:** {pass / N issues (advisory)}
|
|
@@ -70,4 +78,4 @@ Write the result contract per `shared/references/output-contract-schema.md`: the
|
|
|
70
78
|
|
|
71
79
|
### 4. Chain to Health Check
|
|
72
80
|
|
|
73
|
-
ONLY WHEN the active pointer has been created and the completion summary and result contract have been written will you then load, read the full file, and
|
|
81
|
+
ONLY WHEN the active pointer has been created and the completion summary and result contract have been written will you then load, read the full file, and proceed to `{nextStepFile}`. The health-check step is the true terminal step — do not stop here even though the summary reads as final.
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
# `shared/health-check.md` resolves relative to the SKF module root
|
|
3
|
-
# (`_bmad/skf/` when installed, `src/` during
|
|
4
|
-
# to this step file.
|
|
3
|
+
# (`{project-root}/_bmad/skf/` when installed, `{project-root}/src/` during
|
|
4
|
+
# development), NOT relative to this step file.
|
|
5
5
|
nextStepFile: 'shared/health-check.md'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Step 7: Workflow Health Check
|
|
9
9
|
|
|
10
|
+
Communicate with the user in `{communication_language}`.
|
|
11
|
+
|
|
10
12
|
## STEP GOAL:
|
|
11
13
|
|
|
12
14
|
Chain to the shared workflow self-improvement health check at `{nextStepFile}`. This is the terminal step of quick-skill — after the shared health check completes, the workflow is fully done.
|
|
@@ -19,4 +21,4 @@ Chain to the shared workflow self-improvement health check at `{nextStepFile}`.
|
|
|
19
21
|
|
|
20
22
|
## MANDATORY SEQUENCE
|
|
21
23
|
|
|
22
|
-
Load `{nextStepFile}`, read it fully, then execute it.
|
|
24
|
+
Load `{nextStepFile}`, read it fully, then proceed to execute it.
|
package/src/skf-setup/SKILL.md
CHANGED
|
@@ -7,7 +7,7 @@ description: Initialize forge environment, detect tools, and set capability tier
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
Initializes the forge environment by detecting available tools, determining the capability tier (Quick/Forge/Forge+/Deep), writing persistent configuration, and
|
|
10
|
+
Initializes the forge environment by detecting available tools, determining the capability tier (Quick/Forge/Forge+/Deep), and writing persistent configuration to `{project-root}/_bmad/_memory/forger-sidecar/`. When `ccc` (cocoindex-code) is available, also augments `.cocoindex_code/settings.yml` with SKF exclusion patterns and creates or refreshes the project's semantic-search index. On Deep tier, reconciles the QMD collection registry; whenever ccc is available, reconciles the CCC index registry as well. The workflow is autonomous with one optional gate — orphaned QMD collection removal in step 3 (Deep tier only; default action: Keep) — which auto-resolves to the default when `{headless_mode}` is true.
|
|
11
11
|
|
|
12
12
|
## Role
|
|
13
13
|
|
|
@@ -17,7 +17,7 @@ You are a system executor performing environment resolution. Run each step in se
|
|
|
17
17
|
|
|
18
18
|
These rules apply to every step in this workflow:
|
|
19
19
|
|
|
20
|
-
-
|
|
20
|
+
- Autonomous with one optional gate (step 3 orphan-removal prompt; default: Keep) — all other steps auto-proceed with no user interaction until the final report
|
|
21
21
|
- Read each step file completely before taking any action
|
|
22
22
|
- Follow the mandatory sequence in each step exactly — do not skip, reorder, or optimize
|
|
23
23
|
- Only load one step file at a time — never preload future steps
|
|
@@ -29,9 +29,9 @@ These rules apply to every step in this workflow:
|
|
|
29
29
|
| # | Step | File | Auto-proceed |
|
|
30
30
|
|---|------|------|--------------|
|
|
31
31
|
| 1 | Detect Tools & Set Tier | steps-c/step-01-detect-and-tier.md | Yes |
|
|
32
|
-
| 1b | CCC Index | steps-c/step-01b-ccc-index.md | Yes |
|
|
32
|
+
| 1b | CCC Index (only when ccc is available) | steps-c/step-01b-ccc-index.md | Yes |
|
|
33
33
|
| 2 | Write Config | steps-c/step-02-write-config.md | Yes |
|
|
34
|
-
| 3 | QMD Hygiene | steps-c/step-03-auto-index.md | Yes |
|
|
34
|
+
| 3 | QMD + CCC Registry Hygiene | steps-c/step-03-auto-index.md | Yes |
|
|
35
35
|
| 4 | Report | steps-c/step-04-report.md | Yes |
|
|
36
36
|
| 5 | Workflow Health Check | steps-c/step-05-health-check.md | Yes |
|
|
37
37
|
|
|
@@ -39,17 +39,32 @@ These rules apply to every step in this workflow:
|
|
|
39
39
|
|
|
40
40
|
| Aspect | Detail |
|
|
41
41
|
|--------|--------|
|
|
42
|
-
| **Inputs** | (none
|
|
42
|
+
| **Inputs** | (none) |
|
|
43
|
+
| **Flags** | `--headless` / `-H` (skip prompts, auto-resolve gates to defaults); `--require-tier=<Quick\|Forge\|Forge+\|Deep>` (halt with failure if calculated tier does not satisfy the requirement) |
|
|
43
44
|
| **Gates** | One optional: orphaned QMD collection removal (step 3, Deep tier only; default: Keep) |
|
|
44
|
-
| **Outputs** | forge-tier.yaml
|
|
45
|
-
| **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true |
|
|
45
|
+
| **Outputs** | `forger-sidecar/forge-tier.yaml`, `forger-sidecar/preferences.yaml`, `{forge_data_folder}/`; when ccc is available, `.cocoindex_code/settings.yml` (exclusion patterns merged) and the project ccc index |
|
|
46
|
+
| **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true. step-04 emits a single-line `SKF_SETUP_RESULT_JSON: {…}` envelope after the human-readable banner so pipelines can parse the outcome without reading forge-tier.yaml. Schema documented in `steps-c/step-04-report.md` §4. |
|
|
47
|
+
| **Failure modes** | `--require-tier` not satisfied → step-04 prints a "REQUIRED TIER NOT MET" block, the JSON envelope sets `"require_tier_satisfied": false`, and the workflow halts before step-05. |
|
|
48
|
+
| **Exit codes** | The workflow runs as an LLM-driven sequence rather than a CLI process, so "exit code" describes the agent's terminal state for a calling pipeline that reads `SKF_SETUP_RESULT_JSON`. **0 — success** (no JSON `error` field, all writes completed, `require_tier_satisfied` is `true` or `null`). **1 — required-tier failure** (`require_tier_satisfied` is `false`; envelope still emitted with full state for diagnosis). **2 — write failure** (forge-tier.yaml or preferences.yaml could not be written; envelope `error` field names the path and reason). Pipelines should branch on the JSON `require_tier_satisfied` and `error` fields rather than process exit codes. |
|
|
46
49
|
|
|
47
50
|
## On Activation
|
|
48
51
|
|
|
49
|
-
1.
|
|
52
|
+
1. **Probe `uv` runtime.** Run `uv --version`. Every step in this workflow invokes shared Python helpers via `uv run` (PEP 723 inline metadata is what auto-resolves `pyyaml` for the helpers that need it — see `docs/getting-started.md`). If `uv` is missing, halt now with a single cohesive diagnostic rather than letting five separate steps each fail with `uv: command not found`:
|
|
53
|
+
|
|
54
|
+
"**Setup cannot proceed: `uv` is not installed.** SKF helpers depend on `uv` to auto-resolve their Python dependencies. Install it from <https://docs.astral.sh/uv/getting-started/installation/> and re-run `/skf-setup`. (See the Prerequisites section in <https://docs.astral.sh/uv/getting-started/installation/> or the SKF docs at `docs/getting-started.md` for details.)"
|
|
55
|
+
|
|
56
|
+
2. Load config from `{project-root}/_bmad/skf/config.yaml` and resolve:
|
|
50
57
|
- `project_name` (from installer-generated config.yaml, not module.yaml), `output_folder`, `user_name`, `communication_language`, `document_output_language`
|
|
51
58
|
- `skills_output_folder`, `forge_data_folder`, `sidecar_path`
|
|
52
59
|
|
|
53
|
-
|
|
60
|
+
**If the file does not exist**, halt with a single cohesive "wrong directory" diagnostic rather than failing later with a generic file-read error from a downstream step:
|
|
61
|
+
|
|
62
|
+
"**Setup cannot proceed: `{project-root}/_bmad/skf/config.yaml` was not found.** This directory does not appear to be an SKF-initialised project. From the project root, run `npx bmad-module-skill-forge install` (or `npx bmad-method install` and add SKF as a custom module — see `docs/getting-started.md`), then re-run `/skf-setup`. If you ARE in the right project but the file was deleted, restore it from version control or re-run the SKF installer."
|
|
63
|
+
|
|
64
|
+
**If the file exists but is malformed YAML**, halt and surface the parser error along with the file path so the user can fix it directly: "**Setup cannot proceed: `{project-root}/_bmad/skf/config.yaml` is not valid YAML.** Parser error: {error_message}. Open the file and repair the YAML, or restore from version control."
|
|
65
|
+
|
|
66
|
+
3. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in preferences.yaml. Default: false.
|
|
67
|
+
|
|
68
|
+
4. **Resolve `{require_tier}`**: parse `--require-tier=<value>` from the invocation arguments. Accept exactly `Quick`, `Forge`, `Forge+`, or `Deep` (case-sensitive). If absent or unparseable, leave as null (no tier requirement).
|
|
54
69
|
|
|
55
|
-
|
|
70
|
+
5. Load, read the full file, and then execute `./steps-c/step-01-detect-and-tier.md` to begin the workflow.
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
| ast-grep | `ast-grep --version` | Returns version string without error |
|
|
8
8
|
| gh | `gh --version` | Returns version string without error |
|
|
9
9
|
| qmd | `qmd status` | Returns status indicating initialized and operational |
|
|
10
|
-
| ccc | Step A: `ccc --help` Step B: `ccc doctor` | Step A: exits 0
|
|
10
|
+
| ccc | Step A: `ccc --help` Step B: `ccc doctor` | Step A: exits 0 AND help output identifies the binary as cocoindex-code. Step B: daemon healthy. See `steps-c/step-01-detect-and-tier.md` §7 for the full identity-marker procedure. |
|
|
11
11
|
|
|
12
|
-
**Important:** Use verification commands, not existence checks (`which`, `command -v`). A tool must be functional, not just present on PATH. For daemon-based tools (ccc), verify both binary
|
|
12
|
+
**Important:** Use verification commands, not existence checks (`which`, `command -v`). A tool must be functional, not just present on PATH. For daemon-based tools (ccc), verify both binary identity and daemon health — a binary with the right name but the wrong implementation is a false positive, not a tool.
|
|
13
13
|
|
|
14
14
|
## Tier Calculation
|
|
15
15
|
|