bmad-module-skill-forge 0.7.3 → 0.7.4

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 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.7.3",
4
+ "version": "0.7.4",
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",
@@ -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 `ccc init {temp_path}` + `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
 
@@ -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 be available during create-skill if the source is cloned locally."
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
 
@@ -65,9 +65,11 @@ Set `{ccc_discovery: []}` in context. Auto-proceed silently. Display no message.
65
65
 
66
66
  Check `tools.ccc` from forge-tier.yaml. If `tools.ccc` is false, set `{ccc_discovery: []}` in context and auto-proceed to section 5.
67
67
 
68
- If `tools.ccc` is true, continue to section 2.
68
+ If `tools.ccc` is true, check the remote source guard **before** proceeding to section 2:
69
69
 
70
- **Remote source guard:** If `source_root` is a remote URL (GitHub repository not yet cloned locally — ephemeral clone happens in step-03), CCC cannot operate. Set `{ccc_discovery: []}` and display: "CCC discovery skipped — remote source not yet available locally. CCC requires a local source index." Auto-proceed to the step completion / next step section.
70
+ **Remote source guard:** If `source_root` is a remote URL (GitHub repository not yet cloned locally — ephemeral clone happens in step-03), CCC cannot operate yet. Set `{ccc_discovery: []}` and display: "CCC discovery deferred — remote source will be indexed after ephemeral clone in step-03." Auto-proceed to section 5 (step completion). Step-03 will detect the deferred scenario and run CCC discovery on the ephemeral clone before AST extraction begins.
71
+
72
+ If `source_root` is a local path, continue to section 2.
71
73
 
72
74
  ### 2. Check CCC Index State
73
75
 
@@ -96,9 +96,30 @@ Load `{sourceResolutionData}` completely. Follow the **Remote Source Resolution*
96
96
 
97
97
  **Forge/Forge+/Deep Tier (AST available):**
98
98
 
99
+ **Deferred CCC Discovery (Forge+ and Deep — remote sources only):**
100
+
101
+ If ALL of these conditions are true:
102
+ - `tools.ccc` is true in forge-tier.yaml
103
+ - `{ccc_discovery}` is empty (step-02b deferred because source was remote)
104
+ - `ephemeral_clone_active` is true (clone succeeded in source resolution above)
105
+ - Tier is Forge+ or Deep
106
+
107
+ Then run CCC indexing and discovery on the ephemeral clone:
108
+
109
+ 1. **Index the clone:** Run `ccc init {temp_path}` then `ccc index` with an extended timeout or in background mode — indexing can take several minutes on large codebases (1000+ files). Use `ccc status` to verify completion — check that `Chunks` and `Files` counts are non-zero. If init fails or indexing fails, set `{ccc_discovery: []}` and continue — this is not an error.
110
+
111
+ 2. **Construct semantic query:** Build from brief data: `"{brief.name} {brief.scope}"`. Truncate to 80 characters — keep the full skill name and trim `brief.scope` from the end. If `brief.scope` is very short (< 10 chars), append terms from `brief.description` to fill the remaining space.
112
+
113
+ 3. **Execute search:** Run `ccc_bridge.search(query, temp_path, top_k=20)`:
114
+ - **Tool resolution:** Use `/ccc` skill search (Claude Code), ccc MCP server (Cursor), or `ccc search "{query}" --path {temp_path} --top 20` (CLI). See [knowledge/tool-resolution.md](../../../knowledge/tool-resolution.md).
115
+
116
+ 4. **Store results:** If search succeeds, store as `{ccc_discovery: [{file, score, snippet}]}`. Display: "**CCC semantic discovery (post-clone): {N} relevant regions identified across {M} unique files.**"
117
+
118
+ 5. **On failure:** Set `{ccc_discovery: []}`. Display: "CCC post-clone discovery unavailable — proceeding with standard extraction." Do NOT halt.
119
+
99
120
  **CCC Discovery Integration (Forge+ and Deep with ccc only):**
100
121
 
101
- If `{ccc_discovery}` is in context and non-empty (populated by step-02b):
122
+ If `{ccc_discovery}` is in context and non-empty (populated by step-02b or deferred discovery above):
102
123
  - Sort the filtered file list by CCC relevance score: files appearing in `{ccc_discovery}` results move to the front of the extraction queue, sorted by their relevance score descending
103
124
  - Files NOT in CCC results remain in the queue after ranked files — they are not excluded, only deprioritized
104
125
  - Display: "**CCC discovery: {N} files pre-ranked by semantic relevance** — extraction will prioritize these first."
@@ -9,7 +9,7 @@ nextStepFile: './step-02-write-config.md'
9
9
 
10
10
  ## STEP GOAL:
11
11
 
12
- If ccc is available (`{ccc: true}` from step-01), verify that the ccc index exists for the project root. If no index exists, create it. Store index state in context for step-02 to write into forge-tier.yaml.
12
+ If ccc is available (`{ccc: true}` from step-01), configure CCC exclusion patterns for SKF infrastructure directories, verify that the ccc index exists for the project root, and create or refresh it if needed. Store index state and exclusion patterns in context for step-02 to write into forge-tier.yaml.
13
13
 
14
14
  For Quick and Forge tiers, or when ccc is unavailable, skip silently and proceed.
15
15
 
@@ -32,7 +32,7 @@ For Quick and Forge tiers, or when ccc is unavailable, skip silently and proceed
32
32
  - 🎯 Focus only on ccc index verification and creation
33
33
  - 🚫 FORBIDDEN to display skip messages for Quick/Forge tiers
34
34
  - 🚫 FORBIDDEN to fail the workflow if ccc indexing fails
35
- - 🚫 FORBIDDEN to re-index if ccc index already exists and is fresh (< staleness threshold)
35
+ - 🚫 FORBIDDEN to re-index if ccc index already exists and is fresh (< staleness threshold) UNLESS new exclusion patterns were applied to settings.yml
36
36
 
37
37
  ## EXECUTION PROTOCOLS:
38
38
 
@@ -56,7 +56,7 @@ For Quick and Forge tiers, or when ccc is unavailable, skip silently and proceed
56
56
 
57
57
  Read `{ccc}` from step-01 context.
58
58
 
59
- **If `{ccc}` is false:** Set `{ccc_index_result: "none", ccc_indexed_path: null, ccc_last_indexed: null}`. Proceed directly to section 4 (Auto-Proceed) — no output, no messaging.
59
+ **If `{ccc}` is false:** Set `{ccc_index_result: "none", ccc_indexed_path: null, ccc_last_indexed: null, ccc_exclude_patterns: []}`. Proceed directly to section 4 (Auto-Proceed) — no output, no messaging.
60
60
 
61
61
  **If `{ccc}` is true:** Continue to section 2.
62
62
 
@@ -64,17 +64,58 @@ Read `{ccc}` from step-01 context.
64
64
 
65
65
  Read existing forge-tier.yaml at `{project-root}/_bmad/_memory/forger-sidecar/forge-tier.yaml` (if it exists from a previous run).
66
66
 
67
+ Read `staleness_threshold_hours` from `ccc_index.staleness_threshold_hours` in the existing forge-tier.yaml (default: 24 if not present or not a number). Use this value for the freshness check below.
68
+
67
69
  Check the `ccc_index` section:
68
- - If `ccc_index.indexed_path` matches `{project-root}` AND `ccc_index.status` is `"fresh"`:
69
- - Check freshness: if `ccc_index.last_indexed` is within `staleness_threshold_hours` (default 24h) of now → index is fresh
70
+ - If `ccc_index.indexed_path` matches `{project-root}` AND `ccc_index.status` is `"fresh"` or `"created"`:
71
+ - Check freshness: if `ccc_index.last_indexed` is within `staleness_threshold_hours` of now → index is fresh
70
72
  - Store `{ccc_index_result: "fresh", ccc_indexed_path: {project-root}, ccc_last_indexed: {existing timestamp}}`
71
- - Proceed to section 4
73
+ - Set `{needs_reindex: false}` — proceed to section 2b (exclusions must still be configured)
72
74
 
73
75
  - If `ccc_index.indexed_path` matches `{project-root}` but timestamp is older than threshold:
74
- - Note index is stale — proceed to section 3 for re-index (section 3 will overwrite `ccc_index_result` to `"created"` or `"failed"`)
76
+ - Set `{needs_reindex: true}` — proceed to section 2b then section 3
75
77
 
76
78
  - If `ccc_index` is missing, has null values, or path doesn't match:
77
- - Proceed to section 3 for initial index
79
+ - Set `{needs_reindex: true}` — proceed to section 2b then section 3
80
+
81
+ ### 2b. Configure CCC Exclusions
82
+
83
+ SKF infrastructure and output directories must be excluded from the CCC index — they contain workflow instructions, build artifacts, and generated skills that pollute semantic search results with zero extraction value.
84
+
85
+ **Build the SKF exclusion list:**
86
+
87
+ 1. Read `{project-root}/_bmad/_config/skf-manifest.yaml` to resolve configurable paths:
88
+ - `skills_output_folder` (default: `skills` if manifest is missing or field is absent)
89
+ - `forge_data_folder` (default: `forge-data` if manifest is missing or field is absent)
90
+
91
+ 2. Assemble the exclusion patterns using `**/` prefix format (matching `.cocoindex_code/settings.yml` convention — e.g., `**/node_modules`):
92
+ - `**/_bmad` — SKF framework module (workflows, agents, knowledge files)
93
+ - `**/_bmad-output` — Build output artifacts
94
+ - `**/.claude` — Claude Code configuration
95
+ - `**/_skf-learn` — SKF learning materials
96
+ - `**/{skills_output_folder}` — Generated skill files (resolved from manifest)
97
+ - `**/{forge_data_folder}` — Compilation workspace (resolved from manifest)
98
+
99
+ 3. Store `{ccc_exclude_patterns}` in context for step-02 to write into forge-tier.yaml.
100
+
101
+ **Apply exclusions to settings.yml:**
102
+
103
+ Check if `{project-root}/.cocoindex_code/settings.yml` exists. Set `{settings_yml_existed: true}` if it does, `{settings_yml_existed: false}` if not.
104
+
105
+ If `{settings_yml_existed}` is true (from a previous `ccc init` run):
106
+
107
+ 1. Read `settings.yml`
108
+ 2. For each pattern in `{ccc_exclude_patterns}`: if the pattern is NOT already present in `exclude_patterns`, append it and set `{exclusions_changed: true}`
109
+ 3. If `{exclusions_changed}`: write the updated `settings.yml` back, set `{needs_reindex: true}` (new exclusions require re-indexing), display: "**CCC exclusions configured:** {count} SKF patterns applied to .cocoindex_code/settings.yml"
110
+ 4. If no new patterns needed: display nothing (exclusions already configured)
111
+
112
+ This preserves any existing user customizations and default exclusions while ensuring SKF directories are filtered out.
113
+
114
+ If `{settings_yml_existed}` is false: the exclusions will be applied after `ccc init` in section 3.
115
+
116
+ **Flow decision:**
117
+ - If `{needs_reindex}` is true: proceed to section 3
118
+ - If `{needs_reindex}` is false: proceed to section 4 (Auto-Proceed)
78
119
 
79
120
  ### 3. Create or Refresh CCC Index
80
121
 
@@ -93,6 +134,15 @@ ccc init
93
134
 
94
135
  **If init fails** (project may already be initialized): continue — this is not an error.
95
136
 
137
+ **Apply SKF exclusion patterns (if not already applied in section 2b):**
138
+
139
+ If `{settings_yml_existed}` is false (first-time setup — `ccc init` just created it), apply exclusions now:
140
+
141
+ 1. Read `{project-root}/.cocoindex_code/settings.yml` (created by `ccc init`)
142
+ 2. For each pattern in `{ccc_exclude_patterns}`: if the pattern is NOT already present in `exclude_patterns`, append it
143
+ 3. Write the updated `settings.yml` back
144
+ 4. Display: "**CCC exclusions configured:** {count} SKF patterns applied to .cocoindex_code/settings.yml"
145
+
96
146
  Then run:
97
147
  ```bash
