@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
package/lib/dist/ui/index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
|
|
9
9
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16.png" />
|
|
10
10
|
<link rel="apple-touch-icon" sizes="180x180" href="/favicon-180.png" />
|
|
11
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
+
<script type="module" crossorigin src="/assets/index-BzuUWUAE.js"></script>
|
|
12
12
|
<link rel="stylesheet" crossorigin href="/assets/index-ezwX2EfG.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-report ingestion (REQ-VSTATE-004).
|
|
3
|
+
*
|
|
4
|
+
* `verified` used to mean "an LLM read a test log and said it passed". This
|
|
5
|
+
* module replaces that with a deterministic mapping: parse a real test report,
|
|
6
|
+
* match each reported case to the `tests` links that claim it, and move those
|
|
7
|
+
* links — passed → `verified`, failed → `broken` — recording the run itself as
|
|
8
|
+
* the evidence.
|
|
9
|
+
*
|
|
10
|
+
* Parsing is total before any write happens, so a malformed report exits with a
|
|
11
|
+
* parse error having changed no state (A4).
|
|
12
|
+
*/
|
|
13
|
+
import type { SpecLink } from '../types';
|
|
14
|
+
import type { SpecQueries } from '../db/spec-queries';
|
|
15
|
+
/** Thrown for an unreadable / unparseable / shapeless report (REQ-VSTATE-004.A4). */
|
|
16
|
+
export declare class TestReportParseError extends Error {
|
|
17
|
+
constructor(message: string);
|
|
18
|
+
}
|
|
19
|
+
/** One test case as reported by the runner. */
|
|
20
|
+
export interface ReportedTestCase {
|
|
21
|
+
/** Project-relative POSIX path of the test file. */
|
|
22
|
+
file: string;
|
|
23
|
+
/** The `it()` title, without ancestor describe titles. */
|
|
24
|
+
title: string;
|
|
25
|
+
/** Ancestors + title joined, as the runner reported it. */
|
|
26
|
+
fullName: string;
|
|
27
|
+
status: 'passed' | 'failed' | 'skipped';
|
|
28
|
+
failureMessage?: string;
|
|
29
|
+
}
|
|
30
|
+
/** What one link's state move was, for reporting. */
|
|
31
|
+
export interface LinkOutcome {
|
|
32
|
+
linkId: number;
|
|
33
|
+
specId: string;
|
|
34
|
+
file: string;
|
|
35
|
+
/** The matched test titles the verdict rests on. */
|
|
36
|
+
titles: string[];
|
|
37
|
+
from: SpecLink['state'];
|
|
38
|
+
to: SpecLink['state'];
|
|
39
|
+
}
|
|
40
|
+
export interface VerifyReportResult {
|
|
41
|
+
runId: string;
|
|
42
|
+
reportPath: string;
|
|
43
|
+
/** Total cases read out of the report. */
|
|
44
|
+
cases: number;
|
|
45
|
+
promoted: LinkOutcome[];
|
|
46
|
+
demoted: LinkOutcome[];
|
|
47
|
+
/** Links matched whose state didn't move (already there, or only skips). */
|
|
48
|
+
unchanged: number;
|
|
49
|
+
/** Reported cases that matched no `tests` link at all (A3). */
|
|
50
|
+
unmatched: number;
|
|
51
|
+
/** A bounded sample of the unmatched cases, for the operator (A3). */
|
|
52
|
+
unmatchedSample: string[];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Parse a vitest / jest JSON report (`vitest run --reporter=json`).
|
|
56
|
+
*
|
|
57
|
+
* Shape: `{ testResults: [{ name, assertionResults: [{ title, fullName,
|
|
58
|
+
* ancestorTitles, status, failureMessages }] }] }`. Anything else — invalid
|
|
59
|
+
* JSON, a non-object, a missing/!array `testResults` — is a parse error rather
|
|
60
|
+
* than an empty result, so a report written by a crashed runner can never read
|
|
61
|
+
* as "nothing to verify" (A4).
|
|
62
|
+
*/
|
|
63
|
+
export declare function parseVitestJsonReport(raw: string, projectRoot: string): ReportedTestCase[];
|
|
64
|
+
/**
|
|
65
|
+
* Does `testCase` prove `link`? Matching is by FILE first — a link's evidence
|
|
66
|
+
* must live in the file it points at — then by title, in descending precision:
|
|
67
|
+
*
|
|
68
|
+
* 1. the link's recorded `metadata.testTitles` (written by the test-title pass,
|
|
69
|
+
* REQ-VSTATE-002) contains the case's title or full name;
|
|
70
|
+
* 2. the case's full name mentions the link's spec id (the `(REQ-X.A1)` title
|
|
71
|
+
* convention, for links that predate the recorded titles);
|
|
72
|
+
* 3. the case's full name mentions the link's target symbol (a `verifies:`
|
|
73
|
+
* block naming a hoisted test function).
|
|
74
|
+
*/
|
|
75
|
+
export declare function caseMatchesLink(testCase: ReportedTestCase, link: SpecLink): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Read a report and apply it to the DB (REQ-VSTATE-004).
|
|
78
|
+
*
|
|
79
|
+
* Per matched link: any failed case → `broken`; otherwise at least one passed
|
|
80
|
+
* case → `verified`; only-skipped → left alone (a skipped test proves nothing
|
|
81
|
+
* either way). The verification record persisted on the link carries the run id,
|
|
82
|
+
* the report path, the ISO timestamp and the exact test names the verdict rests
|
|
83
|
+
* on, so `verified` is auditable back to a specific run.
|
|
84
|
+
*/
|
|
85
|
+
export declare function ingestTestReport(sq: SpecQueries, projectRoot: string, reportPath: string, options?: {
|
|
86
|
+
runId?: string;
|
|
87
|
+
}): VerifyReportResult;
|
|
88
|
+
//# sourceMappingURL=report-ingest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-ingest.d.ts","sourceRoot":"","sources":["../../src/verify/report-ingest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,qFAAqF;AACrF,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED,+CAA+C;AAC/C,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACxB,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAyBD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAiE1F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,gBAAgB,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAkBnF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,WAAW,EACf,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,kBAAkB,CAqFpB"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Test-report ingestion (REQ-VSTATE-004).
|
|
4
|
+
*
|
|
5
|
+
* `verified` used to mean "an LLM read a test log and said it passed". This
|
|
6
|
+
* module replaces that with a deterministic mapping: parse a real test report,
|
|
7
|
+
* match each reported case to the `tests` links that claim it, and move those
|
|
8
|
+
* links — passed → `verified`, failed → `broken` — recording the run itself as
|
|
9
|
+
* the evidence.
|
|
10
|
+
*
|
|
11
|
+
* Parsing is total before any write happens, so a malformed report exits with a
|
|
12
|
+
* parse error having changed no state (A4).
|
|
13
|
+
*/
|
|
14
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(o, k2, desc);
|
|
21
|
+
}) : (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
o[k2] = m[k];
|
|
24
|
+
}));
|
|
25
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
+
}) : function(o, v) {
|
|
28
|
+
o["default"] = v;
|
|
29
|
+
});
|
|
30
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
+
var ownKeys = function(o) {
|
|
32
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
+
var ar = [];
|
|
34
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
+
return ar;
|
|
36
|
+
};
|
|
37
|
+
return ownKeys(o);
|
|
38
|
+
};
|
|
39
|
+
return function (mod) {
|
|
40
|
+
if (mod && mod.__esModule) return mod;
|
|
41
|
+
var result = {};
|
|
42
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
+
__setModuleDefault(result, mod);
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.TestReportParseError = void 0;
|
|
49
|
+
exports.parseVitestJsonReport = parseVitestJsonReport;
|
|
50
|
+
exports.caseMatchesLink = caseMatchesLink;
|
|
51
|
+
exports.ingestTestReport = ingestTestReport;
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
/** Thrown for an unreadable / unparseable / shapeless report (REQ-VSTATE-004.A4). */
|
|
55
|
+
class TestReportParseError extends Error {
|
|
56
|
+
constructor(message) {
|
|
57
|
+
super(message);
|
|
58
|
+
this.name = 'TestReportParseError';
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.TestReportParseError = TestReportParseError;
|
|
62
|
+
/** Normalize an absolute or relative path to a project-relative POSIX path. */
|
|
63
|
+
function toProjectRelative(projectRoot, filePath) {
|
|
64
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
65
|
+
const abs = path.isAbsolute(normalized)
|
|
66
|
+
? normalized
|
|
67
|
+
: path.resolve(projectRoot, normalized);
|
|
68
|
+
const rel = path.relative(projectRoot, abs).replace(/\\/g, '/');
|
|
69
|
+
return rel.startsWith('..') ? normalized.replace(/^\.\//, '') : rel;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parse a vitest / jest JSON report (`vitest run --reporter=json`).
|
|
73
|
+
*
|
|
74
|
+
* Shape: `{ testResults: [{ name, assertionResults: [{ title, fullName,
|
|
75
|
+
* ancestorTitles, status, failureMessages }] }] }`. Anything else — invalid
|
|
76
|
+
* JSON, a non-object, a missing/!array `testResults` — is a parse error rather
|
|
77
|
+
* than an empty result, so a report written by a crashed runner can never read
|
|
78
|
+
* as "nothing to verify" (A4).
|
|
79
|
+
*/
|
|
80
|
+
function parseVitestJsonReport(raw, projectRoot) {
|
|
81
|
+
const trimmed = raw.trim();
|
|
82
|
+
if (trimmed.length === 0) {
|
|
83
|
+
throw new TestReportParseError('report file is empty');
|
|
84
|
+
}
|
|
85
|
+
let parsed;
|
|
86
|
+
try {
|
|
87
|
+
parsed = JSON.parse(trimmed);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
throw new TestReportParseError(`report is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
91
|
+
}
|
|
92
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
93
|
+
throw new TestReportParseError('report is not a JSON object');
|
|
94
|
+
}
|
|
95
|
+
const results = parsed.testResults;
|
|
96
|
+
if (!Array.isArray(results)) {
|
|
97
|
+
throw new TestReportParseError('report has no `testResults` array — expected `vitest run --reporter=json` output');
|
|
98
|
+
}
|
|
99
|
+
const cases = [];
|
|
100
|
+
for (const entry of results) {
|
|
101
|
+
if (typeof entry !== 'object' || entry === null)
|
|
102
|
+
continue;
|
|
103
|
+
const fileResult = entry;
|
|
104
|
+
const name = typeof fileResult.name === 'string' ? fileResult.name : '';
|
|
105
|
+
if (!name)
|
|
106
|
+
continue;
|
|
107
|
+
const file = toProjectRelative(projectRoot, name);
|
|
108
|
+
const assertions = Array.isArray(fileResult.assertionResults)
|
|
109
|
+
? fileResult.assertionResults
|
|
110
|
+
: [];
|
|
111
|
+
for (const a of assertions) {
|
|
112
|
+
if (typeof a !== 'object' || a === null)
|
|
113
|
+
continue;
|
|
114
|
+
const ar = a;
|
|
115
|
+
const title = typeof ar.title === 'string' ? ar.title : '';
|
|
116
|
+
if (!title)
|
|
117
|
+
continue;
|
|
118
|
+
const ancestors = Array.isArray(ar.ancestorTitles)
|
|
119
|
+
? ar.ancestorTitles.filter((t) => typeof t === 'string')
|
|
120
|
+
: [];
|
|
121
|
+
const fullName = typeof ar.fullName === 'string' && ar.fullName.length > 0
|
|
122
|
+
? ar.fullName
|
|
123
|
+
: [...ancestors, title].join(' > ');
|
|
124
|
+
const rawStatus = typeof ar.status === 'string' ? ar.status : 'skipped';
|
|
125
|
+
const status = rawStatus === 'passed'
|
|
126
|
+
? 'passed'
|
|
127
|
+
: rawStatus === 'failed'
|
|
128
|
+
? 'failed'
|
|
129
|
+
: 'skipped';
|
|
130
|
+
const failures = Array.isArray(ar.failureMessages)
|
|
131
|
+
? ar.failureMessages.filter((m) => typeof m === 'string')
|
|
132
|
+
: [];
|
|
133
|
+
cases.push({
|
|
134
|
+
file,
|
|
135
|
+
title,
|
|
136
|
+
fullName,
|
|
137
|
+
status,
|
|
138
|
+
failureMessage: failures[0],
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return cases;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Does `testCase` prove `link`? Matching is by FILE first — a link's evidence
|
|
146
|
+
* must live in the file it points at — then by title, in descending precision:
|
|
147
|
+
*
|
|
148
|
+
* 1. the link's recorded `metadata.testTitles` (written by the test-title pass,
|
|
149
|
+
* REQ-VSTATE-002) contains the case's title or full name;
|
|
150
|
+
* 2. the case's full name mentions the link's spec id (the `(REQ-X.A1)` title
|
|
151
|
+
* convention, for links that predate the recorded titles);
|
|
152
|
+
* 3. the case's full name mentions the link's target symbol (a `verifies:`
|
|
153
|
+
* block naming a hoisted test function).
|
|
154
|
+
*/
|
|
155
|
+
function caseMatchesLink(testCase, link) {
|
|
156
|
+
const linkFile = link.targetFilePath.replace(/\\/g, '/');
|
|
157
|
+
if (linkFile !== testCase.file)
|
|
158
|
+
return false;
|
|
159
|
+
const recorded = link.metadata?.testTitles;
|
|
160
|
+
if (Array.isArray(recorded)) {
|
|
161
|
+
for (const t of recorded) {
|
|
162
|
+
if (typeof t !== 'string')
|
|
163
|
+
continue;
|
|
164
|
+
if (t === testCase.title || t === testCase.fullName)
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (testCase.fullName.includes(link.specId))
|
|
169
|
+
return true;
|
|
170
|
+
// A file-targeted link (the test-title pass) has no symbol to match on — its
|
|
171
|
+
// qualified name IS the path, whose extension would match almost any title.
|
|
172
|
+
if (link.targetNodeKind === 'file')
|
|
173
|
+
return false;
|
|
174
|
+
const symbol = link.targetQualifiedName.split('.').pop() ?? '';
|
|
175
|
+
if (symbol.length >= 3 && testCase.fullName.includes(symbol))
|
|
176
|
+
return true;
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Read a report and apply it to the DB (REQ-VSTATE-004).
|
|
181
|
+
*
|
|
182
|
+
* Per matched link: any failed case → `broken`; otherwise at least one passed
|
|
183
|
+
* case → `verified`; only-skipped → left alone (a skipped test proves nothing
|
|
184
|
+
* either way). The verification record persisted on the link carries the run id,
|
|
185
|
+
* the report path, the ISO timestamp and the exact test names the verdict rests
|
|
186
|
+
* on, so `verified` is auditable back to a specific run.
|
|
187
|
+
*/
|
|
188
|
+
function ingestTestReport(sq, projectRoot, reportPath, options = {}) {
|
|
189
|
+
let raw;
|
|
190
|
+
try {
|
|
191
|
+
raw = fs.readFileSync(path.resolve(projectRoot, reportPath), 'utf-8');
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
throw new TestReportParseError(`cannot read report ${reportPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
195
|
+
}
|
|
196
|
+
// Parse EVERYTHING before the first write (A4).
|
|
197
|
+
const cases = parseVitestJsonReport(raw, projectRoot);
|
|
198
|
+
const runId = options.runId ?? `run-${Date.now()}`;
|
|
199
|
+
const verifiedAt = new Date().toISOString();
|
|
200
|
+
const testsLinks = sq.getAllLinks().filter((l) => l.kind === 'tests');
|
|
201
|
+
// Bucket the cases per link, and track which cases matched something.
|
|
202
|
+
const perLink = new Map();
|
|
203
|
+
const matchedCases = new Set();
|
|
204
|
+
for (const link of testsLinks) {
|
|
205
|
+
for (const c of cases) {
|
|
206
|
+
if (!caseMatchesLink(c, link))
|
|
207
|
+
continue;
|
|
208
|
+
const bucket = perLink.get(link.id) ?? { link, cases: [] };
|
|
209
|
+
bucket.cases.push(c);
|
|
210
|
+
perLink.set(link.id, bucket);
|
|
211
|
+
matchedCases.add(c);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
const promoted = [];
|
|
215
|
+
const demoted = [];
|
|
216
|
+
let unchanged = 0;
|
|
217
|
+
for (const { link, cases: linkCases } of perLink.values()) {
|
|
218
|
+
const failed = linkCases.filter((c) => c.status === 'failed');
|
|
219
|
+
const passed = linkCases.filter((c) => c.status === 'passed');
|
|
220
|
+
if (failed.length === 0 && passed.length === 0) {
|
|
221
|
+
unchanged++;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const pass = failed.length === 0;
|
|
225
|
+
const relevant = pass ? passed : failed;
|
|
226
|
+
const titles = relevant.map((c) => c.fullName);
|
|
227
|
+
const now = Date.now();
|
|
228
|
+
const metadata = {
|
|
229
|
+
...(link.metadata ?? {}),
|
|
230
|
+
verification: {
|
|
231
|
+
result: pass ? 'pass' : 'fail',
|
|
232
|
+
verifiedAt,
|
|
233
|
+
reason: pass
|
|
234
|
+
? `${passed.length} test(s) passed in ${path.basename(reportPath)}`
|
|
235
|
+
: (failed[0]?.failureMessage?.split('\n')[0] ??
|
|
236
|
+
`${failed.length} test(s) failed in ${path.basename(reportPath)}`),
|
|
237
|
+
evidence: relevant.map((c) => `${c.file}:${c.fullName}`),
|
|
238
|
+
run: { id: runId, report: reportPath, source: 'vitest-json', ranAt: verifiedAt },
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
const to = pass ? 'verified' : 'broken';
|
|
242
|
+
sq.updateSpecLinkState(link.id, to, null, now);
|
|
243
|
+
sq.updateSpecLinkMetadata(link.id, metadata, now);
|
|
244
|
+
const outcome = {
|
|
245
|
+
linkId: link.id,
|
|
246
|
+
specId: link.specId,
|
|
247
|
+
file: link.targetFilePath,
|
|
248
|
+
titles,
|
|
249
|
+
from: link.state,
|
|
250
|
+
to,
|
|
251
|
+
};
|
|
252
|
+
if (pass)
|
|
253
|
+
promoted.push(outcome);
|
|
254
|
+
else
|
|
255
|
+
demoted.push(outcome);
|
|
256
|
+
}
|
|
257
|
+
const unmatchedCases = cases.filter((c) => !matchedCases.has(c));
|
|
258
|
+
return {
|
|
259
|
+
runId,
|
|
260
|
+
reportPath,
|
|
261
|
+
cases: cases.length,
|
|
262
|
+
promoted,
|
|
263
|
+
demoted,
|
|
264
|
+
unchanged,
|
|
265
|
+
unmatched: unmatchedCases.length,
|
|
266
|
+
unmatchedSample: unmatchedCases.slice(0, 10).map((c) => `${c.file}:${c.fullName}`),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=report-ingest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-ingest.js","sourceRoot":"","sources":["../../src/verify/report-ingest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code headless adapter (REQ-AGENTADAPT-005): `claude --print` with
|
|
3
|
+
* stream-json output. The argument list is exactly what the prompt runner
|
|
4
|
+
* built before adapters existed (REQ-AGENTADAPT-005.A1).
|
|
5
|
+
*/
|
|
6
|
+
import type { PromptNode } from '../schemas/workflow';
|
|
7
|
+
import { EmitFn, HeadlessAgent, StreamParseState } from './types';
|
|
8
|
+
export declare function buildClaudeArgs(node: PromptNode): string[];
|
|
9
|
+
/**
|
|
10
|
+
* Parse one stream-json line, emit any activity events, and fold the result
|
|
11
|
+
* into `state`. Pure aside from the `emit` callback. Unknown / non-JSON lines
|
|
12
|
+
* are ignored. Extended-thinking blocks are intentionally NOT emitted.
|
|
13
|
+
*/
|
|
14
|
+
export declare function handleClaudeStreamLine(line: string, emit: EmitFn, state: StreamParseState): void;
|
|
15
|
+
export declare const claudeHeadlessAgent: HeadlessAgent;
|
|
16
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../src/workflows/agents/claude.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAsB,gBAAgB,EAAqC,MAAM,SAAS,CAAC;AAEzH,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,CAkB1D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CA4BhG;AAED,eAAO,MAAM,mBAAmB,EAAE,aAQjC,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Claude Code headless adapter (REQ-AGENTADAPT-005): `claude --print` with
|
|
4
|
+
* stream-json output. The argument list is exactly what the prompt runner
|
|
5
|
+
* built before adapters existed (REQ-AGENTADAPT-005.A1).
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.claudeHeadlessAgent = void 0;
|
|
9
|
+
exports.buildClaudeArgs = buildClaudeArgs;
|
|
10
|
+
exports.handleClaudeStreamLine = handleClaudeStreamLine;
|
|
11
|
+
const types_1 = require("./types");
|
|
12
|
+
function buildClaudeArgs(node) {
|
|
13
|
+
const args = [];
|
|
14
|
+
args.push('--print');
|
|
15
|
+
// Stream the agent's activity as JSONL so we can surface tool calls and
|
|
16
|
+
// messages live. `--print` + `--output-format stream-json` requires
|
|
17
|
+
// `--verbose` (the CLI rejects the combination otherwise).
|
|
18
|
+
args.push('--output-format', 'stream-json', '--verbose');
|
|
19
|
+
if (node.model)
|
|
20
|
+
args.push('--model', node.model);
|
|
21
|
+
if (node.allowed_tools && node.allowed_tools.length > 0) {
|
|
22
|
+
args.push('--allowed-tools', node.allowed_tools.join(','));
|
|
23
|
+
}
|
|
24
|
+
if (node.denied_tools && node.denied_tools.length > 0) {
|
|
25
|
+
args.push('--disallowed-tools', node.denied_tools.join(','));
|
|
26
|
+
}
|
|
27
|
+
if (node.systemPromptAppend) {
|
|
28
|
+
args.push('--append-system-prompt', node.systemPromptAppend);
|
|
29
|
+
}
|
|
30
|
+
return args;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parse one stream-json line, emit any activity events, and fold the result
|
|
34
|
+
* into `state`. Pure aside from the `emit` callback. Unknown / non-JSON lines
|
|
35
|
+
* are ignored. Extended-thinking blocks are intentionally NOT emitted.
|
|
36
|
+
*/
|
|
37
|
+
function handleClaudeStreamLine(line, emit, state) {
|
|
38
|
+
const e = (0, types_1.parseJsonLine)(line);
|
|
39
|
+
if (!e)
|
|
40
|
+
return;
|
|
41
|
+
if (e.type === 'assistant' && e.message && typeof e.message === 'object') {
|
|
42
|
+
state.sawStream = true;
|
|
43
|
+
const content = e.message.content;
|
|
44
|
+
if (Array.isArray(content)) {
|
|
45
|
+
for (const raw of content) {
|
|
46
|
+
const b = raw;
|
|
47
|
+
if (b?.type === 'tool_use') {
|
|
48
|
+
emit('tool_called', { name: b.name, input: (0, types_1.summarizeToolInput)(b.input) });
|
|
49
|
+
}
|
|
50
|
+
else if (b?.type === 'text' && typeof b.text === 'string' && b.text.trim()) {
|
|
51
|
+
state.assistantText += (state.assistantText ? '\n' : '') + b.text;
|
|
52
|
+
emit('agent_message', { text: b.text });
|
|
53
|
+
}
|
|
54
|
+
// 'thinking' blocks: deliberately skipped.
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else if (e.type === 'result') {
|
|
59
|
+
state.sawStream = true;
|
|
60
|
+
if (typeof e.result === 'string')
|
|
61
|
+
state.resultText = e.result;
|
|
62
|
+
if (typeof e.total_cost_usd === 'number')
|
|
63
|
+
state.costUsd = e.total_cost_usd;
|
|
64
|
+
if (typeof e.duration_ms === 'number')
|
|
65
|
+
state.durationMs = e.duration_ms;
|
|
66
|
+
}
|
|
67
|
+
else if (e.type === 'system') {
|
|
68
|
+
state.sawStream = true; // init/system frame — confirms we're on the stream path
|
|
69
|
+
if (typeof e.model === 'string' && e.model)
|
|
70
|
+
state.model = e.model;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.claudeHeadlessAgent = {
|
|
74
|
+
id: 'claude',
|
|
75
|
+
// Claude Code sets CLAUDECODE=1 in the environment of the commands it runs.
|
|
76
|
+
launchedFrom: (env) => env.CLAUDECODE === '1',
|
|
77
|
+
build(node, _config, env) {
|
|
78
|
+
return { bin: env.SPECSHIP_CLAUDE_BIN ?? 'claude', args: buildClaudeArgs(node), stdin: node.prompt };
|
|
79
|
+
},
|
|
80
|
+
handleLine: handleClaudeStreamLine,
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../src/workflows/agents/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini CLI headless adapter (REQ-AGENTADAPT-007), against the installed
|
|
3
|
+
* 0.28.0 source (DOM-SPECSHIP-008): piped stdin runs Gemini headless, and in
|
|
4
|
+
* that mode every approval-needing tool not in `--allowed-tools` is removed,
|
|
5
|
+
* so each step's tools are translated to Gemini's names. There is no deny or
|
|
6
|
+
* append-system-prompt flag: `denied_tools` is refused, and the appended
|
|
7
|
+
* system prompt leads the stdin prompt.
|
|
8
|
+
*/
|
|
9
|
+
import { EmitFn, HeadlessAgent, StreamParseState } from './types';
|
|
10
|
+
/** Translate a step's allowed tools, or name the first one with no Gemini equivalent. */
|
|
11
|
+
export declare function translateGeminiTools(tools: string[]): {
|
|
12
|
+
tools: string[];
|
|
13
|
+
} | {
|
|
14
|
+
error: string;
|
|
15
|
+
};
|
|
16
|
+
/** The Gemini model for a step: a mapped tier alias, a Gemini id as-is, else none (Gemini's default). */
|
|
17
|
+
export declare function geminiModelFor(model: string | undefined, models: Record<string, string> | undefined): string | undefined;
|
|
18
|
+
/** Parse one Gemini stream-json event (init / message / tool_use / error / result). */
|
|
19
|
+
export declare function handleGeminiStreamLine(line: string, emit: EmitFn, state: StreamParseState): void;
|
|
20
|
+
export declare const geminiHeadlessAgent: HeadlessAgent;
|
|
21
|
+
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../src/workflows/agents/gemini.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,aAAa,EAAsB,gBAAgB,EAAqC,MAAM,SAAS,CAAC;AAiBzH,yFAAyF;AACzF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAa7F;AAED,yGAAyG;AACzG,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAIxH;AAED,uFAAuF;AACvF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAmChG;AAED,eAAO,MAAM,mBAAmB,EAAE,aAsBjC,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Gemini CLI headless adapter (REQ-AGENTADAPT-007), against the installed
|
|
4
|
+
* 0.28.0 source (DOM-SPECSHIP-008): piped stdin runs Gemini headless, and in
|
|
5
|
+
* that mode every approval-needing tool not in `--allowed-tools` is removed,
|
|
6
|
+
* so each step's tools are translated to Gemini's names. There is no deny or
|
|
7
|
+
* append-system-prompt flag: `denied_tools` is refused, and the appended
|
|
8
|
+
* system prompt leads the stdin prompt.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.geminiHeadlessAgent = void 0;
|
|
12
|
+
exports.translateGeminiTools = translateGeminiTools;
|
|
13
|
+
exports.geminiModelFor = geminiModelFor;
|
|
14
|
+
exports.handleGeminiStreamLine = handleGeminiStreamLine;
|
|
15
|
+
const types_1 = require("./types");
|
|
16
|
+
/** Claude-form built-in tool names → Gemini CLI 0.28 tool names. */
|
|
17
|
+
const BUILTIN_TOOLS = {
|
|
18
|
+
Read: 'read_file',
|
|
19
|
+
Write: 'write_file',
|
|
20
|
+
Edit: 'replace',
|
|
21
|
+
MultiEdit: 'replace',
|
|
22
|
+
Bash: 'run_shell_command',
|
|
23
|
+
Glob: 'glob',
|
|
24
|
+
Grep: 'grep_search',
|
|
25
|
+
LS: 'list_directory',
|
|
26
|
+
WebFetch: 'web_fetch',
|
|
27
|
+
WebSearch: 'google_web_search',
|
|
28
|
+
};
|
|
29
|
+
const MODEL_TIERS = new Set(['haiku', 'sonnet', 'opus']);
|
|
30
|
+
/** Translate a step's allowed tools, or name the first one with no Gemini equivalent. */
|
|
31
|
+
function translateGeminiTools(tools) {
|
|
32
|
+
const out = [];
|
|
33
|
+
for (const tool of tools) {
|
|
34
|
+
let mapped;
|
|
35
|
+
const mcp = tool.match(/^mcp__([A-Za-z0-9_-]+?)__(.+)$/);
|
|
36
|
+
const shell = tool.match(/^Bash\((.+?)(?::\*)?\)$/);
|
|
37
|
+
if (mcp)
|
|
38
|
+
mapped = `${mcp[1]}__${mcp[2]}`;
|
|
39
|
+
else if (shell)
|
|
40
|
+
mapped = `run_shell_command(${shell[1].trim()})`;
|
|
41
|
+
else
|
|
42
|
+
mapped = BUILTIN_TOOLS[tool];
|
|
43
|
+
if (!mapped)
|
|
44
|
+
return { error: `allowed tool "${tool}" has no Gemini CLI equivalent` };
|
|
45
|
+
if (!out.includes(mapped))
|
|
46
|
+
out.push(mapped);
|
|
47
|
+
}
|
|
48
|
+
return { tools: out };
|
|
49
|
+
}
|
|
50
|
+
/** The Gemini model for a step: a mapped tier alias, a Gemini id as-is, else none (Gemini's default). */
|
|
51
|
+
function geminiModelFor(model, models) {
|
|
52
|
+
if (!model)
|
|
53
|
+
return undefined;
|
|
54
|
+
if (MODEL_TIERS.has(model))
|
|
55
|
+
return models?.[model];
|
|
56
|
+
return /^gemini/i.test(model) ? model : undefined; // a Claude id is never passed to Gemini
|
|
57
|
+
}
|
|
58
|
+
/** Parse one Gemini stream-json event (init / message / tool_use / error / result). */
|
|
59
|
+
function handleGeminiStreamLine(line, emit, state) {
|
|
60
|
+
const e = (0, types_1.parseJsonLine)(line);
|
|
61
|
+
if (!e)
|
|
62
|
+
return;
|
|
63
|
+
switch (e.type) {
|
|
64
|
+
case 'init':
|
|
65
|
+
state.sawStream = true;
|
|
66
|
+
if (typeof e.model === 'string' && e.model)
|
|
67
|
+
state.model = e.model;
|
|
68
|
+
break;
|
|
69
|
+
case 'message':
|
|
70
|
+
state.sawStream = true;
|
|
71
|
+
if (e.role === 'assistant' && typeof e.content === 'string' && e.content) {
|
|
72
|
+
// Deltas are fragments of one turn; whole messages are separate turns.
|
|
73
|
+
state.assistantText += e.delta === true || !state.assistantText ? e.content : `\n${e.content}`;
|
|
74
|
+
emit('agent_message', { text: e.content });
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
case 'tool_use':
|
|
78
|
+
state.sawStream = true;
|
|
79
|
+
emit('tool_called', { name: e.tool_name, input: (0, types_1.summarizeToolInput)(e.parameters) });
|
|
80
|
+
break;
|
|
81
|
+
case 'result': {
|
|
82
|
+
state.sawStream = true;
|
|
83
|
+
const stats = e.stats;
|
|
84
|
+
if (stats && typeof stats.duration_ms === 'number')
|
|
85
|
+
state.durationMs = stats.duration_ms;
|
|
86
|
+
if (e.status === 'error') {
|
|
87
|
+
const err = e.error;
|
|
88
|
+
state.failure = typeof err?.message === 'string' ? err.message : 'Gemini CLI reported an error result';
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case 'error':
|
|
93
|
+
state.sawStream = true;
|
|
94
|
+
if (e.severity === 'error' && typeof e.message === 'string')
|
|
95
|
+
state.failure = e.message;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.geminiHeadlessAgent = {
|
|
100
|
+
id: 'gemini',
|
|
101
|
+
// Gemini CLI sets GEMINI_CLI=1 for the shell commands it runs.
|
|
102
|
+
launchedFrom: (env) => env.GEMINI_CLI === '1',
|
|
103
|
+
build(node, config, env) {
|
|
104
|
+
if (node.denied_tools && node.denied_tools.length > 0) {
|
|
105
|
+
return { error: `denied_tools (${node.denied_tools.join(', ')}) cannot be enforced on Gemini CLI — it has no deny flag` };
|
|
106
|
+
}
|
|
107
|
+
const args = ['--output-format', 'stream-json'];
|
|
108
|
+
const model = geminiModelFor(node.model, config.models);
|
|
109
|
+
if (model)
|
|
110
|
+
args.push('--model', model);
|
|
111
|
+
if (node.allowed_tools && node.allowed_tools.length > 0) {
|
|
112
|
+
const t = translateGeminiTools(node.allowed_tools);
|
|
113
|
+
if ('error' in t)
|
|
114
|
+
return t;
|
|
115
|
+
args.push('--allowed-tools', ...t.tools);
|
|
116
|
+
}
|
|
117
|
+
const stdin = node.systemPromptAppend
|
|
118
|
+
? `${node.systemPromptAppend.trimEnd()}\n\n---\n\n${node.prompt}`
|
|
119
|
+
: node.prompt;
|
|
120
|
+
return { bin: env.SPECSHIP_GEMINI_BIN ?? 'gemini', args, stdin };
|
|
121
|
+
},
|
|
122
|
+
handleLine: handleGeminiStreamLine,
|
|
123
|
+
};
|
|
124
|
+
//# sourceMappingURL=gemini.js.map
|