@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
|
@@ -2,28 +2,34 @@ import { createHash } from 'crypto';
|
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import type { RepositoryRecord } from '../../cli/repositories/types';
|
|
4
4
|
import { CONTROLLER_SCOPE_REPO_ID, controllerSystemRoot, ensureControllerHome, repositoryControllerRoot } from '../../cli/repositories/controller-home';
|
|
5
|
-
import { existsSync, mkdirSync, readdirSync, rmSync } from 'fs';
|
|
5
|
+
import { cpSync, existsSync, lstatSync, mkdirSync, readdirSync, rmSync } from 'fs';
|
|
6
6
|
import type { ExecutionJob, ResourceClaimSpec } from '../execution/jobs/types';
|
|
7
7
|
import { appendRuntimeEvent } from '../evidence/event-ledger';
|
|
8
8
|
import { readJsonFile, sanitizeFileComponent, writeJsonAtomic } from '../shared/json-files';
|
|
9
9
|
import { createFirstPartyPluginAdapterMap } from './first-party-registry';
|
|
10
|
+
import { reconcileFirstPartyExternalPluginRegistration, reconcileFirstPartyExternalPluginRegistrations } from './first-party-external-registration';
|
|
11
|
+
import { REPOSITORY_PLUGIN_CONFIG_IDS, repositoryPluginConfigFileName, repositoryPluginConfigPath } from './config-store';
|
|
10
12
|
import { getExternalPluginAdapter, listExternalPluginAdapters } from './external-adapter';
|
|
11
|
-
import { AssistantPluginError, toAssistantPluginError } from './errors';
|
|
13
|
+
import { AssistantPluginError, isAssistantPluginError, toAssistantPluginError, type AssistantPluginEffectOutcome } from './errors';
|
|
12
14
|
import {
|
|
15
|
+
findActivePluginCapabilityAuthorizationById,
|
|
13
16
|
findActivePluginCapabilityAuthorization,
|
|
14
17
|
pluginCapabilityAuthorizationOwnerScope,
|
|
15
18
|
recordPluginCapabilityAuthorization,
|
|
16
19
|
type PluginCapabilityAuthorizationGrant,
|
|
17
20
|
} from './capability-authorization-grants';
|
|
18
21
|
import { markControllerContextProjectionDirty } from '../projections/controller-context';
|
|
22
|
+
import { acquireExecutionLeases, releaseExactExecutionLeases } from '../resources/leases/store';
|
|
19
23
|
import { classifyRepositoryCommand } from '../../cli/repositories/command-classifier';
|
|
20
24
|
import {
|
|
21
25
|
acceptSubmittedWorkContract,
|
|
26
|
+
activateWorkContract,
|
|
22
27
|
appendWorkEvidence,
|
|
28
|
+
failWorkContract,
|
|
23
29
|
getWorkContract,
|
|
24
30
|
recordWorkCompletionReceipt,
|
|
25
31
|
updateWorkContract,
|
|
26
|
-
} from '
|
|
32
|
+
} from '../../../packages/kernel/work/api/index';
|
|
27
33
|
import { isTerminalWorkContractStatus, type LocalEffectCompletionReceipt, type RemoteEffectCompletionReceipt, type WorkContract, type WorkRisk } from '../control-plane/facade/types';
|
|
28
34
|
import type {
|
|
29
35
|
AssistantPluginAdapter,
|
|
@@ -43,8 +49,10 @@ function resolvePluginAdapter(controllerHome: string, pluginId: string): Assista
|
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
function listPluginAdapters(controllerHome: string): AssistantPluginAdapter[] {
|
|
46
|
-
const
|
|
47
|
-
|
|
52
|
+
const firstParty = [...PLUGIN_ADAPTERS.values()].filter((adapter) => adapter.exposure !== 'internal');
|
|
53
|
+
const external = listExternalPluginAdapters(controllerHome)
|
|
54
|
+
.filter((adapter) => !PLUGIN_ADAPTERS.has(adapter.pluginId) && adapter.exposure !== 'internal');
|
|
55
|
+
return [...firstParty, ...external];
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
export function assistantPluginScope(pluginId: string, controllerHome?: string): AssistantPluginAdapter['scope'] | undefined {
|
|
@@ -89,6 +97,39 @@ export function controllerPluginRepository(controllerHome: string): RepositoryRe
|
|
|
89
97
|
};
|
|
90
98
|
}
|
|
91
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Controller-scoped product facade. The synthetic RepositoryRecord remains an
|
|
102
|
+
* internal storage/projection compatibility shape only; callers need no repo.
|
|
103
|
+
*/
|
|
104
|
+
export function readControllerStoredPluginManifest(controllerHome: string, pluginId: string): AssistantPluginManifest | undefined {
|
|
105
|
+
return readStoredAssistantPluginManifest(controllerHome, controllerPluginRepository(controllerHome), pluginId);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function listControllerPluginManifests(
|
|
109
|
+
controllerHome: string,
|
|
110
|
+
options: ListAssistantPluginManifestsOptions = {},
|
|
111
|
+
): AssistantPluginManifest[] {
|
|
112
|
+
return listAssistantPluginManifests(controllerHome, controllerPluginRepository(controllerHome), options);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function getControllerPluginManifest(controllerHome: string, pluginId: string): AssistantPluginManifest {
|
|
116
|
+
return getAssistantPluginManifest(controllerHome, controllerPluginRepository(controllerHome), pluginId);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function syncControllerPluginRegistry(controllerHome: string) {
|
|
120
|
+
reconcileFirstPartyExternalPluginRegistrations(controllerHome);
|
|
121
|
+
return syncAssistantPluginRegistry(controllerHome, controllerPluginRepository(controllerHome));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function syncControllerPluginManifest(controllerHome: string, pluginId: string) {
|
|
125
|
+
reconcileFirstPartyExternalPluginRegistration(controllerHome, pluginId);
|
|
126
|
+
return syncAssistantPluginManifest(controllerHome, controllerPluginRepository(controllerHome), pluginId);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function removeControllerPluginManifestProjection(controllerHome: string, pluginId: string) {
|
|
130
|
+
return removeAssistantPluginManifestProjection(controllerHome, controllerPluginRepository(controllerHome), pluginId);
|
|
131
|
+
}
|
|
132
|
+
|
|
92
133
|
function adapterMatchesRepository(adapter: AssistantPluginAdapter, repository: RepositoryRecord): boolean {
|
|
93
134
|
const scope = adapter.scope ?? 'repository';
|
|
94
135
|
if (scope === 'controller_with_repository_overlay') return true;
|
|
@@ -99,8 +140,9 @@ function cloneCacheValue<T>(value: T): T {
|
|
|
99
140
|
return structuredClone(value);
|
|
100
141
|
}
|
|
101
142
|
|
|
102
|
-
function listCacheKey(controllerHome: string, repoId: string, preferStored: boolean): string {
|
|
103
|
-
|
|
143
|
+
function listCacheKey(controllerHome: string, repoId: string, preferStored: boolean, fallbackToLive: boolean): string {
|
|
144
|
+
const mode = preferStored ? (fallbackToLive ? 'stored-with-live-fallback' : 'stored-only') : 'live';
|
|
145
|
+
return `${controllerHome}::${repoId}::list::${mode}`;
|
|
104
146
|
}
|
|
105
147
|
|
|
106
148
|
function itemCacheKey(controllerHome: string, repoId: string, pluginId: string, preferStored: boolean): string {
|
|
@@ -236,6 +278,15 @@ function readStoredManifest(controllerHome: string, repoId: string, pluginId: st
|
|
|
236
278
|
}
|
|
237
279
|
}
|
|
238
280
|
|
|
281
|
+
/** Read-only persisted plugin projection. This never probes or rebuilds a provider manifest. */
|
|
282
|
+
export function readStoredAssistantPluginManifest(
|
|
283
|
+
controllerHome: string,
|
|
284
|
+
repository: RepositoryRecord,
|
|
285
|
+
pluginId: string,
|
|
286
|
+
): AssistantPluginManifest | undefined {
|
|
287
|
+
return readStoredManifest(controllerHome, repository.repoId, pluginId);
|
|
288
|
+
}
|
|
289
|
+
|
|
239
290
|
function cachedManifestForRepository(
|
|
240
291
|
controllerHome: string,
|
|
241
292
|
repoId: string,
|
|
@@ -248,12 +299,48 @@ function cachedManifestForRepository(
|
|
|
248
299
|
) ?? readPluginManifestCache(pluginManifestItemCache, itemCacheKey(controllerHome, repoId, pluginId, false));
|
|
249
300
|
}
|
|
250
301
|
|
|
302
|
+
export function migrateRepositoryPluginConfigLegacyFiles(
|
|
303
|
+
controllerHome: string,
|
|
304
|
+
repository: Pick<RepositoryRecord, 'repoId' | 'canonicalRoot'>,
|
|
305
|
+
): string {
|
|
306
|
+
const targetRoot = join(repositoryControllerRoot(controllerHome, repository.repoId), 'plugins', 'config');
|
|
307
|
+
const legacyRoots = [
|
|
308
|
+
join(repository.canonicalRoot, '.forge', 'plugins'),
|
|
309
|
+
join(repository.canonicalRoot, '.repo-harness', 'plugins'),
|
|
310
|
+
];
|
|
311
|
+
mkdirSync(targetRoot, { recursive: true });
|
|
312
|
+
for (const legacyRoot of legacyRoots) {
|
|
313
|
+
if (!existsSync(legacyRoot)) continue;
|
|
314
|
+
const stat = lstatSync(legacyRoot);
|
|
315
|
+
// Historical compatibility symlinks may point at another Controller Home.
|
|
316
|
+
// Never traverse them; unlink only the retired repository-local compatibility entry.
|
|
317
|
+
if (stat.isSymbolicLink()) {
|
|
318
|
+
rmSync(legacyRoot, { force: true });
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (!stat.isDirectory()) throw new Error(`PLUGIN_CONFIG_LEGACY_PATH_INVALID: ${legacyRoot}`);
|
|
322
|
+
for (const pluginId of REPOSITORY_PLUGIN_CONFIG_IDS) {
|
|
323
|
+
const fileName = repositoryPluginConfigFileName(pluginId);
|
|
324
|
+
const source = join(legacyRoot, fileName);
|
|
325
|
+
if (!existsSync(source)) continue;
|
|
326
|
+
const sourceStat = lstatSync(source);
|
|
327
|
+
if (sourceStat.isSymbolicLink() || !sourceStat.isFile()) continue;
|
|
328
|
+
const target = repositoryPluginConfigPath({ controllerHome, repoId: repository.repoId }, pluginId);
|
|
329
|
+
if (!existsSync(target)) cpSync(source, target, { force: false, errorOnExist: false });
|
|
330
|
+
rmSync(source, { force: true });
|
|
331
|
+
}
|
|
332
|
+
if (readdirSync(legacyRoot).length === 0) rmSync(legacyRoot, { recursive: true, force: true });
|
|
333
|
+
}
|
|
334
|
+
return targetRoot;
|
|
335
|
+
}
|
|
336
|
+
|
|
251
337
|
function computeManifest(
|
|
252
338
|
controllerHome: string,
|
|
253
339
|
repository: RepositoryRecord,
|
|
254
340
|
pluginId: string,
|
|
255
341
|
resolvedAdapter?: AssistantPluginAdapter,
|
|
256
342
|
): AssistantPluginManifest {
|
|
343
|
+
migrateRepositoryPluginConfigLegacyFiles(controllerHome, repository);
|
|
257
344
|
const adapter = resolvedAdapter ?? resolvePluginAdapter(controllerHome, pluginId);
|
|
258
345
|
if (!adapter || !adapterMatchesRepository(adapter, repository)) throw new Error(`PLUGIN_NOT_FOUND: ${pluginId}`);
|
|
259
346
|
const previous = readStoredManifest(controllerHome, repository.repoId, pluginId);
|
|
@@ -307,6 +394,71 @@ export function claimsForAssistantPluginAction(
|
|
|
307
394
|
}));
|
|
308
395
|
}
|
|
309
396
|
|
|
397
|
+
async function withAssistantPluginResourceLeases<T>(
|
|
398
|
+
controllerHome: string,
|
|
399
|
+
repository: RepositoryRecord,
|
|
400
|
+
action: AssistantPluginActionDescriptor,
|
|
401
|
+
request: AssistantPluginActionRequest,
|
|
402
|
+
operation: () => Promise<T>,
|
|
403
|
+
): Promise<T> {
|
|
404
|
+
const claims = claimsForAssistantPluginAction(action, repository, request.pluginId).map((claim) => ({
|
|
405
|
+
...claim,
|
|
406
|
+
repoId: repository.repoId,
|
|
407
|
+
checkoutId: repository.activeCheckoutId,
|
|
408
|
+
}));
|
|
409
|
+
if (claims.length === 0) return operation();
|
|
410
|
+
|
|
411
|
+
const ownerJobId = `plugin:${request.requestId}`;
|
|
412
|
+
const timeoutMs = Math.max(5_000, Math.min(10 * 60_000, request.timeoutMs ?? action.defaultTimeoutMs));
|
|
413
|
+
const acquisition = acquireExecutionLeases(controllerHome, repository.repoId, ownerJobId, claims, {
|
|
414
|
+
ttlMs: timeoutMs + 60_000,
|
|
415
|
+
ownerIdentity: {
|
|
416
|
+
repositoryId: repository.repoId,
|
|
417
|
+
checkoutId: repository.activeCheckoutId,
|
|
418
|
+
worktreeId: repository.activeCheckoutId,
|
|
419
|
+
branch: 'workflow-plugin-action',
|
|
420
|
+
principalId: request.origin.actor?.trim() || 'workflow-plugin-action',
|
|
421
|
+
controllerInstanceId: process.env.FORGE_RUNTIME_INSTANCE_ID?.trim()
|
|
422
|
+
|| process.env.FORGE_WRITER_INSTANCE_ID?.trim()
|
|
423
|
+
|| process.env.FORGE_DAEMON_INSTANCE_ID?.trim()
|
|
424
|
+
|| `process:${process.pid}`,
|
|
425
|
+
controllerGeneration: process.env.FORGE_WRITER_GENERATION?.trim()
|
|
426
|
+
|| process.env.FORGE_ACTIVE_RUNTIME_REVISION?.trim()
|
|
427
|
+
|| 'unbound',
|
|
428
|
+
},
|
|
429
|
+
});
|
|
430
|
+
if (!acquisition.acquired) {
|
|
431
|
+
throw new AssistantPluginError(
|
|
432
|
+
'PLUGIN_RESOURCE_CONTENTION',
|
|
433
|
+
`${request.pluginId}/${request.actionId} could not acquire its declared resource claims before dispatch.`,
|
|
434
|
+
{ retryable: true, details: { blockers: acquisition.blockers } },
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
const expected = acquisition.leases.map((lease) => ({
|
|
438
|
+
leaseId: lease.leaseId,
|
|
439
|
+
fencingToken: lease.fencingToken,
|
|
440
|
+
repoId: lease.repoId,
|
|
441
|
+
checkoutId: lease.checkoutId,
|
|
442
|
+
resourceKey: lease.resourceKey,
|
|
443
|
+
ownerIdentityDigest: lease.ownerIdentityDigest,
|
|
444
|
+
}));
|
|
445
|
+
let retainForReconciliation = false;
|
|
446
|
+
try {
|
|
447
|
+
const result = await operation();
|
|
448
|
+
const nestedResult = result && typeof result === 'object' && !Array.isArray(result)
|
|
449
|
+
? (result as Record<string, unknown>).result
|
|
450
|
+
: undefined;
|
|
451
|
+
retainForReconciliation = Boolean(nestedResult && typeof nestedResult === 'object' && !Array.isArray(nestedResult)
|
|
452
|
+
&& (nestedResult as Record<string, unknown>).outcome === 'outcome_unknown');
|
|
453
|
+
return result;
|
|
454
|
+
} catch (error) {
|
|
455
|
+
retainForReconciliation = isAssistantPluginError(error) && error.effectOutcome === 'outcome_unknown';
|
|
456
|
+
throw error;
|
|
457
|
+
} finally {
|
|
458
|
+
if (!retainForReconciliation) releaseExactExecutionLeases(controllerHome, repository.repoId, ownerJobId, expected);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
310
462
|
function semanticKey(repository: RepositoryRecord, pluginId: string, actionId: string, args: Record<string, unknown>): string {
|
|
311
463
|
const digest = createHash('sha256').update(JSON.stringify(canonical(args))).digest('hex').slice(0, 20);
|
|
312
464
|
return `plugin-action:${repository.repoId}:${pluginId}:${actionId}:${digest}`;
|
|
@@ -408,6 +560,92 @@ function originMayEstablishCapabilityAuthorization(origin: AssistantPluginAction
|
|
|
408
560
|
return INTERACTIVE_PLUGIN_AUTHORIZATION_SURFACES.has(origin.surface);
|
|
409
561
|
}
|
|
410
562
|
|
|
563
|
+
function requiresAutomatedWriteAuthorization(origin: AssistantPluginActionExecutionInput['origin']): boolean {
|
|
564
|
+
return ['schedule', 'reconciliation', 'system'].includes(origin.surface);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
const AUTHORIZATION_RISK_RANK: Record<AssistantPluginActionDescriptor['risk'], number> = {
|
|
568
|
+
readonly: 0,
|
|
569
|
+
workspace_write: 1,
|
|
570
|
+
remote_write: 2,
|
|
571
|
+
destructive: 3,
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
function authorizationTargetMatches(
|
|
575
|
+
left: PluginCapabilityAuthorizationGrant['target'],
|
|
576
|
+
right: PluginCapabilityAuthorizationGrant['target'],
|
|
577
|
+
): boolean {
|
|
578
|
+
return left.kind === right.kind
|
|
579
|
+
&& left.id === right.id
|
|
580
|
+
&& (left.identityFingerprint ?? '') === (right.identityFingerprint ?? '');
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
async function resolveAutomatedWriteAuthorization(input: {
|
|
584
|
+
controllerHome: string;
|
|
585
|
+
repository: RepositoryRecord;
|
|
586
|
+
adapter: AssistantPluginAdapter;
|
|
587
|
+
manifest: AssistantPluginManifest;
|
|
588
|
+
action: AssistantPluginActionDescriptor;
|
|
589
|
+
args: Record<string, unknown>;
|
|
590
|
+
origin: AssistantPluginActionExecutionInput['origin'];
|
|
591
|
+
requestId: string;
|
|
592
|
+
jobId?: string;
|
|
593
|
+
authorizationGrantRefs?: readonly string[];
|
|
594
|
+
}): Promise<PluginCapabilityAuthorizationGrant | undefined> {
|
|
595
|
+
if (input.action.readOnly) return undefined;
|
|
596
|
+
if (input.action.confirmation === 'strong_confirmation') {
|
|
597
|
+
throw new AssistantPluginError(
|
|
598
|
+
'EXTERNAL_EFFECT_AUTHORIZATION_REQUIRED',
|
|
599
|
+
`${input.manifest.pluginId}/${input.action.actionId} requires an interactive strong confirmation.`,
|
|
600
|
+
{ retryable: false },
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
const refs = [...new Set((input.authorizationGrantRefs ?? []).map((ref) => ref.trim()).filter(Boolean))];
|
|
604
|
+
if (refs.length === 0 || !input.adapter.resolveAuthorizationContext) {
|
|
605
|
+
throw new AssistantPluginError(
|
|
606
|
+
'EXTERNAL_EFFECT_AUTHORIZATION_REQUIRED',
|
|
607
|
+
`${input.manifest.pluginId}/${input.action.actionId} requires an active Workflow capability grant.`,
|
|
608
|
+
{ retryable: false },
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
const targetContext = await input.adapter.resolveAuthorizationContext({
|
|
612
|
+
controllerHome: input.controllerHome,
|
|
613
|
+
repoId: input.repository.repoId,
|
|
614
|
+
repoRoot: input.repository.canonicalRoot,
|
|
615
|
+
pluginId: input.manifest.pluginId,
|
|
616
|
+
actionId: input.action.actionId,
|
|
617
|
+
requestId: input.requestId,
|
|
618
|
+
args: input.args,
|
|
619
|
+
origin: input.origin,
|
|
620
|
+
jobId: input.jobId,
|
|
621
|
+
});
|
|
622
|
+
if (!targetContext) {
|
|
623
|
+
throw new AssistantPluginError(
|
|
624
|
+
'PLUGIN_CAPABILITY_GRANT_TARGET_UNAVAILABLE',
|
|
625
|
+
`${input.manifest.pluginId}/${input.action.actionId} did not resolve an exact authorization target.`,
|
|
626
|
+
{ retryable: false },
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
const capabilityId = reusableCapabilityId(input.manifest, input.action);
|
|
630
|
+
const grant = refs
|
|
631
|
+
.map((ref) => findActivePluginCapabilityAuthorizationById(input.controllerHome, ref))
|
|
632
|
+
.find((candidate) => candidate
|
|
633
|
+
&& candidate.repoId === input.repository.repoId
|
|
634
|
+
&& candidate.pluginId === input.manifest.pluginId
|
|
635
|
+
&& candidate.capabilityId === capabilityId
|
|
636
|
+
&& authorizationTargetMatches(candidate.target, targetContext.target)
|
|
637
|
+
&& input.action.scopes.every((scope) => candidate.scopes.includes(scope))
|
|
638
|
+
&& AUTHORIZATION_RISK_RANK[candidate.riskCeiling] >= AUTHORIZATION_RISK_RANK[input.action.risk]);
|
|
639
|
+
if (!grant) {
|
|
640
|
+
throw new AssistantPluginError(
|
|
641
|
+
'PLUGIN_CAPABILITY_GRANT_NOT_FOUND',
|
|
642
|
+
`${input.manifest.pluginId}/${input.action.actionId} has no active grant for this exact target.`,
|
|
643
|
+
{ retryable: false },
|
|
644
|
+
);
|
|
645
|
+
}
|
|
646
|
+
return grant;
|
|
647
|
+
}
|
|
648
|
+
|
|
411
649
|
function authorizationTargetSummary(context: AssistantPluginAuthorizationContext): { kind: string; id: string } {
|
|
412
650
|
return { kind: context.target.kind, id: context.target.id };
|
|
413
651
|
}
|
|
@@ -429,19 +667,15 @@ function initialAuthorizationEvidence(
|
|
|
429
667
|
return { source: 'host_permission_model', reusable: false, capabilityId };
|
|
430
668
|
}
|
|
431
669
|
|
|
432
|
-
function denyAutomatedWrite(manifest: AssistantPluginManifest, action: AssistantPluginActionDescriptor, origin: AssistantPluginActionExecutionInput['origin']): void {
|
|
433
|
-
if (!['schedule', 'reconciliation', 'system'].includes(origin.surface)) return;
|
|
434
|
-
if (action.readOnly) return;
|
|
435
|
-
throw new Error(`EXTERNAL_EFFECT_AUTHORIZATION_REQUIRED: ${manifest.pluginId}/${action.actionId} cannot run from ${origin.surface}`);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
670
|
export type ListAssistantPluginManifestsOptions = {
|
|
439
671
|
/**
|
|
440
672
|
* Prefer previously persisted manifests for connector/status hot paths.
|
|
441
673
|
* Live adapter rebuild (including host probes such as Xcode) runs only when
|
|
442
|
-
* no stored manifest exists, or when forceRefresh is true.
|
|
674
|
+
* no stored manifest exists, unless fallbackToLive=false, or when forceRefresh is true.
|
|
443
675
|
*/
|
|
444
676
|
preferStored?: boolean;
|
|
677
|
+
/** Materialized projections set this false so a cold summary never synchronously probes providers. */
|
|
678
|
+
fallbackToLive?: boolean;
|
|
445
679
|
forceRefresh?: boolean;
|
|
446
680
|
};
|
|
447
681
|
|
|
@@ -458,7 +692,8 @@ export function listAssistantPluginManifests(
|
|
|
458
692
|
options: ListAssistantPluginManifestsOptions = {},
|
|
459
693
|
): AssistantPluginManifest[] {
|
|
460
694
|
const preferStored = options.preferStored === true && options.forceRefresh !== true;
|
|
461
|
-
const
|
|
695
|
+
const fallbackToLive = options.fallbackToLive !== false || !preferStored;
|
|
696
|
+
const cacheKey = listCacheKey(controllerHome, repository.repoId, preferStored, fallbackToLive);
|
|
462
697
|
if (options.forceRefresh !== true) {
|
|
463
698
|
// Stored manifests are persisted snapshots. Their freshness is governed by
|
|
464
699
|
// explicit registry/config mutation invalidation, not a wall-clock trust
|
|
@@ -475,9 +710,11 @@ export function listAssistantPluginManifests(
|
|
|
475
710
|
if (preferStored) {
|
|
476
711
|
const stored = readStoredManifest(controllerHome, repository.repoId, pluginId);
|
|
477
712
|
if (stored) return stored;
|
|
713
|
+
if (!fallbackToLive) return undefined;
|
|
478
714
|
}
|
|
479
715
|
return computeManifest(controllerHome, repository, pluginId);
|
|
480
716
|
})
|
|
717
|
+
.filter((manifest): manifest is AssistantPluginManifest => Boolean(manifest))
|
|
481
718
|
.sort((left, right) => left.pluginId.localeCompare(right.pluginId));
|
|
482
719
|
primePluginManifestItemCache(controllerHome, repository.repoId, manifests, preferStored);
|
|
483
720
|
return writePluginManifestCache(pluginManifestListCache, cacheKey, manifests);
|
|
@@ -533,7 +770,7 @@ export function syncAssistantPluginRegistry(
|
|
|
533
770
|
};
|
|
534
771
|
}
|
|
535
772
|
|
|
536
|
-
function syncAssistantPluginManifest(
|
|
773
|
+
export function syncAssistantPluginManifest(
|
|
537
774
|
controllerHome: string,
|
|
538
775
|
repository: RepositoryRecord,
|
|
539
776
|
pluginId: string,
|
|
@@ -558,6 +795,29 @@ function syncAssistantPluginManifest(
|
|
|
558
795
|
};
|
|
559
796
|
}
|
|
560
797
|
|
|
798
|
+
/** Remove one persisted plugin projection without probing or rebuilding unrelated providers. */
|
|
799
|
+
export function removeAssistantPluginManifestProjection(
|
|
800
|
+
controllerHome: string,
|
|
801
|
+
repository: RepositoryRecord,
|
|
802
|
+
pluginId: string,
|
|
803
|
+
): AssistantPluginRegistryIndex {
|
|
804
|
+
invalidateAssistantPluginManifestCache(controllerHome, repository.repoId, pluginId);
|
|
805
|
+
rmSync(manifestPath(controllerHome, repository.repoId, pluginId), { force: true });
|
|
806
|
+
const current = readJsonFile<AssistantPluginRegistryIndex>(indexPath(controllerHome, repository.repoId), {
|
|
807
|
+
schemaVersion: 1,
|
|
808
|
+
updatedAt: now(),
|
|
809
|
+
plugins: [],
|
|
810
|
+
});
|
|
811
|
+
const next: AssistantPluginRegistryIndex = {
|
|
812
|
+
...current,
|
|
813
|
+
updatedAt: now(),
|
|
814
|
+
plugins: current.plugins.filter((entry) => entry.pluginId !== pluginId),
|
|
815
|
+
};
|
|
816
|
+
writeJsonAtomic(indexPath(controllerHome, repository.repoId), next);
|
|
817
|
+
markControllerContextProjectionDirty(repository.canonicalRoot, `plugin:${pluginId}:removed`);
|
|
818
|
+
return next;
|
|
819
|
+
}
|
|
820
|
+
|
|
561
821
|
export function isDirectPluginReadAction(action: AssistantPluginActionDescriptor): boolean {
|
|
562
822
|
return action.readOnly === true
|
|
563
823
|
&& action.risk === 'readonly'
|
|
@@ -565,6 +825,76 @@ export function isDirectPluginReadAction(action: AssistantPluginActionDescriptor
|
|
|
565
825
|
&& action.idempotent === true;
|
|
566
826
|
}
|
|
567
827
|
|
|
828
|
+
export function isDirectNonPersistentPluginAction(action: AssistantPluginActionDescriptor): boolean {
|
|
829
|
+
return action.executionMode === 'direct_non_persistent'
|
|
830
|
+
&& action.readOnly === false
|
|
831
|
+
&& action.risk === 'workspace_write'
|
|
832
|
+
&& action.confirmation === 'authorization'
|
|
833
|
+
&& action.idempotent === false
|
|
834
|
+
&& action.remoteEffectWorkCompletion === undefined
|
|
835
|
+
&& action.resourceClaims.length === 0;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
export async function executeAssistantPluginDirectNonPersistent(
|
|
839
|
+
controllerHome: string,
|
|
840
|
+
repository: RepositoryRecord,
|
|
841
|
+
request: AssistantPluginActionRequest,
|
|
842
|
+
): Promise<{ manifest: AssistantPluginManifest; action: AssistantPluginActionDescriptor; result: Record<string, unknown> }> {
|
|
843
|
+
const adapter = resolvePluginAdapter(controllerHome, request.pluginId);
|
|
844
|
+
if (!adapter) throw new Error(`PLUGIN_NOT_FOUND: ${request.pluginId}`);
|
|
845
|
+
if (PLUGIN_ADAPTERS.get(request.pluginId) !== adapter) {
|
|
846
|
+
throw new Error(`PLUGIN_DIRECT_NON_PERSISTENT_FIRST_PARTY_REQUIRED: ${request.pluginId}/${request.actionId}`);
|
|
847
|
+
}
|
|
848
|
+
const manifestLookup = getAssistantPluginManifestForExecution(controllerHome, repository, request.pluginId, adapter);
|
|
849
|
+
const manifest = manifestLookup.manifest;
|
|
850
|
+
const action = actionForManifest(manifest, request.actionId);
|
|
851
|
+
if (!manifest.enabled && action.actionId !== 'configure') {
|
|
852
|
+
throw new Error(`PLUGIN_DISABLED: ${request.pluginId} is disabled`);
|
|
853
|
+
}
|
|
854
|
+
if (action.executionMode !== 'direct_non_persistent') {
|
|
855
|
+
throw new Error(`PLUGIN_DIRECT_NON_PERSISTENT_NOT_ALLOWED: ${request.pluginId}/${request.actionId}`);
|
|
856
|
+
}
|
|
857
|
+
if (!isDirectNonPersistentPluginAction(action)) {
|
|
858
|
+
throw new Error(`PLUGIN_DIRECT_NON_PERSISTENT_CONTRACT_INVALID: ${request.pluginId}/${request.actionId}`);
|
|
859
|
+
}
|
|
860
|
+
if (request.workId || request.workRepoId) {
|
|
861
|
+
throw new Error(`PLUGIN_DIRECT_NON_PERSISTENT_WORK_ATTRIBUTION_FORBIDDEN: ${request.pluginId}/${request.actionId}`);
|
|
862
|
+
}
|
|
863
|
+
if (request.confirmAuthorization !== true) {
|
|
864
|
+
throw new Error(`PLUGIN_DIRECT_NON_PERSISTENT_AUTHORIZATION_REQUIRED: ${request.pluginId}/${request.actionId} requires confirm_authorization=true for this invocation`);
|
|
865
|
+
}
|
|
866
|
+
const normalizedArgs = validateActionArguments(action, request.args ?? {});
|
|
867
|
+
enforceConfirmation(action, { ...request, args: normalizedArgs });
|
|
868
|
+
if (requiresAutomatedWriteAuthorization(request.origin)) {
|
|
869
|
+
await resolveAutomatedWriteAuthorization({
|
|
870
|
+
controllerHome,
|
|
871
|
+
repository,
|
|
872
|
+
adapter,
|
|
873
|
+
manifest,
|
|
874
|
+
action,
|
|
875
|
+
args: normalizedArgs,
|
|
876
|
+
origin: request.origin,
|
|
877
|
+
requestId: request.requestId,
|
|
878
|
+
authorizationGrantRefs: request.authorizationGrantRefs,
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
const result = await adapter.executeAction({
|
|
882
|
+
controllerHome,
|
|
883
|
+
repoId: repository.repoId,
|
|
884
|
+
repoRoot: repository.canonicalRoot,
|
|
885
|
+
pluginId: request.pluginId,
|
|
886
|
+
actionId: request.actionId,
|
|
887
|
+
requestId: request.requestId,
|
|
888
|
+
args: normalizedArgs,
|
|
889
|
+
origin: request.origin,
|
|
890
|
+
timeoutMs: request.timeoutMs,
|
|
891
|
+
signal: request.signal,
|
|
892
|
+
authorizationGrantRefs: request.authorizationGrantRefs,
|
|
893
|
+
providerIdentityPrevalidated: manifestLookup.providerIdentityPrevalidated,
|
|
894
|
+
});
|
|
895
|
+
return { manifest, action, result };
|
|
896
|
+
}
|
|
897
|
+
|
|
568
898
|
export async function executeAssistantPluginReadDirect(
|
|
569
899
|
controllerHome: string,
|
|
570
900
|
repository: RepositoryRecord,
|
|
@@ -604,6 +934,8 @@ export interface PluginActionReceipt {
|
|
|
604
934
|
actionId: string;
|
|
605
935
|
semanticKey: string;
|
|
606
936
|
status: 'succeeded' | 'failed';
|
|
937
|
+
/** Durable semantic disposition for an attempted external/local effect. */
|
|
938
|
+
effectOutcome?: AssistantPluginEffectOutcome;
|
|
607
939
|
createdAt: string;
|
|
608
940
|
workId?: string;
|
|
609
941
|
origin?: { surface: string; actor?: string; correlationId?: string };
|
|
@@ -661,6 +993,17 @@ export function findPluginActionReceipt(
|
|
|
661
993
|
return undefined;
|
|
662
994
|
}
|
|
663
995
|
|
|
996
|
+
/** Exact request lookup for subordinate Workflow recovery; never dispatches an action. */
|
|
997
|
+
export function readPluginActionReceiptForRequest(controllerHome: string, requestId: string): PluginActionReceipt | undefined {
|
|
998
|
+
const path = pluginActionRequestPath(controllerHome, requestId);
|
|
999
|
+
if (!existsSync(path)) return undefined;
|
|
1000
|
+
const index = readJsonFile<PluginActionRequestIndex>(path);
|
|
1001
|
+
if (index.requestId !== requestId) throw new Error('PLUGIN_RECEIPT_REQUEST_MISMATCH');
|
|
1002
|
+
const receipt = readPluginActionReceipt(controllerHome, index.repoId, index.receiptId);
|
|
1003
|
+
if (!receipt || receipt.requestId !== requestId || receipt.semanticKey !== index.semanticKey) throw new Error('PLUGIN_RECEIPT_LOST');
|
|
1004
|
+
return receipt;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
664
1007
|
export function compatibilityPluginJobFromReceipt(
|
|
665
1008
|
receipt: PluginActionReceipt,
|
|
666
1009
|
checkoutId = 'unknown',
|
|
@@ -914,7 +1257,9 @@ function compatibilityJobFromReceipt(receipt: PluginActionReceipt, checkoutId: s
|
|
|
914
1257
|
repoId: receipt.repoId,
|
|
915
1258
|
checkoutId,
|
|
916
1259
|
type: 'plugin-action',
|
|
917
|
-
status: receipt.
|
|
1260
|
+
status: receipt.effectOutcome === 'outcome_unknown'
|
|
1261
|
+
? 'human_attention_required'
|
|
1262
|
+
: receipt.status === 'succeeded' ? 'succeeded' : 'failed',
|
|
918
1263
|
priority: 'P2',
|
|
919
1264
|
requestId: receipt.requestId,
|
|
920
1265
|
semanticKey: receipt.semanticKey,
|
|
@@ -962,6 +1307,9 @@ export async function submitAssistantPluginAction(
|
|
|
962
1307
|
if (!manifest.enabled && action.actionId !== 'configure') {
|
|
963
1308
|
throw new Error(`PLUGIN_DISABLED: ${request.pluginId} is disabled`);
|
|
964
1309
|
}
|
|
1310
|
+
if (action.executionMode === 'direct_non_persistent') {
|
|
1311
|
+
throw new Error(`PLUGIN_DIRECT_NON_PERSISTENT_RECEIPT_PATH_FORBIDDEN: ${request.pluginId}/${request.actionId}`);
|
|
1312
|
+
}
|
|
965
1313
|
const normalizedArgs = validateActionArguments(action, request.args ?? {});
|
|
966
1314
|
enforceConfirmation(action, { ...request, args: normalizedArgs });
|
|
967
1315
|
|
|
@@ -1009,6 +1357,29 @@ export async function submitAssistantPluginAction(
|
|
|
1009
1357
|
let authorization = initialAuthorizationEvidence(manifest, action);
|
|
1010
1358
|
let authorizationContext: AssistantPluginAuthorizationContext | undefined;
|
|
1011
1359
|
let activeAuthorizationGrant: PluginCapabilityAuthorizationGrant | undefined;
|
|
1360
|
+
if (requiresAutomatedWriteAuthorization(request.origin)) {
|
|
1361
|
+
activeAuthorizationGrant = await resolveAutomatedWriteAuthorization({
|
|
1362
|
+
controllerHome,
|
|
1363
|
+
repository,
|
|
1364
|
+
adapter,
|
|
1365
|
+
manifest,
|
|
1366
|
+
action,
|
|
1367
|
+
args: normalizedArgs,
|
|
1368
|
+
origin: request.origin,
|
|
1369
|
+
requestId: request.requestId,
|
|
1370
|
+
jobId: receiptId,
|
|
1371
|
+
authorizationGrantRefs: request.authorizationGrantRefs,
|
|
1372
|
+
});
|
|
1373
|
+
if (activeAuthorizationGrant) {
|
|
1374
|
+
authorization = {
|
|
1375
|
+
source: 'capability_grant',
|
|
1376
|
+
reusable: true,
|
|
1377
|
+
capabilityId,
|
|
1378
|
+
target: activeAuthorizationGrant.target,
|
|
1379
|
+
grantId: activeAuthorizationGrant.grantId,
|
|
1380
|
+
};
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1012
1383
|
const requiresLocalEffectWork = localSystemActionRequiresWork(
|
|
1013
1384
|
repository,
|
|
1014
1385
|
request.pluginId,
|
|
@@ -1054,12 +1425,15 @@ export async function submitAssistantPluginAction(
|
|
|
1054
1425
|
}).contract
|
|
1055
1426
|
: undefined;
|
|
1056
1427
|
if (acceptedWork) {
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1428
|
+
activateWorkContract(
|
|
1429
|
+
{ controllerHome, repoId: repository.repoId },
|
|
1430
|
+
acceptedWork.workId,
|
|
1431
|
+
{
|
|
1432
|
+
phase: 'implementation',
|
|
1433
|
+
summary: `Controller-local plugin action ${request.pluginId}/${request.actionId} started.`,
|
|
1434
|
+
evidenceState: 'partial',
|
|
1435
|
+
},
|
|
1436
|
+
);
|
|
1063
1437
|
}
|
|
1064
1438
|
appendRuntimeEvent(controllerHome, {
|
|
1065
1439
|
repoId: repository.repoId,
|
|
@@ -1130,22 +1504,29 @@ export async function submitAssistantPluginAction(
|
|
|
1130
1504
|
}
|
|
1131
1505
|
}
|
|
1132
1506
|
|
|
1133
|
-
const result = await
|
|
1507
|
+
const result = await withAssistantPluginResourceLeases(
|
|
1134
1508
|
controllerHome,
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
:
|
|
1148
|
-
|
|
1509
|
+
repository,
|
|
1510
|
+
action,
|
|
1511
|
+
request,
|
|
1512
|
+
() => executeAssistantPluginAction({
|
|
1513
|
+
controllerHome,
|
|
1514
|
+
repoId: repository.repoId,
|
|
1515
|
+
repoRoot: repository.canonicalRoot,
|
|
1516
|
+
pluginId: request.pluginId,
|
|
1517
|
+
actionId: request.actionId,
|
|
1518
|
+
requestId: request.requestId,
|
|
1519
|
+
args: normalizedArgs,
|
|
1520
|
+
origin: request.origin,
|
|
1521
|
+
jobId: receiptId,
|
|
1522
|
+
timeoutMs: request.timeoutMs,
|
|
1523
|
+
signal: request.signal,
|
|
1524
|
+
authorizationGrantRefs: request.authorizationGrantRefs,
|
|
1525
|
+
deadlineAtMs: typeof request.timeoutMs === 'number'
|
|
1526
|
+
? Date.now() + Math.max(1, Math.trunc(request.timeoutMs))
|
|
1527
|
+
: undefined,
|
|
1528
|
+
}),
|
|
1529
|
+
);
|
|
1149
1530
|
if (action.confirmation === 'authorization'
|
|
1150
1531
|
&& authorizationContext
|
|
1151
1532
|
&& !activeAuthorizationGrant
|
|
@@ -1275,27 +1656,46 @@ export async function submitAssistantPluginAction(
|
|
|
1275
1656
|
};
|
|
1276
1657
|
} catch (error) {
|
|
1277
1658
|
const message = error instanceof Error ? error.message : String(error);
|
|
1278
|
-
const code =
|
|
1659
|
+
const code = isAssistantPluginError(error)
|
|
1660
|
+
? error.code
|
|
1661
|
+
: /^([A-Z][A-Z0-9_]+)/.exec(message)?.[1] ?? 'PLUGIN_ACTION_FAILED';
|
|
1662
|
+
const effectOutcome: AssistantPluginEffectOutcome = isAssistantPluginError(error)
|
|
1663
|
+
? error.effectOutcome
|
|
1664
|
+
: 'failed';
|
|
1665
|
+
const outcomeUnknown = effectOutcome === 'outcome_unknown';
|
|
1666
|
+
const outcomeResult = outcomeUnknown
|
|
1667
|
+
? { outcome: 'outcome_unknown', error: { code, message } }
|
|
1668
|
+
: undefined;
|
|
1279
1669
|
if (boundRemoteWork) {
|
|
1280
1670
|
appendWorkEvidence({ controllerHome, repoId: workAttributionRepoId(repository, request) }, boundRemoteWork.workId, {
|
|
1281
|
-
title: 'typed remote plugin effect failed',
|
|
1671
|
+
title: outcomeUnknown ? 'typed remote plugin effect outcome unknown' : 'typed remote plugin effect failed',
|
|
1282
1672
|
summary: `${request.pluginId}/${request.actionId}: ${message}`.slice(0, 1_000),
|
|
1283
1673
|
detailLevel: 'summary',
|
|
1284
1674
|
});
|
|
1285
1675
|
}
|
|
1286
1676
|
if (acceptedWork) {
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
workKind: 'local_effect',
|
|
1291
|
-
dispatchState: 'terminal',
|
|
1292
|
-
evidenceState: 'failed',
|
|
1293
|
-
evidenceRefs: [{
|
|
1294
|
-
title: 'controller-local effect failed',
|
|
1677
|
+
if (outcomeUnknown) {
|
|
1678
|
+
appendWorkEvidence({ controllerHome, repoId: repository.repoId }, acceptedWork.workId, {
|
|
1679
|
+
title: 'controller-local effect outcome unknown',
|
|
1295
1680
|
summary: `${request.pluginId}/${request.actionId}: ${message}`.slice(0, 1_000),
|
|
1296
1681
|
detailLevel: 'summary',
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1682
|
+
});
|
|
1683
|
+
} else {
|
|
1684
|
+
const current = getWorkContract({ controllerHome, repoId: repository.repoId }, acceptedWork.workId);
|
|
1685
|
+
failWorkContract(
|
|
1686
|
+
{ controllerHome, repoId: repository.repoId },
|
|
1687
|
+
acceptedWork.workId,
|
|
1688
|
+
{
|
|
1689
|
+
phase: current?.phase ?? 'implementation',
|
|
1690
|
+
summary: `Controller-local plugin action failed: ${request.pluginId}/${request.actionId}: ${message}`.slice(0, 1_000),
|
|
1691
|
+
evidenceRefs: [{
|
|
1692
|
+
title: 'controller-local effect failed',
|
|
1693
|
+
summary: `${request.pluginId}/${request.actionId}: ${message}`.slice(0, 1_000),
|
|
1694
|
+
detailLevel: 'summary',
|
|
1695
|
+
}, ...(current?.evidenceRefs ?? [])],
|
|
1696
|
+
},
|
|
1697
|
+
);
|
|
1698
|
+
}
|
|
1299
1699
|
}
|
|
1300
1700
|
const receipt: PluginActionReceipt = {
|
|
1301
1701
|
schemaVersion: 1,
|
|
@@ -1307,6 +1707,7 @@ export async function submitAssistantPluginAction(
|
|
|
1307
1707
|
actionId: request.actionId,
|
|
1308
1708
|
semanticKey: key,
|
|
1309
1709
|
status: 'failed',
|
|
1710
|
+
effectOutcome,
|
|
1310
1711
|
createdAt,
|
|
1311
1712
|
...(acceptedWork
|
|
1312
1713
|
? { workId: acceptedWork.workId }
|
|
@@ -1317,20 +1718,45 @@ export async function submitAssistantPluginAction(
|
|
|
1317
1718
|
: {}),
|
|
1318
1719
|
origin: request.origin,
|
|
1319
1720
|
authorization,
|
|
1721
|
+
...(outcomeResult ? { result: outcomeResult } : {}),
|
|
1320
1722
|
error: { code, message },
|
|
1321
1723
|
};
|
|
1322
1724
|
writeJsonAtomic(pluginActionReceiptPath(controllerHome, repository.repoId, receiptId), receipt);
|
|
1323
1725
|
writeJsonAtomic(requestPath, {
|
|
1324
1726
|
requestId: request.requestId,
|
|
1325
1727
|
repoId: repository.repoId,
|
|
1728
|
+
...(request.workId ? { workRepoId: workAttributionRepoId(repository, request) } : {}),
|
|
1326
1729
|
receiptId,
|
|
1327
1730
|
semanticKey: key,
|
|
1328
1731
|
createdAt,
|
|
1329
1732
|
} satisfies PluginActionRequestIndex);
|
|
1733
|
+
if (outcomeUnknown) {
|
|
1734
|
+
return {
|
|
1735
|
+
manifest,
|
|
1736
|
+
action,
|
|
1737
|
+
job: compatibilityJobFromReceipt(receipt, repository.activeCheckoutId),
|
|
1738
|
+
deduplicated: false,
|
|
1739
|
+
result: outcomeResult,
|
|
1740
|
+
receipt,
|
|
1741
|
+
authorization,
|
|
1742
|
+
workId: acceptedWork?.workId ?? boundRemoteWork?.workId ?? attributedWork?.workId,
|
|
1743
|
+
};
|
|
1744
|
+
}
|
|
1330
1745
|
throw error;
|
|
1331
1746
|
}
|
|
1332
1747
|
}
|
|
1333
1748
|
|
|
1749
|
+
export async function executeControllerScopedPluginAction(
|
|
1750
|
+
input: Omit<AssistantPluginActionExecutionInput, 'repoId' | 'repoRoot'>,
|
|
1751
|
+
): Promise<Record<string, unknown>> {
|
|
1752
|
+
const repository = controllerPluginRepository(input.controllerHome);
|
|
1753
|
+
return executeAssistantPluginAction({
|
|
1754
|
+
...input,
|
|
1755
|
+
repoId: repository.repoId,
|
|
1756
|
+
repoRoot: repository.canonicalRoot,
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1334
1760
|
export async function executeAssistantPluginAction(
|
|
1335
1761
|
input: AssistantPluginActionExecutionInput,
|
|
1336
1762
|
): Promise<Record<string, unknown>> {
|
|
@@ -1344,8 +1770,24 @@ export async function executeAssistantPluginAction(
|
|
|
1344
1770
|
const manifestLookup = getAssistantPluginManifestForExecution(input.controllerHome, repository, input.pluginId, adapter);
|
|
1345
1771
|
const manifest = manifestLookup.manifest;
|
|
1346
1772
|
const action = actionForManifest(manifest, input.actionId);
|
|
1347
|
-
|
|
1773
|
+
if (action.executionMode === 'direct_non_persistent') {
|
|
1774
|
+
throw new Error(`PLUGIN_DIRECT_NON_PERSISTENT_APPLICATION_PATH_REQUIRED: ${input.pluginId}/${input.actionId}`);
|
|
1775
|
+
}
|
|
1348
1776
|
const normalizedArgs = validateActionArguments(action, input.args);
|
|
1777
|
+
if (requiresAutomatedWriteAuthorization(input.origin)) {
|
|
1778
|
+
await resolveAutomatedWriteAuthorization({
|
|
1779
|
+
controllerHome: input.controllerHome,
|
|
1780
|
+
repository,
|
|
1781
|
+
adapter,
|
|
1782
|
+
manifest,
|
|
1783
|
+
action,
|
|
1784
|
+
args: normalizedArgs,
|
|
1785
|
+
origin: input.origin,
|
|
1786
|
+
requestId: input.requestId,
|
|
1787
|
+
jobId: input.jobId,
|
|
1788
|
+
authorizationGrantRefs: input.authorizationGrantRefs,
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1349
1791
|
try {
|
|
1350
1792
|
const result = await adapter.executeAction({
|
|
1351
1793
|
...input,
|