@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,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
|
|
3
|
-
import { useState, useEffect, useCallback, useRef } from
|
|
3
|
+
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
4
4
|
import {
|
|
5
5
|
DndContext,
|
|
6
6
|
DragEndEvent,
|
|
@@ -9,167 +9,89 @@ import {
|
|
|
9
9
|
PointerSensor,
|
|
10
10
|
useSensor,
|
|
11
11
|
useSensors,
|
|
12
|
-
} from
|
|
13
|
-
import { Task, Project } from
|
|
14
|
-
import { KanbanColumn } from
|
|
15
|
-
import { TaskCard } from
|
|
16
|
-
import { ChevronDown, Trash2 } from
|
|
17
|
-
import { SpecKanbanColumn } from
|
|
18
|
-
import { SpecModal } from
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
} from '@dnd-kit/core';
|
|
13
|
+
import { Task, Project } from '@/db/schema';
|
|
14
|
+
import { KanbanColumn } from './kanban-column';
|
|
15
|
+
import { TaskCard } from './task-card';
|
|
16
|
+
import { ChevronDown, Trash2 } from 'lucide-react';
|
|
17
|
+
import { SpecKanbanColumn } from './specs/spec-kanban-column';
|
|
18
|
+
import { SpecModal } from './specs/spec-modal';
|
|
19
|
+
import { useProjects, useTasks, useInvalidate } from '@/hooks/use-queries';
|
|
20
|
+
import { useWebSocket } from '@/hooks/use-websocket';
|
|
21
|
+
|
|
22
|
+
type TaskStatus = 'backlog' | 'todo' | 'in_progress' | 'interrupted' | 'done';
|
|
21
23
|
|
|
22
24
|
const COLUMNS: { id: TaskStatus; title: string; color: string }[] = [
|
|
23
|
-
{ id:
|
|
24
|
-
{ id:
|
|
25
|
-
{ id:
|
|
26
|
-
{ id:
|
|
25
|
+
{ id: 'backlog', title: 'Backlog', color: 'bg-gray-200' },
|
|
26
|
+
{ id: 'todo', title: 'To Do', color: 'bg-[--color-primary]' },
|
|
27
|
+
{ id: 'in_progress', title: 'In Progress', color: 'bg-[--color-secondary]' },
|
|
28
|
+
{ id: 'done', title: 'Done', color: 'bg-[--color-success]' },
|
|
27
29
|
];
|
|
28
30
|
|
|
29
31
|
const COLUMN_IDS: Set<string> = new Set(COLUMNS.map((c) => c.id));
|
|
30
32
|
|
|
31
|
-
const STORAGE_KEY =
|
|
33
|
+
const STORAGE_KEY = 'devflow-selected-project';
|
|
32
34
|
|
|
33
35
|
export function KanbanBoard() {
|
|
34
|
-
const [
|
|
35
|
-
const [
|
|
36
|
+
const { data: projects = [], isLoading: projectsLoading } = useProjects();
|
|
37
|
+
const { data: tasks = [], isLoading: tasksLoading } = useTasks();
|
|
38
|
+
const { invalidateTasks, invalidateProjects } = useInvalidate();
|
|
39
|
+
useWebSocket();
|
|
40
|
+
|
|
36
41
|
const [selectedProjectId, setSelectedProjectId] = useState<string | null>(null);
|
|
37
42
|
const [selectedSpecName, setSelectedSpecName] = useState<string | null>(null);
|
|
38
43
|
const [specPanelOpen, setSpecPanelOpen] = useState(false);
|
|
39
44
|
const [activeTask, setActiveTask] = useState<Task | null>(null);
|
|
40
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
41
45
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
42
46
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
43
47
|
|
|
44
|
-
const selectedProjectIdRef = useRef<string | null>(null);
|
|
45
|
-
selectedProjectIdRef.current = selectedProjectId;
|
|
46
|
-
|
|
47
48
|
const sensors = useSensors(
|
|
48
49
|
useSensor(PointerSensor, {
|
|
49
50
|
activationConstraint: {
|
|
50
51
|
distance: 8,
|
|
51
52
|
},
|
|
52
|
-
})
|
|
53
|
+
}),
|
|
53
54
|
);
|
|
54
55
|
|
|
55
56
|
useEffect(() => {
|
|
56
57
|
const saved = localStorage.getItem(STORAGE_KEY);
|
|
57
58
|
if (saved) {
|
|
58
|
-
setSelectedProjectId(saved ===
|
|
59
|
+
setSelectedProjectId(saved === 'all' ? null : saved);
|
|
59
60
|
}
|
|
60
61
|
setIsInitialized(true);
|
|
61
62
|
}, []);
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
setSelectedProjectId(projectId);
|
|
65
|
-
setSelectedSpecName(null);
|
|
66
|
-
localStorage.setItem(STORAGE_KEY, projectId || "all");
|
|
67
|
-
setIsDropdownOpen(false);
|
|
68
|
-
}, []);
|
|
69
|
-
|
|
64
|
+
// Auto-select project if needed
|
|
70
65
|
useEffect(() => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
fetchProjects();
|
|
77
|
-
}, 5000);
|
|
78
|
-
|
|
79
|
-
return () => clearInterval(pollInterval);
|
|
80
|
-
}, []);
|
|
81
|
-
|
|
82
|
-
useEffect(() => {
|
|
83
|
-
let ws: WebSocket | null = null;
|
|
84
|
-
let reconnectTimeout: NodeJS.Timeout;
|
|
85
|
-
let isUnmounted = false;
|
|
86
|
-
|
|
87
|
-
function connect() {
|
|
88
|
-
if (isUnmounted) return;
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
ws = new WebSocket("ws://localhost:3001");
|
|
92
|
-
|
|
93
|
-
ws.onopen = () => {
|
|
94
|
-
console.log("WebSocket connected");
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
ws.onmessage = (event) => {
|
|
98
|
-
const data = JSON.parse(event.data);
|
|
99
|
-
if (data.type === "agent_count") return;
|
|
100
|
-
if (data.type?.includes("project")) {
|
|
101
|
-
fetchProjects();
|
|
102
|
-
}
|
|
103
|
-
fetchTasks();
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
ws.onerror = () => {};
|
|
107
|
-
|
|
108
|
-
ws.onclose = () => {
|
|
109
|
-
if (!isUnmounted) {
|
|
110
|
-
reconnectTimeout = setTimeout(connect, 3000);
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
} catch {
|
|
114
|
-
if (!isUnmounted) {
|
|
115
|
-
reconnectTimeout = setTimeout(connect, 3000);
|
|
116
|
-
}
|
|
66
|
+
if (!isInitialized || projectsLoading) return;
|
|
67
|
+
if (selectedProjectId) {
|
|
68
|
+
const exists = projects.some((p: Project) => p.id === selectedProjectId);
|
|
69
|
+
if (!exists && projects.length > 0) {
|
|
70
|
+
selectProject(projects[0].id);
|
|
117
71
|
}
|
|
72
|
+
} else if (!localStorage.getItem(STORAGE_KEY) && projects.length > 0) {
|
|
73
|
+
selectProject(projects[0].id);
|
|
118
74
|
}
|
|
75
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
76
|
+
}, [isInitialized, projectsLoading, projects]);
|
|
119
77
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
ws?.close();
|
|
126
|
-
};
|
|
127
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
78
|
+
const selectProject = useCallback((projectId: string | null) => {
|
|
79
|
+
setSelectedProjectId(projectId);
|
|
80
|
+
setSelectedSpecName(null);
|
|
81
|
+
localStorage.setItem(STORAGE_KEY, projectId || 'all');
|
|
82
|
+
setIsDropdownOpen(false);
|
|
128
83
|
}, []);
|
|
129
84
|
|
|
130
|
-
async function fetchProjects() {
|
|
131
|
-
try {
|
|
132
|
-
const response = await fetch("/api/projects");
|
|
133
|
-
const data = await response.json();
|
|
134
|
-
setProjects(data);
|
|
135
|
-
|
|
136
|
-
if (isInitialized && selectedProjectId) {
|
|
137
|
-
const exists = data.some((p: Project) => p.id === selectedProjectId);
|
|
138
|
-
if (!exists && data.length > 0) {
|
|
139
|
-
selectProject(data[0].id);
|
|
140
|
-
}
|
|
141
|
-
} else if (isInitialized && !selectedProjectId && !localStorage.getItem(STORAGE_KEY)) {
|
|
142
|
-
if (data.length > 0) {
|
|
143
|
-
selectProject(data[0].id);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
} catch (error) {
|
|
147
|
-
console.error("Failed to fetch projects:", error);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
async function fetchTasks() {
|
|
152
|
-
try {
|
|
153
|
-
const response = await fetch("/api/tasks");
|
|
154
|
-
const data = await response.json();
|
|
155
|
-
setTasks(data);
|
|
156
|
-
} catch (error) {
|
|
157
|
-
console.error("Failed to fetch tasks:", error);
|
|
158
|
-
} finally {
|
|
159
|
-
setIsLoading(false);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
85
|
async function updateTaskStatus(taskId: string, newStatus: TaskStatus) {
|
|
164
86
|
try {
|
|
165
87
|
await fetch(`/api/tasks/${taskId}`, {
|
|
166
|
-
method:
|
|
167
|
-
headers: {
|
|
88
|
+
method: 'PATCH',
|
|
89
|
+
headers: { 'Content-Type': 'application/json' },
|
|
168
90
|
body: JSON.stringify({ status: newStatus }),
|
|
169
91
|
});
|
|
170
|
-
|
|
92
|
+
invalidateTasks();
|
|
171
93
|
} catch (error) {
|
|
172
|
-
console.error(
|
|
94
|
+
console.error('Failed to update task:', error);
|
|
173
95
|
}
|
|
174
96
|
}
|
|
175
97
|
|
|
@@ -205,8 +127,8 @@ export function KanbanBoard() {
|
|
|
205
127
|
function getTasksByStatus(status: TaskStatus) {
|
|
206
128
|
return tasks
|
|
207
129
|
.filter((task) => {
|
|
208
|
-
if (task.status ===
|
|
209
|
-
return status ===
|
|
130
|
+
if (task.status === 'interrupted') {
|
|
131
|
+
return status === 'in_progress';
|
|
210
132
|
}
|
|
211
133
|
return task.status === status;
|
|
212
134
|
})
|
|
@@ -216,29 +138,32 @@ export function KanbanBoard() {
|
|
|
216
138
|
|
|
217
139
|
async function deleteProject(projectId: string, projectName: string) {
|
|
218
140
|
const taskCount = tasks.filter((t) => t.projectId === projectId).length;
|
|
219
|
-
const confirmMessage =
|
|
220
|
-
|
|
221
|
-
|
|
141
|
+
const confirmMessage =
|
|
142
|
+
taskCount > 0
|
|
143
|
+
? `Delete "${projectName}" and its ${taskCount} task${taskCount === 1 ? '' : 's'}? This cannot be undone.`
|
|
144
|
+
: `Delete "${projectName}"? This cannot be undone.`;
|
|
222
145
|
|
|
223
146
|
if (!confirm(confirmMessage)) return;
|
|
224
147
|
|
|
225
148
|
try {
|
|
226
149
|
const response = await fetch(`/api/projects/${projectId}`, {
|
|
227
|
-
method:
|
|
150
|
+
method: 'DELETE',
|
|
228
151
|
});
|
|
229
152
|
|
|
230
153
|
if (response.ok) {
|
|
231
154
|
if (selectedProjectId === projectId) {
|
|
232
155
|
selectProject(null);
|
|
233
156
|
}
|
|
234
|
-
|
|
235
|
-
|
|
157
|
+
invalidateProjects();
|
|
158
|
+
invalidateTasks();
|
|
236
159
|
}
|
|
237
160
|
} catch (error) {
|
|
238
|
-
console.error(
|
|
161
|
+
console.error('Failed to delete project:', error);
|
|
239
162
|
}
|
|
240
163
|
}
|
|
241
164
|
|
|
165
|
+
const isLoading = tasksLoading && !tasks.length;
|
|
166
|
+
|
|
242
167
|
if (isLoading) {
|
|
243
168
|
return (
|
|
244
169
|
<div className="flex items-center justify-center h-screen">
|
|
@@ -264,7 +189,7 @@ export function KanbanBoard() {
|
|
|
264
189
|
<div className="flex items-center gap-6">
|
|
265
190
|
<div className="flex items-center gap-4">
|
|
266
191
|
<h1 className="text-3xl font-black uppercase tracking-tight">DevFlow</h1>
|
|
267
|
-
|
|
192
|
+
</div>
|
|
268
193
|
|
|
269
194
|
{/* Project Chooser Dropdown */}
|
|
270
195
|
<div className="relative">
|
|
@@ -273,24 +198,23 @@ export function KanbanBoard() {
|
|
|
273
198
|
className="flex items-center gap-2 px-4 py-2 bg-[--color-primary] border-4 border-black font-bold text-sm uppercase hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-none transition-all shadow-[4px_4px_0px_0px_rgba(0,0,0,1)]"
|
|
274
199
|
>
|
|
275
200
|
<span className="max-w-[200px] truncate">
|
|
276
|
-
{selectedProject ? selectedProject.name :
|
|
201
|
+
{selectedProject ? selectedProject.name : 'All Projects'}
|
|
277
202
|
</span>
|
|
278
203
|
<span className="text-xs opacity-70">({totalTasks})</span>
|
|
279
|
-
<ChevronDown
|
|
204
|
+
<ChevronDown
|
|
205
|
+
className={`h-4 w-4 transition-transform ${isDropdownOpen ? 'rotate-180' : ''}`}
|
|
206
|
+
/>
|
|
280
207
|
</button>
|
|
281
208
|
|
|
282
209
|
{isDropdownOpen && (
|
|
283
210
|
<>
|
|
284
|
-
<div
|
|
285
|
-
className="fixed inset-0 z-10"
|
|
286
|
-
onClick={() => setIsDropdownOpen(false)}
|
|
287
|
-
/>
|
|
211
|
+
<div className="fixed inset-0 z-10" onClick={() => setIsDropdownOpen(false)} />
|
|
288
212
|
|
|
289
213
|
<div className="absolute top-full left-0 mt-2 w-64 bg-white border-4 border-black shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] z-20 max-h-80 overflow-y-auto">
|
|
290
214
|
<button
|
|
291
215
|
onClick={() => selectProject(null)}
|
|
292
216
|
className={`w-full px-4 py-3 text-left font-bold text-sm uppercase border-b-2 border-black hover:bg-gray-100 flex items-center justify-between ${
|
|
293
|
-
!selectedProjectId ?
|
|
217
|
+
!selectedProjectId ? 'bg-black text-white hover:bg-gray-800' : ''
|
|
294
218
|
}`}
|
|
295
219
|
>
|
|
296
220
|
<span>All Projects</span>
|
|
@@ -298,12 +222,16 @@ export function KanbanBoard() {
|
|
|
298
222
|
</button>
|
|
299
223
|
|
|
300
224
|
{projects.map((project) => {
|
|
301
|
-
const projectTaskCount = tasks.filter(
|
|
225
|
+
const projectTaskCount = tasks.filter(
|
|
226
|
+
(t) => t.projectId === project.id,
|
|
227
|
+
).length;
|
|
302
228
|
return (
|
|
303
229
|
<div
|
|
304
230
|
key={project.id}
|
|
305
231
|
className={`flex items-center border-b border-gray-200 last:border-b-0 ${
|
|
306
|
-
selectedProjectId === project.id
|
|
232
|
+
selectedProjectId === project.id
|
|
233
|
+
? 'bg-[--color-primary]'
|
|
234
|
+
: 'hover:bg-gray-100'
|
|
307
235
|
}`}
|
|
308
236
|
>
|
|
309
237
|
<button
|
|
@@ -328,9 +256,7 @@ export function KanbanBoard() {
|
|
|
328
256
|
})}
|
|
329
257
|
|
|
330
258
|
{projects.length === 0 && (
|
|
331
|
-
<div className="px-4 py-3 text-sm text-gray-500">
|
|
332
|
-
No projects yet
|
|
333
|
-
</div>
|
|
259
|
+
<div className="px-4 py-3 text-sm text-gray-500">No projects yet</div>
|
|
334
260
|
)}
|
|
335
261
|
</div>
|
|
336
262
|
</>
|
|
@@ -353,8 +279,10 @@ export function KanbanBoard() {
|
|
|
353
279
|
)}
|
|
354
280
|
</div>
|
|
355
281
|
<div className="flex items-center gap-4 text-sm font-bold">
|
|
356
|
-
<span>
|
|
357
|
-
|
|
282
|
+
<span>
|
|
283
|
+
{projectTasks.filter((t) => t.status === 'in_progress').length} in progress
|
|
284
|
+
</span>
|
|
285
|
+
<span>{projectTasks.filter((t) => t.status === 'done').length} done</span>
|
|
358
286
|
</div>
|
|
359
287
|
</div>
|
|
360
288
|
</div>
|
|
@@ -376,11 +304,7 @@ export function KanbanBoard() {
|
|
|
376
304
|
|
|
377
305
|
{/* Kanban columns */}
|
|
378
306
|
<main className="flex-1 min-h-0 overflow-hidden">
|
|
379
|
-
<DndContext
|
|
380
|
-
sensors={sensors}
|
|
381
|
-
onDragStart={handleDragStart}
|
|
382
|
-
onDragEnd={handleDragEnd}
|
|
383
|
-
>
|
|
307
|
+
<DndContext sensors={sensors} onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
|
|
384
308
|
<div className="h-full px-6 py-6">
|
|
385
309
|
<div className="grid grid-cols-4 gap-6 h-full min-h-0">
|
|
386
310
|
{COLUMNS.map((column) => (
|
|
@@ -391,7 +315,7 @@ export function KanbanBoard() {
|
|
|
391
315
|
color={column.color}
|
|
392
316
|
tasks={getTasksByStatus(column.id)}
|
|
393
317
|
features={[]}
|
|
394
|
-
onRefresh={
|
|
318
|
+
onRefresh={() => invalidateTasks()}
|
|
395
319
|
/>
|
|
396
320
|
))}
|
|
397
321
|
</div>
|
|
@@ -404,7 +328,7 @@ export function KanbanBoard() {
|
|
|
404
328
|
task={activeTask}
|
|
405
329
|
feature={undefined}
|
|
406
330
|
features={[]}
|
|
407
|
-
onRefresh={
|
|
331
|
+
onRefresh={() => invalidateTasks()}
|
|
408
332
|
/>
|
|
409
333
|
</div>
|
|
410
334
|
) : null}
|
|
@@ -414,10 +338,7 @@ export function KanbanBoard() {
|
|
|
414
338
|
|
|
415
339
|
{/* Spec modal */}
|
|
416
340
|
{specPanelOpen && selectedSpecName && (
|
|
417
|
-
<SpecModal
|
|
418
|
-
specName={selectedSpecName}
|
|
419
|
-
onClose={() => setSpecPanelOpen(false)}
|
|
420
|
-
/>
|
|
341
|
+
<SpecModal specName={selectedSpecName} onClose={() => setSpecPanelOpen(false)} />
|
|
421
342
|
)}
|
|
422
343
|
</div>
|
|
423
344
|
</div>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
|
|
3
|
-
import { useDroppable } from
|
|
4
|
-
import { SortableContext, verticalListSortingStrategy } from
|
|
5
|
-
import { Task } from
|
|
6
|
-
import { TaskCard } from
|
|
7
|
-
import { cn } from
|
|
3
|
+
import { useDroppable } from '@dnd-kit/core';
|
|
4
|
+
import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
|
5
|
+
import { Task } from '@/db/schema';
|
|
6
|
+
import { TaskCard } from './task-card';
|
|
7
|
+
import { cn } from '@/lib/utils';
|
|
8
8
|
|
|
9
9
|
interface KanbanColumnProps {
|
|
10
10
|
id: string;
|
|
@@ -20,20 +20,18 @@ export function KanbanColumn({ id, title, color, tasks, onRefresh }: KanbanColum
|
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
22
|
<div className="flex flex-col h-full min-h-0">
|
|
23
|
-
<div className={cn(
|
|
23
|
+
<div className={cn('px-4 py-3 border-3 border-black border-b-0', color)}>
|
|
24
24
|
<h2 className="font-black uppercase tracking-wide text-black flex items-center justify-between">
|
|
25
25
|
<span>{title}</span>
|
|
26
|
-
<span className="text-sm font-bold bg-black text-white px-2 py-1">
|
|
27
|
-
{tasks.length}
|
|
28
|
-
</span>
|
|
26
|
+
<span className="text-sm font-bold bg-black text-white px-2 py-1">{tasks.length}</span>
|
|
29
27
|
</h2>
|
|
30
28
|
</div>
|
|
31
29
|
|
|
32
30
|
<div
|
|
33
31
|
ref={setNodeRef}
|
|
34
32
|
className={cn(
|
|
35
|
-
|
|
36
|
-
isOver &&
|
|
33
|
+
'flex-1 overflow-y-auto p-4 space-y-3 bg-white border-3 border-black transition-colors',
|
|
34
|
+
isOver && 'bg-gray-100',
|
|
37
35
|
)}
|
|
38
36
|
>
|
|
39
37
|
<SortableContext items={tasks.map((t) => t.id)} strategy={verticalListSortingStrategy}>
|
|
@@ -1,29 +1,40 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
|
|
3
|
-
import { useEffect, useRef, useMemo } from
|
|
4
|
-
import ReactMarkdown from
|
|
5
|
-
import remarkGfm from
|
|
6
|
-
import rehypeRaw from
|
|
7
|
-
import
|
|
8
|
-
import { cn } from "@/lib/utils";
|
|
9
|
-
|
|
10
|
-
mermaid.initialize({ startOnLoad: false, theme: "neutral" });
|
|
3
|
+
import { useEffect, useRef, useMemo, useState } from 'react';
|
|
4
|
+
import ReactMarkdown from 'react-markdown';
|
|
5
|
+
import remarkGfm from 'remark-gfm';
|
|
6
|
+
import rehypeRaw from 'rehype-raw';
|
|
7
|
+
import { cn } from '@/lib/utils';
|
|
11
8
|
|
|
12
9
|
let mermaidCounter = 0;
|
|
13
10
|
|
|
14
11
|
function MermaidBlock({ chart }: { chart: string }) {
|
|
15
12
|
const ref = useRef<HTMLDivElement>(null);
|
|
16
13
|
const id = useMemo(() => `mermaid-${++mermaidCounter}`, []);
|
|
14
|
+
const [error, setError] = useState<string | null>(null);
|
|
17
15
|
|
|
18
16
|
useEffect(() => {
|
|
19
17
|
if (!ref.current) return;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
let cancelled = false;
|
|
19
|
+
import('mermaid')
|
|
20
|
+
.then(({ default: mermaid }) => {
|
|
21
|
+
if (cancelled) return;
|
|
22
|
+
mermaid.initialize({ startOnLoad: false, theme: 'neutral' });
|
|
23
|
+
return mermaid.render(id, chart);
|
|
24
|
+
})
|
|
25
|
+
.then((result) => {
|
|
26
|
+
if (cancelled || !result) return;
|
|
27
|
+
if (ref.current) ref.current.innerHTML = result.svg;
|
|
28
|
+
})
|
|
29
|
+
.catch((err) => {
|
|
30
|
+
if (!cancelled && ref.current) setError(err.message);
|
|
31
|
+
});
|
|
32
|
+
return () => {
|
|
33
|
+
cancelled = true;
|
|
34
|
+
};
|
|
25
35
|
}, [id, chart]);
|
|
26
36
|
|
|
37
|
+
if (error) return <div className="my-4 text-red-600">Mermaid error: {error}</div>;
|
|
27
38
|
return <div ref={ref} className="my-4 overflow-x-auto" />;
|
|
28
39
|
}
|
|
29
40
|
|
|
@@ -34,7 +45,7 @@ interface MarkdownPreviewProps {
|
|
|
34
45
|
|
|
35
46
|
export function MarkdownPreview({ content, className }: MarkdownPreviewProps) {
|
|
36
47
|
return (
|
|
37
|
-
<div className={cn(
|
|
48
|
+
<div className={cn('markdown-preview', className)}>
|
|
38
49
|
<ReactMarkdown
|
|
39
50
|
remarkPlugins={[remarkGfm]}
|
|
40
51
|
rehypePlugins={[rehypeRaw]}
|
|
@@ -63,17 +74,23 @@ export function MarkdownPreview({ content, className }: MarkdownPreviewProps) {
|
|
|
63
74
|
</div>
|
|
64
75
|
),
|
|
65
76
|
thead: ({ children }) => <thead className="bg-black text-white">{children}</thead>,
|
|
66
|
-
th: ({ children }) =>
|
|
77
|
+
th: ({ children }) => (
|
|
78
|
+
<th className="px-3 py-2 text-left font-bold uppercase">{children}</th>
|
|
79
|
+
),
|
|
67
80
|
td: ({ children }) => <td className="px-3 py-2 border-t-2 border-black">{children}</td>,
|
|
68
81
|
// Code blocks + Mermaid
|
|
69
82
|
code: ({ className: cls, children, ...props }) => {
|
|
70
|
-
const lang = /language-(\w+)/.exec(cls ||
|
|
71
|
-
if (lang ===
|
|
83
|
+
const lang = /language-(\w+)/.exec(cls || '')?.[1];
|
|
84
|
+
if (lang === 'mermaid') {
|
|
72
85
|
return <MermaidBlock chart={String(children).trim()} />;
|
|
73
86
|
}
|
|
74
87
|
// Inline code (no language class)
|
|
75
88
|
if (!cls) {
|
|
76
|
-
return
|
|
89
|
+
return (
|
|
90
|
+
<code className="inline-code" {...props}>
|
|
91
|
+
{children}
|
|
92
|
+
</code>
|
|
93
|
+
);
|
|
77
94
|
}
|
|
78
95
|
return (
|
|
79
96
|
<pre className="code-block" data-lang={lang}>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
|
|
6
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
7
|
+
const [queryClient] = useState(
|
|
8
|
+
() =>
|
|
9
|
+
new QueryClient({
|
|
10
|
+
defaultOptions: {
|
|
11
|
+
queries: {
|
|
12
|
+
staleTime: 1000,
|
|
13
|
+
refetchOnWindowFocus: true,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
}),
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
|
|
20
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
interface ArtifactStatus {
|
|
2
2
|
id: string;
|
|
3
|
-
state:
|
|
3
|
+
state: 'blocked' | 'ready' | 'in_review' | 'in_progress' | 'done';
|
|
4
4
|
description: string;
|
|
5
5
|
requires: string[];
|
|
6
6
|
fileExists: boolean;
|
|
@@ -13,19 +13,19 @@ interface ArtifactDagStatusProps {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
const STATE_COLORS: Record<string, string> = {
|
|
16
|
-
blocked:
|
|
17
|
-
ready:
|
|
18
|
-
in_review:
|
|
19
|
-
in_progress:
|
|
20
|
-
done:
|
|
16
|
+
blocked: 'bg-gray-300 border-gray-400 text-gray-600',
|
|
17
|
+
ready: 'bg-blue-200 border-blue-500 text-blue-800',
|
|
18
|
+
in_review: 'bg-yellow-200 border-yellow-500 text-yellow-800',
|
|
19
|
+
in_progress: 'bg-orange-200 border-orange-500 text-orange-800',
|
|
20
|
+
done: 'bg-green-200 border-green-600 text-green-800',
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const STATE_LABELS: Record<string, string> = {
|
|
24
|
-
blocked:
|
|
25
|
-
ready:
|
|
26
|
-
in_review:
|
|
27
|
-
in_progress:
|
|
28
|
-
done:
|
|
24
|
+
blocked: 'Blocked',
|
|
25
|
+
ready: 'Ready',
|
|
26
|
+
in_review: 'In Review',
|
|
27
|
+
in_progress: 'In Progress',
|
|
28
|
+
done: 'Done',
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export function ArtifactDagStatus({ statuses }: ArtifactDagStatusProps) {
|
|
@@ -39,9 +39,7 @@ export function ArtifactDagStatus({ statuses }: ArtifactDagStatusProps) {
|
|
|
39
39
|
<div>{status.id}</div>
|
|
40
40
|
<div className="font-normal capitalize">{STATE_LABELS[status.state]}</div>
|
|
41
41
|
</div>
|
|
42
|
-
{index < statuses.length - 1 &&
|
|
43
|
-
<span className="text-gray-400 font-bold">→</span>
|
|
44
|
-
)}
|
|
42
|
+
{index < statuses.length - 1 && <span className="text-gray-400 font-bold">→</span>}
|
|
45
43
|
</div>
|
|
46
44
|
))}
|
|
47
45
|
</div>
|