@specship/specship-win32-arm64 0.24.0 → 0.28.0
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/bin/specship.cmd +31 -1
- package/lib/dist/activation/cheatsheet.d.ts +17 -1
- package/lib/dist/activation/cheatsheet.d.ts.map +1 -1
- package/lib/dist/activation/cheatsheet.js +47 -3
- package/lib/dist/activation/cheatsheet.js.map +1 -1
- package/lib/dist/activation/hook-output.d.ts +80 -0
- package/lib/dist/activation/hook-output.d.ts.map +1 -0
- package/lib/dist/activation/hook-output.js +103 -0
- package/lib/dist/activation/hook-output.js.map +1 -0
- package/lib/dist/activation/search-intercept.d.ts +60 -29
- package/lib/dist/activation/search-intercept.d.ts.map +1 -1
- package/lib/dist/activation/search-intercept.js +159 -55
- package/lib/dist/activation/search-intercept.js.map +1 -1
- package/lib/dist/activation/steering.d.ts +11 -13
- package/lib/dist/activation/steering.d.ts.map +1 -1
- package/lib/dist/activation/steering.js +25 -10
- package/lib/dist/activation/steering.js.map +1 -1
- package/lib/dist/behaviour/behaviour-surface.d.ts +47 -0
- package/lib/dist/behaviour/behaviour-surface.d.ts.map +1 -1
- package/lib/dist/behaviour/behaviour-surface.js +108 -2
- package/lib/dist/behaviour/behaviour-surface.js.map +1 -1
- package/lib/dist/bin/node-version-check.d.ts +22 -7
- package/lib/dist/bin/node-version-check.d.ts.map +1 -1
- package/lib/dist/bin/node-version-check.js +39 -9
- package/lib/dist/bin/node-version-check.js.map +1 -1
- package/lib/dist/bin/specship.js +989 -116
- package/lib/dist/bin/specship.js.map +1 -1
- package/lib/dist/commands/specship/learn.md +27 -3
- package/lib/dist/commands/specship/spec.md +85 -15
- package/lib/dist/db/spec-queries.d.ts +73 -3
- package/lib/dist/db/spec-queries.d.ts.map +1 -1
- package/lib/dist/db/spec-queries.js +139 -5
- package/lib/dist/db/spec-queries.js.map +1 -1
- package/lib/dist/db/sqlite-adapter.d.ts +7 -5
- package/lib/dist/db/sqlite-adapter.d.ts.map +1 -1
- package/lib/dist/db/sqlite-adapter.js +11 -9
- package/lib/dist/db/sqlite-adapter.js.map +1 -1
- package/lib/dist/enforce/changed-files.d.ts +39 -0
- package/lib/dist/enforce/changed-files.d.ts.map +1 -0
- package/lib/dist/enforce/changed-files.js +114 -0
- package/lib/dist/enforce/changed-files.js.map +1 -0
- package/lib/dist/enforce/enforce.d.ts +53 -2
- package/lib/dist/enforce/enforce.d.ts.map +1 -1
- package/lib/dist/enforce/enforce.js +95 -8
- package/lib/dist/enforce/enforce.js.map +1 -1
- package/lib/dist/enforce/mutation.d.ts +46 -0
- package/lib/dist/enforce/mutation.d.ts.map +1 -0
- package/lib/dist/enforce/mutation.js +104 -0
- package/lib/dist/enforce/mutation.js.map +1 -0
- package/lib/dist/enforce/suppressions.d.ts +33 -0
- package/lib/dist/enforce/suppressions.d.ts.map +1 -0
- package/lib/dist/enforce/suppressions.js +159 -0
- package/lib/dist/enforce/suppressions.js.map +1 -0
- package/lib/dist/extraction/grammars.d.ts +10 -0
- package/lib/dist/extraction/grammars.d.ts.map +1 -1
- package/lib/dist/extraction/grammars.js +32 -3
- package/lib/dist/extraction/grammars.js.map +1 -1
- package/lib/dist/extraction/index.d.ts +7 -0
- package/lib/dist/extraction/index.d.ts.map +1 -1
- package/lib/dist/extraction/index.js.map +1 -1
- package/lib/dist/extraction/specs/markdown-spec-extractor.d.ts +7 -0
- package/lib/dist/extraction/specs/markdown-spec-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/specs/markdown-spec-extractor.js +97 -10
- package/lib/dist/extraction/specs/markdown-spec-extractor.js.map +1 -1
- package/lib/dist/extraction/wasm/tree-sitter-pascal.wasm.gz +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-scala.wasm.gz +0 -0
- package/lib/dist/graph/spec-coverage.d.ts +142 -0
- package/lib/dist/graph/spec-coverage.d.ts.map +1 -0
- package/lib/dist/graph/spec-coverage.js +276 -0
- package/lib/dist/graph/spec-coverage.js.map +1 -0
- package/lib/dist/health/smoke-check.js +2 -2
- package/lib/dist/health/smoke-check.js.map +1 -1
- package/lib/dist/index.d.ts +75 -7
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +191 -23
- package/lib/dist/index.js.map +1 -1
- package/lib/dist/installer/gemini-commands.d.ts +107 -0
- package/lib/dist/installer/gemini-commands.d.ts.map +1 -0
- package/lib/dist/installer/gemini-commands.js +264 -0
- package/lib/dist/installer/gemini-commands.js.map +1 -0
- package/lib/dist/installer/index.d.ts +55 -8
- package/lib/dist/installer/index.d.ts.map +1 -1
- package/lib/dist/installer/index.js +72 -53
- package/lib/dist/installer/index.js.map +1 -1
- package/lib/dist/installer/init-offer.d.ts +14 -9
- package/lib/dist/installer/init-offer.d.ts.map +1 -1
- package/lib/dist/installer/init-offer.js +13 -9
- package/lib/dist/installer/init-offer.js.map +1 -1
- package/lib/dist/installer/install-defaults.d.ts +81 -0
- package/lib/dist/installer/install-defaults.d.ts.map +1 -0
- package/lib/dist/installer/install-defaults.js +95 -0
- package/lib/dist/installer/install-defaults.js.map +1 -0
- package/lib/dist/installer/instructions-template.d.ts +22 -0
- package/lib/dist/installer/instructions-template.d.ts.map +1 -1
- package/lib/dist/installer/instructions-template.js +37 -1
- package/lib/dist/installer/instructions-template.js.map +1 -1
- package/lib/dist/installer/targets/claude.d.ts +18 -0
- package/lib/dist/installer/targets/claude.d.ts.map +1 -1
- package/lib/dist/installer/targets/claude.js +70 -23
- package/lib/dist/installer/targets/claude.js.map +1 -1
- package/lib/dist/installer/targets/gemini.d.ts +85 -12
- package/lib/dist/installer/targets/gemini.d.ts.map +1 -1
- package/lib/dist/installer/targets/gemini.js +527 -30
- package/lib/dist/installer/targets/gemini.js.map +1 -1
- package/lib/dist/installer/targets/shared.d.ts +13 -0
- package/lib/dist/installer/targets/shared.d.ts.map +1 -1
- package/lib/dist/installer/targets/shared.js +22 -4
- package/lib/dist/installer/targets/shared.js.map +1 -1
- package/lib/dist/installer/targets/types.d.ts +12 -0
- package/lib/dist/installer/targets/types.d.ts.map +1 -1
- package/lib/dist/jira/auto-publish.d.ts +71 -4
- package/lib/dist/jira/auto-publish.d.ts.map +1 -1
- package/lib/dist/jira/auto-publish.js +186 -17
- package/lib/dist/jira/auto-publish.js.map +1 -1
- package/lib/dist/jira/reconcile.d.ts +24 -1
- package/lib/dist/jira/reconcile.d.ts.map +1 -1
- package/lib/dist/jira/reconcile.js +46 -2
- package/lib/dist/jira/reconcile.js.map +1 -1
- package/lib/dist/jira/repo-config.d.ts +9 -0
- package/lib/dist/jira/repo-config.d.ts.map +1 -1
- package/lib/dist/jira/repo-config.js +11 -0
- package/lib/dist/jira/repo-config.js.map +1 -1
- package/lib/dist/jira/types.d.ts +7 -0
- package/lib/dist/jira/types.d.ts.map +1 -1
- package/lib/dist/jira/types.js.map +1 -1
- package/lib/dist/knowledge/enforce.d.ts +75 -0
- package/lib/dist/knowledge/enforce.d.ts.map +1 -0
- package/lib/dist/knowledge/enforce.js +250 -0
- package/lib/dist/knowledge/enforce.js.map +1 -0
- package/lib/dist/knowledge/facts.d.ts +33 -0
- package/lib/dist/knowledge/facts.d.ts.map +1 -0
- package/lib/dist/knowledge/facts.js +117 -0
- package/lib/dist/knowledge/facts.js.map +1 -0
- package/lib/dist/knowledge/proposals.d.ts +88 -0
- package/lib/dist/knowledge/proposals.d.ts.map +1 -0
- package/lib/dist/knowledge/proposals.js +360 -0
- package/lib/dist/knowledge/proposals.js.map +1 -0
- package/lib/dist/knowledge/stale.d.ts +64 -0
- package/lib/dist/knowledge/stale.d.ts.map +1 -0
- package/lib/dist/knowledge/stale.js +174 -0
- package/lib/dist/knowledge/stale.js.map +1 -0
- package/lib/dist/mcp/fitness-tool.d.ts +5 -6
- package/lib/dist/mcp/fitness-tool.d.ts.map +1 -1
- package/lib/dist/mcp/fitness-tool.js +0 -16
- package/lib/dist/mcp/fitness-tool.js.map +1 -1
- package/lib/dist/mcp/gemini-session.d.ts +50 -0
- package/lib/dist/mcp/gemini-session.d.ts.map +1 -0
- package/lib/dist/mcp/gemini-session.js +159 -0
- package/lib/dist/mcp/gemini-session.js.map +1 -0
- package/lib/dist/mcp/health-tool.d.ts +26 -0
- package/lib/dist/mcp/health-tool.d.ts.map +1 -0
- package/lib/dist/mcp/health-tool.js +50 -0
- package/lib/dist/mcp/health-tool.js.map +1 -0
- package/lib/dist/mcp/jira-tools.d.ts.map +1 -1
- package/lib/dist/mcp/jira-tools.js +25 -0
- package/lib/dist/mcp/jira-tools.js.map +1 -1
- package/lib/dist/mcp/maintainability-tool.d.ts +5 -7
- package/lib/dist/mcp/maintainability-tool.d.ts.map +1 -1
- package/lib/dist/mcp/maintainability-tool.js +0 -16
- package/lib/dist/mcp/maintainability-tool.js.map +1 -1
- package/lib/dist/mcp/model-context.d.ts +31 -7
- package/lib/dist/mcp/model-context.d.ts.map +1 -1
- package/lib/dist/mcp/model-context.js +70 -21
- package/lib/dist/mcp/model-context.js.map +1 -1
- package/lib/dist/mcp/proxy.d.ts.map +1 -1
- package/lib/dist/mcp/proxy.js +5 -2
- package/lib/dist/mcp/proxy.js.map +1 -1
- package/lib/dist/mcp/server-instructions.d.ts +16 -15
- package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
- package/lib/dist/mcp/server-instructions.js +72 -5
- package/lib/dist/mcp/server-instructions.js.map +1 -1
- package/lib/dist/mcp/session.js +1 -1
- package/lib/dist/mcp/session.js.map +1 -1
- package/lib/dist/mcp/spec-tools.d.ts +9 -1
- package/lib/dist/mcp/spec-tools.d.ts.map +1 -1
- package/lib/dist/mcp/spec-tools.js +282 -49
- package/lib/dist/mcp/spec-tools.js.map +1 -1
- package/lib/dist/mcp/tools.d.ts +49 -9
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +210 -58
- package/lib/dist/mcp/tools.js.map +1 -1
- package/lib/dist/pulse/pulse.d.ts +93 -0
- package/lib/dist/pulse/pulse.d.ts.map +1 -0
- package/lib/dist/pulse/pulse.js +401 -0
- package/lib/dist/pulse/pulse.js.map +1 -0
- package/lib/dist/reflect/apply.d.ts.map +1 -1
- package/lib/dist/reflect/apply.js +38 -3
- package/lib/dist/reflect/apply.js.map +1 -1
- package/lib/dist/reflect/auto-sweep.d.ts +26 -0
- package/lib/dist/reflect/auto-sweep.d.ts.map +1 -0
- package/lib/dist/reflect/auto-sweep.js +90 -0
- package/lib/dist/reflect/auto-sweep.js.map +1 -0
- package/lib/dist/reflect/cli.d.ts +62 -0
- package/lib/dist/reflect/cli.d.ts.map +1 -0
- package/lib/dist/reflect/cli.js +163 -0
- package/lib/dist/reflect/cli.js.map +1 -0
- package/lib/dist/reflect/miner.d.ts.map +1 -1
- package/lib/dist/reflect/miner.js +119 -0
- package/lib/dist/reflect/miner.js.map +1 -1
- package/lib/dist/reflect/sweep.d.ts +1 -0
- package/lib/dist/reflect/sweep.d.ts.map +1 -1
- package/lib/dist/reflect/sweep.js +62 -13
- package/lib/dist/reflect/sweep.js.map +1 -1
- package/lib/dist/reflect/targets.d.ts +2 -0
- package/lib/dist/reflect/targets.d.ts.map +1 -1
- package/lib/dist/reflect/targets.js +33 -0
- package/lib/dist/reflect/targets.js.map +1 -1
- package/lib/dist/reflect/types.d.ts +19 -2
- package/lib/dist/reflect/types.d.ts.map +1 -1
- package/lib/dist/resolution/spec-link-resolver.d.ts +44 -2
- package/lib/dist/resolution/spec-link-resolver.d.ts.map +1 -1
- package/lib/dist/resolution/spec-link-resolver.js +132 -0
- package/lib/dist/resolution/spec-link-resolver.js.map +1 -1
- package/lib/dist/resolution/test-title-links.d.ts +62 -0
- package/lib/dist/resolution/test-title-links.d.ts.map +1 -0
- package/lib/dist/resolution/test-title-links.js +97 -0
- package/lib/dist/resolution/test-title-links.js.map +1 -0
- package/lib/dist/search/query-parser.d.ts.map +1 -1
- package/lib/dist/search/query-parser.js +6 -1
- package/lib/dist/search/query-parser.js.map +1 -1
- package/lib/dist/server/project-registry.js +1 -1
- package/lib/dist/server/routes/claude.js +24 -43
- package/lib/dist/server/routes/graph.js +53 -7
- package/lib/dist/server/routes/knowledge.js +118 -0
- package/lib/dist/server/routes/mcp.js +4 -3
- package/lib/dist/server/routes/projects.js +4 -4
- package/lib/dist/server/routes/spec.js +49 -7
- package/lib/dist/server/server.js +31 -17
- package/lib/dist/skills/spec-author/SKILL.md +164 -0
- package/lib/dist/skills/spec-author/references/format.md +210 -0
- package/lib/dist/skills/spec-author/references/gap-questions.md +152 -0
- package/lib/dist/skills/spec-author/references/quality-rubric.md +125 -0
- package/lib/dist/skills/spec-author/references/review-checklist.md +175 -0
- package/lib/dist/spec-lint/lint.d.ts +82 -0
- package/lib/dist/spec-lint/lint.d.ts.map +1 -0
- package/lib/dist/spec-lint/lint.js +491 -0
- package/lib/dist/spec-lint/lint.js.map +1 -0
- package/lib/dist/spec-quality/criterion-ids.d.ts +13 -0
- package/lib/dist/spec-quality/criterion-ids.d.ts.map +1 -0
- package/lib/dist/spec-quality/criterion-ids.js +38 -0
- package/lib/dist/spec-quality/criterion-ids.js.map +1 -0
- package/lib/dist/spec-quality/evidence-kind.d.ts +54 -0
- package/lib/dist/spec-quality/evidence-kind.d.ts.map +1 -0
- package/lib/dist/spec-quality/evidence-kind.js +183 -0
- package/lib/dist/spec-quality/evidence-kind.js.map +1 -0
- package/lib/dist/spec-quality/link-persist.d.ts +65 -0
- package/lib/dist/spec-quality/link-persist.d.ts.map +1 -0
- package/lib/dist/spec-quality/link-persist.js +249 -0
- package/lib/dist/spec-quality/link-persist.js.map +1 -0
- package/lib/dist/spec-quality/plan-scope.d.ts +38 -0
- package/lib/dist/spec-quality/plan-scope.d.ts.map +1 -0
- package/lib/dist/spec-quality/plan-scope.js +129 -0
- package/lib/dist/spec-quality/plan-scope.js.map +1 -0
- package/lib/dist/spec-quality/postcheck.d.ts +85 -0
- package/lib/dist/spec-quality/postcheck.d.ts.map +1 -0
- package/lib/dist/spec-quality/postcheck.js +390 -0
- package/lib/dist/spec-quality/postcheck.js.map +1 -0
- package/lib/dist/spec-quality/readiness.d.ts +72 -0
- package/lib/dist/spec-quality/readiness.d.ts.map +1 -0
- package/lib/dist/spec-quality/readiness.js +226 -0
- package/lib/dist/spec-quality/readiness.js.map +1 -0
- package/lib/dist/statusline/index.js.map +1 -1
- package/lib/dist/statusline/render.d.ts +1 -1
- package/lib/dist/statusline/render.d.ts.map +1 -1
- package/lib/dist/statusline/render.js +3 -1
- package/lib/dist/statusline/render.js.map +1 -1
- package/lib/dist/ui/assets/index-BzuUWUAE.js +50 -0
- package/lib/dist/ui/index.html +1 -1
- package/lib/dist/verify/report-ingest.d.ts +88 -0
- package/lib/dist/verify/report-ingest.d.ts.map +1 -0
- package/lib/dist/verify/report-ingest.js +269 -0
- package/lib/dist/verify/report-ingest.js.map +1 -0
- package/lib/dist/workflows/agents/claude.d.ts +16 -0
- package/lib/dist/workflows/agents/claude.d.ts.map +1 -0
- package/lib/dist/workflows/agents/claude.js +82 -0
- package/lib/dist/workflows/agents/claude.js.map +1 -0
- package/lib/dist/workflows/agents/gemini.d.ts +21 -0
- package/lib/dist/workflows/agents/gemini.d.ts.map +1 -0
- package/lib/dist/workflows/agents/gemini.js +124 -0
- package/lib/dist/workflows/agents/gemini.js.map +1 -0
- package/lib/dist/workflows/agents/index.d.ts +28 -0
- package/lib/dist/workflows/agents/index.d.ts.map +1 -0
- package/lib/dist/workflows/agents/index.js +104 -0
- package/lib/dist/workflows/agents/index.js.map +1 -0
- package/lib/dist/workflows/agents/types.d.ts +55 -0
- package/lib/dist/workflows/agents/types.d.ts.map +1 -0
- package/lib/dist/workflows/agents/types.js +46 -0
- package/lib/dist/workflows/agents/types.js.map +1 -0
- package/lib/dist/workflows/batch.d.ts +63 -0
- package/lib/dist/workflows/batch.d.ts.map +1 -0
- package/lib/dist/workflows/batch.js +151 -0
- package/lib/dist/workflows/batch.js.map +1 -0
- package/lib/dist/workflows/defaults/claude-design-implement.yaml +3 -4
- package/lib/dist/workflows/defaults/spec-author.yaml +11 -9
- package/lib/dist/workflows/defaults/spec-fix.yaml +103 -12
- package/lib/dist/workflows/defaults/spec-implement-mixed.yaml +21 -193
- package/lib/dist/workflows/defaults/spec-implement.yaml +701 -41
- package/lib/dist/workflows/defaults/spec-verify.yaml +60 -9
- package/lib/dist/workflows/discovery.d.ts +13 -0
- package/lib/dist/workflows/discovery.d.ts.map +1 -1
- package/lib/dist/workflows/discovery.js +79 -17
- package/lib/dist/workflows/discovery.js.map +1 -1
- package/lib/dist/workflows/executor.d.ts +18 -0
- package/lib/dist/workflows/executor.d.ts.map +1 -1
- package/lib/dist/workflows/executor.js +130 -33
- package/lib/dist/workflows/executor.js.map +1 -1
- package/lib/dist/workflows/gc.d.ts +50 -0
- package/lib/dist/workflows/gc.d.ts.map +1 -0
- package/lib/dist/workflows/gc.js +120 -0
- package/lib/dist/workflows/gc.js.map +1 -0
- package/lib/dist/workflows/merge-queue.d.ts +64 -0
- package/lib/dist/workflows/merge-queue.d.ts.map +1 -0
- package/lib/dist/workflows/merge-queue.js +162 -0
- package/lib/dist/workflows/merge-queue.js.map +1 -0
- package/lib/dist/workflows/runners/approval.d.ts +1 -1
- package/lib/dist/workflows/runners/approval.d.ts.map +1 -1
- package/lib/dist/workflows/runners/approval.js +11 -2
- package/lib/dist/workflows/runners/approval.js.map +1 -1
- package/lib/dist/workflows/runners/bash.d.ts +15 -0
- package/lib/dist/workflows/runners/bash.d.ts.map +1 -1
- package/lib/dist/workflows/runners/bash.js +50 -1
- package/lib/dist/workflows/runners/bash.js.map +1 -1
- package/lib/dist/workflows/runners/prompt.d.ts +16 -41
- package/lib/dist/workflows/runners/prompt.d.ts.map +1 -1
- package/lib/dist/workflows/runners/prompt.js +55 -120
- package/lib/dist/workflows/runners/prompt.js.map +1 -1
- package/lib/dist/workflows/runners/types.d.ts +12 -0
- package/lib/dist/workflows/runners/types.d.ts.map +1 -1
- package/lib/dist/workflows/schemas/workflow.d.ts +17 -0
- package/lib/dist/workflows/schemas/workflow.d.ts.map +1 -1
- package/lib/dist/workflows/schemas/workflow.js +27 -0
- package/lib/dist/workflows/schemas/workflow.js.map +1 -1
- package/lib/node_modules/.package-lock.json +1 -1
- package/lib/package.json +8 -4
- package/package.json +5 -3
- package/lib/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
- package/lib/dist/server/ingest/impact-query.js +0 -343
- package/lib/dist/server/routes/events.js +0 -152
- package/lib/dist/ui/assets/index-CjjaftDw.js +0 -50
- package/node.exe +0 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-adapter.d.ts","sourceRoot":"","sources":["../../src/db/sqlite-adapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sqlite-adapter.d.ts","sourceRoot":"","sources":["../../src/db/sqlite-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC7E,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAC3B,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;IAC7B;;;;;OAKG;IACH,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;IACtC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,GAAG,CAAC;IACzD,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACjE,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAqK7D;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,CAkC7F"}
|
|
@@ -10,13 +10,15 @@
|
|
|
10
10
|
* 1. `better-sqlite3` — present only when the host has installed it (a
|
|
11
11
|
* devDependency in this repo, optional in user installs). Ships its
|
|
12
12
|
* own SQLite compiled with FTS5, so it's the only path that works on
|
|
13
|
-
* dev machines whose system Node was built without FTS5.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* dev machines whose system Node was built without FTS5.
|
|
14
|
+
* 2. `node:sqlite` — Node's built-in module (Node 22.5+, the supported
|
|
15
|
+
* floor). Published packages bundle no runtime — they run on the
|
|
16
|
+
* user's installed Node (>=22.5 <25) — and `node:sqlite` only ships
|
|
17
|
+
* FTS5 on Node 24, so Node 22/23 users without better-sqlite3 lack FTS5.
|
|
17
18
|
*
|
|
18
19
|
* Tests, dev runs from source, and contributors get FTS5 via better-sqlite3.
|
|
19
|
-
* End users
|
|
20
|
+
* End users get FTS5 via better-sqlite3 (optional dependency) or Node 24's
|
|
21
|
+
* `node:sqlite`.
|
|
20
22
|
*/
|
|
21
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
24
|
exports.createDatabase = createDatabase;
|
|
@@ -204,10 +206,10 @@ function createDatabase(dbPath) {
|
|
|
204
206
|
errors.push(`node:sqlite: ${error instanceof Error ? error.message : String(error)}`);
|
|
205
207
|
throw new Error('Failed to open SQLite.\n' +
|
|
206
208
|
'SpecShip tries better-sqlite3 first (when installed), then falls back to\n' +
|
|
207
|
-
"Node's built-in node:sqlite (Node 22.5
|
|
208
|
-
'
|
|
209
|
-
'
|
|
210
|
-
'
|
|
209
|
+
"Node's built-in node:sqlite (Node 22.5+; FTS5 ships in node:sqlite only on\n" +
|
|
210
|
+
'Node 24). Run on Node 24, or install better-sqlite3\n' +
|
|
211
|
+
'(`npm install --save-dev better-sqlite3`) so FTS5 works on hosts whose\n' +
|
|
212
|
+
'Node was built without it.\n' +
|
|
211
213
|
`Backend errors:\n${errors.map((e) => ` - ${e}`).join('\n')}`);
|
|
212
214
|
}
|
|
213
215
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-adapter.js","sourceRoot":"","sources":["../../src/db/sqlite-adapter.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"sqlite-adapter.js","sourceRoot":"","sources":["../../src/db/sqlite-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Change scoping for the enforcement gate (REQ-AUTHG-006).
|
|
3
|
+
*
|
|
4
|
+
* `specship check --since <ref>` needs the set of files a working tree has
|
|
5
|
+
* touched since a git ref, so the drift and behaviour checks can evaluate only
|
|
6
|
+
* the requirements that change reaches. Gating all 60+ requirement docs in a
|
|
7
|
+
* repo makes the gate unusable as a pre-commit check; per-ID excludes were the
|
|
8
|
+
* only escape.
|
|
9
|
+
*
|
|
10
|
+
* The ref is validated before anything else runs: an unknown ref throws
|
|
11
|
+
* (REQ-AUTHG-006.A3) rather than silently degrading to a full-repo run, which
|
|
12
|
+
* would report findings the caller never asked about and quietly hide the typo.
|
|
13
|
+
*/
|
|
14
|
+
/** Thrown when `<ref>` is not a commit-ish this repository knows. */
|
|
15
|
+
export declare class InvalidRefError extends Error {
|
|
16
|
+
constructor(ref: string, detail?: string);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Files changed since `ref`: committed changes, uncommitted working-tree
|
|
20
|
+
* changes, and untracked files. Untracked files count because a newly authored
|
|
21
|
+
* spec (or a brand-new source file) is exactly the change a scoped run must
|
|
22
|
+
* see.
|
|
23
|
+
*
|
|
24
|
+
* Throws `InvalidRefError` when `ref` does not resolve, or a plain Error when
|
|
25
|
+
* the directory is not a git repository.
|
|
26
|
+
*/
|
|
27
|
+
export declare function changedFilesSince(projectRoot: string, ref: string): string[];
|
|
28
|
+
/**
|
|
29
|
+
* Unified diff text of the change under review (REQ-QGATE-004): tracked
|
|
30
|
+
* changes since `ref` (default HEAD), plus every untracked file rendered as a
|
|
31
|
+
* pseudo-diff of all-added lines — a brand-new file's suppressions are exactly
|
|
32
|
+
* as introduced as an edit's. Feed the result to `scanDisableComments`.
|
|
33
|
+
*
|
|
34
|
+
* Throws when the directory is not a git repository (callers decide whether
|
|
35
|
+
* an unavailable scan is skipped or fatal); binary/unreadable untracked files
|
|
36
|
+
* are silently omitted.
|
|
37
|
+
*/
|
|
38
|
+
export declare function workingTreeDiffText(projectRoot: string, ref?: string): string;
|
|
39
|
+
//# sourceMappingURL=changed-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changed-files.d.ts","sourceRoot":"","sources":["../../src/enforce/changed-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,qEAAqE;AACrE,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAQzC;AAWD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAwB5E;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CA2B7E"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Change scoping for the enforcement gate (REQ-AUTHG-006).
|
|
4
|
+
*
|
|
5
|
+
* `specship check --since <ref>` needs the set of files a working tree has
|
|
6
|
+
* touched since a git ref, so the drift and behaviour checks can evaluate only
|
|
7
|
+
* the requirements that change reaches. Gating all 60+ requirement docs in a
|
|
8
|
+
* repo makes the gate unusable as a pre-commit check; per-ID excludes were the
|
|
9
|
+
* only escape.
|
|
10
|
+
*
|
|
11
|
+
* The ref is validated before anything else runs: an unknown ref throws
|
|
12
|
+
* (REQ-AUTHG-006.A3) rather than silently degrading to a full-repo run, which
|
|
13
|
+
* would report findings the caller never asked about and quietly hide the typo.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.InvalidRefError = void 0;
|
|
17
|
+
exports.changedFilesSince = changedFilesSince;
|
|
18
|
+
exports.workingTreeDiffText = workingTreeDiffText;
|
|
19
|
+
const child_process_1 = require("child_process");
|
|
20
|
+
const fs_1 = require("fs");
|
|
21
|
+
const path_1 = require("path");
|
|
22
|
+
const enforce_1 = require("./enforce");
|
|
23
|
+
/** Thrown when `<ref>` is not a commit-ish this repository knows. */
|
|
24
|
+
class InvalidRefError extends Error {
|
|
25
|
+
constructor(ref, detail) {
|
|
26
|
+
super(`not a git ref in this repository: ${ref}` +
|
|
27
|
+
(detail ? ` (${detail})` : '') +
|
|
28
|
+
'. Pass a branch, tag or commit `specship check --since` can resolve.');
|
|
29
|
+
this.name = 'InvalidRefError';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.InvalidRefError = InvalidRefError;
|
|
33
|
+
function git(projectRoot, args) {
|
|
34
|
+
return (0, child_process_1.execFileSync)('git', args, {
|
|
35
|
+
cwd: projectRoot,
|
|
36
|
+
encoding: 'utf-8',
|
|
37
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
38
|
+
maxBuffer: 32 * 1024 * 1024,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Files changed since `ref`: committed changes, uncommitted working-tree
|
|
43
|
+
* changes, and untracked files. Untracked files count because a newly authored
|
|
44
|
+
* spec (or a brand-new source file) is exactly the change a scoped run must
|
|
45
|
+
* see.
|
|
46
|
+
*
|
|
47
|
+
* Throws `InvalidRefError` when `ref` does not resolve, or a plain Error when
|
|
48
|
+
* the directory is not a git repository.
|
|
49
|
+
*/
|
|
50
|
+
function changedFilesSince(projectRoot, ref) {
|
|
51
|
+
try {
|
|
52
|
+
git(projectRoot, ['rev-parse', '--is-inside-work-tree']);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
throw new Error(`not a git repository: ${projectRoot} — \`--since\` needs git to compute changed files`);
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
git(projectRoot, ['rev-parse', '--verify', '--quiet', `${ref}^{commit}`]);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
throw new InvalidRefError(ref, err instanceof Error ? err.message.trim().split('\n')[0] : undefined);
|
|
62
|
+
}
|
|
63
|
+
const out = new Set();
|
|
64
|
+
const collect = (raw) => {
|
|
65
|
+
for (const line of raw.split('\n')) {
|
|
66
|
+
const f = (0, enforce_1.normalizePath)(line.trim());
|
|
67
|
+
if (f)
|
|
68
|
+
out.add(f);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
collect(git(projectRoot, ['diff', '--name-only', ref, '--']));
|
|
72
|
+
collect(git(projectRoot, ['ls-files', '--others', '--exclude-standard']));
|
|
73
|
+
return [...out].sort();
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Unified diff text of the change under review (REQ-QGATE-004): tracked
|
|
77
|
+
* changes since `ref` (default HEAD), plus every untracked file rendered as a
|
|
78
|
+
* pseudo-diff of all-added lines — a brand-new file's suppressions are exactly
|
|
79
|
+
* as introduced as an edit's. Feed the result to `scanDisableComments`.
|
|
80
|
+
*
|
|
81
|
+
* Throws when the directory is not a git repository (callers decide whether
|
|
82
|
+
* an unavailable scan is skipped or fatal); binary/unreadable untracked files
|
|
83
|
+
* are silently omitted.
|
|
84
|
+
*/
|
|
85
|
+
function workingTreeDiffText(projectRoot, ref = 'HEAD') {
|
|
86
|
+
const parts = [git(projectRoot, ['diff', '--no-color', ref, '--'])];
|
|
87
|
+
const untracked = git(projectRoot, ['ls-files', '--others', '--exclude-standard'])
|
|
88
|
+
.split('\n')
|
|
89
|
+
.map((l) => l.trim())
|
|
90
|
+
.filter(Boolean);
|
|
91
|
+
for (const file of untracked) {
|
|
92
|
+
try {
|
|
93
|
+
const content = (0, fs_1.readFileSync)((0, path_1.join)(projectRoot, file), 'utf-8');
|
|
94
|
+
if (content.includes('\u0000'))
|
|
95
|
+
continue; // binary
|
|
96
|
+
const lines = content.split('\n');
|
|
97
|
+
if (lines[lines.length - 1] === '')
|
|
98
|
+
lines.pop();
|
|
99
|
+
parts.push([
|
|
100
|
+
`diff --git a/${file} b/${file}`,
|
|
101
|
+
'--- /dev/null',
|
|
102
|
+
`+++ b/${file}`,
|
|
103
|
+
`@@ -0,0 +1,${lines.length} @@`,
|
|
104
|
+
...lines.map((l) => `+${l}`),
|
|
105
|
+
'',
|
|
106
|
+
].join('\n'));
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// unreadable → skip
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return parts.join('\n');
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=changed-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changed-files.js","sourceRoot":"","sources":["../../src/enforce/changed-files.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AAqCH,8CAwBC;AAYD,kDA2BC;AAlGD,iDAA6C;AAC7C,2BAAkC;AAClC,+BAA4B;AAC5B,uCAA0C;AAE1C,qEAAqE;AACrE,MAAa,eAAgB,SAAQ,KAAK;IACxC,YAAY,GAAW,EAAE,MAAe;QACtC,KAAK,CACH,qCAAqC,GAAG,EAAE;YACxC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9B,sEAAsE,CACzE,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AATD,0CASC;AAED,SAAS,GAAG,CAAC,WAAmB,EAAE,IAAc;IAC9C,OAAO,IAAA,4BAAY,EAAC,KAAK,EAAE,IAAI,EAAE;QAC/B,GAAG,EAAE,WAAW;QAChB,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;QACjC,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;KAC5B,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,iBAAiB,CAAC,WAAmB,EAAE,GAAW;IAChE,IAAI,CAAC;QACH,GAAG,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,yBAAyB,WAAW,mDAAmD,CACxF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,GAAG,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC;IAC5E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,eAAe,CAAC,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACvG,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,MAAM,OAAO,GAAG,CAAC,GAAW,EAAQ,EAAE;QACpC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,IAAA,uBAAa,EAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACrC,IAAI,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,mBAAmB,CAAC,WAAmB,EAAE,GAAG,GAAG,MAAM;IACnE,MAAM,KAAK,GAAa,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,oBAAoB,CAAC,CAAC;SAC/E,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAA,iBAAY,EAAC,IAAA,WAAI,EAAC,WAAW,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YAC/D,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,SAAS,CAAC,SAAS;YACnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE;gBAAE,KAAK,CAAC,GAAG,EAAE,CAAC;YAChD,KAAK,CAAC,IAAI,CACR;gBACE,gBAAgB,IAAI,MAAM,IAAI,EAAE;gBAChC,eAAe;gBACf,SAAS,IAAI,EAAE;gBACf,cAAc,KAAK,CAAC,MAAM,KAAK;gBAC/B,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,EAAE;aACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,oBAAoB;QACtB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -17,13 +17,23 @@
|
|
|
17
17
|
import { SpecLink } from './../types';
|
|
18
18
|
import { FitnessReport } from '../fitness/fitness';
|
|
19
19
|
import { MaintainabilityReport } from '../graph/maintainability';
|
|
20
|
-
|
|
20
|
+
import { SuppressionFinding } from './suppressions';
|
|
21
|
+
import { MutationConfig, MutationDeps } from './mutation';
|
|
22
|
+
export type CheckName = 'drift' | 'fitness' | 'maintainability' | 'behaviour' | 'suppressions' | 'mutation';
|
|
23
|
+
/**
|
|
24
|
+
* Project-relative, forward-slashed, no `./` prefix. Link target paths, spec
|
|
25
|
+
* source paths and git's output all have to compare in one shape before
|
|
26
|
+
* change-scoping can match them (REQ-AUTHG-006).
|
|
27
|
+
*/
|
|
28
|
+
export declare function normalizePath(p: string): string;
|
|
21
29
|
/** Which checks gate (fail CI) vs merely advise. Absent key → advisory. */
|
|
22
30
|
export interface GateConfig {
|
|
23
31
|
drift?: boolean;
|
|
24
32
|
fitness?: boolean;
|
|
25
33
|
maintainability?: boolean;
|
|
26
34
|
behaviour?: boolean;
|
|
35
|
+
suppressions?: boolean;
|
|
36
|
+
mutation?: boolean;
|
|
27
37
|
}
|
|
28
38
|
export interface EnforceConfig {
|
|
29
39
|
gate?: GateConfig;
|
|
@@ -31,6 +41,12 @@ export interface EnforceConfig {
|
|
|
31
41
|
behaviour?: {
|
|
32
42
|
exclude?: string[];
|
|
33
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Mutation-score gate config (REQ-QGATE-002) — the check exists only when
|
|
46
|
+
* this key (or `gate.mutation`) is present; the default gate output is
|
|
47
|
+
* byte-identical without it (A1).
|
|
48
|
+
*/
|
|
49
|
+
mutation?: MutationConfig;
|
|
34
50
|
}
|
|
35
51
|
/** Tests-link summary for one requirement (its own + its acceptance criteria's). */
|
|
36
52
|
export interface RequirementVerification {
|
|
@@ -38,6 +54,10 @@ export interface RequirementVerification {
|
|
|
38
54
|
title: string;
|
|
39
55
|
/** All `tests`-kind links for the requirement and its acceptance children. */
|
|
40
56
|
testsLinks: SpecLink[];
|
|
57
|
+
/** Spec file this requirement is authored in, project-relative (REQ-AUTHG-006). */
|
|
58
|
+
sourcePath?: string;
|
|
59
|
+
/** Every file this requirement's links point at, any kind (REQ-AUTHG-006). */
|
|
60
|
+
linkedFiles?: string[];
|
|
41
61
|
}
|
|
42
62
|
export interface EnforceDeps {
|
|
43
63
|
/** Links currently in drifted / broken / orphaned state. */
|
|
@@ -45,12 +65,43 @@ export interface EnforceDeps {
|
|
|
45
65
|
fitness: FitnessReport;
|
|
46
66
|
maintainability: MaintainabilityReport;
|
|
47
67
|
requirements: RequirementVerification[];
|
|
68
|
+
/**
|
|
69
|
+
* Suppression markers introduced by the change under review
|
|
70
|
+
* (REQ-QGATE-004). Absent/undefined → the diff scan did not run (no git,
|
|
71
|
+
* no diff) and the check is omitted entirely — never reported as passed.
|
|
72
|
+
*/
|
|
73
|
+
suppressions?: SuppressionFinding[];
|
|
74
|
+
/** Mutation-score snapshot (REQ-QGATE-002); absent → check omitted (A1). */
|
|
75
|
+
mutation?: MutationDeps;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Change-scoped evaluation (REQ-AUTHG-006): restrict the link-scoped checks to
|
|
79
|
+
* the requirements a set of changed files reaches. Absent → whole repo, the
|
|
80
|
+
* unchanged behaviour (A2).
|
|
81
|
+
*/
|
|
82
|
+
export interface EnforceScope {
|
|
83
|
+
/** Project-relative, forward-slashed paths. */
|
|
84
|
+
changedFiles: string[];
|
|
85
|
+
/** The ref they were computed from, for the report header. */
|
|
86
|
+
since?: string;
|
|
48
87
|
}
|
|
49
88
|
export interface CheckOutcome {
|
|
50
89
|
check: CheckName;
|
|
51
90
|
gating: boolean;
|
|
52
91
|
passed: boolean;
|
|
53
92
|
findings: string[];
|
|
93
|
+
/**
|
|
94
|
+
* True when a `--since` scope narrowed this check. Only `drift` and
|
|
95
|
+
* `behaviour` are link-scoped; `fitness` and `maintainability` are
|
|
96
|
+
* repo-global analyses and always run unscoped (REQ-AUTHG-006).
|
|
97
|
+
*/
|
|
98
|
+
scoped?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* True when the check's input was unavailable (e.g. no mutation report):
|
|
101
|
+
* presented as skipped, never as pass or fail, and never gates
|
|
102
|
+
* (REQ-QGATE-002.A3).
|
|
103
|
+
*/
|
|
104
|
+
skipped?: boolean;
|
|
54
105
|
}
|
|
55
106
|
export interface EnforceReport {
|
|
56
107
|
checks: CheckOutcome[];
|
|
@@ -59,7 +110,7 @@ export interface EnforceReport {
|
|
|
59
110
|
/** True when no gating check failed (CI gate result). */
|
|
60
111
|
passed: boolean;
|
|
61
112
|
}
|
|
62
|
-
export declare function evaluateEnforcement(deps: EnforceDeps, config?: EnforceConfig): EnforceReport;
|
|
113
|
+
export declare function evaluateEnforcement(deps: EnforceDeps, config?: EnforceConfig, scope?: EnforceScope): EnforceReport;
|
|
63
114
|
/** Default name of the checked-in project config file at the project root. */
|
|
64
115
|
export declare const ENFORCE_CONFIG_FILE = "specship.config.json";
|
|
65
116
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforce.d.ts","sourceRoot":"","sources":["../../src/enforce/enforce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"enforce.d.ts","sourceRoot":"","sources":["../../src/enforce/enforce.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,20 +50,40 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
50
50
|
})();
|
|
51
51
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
52
|
exports.ALL_CHECKS = exports.ENFORCE_CONFIG_FILE = void 0;
|
|
53
|
+
exports.normalizePath = normalizePath;
|
|
53
54
|
exports.evaluateEnforcement = evaluateEnforcement;
|
|
54
55
|
exports.loadEnforceConfig = loadEnforceConfig;
|
|
55
56
|
exports.strictEnforceConfig = strictEnforceConfig;
|
|
56
57
|
exports.enableGateChecks = enableGateChecks;
|
|
57
58
|
const fs = __importStar(require("fs"));
|
|
58
59
|
const path = __importStar(require("path"));
|
|
59
|
-
|
|
60
|
+
const maintainability_1 = require("../graph/maintainability");
|
|
61
|
+
const suppressions_1 = require("./suppressions");
|
|
62
|
+
/**
|
|
63
|
+
* Project-relative, forward-slashed, no `./` prefix. Link target paths, spec
|
|
64
|
+
* source paths and git's output all have to compare in one shape before
|
|
65
|
+
* change-scoping can match them (REQ-AUTHG-006).
|
|
66
|
+
*/
|
|
67
|
+
function normalizePath(p) {
|
|
68
|
+
return p.replace(/\\/g, '/').replace(/^\.\//, '').replace(/^\/+/, '');
|
|
69
|
+
}
|
|
70
|
+
function evaluateEnforcement(deps, config = {}, scope) {
|
|
60
71
|
const gate = config.gate ?? {};
|
|
61
72
|
const exclude = new Set(config.behaviour?.exclude ?? []);
|
|
62
73
|
const checks = [];
|
|
74
|
+
// Change scoping (REQ-AUTHG-006.A1): drift and behaviour are link-scoped, so
|
|
75
|
+
// a changed-file set narrows them. Without a scope nothing below filters
|
|
76
|
+
// anything — the gate behaves exactly as it always has (A2).
|
|
77
|
+
const changed = scope ? new Set(scope.changedFiles.map(normalizePath)) : null;
|
|
78
|
+
const touches = (file) => !!file && !!changed && changed.has(normalizePath(file));
|
|
63
79
|
// --- drift ---
|
|
64
80
|
{
|
|
65
|
-
const
|
|
66
|
-
|
|
81
|
+
const links = changed ? deps.drift.filter((l) => touches(l.targetFilePath)) : deps.drift;
|
|
82
|
+
const findings = links.map((l) => `${l.specId} ${l.state} → ${l.targetQualifiedName}`);
|
|
83
|
+
checks.push({
|
|
84
|
+
check: 'drift', gating: gate.drift === true, passed: findings.length === 0, findings,
|
|
85
|
+
...(changed ? { scoped: true } : {}),
|
|
86
|
+
});
|
|
67
87
|
}
|
|
68
88
|
// --- fitness ---
|
|
69
89
|
{
|
|
@@ -74,6 +94,10 @@ function evaluateEnforcement(deps, config = {}) {
|
|
|
74
94
|
checks.push({ check: 'fitness', gating: gate.fitness === true, passed: deps.fitness.clean, findings });
|
|
75
95
|
}
|
|
76
96
|
// --- maintainability ---
|
|
97
|
+
// Gates on `highPrecisionClean`, not `m.clean` (REQ-REVINT-009.A1): the
|
|
98
|
+
// below-gateway signals (dead code, coupling) are lower-confidence and flood
|
|
99
|
+
// any real repo, so gating on them keeps the check permanently red. They
|
|
100
|
+
// still list as advisory findings (A2).
|
|
77
101
|
{
|
|
78
102
|
const m = deps.maintainability;
|
|
79
103
|
const findings = m.clean ? [] : [
|
|
@@ -83,7 +107,8 @@ function evaluateEnforcement(deps, config = {}) {
|
|
|
83
107
|
...(m.cycles.length ? [`${m.cycles.length} dependency cycle(s)`] : []),
|
|
84
108
|
...(m.deadCode.length ? [`${m.deadCode.length} dead-code candidate(s)`] : []),
|
|
85
109
|
];
|
|
86
|
-
|
|
110
|
+
const passed = (0, maintainability_1.highPrecisionClean)(m);
|
|
111
|
+
checks.push({ check: 'maintainability', gating: gate.maintainability === true, passed, findings });
|
|
87
112
|
}
|
|
88
113
|
// --- behaviour (spec→test→verify) ---
|
|
89
114
|
{
|
|
@@ -91,6 +116,11 @@ function evaluateEnforcement(deps, config = {}) {
|
|
|
91
116
|
for (const req of deps.requirements) {
|
|
92
117
|
if (exclude.has(req.id))
|
|
93
118
|
continue; // out of behaviour-gating scope (A4)
|
|
119
|
+
// A requirement is in a scoped run when its own spec file changed or any
|
|
120
|
+
// file it links to changed (REQ-AUTHG-006.A1). Everything else produces
|
|
121
|
+
// no findings at all (A2) — not even an "unverified" one.
|
|
122
|
+
if (changed && !touches(req.sourcePath) && !(req.linkedFiles ?? []).some(touches))
|
|
123
|
+
continue;
|
|
94
124
|
const tests = req.testsLinks;
|
|
95
125
|
const broken = tests.filter((l) => l.state === 'broken');
|
|
96
126
|
const verified = tests.filter((l) => l.state === 'verified');
|
|
@@ -101,9 +131,66 @@ function evaluateEnforcement(deps, config = {}) {
|
|
|
101
131
|
findings.push(`${req.id}: unverified — no passing test links it`); // A3
|
|
102
132
|
}
|
|
103
133
|
}
|
|
104
|
-
checks.push({
|
|
134
|
+
checks.push({
|
|
135
|
+
check: 'behaviour', gating: gate.behaviour === true, passed: findings.length === 0, findings,
|
|
136
|
+
...(changed ? { scoped: true } : {}),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
// --- suppressions (REQ-QGATE-004) ---
|
|
140
|
+
// Only when a diff scan actually ran: an absent scan is unknown, and an
|
|
141
|
+
// unknown result is never rendered as a pass (same doctrine as
|
|
142
|
+
// VERIFY_RESULT=skipped).
|
|
143
|
+
if (deps.suppressions !== undefined) {
|
|
144
|
+
const findings = deps.suppressions.map(suppressions_1.formatSuppressionFinding);
|
|
145
|
+
checks.push({
|
|
146
|
+
check: 'suppressions',
|
|
147
|
+
gating: gate.suppressions === true,
|
|
148
|
+
passed: findings.length === 0,
|
|
149
|
+
findings,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
// --- mutation score (REQ-QGATE-002) ---
|
|
153
|
+
// Present only when configured (A1). Per spec: aggregate mutant kill rates
|
|
154
|
+
// over the requirement's linked files that appear in the report; below the
|
|
155
|
+
// threshold → the spec's test evidence is weak. Report unavailable →
|
|
156
|
+
// skipped, which never fails and is never rendered as pass (A3).
|
|
157
|
+
if (deps.mutation !== undefined) {
|
|
158
|
+
const mu = deps.mutation;
|
|
159
|
+
if (mu.stats === null) {
|
|
160
|
+
checks.push({
|
|
161
|
+
check: 'mutation',
|
|
162
|
+
gating: gate.mutation === true,
|
|
163
|
+
passed: false,
|
|
164
|
+
skipped: true,
|
|
165
|
+
findings: [`mutation gate: skipped — ${mu.reason ?? 'no report'}`],
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const findings = [];
|
|
170
|
+
const pct = (n) => `${Math.round(n * 100)}%`;
|
|
171
|
+
for (const req of deps.requirements) {
|
|
172
|
+
if (changed && !touches(req.sourcePath) && !(req.linkedFiles ?? []).some(touches))
|
|
173
|
+
continue;
|
|
174
|
+
for (const file of new Set((req.linkedFiles ?? []).map(normalizePath))) {
|
|
175
|
+
const s = mu.stats.get(file);
|
|
176
|
+
if (!s || s.total === 0)
|
|
177
|
+
continue;
|
|
178
|
+
const rate = s.killed / s.total;
|
|
179
|
+
if (rate < mu.threshold) {
|
|
180
|
+
findings.push(`${req.id}: weak test evidence — ${file} mutant kill rate ${pct(rate)} < ${pct(mu.threshold)} threshold (${s.killed}/${s.total} killed)`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
checks.push({
|
|
185
|
+
check: 'mutation',
|
|
186
|
+
gating: gate.mutation === true,
|
|
187
|
+
passed: findings.length === 0,
|
|
188
|
+
findings,
|
|
189
|
+
...(changed ? { scoped: true } : {}),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
105
192
|
}
|
|
106
|
-
const gatedFailures = checks.filter((c) => c.gating && !c.passed).map((c) => c.check);
|
|
193
|
+
const gatedFailures = checks.filter((c) => c.gating && !c.passed && !c.skipped).map((c) => c.check);
|
|
107
194
|
return { checks, gatedFailures, passed: gatedFailures.length === 0 };
|
|
108
195
|
}
|
|
109
196
|
/** Default name of the checked-in project config file at the project root. */
|
|
@@ -125,13 +212,13 @@ function loadEnforceConfig(projectRoot) {
|
|
|
125
212
|
return {};
|
|
126
213
|
}
|
|
127
214
|
/** All check names, for `--strict` / `--enable-gate` validation. */
|
|
128
|
-
exports.ALL_CHECKS = ['drift', 'fitness', 'maintainability', 'behaviour'];
|
|
215
|
+
exports.ALL_CHECKS = ['drift', 'fitness', 'maintainability', 'behaviour', 'suppressions', 'mutation'];
|
|
129
216
|
/**
|
|
130
217
|
* The `--strict` override (REQ-ENFORCE-004.A2): every check gates for this
|
|
131
218
|
* run only. Nothing is read from or written to the project config.
|
|
132
219
|
*/
|
|
133
220
|
function strictEnforceConfig() {
|
|
134
|
-
return { gate: { drift: true, fitness: true, maintainability: true, behaviour: true } };
|
|
221
|
+
return { gate: { drift: true, fitness: true, maintainability: true, behaviour: true, suppressions: true, mutation: true } };
|
|
135
222
|
}
|
|
136
223
|
/**
|
|
137
224
|
* Persist gating for the named checks into `specship.config.json`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforce.js","sourceRoot":"","sources":["../../src/enforce/enforce.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"enforce.js","sourceRoot":"","sources":["../../src/enforce/enforce.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutation-score gate (REQ-QGATE-002).
|
|
3
|
+
*
|
|
4
|
+
* A `tests` link proves a test exists and passed — not that it would notice
|
|
5
|
+
* the implementation breaking (agent-written suites average high coverage but
|
|
6
|
+
* low mutant kill rates). This gate closes that: per spec, the kill rate of
|
|
7
|
+
* mutants in its linked implementation files must clear a threshold for the
|
|
8
|
+
* test evidence to count as strong.
|
|
9
|
+
*
|
|
10
|
+
* SpecShip does NOT run the mutation tool. It consumes a checked-in/CI-produced
|
|
11
|
+
* report in the cross-tool mutation-testing-report-schema JSON (StrykerJS and
|
|
12
|
+
* friends emit it natively; mutmut ecosystems convert). That keeps
|
|
13
|
+
* `specship check` deterministic and fast, and keeps the tool choice with the
|
|
14
|
+
* project. Opt-in via `specship.config.json` → `enforce.mutation`; with no
|
|
15
|
+
* config the check does not exist and the gate's output is unchanged (A1).
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_MUTATION_THRESHOLD = 0.8;
|
|
18
|
+
export declare const DEFAULT_MUTATION_REPORT = "reports/mutation/mutation.json";
|
|
19
|
+
/** Per-file mutant stats: killed includes Timeout (the mutant didn't survive). */
|
|
20
|
+
export interface MutationFileStats {
|
|
21
|
+
killed: number;
|
|
22
|
+
total: number;
|
|
23
|
+
}
|
|
24
|
+
export interface MutationConfig {
|
|
25
|
+
/** Project-relative path of the mutation-testing-report-schema JSON. */
|
|
26
|
+
report?: string;
|
|
27
|
+
/** Minimum kill rate (0–1) for a spec's implementation files. */
|
|
28
|
+
threshold?: number;
|
|
29
|
+
}
|
|
30
|
+
/** Deps snapshot the enforcement evaluation consumes. */
|
|
31
|
+
export interface MutationDeps {
|
|
32
|
+
/** Null when the report could not be read — the check reports skipped (A3). */
|
|
33
|
+
stats: Map<string, MutationFileStats> | null;
|
|
34
|
+
reason?: string;
|
|
35
|
+
threshold: number;
|
|
36
|
+
reportPath: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Parse a mutation-testing-report-schema JSON into per-file kill stats.
|
|
40
|
+
* File keys are normalized to project-relative forward-slash paths so they
|
|
41
|
+
* compare against link target paths.
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseMutationReport(json: string): Map<string, MutationFileStats>;
|
|
44
|
+
/** Assemble the deps snapshot from disk — missing/unreadable report → skipped. */
|
|
45
|
+
export declare function loadMutationDeps(projectRoot: string, cfg?: MutationConfig): MutationDeps;
|
|
46
|
+
//# sourceMappingURL=mutation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutation.d.ts","sourceRoot":"","sources":["../../src/enforce/mutation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,uBAAuB,mCAAmC,CAAC;AAExE,kFAAkF;AAClF,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAOD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAehF;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,cAAmB,GAAG,YAAY,CAc5F"}
|