@arimakouyou/spec-workflow-mcp 2.2.7
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/.claude-plugin/.mcp.json +8 -0
- package/.claude-plugin/agents/code-simplifier.md +80 -0
- package/.claude-plugin/agents/integ-test-auditor.md +91 -0
- package/.claude-plugin/agents/integ-test-worker.md +73 -0
- package/.claude-plugin/agents/parallel-worker.md +136 -0
- package/.claude-plugin/agents/review-worker.md +279 -0
- package/.claude-plugin/agents/unit-test-engineer.md +148 -0
- package/.claude-plugin/agents/wave-harness-worker.md +158 -0
- package/.claude-plugin/hooks/hooks.json +16 -0
- package/.claude-plugin/hooks/tasks-read-guard.sh +17 -0
- package/.claude-plugin/marketplace.json +33 -0
- package/.claude-plugin/plugin.json +11 -0
- package/.claude-plugin/rules/axum.md +154 -0
- package/.claude-plugin/rules/cargo-toml.md +63 -0
- package/.claude-plugin/rules/context7.md +17 -0
- package/.claude-plugin/rules/design-conformance.md +82 -0
- package/.claude-plugin/rules/design-principles.md +53 -0
- package/.claude-plugin/rules/diesel.md +176 -0
- package/.claude-plugin/rules/feedback-loop.md +33 -0
- package/.claude-plugin/rules/leptos.md +319 -0
- package/.claude-plugin/rules/project-architecture.md +134 -0
- package/.claude-plugin/rules/quality-checks.md +265 -0
- package/.claude-plugin/rules/rust-style.md +242 -0
- package/.claude-plugin/rules/security.md +67 -0
- package/.claude-plugin/rules/spec-workflow-enforcement.md +47 -0
- package/.claude-plugin/rules/valkey.md +167 -0
- package/.claude-plugin/skills/integration-test/SKILL.md +230 -0
- package/.claude-plugin/skills/integration-test/references/auditor-prompt.md +78 -0
- package/.claude-plugin/skills/integration-test/references/external-api-mock.md +98 -0
- package/.claude-plugin/skills/integration-test/references/fixture-catalog.md +155 -0
- package/.claude-plugin/skills/integration-test/references/parallel-execution.md +124 -0
- package/.claude-plugin/skills/integration-test/references/quality-gate.md +80 -0
- package/.claude-plugin/skills/integration-test/references/test-case-design.md +88 -0
- package/.claude-plugin/skills/integration-test/references/test-patterns.md +215 -0
- package/.claude-plugin/skills/integration-test/references/whiteboard-template.md +81 -0
- package/.claude-plugin/skills/integration-test/references/worker-prompt.md +70 -0
- package/.claude-plugin/skills/knowhow-capture/SKILL.md +143 -0
- package/.claude-plugin/skills/phase-review-team/SKILL.md +380 -0
- package/.claude-plugin/skills/spec-design/SKILL.md +282 -0
- package/.claude-plugin/skills/spec-e2e-implement/SKILL.md +259 -0
- package/.claude-plugin/skills/spec-impl-code/SKILL.md +101 -0
- package/.claude-plugin/skills/spec-impl-review/SKILL.md +115 -0
- package/.claude-plugin/skills/spec-impl-test-run/SKILL.md +98 -0
- package/.claude-plugin/skills/spec-impl-test-write/SKILL.md +121 -0
- package/.claude-plugin/skills/spec-implement/SKILL.md +822 -0
- package/.claude-plugin/skills/spec-requirements/SKILL.md +130 -0
- package/.claude-plugin/skills/spec-review/SKILL.md +274 -0
- package/.claude-plugin/skills/spec-tasks/SKILL.md +372 -0
- package/.claude-plugin/skills/spec-test-design/SKILL.md +233 -0
- package/.claude-plugin/skills/tdd-skills/SKILL.md +95 -0
- package/.claude-plugin/skills/tdd-skills/references/advanced-techniques.md +49 -0
- package/.claude-plugin/skills/tdd-skills/references/green-strategies.md +70 -0
- package/.claude-plugin/skills/tdd-skills/references/tdd-and-design.md +48 -0
- package/.claude-plugin/skills/tdd-skills/references/test-design.md +43 -0
- package/.claude-plugin/skills/tdd-skills/references/test-doubles.md +53 -0
- package/.claude-plugin/skills/tdd-skills/references/test-patterns.md +40 -0
- package/.claude-plugin/skills/tdd-skills-rust/SKILL.md +128 -0
- package/.claude-plugin/skills/tdd-skills-rust/references/advanced-techniques.md +205 -0
- package/.claude-plugin/skills/tdd-skills-rust/references/green-strategies.md +166 -0
- package/.claude-plugin/skills/tdd-skills-rust/references/tdd-and-design.md +215 -0
- package/.claude-plugin/skills/tdd-skills-rust/references/test-design.md +128 -0
- package/.claude-plugin/skills/tdd-skills-rust/references/test-doubles.md +208 -0
- package/.claude-plugin/skills/tdd-skills-rust/references/test-patterns.md +223 -0
- package/.claude-plugin/with-dashboard/.mcp.json +8 -0
- package/.claude-plugin/with-dashboard/plugin.json +10 -0
- package/CHANGELOG.md +1007 -0
- package/LICENSE +674 -0
- package/README.ja.md +380 -0
- package/README.md +437 -0
- package/dist/__tests__/config.test.d.ts +2 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +264 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/index-args.test.d.ts +2 -0
- package/dist/__tests__/index-args.test.d.ts.map +1 -0
- package/dist/__tests__/index-args.test.js +43 -0
- package/dist/__tests__/index-args.test.js.map +1 -0
- package/dist/__tests__/index-entrypoint.test.d.ts +2 -0
- package/dist/__tests__/index-entrypoint.test.d.ts.map +1 -0
- package/dist/__tests__/index-entrypoint.test.js +23 -0
- package/dist/__tests__/index-entrypoint.test.js.map +1 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +188 -0
- package/dist/config.js.map +1 -0
- package/dist/core/__tests__/git-utils.test.d.ts +2 -0
- package/dist/core/__tests__/git-utils.test.d.ts.map +1 -0
- package/dist/core/__tests__/git-utils.test.js +179 -0
- package/dist/core/__tests__/git-utils.test.js.map +1 -0
- package/dist/core/__tests__/mdx-validator.test.d.ts +2 -0
- package/dist/core/__tests__/mdx-validator.test.d.ts.map +1 -0
- package/dist/core/__tests__/mdx-validator.test.js +42 -0
- package/dist/core/__tests__/mdx-validator.test.js.map +1 -0
- package/dist/core/__tests__/path-utils.test.d.ts +2 -0
- package/dist/core/__tests__/path-utils.test.d.ts.map +1 -0
- package/dist/core/__tests__/path-utils.test.js +342 -0
- package/dist/core/__tests__/path-utils.test.js.map +1 -0
- package/dist/core/__tests__/project-registry.test.d.ts +2 -0
- package/dist/core/__tests__/project-registry.test.d.ts.map +1 -0
- package/dist/core/__tests__/project-registry.test.js +62 -0
- package/dist/core/__tests__/project-registry.test.js.map +1 -0
- package/dist/core/__tests__/security-utils.test.d.ts +2 -0
- package/dist/core/__tests__/security-utils.test.d.ts.map +1 -0
- package/dist/core/__tests__/security-utils.test.js +657 -0
- package/dist/core/__tests__/security-utils.test.js.map +1 -0
- package/dist/core/__tests__/task-parser.test.d.ts +2 -0
- package/dist/core/__tests__/task-parser.test.d.ts.map +1 -0
- package/dist/core/__tests__/task-parser.test.js +222 -0
- package/dist/core/__tests__/task-parser.test.js.map +1 -0
- package/dist/core/__tests__/task-validator.test.d.ts +2 -0
- package/dist/core/__tests__/task-validator.test.d.ts.map +1 -0
- package/dist/core/__tests__/task-validator.test.js +308 -0
- package/dist/core/__tests__/task-validator.test.js.map +1 -0
- package/dist/core/archive-service.d.ts +10 -0
- package/dist/core/archive-service.d.ts.map +1 -0
- package/dist/core/archive-service.js +99 -0
- package/dist/core/archive-service.js.map +1 -0
- package/dist/core/dashboard-session.d.ts +49 -0
- package/dist/core/dashboard-session.d.ts.map +1 -0
- package/dist/core/dashboard-session.js +132 -0
- package/dist/core/dashboard-session.js.map +1 -0
- package/dist/core/git-utils.d.ts +25 -0
- package/dist/core/git-utils.d.ts.map +1 -0
- package/dist/core/git-utils.js +87 -0
- package/dist/core/git-utils.js.map +1 -0
- package/dist/core/global-dir.d.ts +44 -0
- package/dist/core/global-dir.d.ts.map +1 -0
- package/dist/core/global-dir.js +74 -0
- package/dist/core/global-dir.js.map +1 -0
- package/dist/core/implementation-log-migrator.d.ts +41 -0
- package/dist/core/implementation-log-migrator.d.ts.map +1 -0
- package/dist/core/implementation-log-migrator.js +258 -0
- package/dist/core/implementation-log-migrator.js.map +1 -0
- package/dist/core/mdx-validator.d.ts +14 -0
- package/dist/core/mdx-validator.d.ts.map +1 -0
- package/dist/core/mdx-validator.js +34 -0
- package/dist/core/mdx-validator.js.map +1 -0
- package/dist/core/parser.d.ts +11 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +128 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/path-utils.d.ts +68 -0
- package/dist/core/path-utils.d.ts.map +1 -0
- package/dist/core/path-utils.js +302 -0
- package/dist/core/path-utils.js.map +1 -0
- package/dist/core/project-registry.d.ts +94 -0
- package/dist/core/project-registry.d.ts.map +1 -0
- package/dist/core/project-registry.js +297 -0
- package/dist/core/project-registry.js.map +1 -0
- package/dist/core/security-utils.d.ts +99 -0
- package/dist/core/security-utils.d.ts.map +1 -0
- package/dist/core/security-utils.js +275 -0
- package/dist/core/security-utils.js.map +1 -0
- package/dist/core/task-parser.d.ts +90 -0
- package/dist/core/task-parser.d.ts.map +1 -0
- package/dist/core/task-parser.js +477 -0
- package/dist/core/task-parser.js.map +1 -0
- package/dist/core/task-validator.d.ts +37 -0
- package/dist/core/task-validator.d.ts.map +1 -0
- package/dist/core/task-validator.js +499 -0
- package/dist/core/task-validator.js.map +1 -0
- package/dist/core/workspace-initializer.d.ts +16 -0
- package/dist/core/workspace-initializer.d.ts.map +1 -0
- package/dist/core/workspace-initializer.js +168 -0
- package/dist/core/workspace-initializer.js.map +1 -0
- package/dist/dashboard/__tests__/approval-storage-path-resolution.test.d.ts +2 -0
- package/dist/dashboard/__tests__/approval-storage-path-resolution.test.d.ts.map +1 -0
- package/dist/dashboard/__tests__/approval-storage-path-resolution.test.js +78 -0
- package/dist/dashboard/__tests__/approval-storage-path-resolution.test.js.map +1 -0
- package/dist/dashboard/__tests__/multi-server-approvals-content.test.d.ts +2 -0
- package/dist/dashboard/__tests__/multi-server-approvals-content.test.d.ts.map +1 -0
- package/dist/dashboard/__tests__/multi-server-approvals-content.test.js +115 -0
- package/dist/dashboard/__tests__/multi-server-approvals-content.test.js.map +1 -0
- package/dist/dashboard/__tests__/watcher-error-handling.test.d.ts +2 -0
- package/dist/dashboard/__tests__/watcher-error-handling.test.d.ts.map +1 -0
- package/dist/dashboard/__tests__/watcher-error-handling.test.js +118 -0
- package/dist/dashboard/__tests__/watcher-error-handling.test.js.map +1 -0
- package/dist/dashboard/approval-storage.d.ts +139 -0
- package/dist/dashboard/approval-storage.d.ts.map +1 -0
- package/dist/dashboard/approval-storage.js +608 -0
- package/dist/dashboard/approval-storage.js.map +1 -0
- package/dist/dashboard/execution-history-manager.d.ts +52 -0
- package/dist/dashboard/execution-history-manager.d.ts.map +1 -0
- package/dist/dashboard/execution-history-manager.js +161 -0
- package/dist/dashboard/execution-history-manager.js.map +1 -0
- package/dist/dashboard/implementation-log-manager.d.ts +97 -0
- package/dist/dashboard/implementation-log-manager.d.ts.map +1 -0
- package/dist/dashboard/implementation-log-manager.js +617 -0
- package/dist/dashboard/implementation-log-manager.js.map +1 -0
- package/dist/dashboard/job-scheduler.d.ts +91 -0
- package/dist/dashboard/job-scheduler.d.ts.map +1 -0
- package/dist/dashboard/job-scheduler.js +321 -0
- package/dist/dashboard/job-scheduler.js.map +1 -0
- package/dist/dashboard/multi-server.d.ts +42 -0
- package/dist/dashboard/multi-server.d.ts.map +1 -0
- package/dist/dashboard/multi-server.js +1460 -0
- package/dist/dashboard/multi-server.js.map +1 -0
- package/dist/dashboard/parser.d.ts +18 -0
- package/dist/dashboard/parser.d.ts.map +1 -0
- package/dist/dashboard/parser.js +269 -0
- package/dist/dashboard/parser.js.map +1 -0
- package/dist/dashboard/project-manager.d.ts +82 -0
- package/dist/dashboard/project-manager.d.ts.map +1 -0
- package/dist/dashboard/project-manager.js +257 -0
- package/dist/dashboard/project-manager.js.map +1 -0
- package/dist/dashboard/public/assets/Inter-Bold-CD3Pr7BX.woff2 +0 -0
- package/dist/dashboard/public/assets/Inter-Medium-B_8v_WHh.woff2 +0 -0
- package/dist/dashboard/public/assets/Inter-Regular-DRVdRqcI.woff2 +0 -0
- package/dist/dashboard/public/assets/Inter-SemiBold-CtskMddL.woff2 +0 -0
- package/dist/dashboard/public/assets/JetBrainsMono-Bold-D4WEaHbo.woff2 +0 -0
- package/dist/dashboard/public/assets/JetBrainsMono-Medium-3S3k2nMz.woff2 +0 -0
- package/dist/dashboard/public/assets/JetBrainsMono-Regular-BQaDgvhP.woff2 +0 -0
- package/dist/dashboard/public/assets/Tableau10-B-NsZVaP.js +1 -0
- package/dist/dashboard/public/assets/apl-B4CMkyY2.js +1 -0
- package/dist/dashboard/public/assets/arc-a5wW942W.js +1 -0
- package/dist/dashboard/public/assets/array-BKyUJesY.js +1 -0
- package/dist/dashboard/public/assets/asciiarmor-Df11BRmG.js +1 -0
- package/dist/dashboard/public/assets/asn1-EdZsLKOL.js +1 -0
- package/dist/dashboard/public/assets/asterisk-B-8jnY81.js +1 -0
- package/dist/dashboard/public/assets/blockDiagram-c4efeb88-CvjTuK-w.js +118 -0
- package/dist/dashboard/public/assets/brainfuck-C4LP7Hcl.js +1 -0
- package/dist/dashboard/public/assets/c4Diagram-c83219d4-NwVQo5kf.js +10 -0
- package/dist/dashboard/public/assets/channel-Bi16YZhk.js +1 -0
- package/dist/dashboard/public/assets/classDiagram-beda092f-BmSeXDdU.js +2 -0
- package/dist/dashboard/public/assets/classDiagram-v2-2358418a-D7GvvuPr.js +2 -0
- package/dist/dashboard/public/assets/clike-B9uivgTg.js +1 -0
- package/dist/dashboard/public/assets/clojure-BMjYHr_A.js +1 -0
- package/dist/dashboard/public/assets/clone-BpKTiq7P.js +1 -0
- package/dist/dashboard/public/assets/cmake-BQqOBYOt.js +1 -0
- package/dist/dashboard/public/assets/cobol-CWcv1MsR.js +1 -0
- package/dist/dashboard/public/assets/coffeescript-S37ZYGWr.js +1 -0
- package/dist/dashboard/public/assets/commonlisp-DBKNyK5s.js +1 -0
- package/dist/dashboard/public/assets/createText-1719965b-qASbqHUP.js +7 -0
- package/dist/dashboard/public/assets/crystal-SjHAIU92.js +1 -0
- package/dist/dashboard/public/assets/css-BnMrqG3P.js +1 -0
- package/dist/dashboard/public/assets/cypher-C_CwsFkJ.js +1 -0
- package/dist/dashboard/public/assets/d-pRatUO7H.js +1 -0
- package/dist/dashboard/public/assets/diff-DbItnlRl.js +1 -0
- package/dist/dashboard/public/assets/dockerfile-BKs6k2Af.js +1 -0
- package/dist/dashboard/public/assets/dtd-DF_7sFjM.js +1 -0
- package/dist/dashboard/public/assets/dylan-DwRh75JA.js +1 -0
- package/dist/dashboard/public/assets/ebnf-CDyGwa7X.js +1 -0
- package/dist/dashboard/public/assets/ecl-Cabwm37j.js +1 -0
- package/dist/dashboard/public/assets/edges-96097737-BItTSnH7.js +4 -0
- package/dist/dashboard/public/assets/eiffel-CnydiIhH.js +1 -0
- package/dist/dashboard/public/assets/elm-vLlmbW-K.js +1 -0
- package/dist/dashboard/public/assets/erDiagram-0228fc6a-DT224olg.js +51 -0
- package/dist/dashboard/public/assets/erlang-BNw1qcRV.js +1 -0
- package/dist/dashboard/public/assets/factor-kuTfRLto.js +1 -0
- package/dist/dashboard/public/assets/fcl-Kvtd6kyn.js +1 -0
- package/dist/dashboard/public/assets/flowDb-c6c81e3f-D9_ukKtv.js +10 -0
- package/dist/dashboard/public/assets/flowDiagram-50d868cf-CylE8siG.js +4 -0
- package/dist/dashboard/public/assets/flowDiagram-v2-4f6560a1-B2O3JN7Y.js +1 -0
- package/dist/dashboard/public/assets/flowchart-elk-definition-6af322e1-BCaqFKf3.js +139 -0
- package/dist/dashboard/public/assets/forth-Ffai-XNe.js +1 -0
- package/dist/dashboard/public/assets/fortran-DYz_wnZ1.js +1 -0
- package/dist/dashboard/public/assets/ganttDiagram-a2739b55-WQUL1QW_.js +257 -0
- package/dist/dashboard/public/assets/gas-Bneqetm1.js +1 -0
- package/dist/dashboard/public/assets/gherkin-heZmZLOM.js +1 -0
- package/dist/dashboard/public/assets/gitGraphDiagram-82fe8481-CttZrdmr.js +70 -0
- package/dist/dashboard/public/assets/graph-Ch-rVueN.js +1 -0
- package/dist/dashboard/public/assets/groovy-D9Dt4D0W.js +1 -0
- package/dist/dashboard/public/assets/haskell-Cw1EW3IL.js +1 -0
- package/dist/dashboard/public/assets/haxe-H-WmDvRZ.js +1 -0
- package/dist/dashboard/public/assets/http-DBlCnlav.js +1 -0
- package/dist/dashboard/public/assets/idl-BEugSyMb.js +1 -0
- package/dist/dashboard/public/assets/index--kbPpDKv.js +1 -0
- package/dist/dashboard/public/assets/index-3scDwWm6.js +1 -0
- package/dist/dashboard/public/assets/index-5325376f-BL2zVOJU.js +1 -0
- package/dist/dashboard/public/assets/index-BZdjbO25.js +1 -0
- package/dist/dashboard/public/assets/index-BmA_batZ.js +1 -0
- package/dist/dashboard/public/assets/index-Bu0u99kF.js +2 -0
- package/dist/dashboard/public/assets/index-Ch-lr7F4.js +1 -0
- package/dist/dashboard/public/assets/index-ClgWbdoq.js +1 -0
- package/dist/dashboard/public/assets/index-CzLwOMQ_.js +3 -0
- package/dist/dashboard/public/assets/index-DAOEjGO7.js +1 -0
- package/dist/dashboard/public/assets/index-DXqf0B9c.js +1 -0
- package/dist/dashboard/public/assets/index-DegWdR16.js +1 -0
- package/dist/dashboard/public/assets/index-DiHyYGim.js +1 -0
- package/dist/dashboard/public/assets/index-DlZtG7I5.js +1 -0
- package/dist/dashboard/public/assets/index-DmhGE2M8.js +1 -0
- package/dist/dashboard/public/assets/index-QEGvld4x.js +1 -0
- package/dist/dashboard/public/assets/index-RfZPGAJu.js +1 -0
- package/dist/dashboard/public/assets/index-UybBj_7u.js +319 -0
- package/dist/dashboard/public/assets/index-bVekzPnl.js +7 -0
- package/dist/dashboard/public/assets/index-f5bysQzW.css +1 -0
- package/dist/dashboard/public/assets/infoDiagram-8eee0895-DjzkkE3o.js +7 -0
- package/dist/dashboard/public/assets/init-Gi6I4Gst.js +1 -0
- package/dist/dashboard/public/assets/javascript-iXu5QeM3.js +1 -0
- package/dist/dashboard/public/assets/journeyDiagram-c64418c1-CxPZkNdB.js +139 -0
- package/dist/dashboard/public/assets/julia-DuME0IfC.js +1 -0
- package/dist/dashboard/public/assets/katex-XbL3y5x-.js +261 -0
- package/dist/dashboard/public/assets/layout-DX7DNTRm.js +1 -0
- package/dist/dashboard/public/assets/line-DfvpmKOn.js +1 -0
- package/dist/dashboard/public/assets/linear-gQbBPHO5.js +1 -0
- package/dist/dashboard/public/assets/livescript-BwQOo05w.js +1 -0
- package/dist/dashboard/public/assets/lua-BgMRiT3U.js +1 -0
- package/dist/dashboard/public/assets/mathematica-DTrFuWx2.js +1 -0
- package/dist/dashboard/public/assets/mbox-CNhZ1qSd.js +1 -0
- package/dist/dashboard/public/assets/mindmap-definition-8da855dc-CNxmpyG6.js +415 -0
- package/dist/dashboard/public/assets/mirc-CjQqDB4T.js +1 -0
- package/dist/dashboard/public/assets/mllike-CXdrOF99.js +1 -0
- package/dist/dashboard/public/assets/modelica-Dc1JOy9r.js +1 -0
- package/dist/dashboard/public/assets/mscgen-BA5vi2Kp.js +1 -0
- package/dist/dashboard/public/assets/mumps-BT43cFF4.js +1 -0
- package/dist/dashboard/public/assets/nginx-DdIZxoE0.js +1 -0
- package/dist/dashboard/public/assets/nsis-LdVXkNf5.js +1 -0
- package/dist/dashboard/public/assets/ntriples-BfvgReVJ.js +1 -0
- package/dist/dashboard/public/assets/octave-Ck1zUtKM.js +1 -0
- package/dist/dashboard/public/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/dashboard/public/assets/oz-BzwKVEFT.js +1 -0
- package/dist/dashboard/public/assets/pascal--L3eBynH.js +1 -0
- package/dist/dashboard/public/assets/path-CbwjOpE9.js +1 -0
- package/dist/dashboard/public/assets/perl-CdXCOZ3F.js +1 -0
- package/dist/dashboard/public/assets/pieDiagram-a8764435-D-xy_NSA.js +35 -0
- package/dist/dashboard/public/assets/pig-CevX1Tat.js +1 -0
- package/dist/dashboard/public/assets/powershell-CFHJl5sT.js +1 -0
- package/dist/dashboard/public/assets/properties-C78fOPTZ.js +1 -0
- package/dist/dashboard/public/assets/protobuf-ChK-085T.js +1 -0
- package/dist/dashboard/public/assets/pug-DeIclll2.js +1 -0
- package/dist/dashboard/public/assets/puppet-DMA9R1ak.js +1 -0
- package/dist/dashboard/public/assets/python-BuPzkPfP.js +1 -0
- package/dist/dashboard/public/assets/q-pXgVlZs6.js +1 -0
- package/dist/dashboard/public/assets/quadrantDiagram-1e28029f-BoL2wzz0.js +7 -0
- package/dist/dashboard/public/assets/r-B6wPVr8A.js +1 -0
- package/dist/dashboard/public/assets/requirementDiagram-08caed73-BujFz0q1.js +52 -0
- package/dist/dashboard/public/assets/rpm-CTu-6PCP.js +1 -0
- package/dist/dashboard/public/assets/ruby-B2Rjki9n.js +1 -0
- package/dist/dashboard/public/assets/sankeyDiagram-a04cb91d-D03_NARm.js +8 -0
- package/dist/dashboard/public/assets/sas-B4kiWyti.js +1 -0
- package/dist/dashboard/public/assets/scheme-C41bIUwD.js +1 -0
- package/dist/dashboard/public/assets/sequenceDiagram-c5b8d532-B65eFcaT.js +122 -0
- package/dist/dashboard/public/assets/shell-CjFT_Tl9.js +1 -0
- package/dist/dashboard/public/assets/sieve-C3Gn_uJK.js +1 -0
- package/dist/dashboard/public/assets/simple-mode-GW_nhZxv.js +1 -0
- package/dist/dashboard/public/assets/smalltalk-CnHTOXQT.js +1 -0
- package/dist/dashboard/public/assets/solr-DehyRSwq.js +1 -0
- package/dist/dashboard/public/assets/sparql-DkYu6x3z.js +1 -0
- package/dist/dashboard/public/assets/spreadsheet-BCZA_wO0.js +1 -0
- package/dist/dashboard/public/assets/sql-D0XecflT.js +1 -0
- package/dist/dashboard/public/assets/stateDiagram-1ecb1508-BDbqu0Vl.js +1 -0
- package/dist/dashboard/public/assets/stateDiagram-v2-c2b004d7-CBHvk4b8.js +1 -0
- package/dist/dashboard/public/assets/stex-C3f8Ysf7.js +1 -0
- package/dist/dashboard/public/assets/styles-b4e223ce-CELsPqaO.js +160 -0
- package/dist/dashboard/public/assets/styles-ca3715f6-BRqMqT6F.js +207 -0
- package/dist/dashboard/public/assets/styles-d45a18b0-e8N-oLPy.js +116 -0
- package/dist/dashboard/public/assets/stylus-B533Al4x.js +1 -0
- package/dist/dashboard/public/assets/svgDrawCommon-b86b1483-vNDtmQc-.js +1 -0
- package/dist/dashboard/public/assets/swift-BzpIVaGY.js +1 -0
- package/dist/dashboard/public/assets/tcl-DVfN8rqt.js +1 -0
- package/dist/dashboard/public/assets/textile-CnDTJFAw.js +1 -0
- package/dist/dashboard/public/assets/tiddlywiki-DO-Gjzrf.js +1 -0
- package/dist/dashboard/public/assets/tiki-DGYXhP31.js +1 -0
- package/dist/dashboard/public/assets/timeline-definition-faaaa080-Dh2_A5VU.js +61 -0
- package/dist/dashboard/public/assets/toml-Bm5Em-hy.js +1 -0
- package/dist/dashboard/public/assets/troff-wAsdV37c.js +1 -0
- package/dist/dashboard/public/assets/ttcn-CfJYG6tj.js +1 -0
- package/dist/dashboard/public/assets/ttcn-cfg-B9xdYoR4.js +1 -0
- package/dist/dashboard/public/assets/turtle-B1tBg_DP.js +1 -0
- package/dist/dashboard/public/assets/vb-CmGdzxic.js +1 -0
- package/dist/dashboard/public/assets/vbscript-BuJXcnF6.js +1 -0
- package/dist/dashboard/public/assets/velocity-D8B20fx6.js +1 -0
- package/dist/dashboard/public/assets/verilog-C6RDOZhf.js +1 -0
- package/dist/dashboard/public/assets/vhdl-lSbBsy5d.js +1 -0
- package/dist/dashboard/public/assets/webidl-ZXfAyPTL.js +1 -0
- package/dist/dashboard/public/assets/xquery-DzFWVndE.js +1 -0
- package/dist/dashboard/public/assets/xychartDiagram-f5964ef8-B76v1AVF.js +7 -0
- package/dist/dashboard/public/assets/yacas-BJ4BC0dw.js +1 -0
- package/dist/dashboard/public/assets/z80-Hz9HOZM7.js +1 -0
- package/dist/dashboard/public/claude-icon-dark.svg +1 -0
- package/dist/dashboard/public/claude-icon.svg +1 -0
- package/dist/dashboard/public/index.html +16 -0
- package/dist/dashboard/settings-manager.d.ts +47 -0
- package/dist/dashboard/settings-manager.d.ts.map +1 -0
- package/dist/dashboard/settings-manager.js +180 -0
- package/dist/dashboard/settings-manager.js.map +1 -0
- package/dist/dashboard/utils.d.ts +31 -0
- package/dist/dashboard/utils.d.ts.map +1 -0
- package/dist/dashboard/utils.js +102 -0
- package/dist/dashboard/utils.js.map +1 -0
- package/dist/dashboard/watcher.d.ts +32 -0
- package/dist/dashboard/watcher.d.ts.map +1 -0
- package/dist/dashboard/watcher.js +173 -0
- package/dist/dashboard/watcher.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +380 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown/templates/design-template.md +126 -0
- package/dist/markdown/templates/product-template.md +51 -0
- package/dist/markdown/templates/requirements-template.md +50 -0
- package/dist/markdown/templates/structure-template.md +145 -0
- package/dist/markdown/templates/tasks-template.md +100 -0
- package/dist/markdown/templates/tech-template.md +99 -0
- package/dist/markdown/templates/test-design-template.md +221 -0
- package/dist/prompts/create-spec.d.ts +3 -0
- package/dist/prompts/create-spec.d.ts.map +1 -0
- package/dist/prompts/create-spec.js +97 -0
- package/dist/prompts/create-spec.js.map +1 -0
- package/dist/prompts/create-steering-doc.d.ts +3 -0
- package/dist/prompts/create-steering-doc.d.ts.map +1 -0
- package/dist/prompts/create-steering-doc.js +75 -0
- package/dist/prompts/create-steering-doc.js.map +1 -0
- package/dist/prompts/implement-task.d.ts +3 -0
- package/dist/prompts/implement-task.d.ts.map +1 -0
- package/dist/prompts/implement-task.js +174 -0
- package/dist/prompts/implement-task.js.map +1 -0
- package/dist/prompts/index.d.ts +20 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +103 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/inject-spec-workflow-guide.d.ts +3 -0
- package/dist/prompts/inject-spec-workflow-guide.d.ts.map +1 -0
- package/dist/prompts/inject-spec-workflow-guide.js +60 -0
- package/dist/prompts/inject-spec-workflow-guide.js.map +1 -0
- package/dist/prompts/inject-steering-guide.d.ts +3 -0
- package/dist/prompts/inject-steering-guide.d.ts.map +1 -0
- package/dist/prompts/inject-steering-guide.js +64 -0
- package/dist/prompts/inject-steering-guide.js.map +1 -0
- package/dist/prompts/refresh-tasks.d.ts +3 -0
- package/dist/prompts/refresh-tasks.d.ts.map +1 -0
- package/dist/prompts/refresh-tasks.js +237 -0
- package/dist/prompts/refresh-tasks.js.map +1 -0
- package/dist/prompts/spec-status.d.ts +3 -0
- package/dist/prompts/spec-status.d.ts.map +1 -0
- package/dist/prompts/spec-status.js +77 -0
- package/dist/prompts/spec-status.js.map +1 -0
- package/dist/prompts/types.d.ts +13 -0
- package/dist/prompts/types.d.ts.map +1 -0
- package/dist/prompts/types.js +2 -0
- package/dist/prompts/types.js.map +1 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +175 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/__tests__/log-implementation-review-process.test.d.ts +2 -0
- package/dist/tools/__tests__/log-implementation-review-process.test.d.ts.map +1 -0
- package/dist/tools/__tests__/log-implementation-review-process.test.js +190 -0
- package/dist/tools/__tests__/log-implementation-review-process.test.js.map +1 -0
- package/dist/tools/__tests__/projectPath.test.d.ts +2 -0
- package/dist/tools/__tests__/projectPath.test.d.ts.map +1 -0
- package/dist/tools/__tests__/projectPath.test.js +187 -0
- package/dist/tools/__tests__/projectPath.test.js.map +1 -0
- package/dist/tools/approvals.d.ts +14 -0
- package/dist/tools/approvals.d.ts.map +1 -0
- package/dist/tools/approvals.js +505 -0
- package/dist/tools/approvals.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +52 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/log-implementation.d.ts +5 -0
- package/dist/tools/log-implementation.d.ts.map +1 -0
- package/dist/tools/log-implementation.js +498 -0
- package/dist/tools/log-implementation.js.map +1 -0
- package/dist/tools/spec-status.d.ts +5 -0
- package/dist/tools/spec-status.d.ts.map +1 -0
- package/dist/tools/spec-status.js +192 -0
- package/dist/tools/spec-status.js.map +1 -0
- package/dist/tools/spec-workflow-guide.d.ts +5 -0
- package/dist/tools/spec-workflow-guide.d.ts.map +1 -0
- package/dist/tools/spec-workflow-guide.js +116 -0
- package/dist/tools/spec-workflow-guide.js.map +1 -0
- package/dist/tools/steering-guide.d.ts +5 -0
- package/dist/tools/steering-guide.d.ts.map +1 -0
- package/dist/tools/steering-guide.js +192 -0
- package/dist/tools/steering-guide.js.map +1 -0
- package/dist/types.d.ts +183 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/package.json +106 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import { join, dirname } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { PathUtils } from './path-utils.js';
|
|
5
|
+
import { ImplementationLogMigrator } from './implementation-log-migrator.js';
|
|
6
|
+
import { getGlobalDir } from './global-dir.js';
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
export class WorkspaceInitializer {
|
|
9
|
+
projectPath;
|
|
10
|
+
version;
|
|
11
|
+
constructor(projectPath, version) {
|
|
12
|
+
this.projectPath = projectPath;
|
|
13
|
+
this.version = version;
|
|
14
|
+
}
|
|
15
|
+
async initializeWorkspace() {
|
|
16
|
+
// Create all necessary directories
|
|
17
|
+
await this.initializeDirectories();
|
|
18
|
+
// Copy template files
|
|
19
|
+
await this.initializeTemplates();
|
|
20
|
+
// Create user templates README
|
|
21
|
+
await this.createUserTemplatesReadme();
|
|
22
|
+
// Migrate implementation logs from JSON to Markdown format
|
|
23
|
+
await this.migrateImplementationLogs();
|
|
24
|
+
}
|
|
25
|
+
async initializeDirectories() {
|
|
26
|
+
const workflowRoot = PathUtils.getWorkflowRoot(this.projectPath);
|
|
27
|
+
const directories = [
|
|
28
|
+
'approvals',
|
|
29
|
+
'archive',
|
|
30
|
+
'specs',
|
|
31
|
+
'steering',
|
|
32
|
+
'templates',
|
|
33
|
+
'user-templates',
|
|
34
|
+
'user-prompts'
|
|
35
|
+
];
|
|
36
|
+
for (const dir of directories) {
|
|
37
|
+
const dirPath = join(workflowRoot, dir);
|
|
38
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async initializeTemplates() {
|
|
42
|
+
const templatesDir = join(PathUtils.getWorkflowRoot(this.projectPath), 'templates');
|
|
43
|
+
const templates = [
|
|
44
|
+
'requirements-template',
|
|
45
|
+
'design-template',
|
|
46
|
+
'test-design-template',
|
|
47
|
+
'tasks-template',
|
|
48
|
+
'product-template',
|
|
49
|
+
'tech-template',
|
|
50
|
+
'structure-template'
|
|
51
|
+
];
|
|
52
|
+
for (const template of templates) {
|
|
53
|
+
await this.copyTemplate(template, templatesDir);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async copyTemplate(templateName, targetDir) {
|
|
57
|
+
// Use simple filename without version
|
|
58
|
+
const targetFileName = `${templateName}.md`;
|
|
59
|
+
const targetPath = join(targetDir, targetFileName);
|
|
60
|
+
const sourcePath = join(__dirname, '..', 'markdown', 'templates', `${templateName}.md`);
|
|
61
|
+
try {
|
|
62
|
+
const content = await fs.readFile(sourcePath, 'utf-8');
|
|
63
|
+
// Always overwrite to ensure latest template version is used
|
|
64
|
+
await fs.writeFile(targetPath, content, 'utf-8');
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
68
|
+
console.error(`Failed to copy template ${templateName}: ${errorMessage}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async createUserTemplatesReadme() {
|
|
72
|
+
const readmePath = join(PathUtils.getWorkflowRoot(this.projectPath), 'user-templates', 'README.md');
|
|
73
|
+
const readmeContent = `# User Templates
|
|
74
|
+
|
|
75
|
+
This directory allows you to create custom templates that override the default Spec Workflow templates.
|
|
76
|
+
|
|
77
|
+
## How to Use Custom Templates
|
|
78
|
+
|
|
79
|
+
1. **Create your custom template file** in this directory with the exact same name as the default template you want to override:
|
|
80
|
+
- \`requirements-template.md\` - Override requirements document template
|
|
81
|
+
- \`design-template.md\` - Override design document template
|
|
82
|
+
- \`test-design-template.md\` - Override test design document template
|
|
83
|
+
- \`tasks-template.md\` - Override tasks document template
|
|
84
|
+
- \`product-template.md\` - Override product steering template
|
|
85
|
+
- \`tech-template.md\` - Override tech steering template
|
|
86
|
+
- \`structure-template.md\` - Override structure steering template
|
|
87
|
+
|
|
88
|
+
2. **Template Loading Priority**:
|
|
89
|
+
- The system first checks this \`user-templates/\` directory
|
|
90
|
+
- If a matching template is found here, it will be used
|
|
91
|
+
- Otherwise, the default template from \`templates/\` will be used
|
|
92
|
+
|
|
93
|
+
## Example Custom Template
|
|
94
|
+
|
|
95
|
+
To create a custom requirements template:
|
|
96
|
+
|
|
97
|
+
1. Create a file named \`requirements-template.md\` in this directory
|
|
98
|
+
2. Add your custom structure, for example:
|
|
99
|
+
|
|
100
|
+
\`\`\`markdown
|
|
101
|
+
# Requirements Document
|
|
102
|
+
|
|
103
|
+
## Executive Summary
|
|
104
|
+
[Your custom section]
|
|
105
|
+
|
|
106
|
+
## Business Requirements
|
|
107
|
+
[Your custom structure]
|
|
108
|
+
|
|
109
|
+
## Technical Requirements
|
|
110
|
+
[Your custom fields]
|
|
111
|
+
|
|
112
|
+
## Custom Sections
|
|
113
|
+
[Add any sections specific to your workflow]
|
|
114
|
+
\`\`\`
|
|
115
|
+
|
|
116
|
+
## Template Variables
|
|
117
|
+
|
|
118
|
+
Templates can include placeholders that will be replaced when documents are created:
|
|
119
|
+
- \`{{projectName}}\` - The name of your project
|
|
120
|
+
- \`{{featureName}}\` - The name of the feature being specified
|
|
121
|
+
- \`{{date}}\` - The current date
|
|
122
|
+
- \`{{author}}\` - The document author
|
|
123
|
+
|
|
124
|
+
## Best Practices
|
|
125
|
+
|
|
126
|
+
1. **Start from defaults**: Copy a default template from \`../templates/\` as a starting point
|
|
127
|
+
2. **Keep structure consistent**: Maintain similar section headers for tool compatibility
|
|
128
|
+
3. **Document changes**: Add comments explaining why sections were added/modified
|
|
129
|
+
4. **Version control**: Track your custom templates in version control
|
|
130
|
+
5. **Test thoroughly**: Ensure custom templates work with the spec workflow tools
|
|
131
|
+
|
|
132
|
+
## Notes
|
|
133
|
+
|
|
134
|
+
- Custom templates are project-specific and not included in the package distribution
|
|
135
|
+
- The \`templates/\` directory contains the default templates which are updated with each version
|
|
136
|
+
- Your custom templates in this directory are preserved during updates
|
|
137
|
+
- If a custom template has errors, the system will fall back to the default template
|
|
138
|
+
`;
|
|
139
|
+
try {
|
|
140
|
+
// Only create if it doesn't exist to avoid overwriting user's README
|
|
141
|
+
await fs.access(readmePath);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// File doesn't exist, create it
|
|
145
|
+
await fs.writeFile(readmePath, readmeContent, 'utf-8');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Migrate implementation logs from JSON to Markdown format
|
|
150
|
+
* Runs on server startup to handle automatic migration for existing specs
|
|
151
|
+
*/
|
|
152
|
+
async migrateImplementationLogs() {
|
|
153
|
+
try {
|
|
154
|
+
const userDataDir = getGlobalDir();
|
|
155
|
+
const specsDir = join(PathUtils.getWorkflowRoot(this.projectPath), 'specs');
|
|
156
|
+
// Create user data directory if it doesn't exist
|
|
157
|
+
await fs.mkdir(userDataDir, { recursive: true });
|
|
158
|
+
const migrator = new ImplementationLogMigrator(userDataDir);
|
|
159
|
+
await migrator.migrateAllSpecs(specsDir);
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
163
|
+
console.error(`Implementation log migration failed: ${errorMessage}`);
|
|
164
|
+
// Don't throw - migration failure shouldn't break server startup
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=workspace-initializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-initializer.js","sourceRoot":"","sources":["../../src/core/workspace-initializer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-storage-path-resolution.test.d.ts","sourceRoot":"","sources":["../../../src/dashboard/__tests__/approval-storage-path-resolution.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { tmpdir } from 'os';
|
|
5
|
+
import { ApprovalStorage } from '../approval-storage.js';
|
|
6
|
+
describe('ApprovalStorage path resolution', () => {
|
|
7
|
+
let tempDir;
|
|
8
|
+
let workflowRootPath;
|
|
9
|
+
let workspacePath;
|
|
10
|
+
let storage;
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
tempDir = join(tmpdir(), `spec-workflow-approvals-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`);
|
|
13
|
+
workflowRootPath = join(tempDir, 'repo-main');
|
|
14
|
+
workspacePath = join(tempDir, 'repo-feature-worktree');
|
|
15
|
+
await fs.mkdir(workflowRootPath, { recursive: true });
|
|
16
|
+
await fs.mkdir(workspacePath, { recursive: true });
|
|
17
|
+
storage = new ApprovalStorage(workflowRootPath, {
|
|
18
|
+
originalPath: workflowRootPath,
|
|
19
|
+
fileResolutionPath: workspacePath
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
afterEach(async () => {
|
|
23
|
+
await storage.stop();
|
|
24
|
+
try {
|
|
25
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Ignore cleanup errors
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
it('prefers workspace file for snapshots when both workspace and workflow files exist', async () => {
|
|
32
|
+
const relativePath = 'src/feature.ts';
|
|
33
|
+
const workspaceFile = join(workspacePath, relativePath);
|
|
34
|
+
const workflowFile = join(workflowRootPath, relativePath);
|
|
35
|
+
await fs.mkdir(join(workspacePath, 'src'), { recursive: true });
|
|
36
|
+
await fs.mkdir(join(workflowRootPath, 'src'), { recursive: true });
|
|
37
|
+
await fs.writeFile(workspaceFile, 'workspace-version', 'utf-8');
|
|
38
|
+
await fs.writeFile(workflowFile, 'workflow-version', 'utf-8');
|
|
39
|
+
const approvalId = await storage.createApproval('Review feature', relativePath, 'spec', 'test-spec');
|
|
40
|
+
const snapshots = await storage.getSnapshots(approvalId);
|
|
41
|
+
expect(snapshots).toHaveLength(1);
|
|
42
|
+
expect(snapshots[0].content).toBe('workspace-version');
|
|
43
|
+
});
|
|
44
|
+
it('falls back to workflow root when file only exists there', async () => {
|
|
45
|
+
const relativePath = '.spec-workflow/specs/test-spec/requirements.md';
|
|
46
|
+
const workflowFile = join(workflowRootPath, relativePath);
|
|
47
|
+
await fs.mkdir(join(workflowRootPath, '.spec-workflow', 'specs', 'test-spec'), { recursive: true });
|
|
48
|
+
await fs.writeFile(workflowFile, '# Requirements from shared root', 'utf-8');
|
|
49
|
+
const approvalId = await storage.createApproval('Review requirements', relativePath, 'spec', 'test-spec');
|
|
50
|
+
const content = await storage.getCurrentFileContent(approvalId);
|
|
51
|
+
expect(content).toBe('# Requirements from shared root');
|
|
52
|
+
});
|
|
53
|
+
it('rejects absolute file paths in createApproval', async () => {
|
|
54
|
+
await expect(storage.createApproval('Review', '/etc/passwd', 'spec', 'test-spec')).rejects.toThrow('absolute paths are not allowed');
|
|
55
|
+
});
|
|
56
|
+
it('rejects path traversal in createApproval', async () => {
|
|
57
|
+
await expect(storage.createApproval('Review', '../../../etc/passwd', 'spec', 'test-spec')).rejects.toThrow('path traversal (..) is not allowed');
|
|
58
|
+
});
|
|
59
|
+
it('rejects embedded path traversal in createApproval', async () => {
|
|
60
|
+
await expect(storage.createApproval('Review', 'src/../../etc/passwd', 'spec', 'test-spec')).rejects.toThrow('path traversal (..) is not allowed');
|
|
61
|
+
});
|
|
62
|
+
it('writes revisions to workspace file when it exists there', async () => {
|
|
63
|
+
const relativePath = 'src/revision-target.ts';
|
|
64
|
+
const workspaceFile = join(workspacePath, relativePath);
|
|
65
|
+
const workflowFile = join(workflowRootPath, relativePath);
|
|
66
|
+
await fs.mkdir(join(workspacePath, 'src'), { recursive: true });
|
|
67
|
+
await fs.mkdir(join(workflowRootPath, 'src'), { recursive: true });
|
|
68
|
+
await fs.writeFile(workspaceFile, 'workspace-original', 'utf-8');
|
|
69
|
+
await fs.writeFile(workflowFile, 'workflow-original', 'utf-8');
|
|
70
|
+
const approvalId = await storage.createApproval('Review revision target', relativePath, 'spec', 'test-spec');
|
|
71
|
+
await storage.createRevision(approvalId, 'workspace-updated', 'needs update');
|
|
72
|
+
const workspaceContent = await fs.readFile(workspaceFile, 'utf-8');
|
|
73
|
+
const workflowContent = await fs.readFile(workflowFile, 'utf-8');
|
|
74
|
+
expect(workspaceContent).toBe('workspace-updated');
|
|
75
|
+
expect(workflowContent).toBe('workflow-original');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=approval-storage-path-resolution.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-storage-path-resolution.test.js","sourceRoot":"","sources":["../../../src/dashboard/__tests__/approval-storage-path-resolution.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-server-approvals-content.test.d.ts","sourceRoot":"","sources":["../../../src/dashboard/__tests__/multi-server-approvals-content.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
import net from 'net';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { tmpdir } from 'os';
|
|
6
|
+
import { MultiProjectDashboardServer } from '../multi-server.js';
|
|
7
|
+
import { ApprovalStorage } from '../approval-storage.js';
|
|
8
|
+
import { ProjectRegistry, generateProjectId } from '../../core/project-registry.js';
|
|
9
|
+
import { SPEC_WORKFLOW_HOME_ENV } from '../../core/global-dir.js';
|
|
10
|
+
async function getFreePort() {
|
|
11
|
+
return await new Promise((resolvePort, reject) => {
|
|
12
|
+
const server = net.createServer();
|
|
13
|
+
server.listen(0, '127.0.0.1', () => {
|
|
14
|
+
const address = server.address();
|
|
15
|
+
if (!address || typeof address === 'string') {
|
|
16
|
+
server.close();
|
|
17
|
+
reject(new Error('Failed to get free port'));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const port = address.port;
|
|
21
|
+
server.close(() => resolvePort(port));
|
|
22
|
+
});
|
|
23
|
+
server.on('error', reject);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
describe('MultiProjectDashboardServer approvals content resolution', () => {
|
|
27
|
+
let tempDir;
|
|
28
|
+
let workspacePath;
|
|
29
|
+
let workflowRootPath;
|
|
30
|
+
let server = null;
|
|
31
|
+
let projectId;
|
|
32
|
+
let realFetch;
|
|
33
|
+
const originalEnv = { ...process.env };
|
|
34
|
+
beforeEach(async () => {
|
|
35
|
+
tempDir = join(tmpdir(), `specwf-multi-server-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
|
|
36
|
+
workspacePath = join(tempDir, 'worktrees', 'wt-a');
|
|
37
|
+
workflowRootPath = join(tempDir, 'repo-main');
|
|
38
|
+
await fs.mkdir(workspacePath, { recursive: true });
|
|
39
|
+
await fs.mkdir(workflowRootPath, { recursive: true });
|
|
40
|
+
process.env[SPEC_WORKFLOW_HOME_ENV] = join(tempDir, '.global-state');
|
|
41
|
+
projectId = generateProjectId(workspacePath);
|
|
42
|
+
realFetch = globalThis.fetch;
|
|
43
|
+
const registry = new ProjectRegistry();
|
|
44
|
+
await registry.registerProject(workspacePath, process.pid, { workflowRootPath });
|
|
45
|
+
// Prevent network dependency in package version lookup.
|
|
46
|
+
vi.stubGlobal('fetch', vi.fn(async () => ({
|
|
47
|
+
ok: false,
|
|
48
|
+
json: async () => ({})
|
|
49
|
+
})));
|
|
50
|
+
});
|
|
51
|
+
afterEach(async () => {
|
|
52
|
+
if (server) {
|
|
53
|
+
await server.stop();
|
|
54
|
+
server = null;
|
|
55
|
+
}
|
|
56
|
+
vi.unstubAllGlobals();
|
|
57
|
+
process.env = { ...originalEnv };
|
|
58
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
59
|
+
});
|
|
60
|
+
it('prioritizes workspace path before workflow root for relative approval filePath', async () => {
|
|
61
|
+
const relativePath = 'src/service.ts';
|
|
62
|
+
await fs.mkdir(join(workspacePath, 'src'), { recursive: true });
|
|
63
|
+
await fs.mkdir(join(workflowRootPath, 'src'), { recursive: true });
|
|
64
|
+
await fs.writeFile(join(workspacePath, relativePath), 'workspace-content', 'utf-8');
|
|
65
|
+
await fs.writeFile(join(workflowRootPath, relativePath), 'workflow-content', 'utf-8');
|
|
66
|
+
const approvalStorage = new ApprovalStorage(workflowRootPath, {
|
|
67
|
+
originalPath: workflowRootPath,
|
|
68
|
+
fileResolutionPath: workspacePath
|
|
69
|
+
});
|
|
70
|
+
const approvalId = await approvalStorage.createApproval('Review service', relativePath, 'spec', 'test-spec');
|
|
71
|
+
const port = await getFreePort();
|
|
72
|
+
server = new MultiProjectDashboardServer({ autoOpen: false, port });
|
|
73
|
+
await server.start();
|
|
74
|
+
const response = await realFetch(`http://127.0.0.1:${port}/api/projects/${projectId}/approvals/${approvalId}/content`);
|
|
75
|
+
const body = await response.json();
|
|
76
|
+
expect(response.status).toBe(200);
|
|
77
|
+
expect(body.content).toBe('workspace-content');
|
|
78
|
+
expect(body.filePath).toContain(join('worktrees', 'wt-a', 'src', 'service.ts'));
|
|
79
|
+
});
|
|
80
|
+
it('falls back to workflow root when relative file only exists there', async () => {
|
|
81
|
+
const relativePath = '.spec-workflow/specs/test-spec/requirements.md';
|
|
82
|
+
await fs.mkdir(join(workflowRootPath, '.spec-workflow', 'specs', 'test-spec'), { recursive: true });
|
|
83
|
+
await fs.writeFile(join(workflowRootPath, relativePath), '# Shared requirements', 'utf-8');
|
|
84
|
+
const approvalStorage = new ApprovalStorage(workflowRootPath, {
|
|
85
|
+
originalPath: workflowRootPath,
|
|
86
|
+
fileResolutionPath: workspacePath
|
|
87
|
+
});
|
|
88
|
+
const approvalId = await approvalStorage.createApproval('Review requirements', relativePath, 'spec', 'test-spec');
|
|
89
|
+
const port = await getFreePort();
|
|
90
|
+
server = new MultiProjectDashboardServer({ autoOpen: false, port });
|
|
91
|
+
await server.start();
|
|
92
|
+
const response = await realFetch(`http://127.0.0.1:${port}/api/projects/${projectId}/approvals/${approvalId}/content`);
|
|
93
|
+
const body = await response.json();
|
|
94
|
+
expect(response.status).toBe(200);
|
|
95
|
+
expect(body.content).toBe('# Shared requirements');
|
|
96
|
+
expect(body.filePath).toContain(join('repo-main', '.spec-workflow', 'specs', 'test-spec', 'requirements.md'));
|
|
97
|
+
});
|
|
98
|
+
it('rejects absolute approval filePath', async () => {
|
|
99
|
+
const absolutePath = join(tempDir, 'absolute-target.md');
|
|
100
|
+
await fs.writeFile(absolutePath, 'absolute-file-content', 'utf-8');
|
|
101
|
+
const approvalStorage = new ApprovalStorage(workflowRootPath, {
|
|
102
|
+
originalPath: workflowRootPath,
|
|
103
|
+
fileResolutionPath: workspacePath
|
|
104
|
+
});
|
|
105
|
+
await expect(approvalStorage.createApproval('Review absolute path', absolutePath, 'spec', 'test-spec')).rejects.toThrow('absolute paths are not allowed');
|
|
106
|
+
});
|
|
107
|
+
it('rejects path traversal in approval filePath', async () => {
|
|
108
|
+
const approvalStorage = new ApprovalStorage(workflowRootPath, {
|
|
109
|
+
originalPath: workflowRootPath,
|
|
110
|
+
fileResolutionPath: workspacePath
|
|
111
|
+
});
|
|
112
|
+
await expect(approvalStorage.createApproval('Review traversal', '../../../etc/passwd', 'spec', 'test-spec')).rejects.toThrow('path traversal (..) is not allowed');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
//# sourceMappingURL=multi-server-approvals-content.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-server-approvals-content.test.js","sourceRoot":"","sources":["../../../src/dashboard/__tests__/multi-server-approvals-content.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher-error-handling.test.d.ts","sourceRoot":"","sources":["../../../src/dashboard/__tests__/watcher-error-handling.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { SpecWatcher } from '../watcher.js';
|
|
3
|
+
import { SpecParser } from '../parser.js';
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { tmpdir } from 'os';
|
|
7
|
+
describe('SpecWatcher Error Handling', () => {
|
|
8
|
+
let testDir;
|
|
9
|
+
let watcher;
|
|
10
|
+
let parser;
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
// Create a temporary test directory
|
|
13
|
+
testDir = join(tmpdir(), `spec-workflow-test-${Date.now()}`);
|
|
14
|
+
await fs.mkdir(testDir, { recursive: true });
|
|
15
|
+
// Create the workflow directory structure
|
|
16
|
+
const workflowDir = join(testDir, '.spec-workflow');
|
|
17
|
+
const specsDir = join(workflowDir, 'specs');
|
|
18
|
+
const steeringDir = join(workflowDir, 'steering');
|
|
19
|
+
await fs.mkdir(workflowDir, { recursive: true });
|
|
20
|
+
await fs.mkdir(specsDir, { recursive: true });
|
|
21
|
+
await fs.mkdir(steeringDir, { recursive: true });
|
|
22
|
+
// Create a test spec
|
|
23
|
+
const testSpecDir = join(specsDir, 'test-spec');
|
|
24
|
+
await fs.mkdir(testSpecDir, { recursive: true });
|
|
25
|
+
await fs.writeFile(join(testSpecDir, 'requirements.md'), '# Test Requirements\n\nSome content');
|
|
26
|
+
// Initialize parser and watcher
|
|
27
|
+
parser = new SpecParser(testDir);
|
|
28
|
+
watcher = new SpecWatcher(testDir, parser);
|
|
29
|
+
});
|
|
30
|
+
afterEach(async () => {
|
|
31
|
+
// Stop watcher
|
|
32
|
+
if (watcher) {
|
|
33
|
+
await watcher.stop();
|
|
34
|
+
}
|
|
35
|
+
// Clean up test directory
|
|
36
|
+
try {
|
|
37
|
+
await fs.rm(testDir, { recursive: true, force: true });
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Ignore cleanup errors
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
it('should start without crashing', async () => {
|
|
44
|
+
await expect(watcher.start()).resolves.not.toThrow();
|
|
45
|
+
});
|
|
46
|
+
it('should handle file changes without crashing', async () => {
|
|
47
|
+
await watcher.start();
|
|
48
|
+
// Set up event listener to track changes
|
|
49
|
+
const changeEvents = [];
|
|
50
|
+
watcher.on('change', (event) => {
|
|
51
|
+
changeEvents.push(event);
|
|
52
|
+
});
|
|
53
|
+
// Modify a file
|
|
54
|
+
const requirementsPath = join(testDir, '.spec-workflow', 'specs', 'test-spec', 'requirements.md');
|
|
55
|
+
await fs.writeFile(requirementsPath, '# Updated Requirements\n\nUpdated content');
|
|
56
|
+
// Wait for file system events to propagate
|
|
57
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
58
|
+
// Watcher should still be running (not crashed)
|
|
59
|
+
expect(watcher).toBeDefined();
|
|
60
|
+
});
|
|
61
|
+
it('should handle parser errors gracefully', async () => {
|
|
62
|
+
await watcher.start();
|
|
63
|
+
// Mock parser to throw an error
|
|
64
|
+
const originalGetSpec = parser.getSpec.bind(parser);
|
|
65
|
+
parser.getSpec = vi.fn().mockRejectedValue(new Error('Parser error'));
|
|
66
|
+
// Set up event listener
|
|
67
|
+
const changeEvents = [];
|
|
68
|
+
watcher.on('change', (event) => {
|
|
69
|
+
changeEvents.push(event);
|
|
70
|
+
});
|
|
71
|
+
// Modify a file (this will trigger the error)
|
|
72
|
+
const requirementsPath = join(testDir, '.spec-workflow', 'specs', 'test-spec', 'requirements.md');
|
|
73
|
+
await fs.writeFile(requirementsPath, '# Updated Requirements\n\nUpdated content');
|
|
74
|
+
// Wait for file system events to propagate
|
|
75
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
76
|
+
// Watcher should still be running despite the error
|
|
77
|
+
expect(watcher).toBeDefined();
|
|
78
|
+
// Restore original method
|
|
79
|
+
parser.getSpec = originalGetSpec;
|
|
80
|
+
});
|
|
81
|
+
it('should handle steering file changes', async () => {
|
|
82
|
+
await watcher.start();
|
|
83
|
+
// Set up event listener
|
|
84
|
+
const steeringEvents = [];
|
|
85
|
+
watcher.on('steering-change', (event) => {
|
|
86
|
+
steeringEvents.push(event);
|
|
87
|
+
});
|
|
88
|
+
// Create a steering file
|
|
89
|
+
const steeringPath = join(testDir, '.spec-workflow', 'steering', 'product.md');
|
|
90
|
+
await fs.writeFile(steeringPath, '# Product Steering\n\nSome guidance');
|
|
91
|
+
// Wait for file system events to propagate
|
|
92
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
93
|
+
// Should have received at least one event
|
|
94
|
+
expect(steeringEvents.length).toBeGreaterThanOrEqual(0); // May be 0 or 1 depending on timing
|
|
95
|
+
});
|
|
96
|
+
it('should stop cleanly', async () => {
|
|
97
|
+
await watcher.start();
|
|
98
|
+
await expect(watcher.stop()).resolves.not.toThrow();
|
|
99
|
+
});
|
|
100
|
+
it('should not crash when stopping without starting', async () => {
|
|
101
|
+
const newWatcher = new SpecWatcher(testDir, parser);
|
|
102
|
+
await expect(newWatcher.stop()).resolves.not.toThrow();
|
|
103
|
+
});
|
|
104
|
+
it('should handle rapid file changes without crashing', async () => {
|
|
105
|
+
await watcher.start();
|
|
106
|
+
const requirementsPath = join(testDir, '.spec-workflow', 'specs', 'test-spec', 'requirements.md');
|
|
107
|
+
// Make multiple rapid changes
|
|
108
|
+
for (let i = 0; i < 5; i++) {
|
|
109
|
+
await fs.writeFile(requirementsPath, `# Updated Requirements ${i}\n\nUpdated content ${i}`);
|
|
110
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
111
|
+
}
|
|
112
|
+
// Wait for all events to propagate
|
|
113
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
114
|
+
// Watcher should still be running
|
|
115
|
+
expect(watcher).toBeDefined();
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=watcher-error-handling.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher-error-handling.test.js","sourceRoot":"","sources":["../../../src/dashboard/__tests__/watcher-error-handling.test.ts"],"names":[],"mappings":"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"}
|