brainfile 0.18.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 (360) hide show
  1. package/README.md +222 -0
  2. package/dist/__tests__/helpers/v2.d.ts +12 -0
  3. package/dist/__tests__/helpers/v2.d.ts.map +1 -0
  4. package/dist/__tests__/helpers/v2.js +73 -0
  5. package/dist/__tests__/helpers/v2.js.map +1 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +480 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/commands/add.d.ts +34 -0
  11. package/dist/commands/add.d.ts.map +1 -0
  12. package/dist/commands/add.js +255 -0
  13. package/dist/commands/add.js.map +1 -0
  14. package/dist/commands/adr.d.ts +22 -0
  15. package/dist/commands/adr.d.ts.map +1 -0
  16. package/dist/commands/adr.js +195 -0
  17. package/dist/commands/adr.js.map +1 -0
  18. package/dist/commands/archive.d.ts +20 -0
  19. package/dist/commands/archive.d.ts.map +1 -0
  20. package/dist/commands/archive.js +590 -0
  21. package/dist/commands/archive.js.map +1 -0
  22. package/dist/commands/auth.d.ts +26 -0
  23. package/dist/commands/auth.d.ts.map +1 -0
  24. package/dist/commands/auth.js +245 -0
  25. package/dist/commands/auth.js.map +1 -0
  26. package/dist/commands/complete.d.ts +30 -0
  27. package/dist/commands/complete.d.ts.map +1 -0
  28. package/dist/commands/complete.js +267 -0
  29. package/dist/commands/complete.js.map +1 -0
  30. package/dist/commands/config.d.ts +29 -0
  31. package/dist/commands/config.d.ts.map +1 -0
  32. package/dist/commands/config.js +210 -0
  33. package/dist/commands/config.js.map +1 -0
  34. package/dist/commands/contract.d.ts +84 -0
  35. package/dist/commands/contract.d.ts.map +1 -0
  36. package/dist/commands/contract.js +715 -0
  37. package/dist/commands/contract.js.map +1 -0
  38. package/dist/commands/delete.d.ts +8 -0
  39. package/dist/commands/delete.d.ts.map +1 -0
  40. package/dist/commands/delete.js +139 -0
  41. package/dist/commands/delete.js.map +1 -0
  42. package/dist/commands/hooks.d.ts +35 -0
  43. package/dist/commands/hooks.d.ts.map +1 -0
  44. package/dist/commands/hooks.js +324 -0
  45. package/dist/commands/hooks.js.map +1 -0
  46. package/dist/commands/init.d.ts +7 -0
  47. package/dist/commands/init.d.ts.map +1 -0
  48. package/dist/commands/init.js +118 -0
  49. package/dist/commands/init.js.map +1 -0
  50. package/dist/commands/lint.d.ts +16 -0
  51. package/dist/commands/lint.d.ts.map +1 -0
  52. package/dist/commands/lint.js +123 -0
  53. package/dist/commands/lint.js.map +1 -0
  54. package/dist/commands/list.d.ts +20 -0
  55. package/dist/commands/list.d.ts.map +1 -0
  56. package/dist/commands/list.js +175 -0
  57. package/dist/commands/list.js.map +1 -0
  58. package/dist/commands/log.d.ts +52 -0
  59. package/dist/commands/log.d.ts.map +1 -0
  60. package/dist/commands/log.js +246 -0
  61. package/dist/commands/log.js.map +1 -0
  62. package/dist/commands/mcp.d.ts +3 -0
  63. package/dist/commands/mcp.d.ts.map +1 -0
  64. package/dist/commands/mcp.js +96 -0
  65. package/dist/commands/mcp.js.map +1 -0
  66. package/dist/commands/migrate.d.ts +16 -0
  67. package/dist/commands/migrate.d.ts.map +1 -0
  68. package/dist/commands/migrate.js +388 -0
  69. package/dist/commands/migrate.js.map +1 -0
  70. package/dist/commands/move.d.ts +16 -0
  71. package/dist/commands/move.d.ts.map +1 -0
  72. package/dist/commands/move.js +225 -0
  73. package/dist/commands/move.js.map +1 -0
  74. package/dist/commands/patch.d.ts +17 -0
  75. package/dist/commands/patch.d.ts.map +1 -0
  76. package/dist/commands/patch.js +226 -0
  77. package/dist/commands/patch.js.map +1 -0
  78. package/dist/commands/restore.d.ts +8 -0
  79. package/dist/commands/restore.d.ts.map +1 -0
  80. package/dist/commands/restore.js +111 -0
  81. package/dist/commands/restore.js.map +1 -0
  82. package/dist/commands/rules.d.ts +68 -0
  83. package/dist/commands/rules.d.ts.map +1 -0
  84. package/dist/commands/rules.js +322 -0
  85. package/dist/commands/rules.js.map +1 -0
  86. package/dist/commands/schema.d.ts +31 -0
  87. package/dist/commands/schema.d.ts.map +1 -0
  88. package/dist/commands/schema.js +374 -0
  89. package/dist/commands/schema.js.map +1 -0
  90. package/dist/commands/search.d.ts +33 -0
  91. package/dist/commands/search.d.ts.map +1 -0
  92. package/dist/commands/search.js +209 -0
  93. package/dist/commands/search.js.map +1 -0
  94. package/dist/commands/show.d.ts +20 -0
  95. package/dist/commands/show.d.ts.map +1 -0
  96. package/dist/commands/show.js +272 -0
  97. package/dist/commands/show.js.map +1 -0
  98. package/dist/commands/subtask.d.ts +12 -0
  99. package/dist/commands/subtask.d.ts.map +1 -0
  100. package/dist/commands/subtask.js +212 -0
  101. package/dist/commands/subtask.js.map +1 -0
  102. package/dist/commands/template.d.ts +17 -0
  103. package/dist/commands/template.d.ts.map +1 -0
  104. package/dist/commands/template.js +149 -0
  105. package/dist/commands/template.js.map +1 -0
  106. package/dist/commands/tui.d.ts +6 -0
  107. package/dist/commands/tui.d.ts.map +1 -0
  108. package/dist/commands/tui.js +79 -0
  109. package/dist/commands/tui.js.map +1 -0
  110. package/dist/commands/types.d.ts +40 -0
  111. package/dist/commands/types.d.ts.map +1 -0
  112. package/dist/commands/types.js +242 -0
  113. package/dist/commands/types.js.map +1 -0
  114. package/dist/index.d.ts +10 -0
  115. package/dist/index.d.ts.map +1 -0
  116. package/dist/index.js +29 -0
  117. package/dist/index.js.map +1 -0
  118. package/dist/lib/contractRunner.d.ts +59 -0
  119. package/dist/lib/contractRunner.d.ts.map +1 -0
  120. package/dist/lib/contractRunner.js +511 -0
  121. package/dist/lib/contractRunner.js.map +1 -0
  122. package/dist/mcp/helpers.d.ts +32 -0
  123. package/dist/mcp/helpers.d.ts.map +1 -0
  124. package/dist/mcp/helpers.js +125 -0
  125. package/dist/mcp/helpers.js.map +1 -0
  126. package/dist/mcp/tools/contract.d.ts +25 -0
  127. package/dist/mcp/tools/contract.d.ts.map +1 -0
  128. package/dist/mcp/tools/contract.js +33 -0
  129. package/dist/mcp/tools/contract.js.map +1 -0
  130. package/dist/mcp/tools/contract_tool.d.ts +3 -0
  131. package/dist/mcp/tools/contract_tool.d.ts.map +1 -0
  132. package/dist/mcp/tools/contract_tool.js +328 -0
  133. package/dist/mcp/tools/contract_tool.js.map +1 -0
  134. package/dist/mcp/tools/get_task_tool.d.ts +3 -0
  135. package/dist/mcp/tools/get_task_tool.d.ts.map +1 -0
  136. package/dist/mcp/tools/get_task_tool.js +55 -0
  137. package/dist/mcp/tools/get_task_tool.js.map +1 -0
  138. package/dist/mcp/tools/list_tasks_tool.d.ts +3 -0
  139. package/dist/mcp/tools/list_tasks_tool.d.ts.map +1 -0
  140. package/dist/mcp/tools/list_tasks_tool.js +82 -0
  141. package/dist/mcp/tools/list_tasks_tool.js.map +1 -0
  142. package/dist/mcp/tools/search_tool.d.ts +3 -0
  143. package/dist/mcp/tools/search_tool.d.ts.map +1 -0
  144. package/dist/mcp/tools/search_tool.js +155 -0
  145. package/dist/mcp/tools/search_tool.js.map +1 -0
  146. package/dist/mcp/tools/subtask_tool.d.ts +3 -0
  147. package/dist/mcp/tools/subtask_tool.d.ts.map +1 -0
  148. package/dist/mcp/tools/subtask_tool.js +321 -0
  149. package/dist/mcp/tools/subtask_tool.js.map +1 -0
  150. package/dist/mcp/tools/task_add_tool.d.ts +3 -0
  151. package/dist/mcp/tools/task_add_tool.d.ts.map +1 -0
  152. package/dist/mcp/tools/task_add_tool.js +196 -0
  153. package/dist/mcp/tools/task_add_tool.js.map +1 -0
  154. package/dist/mcp/tools/task_complete_tool.d.ts +3 -0
  155. package/dist/mcp/tools/task_complete_tool.d.ts.map +1 -0
  156. package/dist/mcp/tools/task_complete_tool.js +265 -0
  157. package/dist/mcp/tools/task_complete_tool.js.map +1 -0
  158. package/dist/mcp/tools/task_delete_tool.d.ts +3 -0
  159. package/dist/mcp/tools/task_delete_tool.d.ts.map +1 -0
  160. package/dist/mcp/tools/task_delete_tool.js +87 -0
  161. package/dist/mcp/tools/task_delete_tool.js.map +1 -0
  162. package/dist/mcp/tools/task_move_tool.d.ts +3 -0
  163. package/dist/mcp/tools/task_move_tool.d.ts.map +1 -0
  164. package/dist/mcp/tools/task_move_tool.js +187 -0
  165. package/dist/mcp/tools/task_move_tool.js.map +1 -0
  166. package/dist/mcp/tools/task_patch_tool.d.ts +3 -0
  167. package/dist/mcp/tools/task_patch_tool.d.ts.map +1 -0
  168. package/dist/mcp/tools/task_patch_tool.js +189 -0
  169. package/dist/mcp/tools/task_patch_tool.js.map +1 -0
  170. package/dist/schemas/base.json +159 -0
  171. package/dist/schemas/board.json +290 -0
  172. package/dist/tui/BrainfileTUI.d.ts +4 -0
  173. package/dist/tui/BrainfileTUI.d.ts.map +1 -0
  174. package/dist/tui/BrainfileTUI.js +272 -0
  175. package/dist/tui/BrainfileTUI.js.map +1 -0
  176. package/dist/tui/actions.d.ts +84 -0
  177. package/dist/tui/actions.d.ts.map +1 -0
  178. package/dist/tui/actions.js +1251 -0
  179. package/dist/tui/actions.js.map +1 -0
  180. package/dist/tui/components/ColumnTabs.d.ts +9 -0
  181. package/dist/tui/components/ColumnTabs.d.ts.map +1 -0
  182. package/dist/tui/components/ColumnTabs.js +34 -0
  183. package/dist/tui/components/ColumnTabs.js.map +1 -0
  184. package/dist/tui/components/Header.d.ts +15 -0
  185. package/dist/tui/components/Header.d.ts.map +1 -0
  186. package/dist/tui/components/Header.js +48 -0
  187. package/dist/tui/components/Header.js.map +1 -0
  188. package/dist/tui/components/HelpOverlay.d.ts +9 -0
  189. package/dist/tui/components/HelpOverlay.d.ts.map +1 -0
  190. package/dist/tui/components/HelpOverlay.js +116 -0
  191. package/dist/tui/components/HelpOverlay.js.map +1 -0
  192. package/dist/tui/components/LogsPanel.d.ts +16 -0
  193. package/dist/tui/components/LogsPanel.d.ts.map +1 -0
  194. package/dist/tui/components/LogsPanel.js +115 -0
  195. package/dist/tui/components/LogsPanel.js.map +1 -0
  196. package/dist/tui/components/MainPanelTabs.d.ts +10 -0
  197. package/dist/tui/components/MainPanelTabs.d.ts.map +1 -0
  198. package/dist/tui/components/MainPanelTabs.js +56 -0
  199. package/dist/tui/components/MainPanelTabs.js.map +1 -0
  200. package/dist/tui/components/ManualBorder.d.ts +42 -0
  201. package/dist/tui/components/ManualBorder.d.ts.map +1 -0
  202. package/dist/tui/components/ManualBorder.js +56 -0
  203. package/dist/tui/components/ManualBorder.js.map +1 -0
  204. package/dist/tui/components/Overlays.d.ts +41 -0
  205. package/dist/tui/components/Overlays.d.ts.map +1 -0
  206. package/dist/tui/components/Overlays.js +127 -0
  207. package/dist/tui/components/Overlays.js.map +1 -0
  208. package/dist/tui/components/ProgressBar.d.ts +8 -0
  209. package/dist/tui/components/ProgressBar.d.ts.map +1 -0
  210. package/dist/tui/components/ProgressBar.js +35 -0
  211. package/dist/tui/components/ProgressBar.js.map +1 -0
  212. package/dist/tui/components/RulesPanel.d.ts +25 -0
  213. package/dist/tui/components/RulesPanel.d.ts.map +1 -0
  214. package/dist/tui/components/RulesPanel.js +139 -0
  215. package/dist/tui/components/RulesPanel.js.map +1 -0
  216. package/dist/tui/components/SearchBar.d.ts +8 -0
  217. package/dist/tui/components/SearchBar.d.ts.map +1 -0
  218. package/dist/tui/components/SearchBar.js +38 -0
  219. package/dist/tui/components/SearchBar.js.map +1 -0
  220. package/dist/tui/components/StackedTaskList.d.ts +27 -0
  221. package/dist/tui/components/StackedTaskList.d.ts.map +1 -0
  222. package/dist/tui/components/StackedTaskList.js +120 -0
  223. package/dist/tui/components/StackedTaskList.js.map +1 -0
  224. package/dist/tui/components/StatusBar.d.ts +14 -0
  225. package/dist/tui/components/StatusBar.d.ts.map +1 -0
  226. package/dist/tui/components/StatusBar.js +42 -0
  227. package/dist/tui/components/StatusBar.js.map +1 -0
  228. package/dist/tui/components/TaskCard.d.ts +25 -0
  229. package/dist/tui/components/TaskCard.d.ts.map +1 -0
  230. package/dist/tui/components/TaskCard.js +221 -0
  231. package/dist/tui/components/TaskCard.js.map +1 -0
  232. package/dist/tui/components/TaskCardMeasure.d.ts +31 -0
  233. package/dist/tui/components/TaskCardMeasure.d.ts.map +1 -0
  234. package/dist/tui/components/TaskCardMeasure.js +133 -0
  235. package/dist/tui/components/TaskCardMeasure.js.map +1 -0
  236. package/dist/tui/components/TaskDetail.d.ts +13 -0
  237. package/dist/tui/components/TaskDetail.d.ts.map +1 -0
  238. package/dist/tui/components/TaskDetail.js +64 -0
  239. package/dist/tui/components/TaskDetail.js.map +1 -0
  240. package/dist/tui/components/TaskList.d.ts +12 -0
  241. package/dist/tui/components/TaskList.d.ts.map +1 -0
  242. package/dist/tui/components/TaskList.js +75 -0
  243. package/dist/tui/components/TaskList.js.map +1 -0
  244. package/dist/tui/components/index.d.ts +31 -0
  245. package/dist/tui/components/index.d.ts.map +1 -0
  246. package/dist/tui/components/index.js +43 -0
  247. package/dist/tui/components/index.js.map +1 -0
  248. package/dist/tui/hooks/index.d.ts +3 -0
  249. package/dist/tui/hooks/index.d.ts.map +1 -0
  250. package/dist/tui/hooks/index.js +8 -0
  251. package/dist/tui/hooks/index.js.map +1 -0
  252. package/dist/tui/hooks/useBrainfileLoader.d.ts +5 -0
  253. package/dist/tui/hooks/useBrainfileLoader.d.ts.map +1 -0
  254. package/dist/tui/hooks/useBrainfileLoader.js +237 -0
  255. package/dist/tui/hooks/useBrainfileLoader.js.map +1 -0
  256. package/dist/tui/hooks/useKeyboardNavigation.d.ts +20 -0
  257. package/dist/tui/hooks/useKeyboardNavigation.d.ts.map +1 -0
  258. package/dist/tui/hooks/useKeyboardNavigation.js +806 -0
  259. package/dist/tui/hooks/useKeyboardNavigation.js.map +1 -0
  260. package/dist/tui/index.d.ts +10 -0
  261. package/dist/tui/index.d.ts.map +1 -0
  262. package/dist/tui/index.js +38 -0
  263. package/dist/tui/index.js.map +1 -0
  264. package/dist/tui/theme.d.ts +119 -0
  265. package/dist/tui/theme.d.ts.map +1 -0
  266. package/dist/tui/theme.js +138 -0
  267. package/dist/tui/theme.js.map +1 -0
  268. package/dist/tui/types.d.ts +53 -0
  269. package/dist/tui/types.d.ts.map +1 -0
  270. package/dist/tui/types.js +12 -0
  271. package/dist/tui/types.js.map +1 -0
  272. package/dist/tui/utils.d.ts +24 -0
  273. package/dist/tui/utils.d.ts.map +1 -0
  274. package/dist/tui/utils.js +161 -0
  275. package/dist/tui/utils.js.map +1 -0
  276. package/dist/utils/archive.d.ts +57 -0
  277. package/dist/utils/archive.d.ts.map +1 -0
  278. package/dist/utils/archive.js +304 -0
  279. package/dist/utils/archive.js.map +1 -0
  280. package/dist/utils/auth-store.d.ts +69 -0
  281. package/dist/utils/auth-store.d.ts.map +1 -0
  282. package/dist/utils/auth-store.js +308 -0
  283. package/dist/utils/auth-store.js.map +1 -0
  284. package/dist/utils/board-types.d.ts +13 -0
  285. package/dist/utils/board-types.d.ts.map +1 -0
  286. package/dist/utils/board-types.js +7 -0
  287. package/dist/utils/board-types.js.map +1 -0
  288. package/dist/utils/brainfile-finder.d.ts +12 -0
  289. package/dist/utils/brainfile-finder.d.ts.map +1 -0
  290. package/dist/utils/brainfile-finder.js +69 -0
  291. package/dist/utils/brainfile-finder.js.map +1 -0
  292. package/dist/utils/brainfile-path.d.ts +10 -0
  293. package/dist/utils/brainfile-path.d.ts.map +1 -0
  294. package/dist/utils/brainfile-path.js +88 -0
  295. package/dist/utils/brainfile-path.js.map +1 -0
  296. package/dist/utils/cli-error.d.ts +44 -0
  297. package/dist/utils/cli-error.d.ts.map +1 -0
  298. package/dist/utils/cli-error.js +85 -0
  299. package/dist/utils/cli-error.js.map +1 -0
  300. package/dist/utils/config.d.ts +119 -0
  301. package/dist/utils/config.d.ts.map +1 -0
  302. package/dist/utils/config.js +304 -0
  303. package/dist/utils/config.js.map +1 -0
  304. package/dist/utils/contractSpec.d.ts +13 -0
  305. package/dist/utils/contractSpec.d.ts.map +1 -0
  306. package/dist/utils/contractSpec.js +61 -0
  307. package/dist/utils/contractSpec.js.map +1 -0
  308. package/dist/utils/dot-brainfile.d.ts +9 -0
  309. package/dist/utils/dot-brainfile.d.ts.map +1 -0
  310. package/dist/utils/dot-brainfile.js +74 -0
  311. package/dist/utils/dot-brainfile.js.map +1 -0
  312. package/dist/utils/errorHandler.d.ts +106 -0
  313. package/dist/utils/errorHandler.d.ts.map +1 -0
  314. package/dist/utils/errorHandler.js +223 -0
  315. package/dist/utils/errorHandler.js.map +1 -0
  316. package/dist/utils/git-helper.d.ts +17 -0
  317. package/dist/utils/git-helper.d.ts.map +1 -0
  318. package/dist/utils/git-helper.js +62 -0
  319. package/dist/utils/git-helper.js.map +1 -0
  320. package/dist/utils/github-auth.d.ts +56 -0
  321. package/dist/utils/github-auth.d.ts.map +1 -0
  322. package/dist/utils/github-auth.js +341 -0
  323. package/dist/utils/github-auth.js.map +1 -0
  324. package/dist/utils/hook-parser.d.ts +15 -0
  325. package/dist/utils/hook-parser.d.ts.map +1 -0
  326. package/dist/utils/hook-parser.js +69 -0
  327. package/dist/utils/hook-parser.js.map +1 -0
  328. package/dist/utils/hook-settings.d.ts +27 -0
  329. package/dist/utils/hook-settings.d.ts.map +1 -0
  330. package/dist/utils/hook-settings.js +364 -0
  331. package/dist/utils/hook-settings.js.map +1 -0
  332. package/dist/utils/linear-auth.d.ts +59 -0
  333. package/dist/utils/linear-auth.d.ts.map +1 -0
  334. package/dist/utils/linear-auth.js +295 -0
  335. package/dist/utils/linear-auth.js.map +1 -0
  336. package/dist/utils/logger.d.ts +34 -0
  337. package/dist/utils/logger.d.ts.map +1 -0
  338. package/dist/utils/logger.js +56 -0
  339. package/dist/utils/logger.js.map +1 -0
  340. package/dist/utils/strict-validation.d.ts +8 -0
  341. package/dist/utils/strict-validation.d.ts.map +1 -0
  342. package/dist/utils/strict-validation.js +41 -0
  343. package/dist/utils/strict-validation.js.map +1 -0
  344. package/dist/utils/v2-detect.d.ts +28 -0
  345. package/dist/utils/v2-detect.d.ts.map +1 -0
  346. package/dist/utils/v2-detect.js +112 -0
  347. package/dist/utils/v2-detect.js.map +1 -0
  348. package/dist/utils/v2-only.d.ts +9 -0
  349. package/dist/utils/v2-only.d.ts.map +1 -0
  350. package/dist/utils/v2-only.js +64 -0
  351. package/dist/utils/v2-only.js.map +1 -0
  352. package/dist/utils/workspace-format.d.ts +25 -0
  353. package/dist/utils/workspace-format.d.ts.map +1 -0
  354. package/dist/utils/workspace-format.js +106 -0
  355. package/dist/utils/workspace-format.js.map +1 -0
  356. package/dist/validation/command-lint.d.ts +11 -0
  357. package/dist/validation/command-lint.d.ts.map +1 -0
  358. package/dist/validation/command-lint.js +88 -0
  359. package/dist/validation/command-lint.js.map +1 -0
  360. package/package.json +69 -0
