@sema-agent/server 1.323.0 → 2.0.1
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/dist/approval-hmac.d.ts +40 -0
- package/dist/approval-hmac.js +67 -0
- package/dist/approval.d.ts +31 -0
- package/dist/approval.js +72 -4
- package/dist/audit.d.ts +26 -0
- package/dist/audit.js +40 -1
- package/dist/auth-bridge.d.ts +10 -0
- package/dist/auth-bridge.js +47 -4
- package/dist/auth-keys.d.ts +19 -0
- package/dist/auth-keys.js +13 -0
- package/dist/bake-runner/main.d.ts +5 -0
- package/dist/bake-runner/main.js +43 -4
- package/dist/bake-runner/protocol.d.ts +57 -0
- package/dist/bake-runner/protocol.js +58 -3
- package/dist/bake-runner/runner.d.ts +54 -0
- package/dist/bake-runner/runner.js +87 -5
- package/dist/bench/l8/artifact.d.ts +63 -0
- package/dist/bench/l8/artifact.js +61 -2
- package/dist/bench/l8/escape.d.ts +36 -0
- package/dist/bench/l8/escape.js +25 -0
- package/dist/bench/l8/index.d.ts +14 -0
- package/dist/bench/l8/index.js +14 -0
- package/dist/bench/l8/probes.d.ts +74 -0
- package/dist/bench/l8/probes.js +60 -0
- package/dist/bench/l8/run-probes.d.ts +43 -0
- package/dist/bench/l8/run-probes.js +45 -2
- package/dist/bench/s1/arms.d.ts +126 -0
- package/dist/bench/s1/arms.js +188 -13
- package/dist/bench/s1/live-deps.d.ts +66 -0
- package/dist/bench/s1/live-deps.js +249 -11
- package/dist/bench/s1/oracle.d.ts +49 -0
- package/dist/bench/s1/oracle.js +36 -1
- package/dist/bench/s1/repair-oracle-adapter.d.ts +33 -0
- package/dist/bench/s1/repair-oracle-adapter.js +30 -0
- package/dist/bench/s1/reviewer.d.ts +38 -0
- package/dist/bench/s1/reviewer.js +34 -0
- package/dist/bench/s1/row.d.ts +77 -0
- package/dist/bench/s1/row.js +62 -0
- package/dist/bench/s1/run-firm.d.ts +47 -0
- package/dist/bench/s1/run-firm.js +70 -4
- package/dist/bench/s1/runner-ctx.d.ts +71 -0
- package/dist/bench/s1/runner-ctx.js +36 -0
- package/dist/bench/s1/tasks.d.ts +108 -0
- package/dist/bench/s1/tasks.js +115 -0
- package/dist/boot/budget-tracing.d.ts +48 -0
- package/dist/boot/budget-tracing.js +86 -0
- package/dist/boot/config-center.d.ts +62 -0
- package/dist/boot/config-center.js +995 -0
- package/dist/boot/coordinators.d.ts +33 -0
- package/dist/boot/coordinators.js +97 -0
- package/dist/boot/execution-env.d.ts +26 -0
- package/dist/boot/execution-env.js +370 -0
- package/dist/boot/leader.d.ts +27 -0
- package/dist/boot/leader.js +81 -0
- package/dist/boot/reapers.d.ts +53 -0
- package/dist/boot/reapers.js +252 -0
- package/dist/boot/resolve-spec.d.ts +70 -0
- package/dist/boot/resolve-spec.js +1072 -0
- package/dist/boot/runner-deps.d.ts +101 -0
- package/dist/boot/runner-deps.js +343 -0
- package/dist/boot/runtime-caps.d.ts +21 -0
- package/dist/boot/runtime-caps.js +62 -0
- package/dist/boot/session-faces.d.ts +57 -0
- package/dist/boot/session-faces.js +157 -0
- package/dist/boot/shutdown.d.ts +50 -0
- package/dist/boot/shutdown.js +129 -0
- package/dist/boot/stores.d.ts +32 -0
- package/dist/boot/stores.js +361 -0
- package/dist/boot/workflow-orchestration.d.ts +46 -0
- package/dist/boot/workflow-orchestration.js +150 -0
- package/dist/boot-reclaim.d.ts +19 -0
- package/dist/boot-reclaim.js +20 -0
- package/dist/brain.d.ts +25 -0
- package/dist/brain.js +61 -1
- package/dist/budget.d.ts +66 -0
- package/dist/budget.js +128 -4
- package/dist/capabilities/builtin-tools.d.ts +3 -0
- package/dist/capabilities/builtin-tools.js +3 -0
- package/dist/capabilities/center-plugins.d.ts +17 -1
- package/dist/capabilities/center-plugins.js +45 -4
- package/dist/capabilities/center-prompts.d.ts +46 -0
- package/dist/capabilities/center-prompts.js +57 -3
- package/dist/capabilities/code-review-council.d.ts +28 -0
- package/dist/capabilities/code-review-council.js +40 -7
- package/dist/capabilities/collab-wire.d.ts +2 -0
- package/dist/capabilities/collab-workflows.d.ts +7 -0
- package/dist/capabilities/collab-workflows.js +44 -1
- package/dist/capabilities/oa-tools.d.ts +6 -0
- package/dist/capabilities/oa-tools.js +10 -0
- package/dist/capabilities/prompt.d.ts +14 -0
- package/dist/capabilities/prompt.js +14 -0
- package/dist/capabilities/prompts/code-review.d.ts +14 -0
- package/dist/capabilities/prompts/code-review.js +14 -0
- package/dist/capabilities/prompts/identity.d.ts +6 -0
- package/dist/capabilities/prompts/identity.js +6 -0
- package/dist/capabilities/prompts/team.d.ts +4 -0
- package/dist/capabilities/prompts/team.js +4 -0
- package/dist/capabilities/repo-tools.d.ts +11 -0
- package/dist/capabilities/repo-tools.js +8 -0
- package/dist/capabilities/sandbox-file-send.d.ts +95 -0
- package/dist/capabilities/sandbox-file-send.js +91 -3
- package/dist/capabilities/scenarios.d.ts +130 -0
- package/dist/capabilities/scenarios.js +180 -7
- package/dist/capabilities/select-environment-tool.d.ts +7 -0
- package/dist/capabilities/select-environment-tool.js +30 -0
- package/dist/capabilities/send-user-file-tool.d.ts +33 -0
- package/dist/capabilities/send-user-file-tool.js +65 -1
- package/dist/capabilities/skills.d.ts +29 -0
- package/dist/capabilities/skills.js +13 -2
- package/dist/capabilities/team.d.ts +22 -0
- package/dist/capabilities/team.js +22 -2
- package/dist/capabilities/tool-defer.d.ts +26 -0
- package/dist/capabilities/tool-defer.js +3 -0
- package/dist/config-center/apply-effective.d.ts +65 -0
- package/dist/config-center/apply-effective.js +204 -12
- package/dist/config-center/http-client.d.ts +34 -0
- package/dist/config-center/http-client.js +68 -0
- package/dist/config-center/restart-signal.d.ts +22 -0
- package/dist/config-center/restart-signal.js +39 -0
- package/dist/config-center/skills-mcp.d.ts +20 -1
- package/dist/config-center/skills-mcp.js +42 -7
- package/dist/config-center/types.d.ts +92 -1
- package/dist/config-lkg.d.ts +12 -0
- package/dist/config-lkg.js +41 -0
- package/dist/config-provider.d.ts +78 -0
- package/dist/config-provider.js +165 -2
- package/dist/config-types.d.ts +585 -1
- package/dist/config.d.ts +78 -2
- package/dist/config.js +874 -301
- package/dist/degenerate-instrument.d.ts +38 -0
- package/dist/degenerate-instrument.js +55 -3
- package/dist/elicitation.d.ts +39 -0
- package/dist/elicitation.js +87 -3
- package/dist/env-facts.d.ts +61 -0
- package/dist/env-facts.js +73 -7
- package/dist/fleet/fleet-bus.d.ts +185 -0
- package/dist/fleet/fleet-bus.js +333 -27
- package/dist/fleet/subagent-tail-bus.d.ts +11 -0
- package/dist/fleet/subagent-tail-bus.js +33 -2
- package/dist/fleet-client.d.ts +38 -0
- package/dist/fleet-client.js +44 -9
- package/dist/fleet-lease.d.ts +46 -0
- package/dist/fleet-lease.js +73 -5
- package/dist/hooks/branch-transcript.d.ts +8 -0
- package/dist/hooks/branch-transcript.js +33 -0
- package/dist/hooks/cc-stop-prompt.d.ts +42 -0
- package/dist/hooks/cc-stop-prompt.js +43 -1
- package/dist/hooks/hook-llm.d.ts +15 -0
- package/dist/hooks/hook-llm.js +47 -0
- package/dist/hooks/hook-runner.d.ts +89 -0
- package/dist/hooks/hook-runner.js +327 -18
- package/dist/http/idempotency.d.ts +31 -0
- package/dist/http/idempotency.js +34 -0
- package/dist/http/principal-gate.d.ts +17 -0
- package/dist/http/principal-gate.js +35 -3
- package/dist/http/route-ctx.d.ts +36 -0
- package/dist/http/routes/approvals-assistant.d.ts +25 -0
- package/dist/http/routes/approvals-assistant.js +253 -23
- package/dist/http/routes/attachments.js +22 -4
- package/dist/http/routes/capabilities.d.ts +7 -0
- package/dist/http/routes/capabilities.js +202 -1
- package/dist/http/routes/fleet.d.ts +6 -0
- package/dist/http/routes/fleet.js +94 -5
- package/dist/http/routes/images.d.ts +17 -0
- package/dist/http/routes/images.js +222 -14
- package/dist/http/routes/leader.d.ts +7 -0
- package/dist/http/routes/leader.js +10 -0
- package/dist/http/routes/memory-policy.d.ts +6 -0
- package/dist/http/routes/memory-policy.js +38 -6
- package/dist/http/routes/notify-wake.d.ts +10 -0
- package/dist/http/routes/notify-wake.js +19 -3
- package/dist/http/routes/observability.d.ts +6 -0
- package/dist/http/routes/observability.js +19 -2
- package/dist/http/routes/runs.d.ts +15 -0
- package/dist/http/routes/runs.js +464 -41
- package/dist/http/routes/session-sync.d.ts +15 -0
- package/dist/http/routes/session-sync.js +229 -19
- package/dist/http/routes/sessions-list.d.ts +6 -0
- package/dist/http/routes/sessions-list.js +35 -4
- package/dist/http/routes/sessions.d.ts +14 -0
- package/dist/http/routes/sessions.js +176 -31
- package/dist/http/routes/side-query.d.ts +8 -0
- package/dist/http/routes/side-query.js +26 -1
- package/dist/http/routes/tasks.d.ts +18 -0
- package/dist/http/routes/tasks.js +501 -38
- package/dist/http/routes/trace-usage.d.ts +10 -0
- package/dist/http/routes/trace-usage.js +66 -14
- package/dist/http/routes/workflows.d.ts +12 -0
- package/dist/http/routes/workflows.js +180 -19
- package/dist/http/run-meta.d.ts +11 -0
- package/dist/http/run-meta.js +6 -0
- package/dist/http/send.d.ts +19 -0
- package/dist/http/send.js +11 -0
- package/dist/http/server.d.ts +255 -0
- package/dist/http/server.js +921 -75
- package/dist/http/sse-log.d.ts +15 -0
- package/dist/http/sse-log.js +16 -0
- package/dist/http/tar.d.ts +9 -0
- package/dist/http/tar.js +21 -5
- package/dist/http/wire-gate.d.ts +9 -0
- package/dist/http/wire-gate.js +9 -0
- package/dist/http/wire-types.d.ts +187 -0
- package/dist/http/workspace-content.d.ts +8 -0
- package/dist/http/workspace-content.js +10 -0
- package/dist/images/bake-validate.d.ts +63 -0
- package/dist/images/bake-validate.js +71 -1
- package/dist/images/manifest.d.ts +19 -0
- package/dist/images/manifest.js +6 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.js +10 -5
- package/dist/key-resolver.d.ts +23 -0
- package/dist/key-resolver.js +27 -2
- package/dist/leader/diffout.d.ts +23 -0
- package/dist/leader/diffout.js +8 -1
- package/dist/leader/diffup.d.ts +32 -0
- package/dist/leader/diffup.js +43 -0
- package/dist/leader/endpoint.d.ts +20 -0
- package/dist/leader/endpoint.js +25 -2
- package/dist/leader/fanout.d.ts +60 -0
- package/dist/leader/fanout.js +29 -3
- package/dist/leader/grader-env-factory.d.ts +74 -0
- package/dist/leader/grader-env-factory.js +62 -3
- package/dist/leader/leader.d.ts +97 -0
- package/dist/leader/leader.js +151 -4
- package/dist/leader/merge.d.ts +94 -0
- package/dist/leader/merge.js +112 -9
- package/dist/leader/planner.d.ts +52 -0
- package/dist/leader/planner.js +47 -3
- package/dist/leader/repair-oracle.d.ts +61 -0
- package/dist/leader/repair-oracle.js +59 -1
- package/dist/leader/repair-wire.d.ts +78 -0
- package/dist/leader/repair-wire.js +79 -2
- package/dist/leader/wire.d.ts +79 -0
- package/dist/leader/wire.js +255 -8
- package/dist/lsp/e2b-bridge.d.ts +16 -0
- package/dist/lsp/e2b-bridge.js +32 -4
- package/dist/lsp/e2b-manager.d.ts +10 -0
- package/dist/lsp/e2b-manager.js +18 -2
- package/dist/lsp/lsp-frames.d.ts +12 -0
- package/dist/lsp/lsp-frames.js +12 -0
- package/dist/lsp/manager.d.ts +12 -0
- package/dist/lsp/manager.js +35 -2
- package/dist/lsp/types.d.ts +10 -0
- package/dist/lsp/ws-transport.d.ts +12 -0
- package/dist/lsp/ws-transport.js +53 -5
- package/dist/lsp-evict.d.ts +14 -0
- package/dist/lsp-evict.js +15 -1
- package/dist/main.js +530 -2129
- package/dist/memory-export.d.ts +1 -0
- package/dist/memory-export.js +4 -0
- package/dist/memory-scope.d.ts +49 -0
- package/dist/memory-scope.js +87 -4
- package/dist/memory-sync-client.d.ts +24 -0
- package/dist/memory-sync-client.js +41 -2
- package/dist/memory-sync.d.ts +23 -0
- package/dist/memory-sync.js +70 -1
- package/dist/model-select.d.ts +39 -0
- package/dist/model-select.js +42 -1
- package/dist/observability/cost-quota.d.ts +20 -0
- package/dist/observability/cost-quota.js +4 -0
- package/dist/observability/cost-taxonomy.d.ts +45 -0
- package/dist/observability/cost-taxonomy.js +34 -0
- package/dist/observability/logger.d.ts +1 -0
- package/dist/observability/logger.js +6 -0
- package/dist/observability/metrics.d.ts +13 -0
- package/dist/observability/metrics.js +63 -0
- package/dist/observability/otel-exporter.d.ts +9 -0
- package/dist/observability/otel-exporter.js +11 -3
- package/dist/observability/principal-context.d.ts +9 -0
- package/dist/observability/principal-context.js +9 -0
- package/dist/observability/prompt-manifest.d.ts +37 -0
- package/dist/observability/prompt-manifest.js +35 -1
- package/dist/observability/rate-limit.d.ts +10 -0
- package/dist/observability/rate-limit.js +1 -0
- package/dist/observability/tool-trace.d.ts +24 -0
- package/dist/observability/tool-trace.js +41 -1
- package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
- package/dist/orchestration/hardened-vm-runner.js +119 -4
- package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
- package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
- package/dist/orchestration/hardened-vm-worker.js +27 -0
- package/dist/orchestration/subagent-steer.d.ts +44 -0
- package/dist/orchestration/subagent-steer.js +45 -1
- package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
- package/dist/orchestration/workflow-agent-steer.js +80 -1
- package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
- package/dist/orchestration/workflow-completion-inbox.js +283 -32
- package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
- package/dist/orchestration/workflow-notify-journal.js +187 -13
- package/dist/parked-decide.d.ts +61 -0
- package/dist/parked-decide.js +58 -1
- package/dist/per-task-image.d.ts +54 -0
- package/dist/per-task-image.js +41 -0
- package/dist/plan-cache-probe.d.ts +35 -0
- package/dist/plan-cache-probe.js +18 -3
- package/dist/plugins/approval-exemption-store.d.ts +7 -0
- package/dist/plugins/approval-exemption-store.js +28 -2
- package/dist/plugins/approval-store-sql.d.ts +64 -0
- package/dist/plugins/approval-store-sql.js +32 -0
- package/dist/plugins/background-agent-store-sql.d.ts +55 -0
- package/dist/plugins/background-agent-store-sql.js +91 -4
- package/dist/plugins/background-shell-support.d.ts +98 -0
- package/dist/plugins/background-shell-support.js +117 -13
- package/dist/plugins/blob-backend.d.ts +104 -0
- package/dist/plugins/blob-backend.js +163 -6
- package/dist/plugins/breaker-state-sql.d.ts +65 -1
- package/dist/plugins/breaker-state-sql.js +46 -8
- package/dist/plugins/caching-session-store.d.ts +42 -0
- package/dist/plugins/caching-session-store.js +63 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
- package/dist/plugins/checkpoint-store-sql.js +239 -11
- package/dist/plugins/file-outcome-sink.d.ts +4 -0
- package/dist/plugins/file-outcome-sink.js +9 -0
- package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
- package/dist/plugins/file-resume-anchor-store.js +43 -4
- package/dist/plugins/file-run-store.d.ts +90 -0
- package/dist/plugins/file-run-store.js +145 -13
- package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
- package/dist/plugins/file-snapshot-store-sql.js +178 -10
- package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
- package/dist/plugins/file-workflow-journal-store.js +10 -0
- package/dist/plugins/fork-routing-session-store.d.ts +47 -0
- package/dist/plugins/fork-routing-session-store.js +51 -3
- package/dist/plugins/host-platform.d.ts +69 -0
- package/dist/plugins/host-platform.js +81 -2
- package/dist/plugins/image-bake-store-sql.d.ts +136 -1
- package/dist/plugins/image-bake-store-sql.js +241 -7
- package/dist/plugins/image-index-sql.d.ts +46 -0
- package/dist/plugins/image-index-sql.js +113 -4
- package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
- package/dist/plugins/k8s-bg-scripts.js +88 -4
- package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
- package/dist/plugins/k8s-exec-protocol.js +41 -0
- package/dist/plugins/local-checkpoint-store.d.ts +40 -0
- package/dist/plugins/local-checkpoint-store.js +86 -7
- package/dist/plugins/local-session-store.d.ts +157 -0
- package/dist/plugins/local-session-store.js +289 -34
- package/dist/plugins/local-task-attachment-store.js +14 -2
- package/dist/plugins/mailbox-store-sql.d.ts +38 -0
- package/dist/plugins/mailbox-store-sql.js +39 -6
- package/dist/plugins/memory-engine-pg.d.ts +30 -0
- package/dist/plugins/memory-engine-pg.js +122 -4
- package/dist/plugins/memory-engine-tidb.d.ts +26 -0
- package/dist/plugins/memory-engine-tidb.js +115 -5
- package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
- package/dist/plugins/memory-engine-vector-util.js +5 -0
- package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
- package/dist/plugins/memory-resume-anchor-store.js +17 -0
- package/dist/plugins/memory-run-store.d.ts +63 -0
- package/dist/plugins/memory-run-store.js +73 -8
- package/dist/plugins/memory-session-policy-store.d.ts +17 -0
- package/dist/plugins/memory-session-policy-store.js +17 -0
- package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
- package/dist/plugins/memory-sync-store-pg.js +45 -2
- package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
- package/dist/plugins/memory-sync-store-tidb.js +31 -1
- package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
- package/dist/plugins/outcome-ledger-sql.js +97 -3
- package/dist/plugins/pg-approval-store.d.ts +7 -0
- package/dist/plugins/pg-approval-store.js +7 -0
- package/dist/plugins/pg-breaker-state.d.ts +6 -0
- package/dist/plugins/pg-breaker-state.js +6 -0
- package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
- package/dist/plugins/pg-checkpoint-store.js +8 -0
- package/dist/plugins/pg-cost-quota.d.ts +17 -0
- package/dist/plugins/pg-cost-quota.js +6 -0
- package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/pg-file-snapshot-store.js +6 -0
- package/dist/plugins/pg-image-bake.d.ts +9 -0
- package/dist/plugins/pg-image-bake.js +9 -0
- package/dist/plugins/pg-image-index.d.ts +9 -0
- package/dist/plugins/pg-image-index.js +9 -0
- package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
- package/dist/plugins/pg-outcome-ledger.js +9 -0
- package/dist/plugins/pg-pool.d.ts +50 -0
- package/dist/plugins/pg-pool.js +78 -0
- package/dist/plugins/pg-query.d.ts +11 -0
- package/dist/plugins/pg-rate-limiter.d.ts +23 -0
- package/dist/plugins/pg-rate-limiter.js +12 -2
- package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/pg-resume-anchor-store.js +5 -0
- package/dist/plugins/pg-run-store.d.ts +7 -0
- package/dist/plugins/pg-run-store.js +7 -0
- package/dist/plugins/pg-safe-json.d.ts +13 -0
- package/dist/plugins/pg-safe-json.js +40 -4
- package/dist/plugins/pg-session-policy-store.d.ts +5 -0
- package/dist/plugins/pg-session-policy-store.js +5 -0
- package/dist/plugins/pg-session-storage.d.ts +72 -0
- package/dist/plugins/pg-session-storage.js +152 -20
- package/dist/plugins/pg-session-store.d.ts +10 -0
- package/dist/plugins/pg-session-store.js +10 -0
- package/dist/plugins/pg-tool-result-store.d.ts +7 -0
- package/dist/plugins/pg-tool-result-store.js +7 -0
- package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-journal-store.js +7 -0
- package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-run-store.js +7 -0
- package/dist/plugins/posix-shell-fs.d.ts +3 -0
- package/dist/plugins/posix-shell-fs.js +31 -1
- package/dist/plugins/remote-env-adb.d.ts +25 -0
- package/dist/plugins/remote-env-adb.js +95 -12
- package/dist/plugins/remote-env-e2b.d.ts +146 -0
- package/dist/plugins/remote-env-e2b.js +371 -40
- package/dist/plugins/remote-env-file-error.d.ts +34 -0
- package/dist/plugins/remote-env-file-error.js +37 -0
- package/dist/plugins/remote-env-host.d.ts +151 -0
- package/dist/plugins/remote-env-host.js +468 -70
- package/dist/plugins/remote-env-k8s.d.ts +135 -0
- package/dist/plugins/remote-env-k8s.js +318 -32
- package/dist/plugins/remote-env-local-docker.d.ts +65 -0
- package/dist/plugins/remote-env-local-docker.js +149 -24
- package/dist/plugins/remote-env-ssh.d.ts +35 -0
- package/dist/plugins/remote-env-ssh.js +117 -20
- package/dist/plugins/remote-scratchpad.d.ts +38 -0
- package/dist/plugins/remote-scratchpad.js +32 -2
- package/dist/plugins/remote-shell.d.ts +22 -0
- package/dist/plugins/remote-shell.js +27 -1
- package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
- package/dist/plugins/resume-anchor-store-sql.js +11 -0
- package/dist/plugins/roster-store-sql.d.ts +27 -0
- package/dist/plugins/roster-store-sql.js +54 -0
- package/dist/plugins/run-store-sql.d.ts +194 -0
- package/dist/plugins/run-store-sql.js +210 -9
- package/dist/plugins/s3-presign.d.ts +20 -0
- package/dist/plugins/s3-presign.js +49 -2
- package/dist/plugins/scheduler-support.d.ts +12 -0
- package/dist/plugins/scheduler-support.js +75 -3
- package/dist/plugins/send-file-ledger.d.ts +15 -0
- package/dist/plugins/send-file-ledger.js +53 -4
- package/dist/plugins/send-user-file.d.ts +77 -0
- package/dist/plugins/send-user-file.js +92 -4
- package/dist/plugins/session-policy-store-sql.d.ts +15 -0
- package/dist/plugins/session-policy-store-sql.js +75 -3
- package/dist/plugins/session-store.d.ts +45 -0
- package/dist/plugins/session-store.js +51 -0
- package/dist/plugins/sql-driver.d.ts +77 -0
- package/dist/plugins/sql-driver.js +4 -0
- package/dist/plugins/sql-escape.d.ts +8 -0
- package/dist/plugins/sql-escape.js +8 -0
- package/dist/plugins/sql-row-helpers.d.ts +25 -0
- package/dist/plugins/sql-row-helpers.js +25 -0
- package/dist/plugins/store-backend.d.ts +103 -0
- package/dist/plugins/store-backend.js +120 -27
- package/dist/plugins/store-contracts.d.ts +62 -0
- package/dist/plugins/store-contracts.js +3 -0
- package/dist/plugins/task-attachment-store.d.ts +60 -0
- package/dist/plugins/task-attachment-store.js +49 -3
- package/dist/plugins/task-list-store-sql.d.ts +25 -0
- package/dist/plugins/task-list-store-sql.js +21 -0
- package/dist/plugins/tidb-approval-store.d.ts +6 -0
- package/dist/plugins/tidb-approval-store.js +6 -0
- package/dist/plugins/tidb-breaker-state.d.ts +5 -0
- package/dist/plugins/tidb-breaker-state.js +5 -0
- package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
- package/dist/plugins/tidb-checkpoint-store.js +7 -0
- package/dist/plugins/tidb-cost-quota.d.ts +6 -0
- package/dist/plugins/tidb-cost-quota.js +1 -0
- package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/tidb-file-snapshot-store.js +6 -0
- package/dist/plugins/tidb-image-bake.d.ts +8 -0
- package/dist/plugins/tidb-image-bake.js +8 -0
- package/dist/plugins/tidb-image-index.d.ts +8 -0
- package/dist/plugins/tidb-image-index.js +8 -0
- package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
- package/dist/plugins/tidb-outcome-ledger.js +10 -0
- package/dist/plugins/tidb-pool.d.ts +56 -0
- package/dist/plugins/tidb-pool.js +181 -1
- package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
- package/dist/plugins/tidb-rate-limiter.js +5 -2
- package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/tidb-resume-anchor-store.js +5 -0
- package/dist/plugins/tidb-run-store.d.ts +7 -0
- package/dist/plugins/tidb-run-store.js +7 -0
- package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
- package/dist/plugins/tidb-session-policy-store.js +5 -0
- package/dist/plugins/tidb-session-storage.d.ts +43 -0
- package/dist/plugins/tidb-session-storage.js +62 -3
- package/dist/plugins/tidb-session-store.d.ts +142 -0
- package/dist/plugins/tidb-session-store.js +264 -16
- package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
- package/dist/plugins/tidb-tool-result-store.js +7 -0
- package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/tidb-workflow-journal-store.js +7 -0
- package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
- package/dist/plugins/tidb-workflow-run-store.js +8 -0
- package/dist/plugins/tool-result-store-sql.d.ts +58 -0
- package/dist/plugins/tool-result-store-sql.js +38 -2
- package/dist/plugins/web-search.d.ts +35 -0
- package/dist/plugins/web-search.js +45 -9
- package/dist/plugins/workflow-journal-limits.d.ts +10 -0
- package/dist/plugins/workflow-journal-limits.js +10 -0
- package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
- package/dist/plugins/workflow-journal-store-sql.js +58 -2
- package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
- package/dist/plugins/workflow-run-store-sql.js +84 -6
- package/dist/plugins/worktree-isolation.d.ts +45 -0
- package/dist/plugins/worktree-isolation.js +105 -6
- package/dist/plugins/write-behind-counter.d.ts +56 -1
- package/dist/plugins/write-behind-counter.js +53 -14
- package/dist/principal-jwt.d.ts +24 -0
- package/dist/principal-jwt.js +60 -5
- package/dist/project-memory.d.ts +22 -0
- package/dist/project-memory.js +144 -15
- package/dist/prompts-domain-validate.d.ts +28 -0
- package/dist/prompts-domain-validate.js +42 -1
- package/dist/question.d.ts +33 -0
- package/dist/question.js +69 -2
- package/dist/resource-suspend.d.ts +21 -0
- package/dist/resource-suspend.js +16 -0
- package/dist/router/route-orchestration.d.ts +78 -0
- package/dist/router/route-orchestration.js +77 -0
- package/dist/run-local.d.ts +32 -0
- package/dist/run-local.js +172 -8
- package/dist/runs.d.ts +189 -4
- package/dist/runs.js +465 -24
- package/dist/runtime-caps-resolver.d.ts +106 -0
- package/dist/runtime-caps-resolver.js +89 -4
- package/dist/runtime-governance.d.ts +84 -0
- package/dist/runtime-governance.js +127 -1
- package/dist/sandbox-pkg-source.d.ts +23 -0
- package/dist/sandbox-pkg-source.js +37 -0
- package/dist/sealed-key.d.ts +54 -0
- package/dist/sealed-key.js +68 -3
- package/dist/security.d.ts +108 -0
- package/dist/security.js +145 -6
- package/dist/sema-registry.d.ts +21 -0
- package/dist/sema-registry.js +21 -0
- package/dist/session-leaf-bus.d.ts +31 -0
- package/dist/session-leaf-bus.js +32 -0
- package/dist/session-sync-content.d.ts +46 -0
- package/dist/session-sync-content.js +47 -1
- package/dist/session-sync-kernel.d.ts +89 -0
- package/dist/session-sync-kernel.js +48 -3
- package/dist/session-sync.d.ts +125 -0
- package/dist/session-sync.js +181 -8
- package/dist/session-titler.d.ts +26 -0
- package/dist/session-titler.js +41 -7
- package/dist/session-watch.d.ts +53 -1
- package/dist/session-watch.js +73 -9
- package/dist/sighup-idle.d.ts +30 -0
- package/dist/sighup-idle.js +12 -1
- package/dist/spec-fields.d.ts +91 -3
- package/dist/spec-fields.js +116 -4
- package/dist/task-cwd.d.ts +50 -0
- package/dist/task-cwd.js +68 -1
- package/dist/task-mcp.d.ts +47 -0
- package/dist/task-mcp.js +29 -0
- package/dist/task-settings.d.ts +175 -0
- package/dist/task-settings.js +226 -11
- package/dist/task-workflow.d.ts +67 -0
- package/dist/task-workflow.js +75 -8
- package/dist/tool-approval.d.ts +91 -0
- package/dist/tool-approval.js +215 -0
- package/dist/trace/artifacts.d.ts +9 -0
- package/dist/trace/artifacts.js +30 -5
- package/dist/trace/core-keyset-guard.d.ts +18 -0
- package/dist/trace/ledger-sink.d.ts +43 -0
- package/dist/trace/ledger-sink.js +64 -5
- package/dist/trace/project.d.ts +133 -0
- package/dist/trace/project.js +189 -2
- package/dist/trace/redact.d.ts +19 -0
- package/dist/trace/redact.js +66 -9
- package/dist/usage-analytics.d.ts +26 -0
- package/dist/usage-analytics.js +26 -3
- package/package.json +1 -1
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bake input WHITELIST + vetted-argv builder (IMAGE-API-DESIGN.md §P2.4 — the anti-RCE core).
|
|
3
|
+
*
|
|
4
|
+
* bands/profile/baseRef/bump compose a Dockerfile + a `FROM` + a `docker build` = arbitrary code on the build
|
|
5
|
+
* host. So EVERY field is validated SERVER-SIDE against a CLOSED SET *before* an argv is built; off-list → an
|
|
6
|
+
* error, never coerced. The runner only ever sees the VETTED argv this module emits (never operator free-text)
|
|
7
|
+
* and only runs `build.sh`, which composes Dockerfiles from the in-repo `bands/` via `gen-dockerfile.sh` — there
|
|
8
|
+
* is no path here to inject a raw Dockerfile or a shell command.
|
|
9
|
+
*
|
|
10
|
+
* Set membership is the gate (NOT regex): `^[a-z0-9-]+$` is belt-only — `python; rm -rf /` ∉ the frozen set →
|
|
11
|
+
* rejected, and the argv is a RAW vetted VECTOR the runner array-spawns (each element in its own argv slot, no
|
|
12
|
+
* shell), never concatenated into a command string.
|
|
13
|
+
*
|
|
14
|
+
* The frozen catalogs below MIRROR the recipe source of truth (`gen-dockerfile.sh` `profile_bands()` + the
|
|
15
|
+
* `bands/` dir). A DRIFT test (test/image-bake-validate.test.ts) asserts they still match — a silently-drifted
|
|
16
|
+
* list would either reject a valid profile or admit a removed band. Keep them in lockstep with the recipes.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* FROZEN profile catalog — mirrored from `e2b-template/dev-sandbox/gen-dockerfile.sh` `profile_bands()`.
|
|
20
|
+
* (db / browser-nodriver are opt-in overlays, NOT in `code-full` — `code-full-db` adds db; per design §4.)
|
|
21
|
+
*/
|
|
1
22
|
export const FROZEN_PROFILES = [
|
|
2
23
|
"code-python",
|
|
3
24
|
"code-node",
|
|
@@ -19,6 +40,7 @@ export const FROZEN_PROFILES = [
|
|
|
19
40
|
"code-full",
|
|
20
41
|
"code-full-db",
|
|
21
42
|
];
|
|
43
|
+
/** FROZEN band set — mirrored from the `e2b-template/dev-sandbox/bands/` directory (one dir per band). */
|
|
22
44
|
export const FROZEN_BANDS = [
|
|
23
45
|
"python",
|
|
24
46
|
"node",
|
|
@@ -40,6 +62,11 @@ export const FROZEN_BANDS = [
|
|
|
40
62
|
"browser-nodriver",
|
|
41
63
|
"db",
|
|
42
64
|
];
|
|
65
|
+
/**
|
|
66
|
+
* FROZEN bump-tool set — the toolchain identifiers a `--bump <tool>=<ver>` may target. Conservative union of the
|
|
67
|
+
* version-overridable toolchains the bands accept (`<TOOL>_VERSION` env, build.sh forwards `--bump tool=ver`).
|
|
68
|
+
* Set-membership is the gate; the value is range-checked by VER_RE. Off-list tool → 400 (never coerced).
|
|
69
|
+
*/
|
|
43
70
|
export const FROZEN_BUMP_TOOLS = [
|
|
44
71
|
"node",
|
|
45
72
|
"python",
|
|
@@ -58,15 +85,30 @@ export const FROZEN_BUMP_TOOLS = [
|
|
|
58
85
|
const PROFILE_SET = new Set(FROZEN_PROFILES);
|
|
59
86
|
const BAND_SET = new Set(FROZEN_BANDS);
|
|
60
87
|
const BUMP_TOOL_SET = new Set(FROZEN_BUMP_TOOLS);
|
|
88
|
+
/** Bump value range (P2.4d): printable version-ish tokens only, ≤40 chars — folds into the lockhash. */
|
|
61
89
|
export const VER_RE = /^[A-Za-z0-9._-]{1,40}$/;
|
|
90
|
+
/** Belt-only band shape (set-membership is the real gate); a defense-in-depth reject of structurally weird ids. */
|
|
62
91
|
export const BAND_SHAPE_RE = /^[a-z0-9-]+$/;
|
|
92
|
+
/** A digest must be an immutable sha256 ref (the allow-list check against the index is the real gate, P2.4c). */
|
|
63
93
|
export const DIGEST_RE = /^sha256:[a-f0-9]{64}$/;
|
|
64
94
|
function reject(status, error, conflictBands) {
|
|
65
95
|
return conflictBands ? { ok: false, status, error, conflictBands } : { ok: false, status, error };
|
|
66
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Validate + normalize a `POST /v1/images/bakes` body into a vetted argv, or a typed rejection.
|
|
99
|
+
*
|
|
100
|
+
* Order is deliberate: profile XOR bands → bands set-membership (dupes/empties/shape) → bump set+range →
|
|
101
|
+
* baseRef shape (the index allow-list check is done by the caller via `baseRefAllowed`, async) → build the
|
|
102
|
+
* raw vetted argv. The output repo is server-fixed (`sema-images/<profile>`); the caller CANNOT set
|
|
103
|
+
* `--tag` (build.sh auto-computes the immutable tag — kills namespace-squat) nor an arbitrary `FROM`.
|
|
104
|
+
*
|
|
105
|
+
* `baseRefAllowed` is checked HERE for shape only; the digest-in-index allow-list is the caller's async step
|
|
106
|
+
* (it owns the TiDB index). A present-but-malformed `baseRef` is rejected before any DB hit.
|
|
107
|
+
*/
|
|
67
108
|
export function validateBake(body) {
|
|
68
109
|
const hasProfile = body.profile !== undefined && body.profile !== null && body.profile !== "";
|
|
69
110
|
const hasBands = body.bands !== undefined && body.bands !== null;
|
|
111
|
+
// profile XOR bands — exactly one required.
|
|
70
112
|
if (hasProfile && hasBands)
|
|
71
113
|
return reject(400, "provide profile OR bands, not both");
|
|
72
114
|
if (!hasProfile && !hasBands)
|
|
@@ -85,6 +127,7 @@ export function validateBake(body) {
|
|
|
85
127
|
return reject(400, "bands must be an array of band ids");
|
|
86
128
|
if (body.bands.length === 0)
|
|
87
129
|
return reject(400, "bands must be a non-empty array");
|
|
130
|
+
// Cap length at the all-bands count — a longer list can only be dupes/garbage.
|
|
88
131
|
if (body.bands.length > FROZEN_BANDS.length)
|
|
89
132
|
return reject(400, `at most ${FROZEN_BANDS.length} bands`);
|
|
90
133
|
const seen = new Set();
|
|
@@ -97,18 +140,21 @@ export function validateBake(body) {
|
|
|
97
140
|
if (seen.has(raw))
|
|
98
141
|
return reject(400, `duplicate band '${raw}'`);
|
|
99
142
|
seen.add(raw);
|
|
143
|
+
// "custom"/tenant bands are a P4 affordance → 501 (not a 400) so the UI distinguishes "not yet" from "bad".
|
|
100
144
|
if (!BAND_SET.has(raw))
|
|
101
145
|
offList.push(raw);
|
|
102
146
|
}
|
|
103
147
|
if (offList.length > 0) {
|
|
148
|
+
// An off-list band that is the reserved tenant marker routes to P4; any other off-list id is an unknown band.
|
|
104
149
|
if (offList.includes("custom")) {
|
|
105
150
|
return reject(501, "custom/tenant bake is P4");
|
|
106
151
|
}
|
|
107
152
|
return reject(400, `unknown band(s): ${offList.join(", ")}`, offList);
|
|
108
153
|
}
|
|
109
154
|
bands = body.bands;
|
|
110
|
-
profile = "custom";
|
|
155
|
+
profile = "custom"; // build.sh records profile="custom" for --bands; the argv carries --bands, not --profile.
|
|
111
156
|
}
|
|
157
|
+
// bump — {tool:ver}: tool ∈ FROZEN_BUMP_TOOLS, ver ∈ VER_RE. Off-list/range → 400.
|
|
112
158
|
let bump = null;
|
|
113
159
|
if (body.bump !== undefined && body.bump !== null) {
|
|
114
160
|
if (typeof body.bump !== "object" || Array.isArray(body.bump)) {
|
|
@@ -125,6 +171,8 @@ export function validateBake(body) {
|
|
|
125
171
|
}
|
|
126
172
|
bump = Object.keys(out).length > 0 ? out : null;
|
|
127
173
|
}
|
|
174
|
+
// baseRef — caller CANNOT pass an arbitrary FROM. Shape-check here (the index allow-list is the caller's async
|
|
175
|
+
// step). Default = the pinned current base, injected by the caller when baseRef is absent.
|
|
128
176
|
let baseRef = null;
|
|
129
177
|
if (body.baseRef !== undefined && body.baseRef !== null && body.baseRef !== "") {
|
|
130
178
|
if (typeof body.baseRef !== "string" || !DIGEST_RE.test(body.baseRef)) {
|
|
@@ -135,6 +183,7 @@ export function validateBake(body) {
|
|
|
135
183
|
const push = body.push === true;
|
|
136
184
|
const dryRun = body.dryRun === true;
|
|
137
185
|
const logs = body.logs === true;
|
|
186
|
+
// pkgSource — RFC B4 closed set (cn|global); off-list → 400, never coerced (same discipline as every field).
|
|
138
187
|
let pkgSource = null;
|
|
139
188
|
if (body.pkgSource !== undefined && body.pkgSource !== null && body.pkgSource !== "") {
|
|
140
189
|
if (body.pkgSource !== "cn" && body.pkgSource !== "global") {
|
|
@@ -152,9 +201,25 @@ export function validateBake(body) {
|
|
|
152
201
|
dryRun,
|
|
153
202
|
logs,
|
|
154
203
|
pkgSource,
|
|
204
|
+
// argv is built by the caller AFTER it resolves the effective baseRef (the index allow-list + default base).
|
|
155
205
|
argv: [],
|
|
156
206
|
};
|
|
157
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Build the VETTED, NORMALIZED build.sh argv from an accepted validation + the caller-resolved effective fields
|
|
210
|
+
* (the index-checked baseRef and the build-host CACHE_BASE — both runner-environment facts image-api injects,
|
|
211
|
+
* never operator free-text). The elements are RAW (no shell-quoting): the runner array-spawns build.sh so each
|
|
212
|
+
* element lands in its own argv slot (no shell can re-interpret a frozen-set value). The runner runs
|
|
213
|
+
* `build.sh <argv...>` and ONLY this.
|
|
214
|
+
*
|
|
215
|
+
* Server-fixed invariants enforced here (NOT caller-settable, P2.4d):
|
|
216
|
+
* - `--json` always (machine output the runner parses).
|
|
217
|
+
* - selection is `--profile <p>` XOR `--bands a,b,c` (already vetted).
|
|
218
|
+
* - NO `--tag` (build.sh auto-computes the immutable tag — kills namespace-squat / overwrite-by-naming).
|
|
219
|
+
* - the output repo is server-fixed `sema-images/<profile>` (build.sh's IMAGE_PREFIX default; not forwarded).
|
|
220
|
+
* - `--base-ref` is the index-checked effective base (caller resolves the default when absent).
|
|
221
|
+
* - `--cache-base` is the build-host promoted cache (runner env).
|
|
222
|
+
*/
|
|
158
223
|
export function buildBakeArgv(v, effective) {
|
|
159
224
|
const args = [];
|
|
160
225
|
if (v.bands && v.bands.length > 0) {
|
|
@@ -178,6 +243,11 @@ export function buildBakeArgv(v, effective) {
|
|
|
178
243
|
if (v.dryRun)
|
|
179
244
|
args.push("--dry-run");
|
|
180
245
|
args.push("--json");
|
|
246
|
+
// Return the RAW vetted vector. Set-membership against FROZEN_PROFILES/BANDS/BUMP_TOOLS is the RCE gate; the
|
|
247
|
+
// runner array-spawns build.sh with each element in its own argv slot (no shell), so a frozen-set value can
|
|
248
|
+
// never be re-interpreted by a shell. Shell-quoting here would embed literal single-quotes into each slot →
|
|
249
|
+
// build.sh sees `'--profile'` (quotes included) and dies "unknown arg" on the first one (H2). Quoting is wrong
|
|
250
|
+
// for an array-spawn boundary; the injection boundary is the array slot, not a joined command string.
|
|
181
251
|
return args;
|
|
182
252
|
}
|
|
183
253
|
//# sourceMappingURL=bake-validate.js.map
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* build.sh manifest → image-index projection (IMAGE-API-DESIGN.md §1/§3, pool design §6).
|
|
3
|
+
*
|
|
4
|
+
* `sandbox-manifest.json` is the replay-sufficient build record; the index row is its queryable projection +
|
|
5
|
+
* the push-time facts (registry repo + runtime digest). This module is the SINGLE pure mapping used by both the
|
|
6
|
+
* one-time seed and the P3 atomic-publish pipeline — kept side-effect-free so it is unit-tested without a DB.
|
|
7
|
+
*/
|
|
1
8
|
import type { ImageIndexUpsert, ImageNestedBuildMode, ImageStatus } from "../plugins/store-contracts.js";
|
|
9
|
+
/** Project the manifest's `nestedBuild` (string posture OR bool) → the enum (center contract). */
|
|
2
10
|
export declare function nestedBuildModeOf(v: string | boolean | undefined): ImageNestedBuildMode;
|
|
11
|
+
/** The fields of build.sh's `sandbox-manifest.json` this projection reads (a superset is fine; extras ignored). */
|
|
3
12
|
export interface BuildManifest {
|
|
13
|
+
/** "custom" for `--bands` builds; the real profile is then the tag's repo part. */
|
|
4
14
|
profile?: string;
|
|
5
15
|
bands?: string[];
|
|
16
|
+
/** e.g. "code-flutter:dev-20260619". */
|
|
6
17
|
tag?: string;
|
|
7
18
|
digest?: string;
|
|
8
19
|
generatorVersion?: string;
|
|
@@ -22,15 +33,23 @@ export interface BuildManifest {
|
|
|
22
33
|
visibility?: string;
|
|
23
34
|
sizeBytes?: number;
|
|
24
35
|
}
|
|
36
|
+
/** The push-time facts the manifest cannot know (the registry repo + the runtime-pinned digest + lifecycle). */
|
|
25
37
|
export interface ManifestProjectOpts {
|
|
38
|
+
/** Registry repo the digest lives in, e.g. "docker.io/claybobby/code-flutter" (historically SWR — deprecated). */
|
|
26
39
|
repo: string;
|
|
40
|
+
/** Runtime-pinned digest (the registry RepoDigest after push); falls back to the manifest digest pre-push. */
|
|
27
41
|
digest?: string;
|
|
42
|
+
/** Lifecycle status to register with (default "published" — the seed runs post-verify). */
|
|
28
43
|
status?: ImageStatus;
|
|
44
|
+
/** sha256 of the manifest blob (the replay anchor). */
|
|
29
45
|
manifestSha?: string | null;
|
|
30
46
|
sizeBytes?: number | null;
|
|
31
47
|
signed?: boolean;
|
|
32
48
|
}
|
|
49
|
+
/** Parse a docker-style size ("64m" / "512M" / "1g") → MB. Undefined on an unparseable / absent value. */
|
|
33
50
|
export declare function shmToMB(v: string | undefined): number | undefined;
|
|
51
|
+
/** --bands builds record profile="custom", so the tag's repo part ("code-flutter:tag" → "code-flutter") wins. */
|
|
34
52
|
export declare function profileFromManifest(m: BuildManifest): string;
|
|
53
|
+
/** Pure projection: a build.sh manifest + the push-time facts → an index upsert. */
|
|
35
54
|
export declare function manifestToIndexEntry(m: BuildManifest, opts: ManifestProjectOpts): ImageIndexUpsert;
|
|
36
55
|
//# sourceMappingURL=manifest.d.ts.map
|
package/dist/images/manifest.js
CHANGED
|
@@ -4,16 +4,18 @@ const NESTED_BUILD_MODES = [
|
|
|
4
4
|
"rootless-buildkit",
|
|
5
5
|
"privileged-dind",
|
|
6
6
|
];
|
|
7
|
+
/** Project the manifest's `nestedBuild` (string posture OR bool) → the enum (center contract). */
|
|
7
8
|
export function nestedBuildModeOf(v) {
|
|
8
9
|
if (typeof v === "string") {
|
|
9
10
|
return NESTED_BUILD_MODES.includes(v)
|
|
10
11
|
? v
|
|
11
12
|
: v
|
|
12
|
-
? "rootless-buildkit"
|
|
13
|
+
? "rootless-buildkit" // an unknown non-empty posture is treated as the safe default the pool uses
|
|
13
14
|
: "none";
|
|
14
15
|
}
|
|
15
16
|
return v ? "rootless-buildkit" : "none";
|
|
16
17
|
}
|
|
18
|
+
/** Parse a docker-style size ("64m" / "512M" / "1g") → MB. Undefined on an unparseable / absent value. */
|
|
17
19
|
export function shmToMB(v) {
|
|
18
20
|
if (!v)
|
|
19
21
|
return undefined;
|
|
@@ -23,12 +25,14 @@ export function shmToMB(v) {
|
|
|
23
25
|
const n = Number(m[1]);
|
|
24
26
|
return (m[2] ?? "m").toLowerCase() === "g" ? n * 1024 : n;
|
|
25
27
|
}
|
|
28
|
+
/** --bands builds record profile="custom", so the tag's repo part ("code-flutter:tag" → "code-flutter") wins. */
|
|
26
29
|
export function profileFromManifest(m) {
|
|
27
30
|
if (m.profile && m.profile !== "custom")
|
|
28
31
|
return m.profile;
|
|
29
32
|
const repo = (m.tag ?? "").split(":")[0] ?? "";
|
|
30
33
|
return repo || m.profile || "custom";
|
|
31
34
|
}
|
|
35
|
+
/** Pure projection: a build.sh manifest + the push-time facts → an index upsert. */
|
|
32
36
|
export function manifestToIndexEntry(m, opts) {
|
|
33
37
|
const profile = profileFromManifest(m);
|
|
34
38
|
const tag = (m.tag ?? "").includes(":") ? (m.tag ?? "").split(":")[1] : (m.tag ?? "");
|
|
@@ -57,6 +61,7 @@ export function manifestToIndexEntry(m, opts) {
|
|
|
57
61
|
sizeBytes: opts.sizeBytes ?? m.sizeBytes ?? null,
|
|
58
62
|
status: opts.status ?? "published",
|
|
59
63
|
visibility,
|
|
64
|
+
// a tenant image carries its owner; the standard pool's "standard-pool" owner is NOT a tenant.
|
|
60
65
|
tenantId: visibility === "tenant" && m.owner && m.owner !== "standard-pool" ? m.owner : null,
|
|
61
66
|
manifestSha: opts.manifestSha ?? null,
|
|
62
67
|
recipeGitSha: m.recipeGitSha && m.recipeGitSha !== "nogit" ? m.recipeGitSha : null,
|
package/dist/index.d.ts
CHANGED
|
@@ -2,14 +2,10 @@ export { loadConfig, type ServiceConfig } from "./config.js";
|
|
|
2
2
|
export { createBrain } from "./brain.js";
|
|
3
3
|
export { createSessionStore } from "./plugins/session-store.js";
|
|
4
4
|
export { createStoreBackend, type StoreBackend } from "./plugins/store-backend.js";
|
|
5
|
-
export { createTidbPool, ensureSchema, SCHEMA_STATEMENTS, } from "./plugins/tidb-pool.js";
|
|
6
|
-
export { TiDBSessionStore } from "./plugins/tidb-session-store.js";
|
|
7
|
-
export { TiDBSessionStorage } from "./plugins/tidb-session-storage.js";
|
|
8
5
|
export { CachingSessionStore, type CachingOptions } from "./plugins/caching-session-store.js";
|
|
9
|
-
export { TiDBRunStore } from "./plugins/tidb-run-store.js";
|
|
10
6
|
export type { RunRecord, RunEvent } from "./plugins/store-contracts.js";
|
|
11
7
|
export { runInBackground } from "./runs.js";
|
|
12
|
-
export {
|
|
8
|
+
export { type ApprovalRow, type ApprovalStatus } from "./plugins/approval-store-sql.js";
|
|
13
9
|
export { createOaApprovalPolicy, type OaApprovalOptions } from "./approval.js";
|
|
14
10
|
export { createHardenedVmRunner, runInHardenedVm, type HardenedVmLimits, type HardenedMembrane } from "./orchestration/hardened-vm-runner.js";
|
|
15
11
|
export { createWorkerHardenedVmRunner } from "./orchestration/hardened-vm-worker-runner.js";
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
// Library surface (for embedding the service wiring in another Node app — e.g. the shell's seamless local mode
|
|
2
|
+
// runs the sema-server HTTP wire in-process via createHttpServer + a local StoreBackend).
|
|
1
3
|
export { loadConfig } from "./config.js";
|
|
2
4
|
export { createBrain } from "./brain.js";
|
|
3
5
|
export { createSessionStore } from "./plugins/session-store.js";
|
|
6
|
+
// design/158 B5-①([1971] 声明后落):中立后端缝 —— 嵌入姿势(见顶注)= createHttpServer + StoreBackend。
|
|
4
7
|
export { createStoreBackend } from "./plugins/store-backend.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
// ── B5-②(clay 两拍终裁 2026-07-30:cli/core 零消费,弃用窗撤销直接删)——6 个 TiDB 方言专属导出已摘 ──
|
|
9
|
+
// 判据:①backend-可插铁律(公面即承诺,方言类在公面=邀请绕过中立缝直连方言);②公面瘸腿(PG 孪生
|
|
10
|
+
// 从未导出);③全生态扫描零消费。替代:构造走 createStoreBackend(kind mysql|pg|local),DDL 审阅走
|
|
11
|
+
// docs/schema/baseline-{mysql,pg}.sql(生成基线,机器门逐字节)。类/函数本体仍是内部实现(深径 import)。
|
|
8
12
|
export { CachingSessionStore } from "./plugins/caching-session-store.js";
|
|
9
|
-
export { TiDBRunStore } from "./plugins/tidb-run-store.js";
|
|
10
13
|
export { runInBackground } from "./runs.js";
|
|
11
|
-
|
|
14
|
+
// B5-② 补漏:TiDBApprovalStore 是证据包漏数的第 7 个方言导出,同判据同车摘(全生态零消费);
|
|
15
|
+
// 两个中立行类型改从 A12 后的真源(approval-store-sql.ts)导出。
|
|
16
|
+
export {} from "./plugins/approval-store-sql.js";
|
|
12
17
|
export { createOaApprovalPolicy } from "./approval.js";
|
|
13
18
|
export { createHardenedVmRunner, runInHardenedVm } from "./orchestration/hardened-vm-runner.js";
|
|
14
19
|
export { createWorkerHardenedVmRunner } from "./orchestration/hardened-vm-worker-runner.js";
|
package/dist/key-resolver.d.ts
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
import type { Model } from "@sema-agent/core";
|
|
2
2
|
import { type SealedKeyPoison } from "./sealed-key.js";
|
|
3
|
+
/**
|
|
4
|
+
* Build a per-model API-key resolver for `TaskSpec.getApiKeyAndHeaders` from the catalog's
|
|
5
|
+
* name → env-var-NAME map (sema-registry `apiKeyEnv`). core threads this per brain call — and per cascade
|
|
6
|
+
* rung — so each model/rung authenticates with its OWN upstream account/key.
|
|
7
|
+
*
|
|
8
|
+
* Additive by construction: a model absent from the map — or whose env var is unset — returns
|
|
9
|
+
* `undefined`, so core falls back to the brain's construction-time gateway key (today's behavior, no
|
|
10
|
+
* regression). When no per-model keys are configured at all this returns `undefined`, leaving the spec
|
|
11
|
+
* field unset so core's default path is byte-for-byte unchanged.
|
|
12
|
+
*
|
|
13
|
+
* Only the api KEY is per-model; the base URL stays brain-owned (design/15) — core's seam carries
|
|
14
|
+
* `{ apiKey, headers? }`, not a baseUrl. Same-account-rotation could round-robin inside this function.
|
|
15
|
+
*
|
|
16
|
+
* `modelApiKeys` (sealed-box custody) carries per-model entries unsealed from `ModelEntry.sealedApiKey` —
|
|
17
|
+
* resolved FIRST (sealed outranks the env-NAME reference, the registry-core mutual-exclusion ruling). Each
|
|
18
|
+
* entry is either the PLAINTEXT key (successful unseal) or a `SealedKeyPoison` marker (unseal FAILED at
|
|
19
|
+
* apply time): a poisoned model THROWS `SealedKeyPoisonedError` on every resolve — task-level fail-loud —
|
|
20
|
+
* because returning `undefined` here means "use the gateway key", and a broken sealed key must NEVER
|
|
21
|
+
* silently burn the shared gateway account (the core invariant of the poison-pill fix; a poisoned model
|
|
22
|
+
* skips its env reference too, same mutual-exclusion as a healthy sealed key). The maps are disjoint by
|
|
23
|
+
* construction in applyEffective (a sealed model never lands in modelApiKeyEnv); the ordering here is
|
|
24
|
+
* belt-and-suspenders. 🔴 Plaintext values are live secrets: memory-only, never log them.
|
|
25
|
+
*/
|
|
3
26
|
export declare function createKeyResolver(modelApiKeyEnv: Record<string, string>, env?: NodeJS.ProcessEnv, modelApiKeys?: Record<string, string | SealedKeyPoison>): ((model: Model) => Promise<{
|
|
4
27
|
apiKey: string;
|
|
5
28
|
} | undefined>) | undefined;
|
package/dist/key-resolver.js
CHANGED
|
@@ -1,16 +1,41 @@
|
|
|
1
1
|
import { isSealedKeyPoison, SealedKeyPoisonedError } from "./sealed-key.js";
|
|
2
|
+
/**
|
|
3
|
+
* Build a per-model API-key resolver for `TaskSpec.getApiKeyAndHeaders` from the catalog's
|
|
4
|
+
* name → env-var-NAME map (sema-registry `apiKeyEnv`). core threads this per brain call — and per cascade
|
|
5
|
+
* rung — so each model/rung authenticates with its OWN upstream account/key.
|
|
6
|
+
*
|
|
7
|
+
* Additive by construction: a model absent from the map — or whose env var is unset — returns
|
|
8
|
+
* `undefined`, so core falls back to the brain's construction-time gateway key (today's behavior, no
|
|
9
|
+
* regression). When no per-model keys are configured at all this returns `undefined`, leaving the spec
|
|
10
|
+
* field unset so core's default path is byte-for-byte unchanged.
|
|
11
|
+
*
|
|
12
|
+
* Only the api KEY is per-model; the base URL stays brain-owned (design/15) — core's seam carries
|
|
13
|
+
* `{ apiKey, headers? }`, not a baseUrl. Same-account-rotation could round-robin inside this function.
|
|
14
|
+
*
|
|
15
|
+
* `modelApiKeys` (sealed-box custody) carries per-model entries unsealed from `ModelEntry.sealedApiKey` —
|
|
16
|
+
* resolved FIRST (sealed outranks the env-NAME reference, the registry-core mutual-exclusion ruling). Each
|
|
17
|
+
* entry is either the PLAINTEXT key (successful unseal) or a `SealedKeyPoison` marker (unseal FAILED at
|
|
18
|
+
* apply time): a poisoned model THROWS `SealedKeyPoisonedError` on every resolve — task-level fail-loud —
|
|
19
|
+
* because returning `undefined` here means "use the gateway key", and a broken sealed key must NEVER
|
|
20
|
+
* silently burn the shared gateway account (the core invariant of the poison-pill fix; a poisoned model
|
|
21
|
+
* skips its env reference too, same mutual-exclusion as a healthy sealed key). The maps are disjoint by
|
|
22
|
+
* construction in applyEffective (a sealed model never lands in modelApiKeyEnv); the ordering here is
|
|
23
|
+
* belt-and-suspenders. 🔴 Plaintext values are live secrets: memory-only, never log them.
|
|
24
|
+
*/
|
|
2
25
|
export function createKeyResolver(modelApiKeyEnv, env = process.env, modelApiKeys = {}) {
|
|
3
26
|
if (Object.keys(modelApiKeyEnv).length === 0 && Object.keys(modelApiKeys).length === 0)
|
|
4
27
|
return undefined;
|
|
5
28
|
return async (model) => {
|
|
6
29
|
const sealed = modelApiKeys[model.name];
|
|
30
|
+
// Poison pill: the operator configured a sealed key for this model but it cannot be unsealed —
|
|
31
|
+
// fail the brain call LOUD (never undefined = never the gateway fallback).
|
|
7
32
|
if (isSealedKeyPoison(sealed))
|
|
8
33
|
throw new SealedKeyPoisonedError(model.name, sealed);
|
|
9
34
|
if (sealed)
|
|
10
|
-
return { apiKey: sealed };
|
|
35
|
+
return { apiKey: sealed }; // sealed-box custody wins (registry-core: sealed 压过 apiKeyEnv)
|
|
11
36
|
const envName = modelApiKeyEnv[model.name];
|
|
12
37
|
if (!envName)
|
|
13
|
-
return undefined;
|
|
38
|
+
return undefined; // model has no per-model key → core uses the gateway key
|
|
14
39
|
const apiKey = env[envName];
|
|
15
40
|
return apiKey ? { apiKey } : undefined;
|
|
16
41
|
};
|
package/dist/leader/diffout.d.ts
CHANGED
|
@@ -1,12 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2 MVP M2 — diff-OUT-of-container (design/50 §7 solution (b), V2-MVP-PLAN.md, findings F1/F3, council#1/#13/#14).
|
|
3
|
+
*
|
|
4
|
+
* The Coordinator pulls a worker's commits as a patch series over `execStream` `git format-patch --stdout` —
|
|
5
|
+
* the diff comes OUT of the worker container, **no push credentials ever go IN** (preserves §5/F3 isolation).
|
|
6
|
+
* The patch then feeds the ephemeral no-creds integration sandbox (M3) via `git am`/`git apply`.
|
|
7
|
+
*
|
|
8
|
+
* Council round-1 folded:
|
|
9
|
+
* - #14: `--stdout` (else format-patch writes .patch FILES and prints only filenames to stdout).
|
|
10
|
+
* - #13 + maxOutputBytes: fail-on-truncation — a runaway diff must NOT be silently half-captured.
|
|
11
|
+
* - exit-code: non-zero `git` → failure (the worker branch / base is bad), surfaced not swallowed.
|
|
12
|
+
* - ref validation: baseSha/ref are interpolated into a shell command in the container; reject anything that
|
|
13
|
+
* isn't a safe git rev token so a worker-influenced value can't inject.
|
|
14
|
+
*/
|
|
1
15
|
import type { OutputChunk, ExecStreamOptions } from "@sema-agent/core";
|
|
16
|
+
/** Only the one method M2 consumes from the remote env (the real RemoteExecutionEnv satisfies it). */
|
|
2
17
|
export interface ExecStreamLike {
|
|
3
18
|
execStream(command: string, options?: ExecStreamOptions): AsyncIterable<OutputChunk>;
|
|
4
19
|
}
|
|
5
20
|
export interface PullDiffOptions {
|
|
21
|
+
/** Worker branch / rev to diff up to (default HEAD — the worker container's checked-out work). */
|
|
6
22
|
ref?: string;
|
|
23
|
+
/** Repo dir inside the container (execStream cwd). */
|
|
7
24
|
cwd?: string;
|
|
25
|
+
/** Fail-on-truncation cap (bytes). Default 5 MiB. */
|
|
8
26
|
maxBytes?: number;
|
|
9
27
|
signal?: AbortSignal;
|
|
28
|
+
/** Idle read timeout (E2B #1128 — never hang on an unreachable sandbox). Default 30s. */
|
|
10
29
|
readTimeoutMs?: number;
|
|
11
30
|
}
|
|
12
31
|
export type PullDiffResult = {
|
|
@@ -20,5 +39,9 @@ export type PullDiffResult = {
|
|
|
20
39
|
exitCode?: number;
|
|
21
40
|
};
|
|
22
41
|
export declare function safeRev(rev: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Pull `<baseSha>..<ref>` from a worker container as a `git format-patch` series. Never throws — failures
|
|
44
|
+
* (bad rev, non-zero git, truncation, transport loss, empty diff) are returned as `{ ok: false }`.
|
|
45
|
+
*/
|
|
23
46
|
export declare function pullDiff(env: ExecStreamLike, baseSha: string, opts?: PullDiffOptions): Promise<PullDiffResult>;
|
|
24
47
|
//# sourceMappingURL=diffout.d.ts.map
|
package/dist/leader/diffout.js
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
const DEFAULT_MAX_DIFF_BYTES = 5 * 1024 * 1024;
|
|
2
2
|
const DEFAULT_READ_TIMEOUT_MS = 30_000;
|
|
3
|
+
/** A safe git rev token: sha, branch/tag name, or `A..B`. No shell metacharacters, no leading dash. */
|
|
3
4
|
const SAFE_REV = /^[A-Za-z0-9._/-]{1,200}$/;
|
|
4
5
|
export function safeRev(rev) {
|
|
5
6
|
return SAFE_REV.test(rev) && !rev.startsWith("-") && !rev.includes("..--");
|
|
6
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Pull `<baseSha>..<ref>` from a worker container as a `git format-patch` series. Never throws — failures
|
|
10
|
+
* (bad rev, non-zero git, truncation, transport loss, empty diff) are returned as `{ ok: false }`.
|
|
11
|
+
*/
|
|
7
12
|
export async function pullDiff(env, baseSha, opts = {}) {
|
|
8
13
|
const ref = opts.ref ?? "HEAD";
|
|
9
14
|
if (!safeRev(baseSha) || !safeRev(ref)) {
|
|
10
15
|
return { ok: false, error: `unsafe git rev (baseSha=${JSON.stringify(baseSha)} ref=${JSON.stringify(ref)})` };
|
|
11
16
|
}
|
|
12
17
|
const maxBytes = opts.maxBytes ?? DEFAULT_MAX_DIFF_BYTES;
|
|
18
|
+
// --stdout (council#14): emit the whole series to stdout, not .patch files. Newest-last (default order).
|
|
13
19
|
const cmd = `git format-patch --stdout ${baseSha}..${ref}`;
|
|
14
20
|
let patch = "";
|
|
15
21
|
let bytes = 0;
|
|
@@ -18,7 +24,7 @@ export async function pullDiff(env, baseSha, opts = {}) {
|
|
|
18
24
|
try {
|
|
19
25
|
for await (const chunk of env.execStream(cmd, {
|
|
20
26
|
...(opts.cwd ? { cwd: opts.cwd } : {}),
|
|
21
|
-
maxOutputBytes: maxBytes + 1,
|
|
27
|
+
maxOutputBytes: maxBytes + 1, // +1 so we can DETECT the overflow (council#13 fail-on-truncation)
|
|
22
28
|
readTimeoutMs: opts.readTimeoutMs ?? DEFAULT_READ_TIMEOUT_MS,
|
|
23
29
|
...(opts.signal ? { signal: opts.signal } : {}),
|
|
24
30
|
})) {
|
|
@@ -38,6 +44,7 @@ export async function pullDiff(env, baseSha, opts = {}) {
|
|
|
38
44
|
}
|
|
39
45
|
}
|
|
40
46
|
catch (e) {
|
|
47
|
+
// execStream throws on transport loss / suspendVM-aborted in-flight command (no exit chunk).
|
|
41
48
|
return { ok: false, error: `execStream failed before exit: ${e instanceof Error ? e.message : String(e)}` };
|
|
42
49
|
}
|
|
43
50
|
if (exitCode === undefined) {
|
package/dist/leader/diffup.d.ts
CHANGED
|
@@ -1,14 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/68 §8 F2(a) — worker SELF-UPLOAD diff-out (the factory-env counterpart of diffout.ts's pullDiff).
|
|
3
|
+
*
|
|
4
|
+
* With a factory env the runner owns the container lifecycle (create at task start, destroy at finish — and
|
|
5
|
+
* durable suspend only produces a complete ownedEnv on this path), so the leader can no longer pull the diff
|
|
6
|
+
* from a still-alive env after the task. Instead (the gate#2-proven MinIO presigned pattern):
|
|
7
|
+
* 1. the env factory STAGES each fresh container (seed repo + write an upload script holding a presigned
|
|
8
|
+
* PUT URL) — adapter-side, so the URL/bulk never enters the model's CONTEXT by construction (it does sit
|
|
9
|
+
* on the sandbox filesystem, readable if the agent goes looking — the objective forbids inspecting it;
|
|
10
|
+
* the URL is single-object, PUT-only, short-TTL, so that residual face is small);
|
|
11
|
+
* 2. the worker's objective ends with a MANDATORY final step: run the upload script (`git format-patch` →
|
|
12
|
+
* `curl -T <file>` — a real file, so Content-Length is set; MinIO 411-rejects chunked presigned PUTs);
|
|
13
|
+
* 3. after fan-out the leader fetches the object over a presigned GET on the CONTROL PLANE (fetchUploadedDiff).
|
|
14
|
+
* A worker that skips the upload surfaces as `{ok:false}` → merge quarantines it (honest failure, no hang).
|
|
15
|
+
* pullDiff stays as the compat path for static (leader-owned) envs — M2 降兼容.
|
|
16
|
+
*/
|
|
1
17
|
import { type PullDiffResult } from "./diffout.js";
|
|
18
|
+
/** The staged upload script. `repoDir`/`workDir` are deployment config; `baseSha` is interpolated into a
|
|
19
|
+
* shell line, so it is re-validated HERE (fail-closed) — callers should already have applied diffout's
|
|
20
|
+
* safeRev rules, but this function is the last line before the shell. The patch is written OUTSIDE the repo
|
|
21
|
+
* dir so it never shows up as untracked noise in the worker's `git status`. */
|
|
2
22
|
export declare function buildUploadScript(p: {
|
|
3
23
|
repoDir: string;
|
|
4
24
|
baseSha: string;
|
|
5
25
|
putUrl: string;
|
|
6
26
|
workDir: string;
|
|
7
27
|
}): string;
|
|
28
|
+
/** The objective suffix that makes the upload the worker's last task step (no URL through the model). */
|
|
8
29
|
export declare function uploadStepSuffix(workDir: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Fetch the worker-uploaded patch over a presigned GET (control plane; creds stay adapter-held). Returns the
|
|
32
|
+
* same result shape as pullDiff so merge consumes either path. 🔴 The presigned URL is a short-lived bearer
|
|
33
|
+
* credential — it must never appear in returned errors (gate#3 council#5 redaction rule).
|
|
34
|
+
*/
|
|
9
35
|
export declare function fetchUploadedDiff(getUrl: string, opts?: {
|
|
10
36
|
maxBytes?: number;
|
|
11
37
|
fetchImpl?: typeof fetch;
|
|
12
38
|
}): Promise<PullDiffResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Wrap an ExecutionEnv so a one-shot `stage(env)` (seed repo + write the upload script) runs before the FIRST
|
|
41
|
+
* workspace-touching call — the adapters are lazy-connect, so there is no explicit connect() hook to ride; this
|
|
42
|
+
* guarantees seed-before-agent on whichever call comes first. A failed staging rejects that call (task fails
|
|
43
|
+
* honestly) and RESETS, so a retried call re-attempts staging instead of replaying a cached rejection.
|
|
44
|
+
*/
|
|
13
45
|
export declare function withStaging<T extends object>(env: T, stage: (env: T) => Promise<void>, finalize?: (env: T) => Promise<void>): T;
|
|
14
46
|
//# sourceMappingURL=diffup.d.ts.map
|
package/dist/leader/diffup.js
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/68 §8 F2(a) — worker SELF-UPLOAD diff-out (the factory-env counterpart of diffout.ts's pullDiff).
|
|
3
|
+
*
|
|
4
|
+
* With a factory env the runner owns the container lifecycle (create at task start, destroy at finish — and
|
|
5
|
+
* durable suspend only produces a complete ownedEnv on this path), so the leader can no longer pull the diff
|
|
6
|
+
* from a still-alive env after the task. Instead (the gate#2-proven MinIO presigned pattern):
|
|
7
|
+
* 1. the env factory STAGES each fresh container (seed repo + write an upload script holding a presigned
|
|
8
|
+
* PUT URL) — adapter-side, so the URL/bulk never enters the model's CONTEXT by construction (it does sit
|
|
9
|
+
* on the sandbox filesystem, readable if the agent goes looking — the objective forbids inspecting it;
|
|
10
|
+
* the URL is single-object, PUT-only, short-TTL, so that residual face is small);
|
|
11
|
+
* 2. the worker's objective ends with a MANDATORY final step: run the upload script (`git format-patch` →
|
|
12
|
+
* `curl -T <file>` — a real file, so Content-Length is set; MinIO 411-rejects chunked presigned PUTs);
|
|
13
|
+
* 3. after fan-out the leader fetches the object over a presigned GET on the CONTROL PLANE (fetchUploadedDiff).
|
|
14
|
+
* A worker that skips the upload surfaces as `{ok:false}` → merge quarantines it (honest failure, no hang).
|
|
15
|
+
* pullDiff stays as the compat path for static (leader-owned) envs — M2 降兼容.
|
|
16
|
+
*/
|
|
1
17
|
import { safeRev } from "./diffout.js";
|
|
2
18
|
const DEFAULT_MAX_DIFF_BYTES = 5 * 1024 * 1024;
|
|
19
|
+
/** The staged upload script. `repoDir`/`workDir` are deployment config; `baseSha` is interpolated into a
|
|
20
|
+
* shell line, so it is re-validated HERE (fail-closed) — callers should already have applied diffout's
|
|
21
|
+
* safeRev rules, but this function is the last line before the shell. The patch is written OUTSIDE the repo
|
|
22
|
+
* dir so it never shows up as untracked noise in the worker's `git status`. */
|
|
3
23
|
export function buildUploadScript(p) {
|
|
4
24
|
if (!safeRev(p.baseSha))
|
|
5
25
|
throw new Error(`buildUploadScript: unsafe baseSha ${JSON.stringify(p.baseSha)}`);
|
|
26
|
+
// presignS3Url percent-encodes all specials today, so a "'" can't occur — escape anyway (belt-and-suspenders;
|
|
27
|
+
// the URL sits inside single quotes in the script below).
|
|
6
28
|
const putUrl = p.putUrl.replaceAll("'", "'\\''");
|
|
7
29
|
return [
|
|
8
30
|
"#!/bin/sh",
|
|
@@ -10,14 +32,21 @@ export function buildUploadScript(p) {
|
|
|
10
32
|
"set -e",
|
|
11
33
|
`cd ${p.repoDir}`,
|
|
12
34
|
`git format-patch --stdout ${p.baseSha}..HEAD > ${p.workDir}/.leader-out.patch`,
|
|
35
|
+
// -T <file> (not stdin): sets Content-Length — MinIO returns 411 on chunked presigned PUTs (gate#3 council#3).
|
|
13
36
|
`curl -fsS -X PUT -T ${p.workDir}/.leader-out.patch '${putUrl}'`,
|
|
14
37
|
`echo leader-diff-uploaded`,
|
|
15
38
|
"",
|
|
16
39
|
].join("\n");
|
|
17
40
|
}
|
|
41
|
+
/** The objective suffix that makes the upload the worker's last task step (no URL through the model). */
|
|
18
42
|
export function uploadStepSuffix(workDir) {
|
|
19
43
|
return `\n\nMANDATORY FINAL STEP: after your final commit, run exactly: sh ${workDir}/.leader-upload.sh — it exports your branch diff for integration. Do not modify, inspect, or skip it; if it fails, fix your git state (commit your work) and run it again.`;
|
|
20
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Fetch the worker-uploaded patch over a presigned GET (control plane; creds stay adapter-held). Returns the
|
|
47
|
+
* same result shape as pullDiff so merge consumes either path. 🔴 The presigned URL is a short-lived bearer
|
|
48
|
+
* credential — it must never appear in returned errors (gate#3 council#5 redaction rule).
|
|
49
|
+
*/
|
|
21
50
|
export async function fetchUploadedDiff(getUrl, opts = {}) {
|
|
22
51
|
const maxBytes = opts.maxBytes ?? DEFAULT_MAX_DIFF_BYTES;
|
|
23
52
|
const f = opts.fetchImpl ?? fetch;
|
|
@@ -29,6 +58,7 @@ export async function fetchUploadedDiff(getUrl, opts = {}) {
|
|
|
29
58
|
return { ok: false, error: `diff fetch failed: ${e instanceof Error ? e.message.replaceAll(getUrl, "<presigned-url>") : "network error"}` };
|
|
30
59
|
}
|
|
31
60
|
if (res.status === 404 || res.status === 403) {
|
|
61
|
+
// MinIO answers 403 (signature scope) for a missing key on some configs — both mean "no upload landed".
|
|
32
62
|
return { ok: false, error: `no uploaded diff (worker skipped the mandatory upload step, or upload failed) [${res.status}]` };
|
|
33
63
|
}
|
|
34
64
|
if (!res.ok)
|
|
@@ -40,7 +70,14 @@ export async function fetchUploadedDiff(getUrl, opts = {}) {
|
|
|
40
70
|
return { ok: false, error: "uploaded diff is empty (worker committed nothing past base)" };
|
|
41
71
|
return { ok: true, patch, bytes: patch.length };
|
|
42
72
|
}
|
|
73
|
+
/** The minimal surface staging must run before (the agent reaches the workspace through these). */
|
|
43
74
|
const STAGED_METHODS = new Set(["exec", "execStream", "writeFile", "readFile"]);
|
|
75
|
+
/**
|
|
76
|
+
* Wrap an ExecutionEnv so a one-shot `stage(env)` (seed repo + write the upload script) runs before the FIRST
|
|
77
|
+
* workspace-touching call — the adapters are lazy-connect, so there is no explicit connect() hook to ride; this
|
|
78
|
+
* guarantees seed-before-agent on whichever call comes first. A failed staging rejects that call (task fails
|
|
79
|
+
* honestly) and RESETS, so a retried call re-attempts staging instead of replaying a cached rejection.
|
|
80
|
+
*/
|
|
44
81
|
export function withStaging(env, stage, finalize) {
|
|
45
82
|
let staged;
|
|
46
83
|
const ensure = () => {
|
|
@@ -57,6 +94,11 @@ export function withStaging(env, stage, finalize) {
|
|
|
57
94
|
return v;
|
|
58
95
|
const fn = v.bind(t);
|
|
59
96
|
if (prop === "destroy" && finalize) {
|
|
97
|
+
// Belt for the MANDATORY upload step (found live: task02b run4 collapse-solo): a worker that did the
|
|
98
|
+
// porting but FORGOT `sh .leader-upload.sh` loses its work when the runner destroys the env — diff-out
|
|
99
|
+
// 404s and merge quarantines a worker that actually finished. Run `finalize` best-effort before the
|
|
100
|
+
// teardown, only if the env was ever staged (never spawn a pod just to upload nothing). Idempotent:
|
|
101
|
+
// re-running the upload script after a model-run upload overwrites the same object with the same diff.
|
|
60
102
|
return async (...args) => {
|
|
61
103
|
if (staged)
|
|
62
104
|
await Promise.resolve(staged).then(() => finalize(env)).catch(() => { });
|
|
@@ -66,6 +108,7 @@ export function withStaging(env, stage, finalize) {
|
|
|
66
108
|
if (!STAGED_METHODS.has(prop))
|
|
67
109
|
return fn;
|
|
68
110
|
if (prop === "execStream") {
|
|
111
|
+
// async-iterable return — staging must complete before the underlying stream starts.
|
|
69
112
|
return (...args) => (async function* () {
|
|
70
113
|
await ensure();
|
|
71
114
|
yield* fn(...args);
|
|
@@ -1,24 +1,38 @@
|
|
|
1
1
|
import type { LeaderResult } from "./leader.js";
|
|
2
2
|
export interface LeaderRequestBody {
|
|
3
|
+
/** The task to decompose + execute (the Planner turns it into N disjoint sub-tasks). */
|
|
3
4
|
objective: string;
|
|
5
|
+
/** Durable-remote base the Coordinator pushes onto (`--force-with-lease=<ref>:<baseSha>`). */
|
|
4
6
|
baseSha?: string;
|
|
5
7
|
[k: string]: unknown;
|
|
6
8
|
}
|
|
7
9
|
export interface LeaderRun {
|
|
8
10
|
id: string;
|
|
11
|
+
/** LEADER-REPAIRLOOP-INTEGRATION §5/§10.6 — `needs_human` is the THIRD terminal state: the repair loop / merge
|
|
12
|
+
* push chokepoint ABSTAINED (a `candidate_only`/`needs_human_oracle`/`conflict` repair terminal), held the push,
|
|
13
|
+
* and surfaced a candidate awaiting a human `/decide` accept — distinct from "broke" (`failed`). Default runs
|
|
14
|
+
* never reach it (no `repairTerminal` ⇒ `completed`/`failed` exactly as before). */
|
|
9
15
|
status: "running" | "completed" | "failed" | "needs_human";
|
|
10
16
|
result?: LeaderResult;
|
|
11
17
|
error?: string;
|
|
12
18
|
startedAt: number;
|
|
13
19
|
finishedAt?: number;
|
|
20
|
+
/** BL-4: the principal that submitted this run (null = anonymous/single-tenant). The GET is owner-checked so
|
|
21
|
+
* an owned run is visible ONLY to its owner (404 to others — no existence oracle), like GET /v1/runs/:id. */
|
|
14
22
|
owner?: string | null;
|
|
15
23
|
}
|
|
16
24
|
export interface LeaderEndpoint {
|
|
25
|
+
/** Returns a {status,body} to send, or null if the (method,url) is not a leader route. Kicks the background
|
|
26
|
+
* run for POST. `body` is the already-parsed request body (server reads it; undefined for GET). `requester`
|
|
27
|
+
* (BL-4) is the authenticated principal: recorded as the run owner on POST and owner-checked on GET. */
|
|
17
28
|
handle(method: string, url: string, body: unknown, requester?: string | null): {
|
|
18
29
|
status: number;
|
|
19
30
|
body: object;
|
|
20
31
|
} | null;
|
|
32
|
+
/** 对抗复查 B-1(CRITICAL):the number of leader runs still RUNNING in the background — the drain gate
|
|
33
|
+
* counts them (a SIGTERM used to see 0 and hard-shut mid-leader-run). */
|
|
21
34
|
inflight(): number;
|
|
35
|
+
/** In-memory run registry (exposed for tests / a future reaper). */
|
|
22
36
|
runs: Map<string, LeaderRun>;
|
|
23
37
|
}
|
|
24
38
|
export declare function createLeaderEndpoint(runLeader: (body: LeaderRequestBody) => Promise<LeaderResult>, opts?: {
|
|
@@ -26,6 +40,12 @@ export declare function createLeaderEndpoint(runLeader: (body: LeaderRequestBody
|
|
|
26
40
|
info?: (m: string, x?: Record<string, unknown>) => void;
|
|
27
41
|
error?: (m: string, x?: Record<string, unknown>) => void;
|
|
28
42
|
};
|
|
43
|
+
/** SDK 全量核查(2026-07-24,黑板 GD 组)撞获:`wire.ts` 的 runLeader 实际要求 objective 之外还有
|
|
44
|
+
* durableRemote/testCmd/seedCmd/baseSha 全部非空,但这个同步门此前只查 objective——一个不完整的
|
|
45
|
+
* 请求会先拿到 202"运行中",然后在后台**必然**失败(wire.ts:369),消费方只能靠后续 GET 才发现。
|
|
46
|
+
* 这个字段名列表由调用方(main.ts wire 真实 runLeader 实现)传入,endpoint 本身不需要知道
|
|
47
|
+
* runLeader 的内部实现细节,依旧保持 pure/testable。不传 = 向后兼容旧行为(只查 objective) ——
|
|
48
|
+
* 本文件其余全部既有用例都用最小 {objective} payload,不能被这个修复打红。 */
|
|
29
49
|
requiredFields?: readonly string[];
|
|
30
50
|
}): LeaderEndpoint;
|
|
31
51
|
//# sourceMappingURL=endpoint.d.ts.map
|