@harness-engineering/cli 1.27.1 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/agents/skills/claude-code/harness-architecture-advisor/SKILL.md +17 -5
  2. package/dist/agents/skills/claude-code/harness-architecture-advisor/skill.yaml +1 -1
  3. package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +4 -4
  4. package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +1 -1
  5. package/dist/agents/skills/claude-code/harness-design-system/SKILL.md +6 -1
  6. package/dist/agents/skills/claude-code/harness-execution/SKILL.md +4 -4
  7. package/dist/agents/skills/claude-code/harness-i18n-process/SKILL.md +2 -2
  8. package/dist/agents/skills/claude-code/harness-integration/SKILL.md +1 -1
  9. package/dist/agents/skills/claude-code/harness-knowledge-pipeline/SKILL.md +1 -0
  10. package/dist/agents/skills/claude-code/harness-onboarding/SKILL.md +1 -1
  11. package/dist/agents/skills/claude-code/harness-planning/SKILL.md +3 -3
  12. package/dist/agents/skills/claude-code/harness-roadmap/SKILL.md +4 -3
  13. package/dist/agents/skills/claude-code/initialize-harness-project/SKILL.md +150 -10
  14. package/dist/agents/skills/claude-code/initialize-harness-project/skill.yaml +2 -1
  15. package/dist/agents/skills/codex/harness-architecture-advisor/SKILL.md +17 -5
  16. package/dist/agents/skills/codex/harness-architecture-advisor/skill.yaml +1 -1
  17. package/dist/agents/skills/codex/harness-autopilot/SKILL.md +4 -4
  18. package/dist/agents/skills/codex/harness-code-review/SKILL.md +1 -1
  19. package/dist/agents/skills/codex/harness-design-system/SKILL.md +6 -1
  20. package/dist/agents/skills/codex/harness-execution/SKILL.md +4 -4
  21. package/dist/agents/skills/codex/harness-i18n-process/SKILL.md +2 -2
  22. package/dist/agents/skills/codex/harness-integration/SKILL.md +1 -1
  23. package/dist/agents/skills/codex/harness-knowledge-pipeline/SKILL.md +1 -0
  24. package/dist/agents/skills/codex/harness-onboarding/SKILL.md +1 -1
  25. package/dist/agents/skills/codex/harness-planning/SKILL.md +3 -3
  26. package/dist/agents/skills/codex/harness-roadmap/SKILL.md +4 -3
  27. package/dist/agents/skills/codex/initialize-harness-project/SKILL.md +150 -10
  28. package/dist/agents/skills/codex/initialize-harness-project/skill.yaml +2 -1
  29. package/dist/agents/skills/cursor/harness-architecture-advisor/SKILL.md +17 -5
  30. package/dist/agents/skills/cursor/harness-architecture-advisor/skill.yaml +1 -1
  31. package/dist/agents/skills/cursor/harness-autopilot/SKILL.md +4 -4
  32. package/dist/agents/skills/cursor/harness-code-review/SKILL.md +1 -1
  33. package/dist/agents/skills/cursor/harness-design-system/SKILL.md +6 -1
  34. package/dist/agents/skills/cursor/harness-execution/SKILL.md +4 -4
  35. package/dist/agents/skills/cursor/harness-i18n-process/SKILL.md +2 -2
  36. package/dist/agents/skills/cursor/harness-integration/SKILL.md +1 -1
  37. package/dist/agents/skills/cursor/harness-knowledge-pipeline/SKILL.md +1 -0
  38. package/dist/agents/skills/cursor/harness-onboarding/SKILL.md +1 -1
  39. package/dist/agents/skills/cursor/harness-planning/SKILL.md +3 -3
  40. package/dist/agents/skills/cursor/harness-roadmap/SKILL.md +4 -3
  41. package/dist/agents/skills/cursor/initialize-harness-project/SKILL.md +150 -10
  42. package/dist/agents/skills/cursor/initialize-harness-project/skill.yaml +2 -1
  43. package/dist/agents/skills/gemini-cli/harness-architecture-advisor/SKILL.md +17 -5
  44. package/dist/agents/skills/gemini-cli/harness-architecture-advisor/skill.yaml +1 -1
  45. package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +4 -4
  46. package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +1 -1
  47. package/dist/agents/skills/gemini-cli/harness-design-system/SKILL.md +6 -1
  48. package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +4 -4
  49. package/dist/agents/skills/gemini-cli/harness-i18n-process/SKILL.md +2 -2
  50. package/dist/agents/skills/gemini-cli/harness-integration/SKILL.md +1 -1
  51. package/dist/agents/skills/gemini-cli/harness-knowledge-pipeline/SKILL.md +1 -0
  52. package/dist/agents/skills/gemini-cli/harness-onboarding/SKILL.md +1 -1
  53. package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +3 -3
  54. package/dist/agents/skills/gemini-cli/harness-roadmap/SKILL.md +4 -3
  55. package/dist/agents/skills/gemini-cli/initialize-harness-project/SKILL.md +150 -10
  56. package/dist/agents/skills/gemini-cli/initialize-harness-project/skill.yaml +2 -1
  57. package/dist/{agents-md-2RN666DE.js → agents-md-76IEMV6O.js} +3 -3
  58. package/dist/{architecture-ZR33YKJB.js → architecture-5GVJRRUD.js} +4 -4
  59. package/dist/{assess-project-LLWWEQEV.js → assess-project-WDUFL7SO.js} +1 -1
  60. package/dist/bin/harness-mcp.js +15 -15
  61. package/dist/bin/harness.js +25 -25
  62. package/dist/{check-phase-gate-ZVG56NT2.js → check-phase-gate-QR3ONJYP.js} +4 -4
  63. package/dist/{chunk-FUS4OOGC.js → chunk-3WLXR23L.js} +1 -1
  64. package/dist/{chunk-IBTHD2UA.js → chunk-6JBJ5FSW.js} +2 -1
  65. package/dist/{chunk-C7RPQWBG.js → chunk-77OMOFZL.js} +1 -1
  66. package/dist/{chunk-YZH4I4JO.js → chunk-AJG2LCMA.js} +1 -1
  67. package/dist/{chunk-3AJW7VQ3.js → chunk-CS7K6ZQ3.js} +2 -2
  68. package/dist/{chunk-SDDQPMZK.js → chunk-D25P6763.js} +1 -1
  69. package/dist/{chunk-XKU37HGH.js → chunk-DHGL3SF2.js} +1 -1
  70. package/dist/{chunk-CJYNZMOP.js → chunk-E7QD4YHA.js} +8 -8
  71. package/dist/{chunk-BO4AJZRE.js → chunk-H43UQY6B.js} +1 -1
  72. package/dist/{chunk-SDPHFDQS.js → chunk-ILVO6LZY.js} +1 -1
  73. package/dist/{chunk-BZZNYHRY.js → chunk-K5ZOBBQB.js} +9 -9
  74. package/dist/{chunk-A4ETL34H.js → chunk-KLE6FXWM.js} +23 -1
  75. package/dist/{chunk-F3Y64VNF.js → chunk-L4RURCSF.js} +6 -6
  76. package/dist/{chunk-EGRQHLDM.js → chunk-LINAFNIK.js} +5 -5
  77. package/dist/{chunk-EHTUWULH.js → chunk-OPOSSZJS.js} +97 -93
  78. package/dist/{chunk-L3Y7L4EG.js → chunk-OQS7KURX.js} +1 -1
  79. package/dist/{chunk-T7UZOJF4.js → chunk-QZ46CI6E.js} +9 -9
  80. package/dist/{chunk-MGPVA2EM.js → chunk-TFNQ72RF.js} +5 -5
  81. package/dist/{chunk-3XMOWLK3.js → chunk-USG7DV5N.js} +2 -2
  82. package/dist/{chunk-776JFSPK.js → chunk-VITLE3PS.js} +1 -1
  83. package/dist/{chunk-2FOLD76X.js → chunk-WPSM7WT6.js} +2 -2
  84. package/dist/{chunk-GAIOIINV.js → chunk-X7XQ3ELM.js} +108 -36
  85. package/dist/{chunk-EICASBYP.js → chunk-YZZVOT7I.js} +1 -1
  86. package/dist/{chunk-VCC47EXU.js → chunk-Z63IDQ7Y.js} +860 -412
  87. package/dist/{chunk-Q5DKIL46.js → chunk-Z7ZF2XDL.js} +3 -3
  88. package/dist/{ci-workflow-JFOL4YWW.js → ci-workflow-GYQXE5X4.js} +3 -3
  89. package/dist/{dist-CPKL5Y2R.js → dist-46VOJIG4.js} +2 -2
  90. package/dist/{dist-BZS2XRLG.js → dist-BP6E6QGG.js} +7 -1
  91. package/dist/{docs-FUTRJQHA.js → docs-CVQMSMQC.js} +4 -4
  92. package/dist/{engine-FB3HCNVT.js → engine-23PJMRHA.js} +3 -3
  93. package/dist/{entropy-FIEE4YDA.js → entropy-K2YTZFCP.js} +3 -3
  94. package/dist/{feedback-7EC4T6XG.js → feedback-6HP42GTK.js} +1 -1
  95. package/dist/{generate-agent-definitions-FOSFADNR.js → generate-agent-definitions-6RJKL6VW.js} +4 -4
  96. package/dist/{graph-loader-QEI7SYOQ.js → graph-loader-BI3OFFFS.js} +1 -1
  97. package/dist/index.d.ts +44 -1
  98. package/dist/index.js +25 -25
  99. package/dist/{loader-HXUOBTYA.js → loader-U2WEC3PZ.js} +3 -3
  100. package/dist/{mcp-NUG4BMKJ.js → mcp-N6XVWPXJ.js} +15 -15
  101. package/dist/{performance-TYXBCTR7.js → performance-T3XAESWR.js} +4 -4
  102. package/dist/{review-pipeline-B4WPU6BQ.js → review-pipeline-HTC5HA5X.js} +3 -3
  103. package/dist/{runtime-HQQNOARD.js → runtime-UFXMNN3Q.js} +3 -3
  104. package/dist/{scan-M4EGDAQ2.js → scan-XRGMTO6K.js} +1 -1
  105. package/dist/{security-25VFLIAO.js → security-ROK5IFDA.js} +1 -1
  106. package/dist/{validate-EAVGKZQB.js → validate-IJHHQHT5.js} +4 -4
  107. package/dist/{validate-cross-check-SPL3H4O5.js → validate-cross-check-LUQYIA46.js} +3 -3
  108. package/package.json +6 -6
