@wrongstack/tools 0.284.1 → 0.286.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/README.md +19 -0
  2. package/dist/_concurrency.d.ts +16 -0
  3. package/dist/_concurrency.d.ts.map +1 -0
  4. package/dist/_danger-detect.d.ts +54 -0
  5. package/dist/_danger-detect.d.ts.map +1 -0
  6. package/dist/_edit-match.d.ts +86 -0
  7. package/dist/_edit-match.d.ts.map +1 -0
  8. package/dist/_env.d.ts +6 -0
  9. package/dist/_env.d.ts.map +1 -0
  10. package/dist/_fetch-guard.d.ts +31 -0
  11. package/dist/_fetch-guard.d.ts.map +1 -0
  12. package/dist/_output-spool.d.ts +38 -0
  13. package/dist/_output-spool.d.ts.map +1 -0
  14. package/dist/_redact-command.d.ts +6 -0
  15. package/dist/_redact-command.d.ts.map +1 -0
  16. package/dist/_regex.d.ts +39 -0
  17. package/dist/_regex.d.ts.map +1 -0
  18. package/dist/_session-shell.d.ts +73 -0
  19. package/dist/_session-shell.d.ts.map +1 -0
  20. package/dist/_shell-pick.d.ts +158 -0
  21. package/dist/_shell-pick.d.ts.map +1 -0
  22. package/dist/_spawn-stream.d.ts +32 -0
  23. package/dist/_spawn-stream.d.ts.map +1 -0
  24. package/dist/_syntax-check.d.ts +16 -0
  25. package/dist/_syntax-check.d.ts.map +1 -0
  26. package/dist/_util.d.ts +68 -0
  27. package/dist/_util.d.ts.map +1 -0
  28. package/dist/_win32-resolve.d.ts +42 -0
  29. package/dist/_win32-resolve.d.ts.map +1 -0
  30. package/dist/audit.d.ts +4 -5
  31. package/dist/audit.d.ts.map +1 -0
  32. package/dist/audit.js +2743 -28
  33. package/dist/audit.js.map +7 -1
  34. package/dist/bash-kill-guard.d.ts +62 -0
  35. package/dist/bash-kill-guard.d.ts.map +1 -0
  36. package/dist/bash.d.ts +4 -5
  37. package/dist/bash.d.ts.map +1 -0
  38. package/dist/bash.js +59 -30
  39. package/dist/bash.js.map +7 -1
  40. package/dist/batch-tool-use.d.ts +4 -5
  41. package/dist/batch-tool-use.d.ts.map +1 -0
  42. package/dist/batch-tool-use.js +3 -3
  43. package/dist/batch-tool-use.js.map +7 -1
  44. package/dist/browser/artifacts.d.ts +13 -0
  45. package/dist/browser/artifacts.d.ts.map +1 -0
  46. package/dist/browser/index.d.ts +7 -0
  47. package/dist/browser/index.d.ts.map +1 -0
  48. package/dist/browser/index.js +1264 -0
  49. package/dist/browser/index.js.map +7 -0
  50. package/dist/browser/manager.d.ts +57 -0
  51. package/dist/browser/manager.d.ts.map +1 -0
  52. package/dist/browser/network-guard-proxy.d.ts +23 -0
  53. package/dist/browser/network-guard-proxy.d.ts.map +1 -0
  54. package/dist/browser/security.d.ts +29 -0
  55. package/dist/browser/security.d.ts.map +1 -0
  56. package/dist/browser/tools.d.ts +62 -0
  57. package/dist/browser/tools.d.ts.map +1 -0
  58. package/dist/browser/types.d.ts +60 -0
  59. package/dist/browser/types.d.ts.map +1 -0
  60. package/dist/builtin.d.ts +11 -12
  61. package/dist/builtin.d.ts.map +1 -0
  62. package/dist/builtin.js +8099 -2178
  63. package/dist/builtin.js.map +7 -1
  64. package/dist/circuit-breaker.d.ts +4 -5
  65. package/dist/circuit-breaker.d.ts.map +1 -0
  66. package/dist/circuit-breaker.js +3 -3
  67. package/dist/circuit-breaker.js.map +7 -1
  68. package/dist/codebase-index/background-indexer.d.ts +116 -0
  69. package/dist/codebase-index/background-indexer.d.ts.map +1 -0
  70. package/dist/codebase-index/bm25.d.ts +40 -0
  71. package/dist/codebase-index/bm25.d.ts.map +1 -0
  72. package/dist/codebase-index/circuit-breaker.d.ts +94 -0
  73. package/dist/codebase-index/circuit-breaker.d.ts.map +1 -0
  74. package/dist/codebase-index/codebase-index-tool.d.ts +17 -0
  75. package/dist/codebase-index/codebase-index-tool.d.ts.map +1 -0
  76. package/dist/codebase-index/codebase-search-tool.d.ts +43 -0
  77. package/dist/codebase-index/codebase-search-tool.d.ts.map +1 -0
  78. package/dist/codebase-index/codebase-stats-tool.d.ts +23 -0
  79. package/dist/codebase-index/codebase-stats-tool.d.ts.map +1 -0
  80. package/dist/codebase-index/gitignore.d.ts +22 -0
  81. package/dist/codebase-index/gitignore.d.ts.map +1 -0
  82. package/dist/codebase-index/go-parser.d.ts +16 -0
  83. package/dist/codebase-index/go-parser.d.ts.map +1 -0
  84. package/dist/codebase-index/index-service.d.ts +25 -0
  85. package/dist/codebase-index/index-service.d.ts.map +1 -0
  86. package/dist/codebase-index/index.d.ts +23 -271
  87. package/dist/codebase-index/index.d.ts.map +1 -0
  88. package/dist/codebase-index/index.js +136 -68
  89. package/dist/codebase-index/index.js.map +7 -1
  90. package/dist/codebase-index/indexer.d.ts +28 -0
  91. package/dist/codebase-index/indexer.d.ts.map +1 -0
  92. package/dist/codebase-index/json-parser.d.ts +8 -0
  93. package/dist/codebase-index/json-parser.d.ts.map +1 -0
  94. package/dist/codebase-index/lsp-kind.d.ts +53 -0
  95. package/dist/codebase-index/lsp-kind.d.ts.map +1 -0
  96. package/dist/codebase-index/py-parser.d.ts +16 -0
  97. package/dist/codebase-index/py-parser.d.ts.map +1 -0
  98. package/dist/codebase-index/refs-extractor.d.ts +25 -0
  99. package/dist/codebase-index/refs-extractor.d.ts.map +1 -0
  100. package/dist/codebase-index/rs-parser.d.ts +8 -0
  101. package/dist/codebase-index/rs-parser.d.ts.map +1 -0
  102. package/dist/codebase-index/schema.d.ts +82 -0
  103. package/dist/codebase-index/schema.d.ts.map +1 -0
  104. package/dist/codebase-index/ts-parser.d.ts +30 -0
  105. package/dist/codebase-index/ts-parser.d.ts.map +1 -0
  106. package/dist/codebase-index/worker-protocol.d.ts +77 -0
  107. package/dist/codebase-index/worker-protocol.d.ts.map +1 -0
  108. package/dist/codebase-index/worker.d.ts +16 -2
  109. package/dist/codebase-index/worker.d.ts.map +1 -0
  110. package/dist/codebase-index/worker.js +103 -65
  111. package/dist/codebase-index/worker.js.map +7 -1
  112. package/dist/codebase-index/writer.d.ts +189 -0
  113. package/dist/codebase-index/writer.d.ts.map +1 -0
  114. package/dist/codebase-index/yaml-parser.d.ts +8 -0
  115. package/dist/codebase-index/yaml-parser.d.ts.map +1 -0
  116. package/dist/design.d.ts +38 -0
  117. package/dist/design.d.ts.map +1 -0
  118. package/dist/design.js +270 -0
  119. package/dist/design.js.map +7 -0
  120. package/dist/diff.d.ts +4 -5
  121. package/dist/diff.d.ts.map +1 -0
  122. package/dist/diff.js +14 -12
  123. package/dist/diff.js.map +7 -1
  124. package/dist/document.d.ts +4 -5
  125. package/dist/document.d.ts.map +1 -0
  126. package/dist/document.js +8 -7
  127. package/dist/document.js.map +7 -1
  128. package/dist/e2e.d.ts +56 -0
  129. package/dist/e2e.d.ts.map +1 -0
  130. package/dist/edit.d.ts +5 -36
  131. package/dist/edit.d.ts.map +1 -0
  132. package/dist/edit.js +28 -16
  133. package/dist/edit.js.map +7 -1
  134. package/dist/exec.d.ts +67 -2
  135. package/dist/exec.d.ts.map +1 -0
  136. package/dist/exec.js +51 -26
  137. package/dist/exec.js.map +7 -1
  138. package/dist/fetch.d.ts +4 -32
  139. package/dist/fetch.d.ts.map +1 -0
  140. package/dist/fetch.js +89 -77
  141. package/dist/fetch.js.map +7 -1
  142. package/dist/format.d.ts +4 -5
  143. package/dist/format.d.ts.map +1 -0
  144. package/dist/format.js +2415 -28
  145. package/dist/format.js.map +7 -1
  146. package/dist/git.d.ts +4 -5
  147. package/dist/git.d.ts.map +1 -0
  148. package/dist/git.js +10 -9
  149. package/dist/git.js.map +7 -1
  150. package/dist/glob.d.ts +4 -5
  151. package/dist/glob.d.ts.map +1 -0
  152. package/dist/glob.js +15 -12
  153. package/dist/glob.js.map +7 -1
  154. package/dist/grep.d.ts +4 -5
  155. package/dist/grep.d.ts.map +1 -0
  156. package/dist/grep.js +13 -10
  157. package/dist/grep.js.map +7 -1
  158. package/dist/index.d.ts +21 -724
  159. package/dist/index.d.ts.map +1 -0
  160. package/dist/index.js +8955 -2866
  161. package/dist/index.js.map +7 -1
  162. package/dist/install.d.ts +4 -5
  163. package/dist/install.d.ts.map +1 -0
  164. package/dist/install.js +2680 -31
  165. package/dist/install.js.map +7 -1
  166. package/dist/json.d.ts +4 -5
  167. package/dist/json.d.ts.map +1 -0
  168. package/dist/json.js +13 -11
  169. package/dist/json.js.map +7 -1
  170. package/dist/kanban.d.ts +107 -0
  171. package/dist/kanban.d.ts.map +1 -0
  172. package/dist/kanban.js +845 -0
  173. package/dist/kanban.js.map +7 -0
  174. package/dist/languages/detect.d.ts +3 -0
  175. package/dist/languages/detect.d.ts.map +1 -0
  176. package/dist/languages/diagnostics.d.ts +15 -0
  177. package/dist/languages/diagnostics.d.ts.map +1 -0
  178. package/dist/languages/execute-tool.d.ts +34 -0
  179. package/dist/languages/execute-tool.d.ts.map +1 -0
  180. package/dist/languages/execute.d.ts +18 -0
  181. package/dist/languages/execute.d.ts.map +1 -0
  182. package/dist/languages/index.d.ts +12 -0
  183. package/dist/languages/index.d.ts.map +1 -0
  184. package/dist/languages/index.js +4457 -0
  185. package/dist/languages/index.js.map +7 -0
  186. package/dist/languages/legacy-bridge.d.ts +29 -0
  187. package/dist/languages/legacy-bridge.d.ts.map +1 -0
  188. package/dist/languages/package-tool.d.ts +29 -0
  189. package/dist/languages/package-tool.d.ts.map +1 -0
  190. package/dist/languages/plan.d.ts +4 -0
  191. package/dist/languages/plan.d.ts.map +1 -0
  192. package/dist/languages/profile-helpers.d.ts +14 -0
  193. package/dist/languages/profile-helpers.d.ts.map +1 -0
  194. package/dist/languages/profiles/additional.d.ts +3 -0
  195. package/dist/languages/profiles/additional.d.ts.map +1 -0
  196. package/dist/languages/profiles/primary.d.ts +3 -0
  197. package/dist/languages/profiles/primary.d.ts.map +1 -0
  198. package/dist/languages/registry.d.ts +11 -0
  199. package/dist/languages/registry.d.ts.map +1 -0
  200. package/dist/languages/tool.d.ts +32 -0
  201. package/dist/languages/tool.d.ts.map +1 -0
  202. package/dist/languages/types.d.ts +207 -0
  203. package/dist/languages/types.d.ts.map +1 -0
  204. package/dist/lint.d.ts +4 -5
  205. package/dist/lint.d.ts.map +1 -0
  206. package/dist/lint.js +2415 -27
  207. package/dist/lint.js.map +7 -1
  208. package/dist/logs.d.ts +4 -5
  209. package/dist/logs.d.ts.map +1 -0
  210. package/dist/logs.js +16 -10
  211. package/dist/logs.js.map +7 -1
  212. package/dist/memory.d.ts +7 -8
  213. package/dist/memory.d.ts.map +1 -0
  214. package/dist/memory.js +7 -5
  215. package/dist/memory.js.map +7 -1
  216. package/dist/mode.d.ts +4 -5
  217. package/dist/mode.d.ts.map +1 -0
  218. package/dist/mode.js +3 -3
  219. package/dist/mode.js.map +7 -1
  220. package/dist/next-steps.d.ts +5 -6
  221. package/dist/next-steps.d.ts.map +1 -0
  222. package/dist/next-steps.js +5 -4
  223. package/dist/next-steps.js.map +7 -1
  224. package/dist/outdated.d.ts +4 -5
  225. package/dist/outdated.d.ts.map +1 -0
  226. package/dist/outdated.js +4777 -68
  227. package/dist/outdated.js.map +7 -1
  228. package/dist/pack.d.ts +3 -6
  229. package/dist/pack.d.ts.map +1 -0
  230. package/dist/pack.js +8134 -2204
  231. package/dist/pack.js.map +7 -1
  232. package/dist/patch.d.ts +4 -5
  233. package/dist/patch.d.ts.map +1 -0
  234. package/dist/patch.js +18 -16
  235. package/dist/patch.js.map +7 -1
  236. package/dist/plan.d.ts +55 -0
  237. package/dist/plan.d.ts.map +1 -0
  238. package/dist/plan.js +280 -0
  239. package/dist/plan.js.map +7 -0
  240. package/dist/process-guardian.d.ts +100 -0
  241. package/dist/process-guardian.d.ts.map +1 -0
  242. package/dist/process-registry-persistent.d.ts +121 -0
  243. package/dist/process-registry-persistent.d.ts.map +1 -0
  244. package/dist/process-registry.d.ts +13 -17
  245. package/dist/process-registry.d.ts.map +1 -0
  246. package/dist/process-registry.js +15 -9
  247. package/dist/process-registry.js.map +7 -1
  248. package/dist/ps-slash.d.ts +106 -0
  249. package/dist/ps-slash.d.ts.map +1 -0
  250. package/dist/ps-slash.js +1291 -0
  251. package/dist/ps-slash.js.map +7 -0
  252. package/dist/read.d.ts +4 -5
  253. package/dist/read.d.ts.map +1 -0
  254. package/dist/read.js +13 -11
  255. package/dist/read.js.map +7 -1
  256. package/dist/replace.d.ts +4 -5
  257. package/dist/replace.d.ts.map +1 -0
  258. package/dist/replace.js +26 -13
  259. package/dist/replace.js.map +7 -1
  260. package/dist/scaffold.d.ts +4 -5
  261. package/dist/scaffold.d.ts.map +1 -0
  262. package/dist/scaffold.js +16 -14
  263. package/dist/scaffold.js.map +7 -1
  264. package/dist/search.d.ts +5 -6
  265. package/dist/search.d.ts.map +1 -0
  266. package/dist/search.js +32 -27
  267. package/dist/search.js.map +7 -1
  268. package/dist/set-working-dir.d.ts +18 -0
  269. package/dist/set-working-dir.d.ts.map +1 -0
  270. package/dist/shim/node-sqlite.d.ts +3 -0
  271. package/dist/shim/node-sqlite.d.ts.map +1 -0
  272. package/dist/skill.d.ts +45 -0
  273. package/dist/skill.d.ts.map +1 -0
  274. package/dist/skill.js +175 -0
  275. package/dist/skill.js.map +7 -0
  276. package/dist/spawn-background.d.ts +80 -0
  277. package/dist/spawn-background.d.ts.map +1 -0
  278. package/dist/task.d.ts +35 -0
  279. package/dist/task.d.ts.map +1 -0
  280. package/dist/task.js +380 -0
  281. package/dist/task.js.map +7 -0
  282. package/dist/test.d.ts +4 -5
  283. package/dist/test.d.ts.map +1 -0
  284. package/dist/test.js +2419 -27
  285. package/dist/test.js.map +7 -1
  286. package/dist/todo.d.ts +4 -5
  287. package/dist/todo.d.ts.map +1 -0
  288. package/dist/todo.js +5 -5
  289. package/dist/todo.js.map +7 -1
  290. package/dist/tool-diff.d.ts +16 -17
  291. package/dist/tool-diff.d.ts.map +1 -0
  292. package/dist/tool-diff.js +11 -3
  293. package/dist/tool-diff.js.map +7 -1
  294. package/dist/tool-help.d.ts +4 -5
  295. package/dist/tool-help.d.ts.map +1 -0
  296. package/dist/tool-help.js +3 -3
  297. package/dist/tool-help.js.map +7 -1
  298. package/dist/tool-icon-map.d.ts +46 -0
  299. package/dist/tool-icon-map.d.ts.map +1 -0
  300. package/dist/tool-icons.d.ts +5 -6
  301. package/dist/tool-icons.d.ts.map +1 -0
  302. package/dist/tool-icons.js +16 -4
  303. package/dist/tool-icons.js.map +7 -1
  304. package/dist/tool-search.d.ts +4 -5
  305. package/dist/tool-search.d.ts.map +1 -0
  306. package/dist/tool-search.js +3 -3
  307. package/dist/tool-search.js.map +7 -1
  308. package/dist/tool-summary.d.ts +4 -5
  309. package/dist/tool-summary.d.ts.map +1 -0
  310. package/dist/tool-summary.js +5 -3
  311. package/dist/tool-summary.js.map +7 -1
  312. package/dist/tool-use.d.ts +4 -5
  313. package/dist/tool-use.d.ts.map +1 -0
  314. package/dist/tool-use.js +3 -3
  315. package/dist/tool-use.js.map +7 -1
  316. package/dist/tree.d.ts +4 -5
  317. package/dist/tree.d.ts.map +1 -0
  318. package/dist/tree.js +11 -9
  319. package/dist/tree.js.map +7 -1
  320. package/dist/typecheck.d.ts +4 -5
  321. package/dist/typecheck.d.ts.map +1 -0
  322. package/dist/typecheck.js +2416 -28
  323. package/dist/typecheck.js.map +7 -1
  324. package/dist/write.d.ts +4 -5
  325. package/dist/write.d.ts.map +1 -0
  326. package/dist/write.js +21 -16
  327. package/dist/write.js.map +7 -1
  328. package/package.json +39 -6
  329. package/dist/background-indexer-BeDBxfSh.d.ts +0 -371
  330. package/dist/exec-2OKoT6tk.d.ts +0 -121
