@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
@@ -1,9 +1,10 @@
1
- import * as path from 'node:path';
2
- import chalk from 'chalk';
3
- import { initContext, validate, loadAllTasks, loadAllItems, AlignmentIndex, ReferenceIndex, fixFiles, findTaskFiles, expandIncludePattern, loadMetaContext, validateConventions, } from '../../parser/index.js';
4
- import { output, error } from '../output.js';
5
- import { validation as validationStrings } from '../../strings/index.js';
6
- import { EXIT_CODES } from '../exit-codes.js';
1
+ import * as path from "node:path";
2
+ import chalk from "chalk";
3
+ import { AlignmentIndex, checkACSchemaReferences, expandIncludePattern, findTaskFiles, fixFiles, initContext, loadAllItems, loadAllTasks, loadMetaContext, ReferenceIndex, validate, validateConventions, } from "../../parser/index.js";
4
+ import { validateSkills, } from "../../parser/validate-skills.js";
5
+ import { validation as validationStrings } from "../../strings/index.js";
6
+ import { EXIT_CODES } from "../exit-codes.js";
7
+ import { error, output } from "../output.js";
7
8
  /**
8
9
  * Check for stale status mismatches between specs and tasks
9
10
  * AC: @stale-status-detection ac-1, ac-2, ac-3
@@ -14,39 +15,39 @@ function checkStaleness(items, tasks, refIndex) {
14
15
  // Check if task with dependencies is pending but all dependencies are completed
15
16
  for (const task of tasks) {
16
17
  // Only check pending/in_progress tasks with dependencies
17
- if (task.status !== 'pending' && task.status !== 'in_progress')
18
+ if (task.status !== "pending" && task.status !== "in_progress")
18
19
  continue;
19
20
  if (!task.depends_on || task.depends_on.length === 0)
20
21
  continue;
21
22
  // Resolve all dependency tasks
22
23
  const depTasks = task.depends_on
23
- .map(depRef => {
24
+ .map((depRef) => {
24
25
  const result = refIndex.resolve(depRef);
25
26
  if (!result.ok)
26
27
  return null;
27
- return tasks.find(t => t._ulid === result.ulid);
28
+ return tasks.find((t) => t._ulid === result.ulid);
28
29
  })
29
30
  .filter((t) => t !== null);
30
31
  if (depTasks.length === 0)
31
32
  continue;
32
33
  // Check if all dependencies are completed and their linked specs are implemented
33
- const allDepsDone = depTasks.every(depTask => {
34
- if (depTask.status !== 'completed')
34
+ const allDepsDone = depTasks.every((depTask) => {
35
+ if (depTask.status !== "completed")
35
36
  return false;
36
37
  // If the dep task has a spec_ref, check if that spec is implemented
37
38
  if (depTask.spec_ref) {
38
39
  const result = refIndex.resolve(depTask.spec_ref);
39
40
  if (!result.ok)
40
41
  return true; // Missing spec ref doesn't block
41
- const spec = items.find(item => item._ulid === result.ulid);
42
- return spec?.status?.implementation === 'implemented';
42
+ const spec = items.find((item) => item._ulid === result.ulid);
43
+ return spec?.status?.implementation === "implemented";
43
44
  }
44
45
  return true;
45
46
  });
46
47
  if (allDepsDone) {
47
48
  const taskRef = task.slugs[0] || refIndex.shortUlid(task._ulid);
48
49
  warnings.push({
49
- type: 'parent-pending-children-done',
50
+ type: "parent-pending-children-done",
50
51
  message: `Task @${taskRef} is ${task.status} but all dependencies are completed. Consider completing or reviewing.`,
51
52
  refs: [task._ulid],
52
53
  });
@@ -55,11 +56,16 @@ function checkStaleness(items, tasks, refIndex) {
55
56
  // AC: @stale-status-detection ac-2 (spec-implemented-no-task)
56
57
  // Check if spec is implemented but has no completed tasks
57
58
  for (const item of items) {
58
- if (item.status?.implementation !== 'implemented')
59
+ if (item.status?.implementation !== "implemented")
60
+ continue;
61
+ // AC: @trait-retrospective ac-1
62
+ // Skip retrospective specs from staleness warnings
63
+ const isRetrospective = item.traits?.includes("@trait-retrospective");
64
+ if (isRetrospective)
59
65
  continue;
60
66
  // Find completed tasks that reference this spec
61
- const completedTasks = tasks.filter(task => {
62
- if (task.status !== 'completed' || !task.spec_ref)
67
+ const completedTasks = tasks.filter((task) => {
68
+ if (task.status !== "completed" || !task.spec_ref)
63
69
  return false;
64
70
  const result = refIndex.resolve(task.spec_ref);
65
71
  return result.ok && result.ulid === item._ulid;
@@ -67,7 +73,7 @@ function checkStaleness(items, tasks, refIndex) {
67
73
  if (completedTasks.length === 0) {
68
74
  const specRef = item.slugs[0] || refIndex.shortUlid(item._ulid);
69
75
  warnings.push({
70
- type: 'spec-implemented-no-task',
76
+ type: "spec-implemented-no-task",
71
77
  message: `Spec @${specRef} is implemented but has no completed tasks. Verify implementation or link existing task.`,
72
78
  refs: [item._ulid],
73
79
  });
@@ -76,7 +82,7 @@ function checkStaleness(items, tasks, refIndex) {
76
82
  // AC: @stale-status-detection ac-3 (task-done-spec-not-started)
77
83
  // Check if task is completed but spec is still not_started
78
84
  for (const task of tasks) {
79
- if (task.status !== 'completed')
85
+ if (task.status !== "completed")
80
86
  continue;
81
87
  if (!task.spec_ref)
82
88
  continue;
@@ -84,19 +90,41 @@ function checkStaleness(items, tasks, refIndex) {
84
90
  const result = refIndex.resolve(task.spec_ref);
85
91
  if (!result.ok)
86
92
  continue;
87
- const spec = items.find(item => item._ulid === result.ulid);
93
+ const spec = items.find((item) => item._ulid === result.ulid);
88
94
  if (!spec)
89
95
  continue;
90
- if (spec.status?.implementation === 'not_started') {
96
+ if (spec.status?.implementation === "not_started") {
91
97
  const taskRef = task.slugs[0] || refIndex.shortUlid(task._ulid);
92
98
  const specRef = spec.slugs[0] || refIndex.shortUlid(spec._ulid);
93
99
  warnings.push({
94
- type: 'task-done-spec-not-started',
100
+ type: "task-done-spec-not-started",
95
101
  message: `Task @${taskRef} completed but spec @${specRef} is not_started. Update spec status.`,
96
102
  refs: [task._ulid, spec._ulid],
97
103
  });
98
104
  }
99
105
  }
106
+ // AC: @validation ac-1
107
+ // Check for manual_only parents blocking eligible children
108
+ for (const parentTask of tasks) {
109
+ if (parentTask.automation !== "manual_only")
110
+ continue;
111
+ // Find tasks that depend on this parent
112
+ const dependentTasks = tasks.filter((t) => t.depends_on?.some((depRef) => {
113
+ const result = refIndex.resolve(depRef);
114
+ return result.ok && result.ulid === parentTask._ulid;
115
+ }));
116
+ // Filter for eligible children
117
+ const eligibleChildren = dependentTasks.filter((t) => t.automation === "eligible");
118
+ if (eligibleChildren.length > 0) {
119
+ const parentRef = parentTask.slugs[0] || refIndex.shortUlid(parentTask._ulid);
120
+ const childRefs = eligibleChildren.map((c) => `@${c.slugs[0] || refIndex.shortUlid(c._ulid)}`);
121
+ warnings.push({
122
+ type: "automation-blocking",
123
+ message: `Task @${parentRef} is manual_only and blocks ${eligibleChildren.length} eligible child task(s): ${childRefs.join(", ")}`,
124
+ refs: [parentTask._ulid, ...eligibleChildren.map((c) => c._ulid)],
125
+ });
126
+ }
127
+ }
100
128
  return warnings;
101
129
  }
102
130
  /**
@@ -105,14 +133,15 @@ function checkStaleness(items, tasks, refIndex) {
105
133
  */