@@ -36,7 +36,7 @@
36
36
  - Config files like `playwright.config.*`, `cypress.config.*`, `wdio.conf.*`
37
37
  - No production runtime — build output consumed only by other test repos (shared library)
38
38
 
39
- **If a test suite:** complete Phase 2 (scaffolding) here, then dispatch to `initialize-test-suite-project` for Phase 3 configuration and Phase 4 verification, then return here for Phase 4 step 4+ (knowledge graph, roadmap nudge, final commit). The test-suite skill owns archetype selection, layer variants, tags, reporters, and the custom report.
39
+ **If a test suite:** complete Phase 2 (scaffolding) here, then dispatch to `initialize-test-suite-project` for Phase 3 configuration and Phase 4 verification, then return here for Phase 4 step 4+ (knowledge graph, roadmap question, final commit). The test-suite skill owns archetype selection, layer variants, tags, reporters, and the custom report.
40
40
 
41
41
  **If a product/service:** continue with the rest of this skill as written.
42
42
 
@@ -83,6 +83,48 @@
83
83
  - **No:** Set `i18n.enabled: false` in `harness.config.json`. The `harness-i18n-process` skill will still fire gentle prompts for unconfigured projects when features touch user-facing strings.
84
84
  - **Not sure yet:** Skip i18n configuration entirely. Do not set `i18n.enabled`. The project can enable i18n later by running `harness-i18n-workflow` directly.
