@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
@@ -2,15 +2,11 @@
2
2
 
3
3
  const path = require('path');
4
4
  const fs = require('fs');
5
- const {
6
- parseTools,
7
- getToolAdapter,
8
- detectEnvironments,
9
- } = require('./install-environments');
5
+ const { parseTools, getToolAdapter, detectEnvironments } = require('./install-environments');
10
6
 
11
7
  const MANAGED_BEGIN = '<!-- DEVFLOW:BEGIN ';
12
8
  const MANAGED_END = '<!-- DEVFLOW:END ';
13
- const COMMAND_SET = ['new', 'continue', 'status', 'promote', 'develop', 'archive'];
9
+ const COMMAND_SET = ['new', 'continue', 'status', 'promote', 'develop', 'archive', 'schema'];
14
10
 
15
11
  function resolveToolDirs(projectRoot, tool) {
16
12
  return getToolAdapter(tool).resolveTargets(projectRoot);
@@ -138,6 +134,44 @@ function renderSkill(tool, command, markerId) {
138
134
  '4. Call `archive_spec`.',
139
135
  '5. Report success and the archive path.',
140
136
  ],
137
+ schema: [
138
+ `# Skill: /df:schema`,
139
+ '',
140
+ `Use this skill to interactively create a custom DevFlow schema in ${agentName}.`,
141
+ '',
142
+ '## Steps (in order)',
143
+ '',
144
+ '1. Call `list_schemas` and show the user what schemas are already available.',
145
+ ' If one fits their needs, suggest using it directly.',
146
+ '2. Ask what kind of project/workflow they need (e.g. mobile app, ML pipeline,',
147
+ ' infrastructure, documentation, data engineering, security review, etc.).',
148
+ '3. Based on the project type, ask which artifacts/documents their workflow',
149
+ ' should include. Suggest sensible defaults. Common options:',
150
+ ' - Proposal / RFC',
151
+ ' - Requirements / Specifications',
152
+ ' - Architecture / Design doc',
153
+ ' - Security review',
154
+ ' - Testing plan / Test strategy',
155
+ ' - Migration plan',
156
+ ' - Deployment / Runbook',
157
+ ' - Implementation tasks',
158
+ '4. Design the artifact dependency DAG — which artifacts must be approved',
159
+ ' before others can be written. Present the DAG to the user for confirmation.',
160
+ '5. Ask about quality rules:',
161
+ ' - RFC 2119 keywords enforced (MUST/SHOULD/MAY)?',
162
+ ' - Minimum scenarios per requirement (suggest 1-2)?',
163
+ '6. Generate well-structured markdown templates for each artifact.',
164
+ '7. Call `create_schema` with name, artifacts, qualityRules, apply, and templates.',
165
+ '8. Report the schema was created and how to use it:',
166
+ ' - `create_spec` with `schema: "<name>"`',
167
+ ' - Or set as default in `devflow/project-config.json`',
168
+ '',
169
+ '## Guidelines',
170
+ '- Keep artifact IDs short and kebab-case (e.g. "security-review", "test-plan")',
171
+ '- Template filenames should match: `<artifact-id>.md`',
172
+ '- Always include a final "tasks" artifact that depends on the key artifacts',
173
+ '- The `apply.requires` should include at minimum the tasks artifact',
174
+ ],
141
175
  };
142
176
 
143
177
  const lines = bodies[command];
