bmad-module-skill-forge 0.2.0 → 0.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.
Files changed (110) hide show
  1. package/README.md +88 -44
  2. package/docs/agents.md +1 -1
  3. package/docs/architecture.md +49 -20
  4. package/docs/examples.md +13 -2
  5. package/docs/getting-started.md +15 -13
  6. package/docs/index.md +3 -1
  7. package/docs/workflows.md +2 -2
  8. package/package.json +5 -3
  9. package/src/forger/forge-tier.yaml +1 -1
  10. package/src/forger/preferences.yaml +8 -1
  11. package/src/knowledge/doc-fetcher.md +55 -0
  12. package/src/knowledge/overview.md +17 -16
  13. package/src/knowledge/progressive-capability.md +9 -1
  14. package/src/knowledge/provenance-tracking.md +31 -23
  15. package/src/knowledge/qmd-registry.md +132 -0
  16. package/src/knowledge/skf-knowledge-index.csv +2 -0
  17. package/src/workflows/analyze-source/data/skill-brief-schema.md +24 -4
  18. package/src/workflows/analyze-source/steps-c/step-01-init.md +19 -9
  19. package/src/workflows/analyze-source/steps-c/step-01b-continue.md +2 -2
  20. package/src/workflows/analyze-source/steps-c/step-02-scan-project.md +10 -2
  21. package/src/workflows/analyze-source/steps-c/step-04-map-and-detect.md +17 -2
  22. package/src/workflows/analyze-source/steps-c/step-05-recommend.md +2 -1
  23. package/src/workflows/analyze-source/steps-c/step-06-generate-briefs.md +3 -3
  24. package/src/workflows/analyze-source/templates/analysis-report-template.md +1 -1
  25. package/src/workflows/analyze-source/validation-report.md +1 -1
  26. package/src/workflows/analyze-source/workflow-plan-analyze-source.md +1 -1
  27. package/src/workflows/analyze-source/workflow.md +1 -1
  28. package/src/workflows/audit-skill/steps-c/step-01-init.md +8 -5
  29. package/src/workflows/audit-skill/steps-c/step-02-re-index.md +12 -2
  30. package/src/workflows/audit-skill/validation-report.md +2 -2
  31. package/src/workflows/audit-skill/workflow-plan-audit-skill.md +1 -1
  32. package/src/workflows/brief-skill/data/scope-templates.md +60 -0
  33. package/src/workflows/brief-skill/data/skill-brief-schema.md +38 -3
  34. package/src/workflows/brief-skill/steps-c/step-01-gather-intent.md +20 -4
  35. package/src/workflows/brief-skill/steps-c/step-03-scope-definition.md +20 -64
  36. package/src/workflows/brief-skill/steps-c/step-04-confirm-brief.md +1 -1
  37. package/src/workflows/brief-skill/steps-c/step-05-write-brief.md +60 -5
  38. package/src/workflows/brief-skill/workflow.md +2 -1
  39. package/src/workflows/create-skill/data/compile-assembly-rules.md +110 -0
  40. package/src/workflows/create-skill/data/extraction-patterns.md +248 -0
  41. package/src/workflows/create-skill/data/skill-sections.md +79 -25
  42. package/src/workflows/create-skill/data/source-resolution-protocols.md +130 -0
  43. package/src/workflows/create-skill/steps-c/step-01-load-brief.md +7 -4
  44. package/src/workflows/create-skill/steps-c/step-02-ecosystem-check.md +10 -7
  45. package/src/workflows/create-skill/steps-c/step-03-extract.md +49 -9
  46. package/src/workflows/create-skill/steps-c/step-03b-fetch-temporal.md +238 -0
  47. package/src/workflows/create-skill/steps-c/step-03c-fetch-docs.md +220 -0
  48. package/src/workflows/create-skill/steps-c/step-04-enrich.md +40 -10
  49. package/src/workflows/create-skill/steps-c/step-05-compile.md +48 -81
  50. package/src/workflows/create-skill/steps-c/step-06-validate.md +149 -63
  51. package/src/workflows/create-skill/steps-c/step-07-generate-artifacts.md +53 -3
  52. package/src/workflows/create-skill/steps-c/step-08-report.md +1 -1
  53. package/src/workflows/create-skill/workflow-plan-create-skill.md +42 -10
  54. package/src/workflows/create-skill/workflow.md +3 -2
  55. package/src/workflows/create-stack-skill/data/stack-skill-template.md +20 -7
  56. package/src/workflows/create-stack-skill/steps-c/step-01-init.md +2 -2
  57. package/src/workflows/create-stack-skill/steps-c/step-04-parallel-extract.md +14 -0
  58. package/src/workflows/create-stack-skill/steps-c/step-06-compile-stack.md +28 -7
  59. package/src/workflows/create-stack-skill/steps-c/step-07-generate-output.md +10 -7
  60. package/src/workflows/create-stack-skill/steps-c/step-08-validate.md +66 -68
  61. package/src/workflows/create-stack-skill/validation-report.md +1 -1
  62. package/src/workflows/create-stack-skill/workflow-plan-create-stack-skill.md +4 -4
  63. package/src/workflows/export-skill/data/managed-section-format.md +1 -0
  64. package/src/workflows/export-skill/data/snippet-format.md +33 -14
  65. package/src/workflows/export-skill/steps-c/step-01-load-skill.md +16 -2
  66. package/src/workflows/export-skill/steps-c/step-03-generate-snippet.md +29 -22
  67. package/src/workflows/export-skill/steps-c/step-04-update-context.md +1 -1
  68. package/src/workflows/export-skill/steps-c/step-05-token-report.md +1 -1
  69. package/src/workflows/export-skill/validation-report.md +1 -1
  70. package/src/workflows/export-skill/workflow-plan-export-skill.md +8 -8
  71. package/src/workflows/quick-skill/data/skill-template.md +27 -7
  72. package/src/workflows/quick-skill/steps-c/step-04-compile.md +44 -13
  73. package/src/workflows/quick-skill/steps-c/step-05-validate.md +79 -16
  74. package/src/workflows/quick-skill/validation-report.md +4 -4
  75. package/src/workflows/quick-skill/workflow-plan-quick-skill.md +4 -4
  76. package/src/workflows/quick-skill/workflow.md +2 -0
  77. package/src/workflows/setup-forge/steps-c/step-01-detect-and-tier.md +12 -3
  78. package/src/workflows/setup-forge/steps-c/step-02-write-config.md +10 -2
  79. package/src/workflows/setup-forge/steps-c/step-03-auto-index.md +111 -40
  80. package/src/workflows/setup-forge/steps-c/step-04-report.md +13 -0
  81. package/src/workflows/setup-forge/workflow.md +1 -0
  82. package/src/workflows/test-skill/data/scoring-rules.md +14 -6
  83. package/src/workflows/test-skill/data/source-access-protocol.md +37 -0
  84. package/src/workflows/test-skill/steps-c/step-01-init.md +38 -13
  85. package/src/workflows/test-skill/steps-c/step-02-detect-mode.md +2 -3
  86. package/src/workflows/test-skill/steps-c/step-03-coverage-check.md +25 -5
  87. package/src/workflows/test-skill/steps-c/step-04-coherence-check.md +18 -43
  88. package/src/workflows/test-skill/steps-c/step-04b-external-validators.md +213 -0
  89. package/src/workflows/test-skill/steps-c/step-05-score.md +24 -27
  90. package/src/workflows/test-skill/steps-c/step-06-report.md +9 -4
  91. package/src/workflows/test-skill/templates/test-report-template.md +2 -1
  92. package/src/workflows/test-skill/validation-report.md +1 -1
  93. package/src/workflows/test-skill/workflow-plan-test-skill.md +7 -3
  94. package/src/workflows/test-skill/workflow.md +1 -1
  95. package/src/workflows/update-skill/data/remote-source-resolution.md +43 -0
  96. package/src/workflows/update-skill/steps-c/step-01-init.md +13 -7
  97. package/src/workflows/update-skill/steps-c/step-02-detect-changes.md +26 -0
  98. package/src/workflows/update-skill/steps-c/step-03-re-extract.md +37 -9
  99. package/src/workflows/update-skill/steps-c/step-04-merge.md +3 -3
  100. package/src/workflows/update-skill/steps-c/step-05-validate.md +63 -67
  101. package/src/workflows/update-skill/steps-c/step-06-write.md +37 -14
  102. package/src/workflows/update-skill/steps-c/step-07-report.md +1 -1
  103. package/src/workflows/update-skill/validation-report.md +4 -4
  104. package/src/workflows/update-skill/workflow-plan-update-skill.md +4 -4
  105. package/src/workflows/update-skill/workflow.md +1 -1
  106. package/tools/cli/commands/status.js +4 -4
  107. package/tools/cli/commands/uninstall.js +1 -1
  108. package/tools/cli/commands/update.js +2 -2
  109. package/tools/cli/lib/ui.js +60 -16
  110. package/tools/cli/lib/version-check.js +2 -2
