@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
@@ -1,15 +1,15 @@
1
- "use client";
1
+ 'use client';
2
2
 
3
- import { useState, useEffect } from "react";
4
- import { X, FileText, ChevronRight, CheckCircle2, Circle, Clock, Lock } from "lucide-react";
5
- import { ArtifactEditor } from "./artifact-editor";
6
- import { ArtifactDagStatus } from "./artifact-dag-status";
7
- import { Button } from "@/components/ui/button";
8
- import { MarkdownPreview } from "@/components/markdown-preview";
3
+ import { useState } from 'react';
4
+ import { X, FileText, ChevronRight, CheckCircle2, Circle, Clock, Lock } from 'lucide-react';
5
+ import { ArtifactEditor } from './artifact-editor';
6
+ import { ArtifactDagStatus } from './artifact-dag-status';
7
+ import { Button } from '@/components/ui/button';
8
+ import { useSpec, useInvalidate } from '@/hooks/use-queries';
9
9
 
10
10
  interface ArtifactStatus {
11
11
  id: string;
12
- state: "blocked" | "ready" | "in_review" | "in_progress" | "done";
12
+ state: 'blocked' | 'ready' | 'in_review' | 'in_progress' | 'done';
13
13
  description: string;
14
14
  requires: string[];
15
15
  fileExists: boolean;
@@ -40,38 +40,48 @@ interface SpecModalProps {
40
40
  }
41
41
 
42
42
  const STATE_ICON: Record<string, React.ReactNode> = {
43
- blocked: <Lock className="h-3 w-3 text-gray-400 flex-shrink-0" />,
44
- ready: <Circle className="h-3 w-3 text-blue-500 flex-shrink-0" />,
45
- in_review: <Clock className="h-3 w-3 text-yellow-500 flex-shrink-0" />,
43
+ blocked: <Lock className="h-3 w-3 text-gray-400 flex-shrink-0" />,
44
+ ready: <Circle className="h-3 w-3 text-blue-500 flex-shrink-0" />,
45
+ in_review: <Clock className="h-3 w-3 text-yellow-500 flex-shrink-0" />,
46
46
  in_progress: <Clock className="h-3 w-3 text-orange-500 flex-shrink-0" />,
47
- done: <CheckCircle2 className="h-3 w-3 text-green-600 flex-shrink-0" />,
47
+ done: <CheckCircle2 className="h-3 w-3 text-green-600 flex-shrink-0" />,
48
48
  };
49
49
 
50
50
  const TASK_STATUS_COLORS: Record<string, string> = {
51
- backlog: "bg-gray-100 border-gray-400 text-gray-600",
52
- todo: "bg-blue-100 border-blue-400 text-blue-700",
53
- in_progress: "bg-orange-100 border-orange-400 text-orange-700",
54
- interrupted: "bg-red-100 border-red-400 text-red-700",
55
- done: "bg-green-100 border-green-500 text-green-700",
51
+ backlog: 'bg-gray-100 border-gray-400 text-gray-600',
52
+ todo: 'bg-blue-100 border-blue-400 text-blue-700',
53
+ in_progress: 'bg-orange-100 border-orange-400 text-orange-700',
54
+ interrupted: 'bg-red-100 border-red-400 text-red-700',
55
+ done: 'bg-green-100 border-green-500 text-green-700',
56
56
  };
57
57
 
58
58
  const PRIORITY_COLORS: Record<string, string> = {
59
- urgent: "text-red-600",
60
- high: "text-orange-500",
61
- medium: "text-gray-500",
62
- low: "text-gray-400",
59
+ urgent: 'text-red-600',
60
+ high: 'text-orange-500',
61
+ medium: 'text-gray-500',
62
+ low: 'text-gray-400',
63
63
  };
64
64
 
65
- function DevelopmentPanel({ tasks, status }: { tasks: PromotedTask[]; status: ArtifactStatus | undefined }) {
65
+ function DevelopmentPanel({
66
+ tasks,
67
+ status,
68
+ }: {
69
+ tasks: PromotedTask[];
70
+ status: ArtifactStatus | undefined;
71
+ }) {
66
72
  const total = tasks.length;
67
- const done = tasks.filter((t) => t.status === "done").length;
68
- const inProgress = tasks.filter((t) => t.status === "in_progress").length;
73
+ const done = tasks.filter((t) => t.status === 'done').length;
74
+ const inProgress = tasks.filter((t) => t.status === 'in_progress').length;
69
75
 
70
- if (status?.state === "blocked") {
76
+ if (status?.state === 'blocked') {
71
77
  return (
72
78
  <div className="p-6 bg-gray-100 border-4 border-gray-300 text-center">
73
- <p className="font-bold text-gray-600 uppercase">Blocked — approve and promote tasks first</p>
74
- <p className="text-sm text-gray-500 mt-1">Approve all artifacts, then click &ldquo;Promote to Tasks&rdquo;</p>
79
+ <p className="font-bold text-gray-600 uppercase">
80
+ Blocked approve and promote tasks first
81
+ </p>
82
+ <p className="text-sm text-gray-500 mt-1">
83
+ Approve all artifacts, then click &ldquo;Promote to Tasks&rdquo;
84
+ </p>
75
85
  </div>
76
86
  );
77
87
  }
@@ -79,7 +89,9 @@ function DevelopmentPanel({ tasks, status }: { tasks: PromotedTask[]; status: Ar
79
89
  return (
80
90
  <div className="p-6 bg-blue-50 border-4 border-blue-300 text-center">
81
91
  <p className="font-bold text-blue-700 uppercase">Ready to promote</p>
82
- <p className="text-sm text-blue-600 mt-1">All artifacts approved. Promote tasks to start development.</p>
92
+ <p className="text-sm text-blue-600 mt-1">
93
+ All artifacts approved. Promote tasks to start development.
94
+ </p>
83
95
  </div>
84
96
  );
85
97
  }
@@ -87,30 +99,44 @@ function DevelopmentPanel({ tasks, status }: { tasks: PromotedTask[]; status: Ar
87
99
  <div className="flex flex-col gap-4">
88
100
  <div className="flex items-center gap-3">
89
101
  <div className="flex-1 h-3 bg-gray-200 border-2 border-black overflow-hidden">
90
- <div className="h-full bg-green-500 transition-all" style={{ width: `${total > 0 ? (done / total) * 100 : 0}%` }} />
102
+ <div
103
+ className="h-full bg-green-500 transition-all"
104
+ style={{ width: `${total > 0 ? (done / total) * 100 : 0}%` }}
105
+ />
91
106
  </div>
92
107
  <span className="font-mono text-sm font-bold whitespace-nowrap">
93
108
  {done}/{total} done
94
- {inProgress > 0 && <span className="text-orange-600 ml-2">· {inProgress} in progress</span>}
109
+ {inProgress > 0 && (
110
+ <span className="text-orange-600 ml-2">· {inProgress} in progress</span>
111
+ )}
95
112
  </span>
96
113
  </div>
97
114
  <div className="flex flex-col gap-2">
98
115
  {tasks.map((task) => (
99
116
  <div key={task.id} className="flex items-center gap-3 p-3 border-4 border-black bg-white">
100
- <span className={`text-lg ${task.status === "done" ? "opacity-100" : "opacity-30"}`}>
101
- {task.status === "done" ? "" : task.status === "in_progress" ? "" : ""}
117
+ <span className={`text-lg ${task.status === 'done' ? 'opacity-100' : 'opacity-30'}`}>
118
+ {task.status === 'done' ? '' : task.status === 'in_progress' ? '' : ''}
102
119
  </span>
103
- <span className={`flex-1 font-bold text-sm ${task.status === "done" ? "line-through text-gray-400" : ""}`}>
120
+ <span
121
+ className={`flex-1 font-bold text-sm ${task.status === 'done' ? 'line-through text-gray-400' : ''}`}
122
+ >
104
123
  {task.title}
105
124
  </span>
106
- <span className={`text-xs font-mono uppercase font-bold ${PRIORITY_COLORS[task.priority] || ""}`}>
125
+ <span
126
+ className={`text-xs font-mono uppercase font-bold ${PRIORITY_COLORS[task.priority] || ''}`}
127
+ >
107
128
  {task.priority}
108
129
  </span>
109
- <span className={`px-2 py-0.5 border-2 text-xs font-bold uppercase ${TASK_STATUS_COLORS[task.status] || ""}`}>
110
- {task.status.replace("_", " ")}
130
+ <span
131
+ className={`px-2 py-0.5 border-2 text-xs font-bold uppercase ${TASK_STATUS_COLORS[task.status] || ''}`}
132
+ >
133
+ {task.status.replace('_', ' ')}
111
134
  </span>
112
135
  {task.assignedAgent && (
113
- <span className="text-xs font-mono text-gray-500 truncate max-w-[120px]" title={task.assignedAgent}>
136
+ <span
137
+ className="text-xs font-mono text-gray-500 truncate max-w-[120px]"
138
+ title={task.assignedAgent}
139
+ >
114
140
  @{task.assignedAgent}
115
141
  </span>
116
142
  )}
@@ -122,33 +148,32 @@ function DevelopmentPanel({ tasks, status }: { tasks: PromotedTask[]; status: Ar
122
148
  }
123
149
 
124
150
  export function SpecModal({ specName, onClose }: SpecModalProps) {
125
- const [spec, setSpec] = useState<SpecDetail | null>(null);
151
+ const { data: specData, isLoading } = useSpec(specName);
152
+ const { invalidateSpec, invalidateSpecs, invalidateTasks } = useInvalidate();
126
153
  const [activeNode, setActiveNode] = useState<string | null>(null);
127
154
  const [isPromoting, setIsPromoting] = useState(false);
128
155
 
129
- async function load() {
130
- const r = await fetch(`/api/specs/${specName}`);
131
- const data = await r.json();
132
- setSpec(data);
133
- // Auto-select first artifact
134
- if (!activeNode && data.statuses?.length) {
135
- setActiveNode(data.statuses[0].id);
136
- }
156
+ const spec = specData as SpecDetail | undefined;
157
+
158
+ // Auto-select first artifact when spec loads
159
+ if (spec && !activeNode && spec.statuses?.length) {
160
+ setActiveNode(spec.statuses[0].id);
137
161
  }
138
162
 
139
- useEffect(() => {
140
- load();
141
- // eslint-disable-next-line react-hooks/exhaustive-deps
142
- }, [specName]);
163
+ function handleRefresh() {
164
+ invalidateSpec(specName);
165
+ invalidateSpecs();
166
+ }
143
167
 
144
168
  async function handlePromote() {
145
169
  setIsPromoting(true);
146
170
  try {
147
- const r = await fetch(`/api/specs/${specName}/promote`, { method: "POST" });
171
+ const r = await fetch(`/api/specs/${specName}/promote`, { method: 'POST' });
148
172
  const data = await r.json();
149
173
  if (r.ok) {
150
174
  alert(`Promoted ${data.promoted} tasks to Kanban board!`);
151
- load();
175
+ handleRefresh();
176
+ invalidateTasks();
152
177
  } else {
153
178
  alert(`Error: ${data.error}`);
154
179
  }
@@ -157,21 +182,24 @@ export function SpecModal({ specName, onClose }: SpecModalProps) {
157
182
  }
158
183
  }
159
184
 
160
- const artifactStatuses = spec?.statuses.filter((s) => s.id !== "development") ?? [];
161
- const developmentStatus = spec?.statuses.find((s) => s.id === "development");
162
- const allArtifactsApproved = artifactStatuses.every((s) => s.state === "done");
185
+ const artifactStatuses = spec?.statuses.filter((s) => s.id !== 'development') ?? [];
186
+ const developmentStatus = spec?.statuses.find((s) => s.id === 'development');
187
+ const allArtifactsApproved = artifactStatuses.every((s) => s.state === 'done');
163
188
  const activeStatus = spec?.statuses.find((s) => s.id === activeNode);
164
- const isDevelopment = activeNode === "development";
189
+ const isDevelopment = activeNode === 'development';
165
190
 
166
191
  return (
167
192
  // Backdrop
168
193
  <div
169
194
  className="fixed inset-0 z-50 flex items-center justify-center bg-black/60"
170
- onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
195
+ onClick={(e) => {
196
+ if (e.target === e.currentTarget) onClose();
197
+ }}
171
198
  >
172
199
  {/* Modal */}
173
- <div className="bg-white border-4 border-black shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] flex flex-col"
174
- style={{ width: "min(1300px, 96vw)", height: "min(920px, 94vh)" }}
200
+ <div
201
+ className="bg-white border-4 border-black shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] flex flex-col"
202
+ style={{ width: 'min(1300px, 96vw)', height: 'min(920px, 94vh)' }}
175
203
  >
176
204
  {/* Header */}
177
205
  <div className="flex items-center justify-between px-6 py-4 border-b-4 border-black bg-white flex-shrink-0">
@@ -200,12 +228,16 @@ export function SpecModal({ specName, onClose }: SpecModalProps) {
200
228
  {allArtifactsApproved && spec?.tasks.length === 0 && (
201
229
  <div className="px-6 py-3 border-b-4 border-green-600 bg-green-100 flex-shrink-0 flex items-center justify-between">
202
230
  <p className="font-black text-green-800 uppercase text-sm">All artifacts approved!</p>
203
- <Button onClick={handlePromote} disabled={isPromoting} className="bg-green-600 hover:bg-green-700 text-white">
204
- {isPromoting ? "Promoting..." : "Promote to Tasks"}
231
+ <Button
232
+ onClick={handlePromote}
233
+ disabled={isPromoting}
234
+ className="bg-green-600 hover:bg-green-700 text-white"
235
+ >
236
+ {isPromoting ? 'Promoting...' : 'Promote to Tasks'}
205
237
  </Button>
206
238
  </div>
207
239
  )}
208
- {developmentStatus?.state === "done" && (
240
+ {developmentStatus?.state === 'done' && (
209
241
  <div className="px-6 py-3 border-b-4 border-green-600 bg-green-100 flex-shrink-0">
210
242
  <p className="font-black text-green-800 uppercase text-sm">
211
243
  ✓ Spec complete — all {spec?.tasks.length} tasks done
@@ -215,7 +247,6 @@ export function SpecModal({ specName, onClose }: SpecModalProps) {
215
247
 
216
248
  {/* Body: tree + editor */}
217
249
  <div className="flex flex-1 min-h-0">
218
-
219
250
  {/* File tree */}
220
251
  <div className="w-60 border-r-4 border-black bg-white flex flex-col flex-shrink-0 overflow-y-auto">
221
252
  <div className="px-3 py-2 border-b-2 border-gray-200">
@@ -232,36 +263,42 @@ export function SpecModal({ specName, onClose }: SpecModalProps) {
232
263
  key={s.id}
233
264
  onClick={() => setActiveNode(s.id)}
234
265
  className={`w-full flex items-center gap-2 px-3 py-2 text-left transition-colors group ${
235
- activeNode === s.id
236
- ? "bg-black text-white"
237
- : "hover:bg-gray-100"
266
+ activeNode === s.id ? 'bg-black text-white' : 'hover:bg-gray-100'
238
267
  }`}
239
268
  >
240
- <ChevronRight className={`h-3 w-3 flex-shrink-0 ${activeNode === s.id ? "text-white" : "text-gray-300"}`} />
241
- <FileText className={`h-3.5 w-3.5 flex-shrink-0 ${activeNode === s.id ? "text-white" : "text-gray-400"}`} />
269
+ <ChevronRight
270
+ className={`h-3 w-3 flex-shrink-0 ${activeNode === s.id ? 'text-white' : 'text-gray-300'}`}
271
+ />
272
+ <FileText
273
+ className={`h-3.5 w-3.5 flex-shrink-0 ${activeNode === s.id ? 'text-white' : 'text-gray-400'}`}
274
+ />
242
275
  <span className="font-mono text-xs font-bold flex-1 truncate">{s.id}.md</span>
243
- <span className={activeNode === s.id ? "text-white opacity-70" : ""}>
276
+ <span className={activeNode === s.id ? 'text-white opacity-70' : ''}>
244
277
  {STATE_ICON[s.state]}
245
278
  </span>
246
279
  </button>
247
280
  ))}
248
281
 
249
282
  {/* development entry — only shown after tasks approved */}
250
- {(allArtifactsApproved || (spec.tasks.length > 0)) && (
283
+ {(allArtifactsApproved || spec.tasks.length > 0) && (
251
284
  <>
252
285
  <div className="mx-3 my-1 border-t border-dashed border-gray-200" />
253
286
  <button
254
- onClick={() => setActiveNode("development")}
287
+ onClick={() => setActiveNode('development')}
255
288
  className={`w-full flex items-center gap-2 px-3 py-2 text-left transition-colors ${
256
- activeNode === "development"
257
- ? "bg-black text-white"
258
- : "hover:bg-gray-100"
289
+ activeNode === 'development' ? 'bg-black text-white' : 'hover:bg-gray-100'
259
290
  }`}
260
291
  >
261
- <ChevronRight className={`h-3 w-3 flex-shrink-0 ${activeNode === "development" ? "text-white" : "text-gray-300"}`} />
262
- <FileText className={`h-3.5 w-3.5 flex-shrink-0 ${activeNode === "development" ? "text-white" : "text-gray-400"}`} />
292
+ <ChevronRight
293
+ className={`h-3 w-3 flex-shrink-0 ${activeNode === 'development' ? 'text-white' : 'text-gray-300'}`}
294
+ />
295
+ <FileText
296
+ className={`h-3.5 w-3.5 flex-shrink-0 ${activeNode === 'development' ? 'text-white' : 'text-gray-400'}`}
297
+ />
263
298
  <span className="font-mono text-xs font-bold flex-1">development</span>
264
- <span className={activeNode === "development" ? "text-white opacity-70" : ""}>
299
+ <span
300
+ className={activeNode === 'development' ? 'text-white opacity-70' : ''}
301
+ >
265
302
  {developmentStatus ? STATE_ICON[developmentStatus.state] : null}
266
303
  </span>
267
304
  </button>
@@ -276,21 +313,20 @@ export function SpecModal({ specName, onClose }: SpecModalProps) {
276
313
 
277
314
  {/* Editor area */}
278
315
  <div className="flex-1 flex flex-col min-h-0 p-6">
279
- {!spec ? (
316
+ {isLoading ? (
280
317
  <div className="flex items-center justify-center h-full">
281
318
  <span className="text-gray-400 font-mono text-sm">Loading...</span>
282
319
  </div>
283
- ) : !activeNode ? null
284
- : isDevelopment ? (
285
- <DevelopmentPanel tasks={spec.tasks} status={developmentStatus} />
320
+ ) : !activeNode ? null : isDevelopment ? (
321
+ <DevelopmentPanel tasks={spec?.tasks ?? []} status={developmentStatus} />
286
322
  ) : activeStatus ? (
287
323
  <ArtifactEditor
288
324
  key={activeNode}
289
325
  specName={specName}
290
326
  artifactType={activeNode}
291
- content={spec.artifacts[activeNode] ?? null}
327
+ content={spec?.artifacts[activeNode] ?? null}
292
328
  status={activeStatus}
293
- onSave={load}
329
+ onSave={handleRefresh}
294
330
  defaultMode="preview"
295
331
  />
296
332
  ) : null}
@@ -1,15 +1,15 @@
1
- "use client";
1
+ 'use client';
2
2
 
3
- import { useState } from "react";
4
- import { useSortable } from "@dnd-kit/sortable";
5
- import { CSS } from "@dnd-kit/utilities";
6
- import { Task } from "@/db/schema";
7
- import { Card, CardContent, CardHeader, CardTitle } from "./ui/card";
8
- import { Badge } from "./ui/badge";
9
- import { Button } from "./ui/button";
10
- import { cn } from "@/lib/utils";
11
- import { GripVertical, User, FileText, Trash2, AlertTriangle } from "lucide-react";
12
- import { TaskDialog } from "./task-dialog";
3
+ import { useState } from 'react';
4
+ import { useSortable } from '@dnd-kit/sortable';
5
+ import { CSS } from '@dnd-kit/utilities';
6
+ import { Task } from '@/db/schema';
7
+ import { Card, CardContent, CardHeader, CardTitle } from './ui/card';
8
+ import { Badge } from './ui/badge';
9
+ import { Button } from './ui/button';
10
+ import { cn } from '@/lib/utils';
11
+ import { GripVertical, User, FileText, Trash2, AlertTriangle } from 'lucide-react';
12
+ import { TaskDialog } from './task-dialog';
13
13
 
14
14
  interface TaskCardProps {
15
15
  task: Task;
@@ -19,22 +19,17 @@ interface TaskCardProps {
19
19
  }
20
20
 
21
21
  const priorityColors = {
22
- low: "bg-[--color-primary] text-black",
23
- medium: "bg-[--color-secondary] text-black",
24
- high: "bg-orange-300 text-black",
25
- urgent: "bg-[--color-accent] text-black",
22
+ low: 'bg-[--color-primary] text-black',
23
+ medium: 'bg-[--color-secondary] text-black',
24
+ high: 'bg-orange-300 text-black',
25
+ urgent: 'bg-[--color-accent] text-black',
26
26
  };
27
27
 
28
28
  export function TaskCard({ task, onRefresh }: TaskCardProps) {
29
29
  const [isDialogOpen, setIsDialogOpen] = useState(false);
30
- const {
31
- attributes,
32
- listeners,
33
- setNodeRef,
34
- transform,
35
- transition,
36
- isDragging,
37
- } = useSortable({ id: task.id });
30
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
31
+ id: task.id,
32
+ });
38
33
 
39
34
  const style = {
40
35
  transform: CSS.Transform.toString(transform),
@@ -43,12 +38,12 @@ export function TaskCard({ task, onRefresh }: TaskCardProps) {
43
38
 
44
39
  async function handleDelete(e: React.MouseEvent) {
45
40
  e.stopPropagation();
46
- if (confirm("Are you sure you want to delete this task?")) {
41
+ if (confirm('Are you sure you want to delete this task?')) {
47
42
  try {
48
- await fetch(`/api/tasks/${task.id}`, { method: "DELETE" });
43
+ await fetch(`/api/tasks/${task.id}`, { method: 'DELETE' });
49
44
  onRefresh();
50
45
  } catch (error) {
51
- console.error("Failed to delete task:", error);
46
+ console.error('Failed to delete task:', error);
52
47
  }
53
48
  }
54
49
  }
@@ -58,24 +53,19 @@ export function TaskCard({ task, onRefresh }: TaskCardProps) {
58
53
  <div
59
54
  ref={setNodeRef}
60
55
  style={style}
61
- className={cn(
62
- "cursor-pointer transition-opacity",
63
- isDragging && "opacity-50"
64
- )}
56
+ className={cn('cursor-pointer transition-opacity', isDragging && 'opacity-50')}
65
57
  >
66
58
  <Card
67
59
  className={cn(
68
- "hover:translate-x-0.5 hover:translate-y-0.5 transition-transform cursor-pointer",
69
- task.status === "interrupted" && "border-amber-500 bg-amber-50"
60
+ 'hover:translate-x-0.5 hover:translate-y-0.5 transition-transform cursor-pointer',
61
+ task.status === 'interrupted' && 'border-amber-500 bg-amber-50',
70
62
  )}
71
63
  onClick={() => setIsDialogOpen(true)}
72
64
  >
73
65
  <CardHeader className="pb-3">
74
66
  <div className="flex items-start justify-between gap-2">
75
67
  <div className="flex-1 min-w-0">
76
- <CardTitle className="text-sm line-clamp-2">
77
- {task.title}
78
- </CardTitle>
68
+ <CardTitle className="text-sm line-clamp-2">{task.title}</CardTitle>
79
69
  </div>
80
70
  <div className="flex items-center gap-1">
81
71
  <Button
@@ -102,8 +92,11 @@ export function TaskCard({ task, onRefresh }: TaskCardProps) {
102
92
 
103
93
  <CardContent className="space-y-2">
104
94
  <div className="flex flex-wrap gap-2">
105
- {task.status === "interrupted" && (
106
- <Badge variant="outline" className="text-xs gap-1 border-amber-500 text-amber-700 bg-amber-50">
95
+ {task.status === 'interrupted' && (
96
+ <Badge
97
+ variant="outline"
98
+ className="text-xs gap-1 border-amber-500 text-amber-700 bg-amber-50"
99
+ >
107
100
  <AlertTriangle className="h-3 w-3" />
108
101
  Interrupted
109
102
  </Badge>
@@ -117,7 +110,10 @@ export function TaskCard({ task, onRefresh }: TaskCardProps) {
117
110
 
118
111
  <Badge
119
112
  variant="outline"
120
- className={cn("text-xs", priorityColors[task.priority as keyof typeof priorityColors])}
113
+ className={cn(
114
+ 'text-xs',
115
+ priorityColors[task.priority as keyof typeof priorityColors],
116
+ )}
121
117
  >
122
118
  {task.priority}
123
119
  </Badge>
@@ -1,17 +1,12 @@
1
- "use client";
1
+ 'use client';
2
2
 
3
- import { useState, useEffect } from "react";
4
- import { Task } from "@/db/schema";
5
- import {
6
- Dialog,
7
- DialogContent,
8
- DialogHeader,
9
- DialogTitle,
10
- } from "./ui/dialog";
11
- import { Button } from "./ui/button";
12
- import { Badge } from "./ui/badge";
13
- import { User, Clock } from "lucide-react";
14
- import { MarkdownPreview } from "./markdown-preview";
3
+ import { useState, useEffect } from 'react';
4
+ import { Task } from '@/db/schema';
5
+ import { Dialog, DialogContent, DialogHeader, DialogTitle } from './ui/dialog';
6
+ import { Button } from './ui/button';
7
+ import { Badge } from './ui/badge';
8
+ import { User, Clock } from 'lucide-react';
9
+ import { MarkdownPreview } from './markdown-preview';
15
10
 
16
11
  interface TaskDialogProps {
17
12
  task: Task;
@@ -52,14 +47,14 @@ export function TaskDialog({ task, open, onOpenChange, onRefresh }: TaskDialogPr
52
47
  setIsSaving(true);
53
48
  try {
54
49
  await fetch(`/api/tasks/${task.id}`, {
55
- method: "PATCH",
56
- headers: { "Content-Type": "application/json" },
50
+ method: 'PATCH',
51
+ headers: { 'Content-Type': 'application/json' },
57
52
  body: JSON.stringify({ title, priority, status }),
58
53
  });
59
54
  onRefresh();
60
55
  onOpenChange(false);
61
56
  } catch (error) {
62
- console.error("Failed to update task:", error);
57
+ console.error('Failed to update task:', error);
63
58
  } finally {
64
59
  setIsSaving(false);
65
60
  }
@@ -75,9 +70,7 @@ export function TaskDialog({ task, open, onOpenChange, onRefresh }: TaskDialogPr
75
70
  <div className="space-y-4">
76
71
  {/* Title */}
77
72
  <div>
78
- <label className="text-xs font-bold uppercase tracking-wide mb-2 block">
79
- Title
80
- </label>
73
+ <label className="text-xs font-bold uppercase tracking-wide mb-2 block">Title</label>
81
74
  <input
82
75
  type="text"
83
76
  value={title}
@@ -106,9 +99,7 @@ export function TaskDialog({ task, open, onOpenChange, onRefresh }: TaskDialogPr
106
99
  </div>
107
100
 
108
101
  <div>
109
- <label className="text-xs font-bold uppercase tracking-wide mb-2 block">
110
- Status
111
- </label>
102
+ <label className="text-xs font-bold uppercase tracking-wide mb-2 block">Status</label>
112
103
  <select
113
104
  value={status}
114
105
  onChange={(e) => setStatus(e.target.value)}
@@ -126,9 +117,7 @@ export function TaskDialog({ task, open, onOpenChange, onRefresh }: TaskDialogPr
126
117
  {/* Spec Name */}
127
118
  {task.specName && (
128
119
  <div>
129
- <label className="text-xs font-bold uppercase tracking-wide mb-2 block">
130
- Spec
131
- </label>
120
+ <label className="text-xs font-bold uppercase tracking-wide mb-2 block">Spec</label>
132
121
  <div className="px-4 py-2 border-2 border-black bg-gray-50 font-mono text-sm">
133
122
  {task.specName}
134
123
  </div>
@@ -169,15 +158,11 @@ export function TaskDialog({ task, open, onOpenChange, onRefresh }: TaskDialogPr
169
158
 
170
159
  {/* Actions */}
171
160
  <div className="flex justify-end gap-3 pt-4 border-t-3 border-black">
172
- <Button
173
- variant="outline"
174
- onClick={() => onOpenChange(false)}
175
- disabled={isSaving}
176
- >
161
+ <Button variant="outline" onClick={() => onOpenChange(false)} disabled={isSaving}>
177
162
  Cancel
178
163
  </Button>
179
164
  <Button onClick={handleSave} disabled={isSaving}>
180
- {isSaving ? "Saving..." : "Save Changes"}
165
+ {isSaving ? 'Saving...' : 'Save Changes'}
181
166
  </Button>
182
167
  </div>
183
168
  </div>
@@ -1,35 +1,29 @@
1
- import * as React from "react";
2
- import { cva, type VariantProps } from "class-variance-authority";
3
- import { cn } from "@/lib/utils";
1
+ import * as React from 'react';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+ import { cn } from '@/lib/utils';
4
4
 
5
5
  const badgeVariants = cva(
6
- "inline-flex items-center border-2 border-black px-3 py-1 text-xs font-bold uppercase tracking-wide shadow-[2px_2px_0px_0px_rgba(0,0,0,1)]",
6
+ 'inline-flex items-center border-2 border-black px-3 py-1 text-xs font-bold uppercase tracking-wide shadow-[2px_2px_0px_0px_rgba(0,0,0,1)]',
7
7
  {
8
8
  variants: {
9
9
  variant: {
10
- default:
11
- "bg-[--color-primary] text-black",
12
- secondary:
13
- "bg-[--color-secondary] text-black",
14
- destructive:
15
- "bg-[--color-accent] text-black",
16
- outline: "bg-white text-black",
10
+ default: 'bg-[--color-primary] text-black',
11
+ secondary: 'bg-[--color-secondary] text-black',
12
+ destructive: 'bg-[--color-accent] text-black',
13
+ outline: 'bg-white text-black',
17
14
  },
18
15
  },
19
16
  defaultVariants: {
20
- variant: "default",
17
+ variant: 'default',
21
18
  },
22
- }
19
+ },
23
20
  );
24
21
 
25
22
  export interface BadgeProps
26
- extends React.HTMLAttributes<HTMLDivElement>,
27
- VariantProps<typeof badgeVariants> {}
23
+ extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {}
28
24
 
29
25
  function Badge({ className, variant, ...props }: BadgeProps) {
30
- return (
31
- <div className={cn(badgeVariants({ variant }), className)} {...props} />
32
- );
26
+ return <div className={cn(badgeVariants({ variant }), className)} {...props} />;
33
27
  }
34
28
 
35
29
  export { Badge, badgeVariants };