package/dist/kanban.js ADDED
@@ -0,0 +1,845 @@
1
+ // src/kanban.ts
2
+ import { deserializeTaskGraph, serializeTaskGraph } from "@wrongstack/core";
3
+ import {
4
+ addCheckToTask,
5
+ addColumn,
6
+ addDependency,
7
+ addGoalMetricToTask,
8
+ addLinkToTask,
9
+ addNoteToTask,
10
+ addTask,
11
+ assignTask,
12
+ claimReadyTask,
13
+ copyTaskToBoard,
14
+ createBoard,
15
+ duplicateBoard,
16
+ exportBoardAsMarkdown,
17
+ exportBoardToTaskGraph,
18
+ generateBoardFromDescription,
19
+ getBoard,
20
+ getKanbanOrchestrationSnapshot,
21
+ getKanbanQueueHealth,
22
+ getTask,
23
+ getTaskChain,
24
+ heartbeatTaskAssignment,
25
+ listBoards,
26
+ listKanbanEvents,
27
+ listReadyTasks,
28
+ mergeTasks,
29
+ moveTask,
30
+ parseLinesIntoTasks,
31
+ recoverStaleTaskAssignments,
32
+ releaseTaskClaim,
33
+ removeBoard,
34
+ removeColumn,
35
+ removeTask,
36
+ searchKanban,
37
+ setTaskChain,
38
+ splitTask,
39
+ syncBoardFromTaskGraph,
40
+ transferTaskToBoard,
41
+ updateBoard,
42
+ updateCheckOnTask,
43
+ updateColumn,
44
+ updateGoalMetricOnTask,
45
+ updateTask,
46
+ updateTaskAssignment
47
+ } from "@wrongstack/kanban";
48
+ var kanbanTool = {
49
+ name: "kanban",
50
+ category: "Project",
51
+ description: "Manage project-scoped multi-kanban boards stored under .wrongstack/kanbans. Supports board/task/column CRUD, ready-task queues, dependency chains, split/merge, assignment metadata, provider/model/fallback routing hints, goal metrics, success checks, notes, links, and run status updates.",
52
+ usageHint: "Use this for durable project kanban state. Agents should call snapshot/ready_tasks, then claim_task before working. Use set_chain for ordered work, split_task/merge_tasks when task scope changes, assign_task with provider/model/fallback hints before spawning, mark_assignment when starting or finishing, and release_task if the claim cannot be worked.",
53
+ permission: "confirm",
54
+ mutating: true,
55
+ capabilities: ["fs.write"],
56
+ icon: "task",
57
+ timeoutMs: 5e3,
58
+ inputSchema: {
59
+ type: "object",
60
+ properties: {
61
+ action: {
62
+ type: "string",
63
+ enum: [
64
+ "list_boards",
65
+ "get_board",
66
+ "create_board",
67
+ "duplicate_board",
68
+ "update_board",
69
+ "delete_board",
70
+ "generate_board",
71
+ "export_markdown",
72
+ "export_task_graph",
73
+ "sync_task_graph",
74
+ "search_tasks",
75
+ "ready_tasks",
76
+ "snapshot",
77
+ "add_column",
78
+ "update_column",
79
+ "delete_column",
80
+ "add_task",
81
+ "split_task",
82
+ "merge_tasks",
83
+ "copy_task",
84
+ "transfer_task",
85
+ "get_task",
86
+ "update_task",
87
+ "move_task",
88
+ "delete_task",
89
+ "set_chain",
90
+ "get_chain",
91
+ "claim_task",
92
+ "release_task",
93
+ "assign_task",
94
+ "mark_assignment",
95
+ "heartbeat_assignment",
96
+ "recover_stale",
97
+ "events",
98
+ "queue_health",
99
+ "add_dependency",
100
+ "add_goal_metric",
101
+ "update_goal_metric",
102
+ "add_check",
103
+ "update_check",
104
+ "add_note",
105
+ "add_link"
106
+ ]
107
+ },
108
+ boardId: { type: "string" },
109
+ taskId: { type: "string" },
110
+ taskIds: { type: "array", items: { type: "string" } },
111
+ chainId: { type: "string" },
112
+ columnId: { type: "string" },
113
+ targetBoardId: { type: "string" },
114
+ targetColumnId: { type: "string" },
115
+ title: { type: "string" },
116
+ description: { type: "string" },
117
+ tags: { type: "array", items: { type: "string" } },
118
+ labels: { type: "array", items: { type: "string" } },
119
+ priority: { type: "string", enum: ["critical", "high", "medium", "low"] },
120
+ status: {
121
+ type: "string",
122
+ enum: [
123
+ "pending",
124
+ "ready",
125
+ "in_progress",
126
+ "blocked",
127
+ "review",
128
+ "completed",
129
+ "failed",
130
+ "archived"
131
+ ]
132
+ },
133
+ order: { type: "number" },
134
+ query: { type: "string" },
135
+ limit: { type: "number" },
136
+ agentId: { type: "string" },
137
+ name: { type: "string" },
138
+ role: { type: "string" },
139
+ provider: { type: "string" },
140
+ model: { type: "string" },
141
+ fallbackProfile: { type: "string" },
142
+ fallbackModels: { type: "array", items: { type: "string" } },
143
+ tools: { type: "array", items: { type: "string" } },
144
+ allowedCapabilities: { type: "array", items: { type: "string" } },
145
+ leaseId: { type: "string" },
146
+ claimedAt: { type: "string" },
147
+ heartbeatAt: { type: "string" },
148
+ leaseExpiresAt: { type: "string" },
149
+ attempt: { type: "number" },
150
+ maxAttempts: { type: "number" },
151
+ subagentId: { type: "string" },
152
+ runTaskId: { type: "string" },
153
+ lastResult: { type: "string" },
154
+ error: { type: "string" },
155
+ assignmentStatus: {
156
+ type: "string",
157
+ enum: ["assigned", "queued", "running", "completed", "failed", "cancelled"]
158
+ },
159
+ releaseStatus: { type: "string", enum: ["pending", "ready", "blocked"] },
160
+ releaseReason: { type: "string" },
161
+ clearAssignee: { type: "boolean" },
162
+ recoveryMode: { type: "string", enum: ["release", "retry", "fail"] },
163
+ recoveryNow: { type: "string" },
164
+ taskGraph: { type: "object" },
165
+ graphId: { type: "string" },
166
+ specId: { type: "string" },
167
+ sourceSystem: { type: "string" },
168
+ phaseId: { type: "string" },
169
+ preserveOriginTaskIds: { type: "boolean" },
170
+ includeArchived: { type: "boolean" },
171
+ archiveMissingTasks: { type: "boolean" },
172
+ preserveManualDependencies: { type: "boolean" },
173
+ dependencyTaskId: { type: "string" },
174
+ enforceDependencies: { type: "boolean" },
175
+ childTitles: { type: "array", items: { type: "string" } },
176
+ inheritAssignment: { type: "boolean" },
177
+ inheritLabels: { type: "boolean" },
178
+ inheritSuccessCriteria: { type: "boolean" },
179
+ inheritGoalMetrics: { type: "boolean" },
180
+ inheritDependencies: { type: "boolean" },
181
+ chainChildren: { type: "boolean" },
182
+ rewireDependents: { type: "boolean" },
183
+ closeSourceTasks: { type: "boolean" },
184
+ metricId: { type: "string" },
185
+ metricName: { type: "string" },
186
+ metricTarget: { oneOf: [{ type: "string" }, { type: "number" }] },
187
+ metricCurrent: { oneOf: [{ type: "string" }, { type: "number" }] },
188
+ metricUnit: { type: "string" },
189
+ metricStatus: { type: "string", enum: ["pending", "met", "missed", "waived"] },
190
+ metricNotes: { type: "string" },
191
+ checkId: { type: "string" },
192
+ checkDescription: { type: "string" },
193
+ checkStatus: { type: "string", enum: ["pending", "passed", "failed", "skipped"] },
194
+ note: { type: "string" },
195
+ author: { type: "string" },
196
+ url: { type: "string" },
197
+ linkTitle: { type: "string" },
198
+ linkType: {
199
+ type: "string",
200
+ enum: ["issue", "pr", "doc", "commit", "design", "file", "url", "other"]
201
+ },
202
+ context: { type: "string" },
203
+ columns: { type: "array", items: { type: "string" } },
204
+ generatedBy: { type: "string" },
205
+ includeTasks: { type: "boolean" },
206
+ includeCompletedTasks: { type: "boolean" },
207
+ preserveAssignment: { type: "boolean" },
208
+ preserveDependencies: { type: "boolean" },
209
+ moveTasksToColumnId: { type: "string" }
210
+ },
211
+ required: ["action"]
212
+ },
213
+ async execute(input, ctx) {
214
+ const projectRoot = ctx.projectRoot;
215
+ if (!projectRoot) return fail("No project root is available.");
216
+ try {
217
+ switch (input.action) {
218
+ case "list_boards": {
219
+ const boards = await listBoards(projectRoot);
220
+ return { ok: true, message: `${boards.length} board(s).`, boards };
221
+ }
222
+ case "get_board": {
223
+ const board = await requireBoard(projectRoot, input.boardId);
224
+ return board ? okBoard(board) : fail("Board not found.");
225
+ }
226
+ case "create_board": {
227
+ if (!input.title) return fail("create_board requires title.");
228
+ const board = await createBoard(projectRoot, {
229
+ title: input.title,
230
+ ...input.description !== void 0 ? { description: input.description } : {},
231
+ ...input.tags !== void 0 ? { tags: input.tags } : {},
232
+ ...input.generatedBy !== void 0 ? { generatedBy: input.generatedBy } : {}
233
+ });
234
+ return { ok: true, message: `Board created: ${board.title}`, board };
235
+ }
236
+ case "update_board": {
237
+ if (!input.boardId) return fail("update_board requires boardId.");
238
+ const board = await updateBoard(projectRoot, input.boardId, {
239
+ ...input.title !== void 0 ? { title: input.title } : {},
240
+ ...input.description !== void 0 ? { description: input.description } : {},
241
+ ...input.tags !== void 0 ? { tags: input.tags } : {}
242
+ });
243
+ return board ? okBoard(board, "Board updated.") : fail("Board not found.");
244
+ }
245
+ case "duplicate_board": {
246
+ if (!input.boardId) return fail("duplicate_board requires boardId.");
247
+ const board = await duplicateBoard(projectRoot, input.boardId, {
248
+ ...input.title !== void 0 ? { title: input.title } : {},
249
+ ...input.generatedBy !== void 0 ? { generatedBy: input.generatedBy } : {},
250
+ ...input.includeTasks !== void 0 ? { includeTasks: input.includeTasks } : {},
251
+ ...input.includeCompletedTasks !== void 0 ? { includeCompletedTasks: input.includeCompletedTasks } : {},
252
+ ...input.preserveAssignment !== void 0 ? { preserveAssignment: input.preserveAssignment } : {}
253
+ });
254
+ return board ? okBoard(board, "Board duplicated.") : fail("Board not found.");
255
+ }
256
+ case "delete_board": {
257
+ if (!input.boardId) return fail("delete_board requires boardId.");
258
+ const removed = await removeBoard(projectRoot, input.boardId);
259
+ return { ok: removed, message: removed ? "Board deleted." : "Board not found." };
260
+ }
261
+ case "generate_board": {
262
+ if (!input.description) return fail("generate_board requires description.");
263
+ const boardInput = generateBoardFromDescription({
264
+ description: input.description,
265
+ ...input.title !== void 0 ? { title: input.title } : {},
266
+ ...input.context !== void 0 ? { context: input.context } : {},
267
+ ...input.columns !== void 0 ? { columns: input.columns } : {}
268
+ });
269
+ const board = await createBoard(projectRoot, boardInput);
270
+ for (const taskInput2 of parseLinesIntoTasks(
271
+ input.description,
272
+ board.columns[0]?.id ?? "backlog"
273
+ )) {
274
+ await addTask(projectRoot, board.id, taskInput2);
275
+ }
276
+ return okBoard(await getBoard(projectRoot, board.id) ?? board, "Board generated.");
277
+ }
278
+ case "export_markdown": {
279
+ const board = await requireBoard(projectRoot, input.boardId);
280
+ if (!board) return fail("Board not found.");
281
+ return {
282
+ ok: true,
283
+ message: "Board exported.",
284
+ board,
285
+ markdown: exportBoardAsMarkdown(board)
286
+ };
287
+ }
288
+ case "export_task_graph": {
289
+ if (!input.boardId) return fail("export_task_graph requires boardId.");
290
+ const exported = await exportBoardToTaskGraph(projectRoot, input.boardId, {
291
+ ...input.graphId !== void 0 ? { graphId: input.graphId } : {},
292
+ ...input.specId !== void 0 ? { specId: input.specId } : {},
293
+ ...input.title !== void 0 ? { title: input.title } : {},
294
+ ...input.preserveOriginTaskIds !== void 0 ? { preserveOriginTaskIds: input.preserveOriginTaskIds } : {},
295
+ ...input.includeArchived !== void 0 ? { includeArchived: input.includeArchived } : {}
296
+ });
297
+ if (!exported) return fail("Board not found.");
298
+ return {
299
+ ok: true,
300
+ message: `Task graph exported with ${exported.graph.nodes.size} node(s).`,
301
+ board: exported.board,
302
+ taskGraph: serializeTaskGraph(exported.graph)
303
+ };
304
+ }
305
+ case "sync_task_graph": {
306
+ if (!input.boardId || !input.taskGraph) {
307
+ return fail("sync_task_graph requires boardId and taskGraph.");
308
+ }
309
+ const graph = deserializeTaskGraph(input.taskGraph);
310
+ const result = await syncBoardFromTaskGraph(projectRoot, input.boardId, graph, {
311
+ ...input.title !== void 0 ? { title: input.title } : {},
312
+ ...input.description !== void 0 ? { description: input.description } : {},
313
+ ...input.tags !== void 0 ? { tags: input.tags } : {},
314
+ ...input.generatedBy !== void 0 ? { generatedBy: input.generatedBy } : {},
315
+ ...input.sourceSystem !== void 0 ? { sourceSystem: input.sourceSystem } : {},
316
+ ...input.phaseId !== void 0 ? { phaseId: input.phaseId } : {},
317
+ ...input.includeCompletedTasks !== void 0 ? { includeCompletedTasks: input.includeCompletedTasks } : {},
318
+ ...input.archiveMissingTasks !== void 0 ? { archiveMissingTasks: input.archiveMissingTasks } : {},
319
+ ...input.preserveManualDependencies !== void 0 ? { preserveManualDependencies: input.preserveManualDependencies } : {}
320
+ });
321
+ return result ? {
322
+ ok: true,
323
+ message: `Task graph synced: ${result.createdTaskIds.length} created, ${result.updatedTaskIds.length} updated, ${result.archivedTaskIds.length} archived.`,
324
+ board: result.board
325
+ } : fail("Board not found.");
326
+ }
327
+ case "search_tasks": {
328
+ const tasks = await searchKanban(projectRoot, {
329
+ query: input.query,
330
+ boardId: input.boardId,
331
+ assignedAgent: input.agentId,
332
+ status: input.status,
333
+ priority: input.priority,
334
+ label: input.labels?.[0],
335
+ chainId: input.chainId
336
+ });
337
+ return { ok: true, message: `${tasks.length} task(s) matched.`, tasks };
338
+ }
339
+ case "ready_tasks": {
340
+ const tasks = await listReadyTasks(projectRoot, {
341
+ query: input.query,
342
+ boardId: input.boardId,
343
+ assignedAgent: input.agentId,
344
+ priority: input.priority,
345
+ label: input.labels?.[0],
346
+ chainId: input.chainId,
347
+ limit: input.limit
348
+ });
349
+ return { ok: true, message: `${tasks.length} ready task(s).`, tasks };
350
+ }
351
+ case "snapshot": {
352
+ const snapshot = await getKanbanOrchestrationSnapshot(projectRoot, {
353
+ query: input.query,
354
+ boardId: input.boardId,
355
+ assignedAgent: input.agentId,
356
+ status: input.status,
357
+ priority: input.priority,
358
+ label: input.labels?.[0],
359
+ chainId: input.chainId
360
+ });
361
+ return {
362
+ ok: true,
363
+ message: `${snapshot.ready.length} ready, ${snapshot.running.length} running, ${snapshot.blocked.length} blocked.`,
364
+ snapshot
365
+ };
366
+ }
367
+ case "add_column": {
368
+ if (!input.boardId || !input.title) return fail("add_column requires boardId and title.");
369
+ const result = await addColumn(projectRoot, input.boardId, {
370
+ title: input.title,
371
+ ...input.description !== void 0 ? { description: input.description } : {}
372
+ });
373
+ return result ? okBoard(result.board, "Column added.") : fail("Board not found.");
374
+ }
375
+ case "update_column": {
376
+ if (!input.boardId || !input.columnId)
377
+ return fail("update_column requires boardId and columnId.");
378
+ const board = await updateColumn(projectRoot, input.boardId, input.columnId, {
379
+ ...input.title !== void 0 ? { title: input.title } : {},
380
+ ...input.description !== void 0 ? { description: input.description } : {},
381
+ ...input.order !== void 0 ? { order: input.order } : {}
382
+ });
383
+ return board ? okBoard(board, "Column updated.") : fail("Column not found.");
384
+ }
385
+ case "delete_column": {
386
+ if (!input.boardId || !input.columnId)
387
+ return fail("delete_column requires boardId and columnId.");
388
+ const board = await removeColumn(projectRoot, input.boardId, input.columnId, {
389
+ moveTasksToColumnId: input.moveTasksToColumnId
390
+ });
391
+ return board ? okBoard(board, "Column deleted.") : fail("Column not found.");
392
+ }
393
+ case "add_task": {
394
+ if (!input.boardId || !input.title) return fail("add_task requires boardId and title.");
395
+ const result = await addTask(projectRoot, input.boardId, taskInput(input));
396
+ return result ? okTask(result.board, result.task, "Task added.") : fail("Board not found.");
397
+ }
398
+ case "split_task": {
399
+ if (!input.boardId || !input.taskId || !input.childTitles?.length) {
400
+ return fail("split_task requires boardId, taskId, and childTitles.");
401
+ }
402
+ const result = await splitTask(projectRoot, input.boardId, input.taskId, {
403
+ titles: input.childTitles,
404
+ ...input.targetColumnId !== void 0 ? { columnId: input.targetColumnId } : {},
405
+ ...input.inheritAssignment !== void 0 ? { inheritAssignment: input.inheritAssignment } : {},
406
+ ...input.inheritLabels !== void 0 ? { inheritLabels: input.inheritLabels } : {},
407
+ ...input.inheritSuccessCriteria !== void 0 ? { inheritSuccessCriteria: input.inheritSuccessCriteria } : {},
408
+ ...input.inheritGoalMetrics !== void 0 ? { inheritGoalMetrics: input.inheritGoalMetrics } : {},
409
+ ...input.inheritDependencies !== void 0 ? { inheritDependencies: input.inheritDependencies } : {},
410
+ ...input.chainChildren !== void 0 ? { chainChildren: input.chainChildren } : {},
411
+ ...input.rewireDependents !== void 0 ? { rewireDependents: input.rewireDependents } : {}
412
+ });
413
+ return result ? {
414
+ ok: true,
415
+ message: `${result.children.length} child task(s) created.`,
416
+ board: result.board,
417
+ task: result.parent,
418
+ children: result.children
419
+ } : fail("Task not found.");
420
+ }
421
+ case "merge_tasks": {
422
+ if (!input.boardId || !input.taskIds?.length || !input.title) {
423
+ return fail("merge_tasks requires boardId, taskIds, and title.");
424
+ }
425
+ const result = await mergeTasks(projectRoot, input.boardId, {
426
+ taskIds: input.taskIds,
427
+ title: input.title,
428
+ ...input.description !== void 0 ? { description: input.description } : {},
429
+ ...input.targetColumnId !== void 0 ? { targetColumnId: input.targetColumnId } : {},
430
+ ...input.preserveAssignment !== void 0 ? { preserveAssignment: input.preserveAssignment } : {},
431
+ ...input.closeSourceTasks !== void 0 ? { closeSourceTasks: input.closeSourceTasks } : {}
432
+ });
433
+ return result ? okTask(result.board, result.task, "Tasks merged.") : fail("Board or task not found.");
434
+ }
435
+ case "copy_task": {
436
+ if (!input.boardId || !input.taskId || !input.targetBoardId) {
437
+ return fail("copy_task requires boardId, taskId, and targetBoardId.");
438
+ }
439
+ const result = await copyTaskToBoard(
440
+ projectRoot,
441
+ input.boardId,
442
+ input.taskId,
443
+ input.targetBoardId,
444
+ {
445
+ ...input.targetColumnId !== void 0 ? { targetColumnId: input.targetColumnId } : {},
446
+ ...input.order !== void 0 ? { targetOrder: input.order } : {},
447
+ ...input.preserveAssignment !== void 0 ? { preserveAssignment: input.preserveAssignment } : {},
448
+ ...input.preserveDependencies !== void 0 ? { preserveDependencies: input.preserveDependencies } : {}
449
+ }
450
+ );
451
+ return result ? okTask(result.targetBoard, result.task, "Task copied to target board.") : fail("Board or task not found.");
452
+ }
453
+ case "transfer_task": {
454
+ if (!input.boardId || !input.taskId || !input.targetBoardId) {
455
+ return fail("transfer_task requires boardId, taskId, and targetBoardId.");
456
+ }
457
+ const result = await transferTaskToBoard(
458
+ projectRoot,
459
+ input.boardId,
460
+ input.taskId,
461
+ input.targetBoardId,
462
+ {
463
+ ...input.targetColumnId !== void 0 ? { targetColumnId: input.targetColumnId } : {},
464
+ ...input.order !== void 0 ? { targetOrder: input.order } : {},
465
+ ...input.preserveAssignment !== void 0 ? { preserveAssignment: input.preserveAssignment } : {},
466
+ ...input.preserveDependencies !== void 0 ? { preserveDependencies: input.preserveDependencies } : {}
467
+ }
468
+ );
469
+ return result ? okTask(result.targetBoard, result.task, "Task transferred to target board.") : fail("Board or task not found.");
470
+ }
471
+ case "get_task": {
472
+ if (!input.boardId || !input.taskId) return fail("get_task requires boardId and taskId.");
473
+ const task = await getTask(projectRoot, input.boardId, input.taskId);
474
+ return task ? { ok: true, message: "Task loaded.", task } : fail("Task not found.");
475
+ }
476
+ case "update_task": {
477
+ if (!input.boardId || !input.taskId)
478
+ return fail("update_task requires boardId and taskId.");
479
+ const board = await updateTask(
480
+ projectRoot,
481
+ input.boardId,
482
+ input.taskId,
483
+ taskPatch(input)
484
+ );
485
+ return board ? okBoard(board, "Task updated.") : fail("Task not found.");
486
+ }
487
+ case "move_task": {
488
+ if (!input.boardId || !input.taskId || !input.targetColumnId) {
489
+ return fail("move_task requires boardId, taskId, and targetColumnId.");
490
+ }
491
+ const board = await moveTask(
492
+ projectRoot,
493
+ input.boardId,
494
+ input.taskId,
495
+ input.targetColumnId,
496
+ input.order
497
+ );
498
+ return board ? okBoard(board, "Task moved.") : fail("Move failed.");
499
+ }
500
+ case "delete_task": {
501
+ if (!input.boardId || !input.taskId)
502
+ return fail("delete_task requires boardId and taskId.");
503
+ const board = await removeTask(projectRoot, input.boardId, input.taskId);
504
+ return board ? okBoard(board, "Task deleted.") : fail("Task not found.");
505
+ }
506
+ case "set_chain": {
507
+ if (!input.boardId || !input.taskIds?.length) {
508
+ return fail("set_chain requires boardId and taskIds.");
509
+ }
510
+ const result = await setTaskChain(projectRoot, input.boardId, {
511
+ taskIds: input.taskIds,
512
+ ...input.chainId !== void 0 ? { chainId: input.chainId } : {},
513
+ ...input.enforceDependencies !== void 0 ? { enforceDependencies: input.enforceDependencies } : {}
514
+ });
515
+ return result ? {
516
+ ok: true,
517
+ message: `Chain set: ${result.chainId}`,
518
+ board: result.board,
519
+ chain: result.tasks
520
+ } : fail("Board or task not found.");
521
+ }
522
+ case "get_chain": {
523
+ if (!input.boardId || !(input.taskId || input.chainId)) {
524
+ return fail("get_chain requires boardId and taskId or chainId.");
525
+ }
526
+ const result = await getTaskChain(
527
+ projectRoot,
528
+ input.boardId,
529
+ input.taskId ?? input.chainId ?? ""
530
+ );
531
+ return result ? {
532
+ ok: true,
533
+ message: `Chain loaded: ${result.chainId}`,
534
+ board: result.board,
535
+ chain: result.tasks
536
+ } : fail("Chain not found.");
537
+ }
538
+ case "claim_task": {
539
+ const result = await claimReadyTask(projectRoot, {
540
+ ...input.boardId !== void 0 ? { boardId: input.boardId } : {},
541
+ ...input.taskId !== void 0 ? { taskId: input.taskId } : {},
542
+ ...assignmentInput(input),
543
+ status: input.assignmentStatus ?? "queued"
544
+ });
545
+ return result ? okTask(result.board, result.task, "Task claimed.") : fail("No ready kanban task matched the claim.");
546
+ }
547
+ case "release_task": {
548
+ if (!input.boardId || !input.taskId) {
549
+ return fail("release_task requires boardId and taskId.");
550
+ }
551
+ const board = await releaseTaskClaim(projectRoot, input.boardId, input.taskId, {
552
+ ...input.releaseStatus !== void 0 ? { status: input.releaseStatus } : {},
553
+ ...input.releaseReason !== void 0 ? { reason: input.releaseReason } : {},
554
+ ...input.clearAssignee !== void 0 ? { clearAssignee: input.clearAssignee } : {}
555
+ });
556
+ return board ? okBoard(board, "Task claim released.") : fail("Task not found.");
557
+ }
558
+ case "assign_task": {
559
+ if (!input.boardId || !input.taskId)
560
+ return fail("assign_task requires boardId and taskId.");
561
+ const board = await assignTask(
562
+ projectRoot,
563
+ input.boardId,
564
+ input.taskId,
565
+ assignmentInput(input)
566
+ );
567
+ return board ? okBoard(board, "Task assigned.") : fail("Task not found.");
568
+ }
569
+ case "mark_assignment": {
570
+ if (!input.boardId || !input.taskId)
571
+ return fail("mark_assignment requires boardId and taskId.");
572
+ const assignmentStatus = input.assignmentStatus ?? (input.status === "completed" ? "completed" : input.error ? "failed" : void 0);
573
+ const board = await updateTaskAssignment(projectRoot, input.boardId, input.taskId, {
574
+ ...assignmentStatus !== void 0 ? { status: assignmentStatus } : {},
575
+ ...input.subagentId !== void 0 ? { subagentId: input.subagentId } : {},
576
+ ...input.runTaskId !== void 0 ? { runTaskId: input.runTaskId } : {},
577
+ ...input.lastResult !== void 0 ? { lastResult: input.lastResult } : {},
578
+ ...input.error !== void 0 ? { error: input.error } : {},
579
+ ...input.agentId !== void 0 ? { agentId: input.agentId } : {},
580
+ ...input.leaseId !== void 0 ? { leaseId: input.leaseId } : {},
581
+ ...input.claimedAt !== void 0 ? { claimedAt: input.claimedAt } : {},
582
+ ...input.heartbeatAt !== void 0 ? { heartbeatAt: input.heartbeatAt } : {},
583
+ ...input.leaseExpiresAt !== void 0 ? { leaseExpiresAt: input.leaseExpiresAt } : {},
584
+ ...input.attempt !== void 0 ? { attempt: input.attempt } : {},
585
+ ...input.maxAttempts !== void 0 ? { maxAttempts: input.maxAttempts } : {}
586
+ });
587
+ return board ? okBoard(board, "Assignment updated.") : fail("Task not found.");
588
+ }
589
+ case "heartbeat_assignment": {
590
+ if (!input.boardId || !input.taskId) {
591
+ return fail("heartbeat_assignment requires boardId and taskId.");
592
+ }
593
+ const board = await heartbeatTaskAssignment(projectRoot, input.boardId, input.taskId, {
594
+ ...input.heartbeatAt !== void 0 ? { heartbeatAt: input.heartbeatAt } : {},
595
+ ...input.leaseExpiresAt !== void 0 ? { leaseExpiresAt: input.leaseExpiresAt } : {}
596
+ });
597
+ return board ? okBoard(board, "Assignment heartbeat updated.") : fail("Task assignment not found.");
598
+ }
599
+ case "recover_stale": {
600
+ if (!input.boardId) return fail("recover_stale requires boardId.");
601
+ const policyFields = [
602
+ input.recoveryPolicyFailOnCostCeiling !== void 0,
603
+ input.recoveryPolicyReleaseOnFailureKinds !== void 0,
604
+ input.recoveryPolicyReleaseOnHeartbeatDue !== void 0,
605
+ input.recoveryPolicyRetryPolicyOverride !== void 0
606
+ ].some(Boolean);
607
+ const result = await recoverStaleTaskAssignments(projectRoot, input.boardId, {
608
+ ...input.recoveryMode !== void 0 ? { mode: input.recoveryMode } : {},
609
+ ...input.recoveryNow !== void 0 ? { now: input.recoveryNow } : {},
610
+ ...input.releaseReason !== void 0 ? { reason: input.releaseReason } : {},
611
+ ...input.clearAssignee !== void 0 ? { clearAssignee: input.clearAssignee } : {},
612
+ ...policyFields ? {
613
+ policy: {
614
+ ...input.recoveryPolicyFailOnCostCeiling !== void 0 ? { failWhenCostCeilingSet: input.recoveryPolicyFailOnCostCeiling } : {},
615
+ ...input.recoveryPolicyReleaseOnFailureKinds !== void 0 ? {
616
+ releaseOnFailureKinds: input.recoveryPolicyReleaseOnFailureKinds
617
+ } : {},
618
+ ...input.recoveryPolicyReleaseOnHeartbeatDue !== void 0 ? {
619
+ releaseOnHeartbeatDue: input.recoveryPolicyReleaseOnHeartbeatDue
620
+ } : {},
621
+ ...input.recoveryPolicyRetryPolicyOverride !== void 0 ? {
622
+ retryPolicyOverride: input.recoveryPolicyRetryPolicyOverride
623
+ } : {}
624
+ }
625
+ } : {}
626
+ });
627
+ return result ? {
628
+ ok: true,
629
+ message: `Recovered ${result.tasks.length} stale assignment(s).`,
630
+ board: result.board,
631
+ recoveredTasks: result.tasks
632
+ } : { ok: true, message: "No stale assignment matched.", recoveredTasks: [] };
633
+ }
634
+ case "events": {
635
+ if (!input.boardId) return fail("events requires boardId.");
636
+ const eventList = await listKanbanEvents(projectRoot, input.boardId);
637
+ return {
638
+ ok: true,
639
+ message: `${eventList.length} event(s).`,
640
+ events: eventList
641
+ };
642
+ }
643
+ case "queue_health": {
644
+ const health = await getKanbanQueueHealth(projectRoot, {
645
+ ...input.boardId !== void 0 ? { boardId: input.boardId } : {}
646
+ });
647
+ return {
648
+ ok: true,
649
+ message: `Counts: ready=${health.counts.ready}, running=${health.counts.running}, stale=${health.staleAssignments.count}.`,
650
+ queueHealth: health
651
+ };
652
+ }
653
+ case "add_dependency": {
654
+ if (!input.boardId || !input.taskId || !input.dependencyTaskId) {
655
+ return fail("add_dependency requires boardId, taskId, and dependencyTaskId.");
656
+ }
657
+ const board = await addDependency(
658
+ projectRoot,
659
+ input.boardId,
660
+ input.taskId,
661
+ input.dependencyTaskId
662
+ );
663
+ return board ? okBoard(board, "Dependency added.") : fail("Task not found.");
664
+ }
665
+ case "add_goal_metric": {
666
+ if (!input.boardId || !input.taskId || !input.metricName) {
667
+ return fail("add_goal_metric requires boardId, taskId, and metricName.");
668
+ }
669
+ const board = await addGoalMetricToTask(projectRoot, input.boardId, input.taskId, {
670
+ name: input.metricName,
671
+ ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
672
+ ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
673
+ ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
674
+ ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
675
+ ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
676
+ });
677
+ return board ? okBoard(board, "Goal metric added.") : fail("Task not found.");
678
+ }
679
+ case "update_goal_metric": {
680
+ if (!input.boardId || !input.taskId || !input.metricId) {
681
+ return fail("update_goal_metric requires boardId, taskId, and metricId.");
682
+ }
683
+ const board = await updateGoalMetricOnTask(
684
+ projectRoot,
685
+ input.boardId,
686
+ input.taskId,
687
+ input.metricId,
688
+ {
689
+ ...input.metricName !== void 0 ? { name: input.metricName } : {},
690
+ ...input.metricStatus !== void 0 ? { status: input.metricStatus } : {},
691
+ ...input.metricTarget !== void 0 ? { target: input.metricTarget } : {},
692
+ ...input.metricCurrent !== void 0 ? { current: input.metricCurrent } : {},
693
+ ...input.metricUnit !== void 0 ? { unit: input.metricUnit } : {},
694
+ ...input.metricNotes !== void 0 ? { notes: input.metricNotes } : {}
695
+ }
696
+ );
697
+ return board ? okBoard(board, "Goal metric updated.") : fail("Metric not found.");
698
+ }
699
+ case "add_check": {
700
+ if (!input.boardId || !input.taskId || !input.checkDescription) {
701
+ return fail("add_check requires boardId, taskId, and checkDescription.");
702
+ }
703
+ const board = await addCheckToTask(projectRoot, input.boardId, input.taskId, {
704
+ description: input.checkDescription,
705
+ type: "manual",
706
+ status: input.checkStatus
707
+ });
708
+ return board ? okBoard(board, "Check added.") : fail("Task not found.");
709
+ }
710
+ case "update_check": {
711
+ if (!input.boardId || !input.taskId || !input.checkId) {
712
+ return fail("update_check requires boardId, taskId, and checkId.");
713
+ }
714
+ const board = await updateCheckOnTask(
715
+ projectRoot,
716
+ input.boardId,
717
+ input.taskId,
718
+ input.checkId,
719
+ {
720
+ ...input.checkDescription !== void 0 ? { description: input.checkDescription } : {},
721
+ ...input.checkStatus !== void 0 ? { status: input.checkStatus } : {}
722
+ }
723
+ );
724
+ return board ? okBoard(board, "Check updated.") : fail("Check not found.");
725
+ }
726
+ case "add_note": {
727
+ if (!input.boardId || !input.taskId || !input.note)
728
+ return fail("add_note requires boardId, taskId, and note.");
729
+ const board = await addNoteToTask(projectRoot, input.boardId, input.taskId, {
730
+ author: input.author ?? "agent",
731
+ content: input.note
732
+ });
733
+ return board ? okBoard(board, "Note added.") : fail("Task not found.");
734
+ }
735
+ case "add_link": {
736
+ if (!input.boardId || !input.taskId || !input.url)
737
+ return fail("add_link requires boardId, taskId, and url.");
738
+ const board = await addLinkToTask(projectRoot, input.boardId, input.taskId, {
739
+ url: input.url,
740
+ type: input.linkType ?? "url",
741
+ ...input.linkTitle !== void 0 ? { title: input.linkTitle } : {}
742
+ });
743
+ return board ? okBoard(board, "Link added.") : fail("Task not found.");
744
+ }
745
+ default:
746
+ return fail(`Unknown kanban action: ${input.action}`);
747
+ }
748
+ } catch (err) {
749
+ return fail(err instanceof Error ? err.message : String(err));
750
+ }
751
+ }
752
+ };
753
+ function fail(message) {
754
+ return { ok: false, message };
755
+ }
756
+ function okBoard(board, message = "Board loaded.") {
757
+ return { ok: true, message, board };
758
+ }
759
+ function okTask(board, task, message) {
760
+ return { ok: true, message, board, task };
761
+ }
762
+ async function requireBoard(projectRoot, boardId) {
763
+ return boardId ? getBoard(projectRoot, boardId) : null;
764
+ }
765
+ function taskInput(input) {
766
+ const assignment = hasAssignmentInput(input) ? assignmentForTaskCreate(input) : void 0;
767
+ return {
768
+ title: input.title ?? "",
769
+ columnId: input.columnId,
770
+ description: input.description,
771
+ priority: input.priority,
772
+ status: input.status,
773
+ labels: input.labels,
774
+ ...assignment?.agentId ?? assignment?.role ?? assignment?.name ? { assignedAgent: assignment.agentId ?? assignment.role ?? assignment.name } : {},
775
+ ...input.assignee ?? assignment?.name ?? assignment?.agentId ? { assignee: input.assignee ?? assignment?.name ?? assignment?.agentId } : {},
776
+ ...input.dependencyTaskId !== void 0 ? { dependsOn: [input.dependencyTaskId] } : {},
777
+ ...assignment ? { assignment } : {}
778
+ };
779
+ }
780
+ function taskPatch(input) {
781
+ return {
782
+ title: input.title,
783
+ description: input.description,
784
+ columnId: input.columnId,
785
+ order: input.order,
786
+ priority: input.priority,
787
+ status: input.status,
788
+ labels: input.labels,
789
+ assignedAgent: input.agentId,
790
+ ...input.dependencyTaskId !== void 0 ? { dependsOn: [input.dependencyTaskId] } : {}
791
+ };
792
+ }
793
+ function assignmentInput(input) {
794
+ return {
795
+ agentId: input.agentId,
796
+ name: input.name,
797
+ role: input.role,
798
+ provider: input.provider,
799
+ model: input.model,
800
+ fallbackProfile: input.fallbackProfile,
801
+ fallbackModels: input.fallbackModels,
802
+ tools: input.tools,
803
+ allowedCapabilities: input.allowedCapabilities,
804
+ assignee: input.assignee,
805
+ leaseId: input.leaseId,
806
+ claimedAt: input.claimedAt,
807
+ heartbeatAt: input.heartbeatAt,
808
+ leaseExpiresAt: input.leaseExpiresAt,
809
+ attempt: input.attempt,
810
+ maxAttempts: input.maxAttempts,
811
+ costCeilingUsd: input.costCeilingUsd,
812
+ retryPolicy: input.retryPolicy,
813
+ lastFailureKind: input.lastFailureKind
814
+ };
815
+ }
816
+ function hasAssignmentInput(input) {
817
+ return input.agentId !== void 0 || input.name !== void 0 || input.role !== void 0 || input.provider !== void 0 || input.model !== void 0 || input.fallbackProfile !== void 0 || input.fallbackModels !== void 0 || input.tools !== void 0 || input.allowedCapabilities !== void 0 || input.assignee !== void 0 || input.leaseId !== void 0 || input.claimedAt !== void 0 || input.heartbeatAt !== void 0 || input.leaseExpiresAt !== void 0 || input.attempt !== void 0 || input.maxAttempts !== void 0 || input.costCeilingUsd !== void 0 || input.retryPolicy !== void 0 || input.lastFailureKind !== void 0 || input.assignmentStatus !== void 0;
818
+ }
819
+ function assignmentForTaskCreate(input) {
820
+ return {
821
+ status: input.assignmentStatus ?? "assigned",
822
+ ...input.agentId !== void 0 ? { agentId: input.agentId } : {},
823
+ ...input.name !== void 0 ? { name: input.name } : {},
824
+ ...input.role !== void 0 ? { role: input.role } : {},
825
+ ...input.provider !== void 0 ? { provider: input.provider } : {},
826
+ ...input.model !== void 0 ? { model: input.model } : {},
827
+ ...input.fallbackProfile !== void 0 ? { fallbackProfile: input.fallbackProfile } : {},
828
+ ...input.fallbackModels !== void 0 ? { fallbackModels: input.fallbackModels } : {},
829
+ ...input.tools !== void 0 ? { tools: input.tools } : {},
830
+ ...input.allowedCapabilities !== void 0 ? { allowedCapabilities: input.allowedCapabilities } : {},
831
+ ...input.leaseId !== void 0 ? { leaseId: input.leaseId } : {},
832
+ ...input.claimedAt !== void 0 ? { claimedAt: input.claimedAt } : {},
833
+ ...input.heartbeatAt !== void 0 ? { heartbeatAt: input.heartbeatAt } : {},
834
+ ...input.leaseExpiresAt !== void 0 ? { leaseExpiresAt: input.leaseExpiresAt } : {},
835
+ ...input.attempt !== void 0 ? { attempt: input.attempt } : {},
836
+ ...input.maxAttempts !== void 0 ? { maxAttempts: input.maxAttempts } : {},
837
+ ...input.costCeilingUsd !== void 0 ? { costCeilingUsd: input.costCeilingUsd } : {},
838
+ ...input.retryPolicy !== void 0 ? { retryPolicy: input.retryPolicy } : {},
839
+ ...input.lastFailureKind !== void 0 ? { lastFailureKind: input.lastFailureKind } : {}
840
+ };
841
+ }
842
+ export {
843
+ kanbanTool
844
+ };
845
+ //# sourceMappingURL=kanban.js.map