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
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
[](https://discord.gg/gk8jAdXWmj)
|
|
17
17
|
[](https://github.com/armelhbobdad/bmad-module-skill-forge/stargazers)
|
|
18
18
|
|
|
19
|
-
_Skill Forge analyzes your code repositories, documentation, and developer discourse to build verified instruction files for AI agents. Every instruction links back to a specific file
|
|
19
|
+
_Skill Forge analyzes your code repositories, documentation, and developer discourse to build verified instruction files for AI agents. Every instruction links back to its upstream — a specific `file:line` at a pinned commit when source is available, or a documentation URL when it isn't._
|
|
20
20
|
|
|
21
21
|
**If SKF fixes your agent's API guesses, give it a ⭐ — it helps others find this tool.**
|
|
22
22
|
**If it saved you an afternoon, [grab me a coffee ☕](https://buymeacoffee.com/armelhbobdad) — it helps me keep forging.**
|
|
@@ -94,7 +94,7 @@ A skeptical reader is probably already considering one of these alternatives:
|
|
|
94
94
|
|
|
95
95
|
| | **Skill Forge** | MCP doc servers | Hand-edited `.cursorrules` | awesome-\* lists |
|
|
96
96
|
| -------------------------- | ----------------------------------------- | ----------------- | -------------------------- | ---------------- |
|
|
97
|
-
| Reproducible from
|
|
97
|
+
| Reproducible from upstream | AST + pinned commit (or pinned doc URL) | varies; opaque | whatever you wrote | none |
|
|
98
98
|
| Version-pinned & immutable | yes — per-version directories | runtime-dependent | rots silently | no |
|
|
99
99
|
| Audit trail | `provenance-map.json` + test + evidence | depends on server | none | none |
|
|
100
100
|
| Runtime cost | zero (markdown + JSON) | a running process | zero | zero |
|
|
@@ -115,13 +115,15 @@ SKF extracts real function signatures, types, and patterns from code, docs, and
|
|
|
115
115
|
|
|
116
116
|
## Verifying a Skill
|
|
117
117
|
|
|
118
|
-
You can falsify any
|
|
118
|
+
You can falsify any citation in an SKF-compiled skill in under a minute:
|
|
119
119
|
|
|
120
120
|
1. **Open the skill's `provenance-map.json`** — find your symbol; read its `source_file` and `source_line`.
|
|
121
121
|
2. **Open the skill's `metadata.json`** — read `source_commit` and `source_repo`.
|
|
122
122
|
3. **Jump to the upstream repo at that commit**, open that file, find that line. The signature in `SKILL.md` should match the one you're reading.
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
For docs-only skills, the audit shape is the same — `provenance-map.json` still lists every symbol — but entries cite `[EXT:{url}]` instead of `file:line@SHA`, and step 3 becomes "open the doc URL and confirm the signature matches."
|
|
125
|
+
|
|
126
|
+
If it doesn't, that's a bug — open an issue and SKF will republish the skill with a fresh provenance map (a new commit SHA for source skills, a fresh fetch for docs-only). Falsifiability isn't a feature; it's the whole deal.
|
|
125
127
|
|
|
126
128
|
**Reference output: [oh-my-skills](https://github.com/armelhbobdad/oh-my-skills)** — four Deep-tier skills compiled by SKF (cocoindex, cognee, Storybook v10, uitripled), each shipping its full audit trail in-repo. Scores range from 99.0% to 99.49%. Every claim walks to an upstream line in under 60 seconds. Serves as both the worked example for this section and ongoing proof that the pipeline does what it says.
|
|
127
129
|
|
package/docs/_data/pinned.yaml
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
# Enforced two ways: (1) release.yaml bumps this line in the same commit
|
|
27
27
|
# as package.json + marketplace.json on every release; (2) validate-docs-drift.js
|
|
28
28
|
# cross-checks this value against package.json.version and fails on mismatch.
|
|
29
|
-
skf_version: "1.
|
|
29
|
+
skf_version: "1.3.0"
|
|
30
30
|
|
|
31
31
|
# Path to the oh-my-skills repo, resolved relative to this repo's root.
|
|
32
32
|
# Override at runtime with the OMS environment variable if oh-my-skills
|
package/docs/bmad-synergy.md
CHANGED
|
@@ -9,7 +9,7 @@ This page builds on BMAD concepts (BMM phases, TEA, modules). New to BMAD? Start
|
|
|
9
9
|
|
|
10
10
|
## Launcher Skills vs Content Skills
|
|
11
11
|
|
|
12
|
-
A BMAD project that also uses SKF ends up with two different kinds of `SKILL.md` files living in the same IDE skills directory. SKF supports
|
|
12
|
+
A BMAD project that also uses SKF ends up with two different kinds of `SKILL.md` files living in the same IDE skills directory. SKF supports 24 IDEs — Claude Code (`.claude/skills/`), Cursor (`.cursor/skills/`), GitHub Copilot (`.github/skills/`), Windsurf (`.windsurf/skills/`), Cline (`.cline/skills/`), Roo Code (`.roo/skills/`), Gemini CLI (`.gemini/skills/`), and 17 others — each with its own skill directory. See the [complete IDE → Context File mapping](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-export-skill/assets/managed-section-format.md) for the full list. They look similar. They are not the same thing. This is the single most durable point of confusion, so get it straight up front.
|
|
13
13
|
|
|
14
14
|
| | BMAD launcher skill | SKF content skill |
|
|
15
15
|
|---|---|---|
|
|
@@ -166,7 +166,7 @@ Beyond briefing, CIS and SKF don't overlap — CIS covers ideation, storytelling
|
|
|
166
166
|
|
|
167
167
|
## Delivery and Lifecycle in a BMAD Project
|
|
168
168
|
|
|
169
|
-
`@Ferris EX` is the **only workflow that introduces new skill context** into the three context files that serve all
|
|
169
|
+
`@Ferris EX` is the **only workflow that introduces new skill context** into the three context files that serve all 24 IDEs: `CLAUDE.md` (Claude Code), `.cursorrules` (Cursor), and `AGENTS.md` (the remaining 22 IDEs — GitHub Copilot, Windsurf, Cline, Roo Code, Gemini CLI, and others). Each IDE also has its own skill root directory where skill files are installed (e.g., `.windsurf/skills/`, `.roo/skills/`, `.gemini/skills/`). Create-skill and update-skill produce draft artifacts that never touch those files directly — nothing reaches an agent's passive context until it has been through the EX gate. See [Skill Model → Dual-Output Strategy](../skill-model/#dual-output-strategy) for the architectural rationale.
|
|
170
170
|
|
|
171
171
|
This matters specifically in a BMAD project: you may have multiple BMAD modules, each with its own launcher skills, plus SKF content skills, all trying to contribute context. The write-guard means only verified, tested SKF skills ever reach an agent's passive context — nothing half-baked sneaks in. `@Ferris EX` injects managed sections that coexist cleanly with whatever BMAD's installer wrote in the same files.
|
|
172
172
|
|
package/docs/getting-started.md
CHANGED
|
@@ -135,7 +135,7 @@ Analyzes your project's dependencies and generates a consolidated stack skill wi
|
|
|
135
135
|
|
|
136
136
|
## Common use cases
|
|
137
137
|
|
|
138
|
-
> **Looking for end-to-end examples?** See [Examples](../examples/) for
|
|
138
|
+
> **Looking for end-to-end examples?** See [Examples](../examples/) for thirteen real-world scenarios with full command transcripts — from Quick Skill under a minute, to brownfield onboarding, stack verification, release-prep drift remediation, and SaaS docs-only skills.
|
|
139
139
|
|
|
140
140
|
---
|
|
141
141
|
|
package/docs/skill-model.md
CHANGED
|
@@ -25,51 +25,45 @@ Setup detects your installed tools and sets your tier automatically:
|
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
```
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
═══════════════════════════════════════
|
|
29
|
+
FORGE STATUS
|
|
30
|
+
═══════════════════════════════════════
|
|
31
31
|
|
|
32
32
|
Tier: Deep
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
with cross-repository synthesis. Maximum provenance and intelligence.
|
|
33
|
+
Deep tier active. Full capability unlocked — AST-backed code analysis,
|
|
34
|
+
GitHub repository exploration, and QMD knowledge search with
|
|
35
|
+
cross-repository synthesis. Maximum provenance and intelligence.
|
|
37
36
|
|
|
38
37
|
Tools Detected:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
- ast-grep 0.42.0
|
|
39
|
+
- gh 2.91.0 (2026-04-22)
|
|
40
|
+
- qmd 2.0.1
|
|
41
|
+
- ccc (daemon healthy)
|
|
43
42
|
|
|
44
43
|
QMD Registry:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
(empty — collections are created automatically when you run [CS] Create Skill)
|
|
44
|
+
0 collection(s) healthy
|
|
45
|
+
23 orphaned collection(s) kept
|
|
48
46
|
|
|
49
47
|
CCC Index:
|
|
50
|
-
|
|
51
|
-
SKF infrastructure excluded: _bmad, _bmad-output, .claude,
|
|
52
|
-
_skf-learn, skills, forge-data
|
|
53
|
-
|
|
54
|
-
┌────────────────────────────────┐
|
|
55
|
-
│ Forge ready. Deep tier active. │
|
|
56
|
-
└────────────────────────────────┘
|
|
57
|
-
|
|
58
|
-
Health Check: Clean run. No workflow issues to report.
|
|
48
|
+
indexed this run — semantic discovery ready (1 file)
|
|
59
49
|
|
|
60
|
-
|
|
50
|
+
Files written this run:
|
|
51
|
+
- forge-tier.yaml — {project-root}/_bmad/_memory/forger-sidecar/forge-tier.yaml
|
|
52
|
+
- .cocoindex_code/settings.yml — {project-root}/.cocoindex_code/settings.yml (6 SKF exclusion patterns merged)
|
|
53
|
+
- .cocoindex_code/ ccc index — 1 file indexed
|
|
61
54
|
|
|
62
|
-
|
|
63
|
-
Forge
|
|
55
|
+
═══════════════════════════════════════
|
|
56
|
+
Forge ready. Deep tier active.
|
|
57
|
+
═══════════════════════════════════════
|
|
64
58
|
|
|
65
|
-
|
|
59
|
+
Next: try [BS] Brief Skill to scope your first compilation target,
|
|
60
|
+
or [QS] Quick Skill for a fast template-driven path.
|
|
61
|
+
Already have a skill? [AS] Audit Skill drift-checks an existing skill
|
|
62
|
+
against current sources.
|
|
66
63
|
|
|
67
|
-
|
|
68
|
-
- BS → CS — brief, then compile a skill from source
|
|
69
|
-
- AN — analyze a large repo to discover what's worth skilling
|
|
70
|
-
- WS — show current lifecycle status
|
|
64
|
+
Health Check: Clean run. No workflow issues to report.
|
|
71
65
|
|
|
72
|
-
|
|
66
|
+
Workflow complete.
|
|
73
67
|
```
|
|
74
68
|
|
|
75
69
|
Don't have ast-grep, cocoindex-code, or QMD yet? No problem — Quick mode works with no additional tools. Optional GitHub CLI improves source access. Install tools later; your tier upgrades automatically.
|
package/docs/troubleshooting.md
CHANGED
|
@@ -9,11 +9,23 @@ If something isn't working, start here. For general setup help see [Getting Star
|
|
|
9
9
|
|
|
10
10
|
## Common errors
|
|
11
11
|
|
|
12
|
+
### "Setup cannot proceed: `uv` is not installed"
|
|
13
|
+
|
|
14
|
+
Surfaced by `/skf-setup` On Activation when `uv --version` is missing on `$PATH`. SKF helpers depend on `uv` to auto-resolve their Python dependencies via PEP 723 inline metadata; bare `python3` ignores that metadata and would fail later with `ModuleNotFoundError: No module named 'yaml'`. The probe halts the workflow up-front with one cohesive diagnostic instead of letting five steps each fail individually.
|
|
15
|
+
|
|
16
|
+
**Fix:** install `uv` from <https://docs.astral.sh/uv/getting-started/installation/> and re-run `/skf-setup`. `uv` is documented as a runtime prerequisite in [Getting Started → Prerequisites](../getting-started/#prerequisites-full-reference).
|
|
17
|
+
|
|
18
|
+
### "Setup cannot proceed: `_bmad/skf/config.yaml` was not found"
|
|
19
|
+
|
|
20
|
+
Surfaced by `/skf-setup` On Activation when the SKF install config is missing — typically because you invoked `/skf-setup` from a directory that is not an SKF-initialised project. The check runs before any file mutation so nothing is written.
|
|
21
|
+
|
|
22
|
+
**Fix:** from the project root, run `npx bmad-module-skill-forge install` (or `npx bmad-method install` and add SKF as a custom module — see [Getting Started → Install](../getting-started/#install)), 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. A separate "config.yaml is not valid YAML" diagnostic surfaces the parser error inline if the file exists but is malformed — open the file at the named path and repair the YAML.
|
|
23
|
+
|
|
12
24
|
### Forge reports ast-grep is unavailable
|
|
13
25
|
|
|
14
26
|
If setup reports that ast-grep was not detected, install it to unlock the Forge tier: <https://ast-grep.github.io>. Re-run `@Ferris SF` afterward — your tier upgrades automatically.
|
|
15
27
|
|
|
16
|
-
### "No brief found"
|
|
28
|
+
### "No skill brief found"
|
|
17
29
|
|
|
18
30
|
Run `@Ferris BS` first to create a skill brief, or use `@Ferris QS` for brief-less generation. `CS` requires either a brief or a direct invocation with scope arguments.
|
|
19
31
|
|
package/docs/why-skf.md
CHANGED
|
@@ -3,7 +3,7 @@ title: Why Skill Forge?
|
|
|
3
3
|
description: The strategic case for SKF — the problem it solves, how it compares to alternatives, who it's for, and who it isn't.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Skill Forge is the only AI-skills toolchain where every claim your agent reads
|
|
6
|
+
Skill Forge is the only AI-skills toolchain where every claim your agent reads points back to a real upstream location — a `file:line` at a pinned commit when source is available, or a documentation URL when it isn't. Not "sourced from training data." Not "retrieved from context." **Cited.** You can open the upstream repo (or the doc page) and see the function exists — in under a minute. That's the wedge. This page explains why it matters, how SKF compares to alternatives, and who it's for.
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -26,7 +26,7 @@ SKF treats this as a citation problem, not a model problem. If a skill claims `c
|
|
|
26
26
|
| RAG / context stuffing | Retrieves relevant code snippets | Returns fragments without synthesis — no coherent skill output |
|
|
27
27
|
| Manual authoring | High initial accuracy | Drifts as the source code changes, doesn't scale across dependencies |
|
|
28
28
|
| IDE built-in context (Copilot, Cursor) | Convenient, zero setup | Uses generic training data, not your project's specific integration patterns |
|
|
29
|
-
| **Skill Forge** | **Every instruction cites upstream `file:line`
|
|
29
|
+
| **Skill Forge** | **Every instruction cites upstream — `file:line@SHA` for source skills, doc URL for docs-only skills. Falsifiable in 60 seconds.** | **Coverage depends on which tools you've installed (Quick / Forge / Forge+ / Deep tiers).** |
|
|
30
30
|
|
|
31
31
|
</div>
|
|
32
32
|
|
|
@@ -40,6 +40,8 @@ Pick any symbol in any SKF-compiled skill. Three clicks:
|
|
|
40
40
|
2. Open the skill's `provenance-map.json` — find your symbol; it lists the file and line.
|
|
41
41
|
3. Visit the upstream repo at that commit and that line. The signature in the skill should match.
|
|
42
42
|
|
|
43
|
+
For docs-only skills, the audit shape is the same — `provenance-map.json` still lists every symbol — but entries cite `[EXT:{url}]` instead of `file:line@SHA`, and step 3 becomes "open the doc URL and confirm the signature matches."
|
|
44
|
+
|
|
43
45
|
If it doesn't, **that's a bug.** [Open an issue](https://github.com/armelhbobdad/bmad-module-skill-forge/issues/new/choose) and SKF republishes the skill with a new commit SHA and a new provenance map. No other AI-skills tool treats disagreement between claim and source as a defect. SKF does.
|
|
44
46
|
|
|
45
47
|
See the [Verifying a Skill](../verifying-a-skill/) page for the full three-step audit on real skills, the test reports that log *exactly* where coverage falls short, and the scoring formula behind the 80% pass threshold.
|
|
@@ -78,9 +80,8 @@ You're considering running SKF across a brownfield platform. You need to know ab
|
|
|
78
80
|
## Not for you if…
|
|
79
81
|
|
|
80
82
|
- You want docs that hand-hold through every happy path with screenshots and emojis. SKF is a citation machine, not a tutorial series.
|
|
81
|
-
- You need perfect coverage of every private implementation detail. SKF extracts public APIs; if you want internals, read the code directly.
|
|
82
83
|
- You don't have Node.js ≥ 22 and Python ≥ 3.10 installed. SKF is a Node/Python toolchain at its core.
|
|
83
|
-
- You
|
|
84
|
+
- You have neither source code nor published documentation for the target. SKF compiles from one or both — a source repo (citations as `file:line@SHA`) or doc URLs (citations as `[EXT:{url}]`). A vague description with no upstream artifact to cite isn't enough.
|
|
84
85
|
|
|
85
86
|
Everything else is downstream of one question: *are the instructions your AI reads provably true?* If yes, SKF isn't adding value. If you can't be sure, SKF is the tool.
|
|
86
87
|
|
package/docs/workflows.md
CHANGED
|
@@ -21,6 +21,11 @@ Trigger workflows by typing commands to [Ferris](../agents/). See [Concepts](../
|
|
|
21
21
|
|
|
22
22
|
**Key Steps:** Detect tools + Determine tier → CCC index check (Forge+) → Write forge-tier.yaml → QMD + CCC registry hygiene (Deep/Forge+) → Status report
|
|
23
23
|
|
|
24
|
+
**Flags:**
|
|
25
|
+
|
|
26
|
+
- `--require-tier=<Quick|Forge|Forge+|Deep>` — fail-fast for CI: if the calculated tier does not satisfy the requested tier (tool-prerequisite check, not a name comparison — Deep does NOT subsume Forge+ because Deep does not require ccc), the workflow halts with a "REQUIRED TIER NOT MET" block and exits without chaining to the health check. Pipelines branch on the JSON envelope's `require_tier_satisfied` field.
|
|
27
|
+
- `--headless` / `-H` — see [Headless Mode](#headless-mode) below. For `/skf-setup` specifically, headless mode emits a single-line `SKF_SETUP_RESULT_JSON: {…}` envelope to stdout (schema-locked, includes `tier`, `previous_tier`, `tier_changed`, `tools`, `tools_added`/`removed`, `files_written`, `warnings`, `error`) and SUPPRESSES the human-readable banner — the entire payload pipelines need is on one parseable line.
|
|
28
|
+
|
|
24
29
|
**Agent:** Ferris (Architect mode)
|
|
25
30
|
|
|
26
31
|
---
|
|
@@ -79,6 +84,19 @@ Trigger workflows by typing commands to [Ferris](../agents/). See [Concepts](../
|
|
|
79
84
|
|
|
80
85
|
**Key Steps:** Resolve target → Ecosystem check → Quick extract → Compile → Validate → Write
|
|
81
86
|
|
|
87
|
+
**Headless / batch flags:**
|
|
88
|
+
|
|
89
|
+
- `--headless` / `-H` — auto-proceed all confirmation gates with documented defaults; emits structured stderr progress events and exit codes (see [Headless Mode](#headless-mode))
|
|
90
|
+
- `--batch <file>` — process N targets from a text file in sequence (one target per line, `#` comments and `language=<lang>` / `scope=<path>` per-line modifiers supported); implies `--headless`
|
|
91
|
+
- `--fail-fast` — only with `--batch`; abort the whole batch on the first per-target failure instead of recording it and proceeding
|
|
92
|
+
|
|
93
|
+
**Per-target overrides** (apply to a single-target run, or globally to every target in `--batch`):
|
|
94
|
+
|
|
95
|
+
- `--description "<string>"` — override the LLM-derived description used in `SKILL.md` frontmatter and `metadata.json`
|
|
96
|
+
- `--exports "name1,name2,..."` — override the extracted export list (comma-separated)
|
|
97
|
+
- `--skip-snippet` — skip `context-snippet.md` generation and write
|
|
98
|
+
- `--no-active-pointer` — skip the active-pointer flip in finalize (deliverables still land in `{skill_package}`)
|
|
99
|
+
|
|
82
100
|
**Agent:** Ferris (Architect mode)
|
|
83
101
|
|
|
84
102
|
---
|
|
@@ -337,6 +355,41 @@ Add `--headless` or `-H` to any workflow command to skip all confirmation gates.
|
|
|
337
355
|
|
|
338
356
|
You can also set `headless_mode: true` in your forge preferences (`_bmad/_memory/forger-sidecar/preferences.yaml`) to make headless the default for all workflows.
|
|
339
357
|
|
|
358
|
+
**Exception — `/skf-setup` headless emits a single-line JSON envelope.** Unlike other workflows, headless `/skf-setup` SUPPRESSES the human-readable status banner entirely and emits exactly one prefixed line on stdout:
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
SKF_SETUP_RESULT_JSON: {"skf_setup":{"tier":"Deep","previous_tier":"Forge","tier_changed":true,"tools":{...},"tools_added":[...],"tools_removed":[],"config_path":"...","ccc_index":{...},"files_written":[...],"tier_override_active":false,"tier_override_invalid":false,"require_tier_satisfied":null,"warnings":[],"error":null}}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Parent skills and CI pipelines `grep` one line out of the workflow log to learn the outcome — no ASCII-art parsing, no race against the [`forge-tier.yaml`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-setup/steps-c/step-02-write-config.md) writer. The envelope schema is versioned at [`src/shared/scripts/schemas/skf-setup-result-envelope.v1.json`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json) and asserted against on every emit.
|
|
365
|
+
|
|
366
|
+
**Exception — `/skf-quick-skill` headless emits structured progress + result envelopes.** Headless `/skf-quick-skill` runs are first-class building blocks for batch automators. Three operational contracts beyond per-gate auto-proceed:
|
|
367
|
+
|
|
368
|
+
1. **Per-step JSON progress events to `stderr`** at each step's entry / exit / HARD HALT — one line per event, no pretty-print:
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
{"step":3,"name":"quick-extract","status":"start"}
|
|
372
|
+
{"step":3,"name":"quick-extract","status":"done"}
|
|
373
|
+
{"step":1,"name":"resolve-target","status":"halt","exit":3}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
`<name>` is the kebab portion of the step filename: `resolve-target`, `ecosystem-check`, `quick-extract`, `compile`, `write-and-validate`, `finalize`, `health-check`.
|
|
377
|
+
|
|
378
|
+
2. **Structured exit-code map.** Every HARD HALT exits with a stable code so pipelines branch on the failure class without grepping message text:
|
|
379
|
+
|
|
380
|
+
| Code | Meaning |
|
|
381
|
+
| ---- | ------------------- |
|
|
382
|
+
| 0 | success |
|
|
383
|
+
| 3 | resolution-failure |
|
|
384
|
+
| 4 | write-failure |
|
|
385
|
+
| 5 | overwrite-cancelled |
|
|
386
|
+
| 6 | compile-cancelled |
|
|
387
|
+
| 7 | finalize-blocked |
|
|
388
|
+
|
|
389
|
+
3. **Error-variant result contract on every HARD HALT.** A `SKF_QUICK_SKILL_RESULT_JSON: {…}` envelope is emitted on `stderr` (always) and copied to `{skill_package}/quick-skill-result-latest.json` when the skill package is known (HALTs at step-05 §1 onward). The schema and full population rules live in [`src/skf-quick-skill/SKILL.md`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-quick-skill/SKILL.md) § "Result Contract on HARD HALT".
|
|
390
|
+
|
|
391
|
+
**Batch mode (`--batch <file>`).** Drives N targets through the full pipeline (steps 1–7 each) in sequence. Input format: one target per line, `#` comments and blank lines ignored, optional per-line modifiers `language=<lang>` and `scope=<path>`. Per-target output lands in `{skill_package}/` as today; an aggregated summary writes to `{skills_output_folder}/_batch/quick-skill-batch-{ts}.json` (with `quick-skill-batch-latest.json` copy). Per-target boundary events (`{"batch":N,"target":"…","status":"start|done|fail",…}`) and a final `{"batch_summary":true,…}` event extend the per-step event stream above. Full input grammar, summary schema, and exit-code semantics in [`src/skf-quick-skill/SKILL.md`](https://github.com/armelhbobdad/bmad-module-skill-forge/blob/main/src/skf-quick-skill/SKILL.md) § "Batch Mode".
|
|
392
|
+
|
|
340
393
|
---
|
|
341
394
|
|
|
342
395
|
## Terminal Step: Health Check
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "bmad-module-skill-forge",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"description": "BMAD module — Turn code and docs into instructions AI agents can actually follow. Progressive capability tiers (Quick/Forge/Forge+/Deep).",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"bmad",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"test:cli": "node test/test-cli-integration.js",
|
|
54
54
|
"test:install": "node test/test-installation-components.js",
|
|
55
55
|
"test:knowledge": "node test/test-knowledge-base.js",
|
|
56
|
-
"test:python": "uv run --with pytest --with pyyaml pytest test/test-compute-score-contract.py test/test-skf-preflight.py test/test-skf-skill-inventory.py test/test-skf-validate-output.py test/test-skf-validate-frontmatter.py test/test-skf-manifest-ops.py test/test-skf-rebuild-managed-sections.py test/test-skf-severity-classify.py test/test-skf-structural-diff.py -v",
|
|
56
|
+
"test:python": "uv run --with pytest --with pyyaml pytest test/test-compute-score-contract.py test/test-skf-preflight.py test/test-skf-skill-inventory.py test/test-skf-validate-output.py test/test-skf-validate-frontmatter.py test/test-skf-manifest-ops.py test/test-skf-rebuild-managed-sections.py test/test-skf-severity-classify.py test/test-skf-structural-diff.py test/test-skf-detect-tools.py test/test-skf-forge-tier-rw.py test/test-skf-emit-result-envelope.py test/test-skf-qmd-classify-collections.py test/test-skf-merge-ccc-exclusions.py test/test-skf-resolve-package.py test/test-skf-extract-public-api.py test/test-skf-render-quick-metadata.py -v",
|
|
57
57
|
"test:schemas": "node test/test-agent-schema.js",
|
|
58
58
|
"test:workflow": "node test/test-workflow-state.js",
|
|
59
59
|
"validate:refs": "node tools/validate-file-refs.js --strict",
|
|
@@ -48,7 +48,7 @@ Returns: list of `{file, score, snippet}` entries ranked by semantic relevance t
|
|
|
48
48
|
### `ccc_bridge.status()`
|
|
49
49
|
|
|
50
50
|
**Resolves to:** Two-step verification:
|
|
51
|
-
1. `ccc --help` — confirms binary exists (exit 0)
|
|
51
|
+
1. `ccc --help` — confirms binary exists (exit 0) AND output contains the `CocoIndex Code` identity marker (rejects unrelated `ccc`-named binaries shadowing PATH)
|
|
52
52
|
2. `ccc doctor` — confirms daemon is running, extracts version string, validates embedding model
|
|
53
53
|
|
|
54
54
|
**Usage context:** Called exclusively by setup step-01 during tool detection. Downstream workflows read the result from forge-tier.yaml — they do not re-verify.
|
|
@@ -33,3 +33,13 @@ Each run writes **two files** to `{output_dir}`:
|
|
|
33
33
|
Write the per-run record first, then copy it to the `-latest.json` path. If the copy fails, the per-run record still exists — the run is not lost.
|
|
34
34
|
|
|
35
35
|
**Consumers (forger, CI, chained workflows):** read from `{skill-name}-result-latest.json`. Do not enumerate timestamped files unless inspecting prior-run history.
|
|
36
|
+
|
|
37
|
+
## Available Helpers
|
|
38
|
+
|
|
39
|
+
There is no generic helper that writes the schema above; each skill assembles the JSON in its terminal step today. One specialised helper exists:
|
|
40
|
+
|
|
41
|
+
- **`src/shared/scripts/skf-emit-result-envelope.py`** — `skf-setup`-specific. Writes a different envelope (`SKF_SETUP_RESULT_JSON: {…}`) following the JSON schema at `src/shared/scripts/schemas/skf-setup-result-envelope.v1.json`. Carries setup-specific fields (`tier`, `previous_tier`, `tools`, `ccc_index`, `tier_override_*`, `qmd_status`, etc.) that have no analogue in other workflows. **Do not reuse for non-skf-setup skills.**
|
|
42
|
+
|
|
43
|
+
A generalised emitter (matching this document's schema) is a reasonable future helper when a second consumer materialises with the same shape. For now, skills that write this contract assemble the JSON in their terminal step — the work is small (5–8 fields) and skill-specific summary content benefits from being expressed inline alongside the rest of the step's logic.
|
|
44
|
+
|
|
45
|
+
skf-quick-skill writes both the success-variant contract (`step-06-finalize.md` §3) and the error-variant contract on every HARD HALT (per `SKILL.md` § "Result Contract on HARD HALT") in this hand-assembled style.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/armelhbobdad/bmad-module-skill-forge/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json",
|
|
4
|
+
"title": "SKF_SETUP_RESULT_JSON envelope (v1)",
|
|
5
|
+
"description": "Single-line JSON document emitted by skf-setup step-04 §4 when {headless_mode} is true, prefixed with the literal 'SKF_SETUP_RESULT_JSON: '. Pipelines grep one line out of the workflow log without parsing ASCII-art and without racing the forge-tier.yaml writer. Schema added in PR #247, extended in PR #248 (header / outputs / failure modes), extended again in this PR with previous_tier / tier_changed / tools_added / tools_removed / error.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["skf_setup"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"skf_setup": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"additionalProperties": false,
|
|
13
|
+
"required": [
|
|
14
|
+
"tier",
|
|
15
|
+
"previous_tier",
|
|
16
|
+
"tier_changed",
|
|
17
|
+
"tools",
|
|
18
|
+
"tools_added",
|
|
19
|
+
"tools_removed",
|
|
20
|
+
"config_path",
|
|
21
|
+
"ccc_index",
|
|
22
|
+
"files_written",
|
|
23
|
+
"tier_override_active",
|
|
24
|
+
"tier_override_invalid",
|
|
25
|
+
"require_tier_satisfied",
|
|
26
|
+
"warnings",
|
|
27
|
+
"error"
|
|
28
|
+
],
|
|
29
|
+
"properties": {
|
|
30
|
+
"tier": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"enum": ["Quick", "Forge", "Forge+", "Deep"],
|
|
33
|
+
"description": "Active capability tier this run."
|
|
34
|
+
},
|
|
35
|
+
"previous_tier": {
|
|
36
|
+
"type": ["string", "null"],
|
|
37
|
+
"enum": ["Quick", "Forge", "Forge+", "Deep", null],
|
|
38
|
+
"description": "Tier read from the existing forge-tier.yaml at workflow start. Null on first runs."
|
|
39
|
+
},
|
|
40
|
+
"tier_changed": {
|
|
41
|
+
"type": "boolean",
|
|
42
|
+
"description": "True when previous_tier is non-null AND differs from tier. False on first runs and same-tier re-runs. Lets pipelines react to upgrades without re-reading forge-tier.yaml."
|
|
43
|
+
},
|
|
44
|
+
"tools": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"additionalProperties": false,
|
|
47
|
+
"required": ["ast_grep", "gh_cli", "qmd", "ccc"],
|
|
48
|
+
"properties": {
|
|
49
|
+
"ast_grep": { "type": "boolean" },
|
|
50
|
+
"gh_cli": { "type": "boolean" },
|
|
51
|
+
"qmd": { "type": "boolean" },
|
|
52
|
+
"ccc": { "type": "boolean" }
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"tools_added": {
|
|
56
|
+
"type": "array",
|
|
57
|
+
"items": { "type": "string", "enum": ["ast_grep", "gh_cli", "qmd", "ccc"] },
|
|
58
|
+
"uniqueItems": true,
|
|
59
|
+
"description": "Tool keys with available=true that were NOT available in previous_tools. On first runs, equals the currently-detected tools."
|
|
60
|
+
},
|
|
61
|
+
"tools_removed": {
|
|
62
|
+
"type": "array",
|
|
63
|
+
"items": { "type": "string", "enum": ["ast_grep", "gh_cli", "qmd", "ccc"] },
|
|
64
|
+
"uniqueItems": true,
|
|
65
|
+
"description": "Tool keys that were available in previous_tools but are NOT available now."
|
|
66
|
+
},
|
|
67
|
+
"config_path": {
|
|
68
|
+
"type": "string",
|
|
69
|
+
"minLength": 1,
|
|
70
|
+
"description": "Absolute path to the forge-tier.yaml that this run wrote (or attempted to write — see error)."
|
|
71
|
+
},
|
|
72
|
+
"ccc_index": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"additionalProperties": false,
|
|
75
|
+
"required": ["status", "indexed_path", "file_count"],
|
|
76
|
+
"properties": {
|
|
77
|
+
"status": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"enum": ["fresh", "created", "failed", "none"]
|
|
80
|
+
},
|
|
81
|
+
"indexed_path": { "type": ["string", "null"] },
|
|
82
|
+
"file_count": { "type": ["integer", "null"], "minimum": 0 }
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"files_written": {
|
|
86
|
+
"type": "array",
|
|
87
|
+
"items": {
|
|
88
|
+
"type": "string",
|
|
89
|
+
"enum": ["forge-tier.yaml", "preferences.yaml", "settings.yml", "ccc_index"]
|
|
90
|
+
},
|
|
91
|
+
"uniqueItems": true,
|
|
92
|
+
"description": "Files actually written this run. Empty array when a write failure halted the run before any file was written."
|
|
93
|
+
},
|
|
94
|
+
"tier_override_active": {
|
|
95
|
+
"type": "boolean",
|
|
96
|
+
"description": "True when a valid tier_override from preferences.yaml was applied."
|
|
97
|
+
},
|
|
98
|
+
"tier_override_invalid": {
|
|
99
|
+
"type": "boolean",
|
|
100
|
+
"description": "True when tier_override was set but did not match Quick|Forge|Forge+|Deep (case-sensitive). Detected tier was used as fallback."
|
|
101
|
+
},
|
|
102
|
+
"require_tier_satisfied": {
|
|
103
|
+
"type": ["boolean", "null"],
|
|
104
|
+
"description": "Null when --require-tier was not set. Otherwise true if the tool prerequisites of the requested tier are met (Deep does NOT subsume Forge+)."
|
|
105
|
+
},
|
|
106
|
+
"warnings": {
|
|
107
|
+
"type": "array",
|
|
108
|
+
"items": { "type": "string" },
|
|
109
|
+
"description": "Non-fatal anomalies surfaced during the run. May include tier_override_invalid, tier_override_unsafe, ccc_exclusion_warnings entries, ccc_registry_stale_removed entries, qmd_daemon_stopped, ccc_indexing_failed, etc. Empty when none."
|
|
110
|
+
},
|
|
111
|
+
"error": {
|
|
112
|
+
"oneOf": [
|
|
113
|
+
{ "type": "null" },
|
|
114
|
+
{
|
|
115
|
+
"type": "object",
|
|
116
|
+
"additionalProperties": false,
|
|
117
|
+
"required": ["phase", "path", "reason"],
|
|
118
|
+
"properties": {
|
|
119
|
+
"phase": {
|
|
120
|
+
"type": "string",
|
|
121
|
+
"minLength": 1,
|
|
122
|
+
"description": "Step or operation that failed (e.g. 'step-02-write-config:forge-tier.yaml')."
|
|
123
|
+
},
|
|
124
|
+
"path": { "type": "string", "minLength": 1, "description": "Absolute path of the file the failed operation targeted." },
|
|
125
|
+
"reason": { "type": "string", "minLength": 1, "description": "Human-readable error message." }
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
"description": "Null on success. Object describing the failure when forge-tier.yaml or preferences.yaml could not be written. Pipelines branch on error !== null for 'exit code 2' semantics."
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|