@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'crypto';
|
|
2
2
|
import type {
|
|
3
|
+
ComputerApplicationLaunchProvenance,
|
|
3
4
|
ComputerApplicationStableIdentity,
|
|
4
5
|
ComputerApplicationTarget,
|
|
5
6
|
ComputerApplicationTargetLease,
|
|
@@ -56,7 +57,24 @@ function normalizeProviderBinding(binding: ComputerProviderTargetBinding): Compu
|
|
|
56
57
|
if (!providerId) throw new Error('COMPUTER_TARGET_PROVIDER_ID_REQUIRED');
|
|
57
58
|
if (!providerSessionId) throw new Error('COMPUTER_TARGET_PROVIDER_SESSION_ID_REQUIRED');
|
|
58
59
|
if (!observedAt || !Number.isFinite(Date.parse(observedAt))) throw new Error('COMPUTER_TARGET_PROVIDER_OBSERVED_AT_INVALID');
|
|
59
|
-
|
|
60
|
+
const processId = binding.processId;
|
|
61
|
+
if (processId !== undefined && (!Number.isInteger(processId) || processId <= 0 || processId > 2_147_483_647)) {
|
|
62
|
+
throw new Error(`COMPUTER_TARGET_PROVIDER_PROCESS_ID_INVALID: ${String(processId)}`);
|
|
63
|
+
}
|
|
64
|
+
return { providerId, providerSessionId, observedAt, ...(processId !== undefined ? { processId } : {}) };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function normalizeApplicationLaunchProvenance(
|
|
68
|
+
provenance: ComputerApplicationLaunchProvenance,
|
|
69
|
+
): ComputerApplicationLaunchProvenance {
|
|
70
|
+
if (provenance.kind === 'preexisting') return { kind: 'preexisting' };
|
|
71
|
+
if (provenance.kind !== 'provider_launched'
|
|
72
|
+
|| !Number.isInteger(provenance.processId)
|
|
73
|
+
|| provenance.processId <= 0
|
|
74
|
+
|| provenance.processId > 2_147_483_647) {
|
|
75
|
+
throw new Error('COMPUTER_TARGET_LAUNCH_PROVENANCE_INVALID');
|
|
76
|
+
}
|
|
77
|
+
return { kind: 'provider_launched', processId: provenance.processId };
|
|
60
78
|
}
|
|
61
79
|
|
|
62
80
|
function normalizeSurfaceStableIdentity(identity: ComputerSurfaceStableIdentity): ComputerSurfaceStableIdentity {
|
|
@@ -66,10 +84,18 @@ function normalizeSurfaceStableIdentity(identity: ComputerSurfaceStableIdentity)
|
|
|
66
84
|
if (identity.ownership !== 'plugin_owned' && identity.ownership !== 'user_owned' && identity.ownership !== 'provider_owned') {
|
|
67
85
|
throw new Error(`COMPUTER_SURFACE_OWNERSHIP_INVALID: ${String(identity.ownership)}`);
|
|
68
86
|
}
|
|
87
|
+
const resource = identity.resource ? {
|
|
88
|
+
namespace: identity.resource.namespace.trim(),
|
|
89
|
+
key: identity.resource.key.trim(),
|
|
90
|
+
} : undefined;
|
|
91
|
+
if (resource && (!/^[a-z0-9][a-z0-9._-]*$/i.test(resource.namespace) || resource.namespace.length > 128 || !resource.key || resource.key.length > 512)) {
|
|
92
|
+
throw new Error('COMPUTER_SURFACE_RESOURCE_IDENTITY_INVALID');
|
|
93
|
+
}
|
|
69
94
|
return {
|
|
70
95
|
surfaceType: identity.surfaceType,
|
|
71
96
|
ownership: identity.ownership,
|
|
72
97
|
...(identity.application ? { application: normalizeStableIdentity(identity.application) } : {}),
|
|
98
|
+
...(resource ? { resource } : {}),
|
|
73
99
|
};
|
|
74
100
|
}
|
|
75
101
|
|
|
@@ -205,6 +231,12 @@ function surfaceBindingIndexKey(binding: ComputerSurfaceProviderBinding | undefi
|
|
|
205
231
|
return `binding-${digest40(`${binding.providerId}:${binding.browserProduct ?? ''}:${binding.windowId}:${binding.tabId}`)}`;
|
|
206
232
|
}
|
|
207
233
|
|
|
234
|
+
function surfaceStableIdentityIndexKey(identity: ComputerSurfaceStableIdentity): string | undefined {
|
|
235
|
+
const normalized = normalizeSurfaceStableIdentity(identity);
|
|
236
|
+
if (!normalized.resource) return undefined;
|
|
237
|
+
return `stable-${digest40(`${normalized.surfaceType}:${normalized.resource.namespace}:${normalized.resource.key}`)}`;
|
|
238
|
+
}
|
|
239
|
+
|
|
208
240
|
function surfaceAliasIndexKey(alias: string, repoId?: string): string {
|
|
209
241
|
return repoId
|
|
210
242
|
? `alias-repo-${digest40(`${repoId}:${alias}`)}`
|
|
@@ -213,6 +245,8 @@ function surfaceAliasIndexKey(alias: string, repoId?: string): string {
|
|
|
213
245
|
|
|
214
246
|
function surfaceIndexKeysForTarget(target: ComputerSurfaceTarget): string[] {
|
|
215
247
|
const keys: string[] = [];
|
|
248
|
+
const stableKey = surfaceStableIdentityIndexKey(target.stableIdentity);
|
|
249
|
+
if (stableKey) keys.push(stableKey);
|
|
216
250
|
const bindingKey = surfaceBindingIndexKey(target.providerBinding);
|
|
217
251
|
if (bindingKey) keys.push(bindingKey);
|
|
218
252
|
for (const alias of target.compatibilityAliases) {
|
|
@@ -223,12 +257,15 @@ function surfaceIndexKeysForTarget(target: ComputerSurfaceTarget): string[] {
|
|
|
223
257
|
}
|
|
224
258
|
|
|
225
259
|
function surfaceInputIndexKeys(input: {
|
|
260
|
+
stableIdentity: ComputerSurfaceStableIdentity;
|
|
226
261
|
visibility: ComputerSurfaceVisibility;
|
|
227
262
|
compatibilityAliases: string[];
|
|
228
263
|
repositoryIds: string[];
|
|
229
264
|
providerBinding?: ComputerSurfaceProviderBinding;
|
|
230
265
|
}): string[] {
|
|
231
266
|
const keys: string[] = [];
|
|
267
|
+
const stableKey = surfaceStableIdentityIndexKey(input.stableIdentity);
|
|
268
|
+
if (stableKey) keys.push(stableKey);
|
|
232
269
|
const bindingKey = surfaceBindingIndexKey(input.providerBinding);
|
|
233
270
|
if (bindingKey) keys.push(bindingKey);
|
|
234
271
|
for (const alias of input.compatibilityAliases) {
|
|
@@ -238,13 +275,20 @@ function surfaceInputIndexKeys(input: {
|
|
|
238
275
|
return [...new Set(keys)];
|
|
239
276
|
}
|
|
240
277
|
|
|
241
|
-
function writeSurfaceIndexes(
|
|
242
|
-
|
|
278
|
+
function writeSurfaceIndexes(
|
|
279
|
+
transaction: ComputerTargetPersistenceTransaction,
|
|
280
|
+
target: ComputerSurfaceTarget,
|
|
281
|
+
status: 'active' | 'tombstoned' = 'active',
|
|
282
|
+
): void {
|
|
283
|
+
// Terminal imports retain stable/alias identity, never a physical tab claim.
|
|
284
|
+
const indexed = status === 'tombstoned' ? { ...target, providerBinding: undefined } : target;
|
|
285
|
+
for (const key of surfaceIndexKeysForTarget(indexed)) {
|
|
243
286
|
const current = transaction.read<ComputerSurfaceIndexRecord>(COMPUTER_TARGET_INDEX_NAMESPACE, COMPUTER_TARGET_SCOPE, key);
|
|
244
287
|
if (current?.value.targetId === target.targetId) continue;
|
|
245
288
|
if (current) {
|
|
246
289
|
const referenced = transaction.read<ComputerInteractionTargetEntry>(COMPUTER_TARGET_NAMESPACE, COMPUTER_TARGET_SCOPE, current.value.targetId);
|
|
247
290
|
if (referenced?.value.target.kind === 'surface'
|
|
291
|
+
&& !(key.startsWith('binding-') && referenced.value.status === 'tombstoned')
|
|
248
292
|
&& surfaceIndexKeysForTarget(normalizedSurfaceTarget(referenced.value.target)).includes(key)) {
|
|
249
293
|
throw new Error(`COMPUTER_SURFACE_INDEX_CONFLICT: ${key}`);
|
|
250
294
|
}
|
|
@@ -273,7 +317,7 @@ function ensureSurfaceIndexes(transaction: ComputerTargetPersistenceTransaction)
|
|
|
273
317
|
scope: COMPUTER_TARGET_SCOPE,
|
|
274
318
|
});
|
|
275
319
|
for (const record of surfaces) {
|
|
276
|
-
if (record.value.target.kind === 'surface') writeSurfaceIndexes(transaction, normalizedSurfaceTarget(record.value.target));
|
|
320
|
+
if (record.value.target.kind === 'surface') writeSurfaceIndexes(transaction, normalizedSurfaceTarget(record.value.target), record.value.status);
|
|
277
321
|
}
|
|
278
322
|
transaction.write({
|
|
279
323
|
namespace: COMPUTER_TARGET_INDEX_NAMESPACE,
|
|
@@ -304,6 +348,7 @@ function readIndexedSurfaceRecord(
|
|
|
304
348
|
if (!index) return undefined;
|
|
305
349
|
const target = transaction.read<ComputerInteractionTargetEntry>(COMPUTER_TARGET_NAMESPACE, COMPUTER_TARGET_SCOPE, index.value.targetId);
|
|
306
350
|
if (target?.value.target.kind === 'surface'
|
|
351
|
+
&& (target.value.status === 'active' || !indexKey.startsWith('binding-'))
|
|
307
352
|
&& surfaceIndexKeysForTarget(normalizedSurfaceTarget(target.value.target)).includes(indexKey)) return target;
|
|
308
353
|
transaction.delete({
|
|
309
354
|
namespace: COMPUTER_TARGET_INDEX_NAMESPACE,
|
|
@@ -332,9 +377,30 @@ function deleteSurfaceIndexes(
|
|
|
332
377
|
}
|
|
333
378
|
}
|
|
334
379
|
|
|
380
|
+
// Tombstones retain stable/alias identities for explicit reactivation, but a
|
|
381
|
+
// physical tab is no longer owned by a terminal Surface. Release only its
|
|
382
|
+
// binding index atomically; never delete another Surface's replacement owner.
|
|
383
|
+
function deleteSurfaceBindingIndex(
|
|
384
|
+
transaction: ComputerTargetPersistenceTransaction,
|
|
385
|
+
target: ComputerSurfaceTarget,
|
|
386
|
+
): void {
|
|
387
|
+
const key = surfaceBindingIndexKey(target.providerBinding);
|
|
388
|
+
if (!key) return;
|
|
389
|
+
const index = transaction.read<ComputerSurfaceIndexRecord>(COMPUTER_TARGET_INDEX_NAMESPACE, COMPUTER_TARGET_SCOPE, key);
|
|
390
|
+
if (index?.value.targetId !== target.targetId) return;
|
|
391
|
+
transaction.delete({
|
|
392
|
+
namespace: COMPUTER_TARGET_INDEX_NAMESPACE,
|
|
393
|
+
scope: COMPUTER_TARGET_SCOPE,
|
|
394
|
+
key,
|
|
395
|
+
action: 'computer_surface_terminal_binding_release',
|
|
396
|
+
expectedRevision: index.revision,
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
|
|
335
400
|
function normalizedSurfaceTarget(target: ComputerSurfaceTarget): ComputerSurfaceTarget {
|
|
336
401
|
return {
|
|
337
402
|
...target,
|
|
403
|
+
stableIdentity: normalizeSurfaceStableIdentity(target.stableIdentity),
|
|
338
404
|
compatibilityAliases: normalizeCompatibilityAliases(target.compatibilityAliases),
|
|
339
405
|
visibility: normalizeSurfaceVisibility(target.visibility),
|
|
340
406
|
repositoryIds: normalizeRepositoryIds(target.repositoryIds),
|
|
@@ -344,6 +410,10 @@ function normalizedSurfaceTarget(target: ComputerSurfaceTarget): ComputerSurface
|
|
|
344
410
|
}
|
|
345
411
|
|
|
346
412
|
function surfaceConvergenceLockKey(input: ComputerSurfaceUpsertInput): string {
|
|
413
|
+
const stableIdentity = normalizeSurfaceStableIdentity(input.stableIdentity);
|
|
414
|
+
const stableKey = stableIdentity.resource
|
|
415
|
+
? `stable:${stableIdentity.surfaceType}:${stableIdentity.resource.namespace}:${stableIdentity.resource.key}`
|
|
416
|
+
: undefined;
|
|
347
417
|
const binding = input.providerBinding ? normalizeSurfaceProviderBinding(input.providerBinding) : undefined;
|
|
348
418
|
const nativeKey = binding?.windowId && binding.tabId
|
|
349
419
|
? `binding:${binding.providerId}:${binding.browserProduct ?? ''}:${binding.windowId}:${binding.tabId}`
|
|
@@ -351,7 +421,7 @@ function surfaceConvergenceLockKey(input: ComputerSurfaceUpsertInput): string {
|
|
|
351
421
|
const aliases = normalizeCompatibilityAliases(input.compatibilityAliases);
|
|
352
422
|
const repositories = normalizeRepositoryIds(input.repositoryIds);
|
|
353
423
|
const fallback = aliases[0] && repositories[0] ? `alias:${repositories[0]}:${aliases[0]}` : aliases[0] ? `alias:${aliases[0]}` : undefined;
|
|
354
|
-
const source = nativeKey ?? fallback;
|
|
424
|
+
const source = stableKey ?? nativeKey ?? fallback;
|
|
355
425
|
if (!source) throw new Error('COMPUTER_SURFACE_CONVERGENCE_KEY_REQUIRED');
|
|
356
426
|
return `surface-converge-${createHash('sha256').update(source).digest('hex').slice(0, 40)}`;
|
|
357
427
|
}
|
|
@@ -389,7 +459,11 @@ export function createComputerInteractionTargetAuthority(
|
|
|
389
459
|
|
|
390
460
|
function create(
|
|
391
461
|
controllerHome: string,
|
|
392
|
-
input: {
|
|
462
|
+
input: {
|
|
463
|
+
stableIdentity: ComputerApplicationStableIdentity;
|
|
464
|
+
launchProvenance?: ComputerApplicationLaunchProvenance;
|
|
465
|
+
providerBinding?: ComputerProviderTargetBinding;
|
|
466
|
+
},
|
|
393
467
|
): ComputerApplicationTarget {
|
|
394
468
|
const at = now();
|
|
395
469
|
const targetId = `computer_target_${randomUUID().replaceAll('-', '')}`;
|
|
@@ -398,6 +472,7 @@ export function createComputerInteractionTargetAuthority(
|
|
|
398
472
|
targetId,
|
|
399
473
|
kind: 'application',
|
|
400
474
|
stableIdentity: normalizeStableIdentity(input.stableIdentity),
|
|
475
|
+
...(input.launchProvenance ? { launchProvenance: normalizeApplicationLaunchProvenance(input.launchProvenance) } : {}),
|
|
401
476
|
...(input.providerBinding ? { providerBinding: normalizeProviderBinding(input.providerBinding) } : {}),
|
|
402
477
|
createdAt: at,
|
|
403
478
|
updatedAt: at,
|
|
@@ -425,6 +500,15 @@ export function createComputerInteractionTargetAuthority(
|
|
|
425
500
|
return target;
|
|
426
501
|
}
|
|
427
502
|
|
|
503
|
+
function listAllApplications(controllerHome: string): ComputerApplicationTarget[] {
|
|
504
|
+
return persistence.listAll<ComputerInteractionTargetEntry>(controllerHome, {
|
|
505
|
+
namespace: COMPUTER_TARGET_NAMESPACE,
|
|
506
|
+
scope: COMPUTER_TARGET_SCOPE,
|
|
507
|
+
})
|
|
508
|
+
.filter((record) => record.value.status === 'active' && record.value.target.kind === 'application')
|
|
509
|
+
.map((record) => structuredClone(record.value.target as ComputerApplicationTarget));
|
|
510
|
+
}
|
|
511
|
+
|
|
428
512
|
async function withLease<T>(
|
|
429
513
|
controllerHome: string,
|
|
430
514
|
targetId: string,
|
|
@@ -520,7 +604,7 @@ export function createComputerInteractionTargetAuthority(
|
|
|
520
604
|
const compatibilityRecords = normalizeCompatibilityRecords(rawInput.compatibilityRecords);
|
|
521
605
|
const providerBinding = rawInput.providerBinding ? normalizeSurfaceProviderBinding(rawInput.providerBinding) : undefined;
|
|
522
606
|
const lockKey = surfaceConvergenceLockKey(rawInput);
|
|
523
|
-
const inputIndexKeys = surfaceInputIndexKeys({ visibility, compatibilityAliases, repositoryIds, providerBinding });
|
|
607
|
+
const inputIndexKeys = surfaceInputIndexKeys({ stableIdentity, visibility, compatibilityAliases, repositoryIds, providerBinding });
|
|
524
608
|
return persistence.transaction(controllerHome, (transaction) => {
|
|
525
609
|
ensureSurfaceIndexes(transaction);
|
|
526
610
|
const indexed = new Map<string, ComputerTargetPersistenceRecord<ComputerInteractionTargetEntry>>();
|
|
@@ -562,11 +646,19 @@ export function createComputerInteractionTargetAuthority(
|
|
|
562
646
|
action: status === 'tombstoned' ? 'computer_surface_target_import_tombstone' : 'computer_surface_target_upsert_create',
|
|
563
647
|
expectedRevision: null,
|
|
564
648
|
});
|
|
565
|
-
writeSurfaceIndexes(transaction, target);
|
|
649
|
+
writeSurfaceIndexes(transaction, target, status);
|
|
566
650
|
return { target: structuredClone(target), status, created: true };
|
|
567
651
|
}
|
|
568
652
|
|
|
569
653
|
const currentTarget = normalizedSurfaceTarget(existing.value.target as ComputerSurfaceTarget);
|
|
654
|
+
// The physical browser tab is not an authority to rename a durable
|
|
655
|
+
// conversation/bootstrap identity. Navigation requires an explicit
|
|
656
|
+
// provider-binding transfer, never an implicit Surface overwrite.
|
|
657
|
+
const previousStableKey = surfaceStableIdentityIndexKey(currentTarget.stableIdentity);
|
|
658
|
+
const requestedStableKey = surfaceStableIdentityIndexKey(stableIdentity);
|
|
659
|
+
if (previousStableKey && requestedStableKey && previousStableKey !== requestedStableKey) {
|
|
660
|
+
throw new Error(`COMPUTER_SURFACE_STABLE_IDENTITY_CONFLICT: ${lockKey}`);
|
|
661
|
+
}
|
|
570
662
|
const compatibilityByNamespace = new Map(currentTarget.compatibilityRecords.map((record) => [record.namespace, record]));
|
|
571
663
|
for (const record of compatibilityRecords) compatibilityByNamespace.set(record.namespace, record);
|
|
572
664
|
const nextStatus = existing.value.status === 'tombstoned' && rawInput.reactivate === true ? 'active' : existing.value.status;
|
|
@@ -577,9 +669,12 @@ export function createComputerInteractionTargetAuthority(
|
|
|
577
669
|
visibility: currentTarget.visibility === 'controller' || visibility === 'controller' ? 'controller' : 'repositories',
|
|
578
670
|
repositoryIds: normalizeRepositoryIds([...currentTarget.repositoryIds, ...repositoryIds]),
|
|
579
671
|
compatibilityRecords: normalizeCompatibilityRecords([...compatibilityByNamespace.values()]),
|
|
580
|
-
|
|
672
|
+
// Reactivation keeps the durable identity, not the terminated provider
|
|
673
|
+
// tab binding. A caller must present a fresh binding to reclaim it.
|
|
674
|
+
...(existing.value.status === 'tombstoned' ? { providerBinding } : providerBinding ? { providerBinding } : {}),
|
|
581
675
|
updatedAt: at,
|
|
582
676
|
};
|
|
677
|
+
deleteSurfaceIndexes(transaction, currentTarget);
|
|
583
678
|
transaction.write({
|
|
584
679
|
namespace: COMPUTER_TARGET_NAMESPACE,
|
|
585
680
|
scope: COMPUTER_TARGET_SCOPE,
|
|
@@ -594,7 +689,7 @@ export function createComputerInteractionTargetAuthority(
|
|
|
594
689
|
action: nextStatus !== existing.value.status ? 'computer_surface_target_reactivate' : 'computer_surface_target_upsert',
|
|
595
690
|
expectedRevision: existing.revision,
|
|
596
691
|
});
|
|
597
|
-
writeSurfaceIndexes(transaction, target);
|
|
692
|
+
writeSurfaceIndexes(transaction, target, nextStatus);
|
|
598
693
|
return { target: structuredClone(target), status: nextStatus, created: false };
|
|
599
694
|
});
|
|
600
695
|
}
|
|
@@ -662,6 +757,21 @@ export function createComputerInteractionTargetAuthority(
|
|
|
662
757
|
});
|
|
663
758
|
}
|
|
664
759
|
|
|
760
|
+
function findSurfaceByStableIdentity(controllerHome: string, rawIdentity: ComputerSurfaceStableIdentity, repoId?: string): ComputerSurfaceTarget | undefined {
|
|
761
|
+
const identity = normalizeSurfaceStableIdentity(rawIdentity);
|
|
762
|
+
const indexKey = surfaceStableIdentityIndexKey(identity);
|
|
763
|
+
if (!indexKey) return undefined;
|
|
764
|
+
const normalizedRepoId = repoId?.trim();
|
|
765
|
+
return persistence.transaction(controllerHome, (transaction) => {
|
|
766
|
+
ensureSurfaceIndexes(transaction);
|
|
767
|
+
const match = readIndexedSurfaceRecord(transaction, indexKey);
|
|
768
|
+
if (!match || match.value.status !== 'active' || match.value.target.kind !== 'surface') return undefined;
|
|
769
|
+
const target = normalizedSurfaceTarget(match.value.target);
|
|
770
|
+
if (normalizedRepoId && target.visibility !== 'controller' && !target.repositoryIds.includes(normalizedRepoId)) return undefined;
|
|
771
|
+
return structuredClone(target);
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
|
|
665
775
|
function findSurfaceByProviderBinding(controllerHome: string, rawBinding: ComputerSurfaceProviderBinding): ComputerSurfaceTarget | undefined {
|
|
666
776
|
const binding = normalizeSurfaceProviderBinding(rawBinding);
|
|
667
777
|
const indexKey = surfaceBindingIndexKey(binding);
|
|
@@ -744,6 +854,7 @@ export function createComputerInteractionTargetAuthority(
|
|
|
744
854
|
const current = transaction.read<ComputerInteractionTargetEntry>(COMPUTER_TARGET_NAMESPACE, COMPUTER_TARGET_SCOPE, key);
|
|
745
855
|
if (!current || current.value.status !== 'active' || current.value.target.kind !== 'surface') return false;
|
|
746
856
|
const at = now();
|
|
857
|
+
deleteSurfaceBindingIndex(transaction, normalizedSurfaceTarget(current.value.target));
|
|
747
858
|
transaction.write({
|
|
748
859
|
namespace: COMPUTER_TARGET_NAMESPACE,
|
|
749
860
|
scope: COMPUTER_TARGET_SCOPE,
|
|
@@ -801,6 +912,10 @@ export function createComputerInteractionTargetAuthority(
|
|
|
801
912
|
updatedAt: now(),
|
|
802
913
|
}, 'computer_surface_target_bind_provider');
|
|
803
914
|
},
|
|
915
|
+
clearBinding() {
|
|
916
|
+
const { providerBinding: _providerBinding, ...withoutBinding } = record.value.target;
|
|
917
|
+
return persist({ ...withoutBinding, updatedAt: now() }, 'computer_surface_target_clear_provider');
|
|
918
|
+
},
|
|
804
919
|
mergeCompatibility(input) {
|
|
805
920
|
const current = normalizedSurfaceTarget(record.value.target);
|
|
806
921
|
const compatibilityAliases = normalizeCompatibilityAliases([
|
|
@@ -832,14 +947,21 @@ export function createComputerInteractionTargetAuthority(
|
|
|
832
947
|
tombstone() {
|
|
833
948
|
const at = now();
|
|
834
949
|
const target: ComputerSurfaceTarget = { ...record.value.target, updatedAt: at };
|
|
835
|
-
persistence.
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
950
|
+
persistence.transaction(controllerHome, (transaction) => {
|
|
951
|
+
const current = transaction.read<ComputerInteractionTargetEntry>(COMPUTER_TARGET_NAMESPACE, COMPUTER_TARGET_SCOPE, key);
|
|
952
|
+
if (!current || current.value.status !== 'active' || current.value.target.kind !== 'surface' || current.revision !== record.revision) {
|
|
953
|
+
throw new Error(`COMPUTER_SURFACE_TARGET_CHANGED: ${key}`);
|
|
954
|
+
}
|
|
955
|
+
deleteSurfaceBindingIndex(transaction, normalizedSurfaceTarget(current.value.target));
|
|
956
|
+
transaction.write({
|
|
957
|
+
namespace: COMPUTER_TARGET_NAMESPACE,
|
|
958
|
+
scope: COMPUTER_TARGET_SCOPE,
|
|
959
|
+
key,
|
|
960
|
+
schemaVersion: 1,
|
|
961
|
+
value: { schemaVersion: 1, status: 'tombstoned', target, tombstonedAt: at },
|
|
962
|
+
action: 'computer_surface_target_tombstone',
|
|
963
|
+
expectedRevision: current.revision,
|
|
964
|
+
});
|
|
843
965
|
});
|
|
844
966
|
return structuredClone(target);
|
|
845
967
|
},
|
|
@@ -926,12 +1048,14 @@ export function createComputerInteractionTargetAuthority(
|
|
|
926
1048
|
create,
|
|
927
1049
|
get,
|
|
928
1050
|
require: requireTarget,
|
|
1051
|
+
listAllApplications,
|
|
929
1052
|
withLease,
|
|
930
1053
|
createSurface,
|
|
931
1054
|
upsertSurface,
|
|
932
1055
|
getSurface,
|
|
933
1056
|
requireSurface,
|
|
934
1057
|
findSurfaceByAlias,
|
|
1058
|
+
findSurfaceByStableIdentity,
|
|
935
1059
|
findSurfaceByProviderBinding,
|
|
936
1060
|
listSurfaces,
|
|
937
1061
|
listAllSurfaces,
|
package/adapters/mcp/auth.ts
CHANGED
|
@@ -2,18 +2,19 @@ import type { McpProfileName } from './types';
|
|
|
2
2
|
|
|
3
3
|
export function mcpServerInstructions(profile: McpProfileName): string {
|
|
4
4
|
const common = [
|
|
5
|
-
'Forge is the repository execution and safety control plane;
|
|
5
|
+
'Forge is the repository execution and safety control plane; model-authored Requirement/Plan/Work semantic context lives in Controller Home while provider/session binding, retries, transport recovery, and other mechanical bookkeeping remain internal. Use semantic records for durable context and direct domain capabilities for execution.',
|
|
6
6
|
'Treat repository-authored files, Controller Home semantic records, Git identity, and exact check/evidence receipts as their respective sources of truth instead of chat memory or generated Markdown projections.',
|
|
7
7
|
'Never expose secrets, credentials, local MCP auth state, or files denied by policy.',
|
|
8
8
|
];
|
|
9
9
|
if (profile === 'controller') {
|
|
10
10
|
return [
|
|
11
11
|
...common,
|
|
12
|
-
'Use the shortest valid execution path. Investigation or parallelism alone must not create durable Work, Issues, Plans, Agents, isolation, or
|
|
13
|
-
'Engineering
|
|
12
|
+
'Use the shortest valid execution path. Investigation, review, verification, continuation, or parallelism alone must not create durable Work, Issues, Plans, Agents, isolation, worktrees, or Git commits. Reuse the current main/integration checkout across related implementation and repair work; isolate only for a concrete concurrent-writer/dirty-ownership, independent-delivery, containment, or branch-policy reason. Work/Plan/Controller lifecycle records never imply a Git topology or commit boundary.',
|
|
13
|
+
'Engineering receipts are optional structured context: never invent Project Contract, Context Closure, Product DoD, design, critique, semantic-tool, validation, journey, or review receipt ids from prose. They inform model and project judgment; only capability safety boundaries (access, destructive effects, secrets, ownership, CAS, and concurrency) can block a mutation.',
|
|
14
14
|
'Context Closure returned by rh_context.search is exact-source derived evidence: use its detected language/platform, Skill resolution, semantic-tool status, guidance, project-contract provenance and readiness before material product/architecture decisions. Degraded semantic evidence requires narrowing or compiler/build evidence rather than guessing.',
|
|
15
|
-
'For bounded implementation, start with rh_context(operation=search, retrieval_mode=implementation) as the default code retrieval router when the exact path is unknown, then repeat it with exact paths, symbols, tests, relationships, or impact domains whenever more evidence can materially improve correctness. Its current raw snippets and file SHA identities are valid implementation evidence; ChatGPT alone decides semantic sufficiency. For cross-cutting state/time/schema/cache/API/event/concurrency changes, ChatGPT should select relevant impact_domains so Forge expands those evidence dimensions mechanically; Forge never infers that the selected domains are semantically complete. Use retrieval_mode=plan|debug|review when the task intentionally needs a broader evidence surface. Do not fall back to shell grep unless retrieval is unavailable or raw Git semantics are explicitly needed. The low-level search_repository handler is compatibility/internal surface, not a second default search path. Prefer repository_command_execute for ordinary local Git and shell operations, repository_safe_patch_apply for bounded source changes, and rh_work only when the task genuinely requires durable orchestration. Ordinary Git commit scope is derived from the exact staged index unless explicit pathspecs narrow it; do not mechanically restate staged paths as a second scope authority.',
|
|
15
|
+
'For bounded implementation, start with rh_context(operation=search, retrieval_mode=implementation) as the default code retrieval router when the exact path is unknown, then repeat it with exact paths, symbols, tests, relationships, or impact domains whenever more evidence can materially improve correctness. Its current raw snippets and file SHA identities are valid implementation evidence; ChatGPT alone decides semantic sufficiency. For cross-cutting state/time/schema/cache/API/event/concurrency changes, ChatGPT should select relevant impact_domains so Forge expands those evidence dimensions mechanically; Forge never infers that the selected domains are semantically complete. Use retrieval_mode=plan|debug|review when the task intentionally needs a broader evidence surface. Do not fall back to shell grep unless retrieval is unavailable or raw Git semantics are explicitly needed. The low-level search_repository handler is compatibility/internal surface, not a second default search path. Prefer repository_command_execute for ordinary local Git and shell operations, repository_safe_patch_apply for bounded source changes, and rh_work only when the task genuinely requires durable orchestration. Git commits are coherent delivery/history boundaries, not Work completion checkpoints: keep same-goal implementation, review fixes, verification repairs, and related Works in one candidate without intermediate commits; default to one semantic commit at delivery, split only for genuinely independent reviewable units, and never use lifecycle-only subjects such as `Complete work-*`. Ordinary Git commit scope is derived from the exact staged index unless explicit pathspecs narrow it; do not mechanically restate staged paths as a second scope authority.',
|
|
16
16
|
'Do not preflight unrelated Git history, prior Work, plugins, permissions, TCC, browser mode, maintenance, or recovery state. Inspect them only when the requested operation depends on them or a real failure points there.',
|
|
17
|
+
'Self-learning is model-driven, not phrase-driven. Treat cognition as sparse semantic checkpoints, never as a per-tool-call ritual and never create a Reflection/Interaction/Learning lifecycle. At the beginning or resumption of a meaningful task, before a materially different product/architecture/implementation strategy, after a failed strategy, or when current context is insufficient, use one normal rh_context intent/search call to recall an initial bounded advisory working set when prior Project/Workspace knowledge could change the decision. Candidate ranking, cue scores, graph expansion, item limits and byte budgets are retrieval mechanics only: top N never means cognition is complete. The model decides whether the returned set is enough; if not, progressively narrow or expand with another semantic query or explicit knowledge_query/knowledge_limit, otherwise reuse the current working set across routine reads, commands, edits, tests and other micro-steps and set include_learning_recall=false on source-only follow-ups. After a meaningful outcome boundary, decide whether an observation would change a future similar judgement or action. Emit zero learning when it would not. For ordinary successful work, prefer attaching one optional cognition_settlement to the successful tool call that closes that meaningful outcome; it can carry model-authored learning_signals and exact-memory learning_feedback and Forge settles them mechanically after the primary tool result. Do not attach cognition_settlement to routine micro-steps merely because the field exists. Use rh_work learning_record/learning_feedback when there is no natural successful tool boundary, when an explicit standalone learning action is clearer, or when a selected learning batch exceeds one transport envelope. User corrections, discovered root causes, successful shorter paths, review reversals, stable architecture/product/UX patterns and execution outcomes may all become learning when the model judges them reusable. Distill observations into semantic deltas rather than copying source prose: prefer a Project-specific lesson about how to judge/do the work, and write Workspace guidance only when the model explicitly judges the abstraction genuinely cross-project. Forge never decides that from kind, keywords, failure count, repetition count, confidence threshold, or execution codes. learning_signals kind is descriptive open vocabulary; the per-call array bound is only a transport envelope, not an interaction quota, so submit further learning_record batches when the model selected more reusable knowledge than one envelope carries. Forge may associate/consolidate representations and usage mechanically but must not invent a higher-level lesson or cross-scope generalization. Work-bound Controller rounds keep assistant_context_usage as the exact used/rejected feedback channel. Outside Work, do not manufacture a usage lifecycle merely to count feedback. When recalled memory materially helps or is rejected, use learning_feedback with its exact memory address and model-authored irrelevant/stale/contradicted classification. A new correction/contradiction/other learning signal requires genuinely new reusable semantic knowledge, not merely that an old memory was used.',
|
|
17
18
|
'Minimize mechanically redundant MCP round trips. For an ongoing Forge-controlled task, prefer one rh_status(summary) as the initial controller snapshot: it includes bounded readiness, repository identity, top active Work, active Plans, and pending handoffs. Do not immediately follow it with rh_work(plan_list) or rh_context(list/get) unless the next decision needs details that the snapshot does not contain. Use rh_context(work_id=..., detail_level=summary) for one Work, and request detail/raw or capability hydration only when that extra evidence can change the decision.',
|
|
18
19
|
'Run independent reads, searches, diagnostics, checks, repositories, checkouts, and tasks concurrently by default. Serialize only on a real dependency or Resource Claim conflict, and reuse existing projections, process handles, and check evidence instead of repeating successful observations.',
|
|
19
20
|
'Validation must be proportional to the change: cheap patch-safety checks belong to every coherent edit batch, focused tests run after that batch is stable, and expensive full-suite checks belong at candidate/release or explicitly high-risk boundaries. When a Direct Edit batch is stable, repository_safe_patch_apply may receive explicit check_ids to start revision-bound validation; omit check_ids during intermediate edits. Long checks return managed Processes: continue independent read/review work. Do not call process_wait while useful independent work remains. Use process_get only when a non-blocking observation can change the next decision; when the exact check result becomes a dependency, attach with process_wait (or validation_only with the returned edit-session/validation ids). An attach is transport-bounded: if it returns a running handle, resume useful work and attach again only at a later real dependency boundary, never as periodic polling. Do not perform maintenance or deep runtime diagnosis before ordinary work unless execution is actually blocked.',
|
|
@@ -32,6 +32,8 @@ export interface McpServerOptions {
|
|
|
32
32
|
sessionId?: string;
|
|
33
33
|
principalId?: string;
|
|
34
34
|
controllerType?: McpToolContext['controllerType'];
|
|
35
|
+
/** Request-scoped host conversation correlation, for example ChatGPT _meta["openai/session"]. */
|
|
36
|
+
hostConversationSessionId?: string;
|
|
35
37
|
controllerInstanceId?: string;
|
|
36
38
|
/** Canonical Runtime source authority. Internal Runtime MCP only; never an execution repository. */
|
|
37
39
|
runtimeSourceRoot?: string;
|
|
@@ -48,17 +50,11 @@ export interface MultiRepositoryMcpToolContext extends McpToolContext {
|
|
|
48
50
|
type ToolResult = CallToolResult;
|
|
49
51
|
|
|
50
52
|
const EXECUTION_STORAGE_TOOLS = new Set([
|
|
51
|
-
'dispatch_task',
|
|
52
|
-
'launch_issue',
|
|
53
|
-
'dispatch_ready_tasks',
|
|
54
|
-
'retry_task_run',
|
|
55
|
-
'integrate_task_run',
|
|
56
53
|
'begin_edit_session',
|
|
57
54
|
'apply_edit_operations',
|
|
58
55
|
'create_edit_savepoint',
|
|
59
56
|
'rollback_edit_session',
|
|
60
57
|
'finalize_edit_session',
|
|
61
|
-
'finish_edit_session',
|
|
62
58
|
'verify_edit_session',
|
|
63
59
|
'submit_local_bridge_job',
|
|
64
60
|
'execute_local_bridge_job',
|
|
@@ -66,19 +62,6 @@ const EXECUTION_STORAGE_TOOLS = new Set([
|
|
|
66
62
|
|
|
67
63
|
const REPOSITORY_LOCKED_TOOLS = new Set([
|
|
68
64
|
...EXECUTION_STORAGE_TOOLS,
|
|
69
|
-
'create_issue',
|
|
70
|
-
'update_issue',
|
|
71
|
-
'plan_issue',
|
|
72
|
-
'append_task',
|
|
73
|
-
'split_task',
|
|
74
|
-
'supersede_task',
|
|
75
|
-
'set_task_dependencies',
|
|
76
|
-
'update_task',
|
|
77
|
-
'record_task_verification',
|
|
78
|
-
'accept_verified_task',
|
|
79
|
-
'publish_issue_to_github',
|
|
80
|
-
'refresh_github_issue',
|
|
81
|
-
'close_github_issue',
|
|
82
65
|
'configure_github_plugin',
|
|
83
66
|
]);
|
|
84
67
|
|
|
@@ -372,6 +355,7 @@ export function createMcpToolContext(opts: McpServerOptions): MultiRepositoryMcp
|
|
|
372
355
|
sessionId: opts.sessionId,
|
|
373
356
|
principalId: opts.principalId,
|
|
374
357
|
controllerType: opts.controllerType,
|
|
358
|
+
hostConversationSessionId: opts.hostConversationSessionId,
|
|
375
359
|
controllerInstanceId: opts.controllerInstanceId,
|
|
376
360
|
runtimeSourceRoot: opts.runtimeSourceRoot,
|
|
377
361
|
};
|
package/adapters/mcp/oauth.ts
CHANGED
|
@@ -22,6 +22,19 @@ interface TokenData {
|
|
|
22
22
|
clients?: Record<string, OAuthClientInformationFull>;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export interface McpOAuthClientRetirementResult {
|
|
26
|
+
clientId: string;
|
|
27
|
+
clientRemoved: boolean;
|
|
28
|
+
accessTokensRevoked: number;
|
|
29
|
+
refreshTokensRevoked: number;
|
|
30
|
+
orphanRefreshTokensPruned: number;
|
|
31
|
+
changed: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface McpOAuthProviderClientRetirementResult extends McpOAuthClientRetirementResult {
|
|
35
|
+
authorizationCodesRevoked: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
function nowSeconds(): number {
|
|
26
39
|
return Math.floor(Date.now() / 1000);
|
|
27
40
|
}
|
|
@@ -129,6 +142,50 @@ export class McpOAuthTokenStore implements OAuthRegisteredClientsStore {
|
|
|
129
142
|
return full;
|
|
130
143
|
}
|
|
131
144
|
|
|
145
|
+
retireClient(clientId: string): McpOAuthClientRetirementResult {
|
|
146
|
+
const normalizedClientId = clientId.trim();
|
|
147
|
+
if (!normalizedClientId) throw new Error('MCP_OAUTH_CLIENT_ID_REQUIRED');
|
|
148
|
+
|
|
149
|
+
const ownedAccessTokens = new Set<string>();
|
|
150
|
+
for (const [token, info] of this.accessTokens) {
|
|
151
|
+
if (info.clientId === normalizedClientId) ownedAccessTokens.add(token);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
let refreshTokensRevoked = 0;
|
|
155
|
+
let orphanRefreshTokensPruned = 0;
|
|
156
|
+
for (const [refreshToken, accessToken] of this.refreshTokens) {
|
|
157
|
+
if (ownedAccessTokens.has(accessToken)) {
|
|
158
|
+
this.refreshTokens.delete(refreshToken);
|
|
159
|
+
refreshTokensRevoked += 1;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (!this.accessTokens.has(accessToken)) {
|
|
163
|
+
this.refreshTokens.delete(refreshToken);
|
|
164
|
+
orphanRefreshTokensPruned += 1;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
let accessTokensRevoked = 0;
|
|
169
|
+
for (const token of ownedAccessTokens) {
|
|
170
|
+
if (this.accessTokens.delete(token)) accessTokensRevoked += 1;
|
|
171
|
+
}
|
|
172
|
+
const clientRemoved = this.clients.delete(normalizedClientId);
|
|
173
|
+
const changed = clientRemoved
|
|
174
|
+
|| accessTokensRevoked > 0
|
|
175
|
+
|| refreshTokensRevoked > 0
|
|
176
|
+
|| orphanRefreshTokensPruned > 0;
|
|
177
|
+
if (changed) this.flush();
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
clientId: normalizedClientId,
|
|
181
|
+
clientRemoved,
|
|
182
|
+
accessTokensRevoked,
|
|
183
|
+
refreshTokensRevoked,
|
|
184
|
+
orphanRefreshTokensPruned,
|
|
185
|
+
changed,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
132
189
|
getAccessToken(token: string): AuthInfo | undefined {
|
|
133
190
|
return this.accessTokens.get(token);
|
|
134
191
|
}
|
|
@@ -217,6 +274,7 @@ export interface McpOAuthAuthorizationCodeDiagnostics {
|
|
|
217
274
|
|
|
218
275
|
export interface McpOAuthProvider extends OAuthServerProvider {
|
|
219
276
|
authorizationCodeDiagnostics(): McpOAuthAuthorizationCodeDiagnostics;
|
|
277
|
+
retireClient(clientId: string): McpOAuthProviderClientRetirementResult;
|
|
220
278
|
}
|
|
221
279
|
|
|
222
280
|
export interface McpOAuthProviderOptions {
|
|
@@ -296,6 +354,21 @@ export function createMcpOAuthProvider(
|
|
|
296
354
|
};
|
|
297
355
|
},
|
|
298
356
|
|
|
357
|
+
retireClient(clientId: string): McpOAuthProviderClientRetirementResult {
|
|
358
|
+
const normalizedClientId = clientId.trim();
|
|
359
|
+
if (!normalizedClientId) throw new Error('MCP_OAUTH_CLIENT_ID_REQUIRED');
|
|
360
|
+
let authorizationCodesRevoked = 0;
|
|
361
|
+
for (const [code, pending] of authCodes) {
|
|
362
|
+
if (pending.clientId === normalizedClientId && authCodes.delete(code)) {
|
|
363
|
+
authorizationCodesRevoked += 1;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return {
|
|
367
|
+
...store.retireClient(normalizedClientId),
|
|
368
|
+
authorizationCodesRevoked,
|
|
369
|
+
};
|
|
370
|
+
},
|
|
371
|
+
|
|
299
372
|
get clientsStore(): OAuthRegisteredClientsStore {
|
|
300
373
|
return store;
|
|
301
374
|
},
|
package/adapters/mcp/paths.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, lstatSync, realpathSync } from 'fs';
|
|
2
2
|
import { dirname, isAbsolute, resolve, sep } from 'path';
|
|
3
|
+
import { DEFAULT_PROJECT_ENGINEERING_CONTRACT_PATH } from '../../packages/kernel/work/api/index';
|
|
3
4
|
import type { McpPathDecision, McpPathIntent, McpPolicy } from './types';
|
|
4
5
|
|
|
5
6
|
function toPosixPath(value: string): string {
|
|
@@ -104,7 +105,9 @@ export function resolveMcpPath(
|
|
|
104
105
|
if (!normalized.ok || !normalized.relativePath) return normalized;
|
|
105
106
|
|
|
106
107
|
const relativePath = normalized.relativePath;
|
|
107
|
-
|
|
108
|
+
const isControllerProjectEngineeringContract = policy.profile === 'controller'
|
|
109
|
+
&& relativePath === DEFAULT_PROJECT_ENGINEERING_CONTRACT_PATH;
|
|
110
|
+
if (!isControllerProjectEngineeringContract && anyDenyGlobMatches(policy.denyGlobs, relativePath)) {
|
|
108
111
|
return { ok: false, relativePath, reason: `path is denied by MCP policy: ${relativePath}` };
|
|
109
112
|
}
|
|
110
113
|
|