@sureshdsk/devflow-mcp 3.0.0 → 3.0.1

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 (504) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +4 -4
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
  6. package/.next/standalone/.next/server/app/_global-error/page.js +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  9. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
  16. package/.next/standalone/.next/server/app/_not-found/page.js +2 -2
  17. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.rsc +14 -13
  21. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -13
  22. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  23. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +5 -4
  24. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  25. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  26. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  27. package/.next/standalone/.next/server/app/api/projects/[id]/route.js +2 -2
  28. package/.next/standalone/.next/server/app/api/projects/[id]/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/projects/route.js +2 -2
  30. package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/specs/[name]/artifacts/[artifactType]/approve/route.js +2 -2
  32. package/.next/standalone/.next/server/app/api/specs/[name]/artifacts/[artifactType]/approve/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/specs/[name]/artifacts/[artifactType]/route.js +2 -2
  34. package/.next/standalone/.next/server/app/api/specs/[name]/artifacts/[artifactType]/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/specs/[name]/promote/route.js +2 -2
  36. package/.next/standalone/.next/server/app/api/specs/[name]/promote/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/specs/[name]/route.js +2 -2
  38. package/.next/standalone/.next/server/app/api/specs/[name]/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/specs/route.js +2 -2
  40. package/.next/standalone/.next/server/app/api/specs/route.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/api/tasks/[id]/route.js +2 -2
  42. package/.next/standalone/.next/server/app/api/tasks/[id]/route.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/api/tasks/route.js +2 -2
  44. package/.next/standalone/.next/server/app/api/tasks/route.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/index.html +1 -1
  46. package/.next/standalone/.next/server/app/index.rsc +15 -14
  47. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  48. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -14
  49. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  50. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +5 -4
  51. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  52. package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
  53. package/.next/standalone/.next/server/app/page.js +2 -2
  54. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/specs/[name]/page/build-manifest.json +2 -2
  57. package/.next/standalone/.next/server/app/specs/[name]/page.js +2 -2
  58. package/.next/standalone/.next/server/app/specs/[name]/page.js.nft.json +1 -1
  59. package/.next/standalone/.next/server/app/specs/[name]/page_client-reference-manifest.js +1 -1
  60. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0be0eb8b._.js +3 -0
  61. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__a9d478ee._.js → [root-of-the-server]__160c54ca._.js} +2 -2
  62. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17ac51e3._.js +3 -0
  63. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1bb083e9._.js +3 -0
  64. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1dc1e944._.js +3 -0
  65. package/.next/standalone/.next/server/chunks/[root-of-the-server]__22ecfa2c._.js +3 -0
  66. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__13a93eb6._.js → [root-of-the-server]__64710c0d._.js} +2 -2
  67. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a2b7e5f2._.js +3 -0
  68. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cf302bda._.js +3 -0
  69. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d85482cd._.js +3 -0
  70. package/.next/standalone/.next/server/chunks/[root-of-the-server]__dfa21757._.js +3 -0
  71. package/.next/standalone/.next/server/chunks/_3f452afe._.js +2 -2
  72. package/.next/standalone/.next/server/chunks/src_db_index_ts_a71f50f0._.js +3 -0
  73. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__023e2c69._.js +3 -0
  74. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0a1a1435._.js +3 -0
  75. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0c49a387._.js +3 -0
  76. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1be1fc5f._.js +3 -0
  77. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__3a2f2efb._.js +3 -0
  78. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__4693399c._.js +3 -0
  79. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__937c9212._.js → [root-of-the-server]__72a14301._.js} +2 -2
  80. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__8064ca06._.js +3 -0
  81. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__8b786d48._.js +3 -0
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__8c052461._.js +3 -0
  83. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__8d306066._.js +3 -0
  84. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__9532fd59._.js +3 -0
  85. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__a119dd75._.js +3 -0
  86. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__7fb6ef14._.js → [root-of-the-server]__a57b312b._.js} +2 -2
  87. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__a80bd0ea._.js +3 -0
  88. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__abe095b3._.js +3 -0
  89. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__ad3bd783._.js +3 -0
  90. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1e05fe0e._.js → [root-of-the-server]__ae9f05d6._.js} +2 -2
  91. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__c8781469._.js +3 -0
  92. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__c8a25070._.js +3 -0
  93. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__e8c1e595._.js +3 -0
  94. package/.next/standalone/.next/server/chunks/ssr/_0ff3de19._.js +1 -1
  95. package/.next/standalone/.next/server/chunks/ssr/node_modules_01a5cd4b._.js +3 -0
  96. package/.next/standalone/.next/server/chunks/ssr/node_modules_05c6819f._.js +31 -0
  97. package/.next/standalone/.next/server/chunks/ssr/node_modules_06c2c30a._.js +3 -0
  98. package/.next/standalone/.next/server/chunks/ssr/node_modules_09efe605._.js +3 -0
  99. package/.next/standalone/.next/server/chunks/ssr/{node_modules_mermaid_dist_chunks_mermaid_core_ef601841._.js → node_modules_0a439e3b._.js} +2 -2
  100. package/.next/standalone/.next/server/chunks/ssr/{node_modules_3507b41a._.js → node_modules_0e73ad6c._.js} +3 -3
  101. package/.next/standalone/.next/server/chunks/ssr/node_modules_0e7ff06d._.js +3 -0
  102. package/.next/standalone/.next/server/chunks/ssr/node_modules_0f73e25c._.js +3 -0
  103. package/.next/standalone/.next/server/chunks/ssr/node_modules_14cf9cea._.js +3 -0
  104. package/.next/standalone/.next/server/chunks/ssr/node_modules_19801f01._.js +3 -0
  105. package/.next/standalone/.next/server/chunks/ssr/node_modules_2235b8cf._.js +17 -0
  106. package/.next/standalone/.next/server/chunks/ssr/node_modules_23096c6d._.js +3 -0
  107. package/.next/standalone/.next/server/chunks/ssr/node_modules_23db4cf7._.js +17 -0
  108. package/.next/standalone/.next/server/chunks/ssr/node_modules_24381e95._.js +3 -0
  109. package/.next/standalone/.next/server/chunks/ssr/node_modules_24ca0eb6._.js +17 -0
  110. package/.next/standalone/.next/server/chunks/ssr/node_modules_27525793._.js +17 -0
  111. package/.next/standalone/.next/server/chunks/ssr/{node_modules_mermaid_dist_chunks_mermaid_core_4cfa6360._.js → node_modules_27c20382._.js} +2 -2
  112. package/.next/standalone/.next/server/chunks/ssr/node_modules_2c901b92._.js +3 -0
  113. package/.next/standalone/.next/server/chunks/ssr/node_modules_33b818b7._.js +45 -0
  114. package/.next/standalone/.next/server/chunks/ssr/node_modules_345d7791._.js +3 -0
  115. package/.next/standalone/.next/server/chunks/ssr/node_modules_36185c24._.js +45 -0
  116. package/.next/standalone/.next/server/chunks/ssr/node_modules_3ac7ce09._.js +3 -0
  117. package/.next/standalone/.next/server/chunks/ssr/node_modules_41b77cc7._.js +3 -0
  118. package/.next/standalone/.next/server/chunks/ssr/{node_modules_ed317ff6._.js → node_modules_42acd8db._.js} +2 -2
  119. package/.next/standalone/.next/server/chunks/ssr/node_modules_434aa5ec._.js +3 -0
  120. package/.next/standalone/.next/server/chunks/ssr/node_modules_54a9e72d._.js +17 -0
  121. package/.next/standalone/.next/server/chunks/ssr/node_modules_54f1273a._.js +26 -0
  122. package/.next/standalone/.next/server/chunks/ssr/node_modules_58d64491._.js +3 -0
  123. package/.next/standalone/.next/server/chunks/ssr/node_modules_5e012e3d._.js +3 -0
  124. package/.next/standalone/.next/server/chunks/ssr/node_modules_5ea9e4cf._.js +3 -0
  125. package/.next/standalone/.next/server/chunks/ssr/node_modules_5ecf8270._.js +26 -0
  126. package/.next/standalone/.next/server/chunks/ssr/node_modules_611c99b5._.js +1 -1
  127. package/.next/standalone/.next/server/chunks/ssr/{node_modules_d3-scale_src_e02ef77f._.js → node_modules_6629853d._.js} +2 -2
  128. package/.next/standalone/.next/server/chunks/ssr/node_modules_6fe2661c._.js +3 -0
  129. package/.next/standalone/.next/server/chunks/ssr/node_modules_7fe65a84._.js +3 -0
  130. package/.next/standalone/.next/server/chunks/ssr/node_modules_860f971a._.js +3 -0
  131. package/.next/standalone/.next/server/chunks/ssr/node_modules_882f3743._.js +3 -0
  132. package/.next/standalone/.next/server/chunks/ssr/node_modules_8e047938._.js +3 -0
  133. package/.next/standalone/.next/server/chunks/ssr/node_modules_9268cdc4._.js +3 -0
  134. package/.next/standalone/.next/server/chunks/ssr/node_modules_942541c9._.js +3 -0
  135. package/.next/standalone/.next/server/chunks/ssr/node_modules_9d52c0d6._.js +3 -0
  136. package/.next/standalone/.next/server/chunks/ssr/node_modules_@tanstack_query-core_build_modern_21ece5ea._.js +3 -0
  137. package/.next/standalone/.next/server/chunks/ssr/node_modules_ae6841d2._.js +17 -0
  138. package/.next/standalone/.next/server/chunks/ssr/node_modules_ba280bb0._.js +31 -0
  139. package/.next/standalone/.next/server/chunks/ssr/node_modules_bffdb8ec._.js +3 -0
  140. package/.next/standalone/.next/server/chunks/ssr/node_modules_c00f1821._.js +17 -0
  141. package/.next/standalone/.next/server/chunks/ssr/node_modules_c142ba86._.js +3 -0
  142. package/.next/standalone/.next/server/chunks/ssr/node_modules_d1a47cde._.js +17 -0
  143. package/.next/standalone/.next/server/chunks/ssr/node_modules_d9b454fe._.js +3 -0
  144. package/.next/standalone/.next/server/chunks/ssr/node_modules_dbe36b1d._.js +3 -0
  145. package/.next/standalone/.next/server/chunks/ssr/node_modules_ddbe26b7._.js +3 -0
  146. package/.next/standalone/.next/server/chunks/ssr/node_modules_e76b8bf2._.js +3 -0
  147. package/.next/standalone/.next/server/chunks/ssr/node_modules_e945b74d._.js +3 -0
  148. package/.next/standalone/.next/server/chunks/ssr/node_modules_fbd8a2ee._.js +17 -0
  149. package/.next/standalone/.next/server/chunks/ssr/node_modules_katex_dist_katex_mjs_31d456ba._.js +3 -0
  150. package/.next/standalone/.next/server/chunks/ssr/node_modules_katex_dist_katex_mjs_e1edc676._.js +3 -0
  151. package/.next/standalone/.next/server/chunks/ssr/node_modules_lodash-es_33e24dce._.js +3 -0
  152. package/.next/standalone/.next/server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_chunk-QXUST7PY_mjs_159fba97._.js +1 -1
  153. package/.next/standalone/.next/server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_chunk-S3R3BYOJ_mjs_dbeeb277._.js +1 -1
  154. package/.next/standalone/.next/server/chunks/ssr/node_modules_mermaid_dist_mermaid_core_mjs_a11916de._.js +9 -0
  155. package/.next/standalone/.next/server/chunks/ssr/src_66a70595._.js +3 -0
  156. package/.next/standalone/.next/server/chunks/ssr/src_components_kanban-board_tsx_7b875e8e._.js +1 -1
  157. package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
  158. package/.next/standalone/.next/server/pages/404.html +1 -1
  159. package/.next/standalone/.next/server/pages/500.html +2 -2
  160. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  161. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  162. package/.next/standalone/AGENTS.md +13 -7
  163. package/.next/standalone/CONTRIBUTING.md +42 -26
  164. package/.next/standalone/README.md +166 -25
  165. package/.next/standalone/bin/devflow.js +12 -5
  166. package/.next/standalone/bun.lock +78 -24
  167. package/.next/standalone/devflow/project-config.json +4 -0
  168. package/.next/standalone/devflow/schemas/api-first/schema.yaml +39 -0
  169. package/.next/standalone/devflow/schemas/api-first/templates/api-design.md +41 -0
  170. package/.next/standalone/devflow/schemas/api-first/templates/db-design.md +28 -0
  171. package/.next/standalone/devflow/schemas/api-first/templates/final-architecture.md +31 -0
  172. package/.next/standalone/devflow/schemas/api-first/templates/proposal.md +22 -0
  173. package/.next/standalone/devflow/schemas/api-first/templates/tasks.md +16 -0
  174. package/.next/standalone/devflow/specs/autodetect-skill-and-slash-command-installation/.approvals.json +1 -1
  175. package/.next/standalone/devflow/specs/autodetect-skill-and-slash-command-installation/.meta.json +1 -1
  176. package/.next/standalone/devflow/specs/autodetect-skill-and-slash-command-installation/design.md +11 -0
  177. package/.next/standalone/devflow/specs/autodetect-skill-and-slash-command-installation/proposal.md +3 -0
  178. package/.next/standalone/devflow/specs/autodetect-skill-and-slash-command-installation/tasks.md +34 -2
  179. package/.next/standalone/devflow/specs/precommit/.approvals.json +26 -0
  180. package/.next/standalone/devflow/specs/precommit/.meta.json +7 -0
  181. package/.next/standalone/devflow/specs/precommit/design.md +105 -0
  182. package/.next/standalone/devflow/specs/precommit/proposal.md +43 -0
  183. package/.next/standalone/devflow/specs/precommit/specs.md +89 -0
  184. package/.next/standalone/devflow/specs/precommit/tasks.md +283 -0
  185. package/.next/standalone/docs/custom-schemas.md +117 -0
  186. package/.next/standalone/docs/local-dev-guide.md +73 -0
  187. package/.next/standalone/drizzle.config.ts +7 -7
  188. package/.next/standalone/eslint.config.mjs +2 -2
  189. package/.next/standalone/instrumentation.ts +3 -5
  190. package/.next/standalone/next.config.ts +11 -2
  191. package/.next/standalone/node_modules/{sharp → libsql}/node_modules/detect-libc/package.json +4 -8
  192. package/.next/standalone/package-lock.json +5257 -2085
  193. package/.next/standalone/package.json +16 -7
  194. package/.next/standalone/postcss.config.mjs +1 -1
  195. package/.next/standalone/scripts/init-db.js +3 -5
  196. package/.next/standalone/scripts/init-db.test.js +6 -6
  197. package/.next/standalone/scripts/init-schema.js +22 -22
  198. package/.next/standalone/scripts/init-schema.test.js +45 -45
  199. package/.next/standalone/scripts/install-environments.js +27 -8
  200. package/.next/standalone/scripts/install-environments.test.js +19 -10
  201. package/.next/standalone/scripts/install-skills.js +104 -31
  202. package/.next/standalone/scripts/install-skills.test.js +6 -6
  203. package/.next/standalone/server.js +1 -1
  204. package/.next/standalone/src/app/api/agents/route.ts +2 -2
  205. package/.next/standalone/src/app/api/projects/[id]/route.ts +10 -19
  206. package/.next/standalone/src/app/api/projects/route.ts +4 -10
  207. package/.next/standalone/src/app/api/specs/[name]/artifacts/[artifactType]/approve/route.ts +8 -8
  208. package/.next/standalone/src/app/api/specs/[name]/artifacts/[artifactType]/route.ts +14 -14
  209. package/.next/standalone/src/app/api/specs/[name]/promote/route.ts +17 -23
  210. package/.next/standalone/src/app/api/specs/[name]/route.ts +34 -36
  211. package/.next/standalone/src/app/api/specs/route.ts +10 -10
  212. package/.next/standalone/src/app/api/tasks/[id]/route.ts +11 -33
  213. package/.next/standalone/src/app/api/tasks/route.ts +3 -6
  214. package/.next/standalone/src/app/globals.css +3 -3
  215. package/.next/standalone/src/app/layout.tsx +9 -5
  216. package/.next/standalone/src/app/page.tsx +1 -1
  217. package/.next/standalone/src/app/specs/[name]/page.tsx +26 -68
  218. package/.next/standalone/src/components/kanban-board.tsx +78 -157
  219. package/.next/standalone/src/components/kanban-column.tsx +10 -12
  220. package/.next/standalone/src/components/markdown-preview.tsx +36 -19
  221. package/.next/standalone/src/components/providers.tsx +20 -0
  222. package/.next/standalone/src/components/specs/artifact-dag-status.tsx +12 -14
  223. package/.next/standalone/src/components/specs/artifact-editor.tsx +55 -26
  224. package/.next/standalone/src/components/specs/spec-detail.tsx +48 -40
  225. package/.next/standalone/src/components/specs/spec-kanban-column.tsx +49 -68
  226. package/.next/standalone/src/components/specs/spec-modal.tsx +119 -83
  227. package/.next/standalone/src/components/task-card.tsx +34 -38
  228. package/.next/standalone/src/components/task-dialog.tsx +16 -31
  229. package/.next/standalone/src/components/ui/badge.tsx +12 -18
  230. package/.next/standalone/src/components/ui/button.tsx +23 -28
  231. package/.next/standalone/src/components/ui/card.tsx +42 -62
  232. package/.next/standalone/src/components/ui/dialog.tsx +17 -35
  233. package/.next/standalone/src/db/index.ts +10 -10
  234. package/.next/standalone/src/db/schema.ts +37 -37
  235. package/.next/standalone/src/hooks/use-queries.ts +81 -0
  236. package/.next/standalone/src/hooks/use-websocket.ts +74 -0
  237. package/.next/standalone/src/lib/schema.test.ts +37 -37
  238. package/.next/standalone/src/lib/schema.ts +77 -31
  239. package/.next/standalone/src/lib/specs-dir.ts +8 -8
  240. package/.next/standalone/src/lib/specs.ts +98 -92
  241. package/.next/standalone/src/lib/utils.ts +2 -2
  242. package/.next/standalone/src/mcp/server.ts +556 -349
  243. package/.next/standalone/src/mcp/websocket.ts +26 -23
  244. package/.next/standalone/src/schemas/backend-api/templates/proposal.md +6 -4
  245. package/.next/standalone/src/schemas/backend-api/templates/tasks.md +6 -0
  246. package/.next/standalone/src/schemas/data-engineering/templates/proposal.md +6 -4
  247. package/.next/standalone/src/schemas/data-engineering/templates/tasks.md +6 -0
  248. package/.next/standalone/src/schemas/devops-platform/templates/proposal.md +6 -4
  249. package/.next/standalone/src/schemas/devops-platform/templates/tasks.md +6 -0
  250. package/.next/standalone/src/schemas/frontend-product/templates/proposal.md +6 -4
  251. package/.next/standalone/src/schemas/frontend-product/templates/tasks.md +6 -0
  252. package/.next/standalone/src/schemas/spec-driven/templates/proposal.md +6 -4
  253. package/.next/standalone/src/schemas/spec-driven/templates/tasks.md +26 -0
  254. package/.next/standalone/src/websocket/server.ts +20 -18
  255. package/.next/standalone/tsconfig.json +3 -12
  256. package/.next/standalone/tsconfig.tsbuildinfo +1 -1
  257. package/.next/static/chunks/4f23f64d46848f57.js +1 -0
  258. package/.next/static/chunks/53081dcdcad4f31e.js +1 -0
  259. package/.next/static/chunks/{6a3d582315f1c214.js → 701cfcbb41e0ab47.js} +1 -1
  260. package/.next/static/chunks/ac4b6b4d5b7e486e.css +1 -0
  261. package/.next/static/chunks/d0309ea872db5d9f.js +1 -0
  262. package/.next/static/chunks/d4cf8893a018e965.js +1 -0
  263. package/.next/static/chunks/e6c0233269a4bd69.js +13 -0
  264. package/.next/static/chunks/{7e65cfa9841f66a5.js → e7d83ce855afe416.js} +2 -2
  265. package/.next/static/chunks/ee7035560fc9e5e9.js +1 -0
  266. package/.next/static/chunks/{turbopack-f4d3806ab575051d.js → turbopack-8b3b66a22a5e0fb4.js} +2 -2
  267. package/README.md +166 -25
  268. package/bin/devflow.js +12 -5
  269. package/drizzle.config.ts +7 -7
  270. package/next.config.ts +11 -2
  271. package/package.json +16 -7
  272. package/scripts/init-db.js +3 -5
  273. package/scripts/init-db.test.js +6 -6
  274. package/scripts/init-schema.js +22 -22
  275. package/scripts/init-schema.test.js +45 -45
  276. package/scripts/install-environments.js +27 -8
  277. package/scripts/install-environments.test.js +19 -10
  278. package/scripts/install-skills.js +104 -31
  279. package/scripts/install-skills.test.js +6 -6
  280. package/src/app/api/agents/route.ts +2 -2
  281. package/src/app/api/projects/[id]/route.ts +10 -19
  282. package/src/app/api/projects/route.ts +4 -10
  283. package/src/app/api/specs/[name]/artifacts/[artifactType]/approve/route.ts +8 -8
  284. package/src/app/api/specs/[name]/artifacts/[artifactType]/route.ts +14 -14
  285. package/src/app/api/specs/[name]/promote/route.ts +17 -23
  286. package/src/app/api/specs/[name]/route.ts +34 -36
  287. package/src/app/api/specs/route.ts +10 -10
  288. package/src/app/api/tasks/[id]/route.ts +11 -33
  289. package/src/app/api/tasks/route.ts +3 -6
  290. package/src/app/globals.css +3 -3
  291. package/src/app/layout.tsx +9 -5
  292. package/src/app/page.tsx +1 -1
  293. package/src/app/specs/[name]/page.tsx +26 -68
  294. package/src/components/kanban-board.tsx +78 -157
  295. package/src/components/kanban-column.tsx +10 -12
  296. package/src/components/markdown-preview.tsx +36 -19
  297. package/src/components/providers.tsx +20 -0
  298. package/src/components/specs/artifact-dag-status.tsx +12 -14
  299. package/src/components/specs/artifact-editor.tsx +55 -26
  300. package/src/components/specs/spec-detail.tsx +48 -40
  301. package/src/components/specs/spec-kanban-column.tsx +49 -68
  302. package/src/components/specs/spec-modal.tsx +119 -83
  303. package/src/components/task-card.tsx +34 -38
  304. package/src/components/task-dialog.tsx +16 -31
  305. package/src/components/ui/badge.tsx +12 -18
  306. package/src/components/ui/button.tsx +23 -28
  307. package/src/components/ui/card.tsx +42 -62
  308. package/src/components/ui/dialog.tsx +17 -35
  309. package/src/db/index.ts +10 -10
  310. package/src/db/schema.ts +37 -37
  311. package/src/hooks/use-queries.ts +81 -0
  312. package/src/hooks/use-websocket.ts +74 -0
  313. package/src/lib/schema.test.ts +37 -37
  314. package/src/lib/schema.ts +77 -31
  315. package/src/lib/specs-dir.ts +8 -8
  316. package/src/lib/specs.ts +98 -92
  317. package/src/lib/utils.ts +2 -2
  318. package/src/mcp/server.ts +556 -349
  319. package/src/mcp/websocket.ts +26 -23
  320. package/src/schemas/backend-api/templates/proposal.md +6 -4
  321. package/src/schemas/backend-api/templates/tasks.md +6 -0
  322. package/src/schemas/data-engineering/templates/proposal.md +6 -4
  323. package/src/schemas/data-engineering/templates/tasks.md +6 -0
  324. package/src/schemas/devops-platform/templates/proposal.md +6 -4
  325. package/src/schemas/devops-platform/templates/tasks.md +6 -0
  326. package/src/schemas/frontend-product/templates/proposal.md +6 -4
  327. package/src/schemas/frontend-product/templates/tasks.md +6 -0
  328. package/src/schemas/spec-driven/templates/proposal.md +6 -4
  329. package/src/schemas/spec-driven/templates/tasks.md +26 -0
  330. package/src/types/bun-sqlite.d.ts +1 -1
  331. package/src/websocket/server.ts +20 -18
  332. package/tsconfig.json +3 -12
  333. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1be4e4b6._.js +0 -3
  334. package/.next/standalone/.next/server/chunks/[root-of-the-server]__492a4a24._.js +0 -3
  335. package/.next/standalone/.next/server/chunks/[root-of-the-server]__67c59ae1._.js +0 -3
  336. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6cc7aecd._.js +0 -3
  337. package/.next/standalone/.next/server/chunks/[root-of-the-server]__83a77b07._.js +0 -3
  338. package/.next/standalone/.next/server/chunks/[root-of-the-server]__88d91cb5._.js +0 -3
  339. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a9e095e8._.js +0 -3
  340. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b367d327._.js +0 -3
  341. package/.next/standalone/.next/server/chunks/[root-of-the-server]__eb413bbc._.js +0 -3
  342. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0b8c072a._.js +0 -3
  343. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12b2191f._.js +0 -3
  344. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15316462._.js +0 -3
  345. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19c9c409._.js +0 -3
  346. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19e5e22f._.js +0 -3
  347. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__25b5ccb3._.js +0 -3
  348. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__2f78c3da._.js +0 -3
  349. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__3160b3f4._.js +0 -9
  350. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__319559be._.js +0 -3
  351. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__34f7cbcb._.js +0 -31
  352. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__3abab94b._.js +0 -3
  353. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__3b3d8930._.js +0 -3
  354. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__4250799b._.js +0 -3
  355. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__4c29cbc3._.js +0 -26
  356. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__4e0bb6eb._.js +0 -9
  357. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__5678d2e3._.js +0 -3
  358. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__673445e0._.js +0 -31
  359. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__934de06b._.js +0 -3
  360. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__9b6c6f09._.js +0 -3
  361. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__a1b83a98._.js +0 -3
  362. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__b00a15c5._.js +0 -3
  363. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__b8567be3._.js +0 -26
  364. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__ce64536e._.js +0 -45
  365. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__e96d33d2._.js +0 -45
  366. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__fd7ec054._.js +0 -3
  367. package/.next/standalone/.next/server/chunks/ssr/node_modules_16a3f9e7._.js +0 -17
  368. package/.next/standalone/.next/server/chunks/ssr/node_modules_45bce0e1._.js +0 -3
  369. package/.next/standalone/.next/server/chunks/ssr/node_modules_5e5a372d._.js +0 -17
  370. package/.next/standalone/.next/server/chunks/ssr/node_modules_6ece6f1e._.js +0 -3
  371. package/.next/standalone/.next/server/chunks/ssr/node_modules_d173e749._.js +0 -3
  372. package/.next/standalone/.next/server/chunks/ssr/node_modules_d3-shape_src_arc_fb1ac087.js +0 -3
  373. package/.next/standalone/.next/server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_1f73a830._.js +0 -3
  374. package/.next/standalone/.next/server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_663ac803._.js +0 -3
  375. package/.next/standalone/.next/server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_chunk-FMBD7UC4_mjs_4f485529._.js +0 -17
  376. package/.next/standalone/.next/server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_chunk-TZMSLE5B_mjs_8436a62a._.js +0 -3
  377. package/.next/standalone/.next/server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_f78d2dc4._.js +0 -3
  378. package/.next/standalone/.next/server/chunks/ssr/src_app_layout_tsx_cc8184fa._.js +0 -3
  379. package/.next/standalone/devflow/specs/add-default-schema-template-selection/.approvals.json +0 -26
  380. package/.next/standalone/devflow/specs/add-default-schema-template-selection/.meta.json +0 -8
  381. package/.next/standalone/devflow/specs/add-default-schema-template-selection/design.md +0 -126
  382. package/.next/standalone/devflow/specs/add-default-schema-template-selection/proposal.md +0 -65
  383. package/.next/standalone/devflow/specs/add-default-schema-template-selection/specs.md +0 -107
  384. package/.next/standalone/devflow/specs/add-default-schema-template-selection/tasks.md +0 -235
  385. package/.next/standalone/devflow/specs/test-no-project/.approvals.json +0 -17
  386. package/.next/standalone/devflow/specs/test-no-project/.meta.json +0 -6
  387. package/.next/standalone/devflow/specs/ui-cleanup/.approvals.json +0 -29
  388. package/.next/standalone/devflow/specs/ui-cleanup/.meta.json +0 -6
  389. package/.next/standalone/devflow/specs/ui-cleanup/design.md +0 -49
  390. package/.next/standalone/devflow/specs/ui-cleanup/proposal.md +0 -34
  391. package/.next/standalone/devflow/specs/ui-cleanup/specs.md +0 -55
  392. package/.next/standalone/devflow/specs/ui-cleanup/tasks.md +0 -28
  393. package/.next/standalone/node_modules/@img/colour/color.cjs +0 -1594
  394. package/.next/standalone/node_modules/@img/colour/index.cjs +0 -1
  395. package/.next/standalone/node_modules/@img/colour/package.json +0 -45
  396. package/.next/standalone/node_modules/@img/sharp-darwin-arm64/lib/sharp-darwin-arm64.node +0 -0
  397. package/.next/standalone/node_modules/@img/sharp-darwin-arm64/package.json +0 -40
  398. package/.next/standalone/node_modules/@img/sharp-libvips-darwin-arm64/README.md +0 -46
  399. package/.next/standalone/node_modules/@img/sharp-libvips-darwin-arm64/lib/glib-2.0/include/glibconfig.h +0 -220
  400. package/.next/standalone/node_modules/@img/sharp-libvips-darwin-arm64/lib/index.js +0 -1
  401. package/.next/standalone/node_modules/@img/sharp-libvips-darwin-arm64/lib/libvips-cpp.8.17.3.dylib +0 -0
  402. package/.next/standalone/node_modules/@img/sharp-libvips-darwin-arm64/package.json +0 -36
  403. package/.next/standalone/node_modules/@img/sharp-libvips-darwin-arm64/versions.json +0 -30
  404. package/.next/standalone/node_modules/buffer-from/index.js +0 -72
  405. package/.next/standalone/node_modules/buffer-from/package.json +0 -19
  406. package/.next/standalone/node_modules/sharp/lib/channel.js +0 -177
  407. package/.next/standalone/node_modules/sharp/lib/colour.js +0 -195
  408. package/.next/standalone/node_modules/sharp/lib/composite.js +0 -212
  409. package/.next/standalone/node_modules/sharp/lib/constructor.js +0 -499
  410. package/.next/standalone/node_modules/sharp/lib/index.js +0 -16
  411. package/.next/standalone/node_modules/sharp/lib/input.js +0 -809
  412. package/.next/standalone/node_modules/sharp/lib/is.js +0 -143
  413. package/.next/standalone/node_modules/sharp/lib/libvips.js +0 -207
  414. package/.next/standalone/node_modules/sharp/lib/operation.js +0 -1016
  415. package/.next/standalone/node_modules/sharp/lib/output.js +0 -1666
  416. package/.next/standalone/node_modules/sharp/lib/resize.js +0 -595
  417. package/.next/standalone/node_modules/sharp/lib/sharp.js +0 -121
  418. package/.next/standalone/node_modules/sharp/lib/utility.js +0 -291
  419. package/.next/standalone/node_modules/sharp/node_modules/detect-libc/lib/detect-libc.js +0 -313
  420. package/.next/standalone/node_modules/sharp/node_modules/detect-libc/lib/elf.js +0 -39
  421. package/.next/standalone/node_modules/sharp/node_modules/detect-libc/lib/filesystem.js +0 -51
  422. package/.next/standalone/node_modules/sharp/node_modules/detect-libc/lib/process.js +0 -24
  423. package/.next/standalone/node_modules/sharp/node_modules/semver/classes/comparator.js +0 -143
  424. package/.next/standalone/node_modules/sharp/node_modules/semver/classes/range.js +0 -557
  425. package/.next/standalone/node_modules/sharp/node_modules/semver/classes/semver.js +0 -333
  426. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/cmp.js +0 -54
  427. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/coerce.js +0 -62
  428. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/compare.js +0 -7
  429. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/eq.js +0 -5
  430. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/gt.js +0 -5
  431. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/gte.js +0 -5
  432. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/lt.js +0 -5
  433. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/lte.js +0 -5
  434. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/neq.js +0 -5
  435. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/parse.js +0 -18
  436. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/satisfies.js +0 -12
  437. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/constants.js +0 -37
  438. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/debug.js +0 -11
  439. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/identifiers.js +0 -29
  440. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/lrucache.js +0 -42
  441. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/parse-options.js +0 -17
  442. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/re.js +0 -223
  443. package/.next/standalone/node_modules/sharp/node_modules/semver/package.json +0 -78
  444. package/.next/standalone/node_modules/sharp/package.json +0 -202
  445. package/.next/standalone/node_modules/source-map/lib/array-set.js +0 -121
  446. package/.next/standalone/node_modules/source-map/lib/base64-vlq.js +0 -140
  447. package/.next/standalone/node_modules/source-map/lib/base64.js +0 -67
  448. package/.next/standalone/node_modules/source-map/lib/binary-search.js +0 -111
  449. package/.next/standalone/node_modules/source-map/lib/mapping-list.js +0 -79
  450. package/.next/standalone/node_modules/source-map/lib/quick-sort.js +0 -114
  451. package/.next/standalone/node_modules/source-map/lib/source-map-consumer.js +0 -1145
  452. package/.next/standalone/node_modules/source-map/lib/source-map-generator.js +0 -425
  453. package/.next/standalone/node_modules/source-map/lib/source-node.js +0 -413
  454. package/.next/standalone/node_modules/source-map/lib/util.js +0 -488
  455. package/.next/standalone/node_modules/source-map/package.json +0 -73
  456. package/.next/standalone/node_modules/source-map/source-map.js +0 -8
  457. package/.next/standalone/node_modules/source-map-support/LICENSE.md +0 -21
  458. package/.next/standalone/node_modules/source-map-support/README.md +0 -284
  459. package/.next/standalone/node_modules/source-map-support/browser-source-map-support.js +0 -114
  460. package/.next/standalone/node_modules/source-map-support/package.json +0 -31
  461. package/.next/standalone/node_modules/source-map-support/register-hook-require.js +0 -1
  462. package/.next/standalone/node_modules/source-map-support/register.js +0 -1
  463. package/.next/standalone/node_modules/source-map-support/source-map-support.js +0 -625
  464. package/.next/standalone/node_modules/typescript/lib/_tsc.js +0 -133818
  465. package/.next/standalone/node_modules/typescript/lib/_tsserver.js +0 -659
  466. package/.next/standalone/node_modules/typescript/lib/_typingsInstaller.js +0 -222
  467. package/.next/standalone/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +0 -2122
  468. package/.next/standalone/node_modules/typescript/lib/de/diagnosticMessages.generated.json +0 -2122
  469. package/.next/standalone/node_modules/typescript/lib/es/diagnosticMessages.generated.json +0 -2122
  470. package/.next/standalone/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +0 -2122
  471. package/.next/standalone/node_modules/typescript/lib/it/diagnosticMessages.generated.json +0 -2122
  472. package/.next/standalone/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +0 -2122
  473. package/.next/standalone/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +0 -2122
  474. package/.next/standalone/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +0 -2122
  475. package/.next/standalone/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +0 -2122
  476. package/.next/standalone/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +0 -2122
  477. package/.next/standalone/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +0 -2122
  478. package/.next/standalone/node_modules/typescript/lib/tsc.js +0 -8
  479. package/.next/standalone/node_modules/typescript/lib/tsserver.js +0 -8
  480. package/.next/standalone/node_modules/typescript/lib/tsserverlibrary.js +0 -21
  481. package/.next/standalone/node_modules/typescript/lib/typesMap.json +0 -497
  482. package/.next/standalone/node_modules/typescript/lib/typescript.js +0 -200276
  483. package/.next/standalone/node_modules/typescript/lib/typingsInstaller.js +0 -8
  484. package/.next/standalone/node_modules/typescript/lib/watchGuard.js +0 -53
  485. package/.next/standalone/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +0 -2122
  486. package/.next/standalone/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +0 -2122
  487. package/.next/standalone/node_modules/typescript/package.json +0 -120
  488. package/.next/standalone/src/components/ui/collapsible.tsx +0 -12
  489. package/.next/standalone/src/components/ui/sheet.tsx +0 -130
  490. package/.next/standalone/src/components/ui/tabs.tsx +0 -58
  491. package/.next/static/chunks/0177331b8adf7346.js +0 -7
  492. package/.next/static/chunks/06af74e2f3e207c5.js +0 -7
  493. package/.next/static/chunks/1748d5cd2443723b.css +0 -1
  494. package/.next/static/chunks/7ae917cb100be2b9.js +0 -7
  495. package/.next/static/chunks/7c4b901b394c3a8c.js +0 -7
  496. package/src/components/ui/collapsible.tsx +0 -12
  497. package/src/components/ui/sheet.tsx +0 -130
  498. package/src/components/ui/tabs.tsx +0 -58
  499. /package/.next/standalone/node_modules/{detect-libc → libsql/node_modules/detect-libc}/lib/detect-libc.js +0 -0
  500. /package/.next/standalone/node_modules/{detect-libc → libsql/node_modules/detect-libc}/lib/filesystem.js +0 -0
  501. /package/.next/standalone/node_modules/{detect-libc → libsql/node_modules/detect-libc}/lib/process.js +0 -0
  502. /package/.next/static/{5YFrdIQd1UU2IxLxekrU9 → Ql6qo0GYLL23WRu6ec4N5}/_buildManifest.js +0 -0
  503. /package/.next/static/{5YFrdIQd1UU2IxLxekrU9 → Ql6qo0GYLL23WRu6ec4N5}/_clientMiddlewareManifest.json +0 -0
  504. /package/.next/static/{5YFrdIQd1UU2IxLxekrU9 → Ql6qo0GYLL23WRu6ec4N5}/_ssgManifest.js +0 -0
