@moretea-labs/forge 1.7.2 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +121 -62
- package/CHANGELOG.md +40 -0
- package/CLAUDE.md +57 -62
- package/CONTRIBUTING.md +3 -2
- 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 +77 -0
- package/adapters/chatgpt/browser-delivery-runtime.ts +1256 -0
- package/adapters/chatgpt/controller-binding-store.ts +134 -0
- package/adapters/chatgpt/controller-round-host.ts +68 -0
- package/adapters/chatgpt/controller-round-settlement-store.ts +99 -0
- package/adapters/chatgpt/provider-delivery.ts +340 -0
- package/adapters/chatgpt/work-conversation-binding-store.ts +218 -0
- package/adapters/chatgpt/wsl-bridge-delivery-host.ts +63 -0
- package/adapters/computer/chatgpt-extension-target.ts +463 -0
- package/adapters/computer/chatgpt-target-router.ts +103 -0
- package/adapters/computer/chrome-extension/background.js +385 -0
- package/adapters/computer/chrome-extension/content.js +378 -0
- package/adapters/computer/chrome-extension/core.js +24 -0
- package/adapters/computer/chrome-extension/manifest.json +30 -0
- package/adapters/computer/desktop-operator-contract.ts +7 -0
- package/adapters/computer/desktop-operator-discovery.ts +181 -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 +1068 -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 +406 -0
- package/adapters/mcp/instructions.ts +37 -0
- package/adapters/mcp/legacy-context.ts +18 -0
- package/adapters/mcp/multi-repository.ts +421 -0
- package/adapters/mcp/oauth.ts +464 -0
- package/adapters/mcp/paths.ts +143 -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/automation-receipt-adapter.ts +87 -0
- package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
- package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
- package/adapters/mcp/runtime-gateway/context-adapter.ts +1167 -0
- package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
- package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +206 -0
- package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
- package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +130 -0
- package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
- package/adapters/mcp/runtime-gateway/execution-control-adapter.ts +28 -0
- package/adapters/mcp/runtime-gateway/execution-tools.ts +173 -0
- package/adapters/mcp/runtime-gateway/filesystem-adapter.ts +38 -0
- package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +412 -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 +380 -0
- package/adapters/mcp/runtime-gateway/process-tools.ts +457 -0
- package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +88 -0
- package/adapters/mcp/runtime-gateway/recovery-adapter.ts +285 -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 +79 -0
- package/adapters/mcp/runtime-gateway/result-adapter.ts +114 -0
- package/adapters/mcp/runtime-gateway/router.ts +242 -0
- package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
- package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1200 -0
- package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +574 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-shared.ts +27 -0
- package/adapters/mcp/runtime-gateway/runtime-tools.ts +78 -0
- package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +187 -0
- package/adapters/mcp/runtime-gateway/shared-adapter.ts +45 -0
- package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +962 -0
- package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
- package/adapters/mcp/runtime-gateway/work-adapter.ts +325 -0
- package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
- package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
- package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
- package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
- package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
- package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
- package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
- package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
- package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
- package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +1 -0
- package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
- package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
- package/adapters/mcp/server.ts +1092 -0
- package/adapters/mcp/setup.ts +789 -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 +5139 -0
- package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +145 -0
- package/adapters/mcp/tool-mapping/repository-tools.ts +1682 -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 +79 -0
- package/adapters/mcp/toolset-selection.ts +41 -0
- package/adapters/mcp/toolset.ts +337 -0
- package/adapters/mcp/transports/http-observation.ts +365 -0
- package/adapters/mcp/transports/http.ts +933 -0
- package/adapters/mcp/transports/oauth-http.ts +322 -0
- package/adapters/mcp/transports/session-registry.ts +519 -0
- package/adapters/mcp/transports/stdio.ts +8 -0
- package/adapters/mcp/tunnels/openai-secure-tunnel.ts +223 -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 +11 -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/agentic-development-flow.md +25 -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 +28 -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 +233 -28
- package/docs/architecture/EVOLUTION.md +13 -0
- package/docs/architecture/decisions/20260801-controller-home-sqlite-state.md +2 -1
- package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
- package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
- package/docs/architecture/decisions/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 +37 -0
- package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +311 -0
- package/docs/architecture/decisions/20260907-maintenance-diagnosis-bounded-read.md +39 -0
- package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
- package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
- package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
- package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
- package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
- package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
- package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
- package/docs/architecture/domains/verification.md +8 -0
- package/docs/architecture/domains/workflow-engine.md +7 -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/controller-performance-and-502.md +17 -0
- package/docs/operations/controller-reliability-runbook.md +2 -2
- package/docs/operations/features.md +1 -1
- package/docs/operations/features.zh-CN.md +1 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +2 -0
- package/docs/operations/platform-support.md +16 -8
- package/docs/operations/platform-support.zh-CN.md +2 -2
- package/docs/operations/releasing.md +2 -0
- package/docs/operations/standalone-disaster-recovery.md +38 -5
- 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 +46 -26
- package/packages/kernel/cognition/api/index.ts +6 -0
- package/packages/kernel/cognition/application/activation-service.ts +451 -0
- package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
- package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
- package/packages/kernel/cognition/application/memory-service.ts +64 -0
- package/packages/kernel/cognition/domain/learning.ts +106 -0
- package/packages/kernel/cognition/domain/memory.ts +254 -0
- package/packages/kernel/controller/api/index.ts +3 -0
- package/packages/kernel/controller/application/continuation-service.ts +281 -0
- package/packages/kernel/controller/application/controller-round-service.ts +41 -0
- package/packages/kernel/controller/application/controller-service.ts +30 -0
- package/packages/kernel/controller/domain/controller-round-transition-policy.ts +529 -0
- package/packages/kernel/controller/domain/controller-round.ts +110 -0
- package/packages/kernel/controller/domain/execution-quality.ts +135 -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 +1970 -0
- package/packages/kernel/controller/infrastructure/controller-session-store.ts +804 -0
- package/packages/kernel/controller/ports/controller-host.ts +18 -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 +15 -0
- package/packages/kernel/identity/application/identity-service.ts +67 -0
- package/packages/kernel/identity/domain/activity-projection.ts +43 -0
- package/packages/kernel/identity/domain/capability-broker.ts +60 -0
- package/packages/kernel/identity/domain/grant.ts +72 -0
- package/packages/kernel/identity/domain/owned-resource.ts +116 -0
- package/packages/kernel/identity/domain/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/user-request.ts +93 -0
- package/packages/kernel/identity/domain/workspace.ts +56 -0
- package/packages/kernel/identity/index.ts +1 -0
- package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
- package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
- package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
- package/packages/kernel/identity/infrastructure/identity-store.ts +75 -0
- package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
- package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
- package/packages/kernel/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/scheduler/api/index.ts +4 -0
- package/packages/kernel/scheduler/application/eligibility.ts +252 -0
- package/packages/kernel/scheduler/application/schedule-service.ts +27 -0
- package/packages/kernel/scheduler/application/settlement.ts +182 -0
- package/packages/kernel/scheduler/domain/schedule.ts +236 -0
- package/packages/kernel/scheduler/index.ts +1 -0
- package/packages/kernel/scheduler/infrastructure/schedule-store.ts +805 -0
- package/packages/kernel/work/api/index.ts +16 -0
- package/packages/kernel/work/application/work-service.ts +123 -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/current-task-lineage.ts +104 -0
- package/packages/kernel/work/domain/engineering-contracts.ts +157 -0
- package/packages/kernel/work/domain/engineering-design.ts +286 -0
- package/packages/kernel/work/domain/engineering-profile.ts +238 -0
- package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
- package/packages/kernel/work/domain/execution-concurrency.ts +247 -0
- package/packages/kernel/work/domain/execution-snapshot.ts +2 -0
- package/packages/kernel/work/domain/implementation-review.ts +193 -0
- package/packages/kernel/work/domain/objective-graph.ts +119 -0
- package/packages/kernel/work/domain/project-engineering-contract.ts +224 -0
- package/packages/kernel/work/domain/repository-completion-receipt.ts +73 -0
- package/{src/runtime/control-plane/facade/work-state-machine.ts → packages/kernel/work/domain/state-machine.ts} +37 -66
- package/packages/kernel/work/domain/types.ts +534 -0
- package/packages/kernel/work/index.ts +1 -0
- package/packages/kernel/work/infrastructure/work-contract-store.ts +1967 -0
- package/packages/kernel/work/ports/work-contract-store.ts +21 -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 +62 -0
- package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
- package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
- package/packages/plugin-runtime/computer/index.ts +8 -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 +215 -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 +581 -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 +225 -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/activate-source-baseline.ts +7 -9
- package/scripts/assemble-template.ts +1 -1
- 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 +183 -0
- package/scripts/canary-global-hook.sh +2 -2
- package/scripts/check-mcp-compatibility.ts +85 -7
- package/scripts/check-platform-support.mjs +28 -2
- package/scripts/check-public-docs.sh +1 -1
- package/scripts/check-repository-hygiene.mjs +92 -0
- package/scripts/check-runtime-architecture.mjs +1643 -127
- package/scripts/check-source-duplication.mjs +9 -1
- package/scripts/controller-ngrok-rotation.sh +5 -4
- package/scripts/create-project-dirs.sh +10 -74
- package/scripts/forge-local-recovery-helper.mjs +282 -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 +42 -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 +11 -1
- package/scripts/portability-bindings.mjs +70 -0
- package/scripts/run-bounded-command.mjs +60 -0
- package/scripts/run-bun-test-file.ts +22 -6
- package/scripts/run-governed-gate.ts +4 -2
- package/scripts/run-mobile-monitor-bridge.ts +0 -1
- package/scripts/smoke-control-plane-failure-domain.ts +94 -0
- package/scripts/smoke-mcp-http-runtime.ts +6 -1
- package/scripts/smoke-runtime-recovery.ts +13 -11
- package/scripts/smoke-schedule-engine.ts +24 -16
- package/scripts/smoke-unattended-transport-recovery.ts +223 -0
- package/scripts/smoke-user-request-continuation-restart.ts +232 -0
- package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
- package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
- package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
- package/scripts/smoke-workflow-supervisor.ts +103 -0
- package/scripts/test-governance.ts +51 -2
- package/scripts/verify-forge-runtime.sh +2 -1
- package/src/cli/agent-jobs/executor-health.ts +11 -34
- package/src/cli/agent-jobs/integration.ts +18 -49
- package/src/cli/agent-jobs/job-manager.ts +17 -4
- 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 +52 -0
- package/src/cli/commands/brain.ts +191 -40
- package/src/cli/commands/chatgpt.ts +32 -67
- 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 +507 -80
- package/src/cli/commands/runtime.ts +12 -7
- package/src/cli/commands/setup-profile.ts +97 -39
- package/src/cli/commands/status.ts +2 -1
- package/src/cli/controller/check-runner.ts +500 -100
- package/src/cli/controller/completion-backlog.ts +3 -3
- package/src/cli/controller/completion-orchestrator.ts +4 -43
- package/src/cli/controller/completion-target.ts +3 -72
- package/src/cli/controller/context/source-materializer.ts +81 -100
- package/src/cli/controller/context/types.ts +7 -1
- package/src/cli/controller/context-pack.ts +28 -6
- package/src/cli/controller/execution-completion.ts +4 -7
- package/src/cli/controller/execution-policy.ts +36 -153
- package/src/cli/controller/governance.ts +2 -3
- package/src/cli/controller/issue-store.ts +4 -99
- package/src/cli/controller/launch-agents.ts +59 -18
- package/src/cli/controller/operational-plan.ts +24 -51
- package/src/cli/controller/runtime-config.ts +5 -1
- package/src/cli/controller/stuck-state-migration.ts +2 -3
- package/src/cli/controller/systemd-user.ts +148 -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 +290 -20
- 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 +20 -15
- package/src/cli/local-bridge/console-view-models.ts +3 -12
- package/src/cli/local-bridge/facade-api.ts +105 -205
- package/src/cli/local-bridge/job-store.ts +1 -1
- package/src/cli/local-bridge/server.ts +48 -174
- package/src/cli/local-bridge/types.ts +0 -1
- 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-client-retirement.ts +74 -0
- 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 -1613
- 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 +91 -39
- package/src/cli/repositories/command-scope.ts +139 -4
- package/src/cli/repositories/controller-home.ts +167 -1
- package/src/cli/repositories/ephemeral-workspace.ts +20 -30
- package/src/cli/repositories/git-command-executor.ts +2 -2
- package/src/cli/repositories/identity.ts +13 -0
- package/src/cli/repositories/registry.ts +145 -60
- 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 +167 -27
- package/src/cli/repository/session-cache.ts +92 -6
- 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 +167 -0
- package/src/runtime/context/assistant-work-context.ts +209 -0
- package/src/runtime/context/automatic-learning.ts +565 -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/cognitive-attention.ts +173 -0
- package/src/runtime/context/cognitive-skill-canary.ts +158 -0
- package/src/runtime/context/context-closure.ts +305 -0
- package/src/runtime/context/context-pack-process.ts +103 -0
- package/src/runtime/context/context-plane.ts +203 -0
- package/src/runtime/context/direct-controller-learning.ts +298 -0
- package/src/runtime/context/project-engineering-contract.ts +60 -0
- package/src/runtime/context/semantic-navigation-contract.ts +9 -0
- package/src/runtime/context/semantic-navigation.ts +6 -34
- package/src/runtime/context/typescript-navigation-process.ts +145 -0
- package/src/runtime/context/typescript-navigation.ts +89 -3
- package/src/runtime/control-plane/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 +531 -0
- package/src/runtime/control-plane/codegraph-cache-retention.ts +164 -0
- package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +282 -0
- package/src/runtime/control-plane/execution/controller-authority-recovery.ts +380 -0
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +113 -16
- package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
- package/src/runtime/control-plane/execution/implementation-review-content.ts +95 -0
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
- package/src/runtime/control-plane/execution/retained-work-resume.ts +439 -102
- package/src/runtime/control-plane/execution/session-store.ts +31 -1
- package/src/runtime/control-plane/execution/validation.ts +34 -11
- package/src/runtime/control-plane/execution/work-authority-reconciler.ts +87 -0
- package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +31 -44
- package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +46 -53
- package/src/runtime/control-plane/execution/work-execution-support.ts +85 -164
- package/src/runtime/control-plane/execution/work-handle-authority.ts +349 -73
- package/src/runtime/control-plane/execution/work-handle-store.ts +55 -2
- package/src/runtime/control-plane/execution/work-head-settlement.ts +108 -0
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +173 -28
- package/src/runtime/control-plane/execution/work-operation-service.ts +92 -40
- package/src/runtime/control-plane/execution/work-preparation-service.ts +145 -269
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
- package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +543 -225
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +59 -45
- package/src/runtime/control-plane/execution/work-verification-context.ts +1 -1
- package/src/runtime/control-plane/execution/work-verification-service.ts +662 -52
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +205 -16
- package/src/runtime/control-plane/facade/capability-registry.ts +380 -44
- package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
- package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
- package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
- package/src/runtime/control-plane/facade/controller-session-store.ts +2 -488
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +6 -22
- package/src/runtime/control-plane/facade/goal-workloop.ts +565 -1202
- package/src/runtime/control-plane/facade/handoff-inbox-application.ts +145 -0
- package/src/runtime/control-plane/facade/handoff-inbox-store.ts +266 -52
- package/src/runtime/control-plane/facade/index.ts +4 -3
- package/src/runtime/control-plane/facade/operation-digest.ts +34 -73
- package/src/runtime/control-plane/facade/plan-contract-store.ts +671 -245
- package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
- package/src/runtime/control-plane/facade/repository-work-admission.ts +31 -23
- package/src/runtime/control-plane/facade/requirement-authority.ts +121 -0
- package/src/runtime/control-plane/facade/requirement-board.ts +9 -4
- package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +85 -0
- package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
- package/src/runtime/control-plane/facade/semantic-admission.ts +8 -16
- package/src/runtime/control-plane/facade/suggested-actions.ts +15 -15
- package/src/runtime/control-plane/facade/types.ts +218 -620
- package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
- package/src/runtime/control-plane/facade/work-contract-store.ts +2 -1043
- package/src/runtime/control-plane/generated-cache-retention.ts +336 -19
- package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +13 -2
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +274 -84
- 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 +3 -2
- package/src/runtime/control-plane/global-scheduler/scheduler-worker-entry.ts +10 -0
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +227 -109
- package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
- package/src/runtime/control-plane/global-scheduler/worker-launch.ts +18 -6
- package/src/runtime/control-plane/governance/access-policy.ts +19 -2
- package/src/runtime/control-plane/governance/authorization.ts +20 -3
- package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +160 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +2 -177
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +139 -670
- package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
- package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +25 -6
- package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -194
- package/src/runtime/control-plane/lifecycle-retention-metrics.ts +60 -0
- package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
- package/src/runtime/control-plane/persistence/experience-store.ts +302 -0
- package/src/runtime/control-plane/persistence/operational-prior-store.ts +348 -0
- package/src/runtime/control-plane/persistence/requirement-store.ts +230 -80
- package/src/runtime/control-plane/persistence/sqlite-store.ts +654 -78
- 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 +154 -26
- package/src/runtime/control-plane/repository-namespace-retention.ts +208 -0
- package/src/runtime/control-plane/runtime-cleanup.ts +844 -38
- package/src/runtime/control-plane/runtime-generation.ts +6 -0
- package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
- package/src/runtime/control-plane/workspace/semantic-sync-service.ts +479 -0
- package/src/runtime/control-plane/workspace/workspace-store.ts +249 -0
- package/src/runtime/diagnostics/incident-repair.ts +573 -0
- package/src/runtime/diagnostics/mcp-timing.ts +239 -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 +216 -35
- package/src/runtime/evidence/evidence-store.ts +112 -8
- package/src/runtime/evidence/operational-shadow.ts +38 -0
- package/src/runtime/evidence/output-handle-index.ts +225 -0
- package/src/runtime/evidence/process-check-receipt.ts +5 -43
- package/src/runtime/evidence/result-store.ts +158 -44
- 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 +124 -6
- package/src/runtime/execution/managed-workspace.ts +112 -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 +24 -10
- 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 +177 -2
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +58 -9
- package/src/runtime/execution/process-runtime/check-storage.ts +187 -0
- package/src/runtime/execution/process-runtime/command-facade.ts +117 -114
- package/src/runtime/execution/process-runtime/gc.ts +15 -2
- package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
- package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
- package/src/runtime/execution/process-runtime/index.ts +4 -0
- package/src/runtime/execution/process-runtime/interactive-admission.ts +2 -1
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +283 -73
- package/src/runtime/execution/process-runtime/persisted-check.ts +130 -23
- package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
- package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
- package/src/runtime/execution/process-runtime/resource-claims.ts +125 -64
- package/src/runtime/execution/process-runtime/runtime.ts +167 -17
- package/src/runtime/execution/process-runtime/store.ts +30 -2
- package/src/runtime/execution/process-runtime/types.ts +27 -0
- package/src/runtime/execution/workers/executor.ts +18 -19
- 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 -6655
- 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-inventory.ts +130 -0
- package/src/runtime/platform/service-manager.ts +146 -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 +192 -0
- package/src/runtime/plugins/app-store-connect-adapter.ts +47 -35
- package/src/runtime/plugins/browser-adapter.ts +898 -135
- package/src/runtime/plugins/browser-automation-service.ts +33 -34
- package/src/runtime/plugins/browser-macos-bridge.ts +386 -46
- package/src/runtime/plugins/browser-manifest-surface.ts +75 -17
- package/src/runtime/plugins/browser-native-session-service.ts +64 -14
- package/src/runtime/plugins/browser-provider-registry.ts +2 -109
- package/src/runtime/plugins/browser-registration.ts +32 -0
- package/src/runtime/plugins/browser-runtime-contract.ts +2 -154
- package/src/runtime/plugins/browser-runtime.ts +55 -10
- 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 +243 -80
- package/src/runtime/plugins/browser-session-types.ts +2 -98
- package/src/runtime/plugins/capability-authorization-grants.ts +272 -59
- package/src/runtime/plugins/catalog-trust.ts +82 -0
- package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
- package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
- package/src/runtime/plugins/computer-registration.ts +1050 -0
- package/src/runtime/plugins/config-store.ts +119 -0
- package/src/runtime/plugins/desktop-operator-external-policy.ts +964 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +123 -12
- package/src/runtime/plugins/errors.ts +8 -1
- package/src/runtime/plugins/external-adapter.ts +82 -323
- package/src/runtime/plugins/external-provider-policy.ts +48 -0
- package/src/runtime/plugins/external-registration.ts +30 -2
- 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 +29 -8
- package/src/runtime/plugins/google-calendar-adapter.ts +8 -8
- package/src/runtime/plugins/google-shared.ts +45 -53
- package/src/runtime/plugins/google-tasks-adapter.ts +8 -8
- package/src/runtime/plugins/ios-adapter.ts +2 -3
- package/src/runtime/plugins/lightweight-action.ts +208 -2
- package/src/runtime/plugins/local-system-adapter.ts +192 -2
- package/src/runtime/plugins/macos-capability-broker.ts +15 -105
- package/src/runtime/plugins/managed-process-adapter.ts +12 -5
- package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
- package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
- package/src/runtime/plugins/resend-adapter.ts +15 -24
- package/src/runtime/plugins/store.ts +1003 -387
- package/src/runtime/plugins/types.ts +28 -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 +102 -430
- package/src/runtime/projections/controller-context.ts +12 -6
- package/src/runtime/projections/git-status-sampler.ts +73 -22
- package/src/runtime/projections/invalidation.ts +7 -3
- package/src/runtime/projections/materialized-view.ts +93 -43
- package/src/runtime/recovery/actions.ts +3 -3
- package/src/runtime/recovery/capability-action-application.ts +229 -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 +701 -168
- package/src/runtime/recovery/quarantine-retention.ts +256 -0
- package/src/runtime/recovery/store.ts +29 -11
- package/src/runtime/release/identity.ts +6 -0
- package/src/runtime/release/release-coordinator.ts +296 -0
- package/src/runtime/release/release-session.ts +716 -0
- package/src/runtime/release/release-state-migration.ts +25 -0
- package/src/runtime/resources/leases/store.ts +56 -25
- package/src/runtime/root/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 +376 -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-progression-composition.ts +192 -0
- package/src/runtime/root/controller-round-composition.ts +126 -0
- package/src/runtime/root/controller-services.ts +2 -0
- package/src/runtime/root/deployment-topology.ts +106 -0
- package/src/runtime/root/entry.ts +8 -6
- package/src/runtime/root/gateway-adapter.ts +3 -3
- package/src/runtime/root/known-good-recovery.ts +184 -0
- package/src/runtime/root/local-bridge.ts +5 -3
- package/src/runtime/root/mcp-transport.ts +116 -23
- package/src/runtime/root/ownership.ts +261 -9
- package/src/runtime/root/package-connector-service.ts +212 -74
- package/src/runtime/root/package-runtime-release.ts +199 -33
- package/src/runtime/root/package-runtime-service.ts +77 -108
- package/src/runtime/root/release-execution-canary.ts +103 -0
- package/src/runtime/root/release-loader.ts +150 -0
- package/src/runtime/root/release-manifest.ts +185 -7
- package/src/runtime/root/release-materialize.ts +474 -31
- package/src/runtime/root/release-store.ts +425 -37
- package/src/runtime/root/runtime-lane.ts +191 -0
- package/src/runtime/root/runtime.ts +379 -32
- package/src/runtime/root/scheduled-controller-composition.ts +76 -0
- package/src/runtime/root/scheduler.ts +12 -4
- package/src/runtime/root/service-runner.ts +3 -3
- package/src/runtime/root/service.ts +73 -45
- package/src/runtime/root/status.ts +49 -0
- package/src/runtime/root/types.ts +55 -3
- package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
- package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
- package/src/runtime/root/write-fence.ts +50 -2
- package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
- package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
- package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
- package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
- package/src/runtime/shared/local-bridge-surface.ts +1 -1
- package/src/runtime/shared/process-environment.ts +36 -10
- package/src/runtime/shared/response-budget.ts +1 -3
- package/src/runtime/shared/storage-capacity.ts +68 -0
- package/src/runtime/standalone-recovery/controller-home-migration.ts +1108 -0
- package/src/runtime/standalone-recovery/core.ts +4609 -495
- package/src/runtime/standalone-recovery/entry.ts +642 -81
- package/src/runtime/standalone-recovery/independent-host-rescue.ts +172 -0
- package/src/runtime/standalone-recovery/installer.ts +399 -177
- package/src/runtime/standalone-recovery/mcp-server.ts +79 -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 +173 -0
- package/src/runtime/standalone-recovery/release.ts +58 -5
- package/src/runtime/standalone-recovery/service-labels.ts +5 -2
- package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
- package/src/runtime/watchdog/workflow-watchdog.ts +1 -1
- package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
- package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +11 -4
- package/src/runtime/workflow/schedules/engine.ts +298 -484
- 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 +220 -16
- package/src/runtime/workflows/first-party/xiaohongshu.ts +122 -0
- package/src/runtime/workflows/runtime.ts +482 -0
- package/src/testing/test-governance.ts +95 -30
- package/supervisor/chatgpt-conversation.ts +23 -0
- package/supervisor/client.ts +201 -0
- package/supervisor/control-plane.ts +868 -0
- package/supervisor/entry.ts +15 -0
- package/supervisor/forge-validators.ts +80 -0
- package/supervisor/index.ts +5 -0
- package/supervisor/native-browser-adapter.ts +786 -0
- package/supervisor/native-messaging/host.ts +39 -0
- package/supervisor/native-messaging/manifest.ts +26 -0
- package/supervisor/native-messaging/protocol.ts +27 -0
- package/supervisor/paths.ts +18 -0
- package/supervisor/protocol.ts +202 -0
- package/supervisor/server.ts +404 -0
- package/supervisor/store.ts +1451 -0
- package/supervisor/tsconfig.json +8 -0
- package/supervisor/types.ts +255 -0
- package/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/benchmark-background-check-overlap.ts +0 -228
- package/scripts/benchmark-controller-hotpath.ts +0 -212
- package/scripts/benchmark-controller-round2.ts +0 -139
- package/scripts/benchmark-ios-agent-device.ts +0 -514
- package/scripts/benchmark-mcp-host.sh +0 -117
- package/scripts/benchmark-mcp-transport.ts +0 -170
- package/scripts/benchmark-quality-harness.ts +0 -146
- package/scripts/benchmark-route-session-concurrency.ts +0 -915
- package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
- package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
- package/scripts/benchmark-thin-harness.ts +0 -251
- package/scripts/benchmark-typescript-navigation.ts +0 -186
- package/scripts/benchmark-work-efficiency.ts +0 -334
- package/scripts/build-controller-ui.ts +0 -28
- package/scripts/check-npm-release.sh +0 -32
- package/scripts/check-public-release-surface.sh +0 -19
- package/scripts/check-release-published.sh +0 -57
- package/scripts/check-release-readiness.sh +0 -37
- package/scripts/check-release-version.mjs +0 -74
- package/scripts/check-tarball-install-smoke.sh +0 -67
- package/scripts/package-source-archive.sh +0 -147
- package/scripts/public-release-files.txt +0 -39
- package/scripts/public-release.ts +0 -174
- package/scripts/publish-release-tarball.sh +0 -27
- package/scripts/route-nl-vs-ts-eval.ts +0 -679
- package/scripts/run-skill-evals.ts +0 -1022
- package/scripts/stage-runtime-release.ts +0 -39
- package/src/cli/controller/progress.ts +0 -656
- package/src/cli/controller/work-mode.ts +0 -181
- package/src/cli/local-bridge/console-assets.ts +0 -17
- package/src/cli/local-bridge/dashboard.ts +0 -17
- package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
- package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
- package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
- package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
- package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
- package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
- package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
- package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
- package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
- package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/styles.css +0 -28
- package/src/cli/local-bridge/frontend/src/types.ts +0 -15
- package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
- package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
- package/src/cli/local-bridge/ui-dist/app.css +0 -1
- package/src/cli/local-bridge/ui-dist/app.js +0 -11228
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -385
- package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -1913
- package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
- package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -449
- package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -1118
- package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -93
- package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
- package/src/runtime/control-plane/routing/index.ts +0 -1
- package/src/runtime/control-plane/routing/route-policy.ts +0 -382
- package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
|
@@ -19,8 +19,7 @@ import {
|
|
|
19
19
|
releaseControllerCheckSubscription,
|
|
20
20
|
runControllerCheckAsync,
|
|
21
21
|
} from '../../../cli/controller/check-runner';
|
|
22
|
-
import {
|
|
23
|
-
import type { RepositoryRecord } from '../../../cli/repositories/types';
|
|
22
|
+
import { commandExecutionScopeKey, type RepositoryCommandScopeTarget } from '../../../cli/repositories/command-scope';
|
|
24
23
|
import { readJsonFile, sanitizeFileComponent, writeJsonAtomic } from '../../shared/json-files';
|
|
25
24
|
import {
|
|
26
25
|
defaultProcessIdentityProbe,
|
|
@@ -30,6 +29,17 @@ import {
|
|
|
30
29
|
} from '../../shared/process-identity';
|
|
31
30
|
import { terminateProcessTree } from '../../shared/process-tree';
|
|
32
31
|
import { runBoundedProcess } from '../thin-harness/async-process';
|
|
32
|
+
import { recordProcessHandleIndexEntry } from './handle-index';
|
|
33
|
+
import {
|
|
34
|
+
FORGE_INSTANCE_PROCESS_SCOPE_KEY,
|
|
35
|
+
isWorkspaceProcessScopeKey,
|
|
36
|
+
legacyWorkspaceScopeRoot,
|
|
37
|
+
normalizeProcessScopeKey,
|
|
38
|
+
processScopeExecutionTarget,
|
|
39
|
+
processScopeFromKey,
|
|
40
|
+
processScopeKey,
|
|
41
|
+
processScopeRoot,
|
|
42
|
+
} from './process-scope';
|
|
33
43
|
import { PROCESS_LOG_TAIL_BYTES, type ProcessHandle, type ProcessLogSlice, type WaitProcessOptions } from './types';
|
|
34
44
|
|
|
35
45
|
const EMPTY_EFFECTS = {
|
|
@@ -66,7 +76,12 @@ interface LightweightExitObservation {
|
|
|
66
76
|
interface LightweightEntry {
|
|
67
77
|
processId: string;
|
|
68
78
|
controllerHome: string;
|
|
69
|
-
|
|
79
|
+
/** Canonical Process scope partition key (`repo_*` repository id, or the ForgeInstance scope key). */
|
|
80
|
+
scopeKey: string;
|
|
81
|
+
/** Repository placement when this handle targets a repository; absent for ForgeInstance targets. */
|
|
82
|
+
repoId?: string;
|
|
83
|
+
/** Owning principal recorded from the invoking MCP/Runtime context. */
|
|
84
|
+
principalId?: string;
|
|
70
85
|
workId?: string;
|
|
71
86
|
commandId: string;
|
|
72
87
|
requestFingerprint: string;
|
|
@@ -93,9 +108,17 @@ interface LightweightEntry {
|
|
|
93
108
|
|
|
94
109
|
const entries = new Map<string, LightweightEntry>();
|
|
95
110
|
|
|
111
|
+
export function hasActiveLightweightProcesses(controllerHome: string): boolean {
|
|
112
|
+
return [...entries.values()].some((entry) => (
|
|
113
|
+
entry.controllerHome === controllerHome && entry.result === undefined
|
|
114
|
+
));
|
|
115
|
+
}
|
|
116
|
+
|
|
96
117
|
interface LightweightRunningReceipt {
|
|
97
118
|
schemaVersion: 1;
|
|
98
|
-
repoId
|
|
119
|
+
/** Canonical scope partition key. Legacy receipts carry only `repoId`. */
|
|
120
|
+
scopeKey?: string;
|
|
121
|
+
repoId?: string;
|
|
99
122
|
processId: string;
|
|
100
123
|
commandId?: string;
|
|
101
124
|
requestFingerprint?: string;
|
|
@@ -107,7 +130,9 @@ interface LightweightRunningReceipt {
|
|
|
107
130
|
|
|
108
131
|
interface LightweightTerminalReceipt {
|
|
109
132
|
schemaVersion: 1;
|
|
110
|
-
repoId
|
|
133
|
+
/** Canonical scope partition key. Legacy receipts carry only `repoId`. */
|
|
134
|
+
scopeKey?: string;
|
|
135
|
+
repoId?: string;
|
|
111
136
|
processId: string;
|
|
112
137
|
commandId?: string;
|
|
113
138
|
requestFingerprint?: string;
|
|
@@ -115,20 +140,44 @@ interface LightweightTerminalReceipt {
|
|
|
115
140
|
handle: ProcessHandle;
|
|
116
141
|
}
|
|
117
142
|
|
|
118
|
-
function runningReceiptRoot(controllerHome: string,
|
|
119
|
-
return join(
|
|
143
|
+
function runningReceiptRoot(controllerHome: string, scopeKey: string): string {
|
|
144
|
+
return join(processScopeRoot(controllerHome, scopeKey), 'process-runtime', 'lightweight-running');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function runningReceiptPath(controllerHome: string, scopeKey: string, processId: string): string {
|
|
148
|
+
return join(runningReceiptRoot(controllerHome, scopeKey), `${sanitizeFileComponent(processId)}.json`);
|
|
120
149
|
}
|
|
121
150
|
|
|
122
|
-
function
|
|
123
|
-
return join(
|
|
151
|
+
function terminalReceiptRoot(controllerHome: string, scopeKey: string): string {
|
|
152
|
+
return join(processScopeRoot(controllerHome, scopeKey), 'process-runtime', 'lightweight-terminal');
|
|
124
153
|
}
|
|
125
154
|
|
|
126
|
-
function
|
|
127
|
-
return join(
|
|
155
|
+
function terminalReceiptPath(controllerHome: string, scopeKey: string, processId: string): string {
|
|
156
|
+
return join(terminalReceiptRoot(controllerHome, scopeKey), `${sanitizeFileComponent(processId)}.json`);
|
|
128
157
|
}
|
|
129
158
|
|
|
130
|
-
|
|
131
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Bounded migration read: a workspace-scoped receipt written before the
|
|
161
|
+
* workspace partition existed still resolves, instead of reporting a running
|
|
162
|
+
* command as missing. Repository scopes never take this path.
|
|
163
|
+
*/
|
|
164
|
+
function existingReceiptPath(
|
|
165
|
+
controllerHome: string,
|
|
166
|
+
scopeKey: string,
|
|
167
|
+
processId: string,
|
|
168
|
+
build: (controllerHome: string, scopeKey: string, processId: string) => string,
|
|
169
|
+
): string {
|
|
170
|
+
const current = build(controllerHome, scopeKey, processId);
|
|
171
|
+
if (existsSync(current) || !isWorkspaceProcessScopeKey(scopeKey)) return current;
|
|
172
|
+
const legacyRoot = legacyWorkspaceScopeRoot(controllerHome, scopeKey);
|
|
173
|
+
if (!legacyRoot) return current;
|
|
174
|
+
const legacy = join(
|
|
175
|
+
legacyRoot,
|
|
176
|
+
'process-runtime',
|
|
177
|
+
build === runningReceiptPath ? 'lightweight-running' : 'lightweight-terminal',
|
|
178
|
+
`${sanitizeFileComponent(processId)}.json`,
|
|
179
|
+
);
|
|
180
|
+
return existsSync(legacy) ? legacy : current;
|
|
132
181
|
}
|
|
133
182
|
|
|
134
183
|
function boundedAppend(current: string, chunk: string, maxBytes: number): string {
|
|
@@ -163,8 +212,8 @@ function captureProcessIdentity(pid: number): ExpectedProcessIdentity | undefine
|
|
|
163
212
|
return { pid, processStartTime, executableFingerprint: executableFingerprint(command) };
|
|
164
213
|
}
|
|
165
214
|
|
|
166
|
-
function removeRunningReceipt(controllerHome: string,
|
|
167
|
-
try { rmSync(runningReceiptPath(controllerHome,
|
|
215
|
+
function removeRunningReceipt(controllerHome: string, scopeKey: string, processId: string): void {
|
|
216
|
+
try { rmSync(runningReceiptPath(controllerHome, scopeKey, processId), { force: true }); } catch { /* best effort */ }
|
|
168
217
|
}
|
|
169
218
|
|
|
170
219
|
function persistRunningReceipt(entry: LightweightEntry, force = false): void {
|
|
@@ -176,12 +225,13 @@ function persistRunningReceipt(entry: LightweightEntry, force = false): void {
|
|
|
176
225
|
if (!force && entry.runningReceiptUpdatedAtMs !== undefined
|
|
177
226
|
&& now - entry.runningReceiptUpdatedAtMs < RUNNING_RECEIPT_PERSIST_INTERVAL_MS) return;
|
|
178
227
|
try {
|
|
179
|
-
const root = runningReceiptRoot(entry.controllerHome, entry.
|
|
228
|
+
const root = runningReceiptRoot(entry.controllerHome, entry.scopeKey);
|
|
180
229
|
mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
181
|
-
const path = runningReceiptPath(entry.controllerHome, entry.
|
|
230
|
+
const path = runningReceiptPath(entry.controllerHome, entry.scopeKey, entry.processId);
|
|
182
231
|
const receipt: LightweightRunningReceipt = {
|
|
183
232
|
schemaVersion: 1,
|
|
184
|
-
|
|
233
|
+
scopeKey: entry.scopeKey,
|
|
234
|
+
...(entry.repoId ? { repoId: entry.repoId } : {}),
|
|
185
235
|
processId: entry.processId,
|
|
186
236
|
commandId: entry.commandId,
|
|
187
237
|
requestFingerprint: entry.requestFingerprint,
|
|
@@ -198,12 +248,12 @@ function persistRunningReceipt(entry: LightweightEntry, force = false): void {
|
|
|
198
248
|
}
|
|
199
249
|
}
|
|
200
250
|
|
|
201
|
-
function readRunningReceipt(controllerHome: string,
|
|
202
|
-
const path =
|
|
251
|
+
function readRunningReceipt(controllerHome: string, scopeKey: string, processId: string): LightweightRunningReceipt | undefined {
|
|
252
|
+
const path = existingReceiptPath(controllerHome, scopeKey, processId, runningReceiptPath);
|
|
203
253
|
if (!existsSync(path)) return undefined;
|
|
204
254
|
try {
|
|
205
255
|
const receipt = readJsonFile<LightweightRunningReceipt>(path);
|
|
206
|
-
if (receipt.schemaVersion !== 1 || receipt.repoId !==
|
|
256
|
+
if (receipt.schemaVersion !== 1 || (receipt.scopeKey ?? receipt.repoId) !== scopeKey || receipt.processId !== processId) return undefined;
|
|
207
257
|
if (receipt.handle?.processId !== processId || receipt.handle.completed) return undefined;
|
|
208
258
|
return receipt;
|
|
209
259
|
} catch {
|
|
@@ -255,18 +305,19 @@ function pruneTerminalReceipts(root: string, keepPath: string): void {
|
|
|
255
305
|
|
|
256
306
|
function persistTerminalReceipt(controllerHome: string, entry: LightweightEntry): void {
|
|
257
307
|
if (!entry.result || !entry.finishedAtMs) return;
|
|
258
|
-
const existing = readTerminalReceipt(controllerHome, entry.
|
|
308
|
+
const existing = readTerminalReceipt(controllerHome, entry.scopeKey, entry.processId);
|
|
259
309
|
if (existing) {
|
|
260
|
-
removeRunningReceipt(controllerHome, entry.
|
|
310
|
+
removeRunningReceipt(controllerHome, entry.scopeKey, entry.processId);
|
|
261
311
|
return;
|
|
262
312
|
}
|
|
263
313
|
try {
|
|
264
|
-
const root = terminalReceiptRoot(controllerHome, entry.
|
|
314
|
+
const root = terminalReceiptRoot(controllerHome, entry.scopeKey);
|
|
265
315
|
mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
266
|
-
const path = terminalReceiptPath(controllerHome, entry.
|
|
316
|
+
const path = terminalReceiptPath(controllerHome, entry.scopeKey, entry.processId);
|
|
267
317
|
const receipt: LightweightTerminalReceipt = {
|
|
268
318
|
schemaVersion: 1,
|
|
269
|
-
|
|
319
|
+
scopeKey: entry.scopeKey,
|
|
320
|
+
...(entry.repoId ? { repoId: entry.repoId } : {}),
|
|
270
321
|
processId: entry.processId,
|
|
271
322
|
commandId: entry.commandId,
|
|
272
323
|
requestFingerprint: entry.requestFingerprint,
|
|
@@ -275,19 +326,19 @@ function persistTerminalReceipt(controllerHome: string, entry: LightweightEntry)
|
|
|
275
326
|
};
|
|
276
327
|
writeJsonAtomic(path, receipt);
|
|
277
328
|
try { chmodSync(path, 0o600); } catch { /* Windows or restricted filesystem. */ }
|
|
278
|
-
removeRunningReceipt(controllerHome, entry.
|
|
329
|
+
removeRunningReceipt(controllerHome, entry.scopeKey, entry.processId);
|
|
279
330
|
pruneTerminalReceipts(root, path);
|
|
280
331
|
} catch {
|
|
281
332
|
// A receipt failure must never turn a completed local command into a failure.
|
|
282
333
|
}
|
|
283
334
|
}
|
|
284
335
|
|
|
285
|
-
function readTerminalReceipt(controllerHome: string,
|
|
286
|
-
const path =
|
|
336
|
+
function readTerminalReceipt(controllerHome: string, scopeKey: string, processId: string): LightweightTerminalReceipt | undefined {
|
|
337
|
+
const path = existingReceiptPath(controllerHome, scopeKey, processId, terminalReceiptPath);
|
|
287
338
|
if (!existsSync(path)) return undefined;
|
|
288
339
|
try {
|
|
289
340
|
const receipt = readJsonFile<LightweightTerminalReceipt>(path);
|
|
290
|
-
if (receipt.schemaVersion !== 1 || receipt.repoId !==
|
|
341
|
+
if (receipt.schemaVersion !== 1 || (receipt.scopeKey ?? receipt.repoId) !== scopeKey || receipt.processId !== processId) return undefined;
|
|
291
342
|
if (!receipt.handle?.completed || receipt.handle.processId !== processId) return undefined;
|
|
292
343
|
const finishedAtMs = Date.parse(receipt.finishedAt);
|
|
293
344
|
if (!Number.isFinite(finishedAtMs) || Date.now() - finishedAtMs > TERMINAL_RECEIPT_RETENTION_MS) {
|
|
@@ -317,24 +368,24 @@ function recoveredRequestMetrics(): LightweightCommandMetrics {
|
|
|
317
368
|
*/
|
|
318
369
|
function findPersistedHandleForCommand(
|
|
319
370
|
controllerHome: string,
|
|
320
|
-
|
|
371
|
+
scopeKey: string,
|
|
321
372
|
commandId: string,
|
|
322
373
|
requestFingerprint: string,
|
|
323
374
|
): ProcessHandle | undefined {
|
|
324
|
-
const roots = [terminalReceiptRoot(controllerHome,
|
|
375
|
+
const roots = [terminalReceiptRoot(controllerHome, scopeKey), runningReceiptRoot(controllerHome, scopeKey)];
|
|
325
376
|
for (const root of roots) {
|
|
326
377
|
if (!existsSync(root)) continue;
|
|
327
378
|
for (const file of readdirSync(root)) {
|
|
328
379
|
if (!file.endsWith('.json')) continue;
|
|
329
380
|
try {
|
|
330
381
|
const receipt = readJsonFile<LightweightRunningReceipt | LightweightTerminalReceipt>(join(root, file));
|
|
331
|
-
if (receipt.schemaVersion !== 1 || receipt.repoId !==
|
|
382
|
+
if (receipt.schemaVersion !== 1 || (receipt.scopeKey ?? receipt.repoId) !== scopeKey || !receipt.processId) continue;
|
|
332
383
|
const persistedCommandId = receipt.commandId ?? receipt.handle?.commandId;
|
|
333
384
|
if (persistedCommandId !== commandId) continue;
|
|
334
385
|
if (!receipt.requestFingerprint || receipt.requestFingerprint !== requestFingerprint) {
|
|
335
386
|
throw new Error(`PROCESS_REQUEST_CONFLICT: command id ${commandId} cannot be safely replayed after Runtime restart`);
|
|
336
387
|
}
|
|
337
|
-
return getLightweightProcessHandle(controllerHome,
|
|
388
|
+
return getLightweightProcessHandle(controllerHome, scopeKey, receipt.processId);
|
|
338
389
|
} catch (error) {
|
|
339
390
|
if (error instanceof Error && error.message.startsWith('PROCESS_REQUEST_CONFLICT:')) throw error;
|
|
340
391
|
// A corrupt or concurrently pruned receipt is not an execution result.
|
|
@@ -393,18 +444,21 @@ function persistRecoveredTerminalReceipt(
|
|
|
393
444
|
receipt: LightweightRunningReceipt,
|
|
394
445
|
handle: ProcessHandle,
|
|
395
446
|
): ProcessHandle {
|
|
396
|
-
const
|
|
447
|
+
const scopeKey = receipt.scopeKey ?? receipt.repoId;
|
|
448
|
+
if (!scopeKey) return handle;
|
|
449
|
+
const existing = readTerminalReceipt(controllerHome, scopeKey, receipt.processId);
|
|
397
450
|
if (existing) {
|
|
398
|
-
removeRunningReceipt(controllerHome,
|
|
451
|
+
removeRunningReceipt(controllerHome, scopeKey, receipt.processId);
|
|
399
452
|
return existing.handle;
|
|
400
453
|
}
|
|
401
454
|
try {
|
|
402
|
-
const root = terminalReceiptRoot(controllerHome,
|
|
455
|
+
const root = terminalReceiptRoot(controllerHome, scopeKey);
|
|
403
456
|
mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
404
|
-
const path = terminalReceiptPath(controllerHome,
|
|
457
|
+
const path = terminalReceiptPath(controllerHome, scopeKey, receipt.processId);
|
|
405
458
|
const terminal: LightweightTerminalReceipt = {
|
|
406
459
|
schemaVersion: 1,
|
|
407
|
-
|
|
460
|
+
scopeKey,
|
|
461
|
+
...(receipt.repoId ? { repoId: receipt.repoId } : {}),
|
|
408
462
|
processId: receipt.processId,
|
|
409
463
|
commandId: receipt.commandId,
|
|
410
464
|
requestFingerprint: receipt.requestFingerprint,
|
|
@@ -413,7 +467,7 @@ function persistRecoveredTerminalReceipt(
|
|
|
413
467
|
};
|
|
414
468
|
writeJsonAtomic(path, terminal);
|
|
415
469
|
try { chmodSync(path, 0o600); } catch { /* Windows or restricted filesystem. */ }
|
|
416
|
-
removeRunningReceipt(controllerHome,
|
|
470
|
+
removeRunningReceipt(controllerHome, scopeKey, receipt.processId);
|
|
417
471
|
pruneTerminalReceipts(root, path);
|
|
418
472
|
} catch {
|
|
419
473
|
// Recovery evidence persistence must not trigger command re-execution or unsafe signalling.
|
|
@@ -549,13 +603,16 @@ function entryHandle(entry: LightweightEntry): ProcessHandle {
|
|
|
549
603
|
|
|
550
604
|
export interface StartLightweightCommandInput {
|
|
551
605
|
controllerHome: string;
|
|
552
|
-
|
|
606
|
+
/** Repository identity is optional: an arbitrary workspace target carries a workspace scope key. */
|
|
607
|
+
repository: RepositoryCommandScopeTarget;
|
|
553
608
|
execution: ExecuteRepositoryCommandInput;
|
|
554
609
|
interactiveWaitMs: number;
|
|
555
610
|
timeoutMs: number;
|
|
556
611
|
maxOutputBytes?: number;
|
|
557
612
|
workId?: string;
|
|
558
613
|
commandId?: string;
|
|
614
|
+
/** Authenticated principal recorded with the handle for principal-bound attachment. */
|
|
615
|
+
principalId?: string;
|
|
559
616
|
/** Start repository preparation on the next event-loop turn so the caller can receive a handle first. */
|
|
560
617
|
deferStart?: boolean;
|
|
561
618
|
/** Reuse an equivalent active local build/test even when a later caller has a different request id. */
|
|
@@ -582,10 +639,15 @@ export interface StartLightweightCheckInput {
|
|
|
582
639
|
timeoutMs: number;
|
|
583
640
|
workId?: string;
|
|
584
641
|
commandId?: string;
|
|
642
|
+
/** Authenticated principal recorded with the handle for principal-bound attachment. */
|
|
643
|
+
principalId?: string;
|
|
585
644
|
}
|
|
586
645
|
|
|
587
646
|
export interface StartLightweightInternalProcessInput {
|
|
588
|
-
repoId
|
|
647
|
+
/** Canonical Process scope key. Defaults to `repoId` for repository-scoped internal processes. */
|
|
648
|
+
scopeKey?: string;
|
|
649
|
+
/** Repository placement when this process targets a repository; absent for ForgeInstance targets. */
|
|
650
|
+
repoId?: string;
|
|
589
651
|
executable: string;
|
|
590
652
|
args: readonly string[];
|
|
591
653
|
cwd: string;
|
|
@@ -597,15 +659,21 @@ export interface StartLightweightInternalProcessInput {
|
|
|
597
659
|
workId?: string;
|
|
598
660
|
commandId?: string;
|
|
599
661
|
signal?: AbortSignal;
|
|
662
|
+
/** Authenticated principal recorded with the handle for principal-bound attachment. */
|
|
663
|
+
principalId?: string;
|
|
600
664
|
}
|
|
601
665
|
|
|
602
666
|
export async function startLightweightRepositoryCommand(
|
|
603
667
|
input: StartLightweightCommandInput,
|
|
604
668
|
): Promise<{ handle: ProcessHandle; metrics: LightweightCommandMetrics }> {
|
|
605
669
|
sweep();
|
|
670
|
+
// Repository targets keep their repository partition; an arbitrary workspace
|
|
671
|
+
// target is scoped by its workspace id instead of a synthetic repository id.
|
|
672
|
+
const scope = processScopeFromKey(commandExecutionScopeKey(input.repository));
|
|
673
|
+
const scopeKey = processScopeKey(scope);
|
|
606
674
|
const stableCommandId = input.commandId?.trim();
|
|
607
675
|
const requestFingerprint = JSON.stringify({
|
|
608
|
-
repoId: input.repository
|
|
676
|
+
repoId: commandExecutionScopeKey(input.repository),
|
|
609
677
|
command: input.execution.command,
|
|
610
678
|
cwd: input.execution.cwd ?? '.',
|
|
611
679
|
timeoutMs: input.timeoutMs,
|
|
@@ -614,7 +682,7 @@ export async function startLightweightRepositoryCommand(
|
|
|
614
682
|
if (stableCommandId) {
|
|
615
683
|
const existing = [...entries.values()].find((entry) => (
|
|
616
684
|
entry.controllerHome === input.controllerHome
|
|
617
|
-
&& entry.
|
|
685
|
+
&& entry.scopeKey === scopeKey
|
|
618
686
|
&& entry.commandId === stableCommandId
|
|
619
687
|
));
|
|
620
688
|
if (existing) {
|
|
@@ -637,7 +705,7 @@ export async function startLightweightRepositoryCommand(
|
|
|
637
705
|
}
|
|
638
706
|
const recovered = findPersistedHandleForCommand(
|
|
639
707
|
input.controllerHome,
|
|
640
|
-
|
|
708
|
+
scopeKey,
|
|
641
709
|
stableCommandId,
|
|
642
710
|
requestFingerprint,
|
|
643
711
|
);
|
|
@@ -645,7 +713,7 @@ export async function startLightweightRepositoryCommand(
|
|
|
645
713
|
}
|
|
646
714
|
if (input.reuseActiveEquivalent) {
|
|
647
715
|
const existing = [...entries.values()].find((entry) => (
|
|
648
|
-
entry.
|
|
716
|
+
entry.scopeKey === scopeKey
|
|
649
717
|
&& entry.requestFingerprint === requestFingerprint
|
|
650
718
|
&& entry.result === undefined
|
|
651
719
|
));
|
|
@@ -669,7 +737,9 @@ export async function startLightweightRepositoryCommand(
|
|
|
669
737
|
const entry: LightweightEntry = {
|
|
670
738
|
processId,
|
|
671
739
|
controllerHome: input.controllerHome,
|
|
672
|
-
|
|
740
|
+
scopeKey,
|
|
741
|
+
...(scope.kind === 'repository' ? { repoId: commandExecutionScopeKey(input.repository) } : {}),
|
|
742
|
+
...(input.principalId ? { principalId: input.principalId } : {}),
|
|
673
743
|
workId: input.workId,
|
|
674
744
|
commandId: stableCommandId || processId,
|
|
675
745
|
requestFingerprint,
|
|
@@ -740,7 +810,31 @@ export async function startLightweightRepositoryCommand(
|
|
|
740
810
|
// degradation is represented by RepositoryCommandExecution.evidenceError;
|
|
741
811
|
// this catch is the final fail-safe for any later post-processing exception.
|
|
742
812
|
if (entry.exitObservation && entry.result) return entry.result;
|
|
743
|
-
|
|
813
|
+
|
|
814
|
+
// Command preparation can fail before spawn (for example a repository-scope
|
|
815
|
+
// or external-filesystem grant denial). In deferred-start mode that rejection
|
|
816
|
+
// must belong to this lightweight Process; allowing it to escape would become
|
|
817
|
+
// an unhandled Runtime rejection and could terminate unrelated in-flight work.
|
|
818
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
819
|
+
const failed: LightweightExecutionResult = {
|
|
820
|
+
ok: false,
|
|
821
|
+
exitCode: 1,
|
|
822
|
+
timedOut: false,
|
|
823
|
+
cancelled: false,
|
|
824
|
+
stdout: visibleOutput(entry.stdout, maxOutputBytes),
|
|
825
|
+
stderr: visibleOutput([entry.stderr, message].filter(Boolean).join('\n'), maxOutputBytes),
|
|
826
|
+
};
|
|
827
|
+
entry.result = failed;
|
|
828
|
+
entry.finishedAtMs = Date.now();
|
|
829
|
+
input.execution.signal?.removeEventListener('abort', onCallerAbort);
|
|
830
|
+
try {
|
|
831
|
+
input.onCompleted?.(failed);
|
|
832
|
+
} catch (callbackError) {
|
|
833
|
+
const callbackMessage = callbackError instanceof Error ? callbackError.message : String(callbackError);
|
|
834
|
+
failed.stderr = visibleOutput([failed.stderr, callbackMessage].filter(Boolean).join('\n'), maxOutputBytes);
|
|
835
|
+
}
|
|
836
|
+
persistTerminalReceipt(input.controllerHome, entry);
|
|
837
|
+
return failed;
|
|
744
838
|
});
|
|
745
839
|
entry.promise = input.deferStart
|
|
746
840
|
? new Promise<LightweightExecutionResult>((resolve, reject) => {
|
|
@@ -750,6 +844,16 @@ export async function startLightweightRepositoryCommand(
|
|
|
750
844
|
})
|
|
751
845
|
: startExecution();
|
|
752
846
|
entries.set(processId, entry);
|
|
847
|
+
// Instance-level locator: a lightweight handle must be attachable from the
|
|
848
|
+
// returned processId alone, including after Runtime memory loss.
|
|
849
|
+
recordProcessHandleIndexEntry(input.controllerHome, {
|
|
850
|
+
processId,
|
|
851
|
+
lane: 'lightweight',
|
|
852
|
+
target: processScopeExecutionTarget(input.controllerHome, processScopeFromKey(entry.scopeKey)),
|
|
853
|
+
principalId: entry.principalId,
|
|
854
|
+
workId: entry.workId,
|
|
855
|
+
commandId: entry.commandId,
|
|
856
|
+
});
|
|
753
857
|
persistRunningReceipt(entry, true);
|
|
754
858
|
|
|
755
859
|
if (entry.interactiveWaitMs > 0) {
|
|
@@ -781,18 +885,31 @@ export async function startLightweightInternalProcess(
|
|
|
781
885
|
input: StartLightweightInternalProcessInput,
|
|
782
886
|
): Promise<{ handle: ProcessHandle; metrics: LightweightCommandMetrics }> {
|
|
783
887
|
sweep();
|
|
888
|
+
const repoId = input.repoId?.trim() || undefined;
|
|
889
|
+
const scopeKey = normalizeProcessScopeKey(input.scopeKey?.trim() || repoId || '');
|
|
890
|
+
const scope = processScopeFromKey(scopeKey);
|
|
784
891
|
const stableCommandId = input.commandId?.trim();
|
|
892
|
+
// Retry identity is commandId + fingerprint(scope target, action, principal).
|
|
893
|
+
// An instance-scope request id is never a naked global namespace: a different
|
|
894
|
+
// principal presenting the same request id fails closed as a request conflict
|
|
895
|
+
// instead of attaching to another principal's process.
|
|
896
|
+
const principalId = input.principalId?.trim() || null;
|
|
785
897
|
const requestFingerprint = JSON.stringify({
|
|
786
|
-
|
|
898
|
+
scopeKey,
|
|
899
|
+
repoId: repoId ?? null,
|
|
787
900
|
executable: input.executable,
|
|
788
901
|
args: input.args,
|
|
789
902
|
cwd: input.cwd,
|
|
790
903
|
timeoutMs: input.timeoutMs,
|
|
904
|
+
// Only a principal-bound lane (the ForgeInstance host command lane) adds the
|
|
905
|
+
// principal to retry identity, so existing repository/plugin fingerprints
|
|
906
|
+
// keep their historical value instead of failing closed after an upgrade.
|
|
907
|
+
...(principalId ? { principalId } : {}),
|
|
791
908
|
});
|
|
792
909
|
if (stableCommandId) {
|
|
793
910
|
const existing = [...entries.values()].find((entry) => (
|
|
794
911
|
entry.controllerHome === input.controllerHome
|
|
795
|
-
&& entry.
|
|
912
|
+
&& entry.scopeKey === scopeKey
|
|
796
913
|
&& entry.commandId === stableCommandId
|
|
797
914
|
));
|
|
798
915
|
if (existing) {
|
|
@@ -815,7 +932,7 @@ export async function startLightweightInternalProcess(
|
|
|
815
932
|
}
|
|
816
933
|
const recovered = findPersistedHandleForCommand(
|
|
817
934
|
input.controllerHome,
|
|
818
|
-
|
|
935
|
+
scopeKey,
|
|
819
936
|
stableCommandId,
|
|
820
937
|
requestFingerprint,
|
|
821
938
|
);
|
|
@@ -828,7 +945,9 @@ export async function startLightweightInternalProcess(
|
|
|
828
945
|
const entry: LightweightEntry = {
|
|
829
946
|
processId,
|
|
830
947
|
controllerHome: input.controllerHome,
|
|
831
|
-
|
|
948
|
+
scopeKey,
|
|
949
|
+
...(repoId ? { repoId } : {}),
|
|
950
|
+
...(input.principalId?.trim() ? { principalId: input.principalId.trim() } : {}),
|
|
832
951
|
workId: input.workId,
|
|
833
952
|
commandId: stableCommandId || processId,
|
|
834
953
|
requestFingerprint,
|
|
@@ -876,6 +995,14 @@ export async function startLightweightInternalProcess(
|
|
|
876
995
|
return result;
|
|
877
996
|
});
|
|
878
997
|
entries.set(processId, entry);
|
|
998
|
+
recordProcessHandleIndexEntry(entry.controllerHome, {
|
|
999
|
+
processId,
|
|
1000
|
+
lane: 'lightweight',
|
|
1001
|
+
target: processScopeExecutionTarget(entry.controllerHome, processScopeFromKey(entry.scopeKey)),
|
|
1002
|
+
principalId: entry.principalId,
|
|
1003
|
+
workId: entry.workId,
|
|
1004
|
+
commandId: entry.commandId,
|
|
1005
|
+
});
|
|
879
1006
|
persistRunningReceipt(entry, true);
|
|
880
1007
|
|
|
881
1008
|
if (entry.interactiveWaitMs > 0) {
|
|
@@ -903,6 +1030,68 @@ export async function startLightweightInternalProcess(
|
|
|
903
1030
|
};
|
|
904
1031
|
}
|
|
905
1032
|
|
|
1033
|
+
export interface StartLightweightHostCommandInput {
|
|
1034
|
+
controllerHome: string;
|
|
1035
|
+
/** Typed argv command; `command[0]` is the executable. */
|
|
1036
|
+
command?: readonly string[];
|
|
1037
|
+
/** Explicit broad host-shell form. Authorized by the same host process grant as argv. */
|
|
1038
|
+
shellCommand?: string;
|
|
1039
|
+
cwd: string;
|
|
1040
|
+
env?: NodeJS.ProcessEnv;
|
|
1041
|
+
interactiveWaitMs: number;
|
|
1042
|
+
timeoutMs: number;
|
|
1043
|
+
maxOutputBytes?: number;
|
|
1044
|
+
workId?: string;
|
|
1045
|
+
commandId?: string;
|
|
1046
|
+
signal?: AbortSignal;
|
|
1047
|
+
principalId?: string;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
/** Platform shell used for the explicit `shell_command` form. Mirrors the Process Runner convention. */
|
|
1051
|
+
export function hostShellInvocation(shellCommand: string): readonly string[] {
|
|
1052
|
+
const command = shellCommand.trim();
|
|
1053
|
+
if (!command) throw new Error('HOST_COMMAND_SHELL_STRING_REQUIRED');
|
|
1054
|
+
return process.platform === 'win32'
|
|
1055
|
+
? ['cmd.exe', '/c', command]
|
|
1056
|
+
: ['/bin/bash', '-lc', command];
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
function hostCommandArgv(input: StartLightweightHostCommandInput): readonly string[] {
|
|
1060
|
+
const shellCommand = input.shellCommand?.trim();
|
|
1061
|
+
if (shellCommand) return hostShellInvocation(shellCommand);
|
|
1062
|
+
const argv = (input.command ?? []).map((entry) => String(entry));
|
|
1063
|
+
if (argv.length === 0 || !argv[0]) throw new Error('HOST_COMMAND_ARGV_REQUIRED');
|
|
1064
|
+
return argv;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
/**
|
|
1068
|
+
* Mode-free host-local command lane. The target is the ForgeInstance, `cwd` is
|
|
1069
|
+
* an execution argument, and no repository registration or checkout identity is
|
|
1070
|
+
* required. Authorization is the caller's responsibility: this lane performs no
|
|
1071
|
+
* command parsing and never becomes a path sandbox.
|
|
1072
|
+
*/
|
|
1073
|
+
export async function startLightweightHostCommand(
|
|
1074
|
+
input: StartLightweightHostCommandInput,
|
|
1075
|
+
): Promise<{ handle: ProcessHandle; metrics: LightweightCommandMetrics }> {
|
|
1076
|
+
const argv = hostCommandArgv(input);
|
|
1077
|
+
const executable = argv[0]!;
|
|
1078
|
+
return startLightweightInternalProcess({
|
|
1079
|
+
controllerHome: input.controllerHome,
|
|
1080
|
+
scopeKey: FORGE_INSTANCE_PROCESS_SCOPE_KEY,
|
|
1081
|
+
executable,
|
|
1082
|
+
args: argv.slice(1),
|
|
1083
|
+
cwd: input.cwd,
|
|
1084
|
+
env: input.env,
|
|
1085
|
+
interactiveWaitMs: input.interactiveWaitMs,
|
|
1086
|
+
timeoutMs: input.timeoutMs,
|
|
1087
|
+
maxOutputBytes: input.maxOutputBytes,
|
|
1088
|
+
workId: input.workId,
|
|
1089
|
+
commandId: input.commandId,
|
|
1090
|
+
signal: input.signal,
|
|
1091
|
+
principalId: input.principalId,
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
|
|
906
1095
|
export async function startLightweightControllerCheck(
|
|
907
1096
|
input: StartLightweightCheckInput,
|
|
908
1097
|
): Promise<{ handle: ProcessHandle; metrics: LightweightCommandMetrics }> {
|
|
@@ -917,7 +1106,7 @@ export async function startLightweightControllerCheck(
|
|
|
917
1106
|
if (stableCommandId) {
|
|
918
1107
|
const existing = [...entries.values()].find((entry) => (
|
|
919
1108
|
entry.controllerHome === input.controllerHome
|
|
920
|
-
&& entry.
|
|
1109
|
+
&& entry.scopeKey === input.repoId
|
|
921
1110
|
&& entry.commandId === stableCommandId
|
|
922
1111
|
));
|
|
923
1112
|
if (existing) {
|
|
@@ -952,7 +1141,9 @@ export async function startLightweightControllerCheck(
|
|
|
952
1141
|
const entry: LightweightEntry = {
|
|
953
1142
|
processId,
|
|
954
1143
|
controllerHome: input.controllerHome,
|
|
1144
|
+
scopeKey: input.repoId,
|
|
955
1145
|
repoId: input.repoId,
|
|
1146
|
+
...(input.principalId ? { principalId: input.principalId } : {}),
|
|
956
1147
|
workId: input.workId,
|
|
957
1148
|
commandId: stableCommandId || processId,
|
|
958
1149
|
requestFingerprint,
|
|
@@ -974,6 +1165,7 @@ export async function startLightweightControllerCheck(
|
|
|
974
1165
|
}, { once: true });
|
|
975
1166
|
entry.promise = runControllerCheckAsync(input.repoRoot, input.checkId, {
|
|
976
1167
|
requestedTimeoutMs: input.timeoutMs,
|
|
1168
|
+
storageAuthority: { controllerHome: input.controllerHome, repoId: input.repoId },
|
|
977
1169
|
subscriberId: processId,
|
|
978
1170
|
onSpawn: (pid) => {
|
|
979
1171
|
entry.pid = pid;
|
|
@@ -1000,6 +1192,14 @@ export async function startLightweightControllerCheck(
|
|
|
1000
1192
|
return result;
|
|
1001
1193
|
});
|
|
1002
1194
|
entries.set(processId, entry);
|
|
1195
|
+
recordProcessHandleIndexEntry(entry.controllerHome, {
|
|
1196
|
+
processId,
|
|
1197
|
+
lane: 'lightweight',
|
|
1198
|
+
target: processScopeExecutionTarget(entry.controllerHome, processScopeFromKey(entry.scopeKey)),
|
|
1199
|
+
principalId: entry.principalId,
|
|
1200
|
+
workId: entry.workId,
|
|
1201
|
+
commandId: entry.commandId,
|
|
1202
|
+
});
|
|
1003
1203
|
persistRunningReceipt(entry, true);
|
|
1004
1204
|
|
|
1005
1205
|
if (entry.interactiveWaitMs > 0) {
|
|
@@ -1027,10 +1227,10 @@ export async function startLightweightControllerCheck(
|
|
|
1027
1227
|
};
|
|
1028
1228
|
}
|
|
1029
1229
|
|
|
1030
|
-
function requireEntry(
|
|
1230
|
+
function requireEntry(scopeKey: string, processId: string): LightweightEntry {
|
|
1031
1231
|
const entry = entries.get(processId);
|
|
1032
1232
|
if (!entry) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
|
|
1033
|
-
if (entry.
|
|
1233
|
+
if (entry.scopeKey !== scopeKey) throw new Error(`PROCESS_SCOPE_MISMATCH: process ${processId} belongs to ${entry.scopeKey}, not ${scopeKey}`);
|
|
1034
1234
|
return entry;
|
|
1035
1235
|
}
|
|
1036
1236
|
|
|
@@ -1038,17 +1238,27 @@ export function isLightweightProcessId(processId: string): boolean {
|
|
|
1038
1238
|
return processId.startsWith('lightweight:');
|
|
1039
1239
|
}
|
|
1040
1240
|
|
|
1241
|
+
/** Repository placement of a lightweight handle this Runtime still owns in memory. */
|
|
1242
|
+
export function lightweightProcessRepositoryId(processId: string): string | undefined {
|
|
1243
|
+
return entries.get(processId)?.repoId;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
/** Canonical Process scope key of a lightweight handle this Runtime still owns in memory. */
|
|
1247
|
+
export function lightweightProcessScopeKey(processId: string): string | undefined {
|
|
1248
|
+
return entries.get(processId)?.scopeKey;
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1041
1251
|
/** Test seam for proving terminal receipt recovery across Runtime-memory loss. */
|
|
1042
1252
|
export function clearLightweightProcessMemoryForTest(): void {
|
|
1043
1253
|
entries.clear();
|
|
1044
1254
|
}
|
|
1045
1255
|
|
|
1046
|
-
export function getLightweightProcessHandle(controllerHome: string,
|
|
1256
|
+
export function getLightweightProcessHandle(controllerHome: string, scopeKey: string, processId: string): ProcessHandle | undefined {
|
|
1047
1257
|
const entry = entries.get(processId);
|
|
1048
|
-
if (entry?.
|
|
1049
|
-
const terminal = readTerminalReceipt(controllerHome,
|
|
1258
|
+
if (entry?.scopeKey === scopeKey) return entryHandle(entry);
|
|
1259
|
+
const terminal = readTerminalReceipt(controllerHome, scopeKey, processId);
|
|
1050
1260
|
if (terminal) return terminal.handle;
|
|
1051
|
-
const running = readRunningReceipt(controllerHome,
|
|
1261
|
+
const running = readRunningReceipt(controllerHome, scopeKey, processId);
|
|
1052
1262
|
if (!running) return undefined;
|
|
1053
1263
|
if (running.exitObservation) {
|
|
1054
1264
|
return persistRecoveredTerminalReceipt(controllerHome, running, completedObservedExitHandle(running));
|
|
@@ -1063,20 +1273,20 @@ export function getLightweightProcessHandle(controllerHome: string, repoId: stri
|
|
|
1063
1273
|
|
|
1064
1274
|
export async function waitForLightweightProcess(
|
|
1065
1275
|
controllerHome: string,
|
|
1066
|
-
|
|
1276
|
+
scopeKey: string,
|
|
1067
1277
|
processId: string,
|
|
1068
1278
|
options: WaitProcessOptions = {},
|
|
1069
1279
|
): Promise<ProcessHandle> {
|
|
1070
1280
|
const entry = entries.get(processId);
|
|
1071
1281
|
if (!entry) {
|
|
1072
|
-
const terminal = readTerminalReceipt(controllerHome,
|
|
1282
|
+
const terminal = readTerminalReceipt(controllerHome, scopeKey, processId);
|
|
1073
1283
|
if (terminal) return terminal.handle;
|
|
1074
|
-
let running = readRunningReceipt(controllerHome,
|
|
1284
|
+
let running = readRunningReceipt(controllerHome, scopeKey, processId);
|
|
1075
1285
|
if (!running) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
|
|
1076
1286
|
const timeoutMs = Math.max(1, options.timeoutMs ?? 15_000);
|
|
1077
1287
|
const deadline = Date.now() + timeoutMs;
|
|
1078
1288
|
while (true) {
|
|
1079
|
-
const recoveredTerminal = readTerminalReceipt(controllerHome,
|
|
1289
|
+
const recoveredTerminal = readTerminalReceipt(controllerHome, scopeKey, processId);
|
|
1080
1290
|
if (recoveredTerminal) return recoveredTerminal.handle;
|
|
1081
1291
|
if (running.exitObservation) {
|
|
1082
1292
|
return persistRecoveredTerminalReceipt(controllerHome, running, completedObservedExitHandle(running));
|
|
@@ -1093,10 +1303,10 @@ export async function waitForLightweightProcess(
|
|
|
1093
1303
|
const timer = setTimeout(resolve, Math.min(50, Math.max(1, deadline - Date.now())));
|
|
1094
1304
|
timer.unref?.();
|
|
1095
1305
|
});
|
|
1096
|
-
running = readRunningReceipt(controllerHome,
|
|
1306
|
+
running = readRunningReceipt(controllerHome, scopeKey, processId) ?? running;
|
|
1097
1307
|
}
|
|
1098
1308
|
}
|
|
1099
|
-
if (entry.
|
|
1309
|
+
if (entry.scopeKey !== scopeKey) throw new Error(`PROCESS_SCOPE_MISMATCH: process ${processId} belongs to ${entry.scopeKey}, not ${scopeKey}`);
|
|
1100
1310
|
if (entry.result) return entryHandle(entry);
|
|
1101
1311
|
const timeoutMs = Math.max(1, options.timeoutMs ?? 15_000);
|
|
1102
1312
|
await Promise.race([
|
|
@@ -1120,12 +1330,12 @@ export async function cancelAllLightweightProcesses(controllerHome: string): Pro
|
|
|
1120
1330
|
return active.length;
|
|
1121
1331
|
}
|
|
1122
1332
|
|
|
1123
|
-
export async function cancelLightweightProcess(controllerHome: string,
|
|
1333
|
+
export async function cancelLightweightProcess(controllerHome: string, scopeKey: string, processId: string): Promise<ProcessHandle> {
|
|
1124
1334
|
const entry = entries.get(processId);
|
|
1125
1335
|
if (!entry) {
|
|
1126
|
-
const terminal = readTerminalReceipt(controllerHome,
|
|
1336
|
+
const terminal = readTerminalReceipt(controllerHome, scopeKey, processId);
|
|
1127
1337
|
if (terminal) return terminal.handle;
|
|
1128
|
-
const running = readRunningReceipt(controllerHome,
|
|
1338
|
+
const running = readRunningReceipt(controllerHome, scopeKey, processId);
|
|
1129
1339
|
if (!running) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
|
|
1130
1340
|
if (running.exitObservation) {
|
|
1131
1341
|
return persistRecoveredTerminalReceipt(controllerHome, running, completedObservedExitHandle(running));
|
|
@@ -1140,7 +1350,7 @@ export async function cancelLightweightProcess(controllerHome: string, repoId: s
|
|
|
1140
1350
|
await terminateProcessTree(pid, { gracePeriodMs: 200, killAfterMs: 1_000, pollIntervalMs: 25 });
|
|
1141
1351
|
return persistRecoveredTerminalReceipt(controllerHome, running, cancelledRecoveredHandle(running));
|
|
1142
1352
|
}
|
|
1143
|
-
if (entry.
|
|
1353
|
+
if (entry.scopeKey !== scopeKey) throw new Error(`PROCESS_SCOPE_MISMATCH: process ${processId} belongs to ${entry.scopeKey}, not ${scopeKey}`);
|
|
1144
1354
|
if (!entry.result) {
|
|
1145
1355
|
entry.abort.abort();
|
|
1146
1356
|
await entry.promise;
|
|
@@ -1150,13 +1360,13 @@ export async function cancelLightweightProcess(controllerHome: string, repoId: s
|
|
|
1150
1360
|
|
|
1151
1361
|
export function readLightweightProcessLogs(
|
|
1152
1362
|
controllerHome: string,
|
|
1153
|
-
|
|
1363
|
+
scopeKey: string,
|
|
1154
1364
|
processId: string,
|
|
1155
1365
|
maxBytes = 32 * 1024,
|
|
1156
1366
|
): ProcessLogSlice | undefined {
|
|
1157
1367
|
const entry = entries.get(processId);
|
|
1158
1368
|
if (!entry) {
|
|
1159
|
-
const terminal = readTerminalReceipt(controllerHome,
|
|
1369
|
+
const terminal = readTerminalReceipt(controllerHome, scopeKey, processId);
|
|
1160
1370
|
if (terminal) {
|
|
1161
1371
|
const stdout = capProcessOutput(terminal.handle.stdout ?? '', maxBytes);
|
|
1162
1372
|
const stderr = capProcessOutput(terminal.handle.stderr ?? '', maxBytes);
|
|
@@ -1170,7 +1380,7 @@ export function readLightweightProcessLogs(
|
|
|
1170
1380
|
|| Buffer.byteLength(terminal.handle.stderr ?? '', 'utf8') > maxBytes,
|
|
1171
1381
|
};
|
|
1172
1382
|
}
|
|
1173
|
-
const running = readRunningReceipt(controllerHome,
|
|
1383
|
+
const running = readRunningReceipt(controllerHome, scopeKey, processId);
|
|
1174
1384
|
if (!running) return undefined;
|
|
1175
1385
|
const stdout = capProcessOutput(running.handle.stdoutTail ?? '', maxBytes);
|
|
1176
1386
|
const stderr = capProcessOutput(running.handle.stderrTail ?? '', maxBytes);
|
|
@@ -1184,7 +1394,7 @@ export function readLightweightProcessLogs(
|
|
|
1184
1394
|
|| Buffer.byteLength(running.handle.stderrTail ?? '', 'utf8') > maxBytes,
|
|
1185
1395
|
};
|
|
1186
1396
|
}
|
|
1187
|
-
if (entry.
|
|
1397
|
+
if (entry.scopeKey !== scopeKey) return undefined;
|
|
1188
1398
|
const rawStdout = entry.result?.stdout ?? entry.stdout;
|
|
1189
1399
|
const rawStderr = entry.result?.stderr ?? entry.stderr;
|
|
1190
1400
|
const visibleStdout = visibleOutput(rawStdout, maxBytes);
|