@harness-engineering/cli 1.20.1 → 1.22.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 (159) hide show
  1. package/dist/agents/skills/claude-code/cleanup-dead-code/skill.yaml +3 -0
  2. package/dist/agents/skills/claude-code/detect-doc-drift/skill.yaml +5 -0
  3. package/dist/agents/skills/claude-code/enforce-architecture/skill.yaml +13 -0
  4. package/dist/agents/skills/claude-code/harness-accessibility/skill.yaml +20 -0
  5. package/dist/agents/skills/claude-code/harness-code-review/skill.yaml +5 -0
  6. package/dist/agents/skills/claude-code/harness-codebase-cleanup/skill.yaml +5 -0
  7. package/dist/agents/skills/claude-code/harness-debugging/skill.yaml +5 -0
  8. package/dist/agents/skills/claude-code/harness-dependency-health/skill.yaml +9 -0
  9. package/dist/agents/skills/claude-code/harness-design/skill.yaml +20 -0
  10. package/dist/agents/skills/claude-code/harness-design-mobile/skill.yaml +20 -0
  11. package/dist/agents/skills/claude-code/harness-design-system/skill.yaml +22 -0
  12. package/dist/agents/skills/claude-code/harness-design-web/skill.yaml +22 -0
  13. package/dist/agents/skills/claude-code/harness-diagnostics/skill.yaml +19 -0
  14. package/dist/agents/skills/claude-code/harness-git-workflow/skill.yaml +15 -0
  15. package/dist/agents/skills/claude-code/harness-hotspot-detector/skill.yaml +9 -0
  16. package/dist/agents/skills/claude-code/harness-i18n/skill.yaml +22 -0
  17. package/dist/agents/skills/claude-code/harness-i18n-process/skill.yaml +15 -0
  18. package/dist/agents/skills/claude-code/harness-i18n-workflow/skill.yaml +19 -0
  19. package/dist/agents/skills/claude-code/harness-integrity/skill.yaml +5 -0
  20. package/dist/agents/skills/claude-code/harness-perf/skill.yaml +3 -0
  21. package/dist/agents/skills/claude-code/harness-perf-tdd/skill.yaml +20 -0
  22. package/dist/agents/skills/claude-code/harness-pre-commit-review/skill.yaml +18 -0
  23. package/dist/agents/skills/claude-code/harness-refactoring/skill.yaml +9 -0
  24. package/dist/agents/skills/claude-code/harness-security-review/skill.yaml +23 -0
  25. package/dist/agents/skills/claude-code/harness-security-scan/skill.yaml +3 -0
  26. package/dist/agents/skills/claude-code/harness-soundness-review/skill.yaml +5 -0
  27. package/dist/agents/skills/claude-code/harness-supply-chain-audit/skill.yaml +3 -0
  28. package/dist/agents/skills/claude-code/harness-tdd/skill.yaml +3 -0
  29. package/dist/agents/skills/codex/cleanup-dead-code/skill.yaml +3 -0
  30. package/dist/agents/skills/codex/detect-doc-drift/skill.yaml +5 -0
  31. package/dist/agents/skills/codex/enforce-architecture/skill.yaml +13 -0
  32. package/dist/agents/skills/codex/harness-accessibility/skill.yaml +20 -0
  33. package/dist/agents/skills/codex/harness-code-review/skill.yaml +5 -0
  34. package/dist/agents/skills/codex/harness-codebase-cleanup/skill.yaml +5 -0
  35. package/dist/agents/skills/codex/harness-debugging/skill.yaml +5 -0
  36. package/dist/agents/skills/codex/harness-dependency-health/skill.yaml +9 -0
  37. package/dist/agents/skills/codex/harness-design/skill.yaml +20 -0
  38. package/dist/agents/skills/codex/harness-design-mobile/skill.yaml +20 -0
  39. package/dist/agents/skills/codex/harness-design-system/skill.yaml +22 -0
  40. package/dist/agents/skills/codex/harness-design-web/skill.yaml +22 -0
  41. package/dist/agents/skills/codex/harness-diagnostics/skill.yaml +19 -0
  42. package/dist/agents/skills/codex/harness-git-workflow/skill.yaml +15 -0
  43. package/dist/agents/skills/codex/harness-hotspot-detector/skill.yaml +9 -0
  44. package/dist/agents/skills/codex/harness-i18n/skill.yaml +22 -0
  45. package/dist/agents/skills/codex/harness-i18n-process/skill.yaml +15 -0
  46. package/dist/agents/skills/codex/harness-i18n-workflow/skill.yaml +19 -0
  47. package/dist/agents/skills/codex/harness-integrity/skill.yaml +5 -0
  48. package/dist/agents/skills/codex/harness-perf/skill.yaml +3 -0
  49. package/dist/agents/skills/codex/harness-perf-tdd/skill.yaml +20 -0
  50. package/dist/agents/skills/codex/harness-pre-commit-review/skill.yaml +18 -0
  51. package/dist/agents/skills/codex/harness-refactoring/skill.yaml +9 -0
  52. package/dist/agents/skills/codex/harness-security-review/skill.yaml +23 -0
  53. package/dist/agents/skills/codex/harness-security-scan/skill.yaml +3 -0
  54. package/dist/agents/skills/codex/harness-soundness-review/skill.yaml +5 -0
  55. package/dist/agents/skills/codex/harness-supply-chain-audit/skill.yaml +3 -0
  56. package/dist/agents/skills/codex/harness-tdd/skill.yaml +3 -0
  57. package/dist/agents/skills/cursor/cleanup-dead-code/skill.yaml +3 -0
  58. package/dist/agents/skills/cursor/detect-doc-drift/skill.yaml +5 -0
  59. package/dist/agents/skills/cursor/enforce-architecture/skill.yaml +13 -0
  60. package/dist/agents/skills/cursor/harness-accessibility/skill.yaml +20 -0
  61. package/dist/agents/skills/cursor/harness-code-review/skill.yaml +5 -0
  62. package/dist/agents/skills/cursor/harness-codebase-cleanup/skill.yaml +5 -0
  63. package/dist/agents/skills/cursor/harness-debugging/skill.yaml +5 -0
  64. package/dist/agents/skills/cursor/harness-dependency-health/skill.yaml +9 -0
  65. package/dist/agents/skills/cursor/harness-design/skill.yaml +20 -0
  66. package/dist/agents/skills/cursor/harness-design-mobile/skill.yaml +20 -0
  67. package/dist/agents/skills/cursor/harness-design-system/skill.yaml +22 -0
  68. package/dist/agents/skills/cursor/harness-design-web/skill.yaml +22 -0
  69. package/dist/agents/skills/cursor/harness-diagnostics/skill.yaml +19 -0
  70. package/dist/agents/skills/cursor/harness-git-workflow/skill.yaml +15 -0
  71. package/dist/agents/skills/cursor/harness-hotspot-detector/skill.yaml +9 -0
  72. package/dist/agents/skills/cursor/harness-i18n/skill.yaml +22 -0
  73. package/dist/agents/skills/cursor/harness-i18n-process/skill.yaml +15 -0
  74. package/dist/agents/skills/cursor/harness-i18n-workflow/skill.yaml +19 -0
  75. package/dist/agents/skills/cursor/harness-integrity/skill.yaml +5 -0
  76. package/dist/agents/skills/cursor/harness-perf/skill.yaml +3 -0
  77. package/dist/agents/skills/cursor/harness-perf-tdd/skill.yaml +20 -0
  78. package/dist/agents/skills/cursor/harness-pre-commit-review/skill.yaml +18 -0
  79. package/dist/agents/skills/cursor/harness-refactoring/skill.yaml +9 -0
  80. package/dist/agents/skills/cursor/harness-security-review/skill.yaml +23 -0
  81. package/dist/agents/skills/cursor/harness-security-scan/skill.yaml +3 -0
  82. package/dist/agents/skills/cursor/harness-soundness-review/skill.yaml +5 -0
  83. package/dist/agents/skills/cursor/harness-supply-chain-audit/skill.yaml +3 -0
  84. package/dist/agents/skills/cursor/harness-tdd/skill.yaml +3 -0
  85. package/dist/agents/skills/gemini-cli/cleanup-dead-code/skill.yaml +3 -0
  86. package/dist/agents/skills/gemini-cli/detect-doc-drift/skill.yaml +5 -0
  87. package/dist/agents/skills/gemini-cli/enforce-architecture/skill.yaml +13 -0
  88. package/dist/agents/skills/gemini-cli/harness-accessibility/skill.yaml +20 -0
  89. package/dist/agents/skills/gemini-cli/harness-code-review/skill.yaml +5 -0
  90. package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/skill.yaml +5 -0
  91. package/dist/agents/skills/gemini-cli/harness-debugging/skill.yaml +5 -0
  92. package/dist/agents/skills/gemini-cli/harness-dependency-health/skill.yaml +9 -0
  93. package/dist/agents/skills/gemini-cli/harness-design/skill.yaml +20 -0
  94. package/dist/agents/skills/gemini-cli/harness-design-mobile/skill.yaml +20 -0
  95. package/dist/agents/skills/gemini-cli/harness-design-system/skill.yaml +22 -0
  96. package/dist/agents/skills/gemini-cli/harness-design-web/skill.yaml +22 -0
  97. package/dist/agents/skills/gemini-cli/harness-diagnostics/skill.yaml +19 -0
  98. package/dist/agents/skills/gemini-cli/harness-git-workflow/skill.yaml +15 -0
  99. package/dist/agents/skills/gemini-cli/harness-hotspot-detector/skill.yaml +9 -0
  100. package/dist/agents/skills/gemini-cli/harness-i18n/skill.yaml +22 -0
  101. package/dist/agents/skills/gemini-cli/harness-i18n-process/skill.yaml +15 -0
  102. package/dist/agents/skills/gemini-cli/harness-i18n-workflow/skill.yaml +19 -0
  103. package/dist/agents/skills/gemini-cli/harness-integrity/skill.yaml +5 -0
  104. package/dist/agents/skills/gemini-cli/harness-perf/skill.yaml +3 -0
  105. package/dist/agents/skills/gemini-cli/harness-perf-tdd/skill.yaml +20 -0
  106. package/dist/agents/skills/gemini-cli/harness-pre-commit-review/skill.yaml +18 -0
  107. package/dist/agents/skills/gemini-cli/harness-refactoring/skill.yaml +9 -0
  108. package/dist/agents/skills/gemini-cli/harness-security-review/skill.yaml +23 -0
  109. package/dist/agents/skills/gemini-cli/harness-security-scan/skill.yaml +3 -0
  110. package/dist/agents/skills/gemini-cli/harness-soundness-review/skill.yaml +5 -0
  111. package/dist/agents/skills/gemini-cli/harness-supply-chain-audit/skill.yaml +3 -0
  112. package/dist/agents/skills/gemini-cli/harness-tdd/skill.yaml +3 -0
  113. package/dist/{agents-md-WHXVPOK2.js → agents-md-PM7LO74M.js} +2 -1
  114. package/dist/{architecture-45YCLD26.js → architecture-OVOCDTI6.js} +3 -2
  115. package/dist/assess-project-R2OZIDDS.js +9 -0
  116. package/dist/bin/harness-mcp.js +15 -13
  117. package/dist/bin/harness.js +21 -19
  118. package/dist/{check-phase-gate-2VXVOUJ5.js → check-phase-gate-7JQ6EW5R.js} +4 -3
  119. package/dist/{chunk-M6TIO6NF.js → chunk-2PAPHA77.js} +1 -1
  120. package/dist/chunk-5FBWWMY2.js +293 -0
  121. package/dist/{chunk-H6KZAGHZ.js → chunk-5QTWFO24.js} +8 -8
  122. package/dist/{chunk-CZZXE6BL.js → chunk-ASS5TD2Y.js} +1 -1
  123. package/dist/{chunk-45ZJPG24.js → chunk-B4WHXHF7.js} +1 -1
  124. package/dist/{chunk-SQY4AAKP.js → chunk-DJEBBENF.js} +1005 -408
  125. package/dist/{chunk-LEWXD6PR.js → chunk-DXYOAQQC.js} +1 -1
  126. package/dist/{chunk-PDEEQJHH.js → chunk-FSLFBLYW.js} +7 -7
  127. package/dist/{chunk-YDOGGQSF.js → chunk-GRJ7A4WT.js} +17 -2
  128. package/dist/{chunk-4U4V7A6U.js → chunk-IK5GSLW6.js} +4 -4
  129. package/dist/{chunk-LVJ7SCD7.js → chunk-J7W4LTRK.js} +2 -2
  130. package/dist/{chunk-PDOSLTWP.js → chunk-PUOMFNRO.js} +26 -3
  131. package/dist/{chunk-HKUX2X7O.js → chunk-SE4YPMLH.js} +9 -1
  132. package/dist/{chunk-HAJD5LTI.js → chunk-SOTTK27D.js} +459 -37
  133. package/dist/{chunk-LRG3B43J.js → chunk-T5QWCVGK.js} +1 -1
  134. package/dist/{dist-U7EAO6T2.js → chunk-TEZI27SA.js} +401 -60
  135. package/dist/{chunk-IC5CZSHF.js → chunk-U44JNY3Y.js} +1549 -593
  136. package/dist/{chunk-A33LHIRD.js → chunk-W6MPLFXU.js} +3 -3
  137. package/dist/{chunk-V73TEHIF.js → chunk-ZEIEUCZL.js} +9 -9
  138. package/dist/{ci-workflow-HWX5OVLI.js → ci-workflow-OTTEERPF.js} +2 -1
  139. package/dist/{create-skill-NDXQSTIK.js → create-skill-U3XCFRZN.js} +2 -2
  140. package/dist/dist-IA6XYKNO.js +92 -0
  141. package/dist/{dist-WHL3NN5S.js → dist-LCR2IO7U.js} +56 -3
  142. package/dist/{docs-FJFY7GF2.js → docs-CHAYSGOP.js} +4 -3
  143. package/dist/{engine-R5BZHIZB.js → engine-4MY2U5RZ.js} +2 -1
  144. package/dist/{entropy-Y2GE4MYS.js → entropy-AKSZG7G5.js} +3 -2
  145. package/dist/{feedback-FKZ7GMPO.js → feedback-QGCSW7SB.js} +1 -1
  146. package/dist/{generate-agent-definitions-LN3A45OL.js → generate-agent-definitions-KU6X2UQN.js} +2 -1
  147. package/dist/{graph-loader-KMHDQYDT.js → graph-loader-FJN4H7Y4.js} +1 -1
  148. package/dist/index.d.ts +58 -2
  149. package/dist/index.js +27 -23
  150. package/dist/{loader-2TBQUFWX.js → loader-AV5XEMER.js} +2 -1
  151. package/dist/{mcp-KEY575NJ.js → mcp-LWHVQRG7.js} +15 -13
  152. package/dist/{performance-BSOMMWK5.js → performance-ETZVXXGQ.js} +4 -3
  153. package/dist/{review-pipeline-KUBHP3RV.js → review-pipeline-3ZS3GJSP.js} +1 -1
  154. package/dist/{runtime-BN7KGJAO.js → runtime-KQTJRK3H.js} +2 -1
  155. package/dist/{security-3T4JGDZP.js → security-LJCLZES6.js} +1 -1
  156. package/dist/{skill-executor-XEVDGXUM.js → skill-executor-2BZQLHYN.js} +2 -2
  157. package/dist/{validate-R5WGB2AV.js → validate-4IA5RPEX.js} +3 -2
  158. package/dist/{validate-cross-check-76Z5P6EX.js → validate-cross-check-VX2BAHQI.js} +2 -1
  159. package/package.json +4 -4
