coding-agent-harness 1.0.7 → 1.1.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 (238) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/CONTRIBUTING.md +9 -5
  3. package/README.md +12 -2
  4. package/README.zh-CN.md +10 -2
  5. package/SKILL.md +14 -3
  6. package/dist/build-dist.mjs +32 -6
  7. package/dist/check-dist-observation.mjs +73 -28
  8. package/dist/check-harness.mjs +0 -1
  9. package/dist/check-import-graph.mjs +44 -27
  10. package/dist/check-lite-forbidden-surfaces.mjs +121 -0
  11. package/dist/check-no-ts-nocheck.mjs +88 -0
  12. package/dist/check-runtime-emit.mjs +10 -3
  13. package/dist/check-type-boundaries.mjs +67 -8
  14. package/dist/commands/dashboard-command.mjs +52 -14
  15. package/dist/commands/migration-command.mjs +18 -8
  16. package/dist/commands/module-command.mjs +142 -0
  17. package/dist/commands/preset-command.mjs +65 -4
  18. package/dist/commands/registry.mjs +483 -0
  19. package/dist/commands/task-command.mjs +111 -53
  20. package/dist/harness.mjs +6 -303
  21. package/dist/lib/capability-registry.mjs +229 -53
  22. package/dist/lib/check-module-parallel.mjs +1 -6
  23. package/dist/lib/check-profiles.mjs +39 -46
  24. package/dist/lib/check-task-contracts.mjs +6 -4
  25. package/dist/lib/command-registry.mjs +248 -0
  26. package/dist/lib/core-shared.mjs +78 -3
  27. package/dist/lib/dashboard-data.mjs +203 -22
  28. package/dist/lib/dashboard-workbench.mjs +245 -21
  29. package/dist/lib/dashboard-writer.mjs +4 -1
  30. package/dist/lib/git-status-summary.mjs +0 -1
  31. package/dist/lib/governance-index-generator.mjs +7 -5
  32. package/dist/lib/governance-sync.mjs +46 -121
  33. package/dist/lib/governance-table-boundary.mjs +1 -14
  34. package/dist/lib/harness-core.mjs +5 -1
  35. package/dist/lib/harness-paths.mjs +115 -1
  36. package/dist/lib/impact-classifier.mjs +420 -0
  37. package/dist/lib/lesson-maintenance.mjs +1 -2
  38. package/dist/lib/markdown-utils.mjs +50 -1
  39. package/dist/lib/migration-planner.mjs +31 -16
  40. package/dist/lib/migration-support.mjs +5 -4
  41. package/dist/lib/module-registry.mjs +296 -0
  42. package/dist/lib/preset-audit-contracts.mjs +24 -1
  43. package/dist/lib/preset-engine.mjs +68 -29
  44. package/dist/lib/preset-registry.mjs +374 -72
  45. package/dist/lib/preset-runner.mjs +560 -0
  46. package/dist/lib/review-confirm-git-gate.mjs +73 -19
  47. package/dist/lib/status-builder.mjs +23 -8
  48. package/dist/lib/structure-migration.mjs +6 -4
  49. package/dist/lib/subagent-authorization-audit.mjs +8 -2
  50. package/dist/lib/task-archive-eligibility.mjs +65 -0
  51. package/dist/lib/task-audit-metadata.mjs +25 -11
  52. package/dist/lib/task-audit-migration.mjs +21 -14
  53. package/dist/lib/task-discovery-contract.mjs +32 -0
  54. package/dist/lib/task-index.mjs +4 -2
  55. package/dist/lib/task-lesson-candidates.mjs +1 -2
  56. package/dist/lib/task-lesson-sedimentation.mjs +310 -9
  57. package/dist/lib/task-lifecycle/create-task-helpers.mjs +6 -3
  58. package/dist/lib/task-lifecycle/phase-sync.mjs +0 -1
  59. package/dist/lib/task-lifecycle/preset-interop.mjs +16 -0
  60. package/dist/lib/task-lifecycle/review-confirm.mjs +34 -2
  61. package/dist/lib/task-lifecycle/review-gates.mjs +12 -5
  62. package/dist/lib/task-lifecycle/review-submission.mjs +1 -2
  63. package/dist/lib/task-lifecycle/scaffold-provenance.mjs +0 -1
  64. package/dist/lib/task-lifecycle/template-files.mjs +2 -5
  65. package/dist/lib/task-lifecycle.mjs +117 -159
  66. package/dist/lib/task-metadata.mjs +10 -5
  67. package/dist/lib/task-preset-contract-drift.mjs +45 -0
  68. package/dist/lib/task-repository.mjs +192 -0
  69. package/dist/lib/task-review-model.mjs +38 -17
  70. package/dist/lib/task-scanner.mjs +75 -23
  71. package/dist/lib/task-template-materials.mjs +131 -0
  72. package/dist/lib/task-tombstone-commands.mjs +187 -18
  73. package/dist/lib/types/check-profiles.js +1 -0
  74. package/dist/lib/types/impact.js +1 -0
  75. package/dist/lib/types/preset.js +1 -0
  76. package/dist/lib/types/task-lifecycle.js +1 -0
  77. package/dist/lib/types/task-scanner.js +1 -0
  78. package/dist/postinstall.mjs +2 -2
  79. package/dist/run-built-tests.mjs +10 -3
  80. package/docs-release/README.md +2 -1
  81. package/docs-release/architecture/document-contract-kernel/README.md +150 -0
  82. package/docs-release/architecture/document-contract-kernel/products/full-skill-overlay.md +29 -0
  83. package/docs-release/architecture/document-contract-kernel/products/lite-forbidden-surfaces.txt +26 -0
  84. package/docs-release/architecture/document-contract-kernel/products/lite-skill-overlay.md +37 -0
  85. package/docs-release/architecture/overview.md +2 -2
  86. package/docs-release/architecture/overview.zh-CN.md +2 -2
  87. package/docs-release/architecture/system-explainer/01-system-overview.md +11 -7
  88. package/docs-release/architecture/system-explainer/02-module-dependency.md +4 -4
  89. package/docs-release/architecture/system-explainer/03-task-lifecycle.md +17 -12
  90. package/docs-release/architecture/system-explainer/05-data-flow.md +6 -6
  91. package/docs-release/architecture/system-explainer/06-preset-and-migration.md +2 -2
  92. package/docs-release/architecture/system-explainer/README.md +1 -1
  93. package/docs-release/architecture/system-explainer/en-US/01-system-overview.md +12 -8
  94. package/docs-release/architecture/system-explainer/en-US/02-module-dependency.md +5 -5
  95. package/docs-release/architecture/system-explainer/en-US/03-task-lifecycle.md +19 -11
  96. package/docs-release/architecture/system-explainer/en-US/05-data-flow.md +5 -5
  97. package/docs-release/architecture/system-explainer/en-US/06-preset-and-migration.md +2 -2
  98. package/docs-release/architecture/system-explainer/en-US/README.md +1 -1
  99. package/docs-release/guides/agent-installation.en-US.md +4 -6
  100. package/docs-release/guides/agent-installation.md +11 -8
  101. package/docs-release/guides/contributing.md +10 -3
  102. package/docs-release/guides/contributing.zh-CN.md +10 -3
  103. package/docs-release/guides/legacy-migration-agent-prompt.md +1 -1
  104. package/docs-release/guides/legacy-migration-agent-prompt.zh-CN.md +1 -1
  105. package/docs-release/guides/migration-playbook.en-US.md +9 -6
  106. package/docs-release/guides/migration-playbook.md +9 -6
  107. package/docs-release/guides/preset-development.md +68 -2
  108. package/docs-release/guides/task-state-machine.en-US.md +8 -8
  109. package/docs-release/guides/task-state-machine.md +7 -7
  110. package/docs-release/guides/typescript-runtime-migration-closeout.md +17 -13
  111. package/package.json +19 -11
  112. package/postinstall.mjs +37 -0
  113. package/presets/legacy-migration/preset.yaml +5 -5
  114. package/presets/legacy-migration/templates/execution_strategy.append.md +1 -1
  115. package/presets/lesson-sedimentation/preset.yaml +3 -3
  116. package/presets/module/preset.yaml +2 -2
  117. package/presets/module/templates/execution_strategy.append.md +1 -1
  118. package/presets/module/templates/task_plan.append.md +3 -3
  119. package/presets/release-closeout/checks/check-release-package.mjs +29 -0
  120. package/presets/release-closeout/preset.yaml +100 -0
  121. package/presets/release-closeout/scripts/generate-release-package.mjs +572 -0
  122. package/presets/release-closeout/templates/execution_strategy.append.md +7 -0
  123. package/presets/release-closeout/templates/findings.seed.md +5 -0
  124. package/presets/release-closeout/templates/review.seed.md +3 -0
  125. package/presets/release-closeout/templates/task_plan.append.md +24 -0
  126. package/presets/standard-task/preset.yaml +2 -2
  127. package/references/agents-md-pattern.md +23 -17
  128. package/references/lessons-governance.md +2 -2
  129. package/references/module-parallel-standard.md +3 -6
  130. package/references/pull-request-standard.md +2 -2
  131. package/references/ssot-governance.md +2 -2
  132. package/references/taskr-gap-analysis.md +3 -3
  133. package/run-dist.mjs +34 -0
  134. package/skills/preset-creator/SKILL.md +40 -8
  135. package/skills/preset-creator/references/complex-task-skeleton/brief.md +32 -8
  136. package/skills/preset-creator/references/preset-package-skeleton.md +15 -5
  137. package/skills/preset-creator/references/structure-aware-paths.md +112 -0
  138. package/templates/AGENTS.md.template +28 -26
  139. package/templates/architecture/README.md +2 -2
  140. package/templates/architecture/service-catalog.md +2 -2
  141. package/templates/architecture/services/service-template.md +1 -1
  142. package/templates/dashboard/assets/app-src/00-state.js +5 -1
  143. package/templates/dashboard/assets/app-src/10-router.js +7 -0
  144. package/templates/dashboard/assets/app-src/20-overview.js +8 -8
  145. package/templates/dashboard/assets/app-src/30-tasks.js +132 -40
  146. package/templates/dashboard/assets/app-src/32-task-swimlane.js +314 -0
  147. package/templates/dashboard/assets/app-src/35-task-detail.js +35 -5
  148. package/templates/dashboard/assets/app-src/40-modules.js +257 -41
  149. package/templates/dashboard/assets/app-src/45-review.js +127 -1
  150. package/templates/dashboard/assets/app-src/90-bindings.js +185 -2
  151. package/templates/dashboard/assets/app.css +928 -53
  152. package/templates/dashboard/assets/app.css.manifest.json +2 -0
  153. package/templates/dashboard/assets/app.js +1071 -98
  154. package/templates/dashboard/assets/app.manifest.json +1 -0
  155. package/templates/dashboard/assets/css-src/00-foundation.css +12 -6
  156. package/templates/dashboard/assets/css-src/10-panels-flow.css +2 -2
  157. package/templates/dashboard/assets/css-src/30-task-index.css +21 -13
  158. package/templates/dashboard/assets/css-src/31-archive.css +94 -0
  159. package/templates/dashboard/assets/css-src/32-task-swimlane.css +487 -0
  160. package/templates/dashboard/assets/css-src/35-review-workspace.css +78 -0
  161. package/templates/dashboard/assets/css-src/40-detail-modules-migration.css +191 -14
  162. package/templates/dashboard/assets/css-src/50-responsive-overrides.css +23 -0
  163. package/templates/dashboard/assets/i18n.js +166 -2
  164. package/templates/development/README.md +9 -9
  165. package/templates/development/cross-repo-debugging.md +3 -3
  166. package/templates/development/external-context/service-template.md +1 -1
  167. package/templates/development/external-source-packs/README.md +2 -2
  168. package/templates/integrations/README.md +4 -4
  169. package/templates/integrations/api-contract.md +1 -1
  170. package/templates/integrations/event-contract.md +1 -1
  171. package/templates/integrations/third-party/vendor-template.md +1 -1
  172. package/templates/integrations/webhook-contract.md +1 -1
  173. package/templates/ledger/Harness-Ledger.md +1 -1
  174. package/templates/modules/module_brief.md +50 -0
  175. package/templates/modules/module_plan.md +49 -0
  176. package/templates/modules/registry_view.md +9 -0
  177. package/templates/modules/session_prompt_pack.md +55 -0
  178. package/templates/planning/brief.md +32 -8
  179. package/templates/planning/module_brief.md +28 -3
  180. package/templates/planning/module_plan.md +26 -11
  181. package/templates/planning/module_session_prompt.md +11 -2
  182. package/templates/planning/optional/slices/_slice-template/brief.md +28 -0
  183. package/templates/planning/review.md +1 -1
  184. package/templates/planning/visual_map.md +1 -1
  185. package/templates/reference/docs-library-standard.md +7 -7
  186. package/templates/reference/execution-workflow-standard.md +13 -0
  187. package/templates/reference/external-source-intake-standard.md +10 -10
  188. package/templates/reference/pull-request-standard.md +2 -2
  189. package/templates/reference/repo-governance-standard.md +1 -1
  190. package/templates/reference/review-routing-standard.md +4 -0
  191. package/templates/ssot/Module-Registry.md +4 -38
  192. package/templates/walkthrough/walkthrough-template.md +1 -1
  193. package/templates-zh-CN/AGENTS.md.template +27 -25
  194. package/templates-zh-CN/CLAUDE.md.template +1 -1
  195. package/templates-zh-CN/architecture/README.md +2 -2
  196. package/templates-zh-CN/architecture/service-catalog.md +2 -2
  197. package/templates-zh-CN/architecture/services/service-template.md +1 -1
  198. package/templates-zh-CN/development/README.md +9 -9
  199. package/templates-zh-CN/development/cross-repo-debugging.md +3 -3
  200. package/templates-zh-CN/development/external-context/service-template.md +1 -1
  201. package/templates-zh-CN/development/external-source-packs/README.md +2 -2
  202. package/templates-zh-CN/integrations/README.md +4 -4
  203. package/templates-zh-CN/integrations/api-contract.md +1 -1
  204. package/templates-zh-CN/integrations/event-contract.md +1 -1
  205. package/templates-zh-CN/integrations/third-party/vendor-template.md +1 -1
  206. package/templates-zh-CN/integrations/webhook-contract.md +1 -1
  207. package/templates-zh-CN/ledger/Harness-Ledger.md +1 -1
  208. package/templates-zh-CN/lessons/lesson-arch-process-change.md +1 -1
  209. package/templates-zh-CN/lessons/lesson-new-doc.md +3 -3
  210. package/templates-zh-CN/lessons/lesson-ref-change.md +4 -4
  211. package/templates-zh-CN/modules/module_brief.md +47 -0
  212. package/templates-zh-CN/modules/module_plan.md +48 -0
  213. package/templates-zh-CN/modules/registry_view.md +9 -0
  214. package/templates-zh-CN/modules/session_prompt_pack.md +50 -0
  215. package/templates-zh-CN/planning/INDEX.md +1 -0
  216. package/templates-zh-CN/planning/brief.md +26 -7
  217. package/templates-zh-CN/planning/module_brief.md +24 -2
  218. package/templates-zh-CN/planning/module_plan.md +35 -29
  219. package/templates-zh-CN/planning/module_session_prompt.md +15 -11
  220. package/templates-zh-CN/planning/optional/slices/_slice-template/brief.md +28 -11
  221. package/templates-zh-CN/planning/review.md +1 -1
  222. package/templates-zh-CN/reference/adversarial-review-standard.md +1 -1
  223. package/templates-zh-CN/reference/delivery-operating-model-standard.md +3 -3
  224. package/templates-zh-CN/reference/docs-library-standard.md +27 -27
  225. package/templates-zh-CN/reference/execution-workflow-standard.md +12 -2
  226. package/templates-zh-CN/reference/external-source-intake-standard.md +10 -10
  227. package/templates-zh-CN/reference/harness-ledger-standard.md +3 -3
  228. package/templates-zh-CN/reference/pull-request-standard.md +1 -1
  229. package/templates-zh-CN/reference/regression-ssot-governance.md +2 -2
  230. package/templates-zh-CN/reference/repo-governance-standard.md +1 -1
  231. package/templates-zh-CN/reference/review-routing-standard.md +3 -0
  232. package/templates-zh-CN/reference/walkthrough-standard.md +2 -2
  233. package/templates-zh-CN/reference/worktree-standard.md +1 -1
  234. package/templates-zh-CN/regression/Cadence-Ledger.md +2 -2
  235. package/templates-zh-CN/ssot/Delivery-SSoT.md +2 -2
  236. package/templates-zh-CN/ssot/Module-Registry.md +5 -44
  237. package/templates-zh-CN/ssot/Regression-SSoT.md +2 -2
  238. package/templates-zh-CN/walkthrough/walkthrough-template.md +4 -4
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  import { applyStructureMigration, buildMigrationPlan, planStructureMigration, runMigration, verifyMigrationSession, } from "../lib/harness-core.mjs";
3
2
  import { applyTaskAuditIndexMigration, planTaskAuditIndexMigration, } from "../lib/task-audit-migration.mjs";