106
134
  function formatStalenessWarnings(warnings, verbose) {
107
135
  if (warnings.length === 0) {
108
- console.log(chalk.green('Staleness: OK'));
136
+ console.log(chalk.green("Staleness: OK"));
109
137
  return;
110
138
  }
111
139
  console.log(chalk.yellow(`\nStaleness warnings: ${warnings.length}`));
112
140
  // Group by type
113
- const parentPending = warnings.filter(w => w.type === 'parent-pending-children-done');
114
- const specNoTask = warnings.filter(w => w.type === 'spec-implemented-no-task');
115
- const taskDoneSpecNot = warnings.filter(w => w.type === 'task-done-spec-not-started');
141
+ const parentPending = warnings.filter((w) => w.type === "parent-pending-children-done");
142
+ const specNoTask = warnings.filter((w) => w.type === "spec-implemented-no-task");
143
+ const taskDoneSpecNot = warnings.filter((w) => w.type === "task-done-spec-not-started");
144
+ const automationBlocking = warnings.filter((w) => w.type === "automation-blocking");
116
145
  if (parentPending.length > 0) {
117
146
  console.log(chalk.yellow(` Parent pending, children done: ${parentPending.length}`));
118
147
  const shown = verbose ? parentPending : parentPending.slice(0, 3);
@@ -143,6 +172,50 @@ function formatStalenessWarnings(warnings, verbose) {
143
172
  console.log(chalk.gray(` ... and ${taskDoneSpecNot.length - 3} more`));
144
173
  }
145
174
  }
175
+ if (automationBlocking.length > 0) {
176
+ console.log(chalk.yellow(` Automation blocking: ${automationBlocking.length}`));
177
+ const shown = verbose ? automationBlocking : automationBlocking.slice(0, 3);
178
+ for (const w of shown) {
179
+ console.log(chalk.yellow(` ! ${w.message}`));
180
+ }
181
+ if (!verbose && automationBlocking.length > 3) {
182
+ console.log(chalk.gray(` ... and ${automationBlocking.length - 3} more`));
183
+ }
184
+ }
185
+ }
186
+ /**
187
+ * Format AC schema drift warnings for display
188
+ */
189
+ function formatDriftWarnings(warnings, verbose) {
190
+ // Filter to only drift warnings
191
+ const driftWarnings = warnings.filter((w) => w.type === "ac_schema_field_mismatch");
192
+ if (driftWarnings.length === 0) {
193
+ console.log(chalk.green("AC Schema Drift: OK"));
194
+ return;
195
+ }
196
+ console.log(chalk.yellow(`\nAC Schema Drift warnings: ${driftWarnings.length}`));
197
+ // Group by item
198
+ const byItem = new Map();
199
+ for (const w of driftWarnings) {
200
+ const existing = byItem.get(w.itemRef) || [];
201
+ existing.push(w);
202
+ byItem.set(w.itemRef, existing);
203
+ }
204
+ const itemEntries = [...byItem.entries()];
205
+ const shown = verbose ? itemEntries : itemEntries.slice(0, 5);
206
+ for (const [itemRef, itemWarnings] of shown) {
207
+ const firstWarning = itemWarnings[0];
208
+ console.log(chalk.yellow(` ${itemRef} - ${firstWarning.itemTitle}`));
209
+ for (const w of itemWarnings) {
210
+ console.log(chalk.yellow(` ! ${w.message}`));
211
+ if (w.details) {
212
+ console.log(chalk.gray(` ${w.details}`));
213
+ }
214
+ }
215
+ }
216
+ if (!verbose && itemEntries.length > 5) {
217
+ console.log(chalk.gray(` ... and ${itemEntries.length - 5} more items with drift`));
218
+ }
146
219
  }
