@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
package/scripts/init-schema.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
const fs = require(
|
|
2
|
-
const path = require(
|
|
3
|
-
const yaml = require(
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const yaml = require('js-yaml');
|
|
4
4
|
|
|
5
5
|
function getProjectConfigPath(projectRoot) {
|
|
6
|
-
return path.join(projectRoot,
|
|
6
|
+
return path.join(projectRoot, 'devflow', 'project-config.json');
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
function readProjectConfig(projectRoot) {
|
|
10
10
|
const configPath = getProjectConfigPath(projectRoot);
|
|
11
11
|
if (!fs.existsSync(configPath)) return {};
|
|
12
12
|
try {
|
|
13
|
-
return JSON.parse(fs.readFileSync(configPath,
|
|
13
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
14
14
|
} catch {
|
|
15
15
|
return {};
|
|
16
16
|
}
|
|
@@ -19,7 +19,7 @@ function readProjectConfig(projectRoot) {
|
|
|
19
19
|
function writeProjectConfig(projectRoot, config) {
|
|
20
20
|
const configPath = getProjectConfigPath(projectRoot);
|
|
21
21
|
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
22
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2),
|
|
22
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function readSchemasFromDir(baseDir, source) {
|
|
@@ -31,9 +31,9 @@ function readSchemasFromDir(baseDir, source) {
|
|
|
31
31
|
|
|
32
32
|
const schemas = [];
|
|
33
33
|
for (const entryName of entries) {
|
|
34
|
-
const schemaPath = path.join(baseDir, entryName,
|
|
34
|
+
const schemaPath = path.join(baseDir, entryName, 'schema.yaml');
|
|
35
35
|
if (!fs.existsSync(schemaPath)) continue;
|
|
36
|
-
const parsed = yaml.load(fs.readFileSync(schemaPath,
|
|
36
|
+
const parsed = yaml.load(fs.readFileSync(schemaPath, 'utf-8')) || {};
|
|
37
37
|
if (!parsed.name) {
|
|
38
38
|
throw new Error(`Invalid schema at ${schemaPath}: missing name`);
|
|
39
39
|
}
|
|
@@ -41,7 +41,7 @@ function readSchemasFromDir(baseDir, source) {
|
|
|
41
41
|
id: String(parsed.name),
|
|
42
42
|
source,
|
|
43
43
|
schemaPath,
|
|
44
|
-
templatesDir: path.join(path.dirname(schemaPath),
|
|
44
|
+
templatesDir: path.join(path.dirname(schemaPath), 'templates'),
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
return schemas;
|
|
@@ -50,11 +50,11 @@ function readSchemasFromDir(baseDir, source) {
|
|
|
50
50
|
function discoverSchemaTemplates(options) {
|
|
51
51
|
const projectRoot = options.projectRoot;
|
|
52
52
|
const packageRoot = options.packageRoot;
|
|
53
|
-
const bundledDir = options.bundledDir || path.join(packageRoot,
|
|
54
|
-
const projectSchemaDir = path.join(projectRoot,
|
|
53
|
+
const bundledDir = options.bundledDir || path.join(packageRoot, 'src', 'schemas');
|
|
54
|
+
const projectSchemaDir = path.join(projectRoot, 'schemas');
|
|
55
55
|
|
|
56
|
-
const bundled = readSchemasFromDir(bundledDir,
|
|
57
|
-
const project = readSchemasFromDir(projectSchemaDir,
|
|
56
|
+
const bundled = readSchemasFromDir(bundledDir, 'bundled');
|
|
57
|
+
const project = readSchemasFromDir(projectSchemaDir, 'project');
|
|
58
58
|
const merged = [...bundled, ...project];
|
|
59
59
|
|
|
60
60
|
const idToSchema = new Map();
|
|
@@ -62,7 +62,7 @@ function discoverSchemaTemplates(options) {
|
|
|
62
62
|
const existing = idToSchema.get(schema.id);
|
|
63
63
|
if (existing) {
|
|
64
64
|
throw new Error(
|
|
65
|
-
`Schema ID conflict for "${schema.id}" between ${existing.source}:${existing.schemaPath} and ${schema.source}:${schema.schemaPath}
|
|
65
|
+
`Schema ID conflict for "${schema.id}" between ${existing.source}:${existing.schemaPath} and ${schema.source}:${schema.schemaPath}`,
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
idToSchema.set(schema.id, schema);
|
|
@@ -74,7 +74,7 @@ function discoverSchemaTemplates(options) {
|
|
|
74
74
|
function assertKnownSchema(schemaId, availableSchemaIds) {
|
|
75
75
|
if (!availableSchemaIds.includes(schemaId)) {
|
|
76
76
|
throw new Error(
|
|
77
|
-
`Unknown schema "${schemaId}". Available schemas: ${availableSchemaIds.join(
|
|
77
|
+
`Unknown schema "${schemaId}". Available schemas: ${availableSchemaIds.join(', ')}`,
|
|
78
78
|
);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
@@ -91,31 +91,31 @@ async function resolveInitSchemaSelection(options) {
|
|
|
91
91
|
|
|
92
92
|
if (requestedSchema) {
|
|
93
93
|
assertKnownSchema(requestedSchema, availableSchemaIds);
|
|
94
|
-
return { schemaId: requestedSchema, reason:
|
|
94
|
+
return { schemaId: requestedSchema, reason: 'explicit' };
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
if (!interactive) {
|
|
98
98
|
if (existingDefaultSchema && availableSchemaIds.includes(existingDefaultSchema)) {
|
|
99
|
-
return { schemaId: existingDefaultSchema, reason:
|
|
99
|
+
return { schemaId: existingDefaultSchema, reason: 'existing-default' };
|
|
100
100
|
}
|
|
101
|
-
if (availableSchemaIds.includes(
|
|
102
|
-
return { schemaId:
|
|
101
|
+
if (availableSchemaIds.includes('spec-driven')) {
|
|
102
|
+
return { schemaId: 'spec-driven', reason: 'non-interactive-fallback' };
|
|
103
103
|
}
|
|
104
104
|
throw new Error(
|
|
105
|
-
`Non-interactive init requires a schema. Available schemas: ${availableSchemaIds.join(
|
|
105
|
+
`Non-interactive init requires a schema. Available schemas: ${availableSchemaIds.join(', ')}`,
|
|
106
106
|
);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
if (existingDefaultSchema && availableSchemaIds.includes(existingDefaultSchema)) {
|
|
110
110
|
const keep = (await confirmKeepExisting(existingDefaultSchema)) !== false;
|
|
111
111
|
if (keep) {
|
|
112
|
-
return { schemaId: existingDefaultSchema, reason:
|
|
112
|
+
return { schemaId: existingDefaultSchema, reason: 'existing-default-kept' };
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
const selected = await promptSelectSchema(availableSchemaIds, existingDefaultSchema);
|
|
117
117
|
assertKnownSchema(selected, availableSchemaIds);
|
|
118
|
-
return { schemaId: selected, reason:
|
|
118
|
+
return { schemaId: selected, reason: 'interactive-selection' };
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
module.exports = {
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
const test = require(
|
|
2
|
-
const assert = require(
|
|
3
|
-
const fs = require(
|
|
4
|
-
const os = require(
|
|
5
|
-
const path = require(
|
|
1
|
+
const test = require('node:test');
|
|
2
|
+
const assert = require('node:assert/strict');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const path = require('path');
|
|
6
6
|
|
|
7
7
|
const {
|
|
8
8
|
discoverSchemaTemplates,
|
|
9
9
|
resolveInitSchemaSelection,
|
|
10
10
|
readProjectConfig,
|
|
11
11
|
writeProjectConfig,
|
|
12
|
-
} = require(
|
|
12
|
+
} = require('./init-schema');
|
|
13
13
|
|
|
14
14
|
function withTempDir(fn) {
|
|
15
|
-
const dir = fs.mkdtempSync(path.join(os.tmpdir(),
|
|
15
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'devflow-init-schema-'));
|
|
16
16
|
try {
|
|
17
17
|
return fn(dir);
|
|
18
18
|
} finally {
|
|
@@ -22,82 +22,82 @@ function withTempDir(fn) {
|
|
|
22
22
|
|
|
23
23
|
function writeSchema(baseDir, id) {
|
|
24
24
|
const schemaDir = path.join(baseDir, id);
|
|
25
|
-
fs.mkdirSync(path.join(schemaDir,
|
|
25
|
+
fs.mkdirSync(path.join(schemaDir, 'templates'), { recursive: true });
|
|
26
26
|
fs.writeFileSync(
|
|
27
|
-
path.join(schemaDir,
|
|
27
|
+
path.join(schemaDir, 'schema.yaml'),
|
|
28
28
|
`name: ${id}\nversion: 1\nartifacts: []\n`,
|
|
29
|
-
|
|
29
|
+
'utf-8',
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
test(
|
|
33
|
+
test('resolveInitSchemaSelection respects explicit schema', async () => {
|
|
34
34
|
const result = await resolveInitSchemaSelection({
|
|
35
|
-
requestedSchema:
|
|
36
|
-
existingDefaultSchema:
|
|
37
|
-
availableSchemaIds: [
|
|
35
|
+
requestedSchema: 'backend-api',
|
|
36
|
+
existingDefaultSchema: 'spec-driven',
|
|
37
|
+
availableSchemaIds: ['spec-driven', 'backend-api'],
|
|
38
38
|
interactive: false,
|
|
39
39
|
});
|
|
40
|
-
assert.equal(result.schemaId,
|
|
41
|
-
assert.equal(result.reason,
|
|
40
|
+
assert.equal(result.schemaId, 'backend-api');
|
|
41
|
+
assert.equal(result.reason, 'explicit');
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
test(
|
|
44
|
+
test('resolveInitSchemaSelection keeps existing default in interactive mode', async () => {
|
|
45
45
|
const result = await resolveInitSchemaSelection({
|
|
46
|
-
existingDefaultSchema:
|
|
47
|
-
availableSchemaIds: [
|
|
46
|
+
existingDefaultSchema: 'frontend-product',
|
|
47
|
+
availableSchemaIds: ['frontend-product', 'spec-driven'],
|
|
48
48
|
interactive: true,
|
|
49
49
|
confirmKeepExisting: async () => true,
|
|
50
|
-
promptSelectSchema: async () =>
|
|
50
|
+
promptSelectSchema: async () => 'spec-driven',
|
|
51
51
|
});
|
|
52
|
-
assert.equal(result.schemaId,
|
|
53
|
-
assert.equal(result.reason,
|
|
52
|
+
assert.equal(result.schemaId, 'frontend-product');
|
|
53
|
+
assert.equal(result.reason, 'existing-default-kept');
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
-
test(
|
|
56
|
+
test('resolveInitSchemaSelection uses fallback in non-interactive mode', async () => {
|
|
57
57
|
const result = await resolveInitSchemaSelection({
|
|
58
|
-
availableSchemaIds: [
|
|
58
|
+
availableSchemaIds: ['spec-driven', 'backend-api'],
|
|
59
59
|
interactive: false,
|
|
60
60
|
});
|
|
61
|
-
assert.equal(result.schemaId,
|
|
62
|
-
assert.equal(result.reason,
|
|
61
|
+
assert.equal(result.schemaId, 'spec-driven');
|
|
62
|
+
assert.equal(result.reason, 'non-interactive-fallback');
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
test(
|
|
65
|
+
test('discoverSchemaTemplates returns bundled and project schemas', () =>
|
|
66
66
|
withTempDir((root) => {
|
|
67
|
-
const projectRoot = path.join(root,
|
|
68
|
-
const packageRoot = path.join(root,
|
|
69
|
-
const bundledDir = path.join(packageRoot,
|
|
70
|
-
fs.mkdirSync(path.join(projectRoot,
|
|
67
|
+
const projectRoot = path.join(root, 'project');
|
|
68
|
+
const packageRoot = path.join(root, 'package');
|
|
69
|
+
const bundledDir = path.join(packageRoot, 'src', 'schemas');
|
|
70
|
+
fs.mkdirSync(path.join(projectRoot, 'schemas'), { recursive: true });
|
|
71
71
|
fs.mkdirSync(bundledDir, { recursive: true });
|
|
72
72
|
|
|
73
|
-
writeSchema(bundledDir,
|
|
74
|
-
writeSchema(path.join(projectRoot,
|
|
73
|
+
writeSchema(bundledDir, 'spec-driven');
|
|
74
|
+
writeSchema(path.join(projectRoot, 'schemas'), 'custom-team');
|
|
75
75
|
|
|
76
76
|
const schemas = discoverSchemaTemplates({ projectRoot, packageRoot, bundledDir });
|
|
77
77
|
const ids = schemas.map((s) => s.id);
|
|
78
|
-
assert.deepEqual(ids, [
|
|
78
|
+
assert.deepEqual(ids, ['custom-team', 'spec-driven']);
|
|
79
79
|
}));
|
|
80
80
|
|
|
81
|
-
test(
|
|
81
|
+
test('discoverSchemaTemplates fails on duplicate IDs', () =>
|
|
82
82
|
withTempDir((root) => {
|
|
83
|
-
const projectRoot = path.join(root,
|
|
84
|
-
const packageRoot = path.join(root,
|
|
85
|
-
const bundledDir = path.join(packageRoot,
|
|
86
|
-
fs.mkdirSync(path.join(projectRoot,
|
|
83
|
+
const projectRoot = path.join(root, 'project');
|
|
84
|
+
const packageRoot = path.join(root, 'package');
|
|
85
|
+
const bundledDir = path.join(packageRoot, 'src', 'schemas');
|
|
86
|
+
fs.mkdirSync(path.join(projectRoot, 'schemas'), { recursive: true });
|
|
87
87
|
fs.mkdirSync(bundledDir, { recursive: true });
|
|
88
88
|
|
|
89
|
-
writeSchema(bundledDir,
|
|
90
|
-
writeSchema(path.join(projectRoot,
|
|
89
|
+
writeSchema(bundledDir, 'spec-driven');
|
|
90
|
+
writeSchema(path.join(projectRoot, 'schemas'), 'spec-driven');
|
|
91
91
|
|
|
92
92
|
assert.throws(
|
|
93
93
|
() => discoverSchemaTemplates({ projectRoot, packageRoot, bundledDir }),
|
|
94
|
-
/Schema ID conflict
|
|
94
|
+
/Schema ID conflict/,
|
|
95
95
|
);
|
|
96
96
|
}));
|
|
97
97
|
|
|
98
|
-
test(
|
|
98
|
+
test('project config read/write round-trip', () =>
|
|
99
99
|
withTempDir((projectRoot) => {
|
|
100
|
-
writeProjectConfig(projectRoot, { defaultSchemaTemplateId:
|
|
100
|
+
writeProjectConfig(projectRoot, { defaultSchemaTemplateId: 'devops-platform' });
|
|
101
101
|
const cfg = readProjectConfig(projectRoot);
|
|
102
|
-
assert.equal(cfg.defaultSchemaTemplateId,
|
|
102
|
+
assert.equal(cfg.defaultSchemaTemplateId, 'devops-platform');
|
|
103
103
|
}));
|
|
@@ -17,7 +17,14 @@ function parseTools(value) {
|
|
|
17
17
|
const raw = (value ?? 'all').trim().toLowerCase();
|
|
18
18
|
if (raw === 'none') return [];
|
|
19
19
|
if (raw === 'all') return [...SUPPORTED_TOOLS];
|
|
20
|
-
return [
|
|
20
|
+
return [
|
|
21
|
+
...new Set(
|
|
22
|
+
raw
|
|
23
|
+
.split(',')
|
|
24
|
+
.map((p) => normalizeToolId(p.trim()))
|
|
25
|
+
.filter(Boolean),
|
|
26
|
+
),
|
|
27
|
+
];
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
function defaultCommandExists(command) {
|
|
@@ -36,7 +43,7 @@ function buildDetectionContext(projectRoot, overrides = {}) {
|
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
function createDetectedEnvironment(id, signals) {
|
|
39
|
-
const detected = signals.some(signal => signal.present);
|
|
46
|
+
const detected = signals.some((signal) => signal.present);
|
|
40
47
|
return { id, detected, signals };
|
|
41
48
|
}
|
|
42
49
|
|
|
@@ -46,7 +53,11 @@ function detectCodex(context) {
|
|
|
46
53
|
: path.join(context.homedir, '.codex');
|
|
47
54
|
return createDetectedEnvironment('codex', [
|
|
48
55
|
{ kind: 'binary', name: 'codex', present: context.commandExists('codex') },
|
|
49
|
-
{
|
|
56
|
+
{
|
|
57
|
+
kind: 'directory',
|
|
58
|
+
name: path.join(context.projectRoot, '.codex'),
|
|
59
|
+
present: context.pathExists(path.join(context.projectRoot, '.codex')),
|
|
60
|
+
},
|
|
50
61
|
{ kind: 'directory', name: codexHome, present: context.pathExists(codexHome) },
|
|
51
62
|
]);
|
|
52
63
|
}
|
|
@@ -54,8 +65,16 @@ function detectCodex(context) {
|
|
|
54
65
|
function detectClaudeCode(context) {
|
|
55
66
|
return createDetectedEnvironment('claudecode', [
|
|
56
67
|
{ kind: 'binary', name: 'claude', present: context.commandExists('claude') },
|
|
57
|
-
{
|
|
58
|
-
|
|
68
|
+
{
|
|
69
|
+
kind: 'directory',
|
|
70
|
+
name: path.join(context.projectRoot, '.claude'),
|
|
71
|
+
present: context.pathExists(path.join(context.projectRoot, '.claude')),
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
kind: 'directory',
|
|
75
|
+
name: path.join(context.homedir, '.claude'),
|
|
76
|
+
present: context.pathExists(path.join(context.homedir, '.claude')),
|
|
77
|
+
},
|
|
59
78
|
]);
|
|
60
79
|
}
|
|
61
80
|
|
|
@@ -69,13 +88,13 @@ function getEnvironmentDetectors() {
|
|
|
69
88
|
function detectEnvironments(projectRoot, overrides = {}) {
|
|
70
89
|
const context = buildDetectionContext(projectRoot, overrides);
|
|
71
90
|
const detectors = getEnvironmentDetectors();
|
|
72
|
-
return SUPPORTED_TOOLS.map(tool => detectors[tool].detect(context));
|
|
91
|
+
return SUPPORTED_TOOLS.map((tool) => detectors[tool].detect(context));
|
|
73
92
|
}
|
|
74
93
|
|
|
75
94
|
function detectInstalledTools(projectRoot, overrides = {}) {
|
|
76
95
|
return detectEnvironments(projectRoot, overrides)
|
|
77
|
-
.filter(result => result.detected)
|
|
78
|
-
.map(result => result.id);
|
|
96
|
+
.filter((result) => result.detected)
|
|
97
|
+
.map((result) => result.id);
|
|
79
98
|
}
|
|
80
99
|
|
|
81
100
|
function getToolAdapters() {
|
|
@@ -13,7 +13,7 @@ const HOME_DIR = '/home/tester';
|
|
|
13
13
|
|
|
14
14
|
function detectionHarness({ commands = [], paths = [] } = {}) {
|
|
15
15
|
const commandSet = new Set(commands);
|
|
16
|
-
const pathSet = new Set(paths.map(p => path.resolve(p)));
|
|
16
|
+
const pathSet = new Set(paths.map((p) => path.resolve(p)));
|
|
17
17
|
return {
|
|
18
18
|
commandExists: (command) => commandSet.has(command),
|
|
19
19
|
pathExists: (targetPath) => pathSet.has(path.resolve(targetPath)),
|
|
@@ -23,23 +23,32 @@ function detectionHarness({ commands = [], paths = [] } = {}) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
test('detectInstalledTools returns claudecode when only Claude signals are present', () => {
|
|
26
|
-
const detected = detectInstalledTools(
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
const detected = detectInstalledTools(
|
|
27
|
+
PROJECT_ROOT,
|
|
28
|
+
detectionHarness({
|
|
29
|
+
commands: ['claude'],
|
|
30
|
+
}),
|
|
31
|
+
);
|
|
29
32
|
assert.deepEqual(detected, ['claudecode']);
|
|
30
33
|
});
|
|
31
34
|
|
|
32
35
|
test('detectInstalledTools returns codex when only Codex signals are present', () => {
|
|
33
|
-
const detected = detectInstalledTools(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const detected = detectInstalledTools(
|
|
37
|
+
PROJECT_ROOT,
|
|
38
|
+
detectionHarness({
|
|
39
|
+
commands: ['codex'],
|
|
40
|
+
}),
|
|
41
|
+
);
|
|
36
42
|
assert.deepEqual(detected, ['codex']);
|
|
37
43
|
});
|
|
38
44
|
|
|
39
45
|
test('detectInstalledTools returns both tools when both signals are present', () => {
|
|
40
|
-
const detected = detectInstalledTools(
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
const detected = detectInstalledTools(
|
|
47
|
+
PROJECT_ROOT,
|
|
48
|
+
detectionHarness({
|
|
49
|
+
commands: ['codex', 'claude'],
|
|
50
|
+
}),
|
|
51
|
+
);
|
|
43
52
|
assert.deepEqual(detected, ['codex', 'claudecode']);
|
|
44
53
|
});
|
|
45
54
|
|
|
@@ -2,15 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const fs = require('fs');
|
|
5
|
-
const {
|
|
6
|
-
parseTools,
|
|
7
|
-
getToolAdapter,
|
|
8
|
-
detectEnvironments,
|
|
9
|
-
} = require('./install-environments');
|
|
5
|
+
const { parseTools, getToolAdapter, detectEnvironments } = require('./install-environments');
|
|
10
6
|
|
|
11
7
|
const MANAGED_BEGIN = '<!-- DEVFLOW:BEGIN ';
|
|
12
8
|
const MANAGED_END = '<!-- DEVFLOW:END ';
|
|
13
|
-
const COMMAND_SET = ['new', 'continue', 'status', 'promote', 'develop', 'archive'];
|
|
9
|
+
const COMMAND_SET = ['new', 'continue', 'status', 'promote', 'develop', 'archive', 'schema'];
|
|
14
10
|
|
|
15
11
|
function resolveToolDirs(projectRoot, tool) {
|
|
16
12
|
return getToolAdapter(tool).resolveTargets(projectRoot);
|
|
@@ -138,6 +134,44 @@ function renderSkill(tool, command, markerId) {
|
|
|
138
134
|
'4. Call `archive_spec`.',
|
|
139
135
|
'5. Report success and the archive path.',
|
|
140
136
|
],
|
|
137
|
+
schema: [
|
|
138
|
+
`# Skill: /df:schema`,
|
|
139
|
+
'',
|
|
140
|
+
`Use this skill to interactively create a custom DevFlow schema in ${agentName}.`,
|
|
141
|
+
'',
|
|
142
|
+
'## Steps (in order)',
|
|
143
|
+
'',
|
|
144
|
+
'1. Call `list_schemas` and show the user what schemas are already available.',
|
|
145
|
+
' If one fits their needs, suggest using it directly.',
|
|
146
|
+
'2. Ask what kind of project/workflow they need (e.g. mobile app, ML pipeline,',
|
|
147
|
+
' infrastructure, documentation, data engineering, security review, etc.).',
|
|
148
|
+
'3. Based on the project type, ask which artifacts/documents their workflow',
|
|
149
|
+
' should include. Suggest sensible defaults. Common options:',
|
|
150
|
+
' - Proposal / RFC',
|
|
151
|
+
' - Requirements / Specifications',
|
|
152
|
+
' - Architecture / Design doc',
|
|
153
|
+
' - Security review',
|
|
154
|
+
' - Testing plan / Test strategy',
|
|
155
|
+
' - Migration plan',
|
|
156
|
+
' - Deployment / Runbook',
|
|
157
|
+
' - Implementation tasks',
|
|
158
|
+
'4. Design the artifact dependency DAG — which artifacts must be approved',
|
|
159
|
+
' before others can be written. Present the DAG to the user for confirmation.',
|
|
160
|
+
'5. Ask about quality rules:',
|
|
161
|
+
' - RFC 2119 keywords enforced (MUST/SHOULD/MAY)?',
|
|
162
|
+
' - Minimum scenarios per requirement (suggest 1-2)?',
|
|
163
|
+
'6. Generate well-structured markdown templates for each artifact.',
|
|
164
|
+
'7. Call `create_schema` with name, artifacts, qualityRules, apply, and templates.',
|
|
165
|
+
'8. Report the schema was created and how to use it:',
|
|
166
|
+
' - `create_spec` with `schema: "<name>"`',
|
|
167
|
+
' - Or set as default in `devflow/project-config.json`',
|
|
168
|
+
'',
|
|
169
|
+
'## Guidelines',
|
|
170
|
+
'- Keep artifact IDs short and kebab-case (e.g. "security-review", "test-plan")',
|
|
171
|
+
'- Template filenames should match: `<artifact-id>.md`',
|
|
172
|
+
'- Always include a final "tasks" artifact that depends on the key artifacts',
|
|
173
|
+
'- The `apply.requires` should include at minimum the tasks artifact',
|
|
174
|
+
],
|
|
141
175
|
};
|
|
142
176
|
|
|
143
177
|
const lines = bodies[command];
|
|
@@ -147,9 +181,10 @@ function renderSkill(tool, command, markerId) {
|
|
|
147
181
|
|
|
148
182
|
function renderCommand(tool, command, markerId) {
|
|
149
183
|
const commandName = `/df:${command}`;
|
|
150
|
-
const codexHeader =
|
|
151
|
-
|
|
152
|
-
|
|
184
|
+
const codexHeader =
|
|
185
|
+
tool === 'codex'
|
|
186
|
+
? ['---', `description: DevFlow ${commandName} workflow action`, '---', '']
|
|
187
|
+
: [];
|
|
153
188
|
|
|
154
189
|
const bodies = {
|
|
155
190
|
new: [
|
|
@@ -262,6 +297,24 @@ function renderCommand(tool, command, markerId) {
|
|
|
262
297
|
'4. Call `archive_spec`.',
|
|
263
298
|
'5. Report success and the archive path.',
|
|
264
299
|
],
|
|
300
|
+
schema: [
|
|
301
|
+
`# ${commandName}`,
|
|
302
|
+
'',
|
|
303
|
+
'Interactively create a custom DevFlow schema.',
|
|
304
|
+
'',
|
|
305
|
+
'## Steps (in order)',
|
|
306
|
+
'',
|
|
307
|
+
'1. Call `list_schemas` and show available schemas. If one fits, suggest it.',
|
|
308
|
+
'2. Ask what kind of project/workflow the user needs.',
|
|
309
|
+
'3. Ask which artifacts/documents their workflow should include.',
|
|
310
|
+
'4. Design the artifact dependency DAG. Present it for confirmation.',
|
|
311
|
+
'5. Ask about quality rules (RFC 2119, min scenarios per requirement).',
|
|
312
|
+
'6. Generate markdown templates for each artifact.',
|
|
313
|
+
'7. Call `create_schema` with name, artifacts, qualityRules, apply, and templates.',
|
|
314
|
+
'8. Report the schema was created and how to use it:',
|
|
315
|
+
' - `create_spec` with `schema: "<name>"`',
|
|
316
|
+
' - Or set as default in `devflow/project-config.json`',
|
|
317
|
+
],
|
|
265
318
|
};
|
|
266
319
|
|
|
267
320
|
const bodyLines = bodies[command];
|
|
@@ -273,7 +326,7 @@ function replaceManagedSection(existing, markerId, nextContent) {
|
|
|
273
326
|
const escaped = markerId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
274
327
|
const pattern = new RegExp(
|
|
275
328
|
`<!-- DEVFLOW:BEGIN ${escaped} -->[\\s\\S]*?<!-- DEVFLOW:END ${escaped} -->\\n?`,
|
|
276
|
-
'm'
|
|
329
|
+
'm',
|
|
277
330
|
);
|
|
278
331
|
if (!pattern.test(existing)) return null;
|
|
279
332
|
return existing.replace(pattern, nextContent);
|
|
@@ -300,7 +353,9 @@ function buildAssets(projectRoot, tools, delivery) {
|
|
|
300
353
|
const commandMarker = `${tool}:command:df-${command}`;
|
|
301
354
|
if (delivery !== 'commands') {
|
|
302
355
|
assets.push({
|
|
303
|
-
tool,
|
|
356
|
+
tool,
|
|
357
|
+
kind: 'skill',
|
|
358
|
+
command,
|
|
304
359
|
outputPath: path.join(dirs.skillsDir, `df-${command}.md`),
|
|
305
360
|
markerId: skillMarker,
|
|
306
361
|
content: renderSkill(tool, command, skillMarker),
|
|
@@ -308,7 +363,9 @@ function buildAssets(projectRoot, tools, delivery) {
|
|
|
308
363
|
}
|
|
309
364
|
if (delivery !== 'skills') {
|
|
310
365
|
assets.push({
|
|
311
|
-
tool,
|
|
366
|
+
tool,
|
|
367
|
+
kind: 'command',
|
|
368
|
+
command,
|
|
312
369
|
outputPath: path.join(dirs.commandsDir, `df-${command}.md`),
|
|
313
370
|
markerId: commandMarker,
|
|
314
371
|
content: renderCommand(tool, command, commandMarker),
|
|
@@ -329,7 +386,7 @@ function selectTools(projectRoot, options) {
|
|
|
329
386
|
} else if (options.tools !== undefined) {
|
|
330
387
|
selectedTools = parseTools(options.tools);
|
|
331
388
|
} else if (autodetect) {
|
|
332
|
-
selectedTools = detection.filter(d => d.detected).map(d => d.id);
|
|
389
|
+
selectedTools = detection.filter((d) => d.detected).map((d) => d.id);
|
|
333
390
|
} else {
|
|
334
391
|
selectedTools = parseTools('all');
|
|
335
392
|
}
|
|
@@ -354,17 +411,17 @@ function installSkills(projectRoot, options = {}) {
|
|
|
354
411
|
dryRun,
|
|
355
412
|
autodetect: selection.autodetect,
|
|
356
413
|
selectedTools: selection.selectedTools,
|
|
357
|
-
environments: selection.detection.map(d => ({
|
|
414
|
+
environments: selection.detection.map((d) => ({
|
|
358
415
|
tool: d.id,
|
|
359
416
|
detected: d.detected,
|
|
360
|
-
status: selection.selectedTools.includes(d.id)
|
|
361
|
-
? (dryRun ? 'planned' : 'pending')
|
|
362
|
-
: 'skipped',
|
|
417
|
+
status: selection.selectedTools.includes(d.id) ? (dryRun ? 'planned' : 'pending') : 'skipped',
|
|
363
418
|
reason: selection.selectedTools.includes(d.id)
|
|
364
419
|
? undefined
|
|
365
|
-
:
|
|
366
|
-
?
|
|
367
|
-
|
|
420
|
+
: selection.autodetect && options.tools === undefined && !options.only
|
|
421
|
+
? d.detected
|
|
422
|
+
? 'not-selected'
|
|
423
|
+
: 'not-detected'
|
|
424
|
+
: 'not-selected',
|
|
368
425
|
created: 0,
|
|
369
426
|
updated: 0,
|
|
370
427
|
skipped: 0,
|
|
@@ -378,7 +435,7 @@ function installSkills(projectRoot, options = {}) {
|
|
|
378
435
|
|
|
379
436
|
for (const asset of assets) {
|
|
380
437
|
const { outputPath, markerId, content, tool } = asset;
|
|
381
|
-
const envReport = report.environments.find(e => e.tool === tool);
|
|
438
|
+
const envReport = report.environments.find((e) => e.tool === tool);
|
|
382
439
|
const displayPath = path.relative(projectRoot, outputPath);
|
|
383
440
|
try {
|
|
384
441
|
const alreadyExists = exists(outputPath);
|
|
@@ -393,7 +450,11 @@ function installSkills(projectRoot, options = {}) {
|
|
|
393
450
|
}
|
|
394
451
|
report.updated++;
|
|
395
452
|
if (envReport) envReport.updated++;
|
|
396
|
-
report.results.push({
|
|
453
|
+
report.results.push({
|
|
454
|
+
...asset,
|
|
455
|
+
path: displayPath,
|
|
456
|
+
action: dryRun ? 'would_update' : 'updated',
|
|
457
|
+
});
|
|
397
458
|
} else {
|
|
398
459
|
report.skipped++;
|
|
399
460
|
if (envReport) envReport.skipped++;
|
|
@@ -403,7 +464,7 @@ function installSkills(projectRoot, options = {}) {
|
|
|
403
464
|
}
|
|
404
465
|
|
|
405
466
|
const ownershipError = new Error(
|
|
406
|
-
`Refusing to modify unmanaged file for ${tool}: ${displayPath}
|
|
467
|
+
`Refusing to modify unmanaged file for ${tool}: ${displayPath}`,
|
|
407
468
|
);
|
|
408
469
|
ownershipError.code = 'UNMANAGED_FILE';
|
|
409
470
|
throw ownershipError;
|
|
@@ -414,7 +475,11 @@ function installSkills(projectRoot, options = {}) {
|
|
|
414
475
|
}
|
|
415
476
|
report.created++;
|
|
416
477
|
if (envReport) envReport.created++;
|
|
417
|
-
report.results.push({
|
|
478
|
+
report.results.push({
|
|
479
|
+
...asset,
|
|
480
|
+
path: displayPath,
|
|
481
|
+
action: dryRun ? 'would_create' : 'created',
|
|
482
|
+
});
|
|
418
483
|
} catch (error) {
|
|
419
484
|
report.failed++;
|
|
420
485
|
if (envReport) envReport.failed++;
|
|
@@ -432,7 +497,8 @@ function installSkills(projectRoot, options = {}) {
|
|
|
432
497
|
if (!selection.selectedTools.includes(envReport.tool)) continue;
|
|
433
498
|
if (envReport.failed > 0) {
|
|
434
499
|
envReport.status = 'failed';
|
|
435
|
-
envReport.reason =
|
|
500
|
+
envReport.reason =
|
|
501
|
+
envReport.created + envReport.updated > 0 ? 'partial-failure' : 'install-failed';
|
|
436
502
|
} else if (dryRun) {
|
|
437
503
|
envReport.status = 'planned';
|
|
438
504
|
} else {
|
|
@@ -449,22 +515,29 @@ function printReport(report) {
|
|
|
449
515
|
for (const env of report.environments) {
|
|
450
516
|
const statusDetails = env.reason ? `${env.status} (${env.reason})` : env.status;
|
|
451
517
|
const detectedText = env.detected ? 'detected' : 'not detected';
|
|
452
|
-
console.log(
|
|
518
|
+
console.log(
|
|
519
|
+
` - ${env.tool}: ${statusDetails}; ${detectedText}; created=${env.created} updated=${env.updated} skipped=${env.skipped} failed=${env.failed}`,
|
|
520
|
+
);
|
|
453
521
|
}
|
|
454
522
|
console.log('');
|
|
455
523
|
}
|
|
456
524
|
|
|
457
525
|
for (const r of report.results) {
|
|
458
526
|
const icon =
|
|
459
|
-
r.action === 'created' || r.action === 'would_create'
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
527
|
+
r.action === 'created' || r.action === 'would_create'
|
|
528
|
+
? '✓'
|
|
529
|
+
: r.action === 'updated' || r.action === 'would_update'
|
|
530
|
+
? '↻'
|
|
531
|
+
: r.action === 'failed'
|
|
532
|
+
? '✗'
|
|
533
|
+
: '–';
|
|
463
534
|
const errorSuffix = r.action === 'failed' ? ` - ${r.error}` : '';
|
|
464
535
|
console.log(` ${icon} [${r.tool}] ${r.kind} ${r.path} (${r.action})${errorSuffix}`);
|
|
465
536
|
}
|
|
466
537
|
const mode = report.dryRun ? ' (dry-run)' : '';
|
|
467
|
-
console.log(
|
|
538
|
+
console.log(
|
|
539
|
+
`\n ${report.created} created, ${report.updated} updated, ${report.skipped} skipped, ${report.failed} failed${mode}`,
|
|
540
|
+
);
|
|
468
541
|
}
|
|
469
542
|
|
|
470
543
|
// CLI usage: node scripts/install-skills.js [--tools all|codex|claudecode] [--delivery both|skills|commands] [--force]
|