4
3
  export function runMigrationCommand(command, { args, takeFlag, takeOption, targetArg }) {
@@ -8,6 +7,7 @@ export function runMigrationCommand(command, { args, takeFlag, takeOption, targe
8
7
  const planOnly = takeFlag("--plan");
9
8
  const force = takeFlag("--force");
10
9
  try {
10
+ const shouldApply = apply && !planOnly;
11
11
  const result = apply && !planOnly
12
12
  ? applyStructureMigration(targetArg(), { force })
13
13
  : planStructureMigration(targetArg());
@@ -15,7 +15,7 @@ export function runMigrationCommand(command, { args, takeFlag, takeOption, targe
15
15
  console.log(JSON.stringify(result, null, 2));
16
16
  }
17
17
  else {
18
- console.log(`Structure migration ${result.applied ? "applied" : "plan"}: ${result.target}`);
18
+ console.log(`Structure migration ${shouldApply ? "applied" : "plan"}: ${result.target}`);
19
19
  console.log(`manifest: ${result.manifest}`);
20
20
  console.log(`actions: ${result.summary.actions}`);
21
21
  for (const action of result.actions || [])
@@ -23,7 +23,7 @@ export function runMigrationCommand(command, { args, takeFlag, takeOption, targe
23
23
  }
24
24
  }
25
25
  catch (error) {
26
- console.error(error.message);
26
+ console.error(errorMessage(error));
27
27
  process.exit(1);
28
28
  }
29
29
  return;
@@ -52,10 +52,11 @@ export function runMigrationCommand(command, { args, takeFlag, takeOption, targe
52
52
  process.exit(result.failures?.length ? 1 : 0);
53
53
  }
54
54
  catch (error) {
55
- if (json && error.plan)
56
- console.error(JSON.stringify(error.plan, null, 2));
55
+ const plan = readProperty(error, "plan");
56
+ if (json && plan)
57
+ console.error(JSON.stringify(plan, null, 2));
57
58
  else
58
- console.error(error.message);
59
+ console.error(errorMessage(error));
59
60
  process.exit(1);
60
61
  }
61
62
  }
@@ -99,7 +100,7 @@ export function runMigrationCommand(command, { args, takeFlag, takeOption, targe
99
100
  }
100
101
  }
101
102
  catch (error) {
102
- console.error(error.message);
103
+ console.error(errorMessage(error));
103
104
  process.exit(1);
104
105
  }
105
106
  return;
@@ -122,7 +123,7 @@ export function runMigrationCommand(command, { args, takeFlag, takeOption, targe
122
123
  }), null, 2));
123
124
  }
124
125
  catch (error) {
125
- console.error(error.message);
126
+ console.error(errorMessage(error));
126
127
  process.exit(1);
127
128
  }
128
129
  return;
@@ -150,3 +151,12 @@ export function runMigrationCommand(command, { args, takeFlag, takeOption, targe
150
151
  }
151
152
  throw new Error(`Unsupported migration command: ${command}`);
152
153
  }
154
+ function readProperty(value, key) {
155
+ return isRecord(value) ? value[key] : undefined;
156
+ }
157
+ function isRecord(value) {
158
+ return typeof value === "object" && value !== null;
159
+ }
160
+ function errorMessage(error) {
161
+ return error instanceof Error ? error.message : String(error);
162
+ }
@@ -0,0 +1,142 @@
1
+ import { normalizeTarget, prepareModuleRegistration, prepareModuleScaffold, prepareModuleUnregister, readHarnessModules, } from "../lib/harness-core.mjs";
2
+ import { takeRepeatedOptionsFromArgs } from "../lib/command-registry.mjs";
3
+ import { beginGovernanceSync, commitGovernanceSync, governanceRelativePaths, releaseGovernanceSync } from "../lib/governance-sync.mjs";
4
+ export function runModuleCommand({ args, takeFlag, takeOption, targetArg }) {
5
+ const subcommand = args.shift() || "list";
6
+ const json = takeFlag("--json");
7
+ if (subcommand === "list") {
8
+ const modules = readHarnessModules(targetArg());
9
+ const items = Object.entries(modules.items || {}).map(([key, module]) => ({ key, ...module }));
10
+ if (json)
11
+ console.log(JSON.stringify({ schema: modules.schema, generatedView: modules.generatedView, modules: items }, null, 2));
12
+ else
13
+ for (const item of items)
14
+ console.log(`${item.key}\t${item.status || "planned"}\t${item.title || item.key}`);
15
+ return;
16
+ }
17
+ if (subcommand === "inspect") {
18
+ const moduleKey = args.shift();
19
+ if (!moduleKey) {
20
+ console.error("Missing module key");
21
+ process.exit(2);
22
+ }
23
+ const modules = readHarnessModules(targetArg());
24
+ const module = modules.items[moduleKey];
25
+ if (!module) {
26
+ console.error(`Module is not registered: ${moduleKey}`);
27
+ process.exit(1);
28
+ }
29
+ console.log(JSON.stringify({ key: moduleKey, ...module }, null, 2));
30
+ return;
31
+ }
32
+ if (subcommand === "register") {
33
+ const dryRun = takeFlag("--dry-run");
34
+ const moduleKey = args.shift();
35
+ if (!moduleKey) {
36
+ console.error("Missing module key");
37
+ process.exit(2);
38
+ }
39
+ const input = {
40
+ title: takeOption("--title", ""),
41
+ prefix: takeOption("--prefix", ""),
42
+ status: takeOption("--status", "planned"),
43
+ branch: takeOption("--branch", ""),
44
+ owner: takeOption("--owner", "coordinator"),
45
+ currentStep: takeOption("--current-step", ""),
46
+ locale: takeOption("--locale", ""),
47
+ scope: takeRepeatedOptionsFromArgs(args, "--scope"),
48
+ shared: takeRepeatedOptionsFromArgs(args, "--shared"),
49
+ dependsOn: takeRepeatedOptionsFromArgs(args, "--depends-on"),
50
+ };
51
+ const target = normalizeTarget(targetArg());
52
+ const planned = prepareModuleRegistration(target, moduleKey, input, { dryRun: true });
53
+ const context = beginGovernanceSync(target, {
54
+ operation: `module register ${moduleKey}`,
55
+ dryRun,
56
+ allowDirtyWorktree: true,
57
+ allowedRelativePaths: governanceRelativePaths(planned.changes),
58
+ });
59
+ try {
60
+ const result = prepareModuleRegistration(target, moduleKey, input, { dryRun });
61
+ const commit = commitGovernanceSync(context, governanceRelativePaths(result.changes), { message: `chore(harness): register module ${result.moduleKey}` });
62
+ console.log(JSON.stringify({ ...result, governance: { commit } }, null, 2));
63
+ }
64
+ catch (error) {
65
+ console.error(errorMessage(error));
66
+ process.exit(1);
67
+ }
68
+ finally {
69
+ releaseGovernanceSync(context);
70
+ }
71
+ return;
72
+ }
73
+ if (subcommand === "unregister") {
74
+ const dryRun = takeFlag("--dry-run");
75
+ const moduleKey = args.shift();
76
+ if (!moduleKey) {
77
+ console.error("Missing module key");
78
+ process.exit(2);
79
+ }
80
+ const target = normalizeTarget(targetArg());
81
+ const planned = prepareModuleUnregister(target, moduleKey, { dryRun: true });
82
+ const context = beginGovernanceSync(target, {
83
+ operation: `module unregister ${moduleKey}`,
84
+ dryRun,
85
+ allowDirtyWorktree: true,
86
+ allowedRelativePaths: governanceRelativePaths(planned.changes),
87
+ });
88
+ try {
89
+ const result = prepareModuleUnregister(target, moduleKey, { dryRun });
90
+ const commit = commitGovernanceSync(context, governanceRelativePaths(result.changes), { message: `chore(harness): unregister module ${result.moduleKey}` });
91
+ console.log(JSON.stringify({ ...result, governance: { commit } }, null, 2));
92
+ }
93
+ catch (error) {
94
+ console.error(errorMessage(error));
95
+ process.exit(1);
96
+ }
97
+ finally {
98
+ releaseGovernanceSync(context);
99
+ }
100
+ return;
101
+ }
102
+ if (subcommand === "scaffold") {
103
+ const dryRun = takeFlag("--dry-run");
104
+ const all = takeFlag("--all");
105
+ const locale = takeOption("--locale", "");
106
+ const moduleKey = all ? "" : args.shift();
107
+ if (!all && !moduleKey) {
108
+ console.error("Missing module key");
109
+ process.exit(2);
110
+ }
111
+ const target = normalizeTarget(targetArg());
112
+ const modules = readHarnessModules(target);
113
+ const keys = all ? Object.keys(modules.items || {}).sort() : [moduleKey || ""];
114
+ const plannedChanges = keys.flatMap((key) => prepareModuleScaffold(target, key, { dryRun: true, locale }).changes);
115
+ const context = beginGovernanceSync(target, {
116
+ operation: all ? "module scaffold --all" : `module scaffold ${moduleKey}`,
117
+ dryRun,
118
+ allowDirtyWorktree: true,
119
+ allowedRelativePaths: governanceRelativePaths(plannedChanges),
120
+ allowDirtyWriteScope: true,
121
+ });
122
+ try {
123
+ const results = keys.map((key) => prepareModuleScaffold(target, key, { dryRun, locale }));
124
+ const changes = results.flatMap((result) => result.changes);
125
+ const commit = commitGovernanceSync(context, governanceRelativePaths(changes), { message: all ? "chore(harness): scaffold registered modules" : `chore(harness): scaffold module ${moduleKey}` });
126
+ console.log(JSON.stringify({ modules: results, changes, governance: { commit } }, null, 2));
127
+ }
128
+ catch (error) {
129
+ console.error(errorMessage(error));
130
+ process.exit(1);
131
+ }
132
+ finally {
133
+ releaseGovernanceSync(context);
134
+ }
135
+ return;
136
+ }
137
+ console.error(`Unknown module subcommand: ${subcommand}`);
138
+ process.exit(2);
139
+ }
140
+ function errorMessage(error) {
141
+ return error instanceof Error ? error.message : String(error);
142
+ }
@@ -1,5 +1,7 @@
1
- // @ts-nocheck
2
- import { checkPresetPackage, inspectPresetPackage, installPresetPackage, listPresetPackages, seedBundledPresets, uninstallPresetPackage, } from "../lib/harness-core.mjs";
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { checkPresetPackage, inspectPresetPackage, installPresetPackage, auditBundledPresetDrift, listPresetPackages, seedBundledPresets, runPresetAction, runPresetEntrypoint, uninstallPresetPackage, } from "../lib/harness-core.mjs";
4
+ import { takeOptionFromArgs } from "../lib/command-registry.mjs";
3
5
  export function runPresetCommand({ args, takeFlag, targetArg }) {
4
6
  const subcommand = args.shift() || "list";
5
7
  const json = takeFlag("--json");
@@ -49,10 +51,11 @@ export function runPresetCommand({ args, takeFlag, targetArg }) {
49
51
  }
50
52
  else if (subcommand === "install") {
51
53
  const force = takeFlag("--force");
54
+ const allowScripts = takeFlag("--allow-scripts");
52
55
  const source = args.shift();
53
56
  if (!source)
54
57
  throw new Error("Missing preset source");
55
- const result = installPresetPackage(source, { force, scope: project ? "project" : "user", targetInput: targetArg() });
58
+ const result = installPresetPackage(source, { force, allowScripts, scope: project ? "project" : "user", targetInput: targetArg() });
56
59
  if (json)
57
60
  console.log(JSON.stringify(result, null, 2));
58
61
  else
@@ -70,6 +73,16 @@ export function runPresetCommand({ args, takeFlag, targetArg }) {
70
73
  console.log(`${preset.action}: ${preset.id}@${preset.version}`);
71
74
  }
72
75
  }
76
+ else if (subcommand === "audit") {
77
+ const result = auditBundledPresetDrift({ scope: project ? "project" : "user", targetInput: targetArg() });
78
+ if (json)
79
+ console.log(JSON.stringify(result, null, 2));
80
+ else {
81
+ console.log(`Preset audit ${result.scope}: ${result.stale} stale or missing bundled presets`);
82
+ for (const preset of result.presets)
83
+ console.log(`${preset.upgradeAction}: ${preset.id}@${preset.installedVersion || "missing"} [builtin ${preset.builtinVersion}]`);
84
+ }
85
+ }
73
86
  else if (subcommand === "uninstall") {
74
87
  const id = args.shift();
75
88
  if (!id)
@@ -80,12 +93,60 @@ export function runPresetCommand({ args, takeFlag, targetArg }) {
80
93
  else
81
94
  console.log(`${result.removed ? "Removed" : "Preset not installed"}: ${result.id}`);
82
95
  }
96
+ else if (subcommand === "run") {
97
+ const allowScripts = takeFlag("--allow-scripts");
98
+ const taskRef = takeOptionFromArgs(args, "--task", "");
99
+ const useCurrentPreset = takeFlag("--use-current-preset");
100
+ const reason = takeOptionFromArgs(args, "--reason", "");
101
+ const id = args.shift();
102
+ const entrypoint = args.shift();
103
+ if (!id)
104
+ throw new Error("Missing preset id");
105
+ if (!entrypoint)
106
+ throw new Error("Missing preset entrypoint");
107
+ const result = runPresetEntrypoint(id, entrypoint, { taskRef, targetInput: targetArg(), json, allowScripts, useCurrentPreset, reason });
108
+ if (json)
109
+ console.log(JSON.stringify(result, null, 2));
110
+ else
111
+ console.log(`Preset run ${result.status}: ${result.preset}.${result.entrypoint} (${result.materialized.length} writes)`);
112
+ }
113
+ else if (subcommand === "action") {
114
+ const allowScripts = takeFlag("--allow-scripts");
115
+ const useCurrentPreset = takeFlag("--use-current-preset");
116
+ const reason = takeOptionFromArgs(args, "--reason", "");
117
+ const taskRef = takeOptionFromArgs(args, "--task", "");
118
+ const id = args.shift();
119
+ const action = args.shift();
120
+ if (!id)
121
+ throw new Error("Missing preset id");
122
+ if (!action)
123
+ throw new Error("Missing preset action");
124
+ const target = takeTrailingActionTarget(args);
125
+ const result = runPresetAction(id, action, { taskRef, targetInput: target, json, allowScripts, useCurrentPreset, reason, actionArgs: args });
126
+ if (json)
127
+ console.log(JSON.stringify(result, null, 2));
128
+ else
129
+ console.log(`Preset action ${result.status}: ${result.preset}.${result.action} (${result.materialized.length} writes) [${result.source} ${String(result.manifestSha256 || "").slice(0, 12)}]`);
130
+ }
83
131
  else {
84
132
  throw new Error(`Unknown preset subcommand: ${subcommand}`);
85
133
  }
86
134
  }
87
135
  catch (error) {
88
- console.error(error.message);
136
+ console.error(errorMessage(error));
89
137
  process.exit(1);
90
138
  }
91
139
  }
140
+ function takeTrailingActionTarget(args) {
141
+ const candidate = args[args.length - 1] || "";
142
+ if (!candidate || candidate.startsWith("-"))
143
+ return ".";
144
+ if (candidate === "." || candidate.startsWith("~") || candidate.includes("/") || candidate.includes("\\") || fs.existsSync(path.resolve(candidate))) {
145
+ args.pop();
146
+ return candidate;
147
+ }
148
+ return ".";
149
+ }
150
+ function errorMessage(error) {
151
+ return error instanceof Error ? error.message : String(error);
152
+ }