98
148
  ccc index
@@ -102,8 +152,8 @@ ccc index
102
152
 
103
153
  **If succeeds:**
104
154
  - Run `ccc status` to get file count
105
- - Store `{ccc_index_result: "created", ccc_indexed_path: {project-root}, ccc_last_indexed: {current ISO timestamp}, ccc_file_count: {count from status}}`
106
- - Display: "**CCC index created.** {file_count} files indexed for semantic discovery."
155
+ - Store `{ccc_index_result: "created", ccc_indexed_path: {project-root}, ccc_last_indexed: {current ISO timestamp}, ccc_file_count: {count from ccc status}}`
156
+ - Display: "**CCC index created.** {ccc_file_count} files indexed for semantic discovery."
107
157
 
108
158
  **If fails:**
109
159
  - Store `{ccc_index_result: "failed", ccc_indexed_path: null, ccc_last_indexed: null}`
@@ -134,8 +184,8 @@ ONLY WHEN ccc index verification is complete (or step is skipped for ccc unavail
134
184
  ### ✅ SUCCESS:
135
185
 
136
186
  - ccc unavailable: skipped silently with no output, context variables set to null/none
137
- - ccc available with fresh index: verified freshness, skipped re-index, context variables set
138
- - ccc available with stale/missing index: index created, context variables set with fresh timestamp
187
+ - ccc available with fresh index: verified freshness, exclusions configured, skipped re-index, context variables set
188
+ - ccc available with stale/missing index: exclusions configured, index created, context variables set with fresh timestamp
139
189
  - ccc indexing fails: logged gracefully, workflow continues, context variables set to failed/null
140
190
  - Auto-proceeded to step-02
141
191
 
@@ -143,8 +193,10 @@ ONLY WHEN ccc index verification is complete (or step is skipped for ccc unavail
143
193
 
144
194
  - Displaying skip messages when ccc is unavailable
145
195
  - Halting the workflow on ccc index failure
146
- - Re-indexing when index is already fresh and path matches
196
+ - Re-indexing when index is already fresh and path matches (unless exclusion patterns changed)
147
197
  - Writing forge-tier.yaml (that is step-02's responsibility)
148
198
  - Not storing ccc index context variables for step-02
199
+ - Indexing without configuring SKF exclusion patterns in `.cocoindex_code/settings.yml`
200
+ - Overwriting user customizations in `.cocoindex_code/settings.yml` instead of appending
149
201
 
150
202
  **Master Rule:** CCC indexing is always best-effort. Failures degrade gracefully. The workflow never halts over ccc issues.
@@ -41,7 +41,7 @@ Write the detected tool availability and calculated tier to forge-tier.yaml, cre
41
41
 
42
42
  ## CONTEXT BOUNDARIES:
43
43
 
44
- - Available: {detected_tools}, {calculated_tier}, {previous_tier} from step-01; {ccc_index_result}, {ccc_indexed_path}, {ccc_last_indexed} from step-01b
44
+ - Available: {detected_tools}, {calculated_tier}, {previous_tier} from step-01; {ccc_index_result}, {ccc_indexed_path}, {ccc_last_indexed}, {ccc_file_count}, {ccc_exclude_patterns} from step-01b
45
45
  - Focus: file I/O operations only
46
46
  - Limits: do not modify preferences.yaml if it exists
47
47
  - Dependencies: step-01 and step-01b must have completed with tool detection and CCC index results
@@ -78,6 +78,8 @@ ccc_index:
78
78
  last_indexed: {ccc_last_indexed from step-01b, or ~}
79
79
  status: {ccc_index_result from step-01b: "fresh"|"created"|"none"|"failed"}
80
80
  staleness_threshold_hours: 24
81
+ file_count: {ccc_file_count from step-01b, or ~}
82
+ exclude_patterns: {ccc_exclude_patterns from step-01b, or []}
81
83
 
82
84
  # CCC index registry (tracks which source paths have been indexed for skill workflows)
83
85
  # PRESERVE existing entries on re-runs — see Note below
@@ -88,7 +90,7 @@ ccc_index_registry: {preserved from existing forge-tier.yaml, or [] if first run
88
90
  qmd_collections: {preserved from existing forge-tier.yaml, or [] if first run}
89
91
  ```
90
92
 
91
- **Note on re-runs:** The `qmd_collections`, `ccc_index_registry` arrays, and `staleness_threshold_hours` value must be preserved across re-runs. Before overwriting forge-tier.yaml, read these existing values and re-inject them into the new write. These values are populated by create-skill workflows or customized by users and must not be reset.
93
+ **Note on re-runs:** The `qmd_collections`, `ccc_index_registry` arrays, and `staleness_threshold_hours` value must be preserved across re-runs. Before overwriting forge-tier.yaml, read these existing values and re-inject them into the new write. These values are populated by create-skill workflows or customized by users and must not be reset. Note: `exclude_patterns` is NOT preserved — it is always written fresh from `{ccc_exclude_patterns}` computed by step-01b.
92
94
 
93
95
  **This file is ALWAYS overwritten** on every run — it reflects current tool state.
94
96
 
@@ -150,7 +152,7 @@ ONLY WHEN forge-tier.yaml has been written successfully and preferences.yaml exi
150
152
 
151
153
  ### ✅ SUCCESS:
152
154
 
153
- - forge-tier.yaml written with accurate tool booleans (including ccc), tier, timestamp, ccc_index state, and preserved qmd_collections/ccc_index_registry arrays
155
+ - forge-tier.yaml written with accurate tool booleans (including ccc), tier, timestamp, ccc_index state (including exclude_patterns), and preserved qmd_collections/ccc_index_registry arrays
154
156
  - preferences.yaml exists (created with defaults on first run, preserved on re-run)
155
157
  - forge-data/ directory exists (created or pre-existing)
156
158
  - Auto-proceeded to step-03
@@ -139,6 +139,8 @@ This helps the merge step (section 4) prioritize which changes are most likely t
139
139
 
140
140
  CCC failures: skip ranking silently, all changes treated equally.
141
141
 
142
+ **Note on remote sources:** If `source_root` is an ephemeral clone (remote source), the clone path is not indexed by CCC. The search will return empty results and semantic ranking will be skipped. This is expected — deferred CCC indexing is implemented in create-skill step-03 but not in update-skill. All changes are treated equally for remote sources.
143
+
142
144
  **IF `tools.ccc` is false:** Skip this section silently.
143
145
 
144
146
  ### 3. Deep Tier QMD Enrichment (Conditional)