@moretea-labs/forge 1.7.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +58 -62
- package/CHANGELOG.md +39 -0
- package/CLAUDE.md +42 -62
- package/README.md +2 -2
- package/SKILL.md +0 -1
- package/THIRD_PARTY_NOTICES.md +5 -2
- package/adapters/browser/index.ts +2 -0
- package/adapters/chatgpt/browser-delivery-host.ts +71 -0
- package/adapters/chatgpt/browser-delivery-runtime.ts +783 -0
- package/adapters/chatgpt/controller-binding-store.ts +55 -0
- package/adapters/chatgpt/controller-host.ts +119 -0
- package/adapters/chatgpt/controller-round-host.ts +78 -0
- package/adapters/chatgpt/controller-round-settlement-store.ts +45 -0
- package/adapters/chatgpt/provider-delivery.ts +113 -0
- package/adapters/chatgpt/work-conversation-binding-store.ts +192 -0
- package/adapters/chatgpt/wsl-bridge-delivery-host.ts +63 -0
- package/adapters/computer/desktop-operator-contract.ts +7 -0
- package/adapters/computer/desktop-operator-discovery.ts +201 -0
- package/adapters/computer/desktop-operator-negotiation.ts +174 -0
- package/adapters/computer/desktop-operator-provider.ts +312 -0
- package/adapters/computer/index.ts +1 -0
- package/adapters/computer/interaction-target-authority.ts +944 -0
- package/adapters/controller-process/binding-store.ts +34 -0
- package/adapters/controller-process/controller-host.ts +26 -0
- package/adapters/mcp/access-mode.ts +132 -0
- package/adapters/mcp/audit.ts +32 -0
- package/adapters/mcp/auth.ts +407 -0
- package/adapters/mcp/controller-round-compatibility.ts +184 -0
- package/adapters/mcp/frozen-client-semantic-compatibility.ts +292 -0
- package/adapters/mcp/instructions.ts +36 -0
- package/adapters/mcp/legacy-context.ts +18 -0
- package/adapters/mcp/multi-repository.ts +437 -0
- package/adapters/mcp/oauth.ts +391 -0
- package/adapters/mcp/paths.ts +140 -0
- package/adapters/mcp/policy.ts +232 -0
- package/adapters/mcp/proxy-env.ts +62 -0
- package/adapters/mcp/readiness-projection.ts +24 -0
- package/adapters/mcp/redaction.ts +21 -0
- package/adapters/mcp/repo.ts +24 -0
- package/adapters/mcp/runtime-gateway/artifact-adapter.ts +52 -0
- package/adapters/mcp/runtime-gateway/context-adapter.ts +829 -0
- package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +191 -0
- package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +147 -0
- package/adapters/mcp/runtime-gateway/execution-control-adapter.ts +28 -0
- package/adapters/mcp/runtime-gateway/execution-tools.ts +207 -0
- package/adapters/mcp/runtime-gateway/filesystem-adapter.ts +38 -0
- package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +411 -0
- package/adapters/mcp/runtime-gateway/legacy-ios-tool-adapter.ts +105 -0
- package/adapters/mcp/runtime-gateway/maintenance-adapter.ts +44 -0
- package/adapters/mcp/runtime-gateway/model-adapter.ts +63 -0
- package/adapters/mcp/runtime-gateway/persisted-check-process.ts +3 -0
- package/adapters/mcp/runtime-gateway/plugin-adapter.ts +308 -0
- package/adapters/mcp/runtime-gateway/process-tools.ts +289 -0
- package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +76 -0
- package/adapters/mcp/runtime-gateway/recovery-adapter.ts +268 -0
- package/adapters/mcp/runtime-gateway/recovery-client-adapter.ts +70 -0
- package/adapters/mcp/runtime-gateway/recovery-tool-contract.ts +99 -0
- package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +110 -0
- package/adapters/mcp/runtime-gateway/result-adapter.ts +108 -0
- package/adapters/mcp/runtime-gateway/router.ts +728 -0
- package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1251 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +634 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-shared.ts +27 -0
- package/adapters/mcp/runtime-gateway/runtime-tools.ts +68 -0
- package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +186 -0
- package/adapters/mcp/runtime-gateway/shared-adapter.ts +25 -0
- package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +870 -0
- package/adapters/mcp/runtime-gateway/work-adapter.ts +3186 -0
- package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +502 -0
- package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +1 -0
- package/adapters/mcp/server.ts +1048 -0
- package/adapters/mcp/setup.ts +791 -0
- package/adapters/mcp/tool-capability-cache.ts +87 -0
- package/adapters/mcp/tool-mapping/access-tools.ts +387 -0
- package/adapters/mcp/tool-mapping/legacy-tool-service.ts +5265 -0
- package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +150 -0
- package/adapters/mcp/tool-mapping/repository-tools.ts +1691 -0
- package/adapters/mcp/tool-mapping/tools.ts +9 -0
- package/adapters/mcp/tool-mapping/umbrella-tools.ts +117 -0
- package/adapters/mcp/toolset-names.ts +74 -0
- package/adapters/mcp/toolset-selection.ts +41 -0
- package/adapters/mcp/toolset.ts +336 -0
- package/adapters/mcp/transports/http.ts +1456 -0
- package/adapters/mcp/transports/session-registry.ts +513 -0
- package/adapters/mcp/transports/stdio.ts +8 -0
- package/adapters/mcp/tunnels/openai-secure-tunnel.ts +139 -0
- package/adapters/mcp/types.ts +41 -0
- package/assets/AGENTS.md +2 -16
- package/assets/CLAUDE.md +2 -16
- package/assets/hooks/AGENTS.md +3 -14
- package/assets/hooks/CLAUDE.md +3 -14
- package/assets/hooks/hook-input.sh +9 -2
- package/assets/hooks/lib/workflow-state.sh +28 -10
- package/assets/hooks/prompt-guard.sh +63 -37
- package/assets/hooks/security-sentinel.sh +2 -1
- package/assets/hooks/session-start-context.sh +7 -5
- package/assets/hooks/stop-orchestrator.sh +13 -3
- package/assets/initializer-question-pack.v4.json +11 -7
- package/assets/partials/05-workflow.partial.md +18 -73
- package/assets/partials/07-footer.partial.md +1 -1
- package/assets/partials-agents/02-operating-mode.partial.md +1 -2
- package/assets/partials-agents/04-task-protocol.partial.md +14 -59
- package/assets/partials-agents/06-quality-safety.partial.md +11 -16
- package/assets/partials-agents/08-deep-docs.partial.md +1 -2
- package/assets/plan-map.json +11 -11
- package/assets/plugin-registry.v1.json +9 -3
- package/assets/plugin-trust-policy.v1.json +6 -0
- package/assets/recovery/ForgeRecovery.ps1 +100 -0
- package/assets/recovery/forge-wsl-rescue +271 -0
- package/assets/reference-configs/development-protocol.md +11 -15
- package/assets/reference-configs/document-generation.md +1 -1
- package/assets/reference-configs/global-working-rules.md +9 -1
- package/assets/reference-configs/harness-overview.md +22 -112
- package/assets/reference-configs/hook-operations.md +1 -1
- package/assets/reference-configs/sprint-contracts.md +2 -2
- package/assets/skill-version.json +2 -2
- package/assets/templates/helpers/architecture-event.ts +3 -34
- package/assets/templates/helpers/architecture-queue.sh +61 -10
- package/assets/templates/helpers/archive-workflow.sh +90 -180
- package/assets/templates/helpers/capability-config.ts +8 -11
- package/assets/templates/helpers/capability-resolver.ts +37 -19
- package/assets/templates/helpers/capture-plan.sh +2 -2
- package/assets/templates/helpers/check-architecture-sync.sh +1 -9
- package/assets/templates/helpers/check-task-sync.sh +82 -11
- package/assets/templates/helpers/check-task-workflow.sh +1 -3
- package/assets/templates/helpers/context-contract-sync.sh +1 -12
- package/assets/templates/helpers/contract-worktree.sh +26 -24
- package/assets/templates/helpers/ensure-task-workflow.sh +6 -8
- package/assets/templates/helpers/inspect-project-state.ts +1 -1
- package/assets/templates/helpers/migrate-project-template.sh +1 -1
- package/assets/templates/helpers/migrate-workflow-docs.ts +53 -239
- package/assets/templates/helpers/new-plan.sh +2 -2
- package/assets/templates/helpers/plan-to-todo.sh +3 -31
- package/assets/templates/helpers/sprint-backlog.sh +1 -1
- package/assets/templates/helpers/switch-plan.sh +1 -1
- package/assets/templates/helpers/workflow-contract.ts +1 -0
- package/assets/workflow-contract.v1.json +63 -171
- package/assets/workflows/xiaohongshu/xiaohongshu.collect-metrics.v1.draft.json +118 -0
- package/assets/workflows/xiaohongshu/xiaohongshu.publish-image-note.v1.draft.json +316 -0
- package/assets/workflows/xiaohongshu/xiaohongshu.publish-long-text.v1.draft.json +324 -0
- package/docs/architecture/CURRENT.md +148 -13
- package/docs/architecture/EVOLUTION.md +13 -0
- package/docs/architecture/decisions/20260801-controller-home-sqlite-state.md +2 -1
- package/docs/architecture/decisions/20260831-independent-windows-wsl-host-rescue.md +59 -0
- package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +120 -0
- package/docs/architecture/decisions/20260904-repository-runtime-data-boundary.md +42 -0
- package/docs/architecture/decisions/20260907-assistant-learning-loop.md +35 -0
- package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +296 -0
- package/docs/architecture/decisions/20260907-maintenance-diagnosis-bounded-read.md +39 -0
- package/docs/architecture/domains/verification.md +7 -0
- package/docs/architecture/domains/workflow-engine.md +1 -1
- package/docs/architecture/index.md +3 -3
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +19 -8
- package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +124 -0
- package/docs/forge-chatgpt-mcp-setup.md +5 -3
- package/docs/forge-plugin-management.md +20 -4
- package/docs/forge-runtime-self-healing-loop.md +2 -0
- package/docs/operations/benchmark-cross-version-freeze.md +38 -0
- package/docs/operations/controller-browser-plugin.md +3 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/platform-support.md +16 -8
- package/docs/operations/platform-support.zh-CN.md +2 -2
- package/docs/operations/standalone-disaster-recovery.md +26 -1
- package/docs/operations/uu-remote-rescue.md +41 -0
- package/docs/operations/windows-wsl-host-rescue.md +133 -0
- package/docs/public-usage-guide.md +1 -1
- package/docs/public-usage-guide.zh-CN.md +1 -1
- package/docs/tutorials/01-install-and-start.md +1 -1
- package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
- package/docs/tutorials/02-connect-chatgpt.md +4 -4
- package/docs/tutorials/02-connect-chatgpt.zh-CN.md +4 -4
- package/docs/wiki/Implementation.md +1 -1
- package/package.json +23 -14
- package/packages/kernel/controller/api/index.ts +2 -0
- package/packages/kernel/controller/application/controller-round-service.ts +29 -0
- package/packages/kernel/controller/application/controller-service.ts +30 -0
- package/packages/kernel/controller/domain/controller-round-transition-policy.ts +308 -0
- package/packages/kernel/controller/domain/controller-round.ts +107 -0
- package/packages/kernel/controller/domain/execution-quality.ts +133 -0
- package/packages/kernel/controller/domain/types.ts +56 -0
- package/packages/kernel/controller/index.ts +1 -0
- package/packages/kernel/controller/infrastructure/controller-binding-store.ts +84 -0
- package/packages/kernel/controller/infrastructure/controller-round-store.ts +1384 -0
- package/packages/kernel/controller/infrastructure/controller-session-store.ts +578 -0
- package/packages/kernel/controller/ports/controller-host.ts +16 -0
- package/packages/kernel/goal/api/index.ts +1 -0
- package/packages/kernel/goal/domain/types.ts +40 -0
- package/packages/kernel/goal/index.ts +1 -0
- package/packages/kernel/identity/api/index.ts +5 -0
- package/packages/kernel/identity/application/identity-service.ts +67 -0
- package/packages/kernel/identity/domain/scope.ts +63 -0
- package/packages/kernel/identity/domain/semantic-sync.ts +81 -0
- package/packages/kernel/identity/domain/types.ts +44 -0
- package/packages/kernel/identity/domain/workspace.ts +56 -0
- package/packages/kernel/identity/index.ts +1 -0
- package/packages/kernel/identity/infrastructure/identity-store.ts +75 -0
- package/packages/kernel/memory/api/index.ts +5 -0
- package/packages/kernel/memory/application/experience-service.ts +118 -0
- package/packages/kernel/memory/application/outcome-service.ts +77 -0
- package/packages/kernel/memory/domain/experience.ts +103 -0
- package/packages/kernel/memory/domain/operational-prior.ts +92 -0
- package/packages/kernel/memory/index.ts +1 -0
- package/packages/kernel/progression/api/index.ts +2 -0
- package/packages/kernel/progression/application/projector.ts +211 -0
- package/packages/kernel/progression/domain/types.ts +116 -0
- package/packages/kernel/progression/index.ts +1 -0
- package/packages/kernel/scheduler/api/index.ts +6 -0
- package/packages/kernel/scheduler/application/continuation-service.ts +212 -0
- package/packages/kernel/scheduler/application/eligibility.ts +252 -0
- package/packages/kernel/scheduler/application/schedule-service.ts +24 -0
- package/packages/kernel/scheduler/application/settlement.ts +197 -0
- package/packages/kernel/scheduler/domain/continuation.ts +38 -0
- package/packages/kernel/scheduler/domain/schedule.ts +149 -0
- package/packages/kernel/scheduler/index.ts +1 -0
- package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +38 -0
- package/packages/kernel/scheduler/infrastructure/schedule-store.ts +785 -0
- package/packages/kernel/work/api/index.ts +15 -0
- package/packages/kernel/work/application/work-service.ts +148 -0
- package/packages/kernel/work/domain/admission-policy.ts +34 -0
- package/packages/kernel/work/domain/check-receipt.ts +43 -0
- package/packages/kernel/work/domain/context-closure-receipt.ts +32 -0
- package/packages/kernel/work/domain/engineering-contracts.ts +157 -0
- package/packages/kernel/work/domain/engineering-design.ts +281 -0
- package/packages/kernel/work/domain/engineering-profile.ts +242 -0
- package/packages/kernel/work/domain/execution-concurrency.ts +254 -0
- package/packages/kernel/work/domain/execution-snapshot.ts +33 -0
- package/packages/kernel/work/domain/implementation-review.ts +510 -0
- package/packages/kernel/work/domain/project-engineering-contract.ts +202 -0
- package/packages/kernel/work/domain/repository-completion-receipt.ts +73 -0
- package/packages/kernel/work/domain/state-machine.ts +259 -0
- package/packages/kernel/work/domain/types.ts +528 -0
- package/packages/kernel/work/index.ts +1 -0
- package/packages/kernel/work/infrastructure/work-contract-store.ts +1876 -0
- package/packages/kernel/work/ports/work-contract-store.ts +18 -0
- package/packages/plugin-runtime/browser/index.ts +3 -0
- package/packages/plugin-runtime/browser/provider-registry.ts +110 -0
- package/packages/plugin-runtime/browser/runtime-contract.ts +150 -0
- package/packages/plugin-runtime/browser/session-authority.ts +61 -0
- package/packages/plugin-runtime/computer/index.ts +6 -0
- package/packages/plugin-runtime/computer/provider-error.ts +26 -0
- package/packages/plugin-runtime/computer/provider-registration.ts +52 -0
- package/packages/plugin-runtime/computer/provider-registry.ts +63 -0
- package/packages/plugin-runtime/computer/provider.ts +19 -0
- package/packages/plugin-runtime/computer/target-authority.ts +190 -0
- package/packages/plugin-runtime/computer/target-persistence.ts +54 -0
- package/packages/plugin-runtime/external/index.ts +1 -0
- package/packages/plugin-runtime/external/unix-jsonl-transport.ts +457 -0
- package/packages/plugin-runtime/index.ts +3 -0
- package/packages/protocols/browser/index.ts +1 -0
- package/packages/protocols/browser/session.ts +98 -0
- package/packages/protocols/computer/contract.ts +199 -0
- package/packages/protocols/computer/index.ts +1 -0
- package/packages/protocols/failure/contract.ts +158 -0
- package/packages/protocols/failure/index.ts +1 -0
- package/packages/protocols/handoff/index.ts +1 -0
- package/packages/protocols/handoff/status.ts +22 -0
- package/packages/protocols/mcp/execution-context.ts +11 -0
- package/packages/protocols/mcp/index.ts +2 -0
- package/packages/protocols/mcp/tool-contract.ts +42 -0
- package/packages/workflow-runtime/api/index.ts +2 -0
- package/packages/workflow-runtime/application/interpreter.ts +342 -0
- package/packages/workflow-runtime/domain/workflow-asset.ts +223 -0
- package/packages/workflow-runtime/index.ts +1 -0
- package/scripts/assemble-template.ts +1 -1
- package/scripts/benchmark-computer-hotpath.ts +255 -0
- package/scripts/benchmark-controller-round2.ts +54 -2
- package/scripts/benchmark-ios-agent-device.ts +3 -6
- package/scripts/benchmark-mcp-transport.ts +3 -4
- package/scripts/benchmark-operational-memory-activation.ts +235 -0
- package/scripts/benchmark-operational-shadow.ts +28 -0
- package/scripts/bootstrap-runtime-maintenance-recovery.sh +4 -1
- package/scripts/canary-chatgpt-provider-delivery.ts +97 -0
- package/scripts/canary-controller-semantic-wait.ts +195 -0
- package/scripts/canary-global-hook.sh +2 -2
- package/scripts/check-mcp-compatibility.ts +173 -7
- package/scripts/check-platform-support.mjs +28 -2
- package/scripts/check-public-docs.sh +1 -1
- package/scripts/check-release-readiness.sh +1 -1
- package/scripts/check-repository-hygiene.mjs +92 -0
- package/scripts/check-runtime-architecture.mjs +1206 -95
- package/scripts/check-source-duplication.mjs +9 -1
- package/scripts/check-tarball-install-smoke.sh +98 -15
- package/scripts/controller-ngrok-rotation.sh +5 -4
- package/scripts/create-project-dirs.sh +10 -74
- package/scripts/forge-local-recovery-helper.mjs +204 -0
- package/scripts/forge-uu-remote-rescue-helper.d.mts +31 -0
- package/scripts/forge-uu-remote-rescue-helper.mjs +409 -0
- package/scripts/forge-windows-host-recovery-helper.mjs +136 -0
- package/scripts/hook-shim.sh +2 -2
- package/scripts/init-project.sh +12 -70
- package/scripts/install-desktop-operator-registration.ts +4 -2
- package/scripts/install-independent-windows-wsl-recovery.ts +125 -0
- package/scripts/install-standalone-recovery.ts +122 -10
- package/scripts/install-uu-remote-rescue-registration.ts +74 -0
- package/scripts/install-windows-host-recovery-registration.ts +22 -0
- package/scripts/lib/controller-home-env.sh +6 -3
- package/scripts/lib/project-init-lib.sh +39 -582
- package/scripts/migrate-chatgpt-automation-schedules.ts +2 -2
- package/scripts/migrate-windows-wsl-controller-home.ts +306 -0
- package/scripts/open-source-audit-allowlist.txt +12 -1
- package/scripts/portability-bindings.mjs +70 -0
- package/scripts/run-bounded-command.mjs +55 -0
- package/scripts/run-bun-test-file.ts +22 -6
- package/scripts/run-governed-gate.ts +4 -1
- package/scripts/smoke-mcp-http-runtime.ts +1 -1
- package/scripts/smoke-runtime-recovery.ts +34 -1
- package/scripts/smoke-schedule-engine.ts +1 -1
- package/scripts/stage-runtime-release.ts +6 -1
- package/scripts/test-governance.ts +51 -2
- package/src/cli/agent-jobs/job-manager.ts +10 -1
- package/src/cli/chatgpt-browser/bind-server.ts +2 -1
- package/src/cli/chatgpt-browser/binding.ts +20 -10
- package/src/cli/chatgpt-browser/bridge-extension.ts +75 -0
- package/src/cli/chatgpt-browser/bridge-provider.ts +376 -11
- package/src/cli/chatgpt-browser/engine.ts +10 -11
- package/src/cli/chatgpt-browser/native-provider.ts +24 -83
- package/src/cli/chatgpt-browser/oracle-provider.ts +5 -3
- package/src/cli/chatgpt-browser/types.ts +1 -0
- package/src/cli/commands/bootstrap-control.ts +334 -0
- package/src/cli/commands/brain-assistant.ts +38 -0
- package/src/cli/commands/brain.ts +193 -40
- package/src/cli/commands/chatgpt.ts +127 -0
- package/src/cli/commands/computer.ts +437 -0
- package/src/cli/commands/doctor.ts +18 -1
- package/src/cli/commands/init-hook.ts +71 -61
- package/src/cli/commands/init.ts +3 -1
- package/src/cli/commands/mcp.ts +16 -10
- package/src/cli/commands/plugin.ts +38 -12
- package/src/cli/commands/recovery.ts +493 -80
- package/src/cli/commands/runtime.ts +9 -4
- package/src/cli/commands/setup-profile.ts +89 -39
- package/src/cli/commands/status.ts +2 -1
- package/src/cli/controller/check-runner.ts +487 -98
- package/src/cli/controller/context/types.ts +7 -1
- package/src/cli/controller/context-pack.ts +23 -3
- package/src/cli/controller/issue-store.ts +1 -1
- package/src/cli/controller/systemd-user.ts +110 -0
- package/src/cli/controller/types.ts +10 -70
- package/src/cli/controller/worklog.ts +67 -13
- package/src/cli/editing/edit-operation-contract.ts +92 -0
- package/src/cli/editing/edit-session.ts +289 -13
- package/src/cli/github/plugin.ts +17 -12
- package/src/cli/hook/route-registry.ts +3 -5
- package/src/cli/hook/runtime.ts +49 -3
- package/src/cli/index.ts +3 -0
- package/src/cli/local-bridge/connector-freshness.ts +2 -2
- package/src/cli/local-bridge/console-automations.ts +2 -2
- package/src/cli/local-bridge/facade-api.ts +41 -14
- package/src/cli/local-bridge/job-store.ts +1 -1
- package/src/cli/local-bridge/server.ts +24 -27
- package/src/cli/mcp/access-mode.ts +2 -132
- package/src/cli/mcp/access-tools.ts +2 -387
- package/src/cli/mcp/audit.ts +2 -32
- package/src/cli/mcp/auth.ts +2 -404
- package/src/cli/mcp/instructions.ts +2 -34
- package/src/cli/mcp/legacy-context.ts +2 -16
- package/src/cli/mcp/legacy-tool-service.ts +2 -5308
- package/src/cli/mcp/multi-repository.ts +2 -436
- package/src/cli/mcp/oauth.ts +2 -375
- package/src/cli/mcp/openai-secure-tunnel.ts +2 -0
- package/src/cli/mcp/paths.ts +2 -140
- package/src/cli/mcp/policy.ts +2 -232
- package/src/cli/mcp/post-finalize-work-attribution.ts +2 -150
- package/src/cli/mcp/proxy-env.ts +2 -62
- package/src/cli/mcp/readiness-projection.ts +2 -24
- package/src/cli/mcp/redaction.ts +2 -21
- package/src/cli/mcp/repo.ts +2 -24
- package/src/cli/mcp/repository-tools.ts +2 -1585
- package/src/cli/mcp/server.ts +2 -951
- package/src/cli/mcp/setup.ts +2 -737
- package/src/cli/mcp/tool-capability-cache.ts +2 -87
- package/src/cli/mcp/tool-contract.ts +2 -14
- package/src/cli/mcp/tools.ts +2 -9
- package/src/cli/mcp/toolset-names.ts +2 -70
- package/src/cli/mcp/toolset-selection.ts +2 -41
- package/src/cli/mcp/toolset.ts +2 -336
- package/src/cli/mcp/transports/AGENTS.md +1 -10
- package/src/cli/mcp/transports/CLAUDE.md +1 -10
- package/src/cli/mcp/transports/http.ts +2 -1414
- package/src/cli/mcp/transports/session-registry.ts +2 -490
- package/src/cli/mcp/transports/stdio.ts +2 -8
- package/src/cli/mcp/types.ts +2 -41
- package/src/cli/mcp/umbrella-tools.ts +2 -117
- package/src/cli/repositories/command-executor.ts +64 -18
- package/src/cli/repositories/command-scope.ts +117 -1
- package/src/cli/repositories/controller-home.ts +119 -1
- package/src/cli/repositories/identity.ts +13 -0
- package/src/cli/repositories/registry.ts +68 -49
- package/src/cli/repositories/repository-snapshot.ts +53 -7
- package/src/cli/repositories/runtime-storage.ts +27 -2
- package/src/cli/repositories/safe-patch.ts +34 -38
- package/src/cli/repositories/selected-path-actions.ts +22 -2
- package/src/cli/repositories/structured-git.ts +105 -25
- package/src/cli/runtime/helper-runner.ts +7 -0
- package/src/cli/runtime-invocation.ts +8 -1
- package/src/cli/tools/codegraph.ts +44 -25
- package/src/core/adoption/manifest-templates.ts +1 -1
- package/src/core/adoption/plan.ts +3 -26
- package/src/core/adoption/workflow-contract-plan.ts +17 -9
- package/src/effects/process-runner.ts +8 -14
- package/src/runtime/context/assistant-context.ts +154 -0
- package/src/runtime/context/assistant-work-context.ts +147 -0
- package/src/runtime/context/codegraph-cache-boundary.ts +255 -0
- package/src/runtime/context/codegraph-read-provider.ts +55 -22
- package/src/runtime/context/codegraph-sidecar.cjs +8 -1
- package/src/runtime/context/context-closure.ts +268 -0
- package/src/runtime/context/context-plane.ts +211 -0
- package/src/runtime/context/project-engineering-contract.ts +60 -0
- package/src/runtime/control-plane/bootstrap/capability-provider.ts +74 -0
- package/src/runtime/control-plane/bootstrap/control-api.ts +57 -0
- package/src/runtime/control-plane/bootstrap/index.ts +5 -0
- package/src/runtime/control-plane/bootstrap/state-machine.ts +141 -0
- package/src/runtime/control-plane/bootstrap/store.ts +21 -0
- package/src/runtime/control-plane/bootstrap/types.ts +87 -0
- package/src/runtime/control-plane/cleanup-artifact-retention.ts +328 -0
- package/src/runtime/control-plane/codegraph-cache-retention.ts +164 -0
- package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +320 -0
- package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +169 -0
- package/src/runtime/control-plane/execution/controller-authority-recovery.ts +350 -0
- package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +85 -0
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +417 -100
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +103 -15
- package/src/runtime/control-plane/execution/implementation-review-content.ts +95 -0
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +2 -2
- package/src/runtime/control-plane/execution/retained-work-resume.ts +336 -6
- package/src/runtime/control-plane/execution/validation.ts +28 -3
- package/src/runtime/control-plane/execution/work-authority-reconciler.ts +116 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +44 -2
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +34 -3
- package/src/runtime/control-plane/execution/work-execution-support.ts +42 -22
- package/src/runtime/control-plane/execution/work-finalization-service.ts +1103 -166
- package/src/runtime/control-plane/execution/work-handle-authority.ts +267 -16
- package/src/runtime/control-plane/execution/work-handle-store.ts +77 -0
- package/src/runtime/control-plane/execution/work-head-settlement.ts +75 -0
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +145 -23
- package/src/runtime/control-plane/execution/work-operation-service.ts +49 -13
- package/src/runtime/control-plane/execution/work-preparation-service.ts +31 -15
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +1 -1
- package/src/runtime/control-plane/execution/work-task-receipt.ts +20 -1
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +407 -76
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +88 -18
- package/src/runtime/control-plane/execution/work-verification-context.ts +1 -1
- package/src/runtime/control-plane/execution/work-verification-service.ts +258 -4
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +200 -15
- package/src/runtime/control-plane/facade/capability-registry.ts +21 -10
- package/src/runtime/control-plane/facade/controller-round-relay.ts +3 -1118
- package/src/runtime/control-plane/facade/controller-session-store.ts +2 -488
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +6 -3
- package/src/runtime/control-plane/facade/goal-workloop.ts +972 -137
- package/src/runtime/control-plane/facade/handoff-inbox-application.ts +158 -0
- package/src/runtime/control-plane/facade/handoff-inbox-store.ts +10 -0
- package/src/runtime/control-plane/facade/index.ts +4 -2
- package/src/runtime/control-plane/facade/operation-digest.ts +22 -58
- package/src/runtime/control-plane/facade/plan-contract-store.ts +1004 -38
- package/src/runtime/control-plane/facade/repository-work-admission.ts +19 -1
- package/src/runtime/control-plane/facade/requirement-authority.ts +218 -0
- package/src/runtime/control-plane/facade/requirement-board.ts +6 -1
- package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +48 -0
- package/src/runtime/control-plane/facade/semantic-admission.ts +8 -16
- package/src/runtime/control-plane/facade/suggested-actions.ts +4 -1
- package/src/runtime/control-plane/facade/types.ts +189 -532
- package/src/runtime/control-plane/facade/work-admission-policy.ts +84 -35
- package/src/runtime/control-plane/facade/work-contract-store.ts +2 -1043
- package/src/runtime/control-plane/facade/work-implementation-review.ts +2 -0
- package/src/runtime/control-plane/facade/work-state-machine.ts +2 -250
- package/src/runtime/control-plane/generated-cache-retention.ts +239 -18
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +12 -1
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +76 -13
- package/src/runtime/control-plane/global-scheduler/periodic-cleanup-entry.ts +55 -0
- package/src/runtime/control-plane/global-scheduler/periodic-cleanup-process.ts +98 -0
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +1 -1
- package/src/runtime/control-plane/global-scheduler/scheduler-worker-entry.ts +10 -0
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +173 -81
- package/src/runtime/control-plane/global-scheduler/worker-launch.ts +18 -6
- package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +397 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +2 -177
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +301 -560
- package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +20 -4
- package/src/runtime/control-plane/launcher/thin-launcher.ts +50 -4
- package/src/runtime/control-plane/lifecycle-retention-metrics.ts +60 -0
- package/src/runtime/control-plane/persistence/experience-store.ts +169 -0
- package/src/runtime/control-plane/persistence/operational-prior-store.ts +348 -0
- package/src/runtime/control-plane/persistence/requirement-store.ts +30 -22
- package/src/runtime/control-plane/persistence/sqlite-store.ts +545 -76
- package/src/runtime/control-plane/persistence/workflow-content-store.ts +98 -0
- package/src/runtime/control-plane/persistence/workflow-registry-store.ts +186 -0
- package/src/runtime/control-plane/persistence/workflow-run-store.ts +123 -0
- package/src/runtime/control-plane/release-retention.ts +56 -16
- package/src/runtime/control-plane/repository-namespace-retention.ts +208 -0
- package/src/runtime/control-plane/routing/route-policy.ts +19 -0
- package/src/runtime/control-plane/runtime-cleanup.ts +574 -37
- package/src/runtime/control-plane/runtime-generation.ts +6 -0
- package/src/runtime/control-plane/workspace/semantic-sync-service.ts +465 -0
- package/src/runtime/control-plane/workspace/workspace-store.ts +80 -0
- package/src/runtime/diagnostics/incident-repair.ts +406 -0
- package/src/runtime/diagnostics/mcp-timing.ts +125 -6
- package/src/runtime/diagnostics/performance.ts +6 -14
- package/src/runtime/diagnostics/read-only-tool.ts +1 -1
- package/src/runtime/evidence/artifact-store.ts +65 -2
- package/src/runtime/evidence/operational-shadow.ts +38 -0
- package/src/runtime/evidence/process-check-receipt.ts +5 -43
- package/src/runtime/evidence/sensitive-output.ts +4 -4
- package/src/runtime/execution/jobs/receipt-recovery.ts +1 -1
- package/src/runtime/execution/jobs/store.ts +121 -2
- package/src/runtime/execution/managed-workspace.ts +55 -5
- package/src/runtime/execution/process-runtime/canary.ts +19 -5
- package/src/runtime/execution/process-runtime/check-classification.ts +48 -0
- package/src/runtime/execution/process-runtime/check-facade.ts +23 -9
- package/src/runtime/execution/process-runtime/check-receipt.ts +1 -1
- package/src/runtime/execution/process-runtime/check-result-retention.ts +132 -0
- package/src/runtime/execution/process-runtime/check-result.ts +73 -2
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +42 -3
- package/src/runtime/execution/process-runtime/check-storage.ts +187 -0
- package/src/runtime/execution/process-runtime/command-facade.ts +38 -87
- package/src/runtime/execution/process-runtime/index.ts +1 -0
- package/src/runtime/execution/process-runtime/interactive-admission.ts +2 -1
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +32 -1
- package/src/runtime/execution/process-runtime/persisted-check.ts +128 -21
- package/src/runtime/execution/process-runtime/resource-claims.ts +60 -3
- package/src/runtime/execution/process-runtime/runtime.ts +132 -15
- package/src/runtime/execution/process-runtime/types.ts +22 -0
- package/src/runtime/execution/workers/executor.ts +16 -13
- package/src/runtime/execution/workers/worker-entry.ts +1 -1
- package/src/runtime/gateway/mcp/execution-tools.ts +2 -207
- package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +2 -61
- package/src/runtime/gateway/mcp/persisted-check-process.ts +2 -3
- package/src/runtime/gateway/mcp/process-tools.ts +2 -289
- package/src/runtime/gateway/mcp/router.ts +2 -1125
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +2 -565
- package/src/runtime/gateway/mcp/runtime-tools.ts +2 -6651
- package/src/runtime/gateway/mcp/work-validation-reconciler.ts +2 -1
- package/src/runtime/maintenance/cleanup.ts +38 -24
- package/src/runtime/platform/browser-product-discovery.ts +174 -0
- package/src/runtime/platform/computer-platform.ts +14 -0
- package/src/runtime/platform/executable-discovery.ts +54 -0
- package/src/runtime/platform/fetch-http-server.ts +90 -0
- package/src/runtime/platform/service-manager.ts +138 -0
- package/src/runtime/platform/windows-host-discovery.ts +118 -0
- package/src/runtime/platform/windows-recovery-deployment.ts +67 -0
- package/src/runtime/plugins/action-application.ts +135 -0
- package/src/runtime/plugins/app-store-connect-adapter.ts +9 -21
- package/src/runtime/plugins/browser-adapter.ts +140 -100
- package/src/runtime/plugins/browser-automation-service.ts +15 -36
- package/src/runtime/plugins/browser-macos-bridge.ts +69 -21
- package/src/runtime/plugins/browser-manifest-surface.ts +30 -6
- package/src/runtime/plugins/browser-native-session-service.ts +1 -1
- package/src/runtime/plugins/browser-provider-registry.ts +2 -109
- package/src/runtime/plugins/browser-registration.ts +16 -0
- package/src/runtime/plugins/browser-runtime-contract.ts +2 -154
- package/src/runtime/plugins/browser-runtime.ts +41 -9
- package/src/runtime/plugins/browser-session-authority.ts +101 -291
- package/src/runtime/plugins/browser-session-legacy-migration.ts +203 -0
- package/src/runtime/plugins/browser-session-store.ts +229 -36
- package/src/runtime/plugins/browser-session-types.ts +2 -98
- package/src/runtime/plugins/capability-authorization-grants.ts +17 -0
- package/src/runtime/plugins/catalog-trust.ts +82 -0
- package/src/runtime/plugins/computer-registration.ts +839 -0
- package/src/runtime/plugins/config-store.ts +119 -0
- package/src/runtime/plugins/desktop-operator-external-policy.ts +932 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +111 -8
- package/src/runtime/plugins/errors.ts +8 -1
- package/src/runtime/plugins/external-adapter.ts +45 -322
- package/src/runtime/plugins/external-provider-policy.ts +48 -0
- package/src/runtime/plugins/external-registration.ts +9 -1
- package/src/runtime/plugins/external-unix-socket-probe.cjs +9 -3
- package/src/runtime/plugins/external-unix-socket.ts +64 -193
- package/src/runtime/plugins/first-party-external-registration.ts +163 -0
- package/src/runtime/plugins/first-party-registry.ts +3 -1
- package/src/runtime/plugins/github-adapter.ts +1 -2
- package/src/runtime/plugins/gmail-adapter.ts +6 -6
- package/src/runtime/plugins/google-calendar-adapter.ts +6 -6
- package/src/runtime/plugins/google-shared.ts +31 -46
- package/src/runtime/plugins/google-tasks-adapter.ts +6 -6
- package/src/runtime/plugins/ios-adapter.ts +1 -2
- package/src/runtime/plugins/local-system-adapter.ts +180 -0
- package/src/runtime/plugins/macos-capability-broker.ts +15 -105
- package/src/runtime/plugins/resend-adapter.ts +15 -24
- package/src/runtime/plugins/store.ts +493 -51
- package/src/runtime/plugins/types.ts +8 -1
- package/src/runtime/plugins/uu-remote-rescue-registration.ts +155 -0
- package/src/runtime/plugins/windows-host-recovery-install.ts +68 -0
- package/src/runtime/plugins/windows-host-recovery-registration.ts +85 -0
- package/src/runtime/plugins/xiaohongshu-publish.ts +86 -430
- package/src/runtime/projections/controller-context.ts +12 -6
- package/src/runtime/projections/git-status-sampler.ts +73 -22
- package/src/runtime/projections/materialized-view.ts +14 -8
- package/src/runtime/recovery/capability-action-application.ts +228 -0
- package/src/runtime/recovery/index.ts +3 -0
- package/src/runtime/recovery/lifecycle-inventory.ts +338 -0
- package/src/runtime/recovery/local-jobs-repair.ts +14 -14
- package/src/runtime/recovery/maintenance-executor.ts +358 -76
- package/src/runtime/recovery/quarantine-retention.ts +256 -0
- package/src/runtime/release/identity.ts +6 -0
- package/src/runtime/resources/leases/store.ts +1 -1
- package/src/runtime/root/active-execution-power-assertion.ts +139 -0
- package/src/runtime/root/assistant-learning-loop.ts +45 -0
- package/src/runtime/root/browser-session-composition.ts +59 -0
- package/src/runtime/root/computer-composition.ts +191 -0
- package/src/runtime/root/computer-target-composition.ts +16 -0
- package/src/runtime/root/computer-target-persistence.ts +39 -0
- package/src/runtime/root/controller-round-composition.ts +107 -0
- package/src/runtime/root/controller-services.ts +2 -0
- package/src/runtime/root/entry.ts +4 -3
- package/src/runtime/root/gateway-adapter.ts +3 -3
- package/src/runtime/root/local-bridge.ts +5 -2
- package/src/runtime/root/mcp-transport.ts +5 -5
- package/src/runtime/root/package-connector-service.ts +108 -56
- package/src/runtime/root/package-runtime-release.ts +86 -18
- package/src/runtime/root/package-runtime-service.ts +63 -86
- package/src/runtime/root/release-execution-canary.ts +71 -0
- package/src/runtime/root/release-loader.ts +68 -0
- package/src/runtime/root/release-manifest.ts +106 -2
- package/src/runtime/root/release-materialize.ts +103 -4
- package/src/runtime/root/release-store.ts +31 -2
- package/src/runtime/root/runtime.ts +240 -25
- package/src/runtime/root/scheduled-controller-composition.ts +51 -0
- package/src/runtime/root/scheduler.ts +12 -4
- package/src/runtime/root/service-runner.ts +1 -1
- package/src/runtime/root/service.ts +41 -16
- package/src/runtime/root/status.ts +1 -0
- package/src/runtime/root/types.ts +24 -1
- package/src/runtime/shared/local-bridge-surface.ts +1 -1
- package/src/runtime/shared/process-environment.ts +19 -4
- package/src/runtime/shared/storage-capacity.ts +68 -0
- package/src/runtime/standalone-recovery/controller-home-migration.ts +1116 -0
- package/src/runtime/standalone-recovery/core.ts +984 -230
- package/src/runtime/standalone-recovery/entry.ts +182 -51
- package/src/runtime/standalone-recovery/independent-host-rescue.ts +172 -0
- package/src/runtime/standalone-recovery/installer.ts +212 -104
- package/src/runtime/standalone-recovery/mcp-server.ts +243 -0
- package/src/runtime/standalone-recovery/mutation-identity-contract.ts +21 -0
- package/src/runtime/standalone-recovery/operation-lock.ts +160 -0
- package/src/runtime/standalone-recovery/performance.ts +135 -0
- package/src/runtime/standalone-recovery/release.ts +5 -0
- package/src/runtime/watchdog/workflow-watchdog.ts +1 -1
- package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +1 -1
- package/src/runtime/workflow/schedules/engine.ts +191 -343
- package/src/runtime/workflow/schedules/pending-activation.ts +1 -1
- package/src/runtime/workflow/schedules/settlement.ts +2 -191
- package/src/runtime/workflow/schedules/store.ts +2 -607
- package/src/runtime/workflow/schedules/types.ts +2 -127
- package/src/runtime/workflow/schedules/work-continuation.ts +180 -15
- package/src/runtime/workflows/first-party/xiaohongshu.ts +122 -0
- package/src/runtime/workflows/runtime.ts +486 -0
- package/src/testing/test-governance.ts +90 -29
- package/assets/templates/helpers/archive-architecture-request.sh +0 -244
- package/docs/architecture/history/README.md +0 -7
- package/docs/architecture/history/chatgpt-handoff-facade.md +0 -397
- package/docs/architecture/history/global-hook-runtime.md +0 -166
- package/docs/architecture/history/ios-semantic-automation-provider-v2.md +0 -170
- package/docs/architecture/requests/archive/2026/20260528-154740-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-154816-assets-hooks-assets-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-161851-ai-harness-workflow-contract-json-ai-harness-workflow-contract-json.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-161853-scripts-check-task-workflow-sh-scripts-check-task-workflow-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-161911-assets-workflow-contract-v1-json-assets-workflow-contract-v1-json.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222416-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222444-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222457-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222648-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222705-ai-hooks-ai-hooks-worktree-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222726-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222727-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-224736-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233259-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233335-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233456-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233457-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233637-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233638-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260529-000322-root-package-json.md +0 -59
- package/docs/architecture/requests/archive/2026/20260529-004238-ai-hooks-ai-hooks-lib-workflow-state-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260529-020654-ai-harness-policy-json-ai-harness-policy-json.md +0 -63
- package/docs/architecture/requests/archive/2026/20260529-094236-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094323-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094331-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094339-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094430-assets-hooks-assets-hooks-session-start-context-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094446-ai-hooks-ai-hooks-session-start-context-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260613-002040-runtime-harness-hook-adapters.md +0 -68
- package/docs/architecture/requests/archive/2026/root.md +0 -68
- package/docs/architecture/requests/archive/2026/runtime-harness-hook-adapters.md +0 -76
- package/docs/architecture/requests/archive/2026/verification-evals-checks.md +0 -68
- package/docs/architecture/requests/archive/2026/workflow-engine-contract-assets.md +0 -69
- package/scripts/archive-architecture-request.sh +0 -4
- package/scripts/run-skill-evals.ts +0 -1022
|
@@ -5,34 +5,41 @@ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'pat
|
|
|
5
5
|
import type {
|
|
6
6
|
AssistantPluginActionExecutionInput,
|
|
7
7
|
AssistantPluginAuthorizationContext,
|
|
8
|
+
AssistantPluginBuildContext,
|
|
8
9
|
AssistantPluginHealth,
|
|
9
10
|
AssistantPluginManifest,
|
|
10
11
|
} from './types';
|
|
11
12
|
import { AssistantPluginError, toAssistantPluginError } from './errors';
|
|
13
|
+
import { readRepositoryPluginConfig, writeRepositoryPluginConfig, type RepositoryPluginConfigContext } from './config-store';
|
|
12
14
|
import {
|
|
13
15
|
browserActions,
|
|
14
16
|
browserCapabilities,
|
|
15
17
|
browserPermissions,
|
|
16
18
|
} from './browser-manifest-surface';
|
|
17
19
|
import { executeBrowserActionThroughNode, shouldUseBrowserNodeBridge } from './browser-node-bridge';
|
|
18
|
-
import { BrowserProviderUnavailableBeforeActionError } from '
|
|
19
|
-
import { MAX_BROWSER_CDP_ENDPOINT_CANDIDATES } from '
|
|
20
|
+
import { BrowserProviderUnavailableBeforeActionError } from '../../../packages/plugin-runtime/browser/provider-registry';
|
|
21
|
+
import { MAX_BROWSER_CDP_ENDPOINT_CANDIDATES } from '../../../packages/plugin-runtime/browser/runtime-contract';
|
|
20
22
|
import {
|
|
21
23
|
ALL_BROWSER_PROVIDER_CAPABILITIES,
|
|
22
24
|
browserActionCanReplayAfterDispatch as canReplayBrowserActionAfterDispatch,
|
|
25
|
+
browserExplicitPostActionWaitMs,
|
|
26
|
+
browserNativeForegroundVerificationWaitMs,
|
|
23
27
|
executeBrowserRuntimeAction,
|
|
24
28
|
invalidateBrowserRuntime,
|
|
25
29
|
} from './browser-runtime';
|
|
26
|
-
import {
|
|
30
|
+
import { activateRuntimeComputerBrowserApplication } from '../root/computer-composition';
|
|
27
31
|
import {
|
|
28
|
-
currentBrowserSessionAuthorityContext,
|
|
29
32
|
DEFAULT_BROWSER_SESSION_LIST_LIMIT,
|
|
30
33
|
MAX_BROWSER_SESSION_LIST_LIMIT,
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
} from '../../../packages/plugin-runtime/browser/session-authority';
|
|
35
|
+
import {
|
|
36
|
+
currentRuntimeBrowserSessionAuthorityContext as currentBrowserSessionAuthorityContext,
|
|
37
|
+
withRuntimeBrowserSessionAuthorityContext as withBrowserSessionAuthorityContext,
|
|
38
|
+
} from '../root/browser-session-composition';
|
|
33
39
|
import {
|
|
34
40
|
closeMacOsBrowserOwnedTab,
|
|
35
41
|
createMacOsBrowserOwnedPage,
|
|
42
|
+
createMacOsBrowserOwnedPageForProduct,
|
|
36
43
|
reattachMacOsBrowserOwnedPage,
|
|
37
44
|
discoverMacOsBrowserAttachment,
|
|
38
45
|
invalidateMacOsBrowserPageHandle,
|
|
@@ -87,13 +94,11 @@ import type {
|
|
|
87
94
|
BrowserTabMatchReason,
|
|
88
95
|
BrowserTabResumeState,
|
|
89
96
|
CdpAttachAttempt,
|
|
90
|
-
} from '
|
|
97
|
+
} from '../../../packages/protocols/browser/index';
|
|
91
98
|
|
|
92
99
|
const BROWSER_PLUGIN_ID = 'browser';
|
|
93
|
-
const CONFIG_ROOT = '.forge/plugins';
|
|
94
100
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
95
101
|
const DEFAULT_MAX_TEXT_CHARS = 20_000;
|
|
96
|
-
const DEFAULT_POST_ACTION_WAIT_MS = 750;
|
|
97
102
|
const DEFAULT_CDP_DISCOVERY_TIMEOUT_MS = 1_500;
|
|
98
103
|
const MAX_CDP_DISCOVERY_TIMEOUT_MS = 5_000;
|
|
99
104
|
|
|
@@ -149,6 +154,15 @@ interface BrowserActionTarget {
|
|
|
149
154
|
existingSession?: BrowserSessionState;
|
|
150
155
|
}
|
|
151
156
|
|
|
157
|
+
export function browserExplicitSessionRequiresExistingResource(
|
|
158
|
+
actionId: string,
|
|
159
|
+
explicitSessionId: string | undefined,
|
|
160
|
+
existingSessionPresent: boolean,
|
|
161
|
+
): boolean {
|
|
162
|
+
if (!explicitSessionId) return false;
|
|
163
|
+
return actionId === 'navigate' || existingSessionPresent;
|
|
164
|
+
}
|
|
165
|
+
|
|
152
166
|
interface BrowserActionScreenshot {
|
|
153
167
|
path: string;
|
|
154
168
|
relativePath: string;
|
|
@@ -245,39 +259,6 @@ interface BrowserPluginRuntimeHooks {
|
|
|
245
259
|
activateNativeBrowserApplication(input: AssistantPluginActionExecutionInput, product: MacOsBrowserProduct): Promise<void>;
|
|
246
260
|
}
|
|
247
261
|
|
|
248
|
-
const NATIVE_BROWSER_BUNDLE_IDS: Record<MacOsBrowserProduct, string> = {
|
|
249
|
-
chrome: 'com.google.Chrome',
|
|
250
|
-
vivaldi: 'com.vivaldi.Vivaldi',
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
async function activateNativeBrowserApplicationViaDesktopOperator(
|
|
254
|
-
input: AssistantPluginActionExecutionInput,
|
|
255
|
-
product: MacOsBrowserProduct,
|
|
256
|
-
): Promise<void> {
|
|
257
|
-
const desktopOperator = getExternalPluginAdapter(input.controllerHome, 'desktop_operator');
|
|
258
|
-
if (!desktopOperator) {
|
|
259
|
-
throw new AssistantPluginError(
|
|
260
|
-
'PLUGIN_BROWSER_NATIVE_FOREGROUND_ACTIVATOR_UNAVAILABLE',
|
|
261
|
-
'Native browser foreground activation requires the registered Forge Desktop Operator.',
|
|
262
|
-
{ retryable: true, details: { browserProduct: product } },
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
await desktopOperator.executeAction({
|
|
266
|
-
controllerHome: input.controllerHome,
|
|
267
|
-
repoId: input.repoId,
|
|
268
|
-
repoRoot: input.repoRoot,
|
|
269
|
-
pluginId: 'desktop_operator',
|
|
270
|
-
actionId: 'desktop_session_open',
|
|
271
|
-
requestId: `${input.requestId}:native-browser-foreground:${product}`,
|
|
272
|
-
args: { bundle_id: NATIVE_BROWSER_BUNDLE_IDS[product], launch: false, activate: true },
|
|
273
|
-
origin: input.origin,
|
|
274
|
-
jobId: input.jobId,
|
|
275
|
-
timeoutMs: input.timeoutMs,
|
|
276
|
-
signal: input.signal,
|
|
277
|
-
deadlineAtMs: input.deadlineAtMs,
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
|
|
281
262
|
const defaultRuntimeHooks: BrowserPluginRuntimeHooks = {
|
|
282
263
|
now: () => new Date().toISOString(),
|
|
283
264
|
moduleAvailable: (name: string, repoRoot?: string) => {
|
|
@@ -318,7 +299,7 @@ const defaultRuntimeHooks: BrowserPluginRuntimeHooks = {
|
|
|
318
299
|
clearTimeout(timer);
|
|
319
300
|
}
|
|
320
301
|
},
|
|
321
|
-
activateNativeBrowserApplication:
|
|
302
|
+
activateNativeBrowserApplication: activateRuntimeComputerBrowserApplication,
|
|
322
303
|
};
|
|
323
304
|
|
|
324
305
|
let runtimeHooks: BrowserPluginRuntimeHooks = { ...defaultRuntimeHooks };
|
|
@@ -406,10 +387,6 @@ function stringList(value: unknown): string[] | undefined {
|
|
|
406
387
|
return normalized.length > 0 ? Array.from(new Set(normalized)) : undefined;
|
|
407
388
|
}
|
|
408
389
|
|
|
409
|
-
function configPath(repoRoot: string): string {
|
|
410
|
-
return join(repoRoot, CONFIG_ROOT, 'browser.json');
|
|
411
|
-
}
|
|
412
|
-
|
|
413
390
|
function defaultProfileDir(repoRoot: string): string {
|
|
414
391
|
return join(browserStateDir(repoRoot, 'profiles'), 'default');
|
|
415
392
|
}
|
|
@@ -501,8 +478,10 @@ function writeJson(path: string, value: unknown): void {
|
|
|
501
478
|
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`, 'utf-8');
|
|
502
479
|
}
|
|
503
480
|
|
|
504
|
-
function loadConfig(repoRoot: string): BrowserPluginConfig {
|
|
505
|
-
const persisted =
|
|
481
|
+
function loadConfig(repoRoot: string, context?: Pick<RepositoryPluginConfigContext, 'controllerHome' | 'repoId'>): BrowserPluginConfig {
|
|
482
|
+
const persisted = context
|
|
483
|
+
? readRepositoryPluginConfig<PersistedBrowserPluginConfig>({ ...context, repoRoot }, BROWSER_PLUGIN_ID)
|
|
484
|
+
: undefined;
|
|
506
485
|
if (!persisted) return normalizeConfig({});
|
|
507
486
|
return normalizeConfig(migrateLegacyRepositoryConfig(persisted));
|
|
508
487
|
}
|
|
@@ -513,7 +492,7 @@ async function resolveBrowserPluginAuthorizationContextInternal(
|
|
|
513
492
|
const action = browserActions().find((entry) => entry.actionId === input.actionId);
|
|
514
493
|
if (!action || action.confirmation !== 'authorization' || !action.scopes.includes('browser.interact')) return undefined;
|
|
515
494
|
|
|
516
|
-
const persistedConfig = loadConfig(input.repoRoot);
|
|
495
|
+
const persistedConfig = loadConfig(input.repoRoot, input);
|
|
517
496
|
const sessionId = stringValue(input.args.session_id);
|
|
518
497
|
const authorizationBrowserMode = parseBrowserModeInput(input.args.browser_mode) ?? persistedConfig.browserMode;
|
|
519
498
|
if (!sessionId || authorizationBrowserMode === 'isolated') return undefined;
|
|
@@ -568,15 +547,9 @@ export async function resolveBrowserPluginAuthorizationContext(
|
|
|
568
547
|
);
|
|
569
548
|
}
|
|
570
549
|
|
|
571
|
-
|
|
572
|
-
const
|
|
573
|
-
return
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
function saveConfig(repoRoot: string, patch: Partial<BrowserPluginConfig>): BrowserPluginConfig {
|
|
577
|
-
const next = normalizeConfig({ ...loadConfig(repoRoot), ...patch });
|
|
578
|
-
writeJson(configPath(repoRoot), next);
|
|
579
|
-
return next;
|
|
550
|
+
function saveConfig(input: Pick<AssistantPluginActionExecutionInput, 'controllerHome' | 'repoId' | 'repoRoot'>, patch: Partial<BrowserPluginConfig>): BrowserPluginConfig {
|
|
551
|
+
const next = normalizeConfig({ ...loadConfig(input.repoRoot, input), ...patch });
|
|
552
|
+
return writeRepositoryPluginConfig(input, BROWSER_PLUGIN_ID, next);
|
|
580
553
|
}
|
|
581
554
|
|
|
582
555
|
function parsedAbsoluteUrl(value: unknown): { raw: string; parsed: URL } {
|
|
@@ -1054,7 +1027,7 @@ async function establishAuthoritativeNativeForeground(
|
|
|
1054
1027
|
const cause = error instanceof Error ? error.message : String(error);
|
|
1055
1028
|
throw new AssistantPluginError(
|
|
1056
1029
|
'PLUGIN_BROWSER_ACTIVATION_FAILED',
|
|
1057
|
-
'Native browser exact-tab activation could not establish
|
|
1030
|
+
'Native browser exact-tab activation could not establish system foreground authority through the configured Computer provider.',
|
|
1058
1031
|
{ retryable: true, details: { sessionId: target.sessionId, browserProduct: product, ...state, ...(causeCode ? { causeCode } : {}), cause: cause.slice(0, 500) } },
|
|
1059
1032
|
);
|
|
1060
1033
|
}
|
|
@@ -2127,14 +2100,36 @@ async function openNativeAttachedContext(
|
|
|
2127
2100
|
: { sessionId: target.sessionId, status: 'no_saved_tab', reason: 'Created one plugin-owned tab while preserving the user active tab.' };
|
|
2128
2101
|
}
|
|
2129
2102
|
|
|
2103
|
+
let createdThisCallRef: MacOsBrowserTabRef | undefined;
|
|
2130
2104
|
if (!discovered?.attachment) {
|
|
2131
2105
|
const candidates = savedProduct ? [savedProduct] : (config.nativeBrowserCandidates ?? [...DEFAULT_USER_NATIVE_BROWSER_CANDIDATES]);
|
|
2132
2106
|
discovered = await discoverMacOsBrowserAttachment(candidates, Math.min(timeout, MAX_CDP_DISCOVERY_TIMEOUT_MS));
|
|
2107
|
+
const zeroWindowAttempt = args.__forge_require_existing_resource !== true
|
|
2108
|
+
? discovered.attempts.find((attempt) => attempt.status === 'unavailable' && attempt.error?.includes('FORGE_NO_BROWSER_WINDOW'))
|
|
2109
|
+
: undefined;
|
|
2110
|
+
if (!discovered.attachment && zeroWindowAttempt) {
|
|
2111
|
+
const created = await createMacOsBrowserOwnedPageForProduct(
|
|
2112
|
+
zeroWindowAttempt.product,
|
|
2113
|
+
target.url,
|
|
2114
|
+
discovered.attempts,
|
|
2115
|
+
timeout,
|
|
2116
|
+
);
|
|
2117
|
+
page = created.page as unknown as PageLike;
|
|
2118
|
+
discovered = { attachment: created.attachment, attempts: created.attachment.attempts };
|
|
2119
|
+
createdThisCallRef = created.page.tabRef();
|
|
2120
|
+
matchedBy = 'owned_token';
|
|
2121
|
+
effectiveOwnership = 'plugin_owned';
|
|
2122
|
+
sessionResume = {
|
|
2123
|
+
sessionId: target.sessionId,
|
|
2124
|
+
status: 'stale_tab',
|
|
2125
|
+
reason: 'Browser process had no window; created the first Forge-owned tab through the existing create_tab Computer capability.',
|
|
2126
|
+
savedTab,
|
|
2127
|
+
};
|
|
2128
|
+
}
|
|
2133
2129
|
}
|
|
2134
2130
|
if (!discovered.attachment) return { attempts: discovered.attempts };
|
|
2135
2131
|
let activeAttachment = discovered.attachment;
|
|
2136
2132
|
|
|
2137
|
-
let createdThisCallRef: MacOsBrowserTabRef | undefined;
|
|
2138
2133
|
let navigationUsedReplacement = false;
|
|
2139
2134
|
const navigateNativePageWithReplacement = async (candidate: PageLike): Promise<PageLike> => {
|
|
2140
2135
|
const obsoleteRef = (candidate as unknown as { tabRef?: () => MacOsBrowserTabRef | undefined }).tabRef?.();
|
|
@@ -2486,11 +2481,13 @@ async function withPage<T>(
|
|
|
2486
2481
|
let lastError: unknown;
|
|
2487
2482
|
for (let attempt = 1; attempt <= retries; attempt += 1) {
|
|
2488
2483
|
let handle: BrowserOpenHandle | undefined;
|
|
2489
|
-
//
|
|
2490
|
-
//
|
|
2491
|
-
//
|
|
2492
|
-
//
|
|
2493
|
-
|
|
2484
|
+
// A provider/readiness failure before openBrowser returns a handle has not
|
|
2485
|
+
// crossed the action dispatch boundary. Native open-page creation is itself
|
|
2486
|
+
// transactional: its bridge either returns an exact created-tab receipt or
|
|
2487
|
+
// cleans up the created tab before propagating failure. Mark dispatch only
|
|
2488
|
+
// after a usable handle exists; subsequent goto/click/fill failures retain
|
|
2489
|
+
// outcome-unknown fencing for non-replay-safe actions.
|
|
2490
|
+
let actionDispatched = false;
|
|
2494
2491
|
try {
|
|
2495
2492
|
if (target.existingSession) assertBrowserSessionAvailable(repoRoot, target.sessionId);
|
|
2496
2493
|
const browserArgs = requireExistingResource
|
|
@@ -2537,7 +2534,7 @@ async function withPage<T>(
|
|
|
2537
2534
|
throw new AssistantPluginError(
|
|
2538
2535
|
'PLUGIN_BROWSER_MUTATION_OUTCOME_UNKNOWN',
|
|
2539
2536
|
`Browser action ${actionId} reported a transient failure after dispatch. Forge refused automatic replay because the external mutation outcome is unknown; verify current browser state before retrying.`,
|
|
2540
|
-
{ retryable: false, details: { actionId, requestedRetries: retries } },
|
|
2537
|
+
{ retryable: false, effectOutcome: 'outcome_unknown', details: { actionId, requestedRetries: retries } },
|
|
2541
2538
|
);
|
|
2542
2539
|
}
|
|
2543
2540
|
if (attempt >= retries) throw error;
|
|
@@ -2733,9 +2730,10 @@ const STABLE_SELECTOR_HELPERS = `
|
|
|
2733
2730
|
`;
|
|
2734
2731
|
|
|
2735
2732
|
const EXTRACTION_SCRIPTS = {
|
|
2736
|
-
query: (selector: string, limit: number) => `(() => {
|
|
2733
|
+
query: (selector: string, limit: number, fromEnd = false) => `(() => {
|
|
2737
2734
|
${STABLE_SELECTOR_HELPERS}
|
|
2738
|
-
const
|
|
2735
|
+
const allNodes = ${openShadowSelectorExpression(selector, true)};
|
|
2736
|
+
const nodes = ${fromEnd ? `allNodes.slice(-${limit})` : `allNodes.slice(0, ${limit})`};
|
|
2739
2737
|
return nodes.map((el) => {
|
|
2740
2738
|
const role = el.getAttribute('role');
|
|
2741
2739
|
const text = (el.innerText || el.textContent || '').trim().slice(0, 120);
|
|
@@ -3223,9 +3221,9 @@ function health(config: BrowserPluginConfig, repoRoot?: string): AssistantPlugin
|
|
|
3223
3221
|
};
|
|
3224
3222
|
}
|
|
3225
3223
|
|
|
3226
|
-
export function buildBrowserPluginManifest(previousRevision = 0, previousUpdatedAt?: string, repoRoot?: string): AssistantPluginManifest {
|
|
3224
|
+
export function buildBrowserPluginManifest(previousRevision = 0, previousUpdatedAt?: string, repoRoot?: string, context?: AssistantPluginBuildContext): AssistantPluginManifest {
|
|
3227
3225
|
const root = repoRoot ?? process.cwd();
|
|
3228
|
-
const config = loadConfig(root);
|
|
3226
|
+
const config = loadConfig(root, context);
|
|
3229
3227
|
const state = health(config, root);
|
|
3230
3228
|
return {
|
|
3231
3229
|
schemaVersion: 1,
|
|
@@ -3238,7 +3236,7 @@ export function buildBrowserPluginManifest(previousRevision = 0, previousUpdated
|
|
|
3238
3236
|
authority: {
|
|
3239
3237
|
strategy: 'derived',
|
|
3240
3238
|
duplicateStateAllowed: false,
|
|
3241
|
-
sourceOfTruth: ['
|
|
3239
|
+
sourceOfTruth: ['controller-home:repositories/<repoId>/plugins/config/browser.json', 'controller-home:sqlite/computer_interaction_target', 'controller-home:repository browser artifacts'],
|
|
3242
3240
|
},
|
|
3243
3241
|
enabled: config.enabled,
|
|
3244
3242
|
lifecycle: {
|
|
@@ -3278,7 +3276,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
3278
3276
|
input: AssistantPluginActionExecutionInput,
|
|
3279
3277
|
runtimeAlreadyRouted = false,
|
|
3280
3278
|
): Promise<Record<string, unknown>> {
|
|
3281
|
-
const persisted = loadConfig(input.repoRoot);
|
|
3279
|
+
const persisted = loadConfig(input.repoRoot, input);
|
|
3282
3280
|
const actionSessionId = input.actionId === 'configure' ? undefined : stringValue(input.args.session_id);
|
|
3283
3281
|
const actionSession = actionSessionId ? findBrowserSession(input.repoRoot, actionSessionId) : undefined;
|
|
3284
3282
|
const current = input.actionId === 'configure' ? persisted : effectiveBrowserActionConfig(persisted, input.args, actionSession);
|
|
@@ -3360,7 +3358,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
3360
3358
|
const nextCdpAttachFallback = parseCdpAttachFallbackInput(args.cdp_attach_fallback) ?? current.cdpAttachFallback;
|
|
3361
3359
|
const nextNativeAttachMode = parseNativeAttachModeInput(args.native_attach_mode) ?? current.nativeAttachMode;
|
|
3362
3360
|
const nextNativeBrowserCandidates = parseNativeBrowserCandidatesInput(args.native_browser_candidates) ?? current.nativeBrowserCandidates;
|
|
3363
|
-
const config = saveConfig(input
|
|
3361
|
+
const config = saveConfig(input, {
|
|
3364
3362
|
enabled: typeof args.enabled === 'boolean' ? args.enabled : current.enabled,
|
|
3365
3363
|
browserMode: nextBrowserMode,
|
|
3366
3364
|
profileMode: nextProfileMode,
|
|
@@ -3807,7 +3805,13 @@ async function executeBrowserPluginActionInternal(
|
|
|
3807
3805
|
? { text: await extractText(page, undefined, positiveNumber(input.args.max_chars, DEFAULT_MAX_TEXT_CHARS)) }
|
|
3808
3806
|
: {}),
|
|
3809
3807
|
};
|
|
3810
|
-
}, {
|
|
3808
|
+
}, {
|
|
3809
|
+
requireExistingResource: browserExplicitSessionRequiresExistingResource(
|
|
3810
|
+
input.actionId,
|
|
3811
|
+
existingSessionId,
|
|
3812
|
+
Boolean(target.existingSession),
|
|
3813
|
+
),
|
|
3814
|
+
});
|
|
3811
3815
|
}
|
|
3812
3816
|
case 'reload':
|
|
3813
3817
|
case 'go_back':
|
|
@@ -3877,7 +3881,11 @@ async function executeBrowserPluginActionInternal(
|
|
|
3877
3881
|
const limit = Math.min(positiveNumber(input.args.limit, 25), 100);
|
|
3878
3882
|
return await withPage(input.actionId, input.repoRoot, current, target, input.args, async (page, _diagnostics, connection) => {
|
|
3879
3883
|
const selection = resolveBrowserEvaluationScope(page, input.args, connection);
|
|
3880
|
-
const matches = await selection.scope.evaluate<Array<Record<string, unknown>>>(EXTRACTION_SCRIPTS.query(
|
|
3884
|
+
const matches = await selection.scope.evaluate<Array<Record<string, unknown>>>(EXTRACTION_SCRIPTS.query(
|
|
3885
|
+
selector,
|
|
3886
|
+
input.actionId === 'query_selector' ? 1 : limit,
|
|
3887
|
+
input.actionId === 'query_all' && input.args.from_end === true,
|
|
3888
|
+
));
|
|
3881
3889
|
return {
|
|
3882
3890
|
provider: browserResultProvider(connection.provider),
|
|
3883
3891
|
sessionId: target.sessionId,
|
|
@@ -3932,17 +3940,50 @@ async function executeBrowserPluginActionInternal(
|
|
|
3932
3940
|
};
|
|
3933
3941
|
}, { persistSession: true });
|
|
3934
3942
|
}
|
|
3943
|
+
case 'reconcile_effect': {
|
|
3944
|
+
const effectRequestId = requiredString(input.args.effect_request_id, 'effect_request_id');
|
|
3945
|
+
requiredString(input.args.session_id, 'session_id');
|
|
3946
|
+
const observationArgs = (prefix: 'applied' | 'not_applied'): Record<string, unknown> => ({
|
|
3947
|
+
session_id: input.args.session_id,
|
|
3948
|
+
...(input.args.url !== undefined ? { url: input.args.url } : {}),
|
|
3949
|
+
...(input.args.max_chars !== undefined ? { max_chars: input.args.max_chars } : {}),
|
|
3950
|
+
...(input.args.frame_url !== undefined ? { frame_url: input.args.frame_url } : {}),
|
|
3951
|
+
...(input.args.frame_name !== undefined ? { frame_name: input.args.frame_name } : {}),
|
|
3952
|
+
...(input.args.frame_index !== undefined ? { frame_index: input.args.frame_index } : {}),
|
|
3953
|
+
...(input.args[`${prefix}_url_contains_any`] !== undefined ? { url_contains_any: input.args[`${prefix}_url_contains_any`] } : {}),
|
|
3954
|
+
...(input.args[`${prefix}_url_contains_none`] !== undefined ? { url_contains_none: input.args[`${prefix}_url_contains_none`] } : {}),
|
|
3955
|
+
...(input.args[`${prefix}_text_contains_any`] !== undefined ? { text_contains_any: input.args[`${prefix}_text_contains_any`] } : {}),
|
|
3956
|
+
...(input.args[`${prefix}_text_contains_none`] !== undefined ? { text_contains_none: input.args[`${prefix}_text_contains_none`] } : {}),
|
|
3957
|
+
...(input.args[`${prefix}_selector`] !== undefined ? { selector: input.args[`${prefix}_selector`] } : {}),
|
|
3958
|
+
});
|
|
3959
|
+
const hasCriteria = (args: Record<string, unknown>) => Object.keys(args).some((key) => !['session_id', 'url', 'max_chars', 'frame_url', 'frame_name', 'frame_index'].includes(key));
|
|
3960
|
+
const appliedArgs = observationArgs('applied');
|
|
3961
|
+
if (!hasCriteria(appliedArgs)) throw new AssistantPluginError('PLUGIN_ACTION_ARGUMENT_INVALID', 'reconcile_effect requires at least one applied_* observation criterion.', { retryable: false });
|
|
3962
|
+
const applied = await executeBrowserPluginAction({ ...input, actionId: 'verify_state', args: appliedArgs });
|
|
3963
|
+
if (applied.matched === true) return { effectRequestId, outcome: 'applied', output: applied, observation: applied };
|
|
3964
|
+
const notAppliedArgs = observationArgs('not_applied');
|
|
3965
|
+
if (hasCriteria(notAppliedArgs)) {
|
|
3966
|
+
const notApplied = await executeBrowserPluginAction({ ...input, actionId: 'verify_state', args: notAppliedArgs });
|
|
3967
|
+
if (notApplied.matched === true) return { effectRequestId, outcome: 'not_applied', observation: notApplied };
|
|
3968
|
+
return { effectRequestId, outcome: 'unknown', observation: { applied, notApplied } };
|
|
3969
|
+
}
|
|
3970
|
+
return { effectRequestId, outcome: 'unknown', observation: { applied } };
|
|
3971
|
+
}
|
|
3935
3972
|
case 'verify_state': {
|
|
3936
3973
|
requiredString(input.args.session_id, 'session_id');
|
|
3937
3974
|
const target = resolveActionTarget(input.repoRoot, input.args);
|
|
3938
3975
|
const expectedUrlRaw = stringValue(input.args.expected_url);
|
|
3939
3976
|
const expectedUrl = expectedUrlRaw ? normalizedUrl(expectedUrlRaw) : undefined;
|
|
3940
3977
|
const urlContains = stringValue(input.args.url_contains);
|
|
3978
|
+
const urlContainsAny = stringList(input.args.url_contains_any);
|
|
3979
|
+
const urlContainsNone = stringList(input.args.url_contains_none);
|
|
3941
3980
|
const selector = stringValue(input.args.selector);
|
|
3942
3981
|
const requireVisible = input.args.require_visible === true;
|
|
3943
3982
|
const textContains = stringValue(input.args.text_contains);
|
|
3944
|
-
|
|
3945
|
-
|
|
3983
|
+
const textContainsAny = stringList(input.args.text_contains_any);
|
|
3984
|
+
const textContainsNone = stringList(input.args.text_contains_none);
|
|
3985
|
+
if (!expectedUrl && !urlContains && !urlContainsAny && !urlContainsNone && !selector && !textContains && !textContainsAny && !textContainsNone) {
|
|
3986
|
+
throw new AssistantPluginError('PLUGIN_ACTION_ARGUMENT_INVALID', 'verify_state requires at least one URL, selector, or text criterion.', { retryable: false });
|
|
3946
3987
|
}
|
|
3947
3988
|
if (requireVisible && !selector) {
|
|
3948
3989
|
throw new AssistantPluginError('PLUGIN_ACTION_ARGUMENT_INVALID', 'require_visible requires selector.', { retryable: false });
|
|
@@ -3953,9 +3994,11 @@ async function executeBrowserPluginActionInternal(
|
|
|
3953
3994
|
const checks: Array<Record<string, unknown>> = [];
|
|
3954
3995
|
if (expectedUrl) checks.push({ criterion: 'url_exact', expected: expectedUrl, observed: observedUrl, matched: observedUrl === expectedUrl });
|
|
3955
3996
|
if (urlContains) checks.push({ criterion: 'url_contains', expected: urlContains, observed: observedUrl, matched: observedUrl.includes(urlContains) });
|
|
3997
|
+
if (urlContainsAny) checks.push({ criterion: 'url_contains_any', expected: urlContainsAny, observed: observedUrl, matched: urlContainsAny.some((value) => observedUrl.includes(value)) });
|
|
3998
|
+
if (urlContainsNone) checks.push({ criterion: 'url_contains_none', expected: urlContainsNone, observed: observedUrl, matched: urlContainsNone.every((value) => !observedUrl.includes(value)) });
|
|
3956
3999
|
let observation: { verificationVersion?: unknown; selectorExists?: unknown; visible?: unknown; textContains?: unknown; textSample?: unknown; textLength?: unknown; truncated?: unknown } | undefined;
|
|
3957
|
-
if (selector || textContains) {
|
|
3958
|
-
observation = await selection.scope.evaluate(verifyStateObservationScript(selector, textContains, Math.min(positiveNumber(input.args.max_chars,
|
|
4000
|
+
if (selector || textContains || textContainsAny || textContainsNone) {
|
|
4001
|
+
observation = await selection.scope.evaluate(verifyStateObservationScript(selector, textContains, Math.min(positiveNumber(input.args.max_chars, 12_000), 100_000)));
|
|
3959
4002
|
if (observation?.verificationVersion !== 1) {
|
|
3960
4003
|
throw new AssistantPluginError('PLUGIN_BROWSER_VERIFY_STATE_UNAVAILABLE', 'Browser state observation returned an unsupported result.', { retryable: true });
|
|
3961
4004
|
}
|
|
@@ -3973,6 +4016,9 @@ async function executeBrowserPluginActionInternal(
|
|
|
3973
4016
|
...(selector ? { selector } : {}),
|
|
3974
4017
|
});
|
|
3975
4018
|
}
|
|
4019
|
+
const textSample = typeof observation?.textSample === 'string' ? observation.textSample : '';
|
|
4020
|
+
if (textContainsAny) checks.push({ criterion: 'text_contains_any', expected: textContainsAny, observed: textSample, matched: textContainsAny.some((value) => textSample.includes(value)), textLength: observation?.textLength, truncated: observation?.truncated });
|
|
4021
|
+
if (textContainsNone) checks.push({ criterion: 'text_contains_none', expected: textContainsNone, observed: textSample, matched: textContainsNone.every((value) => !textSample.includes(value)), textLength: observation?.textLength, truncated: observation?.truncated });
|
|
3976
4022
|
return {
|
|
3977
4023
|
provider: browserResultProvider(connection.provider),
|
|
3978
4024
|
sessionId: target.sessionId,
|
|
@@ -4086,15 +4132,16 @@ async function executeBrowserPluginActionInternal(
|
|
|
4086
4132
|
case 'activate_page': {
|
|
4087
4133
|
const target = resolveActionTarget(input.repoRoot, input.args);
|
|
4088
4134
|
return await withPage(input.actionId, input.repoRoot, current, target, input.args, async (page, _diagnostics, connection) => {
|
|
4089
|
-
const waitMs = positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS);
|
|
4090
4135
|
if (connection.provider === 'macos-apple-events') {
|
|
4091
|
-
await establishAuthoritativeNativeForeground(
|
|
4136
|
+
await establishAuthoritativeNativeForeground(
|
|
4137
|
+
input, page, connection, target, browserNativeForegroundVerificationWaitMs(input.args.post_action_wait_ms),
|
|
4138
|
+
);
|
|
4092
4139
|
} else {
|
|
4093
4140
|
if (!page.bringToFront) {
|
|
4094
4141
|
throw new AssistantPluginError('PLUGIN_BROWSER_ACTIVATION_UNSUPPORTED', 'The selected browser provider cannot bring the saved page to the foreground.', { retryable: false });
|
|
4095
4142
|
}
|
|
4096
4143
|
await page.bringToFront();
|
|
4097
|
-
await delay(
|
|
4144
|
+
await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
|
|
4098
4145
|
}
|
|
4099
4146
|
return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'activate_page', 'Activated the exact saved browser page in authoritative foreground state.', {});
|
|
4100
4147
|
});
|
|
@@ -4137,7 +4184,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
4137
4184
|
element.click();
|
|
4138
4185
|
return { tag: element.tagName.toLowerCase(), className: element.className || '', text: normalize(element.innerText || element.textContent || '') };
|
|
4139
4186
|
}, { text });
|
|
4140
|
-
await delay(
|
|
4187
|
+
await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
|
|
4141
4188
|
return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'click_text', `Clicked exact visible text ${text}.`, { text, clicked });
|
|
4142
4189
|
});
|
|
4143
4190
|
}
|
|
@@ -4182,7 +4229,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
4182
4229
|
if (page.uncheck) await page.uncheck(selector, { timeout: timeoutMs });
|
|
4183
4230
|
else await page.click(selector, { timeout: timeoutMs });
|
|
4184
4231
|
}
|
|
4185
|
-
await delay(
|
|
4232
|
+
await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
|
|
4186
4233
|
const summary = input.actionId === 'click'
|
|
4187
4234
|
? `Clicked ${selector}.`
|
|
4188
4235
|
: input.actionId === 'double_click'
|
|
@@ -4213,7 +4260,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
4213
4260
|
return await withPage(input.actionId, input.repoRoot, current, target, input.args, async (page, _diagnostics, connection) => {
|
|
4214
4261
|
if (input.actionId === 'fill' || !page.type) await page.fill(selector, text, { timeout: timeoutMs });
|
|
4215
4262
|
else await page.type(selector, text, { timeout: timeoutMs });
|
|
4216
|
-
await delay(
|
|
4263
|
+
await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
|
|
4217
4264
|
return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, input.actionId, `${input.actionId} ${selector} with ${text.length} characters.`, {
|
|
4218
4265
|
selector,
|
|
4219
4266
|
textLength: text.length,
|
|
@@ -4233,7 +4280,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
4233
4280
|
if (!Array.isArray(selectedValues) || selectedValues.length === 0) {
|
|
4234
4281
|
throw new AssistantPluginError('PLUGIN_BROWSER_SELECT_OPTION_FAILED', 'The browser provider did not retain any requested option selection.', { retryable: true, details: { selector, requestedCount: values.length } });
|
|
4235
4282
|
}
|
|
4236
|
-
await delay(
|
|
4283
|
+
await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
|
|
4237
4284
|
return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'select_option', `Selected ${values.length} option(s) on ${selector}.`, { selector, values, selectedValues });
|
|
4238
4285
|
});
|
|
4239
4286
|
}
|
|
@@ -4243,7 +4290,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
4243
4290
|
const key = requiredString(input.args.key, 'key');
|
|
4244
4291
|
return await withPage(input.actionId, input.repoRoot, current, target, input.args, async (page, _diagnostics, connection) => {
|
|
4245
4292
|
await page.press(selector, key, { timeout: positiveNumber(input.args.timeout_ms, current.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS) });
|
|
4246
|
-
await delay(
|
|
4293
|
+
await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
|
|
4247
4294
|
return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'press', `Pressed ${key} on ${selector}.`, {
|
|
4248
4295
|
selector,
|
|
4249
4296
|
key,
|
|
@@ -4256,7 +4303,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
4256
4303
|
return await withPage(input.actionId, input.repoRoot, current, target, input.args, async (page, _diagnostics, connection) => {
|
|
4257
4304
|
if (page.keyboard?.press) await page.keyboard.press(key);
|
|
4258
4305
|
else await page.press('body', key, { timeout: positiveNumber(input.args.timeout_ms, current.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS) });
|
|
4259
|
-
await delay(
|
|
4306
|
+
await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
|
|
4260
4307
|
return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'keyboard_shortcut', `Pressed shortcut ${key}.`, { key });
|
|
4261
4308
|
});
|
|
4262
4309
|
}
|
|
@@ -4398,7 +4445,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
4398
4445
|
}
|
|
4399
4446
|
}
|
|
4400
4447
|
if (nativeTrustedInput) await page.trustedInput!(trustedRequest);
|
|
4401
|
-
await delay(
|
|
4448
|
+
await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
|
|
4402
4449
|
return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'trusted_input', `Sent trusted browser input (${kind}).`, { kind, ...(guard ? { guard } : {}) });
|
|
4403
4450
|
});
|
|
4404
4451
|
}
|
|
@@ -4418,7 +4465,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
4418
4465
|
const accepted = element.dispatchEvent(domEvent);
|
|
4419
4466
|
return { accepted, defaultPrevented: domEvent.defaultPrevented };
|
|
4420
4467
|
}, { selector, event });
|
|
4421
|
-
await delay(
|
|
4468
|
+
await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
|
|
4422
4469
|
return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'dispatch_event', `Dispatched ${event} on ${selector}.`, {
|
|
4423
4470
|
selector,
|
|
4424
4471
|
event,
|
|
@@ -4488,7 +4535,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
4488
4535
|
throw new AssistantPluginError('PLUGIN_BROWSER_FILE_ATTACH_UNSUPPORTED', 'The selected browser provider does not support local file attachment.', { retryable: false });
|
|
4489
4536
|
}
|
|
4490
4537
|
await page.setInputFiles(selector, resolved.length === 1 ? resolved[0] : resolved);
|
|
4491
|
-
await delay(
|
|
4538
|
+
await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
|
|
4492
4539
|
const fileNames = resolved.map((path) => basename(path));
|
|
4493
4540
|
return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'attach_local_file', `Attached ${resolved.length} local file(s) to ${selector}.`, {
|
|
4494
4541
|
selector,
|
|
@@ -4549,7 +4596,7 @@ async function executeBrowserPluginActionInternal(
|
|
|
4549
4596
|
if (!existsSync(dest)) {
|
|
4550
4597
|
throw new AssistantPluginError('PLUGIN_BROWSER_DOWNLOAD_FAILED', 'Browser download save completed without producing an artifact; refusing false success.', { retryable: true, details: { selector } });
|
|
4551
4598
|
}
|
|
4552
|
-
await delay(
|
|
4599
|
+
await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
|
|
4553
4600
|
return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'await_file_transfer', `Captured download artifact for ${selector}.`, {
|
|
4554
4601
|
selector,
|
|
4555
4602
|
download: {
|
|
@@ -4588,10 +4635,3 @@ export async function executeBrowserPluginAction(input: AssistantPluginActionExe
|
|
|
4588
4635
|
() => executeBrowserPluginActionInternal(input),
|
|
4589
4636
|
);
|
|
4590
4637
|
}
|
|
4591
|
-
|
|
4592
|
-
export const browserPluginAdapter = {
|
|
4593
|
-
pluginId: BROWSER_PLUGIN_ID,
|
|
4594
|
-
buildManifest: buildBrowserPluginManifest,
|
|
4595
|
-
executeAction: executeBrowserPluginAction,
|
|
4596
|
-
resolveAuthorizationContext: resolveBrowserPluginAuthorizationContext,
|
|
4597
|
-
};
|
|
@@ -1,45 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {
|
|
2
|
+
ComputerBrowserAutomationRequest,
|
|
3
|
+
ComputerBrowserProduct,
|
|
4
|
+
ComputerBrowserTabRef,
|
|
5
|
+
ComputerCaptureRegion,
|
|
6
|
+
ComputerTrustedInput,
|
|
7
|
+
} from '../../../packages/protocols/computer/index';
|
|
8
|
+
import { executeRuntimeComputerBrowserAutomation } from '../root/computer-composition';
|
|
2
9
|
import { AssistantPluginError } from './errors';
|
|
3
10
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export type
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
tabId: string;
|
|
10
|
-
}
|
|
11
|
-
export interface BrowserAutomationRegion {
|
|
12
|
-
x: number;
|
|
13
|
-
y: number;
|
|
14
|
-
width: number;
|
|
15
|
-
height: number;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export type BrowserAutomationTrustedInput =
|
|
19
|
-
| { kind: 'click'; x: number; y: number; button: 'left' | 'middle' | 'right'; clickCount: number }
|
|
20
|
-
| { kind: 'move'; x: number; y: number; steps: number }
|
|
21
|
-
| { kind: 'wheel'; deltaX: number; deltaY: number }
|
|
22
|
-
| { kind: 'drag'; fromX: number; fromY: number; toX: number; toY: number; button: 'left' | 'middle' | 'right'; steps: number }
|
|
23
|
-
| { kind: 'key'; key: string }
|
|
24
|
-
| { kind: 'text'; text: string };
|
|
25
|
-
|
|
26
|
-
export type BrowserAutomationBrokerAction =
|
|
27
|
-
| { action: 'metadata'; product: BrowserAutomationProduct; ref?: BrowserAutomationTabRef }
|
|
28
|
-
| { action: 'list_tabs'; product: BrowserAutomationProduct }
|
|
29
|
-
| { action: 'create_tab'; product: BrowserAutomationProduct; url: string }
|
|
30
|
-
| { action: 'close_tab'; product: BrowserAutomationProduct; ref: BrowserAutomationTabRef }
|
|
31
|
-
| { action: 'navigate'; product: BrowserAutomationProduct; ref?: BrowserAutomationTabRef; url: string }
|
|
32
|
-
| { action: 'reload'; product: BrowserAutomationProduct; ref?: BrowserAutomationTabRef }
|
|
33
|
-
| { action: 'execute_javascript'; product: BrowserAutomationProduct; ref?: BrowserAutomationTabRef; source: string }
|
|
34
|
-
| { action: 'activate'; product: BrowserAutomationProduct; ref?: BrowserAutomationTabRef }
|
|
35
|
-
| { action: 'trusted_input'; product: BrowserAutomationProduct; ref: BrowserAutomationTabRef; input: BrowserAutomationTrustedInput }
|
|
36
|
-
| { action: 'capture_region'; region: BrowserAutomationRegion };
|
|
11
|
+
export type BrowserAutomationProduct = ComputerBrowserProduct;
|
|
12
|
+
export type BrowserAutomationTabRef = ComputerBrowserTabRef;
|
|
13
|
+
export type BrowserAutomationRegion = ComputerCaptureRegion;
|
|
14
|
+
export type BrowserAutomationTrustedInput = ComputerTrustedInput;
|
|
15
|
+
export type BrowserAutomationBrokerAction = ComputerBrowserAutomationRequest;
|
|
37
16
|
|
|
38
17
|
export async function callBrowserAutomationBroker(
|
|
39
18
|
request: BrowserAutomationBrokerAction,
|
|
40
19
|
timeoutMs: number,
|
|
41
20
|
): Promise<Record<string, unknown>> {
|
|
42
|
-
return await
|
|
21
|
+
return await executeRuntimeComputerBrowserAutomation(request, timeoutMs);
|
|
43
22
|
}
|
|
44
23
|
|
|
45
24
|
export async function captureBrowserAutomationRegion(region: BrowserAutomationRegion, timeoutMs: number): Promise<Buffer> {
|
|
@@ -48,7 +27,7 @@ export async function captureBrowserAutomationRegion(region: BrowserAutomationRe
|
|
|
48
27
|
if (!base64) {
|
|
49
28
|
throw new AssistantPluginError(
|
|
50
29
|
'PLUGIN_MACOS_CAPABILITY_BROKER_PROTOCOL_ERROR',
|
|
51
|
-
'
|
|
30
|
+
'Computer capture provider returned an invalid screenshot payload.',
|
|
52
31
|
{ retryable: true },
|
|
53
32
|
);
|
|
54
33
|
}
|