@moretea-labs/forge 1.8.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +70 -7
- package/CHANGELOG.md +14 -0
- package/CLAUDE.md +17 -2
- package/CONTRIBUTING.md +3 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/adapters/chatgpt/browser-delivery-host.ts +7 -1
- package/adapters/chatgpt/browser-delivery-runtime.ts +529 -56
- package/adapters/chatgpt/controller-binding-store.ts +101 -22
- package/adapters/chatgpt/controller-round-host.ts +15 -25
- package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
- package/adapters/chatgpt/provider-delivery.ts +228 -1
- package/adapters/chatgpt/work-conversation-binding-store.ts +79 -53
- package/adapters/computer/chatgpt-extension-target.ts +463 -0
- package/adapters/computer/chatgpt-target-router.ts +103 -0
- package/adapters/computer/chrome-extension/background.js +385 -0
- package/adapters/computer/chrome-extension/content.js +378 -0
- package/adapters/computer/chrome-extension/core.js +24 -0
- package/adapters/computer/chrome-extension/manifest.json +30 -0
- package/adapters/computer/desktop-operator-discovery.ts +11 -31
- package/adapters/computer/interaction-target-authority.ts +142 -18
- package/adapters/mcp/auth.ts +0 -1
- package/adapters/mcp/instructions.ts +5 -4
- package/adapters/mcp/multi-repository.ts +3 -19
- package/adapters/mcp/oauth.ts +73 -0
- package/adapters/mcp/paths.ts +4 -1
- package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +87 -0
- package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
- package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
- package/adapters/mcp/runtime-gateway/context-adapter.ts +411 -73
- package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
- package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
- package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
- package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
- package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
- package/adapters/mcp/runtime-gateway/execution-tools.ts +8 -42
- package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
- package/adapters/mcp/runtime-gateway/plugin-adapter.ts +117 -45
- package/adapters/mcp/runtime-gateway/process-tools.ts +190 -22
- package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
- package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
- package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
- package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
- package/adapters/mcp/runtime-gateway/router.ts +18 -504
- package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
- package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +14 -65
- package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +113 -173
- package/adapters/mcp/runtime-gateway/runtime-tools.ts +15 -5
- package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +1 -0
- package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
- package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +358 -266
- package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
- package/adapters/mcp/runtime-gateway/work-adapter.ts +261 -3122
- package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
- package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
- package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
- package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
- package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
- package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
- package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
- package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
- package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
- package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
- package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
- package/adapters/mcp/server.ts +67 -23
- package/adapters/mcp/setup.ts +1 -3
- package/adapters/mcp/tool-mapping/legacy-tool-service.ts +44 -170
- package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +4 -9
- package/adapters/mcp/tool-mapping/repository-tools.ts +133 -142
- package/adapters/mcp/toolset-names.ts +5 -0
- package/adapters/mcp/toolset.ts +6 -5
- package/adapters/mcp/transports/http-observation.ts +365 -0
- package/adapters/mcp/transports/http.ts +154 -677
- package/adapters/mcp/transports/oauth-http.ts +322 -0
- package/adapters/mcp/transports/session-registry.ts +6 -0
- package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
- package/assets/plugin-registry.v1.json +6 -4
- package/assets/reference-configs/agentic-development-flow.md +25 -0
- package/assets/reference-configs/global-working-rules.md +19 -0
- package/assets/skill-version.json +2 -2
- package/docs/architecture/CURRENT.md +111 -41
- package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
- package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
- package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
- package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
- package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
- package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
- package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
- package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
- package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
- package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
- package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
- package/docs/architecture/domains/verification.md +1 -0
- package/docs/architecture/domains/workflow-engine.md +6 -0
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
- package/docs/forge-plugin-management.md +2 -2
- package/docs/operations/controller-performance-and-502.md +17 -0
- package/docs/operations/controller-reliability-runbook.md +2 -2
- package/docs/operations/features.md +1 -1
- package/docs/operations/features.zh-CN.md +1 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +2 -0
- package/docs/operations/releasing.md +2 -0
- package/docs/operations/standalone-disaster-recovery.md +14 -6
- package/docs/wiki/Implementation.md +1 -1
- package/package.json +25 -14
- package/packages/kernel/cognition/api/index.ts +6 -0
- package/packages/kernel/cognition/application/activation-service.ts +451 -0
- package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
- package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
- package/packages/kernel/cognition/application/memory-service.ts +64 -0
- package/packages/kernel/cognition/domain/learning.ts +106 -0
- package/packages/kernel/cognition/domain/memory.ts +254 -0
- package/packages/kernel/controller/api/index.ts +1 -0
- package/packages/kernel/controller/application/continuation-service.ts +281 -0
- package/packages/kernel/controller/application/controller-round-service.ts +12 -0
- package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
- package/packages/kernel/controller/domain/controller-round.ts +4 -1
- package/packages/kernel/controller/domain/execution-quality.ts +3 -1
- package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
- package/packages/kernel/controller/infrastructure/controller-session-store.ts +297 -71
- package/packages/kernel/controller/ports/controller-host.ts +2 -0
- package/packages/kernel/identity/api/index.ts +10 -0
- package/packages/kernel/identity/domain/activity-projection.ts +43 -0
- package/packages/kernel/identity/domain/capability-broker.ts +60 -0
- package/packages/kernel/identity/domain/grant.ts +72 -0
- package/packages/kernel/identity/domain/owned-resource.ts +116 -0
- package/packages/kernel/identity/domain/user-request.ts +93 -0
- package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
- package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
- package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
- package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
- package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
- package/packages/kernel/scheduler/api/index.ts +0 -2
- package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
- package/packages/kernel/scheduler/application/settlement.ts +0 -15
- package/packages/kernel/scheduler/domain/schedule.ts +87 -0
- package/packages/kernel/scheduler/infrastructure/schedule-store.ts +153 -133
- package/packages/kernel/work/api/index.ts +3 -2
- package/packages/kernel/work/application/work-service.ts +17 -42
- package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
- package/packages/kernel/work/domain/engineering-design.ts +10 -5
- package/packages/kernel/work/domain/engineering-profile.ts +8 -12
- package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
- package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
- package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
- package/packages/kernel/work/domain/implementation-review.ts +14 -331
- package/packages/kernel/work/domain/objective-graph.ts +119 -0
- package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
- package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
- package/packages/kernel/work/domain/state-machine.ts +25 -63
- package/packages/kernel/work/domain/types.ts +57 -51
- package/packages/kernel/work/infrastructure/work-contract-store.ts +819 -728
- package/packages/kernel/work/ports/work-contract-store.ts +5 -2
- package/packages/plugin-runtime/browser/session-authority.ts +2 -1
- package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
- package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
- package/packages/plugin-runtime/computer/index.ts +2 -0
- package/packages/plugin-runtime/computer/target-authority.ts +26 -1
- package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
- package/packages/protocols/computer/contract.ts +27 -1
- package/scripts/activate-source-baseline.ts +7 -9
- package/scripts/canary-controller-semantic-wait.ts +12 -24
- package/scripts/check-mcp-compatibility.ts +48 -136
- package/scripts/check-runtime-architecture.mjs +622 -217
- package/scripts/forge-local-recovery-helper.mjs +93 -15
- package/scripts/lib/project-init-lib.sh +3 -0
- package/scripts/open-source-audit-allowlist.txt +1 -2
- package/scripts/run-bounded-command.mjs +5 -0
- package/scripts/run-governed-gate.ts +0 -1
- package/scripts/run-mobile-monitor-bridge.ts +0 -1
- package/scripts/smoke-control-plane-failure-domain.ts +94 -0
- package/scripts/smoke-mcp-http-runtime.ts +5 -0
- package/scripts/smoke-runtime-recovery.ts +12 -43
- package/scripts/smoke-schedule-engine.ts +23 -15
- package/scripts/smoke-unattended-transport-recovery.ts +223 -0
- package/scripts/smoke-user-request-continuation-restart.ts +232 -0
- package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
- package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
- package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
- package/scripts/smoke-workflow-supervisor.ts +103 -0
- package/scripts/verify-forge-runtime.sh +2 -1
- package/src/cli/agent-jobs/executor-health.ts +11 -34
- package/src/cli/agent-jobs/integration.ts +18 -49
- package/src/cli/agent-jobs/job-manager.ts +7 -3
- package/src/cli/commands/brain-assistant.ts +27 -13
- package/src/cli/commands/brain.ts +13 -15
- package/src/cli/commands/chatgpt.ts +1 -163
- package/src/cli/commands/recovery.ts +135 -121
- package/src/cli/commands/runtime.ts +3 -3
- package/src/cli/commands/setup-profile.ts +8 -0
- package/src/cli/controller/check-runner.ts +13 -2
- package/src/cli/controller/completion-backlog.ts +3 -3
- package/src/cli/controller/completion-orchestrator.ts +4 -43
- package/src/cli/controller/completion-target.ts +3 -72
- package/src/cli/controller/context/source-materializer.ts +81 -100
- package/src/cli/controller/context-pack.ts +10 -8
- package/src/cli/controller/execution-completion.ts +4 -7
- package/src/cli/controller/execution-policy.ts +36 -153
- package/src/cli/controller/governance.ts +2 -3
- package/src/cli/controller/issue-store.ts +4 -99
- package/src/cli/controller/launch-agents.ts +59 -18
- package/src/cli/controller/operational-plan.ts +24 -51
- package/src/cli/controller/runtime-config.ts +5 -1
- package/src/cli/controller/stuck-state-migration.ts +2 -3
- package/src/cli/controller/systemd-user.ts +39 -1
- package/src/cli/editing/edit-session.ts +1 -7
- package/src/cli/local-bridge/console-automations.ts +18 -13
- package/src/cli/local-bridge/console-view-models.ts +3 -12
- package/src/cli/local-bridge/facade-api.ts +64 -191
- package/src/cli/local-bridge/server.ts +24 -147
- package/src/cli/local-bridge/types.ts +0 -1
- package/src/cli/mcp/oauth-client-retirement.ts +74 -0
- package/src/cli/repositories/command-executor.ts +29 -23
- package/src/cli/repositories/command-scope.ts +35 -16
- package/src/cli/repositories/controller-home.ts +48 -0
- package/src/cli/repositories/ephemeral-workspace.ts +20 -30
- package/src/cli/repositories/git-command-executor.ts +2 -2
- package/src/cli/repositories/registry.ts +77 -11
- package/src/cli/repositories/structured-git.ts +62 -2
- package/src/cli/repository/session-cache.ts +92 -6
- package/src/runtime/context/assistant-context.ts +20 -7
- package/src/runtime/context/assistant-work-context.ts +89 -27
- package/src/runtime/context/automatic-learning.ts +565 -0
- package/src/runtime/context/cognitive-attention.ts +173 -0
- package/src/runtime/context/cognitive-skill-canary.ts +158 -0
- package/src/runtime/context/context-closure.ts +46 -9
- package/src/runtime/context/context-pack-process.ts +103 -0
- package/src/runtime/context/context-plane.ts +1 -9
- package/src/runtime/context/direct-controller-learning.ts +298 -0
- package/src/runtime/context/semantic-navigation-contract.ts +9 -0
- package/src/runtime/context/semantic-navigation.ts +6 -34
- package/src/runtime/context/typescript-navigation-process.ts +145 -0
- package/src/runtime/context/typescript-navigation.ts +89 -3
- package/src/runtime/control-plane/cleanup-artifact-retention.ts +212 -9
- package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
- package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
- package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
- package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
- package/src/runtime/control-plane/execution/session-store.ts +31 -1
- package/src/runtime/control-plane/execution/validation.ts +6 -8
- package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
- package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
- package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
- package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
- package/src/runtime/control-plane/execution/work-handle-authority.ts +188 -109
- package/src/runtime/control-plane/execution/work-handle-store.ts +19 -43
- package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
- package/src/runtime/control-plane/execution/work-operation-service.ts +43 -27
- package/src/runtime/control-plane/execution/work-preparation-service.ts +126 -266
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
- package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +173 -186
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +28 -84
- package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
- package/src/runtime/control-plane/facade/capability-registry.ts +362 -37
- package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
- package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
- package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
- package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
- package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
- package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
- package/src/runtime/control-plane/facade/index.ts +0 -1
- package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
- package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
- package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
- package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
- package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
- package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
- package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
- package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
- package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
- package/src/runtime/control-plane/facade/types.ts +49 -108
- package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
- package/src/runtime/control-plane/generated-cache-retention.ts +97 -1
- package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +239 -112
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +2 -1
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
- package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
- package/src/runtime/control-plane/governance/access-policy.ts +19 -2
- package/src/runtime/control-plane/governance/authorization.ts +20 -3
- package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +28 -300
- package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
- package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
- package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
- package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
- package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
- package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
- package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
- package/src/runtime/control-plane/release-retention.ts +135 -47
- package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
- package/src/runtime/control-plane/runtime-cleanup.ts +290 -21
- package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
- package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
- package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
- package/src/runtime/diagnostics/incident-repair.ts +313 -146
- package/src/runtime/diagnostics/mcp-timing.ts +114 -0
- package/src/runtime/evidence/artifact-store.ts +158 -40
- package/src/runtime/evidence/evidence-store.ts +112 -8
- package/src/runtime/evidence/output-handle-index.ts +225 -0
- package/src/runtime/evidence/result-store.ts +158 -44
- package/src/runtime/execution/jobs/store.ts +3 -4
- package/src/runtime/execution/managed-workspace.ts +57 -0
- package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
- package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
- package/src/runtime/execution/process-runtime/check-result.ts +105 -1
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
- package/src/runtime/execution/process-runtime/command-facade.ts +79 -27
- package/src/runtime/execution/process-runtime/gc.ts +15 -2
- package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
- package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
- package/src/runtime/execution/process-runtime/index.ts +3 -0
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
- package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
- package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
- package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
- package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
- package/src/runtime/execution/process-runtime/runtime.ts +35 -2
- package/src/runtime/execution/process-runtime/store.ts +30 -2
- package/src/runtime/execution/process-runtime/types.ts +6 -1
- package/src/runtime/execution/workers/executor.ts +2 -6
- package/src/runtime/platform/service-inventory.ts +130 -0
- package/src/runtime/platform/service-manager.ts +8 -0
- package/src/runtime/plugins/action-application.ts +85 -28
- package/src/runtime/plugins/app-store-connect-adapter.ts +38 -14
- package/src/runtime/plugins/browser-adapter.ts +757 -34
- package/src/runtime/plugins/browser-automation-service.ts +23 -3
- package/src/runtime/plugins/browser-macos-bridge.ts +321 -29
- package/src/runtime/plugins/browser-manifest-surface.ts +45 -11
- package/src/runtime/plugins/browser-native-session-service.ts +63 -13
- package/src/runtime/plugins/browser-registration.ts +16 -0
- package/src/runtime/plugins/browser-runtime.ts +14 -1
- package/src/runtime/plugins/browser-session-authority.ts +2 -2
- package/src/runtime/plugins/browser-session-store.ts +46 -76
- package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
- package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
- package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
- package/src/runtime/plugins/computer-registration.ts +222 -11
- package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
- package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
- package/src/runtime/plugins/external-adapter.ts +42 -6
- package/src/runtime/plugins/external-registration.ts +21 -1
- package/src/runtime/plugins/gmail-adapter.ts +23 -2
- package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
- package/src/runtime/plugins/google-shared.ts +14 -7
- package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
- package/src/runtime/plugins/ios-adapter.ts +1 -1
- package/src/runtime/plugins/lightweight-action.ts +208 -2
- package/src/runtime/plugins/local-system-adapter.ts +12 -2
- package/src/runtime/plugins/managed-process-adapter.ts +12 -5
- package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
- package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
- package/src/runtime/plugins/store.ts +602 -428
- package/src/runtime/plugins/types.ts +20 -0
- package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
- package/src/runtime/projections/invalidation.ts +7 -3
- package/src/runtime/projections/materialized-view.ts +80 -36
- package/src/runtime/recovery/actions.ts +3 -3
- package/src/runtime/recovery/capability-action-application.ts +46 -45
- package/src/runtime/recovery/lifecycle-inventory.ts +29 -29
- package/src/runtime/recovery/maintenance-executor.ts +374 -123
- package/src/runtime/recovery/store.ts +29 -11
- package/src/runtime/release/release-coordinator.ts +296 -0
- package/src/runtime/release/release-session.ts +716 -0
- package/src/runtime/release/release-state-migration.ts +25 -0
- package/src/runtime/resources/leases/store.ts +56 -25
- package/src/runtime/root/computer-composition.ts +191 -6
- package/src/runtime/root/controller-progression-composition.ts +192 -0
- package/src/runtime/root/controller-round-composition.ts +20 -1
- package/src/runtime/root/deployment-topology.ts +106 -0
- package/src/runtime/root/entry.ts +4 -3
- package/src/runtime/root/known-good-recovery.ts +184 -0
- package/src/runtime/root/local-bridge.ts +0 -1
- package/src/runtime/root/mcp-transport.ts +111 -18
- package/src/runtime/root/ownership.ts +261 -9
- package/src/runtime/root/package-connector-service.ts +105 -19
- package/src/runtime/root/package-runtime-release.ts +117 -18
- package/src/runtime/root/package-runtime-service.ts +17 -11
- package/src/runtime/root/release-execution-canary.ts +44 -12
- package/src/runtime/root/release-loader.ts +90 -8
- package/src/runtime/root/release-manifest.ts +80 -6
- package/src/runtime/root/release-materialize.ts +372 -28
- package/src/runtime/root/release-store.ts +395 -36
- package/src/runtime/root/runtime-lane.ts +191 -0
- package/src/runtime/root/runtime.ts +159 -27
- package/src/runtime/root/scheduled-controller-composition.ts +28 -3
- package/src/runtime/root/service-runner.ts +2 -2
- package/src/runtime/root/service.ts +36 -33
- package/src/runtime/root/status.ts +48 -0
- package/src/runtime/root/types.ts +32 -3
- package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
- package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
- package/src/runtime/root/write-fence.ts +50 -2
- package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
- package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
- package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
- package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
- package/src/runtime/shared/process-environment.ts +20 -9
- package/src/runtime/shared/response-budget.ts +1 -3
- package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
- package/src/runtime/standalone-recovery/core.ts +3702 -342
- package/src/runtime/standalone-recovery/entry.ts +469 -39
- package/src/runtime/standalone-recovery/installer.ts +262 -148
- package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
- package/src/runtime/standalone-recovery/operation-lock.ts +1 -1
- package/src/runtime/standalone-recovery/performance.ts +54 -16
- package/src/runtime/standalone-recovery/release.ts +53 -5
- package/src/runtime/standalone-recovery/service-labels.ts +5 -2
- package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
- package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
- package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +10 -3
- package/src/runtime/workflow/schedules/engine.ts +138 -172
- package/src/runtime/workflow/schedules/work-continuation.ts +44 -5
- package/src/runtime/workflows/runtime.ts +15 -19
- package/src/testing/test-governance.ts +5 -1
- package/supervisor/chatgpt-conversation.ts +23 -0
- package/supervisor/client.ts +201 -0
- package/supervisor/control-plane.ts +868 -0
- package/supervisor/entry.ts +15 -0
- package/supervisor/forge-validators.ts +80 -0
- package/supervisor/index.ts +5 -0
- package/supervisor/native-browser-adapter.ts +786 -0
- package/supervisor/native-messaging/host.ts +39 -0
- package/supervisor/native-messaging/manifest.ts +26 -0
- package/supervisor/native-messaging/protocol.ts +27 -0
- package/supervisor/paths.ts +18 -0
- package/supervisor/protocol.ts +202 -0
- package/supervisor/server.ts +404 -0
- package/supervisor/store.ts +1451 -0
- package/supervisor/tsconfig.json +8 -0
- package/supervisor/types.ts +255 -0
- package/adapters/chatgpt/controller-host.ts +0 -119
- package/adapters/mcp/controller-round-compatibility.ts +0 -184
- package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
- package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
- package/packages/kernel/progression/api/index.ts +0 -2
- package/packages/kernel/progression/application/projector.ts +0 -211
- package/packages/kernel/progression/domain/types.ts +0 -116
- package/packages/kernel/progression/index.ts +0 -1
- package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
- package/packages/kernel/scheduler/domain/continuation.ts +0 -38
- package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
- package/packages/kernel/work/domain/admission-policy.ts +0 -34
- package/scripts/benchmark-background-check-overlap.ts +0 -228
- package/scripts/benchmark-computer-hotpath.ts +0 -255
- package/scripts/benchmark-controller-hotpath.ts +0 -212
- package/scripts/benchmark-controller-round2.ts +0 -191
- package/scripts/benchmark-ios-agent-device.ts +0 -511
- package/scripts/benchmark-mcp-host.sh +0 -117
- package/scripts/benchmark-mcp-transport.ts +0 -169
- package/scripts/benchmark-operational-memory-activation.ts +0 -235
- package/scripts/benchmark-operational-shadow.ts +0 -28
- package/scripts/benchmark-quality-harness.ts +0 -146
- package/scripts/benchmark-route-session-concurrency.ts +0 -915
- package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
- package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
- package/scripts/benchmark-thin-harness.ts +0 -251
- package/scripts/benchmark-typescript-navigation.ts +0 -186
- package/scripts/benchmark-work-efficiency.ts +0 -334
- package/scripts/build-controller-ui.ts +0 -28
- package/scripts/check-npm-release.sh +0 -32
- package/scripts/check-public-release-surface.sh +0 -19
- package/scripts/check-release-published.sh +0 -57
- package/scripts/check-release-readiness.sh +0 -37
- package/scripts/check-release-version.mjs +0 -74
- package/scripts/check-tarball-install-smoke.sh +0 -150
- package/scripts/package-source-archive.sh +0 -147
- package/scripts/public-release-files.txt +0 -39
- package/scripts/public-release.ts +0 -174
- package/scripts/publish-release-tarball.sh +0 -27
- package/scripts/route-nl-vs-ts-eval.ts +0 -679
- package/scripts/stage-runtime-release.ts +0 -44
- package/src/cli/controller/progress.ts +0 -656
- package/src/cli/controller/work-mode.ts +0 -181
- package/src/cli/local-bridge/console-assets.ts +0 -17
- package/src/cli/local-bridge/dashboard.ts +0 -17
- package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
- package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
- package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
- package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
- package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
- package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
- package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
- package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
- package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
- package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/styles.css +0 -28
- package/src/cli/local-bridge/frontend/src/types.ts +0 -15
- package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
- package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
- package/src/cli/local-bridge/ui-dist/app.css +0 -1
- package/src/cli/local-bridge/ui-dist/app.js +0 -11228
- package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
- package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
- package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
- package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
- package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
- package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
- package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
- package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
- package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
- package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
- package/src/runtime/control-plane/routing/index.ts +0 -1
- package/src/runtime/control-plane/routing/route-policy.ts +0 -401
- package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
|
@@ -33,6 +33,13 @@ export function browserPermissions(ready: boolean): AssistantPluginPermissionSco
|
|
|
33
33
|
granted: ready,
|
|
34
34
|
required: true,
|
|
35
35
|
},
|
|
36
|
+
{
|
|
37
|
+
scope: 'browser.extensions',
|
|
38
|
+
mode: 'write',
|
|
39
|
+
description: 'List or load bounded unpacked extensions through the existing Browser provider control plane.',
|
|
40
|
+
granted: ready,
|
|
41
|
+
required: false,
|
|
42
|
+
},
|
|
36
43
|
];
|
|
37
44
|
}
|
|
38
45
|
|
|
@@ -64,6 +71,13 @@ export function browserCapabilities(): AssistantPluginCapability[] {
|
|
|
64
71
|
'get_console_errors', 'get_failed_requests',
|
|
65
72
|
],
|
|
66
73
|
},
|
|
74
|
+
{
|
|
75
|
+
capabilityId: 'browser-extensions',
|
|
76
|
+
title: 'Browser Extensions',
|
|
77
|
+
description: 'List or load unpacked extensions from policy-bounded local directories without exposing raw CDP methods.',
|
|
78
|
+
scopes: ['browser.extensions', 'browser.profile'],
|
|
79
|
+
actions: ['list_unpacked_extensions', 'install_unpacked_extension'],
|
|
80
|
+
},
|
|
67
81
|
{
|
|
68
82
|
capabilityId: 'browser-interaction',
|
|
69
83
|
title: 'Browser Interaction',
|
|
@@ -112,11 +126,11 @@ function interactSchema(extra: Record<string, unknown>, required: string[]): Rec
|
|
|
112
126
|
export function browserActions(): AssistantPluginActionDescriptor[] {
|
|
113
127
|
const readRemote = [
|
|
114
128
|
{ resource: 'remote' as const, mode: 'read' as const },
|
|
115
|
-
{ resource: '
|
|
129
|
+
{ resource: 'provider-state' as const, mode: 'write' as const },
|
|
116
130
|
];
|
|
117
131
|
const writeRemote = [
|
|
118
132
|
{ resource: 'remote' as const, mode: 'exclusive' as const },
|
|
119
|
-
{ resource: '
|
|
133
|
+
{ resource: 'provider-state' as const, mode: 'write' as const },
|
|
120
134
|
];
|
|
121
135
|
const descriptors: AssistantPluginActionDescriptor[] = [
|
|
122
136
|
{
|
|
@@ -130,7 +144,7 @@ export function browserActions(): AssistantPluginActionDescriptor[] {
|
|
|
130
144
|
cancellable: true,
|
|
131
145
|
idempotent: true,
|
|
132
146
|
scopes: ['browser.profile'],
|
|
133
|
-
resourceClaims: [{ resource: '
|
|
147
|
+
resourceClaims: [{ resource: 'provider-state', mode: 'write' }],
|
|
134
148
|
argumentsSchema: {
|
|
135
149
|
type: 'object',
|
|
136
150
|
properties: {
|
|
@@ -158,12 +172,31 @@ export function browserActions(): AssistantPluginActionDescriptor[] {
|
|
|
158
172
|
additionalProperties: false,
|
|
159
173
|
},
|
|
160
174
|
},
|
|
175
|
+
{
|
|
176
|
+
actionId: 'list_unpacked_extensions',
|
|
177
|
+
title: 'List unpacked browser extensions',
|
|
178
|
+
description: 'List unpacked extensions visible to the selected Browser provider. No arbitrary CDP method is accepted.',
|
|
179
|
+
readOnly: true, risk: 'readonly', confirmation: 'none', defaultTimeoutMs: 30_000, cancellable: true, idempotent: true,
|
|
180
|
+
scopes: ['browser.extensions', 'browser.profile'], resourceClaims: readRemote,
|
|
181
|
+
argumentsSchema: sessionTargetSchema({}, []),
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
actionId: 'install_unpacked_extension',
|
|
185
|
+
title: 'Install unpacked browser extension',
|
|
186
|
+
description: 'Load one policy-bounded unpacked extension directory through the selected Browser provider and verify its exact installed identity.',
|
|
187
|
+
readOnly: false, risk: 'remote_write', confirmation: 'authorization', defaultTimeoutMs: 30_000, cancellable: false, idempotent: false,
|
|
188
|
+
scopes: ['browser.extensions', 'browser.profile'], resourceClaims: writeRemote,
|
|
189
|
+
argumentsSchema: sessionTargetSchema({
|
|
190
|
+
extension_path: { type: 'string' },
|
|
191
|
+
enable_in_incognito: { type: 'boolean' },
|
|
192
|
+
}, ['extension_path']),
|
|
193
|
+
},
|
|
161
194
|
{
|
|
162
195
|
actionId: 'create_session',
|
|
163
196
|
title: 'Create browser session',
|
|
164
197
|
description: 'Open an HTTP(S) URL or explicitly adopt the matching frontmost native tab, then persist a reusable session id.',
|
|
165
198
|
readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 60_000, cancellable: true, idempotent: false,
|
|
166
|
-
scopes: ['browser.read', 'browser.profile'], resourceClaims:
|
|
199
|
+
scopes: ['browser.read', 'browser.profile'], resourceClaims: readRemote,
|
|
167
200
|
argumentsSchema: sessionTargetSchema({
|
|
168
201
|
extract_text: { type: 'boolean' },
|
|
169
202
|
max_chars: { type: 'number' },
|
|
@@ -178,7 +211,7 @@ export function browserActions(): AssistantPluginActionDescriptor[] {
|
|
|
178
211
|
title: 'List browser sessions',
|
|
179
212
|
description: 'List saved browser session metadata without secrets or cookies.',
|
|
180
213
|
readOnly: true, risk: 'readonly', confirmation: 'none', defaultTimeoutMs: 10_000, cancellable: true, idempotent: true,
|
|
181
|
-
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: '
|
|
214
|
+
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: 'provider-state', mode: 'read' }],
|
|
182
215
|
argumentsSchema: {
|
|
183
216
|
type: 'object',
|
|
184
217
|
properties: {
|
|
@@ -193,7 +226,7 @@ export function browserActions(): AssistantPluginActionDescriptor[] {
|
|
|
193
226
|
title: 'Reconcile browser sessions',
|
|
194
227
|
description: 'Prune only saved managed-session metadata whose exact Runtime-bound page is positively proven gone. Never removes profiles, cookies, or unverified native sessions.',
|
|
195
228
|
readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 15_000, cancellable: true, idempotent: true,
|
|
196
|
-
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: '
|
|
229
|
+
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: 'provider-state', mode: 'write' }],
|
|
197
230
|
argumentsSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
198
231
|
},
|
|
199
232
|
{
|
|
@@ -201,7 +234,7 @@ export function browserActions(): AssistantPluginActionDescriptor[] {
|
|
|
201
234
|
title: 'Close browser session',
|
|
202
235
|
description: 'Remove one saved session metadata record.',
|
|
203
236
|
readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 15_000, cancellable: true, idempotent: true,
|
|
204
|
-
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: '
|
|
237
|
+
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: 'provider-state', mode: 'write' }],
|
|
205
238
|
argumentsSchema: { type: 'object', properties: { session_id: { type: 'string' } }, required: ['session_id'], additionalProperties: false },
|
|
206
239
|
},
|
|
207
240
|
{
|
|
@@ -209,7 +242,7 @@ export function browserActions(): AssistantPluginActionDescriptor[] {
|
|
|
209
242
|
title: 'Clear all browser sessions',
|
|
210
243
|
description: 'Remove all saved session metadata while keeping the profile.',
|
|
211
244
|
readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 15_000, cancellable: true, idempotent: true,
|
|
212
|
-
scopes: ['browser.profile'], resourceClaims: [{ resource: '
|
|
245
|
+
scopes: ['browser.profile'], resourceClaims: [{ resource: 'provider-state', mode: 'write' }],
|
|
213
246
|
argumentsSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
214
247
|
},
|
|
215
248
|
{
|
|
@@ -229,7 +262,7 @@ export function browserActions(): AssistantPluginActionDescriptor[] {
|
|
|
229
262
|
title: 'Get browser handoff status',
|
|
230
263
|
description: 'Read durable browser handoff status and reconcile a stale or crashed host.',
|
|
231
264
|
readOnly: true, risk: 'readonly', confirmation: 'none', defaultTimeoutMs: 10_000, cancellable: true, idempotent: true,
|
|
232
|
-
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: '
|
|
265
|
+
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: 'provider-state', mode: 'read' }],
|
|
233
266
|
argumentsSchema: { type: 'object', properties: { interaction_id: { type: 'string' } }, required: ['interaction_id'], additionalProperties: false },
|
|
234
267
|
},
|
|
235
268
|
{
|
|
@@ -237,7 +270,7 @@ export function browserActions(): AssistantPluginActionDescriptor[] {
|
|
|
237
270
|
title: 'Resolve browser handoff',
|
|
238
271
|
description: 'Resume or cancel a foreground browser handoff.',
|
|
239
272
|
readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 15_000, cancellable: true, idempotent: true,
|
|
240
|
-
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: '
|
|
273
|
+
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: 'provider-state', mode: 'write' }],
|
|
241
274
|
argumentsSchema: {
|
|
242
275
|
type: 'object',
|
|
243
276
|
properties: {
|
|
@@ -605,7 +638,7 @@ export function browserActions(): AssistantPluginActionDescriptor[] {
|
|
|
605
638
|
title: 'Close session',
|
|
606
639
|
description: 'Remove saved session metadata while keeping the persistent profile.',
|
|
607
640
|
readOnly: false, risk: 'workspace_write', confirmation: 'authorization', defaultTimeoutMs: 15_000, cancellable: true, idempotent: true,
|
|
608
|
-
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: '
|
|
641
|
+
scopes: ['browser.read', 'browser.profile'], resourceClaims: [{ resource: 'provider-state', mode: 'write' }],
|
|
609
642
|
argumentsSchema: { type: 'object', properties: { session_id: { type: 'string' } }, required: ['session_id'], additionalProperties: false },
|
|
610
643
|
},
|
|
611
644
|
];
|
|
@@ -618,6 +651,7 @@ export function browserActions(): AssistantPluginActionDescriptor[] {
|
|
|
618
651
|
]);
|
|
619
652
|
return descriptors.map((descriptor) => ({
|
|
620
653
|
...descriptor,
|
|
654
|
+
executionMode: 'runtime',
|
|
621
655
|
foregroundEffect: foregroundRequired.has(descriptor.actionId)
|
|
622
656
|
? 'required'
|
|
623
657
|
: foregroundPossible.has(descriptor.actionId)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { AssistantPluginError } from './errors';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
closeResolvedMacOsBrowserOwnedTab,
|
|
4
4
|
listMacOsBrowserTabs,
|
|
5
5
|
macOsBrowserPageHandleStale,
|
|
6
|
-
|
|
6
|
+
readResolvedMacOsBrowserOwnedTabMetadata,
|
|
7
7
|
type MacOsBrowserProduct,
|
|
8
8
|
} from './browser-macos-bridge';
|
|
9
9
|
import { listSavedBrowserSessions, removeBrowserSession } from './browser-session-store';
|
|
@@ -19,12 +19,22 @@ export interface NativeOwnedSessionInspection {
|
|
|
19
19
|
failedCleanupCount: number;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
const MAX_NATIVE_INVENTORY_TIMEOUT_MS = 3_000;
|
|
23
|
+
|
|
24
|
+
function nativeInventoryTimeoutMs(timeoutMs: number): number {
|
|
25
|
+
return Math.max(1, Math.min(timeoutMs, MAX_NATIVE_INVENTORY_TIMEOUT_MS));
|
|
26
|
+
}
|
|
27
|
+
|
|
22
28
|
export function nativeTabInventoryUnsupported(error: unknown): boolean {
|
|
23
29
|
if (error instanceof AssistantPluginError && error.code === 'BROWSER_AUTOMATION_ACTION_UNSUPPORTED') return true;
|
|
24
30
|
const message = error instanceof Error ? error.message : String(error ?? '');
|
|
25
31
|
return /\bBROWSER_AUTOMATION_ACTION_UNSUPPORTED\b/.test(message);
|
|
26
32
|
}
|
|
27
33
|
|
|
34
|
+
function nativeBrowserApplicationNotRunning(error: unknown): boolean {
|
|
35
|
+
return error instanceof AssistantPluginError && error.code === 'PLUGIN_BROWSER_NATIVE_APP_NOT_RUNNING';
|
|
36
|
+
}
|
|
37
|
+
|
|
28
38
|
function isDiscardableNativeOwnedTabUrl(url: string): boolean {
|
|
29
39
|
const normalized = url.trim().toLowerCase();
|
|
30
40
|
return normalized === ''
|
|
@@ -35,6 +45,20 @@ function isDiscardableNativeOwnedTabUrl(url: string): boolean {
|
|
|
35
45
|
|| normalized === 'vivaldi://startpage/';
|
|
36
46
|
}
|
|
37
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Native tab ids are only stable while the browser keeps the same tab alive.
|
|
50
|
+
* If a later inventory resolves that id to a different URL, the saved binding
|
|
51
|
+
* no longer proves ownership of that live tab. Treat the session as detached;
|
|
52
|
+
* never close the replacement tab merely because it inherited an old id.
|
|
53
|
+
*/
|
|
54
|
+
function nativeTabMatchesSessionUrl(session: BrowserSessionState, url: string): boolean {
|
|
55
|
+
try {
|
|
56
|
+
return new URL(session.url).toString() === new URL(url).toString();
|
|
57
|
+
} catch {
|
|
58
|
+
return session.url.trim() === url.trim();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
38
62
|
/**
|
|
39
63
|
* Native tab liveness/cleanup belongs to one service so the Browser adapter does
|
|
40
64
|
* not reinterpret stable native identity or prune policy action-by-action.
|
|
@@ -75,13 +99,26 @@ export async function inspectNativeOwnedSessions(input: {
|
|
|
75
99
|
let inventory = inventories.get(product);
|
|
76
100
|
if (!inventory) {
|
|
77
101
|
try {
|
|
78
|
-
inventory = await listMacOsBrowserTabs(product, timeoutMs);
|
|
102
|
+
inventory = await listMacOsBrowserTabs(product, nativeInventoryTimeoutMs(timeoutMs));
|
|
79
103
|
} catch (error) {
|
|
80
104
|
inventory = error instanceof Error ? error : new Error(String(error));
|
|
81
105
|
}
|
|
82
106
|
inventories.set(product, inventory);
|
|
83
107
|
}
|
|
84
108
|
if (inventory instanceof Error) {
|
|
109
|
+
// A plugin-owned tab cannot outlive its native browser process. This is
|
|
110
|
+
// stronger than an unavailable inventory: retire the stale transport
|
|
111
|
+
// metadata so a later continuation opens a fresh effect-scoped tab.
|
|
112
|
+
if (nativeBrowserApplicationNotRunning(inventory)) {
|
|
113
|
+
const pruned = input.pruneDead === true;
|
|
114
|
+
if (pruned) {
|
|
115
|
+
for (const session of group) removeBrowserSession(repoRoot, session.sessionId);
|
|
116
|
+
prunedCount += group.length;
|
|
117
|
+
}
|
|
118
|
+
for (const session of group) items.set(session.sessionId, { session, liveness: 'dead', evidence: 'native_tab_missing', pruned });
|
|
119
|
+
deadCount += group.length;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
85
122
|
if (!nativeTabInventoryUnsupported(inventory)) {
|
|
86
123
|
for (const session of group) items.set(session.sessionId, { session, liveness: 'unverified', evidence: 'native_inventory_unavailable', cleanupError: inventory.message });
|
|
87
124
|
unverifiedCount += group.length;
|
|
@@ -89,9 +126,9 @@ export async function inspectNativeOwnedSessions(input: {
|
|
|
89
126
|
}
|
|
90
127
|
|
|
91
128
|
const ref = { windowId: tab.windowId!, tabId: tab.tabId! };
|
|
92
|
-
let metadata: Awaited<ReturnType<typeof
|
|
129
|
+
let metadata: Awaited<ReturnType<typeof readResolvedMacOsBrowserOwnedTabMetadata>>;
|
|
93
130
|
try {
|
|
94
|
-
metadata = await
|
|
131
|
+
metadata = await readResolvedMacOsBrowserOwnedTabMetadata(product, ref, timeoutMs);
|
|
95
132
|
} catch (metadataError) {
|
|
96
133
|
if (macOsBrowserPageHandleStale(metadataError)) {
|
|
97
134
|
const pruned = input.pruneDead === true;
|
|
@@ -113,7 +150,7 @@ export async function inspectNativeOwnedSessions(input: {
|
|
|
113
150
|
deadCount += group.length;
|
|
114
151
|
if (input.pruneDead === true) {
|
|
115
152
|
try {
|
|
116
|
-
await
|
|
153
|
+
await closeResolvedMacOsBrowserOwnedTab(product, ref, timeoutMs);
|
|
117
154
|
for (const session of group) removeBrowserSession(repoRoot, session.sessionId);
|
|
118
155
|
prunedCount += group.length;
|
|
119
156
|
closedInvalidCount += 1;
|
|
@@ -134,7 +171,7 @@ export async function inspectNativeOwnedSessions(input: {
|
|
|
134
171
|
}
|
|
135
172
|
|
|
136
173
|
const live = inventory.tabs.find((entry) => entry.windowId === tab.windowId && entry.tabId === tab.tabId);
|
|
137
|
-
if (!live) {
|
|
174
|
+
if (!live || !nativeTabMatchesSessionUrl(canonical, live.url)) {
|
|
138
175
|
const pruned = input.pruneDead === true;
|
|
139
176
|
if (pruned) {
|
|
140
177
|
for (const session of group) removeBrowserSession(repoRoot, session.sessionId);
|
|
@@ -149,7 +186,11 @@ export async function inspectNativeOwnedSessions(input: {
|
|
|
149
186
|
deadCount += group.length;
|
|
150
187
|
if (input.pruneDead === true) {
|
|
151
188
|
try {
|
|
152
|
-
await
|
|
189
|
+
await closeResolvedMacOsBrowserOwnedTab(
|
|
190
|
+
product,
|
|
191
|
+
{ windowId: live.windowId, tabId: live.tabId },
|
|
192
|
+
timeoutMs,
|
|
193
|
+
);
|
|
153
194
|
for (const session of group) removeBrowserSession(repoRoot, session.sessionId);
|
|
154
195
|
prunedCount += group.length;
|
|
155
196
|
closedInvalidCount += 1;
|
|
@@ -189,20 +230,29 @@ export async function closeTrackedNativeOwnedSession(
|
|
|
189
230
|
const ref = { windowId: tab.windowId, tabId: tab.tabId };
|
|
190
231
|
let inventory: Awaited<ReturnType<typeof listMacOsBrowserTabs>> | undefined;
|
|
191
232
|
try {
|
|
192
|
-
inventory = await listMacOsBrowserTabs(browser.browserProduct, timeoutMs);
|
|
233
|
+
inventory = await listMacOsBrowserTabs(browser.browserProduct, nativeInventoryTimeoutMs(timeoutMs));
|
|
193
234
|
} catch (error) {
|
|
235
|
+
if (nativeBrowserApplicationNotRunning(error)) return { resourceClosed: false, resourceAlreadyMissing: true };
|
|
194
236
|
if (!nativeTabInventoryUnsupported(error)) throw error;
|
|
195
237
|
try {
|
|
196
|
-
await
|
|
238
|
+
await readResolvedMacOsBrowserOwnedTabMetadata(browser.browserProduct, ref, timeoutMs);
|
|
197
239
|
} catch (metadataError) {
|
|
198
240
|
if (macOsBrowserPageHandleStale(metadataError)) return { resourceClosed: false, resourceAlreadyMissing: true };
|
|
199
241
|
throw metadataError;
|
|
200
242
|
}
|
|
201
243
|
}
|
|
202
|
-
if (inventory
|
|
203
|
-
|
|
244
|
+
if (inventory) {
|
|
245
|
+
const live = inventory.tabs.find((entry) => entry.windowId === tab.windowId && entry.tabId === tab.tabId);
|
|
246
|
+
if (!live) return { resourceClosed: false, resourceAlreadyMissing: true };
|
|
247
|
+
if (!nativeTabMatchesSessionUrl(session, live.url)) return { resourceClosed: false, resourceAlreadyMissing: true };
|
|
248
|
+
await closeResolvedMacOsBrowserOwnedTab(
|
|
249
|
+
browser.browserProduct,
|
|
250
|
+
{ windowId: live.windowId, tabId: live.tabId },
|
|
251
|
+
timeoutMs,
|
|
252
|
+
);
|
|
253
|
+
return { resourceClosed: true, resourceAlreadyMissing: false };
|
|
204
254
|
}
|
|
205
|
-
await
|
|
255
|
+
await closeResolvedMacOsBrowserOwnedTab(browser.browserProduct, ref, timeoutMs);
|
|
206
256
|
return { resourceClosed: true, resourceAlreadyMissing: false };
|
|
207
257
|
}
|
|
208
258
|
|
|
@@ -5,6 +5,19 @@ import {
|
|
|
5
5
|
} from './browser-adapter';
|
|
6
6
|
import type { AssistantPluginAdapter } from './types';
|
|
7
7
|
|
|
8
|
+
/** Browser manifests derive from config plus saved-session and active-handoff authority. */
|
|
9
|
+
const BROWSER_MANIFEST_MUTATING_ACTIONS = new Set([
|
|
10
|
+
'configure',
|
|
11
|
+
'reconcile_sessions',
|
|
12
|
+
'close_session',
|
|
13
|
+
'close_page',
|
|
14
|
+
'clear_session',
|
|
15
|
+
'request_human_handoff',
|
|
16
|
+
'resolve_handoff',
|
|
17
|
+
'create_session',
|
|
18
|
+
'open_page',
|
|
19
|
+
]);
|
|
20
|
+
|
|
8
21
|
/** Thin first-party registration. Browser execution remains an adapter implementation detail. */
|
|
9
22
|
export const browserPluginAdapter: AssistantPluginAdapter = {
|
|
10
23
|
pluginId: 'browser',
|
|
@@ -13,4 +26,7 @@ export const browserPluginAdapter: AssistantPluginAdapter = {
|
|
|
13
26
|
buildManifest: buildBrowserPluginManifest,
|
|
14
27
|
executeAction: executeBrowserPluginAction,
|
|
15
28
|
resolveAuthorizationContext: resolveBrowserPluginAuthorizationContext,
|
|
29
|
+
shouldRefreshManifestAfterAction(actionId) {
|
|
30
|
+
return BROWSER_MANIFEST_MUTATING_ACTIONS.has(actionId);
|
|
31
|
+
},
|
|
16
32
|
};
|
|
@@ -56,6 +56,8 @@ const READ_ACTIONS = new Set([
|
|
|
56
56
|
'wait_for_load_state', 'wait_for_selector', 'await_file_transfer',
|
|
57
57
|
]);
|
|
58
58
|
const SCREENSHOT_ACTIONS = new Set(['screenshot']);
|
|
59
|
+
const INTERNAL_RESOURCE_READ_ACTIONS = new Set(['list_unpacked_extensions']);
|
|
60
|
+
const INTERNAL_RESOURCE_MUTATION_ACTIONS = new Set(['install_unpacked_extension']);
|
|
59
61
|
const TRUSTED_INPUT_ACTIONS = new Set(['trusted_input', 'activate_page']);
|
|
60
62
|
const DOM_INTERACTION_ACTIONS = new Set([
|
|
61
63
|
'create_session', 'open_page', 'navigate', 'reload', 'go_back',
|
|
@@ -89,6 +91,12 @@ export function browserRuntimeActionPolicy(actionId: string): BrowserRuntimeActi
|
|
|
89
91
|
if (SCREENSHOT_ACTIONS.has(actionId)) {
|
|
90
92
|
return { requiredCapabilities: ['browser.screenshot', 'browser.transaction'], foreground: 'none', replaySafety: 'read_only' };
|
|
91
93
|
}
|
|
94
|
+
if (INTERNAL_RESOURCE_READ_ACTIONS.has(actionId)) {
|
|
95
|
+
return { requiredCapabilities: ['browser.internal_resources', 'browser.transaction'], foreground: 'none', replaySafety: 'read_only' };
|
|
96
|
+
}
|
|
97
|
+
if (INTERNAL_RESOURCE_MUTATION_ACTIONS.has(actionId)) {
|
|
98
|
+
return { requiredCapabilities: ['browser.internal_resources', 'browser.transaction'], foreground: 'none', replaySafety: 'non_idempotent' };
|
|
99
|
+
}
|
|
92
100
|
if (TRUSTED_INPUT_ACTIONS.has(actionId)) {
|
|
93
101
|
return {
|
|
94
102
|
requiredCapabilities: ['browser.trusted_input', 'browser.foreground', 'browser.transaction'],
|
|
@@ -125,6 +133,9 @@ function stringArgument(args: Record<string, unknown>, key: string): string | un
|
|
|
125
133
|
}
|
|
126
134
|
|
|
127
135
|
function stableTargetFor(input: AssistantPluginActionExecutionInput, providerId: string): BrowserTargetIdentity {
|
|
136
|
+
if (INTERNAL_RESOURCE_READ_ACTIONS.has(input.actionId) || INTERNAL_RESOURCE_MUTATION_ACTIONS.has(input.actionId)) {
|
|
137
|
+
return { providerId, resourceKind: 'browser_internal_resource', resourceId: 'unpacked-extensions', ownership: 'provider_owned' };
|
|
138
|
+
}
|
|
128
139
|
const sessionId = stringArgument(input.args, 'session_id');
|
|
129
140
|
const nativeProduct = stringArgument(input.args, 'native_browser_product');
|
|
130
141
|
const nativeWindowId = stringArgument(input.args, 'native_window_id');
|
|
@@ -166,7 +177,9 @@ function transactionFor(
|
|
|
166
177
|
foreground: policy.foreground,
|
|
167
178
|
replaySafety: policy.replaySafety,
|
|
168
179
|
action: {
|
|
169
|
-
kind:
|
|
180
|
+
kind: INTERNAL_RESOURCE_READ_ACTIONS.has(input.actionId) || INTERNAL_RESOURCE_MUTATION_ACTIONS.has(input.actionId)
|
|
181
|
+
? 'internal_resource'
|
|
182
|
+
: policy.replaySafety === 'read_only' ? 'read' : policy.foreground === 'explicit_required' ? 'trusted_input' : 'dom',
|
|
170
183
|
operation: input.actionId,
|
|
171
184
|
arguments: input.args,
|
|
172
185
|
},
|
|
@@ -39,8 +39,8 @@ export {
|
|
|
39
39
|
withRuntimeBrowserSessionExecutionContext as withBrowserSessionAuthorityContext,
|
|
40
40
|
} from '../root/browser-session-composition';
|
|
41
41
|
|
|
42
|
-
function withContext<T>(controllerHome: string, repoId: string, operation: () => T): T {
|
|
43
|
-
return withRuntimeBrowserSessionExecutionContext({ controllerHome, repoId }, operation);
|
|
42
|
+
function withContext<T>(controllerHome: string, repoId: string | undefined, operation: () => T): T {
|
|
43
|
+
return withRuntimeBrowserSessionExecutionContext({ controllerHome, ...(repoId?.trim() ? { repoId: repoId.trim() } : {}) }, operation);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export function ensureLegacyBrowserSessionsImported(controllerHome: string, repoId: string, repoRoot: string): number {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { cpSync, lstatSync, mkdirSync,
|
|
2
|
-
import {
|
|
1
|
+
import { cpSync, lstatSync, mkdirSync, readlinkSync, rmSync } from 'fs';
|
|
2
|
+
import { join, resolve } from 'path';
|
|
3
3
|
import type {
|
|
4
4
|
ComputerSurfaceProviderBinding,
|
|
5
5
|
ComputerSurfaceTarget,
|
|
@@ -12,13 +12,24 @@ import {
|
|
|
12
12
|
cleanupLegacyBrowserSessionJson,
|
|
13
13
|
readLegacyBrowserSessionMigrationEntries,
|
|
14
14
|
} from './browser-session-legacy-migration';
|
|
15
|
-
import { writeJsonAtomic } from '../shared/json-files';
|
|
16
15
|
import { AssistantPluginError } from './errors';
|
|
17
16
|
|
|
18
17
|
const BROWSER_STATE_ROOT = '.forge/browser';
|
|
19
18
|
const BROWSER_SESSION_COMPATIBILITY_NAMESPACE = 'browser.session.v1';
|
|
20
19
|
const BROWSER_SESSION_COMPUTER_MIGRATION_ID = 'browser-session-authority-v1-to-computer-surface-v1';
|
|
21
20
|
|
|
21
|
+
function requireBrowserSessionExecutionContext() {
|
|
22
|
+
const context = currentRuntimeBrowserSessionExecutionContext();
|
|
23
|
+
if (!context) {
|
|
24
|
+
throw new AssistantPluginError(
|
|
25
|
+
'PLUGIN_BROWSER_SESSION_CONTEXT_REQUIRED',
|
|
26
|
+
'Browser session identity is owned by the Computer target authority and requires an explicit Controller execution context.',
|
|
27
|
+
{ retryable: false },
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
return context;
|
|
31
|
+
}
|
|
32
|
+
|
|
22
33
|
function unique(values: readonly string[]): string[] {
|
|
23
34
|
return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
|
|
24
35
|
}
|
|
@@ -109,9 +120,9 @@ function surfaceInput(
|
|
|
109
120
|
* Browser actions never read or write Browser-owned durable session state.
|
|
110
121
|
*/
|
|
111
122
|
export function ensureBrowserSessionsMigratedToComputer(repoRoot: string): number {
|
|
112
|
-
const context =
|
|
113
|
-
if (!context) return 0;
|
|
123
|
+
const context = requireBrowserSessionExecutionContext();
|
|
114
124
|
const computer = runtimeComputerInteractionTargetAuthority();
|
|
125
|
+
if (!context.repoId) return 0;
|
|
115
126
|
if (computer.compatibilityMigrationMarker(context.controllerHome, BROWSER_SESSION_COMPUTER_MIGRATION_ID, context.repoId)) {
|
|
116
127
|
cleanupLegacyBrowserSessionJson(context.controllerHome, context.repoId, repoRoot);
|
|
117
128
|
return 0;
|
|
@@ -146,8 +157,10 @@ export function ensureBrowserSessionsMigratedToComputer(repoRoot: string): numbe
|
|
|
146
157
|
}
|
|
147
158
|
|
|
148
159
|
/** Move legacy provider files out of the repository and retire the old path after migration. */
|
|
149
|
-
export function ensureBrowserStateInControllerHome(controllerHome: string, repoId: string, repoRoot: string): string {
|
|
150
|
-
const targetRoot =
|
|
160
|
+
export function ensureBrowserStateInControllerHome(controllerHome: string, repoId: string | undefined, repoRoot: string): string {
|
|
161
|
+
const targetRoot = repoId
|
|
162
|
+
? join(controllerHome, 'repositories', repoId, 'browser')
|
|
163
|
+
: join(controllerHome, 'browser');
|
|
151
164
|
const compatibilityParent = join(repoRoot, '.forge');
|
|
152
165
|
const compatibilityRoot = join(compatibilityParent, 'browser');
|
|
153
166
|
mkdirSync(targetRoot, { recursive: true });
|
|
@@ -178,50 +191,25 @@ export function ensureBrowserStateInControllerHome(controllerHome: string, repoI
|
|
|
178
191
|
/**
|
|
179
192
|
* Browser semantic identity belongs to Computer SurfaceTarget authority. Provider
|
|
180
193
|
* working state (profiles, screenshots, downloads, diagnostics) remains
|
|
181
|
-
* repository-scoped under Controller Home.
|
|
182
|
-
*
|
|
194
|
+
* repository-scoped under Controller Home. Session identity has no standalone
|
|
195
|
+
* repository-local fallback; callers must supply Controller execution context.
|
|
183
196
|
*/
|
|
184
197
|
export function browserStateDir(
|
|
185
198
|
repoRoot: string,
|
|
186
199
|
name: 'sessions' | 'screenshots' | 'profiles' | 'downloads' | 'diagnostics',
|
|
187
200
|
): string {
|
|
188
201
|
const context = currentRuntimeBrowserSessionExecutionContext();
|
|
202
|
+
if (name === 'sessions') {
|
|
203
|
+
const sessionContext = context ?? requireBrowserSessionExecutionContext();
|
|
204
|
+
return join(ensureBrowserStateInControllerHome(sessionContext.controllerHome, sessionContext.repoId, repoRoot), name);
|
|
205
|
+
}
|
|
189
206
|
return context
|
|
190
207
|
? join(ensureBrowserStateInControllerHome(context.controllerHome, context.repoId, repoRoot), name)
|
|
191
208
|
: join(repoRoot, BROWSER_STATE_ROOT, name);
|
|
192
209
|
}
|
|
193
210
|
|
|
194
|
-
function sessionPath(repoRoot: string, sessionId: string): string {
|
|
195
|
-
return join(browserStateDir(repoRoot, 'sessions'), `${sessionId.replace(/[^a-zA-Z0-9_-]/g, '_')}.json`);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
function readLegacyBrowserSessionJson(path: string): BrowserSessionState | undefined {
|
|
199
|
-
let raw: string;
|
|
200
|
-
try {
|
|
201
|
-
raw = readFileSync(path, 'utf-8');
|
|
202
|
-
} catch (error) {
|
|
203
|
-
if ((error as NodeJS.ErrnoException)?.code === 'ENOENT') return undefined;
|
|
204
|
-
throw new AssistantPluginError('PLUGIN_BROWSER_SESSION_STATE_READ_FAILED', 'Saved browser session metadata could not be read.', {
|
|
205
|
-
retryable: true,
|
|
206
|
-
details: { fileName: basename(path), cause: error instanceof Error ? error.message : String(error) },
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
try {
|
|
210
|
-
return JSON.parse(raw) as BrowserSessionState;
|
|
211
|
-
} catch (error) {
|
|
212
|
-
throw new AssistantPluginError('PLUGIN_BROWSER_SESSION_STATE_CORRUPT', 'Saved browser session metadata is malformed; refusing to treat corrupt state as a missing session.', {
|
|
213
|
-
retryable: false,
|
|
214
|
-
details: { fileName: basename(path), cause: error instanceof Error ? error.message : String(error) },
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
211
|
export function saveBrowserSession(repoRoot: string, session: BrowserSessionState): BrowserSessionState {
|
|
220
|
-
const context =
|
|
221
|
-
if (!context) {
|
|
222
|
-
writeJsonAtomic(sessionPath(repoRoot, session.sessionId), session);
|
|
223
|
-
return session;
|
|
224
|
-
}
|
|
212
|
+
const context = requireBrowserSessionExecutionContext();
|
|
225
213
|
ensureBrowserSessionsMigratedToComputer(repoRoot);
|
|
226
214
|
const computer = runtimeComputerInteractionTargetAuthority();
|
|
227
215
|
const binding = surfaceProviderBinding(session);
|
|
@@ -235,7 +223,8 @@ export function saveBrowserSession(repoRoot: string, session: BrowserSessionStat
|
|
|
235
223
|
if (!existing) {
|
|
236
224
|
existing = computer.upsertSurface(context.controllerHome, surfaceInput(session, {
|
|
237
225
|
aliases: [session.sessionId],
|
|
238
|
-
repositoryIds: [context.repoId],
|
|
226
|
+
repositoryIds: context.repoId ? [context.repoId] : [],
|
|
227
|
+
visibility: context.repoId ? undefined : 'controller',
|
|
239
228
|
includeCompatibility: false,
|
|
240
229
|
reactivate: true,
|
|
241
230
|
})).target;
|
|
@@ -248,7 +237,8 @@ export function saveBrowserSession(repoRoot: string, session: BrowserSessionStat
|
|
|
248
237
|
if (normalized.browser?.sessionResume) normalized.browser.sessionResume.sessionId = canonicalSessionId;
|
|
249
238
|
const saved = computer.upsertSurface(context.controllerHome, surfaceInput(normalized, {
|
|
250
239
|
aliases: [session.sessionId, canonicalSessionId],
|
|
251
|
-
repositoryIds: [context.repoId],
|
|
240
|
+
repositoryIds: context.repoId ? [context.repoId] : [],
|
|
241
|
+
visibility: context.repoId ? undefined : 'controller',
|
|
252
242
|
reactivate: true,
|
|
253
243
|
}));
|
|
254
244
|
return browserSessionFromSurface(saved.target) ?? normalized;
|
|
@@ -256,49 +246,29 @@ export function saveBrowserSession(repoRoot: string, session: BrowserSessionStat
|
|
|
256
246
|
|
|
257
247
|
export function findBrowserSession(repoRoot: string, sessionId?: string): BrowserSessionState | undefined {
|
|
258
248
|
if (!sessionId) return undefined;
|
|
259
|
-
const context =
|
|
260
|
-
if (!context) return readLegacyBrowserSessionJson(sessionPath(repoRoot, sessionId));
|
|
249
|
+
const context = requireBrowserSessionExecutionContext();
|
|
261
250
|
ensureBrowserSessionsMigratedToComputer(repoRoot);
|
|
262
251
|
const target = runtimeComputerInteractionTargetAuthority().findSurfaceByAlias(context.controllerHome, sessionId, context.repoId);
|
|
263
|
-
|
|
252
|
+
if (!target || (!context.repoId && target.visibility !== 'controller')) return undefined;
|
|
253
|
+
return browserSessionFromSurface(target);
|
|
264
254
|
}
|
|
265
255
|
|
|
266
256
|
export function listSavedBrowserSessions(repoRoot: string): BrowserSessionState[] {
|
|
267
|
-
const context =
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
const root = browserStateDir(repoRoot, 'sessions');
|
|
276
|
-
let names: string[];
|
|
277
|
-
try {
|
|
278
|
-
names = readdirSync(root);
|
|
279
|
-
} catch (error) {
|
|
280
|
-
if ((error as NodeJS.ErrnoException)?.code === 'ENOENT') return [];
|
|
281
|
-
throw new AssistantPluginError('PLUGIN_BROWSER_SESSION_STATE_READ_FAILED', 'Saved browser session directory could not be read.', {
|
|
282
|
-
retryable: true,
|
|
283
|
-
details: { cause: error instanceof Error ? error.message : String(error) },
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
return names
|
|
287
|
-
.filter((name) => name.endsWith('.json'))
|
|
288
|
-
.map((name) => readLegacyBrowserSessionJson(join(root, name)))
|
|
289
|
-
.filter((session): session is BrowserSessionState => Boolean(session));
|
|
257
|
+
const context = requireBrowserSessionExecutionContext();
|
|
258
|
+
ensureBrowserSessionsMigratedToComputer(repoRoot);
|
|
259
|
+
return runtimeComputerInteractionTargetAuthority().listAllSurfaces(context.controllerHome, { repoId: context.repoId })
|
|
260
|
+
.filter((target) => Boolean(context.repoId) || target.visibility === 'controller')
|
|
261
|
+
.map(browserSessionFromSurface)
|
|
262
|
+
.filter((session): session is BrowserSessionState => Boolean(session))
|
|
263
|
+
.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt) || left.sessionId.localeCompare(right.sessionId));
|
|
290
264
|
}
|
|
291
265
|
|
|
292
266
|
export function removeBrowserSession(repoRoot: string, sessionId: string): void {
|
|
293
|
-
const context =
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
if (target) computer.tombstoneSurface(context.controllerHome, target.targetId);
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
rmSync(sessionPath(repoRoot, sessionId), { force: true });
|
|
267
|
+
const context = requireBrowserSessionExecutionContext();
|
|
268
|
+
ensureBrowserSessionsMigratedToComputer(repoRoot);
|
|
269
|
+
const computer = runtimeComputerInteractionTargetAuthority();
|
|
270
|
+
const target = computer.findSurfaceByAlias(context.controllerHome, sessionId, context.repoId);
|
|
271
|
+
if (target && (context.repoId || target.visibility === 'controller')) computer.tombstoneSurface(context.controllerHome, target.targetId);
|
|
302
272
|
}
|
|
303
273
|
|
|
304
274
|
export function loadBrowserSession(repoRoot: string, sessionId?: string): BrowserSessionState | undefined {
|