@lumenflow/cli 3.1.1 → 3.1.3

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 (389) hide show
  1. package/README.md +36 -35
  2. package/dist/agent-issues-query.js +13 -8
  3. package/dist/agent-log-issue.js +15 -4
  4. package/dist/agent-session-end.js +15 -4
  5. package/dist/agent-session.js +18 -6
  6. package/dist/backlog-prune.js +1 -1
  7. package/dist/commands/integrate.js +32 -18
  8. package/dist/config-get.js +27 -15
  9. package/dist/config-set.js +104 -37
  10. package/dist/delegation-list.js +1 -1
  11. package/dist/doctor.js +19 -13
  12. package/dist/file-delete.js +1 -1
  13. package/dist/file-edit.js +1 -1
  14. package/dist/file-read.js +1 -1
  15. package/dist/file-write.js +1 -1
  16. package/dist/flow-bottlenecks.js +1 -1
  17. package/dist/flow-report.js +10 -9
  18. package/dist/gates.js +3 -2
  19. package/dist/git-branch.js +1 -1
  20. package/dist/git-diff.js +1 -1
  21. package/dist/git-log.js +1 -1
  22. package/dist/init.js +244 -61
  23. package/dist/initiative-add-wu.js +1 -1
  24. package/dist/initiative-bulk-assign-wus.js +1 -1
  25. package/dist/initiative-create.js +2 -2
  26. package/dist/initiative-edit.js +1 -1
  27. package/dist/initiative-list.js +1 -1
  28. package/dist/initiative-plan.js +1 -3
  29. package/dist/initiative-status.js +47 -6
  30. package/dist/lane-edit.js +19 -10
  31. package/dist/lane-health.js +13 -24
  32. package/dist/lane-lock.js +4 -5
  33. package/dist/lane-setup.js +5 -5
  34. package/dist/lane-status.js +4 -5
  35. package/dist/lane-suggest.js +9 -7
  36. package/dist/lane-validate.js +4 -5
  37. package/dist/lumenflow-upgrade.js +17 -11
  38. package/dist/mem-checkpoint.js +1 -1
  39. package/dist/mem-cleanup.js +6 -23
  40. package/dist/mem-context.js +1 -1
  41. package/dist/mem-create.js +1 -1
  42. package/dist/mem-delete.js +1 -1
  43. package/dist/mem-export.js +1 -1
  44. package/dist/mem-inbox.js +1 -1
  45. package/dist/mem-init.js +1 -1
  46. package/dist/mem-ready.js +1 -1
  47. package/dist/mem-recover.js +1 -1
  48. package/dist/mem-signal.js +1 -1
  49. package/dist/mem-start.js +1 -1
  50. package/dist/mem-summarize.js +8 -7
  51. package/dist/mem-triage.js +7 -5
  52. package/dist/metrics-cli.js +1 -1
  53. package/dist/metrics-snapshot.js +1 -1
  54. package/dist/onboard.js +295 -120
  55. package/dist/orchestrate-init-status.js +12 -7
  56. package/dist/orchestrate-initiative.js +23 -12
  57. package/dist/orchestrate-monitor.js +20 -8
  58. package/dist/pack-scaffold.js +1 -1
  59. package/dist/plan-create.js +1 -3
  60. package/dist/plan-edit.js +1 -3
  61. package/dist/plan-link.js +1 -3
  62. package/dist/plan-promote.js +1 -3
  63. package/dist/release.js +1 -3
  64. package/dist/signal-cleanup.js +4 -18
  65. package/dist/state-bootstrap.js +11 -8
  66. package/dist/state-cleanup.js +5 -19
  67. package/dist/state-doctor.js +213 -9
  68. package/dist/task-claim.js +1 -1
  69. package/dist/validate.js +1 -1
  70. package/dist/workspace-init.js +61 -61
  71. package/dist/wu-block.js +1 -1
  72. package/dist/wu-brief.js +1 -1
  73. package/dist/wu-claim.js +1 -1
  74. package/dist/wu-cleanup.js +1 -1
  75. package/dist/wu-create.js +3 -3
  76. package/dist/wu-delegate.js +1 -1
  77. package/dist/wu-deps.js +1 -1
  78. package/dist/wu-done.js +66 -34
  79. package/dist/wu-edit.js +1 -1
  80. package/dist/wu-infer-lane.js +1 -1
  81. package/dist/wu-preflight.js +1 -1
  82. package/dist/wu-prep.js +1 -1
  83. package/dist/wu-proto.js +1 -1
  84. package/dist/wu-prune.js +1 -1
  85. package/dist/wu-recover.js +1 -1
  86. package/dist/wu-release.js +1 -1
  87. package/dist/wu-repair.js +1 -1
  88. package/dist/wu-sandbox.js +40 -27
  89. package/dist/wu-status.js +1 -1
  90. package/dist/wu-unblock.js +1 -1
  91. package/dist/wu-unlock-lane.js +1 -1
  92. package/dist/wu-validate.js +1 -1
  93. package/package.json +12 -8
  94. package/packs/software-delivery/constants.ts +10 -0
  95. package/packs/software-delivery/extensions.ts +140 -0
  96. package/packs/software-delivery/gate-policies.ts +134 -0
  97. package/packs/software-delivery/index.ts +8 -0
  98. package/packs/software-delivery/manifest-schema.ts +236 -0
  99. package/packs/software-delivery/manifest.ts +417 -0
  100. package/packs/software-delivery/manifest.yaml +711 -0
  101. package/packs/software-delivery/pack-registration.ts +113 -0
  102. package/packs/software-delivery/tool-impl/agent-tools.ts +263 -0
  103. package/packs/software-delivery/tool-impl/delegation-tools.ts +66 -0
  104. package/packs/software-delivery/tool-impl/flow-metrics-tools.ts +219 -0
  105. package/packs/software-delivery/tool-impl/git-runner.ts +113 -0
  106. package/packs/software-delivery/tool-impl/git-tools.ts +316 -0
  107. package/packs/software-delivery/tool-impl/index.ts +15 -0
  108. package/packs/software-delivery/tool-impl/initiative-orchestration-tools.ts +720 -0
  109. package/packs/software-delivery/tool-impl/lane-lock.ts +246 -0
  110. package/packs/software-delivery/tool-impl/memory-tools.ts +415 -0
  111. package/packs/software-delivery/tool-impl/pending-runtime-tools.ts +21 -0
  112. package/packs/software-delivery/tool-impl/runtime-cli-adapter.ts +328 -0
  113. package/packs/software-delivery/tool-impl/runtime-native-tools.ts +687 -0
  114. package/packs/software-delivery/tool-impl/worker-loader.ts +52 -0
  115. package/packs/software-delivery/tool-impl/worktree-tools.ts +46 -0
  116. package/packs/software-delivery/tool-impl/wu-lifecycle-tools.ts +759 -0
  117. package/packs/software-delivery/tools/delegation-tools.ts +23 -0
  118. package/packs/software-delivery/tools/git-tools.ts +55 -0
  119. package/packs/software-delivery/tools/index.ts +8 -0
  120. package/packs/software-delivery/tools/lane-lock-tool.ts +37 -0
  121. package/packs/software-delivery/tools/types.ts +71 -0
  122. package/packs/software-delivery/tools/worktree-tools.ts +49 -0
  123. package/templates/core/LUMENFLOW.md.template +3 -3
  124. package/templates/core/ai/onboarding/agent-invocation-guide.md.template +1 -1
  125. package/templates/core/ai/onboarding/lumenflow-force-usage.md.template +1 -1
  126. package/templates/core/ai/onboarding/quick-ref-commands.md.template +5 -5
  127. package/templates/core/ai/onboarding/starting-prompt.md.template +3 -3
  128. package/templates/core/ai/onboarding/vendor-support.md.template +1 -1
  129. package/templates/core/ai/onboarding/wu-create-checklist.md.template +1 -1
  130. package/dist/agent-issues-query.js.map +0 -1
  131. package/dist/agent-log-issue.js.map +0 -1
  132. package/dist/agent-session-end.js.map +0 -1
  133. package/dist/agent-session.js.map +0 -1
  134. package/dist/backlog-prune.js.map +0 -1
  135. package/dist/cli-entry-point.js +0 -149
  136. package/dist/cli-entry-point.js.map +0 -1
  137. package/dist/commands/integrate.js.map +0 -1
  138. package/dist/commands.js.map +0 -1
  139. package/dist/config-get.js.map +0 -1
  140. package/dist/config-set.js.map +0 -1
  141. package/dist/delegation-list.js.map +0 -1
  142. package/dist/deps-add.js +0 -259
  143. package/dist/deps-add.js.map +0 -1
  144. package/dist/deps-remove.js +0 -105
  145. package/dist/deps-remove.js.map +0 -1
  146. package/dist/docs-sync.js.map +0 -1
  147. package/dist/doctor.js.map +0 -1
  148. package/dist/file-delete.js.map +0 -1
  149. package/dist/file-edit.js.map +0 -1
  150. package/dist/file-read.js.map +0 -1
  151. package/dist/file-write.js.map +0 -1
  152. package/dist/flow-bottlenecks.js.map +0 -1
  153. package/dist/flow-report.js.map +0 -1
  154. package/dist/formatters.js +0 -151
  155. package/dist/formatters.js.map +0 -1
  156. package/dist/gate-defaults.js +0 -131
  157. package/dist/gate-defaults.js.map +0 -1
  158. package/dist/gate-registry.js +0 -73
  159. package/dist/gate-registry.js.map +0 -1
  160. package/dist/gates-graceful-degradation.js +0 -153
  161. package/dist/gates-graceful-degradation.js.map +0 -1
  162. package/dist/gates-plan-resolvers.js +0 -152
  163. package/dist/gates-plan-resolvers.js.map +0 -1
  164. package/dist/gates-runners.js +0 -509
  165. package/dist/gates-runners.js.map +0 -1
  166. package/dist/gates-types.js +0 -4
  167. package/dist/gates-types.js.map +0 -1
  168. package/dist/gates-utils.js +0 -323
  169. package/dist/gates-utils.js.map +0 -1
  170. package/dist/gates.js.map +0 -1
  171. package/dist/git-branch.js.map +0 -1
  172. package/dist/git-diff.js.map +0 -1
  173. package/dist/git-log.js.map +0 -1
  174. package/dist/git-status.js.map +0 -1
  175. package/dist/guard-locked.js +0 -172
  176. package/dist/guard-locked.js.map +0 -1
  177. package/dist/guard-main-branch.js +0 -217
  178. package/dist/guard-main-branch.js.map +0 -1
  179. package/dist/guard-worktree-commit.js +0 -163
  180. package/dist/guard-worktree-commit.js.map +0 -1
  181. package/dist/hooks/auto-checkpoint-utils.js +0 -54
  182. package/dist/hooks/auto-checkpoint-utils.js.map +0 -1
  183. package/dist/hooks/enforcement-checks.js +0 -399
  184. package/dist/hooks/enforcement-checks.js.map +0 -1
  185. package/dist/hooks/enforcement-generator.js +0 -139
  186. package/dist/hooks/enforcement-generator.js.map +0 -1
  187. package/dist/hooks/enforcement-sync.js +0 -385
  188. package/dist/hooks/enforcement-sync.js.map +0 -1
  189. package/dist/hooks/generators/auto-checkpoint.js +0 -125
  190. package/dist/hooks/generators/auto-checkpoint.js.map +0 -1
  191. package/dist/hooks/generators/enforce-worktree.js +0 -190
  192. package/dist/hooks/generators/enforce-worktree.js.map +0 -1
  193. package/dist/hooks/generators/index.js +0 -18
  194. package/dist/hooks/generators/index.js.map +0 -1
  195. package/dist/hooks/generators/pre-compact-checkpoint.js +0 -136
  196. package/dist/hooks/generators/pre-compact-checkpoint.js.map +0 -1
  197. package/dist/hooks/generators/require-wu.js +0 -117
  198. package/dist/hooks/generators/require-wu.js.map +0 -1
  199. package/dist/hooks/generators/session-start-recovery.js +0 -103
  200. package/dist/hooks/generators/session-start-recovery.js.map +0 -1
  201. package/dist/hooks/generators/signal-utils.js +0 -54
  202. package/dist/hooks/generators/signal-utils.js.map +0 -1
  203. package/dist/hooks/generators/warn-incomplete.js +0 -67
  204. package/dist/hooks/generators/warn-incomplete.js.map +0 -1
  205. package/dist/hooks/index.js +0 -10
  206. package/dist/hooks/index.js.map +0 -1
  207. package/dist/index.js.map +0 -1
  208. package/dist/init-detection.js +0 -230
  209. package/dist/init-detection.js.map +0 -1
  210. package/dist/init-lane-validation.js +0 -143
  211. package/dist/init-lane-validation.js.map +0 -1
  212. package/dist/init-scaffolding.js +0 -158
  213. package/dist/init-scaffolding.js.map +0 -1
  214. package/dist/init-templates.js +0 -1964
  215. package/dist/init-templates.js.map +0 -1
  216. package/dist/init.js.map +0 -1
  217. package/dist/initiative-add-wu.js.map +0 -1
  218. package/dist/initiative-bulk-assign-wus.js.map +0 -1
  219. package/dist/initiative-create.js.map +0 -1
  220. package/dist/initiative-edit.js.map +0 -1
  221. package/dist/initiative-list.js.map +0 -1
  222. package/dist/initiative-plan.js.map +0 -1
  223. package/dist/initiative-remove-wu.js.map +0 -1
  224. package/dist/initiative-status.js.map +0 -1
  225. package/dist/lane-edit.js.map +0 -1
  226. package/dist/lane-health.js.map +0 -1
  227. package/dist/lane-lifecycle-process.js +0 -366
  228. package/dist/lane-lifecycle-process.js.map +0 -1
  229. package/dist/lane-lock.js.map +0 -1
  230. package/dist/lane-setup.js.map +0 -1
  231. package/dist/lane-status.js.map +0 -1
  232. package/dist/lane-suggest.js.map +0 -1
  233. package/dist/lane-validate.js.map +0 -1
  234. package/dist/lifecycle-regression-harness.js +0 -181
  235. package/dist/lifecycle-regression-harness.js.map +0 -1
  236. package/dist/lumenflow-upgrade.js.map +0 -1
  237. package/dist/mem-checkpoint.js.map +0 -1
  238. package/dist/mem-cleanup.js.map +0 -1
  239. package/dist/mem-context.js.map +0 -1
  240. package/dist/mem-create.js.map +0 -1
  241. package/dist/mem-delete.js.map +0 -1
  242. package/dist/mem-export.js.map +0 -1
  243. package/dist/mem-inbox.js.map +0 -1
  244. package/dist/mem-index.js +0 -214
  245. package/dist/mem-index.js.map +0 -1
  246. package/dist/mem-init.js.map +0 -1
  247. package/dist/mem-profile.js +0 -210
  248. package/dist/mem-profile.js.map +0 -1
  249. package/dist/mem-promote.js +0 -257
  250. package/dist/mem-promote.js.map +0 -1
  251. package/dist/mem-ready.js.map +0 -1
  252. package/dist/mem-recover.js.map +0 -1
  253. package/dist/mem-signal.js.map +0 -1
  254. package/dist/mem-start.js.map +0 -1
  255. package/dist/mem-summarize.js.map +0 -1
  256. package/dist/mem-triage.js.map +0 -1
  257. package/dist/merge-block.js +0 -225
  258. package/dist/merge-block.js.map +0 -1
  259. package/dist/metrics-cli.js.map +0 -1
  260. package/dist/metrics-snapshot.js.map +0 -1
  261. package/dist/onboard.js.map +0 -1
  262. package/dist/onboarding-smoke-test.js +0 -418
  263. package/dist/onboarding-smoke-test.js.map +0 -1
  264. package/dist/orchestrate-init-status.js.map +0 -1
  265. package/dist/orchestrate-initiative.js.map +0 -1
  266. package/dist/orchestrate-monitor.js.map +0 -1
  267. package/dist/pack-author.js.map +0 -1
  268. package/dist/pack-hash.js.map +0 -1
  269. package/dist/pack-install.js.map +0 -1
  270. package/dist/pack-publish.js.map +0 -1
  271. package/dist/pack-scaffold.js.map +0 -1
  272. package/dist/pack-search.js.map +0 -1
  273. package/dist/pack-validate.js.map +0 -1
  274. package/dist/plan-create.js.map +0 -1
  275. package/dist/plan-edit.js.map +0 -1
  276. package/dist/plan-link.js.map +0 -1
  277. package/dist/plan-promote.js.map +0 -1
  278. package/dist/public-manifest.js +0 -920
  279. package/dist/public-manifest.js.map +0 -1
  280. package/dist/release.js.map +0 -1
  281. package/dist/rotate-progress.js +0 -253
  282. package/dist/rotate-progress.js.map +0 -1
  283. package/dist/session-coordinator.js +0 -303
  284. package/dist/session-coordinator.js.map +0 -1
  285. package/dist/shared-validators.js +0 -81
  286. package/dist/shared-validators.js.map +0 -1
  287. package/dist/signal-cleanup.js.map +0 -1
  288. package/dist/state-bootstrap.js.map +0 -1
  289. package/dist/state-cleanup.js.map +0 -1
  290. package/dist/state-doctor-fix.js +0 -226
  291. package/dist/state-doctor-fix.js.map +0 -1
  292. package/dist/state-doctor-stamps.js +0 -23
  293. package/dist/state-doctor-stamps.js.map +0 -1
  294. package/dist/state-doctor.js.map +0 -1
  295. package/dist/strict-progress.js +0 -255
  296. package/dist/strict-progress.js.map +0 -1
  297. package/dist/sync-templates.js.map +0 -1
  298. package/dist/task-claim.js.map +0 -1
  299. package/dist/trace-gen.js +0 -401
  300. package/dist/trace-gen.js.map +0 -1
  301. package/dist/validate-agent-skills.js +0 -223
  302. package/dist/validate-agent-skills.js.map +0 -1
  303. package/dist/validate-agent-sync.js +0 -151
  304. package/dist/validate-agent-sync.js.map +0 -1
  305. package/dist/validate-backlog-sync.js +0 -77
  306. package/dist/validate-backlog-sync.js.map +0 -1
  307. package/dist/validate-skills-spec.js +0 -211
  308. package/dist/validate-skills-spec.js.map +0 -1
  309. package/dist/validate.js.map +0 -1
  310. package/dist/validator-defaults.js +0 -107
  311. package/dist/validator-defaults.js.map +0 -1
  312. package/dist/validator-registry.js +0 -71
  313. package/dist/validator-registry.js.map +0 -1
  314. package/dist/workspace-init.js.map +0 -1
  315. package/dist/wu-block.js.map +0 -1
  316. package/dist/wu-brief.js.map +0 -1
  317. package/dist/wu-claim-branch.js +0 -123
  318. package/dist/wu-claim-branch.js.map +0 -1
  319. package/dist/wu-claim-cloud.js +0 -79
  320. package/dist/wu-claim-cloud.js.map +0 -1
  321. package/dist/wu-claim-mode.js +0 -82
  322. package/dist/wu-claim-mode.js.map +0 -1
  323. package/dist/wu-claim-output.js +0 -85
  324. package/dist/wu-claim-output.js.map +0 -1
  325. package/dist/wu-claim-repair-guidance.js +0 -12
  326. package/dist/wu-claim-repair-guidance.js.map +0 -1
  327. package/dist/wu-claim-resume-handler.js +0 -87
  328. package/dist/wu-claim-resume-handler.js.map +0 -1
  329. package/dist/wu-claim-state.js +0 -581
  330. package/dist/wu-claim-state.js.map +0 -1
  331. package/dist/wu-claim-validation.js +0 -457
  332. package/dist/wu-claim-validation.js.map +0 -1
  333. package/dist/wu-claim-worktree.js +0 -223
  334. package/dist/wu-claim-worktree.js.map +0 -1
  335. package/dist/wu-claim.js.map +0 -1
  336. package/dist/wu-cleanup-cloud.js +0 -78
  337. package/dist/wu-cleanup-cloud.js.map +0 -1
  338. package/dist/wu-cleanup.js.map +0 -1
  339. package/dist/wu-code-path-coverage.js +0 -83
  340. package/dist/wu-code-path-coverage.js.map +0 -1
  341. package/dist/wu-create-cloud.js +0 -30
  342. package/dist/wu-create-cloud.js.map +0 -1
  343. package/dist/wu-create-content.js +0 -264
  344. package/dist/wu-create-content.js.map +0 -1
  345. package/dist/wu-create-readiness.js +0 -59
  346. package/dist/wu-create-readiness.js.map +0 -1
  347. package/dist/wu-create-validation.js +0 -128
  348. package/dist/wu-create-validation.js.map +0 -1
  349. package/dist/wu-create.js.map +0 -1
  350. package/dist/wu-delegate.js.map +0 -1
  351. package/dist/wu-delete.js.map +0 -1
  352. package/dist/wu-deps.js.map +0 -1
  353. package/dist/wu-done-auto-cleanup.js +0 -203
  354. package/dist/wu-done-auto-cleanup.js.map +0 -1
  355. package/dist/wu-done-check.js +0 -38
  356. package/dist/wu-done-check.js.map +0 -1
  357. package/dist/wu-done-cloud.js +0 -48
  358. package/dist/wu-done-cloud.js.map +0 -1
  359. package/dist/wu-done-decay.js +0 -86
  360. package/dist/wu-done-decay.js.map +0 -1
  361. package/dist/wu-done.js.map +0 -1
  362. package/dist/wu-edit-operations.js +0 -399
  363. package/dist/wu-edit-operations.js.map +0 -1
  364. package/dist/wu-edit-validators.js +0 -282
  365. package/dist/wu-edit-validators.js.map +0 -1
  366. package/dist/wu-edit.js.map +0 -1
  367. package/dist/wu-infer-lane.js.map +0 -1
  368. package/dist/wu-preflight.js.map +0 -1
  369. package/dist/wu-prep.js.map +0 -1
  370. package/dist/wu-proto.js.map +0 -1
  371. package/dist/wu-prune.js.map +0 -1
  372. package/dist/wu-recover.js.map +0 -1
  373. package/dist/wu-release.js.map +0 -1
  374. package/dist/wu-repair.js.map +0 -1
  375. package/dist/wu-sandbox.js.map +0 -1
  376. package/dist/wu-spawn-completion.js +0 -33
  377. package/dist/wu-spawn-completion.js.map +0 -1
  378. package/dist/wu-spawn-prompt-builders.js +0 -1197
  379. package/dist/wu-spawn-prompt-builders.js.map +0 -1
  380. package/dist/wu-spawn-strategy-resolver.js +0 -322
  381. package/dist/wu-spawn-strategy-resolver.js.map +0 -1
  382. package/dist/wu-spawn.js +0 -59
  383. package/dist/wu-spawn.js.map +0 -1
  384. package/dist/wu-state-cloud.js +0 -41
  385. package/dist/wu-state-cloud.js.map +0 -1
  386. package/dist/wu-status.js.map +0 -1
  387. package/dist/wu-unblock.js.map +0 -1
  388. package/dist/wu-unlock-lane.js.map +0 -1
  389. package/dist/wu-validate.js.map +0 -1
