@kynetic-ai/spec 0.11.0 → 0.12.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 (501) hide show
  1. package/README.md +55 -455
  2. package/dist/agent-runtime/bootstrap.d.ts +31 -0
  3. package/dist/agent-runtime/bootstrap.d.ts.map +1 -0
  4. package/dist/agent-runtime/bootstrap.js +302 -0
  5. package/dist/agent-runtime/bootstrap.js.map +1 -0
  6. package/dist/agent-runtime/dispatch.d.ts +119 -10
  7. package/dist/agent-runtime/dispatch.d.ts.map +1 -1
  8. package/dist/agent-runtime/dispatch.js +1154 -219
  9. package/dist/agent-runtime/dispatch.js.map +1 -1
  10. package/dist/agent-runtime/invocation.d.ts +28 -1
  11. package/dist/agent-runtime/invocation.d.ts.map +1 -1
  12. package/dist/agent-runtime/invocation.js +171 -59
  13. package/dist/agent-runtime/invocation.js.map +1 -1
  14. package/dist/agent-runtime/prompts.d.ts +9 -0
  15. package/dist/agent-runtime/prompts.d.ts.map +1 -1
  16. package/dist/agent-runtime/prompts.js +42 -7
  17. package/dist/agent-runtime/prompts.js.map +1 -1
  18. package/dist/agent-runtime/session-event-accumulator.d.ts +83 -0
  19. package/dist/agent-runtime/session-event-accumulator.d.ts.map +1 -0
  20. package/dist/agent-runtime/session-event-accumulator.js +203 -0
  21. package/dist/agent-runtime/session-event-accumulator.js.map +1 -0
  22. package/dist/agent-runtime/session-event-types.d.ts +67 -0
  23. package/dist/agent-runtime/session-event-types.d.ts.map +1 -0
  24. package/dist/agent-runtime/session-event-types.js +13 -0
  25. package/dist/agent-runtime/session-event-types.js.map +1 -0
  26. package/dist/agent-runtime/workspace.d.ts +244 -0
  27. package/dist/agent-runtime/workspace.d.ts.map +1 -0
  28. package/dist/agent-runtime/workspace.js +2025 -0
  29. package/dist/agent-runtime/workspace.js.map +1 -0
  30. package/dist/agents/adapters.d.ts.map +1 -1
  31. package/dist/agents/adapters.js +58 -13
  32. package/dist/agents/adapters.js.map +1 -1
  33. package/dist/agents/spawner.d.ts +8 -0
  34. package/dist/agents/spawner.d.ts.map +1 -1
  35. package/dist/agents/spawner.js +25 -3
  36. package/dist/agents/spawner.js.map +1 -1
  37. package/dist/cli/batch-exec.js +1 -1
  38. package/dist/cli/batch-exec.js.map +1 -1
  39. package/dist/cli/command-annotations.d.ts +15 -3
  40. package/dist/cli/command-annotations.d.ts.map +1 -1
  41. package/dist/cli/command-annotations.js +23 -3
  42. package/dist/cli/command-annotations.js.map +1 -1
  43. package/dist/cli/commands/agent.d.ts +2 -0
  44. package/dist/cli/commands/agent.d.ts.map +1 -1
  45. package/dist/cli/commands/agent.js +144 -27
  46. package/dist/cli/commands/agent.js.map +1 -1
  47. package/dist/cli/commands/agents.d.ts.map +1 -1
  48. package/dist/cli/commands/agents.js +5 -5
  49. package/dist/cli/commands/agents.js.map +1 -1
  50. package/dist/cli/commands/derive.d.ts.map +1 -1
  51. package/dist/cli/commands/derive.js +118 -3
  52. package/dist/cli/commands/derive.js.map +1 -1
  53. package/dist/cli/commands/guard.d.ts.map +1 -1
  54. package/dist/cli/commands/guard.js +8 -6
  55. package/dist/cli/commands/guard.js.map +1 -1
  56. package/dist/cli/commands/index.d.ts +1 -0
  57. package/dist/cli/commands/index.d.ts.map +1 -1
  58. package/dist/cli/commands/index.js +1 -0
  59. package/dist/cli/commands/index.js.map +1 -1
  60. package/dist/cli/commands/init.d.ts.map +1 -1
  61. package/dist/cli/commands/init.js +20 -0
  62. package/dist/cli/commands/init.js.map +1 -1
  63. package/dist/cli/commands/item.d.ts.map +1 -1
  64. package/dist/cli/commands/item.js +205 -47
  65. package/dist/cli/commands/item.js.map +1 -1
  66. package/dist/cli/commands/log.d.ts.map +1 -1
  67. package/dist/cli/commands/log.js +24 -10
  68. package/dist/cli/commands/log.js.map +1 -1
  69. package/dist/cli/commands/plan-import.d.ts +3 -3
  70. package/dist/cli/commands/plan-import.d.ts.map +1 -1
  71. package/dist/cli/commands/plan-import.js +213 -528
  72. package/dist/cli/commands/plan-import.js.map +1 -1
  73. package/dist/cli/commands/plan.d.ts.map +1 -1
  74. package/dist/cli/commands/plan.js +533 -83
  75. package/dist/cli/commands/plan.js.map +1 -1
  76. package/dist/cli/commands/review.d.ts +14 -0
  77. package/dist/cli/commands/review.d.ts.map +1 -0
  78. package/dist/cli/commands/review.js +1142 -0
  79. package/dist/cli/commands/review.js.map +1 -0
  80. package/dist/cli/commands/serve.d.ts +1 -0
  81. package/dist/cli/commands/serve.d.ts.map +1 -1
  82. package/dist/cli/commands/serve.js +33 -10
  83. package/dist/cli/commands/serve.js.map +1 -1
  84. package/dist/cli/commands/session/checkpoint.d.ts +2 -4
  85. package/dist/cli/commands/session/checkpoint.d.ts.map +1 -1
  86. package/dist/cli/commands/session/checkpoint.js +6 -107
  87. package/dist/cli/commands/session/checkpoint.js.map +1 -1
  88. package/dist/cli/commands/session/commands.d.ts.map +1 -1
  89. package/dist/cli/commands/session/commands.js +33 -23
  90. package/dist/cli/commands/session/commands.js.map +1 -1
  91. package/dist/cli/commands/session/compact.js +4 -4
  92. package/dist/cli/commands/session/compact.js.map +1 -1
  93. package/dist/cli/commands/session/create.js +2 -2
  94. package/dist/cli/commands/session/create.js.map +1 -1
  95. package/dist/cli/commands/session/format.d.ts.map +1 -1
  96. package/dist/cli/commands/session/format.js +1 -6
  97. package/dist/cli/commands/session/format.js.map +1 -1
  98. package/dist/cli/commands/session/log.d.ts +32 -7
  99. package/dist/cli/commands/session/log.d.ts.map +1 -1
  100. package/dist/cli/commands/session/log.js +166 -60
  101. package/dist/cli/commands/session/log.js.map +1 -1
  102. package/dist/cli/commands/session/migrate.d.ts +9 -0
  103. package/dist/cli/commands/session/migrate.d.ts.map +1 -0
  104. package/dist/cli/commands/session/migrate.js +46 -0
  105. package/dist/cli/commands/session/migrate.js.map +1 -0
  106. package/dist/cli/commands/session/stale-close.d.ts.map +1 -1
  107. package/dist/cli/commands/session/stale-close.js +5 -8
  108. package/dist/cli/commands/session/stale-close.js.map +1 -1
  109. package/dist/cli/commands/session/types.d.ts +1 -1
  110. package/dist/cli/commands/session/types.d.ts.map +1 -1
  111. package/dist/cli/commands/setup.d.ts +2 -2
  112. package/dist/cli/commands/setup.d.ts.map +1 -1
  113. package/dist/cli/commands/setup.js +287 -257
  114. package/dist/cli/commands/setup.js.map +1 -1
  115. package/dist/cli/commands/shadow.d.ts.map +1 -1
  116. package/dist/cli/commands/shadow.js +147 -31
  117. package/dist/cli/commands/shadow.js.map +1 -1
  118. package/dist/cli/commands/skill-crud.d.ts +7 -0
  119. package/dist/cli/commands/skill-crud.d.ts.map +1 -1
  120. package/dist/cli/commands/skill-crud.js +41 -18
  121. package/dist/cli/commands/skill-crud.js.map +1 -1
  122. package/dist/cli/commands/skill-diff.d.ts.map +1 -1
  123. package/dist/cli/commands/skill-diff.js +29 -3
  124. package/dist/cli/commands/skill-diff.js.map +1 -1
  125. package/dist/cli/commands/skill-install.d.ts.map +1 -1
  126. package/dist/cli/commands/skill-install.js +5 -4
  127. package/dist/cli/commands/skill-install.js.map +1 -1
  128. package/dist/cli/commands/task.d.ts.map +1 -1
  129. package/dist/cli/commands/task.js +359 -49
  130. package/dist/cli/commands/task.js.map +1 -1
  131. package/dist/cli/commands/trait.d.ts.map +1 -1
  132. package/dist/cli/commands/trait.js +5 -27
  133. package/dist/cli/commands/trait.js.map +1 -1
  134. package/dist/cli/commands/validate.d.ts.map +1 -1
  135. package/dist/cli/commands/validate.js +113 -52
  136. package/dist/cli/commands/validate.js.map +1 -1
  137. package/dist/cli/index.d.ts.map +1 -1
  138. package/dist/cli/index.js +69 -2
  139. package/dist/cli/index.js.map +1 -1
  140. package/dist/cli/output.d.ts +26 -0
  141. package/dist/cli/output.d.ts.map +1 -1
  142. package/dist/cli/output.js +108 -1
  143. package/dist/cli/output.js.map +1 -1
  144. package/dist/cli/sync-mode.d.ts +44 -0
  145. package/dist/cli/sync-mode.d.ts.map +1 -0
  146. package/dist/cli/sync-mode.js +64 -0
  147. package/dist/cli/sync-mode.js.map +1 -0
  148. package/dist/daemon/middleware/project-context.ts +25 -7
  149. package/dist/daemon/project-context.ts +18 -0
  150. package/dist/daemon/routes/agent-dispatch.ts +99 -22
  151. package/dist/daemon/routes/aggregation.ts +184 -0
  152. package/dist/daemon/routes/inbox.ts +5 -0
  153. package/dist/daemon/routes/items.ts +145 -0
  154. package/dist/daemon/routes/meta.ts +1 -1
  155. package/dist/daemon/routes/projects.ts +28 -6
  156. package/dist/daemon/routes/ref-resolution.ts +119 -0
  157. package/dist/daemon/routes/refs.ts +42 -0
  158. package/dist/daemon/routes/session-related.ts +140 -0
  159. package/dist/daemon/routes/sessions.ts +420 -19
  160. package/dist/daemon/routes/tasks.ts +62 -5
  161. package/dist/daemon/routes/triage.ts +40 -1
  162. package/dist/daemon/server.ts +143 -49
  163. package/dist/daemon/session-sync.ts +11 -0
  164. package/dist/daemon/shadow-sync.ts +11 -0
  165. package/dist/daemon/watcher.ts +56 -5
  166. package/dist/daemon/websocket/project-resolution.ts +77 -0
  167. package/dist/export/json.d.ts.map +1 -1
  168. package/dist/export/json.js +104 -1
  169. package/dist/export/json.js.map +1 -1
  170. package/dist/export/types.d.ts +52 -1
  171. package/dist/export/types.d.ts.map +1 -1
  172. package/dist/index.d.ts +1 -0
  173. package/dist/index.d.ts.map +1 -1
  174. package/dist/index.js +1 -0
  175. package/dist/index.js.map +1 -1
  176. package/dist/parser/agent-detection.d.ts +1 -1
  177. package/dist/parser/agent-detection.d.ts.map +1 -1
  178. package/dist/parser/agent-detection.js +10 -0
  179. package/dist/parser/agent-detection.js.map +1 -1
  180. package/dist/parser/config.d.ts +397 -2
  181. package/dist/parser/config.d.ts.map +1 -1
  182. package/dist/parser/config.js +125 -3
  183. package/dist/parser/config.js.map +1 -1
  184. package/dist/parser/dispatch-workspaces.d.ts +18 -0
  185. package/dist/parser/dispatch-workspaces.d.ts.map +1 -0
  186. package/dist/parser/dispatch-workspaces.js +209 -0
  187. package/dist/parser/dispatch-workspaces.js.map +1 -0
  188. package/dist/parser/doctor.d.ts.map +1 -1
  189. package/dist/parser/doctor.js +27 -8
  190. package/dist/parser/doctor.js.map +1 -1
  191. package/dist/parser/file-lock.d.ts.map +1 -1
  192. package/dist/parser/file-lock.js +9 -2
  193. package/dist/parser/file-lock.js.map +1 -1
  194. package/dist/parser/index.d.ts +6 -0
  195. package/dist/parser/index.d.ts.map +1 -1
  196. package/dist/parser/index.js +6 -0
  197. package/dist/parser/index.js.map +1 -1
  198. package/dist/parser/plans.d.ts.map +1 -1
  199. package/dist/parser/plans.js +1 -0
  200. package/dist/parser/plans.js.map +1 -1
  201. package/dist/parser/refs.d.ts +8 -1
  202. package/dist/parser/refs.d.ts.map +1 -1
  203. package/dist/parser/refs.js +27 -1
  204. package/dist/parser/refs.js.map +1 -1
  205. package/dist/parser/review-operations.d.ts +72 -0
  206. package/dist/parser/review-operations.d.ts.map +1 -0
  207. package/dist/parser/review-operations.js +185 -0
  208. package/dist/parser/review-operations.js.map +1 -0
  209. package/dist/parser/review-task-integration.d.ts +78 -0
  210. package/dist/parser/review-task-integration.d.ts.map +1 -0
  211. package/dist/parser/review-task-integration.js +173 -0
  212. package/dist/parser/review-task-integration.js.map +1 -0
  213. package/dist/parser/review-threads.d.ts +101 -0
  214. package/dist/parser/review-threads.d.ts.map +1 -0
  215. package/dist/parser/review-threads.js +222 -0
  216. package/dist/parser/review-threads.js.map +1 -0
  217. package/dist/parser/review-validation.d.ts +69 -0
  218. package/dist/parser/review-validation.d.ts.map +1 -0
  219. package/dist/parser/review-validation.js +207 -0
  220. package/dist/parser/review-validation.js.map +1 -0
  221. package/dist/parser/reviews.d.ts +58 -0
  222. package/dist/parser/reviews.d.ts.map +1 -0
  223. package/dist/parser/reviews.js +230 -0
  224. package/dist/parser/reviews.js.map +1 -0
  225. package/dist/parser/session-branch.d.ts +91 -0
  226. package/dist/parser/session-branch.d.ts.map +1 -0
  227. package/dist/parser/session-branch.js +565 -0
  228. package/dist/parser/session-branch.js.map +1 -0
  229. package/dist/parser/session-sync-scheduler.d.ts +53 -0
  230. package/dist/parser/session-sync-scheduler.d.ts.map +1 -0
  231. package/dist/parser/session-sync-scheduler.js +100 -0
  232. package/dist/parser/session-sync-scheduler.js.map +1 -0
  233. package/dist/parser/setup-status.d.ts +7 -1
  234. package/dist/parser/setup-status.d.ts.map +1 -1
  235. package/dist/parser/setup-status.js +104 -39
  236. package/dist/parser/setup-status.js.map +1 -1
  237. package/dist/parser/shadow-sync-scheduler.d.ts +71 -0
  238. package/dist/parser/shadow-sync-scheduler.d.ts.map +1 -0
  239. package/dist/parser/shadow-sync-scheduler.js +139 -0
  240. package/dist/parser/shadow-sync-scheduler.js.map +1 -0
  241. package/dist/parser/shadow.d.ts +121 -14
  242. package/dist/parser/shadow.d.ts.map +1 -1
  243. package/dist/parser/shadow.js +752 -27
  244. package/dist/parser/shadow.js.map +1 -1
  245. package/dist/parser/skill-render.d.ts +24 -0
  246. package/dist/parser/skill-render.d.ts.map +1 -1
  247. package/dist/parser/skill-render.js +98 -26
  248. package/dist/parser/skill-render.js.map +1 -1
  249. package/dist/parser/validate.d.ts +43 -3
  250. package/dist/parser/validate.d.ts.map +1 -1
  251. package/dist/parser/validate.js +204 -30
  252. package/dist/parser/validate.js.map +1 -1
  253. package/dist/parser/yaml.d.ts +47 -11
  254. package/dist/parser/yaml.d.ts.map +1 -1
  255. package/dist/parser/yaml.js +329 -149
  256. package/dist/parser/yaml.js.map +1 -1
  257. package/dist/review/checks.d.ts +97 -0
  258. package/dist/review/checks.d.ts.map +1 -0
  259. package/dist/review/checks.js +175 -0
  260. package/dist/review/checks.js.map +1 -0
  261. package/dist/review/index.d.ts +3 -0
  262. package/dist/review/index.d.ts.map +1 -0
  263. package/dist/review/index.js +3 -0
  264. package/dist/review/index.js.map +1 -0
  265. package/dist/review/subject-bindings.d.ts +83 -0
  266. package/dist/review/subject-bindings.d.ts.map +1 -0
  267. package/dist/review/subject-bindings.js +175 -0
  268. package/dist/review/subject-bindings.js.map +1 -0
  269. package/dist/schema/common.d.ts +26 -0
  270. package/dist/schema/common.d.ts.map +1 -1
  271. package/dist/schema/common.js +13 -0
  272. package/dist/schema/common.js.map +1 -1
  273. package/dist/schema/dispatch-workspace.d.ts +2643 -0
  274. package/dist/schema/dispatch-workspace.d.ts.map +1 -0
  275. package/dist/schema/dispatch-workspace.js +187 -0
  276. package/dist/schema/dispatch-workspace.js.map +1 -0
  277. package/dist/schema/inbox.d.ts +8 -8
  278. package/dist/schema/index.d.ts +2 -0
  279. package/dist/schema/index.d.ts.map +1 -1
  280. package/dist/schema/index.js +2 -0
  281. package/dist/schema/index.js.map +1 -1
  282. package/dist/schema/meta.d.ts +648 -116
  283. package/dist/schema/meta.d.ts.map +1 -1
  284. package/dist/schema/meta.js +27 -0
  285. package/dist/schema/meta.js.map +1 -1
  286. package/dist/schema/plan.d.ts +30 -19
  287. package/dist/schema/plan.d.ts.map +1 -1
  288. package/dist/schema/plan.js +3 -1
  289. package/dist/schema/plan.js.map +1 -1
  290. package/dist/schema/review-records.d.ts +2676 -0
  291. package/dist/schema/review-records.d.ts.map +1 -0
  292. package/dist/schema/review-records.js +232 -0
  293. package/dist/schema/review-records.js.map +1 -0
  294. package/dist/schema/spec.d.ts +32 -14
  295. package/dist/schema/spec.d.ts.map +1 -1
  296. package/dist/schema/spec.js +5 -0
  297. package/dist/schema/spec.js.map +1 -1
  298. package/dist/schema/task.d.ts +187 -29
  299. package/dist/schema/task.d.ts.map +1 -1
  300. package/dist/schema/task.js +12 -2
  301. package/dist/schema/task.js.map +1 -1
  302. package/dist/schema/triage.d.ts +22 -22
  303. package/dist/sessions/cache.d.ts +119 -0
  304. package/dist/sessions/cache.d.ts.map +1 -0
  305. package/dist/sessions/cache.js +284 -0
  306. package/dist/sessions/cache.js.map +1 -0
  307. package/dist/sessions/index.d.ts +1 -0
  308. package/dist/sessions/index.d.ts.map +1 -1
  309. package/dist/sessions/index.js +2 -0
  310. package/dist/sessions/index.js.map +1 -1
  311. package/dist/sessions/legacy.d.ts +77 -0
  312. package/dist/sessions/legacy.d.ts.map +1 -0
  313. package/dist/sessions/legacy.js +146 -0
  314. package/dist/sessions/legacy.js.map +1 -0
  315. package/dist/sessions/store.d.ts +103 -73
  316. package/dist/sessions/store.d.ts.map +1 -1
  317. package/dist/sessions/store.js +335 -186
  318. package/dist/sessions/store.js.map +1 -1
  319. package/dist/sessions/types.d.ts +44 -16
  320. package/dist/sessions/types.d.ts.map +1 -1
  321. package/dist/sessions/types.js +11 -2
  322. package/dist/sessions/types.js.map +1 -1
  323. package/dist/strings/errors.d.ts +32 -0
  324. package/dist/strings/errors.d.ts.map +1 -1
  325. package/dist/strings/errors.js +17 -0
  326. package/dist/strings/errors.js.map +1 -1
  327. package/dist/strings/labels.d.ts +1 -0
  328. package/dist/strings/labels.d.ts.map +1 -1
  329. package/dist/strings/labels.js +1 -0
  330. package/dist/strings/labels.js.map +1 -1
  331. package/dist/utils/activity.d.ts +101 -0
  332. package/dist/utils/activity.d.ts.map +1 -0
  333. package/dist/utils/activity.js +408 -0
  334. package/dist/utils/activity.js.map +1 -0
  335. package/dist/utils/git.d.ts +31 -0
  336. package/dist/utils/git.d.ts.map +1 -1
  337. package/dist/utils/git.js +87 -0
  338. package/dist/utils/git.js.map +1 -1
  339. package/dist/utils/index.d.ts +2 -0
  340. package/dist/utils/index.d.ts.map +1 -1
  341. package/dist/utils/index.js +1 -0
  342. package/dist/utils/index.js.map +1 -1
  343. package/dist/web-ui/_app/immutable/assets/0.tmlwn-Ih.css +1 -0
  344. package/dist/web-ui/_app/immutable/assets/9.BwwJybWx.css +1 -0
  345. package/dist/web-ui/_app/immutable/chunks/2KqE8gtn.js +1 -0
  346. package/dist/web-ui/_app/immutable/chunks/70-t_QvE.js +1 -0
  347. package/dist/web-ui/_app/immutable/chunks/AiWQj974.js +1 -0
  348. package/dist/web-ui/_app/immutable/chunks/{CPPfDSei.js → B25nWFyA.js} +4 -4
  349. package/dist/web-ui/_app/immutable/chunks/{DBYE9jOd.js → B2bcA_Q_.js} +1 -1
  350. package/dist/web-ui/_app/immutable/chunks/B5e5HYyB.js +1 -0
  351. package/dist/web-ui/_app/immutable/chunks/B7-5z6eA.js +1 -0
  352. package/dist/web-ui/_app/immutable/chunks/B7bGmhK0.js +1 -0
  353. package/dist/web-ui/_app/immutable/chunks/{DzO4hlg9.js → B8tYZKAE.js} +1 -1
  354. package/dist/web-ui/_app/immutable/chunks/{B5LJFxqa.js → BFGAyJjD.js} +1 -1
  355. package/dist/web-ui/_app/immutable/chunks/BG0850zf.js +1 -0
  356. package/dist/web-ui/_app/immutable/chunks/{DAMmvwn4.js → BG8eSzAd.js} +1 -1
  357. package/dist/web-ui/_app/immutable/chunks/BIMxXS8I.js +1 -0
  358. package/dist/web-ui/_app/immutable/chunks/BSzL1fpU.js +1 -0
  359. package/dist/web-ui/_app/immutable/chunks/BYtjHfeq.js +1 -0
  360. package/dist/web-ui/_app/immutable/chunks/{DxCk-KHc.js → Bp5pFYXL.js} +1 -1
  361. package/dist/web-ui/_app/immutable/chunks/{B8a0xDxR.js → BsJFsuAT.js} +1 -1
  362. package/dist/web-ui/_app/immutable/chunks/BvpNHcD6.js +1 -0
  363. package/dist/web-ui/_app/immutable/chunks/BypqA25-.js +1 -0
  364. package/dist/web-ui/_app/immutable/chunks/{BVA9Exy-.js → C0w6WDm5.js} +1 -1
  365. package/dist/web-ui/_app/immutable/chunks/C5_PAZ0y.js +1 -0
  366. package/dist/web-ui/_app/immutable/chunks/CDRO15Iv.js +1 -0
  367. package/dist/web-ui/_app/immutable/chunks/CF1CoqD5.js +1 -0
  368. package/dist/web-ui/_app/immutable/chunks/CS2sa4_m.js +1 -0
  369. package/dist/web-ui/_app/immutable/chunks/{BJ0JX3ea.js → CWUQwB9H.js} +1 -1
  370. package/dist/web-ui/_app/immutable/chunks/CY5FDdSU.js +1 -0
  371. package/dist/web-ui/_app/immutable/chunks/C_7MTDoj.js +1 -0
  372. package/dist/web-ui/_app/immutable/chunks/{D3vxvonu.js → CaAJD3dl.js} +1 -1
  373. package/dist/web-ui/_app/immutable/chunks/{BP352uRn.js → ChB5iyEL.js} +1 -1
  374. package/dist/web-ui/_app/immutable/chunks/{pE6cYWlS.js → ChQD-6N8.js} +1 -1
  375. package/dist/web-ui/_app/immutable/chunks/{Eo4gF7ih.js → CqbsoCwA.js} +1 -1
  376. package/dist/web-ui/_app/immutable/chunks/DCeJW50p.js +1 -0
  377. package/dist/web-ui/_app/immutable/chunks/{Cncwi6fQ.js → DJtZNgcs.js} +1 -1
  378. package/dist/web-ui/_app/immutable/chunks/DKIeaprD.js +1 -0
  379. package/dist/web-ui/_app/immutable/chunks/DLd2uVIA.js +1 -0
  380. package/dist/web-ui/_app/immutable/chunks/{DjcCz-PU.js → DW_subyT.js} +2 -2
  381. package/dist/web-ui/_app/immutable/chunks/DbU6lVn0.js +1 -0
  382. package/dist/web-ui/_app/immutable/chunks/Dc7ZCC5m.js +1 -0
  383. package/dist/web-ui/_app/immutable/chunks/Dd5umPsk.js +2 -0
  384. package/dist/web-ui/_app/immutable/chunks/{BysXJlZb.js → Dg_zDpDS.js} +1 -1
  385. package/dist/web-ui/_app/immutable/chunks/Dgqu8Yuc.js +1 -0
  386. package/dist/web-ui/_app/immutable/chunks/DmxsPZTB.js +1 -0
  387. package/dist/web-ui/_app/immutable/chunks/DphTaFUB.js +1 -0
  388. package/dist/web-ui/_app/immutable/chunks/DqK4iHp0.js +1 -0
  389. package/dist/web-ui/_app/immutable/chunks/{D9QNBZM2.js → DqT6OH_u.js} +2 -2
  390. package/dist/web-ui/_app/immutable/chunks/Ds9I9wQb.js +1 -0
  391. package/dist/web-ui/_app/immutable/chunks/Du5ng3u4.js +1 -0
  392. package/dist/web-ui/_app/immutable/chunks/DxJw79Wi.js +1 -0
  393. package/dist/web-ui/_app/immutable/chunks/GFTX8GgV.js +1 -0
  394. package/dist/web-ui/_app/immutable/chunks/{C076q4JN.js → HNjs76Zz.js} +1 -1
  395. package/dist/web-ui/_app/immutable/chunks/HVMjDi4_.js +1 -0
  396. package/dist/web-ui/_app/immutable/chunks/{BkOJ8DkV.js → P0A_fJvS.js} +1 -1
  397. package/dist/web-ui/_app/immutable/chunks/T3vGWjIL.js +1 -0
  398. package/dist/web-ui/_app/immutable/chunks/VTmrX9Qu.js +1 -0
  399. package/dist/web-ui/_app/immutable/chunks/{k_Qegko0.js → Xvwhx_F1.js} +1 -1
  400. package/dist/web-ui/_app/immutable/chunks/Yyz1XMQA.js +1 -0
  401. package/dist/web-ui/_app/immutable/chunks/{62JVKtnb.js → dh5HeqUr.js} +1 -1
  402. package/dist/web-ui/_app/immutable/chunks/fZMteyca.js +62 -0
  403. package/dist/web-ui/_app/immutable/chunks/{D82RulSH.js → gPrj-hqC.js} +1 -1
  404. package/dist/web-ui/_app/immutable/chunks/htcWMiYN.js +1 -0
  405. package/dist/web-ui/_app/immutable/chunks/{CwELQvbx.js → oTsvd9y4.js} +1 -1
  406. package/dist/web-ui/_app/immutable/chunks/qJfLUwU4.js +1 -0
  407. package/dist/web-ui/_app/immutable/chunks/xCtiO_JE.js +1 -0
  408. package/dist/web-ui/_app/immutable/chunks/{DvA-KON-.js → y4GeEH6k.js} +1 -1
  409. package/dist/web-ui/_app/immutable/entry/app.C4h_eOn6.js +2 -0
  410. package/dist/web-ui/_app/immutable/entry/start.CQFTf9ep.js +1 -0
  411. package/dist/web-ui/_app/immutable/nodes/0.Dh1xO970.js +1 -0
  412. package/dist/web-ui/_app/immutable/nodes/1.l75D3Opx.js +1 -0
  413. package/dist/web-ui/_app/immutable/nodes/10.DBidBPc-.js +1 -0
  414. package/dist/web-ui/_app/immutable/nodes/11.Ab0gUKWe.js +1 -0
  415. package/dist/web-ui/_app/immutable/nodes/12.CMsnoxfs.js +1 -0
  416. package/dist/web-ui/_app/immutable/nodes/13.D8YKuknB.js +1 -0
  417. package/dist/web-ui/_app/immutable/nodes/14.DZ0aan7y.js +1 -0
  418. package/dist/web-ui/_app/immutable/nodes/15.CUIKreDL.js +2 -0
  419. package/dist/web-ui/_app/immutable/nodes/16.BWc8--BO.js +1 -0
  420. package/dist/web-ui/_app/immutable/nodes/2.CDUonbuh.js +1 -0
  421. package/dist/web-ui/_app/immutable/nodes/3.Ctg3M00i.js +1 -0
  422. package/dist/web-ui/_app/immutable/nodes/4.Ci-JDwbA.js +2 -0
  423. package/dist/web-ui/_app/immutable/nodes/5.CTyEDAq0.js +1 -0
  424. package/dist/web-ui/_app/immutable/nodes/6.BTZZqsAb.js +1 -0
  425. package/dist/web-ui/_app/immutable/nodes/7.BI52g_Jo.js +137 -0
  426. package/dist/web-ui/_app/immutable/nodes/8.3hZPaB9x.js +1 -0
  427. package/dist/web-ui/_app/immutable/nodes/9.DS49kvwl.js +29 -0
  428. package/dist/web-ui/_app/version.json +1 -1
  429. package/dist/web-ui/favicon-192.png +0 -0
  430. package/dist/web-ui/favicon-32.png +0 -0
  431. package/dist/web-ui/favicon.ico +0 -0
  432. package/dist/web-ui/index.html +14 -14
  433. package/package.json +12 -6
  434. package/plugin/.claude-plugin/marketplace.json +1 -1
  435. package/plugin/.claude-plugin/plugin.json +1 -1
  436. package/plugin/plugins/kspec/skills/merge/SKILL.md +127 -0
  437. package/plugin/plugins/kspec/skills/plan/SKILL.md +55 -26
  438. package/plugin/plugins/kspec/skills/review/SKILL.md +350 -133
  439. package/plugin/plugins/kspec/skills/task-work/SKILL.md +96 -106
  440. package/templates/agents-sections/04-pr-workflow.md +15 -12
  441. package/templates/agents-sections/06-ralph-loop.md +15 -10
  442. package/templates/skills/manifest.yaml +25 -7
  443. package/templates/skills/merge/SKILL.md +120 -0
  444. package/templates/skills/plan/SKILL.md +55 -26
  445. package/templates/skills/review/SKILL.md +346 -130
  446. package/templates/skills/task-work/SKILL.md +93 -103
  447. package/dist/web-ui/_app/immutable/assets/0.BJaYkGW2.css +0 -1
  448. package/dist/web-ui/_app/immutable/assets/9.SzGLxi4x.css +0 -1
  449. package/dist/web-ui/_app/immutable/chunks/-lc0BifF.js +0 -1
  450. package/dist/web-ui/_app/immutable/chunks/8RBjHMN1.js +0 -1
  451. package/dist/web-ui/_app/immutable/chunks/B5wTVqxm.js +0 -1
  452. package/dist/web-ui/_app/immutable/chunks/B6VSmczZ.js +0 -1
  453. package/dist/web-ui/_app/immutable/chunks/BEOQc37C.js +0 -1
  454. package/dist/web-ui/_app/immutable/chunks/BHtYorjv.js +0 -1
  455. package/dist/web-ui/_app/immutable/chunks/BMuCqDX8.js +0 -1
  456. package/dist/web-ui/_app/immutable/chunks/BUZujXJ2.js +0 -1
  457. package/dist/web-ui/_app/immutable/chunks/BWET-efb.js +0 -1
  458. package/dist/web-ui/_app/immutable/chunks/BXkNecpt.js +0 -1
  459. package/dist/web-ui/_app/immutable/chunks/BYzrIfX8.js +0 -1
  460. package/dist/web-ui/_app/immutable/chunks/BpuwufMc.js +0 -1
  461. package/dist/web-ui/_app/immutable/chunks/BwMO4RrG.js +0 -1
  462. package/dist/web-ui/_app/immutable/chunks/C33JaVbg.js +0 -1
  463. package/dist/web-ui/_app/immutable/chunks/CGtqifKp.js +0 -1
  464. package/dist/web-ui/_app/immutable/chunks/CHDZZ7OG.js +0 -1
  465. package/dist/web-ui/_app/immutable/chunks/CUir3f4J.js +0 -60
  466. package/dist/web-ui/_app/immutable/chunks/CrCIbn0C.js +0 -1
  467. package/dist/web-ui/_app/immutable/chunks/D6TVmR9T.js +0 -1
  468. package/dist/web-ui/_app/immutable/chunks/D7LTux4W.js +0 -1
  469. package/dist/web-ui/_app/immutable/chunks/DAh4Wfku.js +0 -1
  470. package/dist/web-ui/_app/immutable/chunks/DAx07bEQ.js +0 -1
  471. package/dist/web-ui/_app/immutable/chunks/DOno4cA2.js +0 -1
  472. package/dist/web-ui/_app/immutable/chunks/DQA8NZIH.js +0 -2
  473. package/dist/web-ui/_app/immutable/chunks/DRfPm2bo.js +0 -1
  474. package/dist/web-ui/_app/immutable/chunks/DhQhksaB.js +0 -1
  475. package/dist/web-ui/_app/immutable/chunks/DjG7s6hm.js +0 -1
  476. package/dist/web-ui/_app/immutable/chunks/DkltRNvh.js +0 -1
  477. package/dist/web-ui/_app/immutable/chunks/DlaTnPKL.js +0 -1
  478. package/dist/web-ui/_app/immutable/chunks/ExCq5swK.js +0 -1
  479. package/dist/web-ui/_app/immutable/chunks/T3zZGv51.js +0 -1
  480. package/dist/web-ui/_app/immutable/chunks/XZumBYeP.js +0 -1
  481. package/dist/web-ui/_app/immutable/chunks/_ySfNjkF.js +0 -1
  482. package/dist/web-ui/_app/immutable/chunks/iEtR5cV6.js +0 -1
  483. package/dist/web-ui/_app/immutable/entry/app.Cgu6uKeS.js +0 -2
  484. package/dist/web-ui/_app/immutable/entry/start.9XifnLoB.js +0 -1
  485. package/dist/web-ui/_app/immutable/nodes/0.DISwcKSK.js +0 -1
  486. package/dist/web-ui/_app/immutable/nodes/1.Cx2Ufqp1.js +0 -1
  487. package/dist/web-ui/_app/immutable/nodes/10.C3z8ijXL.js +0 -1
  488. package/dist/web-ui/_app/immutable/nodes/11.DZdIjZmM.js +0 -1
  489. package/dist/web-ui/_app/immutable/nodes/12.FsIGfAOa.js +0 -1
  490. package/dist/web-ui/_app/immutable/nodes/13.DZoFwagf.js +0 -1
  491. package/dist/web-ui/_app/immutable/nodes/14.DaIzDKbQ.js +0 -1
  492. package/dist/web-ui/_app/immutable/nodes/15.BYyt4XWF.js +0 -2
  493. package/dist/web-ui/_app/immutable/nodes/16.CQkSqpOe.js +0 -1
  494. package/dist/web-ui/_app/immutable/nodes/2.Bkf_j2UJ.js +0 -1
  495. package/dist/web-ui/_app/immutable/nodes/3.kaMCurJG.js +0 -1
  496. package/dist/web-ui/_app/immutable/nodes/4.BSsFPTHG.js +0 -2
  497. package/dist/web-ui/_app/immutable/nodes/5.CpPlcCEZ.js +0 -1
  498. package/dist/web-ui/_app/immutable/nodes/6.BN4FqQmY.js +0 -1
  499. package/dist/web-ui/_app/immutable/nodes/7.9kBYIZik.js +0 -1
  500. package/dist/web-ui/_app/immutable/nodes/8.BuijtZ6B.js +0 -1
  501. package/dist/web-ui/_app/immutable/nodes/9.C-Weba8R.js +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-validation.d.ts","sourceRoot":"","sources":["../../src/parser/review-validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAG3D;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,qBAAqB,EAAE,CAAC;CACjC;AAsDD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,MAAM,CAAC,EAAE,MAAM,GACd,sBAAsB,CAoBxB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,OAAO,EACb,MAAM,CAAC,EAAE,MAAM,GACd,sBAAsB,CAoBxB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,qBAAqB,EAAE,CAAC,CA2DlC;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsBpE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,OAAO,EACb,MAAM,CAAC,EAAE,MAAM,GACd;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,6BAA6B,EAAE,YAAY,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,qBAAqB,EAAE,CAAA;CAAE,CAOzH;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,MAAM,CAAC,EAAE,MAAM,GACd;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,6BAA6B,EAAE,iBAAiB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,qBAAqB,EAAE,CAAA;CAAE,CAM9H"}
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Validation module for review records.
3
+ *
4
+ * Provides schema validation for review records, threads, checks, verdicts,
5
+ * events, and subject bindings. Used during parsing, persistence, and
6
+ * command mutation to ensure review data integrity.
7
+ *
8
+ * AC: @review-record-validation ac-1, ac-2
9
+ */
10
+ import * as path from "node:path";
11
+ import { ReviewRecordSchema, ReviewRecordsFileSchema, ReviewRecordInputSchema, } from "../schema/review-records.js";
12
+ import { readYamlFile } from "./yaml.js";
13
+ /**
14
+ * Provide actionable guidance for common review validation failures.
15
+ *
16
+ * AC: @review-record-validation ac-2
17
+ */
18
+ function formatActionableMessage(fieldPath, message) {
19
+ // Subject type discrimination errors
20
+ if (fieldPath.includes("subject") && message.includes("discriminator")) {
21
+ return `${message}. Subject type must be one of: code, plan, task, spec, external`;
22
+ }
23
+ // Subject version discrimination errors
24
+ if (fieldPath.includes("applies_to_version") && message.includes("discriminator")) {
25
+ return `${message}. Version type must be one of: code_compare, entity_version`;
26
+ }
27
+ // Anchor type discrimination errors
28
+ if (fieldPath.includes("anchor") && message.includes("discriminator")) {
29
+ return `${message}. Anchor type must be one of: code, structured`;
30
+ }
31
+ // Missing required title
32
+ if (fieldPath.endsWith("title") && message.includes("too_small")) {
33
+ return "Title is required and must be non-empty";
34
+ }
35
+ // Invalid URL
36
+ if (message.includes("Invalid url")) {
37
+ return `${message}. Provide a valid URL (e.g., https://example.com)`;
38
+ }
39
+ // Invalid ULID
40
+ if (fieldPath.endsWith("_ulid") && (message.includes("String must contain") || message.includes("Invalid"))) {
41
+ return `${message}. ULIDs must be exactly 26 uppercase alphanumeric characters (Crockford base32)`;
42
+ }
43
+ // Invalid enum value
44
+ if (message.includes("Invalid enum value")) {
45
+ return message;
46
+ }
47
+ // Invalid datetime
48
+ if (message.includes("Invalid datetime")) {
49
+ return `${message}. Use ISO 8601 format (e.g., 2026-03-14T00:00:00.000Z)`;
50
+ }
51
+ return message;
52
+ }
53
+ /**
54
+ * Validate a single review record against the full ReviewRecordSchema.
55
+ * Use this when validating persisted or loaded review records.
56
+ *
57
+ * AC: @review-record-validation ac-1
58
+ */
59
+ export function validateReviewRecord(data, source) {
60
+ const errors = [];
61
+ const file = source ?? "review-record";
62
+ const result = ReviewRecordSchema.safeParse(data);
63
+ if (!result.success) {
64
+ for (const issue of result.error.issues) {
65
+ errors.push({
66
+ file,
67
+ path: issue.path.join("."),
68
+ message: formatActionableMessage(issue.path.join("."), issue.message),
69
+ details: issue,
70
+ });
71
+ }
72
+ }
73
+ return { valid: errors.length === 0, errors };
74
+ }
75
+ /**
76
+ * Validate review record input (for creating new reviews).
77
+ * Uses ReviewRecordInputSchema which has relaxed requirements.
78
+ *
79
+ * AC: @review-record-validation ac-1, ac-2
80
+ */
81
+ export function validateReviewRecordInput(data, source) {
82
+ const errors = [];
83
+ const file = source ?? "review-record-input";
84
+ const result = ReviewRecordInputSchema.safeParse(data);
85
+ if (!result.success) {
86
+ for (const issue of result.error.issues) {
87
+ errors.push({
88
+ file,
89
+ path: issue.path.join("."),
90
+ message: formatActionableMessage(issue.path.join("."), issue.message),
91
+ details: issue,
92
+ });
93
+ }
94
+ }
95
+ return { valid: errors.length === 0, errors };
96
+ }
97
+ /**
98
+ * Validate a reviews YAML file (project.reviews.yaml).
99
+ * Validates the file-level schema and each individual review record.
100
+ *
101
+ * AC: @review-record-validation ac-1, ac-2
102
+ */
103
+ export async function validateReviewsFile(filePath) {
104
+ const errors = [];
105
+ try {
106
+ const raw = await readYamlFile(filePath);
107
+ if (!raw || typeof raw !== "object") {
108
+ errors.push({
109
+ file: filePath,
110
+ message: "Invalid reviews file format: expected an object with { kynetic_reviews, reviews }",
111
+ });
112
+ return errors;
113
+ }
114
+ // Validate the full file schema
115
+ const fileResult = ReviewRecordsFileSchema.safeParse(raw);
116
+ if (!fileResult.success) {
117
+ // Try to give per-review errors for better diagnostics
118
+ const rawObj = raw;
119
+ if (Array.isArray(rawObj.reviews)) {
120
+ for (let i = 0; i < rawObj.reviews.length; i++) {
121
+ const reviewResult = ReviewRecordSchema.safeParse(rawObj.reviews[i]);
122
+ if (!reviewResult.success) {
123
+ for (const issue of reviewResult.error.issues) {
124
+ const fieldPath = `reviews[${i}].${issue.path.join(".")}`;
125
+ errors.push({
126
+ file: filePath,
127
+ path: fieldPath,
128
+ message: formatActionableMessage(fieldPath, issue.message),
129
+ details: issue,
130
+ });
131
+ }
132
+ }
133
+ }
134
+ }
135
+ // If no per-review errors were found, report file-level errors
136
+ if (errors.length === 0) {
137
+ for (const issue of fileResult.error.issues) {
138
+ errors.push({
139
+ file: filePath,
140
+ path: issue.path.join("."),
141
+ message: formatActionableMessage(issue.path.join("."), issue.message),
142
+ details: issue,
143
+ });
144
+ }
145
+ }
146
+ }
147
+ }
148
+ catch (err) {
149
+ errors.push({
150
+ file: filePath,
151
+ message: `Failed to parse reviews YAML: ${err instanceof Error ? err.message : String(err)}`,
152
+ });
153
+ }
154
+ return errors;
155
+ }
156
+ /**
157
+ * Find review files in a directory (files matching *.reviews.yaml).
158
+ */
159
+ export async function findReviewFiles(dir) {
160
+ const files = [];
161
+ try {
162
+ const { readdir } = await import("node:fs/promises");
163
+ const entries = await readdir(dir, { withFileTypes: true });
164
+ for (const entry of entries) {
165
+ const fullPath = path.join(dir, entry.name);
166
+ if (entry.isDirectory()) {
167
+ const subFiles = await findReviewFiles(fullPath);
168
+ files.push(...subFiles);
169
+ }
170
+ else if (entry.isFile() && entry.name.endsWith(".reviews.yaml")) {
171
+ files.push(fullPath);
172
+ }
173
+ }
174
+ }
175
+ catch {
176
+ // Directory doesn't exist or not readable
177
+ }
178
+ return files;
179
+ }
180
+ /**
181
+ * Convenience: parse and validate a review record, returning the typed
182
+ * result on success or errors on failure.
183
+ *
184
+ * AC: @review-record-validation ac-1, ac-2
185
+ */
186
+ export function parseReviewRecord(data, source) {
187
+ const result = validateReviewRecord(data, source);
188
+ if (!result.valid) {
189
+ return { ok: false, errors: result.errors };
190
+ }
191
+ // Safe to parse — validation already passed
192
+ return { ok: true, data: ReviewRecordSchema.parse(data) };
193
+ }
194
+ /**
195
+ * Convenience: parse and validate review record input, returning the typed
196
+ * result on success or errors on failure.
197
+ *
198
+ * AC: @review-record-validation ac-1, ac-2
199
+ */
200
+ export function parseReviewRecordInput(data, source) {
201
+ const result = validateReviewRecordInput(data, source);
202
+ if (!result.valid) {
203
+ return { ok: false, errors: result.errors };
204
+ }
205
+ return { ok: true, data: ReviewRecordInputSchema.parse(data) };
206
+ }
207
+ //# sourceMappingURL=review-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-validation.js","sourceRoot":"","sources":["../../src/parser/review-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Review record loading and operations.
3
+ *
4
+ * Review records are first-party top-level entities stored in
5
+ * project.reviews.yaml with stable ULID-backed identity.
6
+ *
7
+ * AC: @review-record-storage-and-identity ac-1 - Dedicated first-party review storage
8
+ * AC: @review-record-storage-and-identity ac-3 - Single dedicated file per project
9
+ */
10
+ import { type ReviewRecord, type ReviewRecordInput } from "../schema/index.js";
11
+ import type { KspecContext } from "./yaml.js";
12
+ /**
13
+ * Loaded review record with runtime metadata.
14
+ * AC: @review-record-storage-and-identity ac-2 - ULID-backed identity
15
+ */
16
+ export interface LoadedReviewRecord extends ReviewRecord {
17
+ _sourceFile?: string;
18
+ }
19
+ /**
20
+ * Get the reviews file path.
21
+ * AC: @review-record-storage-and-identity ac-3 - single dedicated file per project
22
+ */
23
+ export declare function getReviewsFilePath(ctx: KspecContext): string;
24
+ /**
25
+ * Load all review records from the project.
26
+ * AC: @review-record-storage-and-identity ac-1 - dedicated first-party review storage
27
+ * AC: @review-record-storage-and-identity ac-3 - single dedicated file per project
28
+ */
29
+ export declare function loadReviewRecords(ctx: KspecContext): Promise<LoadedReviewRecord[]>;
30
+ /**
31
+ * Find a review record by reference (ULID, short ULID, or slug).
32
+ * AC: @review-record-storage-and-identity ac-2 - addressable by @review ref
33
+ */
34
+ export declare function findReviewByRef(reviews: LoadedReviewRecord[], ref: string): LoadedReviewRecord | undefined;
35
+ /**
36
+ * Create a new review record from input.
37
+ * AC: @review-record-storage-and-identity ac-2 - ULID-backed identity
38
+ */
39
+ export declare function createReviewRecord(input: ReviewRecordInput): ReviewRecord;
40
+ /**
41
+ * Save a single review record (create or update).
42
+ * AC: @review-record-storage-and-identity ac-1 - dedicated first-party review storage
43
+ * AC: @review-record-storage-and-identity ac-3 - single dedicated file per project
44
+ * Uses file lock to prevent TOCTOU race on concurrent writes.
45
+ */
46
+ export declare function saveReviewRecord(ctx: KspecContext, review: LoadedReviewRecord): Promise<void>;
47
+ /**
48
+ * Atomically mutate a review record using the latest on-disk state.
49
+ *
50
+ * The callback receives the current review value while holding the file lock,
51
+ * so concurrent writers do not clobber unrelated fields.
52
+ */
53
+ export declare function mutateReviewAtomically(ctx: KspecContext, review: LoadedReviewRecord, mutate: (latestReview: LoadedReviewRecord) => ReviewRecord | LoadedReviewRecord | Promise<ReviewRecord | LoadedReviewRecord>): Promise<LoadedReviewRecord>;
54
+ /**
55
+ * Delete a review record by ULID.
56
+ */
57
+ export declare function deleteReviewRecord(ctx: KspecContext, reviewUlid: string): Promise<boolean>;
58
+ //# sourceMappingURL=reviews.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviews.d.ts","sourceRoot":"","sources":["../../src/parser/reviews.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAIvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG9C;;;GAGG;AACH,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAE5D;AAmDD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAa/B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,kBAAkB,EAAE,EAC7B,GAAG,EAAE,MAAM,GACV,kBAAkB,GAAG,SAAS,CAYhC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAqBzE;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,CACN,YAAY,EAAE,kBAAkB,KAC7B,YAAY,GAAG,kBAAkB,GAAG,OAAO,CAAC,YAAY,GAAG,kBAAkB,CAAC,GAClF,OAAO,CAAC,kBAAkB,CAAC,CAiD7B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,YAAY,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CAyBlB"}
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Review record loading and operations.
3
+ *
4
+ * Review records are first-party top-level entities stored in
5
+ * project.reviews.yaml with stable ULID-backed identity.
6
+ *
7
+ * AC: @review-record-storage-and-identity ac-1 - Dedicated first-party review storage
8
+ * AC: @review-record-storage-and-identity ac-3 - Single dedicated file per project
9
+ */
10
+ import * as fs from "node:fs/promises";
11
+ import * as path from "node:path";
12
+ import { ulid } from "ulid";
13
+ import { withFileLock } from "./file-lock.js";
14
+ import { ReviewRecordSchema, ReviewRecordsFileSchema, } from "../schema/index.js";
15
+ import { readYamlFile, writeYamlFilePreserveFormat } from "./yaml.js";
16
+ /**
17
+ * Get the reviews file path.
18
+ * AC: @review-record-storage-and-identity ac-3 - single dedicated file per project
19
+ */
20
+ export function getReviewsFilePath(ctx) {
21
+ return path.join(ctx.specDir, "project.reviews.yaml");
22
+ }
23
+ /**
24
+ * Parse review records from raw YAML payload.
25
+ *
26
+ * Supports the canonical { kynetic_reviews, reviews } shape and a fallback
27
+ * { reviews } shape for older files without version metadata.
28
+ */
29
+ function parseReviewsFromRaw(raw) {
30
+ const parsed = ReviewRecordsFileSchema.safeParse(raw);
31
+ if (parsed.success) {
32
+ return parsed.data.reviews;
33
+ }
34
+ if (raw && typeof raw === "object" && "reviews" in raw) {
35
+ const fallbackReviews = raw.reviews;
36
+ if (Array.isArray(fallbackReviews)) {
37
+ const reviews = [];
38
+ for (const review of fallbackReviews) {
39
+ const reviewResult = ReviewRecordSchema.safeParse(review);
40
+ if (reviewResult.success) {
41
+ reviews.push(reviewResult.data);
42
+ }
43
+ }
44
+ return reviews;
45
+ }
46
+ }
47
+ return [];
48
+ }
49
+ /**
50
+ * Load review records from an explicit file path.
51
+ */
52
+ async function loadReviewsFromFile(reviewsPath) {
53
+ const raw = await readYamlFile(reviewsPath);
54
+ return parseReviewsFromRaw(raw);
55
+ }
56
+ /**
57
+ * Strip runtime metadata before serialization.
58
+ */
59
+ function stripReviewMetadata(review) {
60
+ const { _sourceFile, ...cleanReview } = review;
61
+ return cleanReview;
62
+ }
63
+ /**
64
+ * Load all review records from the project.
65
+ * AC: @review-record-storage-and-identity ac-1 - dedicated first-party review storage
66
+ * AC: @review-record-storage-and-identity ac-3 - single dedicated file per project
67
+ */
68
+ export async function loadReviewRecords(ctx) {
69
+ const reviewsPath = getReviewsFilePath(ctx);
70
+ try {
71
+ const reviews = await loadReviewsFromFile(reviewsPath);
72
+ return reviews.map((review) => ({
73
+ ...review,
74
+ _sourceFile: reviewsPath,
75
+ }));
76
+ }
77
+ catch {
78
+ // File doesn't exist or parse error
79
+ return [];
80
+ }
81
+ }
82
+ /**
83
+ * Find a review record by reference (ULID, short ULID, or slug).
84
+ * AC: @review-record-storage-and-identity ac-2 - addressable by @review ref
85
+ */
86
+ export function findReviewByRef(reviews, ref) {
87
+ const cleanRef = ref.startsWith("@") ? ref.slice(1) : ref;
88
+ return reviews.find((r) =>
89
+ // Match full ULID
90
+ r._ulid === cleanRef ||
91
+ // Match short ULID (prefix)
92
+ r._ulid.toLowerCase().startsWith(cleanRef.toLowerCase()) ||
93
+ // Match any slug
94
+ r.slugs.includes(cleanRef));
95
+ }
96
+ /**
97
+ * Create a new review record from input.
98
+ * AC: @review-record-storage-and-identity ac-2 - ULID-backed identity
99
+ */
100
+ export function createReviewRecord(input) {
101
+ const now = new Date().toISOString();
102
+ return {
103
+ _ulid: input._ulid ?? ulid(),
104
+ slugs: input.slugs ?? [],
105
+ title: input.title,
106
+ lifecycle_state: input.lifecycle_state ?? "draft",
107
+ subject: input.subject,
108
+ author: input.author,
109
+ related_refs: input.related_refs ?? [],
110
+ threads: input.threads ?? [],
111
+ checks: input.checks ?? [],
112
+ verdicts: input.verdicts ?? [],
113
+ events: input.events ?? [],
114
+ notes: input.notes ?? [],
115
+ external_links: input.external_links ?? [],
116
+ examined_commit: input.examined_commit ?? null,
117
+ created_at: input.created_at ?? now,
118
+ updated_at: input.updated_at ?? null,
119
+ };
120
+ }
121
+ /**
122
+ * Save a single review record (create or update).
123
+ * AC: @review-record-storage-and-identity ac-1 - dedicated first-party review storage
124
+ * AC: @review-record-storage-and-identity ac-3 - single dedicated file per project
125
+ * Uses file lock to prevent TOCTOU race on concurrent writes.
126
+ */
127
+ export async function saveReviewRecord(ctx, review) {
128
+ const reviewsPath = getReviewsFilePath(ctx);
129
+ // Lock the file to prevent concurrent read-modify-write races
130
+ await withFileLock(reviewsPath, async () => {
131
+ // Ensure directory exists
132
+ const dir = path.dirname(reviewsPath);
133
+ await fs.mkdir(dir, { recursive: true });
134
+ // Load existing reviews (inside lock to prevent TOCTOU)
135
+ let reviews = [];
136
+ try {
137
+ reviews = await loadReviewsFromFile(reviewsPath);
138
+ }
139
+ catch {
140
+ // File doesn't exist yet, start fresh
141
+ }
142
+ const cleanReview = stripReviewMetadata(review);
143
+ // Update or add
144
+ const existingIndex = reviews.findIndex((r) => r._ulid === review._ulid);
145
+ if (existingIndex >= 0) {
146
+ reviews[existingIndex] = cleanReview;
147
+ }
148
+ else {
149
+ reviews.push(cleanReview);
150
+ }
151
+ // Save back to file
152
+ const reviewsFile = {
153
+ kynetic_reviews: "1.0",
154
+ reviews,
155
+ };
156
+ await writeYamlFilePreserveFormat(reviewsPath, reviewsFile);
157
+ });
158
+ }
159
+ /**
160
+ * Atomically mutate a review record using the latest on-disk state.
161
+ *
162
+ * The callback receives the current review value while holding the file lock,
163
+ * so concurrent writers do not clobber unrelated fields.
164
+ */
165
+ export async function mutateReviewAtomically(ctx, review, mutate) {
166
+ const reviewsPath = review._sourceFile || getReviewsFilePath(ctx);
167
+ let updatedReview;
168
+ await withFileLock(reviewsPath, async () => {
169
+ // Ensure directory exists
170
+ const dir = path.dirname(reviewsPath);
171
+ await fs.mkdir(dir, { recursive: true });
172
+ let reviews = [];
173
+ try {
174
+ reviews = await loadReviewsFromFile(reviewsPath);
175
+ }
176
+ catch {
177
+ throw new Error(`Reviews file not found: ${reviewsPath}`);
178
+ }
179
+ const reviewIndex = reviews.findIndex((candidate) => candidate._ulid === review._ulid);
180
+ if (reviewIndex === -1) {
181
+ throw new Error(`Review not found in file: ${review._ulid}`);
182
+ }
183
+ const latestReview = {
184
+ ...reviews[reviewIndex],
185
+ _sourceFile: reviewsPath,
186
+ };
187
+ const mutatedReview = await mutate(latestReview);
188
+ const cleanMutatedReview = stripReviewMetadata(mutatedReview);
189
+ reviews[reviewIndex] = cleanMutatedReview;
190
+ const reviewsFile = {
191
+ kynetic_reviews: "1.0",
192
+ reviews,
193
+ };
194
+ await writeYamlFilePreserveFormat(reviewsPath, reviewsFile);
195
+ updatedReview = {
196
+ ...cleanMutatedReview,
197
+ _sourceFile: reviewsPath,
198
+ };
199
+ });
200
+ if (!updatedReview) {
201
+ throw new Error(`Failed to mutate review atomically: ${review._ulid}`);
202
+ }
203
+ return updatedReview;
204
+ }
205
+ /**
206
+ * Delete a review record by ULID.
207
+ */
208
+ export async function deleteReviewRecord(ctx, reviewUlid) {
209
+ const reviewsPath = getReviewsFilePath(ctx);
210
+ return withFileLock(reviewsPath, async () => {
211
+ try {
212
+ const reviews = await loadReviewsFromFile(reviewsPath);
213
+ const index = reviews.findIndex((r) => r._ulid === reviewUlid);
214
+ if (index < 0) {
215
+ return false;
216
+ }
217
+ reviews.splice(index, 1);
218
+ const reviewsFile = {
219
+ kynetic_reviews: "1.0",
220
+ reviews,
221
+ };
222
+ await writeYamlFilePreserveFormat(reviewsPath, reviewsFile);
223
+ return true;
224
+ }
225
+ catch {
226
+ return false;
227
+ }
228
+ });
229
+ }
230
+ //# sourceMappingURL=reviews.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviews.js","sourceRoot":"","sources":["../../src/parser/reviews.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAGL,kBAAkB,EAElB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AAUtE;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAiB;IAClD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;AACxD,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,GAAY;IACvC,MAAM,MAAM,GAAG,uBAAuB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACtD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;QACvD,MAAM,eAAe,GAAI,GAA6B,CAAC,OAAO,CAAC;QAC/D,IAAI,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAmB,EAAE,CAAC;YACnC,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;gBACrC,MAAM,YAAY,GAAG,kBAAkB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAC1D,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;oBACzB,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,mBAAmB,CAChC,WAAmB;IAEnB,MAAM,GAAG,GAAG,MAAM,YAAY,CAAU,WAAW,CAAC,CAAC;IACrD,OAAO,mBAAmB,CAAC,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAC1B,MAAyC;IAEzC,MAAM,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,GAAG,MAA4B,CAAC;IACrE,OAAO,WAA2B,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAiB;IAEjB,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAE5C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;QACvD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC9B,GAAG,MAAM;YACT,WAAW,EAAE,WAAW;SACzB,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,MAAM,CAAC;QACP,oCAAoC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,OAA6B,EAC7B,GAAW;IAEX,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAE1D,OAAO,OAAO,CAAC,IAAI,CACjB,CAAC,CAAC,EAAE,EAAE;IACJ,kBAAkB;IAClB,CAAC,CAAC,KAAK,KAAK,QAAQ;QACpB,4BAA4B;QAC5B,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACxD,iBAAiB;QACjB,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC7B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAwB;IACzD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE;QAC5B,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI,OAAO;QACjD,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,EAAE;QACtC,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;QAC5B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;QAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,EAAE;QAC9B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;QAC1B,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;QACxB,cAAc,EAAE,KAAK,CAAC,cAAc,IAAI,EAAE;QAC1C,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI,IAAI;QAC9C,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,GAAG;QACnC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;KACrC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAiB,EACjB,MAA0B;IAE1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAE5C,8DAA8D;IAC9D,MAAM,YAAY,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;QACzC,0BAA0B;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACtC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEzC,wDAAwD;QACxD,IAAI,OAAO,GAAmB,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,sCAAsC;QACxC,CAAC;QAED,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAEhD,gBAAgB;QAChB,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;QACzE,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,aAAa,CAAC,GAAG,WAAW,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5B,CAAC;QAED,oBAAoB;QACpB,MAAM,WAAW,GAAsB;YACrC,eAAe,EAAE,KAAK;YACtB,OAAO;SACR,CAAC;QAEF,MAAM,2BAA2B,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,GAAiB,EACjB,MAA0B,EAC1B,MAEmF;IAEnF,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAClE,IAAI,aAA6C,CAAC;IAElD,MAAM,YAAY,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;QACzC,0BAA0B;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACtC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEzC,IAAI,OAAO,GAAmB,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,2BAA2B,WAAW,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CACnC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAChD,CAAC;QACF,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,YAAY,GAAuB;YACvC,GAAG,OAAO,CAAC,WAAW,CAAC;YACvB,WAAW,EAAE,WAAW;SACzB,CAAC;QAEF,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QACjD,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;QAC9D,OAAO,CAAC,WAAW,CAAC,GAAG,kBAAkB,CAAC;QAE1C,MAAM,WAAW,GAAsB;YACrC,eAAe,EAAE,KAAK;YACtB,OAAO;SACR,CAAC;QACF,MAAM,2BAA2B,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QAE5D,aAAa,GAAG;YACd,GAAG,kBAAkB;YACrB,WAAW,EAAE,WAAW;SACzB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,uCAAuC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAiB,EACjB,UAAkB;IAElB,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAE5C,OAAO,YAAY,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;QAC1C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;YAEvD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC;YAC/D,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACd,OAAO,KAAK,CAAC;YACf,CAAC;YAED,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAEzB,MAAM,WAAW,GAAsB;gBACrC,eAAe,EAAE,KAAK;gBACtB,OAAO;aACR,CAAC;YAEF,MAAM,2BAA2B,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YAC5D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Session branch worktree management.
3
+ *
4
+ * When sessions.storage is "branch", sessions are stored in a git worktree
5
+ * on a named orphan branch (default: "kspec-sessions") at .kspec-sessions/.
6
+ * This provides git-tracked session persistence independent of kspec-meta.
7
+ *
8
+ * AC: @session-branch-worktree — all ACs
9
+ */
10
+ import { type ShadowSyncResult } from "./shadow.js";
11
+ /** Default session branch name */
12
+ export declare const SESSION_BRANCH_NAME = "kspec-sessions";
13
+ /** Configuration for session branch mode */
14
+ export interface SessionBranchConfig {
15
+ /** Whether session branch mode is enabled */
16
+ enabled: boolean;
17
+ /** Path to .kspec-sessions/ worktree directory */
18
+ worktreeDir: string;
19
+ /** Session branch name (default: kspec-sessions) */
20
+ branchName: string;
21
+ /** Project root */
22
+ projectRoot: string;
23
+ }
24
+ /** Status of the session branch worktree */
25
+ export interface SessionBranchStatus {
26
+ exists: boolean;
27
+ healthy: boolean;
28
+ branchExists: boolean;
29
+ worktreeExists: boolean;
30
+ worktreeLinked: boolean;
31
+ error?: string;
32
+ }
33
+ /** Result from session branch initialization */
34
+ export interface SessionBranchInitResult {
35
+ success: boolean;
36
+ branchCreated: boolean;
37
+ worktreeCreated: boolean;
38
+ alreadyExists: boolean;
39
+ error?: string;
40
+ }
41
+ /**
42
+ * Get the status of the session branch worktree.
43
+ *
44
+ * AC: @session-branch-worktree ac-status
45
+ */
46
+ export declare function getSessionBranchStatus(projectRoot: string, branchName?: string): Promise<SessionBranchStatus>;
47
+ /**
48
+ * Initialize session branch worktree.
49
+ * Creates an orphan branch and worktree at .kspec-sessions/.
50
+ *
51
+ * AC: @session-branch-worktree ac-init
52
+ */
53
+ export declare function initializeSessionBranch(projectRoot: string, branchName?: string): Promise<SessionBranchInitResult>;
54
+ /**
55
+ * Repair a broken session branch worktree.
56
+ *
57
+ * AC: @session-branch-worktree ac-repair
58
+ */
59
+ export declare function repairSessionBranch(projectRoot: string, branchName?: string): Promise<SessionBranchInitResult>;
60
+ /**
61
+ * Auto-commit changes to the session branch.
62
+ * Called at session lifecycle boundaries (create, close, stale cleanup, compact).
63
+ *
64
+ * AC: @session-branch-worktree ac-commit-boundaries
65
+ */
66
+ export declare function sessionBranchAutoCommit(worktreeDir: string, message: string): Promise<boolean>;
67
+ /**
68
+ * Commit session changes if session branch mode is enabled.
69
+ * Respects batch mode (suppresses commits during atomic batch execution).
70
+ *
71
+ * AC: @session-branch-worktree ac-commit-boundaries
72
+ */
73
+ export declare function commitIfSessionBranch(config: SessionBranchConfig | null, operation: string, sessionId?: string): Promise<boolean>;
74
+ /**
75
+ * Pull remote changes for the session branch.
76
+ * Uses in-flight dedup to prevent concurrent pulls.
77
+ *
78
+ * AC: @session-branch-worktree ac-sync
79
+ */
80
+ export declare function sessionBranchPull(worktreeDir: string, branchName?: string): Promise<ShadowSyncResult>;
81
+ /**
82
+ * Resolve session branch config from manifest.
83
+ * Returns null if sessions.storage is not "branch".
84
+ */
85
+ export declare function resolveSessionBranchConfig(projectRoot: string, manifest: {
86
+ sessions?: {
87
+ storage?: string;
88
+ branch?: string;
89
+ };
90
+ } | null): SessionBranchConfig | null;
91
+ //# sourceMappingURL=session-branch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-branch.d.ts","sourceRoot":"","sources":["../../src/parser/session-branch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EAQL,KAAK,gBAAgB,EAEtB,MAAM,aAAa,CAAC;AAOrB,kCAAkC;AAClC,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAIpD,4CAA4C;AAC5C,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,4CAA4C;AAC5C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,gDAAgD;AAChD,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAgDD;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,UAAU,GAAE,MAA4B,GACvC,OAAO,CAAC,mBAAmB,CAAC,CAgD9B;AAID;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,UAAU,GAAE,MAA4B,GACvC,OAAO,CAAC,uBAAuB,CAAC,CA6KlC;AAID;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,UAAU,GAAE,MAA4B,GACvC,OAAO,CAAC,uBAAuB,CAAC,CAwElC;AAID;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC,CAoElB;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAClC,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CAelB;AAWD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,UAAU,GAAE,MAA4B,GACvC,OAAO,CAAC,gBAAgB,CAAC,CAW3B;AA+GD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE;IAAE,QAAQ,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,IAAI,GACpE,mBAAmB,GAAG,IAAI,CAa5B"}