85
85
 
86
+ 5b. **Configure design system (non-test-suite projects).** Ask: "Will this project have a UI requiring a design system?" Mirror the i18n step's three-way response shape. Use `emit_interaction`:
87
+
88
+ ```json
89
+ emit_interaction({
90
+ type: "question",
91
+ question: {
92
+ text: "Will this project have a UI requiring a design system?",
93
+ options: [
94
+ {
95
+ label: "Yes — capture design intent now",
96
+ pros: ["Records platforms in harness.config.json", "harness-design-system fires automatically on first design-touching feature"],
97
+ cons: ["One extra follow-up question (which platforms)"],
98
+ risk: "low",
99
+ effort: "low"
100
+ },
101
+ {
102
+ label: "No — this project has no UI",
103
+ pros: ["No future design nudges", "Permanent decline recorded"],
104
+ cons: ["Re-running init is required if a UI is added later"],
105
+ risk: "low",
106
+ effort: "low"
107
+ },
108
+ {
109
+ label: "Not sure yet",
110
+ pros: ["Decision deferred without commitment", "Can run harness-design-system later"],
111
+ cons: ["No design.enabled flag set; on_new_feature will prompt later"],
112
+ risk: "low",
113
+ effort: "low"
114
+ }
115
+ ],
116
+ recommendation: { optionIndex: 0, reason: "Most product/service projects benefit from a centralized design system", confidence: "medium" }
117
+ }
118
+ })
119
+ ```
120
+
121
+ Based on the answer:
122
+ - **Yes:** Ask a follow-up: "Which platforms? `web`, `mobile`, or both?" Write `design.enabled: true` and `design.platforms: [...]` (a non-empty array of `web` and/or `mobile`) to `harness.config.json`. Inform the user: "Design tokens will be generated when you start your first design-touching feature — `harness-design-system` fires automatically via `on_new_feature`."
123
+ - **No:** Write `design.enabled: false` to `harness.config.json`. Do not write `design.platforms`. The `on_new_feature` trigger respects this flag and will not fire `harness-design-system`.
124
+ - **Not sure yet:** Do not write `design.enabled` or `design.platforms`. The project can enable design later by running `harness-design-system` directly; `on_new_feature` will prompt gently when a feature touches user-facing UI.
125
+
126
+ **Skip this step entirely if Phase 1 step 5 classified the project as a test suite.** Test-suite projects will be dispatched at step 6 below to `initialize-test-suite-project` and have no UI to govern.
127
+
86
128
  6. **Test-suite projects only — dispatch to `initialize-test-suite-project`.** If Phase 1 step 5 classified this as a test suite, invoke `initialize-test-suite-project` now and let it own archetype selection, shared-library decision, layer variants (A self-contained vs B consumer), ESLint flat-config fix, tag taxonomy, reporter stack, custom report, and the "prove the guards fire" verification. Return here for Phase 4 step 4+ (knowledge graph, roadmap, commit). Product and service projects skip this step entirely.
87
129
 
88
130
  ### Phase 4: VALIDATE — Confirm Everything Works
@@ -108,7 +150,38 @@ harness scan [path]
108
150
 
109
151
  This creates the `.harness/graph/` directory and populates it with the project's dependency and relationship data. Subsequent graph queries (impact analysis, dependency health, test advisor) depend on this initial scan.
110
152
 
111
- 4. **Mention roadmap.** After validation passes, inform the user: "When you are ready to set up a project roadmap, run `/harness:roadmap --create`. This creates a unified `docs/roadmap.md` that tracks features, milestones, and status across your specs and plans." This is informational only — do not create the roadmap automatically.
153
+ 4. **Set up project roadmap.** Ask: "Set up a project roadmap now? `docs/roadmap.md` tracks features, milestones, and status across your specs and plans." Use `emit_interaction`:
154
+
155
+ ```json
156
+ emit_interaction({
157
+ type: "question",
158
+ question: {
159
+ text: "Set up a project roadmap now?",
160
+ options: [
161
+ {
162
+ label: "Yes — create docs/roadmap.md now",
163
+ pros: ["Roadmap visible from day one", "Future specs auto-discovered on next sync"],
164
+ cons: ["Adds one file to the initial commit"],
165
+ risk: "low",
166
+ effort: "low"
167
+ },
168
+ {
169
+ label: "No — skip for now",
170
+ pros: ["Smaller initial footprint"],
171
+ cons: ["Run `/harness:roadmap --create` later when ready"],
172
+ risk: "low",
173
+ effort: "low"
174
+ }
175
+ ],
176
+ recommendation: { optionIndex: 0, reason: "Validation has just passed — a tangible 'project works' signal is the right moment to introduce planning artifacts", confidence: "medium" }
177
+ }
178
+ })
179
+ ```
180
+
181
+ Based on the answer:
182
+ - **Yes:** Invoke `harness-roadmap` (skill) or run `/harness:roadmap --create` to create `docs/roadmap.md`. Verify the file exists. The `manage_roadmap` MCP tool is for managing entries in an existing roadmap, not for creating one.
183
+ - **If `design.enabled === true` in `harness.config.json`** (set by Phase 3 step 5b), call `manage_roadmap` with `action: add`, `feature: "Set up design system"`, `status: "planned"`, `milestone: "Current Work"`, `summary: "Run harness-design-system to define palette, typography, and generate W3C DTCG tokens. Deferred from project init — fires on first design-touching feature via on_new_feature."`. Skip silently if `manage_roadmap show` reports a duplicate `(feature, milestone)` pair. This closes the loop between deferred design intent and visible planning work.
184
+ - **No:** Skip silently. The user can still run `/harness:roadmap --create` later — that informational fallback remains valid.
112
185
 
