@sema-agent/server 7.138.0 → 7.140.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 +457 -7
- package/README.md +7 -4
- package/README.zh-CN.md +6 -4
- package/USAGE.md +91 -41
- package/deploy/sema-up/README.md +1 -1
- package/deploy/sema-up/lib/lanes.json +3 -2
- package/dist/adoption/runner.js +1 -1
- package/dist/adoption/sql.js +1 -1
- package/dist/adoption/wire.d.ts +3 -3
- package/dist/approval-card.d.ts +26 -26
- package/dist/bench/s1/arms.d.ts +1 -1
- package/dist/bench/s1/arms.js +1 -3
- package/dist/bench/s1/live-deps.js +3 -2
- package/dist/bench/s1/row.d.ts +5 -2
- package/dist/bench/s1/row.js +2 -22
- package/dist/bench/s1/run-firm.js +2 -2
- package/dist/boot/adoption.js +1 -1
- package/dist/boot/device-lane.d.ts +8 -3
- package/dist/boot/device-lane.js +7 -2
- package/dist/boot/execution-env.d.ts +4 -2
- package/dist/boot/execution-env.js +28 -34
- package/dist/boot/execution-lane.d.ts +9 -1
- package/dist/boot/execution-lane.js +6 -1
- package/dist/boot/governance-seams.d.ts +3 -2
- package/dist/boot/governance-seams.js +9 -11
- package/dist/boot/memory-boundary.d.ts +14 -51
- package/dist/boot/memory-boundary.js +10 -20
- package/dist/boot/memory-consolidation.d.ts +15 -11
- package/dist/boot/memory-consolidation.js +25 -14
- package/dist/boot/resolve-spec.d.ts +4 -6
- package/dist/boot/resolve-spec.js +10 -13
- package/dist/boot/retention-lane.d.ts +5 -5
- package/dist/boot/retention-lane.js +0 -6
- package/dist/boot/runner-deps.d.ts +6 -4
- package/dist/boot/runner-deps.js +3 -1
- package/dist/boot/session-faces.d.ts +0 -3
- package/dist/boot/session-faces.js +15 -8
- package/dist/boot/stage-02-web-admin-pull.js +2 -2
- package/dist/boot/stage-03-store-backend.d.ts +2 -6
- package/dist/boot/stage-03-store-backend.js +2 -3
- package/dist/boot/stage-04-stores.d.ts +2 -6
- package/dist/boot/stage-04-stores.js +5 -5
- package/dist/boot/stage-05-execution-env.d.ts +2 -6
- package/dist/boot/stage-05-execution-env.js +2 -2
- package/dist/boot/stage-06-runners.d.ts +2 -6
- package/dist/boot/stage-06-runners.js +2 -3
- package/dist/boot/stage-07-capability-layer.d.ts +2 -6
- package/dist/boot/stage-08-reapers.d.ts +2 -6
- package/dist/boot/stage-09-leader.d.ts +2 -6
- package/dist/boot/stage-09-leader.js +1 -2
- package/dist/boot/stage-10-http-server.d.ts +2 -6
- package/dist/boot/stage-10-http-server.js +7 -6
- package/dist/boot/stores.d.ts +3 -6
- package/dist/boot/stores.js +27 -40
- package/dist/boot/task-list-lane.d.ts +1 -1
- package/dist/boot/task-list-lane.js +1 -1
- package/dist/boot/web-admin.js +37 -11
- package/dist/capabilities/execution-lane.d.ts +2 -2
- package/dist/capabilities/mcp-probe.js +1 -1
- package/dist/capabilities/scenarios.d.ts +1 -1
- package/dist/capability-facts.d.ts +15 -7
- package/dist/capability-facts.js +8 -3
- package/dist/config-catalog.js +9 -8
- package/dist/config-invariants.d.ts +23 -3
- package/dist/config-invariants.js +42 -0
- package/dist/config-provider.d.ts +33 -37
- package/dist/config-provider.js +51 -30
- package/dist/config-types.d.ts +21 -7
- package/dist/config.d.ts +33 -0
- package/dist/config.js +46 -16
- package/dist/delegated-session-owner.d.ts +4 -3
- package/dist/delegated-session-owner.js +1 -1
- package/dist/deployment-shape.d.ts +10 -9
- package/dist/deployment-shape.js +4 -4
- package/dist/device-enrollment.d.ts +41 -2
- package/dist/device-enrollment.js +27 -12
- package/dist/device-store.d.ts +58 -85
- package/dist/device-store.js +19 -49
- package/dist/device-ws-hub.js +2 -1
- package/dist/env-name-allowlist-knobs.d.ts +5 -4
- package/dist/exec-cut.d.ts +60 -0
- package/dist/exec-cut.js +36 -0
- package/dist/execution-lane-caps.d.ts +115 -105
- package/dist/execution-lane-caps.js +76 -82
- package/dist/execution-placement.d.ts +259 -0
- package/dist/execution-placement.js +199 -0
- package/dist/field-conflict.d.ts +3 -2
- package/dist/field-conflict.js +1 -0
- package/dist/hosted-posture.d.ts +2 -2
- package/dist/http/admission.js +8 -19
- package/dist/http/checkpoint-ctx.d.ts +21 -12
- package/dist/http/checkpoint-ctx.js +4 -2
- package/dist/http/claimed-run.d.ts +1 -1
- package/dist/http/durable-run-leg.js +9 -5
- package/dist/http/execution-context.d.ts +218 -0
- package/dist/http/execution-context.js +330 -0
- package/dist/http/memory-compliance-failure-reply.d.ts +3 -1
- package/dist/http/memory-compliance-failure-reply.js +5 -0
- package/dist/http/memory-layer-reply.d.ts +30 -0
- package/dist/http/memory-layer-reply.js +24 -0
- package/dist/http/resume-legs.js +63 -36
- package/dist/http/retired-service-deps.d.ts +1 -1
- package/dist/http/retired-service-deps.js +1 -1
- package/dist/http/route-ctx.d.ts +14 -8
- package/dist/http/routes/adoption.js +1 -1
- package/dist/http/routes/background.d.ts +29 -1
- package/dist/http/routes/background.js +29 -2
- package/dist/http/routes/devices.d.ts +13 -19
- package/dist/http/routes/devices.js +21 -26
- package/dist/http/routes/memory-bundle.js +3 -0
- package/dist/http/routes/memory-compliance.js +8 -1
- package/dist/http/routes/memory-consolidation.js +12 -1
- package/dist/http/routes/memory-origin.js +14 -2
- package/dist/http/routes/memory-policy.js +5 -0
- package/dist/http/routes/session-sync.js +110 -15
- package/dist/http/routes/sessions.d.ts +6 -0
- package/dist/http/routes/sessions.js +143 -22
- package/dist/http/routes/side-query.d.ts +12 -4
- package/dist/http/routes/side-query.js +4 -5
- package/dist/http/routes/tasks.js +41 -33
- package/dist/http/server.d.ts +40 -44
- package/dist/http/server.js +13 -2
- package/dist/http/session-inherit-env.d.ts +3 -4
- package/dist/http/session-inherit-env.js +1 -1
- package/dist/http/wire-types.d.ts +8 -12
- package/dist/identity-source.d.ts +1 -1
- package/dist/identity-source.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/lane-home-probe.d.ts +68 -42
- package/dist/lane-home-probe.js +53 -30
- package/dist/leader/wire.js +5 -4
- package/dist/memory-bundle-engine.d.ts +16 -9
- package/dist/memory-bundle-engine.js +29 -6
- package/dist/memory-operator-faces.d.ts +85 -30
- package/dist/memory-operator-faces.js +136 -30
- package/dist/memory-project-layer.d.ts +3 -21
- package/dist/memory-project-layer.js +11 -8
- package/dist/memory-scope-stores.d.ts +73 -0
- package/dist/memory-scope-stores.js +86 -0
- package/dist/memory-scope.d.ts +29 -5
- package/dist/memory-scope.js +16 -4
- package/dist/memory-sync-client.d.ts +70 -18
- package/dist/memory-sync-client.js +215 -117
- package/dist/memory-sync.d.ts +1 -1
- package/dist/memory-sync.js +3 -2
- package/dist/observability/cost-taxonomy.d.ts +2 -2
- package/dist/observability/fail-open.d.ts +12 -0
- package/dist/observability/fail-open.js +12 -0
- package/dist/observability/run-terminal.js +0 -1
- package/dist/orchestration/workflow-notify-journal.js +4 -4
- package/dist/org-memory-admission.d.ts +4 -3
- package/dist/org-memory-admission.js +6 -6
- package/dist/parked-decide.d.ts +34 -9
- package/dist/parked-decide.js +12 -19
- package/dist/parked-revive-surface.d.ts +12 -15
- package/dist/parked-revive-surface.js +3 -6
- package/dist/peer-seat.d.ts +13 -7
- package/dist/peer-seat.js +37 -3
- package/dist/plugins/adoption-log-sql.js +4 -4
- package/dist/plugins/approval-ask-store-file.d.ts +7 -0
- package/dist/plugins/approval-ask-store-file.js +11 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +6 -0
- package/dist/plugins/approval-ask-store-memory.js +12 -0
- package/dist/plugins/approval-ask-store-sql.d.ts +22 -5
- package/dist/plugins/approval-ask-store-sql.js +44 -26
- package/dist/plugins/approval-nonce-store.js +4 -4
- package/dist/plugins/blob-backend.d.ts +4 -4
- package/dist/plugins/blob-backend.js +7 -7
- package/dist/plugins/breaker-state-sql.js +2 -2
- package/dist/plugins/caching-session-store.d.ts +6 -2
- package/dist/plugins/caching-session-store.js +9 -3
- package/dist/plugins/checkpoint-index-columns.js +2 -2
- package/dist/plugins/checkpoint-store-sql.d.ts +6 -5
- package/dist/plugins/checkpoint-store-sql.js +21 -23
- package/dist/plugins/device-store-sql.d.ts +25 -51
- package/dist/plugins/device-store-sql.js +68 -122
- package/dist/plugins/ensure-index.d.ts +1 -2
- package/dist/plugins/execution-placement-sql.d.ts +151 -0
- package/dist/plugins/execution-placement-sql.js +223 -0
- package/dist/plugins/file-history-store-sql.d.ts +9 -8
- package/dist/plugins/file-history-store-sql.js +9 -9
- package/dist/plugins/file-run-store.d.ts +6 -1
- package/dist/plugins/file-run-store.js +4 -0
- package/dist/plugins/fork-routing-session-store.d.ts +6 -0
- package/dist/plugins/fork-routing-session-store.js +16 -0
- package/dist/plugins/image-bake-store-sql.js +9 -9
- package/dist/plugins/image-index-sql.js +11 -11
- package/dist/plugins/leader-run-store-sql.js +4 -4
- package/dist/plugins/local-session-store.d.ts +149 -50
- package/dist/plugins/local-session-store.js +382 -107
- package/dist/plugins/mailbox-store-sql.d.ts +2 -1
- package/dist/plugins/mailbox-store-sql.js +4 -4
- package/dist/plugins/memory-engine-tidb.js +5 -5
- package/dist/plugins/memory-key-guards.d.ts +4 -0
- package/dist/plugins/memory-key-guards.js +1 -0
- package/dist/plugins/memory-optout-grant-store-sql.js +1 -1
- package/dist/plugins/memory-run-store.d.ts +1 -1
- package/dist/plugins/memory-sync-store-tidb.js +3 -3
- package/dist/plugins/one-time-migrations.d.ts +117 -8
- package/dist/plugins/one-time-migrations.js +408 -38
- package/dist/plugins/org-delivery-quota-store.js +2 -2
- package/dist/plugins/outcome-ledger-sql.d.ts +2 -2
- package/dist/plugins/outcome-ledger-sql.js +2 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +17 -19
- package/dist/plugins/permission-rule-store-sql.js +29 -32
- package/dist/plugins/pg-pool.d.ts +7 -3
- package/dist/plugins/pg-session-storage.d.ts +31 -20
- package/dist/plugins/pg-session-storage.js +120 -52
- package/dist/plugins/remote-env-adb.d.ts +18 -19
- package/dist/plugins/remote-env-adb.js +91 -66
- package/dist/plugins/remote-env-device.d.ts +23 -31
- package/dist/plugins/remote-env-device.js +19 -17
- package/dist/plugins/remote-env-e2b.d.ts +27 -21
- package/dist/plugins/remote-env-e2b.js +91 -45
- package/dist/plugins/remote-env-file-error.d.ts +3 -1
- package/dist/plugins/remote-env-file-error.js +9 -3
- package/dist/plugins/remote-env-host.d.ts +31 -34
- package/dist/plugins/remote-env-host.js +91 -72
- package/dist/plugins/remote-env-k8s.d.ts +13 -29
- package/dist/plugins/remote-env-k8s.js +63 -55
- package/dist/plugins/remote-env-local-docker.d.ts +24 -12
- package/dist/plugins/remote-env-local-docker.js +49 -61
- package/dist/plugins/remote-env-ssh.d.ts +11 -19
- package/dist/plugins/remote-env-ssh.js +74 -57
- package/dist/plugins/remote-shell.d.ts +100 -3
- package/dist/plugins/remote-shell.js +166 -2
- package/dist/plugins/resume-anchor-store-sql.js +2 -2
- package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
- package/dist/plugins/retention-lane-store-sql.js +2 -2
- package/dist/plugins/retention-store-sql.d.ts +10 -7
- package/dist/plugins/retention-store-sql.js +13 -7
- package/dist/plugins/run-store-sql.d.ts +13 -3
- package/dist/plugins/run-store-sql.js +20 -15
- package/dist/plugins/schema-consistency.d.ts +21 -11
- package/dist/plugins/schema-consistency.js +15 -9
- package/dist/plugins/schema-drift-sentence.d.ts +27 -0
- package/dist/plugins/schema-drift-sentence.js +38 -0
- package/dist/plugins/schema-ensure-legs.d.ts +2 -3
- package/dist/plugins/schema-ensure-legs.js +2 -2
- package/dist/plugins/schema-live-columns.d.ts +1 -1
- package/dist/plugins/session-capture-record-store-sql.js +1 -1
- package/dist/plugins/session-fork.d.ts +54 -0
- package/dist/plugins/session-fork.js +38 -1
- package/dist/plugins/session-row-sql.d.ts +22 -0
- package/dist/plugins/session-row-sql.js +81 -0
- package/dist/plugins/session-rules-column.d.ts +1 -1
- package/dist/plugins/session-rules-column.js +1 -1
- package/dist/plugins/session-store.d.ts +1 -1
- package/dist/plugins/session-workspace-cell.d.ts +1 -1
- package/dist/plugins/session-workspace-cell.js +1 -1
- package/dist/plugins/shared-memory-store-sql.js +2 -2
- package/dist/plugins/sql-driver.d.ts +10 -5
- package/dist/plugins/sql-driver.js +6 -6
- package/dist/plugins/sql-errors.js +1 -1
- package/dist/plugins/store-backend.d.ts +5 -7
- package/dist/plugins/store-backend.js +23 -11
- package/dist/plugins/store-contracts.d.ts +25 -5
- package/dist/plugins/task-list-store-sql.js +11 -11
- package/dist/plugins/tidb-pool.d.ts +12 -7
- package/dist/plugins/tidb-pool.js +13 -7
- package/dist/plugins/tidb-session-storage.js +4 -4
- package/dist/plugins/tidb-session-store.d.ts +57 -26
- package/dist/plugins/tidb-session-store.js +127 -59
- package/dist/plugins/tool-result-store-sql.d.ts +5 -4
- package/dist/plugins/tool-result-store-sql.js +21 -13
- package/dist/plugins/user-input-ledger-sql.js +2 -2
- package/dist/plugins/workflow-journal-store-sql.js +5 -5
- package/dist/plugins/workflow-run-store-sql.js +19 -19
- package/dist/plugins/write-behind-counter.d.ts +2 -3
- package/dist/plugins/write-behind-counter.js +5 -5
- package/dist/project-memory.d.ts +9 -15
- package/dist/project-memory.js +5 -4
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +6 -7
- package/dist/request-value-closure.js +1 -3
- package/dist/resource-suspend.d.ts +14 -12
- package/dist/resource-suspend.js +1 -1
- package/dist/resource-window.d.ts +4 -3
- package/dist/run-local.d.ts +6 -0
- package/dist/run-local.js +34 -35
- package/dist/runs.d.ts +10 -5
- package/dist/runs.js +52 -66
- package/dist/security.d.ts +38 -12
- package/dist/security.js +8 -2
- package/dist/server-secret-env.d.ts +9 -5
- package/dist/session-children-retire.d.ts +27 -9
- package/dist/session-children-retire.js +9 -5
- package/dist/session-incarnation.d.ts +20 -10
- package/dist/session-incarnation.js +5 -3
- package/dist/session-policy-wire.d.ts +1 -1
- package/dist/session-row.d.ts +114 -5
- package/dist/session-row.js +55 -5
- package/dist/session-titler.d.ts +2 -2
- package/dist/sql-engine-posture.d.ts +1 -1
- package/dist/sql-engine-posture.js +1 -1
- package/dist/{plugins → stores-sql}/background-agent-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/background-agent-store-sql.js +8 -8
- package/dist/{plugins → stores-sql}/session-policy-store-sql.d.ts +7 -5
- package/dist/{plugins → stores-sql}/session-policy-store-sql.js +12 -12
- package/dist/{plugins → stores-sql}/usage-window-store-sql.d.ts +1 -1
- package/dist/{plugins → stores-sql}/usage-window-store-sql.js +3 -3
- package/dist/task-a2a.d.ts +1 -1
- package/dist/task-a2a.js +5 -6
- package/dist/task-cwd.d.ts +6 -1
- package/dist/task-mcp.d.ts +22 -9
- package/dist/task-mcp.js +17 -9
- package/dist/terminal.d.ts +27 -0
- package/dist/terminal.js +6 -0
- package/dist/tool-approval.d.ts +6 -0
- package/dist/tool-approval.js +8 -1
- package/dist/trace/project.d.ts +1 -0
- package/dist/trace/project.js +1 -0
- package/dist/trace/redact.d.ts +3 -1
- package/dist/trace/redact.js +80 -28
- package/dist/trace/self-minted-wire.d.ts +169 -2
- package/dist/trace/self-minted-wire.js +54 -1
- package/dist/url-refusal.d.ts +1 -1
- package/dist/web-admin-client/apply-effective.d.ts +17 -3
- package/dist/web-admin-client/apply-effective.js +20 -10
- package/dist/web-admin-client/candidate-gate.d.ts +11 -7
- package/dist/web-admin-client/candidate-gate.js +1 -1
- package/dist/web-admin-client/http-client.d.ts +5 -4
- package/dist/web-admin-client/http-client.js +2 -2
- package/dist/web-admin-client/read-warnings.d.ts +7 -17
- package/dist/web-admin-client/read-warnings.js +5 -9
- package/dist/web-admin-client/skills-mcp.js +3 -2
- package/dist/web-admin-client/types.d.ts +6 -0
- package/package.json +3 -3
- package/wire-changes/server@7.139.0.json +348 -0
- package/wire-changes/server@7.140.0.json +184 -0
- package/dist/http/device-placement.d.ts +0 -175
- package/dist/http/device-placement.js +0 -145
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { emitLeafAdvance } from "../session-leaf-bus.js";
|
|
2
2
|
import { BaseSessionStorage, StoredSession, SessionError, uuidv7, validateEntriesForImport, leafIdAfterEntry, admitSessionPlacement, } from "@sema-agent/core";
|
|
3
|
-
import { SESSION_TITLE_MAX_CHARS } from "../session-row.js";
|
|
3
|
+
import { SESSION_TITLE_MAX_CHARS, sessionRowTagKey } from "../session-row.js";
|
|
4
|
+
import { writeSessionRowCellsSql } from "./session-row-sql.js";
|
|
4
5
|
import { escapeLike } from "./sql-escape.js";
|
|
5
6
|
import { decodeSessionEventPayload } from "./session-event-payload.js";
|
|
6
7
|
import { scanEpochAnchor } from "./session-epoch-anchor.js";
|
|
@@ -16,11 +17,15 @@ import { isPgUniqueViolation } from "./sql-errors.js";
|
|
|
16
17
|
import { BASELINE_IO_DEADLINE_MS, decodeInstructionSource, encodeInstructionSource } from "../instruction-source-notice.js";
|
|
17
18
|
import { SESSION_META_WORKSPACE_COLUMN, decodeSessionWorkspaceCell, encodeSessionWorkspaceCell } from "./session-workspace-cell.js";
|
|
18
19
|
import { MANAGED_RETENTION, UNMANAGED_RETENTION } from "./retention-store-sql.js";
|
|
19
|
-
import { SESSION_META_INCARNATION_COLUMN,
|
|
20
|
+
import { SESSION_META_INCARNATION_COLUMN, carriedRowCells, headFromRow, incarnationFromCell, mintSessionIncarnation, sessionFaceFromRow } from "../session-incarnation.js";
|
|
20
21
|
import { ensureIndexes } from "./ensure-index.js";
|
|
21
22
|
import { assertFirstOwnerWritable, forkOwnerOf, isSessionOwnerValue } from "./session-ownership.js";
|
|
22
23
|
import { selectForkRows } from "@sema-agent/core";
|
|
23
|
-
import { FORK_LOG_ROW_SHAPE, forkPointOf } from "./session-fork.js";
|
|
24
|
+
import { FORK_LOG_ROW_SHAPE, ForkTargetUnsettledError, classifyForkTarget, forkByFreshId, forkPointOf } from "./session-fork.js";
|
|
25
|
+
import { pgDriver } from "./sql-driver.js";
|
|
26
|
+
import { MIRROR_ON_COMMIT_GUARD, MIRROR_ON_COMMIT_SET, SESSION_META_PLACEMENT_READ_COLUMNS, createSqlExecutionPlacementSeat, importedRowCells, lockRootAndReadClaim, placementCellFromRow, readPlacementRowStatement, sessionMetaPlacementColumnsDdl } from "./execution-placement-sql.js";
|
|
27
|
+
import { SessionActiveRunError, SessionWriterPresentError } from "../execution-placement.js";
|
|
28
|
+
const rowsOnClient = (conn) => async (sql, values) => (await conn.query(sql, [...values])).rows;
|
|
24
29
|
const isDupKey = isPgUniqueViolation;
|
|
25
30
|
function baselineQuery(text, values) {
|
|
26
31
|
return { text, values, query_timeout: BASELINE_IO_DEADLINE_MS };
|
|
@@ -34,7 +39,7 @@ export const PG_SESSION_SCHEMA = [
|
|
|
34
39
|
leaf_id VARCHAR(64) COLLATE "C",
|
|
35
40
|
leaf_seq BIGINT NOT NULL DEFAULT 0,
|
|
36
41
|
-- title: one column, two writers (TiDB twin, same name / width; law in src/session-row.ts): the user's write
|
|
37
|
-
-- (
|
|
42
|
+
-- (writeSessionRowCells, unconditional unless the PATCH carries expectedRowTag; null = cleared back to automatic) and the auto-titler (setTitleIfNull / probeTitle
|
|
38
43
|
-- — fills NULL only; NULL = "untitled", the three-state probe distinguishes it from "no such session").
|
|
39
44
|
title VARCHAR(${SESSION_TITLE_MAX_CHARS}) COLLATE "C",
|
|
40
45
|
-- pinned: the user's pin (TiDB twin); every list row carries it, false by default.
|
|
@@ -56,6 +61,8 @@ export const PG_SESSION_SCHEMA = [
|
|
|
56
61
|
placed_at TIMESTAMPTZ(3),
|
|
57
62
|
-- S-790 / S-506:会话化身(TiDB 孪生同名同义;列定义唯一属主 = src/session-incarnation.ts 的 SESSION_META_INCARNATION_COLUMN)。
|
|
58
63
|
${SESSION_META_INCARNATION_COLUMN.pg},
|
|
64
|
+
-- 执行放置(根会话行上这一位住客的一格:execution_* 七列)+ fork 键(fork_key)—— TiDB 孪生同名同义;列定义与语句的唯一属主 = src/plugins/execution-placement-sql.ts。
|
|
65
|
+
${sessionMetaPlacementColumnsDdl("pg")},
|
|
59
66
|
PRIMARY KEY (session_id)
|
|
60
67
|
)`,
|
|
61
68
|
`CREATE TABLE IF NOT EXISTS session_event (
|
|
@@ -184,10 +191,14 @@ export class PgSessionStore {
|
|
|
184
191
|
placements = SQL_SESSION_PLACEMENTS;
|
|
185
192
|
pending = new Map();
|
|
186
193
|
log;
|
|
194
|
+
executionPlacement;
|
|
195
|
+
db;
|
|
187
196
|
constructor(pool, opts = {}) {
|
|
188
197
|
this.pool = pool;
|
|
189
198
|
this.log = opts.log ?? createLogger();
|
|
190
199
|
this.retention = opts.retention ?? UNMANAGED_RETENTION;
|
|
200
|
+
this.db = pgDriver(pool);
|
|
201
|
+
this.executionPlacement = createSqlExecutionPlacementSeat(this.db);
|
|
191
202
|
}
|
|
192
203
|
async acquire(sessionId, opts) {
|
|
193
204
|
if (!sessionId) {
|
|
@@ -341,38 +352,25 @@ export class PgSessionStore {
|
|
|
341
352
|
const sid = ph(opts.cursor.sessionId);
|
|
342
353
|
where.push(`(sm.updated_at < ${a} OR (sm.updated_at = ${b} AND sm.session_id < ${sid}))`);
|
|
343
354
|
}
|
|
344
|
-
return this.
|
|
355
|
+
return (await this.selectListRows({ where, params, limit: opts.limit })).map((a) => a.row);
|
|
345
356
|
}
|
|
346
357
|
async sessionSummaryOf(sessionId) {
|
|
347
|
-
|
|
348
|
-
return rows[0];
|
|
358
|
+
return (await this.listRowOf(sessionId))?.row;
|
|
349
359
|
}
|
|
350
|
-
async
|
|
351
|
-
|
|
352
|
-
const params = [];
|
|
353
|
-
if (patch.title !== undefined) {
|
|
354
|
-
params.push(patch.title);
|
|
355
|
-
sets.push(`title = $${params.length}`);
|
|
356
|
-
}
|
|
357
|
-
if (patch.pinned !== undefined) {
|
|
358
|
-
params.push(patch.pinned);
|
|
359
|
-
sets.push(`pinned = $${params.length}`);
|
|
360
|
-
}
|
|
361
|
-
if (sets.length > 0) {
|
|
362
|
-
params.push(sessionId, face.incarnation);
|
|
363
|
-
await this.pool.query(`UPDATE session_meta SET ${sets.join(", ")} WHERE session_id = $${params.length - 1} AND incarnation = $${params.length} AND placement_kind IS NULL`, params);
|
|
364
|
-
}
|
|
365
|
-
const rows = await this.selectSummaries({ where: ["sm.placement_kind IS NULL", "sm.session_id = $1", "sm.incarnation = $2"], params: [sessionId, face.incarnation], limit: 1, runSessionId: sessionId });
|
|
366
|
-
return rows[0];
|
|
360
|
+
async listRowOf(sessionId) {
|
|
361
|
+
return (await this.selectListRows({ where: ["sm.placement_kind IS NULL", "sm.session_id = $1"], params: [sessionId], limit: 1, runSessionId: sessionId }))[0];
|
|
367
362
|
}
|
|
368
|
-
async
|
|
363
|
+
async writeSessionRowCells(sessionId, cells, how) {
|
|
364
|
+
return writeSessionRowCellsSql(this.db, sessionId, cells, how, (id) => this.listRowOf(id));
|
|
365
|
+
}
|
|
366
|
+
async selectListRows(q) {
|
|
369
367
|
const params = [...q.params];
|
|
370
368
|
const ph = (v) => {
|
|
371
369
|
params.push(v);
|
|
372
370
|
return `$${params.length}`;
|
|
373
371
|
};
|
|
374
372
|
const runWhere = q.runSessionId !== undefined ? ` WHERE session_id = ${ph(q.runSessionId)}` : "";
|
|
375
|
-
const sql = "SELECT sm.session_id, sm.owner, sm.updated_at AS last_activity, sm.created_at AS first_activity, sm.title, sm.pinned, " +
|
|
373
|
+
const sql = "SELECT sm.session_id, sm.owner, sm.incarnation, sm.updated_at AS last_activity, sm.created_at AS first_activity, sm.title, sm.pinned, " +
|
|
376
374
|
" COALESCE(r.run_count, 0) AS run_count, latest.objective_preview, latest.status, latest.task_id AS last_run_id, latest.last_task_run_id " +
|
|
377
375
|
"FROM session_meta sm " +
|
|
378
376
|
"LEFT JOIN (SELECT session_id, COUNT(*) AS run_count FROM task_run" + runWhere + " GROUP BY session_id) r ON r.session_id = sm.session_id " +
|
|
@@ -383,9 +381,14 @@ export class PgSessionStore {
|
|
|
383
381
|
const res = await this.pool.query(sql, params);
|
|
384
382
|
return res.rows.map((r) => {
|
|
385
383
|
const runId = r.last_task_run_id;
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
384
|
+
const sessionId = String(r.session_id);
|
|
385
|
+
const owner = r.owner ?? null;
|
|
386
|
+
const incarnation = incarnationFromCell(sessionId, r.incarnation, "absent");
|
|
387
|
+
const title = r.title ?? null;
|
|
388
|
+
const pinned = r.pinned === true;
|
|
389
|
+
const row = {
|
|
390
|
+
sessionId,
|
|
391
|
+
owner,
|
|
389
392
|
lastActivityAt: r.last_activity instanceof Date ? r.last_activity.toISOString() : String(r.last_activity),
|
|
390
393
|
firstActivityAt: r.first_activity instanceof Date ? r.first_activity.toISOString() : String(r.first_activity),
|
|
391
394
|
runCount: Number(r.run_count),
|
|
@@ -393,9 +396,11 @@ export class PgSessionStore {
|
|
|
393
396
|
lastStatus: r.status == null ? "" : String(r.status),
|
|
394
397
|
lastRunId: r.last_run_id ?? null,
|
|
395
398
|
...(typeof runId === "string" && runId !== "" ? { lastTaskRunId: runId } : {}),
|
|
396
|
-
title
|
|
397
|
-
pinned
|
|
399
|
+
title,
|
|
400
|
+
pinned,
|
|
401
|
+
...sessionRowTagKey({ sessionId, owner, incarnation, cells: { title, pinned } }),
|
|
398
402
|
};
|
|
403
|
+
return { row, occupant: { owner, incarnation } };
|
|
399
404
|
});
|
|
400
405
|
}
|
|
401
406
|
async probeTitle(sessionId) {
|
|
@@ -431,6 +436,17 @@ export class PgSessionStore {
|
|
|
431
436
|
await this.pool.query("UPDATE session_meta SET workspace = $1::jsonb WHERE session_id = $2 AND incarnation = $3", [encodeSessionWorkspaceCell(workspace, pgSafeJsonStringify, sessionId), sessionId, incarnation]);
|
|
432
437
|
}
|
|
433
438
|
async fork(sourceId, owner) {
|
|
439
|
+
return forkByFreshId((s, o, t) => this.forkTo(s, o, t), sourceId, owner);
|
|
440
|
+
}
|
|
441
|
+
async forkTo(sourceId, owner, target) {
|
|
442
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
443
|
+
const out = await this.forkToOnce(sourceId, owner, target);
|
|
444
|
+
if (out !== "unsettled")
|
|
445
|
+
return out;
|
|
446
|
+
}
|
|
447
|
+
throw new ForkTargetUnsettledError(target.id);
|
|
448
|
+
}
|
|
449
|
+
async forkToOnce(sourceId, owner, target) {
|
|
434
450
|
const metaRes = await this.pool.query("SELECT leaf_id, owner FROM session_meta WHERE session_id = $1", [sourceId]);
|
|
435
451
|
if (!metaRes.rows[0])
|
|
436
452
|
return null;
|
|
@@ -442,19 +458,29 @@ export class PgSessionStore {
|
|
|
442
458
|
const point = await forkPointOf(storage);
|
|
443
459
|
const eventRes = await this.pool.query(`SELECT entry_id, parent_id, type, ${jsonColumnText("pg", "payload")}, ts FROM session_event WHERE session_id = $1 ORDER BY seq ASC`, [sourceId]);
|
|
444
460
|
const { rows, leafId: forkLeafId } = selectForkRows(eventRes.rows, leafId, point, FORK_LOG_ROW_SHAPE);
|
|
445
|
-
const newId = uuidv7();
|
|
446
461
|
const now = new Date();
|
|
447
462
|
const conn = await this.pool.connect();
|
|
463
|
+
let collided = false;
|
|
448
464
|
try {
|
|
449
465
|
await conn.query("BEGIN");
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
const payload = String(r.payload);
|
|
453
|
-
await conn.query("INSERT INTO session_event (session_id, seq, entry_id, parent_id, type, payload, ts) VALUES ($1,$2,$3,$4,$5,$6::jsonb,$7)", [newId, seq, r.entry_id, r.parent_id ?? null, r.type, payload, r.ts]);
|
|
466
|
+
try {
|
|
467
|
+
await conn.query("INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation, fork_key) VALUES ($1,$2,$3,$4,$5,$6,$7,$8)", [target.id, forkOwner, now, now, forkLeafId, rows.length, mintSessionIncarnation(), target.key ?? null]);
|
|
454
468
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
469
|
+
catch (err) {
|
|
470
|
+
if (!isDupKey(err))
|
|
471
|
+
throw err;
|
|
472
|
+
collided = true;
|
|
473
|
+
}
|
|
474
|
+
if (!collided) {
|
|
475
|
+
for (let seq = 0; seq < rows.length; seq++) {
|
|
476
|
+
const r = rows[seq];
|
|
477
|
+
const payload = String(r.payload);
|
|
478
|
+
await conn.query("INSERT INTO session_event (session_id, seq, entry_id, parent_id, type, payload, ts) VALUES ($1,$2,$3,$4,$5,$6::jsonb,$7)", [target.id, seq, r.entry_id, r.parent_id ?? null, r.type, payload, r.ts]);
|
|
479
|
+
}
|
|
480
|
+
await conn.query("COMMIT");
|
|
481
|
+
return { outcome: "created", id: target.id };
|
|
482
|
+
}
|
|
483
|
+
await conn.query("ROLLBACK");
|
|
458
484
|
}
|
|
459
485
|
catch (err) {
|
|
460
486
|
try {
|
|
@@ -467,6 +493,9 @@ export class PgSessionStore {
|
|
|
467
493
|
finally {
|
|
468
494
|
conn.release();
|
|
469
495
|
}
|
|
496
|
+
const existing = await this.pool.query("SELECT owner, fork_key FROM session_meta WHERE session_id = $1", [target.id]);
|
|
497
|
+
const row = existing.rows[0];
|
|
498
|
+
return row === undefined ? "unsettled" : classifyForkTarget(target, { owner: row.owner ?? null, forkKey: row.fork_key ?? null }, forkOwner);
|
|
470
499
|
}
|
|
471
500
|
async exportEntries(sessionId) {
|
|
472
501
|
const metaRes = await this.pool.query("SELECT 1 FROM session_meta WHERE session_id = $1", [sessionId]);
|
|
@@ -506,7 +535,7 @@ export class PgSessionStore {
|
|
|
506
535
|
const conn = await this.pool.connect();
|
|
507
536
|
try {
|
|
508
537
|
await conn.query("BEGIN");
|
|
509
|
-
await this.
|
|
538
|
+
await this.writeImportedLog(conn, sessionId, owner, validated, { incarnation: mintSessionIncarnation(), forkKey: null }, "create");
|
|
510
539
|
await conn.query("COMMIT");
|
|
511
540
|
}
|
|
512
541
|
catch (err) {
|
|
@@ -515,7 +544,7 @@ export class PgSessionStore {
|
|
|
515
544
|
}
|
|
516
545
|
catch {
|
|
517
546
|
}
|
|
518
|
-
if (err instanceof SessionError)
|
|
547
|
+
if (err instanceof SessionError || err instanceof SessionActiveRunError)
|
|
519
548
|
throw err;
|
|
520
549
|
throw new SessionError("storage", `import of session ${sessionId} failed`, err instanceof Error ? err : undefined);
|
|
521
550
|
}
|
|
@@ -529,14 +558,21 @@ export class PgSessionStore {
|
|
|
529
558
|
const conn = await this.pool.connect();
|
|
530
559
|
try {
|
|
531
560
|
await conn.query("BEGIN");
|
|
532
|
-
const placedRes = await conn.query(
|
|
533
|
-
|
|
561
|
+
const placedRes = await conn.query(`SELECT ${SESSION_META_PLACEMENT_READ_COLUMNS}, fork_key FROM session_meta WHERE session_id = $1 FOR UPDATE`, [sessionId]);
|
|
562
|
+
const prior = placedRes.rows[0];
|
|
563
|
+
if (prior?.placement_kind != null) {
|
|
534
564
|
await conn.query("ROLLBACK");
|
|
535
|
-
throw new SessionError("placement_refused", `session ${sessionId} belongs to the ${
|
|
565
|
+
throw new SessionError("placement_refused", `session ${sessionId} belongs to the ${String(prior.placement_kind)} placement partition — a session-sync replace cannot overwrite a delegation transcript`);
|
|
536
566
|
}
|
|
537
|
-
await conn.query("DELETE FROM
|
|
538
|
-
|
|
539
|
-
|
|
567
|
+
const purged = 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]);
|
|
568
|
+
const swapped = (purged.rowCount ?? 0) === 1 ? prior : undefined;
|
|
569
|
+
const cells = carriedRowCells(sessionId, swapped === undefined ? undefined : { incarnation: swapped.incarnation, forkKey: swapped.fork_key });
|
|
570
|
+
const priorCell = swapped === undefined ? undefined : placementCellFromRow(sessionId, swapped);
|
|
571
|
+
if (priorCell?.role === "writer") {
|
|
572
|
+
await conn.query("ROLLBACK");
|
|
573
|
+
throw new SessionWriterPresentError(sessionId, priorCell.lane);
|
|
574
|
+
}
|
|
575
|
+
await this.writeImportedLog(conn, sessionId, owner, validated, cells, "replace");
|
|
540
576
|
await conn.query("COMMIT");
|
|
541
577
|
}
|
|
542
578
|
catch (err) {
|
|
@@ -545,7 +581,7 @@ export class PgSessionStore {
|
|
|
545
581
|
}
|
|
546
582
|
catch {
|
|
547
583
|
}
|
|
548
|
-
if (err instanceof SessionError)
|
|
584
|
+
if (err instanceof SessionError || err instanceof SessionWriterPresentError || err instanceof SessionActiveRunError)
|
|
549
585
|
throw err;
|
|
550
586
|
throw new SessionError("storage", `replace of session ${sessionId} failed`, err instanceof Error ? err : undefined);
|
|
551
587
|
}
|
|
@@ -553,16 +589,29 @@ export class PgSessionStore {
|
|
|
553
589
|
conn.release();
|
|
554
590
|
}
|
|
555
591
|
}
|
|
556
|
-
async
|
|
592
|
+
async writeImportedLog(conn, sessionId, owner, validated, cells, mode) {
|
|
557
593
|
let leafId = null;
|
|
558
594
|
for (const e of validated)
|
|
559
595
|
leafId = leafIdAfterEntry(e);
|
|
560
596
|
const now = new Date();
|
|
597
|
+
const imported = importedRowCells(cells.forkKey);
|
|
598
|
+
await conn.query(`INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation, ${imported.columns}) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)` +
|
|
599
|
+
(mode === "create" ? " ON CONFLICT (session_id) DO NOTHING" : ""), [sessionId, owner, now, now, leafId, validated.length, cells.incarnation, ...imported.values]);
|
|
600
|
+
if (mode === "create") {
|
|
601
|
+
const held = await conn.query("SELECT incarnation FROM session_meta WHERE session_id = $1 FOR UPDATE", [sessionId]);
|
|
602
|
+
if (String(held.rows[0]?.incarnation) !== cells.incarnation) {
|
|
603
|
+
throw new SessionError("storage", `import of session ${sessionId} failed`, new Error(`session ${sessionId} already exists — importEntries only creates a session (replaceEntries rewrites one); nothing was written`));
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
const claim = await lockRootAndReadClaim(rowsOnClient(conn), "pg", sessionId);
|
|
607
|
+
if (claim.activeTaskId !== null)
|
|
608
|
+
throw new SessionActiveRunError(sessionId, claim.activeTaskId);
|
|
609
|
+
if (mode === "replace")
|
|
610
|
+
await conn.query("DELETE FROM session_event WHERE session_id = $1", [sessionId]);
|
|
561
611
|
for (let seq = 0; seq < validated.length; seq++) {
|
|
562
612
|
const e = validated[seq];
|
|
563
613
|
await conn.query("INSERT INTO session_event (session_id, seq, entry_id, parent_id, type, payload, ts) VALUES ($1,$2,$3,$4,$5,$6::jsonb,$7)", [sessionId, seq, e.id, e.parentId ?? null, e.type, pgSafeJsonStringify(e), new Date(e.timestamp)]);
|
|
564
614
|
}
|
|
565
|
-
await conn.query("INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation) VALUES ($1,$2,$3,$4,$5,$6,$7)", [sessionId, owner, now, now, leafId, validated.length, incarnation]);
|
|
566
615
|
}
|
|
567
616
|
beginImportStaging(realSessionId, token) {
|
|
568
617
|
return new PgStagingHandle(this.pool, realSessionId, stagingIdFor(realSessionId, token));
|
|
@@ -587,6 +636,11 @@ export class PgSessionStore {
|
|
|
587
636
|
const conn = await this.pool.connect();
|
|
588
637
|
try {
|
|
589
638
|
await conn.query("BEGIN");
|
|
639
|
+
const claim = await lockRootAndReadClaim(rowsOnClient(conn), "pg", sessionId);
|
|
640
|
+
if (claim.activeTaskId !== null) {
|
|
641
|
+
await conn.query("ROLLBACK");
|
|
642
|
+
throw new SessionActiveRunError(sessionId, claim.activeTaskId);
|
|
643
|
+
}
|
|
590
644
|
const metaRes = await conn.query("DELETE FROM session_meta WHERE session_id = $1 AND owner IS NOT DISTINCT FROM $2", [sessionId, owner]);
|
|
591
645
|
if ((metaRes.rowCount ?? 0) > 0)
|
|
592
646
|
await conn.query("DELETE FROM session_event WHERE session_id = $1", [sessionId]);
|
|
@@ -666,6 +720,11 @@ class PgStagingHandle {
|
|
|
666
720
|
throw new StagedCommitOwnerChangedError(this.realSessionId);
|
|
667
721
|
}
|
|
668
722
|
}
|
|
723
|
+
const claim = await lockRootAndReadClaim(rowsOnClient(conn), "pg", this.realSessionId);
|
|
724
|
+
if (claim.activeTaskId !== null) {
|
|
725
|
+
await conn.query("ROLLBACK");
|
|
726
|
+
throw new SessionActiveRunError(this.realSessionId, claim.activeTaskId);
|
|
727
|
+
}
|
|
669
728
|
const staged = await conn.query("SELECT entry_id FROM session_event WHERE session_id = $1 ORDER BY seq ASC FOR UPDATE", [this.stagingId]);
|
|
670
729
|
const dst = await conn.query("SELECT entry_id FROM session_event WHERE session_id = $1 ORDER BY seq ASC FOR UPDATE", [this.realSessionId]);
|
|
671
730
|
const dstMeta = await conn.query("SELECT placement_kind FROM session_meta WHERE session_id = $1", [this.realSessionId]);
|
|
@@ -698,7 +757,16 @@ class PgStagingHandle {
|
|
|
698
757
|
let leafId = null;
|
|
699
758
|
if (lastRes.rows[0])
|
|
700
759
|
leafId = leafIdAfterEntry(decodeSessionEventPayload(lastRes.rows[0].payload, this.realSessionId, "last staged row"));
|
|
701
|
-
await conn.query(
|
|
760
|
+
const settle = await conn.query(`UPDATE session_meta SET owner = $1, updated_at = $2, leaf_id = $3, leaf_seq = $4, ${MIRROR_ON_COMMIT_SET} WHERE session_id = $5 AND ${MIRROR_ON_COMMIT_GUARD}`, [owner, now, leafId, srcIds.length, this.realSessionId]);
|
|
761
|
+
if ((settle.rowCount ?? 0) !== 1) {
|
|
762
|
+
const locked = readPlacementRowStatement("pg", this.realSessionId, { lock: true });
|
|
763
|
+
const lockedRow = (await conn.query(locked.text, [...locked.values])).rows[0];
|
|
764
|
+
const cell = lockedRow === undefined ? undefined : placementCellFromRow(this.realSessionId, lockedRow);
|
|
765
|
+
await conn.query("ROLLBACK");
|
|
766
|
+
if (cell?.role === "writer")
|
|
767
|
+
throw new SessionWriterPresentError(this.realSessionId, cell.lane);
|
|
768
|
+
throw new SessionError("storage", `staged commit for ${this.realSessionId}: the commit point matched no row under a held row lock and the row is not a writer — refusing to guess`);
|
|
769
|
+
}
|
|
702
770
|
const afterMeta = await conn.query("SELECT placement_kind, owner, incarnation FROM session_meta WHERE session_id = $1", [this.realSessionId]);
|
|
703
771
|
if (afterMeta.rows[0]?.placement_kind != null) {
|
|
704
772
|
await conn.query("ROLLBACK");
|
|
@@ -713,7 +781,7 @@ class PgStagingHandle {
|
|
|
713
781
|
await conn.query("ROLLBACK");
|
|
714
782
|
}
|
|
715
783
|
catch { }
|
|
716
|
-
if (err instanceof SyncConflictError || err instanceof SessionError)
|
|
784
|
+
if (err instanceof SyncConflictError || err instanceof SessionError || err instanceof SessionWriterPresentError || err instanceof SessionActiveRunError)
|
|
717
785
|
throw err;
|
|
718
786
|
throw new SessionError("storage", `staged commit for ${this.realSessionId} failed`, err instanceof Error ? err : undefined);
|
|
719
787
|
}
|
|
@@ -52,23 +52,8 @@ export interface AdbEnvDeps {
|
|
|
52
52
|
* **结构**信号;adb 的 shell v2 没有等价物,所以这里只能靠标记词,**这条臂就把话说在这里**。 */
|
|
53
53
|
export declare function isAdbTransportLost(stderr: string): boolean;
|
|
54
54
|
export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
|
|
55
|
-
/**
|
|
56
|
-
|
|
57
|
-
* 就是**命令真正跑的那块文件系统**的权威答案(`posix-shell-fs` 的 `canonicalPath` 原语,在设备 shell 里解到落点)。声明它 = 告诉引擎:整链答不出来是**解析器出了事**
|
|
58
|
-
* (RPC 断、传输掉),不是「一个它看不见的命名空间」⇒ 读边界的执行期复核**拒**,而不是让词法判决站着。
|
|
59
|
-
* 缺席是今天每个适配器的读法(整链沉默 ⇒ 词法判决成立、命令照跑),所以这一声明是**收紧**方向。
|
|
60
|
-
* 严格读法 `=== true`(core `canonicalPathIsAuthoritative`);`isSuspendable` 一族同样严格,对本仓的
|
|
61
|
-
* 布尔字面量零影响(四键都写死字面 `true`/`false`,不存在「非布尔值被读成缺席」那一形 —— 那一形由
|
|
62
|
-
* core 的 `config.execution_env_capability_invalid` 普查响亮播报,本仓的受众表已登记)。
|
|
63
|
-
* 谁该声明由闭集门看着(`test/execution-lane-caps.test.ts` 的逐 lane 对账:新 lane 不表态 = 编译红)。
|
|
64
|
-
*/
|
|
65
|
-
/** `sharesProcessTable`(core 7.57.0,必填):命令跑在设备上(adb shell),不在本进程所在的进程表。 */
|
|
66
|
-
readonly capabilities: {
|
|
67
|
-
isolation: boolean;
|
|
68
|
-
suspendable: boolean;
|
|
69
|
-
canonicalPathAuthoritative: boolean;
|
|
70
|
-
sharesProcessTable: boolean;
|
|
71
|
-
};
|
|
55
|
+
/** 能力块的唯一作者 = `capabilitiesFor`(`execution-lane-caps.ts`;逐键表态与理由在那里,本类零能力字面量)。 */
|
|
56
|
+
readonly capabilities: import("@sema-agent/core").ExecutionEnvCapabilities;
|
|
72
57
|
cwd: string;
|
|
73
58
|
private connected;
|
|
74
59
|
/** 🔴 拆除是**终态**(2026-07-25 补齐:此前本适配器是同族里唯一没有这个概念的一条腿)。
|
|
@@ -80,10 +65,13 @@ export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
|
|
|
80
65
|
private destroyed;
|
|
81
66
|
/** 在飞的那一次懒连接(单飞记忆)——见 {@link ensureConnected}。settle 即清,**不缓存败诺**。 */
|
|
82
67
|
private connectPromise?;
|
|
83
|
-
/** core `ExecutionEnv.homeDir`([ref]):设备 shell 里执行用户的 home ——
|
|
68
|
+
/** core `ExecutionEnv.homeDir`([ref]):设备 shell 里执行用户的 home —— 声明在场 ⇒ 声明(首连时与设备 shell 的 `$HOME` 对证过),否则首连时 `adb shell` 实测的 `$HOME`(Android 常为 `/` 或 `/data/local/tmp` 一类,读到什么填什么,绝对即可),见 {@link LaneHomeSeat}。读时才取(没声明时连上之前缺席)。 */
|
|
84
69
|
get homeDir(): string | undefined;
|
|
85
|
-
/** 家目录的座(
|
|
70
|
+
/** 家目录的座(声明在场 ⇒ 首连时对证 · 否则首连时实测 · 实测缺席 ⇒ 缺席 + 一行 warn)。设备 shell 答得出 `$HOME`,命令里的 `~` / `$HOME` 展开的就是它 ——
|
|
71
|
+
* 声明与它不一致时规则守的是声明那个目录,所以与其余读得出家目录的车道同一只判官、同一句拒。 */
|
|
86
72
|
private readonly homeSeat;
|
|
73
|
+
/** 家目录:设备答了而与声明不一致(或答的不是绝对路径)⇒ 这只环境的拒,记一次、此后每次连接原样回它(同一台设备同一个答案:不重试、不再问)。 */
|
|
74
|
+
private homeRefusal?;
|
|
87
75
|
/** core 7.49.0 [ref]:shell 子进程真拿到的 `CDPATH` 条目 —— 本车道的命令跑在 Android 设备的 shell 里(设备自己的 env),本类不读那份 env ⇒ `"unknown"`(core 契约:说不出就说 unknown,
|
|
88
76
|
* 不许报一张没读过的空表;删除守卫因此对裸 `cd <相对名>` 之后的删除问人,而不是按「没有 CDPATH」放行)。 */
|
|
89
77
|
readonly cdPath: "unknown";
|
|
@@ -175,8 +163,19 @@ export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
|
|
|
175
163
|
maxLines?: number;
|
|
176
164
|
abortSignal?: AbortSignal;
|
|
177
165
|
}): Promise<Result<string[], FileError>>;
|
|
166
|
+
/** 暂存写的两只面(规则与提交脚本的唯一属主 = `remote-shell.ts` `writeFileStaged` / `appendFileStaged`;父目录与私有暂存目录由编排的准备那一步建):
|
|
167
|
+
* 上传 = `adb push` 到私有目录里的暂存件;提交 = 文件面探针 exec。两者同一身份(push 与 `adb shell` 都由设备上的 adbd 以它的身份落盘 / 起进程)。 */
|
|
168
|
+
private stagedLane;
|
|
169
|
+
/** 整旧或整新(暂存 → 一次 `mv -f`)。修前 push 直落目标:传输中途断 / 取消时目标剩什么取决于设备侧 adbd 的落地实现,本适配器不依赖它。 */
|
|
178
170
|
writeFile(p: string, content: string | Uint8Array, abortSignal?: AbortSignal): Promise<Result<void, FileError>>;
|
|
171
|
+
/** 追加(暂存要加的字节 → 一次 `cat >>`;inode 不换、已有字节不重写)。修前 = 读旧 + 拼 + 整份 push(O(文件);中途断 ⇒ 目标没了或半份)。
|
|
172
|
+
* 目录不收新名字 / 私有目录收不成私有时的退路 = 修前那一形(push 没有追加写,只能把整份文件落到一个路径上):读旧(不在 ⇒ 按空;别的读错照实答、不 push)
|
|
173
|
+
* + 拼 + 整份 push 直落目标(与 e2b 共用 `rewriteAppend`)—— 非原子,push 中途断 / 取消 ⇒ 目标可能没了或只剩半份(只有 push 那一步经 `ctx.inPlace`:读旧时取消照答 `aborted`,目标未碰)。
|
|
174
|
+
* Android 共享存储(权限位由挂载派生)上收紧那一步按 sdcardfs / MediaProvider FUSE 的权限语义**推断**不过(未上真机,真机读数候 test),追加每次走这里。 */
|
|
179
175
|
appendFile(p: string, content: string | Uint8Array, abortSignal?: AbortSignal): Promise<Result<void, FileError>>;
|
|
176
|
+
/** 把整份内容 `adb push` 到设备上的 `dest`(建或覆盖)。本机这一侧先落一只本地临时件再 push(二进制安全,不经 shell 转义载荷)——
|
|
177
|
+
* 临时件同样只在私有目录里出现(`mkdtemp` 建的目录生来 0700),本机别的用户读不到;文件自己的权限位照缺省(push 把它带到设备上,与修前同)。 */
|
|
178
|
+
private push;
|
|
180
179
|
private posixFsInst?;
|
|
181
180
|
private get posixFs();
|
|
182
181
|
fileInfo(p: string, abortSignal?: AbortSignal): Promise<Result<FileInfo, FileError>>;
|