147
220
  /**
148
221
  * Format convention validation results for display
@@ -150,7 +223,7 @@ function formatStalenessWarnings(warnings, verbose) {
150
223
  */
151
224
  function formatConventionValidationResult(result) {
152
225
  if (result.valid && result.skipped.length === 0) {
153
- console.log(chalk.green('Conventions: OK'));
226
+ console.log(chalk.green("Conventions: OK"));
154
227
  return;
155
228
  }
156
229
  // AC: @convention-definitions ac-4
@@ -176,28 +249,62 @@ function formatConventionValidationResult(result) {
176
249
  }
177
250
  }
178
251
  else {
179
- console.log(chalk.green('\nConventions: OK'));
252
+ console.log(chalk.green("\nConventions: OK"));
180
253
  }
181
254
  // Stats
182
255
  console.log(chalk.gray(`\nConventions checked: ${result.stats.conventionsChecked}`));
183
256
  console.log(chalk.gray(`Conventions skipped: ${result.stats.conventionsSkipped}`));
184
257
  }
258
+ /**
259
+ * Format skill validation results for display
260
+ */
261
+ function formatSkillValidationResult(result, verbose) {
262
+ if (result.filesChecked === 0) {
263
+ console.log(chalk.gray("Skills: No skill files found"));
264
+ return;
265
+ }
266
+ if (result.valid) {
267
+ console.log(chalk.green(`Skills: OK (${result.filesChecked} files checked)`));
268
+ return;
269
+ }
270
+ console.log(chalk.red(`\nSkill validation errors: ${result.errors.length}`));
271
+ console.log(chalk.gray(`Files checked: ${result.filesChecked}`));
272
+ // Group errors by file
273
+ const errorsByFile = new Map();
274
+ for (const err of result.errors) {
275
+ const existing = errorsByFile.get(err.file) || [];
276
+ existing.push(err);
277
+ errorsByFile.set(err.file, existing);
278
+ }
279
+ for (const [file, errors] of errorsByFile.entries()) {
280
+ console.log(chalk.yellow(`\n ${file}:`));
281
+ const shown = verbose ? errors : errors.slice(0, 5);
282
+ for (const err of shown) {
283
+ const location = err.line ? `:${err.line}` : "";
284
+ console.log(chalk.red(` ✗ ${err.type}${location}`));
285
+ console.log(chalk.gray(` ${err.message}`));
286
+ }
287
+ if (!verbose && errors.length > 5) {
288
+ console.log(chalk.gray(` ... and ${errors.length - 5} more`));
289
+ }
290
+ }
291
+ }
185
292
  /**
186
293
  * Format completeness warnings for display
187
294
  * AC: @spec-completeness ac-4
188
295
  */