@@ -61,3 +61,251 @@ Same extraction as Forge tier. Deep tier adds enrichment in step-04, not extract
61
61
  ### Confidence
62
62
  - Extraction: same as Forge (T1)
63
63
  - Enrichment annotations added in step-04: T2
64
+
65
+ ---
66
+
67
+ ## AST Extraction Protocol
68
+
69
+ When AST tools are available (Forge/Deep tier), follow this deterministic protocol to prevent output overflow on large codebases.
70
+
71
+ **"Files in scope"** = files remaining after applying `include_patterns` and `exclude_patterns` from the brief, filtered by the target language extension. This is NOT the total repository file count from step-01's tree listing. Use the filtered count from step-03 section 2 as the decision tree input.
72
+
73
+ ### Decision Tree
74
+
75
+ Apply the first matching condition:
76
+
77
+ ```
78
+ Files in scope ≤ 100
79
+ → Use ast-grep MCP tool: find_code(pattern, max_results=100, output_format="text")
80
+ → Parse compact text output directly into extraction inventory
81
+
82
+ Files in scope 101–500
83
+ → Use ast-grep MCP tool: find_code_by_rule(yaml, max_results=150, output_format="text")
84
+ → Use scoped YAML rules (see recipes below) to filter at the AST level
85
+ → Parse compact text output into extraction inventory
86
+
87
+ Files in scope > 500
88
+ → CLI streaming fallback: ast-grep --json=stream + line-by-line Python processing
89
+ → Process in directory batches, cap per-batch output
90
+ → Merge batch results into extraction inventory
91
+ ```
92
+
93
+ ### Safety Valve
94
+
95
+ If any ast-grep operation (MCP or CLI) visibly causes a timeout, returns an error related to output size, or produces unexpectedly large output: immediately switch to the CLI streaming fallback with `--json=stream`. Do not retry the same approach. When falling back to the CLI streaming template, inject the brief's `scope.exclude` patterns into the `EXCLUDES` list (use `[]` if absent) — this applies regardless of which path triggered the fallback. Note: `max_results` in the MCP tool and `| head -N` in the CLI path provide hard caps, but this safety valve covers cases where the upstream tool itself fails before returning results (e.g., OOM during JSON serialization).
96
+
97
+ ### MCP Tool Usage (Preferred)
98
+
99
+ **Simple pattern search:**
100
+
101
+ ```
102
+ find_code(
103
+ project_folder="{source_path}",
104
+ pattern="async def $NAME($$$PARAMS)",
105
+ language="python",
106
+ max_results=100,
107
+ output_format="text"
108
+ )
109
+ ```
110
+
111
+ **Scoped YAML rule search (for larger repos):**
112
+
113
+ ```
114
+ find_code_by_rule(
115
+ project_folder="{source_path}",
116
+ yaml="id: public-api\nlanguage: python\nrule:\n pattern: 'def $NAME($$$PARAMS)'\n inside:\n kind: module\n stopBy: end\nconstraints:\n NAME:\n regex: '^[^_]'",
117
+ max_results=150,
118
+ output_format="text"
119
+ )
120
+ ```
121
+
122
+ ### CLI Streaming Fallback
123
+
124
+ When MCP tools are unavailable or the repo exceeds 500 files in scope, use `--json=stream` (NEVER `--json` or `--json=pretty`) with line-by-line Python processing:
125
+
126
+ ```bash
127
+ # Note: use $$$ for variadic params in ast-grep patterns (e.g., 'def $NAME($$$PARAMS)')
128
+ # {exclude_patterns} = Python list from brief's scope.exclude, e.g. ['tests/**', '**/test_*']
129
+ # If scope.exclude is absent or empty in the brief, inject [] as the default.
130
+ # Patterns are matched against the full file path as emitted by ast-grep.
131
+ # Ensure paths are relative to the same root as the patterns (strip ./ prefix if needed).
132
+ ast-grep -p '{pattern}' -l {language} --json=stream {path} | python3 -c "
133
+ import sys, json, fnmatch
134
+
135
+ EXCLUDES = {exclude_patterns}
136
+
137
+ for line in sys.stdin:
138
+ try:
139
+ m = json.loads(line)
140
+ f = m.get('file','')
141
+ if EXCLUDES and any(fnmatch.fnmatch(f, pat) for pat in EXCLUDES):
142
+ continue
143
+ v = m.get('metaVariables',{})
144
+ name = v.get('single',{}).get('NAME',{}).get('text','')
145
+ if name and not name.startswith('_'):
146
+ ln = m.get('range',{}).get('start',{}).get('line',0)+1
147
+ sig = m.get('text','').split(chr(10))[0].strip()
148
+ print(f'[AST:{f}:L{ln}] {sig}')
149
+ except: pass
150
+ " | head -200
151
+ ```
152
+
153
+ **Critical constraints:**
154
+
155
+ - ALWAYS use `--json=stream` — never `--json` (loads entire array into memory)
156
+ - ALWAYS process line-by-line (`for line in sys.stdin`) — never `json.load(sys.stdin)`
157
+ - ALWAYS cap output with `| head -N` as a safety valve
158
+ - For repos > 500 files, process in directory batches of 20-50 files each
159
+
160
+ ### YAML Rule Recipes by Language
161
+
162
+ **Python — public functions:**
163
+
164
+ ```yaml
165
+ id: python-public-functions
166
+ language: python
167
+ rule:
168
+ pattern: 'def $NAME($$$PARAMS)'
169
+ inside:
170
+ kind: module
171
+ stopBy: end
172
+ constraints:
173
+ NAME:
174
+ regex: '^[^_]'
175
+ ```
176
+
177
+ **Python — public classes:**
178
+
179
+ ```yaml
180
+ id: python-public-classes
181
+ language: python
182
+ rule:
183
+ pattern: 'class $NAME($$$BASES)'
184
+ inside:
185
+ kind: module
186
+ stopBy: end
187
+ constraints:
188
+ NAME:
189
+ regex: '^[^_]'
190
+ ```
191
+
192
+ **JavaScript/TypeScript — exported functions:**
193
+
194
+ ```yaml
195
+ id: js-exported-functions
196
+ language: typescript
197
+ rule:
198
+ pattern: 'export function $NAME($$$PARAMS)'
199
+ ```
200
+
201
+ **JavaScript/TypeScript — exported constants:**
202
+
203
+ ```yaml
204
+ id: js-exported-constants
205
+ language: typescript
206
+ rule:
207
+ pattern: 'export const $NAME = $VALUE'
208
+ ```
209
+
210
+ **Rust — public functions:**
211
+
212
+ ```yaml
213
+ id: rust-public-functions
214
+ language: rust
215
+ rule:
216
+ any:
217
+ - pattern: 'pub fn $NAME($$$PARAMS) -> $RET'
218
+ - pattern: 'pub fn $NAME($$$PARAMS)'
219
+ ```
220
+
221
+ **Go — exported functions (capitalized):**
222
+
223
+ ```yaml
224
+ id: go-exported-functions
225
+ language: go
226
+ rule:
227
+ pattern: 'func $NAME($$$PARAMS) $RET'
228
+ constraints:
229
+ NAME:
230
+ regex: '^[A-Z]'
231
+ ```
232
+
233
+ ### Re-Export Tracing
234
+
235
+ After initial AST extraction, some top-level exports may resolve to **module imports** rather than direct function definitions. This is common in Python libraries that use `__init__.py` re-exports for a clean public API.
236
+
237
+ **Detection heuristic:** For each top-level export from `__init__.py` (or equivalent entry point), check if the import path resolves to a directory (contains `__init__.py`) rather than a `.py` file with a matching `def` or `class`. If the initial AST scan found no function/class definition for a known public export, it is likely a module re-export.
238
+
239
+ **Tracing protocol:**
240
+
241
+ 1. Read the entry point file (e.g., `{package}/__init__.py`) and extract all `from .X import Y` statements
242
+ 2. For each import where Y was NOT found by the initial AST scan:
243
+ - Check if the import path resolves to a directory (e.g., `{package}/api/v1/delete/` exists with `__init__.py`)
244
+ - If directory: read its `__init__.py` to find the actual re-exported symbol
245
+ - Trace the symbol to its definition file and run AST extraction on that file
246
+ 3. Cite the actual definition location: `[AST:{definition_file}:L{line}]`
247
+
248
+ **Examples:**
249
+
250
+ ```python
251
+ # Module re-export — follow required
252
+ from .api.v1.delete import delete # delete/ is a directory → read delete/__init__.py
253
+
254
+ # Direct function import — no follow needed
255
+ from .api.v1.add.add import add # add.py exists with def add()
256
+ ```
257
+
258
+ **Unresolvable imports:** If the import statement is a star-import (`from .X import *`) or a conditional import (`try`/`except`), the symbol cannot be reliably traced via this protocol. Record it with `[SRC:{package}/__init__.py:L{line}]` (T1-low) and a note: "star/conditional import — manual trace required."
259
+
260
+ **Scope limit:** Only trace re-exports for symbols listed in the top-level entry point's public API. Do not recursively trace beyond one level of `__init__.py` indirection. If a re-export cannot be resolved after one level, record it with a `[SRC:{package}/__init__.py:L{line}]` citation (T1-low) from the import statement itself.
261
+
262
+ **Other languages:** JS/TS barrel files (`index.ts` with `export { X } from './module'`) follow the same principle — trace the re-export to the definition file. Rust `pub use` and Go package-level re-exports are less common but follow the same heuristic when encountered.
263
+
264
+ ---
265
+
266
+ ## Tier Degradation Rules
267
+
268
+ ### Remote Source at Forge/Deep Tier
269
+
270
+ When `source_repo` is a remote URL (GitHub URL or owner/repo format) and the tier is Forge or Deep:
271
+
272
+ - **ast-grep requires local files** — it cannot operate on remote URLs
273
+
274
+ **Ephemeral clone strategy (preferred):**
275
+
276
+ 1. Check `git` availability (`git --version`). `git` is effectively guaranteed at Deep tier (via `gh` dependency) but NOT guaranteed at Forge tier.
277
+ 2. If `git` is available: perform an ephemeral shallow clone to a system temp path (`{system_temp}/skf-ephemeral-{skill-name}-{timestamp}/`).
278
+ 3. For create-skill: use `--depth 1 --single-branch --filter=blob:none`; if `include_patterns` are specified, apply mode selection: if `exclude_patterns` are absent, use cone mode (convert include_patterns to directory roots; use `--skip-checks` for individual file paths); if `exclude_patterns` are present, use `--no-cone` mode (pass gitignore-style patterns with `!`-prefixed excludes — includes first, then negations). See source-resolution-protocols.md for the full conversion rules.
279
+ 4. For update-skill: use sparse-checkout with `--skip-checks` scoped to the changed files from the change manifest only (file paths require `--skip-checks`). No `--branch` flag — uses the remote default branch (must match the branch used during original create-skill run).
280
+ 5. If clone succeeds: use the local clone path for AST extraction. All results are T1 with `[AST:...]` citations.
281
+ 6. Cleanup: delete the temp directory after extraction inventory is built and all data is in context. The clone never persists beyond the extraction step.
282
+
283
+ **Fallback (clone fails or `git` unavailable):**
284
+
285
+ - The extraction step MUST warn the user explicitly before degrading
286
+ - **create-skill:** Warning must include actionable guidance — clone locally and update `source_repo` in the brief to the local path
287
+ - **update-skill:** Warning must include actionable guidance — clone locally, re-run [CS] Create Skill with the local path to regenerate provenance data, then re-run the update
288
+ - Extraction proceeds using Quick tier strategy (source reading via gh_bridge)
289
+ - All results labeled T1-low with `[SRC:...]` citations
290
+ - The degradation reason is recorded in the evidence report
291
+
292
+ Silent degradation is **forbidden**. The user must always know when AST extraction was skipped and why.
293
+
294
+ ### AST Tool Unavailable at Forge/Deep Tier
295
+
296
+ When the tier is Forge or Deep but ast-grep is not functional:
297
+
298
+ - The extraction step MUST warn the user explicitly before degrading
299
+ - Warning must include actionable guidance: run [SF] Setup Forge to detect tools
300
+ - Extraction proceeds using Quick tier strategy
301
+ - All results labeled T1-low
302
+ - The degradation reason is recorded in the evidence report
303
+
304
+ ### Per-File AST Failure
305
+
306
+ When ast-grep fails on an individual file (parse error, unsupported syntax):
307
+
308
+ - Fall back to source reading for **that file only**
309
+ - Other files continue with AST extraction
310
+ - The affected file's results are labeled T1-low; unaffected files retain T1
311
+ - Log a warning noting which file degraded and why
@@ -2,30 +2,60 @@
2
2
 
