@sema-agent/server 1.322.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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-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 +546 -0
- package/dist/config.d.ts +64 -0
- package/dist/config.js +455 -60
- 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 +2132 -96
- 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 +59 -3
- 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
|
@@ -2,6 +2,7 @@ import { SchedulerError } from "@sema-agent/core";
|
|
|
2
2
|
import type { SchedulerCapability, ScheduledIntent, SchedulerContext, ScheduledTaskId, ScheduledTaskSummary } from "@sema-agent/core";
|
|
3
3
|
import type { SchedulerRecord } from "@sema-agent/registry-core/scheduler-store";
|
|
4
4
|
export type { SchedulerRecord };
|
|
5
|
+
/** core `Result<T,E>` shape (harness/types) — `{ok:true,value} | {ok:false,error}`. */
|
|
5
6
|
type Result<T, E> = {
|
|
6
7
|
ok: true;
|
|
7
8
|
value: T;
|
|
@@ -9,6 +10,7 @@ type Result<T, E> = {
|
|
|
9
10
|
ok: false;
|
|
10
11
|
error: E;
|
|
11
12
|
};
|
|
13
|
+
/** Default caps (fail-closed bounds; design/105 §3.9). Override per deployment. */
|
|
12
14
|
export declare const DEFAULT_SCHEDULER_CAPS: {
|
|
13
15
|
readonly supported: true;
|
|
14
16
|
readonly maxScheduledPerScope: 32;
|
|
@@ -19,8 +21,18 @@ export declare const DEFAULT_SCHEDULER_CAPS: {
|
|
|
19
21
|
readonly supportsSessionWakeup: true;
|
|
20
22
|
};
|
|
21
23
|
type Caps = SchedulerCapability["schedulerCapabilities"];
|
|
24
|
+
/**
|
|
25
|
+
* PURE validation of an intent against caps + now. Returns a SchedulerError or null (ok). No IO. Testable.
|
|
26
|
+
* cron via core `isValidCronExpr` (RCE-safe, no shell-exec); delay/at bounded by minDelaySec + horizon.
|
|
27
|
+
*/
|
|
22
28
|
export declare function validateIntent(intent: ScheduledIntent, caps: Caps, nowMs: number): SchedulerError | null;
|
|
29
|
+
/** The default shared store path: `SEMA_CONFIG_DIR` → `~/.sema`, file `scheduled_tasks.json` (server + shell agree). */
|
|
23
30
|
export declare function defaultSchedulerStorePath(): string;
|
|
31
|
+
/**
|
|
32
|
+
* File-backed SchedulerCapability (durable across daemon restarts). Store = a single JSON file (atomic write via
|
|
33
|
+
* the registry-core /node binding). The resident shell daemon reads the same store to fire intents. `now`
|
|
34
|
+
* injectable for tests.
|
|
35
|
+
*/
|
|
24
36
|
export declare class FileSchedulerBackend implements SchedulerCapability {
|
|
25
37
|
readonly schedulerCapabilities: Caps;
|
|
26
38
|
private readonly storePath;
|
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/plugins/scheduler-support.ts — the server-side `SchedulerCapability` backend (R7 self-wake).
|
|
3
|
+
*
|
|
4
|
+
* core 1.165.0 ships the `SchedulerCapability` seam (design/105): core 出接口 + 工具壳 (现名 CronCreate/CronDelete/
|
|
5
|
+
* CronList——L8 订正:CronCancel 旧名、Sleep 已 design/136 撤除、挂载在 core prepare-task 非 createHandsToolkit,
|
|
6
|
+
* `hasScheduler(env)` 门不变) + the `hasScheduler` gate. **持久化 /
|
|
7
|
+
* cron 时钟 / idle 触发 / 起新 task 全在 backend** — core is request-driven, not resident. R7 splits the backend:
|
|
8
|
+
* - THIS file (server) = the SchedulerCapability impl: the WRITE side — schedule/cancel/list, persisted to the
|
|
9
|
+
* SHARED on-disk store. Injected into `RemoteHostExecutionEnv` (the TOC host lane). deps `@sema-agent/core` (fine
|
|
10
|
+
* server-side).
|
|
11
|
+
* - The TOC shell `SchedulerDaemon` (shell-host, design R7 part3b) = the READ side: a resident process that
|
|
12
|
+
* polls the SAME store, resolves cron, fires due intents via the SDK (principal pinned), and reaps.
|
|
13
|
+
*
|
|
14
|
+
* The shared on-disk FORMAT is the dep-free `@sema-agent/registry-core/scheduler-store` contract; the fs binding is
|
|
15
|
+
* `@sema-agent/registry-core/node`. server (writer) + shell daemon (reader) share ONE impl ⇒ zero format drift.
|
|
16
|
+
*
|
|
17
|
+
* Logic ported from the shell-host's canonical `scheduler/schedulerBackend.ts` (design doc
|
|
18
|
+
* `R7-scheduler-rewind.md` §1: the server reuses the same schedulerBackend logic verbatim).
|
|
19
|
+
*
|
|
20
|
+
* 🔴 红线 (design/105): `principal` is `ctx` (Runner-held) NOT `intent` (model-controllable) → pinned into the
|
|
21
|
+
* record, passed through to runTask unchanged by the daemon (no privilege escalation). cron via core
|
|
22
|
+
* `isValidCronExpr` (no shell-exec / RCE). scope isolation: cancel/list touch only the caller's scope. durable:
|
|
23
|
+
* the store is on disk (survives a daemon restart). upsert: same (scope, when, label) overwrites (idempotent on a
|
|
24
|
+
* tool retry).
|
|
25
|
+
*/
|
|
1
26
|
import { join } from "node:path";
|
|
2
27
|
import { homedir } from "node:os";
|
|
3
28
|
import { randomBytes, createHash } from "node:crypto";
|
|
@@ -5,15 +30,27 @@ import { SchedulerError, isValidCronExpr } from "@sema-agent/core";
|
|
|
5
30
|
import { loadSchedulerStore, saveSchedulerStore } from "@sema-agent/registry-core/node";
|
|
6
31
|
const ok = (value) => ({ ok: true, value });
|
|
7
32
|
const err = (error) => ({ ok: false, error });
|
|
33
|
+
/** Default caps (fail-closed bounds; design/105 §3.9). Override per deployment. */
|
|
8
34
|
export const DEFAULT_SCHEDULER_CAPS = {
|
|
9
35
|
supported: true,
|
|
10
36
|
maxScheduledPerScope: 32,
|
|
11
37
|
minDelaySec: 10,
|
|
12
38
|
minCronIntervalSec: 60,
|
|
13
|
-
maxScheduledHorizonSec: 60 * 60 * 24 * 30,
|
|
39
|
+
maxScheduledHorizonSec: 60 * 60 * 24 * 30, // 30d
|
|
40
|
+
// core 1.301 CronCreate durable/session 分层 ([950]): session-scoped jobs are persisted with
|
|
41
|
+
// lifetime:"session" and reaped by the resident shell daemon when the session ends. True here because
|
|
42
|
+
// this backend faithfully persists the lifetime field (schedule() below) — without the flag core's
|
|
43
|
+
// CronCreate refuses durable:false up front (fail-closed at the tool layer).
|
|
14
44
|
supportsSessionLifetime: true,
|
|
45
|
+
// core 1.309 ([1000]③ ScheduleWakeup 治本位): true = a resident daemon reads this store and fires
|
|
46
|
+
// session-wakeup records for its own sessions (the normal co-resident TOC shape). The DEPLOYMENT flips
|
|
47
|
+
// this to false via SCHEDULER_SESSION_WAKEUP=false when the spawning shell knows no daemon will honor
|
|
48
|
+
// them (headless spawn without a resident daemon) — core's ScheduleWakeup then refuses up front instead
|
|
49
|
+
// of parking a wakeup that never fires. Capability = instance-lifetime snapshot (core TOCTOU 契约条款),
|
|
50
|
+
// so the signal rides construction, never per-call.
|
|
15
51
|
supportsSessionWakeup: true,
|
|
16
52
|
};
|
|
53
|
+
/** Human-readable `when` summary for list(). */
|
|
17
54
|
function whenSummary(when) {
|
|
18
55
|
if (when.kind === "cron")
|
|
19
56
|
return `cron ${when.expr}`;
|
|
@@ -21,16 +58,30 @@ function whenSummary(when) {
|
|
|
21
58
|
return `at ${new Date(when.atMs).toISOString()}`;
|
|
22
59
|
return `delay ${when.delaySec}s`;
|
|
23
60
|
}
|
|
61
|
+
/** Upsert dedup key — same (scope, LANE, when, label) overwrites (idempotent on tool retry).
|
|
62
|
+
* The lane term is the lifetime identity (adversarial review F1): without it a session job and a durable
|
|
63
|
+
* job — or two different sessions' jobs — with the same (when, label) collide, and the daemon's
|
|
64
|
+
* session-end reap would then silently delete what USED to be a durable/other-session job. core's cron
|
|
65
|
+
* shorthand defaults to session lifetime with no label, so the collision is normal usage, not an edge. */
|
|
24
66
|
function dedupKey(scope, intent, sessionId) {
|
|
25
67
|
const lane = intent.lifetime === "session" ? `session:${sessionId ?? ""}` : "durable";
|
|
26
68
|
return createHash("sha256").update(JSON.stringify([scope, lane, intent.when, intent.label ?? ""])).digest("hex").slice(0, 16);
|
|
27
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* PURE validation of an intent against caps + now. Returns a SchedulerError or null (ok). No IO. Testable.
|
|
72
|
+
* cron via core `isValidCronExpr` (RCE-safe, no shell-exec); delay/at bounded by minDelaySec + horizon.
|
|
73
|
+
*/
|
|
28
74
|
export function validateIntent(intent, caps, nowMs) {
|
|
29
75
|
if (!intent.prompt || typeof intent.prompt !== "string")
|
|
30
76
|
return new SchedulerError("invalid_schedule", "prompt is required");
|
|
31
77
|
const w = intent.when;
|
|
32
78
|
const horizonMs = caps.maxScheduledHorizonSec * 1000;
|
|
33
79
|
if (w.kind === "cron") {
|
|
80
|
+
// Validate the cron is WELL-FORMED (RCE-safe — the expr never reaches a shell). The `minCronIntervalSec` FLOOR is
|
|
81
|
+
// NOT enforced here: realizing a cron's actual fire interval requires cron-next, which the design assigns to the
|
|
82
|
+
// resident daemon (it computes nextRunMs + can skip/floor a sub-interval fire). A 5-field cron's minimum interval
|
|
83
|
+
// is 60s, so the default 60s floor is naturally satisfied; a deployment that TIGHTENS minCronIntervalSec relies on
|
|
84
|
+
// the daemon to honor it. (Adversarial-review LOW: the advertised cap is daemon-enforced, not writer-enforced.)
|
|
34
85
|
if (!isValidCronExpr(w.expr))
|
|
35
86
|
return new SchedulerError("invalid_schedule", `invalid cron expression: ${w.expr}`);
|
|
36
87
|
}
|
|
@@ -52,6 +103,7 @@ export function validateIntent(intent, caps, nowMs) {
|
|
|
52
103
|
}
|
|
53
104
|
return null;
|
|
54
105
|
}
|
|
106
|
+
/** nextRunMs for at/delay (direct); cron left undefined here (the resident daemon computes via a cron lib). */
|
|
55
107
|
function computeNextRunMs(when, nowMs) {
|
|
56
108
|
if (when.kind === "at")
|
|
57
109
|
return when.atMs;
|
|
@@ -59,9 +111,15 @@ function computeNextRunMs(when, nowMs) {
|
|
|
59
111
|
return nowMs + when.delaySec * 1000;
|
|
60
112
|
return undefined;
|
|
61
113
|
}
|
|
114
|
+
/** The default shared store path: `SEMA_CONFIG_DIR` → `~/.sema`, file `scheduled_tasks.json` (server + shell agree). */
|
|
62
115
|
export function defaultSchedulerStorePath() {
|
|
63
116
|
return join(process.env.SEMA_CONFIG_DIR ?? join(homedir(), ".sema"), "scheduled_tasks.json");
|
|
64
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* File-backed SchedulerCapability (durable across daemon restarts). Store = a single JSON file (atomic write via
|
|
120
|
+
* the registry-core /node binding). The resident shell daemon reads the same store to fire intents. `now`
|
|
121
|
+
* injectable for tests.
|
|
122
|
+
*/
|
|
65
123
|
export class FileSchedulerBackend {
|
|
66
124
|
schedulerCapabilities;
|
|
67
125
|
storePath;
|
|
@@ -82,6 +140,8 @@ export class FileSchedulerBackend {
|
|
|
82
140
|
const bad = validateIntent(intent, this.schedulerCapabilities, nowMs);
|
|
83
141
|
if (bad)
|
|
84
142
|
return err(bad);
|
|
143
|
+
// A session-scoped job with no session to bind to could never be reaped (a zombie the daemon would
|
|
144
|
+
// fire forever) — core's CronCreate refuses this at the tool layer; refuse here too for non-tool callers.
|
|
85
145
|
if (intent.lifetime === "session" && !ctx.sessionId) {
|
|
86
146
|
return err(new SchedulerError("invalid_schedule", 'lifetime:"session" requires a session to bind to (ctx.sessionId missing)'));
|
|
87
147
|
}
|
|
@@ -91,6 +151,7 @@ export class FileSchedulerBackend {
|
|
|
91
151
|
const rr = r;
|
|
92
152
|
return r.scope === ctx.scope && dedupKey(r.scope, { when: r.when, label: r.label, lifetime: rr.lifetime }, r.sessionId) === key;
|
|
93
153
|
});
|
|
154
|
+
// Per-scope cap (excluding the upsert target — overwriting an existing one doesn't grow the count).
|
|
94
155
|
const scopeCount = records.filter((r) => r.scope === ctx.scope).length;
|
|
95
156
|
if (existingIdx < 0 && scopeCount >= this.schedulerCapabilities.maxScheduledPerScope) {
|
|
96
157
|
return err(new SchedulerError("limit_exceeded", `scope at cap (${this.schedulerCapabilities.maxScheduledPerScope})`));
|
|
@@ -99,12 +160,20 @@ export class FileSchedulerBackend {
|
|
|
99
160
|
const rec = {
|
|
100
161
|
id,
|
|
101
162
|
scope: ctx.scope,
|
|
102
|
-
...(ctx.principal ? { principal: ctx.principal } : {}),
|
|
163
|
+
...(ctx.principal ? { principal: ctx.principal } : {}), // 🔴 pinned from ctx (Runner-held), never intent
|
|
103
164
|
...(ctx.sessionId ? { sessionId: ctx.sessionId } : {}),
|
|
104
165
|
prompt: intent.prompt,
|
|
105
166
|
when: intent.when,
|
|
106
167
|
...(intent.label ? { label: intent.label } : {}),
|
|
168
|
+
// core 1.265 ScheduledIntent.mode(缺省 "task" 向后兼容):persist the execution shape —
|
|
169
|
+
// ScheduleWakeup's stop:true keys off the LIST face's mode echo (CC 206 D9); a dropped mode forced the
|
|
170
|
+
// shell onto its label fallback. registry-core SchedulerRecord optional fields are additive by contract.
|
|
107
171
|
...(intent.mode ? { mode: intent.mode } : {}),
|
|
172
|
+
// core 1.301 lifetime/recurring ([950]/[954]): persist BOTH so the daemon can reap session-scoped
|
|
173
|
+
// jobs and delete a recurring:false cron after its first firing. Dropping them here was [954]-(b):
|
|
174
|
+
// the tool answered "once" while the record said nothing → the daemon fired forever. Additive
|
|
175
|
+
// SchedulerRecord fields (registry-core contract), same posture as `mode` above. recurring is a
|
|
176
|
+
// tri-state (undefined = cron default "fire every match") — persist only when explicitly set.
|
|
108
177
|
...(intent.lifetime ? { lifetime: intent.lifetime } : {}),
|
|
109
178
|
...(intent.recurring !== undefined ? { recurring: intent.recurring } : {}),
|
|
110
179
|
createdMs: nowMs,
|
|
@@ -125,6 +194,7 @@ export class FileSchedulerBackend {
|
|
|
125
194
|
async cancel(id, ctx) {
|
|
126
195
|
const records = this.load();
|
|
127
196
|
const idx = records.findIndex((r) => r.id === id);
|
|
197
|
+
// 🔴 scope isolation: a non-own-scope id is `not_found` (don't leak existence). Idempotent: missing = ok.
|
|
128
198
|
if (idx < 0 || records[idx].scope !== ctx.scope)
|
|
129
199
|
return ok(undefined);
|
|
130
200
|
records.splice(idx, 1);
|
|
@@ -138,13 +208,15 @@ export class FileSchedulerBackend {
|
|
|
138
208
|
}
|
|
139
209
|
async list(ctx) {
|
|
140
210
|
const summaries = this.load()
|
|
141
|
-
.filter((r) => r.scope === ctx.scope)
|
|
211
|
+
.filter((r) => r.scope === ctx.scope) // 🔴 scope-scoped, not global
|
|
142
212
|
.map((r) => ({
|
|
143
213
|
id: r.id,
|
|
144
214
|
when: whenSummary(r.when),
|
|
145
215
|
...(r.label ? { label: r.label } : {}),
|
|
146
216
|
...(r.nextRunMs !== undefined ? { nextRunMs: r.nextRunMs } : {}),
|
|
217
|
+
// echo the persisted mode (additive; pre-1.159.x records lack it → undefined = shell label fallback).
|
|
147
218
|
...(r.mode ? { mode: r.mode } : {}),
|
|
219
|
+
// echo lifetime/recurring (ScheduledTaskSummary 1.302 fields; absent on pre-1.215 records).
|
|
148
220
|
...(r.lifetime ? { lifetime: r.lifetime } : {}),
|
|
149
221
|
...(r.recurring !== undefined ? { recurring: r.recurring } : {}),
|
|
150
222
|
}));
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
import type { Pool as MysqlPool } from "mysql2/promise";
|
|
2
2
|
import type { Pool as PgPool } from "pg";
|
|
3
3
|
import type { IssuedFileLink } from "./send-user-file.js";
|
|
4
|
+
/** Ledger scope sentinel for single-user issuance (no principal) — mirrors scopeSegment's "_" key segment. */
|
|
4
5
|
export declare const SENDFILE_SINGLE_USER_SCOPE = "_";
|
|
5
6
|
export interface SendFileLedgerEntry {
|
|
7
|
+
/** uuidv7 — PK and the keyset cursor (time-ordered, newest = lexicographically greatest). */
|
|
6
8
|
id: string;
|
|
9
|
+
/** Verified principal verbatim ("_" = single-user). NEVER derived from the hashed key segment (one-way). */
|
|
7
10
|
scope: string;
|
|
8
11
|
bucket: string;
|
|
9
12
|
objectKey: string;
|
|
10
13
|
track: "public" | "presigned";
|
|
11
14
|
filename: string;
|
|
12
15
|
size: number;
|
|
16
|
+
/** 0 = permanent (public track). */
|
|
13
17
|
ttlSec: number;
|
|
14
18
|
taskId?: string;
|
|
15
19
|
sessionId?: string;
|
|
16
20
|
createdAt: number;
|
|
17
21
|
}
|
|
18
22
|
export interface SendFileLedger {
|
|
23
|
+
/** Record one issued link. Idempotent on `id` (a retry after a lost ack must not duplicate). */
|
|
19
24
|
record(entry: SendFileLedgerEntry): Promise<void>;
|
|
25
|
+
/** Newest-first page of one scope's links; keyset = `id < beforeId` (listSessions posture: fetch limit+1
|
|
26
|
+
* to detect more). `beforeId` absent = first page. */
|
|
20
27
|
listByScope(scope: string, limit: number, beforeId?: string): Promise<SendFileLedgerEntry[]>;
|
|
21
28
|
}
|
|
22
29
|
export declare class TiDBSendFileLedger implements SendFileLedger {
|
|
@@ -43,15 +50,23 @@ export declare class FileSendFileLedger implements SendFileLedger {
|
|
|
43
50
|
constructor(root: string);
|
|
44
51
|
record(entry: SendFileLedgerEntry): Promise<void>;
|
|
45
52
|
listByScope(scope: string, limit: number, beforeId?: string): Promise<SendFileLedgerEntry[]>;
|
|
53
|
+
/** Release the append-log fd (LocalBackend.close → graceful-restart re-open). */
|
|
46
54
|
dispose(): void;
|
|
47
55
|
}
|
|
48
56
|
export interface LedgerRecordingDeps {
|
|
49
57
|
ledger: SendFileLedger;
|
|
58
|
+
/** Best-effort reclaim of the uploaded object when the record fails (issuer.deleteObject). */
|
|
50
59
|
deleteObject: (bucket: string, key: string) => Promise<void>;
|
|
51
60
|
warn?: (msg: string, meta?: Record<string, unknown>) => void;
|
|
52
61
|
now?: () => number;
|
|
53
62
|
newId?: () => string;
|
|
54
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Wrap a lane `send` with the ledger write point: upload+verify succeed (the inner send resolved) → record →
|
|
66
|
+
* only then return (the tool emits the file_link frame strictly after). Record failure ⇒ fail-loud for THIS
|
|
67
|
+
* file + delete of the uploaded object with ONE retry; the throw is the contract either way, and its message
|
|
68
|
+
* states the true reclaim outcome (F2: a failed reclaim = permanent orphan, warned with coordinates).
|
|
69
|
+
*/
|
|
55
70
|
export declare function withLedgerRecording(send: (path: string, ctx: {
|
|
56
71
|
taskId?: string;
|
|
57
72
|
sessionId?: string;
|
|
@@ -1,6 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SendUserFile server-side LEDGER (multi-tenant governance face, clay ruling 2026-07-14 — the second half of
|
|
3
|
+
* [768]②a: the object key carries a HASHED scope segment, so the store alone can't answer "which tenant sent
|
|
4
|
+
* what". This ledger is the scope↔object mapping the hash deliberately hides from URLs): one row per issued
|
|
5
|
+
* link, keyed by a uuidv7 `id` (time-ordered → keyset pagination), indexed by `scope` (the VERIFIED principal
|
|
6
|
+
* verbatim; "_" = the single-user sentinel, same as the checkpoint scope column).
|
|
7
|
+
*
|
|
8
|
+
* WRITE SEMANTICS (enforced by {@link withLedgerRecording}, wrapped around BOTH send lanes in main.ts): record
|
|
9
|
+
* AFTER upload+verify succeed and BEFORE the file_link frame is emitted. A record failure is FAIL-LOUD for that
|
|
10
|
+
* file (the governance face MUST have the row — a link the ledger can't see can't be listed or revoked) and the
|
|
11
|
+
* already-uploaded object is DELETED with one retry (a public-track object with no ledger row would be an
|
|
12
|
+
* unmanageable orphan); the thrown message reports the TRUE reclaim outcome (reclaimed vs orphan) but — 修4 —
|
|
13
|
+
* NEVER the coordinates or the cause (it is model-visible via the tool result; a bucket/key leak there would
|
|
14
|
+
* let the model rebuild the capability URL): those go to the operator log under a shared incident id.
|
|
15
|
+
*
|
|
16
|
+
* The ledger does NOT store URLs: the public-track URL is reconstructible from bucket+key, and a presigned-track
|
|
17
|
+
* URL is a decaying capability that would be expired by the time anyone lists it. Reads return metadata + key.
|
|
18
|
+
*
|
|
19
|
+
* Four twins behind one interface (the approval-exemption pattern): TiDB/PG = durable cross-replica SQL rows
|
|
20
|
+
* (`sendfile_link` table, DDL in tidb-pool.ts / pg-pool.ts); File = append-only JSONL hydrated on boot
|
|
21
|
+
* (fsync — a torn tail must not fabricate a row); Memory = tests / ephemeral.
|
|
22
|
+
*/
|
|
1
23
|
import { join } from "node:path";
|
|
2
24
|
import { AppendLog, ensureDir, readJsonlRecords, uuidv7 } from "@sema-agent/core";
|
|
25
|
+
/** Ledger scope sentinel for single-user issuance (no principal) — mirrors scopeSegment's "_" key segment. */
|
|
3
26
|
export const SENDFILE_SINGLE_USER_SCOPE = "_";
|
|
27
|
+
// ─── TiDB / MySQL twin ───────────────────────────────────────────────────────────────────────────────────
|
|
4
28
|
export class TiDBSendFileLedger {
|
|
5
29
|
pool;
|
|
6
30
|
constructor(pool) {
|
|
@@ -8,7 +32,8 @@ export class TiDBSendFileLedger {
|
|
|
8
32
|
}
|
|
9
33
|
async record(entry) {
|
|
10
34
|
await this.pool.query("INSERT INTO sendfile_link (id, scope, bucket, object_key, track, filename, byte_len, ttl_sec, task_id, session_id, created_at) " +
|
|
11
|
-
"VALUES (?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE id = id",
|
|
35
|
+
"VALUES (?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE id = id", // idempotent on the uuidv7 PK (retry-safe no-op)
|
|
36
|
+
[entry.id, entry.scope, entry.bucket, entry.objectKey, entry.track, entry.filename, entry.size, entry.ttlSec, entry.taskId ?? null, entry.sessionId ?? null, new Date(entry.createdAt)]);
|
|
12
37
|
}
|
|
13
38
|
async listByScope(scope, limit, beforeId) {
|
|
14
39
|
const [rows] = await this.pool.query("SELECT id, scope, bucket, object_key, track, filename, byte_len, ttl_sec, task_id, session_id, created_at FROM sendfile_link " +
|
|
@@ -16,6 +41,7 @@ export class TiDBSendFileLedger {
|
|
|
16
41
|
return rows.map((r) => rowToEntry(r));
|
|
17
42
|
}
|
|
18
43
|
}
|
|
44
|
+
// ─── PG twin (dialect twin — $n placeholders + ON CONFLICT) ──────────────────────────────────────────────
|
|
19
45
|
export class PgSendFileLedger {
|
|
20
46
|
pool;
|
|
21
47
|
constructor(pool) {
|
|
@@ -46,6 +72,7 @@ function rowToEntry(r) {
|
|
|
46
72
|
createdAt: new Date(r.created_at).getTime(),
|
|
47
73
|
};
|
|
48
74
|
}
|
|
75
|
+
// ─── Memory twin (tests / ephemeral) ─────────────────────────────────────────────────────────────────────
|
|
49
76
|
export class MemorySendFileLedger {
|
|
50
77
|
byScope = new Map();
|
|
51
78
|
async record(entry) {
|
|
@@ -55,7 +82,7 @@ export class MemorySendFileLedger {
|
|
|
55
82
|
this.byScope.set(entry.scope, m);
|
|
56
83
|
}
|
|
57
84
|
if (!m.has(entry.id))
|
|
58
|
-
m.set(entry.id, { ...entry });
|
|
85
|
+
m.set(entry.id, { ...entry }); // idempotent on id
|
|
59
86
|
}
|
|
60
87
|
async listByScope(scope, limit, beforeId) {
|
|
61
88
|
const m = this.byScope.get(scope);
|
|
@@ -68,6 +95,7 @@ export class MemorySendFileLedger {
|
|
|
68
95
|
.map((e) => ({ ...e }));
|
|
69
96
|
}
|
|
70
97
|
}
|
|
98
|
+
// ─── File twin (local lane — single append-only JSONL + boot hydrate, torn-tail-safe) ───────────────────
|
|
71
99
|
export class FileSendFileLedger {
|
|
72
100
|
path;
|
|
73
101
|
mem = new MemorySendFileLedger();
|
|
@@ -77,6 +105,7 @@ export class FileSendFileLedger {
|
|
|
77
105
|
ensureDir(dir);
|
|
78
106
|
this.path = join(dir, "links.jsonl");
|
|
79
107
|
for (const r of readJsonlRecords(this.path)) {
|
|
108
|
+
// hydrate defensively: a record without the identity triple can't be listed/revoked — skip, don't fabricate
|
|
80
109
|
if (!r || typeof r.id !== "string" || typeof r.scope !== "string" || typeof r.objectKey !== "string")
|
|
81
110
|
continue;
|
|
82
111
|
void this.mem.record(r);
|
|
@@ -84,21 +113,29 @@ export class FileSendFileLedger {
|
|
|
84
113
|
}
|
|
85
114
|
async record(entry) {
|
|
86
115
|
this.log ??= new AppendLog(this.path);
|
|
87
|
-
this.log.append(entry, true);
|
|
116
|
+
this.log.append(entry, true); // fsync — the governance row must survive a crash
|
|
88
117
|
await this.mem.record(entry);
|
|
89
118
|
}
|
|
90
119
|
listByScope(scope, limit, beforeId) {
|
|
91
120
|
return this.mem.listByScope(scope, limit, beforeId);
|
|
92
121
|
}
|
|
122
|
+
/** Release the append-log fd (LocalBackend.close → graceful-restart re-open). */
|
|
93
123
|
dispose() {
|
|
94
124
|
try {
|
|
95
125
|
this.log?.close();
|
|
96
126
|
}
|
|
97
127
|
catch {
|
|
128
|
+
/* best-effort */
|
|
98
129
|
}
|
|
99
130
|
this.log = undefined;
|
|
100
131
|
}
|
|
101
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Wrap a lane `send` with the ledger write point: upload+verify succeed (the inner send resolved) → record →
|
|
135
|
+
* only then return (the tool emits the file_link frame strictly after). Record failure ⇒ fail-loud for THIS
|
|
136
|
+
* file + delete of the uploaded object with ONE retry; the throw is the contract either way, and its message
|
|
137
|
+
* states the true reclaim outcome (F2: a failed reclaim = permanent orphan, warned with coordinates).
|
|
138
|
+
*/
|
|
102
139
|
export function withLedgerRecording(send, deps) {
|
|
103
140
|
return async (path, ctx) => {
|
|
104
141
|
const link = await send(path, ctx);
|
|
@@ -118,6 +155,18 @@ export function withLedgerRecording(send, deps) {
|
|
|
118
155
|
});
|
|
119
156
|
}
|
|
120
157
|
catch (e) {
|
|
158
|
+
// Governance face MUST have the row — reclaim the object (an unledgered public object is unmanageable),
|
|
159
|
+
// then fail loud for this file. F2 (codex scope-ledger audit): the DELETE gets ONE retry (S3 DELETE is
|
|
160
|
+
// idempotent, so a transient blip degrades to a second attempt), and the thrown message reports the TRUE
|
|
161
|
+
// reclaim outcome — a failed reclaim is a PERMANENT ORPHAN (record failed + object still live) and must
|
|
162
|
+
// never be described as "reclaimed"; the warns carry the coordinates for manual cleanup.
|
|
163
|
+
// 修4 (三路复审): the THROWN message is MODEL-VISIBLE (the tool splices per-file errors into its result,
|
|
164
|
+
// and capabilities already expose the public endpoint) — bucket/key/underlying cause in it would let the
|
|
165
|
+
// model reconstruct the permanent capability URL of an object the governance face can't see. The message
|
|
166
|
+
// therefore carries only a fixed error code + a short incident id; coordinates and cause go to the
|
|
167
|
+
// OPERATOR log (warn) keyed by the same incident id.
|
|
168
|
+
// Backlog (deliberately not built here): a durable reclaim queue that retries beyond this request's
|
|
169
|
+
// lifetime — today the orphan is surfaced loudly (incident-tagged warns) and cleaned up by hand.
|
|
121
170
|
const incident = (deps.newId ? deps.newId() : uuidv7()).replace(/-/g, "").slice(-12);
|
|
122
171
|
let reclaimed = true;
|
|
123
172
|
try {
|
|
@@ -125,7 +174,7 @@ export function withLedgerRecording(send, deps) {
|
|
|
125
174
|
await deps.deleteObject(link.bucket, link.key);
|
|
126
175
|
}
|
|
127
176
|
catch {
|
|
128
|
-
await deps.deleteObject(link.bucket, link.key);
|
|
177
|
+
await deps.deleteObject(link.bucket, link.key); // one retry: transient-fault degrade
|
|
129
178
|
}
|
|
130
179
|
}
|
|
131
180
|
catch (de) {
|
|
@@ -1,42 +1,119 @@
|
|
|
1
|
+
/** SigV4 physical ceiling (AWS: X-Amz-Expires max 604800s = 7 days). */
|
|
1
2
|
export declare const PRESIGN_MAX_TTL_SEC = 604800;
|
|
3
|
+
/**
|
|
4
|
+
* Multi-tenant governance (clay ruling 2026-07-14, blackboard [768]② variant a with a HASHED segment): every
|
|
5
|
+
* object key carries a per-tenant SCOPE SEGMENT so tenants can be listed/revoked by prefix on the store itself,
|
|
6
|
+
* WITHOUT leaking the principal into the (user-visible, forwardable) URL. The segment is
|
|
7
|
+
* `HMAC-SHA256(secretKey, "sendfile-scope:" + scope)` hex, truncated to 32 chars:
|
|
8
|
+
* - keyed on the S3 SECRET KEY — server-held and stable, so the mapping is deterministic per deployment but
|
|
9
|
+
* unforgeable/unenumerable from outside (a URL holder cannot test principal guesses without the key);
|
|
10
|
+
* - the "sendfile-scope:" DOMAIN SEPARATOR pins this HMAC use — the same secret signs SigV4 requests, and a
|
|
11
|
+
* cross-protocol collision between "scope segment" and any other HMAC-of-attacker-controlled-string use is
|
|
12
|
+
* exactly what domain separation exists to prevent;
|
|
13
|
+
* - 32 hex chars (128 bits) is a NAMESPACE label, not a secret: the cross-tenant BIRTHDAY bound at even a
|
|
14
|
+
* billion tenants is ~n²/2^129 ≈ 2^-69 — negligible. (The earlier 16-hex/64-bit cut had a ~2.7% birthday
|
|
15
|
+
* collision probability at that scale — n²/2^65, NOT the per-pair 2^-32 the old note claimed; codex audit
|
|
16
|
+
* F4, widened pre-release at zero cost.) Capability secrecy still lives in the uuidv7 segment. Key budget
|
|
17
|
+
* stays comfortable: worst-case private-track key = 9 ("sendfile/") + 32 + 1 + 36 + 1 + 128 = 207 chars,
|
|
18
|
+
* under both sendfile_link.object_key VARCHAR(512) and S3's 1024-byte key ceiling.
|
|
19
|
+
* scope undefined/"" (single-user deployments have no principal) → the literal "_" sentinel (same sentinel the
|
|
20
|
+
* checkpoint scope column uses for anonymous), so the key SHAPE is uniform across deployments.
|
|
21
|
+
* ⚠️ Objects issued before 1.190.0 have NO scope segment (`<uuidv7>/<name>`); they stay valid — the segment is
|
|
22
|
+
* purely additive (URLs are capability-complete either way), zero migration.
|
|
23
|
+
*/
|
|
2
24
|
export declare function scopeSegment(secretKey: string, scope: string | undefined): string;
|
|
3
25
|
export interface SendUserFileConfig {
|
|
26
|
+
/** Internal S3/MinIO endpoint the SERVER uploads through (adapter-held creds never leave the server). */
|
|
4
27
|
endpoint: string;
|
|
28
|
+
/** Public base URL users reach (files. subdomain / NodePort / CDN). Absent ⇒ issue() fail-louds with the fix. */
|
|
5
29
|
publicEndpoint?: string;
|
|
30
|
+
/** Anonymous-GET bucket for the permanent track. */
|
|
6
31
|
publicBucket: string;
|
|
32
|
+
/** Private bucket for the presigned track. */
|
|
7
33
|
privateBucket: string;
|
|
34
|
+
/** Key prefix inside the private bucket (keeps sendfile objects apart from snapshot blobs). */
|
|
8
35
|
privateKeyPrefix: string;
|
|
36
|
+
/** v2: endpoint the SANDBOX uploads through (presigned PUT Host-binding). Default = publicEndpoint —
|
|
37
|
+
* an e2b cloud sandbox can only reach the public face; an in-cluster k8s pod may prefer the internal
|
|
38
|
+
* endpoint (SEND_USER_FILE_SANDBOX_PUT_ENDPOINT). */
|
|
9
39
|
sandboxPutEndpoint?: string;
|
|
10
40
|
accessKey: string;
|
|
11
41
|
secretKey: string;
|
|
12
42
|
region?: string;
|
|
43
|
+
/** Default ttl when the tool call omits it. 0 = permanent (the settled default). */
|
|
13
44
|
defaultTtlSec: number;
|
|
14
45
|
}
|
|
15
46
|
export interface IssuedFileLink {
|
|
16
47
|
url: string;
|
|
17
48
|
filename: string;
|
|
18
49
|
size: number;
|
|
50
|
+
/** 0 = permanent (public track). */
|
|
19
51
|
ttlSec: number;
|
|
20
52
|
track: "public" | "presigned";
|
|
21
53
|
bucket: string;
|
|
22
54
|
key: string;
|
|
55
|
+
/** The ORIGINAL tenant scope this link was issued under (verbatim, for the server-side ledger — the KEY only
|
|
56
|
+
* carries the hashed segment). Absent on single-user issuance (no principal). */
|
|
23
57
|
scope?: string;
|
|
24
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Collapse an arbitrary client-supplied name to ONE safe path segment: strip directories (both
|
|
61
|
+
* separators), control/bidi characters (the session-title sanitize class), leading dots (no hidden
|
|
62
|
+
* files / no "." ".."), and cap the length (S3 key segment budget; keep the extension when truncating).
|
|
63
|
+
* Empty in ⇒ "file".
|
|
64
|
+
*/
|
|
25
65
|
export declare function sanitizeSendFileName(name: string | undefined): string;
|
|
66
|
+
/** v2 (sandbox direct-upload, clay 2026-07-14): the two-phase face. `prepare` mints the FINAL object key
|
|
67
|
+
* plus a short-lived single-object presigned PUT on a separate STAGING key (the sandbox `curl -T`s the
|
|
68
|
+
* file itself — bytes never relay through the server, creds never enter the sandbox); `finalize` mints the
|
|
69
|
+
* user-facing link for the FINAL key. The PUT URL is a capability secret scoped to one object+method+TTL —
|
|
70
|
+
* callers must keep it out of model context and redact it from errors/logs (adapter posture,
|
|
71
|
+
* remote-env-k8s redactPresigned).
|
|
72
|
+
*
|
|
73
|
+
* STAGING two-phase (修3, closes the 1.190 Plan B residual): the PUT URL rides the sandbox exec argv, so
|
|
74
|
+
* any process in the sandbox can read it via /proc and re-PUT while it is valid (120s) — previously that
|
|
75
|
+
* meant overwriting the FINAL object AFTER server-side verification, i.e. after the user got the link.
|
|
76
|
+
* Now the sandbox can only ever write the staging key (`<privateKeyPrefix>staging/<seg>/<uuidv7>` in the
|
|
77
|
+
* PRIVATE bucket — never exposed as a public URL); the server CopyObjects it to the final random key with
|
|
78
|
+
* its own creds (the sandbox never sees a write capability for that key), deletes the staging object, and
|
|
79
|
+
* verifies size on the now-immutable final object. A late re-PUT of the expired-or-not staging URL can no
|
|
80
|
+
* longer touch what the user's link points at. */
|
|
26
81
|
export interface PreparedDirectUpload {
|
|
82
|
+
/** Presigned PUT the sandbox uploads through — the STAGING key (single object, method-bound, short TTL);
|
|
83
|
+
* never the final key, which no sandbox-visible write capability ever exists for. */
|
|
27
84
|
putUrl: string;
|
|
85
|
+
/** SERVER-side post-upload accounting (codex review: the in-sandbox stat is advisory — the sandbox owns
|
|
86
|
+
* its filesystem and the presigned PUT is UNSIGNED-PAYLOAD, so nothing binds the uploaded byte count).
|
|
87
|
+
* Runs the staging→final promotion with adapter creds via the internal endpoint: HEAD staging (missing ⇒
|
|
88
|
+
* throw — claimed upload didn't land; over-cap ⇒ DELETE staging, throw), CopyObject staging→final, DELETE
|
|
89
|
+
* staging, then an authoritative HEAD of the FINAL object (whose size the card must carry — the copy is
|
|
90
|
+
* what pins the bytes). 修2: EVERY failure past the object landing reclaims best-effort (staging and/or
|
|
91
|
+
* final) before throwing — a transient HEAD 5xx must not leave an unledgered orphan. */
|
|
28
92
|
verifySize(maxBytes: number): Promise<number>;
|
|
93
|
+
/** Mint the user-facing link once the upload is verified. `size` = verifySize's reading. */
|
|
29
94
|
finalize(size: number): IssuedFileLink;
|
|
30
95
|
}
|
|
31
96
|
export interface SendUserFileIssuer {
|
|
97
|
+
/** Upload bytes and mint the user-facing URL. Throws (fail-loud, typed message) on config/物理 limits.
|
|
98
|
+
* `scope` = the caller's VERIFIED principal (multi-tenant); it keys the hashed scope segment in the object
|
|
99
|
+
* key and rides back verbatim on IssuedFileLink.scope for the ledger. Omit on single-user. */
|
|
32
100
|
issue(bytes: Uint8Array, filename: string | undefined, ttlSec?: number, scope?: string): Promise<IssuedFileLink>;
|
|
101
|
+
/** v2: mint a presigned PUT for a sandbox-side direct upload (no bytes through the server). Same `scope`
|
|
102
|
+
* semantics as issue() — prepare and finalize share ONE key, so the segment is fixed at prepare time. */
|
|
33
103
|
prepareDirectUpload(filename: string | undefined, ttlSec?: number, scope?: string): PreparedDirectUpload;
|
|
104
|
+
/** Best-effort object reclaim (ledger fail-loud path: an uploaded object whose ledger record failed would be
|
|
105
|
+
* an unmanageable orphan — delete it). Signed DELETE against the INTERNAL endpoint with adapter creds. */
|
|
34
106
|
deleteObject(bucket: string, key: string): Promise<void>;
|
|
107
|
+
/** The public endpoint web clients need for rendering context (bootstrap/capabilities透出). */
|
|
35
108
|
readonly publicEndpoint: string | undefined;
|
|
36
109
|
}
|
|
37
110
|
export declare function createSendUserFileIssuer(cfg: SendUserFileConfig, deps?: {
|
|
111
|
+
/** Injectable upload (tests). Default = SigV4 presigned PUT against the INTERNAL endpoint + fetch. */
|
|
38
112
|
upload?: (bucket: string, key: string, bytes: Uint8Array) => Promise<void>;
|
|
113
|
+
/** Injectable post-direct-upload accounting (tests). Default = HEAD (+ DELETE when over cap) against
|
|
114
|
+
* the INTERNAL endpoint with adapter creds. Returns the object's real size. */
|
|
39
115
|
verify?: (bucket: string, key: string, maxBytes: number) => Promise<number>;
|
|
116
|
+
/** Injectable object delete (tests). Default = signed DELETE against the INTERNAL endpoint. */
|
|
40
117
|
remove?: (bucket: string, key: string) => Promise<void>;
|
|
41
118
|
now?: () => Date;
|
|
42
119
|
}): SendUserFileIssuer;
|