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