@@ -0,0 +1,715 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CONTRACT_GRAPH_HELP = exports.CONTRACT_ACTIVATE_HELP = exports.CONTRACT_ATTACH_HELP = exports.CONTRACT_VALIDATE_HELP = exports.CONTRACT_DELIVER_HELP = exports.CONTRACT_PICKUP_HELP = exports.CONTRACT_COMMAND_HELP = void 0;
37
+ exports.parseContractGraphArgs = parseContractGraphArgs;
38
+ exports.contractGraphCommand = contractGraphCommand;
39
+ exports.contractPickupCommand = contractPickupCommand;
40
+ exports.contractDeliverCommand = contractDeliverCommand;
41
+ exports.contractValidateCommand = contractValidateCommand;
42
+ exports.contractAttachCommand = contractAttachCommand;
43
+ exports.contractActivateCommand = contractActivateCommand;
44
+ const contractRunner_1 = require("../lib/contractRunner");
45
+ const logger_1 = require("../utils/logger");
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const core_1 = require("@brainfile/core");
49
+ const cli_error_1 = require("../utils/cli-error");
50
+ const contractSpec_1 = require("../utils/contractSpec");
51
+ const brainfile_path_1 = require("../utils/brainfile-path");
52
+ const v2_detect_1 = require("../utils/v2-detect");
53
+ const command_lint_1 = require("../validation/command-lint");
54
+ exports.CONTRACT_COMMAND_HELP = `
55
+ Workflow (PM → Agent → PM):
56
+ 1) PM creates a task with a contract:
57
+ brainfile add -c todo -t "Feature" --assignee codex --with-contract --deliverable "file:src/feature.ts:Impl"
58
+
59
+ 2) Agent picks it up (status → in_progress):
60
+ brainfile contract pickup -t task-123
61
+
62
+ 3) Agent delivers (status → delivered):
63
+ brainfile contract deliver -t task-123
64
+
65
+ 4) PM validates (status → done | failed):
66
+ brainfile contract validate -t task-123
67
+
68
+ Contract metrics are tracked on the task file under contract.metrics.
69
+
70
+ Find available contracts:
71
+ brainfile list --contract ready
72
+ `.trimEnd();
73
+ exports.CONTRACT_PICKUP_HELP = `
74
+ Examples:
75
+ brainfile contract pickup -t task-123
76
+ brainfile contract pickup -t task-123 -f .brainfile/brainfile.md
77
+ `.trimEnd();
78
+ exports.CONTRACT_DELIVER_HELP = `
79
+ Examples:
80
+ brainfile contract deliver -t task-123
81
+ `.trimEnd();
82
+ exports.CONTRACT_VALIDATE_HELP = `
83
+ Examples:
84
+ brainfile contract validate -t task-123
85
+ `.trimEnd();
86
+ exports.CONTRACT_ATTACH_HELP = `
87
+ Examples:
88
+ brainfile contract attach -t task-123 \\
89
+ --deliverable "file:src/feature.ts:Implementation" \\
90
+ --validation "npm test" \\
91
+ --constraint "Make minimal changes"
92
+ `.trimEnd();
93
+ exports.CONTRACT_ACTIVATE_HELP = `
94
+ Examples:
95
+ # Activate a single contract (draft → ready)
96
+ brainfile contract activate -t task-123
97
+
98
+ # Activate all draft contracts whose parent is epic-1
99
+ brainfile contract activate --parent epic-1
100
+ `.trimEnd();
101
+ exports.CONTRACT_GRAPH_HELP = `
102
+ Examples:
103
+ brainfile contract graph \\
104
+ --task research-1 --deliverable "file:docs/findings.md" \\
105
+ --task impl-1 --deliverable "file:src/bridge.ts" --depends-on research-1 \\
106
+ --task test-1 --deliverable "test:src/tests/bridge.test.ts" --depends-on impl-1 \\
107
+ --ready
108
+
109
+ brainfile contract graph --show
110
+ `.trimEnd();
111
+ class MissingDependencyError extends Error {
112
+ constructor(taskId, dependencyId) {
113
+ super(`Task ${taskId} depends on missing task ${dependencyId}`);
114
+ this.name = 'MissingDependencyError';
115
+ this.taskId = taskId;
116
+ this.dependencyId = dependencyId;
117
+ }
118
+ }
119
+ class DependencyCycleError extends Error {
120
+ constructor(cycle) {
121
+ super(`Dependency cycle detected: ${cycle.join(' -> ')}`);
122
+ this.name = 'DependencyCycleError';
123
+ this.cycle = cycle;
124
+ }
125
+ }
126
+ function isUnsafeTaskId(taskId) {
127
+ const trimmed = taskId.trim();
128
+ if (!trimmed || trimmed !== taskId) {
129
+ return true;
130
+ }
131
+ if (taskId === '.' || taskId === '..') {
132
+ return true;
133
+ }
134
+ return /[\\/]/.test(taskId);
135
+ }
136
+ function normalizeDependencyIds(dependsOn) {
137
+ if (!Array.isArray(dependsOn)) {
138
+ return undefined;
139
+ }
140
+ const normalized = [...new Set(dependsOn.map((value) => value.trim()).filter(Boolean))];
141
+ return normalized.length > 0 ? normalized : undefined;
142
+ }
143
+ function taskDependsOn(task) {
144
+ const rawDependsOn = task?.dependsOn;
145
+ if (!Array.isArray(rawDependsOn)) {
146
+ return undefined;
147
+ }
148
+ return rawDependsOn.filter((value) => typeof value === 'string');
149
+ }
150
+ function topologicalSort(nodes) {
151
+ const dependenciesById = new Map();
152
+ for (const node of nodes) {
153
+ if (dependenciesById.has(node.id)) {
154
+ throw new Error(`Duplicate graph node: ${node.id}`);
155
+ }
156
+ dependenciesById.set(node.id, normalizeDependencyIds(node.dependsOn ? [...node.dependsOn] : undefined) ?? []);
157
+ }
158
+ const state = new Map();
159
+ const stack = [];
160
+ const order = [];
161
+ const visit = (taskId) => {
162
+ const currentState = state.get(taskId);
163
+ if (currentState === 'done') {
164
+ return;
165
+ }
166
+ if (currentState === 'visiting') {
167
+ const cycleStart = stack.indexOf(taskId);
168
+ const cycle = cycleStart >= 0
169
+ ? [...stack.slice(cycleStart), taskId]
170
+ : [taskId, taskId];
171
+ throw new DependencyCycleError(cycle);
172
+ }
173
+ state.set(taskId, 'visiting');
174
+ stack.push(taskId);
175
+ for (const dependencyId of dependenciesById.get(taskId) ?? []) {
176
+ if (!dependenciesById.has(dependencyId)) {
177
+ throw new MissingDependencyError(taskId, dependencyId);
178
+ }
179
+ visit(dependencyId);
180
+ }
181
+ stack.pop();
182
+ state.set(taskId, 'done');
183
+ order.push(taskId);
184
+ };
185
+ for (const taskId of dependenciesById.keys()) {
186
+ visit(taskId);
187
+ }
188
+ return order;
189
+ }
190
+ function boardTasks(board) {
191
+ return board.columns.flatMap((column) => column.tasks);
192
+ }
193
+ function validateTaskDependencyGraph(tasks) {
194
+ try {
195
+ return topologicalSort(tasks.map((task) => ({
196
+ id: task.id,
197
+ dependsOn: taskDependsOn(task),
198
+ })));
199
+ }
200
+ catch (error) {
201
+ if (error instanceof DependencyCycleError || error instanceof MissingDependencyError) {
202
+ throw (0, cli_error_1.validationError)(error.message);
203
+ }
204
+ throw error;
205
+ }
206
+ }
207
+ function renderTaskDependencyGraph(tasks) {
208
+ if (tasks.length === 0) {
209
+ return '(no active tasks)';
210
+ }
211
+ const order = validateTaskDependencyGraph(tasks);
212
+ const taskById = new Map(tasks.map((task) => [task.id, task]));
213
+ return order
214
+ .map((taskId) => {
215
+ const dependsOn = normalizeDependencyIds(taskDependsOn(taskById.get(taskId)));
216
+ return dependsOn && dependsOn.length > 0
217
+ ? `${dependsOn.join(', ')} -> ${taskId}`
218
+ : taskId;
219
+ })
220
+ .join('\n');
221
+ }
222
+ function updateBoardTask(board, taskId, updater) {
223
+ let found = false;
224
+ const columns = board.columns.map((column) => ({
225
+ ...column,
226
+ tasks: column.tasks.map((task) => {
227
+ if (task.id !== taskId) {
228
+ return task;
229
+ }
230
+ found = true;
231
+ return updater(task);
232
+ }),
233
+ }));
234
+ if (!found) {
235
+ throw (0, cli_error_1.operationFailed)(`Task not found: ${taskId}`);
236
+ }
237
+ return { ...board, columns };
238
+ }
239
+ function applyGraphTaskUpdate(task, spec, ready, now) {
240
+ let contract;
241
+ try {
242
+ contract = (0, contractSpec_1.buildContract)({
243
+ deliverableSpecs: spec.deliverable,
244
+ validationCommands: spec.validation,
245
+ constraints: spec.constraint,
246
+ status: ready ? 'ready' : 'draft',
247
+ });
248
+ }
249
+ catch (error) {
250
+ throw (0, cli_error_1.validationError)(error.message);
251
+ }
252
+ const nextTask = {
253
+ ...task,
254
+ contract,
255
+ updatedAt: now,
256
+ };
257
+ if (spec.dependsOn !== undefined) {
258
+ const normalized = normalizeDependencyIds(spec.dependsOn);
259
+ if (normalized) {
260
+ nextTask.dependsOn = normalized;
261
+ }
262
+ else {
263
+ delete nextTask.dependsOn;
264
+ }
265
+ }
266
+ return nextTask;
267
+ }
268
+ function ensureUniqueGraphTasks(specs) {
269
+ const seen = new Set();
270
+ for (const spec of specs) {
271
+ if (seen.has(spec.task)) {
272
+ throw (0, cli_error_1.validationError)(`Duplicate task in graph input: ${spec.task}`);
273
+ }
274
+ seen.add(spec.task);
275
+ }
276
+ }
277
+ function loadActiveTasks(filePath) {
278
+ if ((0, v2_detect_1.isV2)(filePath)) {
279
+ const dirs = (0, v2_detect_1.getV2Dirs)(filePath);
280
+ return (0, core_1.readTasksDir)(dirs.boardDir).map((doc) => doc.task);
281
+ }
282
+ const content = fs.readFileSync(filePath, 'utf-8');
283
+ const parsed = core_1.Brainfile.parseWithErrors(content);
284
+ if (!parsed.board) {
285
+ throw (0, cli_error_1.operationFailed)(parsed.error || 'Failed to parse brainfile');
286
+ }
287
+ return boardTasks(parsed.board);
288
+ }
289
+ function parseContractGraphArgs(args) {
290
+ const options = {
291
+ file: 'brainfile.md',
292
+ tasks: [],
293
+ };
294
+ let currentTask;
295
+ const readValue = (index, flag) => {
296
+ const value = args[index + 1];
297
+ if (value === undefined) {
298
+ throw (0, cli_error_1.validationError)(`Missing value for ${flag}`);
299
+ }
300
+ return value;
301
+ };
302
+ const pushValue = (spec, key, value, flag) => {
303
+ if (!spec) {
304
+ throw (0, cli_error_1.validationError)(`${flag} must follow a --task declaration`);
305
+ }
306
+ const existing = spec[key];
307
+ if (!existing) {
308
+ spec[key] = [value];
309
+ return;
310
+ }
311
+ spec[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];
312
+ };
313
+ for (let index = 0; index < args.length; index += 1) {
314
+ const token = args[index];
315
+ switch (token) {
316
+ case '-f':
317
+ case '--file':
318
+ options.file = readValue(index, token);
319
+ index += 1;
320
+ break;
321
+ case '--ready':
322
+ options.ready = true;
323
+ break;
324
+ case '--show':
325
+ options.show = true;
326
+ break;
327
+ case '-t':
328
+ case '--task': {
329
+ const task = readValue(index, token);
330
+ currentTask = { task };
331
+ options.tasks.push(currentTask);
332
+ index += 1;
333
+ break;
334
+ }
335
+ case '--deliverable':
336
+ pushValue(currentTask, 'deliverable', readValue(index, token), token);
337
+ index += 1;
338
+ break;
339
+ case '--validation':
340
+ pushValue(currentTask, 'validation', readValue(index, token), token);
341
+ index += 1;
342
+ break;
343
+ case '--constraint':
344
+ pushValue(currentTask, 'constraint', readValue(index, token), token);
345
+ index += 1;
346
+ break;
347
+ case '--depends-on':
348
+ if (!currentTask) {
349
+ throw (0, cli_error_1.validationError)('--depends-on must follow a --task declaration');
350
+ }
351
+ currentTask.dependsOn = [...(currentTask.dependsOn ?? []), readValue(index, token)];
352
+ index += 1;
353
+ break;
354
+ default:
355
+ throw (0, cli_error_1.validationError)(`Unknown contract graph flag: ${token}`);
356
+ }
357
+ }
358
+ if (options.show && options.tasks.length > 0) {
359
+ throw (0, cli_error_1.validationError)('--show cannot be combined with task graph mutations');
360
+ }
361
+ if (!options.show && options.tasks.length === 0) {
362
+ throw (0, cli_error_1.missingRequired)('--task', 'brainfile contract graph --task <task-id> [graph options]');
363
+ }
364
+ return options;
365
+ }
366
+ function contractGraphCommand(options, logger = logger_1.defaultLogger) {
367
+ const filePath = (0, brainfile_path_1.resolveCliBrainfilePath)(options.file);
368
+ if (!fs.existsSync(filePath)) {
369
+ throw (0, cli_error_1.operationFailed)(`File not found: ${filePath}`);
370
+ }
371
+ if (options.show) {
372
+ const activeTasks = loadActiveTasks(filePath);
373
+ const graph = renderTaskDependencyGraph(activeTasks);
374
+ logger.log(graph);
375
+ return { success: true, attached: [], order: validateTaskDependencyGraph(activeTasks), graph };
376
+ }
377
+ const specs = options.tasks ?? [];
378
+ ensureUniqueGraphTasks(specs);
379
+ const now = new Date().toISOString();
380
+ if ((0, v2_detect_1.isV2)(filePath)) {
381
+ const dirs = (0, v2_detect_1.getV2Dirs)(filePath);
382
+ const docs = (0, core_1.readTasksDir)(dirs.boardDir);
383
+ const docById = new Map(docs.map((doc) => [doc.task.id, doc]));
384
+ for (const spec of specs) {
385
+ if (isUnsafeTaskId(spec.task)) {
386
+ throw (0, cli_error_1.operationFailed)(`Invalid task ID: ${spec.task}`);
387
+ }
388
+ if (!docById.has(spec.task)) {
389
+ throw (0, cli_error_1.operationFailed)(`Task not found: ${spec.task}`);
390
+ }
391
+ }
392
+ const nextTasks = new Map(docs.map((doc) => [doc.task.id, { ...doc.task }]));
393
+ for (const spec of specs) {
394
+ nextTasks.set(spec.task, applyGraphTaskUpdate(nextTasks.get(spec.task), spec, Boolean(options.ready), now));
395
+ }
396
+ const order = validateTaskDependencyGraph([...nextTasks.values()]);
397
+ const graph = renderTaskDependencyGraph([...nextTasks.values()]);
398
+ for (const taskId of order) {
399
+ if (!specs.some((spec) => spec.task === taskId)) {
400
+ continue;
401
+ }
402
+ const doc = docById.get(taskId);
403
+ (0, core_1.writeTaskFile)(doc.filePath, nextTasks.get(taskId), doc.body);
404
+ }
405
+ logger.log(`Contract graph attached (${options.ready ? 'ready' : 'draft'}): ${specs.map((spec) => spec.task).join(', ')}`);
406
+ return {
407
+ success: true,
408
+ attached: specs.map((spec) => spec.task),
409
+ order,
410
+ graph,
411
+ };
412
+ }
413
+ const content = fs.readFileSync(filePath, 'utf-8');
414
+ const parsed = core_1.Brainfile.parseWithErrors(content);
415
+ if (!parsed.board) {
416
+ throw (0, cli_error_1.operationFailed)(parsed.error || 'Failed to parse brainfile');
417
+ }
418
+ let board = parsed.board;
419
+ for (const spec of specs) {
420
+ if (!(0, core_1.findTaskById)(board, spec.task)) {
421
+ throw (0, cli_error_1.operationFailed)(`Task not found: ${spec.task}`);
422
+ }
423
+ board = updateBoardTask(board, spec.task, (task) => applyGraphTaskUpdate(task, spec, Boolean(options.ready), now));
424
+ }
425
+ const order = validateTaskDependencyGraph(boardTasks(board));
426
+ const graph = renderTaskDependencyGraph(boardTasks(board));
427
+ fs.writeFileSync(filePath, core_1.Brainfile.serialize(board), 'utf-8');
428
+ logger.log(`Contract graph attached (${options.ready ? 'ready' : 'draft'}): ${specs.map((spec) => spec.task).join(', ')}`);
429
+ return {
430
+ success: true,
431
+ attached: specs.map((spec) => spec.task),
432
+ order,
433
+ graph,
434
+ };
435
+ }
436
+ function contractPickupCommand(options, logger = logger_1.defaultLogger) {
437
+ if (!options.task) {
438
+ throw (0, cli_error_1.missingRequired)('--task', 'brainfile contract pickup --task <task-id> [--file <path>]');
439
+ }
440
+ const filePath = (0, brainfile_path_1.resolveCliBrainfilePath)(options.file);
441
+ const result = (0, contractRunner_1.pickupContract)({ filePath, taskId: options.task });
442
+ if ('error' in result) {
443
+ throw (0, cli_error_1.operationFailed)(result.error);
444
+ }
445
+ logger.log(result.markdown);
446
+ return { success: true, markdown: result.markdown };
447
+ }
448
+ function contractDeliverCommand(options, logger = logger_1.defaultLogger) {
449
+ if (!options.task) {
450
+ throw (0, cli_error_1.missingRequired)('--task', 'brainfile contract deliver --task <task-id> [--file <path>]');
451
+ }
452
+ const filePath = (0, brainfile_path_1.resolveCliBrainfilePath)(options.file);
453
+ const result = (0, contractRunner_1.deliverContract)({ filePath, taskId: options.task });
454
+ if ('error' in result) {
455
+ throw (0, cli_error_1.operationFailed)(result.error);
456
+ }
457
+ logger.log(`Contract delivered: ${options.task}`);
458
+ return { success: true };
459
+ }
460
+ function contractValidateCommand(options, logger = logger_1.defaultLogger) {
461
+ if (!options.task) {
462
+ throw (0, cli_error_1.missingRequired)('--task', 'brainfile contract validate --task <task-id> [--file <path>]');
463
+ }
464
+ const filePath = (0, brainfile_path_1.resolveCliBrainfilePath)(options.file);
465
+ const result = (0, contractRunner_1.validateContract)({ filePath, taskId: options.task });
466
+ if ('error' in result) {
467
+ throw (0, cli_error_1.operationFailed)(result.error);
468
+ }
469
+ const deliverablesOk = result.deliverableChecks.every((c) => c.ok);
470
+ const commandsOk = result.commandResults.every((c) => c.exitCode === 0);
471
+ const ok = result.ok;
472
+ // Show warnings first (before success/fail status)
473
+ if (result.warnings.length > 0) {
474
+ logger.log('');
475
+ logger.log('⚠️ Warnings:');
476
+ for (const warning of result.warnings) {
477
+ logger.log(` Command: ${warning.command}`);
478
+ logger.log(` ${warning.message}`);
479
+ logger.log('');
480
+ }
481
+ }
482
+ logger.log(`Contract validation ${ok ? 'passed' : 'failed'}: ${options.task}`);
483
+ if (!deliverablesOk) {
484
+ logger.log('');
485
+ logger.log('Deliverables:');
486
+ for (const check of result.deliverableChecks) {
487
+ if (check.deliverable.type !== 'file')
488
+ continue;
489
+ const status = check.ok ? 'OK' : 'MISSING';
490
+ logger.log(`- [${status}] ${check.deliverable.path}${check.resolvedPath ? ` (${check.resolvedPath})` : ''}`);
491
+ }
492
+ }
493
+ if (!commandsOk && result.commandResults.length > 0) {
494
+ logger.log('');
495
+ logger.log('Validation commands:');
496
+ for (const cmd of result.commandResults) {
497
+ logger.log(`- [${cmd.exitCode === 0 ? 'OK' : `FAIL(${cmd.exitCode})`}] ${cmd.command}`);
498
+ }
499
+ }
500
+ return { success: ok };
501
+ }
502
+ /**
503
+ * Attach a new contract to an existing task (default status=draft).
504
+ * This is for programmatic contract creation (no manual YAML editing).
505
+ * Pass ready:true via options to make the contract immediately dispatchable.
506
+ */
507
+ function contractAttachCommand(options, logger = logger_1.defaultLogger) {
508
+ if (!options.task) {
509
+ throw (0, cli_error_1.missingRequired)('--task', 'brainfile contract attach --task <task-id> [--file <path>] [--deliverable ...]');
510
+ }
511
+ const filePath = (0, brainfile_path_1.resolveCliBrainfilePath)(options.file);
512
+ if (!fs.existsSync(filePath)) {
513
+ throw (0, cli_error_1.operationFailed)(`File not found: ${filePath}`);
514
+ }
515
+ const validationCommands = Array.isArray(options.validation)
516
+ ? options.validation
517
+ : options.validation
518
+ ? [options.validation]
519
+ : [];
520
+ for (const warning of (0, command_lint_1.lintValidationCommands)(validationCommands, filePath)) {
521
+ logger.warn(`Warning: ${warning.message}`);
522
+ }
523
+ let contract;
524
+ try {
525
+ contract = (0, contractSpec_1.buildContract)({
526
+ deliverableSpecs: options.deliverable,
527
+ validationCommands: options.validation,
528
+ constraints: options.constraint,
529
+ status: options.ready ? 'ready' : 'draft',
530
+ });
531
+ }
532
+ catch (e) {
533
+ throw (0, cli_error_1.validationError)(e.message);
534
+ }
535
+ if ((0, v2_detect_1.isV2)(filePath)) {
536
+ if (isUnsafeTaskId(options.task)) {
537
+ throw (0, cli_error_1.operationFailed)(`Invalid task ID: ${options.task}`);
538
+ }
539
+ const dirs = (0, v2_detect_1.getV2Dirs)(filePath);
540
+ const found = (0, v2_detect_1.findV2Task)(dirs, options.task, false);
541
+ if (!found || found.isLog) {
542
+ throw (0, cli_error_1.operationFailed)(`Task not found: ${options.task}`);
543
+ }
544
+ found.doc.task.contract = contract;
545
+ (0, core_1.writeTaskFile)(found.filePath, found.doc.task, found.doc.body);
546
+ logger.log(`Contract attached: ${options.task}`);
547
+ return { success: true };
548
+ }
549
+ const content = fs.readFileSync(filePath, 'utf-8');
550
+ const parsed = core_1.Brainfile.parseWithErrors(content);
551
+ if (!parsed.board) {
552
+ throw (0, cli_error_1.operationFailed)(parsed.error || 'Failed to parse brainfile');
553
+ }
554
+ const taskInfo = (0, core_1.findTaskById)(parsed.board, options.task);
555
+ if (!taskInfo) {
556
+ throw (0, cli_error_1.operationFailed)(`Task not found: ${options.task}`);
557
+ }
558
+ const result = (0, core_1.setTaskContract)(parsed.board, options.task, contract);
559
+ if (!result.success || !result.board) {
560
+ throw (0, cli_error_1.operationFailed)(result.error || 'Failed to attach contract');
561
+ }
562
+ fs.writeFileSync(filePath, core_1.Brainfile.serialize(result.board), 'utf-8');
563
+ logger.log(`Contract attached: ${options.task}`);
564
+ return { success: true };
565
+ }
566
+ /**
567
+ * Activate one or more draft contracts (draft → ready).
568
+ *
569
+ * - Single task: `--task <id>`
570
+ * - Bulk by parent: `--parent <epic-id>` (activates all draft children)
571
+ */
572
+ function contractActivateCommand(options, logger = logger_1.defaultLogger) {
573
+ if (!options.task && !options.parent) {
574
+ throw (0, cli_error_1.missingRequired)('--task or --parent', 'brainfile contract activate -t <task-id> | --parent <epic-id>');
575
+ }
576
+ const filePath = (0, brainfile_path_1.resolveCliBrainfilePath)(options.file);
577
+ if (!fs.existsSync(filePath)) {
578
+ throw (0, cli_error_1.operationFailed)(`File not found: ${filePath}`);
579
+ }
580
+ const activated = [];
581
+ // ── V2 per-task file architecture ──────────────────────────────────────────
582
+ if ((0, v2_detect_1.isV2)(filePath)) {
583
+ const dirs = (0, v2_detect_1.getV2Dirs)(filePath);
584
+ if (options.task) {
585
+ // Single task activation
586
+ if (isUnsafeTaskId(options.task)) {
587
+ throw (0, cli_error_1.operationFailed)(`Invalid task ID: ${options.task}`);
588
+ }
589
+ const found = (0, v2_detect_1.findV2Task)(dirs, options.task, false);
590
+ if (!found || found.isLog) {
591
+ throw (0, cli_error_1.operationFailed)(`Task not found: ${options.task}`);
592
+ }
593
+ if (!found.doc.task.contract) {
594
+ throw (0, cli_error_1.operationFailed)(`Task ${options.task} has no contract`);
595
+ }
596
+ if (found.doc.task.contract.status !== 'draft') {
597
+ throw (0, cli_error_1.operationFailed)(`Contract is not in draft status (current: ${found.doc.task.contract.status})`);
598
+ }
599
+ const readyAt = new Date().toISOString();
600
+ found.doc.task.contract = {
601
+ ...found.doc.task.contract,
602
+ status: 'ready',
603
+ metrics: {
604
+ ...(found.doc.task.contract.metrics ?? {}),
605
+ readyAt,
606
+ },
607
+ };
608
+ found.doc.task.updatedAt = readyAt;
609
+ (0, core_1.writeTaskFile)(found.filePath, found.doc.task, found.doc.body);
610
+ activated.push(options.task);
611
+ logger.log(`Contract activated: ${options.task}`);
612
+ }
613
+ else {
614
+ // Bulk activation by parentId
615
+ const parentId = options.parent;
616
+ const allTasks = (0, core_1.readTasksDir)(dirs.boardDir);
617
+ for (const doc of allTasks) {
618
+ const task = doc.task;
619
+ if (task.parentId !== parentId)
620
+ continue;
621
+ if (!task.contract || task.contract.status !== 'draft')
622
+ continue;
623
+ const readyAt = new Date().toISOString();
624
+ task.contract = {
625
+ ...task.contract,
626
+ status: 'ready',
627
+ metrics: {
628
+ ...(task.contract.metrics ?? {}),
629
+ readyAt,
630
+ },
631
+ };
632
+ task.updatedAt = readyAt;
633
+ const taskPath = path.join(dirs.boardDir, (0, core_1.taskFileName)(task.id));
634
+ (0, core_1.writeTaskFile)(taskPath, task, doc.body);
635
+ activated.push(task.id);
636
+ logger.log(`Contract activated: ${task.id}`);
637
+ }
638
+ if (activated.length === 0) {
639
+ logger.log(`No draft contracts found with parent: ${parentId}`);
640
+ }
641
+ }
642
+ return { success: true, activated };
643
+ }
644
+ // ── V1 board ──────────────────────────────────────────────────────────────
645
+ const content = fs.readFileSync(filePath, 'utf-8');
646
+ const parsed = core_1.Brainfile.parseWithErrors(content);
647
+ if (!parsed.board) {
648
+ throw (0, cli_error_1.operationFailed)(parsed.error || 'Failed to parse brainfile');
649
+ }
650
+ let board = parsed.board;
651
+ if (options.task) {
652
+ // Single task
653
+ const taskInfo = (0, core_1.findTaskById)(board, options.task);
654
+ if (!taskInfo) {
655
+ throw (0, cli_error_1.operationFailed)(`Task not found: ${options.task}`);
656
+ }
657
+ if (!taskInfo.task.contract) {
658
+ throw (0, cli_error_1.operationFailed)(`Task ${options.task} has no contract`);
659
+ }
660
+ if (taskInfo.task.contract.status !== 'draft') {
661
+ throw (0, cli_error_1.operationFailed)(`Contract is not in draft status (current: ${taskInfo.task.contract.status})`);
662
+ }
663
+ // Mutate via setTaskContract (re-attach with status=ready)
664
+ const readyAt = new Date().toISOString();
665
+ const updatedContract = {
666
+ ...taskInfo.task.contract,
667
+ status: 'ready',
668
+ metrics: {
669
+ ...(taskInfo.task.contract.metrics ?? {}),
670
+ readyAt,
671
+ },
672
+ };
673
+ const result = (0, core_1.setTaskContract)(board, options.task, updatedContract);
674
+ if (!result.success || !result.board) {
675
+ throw (0, cli_error_1.operationFailed)(result.error || 'Failed to activate contract');
676
+ }
677
+ board = result.board;
678
+ activated.push(options.task);
679
+ logger.log(`Contract activated: ${options.task}`);
680
+ }
681
+ else {
682
+ // Bulk by parentId (V1 boards store parentId on task)
683
+ const parentId = options.parent;
684
+ for (const col of board.columns) {
685
+ for (const task of col.tasks) {
686
+ const t = task;
687
+ if (t.parentId !== parentId)
688
+ continue;
689
+ if (!task.contract || task.contract.status !== 'draft')
690
+ continue;
691
+ const readyAt = new Date().toISOString();
692
+ const updatedContract = {
693
+ ...task.contract,
694
+ status: 'ready',
695
+ metrics: {
696
+ ...(task.contract.metrics ?? {}),
697
+ readyAt,
698
+ },
699
+ };
700
+ const result = (0, core_1.setTaskContract)(board, task.id, updatedContract);
701
+ if (result.success && result.board) {
702
+ board = result.board;
703
+ activated.push(task.id);
704
+ logger.log(`Contract activated: ${task.id}`);
705
+ }
706
+ }
707
+ }
708
+ if (activated.length === 0) {
709
+ logger.log(`No draft contracts found with parent: ${parentId}`);
710
+ }
711
+ }
712
+ fs.writeFileSync(filePath, core_1.Brainfile.serialize(board), 'utf-8');
713
+ return { success: true, activated };
714
+ }
715
+ //# sourceMappingURL=contract.js.map