@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,164 @@
1
+ /**
2
+ * Inbox API Routes
3
+ *
4
+ * REST endpoints for inbox item operations:
5
+ * - GET /api/inbox - list all items
6
+ * - POST /api/inbox - create item
7
+ * - DELETE /api/inbox/:ref - delete item
8
+ *
9
+ * AC Coverage:
10
+ * - ac-12: GET /api/inbox returns items ordered by created_at desc
11
+ * - ac-13: POST /api/inbox creates item with generated ULID
12
+ * - ac-14: DELETE /api/inbox/:ref removes item
13
+ */
14
+
15
+ import { Elysia, t } from 'elysia';
16
+ import {
17
+ initContext,
18
+ loadInboxItems,
19
+ createInboxItem,
20
+ saveInboxItem,
21
+ deleteInboxItem,
22
+ findInboxItemByRef,
23
+ ReferenceIndex,
24
+ loadAllTasks,
25
+ loadAllItems,
26
+ type InboxItemInput,
27
+ } from '../../parser/index.js';
28
+ import { commitIfShadow } from '../../parser/shadow.js';
29
+ import type { PubSubManager } from '../websocket/pubsub';
30
+
31
+ interface InboxRouteOptions {
32
+ pubsub: PubSubManager;
33
+ }
34
+
35
+ export function createInboxRoutes(options: InboxRouteOptions) {
36
+ const { pubsub } = options;
37
+
38
+ return new Elysia({ prefix: '/api/inbox' })
39
+ // AC: @api-contract ac-12 - List inbox items ordered by created_at desc
40
+ .get('/', async ({ projectContext }) => {
41
+ // AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
42
+ const ctx = await initContext(projectContext.path);
43
+ const items = await loadInboxItems(ctx);
44
+
45
+ // AC: @api-contract ac-12 - Sort by created_at descending (newest first)
46
+ const sorted = [...items].sort(
47
+ (a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
48
+ );
49
+
50
+ return {
51
+ items: sorted,
52
+ total: sorted.length,
53
+ };
54
+ })
55
+
56
+ // AC: @api-contract ac-13 - Create inbox item
57
+ .post(
58
+ '/',
59
+ async ({ body, error: errorResponse, projectContext }) => {
60
+ // AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
61
+ const ctx = await initContext(projectContext.path);
62
+
63
+ // AC: @trait-api-endpoint ac-3 - Validate body
64
+ if (!body.text || typeof body.text !== 'string' || body.text.trim().length === 0) {
65
+ return errorResponse(400, {
66
+ error: 'validation_error',
67
+ details: [
68
+ {
69
+ field: 'text',
70
+ message: 'Text is required and must be a non-empty string',
71
+ },
72
+ ],
73
+ });
74
+ }
75
+
76
+ // Create inbox item input
77
+ const input: InboxItemInput = {
78
+ text: body.text,
79
+ tags: body.tags,
80
+ added_by: body.added_by,
81
+ };
82
+
83
+ // AC: @api-contract ac-13 - Generate ULID and create item
84
+ const item = createInboxItem(input, ctx.config?.identity?.author);
85
+
86
+ // Save and commit
87
+ await saveInboxItem(ctx, item);
88
+ await commitIfShadow(ctx.shadow, `inbox: add item ${item._ulid}`);
89
+
90
+ // Broadcast update
91
+ // AC: @multi-directory-daemon ac-18 - Broadcast scoped to request project
92
+ pubsub.broadcast('inbox:updates', 'inbox_item_created', {
93
+ ulid: item._ulid,
94
+ }, projectContext.path);
95
+
96
+ // AC: @api-contract ac-13 - Return item with generated ULID
97
+ return {
98
+ success: true,
99
+ item,
100
+ };
101
+ },
102
+ {
103
+ body: t.Object({
104
+ text: t.String(),
105
+ tags: t.Optional(t.Array(t.String())),
106
+ added_by: t.Optional(t.String()),
107
+ }),
108
+ }
109
+ )
110
+
111
+ // AC: @api-contract ac-14 - Delete inbox item
112
+ .delete(
113
+ '/:ref',
114
+ async ({ params, error: errorResponse, projectContext }) => {
115
+ // AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
116
+ const ctx = await initContext(projectContext.path);
117
+ const inboxItems = await loadInboxItems(ctx);
118
+ const tasks = await loadAllTasks(ctx);
119
+ const specItems = await loadAllItems(ctx);
120
+ const index = new ReferenceIndex(tasks, specItems);
121
+
122
+ // Resolve ref
123
+ const result = index.resolve(params.ref);
124
+ if (!result.ok) {
125
+ return errorResponse(404, {
126
+ error: 'not_found',
127
+ message: `Inbox item reference "${params.ref}" not found`,
128
+ suggestion: 'Use kspec inbox list to find valid inbox item references',
129
+ });
130
+ }
131
+
132
+ // Verify it's an inbox item
133
+ const item = findInboxItemByRef(inboxItems, result.ulid);
134
+ if (!item) {
135
+ return errorResponse(404, {
136
+ error: 'not_found',
137
+ message: `Reference "${params.ref}" is not an inbox item`,
138
+ });
139
+ }
140
+
141
+ // AC: @api-contract ac-14 - Delete item
142
+ await deleteInboxItem(ctx, result.ulid);
143
+ await commitIfShadow(ctx.shadow, `inbox: delete ${params.ref}`);
144
+
145
+ // Broadcast update
146
+ // AC: @multi-directory-daemon ac-18 - Broadcast scoped to request project
147
+ pubsub.broadcast('inbox:updates', 'inbox_item_deleted', {
148
+ ref: params.ref,
149
+ ulid: result.ulid,
150
+ }, projectContext.path);
151
+
152
+ // AC: @api-contract ac-14 - Return success confirmation
153
+ return {
154
+ success: true,
155
+ deleted: result.ulid,
156
+ };
157
+ },
158
+ {
159
+ params: t.Object({
160
+ ref: t.String(),
161
+ }),
162
+ }
163
+ );
164
+ }
@@ -0,0 +1,322 @@
1
+ /**
2
+ * Spec Item API Routes
3
+ *
4
+ * REST endpoints for spec item operations:
5
+ * - GET /api/items - list with filters and pagination
6
+ * - GET /api/items/:ref - get single item
7
+ * - GET /api/items/:ref/tasks - get linked tasks
8
+ *
9
+ * AC Coverage:
10
+ * - ac-8: GET /api/items returns array of spec items
11
+ * - ac-9: Type filter with multi-value support
12
+ * - ac-10: GET /api/items/:ref with full details
13
+ * - ac-11: GET /api/items/:ref/tasks via AlignmentIndex
14
+ */
15
+
16
+ import { Elysia, t } from 'elysia';
17
+ import {
18
+ initContext,
19
+ loadAllItems,
20
+ loadAllTasks,
21
+ ReferenceIndex,
22
+ AlignmentIndex,
23
+ getCachedTestCoverage,
24
+ computeACCoverage,
25
+ type LoadedSpecItem,
26
+ } from '../../parser/index.js';
27
+
28
+ interface ItemsRouteOptions {}
29
+
30
+ /**
31
+ * Compute parent ULIDs for items based on _path and _sourceFile.
32
+ * Items are nested when they share the same source file and
33
+ * one item's path is a prefix of another's path.
34
+ */
35
+ function computeParentMap(items: LoadedSpecItem[]): Map<string, string | undefined> {
36
+ const parentMap = new Map<string, string | undefined>();
37
+
38
+ // Group items by source file
39
+ const byFile = new Map<string, LoadedSpecItem[]>();
40
+ for (const item of items) {
41
+ const file = item._sourceFile || '';
42
+ if (!byFile.has(file)) {
43
+ byFile.set(file, []);
44
+ }
45
+ byFile.get(file)!.push(item);
46
+ }
47
+
48
+ // For each file, determine parent relationships based on path
49
+ for (const [, fileItems] of byFile) {
50
+ // Sort by path length (shorter paths are potential parents)
51
+ const sorted = [...fileItems].sort((a, b) => {
52
+ const aLen = a._path?.length || 0;
53
+ const bLen = b._path?.length || 0;
54
+ return aLen - bLen;
55
+ });
56
+
57
+ for (const item of sorted) {
58
+ const itemPath = item._path;
59
+
60
+ if (!itemPath) {
61
+ // Root item in file - no parent
62
+ parentMap.set(item._ulid, undefined);
63
+ continue;
64
+ }
65
+
66
+ // Find the closest parent by matching path prefix
67
+ // Path format: "features[0].requirements[0]"
68
+ // Parent path: "features[0]" or undefined (root item)
69
+ const lastDot = itemPath.lastIndexOf('.');
70
+ const parentPath = lastDot > -1 ? itemPath.substring(0, lastDot) : undefined;
71
+
72
+ // Find parent item
73
+ let parentUlid: string | undefined;
74
+ if (parentPath === undefined) {
75
+ // Direct child of the root item (the item with no path)
76
+ const rootItem = fileItems.find(i => !i._path);
77
+ parentUlid = rootItem?._ulid;
78
+ } else {
79
+ // Find item with matching parent path
80
+ const parentItem = fileItems.find(i => i._path === parentPath);
81
+ parentUlid = parentItem?._ulid;
82
+ }
83
+
84
+ parentMap.set(item._ulid, parentUlid);
85
+ }
86
+ }
87
+
88
+ return parentMap;
89
+ }
90
+
91
+ export function createItemsRoutes(options: ItemsRouteOptions = {}) {
92
+ // No closure-scoped kspecDir needed - comes from middleware
93
+
94
+ return new Elysia({ prefix: '/api/items' })
95
+ // AC: @api-contract ac-8, ac-9 - List items with type filter
96
+ .get(
97
+ '/',
98
+ async ({ query, projectContext }) => {
99
+ // AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
100
+ const ctx = await initContext(projectContext.path);
101
+ const items = await loadAllItems(ctx);
102
+
103
+ // Compute parent relationships from path structure
104
+ const parentMap = computeParentMap(items);
105
+
106
+ // Apply filters
107
+ let filtered = items;
108
+
109
+ // AC: @api-contract ac-9 - Multi-value type filter
110
+ if (query.type) {
111
+ const typeFilters = Array.isArray(query.type) ? query.type : [query.type];
112
+ filtered = filtered.filter((item) => typeFilters.includes(item.type));
113
+ }
114
+
115
+ // Optional maturity filter (not in ACs but useful)
116
+ if (query.maturity) {
117
+ const maturityFilters = Array.isArray(query.maturity) ? query.maturity : [query.maturity];
118
+ filtered = filtered.filter((item) => {
119
+ if (typeof item.status === 'object' && item.status?.maturity) {
120
+ return maturityFilters.includes(item.status.maturity);
121
+ }
122
+ return false;
123
+ });
124
+ }
125
+
126
+ // Optional implementation filter (not in ACs but useful)
127
+ if (query.implementation) {
128
+ const implFilters = Array.isArray(query.implementation)
129
+ ? query.implementation
130
+ : [query.implementation];
131
+ filtered = filtered.filter((item) => {
132
+ if (typeof item.status === 'object' && item.status?.implementation) {
133
+ return implFilters.includes(item.status.implementation);
134
+ }
135
+ return false;
136
+ });
137
+ }
138
+
139
+ // Tag filter (not in ACs but useful)
140
+ if (query.tag) {
141
+ const tagFilters = Array.isArray(query.tag) ? query.tag : [query.tag];
142
+ filtered = filtered.filter((item) =>
143
+ item.tags?.some((t) => tagFilters.includes(t))
144
+ );
145
+ }
146
+
147
+ // Pagination
148
+ const total = filtered.length;
149
+ const offset = Number(query.offset) || 0;
150
+ const limit = Number(query.limit) || total;
151
+
152
+ const paginated = filtered.slice(offset, offset + limit);
153
+
154
+ // AC: @api-contract ac-8 - Return spec items (modules, features, requirements)
155
+ const result = paginated.map((item) => ({
156
+ _ulid: item._ulid,
157
+ slugs: item.slugs,
158
+ title: item.title,
159
+ type: item.type,
160
+ status: item.status,
161
+ tags: item.tags,
162
+ parent: parentMap.get(item._ulid),
163
+ created_at: item.created_at,
164
+ acceptance_criteria_count: item.acceptance_criteria?.length || 0,
165
+ }));
166
+
167
+ // AC: @trait-api-endpoint ac-4 - Return pagination wrapper
168
+ return {
169
+ items: result,
170
+ total,
171
+ offset,
172
+ limit,
173
+ };
174
+ },
175
+ {
176
+ query: t.Object({
177
+ type: t.Optional(t.Union([t.String(), t.Array(t.String())])),
178
+ maturity: t.Optional(t.Union([t.String(), t.Array(t.String())])),
179
+ implementation: t.Optional(t.Union([t.String(), t.Array(t.String())])),
180
+ tag: t.Optional(t.Union([t.String(), t.Array(t.String())])),
181
+ limit: t.Optional(t.String()),
182
+ offset: t.Optional(t.String()),
183
+ }),
184
+ }
185
+ )
186
+
187
+ // AC: @api-contract ac-10 - Get single item by ref
188
+ .get(
189
+ '/:ref',
190
+ async ({ params, error: errorResponse, projectContext }) => {
191
+ // AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
192
+ const ctx = await initContext(projectContext.path);
193
+ const items = await loadAllItems(ctx);
194
+ const tasks = await loadAllTasks(ctx);
195
+ const index = new ReferenceIndex(tasks, items);
196
+
197
+ // Compute parent relationships from path structure
198
+ const parentMap = computeParentMap(items);
199
+
200
+ // AC: @api-contract ac-10, @trait-api-endpoint ac-2 - Resolve ref via ReferenceIndex
201
+ const result = index.resolve(params.ref);
202
+
203
+ if (!result.ok) {
204
+ // AC: @trait-api-endpoint ac-2 - Return 404 with error details
205
+ return errorResponse(404, {
206
+ error: 'not_found',
207
+ message: `Item reference "${params.ref}" not found`,
208
+ suggestion: 'Use kspec item list or kspec search to find valid item references',
209
+ });
210
+ }
211
+
212
+ // Find the item
213
+ const item = items.find((i) => i._ulid === result.ulid);
214
+ if (!item) {
215
+ return errorResponse(404, {
216
+ error: 'not_found',
217
+ message: `Reference "${params.ref}" is not a spec item`,
218
+ suggestion: 'This reference might point to a task instead',
219
+ });
220
+ }
221
+
222
+ // AC: @web-dashboard ac-15 - Compute test coverage for acceptance criteria
223
+ // Uses cached coverage scan for performance (avoids re-scanning on every request)
224
+ let acceptanceCriteriaWithCoverage = item.acceptance_criteria;
225
+ if (item.acceptance_criteria && item.acceptance_criteria.length > 0) {
226
+ try {
227
+ const coveredACs = await getCachedTestCoverage(projectContext.path);
228
+ acceptanceCriteriaWithCoverage = computeACCoverage(item, coveredACs);
229
+ } catch (err) {
230
+ // Coverage scan failed - leave as undefined
231
+ console.warn('AC coverage scan failed:', err);
232
+ }
233
+ }
234
+
235
+ // AC: @api-contract ac-10 - Return full item with acceptance_criteria, traits, relationships
236
+ return {
237
+ _ulid: item._ulid,
238
+ slugs: item.slugs,
239
+ title: item.title,
240
+ type: item.type,
241
+ status: item.status,
242
+ tags: item.tags,
243
+ parent: parentMap.get(item._ulid),
244
+ description: item.description,
245
+ acceptance_criteria: acceptanceCriteriaWithCoverage,
246
+ traits: item.traits,
247
+ relationships: item.relationships,
248
+ created_at: item.created_at,
249
+ _sourceFile: item._sourceFile,
250
+ };
251
+ },
252
+ {
253
+ params: t.Object({
254
+ ref: t.String(),
255
+ }),
256
+ }
257
+ )
258
+
259
+ // AC: @api-contract ac-11 - Get tasks linked to spec item
260
+ .get(
261
+ '/:ref/tasks',
262
+ async ({ params, error: errorResponse, projectContext }) => {
263
+ // AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
264
+ const ctx = await initContext(projectContext.path);
265
+ const items = await loadAllItems(ctx);
266
+ const tasks = await loadAllTasks(ctx);
267
+ const refIndex = new ReferenceIndex(tasks, items);
268
+ const alignIndex = new AlignmentIndex(tasks, items);
269
+ alignIndex.buildLinks(refIndex);
270
+
271
+ // Resolve ref
272
+ const result = refIndex.resolve(params.ref);
273
+
274
+ if (!result.ok) {
275
+ return errorResponse(404, {
276
+ error: 'not_found',
277
+ message: `Item reference "${params.ref}" not found`,
278
+ suggestion: 'Use kspec item list to find valid item references',
279
+ });
280
+ }
281
+
282
+ const item = items.find((i) => i._ulid === result.ulid);
283
+ if (!item) {
284
+ return errorResponse(404, {
285
+ error: 'not_found',
286
+ message: `Reference "${params.ref}" is not a spec item`,
287
+ });
288
+ }
289
+
290
+ // AC: @api-contract ac-11 - Get tasks via AlignmentIndex
291
+ const linkedTasks = alignIndex.getTasksForSpec(result.ulid);
292
+
293
+ // Return tasks with summary info
294
+ const result_items = linkedTasks.map((task) => ({
295
+ _ulid: task._ulid,
296
+ slugs: task.slugs,
297
+ title: task.title,
298
+ type: task.type || 'task',
299
+ status: task.status,
300
+ priority: task.priority,
301
+ spec_ref: task.spec_ref,
302
+ tags: task.tags || [],
303
+ depends_on: task.depends_on || [],
304
+ started_at: task.started_at,
305
+ completed_at: task.completed_at,
306
+ created_at: task.created_at,
307
+ notes_count: task.notes?.length || 0,
308
+ todos_count: task.todos?.length || 0,
309
+ }));
310
+
311
+ return {
312
+ items: result_items,
313
+ total: result_items.length,
314
+ };
315
+ },
316
+ {
317
+ params: t.Object({
318
+ ref: t.String(),
319
+ }),
320
+ }
321
+ );
322
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Meta API Routes
3
+ *
4
+ * REST endpoints for meta operations:
5
+ * - GET /api/meta/session - get session context
6
+ * - GET /api/meta/agents - list agents
7
+ * - GET /api/meta/workflows - list workflows
8
+ * - GET /api/meta/observations - list observations with filter
9
+ *
10
+ * AC Coverage:
11
+ * - ac-15: GET /api/meta/session returns session context
12
+ * - ac-16: GET /api/meta/agents returns all agents
13
+ * - ac-17: GET /api/meta/workflows returns all workflows
14
+ * - ac-18: GET /api/meta/observations with filter
15
+ */
16
+
17
+ import { Elysia, t } from 'elysia';
18
+ import {
19
+ initContext,
20
+ loadMetaContext,
21
+ loadSessionContext,
22
+ } from '../../parser/index.js';
23
+
24
+ interface MetaRouteOptions {}
25
+
26
+ export function createMetaRoutes(options: MetaRouteOptions = {}) {
27
+ // No closure-scoped kspecDir needed - comes from middleware
28
+
29
+ return new Elysia({ prefix: '/api/meta' })
30
+ // AC: @api-contract ac-15 - Get session context
31
+ .get('/session', async ({ projectContext }) => {
32
+ // AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
33
+ const ctx = await initContext(projectContext.path);
34
+ const session = await loadSessionContext(ctx);
35
+
36
+ // AC: @api-contract ac-15 - Return session context (focus, threads, questions)
37
+ return {
38
+ focus: session.focus,
39
+ threads: session.threads || [],
40
+ questions: session.questions || [],
41
+ updated_at: session.updated_at,
42
+ };
43
+ })
44
+
45
+ // AC: @api-contract ac-16 - List agents
46
+ .get('/agents', async ({ projectContext }) => {
47
+ // AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
48
+ const ctx = await initContext(projectContext.path);
49
+ const meta = await loadMetaContext(ctx);
50
+
51
+ // AC: @api-contract ac-16 - Return all defined agents
52
+ const agents = meta.agents;
53
+
54
+ return {
55
+ items: agents,
56
+ total: agents.length,
57
+ };
58
+ })
59
+
60
+ // AC: @api-contract ac-17 - List workflows
61
+ .get('/workflows', async ({ projectContext }) => {
62
+ // AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
63
+ const ctx = await initContext(projectContext.path);
64
+ const meta = await loadMetaContext(ctx);
65
+
66
+ // AC: @api-contract ac-17 - Return all defined workflows
67
+ const workflows = meta.workflows;
68
+
69
+ return {
70
+ items: workflows,
71
+ total: workflows.length,
72
+ };
73
+ })
74
+
75
+ // AC: @api-contract ac-18 - List observations with filter
76
+ .get(
77
+ '/observations',
78
+ async ({ query, projectContext }) => {
79
+ // AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
80
+ const ctx = await initContext(projectContext.path);
81
+ const meta = await loadMetaContext(ctx);
82
+
83
+ // Start with all observations
84
+ let filtered = meta.observations || [];
85
+
86
+ // AC: @api-contract ac-18 - Filter by resolved status
87
+ if (query.resolved !== undefined) {
88
+ const resolvedFilter = query.resolved === 'true';
89
+ filtered = filtered.filter((obs) => {
90
+ const isResolved = !!obs.resolved_at;
91
+ return isResolved === resolvedFilter;
92
+ });
93
+ }
94
+
95
+ // Optional type filter (not in ACs but useful)
96
+ if (query.type) {
97
+ const typeFilters = Array.isArray(query.type) ? query.type : [query.type];
98
+ filtered = filtered.filter((obs) => typeFilters.includes(obs.type));
99
+ }
100
+
101
+ // Sort by created_at descending (newest first)
102
+ const sorted = [...filtered].sort(
103
+ (a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
104
+ );
105
+
106
+ return {
107
+ items: sorted,
108
+ total: sorted.length,
109
+ };
110
+ },
111
+ {
112
+ query: t.Object({
113
+ resolved: t.Optional(t.String()),
114
+ type: t.Optional(t.Union([t.String(), t.Array(t.String())])),
115
+ }),
116
+ }
117
+ );
118
+ }