113
186
  5. **Commit the initialization.** All generated and configured files in a single commit.
114
187
 
@@ -120,8 +193,10 @@ This creates the `.harness/graph/` directory and populates it with the project's
120
193
  - **`harness validate`** — Verify the full project configuration is valid and complete.
121
194
  - **`harness check-deps`** — Verify dependency constraints match the actual codebase (intermediate and above).
122
195
  - **`harness-i18n-workflow configure` + `harness-i18n-workflow scaffold`** — Invoked during Phase 3 if the project will support multiple languages. Sets up i18n configuration and translation file structure.
196
+ - **`harness-design-system` (deferred via `on_new_feature`)** — Phase 3 step 5b records `design.enabled` + `design.platforms` in `harness.config.json` but does NOT run the full design-system skill. Token generation defers to the first design-touching feature, where `harness-design-system` fires via `on_new_feature` and reads `design.enabled` to decide whether to proceed.
123
197
  - **`initialize-test-suite-project`** — Sub-skill. Invoked during Phase 3 step 6 when Phase 1 step 5 classified the project as a test suite. Owns archetype selection, shared-library vs in-repo decision, layer variants, tag taxonomy, reporter stack, custom report, and "prove the guards fire" verification.
124
- - **Roadmap nudge** — After successful initialization, inform the user about `/harness:roadmap --create` for setting up project-level feature tracking. Informational only; does not create the roadmap.
198
+ - **`harness-roadmap` skill** — Phase 4 step 4 invokes this skill (or `/harness:roadmap --create`) when the user opts in to creating `docs/roadmap.md`. The `manage_roadmap` MCP tool does not create roadmaps; it manages entries in an existing one.
199
+ - **`manage_roadmap` MCP tool** — Phase 4 step 4, when `design.enabled === true`, calls `manage_roadmap` with `action: add` to insert a `planned` "Set up design system" item under milestone `Current Work` with a summary describing the deferred work.
125
200
 
126
201
  ## Success Criteria
127
202
 
@@ -134,17 +209,21 @@ This creates the `.harness/graph/` directory and populates it with the project's
134
209
  - The adoption level matches what was agreed upon with the human
135
210
  - All generated files are committed in a single atomic commit
136
211
  - i18n configuration is set if the human chose to enable it during init
212
+ - For non-test-suite projects, the design-system question was asked and `harness.config.json` reflects the answer: `design.enabled: true` (with `design.platforms` populated) for yes, `design.enabled: false` for no, or absent for not-sure.
213
+ - The roadmap question was asked. If the user answered yes, `docs/roadmap.md` exists and was created via `harness-roadmap` (or the documented `/harness:roadmap --create` fallback).
214
+ - When `design.enabled === true` AND the user answered yes to the roadmap question, `docs/roadmap.md` contains a `planned` entry titled "Set up design system" under milestone `Current Work` with a summary describing the deferred work. The entry is absent in all other answer combinations.
137
215
  - For test suites: `initialize-test-suite-project` ran to completion and its Success Criteria are also met
138
216
 
139
217
  ## Rationalizations to Reject
140
218
 
141
- | Rationalization | Why It Is Wrong |
142
- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
143
- | "The generated AGENTS.md template looks fine -- no need to customize it" | Phase 3 says do not blindly accept generated content. Without project-specific descriptions, agents receive generic instructions. |
144
- | "We should start at the advanced level since we want full coverage" | The skill recommends basic for new projects. Each level builds on the previous. Jumping to advanced creates misconfigured rules. |
145
- | "I will skip the i18n question to keep setup fast" | Phase 3 requires asking about i18n and recording the decision. Skipping creates ambiguity about whether the omission was intentional. |
146
- | "Validation passed, so the project is ready" | Phase 4 includes harness check-deps for intermediate+ projects and knowledge graph initialization. Validation alone is not sufficient. |
147
- | "This is a test suite, we'll configure layers in this skill" | Phase 3 step 6 dispatches to `initialize-test-suite-project` for archetype selection, layer variants, and the rest. Do not inline test-suite-specific configuration here — the sub-skill owns it and carries the gotchas. |
219
+ | Rationalization | Why It Is Wrong |
220
+ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
221
+ | "The generated AGENTS.md template looks fine -- no need to customize it" | Phase 3 says do not blindly accept generated content. Without project-specific descriptions, agents receive generic instructions. |
222
+ | "We should start at the advanced level since we want full coverage" | The skill recommends basic for new projects. Each level builds on the previous. Jumping to advanced creates misconfigured rules. |
223
+ | "I will skip the i18n question to keep setup fast" | Phase 3 requires asking about i18n and recording the decision. Skipping creates ambiguity about whether the omission was intentional. |
224
+ | "I will skip the design-system question to keep setup fast" | Phase 3 step 5b requires asking about design and recording the answer in `design.enabled`. Skipping creates ambiguity about whether the omission was intentional and bypasses the linkage between init and the deferred `harness-design-system` invocation on `on_new_feature`. |
225
+ | "Validation passed, so the project is ready" | Phase 4 includes harness check-deps for intermediate+ projects and knowledge graph initialization. Validation alone is not sufficient. |
226
+ | "This is a test suite, we'll configure layers in this skill" | Phase 3 step 6 dispatches to `initialize-test-suite-project` for archetype selection, layer variants, and the rest. Do not inline test-suite-specific configuration here — the sub-skill owns it and carries the gotchas. |
148
227
 
