@bjoernrochel/sevro 0.1.0-rc.8 → 1.1.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 +52 -6
- package/README.md +12 -7
- package/dist/examples/basic/graded.json +13 -0
- package/dist/examples/basic/host.js +9 -0
- package/dist/examples/basic/host.js.map +1 -0
- package/dist/examples/basic/prompt-only.json +7 -0
- package/dist/examples/recipes/candidate.js +23 -0
- package/dist/examples/recipes/candidate.js.map +1 -0
- package/dist/examples/recipes/cases/coding-change.json +21 -0
- package/dist/examples/recipes/cases/host-tools.json +21 -0
- package/dist/examples/recipes/cases/mise.json +21 -0
- package/dist/examples/recipes/cases/node.json +21 -0
- package/dist/examples/recipes/cases/python-uv.json +21 -0
- package/dist/examples/recipes/cases/semantic.json +17 -0
- package/dist/examples/recipes/coding-change/check.js +16 -0
- package/dist/examples/recipes/coding-change/check.js.map +1 -0
- package/dist/examples/recipes/executable.js +20 -0
- package/dist/examples/recipes/executable.js.map +1 -0
- package/dist/examples/recipes/extension-artifacts.js +56 -0
- package/dist/examples/recipes/extension-artifacts.js.map +1 -0
- package/dist/examples/recipes/extension-methods.js +167 -0
- package/dist/examples/recipes/extension-methods.js.map +1 -0
- package/dist/examples/recipes/extension.js +28 -0
- package/dist/examples/recipes/extension.js.map +1 -0
- package/dist/examples/recipes/modules.js +9 -0
- package/dist/examples/recipes/modules.js.map +1 -0
- package/dist/examples/recipes/repository-skill/.agents/skills/startup-guide/SKILL.md +7 -0
- package/dist/examples/recipes/repository-skill/.claude/skills/startup-guide/SKILL.md +7 -0
- package/dist/examples/recipes/repository-skill/README.md +3 -0
- package/dist/examples/recipes/run-inputs.js +144 -0
- package/dist/examples/recipes/run-inputs.js.map +1 -0
- package/dist/examples/recipes/run-options.js +103 -0
- package/dist/examples/recipes/run-options.js.map +1 -0
- package/dist/examples/recipes/run.js +62 -0
- package/dist/examples/recipes/run.js.map +1 -0
- package/dist/examples/recipes/runtime/empty.json +1 -0
- package/dist/examples/recipes/runtime/goals.json +1 -0
- package/dist/examples/recipes/runtime/mise.json +6 -0
- package/dist/examples/recipes/runtime/path.json +1 -0
- package/dist/examples/recipes/runtime/plugins.json +4 -0
- package/dist/examples/recipes/runtime/python-uv.json +10 -0
- package/dist/examples/recipes/semantic-judge.js +27 -0
- package/dist/examples/recipes/semantic-judge.js.map +1 -0
- package/dist/examples/templates/coding/adapter.js +14 -0
- package/dist/examples/templates/coding/adapter.js.map +1 -0
- package/dist/examples/templates/coding/case.json +15 -0
- package/dist/examples/templates/repository-skill/.agents/skills/startup-guide/SKILL.md +6 -0
- package/dist/examples/templates/repository-skill/extension-data.js +61 -0
- package/dist/examples/templates/repository-skill/extension-data.js.map +1 -0
- package/dist/examples/templates/repository-skill/extension.js +29 -0
- package/dist/examples/templates/repository-skill/extension.js.map +1 -0
- package/dist/examples/templates/response/adapter.js +13 -0
- package/dist/examples/templates/response/adapter.js.map +1 -0
- package/dist/examples/templates/response/case.json +13 -0
- package/dist/src/advisory.js +86 -0
- package/dist/src/advisory.js.map +1 -0
- package/dist/src/candidate-artifacts.js +139 -0
- package/dist/src/candidate-artifacts.js.map +1 -0
- package/dist/src/candidate-codex-state.js +110 -0
- package/dist/src/candidate-codex-state.js.map +1 -0
- package/dist/src/case-validation.js +92 -0
- package/dist/src/case-validation.js.map +1 -0
- package/dist/src/cli/cancellation.js +21 -0
- package/dist/src/cli/cancellation.js.map +1 -0
- package/dist/src/cli/command.js +60 -0
- package/dist/src/cli/command.js.map +1 -0
- package/dist/src/cli/completion.js +14 -0
- package/dist/src/cli/completion.js.map +1 -0
- package/dist/src/cli/demo.js +45 -0
- package/dist/src/cli/demo.js.map +1 -0
- package/dist/src/cli/evaluation.js +40 -0
- package/dist/src/cli/evaluation.js.map +1 -0
- package/dist/src/cli/extension.js +54 -0
- package/dist/src/cli/extension.js.map +1 -0
- package/dist/src/cli/help.js +190 -0
- package/dist/src/cli/help.js.map +1 -0
- package/dist/src/cli/hosts.js +33 -0
- package/dist/src/cli/hosts.js.map +1 -0
- package/dist/src/cli/init-settings.js +29 -0
- package/dist/src/cli/init-settings.js.map +1 -0
- package/dist/src/cli/init.js +82 -0
- package/dist/src/cli/init.js.map +1 -0
- package/dist/src/cli/invocation.js +431 -0
- package/dist/src/cli/invocation.js.map +1 -0
- package/dist/src/cli/loading.js +110 -0
- package/dist/src/cli/loading.js.map +1 -0
- package/dist/src/cli/preparation.js +88 -0
- package/dist/src/cli/preparation.js.map +1 -0
- package/dist/src/cli/presentation.js +61 -0
- package/dist/src/cli/presentation.js.map +1 -0
- package/dist/src/cli/progress.js +5 -0
- package/dist/src/cli/progress.js.map +1 -0
- package/dist/src/cli/run-manifest.js +108 -0
- package/dist/src/cli/run-manifest.js.map +1 -0
- package/dist/src/cli/run-options.js +367 -0
- package/dist/src/cli/run-options.js.map +1 -0
- package/dist/src/cli/run-overrides.js +51 -0
- package/dist/src/cli/run-overrides.js.map +1 -0
- package/dist/src/cli/settings.js +127 -0
- package/dist/src/cli/settings.js.map +1 -0
- package/dist/src/cli/summary.js +28 -0
- package/dist/src/cli/summary.js.map +1 -0
- package/dist/src/cli.js +20 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/contract-types.js +2 -0
- package/dist/src/contract-types.js.map +1 -0
- package/dist/src/engine.js +4 -0
- package/dist/src/engine.js.map +1 -0
- package/dist/src/evaluation/advisory.js +85 -0
- package/dist/src/evaluation/advisory.js.map +1 -0
- package/dist/src/evaluation/check-plan.js +292 -0
- package/dist/src/evaluation/check-plan.js.map +1 -0
- package/dist/src/evaluation/collection.js +61 -0
- package/dist/src/evaluation/collection.js.map +1 -0
- package/dist/src/evaluation/context.js +2 -0
- package/dist/src/evaluation/context.js.map +1 -0
- package/dist/src/evaluation/grading-host.js +28 -0
- package/dist/src/evaluation/grading-host.js.map +1 -0
- package/dist/src/evaluation/grading.js +154 -0
- package/dist/src/evaluation/grading.js.map +1 -0
- package/dist/src/evaluation/invocation-plan.js +312 -0
- package/dist/src/evaluation/invocation-plan.js.map +1 -0
- package/dist/src/evaluation/plan.js +376 -0
- package/dist/src/evaluation/plan.js.map +1 -0
- package/dist/src/evaluation/progress.js +14 -0
- package/dist/src/evaluation/progress.js.map +1 -0
- package/dist/src/evaluation/resources.js +159 -0
- package/dist/src/evaluation/resources.js.map +1 -0
- package/dist/src/evaluation/run.js +148 -0
- package/dist/src/evaluation/run.js.map +1 -0
- package/dist/src/evaluation/scheduler.js +27 -0
- package/dist/src/evaluation/scheduler.js.map +1 -0
- package/dist/src/evaluation/semantic.js +183 -0
- package/dist/src/evaluation/semantic.js.map +1 -0
- package/dist/src/evaluation/trial.js +593 -0
- package/dist/src/evaluation/trial.js.map +1 -0
- package/dist/src/evaluation/types.js +20 -0
- package/dist/src/evaluation/types.js.map +1 -0
- package/dist/src/evidence/host-results.js +67 -0
- package/dist/src/evidence/host-results.js.map +1 -0
- package/dist/src/evidence/retained-artifacts.js +17 -0
- package/dist/src/evidence/retained-artifacts.js.map +1 -0
- package/dist/src/evidence/trial-writer.js +131 -0
- package/dist/src/evidence/trial-writer.js.map +1 -0
- package/dist/src/evidence/usage.js +14 -0
- package/dist/src/evidence/usage.js.map +1 -0
- package/dist/src/executable.js +20 -0
- package/dist/src/executable.js.map +1 -0
- package/dist/src/extension-client.js +212 -0
- package/dist/src/extension-client.js.map +1 -0
- package/dist/src/extension-session.js +236 -0
- package/dist/src/extension-session.js.map +1 -0
- package/dist/src/fixtures/advisory.js +206 -0
- package/dist/src/fixtures/advisory.js.map +1 -0
- package/dist/src/fixtures/bin.js +41 -0
- package/dist/src/fixtures/bin.js.map +1 -0
- package/dist/src/fixtures/cleanup.js +43 -0
- package/dist/src/fixtures/cleanup.js.map +1 -0
- package/dist/src/fixtures/create.js +94 -0
- package/dist/src/fixtures/create.js.map +1 -0
- package/dist/src/fixtures/generated.js +181 -0
- package/dist/src/fixtures/generated.js.map +1 -0
- package/dist/src/fixtures/git-hooks.js +16 -0
- package/dist/src/fixtures/git-hooks.js.map +1 -0
- package/dist/src/fixtures/preparation.js +201 -0
- package/dist/src/fixtures/preparation.js.map +1 -0
- package/dist/src/fixtures/repository.js +255 -0
- package/dist/src/fixtures/repository.js.map +1 -0
- package/dist/src/fixtures/setup.js +175 -0
- package/dist/src/fixtures/setup.js.map +1 -0
- package/dist/src/fixtures/tools.js +57 -0
- package/dist/src/fixtures/tools.js.map +1 -0
- package/dist/src/fixtures/workspace-state.js +155 -0
- package/dist/src/fixtures/workspace-state.js.map +1 -0
- package/dist/src/generated/cli-result.cjs +2 -0
- package/dist/src/generated/extension.cjs +2 -0
- package/dist/src/generated/report.cjs +2 -0
- package/dist/src/generated/run-evidence.cjs +2 -0
- package/dist/src/generated/runtime.cjs +2 -0
- package/dist/src/git.js +72 -0
- package/dist/src/git.js.map +1 -0
- package/dist/src/graders/artifact.js +68 -0
- package/dist/src/graders/artifact.js.map +1 -0
- package/dist/src/graders/git-head.js +112 -0
- package/dist/src/graders/git-head.js.map +1 -0
- package/dist/src/graders/output.js +345 -0
- package/dist/src/graders/output.js.map +1 -0
- package/dist/src/graders/semantic.js +132 -0
- package/dist/src/graders/semantic.js.map +1 -0
- package/dist/src/graders/shell.js +321 -0
- package/dist/src/graders/shell.js.map +1 -0
- package/dist/src/host-diagnostic-redaction.js +52 -0
- package/dist/src/host-diagnostic-redaction.js.map +1 -0
- package/dist/src/host-diagnostics.js +248 -0
- package/dist/src/host-diagnostics.js.map +1 -0
- package/dist/src/hosts/claude-continuation.js +89 -0
- package/dist/src/hosts/claude-continuation.js.map +1 -0
- package/dist/src/hosts/claude-credential.js +121 -0
- package/dist/src/hosts/claude-credential.js.map +1 -0
- package/dist/src/hosts/claude-events.js +136 -0
- package/dist/src/hosts/claude-events.js.map +1 -0
- package/dist/src/hosts/claude-keychain.js +100 -0
- package/dist/src/hosts/claude-keychain.js.map +1 -0
- package/dist/src/hosts/claude-login-recovery.js +67 -0
- package/dist/src/hosts/claude-login-recovery.js.map +1 -0
- package/dist/src/hosts/claude-login-refresh.js +146 -0
- package/dist/src/hosts/claude-login-refresh.js.map +1 -0
- package/dist/src/hosts/claude-login-store.js +124 -0
- package/dist/src/hosts/claude-login-store.js.map +1 -0
- package/dist/src/hosts/claude-login.js +74 -0
- package/dist/src/hosts/claude-login.js.map +1 -0
- package/dist/src/hosts/claude-native-goal.js +138 -0
- package/dist/src/hosts/claude-native-goal.js.map +1 -0
- package/dist/src/hosts/claude-process.js +10 -0
- package/dist/src/hosts/claude-process.js.map +1 -0
- package/dist/src/hosts/claude-refresh-lock.js +76 -0
- package/dist/src/hosts/claude-refresh-lock.js.map +1 -0
- package/dist/src/hosts/claude-repository-invocation.js +229 -0
- package/dist/src/hosts/claude-repository-invocation.js.map +1 -0
- package/dist/src/hosts/claude-settings.js +156 -0
- package/dist/src/hosts/claude-settings.js.map +1 -0
- package/dist/src/hosts/claude-skill-activations.js +131 -0
- package/dist/src/hosts/claude-skill-activations.js.map +1 -0
- package/dist/src/hosts/claude-state.js +237 -0
- package/dist/src/hosts/claude-state.js.map +1 -0
- package/dist/src/hosts/claude-tool-calls.js +150 -0
- package/dist/src/hosts/claude-tool-calls.js.map +1 -0
- package/dist/src/hosts/claude.js +373 -0
- package/dist/src/hosts/claude.js.map +1 -0
- package/dist/src/hosts/codex-app-server.js +764 -0
- package/dist/src/hosts/codex-app-server.js.map +1 -0
- package/dist/src/hosts/codex-configuration.js +91 -0
- package/dist/src/hosts/codex-configuration.js.map +1 -0
- package/dist/src/hosts/codex-events.js +104 -0
- package/dist/src/hosts/codex-events.js.map +1 -0
- package/dist/src/hosts/codex-exec-controls.js +434 -0
- package/dist/src/hosts/codex-exec-controls.js.map +1 -0
- package/dist/src/hosts/codex-invocation.js +54 -0
- package/dist/src/hosts/codex-invocation.js.map +1 -0
- package/dist/src/hosts/codex-marketplace.js +185 -0
- package/dist/src/hosts/codex-marketplace.js.map +1 -0
- package/dist/src/hosts/codex-native-calls.js +516 -0
- package/dist/src/hosts/codex-native-calls.js.map +1 -0
- package/dist/src/hosts/codex-process.js +10 -0
- package/dist/src/hosts/codex-process.js.map +1 -0
- package/dist/src/hosts/codex-profile.js +206 -0
- package/dist/src/hosts/codex-profile.js.map +1 -0
- package/dist/src/hosts/codex-session-files.js +89 -0
- package/dist/src/hosts/codex-session-files.js.map +1 -0
- package/dist/src/hosts/codex-state.js +310 -0
- package/dist/src/hosts/codex-state.js.map +1 -0
- package/dist/src/hosts/codex.js +527 -0
- package/dist/src/hosts/codex.js.map +1 -0
- package/dist/src/hosts/isolation-common.js +43 -0
- package/dist/src/hosts/isolation-common.js.map +1 -0
- package/dist/src/hosts/isolation-roots.js +64 -0
- package/dist/src/hosts/isolation-roots.js.map +1 -0
- package/dist/src/hosts/isolation.js +12 -0
- package/dist/src/hosts/isolation.js.map +1 -0
- package/dist/src/hosts/linux-sandbox.js +127 -0
- package/dist/src/hosts/linux-sandbox.js.map +1 -0
- package/dist/src/hosts/mac-sandbox.js +137 -0
- package/dist/src/hosts/mac-sandbox.js.map +1 -0
- package/dist/src/hosts/native-controls.js +151 -0
- package/dist/src/hosts/native-controls.js.map +1 -0
- package/dist/src/hosts/native-request.js +33 -0
- package/dist/src/hosts/native-request.js.map +1 -0
- package/dist/src/hosts/process-lifecycle.js +167 -0
- package/dist/src/hosts/process-lifecycle.js.map +1 -0
- package/dist/src/hosts/protected-worktrees.js +81 -0
- package/dist/src/hosts/protected-worktrees.js.map +1 -0
- package/dist/src/hosts/skill-hook-catalog.js +100 -0
- package/dist/src/hosts/skill-hook-catalog.js.map +1 -0
- package/dist/src/hosts/skill-hook-handler.js +228 -0
- package/dist/src/hosts/skill-hook-handler.js.map +1 -0
- package/dist/src/hosts/skill-hooks.js +423 -0
- package/dist/src/hosts/skill-hooks.js.map +1 -0
- package/dist/src/hosts/workspace-fingerprint.js +72 -0
- package/dist/src/hosts/workspace-fingerprint.js.map +1 -0
- package/dist/src/identity.js +167 -0
- package/dist/src/identity.js.map +1 -0
- package/dist/src/instrumentation.js +83 -0
- package/dist/src/instrumentation.js.map +1 -0
- package/dist/src/native-transcript-state.js +85 -0
- package/dist/src/native-transcript-state.js.map +1 -0
- package/dist/src/native-transcript-view.js +65 -0
- package/dist/src/native-transcript-view.js.map +1 -0
- package/dist/src/native-transcripts.js +208 -0
- package/dist/src/native-transcripts.js.map +1 -0
- package/dist/src/paths.js +13 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/process-lifecycle.js +101 -0
- package/dist/src/process-lifecycle.js.map +1 -0
- package/dist/src/provenance.js +263 -0
- package/dist/src/provenance.js.map +1 -0
- package/dist/src/prune.js +228 -0
- package/dist/src/prune.js.map +1 -0
- package/dist/src/report.js +276 -0
- package/dist/src/report.js.map +1 -0
- package/dist/src/resolved-case.js +29 -0
- package/dist/src/resolved-case.js.map +1 -0
- package/dist/src/results-lock.js +40 -0
- package/dist/src/results-lock.js.map +1 -0
- package/dist/src/results.js +127 -0
- package/dist/src/results.js.map +1 -0
- package/dist/src/run-owner.js +283 -0
- package/dist/src/run-owner.js.map +1 -0
- package/dist/src/runner-paths.js +11 -0
- package/dist/src/runner-paths.js.map +1 -0
- package/dist/src/runtime/config.js +323 -0
- package/dist/src/runtime/config.js.map +1 -0
- package/dist/src/runtime/discovery-apple.js +65 -0
- package/dist/src/runtime/discovery-apple.js.map +1 -0
- package/dist/src/runtime/discovery-providers.js +37 -0
- package/dist/src/runtime/discovery-providers.js.map +1 -0
- package/dist/src/runtime/discovery.js +40 -0
- package/dist/src/runtime/discovery.js.map +1 -0
- package/dist/src/runtime/hook-processes.js +81 -0
- package/dist/src/runtime/hook-processes.js.map +1 -0
- package/dist/src/runtime/hooks.js +304 -0
- package/dist/src/runtime/hooks.js.map +1 -0
- package/dist/src/runtime/paths.js +244 -0
- package/dist/src/runtime/paths.js.map +1 -0
- package/dist/src/runtime/query.js +76 -0
- package/dist/src/runtime/query.js.map +1 -0
- package/dist/src/runtime/seeds.js +98 -0
- package/dist/src/runtime/seeds.js.map +1 -0
- package/dist/src/runtime/shared-cache.js +81 -0
- package/dist/src/runtime/shared-cache.js.map +1 -0
- package/dist/src/runtime/state.js +106 -0
- package/dist/src/runtime/state.js.map +1 -0
- package/dist/src/runtime-process.js +148 -0
- package/dist/src/runtime-process.js.map +1 -0
- package/dist/src/schema-types.js +2 -0
- package/dist/src/schema-types.js.map +1 -0
- package/dist/src/schema.js +16 -0
- package/dist/src/schema.js.map +1 -0
- package/dist/src/shell.js +5 -0
- package/dist/src/shell.js.map +1 -0
- package/dist/src/sqlite-lock.js +18 -0
- package/dist/src/sqlite-lock.js.map +1 -0
- package/dist/src/storage.js +21 -0
- package/dist/src/storage.js.map +1 -0
- package/dist/src/transcript-retention.js +109 -0
- package/dist/src/transcript-retention.js.map +1 -0
- package/dist/src/value-guards.js +26 -0
- package/dist/src/value-guards.js.map +1 -0
- package/docs/README.md +19 -15
- package/docs/architecture.md +141 -17
- package/docs/assets/README.md +5 -4
- package/docs/builtin-graders-v1.md +9 -2
- package/docs/codex-host.md +155 -57
- package/docs/contracts.md +2 -1
- package/docs/creating-cases.md +10 -4
- package/docs/development-cli.md +197 -24
- package/docs/documentation-quality.md +16 -5
- package/docs/evaluation-workflow.md +110 -0
- package/docs/extension-protocol-v1.md +26 -3
- package/docs/getting-started.md +29 -7
- package/docs/guide-evaluation.md +34 -2
- package/docs/identity-v1.md +29 -3
- package/docs/installing.md +35 -17
- package/docs/licensing.md +2 -2
- package/docs/native-controls.md +76 -5
- package/docs/native-hosts.md +197 -8
- package/docs/reading-results.md +102 -0
- package/docs/recipes.md +490 -0
- package/docs/releases.md +48 -13
- package/docs/report-v1.md +29 -1
- package/docs/results-v1.md +122 -4
- package/docs/run-settings-v1.md +147 -0
- package/docs/runtime-v1.md +255 -22
- package/docs/specs/repository-guide.md +1 -1
- package/docs/troubleshooting.md +12 -12
- package/docs/typescript-quality.md +106 -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/executable.ts +19 -0
- package/examples/recipes/extension-artifacts.ts +65 -0
- package/examples/recipes/extension-methods.ts +174 -0
- package/examples/recipes/extension.ts +38 -0
- package/examples/recipes/modules.ts +9 -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 +183 -0
- package/examples/recipes/run-options.ts +132 -0
- package/examples/recipes/run.ts +77 -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 +32 -0
- package/examples/templates/response/adapter.ts +12 -0
- package/examples/templates/response/case.json +13 -0
- package/package.json +23 -9
- package/schemas/report-v1.schema.json +9 -0
- package/schemas/run-evidence-v1.schema.json +2 -1
- package/schemas/runtime-v1.schema.json +43 -7
- package/src/advisory.ts +2 -2
- package/src/candidate-artifacts.ts +42 -11
- 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 +61 -0
- package/src/cli/evaluation.ts +55 -0
- package/src/cli/extension.ts +79 -0
- package/src/cli/help.ts +199 -0
- package/src/cli/hosts.ts +55 -0
- package/src/cli/init-settings.ts +31 -0
- package/src/cli/init.ts +112 -0
- package/src/{cli-invocation.ts → cli/invocation.ts} +215 -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 +14 -592
- package/src/contract-types.ts +94 -0
- package/src/engine.ts +9 -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} +77 -87
- package/src/evaluation/trial.ts +800 -0
- package/src/{evaluation-types.ts → evaluation/types.ts} +79 -29
- 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/executable.ts +19 -0
- package/src/extension-client.ts +40 -108
- package/src/extension-session.ts +24 -48
- package/src/{advisory-fixture.ts → fixtures/advisory.ts} +12 -72
- 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} +36 -53
- package/src/{fixture-tools.ts → fixtures/tools.ts} +1 -1
- package/src/{workspace-state.ts → fixtures/workspace-state.ts} +5 -5
- 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 +94 -0
- package/src/graders/git-head.ts +31 -85
- package/src/graders/shell.ts +54 -71
- 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 +79 -21
- package/src/hosts/claude-login-recovery.ts +85 -0
- package/src/hosts/claude-login-refresh.ts +179 -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 +82 -0
- package/src/hosts/claude-repository-invocation.ts +9 -34
- package/src/hosts/claude-settings.ts +46 -9
- package/src/hosts/claude-skill-activations.ts +169 -0
- package/src/hosts/claude-state.ts +28 -15
- package/src/hosts/claude-tool-calls.ts +13 -10
- package/src/hosts/claude.ts +121 -81
- 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 -183
- package/src/hosts/codex-profile.ts +36 -21
- package/src/hosts/codex-session-files.ts +1 -9
- package/src/hosts/codex-state.ts +134 -18
- package/src/hosts/codex.ts +210 -183
- package/src/hosts/isolation-common.ts +8 -11
- package/src/hosts/isolation-roots.ts +5 -4
- package/src/hosts/linux-sandbox.ts +15 -2
- package/src/hosts/mac-sandbox.ts +87 -18
- package/src/hosts/native-controls.ts +72 -22
- package/src/hosts/native-request.ts +55 -0
- package/src/hosts/process-lifecycle.ts +215 -49
- package/src/hosts/protected-worktrees.ts +3 -2
- package/src/hosts/skill-hook-catalog.ts +131 -0
- package/src/hosts/skill-hook-handler.ts +374 -0
- package/src/hosts/skill-hooks.ts +585 -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 +26 -11
- package/src/paths.ts +22 -0
- package/src/process-lifecycle.ts +150 -0
- package/src/provenance.ts +34 -13
- 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 +15 -9
- package/src/runner-paths.ts +21 -0
- package/src/{runtime-config.ts → runtime/config.ts} +160 -46
- 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} +3 -2
- package/src/{runtime-hooks.ts → runtime/hooks.ts} +40 -28
- package/src/{runtime-paths.ts → runtime/paths.ts} +5 -19
- 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/runtime-process.ts +194 -0
- package/src/schema-types.ts +73 -161
- package/src/shell.ts +4 -0
- package/src/sqlite-lock.ts +25 -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 -73
- package/docs/guide-verification.json +0 -239
- package/src/evaluation-context.ts +0 -259
- package/src/evaluation-fixture.ts +0 -302
- package/src/evaluation-run.ts +0 -200
- package/src/evaluation-trial.ts +0 -1016
- 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 -783
- /package/src/{trial-scheduler.ts → evaluation/scheduler.ts} +0 -0
package/src/extension-client.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import { spawn, type Subprocess } from "./runtime-process";
|
|
1
2
|
import { randomUUID } from "node:crypto";
|
|
2
3
|
import validExchange from "./generated/extension.cjs";
|
|
3
4
|
import { isRecord, isStringArray } from "./value-guards";
|
|
5
|
+
import {
|
|
6
|
+
captureBoundedBytes,
|
|
7
|
+
ProcessDeadline,
|
|
8
|
+
terminateOwnedProcessGroup,
|
|
9
|
+
} from "./process-lifecycle";
|
|
4
10
|
|
|
5
11
|
const MAX_MESSAGE_BYTES = 8 * 1024 * 1024;
|
|
6
12
|
const MAX_DIAGNOSTIC_BYTES = 64 * 1024;
|
|
@@ -35,61 +41,6 @@ export interface ExchangeOptions {
|
|
|
35
41
|
signal?: AbortSignal;
|
|
36
42
|
}
|
|
37
43
|
|
|
38
|
-
function boundedChunk(
|
|
39
|
-
value: Uint8Array,
|
|
40
|
-
size: number,
|
|
41
|
-
limit: number,
|
|
42
|
-
truncate: boolean,
|
|
43
|
-
): Uint8Array {
|
|
44
|
-
if (!truncate && size + value.byteLength > limit)
|
|
45
|
-
throw new ExtensionProtocolError("extension message exceeds 8 MiB");
|
|
46
|
-
return value.subarray(0, Math.max(0, limit - size));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async function readBounded(
|
|
50
|
-
stream: ReadableStream<Uint8Array>,
|
|
51
|
-
limit: number,
|
|
52
|
-
truncate: boolean,
|
|
53
|
-
): Promise<Uint8Array> {
|
|
54
|
-
const reader = stream.getReader();
|
|
55
|
-
const chunks: Uint8Array[] = [];
|
|
56
|
-
let size = 0;
|
|
57
|
-
for (;;) {
|
|
58
|
-
const { value, done } = await reader.read();
|
|
59
|
-
if (done) break;
|
|
60
|
-
const kept = boundedChunk(value, size, limit, truncate);
|
|
61
|
-
if (kept.byteLength) chunks.push(kept);
|
|
62
|
-
size += kept.byteLength;
|
|
63
|
-
}
|
|
64
|
-
return concatenateChunks(chunks, size);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function concatenateChunks(chunks: Uint8Array[], size: number): Uint8Array {
|
|
68
|
-
const result = new Uint8Array(size);
|
|
69
|
-
let offset = 0;
|
|
70
|
-
for (const chunk of chunks) {
|
|
71
|
-
result.set(chunk, offset);
|
|
72
|
-
offset += chunk.byteLength;
|
|
73
|
-
}
|
|
74
|
-
return result;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function terminate(proc: Bun.Subprocess): void {
|
|
78
|
-
if (process.platform !== "win32") {
|
|
79
|
-
try {
|
|
80
|
-
process.kill(-proc.pid, "SIGKILL");
|
|
81
|
-
return;
|
|
82
|
-
} catch {
|
|
83
|
-
// The group may have exited while the runner was handling the error.
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
try {
|
|
87
|
-
proc.kill("SIGKILL");
|
|
88
|
-
} catch {
|
|
89
|
-
// The process already exited.
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
44
|
interface SuccessfulExtensionResponse extends ExtensionResponse {
|
|
94
45
|
result: Record<string, unknown>;
|
|
95
46
|
error?: never;
|
|
@@ -121,9 +72,9 @@ function extensionPayload(request: ExtensionRequest): Uint8Array {
|
|
|
121
72
|
function spawnExtension(
|
|
122
73
|
command: string[],
|
|
123
74
|
options: ExchangeOptions,
|
|
124
|
-
):
|
|
75
|
+
): Subprocess {
|
|
125
76
|
try {
|
|
126
|
-
return
|
|
77
|
+
return spawn(command, {
|
|
127
78
|
cwd: options.cwd,
|
|
128
79
|
stdin: "pipe",
|
|
129
80
|
stdout: "pipe",
|
|
@@ -137,22 +88,15 @@ function spawnExtension(
|
|
|
137
88
|
}
|
|
138
89
|
}
|
|
139
90
|
|
|
140
|
-
function extensionWriter(proc:
|
|
91
|
+
function extensionWriter(proc: Subprocess) {
|
|
141
92
|
const stdin = proc.stdin;
|
|
142
93
|
if (!stdin || typeof stdin === "number")
|
|
143
94
|
throw new ExtensionProtocolError("extension pipes are unavailable");
|
|
144
95
|
return stdin;
|
|
145
96
|
}
|
|
146
97
|
|
|
147
|
-
function extensionReaders(proc:
|
|
98
|
+
function extensionReaders(proc: Subprocess) {
|
|
148
99
|
const { stdout, stderr } = proc;
|
|
149
|
-
if (
|
|
150
|
-
!stdout ||
|
|
151
|
-
typeof stdout === "number" ||
|
|
152
|
-
!stderr ||
|
|
153
|
-
typeof stderr === "number"
|
|
154
|
-
)
|
|
155
|
-
throw new ExtensionProtocolError("extension pipes are unavailable");
|
|
156
100
|
return { stdout, stderr };
|
|
157
101
|
}
|
|
158
102
|
|
|
@@ -217,13 +161,23 @@ function assertSuccessfulResponse(
|
|
|
217
161
|
}
|
|
218
162
|
|
|
219
163
|
class ExtensionExchange {
|
|
220
|
-
private
|
|
221
|
-
private cancel: (() => void) | undefined;
|
|
164
|
+
private readonly deadline: ProcessDeadline;
|
|
222
165
|
constructor(
|
|
223
|
-
private readonly proc:
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
) {
|
|
166
|
+
private readonly proc: Subprocess,
|
|
167
|
+
options: ExchangeOptions,
|
|
168
|
+
timeoutMs: number,
|
|
169
|
+
) {
|
|
170
|
+
this.deadline = new ProcessDeadline({
|
|
171
|
+
timeoutMs,
|
|
172
|
+
signal: options.signal,
|
|
173
|
+
interruption: (reason) =>
|
|
174
|
+
new ExtensionProtocolError(
|
|
175
|
+
reason === "timeout"
|
|
176
|
+
? "extension timed out"
|
|
177
|
+
: "extension request cancelled",
|
|
178
|
+
),
|
|
179
|
+
});
|
|
180
|
+
}
|
|
227
181
|
|
|
228
182
|
private async output(
|
|
229
183
|
request: ExtensionRequest,
|
|
@@ -232,9 +186,17 @@ class ExtensionExchange {
|
|
|
232
186
|
const stdin = extensionWriter(this.proc);
|
|
233
187
|
const { stdout, stderr } = extensionReaders(this.proc);
|
|
234
188
|
const write = writeExtensionRequest(stdin, payload);
|
|
235
|
-
const [bytes, , exitCode] = await Promise.all([
|
|
236
|
-
|
|
237
|
-
|
|
189
|
+
const [{ bytes }, , exitCode] = await Promise.all([
|
|
190
|
+
captureBoundedBytes(stdout, {
|
|
191
|
+
limit: MAX_MESSAGE_BYTES,
|
|
192
|
+
overflow: "reject",
|
|
193
|
+
exceeded: () =>
|
|
194
|
+
new ExtensionProtocolError("extension message exceeds 8 MiB"),
|
|
195
|
+
}),
|
|
196
|
+
captureBoundedBytes(stderr, {
|
|
197
|
+
limit: MAX_DIAGNOSTIC_BYTES,
|
|
198
|
+
overflow: "truncate",
|
|
199
|
+
}),
|
|
238
200
|
this.proc.exited,
|
|
239
201
|
write,
|
|
240
202
|
]);
|
|
@@ -248,48 +210,18 @@ class ExtensionExchange {
|
|
|
248
210
|
return response;
|
|
249
211
|
}
|
|
250
212
|
|
|
251
|
-
private timeout(): Promise<never> {
|
|
252
|
-
return new Promise((_resolve, reject) => {
|
|
253
|
-
this.timer = setTimeout(() => {
|
|
254
|
-
reject(new ExtensionProtocolError("extension timed out"));
|
|
255
|
-
}, this.timeoutMs);
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
private aborted(): Promise<never> {
|
|
260
|
-
return new Promise((_resolve, reject) => {
|
|
261
|
-
const signal = this.options.signal;
|
|
262
|
-
if (!signal) return;
|
|
263
|
-
this.cancel = () => {
|
|
264
|
-
reject(new ExtensionProtocolError("extension request cancelled"));
|
|
265
|
-
};
|
|
266
|
-
if (signal.aborted) this.cancel();
|
|
267
|
-
else signal.addEventListener("abort", this.cancel, { once: true });
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
private dispose(): void {
|
|
272
|
-
if (this.timer) clearTimeout(this.timer);
|
|
273
|
-
if (this.cancel)
|
|
274
|
-
this.options.signal?.removeEventListener("abort", this.cancel);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
213
|
async run(
|
|
278
214
|
request: ExtensionRequest,
|
|
279
215
|
payload: Uint8Array,
|
|
280
216
|
): Promise<SuccessfulExtensionResponse> {
|
|
281
217
|
try {
|
|
282
|
-
return await
|
|
283
|
-
this.output(request, payload),
|
|
284
|
-
this.timeout(),
|
|
285
|
-
this.aborted(),
|
|
286
|
-
]);
|
|
218
|
+
return await this.deadline.wait(this.output(request, payload));
|
|
287
219
|
} catch (cause) {
|
|
288
|
-
|
|
220
|
+
terminateOwnedProcessGroup(this.proc);
|
|
289
221
|
if (cause instanceof ExtensionProtocolError) throw cause;
|
|
290
222
|
throw new ExtensionProtocolError("extension transport failed", { cause });
|
|
291
223
|
} finally {
|
|
292
|
-
this.dispose();
|
|
224
|
+
this.deadline.dispose();
|
|
293
225
|
}
|
|
294
226
|
}
|
|
295
227
|
}
|
package/src/extension-session.ts
CHANGED
|
@@ -4,9 +4,20 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
4
4
|
import { createReadStream } from "node:fs";
|
|
5
5
|
import { isAbsolute } from "node:path";
|
|
6
6
|
import { canonicalJson, hashJson } from "./identity";
|
|
7
|
-
import type { GeneratedFixture } from "./generated
|
|
8
|
-
import type { RepositoryFixture } from "./repository
|
|
9
|
-
import type { FixtureSetupDeclaration } from "./
|
|
7
|
+
import type { GeneratedFixture } from "./fixtures/generated";
|
|
8
|
+
import type { RepositoryFixture } from "./fixtures/repository";
|
|
9
|
+
import type { FixtureSetupDeclaration } from "./fixtures/setup";
|
|
10
|
+
import type {
|
|
11
|
+
ArtifactReference,
|
|
12
|
+
Assessment,
|
|
13
|
+
CheckDeclaration,
|
|
14
|
+
DomainOutcome,
|
|
15
|
+
ExtensionCheckOutcome,
|
|
16
|
+
MetricEvidence,
|
|
17
|
+
ObservationEvidence,
|
|
18
|
+
TaskVerdict,
|
|
19
|
+
} from "./contract-types";
|
|
20
|
+
import type { InstrumentationRequest } from "./instrumentation";
|
|
10
21
|
import {
|
|
11
22
|
ExtensionProtocolError,
|
|
12
23
|
exchangeExtension,
|
|
@@ -32,11 +43,7 @@ export interface ExtensionCase {
|
|
|
32
43
|
| { kind: "inline"; files: Record<string, string> }
|
|
33
44
|
| RepositoryFixture
|
|
34
45
|
| GeneratedFixture;
|
|
35
|
-
checks:
|
|
36
|
-
id: string;
|
|
37
|
-
grader: string;
|
|
38
|
-
configuration: Record<string, unknown>;
|
|
39
|
-
}[];
|
|
46
|
+
checks: CheckDeclaration[];
|
|
40
47
|
requiredEvidence: string[];
|
|
41
48
|
extensionData: Record<string, unknown>;
|
|
42
49
|
}
|
|
@@ -51,10 +58,7 @@ export interface PreparationResult {
|
|
|
51
58
|
gitExclude?: boolean;
|
|
52
59
|
executable?: boolean;
|
|
53
60
|
}[];
|
|
54
|
-
requestedInstrumentation:
|
|
55
|
-
id: string;
|
|
56
|
-
configuration: Record<string, unknown>;
|
|
57
|
-
}[];
|
|
61
|
+
requestedInstrumentation: InstrumentationRequest[];
|
|
58
62
|
fixtureSetup?: FixtureSetupDeclaration;
|
|
59
63
|
codexMarketplace?: {
|
|
60
64
|
artifactRoot: string;
|
|
@@ -77,48 +81,20 @@ export interface PreparationResult {
|
|
|
77
81
|
|
|
78
82
|
export interface EvaluationRequest {
|
|
79
83
|
caseId: string;
|
|
80
|
-
execution: {
|
|
81
|
-
status: "completed" | "failed" | "cancelled" | "not_run";
|
|
84
|
+
execution: Assessment["execution"] & {
|
|
82
85
|
errorCode?: string;
|
|
83
86
|
};
|
|
84
|
-
observations:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
completeness: "complete" | "partial" | "unavailable";
|
|
88
|
-
data: Record<string, unknown>;
|
|
89
|
-
}[];
|
|
90
|
-
builtinChecks: {
|
|
91
|
-
id: string;
|
|
92
|
-
status: "passed" | "failed" | "unavailable";
|
|
93
|
-
detail?: string;
|
|
94
|
-
evidenceRefs: string[];
|
|
95
|
-
}[];
|
|
96
|
-
artifacts: {
|
|
97
|
-
id: string;
|
|
98
|
-
path: string;
|
|
99
|
-
sha256: string;
|
|
100
|
-
gitExclude?: boolean;
|
|
101
|
-
executable?: boolean;
|
|
102
|
-
}[];
|
|
87
|
+
observations: ObservationEvidence[];
|
|
88
|
+
builtinChecks: ExtensionCheckOutcome[];
|
|
89
|
+
artifacts: ArtifactReference[];
|
|
103
90
|
extensionData: Record<string, unknown>;
|
|
104
91
|
}
|
|
105
92
|
|
|
106
93
|
export interface EvaluationResult {
|
|
107
|
-
checks:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
evidenceRefs: string[];
|
|
112
|
-
}[];
|
|
113
|
-
metrics: { id: string; value: number | null; unit: string }[];
|
|
114
|
-
domainOutcomes?: {
|
|
115
|
-
id: string;
|
|
116
|
-
status: "passed" | "failed" | "unavailable";
|
|
117
|
-
detail?: string;
|
|
118
|
-
evidenceRefs: string[];
|
|
119
|
-
data?: Record<string, unknown>;
|
|
120
|
-
}[];
|
|
121
|
-
taskVerdictRecommendation?: "passed" | "failed" | "not_assessed";
|
|
94
|
+
checks: ExtensionCheckOutcome[];
|
|
95
|
+
metrics: MetricEvidence[];
|
|
96
|
+
domainOutcomes?: DomainOutcome[];
|
|
97
|
+
taskVerdictRecommendation?: TaskVerdict;
|
|
122
98
|
}
|
|
123
99
|
|
|
124
100
|
export interface ExtensionSessionOptions extends ExchangeOptions {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Dirent, Stats } from "node:fs";
|
|
2
|
-
import { isMissingFile } from "./
|
|
2
|
+
import { isMissingFile } from "./tools";
|
|
3
3
|
import {
|
|
4
4
|
lstat,
|
|
5
5
|
mkdir,
|
|
@@ -11,7 +11,9 @@ import {
|
|
|
11
11
|
copyFile,
|
|
12
12
|
} from "node:fs/promises";
|
|
13
13
|
import { allocateWorkspace, removeWorkspace } from "./workspace-state";
|
|
14
|
-
import { dirname, isAbsolute, join,
|
|
14
|
+
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
15
|
+
import { insideRoot as contained } from "../paths";
|
|
16
|
+
import { runGit } from "../git";
|
|
15
17
|
import { fixtureParts } from "./preparation";
|
|
16
18
|
|
|
17
19
|
const MAX_GIT_OUTPUT = 16 * 1024 * 1024;
|
|
@@ -19,87 +21,25 @@ const MAX_UNTRACKED_BYTES = 32 * 1024 * 1024;
|
|
|
19
21
|
const MAX_UNTRACKED_FILES = 1024;
|
|
20
22
|
const HIDDEN_ROOTS = [".agents", ".claude", ".codex", ".git"];
|
|
21
23
|
|
|
22
|
-
function contained(root: string, path: string): boolean {
|
|
23
|
-
const child = relative(root, path);
|
|
24
|
-
return (
|
|
25
|
-
child === "" ||
|
|
26
|
-
(child !== ".." && !child.startsWith(`..${sep}`) && !isAbsolute(child))
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
24
|
function excluded(path: string, roots: string[]): boolean {
|
|
31
25
|
return roots.some((root) => path === root || path.startsWith(`${root}/`));
|
|
32
26
|
}
|
|
33
27
|
|
|
34
|
-
async function bounded(stream: ReadableStream<Uint8Array>): Promise<Buffer> {
|
|
35
|
-
const chunks: Uint8Array[] = [];
|
|
36
|
-
let size = 0;
|
|
37
|
-
for await (const chunk of stream) {
|
|
38
|
-
size += chunk.byteLength;
|
|
39
|
-
if (size > MAX_GIT_OUTPUT)
|
|
40
|
-
throw new Error("advisory fixture Git output is too large");
|
|
41
|
-
chunks.push(chunk);
|
|
42
|
-
}
|
|
43
|
-
return Buffer.concat(chunks);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function nullGitConfig(): string {
|
|
47
|
-
return process.platform === "win32" ? "NUL" : "/dev/null";
|
|
48
|
-
}
|
|
49
|
-
function gitEnvironment(): Record<string, string> {
|
|
50
|
-
return {
|
|
51
|
-
PATH: process.env.PATH ?? "/usr/bin:/bin",
|
|
52
|
-
...(process.env.SystemRoot ? { SystemRoot: process.env.SystemRoot } : {}),
|
|
53
|
-
GIT_CONFIG_NOSYSTEM: "1",
|
|
54
|
-
GIT_CONFIG_GLOBAL: nullGitConfig(),
|
|
55
|
-
GIT_TERMINAL_PROMPT: "0",
|
|
56
|
-
GIT_AUTHOR_NAME: "Sevro Advisory",
|
|
57
|
-
GIT_AUTHOR_EMAIL: "advisory@sevro.invalid",
|
|
58
|
-
GIT_COMMITTER_NAME: "Sevro Advisory",
|
|
59
|
-
GIT_COMMITTER_EMAIL: "advisory@sevro.invalid",
|
|
60
|
-
GIT_AUTHOR_DATE: "2000-01-01T00:00:00+00:00",
|
|
61
|
-
GIT_COMMITTER_DATE: "2000-01-01T00:00:00+00:00",
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
28
|
async function git(
|
|
66
29
|
cwd: string,
|
|
67
30
|
args: string[],
|
|
68
31
|
input?: Uint8Array,
|
|
69
32
|
): Promise<Buffer> {
|
|
70
|
-
const proc = Bun.spawn(
|
|
71
|
-
["git", "-c", `core.hooksPath=${nullGitConfig()}`, ...args],
|
|
72
|
-
{
|
|
73
|
-
cwd,
|
|
74
|
-
stdin: input ? "pipe" : "ignore",
|
|
75
|
-
stdout: "pipe",
|
|
76
|
-
stderr: "pipe",
|
|
77
|
-
env: gitEnvironment(),
|
|
78
|
-
},
|
|
79
|
-
);
|
|
80
33
|
try {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
bounded(proc.stdout),
|
|
90
|
-
bounded(proc.stderr),
|
|
91
|
-
proc.exited,
|
|
92
|
-
write,
|
|
93
|
-
]);
|
|
94
|
-
if (code !== 0) throw new Error("advisory fixture Git operation failed");
|
|
95
|
-
return out;
|
|
34
|
+
return await runGit({
|
|
35
|
+
cwd,
|
|
36
|
+
args,
|
|
37
|
+
input,
|
|
38
|
+
identity: "advisory",
|
|
39
|
+
label: "advisory fixture",
|
|
40
|
+
maxOutputBytes: MAX_GIT_OUTPUT,
|
|
41
|
+
});
|
|
96
42
|
} catch (cause) {
|
|
97
|
-
try {
|
|
98
|
-
proc.kill("SIGKILL");
|
|
99
|
-
} catch {
|
|
100
|
-
// The process may already have exited.
|
|
101
|
-
}
|
|
102
|
-
await proc.exited;
|
|
103
43
|
throw new Error("advisory fixture Git operation failed", { cause });
|
|
104
44
|
}
|
|
105
45
|
}
|
|
@@ -15,6 +15,18 @@ async function restoreDirectoryAccess(path: string): Promise<void> {
|
|
|
15
15
|
await restoreDirectoryAccess(join(path, child.name));
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/** Remove owned disposable state without following cache or fixture symlinks. */
|
|
19
|
+
export async function removeDisposableDirectory(path: string): Promise<void> {
|
|
20
|
+
try {
|
|
21
|
+
await rm(path, { recursive: true, force: true });
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if ((error as NodeJS.ErrnoException).code === "ENOTDIR") return;
|
|
24
|
+
if (!permissionFailure(error)) throw error;
|
|
25
|
+
await restoreDirectoryAccess(path);
|
|
26
|
+
await rm(path, { recursive: true, force: true });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
18
30
|
/** Clear a completed fixture while preserving its reserved root for active peers. */
|
|
19
31
|
export async function clearFixtureContents(workspace: string): Promise<void> {
|
|
20
32
|
const root = await lstat(workspace);
|
|
@@ -26,13 +38,7 @@ export async function clearFixtureContents(workspace: string): Promise<void> {
|
|
|
26
38
|
await Promise.all(
|
|
27
39
|
names.map(async (name) => {
|
|
28
40
|
const path = join(workspace, name);
|
|
29
|
-
|
|
30
|
-
await rm(path, { recursive: true, force: true });
|
|
31
|
-
} catch (error) {
|
|
32
|
-
if (!permissionFailure(error)) throw error;
|
|
33
|
-
await restoreDirectoryAccess(path);
|
|
34
|
-
await rm(path, { recursive: true, force: true });
|
|
35
|
-
}
|
|
41
|
+
await removeDisposableDirectory(path);
|
|
36
42
|
}),
|
|
37
43
|
);
|
|
38
44
|
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { appendFile, mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { allocateWorkspace, removeWorkspace } from "./workspace-state";
|
|
4
|
+
import { fixtureBinDirectory, installFixtureBin } from "./bin";
|
|
5
|
+
import { installGitHooks } from "./git-hooks";
|
|
6
|
+
import {
|
|
7
|
+
materializeGeneratedFixture,
|
|
8
|
+
type GeneratedFixture,
|
|
9
|
+
} from "./generated";
|
|
10
|
+
import { runFixtureSetup, type FixtureSetup } from "./setup";
|
|
11
|
+
import {
|
|
12
|
+
fixtureParts,
|
|
13
|
+
safePreparationTarget,
|
|
14
|
+
type InlineArtifact,
|
|
15
|
+
type PreparationSources,
|
|
16
|
+
} from "./preparation";
|
|
17
|
+
import {
|
|
18
|
+
applyRepositoryOverlay,
|
|
19
|
+
cloneRepositorySource,
|
|
20
|
+
type RepositoryFixture,
|
|
21
|
+
type RepositorySource,
|
|
22
|
+
} from "./repository";
|
|
23
|
+
import {
|
|
24
|
+
EvaluationConfigurationError,
|
|
25
|
+
type ResolvedCase,
|
|
26
|
+
} from "../evaluation/types";
|
|
27
|
+
|
|
28
|
+
export type FixtureSource<Repository = RepositorySource> =
|
|
29
|
+
| { kind: "inline"; files: ResolvedCase["fixture"]["files"] }
|
|
30
|
+
| { kind: "generated"; fixture: GeneratedFixture }
|
|
31
|
+
| { kind: "repository"; fixture: RepositoryFixture; repository: Repository };
|
|
32
|
+
|
|
33
|
+
interface FixtureOptions {
|
|
34
|
+
artifacts?: InlineArtifact[];
|
|
35
|
+
sources?: PreparationSources;
|
|
36
|
+
setup?: FixtureSetup | null;
|
|
37
|
+
projectRoot: string;
|
|
38
|
+
signal?: AbortSignal;
|
|
39
|
+
reservedWorkspace?: string;
|
|
40
|
+
candidateRuntimeRoot?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function createFixture(
|
|
44
|
+
source: FixtureSource,
|
|
45
|
+
options: FixtureOptions,
|
|
46
|
+
): Promise<string> {
|
|
47
|
+
const paths = inlineFixturePaths(source);
|
|
48
|
+
const artifacts = options.artifacts ?? [];
|
|
49
|
+
const workspace = options.reservedWorkspace ?? (await allocateWorkspace());
|
|
50
|
+
try {
|
|
51
|
+
await initializeFixtureHistory(source, options.sources, workspace);
|
|
52
|
+
await installDeclaredFixtureTools(source, workspace);
|
|
53
|
+
await writeInlineFixtureFiles(paths, workspace);
|
|
54
|
+
await setupFixture(
|
|
55
|
+
options.setup,
|
|
56
|
+
workspace,
|
|
57
|
+
options.projectRoot,
|
|
58
|
+
options.signal,
|
|
59
|
+
options.candidateRuntimeRoot,
|
|
60
|
+
);
|
|
61
|
+
await mountPreparationArtifacts(artifacts, workspace);
|
|
62
|
+
await excludePreparationArtifacts(artifacts, workspace);
|
|
63
|
+
await fixtureBinDirectory(workspace);
|
|
64
|
+
return workspace;
|
|
65
|
+
} catch (error) {
|
|
66
|
+
if (!options.reservedWorkspace) await removeWorkspace(workspace);
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function inlineFixturePaths(source: FixtureSource) {
|
|
72
|
+
return Object.entries(
|
|
73
|
+
source.kind === "inline" ? (source.files ?? {}) : {},
|
|
74
|
+
).map(([path, content]) => ({ path, parts: fixtureParts(path), content }));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function cloneFixtureRepository(
|
|
78
|
+
source: Extract<FixtureSource, { kind: "repository" }>,
|
|
79
|
+
sources: PreparationSources | undefined,
|
|
80
|
+
workspace: string,
|
|
81
|
+
): Promise<void> {
|
|
82
|
+
if (!sources)
|
|
83
|
+
throw new EvaluationConfigurationError(
|
|
84
|
+
"repository source root is required and must be absolute",
|
|
85
|
+
);
|
|
86
|
+
await cloneRepositorySource(
|
|
87
|
+
source.fixture.sourceRef,
|
|
88
|
+
sources,
|
|
89
|
+
source.repository,
|
|
90
|
+
workspace,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function initializeFixtureHistory(
|
|
95
|
+
source: FixtureSource,
|
|
96
|
+
sources: PreparationSources | undefined,
|
|
97
|
+
workspace: string,
|
|
98
|
+
): Promise<void> {
|
|
99
|
+
switch (source.kind) {
|
|
100
|
+
case "repository":
|
|
101
|
+
await cloneFixtureRepository(source, sources, workspace);
|
|
102
|
+
await applyRepositoryOverlay(source.fixture, workspace);
|
|
103
|
+
break;
|
|
104
|
+
case "generated":
|
|
105
|
+
await materializeGeneratedFixture(source.fixture, workspace);
|
|
106
|
+
break;
|
|
107
|
+
case "inline":
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function installDeclaredFixtureTools(
|
|
113
|
+
source: FixtureSource,
|
|
114
|
+
workspace: string,
|
|
115
|
+
): Promise<void> {
|
|
116
|
+
const fixture = source.kind === "inline" ? undefined : source.fixture;
|
|
117
|
+
await installFixtureBin(fixture?.bin, workspace);
|
|
118
|
+
await installGitHooks(fixture?.hooks, workspace);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function writeInlineFixtureFiles(
|
|
122
|
+
files: ReturnType<typeof inlineFixturePaths>,
|
|
123
|
+
workspace: string,
|
|
124
|
+
): Promise<void> {
|
|
125
|
+
for (const file of files) {
|
|
126
|
+
const target = join(workspace, ...file.parts);
|
|
127
|
+
await mkdir(dirname(target), { recursive: true, mode: 0o700 });
|
|
128
|
+
await writeFile(target, file.content, { flag: "wx", mode: 0o600 });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async function setupFixture(
|
|
133
|
+
setup: FixtureSetup | null | undefined,
|
|
134
|
+
workspace: string,
|
|
135
|
+
projectRoot: string,
|
|
136
|
+
signal?: AbortSignal,
|
|
137
|
+
candidateRuntimeRoot?: string,
|
|
138
|
+
): Promise<void> {
|
|
139
|
+
if (!setup) return;
|
|
140
|
+
await runFixtureSetup(setup, {
|
|
141
|
+
workspace,
|
|
142
|
+
projectRoot,
|
|
143
|
+
fixtureBinDir: (await fixtureBinDirectory(workspace)) ?? undefined,
|
|
144
|
+
signal,
|
|
145
|
+
candidateRuntimeRoot,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async function mountPreparationArtifacts(
|
|
150
|
+
artifacts: InlineArtifact[],
|
|
151
|
+
workspace: string,
|
|
152
|
+
): Promise<void> {
|
|
153
|
+
for (const artifact of artifacts) {
|
|
154
|
+
const target = await safePreparationTarget(
|
|
155
|
+
workspace,
|
|
156
|
+
artifact.relativePath,
|
|
157
|
+
);
|
|
158
|
+
await writeFile(target, artifact.bytes, {
|
|
159
|
+
flag: "wx",
|
|
160
|
+
mode: artifact.executable ? 0o700 : 0o600,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function excludePreparationArtifacts(
|
|
166
|
+
artifacts: InlineArtifact[],
|
|
167
|
+
workspace: string,
|
|
168
|
+
): Promise<void> {
|
|
169
|
+
const gitExcluded = artifacts.filter((artifact) => artifact.gitExclude);
|
|
170
|
+
if (!gitExcluded.length) return;
|
|
171
|
+
const special = new Set(["\\", "*", "?", "[", "]", "#", "!", " "]);
|
|
172
|
+
const patterns = gitExcluded.map((artifact) =>
|
|
173
|
+
Array.from(artifact.relativePath)
|
|
174
|
+
.map((character) =>
|
|
175
|
+
special.has(character) ? `\\${character}` : character,
|
|
176
|
+
)
|
|
177
|
+
.join(""),
|
|
178
|
+
);
|
|
179
|
+
await appendFile(
|
|
180
|
+
join(workspace, ".git", "info", "exclude"),
|
|
181
|
+
`\n${patterns.map((path) => `/${path}`).join("\n")}\n`,
|
|
182
|
+
);
|
|
183
|
+
}
|