bmad-module-skill-forge 0.7.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/agents/forger.agent.yaml +1 -1
- package/src/knowledge/ccc-bridge.md +34 -2
- package/src/knowledge/tool-resolution.md +3 -3
- package/src/module.yaml +5 -3
- package/src/workflows/analyze-source/data/skill-brief-schema.md +11 -2
- package/src/workflows/analyze-source/data/unit-detection-heuristics.md +9 -0
- package/src/workflows/analyze-source/steps-c/step-05-recommend.md +1 -1
- package/src/workflows/analyze-source/steps-c/step-06-generate-briefs.md +2 -1
- package/src/workflows/brief-skill/data/scope-templates.md +41 -0
- package/src/workflows/brief-skill/data/skill-brief-schema.md +11 -3
- package/src/workflows/brief-skill/steps-c/step-02-analyze-target.md +1 -1
- package/src/workflows/brief-skill/steps-c/step-03-scope-definition.md +6 -6
- package/src/workflows/create-skill/data/compile-assembly-rules.md +108 -0
- package/src/workflows/create-skill/data/extraction-patterns.md +94 -3
- package/src/workflows/create-skill/data/skill-sections.md +76 -0
- package/src/workflows/create-skill/data/source-resolution-protocols.md +21 -9
- package/src/workflows/create-skill/steps-c/step-02b-ccc-discover.md +6 -4
- package/src/workflows/create-skill/steps-c/step-03-extract.md +48 -12
- package/src/workflows/create-skill/steps-c/step-03d-component-extraction.md +292 -0
- package/src/workflows/create-skill/steps-c/step-05-compile.md +9 -0
- package/src/workflows/setup-forge/steps-c/step-01b-ccc-index.md +65 -13
- package/src/workflows/setup-forge/steps-c/step-02-write-config.md +5 -3
- package/src/workflows/update-skill/steps-c/step-03-re-extract.md +2 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "bmad-module-skill-forge",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0",
|
|
5
5
|
"description": "BMAD module — Turn code and docs into instructions AI agents can actually follow. Progressive capability tiers (Quick/Forge/Forge+/Deep).",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"bmad",
|
|
@@ -33,7 +33,7 @@ When either condition is false, calling steps skip ccc discovery silently and pr
|
|
|
33
33
|
|
|
34
34
|
### `ccc_bridge.search(query, path?, top_k?)`
|
|
35
35
|
|
|
36
|
-
**Resolves to:** `
|
|
36
|
+
**Resolves to:** `cd {path} && ccc search --limit {top_k} "{query}"` (CLI) or the `ccc` MCP search tool (preferred). Note: `ccc search` operates on the index in the current working directory — there is no flag to specify a project directory. The `--path` flag is a file path glob filter within the index, not a project selector.
|
|
37
37
|
|
|
38
38
|
Returns: list of `{file, score, snippet}` entries ranked by semantic relevance to the query. These are **candidates** for ast-grep extraction — not verified exports.
|
|
39
39
|
|
|
@@ -41,7 +41,7 @@ Returns: list of `{file, score, snippet}` entries ranked by semantic relevance t
|
|
|
41
41
|
|
|
42
42
|
### `ccc_bridge.ensure_index(path)`
|
|
43
43
|
|
|
44
|
-
**Resolves to:** Check `ccc_index.status` in forge-tier.yaml. If `"none"` or the indexed_path does not match, run `
|
|
44
|
+
**Resolves to:** Check `ccc_index.status` in forge-tier.yaml. If `"none"` or the indexed_path does not match, run `cd {path} && ccc init` then `ccc index` and update forge-tier.yaml. Note: `ccc init` takes no positional arguments — it initializes the index for the current working directory.
|
|
45
45
|
|
|
46
46
|
**Usage context:** Called by setup-forge step-01b to ensure the project root is indexed. Called lazily by extraction steps when `ccc_index.status` is `"none"` but ccc is available.
|
|
47
47
|
|
|
@@ -77,6 +77,36 @@ The ccc search is invisible in the output artifact. A Forge+ skill's citations a
|
|
|
77
77
|
- A stale index still produces useful results — the workflow proceeds with the stale index and notes the staleness
|
|
78
78
|
- setup-forge is the designated refresh authority
|
|
79
79
|
|
|
80
|
+
### Exclusion Patterns
|
|
81
|
+
|
|
82
|
+
CCC stores its configuration at `{project-root}/.cocoindex_code/settings.yml`. This file contains `exclude_patterns` and `include_patterns` arrays in glob format. `ccc init` creates the file with sensible defaults (excludes `node_modules`, `__pycache__`, hidden dirs, etc.).
|
|
83
|
+
|
|
84
|
+
**SKF infrastructure exclusions:** setup-forge step-01b appends SKF-specific exclusion patterns after `ccc init` creates the default config. These patterns prevent indexing of framework and output directories that have zero value for source extraction:
|
|
85
|
+
|
|
86
|
+
| Pattern | Purpose |
|
|
87
|
+
|---------|---------|
|
|
88
|
+
| `**/_bmad` | SKF framework module (workflow instructions, agents, knowledge) |
|
|
89
|
+
| `**/_bmad-output` | Build output artifacts (TODO files, reports) |
|
|
90
|
+
| `**/.claude` | Claude Code configuration |
|
|
91
|
+
| `**/_skf-learn` | SKF learning materials |
|
|
92
|
+
| `**/{skills_output_folder}` | Generated skill files (from manifest, default: `skills`) |
|
|
93
|
+
| `**/{forge_data_folder}` | Compilation workspace (from manifest, default: `forge-data`) |
|
|
94
|
+
|
|
95
|
+
The `skills_output_folder` and `forge_data_folder` values are read from `_bmad/_config/skf-manifest.yaml` when available, falling back to the defaults `skills` and `forge-data`. Patterns are appended only if not already present — user customizations to `settings.yml` are preserved.
|
|
96
|
+
|
|
97
|
+
The configured exclusion patterns are stored in `ccc_index.exclude_patterns` in forge-tier.yaml for reference.
|
|
98
|
+
|
|
99
|
+
### Deferred Discovery (Remote Sources)
|
|
100
|
+
|
|
101
|
+
For remote repository sources (GitHub URLs), CCC cannot operate during step-02b because no local code exists yet. The ephemeral clone happens in step-03. To provide CCC pre-ranking for remote sources:
|
|
102
|
+
|
|
103
|
+
1. **step-02b:** Detects remote source, sets `{ccc_discovery: []}`, displays deferred message
|
|
104
|
+
2. **step-03:** After ephemeral clone succeeds, detects the deferred scenario (`tools.ccc == true AND {ccc_discovery} is empty AND ephemeral_clone_active == true AND tier is Forge+/Deep`)
|
|
105
|
+
3. **step-03:** Runs `cd {temp_path} && ccc init` + `ccc index` on the ephemeral clone (extended timeout or background mode, verified via `ccc status`)
|
|
106
|
+
4. **step-03:** Executes CCC search and populates `{ccc_discovery}` before AST extraction begins
|
|
107
|
+
|
|
108
|
+
The ephemeral clone index is not registered in `ccc_index_registry` — the clone is deleted after extraction and the CCC daemon's own GC handles orphaned indexes.
|
|
109
|
+
|
|
80
110
|
### Relationship to QMD Registry
|
|
81
111
|
|
|
82
112
|
ccc_index and qmd_collections are **orthogonal**:
|
|
@@ -100,6 +130,8 @@ To prevent excessive daemon calls, workflow steps cap ccc queries:
|
|
|
100
130
|
- Running ccc_bridge.ensure_index() without checking ccc_index.status first — unnecessary re-indexing
|
|
101
131
|
- Passing ccc results directly to the extraction inventory — they are candidates, not extractions
|
|
102
132
|
- Listing ccc as "unavailable" in reports for Quick/Forge tiers — ccc is a Forge+ capability, not something Quick/Forge tiers are missing
|
|
133
|
+
- Indexing without configuring SKF exclusions — framework and output directories pollute search results
|
|
134
|
+
- Skipping CCC discovery for remote sources without deferring to step-03 — remote repos deserve the same pre-ranking as local sources
|
|
103
135
|
|
|
104
136
|
## Related Fragments
|
|
105
137
|
|
|
@@ -7,9 +7,9 @@ Bridge names (`ast_bridge`, `ccc_bridge`, `qmd_bridge`, `gh_bridge`) and subproc
|
|
|
7
7
|
| Bridge | Operation | Claude Code | Cursor | CLI | Fallback |
|
|
8
8
|
|--------------|----------------------------------|------------------------------------------------------------------|----------------|----------------------------------------------------|----------------------------------|
|
|
9
9
|
| `ast_bridge` | `scan_definitions()` | `mcp__ast-grep__find_code` or `mcp__ast-grep__find_code_by_rule` | ast-grep MCP | `sg run` / `ast-grep -p` | Source reading (T1-low) |
|
|
10
|
-
| `ast_bridge` | `detect_co_imports()` | `mcp__ast-grep__find_code_by_rule` with co-import YAML rule | ast-grep MCP | `ast-grep -p 'import $$$' --json=stream`
|
|
11
|
-
| `ccc_bridge` | `search(query, root, top_k)` | `/ccc` skill search | ccc MCP server | `
|
|
12
|
-
| `ccc_bridge` | `ensure_index(root)` | `/ccc` skill indexing | ccc MCP server | `ccc init` + `ccc index
|
|
10
|
+
| `ast_bridge` | `detect_co_imports()` | `mcp__ast-grep__find_code_by_rule` with co-import YAML rule | ast-grep MCP | `ast-grep run -p 'import $$$' --json=stream` | grep-based co-import count |
|
|
11
|
+
| `ccc_bridge` | `search(query, root, top_k)` | `/ccc` skill search | ccc MCP server | `cd {root} && ccc search --limit {top_k} "{query}"` | Skip silently |
|
|
12
|
+
| `ccc_bridge` | `ensure_index(root)` | `/ccc` skill indexing | ccc MCP server | `cd {root} && ccc init` + `ccc index` | Skip silently |
|
|
13
13
|
| `ccc_bridge` | `status()` | `/ccc` skill status | ccc MCP server | `ccc --help` + `ccc doctor` | Unavailable = `tools.ccc: false` |
|
|
14
14
|
| `qmd_bridge` | `search(query)` | `mcp__plugin_qmd-plugin_qmd__search` | qmd MCP server | `qmd search "{query}"` | Skip enrichment |
|
|
15
15
|
| `qmd_bridge` | `vector_search(query)` | `mcp__plugin_qmd-plugin_qmd__vector_search` | qmd MCP server | `qmd vector_search "{query}"` | Use BM25 search only |
|
package/src/module.yaml
CHANGED
|
@@ -15,11 +15,13 @@ forge_data_folder:
|
|
|
15
15
|
default: "forge-data"
|
|
16
16
|
result: "{project-root}/{value}"
|
|
17
17
|
|
|
18
|
+
sidecar_path:
|
|
19
|
+
prompt: false
|
|
20
|
+
default: "_bmad/_memory/forger-sidecar"
|
|
21
|
+
result: "{project-root}/{value}"
|
|
22
|
+
|
|
18
23
|
# Variables from Core Config inserted:
|
|
19
24
|
## user_name
|
|
20
25
|
## communication_language
|
|
21
26
|
## document_output_language
|
|
22
27
|
## output_folder
|
|
23
|
-
|
|
24
|
-
# Variables from Agent Sidecar Config:
|
|
25
|
-
## sidecar_path (from forger.agent.yaml metadata.sidecar-path)
|
|
@@ -55,12 +55,20 @@ The create-skill workflow (step-03-extract) also performs version reconciliation
|
|
|
55
55
|
|
|
56
56
|
```yaml
|
|
57
57
|
scope:
|
|
58
|
-
type: full-library | specific-modules | public-api | docs-only
|
|
58
|
+
type: full-library | specific-modules | public-api | component-library | docs-only
|
|
59
59
|
include:
|
|
60
60
|
- 'src/**/*.ts' # At least one required
|
|
61
61
|
exclude:
|
|
62
62
|
- 'src/**/*.test.ts' # Optional
|
|
63
63
|
notes: 'Optional rationale for scope decision'
|
|
64
|
+
# Additional fields when scope.type is "component-library":
|
|
65
|
+
# registry_path: "path/to/registry.ts" # Optional — auto-detected if omitted
|
|
66
|
+
# ui_variants: # Optional — design system variants
|
|
67
|
+
# - name: "shadcnui"
|
|
68
|
+
# package: "packages/components/react-shadcn"
|
|
69
|
+
# demo_patterns: # Optional — auto-detected if omitted
|
|
70
|
+
# - "**/demo/**"
|
|
71
|
+
# - "**/*.stories.*"
|
|
64
72
|
```
|
|
65
73
|
|
|
66
74
|
### Scope Types
|
|
@@ -70,6 +78,7 @@ scope:
|
|
|
70
78
|
| full-library | Entire codebase of a unit |
|
|
71
79
|
| specific-modules | Selected components or packages |
|
|
72
80
|
| public-api | Only exported interfaces |
|
|
81
|
+
| component-library | UI component libraries with registries, props-based APIs, and design system variants |
|
|
73
82
|
| docs-only | When source_type is docs-only — no source code available, all content from doc_urls |
|
|
74
83
|
|
|
75
84
|
## YAML Template
|
|
@@ -98,7 +107,7 @@ created_by: '{user_name}'
|
|
|
98
107
|
1. **Name uniqueness**: No duplicate names within forge_data_folder
|
|
99
108
|
2. **Source accessibility**: source_repo path must exist or be reachable
|
|
100
109
|
3. **Language recognized**: Must be a known programming language
|
|
101
|
-
4. **Scope type valid**: Must match one of the
|
|
110
|
+
4. **Scope type valid**: Must match one of the five defined types (full-library, specific-modules, public-api, component-library, docs-only)
|
|
102
111
|
5. **Include patterns**: At least one include glob pattern required (exception: `docs-only` scope, where include patterns are optional since no source code is available)
|
|
103
112
|
6. **Forge tier match**: Must match value in forge-tier.yaml
|
|
104
113
|
7. **Docs-only mode**: When `source_type: "docs-only"`, `doc_urls` required (>= 1), `source_repo` optional
|
|
@@ -59,6 +59,15 @@ Rules for identifying discrete skillable units within a project. A "skillable un
|
|
|
59
59
|
- Custom wrappers, configurations, or integration code
|
|
60
60
|
- Scope type: `public-api`
|
|
61
61
|
|
|
62
|
+
### Component Library Boundary
|
|
63
|
+
- Contains a component registry or catalog file (array of component definitions with IDs, names, categories)
|
|
64
|
+
- Has `components/`, `packages/components/`, or similar multi-component directory structure
|
|
65
|
+
- Multiple design system variant directories (e.g., `react-shadcn/`, `react-baseui/`, `react-carbon/`)
|
|
66
|
+
- Significant demo/story/example file ratio (>30% of total files)
|
|
67
|
+
- CLI-based installation pattern (e.g., `npx <tool> add <component-id>`)
|
|
68
|
+
- Props interfaces outnumber function signatures as primary API surface
|
|
69
|
+
- Scope type: `component-library`
|
|
70
|
+
|
|
62
71
|
## Disqualification Rules
|
|
63
72
|
|
|
64
73
|
Do NOT recommend as a skillable unit if:
|
|
@@ -90,7 +90,7 @@ For EACH qualifying unit, prepare a recommendation card:
|
|
|
90
90
|
|
|
91
91
|
**Proposed Brief Fields:**
|
|
92
92
|
- name: {suggested kebab-case name}
|
|
93
|
-
- scope.type: {full-library / specific-modules / public-api}
|
|
93
|
+
- scope.type: {full-library / specific-modules / public-api / component-library}
|
|
94
94
|
- scope.include: {suggested glob patterns}
|
|
95
95
|
- description: {suggested 1-3 sentence description}
|
|
96
96
|
```
|
|
@@ -97,7 +97,7 @@ For each generated brief, check against {schemaFile} validation rules:
|
|
|
97
97
|
1. **Name uniqueness** — no duplicate names within the batch or existing skills
|
|
98
98
|
2. **Source accessible** — project_path exists
|
|
99
99
|
3. **Language recognized** — valid programming language identifier
|
|
100
|
-
4. **Scope type valid** — matches `full-library`, `specific-modules`,
|
|
100
|
+
4. **Scope type valid** — matches `full-library`, `specific-modules`, `public-api`, or `component-library`
|
|
101
101
|
5. **Include patterns** — at least one glob pattern present
|
|
102
102
|
6. **Forge tier match** — matches forge_tier from config
|
|
103
103
|
|
|
@@ -152,6 +152,7 @@ For each generated brief, recommend the appropriate next workflow:
|
|
|
152
152
|
| Condition | Recommendation |
|
|
153
153
|
|-----------|---------------|
|
|
154
154
|
| Brief has `scope.type: full-library` and unit is well-bounded | create-skill — brief is sufficient for direct skill creation |
|
|
155
|
+
| Brief has `scope.type: component-library` and registry defines boundaries | create-skill — component boundaries defined by registry |
|
|
155
156
|
| Brief has `scope.type: specific-modules` or scope needs refinement | brief-skill — refine scope before creating skill |
|
|
156
157
|
| Brief has `scope.type: public-api` or complex interface | brief-skill — detailed scoping needed |
|
|
157
158
|
| Unit flagged as stack skill candidate | create-stack-skill — after individual skills exist |
|
|
@@ -16,6 +16,12 @@ Present these options to the user for selection:
|
|
|
16
16
|
- Entry points and exported interfaces only
|
|
17
17
|
- Internal implementation excluded
|
|
18
18
|
|
|
19
|
+
**[C] Component Library** — Optimized for UI component libraries with registries, props-based APIs, and design system variants.
|
|
20
|
+
- Component registry as primary API surface (not individual exports)
|
|
21
|
+
- Props interfaces as API contracts (not function signatures)
|
|
22
|
+
- Auto-exclude demo/example/story files (with user confirmation)
|
|
23
|
+
- Variant consolidation across design systems
|
|
24
|
+
|
|
19
25
|
## Boundary Definitions by Scope Type
|
|
20
26
|
|
|
21
27
|
### Full Library Boundaries
|
|
@@ -69,6 +75,41 @@ Prompt: "Any additional items you'd like to include or exclude?"
|
|
|
69
75
|
|
|
70
76
|
Prompt: "Any additional documentation URLs to include? Or URLs to exclude from the ones collected?"
|
|
71
77
|
|
|
78
|
+
### Component Library Boundaries
|
|
79
|
+
|
|
80
|
+
**Phase 1 — Registry Detection:**
|
|
81
|
+
|
|
82
|
+
Auto-detect or accept explicit `registry_path` from user. Scan source tree for files matching common registry patterns:
|
|
83
|
+
- Files named `registry.ts`, `components.ts`, `index.ts` in `registry/`, `catalog/`, or `components/` directories
|
|
84
|
+
- Arrays of objects with `{ id, name, component }` structure and 10+ entries
|
|
85
|
+
- Files with `Component[]` type annotations
|
|
86
|
+
|
|
87
|
+
Present detected registry candidate(s) to user for confirmation.
|
|
88
|
+
Prompt: "I found what looks like a component registry at {path} ({count} entries). Is this correct? Or provide the registry path:"
|
|
89
|
+
|
|
90
|
+
**Phase 2 — Demo/Example Exclusion:**
|
|
91
|
+
|
|
92
|
+
Auto-detect demo directories and file patterns:
|
|
93
|
+
- Directories: `demo/`, `demos/`, `stories/`, `examples/`, `__stories__/`, `storybook/`
|
|
94
|
+
- Files: `*.stories.*`, `*.story.*`, `*.example.*`, `*.demo.*`
|
|
95
|
+
|
|
96
|
+
Present detected patterns to user before applying (do NOT exclude silently).
|
|
97
|
+
Prompt: "**Auto-detected {N} demo/example files** in {M} directories. Confirm exclusion? [Y/n] Or adjust patterns:"
|
|
98
|
+
|
|
99
|
+
**Phase 3 — Variant Selection (if applicable):**
|
|
100
|
+
|
|
101
|
+
If multiple design system variant directories detected (e.g., `react-shadcn/`, `react-baseui/`, `react-carbon/`):
|
|
102
|
+
- Present detected variants with component counts per variant
|
|
103
|
+
- User selects primary variant and which variants to include
|
|
104
|
+
- Record as `ui_variants` in brief
|
|
105
|
+
|
|
106
|
+
Prompt: "I detected {count} design system variants: {list with counts}. Which is the primary variant? Include all? [Y/n]"
|
|
107
|
+
|
|
108
|
+
**Phase 4 — Scope Confirmation:**
|
|
109
|
+
|
|
110
|
+
Summary showing: component count, excluded demo count, variant summary, include/exclude patterns.
|
|
111
|
+
Prompt: "Does this component library scope look right? Adjust before continuing."
|
|
112
|
+
|
|
72
113
|
## Scripts & Assets Detection (Optional Refinement)
|
|
73
114
|
|
|
74
115
|
When `scripts_intent` or `assets_intent` is `detect` (default), SKF auto-detects from source directories matching: `scripts/`, `bin/`, `tools/`, `cli/` (for scripts) and `assets/`, `templates/`, `schemas/`, `configs/`, `examples/` (for assets). Detection applies to all scope types except `docs-only`.
|
|
@@ -51,13 +51,21 @@ The create-skill workflow (step-03-extract) also performs version reconciliation
|
|
|
51
51
|
|
|
52
52
|
```yaml
|
|
53
53
|
scope:
|
|
54
|
-
type: full-library | specific-modules | public-api | docs-only
|
|
54
|
+
type: full-library | specific-modules | public-api | component-library | docs-only
|
|
55
55
|
include:
|
|
56
56
|
- "src/**/*.ts" # Glob patterns for included files/directories
|
|
57
57
|
exclude:
|
|
58
58
|
- "**/*.test.*" # Glob patterns for excluded files
|
|
59
59
|
- "**/node_modules/**"
|
|
60
60
|
notes: "Optional notes about scope decisions"
|
|
61
|
+
# Additional fields when scope.type is "component-library":
|
|
62
|
+
# registry_path: "path/to/registry.ts" # Optional — auto-detected if omitted
|
|
63
|
+
# ui_variants: # Optional — design system variants
|
|
64
|
+
# - name: "shadcnui"
|
|
65
|
+
# package: "packages/components/react-shadcn"
|
|
66
|
+
# demo_patterns: # Optional — auto-detected if omitted
|
|
67
|
+
# - "**/demo/**"
|
|
68
|
+
# - "**/*.stories.*"
|
|
61
69
|
```
|
|
62
70
|
|
|
63
71
|
## YAML Template
|
|
@@ -74,7 +82,7 @@ forge_tier: "{Quick|Forge|Forge+|Deep}"
|
|
|
74
82
|
created: "{date}"
|
|
75
83
|
created_by: "{user_name}"
|
|
76
84
|
scope:
|
|
77
|
-
type: "{full-library|specific-modules|public-api|docs-only}"
|
|
85
|
+
type: "{full-library|specific-modules|public-api|component-library|docs-only}"
|
|
78
86
|
include:
|
|
79
87
|
- "{pattern}"
|
|
80
88
|
exclude:
|
|
@@ -133,7 +141,7 @@ Created by: {created_by}
|
|
|
133
141
|
1. `name` must be unique within {forge_data_folder}
|
|
134
142
|
2. `source_repo` must be accessible (gh api for GitHub, path exists for local)
|
|
135
143
|
3. `language` must be a recognized programming language
|
|
136
|
-
4. `scope.type` must be one of the
|
|
144
|
+
4. `scope.type` must be one of the five defined types
|
|
137
145
|
5. `scope.include` must have at least one pattern (exception: `docs-only` scope, where include patterns are optional since no source code is available)
|
|
138
146
|
6. `forge_tier` must be one of: Quick, Forge, Forge+, Deep (Title Case, must match the tier from forge-tier.yaml, or default to Quick)
|
|
139
147
|
7. When `source_type: "docs-only"`: `doc_urls` must have >= 1 entry, `source_repo` becomes optional
|
|
@@ -139,7 +139,7 @@ Based on detected language, identify public API surface:
|
|
|
139
139
|
|
|
140
140
|
**Semantic Signals (Forge+ and Deep with ccc only):**
|
|
141
141
|
|
|
142
|
-
**Remote source guard:** If the target source was resolved via GitHub API (remote URL, not a local file path), skip this CCC subsection — CCC requires a local source index and cannot operate on remote-only sources. Note: "CCC semantic discovery skipped — target is remote. CCC will
|
|
142
|
+
**Remote source guard:** If the target source was resolved via GitHub API (remote URL, not a local file path), skip this CCC subsection — CCC requires a local source index and cannot operate on remote-only sources. Note: "CCC semantic discovery skipped — target is remote. CCC discovery will run automatically during create-skill after the source is cloned."
|
|
143
143
|
|
|
144
144
|
If `tools.ccc` is true in forge-tier.yaml, supplement the module listing with a semantic discovery pass:
|
|
145
145
|
|
|
@@ -106,9 +106,9 @@ Wait for confirmation. Record any changes to `doc_urls`.
|
|
|
106
106
|
|
|
107
107
|
### 2c. Offer Scope Templates
|
|
108
108
|
|
|
109
|
-
Load `{scopeTemplatesFile}` for the scope type options ([F], [M], [P]) and their descriptions.
|
|
109
|
+
Load `{scopeTemplatesFile}` for the scope type options ([F], [M], [P], [C]) and their descriptions.
|
|
110
110
|
|
|
111
|
-
Present: "**How broadly should this skill cover the library?**" followed by the
|
|
111
|
+
Present: "**How broadly should this skill cover the library?**" followed by the scope type options from the loaded reference.
|
|
112
112
|
|
|
113
113
|
Ask: "Which scope type fits your needs?"
|
|
114
114
|
|
|
@@ -116,7 +116,7 @@ Wait for user selection.
|
|
|
116
116
|
|
|
117
117
|
### 3. Define Boundaries Based on Selection
|
|
118
118
|
|
|
119
|
-
Using the boundary definitions from `{scopeTemplatesFile}`, present the appropriate flow for the user's selected scope type ([F], [M], or [
|
|
119
|
+
Using the boundary definitions from `{scopeTemplatesFile}`, present the appropriate flow for the user's selected scope type ([F], [M], [P], or [C]). Follow each type's prompts and wait for user input at each phase before proceeding.
|
|
120
120
|
|
|
121
121
|
### 4. Handle Language Override
|
|
122
122
|
|
|
@@ -132,7 +132,7 @@ Wait for confirmation or override.
|
|
|
132
132
|
|
|
133
133
|
"**Scope Summary:**
|
|
134
134
|
|
|
135
|
-
**Type:** {Full Library / Specific Modules / Public API}
|
|
135
|
+
**Type:** {Full Library / Specific Modules / Public API / Component Library}
|
|
136
136
|
|
|
137
137
|
**Include:**
|
|
138
138
|
{bulleted list of include patterns}
|
|
@@ -151,7 +151,7 @@ Wait for confirmation. Make adjustments if requested.
|
|
|
151
151
|
|
|
152
152
|
### 5b. Scripts & Assets Intent (Optional)
|
|
153
153
|
|
|
154
|
-
**Only ask when `scope.type` is `full-library` or `
|
|
154
|
+
**Only ask when `scope.type` is `full-library`, `specific-modules`, or `component-library` (skip for `public-api` and `docs-only`).**
|
|
155
155
|
|
|
156
156
|
"Does this library include executable scripts (CLI tools, validation scripts, setup helpers) or static assets (config templates, JSON schemas, example configs) that should be packaged with the skill?"
|
|
157
157
|
|
|
@@ -189,7 +189,7 @@ ONLY WHEN C is selected and scope boundaries are confirmed will you load and rea
|
|
|
189
189
|
|
|
190
190
|
### ✅ SUCCESS:
|
|
191
191
|
|
|
192
|
-
- Scope type selected by user (Full Library, Specific Modules, or
|
|
192
|
+
- Scope type selected by user (Full Library, Specific Modules, Public API, or Component Library)
|
|
193
193
|
- Include patterns defined and confirmed
|
|
194
194
|
- Exclude patterns defined and confirmed
|
|
195
195
|
- Language confirmed (or overridden if detection was low confidence)
|
|
@@ -108,6 +108,114 @@ Assemble Sections 9-11 (Full API Reference, Full Type Definitions, Full Integrat
|
|
|
108
108
|
|
|
109
109
|
Do NOT repeat Tier 1's name/purpose/key-params table format in Tier 2. Tier 2 is a deep reference, not a reformatted summary. This distinction prevents conciseness scorers from flagging the two-tier design as redundancy.
|
|
110
110
|
|
|
111
|
+
### Component Library Assembly Overrides
|
|
112
|
+
|
|
113
|
+
When `scope.type: "component-library"` in the brief AND `component_catalog[]` is available in context, apply these overrides to the standard assembly. All other sections remain unchanged.
|
|
114
|
+
|
|
115
|
+
**Section 2 (Quick Start) — CLI-first override:**
|
|
116
|
+
|
|
117
|
+
Replace the standard function-based Quick Start with CLI installation:
|
|
118
|
+
|
|
119
|
+
```markdown
|
|
120
|
+
## Quick Start
|
|
121
|
+
|
|
122
|
+
Install a component:
|
|
123
|
+
`npx {cli-name} add {top-component-id}`
|
|
124
|
+
|
|
125
|
+
{If provider wrapping detected in source:}
|
|
126
|
+
Set up providers:
|
|
127
|
+
\`\`\`tsx
|
|
128
|
+
import { ThemeProvider, UILibraryProvider } from "{primary-package}";
|
|
129
|
+
|
|
130
|
+
<ThemeProvider>
|
|
131
|
+
<UILibraryProvider>
|
|
132
|
+
<YourApp />
|
|
133
|
+
</UILibraryProvider>
|
|
134
|
+
</ThemeProvider>
|
|
135
|
+
\`\`\`
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Detect CLI name from: `package.json` `bin` field, README usage examples, or `registry_path` context. If no CLI detected, fall back to standard import-based Quick Start.
|
|
139
|
+
|
|
140
|
+
**Section 4 (Key API Summary) — Component Catalog override:**
|
|
141
|
+
|
|
142
|
+
Replace the function table with a Component Catalog organized by category:
|
|
143
|
+
|
|
144
|
+
```markdown
|
|
145
|
+
## Component Catalog
|
|
146
|
+
|
|
147
|
+
| Category | Count | Key Components |
|
|
148
|
+
|----------|-------|---------------|
|
|
149
|
+
| {category} | {count} | {top 3-5 component names, comma-separated} |
|
|
150
|
+
|
|
151
|
+
**Design system variants:** {variant list with primary marked}
|
|
152
|
+
**Total components:** {unique count} | {Per variant: **With {name}:** {count}}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Source: `component_catalog[]` from step-03d. Group by `category` field. Provenance: cite the registry file.
|
|
156
|
+
|
|
157
|
+
**Section 5 (Key Types) — Props-focused override:**
|
|
158
|
+
|
|
159
|
+
Replace generic types with the top 5 most-used Props interfaces (by component count or prominence):
|
|
160
|
+
|
|
161
|
+
```markdown
|
|
162
|
+
## Key Types
|
|
163
|
+
|
|
164
|
+
### {ComponentName}Props
|
|
165
|
+
| Prop | Type | Default | Required |
|
|
166
|
+
|------|------|---------|----------|
|
|
167
|
+
| {prop} | {type} | {default or —} | {yes/no} |
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Show only the 5 most important Props interfaces inline. Full Props details go in Tier 2.
|
|
171
|
+
|
|
172
|
+
**Tier 2 (Full API Reference) — Props Reference override:**
|
|
173
|
+
|
|
174
|
+
Organize by component (not by function). Per component:
|
|
175
|
+
|
|
176
|
+
```markdown
|
|
177
|
+
### {ComponentName}
|
|
178
|
+
|
|
179
|
+
**Install:** `npx {cli} add {component-id}`
|
|
180
|
+
**Available in:** {variant list}
|
|
181
|
+
**Props:** `{ComponentName}Props`
|
|
182
|
+
|
|
183
|
+
| Prop | Type | Default | Description |
|
|
184
|
+
|------|------|---------|-------------|
|
|
185
|
+
| {prop} | {type} | {default} | {JSDoc description or —} |
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**context-snippet.md — Component Library format:**
|
|
189
|
+
|
|
190
|
+
```markdown
|
|
191
|
+
[{name} v{version}]|root: skills/{name}/
|
|
192
|
+
|IMPORTANT: {name} v{version} — read SKILL.md before writing {name} code. Do NOT rely on training data.
|
|
193
|
+
|install: npx {cli} add <component-id>
|
|
194
|
+
|catalog:{SKILL.md#component-catalog} — {N} components: {category(count), ...}
|
|
195
|
+
|variants: {variant list} — {provider wrapping note if applicable}
|
|
196
|
+
|key-props:{SKILL.md#key-types} — {top props interfaces with key fields}
|
|
197
|
+
|gotchas: {detected gotchas}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**metadata.json — Component Library stats:**
|
|
201
|
+
|
|
202
|
+
When `scope.type: "component-library"`, add these fields to `stats`:
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"stats": {
|
|
207
|
+
"components_registered": 0,
|
|
208
|
+
"components_documented": 0,
|
|
209
|
+
"props_interfaces_extracted": 0,
|
|
210
|
+
"components_unique": 0,
|
|
211
|
+
"demo_files_excluded": 0,
|
|
212
|
+
"design_variants": {}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
These are in addition to the standard stats fields (exports_documented, etc.).
|
|
218
|
+
|
|
111
219
|
### Assembly Rules
|
|
112
220
|
|
|
113
221
|
1. Assemble all Tier 1 sections first — these form the essential standalone body
|
|
@@ -130,7 +130,7 @@ Files in scope 101–500
|
|
|
130
130
|
→ Parse compact text output into extraction inventory
|
|
131
131
|
|
|
132
132
|
Files in scope > 500
|
|
133
|
-
→ CLI streaming fallback: ast-grep --json=stream + line-by-line Python processing
|
|
133
|
+
→ CLI streaming fallback: ast-grep run --json=stream + line-by-line Python processing
|
|
134
134
|
→ Process in directory batches, cap per-batch output
|
|
135
135
|
→ Merge batch results into extraction inventory
|
|
136
136
|
```
|
|
@@ -171,6 +171,7 @@ When MCP tools are unavailable or the repo exceeds 500 files in scope, use `--js
|
|
|
171
171
|
**Head cap selection:** The `| head -N` cap at the end of the pipeline controls how many exports are captured. Select `N` based on scope and tier:
|
|
172
172
|
- **Default (Quick/Forge, any scope):** `N = 200`
|
|
173
173
|
- **Forge+/Deep with `scope.type: "full-library"`:** `N = 500`
|
|
174
|
+
- **Forge+/Deep with `scope.type: "component-library"`:** `N = 300` (components have fewer but richer exports; props interfaces are the primary API surface)
|
|
174
175
|
|
|
175
176
|
For full-library skills at higher tiers, the larger cap prevents silently dropping internal module exports that maintainers need. The cap is applied AFTER exclude-pattern filtering, so useful results are not wasted on excluded files.
|
|
176
177
|
|
|
@@ -181,7 +182,8 @@ For full-library skills at higher tiers, the larger cap prevents silently droppi
|
|
|
181
182
|
# Patterns are matched against the full file path as emitted by ast-grep.
|
|
182
183
|
# Ensure paths are relative to the same root as the patterns (strip ./ prefix if needed).
|
|
183
184
|
# {HEAD_CAP} = 200 (default) or 500 (Forge+/Deep full-library) — see head cap selection above.
|
|
184
|
-
|
|
185
|
+
# IMPORTANT: The explicit 'run' subcommand is required for --json=stream to work.
|
|
186
|
+
ast-grep run -p '{pattern}' -l {language} --json=stream {path} | python3 -c "
|
|
185
187
|
import sys, json, fnmatch, signal
|
|
186
188
|
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
|
187
189
|
|
|
@@ -244,9 +246,11 @@ constraints:
|
|
|
244
246
|
|
|
245
247
|
**JavaScript/TypeScript — exported functions:**
|
|
246
248
|
|
|
249
|
+
> **Language selection:** Use `language: typescript` for `.ts` files and `language: tsx` for `.tsx` files. Patterns that work with `typescript` may return zero results with `tsx` and vice versa — they use different tree-sitter parsers. For mixed codebases, run each pattern twice (once per language) and merge results. Note: `export function` patterns may fail with `tsx` on ast-grep 0.41.x (see Known Limitations #5) — use source reading as fallback for those.
|
|
250
|
+
|
|
247
251
|
```yaml
|
|
248
252
|
id: js-exported-functions
|
|
249
|
-
language: typescript
|
|
253
|
+
language: typescript # Use 'tsx' for .tsx files — see language selection note above
|
|
250
254
|
rule:
|
|
251
255
|
pattern: 'export function $NAME($$$PARAMS)'
|
|
252
256
|
```
|
|
@@ -311,6 +315,67 @@ constraints:
|
|
|
311
315
|
regex: '^[A-Z]'
|
|
312
316
|
```
|
|
313
317
|
|
|
318
|
+
### Component Library YAML Rule Recipes
|
|
319
|
+
|
|
320
|
+
These patterns are used by `step-03d-component-extraction.md` when `scope.type: "component-library"`. They prioritize Props interfaces and PascalCase component exports.
|
|
321
|
+
|
|
322
|
+
**React/TypeScript — Props interfaces (primary API contracts):**
|
|
323
|
+
|
|
324
|
+
```yaml
|
|
325
|
+
id: react-props-interfaces
|
|
326
|
+
language: typescript # Use 'tsx' for .tsx files
|
|
327
|
+
rule:
|
|
328
|
+
pattern: 'export interface $NAME { $$$ }'
|
|
329
|
+
constraints:
|
|
330
|
+
NAME:
|
|
331
|
+
regex: '.*Props$'
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**React/TypeScript — Component function exports (PascalCase):**
|
|
335
|
+
|
|
336
|
+
> **Language note:** Use `language: tsx` for `.tsx` files. The `export function` pattern may fail with tsx on ast-grep 0.41.x (see Known Limitations #5). Use `export const` patterns as primary and fall back to source reading for `export function` in tsx files.
|
|
337
|
+
|
|
338
|
+
```yaml
|
|
339
|
+
id: react-component-functions
|
|
340
|
+
language: tsx
|
|
341
|
+
rule:
|
|
342
|
+
pattern: 'export function $NAME($$$PARAMS)'
|
|
343
|
+
constraints:
|
|
344
|
+
NAME:
|
|
345
|
+
regex: '^[A-Z]'
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**React/TypeScript — Component arrow function exports:**
|
|
349
|
+
|
|
350
|
+
```yaml
|
|
351
|
+
id: react-component-arrow-functions
|
|
352
|
+
language: typescript
|
|
353
|
+
rule:
|
|
354
|
+
pattern: 'export const $NAME = ($$$PARAMS) => $BODY'
|
|
355
|
+
constraints:
|
|
356
|
+
NAME:
|
|
357
|
+
regex: '^[A-Z]'
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**Vue — defineProps extraction:**
|
|
361
|
+
|
|
362
|
+
```yaml
|
|
363
|
+
id: vue-define-props
|
|
364
|
+
language: typescript
|
|
365
|
+
rule:
|
|
366
|
+
pattern: 'defineProps<$TYPE>()'
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**Props-to-Component linking strategy:**
|
|
370
|
+
|
|
371
|
+
After extracting Props interfaces and component exports, link them using this 3-level fallback chain:
|
|
372
|
+
|
|
373
|
+
1. **Naming convention (primary):** Strip `Props` suffix from interface name → match to component export (e.g., `NativeLiquidButtonProps` → `NativeLiquidButton`)
|
|
374
|
+
2. **File co-location (fallback):** If naming doesn't match, check if a Props interface and a PascalCase export function are defined in the same file — link them
|
|
375
|
+
3. **Generic parameter (deep fallback):** Search for `ComponentProps<typeof $NAME>` or `React.ComponentProps<typeof $NAME>` patterns that reference the component by name
|
|
376
|
+
|
|
377
|
+
Unlinked Props interfaces are included as standalone type exports. Unlinked component exports are included with a note that no Props interface was found (signature-only, T1-low confidence for API contract).
|
|
378
|
+
|
|
314
379
|
### Known ast-grep Limitations
|
|
315
380
|
|
|
316
381
|
When using ast-grep for extraction, be aware of these documented limitations:
|
|
@@ -326,6 +391,32 @@ When using ast-grep for extraction, be aware of these documented limitations:
|
|
|
326
391
|
- Second: if `find_code()` also fails, fall back to source reading for that pattern category (T1-low confidence)
|
|
327
392
|
- Never silently accept zero results for a pattern category that the source language commonly uses
|
|
328
393
|
|
|
394
|
+
5. **TSX `export function` pattern failure:** The `export function $NAME($$$PARAMS)` pattern may return zero results in TSX files with ast-grep 0.41.x. This affects both MCP tools and CLI. `export const` and `export type` patterns are unaffected. **Workaround:** For TSX files, use `export const` patterns first (which work), then fall back to source reading (grep/file read) for `export function` declarations. When a TSX codebase shows zero `export function` matches but source files clearly contain them, this is a known ast-grep tree-sitter tsx parser limitation — not an extraction error. Log it in the evidence report and proceed with T1-low confidence for those exports.
|
|
395
|
+
|
|
396
|
+
6. **CLI `--json=stream` may produce no output:** On ast-grep 0.41.x, `--json=stream` may produce empty output for certain patterns. The `--json=stream` flag requires the explicit `run` subcommand: use `ast-grep run -p '{pattern}' --json=stream` (not `ast-grep -p '{pattern}' --json=stream`). If streaming still produces no output, fall back to the MCP tool or source reading.
|
|
397
|
+
|
|
398
|
+
### Component Library Demo/Example Auto-Exclusion
|
|
399
|
+
|
|
400
|
+
When `scope.type: "component-library"`, auto-detect and propose demo/example exclusions before extraction begins. **User confirmation is required before applying** — some `examples/` directories contain API-level code.
|
|
401
|
+
|
|
402
|
+
**Auto-detect directory patterns:**
|
|
403
|
+
- `**/demo/**`, `**/demos/**`
|
|
404
|
+
- `**/stories/**`, `**/__stories__/**`, `**/storybook/**`
|
|
405
|
+
- `**/examples/**`, `**/example/**`
|
|
406
|
+
|
|
407
|
+
**Auto-detect file patterns:**
|
|
408
|
+
- `**/*.stories.*`, `**/*.story.*`
|
|
409
|
+
- `**/*.example.*`, `**/*.demo.*`
|
|
410
|
+
|
|
411
|
+
If `demo_patterns` is specified in the brief, use those instead of auto-detection.
|
|
412
|
+
|
|
413
|
+
**Procedure:**
|
|
414
|
+
1. Scan the scoped file tree for matching directories and files
|
|
415
|
+
2. Count matches per pattern category
|
|
416
|
+
3. Present to user: "**Auto-detected {N} demo/example files** in {M} directories matching these patterns: {list}. Confirm exclusion? [Y/n] Or adjust patterns:"
|
|
417
|
+
4. Apply confirmed patterns to the exclude list before AST extraction
|
|
418
|
+
5. Record in extraction inventory: `demo_files_excluded: {count}`
|
|
419
|
+
|
|
329
420
|
### Re-Export Tracing and Script/Asset Extraction
|
|
330
421
|
|
|
331
422
|
See `extraction-patterns-tracing.md` for:
|