149
228
  ## Examples
150
229
 
@@ -188,6 +267,67 @@ git add harness.config.json .harness/ AGENTS.md
188
267
  git commit -m "feat: initialize harness project at basic level"
189
268
  ```
190
269
 
270
+ ### Example: New TypeScript Web App with Design and Roadmap
271
+
272
+ **ASSESS:**
273
+
274
+ ```
275
+ Human: "I'm starting a new Next.js web app. Single-language, but it definitely needs a design system."
276
+ Check for .harness/ — not found. Recommend: basic level.
277
+ Phase 1 step 5 classification: not a test suite (Next.js app with src/, no playwright/cypress).
278
+ ```
279
+
280
+ **SCAFFOLD:**
281
+
282
+ ```bash
283
+ harness init --level basic --framework nextjs
284
+ ```
285
+
286
+ **CONFIGURE (Phase 3):**
287
+
288
+ ```
289
+ Step 5 (i18n): "Will this project support multiple languages?"
290
+ Human: "No, English only."
291
+ Result: i18n.enabled = false in harness.config.json.
292
+
293
+ Step 5b (design): "Will this project have a UI requiring a design system?"
294
+ Human: "Yes."
295
+ Follow-up: "Which platforms? web, mobile, or both?"
296
+ Human: "Web."
297
+ Result: design.enabled = true, design.platforms = ["web"] in harness.config.json.
298
+ Inform: "Design tokens will be generated when you start your first design-touching
299
+ feature — harness-design-system fires automatically via on_new_feature."
300
+
301
+ Step 6 (test-suite dispatch): skipped (not a test suite).
302
+ ```
303
+
304
+ **VALIDATE (Phase 4):**
305
+
306
+ ```
307
+ Step 1: harness validate — pass.
308
+ Step 3: harness check-deps — pass (basic level, no constraints yet).
309
+ Build initial knowledge graph: harness scan — graph populated.
310
+
311
+ Step 4 (roadmap): "Set up a project roadmap now?"
312
+ Human: "Yes."
313
+ Invoke harness-roadmap (or /harness:roadmap --create) — docs/roadmap.md created.
314
+ design.enabled === true detected → manage_roadmap action: add
315
+ feature: "Set up design system"
316
+ status: planned
317
+ milestone: Current Work
318
+ summary: "Run harness-design-system to define palette, typography, and generate W3C DTCG tokens..."
319
+ Result: docs/roadmap.md contains the planned design item.
320
+
321
+ Step 5: commit.
322
+ ```
323
+
324
+ ```bash
325
+ git add harness.config.json .harness/ AGENTS.md docs/roadmap.md
326
+ git commit -m "feat: initialize harness project with design and roadmap"
327
+ ```
328
+
329
+ **Final state:** `harness.config.json` has `design.enabled: true` + `design.platforms: ["web"]`; `docs/roadmap.md` lists "Set up design system" as a `planned` item under `Current Work`; on the first feature touching UI, `on_new_feature` fires `harness-design-system` which reads `design.enabled` and runs the full discover/define/generate/validate flow.
330
+
191
331
  ### Example: Migrating Existing Project from Basic to Intermediate
192
332
 
193
333
  **ASSESS:**
@@ -1,6 +1,6 @@
1
1
  name: initialize-harness-project
2
2
  version: "1.0.0"
3
- description: Scaffold a new harness-compliant project
3
+ description: Scaffold a new harness-compliant project, including design system and roadmap configuration
4
4
  stability: static
5
5
  cognitive_mode: constructive-architect
6
6
  triggers:
@@ -34,3 +34,4 @@ state:
34
34
  files: []
35
35
  depends_on:
36
36
  - initialize-test-suite-project
37
+ - harness-design-system
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  generateAgentsMd
3
- } from "./chunk-C7RPQWBG.js";
4
- import "./chunk-IBTHD2UA.js";
3
+ } from "./chunk-77OMOFZL.js";
4
+ import "./chunk-6JBJ5FSW.js";
5
5
  import "./chunk-RL4VMEXL.js";
6
- import "./chunk-GAIOIINV.js";
6
+ import "./chunk-X7XQ3ELM.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-MGPVA2EM.js";
5
- import "./chunk-YZH4I4JO.js";
4
+ } from "./chunk-TFNQ72RF.js";
5
+ import "./chunk-AJG2LCMA.js";
6
6
  import "./chunk-EPUKTTJZ.js";
7
7
  import "./chunk-W6Y7ZW3Y.js";
8
- import "./chunk-IBTHD2UA.js";
8
+ import "./chunk-6JBJ5FSW.js";
9
9
  import "./chunk-RL4VMEXL.js";
10
- import "./chunk-GAIOIINV.js";
10
+ import "./chunk-X7XQ3ELM.js";
11
11
  import "./chunk-KFQGP6VL.js";
12
12
  export {
13
13
  checkDependenciesDefinition,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  assessProjectDefinition,
3
3
  handleAssessProject
4
- } from "./chunk-F3Y64VNF.js";
4
+ } from "./chunk-L4RURCSF.js";
5
5
  import "./chunk-W6Y7ZW3Y.js";
6
6
  import "./chunk-KFQGP6VL.js";
7
7
  export {
@@ -1,28 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startServer
4
- } from "../chunk-EHTUWULH.js";
5
- import "../chunk-2FOLD76X.js";
6
- import "../chunk-F3Y64VNF.js";
4
+ } from "../chunk-OPOSSZJS.js";
5
+ import "../chunk-WPSM7WT6.js";
6
+ import "../chunk-L4RURCSF.js";
7
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";
8
+ import "../chunk-K5ZOBBQB.js";
9
+ import "../chunk-CS7K6ZQ3.js";
10
+ import "../chunk-VITLE3PS.js";
11
+ import "../chunk-Z7ZF2XDL.js";
12
+ import "../chunk-TFNQ72RF.js";
13
+ import "../chunk-AJG2LCMA.js";
14
+ import "../chunk-QZ46CI6E.js";
15
+ import "../chunk-LINAFNIK.js";
16
+ import "../chunk-E7QD4YHA.js";
17
17
  import "../chunk-EPUKTTJZ.js";
18
18
  import "../chunk-W6Y7ZW3Y.js";
19
19
  import "../chunk-27AJKSQY.js";
20
- import "../chunk-A4ETL34H.js";
20
+ import "../chunk-KLE6FXWM.js";
21
21
  import "../chunk-3ISINLYT.js";
22
22
  import "../chunk-6B6UN6SG.js";
23
- import "../chunk-IBTHD2UA.js";
23
+ import "../chunk-6JBJ5FSW.js";
24
24
  import "../chunk-RL4VMEXL.js";
25
- import "../chunk-GAIOIINV.js";
25
+ import "../chunk-X7XQ3ELM.js";
26
26
  import "../chunk-HIK6OEUF.js";
27
27
  import "../chunk-EBJQ6N4M.js";
28
28
  import "../chunk-3WGJMBKH.js";
@@ -3,43 +3,43 @@ import {
3
3
  createProgram,
4
4
  installCommandTelemetry,
5
5
  printFirstRunWelcome
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";
6
+ } from "../chunk-Z63IDQ7Y.js";
7
+ import "../chunk-YZZVOT7I.js";
8
+ import "../chunk-77OMOFZL.js";
9
+ import "../chunk-3WLXR23L.js";
10
+ import "../chunk-ILVO6LZY.js";
11
+ import "../chunk-OQS7KURX.js";
12
12
  import "../chunk-CQ553GZO.js";
13
13
  import "../chunk-GISMXMVL.js";
14
14
  import "../chunk-WWACIIBA.js";
15
15
  import "../chunk-TEFCFC4H.js";
16
- import "../chunk-3XMOWLK3.js";
17
- import "../chunk-SDDQPMZK.js";
16
+ import "../chunk-USG7DV5N.js";
17
+ import "../chunk-D25P6763.js";
18
18
  import "../chunk-KET4QQZB.js";
19
- import "../chunk-BO4AJZRE.js";
20
- import "../chunk-XKU37HGH.js";
19
+ import "../chunk-H43UQY6B.js";
20
+ import "../chunk-DHGL3SF2.js";
21
21
  import {
22
22
  dispatchSkillsFromGit
23
- } from "../chunk-EHTUWULH.js";
24
- import "../chunk-2FOLD76X.js";
25
- import "../chunk-F3Y64VNF.js";
23
+ } from "../chunk-OPOSSZJS.js";
24
+ import "../chunk-WPSM7WT6.js";
25
+ import "../chunk-L4RURCSF.js";
26
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";
27
+ import "../chunk-K5ZOBBQB.js";
28
+ import "../chunk-CS7K6ZQ3.js";
29
+ import "../chunk-VITLE3PS.js";
30
+ import "../chunk-Z7ZF2XDL.js";
31
+ import "../chunk-TFNQ72RF.js";
32
+ import "../chunk-AJG2LCMA.js";
33
+ import "../chunk-QZ46CI6E.js";
34
+ import "../chunk-LINAFNIK.js";
35
+ import "../chunk-E7QD4YHA.js";
36
36
  import "../chunk-EPUKTTJZ.js";
37
37
  import "../chunk-W6Y7ZW3Y.js";
38
38
  import "../chunk-27AJKSQY.js";
39
39
  import {
40
40
  findConfigFile,
41
41
  loadConfig
42
- } from "../chunk-A4ETL34H.js";
42
+ } from "../chunk-KLE6FXWM.js";
43
43
  import "../chunk-3ISINLYT.js";
44
44
  import "../chunk-6B6UN6SG.js";
45
45
  import {
@@ -52,9 +52,9 @@ import {
52
52
  readCheckState,
53
53
  shouldRunCheck,
54
54
  spawnBackgroundCheck
55
- } from "../chunk-IBTHD2UA.js";
55
+ } from "../chunk-6JBJ5FSW.js";
56
56
  import "../chunk-RL4VMEXL.js";
57
- import "../chunk-GAIOIINV.js";
57
+ import "../chunk-X7XQ3ELM.js";
58
58
  import "../chunk-ZP5E7YET.js";
59
59
  import "../chunk-HIK6OEUF.js";
60
60
  import "../chunk-EBJQ6N4M.js";
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createCheckPhaseGateCommand,
3
3
  runCheckPhaseGate
4
- } from "./chunk-3XMOWLK3.js";
5
- import "./chunk-A4ETL34H.js";
6
- import "./chunk-IBTHD2UA.js";
4
+ } from "./chunk-USG7DV5N.js";
5
+ import "./chunk-KLE6FXWM.js";
6
+ import "./chunk-6JBJ5FSW.js";
7
7
  import "./chunk-RL4VMEXL.js";
8
- import "./chunk-GAIOIINV.js";
8
+ import "./chunk-X7XQ3ELM.js";
9
9
  import "./chunk-EBJQ6N4M.js";
10
10
  import "./chunk-3WGJMBKH.js";
11
11
  import "./chunk-KFQGP6VL.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  init_dist
3
- } from "./chunk-IBTHD2UA.js";
3
+ } from "./chunk-6JBJ5FSW.js";
4
4
  import {
5
5
  Err,
6
6
  Ok
@@ -13,7 +13,7 @@ import {
13
13
  NODE_STABILITY,
14
14
  init_dist as init_dist2,
15
15
  queryTraceability
16
- } from "./chunk-GAIOIINV.js";
16
+ } from "./chunk-X7XQ3ELM.js";
17
17
  import {
18
18
  __esm,
19
19
  __export
@@ -12645,6 +12645,7 @@ function inferStatus(feature, projectPath, allFeatures) {
12645
12645
  return !blocker || blocker.status !== "done";
12646
12646
  });
12647
12647
  if (blockerNotDone) return "blocked";
12648
+ if (feature.status === "blocked") return "planned";
12648
12649
  }
12649
12650
  if (feature.plans.length === 0) return null;
12650
12651
  const allTaskStatuses = [];
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  init_dist
3
- } from "./chunk-IBTHD2UA.js";
3
+ } from "./chunk-6JBJ5FSW.js";
4
4
  import {
5
5
  Err,
6
6
  Ok
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  init_dist
3
- } from "./chunk-IBTHD2UA.js";
3
+ } from "./chunk-6JBJ5FSW.js";
4
4
  import {
5
5
  Err,
6
6
  Ok
@@ -27,7 +27,7 @@ var runSecurityScanDefinition = {
27
27
  };
28
28
  async function handleRunSecurityScan(input) {
29
29
  try {
30
- const core = await import("./dist-CPKL5Y2R.js");
30
+ const core = await import("./dist-46VOJIG4.js");
31
31
  const projectRoot = sanitizePath(input.path);
32
32
  let configData = {};
33
33
  try {
@@ -114,7 +114,7 @@ var getSecurityTrendsDefinition = {
114
114
  };
115
115
  async function handleGetSecurityTrends(input) {
116
116
  try {
117
- const core = await import("./dist-CPKL5Y2R.js");
117
+ const core = await import("./dist-46VOJIG4.js");
118
118
  const projectRoot = sanitizePath(input.path);
119
119
  const manager = new core.SecurityTimelineManager(projectRoot);
120
120
  const trendOptions = {};
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  listPersonas,
6
6
  loadPersona
7
- } from "./chunk-BO4AJZRE.js";
7
+ } from "./chunk-H43UQY6B.js";
8
8
  import {
9
9
  GENERATED_HEADER_AGENT,
10
10
  VALID_PLATFORMS,
@@ -9,7 +9,7 @@ async function runScan(projectPath) {
9
9
  KnowledgeIngestor,
10
10
  GitIngestor,
11
11
  RequirementIngestor
12
- } = await import("./dist-BZS2XRLG.js");
12
+ } = await import("./dist-BP6E6QGG.js");
13
13
  const store = new GraphStore();
14
14
  const start = Date.now();
15
15
  await new CodeIngestor(store).ingest(projectPath);
@@ -7,10 +7,10 @@ import {
7
7
  import {
8
8
  findConfigFile,
9
9
  loadConfig
10
- } from "./chunk-A4ETL34H.js";
10
+ } from "./chunk-KLE6FXWM.js";
11
11
  import {
12
12
  init_dist
13
- } from "./chunk-IBTHD2UA.js";
13
+ } from "./chunk-6JBJ5FSW.js";
14
14
  import {
15
15
  Ok
16
16
  } from "./chunk-RL4VMEXL.js";
@@ -35,7 +35,7 @@ var checkPerformanceDefinition = {
35
35
  };
36
36
  async function handleCheckPerformance(input) {
37
37
  try {
38
- const { EntropyAnalyzer } = await import("./dist-CPKL5Y2R.js");
38
+ const { EntropyAnalyzer } = await import("./dist-46VOJIG4.js");
39
39
  const typeFilter = input.type ?? "all";
40
40
  const projectPath = sanitizePath(input.path);
41
41
  let entryPoints;
@@ -58,10 +58,10 @@ async function handleCheckPerformance(input) {
58
58
  });
59
59
  let graphOptions;
60
60
  try {
61
- const { loadGraphStore } = await import("./graph-loader-QEI7SYOQ.js");
61
+ const { loadGraphStore } = await import("./graph-loader-BI3OFFFS.js");
62
62
  const store = await loadGraphStore(projectPath);
63
63
  if (store) {
64
- const { GraphComplexityAdapter, GraphCouplingAdapter } = await import("./dist-BZS2XRLG.js");
64
+ const { GraphComplexityAdapter, GraphCouplingAdapter } = await import("./dist-BP6E6QGG.js");
65
65
  const complexityAdapter = new GraphComplexityAdapter(store);
66
66
  const couplingAdapter = new GraphCouplingAdapter(store);
67
67
  graphOptions = {
@@ -98,7 +98,7 @@ var getPerfBaselinesDefinition = {
98
98
  };
99
99
  async function handleGetPerfBaselines(input) {
100
100
  try {
101
- const { BaselineManager } = await import("./dist-CPKL5Y2R.js");
101
+ const { BaselineManager } = await import("./dist-46VOJIG4.js");
102
102
  const manager = new BaselineManager(sanitizePath(input.path));
103
103
  const baselines = manager.load();
104
104
  return resultToMcpResponse(
@@ -146,7 +146,7 @@ var updatePerfBaselinesDefinition = {
146
146
  };
147
147
  async function handleUpdatePerfBaselines(input) {
148
148
  try {
149
- const { BaselineManager } = await import("./dist-CPKL5Y2R.js");
149
+ const { BaselineManager } = await import("./dist-46VOJIG4.js");
150
150
  const manager = new BaselineManager(sanitizePath(input.path));
151
151
  manager.save(input.results, input.commitHash);
152
152
  const updated = manager.load();
@@ -176,7 +176,7 @@ var getCriticalPathsDefinition = {
176
176
  };
177
177
  async function handleGetCriticalPaths(input) {
178
178
  try {
179
- const { CriticalPathResolver } = await import("./dist-CPKL5Y2R.js");
179
+ const { CriticalPathResolver } = await import("./dist-46VOJIG4.js");
180
180
  const resolver = new CriticalPathResolver(sanitizePath(input.path));
181
181
  const result = await resolver.resolve();
182
182
  return resultToMcpResponse(Ok(result));
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  init_dist
3
- } from "./chunk-IBTHD2UA.js";
3
+ } from "./chunk-6JBJ5FSW.js";
4
4
  import {
5
5
  Err,
6
6
  Ok
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  init_dist
3
- } from "./chunk-IBTHD2UA.js";
3
+ } from "./chunk-6JBJ5FSW.js";
4
4
  import {
5
5
  Ok
6
6
  } from "./chunk-RL4VMEXL.js";
@@ -33,7 +33,7 @@ var createSelfReviewDefinition = {
33
33
  };
34
34
  async function handleCreateSelfReview(input) {
35
35
  try {
36
- const { parseDiff, createSelfReview } = await import("./dist-CPKL5Y2R.js");
36
+ const { parseDiff, createSelfReview } = await import("./dist-46VOJIG4.js");
37
37
  const parseResult = parseDiff(input.diff);
38
38
  if (!parseResult.ok) {
39
39
  return resultToMcpResponse(parseResult);
@@ -53,11 +53,11 @@ async function handleCreateSelfReview(input) {
53
53
  ...input.maxFileCount !== void 0 ? { maxChangedFiles: input.maxFileCount } : {}
54
54
  }
55
55
  };
56
- const { loadGraphStore } = await import("./graph-loader-QEI7SYOQ.js");
56
+ const { loadGraphStore } = await import("./graph-loader-BI3OFFFS.js");
57
57
  const store = await loadGraphStore(projectPath);
58
58
  let graphData;
59
59
  if (store) {
60
- const { GraphFeedbackAdapter } = await import("./dist-BZS2XRLG.js");
60
+ const { GraphFeedbackAdapter } = await import("./dist-BP6E6QGG.js");
61
61
  const adapter = new GraphFeedbackAdapter(store);
62
62
  const changedFiles = parseResult.value.files.map((f) => f.path);
63
63
  const impact = adapter.computeImpactData(changedFiles);
@@ -119,7 +119,7 @@ var analyzeDiffDefinition = {
119
119
  };
120
120
  async function handleAnalyzeDiff(input) {
121
121
  try {
122
- const { parseDiff, analyzeDiff } = await import("./dist-CPKL5Y2R.js");
122
+ const { parseDiff, analyzeDiff } = await import("./dist-46VOJIG4.js");
123
123
  const parseResult = parseDiff(input.diff);
124
124
  if (!parseResult.ok) {
125
125
  return resultToMcpResponse(parseResult);
@@ -139,10 +139,10 @@ async function handleAnalyzeDiff(input) {
139
139
  let graphImpactData;
140
140
  if (input.path) {
141
141
  try {
142
- const { loadGraphStore } = await import("./graph-loader-QEI7SYOQ.js");
142
+ const { loadGraphStore } = await import("./graph-loader-BI3OFFFS.js");
143
143
  const store = await loadGraphStore(sanitizePath(input.path));
144
144
  if (store) {
145
- const { GraphFeedbackAdapter } = await import("./dist-BZS2XRLG.js");
145
+ const { GraphFeedbackAdapter } = await import("./dist-BP6E6QGG.js");
146
146
  const adapter = new GraphFeedbackAdapter(store);
147
147
  const changedFiles = parseResult.value.files.map((f) => f.path);
148
148
  const impact = adapter.computeImpactData(changedFiles);
@@ -195,7 +195,7 @@ var requestPeerReviewDefinition = {
195
195
  };
196
196
  async function handleRequestPeerReview(input) {
197
197
  try {
198
- const { parseDiff, requestPeerReview } = await import("./dist-CPKL5Y2R.js");
198
+ const { parseDiff, requestPeerReview } = await import("./dist-46VOJIG4.js");
199
199
  const parseResult = parseDiff(input.diff);
200
200
  if (!parseResult.ok) {
201
201
  return resultToMcpResponse(parseResult);
@@ -206,10 +206,10 @@ async function handleRequestPeerReview(input) {
206
206
  ...input.context ? { metadata: { context: input.context } } : {}
207
207
  };
208
208
  try {
209
- const { loadGraphStore } = await import("./graph-loader-QEI7SYOQ.js");
209
+ const { loadGraphStore } = await import("./graph-loader-BI3OFFFS.js");
210
210
  const store = await loadGraphStore(sanitizePath(input.path));
211
211
  if (store) {
212
- const { GraphFeedbackAdapter } = await import("./dist-BZS2XRLG.js");
212
+ const { GraphFeedbackAdapter } = await import("./dist-BP6E6QGG.js");
213
213
  const adapter = new GraphFeedbackAdapter(store);
214
214
  const changedFiles = parseResult.value.files.map((f) => f.path);
215
215
  const impactData = adapter.computeImpactData(changedFiles);