@kynetic-ai/spec 0.1.2 → 0.4.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 (540) hide show
  1. package/README.md +250 -17
  2. package/dist/acp/client.d.ts +18 -4
  3. package/dist/acp/client.d.ts.map +1 -1
  4. package/dist/acp/client.js +44 -26
  5. package/dist/acp/client.js.map +1 -1
  6. package/dist/acp/framing.d.ts +2 -2
  7. package/dist/acp/framing.d.ts.map +1 -1
  8. package/dist/acp/framing.js +37 -29
  9. package/dist/acp/framing.js.map +1 -1
  10. package/dist/acp/index.d.ts +6 -7
  11. package/dist/acp/index.d.ts.map +1 -1
  12. package/dist/acp/index.js +3 -3
  13. package/dist/acp/index.js.map +1 -1
  14. package/dist/acp/types.d.ts +5 -5
  15. package/dist/acp/types.d.ts.map +1 -1
  16. package/dist/acp/types.js +18 -18
  17. package/dist/acp/types.js.map +1 -1
  18. package/dist/agents/adapters.d.ts.map +1 -1
  19. package/dist/agents/adapters.js +24 -13
  20. package/dist/agents/adapters.js.map +1 -1
  21. package/dist/agents/index.d.ts +2 -2
  22. package/dist/agents/index.js +2 -2
  23. package/dist/agents/spawner.d.ts +4 -4
  24. package/dist/agents/spawner.d.ts.map +1 -1
  25. package/dist/agents/spawner.js +6 -6
  26. package/dist/agents/spawner.js.map +1 -1
  27. package/dist/cli/batch-context.d.ts +43 -0
  28. package/dist/cli/batch-context.d.ts.map +1 -0
  29. package/dist/cli/batch-context.js +93 -0
  30. package/dist/cli/batch-context.js.map +1 -0
  31. package/dist/cli/batch-exec.d.ts +107 -0
  32. package/dist/cli/batch-exec.d.ts.map +1 -0
  33. package/dist/cli/batch-exec.js +706 -0
  34. package/dist/cli/batch-exec.js.map +1 -0
  35. package/dist/cli/batch.d.ts +4 -2
  36. package/dist/cli/batch.d.ts.map +1 -1
  37. package/dist/cli/batch.js +15 -14
  38. package/dist/cli/batch.js.map +1 -1
  39. package/dist/cli/command-annotations.d.ts +23 -0
  40. package/dist/cli/command-annotations.d.ts.map +1 -0
  41. package/dist/cli/command-annotations.js +27 -0
  42. package/dist/cli/command-annotations.js.map +1 -0
  43. package/dist/cli/commands/agents.d.ts +46 -0
  44. package/dist/cli/commands/agents.d.ts.map +1 -0
  45. package/dist/cli/commands/agents.js +377 -0
  46. package/dist/cli/commands/agents.js.map +1 -0
  47. package/dist/cli/commands/batch.d.ts +20 -0
  48. package/dist/cli/commands/batch.d.ts.map +1 -0
  49. package/dist/cli/commands/batch.js +214 -0
  50. package/dist/cli/commands/batch.js.map +1 -0
  51. package/dist/cli/commands/clone-for-testing.d.ts +1 -1
  52. package/dist/cli/commands/clone-for-testing.d.ts.map +1 -1
  53. package/dist/cli/commands/clone-for-testing.js +37 -47
  54. package/dist/cli/commands/clone-for-testing.js.map +1 -1
  55. package/dist/cli/commands/derive.d.ts +1 -1
  56. package/dist/cli/commands/derive.d.ts.map +1 -1
  57. package/dist/cli/commands/derive.js +141 -88
  58. package/dist/cli/commands/derive.js.map +1 -1
  59. package/dist/cli/commands/doctor.d.ts +11 -0
  60. package/dist/cli/commands/doctor.d.ts.map +1 -0
  61. package/dist/cli/commands/doctor.js +152 -0
  62. package/dist/cli/commands/doctor.js.map +1 -0
  63. package/dist/cli/commands/export.d.ts +12 -0
  64. package/dist/cli/commands/export.d.ts.map +1 -0
  65. package/dist/cli/commands/export.js +134 -0
  66. package/dist/cli/commands/export.js.map +1 -0
  67. package/dist/cli/commands/help.d.ts +1 -1
  68. package/dist/cli/commands/help.d.ts.map +1 -1
  69. package/dist/cli/commands/help.js +163 -37
  70. package/dist/cli/commands/help.js.map +1 -1
  71. package/dist/cli/commands/inbox.d.ts +1 -1
  72. package/dist/cli/commands/inbox.d.ts.map +1 -1
  73. package/dist/cli/commands/inbox.js +178 -56
  74. package/dist/cli/commands/inbox.js.map +1 -1
  75. package/dist/cli/commands/index.d.ts +31 -19
  76. package/dist/cli/commands/index.d.ts.map +1 -1
  77. package/dist/cli/commands/index.js +31 -19
  78. package/dist/cli/commands/index.js.map +1 -1
  79. package/dist/cli/commands/init.d.ts +5 -1
  80. package/dist/cli/commands/init.d.ts.map +1 -1
  81. package/dist/cli/commands/init.js +108 -57
  82. package/dist/cli/commands/init.js.map +1 -1
  83. package/dist/cli/commands/item.d.ts +1 -1
  84. package/dist/cli/commands/item.d.ts.map +1 -1
  85. package/dist/cli/commands/item.js +557 -274
  86. package/dist/cli/commands/item.js.map +1 -1
  87. package/dist/cli/commands/link.d.ts +1 -1
  88. package/dist/cli/commands/link.d.ts.map +1 -1
  89. package/dist/cli/commands/link.js +55 -46
  90. package/dist/cli/commands/link.js.map +1 -1
  91. package/dist/cli/commands/log.d.ts +1 -1
  92. package/dist/cli/commands/log.d.ts.map +1 -1
  93. package/dist/cli/commands/log.js +58 -51
  94. package/dist/cli/commands/log.js.map +1 -1
  95. package/dist/cli/commands/merge-driver.d.ts +19 -0
  96. package/dist/cli/commands/merge-driver.d.ts.map +1 -0
  97. package/dist/cli/commands/merge-driver.js +398 -0
  98. package/dist/cli/commands/merge-driver.js.map +1 -0
  99. package/dist/cli/commands/meta.d.ts +1 -1
  100. package/dist/cli/commands/meta.d.ts.map +1 -1
  101. package/dist/cli/commands/meta.js +534 -399
  102. package/dist/cli/commands/meta.js.map +1 -1
  103. package/dist/cli/commands/module.d.ts +1 -1
  104. package/dist/cli/commands/module.d.ts.map +1 -1
  105. package/dist/cli/commands/module.js +30 -25
  106. package/dist/cli/commands/module.js.map +1 -1
  107. package/dist/cli/commands/plan-import.d.ts +11 -0
  108. package/dist/cli/commands/plan-import.d.ts.map +1 -0
  109. package/dist/cli/commands/plan-import.js +547 -0
  110. package/dist/cli/commands/plan-import.js.map +1 -0
  111. package/dist/cli/commands/plan.d.ts +10 -0
  112. package/dist/cli/commands/plan.d.ts.map +1 -0
  113. package/dist/cli/commands/plan.js +421 -0
  114. package/dist/cli/commands/plan.js.map +1 -0
  115. package/dist/cli/commands/ralph.d.ts +1 -1
  116. package/dist/cli/commands/ralph.d.ts.map +1 -1
  117. package/dist/cli/commands/ralph.js +1109 -170
  118. package/dist/cli/commands/ralph.js.map +1 -1
  119. package/dist/cli/commands/refs.d.ts +13 -0
  120. package/dist/cli/commands/refs.d.ts.map +1 -0
  121. package/dist/cli/commands/refs.js +283 -0
  122. package/dist/cli/commands/refs.js.map +1 -0
  123. package/dist/cli/commands/search.d.ts +1 -1
  124. package/dist/cli/commands/search.d.ts.map +1 -1
  125. package/dist/cli/commands/search.js +199 -37
  126. package/dist/cli/commands/search.js.map +1 -1
  127. package/dist/cli/commands/serve.d.ts +10 -0
  128. package/dist/cli/commands/serve.d.ts.map +1 -0
  129. package/dist/cli/commands/serve.js +491 -0
  130. package/dist/cli/commands/serve.js.map +1 -0
  131. package/dist/cli/commands/session.d.ts +25 -6
  132. package/dist/cli/commands/session.d.ts.map +1 -1
  133. package/dist/cli/commands/session.js +810 -127
  134. package/dist/cli/commands/session.js.map +1 -1
  135. package/dist/cli/commands/setup-seeding.d.ts +81 -0
  136. package/dist/cli/commands/setup-seeding.d.ts.map +1 -0
  137. package/dist/cli/commands/setup-seeding.js +292 -0
  138. package/dist/cli/commands/setup-seeding.js.map +1 -0
  139. package/dist/cli/commands/setup.d.ts +77 -3
  140. package/dist/cli/commands/setup.d.ts.map +1 -1
  141. package/dist/cli/commands/setup.js +1267 -274
  142. package/dist/cli/commands/setup.js.map +1 -1
  143. package/dist/cli/commands/shadow.d.ts +1 -1
  144. package/dist/cli/commands/shadow.d.ts.map +1 -1
  145. package/dist/cli/commands/shadow.js +70 -50
  146. package/dist/cli/commands/shadow.js.map +1 -1
  147. package/dist/cli/commands/skill-crud.d.ts +58 -0
  148. package/dist/cli/commands/skill-crud.d.ts.map +1 -0
  149. package/dist/cli/commands/skill-crud.js +753 -0
  150. package/dist/cli/commands/skill-crud.js.map +1 -0
  151. package/dist/cli/commands/skill-diff.d.ts +27 -0
  152. package/dist/cli/commands/skill-diff.d.ts.map +1 -0
  153. package/dist/cli/commands/skill-diff.js +840 -0
  154. package/dist/cli/commands/skill-diff.js.map +1 -0
  155. package/dist/cli/commands/skill-install.d.ts +56 -0
  156. package/dist/cli/commands/skill-install.d.ts.map +1 -0
  157. package/dist/cli/commands/skill-install.js +509 -0
  158. package/dist/cli/commands/skill-install.js.map +1 -0
  159. package/dist/cli/commands/skill.d.ts +20 -0
  160. package/dist/cli/commands/skill.d.ts.map +1 -0
  161. package/dist/cli/commands/skill.js +36 -0
  162. package/dist/cli/commands/skill.js.map +1 -0
  163. package/dist/cli/commands/task.d.ts +1 -1
  164. package/dist/cli/commands/task.d.ts.map +1 -1
  165. package/dist/cli/commands/task.js +584 -350
  166. package/dist/cli/commands/task.js.map +1 -1
  167. package/dist/cli/commands/tasks.d.ts +26 -1
  168. package/dist/cli/commands/tasks.d.ts.map +1 -1
  169. package/dist/cli/commands/tasks.js +225 -122
  170. package/dist/cli/commands/tasks.js.map +1 -1
  171. package/dist/cli/commands/trait.d.ts +1 -1
  172. package/dist/cli/commands/trait.d.ts.map +1 -1
  173. package/dist/cli/commands/trait.js +166 -101
  174. package/dist/cli/commands/trait.js.map +1 -1
  175. package/dist/cli/commands/triage.d.ts +7 -0
  176. package/dist/cli/commands/triage.d.ts.map +1 -0
  177. package/dist/cli/commands/triage.js +483 -0
  178. package/dist/cli/commands/triage.js.map +1 -0
  179. package/dist/cli/commands/util.d.ts +7 -0
  180. package/dist/cli/commands/util.d.ts.map +1 -0
  181. package/dist/cli/commands/util.js +30 -0
  182. package/dist/cli/commands/util.js.map +1 -0
  183. package/dist/cli/commands/validate.d.ts +1 -1
  184. package/dist/cli/commands/validate.d.ts.map +1 -1
  185. package/dist/cli/commands/validate.js +264 -83
  186. package/dist/cli/commands/validate.js.map +1 -1
  187. package/dist/cli/commands/workflow.d.ts +16 -0
  188. package/dist/cli/commands/workflow.d.ts.map +1 -0
  189. package/dist/cli/commands/workflow.js +851 -0
  190. package/dist/cli/commands/workflow.js.map +1 -0
  191. package/dist/cli/exit-codes.d.ts +7 -0
  192. package/dist/cli/exit-codes.d.ts.map +1 -1
  193. package/dist/cli/exit-codes.js +26 -18
  194. package/dist/cli/exit-codes.js.map +1 -1
  195. package/dist/cli/help/content.d.ts.map +1 -1
  196. package/dist/cli/help/content.js +86 -71
  197. package/dist/cli/help/content.js.map +1 -1
  198. package/dist/cli/index.d.ts +1 -1
  199. package/dist/cli/index.d.ts.map +1 -1
  200. package/dist/cli/index.js +131 -19
  201. package/dist/cli/index.js.map +1 -1
  202. package/dist/cli/introspection.d.ts +6 -2
  203. package/dist/cli/introspection.d.ts.map +1 -1
  204. package/dist/cli/introspection.js +11 -8
  205. package/dist/cli/introspection.js.map +1 -1
  206. package/dist/cli/output.d.ts +64 -4
  207. package/dist/cli/output.d.ts.map +1 -1
  208. package/dist/cli/output.js +237 -85
  209. package/dist/cli/output.js.map +1 -1
  210. package/dist/cli/parse-utils.d.ts +21 -0
  211. package/dist/cli/parse-utils.d.ts.map +1 -0
  212. package/dist/cli/parse-utils.js +32 -0
  213. package/dist/cli/parse-utils.js.map +1 -0
  214. package/dist/cli/pid-utils.d.ts +72 -0
  215. package/dist/cli/pid-utils.d.ts.map +1 -0
  216. package/dist/cli/pid-utils.js +174 -0
  217. package/dist/cli/pid-utils.js.map +1 -0
  218. package/dist/cli/suggest.d.ts.map +1 -1
  219. package/dist/cli/suggest.js +1 -2
  220. package/dist/cli/suggest.js.map +1 -1
  221. package/dist/cli/validators.d.ts +43 -0
  222. package/dist/cli/validators.d.ts.map +1 -0
  223. package/dist/cli/validators.js +84 -0
  224. package/dist/cli/validators.js.map +1 -0
  225. package/dist/daemon/index.ts +52 -0
  226. package/dist/daemon/middleware/project-context.ts +126 -0
  227. package/dist/daemon/pid.ts +179 -0
  228. package/dist/daemon/project-context.ts +343 -0
  229. package/dist/daemon/routes/inbox.ts +164 -0
  230. package/dist/daemon/routes/items.ts +322 -0
  231. package/dist/daemon/routes/meta.ts +118 -0
  232. package/dist/daemon/routes/projects.ts +162 -0
  233. package/dist/daemon/routes/tasks.ts +327 -0
  234. package/dist/daemon/routes/triage.ts +402 -0
  235. package/dist/daemon/routes/validation.ts +248 -0
  236. package/dist/daemon/server.ts +408 -0
  237. package/dist/daemon/watcher.ts +195 -0
  238. package/dist/daemon/websocket/handler.ts +138 -0
  239. package/dist/daemon/websocket/heartbeat.ts +71 -0
  240. package/dist/daemon/websocket/pubsub.ts +125 -0
  241. package/dist/daemon/websocket/types.ts +66 -0
  242. package/dist/export/html.d.ts +19 -0
  243. package/dist/export/html.d.ts.map +1 -0
  244. package/dist/export/html.js +239 -0
  245. package/dist/export/html.js.map +1 -0
  246. package/dist/export/index.d.ts +10 -0
  247. package/dist/export/index.d.ts.map +1 -0
  248. package/dist/export/index.js +10 -0
  249. package/dist/export/index.js.map +1 -0
  250. package/dist/export/json.d.ts +24 -0
  251. package/dist/export/json.d.ts.map +1 -0
  252. package/dist/export/json.js +198 -0
  253. package/dist/export/json.js.map +1 -0
  254. package/dist/export/triage.d.ts +51 -0
  255. package/dist/export/triage.d.ts.map +1 -0
  256. package/dist/export/triage.js +83 -0
  257. package/dist/export/triage.js.map +1 -0
  258. package/dist/export/types.d.ts +122 -0
  259. package/dist/export/types.d.ts.map +1 -0
  260. package/dist/export/types.js +9 -0
  261. package/dist/export/types.js.map +1 -0
  262. package/dist/index.d.ts +2 -2
  263. package/dist/index.js +2 -2
  264. package/dist/lib/claude-plugin-registry.d.ts +66 -0
  265. package/dist/lib/claude-plugin-registry.d.ts.map +1 -0
  266. package/dist/lib/claude-plugin-registry.js +318 -0
  267. package/dist/lib/claude-plugin-registry.js.map +1 -0
  268. package/dist/merge/arrays.d.ts +87 -0
  269. package/dist/merge/arrays.d.ts.map +1 -0
  270. package/dist/merge/arrays.js +164 -0
  271. package/dist/merge/arrays.js.map +1 -0
  272. package/dist/merge/file-type.d.ts +32 -0
  273. package/dist/merge/file-type.d.ts.map +1 -0
  274. package/dist/merge/file-type.js +70 -0
  275. package/dist/merge/file-type.js.map +1 -0
  276. package/dist/merge/index.d.ts +14 -0
  277. package/dist/merge/index.d.ts.map +1 -0
  278. package/dist/merge/index.js +11 -0
  279. package/dist/merge/index.js.map +1 -0
  280. package/dist/merge/objects.d.ts +46 -0
  281. package/dist/merge/objects.d.ts.map +1 -0
  282. package/dist/merge/objects.js +193 -0
  283. package/dist/merge/objects.js.map +1 -0
  284. package/dist/merge/parse.d.ts +23 -0
  285. package/dist/merge/parse.d.ts.map +1 -0
  286. package/dist/merge/parse.js +78 -0
  287. package/dist/merge/parse.js.map +1 -0
  288. package/dist/merge/resolve.d.ts +66 -0
  289. package/dist/merge/resolve.d.ts.map +1 -0
  290. package/dist/merge/resolve.js +189 -0
  291. package/dist/merge/resolve.js.map +1 -0
  292. package/dist/merge/types.d.ts +82 -0
  293. package/dist/merge/types.d.ts.map +1 -0
  294. package/dist/merge/types.js +8 -0
  295. package/dist/merge/types.js.map +1 -0
  296. package/dist/parser/agent-data-sections.d.ts +53 -0
  297. package/dist/parser/agent-data-sections.d.ts.map +1 -0
  298. package/dist/parser/agent-data-sections.js +118 -0
  299. package/dist/parser/agent-data-sections.js.map +1 -0
  300. package/dist/parser/alignment.d.ts +4 -4
  301. package/dist/parser/alignment.d.ts.map +1 -1
  302. package/dist/parser/alignment.js +27 -22
  303. package/dist/parser/alignment.js.map +1 -1
  304. package/dist/parser/assess.d.ts +5 -5
  305. package/dist/parser/assess.d.ts.map +1 -1
  306. package/dist/parser/assess.js +36 -32
  307. package/dist/parser/assess.js.map +1 -1
  308. package/dist/parser/config.d.ts +457 -0
  309. package/dist/parser/config.d.ts.map +1 -0
  310. package/dist/parser/config.js +373 -0
  311. package/dist/parser/config.js.map +1 -0
  312. package/dist/parser/convention-validation.d.ts +1 -1
  313. package/dist/parser/convention-validation.d.ts.map +1 -1
  314. package/dist/parser/convention-validation.js +21 -16
  315. package/dist/parser/convention-validation.js.map +1 -1
  316. package/dist/parser/coverage-cache.d.ts +49 -0
  317. package/dist/parser/coverage-cache.d.ts.map +1 -0
  318. package/dist/parser/coverage-cache.js +123 -0
  319. package/dist/parser/coverage-cache.js.map +1 -0
  320. package/dist/parser/daemon-status.d.ts +37 -0
  321. package/dist/parser/daemon-status.d.ts.map +1 -0
  322. package/dist/parser/daemon-status.js +67 -0
  323. package/dist/parser/daemon-status.js.map +1 -0
  324. package/dist/parser/doctor.d.ts +107 -0
  325. package/dist/parser/doctor.d.ts.map +1 -0
  326. package/dist/parser/doctor.js +366 -0
  327. package/dist/parser/doctor.js.map +1 -0
  328. package/dist/parser/fix.d.ts +1 -1
  329. package/dist/parser/fix.d.ts.map +1 -1
  330. package/dist/parser/fix.js +31 -27
  331. package/dist/parser/fix.js.map +1 -1
  332. package/dist/parser/index.d.ts +16 -11
  333. package/dist/parser/index.d.ts.map +1 -1
  334. package/dist/parser/index.js +16 -11
  335. package/dist/parser/index.js.map +1 -1
  336. package/dist/parser/items.d.ts +8 -2
  337. package/dist/parser/items.d.ts.map +1 -1
  338. package/dist/parser/items.js +71 -35
  339. package/dist/parser/items.js.map +1 -1
  340. package/dist/parser/meta.d.ts +167 -9
  341. package/dist/parser/meta.d.ts.map +1 -1
  342. package/dist/parser/meta.js +379 -46
  343. package/dist/parser/meta.js.map +1 -1
  344. package/dist/parser/plan-document.d.ts +197 -0
  345. package/dist/parser/plan-document.d.ts.map +1 -0
  346. package/dist/parser/plan-document.js +341 -0
  347. package/dist/parser/plan-document.js.map +1 -0
  348. package/dist/parser/plans.d.ts +59 -0
  349. package/dist/parser/plans.d.ts.map +1 -0
  350. package/dist/parser/plans.js +239 -0
  351. package/dist/parser/plans.js.map +1 -0
  352. package/dist/parser/refs.d.ts +22 -9
  353. package/dist/parser/refs.d.ts.map +1 -1
  354. package/dist/parser/refs.js +102 -50
  355. package/dist/parser/refs.js.map +1 -1
  356. package/dist/parser/setup-status.d.ts +71 -0
  357. package/dist/parser/setup-status.d.ts.map +1 -0
  358. package/dist/parser/setup-status.js +269 -0
  359. package/dist/parser/setup-status.js.map +1 -0
  360. package/dist/parser/shadow.d.ts +150 -19
  361. package/dist/parser/shadow.d.ts.map +1 -1
  362. package/dist/parser/shadow.js +548 -187
  363. package/dist/parser/shadow.js.map +1 -1
  364. package/dist/parser/skill-render.d.ts +317 -0
  365. package/dist/parser/skill-render.d.ts.map +1 -0
  366. package/dist/parser/skill-render.js +943 -0
  367. package/dist/parser/skill-render.js.map +1 -0
  368. package/dist/parser/traits.d.ts +3 -3
  369. package/dist/parser/traits.d.ts.map +1 -1
  370. package/dist/parser/traits.js +2 -2
  371. package/dist/parser/traits.js.map +1 -1
  372. package/dist/parser/validate-skills.d.ts +32 -0
  373. package/dist/parser/validate-skills.d.ts.map +1 -0
  374. package/dist/parser/validate-skills.js +202 -0
  375. package/dist/parser/validate-skills.js.map +1 -0
  376. package/dist/parser/validate.d.ts +45 -3
  377. package/dist/parser/validate.d.ts.map +1 -1
  378. package/dist/parser/validate.js +622 -105
  379. package/dist/parser/validate.js.map +1 -1
  380. package/dist/parser/yaml.d.ts +83 -19
  381. package/dist/parser/yaml.d.ts.map +1 -1
  382. package/dist/parser/yaml.js +478 -173
  383. package/dist/parser/yaml.js.map +1 -1
  384. package/dist/ralph/cli-renderer.d.ts +8 -1
  385. package/dist/ralph/cli-renderer.d.ts.map +1 -1
  386. package/dist/ralph/cli-renderer.js +105 -34
  387. package/dist/ralph/cli-renderer.js.map +1 -1
  388. package/dist/ralph/events.d.ts +10 -10
  389. package/dist/ralph/events.d.ts.map +1 -1
  390. package/dist/ralph/events.js +301 -98
  391. package/dist/ralph/events.js.map +1 -1
  392. package/dist/ralph/index.d.ts +5 -2
  393. package/dist/ralph/index.d.ts.map +1 -1
  394. package/dist/ralph/index.js +9 -3
  395. package/dist/ralph/index.js.map +1 -1
  396. package/dist/ralph/loop-errors.d.ts +83 -0
  397. package/dist/ralph/loop-errors.d.ts.map +1 -0
  398. package/dist/ralph/loop-errors.js +150 -0
  399. package/dist/ralph/loop-errors.js.map +1 -0
  400. package/dist/ralph/subagent.d.ts +94 -0
  401. package/dist/ralph/subagent.d.ts.map +1 -0
  402. package/dist/ralph/subagent.js +193 -0
  403. package/dist/ralph/subagent.js.map +1 -0
  404. package/dist/ralph/wrap-up.d.ts +125 -0
  405. package/dist/ralph/wrap-up.d.ts.map +1 -0
  406. package/dist/ralph/wrap-up.js +270 -0
  407. package/dist/ralph/wrap-up.js.map +1 -0
  408. package/dist/schema/batch.d.ts +97 -0
  409. package/dist/schema/batch.d.ts.map +1 -0
  410. package/dist/schema/batch.js +24 -0
  411. package/dist/schema/batch.js.map +1 -0
  412. package/dist/schema/common.d.ts +8 -2
  413. package/dist/schema/common.d.ts.map +1 -1
  414. package/dist/schema/common.js +42 -31
  415. package/dist/schema/common.js.map +1 -1
  416. package/dist/schema/inbox.d.ts +12 -12
  417. package/dist/schema/inbox.js +4 -4
  418. package/dist/schema/inbox.js.map +1 -1
  419. package/dist/schema/index.d.ts +8 -5
  420. package/dist/schema/index.d.ts.map +1 -1
  421. package/dist/schema/index.js +8 -5
  422. package/dist/schema/index.js.map +1 -1
  423. package/dist/schema/meta.d.ts +1454 -27
  424. package/dist/schema/meta.d.ts.map +1 -1
  425. package/dist/schema/meta.js +198 -21
  426. package/dist/schema/meta.js.map +1 -1
  427. package/dist/schema/plan.d.ts +285 -0
  428. package/dist/schema/plan.d.ts.map +1 -0
  429. package/dist/schema/plan.js +81 -0
  430. package/dist/schema/plan.js.map +1 -0
  431. package/dist/schema/spec.d.ts +72 -33
  432. package/dist/schema/spec.d.ts.map +1 -1
  433. package/dist/schema/spec.js +22 -9
  434. package/dist/schema/spec.js.map +1 -1
  435. package/dist/schema/task.d.ts +172 -161
  436. package/dist/schema/task.d.ts.map +1 -1
  437. package/dist/schema/task.js +21 -12
  438. package/dist/schema/task.js.map +1 -1
  439. package/dist/schema/triage.d.ts +266 -0
  440. package/dist/schema/triage.d.ts.map +1 -0
  441. package/dist/schema/triage.js +134 -0
  442. package/dist/schema/triage.js.map +1 -0
  443. package/dist/sessions/index.d.ts +2 -2
  444. package/dist/sessions/index.d.ts.map +1 -1
  445. package/dist/sessions/index.js +3 -3
  446. package/dist/sessions/index.js.map +1 -1
  447. package/dist/sessions/store.d.ts +241 -1
  448. package/dist/sessions/store.d.ts.map +1 -1
  449. package/dist/sessions/store.js +810 -31
  450. package/dist/sessions/store.js.map +1 -1
  451. package/dist/sessions/types.d.ts +10 -10
  452. package/dist/sessions/types.d.ts.map +1 -1
  453. package/dist/sessions/types.js +10 -9
  454. package/dist/sessions/types.js.map +1 -1
  455. package/dist/strings/errors.d.ts +55 -0
  456. package/dist/strings/errors.d.ts.map +1 -1
  457. package/dist/strings/errors.js +138 -106
  458. package/dist/strings/errors.js.map +1 -1
  459. package/dist/strings/guidance.d.ts.map +1 -1
  460. package/dist/strings/guidance.js +16 -16
  461. package/dist/strings/guidance.js.map +1 -1
  462. package/dist/strings/index.d.ts +4 -4
  463. package/dist/strings/index.d.ts.map +1 -1
  464. package/dist/strings/index.js +4 -4
  465. package/dist/strings/index.js.map +1 -1
  466. package/dist/strings/labels.d.ts +4 -0
  467. package/dist/strings/labels.d.ts.map +1 -1
  468. package/dist/strings/labels.js +45 -41
  469. package/dist/strings/labels.js.map +1 -1
  470. package/dist/strings/validation.d.ts.map +1 -1
  471. package/dist/strings/validation.js +71 -71
  472. package/dist/strings/validation.js.map +1 -1
  473. package/dist/triage/actions.d.ts +27 -0
  474. package/dist/triage/actions.d.ts.map +1 -0
  475. package/dist/triage/actions.js +95 -0
  476. package/dist/triage/actions.js.map +1 -0
  477. package/dist/triage/constants.d.ts +6 -0
  478. package/dist/triage/constants.d.ts.map +1 -0
  479. package/dist/triage/constants.js +7 -0
  480. package/dist/triage/constants.js.map +1 -0
  481. package/dist/triage/index.d.ts +3 -0
  482. package/dist/triage/index.d.ts.map +1 -0
  483. package/dist/triage/index.js +3 -0
  484. package/dist/triage/index.js.map +1 -0
  485. package/dist/utils/commit.d.ts +1 -1
  486. package/dist/utils/commit.d.ts.map +1 -1
  487. package/dist/utils/commit.js +28 -26
  488. package/dist/utils/commit.js.map +1 -1
  489. package/dist/utils/git.d.ts +1 -1
  490. package/dist/utils/git.d.ts.map +1 -1
  491. package/dist/utils/git.js +40 -38
  492. package/dist/utils/git.js.map +1 -1
  493. package/dist/utils/grep.js +11 -11
  494. package/dist/utils/grep.js.map +1 -1
  495. package/dist/utils/index.d.ts +7 -7
  496. package/dist/utils/index.d.ts.map +1 -1
  497. package/dist/utils/index.js +4 -4
  498. package/dist/utils/index.js.map +1 -1
  499. package/dist/utils/time.d.ts.map +1 -1
  500. package/dist/utils/time.js +10 -10
  501. package/dist/utils/time.js.map +1 -1
  502. package/package.json +28 -5
  503. package/plugin/.claude-plugin/marketplace.json +17 -0
  504. package/plugin/.claude-plugin/plugin.json +5 -0
  505. package/plugin/plugins/kspec/skills/create-workflow/SKILL.md +235 -0
  506. package/plugin/plugins/kspec/skills/help/SKILL.md +42 -0
  507. package/plugin/plugins/kspec/skills/observations/SKILL.md +143 -0
  508. package/plugin/plugins/kspec/skills/plan/SKILL.md +343 -0
  509. package/plugin/plugins/kspec/skills/reflect/SKILL.md +161 -0
  510. package/plugin/plugins/kspec/skills/review/SKILL.md +193 -0
  511. package/plugin/plugins/kspec/skills/task-work/SKILL.md +303 -0
  512. package/plugin/plugins/kspec/skills/triage/SKILL.md +206 -0
  513. package/plugin/plugins/kspec/skills/triage/docs/automation.md +120 -0
  514. package/plugin/plugins/kspec/skills/triage/docs/inbox.md +144 -0
  515. package/plugin/plugins/kspec/skills/triage/docs/observations.md +85 -0
  516. package/plugin/plugins/kspec/skills/triage-automation/SKILL.md +140 -0
  517. package/plugin/plugins/kspec/skills/triage-inbox/SKILL.md +232 -0
  518. package/plugin/plugins/kspec/skills/writing-specs/SKILL.md +340 -0
  519. package/templates/agents-sections/01-quick-start.md +22 -0
  520. package/templates/agents-sections/02-shadow-branch.md +34 -0
  521. package/templates/agents-sections/03-task-lifecycle.md +48 -0
  522. package/templates/agents-sections/04-pr-workflow.md +17 -0
  523. package/templates/agents-sections/05-commit-convention.md +27 -0
  524. package/templates/agents-sections/06-ralph-loop.md +45 -0
  525. package/templates/hooks/pre-commit +34 -0
  526. package/templates/skills/create-workflow/SKILL.md +228 -0
  527. package/templates/skills/help/SKILL.md +37 -0
  528. package/templates/skills/manifest.yaml +60 -0
  529. package/templates/skills/observations/SKILL.md +137 -0
  530. package/templates/skills/plan/SKILL.md +336 -0
  531. package/templates/skills/reflect/SKILL.md +155 -0
  532. package/templates/skills/review/SKILL.md +186 -0
  533. package/templates/skills/task-work/SKILL.md +296 -0
  534. package/templates/skills/triage/SKILL.md +199 -0
  535. package/templates/skills/triage/docs/automation.md +120 -0
  536. package/templates/skills/triage/docs/inbox.md +144 -0
  537. package/templates/skills/triage/docs/observations.md +85 -0
  538. package/templates/skills/triage-automation/SKILL.md +134 -0
  539. package/templates/skills/triage-inbox/SKILL.md +225 -0
  540. package/templates/skills/writing-specs/SKILL.md +333 -0