@@ -0,0 +1,759 @@
1
+ // Copyright (c) 2026 Hellmai Ltd
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+
4
+ import type { ToolOutput } from '@lumenflow/kernel';
5
+ import { RUNTIME_CLI_COMMANDS, runtimeCliAdapter } from './runtime-cli-adapter.js';
6
+
7
+ const LIFECYCLE_TOOLS = {
8
+ WU_STATUS: 'wu:status',
9
+ WU_CREATE: 'wu:create',
10
+ WU_CLAIM: 'wu:claim',
11
+ WU_PREP: 'wu:prep',
12
+ WU_DONE: 'wu:done',
13
+ WU_SANDBOX: 'wu:sandbox',
14
+ WU_PRUNE: 'wu:prune',
15
+ WU_DELETE: 'wu:delete',
16
+ WU_CLEANUP: 'wu:cleanup',
17
+ WU_UNLOCK_LANE: 'wu:unlock-lane',
18
+ WU_BRIEF: 'wu:brief',
19
+ WU_DELEGATE: 'wu:delegate',
20
+ WU_DEPS: 'wu:deps',
21
+ WU_EDIT: 'wu:edit',
22
+ WU_PROTO: 'wu:proto',
23
+ WU_PREFLIGHT: 'wu:preflight',
24
+ WU_VALIDATE: 'wu:validate',
25
+ WU_BLOCK: 'wu:block',
26
+ WU_UNBLOCK: 'wu:unblock',
27
+ WU_RELEASE: 'wu:release',
28
+ WU_RECOVER: 'wu:recover',
29
+ WU_REPAIR: 'wu:repair',
30
+ GATES: 'gates',
31
+ } as const;
32
+
33
+ type LifecycleToolName = (typeof LIFECYCLE_TOOLS)[keyof typeof LIFECYCLE_TOOLS];
34
+
35
+ const LIFECYCLE_TOOL_ERROR_CODES: Record<LifecycleToolName, string> = {
36
+ 'wu:status': 'WU_STATUS_ERROR',
37
+ 'wu:create': 'WU_CREATE_ERROR',
38
+ 'wu:claim': 'WU_CLAIM_ERROR',
39
+ 'wu:prep': 'WU_PREP_ERROR',
40
+ 'wu:done': 'WU_DONE_ERROR',
41
+ 'wu:sandbox': 'WU_SANDBOX_ERROR',
42
+ 'wu:prune': 'WU_PRUNE_ERROR',
43
+ 'wu:delete': 'WU_DELETE_ERROR',
44
+ 'wu:cleanup': 'WU_CLEANUP_ERROR',
45
+ 'wu:unlock-lane': 'WU_UNLOCK_LANE_ERROR',
46
+ 'wu:brief': 'WU_BRIEF_ERROR',
47
+ 'wu:delegate': 'WU_DELEGATE_ERROR',
48
+ 'wu:deps': 'WU_DEPS_ERROR',
49
+ 'wu:edit': 'WU_EDIT_ERROR',
50
+ 'wu:proto': 'WU_PROTO_ERROR',
51
+ 'wu:preflight': 'WU_PREFLIGHT_ERROR',
52
+ 'wu:validate': 'WU_VALIDATE_ERROR',
53
+ 'wu:block': 'WU_BLOCK_ERROR',
54
+ 'wu:unblock': 'WU_UNBLOCK_ERROR',
55
+ 'wu:release': 'WU_RELEASE_ERROR',
56
+ 'wu:recover': 'WU_RECOVER_ERROR',
57
+ 'wu:repair': 'WU_REPAIR_ERROR',
58
+ gates: 'GATES_ERROR',
59
+ };
60
+
61
+ interface LifecycleToolCommandSpec {
62
+ command: (typeof RUNTIME_CLI_COMMANDS)[keyof typeof RUNTIME_CLI_COMMANDS];
63
+ }
64
+
65
+ const LIFECYCLE_TOOL_COMMAND_SPECS: Record<LifecycleToolName, LifecycleToolCommandSpec> = {
66
+ 'wu:status': { command: RUNTIME_CLI_COMMANDS.WU_STATUS },
67
+ 'wu:create': { command: RUNTIME_CLI_COMMANDS.WU_CREATE },
68
+ 'wu:claim': { command: RUNTIME_CLI_COMMANDS.WU_CLAIM },
69
+ 'wu:prep': { command: RUNTIME_CLI_COMMANDS.WU_PREP },
70
+ 'wu:done': { command: RUNTIME_CLI_COMMANDS.WU_DONE },
71
+ 'wu:sandbox': { command: RUNTIME_CLI_COMMANDS.WU_SANDBOX },
72
+ 'wu:prune': { command: RUNTIME_CLI_COMMANDS.WU_PRUNE },
73
+ 'wu:delete': { command: RUNTIME_CLI_COMMANDS.WU_DELETE },
74
+ 'wu:cleanup': { command: RUNTIME_CLI_COMMANDS.WU_CLEANUP },
75
+ 'wu:unlock-lane': { command: RUNTIME_CLI_COMMANDS.WU_UNLOCK_LANE },
76
+ 'wu:brief': { command: RUNTIME_CLI_COMMANDS.WU_BRIEF },
77
+ 'wu:delegate': { command: RUNTIME_CLI_COMMANDS.WU_DELEGATE },
78
+ 'wu:deps': { command: RUNTIME_CLI_COMMANDS.WU_DEPS },
79
+ 'wu:edit': { command: RUNTIME_CLI_COMMANDS.WU_EDIT },
80
+ 'wu:proto': { command: RUNTIME_CLI_COMMANDS.WU_PROTO },
81
+ 'wu:preflight': { command: RUNTIME_CLI_COMMANDS.WU_PREFLIGHT },
82
+ 'wu:validate': { command: RUNTIME_CLI_COMMANDS.WU_VALIDATE },
83
+ 'wu:block': { command: RUNTIME_CLI_COMMANDS.WU_BLOCK },
84
+ 'wu:unblock': { command: RUNTIME_CLI_COMMANDS.WU_UNBLOCK },
85
+ 'wu:release': { command: RUNTIME_CLI_COMMANDS.WU_RELEASE },
86
+ 'wu:recover': { command: RUNTIME_CLI_COMMANDS.WU_RECOVER },
87
+ 'wu:repair': { command: RUNTIME_CLI_COMMANDS.WU_REPAIR },
88
+ gates: { command: RUNTIME_CLI_COMMANDS.GATES },
89
+ };
90
+
91
+ const MISSING_PARAMETER_MESSAGES = {
92
+ ID_REQUIRED: 'id is required',
93
+ COMMAND_REQUIRED: 'command is required',
94
+ PARENT_WU_REQUIRED: 'parent_wu is required',
95
+ LANE_REQUIRED: 'lane is required',
96
+ TITLE_REQUIRED: 'title is required',
97
+ REASON_REQUIRED: 'reason is required',
98
+ SANDBOX_COMMAND_REQUIRED: 'sandbox_command is required when sandbox=true',
99
+ } as const;
100
+
101
+ const LIFECYCLE_FLAGS = {
102
+ DESCRIPTION: '--description',
103
+ CODE_PATHS: '--code-paths',
104
+ } as const;
105
+
106
+ interface CommandExecutionResult {
107
+ ok: boolean;
108
+ status: number;
109
+ stdout: string;
110
+ stderr: string;
111
+ executionError?: string;
112
+ }
113
+
114
+ interface RunOptions {
115
+ parseJson?: boolean;
116
+ }
117
+
118
+ function toRecord(input: unknown): Record<string, unknown> {
119
+ if (input && typeof input === 'object') {
120
+ return input as Record<string, unknown>;
121
+ }
122
+ return {};
123
+ }
124
+
125
+ function toStringValue(value: unknown): string | null {
126
+ if (typeof value !== 'string') {
127
+ return null;
128
+ }
129
+ const trimmed = value.trim();
130
+ return trimmed.length > 0 ? trimmed : null;
131
+ }
132
+
133
+ function toStringArray(value: unknown): string[] {
134
+ if (!Array.isArray(value)) {
135
+ return [];
136
+ }
137
+ return value
138
+ .map((entry) => toStringValue(entry))
139
+ .filter((entry): entry is string => entry !== null);
140
+ }
141
+
142
+ function toIntegerString(value: unknown): string | null {
143
+ if (typeof value === 'number' && Number.isFinite(value)) {
144
+ return String(Math.trunc(value));
145
+ }
146
+ if (typeof value === 'string') {
147
+ const trimmed = value.trim();
148
+ return trimmed.length > 0 ? trimmed : null;
149
+ }
150
+ return null;
151
+ }
152
+
153
+ async function runLifecycleCommand(
154
+ toolName: LifecycleToolName,
155
+ args: string[],
156
+ ): Promise<CommandExecutionResult> {
157
+ const spec = LIFECYCLE_TOOL_COMMAND_SPECS[toolName];
158
+ return runtimeCliAdapter.run(spec.command, args);
159
+ }
160
+
161
+ function createMissingParameterOutput(message: string): ToolOutput {
162
+ return {
163
+ success: false,
164
+ error: {
165
+ code: 'MISSING_PARAMETER',
166
+ message,
167
+ },
168
+ };
169
+ }
170
+
171
+ function createFailureOutput(
172
+ toolName: LifecycleToolName,
173
+ execution: CommandExecutionResult,
174
+ ): ToolOutput {
175
+ const stderrMessage = execution.stderr.trim();
176
+ const stdoutMessage = execution.stdout.trim();
177
+ const message =
178
+ execution.executionError ??
179
+ (stderrMessage.length > 0
180
+ ? stderrMessage
181
+ : stdoutMessage.length > 0
182
+ ? stdoutMessage
183
+ : `${toolName} failed`);
184
+ return {
185
+ success: false,
186
+ error: {
187
+ code: LIFECYCLE_TOOL_ERROR_CODES[toolName],
188
+ message,
189
+ details: {
190
+ exit_code: execution.status,
191
+ stdout: execution.stdout,
192
+ stderr: execution.stderr,
193
+ },
194
+ },
195
+ };
196
+ }
197
+
198
+ function parseJsonOutput(stdout: string): unknown | null {
199
+ const trimmed = stdout.trim();
200
+ if (trimmed.length === 0) {
201
+ return null;
202
+ }
203
+ try {
204
+ return JSON.parse(trimmed) as unknown;
205
+ } catch {
206
+ return null;
207
+ }
208
+ }
209
+
210
+ function createSuccessOutput(
211
+ toolName: LifecycleToolName,
212
+ execution: CommandExecutionResult,
213
+ options: RunOptions,
214
+ ): ToolOutput {
215
+ const parsedJson = options.parseJson ? parseJsonOutput(execution.stdout) : null;
216
+ if (parsedJson !== null) {
217
+ return {
218
+ success: true,
219
+ data: parsedJson,
220
+ };
221
+ }
222
+
223
+ const message = execution.stdout.trim().length > 0 ? execution.stdout.trim() : `${toolName} ran`;
224
+ return {
225
+ success: true,
226
+ data: {
227
+ message,
228
+ },
229
+ };
230
+ }
231
+
232
+ async function executeLifecycleTool(
233
+ toolName: LifecycleToolName,
234
+ args: string[],
235
+ options: RunOptions = {},
236
+ ): Promise<ToolOutput> {
237
+ const execution = await runLifecycleCommand(toolName, args);
238
+ if (!execution.ok) {
239
+ return createFailureOutput(toolName, execution);
240
+ }
241
+ return createSuccessOutput(toolName, execution, options);
242
+ }
243
+
244
+ function pushRepeatedFlag(args: string[], flag: string, values: string[]): void {
245
+ for (const value of values) {
246
+ args.push(flag, value);
247
+ }
248
+ }
249
+
250
+ function appendWuPromptArgs(parsed: Record<string, unknown>, args: string[]): void {
251
+ const client = toStringValue(parsed.client);
252
+ if (client) {
253
+ args.push('--client', client);
254
+ }
255
+ if (parsed.thinking === true) {
256
+ args.push('--thinking');
257
+ }
258
+ const budget = toIntegerString(parsed.budget);
259
+ if (budget) {
260
+ args.push('--budget', budget);
261
+ }
262
+ const parentWu = toStringValue(parsed.parent_wu);
263
+ if (parentWu) {
264
+ args.push('--parent-wu', parentWu);
265
+ }
266
+ if (parsed.no_context === true) {
267
+ args.push('--no-context');
268
+ }
269
+ }
270
+
271
+ export async function wuCreateTool(input: unknown): Promise<ToolOutput> {
272
+ const parsed = toRecord(input);
273
+ const lane = toStringValue(parsed.lane);
274
+ const title = toStringValue(parsed.title);
275
+ if (!lane) {
276
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.LANE_REQUIRED);
277
+ }
278
+ if (!title) {
279
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.TITLE_REQUIRED);
280
+ }
281
+
282
+ const args: string[] = ['--lane', lane, '--title', title];
283
+ const id = toStringValue(parsed.id);
284
+ if (id) {
285
+ args.push('--id', id);
286
+ }
287
+ const description = toStringValue(parsed.description);
288
+ if (description) {
289
+ args.push(LIFECYCLE_FLAGS.DESCRIPTION, description);
290
+ }
291
+ pushRepeatedFlag(args, '--acceptance', toStringArray(parsed.acceptance));
292
+ pushRepeatedFlag(args, LIFECYCLE_FLAGS.CODE_PATHS, toStringArray(parsed.code_paths));
293
+ const exposure = toStringValue(parsed.exposure);
294
+ if (exposure) {
295
+ args.push('--exposure', exposure);
296
+ }
297
+
298
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_CREATE, args);
299
+ }
300
+
301
+ export async function wuClaimTool(input: unknown): Promise<ToolOutput> {
302
+ const parsed = toRecord(input);
303
+ const id = toStringValue(parsed.id);
304
+ const lane = toStringValue(parsed.lane);
305
+ if (!id) {
306
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
307
+ }
308
+ if (!lane) {
309
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.LANE_REQUIRED);
310
+ }
311
+
312
+ const args: string[] = ['--id', id, '--lane', lane];
313
+ if (parsed.cloud === true) {
314
+ args.push('--cloud');
315
+ }
316
+ if (parsed.branch_only === true) {
317
+ args.push('--branch-only');
318
+ }
319
+ if (parsed.pr_mode === true) {
320
+ args.push('--pr-mode');
321
+ }
322
+ if (parsed.sandbox === true) {
323
+ const sandboxCommand = toStringArray(parsed.sandbox_command);
324
+ if (sandboxCommand.length === 0) {
325
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.SANDBOX_COMMAND_REQUIRED);
326
+ }
327
+ args.push('--sandbox', '--', ...sandboxCommand);
328
+ }
329
+
330
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_CLAIM, args);
331
+ }
332
+
333
+ export async function wuPrepTool(input: unknown): Promise<ToolOutput> {
334
+ const parsed = toRecord(input);
335
+ const id = toStringValue(parsed.id);
336
+ if (!id) {
337
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
338
+ }
339
+
340
+ const args = ['--id', id];
341
+ if (parsed.docs_only === true) {
342
+ args.push('--docs-only');
343
+ }
344
+ if (parsed.full_tests === true) {
345
+ args.push('--full-tests');
346
+ }
347
+
348
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_PREP, args);
349
+ }
350
+
351
+ export async function wuDoneTool(input: unknown): Promise<ToolOutput> {
352
+ const parsed = toRecord(input);
353
+ const id = toStringValue(parsed.id);
354
+ if (!id) {
355
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
356
+ }
357
+
358
+ const args = ['--id', id];
359
+ if (parsed.skip_gates === true) {
360
+ args.push('--skip-gates');
361
+ const reason = toStringValue(parsed.reason);
362
+ if (reason) {
363
+ args.push('--reason', reason);
364
+ }
365
+ const fixWu = toStringValue(parsed.fix_wu);
366
+ if (fixWu) {
367
+ args.push('--fix-wu', fixWu);
368
+ }
369
+ }
370
+
371
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_DONE, args);
372
+ }
373
+
374
+ export async function wuSandboxTool(input: unknown): Promise<ToolOutput> {
375
+ const parsed = toRecord(input);
376
+ const id = toStringValue(parsed.id);
377
+ if (!id) {
378
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
379
+ }
380
+
381
+ const command = toStringArray(parsed.command);
382
+ if (command.length === 0) {
383
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.COMMAND_REQUIRED);
384
+ }
385
+
386
+ const args: string[] = ['--id', id];
387
+ const worktree = toStringValue(parsed.worktree);
388
+ if (worktree) {
389
+ args.push('--worktree', worktree);
390
+ }
391
+ args.push('--', ...command);
392
+
393
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_SANDBOX, args);
394
+ }
395
+
396
+ export async function wuPruneTool(input: unknown): Promise<ToolOutput> {
397
+ const parsed = toRecord(input);
398
+ const args: string[] = [];
399
+ if (parsed.execute === true) {
400
+ args.push('--execute');
401
+ }
402
+
403
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_PRUNE, args);
404
+ }
405
+
406
+ export async function wuDeleteTool(input: unknown): Promise<ToolOutput> {
407
+ const parsed = toRecord(input);
408
+ const id = toStringValue(parsed.id);
409
+ const batch = toStringValue(parsed.batch);
410
+ if (!id && !batch) {
411
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
412
+ }
413
+
414
+ const args: string[] = [];
415
+ if (id) {
416
+ args.push('--id', id);
417
+ }
418
+ if (parsed.dry_run === true) {
419
+ args.push('--dry-run');
420
+ }
421
+ if (batch) {
422
+ args.push('--batch', batch);
423
+ }
424
+
425
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_DELETE, args);
426
+ }
427
+
428
+ export async function wuCleanupTool(input: unknown): Promise<ToolOutput> {
429
+ const parsed = toRecord(input);
430
+ const id = toStringValue(parsed.id);
431
+ if (!id) {
432
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
433
+ }
434
+
435
+ const args: string[] = ['--id', id];
436
+ if (parsed.artifacts === true) {
437
+ args.push('--artifacts');
438
+ }
439
+
440
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_CLEANUP, args);
441
+ }
442
+
443
+ export async function wuUnlockLaneTool(input: unknown): Promise<ToolOutput> {
444
+ const parsed = toRecord(input);
445
+ const listMode = parsed.list === true;
446
+ const lane = toStringValue(parsed.lane);
447
+ if (!listMode && !lane) {
448
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.LANE_REQUIRED);
449
+ }
450
+
451
+ const args: string[] = [];
452
+ if (lane) {
453
+ args.push('--lane', lane);
454
+ }
455
+ const reason = toStringValue(parsed.reason);
456
+ if (reason) {
457
+ args.push('--reason', reason);
458
+ }
459
+ if (parsed.force === true) {
460
+ args.push('--force');
461
+ }
462
+ if (listMode) {
463
+ args.push('--list');
464
+ }
465
+ if (parsed.status === true) {
466
+ args.push('--status');
467
+ }
468
+
469
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_UNLOCK_LANE, args);
470
+ }
471
+
472
+ export async function wuProtoTool(input: unknown): Promise<ToolOutput> {
473
+ const parsed = toRecord(input);
474
+ const lane = toStringValue(parsed.lane);
475
+ const title = toStringValue(parsed.title);
476
+ if (!lane) {
477
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.LANE_REQUIRED);
478
+ }
479
+ if (!title) {
480
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.TITLE_REQUIRED);
481
+ }
482
+
483
+ const args: string[] = ['--lane', lane, '--title', title];
484
+ const description = toStringValue(parsed.description);
485
+ if (description) {
486
+ args.push(LIFECYCLE_FLAGS.DESCRIPTION, description);
487
+ }
488
+ pushRepeatedFlag(args, LIFECYCLE_FLAGS.CODE_PATHS, toStringArray(parsed.code_paths));
489
+ const labels = toStringArray(parsed.labels);
490
+ if (labels.length > 0) {
491
+ args.push('--labels', labels.join(','));
492
+ }
493
+ const assignedTo = toStringValue(parsed.assigned_to);
494
+ if (assignedTo) {
495
+ args.push('--assigned-to', assignedTo);
496
+ }
497
+
498
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_PROTO, args);
499
+ }
500
+
501
+ export async function wuBriefTool(input: unknown): Promise<ToolOutput> {
502
+ const parsed = toRecord(input);
503
+ const id = toStringValue(parsed.id);
504
+ if (!id) {
505
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
506
+ }
507
+
508
+ const args: string[] = ['--id', id];
509
+ appendWuPromptArgs(parsed, args);
510
+
511
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_BRIEF, args);
512
+ }
513
+
514
+ export async function wuDelegateTool(input: unknown): Promise<ToolOutput> {
515
+ const parsed = toRecord(input);
516
+ const id = toStringValue(parsed.id);
517
+ const parentWu = toStringValue(parsed.parent_wu);
518
+ if (!id) {
519
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
520
+ }
521
+ if (!parentWu) {
522
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.PARENT_WU_REQUIRED);
523
+ }
524
+
525
+ const args: string[] = ['--id', id];
526
+ appendWuPromptArgs(parsed, args);
527
+
528
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_DELEGATE, args);
529
+ }
530
+
531
+ export async function wuDepsTool(input: unknown): Promise<ToolOutput> {
532
+ const parsed = toRecord(input);
533
+ const id = toStringValue(parsed.id);
534
+ if (!id) {
535
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
536
+ }
537
+
538
+ const args: string[] = ['--id', id];
539
+ const format = toStringValue(parsed.format);
540
+ if (format) {
541
+ args.push('--format', format);
542
+ }
543
+ const depth = toIntegerString(parsed.depth);
544
+ if (depth) {
545
+ args.push('--depth', depth);
546
+ }
547
+ const direction = toStringValue(parsed.direction);
548
+ if (direction) {
549
+ args.push('--direction', direction);
550
+ }
551
+
552
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_DEPS, args);
553
+ }
554
+
555
+ export async function wuEditTool(input: unknown): Promise<ToolOutput> {
556
+ const parsed = toRecord(input);
557
+ const id = toStringValue(parsed.id);
558
+ if (!id) {
559
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
560
+ }
561
+
562
+ const args: string[] = ['--id', id];
563
+ const description = toStringValue(parsed.description);
564
+ if (description) {
565
+ args.push(LIFECYCLE_FLAGS.DESCRIPTION, description);
566
+ }
567
+ pushRepeatedFlag(args, '--acceptance', toStringArray(parsed.acceptance));
568
+ const notes = toStringValue(parsed.notes);
569
+ if (notes) {
570
+ args.push('--notes', notes);
571
+ }
572
+ pushRepeatedFlag(args, LIFECYCLE_FLAGS.CODE_PATHS, toStringArray(parsed.code_paths));
573
+ const lane = toStringValue(parsed.lane);
574
+ if (lane) {
575
+ args.push('--lane', lane);
576
+ }
577
+ const priority = toStringValue(parsed.priority);
578
+ if (priority) {
579
+ args.push('--priority', priority);
580
+ }
581
+ const initiative = toStringValue(parsed.initiative);
582
+ if (initiative) {
583
+ args.push('--initiative', initiative);
584
+ }
585
+ const phase = toIntegerString(parsed.phase);
586
+ if (phase) {
587
+ args.push('--phase', phase);
588
+ }
589
+ if (parsed.no_strict === true) {
590
+ args.push('--no-strict');
591
+ }
592
+
593
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_EDIT, args);
594
+ }
595
+
596
+ export async function wuBlockTool(input: unknown): Promise<ToolOutput> {
597
+ const parsed = toRecord(input);
598
+ const id = toStringValue(parsed.id);
599
+ const reason = toStringValue(parsed.reason);
600
+ if (!id) {
601
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
602
+ }
603
+ if (!reason) {
604
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.REASON_REQUIRED);
605
+ }
606
+
607
+ const args = ['--id', id, '--reason', reason];
608
+ if (parsed.remove_worktree === true) {
609
+ args.push('--remove-worktree');
610
+ }
611
+
612
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_BLOCK, args);
613
+ }
614
+
615
+ export async function wuUnblockTool(input: unknown): Promise<ToolOutput> {
616
+ const parsed = toRecord(input);
617
+ const id = toStringValue(parsed.id);
618
+ if (!id) {
619
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
620
+ }
621
+
622
+ const args = ['--id', id];
623
+ const reason = toStringValue(parsed.reason);
624
+ if (reason) {
625
+ args.push('--reason', reason);
626
+ }
627
+ if (parsed.create_worktree === true) {
628
+ args.push('--create-worktree');
629
+ }
630
+
631
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_UNBLOCK, args);
632
+ }
633
+
634
+ export async function wuReleaseTool(input: unknown): Promise<ToolOutput> {
635
+ const parsed = toRecord(input);
636
+ const id = toStringValue(parsed.id);
637
+ if (!id) {
638
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
639
+ }
640
+
641
+ const args = ['--id', id];
642
+ const reason = toStringValue(parsed.reason);
643
+ if (reason) {
644
+ args.push('--reason', reason);
645
+ }
646
+
647
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_RELEASE, args);
648
+ }
649
+
650
+ export async function wuRecoverTool(input: unknown): Promise<ToolOutput> {
651
+ const parsed = toRecord(input);
652
+ const id = toStringValue(parsed.id);
653
+ if (!id) {
654
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
655
+ }
656
+
657
+ const args = ['--id', id];
658
+ const action = toStringValue(parsed.action);
659
+ if (action) {
660
+ args.push('--action', action);
661
+ }
662
+ if (parsed.force === true) {
663
+ args.push('--force');
664
+ }
665
+ if (parsed.json === true) {
666
+ args.push('--json');
667
+ }
668
+
669
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_RECOVER, args, {
670
+ parseJson: parsed.json === true,
671
+ });
672
+ }
673
+
674
+ export async function wuRepairTool(input: unknown): Promise<ToolOutput> {
675
+ const parsed = toRecord(input);
676
+
677
+ const args: string[] = [];
678
+ const id = toStringValue(parsed.id);
679
+ if (id) {
680
+ args.push('--id', id);
681
+ }
682
+ if (parsed.check === true) {
683
+ args.push('--check');
684
+ }
685
+ if (parsed.all === true) {
686
+ args.push('--all');
687
+ }
688
+ if (parsed.claim === true) {
689
+ args.push('--claim');
690
+ }
691
+ if (parsed.admin === true) {
692
+ args.push('--admin');
693
+ }
694
+ if (parsed.repair_state === true) {
695
+ args.push('--repair-state');
696
+ }
697
+
698
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_REPAIR, args);
699
+ }
700
+
701
+ export async function wuStatusTool(input: unknown): Promise<ToolOutput> {
702
+ const parsed = toRecord(input);
703
+ const id = toStringValue(parsed.id);
704
+ if (!id) {
705
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
706
+ }
707
+
708
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_STATUS, ['--id', id, '--json'], {
709
+ parseJson: true,
710
+ });
711
+ }
712
+
713
+ export async function wuPreflightTool(input: unknown): Promise<ToolOutput> {
714
+ const parsed = toRecord(input);
715
+ const id = toStringValue(parsed.id);
716
+ if (!id) {
717
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
718
+ }
719
+
720
+ const args = ['--id', id];
721
+ const worktree = toStringValue(parsed.worktree);
722
+ if (worktree) {
723
+ args.push('--worktree', worktree);
724
+ }
725
+
726
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_PREFLIGHT, args);
727
+ }
728
+
729
+ export async function wuValidateTool(input: unknown): Promise<ToolOutput> {
730
+ const parsed = toRecord(input);
731
+ const id = toStringValue(parsed.id);
732
+ if (!id) {
733
+ return createMissingParameterOutput(MISSING_PARAMETER_MESSAGES.ID_REQUIRED);
734
+ }
735
+
736
+ const args = ['--id', id];
737
+ if (parsed.no_strict === true) {
738
+ args.push('--no-strict');
739
+ }
740
+
741
+ return executeLifecycleTool(LIFECYCLE_TOOLS.WU_VALIDATE, args);
742
+ }
743
+
744
+ export async function gatesTool(input: unknown): Promise<ToolOutput> {
745
+ const parsed = toRecord(input);
746
+ const args: string[] = [];
747
+ if (parsed.docs_only === true) {
748
+ args.push('--docs-only');
749
+ }
750
+ if (parsed.full_lint === true) {
751
+ args.push('--full-lint');
752
+ }
753
+ const coverageMode = toStringValue(parsed.coverage_mode);
754
+ if (coverageMode) {
755
+ args.push('--coverage-mode', coverageMode);
756
+ }
757
+
758
+ return executeLifecycleTool(LIFECYCLE_TOOLS.GATES, args);
759
+ }