coding-agent-harness 1.0.5 → 1.0.7

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 (260) hide show
  1. package/CONTRIBUTING.md +2 -2
  2. package/README.md +63 -3
  3. package/README.zh-CN.md +52 -3
  4. package/SKILL.md +43 -43
  5. package/dist/build-dist.mjs +189 -0
  6. package/dist/check-dist-observation.mjs +428 -0
  7. package/dist/check-harness.mjs +489 -0
  8. package/dist/check-import-graph.mjs +511 -0
  9. package/dist/check-runtime-emit.mjs +304 -0
  10. package/dist/check-type-boundaries.mjs +139 -0
  11. package/dist/commands/dashboard-command.mjs +80 -0
  12. package/dist/commands/migration-command.mjs +152 -0
  13. package/dist/commands/preset-command.mjs +91 -0
  14. package/dist/commands/task-command.mjs +324 -0
  15. package/dist/harness.mjs +304 -0
  16. package/dist/lib/capability-registry.mjs +643 -0
  17. package/dist/lib/check-module-parallel.mjs +227 -0
  18. package/dist/lib/check-profiles.mjs +414 -0
  19. package/dist/lib/check-task-contracts.mjs +54 -0
  20. package/dist/lib/core-shared.mjs +254 -0
  21. package/dist/lib/dashboard-data.mjs +608 -0
  22. package/dist/lib/dashboard-workbench.mjs +334 -0
  23. package/dist/lib/dashboard-writer.mjs +200 -0
  24. package/dist/lib/git-status-summary.mjs +45 -0
  25. package/dist/lib/governance-index-generator.mjs +236 -0
  26. package/dist/lib/governance-sync.mjs +617 -0
  27. package/dist/lib/governance-table-boundary.mjs +161 -0
  28. package/{scripts → dist}/lib/harness-core.mjs +2 -0
  29. package/dist/lib/harness-paths.mjs +338 -0
  30. package/dist/lib/lesson-maintenance.mjs +139 -0
  31. package/dist/lib/markdown-utils.mjs +193 -0
  32. package/dist/lib/migration-planner.mjs +439 -0
  33. package/dist/lib/migration-support.mjs +317 -0
  34. package/dist/lib/phase-kind.mjs +46 -0
  35. package/dist/lib/preset-audit-contracts.mjs +40 -0
  36. package/dist/lib/preset-engine.mjs +516 -0
  37. package/dist/lib/preset-registry.mjs +831 -0
  38. package/dist/lib/preset-resource-contracts.mjs +83 -0
  39. package/dist/lib/review-confirm-git-gate.mjs +244 -0
  40. package/dist/lib/status-builder.mjs +87 -0
  41. package/{scripts → dist}/lib/status-dashboard-renderer.mjs +44 -46
  42. package/dist/lib/structure-migration.mjs +404 -0
  43. package/dist/lib/subagent-authorization-audit.mjs +198 -0
  44. package/dist/lib/task-audit-metadata.mjs +376 -0
  45. package/dist/lib/task-audit-migration.mjs +355 -0
  46. package/dist/lib/task-completion-consistency.mjs +29 -0
  47. package/dist/lib/task-index.mjs +133 -0
  48. package/dist/lib/task-lesson-candidates.mjs +239 -0
  49. package/dist/lib/task-lesson-sedimentation.mjs +300 -0
  50. package/dist/lib/task-lifecycle/create-task-helpers.mjs +84 -0
  51. package/dist/lib/task-lifecycle/phase-sync.mjs +82 -0
  52. package/dist/lib/task-lifecycle/review-confirm.mjs +93 -0
  53. package/dist/lib/task-lifecycle/review-gates.mjs +62 -0
  54. package/dist/lib/task-lifecycle/review-submission.mjs +52 -0
  55. package/dist/lib/task-lifecycle/scaffold-provenance.mjs +54 -0
  56. package/dist/lib/task-lifecycle/template-files.mjs +52 -0
  57. package/dist/lib/task-lifecycle/text-utils.mjs +26 -0
  58. package/dist/lib/task-lifecycle.mjs +611 -0
  59. package/dist/lib/task-metadata.mjs +116 -0
  60. package/dist/lib/task-review-model.mjs +474 -0
  61. package/dist/lib/task-scanner.mjs +439 -0
  62. package/dist/lib/task-tombstone-commands.mjs +125 -0
  63. package/dist/postinstall.mjs +14 -0
  64. package/dist/run-built-tests.mjs +84 -0
  65. package/docs-release/README.md +1 -0
  66. package/docs-release/architecture/overview.md +12 -12
  67. package/docs-release/architecture/overview.zh-CN.md +12 -12
  68. package/docs-release/architecture/system-explainer/01-system-overview.md +15 -14
  69. package/docs-release/architecture/system-explainer/02-module-dependency.md +8 -8
  70. package/docs-release/architecture/system-explainer/03-task-lifecycle.md +3 -3
  71. package/docs-release/architecture/system-explainer/04-check-and-governance.md +9 -7
  72. package/docs-release/architecture/system-explainer/05-data-flow.md +5 -5
  73. package/docs-release/architecture/system-explainer/06-preset-and-migration.md +1 -4
  74. package/docs-release/architecture/system-explainer/en-US/01-system-overview.md +15 -14
  75. package/docs-release/architecture/system-explainer/en-US/02-module-dependency.md +8 -8
  76. package/docs-release/architecture/system-explainer/en-US/03-task-lifecycle.md +3 -3
  77. package/docs-release/architecture/system-explainer/en-US/04-check-and-governance.md +10 -8
  78. package/docs-release/architecture/system-explainer/en-US/05-data-flow.md +5 -5
  79. package/docs-release/architecture/system-explainer/en-US/06-preset-and-migration.md +1 -4
  80. package/docs-release/guides/agent-installation.en-US.md +14 -8
  81. package/docs-release/guides/agent-installation.md +14 -8
  82. package/docs-release/guides/contributing.md +3 -3
  83. package/docs-release/guides/contributing.zh-CN.md +3 -3
  84. package/docs-release/guides/document-audience-and-surfaces.en-US.md +10 -10
  85. package/docs-release/guides/document-audience-and-surfaces.md +10 -10
  86. package/docs-release/guides/legacy-migration-agent-prompt.md +25 -2
  87. package/docs-release/guides/legacy-migration-agent-prompt.zh-CN.md +25 -2
  88. package/docs-release/guides/migration-playbook.en-US.md +63 -1
  89. package/docs-release/guides/migration-playbook.md +59 -1
  90. package/docs-release/guides/parent-control-repository-pattern.en-US.md +25 -25
  91. package/docs-release/guides/parent-control-repository-pattern.md +25 -25
  92. package/docs-release/guides/preset-development.md +2 -2
  93. package/docs-release/guides/repository-operating-models.en-US.md +21 -21
  94. package/docs-release/guides/repository-operating-models.md +21 -21
  95. package/docs-release/guides/task-state-machine.en-US.md +5 -5
  96. package/docs-release/guides/task-state-machine.md +5 -5
  97. package/docs-release/guides/typescript-runtime-migration-closeout.md +96 -0
  98. package/examples/minimal-project/AGENTS.md +2 -2
  99. package/examples/minimal-project/coding-agent-harness/harness.yaml +14 -0
  100. package/examples/minimal-project/coding-agent-harness/planning/tasks/demo-task/progress.md +11 -0
  101. package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/review.md +1 -1
  102. package/package.json +20 -12
  103. package/presets/legacy-migration/preset.yaml +5 -5
  104. package/presets/legacy-migration/templates/execution_strategy.append.md +1 -1
  105. package/presets/lesson-sedimentation/preset.yaml +3 -3
  106. package/presets/module/preset.yaml +2 -2
  107. package/presets/module/templates/execution_strategy.append.md +1 -1
  108. package/presets/module/templates/task_plan.append.md +3 -3
  109. package/presets/standard-task/preset.yaml +2 -2
  110. package/references/adversarial-review-standard.md +2 -2
  111. package/references/agents-md-pattern.md +14 -14
  112. package/references/cadence-ledger.md +1 -1
  113. package/references/ci-cd-standard.md +1 -1
  114. package/references/delivery-operating-model-standard.md +4 -4
  115. package/references/docs-directory-standard.md +65 -159
  116. package/references/external-source-intake-standard.md +10 -10
  117. package/references/harness-ledger.md +5 -5
  118. package/references/legacy-12-phase-bootstrap.md +2 -2
  119. package/references/lessons-governance.md +15 -15
  120. package/references/long-running-task-standard.md +6 -6
  121. package/references/module-parallel-standard.md +34 -34
  122. package/references/planning-loop.md +6 -6
  123. package/references/project-onboarding-audit.md +4 -4
  124. package/references/regression-system.md +2 -2
  125. package/references/repo-governance-standard.md +4 -4
  126. package/references/review-routing-standard.md +1 -1
  127. package/references/ssot-governance.md +19 -19
  128. package/references/taskr-gap-analysis.md +5 -5
  129. package/references/walkthrough-closeout.md +14 -14
  130. package/references/worktree-parallel.md +3 -3
  131. package/skills/preset-creator/references/complex-task-skeleton/task_plan.md +1 -1
  132. package/skills/preset-creator/references/preset-package-skeleton.md +5 -5
  133. package/templates/AGENTS.md.template +26 -26
  134. package/templates/architecture/README.md +4 -4
  135. package/templates/architecture/service-catalog.md +2 -2
  136. package/templates/architecture/services/service-template.md +1 -1
  137. package/templates/dashboard/assets/app-src/20-overview.js +11 -5
  138. package/templates/dashboard/assets/app-src/40-modules.js +1 -1
  139. package/templates/dashboard/assets/app.js +12 -6
  140. package/templates/dashboard/assets/i18n.js +4 -2
  141. package/templates/development/README.md +10 -10
  142. package/templates/development/cross-repo-debugging.md +3 -3
  143. package/templates/development/external-context/service-template.md +2 -2
  144. package/templates/development/external-source-packs/README.md +4 -4
  145. package/templates/integrations/README.md +4 -4
  146. package/templates/integrations/api-contract.md +2 -2
  147. package/templates/integrations/event-contract.md +2 -2
  148. package/templates/integrations/third-party/vendor-template.md +2 -2
  149. package/templates/integrations/webhook-contract.md +2 -2
  150. package/templates/ledger/Harness-Ledger.md +1 -1
  151. package/templates/planning/INDEX.md +1 -0
  152. package/templates/planning/module_session_prompt.md +1 -1
  153. package/templates/planning/task_plan.md +1 -1
  154. package/templates/planning/walkthrough.md +47 -0
  155. package/templates/reference/docs-library-standard.md +8 -8
  156. package/templates/reference/external-source-intake-standard.md +15 -15
  157. package/templates/reference/repo-governance-standard.md +1 -1
  158. package/templates/ssot/Module-Registry.md +1 -1
  159. package/templates/walkthrough/walkthrough-template.md +2 -2
  160. package/templates-zh-CN/AGENTS.md.template +26 -26
  161. package/templates-zh-CN/CLAUDE.md.template +1 -1
  162. package/templates-zh-CN/architecture/README.md +4 -4
  163. package/templates-zh-CN/architecture/service-catalog.md +2 -2
  164. package/templates-zh-CN/architecture/services/service-template.md +1 -1
  165. package/templates-zh-CN/development/README.md +10 -10
  166. package/templates-zh-CN/development/cross-repo-debugging.md +3 -3
  167. package/templates-zh-CN/development/external-context/service-template.md +2 -2
  168. package/templates-zh-CN/development/external-source-packs/README.md +4 -4
  169. package/templates-zh-CN/integrations/README.md +4 -4
  170. package/templates-zh-CN/integrations/api-contract.md +2 -2
  171. package/templates-zh-CN/integrations/event-contract.md +2 -2
  172. package/templates-zh-CN/integrations/third-party/vendor-template.md +2 -2
  173. package/templates-zh-CN/integrations/webhook-contract.md +2 -2
  174. package/templates-zh-CN/ledger/Harness-Ledger.md +1 -1
  175. package/templates-zh-CN/lessons/lesson-arch-process-change.md +1 -1
  176. package/templates-zh-CN/lessons/lesson-new-doc.md +3 -3
  177. package/templates-zh-CN/lessons/lesson-ref-change.md +4 -4
  178. package/templates-zh-CN/planning/module_session_prompt.md +11 -11
  179. package/templates-zh-CN/planning/walkthrough.md +47 -0
  180. package/templates-zh-CN/reference/adversarial-review-standard.md +2 -2
  181. package/templates-zh-CN/reference/delivery-operating-model-standard.md +3 -3
  182. package/templates-zh-CN/reference/docs-library-standard.md +28 -28
  183. package/templates-zh-CN/reference/execution-workflow-standard.md +1 -1
  184. package/templates-zh-CN/reference/external-source-intake-standard.md +16 -16
  185. package/templates-zh-CN/reference/harness-ledger-standard.md +6 -6
  186. package/templates-zh-CN/reference/regression-ssot-governance.md +2 -2
  187. package/templates-zh-CN/reference/repo-governance-standard.md +1 -1
  188. package/templates-zh-CN/reference/review-routing-standard.md +1 -1
  189. package/templates-zh-CN/reference/walkthrough-standard.md +7 -7
  190. package/templates-zh-CN/reference/worktree-standard.md +1 -1
  191. package/templates-zh-CN/regression/Cadence-Ledger.md +2 -2
  192. package/templates-zh-CN/ssot/Delivery-SSoT.md +3 -3
  193. package/templates-zh-CN/ssot/Module-Registry.md +3 -3
  194. package/templates-zh-CN/ssot/Regression-SSoT.md +2 -2
  195. package/templates-zh-CN/walkthrough/walkthrough-template.md +5 -5
  196. package/tsconfig.dist.json +16 -0
  197. package/tsconfig.json +25 -0
  198. package/tsconfig.runtime.json +24 -0
  199. package/examples/minimal-project/.harness-capabilities.json +0 -8
  200. package/examples/minimal-project/docs/09-PLANNING/TASKS/demo-task/progress.md +0 -11
  201. package/scripts/check-harness.mjs +0 -508
  202. package/scripts/commands/dashboard-command.mjs +0 -67
  203. package/scripts/commands/migration-command.mjs +0 -126
  204. package/scripts/commands/preset-command.mjs +0 -73
  205. package/scripts/commands/task-command.mjs +0 -328
  206. package/scripts/harness.mjs +0 -291
  207. package/scripts/lib/capability-registry.mjs +0 -587
  208. package/scripts/lib/check-module-parallel.mjs +0 -230
  209. package/scripts/lib/check-profiles.mjs +0 -372
  210. package/scripts/lib/check-task-contracts.mjs +0 -55
  211. package/scripts/lib/core-shared.mjs +0 -249
  212. package/scripts/lib/dashboard-data.mjs +0 -520
  213. package/scripts/lib/dashboard-workbench.mjs +0 -336
  214. package/scripts/lib/dashboard-writer.mjs +0 -202
  215. package/scripts/lib/git-status-summary.mjs +0 -46
  216. package/scripts/lib/governance-index-generator.mjs +0 -174
  217. package/scripts/lib/governance-sync.mjs +0 -611
  218. package/scripts/lib/governance-table-boundary.mjs +0 -175
  219. package/scripts/lib/lesson-maintenance.mjs +0 -152
  220. package/scripts/lib/markdown-utils.mjs +0 -191
  221. package/scripts/lib/migration-planner.mjs +0 -476
  222. package/scripts/lib/migration-support.mjs +0 -312
  223. package/scripts/lib/phase-kind.mjs +0 -50
  224. package/scripts/lib/preset-audit-contracts.mjs +0 -37
  225. package/scripts/lib/preset-engine.mjs +0 -494
  226. package/scripts/lib/preset-registry.mjs +0 -776
  227. package/scripts/lib/preset-resource-contracts.mjs +0 -83
  228. package/scripts/lib/review-confirm-git-gate.mjs +0 -248
  229. package/scripts/lib/status-builder.mjs +0 -88
  230. package/scripts/lib/subagent-authorization-audit.mjs +0 -196
  231. package/scripts/lib/task-audit-metadata.mjs +0 -385
  232. package/scripts/lib/task-audit-migration.mjs +0 -350
  233. package/scripts/lib/task-completion-consistency.mjs +0 -26
  234. package/scripts/lib/task-index.mjs +0 -93
  235. package/scripts/lib/task-lesson-candidates.mjs +0 -242
  236. package/scripts/lib/task-lesson-sedimentation.mjs +0 -326
  237. package/scripts/lib/task-lifecycle/create-task-helpers.mjs +0 -67
  238. package/scripts/lib/task-lifecycle/phase-sync.mjs +0 -88
  239. package/scripts/lib/task-lifecycle/review-confirm.mjs +0 -112
  240. package/scripts/lib/task-lifecycle/review-gates.mjs +0 -73
  241. package/scripts/lib/task-lifecycle/review-submission.mjs +0 -63
  242. package/scripts/lib/task-lifecycle/scaffold-provenance.mjs +0 -49
  243. package/scripts/lib/task-lifecycle/template-files.mjs +0 -53
  244. package/scripts/lib/task-lifecycle/text-utils.mjs +0 -24
  245. package/scripts/lib/task-lifecycle.mjs +0 -616
  246. package/scripts/lib/task-metadata.mjs +0 -118
  247. package/scripts/lib/task-review-model.mjs +0 -455
  248. package/scripts/lib/task-scanner.mjs +0 -503
  249. package/scripts/lib/task-tombstone-commands.mjs +0 -140
  250. package/scripts/postinstall.mjs +0 -14
  251. package/templates/walkthrough/Closeout-SSoT.md +0 -43
  252. package/templates-zh-CN/walkthrough/Closeout-SSoT.md +0 -42
  253. /package/examples/minimal-project/{docs → coding-agent-harness/governance/generated}/Harness-Ledger.md +0 -0
  254. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/INDEX.md +0 -0
  255. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/brief.md +0 -0
  256. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/execution_strategy.md +0 -0
  257. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/findings.md +0 -0
  258. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/lesson_candidates.md +0 -0
  259. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/task_plan.md +0 -0
  260. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/visual_map.md +0 -0
