bmad-module-skill-forge 2.0.0 → 2.0.1
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/.nvmrc +1 -1
- package/docs/_data/pinned.yaml +1 -1
- package/package.json +2 -2
- package/src/knowledge/skill-lifecycle.md +1 -1
- package/src/module-help.csv +2 -2
- package/src/shared/scripts/skf-comention-pairs.py +350 -0
- package/src/shared/scripts/skf-count-tokens.py +222 -0
- package/src/shared/scripts/skf-detect-docs.py +232 -1
- package/src/shared/scripts/skf-detect-language.py +77 -0
- package/src/shared/scripts/skf-detect-tools.py +105 -2
- package/src/shared/scripts/skf-enumerate-stack-skills.py +111 -2
- package/src/shared/scripts/skf-find-cycles.py +246 -0
- package/src/shared/scripts/skf-hash-content.py +487 -2
- package/src/shared/scripts/skf-manifest-ops.py +67 -1
- package/src/shared/scripts/skf-rebuild-managed-sections.py +180 -0
- package/src/shared/scripts/skf-recommend-scope-type.py +1 -2
- package/src/shared/scripts/skf-render-metadata-stats.py +499 -0
- package/src/shared/scripts/skf-rewrite-skill-name.py +308 -0
- package/src/shared/scripts/skf-shard-body.py +461 -0
- package/src/shared/scripts/skf-skill-inventory.py +139 -3
- package/src/shared/scripts/skf-structural-diff.py +307 -67
- package/src/shared/scripts/skf-validate-brief-schema.py +39 -1
- package/src/shared/scripts/skf-validate-feasibility-report.py +234 -0
- package/src/shared/scripts/skf-validate-frontmatter.py +17 -12
- package/src/shared/scripts/skf-validate-output.py +443 -10
- package/src/shared/scripts/skf-validate-pins.py +1 -1
- package/src/shared/scripts/skf-verify-no-trace.py +214 -0
- package/src/shared/scripts/skf-verify-provenance-completeness.py +439 -0
- package/src/skf-analyze-source/SKILL.md +17 -32
- package/src/skf-analyze-source/customize.toml +2 -0
- package/src/skf-analyze-source/references/auto-docs-only.md +116 -0
- package/src/skf-analyze-source/references/continue.md +8 -13
- package/src/skf-analyze-source/references/generate-briefs.md +28 -12
- package/src/skf-analyze-source/references/headless-contract.md +33 -0
- package/src/skf-analyze-source/references/health-check.md +1 -2
- package/src/skf-analyze-source/references/identify-units.md +25 -36
- package/src/skf-analyze-source/references/init.md +12 -25
- package/src/skf-analyze-source/references/map-and-detect.md +8 -20
- package/src/skf-analyze-source/references/recommend.md +4 -14
- package/src/skf-analyze-source/references/scan-project.md +3 -11
- package/src/skf-analyze-source/references/step-auto-scope.md +42 -180
- package/src/skf-analyze-source/references/unit-detection-heuristics.md +2 -2
- package/src/skf-audit-skill/SKILL.md +9 -6
- package/src/skf-audit-skill/customize.toml +2 -0
- package/src/skf-audit-skill/references/init.md +58 -32
- package/src/skf-audit-skill/references/re-index.md +15 -34
- package/src/skf-audit-skill/references/report.md +11 -58
- package/src/skf-audit-skill/references/semantic-diff.md +4 -22
- package/src/skf-audit-skill/references/severity-classify.md +53 -87
- package/src/skf-audit-skill/references/step-doc-drift.md +49 -19
- package/src/skf-audit-skill/references/structural-diff.md +43 -68
- package/src/skf-brief-skill/SKILL.md +7 -36
- package/src/skf-brief-skill/assets/scope-templates.md +1 -1
- package/src/skf-brief-skill/customize.toml +14 -0
- package/src/skf-brief-skill/references/analyze-target.md +6 -14
- package/src/skf-brief-skill/references/confirm-brief.md +2 -14
- package/src/skf-brief-skill/references/draft-checkpoint.md +8 -8
- package/src/skf-brief-skill/references/gather-intent.md +19 -22
- package/src/skf-brief-skill/references/headless-args.md +1 -1
- package/src/skf-brief-skill/references/health-check.md +1 -22
- package/src/skf-brief-skill/references/invocation-contract.md +37 -0
- package/src/skf-brief-skill/references/scope-definition.md +4 -14
- package/src/skf-brief-skill/references/step-auto-brief.md +1 -5
- package/src/skf-brief-skill/references/step-auto-validate.md +1 -5
- package/src/skf-brief-skill/references/version-resolution.md +1 -1
- package/src/skf-brief-skill/references/write-brief.md +17 -10
- package/src/skf-campaign/SKILL.md +15 -84
- package/src/skf-campaign/customize.toml +2 -0
- package/src/skf-campaign/manifest.yaml +4 -0
- package/src/skf-campaign/references/campaign-contracts.md +67 -0
- package/src/skf-campaign/references/campaign-directive-spec.md +14 -103
- package/src/skf-campaign/references/step-01-setup.md +4 -5
- package/src/skf-campaign/references/step-02-strategy.md +8 -3
- package/src/skf-campaign/references/step-03-pins.md +1 -1
- package/src/skf-campaign/references/step-04-provenance.md +1 -1
- package/src/skf-campaign/references/step-05-skill-loop.md +1 -1
- package/src/skf-campaign/references/step-06-batch.md +7 -6
- package/src/skf-campaign/references/step-11-maintenance.md +2 -2
- package/src/skf-campaign/references/step-resume.md +9 -8
- package/src/skf-campaign/scripts/campaign-deps.py +10 -1
- package/src/skf-campaign/scripts/campaign-render-batch.py +199 -0
- package/src/skf-campaign/scripts/campaign-status.py +162 -0
- package/src/skf-campaign/templates/campaign-brief-template.yaml +1 -1
- package/src/skf-create-skill/SKILL.md +14 -3
- package/src/skf-create-skill/assets/compile-assembly-rules.md +17 -38
- package/src/skf-create-skill/assets/skill-sections.md +9 -100
- package/src/skf-create-skill/assets/tessl-dismissal-rules.md +4 -13
- package/src/skf-create-skill/customize.toml +13 -0
- package/src/skf-create-skill/references/authoritative-files-protocol.md +7 -7
- package/src/skf-create-skill/references/compile.md +34 -47
- package/src/skf-create-skill/references/component-extraction.md +8 -35
- package/src/skf-create-skill/references/ecosystem-check.md +9 -25
- package/src/skf-create-skill/references/enrich.md +4 -17
- package/src/skf-create-skill/references/extract.md +14 -29
- package/src/skf-create-skill/references/extraction-patterns-tracing.md +1 -1
- package/src/skf-create-skill/references/extraction-patterns.md +7 -7
- package/src/skf-create-skill/references/generate-artifacts.md +9 -23
- package/src/skf-create-skill/references/health-check.md +1 -1
- package/src/skf-create-skill/references/load-brief.md +16 -18
- package/src/skf-create-skill/references/report.md +12 -15
- package/src/skf-create-skill/references/source-resolution-protocols.md +3 -3
- package/src/skf-create-skill/references/step-auto-shard.md +52 -25
- package/src/skf-create-skill/references/step-doc-rot.md +30 -12
- package/src/skf-create-skill/references/step-doc-sources.md +2 -2
- package/src/skf-create-skill/references/sub/ccc-discover.md +2 -13
- package/src/skf-create-skill/references/sub/fetch-docs.md +8 -50
- package/src/skf-create-skill/references/sub/fetch-temporal.md +5 -20
- package/src/skf-create-skill/references/tier-degradation-rules.md +6 -8
- package/src/skf-create-skill/references/validate.md +59 -28
- package/src/skf-create-skill/scripts/scan-doc-rot.py +245 -0
- package/src/skf-create-stack-skill/SKILL.md +15 -9
- package/src/skf-create-stack-skill/assets/provenance-map-schema.md +1 -1
- package/src/skf-create-stack-skill/customize.toml +10 -0
- package/src/skf-create-stack-skill/references/compile-stack.md +7 -8
- package/src/skf-create-stack-skill/references/compose-mode-rules.md +2 -13
- package/src/skf-create-stack-skill/references/detect-integrations.md +49 -54
- package/src/skf-create-stack-skill/references/detect-manifests.md +37 -30
- package/src/skf-create-stack-skill/references/generate-output.md +24 -75
- package/src/skf-create-stack-skill/references/init.md +9 -81
- package/src/skf-create-stack-skill/references/manifest-patterns.md +5 -35
- package/src/skf-create-stack-skill/references/parallel-extract.md +12 -27
- package/src/skf-create-stack-skill/references/rank-and-confirm.md +6 -6
- package/src/skf-create-stack-skill/references/report.md +27 -62
- package/src/skf-create-stack-skill/references/validate.md +35 -31
- package/src/skf-drop-skill/SKILL.md +20 -23
- package/src/skf-drop-skill/customize.toml +10 -0
- package/src/skf-drop-skill/references/execute.md +51 -31
- package/src/skf-drop-skill/references/headless-contract.md +18 -0
- package/src/skf-drop-skill/references/health-check.md +1 -13
- package/src/skf-drop-skill/references/report.md +42 -10
- package/src/skf-drop-skill/references/select.md +88 -48
- package/src/skf-drop-skill/scripts/dir-sizes.py +116 -0
- package/src/skf-export-skill/SKILL.md +17 -14
- package/src/skf-export-skill/assets/managed-section-format.md +2 -5
- package/src/skf-export-skill/customize.toml +10 -6
- package/src/skf-export-skill/references/generate-snippet.md +21 -35
- package/src/skf-export-skill/references/load-skill.md +44 -42
- package/src/skf-export-skill/references/multi-skill-mode.md +1 -1
- package/src/skf-export-skill/references/orphan-context-detection.md +11 -3
- package/src/skf-export-skill/references/package.md +27 -33
- package/src/skf-export-skill/references/preflight-snippet-root-probe.md +24 -5
- package/src/skf-export-skill/references/result-envelope.md +28 -0
- package/src/skf-export-skill/references/summary.md +11 -5
- package/src/skf-export-skill/references/token-report.md +42 -24
- package/src/skf-export-skill/references/update-context.md +32 -33
- package/src/skf-forger/SKILL.md +27 -39
- package/src/skf-forger/references/pipeline-mode.md +34 -0
- package/src/skf-forger/scripts/parse-pipeline.py +270 -0
- package/src/skf-quick-skill/SKILL.md +10 -60
- package/src/skf-quick-skill/customize.toml +9 -0
- package/src/skf-quick-skill/references/batch-mode.md +6 -4
- package/src/skf-quick-skill/references/compile.md +15 -52
- package/src/skf-quick-skill/references/ecosystem-check.md +5 -20
- package/src/skf-quick-skill/references/finalize.md +12 -6
- package/src/skf-quick-skill/references/halt-contract.md +54 -0
- package/src/skf-quick-skill/references/health-check.md +3 -4
- package/src/skf-quick-skill/references/quick-extract.md +7 -18
- package/src/skf-quick-skill/references/registry-resolution.md +1 -23
- package/src/skf-quick-skill/references/resolve-target.md +27 -34
- package/src/skf-quick-skill/references/write-and-validate.md +10 -25
- package/src/skf-refine-architecture/SKILL.md +14 -7
- package/src/skf-refine-architecture/customize.toml +9 -0
- package/src/skf-refine-architecture/references/compile.md +9 -7
- package/src/skf-refine-architecture/references/gap-analysis.md +21 -50
- package/src/skf-refine-architecture/references/health-check.md +1 -1
- package/src/skf-refine-architecture/references/improvements.md +9 -25
- package/src/skf-refine-architecture/references/init.md +9 -16
- package/src/skf-refine-architecture/references/issue-detection.md +10 -25
- package/src/skf-refine-architecture/references/refinement-rules.md +4 -16
- package/src/skf-refine-architecture/references/report.md +13 -10
- package/src/skf-rename-skill/SKILL.md +11 -21
- package/src/skf-rename-skill/customize.toml +10 -0
- package/src/skf-rename-skill/references/execute.md +107 -78
- package/src/skf-rename-skill/references/exit-codes.md +12 -0
- package/src/skf-rename-skill/references/report.md +16 -8
- package/src/skf-rename-skill/references/select.md +69 -42
- package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -0
- package/src/skf-setup/SKILL.md +20 -12
- package/src/skf-setup/customize.toml +10 -0
- package/src/skf-setup/references/auto-index.md +9 -10
- package/src/skf-setup/references/ccc-index.md +14 -15
- package/src/skf-setup/references/detect-and-tier.md +6 -8
- package/src/skf-setup/references/report.md +22 -31
- package/src/skf-setup/references/tier-rules.md +2 -32
- package/src/skf-setup/references/write-config.md +9 -10
- package/src/skf-test-skill/SKILL.md +10 -8
- package/src/skf-test-skill/customize.toml +2 -0
- package/src/skf-test-skill/references/coherence-check.md +19 -31
- package/src/skf-test-skill/references/coverage-check.md +109 -75
- package/src/skf-test-skill/references/detect-mode.md +10 -41
- package/src/skf-test-skill/references/external-validators.md +11 -19
- package/src/skf-test-skill/references/init.md +38 -20
- package/src/skf-test-skill/references/migration-section-rules.md +4 -4
- package/src/skf-test-skill/references/report.md +60 -40
- package/src/skf-test-skill/references/score.md +32 -64
- package/src/skf-test-skill/references/scoring-rules.md +6 -62
- package/src/skf-test-skill/references/source-access-protocol.md +6 -6
- package/src/skf-test-skill/references/step-hard-gate.md +1 -3
- package/src/skf-test-skill/scripts/aggregate-coherence.py +276 -0
- package/src/skf-test-skill/scripts/check-metadata-coherence.py +359 -0
- package/src/skf-test-skill/scripts/combine-external-scores.py +190 -0
- package/src/skf-test-skill/scripts/compute-score.py +131 -1
- package/src/skf-test-skill/scripts/reconcile-coverage.py +327 -0
- package/src/skf-test-skill/scripts/validate-inventory.py +251 -0
- package/src/skf-test-skill/scripts/verify-declared-numerator.py +192 -0
- package/src/skf-update-skill/SKILL.md +17 -5
- package/src/skf-update-skill/customize.toml +14 -0
- package/src/skf-update-skill/references/detect-changes.md +19 -37
- package/src/skf-update-skill/references/health-check.md +3 -9
- package/src/skf-update-skill/references/init.md +39 -32
- package/src/skf-update-skill/references/manual-section-rules.md +1 -2
- package/src/skf-update-skill/references/merge-conflict-rules.md +1 -52
- package/src/skf-update-skill/references/merge.md +13 -57
- package/src/skf-update-skill/references/re-extract.md +12 -24
- package/src/skf-update-skill/references/report.md +14 -7
- package/src/skf-update-skill/references/validate.md +32 -30
- package/src/skf-update-skill/references/write.md +86 -51
- package/src/skf-update-skill/scripts/skf-new-file-diff.py +167 -0
- package/src/skf-verify-stack/SKILL.md +11 -21
- package/src/skf-verify-stack/customize.toml +12 -3
- package/src/skf-verify-stack/references/coverage-patterns.md +1 -29
- package/src/skf-verify-stack/references/coverage.md +21 -10
- package/src/skf-verify-stack/references/exit-codes.md +14 -0
- package/src/skf-verify-stack/references/health-check.md +1 -1
- package/src/skf-verify-stack/references/init.md +20 -25
- package/src/skf-verify-stack/references/integration-verification-rules.md +10 -19
- package/src/skf-verify-stack/references/integrations.md +44 -49
- package/src/skf-verify-stack/references/report.md +28 -34
- package/src/skf-verify-stack/references/requirements.md +3 -3
- package/src/skf-verify-stack/references/synthesize.md +36 -39
- package/src/skf-verify-stack/scripts/skf-coverage-tally.py +196 -0
- package/src/skf-verify-stack/scripts/skf-report-delta.py +256 -0
- package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +258 -0
- package/src/skf-rename-skill/references/rebuild-context.md +0 -110
|
@@ -7,7 +7,7 @@ description: Fast skill from a package name or GitHub URL — no brief needed. U
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
The fastest path to a skill — accept a GitHub URL or package name, resolve to source, extract the public API surface, and produce a best-effort SKILL.md with context snippet and metadata. No brief needed.
|
|
10
|
+
The fastest path to a skill — accept a GitHub URL or package name, resolve to source, extract the public API surface, and produce a best-effort SKILL.md with context snippet and metadata. No brief needed. Output is always community-tier quality, regardless of which tools are available.
|
|
11
11
|
|
|
12
12
|
## Conventions
|
|
13
13
|
|
|
@@ -28,7 +28,7 @@ These rules apply to every step in this workflow:
|
|
|
28
28
|
- Never fabricate content — all data must come from source extraction or user input
|
|
29
29
|
- Only load one step file at a time — never preload future steps
|
|
30
30
|
- Always communicate in `{communication_language}`
|
|
31
|
-
- **Universal cancel-line affordance** — at any interactive prompt the user may type `cancel`, `exit`, `:q`, or select the `[X] Cancel and exit` menu option (where surfaced) to leave cleanly. HARD HALT with **exit code 6 (user-cancelled)** and emit the error result contract per
|
|
31
|
+
- **Universal cancel-line affordance** — at any interactive prompt the user may type `cancel`, `exit`, `:q`, or select the `[X] Cancel and exit` menu option (where surfaced) to leave cleanly. HARD HALT with **exit code 6 (user-cancelled)** and emit the error result contract per `references/halt-contract.md` with `error.code: "user-cancelled"`. In step 4 §6 the equivalent affordance is `[Q] Quit without writing` — same exit code, same envelope contract.
|
|
32
32
|
- If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action and log each auto-decision
|
|
33
33
|
- If `{headless_mode}` is true, emit a single-line JSON progress event to **stderr** at each step's entry and exit so pipeline schedulers can stream live progress instead of post-mortem-parsing the result contract:
|
|
34
34
|
- entry: `{"step":N,"name":"<slug>","status":"start"}`
|
|
@@ -55,61 +55,14 @@ These rules apply to every step in this workflow:
|
|
|
55
55
|
|--------|--------|
|
|
56
56
|
| **Inputs** | target (GitHub URL or package name) [required for single-target mode], language_hint [optional], scope_hint [optional] |
|
|
57
57
|
| **Overrides** | `--description`, `--exports`, `--skip-snippet`, `--no-active-pointer`, `--batch <file>`, `--fail-fast` — see On Activation step 4 |
|
|
58
|
-
| **Gates** | step 1:
|
|
58
|
+
| **Gates** | step 1: target input, multi-language disambiguation [C/A]; step 2: ecosystem match [P/I/A] (if match); step 3: repo-shape [C/A] + zero-exports rescue [R/P/A]; step 4: review [C/E/S/Q]; step 5: overwrite [Y/N] |
|
|
59
59
|
| **Outputs** | SKILL.md, context-snippet.md, metadata.json, active pointer, result contract (timestamped + `-latest` copy). Snippet and active pointer can be skipped per overrides. |
|
|
60
60
|
| **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true |
|
|
61
|
-
| **Exit codes** | See
|
|
61
|
+
| **Exit codes** | See `references/halt-contract.md` |
|
|
62
62
|
|
|
63
|
-
## Exit Codes
|
|
63
|
+
## Exit Codes & HARD HALT Contract
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
| Code | Meaning | Raised by |
|
|
68
|
-
| ---- | ---------------------- | ----------------------------------------------------------- |
|
|
69
|
-
| 0 | success | step 7 (terminal) |
|
|
70
|
-
| 3 | resolution-failure | step 1 §2c (prose input), step 1 §3 (registry chain failed) |
|
|
71
|
-
| 4 | write-failure | step 5 §2 (deliverable write failed) |
|
|
72
|
-
| 5 | overwrite-cancelled | step 5 §1 (user selected [N]) |
|
|
73
|
-
| 6 | user-cancelled | step 1 §1 ([X] Cancel and exit, or cancel-line affordance); step 2 §3 ([A] Abort at ecosystem-match gate); step 4 §6 (user selected [Q]) — originally `compile-cancelled`, generalised to cover any interactive gate |
|
|
74
|
-
| 7 | finalize-blocked | step 6 §1 (active-pointer flip refused — non-link in place) |
|
|
75
|
-
| 8 | ecosystem-redirect | step 2 §3 ([I] Install at ecosystem-match gate — user opted to install the existing official skill instead of compiling a custom community skill) |
|
|
76
|
-
|
|
77
|
-
Reserved: `validator-missing` may be promoted from advisory log to fatal exit code in a future revision.
|
|
78
|
-
|
|
79
|
-
## Result Contract on HARD HALT
|
|
80
|
-
|
|
81
|
-
In addition to the success-variant result contract written by step 6 §3, every HARD HALT must surface an **error variant** so headless automators don't silently break when `quick-skill-result-latest.json` is missing on failed runs.
|
|
82
|
-
|
|
83
|
-
**Always (every HARD HALT, regardless of phase)** — emit a single line on **stderr**:
|
|
84
|
-
|
|
85
|
-
```
|
|
86
|
-
SKF_QUICK_SKILL_RESULT_JSON: {"status":"error","exit_code":<N>,"phase":"<slug>","error":{"code":"<class>","message":"<short>"},"outputs":{},"summary":{},"skill_package":"<path-or-null>"}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
One line, no pretty-print. Matches the prefix-and-envelope convention used by `skf-emit-result-envelope.py`.
|
|
90
|
-
|
|
91
|
-
**Additionally, when `{skill_package}` is known** (HALT at step 5 §1 onward) — write the same JSON object (without the `SKF_QUICK_SKILL_RESULT_JSON: ` prefix) to disk:
|
|
92
|
-
|
|
93
|
-
```
|
|
94
|
-
{skill_package}/quick-skill-result-{YYYYMMDD-HHmmss}.json
|
|
95
|
-
{skill_package}/quick-skill-result-latest.json (copy, not symlink)
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
so consumers that hardcode the `-latest.json` path see a deterministic file even on failed runs. HALTs at step 1/02/03/04 cannot write to disk because `{skill_package}` is computed only in step 5 §1; for those, the stderr envelope plus exit code is the contract.
|
|
99
|
-
|
|
100
|
-
**Schema:**
|
|
101
|
-
|
|
102
|
-
| Field | Type | Notes |
|
|
103
|
-
| --------------- | -------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
104
|
-
| `status` | string | always `"error"` for HARD HALTs |
|
|
105
|
-
| `exit_code` | integer | matches the Exit Codes table |
|
|
106
|
-
| `phase` | string | step slug where the HALT occurred (e.g. `resolve-target`, `compile`) |
|
|
107
|
-
| `error.code` | string | one of: `resolution-failure`, `write-failure`, `overwrite-cancelled`, `user-cancelled` (formerly `compile-cancelled`), `finalize-blocked`, `ecosystem-redirect` |
|
|
108
|
-
| `error.message` | string | the user-facing message that was displayed |
|
|
109
|
-
| `error.details` | any | optional — phase-specific context (e.g. the failed file path) |
|
|
110
|
-
| `outputs` | object | empty `{}` on early HALTs; partial when files were already written |
|
|
111
|
-
| `summary` | object | empty `{}` on early HALTs |
|
|
112
|
-
| `skill_package` | string \| null | absolute path when known, `null` when HALT preceded step 5 §1 |
|
|
65
|
+
See `references/halt-contract.md` for the exit-code map and the error-result envelope every HARD HALT emits (the `SKF_QUICK_SKILL_RESULT_JSON:` stderr line, the on-disk `-latest.json` write once `{skill_package}` is known, and the schema). Steps load it on their failure path so the wire format survives compaction.
|
|
113
66
|
|
|
114
67
|
## On Activation
|
|
115
68
|
|
|
@@ -139,8 +92,11 @@ so consumers that hardcode the `-latest.json` path see a deterministic file even
|
|
|
139
92
|
- `{skillTemplatePath}` ← `workflow.skill_template_path` if non-empty, else `assets/skill-template.md`
|
|
140
93
|
- `{registryResolutionPath}` ← `workflow.registry_resolution_path` if non-empty, else `references/registry-resolution.md`
|
|
141
94
|
- `{batchOutputPath}` ← `workflow.batch_output_path` if non-empty, else `{skills_output_folder}/_batch/`
|
|
95
|
+
- `{onCompleteCommand}` ← `workflow.on_complete` if non-empty, else empty (no-op — step 6 §3 skips the hook invocation entirely)
|
|
142
96
|
|
|
143
|
-
Stash all
|
|
97
|
+
Stash all four as workflow-context variables. Stage files reference `{skillTemplatePath}` / `{registryResolutionPath}` / `{batchOutputPath}` / `{onCompleteCommand}` directly — no conditional at the usage site. Empty-string overrides cleanly fall through to the bundled default; non-empty values let orgs swap in house-style copies (custom template, registry chain, batch output dir) or wire in a post-completion hook (git-add, register, notify) without forking the skill.
|
|
98
|
+
|
|
99
|
+
**Apply the array surfaces** so the declared overrides are not silent no-ops: execute each entry in `workflow.activation_steps_prepend` in order now; treat every entry in `workflow.persistent_facts` as standing context for the whole run (`file:`-prefixed entries are paths or globs whose contents load as facts — the bundled default loads any `project-context.md`); then, after activation completes and before the first stage runs, execute each entry in `workflow.activation_steps_append` in order.
|
|
144
100
|
|
|
145
101
|
4. **Parse CLI overrides** — capture optional override flags into the workflow context as `{overrides}`. Each override is opt-in; when omitted, the workflow runs as today.
|
|
146
102
|
|
|
@@ -156,9 +112,3 @@ so consumers that hardcode the `-latest.json` path see a deterministic file even
|
|
|
156
112
|
5. **If `--batch` is set**, force `{headless_mode} = true` (log "headless: coerced by --batch" if it was false), then load and read `references/batch-mode.md` in full before proceeding. Follow its protocol to read the batch file, parse the target list, and drive the batch loop that wraps the step 1 → step 7 pipeline that follows.
|
|
157
113
|
|
|
158
114
|
6. Load, read the full file, and then execute `references/resolve-target.md` to begin the workflow. (In batch mode, control returns here for each subsequent target after step 7 completes; see `references/batch-mode.md`.)
|
|
159
|
-
|
|
160
|
-
## Batch Mode
|
|
161
|
-
|
|
162
|
-
When `--batch <file>` is supplied, quick-skill processes a list of targets from a text file in sequence rather than a single argument.
|
|
163
|
-
|
|
164
|
-
See `references/batch-mode.md` for the full protocol (input format, execution loop, summary contract, headless events, exit code).
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# DO NOT EDIT -- overwritten on every update.
|
|
2
2
|
#
|
|
3
3
|
# Workflow customization surface for skf-quick-skill.
|
|
4
|
+
# Team overrides: _bmad/custom/skf-quick-skill.toml (under {project-root})
|
|
5
|
+
# Personal overrides: _bmad/custom/skf-quick-skill.user.toml (under {project-root})
|
|
4
6
|
|
|
5
7
|
[workflow]
|
|
6
8
|
|
|
@@ -42,3 +44,10 @@ persistent_facts = [
|
|
|
42
44
|
skill_template_path = ""
|
|
43
45
|
registry_resolution_path = ""
|
|
44
46
|
batch_output_path = ""
|
|
47
|
+
|
|
48
|
+
# Optional post-completion hook. When non-empty, invoked with
|
|
49
|
+
# `--skill-package=<path>` after the result contract is finalized in step 6.
|
|
50
|
+
# Failures are logged but never fail the workflow. Use for git-add,
|
|
51
|
+
# skill-registry registration, or a notifier on the freshly compiled skill.
|
|
52
|
+
|
|
53
|
+
on_complete = ""
|
|
@@ -6,7 +6,7 @@ nextStepFile: 'resolve-target.md'
|
|
|
6
6
|
|
|
7
7
|
# Batch Mode
|
|
8
8
|
|
|
9
|
-
When `--batch <file>` is supplied, quick-skill processes a list of targets from a text file in sequence rather than a single target from arguments. Designed for unattended bulk runs
|
|
9
|
+
When `--batch <file>` is supplied, quick-skill processes a list of targets from a text file in sequence rather than a single target from arguments. Designed for unattended bulk runs — CI pipelines, mass-rebuilds, and batch meta-workflows.
|
|
10
10
|
|
|
11
11
|
## Input format
|
|
12
12
|
|
|
@@ -43,17 +43,19 @@ Per-line modifiers shadow the global `--description` / `--exports` / `--skip-sni
|
|
|
43
43
|
3. After step 7 completes (success or HARD HALT), record the per-target outcome (target, status, exit_code, skill_package, error.code) into the batch result list.
|
|
44
44
|
4. If `--fail-fast` is set and the target failed, exit the batch loop immediately. Otherwise continue with the next target.
|
|
45
45
|
|
|
46
|
-
Per-target output lands in `{skill_package}/` as today, with the per-target result contract at `{skill_package}/quick-skill-result-latest.json` (success or error variant per
|
|
46
|
+
Per-target output lands in `{skill_package}/` as today, with the per-target result contract at `{skill_package}/quick-skill-result-latest.json` (success or error variant per `references/halt-contract.md`).
|
|
47
47
|
|
|
48
48
|
## Batch summary contract
|
|
49
49
|
|
|
50
50
|
After the last target completes (or `--fail-fast` triggers an early exit), write the batch summary at:
|
|
51
51
|
|
|
52
52
|
```
|
|
53
|
-
{
|
|
54
|
-
{
|
|
53
|
+
{batchOutputPath}quick-skill-batch-{YYYYMMDD-HHmmss}.json
|
|
54
|
+
{batchOutputPath}quick-skill-batch-latest.json (copy, not symlink)
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
+
`{batchOutputPath}` is resolved at SKILL.md On Activation §3 from `workflow.batch_output_path` (bundled default `{skills_output_folder}/_batch/`, trailing slash included).
|
|
58
|
+
|
|
57
59
|
Schema:
|
|
58
60
|
|
|
59
61
|
```json
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
nextStepFile: 'write-and-validate.md'
|
|
3
|
-
skillTemplateData: '
|
|
3
|
+
skillTemplateData: '{skillTemplatePath}'
|
|
4
4
|
quickMetadataRendererProbeOrder:
|
|
5
5
|
- '{project-root}/_bmad/skf/shared/scripts/skf-render-quick-metadata.py'
|
|
6
6
|
- '{project-root}/src/shared/scripts/skf-render-quick-metadata.py'
|
|
@@ -20,7 +20,7 @@ To assemble the best-effort SKILL.md document, context-snippet.md in Vercel-alig
|
|
|
20
20
|
- Follow template structure exactly from {skillTemplateData}
|
|
21
21
|
- Mark any sections with insufficient data as best-effort
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Steps
|
|
24
24
|
|
|
25
25
|
### 1. Load Skill Template
|
|
26
26
|
|
|
@@ -31,57 +31,28 @@ Load {skillTemplateData} to understand:
|
|
|
31
31
|
|
|
32
32
|
### 2. Assemble SKILL.md
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Populate the SKILL.md section structure from `{skillTemplateData}` § "SKILL.md Section Structure" (the frontmatter skeleton and the Required/Optional section list live there) using extraction_inventory. The rules below are the deltas the template does not encode:
|
|
35
35
|
|
|
36
|
-
**Frontmatter (
|
|
37
|
-
|
|
38
|
-
The SKILL.md MUST begin with YAML frontmatter:
|
|
39
|
-
|
|
40
|
-
```yaml
|
|
41
|
-
---
|
|
42
|
-
name: {skill_name}
|
|
43
|
-
description: >
|
|
44
|
-
{Trigger-optimized description from extraction_inventory.description.
|
|
45
|
-
1-1024 chars. Include what it does, when to use it, and what NOT to use it for.}
|
|
46
|
-
---
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
**Frontmatter rules:**
|
|
36
|
+
**Frontmatter rules (agentskills.io compliance):**
|
|
50
37
|
- `name`: lowercase alphanumeric + hyphens only, must match the skill output directory name. Prefer gerund form (`processing-pdfs`) for clarity.
|
|
51
|
-
- `description`: non-empty, max 1024 chars, optimized for agent discovery.
|
|
38
|
+
- `description`: non-empty, max 1024 chars, optimized for agent discovery. Use third-person voice ("Processes..." not "I can..." / "You can...") so it reads correctly in the agent's skill index.
|
|
52
39
|
- No other frontmatter fields — only `name` and `description` for community skills
|
|
53
40
|
|
|
54
|
-
**
|
|
55
|
-
- **Overview:** Package name, repository, language, source authority, generation date
|
|
41
|
+
**Per-section override wiring:**
|
|
56
42
|
- **Description:** From `{overrides.description}` if set (subject to the same length/voice checks as extracted descriptions); otherwise from extraction_inventory.description (README-derived)
|
|
57
43
|
- **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
|
|
58
|
-
- **Usage Patterns:** From extraction_inventory.usage_patterns (README examples)
|
|
59
44
|
|
|
60
|
-
**
|
|
61
|
-
- **Configuration:** If configuration options were found in source
|
|
62
|
-
- **Dependencies:** Key dependencies from manifest
|
|
63
|
-
- **Notes:** Caveats, limitations, extraction confidence level
|
|
64
|
-
- **Scripts & Assets Note** (if source contains `scripts/`, `bin/`, `assets/`, `templates/`, or `schemas/` directories): "This package may include scripts and assets. Run create-skill for full extraction with provenance tracking."
|
|
45
|
+
**Scripts & Assets Note** (add as an optional section if source contains `scripts/`, `bin/`, `assets/`, `templates/`, or `schemas/` directories): "This package may include scripts and assets. Run create-skill for full extraction with provenance tracking."
|
|
65
46
|
|
|
66
|
-
**If confidence is low
|
|
67
|
-
- Include a note: "This skill was generated with limited source data. Consider running create-skill for a more thorough compilation."
|
|
47
|
+
**If confidence is low** — include a note: "This skill was generated with limited source data. Consider running create-skill for a more thorough compilation."
|
|
68
48
|
|
|
69
49
|
### 3. Generate Context Snippet
|
|
70
50
|
|
|
71
51
|
**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 5 §5 advisory snippet validation will report a "skipped" entry.
|
|
72
52
|
|
|
73
|
-
Otherwise,
|
|
53
|
+
Otherwise, produce context-snippet.md in the Vercel-aligned indexed format from `{skillTemplateData}` § "context-snippet.md Format" (~80-120 tokens).
|
|
74
54
|
|
|
75
|
-
|
|
76
|
-
[{skill_name} v{version}]|root: skills/{skill_name}/
|
|
77
|
-
|IMPORTANT: {skill_name} v{version} — read SKILL.md before writing {skill_name} code. Do NOT rely on training data.
|
|
78
|
-
|quick-start:{SKILL.md#usage-patterns}
|
|
79
|
-
|api: {top-5 exports with () for functions}
|
|
80
|
-
|key-types:{SKILL.md#key-exports} — {inline summary of most important type values}
|
|
81
|
-
|gotchas: {2-3 most critical pitfalls or breaking changes, inline}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
The anchors point to the QS template's actual headings — `#usage-patterns` (Usage Patterns) and `#key-exports` (Key Exports). The QS template has no `## Quick Start` / `## Key Types` headings (those are Deep-tier sections), so the Deep-tier anchors `#quick-start` / `#key-types` would dangle. If the assembled SKILL.md is missing the referenced heading, omit that line rather than emit a dangling anchor.
|
|
55
|
+
The snippet anchors point to the QS template's actual headings — `#usage-patterns` (Usage Patterns) and `#key-exports` (Key Exports). The QS template has no `## Quick Start` / `## Key Types` headings (those are Deep-tier sections), so the Deep-tier anchors `#quick-start` / `#key-types` would dangle. If the assembled SKILL.md is missing the referenced heading, omit that line rather than emit a dangling anchor.
|
|
85
56
|
|
|
86
57
|
**If fewer than 5 exports:** Use all available exports.
|
|
87
58
|
**If no exports:** Omit the api line.
|
|
@@ -91,7 +62,7 @@ The anchors point to the QS template's actual headings — `#usage-patterns` (Us
|
|
|
91
62
|
|
|
92
63
|
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".
|
|
93
64
|
|
|
94
|
-
**Resolve `{quickMetadataRenderer}`** from `{quickMetadataRendererProbeOrder}`; first existing path wins. If no candidate exists, fall back to in-prompt rendering
|
|
65
|
+
**Resolve `{quickMetadataRenderer}`** from `{quickMetadataRendererProbeOrder}`; first existing path wins. If no candidate exists, fall back to in-prompt rendering of the canonical envelope per `{skillTemplateData}` § "metadata.json Format".
|
|
95
66
|
|
|
96
67
|
**Probe `tool_versions.skf` first** (the helper expects it as input — the filesystem walk stays here because the helper does no I/O):
|
|
97
68
|
|
|
@@ -108,8 +79,6 @@ echo '{"name":"<name>","version":"<v>","description":"<desc>","language":"<lang>
|
|
|
108
79
|
|
|
109
80
|
The renderer emits the rendered metadata.json on stdout. Capture the output as `metadata` for the §5 preview and step 5 §2's deliverable write.
|
|
110
81
|
|
|
111
|
-
**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.
|
|
112
|
-
|
|
113
82
|
### 5. Present Compiled Output for Review
|
|
114
83
|
|
|
115
84
|
**If `{headless_mode}` is true** — skip the inline preview (no human reviewer reads it) and emit a one-line summary instead:
|
|
@@ -156,18 +125,12 @@ Display: **Select:** [C] Continue to Validation · [E] Edit description · [S] A
|
|
|
156
125
|
- **IF C** — Load, read entire file, then execute {nextStepFile}.
|
|
157
126
|
- **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.
|
|
158
127
|
- **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 `quick-extract.md` to re-extract. The new extraction returns to §1 of this step on completion. Discards the prior compiled output.
|
|
159
|
-
- **IF Q** — HARD HALT with **exit code 6 (user-cancelled)** per the
|
|
128
|
+
- **IF Q** — HARD HALT with **exit code 6 (user-cancelled)** per the exit-code map in `references/halt-contract.md`: "Compilation cancelled. No files written." Before exiting, emit the error result contract per `references/halt-contract.md` (`phase: "compile"`, `error.code: "user-cancelled"`, `skill_package: null`). Do not proceed to validation; do not write any artifacts.
|
|
160
129
|
- **IF Any other** — Help the user adjust the compiled output (treated as a free-form revision request), then redisplay the menu.
|
|
161
130
|
|
|
162
|
-
####
|
|
131
|
+
#### Gate:
|
|
163
132
|
|
|
164
|
-
-
|
|
133
|
+
- Halt and wait for user input after presenting the compiled output; only [C] (or a headless auto-approve) chains to `{nextStepFile}` for validation.
|
|
165
134
|
- **GATE [default: C]** — If `{headless_mode}`: auto-proceed with [C] Continue, log: "headless: auto-approve compiled output"
|
|
166
|
-
-
|
|
167
|
-
- [E] is local: re-renders the preview without re-running extraction
|
|
168
|
-
- [S] is the heavy option: it discards the compiled output and re-runs step 3 with new hints
|
|
169
|
-
|
|
170
|
-
## CRITICAL STEP COMPLETION NOTE
|
|
171
|
-
|
|
172
|
-
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.
|
|
135
|
+
- [E] re-renders the preview without re-running extraction; [S] discards the compiled output and re-runs step 3 with new hints.
|
|
173
136
|
|
|
@@ -12,11 +12,10 @@ To query the agentskills.io ecosystem for an existing official skill matching th
|
|
|
12
12
|
|
|
13
13
|
## Rules
|
|
14
14
|
|
|
15
|
-
- This check is advisory — never block the workflow on failure
|
|
16
15
|
- 5-second timeout on ecosystem queries; tool unavailability is a silent skip, not an error
|
|
17
16
|
- Do not begin extraction or compilation
|
|
18
17
|
|
|
19
|
-
##
|
|
18
|
+
## Steps
|
|
20
19
|
|
|
21
20
|
### 1. Query Ecosystem
|
|
22
21
|
|
|
@@ -54,34 +53,20 @@ An official skill already exists. You can:
|
|
|
54
53
|
**[I] Install** — Install the existing official skill instead (exits this workflow)
|
|
55
54
|
**[A] Abort** — Cancel compilation"
|
|
56
55
|
|
|
57
|
-
### 3. Handle Match Menu (
|
|
56
|
+
### 3. Handle Match Menu (only when a match was found)
|
|
58
57
|
|
|
59
58
|
#### Menu Handling Logic:
|
|
60
59
|
|
|
61
60
|
- IF P: Set `ecosystem_status: match-proceed`, then load, read entire file, then execute {nextStepFile}
|
|
62
|
-
- IF I: Display install instructions for the official skill, emit the HARD HALT envelope per
|
|
61
|
+
- IF I: Display install instructions for the official skill, emit the HARD HALT envelope per `references/halt-contract.md` (`phase: "ecosystem-check"`, `error.code: "ecosystem-redirect"`, `error.message: "User opted to install existing official skill instead of compiling a custom community skill."`, `skill_package: null`), exit with code 8 (ecosystem-redirect). Skill package is unknown at this phase — no on-disk result file is written.
|
|
63
62
|
- IF A: Display "Compilation cancelled.", emit the HARD HALT envelope (`phase: "ecosystem-check"`, `error.code: "user-cancelled"`, `error.message: "User aborted at ecosystem-match gate."`, `skill_package: null`), exit with code 6 (user-cancelled). Skill package is unknown at this phase — no on-disk result file is written.
|
|
64
63
|
- IF Any other: help user, then redisplay the match menu
|
|
65
64
|
|
|
66
|
-
####
|
|
65
|
+
#### Gate:
|
|
67
66
|
|
|
68
|
-
- ONLY display this menu when ecosystem_status is match
|
|
69
|
-
- ALWAYS halt and wait for user input when match is found
|
|
70
67
|
- **GATE [default: P]** — If `{headless_mode}` and match found: auto-proceed with [P] Proceed (compile custom skill anyway), log: "headless: ecosystem match found, auto-proceeding with custom compilation"
|
|
71
|
-
- For no-match and skip cases, auto-proceed without menu
|
|
72
68
|
|
|
73
69
|
### 4. Auto-Proceed (No Match or Skip)
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
- After no-match or skip determination, immediately load, read entire file, then execute {nextStepFile}
|
|
78
|
-
|
|
79
|
-
#### EXECUTION RULES:
|
|
80
|
-
|
|
81
|
-
- This is an auto-proceed path — no user interaction needed
|
|
82
|
-
- Proceed directly to extraction step
|
|
83
|
-
|
|
84
|
-
## CRITICAL STEP COMPLETION NOTE
|
|
85
|
-
|
|
86
|
-
ONLY WHEN ecosystem check completes (match with user choice, no-match, or skip) will you load and read fully `{nextStepFile}` to proceed to source extraction.
|
|
71
|
+
For no-match and skip, load and execute {nextStepFile} to proceed to source extraction.
|
|
87
72
|
|
|
@@ -19,7 +19,7 @@ To finalize the skill by creating the active-version pointer, displaying the com
|
|
|
19
19
|
- Create the active pointer via the shared helper — never `rm` + `ln -s` manually
|
|
20
20
|
- Result contract writing is mandatory (pipeline consumers depend on it)
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Steps
|
|
23
23
|
|
|
24
24
|
### 1. Create Active Pointer (atomic flip, Windows-safe)
|
|
25
25
|
|
|
@@ -29,7 +29,7 @@ To finalize the skill by creating the active-version pointer, displaying the com
|
|
|
29
29
|
|
|
30
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:
|
|
31
31
|
|
|
32
|
-
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins.
|
|
32
|
+
**Resolve `{atomicWriteHelper}`** from `{atomicWriteProbeOrder}`; first existing path wins. If no candidate exists, skip the flip the same way `--no-active-pointer` does: log "Active pointer: skipped — atomic-write helper unavailable", omit the active-pointer line from the completion summary and outputs, and record `active_pointer: "skipped-helper-missing"` in the result-contract summary (§3) so consumers see why the pointer is absent. The deliverables are already on disk, so a missing helper degrades to "no pointer" rather than a failed run. There is no manual fallback: a hand-rolled `rm` + `ln -s` loses the helper's atomicity and non-link guard, risking a half-flipped pointer or an `rm -rf` into a real directory.
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
35
|
python3 {atomicWriteHelper} flip-link \
|
|
@@ -37,9 +37,7 @@ python3 {atomicWriteHelper} flip-link \
|
|
|
37
37
|
--target {version}
|
|
38
38
|
```
|
|
39
39
|
|
|
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
|
|
41
|
-
|
|
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.
|
|
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 exit-code map in `references/halt-contract.md`: "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 `references/halt-contract.md` (`phase: "finalize"`, `error.code: "finalize-blocked"`, `skill_package` set, `outputs` listing the deliverables already on disk from step 5). 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.
|
|
43
41
|
|
|
44
42
|
Confirm: "Active pointer: {skill_group}/active -> {version} ({kind})" where `{kind}` is `symlink` or `junction` as returned by the helper.
|
|
45
43
|
|
|
@@ -76,6 +74,14 @@ Confirm: "Active pointer: {skill_group}/active -> {version} ({kind})" where `{ki
|
|
|
76
74
|
|
|
77
75
|
Write the result contract per `shared/references/output-contract-schema.md`: the per-run record at `{skill_package}/quick-skill-result-{YYYYMMDD-HHmmss}.json` (UTC timestamp, resolution to seconds) and a copy at `{skill_package}/quick-skill-result-latest.json` (stable path for pipeline consumers — copy, not symlink). Include `SKILL.md`, `context-snippet.md`, and `metadata.json` paths in `outputs` and export count in `summary`.
|
|
78
76
|
|
|
77
|
+
**Post-completion hook (optional).** If `{onCompleteCommand}` is non-empty (resolved at SKILL.md On Activation §3 from `workflow.on_complete`), invoke it after the result contract is finalized:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
{onCompleteCommand} --skill-package={skill_package}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Log success/failure but never fail the workflow on a hook error — the skill is already written. The hook runs last so a git-add, registry registration, or notifier sees a complete package. When `{onCompleteCommand}` is empty (bundled default), skip the invocation entirely.
|
|
84
|
+
|
|
79
85
|
### 4. Chain to Health Check
|
|
80
86
|
|
|
81
|
-
|
|
87
|
+
Once the active pointer, completion summary, result contract, and any post-completion hook are done, load and execute {nextStepFile}. Do not stop here — health-check is the true terminal step even though the summary reads as final.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
2
|
+
|
|
3
|
+
# HARD HALT Contract
|
|
4
|
+
|
|
5
|
+
The exit-code map and error-result envelope every step emits on a HARD HALT. Any step loads this file on its failure path, so the wire format is available even if SKILL.md has been compacted mid-run.
|
|
6
|
+
|
|
7
|
+
## Exit Codes
|
|
8
|
+
|
|
9
|
+
Every HARD HALT in this workflow exits with a stable, documented code so headless automators can branch on the failure class without grepping message text:
|
|
10
|
+
|
|
11
|
+
| Code | Meaning | Raised by |
|
|
12
|
+
| ---- | ---------------------- | ----------------------------------------------------------- |
|
|
13
|
+
| 0 | success | step 7 (terminal) |
|
|
14
|
+
| 3 | resolution-failure | step 1 (prose input §2, registry chain §3, version-tag miss §3a, language abort §4); step 3 (non-library shape §1.5, zero-exports §4.5) |
|
|
15
|
+
| 4 | write-failure | step 5 §2 (deliverable write failed) |
|
|
16
|
+
| 5 | overwrite-cancelled | step 5 §1 (user selected [N]) |
|
|
17
|
+
| 6 | user-cancelled | step 1 §1 ([X] Cancel and exit, or cancel-line affordance); step 2 §3 ([A] Abort at ecosystem-match gate); step 4 §6 (user selected [Q]) |
|
|
18
|
+
| 7 | finalize-blocked | step 6 §1 (active-pointer flip refused — non-link in place) |
|
|
19
|
+
| 8 | ecosystem-redirect | step 2 §3 ([I] Install at ecosystem-match gate — user opted to install the existing official skill instead of compiling a custom community skill) |
|
|
20
|
+
|
|
21
|
+
## Result Contract on HARD HALT
|
|
22
|
+
|
|
23
|
+
In addition to the success-variant result contract written by step 6 §3, every HARD HALT must surface an **error variant** so headless automators don't silently break when `quick-skill-result-latest.json` is missing on failed runs.
|
|
24
|
+
|
|
25
|
+
**Always (every HARD HALT, regardless of phase)** — emit a single line on **stderr**:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
SKF_QUICK_SKILL_RESULT_JSON: {"status":"error","exit_code":<N>,"phase":"<slug>","error":{"code":"<class>","message":"<short>"},"outputs":{},"summary":{},"skill_package":"<path-or-null>"}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
One line, no pretty-print. Matches the prefix-and-envelope convention used by `skf-emit-result-envelope.py`.
|
|
32
|
+
|
|
33
|
+
**Additionally, when `{skill_package}` is known** (HALT at step 5 §1 onward) — write the same JSON object (without the `SKF_QUICK_SKILL_RESULT_JSON: ` prefix) to disk:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
{skill_package}/quick-skill-result-{YYYYMMDD-HHmmss}.json
|
|
37
|
+
{skill_package}/quick-skill-result-latest.json (copy, not symlink)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
so consumers that hardcode the `-latest.json` path see a deterministic file even on failed runs. HALTs at step 1/02/03/04 cannot write to disk because `{skill_package}` is computed only in step 5 §1; for those, the stderr envelope plus exit code is the contract.
|
|
41
|
+
|
|
42
|
+
**Schema:**
|
|
43
|
+
|
|
44
|
+
| Field | Type | Notes |
|
|
45
|
+
| --------------- | -------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
46
|
+
| `status` | string | always `"error"` for HARD HALTs |
|
|
47
|
+
| `exit_code` | integer | matches the Exit Codes table above |
|
|
48
|
+
| `phase` | string | step slug where the HALT occurred (e.g. `resolve-target`, `compile`) |
|
|
49
|
+
| `error.code` | string | one of: `resolution-failure`, `write-failure`, `overwrite-cancelled`, `user-cancelled`, `finalize-blocked`, `ecosystem-redirect` |
|
|
50
|
+
| `error.message` | string | the user-facing message that was displayed |
|
|
51
|
+
| `error.details` | any | optional — phase-specific context (e.g. the failed file path) |
|
|
52
|
+
| `outputs` | object | empty `{}` on early HALTs; partial when files were already written |
|
|
53
|
+
| `summary` | object | empty `{}` on early HALTs |
|
|
54
|
+
| `skill_package` | string \| null | absolute path when known, `null` when HALT preceded step 5 §1 |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
# `shared/health-check.md` resolves relative to the SKF module root
|
|
3
3
|
# (`{project-root}/_bmad/skf/` when installed, `{project-root}/src/` during
|
|
4
|
-
# development),
|
|
4
|
+
# development), not relative to this step file.
|
|
5
5
|
nextStepFile: 'shared/health-check.md'
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -16,9 +16,8 @@ Chain to the shared workflow self-improvement health check at `{nextStepFile}`.
|
|
|
16
16
|
## Rules
|
|
17
17
|
|
|
18
18
|
- No user-facing reports, file writes, or result contracts in this step — those belong in step 6
|
|
19
|
-
- Delegate directly to `{nextStepFile}` with no additional commentary
|
|
20
|
-
- Do not attempt any other action between loading this step and executing `{nextStepFile}`
|
|
19
|
+
- Delegate directly to `{nextStepFile}` with no additional commentary or intervening action
|
|
21
20
|
|
|
22
|
-
##
|
|
21
|
+
## Steps
|
|
23
22
|
|
|
24
23
|
Load `{nextStepFile}`, read it fully, then proceed to execute it.
|
|
@@ -19,7 +19,7 @@ To read the resolved GitHub repository source and extract the public API surface
|
|
|
19
19
|
- Do not begin compilation or write output files
|
|
20
20
|
- If no exports found, use README content as fallback
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Steps
|
|
23
23
|
|
|
24
24
|
**Ref-aware source reading:** When `source_ref` is set from tag resolution (see step 1), append `?ref={source_ref}` to all GitHub API content and tree requests (e.g., `gh api repos/{owner}/{repo}/contents/{path}?ref={source_ref}`) to read from the tagged version. When using web browsing, use the tagged URL format (e.g., `github.com/{owner}/{repo}/blob/{source_ref}/{path}`). This ensures extraction reads from the same source version resolved during tag resolution.
|
|
25
25
|
|
|
@@ -57,7 +57,7 @@ Quick-skill is designed to wrap a library's public API. The compiled SKILL.md wi
|
|
|
57
57
|
Select: [C] Continue anyway · [A] Abort"
|
|
58
58
|
|
|
59
59
|
- **IF C** — log "user accepted `{shape}` shape" and proceed to §2. Set `extraction_inventory.repo_shape` to the detected shape so the result contract carries the signal for automators.
|
|
60
|
-
- **IF A** — HARD HALT with **exit code 3 (resolution-failure)** per the
|
|
60
|
+
- **IF A** — HARD HALT with **exit code 3 (resolution-failure)** per the exit-code map in `references/halt-contract.md`: "Aborted. `{shape}` repos are best wrapped manually with `/skf-create-skill` from a brief, not auto-extracted." Before exiting, emit the error result contract per `references/halt-contract.md` (`phase: "quick-extract"`, `error.code: "resolution-failure"`, `error.details: {repo_shape: "{shape}"}`, `skill_package: null`).
|
|
61
61
|
|
|
62
62
|
**GATE [default: C]** — In headless mode, log "headless: detected `{shape}` repo, continuing anyway" and proceed; the result contract's `summary.repo_shape` carries the signal so automators can flag low-quality outputs without re-parsing logs.
|
|
63
63
|
|
|
@@ -76,13 +76,13 @@ Fetch the manifest file and the top-level entry-point file(s) for the detected l
|
|
|
76
76
|
|
|
77
77
|
**If `scope_hint` provided:** focus the entry-point fetch on the specified directories instead of repo root.
|
|
78
78
|
|
|
79
|
-
For multi-module Maven (`<modules>`) and multi-project Gradle (`include(...)`) builds, fetch the parent manifest first, then loop §2+§3 per module.
|
|
79
|
+
For multi-module Maven (`<modules>`) and multi-project Gradle (`include(...)`) builds, fetch the parent manifest first, then loop §2+§3 per module. Batch the sub-module fetches per the parallel-fetch directive at the top of this step.
|
|
80
80
|
|
|
81
81
|
### 3. Parse Manifest and Scan Exports
|
|
82
82
|
|
|
83
83
|
Run the shared extractor against the contents fetched in §2. The helper does manifest parse + export scan in one invocation and emits a structured envelope ready to feed §4's inventory.
|
|
84
84
|
|
|
85
|
-
**Resolve `{publicApiExtractor}`** from `{publicApiExtractorProbeOrder}`; first existing path wins. If no candidate exists, fall back to in-prompt
|
|
85
|
+
**Resolve `{publicApiExtractor}`** from `{publicApiExtractorProbeOrder}`; first existing path wins. If no candidate exists, fall back to in-prompt per-language regex parsing of the manifest and entry-point files.
|
|
86
86
|
|
|
87
87
|
Build the input payload from §2's fetched files and pipe it to the helper:
|
|
88
88
|
|
|
@@ -129,7 +129,7 @@ extraction_inventory:
|
|
|
129
129
|
|
|
130
130
|
### 4.5. Zero-Exports Soft Gate (rescue mode)
|
|
131
131
|
|
|
132
|
-
Run this gate **only when** `extraction_inventory.exports.length == 0`
|
|
132
|
+
Run this gate **only when** `extraction_inventory.exports.length == 0` and `extraction_inventory.description` is empty (no usable README content either). When either is non-empty, the README-fallback in §4 produces a usable skill and this section is skipped.
|
|
133
133
|
|
|
134
134
|
When both are empty, the compiled SKILL.md would be effectively empty — no API surface to document and no description to fall back on. Offer the user a chance to retry with hints before producing a degenerate output:
|
|
135
135
|
|
|
@@ -146,7 +146,7 @@ Select: [R] Retry with new hints · [P] Proceed anyway (low-confidence skill) ·
|
|
|
146
146
|
|
|
147
147
|
- **IF R** — prompt for new `scope_hint` ("New scope hint (e.g. `src/server/`):") and optional new `language_hint` ("New language hint (or empty to keep `{language}`):"). Update the extraction context with the new hints, then **re-execute step 3 from §1** with the new values. Discards the prior empty inventory.
|
|
148
148
|
- **IF P** — log "user accepted zero-exports outcome" and proceed to §5. The compiled skill will be README-content-only with confidence `low`. Record `zero_exports_rescue: "user-accepted"` in the inventory so the result contract summary surfaces it.
|
|
149
|
-
- **IF A** — HARD HALT with **exit code 3 (resolution-failure)**: "Aborted. Run `/skf-create-skill` from a brief if you want a guided extraction with provenance tracking." Before exiting, emit the error result contract per
|
|
149
|
+
- **IF A** — HARD HALT with **exit code 3 (resolution-failure)**: "Aborted. Run `/skf-create-skill` from a brief if you want a guided extraction with provenance tracking." Before exiting, emit the error result contract per `references/halt-contract.md` (`phase: "quick-extract"`, `error.code: "resolution-failure"`, `error.details: {exports_found: 0, description_empty: true, language: "{language}", scope: "{scope_hint or 'entire repo'}"}`, `skill_package: null`).
|
|
150
150
|
|
|
151
151
|
**GATE [default: P]** — In headless mode, log "headless: zero exports + empty description, proceeding with low-confidence skill" and proceed; record `zero_exports_rescue: "auto-proceeded"` in the result contract summary so batch automators can re-queue these targets with stricter hints downstream. [P] preserves the pre-rescue behaviour for unattended pipelines.
|
|
152
152
|
|
|
@@ -164,16 +164,5 @@ Select: [R] Retry with new hints · [P] Proceed anyway (low-confidence skill) ·
|
|
|
164
164
|
|
|
165
165
|
### 6. Auto-Proceed to Compilation
|
|
166
166
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
- After extraction summary, immediately load, read entire file, then execute {nextStepFile}
|
|
170
|
-
|
|
171
|
-
#### EXECUTION RULES:
|
|
172
|
-
|
|
173
|
-
- This is an auto-proceed step — extraction results flow directly to compilation
|
|
174
|
-
- Proceed directly to next step after summary
|
|
175
|
-
|
|
176
|
-
## CRITICAL STEP COMPLETION NOTE
|
|
177
|
-
|
|
178
|
-
ONLY WHEN extraction is complete and extraction_inventory is assembled (even if minimal/low-confidence) will you load and read fully `{nextStepFile}` to execute compilation.
|
|
167
|
+
Once extraction_inventory is assembled (even if minimal or low-confidence), load and execute {nextStepFile} to compile.
|
|
179
168
|
|
|
@@ -70,26 +70,4 @@ Please provide the GitHub URL directly, or check:
|
|
|
70
70
|
|
|
71
71
|
**Hard halt** — cannot proceed without a resolved source.
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
After resolving to a GitHub repo, detect primary language from:
|
|
76
|
-
|
|
77
|
-
1. Manifest file presence:
|
|
78
|
-
- `package.json` → JavaScript/TypeScript
|
|
79
|
-
- `pyproject.toml` or `setup.py` → Python
|
|
80
|
-
- `Cargo.toml` → Rust
|
|
81
|
-
- `go.mod` → Go
|
|
82
|
-
- `pom.xml` or `build.gradle` → Java
|
|
83
|
-
2. User-provided language hint (overrides detection)
|
|
84
|
-
3. GitHub API language field (if accessible)
|
|
85
|
-
|
|
86
|
-
## Manifest File Priority
|
|
87
|
-
|
|
88
|
-
For each language, the primary manifest to read:
|
|
89
|
-
|
|
90
|
-
| Language | Manifest | Key Fields |
|
|
91
|
-
|----------|----------------|--------------------------------------------------------------------------|
|
|
92
|
-
| JS/TS | package.json | name, version, description, main, exports, dependencies |
|
|
93
|
-
| Python | pyproject.toml | project.name, project.version, project.description, project.dependencies |
|
|
94
|
-
| Rust | Cargo.toml | package.name, package.version, package.description, dependencies |
|
|
95
|
-
| Go | go.mod | module path, require list |
|
|
73
|
+
Language detection is authoritative in `resolve-target.md` §4 (Detect Language) — this file covers only the package-to-repo registry chain.
|