coding-agent-harness 1.0.5 → 1.0.6

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
@@ -0,0 +1,91 @@
1
+ // @ts-nocheck
2
+ import { checkPresetPackage, inspectPresetPackage, installPresetPackage, listPresetPackages, seedBundledPresets, uninstallPresetPackage, } from "../lib/harness-core.mjs";
3
+ export function runPresetCommand({ args, takeFlag, targetArg }) {
4
+ const subcommand = args.shift() || "list";
5
+ const json = takeFlag("--json");
6
+ const project = takeFlag("--project");
7
+ try {
8
+ if (subcommand === "list") {
9
+ const target = targetArg();
10
+ const presets = listPresetPackages({ targetInput: target }).map((preset) => ({
11
+ id: preset.id,
12
+ version: preset.version,
13
+ purpose: preset.purpose,
14
+ compatibleBudgets: preset.compatibleBudgets,
15
+ source: preset.source,
16
+ manifestPath: preset.manifestRelativePath,
17
+ }));
18
+ if (json)
19
+ console.log(JSON.stringify({ presets }, null, 2));
20
+ else
21
+ for (const preset of presets)
22
+ console.log(`${preset.id}@${preset.version} [${preset.source}] ${preset.compatibleBudgets.join(",")} - ${preset.purpose}`);
23
+ }
24
+ else if (subcommand === "inspect") {
25
+ const id = args.shift();
26
+ if (!id)
27
+ throw new Error("Missing preset id");
28
+ const preset = inspectPresetPackage(id, { targetInput: targetArg() });
29
+ if (json)
30
+ console.log(JSON.stringify(preset, null, 2));
31
+ else
32
+ console.log(`${preset.id}@${preset.version}\n${preset.purpose}`);
33
+ }
34
+ else if (subcommand === "check") {
35
+ const id = args.shift();
36
+ if (!id)
37
+ throw new Error("Missing preset id");
38
+ const report = checkPresetPackage(id, { targetInput: targetArg() });
39
+ if (json)
40
+ console.log(JSON.stringify(report, null, 2));
41
+ else {
42
+ for (const failure of report.failures)
43
+ console.error(`Failure: ${failure}`);
44
+ for (const warning of report.warnings)
45
+ console.log(`Warning: ${warning}`);
46
+ console.log(`Preset check ${report.status}: ${report.id}@${report.version}`);
47
+ }
48
+ process.exit(report.status === "pass" ? 0 : 1);
49
+ }
50
+ else if (subcommand === "install") {
51
+ const force = takeFlag("--force");
52
+ const source = args.shift();
53
+ if (!source)
54
+ throw new Error("Missing preset source");
55
+ const result = installPresetPackage(source, { force, scope: project ? "project" : "user", targetInput: targetArg() });
56
+ if (json)
57
+ console.log(JSON.stringify(result, null, 2));
58
+ else
59
+ console.log(`Installed preset ${result.id}@${result.version} to ${result.destination}`);
60
+ }
61
+ else if (subcommand === "seed") {
62
+ const force = takeFlag("--force");
63
+ const dryRun = takeFlag("--dry-run");
64
+ const result = seedBundledPresets({ force, dryRun, scope: project ? "project" : "user", targetInput: targetArg() });
65
+ if (json)
66
+ console.log(JSON.stringify(result, null, 2));
67
+ else {
68
+ console.log(`Seeded bundled presets to ${result.target}`);
69
+ for (const preset of result.presets)
70
+ console.log(`${preset.action}: ${preset.id}@${preset.version}`);
71
+ }
72
+ }
73
+ else if (subcommand === "uninstall") {
74
+ const id = args.shift();
75
+ if (!id)
76
+ throw new Error("Missing preset id");
77
+ const result = uninstallPresetPackage(id, { scope: project ? "project" : "user", targetInput: targetArg() });
78
+ if (json)
79
+ console.log(JSON.stringify(result, null, 2));
80
+ else
81
+ console.log(`${result.removed ? "Removed" : "Preset not installed"}: ${result.id}`);
82
+ }
83
+ else {
84
+ throw new Error(`Unknown preset subcommand: ${subcommand}`);
85
+ }
86
+ }
87
+ catch (error) {
88
+ console.error(error.message);
89
+ process.exit(1);
90
+ }
91
+ }
@@ -0,0 +1,324 @@
1
+ // @ts-nocheck
2
+ import { confirmTaskReview, createTask, readPresetPackage, buildTaskIndex, createLessonSedimentationTask, archiveTask, listLifecycleTasks, promoteLessonCandidate, reopenTask, softDeleteTask, supersedeTask, updateModuleStep, updateTaskPhase, updateTaskLifecycle, } from "../lib/harness-core.mjs";
3
+ export function runTaskCommand(command, { args, takeFlag, takeOption, targetArg }) {
4
+ if (command === "new-task") {
5
+ const dryRun = takeFlag("--dry-run");
6
+ const locale = takeOption("--locale", "");
7
+ const title = takeOption("--title", "");
8
+ const moduleKey = takeOption("--module", "");
9
+ const budget = takeOption("--budget", "standard");
10
+ const preset = takeOption("--preset", "");
11
+ const fromSession = takeOption("--from-session", "");
12
+ const longRunning = takeFlag("--long-running");
13
+ try {
14
+ const parsed = parseNewTaskArgs(args, { preset, fromSession });
15
+ 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));
16
+ }
17
+ catch (error) {
18
+ console.error(error.message);
19
+ process.exit(1);
20
+ }
21
+ return;
22
+ }
23
+ if (command === "task-phase") {
24
+ const state = takeOption("--state", "");
25
+ const completion = takeOption("--completion", "");
26
+ const evidenceStatus = takeOption("--evidence", "");
27
+ const taskId = args.shift();
28
+ const phaseId = args.shift();
29
+ if (!taskId || !phaseId) {
30
+ console.error("Missing task id or phase id");
31
+ process.exit(2);
32
+ }
33
+ try {
34
+ console.log(JSON.stringify(updateTaskPhase(targetArg(), taskId, phaseId, { state, completion, evidenceStatus }), null, 2));
35
+ }
36
+ catch (error) {
37
+ console.error(error.message);
38
+ process.exit(1);
39
+ }
40
+ return;
41
+ }
42
+ if (["task-start", "task-log", "task-block", "task-review", "task-complete"].includes(command)) {
43
+ const message = takeOption("--message", "");
44
+ const evidence = takeOption("--evidence", "");
45
+ const taskId = args.shift();
46
+ if (!taskId) {
47
+ console.error("Missing task id");
48
+ process.exit(2);
49
+ }
50
+ const lifecycle = {
51
+ "task-start": { event: "task-start", state: "in_progress" },
52
+ "task-log": { event: "task-log", state: "" },
53
+ "task-block": { event: "task-block", state: "blocked" },
54
+ "task-review": { event: "task-review", state: "review" },
55
+ "task-complete": { event: "task-complete", state: "done" },
56
+ }[command];
57
+ try {
58
+ console.log(JSON.stringify(updateTaskLifecycle(targetArg(), taskId, { ...lifecycle, message, evidence }), null, 2));
59
+ }
60
+ catch (error) {
61
+ console.error(error.message);
62
+ process.exit(1);
63
+ }
64
+ return;
65
+ }
66
+ if (command === "review-confirm") {
67
+ const reviewer = takeOption("--reviewer", "Human Reviewer");
68
+ const message = takeOption("--message", "");
69
+ const evidence = takeOption("--evidence", "");
70
+ const confirmText = takeOption("--confirm", "");
71
+ const taskId = args.shift();
72
+ if (!taskId) {
73
+ console.error("Missing task id");
74
+ process.exit(2);
75
+ }
76
+ try {
77
+ console.log(JSON.stringify(confirmTaskReview(targetArg(), taskId, { reviewer, message, evidence, confirmText }), null, 2));
78
+ }
79
+ catch (error) {
80
+ console.error(formatTaskCommandError(error));
81
+ process.exit(1);
82
+ }
83
+ return;
84
+ }
85
+ if (command === "lesson-promote") {
86
+ const dryRun = takeFlag("--dry-run");
87
+ const apply = takeFlag("--apply");
88
+ const taskId = args.shift();
89
+ const candidateId = args.shift();
90
+ if (!taskId || !candidateId) {
91
+ console.error("Missing task id or candidate id");
92
+ process.exit(2);
93
+ }
94
+ try {
95
+ console.log(JSON.stringify(promoteLessonCandidate(targetArg(), taskId, candidateId, { dryRun, apply }), null, 2));
96
+ }
97
+ catch (error) {
98
+ console.error(error.message);
99
+ process.exit(1);
100
+ }
101
+ return;
102
+ }
103
+ if (command === "lesson-sediment") {
104
+ const dryRun = takeFlag("--dry-run");
105
+ const title = takeOption("--title", "");
106
+ const taskId = args.shift();
107
+ const candidateId = args.shift();
108
+ if (!taskId || !candidateId) {
109
+ console.error("Missing task id or candidate id");
110
+ process.exit(2);
111
+ }
112
+ try {
113
+ console.log(JSON.stringify(createLessonSedimentationTask(targetArg(), taskId, candidateId, { dryRun, title }), null, 2));
114
+ }
115
+ catch (error) {
116
+ console.error(error.message);
117
+ process.exit(1);
118
+ }
119
+ return;
120
+ }
121
+ if (command === "task-list") {
122
+ const json = takeFlag("--json");
123
+ const state = takeOption("--state", "");
124
+ const moduleKey = takeOption("--module", "");
125
+ const queue = takeOption("--queue", "");
126
+ const preset = takeOption("--preset", "");
127
+ const review = takeOption("--review", "");
128
+ const lesson = takeOption("--lesson", "");
129
+ const search = takeOption("--search", "");
130
+ const missingMaterials = takeFlag("--missing-materials");
131
+ const result = listLifecycleTasks(targetArg(), { state, moduleKey, queue, preset, review, lesson, search, missingMaterials });
132
+ if (json) {
133
+ console.log(JSON.stringify(result, null, 2));
134
+ }
135
+ else {
136
+ for (const task of result.tasks) {
137
+ console.log(`${task.id}\t${task.state}\t${task.completion}%\t${task.title}`);
138
+ }
139
+ }
140
+ return;
141
+ }
142
+ if (command === "task-index") {
143
+ const json = takeFlag("--json");
144
+ const result = buildTaskIndex(targetArg());
145
+ if (json)
146
+ console.log(JSON.stringify(result, null, 2));
147
+ else
148
+ console.log(`${result.tasks.length} tasks indexed (${result.schemaVersion})`);
149
+ return;
150
+ }
151
+ if (command === "task-supersede") {
152
+ const by = takeOption("--by", "");
153
+ const reason = takeOption("--reason", "");
154
+ const taskId = args.shift();
155
+ if (!taskId) {
156
+ console.error("Missing task id");
157
+ process.exit(2);
158
+ }
159
+ try {
160
+ console.log(JSON.stringify(supersedeTask(targetArg(), taskId, { by, reason }), null, 2));
161
+ }
162
+ catch (error) {
163
+ console.error(error.message);
164
+ process.exit(1);
165
+ }
166
+ return;
167
+ }
168
+ if (["task-delete", "task-archive", "task-reopen"].includes(command)) {
169
+ const soft = takeFlag("--soft");
170
+ const reason = takeOption("--reason", "");
171
+ const taskId = args.shift();
172
+ if (!taskId) {
173
+ console.error("Missing task id");
174
+ process.exit(2);
175
+ }
176
+ try {
177
+ if (command === "task-delete" && !soft)
178
+ throw new Error("task-delete only supports --soft; hard delete is intentionally disabled.");
179
+ const result = command === "task-delete"
180
+ ? softDeleteTask(targetArg(), taskId, { reason })
181
+ : command === "task-archive"
182
+ ? archiveTask(targetArg(), taskId, { reason })
183
+ : reopenTask(targetArg(), taskId, { reason });
184
+ console.log(JSON.stringify(result, null, 2));
185
+ }
186
+ catch (error) {
187
+ console.error(error.message);
188
+ process.exit(1);
189
+ }
190
+ return;
191
+ }
192
+ if (command === "module-step") {
193
+ const state = takeOption("--state", "done");
194
+ const moduleKey = args.shift();
195
+ const stepId = args.shift();
196
+ if (!moduleKey || !stepId) {
197
+ console.error("Missing module key or step id");
198
+ process.exit(2);
199
+ }
200
+ try {
201
+ console.log(JSON.stringify(updateModuleStep(targetArg(), moduleKey, stepId, { state }), null, 2));
202
+ }
203
+ catch (error) {
204
+ console.error(error.message);
205
+ process.exit(1);
206
+ }
207
+ return;
208
+ }
209
+ throw new Error(`Unsupported task command: ${command}`);
210
+ }
211
+ function parseNewTaskArgs(args, { preset = "" } = {}) {
212
+ const values = [...args];
213
+ const presetPackage = preset ? readPresetPackageForNewTask(preset, values) : null;
214
+ const parsed = splitPresetArgsAndPositionals(values, presetPackage);
215
+ const resolved = resolveNewTaskPositionals(parsed.positionals);
216
+ return {
217
+ taskId: resolved.taskId,
218
+ target: resolved.target || ".",
219
+ automaticTaskId: !resolved.taskId,
220
+ presetArgs: parsed.presetArgs,
221
+ };
222
+ }
223
+ function readPresetPackageForNewTask(preset, values) {
224
+ const candidates = presetDiscoveryTargetCandidates(values);
225
+ let fallbackPackage = null;
226
+ let lastError = null;
227
+ for (const targetInput of candidates) {
228
+ try {
229
+ const presetPackage = readPresetPackage(preset, { targetInput });
230
+ if (presetPackage.source === "project")
231
+ return presetPackage;
232
+ if (!fallbackPackage)
233
+ fallbackPackage = presetPackage;
234
+ }
235
+ catch (error) {
236
+ lastError = error;
237
+ }
238
+ }
239
+ if (fallbackPackage)
240
+ return fallbackPackage;
241
+ throw lastError;
242
+ }
243
+ function presetDiscoveryTargetCandidates(values) {
244
+ const candidates = [];
245
+ for (let index = values.length - 1; index >= 0; index -= 1) {
246
+ const value = values[index];
247
+ if (!value || value.startsWith("-"))
248
+ continue;
249
+ if (!candidates.includes(value))
250
+ candidates.push(value);
251
+ }
252
+ if (!candidates.includes("."))
253
+ candidates.push(".");
254
+ return candidates;
255
+ }
256
+ function splitPresetArgsAndPositionals(values, presetPackage) {
257
+ const presetArgs = [];
258
+ const positionals = [];
259
+ const declaredFlags = new Map(Object.values(presetPackage?.inputs || {}).filter((input) => input.flag).map((input) => [input.flag, input]));
260
+ for (let index = 0; index < values.length; index += 1) {
261
+ const value = values[index];
262
+ const declared = declaredFlags.get(value);
263
+ if (declared) {
264
+ presetArgs.push(value);
265
+ if (declared.type !== "flag" && index + 1 < values.length) {
266
+ presetArgs.push(values[index + 1]);
267
+ index += 1;
268
+ }
269
+ }
270
+ else if (value.startsWith("-")) {
271
+ presetArgs.push(value);
272
+ if (index + 1 < values.length && !values[index + 1].startsWith("-")) {
273
+ presetArgs.push(values[index + 1]);
274
+ index += 1;
275
+ }
276
+ }
277
+ else {
278
+ positionals.push(value);
279
+ }
280
+ }
281
+ return {
282
+ positionals,
283
+ presetArgs,
284
+ };
285
+ }
286
+ function isPathLikePositional(value) {
287
+ return value === "." || value === ".." || value.startsWith("/") || value.startsWith("~/") || /^\.[^./\\]/.test(value) || value.includes("/") || value.includes("\\");
288
+ }
289
+ function resolveNewTaskPositionals(positionals) {
290
+ if (positionals.length === 0)
291
+ return { taskId: "", target: "" };
292
+ if (positionals.length === 1) {
293
+ const [value] = positionals;
294
+ if (isPathLikePositional(value))
295
+ return { taskId: "", target: value };
296
+ return { taskId: value, target: "" };
297
+ }
298
+ if (positionals.length === 2)
299
+ return { taskId: positionals[0], target: positionals[1] };
300
+ throw new Error(`Too many positional arguments for new-task: ${positionals.join(", ")}`);
301
+ }
302
+ function formatTaskCommandError(error) {
303
+ const lines = [error.message];
304
+ if (Array.isArray(error.recovery) && error.recovery.length > 0) {
305
+ lines.push("", "Recovery:");
306
+ for (const item of error.recovery)
307
+ lines.push(`- ${item}`);
308
+ }
309
+ if (error.details?.entries?.length) {
310
+ lines.push("", "Blocking Git status:");
311
+ for (const entry of error.details.entries)
312
+ lines.push(`- ${entry.raw || entry.path}`);
313
+ }
314
+ if (error.details?.disallowed?.length) {
315
+ lines.push("", "Disallowed paths:");
316
+ for (const item of error.details.disallowed)
317
+ lines.push(`- ${item}`);
318
+ }
319
+ if (error.details?.stderr)
320
+ lines.push("", error.details.stderr);
321
+ if (error.details?.stdout)
322
+ lines.push("", error.details.stdout);
323
+ return lines.join("\n");
324
+ }