189
296
  function formatCompletenessWarnings(warnings, verbose) {
190
297
  if (warnings.length === 0) {
191
- console.log(chalk.green('Completeness: OK'));
298
+ console.log(chalk.green("Completeness: OK"));
192
299
  return;
193
300
  }
194
301
  console.log(chalk.yellow(`\nCompleteness warnings: ${warnings.length}`));
195
302
  // Group by type
196
- const missingAC = warnings.filter(w => w.type === 'missing_acceptance_criteria');
197
- const missingDesc = warnings.filter(w => w.type === 'missing_description');
198
- const statusMismatch = warnings.filter(w => w.type === 'status_inconsistency');
199
- const missingTestCoverage = warnings.filter(w => w.type === 'missing_test_coverage');
200
- const automationNoSpec = warnings.filter(w => w.type === 'automation_eligible_no_spec');
303
+ const missingAC = warnings.filter((w) => w.type === "missing_acceptance_criteria");
304
+ const missingDesc = warnings.filter((w) => w.type === "missing_description");
305
+ const statusMismatch = warnings.filter((w) => w.type === "status_inconsistency");
306
+ const missingTestCoverage = warnings.filter((w) => w.type === "missing_test_coverage");
307
+ const automationNoSpec = warnings.filter((w) => w.type === "automation_eligible_no_spec");
201
308
  // AC: @spec-completeness ac-4
202
309
  // Show summary with counts by issue type
203
310
  if (missingAC.length > 0) {
@@ -231,7 +338,9 @@ function formatCompletenessWarnings(warnings, verbose) {
231
338
  }
232
339
  if (missingTestCoverage.length > 0) {
233
340
  console.log(chalk.yellow(` Missing test coverage: ${missingTestCoverage.length}`));
234
- const shown = verbose ? missingTestCoverage : missingTestCoverage.slice(0, 3);
341
+ const shown = verbose
342
+ ? missingTestCoverage
343
+ : missingTestCoverage.slice(0, 3);
235
344
  for (const w of shown) {
236
345
  console.log(chalk.yellow(` ! ${w.itemRef} - ${w.itemTitle}`));
237
346
  if (w.details) {
@@ -260,14 +369,14 @@ function formatCompletenessWarnings(warnings, verbose) {
260
369
  */
261
370
  function formatAlignmentWarnings(warnings, verbose) {
262
371
  if (warnings.length === 0) {
263
- console.log(chalk.green('Alignment: OK'));
372
+ console.log(chalk.green("Alignment: OK"));
264
373
  return;
265
374
  }
266
375
  console.log(chalk.yellow(`\nAlignment warnings: ${warnings.length}`));
267
376
  // Group by type
268
- const orphaned = warnings.filter(w => w.type === 'orphaned_spec');
269
- const mismatches = warnings.filter(w => w.type === 'status_mismatch');
270
- const stale = warnings.filter(w => w.type === 'stale_implementation');
377
+ const orphaned = warnings.filter((w) => w.type === "orphaned_spec");
378
+ const mismatches = warnings.filter((w) => w.type === "status_mismatch");
379
+ const stale = warnings.filter((w) => w.type === "stale_implementation");
271
380
  if (orphaned.length > 0) {
272
381
  console.log(chalk.yellow(` Orphaned specs (no tasks): ${orphaned.length}`));
273
382
  const shown = verbose ? orphaned : orphaned.slice(0, 3);
@@ -297,15 +406,15 @@ function formatAlignmentWarnings(warnings, verbose) {
297
406
  */
298
407
  function formatFixResult(result) {
299
408
  if (result.fixesApplied.length === 0) {
300
- console.log(chalk.gray('\nNo auto-fixable issues found.'));
409
+ console.log(chalk.gray("\nNo auto-fixable issues found."));
301
410
  return;
302
411
  }
303
412
  console.log(chalk.cyan(`\n✓ Applied ${result.fixesApplied.length} fix(es) to ${result.filesModified} file(s):`));
304
413
  for (const fix of result.fixesApplied) {
305
414
  const typeLabel = {
306
- ulid_regenerated: 'ULID regenerated',
307
- timestamp_added: 'Timestamp added',
308
- status_added: 'Status added',
415
+ ulid_regenerated: "ULID regenerated",
416
+ timestamp_added: "Timestamp added",
417
+ status_added: "Status added",
309
418
  }[fix.type];
310
419
  const shortFile = path.basename(fix.file);
311
420
  console.log(chalk.cyan(` ✓ ${shortFile}:${fix.path} - ${typeLabel}`));
@@ -324,9 +433,9 @@ async function collectFixableFiles(ctx) {
324
433
  const files = [];
325
434
  // Task files (exclude test fixtures)
326
435
  const taskFiles = await findTaskFiles(ctx.rootDir);
327
- const specTaskFiles = await findTaskFiles(path.join(ctx.rootDir, 'spec'));
436
+ const specTaskFiles = await findTaskFiles(path.join(ctx.rootDir, "spec"));
328
437
  const allTaskFiles = [...new Set([...taskFiles, ...specTaskFiles])];
329
- files.push(...allTaskFiles.filter(f => !f.includes('fixtures') && !f.includes('test')));
438
+ files.push(...allTaskFiles.filter((f) => !f.includes("fixtures") && !f.includes("test")));
330
439
  // Spec files from includes
331
440
  if (ctx.manifest && ctx.manifestPath) {
332
441
  const manifestDir = path.dirname(ctx.manifestPath);
@@ -337,9 +446,9 @@ async function collectFixableFiles(ctx) {
337
446
  }
338
447
  }
339
448
  // Inbox file
340
- const inboxPath = path.join(ctx.rootDir, 'spec', 'kynetic.inbox.yaml');
449
+ const inboxPath = path.join(ctx.rootDir, "spec", "kynetic.inbox.yaml");
341
450
  try {
342
- await import('node:fs/promises').then(fs => fs.access(inboxPath));
451
+ await import("node:fs/promises").then((fs) => fs.access(inboxPath));
343
452
  files.push(inboxPath);
344
453
  }
345
454
  catch {
@@ -353,12 +462,12 @@ async function collectFixableFiles(ctx) {
353
462
  function formatValidationResult(result, verbose) {
354
463
  // Header
355
464
  if (result.valid) {
356
- console.log(chalk.green.bold('✓ Validation passed'));
465
+ console.log(chalk.green.bold("✓ Validation passed"));
357
466
  }
358
467
  else {
359
- console.log(chalk.red.bold('✗ Validation failed'));
468
+ console.log(chalk.red.bold("✗ Validation failed"));
360
469
  }
361
- console.log(chalk.gray(''.repeat(40)));
470
+ console.log(chalk.gray("".repeat(40)));
362
471
  console.log(`Files checked: ${result.stats.filesChecked}`);
363
472
  console.log(`Items checked: ${result.stats.itemsChecked}`);
364
473
  console.log(`Tasks checked: ${result.stats.tasksChecked}`);
@@ -379,7 +488,7 @@ function formatValidationResult(result, verbose) {
379
488
  }
380
489
  }
381
490
  else {
382
- console.log(chalk.green('\nSchema: OK'));
491
+ console.log(chalk.green("\nSchema: OK"));
383
492
  }
384
493
  // Reference errors
385
494
  if (result.refErrors.length > 0) {
@@ -394,7 +503,7 @@ function formatValidationResult(result, verbose) {
394
503
  }
395
504
  }
396
505
  else {
397
- console.log(chalk.green('References: OK'));
506
+ console.log(chalk.green("References: OK"));
398
507
  }
399
508
  // Reference warnings (deprecated targets)
400
509
  if (result.refWarnings.length > 0) {
@@ -446,18 +555,20 @@ function formatValidationResult(result, verbose) {
446
555
  */
447
556
  export function registerValidateCommand(program) {
448
557
  program
449
- .command('validate')
450
- .description('Validate spec files')
451
- .option('--schema', 'Check schema conformance only')
452
- .option('--refs', 'Check reference resolution only')
453
- .option('--orphans', 'Find orphaned items only')
454
- .option('--alignment', 'Check spec-task alignment')
455
- .option('--completeness', 'Check spec completeness (missing AC, descriptions, status inconsistencies)')
456
- .option('--conventions', 'Validate conventions')
457
- .option('--staleness', 'Check for stale status mismatches between specs and tasks')
458
- .option('--fix', 'Auto-fix issues where possible (invalid ULIDs, missing timestamps)')
459
- .option('-v, --verbose', 'Show detailed output')
460
- .option('--strict', 'Treat orphans and staleness warnings as errors')
558
+ .command("validate")
559
+ .description("Validate spec files")
560
+ .option("--schema", "Check schema conformance only")
561
+ .option("--refs", "Check reference resolution only")
562
+ .option("--orphans", "Find orphaned items only")
563
+ .option("--alignment", "Check spec-task alignment")
564
+ .option("--completeness", "Check spec completeness (missing AC, descriptions, status inconsistencies)")
565
+ .option("--conventions", "Validate conventions")
566
+ .option("--staleness", "Check for stale status mismatches between specs and tasks")
567
+ .option("--skills", "Validate skill files (.claude/skills/*/SKILL.md)")
568
+ .option("--drift", "Check AC field references against actual schema (catches spec prose drift)")
569
+ .option("--fix", "Auto-fix issues where possible (invalid ULIDs, missing timestamps)")
570
+ .option("-v, --verbose", "Show detailed output")
571
+ .option("--strict", "Treat orphans and staleness warnings as errors")
461
572
  .action(async (options) => {
462
573
  try {
463
574
  const ctx = await initContext();
@@ -466,13 +577,29 @@ export function registerValidateCommand(program) {
466
577
  console.log(validationStrings.initHint);
467
578
  process.exit(EXIT_CODES.ERROR);
468
579
  }
580
+ // Track warnings from all sources for exit code determination
581
+ let additionalWarningCount = 0;
469
582
  // Determine which checks to run
470
- const runAll = !options.schema && !options.refs && !options.orphans && !options.alignment && !options.completeness && !options.conventions;
583
+ const runAll = !options.schema &&
584
+ !options.refs &&
585
+ !options.orphans &&
586
+ !options.alignment &&
587
+ !options.completeness &&
588
+ !options.conventions &&
589
+ !options.skills;
590
+ // AC: @config-validation ac-4 — CLI --strict overrides config strict_refs
591
+ // If --strict is passed, use strict behavior regardless of config
592
+ // Otherwise, use config value (which defaults to false)
593
+ const strictRefs = options.strict ? true : ctx.config.validation.strict_refs;
594
+ const requireAcceptance = ctx.config.validation.require_acceptance;
471
595
  const validateOptions = {
472
596
  schema: runAll || options.schema,
473
597
  refs: runAll || options.refs,
474
598
  orphans: runAll || options.orphans,
475
599
  completeness: runAll || options.completeness,
600
+ // AC: @config-validation ac-2 ac-3 ac-4 — wire config into validation
601
+ strictRefs,
602
+ requireAcceptance,
476
603
  };
477
604
  const result = await validate(ctx, validateOptions);
478
605
  // In strict mode, orphans are errors
@@ -510,6 +637,7 @@ export function registerValidateCommand(program) {
510
637
  alignmentIndex.buildLinks(refIndex);
511
638
  const alignmentWarnings = alignmentIndex.findAlignmentWarnings();
512
639
  formatAlignmentWarnings(alignmentWarnings, options.verbose);
640
+ additionalWarningCount += alignmentWarnings.length;
513
641
  // Show alignment stats
514
642
  const stats = alignmentIndex.getStats();
515
643
  console.log(validationStrings.alignmentStats(stats.specsWithTasks, stats.totalSpecs, stats.alignedSpecs));
@@ -535,30 +663,66 @@ export function registerValidateCommand(program) {
535
663
  }
536
664
  }
537
665
  else {
538
- console.log(chalk.gray('No conventions defined in meta manifest'));
666
+ console.log(chalk.gray("No conventions defined in meta manifest"));
539
667
  }
540
668
  }
541
- catch (err) {
542
- console.log(chalk.yellow('Warning: Could not load meta manifest for convention validation'));
669
+ catch (_err) {
670
+ console.log(chalk.yellow("Warning: Could not load meta manifest for convention validation"));
543
671
  }
544
672
  }
545
673
  // Run staleness checks if requested
546
674
  // AC: @stale-status-detection ac-4, ac-5
675
+ let stalenessWarningCount = 0;
547
676
  if (options.staleness) {
548
677
  const tasks = await loadAllTasks(ctx);
549
678
  const items = await loadAllItems(ctx);
550
679
  const refIndex = new ReferenceIndex(tasks, items);
551
680
  const stalenessWarnings = checkStaleness(items, tasks, refIndex);
552
681
  formatStalenessWarnings(stalenessWarnings, options.verbose);
682
+ stalenessWarningCount = stalenessWarnings.length;
553
683
  // AC: @stale-status-detection ac-5 (staleness-exit-code)
554
684
  // With --strict, staleness warnings cause validation failure
555
685
  if (options.strict && stalenessWarnings.length > 0) {
556
- process.exit(EXIT_CODES.VALIDATION_FAILED);
686
+ result.valid = false;
557
687
  }
558
688
  }
559
- if (!result.valid) {
560
- process.exit(EXIT_CODES.ERROR);
689
+ // Run skill file validation if requested or running all checks
690
+ if (runAll || options.skills) {
691
+ const skillResult = await validateSkills(ctx.rootDir);
692
+ formatSkillValidationResult(skillResult, options.verbose);
693
+ if (!skillResult.valid) {
694
+ result.valid = false;
695
+ }
561
696
  }
697
+ // Run AC schema drift checks if requested
698
+ let driftWarningCount = 0;
699
+ if (options.drift) {
700
+ const items = await loadAllItems(ctx);
701
+ const driftWarnings = checkACSchemaReferences(items);
702
+ formatDriftWarnings(driftWarnings, options.verbose);
703
+ driftWarningCount = driftWarnings.length;
704
+ // With --strict, drift warnings cause validation failure
705
+ if (options.strict && driftWarnings.length > 0) {
706
+ result.valid = false;
707
+ }
708
+ }
709
+ // Determine exit code based on errors vs warnings
710
+ // Errors: schema, refs, trait cycles, conventions, skills (result.valid = false)
711
+ // Warnings: orphans, alignment, completeness, staleness, drift, ref warnings
712
+ const hasErrors = !result.valid;
713
+ const hasWarnings = result.orphans.length > 0 ||
714
+ result.refWarnings.length > 0 ||
715
+ result.completenessWarnings.length > 0 ||
716
+ additionalWarningCount > 0 ||
717
+ stalenessWarningCount > 0 ||
718
+ driftWarningCount > 0;
719
+ if (hasErrors) {
720
+ process.exit(EXIT_CODES.VALIDATION_FAILED);
721
+ }
722
+ else if (hasWarnings) {
723
+ process.exit(EXIT_CODES.VALIDATION_WARNINGS);
724
+ }
725
+ // Otherwise exit 0 (success)
562
726
  }
563
727
  catch (err) {
564
728
  error(validationStrings.failed, err);
@@ -567,15 +731,15 @@ export function registerValidateCommand(program) {
567
731
  });
568
732
  // Alias: kspec lint
569
733
  program
570
- .command('lint')
571
- .description('Alias for validate with style checks')
572
- .option('--schema', 'Check schema conformance only')
573
- .option('--refs', 'Check reference resolution only')
574
- .option('--orphans', 'Find orphaned items only')
575
- .option('--completeness', 'Check spec completeness (missing AC, descriptions, status inconsistencies)')
576
- .option('--fix', 'Auto-fix issues where possible (invalid ULIDs, missing timestamps)')
577
- .option('-v, --verbose', 'Show detailed output')
578
- .option('--strict', 'Treat orphans as errors')
734
+ .command("lint")
735
+ .description("Alias for validate with style checks")
736
+ .option("--schema", "Check schema conformance only")
737
+ .option("--refs", "Check reference resolution only")
738
+ .option("--orphans", "Find orphaned items only")
739
+ .option("--completeness", "Check spec completeness (missing AC, descriptions, status inconsistencies)")
740
+ .option("--fix", "Auto-fix issues where possible (invalid ULIDs, missing timestamps)")
741
+ .option("-v, --verbose", "Show detailed output")
742
+ .option("--strict", "Treat orphans as errors")
579
743
  .action(async (options) => {
580
744
  try {
581
745
  const ctx = await initContext();
@@ -583,12 +747,20 @@ export function registerValidateCommand(program) {
583
747
  error(validationStrings.noManifest);
584
748
  process.exit(EXIT_CODES.ERROR);
585
749
  }
586
- const runAll = !options.schema && !options.refs && !options.orphans && !options.completeness;
750
+ const runAll = !options.schema &&
751
+ !options.refs &&
752
+ !options.orphans &&
753
+ !options.completeness;
754
+ // AC: @config-validation ac-4 — CLI --strict overrides config strict_refs
755
+ const strictRefs = options.strict ? true : ctx.config.validation.strict_refs;
756
+ const requireAcceptance = ctx.config.validation.require_acceptance;
587
757
  const validateOptions = {
588
758
  schema: runAll || options.schema,
589
759
  refs: runAll || options.refs,
590
760
  orphans: runAll || options.orphans,
591
761
  completeness: runAll || options.completeness,
762
+ strictRefs,
763
+ requireAcceptance,
592
764
  };
593
765
  const result = await validate(ctx, validateOptions);
594
766
  if (options.strict && result.orphans.length > 0) {
@@ -613,9 +785,18 @@ export function registerValidateCommand(program) {
613
785
  result.valid = revalidateResult.valid;
614
786
  }
615
787
  }
616
- if (!result.valid) {
617
- process.exit(EXIT_CODES.ERROR);
788
+ // Determine exit code based on errors vs warnings
789
+ const hasErrors = !result.valid;
790
+ const hasWarnings = result.orphans.length > 0 ||
791
+ result.refWarnings.length > 0 ||
792
+ result.completenessWarnings.length > 0;
793
+ if (hasErrors) {
794
+ process.exit(EXIT_CODES.VALIDATION_FAILED);
795
+ }
796
+ else if (hasWarnings) {
797
+ process.exit(EXIT_CODES.VALIDATION_WARNINGS);
618
798
  }
799
+ // Otherwise exit 0 (success)
619
800
  }
620
801
  catch (err) {
621
802
  error(validationStrings.lintFailed, err);