@@ -26,7 +26,7 @@ var runSecurityScanDefinition = {
26
26
  };
27
27
  async function handleRunSecurityScan(input) {
28
28
  try {
29
- const core = await import("./dist-WHL3NN5S.js");
29
+ const core = await import("./dist-LCR2IO7U.js");
30
30
  const projectRoot = sanitizePath(input.path);
31
31
  let configData = {};
32
32
  try {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  findConfigFile,
3
3
  loadConfig
4
- } from "./chunk-YDOGGQSF.js";
4
+ } from "./chunk-GRJ7A4WT.js";
5
5
  import {
6
6
  resultToMcpResponse
7
7
  } from "./chunk-IDZNPTYD.js";
@@ -31,7 +31,7 @@ var checkPerformanceDefinition = {
31
31
  };
32
32
  async function handleCheckPerformance(input) {
33
33
  try {
34
- const { EntropyAnalyzer } = await import("./dist-WHL3NN5S.js");
34
+ const { EntropyAnalyzer } = await import("./dist-LCR2IO7U.js");
35
35
  const typeFilter = input.type ?? "all";
36
36
  const projectPath = sanitizePath(input.path);
37
37
  let entryPoints;
@@ -54,10 +54,10 @@ async function handleCheckPerformance(input) {
54
54
  });
55
55
  let graphOptions;
56
56
  try {
57
- const { loadGraphStore } = await import("./graph-loader-KMHDQYDT.js");
57
+ const { loadGraphStore } = await import("./graph-loader-FJN4H7Y4.js");
58
58
  const store = await loadGraphStore(projectPath);
59
59
  if (store) {
60
- const { GraphComplexityAdapter, GraphCouplingAdapter } = await import("./dist-U7EAO6T2.js");
60
+ const { GraphComplexityAdapter, GraphCouplingAdapter } = await import("./dist-IA6XYKNO.js");
61
61
  const complexityAdapter = new GraphComplexityAdapter(store);
62
62
  const couplingAdapter = new GraphCouplingAdapter(store);
63
63
  graphOptions = {
@@ -94,7 +94,7 @@ var getPerfBaselinesDefinition = {
94
94
  };
95
95
  async function handleGetPerfBaselines(input) {
96
96
  try {
97
- const { BaselineManager } = await import("./dist-WHL3NN5S.js");
97
+ const { BaselineManager } = await import("./dist-LCR2IO7U.js");
98
98
  const manager = new BaselineManager(sanitizePath(input.path));
99
99
  const baselines = manager.load();
100
100
  return resultToMcpResponse(
@@ -142,7 +142,7 @@ var updatePerfBaselinesDefinition = {
142
142
  };
143
143
  async function handleUpdatePerfBaselines(input) {
144
144
  try {
145
- const { BaselineManager } = await import("./dist-WHL3NN5S.js");
145
+ const { BaselineManager } = await import("./dist-LCR2IO7U.js");
146
146
  const manager = new BaselineManager(sanitizePath(input.path));
147
147
  manager.save(input.results, input.commitHash);
148
148
  const updated = manager.load();
@@ -172,7 +172,7 @@ var getCriticalPathsDefinition = {
172
172
  };
173
173
  async function handleGetCriticalPaths(input) {
174
174
  try {
175
- const { CriticalPathResolver } = await import("./dist-WHL3NN5S.js");
175
+ const { CriticalPathResolver } = await import("./dist-LCR2IO7U.js");
176
176
  const resolver = new CriticalPathResolver(sanitizePath(input.path));
177
177
  const result = await resolver.resolve();
178
178
  return resultToMcpResponse(Ok(result));
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-3WGJMBKH.js";
5
5
  import {
6
6
  ArchConfigSchema
7
- } from "./chunk-IC5CZSHF.js";
7
+ } from "./chunk-U44JNY3Y.js";
8
8
  import {
9
9
  Err,
10
10
  Ok
@@ -54,7 +54,9 @@ var PhaseGateMappingSchema = z.object({
54
54
  /** Pattern for implementation files */
55
55
  implPattern: z.string(),
56
56
  /** Pattern for corresponding specification files */
57
- specPattern: z.string()
57
+ specPattern: z.string(),
58
+ /** When true, validate that the spec file contains a numbered requirements section */
59
+ contentValidation: z.boolean().default(false)
58
60
  });
59
61
  var PhaseGatesConfigSchema = z.object({
60
62
  /** Whether phase gate checks are enabled */
@@ -245,6 +247,19 @@ var HarnessConfigSchema = z.object({
245
247
  /** Override the tier of specific skills (e.g., promote a Tier 3 skill to Tier 2) */
246
248
  tierOverrides: z.record(z.string(), z.number().int().min(1).max(3)).default({})
247
249
  }).optional(),
250
+ /** Spec-to-implementation traceability check settings */
251
+ traceability: z.object({
252
+ /** Whether traceability checks are enabled */
253
+ enabled: z.boolean().default(true),
254
+ /** Severity level when traceability coverage is below threshold */
255
+ severity: z.enum(["error", "warning"]).default("warning"),
256
+ /** Minimum required coverage percentage (0-100) */
257
+ minCoverage: z.number().min(0).max(100).default(0),
258
+ /** Glob patterns for specs to include in traceability checks */
259
+ includeSpecs: z.array(z.string()).default(["docs/changes/*/proposal.md"]),
260
+ /** Glob patterns for specs to exclude from traceability checks */
261
+ excludeSpecs: z.array(z.string()).default([])
262
+ }).optional(),
248
263
  /** Roadmap sync and tracker integration settings */
249
264
  roadmap: RoadmapConfigSchema.optional(),
250
265
  /** How often (in ms) to check for CLI updates */
@@ -10,10 +10,10 @@ import {
10
10
 
11
11
  // src/mcp/tools/entropy.ts
12
12
  async function loadEntropyGraphOptions(projectPath) {
13
- const { loadGraphStore } = await import("./graph-loader-KMHDQYDT.js");
13
+ const { loadGraphStore } = await import("./graph-loader-FJN4H7Y4.js");
14
14
  const store = await loadGraphStore(projectPath);
15
15
  if (!store) return void 0;
16
- const { GraphEntropyAdapter } = await import("./dist-U7EAO6T2.js");
16
+ const { GraphEntropyAdapter } = await import("./dist-IA6XYKNO.js");
17
17
  const adapter = new GraphEntropyAdapter(store);
18
18
  const driftData = adapter.computeDriftData();
19
19
  const deadCodeData = adapter.computeDeadCodeData();
@@ -123,7 +123,7 @@ function buildSummaryResponse(report) {
123
123
  }
124
124
  async function handleDetectEntropy(input) {
125
125
  try {
126
- const { EntropyAnalyzer } = await import("./dist-WHL3NN5S.js");
126
+ const { EntropyAnalyzer } = await import("./dist-LCR2IO7U.js");
127
127
  const typeFilter = input.type ?? "all";
128
128
  const analyzer = new EntropyAnalyzer({
129
129
  rootDir: sanitizePath(input.path),
@@ -142,7 +142,7 @@ async function handleDetectEntropy(input) {
142
142
  return resultToMcpResponse(result);
143
143
  }
144
144
  if (!result.ok) return resultToMcpResponse(result);
145
- const { createFixes, applyFixes, generateSuggestions } = await import("./dist-WHL3NN5S.js");
145
+ const { createFixes, applyFixes, generateSuggestions } = await import("./dist-LCR2IO7U.js");
146
146
  const report = result.value;
147
147
  const deadCode = report.deadCode;
148
148
  const fixTypesConfig = input.fixTypes ? { fixTypes: input.fixTypes } : void 0;
@@ -49,7 +49,7 @@ async function handleValidateProject(input) {
49
49
  checks.config = "pass";
50
50
  const config = configResult.value;
51
51
  try {
52
- const core = await import("./dist-WHL3NN5S.js");
52
+ const core = await import("./dist-LCR2IO7U.js");
53
53
  if (typeof core.validateFileStructure === "function" && Array.isArray(config.conventions)) {
54
54
  const conventions = config.conventions;
55
55
  const structureResult = await core.validateFileStructure(projectPath, conventions);
@@ -68,7 +68,7 @@ async function handleValidateProject(input) {
68
68
  } catch {
69
69
  }
70
70
  try {
71
- const core = await import("./dist-WHL3NN5S.js");
71
+ const core = await import("./dist-LCR2IO7U.js");
72
72
  if (typeof core.validateAgentsMap === "function") {
73
73
  const agentsMapPath = path.join(projectPath, "AGENTS.md");
74
74
  const agentsResult = await core.validateAgentsMap(agentsMapPath);
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-EBJQ6N4M.js";
4
4
  import {
5
5
  resolveConfig
6
- } from "./chunk-YDOGGQSF.js";
6
+ } from "./chunk-GRJ7A4WT.js";
7
7
  import {
8
8
  ExitCode
9
9
  } from "./chunk-3WGJMBKH.js";
@@ -138,11 +138,34 @@ async function runCheckPhaseGate(options) {
138
138
  for (const implFile of implFiles) {
139
139
  checkedFiles++;
140
140
  const expectedSpec = resolveSpecPath(implFile, mapping.implPattern, mapping.specPattern, cwd);
141
+ const relImpl = path.relative(cwd, implFile).replace(/\\/g, "/");
142
+ const relSpec = path.relative(cwd, expectedSpec).replace(/\\/g, "/");
141
143
  if (!fs.existsSync(expectedSpec)) {
142
144
  missingSpecs.push({
143
- implFile: path.relative(cwd, implFile).replace(/\\/g, "/"),
144
- expectedSpec: path.relative(cwd, expectedSpec).replace(/\\/g, "/")
145
+ implFile: relImpl,
146
+ expectedSpec: relSpec
145
147
  });
148
+ } else if (mapping.contentValidation) {
149
+ const content = fs.readFileSync(expectedSpec, "utf-8");
150
+ const sectionPattern = /^#+\s*(Observable Truths|Success Criteria|Acceptance Criteria)/im;
151
+ const sectionMatch = sectionPattern.exec(content);
152
+ if (!sectionMatch) {
153
+ missingSpecs.push({
154
+ implFile: relImpl,
155
+ expectedSpec: `${relSpec} (missing requirements section: expected Observable Truths, Success Criteria, or Acceptance Criteria heading)`
156
+ });
157
+ } else {
158
+ const sectionStart = sectionMatch.index + sectionMatch[0].length;
159
+ const nextHeadingMatch = /^#+\s/m.exec(content.slice(sectionStart));
160
+ const sectionContent = nextHeadingMatch ? content.slice(sectionStart, sectionStart + nextHeadingMatch.index) : content.slice(sectionStart);
161
+ const hasNumberedItem = /^\s*\d+\.\s+/m.test(sectionContent);
162
+ if (!hasNumberedItem) {
163
+ missingSpecs.push({
164
+ implFile: relImpl,
165
+ expectedSpec: `${relSpec} (requirements section "${sectionMatch[1]}" has no numbered items)`
166
+ });
167
+ }
168
+ }
146
169
  }
147
170
  }
148
171
  }
@@ -52,6 +52,13 @@ var SkillCursorSchema = z.object({
52
52
  var SkillCodexSchema = z.object({
53
53
  instructions_override: z.string().optional()
54
54
  });
55
+ var SkillAddressSchema = z.object({
56
+ signal: z.string(),
57
+ hard: z.boolean().optional(),
58
+ metric: z.string().optional(),
59
+ threshold: z.number().optional(),
60
+ weight: z.number().min(0).max(1).optional()
61
+ });
55
62
  var SkillMetadataSchema = z.object({
56
63
  name: z.string().regex(/^[a-z][a-z0-9-]*$/, "Name must be lowercase with hyphens"),
57
64
  version: z.string().regex(/^\d+\.\d+\.\d+$/, "Version must be semver format"),
@@ -72,7 +79,8 @@ var SkillMetadataSchema = z.object({
72
79
  keywords: z.array(z.string()).default([]),
73
80
  stack_signals: z.array(z.string()).default([]),
74
81
  cursor: SkillCursorSchema.optional(),
75
- codex: SkillCodexSchema.optional()
82
+ codex: SkillCodexSchema.optional(),
83
+ addresses: z.array(SkillAddressSchema).default([])
76
84
  });
77
85
 
78
86
  export {