3
3
  ## agentskills.io Compliant Format
4
4
 
5
- ### Frontmatter (Required)
5
+ ### Frontmatter (Required — agentskills.io Compliance)
6
6
 
7
7
  ```yaml
8
8
  ---
9
9
  name: {skill-name}
10
- version: {source-version}
11
- description: {skill-name} {export-count} verified functions
12
- author: {source-author}
10
+ description: >
11
+ {Trigger-optimized description of what the skill does and when to use it.
12
+ Include specific keywords for agent discovery.
13
+ Mention what NOT to use it for if applicable.
14
+ 1-1024 characters.}
13
15
  ---
14
16
  ```
15
17
 
16
- ### Section Order
18
+ **Frontmatter rules (agentskills.io specification):**
17
19
 
18
- 1. **Overview** What this skill provides, source repo, version, tier used
19
- 2. **Quick Start** Most common 3-5 functions with minimal examples
20
- 3. **API Reference** Grouped by module/file, each function with:
21
- - Signature with types
22
- - Parameters table
23
- - Return type
24
- - Usage example (from source tests/docs if available)
25
- - Provenance citation: `[AST:{file}:L{line}]` or `[SRC:{file}:L{line}]`
26
- 4. **Type Definitions** — Exported types, interfaces, enums
27
- 5. **Integration Patterns**Co-import patterns detected by ast_bridge (Forge/Deep only)
28
- 6. **Manual Sections** — Seeded with `<!-- [MANUAL] -->` markers for update-skill
20
+ - `name`: 1-64 characters, lowercase alphanumeric + hyphens only, must match parent directory name
21
+ - `description`: 1-1024 characters, trigger-optimized for agent matching
22
+ - Only 6 fields permitted: `name`, `description`, `license`, `compatibility`, `metadata`, `allowed-tools`
23
+ - `version` and `author` belong in metadata.json, NOT in frontmatter
24
+
25
+ ### Two-Tier Section Structure
26
+
27
+ SKILL.md uses a two-tier structure to ensure actionable content survives `split-body` extraction.
28
+
29
+ #### Tier 1Always Inline (survives split-body, target <300 lines)
30
+
31
+ | # | Section | Budget | Purpose |
32
+ |---|---------|--------|---------|
33
+ | 1 | **Overview** | ~10 lines | What the library does, source repo, version, tier, export count |
34
+ | 2 | **Quick Start** | ~30 lines | 3-5 core functions with one runnable end-to-end example |
35
+ | 3 | **Common Workflows** | ~30 lines | 4-5 typical function call sequences for common tasks |
36
+ | 4 | **Key API Summary** | ~20 lines | Table of top 10-15 functions (name, purpose, key params) |
37
+ | 4b | **Migration & Deprecation Warnings** | ~10 lines | T2-future warnings inline (Deep tier only, skip if none) |
38
+ | 5 | **Key Types** | ~20 lines | Most important enum/type values inline |
39
+ | 6 | **Architecture at a Glance** | ~10 lines | Bullet list of subsystem categories |
40
+ | 7 | **CLI** | ~10 lines | Basic CLI commands (skip if no CLI) |
41
+ | 8 | **Manual Sections** | ~5 lines | `<!-- [MANUAL] -->` markers for update-skill |
42
+
43
+ #### Tier 2 — Reference-Eligible (extracted by split-body into references/)
44
+
45
+ | # | Section | Purpose |
46
+ |---|---------|---------|
47
+ | 9 | **Full API Reference** | Complete signatures, parameter tables, return types, examples, citations |
48
+ | 10 | **Full Type Definitions** | All types, interfaces, enums with full field details |
49
+ | 11 | **Full Integration Patterns** | Co-import patterns, adapter details, pipeline internals (Forge/Deep only) |
50
+
51
+ #### Assembly Rules
52
+
53
+ - Tier 1 sections are assembled first — they form the standalone body
54
+ - Tier 2 sections are assembled after — they are progressive disclosure detail
55
+ - Tier 1 sections are kept short enough that `split-body` targets the larger Tier 2 sections (`## Full` headings) into `references/`
56
+ - After split-body, SKILL.md retains all Tier 1 content — actionable without loading references
57
+ - An agent loading only SKILL.md (no references) must get enough to act
58
+ - **Section 4b (Migration & Deprecation Warnings)** is conditional: only emitted for Deep tier when T2-future annotations exist. Quick/Forge tiers and Deep tiers without T2-future annotations omit it entirely (no empty section). Parsers and validators must treat this section as optional.
29
59
 