@@ -0,0 +1,706 @@
1
+ /**
2
+ * Batch command parsing, validation, execution, and error reporting.
3
+ *
4
+ * Parses JSON batch input from stdin/file/inline, validates command paths
5
+ * against the CLI's introspection tree, executes in atomic or immediate
6
+ * mode, and produces helpful error messages.
7
+ */
8
+ import * as fs from "node:fs/promises";
9
+ import * as path from "node:path";
10
+ import * as os from "node:os";
11
+ import chalk from "chalk";
12
+ import { ZodError } from "zod";
13
+ import { BatchInputSchema, } from "../schema/batch.js";
14
+ import { initContext } from "../parser/yaml.js";
15
+ import { shadowAutoCommit, shadowPushAsync } from "../parser/shadow.js";
16
+ import { extractCommandTree, findCommand, flattenCommandTree } from "./introspection.js";
17
+ import { findClosestCommand } from "./suggest.js";
18
+ import { createBatchCommandFilter } from "./command-annotations.js";
19
+ import { setJsonMode, setVerboseMode } from "./output.js";
20
+ import { BatchExitError, OutputCapture, installExitInterceptor, uninstallExitInterceptor, setBatchMode, } from "./batch-context.js";
21
+ // ── Error Types ─────────────────────────────────────────────────────
22
+ export class BatchParseError extends Error {
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = "BatchParseError";
26
+ }
27
+ }
28
+ // ── Parsing ─────────────────────────────────────────────────────────
29
+ /**
30
+ * Read raw text from a batch input source.
31
+ */
32
+ async function readSource(source) {
33
+ switch (source.type) {
34
+ case "inline":
35
+ return source.json;
36
+ case "file":
37
+ try {
38
+ return await fs.readFile(source.path, "utf-8");
39
+ }
40
+ catch (err) {
41
+ throw new BatchParseError(`Failed to read batch file: ${err.message}`);
42
+ }
43
+ case "stdin": {
44
+ const chunks = [];
45
+ for await (const chunk of process.stdin) {
46
+ chunks.push(chunk);
47
+ }
48
+ const text = Buffer.concat(chunks).toString("utf-8");
49
+ if (!text.trim()) {
50
+ throw new BatchParseError("No input received on stdin");
51
+ }
52
+ return text;
53
+ }
54
+ }
55
+ }
56
+ /**
57
+ * Parse batch input from a source, returning validated commands.
58
+ *
59
+ * @throws {BatchParseError} on invalid JSON, empty array, or schema violations
60
+ */
61
+ export async function parseBatchInput(source) {
62
+ const raw = await readSource(source);
63
+ // Parse JSON — preserve the native error message which includes position
64
+ let parsed;
65
+ try {
66
+ parsed = JSON.parse(raw);
67
+ }
68
+ catch (err) {
69
+ throw new BatchParseError(`Invalid JSON: ${err.message}`);
70
+ }
71
+ // Validate against schema
72
+ try {
73
+ return BatchInputSchema.parse(parsed);
74
+ }
75
+ catch (err) {
76
+ if (err instanceof ZodError) {
77
+ const messages = err.errors.map((e) => {
78
+ const path = e.path.length > 0 ? ` at ${e.path.join(".")}` : "";
79
+ return `${e.message}${path}`;
80
+ });
81
+ throw new BatchParseError(`Batch validation failed: ${messages.join("; ")}`);
82
+ }
83
+ throw err;
84
+ }
85
+ }
86
+ // ── Validation ──────────────────────────────────────────────────────
87
+ /**
88
+ * Extract the option name from Commander flag syntax.
89
+ * e.g. "-f, --force" → "force", "--spec-ref <value>" → "spec-ref"
90
+ */
91
+ function extractOptionName(flags) {
92
+ const match = flags.match(/--([a-zA-Z0-9-]+)/);
93
+ return match ? match[1] : null;
94
+ }
95
+ /**
96
+ * Convert a kebab-case string to camelCase.
97
+ * e.g. "spec-ref" → "specRef"
98
+ */
99
+ function kebabToCamel(s) {
100
+ return s.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
101
+ }
102
+ /**
103
+ * Get all known argument and option names for a command, returning both
104
+ * kebab-case and camelCase variants.
105
+ */
106
+ function getKnownArgNames(cmd) {
107
+ const names = new Set();
108
+ const required = [];
109
+ // Positional arguments
110
+ for (const arg of cmd.arguments) {
111
+ names.add(arg.name);
112
+ names.add(kebabToCamel(arg.name));
113
+ if (arg.required) {
114
+ required.push(arg.name);
115
+ }
116
+ }
117
+ // Options
118
+ for (const opt of cmd.options) {
119
+ const optName = extractOptionName(opt.flags);
120
+ if (optName) {
121
+ names.add(optName);
122
+ names.add(kebabToCamel(optName));
123
+ if (opt.mandatory) {
124
+ required.push(optName);
125
+ }
126
+ }
127
+ }
128
+ return { names, required };
129
+ }
130
+ /**
131
+ * Collect all leaf command paths from a command tree as space-joined strings.
132
+ */
133
+ function collectLeafCommandPaths(tree) {
134
+ const flat = flattenCommandTree(tree);
135
+ return flat
136
+ .filter((cmd) => cmd.subcommands.length === 0)
137
+ .map((cmd) => cmd.fullPath.slice(1).join(" ")) // skip root name
138
+ .filter((path) => path.length > 0);
139
+ }
140
+ /**
141
+ * Validate batch commands against the CLI's command tree.
142
+ *
143
+ * AC: @batch-command-schema ac-command-field — validates command paths
144
+ * AC: @batch-command-schema ac-args-mapping — validates arg names
145
+ * AC: @batch-command-schema ac-unknown-command — suggests similar commands
146
+ * AC: @batch-command-schema ac-missing-required — identifies missing args
147
+ * AC: @batch-command-schema ac-id-field — preserves id in errors
148
+ */
149
+ export function validateBatchCommands(commands, program, options) {
150
+ const errors = [];
151
+ const validLeafPaths = collectLeafCommandPaths(program);
152
+ for (let i = 0; i < commands.length; i++) {
153
+ const cmd = commands[i];
154
+ const parts = cmd.command.trim().split(/\s+/);
155
+ // 1. Resolve command path
156
+ const found = findCommand(program, parts);
157
+ if (!found) {
158
+ // Unknown command — suggest closest
159
+ const suggestion = findClosestCommand(cmd.command, validLeafPaths);
160
+ errors.push({
161
+ index: i,
162
+ id: cmd.id,
163
+ command: cmd.command,
164
+ type: "unknown_command",
165
+ message: `Unknown command: "${cmd.command}"`,
166
+ suggestion: suggestion ?? undefined,
167
+ });
168
+ continue;
169
+ }
170
+ // Reject command groups (non-leaf nodes)
171
+ if (found.subcommands.length > 0) {
172
+ const suggestion = findClosestCommand(cmd.command, validLeafPaths);
173
+ errors.push({
174
+ index: i,
175
+ id: cmd.id,
176
+ command: cmd.command,
177
+ type: "unknown_command",
178
+ message: `"${cmd.command}" is a command group, not an executable command`,
179
+ suggestion: suggestion ?? undefined,
180
+ });
181
+ continue;
182
+ }
183
+ // 2. Reject nested batch commands (batch or any subcommands like batch commands)
184
+ // AC: @batch-allowed-commands ac-batch-itself
185
+ if (found.fullPath[1] === "batch") {
186
+ errors.push({
187
+ index: i,
188
+ id: cmd.id,
189
+ command: cmd.command,
190
+ type: "rejected_command",
191
+ message: "Nested batch commands are not allowed",
192
+ });
193
+ continue;
194
+ }
195
+ // 3. Apply command filter if provided
196
+ // AC: @batch-allowed-commands ac-denylist
197
+ if (options?.commandFilter && !options.commandFilter(found)) {
198
+ errors.push({
199
+ index: i,
200
+ id: cmd.id,
201
+ command: cmd.command,
202
+ type: "rejected_command",
203
+ message: `Command "${cmd.command}" is not allowed in batch mode. Only mutating commands can be used in batch.`,
204
+ });
205
+ continue;
206
+ }
207
+ // 4. Check for unknown args
208
+ const { names: knownNames, required: requiredNames } = getKnownArgNames(found);
209
+ // Collect all known names as flat array for suggestion matching
210
+ const knownNamesArray = Array.from(knownNames);
211
+ for (const argKey of Object.keys(cmd.args)) {
212
+ // Accept both kebab-case and camelCase
213
+ if (!knownNames.has(argKey)) {
214
+ const suggestion = findClosestCommand(argKey, knownNamesArray);
215
+ errors.push({
216
+ index: i,
217
+ id: cmd.id,
218
+ command: cmd.command,
219
+ type: "unknown_arg",
220
+ message: `Unknown argument "${argKey}" for command "${cmd.command}"`,
221
+ suggestion: suggestion ?? undefined,
222
+ });
223
+ }
224
+ }
225
+ // 5. Check for missing required args
226
+ for (const reqName of requiredNames) {
227
+ const camelName = kebabToCamel(reqName);
228
+ if (!(reqName in cmd.args) &&
229
+ !(camelName in cmd.args) &&
230
+ // Skip if provided via positional alias
231
+ !Object.keys(cmd.args).some((k) => kebabToCamel(k) === camelName)) {
232
+ errors.push({
233
+ index: i,
234
+ id: cmd.id,
235
+ command: cmd.command,
236
+ type: "missing_required",
237
+ message: `Missing required argument "${reqName}" for command "${cmd.command}"`,
238
+ });
239
+ }
240
+ }
241
+ }
242
+ return {
243
+ valid: errors.length === 0,
244
+ commands,
245
+ errors,
246
+ };
247
+ }
248
+ // ── Error Reporting ─────────────────────────────────────────────────
249
+ /**
250
+ * Format validation errors for human or JSON output.
251
+ *
252
+ * @param result - Validation result containing errors
253
+ * @param json - If true, return JSON string; otherwise human-readable lines
254
+ * @returns Formatted error string
255
+ */
256
+ export function reportBatchValidationErrors(result, json = false) {
257
+ if (result.valid) {
258
+ return json ? JSON.stringify({ valid: true, errors: [] }) : "";
259
+ }
260
+ if (json) {
261
+ return JSON.stringify({
262
+ valid: false,
263
+ errors: result.errors,
264
+ }, null, 2);
265
+ }
266
+ // Human-readable format
267
+ const lines = [];
268
+ for (const err of result.errors) {
269
+ const label = err.id ?? `#${err.index}`;
270
+ lines.push(`[${label}] ${err.message}`);
271
+ if (err.suggestion) {
272
+ lines.push(` Did you mean: ${err.suggestion}?`);
273
+ }
274
+ }
275
+ // Add helpful hint for discoverability
276
+ lines.push("");
277
+ lines.push("Run 'kspec batch commands' for a list of available commands.");
278
+ return lines.join("\n");
279
+ }
280
+ /**
281
+ * Build Commander argv from a BatchCommand and its CommandMeta.
282
+ *
283
+ * Translates { command: "inbox add", args: { content: "hello", tag: ["a","b"] } }
284
+ * into ["inbox", "add", "hello", "--tag", "a", "--tag", "b"]
285
+ *
286
+ * Positional args are emitted in Commander definition order (not JSON key order)
287
+ * to ensure correct argument mapping regardless of how the JSON was serialized.
288
+ */
289
+ /**
290
+ * Serialize a value for CLI argv. Plain objects are JSON-stringified
291
+ * so that flags like --data receive valid JSON instead of "[object Object]".
292
+ */
293
+ function toArgString(value) {
294
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
295
+ return JSON.stringify(value);
296
+ }
297
+ return String(value);
298
+ }
299
+ export function buildCommandArgv(cmd, cmdMeta) {
300
+ const argv = [...cmd.command.trim().split(/\s+/)];
301
+ // Build sets for classification
302
+ const positionalDefs = cmdMeta.arguments; // ordered by Commander definition
303
+ const positionalNameSet = new Set();
304
+ for (const arg of positionalDefs) {
305
+ positionalNameSet.add(arg.name);
306
+ positionalNameSet.add(kebabToCamel(arg.name));
307
+ }
308
+ const optionMap = new Map();
309
+ for (const opt of cmdMeta.options) {
310
+ const name = extractOptionName(opt.flags);
311
+ if (name) {
312
+ optionMap.set(name, { flags: opt.flags, variadic: opt.variadic });
313
+ optionMap.set(kebabToCamel(name), { flags: opt.flags, variadic: opt.variadic });
314
+ }
315
+ }
316
+ // Phase 1: Emit positional args in Commander definition order
317
+ for (const argDef of positionalDefs) {
318
+ const name = argDef.name;
319
+ const camelName = kebabToCamel(name);
320
+ const value = cmd.args[name] ?? cmd.args[camelName];
321
+ if (value === undefined)
322
+ continue;
323
+ if (Array.isArray(value)) {
324
+ for (const v of value)
325
+ argv.push(toArgString(v));
326
+ }
327
+ else {
328
+ argv.push(toArgString(value));
329
+ }
330
+ }
331
+ // Phase 2: Emit options from remaining keys
332
+ for (const [key, value] of Object.entries(cmd.args)) {
333
+ const camelKey = kebabToCamel(key);
334
+ // Skip positional args (already emitted)
335
+ if (positionalNameSet.has(key) || positionalNameSet.has(camelKey)) {
336
+ continue;
337
+ }
338
+ // Convert camelCase key back to kebab-case for CLI
339
+ const kebabKey = key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
340
+ const flagName = `--${kebabKey}`;
341
+ if (typeof value === "boolean") {
342
+ if (value) {
343
+ argv.push(flagName);
344
+ }
345
+ // false booleans: omit (Commander treats absence as false)
346
+ }
347
+ else if (Array.isArray(value)) {
348
+ // Variadic or repeated options
349
+ for (const v of value) {
350
+ argv.push(flagName, toArgString(v));
351
+ }
352
+ }
353
+ else if (value !== null && value !== undefined) {
354
+ argv.push(flagName, toArgString(value));
355
+ }
356
+ }
357
+ return argv;
358
+ }
359
+ /**
360
+ * Reset Commander command tree state between dispatches.
361
+ * Commander retains _optionValues between parseAsync calls.
362
+ */
363
+ export function resetCommandTree(cmd) {
364
+ cmd._optionValues = {};
365
+ cmd._optionValueSources = {};
366
+ cmd.processedArgs = [];
367
+ for (const sub of cmd.commands) {
368
+ resetCommandTree(sub);
369
+ }
370
+ }
371
+ /**
372
+ * Check if a CommandMeta supports the --force option.
373
+ */
374
+ function commandHasForce(cmdMeta) {
375
+ return cmdMeta.options.some((opt) => {
376
+ const name = extractOptionName(opt.flags);
377
+ return name === "force";
378
+ });
379
+ }
380
+ /**
381
+ * Execute a batch of commands.
382
+ *
383
+ * AC: @batch-exec ac-default-atomic — atomic mode by default
384
+ * AC: @batch-exec ac-no-atomic-flag — immediate mode with --no-atomic
385
+ * AC: @batch-exec ac-stop-on-error — stop on first failure (default)
386
+ * AC: @batch-exec ac-continue — continue on error with --continue
387
+ * AC: @batch-exec ac-dry-run — validate without executing
388
+ * AC: @batch-exec ac-prevalidate — validation before any execution
389
+ * AC: @batch-exec ac-confirmation-suppressed — auto-append --force
390
+ */
391
+ export async function executeBatch(commands, program, options) {
392
+ const mode = options.atomic ? "atomic" : "immediate";
393
+ // Build command tree for validation
394
+ const tree = extractCommandTree(program);
395
+ const commandFilter = createBatchCommandFilter();
396
+ // AC: ac-prevalidate — validate all commands before executing any
397
+ const validation = validateBatchCommands(commands, tree, { commandFilter });
398
+ if (!validation.valid) {
399
+ return {
400
+ success: false,
401
+ mode,
402
+ summary: {
403
+ total: commands.length,
404
+ succeeded: 0,
405
+ failed: validation.errors.length,
406
+ },
407
+ results: validation.errors.map((err) => ({
408
+ index: err.index,
409
+ id: err.id,
410
+ command: err.command,
411
+ success: false,
412
+ error: err.message,
413
+ suggestion: err.suggestion,
414
+ })),
415
+ validationFailed: true,
416
+ };
417
+ }
418
+ // AC: ac-dry-run — validate without executing
419
+ // AC: @trait-dry-run ac-6 — include dry_run boolean in JSON output
420
+ if (options.dryRun) {
421
+ return {
422
+ success: true,
423
+ dry_run: true,
424
+ mode,
425
+ summary: { total: commands.length, succeeded: commands.length, failed: 0 },
426
+ results: commands.map((cmd, i) => ({
427
+ index: i,
428
+ id: cmd.id,
429
+ command: cmd.command,
430
+ success: true,
431
+ output: "dry-run: would execute",
432
+ })),
433
+ };
434
+ }
435
+ if (options.atomic) {
436
+ return executeAtomic(commands, program, tree, options);
437
+ }
438
+ else {
439
+ return executeImmediate(commands, program, tree, options);
440
+ }
441
+ }
442
+ /**
443
+ * Atomic execution: copy specDir to temp, run all, copy back on success.
444
+ *
445
+ * AC: @batch-exec ac-default-atomic
446
+ * AC: @batch-exec ac-atomic-rollback
447
+ * AC: @batch-exec ac-atomic-isolation
448
+ * AC: @batch-exec ac-single-commit
449
+ */
450
+ async function executeAtomic(commands, program, tree, options) {
451
+ // Get the real context for copy-back
452
+ const ctx = await initContext();
453
+ const realSpecDir = ctx.specDir;
454
+ // Create temp copy using mkdtemp for safe, collision-free naming
455
+ const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "kspec-batch-"));
456
+ await fs.cp(realSpecDir, tempDir, { recursive: true });
457
+ // Remove .git from temp copy to prevent worktree pointer leaks
458
+ await fs.rm(path.join(tempDir, ".git"), { force: true, recursive: true });
459
+ // Set up atomic context
460
+ const savedChalkLevel = chalk.level;
461
+ const savedSpecDir = process.env.KSPEC_SPEC_DIR;
462
+ const savedBatchProjectRoot = process.env.KSPEC_BATCH_PROJECT_ROOT;
463
+ // AC: @project-config ac-7 — set real project root before redirecting spec dir
464
+ process.env.KSPEC_BATCH_PROJECT_ROOT = ctx.rootDir;
465
+ process.env.KSPEC_SPEC_DIR = tempDir;
466
+ setBatchMode(true);
467
+ chalk.level = 0;
468
+ const results = [];
469
+ let allSucceeded = true;
470
+ let copyBackFailed = false;
471
+ try {
472
+ for (let i = 0; i < commands.length; i++) {
473
+ const cmd = commands[i];
474
+ const result = await dispatchCommand(cmd, i, program, tree);
475
+ results.push(result);
476
+ if (!result.success) {
477
+ allSucceeded = false;
478
+ // Atomic mode: stop on first failure, discard everything
479
+ // Fill remaining as not-executed
480
+ for (let j = i + 1; j < commands.length; j++) {
481
+ results.push({
482
+ index: j,
483
+ id: commands[j].id,
484
+ command: commands[j].command,
485
+ success: false,
486
+ error: "Not executed (prior command failed in atomic mode)",
487
+ });
488
+ }
489
+ break;
490
+ }
491
+ }
492
+ // Copy back on success
493
+ if (allSucceeded) {
494
+ try {
495
+ // Clear real specDir contents (except .git and .gitattributes) before copy-back
496
+ const entries = await fs.readdir(realSpecDir);
497
+ for (const entry of entries) {
498
+ if (entry === ".git" || entry === ".gitattributes")
499
+ continue;
500
+ await fs.rm(path.join(realSpecDir, entry), { recursive: true, force: true });
501
+ }
502
+ // Copy temp contents back
503
+ const tempEntries = await fs.readdir(tempDir);
504
+ for (const entry of tempEntries) {
505
+ await fs.cp(path.join(tempDir, entry), path.join(realSpecDir, entry), { recursive: true });
506
+ }
507
+ // Single shadow commit for all changes
508
+ if (ctx.shadow?.enabled) {
509
+ const successCount = results.filter((r) => r.success).length;
510
+ await shadowAutoCommit(ctx.shadow.worktreeDir, `batch: ${successCount} command${successCount !== 1 ? "s" : ""}`);
511
+ shadowPushAsync(ctx.shadow.worktreeDir);
512
+ }
513
+ }
514
+ catch (copyErr) {
515
+ // Copy-back failed — preserve tempDir for manual recovery
516
+ copyBackFailed = true;
517
+ allSucceeded = false;
518
+ console.error(`Batch copy-back failed: ${copyErr instanceof Error ? copyErr.message : copyErr}`);
519
+ console.error(`Temp dir preserved for recovery: ${tempDir}`);
520
+ }
521
+ }
522
+ }
523
+ finally {
524
+ // Clean up
525
+ setBatchMode(false);
526
+ chalk.level = savedChalkLevel;
527
+ if (savedSpecDir !== undefined) {
528
+ process.env.KSPEC_SPEC_DIR = savedSpecDir;
529
+ }
530
+ else {
531
+ delete process.env.KSPEC_SPEC_DIR;
532
+ }
533
+ // AC: @project-config ac-7 — restore batch project root env var
534
+ if (savedBatchProjectRoot !== undefined) {
535
+ process.env.KSPEC_BATCH_PROJECT_ROOT = savedBatchProjectRoot;
536
+ }
537
+ else {
538
+ delete process.env.KSPEC_BATCH_PROJECT_ROOT;
539
+ }
540
+ // Only remove temp dir if copy-back succeeded (or commands failed)
541
+ if (!copyBackFailed) {
542
+ await fs.rm(tempDir, { recursive: true, force: true }).catch(() => { });
543
+ }
544
+ }
545
+ const succeeded = results.filter((r) => r.success).length;
546
+ const failed = results.filter((r) => !r.success).length;
547
+ return {
548
+ success: allSucceeded,
549
+ mode: "atomic",
550
+ summary: { total: commands.length, succeeded, failed },
551
+ results,
552
+ };
553
+ }
554
+ /**
555
+ * Immediate execution: execute against real state, per-command commits.
556
+ *
557
+ * AC: @batch-exec ac-no-atomic-flag
558
+ * AC: @batch-exec ac-immediate-per-commit
559
+ * AC: @batch-exec ac-immediate-no-rollback
560
+ */
561
+ async function executeImmediate(commands, program, tree, options) {
562
+ const savedChalkLevel = chalk.level;
563
+ chalk.level = 0;
564
+ const results = [];
565
+ try {
566
+ for (let i = 0; i < commands.length; i++) {
567
+ const cmd = commands[i];
568
+ const result = await dispatchCommand(cmd, i, program, tree);
569
+ results.push(result);
570
+ if (!result.success && !options.continueOnError) {
571
+ // Stop on first failure, remaining not executed
572
+ for (let j = i + 1; j < commands.length; j++) {
573
+ results.push({
574
+ index: j,
575
+ id: commands[j].id,
576
+ command: commands[j].command,
577
+ success: false,
578
+ error: "Not executed (prior command failed)",
579
+ });
580
+ }
581
+ break;
582
+ }
583
+ }
584
+ }
585
+ finally {
586
+ chalk.level = savedChalkLevel;
587
+ }
588
+ const succeeded = results.filter((r) => r.success).length;
589
+ const failed = results.filter((r) => !r.success).length;
590
+ return {
591
+ success: failed === 0,
592
+ mode: "immediate",
593
+ summary: { total: commands.length, succeeded, failed },
594
+ results,
595
+ };
596
+ }
597
+ /**
598
+ * Dispatch a single command through Commander's parseAsync.
599
+ */
600
+ async function dispatchCommand(cmd, index, program, tree) {
601
+ const parts = cmd.command.trim().split(/\s+/);
602
+ const cmdMeta = findCommand(tree, parts);
603
+ if (!cmdMeta) {
604
+ return {
605
+ index,
606
+ id: cmd.id,
607
+ command: cmd.command,
608
+ success: false,
609
+ error: `Command not found: ${cmd.command}`,
610
+ };
611
+ }
612
+ // Build argv, auto-appending --force if supported
613
+ // AC: ac-confirmation-suppressed
614
+ const enrichedCmd = { ...cmd, args: { ...cmd.args } };
615
+ if (commandHasForce(cmdMeta) && !("force" in enrichedCmd.args)) {
616
+ enrichedCmd.args.force = true;
617
+ }
618
+ const argv = buildCommandArgv(enrichedCmd, cmdMeta);
619
+ // Reset Commander state
620
+ resetCommandTree(program);
621
+ setJsonMode(false);
622
+ setVerboseMode(false);
623
+ const capture = new OutputCapture();
624
+ capture.start();
625
+ installExitInterceptor();
626
+ let caughtError = undefined;
627
+ let succeeded = false;
628
+ try {
629
+ await program.parseAsync(argv, { from: "user" });
630
+ succeeded = true;
631
+ }
632
+ catch (err) {
633
+ caughtError = err;
634
+ }
635
+ finally {
636
+ capture.stop();
637
+ uninstallExitInterceptor();
638
+ }
639
+ if (succeeded) {
640
+ const output = capture.getOutput();
641
+ // Try to parse output as JSON for structured results
642
+ let parsedOutput = output;
643
+ try {
644
+ parsedOutput = JSON.parse(output);
645
+ }
646
+ catch {
647
+ // Not JSON, keep as string
648
+ }
649
+ return {
650
+ index,
651
+ id: cmd.id,
652
+ command: cmd.command,
653
+ success: true,
654
+ output: parsedOutput,
655
+ };
656
+ }
657
+ // Handle errors
658
+ const err = caughtError;
659
+ if (err instanceof BatchExitError) {
660
+ // Filter out BatchExitError noise from captured output (handlers may
661
+ // catch and re-log the error before calling process.exit again)
662
+ const capturedOutput = capture
663
+ .getOutput()
664
+ .split("\n")
665
+ .filter((line) => !line.includes("BatchExitError"))
666
+ .join("\n")
667
+ .trim();
668
+ if (err.code === 0) {
669
+ return {
670
+ index,
671
+ id: cmd.id,
672
+ command: cmd.command,
673
+ success: true,
674
+ output: capturedOutput,
675
+ };
676
+ }
677
+ return {
678
+ index,
679
+ id: cmd.id,
680
+ command: cmd.command,
681
+ success: false,
682
+ error: capturedOutput || `Command exited with code ${err.code}`,
683
+ };
684
+ }
685
+ // Commander errors (e.g., missing required arg at runtime)
686
+ const isCommanderError = err && typeof err === "object" && "code" in err && "exitCode" in err;
687
+ if (isCommanderError) {
688
+ const cmdErr = err;
689
+ return {
690
+ index,
691
+ id: cmd.id,
692
+ command: cmd.command,
693
+ success: false,
694
+ error: cmdErr.message || capture.getOutput(),
695
+ };
696
+ }
697
+ // Generic errors
698
+ return {
699
+ index,
700
+ id: cmd.id,
701
+ command: cmd.command,
702
+ success: false,
703
+ error: err instanceof Error ? err.message : String(err),
704
+ };
705
+ }
706
+ //# sourceMappingURL=batch-exec.js.map