@bjoernrochel/sevro 0.1.0-rc.7 → 1.0.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/CONTRIBUTING.md +22 -6
- package/README.md +5 -1
- package/docs/README.md +19 -15
- package/docs/architecture.md +138 -17
- package/docs/assets/README.md +5 -4
- package/docs/builtin-graders-v1.md +17 -3
- package/docs/codex-host.md +155 -49
- package/docs/contracts.md +2 -1
- package/docs/creating-cases.md +9 -2
- package/docs/development-cli.md +187 -19
- package/docs/documentation-quality.md +12 -2
- package/docs/evaluation-workflow.md +110 -0
- package/docs/extension-protocol-v1.md +26 -3
- package/docs/getting-started.md +23 -2
- package/docs/guide-evaluation.md +33 -1
- package/docs/identity-v1.md +25 -2
- package/docs/installing.md +11 -11
- package/docs/native-controls.md +76 -5
- package/docs/native-hosts.md +196 -7
- package/docs/reading-results.md +102 -0
- package/docs/recipes.md +489 -0
- package/docs/releases.md +31 -12
- package/docs/report-v1.md +29 -1
- package/docs/results-v1.md +141 -4
- package/docs/run-settings-v1.md +147 -0
- package/docs/runtime-v1.md +307 -18
- package/docs/troubleshooting.md +12 -12
- package/docs/typescript-quality.md +89 -26
- package/examples/recipes/candidate.ts +26 -0
- package/examples/recipes/cases/coding-change.json +21 -0
- package/examples/recipes/cases/host-tools.json +21 -0
- package/examples/recipes/cases/mise.json +21 -0
- package/examples/recipes/cases/node.json +21 -0
- package/examples/recipes/cases/python-uv.json +21 -0
- package/examples/recipes/cases/semantic.json +17 -0
- package/examples/recipes/coding-change/check.ts +23 -0
- package/examples/recipes/extension-artifacts.ts +65 -0
- package/examples/recipes/extension-methods.ts +174 -0
- package/examples/recipes/extension.ts +37 -0
- package/examples/recipes/repository-skill/.agents/skills/startup-guide/SKILL.md +7 -0
- package/examples/recipes/repository-skill/.claude/skills/startup-guide/SKILL.md +7 -0
- package/examples/recipes/repository-skill/README.md +3 -0
- package/examples/recipes/run-inputs.ts +188 -0
- package/examples/recipes/run-options.ts +131 -0
- package/examples/recipes/run.ts +63 -0
- package/examples/recipes/runtime/empty.json +1 -0
- package/examples/recipes/runtime/goals.json +1 -0
- package/examples/recipes/runtime/mise.json +6 -0
- package/examples/recipes/runtime/path.json +1 -0
- package/examples/recipes/runtime/plugins.json +4 -0
- package/examples/recipes/runtime/python-uv.json +10 -0
- package/examples/recipes/semantic-judge.ts +29 -0
- package/examples/templates/coding/adapter.ts +17 -0
- package/examples/templates/coding/case.json +15 -0
- package/examples/templates/repository-skill/.agents/skills/startup-guide/SKILL.md +6 -0
- package/examples/templates/repository-skill/extension-data.ts +64 -0
- package/examples/templates/repository-skill/extension.ts +31 -0
- package/examples/templates/response/adapter.ts +12 -0
- package/examples/templates/response/case.json +13 -0
- package/package.json +11 -5
- package/schemas/report-v1.schema.json +9 -0
- package/schemas/run-evidence-v1.schema.json +2 -1
- package/schemas/runtime-v1.schema.json +63 -7
- package/src/advisory.ts +2 -2
- package/src/candidate-artifacts.ts +206 -0
- package/src/candidate-codex-state.ts +185 -0
- package/src/case-validation.ts +73 -50
- package/src/cli/cancellation.ts +20 -0
- package/src/cli/command.ts +87 -0
- package/src/cli/completion.ts +15 -0
- package/src/cli/demo.ts +60 -0
- package/src/cli/evaluation.ts +55 -0
- package/src/cli/extension.ts +79 -0
- package/src/cli/help.ts +198 -0
- package/src/cli/hosts.ts +55 -0
- package/src/cli/init-settings.ts +30 -0
- package/src/cli/init.ts +111 -0
- package/src/{cli-invocation.ts → cli/invocation.ts} +214 -218
- package/src/cli/loading.ts +151 -0
- package/src/cli/preparation.ts +154 -0
- package/src/cli/presentation.ts +93 -0
- package/src/cli/progress.ts +6 -0
- package/src/cli/run-manifest.ts +128 -0
- package/src/cli/run-options.ts +403 -0
- package/src/cli/run-overrides.ts +69 -0
- package/src/cli/settings.ts +154 -0
- package/src/cli/summary.ts +43 -0
- package/src/cli.ts +13 -591
- package/src/contract-types.ts +94 -0
- package/src/engine.ts +13 -5
- package/src/evaluation/advisory.ts +150 -0
- package/src/{evaluation-check-plan.ts → evaluation/check-plan.ts} +103 -67
- package/src/evaluation/collection.ts +88 -0
- package/src/evaluation/context.ts +10 -0
- package/src/{evaluation-grading-host.ts → evaluation/grading-host.ts} +5 -5
- package/src/evaluation/grading.ts +235 -0
- package/src/{evaluation-invocation-plan.ts → evaluation/invocation-plan.ts} +147 -58
- package/src/{evaluation-plan.ts → evaluation/plan.ts} +208 -141
- package/src/evaluation/progress.ts +19 -0
- package/src/evaluation/resources.ts +241 -0
- package/src/evaluation/run.ts +206 -0
- package/src/{evaluation-semantic.ts → evaluation/semantic.ts} +133 -115
- package/src/evaluation/trial.ts +800 -0
- package/src/evaluation/types.ts +207 -0
- package/src/evidence/host-results.ts +85 -0
- package/src/evidence/retained-artifacts.ts +18 -0
- package/src/evidence/trial-writer.ts +203 -0
- package/src/evidence/usage.ts +17 -0
- package/src/extension-client.ts +34 -96
- package/src/extension-session.ts +24 -48
- package/src/{advisory-fixture.ts → fixtures/advisory.ts} +15 -76
- package/src/{fixture-bin.ts → fixtures/bin.ts} +1 -1
- package/src/{fixture-cleanup.ts → fixtures/cleanup.ts} +13 -7
- package/src/fixtures/create.ts +183 -0
- package/src/{generated-fixture.ts → fixtures/generated.ts} +10 -53
- package/src/{git-hooks.ts → fixtures/git-hooks.ts} +1 -1
- package/src/{preparation.ts → fixtures/preparation.ts} +6 -16
- package/src/{repository-fixture.ts → fixtures/repository.ts} +30 -64
- package/src/{fixture-setup.ts → fixtures/setup.ts} +33 -51
- package/src/{fixture-tools.ts → fixtures/tools.ts} +1 -1
- package/src/fixtures/workspace-state.ts +212 -0
- package/src/generated/cli-result.d.cts +2 -1
- package/src/generated/extension.d.cts +2 -1
- package/src/generated/report.cjs +1 -1
- package/src/generated/report.d.cts +2 -1
- package/src/generated/run-evidence.cjs +1 -1
- package/src/generated/run-evidence.d.cts +2 -1
- package/src/generated/runtime.cjs +1 -1
- package/src/generated/runtime.d.cts +2 -1
- package/src/git.ts +93 -0
- package/src/graders/git-head.ts +29 -84
- package/src/graders/shell.ts +57 -68
- package/src/host-diagnostic-redaction.ts +52 -0
- package/src/host-diagnostics.ts +331 -0
- package/src/hosts/claude-continuation.ts +57 -40
- package/src/hosts/claude-credential.ts +160 -63
- package/src/hosts/claude-events.ts +34 -18
- package/src/hosts/claude-keychain.ts +78 -21
- package/src/hosts/claude-login-recovery.ts +85 -0
- package/src/hosts/claude-login-refresh.ts +178 -0
- package/src/hosts/claude-login-store.ts +162 -0
- package/src/hosts/claude-login.ts +107 -0
- package/src/hosts/claude-native-goal.ts +15 -12
- package/src/hosts/claude-process.ts +10 -50
- package/src/hosts/claude-refresh-lock.ts +81 -0
- package/src/hosts/claude-repository-invocation.ts +9 -34
- package/src/hosts/claude-settings.ts +91 -14
- package/src/hosts/claude-skill-activations.ts +169 -0
- package/src/hosts/claude-state.ts +46 -16
- package/src/hosts/claude-tool-calls.ts +13 -10
- package/src/hosts/claude.ts +122 -73
- package/src/hosts/codex-app-server.ts +78 -52
- package/src/hosts/codex-configuration.ts +5 -10
- package/src/hosts/codex-exec-controls.ts +516 -0
- package/src/hosts/codex-marketplace.ts +12 -10
- package/src/hosts/codex-native-calls.ts +15 -122
- package/src/hosts/codex-process.ts +10 -54
- package/src/hosts/codex-profile.ts +50 -21
- package/src/hosts/codex-session-files.ts +1 -9
- package/src/hosts/codex-state.ts +141 -19
- package/src/hosts/codex.ts +221 -179
- package/src/hosts/isolation-common.ts +15 -11
- package/src/hosts/isolation-roots.ts +13 -20
- package/src/hosts/linux-sandbox.ts +27 -3
- package/src/hosts/mac-sandbox.ts +111 -18
- package/src/hosts/native-controls.ts +72 -22
- package/src/hosts/native-request.ts +55 -0
- package/src/hosts/process-lifecycle.ts +221 -45
- package/src/hosts/protected-worktrees.ts +1 -1
- package/src/hosts/skill-hook-catalog.ts +131 -0
- package/src/hosts/skill-hook-handler.ts +374 -0
- package/src/hosts/skill-hooks.ts +577 -0
- package/src/instrumentation.ts +7 -8
- package/src/native-transcript-state.ts +22 -3
- package/src/native-transcript-view.ts +52 -13
- package/src/native-transcripts.ts +34 -15
- package/src/paths.ts +22 -0
- package/src/process-lifecycle.ts +150 -0
- package/src/provenance.ts +27 -7
- package/src/prune.ts +300 -0
- package/src/report.ts +63 -36
- package/src/resolved-case.ts +1 -1
- package/src/results-lock.ts +42 -0
- package/src/results.ts +14 -18
- package/src/run-owner.ts +4 -4
- package/src/{runtime-config.ts → runtime/config.ts} +182 -44
- package/src/{runtime-discovery-apple.ts → runtime/discovery-apple.ts} +3 -3
- package/src/{runtime-discovery-providers.ts → runtime/discovery-providers.ts} +3 -9
- package/src/{runtime-discovery.ts → runtime/discovery.ts} +4 -4
- package/src/{runtime-hook-processes.ts → runtime/hook-processes.ts} +1 -1
- package/src/{runtime-hooks.ts → runtime/hooks.ts} +33 -22
- package/src/{runtime-paths.ts → runtime/paths.ts} +6 -18
- package/src/{runtime-query.ts → runtime/query.ts} +5 -5
- package/src/{runtime-seeds.ts → runtime/seeds.ts} +3 -3
- package/src/runtime/shared-cache.ts +130 -0
- package/src/{runtime-state.ts → runtime/state.ts} +28 -11
- package/src/schema-types.ts +73 -161
- package/src/shell.ts +4 -0
- package/src/transcript-retention.ts +146 -0
- package/src/value-guards.ts +22 -0
- package/docs/assets/sevro-logo.png +0 -0
- package/docs/assets/sevro-symbol.svg +0 -1
- package/docs/assets/sevro-wordmark.svg +0 -1
- package/docs/cache-ownership-validation.md +0 -49
- package/docs/claude-continuation-validation.md +0 -47
- package/docs/concurrency-validation.md +0 -86
- package/docs/configuration-root-validation.md +0 -70
- package/docs/engine-slice.md +0 -114
- package/docs/evidence/runtime-startup-30/README.md +0 -185
- package/docs/evidence/runtime-startup-30/after.json +0 -319
- package/docs/evidence/runtime-startup-30/baseline-timeout.jsonl +0 -2
- package/docs/evidence/runtime-startup-30/before.json +0 -403
- package/docs/evidence/runtime-startup-30/consumer-smoke.json +0 -63
- package/docs/evidence/runtime-startup-30/full-policy-diagnostic.jsonl +0 -3
- package/docs/evidence/runtime-startup-30/minimal-policy-diagnostic.jsonl +0 -3
- package/docs/evidence/runtime-startup-30/plugin-template-assessment.json +0 -20
- package/docs/evidence/runtime-startup-30/seedless-timeout.jsonl +0 -2
- package/docs/evidence.md +0 -17
- package/docs/fixture-cleanup-validation.md +0 -70
- package/docs/guide-verification.json +0 -239
- package/src/evaluation-context.ts +0 -257
- package/src/evaluation-fixture.ts +0 -313
- package/src/evaluation-run.ts +0 -198
- package/src/evaluation-trial.ts +0 -946
- package/src/evaluation-types.ts +0 -149
- package/src/hosts/claude-nested-skills.ts +0 -272
- package/src/hosts/codex-command-output.ts +0 -510
- package/src/hosts/codex-executor-command.ts +0 -291
- package/src/hosts/codex-skill-reads.ts +0 -609
- /package/src/{trial-scheduler.ts → evaluation/scheduler.ts} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# TypeScript quality
|
|
2
2
|
|
|
3
|
-
`bun run check:typescript` is the local
|
|
3
|
+
`bun run check:typescript` is the complete local acceptance command. CI runs the
|
|
4
|
+
same checks in parallel phases. The complete command performs a
|
|
4
5
|
frozen dependency installation, checks the complete source inventory, verifies
|
|
5
6
|
generated schemas, documentation contracts, formatting, type-aware lint and typing,
|
|
6
7
|
checks the Codex guide evaluation in dry mode and runs documentation examples, exercises coverage
|
|
@@ -14,13 +15,44 @@ schemas, documentation contracts, formatting, lint and types without the full in
|
|
|
14
15
|
or package installation. Install dependencies with `bun install --frozen-lockfile`
|
|
15
16
|
first. Quality dependencies are development dependencies pinned in `bun.lock`.
|
|
16
17
|
|
|
18
|
+
After frozen installation, `bun run check:typescript --phase <name>` runs one
|
|
19
|
+
phase and checks the complete source inventory. Each phase reports its elapsed
|
|
20
|
+
time, including when it fails. The complete command runs these same phases in
|
|
21
|
+
order; `--fast` runs only `static` without installing dependencies.
|
|
22
|
+
|
|
23
|
+
| Phase | Checks |
|
|
24
|
+
| --------- | --------------------------------------------------------------------------------------------- |
|
|
25
|
+
| `static` | Schema freshness, documentation contracts, formatting, type-aware lint and typing |
|
|
26
|
+
| `docs` | All guide dry runs, tutorial examples and recipe checks |
|
|
27
|
+
| `tests` | Coverage integrity controls, the complete instrumented Bun suite and both coverage thresholds |
|
|
28
|
+
| `package` | Packed-package installation and installed CLI workflows |
|
|
29
|
+
|
|
30
|
+
Use the same prerequisites as the corresponding complete-gate checks. A single
|
|
31
|
+
phase is partial evidence; full acceptance requires all four on the same candidate.
|
|
32
|
+
CI assigns every test file to exactly one of four duration-balanced shards, then
|
|
33
|
+
enforces both coverage thresholds on their combined counters over the complete
|
|
34
|
+
production inventory. Local `--phase tests` and the complete command still run
|
|
35
|
+
the suite in one process. See the [shard commands](../scripts/coverage/README.md#test-shards)
|
|
36
|
+
for reproducing the CI split.
|
|
37
|
+
|
|
17
38
|
## Source dispositions
|
|
18
39
|
|
|
19
|
-
[
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
40
|
+
The [inventory guard](../scripts/typescript-inventory.ts) derives every TypeScript
|
|
41
|
+
and JavaScript source disposition from Git paths, following the
|
|
42
|
+
[maintainer decision in #143](https://github.com/BjRo/sevro/issues/143#issuecomment-6382662399).
|
|
43
|
+
It classifies `git ls-files --cached --others --exclude-standard -z` output using
|
|
44
|
+
the checked path rules, so supported additions and staged renames or deletions
|
|
45
|
+
need no manual manifest edit. Non-ignored untracked sources are included in local
|
|
46
|
+
candidate checks; committed CI checkouts use their tracked paths. Declarations
|
|
47
|
+
take precedence over directory roles, and only the validators in the shared
|
|
48
|
+
[schema catalog](../scripts/schema-catalog.ts) receive the generated disposition.
|
|
49
|
+
Unknown or ambiguous paths, missing tracked files, an incomplete generated set,
|
|
50
|
+
and sources outside lint or typing are refused. An independent filesystem audit
|
|
51
|
+
also refuses ignored authored sources rather than silently dropping them.
|
|
52
|
+
Changing a disposition rule still requires review. Isolated coverage snapshots
|
|
53
|
+
index their copied candidate independently, preserving additions and deletions
|
|
54
|
+
without changing the source checkout's index.
|
|
55
|
+
The coverage baseline includes the platform-reachable subset of
|
|
24
56
|
`inventory.production`; `scripts/coverage/platform-scope.ts` names each excluded
|
|
25
57
|
host-specific file. Every production file remains inventoried, typed and linted,
|
|
26
58
|
and the opposite platform measures it. Current instrumentation supports authored
|
|
@@ -29,14 +61,14 @@ validators in `inventory.generated` are excluded from instrumentation and the
|
|
|
29
61
|
coverage denominator. New `.tsx`, `.mts`, `.cts` or JavaScript
|
|
30
62
|
production requires an explicit instrumentation and quality-policy change first.
|
|
31
63
|
|
|
32
|
-
| Inventory | Lint and typing | Test and coverage disposition
|
|
33
|
-
| -------------- | ---------------------------------------------------------------------------------------------------- |
|
|
34
|
-
| `production` | Type-aware strict lint and strict compiler | All platform-reachable authored executable `src` statements and branch outcomes, including unimported files in that scope
|
|
35
|
-
| `generated` | CommonJS syntax parsing, exact `schemas:check` freshness, and checked `.d.cts` boundary declarations | Real Bun schema tests; the five declared generated validators are outside the coverage denominator
|
|
36
|
-
| `declarations` | Type-aware lint and compiler | Declaration-only files have no executable counters
|
|
37
|
-
| `tooling` | Same type-aware lint and strict compiler; `.mjs`/`.cjs` use `checkJs` and explicit JSDoc contracts | Durable public gate probes, schema freshness, release and installed-package tests; outside the runner-production denominator
|
|
38
|
-
| `tests` | Same type-aware lint and strict compiler, including fixtures | Real Bun filesystem/process/protocol tests; outside the production denominator
|
|
39
|
-
| `examples` | Same type-aware lint and strict compiler | Packaged
|
|
64
|
+
| Inventory | Lint and typing | Test and coverage disposition |
|
|
65
|
+
| -------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
66
|
+
| `production` | Type-aware strict lint and strict compiler | All platform-reachable authored executable `src` statements and branch outcomes, including unimported files in that scope |
|
|
67
|
+
| `generated` | CommonJS syntax parsing, exact `schemas:check` freshness, and checked `.d.cts` boundary declarations | Real Bun schema tests; the five declared generated validators are outside the coverage denominator |
|
|
68
|
+
| `declarations` | Type-aware lint and compiler | Declaration-only files have no executable counters |
|
|
69
|
+
| `tooling` | Same type-aware lint and strict compiler; `.mjs`/`.cjs` use `checkJs` and explicit JSDoc contracts | Durable public gate probes, schema freshness, release and installed-package tests; outside the runner-production denominator |
|
|
70
|
+
| `tests` | Same type-aware lint and strict compiler, including fixtures | Real Bun filesystem/process/protocol tests; outside the production denominator |
|
|
71
|
+
| `examples` | Same type-aware lint and strict compiler | Packaged recipe adapters, extensions and evaluator checks are consumer examples, exercised by tutorial and installed-package validation; they implement no runner behavior and are outside the runner-production denominator |
|
|
40
72
|
|
|
41
73
|
Generated AJV CommonJS is deliberately not rewritten to conform to authored-code
|
|
42
74
|
rules. An earlier audit of the original four generated files using ESLint's
|
|
@@ -45,8 +77,8 @@ recommended JavaScript rules found 879 redeclarations, 281 useless assignments,
|
|
|
45
77
|
generation freshness, typed public boundaries and runtime behavior remain checked.
|
|
46
78
|
Generated compiler output is excluded from coverage because the coverage target
|
|
47
79
|
measures authored runner behavior. This applies only to
|
|
48
|
-
|
|
49
|
-
|
|
80
|
+
the exact validator paths derived from the [schema catalog](../scripts/schema-catalog.ts),
|
|
81
|
+
which also drives schema generation. This disposition does not apply to authored CommonJS, including
|
|
50
82
|
the coverage capture hook.
|
|
51
83
|
|
|
52
84
|
## Types, functions and review
|
|
@@ -120,7 +152,7 @@ macOS `sandbox-exec`, Keychain and Apple metadata modules are excluded; on macOS
|
|
|
120
152
|
`bubblewrap` module is excluded. Shared isolation and credential code is counted
|
|
121
153
|
on both.
|
|
122
154
|
|
|
123
|
-
Apple developer-tool discovery lives in `src/runtime
|
|
155
|
+
Apple developer-tool discovery lives in `src/runtime/discovery-apple.ts`, which
|
|
124
156
|
the public loader imports only under its explicit Darwin guard. Linux excludes
|
|
125
157
|
that exact native module; macOS measures it, and both platforms still typecheck
|
|
126
158
|
and lint it. The provider lookup, bounded query and read-root safeguards remain
|
|
@@ -146,12 +178,24 @@ summary, process ledger, Bun test log, unmodified source snapshot, LCOV and HTML
|
|
|
146
178
|
production files, branch exclusions, and exact projected counts.
|
|
147
179
|
`coverage-raw.json` and the raw summary preserve all validated counters before
|
|
148
180
|
platform projection.
|
|
181
|
+
CI also retains `.quality/shards/<index>/` with each shard's source snapshot,
|
|
182
|
+
process ledger, test log, raw and portable counters, and manifest. Process IDs
|
|
183
|
+
remain scoped to their original shard. Aggregation verifies candidate contents,
|
|
184
|
+
workflow run, platform, architecture, Bun version, instrumentation
|
|
185
|
+
layout, and exact test assignments before combining counters with normalized
|
|
186
|
+
source paths. Missing, repeated, incomplete, or mismatched shards fail the gate.
|
|
187
|
+
Failed-job reruns can reuse successful shards from earlier attempts of the same
|
|
188
|
+
workflow run; manifests retain each attempt, and rerun shards replace only their
|
|
189
|
+
own artifacts. Another candidate or workflow run cannot supply missing evidence.
|
|
149
190
|
`--coverage [Bun test arguments]` is a diagnostic measurement; it still enforces
|
|
150
191
|
both thresholds and writes `.quality/coverage-targeted`, keeping it distinct from
|
|
151
192
|
the full-suite evidence. Sparse runs are expected to fail the full denominator.
|
|
152
193
|
|
|
153
194
|
The durable public probes are `--probe snapshot`, `--probe scope`, `--probe branch`,
|
|
154
195
|
`--probe missing-reports`, `--probe integrity`, and `--probe source-map`.
|
|
196
|
+
`tests/scripts/typescript-quality.test.ts` invokes each probe once during the suite;
|
|
197
|
+
the phase entrypoint and shard merge do not rerun them. The commands remain
|
|
198
|
+
available for targeted diagnostics.
|
|
155
199
|
The scope probe records a zero-seeded baseline and merged real process report
|
|
156
200
|
under `.quality/coverage-scope`; it verifies that ordinary generated CommonJS
|
|
157
201
|
validation still runs. Branch and missing-report controls
|
|
@@ -167,21 +211,40 @@ Codex 0.160.1 and Claude Code 2.1.284 for deterministic native hook tests. Hoste
|
|
|
167
211
|
CI targets `ubuntu-24.04` x64 with Bun 1.3.13 and Node 24.13.0. Its first
|
|
168
212
|
successful hosted run is required before describing that environment as validated.
|
|
169
213
|
GitHub documents the [Ubuntu runner labels](https://docs.github.com/en/actions/reference/runners/github-hosted-runners).
|
|
170
|
-
Ubuntu installs `bubblewrap` and `socat` and runs the same native isolation cases;
|
|
171
|
-
local macOS runs retain `sandbox-exec`.
|
|
214
|
+
Ubuntu installs `bubblewrap`, `ripgrep`, and `socat` and runs the same native isolation cases;
|
|
215
|
+
local macOS runs retain `sandbox-exec`. The macOS quality and coverage gate is
|
|
216
|
+
local-only; the hosted workflow does not run a macOS gate. Windows remains unverified.
|
|
217
|
+
|
|
218
|
+
Ordinary changes and explicit workflow dispatches run the four canonical phases
|
|
219
|
+
concurrently. The tests phase consists of four shard jobs followed by a combined
|
|
220
|
+
coverage job. Each job installs locked dependencies; native host tools are
|
|
221
|
+
installed for `docs` and the test shards, and UV and mise for `docs`. Each shard
|
|
222
|
+
retains its evidence, and the combined `tests` job uploads `.quality` even when
|
|
223
|
+
coverage fails. Shards do not cancel their siblings on failure. A new commit to
|
|
224
|
+
the same pull request cancels its superseded workflow run; main pushes and manual
|
|
225
|
+
runs have independent concurrency groups. The stable aggregate `TypeScript quality`
|
|
226
|
+
status requires every phase and all four shards to succeed. A missing, cancelled,
|
|
227
|
+
skipped or failed phase or shard cannot turn that status green.
|
|
172
228
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
229
|
+
CI caches Bun's package downloads by Bun version, OS, architecture and `bun.lock`;
|
|
230
|
+
every job still performs frozen installation. The docs job and test shards also
|
|
231
|
+
cache the installed Codex and Claude packages by OS, architecture and the setup
|
|
232
|
+
script's content hash, which includes both pinned versions and their installation
|
|
233
|
+
layout. There are no fallback keys for native tools. On a hit, setup copies the
|
|
234
|
+
cached packages into a fresh temporary tool root and verifies both native versions
|
|
235
|
+
before publishing their paths. The cache never contains credentials or replaces
|
|
236
|
+
the isolation prerequisites or required checks.
|
|
177
237
|
|
|
178
238
|
Release metadata changes follow [the release workflow](releases.md) and reuse a
|
|
179
239
|
successful full gate from an ancestor on `main`, with identical code,
|
|
180
240
|
dependencies, schemas, tests, and other quality inputs. The selector permits
|
|
181
241
|
only version/distribution-tag changes and its exact release-file inventory.
|
|
182
|
-
It verifies
|
|
183
|
-
|
|
184
|
-
|
|
242
|
+
It verifies each original phase job and its gate step, including every shard and
|
|
243
|
+
the combined tests job for sharded runs, or a historical complete gate job and
|
|
244
|
+
step. A partial matrix or reused release run cannot serve as fresh test evidence.
|
|
245
|
+
Duplicate phase or shard jobs are ambiguous and refused. Release CI
|
|
246
|
+
runs `check:typescript --fast`, records the tested source and CI run URL, and
|
|
247
|
+
skips all four full-gate phase jobs. The aggregate
|
|
185
248
|
status requires both verified prior evidence and successful static checks;
|
|
186
249
|
missing, cancelled, failed, or ambiguous evidence cannot establish a pass.
|
|
187
250
|
Reused results remain attributed to their original run rather than being
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
/** Trusted, deterministic participant for exercising the recipe's real graders. */
|
|
5
|
+
const host = {
|
|
6
|
+
id: "recipes.deterministic",
|
|
7
|
+
model: "fixture-editor",
|
|
8
|
+
effort: "none",
|
|
9
|
+
async run({ workspace }: { workspace: string }) {
|
|
10
|
+
const task = await readFile(join(workspace, "README.md"), "utf8");
|
|
11
|
+
const failing = process.env.SEVRO_RECIPE_FAIL === "1";
|
|
12
|
+
if (task.includes("Fix add")) {
|
|
13
|
+
await writeFile(
|
|
14
|
+
join(workspace, "math.cjs"),
|
|
15
|
+
`exports.add = (a, b) => a ${failing ? "-" : "+"} b;\n`,
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
finalMessage: failing
|
|
20
|
+
? "Start with npm start on port 9000."
|
|
21
|
+
: "Run bun run dev on port 3000.",
|
|
22
|
+
complete: true,
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export default host;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "recipe-coding-change",
|
|
3
|
+
"prompt": "Fix add in math.cjs so it adds its two numeric arguments. Do not modify README.md. Explain how to start the application.",
|
|
4
|
+
"fixture": {
|
|
5
|
+
"files": {
|
|
6
|
+
"README.md": "Fix add in math.cjs. Start the application with bun run dev on port 3000.\n",
|
|
7
|
+
"math.cjs": "exports.add = (a, b) => a - b;\n"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"checks": [
|
|
11
|
+
{
|
|
12
|
+
"id": "addition",
|
|
13
|
+
"grader": "sevro.shell",
|
|
14
|
+
"configuration": {
|
|
15
|
+
"run": "{{evaluator-test}}",
|
|
16
|
+
"expectExact": "coding checks passed"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"requiredEvidence": []
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "recipe-host-tools",
|
|
3
|
+
"prompt": "Read app.env with rg, then explain the application's start command and port.",
|
|
4
|
+
"fixture": {
|
|
5
|
+
"files": {
|
|
6
|
+
"README.md": "Start with bun run dev on port 3000.\n",
|
|
7
|
+
"app.env": "port=3000\n"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"checks": [
|
|
11
|
+
{
|
|
12
|
+
"id": "rg-access",
|
|
13
|
+
"grader": "sevro.shell",
|
|
14
|
+
"configuration": {
|
|
15
|
+
"run": "rg '^port=3000$' app.env",
|
|
16
|
+
"expectExact": "port=3000"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"requiredEvidence": []
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "recipe-mise",
|
|
3
|
+
"prompt": "Use node from PATH to read app.json, then explain the application's start command and port. The operator has resolved mise's existing node@24.13.0 installation; do not download anything.",
|
|
4
|
+
"fixture": {
|
|
5
|
+
"files": {
|
|
6
|
+
"README.md": "Start with bun run dev on port 3000.\n",
|
|
7
|
+
"app.json": "{\"port\":3000}\n"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"checks": [
|
|
11
|
+
{
|
|
12
|
+
"id": "mise-node-access",
|
|
13
|
+
"grader": "sevro.shell",
|
|
14
|
+
"configuration": {
|
|
15
|
+
"run": "node -e 'if (process.version !== \"v24.13.0\") process.exit(1); const a = require(\"./app.json\"); if (a.port !== 3000) process.exit(1); console.log(a.port)'",
|
|
16
|
+
"expectExact": "3000"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"requiredEvidence": []
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "recipe-node",
|
|
3
|
+
"prompt": "Read app.json with Node and explain the application's start command and port.",
|
|
4
|
+
"fixture": {
|
|
5
|
+
"files": {
|
|
6
|
+
"README.md": "Start with bun run dev on port 3000.\n",
|
|
7
|
+
"app.json": "{\"port\":3000}\n"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"checks": [
|
|
11
|
+
{
|
|
12
|
+
"id": "node-access",
|
|
13
|
+
"grader": "sevro.shell",
|
|
14
|
+
"configuration": {
|
|
15
|
+
"run": "node -e 'const a = require(\"./app.json\"); if (a.port !== 3000) process.exit(1); console.log(a.port)'",
|
|
16
|
+
"expectExact": "3000"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"requiredEvidence": []
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "recipe-python-uv",
|
|
3
|
+
"prompt": "Use uv run --offline --no-project --python \"$RECIPE_PYTHON\" python to read app.json, then explain the application's start command and port.",
|
|
4
|
+
"fixture": {
|
|
5
|
+
"files": {
|
|
6
|
+
"README.md": "Start with bun run dev on port 3000.\n",
|
|
7
|
+
"app.json": "{\"port\":3000}\n"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"checks": [
|
|
11
|
+
{
|
|
12
|
+
"id": "uv-python-access",
|
|
13
|
+
"grader": "sevro.shell",
|
|
14
|
+
"configuration": {
|
|
15
|
+
"run": "uv run --offline --no-project --python \"$RECIPE_PYTHON\" python -c 'import json; p=json.load(open(\"app.json\"))[\"port\"]; assert p == 3000; print(p)'",
|
|
16
|
+
"expectExact": "3000"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"requiredEvidence": []
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "recipe-semantic",
|
|
3
|
+
"prompt": "Read README.md and explain how to start the application, including its port.",
|
|
4
|
+
"fixture": {
|
|
5
|
+
"files": { "README.md": "Start with bun run dev on port 3000.\n" }
|
|
6
|
+
},
|
|
7
|
+
"checks": [
|
|
8
|
+
{
|
|
9
|
+
"id": "startup-meaning",
|
|
10
|
+
"grader": "sevro.semantic",
|
|
11
|
+
"configuration": {
|
|
12
|
+
"proposition": "The response tells the reader to run bun run dev and says that the application listens on port 3000."
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"requiredEvidence": []
|
|
17
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
|
|
5
|
+
interface Addition {
|
|
6
|
+
add: (left: number, right: number) => number;
|
|
7
|
+
}
|
|
8
|
+
function isAddition(value: unknown): value is Addition {
|
|
9
|
+
return (
|
|
10
|
+
typeof value === "object" &&
|
|
11
|
+
value !== null &&
|
|
12
|
+
"add" in value &&
|
|
13
|
+
typeof value.add === "function"
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
const candidate: unknown = await import(
|
|
17
|
+
pathToFileURL(join(process.cwd(), "math.cjs")).href
|
|
18
|
+
);
|
|
19
|
+
assert.ok(isAddition(candidate), "Candidate must export add");
|
|
20
|
+
assert.equal(candidate.add(2, 3), 5);
|
|
21
|
+
assert.equal(candidate.add(-2, 3), 1);
|
|
22
|
+
assert.equal(candidate.add(0, 0), 0);
|
|
23
|
+
console.log("coding checks passed");
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
export function artifact(relativePath: string, content: string) {
|
|
6
|
+
return {
|
|
7
|
+
id: `recipes.${createHash("sha256").update(relativePath).digest("hex").slice(0, 16)}`,
|
|
8
|
+
relativePath,
|
|
9
|
+
sha256: createHash("sha256").update(content).digest("hex"),
|
|
10
|
+
contentBase64: Buffer.from(content).toString("base64"),
|
|
11
|
+
gitExclude: true,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function repositoryArtifacts(host: string) {
|
|
16
|
+
const directory = host === "claude" ? ".claude" : ".agents";
|
|
17
|
+
const relative = `${directory}/skills/startup-guide/SKILL.md`;
|
|
18
|
+
const body = await readFile(
|
|
19
|
+
join(import.meta.dir, "repository-skill", relative),
|
|
20
|
+
"utf8",
|
|
21
|
+
);
|
|
22
|
+
return [artifact(relative, body)];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function pluginArtifacts() {
|
|
26
|
+
const files = {
|
|
27
|
+
"marketplace/.claude-plugin/marketplace.json": JSON.stringify({
|
|
28
|
+
name: "recipes",
|
|
29
|
+
owner: { name: "Sevro examples" },
|
|
30
|
+
plugins: [
|
|
31
|
+
{ name: "startup", source: "./plugin", description: "Startup recipe" },
|
|
32
|
+
],
|
|
33
|
+
}),
|
|
34
|
+
"marketplace/plugin/.claude-plugin/plugin.json": JSON.stringify({
|
|
35
|
+
name: "startup",
|
|
36
|
+
version: "1.0.0",
|
|
37
|
+
}),
|
|
38
|
+
"marketplace/plugin/.codex-plugin/plugin.json": JSON.stringify({
|
|
39
|
+
name: "startup",
|
|
40
|
+
version: "1.0.0",
|
|
41
|
+
skills: "./skills/",
|
|
42
|
+
}),
|
|
43
|
+
"marketplace/plugin/skills/startup-guide/SKILL.md":
|
|
44
|
+
"---\nname: startup-guide\ndescription: Explain application startup.\n---\nRead README.md. Explain its command and port.\n",
|
|
45
|
+
"marketplace/plugin/hooks/hooks.json": JSON.stringify({
|
|
46
|
+
hooks: {
|
|
47
|
+
SessionStart: [
|
|
48
|
+
{
|
|
49
|
+
hooks: [
|
|
50
|
+
{
|
|
51
|
+
type: "command",
|
|
52
|
+
command: '/bin/sh "${CLAUDE_PLUGIN_ROOT}/hooks/start.sh"',
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
"marketplace/plugin/hooks/start.sh":
|
|
60
|
+
"#!/bin/sh\nprintf 'hook ran\\n' > \"$PWD/hook-ran.txt\"\n",
|
|
61
|
+
};
|
|
62
|
+
return Object.entries(files).map(([path, content]) =>
|
|
63
|
+
artifact(path, content),
|
|
64
|
+
);
|
|
65
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
artifact,
|
|
3
|
+
pluginArtifacts,
|
|
4
|
+
repositoryArtifacts,
|
|
5
|
+
} from "./extension-artifacts";
|
|
6
|
+
|
|
7
|
+
export function record(value: unknown): Record<string, unknown> {
|
|
8
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
9
|
+
throw new Error("Expected a JSON object");
|
|
10
|
+
return value as Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function describe(mode: string, host: string) {
|
|
14
|
+
const capabilities: Record<string, string[]> = {
|
|
15
|
+
lifecycle: [],
|
|
16
|
+
"repository-skill": [`sevro.${host}.repository-invocation`],
|
|
17
|
+
plugins:
|
|
18
|
+
host === "codex"
|
|
19
|
+
? ["sevro.codex.plugin-marketplace", "sevro.codex.explicit-invocation"]
|
|
20
|
+
: ["sevro.claude.plugin-dirs", "sevro.claude.explicit-invocation"],
|
|
21
|
+
};
|
|
22
|
+
const requiredCapabilities = capabilities[mode];
|
|
23
|
+
if (!requiredCapabilities) throw new Error("Unknown extension recipe");
|
|
24
|
+
return {
|
|
25
|
+
extension: { id: "recipes.startup", version: "1.0.0" },
|
|
26
|
+
protocols: ["sevro.extension.v1"],
|
|
27
|
+
requiredCapabilities,
|
|
28
|
+
optionalCapabilities: [],
|
|
29
|
+
graders: ["recipes.startup"],
|
|
30
|
+
taskVerdictPolicies: [],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function requiredInvocation(mode: string, host: string): string[] {
|
|
35
|
+
if (mode !== "repository-skill") return [];
|
|
36
|
+
return [
|
|
37
|
+
host === "codex"
|
|
38
|
+
? "sevro.codex.explicit-invocation"
|
|
39
|
+
: "sevro.claude.repository-invocation",
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function resolveCase(mode: string, host: string, fail: boolean) {
|
|
44
|
+
const invocation = mode === "lifecycle" ? "" : "{{sevro.skill_invocation}} ";
|
|
45
|
+
const prompt = fail
|
|
46
|
+
? "Deliberate negative control: return only wrong."
|
|
47
|
+
: "Read README.md. Explain the application's start command and port. Do not change files.";
|
|
48
|
+
const requiredEvidence = requiredInvocation(mode, host);
|
|
49
|
+
return {
|
|
50
|
+
cases: [
|
|
51
|
+
{
|
|
52
|
+
id: "recipe-extension",
|
|
53
|
+
prompt: invocation + prompt,
|
|
54
|
+
fixture: {
|
|
55
|
+
kind: "generated",
|
|
56
|
+
commits: [
|
|
57
|
+
{
|
|
58
|
+
message: "chore: initialize sample",
|
|
59
|
+
files: { "README.md": "Run bun run dev on port 3000.\n" },
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
checks: [
|
|
64
|
+
{
|
|
65
|
+
id: "startup-command",
|
|
66
|
+
grader: "sevro.regex",
|
|
67
|
+
configuration: { pattern: "bun run dev" },
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "prepared-input",
|
|
71
|
+
grader: "sevro.shell",
|
|
72
|
+
configuration: {
|
|
73
|
+
run: "test \"$(cat startup.txt)\" = 'prepared startup data'",
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
...(mode === "plugins"
|
|
77
|
+
? [
|
|
78
|
+
{
|
|
79
|
+
id: "plugin-hook",
|
|
80
|
+
grader: "sevro.shell",
|
|
81
|
+
configuration: {
|
|
82
|
+
run: "cat hook-ran.txt",
|
|
83
|
+
expectExact: "hook ran",
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
]
|
|
87
|
+
: []),
|
|
88
|
+
{
|
|
89
|
+
id: "recipes.startup.answer",
|
|
90
|
+
grader: "recipes.startup",
|
|
91
|
+
configuration: {},
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
requiredEvidence,
|
|
95
|
+
extensionData: { "recipes.startup": { mode, host } },
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export async function prepare(mode: string, host: string) {
|
|
102
|
+
const base = {
|
|
103
|
+
artifacts: [artifact("startup.txt", "prepared startup data\n")],
|
|
104
|
+
requestedInstrumentation: [],
|
|
105
|
+
extensionData: { "recipes.startup": { mode, host } },
|
|
106
|
+
};
|
|
107
|
+
switch (mode) {
|
|
108
|
+
case "repository-skill":
|
|
109
|
+
return {
|
|
110
|
+
...base,
|
|
111
|
+
artifacts: [...base.artifacts, ...(await repositoryArtifacts(host))],
|
|
112
|
+
...(host === "codex"
|
|
113
|
+
? { codexRepositorySkillInvocation: { skillName: "startup-guide" } }
|
|
114
|
+
: {
|
|
115
|
+
claudeRepositorySkillInvocation: { skillName: "startup-guide" },
|
|
116
|
+
}),
|
|
117
|
+
};
|
|
118
|
+
case "plugins":
|
|
119
|
+
return {
|
|
120
|
+
...base,
|
|
121
|
+
artifacts: [...base.artifacts, ...pluginArtifacts()],
|
|
122
|
+
...(host === "codex"
|
|
123
|
+
? {
|
|
124
|
+
codexMarketplace: {
|
|
125
|
+
artifactRoot: "marketplace",
|
|
126
|
+
marketplaceName: "recipes",
|
|
127
|
+
pluginNames: ["startup"],
|
|
128
|
+
},
|
|
129
|
+
codexSkillInvocation: {
|
|
130
|
+
pluginName: "startup",
|
|
131
|
+
skillName: "startup-guide",
|
|
132
|
+
},
|
|
133
|
+
}
|
|
134
|
+
: {
|
|
135
|
+
claudePluginDirs: { artifactRoots: ["marketplace/plugin"] },
|
|
136
|
+
claudeSkillInvocation: {
|
|
137
|
+
pluginName: "startup",
|
|
138
|
+
skillName: "startup-guide",
|
|
139
|
+
},
|
|
140
|
+
}),
|
|
141
|
+
};
|
|
142
|
+
default:
|
|
143
|
+
return base;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function answerStatus(observation: Record<string, unknown>) {
|
|
148
|
+
if (observation.completeness !== "complete") return "unavailable";
|
|
149
|
+
const text = record(observation.data).text;
|
|
150
|
+
return typeof text === "string" && /\b3000\b/.test(text)
|
|
151
|
+
? "passed"
|
|
152
|
+
: "failed";
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function evaluate(params: Record<string, unknown>) {
|
|
156
|
+
if (!Array.isArray(params.observations))
|
|
157
|
+
throw new Error("Missing observations");
|
|
158
|
+
const observations: unknown[] = params.observations;
|
|
159
|
+
const observation = observations
|
|
160
|
+
.map(record)
|
|
161
|
+
.find((item) => item.id === "sevro.observation.final-message");
|
|
162
|
+
if (!observation) throw new Error("Missing final-message observation");
|
|
163
|
+
const status = answerStatus(observation);
|
|
164
|
+
return {
|
|
165
|
+
checks: [
|
|
166
|
+
{
|
|
167
|
+
id: "recipes.startup.answer",
|
|
168
|
+
status,
|
|
169
|
+
evidenceRefs: ["sevro.observation.final-message"],
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
metrics: [],
|
|
173
|
+
};
|
|
174
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
describe,
|
|
3
|
+
evaluate,
|
|
4
|
+
prepare,
|
|
5
|
+
record,
|
|
6
|
+
resolveCase,
|
|
7
|
+
} from "./extension-methods";
|
|
8
|
+
|
|
9
|
+
const mode = process.argv[2] ?? "lifecycle";
|
|
10
|
+
const host = process.argv[3] ?? "deterministic";
|
|
11
|
+
const fail = process.argv[4] === "fail";
|
|
12
|
+
const request = record(JSON.parse(await Bun.stdin.text()) as unknown);
|
|
13
|
+
|
|
14
|
+
async function result() {
|
|
15
|
+
switch (request.method) {
|
|
16
|
+
case "describe":
|
|
17
|
+
return describe(mode, host);
|
|
18
|
+
case "resolve":
|
|
19
|
+
return resolveCase(mode, host, fail);
|
|
20
|
+
case "prepare":
|
|
21
|
+
return await prepare(mode, host);
|
|
22
|
+
case "evaluate":
|
|
23
|
+
return evaluate(record(request.params));
|
|
24
|
+
default:
|
|
25
|
+
throw new Error("Unsupported extension method");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// One request per process; stdout contains only the matching protocol response.
|
|
30
|
+
process.stdout.write(
|
|
31
|
+
JSON.stringify({
|
|
32
|
+
protocol: request.protocol,
|
|
33
|
+
id: request.id,
|
|
34
|
+
method: request.method,
|
|
35
|
+
result: await result(),
|
|
36
|
+
}),
|
|
37
|
+
);
|