30
60
  ### Provenance Citation Format
31
61
 
@@ -50,15 +80,31 @@ Place after Quick Start and after API Reference sections.
50
80
 
51
81
  ---
52
82
 
53
- ## context-snippet.md Format
83
+ ## context-snippet.md Format (Vercel-aligned indexed format)
54
84
 
55
- Compressed 2-line-per-skill format for CLAUDE.md managed section:
85
+ Indexed pipe-delimited format for CLAUDE.md managed section (~80-120 tokens per skill). Aligned with Vercel's research finding that retrieval instructions + indexed file maps + inline gotchas dramatically improve agent performance.
56
86
 
57
87
  ```markdown
58
- {skill-name} -> skills/{skill-name}/
59
- exports: {comma-separated top 10 function names}
88
+ [{skill-name} v{version}]|root: skills/{skill-name}/
89
+ |IMPORTANT: {skill-name} v{version} read SKILL.md before writing {skill-name} code. Do NOT rely on training data.
90
+ |quick-start:{SKILL.md#quick-start}
91
+ |api: {top exports with () for functions, comma-separated}
92
+ |key-types:{SKILL.md#key-types} — {inline summary of most important type values}
93
+ |gotchas: {2-3 most critical pitfalls or breaking changes, inline}
60
94
  ```