@@ -1,67 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import {
4
- serveDashboardWorkbench,
5
- writeDashboardFolder,
6
- writeDashboardSingleFile,
7
- } from "../lib/harness-core.mjs";
8
-
9
- export async function runDashboardCommand({ takeFlag, takeOption, targetArg }) {
10
- const watch = takeFlag("--watch");
11
- const workbench = takeFlag("--workbench");
12
- const out = takeOption("--out", path.join("tmp", "harness-dashboard.html"));
13
- const outDir = takeOption("--out-dir", "");
14
- const host = takeOption("--host", "127.0.0.1");
15
- const port = takeOption("--port", "0");
16
- const localeOverride = takeOption("--locale", "");
17
- const opts = localeOverride ? { localeOverride } : {};
18
- if (workbench) {
19
- if (!outDir) {
20
- console.error("dashboard --workbench requires --out-dir so regenerated data has a stable folder");
21
- process.exit(2);
22
- }
23
- try {
24
- await serveDashboardWorkbench(outDir, targetArg(), { ...opts, host, port });
25
- } catch (error) {
26
- console.error(error.message);
27
- process.exit(1);
28
- }
29
- }
30
- if (watch) {
31
- if (!outDir) {
32
- console.error("dashboard --watch requires --out-dir so updates are written to a stable folder");
33
- process.exit(2);
34
- }
35
- const target = targetArg();
36
- const docsRoot = path.basename(path.resolve(target)) === "docs" ? path.resolve(target) : path.join(path.resolve(target), "docs");
37
- const regenerate = () => {
38
- try {
39
- console.log(writeDashboardFolder(outDir, target, opts));
40
- console.log(`dashboard regenerated: ${new Date().toISOString()}`);
41
- } catch (error) {
42
- console.error(`dashboard regeneration failed: ${error.message}`);
43
- }
44
- };
45
- regenerate();
46
- let timer = null;
47
- const watcher = fs.watch(docsRoot, { recursive: true }, () => {
48
- clearTimeout(timer);
49
- timer = setTimeout(regenerate, 300);
50
- });
51
- const close = () => {
52
- watcher.close();
53
- clearTimeout(timer);
54
- process.exit(0);
55
- };
56
- process.on("SIGINT", close);
57
- process.on("SIGTERM", close);
58
- console.log(`watching ${docsRoot}`);
59
- await new Promise(() => {});
60
- }
61
- if (outDir) {
62
- console.log(writeDashboardFolder(outDir, targetArg(), opts));
63
- } else {
64
- console.log(writeDashboardSingleFile(out, targetArg(), opts));
65
- }
66
- process.exit(0);
67
- }
@@ -1,126 +0,0 @@
1
- import {
2
- buildMigrationPlan,
3
- runMigration,
4
- verifyMigrationSession,
5
- } from "../lib/harness-core.mjs";
6
- import {
7
- applyTaskAuditIndexMigration,
8
- planTaskAuditIndexMigration,
9
- } from "../lib/task-audit-migration.mjs";
10
-
11
- export function runMigrationCommand(command, { args, takeFlag, takeOption, targetArg }) {
12
- if (command === "migrate-task-audit-index") {
13
- const json = takeFlag("--json");
14
- const apply = takeFlag("--apply");
15
- const planOnly = takeFlag("--plan");
16
- try {
17
- const result = apply && !planOnly
18
- ? applyTaskAuditIndexMigration(targetArg())
19
- : planTaskAuditIndexMigration(targetArg());
20
- if (json) {
21
- console.log(JSON.stringify(result, null, 2));
22
- } else {
23
- console.log(`Task audit INDEX migration ${result.result}: ${result.target}`);
24
- console.log(`actions: ${result.summary.actions}`);
25
- console.log(`legacy audit blocks: ${result.summary.legacyAuditBlocks}`);
26
- console.log(`failures: ${result.summary.failures}`);
27
- for (const action of result.actions || []) console.log(`- ${action.taskId}: ${action.legacyBlocks.join(", ")}`);
28
- for (const failure of result.failures || []) console.error(`Failure: ${failure.taskId}: ${failure.failure}`);
29
- }
30
- process.exit(result.failures?.length ? 1 : 0);
31
- } catch (error) {
32
- if (json && error.plan) console.error(JSON.stringify(error.plan, null, 2));
33
- else console.error(error.message);
34
- process.exit(1);
35
- }
36
- }
37
-
38
- if (command === "migrate-plan") {
39
- const json = takeFlag("--json");
40
- const limit = Number.parseInt(takeOption("--limit", "20"), 10) || 20;
41
- try {
42
- const plan = buildMigrationPlan(targetArg(), { limit });
43
- if (json) {
44
- console.log(JSON.stringify(plan, null, 2));
45
- } else {
46
- console.log(`Migration Plan: ${plan.target}`);
47
- console.log(`mode: ${plan.mode}`);
48
- console.log(`warnings: ${plan.summary.warnings}`);
49
- console.log(`task actions: ${plan.summary.taskActions}`);
50
- console.log(`visual map actions: ${plan.summary.visualMapActions}`);
51
- console.log(`legacy visual-only tasks: ${plan.summary.legacyVisualOnly}`);
52
- console.log(`weak briefs: ${plan.summary.weakBrief}`);
53
- console.log(`unknown classifications: ${plan.summary.unknownClassification}`);
54
- console.log(`full cutover eligible: ${plan.summary.fullCutoverEligible ? "yes" : "no"}`);
55
- console.log(`review actions: ${plan.summary.reviewSchemaGaps}`);
56
- console.log(`legacy actions: ${plan.summary.legacyReferenceGaps}`);
57
- console.log(`legacy residuals: ${plan.summary.legacyResiduals}`);
58
- console.log(`recommended capabilities: ${plan.summary.recommendedCapabilities.join(", ") || "none"}`);
59
- console.log("\nPhases:");
60
- for (const phase of plan.phases) console.log(`- ${phase.id}: ${phase.title}`);
61
- console.log("\nTop task actions:");
62
- for (const action of plan.taskActions) console.log(`- ${action.taskId}: add ${action.files.join(", ")}`);
63
- console.log("\nTop review actions:");
64
- for (const action of plan.reviewActions) console.log(`- ${action.path}: add ${action.missing.join(", ")}`);
65
- console.log("\nTop legacy residuals:");
66
- for (const action of plan.legacyResiduals) console.log(`- ${action.taskId}: ${action.missing} (${action.reason})`);
67
- console.log("\nNext commands:");
68
- for (const next of plan.nextCommands) console.log(`- ${next}`);
69
- }
70
- } catch (error) {
71
- console.error(error.message);
72
- process.exit(1);
73
- }
74
- return;
75
- }
76
-
77
- if (command === "migrate-run") {
78
- const locale = takeOption("--locale", "");
79
- const assumeLocale = takeFlag("--assume-locale");
80
- const allowDirty = takeFlag("--allow-dirty");
81
- const planOnly = takeFlag("--plan-only");
82
- const outDir = takeOption("--out-dir", "");
83
- const sessionDir = takeOption("--session-dir", "");
84
- try {
85
- console.log(
86
- JSON.stringify(
87
- runMigration(targetArg(), {
88
- locale,
89
- assumeLocale,
90
- allowDirty,
91
- planOnly,
92
- outDir,
93
- sessionDir,
94
- }),
95
- null,
96
- 2,
97
- ),
98
- );
99
- } catch (error) {
100
- console.error(error.message);
101
- process.exit(1);
102
- }
103
- return;
104
- }
105
-
106
- if (command === "migrate-verify") {
107
- const json = takeFlag("--json");
108
- const fullCutover = takeFlag("--full-cutover");
109
- const sessionPath = args.shift();
110
- if (!sessionPath) {
111
- console.error("Missing session.json path");
112
- process.exit(2);
113
- }
114
- const result = verifyMigrationSession(sessionPath, { fullCutover });
115
- if (json) {
116
- console.log(JSON.stringify(result, null, 2));
117
- } else {
118
- for (const failure of result.failures) console.error(`Failure: ${failure}`);
119
- for (const warning of result.warnings) console.log(`Warning: ${warning}`);
120
- console.log(`Migration verify ${result.status}: ${result.sessionPath}`);
121
- }
122
- process.exit(result.status === "pass" ? 0 : 1);
123
- }
124
-
125
- throw new Error(`Unsupported migration command: ${command}`);
126
- }
@@ -1,73 +0,0 @@
1
- import {
2
- checkPresetPackage,
3
- inspectPresetPackage,
4
- installPresetPackage,
5
- listPresetPackages,
6
- seedBundledPresets,
7
- uninstallPresetPackage,
8
- } from "../lib/harness-core.mjs";
9
-
10
- export function runPresetCommand({ args, takeFlag, targetArg }) {
11
- const subcommand = args.shift() || "list";
12
- const json = takeFlag("--json");
13
- const project = takeFlag("--project");
14
- try {
15
- if (subcommand === "list") {
16
- const target = targetArg();
17
- const presets = listPresetPackages({ targetInput: target }).map((preset) => ({
18
- id: preset.id,
19
- version: preset.version,
20
- purpose: preset.purpose,
21
- compatibleBudgets: preset.compatibleBudgets,
22
- source: preset.source,
23
- manifestPath: preset.manifestRelativePath,
24
- }));
25
- if (json) console.log(JSON.stringify({ presets }, null, 2));
26
- else for (const preset of presets) console.log(`${preset.id}@${preset.version} [${preset.source}] ${preset.compatibleBudgets.join(",")} - ${preset.purpose}`);
27
- } else if (subcommand === "inspect") {
28
- const id = args.shift();
29
- if (!id) throw new Error("Missing preset id");
30
- const preset = inspectPresetPackage(id, { targetInput: targetArg() });
31
- if (json) console.log(JSON.stringify(preset, null, 2));
32
- else console.log(`${preset.id}@${preset.version}\n${preset.purpose}`);
33
- } else if (subcommand === "check") {
34
- const id = args.shift();
35
- if (!id) throw new Error("Missing preset id");
36
- const report = checkPresetPackage(id, { targetInput: targetArg() });
37
- if (json) console.log(JSON.stringify(report, null, 2));
38
- else {
39
- for (const failure of report.failures) console.error(`Failure: ${failure}`);
40
- for (const warning of report.warnings) console.log(`Warning: ${warning}`);
41
- console.log(`Preset check ${report.status}: ${report.id}@${report.version}`);
42
- }
43
- process.exit(report.status === "pass" ? 0 : 1);
44
- } else if (subcommand === "install") {
45
- const force = takeFlag("--force");
46
- const source = args.shift();
47
- if (!source) throw new Error("Missing preset source");
48
- const result = installPresetPackage(source, { force, scope: project ? "project" : "user", targetInput: targetArg() });
49
- if (json) console.log(JSON.stringify(result, null, 2));
50
- else console.log(`Installed preset ${result.id}@${result.version} to ${result.destination}`);
51
- } else if (subcommand === "seed") {
52
- const force = takeFlag("--force");
53
- const dryRun = takeFlag("--dry-run");
54
- const result = seedBundledPresets({ force, dryRun, scope: project ? "project" : "user", targetInput: targetArg() });
55
- if (json) console.log(JSON.stringify(result, null, 2));
56
- else {
57
- console.log(`Seeded bundled presets to ${result.target}`);
58
- for (const preset of result.presets) console.log(`${preset.action}: ${preset.id}@${preset.version}`);
59
- }
60
- } else if (subcommand === "uninstall") {
61
- const id = args.shift();
62
- if (!id) throw new Error("Missing preset id");
63
- const result = uninstallPresetPackage(id, { scope: project ? "project" : "user", targetInput: targetArg() });
64
- if (json) console.log(JSON.stringify(result, null, 2));
65
- else console.log(`${result.removed ? "Removed" : "Preset not installed"}: ${result.id}`);
66
- } else {
67
- throw new Error(`Unknown preset subcommand: ${subcommand}`);
68
- }
69
- } catch (error) {
70
- console.error(error.message);
71
- process.exit(1);
72
- }
73
- }
@@ -1,328 +0,0 @@
1
- import {
2
- confirmTaskReview,
3
- createTask,
4
- readPresetPackage,
5
- buildTaskIndex,
6
- createLessonSedimentationTask,
7
- archiveTask,
8
- listLifecycleTasks,
9
- promoteLessonCandidate,
10
- reopenTask,
11
- softDeleteTask,
12
- supersedeTask,
13
- updateModuleStep,
14
- updateTaskPhase,
15
- updateTaskLifecycle,
16
- } from "../lib/harness-core.mjs";
17
-
18
- export function runTaskCommand(command, { args, takeFlag, takeOption, targetArg }) {
19
- if (command === "new-task") {
20
- const dryRun = takeFlag("--dry-run");
21
- const locale = takeOption("--locale", "");
22
- const title = takeOption("--title", "");
23
- const moduleKey = takeOption("--module", "");
24
- const budget = takeOption("--budget", "standard");
25
- const preset = takeOption("--preset", "");
26
- const fromSession = takeOption("--from-session", "");
27
- const longRunning = takeFlag("--long-running");
28
- try {
29
- const parsed = parseNewTaskArgs(args, { preset, fromSession });
30
- console.log(JSON.stringify(createTask(parsed.target, parsed.taskId, { title, locale, dryRun, moduleKey, budget, longRunning, preset, fromSession, presetArgs: parsed.presetArgs, automaticTaskId: parsed.automaticTaskId }), null, 2));
31
- } catch (error) {
32
- console.error(error.message);
33
- process.exit(1);
34
- }
35
- return;
36
- }
37
-
38
- if (command === "task-phase") {
39
- const state = takeOption("--state", "");
40
- const completion = takeOption("--completion", "");
41
- const evidenceStatus = takeOption("--evidence", "");
42
- const taskId = args.shift();
43
- const phaseId = args.shift();
44
- if (!taskId || !phaseId) {
45
- console.error("Missing task id or phase id");
46
- process.exit(2);
47
- }
48
- try {
49
- console.log(JSON.stringify(updateTaskPhase(targetArg(), taskId, phaseId, { state, completion, evidenceStatus }), null, 2));
50
- } catch (error) {
51
- console.error(error.message);
52
- process.exit(1);
53
- }
54
- return;
55
- }
56
-
57
- if (["task-start", "task-log", "task-block", "task-review", "task-complete"].includes(command)) {
58
- const message = takeOption("--message", "");
59
- const evidence = takeOption("--evidence", "");
60
- const taskId = args.shift();
61
- if (!taskId) {
62
- console.error("Missing task id");
63
- process.exit(2);
64
- }
65
- const lifecycle = {
66
- "task-start": { event: "task-start", state: "in_progress" },
67
- "task-log": { event: "task-log", state: "" },
68
- "task-block": { event: "task-block", state: "blocked" },
69
- "task-review": { event: "task-review", state: "review" },
70
- "task-complete": { event: "task-complete", state: "done" },
71
- }[command];
72
- try {
73
- console.log(JSON.stringify(updateTaskLifecycle(targetArg(), taskId, { ...lifecycle, message, evidence }), null, 2));
74
- } catch (error) {
75
- console.error(error.message);
76
- process.exit(1);
77
- }
78
- return;
79
- }
80
-
81
- if (command === "review-confirm") {
82
- const reviewer = takeOption("--reviewer", "Human Reviewer");
83
- const message = takeOption("--message", "");
84
- const evidence = takeOption("--evidence", "");
85
- const confirmText = takeOption("--confirm", "");
86
- const taskId = args.shift();
87
- if (!taskId) {
88
- console.error("Missing task id");
89
- process.exit(2);
90
- }
91
- try {
92
- console.log(JSON.stringify(confirmTaskReview(targetArg(), taskId, { reviewer, message, evidence, confirmText }), null, 2));
93
- } catch (error) {
94
- console.error(formatTaskCommandError(error));
95
- process.exit(1);
96
- }
97
- return;
98
- }
99
-
100
- if (command === "lesson-promote") {
101
- const dryRun = takeFlag("--dry-run");
102
- const apply = takeFlag("--apply");
103
- const taskId = args.shift();
104
- const candidateId = args.shift();
105
- if (!taskId || !candidateId) {
106
- console.error("Missing task id or candidate id");
107
- process.exit(2);
108
- }
109
- try {
110
- console.log(JSON.stringify(promoteLessonCandidate(targetArg(), taskId, candidateId, { dryRun, apply }), null, 2));
111
- } catch (error) {
112
- console.error(error.message);
113
- process.exit(1);
114
- }
115
- return;
116
- }
117
-
118
- if (command === "lesson-sediment") {
119
- const dryRun = takeFlag("--dry-run");
120
- const title = takeOption("--title", "");
121
- const taskId = args.shift();
122
- const candidateId = args.shift();
123
- if (!taskId || !candidateId) {
124
- console.error("Missing task id or candidate id");
125
- process.exit(2);
126
- }
127
- try {
128
- console.log(JSON.stringify(createLessonSedimentationTask(targetArg(), taskId, candidateId, { dryRun, title }), null, 2));
129
- } catch (error) {
130
- console.error(error.message);
131
- process.exit(1);
132
- }
133
- return;
134
- }
135
-
136
- if (command === "task-list") {
137
- const json = takeFlag("--json");
138
- const state = takeOption("--state", "");
139
- const moduleKey = takeOption("--module", "");
140
- const queue = takeOption("--queue", "");
141
- const preset = takeOption("--preset", "");
142
- const review = takeOption("--review", "");
143
- const lesson = takeOption("--lesson", "");
144
- const search = takeOption("--search", "");
145
- const missingMaterials = takeFlag("--missing-materials");
146
- const result = listLifecycleTasks(targetArg(), { state, moduleKey, queue, preset, review, lesson, search, missingMaterials });
147
- if (json) {
148
- console.log(JSON.stringify(result, null, 2));
149
- } else {
150
- for (const task of result.tasks) {
151
- console.log(`${task.id}\t${task.state}\t${task.completion}%\t${task.title}`);
152
- }
153
- }
154
- return;
155
- }
156
-
157
- if (command === "task-index") {
158
- const json = takeFlag("--json");
159
- const result = buildTaskIndex(targetArg());
160
- if (json) console.log(JSON.stringify(result, null, 2));
161
- else console.log(`${result.tasks.length} tasks indexed (${result.schemaVersion})`);
162
- return;
163
- }
164
-
165
- if (command === "task-supersede") {
166
- const by = takeOption("--by", "");
167
- const reason = takeOption("--reason", "");
168
- const taskId = args.shift();
169
- if (!taskId) {
170
- console.error("Missing task id");
171
- process.exit(2);
172
- }
173
- try {
174
- console.log(JSON.stringify(supersedeTask(targetArg(), taskId, { by, reason }), null, 2));
175
- } catch (error) {
176
- console.error(error.message);
177
- process.exit(1);
178
- }
179
- return;
180
- }
181
-
182
- if (["task-delete", "task-archive", "task-reopen"].includes(command)) {
183
- const soft = takeFlag("--soft");
184
- const reason = takeOption("--reason", "");
185
- const taskId = args.shift();
186
- if (!taskId) {
187
- console.error("Missing task id");
188
- process.exit(2);
189
- }
190
- try {
191
- if (command === "task-delete" && !soft) throw new Error("task-delete only supports --soft; hard delete is intentionally disabled.");
192
- const result =
193
- command === "task-delete"
194
- ? softDeleteTask(targetArg(), taskId, { reason })
195
- : command === "task-archive"
196
- ? archiveTask(targetArg(), taskId, { reason })
197
- : reopenTask(targetArg(), taskId, { reason });
198
- console.log(JSON.stringify(result, null, 2));
199
- } catch (error) {
200
- console.error(error.message);
201
- process.exit(1);
202
- }
203
- return;
204
- }
205
-
206
- if (command === "module-step") {
207
- const state = takeOption("--state", "done");
208
- const moduleKey = args.shift();
209
- const stepId = args.shift();
210
- if (!moduleKey || !stepId) {
211
- console.error("Missing module key or step id");
212
- process.exit(2);
213
- }
214
- try {
215
- console.log(JSON.stringify(updateModuleStep(targetArg(), moduleKey, stepId, { state }), null, 2));
216
- } catch (error) {
217
- console.error(error.message);
218
- process.exit(1);
219
- }
220
- return;
221
- }
222
-
223
- throw new Error(`Unsupported task command: ${command}`);
224
- }
225
-
226
- function parseNewTaskArgs(args, { preset = "" } = {}) {
227
- const values = [...args];
228
- const presetPackage = preset ? readPresetPackageForNewTask(preset, values) : null;
229
- const parsed = splitPresetArgsAndPositionals(values, presetPackage);
230
- const resolved = resolveNewTaskPositionals(parsed.positionals);
231
- return {
232
- taskId: resolved.taskId,
233
- target: resolved.target || ".",
234
- automaticTaskId: !resolved.taskId,
235
- presetArgs: parsed.presetArgs,
236
- };
237
- }
238
-
239
- function readPresetPackageForNewTask(preset, values) {
240
- const candidates = presetDiscoveryTargetCandidates(values);
241
- let fallbackPackage = null;
242
- let lastError = null;
243
- for (const targetInput of candidates) {
244
- try {
245
- const presetPackage = readPresetPackage(preset, { targetInput });
246
- if (presetPackage.source === "project") return presetPackage;
247
- if (!fallbackPackage) fallbackPackage = presetPackage;
248
- } catch (error) {
249
- lastError = error;
250
- }
251
- }
252
- if (fallbackPackage) return fallbackPackage;
253
- throw lastError;
254
- }
255
-
256
- function presetDiscoveryTargetCandidates(values) {
257
- const candidates = [];
258
- for (let index = values.length - 1; index >= 0; index -= 1) {
259
- const value = values[index];
260
- if (!value || value.startsWith("-")) continue;
261
- if (!candidates.includes(value)) candidates.push(value);
262
- }
263
- if (!candidates.includes(".")) candidates.push(".");
264
- return candidates;
265
- }
266
-
267
- function splitPresetArgsAndPositionals(values, presetPackage) {
268
- const presetArgs = [];
269
- const positionals = [];
270
- const declaredFlags = new Map(Object.values(presetPackage?.inputs || {}).filter((input) => input.flag).map((input) => [input.flag, input]));
271
- for (let index = 0; index < values.length; index += 1) {
272
- const value = values[index];
273
- const declared = declaredFlags.get(value);
274
- if (declared) {
275
- presetArgs.push(value);
276
- if (declared.type !== "flag" && index + 1 < values.length) {
277
- presetArgs.push(values[index + 1]);
278
- index += 1;
279
- }
280
- } else if (value.startsWith("-")) {
281
- presetArgs.push(value);
282
- if (index + 1 < values.length && !values[index + 1].startsWith("-")) {
283
- presetArgs.push(values[index + 1]);
284
- index += 1;
285
- }
286
- } else {
287
- positionals.push(value);
288
- }
289
- }
290
- return {
291
- positionals,
292
- presetArgs,
293
- };
294
- }
295
-
296
- function isPathLikePositional(value) {
297
- return value === "." || value === ".." || value.startsWith("/") || value.startsWith("~/") || value.includes("/") || value.includes("\\");
298
- }
299
-
300
- function resolveNewTaskPositionals(positionals) {
301
- if (positionals.length === 0) return { taskId: "", target: "" };
302
- if (positionals.length === 1) {
303
- const [value] = positionals;
304
- if (isPathLikePositional(value)) return { taskId: "", target: value };
305
- return { taskId: value, target: "" };
306
- }
307
- if (positionals.length === 2) return { taskId: positionals[0], target: positionals[1] };
308
- throw new Error(`Too many positional arguments for new-task: ${positionals.join(", ")}`);
309
- }
310
-
311
- function formatTaskCommandError(error) {
312
- const lines = [error.message];
313
- if (Array.isArray(error.recovery) && error.recovery.length > 0) {
314
- lines.push("", "Recovery:");
315
- for (const item of error.recovery) lines.push(`- ${item}`);
316
- }
317
- if (error.details?.entries?.length) {
318
- lines.push("", "Blocking Git status:");
319
- for (const entry of error.details.entries) lines.push(`- ${entry.raw || entry.path}`);
320
- }
321
- if (error.details?.disallowed?.length) {
322
- lines.push("", "Disallowed paths:");
323
- for (const item of error.details.disallowed) lines.push(`- ${item}`);
324
- }
325
- if (error.details?.stderr) lines.push("", error.details.stderr);
326
- if (error.details?.stdout) lines.push("", error.details.stdout);
327
- return lines.join("\n");
328
- }