@sema-agent/server 7.131.0 → 7.133.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/MIGRATION.md +575 -0
- package/README.md +12 -9
- package/README.zh-CN.md +9 -6
- package/USAGE.md +326 -98
- package/deploy/sema-up/README.md +19 -1
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -2
- package/deploy/sema-up/chart/templates/server.yaml +5 -2
- package/deploy/sema-up/stack/compose.yaml +3 -0
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
- package/dist/adoption/plan.d.ts +3 -2
- package/dist/adoption/plan.js +7 -5
- package/dist/adoption/runner.js +3 -10
- package/dist/adoption/sql.d.ts +3 -2
- package/dist/adoption/sql.js +3 -5
- package/dist/adoption/wire.d.ts +4 -1
- package/dist/adoption/wire.js +1 -0
- package/dist/approval-ask-audit-store.d.ts +31 -13
- package/dist/approval-ask-audit-store.js +272 -74
- package/dist/approval-ask-machine.d.ts +15 -0
- package/dist/approval-ask-machine.js +6 -0
- package/dist/approval-ask-retention.d.ts +136 -0
- package/dist/approval-ask-retention.js +102 -0
- package/dist/approval-card.d.ts +82 -20
- package/dist/approval-card.js +46 -16
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval.d.ts +9 -0
- package/dist/approval.js +24 -3
- package/dist/audit.d.ts +33 -19
- package/dist/audit.js +12 -16
- package/dist/auth-bridge.d.ts +4 -0
- package/dist/auth-bridge.js +10 -11
- package/dist/bake-runner/main.js +3 -2
- package/dist/boot/deferred-sandbox-path-env.js +1 -1
- package/dist/boot/deployment-mods.d.ts +31 -0
- package/dist/boot/deployment-mods.js +26 -0
- package/dist/boot/execution-env.d.ts +1 -1
- package/dist/boot/execution-env.js +27 -12
- package/dist/boot/execution-lane.js +11 -0
- package/dist/boot/leader.js +2 -0
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/memory-boundary.js +2 -2
- package/dist/boot/memory-consolidation.d.ts +5 -4
- package/dist/boot/memory-consolidation.js +7 -6
- package/dist/boot/org-delivery.d.ts +28 -0
- package/dist/boot/org-delivery.js +20 -0
- package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
- package/dist/boot/read-deny-anchor-audit.js +36 -0
- package/dist/boot/reapers.d.ts +3 -0
- package/dist/boot/reapers.js +21 -1
- package/dist/boot/resolve-spec.d.ts +4 -5
- package/dist/boot/resolve-spec.js +74 -123
- package/dist/boot/runner-deps.d.ts +19 -8
- package/dist/boot/runner-deps.js +15 -2
- package/dist/boot/session-faces.d.ts +2 -7
- package/dist/boot/session-faces.js +4 -2
- package/dist/boot/stage-02-web-admin-pull.js +4 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -4
- package/dist/boot/stage-05-execution-env.js +7 -10
- package/dist/boot/stage-06-runners.d.ts +4 -2
- package/dist/boot/stage-06-runners.js +11 -7
- package/dist/boot/stage-07-capability-layer.d.ts +4 -2
- package/dist/boot/stage-07-capability-layer.js +27 -6
- package/dist/boot/stage-08-reapers.d.ts +4 -2
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +6 -9
- package/dist/boot/stage-10-http-server.d.ts +6 -9
- package/dist/boot/stage-10-http-server.js +7 -9
- package/dist/boot/stores.d.ts +1 -1
- package/dist/boot/stores.js +7 -8
- package/dist/boot/web-admin.d.ts +4 -3
- package/dist/boot/web-admin.js +186 -98
- package/dist/boot/workflow-orchestration.d.ts +2 -0
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/brain.js +25 -25
- package/dist/breaker-key.d.ts +6 -0
- package/dist/breaker-key.js +29 -0
- package/dist/budget.js +5 -4
- package/dist/caller-text-echo.d.ts +23 -0
- package/dist/caller-text-echo.js +21 -0
- package/dist/capabilities/brand-identity.d.ts +26 -0
- package/dist/capabilities/brand-identity.js +27 -0
- package/dist/capabilities/center-plugins.d.ts +7 -0
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/center-prompts.d.ts +32 -59
- package/dist/capabilities/center-prompts.js +18 -32
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/engine-capabilities.js +2 -1
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +30 -6
- package/dist/capabilities/hands-lane.js +11 -1
- package/dist/capabilities/mcp-probe.d.ts +48 -3
- package/dist/capabilities/mcp-probe.js +47 -135
- package/dist/capabilities/scenarios.d.ts +95 -45
- package/dist/capabilities/scenarios.js +53 -38
- package/dist/capabilities/skills.d.ts +19 -4
- package/dist/capabilities/skills.js +30 -10
- package/dist/capability-facts.d.ts +34 -4
- package/dist/capability-facts.js +28 -2
- package/dist/center-config-tier.d.ts +69 -0
- package/dist/center-config-tier.js +42 -0
- package/dist/checkpoint-identity.d.ts +16 -0
- package/dist/checkpoint-identity.js +19 -0
- package/dist/config-catalog.d.ts +17 -10
- package/dist/config-catalog.js +47 -32
- package/dist/config-d-migration.d.ts +3 -1
- package/dist/config-d-migration.js +2 -2
- package/dist/config-dir-trust.d.ts +114 -0
- package/dist/config-dir-trust.js +388 -0
- package/dist/config-invariants.d.ts +18 -5
- package/dist/config-invariants.js +35 -3
- package/dist/config-lkg.d.ts +9 -9
- package/dist/config-lkg.js +20 -4
- package/dist/config-provider.d.ts +9 -2
- package/dist/config-provider.js +18 -6
- package/dist/config-types.d.ts +75 -20
- package/dist/config-types.js +8 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +137 -62
- package/dist/delegated-session-owner.d.ts +185 -0
- package/dist/delegated-session-owner.js +119 -0
- package/dist/device-protocol.d.ts +5 -3
- package/dist/device-protocol.js +1 -1
- package/dist/device-ws-hub.js +21 -2
- package/dist/device-ws-protocol.d.ts +70 -6
- package/dist/device-ws-protocol.js +50 -22
- package/dist/elicitation.js +3 -2
- package/dist/entry-problems.d.ts +34 -0
- package/dist/entry-problems.js +14 -0
- package/dist/env-name-allowlist-knobs.d.ts +12 -2
- package/dist/env-name-allowlist-knobs.js +5 -4
- package/dist/exec-bounds.d.ts +15 -3
- package/dist/exec-bounds.js +4 -0
- package/dist/execution-lane-caps.d.ts +56 -10
- package/dist/execution-lane-caps.js +50 -0
- package/dist/field-conflict.d.ts +43 -0
- package/dist/field-conflict.js +20 -0
- package/dist/fleet/fleet-bus.d.ts +80 -6
- package/dist/fleet/fleet-bus.js +41 -9
- package/dist/hooks/classic-stations.d.ts +91 -0
- package/dist/hooks/classic-stations.js +27 -0
- package/dist/hooks/command-spawn.d.ts +57 -0
- package/dist/hooks/command-spawn.js +139 -0
- package/dist/hooks/hook-llm.d.ts +8 -5
- package/dist/hooks/hook-llm.js +79 -36
- package/dist/hooks/hook-runner.d.ts +349 -95
- package/dist/hooks/hook-runner.js +855 -568
- package/dist/hooks/hook-source.d.ts +44 -0
- package/dist/hooks/hook-source.js +40 -0
- package/dist/http/active-run-conflict.d.ts +5 -13
- package/dist/http/active-run-conflict.js +17 -27
- package/dist/http/admission.d.ts +8 -2
- package/dist/http/admission.js +188 -101
- package/dist/http/approval-sweeps.js +99 -21
- package/dist/http/caller-trust.d.ts +77 -0
- package/dist/http/caller-trust.js +143 -0
- package/dist/http/checkpoint-ctx.d.ts +41 -24
- package/dist/http/checkpoint-ctx.js +23 -16
- package/dist/http/claimed-run.d.ts +14 -0
- package/dist/http/claimed-run.js +15 -0
- package/dist/http/device-placement.d.ts +2 -4
- package/dist/http/device-placement.js +7 -11
- package/dist/http/dispatch.d.ts +0 -4
- package/dist/http/dispatch.js +15 -13
- package/dist/http/durable-run-leg.d.ts +6 -33
- package/dist/http/durable-run-leg.js +36 -10
- package/dist/http/health-self-report.d.ts +7 -5
- package/dist/http/health-self-report.js +4 -18
- package/dist/http/owner-access.d.ts +56 -0
- package/dist/http/owner-access.js +42 -0
- package/dist/http/principal-gate.d.ts +70 -28
- package/dist/http/principal-gate.js +61 -15
- package/dist/http/readiness.d.ts +11 -5
- package/dist/http/readiness.js +10 -3
- package/dist/http/refusal-body.d.ts +21 -0
- package/dist/http/refusal-body.js +4 -0
- package/dist/http/request-guards.d.ts +43 -23
- package/dist/http/request-guards.js +53 -17
- package/dist/http/resume-ctx-read.d.ts +2 -5
- package/dist/http/resume-ctx-read.js +7 -4
- package/dist/http/resume-legs.d.ts +28 -4
- package/dist/http/resume-legs.js +169 -91
- package/dist/http/retired-service-deps.d.ts +43 -0
- package/dist/http/retired-service-deps.js +18 -0
- package/dist/http/route-ctx.d.ts +44 -28
- package/dist/http/route-ctx.js +4 -0
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/a2a-serve.js +3 -4
- package/dist/http/routes/admin-config-refresh.js +1 -1
- package/dist/http/routes/admin-drain.js +1 -1
- package/dist/http/routes/admin-memory-optout.js +5 -1
- package/dist/http/routes/adoption.js +2 -9
- package/dist/http/routes/approvals-assistant.js +49 -48
- package/dist/http/routes/background.js +3 -2
- package/dist/http/routes/capabilities.js +21 -5
- package/dist/http/routes/config-catalog.d.ts +3 -3
- package/dist/http/routes/config-catalog.js +1 -1
- package/dist/http/routes/devices.js +3 -17
- package/dist/http/routes/diagnostics.js +6 -2
- package/dist/http/routes/images.js +6 -7
- package/dist/http/routes/leader.js +1 -8
- package/dist/http/routes/mcp-reconnect.d.ts +1 -1
- package/dist/http/routes/mcp-reconnect.js +3 -2
- package/dist/http/routes/memory-bundle.js +1 -1
- package/dist/http/routes/memory-compliance.js +1 -1
- package/dist/http/routes/memory-consolidation.js +1 -1
- package/dist/http/routes/memory-origin.js +1 -1
- package/dist/http/routes/memory-policy.d.ts +1 -1
- package/dist/http/routes/memory-policy.js +3 -2
- package/dist/http/routes/notify-wake.js +8 -21
- package/dist/http/routes/observability.js +2 -2
- package/dist/http/routes/principal-inbox.d.ts +39 -0
- package/dist/http/routes/principal-inbox.js +76 -0
- package/dist/http/routes/retention-ops.js +2 -9
- package/dist/http/routes/rules.js +5 -18
- package/dist/http/routes/runs.d.ts +5 -0
- package/dist/http/routes/runs.js +34 -107
- package/dist/http/routes/session-sync.js +15 -26
- package/dist/http/routes/sessions.js +30 -40
- package/dist/http/routes/shared-memory.js +2 -13
- package/dist/http/routes/side-query.js +8 -7
- package/dist/http/routes/tasks.js +67 -21
- package/dist/http/routes/workflows.d.ts +351 -0
- package/dist/http/routes/workflows.js +153 -119
- package/dist/http/send.d.ts +33 -10
- package/dist/http/send.js +21 -4
- package/dist/http/server.d.ts +27 -18
- package/dist/http/server.js +34 -6
- package/dist/http/stored-body-replay.js +17 -4
- package/dist/http/submit-ctx.d.ts +25 -0
- package/dist/http/submit-ctx.js +40 -0
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +5 -4
- package/dist/http/wire-types.d.ts +11 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -2
- package/dist/lane-home-probe.d.ts +112 -0
- package/dist/lane-home-probe.js +101 -0
- package/dist/leader/endpoint.d.ts +4 -1
- package/dist/leader/endpoint.js +11 -10
- package/dist/limit-refusal.d.ts +59 -0
- package/dist/limit-refusal.js +15 -0
- package/dist/main.js +1 -1
- package/dist/mcp-assertion-header.d.ts +32 -19
- package/dist/mcp-assertion-header.js +10 -9
- package/dist/mcp-tool-faces.d.ts +5 -0
- package/dist/mcp-tool-faces.js +6 -4
- package/dist/memory-project-layer.d.ts +37 -0
- package/dist/memory-project-layer.js +46 -0
- package/dist/memory-scope.d.ts +24 -17
- package/dist/memory-scope.js +24 -8
- package/dist/memory-sync-client.d.ts +27 -13
- package/dist/memory-sync-client.js +107 -18
- package/dist/model-entry-refusal.d.ts +9 -1
- package/dist/model-entry-refusal.js +6 -1
- package/dist/model-plane-face.d.ts +51 -0
- package/dist/model-plane-face.js +24 -0
- package/dist/model-provider.d.ts +44 -12
- package/dist/model-provider.js +21 -2
- package/dist/model-route-endpoint.d.ts +9 -12
- package/dist/model-route-endpoint.js +8 -11
- package/dist/model-route-env.d.ts +22 -0
- package/dist/model-route-env.js +2 -0
- package/dist/model-route-gap.d.ts +60 -30
- package/dist/model-route-gap.js +21 -15
- package/dist/observability/corrupt-read-seat.d.ts +7 -0
- package/dist/observability/corrupt-read-seat.js +9 -0
- package/dist/observability/cost-taxonomy.d.ts +7 -7
- package/dist/observability/err-text.d.ts +6 -0
- package/dist/observability/err-text.js +18 -4
- package/dist/observability/fail-open.d.ts +76 -14
- package/dist/observability/fail-open.js +76 -14
- package/dist/observability/metrics.js +4 -1
- package/dist/observability/prompt-manifest.d.ts +33 -82
- package/dist/observability/prompt-manifest.js +122 -17
- package/dist/observability/run-terminal.js +14 -6
- package/dist/observability/secret-env-scrub.d.ts +13 -1
- package/dist/observability/secret-env-scrub.js +13 -1
- package/dist/observability/tool-trace.d.ts +16 -21
- package/dist/observability/tool-trace.js +58 -49
- package/dist/operator-ask.d.ts +10 -0
- package/dist/operator-ask.js +3 -0
- package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
- package/dist/orchestration/workflow-agent-session-index.js +9 -13
- package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
- package/dist/orchestration/workflow-completion-inbox.js +13 -0
- package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
- package/dist/orchestration/workflow-notify-journal.js +27 -34
- package/dist/orchestration/workflow-park-decision.d.ts +89 -0
- package/dist/orchestration/workflow-park-decision.js +118 -0
- package/dist/org-delivery-gate.d.ts +81 -0
- package/dist/org-delivery-gate.js +59 -0
- package/dist/panel-tool-names.d.ts +23 -0
- package/dist/panel-tool-names.js +8 -0
- package/dist/parked-decide.d.ts +39 -6
- package/dist/parked-decide.js +98 -51
- package/dist/parked-revive-surface.d.ts +9 -2
- package/dist/parked-revive-surface.js +11 -8
- package/dist/per-task-image.d.ts +7 -1
- package/dist/per-task-image.js +3 -3
- package/dist/permission-rule-list.d.ts +1 -1
- package/dist/permission-rule-list.js +2 -2
- package/dist/plain-string-record.d.ts +25 -0
- package/dist/plain-string-record.js +32 -0
- package/dist/plugins/approval-ask-store-file.d.ts +16 -1
- package/dist/plugins/approval-ask-store-file.js +21 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
- package/dist/plugins/approval-ask-store-memory.js +34 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
- package/dist/plugins/approval-ask-store-sql.js +37 -1
- package/dist/plugins/blob-backend.d.ts +83 -15
- package/dist/plugins/blob-backend.js +68 -15
- package/dist/plugins/breaker-state-sql.d.ts +2 -2
- package/dist/plugins/breaker-state-sql.js +4 -4
- package/dist/plugins/caching-session-store.d.ts +3 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +28 -4
- package/dist/plugins/checkpoint-store-sql.js +59 -28
- package/dist/plugins/file-history-store-sql.d.ts +5 -2
- package/dist/plugins/file-history-store-sql.js +3 -1
- package/dist/plugins/file-run-store.d.ts +5 -13
- package/dist/plugins/file-run-store.js +9 -0
- package/dist/plugins/fork-routing-session-store.d.ts +9 -1
- package/dist/plugins/fork-routing-session-store.js +12 -1
- package/dist/plugins/host-platform.d.ts +2 -0
- package/dist/plugins/host-platform.js +2 -1
- package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
- package/dist/plugins/k8s-bg-scripts.js +22 -0
- package/dist/plugins/local-checkpoint-store.d.ts +2 -0
- package/dist/plugins/local-checkpoint-store.js +11 -3
- package/dist/plugins/local-session-store.d.ts +1 -1
- package/dist/plugins/local-session-store.js +1 -1
- package/dist/plugins/local-session-window.d.ts +39 -0
- package/dist/plugins/local-session-window.js +54 -0
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
- package/dist/plugins/mailbox-store-sql.d.ts +30 -48
- package/dist/plugins/mailbox-store-sql.js +77 -52
- package/dist/plugins/memory-embedder-fingerprint.js +2 -1
- package/dist/plugins/memory-run-store.d.ts +5 -13
- package/dist/plugins/memory-run-store.js +8 -0
- package/dist/plugins/one-time-migrations.d.ts +245 -93
- package/dist/plugins/one-time-migrations.js +668 -207
- package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
- package/dist/plugins/org-delivery-quota-store.js +228 -0
- package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
- package/dist/plugins/permission-rule-store-sql.js +4 -18
- package/dist/plugins/pg-pool.js +39 -7
- package/dist/plugins/pg-session-storage.d.ts +20 -8
- package/dist/plugins/pg-session-storage.js +34 -21
- package/dist/plugins/remote-env-adb.d.ts +12 -12
- package/dist/plugins/remote-env-adb.js +21 -6
- package/dist/plugins/remote-env-device.js +3 -0
- package/dist/plugins/remote-env-e2b.d.ts +1 -1
- package/dist/plugins/remote-env-e2b.js +21 -9
- package/dist/plugins/remote-env-host.d.ts +9 -9
- package/dist/plugins/remote-env-host.js +10 -32
- package/dist/plugins/remote-env-k8s.d.ts +103 -38
- package/dist/plugins/remote-env-k8s.js +288 -95
- package/dist/plugins/remote-env-local-docker.d.ts +27 -13
- package/dist/plugins/remote-env-local-docker.js +82 -11
- package/dist/plugins/remote-env-ssh.d.ts +21 -12
- package/dist/plugins/remote-env-ssh.js +117 -5
- package/dist/plugins/remote-shell.d.ts +0 -1
- package/dist/plugins/remote-shell.js +1 -2
- package/dist/plugins/retention-store-sql.js +6 -2
- package/dist/plugins/run-store-sql.d.ts +16 -14
- package/dist/plugins/run-store-sql.js +22 -2
- package/dist/plugins/schema-consistency.d.ts +54 -0
- package/dist/plugins/schema-consistency.js +52 -0
- package/dist/plugins/schema-indexes.js +2 -0
- package/dist/plugins/send-user-file.js +2 -2
- package/dist/plugins/session-epoch-anchor.d.ts +39 -0
- package/dist/plugins/session-epoch-anchor.js +22 -0
- package/dist/plugins/session-store.d.ts +18 -8
- package/dist/plugins/session-store.js +15 -4
- package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
- package/dist/plugins/shared-memory-store-sql.js +5 -16
- package/dist/plugins/sql-driver.d.ts +205 -1
- package/dist/plugins/sql-driver.js +325 -13
- package/dist/plugins/sql-errors.d.ts +64 -0
- package/dist/plugins/sql-errors.js +57 -0
- package/dist/plugins/store-backend.d.ts +36 -1
- package/dist/plugins/store-backend.js +42 -15
- package/dist/plugins/store-contracts.d.ts +42 -0
- package/dist/plugins/store-contracts.js +1 -0
- package/dist/plugins/tidb-pool.d.ts +6 -1
- package/dist/plugins/tidb-pool.js +44 -10
- package/dist/plugins/tidb-session-storage.d.ts +8 -11
- package/dist/plugins/tidb-session-storage.js +6 -16
- package/dist/plugins/tidb-session-store.d.ts +24 -4
- package/dist/plugins/tidb-session-store.js +29 -5
- package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
- package/dist/plugins/workflow-journal-store-sql.js +19 -6
- package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
- package/dist/plugins/workflow-run-store-sql.js +50 -9
- package/dist/posture-source.d.ts +18 -10
- package/dist/posture-source.js +4 -1
- package/dist/project-identity.d.ts +45 -6
- package/dist/project-identity.js +162 -8
- package/dist/project-layer-key.d.ts +28 -0
- package/dist/project-layer-key.js +29 -0
- package/dist/prompts-domain-validate.d.ts +17 -61
- package/dist/prompts-domain-validate.js +9 -119
- package/dist/question.js +3 -2
- package/dist/read-deny-entry.d.ts +25 -0
- package/dist/read-deny-entry.js +12 -0
- package/dist/read-face-posture.d.ts +37 -11
- package/dist/read-face-posture.js +32 -3
- package/dist/request-key-closure.d.ts +9 -2
- package/dist/request-key-closure.js +11 -5
- package/dist/request-value-closure.d.ts +5 -0
- package/dist/request-value-closure.js +11 -3
- package/dist/rule-entry-list.d.ts +38 -11
- package/dist/rule-entry-list.js +106 -30
- package/dist/rules-consent.js +3 -4
- package/dist/run-acceptance.d.ts +19 -3
- package/dist/run-acceptance.js +13 -1
- package/dist/run-local.js +54 -24
- package/dist/runs.d.ts +15 -8
- package/dist/runs.js +35 -1
- package/dist/runtime-caps-resolver.d.ts +16 -6
- package/dist/runtime-caps-resolver.js +18 -5
- package/dist/sandbox-pkg-source.d.ts +19 -1
- package/dist/sandbox-pkg-source.js +29 -7
- package/dist/security.d.ts +87 -9
- package/dist/security.js +52 -9
- package/dist/server-secret-env.d.ts +44 -18
- package/dist/server-secret-env.js +49 -8
- package/dist/session-error-wire.d.ts +19 -2
- package/dist/session-error-wire.js +5 -1
- package/dist/session-incarnation.d.ts +15 -5
- package/dist/session-incarnation.js +16 -9
- package/dist/session-titled-frame.d.ts +33 -0
- package/dist/session-titled-frame.js +4 -0
- package/dist/session-titler.d.ts +9 -1
- package/dist/session-titler.js +27 -6
- package/dist/spec-fields.d.ts +28 -16
- package/dist/spec-fields.js +66 -54
- package/dist/sql-engine-posture.d.ts +31 -4
- package/dist/sql-engine-posture.js +36 -1
- package/dist/stored-request-tool-axes-m19.d.ts +19 -4
- package/dist/stored-request-tool-axes-m19.js +30 -2
- package/dist/task-a2a.d.ts +9 -1
- package/dist/task-a2a.js +73 -47
- package/dist/task-cwd.d.ts +1 -1
- package/dist/task-mcp.d.ts +46 -58
- package/dist/task-mcp.js +82 -107
- package/dist/task-settings.d.ts +95 -108
- package/dist/task-settings.js +77 -98
- package/dist/text-bidi.d.ts +1 -48
- package/dist/text-bidi.js +3 -5
- package/dist/tighten-only-seats.d.ts +150 -0
- package/dist/tighten-only-seats.js +196 -0
- package/dist/tool-approval.d.ts +304 -88
- package/dist/tool-approval.js +623 -239
- package/dist/trace/core-keyset-guard.d.ts +122 -20
- package/dist/trace/engine-notice-wire.d.ts +11 -3
- package/dist/trace/engine-notice-wire.js +8 -1
- package/dist/trace/exit-seat.d.ts +28 -0
- package/dist/trace/exit-seat.js +76 -0
- package/dist/trace/ledger-events.d.ts +6 -3
- package/dist/trace/ledger-sink.js +4 -1
- package/dist/trace/model-segment.js +1 -1
- package/dist/trace/project.d.ts +98 -17
- package/dist/trace/project.js +98 -50
- package/dist/trace/projection-table.d.ts +100 -0
- package/dist/trace/projection-table.js +130 -0
- package/dist/trace/redact.d.ts +54 -0
- package/dist/trace/redact.js +778 -152
- package/dist/trace/self-minted-wire.d.ts +345 -1
- package/dist/trace/self-minted-wire.js +117 -1
- package/dist/trace/wire-projection-faces.d.ts +377 -3
- package/dist/trace/wire-projection-faces.js +164 -1
- package/dist/url-refusal.js +2 -0
- package/dist/web-admin-client/apply-effective.d.ts +12 -0
- package/dist/web-admin-client/apply-effective.js +56 -5
- package/dist/web-admin-client/candidate-gate.d.ts +6 -6
- package/dist/web-admin-client/candidate-gate.js +3 -3
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/http-client.js +0 -6
- package/dist/web-admin-client/read-face.js +5 -9
- package/dist/web-admin-client/read-warnings.d.ts +13 -0
- package/dist/web-admin-client/read-warnings.js +10 -0
- package/dist/web-admin-client/skills-mcp.d.ts +3 -0
- package/dist/web-admin-client/skills-mcp.js +11 -9
- package/dist/web-admin-client/types.d.ts +2 -3
- package/dist/workspace-cache.d.ts +35 -0
- package/dist/workspace-cache.js +36 -0
- package/dist/workspace-space.d.ts +3 -2
- package/dist/workspace-space.js +2 -0
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +65 -10
- package/package.json +8 -4
- package/scripts/drain-check-local.mjs +34 -1
- package/scripts/drain-check.mysql.sql +30 -2
- package/scripts/drain-check.pg.sql +29 -2
- package/dist/capabilities/memory-notice.d.ts +0 -138
- package/dist/capabilities/memory-notice.js +0 -64
- package/dist/capabilities/prompt.d.ts +0 -17
- package/dist/capabilities/prompt.js +0 -6
- package/dist/mcp-content-origin.d.ts +0 -34
- package/dist/mcp-content-origin.js +0 -10
- package/dist/tool-axis-words.d.ts +0 -27
- package/dist/tool-axis-words.js +0 -9
- package/dist/wire-name-bound.d.ts +0 -14
- package/dist/wire-name-bound.js +0 -13
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { emitLeafAdvance } from "../session-leaf-bus.js";
|
|
2
|
-
import { BaseSessionStorage, StoredSession, SessionError, uuidv7, validateEntriesForImport, leafIdAfterEntry,
|
|
2
|
+
import { BaseSessionStorage, StoredSession, SessionError, uuidv7, validateEntriesForImport, leafIdAfterEntry, } from "@sema-agent/core";
|
|
3
3
|
import { SESSION_TITLE_MAX_CHARS } from "../session-row.js";
|
|
4
4
|
import { escapeLike } from "./sql-escape.js";
|
|
5
5
|
import { decodeSessionEventPayload } from "./session-event-payload.js";
|
|
6
|
+
import { scanEpochAnchor } from "./session-epoch-anchor.js";
|
|
6
7
|
import { jsonColumnText } from "./sql-json-column.js";
|
|
7
8
|
import { pgSafeJsonStringify } from "./pg-safe-json.js";
|
|
8
9
|
import { toIso } from "./sql-row-helpers.js";
|
|
9
10
|
import { assertPlacementAdmission, LIST_PLACED_BATCH, PLACEMENT_SELECT_COLUMNS, placedRowFromRow, placementFromRow, placementInsertValues, SQL_SESSION_PLACEMENTS, } from "./session-placement.js";
|
|
10
11
|
import { contentForkRelation, fastForwardSharedContentDiverged } from "../session-sync-content.js";
|
|
12
|
+
import { CLAIM_OWNERLESS_PLACED_SQL, claimOwnerlessParams, createPlacedSessionRow } from "../delegated-session-owner.js";
|
|
13
|
+
import { createLogger } from "../observability/logger.js";
|
|
11
14
|
import { classifySyncRelationshipByIds, SyncConflictError, stagingIdFor, STAGING_ID_MARKER, STAGING_GC_GRACE_MS, } from "../session-sync-kernel.js";
|
|
12
15
|
import { isPgUniqueViolation } from "./sql-errors.js";
|
|
13
16
|
import { BASELINE_IO_DEADLINE_MS, decodeInstructionSource, encodeInstructionSource } from "../instruction-source-notice.js";
|
|
@@ -82,21 +85,10 @@ export class PgSessionStorage extends BaseSessionStorage {
|
|
|
82
85
|
this.floorSeq = floorSeq;
|
|
83
86
|
}
|
|
84
87
|
async getEpochAnchor() {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const res = await this.pool.query(`SELECT seq, ${jsonColumnText("pg", "payload")} FROM session_event WHERE session_id = $1 AND seq < $2 AND type IN ('prompt_epoch','compaction') ORDER BY seq DESC LIMIT 100`, [this.sessionId, cursor]);
|
|
90
|
-
if (res.rows.length === 0)
|
|
91
|
-
return undefined;
|
|
92
|
-
for (const r of res.rows) {
|
|
93
|
-
const e = decodeSessionEventPayload(r.payload, this.sessionId, r.seq);
|
|
94
|
-
const d = e.type === "prompt_epoch" ? normalizePromptEpoch(e) : normalizePromptEpoch(e.details?.promptEpoch);
|
|
95
|
-
if (d)
|
|
96
|
-
return d;
|
|
97
|
-
}
|
|
98
|
-
cursor = Number(res.rows[res.rows.length - 1].seq);
|
|
99
|
-
}
|
|
88
|
+
return scanEpochAnchor(this.floorSeq, async (beforeSeq) => {
|
|
89
|
+
const res = await this.pool.query(`SELECT seq, ${jsonColumnText("pg", "payload")} FROM session_event WHERE session_id = $1 AND seq < $2 AND type IN ('prompt_epoch','compaction') ORDER BY seq DESC LIMIT 100`, [this.sessionId, beforeSeq]);
|
|
90
|
+
return res.rows;
|
|
91
|
+
}, (row) => decodeSessionEventPayload(row.payload, this.sessionId, row.seq));
|
|
100
92
|
}
|
|
101
93
|
static async wake(pool, sessionId) {
|
|
102
94
|
const metaRes = await pool.query(`SELECT created_at, leaf_id, leaf_seq, incarnation, ${PLACEMENT_SELECT_COLUMNS} FROM session_meta WHERE session_id = $1`, [sessionId]);
|
|
@@ -185,13 +177,15 @@ export class PgSessionStore {
|
|
|
185
177
|
retention = MANAGED_RETENTION;
|
|
186
178
|
placements = SQL_SESSION_PLACEMENTS;
|
|
187
179
|
pending = new Map();
|
|
188
|
-
|
|
180
|
+
log;
|
|
181
|
+
constructor(pool, opts = {}) {
|
|
189
182
|
this.pool = pool;
|
|
183
|
+
this.log = opts.log ?? createLogger();
|
|
190
184
|
}
|
|
191
185
|
async acquire(sessionId, opts) {
|
|
192
186
|
if (!sessionId) {
|
|
193
187
|
const id = uuidv7();
|
|
194
|
-
await this.
|
|
188
|
+
await this.createOnAcquire(id, opts?.placement);
|
|
195
189
|
return this.load(id, false, opts);
|
|
196
190
|
}
|
|
197
191
|
if (opts?.requireExisting)
|
|
@@ -214,7 +208,7 @@ export class PgSessionStore {
|
|
|
214
208
|
}
|
|
215
209
|
if (requireExisting)
|
|
216
210
|
throw new SessionError("not_found", `session ${sessionId} not found`);
|
|
217
|
-
await this.
|
|
211
|
+
await this.createOnAcquire(sessionId, opts?.placement);
|
|
218
212
|
storage = await PgSessionStorage.wake(this.pool, sessionId);
|
|
219
213
|
if (!storage) {
|
|
220
214
|
throw new SessionError("storage", `session ${sessionId} vanished between register and wake (a concurrent purge won the race) — retry`);
|
|
@@ -222,7 +216,26 @@ export class PgSessionStore {
|
|
|
222
216
|
assertPlacementAdmission(sessionId, (await storage.getMetadata()).placement, opts);
|
|
223
217
|
return { session: new StoredSession(storage), sessionId };
|
|
224
218
|
}
|
|
225
|
-
async register(sessionId, owner
|
|
219
|
+
async register(sessionId, owner) {
|
|
220
|
+
await this.insertMeta(sessionId, owner, undefined);
|
|
221
|
+
}
|
|
222
|
+
async createOnAcquire(sessionId, placement) {
|
|
223
|
+
if (placement === undefined)
|
|
224
|
+
return this.insertMeta(sessionId, null, undefined);
|
|
225
|
+
await createPlacedSessionRow(sessionId, placement, {
|
|
226
|
+
readFaces: (ids) => this.sourceFaces(ids),
|
|
227
|
+
insert: (owner) => this.insertMeta(sessionId, owner, placement),
|
|
228
|
+
readOwner: () => this.ownerOf(sessionId),
|
|
229
|
+
}, this.log);
|
|
230
|
+
}
|
|
231
|
+
async claimOwnerless(sessionId, incarnation, owner) {
|
|
232
|
+
return ((await this.pool.query(CLAIM_OWNERLESS_PLACED_SQL.pg, [...claimOwnerlessParams(sessionId, incarnation, owner)])).rowCount ?? 0) > 0;
|
|
233
|
+
}
|
|
234
|
+
async sourceFaces(ids) {
|
|
235
|
+
const res = await this.pool.query(`SELECT session_id, owner, incarnation FROM session_meta WHERE session_id IN (${ids.map((_, i) => `$${i + 1}`).join(", ")})`, [...ids]);
|
|
236
|
+
return new Map(res.rows.map((r) => [String(r.session_id), sessionFaceFromRow(String(r.session_id), r.owner ?? null, r.incarnation)]));
|
|
237
|
+
}
|
|
238
|
+
async insertMeta(sessionId, owner, placement) {
|
|
226
239
|
const now = new Date();
|
|
227
240
|
await this.pool.query("INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation, " +
|
|
228
241
|
"placement_kind, placement_scope, placement_parent_session_id, placement_root_session_id, placement_handle, placed_at) " +
|
|
@@ -516,7 +529,7 @@ export class PgSessionStore {
|
|
|
516
529
|
}
|
|
517
530
|
await conn.query("DELETE FROM session_event WHERE session_id = $1", [sessionId]);
|
|
518
531
|
await conn.query("DELETE FROM session_meta WHERE session_id = $1 AND owner IS NOT DISTINCT FROM $2 AND placement_kind IS NULL", [sessionId, owner]);
|
|
519
|
-
await this.insertValidatedLog(conn, sessionId, owner, validated, carriedIncarnation(placedRes.rows[0], owner));
|
|
532
|
+
await this.insertValidatedLog(conn, sessionId, owner, validated, carriedIncarnation(sessionId, placedRes.rows[0], owner));
|
|
520
533
|
await conn.query("COMMIT");
|
|
521
534
|
}
|
|
522
535
|
catch (err) {
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import { type LaneHomeConfig } from "../lane-home-probe.js";
|
|
2
3
|
import { FileError, ExecutionError, RemoteExecutionError, type ExecutionEnv, type RemoteExecutionEnv, type WorkspaceHandle, type FileInfo, type Result, type SymlinkChain, type OutputChunk, type ExecStreamOptions, type RemoteConnectConfig, type SnapshotId, type SessionToken, type VmLifecycleOptions, type ExecutionEnvFactory } from "@sema-agent/core";
|
|
3
4
|
type ExecOpts = Parameters<ExecutionEnv["exec"]>[1];
|
|
4
|
-
export interface AdbEnvConfig {
|
|
5
|
+
export interface AdbEnvConfig extends LaneHomeConfig {
|
|
5
6
|
/** Device serial or `host:port` (TCP). `host:port` triggers `adb connect` on connect()/reconnect(). */
|
|
6
7
|
serial: string;
|
|
7
8
|
/** Path to the adb binary. Default "adb" (must be on PATH in the runner image). */
|
|
8
9
|
adbPath?: string;
|
|
9
|
-
/**
|
|
10
|
-
* S-213④ / core [ref] —— 本执行环境的 **home 目录**(`ExecutionEnv.homeDir` 座,绝对路径,本环境自己的
|
|
11
|
-
* 命名空间里)。`~/…` 形权限规则(`Edit(~/.ssh/**)`)对**跑在本 env 里的调用**就以它为基。
|
|
12
|
-
* 缺席 ⇒ 本 env 声明「我没有 home」,core 对 `~/` 规则判 `unreadable`(fail-closed 的 ask),
|
|
13
|
-
* 绝不回落引擎进程自己的 home(那在远端腿上是另一个用户的另一个目录 —— 静默守错目录正是 [ref] 的病)。
|
|
14
|
-
* 值由 `boot/execution-env.ts` 从**唯一属主** `execution-lane-caps.ts` 的 `executionLaneHomeDir` 递进来;
|
|
15
|
-
* adapter 不自算(两处各算一份 = 422 门与引擎对同一条规则给相反答案)。
|
|
16
|
-
*/
|
|
17
|
-
homeDir?: string;
|
|
18
10
|
/** On-device workspace root; relative paths resolve against it. Default "/data/local/tmp". */
|
|
19
11
|
mountPath?: string;
|
|
20
12
|
commandTimeoutMs?: number;
|
|
@@ -86,8 +78,10 @@ export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
|
|
|
86
78
|
private destroyed;
|
|
87
79
|
/** 在飞的那一次懒连接(单飞记忆)——见 {@link ensureConnected}。settle 即清,**不缓存败诺**。 */
|
|
88
80
|
private connectPromise?;
|
|
89
|
-
/** core `ExecutionEnv.homeDir`([ref])
|
|
90
|
-
|
|
81
|
+
/** core `ExecutionEnv.homeDir`([ref]):设备 shell 里执行用户的 home —— 声明胜,否则首连时 `adb shell` 实测的 `$HOME`(Android 常为 `/` 或 `/data/local/tmp` 一类,读到什么填什么,绝对即可),见 {@link LaneHomeSeat}。读时才取(没声明时连上之前缺席)。 */
|
|
82
|
+
get homeDir(): string | undefined;
|
|
83
|
+
/** 家目录的座(声明胜 · 否则首连时实测 · 实测缺席 ⇒ 缺席 + 一行 warn)。本车道**不对证**声明:Android 没有 POSIX 登录家目录,声明是运维的断言,照单全收。 */
|
|
84
|
+
private readonly homeSeat;
|
|
91
85
|
/** core 7.49.0 #1554:shell 子进程真拿到的 `CDPATH` 条目 —— 本车道的命令跑在 Android 设备的 shell 里(设备自己的 env),本类不读那份 env ⇒ `"unknown"`(core 契约:说不出就说 unknown,
|
|
92
86
|
* 不许报一张没读过的空表;删除守卫因此对裸 `cd <相对名>` 之后的删除问人,而不是按「没有 CDPATH」放行)。 */
|
|
93
87
|
readonly cdPath: "unknown";
|
|
@@ -204,6 +198,12 @@ export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
|
|
|
204
198
|
suffix?: string;
|
|
205
199
|
abortSignal?: AbortSignal;
|
|
206
200
|
}): Promise<Result<string, FileError>>;
|
|
201
|
+
/**
|
|
202
|
+
* 交给宿主 `adb` CLI 的 env —— 宿主子进程 env 的唯一组合(`server-secret-env.ts` `hostSubprocessEnv`),继承词 `"all"`:本服务自有凭据(起服声明的名与值)
|
|
203
|
+
* 任何词都不交,adb 自己要读的变量(`ADB_VENDOR_KEYS` / `ANDROID_*` …)照交 —— 形状剥会剥 `ADB_VENDOR_KEYS`(名形),设备鉴权因此断。首次调用拉起的常驻 adb server
|
|
204
|
+
* 继承的就是这一份。命令本身跑在设备的 shell 里,本 env 到不了设备。每次起进程现算一次(与 host shell 同)。
|
|
205
|
+
*/
|
|
206
|
+
private cliEnv;
|
|
207
207
|
/** Spawn the adb binary with the given args; collect stdout/stderr (+ raw bytes when binary), bound by timeout/abort. */
|
|
208
208
|
private adb;
|
|
209
209
|
/**
|
|
@@ -2,9 +2,11 @@ import path from "node:path";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
|
+
import { hostSubprocessEnv } from "../server-secret-env.js";
|
|
6
|
+
import { LANE_HOME_PROBE_COMMAND, LaneHomeSeat } from "../lane-home-probe.js";
|
|
5
7
|
import { buildCwdEnvCommand, createCwdGuardedCall, shellQuote, armPipeDestroyGrace } from "./remote-shell.js";
|
|
6
8
|
import { signalNumber } from "./host-platform.js";
|
|
7
|
-
import {
|
|
9
|
+
import { buildLivenessCut, commandBoundsOf } from "../exec-bounds.js";
|
|
8
10
|
import { FileError, ExecutionError, RemoteExecutionError, withRetry, RollingTailBuffer, markTruncated, } from "@sema-agent/core";
|
|
9
11
|
import { classifyFsStderr, fileErrorFromExec } from "./remote-env-file-error.js";
|
|
10
12
|
import { createPosixShellFs } from "./posix-shell-fs.js";
|
|
@@ -30,7 +32,10 @@ export class RemoteAdbExecutionEnv {
|
|
|
30
32
|
connected = false;
|
|
31
33
|
destroyed = false;
|
|
32
34
|
connectPromise;
|
|
33
|
-
homeDir
|
|
35
|
+
get homeDir() {
|
|
36
|
+
return this.homeSeat.home;
|
|
37
|
+
}
|
|
38
|
+
homeSeat;
|
|
34
39
|
cdPath = "unknown";
|
|
35
40
|
cfg;
|
|
36
41
|
spawnFn;
|
|
@@ -45,7 +50,7 @@ export class RemoteAdbExecutionEnv {
|
|
|
45
50
|
retry: { maxAttempts: config.retry?.maxAttempts ?? 3, backoffMs: config.retry?.backoffMs ?? 800 },
|
|
46
51
|
};
|
|
47
52
|
this.cwd = this.cfg.mountPath;
|
|
48
|
-
this.
|
|
53
|
+
this.homeSeat = new LaneHomeSeat({ lane: PROVIDER, declared: config.homeDir, verifiesDeclared: false, onAbsent: config.onHomeAbsent });
|
|
49
54
|
this.spawnFn = deps?.spawn ?? spawn;
|
|
50
55
|
this.injectedConnectOnce = deps?.connectOnce;
|
|
51
56
|
}
|
|
@@ -116,6 +121,12 @@ export class RemoteAdbExecutionEnv {
|
|
|
116
121
|
error: new RemoteExecutionError("unsupported", `device ${this.cfg.serial} does not advertise the 'shell_v2' feature, so this adapter cannot establish that its command round-trip carries a real exit code with stderr kept separate — the two properties every filesystem judgment on this lane depends on to tell failure from success. Refusing to connect rather than run on an unverifiable transport: attach a device that supports adb shell protocol v2.`),
|
|
117
122
|
};
|
|
118
123
|
}
|
|
124
|
+
if (this.homeSeat.asks) {
|
|
125
|
+
const home = await this.adb(this.deviceShellArgs(LANE_HOME_PROBE_COMMAND), { signal, timeoutMs: this.cfg.commandTimeoutMs });
|
|
126
|
+
if (!home.ok && home.error.code === "aborted")
|
|
127
|
+
return { ok: false, error: new RemoteExecutionError("aborted", "connect aborted while reading the device's home") };
|
|
128
|
+
this.homeSeat.settle(home.ok && home.value.exitCode === 0 ? { ok: true, stdout: home.value.stdout } : { ok: false, reason: home.ok ? `exit ${home.value.exitCode}` : home.error.message });
|
|
129
|
+
}
|
|
119
130
|
this.connected = true;
|
|
120
131
|
return ok(this.workspaceHandle());
|
|
121
132
|
}
|
|
@@ -180,7 +191,7 @@ export class RemoteAdbExecutionEnv {
|
|
|
180
191
|
if (this.destroyed)
|
|
181
192
|
throw new RemoteExecutionError("connect_failed", "execution env already destroyed");
|
|
182
193
|
const wrapped = buildCwdEnvCommand(command, this.workingDirOf(options?.cwd), options?.env, "raw").command;
|
|
183
|
-
const child = this.spawnFn(this.cfg.adbPath, this.deviceShellArgs(wrapped), { stdio: ["ignore", "pipe", "pipe"] });
|
|
194
|
+
const child = this.spawnFn(this.cfg.adbPath, this.deviceShellArgs(wrapped), { stdio: ["ignore", "pipe", "pipe"], env: this.cliEnv() });
|
|
184
195
|
const queue = [];
|
|
185
196
|
let finished = false;
|
|
186
197
|
let failure;
|
|
@@ -276,7 +287,8 @@ export class RemoteAdbExecutionEnv {
|
|
|
276
287
|
clearTimeout(waitTimer);
|
|
277
288
|
}
|
|
278
289
|
if (liveness !== undefined && !finished && Date.now() - lastChunk >= liveness.ms) {
|
|
279
|
-
|
|
290
|
+
const cut = buildLivenessCut(liveness);
|
|
291
|
+
throw new RemoteExecutionError(cut.code, cut.message);
|
|
280
292
|
}
|
|
281
293
|
}
|
|
282
294
|
while (queue.length)
|
|
@@ -417,13 +429,16 @@ export class RemoteAdbExecutionEnv {
|
|
|
417
429
|
async createTempFile(options) {
|
|
418
430
|
return this.posixFs.createTempFile(options);
|
|
419
431
|
}
|
|
432
|
+
cliEnv() {
|
|
433
|
+
return hostSubprocessEnv({ site: "server.remote-env-adb.spawn-env", policy: "all", allow: [] });
|
|
434
|
+
}
|
|
420
435
|
adb(args, opts) {
|
|
421
436
|
if (this.destroyed)
|
|
422
437
|
return Promise.resolve({ ok: false, error: new ExecutionError("shell_unavailable", "execution env already destroyed") });
|
|
423
438
|
return new Promise((resolve) => {
|
|
424
439
|
let settled = false;
|
|
425
440
|
let forceSettleTimer;
|
|
426
|
-
const child = this.spawnFn(this.cfg.adbPath, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
441
|
+
const child = this.spawnFn(this.cfg.adbPath, args, { stdio: ["ignore", "pipe", "pipe"], env: this.cliEnv() });
|
|
427
442
|
const killGrace = () => {
|
|
428
443
|
try {
|
|
429
444
|
child.kill("SIGKILL");
|
|
@@ -12,6 +12,7 @@ export const DEVICE_OUTCOME_TO_FILE_ERROR = {
|
|
|
12
12
|
callback_error: "unknown",
|
|
13
13
|
invalid: "invalid",
|
|
14
14
|
is_directory: "is_directory",
|
|
15
|
+
liveness_no_output: "unknown",
|
|
15
16
|
not_directory: "not_directory",
|
|
16
17
|
not_found: "not_found",
|
|
17
18
|
not_supported: "not_supported",
|
|
@@ -33,6 +34,7 @@ export const DEVICE_OUTCOME_TO_EXEC_ERROR = {
|
|
|
33
34
|
callback_error: "callback_error",
|
|
34
35
|
invalid: "unknown",
|
|
35
36
|
is_directory: "unknown",
|
|
37
|
+
liveness_no_output: "liveness_no_output",
|
|
36
38
|
not_directory: "unknown",
|
|
37
39
|
not_found: "unknown",
|
|
38
40
|
not_supported: "shell_unavailable",
|
|
@@ -763,6 +765,7 @@ const OUTCOME_TO_REMOTE_ERROR = {
|
|
|
763
765
|
callback_error: "unknown",
|
|
764
766
|
invalid: "unknown",
|
|
765
767
|
is_directory: "unknown",
|
|
768
|
+
liveness_no_output: "liveness_no_output",
|
|
766
769
|
not_directory: "unknown",
|
|
767
770
|
not_found: "unknown",
|
|
768
771
|
not_supported: "unsupported",
|
|
@@ -321,7 +321,7 @@ export declare class RemoteContainerExecutionEnv implements RemoteExecutionEnv,
|
|
|
321
321
|
* a command that hangs DURING execution (not creation) would otherwise wait the E2B command timeout (= the
|
|
322
322
|
* lifetime when none is set, the original hang bug). With a `liveness` bound (the caller stated no `timeout` —
|
|
323
323
|
* `exec-bounds.ts`) it races wait() against an idle check: no stdout/stderr for `liveness.ms` ⇒ hung → kill + typed
|
|
324
|
-
* retryable
|
|
324
|
+
* retryable `liveness_no_output` (the shared cut: code, sentence and the window in whole seconds — `buildLivenessCut`). `lastProgress()` is bumped by the stdout/stderr callbacks, so a
|
|
325
325
|
* slow-but-PROGRESSING command (long `npm ci`) is never killed. Both cuts reject with an `ExecutionError` carrying
|
|
326
326
|
* its real code (exec returns it as-is) — a `RemoteExecutionError` here would reach {@link execError}'s text match
|
|
327
327
|
* and land as `unknown`. The rejection is armed BEFORE the kill: the kill rejects `wait()` too, and the race must
|
|
@@ -3,7 +3,7 @@ import { Sandbox, CommandExitError, FileType } from "e2b";
|
|
|
3
3
|
import { FileError, ExecutionError, RemoteExecutionError, RollingTailBuffer, markTruncated, } from "@sema-agent/core";
|
|
4
4
|
import { fileErrorFromExec } from "./remote-env-file-error.js";
|
|
5
5
|
import { numEnvOr, runSymlinkChain, shellQuote } from "./remote-shell.js";
|
|
6
|
-
import { commandBoundsOf, firstBoundOf, laneLivenessOf,
|
|
6
|
+
import { buildLivenessCut, commandBoundsOf, firstBoundOf, laneLivenessOf, LIVENESS_MS_DEFAULT } from "../exec-bounds.js";
|
|
7
7
|
import { BackgroundShellManager } from "./background-shell-support.js";
|
|
8
8
|
const PROVIDER = "e2b";
|
|
9
9
|
const DEFAULT_MOUNT_PATH = "/home/user";
|
|
@@ -297,7 +297,10 @@ export class RemoteContainerExecutionEnv {
|
|
|
297
297
|
startCut = true;
|
|
298
298
|
this.settleAbandonedStart(starting);
|
|
299
299
|
const cut = e instanceof RemoteExecutionError && e.code === "timeout" && !options?.abortSignal?.aborted;
|
|
300
|
-
|
|
300
|
+
if (!cut)
|
|
301
|
+
return { ok: false, error: this.execError(e, options?.abortSignal) };
|
|
302
|
+
const bc = boundCut(first);
|
|
303
|
+
return { ok: false, error: new ExecutionError(bc.code, bc.message, undefined, undefined, bc.noOutputSec) };
|
|
301
304
|
}
|
|
302
305
|
const onAbort = () => { if (!detached)
|
|
303
306
|
void handle.kill().catch(() => { }); };
|
|
@@ -425,8 +428,10 @@ export class RemoteContainerExecutionEnv {
|
|
|
425
428
|
catch (e) {
|
|
426
429
|
finished = true;
|
|
427
430
|
this.settleAbandonedStart(starting);
|
|
428
|
-
if (e instanceof RemoteExecutionError && e.code === "timeout" && !options?.signal?.aborted)
|
|
429
|
-
|
|
431
|
+
if (e instanceof RemoteExecutionError && e.code === "timeout" && !options?.signal?.aborted) {
|
|
432
|
+
const bc = boundCut(first);
|
|
433
|
+
throw new RemoteExecutionError(bc.code, bc.message, e);
|
|
434
|
+
}
|
|
430
435
|
throw this.remoteError(e, "connect_failed");
|
|
431
436
|
}
|
|
432
437
|
handle
|
|
@@ -490,7 +495,10 @@ export class RemoteContainerExecutionEnv {
|
|
|
490
495
|
const idle = liveness === undefined
|
|
491
496
|
? undefined
|
|
492
497
|
: new Promise((_, reject) => {
|
|
493
|
-
timer = setTimeout(() =>
|
|
498
|
+
timer = setTimeout(() => {
|
|
499
|
+
const cut = buildLivenessCut(liveness);
|
|
500
|
+
reject(new RemoteExecutionError(cut.code, cut.message));
|
|
501
|
+
}, liveness.ms);
|
|
494
502
|
});
|
|
495
503
|
try {
|
|
496
504
|
await (idle === undefined ? next : Promise.race([next, idle]));
|
|
@@ -850,7 +858,8 @@ export class RemoteContainerExecutionEnv {
|
|
|
850
858
|
return;
|
|
851
859
|
const idleFor = Date.now() - lastProgress();
|
|
852
860
|
if (idleFor >= bound.ms) {
|
|
853
|
-
|
|
861
|
+
const cut = buildLivenessCut(bound);
|
|
862
|
+
reject(new ExecutionError(cut.code, cut.message, undefined, undefined, cut.noOutputSec));
|
|
854
863
|
void handle.kill().catch(() => { });
|
|
855
864
|
this.cfg.metrics?.inc("remote_env_exec_idle_timeout_total", { provider: PROVIDER });
|
|
856
865
|
}
|
|
@@ -866,7 +875,7 @@ export class RemoteContainerExecutionEnv {
|
|
|
866
875
|
wallTimer = setTimeout(() => {
|
|
867
876
|
if (opts.disarmed?.())
|
|
868
877
|
return;
|
|
869
|
-
reject(new ExecutionError("timeout",
|
|
878
|
+
reject(new ExecutionError("timeout", wallCutMessage(wall.totalMs)));
|
|
870
879
|
void handle.kill().catch(() => { });
|
|
871
880
|
}, wall.leftMs);
|
|
872
881
|
}
|
|
@@ -969,8 +978,11 @@ export function e2bExecutionEnvFactory(config, deps) {
|
|
|
969
978
|
function errMsg(e) {
|
|
970
979
|
return e instanceof Error ? e.message : String(e);
|
|
971
980
|
}
|
|
972
|
-
function
|
|
973
|
-
return
|
|
981
|
+
function wallCutMessage(ms) {
|
|
982
|
+
return `exec exceeded ${ms}ms`;
|
|
983
|
+
}
|
|
984
|
+
function boundCut(first) {
|
|
985
|
+
return first.cut === "wall" ? { code: "timeout", message: wallCutMessage(first.ms) } : buildLivenessCut(first.cut);
|
|
974
986
|
}
|
|
975
987
|
function providerTimedOut(e) {
|
|
976
988
|
return e?.name === "TimeoutError" || /timeout|timed out/i.test(errMsg(e));
|
|
@@ -314,17 +314,17 @@ export declare class RemoteHostExecutionEnv implements RemoteExecutionEnv, Sched
|
|
|
314
314
|
canonicalPath(p: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>>;
|
|
315
315
|
readLink(p: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>>;
|
|
316
316
|
/**
|
|
317
|
-
* S-362 / core 7.21.0 [ref] —— **实现**(表态:本腿实现 `canonicalChain`)。host 腿是 node:fs
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
* (UNC)时**记下该跳并停止探测**(不碰网络,CC `vr` 对网络拼法只给拼法)。
|
|
317
|
+
* S-362 / core 7.21.0 [ref] —— **实现**(表态:本腿实现 `canonicalChain`)。host 腿是 node:fs 腿:走法(对整条拼法 `readlink`、再对每一跳
|
|
318
|
+
* `readlink`,**上限**、**只锚不折**、**遇环即止**、win32 宿主上跳到共享(UNC)时**记下该跳并停止探测** —— 不碰网络)是 core 导出的
|
|
319
|
+
* `walkSymlinkChain`,本腿只供它**逐跳的读口**;上限、播种、锚法、UNC 判都在那一只里,本仓不再重写第二遍。
|
|
321
320
|
*
|
|
322
|
-
* 🔴
|
|
323
|
-
*
|
|
324
|
-
*
|
|
321
|
+
* 🔴 为什么本腿仍自备读口而不是整体复用 core 的 `NodeExecutionEnv.canonicalChain`:本腿的每一次读都必须先过 {@link fsReady}
|
|
322
|
+
* (2026-07-25 全族统一:拆除之后只读面不得与写面自相矛盾),那道门在 core 的实现里不存在 —— 门在**起点**过一次,读口不再逐跳过
|
|
323
|
+
* (中途 destroy 不改变「这一次链读」的读数:每跳是同一次往返里对本机盘的读,与旧循环逐字同姿势)。
|
|
325
324
|
*
|
|
326
|
-
* 链尽的三种 errno(`EINVAL` 不是软链 / `ENOENT` 不存在 / `ENOTDIR`)
|
|
327
|
-
* (`EACCES` …)⇒ `ok:false`(core 读作「这一次没有跳」,**永不是拒绝**)
|
|
325
|
+
* 链尽的三种 errno(`EINVAL` 不是软链 / `ENOENT` 不存在 / `ENOTDIR`)由本腿的 `fileError` 归成 `invalid` / `not_found` / `not_directory`,
|
|
326
|
+
* core 的走法读作「到此为止」⇒ `ok` + 到此为止的跳;其余 errno(`EACCES` …)⇒ `ok:false`(core 读作「这一次没有跳」,**永不是拒绝**)。
|
|
327
|
+
* 非链接的叶答 `[]`。同形的判据钉在 `test/remote-env-canonical-chain.test.ts`,「读 core 导出」的钉在 `test/core-export-single-source-*.test.ts`。
|
|
328
328
|
*/
|
|
329
329
|
canonicalChain(p: string, abortSignal?: AbortSignal): Promise<Result<SymlinkChain, FileError>>;
|
|
330
330
|
exists(p: string, abortSignal?: AbortSignal): Promise<Result<boolean, FileError>>;
|
|
@@ -5,12 +5,12 @@ import fs from "node:fs/promises";
|
|
|
5
5
|
import { randomBytes } from "node:crypto";
|
|
6
6
|
import { openSync, closeSync, readSync, statSync, truncateSync, unlinkSync, mkdirSync, rmdirSync, mkdtempSync, existsSync, realpathSync, accessSync, constants as FS_CONST } from "node:fs";
|
|
7
7
|
import { StringDecoder } from "node:string_decoder";
|
|
8
|
-
import { armPipeDestroyGrace, numEnvOr
|
|
9
|
-
import {
|
|
8
|
+
import { armPipeDestroyGrace, numEnvOr } from "./remote-shell.js";
|
|
9
|
+
import { buildLivenessCut, commandBoundsOf } from "../exec-bounds.js";
|
|
10
10
|
import { hostBackgroundShellEnabled, hostExecSpoolEnabled } from "../config.js";
|
|
11
11
|
import { IS_WIN32, resolveHostShell, hostShell, pinHostShell, spawnGroupOptions, killTreeHard, killTreeSoft, hardKillGroupNow, collapseWin32EnvKeys, adoptHostForegroundChild } from "./host-platform.js";
|
|
12
12
|
import { BackgroundShellManager, seedMemStream, feedMemStream, drainMemStream } from "./background-shell-support.js";
|
|
13
|
-
import { FileError, NodeExecutionEnv, inheritEnvPolicyProblem, ExecutionError, RemoteExecutionError, RollingTailBuffer, markTruncated, SchedulerError, BackgroundShellError, } from "@sema-agent/core";
|
|
13
|
+
import { FileError, NodeExecutionEnv, inheritEnvPolicyProblem, ExecutionError, RemoteExecutionError, RollingTailBuffer, walkSymlinkChain, markTruncated, SchedulerError, BackgroundShellError, } from "@sema-agent/core";
|
|
14
14
|
import { composeHostSubprocessEnv, hostSubprocessEnv } from "../server-secret-env.js";
|
|
15
15
|
import { trackEphemeralHostWorkspace, untrackEphemeralHostWorkspace } from "./host-workspace-registry.js";
|
|
16
16
|
const PROVIDER = "host";
|
|
@@ -24,7 +24,6 @@ const HOST_BG_FILE_CAP = numEnvOr("HOST_BG_FILE_CAP", 64 * 1024 * 1024, HOST_BG_
|
|
|
24
24
|
export const HOST_BG_KILL_GRACE_MS = numEnvOr("HOST_BG_KILL_GRACE_MS", 1000, 0);
|
|
25
25
|
const HOST_BG_MEM_CAP = numEnvOr("HOST_BG_MEM_CAP", 8 * 1024 * 1024, 64 * 1024);
|
|
26
26
|
const ok = (value) => ({ ok: true, value });
|
|
27
|
-
const UNC_SPELLING = /^[\\/]{2}[^\\/]+[\\/]+[^\\/]/;
|
|
28
27
|
const unsupported = (op) => ({
|
|
29
28
|
ok: false,
|
|
30
29
|
error: new RemoteExecutionError("unsupported", `${op} is not supported on a host target (the operator's own machine — no container boundary, not snapshotable; capabilities.suspendable=false)`),
|
|
@@ -919,7 +918,8 @@ export class RemoteHostExecutionEnv {
|
|
|
919
918
|
if (liveness !== undefined && !finished && Date.now() - lastChunk >= liveness.ms) {
|
|
920
919
|
finished = true;
|
|
921
920
|
kill();
|
|
922
|
-
|
|
921
|
+
const cut = buildLivenessCut(liveness);
|
|
922
|
+
throw new RemoteExecutionError(cut.code, cut.message);
|
|
923
923
|
}
|
|
924
924
|
}
|
|
925
925
|
while (queue.length)
|
|
@@ -1099,36 +1099,14 @@ export class RemoteHostExecutionEnv {
|
|
|
1099
1099
|
const ready = await this.fsReady(p);
|
|
1100
1100
|
if (!ready.ok)
|
|
1101
1101
|
return ready;
|
|
1102
|
-
|
|
1103
|
-
let cur = this.resolve(p);
|
|
1104
|
-
const seen = new Set([cur]);
|
|
1105
|
-
for (let i = 0; i < SYMLINK_CHAIN_MAX_HOPS; i += 1) {
|
|
1106
|
-
let target;
|
|
1102
|
+
return walkSymlinkChain(this.resolve(p), async (hop) => {
|
|
1107
1103
|
try {
|
|
1108
|
-
|
|
1104
|
+
return ok(await fs.readlink(hop));
|
|
1109
1105
|
}
|
|
1110
1106
|
catch (e) {
|
|
1111
|
-
|
|
1112
|
-
if (fe.code === "invalid" || fe.code === "not_found" || fe.code === "not_directory")
|
|
1113
|
-
break;
|
|
1114
|
-
return { ok: false, error: fe };
|
|
1107
|
+
return { ok: false, error: this.fileError(e, hop, abortSignal) };
|
|
1115
1108
|
}
|
|
1116
|
-
|
|
1117
|
-
if (path.isAbsolute(target))
|
|
1118
|
-
next = target;
|
|
1119
|
-
else {
|
|
1120
|
-
const dir = path.dirname(cur);
|
|
1121
|
-
next = dir.endsWith(path.sep) ? `${dir}${target}` : `${dir}${path.sep}${target}`;
|
|
1122
|
-
}
|
|
1123
|
-
if (seen.has(next))
|
|
1124
|
-
break;
|
|
1125
|
-
seen.add(next);
|
|
1126
|
-
hops.push(next);
|
|
1127
|
-
if (IS_WIN32 && UNC_SPELLING.test(next))
|
|
1128
|
-
break;
|
|
1129
|
-
cur = next;
|
|
1130
|
-
}
|
|
1131
|
-
return ok({ hops });
|
|
1109
|
+
});
|
|
1132
1110
|
}
|
|
1133
1111
|
async exists(p, abortSignal) {
|
|
1134
1112
|
const ready = await this.fsReady(p);
|
|
@@ -1325,7 +1303,7 @@ export class RemoteHostExecutionEnv {
|
|
|
1325
1303
|
}
|
|
1326
1304
|
childEnv(perCommand, spawnShell) {
|
|
1327
1305
|
const base = spawnShell !== undefined
|
|
1328
|
-
? hostSubprocessEnv({ site: "server.remote-env-host.
|
|
1306
|
+
? hostSubprocessEnv({ site: "server.remote-env-host.spawn-env", policy: this.cfg.inheritEnv, allow: [] })
|
|
1329
1307
|
: composeHostSubprocessEnv({ policy: this.cfg.inheritEnv, allow: [] });
|
|
1330
1308
|
if (this.cfg.env)
|
|
1331
1309
|
Object.assign(base, this.cfg.env);
|