@harness-engineering/cli 1.26.1 → 1.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/skills/claude-code/cleanup-dead-code/SKILL.md +3 -1
- package/dist/agents/skills/claude-code/detect-doc-drift/SKILL.md +3 -1
- package/dist/agents/skills/claude-code/harness-architecture-advisor/SKILL.md +4 -0
- package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +55 -24
- package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +16 -5
- package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +21 -6
- package/dist/agents/skills/claude-code/harness-codebase-cleanup/SKILL.md +2 -0
- package/dist/agents/skills/claude-code/harness-debugging/SKILL.md +13 -1
- package/dist/agents/skills/claude-code/harness-dependency-health/SKILL.md +4 -0
- package/dist/agents/skills/claude-code/harness-execution/SKILL.md +16 -6
- package/dist/agents/skills/claude-code/harness-impact-analysis/SKILL.md +2 -0
- package/dist/agents/skills/claude-code/harness-integration/SKILL.md +560 -0
- package/dist/agents/skills/claude-code/harness-integration/skill.yaml +65 -0
- package/dist/agents/skills/claude-code/harness-integrity/SKILL.md +2 -0
- package/dist/agents/skills/claude-code/harness-onboarding/SKILL.md +4 -0
- package/dist/agents/skills/claude-code/harness-perf/SKILL.md +9 -7
- package/dist/agents/skills/claude-code/harness-planning/SKILL.md +77 -10
- package/dist/agents/skills/claude-code/harness-refactoring/SKILL.md +13 -4
- package/dist/agents/skills/claude-code/harness-security-scan/SKILL.md +3 -1
- package/dist/agents/skills/claude-code/harness-soundness-review/SKILL.md +4 -0
- package/dist/agents/skills/claude-code/harness-tdd/SKILL.md +5 -2
- package/dist/agents/skills/claude-code/harness-verification/SKILL.md +4 -0
- package/dist/agents/skills/codex/cleanup-dead-code/SKILL.md +3 -1
- package/dist/agents/skills/codex/detect-doc-drift/SKILL.md +3 -1
- package/dist/agents/skills/codex/harness-architecture-advisor/SKILL.md +4 -0
- package/dist/agents/skills/codex/harness-autopilot/SKILL.md +55 -24
- package/dist/agents/skills/codex/harness-brainstorming/SKILL.md +16 -5
- package/dist/agents/skills/codex/harness-code-review/SKILL.md +21 -6
- package/dist/agents/skills/codex/harness-codebase-cleanup/SKILL.md +2 -0
- package/dist/agents/skills/codex/harness-debugging/SKILL.md +13 -1
- package/dist/agents/skills/codex/harness-dependency-health/SKILL.md +4 -0
- package/dist/agents/skills/codex/harness-execution/SKILL.md +16 -6
- package/dist/agents/skills/codex/harness-impact-analysis/SKILL.md +2 -0
- package/dist/agents/skills/codex/harness-integration/SKILL.md +560 -0
- package/dist/agents/skills/codex/harness-integration/skill.yaml +65 -0
- package/dist/agents/skills/codex/harness-integrity/SKILL.md +2 -0
- package/dist/agents/skills/codex/harness-onboarding/SKILL.md +4 -0
- package/dist/agents/skills/codex/harness-perf/SKILL.md +9 -7
- package/dist/agents/skills/codex/harness-planning/SKILL.md +77 -10
- package/dist/agents/skills/codex/harness-refactoring/SKILL.md +13 -4
- package/dist/agents/skills/codex/harness-security-scan/SKILL.md +3 -1
- package/dist/agents/skills/codex/harness-soundness-review/SKILL.md +4 -0
- package/dist/agents/skills/codex/harness-tdd/SKILL.md +5 -2
- package/dist/agents/skills/codex/harness-verification/SKILL.md +4 -0
- package/dist/agents/skills/cursor/cleanup-dead-code/SKILL.md +3 -1
- package/dist/agents/skills/cursor/detect-doc-drift/SKILL.md +3 -1
- package/dist/agents/skills/cursor/harness-architecture-advisor/SKILL.md +4 -0
- package/dist/agents/skills/cursor/harness-autopilot/SKILL.md +55 -24
- package/dist/agents/skills/cursor/harness-brainstorming/SKILL.md +16 -5
- package/dist/agents/skills/cursor/harness-code-review/SKILL.md +21 -6
- package/dist/agents/skills/cursor/harness-codebase-cleanup/SKILL.md +2 -0
- package/dist/agents/skills/cursor/harness-debugging/SKILL.md +13 -1
- package/dist/agents/skills/cursor/harness-dependency-health/SKILL.md +4 -0
- package/dist/agents/skills/cursor/harness-execution/SKILL.md +16 -6
- package/dist/agents/skills/cursor/harness-impact-analysis/SKILL.md +2 -0
- package/dist/agents/skills/cursor/harness-integration/SKILL.md +560 -0
- package/dist/agents/skills/cursor/harness-integration/skill.yaml +65 -0
- package/dist/agents/skills/cursor/harness-integrity/SKILL.md +2 -0
- package/dist/agents/skills/cursor/harness-onboarding/SKILL.md +4 -0
- package/dist/agents/skills/cursor/harness-perf/SKILL.md +9 -7
- package/dist/agents/skills/cursor/harness-planning/SKILL.md +77 -10
- package/dist/agents/skills/cursor/harness-refactoring/SKILL.md +13 -4
- package/dist/agents/skills/cursor/harness-security-scan/SKILL.md +3 -1
- package/dist/agents/skills/cursor/harness-soundness-review/SKILL.md +4 -0
- package/dist/agents/skills/cursor/harness-tdd/SKILL.md +5 -2
- package/dist/agents/skills/cursor/harness-verification/SKILL.md +4 -0
- package/dist/agents/skills/gemini-cli/cleanup-dead-code/SKILL.md +3 -1
- package/dist/agents/skills/gemini-cli/detect-doc-drift/SKILL.md +3 -1
- package/dist/agents/skills/gemini-cli/harness-architecture-advisor/SKILL.md +4 -0
- package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +55 -24
- package/dist/agents/skills/gemini-cli/harness-brainstorming/SKILL.md +16 -5
- package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +21 -6
- package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/SKILL.md +2 -0
- package/dist/agents/skills/gemini-cli/harness-debugging/SKILL.md +13 -1
- package/dist/agents/skills/gemini-cli/harness-dependency-health/SKILL.md +4 -0
- package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +16 -6
- package/dist/agents/skills/gemini-cli/harness-impact-analysis/SKILL.md +2 -0
- package/dist/agents/skills/gemini-cli/harness-integration/SKILL.md +560 -0
- package/dist/agents/skills/gemini-cli/harness-integration/skill.yaml +65 -0
- package/dist/agents/skills/gemini-cli/harness-integrity/SKILL.md +2 -0
- package/dist/agents/skills/gemini-cli/harness-onboarding/SKILL.md +4 -0
- package/dist/agents/skills/gemini-cli/harness-perf/SKILL.md +9 -7
- package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +77 -10
- package/dist/agents/skills/gemini-cli/harness-refactoring/SKILL.md +13 -4
- package/dist/agents/skills/gemini-cli/harness-security-scan/SKILL.md +3 -1
- package/dist/agents/skills/gemini-cli/harness-soundness-review/SKILL.md +4 -0
- package/dist/agents/skills/gemini-cli/harness-tdd/SKILL.md +5 -2
- package/dist/agents/skills/gemini-cli/harness-verification/SKILL.md +4 -0
- package/dist/{agents-md-VI3HLR7E.js → agents-md-2RN666DE.js} +3 -3
- package/dist/{architecture-ZDDKEVID.js → architecture-ZR33YKJB.js} +4 -4
- package/dist/{assess-project-Y6W7YDUA.js → assess-project-LLWWEQEV.js} +1 -1
- package/dist/bin/harness-mcp.js +17 -16
- package/dist/bin/harness.js +27 -26
- package/dist/{business-knowledge-6RHYJOB3.js → business-knowledge-EISPR7FU.js} +1 -1
- package/dist/{check-phase-gate-CXR3VM22.js → check-phase-gate-ZVG56NT2.js} +4 -4
- package/dist/chunk-27AJKSQY.js +107 -0
- package/dist/{chunk-DBIX3X4H.js → chunk-2FOLD76X.js} +2 -2
- package/dist/{chunk-3AMQYWGT.js → chunk-3AJW7VQ3.js} +2 -2
- package/dist/{chunk-FUND5WJR.js → chunk-3XMOWLK3.js} +2 -2
- package/dist/{chunk-OLW7BJ5N.js → chunk-776JFSPK.js} +1 -1
- package/dist/{chunk-VKS3F46M.js → chunk-A4ETL34H.js} +7 -2
- package/dist/{chunk-JV4Y2U5F.js → chunk-BO4AJZRE.js} +1 -1
- package/dist/{chunk-WZ7UHPT3.js → chunk-BZZNYHRY.js} +9 -9
- package/dist/{chunk-ZN6ROTYP.js → chunk-C7RPQWBG.js} +1 -1
- package/dist/{chunk-RAVD7QLY.js → chunk-CJYNZMOP.js} +8 -8
- package/dist/{chunk-PNNFCVW4.js → chunk-EGRQHLDM.js} +5 -5
- package/dist/{chunk-2BPPS6YQ.js → chunk-EHTUWULH.js} +458 -363
- package/dist/{chunk-N6B6RKQQ.js → chunk-EICASBYP.js} +1 -1
- package/dist/{chunk-K56DTX7G.js → chunk-F3Y64VNF.js} +6 -6
- package/dist/{chunk-ORNEK65Y.js → chunk-FUS4OOGC.js} +1 -1
- package/dist/{chunk-2FPUPRCY.js → chunk-GAIOIINV.js} +594 -127
- package/dist/{chunk-YC4EYIER.js → chunk-IBTHD2UA.js} +132 -77
- package/dist/{chunk-RC5ZY3EV.js → chunk-IOW3MW2K.js} +2 -2
- package/dist/{chunk-B66LRB5M.js → chunk-L3Y7L4EG.js} +1 -1
- package/dist/{chunk-BK4DJIIY.js → chunk-MGPVA2EM.js} +27 -4
- package/dist/{chunk-NY7DTZ6K.js → chunk-Q5DKIL46.js} +3 -3
- package/dist/{chunk-TY2ESLVL.js → chunk-SDDQPMZK.js} +1 -1
- package/dist/{chunk-7GY6WNEI.js → chunk-SDPHFDQS.js} +1 -1
- package/dist/{chunk-56A6OXVA.js → chunk-T7UZOJF4.js} +9 -9
- package/dist/{chunk-AMRC4FU2.js → chunk-VCC47EXU.js} +109 -57
- package/dist/{chunk-Q3ZLVMQM.js → chunk-XKU37HGH.js} +10 -1
- package/dist/{chunk-TSVYBDDE.js → chunk-YZH4I4JO.js} +1 -1
- package/dist/{ci-workflow-EW37KVPS.js → ci-workflow-JFOL4YWW.js} +3 -3
- package/dist/{dist-NCNAXUFD.js → dist-BZS2XRLG.js} +5 -1
- package/dist/{dist-CJDGASPP.js → dist-CPKL5Y2R.js} +2 -2
- package/dist/{docs-4XI2FQW2.js → docs-FUTRJQHA.js} +4 -4
- package/dist/{engine-4L4CDTHU.js → engine-FB3HCNVT.js} +3 -3
- package/dist/{entropy-PBYSIQYS.js → entropy-FIEE4YDA.js} +3 -3
- package/dist/{feedback-OTIFW5MK.js → feedback-7EC4T6XG.js} +1 -1
- package/dist/{generate-agent-definitions-CZGUXIIN.js → generate-agent-definitions-FOSFADNR.js} +4 -4
- package/dist/{graph-loader-RDXSEBD7.js → graph-loader-QEI7SYOQ.js} +1 -1
- package/dist/hooks/adoption-tracker.js +36 -8
- package/dist/hooks/sentinel-pre.js +3 -2
- package/dist/hooks/telemetry-reporter.js +34 -15
- package/dist/index-builder-3AOQ3ZII.js +13 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +29 -28
- package/dist/{loader-UZOXCWFC.js → loader-HXUOBTYA.js} +3 -3
- package/dist/{mcp-GWVVV6LH.js → mcp-NUG4BMKJ.js} +17 -16
- package/dist/{performance-5UQPP3XX.js → performance-TYXBCTR7.js} +4 -4
- package/dist/{review-pipeline-65V4EO6O.js → review-pipeline-B4WPU6BQ.js} +3 -3
- package/dist/{runtime-PXX7HNB3.js → runtime-HQQNOARD.js} +3 -3
- package/dist/{scan-WM7XDUF7.js → scan-M4EGDAQ2.js} +1 -1
- package/dist/{security-CAYDRZIZ.js → security-25VFLIAO.js} +1 -1
- package/dist/templates/orchestrator/harness.orchestrator.md +18 -8
- package/dist/{validate-CWGXR7QM.js → validate-EAVGKZQB.js} +4 -4
- package/dist/{validate-cross-check-BKCNLZYG.js → validate-cross-check-SPL3H4O5.js} +3 -3
- package/package.json +13 -5
- package/dist/hooks/profiles.ts +0 -48
|
@@ -22,26 +22,28 @@ Tier 1 violations are non-negotiable blockers. If a Tier 1 violation is detected
|
|
|
22
22
|
|
|
23
23
|
### Phase 1: ANALYZE — Structural and Coupling Checks
|
|
24
24
|
|
|
25
|
-
1. **
|
|
25
|
+
1. **Assess current performance posture.** Run `check_performance` to evaluate current performance metrics against defined budgets. Run `get_critical_paths` to identify performance-critical functions and hot paths.
|
|
26
|
+
|
|
27
|
+
2. **Run structural checks.** Execute `harness check-perf --structural` to compute complexity metrics for all changed files:
|
|
26
28
|
- Cyclomatic complexity per function
|
|
27
29
|
- Nesting depth per function
|
|
28
30
|
- File length (lines of code)
|
|
29
31
|
- Parameter count per function
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
3. **Run coupling checks.** Execute `harness check-perf --coupling` to compute coupling metrics:
|
|
32
34
|
- Fan-in and fan-out per module
|
|
33
35
|
- Afferent and efferent coupling
|
|
34
36
|
- Transitive dependency depth
|
|
35
37
|
- Circular dependency detection
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
4. **Classify violations by tier:**
|
|
38
40
|
- **Tier 1 (error, block commit):** Cyclomatic complexity > 15, circular dependencies, hotspot in top 5%
|
|
39
41
|
- **Tier 2 (warning, block merge):** Complexity > 10, nesting > 4, fan-out > 10, size budget exceeded
|
|
40
42
|
- **Tier 3 (info, no gate):** File length > 300, fan-in > 20, transitive depth > 30
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
5. **If Tier 1 violations found,** report them immediately and STOP. Do not proceed to benchmarks. The violations must be fixed first.
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
6. **If no violations found,** proceed to Phase 2.
|
|
45
47
|
|
|
46
48
|
---
|
|
47
49
|
|
|
@@ -83,7 +85,7 @@ This phase runs only when `.bench.ts` files exist in the project. If none are fo
|
|
|
83
85
|
|
|
84
86
|
4. **Run benchmarks.** Execute `harness perf bench` to run all benchmark suites.
|
|
85
87
|
|
|
86
|
-
5. **Load baselines.** Read `.harness/perf/baselines.json` for previous benchmark results. If no baselines exist, treat this as a baseline-capture run.
|
|
88
|
+
5. **Load baselines.** Load existing baselines via `get_perf_baselines` before running new benchmarks. Read `.harness/perf/baselines.json` for previous benchmark results. If no baselines exist, treat this as a baseline-capture run.
|
|
87
89
|
|
|
88
90
|
6. **Compare results against baselines** using the `RegressionDetector`:
|
|
89
91
|
- Calculate percentage change for each benchmark
|
|
@@ -100,7 +102,7 @@ This phase runs only when `.bench.ts` files exist in the project. If none are fo
|
|
|
100
102
|
- **Tier 2:** >10% regression on a non-critical-path benchmark
|
|
101
103
|
- **Tier 3:** >5% regression on a non-critical-path benchmark (within noise margin consideration)
|
|
102
104
|
|
|
103
|
-
9. **If this is a baseline-capture run,** report results without regression comparison. Recommend running `harness perf baselines update` to persist.
|
|
105
|
+
9. **If this is a baseline-capture run,** report results without regression comparison. Recommend running `harness perf baselines update` to persist. After benchmarks pass, update baselines via `update_perf_baselines` to record new performance targets.
|
|
104
106
|
|
|
105
107
|
---
|
|
106
108
|
|
|
@@ -29,6 +29,7 @@ The `rigorLevel` is passed by autopilot (or set via `--fast`/`--thorough` flags)
|
|
|
29
29
|
| Phase | `fast` | `standard` (default) | `thorough` |
|
|
30
30
|
| --------- | -------------------------------------------------- | ------------------------------------------ | --------------------------------------------------- |
|
|
31
31
|
| SCOPE | No change. | No change. | No change. |
|
|
32
|
+
| KNOWLEDGE | Skip entirely. | Run detect; fix if gaps found. | Run detect; fix if gaps found. |
|
|
32
33
|
| DECOMPOSE | Skip skeleton. Full tasks directly after file map. | Skeleton if tasks >= 8; full tasks if < 8. | Always skeleton. Require approval before expanding. |
|
|
33
34
|
| SEQUENCE | No change. | No change. | No change. |
|
|
34
35
|
| VALIDATE | No change. | No change. | No change. |
|
|
@@ -41,7 +42,7 @@ The skeleton pass is the primary rigor lever. Fast mode goes straight to full de
|
|
|
41
42
|
|
|
42
43
|
When invoked by autopilot (or with explicit arguments), resolve paths before starting:
|
|
43
44
|
|
|
44
|
-
1. **Session slug:** If `session-slug` argument provided, set `{sessionDir} = .harness/sessions/<session-slug>/`. Pass to `gather_context({ session: "<session-slug>" })`. All handoff writes go to `{sessionDir}/handoff.json`.
|
|
45
|
+
1. **Session slug:** If `session-slug` argument provided, set `{sessionDir} = .harness/sessions/<session-slug>/`. Pass to `gather_context({ session: "<session-slug>", include: ["state", "learnings", "handoff", "graph", "businessKnowledge", "sessions", "validation"] })`. All handoff writes go to `{sessionDir}/handoff.json`.
|
|
45
46
|
2. **Spec path:** If `spec-path` argument provided, read spec from that path. Otherwise, discover from `{sessionDir}/handoff.json` (read upstream brainstorming output) or prompt the user.
|
|
46
47
|
3. **Rigor level:** If `fast`/`thorough` argument provided, use it. Otherwise default to `standard`.
|
|
47
48
|
|
|
@@ -69,14 +70,16 @@ Work backward from the goal. Start with "what must be true when we are done?"
|
|
|
69
70
|
|
|
70
71
|
Store the parsed skill list for use in Phase 2 task annotation.
|
|
71
72
|
|
|
72
|
-
2. **
|
|
73
|
+
2. **Review prior decisions.** Check `decisions` from the prior brainstorming session (loaded via `sessions` in gather_context). Do not re-decide what was already decided — build on those choices.
|
|
74
|
+
|
|
75
|
+
3. **Derive observable truths.** What can be observed (running a command, opening a browser, reading a file) that proves the goal is met? Be specific:
|
|
73
76
|
- BAD: "The API handles errors"
|
|
74
77
|
- GOOD: "GET /api/users/nonexistent returns 404 with `{ error: 'User not found' }` body"
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
4. **Derive required artifacts.** For each truth, what files must exist? What functions? What tests pass? List exact file paths.
|
|
79
|
+
5. **Identify key links.** How do artifacts connect? What imports what? What calls what?
|
|
80
|
+
6. **Apply YAGNI.** For every artifact: "Is this required for an observable truth?" If not, cut it.
|
|
78
81
|
|
|
79
|
-
|
|
82
|
+
7. **Surface uncertainties.** Before proceeding to Phase 2, explicitly list what you do NOT know. For each uncertainty, classify it:
|
|
80
83
|
- **Blocking:** Cannot decompose tasks without resolving this. Escalate to user.
|
|
81
84
|
- **Assumption:** Can proceed with a stated assumption. Document it. If wrong, specific tasks will need revision.
|
|
82
85
|
- **Deferrable:** Does not affect task decomposition. Note for execution phase.
|
|
@@ -90,7 +93,7 @@ Store the parsed skill list for use in Phase 2 task annotation.
|
|
|
90
93
|
- [DEFERRABLE] Exact error message wording. (Can be finalized during implementation.)
|
|
91
94
|
```
|
|
92
95
|
|
|
93
|
-
**Read-only constraint:** Steps 1-
|
|
96
|
+
**Read-only constraint:** Steps 1-6 above are research and analysis. Do not propose task structure, file organization, or implementation approaches during SCOPE. Record what must be true (observable truths) and what you do not know (uncertainties). Solutions belong in DECOMPOSE.
|
|
94
97
|
|
|
95
98
|
When scope is ambiguous, use `emit_interaction`:
|
|
96
99
|
|
|
@@ -160,9 +163,39 @@ When a knowledge graph exists at `.harness/graph/`, use graph queries for faster
|
|
|
160
163
|
|
|
161
164
|
- `query_graph` — discover module dependencies for realistic task decomposition
|
|
162
165
|
- `get_impact` — estimate which modules a feature touches
|
|
166
|
+
- `compute_blast_radius` — simulate failure propagation from target files to understand scope
|
|
167
|
+
- `predict_failures` — forecast which architectural constraints are at risk from planned changes, informing where extra test coverage or smaller tasks are needed
|
|
168
|
+
- `detect_anomalies` — identify structural irregularities in the affected area before planning tasks around them
|
|
163
169
|
|
|
164
170
|
Fall back to file-based commands if no graph is available.
|
|
165
171
|
|
|
172
|
+
### Intelligence Signals (when orchestrator is available)
|
|
173
|
+
|
|
174
|
+
If the orchestrator is running, request intelligence analysis via `POST /api/analyze` with the feature title/description before decomposing. The pipeline returns:
|
|
175
|
+
|
|
176
|
+
- **SEL** (Spec Enrichment) — affected systems and blast radius derived from the graph
|
|
177
|
+
- **CML** (Complexity Modeling) — structural, semantic, and historical complexity scores. Use `structuralComplexity > 0.7` to flag areas needing smaller, more cautious tasks.
|
|
178
|
+
- **PESL** (Pre-Execution Simulation) — simulated risk score. Use `riskScore > 0.6` to add extra checkpoints or split risky tasks further.
|
|
179
|
+
|
|
180
|
+
If no orchestrator, `predict_failures` and `compute_blast_radius` MCP tools provide equivalent directional signals.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### Phase 1.5: KNOWLEDGE BASELINE — Materialize Domain Knowledge
|
|
185
|
+
|
|
186
|
+
Before decomposing into tasks, ensure domain knowledge from PRDs and specs is documented. **Skip this phase** when no PRDs, specs, or business domain documents exist in the project, or when rigor level is `fast`.
|
|
187
|
+
|
|
188
|
+
1. **Run knowledge pipeline in detect mode.** Execute `harness knowledge-pipeline --domain <feature-domain>` to produce a differential gap report comparing extracted business rules against documented knowledge in `docs/knowledge/`.
|
|
189
|
+
|
|
190
|
+
2. **If gaps exist and `--fix` is appropriate,** run `harness knowledge-pipeline --fix --domain <feature-domain>` to materialize `docs/knowledge/{domain}/*.md` files from extracted findings. This creates the knowledge baseline from PRDs before any tasks are written.
|
|
191
|
+
|
|
192
|
+
3. **Cross-check uncertainties against materialized knowledge** (from `businessKnowledge` loaded in gather_context and freshly materialized docs):
|
|
193
|
+
- Remove "assumptions" from the uncertainty list that are now documented facts in `docs/knowledge/`
|
|
194
|
+
- Escalate if contradictions exist between PRDs and existing knowledge docs
|
|
195
|
+
- Use `business_fact` nodes from the graph context to validate domain assumptions
|
|
196
|
+
|
|
197
|
+
4. **Reference materialized knowledge in Phase 2 task decomposition.** Tasks should reference specific knowledge docs they implement. Observable truths should map back to documented business rules. Use the `businessKnowledge` context (domains, tags, documented facts) loaded in Phase 1 to ground task instructions in verified domain knowledge rather than assumptions.
|
|
198
|
+
|
|
166
199
|
---
|
|
167
200
|
|
|
168
201
|
### Phase 2: DECOMPOSE — Map File Structure and Create Tasks
|
|
@@ -219,11 +252,33 @@ Report progress: `**[Phase 2/4]** DECOMPOSE — mapping file structure and creat
|
|
|
219
252
|
- `[checkpoint:decision]` — Pause, present options, wait for choice
|
|
220
253
|
- `[checkpoint:human-action]` — Pause, instruct human on required action
|
|
221
254
|
|
|
255
|
+
7. **Derive integration tasks from the spec's Integration Points section.** If the spec contains an Integration Points section, create tasks for each non-empty integration point. Skip subsections marked "None" — do not derive tasks from them. Integration tasks are normal plan tasks but tagged with `category: "integration"` in their description. They appear at the end of the task list, after all implementation tasks.
|
|
256
|
+
|
|
257
|
+
For each subsection of Integration Points, derive tasks:
|
|
258
|
+
|
|
259
|
+
| Integration Point | Example Derived Task |
|
|
260
|
+
| ----------------------------------------------- | -------------------------------------------------------------------------- |
|
|
261
|
+
| Entry Points: "New CLI command" | "Regenerate barrel exports. Verify new command appears in `_registry.ts`." |
|
|
262
|
+
| Registrations Required: "Skill at tier 2" | "Add skill to tier list in `AGENTS.md`. Generate slash commands." |
|
|
263
|
+
| Documentation Updates: "AGENTS.md capabilities" | "Update AGENTS.md to describe the feature." |
|
|
264
|
+
| Architectural Decisions: "ADR for approach X" | "Write ADR `docs/knowledge/decisions/NNNN-<slug>.md`." |
|
|
265
|
+
| Knowledge Impact: "Domain concept Y" | "Enrich knowledge graph with concept node." |
|
|
266
|
+
|
|
267
|
+
Integration tasks follow the same atomic task rules (2-5 minutes, exact file paths, exact code). Use the `**Category:** integration` tag in the task header, e.g.:
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
### Task N: Update AGENTS.md with new feature description
|
|
271
|
+
|
|
272
|
+
**Depends on:** Task N-1 | **Files:** `AGENTS.md` | **Category:** integration
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
If the spec has no Integration Points section, skip this step.
|
|
276
|
+
|
|
222
277
|
---
|
|
223
278
|
|
|
224
279
|
### Phase 3: SEQUENCE — Order Tasks and Identify Dependencies
|
|
225
280
|
|
|
226
|
-
1. **Order by dependency.** Types before implementations. Implementations before integrations. Tests alongside implementations (same task, TDD style).
|
|
281
|
+
1. **Order by dependency.** Types before implementations. Implementations before integrations. Integration tasks (tagged `category: "integration"`) after all implementation tasks. Tests alongside implementations (same task, TDD style).
|
|
227
282
|
2. **Identify parallel opportunities.** Tasks touching different subsystems with no shared state can be marked parallelizable.
|
|
228
283
|
3. **Number tasks sequentially.** Use `Task 1`, `Task 2`, etc. Dependencies reference task numbers.
|
|
229
284
|
4. **Estimate total time.** Sum 2-5 minutes per task. If total exceeds available time, identify a milestone boundary for pausing.
|
|
@@ -260,7 +315,7 @@ Report progress: `**[Phase 2/4]** DECOMPOSE — mapping file structure and creat
|
|
|
260
315
|
```markdown
|
|
261
316
|
# Plan: <Feature Name>
|
|
262
317
|
|
|
263
|
-
**Date:** YYYY-MM-DD | **Spec:** (if applicable) | **Tasks:** N | **Time:** N min
|
|
318
|
+
**Date:** YYYY-MM-DD | **Spec:** (if applicable) | **Tasks:** N | **Time:** N min | **Integration Tier:** small | medium | large
|
|
264
319
|
|
|
265
320
|
## Goal
|
|
266
321
|
|
|
@@ -298,6 +353,18 @@ One sentence.
|
|
|
298
353
|
[checkpoint:human-verify] ...
|
|
299
354
|
```
|
|
300
355
|
|
|
356
|
+
### Integration Tier Heuristics
|
|
357
|
+
|
|
358
|
+
When a spec contains an **Integration Points** section, set the plan's `integrationTier` field based on scope:
|
|
359
|
+
|
|
360
|
+
| Tier | Signal | Integration Requirements |
|
|
361
|
+
| ---------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
362
|
+
| **small** | Bug fix, config change, < 3 files, no new exports | Wiring checks only (defaults always run) |
|
|
363
|
+
| **medium** | New feature within existing package, new exports, 3-15 files | Wiring + project updates (roadmap, changelog, graph enrichment) |
|
|
364
|
+
| **large** | New package, new skill, new public API surface, architectural change | Wiring + project updates + knowledge materialization (ADRs, doc updates) |
|
|
365
|
+
|
|
366
|
+
If the spec has no Integration Points section, omit the `integrationTier` field from the plan header.
|
|
367
|
+
|
|
301
368
|
## Session State
|
|
302
369
|
|
|
303
370
|
| Section | Read | Write | Purpose |
|
|
@@ -311,7 +378,7 @@ One sentence.
|
|
|
311
378
|
|
|
312
379
|
**When to write:** Phase 1 — constraints and risks. Phase 2 — decisions about task structure. Phase 4 — resolve questions.
|
|
313
380
|
|
|
314
|
-
**When to read:** Start of Phase 1 via `gather_context` with `include: ["sessions"]` to inherit brainstorming context.
|
|
381
|
+
**When to read:** Start of Phase 1 via `gather_context` with `include: ["state", "learnings", "handoff", "graph", "businessKnowledge", "sessions", "validation"]` to inherit brainstorming context and load documented business knowledge.
|
|
315
382
|
|
|
316
383
|
## Evidence Requirements
|
|
317
384
|
|
|
@@ -28,9 +28,11 @@ If tests are not green before you start, you are not refactoring — you are deb
|
|
|
28
28
|
|
|
29
29
|
2. **Run `harness validate`** and **`harness check-deps`**. Both must pass. You are establishing a clean baseline. If either reports issues, fix those first (that is a separate task, not part of this refactoring).
|
|
30
30
|
|
|
31
|
-
3. **
|
|
31
|
+
3. **Run `compute_blast_radius` on target files** to understand downstream impact before refactoring. This reveals which modules, tests, and consumers will be affected by structural changes.
|
|
32
32
|
|
|
33
|
-
4. **
|
|
33
|
+
4. **Identify the refactoring target.** Be specific: which file, function, class, or module? What is wrong with the current structure? What will be better after refactoring?
|
|
34
|
+
|
|
35
|
+
5. **Plan the steps.** Break the refactoring into the smallest possible individual changes. Each step should be independently committable and verifiable. If you cannot describe a step in one sentence, it is too large.
|
|
34
36
|
|
|
35
37
|
### Graph-Enhanced Context (when available)
|
|
36
38
|
|
|
@@ -81,6 +83,10 @@ For EACH step in the plan:
|
|
|
81
83
|
|
|
82
84
|
2. **Run `harness validate` and `harness check-deps` one final time.** Clean output.
|
|
83
85
|
|
|
86
|
+
3. **Run `detect_stale_constraints`** to verify architectural constraints are still valid after structural changes. Refactoring can render existing constraints obsolete or misaligned.
|
|
87
|
+
|
|
88
|
+
4. **Run `check_traceability`** to confirm refactoring didn't break requirement-to-implementation mappings. Moved or renamed code may orphan traceability links.
|
|
89
|
+
|
|
84
90
|
### Graph Refresh
|
|
85
91
|
|
|
86
92
|
If a knowledge graph exists at `.harness/graph/`, refresh it after code changes to keep graph queries accurate:
|
|
@@ -91,9 +97,9 @@ harness scan [path]
|
|
|
91
97
|
|
|
92
98
|
Skipping this step means subsequent graph queries (impact analysis, dependency health, test advisor) may return stale results.
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
5. **Review the cumulative diff.** Does the final state match the intended improvement? Is the code genuinely better, or just different?
|
|
95
101
|
|
|
96
|
-
|
|
102
|
+
6. **If the refactoring introduced no improvement,** revert the entire sequence. Refactoring for its own sake is churn.
|
|
97
103
|
|
|
98
104
|
## Common Refactoring Patterns
|
|
99
105
|
|
|
@@ -133,6 +139,9 @@ Skipping this step means subsequent graph queries (impact analysis, dependency h
|
|
|
133
139
|
- **`harness check-deps`** — Run after each step, especially when moving code between files or layers. Catches dependency violations introduced by structural changes.
|
|
134
140
|
- **`harness check-docs`** — Run after renaming or moving public APIs. Catches documentation that references old names or locations.
|
|
135
141
|
- **`harness cleanup`** — Run after completing a refactoring sequence. Detects dead code that the refactoring may have created (unused exports, orphaned files).
|
|
142
|
+
- **`compute_blast_radius`** — Run in Phase 1 PREPARE before making changes. Reveals downstream impact of target files so you understand what the refactoring will affect.
|
|
143
|
+
- **`detect_stale_constraints`** — Run in Phase 3 VERIFY after refactoring. Checks whether architectural constraints are still valid after structural changes.
|
|
144
|
+
- **`check_traceability`** — Run in Phase 3 VERIFY after refactoring. Confirms requirement-to-implementation mappings were not broken by moved or renamed code.
|
|
136
145
|
|
|
137
146
|
## Success Criteria
|
|
138
147
|
|
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
- `warning`: errors and warnings (default)
|
|
35
35
|
- `info`: all findings
|
|
36
36
|
|
|
37
|
-
6. **
|
|
37
|
+
6. **Check security trends.** Check `get_security_trends` to compare current scan results against the project's security posture history and identify trajectory changes.
|
|
38
|
+
|
|
39
|
+
7. **Output report.** Present findings grouped by severity:
|
|
38
40
|
|
|
39
41
|
```
|
|
40
42
|
Security Scan: [PASS/FAIL]
|
|
@@ -47,6 +47,10 @@ Every finding conforms to this structure:
|
|
|
47
47
|
|
|
48
48
|
Execute all checks for the active mode. Classify each finding as `autoFixable: true` or `false`. Record total issue count.
|
|
49
49
|
|
|
50
|
+
#### Traceability and Cross-Check Tools
|
|
51
|
+
|
|
52
|
+
Run `check_traceability` to verify that all requirements in the spec/plan have corresponding implementation artifacts. Run `validate_cross_check` to verify plan-to-implementation alignment as part of the soundness assessment.
|
|
53
|
+
|
|
50
54
|
#### Graph Detection and Fallback
|
|
51
55
|
|
|
52
56
|
Before running checks, determine graph availability:
|
|
@@ -71,9 +71,11 @@ If you find yourself writing production code first, STOP. Delete it. Write the t
|
|
|
71
71
|
|
|
72
72
|
2. **Run `harness validate`** to verify the full project health. This catches architectural drift, documentation gaps, and constraint violations.
|
|
73
73
|
|
|
74
|
-
3. **
|
|
74
|
+
3. **Run `check_traceability`** to verify new tests map to specific requirements, ensuring test coverage aligns with spec expectations. This catches tests that exist in isolation without a traced requirement.
|
|
75
75
|
|
|
76
|
-
4. **
|
|
76
|
+
4. **If any check fails,** fix the issue before committing. The fix may require another RED-GREEN-REFACTOR cycle if it involves behavioral changes.
|
|
77
|
+
|
|
78
|
+
5. **Commit the cycle.** Each RED-GREEN-REFACTOR-VALIDATE cycle produces one atomic commit. The commit message references what behavior was added (not "add test" — describe the behavior).
|
|
77
79
|
|
|
78
80
|
### Graph Refresh
|
|
79
81
|
|
|
@@ -111,6 +113,7 @@ Repeat the 4 phases for each new behavior. A typical feature requires 3-10 cycle
|
|
|
111
113
|
- **`harness check-deps`** — Run in VALIDATE phase after each cycle. Catches forbidden imports and layer boundary violations introduced by new code.
|
|
112
114
|
- **`harness validate`** — Run in VALIDATE phase after each cycle. Full project health check including architecture, documentation, and constraints.
|
|
113
115
|
- **`harness cleanup`** — Run periodically (every 3-5 cycles) to detect entropy accumulation. Address any issues before they compound.
|
|
116
|
+
- **`check_traceability`** — Run in VALIDATE phase after tests are written. Verifies new tests map to specific requirements so test coverage aligns with spec expectations.
|
|
114
117
|
- **Test runner** — Use the project's configured test runner. Harness does not prescribe a test framework but the test must actually execute and report results.
|
|
115
118
|
|
|
116
119
|
## Success Criteria
|
|
@@ -386,6 +386,10 @@ Task: "Create UserService with CRUD operations."
|
|
|
386
386
|
- **`harness check-deps`** -- Run during Level 3 (WIRED) to verify dependency boundaries.
|
|
387
387
|
- **`harness check-docs`** -- Verify documentation updated for new artifacts. Missing docs for public APIs is a gap.
|
|
388
388
|
- **Test runner** -- Must be run fresh (not cached) during Level 3. Read actual output, check exit codes.
|
|
389
|
+
- **`check_traceability`** -- Run during Level 3 (WIRED) to verify every requirement in the spec maps to at least one implemented artifact and test.
|
|
390
|
+
- **`validate_cross_check`** -- Run after Level 3 against the plan to verify implementation matches planned file map and task descriptions.
|
|
391
|
+
- **`check_phase_gate`** -- Run before producing the verification report to validate the current phase meets all gate criteria before marking complete.
|
|
392
|
+
- **`detect_anomalies`** -- Run during the Anti-Pattern Scan to identify structural inconsistencies (orphaned files, missing tests, unusual coupling) introduced during execution.
|
|
389
393
|
- **`emit_interaction`** -- Auto-transition to harness-code-review on PASS verdict only.
|
|
390
394
|
- **Session directory** -- `.harness/sessions/<slug>/` contains `handoff.json`, `state.json`, `artifacts.json` (spec path, plan path, file lists from execution). Do not write to global `.harness/handoff.json` when session slug is known.
|
|
391
395
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateAgentsMd
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-C7RPQWBG.js";
|
|
4
|
+
import "./chunk-IBTHD2UA.js";
|
|
5
5
|
import "./chunk-RL4VMEXL.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-GAIOIINV.js";
|
|
7
7
|
import "./chunk-KFQGP6VL.js";
|
|
8
8
|
export {
|
|
9
9
|
generateAgentsMd
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
checkDependenciesDefinition,
|
|
3
3
|
handleCheckDependencies
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-MGPVA2EM.js";
|
|
5
|
+
import "./chunk-YZH4I4JO.js";
|
|
6
6
|
import "./chunk-EPUKTTJZ.js";
|
|
7
7
|
import "./chunk-W6Y7ZW3Y.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-IBTHD2UA.js";
|
|
9
9
|
import "./chunk-RL4VMEXL.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-GAIOIINV.js";
|
|
11
11
|
import "./chunk-KFQGP6VL.js";
|
|
12
12
|
export {
|
|
13
13
|
checkDependenciesDefinition,
|
package/dist/bin/harness-mcp.js
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
startServer
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-EHTUWULH.js";
|
|
5
|
+
import "../chunk-2FOLD76X.js";
|
|
6
|
+
import "../chunk-F3Y64VNF.js";
|
|
7
|
+
import "../chunk-IOW3MW2K.js";
|
|
8
|
+
import "../chunk-BZZNYHRY.js";
|
|
9
|
+
import "../chunk-3AJW7VQ3.js";
|
|
10
|
+
import "../chunk-776JFSPK.js";
|
|
11
|
+
import "../chunk-Q5DKIL46.js";
|
|
12
|
+
import "../chunk-MGPVA2EM.js";
|
|
13
|
+
import "../chunk-YZH4I4JO.js";
|
|
14
|
+
import "../chunk-T7UZOJF4.js";
|
|
15
|
+
import "../chunk-EGRQHLDM.js";
|
|
16
|
+
import "../chunk-CJYNZMOP.js";
|
|
16
17
|
import "../chunk-EPUKTTJZ.js";
|
|
17
18
|
import "../chunk-W6Y7ZW3Y.js";
|
|
18
|
-
import "../chunk-
|
|
19
|
+
import "../chunk-27AJKSQY.js";
|
|
20
|
+
import "../chunk-A4ETL34H.js";
|
|
19
21
|
import "../chunk-3ISINLYT.js";
|
|
20
22
|
import "../chunk-6B6UN6SG.js";
|
|
21
|
-
import "../chunk-
|
|
22
|
-
import "../chunk-YC4EYIER.js";
|
|
23
|
+
import "../chunk-IBTHD2UA.js";
|
|
23
24
|
import "../chunk-RL4VMEXL.js";
|
|
24
|
-
import "../chunk-
|
|
25
|
+
import "../chunk-GAIOIINV.js";
|
|
25
26
|
import "../chunk-HIK6OEUF.js";
|
|
26
27
|
import "../chunk-EBJQ6N4M.js";
|
|
27
28
|
import "../chunk-3WGJMBKH.js";
|
package/dist/bin/harness.js
CHANGED
|
@@ -3,44 +3,45 @@ import {
|
|
|
3
3
|
createProgram,
|
|
4
4
|
installCommandTelemetry,
|
|
5
5
|
printFirstRunWelcome
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-VCC47EXU.js";
|
|
7
|
+
import "../chunk-EICASBYP.js";
|
|
8
|
+
import "../chunk-C7RPQWBG.js";
|
|
9
|
+
import "../chunk-FUS4OOGC.js";
|
|
10
|
+
import "../chunk-SDPHFDQS.js";
|
|
11
|
+
import "../chunk-L3Y7L4EG.js";
|
|
11
12
|
import "../chunk-CQ553GZO.js";
|
|
12
|
-
import "../chunk-N6B6RKQQ.js";
|
|
13
13
|
import "../chunk-GISMXMVL.js";
|
|
14
14
|
import "../chunk-WWACIIBA.js";
|
|
15
15
|
import "../chunk-TEFCFC4H.js";
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
16
|
+
import "../chunk-3XMOWLK3.js";
|
|
17
|
+
import "../chunk-SDDQPMZK.js";
|
|
18
18
|
import "../chunk-KET4QQZB.js";
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
19
|
+
import "../chunk-BO4AJZRE.js";
|
|
20
|
+
import "../chunk-XKU37HGH.js";
|
|
21
21
|
import {
|
|
22
22
|
dispatchSkillsFromGit
|
|
23
|
-
} from "../chunk-
|
|
24
|
-
import "../chunk-
|
|
25
|
-
import "../chunk-
|
|
26
|
-
import "../chunk-
|
|
27
|
-
import "../chunk-
|
|
28
|
-
import "../chunk-
|
|
29
|
-
import "../chunk-
|
|
30
|
-
import "../chunk-
|
|
31
|
-
import "../chunk-
|
|
32
|
-
import "../chunk-
|
|
33
|
-
import "../chunk-
|
|
34
|
-
import "../chunk-
|
|
23
|
+
} from "../chunk-EHTUWULH.js";
|
|
24
|
+
import "../chunk-2FOLD76X.js";
|
|
25
|
+
import "../chunk-F3Y64VNF.js";
|
|
26
|
+
import "../chunk-IOW3MW2K.js";
|
|
27
|
+
import "../chunk-BZZNYHRY.js";
|
|
28
|
+
import "../chunk-3AJW7VQ3.js";
|
|
29
|
+
import "../chunk-776JFSPK.js";
|
|
30
|
+
import "../chunk-Q5DKIL46.js";
|
|
31
|
+
import "../chunk-MGPVA2EM.js";
|
|
32
|
+
import "../chunk-YZH4I4JO.js";
|
|
33
|
+
import "../chunk-T7UZOJF4.js";
|
|
34
|
+
import "../chunk-EGRQHLDM.js";
|
|
35
|
+
import "../chunk-CJYNZMOP.js";
|
|
35
36
|
import "../chunk-EPUKTTJZ.js";
|
|
36
37
|
import "../chunk-W6Y7ZW3Y.js";
|
|
38
|
+
import "../chunk-27AJKSQY.js";
|
|
37
39
|
import {
|
|
38
40
|
findConfigFile,
|
|
39
41
|
loadConfig
|
|
40
|
-
} from "../chunk-
|
|
42
|
+
} from "../chunk-A4ETL34H.js";
|
|
41
43
|
import "../chunk-3ISINLYT.js";
|
|
42
44
|
import "../chunk-6B6UN6SG.js";
|
|
43
|
-
import "../chunk-OLW7BJ5N.js";
|
|
44
45
|
import {
|
|
45
46
|
CLI_VERSION
|
|
46
47
|
} from "../chunk-BM3PWGXQ.js";
|
|
@@ -51,9 +52,9 @@ import {
|
|
|
51
52
|
readCheckState,
|
|
52
53
|
shouldRunCheck,
|
|
53
54
|
spawnBackgroundCheck
|
|
54
|
-
} from "../chunk-
|
|
55
|
+
} from "../chunk-IBTHD2UA.js";
|
|
55
56
|
import "../chunk-RL4VMEXL.js";
|
|
56
|
-
import "../chunk-
|
|
57
|
+
import "../chunk-GAIOIINV.js";
|
|
57
58
|
import "../chunk-ZP5E7YET.js";
|
|
58
59
|
import "../chunk-HIK6OEUF.js";
|
|
59
60
|
import "../chunk-EBJQ6N4M.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createCheckPhaseGateCommand,
|
|
3
3
|
runCheckPhaseGate
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-3XMOWLK3.js";
|
|
5
|
+
import "./chunk-A4ETL34H.js";
|
|
6
|
+
import "./chunk-IBTHD2UA.js";
|
|
7
7
|
import "./chunk-RL4VMEXL.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-GAIOIINV.js";
|
|
9
9
|
import "./chunk-EBJQ6N4M.js";
|
|
10
10
|
import "./chunk-3WGJMBKH.js";
|
|
11
11
|
import "./chunk-KFQGP6VL.js";
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveAllSkillsDirs
|
|
3
|
+
} from "./chunk-6B6UN6SG.js";
|
|
4
|
+
import {
|
|
5
|
+
SkillMetadataSchema
|
|
6
|
+
} from "./chunk-HIK6OEUF.js";
|
|
7
|
+
|
|
8
|
+
// src/skill/index-builder.ts
|
|
9
|
+
import fs from "fs";
|
|
10
|
+
import path from "path";
|
|
11
|
+
import crypto from "crypto";
|
|
12
|
+
import { parse } from "yaml";
|
|
13
|
+
function computeSkillsDirHash(skillsDirs) {
|
|
14
|
+
const hash = crypto.createHash("sha256");
|
|
15
|
+
for (const dir of skillsDirs) {
|
|
16
|
+
if (!fs.existsSync(dir)) continue;
|
|
17
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
18
|
+
if (!entry.isDirectory()) continue;
|
|
19
|
+
const yamlPath = path.join(dir, entry.name, "skill.yaml");
|
|
20
|
+
if (!fs.existsSync(yamlPath)) continue;
|
|
21
|
+
const stat = fs.statSync(yamlPath);
|
|
22
|
+
hash.update(`${yamlPath}:${stat.mtimeMs}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return hash.digest("hex");
|
|
26
|
+
}
|
|
27
|
+
function parseSkillEntry(yamlPath, source, tierOverrides) {
|
|
28
|
+
const raw = fs.readFileSync(yamlPath, "utf-8");
|
|
29
|
+
const parsed = parse(raw);
|
|
30
|
+
const result = SkillMetadataSchema.safeParse(parsed);
|
|
31
|
+
if (!result.success) return null;
|
|
32
|
+
const meta = result.data;
|
|
33
|
+
const effectiveTier = tierOverrides?.[meta.name] ?? meta.tier;
|
|
34
|
+
if (meta.internal) return null;
|
|
35
|
+
return {
|
|
36
|
+
tier: effectiveTier ?? 3,
|
|
37
|
+
type: meta.type,
|
|
38
|
+
description: meta.description,
|
|
39
|
+
keywords: meta.keywords ?? [],
|
|
40
|
+
stackSignals: meta.stack_signals ?? [],
|
|
41
|
+
cognitiveMode: meta.cognitive_mode,
|
|
42
|
+
phases: (meta.phases ?? []).map((p) => p.name),
|
|
43
|
+
paths: meta.paths ?? [],
|
|
44
|
+
relatedSkills: meta.related_skills ?? [],
|
|
45
|
+
source,
|
|
46
|
+
addresses: meta.addresses ?? [],
|
|
47
|
+
dependsOn: meta.depends_on ?? [],
|
|
48
|
+
triggers: meta.triggers ?? ["manual"],
|
|
49
|
+
...meta.context_budget && {
|
|
50
|
+
contextBudget: {
|
|
51
|
+
maxTokens: meta.context_budget.max_tokens,
|
|
52
|
+
priority: meta.context_budget.priority
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function scanDirectory(dir, source, index, tierOverrides) {
|
|
58
|
+
if (!fs.existsSync(dir)) return;
|
|
59
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
60
|
+
if (!entry.isDirectory()) continue;
|
|
61
|
+
if (index.skills[entry.name]) continue;
|
|
62
|
+
const yamlPath = path.join(dir, entry.name, "skill.yaml");
|
|
63
|
+
if (!fs.existsSync(yamlPath)) continue;
|
|
64
|
+
try {
|
|
65
|
+
const parsed = parseSkillEntry(yamlPath, source, tierOverrides);
|
|
66
|
+
if (parsed) index.skills[entry.name] = parsed;
|
|
67
|
+
} catch {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function buildIndex(platform, _projectRoot, tierOverrides) {
|
|
73
|
+
const skillsDirs = resolveAllSkillsDirs(platform);
|
|
74
|
+
const sourceMap = ["project", "community", "bundled"];
|
|
75
|
+
const index = {
|
|
76
|
+
version: 1,
|
|
77
|
+
hash: computeSkillsDirHash(skillsDirs),
|
|
78
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
79
|
+
skills: {}
|
|
80
|
+
};
|
|
81
|
+
for (let i = 0; i < skillsDirs.length; i++) {
|
|
82
|
+
scanDirectory(skillsDirs[i], sourceMap[i] ?? "bundled", index, tierOverrides);
|
|
83
|
+
}
|
|
84
|
+
return index;
|
|
85
|
+
}
|
|
86
|
+
function loadOrRebuildIndex(platform, projectRoot, tierOverrides) {
|
|
87
|
+
const indexPath = path.join(projectRoot, ".harness", "skills-index.json");
|
|
88
|
+
const skillsDirs = resolveAllSkillsDirs(platform);
|
|
89
|
+
const currentHash = computeSkillsDirHash(skillsDirs);
|
|
90
|
+
if (fs.existsSync(indexPath)) {
|
|
91
|
+
try {
|
|
92
|
+
const existing = JSON.parse(fs.readFileSync(indexPath, "utf-8"));
|
|
93
|
+
if (existing.hash === currentHash) return existing;
|
|
94
|
+
} catch {
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const index = buildIndex(platform, projectRoot, tierOverrides);
|
|
98
|
+
fs.mkdirSync(path.dirname(indexPath), { recursive: true });
|
|
99
|
+
fs.writeFileSync(indexPath, JSON.stringify(index, null, 2));
|
|
100
|
+
return index;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export {
|
|
104
|
+
computeSkillsDirHash,
|
|
105
|
+
buildIndex,
|
|
106
|
+
loadOrRebuildIndex
|
|
107
|
+
};
|