@@ -147,9 +181,10 @@ function renderSkill(tool, command, markerId) {
147
181
 
148
182
  function renderCommand(tool, command, markerId) {
149
183
  const commandName = `/df:${command}`;
150
- const codexHeader = tool === 'codex'
151
- ? ['---', `description: DevFlow ${commandName} workflow action`, '---', '']
152
- : [];
184
+ const codexHeader =
185
+ tool === 'codex'
186
+ ? ['---', `description: DevFlow ${commandName} workflow action`, '---', '']
187
+ : [];
153
188
 
154
189
  const bodies = {
155
190
  new: [
@@ -262,6 +297,24 @@ function renderCommand(tool, command, markerId) {
262
297
  '4. Call `archive_spec`.',
263
298
  '5. Report success and the archive path.',
264
299
  ],
300
+ schema: [
301
+ `# ${commandName}`,
302
+ '',
303
+ 'Interactively create a custom DevFlow schema.',
304
+ '',
305
+ '## Steps (in order)',
306
+ '',
307
+ '1. Call `list_schemas` and show available schemas. If one fits, suggest it.',
308
+ '2. Ask what kind of project/workflow the user needs.',
309
+ '3. Ask which artifacts/documents their workflow should include.',
310
+ '4. Design the artifact dependency DAG. Present it for confirmation.',
311
+ '5. Ask about quality rules (RFC 2119, min scenarios per requirement).',
312
+ '6. Generate markdown templates for each artifact.',
313
+ '7. Call `create_schema` with name, artifacts, qualityRules, apply, and templates.',
314
+ '8. Report the schema was created and how to use it:',
315
+ ' - `create_spec` with `schema: "<name>"`',
316
+ ' - Or set as default in `devflow/project-config.json`',
317
+ ],
265
318
  };
266
319
 
267
320
  const bodyLines = bodies[command];
@@ -273,7 +326,7 @@ function replaceManagedSection(existing, markerId, nextContent) {
273
326
  const escaped = markerId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
274
327
  const pattern = new RegExp(
275
328
  `<!-- DEVFLOW:BEGIN ${escaped} -->[\\s\\S]*?<!-- DEVFLOW:END ${escaped} -->\\n?`,
276
- 'm'
329
+ 'm',
277
330
  );
278
331
  if (!pattern.test(existing)) return null;
279
332
  return existing.replace(pattern, nextContent);
@@ -300,7 +353,9 @@ function buildAssets(projectRoot, tools, delivery) {
300
353
  const commandMarker = `${tool}:command:df-${command}`;
301
354
  if (delivery !== 'commands') {
302
355
  assets.push({
303
- tool, kind: 'skill', command,
356
+ tool,
357
+ kind: 'skill',
358
+ command,
304
359
  outputPath: path.join(dirs.skillsDir, `df-${command}.md`),
305
360
  markerId: skillMarker,
306
361
  content: renderSkill(tool, command, skillMarker),
@@ -308,7 +363,9 @@ function buildAssets(projectRoot, tools, delivery) {
308
363
  }
309
364
  if (delivery !== 'skills') {
310
365
  assets.push({
311
- tool, kind: 'command', command,
366
+ tool,
367
+ kind: 'command',
368
+ command,
312
369
  outputPath: path.join(dirs.commandsDir, `df-${command}.md`),
313
370
  markerId: commandMarker,
314
371
  content: renderCommand(tool, command, commandMarker),
@@ -329,7 +386,7 @@ function selectTools(projectRoot, options) {
329
386
  } else if (options.tools !== undefined) {
330
387
  selectedTools = parseTools(options.tools);
331
388
  } else if (autodetect) {
332
- selectedTools = detection.filter(d => d.detected).map(d => d.id);
389
+ selectedTools = detection.filter((d) => d.detected).map((d) => d.id);
333
390
  } else {
334
391
  selectedTools = parseTools('all');
335
392
  }
@@ -354,17 +411,17 @@ function installSkills(projectRoot, options = {}) {
354
411
  dryRun,
355
412
  autodetect: selection.autodetect,
356
413
  selectedTools: selection.selectedTools,
357
- environments: selection.detection.map(d => ({
414
+ environments: selection.detection.map((d) => ({
358
415
  tool: d.id,
359
416
  detected: d.detected,
360
- status: selection.selectedTools.includes(d.id)
361
- ? (dryRun ? 'planned' : 'pending')
362
- : 'skipped',
417
+ status: selection.selectedTools.includes(d.id) ? (dryRun ? 'planned' : 'pending') : 'skipped',
363
418
  reason: selection.selectedTools.includes(d.id)
364
419
  ? undefined
365
- : (selection.autodetect && options.tools === undefined && !options.only
366
- ? (d.detected ? 'not-selected' : 'not-detected')
367
- : 'not-selected'),
420
+ : selection.autodetect && options.tools === undefined && !options.only
421
+ ? d.detected
422
+ ? 'not-selected'
423
+ : 'not-detected'
424
+ : 'not-selected',
368
425
  created: 0,
369
426
  updated: 0,
370
427
  skipped: 0,
@@ -378,7 +435,7 @@ function installSkills(projectRoot, options = {}) {
378
435
 
379
436
  for (const asset of assets) {
380
437
  const { outputPath, markerId, content, tool } = asset;
381
- const envReport = report.environments.find(e => e.tool === tool);
438
+ const envReport = report.environments.find((e) => e.tool === tool);
382
439
  const displayPath = path.relative(projectRoot, outputPath);
383
440
  try {
384
441
  const alreadyExists = exists(outputPath);
@@ -393,7 +450,11 @@ function installSkills(projectRoot, options = {}) {
393
450
  }
394
451
  report.updated++;
395
452
  if (envReport) envReport.updated++;
396
- report.results.push({ ...asset, path: displayPath, action: dryRun ? 'would_update' : 'updated' });
453
+ report.results.push({
454
+ ...asset,
455
+ path: displayPath,
456
+ action: dryRun ? 'would_update' : 'updated',
457
+ });
397
458
  } else {
398
459
  report.skipped++;
399
460
  if (envReport) envReport.skipped++;
@@ -403,7 +464,7 @@ function installSkills(projectRoot, options = {}) {
403
464
  }
404
465
 
405
466
  const ownershipError = new Error(
406
- `Refusing to modify unmanaged file for ${tool}: ${displayPath}`
467
+ `Refusing to modify unmanaged file for ${tool}: ${displayPath}`,
407
468
  );
408
469
  ownershipError.code = 'UNMANAGED_FILE';
409
470
  throw ownershipError;
@@ -414,7 +475,11 @@ function installSkills(projectRoot, options = {}) {
414
475
  }
415
476
  report.created++;
416
477
  if (envReport) envReport.created++;
417
- report.results.push({ ...asset, path: displayPath, action: dryRun ? 'would_create' : 'created' });
478
+ report.results.push({
479
+ ...asset,
480
+ path: displayPath,
481
+ action: dryRun ? 'would_create' : 'created',
482
+ });
418
483
  } catch (error) {
419
484
  report.failed++;
420
485
  if (envReport) envReport.failed++;
@@ -432,7 +497,8 @@ function installSkills(projectRoot, options = {}) {
432
497
  if (!selection.selectedTools.includes(envReport.tool)) continue;
433
498
  if (envReport.failed > 0) {
434
499
  envReport.status = 'failed';
435
- envReport.reason = envReport.created + envReport.updated > 0 ? 'partial-failure' : 'install-failed';
500
+ envReport.reason =
501
+ envReport.created + envReport.updated > 0 ? 'partial-failure' : 'install-failed';
436
502
  } else if (dryRun) {
437
503
  envReport.status = 'planned';
438
504
  } else {
@@ -449,22 +515,29 @@ function printReport(report) {
449
515
  for (const env of report.environments) {
450
516
  const statusDetails = env.reason ? `${env.status} (${env.reason})` : env.status;
451
517
  const detectedText = env.detected ? 'detected' : 'not detected';
452
- console.log(` - ${env.tool}: ${statusDetails}; ${detectedText}; created=${env.created} updated=${env.updated} skipped=${env.skipped} failed=${env.failed}`);
518
+ console.log(
519
+ ` - ${env.tool}: ${statusDetails}; ${detectedText}; created=${env.created} updated=${env.updated} skipped=${env.skipped} failed=${env.failed}`,
520
+ );
453
521
  }
454
522
  console.log('');
455
523
  }
456
524
 
457
525
  for (const r of report.results) {
458
526
  const icon =
459
- r.action === 'created' || r.action === 'would_create' ? '✓' :
460
- r.action === 'updated' || r.action === 'would_update' ? '' :
461
- r.action === 'failed' ? '' :
462
- '';
527
+ r.action === 'created' || r.action === 'would_create'
528
+ ? ''
529
+ : r.action === 'updated' || r.action === 'would_update'
530
+ ? ''
531
+ : r.action === 'failed'
532
+ ? '✗'
533
+ : '–';
463
534
  const errorSuffix = r.action === 'failed' ? ` - ${r.error}` : '';
464
535
  console.log(` ${icon} [${r.tool}] ${r.kind} ${r.path} (${r.action})${errorSuffix}`);
465
536
  }
466
537
  const mode = report.dryRun ? ' (dry-run)' : '';
467
- console.log(`\n ${report.created} created, ${report.updated} updated, ${report.skipped} skipped, ${report.failed} failed${mode}`);
538
+ console.log(
539
+ `\n ${report.created} created, ${report.updated} updated, ${report.skipped} skipped, ${report.failed} failed${mode}`,
540
+ );
468
541
  }
469
542
 
470
543
  // CLI usage: node scripts/install-skills.js [--tools all|codex|claudecode] [--delivery both|skills|commands] [--force]
@@ -82,7 +82,7 @@ test('installer refuses to overwrite unmanaged files even with force', () => {
82
82
  });
83
83
 
84
84
  assert.ok(report.failed >= 1);
85
- const failedNewSkill = report.results.find(r => r.path.endsWith('.codex/skills/df-new.md'));
85
+ const failedNewSkill = report.results.find((r) => r.path.endsWith('.codex/skills/df-new.md'));
86
86
  assert.ok(failedNewSkill);
87
87
  assert.equal(failedNewSkill.errorCode, 'UNMANAGED_FILE');
88
88
  assert.equal(fs.readFileSync(target, 'utf-8'), '# user owned file\n');
@@ -106,8 +106,8 @@ test('installer autodetect default installs only detected environments', () => {
106
106
  });
107
107
 
108
108
  assert.deepEqual(report.selectedTools, ['codex']);
109
- const codexSummary = report.environments.find(e => e.tool === 'codex');
110
- const claudeSummary = report.environments.find(e => e.tool === 'claudecode');
109
+ const codexSummary = report.environments.find((e) => e.tool === 'codex');
110
+ const claudeSummary = report.environments.find((e) => e.tool === 'claudecode');
111
111
  assert.equal(codexSummary.status, 'installed');
112
112
  assert.equal(claudeSummary.status, 'skipped');
113
113
  assert.equal(claudeSummary.reason, 'not-detected');
@@ -128,7 +128,7 @@ test('dry-run reports planned actions without writing files', () => {
128
128
  });
129
129
  assert.equal(report.dryRun, true);
130
130
  assert.ok(report.created > 0);
131
- assert.ok(report.results.some(r => r.action === 'would_create'));
131
+ assert.ok(report.results.some((r) => r.action === 'would_create'));
132
132
  const expectedPath = path.join(projectRoot, '.codex', 'skills', 'df-new.md');
133
133
  assert.equal(fs.existsSync(expectedPath), false);
134
134
  });
@@ -152,8 +152,8 @@ test('disabling autodetect targets all supported tools by default', () => {
152
152
  });
153
153
 
154
154
  assert.deepEqual(report.selectedTools.sort(), ['claudecode', 'codex']);
155
- const codexSummary = report.environments.find(e => e.tool === 'codex');
156
- const claudeSummary = report.environments.find(e => e.tool === 'claudecode');
155
+ const codexSummary = report.environments.find((e) => e.tool === 'codex');
156
+ const claudeSummary = report.environments.find((e) => e.tool === 'claudecode');
157
157
  assert.equal(codexSummary.status, 'installed');
158
158
  assert.equal(claudeSummary.status, 'installed');
159
159
  });
@@ -9,7 +9,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
9
9
  const hostname = process.env.HOSTNAME || '0.0.0.0'
10
10
 
11
11
  let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
12
- const nextConfig = {"distDir":"./.next","cacheComponents":false,"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","assetPrefix":"","output":"standalone","trailingSlash":false,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":false},"reactMaxHeadersLength":6000,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"basePath":"","expireTime":31536000,"generateEtags":true,"poweredByHeader":true,"cacheHandlers":{},"cacheMaxMemorySize":52428800,"compress":true,"i18n":null,"httpAgentOptions":{"keepAlive":true},"pageExtensions":["tsx","ts","jsx","js"],"useFileSystemPublicRoutes":true,"experimental":{"ppr":false,"staleTimes":{"dynamic":0,"static":300},"dynamicOnHover":false,"inlineCss":false,"authInterrupts":false,"fetchCacheKeyPrefix":"","isrFlushToDisk":true,"optimizeCss":false,"nextScriptWorkers":false,"disableOptimizedLoading":false,"largePageDataBytes":128000,"serverComponentsHmrCache":true,"caseSensitiveRoutes":false,"validateRSCRequestHeaders":false,"useSkewCookie":false,"preloadEntriesOnStart":true,"hideLogsAfterAbort":false,"removeUncaughtErrorAndRejectionListeners":false,"imgOptConcurrency":null,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"imgOptTimeoutInSeconds":7,"proxyClientMaxBodySize":10485760,"trustHostHeader":false,"isExperimentalCompile":false}}
12
+ const nextConfig = {"distDir":"./.next","cacheComponents":false,"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","assetPrefix":"","output":"standalone","trailingSlash":false,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true},"reactMaxHeadersLength":6000,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"basePath":"","expireTime":31536000,"generateEtags":true,"poweredByHeader":true,"cacheHandlers":{},"cacheMaxMemorySize":52428800,"compress":true,"i18n":null,"httpAgentOptions":{"keepAlive":true},"pageExtensions":["tsx","ts","jsx","js"],"useFileSystemPublicRoutes":true,"experimental":{"ppr":false,"staleTimes":{"dynamic":0,"static":300},"dynamicOnHover":false,"inlineCss":false,"authInterrupts":false,"fetchCacheKeyPrefix":"","isrFlushToDisk":true,"optimizeCss":false,"nextScriptWorkers":false,"disableOptimizedLoading":false,"largePageDataBytes":128000,"serverComponentsHmrCache":true,"caseSensitiveRoutes":false,"validateRSCRequestHeaders":false,"useSkewCookie":false,"preloadEntriesOnStart":true,"hideLogsAfterAbort":false,"removeUncaughtErrorAndRejectionListeners":false,"imgOptConcurrency":null,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"imgOptTimeoutInSeconds":7,"proxyClientMaxBodySize":10485760,"trustHostHeader":false,"isExperimentalCompile":false}}
13
13
 
14
14
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
15
15
 
@@ -1,5 +1,5 @@
1
- import { NextResponse } from "next/server";
2
- import { getAgentCount, getAgentList } from "@/websocket/server";
1
+ import { NextResponse } from 'next/server';
2
+ import { getAgentCount, getAgentList } from '@/websocket/server';
3
3
 
4
4
  export async function GET() {
5
5
  const agents = getAgentList();
@@ -1,11 +1,8 @@
1
- import { NextResponse } from "next/server";
2
- import { getDb, schema } from "@/db";
3
- import { eq } from "drizzle-orm";
1
+ import { NextResponse } from 'next/server';
2
+ import { getDb, schema } from '@/db';
3
+ import { eq } from 'drizzle-orm';
4
4
 
5
- export async function DELETE(
6
- request: Request,
7
- { params }: { params: Promise<{ id: string }> }
8
- ) {
5
+ export async function DELETE(request: Request, { params }: { params: Promise<{ id: string }> }) {
9
6
  try {
10
7
  const { id } = await params;
11
8
  const db = await getDb();
@@ -17,7 +14,7 @@ export async function DELETE(
17
14
  .limit(1);
18
15
 
19
16
  if (project.length === 0) {
20
- return NextResponse.json({ error: "Project not found" }, { status: 404 });
17
+ return NextResponse.json({ error: 'Project not found' }, { status: 404 });
21
18
  }
22
19
 
23
20
  const projectTasks = await db
@@ -34,18 +31,15 @@ export async function DELETE(
34
31
 
35
32
  return NextResponse.json({ success: true });
36
33
  } catch (error) {
37
- console.error("Delete project error:", error);
34
+ console.error('Delete project error:', error);
38
35
  return NextResponse.json(
39
- { error: "Failed to delete project", details: String(error) },
40
- { status: 500 }
36
+ { error: 'Failed to delete project', details: String(error) },
37
+ { status: 500 },
41
38
  );
42
39
  }
43
40
  }
44
41
 
45
- export async function PATCH(
46
- request: Request,
47
- { params }: { params: Promise<{ id: string }> }
48
- ) {
42
+ export async function PATCH(request: Request, { params }: { params: Promise<{ id: string }> }) {
49
43
  try {
50
44
  const { id } = await params;
51
45
  const body = await request.json();
@@ -67,9 +61,6 @@ export async function PATCH(
67
61
 
68
62
  return NextResponse.json(updatedProject[0]);
69
63
  } catch (error) {
70
- return NextResponse.json(
71
- { error: "Failed to update project" },
72
- { status: 500 }
73
- );
64
+ return NextResponse.json({ error: 'Failed to update project' }, { status: 500 });
74
65
  }
75
66
  }
@@ -1,18 +1,12 @@
1
- import { NextResponse } from "next/server";
2
- import { getDb, schema } from "@/db";
1
+ import { NextResponse } from 'next/server';
2
+ import { getDb, schema } from '@/db';
3
3
 
4
4
  export async function GET() {
5
5
  try {
6
6
  const db = await getDb();
7
- const projects = await db
8
- .select()
9
- .from(schema.projects)
10
- .orderBy(schema.projects.createdAt);
7
+ const projects = await db.select().from(schema.projects).orderBy(schema.projects.createdAt);
11
8
  return NextResponse.json(projects);
12
9
  } catch (error) {
13
- return NextResponse.json(
14
- { error: "Failed to fetch projects" },
15
- { status: 500 }
16
- );
10
+ return NextResponse.json({ error: 'Failed to fetch projects' }, { status: 500 });
17
11
  }
18
12
  }
@@ -1,23 +1,23 @@
1
- import { NextResponse } from "next/server";
2
- import { approveArtifact } from "@/lib/specs";
3
- import { broadcastUpdate } from "@/mcp/websocket";
1
+ import { NextResponse } from 'next/server';
2
+ import { approveArtifact } from '@/lib/specs';
3
+ import { broadcastUpdate } from '@/mcp/websocket';
4
4
 
5
5
  export async function POST(
6
6
  request: Request,
7
- { params }: { params: Promise<{ name: string; artifactType: string }> }
7
+ { params }: { params: Promise<{ name: string; artifactType: string }> },
8
8
  ) {
9
9
  try {
10
10
  const { name, artifactType } = await params;
11
11
  const body = await request.json();
12
- const approvedBy = body.approvedBy || "human";
12
+ const approvedBy = body.approvedBy || 'human';
13
13
 
14
14
  await approveArtifact(name, artifactType, approvedBy);
15
- broadcastUpdate({ type: "artifact_approved", specName: name, artifactType });
15
+ broadcastUpdate({ type: 'artifact_approved', specName: name, artifactType });
16
16
  return NextResponse.json({ success: true });
17
17
  } catch (error) {
18
18
  return NextResponse.json(
19
- { error: error instanceof Error ? error.message : "Failed to approve artifact" },
20
- { status: 422 }
19
+ { error: error instanceof Error ? error.message : 'Failed to approve artifact' },
20
+ { status: 422 },
21
21
  );
22
22
  }
23
23
  }
@@ -1,36 +1,36 @@
1
- import { NextResponse } from "next/server";
2
- import { getArtifact, writeArtifact, getSpecStatus, getArtifactTemplate } from "@/lib/specs";
3
- import { broadcastUpdate } from "@/mcp/websocket";
1
+ import { NextResponse } from 'next/server';
2
+ import { getArtifact, writeArtifact, getSpecStatus, getArtifactTemplate } from '@/lib/specs';
3
+ import { broadcastUpdate } from '@/mcp/websocket';
4
4
 
5
5
  export async function GET(
6
6
  request: Request,
7
- { params }: { params: Promise<{ name: string; artifactType: string }> }
7
+ { params }: { params: Promise<{ name: string; artifactType: string }> },
8
8
  ) {
9
9
  try {
10
10
  const { name, artifactType } = await params;
11
11
  const { searchParams } = new URL(request.url);
12
12
 
13
- if (searchParams.get("template") === "true") {
13
+ if (searchParams.get('template') === 'true') {
14
14
  const template = await getArtifactTemplate(name, artifactType);
15
15
  return NextResponse.json({ template });
16
16
  }
17
17
 
18
18
  const content = await getArtifact(name, artifactType);
19
19
  if (content === null) {
20
- return NextResponse.json({ error: "Artifact not found" }, { status: 404 });
20
+ return NextResponse.json({ error: 'Artifact not found' }, { status: 404 });
21
21
  }
22
22
  return NextResponse.json({ content });
23
23
  } catch (error) {
24
24
  return NextResponse.json(
25
- { error: error instanceof Error ? error.message : "Failed to get artifact" },
26
- { status: 500 }
25
+ { error: error instanceof Error ? error.message : 'Failed to get artifact' },
26
+ { status: 500 },
27
27
  );
28
28
  }
29
29
  }
30
30
 
31
31
  export async function PUT(
32
32
  request: Request,
33
- { params }: { params: Promise<{ name: string; artifactType: string }> }
33
+ { params }: { params: Promise<{ name: string; artifactType: string }> },
34
34
  ) {
35
35
  try {
36
36
  const { name, artifactType } = await params;
@@ -38,21 +38,21 @@ export async function PUT(
38
38
  // Check blocker gate
39
39
  const statuses = await getSpecStatus(name);
40
40
  const status = statuses.find((s) => s.id === artifactType);
41
- if (status?.state === "blocked") {
41
+ if (status?.state === 'blocked') {
42
42
  return NextResponse.json(
43
43
  { error: `Cannot write "${artifactType}": required artifacts not yet approved` },
44
- { status: 422 }
44
+ { status: 422 },
45
45
  );
46
46
  }
47
47
 
48
48
  const body = await request.json();
49
49
  await writeArtifact(name, artifactType, body.content);
50
- broadcastUpdate({ type: "artifact_updated", specName: name, artifactType });
50
+ broadcastUpdate({ type: 'artifact_updated', specName: name, artifactType });
51
51
  return NextResponse.json({ success: true });
52
52
  } catch (error) {
53
53
  return NextResponse.json(
54
- { error: error instanceof Error ? error.message : "Failed to write artifact" },
55
- { status: 500 }
54
+ { error: error instanceof Error ? error.message : 'Failed to write artifact' },
55
+ { status: 500 },
56
56
  );
57
57
  }
58
58
  }
@@ -1,13 +1,10 @@
1
- import { NextResponse } from "next/server";
2
- import { parseTasksArtifact, getApprovals, getSpec } from "@/lib/specs";
3
- import { getDb, schema } from "@/db";
4
- import { randomUUID } from "crypto";
5
- import { broadcastUpdate } from "@/mcp/websocket";
1
+ import { NextResponse } from 'next/server';
2
+ import { parseTasksArtifact, getApprovals, getSpec } from '@/lib/specs';
3
+ import { getDb, schema } from '@/db';
4
+ import { randomUUID } from 'crypto';
5
+ import { broadcastUpdate } from '@/mcp/websocket';
6
6
 
7
- export async function POST(
8
- _request: Request,
9
- { params }: { params: Promise<{ name: string }> }
10
- ) {
7
+ export async function POST(_request: Request, { params }: { params: Promise<{ name: string }> }) {
11
8
  try {
12
9
  const { name } = await params;
13
10
 
@@ -15,26 +12,23 @@ export async function POST(
15
12
  const projectId = spec.projectId;
16
13
  if (!projectId) {
17
14
  return NextResponse.json(
18
- { error: "Spec has no project — re-create it with a projectId" },
19
- { status: 422 }
15
+ { error: 'Spec has no project — re-create it with a projectId' },
16
+ { status: 422 },
20
17
  );
21
18
  }
22
19
 
23
20
  // Check tasks artifact is approved
24
21
  const approvals = await getApprovals(name);
25
- if (approvals.artifacts["tasks"]?.state !== "approved") {
22
+ if (approvals.artifacts['tasks']?.state !== 'approved') {
26
23
  return NextResponse.json(
27
- { error: "tasks artifact must be approved before promoting" },
28
- { status: 422 }
24
+ { error: 'tasks artifact must be approved before promoting' },
25
+ { status: 422 },
29
26
  );
30
27
  }
31
28
 
32
29
  const parsedTasks = await parseTasksArtifact(name);
33
30
  if (parsedTasks.length === 0) {
34
- return NextResponse.json(
35
- { error: "No tasks found in tasks.md" },
36
- { status: 422 }
37
- );
31
+ return NextResponse.json({ error: 'No tasks found in tasks.md' }, { status: 422 });
38
32
  }
39
33
 
40
34
  const db = await getDb();
@@ -44,20 +38,20 @@ export async function POST(
44
38
  specName: name,
45
39
  title: task.title,
46
40
  body: task.body || null,
47
- status: "backlog" as const,
48
- priority: (task.priority || "medium") as "low" | "medium" | "high" | "urgent",
41
+ status: 'backlog' as const,
42
+ priority: (task.priority || 'medium') as 'low' | 'medium' | 'high' | 'urgent',
49
43
  assignedAgent: null,
50
44
  order: index,
51
45
  }));
52
46
 
53
47
  await db.insert(schema.tasks).values(newTasks);
54
- broadcastUpdate({ type: "spec_promoted", specName: name, taskCount: newTasks.length });
48
+ broadcastUpdate({ type: 'spec_promoted', specName: name, taskCount: newTasks.length });
55
49
 
56
50
  return NextResponse.json({ promoted: newTasks.length, tasks: newTasks });
57
51
  } catch (error) {
58
52
  return NextResponse.json(
59
- { error: error instanceof Error ? error.message : "Failed to promote spec" },
60
- { status: 500 }
53
+ { error: error instanceof Error ? error.message : 'Failed to promote spec' },
54
+ { status: 500 },
61
55
  );
62
56
  }
63
57
  }