package/src/lib/specs.ts CHANGED
@@ -1,13 +1,13 @@
1
- import * as fs from "fs";
2
- import * as path from "path";
3
- import { createHash } from "crypto";
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { createHash } from 'crypto';
4
4
  import {
5
5
  getSpecsDir,
6
6
  getSpecDir,
7
7
  getApprovalsPath,
8
8
  getMetaPath,
9
9
  getArtifactPath,
10
- } from "./specs-dir";
10
+ } from './specs-dir';
11
11
  import {
12
12
  loadSchema,
13
13
  computeSpecStatus,
@@ -15,8 +15,8 @@ import {
15
15
  type ApprovalsFile,
16
16
  type ArtifactStatus,
17
17
  type Schema,
18
- } from "./schema";
19
- import { getDb, schema as dbSchema } from "../db/index";
18
+ } from './schema';
19
+ import { getDb, schema as dbSchema } from '../db/index';
20
20
 
21
21
  export interface SpecMeta {
22
22
  name: string;
@@ -41,7 +41,7 @@ export interface ParsedTask {
41
41
 
42
42
  export interface ValidationFinding {
43
43
  code: string;
44
- severity: "error" | "warning";
44
+ severity: 'error' | 'warning';
45
45
  message: string;
46
46
  }
47
47
 
@@ -51,19 +51,19 @@ export interface ValidationReport {
51
51
  }
52
52
 
53
53
  function defaultApprovals(schema: Schema): ApprovalsFile {
54
- const artifacts: Record<string, { state: "draft" }> = {};
54
+ const artifacts: Record<string, { state: 'draft' }> = {};
55
55
  for (const artifact of schema.artifacts) {
56
- artifacts[artifact.id] = { state: "draft" };
56
+ artifacts[artifact.id] = { state: 'draft' };
57
57
  }
58
58
  return { version: 1, artifacts };
59
59
  }
60
60
 
61
61
  async function getSchema(specName: string): Promise<Schema> {
62
62
  const metaPath = getMetaPath(specName);
63
- let schemaName = "spec-driven";
63
+ let schemaName = 'spec-driven';
64
64
  if (fs.existsSync(metaPath)) {
65
- const meta = JSON.parse(fs.readFileSync(metaPath, "utf-8"));
66
- schemaName = meta.schema || "spec-driven";
65
+ const meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
66
+ schemaName = meta.schema || 'spec-driven';
67
67
  }
68
68
  return loadSchema(schemaName, getSpecsDir());
69
69
  }
@@ -76,10 +76,10 @@ export async function listSpecs(): Promise<SpecMeta[]> {
76
76
  const specs: SpecMeta[] = [];
77
77
 
78
78
  for (const entry of entries) {
79
- if (!entry.isDirectory() || entry.name === "archive") continue;
80
- const metaPath = path.join(specsDir, entry.name, ".meta.json");
79
+ if (!entry.isDirectory() || entry.name === 'archive') continue;
80
+ const metaPath = path.join(specsDir, entry.name, '.meta.json');
81
81
  if (fs.existsSync(metaPath)) {
82
- const meta = JSON.parse(fs.readFileSync(metaPath, "utf-8"));
82
+ const meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
83
83
  specs.push({ name: entry.name, ...meta });
84
84
  }
85
85
  }
@@ -93,8 +93,8 @@ export async function getSpec(specName: string): Promise<SpecDetail> {
93
93
  throw new Error(`Spec "${specName}" not found`);
94
94
  }
95
95
 
96
- const meta = JSON.parse(fs.readFileSync(metaPath, "utf-8")) as SpecMeta;
97
- const schema = await loadSchema(meta.schema || "spec-driven", getSpecsDir());
96
+ const meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8')) as SpecMeta;
97
+ const schema = await loadSchema(meta.schema || 'spec-driven', getSpecsDir());
98
98
  const approvals = await getApprovals(specName);
99
99
 
100
100
  const artifacts: Record<string, string | null> = {};
@@ -103,7 +103,7 @@ export async function getSpec(specName: string): Promise<SpecDetail> {
103
103
  for (const artifact of schema.artifacts) {
104
104
  const artifactPath = getArtifactPath(specName, artifact.id);
105
105
  if (fs.existsSync(artifactPath)) {
106
- artifacts[artifact.id] = fs.readFileSync(artifactPath, "utf-8");
106
+ artifacts[artifact.id] = fs.readFileSync(artifactPath, 'utf-8');
107
107
  artifactFiles[artifact.id] = true;
108
108
  } else {
109
109
  artifacts[artifact.id] = null;
@@ -125,13 +125,13 @@ export async function getSpec(specName: string): Promise<SpecDetail> {
125
125
  export async function getArtifact(specName: string, artifactType: string): Promise<string | null> {
126
126
  const artifactPath = getArtifactPath(specName, artifactType);
127
127
  if (!fs.existsSync(artifactPath)) return null;
128
- return fs.readFileSync(artifactPath, "utf-8");
128
+ return fs.readFileSync(artifactPath, 'utf-8');
129
129
  }
130
130
 
131
131
  export async function writeArtifact(
132
132
  specName: string,
133
133
  artifactType: string,
134
- content: string
134
+ content: string,
135
135
  ): Promise<void> {
136
136
  const specDir = getSpecDir(specName);
137
137
  if (!fs.existsSync(specDir)) {
@@ -139,14 +139,29 @@ export async function writeArtifact(
139
139
  }
140
140
 
141
141
  const artifactPath = getArtifactPath(specName, artifactType);
142
- fs.writeFileSync(artifactPath, content, "utf-8");
142
+ fs.writeFileSync(artifactPath, content, 'utf-8');
143
143
 
144
144
  // Auto-invalidate: if was approved, reset to draft
145
+ // But skip reset for "tasks" if tasks have already been promoted to Kanban
145
146
  const approvals = await getApprovals(specName);
146
147
  const existing = approvals.artifacts[artifactType];
147
- if (existing?.state === "approved") {
148
- approvals.artifacts[artifactType] = { state: "draft" };
149
- await writeApprovals(specName, approvals);
148
+ if (existing?.state === 'approved') {
149
+ let skipReset = false;
150
+ if (artifactType === 'tasks') {
151
+ const { getDb, schema: dbSchema } = await import('@/db');
152
+ const { eq } = await import('drizzle-orm');
153
+ const db = await getDb();
154
+ const promoted = await db
155
+ .select({ id: dbSchema.tasks.id })
156
+ .from(dbSchema.tasks)
157
+ .where(eq(dbSchema.tasks.specName, specName))
158
+ .limit(1);
159
+ skipReset = promoted.length > 0;
160
+ }
161
+ if (!skipReset) {
162
+ approvals.artifacts[artifactType] = { state: 'draft' };
163
+ await writeApprovals(specName, approvals);
164
+ }
150
165
  }
151
166
  }
152
167
 
@@ -156,18 +171,18 @@ export async function getApprovals(specName: string): Promise<ApprovalsFile> {
156
171
  const schema = await getSchema(specName);
157
172
  return defaultApprovals(schema);
158
173
  }
159
- return JSON.parse(fs.readFileSync(approvalsPath, "utf-8")) as ApprovalsFile;
174
+ return JSON.parse(fs.readFileSync(approvalsPath, 'utf-8')) as ApprovalsFile;
160
175
  }
161
176
 
162
177
  export async function writeApprovals(specName: string, approvals: ApprovalsFile): Promise<void> {
163
178
  const approvalsPath = getApprovalsPath(specName);
164
- fs.writeFileSync(approvalsPath, JSON.stringify(approvals, null, 2), "utf-8");
179
+ fs.writeFileSync(approvalsPath, JSON.stringify(approvals, null, 2), 'utf-8');
165
180
  }
166
181
 
167
182
  export async function approveArtifact(
168
183
  specName: string,
169
184
  artifactType: string,
170
- approvedBy: string
185
+ approvedBy: string,
171
186
  ): Promise<void> {
172
187
  const schema = await getSchema(specName);
173
188
  const artifactDef = schema.artifacts.find((a) => a.id === artifactType);
@@ -178,7 +193,7 @@ export async function approveArtifact(
178
193
  // Check blockers
179
194
  for (const req of artifactDef.requires) {
180
195
  const reqApproval = approvals.artifacts[req];
181
- if (!reqApproval || reqApproval.state !== "approved") {
196
+ if (!reqApproval || reqApproval.state !== 'approved') {
182
197
  throw new Error(`Cannot approve "${artifactType}": "${req}" must be approved first`);
183
198
  }
184
199
  }
@@ -188,9 +203,9 @@ export async function approveArtifact(
188
203
  throw new Error(`Cannot approve "${artifactType}": file does not exist`);
189
204
  }
190
205
 
191
- const contentHash = createHash("sha256").update(content).digest("hex");
206
+ const contentHash = createHash('sha256').update(content).digest('hex');
192
207
  approvals.artifacts[artifactType] = {
193
- state: "approved",
208
+ state: 'approved',
194
209
  approvedAt: new Date().toISOString(),
195
210
  contentHash,
196
211
  approvedBy,
@@ -201,7 +216,7 @@ export async function approveArtifact(
201
216
 
202
217
  export async function draftArtifact(specName: string, artifactType: string): Promise<void> {
203
218
  const approvals = await getApprovals(specName);
204
- approvals.artifacts[artifactType] = { state: "draft" };
219
+ approvals.artifacts[artifactType] = { state: 'draft' };
205
220
  await writeApprovals(specName, approvals);
206
221
  }
207
222
 
@@ -219,9 +234,9 @@ export async function getSpecStatus(specName: string): Promise<ArtifactStatus[]>
219
234
  }
220
235
 
221
236
  const PRIORITY_MAP: Record<string, string> = {
222
- p0: "high",
223
- p1: "medium",
224
- p2: "low",
237
+ p0: 'high',
238
+ p1: 'medium',
239
+ p2: 'low',
225
240
  };
226
241
 
227
242
  function normalizePriority(raw: string): string {
@@ -230,13 +245,13 @@ function normalizePriority(raw: string): string {
230
245
  }
231
246
 
232
247
  export async function parseTasksArtifact(specName: string): Promise<ParsedTask[]> {
233
- const content = await getArtifact(specName, "tasks");
248
+ const content = await getArtifact(specName, 'tasks');
234
249
  if (!content) return [];
235
250
 
236
251
  const taskHeaderRegex = /^#{2,4}\s+\d*\.?\d*\s*Task:\s*(.+)/m;
237
- const blocks = content.split(/(?=^#{2,4}\s+\d*\.?\d*\s*Task:\s*)/m).filter((b) =>
238
- taskHeaderRegex.test(b)
239
- );
252
+ const blocks = content
253
+ .split(/(?=^#{2,4}\s+\d*\.?\d*\s*Task:\s*)/m)
254
+ .filter((b) => taskHeaderRegex.test(b));
240
255
 
241
256
  const tasks: ParsedTask[] = [];
242
257
 
@@ -247,7 +262,7 @@ export async function parseTasksArtifact(specName: string): Promise<ParsedTask[]
247
262
  const title = headerMatch[1].trim();
248
263
 
249
264
  // Extract priority from **Priority:** metadata line
250
- let priority = "medium";
265
+ let priority = 'medium';
251
266
  const priorityMatch = block.match(/^\*\*Priority:\*\*\s*(.+)$/m);
252
267
  if (priorityMatch) {
253
268
  priority = normalizePriority(priorityMatch[1]);
@@ -272,38 +287,29 @@ export function fillTaskSummary(
272
287
  filesChanged?: string;
273
288
  issuesEncountered?: string;
274
289
  followUps?: string;
275
- }
290
+ },
276
291
  ): string {
277
292
  let result = body;
278
293
 
279
294
  // Replace the entire Task Summary section lines with filled values.
280
295
  // Handles both "- Key: <!-- placeholder -->" and bare "<!-- placeholder -->" patterns.
281
- result = result.replace(
282
- /^(- Completed:)\s*<!--.*?-->/gim,
283
- `$1 yes`
284
- );
285
- result = result.replace(
286
- /^(- What was done:)\s*<!--.*?-->/gim,
287
- `$1 ${summary.whatWasDone}`
288
- );
296
+ result = result.replace(/^(- Completed:)\s*<!--.*?-->/gim, `$1 yes`);
297
+ result = result.replace(/^(- What was done:)\s*<!--.*?-->/gim, `$1 ${summary.whatWasDone}`);
289
298
  result = result.replace(
290
299
  /^(- Files changed:)\s*<!--.*?-->/gim,
291
- `$1 ${summary.filesChanged ?? "N/A"}`
300
+ `$1 ${summary.filesChanged ?? 'N/A'}`,
292
301
  );
293
302
  result = result.replace(
294
303
  /^(- Issues encountered:)\s*<!--.*?-->/gim,
295
- `$1 ${summary.issuesEncountered ?? "None"}`
296
- );
297
- result = result.replace(
298
- /^(- Follow-ups:)\s*<!--.*?-->/gim,
299
- `$1 ${summary.followUps ?? "None"}`
304
+ `$1 ${summary.issuesEncountered ?? 'None'}`,
300
305
  );
306
+ result = result.replace(/^(- Follow-ups:)\s*<!--.*?-->/gim, `$1 ${summary.followUps ?? 'None'}`);
301
307
 
302
308
  // Fallback: bare <!-- what was done --> style comments (legacy)
303
309
  result = result.replace(/<!--\s*what was done\s*-->/gi, summary.whatWasDone);
304
- result = result.replace(/<!--\s*files changed\s*-->/gi, summary.filesChanged ?? "N/A");
305
- result = result.replace(/<!--\s*issues encountered\s*-->/gi, summary.issuesEncountered ?? "None");
306
- result = result.replace(/<!--\s*follow.?ups?\s*-->/gi, summary.followUps ?? "None");
310
+ result = result.replace(/<!--\s*files changed\s*-->/gi, summary.filesChanged ?? 'N/A');
311
+ result = result.replace(/<!--\s*issues encountered\s*-->/gi, summary.issuesEncountered ?? 'None');
312
+ result = result.replace(/<!--\s*follow.?ups?\s*-->/gi, summary.followUps ?? 'None');
307
313
 
308
314
  return result;
309
315
  }
@@ -311,13 +317,13 @@ export function fillTaskSummary(
311
317
  export async function updateTaskBodyInSpec(
312
318
  specName: string,
313
319
  taskTitle: string,
314
- newBody: string
320
+ newBody: string,
315
321
  ): Promise<void> {
316
322
  try {
317
- const artifactPath = getArtifactPath(specName, "tasks");
323
+ const artifactPath = getArtifactPath(specName, 'tasks');
318
324
  if (!fs.existsSync(artifactPath)) return;
319
325
 
320
- const content = fs.readFileSync(artifactPath, "utf-8");
326
+ const content = fs.readFileSync(artifactPath, 'utf-8');
321
327
  const taskHeaderRegex = /^#{2,4}\s+\d*\.?\d*\s*Task:\s*(.+)/m;
322
328
 
323
329
  // Split into blocks
@@ -328,21 +334,21 @@ export async function updateTaskBodyInSpec(
328
334
  const match = part.match(taskHeaderRegex);
329
335
  if (match && match[1].trim() === taskTitle) {
330
336
  replaced = true;
331
- return newBody + (part.endsWith("\n") ? "\n" : "");
337
+ return newBody + (part.endsWith('\n') ? '\n' : '');
332
338
  }
333
339
  return part;
334
340
  });
335
341
 
336
342
  if (!replaced) return;
337
343
 
338
- const newContent = newParts.join("");
339
- fs.writeFileSync(artifactPath, newContent, "utf-8");
344
+ const newContent = newParts.join('');
345
+ fs.writeFileSync(artifactPath, newContent, 'utf-8');
340
346
 
341
347
  // Reset approval to draft
342
348
  const approvals = await getApprovals(specName);
343
- const existing = approvals.artifacts["tasks"];
344
- if (existing?.state === "approved") {
345
- approvals.artifacts["tasks"] = { state: "draft" };
349
+ const existing = approvals.artifacts['tasks'];
350
+ if (existing?.state === 'approved') {
351
+ approvals.artifacts['tasks'] = { state: 'draft' };
346
352
  await writeApprovals(specName, approvals);
347
353
  }
348
354
  } catch {
@@ -355,7 +361,7 @@ export async function createSpec(
355
361
  title: string,
356
362
  projectId: string,
357
363
  description?: string,
358
- schemaName = "spec-driven"
364
+ schemaName = 'spec-driven',
359
365
  ): Promise<void> {
360
366
  const specDir = getSpecDir(specName);
361
367
  if (fs.existsSync(specDir)) {
@@ -373,7 +379,7 @@ export async function createSpec(
373
379
  createdAt: new Date().toISOString(),
374
380
  };
375
381
 
376
- fs.writeFileSync(getMetaPath(specName), JSON.stringify(meta, null, 2), "utf-8");
382
+ fs.writeFileSync(getMetaPath(specName), JSON.stringify(meta, null, 2), 'utf-8');
377
383
 
378
384
  const artifactSchema = await loadSchema(schemaName, getSpecsDir());
379
385
  await writeApprovals(specName, defaultApprovals(artifactSchema));
@@ -386,7 +392,7 @@ export async function createSpec(
386
392
  title,
387
393
  description: description ?? null,
388
394
  schema: schemaName,
389
- status: "active",
395
+ status: 'active',
390
396
  createdAt: new Date(),
391
397
  });
392
398
  }
@@ -400,52 +406,52 @@ export async function validateSpec(specName: string): Promise<ValidationReport>
400
406
  const content = await getArtifact(specName, artifact.id);
401
407
  if (!content) {
402
408
  findings.push({
403
- code: "ARTIFACT_MISSING",
404
- severity: "error",
409
+ code: 'ARTIFACT_MISSING',
410
+ severity: 'error',
405
411
  message: `Artifact "${artifact.id}" has not been created yet`,
406
412
  });
407
413
  continue;
408
414
  }
409
415
 
410
416
  const approval = approvals.artifacts[artifact.id];
411
- if (!approval || approval.state !== "approved") {
417
+ if (!approval || approval.state !== 'approved') {
412
418
  findings.push({
413
- code: "ARTIFACT_NOT_APPROVED",
414
- severity: "error",
419
+ code: 'ARTIFACT_NOT_APPROVED',
420
+ severity: 'error',
415
421
  message: `Artifact "${artifact.id}" exists but has not been approved`,
416
422
  });
417
423
  }
418
424
 
419
- if (artifact.id === "tasks") {
425
+ if (artifact.id === 'tasks') {
420
426
  const parsedTasks = await parseTasksArtifact(specName);
421
427
  if (parsedTasks.length === 0) {
422
428
  findings.push({
423
- code: "TASKS_EMPTY",
424
- severity: "error",
429
+ code: 'TASKS_EMPTY',
430
+ severity: 'error',
425
431
  message: 'tasks.md has no parseable "## Task:" entries',
426
432
  });
427
433
  }
428
434
  }
429
435
 
430
- if (artifact.id === "specs" && content) {
431
- if (!content.includes("### Requirement:")) {
436
+ if (artifact.id === 'specs' && content) {
437
+ if (!content.includes('### Requirement:')) {
432
438
  findings.push({
433
- code: "SPEC_NO_REQUIREMENTS",
434
- severity: "warning",
439
+ code: 'SPEC_NO_REQUIREMENTS',
440
+ severity: 'warning',
435
441
  message: 'specs.md has no "### Requirement:" headings',
436
442
  });
437
443
  }
438
- if (!content.includes("#### Scenario:")) {
444
+ if (!content.includes('#### Scenario:')) {
439
445
  findings.push({
440
- code: "SPEC_NO_SCENARIOS",
441
- severity: "warning",
446
+ code: 'SPEC_NO_SCENARIOS',
447
+ severity: 'warning',
442
448
  message: 'specs.md has no "#### Scenario:" headings',
443
449
  });
444
450
  }
445
451
  }
446
452
  }
447
453
 
448
- return { ok: findings.filter((f) => f.severity === "error").length === 0, findings };
454
+ return { ok: findings.filter((f) => f.severity === 'error').length === 0, findings };
449
455
  }
450
456
 
451
457
  export async function archiveSpec(specName: string): Promise<void> {
@@ -454,7 +460,7 @@ export async function archiveSpec(specName: string): Promise<void> {
454
460
  throw new Error(`Spec "${specName}" not found`);
455
461
  }
456
462
 
457
- const archiveDir = path.join(getSpecsDir(), "archive");
463
+ const archiveDir = path.join(getSpecsDir(), 'archive');
458
464
  fs.mkdirSync(archiveDir, { recursive: true });
459
465
 
460
466
  const archiveDest = path.join(archiveDir, specName);
@@ -462,14 +468,14 @@ export async function archiveSpec(specName: string): Promise<void> {
462
468
 
463
469
  // Update DB status
464
470
  const db = await getDb();
465
- const { eq } = await import("drizzle-orm");
466
- await db.update(dbSchema.specs).set({ status: "archived" }).where(eq(dbSchema.specs.name, specName));
471
+ const { eq } = await import('drizzle-orm');
472
+ await db
473
+ .update(dbSchema.specs)
474
+ .set({ status: 'archived' })
475
+ .where(eq(dbSchema.specs.name, specName));
467
476
  }
468
477
 
469
- export async function getArtifactTemplate(
470
- specName: string,
471
- artifactId: string
472
- ): Promise<string> {
478
+ export async function getArtifactTemplate(specName: string, artifactId: string): Promise<string> {
473
479
  const schema = await getSchema(specName);
474
480
  return resolveTemplate(schema, artifactId, getSpecsDir());
475
481
  }
package/src/lib/utils.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { type ClassValue, clsx } from "clsx";
2
- import { twMerge } from "tailwind-merge";
1
+ import { type ClassValue, clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
3
 
4
4
  export function cn(...inputs: ClassValue[]) {
5
5
  return twMerge(clsx(inputs));