@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
@@ -15,49 +15,49 @@
15
15
  function getToolSummary(tool, input) {
16
16
  const inp = input;
17
17
  switch (tool) {
18
- case 'Bash': {
18
+ case "Bash": {
19
19
  const cmd = inp.command;
20
20
  if (cmd) {
21
- return cmd.length > 50 ? cmd.slice(0, 47) + '...' : cmd;
21
+ return cmd.length > 50 ? `${cmd.slice(0, 47)}...` : cmd;
22
22
  }
23
- return '';
23
+ return "";
24
24
  }
25
- case 'Read':
26
- case 'Write':
27
- case 'Edit': {
25
+ case "Read":
26
+ case "Write":
27
+ case "Edit": {
28
28
  const filePath = inp.file_path;
29
29
  if (filePath) {
30
30
  // Extract filename from path
31
- const parts = filePath.split('/');
31
+ const parts = filePath.split("/");
32
32
  return parts[parts.length - 1] || filePath;
33
33
  }
34
- return '';
34
+ return "";
35
35
  }
36
- case 'Grep': {
36
+ case "Grep": {
37
37
  const pattern = inp.pattern;
38
- return pattern ? `/${pattern}/` : '';
38
+ return pattern ? `/${pattern}/` : "";
39
39
  }
40
- case 'Glob': {
40
+ case "Glob": {
41
41
  const pattern = inp.pattern;
42
- return pattern || '';
42
+ return pattern || "";
43
43
  }
44
- case 'WebSearch': {
44
+ case "WebSearch": {
45
45
  const query = inp.query;
46
- return query || '';
46
+ return query || "";
47
47
  }
48
- case 'Task': {
48
+ case "Task": {
49
49
  const desc = inp.description;
50
- return desc || '';
50
+ return desc || "";
51
51
  }
52
- case 'TodoWrite': {
52
+ case "TodoWrite": {
53
53
  const todos = inp.todos;
54
54
  if (todos && todos.length > 0) {
55
55
  return `${todos.length} item(s)`;
56
56
  }
57
- return '';
57
+ return "";
58
58
  }
59
59
  default:
60
- return '';
60
+ return "";
61
61
  }
62
62
  }
63
63
  /**
@@ -84,7 +84,7 @@ function extractToolName(update) {
84
84
  if (update.title) {
85
85
  return normalizeTool(update.title);
86
86
  }
87
- return 'unknown';
87
+ return "unknown";
88
88
  }
89
89
  /**
90
90
  * Normalize tool name by stripping MCP prefixes.
@@ -103,7 +103,7 @@ function normalizeTool(name) {
103
103
  function extractToolOutput(update) {
104
104
  // Try rawOutput first
105
105
  if (update.rawOutput !== undefined) {
106
- return truncateOutput(String(update.rawOutput));
106
+ return truncateOutput(stringify(update.rawOutput));
107
107
  }
108
108
  // Try _meta.claudeCode.toolResponse (Claude Code pattern)
109
109
  // toolResponse is an object with stdout/stderr, not a string
@@ -113,16 +113,17 @@ function extractToolOutput(update) {
113
113
  if (claudeCode?.toolResponse !== undefined) {
114
114
  const toolResponse = claudeCode.toolResponse;
115
115
  // Extract stdout, falling back to stringifying the whole response
116
- if (typeof toolResponse.stdout === 'string') {
117
- const combined = toolResponse.stdout + (toolResponse.stderr ? `\n${toolResponse.stderr}` : '');
116
+ if (typeof toolResponse.stdout === "string") {
117
+ const combined = toolResponse.stdout +
118
+ (toolResponse.stderr ? `\n${toolResponse.stderr}` : "");
118
119
  return truncateOutput(combined.trim());
119
120
  }
120
- return truncateOutput(String(toolResponse));
121
+ return truncateOutput(stringify(toolResponse));
121
122
  }
122
123
  }
123
124
  // Try output field
124
125
  if (update.output !== undefined) {
125
- return truncateOutput(String(update.output));
126
+ return truncateOutput(stringify(update.output));
126
127
  }
127
128
  return undefined;
128
129
  }
@@ -131,32 +132,56 @@ function extractToolOutput(update) {
131
132
  */
132
133
  function extractOriginalOutput(update) {
133
134
  if (update.rawOutput !== undefined) {
134
- return String(update.rawOutput);
135
+ return stringify(update.rawOutput);
135
136
  }
136
137
  const meta = update._meta;
137
138
  if (meta) {
138
139
  const claudeCode = meta.claudeCode;
139
140
  if (claudeCode?.toolResponse !== undefined) {
140
141
  const toolResponse = claudeCode.toolResponse;
141
- if (typeof toolResponse.stdout === 'string') {
142
- return (toolResponse.stdout + (toolResponse.stderr ? `\n${toolResponse.stderr}` : '')).trim();
142
+ if (typeof toolResponse.stdout === "string") {
143
+ return (toolResponse.stdout +
144
+ (toolResponse.stderr ? `\n${toolResponse.stderr}` : "")).trim();
143
145
  }
144
146
  }
145
147
  }
146
148
  if (update.output !== undefined) {
147
- return String(update.output);
149
+ return stringify(update.output);
148
150
  }
149
151
  return undefined;
150
152
  }
153
+ /**
154
+ * Safely stringify a value that may be a string, array of content blocks, or object.
155
+ * Handles ACP tool results delivered as arrays like [{type:'text',text:'...'},...]
156
+ */
157
+ function stringify(value) {
158
+ if (typeof value === "string")
159
+ return value;
160
+ if (Array.isArray(value)) {
161
+ // Array of content blocks: extract .text fields
162
+ const texts = value
163
+ .map((item) => typeof item === "string"
164
+ ? item
165
+ : typeof item === "object" && item !== null && "text" in item
166
+ ? String(item.text)
167
+ : JSON.stringify(item))
168
+ .filter(Boolean);
169
+ return texts.join("\n");
170
+ }
171
+ if (typeof value === "object" && value !== null) {
172
+ return JSON.stringify(value);
173
+ }
174
+ return String(value);
175
+ }
151
176
  /**
152
177
  * Truncate output to reasonable size.
153
178
  */
154
179
  function truncateOutput(output) {
155
180
  const MAX_LINES = 20;
156
181
  const MAX_CHARS = 1000;
157
- const lines = output.split('\n');
182
+ const lines = output.split("\n");
158
183
  if (lines.length > MAX_LINES) {
159
- return lines.slice(0, MAX_LINES).join('\n');
184
+ return lines.slice(0, MAX_LINES).join("\n");
160
185
  }
161
186
  if (output.length > MAX_CHARS) {
162
187
  return output.slice(0, MAX_CHARS);
@@ -174,119 +199,256 @@ function wasOutputTruncated(original, truncated) {
174
199
  // ============================================================================
175
200
  // Noise Suppression
176
201
  // ============================================================================
177
- const SUPPRESSED_PATTERNS = [
178
- /No onPostToolUseHook found/i,
179
- /No onPreToolUseHook found/i,
202
+ /**
203
+ * Noise patterns to strip from streaming content.
204
+ * These match Claude Code hook warning messages that leak into agent output.
205
+ * Pattern structure handles various noise forms:
206
+ * - "No on[Pre|Post]ToolUseHook found"
207
+ * - "No on[Pre|Post]ToolUseHook found for tool use"
208
+ * - "No on[Pre|Post]ToolUseHook found for tool use ID: toolu_<24 chars>"
209
+ * Tool IDs are exactly 24 base62 characters after "toolu_".
210
+ */
211
+ const NOISE_PATTERNS = [
212
+ /No onPostToolUseHook found(?:\s+for\s+tool\s+use(?:\s+ID:\s*toolu_[A-Za-z0-9]{24})?)?/gi,
213
+ /No onPreToolUseHook found(?:\s+for\s+tool\s+use(?:\s+ID:\s*toolu_[A-Za-z0-9]{24})?)?/gi,
180
214
  ];
181
215
  /**
182
- * Check if a message should be suppressed from display.
216
+ * Full noise pattern strings (without tool ID suffix).
217
+ * Used to check if a suffix could be a prefix of a noise pattern.
183
218
  */
184
- function shouldSuppress(content) {
185
- return SUPPRESSED_PATTERNS.some((pattern) => pattern.test(content));
219
+ const NOISE_PATTERN_STRINGS = [
220
+ "No onPostToolUseHook found for tool use ID: toolu_",
221
+ "No onPreToolUseHook found for tool use ID: toolu_",
222
+ "No onPostToolUseHook found for tool use",
223
+ "No onPreToolUseHook found for tool use",
224
+ "No onPostToolUseHook found",
225
+ "No onPreToolUseHook found",
226
+ ];
227
+ // Maximum length to check for potential partial match
228
+ const MAX_NOISE_PATTERN_LEN = Math.max(...NOISE_PATTERN_STRINGS.map((p) => p.length)) + 24; // +24 for tool ID
229
+ /**
230
+ * Check if the content ends with a potential partial noise pattern.
231
+ * Returns the partial match length if found, 0 otherwise.
232
+ *
233
+ * A partial match occurs when:
234
+ * 1. The content ends with something that is a PREFIX of a noise pattern
235
+ * (e.g., "No on" or "No onPostToolUseHook found"), OR
236
+ * 2. The content ends with a complete noise pattern prefix followed by
237
+ * a partial tool ID (< 24 chars)
238
+ */
239
+ function getPartialNoiseLength(content) {
240
+ // Check suffixes of decreasing length (longer matches first)
241
+ const maxCheck = Math.min(content.length, MAX_NOISE_PATTERN_LEN);
242
+ for (let len = maxCheck; len > 0; len--) {
243
+ const suffix = content.slice(-len);
244
+ for (const pattern of NOISE_PATTERN_STRINGS) {
245
+ // Case 1: suffix is a prefix of a pattern (suffix is shorter than pattern)
246
+ // e.g., suffix="No onPost" is a prefix of pattern="No onPostToolUseHook found..."
247
+ if (suffix.length <= pattern.length && pattern.startsWith(suffix)) {
248
+ return len;
249
+ }
250
+ // Case 2: suffix starts with a complete toolu_ pattern and has partial tool ID
251
+ // e.g., suffix="No onPostToolUseHook found for tool use ID: toolu_ABC123"
252
+ // where the tool ID is < 24 chars
253
+ if (pattern.endsWith("toolu_") && suffix.startsWith(pattern)) {
254
+ const afterToolu = suffix.slice(pattern.length);
255
+ // If tool ID is incomplete (< 24 chars) and valid chars, it's a partial match
256
+ if (afterToolu.length < 24 && /^[A-Za-z0-9]*$/.test(afterToolu)) {
257
+ return len;
258
+ }
259
+ }
260
+ }
261
+ }
262
+ return 0;
263
+ }
264
+ /**
265
+ * Strip noise patterns from content.
266
+ * Returns the cleaned content, or null if nothing remains after stripping.
267
+ * Preserves whitespace-only chunks that aren't noise to maintain streaming formatting.
268
+ */
269
+ function stripNoise(content) {
270
+ let cleaned = content;
271
+ for (const pattern of NOISE_PATTERNS) {
272
+ cleaned = cleaned.replace(pattern, "");
273
+ }
274
+ // If nothing was stripped, return original (preserves pure whitespace chunks)
275
+ if (cleaned === content) {
276
+ return content;
277
+ }
278
+ // Something was stripped - return cleaned if non-empty, null otherwise
279
+ return cleaned.length > 0 ? cleaned : null;
186
280
  }
187
281
  export function createTranslator() {
188
282
  const state = {
189
283
  sessionStart: Date.now(),
190
284
  activeMessage: null,
191
285
  pendingTools: new Map(),
286
+ noiseBuffer: "",
192
287
  };
193
288
  function getTimestamp() {
194
289
  return Date.now() - state.sessionStart;
195
290
  }
291
+ /**
292
+ * Process a text chunk with boundary-aware noise stripping.
293
+ * Returns the safe content to emit, and updates the noise buffer.
294
+ * Returns null if the entire chunk should be suppressed.
295
+ *
296
+ * The key insight is that we need to check for partial noise patterns
297
+ * BEFORE stripping, because partial patterns won't match the full regex
298
+ * and could leave fragments behind.
299
+ */
300
+ function processChunkWithBuffer(text) {
301
+ // Combine buffer with new text
302
+ const combined = state.noiseBuffer + text;
303
+ state.noiseBuffer = "";
304
+ // First, check if the combined content ends with a partial noise pattern
305
+ // This must happen BEFORE stripping, because partial patterns at the end
306
+ // won't match the regex and could leave fragments
307
+ const partialLen = getPartialNoiseLength(combined);
308
+ if (partialLen > 0) {
309
+ // Buffer the potential partial match
310
+ state.noiseBuffer = combined.slice(-partialLen);
311
+ const safeContent = combined.slice(0, -partialLen);
312
+ // Strip complete noise patterns from the safe content
313
+ const cleaned = stripNoise(safeContent);
314
+ if (cleaned === null || cleaned.length === 0) {
315
+ return null;
316
+ }
317
+ return cleaned;
318
+ }
319
+ // No partial match at the end - strip complete patterns
320
+ const cleaned = stripNoise(combined);
321
+ if (cleaned === null) {
322
+ return null;
323
+ }
324
+ return cleaned;
325
+ }
326
+ /**
327
+ * Flush any remaining buffer content at finalization.
328
+ * Strips any complete noise patterns from the buffer.
329
+ */
330
+ function flushBuffer() {
331
+ const buffered = state.noiseBuffer;
332
+ state.noiseBuffer = "";
333
+ // Strip any complete noise from the buffer
334
+ const cleaned = stripNoise(buffered);
335
+ return cleaned ?? "";
336
+ }
196
337
  function translate(update) {
197
338
  const updateType = update.sessionUpdate;
198
339
  const timestamp = getTimestamp();
199
340
  switch (updateType) {
200
341
  // ─── Content Chunks ─────────────────────────────────────────────────────
201
- case 'agent_message_chunk': {
342
+ case "agent_message_chunk": {
202
343
  const content = update.content;
203
- if (content?.type === 'text' && typeof content.text === 'string') {
204
- // Check for noise
205
- if (shouldSuppress(content.text)) {
206
- return null;
207
- }
344
+ if (content?.type === "text" && typeof content.text === "string") {
208
345
  // Empty string signals finalization
209
- if (content.text === '') {
210
- if (state.activeMessage?.type === 'agent_message') {
211
- const final = {
212
- type: 'agent_message',
346
+ if (content.text === "") {
347
+ if (state.activeMessage?.type === "agent_message") {
348
+ // Flush buffer and strip noise from accumulated content
349
+ const buffered = flushBuffer();
350
+ const combined = state.activeMessage.content + buffered;
351
+ const finalContent = stripNoise(combined);
352
+ state.activeMessage = null;
353
+ if (finalContent === null || finalContent.trim() === "") {
354
+ return null;
355
+ }
356
+ return {
357
+ type: "agent_message",
213
358
  timestamp,
214
359
  data: {
215
- kind: 'agent_message',
216
- content: state.activeMessage.content,
360
+ kind: "agent_message",
361
+ content: finalContent,
217
362
  isStreaming: false,
218
363
  },
219
364
  };
220
- state.activeMessage = null;
221
- return final;
222
365
  }
223
366
  return null;
224
367
  }
368
+ // Process chunk with boundary-aware noise stripping
369
+ const cleanedText = processChunkWithBuffer(content.text);
370
+ if (cleanedText === null) {
371
+ return null;
372
+ }
225
373
  // Accumulate content
226
- if (state.activeMessage?.type === 'agent_message') {
227
- state.activeMessage.content += content.text;
374
+ if (state.activeMessage?.type === "agent_message") {
375
+ state.activeMessage.content += cleanedText;
228
376
  }
229
377
  else {
230
- state.activeMessage = { type: 'agent_message', content: content.text };
378
+ state.activeMessage = {
379
+ type: "agent_message",
380
+ content: cleanedText,
381
+ };
231
382
  }
232
383
  return {
233
- type: 'agent_message',
384
+ type: "agent_message",
234
385
  timestamp,
235
386
  data: {
236
- kind: 'agent_message',
237
- content: content.text,
387
+ kind: "agent_message",
388
+ content: cleanedText,
238
389
  isStreaming: true,
239
390
  },
240
391
  };
241
392
  }
242
393
  return null;
243
394
  }
244
- case 'agent_thought_chunk': {
395
+ case "agent_thought_chunk": {
245
396
  const content = update.content;
246
- if (content?.type === 'text' && typeof content.text === 'string') {
247
- if (shouldSuppress(content.text)) {
248
- return null;
249
- }
250
- if (content.text === '') {
251
- if (state.activeMessage?.type === 'agent_thought') {
252
- const final = {
253
- type: 'agent_thought',
397
+ if (content?.type === "text" && typeof content.text === "string") {
398
+ if (content.text === "") {
399
+ if (state.activeMessage?.type === "agent_thought") {
400
+ // Flush buffer and strip noise from accumulated content
401
+ const buffered = flushBuffer();
402
+ const combined = state.activeMessage.content + buffered;
403
+ const finalContent = stripNoise(combined);
404
+ state.activeMessage = null;
405
+ if (finalContent === null || finalContent.trim() === "") {
406
+ return null;
407
+ }
408
+ return {
409
+ type: "agent_thought",
254
410
  timestamp,
255
411
  data: {
256
- kind: 'agent_thought',
257
- content: state.activeMessage.content,
412
+ kind: "agent_thought",
413
+ content: finalContent,
258
414
  isStreaming: false,
259
415
  },
260
416
  };
261
- state.activeMessage = null;
262
- return final;
263
417
  }
264
418
  return null;
265
419
  }
266
- if (state.activeMessage?.type === 'agent_thought') {
267
- state.activeMessage.content += content.text;
420
+ // Process chunk with boundary-aware noise stripping
421
+ const cleanedText = processChunkWithBuffer(content.text);
422
+ if (cleanedText === null) {
423
+ return null;
424
+ }
425
+ if (state.activeMessage?.type === "agent_thought") {
426
+ state.activeMessage.content += cleanedText;
268
427
  }
269
428
  else {
270
- state.activeMessage = { type: 'agent_thought', content: content.text };
429
+ state.activeMessage = {
430
+ type: "agent_thought",
431
+ content: cleanedText,
432
+ };
271
433
  }
272
434
  return {
273
- type: 'agent_thought',
435
+ type: "agent_thought",
274
436
  timestamp,
275
437
  data: {
276
- kind: 'agent_thought',
277
- content: content.text,
438
+ kind: "agent_thought",
439
+ content: cleanedText,
278
440
  isStreaming: true,
279
441
  },
280
442
  };
281
443
  }
282
444
  return null;
283
445
  }
284
- case 'user_message_chunk': {
446
+ case "user_message_chunk": {
285
447
  // User messages are typically the prompt we sent, skip display
286
448
  return null;
287
449
  }
288
450
  // ─── Tool Events ────────────────────────────────────────────────────────
289
- case 'tool_call': {
451
+ case "tool_call": {
290
452
  const u = update;
291
453
  const toolCallId = (u.tool_call_id || u.toolCallId || u.id);
292
454
  const tool = extractToolName(u);
@@ -302,13 +464,13 @@ export function createTranslator() {
302
464
  // Only emit update if we now have a summary we didn't have before
303
465
  if (summary && !hadSummary) {
304
466
  return {
305
- type: 'tool_update',
467
+ type: "tool_update",
306
468
  timestamp,
307
469
  data: {
308
- kind: 'tool_update',
470
+ kind: "tool_update",
309
471
  toolCallId,
310
472
  tool,
311
- status: 'pending',
473
+ status: "pending",
312
474
  summary,
313
475
  },
314
476
  };
@@ -317,12 +479,16 @@ export function createTranslator() {
317
479
  return null;
318
480
  }
319
481
  // First time seeing this tool_call_id - create entry and emit tool_start
320
- state.pendingTools.set(toolCallId, { tool, input, startTime: timestamp });
482
+ state.pendingTools.set(toolCallId, {
483
+ tool,
484
+ input,
485
+ startTime: timestamp,
486
+ });
321
487
  return {
322
- type: 'tool_start',
488
+ type: "tool_start",
323
489
  timestamp,
324
490
  data: {
325
- kind: 'tool_start',
491
+ kind: "tool_start",
326
492
  toolCallId,
327
493
  tool,
328
494
  summary,
@@ -330,35 +496,65 @@ export function createTranslator() {
330
496
  },
331
497
  };
332
498
  }
333
- case 'tool_call_update': {
499
+ case "tool_call_update": {
334
500
  const u = update;
335
501
  const toolCallId = (u.tool_call_id || u.toolCallId || u.id);
336
502
  const status = u.status;
337
503
  const pending = state.pendingTools.get(toolCallId);
338
504
  const tool = pending?.tool || extractToolName(u);
505
+ // Check if rawInput arrived with this update (phased event pattern)
506
+ const newInput = u.rawInput || u.input || u.params;
507
+ if (newInput && pending) {
508
+ const oldSummary = getToolSummary(pending.tool, pending.input);
509
+ const newSummary = getToolSummary(tool, newInput);
510
+ if (newSummary && !oldSummary) {
511
+ // Input became available - update pending entry and emit summary
512
+ pending.input = newInput;
513
+ pending.tool = tool;
514
+ return {
515
+ type: "tool_update",
516
+ timestamp,
517
+ data: {
518
+ kind: "tool_update",
519
+ toolCallId,
520
+ tool,
521
+ status: "pending",
522
+ summary: newSummary,
523
+ },
524
+ };
525
+ }
526
+ // Update the pending entry even if summary didn't change
527
+ pending.input = newInput;
528
+ }
339
529
  // Non-terminal status update
340
- if (status === 'pending' || status === 'in_progress' || status === 'running') {
530
+ if (status === "pending" ||
531
+ status === "in_progress" ||
532
+ status === "running") {
341
533
  return {
342
- type: 'tool_update',
534
+ type: "tool_update",
343
535
  timestamp,
344
536
  data: {
345
- kind: 'tool_update',
537
+ kind: "tool_update",
346
538
  toolCallId,
347
539
  tool,
348
- status: status === 'in_progress' ? 'running' : status,
540
+ status: status === "in_progress"
541
+ ? "running"
542
+ : status,
349
543
  },
350
544
  };
351
545
  }
352
546
  // Terminal status - treat as result
353
- if (status === 'completed' || status === 'failed' || status === 'cancelled') {
547
+ if (status === "completed" ||
548
+ status === "failed" ||
549
+ status === "cancelled") {
354
550
  const rawOutput = extractToolOutput(u);
355
551
  const originalOutput = extractOriginalOutput(u);
356
552
  state.pendingTools.delete(toolCallId);
357
553
  return {
358
- type: 'tool_result',
554
+ type: "tool_result",
359
555
  timestamp,
360
556
  data: {
361
- kind: 'tool_result',
557
+ kind: "tool_result",
362
558
  toolCallId,
363
559
  tool,
364
560
  status,
@@ -378,17 +574,24 @@ export function createTranslator() {
378
574
  }
379
575
  function finalize() {
380
576
  if (state.activeMessage) {
381
- const final = {
382
- type: state.activeMessage.type,
577
+ // Flush buffer and strip noise from accumulated content
578
+ const buffered = flushBuffer();
579
+ const combined = state.activeMessage.content + buffered;
580
+ const finalContent = stripNoise(combined);
581
+ const type = state.activeMessage.type;
582
+ state.activeMessage = null;
583
+ if (finalContent === null || finalContent.trim() === "") {
584
+ return null;
585
+ }
586
+ return {
587
+ type,
383
588
  timestamp: getTimestamp(),
384
589
  data: {
385
- kind: state.activeMessage.type,
386
- content: state.activeMessage.content,
590
+ kind: type,
591
+ content: finalContent,
387
592
  isStreaming: false,
388
593
  },
389
594
  };
390
- state.activeMessage = null;
391
- return final;
392
595
  }
393
596
  return null;
394
597
  }