61
95
 
96
+ ### Format rules
97
+
98
+ - **Line 1:** Skill name + version + root path — version signals training data staleness
99
+ - **Line 2 (IMPORTANT):** Retrieval instruction — always present, tells agent to read SKILL.md before acting
100
+ - **Lines 3+:** Pipe-delimited index mapping topics to SKILL.md sections (with `#anchor` pointers)
101
+ - **Inline content:** Each index line includes a brief inline summary (~10 words) so the agent can decide whether to read the full section
102
+ - **gotchas line:** 2-3 most critical pitfalls inline — prevents mistakes without requiring a file read
103
+ - **Token budget:** ~80-120 tokens per skill (justified by Vercel's finding that indexed format maintains performance at 80% compression)
104
+ - **T1-now content only** — no T2 annotations in the snippet
105
+ - **Section anchors** (`#quick-start`, `#key-types`) must match actual SKILL.md heading slugs
106
+ - **Version** comes from source detection (per issue #32), not brief default
107
+
62
108
  ---
63
109
 
64
110
  ## metadata.json Structure
@@ -67,13 +113,15 @@ Compressed 2-line-per-skill format for CLAUDE.md managed section:
67
113
  {
68
114
  "name": "{skill-name}",
69
115
  "version": "{source-version}",
70
- "skill_type": "individual",
116
+ "skill_type": "single",
71
117
  "source_authority": "{official|community|internal}",
72
118
  "source_repo": "{github-url}",
119
+ "source_root": "{resolved-source-path}",
73
120
  "source_commit": "{commit-hash}",
74
- "forge_tier": "{quick|forge|deep}",
121
+ "confidence_tier": "{Quick|Forge|Deep}",
75
122
  "spec_version": "1.3",
76
- "generated_at": "{ISO-8601}",
123
+ "generation_date": "{ISO-8601}",
124
+ "exports": [],
77
125
  "tool_versions": {
78
126
  "ast_grep": "{version-or-null}",
79
127
  "qmd": "{version-or-null}",
@@ -81,8 +129,11 @@ Compressed 2-line-per-skill format for CLAUDE.md managed section:
81
129
  },
82
130
  "stats": {
83
131
  "exports_documented": 0,
132
+ "exports_public_api": 0,
133
+ "exports_internal": 0,
84
134
  "exports_total": 0,
85
- "coverage": 0.0,
135
+ "public_api_coverage": 0.0,
136
+ "total_coverage": 0.0,
86
137
  "confidence_t1": 0,
87
138
  "confidence_t2": 0,
88
139
  "confidence_t3": 0
@@ -125,7 +176,10 @@ Each reference file includes:
125
176
  "generated_at": "{ISO-8601}",
126
177
  "entries": [
127
178
  {
128
- "claim": "getToken accepts userId and optional TokenOptions",
179
+ "export_name": "getToken",
180
+ "export_type": "function",
181
+ "params": ["userId: string", "options?: TokenOptions"],
182
+ "return_type": "Token",
129
183
  "source_file": "src/auth/index.ts",
130
184
  "source_line": 42,
131
185
  "confidence": "T1",
@@ -0,0 +1,130 @@
1
+ # Source Resolution Protocols
2
+
3
+ ## Remote Source Resolution (Forge/Deep only)
4
+
5
+ If `source_repo` is a local path: proceed with the tier-appropriate strategy as normal.
6
+
7
+ If `source_repo` is a remote URL (GitHub URL or owner/repo format) AND tier is Forge or Deep:
8
+
9
+ 1. **Check `git` availability:** Verify `git` is functional (`git --version`). If `git` is not available, skip to the fallback warning below.
10
+
11
+ 2. **Ephemeral shallow clone:** Clone the repository to a system temp path for AST access:
12
+
13
+ ```
14
+ temp_path = {system_temp}/skf-ephemeral-{skill-name}-{timestamp}/
15
+ git clone --depth 1 --branch {branch} --single-branch --filter=blob:none {source_repo} {temp_path}
16
+ ```
17
+
18
+ **If `include_patterns` are NOT specified:**
19
+
20
+ ```
21
+ git clone --depth 1 --branch {branch} --single-branch --filter=blob:none {source_repo} {temp_path}
22
+ ```
23
+
24
+ **If `include_patterns` ARE specified**, use sparse-checkout to limit the clone scope:
25
+
26
+ ```
27
+ git clone --depth 1 --branch {branch} --single-branch --filter=blob:none --sparse {source_repo} {temp_path}
28
+ ```
29
+
30
+ **Mode selection:** Choose sparse-checkout mode based on whether `exclude_patterns` exist:
31
+
32
+ - **No `exclude_patterns`:** Use default **cone mode** (faster). Convert `include_patterns` to directory roots.
33
+ - **`exclude_patterns` present:** Use **`--no-cone` mode** which supports gitignore-style negation patterns (`!` prefix). This applies both include and exclude at the git level, avoiding unnecessary blob downloads.
34
+
35
+ **Cone mode (no exclude patterns):**
36
+
37
+ **IMPORTANT:** `git sparse-checkout set` expects **directories**, not glob patterns. Convert `include_patterns` before passing them:
38
+
39
+ **Classification rule:** A pattern is an **individual file** if it contains no glob characters (`*`, `?`, `[`) AND does not end with `/`. Everything else is a glob — strip it to its directory root (the path prefix before the first glob character or wildcard segment).
40
+
41
+ - Strip glob suffixes to directory roots (e.g., `src/core/**/*.py` → `src/core`, `src/api/*.ts` → `src/api`)
42
+ - Deduplicate the resulting directory list
43
+ - Individual files (e.g., `pyproject.toml`, `src/utils/helpers.py`) are kept as-is
44
+
45
+ **If only directory roots (no individual files):**
46
+
47
+ ```
48
+ git -C {temp_path} sparse-checkout set {converted_directory_roots}
49
+ ```
50
+
51
+ **If any individual files are present (or mixed):**
52
+
53
+ ```
54
+ git -C {temp_path} sparse-checkout set --skip-checks {converted_directory_roots} {individual_files}
55
+ ```
56
+
57
+ Example transformation:
58
+ ```
59
+ Brief include_patterns: sparse-checkout args:
60
+ src/core/**/*.py → src/core (directory root)
61
+ src/api/*.ts → src/api (directory root)
62
+ examples/**/*.py → examples (directory root)
63
+ pyproject.toml → pyproject.toml (individual file, needs --skip-checks)
64
+ src/utils/helpers.py → src/utils/helpers.py (individual file, needs --skip-checks)
65
+ ```
66
+
67
+ **No-cone mode (exclude patterns present):**
68
+
69
+ When `exclude_patterns` exist, use `--no-cone` mode to pass both include and exclude patterns directly as gitignore-style rules:
70
+
71
+ 1. Convert `include_patterns` to gitignore-style patterns. If a pattern contains no glob characters (`*`, `?`, `[`) and does not end with `/`, append `/**` to match directory contents recursively (e.g., `cognee` → `cognee/**`; `cognee/**` → kept as-is).
72
+ 2. Convert `exclude_patterns` to negation patterns by prepending `!`. Apply the same anchoring rule (e.g., `cognee/tests` → `!cognee/tests/**`; `cognee/tests/**` → `!cognee/tests/**`; `**/test_*` → `!**/test_*`).
73
+ 3. **CRITICAL:** List all include patterns BEFORE negated exclude patterns — git processes patterns in order and a negation can only suppress a prior inclusion.
74
+ 4. Pass to sparse-checkout — include patterns first, then negated exclude patterns:
75
+
76
+ ```
77
+ git -C {temp_path} sparse-checkout set --no-cone {include_gitignore_patterns} {negated_exclude_patterns}
78
+ ```
79
+
80
+ Example transformation:
81
+ ```
82
+ Brief include_patterns: Brief exclude_patterns:
83
+ cognee/** cognee/tests/**
84
+ cognee/alembic/**
85
+ **/test_*
86
+
87
+ sparse-checkout args (--no-cone):
88
+ 'cognee/**' '!cognee/tests/**' '!cognee/alembic/**' '!**/test_*'
89
+ ```
90
+
91
+ **Note:** `--no-cone` mode is slower than cone mode for very large repositories but eliminates downloading excluded blobs entirely.
92
+
93
+ **Post-checkout filtering:**
94
+
95
+ After checkout, apply the original glob `include_patterns` as file-level filters when building the extraction file list — sparse-checkout gets the right directories, glob filtering narrows to the exact files. When `--no-cone` mode was used, most exclude filtering is already done at the git level, but apply `exclude_patterns` as a final pass to catch any edge cases where gitignore pattern matching diverges from the brief's glob semantics.
96
+
97
+ 3. **If clone succeeds:** Update the working source path to `{temp_path}` for all subsequent AST operations in this step. Proceed with the **Forge/Deep Tier** extraction strategy below. Mark `ephemeral_clone_active = true` for cleanup.
98
+
99
+ 4. **If clone fails (network error, auth failure, timeout):**
100
+
101
+ ⚠️ **Warn the user explicitly:**
102
+
103
+ "Ephemeral clone of `{source_repo}` failed: {error}. Degrading to source reading (T1-low) for this run. For T1 (AST-verified) confidence, clone the repository locally and update `source_repo` in your brief to the local path."
104
+
105
+ Proceed with Quick tier extraction strategy below. Note the degradation reason in context for the evidence report.
106
+
107
+ **Ephemeral clone cleanup:** After extraction is complete for all files in scope (whether successful or partially failed), before presenting the Gate 2 summary (Section 6), if `ephemeral_clone_active`, delete the `{temp_path}` directory. Log: "Ephemeral source clone cleaned up." This ensures cleanup runs even if some extractions failed, as long as the step itself is still executing.
108
+
109
+ ---
110
+
111
+ ## Version Reconciliation (all tiers, source mode only)
112
+
113
+ **If `source_type: "docs-only"`:** skip this section — no source files exist to reconcile.
114
+
115
+ After the source path is accessible (local path from step-01, or ephemeral clone from above), check whether the source contains a version identifier and reconcile it with `brief.version`. Look for the first matching version file in the resolved source path:
116
+
117
+ - Python: `pyproject.toml` (`[project] version`), `setup.py` (`version=`), `__version__` in `__init__.py`
118
+ - JavaScript/TypeScript: `package.json` (`"version"`)
119
+ - Rust: `Cargo.toml` (`[package] version`)
120
+ - Go: `go.mod` (module version if tagged)
121
+
122
+ **If a source version is found AND it differs from `brief.version`:**
123
+
124
+ ⚠️ Warn the user: "Brief version ({brief.version}) differs from source version ({source_version}). Using source version ({source_version})."
125
+
126
+ Update the working version in context to the source version. Record the mismatch in context for the evidence report (step-08).
127
+
128
+ **If no version file is found or version cannot be extracted:** keep `brief.version` as-is. No warning needed.
129
+
130
+ **If source is remote and accessed via Quick tier (gh_bridge, no local files):** attempt to read the version file via `gh_bridge.read_file(owner, repo, "{version_file}")` for the primary version file of the detected language. If the read fails, keep `brief.version`.
@@ -63,9 +63,8 @@ Halt with: "Forge halted: No forge configuration found. Run [SF] Setup Forge fir
63
63
  Extract and report:
64
64
  - `tier`: Quick, Forge, or Deep
65
65
  - `tools`: which tools are available (gh, ast-grep, qmd)
66
- - `tier_override`: if set, use override tier instead of detected
67
66
 
68
- Check for `tier_override` in `{preferencesFile}`. If `tier_override` is set and differs from detected tier, use the override value.
67
+ **Apply tier override:** Read `{preferencesFile}`. If `tier_override` is set and is a valid tier value (Quick, Forge, or Deep), use it instead of the detected tier.
69
68
 
70
69
  ### 2. Discover Skill Brief
71
70
 
@@ -89,17 +88,21 @@ Check that the loaded skill-brief.yaml contains required fields:
89
88
  **Required fields:**
90
89
  - `name` — skill identifier (kebab-case)
91
90
  - `version` — source version to compile against
92
- - `source_repo` — GitHub owner/repo or local path
91
+ - `source_repo` — GitHub owner/repo or local path (**optional when `source_type: "docs-only"`**)
93
92
  - `language` — primary source language
94
93
  - `scope` — what to extract (e.g., "all public exports", specific modules)
95
94
 
96
95
  **Optional fields:**
96
+ - `source_type` — `"source"` (default) or `"docs-only"` (external documentation only)
97
+ - `doc_urls` — array of `{url, label}` documentation URLs (required when `source_type: "docs-only"`)
97
98
  - `source_branch` — branch to use (default: main/master)
98
- - `source_authority` — official/community/internal (default: community)
99
+ - `source_authority` — official/community/internal (default: community; forced to `community` for docs-only)
99
100
  - `include_patterns` — file glob patterns to include
100
101
  - `exclude_patterns` — file glob patterns to exclude
101
102
  - `description` — human description of the skill
102
103
 
104
+ **Docs-only validation:** When `source_type: "docs-only"`, `source_repo` is not required but `doc_urls` must have at least one entry. `source_authority` is forced to `community`.
105
+
103
106
  **If required fields missing:**
104
107
  Halt with specific error: "Brief validation failed: missing required field `{field}`. Update your skill-brief.yaml and re-run."
105
108
 
@@ -53,16 +53,18 @@ To search the agentskills.io ecosystem for an existing official skill matching t
53
53
 
54
54
  ### 1. Check Ecosystem for Existing Skill
55
55
 
56
- **If skills_ref tool is available:**
56
+ **Note:** Ecosystem lookup requires the agentskills.io registry API, which is not yet available. The `skill-check` CLI validates local skills but does not query a remote registry.
57
+
58
+ **If agentskills.io registry API is available:**
57
59
 
58
60
  Query the ecosystem using the skill name from the brief:
59
- - `skills_ref.check_ecosystem(brief.name)`
61
+ - Call the registry API with brief.name — check if an official skill already exists
60
62
  - Enforce 5-second timeout — if the query does not return within 5 seconds, treat as no match
61
63
  - Cache results for 24 hours (if re-running same skill)
62
64
 
63
- **If skills_ref tool is NOT available:**
65
+ **If registry API is NOT available (current default):**
64
66
 
65
- Skip silently. Tool unavailability is not an error. Proceed as if no match was found.
67
+ Skip completely and silently. Do not output any message about API unavailability or the ecosystem check being skipped. Emit zero text to the console. Proceed exactly as if no match was found.
66
68
 
67
69
  ### 2. Evaluate Results
68
70
 
@@ -124,7 +126,7 @@ If no match is found, this step auto-proceeds with no user interaction.
124
126
 
125
127
  ### ✅ SUCCESS:
126
128
 
127
- - Ecosystem check attempted (or gracefully skipped if tool unavailable)
129
+ - Ecosystem check attempted via registry API (or gracefully skipped if API unavailable)
128
130
  - 5-second timeout enforced on ecosystem queries
129
131
  - Match presented factually with clear options if found
130
132
  - No-match case auto-proceeds silently
@@ -134,10 +136,11 @@ If no match is found, this step auto-proceeds with no user interaction.
134
136
  ### ❌ SYSTEM FAILURE:
135
137
 
136
138
  - Halting the workflow because ecosystem check failed or timed out
137
- - Treating tool unavailability as an error
139
+ - Treating API unavailability as an error
140
+ - Confusing `npx skill-check check` (local validation) with ecosystem lookup
138
141
  - Displaying "no match found" messages (absence should be silent)
139
142
  - Beginning extraction or compilation work in this step
140
143
  - Proceeding without user decision when a match IS found
141
144
  - Not enforcing the 5-second timeout
142
145
 
143
- **Master Rule:** This step is advisory. Tool failures and timeouts are silent skips, not errors. Only a confirmed match requires user interaction.
146
+ **Master Rule:** This step is advisory. API unavailability and timeouts are silent skips, not errors. Only a confirmed match requires user interaction.