@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
|
@@ -135,9 +135,115 @@ export function rollbackStoppedRepoLocalControllerHomeStorage(migration: Control
|
|
|
135
135
|
renameSync(physicalHome, logicalHome);
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
|
|
139
|
+
export interface StoppedControllerHomeAuthorityRelocation {
|
|
140
|
+
migrated: boolean;
|
|
141
|
+
sourceHome: string;
|
|
142
|
+
destinationHome: string;
|
|
143
|
+
archivedDestinationHome?: string;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function directoryEntryExists(path: string): boolean {
|
|
147
|
+
try { lstatSync(path); return true; } catch (error) {
|
|
148
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false;
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Atomically relocate one fully stopped Controller Home to a new durable path.
|
|
155
|
+
* The caller owns liveness fencing and must prove Runtime, Connector, Recovery
|
|
156
|
+
* Gateway, Recovery Watchdog, and any other writers are stopped before calling.
|
|
157
|
+
*
|
|
158
|
+
* Existing destination contents are never merged. A caller that has already
|
|
159
|
+
* proven the destination is an authority-free shell may request archival; the
|
|
160
|
+
* entire shell is renamed aside so rollback can restore it byte-for-byte.
|
|
161
|
+
*/
|
|
162
|
+
export function relocateStoppedControllerHomeAuthority(input: {
|
|
163
|
+
sourceHome: string;
|
|
164
|
+
destinationHome: string;
|
|
165
|
+
archiveExistingDestination?: boolean;
|
|
166
|
+
archiveSuffix?: string;
|
|
167
|
+
}): StoppedControllerHomeAuthorityRelocation {
|
|
168
|
+
const sourceHome = resolve(input.sourceHome);
|
|
169
|
+
const destinationHome = resolve(input.destinationHome);
|
|
170
|
+
if (sourceHome === destinationHome) throw new Error('CONTROLLER_HOME_RELOCATION_SAME_HOME');
|
|
171
|
+
if (!directoryEntryExists(sourceHome)) throw new Error(`CONTROLLER_HOME_RELOCATION_SOURCE_MISSING: ${sourceHome}`);
|
|
172
|
+
const sourceStat = lstatSync(sourceHome);
|
|
173
|
+
if (!sourceStat.isDirectory() || sourceStat.isSymbolicLink()) {
|
|
174
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_SOURCE_UNSUPPORTED: ${sourceHome}`);
|
|
175
|
+
}
|
|
176
|
+
mkdirSync(dirname(destinationHome), { recursive: true });
|
|
177
|
+
|
|
178
|
+
let archivedDestinationHome: string | undefined;
|
|
179
|
+
if (directoryEntryExists(destinationHome)) {
|
|
180
|
+
const destinationStat = lstatSync(destinationHome);
|
|
181
|
+
if (!destinationStat.isDirectory() || destinationStat.isSymbolicLink()) {
|
|
182
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_DESTINATION_UNSUPPORTED: ${destinationHome}`);
|
|
183
|
+
}
|
|
184
|
+
if (!input.archiveExistingDestination) {
|
|
185
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_DESTINATION_EXISTS: ${destinationHome}`);
|
|
186
|
+
}
|
|
187
|
+
const suffix = input.archiveSuffix?.trim() || `${Date.now()}-${process.pid}`;
|
|
188
|
+
if (!/^[A-Za-z0-9._-]{1,120}$/.test(suffix)) throw new Error('CONTROLLER_HOME_RELOCATION_ARCHIVE_SUFFIX_INVALID');
|
|
189
|
+
archivedDestinationHome = `${destinationHome}.pre-migration-${suffix}`;
|
|
190
|
+
if (directoryEntryExists(archivedDestinationHome)) {
|
|
191
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_ARCHIVE_EXISTS: ${archivedDestinationHome}`);
|
|
192
|
+
}
|
|
193
|
+
renameSync(destinationHome, archivedDestinationHome);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
renameSync(sourceHome, destinationHome);
|
|
198
|
+
if (directoryEntryExists(sourceHome) || !lstatSync(destinationHome).isDirectory()) {
|
|
199
|
+
throw new Error('CONTROLLER_HOME_RELOCATION_POSTCHECK_FAILED');
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
migrated: true,
|
|
203
|
+
sourceHome,
|
|
204
|
+
destinationHome,
|
|
205
|
+
...(archivedDestinationHome ? { archivedDestinationHome } : {}),
|
|
206
|
+
};
|
|
207
|
+
} catch (error) {
|
|
208
|
+
try {
|
|
209
|
+
if (!directoryEntryExists(sourceHome) && directoryEntryExists(destinationHome)) renameSync(destinationHome, sourceHome);
|
|
210
|
+
if (archivedDestinationHome && !directoryEntryExists(destinationHome) && directoryEntryExists(archivedDestinationHome)) {
|
|
211
|
+
renameSync(archivedDestinationHome, destinationHome);
|
|
212
|
+
}
|
|
213
|
+
} catch {
|
|
214
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_ROLLBACK_FAILED: ${error instanceof Error ? error.message : String(error)}`);
|
|
215
|
+
}
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Caller must keep all Controller Home writers stopped until rollback completes. */
|
|
221
|
+
export function rollbackStoppedControllerHomeAuthorityRelocation(
|
|
222
|
+
relocation: StoppedControllerHomeAuthorityRelocation,
|
|
223
|
+
): void {
|
|
224
|
+
if (!relocation.migrated) return;
|
|
225
|
+
const sourceHome = resolve(relocation.sourceHome);
|
|
226
|
+
const destinationHome = resolve(relocation.destinationHome);
|
|
227
|
+
const archivedDestinationHome = relocation.archivedDestinationHome ? resolve(relocation.archivedDestinationHome) : undefined;
|
|
228
|
+
if (directoryEntryExists(sourceHome)) throw new Error(`CONTROLLER_HOME_RELOCATION_ROLLBACK_SOURCE_EXISTS: ${sourceHome}`);
|
|
229
|
+
if (!directoryEntryExists(destinationHome) || !lstatSync(destinationHome).isDirectory()) {
|
|
230
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_ROLLBACK_DESTINATION_MISSING: ${destinationHome}`);
|
|
231
|
+
}
|
|
232
|
+
if (archivedDestinationHome && !directoryEntryExists(archivedDestinationHome)) {
|
|
233
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_ROLLBACK_ARCHIVE_MISSING: ${archivedDestinationHome}`);
|
|
234
|
+
}
|
|
235
|
+
renameSync(destinationHome, sourceHome);
|
|
236
|
+
try {
|
|
237
|
+
if (archivedDestinationHome) renameSync(archivedDestinationHome, destinationHome);
|
|
238
|
+
} catch (error) {
|
|
239
|
+
try { if (!directoryEntryExists(destinationHome) && directoryEntryExists(sourceHome)) renameSync(sourceHome, destinationHome); } catch { /* best effort */ }
|
|
240
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_ROLLBACK_RESTORE_FAILED: ${error instanceof Error ? error.message : String(error)}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
138
244
|
export function ensureControllerHome(explicit?: string): string {
|
|
139
245
|
const home = ensureControllerHomeStorage(resolveControllerHome(explicit));
|
|
140
|
-
for (const child of ['', 'repositories', 'system', 'locks', 'indexes', 'audit', 'mcp', 'sessions', 'work-handles']) {
|
|
246
|
+
for (const child of ['', 'repositories', 'system', 'locks', 'indexes', 'audit', 'mcp', 'sessions', 'work-handles', 'workflows']) {
|
|
141
247
|
mkdirSync(join(home, child), { recursive: true });
|
|
142
248
|
}
|
|
143
249
|
return home;
|
|
@@ -147,7 +253,21 @@ export function ensureRepoPreferredControllerHome(repoRoot?: string, explicit?:
|
|
|
147
253
|
return ensureControllerHome(resolveRepoPreferredControllerHome(repoRoot, explicit));
|
|
148
254
|
}
|
|
149
255
|
|
|
256
|
+
/** Legacy adapter-only sentinel. Never use this as a canonical storage or resource scope. */
|
|
150
257
|
export const CONTROLLER_SCOPE_REPO_ID = '__controller__';
|
|
258
|
+
/** Canonical mechanical scope for state owned by the serving ForgeInstance itself. */
|
|
259
|
+
export const FORGE_INSTANCE_SCOPE_KEY = 'forge-instance';
|
|
260
|
+
|
|
261
|
+
/** Human-editable user Workflow Asset content. Machine workflow state stays in control-plane persistence. */
|
|
262
|
+
export function controllerWorkflowContentRoot(controllerHome: string): string {
|
|
263
|
+
return join(resolveControllerHome(controllerHome), 'workflows');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export function ensureControllerWorkflowContentRoot(controllerHome: string): string {
|
|
267
|
+
const root = controllerWorkflowContentRoot(ensureControllerHome(controllerHome));
|
|
268
|
+
mkdirSync(root, { recursive: true });
|
|
269
|
+
return root;
|
|
270
|
+
}
|
|
151
271
|
|
|
152
272
|
export function controllerSystemRoot(controllerHome: string): string {
|
|
153
273
|
return join(resolveControllerHome(controllerHome), 'system');
|
|
@@ -166,6 +286,51 @@ export function repositoryControllerRoot(controllerHome: string, repoId: string)
|
|
|
166
286
|
: join(resolveControllerHome(durableHome), 'repositories', repoId);
|
|
167
287
|
}
|
|
168
288
|
|
|
289
|
+
/** Reserved prefix for arbitrary workspace scopes; registered repository ids are `repo_*`. */
|
|
290
|
+
export const WORKSPACE_SCOPE_PREFIX = 'workspace_';
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Reserved scope key for portable semantic facts (Requirement/Plan/Work) that
|
|
294
|
+
* belong to the ForgeInstance rather than to one repository. Repository and
|
|
295
|
+
* project placement stays optional provenance on those records.
|
|
296
|
+
*/
|
|
297
|
+
export const SEMANTIC_SCOPE_KEY = 'semantic';
|
|
298
|
+
|
|
299
|
+
export function isWorkspaceScopeKey(scopeKey: string): boolean {
|
|
300
|
+
return scopeKey.trim().startsWith(WORKSPACE_SCOPE_PREFIX);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export function isSemanticScopeKey(scopeKey: string): boolean {
|
|
304
|
+
return scopeKey.trim() === SEMANTIC_SCOPE_KEY;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Controller-Home root for an arbitrary workspace scope. A workspace has no
|
|
309
|
+
* repository semantics, so its operation facts own a sibling partition instead
|
|
310
|
+
* of a repository partition.
|
|
311
|
+
*/
|
|
312
|
+
export function workspaceScopeRoot(controllerHome: string, scopeKey: string): string {
|
|
313
|
+
const key = scopeKey.trim();
|
|
314
|
+
if (!isWorkspaceScopeKey(key)) throw new Error(`WORKSPACE_SCOPE_KEY_REQUIRED: ${scopeKey}`);
|
|
315
|
+
return join(resolveControllerHome(durableControllerHome(controllerHome)), 'workspaces', key);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Controller-Home root for one operation scope key. Repository scopes (including
|
|
320
|
+
* the controller-system sentinel) keep their established root; workspace scopes
|
|
321
|
+
* own the workspace partition.
|
|
322
|
+
*/
|
|
323
|
+
export function scopedOperationRoot(controllerHome: string, scopeKey: string): string {
|
|
324
|
+
const key = scopeKey.trim();
|
|
325
|
+
return key === FORGE_INSTANCE_SCOPE_KEY
|
|
326
|
+
? controllerSystemRoot(controllerHome)
|
|
327
|
+
: isWorkspaceScopeKey(key)
|
|
328
|
+
? workspaceScopeRoot(controllerHome, key)
|
|
329
|
+
: isSemanticScopeKey(key)
|
|
330
|
+
? join(resolveControllerHome(durableControllerHome(controllerHome)), SEMANTIC_SCOPE_KEY)
|
|
331
|
+
: repositoryControllerRoot(controllerHome, key);
|
|
332
|
+
}
|
|
333
|
+
|
|
169
334
|
export function ensureRepositoryControllerLayout(controllerHome: string, repoId: string): string {
|
|
170
335
|
const root = repositoryControllerRoot(controllerHome, repoId);
|
|
171
336
|
for (const child of [
|
|
@@ -178,6 +343,7 @@ export function ensureRepositoryControllerLayout(controllerHome: string, repoId:
|
|
|
178
343
|
'indexes',
|
|
179
344
|
'edit-sessions',
|
|
180
345
|
'controller',
|
|
346
|
+
'hook-state',
|
|
181
347
|
'local-bridge',
|
|
182
348
|
'ephemeral-issues',
|
|
183
349
|
'work-handles',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'crypto';
|
|
2
2
|
import { existsSync, realpathSync, statSync } from 'fs';
|
|
3
|
-
import { isAbsolute
|
|
4
|
-
import type {
|
|
3
|
+
import { isAbsolute } from 'path';
|
|
4
|
+
import type { RepositoryCommandScopeTarget } from './command-scope';
|
|
5
5
|
|
|
6
6
|
export interface EphemeralWorkspaceCoordinates {
|
|
7
7
|
workspaceId: string;
|
|
@@ -10,7 +10,11 @@ export interface EphemeralWorkspaceCoordinates {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export interface EphemeralWorkspaceTarget extends EphemeralWorkspaceCoordinates {
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Typed command target for an arbitrary workspace: it carries the workspace
|
|
15
|
+
* scope key and root, and no repository identity at all.
|
|
16
|
+
*/
|
|
17
|
+
commandTarget: RepositoryCommandScopeTarget;
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
export function ephemeralWorkspaceCoordinates(rootInput: string): EphemeralWorkspaceCoordinates {
|
|
@@ -29,34 +33,20 @@ export function ephemeralWorkspaceCoordinates(rootInput: string): EphemeralWorks
|
|
|
29
33
|
};
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
|
|
36
|
+
/**
|
|
37
|
+
* `controllerHome` is retained for call-site compatibility; an arbitrary
|
|
38
|
+
* workspace owns no controller-scoped repository record.
|
|
39
|
+
*/
|
|
40
|
+
export function resolveEphemeralWorkspaceTarget(rootInput: string, _controllerHome?: string): EphemeralWorkspaceTarget {
|
|
33
41
|
const coordinates = ephemeralWorkspaceCoordinates(rootInput);
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
repoId: coordinates.workspaceId,
|
|
38
|
-
displayName: `Ephemeral Workspace (${coordinates.canonicalRoot.split(/[\\/]/).at(-1) || 'root'})`,
|
|
39
|
-
localRoot: coordinates.canonicalRoot,
|
|
40
|
-
canonicalRoot: coordinates.canonicalRoot,
|
|
41
|
-
activeCheckoutId: coordinates.checkoutId,
|
|
42
|
-
checkouts: [{
|
|
43
|
-
checkoutId: coordinates.checkoutId,
|
|
44
|
-
localRoot: coordinates.canonicalRoot,
|
|
42
|
+
return {
|
|
43
|
+
...coordinates,
|
|
44
|
+
commandTarget: {
|
|
45
45
|
canonicalRoot: coordinates.canonicalRoot,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
lifecycle: 'active',
|
|
52
|
-
}],
|
|
53
|
-
repositoryType: 'unknown',
|
|
54
|
-
enabled: true,
|
|
55
|
-
createdAt: now,
|
|
56
|
-
updatedAt: now,
|
|
57
|
-
lastSeenAt: now,
|
|
58
|
-
configurationPath: join(controllerHome, 'ephemeral-workspaces', `${coordinates.workspaceId}.json`),
|
|
59
|
-
stateStorageStrategy: 'controller-home',
|
|
46
|
+
workspaceScopeKey: coordinates.workspaceId,
|
|
47
|
+
// The workspace's own checkout coordinate, never a repository checkout id.
|
|
48
|
+
activeCheckoutId: coordinates.checkoutId,
|
|
49
|
+
enabled: true,
|
|
50
|
+
},
|
|
60
51
|
};
|
|
61
|
-
return { ...coordinates, repository };
|
|
62
52
|
}
|
|
@@ -3,7 +3,7 @@ import { spawnSync } from 'child_process';
|
|
|
3
3
|
import { appendFileSync, mkdirSync, realpathSync } from 'fs';
|
|
4
4
|
import { dirname, join, relative } from 'path';
|
|
5
5
|
import { capProcessOutput, redactProcessOutput } from '../../effects/process-runner';
|
|
6
|
-
import {
|
|
6
|
+
import { scopedOperationRoot } from './controller-home';
|
|
7
7
|
import { classifyRepositoryCommand, type RepositoryCommandAuthorization, type RepositoryCommandClassification } from './command-classifier';
|
|
8
8
|
import { resolveRepositoryCommandCwd } from './command-scope';
|
|
9
9
|
import type { RepositoryRecord } from './types';
|
|
@@ -209,7 +209,7 @@ function snapshotChanged(before: RepositoryGitSnapshot, after: RepositoryGitSnap
|
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
function auditExecution(controllerHome: string, repository: RepositoryRecord, execution: RepositoryGitExecution): void {
|
|
212
|
-
const path = join(
|
|
212
|
+
const path = join(scopedOperationRoot(controllerHome, repository.repoId), 'audit', 'git-commands.jsonl');
|
|
213
213
|
mkdirSync(dirname(path), { recursive: true });
|
|
214
214
|
appendFileSync(path, `${JSON.stringify({
|
|
215
215
|
timestamp: new Date().toISOString(),
|
|
@@ -39,6 +39,19 @@ export function stableRemoteRepoId(canonicalRemote: string): string {
|
|
|
39
39
|
return `repo_${digest(`remote\0${canonicalRemote}`).slice(0, 24)}`;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/** Portable Project identity: stable across ForgeInstance/repository registrations for the same canonical remote. */
|
|
43
|
+
export function stablePortableProjectId(canonicalRemote: string): string {
|
|
44
|
+
const normalized = normalizeRemoteUrl(canonicalRemote);
|
|
45
|
+
if (!normalized) throw new Error('PROJECT_REMOTE_IDENTITY_REQUIRED');
|
|
46
|
+
return `project_${digest(`project\0${normalized}`).slice(0, 24)}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function portableProjectSourceFingerprint(canonicalRemote: string): string {
|
|
50
|
+
const normalized = normalizeRemoteUrl(canonicalRemote);
|
|
51
|
+
if (!normalized) throw new Error('PROJECT_REMOTE_IDENTITY_REQUIRED');
|
|
52
|
+
return digest(`project-source\0${normalized}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
42
55
|
export function newLocalRepoId(): string {
|
|
43
56
|
return `repo_local_${randomUUID().replace(/-/g, '')}`;
|
|
44
57
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { spawnSync } from 'child_process';
|
|
2
2
|
import {
|
|
3
|
-
appendFileSync,
|
|
4
3
|
existsSync,
|
|
5
4
|
mkdirSync,
|
|
6
5
|
readFileSync,
|
|
7
6
|
realpathSync,
|
|
8
7
|
renameSync,
|
|
9
8
|
rmSync,
|
|
9
|
+
statSync,
|
|
10
10
|
writeFileSync,
|
|
11
11
|
} from 'fs';
|
|
12
12
|
import { dirname, join, relative, resolve } from 'path';
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
ensureControllerHome,
|
|
18
18
|
ensureRepositoryControllerLayout,
|
|
19
19
|
} from './controller-home';
|
|
20
|
+
import { withControllerLock } from './locks';
|
|
20
21
|
import {
|
|
21
22
|
inferDisplayName,
|
|
22
23
|
newLocalRepoId,
|
|
@@ -38,7 +39,7 @@ import type {
|
|
|
38
39
|
|
|
39
40
|
const REGISTRY_FILE = 'repositories.json';
|
|
40
41
|
const FOCUS_FILE = 'focus.json';
|
|
41
|
-
const
|
|
42
|
+
const LEGACY_LOCAL_CONFIG = '.ai/harness/repository.json';
|
|
42
43
|
const LEGACY_GITHUB_PLUGIN_CONFIG = '.forge/plugins/github.json';
|
|
43
44
|
|
|
44
45
|
interface RegisterRepositoryInput {
|
|
@@ -218,6 +219,25 @@ function repositoryByGitCommonDirectory(records: RepositoryRecord[], root: strin
|
|
|
218
219
|
return linkedWorktreeFallback ?? historicalCheckoutFallback;
|
|
219
220
|
}
|
|
220
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Resolve an already-registered repository from one concrete checkout root
|
|
224
|
+
* without mutating Repository Registry state. Exact canonical/active-checkout
|
|
225
|
+
* matches stay filesystem-only; Git common-directory probing is a bounded
|
|
226
|
+
* compatibility fallback for linked worktrees that predate checkout tracking.
|
|
227
|
+
*/
|
|
228
|
+
export function findRegisteredRepositoryByCheckoutRoot(
|
|
229
|
+
root: string,
|
|
230
|
+
controllerHome?: string,
|
|
231
|
+
): RepositoryRecord | undefined {
|
|
232
|
+
const candidateRoot = resolve(root);
|
|
233
|
+
const records = listRepositories(controllerHome).filter((record) => record.enabled !== false && !record.removedAt);
|
|
234
|
+
const exact = records.find((record) => (
|
|
235
|
+
comparablePath(record.canonicalRoot) === comparablePath(candidateRoot)
|
|
236
|
+
|| activeCheckouts(record).some((checkout) => comparablePath(checkout.canonicalRoot) === comparablePath(candidateRoot))
|
|
237
|
+
));
|
|
238
|
+
return exact ?? repositoryByGitCommonDirectory(records, candidateRoot);
|
|
239
|
+
}
|
|
240
|
+
|
|
221
241
|
function managedCheckoutMatchesRepository(record: RepositoryRecord, checkout: RepositoryCheckout): boolean {
|
|
222
242
|
return repositoryCheckoutRootMatches(record, checkout.canonicalRoot);
|
|
223
243
|
}
|
|
@@ -272,6 +292,51 @@ function readRegistryFile(path: string, strict: boolean): RepositoryRegistry | u
|
|
|
272
292
|
}
|
|
273
293
|
}
|
|
274
294
|
|
|
295
|
+
interface RepositoryRegistryReadSnapshot {
|
|
296
|
+
fileIdentity: string;
|
|
297
|
+
registry: RepositoryRegistry;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const repositoryRegistryReadSnapshots = new Map<string, RepositoryRegistryReadSnapshot>();
|
|
301
|
+
|
|
302
|
+
function registryFileIdentity(path: string): string | undefined {
|
|
303
|
+
try {
|
|
304
|
+
const stat = statSync(path, { bigint: true });
|
|
305
|
+
return `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}`;
|
|
306
|
+
} catch {
|
|
307
|
+
return undefined;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function cloneRepositoryRecord(record: RepositoryRecord): RepositoryRecord {
|
|
312
|
+
return {
|
|
313
|
+
...record,
|
|
314
|
+
checkouts: record.checkouts.map((checkout) => ({ ...checkout })),
|
|
315
|
+
github: record.github
|
|
316
|
+
? { ...record.github, labels: record.github.labels ? [...record.github.labels] : undefined }
|
|
317
|
+
: undefined,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function loadRepositoryRegistryReadSnapshot(controllerHome?: string): RepositoryRegistry {
|
|
322
|
+
const path = registryPath(controllerHome);
|
|
323
|
+
const beforeIdentity = registryFileIdentity(path);
|
|
324
|
+
const cached = beforeIdentity ? repositoryRegistryReadSnapshots.get(path) : undefined;
|
|
325
|
+
if (cached && cached.fileIdentity === beforeIdentity) return cached.registry;
|
|
326
|
+
|
|
327
|
+
let registry = readRegistryFile(path, true) ?? defaultRegistry();
|
|
328
|
+
let afterIdentity = registryFileIdentity(path);
|
|
329
|
+
if (beforeIdentity && afterIdentity && beforeIdentity !== afterIdentity) {
|
|
330
|
+
// A cross-process atomic replacement raced this read. Re-read once from the
|
|
331
|
+
// new physical authority instead of caching a mixed-generation snapshot.
|
|
332
|
+
registry = readRegistryFile(path, true) ?? defaultRegistry();
|
|
333
|
+
afterIdentity = registryFileIdentity(path);
|
|
334
|
+
}
|
|
335
|
+
if (afterIdentity) repositoryRegistryReadSnapshots.set(path, { fileIdentity: afterIdentity, registry });
|
|
336
|
+
else repositoryRegistryReadSnapshots.delete(path);
|
|
337
|
+
return registry;
|
|
338
|
+
}
|
|
339
|
+
|
|
275
340
|
function timestampValue(value: string | undefined): number {
|
|
276
341
|
const parsed = value ? Date.parse(value) : Number.NaN;
|
|
277
342
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
@@ -336,9 +401,27 @@ export function loadRepositoryRegistry(controllerHome?: string): RepositoryRegis
|
|
|
336
401
|
|
|
337
402
|
export function saveRepositoryRegistry(registry: RepositoryRegistry, controllerHome?: string): RepositoryRegistry {
|
|
338
403
|
const home = ensureControllerHome(registryHome(controllerHome));
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
404
|
+
return withControllerLock(
|
|
405
|
+
home,
|
|
406
|
+
{ scope: 'global', resource: 'repository-registry' },
|
|
407
|
+
'repository-registry:save',
|
|
408
|
+
() => {
|
|
409
|
+
const path = join(home, REGISTRY_FILE);
|
|
410
|
+
const current = readRegistryFile(path, true);
|
|
411
|
+
if (current && current.updatedAt !== registry.updatedAt) {
|
|
412
|
+
throw new Error(
|
|
413
|
+
`REPOSITORY_REGISTRY_STALE: expected=${registry.updatedAt}; current=${current.updatedAt}; reload canonical Repository Registry and retry`,
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
const previousRevision = timestampValue(registry.updatedAt);
|
|
417
|
+
const updatedAt = new Date(Math.max(Date.now(), previousRevision + 1)).toISOString();
|
|
418
|
+
const next = { ...registry, schemaVersion: 1 as const, updatedAt };
|
|
419
|
+
atomicJson(path, next);
|
|
420
|
+
return next;
|
|
421
|
+
},
|
|
422
|
+
30_000,
|
|
423
|
+
5_000,
|
|
424
|
+
);
|
|
342
425
|
}
|
|
343
426
|
|
|
344
427
|
export function consolidateRepositoryRegistry(controllerHome?: string): RepositoryRegistry {
|
|
@@ -354,7 +437,7 @@ function resolveGitRoot(inputPath: string): string {
|
|
|
354
437
|
}
|
|
355
438
|
|
|
356
439
|
function readLocalIdentity(canonicalRoot: string): { repoId?: string } {
|
|
357
|
-
const path = join(canonicalRoot,
|
|
440
|
+
const path = join(canonicalRoot, LEGACY_LOCAL_CONFIG);
|
|
358
441
|
if (!existsSync(path)) return {};
|
|
359
442
|
try {
|
|
360
443
|
const parsed = JSON.parse(readFileSync(path, 'utf-8')) as { repoId?: unknown };
|
|
@@ -395,28 +478,6 @@ function readLegacyGitHubPluginConfig(canonicalRoot: string): Partial<Repository
|
|
|
395
478
|
}
|
|
396
479
|
}
|
|
397
480
|
|
|
398
|
-
function ensureHarnessRuntimeIgnored(canonicalRoot: string): void {
|
|
399
|
-
const gitExclude = git(canonicalRoot, ['rev-parse', '--git-path', 'info/exclude']);
|
|
400
|
-
if (!gitExclude) return;
|
|
401
|
-
const path = resolve(canonicalRoot, gitExclude);
|
|
402
|
-
const existing = existsSync(path) ? readFileSync(path, 'utf-8') : '';
|
|
403
|
-
if (existing.split(/\r?\n/).some((line) => line.trim() === '.ai/harness/')) return;
|
|
404
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
405
|
-
const prefix = existing.length > 0 && !existing.endsWith('\n') ? '\n' : '';
|
|
406
|
-
appendFileSync(path, `${prefix}# forge runtime metadata (controller-owned, never source)\n.ai/harness/\n`, 'utf-8');
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
function writeLocalIdentity(record: RepositoryRecord): void {
|
|
410
|
-
ensureHarnessRuntimeIgnored(record.canonicalRoot);
|
|
411
|
-
const path = join(record.canonicalRoot, LOCAL_CONFIG);
|
|
412
|
-
atomicJson(path, {
|
|
413
|
-
schemaVersion: 1,
|
|
414
|
-
repoId: record.repoId,
|
|
415
|
-
checkoutId: record.activeCheckoutId,
|
|
416
|
-
stateStorageStrategy: record.stateStorageStrategy,
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
|
|
420
481
|
function repositoryType(root: string, remoteUrl: string | undefined): RepositoryType {
|
|
421
482
|
const bare = git(root, ['rev-parse', '--is-bare-repository']);
|
|
422
483
|
if (bare === 'true') return 'bare';
|
|
@@ -540,17 +601,39 @@ export function repositorySummary(record: RepositoryRecord): RepositorySummary {
|
|
|
540
601
|
}
|
|
541
602
|
|
|
542
603
|
export function listRepositories(controllerHome?: string, options: { includeRemoved?: boolean } = {}): RepositoryRecord[] {
|
|
543
|
-
return
|
|
604
|
+
return loadRepositoryRegistryReadSnapshot(controllerHome).repositories
|
|
544
605
|
.filter((record) => options.includeRemoved === true || !record.removedAt)
|
|
545
|
-
.sort((a, b) => a.displayName.localeCompare(b.displayName) || a.repoId.localeCompare(b.repoId))
|
|
606
|
+
.sort((a, b) => a.displayName.localeCompare(b.displayName) || a.repoId.localeCompare(b.repoId))
|
|
607
|
+
.map(cloneRepositoryRecord);
|
|
546
608
|
}
|
|
547
609
|
|
|
548
610
|
export function getRepository(repoId: string, controllerHome?: string, options: { includeRemoved?: boolean } = {}): RepositoryRecord {
|
|
549
|
-
const record =
|
|
611
|
+
const record = loadRepositoryRegistryReadSnapshot(controllerHome).repositories.find((candidate) => candidate.repoId === repoId);
|
|
550
612
|
if (!record || (record.removedAt && options.includeRemoved !== true)) {
|
|
551
613
|
throw new Error(`repository not found: ${repoId}`);
|
|
552
614
|
}
|
|
553
|
-
return record;
|
|
615
|
+
return cloneRepositoryRecord(record);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
export type RepositoryCheckoutSelectionErrorCode = 'CHECKOUT_NOT_FOUND' | 'CHECKOUT_NOT_ACTIVE';
|
|
619
|
+
|
|
620
|
+
export class RepositoryCheckoutSelectionError extends Error {
|
|
621
|
+
readonly code: RepositoryCheckoutSelectionErrorCode;
|
|
622
|
+
readonly repoId: string;
|
|
623
|
+
readonly checkoutId: string;
|
|
624
|
+
readonly lifecycle?: RepositoryCheckoutLifecycle;
|
|
625
|
+
|
|
626
|
+
constructor(input: { code: RepositoryCheckoutSelectionErrorCode; repoId: string; checkoutId: string; lifecycle?: RepositoryCheckoutLifecycle }) {
|
|
627
|
+
const message = input.code === 'CHECKOUT_NOT_FOUND'
|
|
628
|
+
? `checkout not found for ${input.repoId}: ${input.checkoutId}`
|
|
629
|
+
: `CHECKOUT_NOT_ACTIVE: ${input.repoId}/${input.checkoutId} is ${input.lifecycle ?? 'unknown'}`;
|
|
630
|
+
super(message);
|
|
631
|
+
this.name = 'RepositoryCheckoutSelectionError';
|
|
632
|
+
this.code = input.code;
|
|
633
|
+
this.repoId = input.repoId;
|
|
634
|
+
this.checkoutId = input.checkoutId;
|
|
635
|
+
this.lifecycle = input.lifecycle;
|
|
636
|
+
}
|
|
554
637
|
}
|
|
555
638
|
|
|
556
639
|
export function selectRepositoryCheckout(
|
|
@@ -560,10 +643,10 @@ export function selectRepositoryCheckout(
|
|
|
560
643
|
): RepositoryRecord {
|
|
561
644
|
if (!checkoutId?.trim()) return record;
|
|
562
645
|
const checkout = record.checkouts.find((candidate) => candidate.checkoutId === checkoutId.trim());
|
|
563
|
-
if (!checkout) throw new
|
|
646
|
+
if (!checkout) throw new RepositoryCheckoutSelectionError({ code: 'CHECKOUT_NOT_FOUND', repoId: record.repoId, checkoutId: checkoutId.trim() });
|
|
564
647
|
const lifecycle = repositoryCheckoutLifecycle(checkout);
|
|
565
648
|
if (lifecycle !== 'active' && !(options.allowArchived === true && lifecycle === 'archived')) {
|
|
566
|
-
throw new
|
|
649
|
+
throw new RepositoryCheckoutSelectionError({ code: 'CHECKOUT_NOT_ACTIVE', repoId: record.repoId, checkoutId: checkout.checkoutId, lifecycle });
|
|
567
650
|
}
|
|
568
651
|
return {
|
|
569
652
|
...record,
|
|
@@ -599,13 +682,29 @@ export function registerRepository(input: RegisterRepositoryInput): RepositoryRe
|
|
|
599
682
|
? repositoryByGitCommonDirectory(registry.repositories, canonicalRoot)
|
|
600
683
|
: undefined;
|
|
601
684
|
const existingIdentity = existingByRoot ?? existingByCommonDirectory;
|
|
602
|
-
const
|
|
685
|
+
const explicitRepoId = input.repoIdOverride?.trim();
|
|
686
|
+
const derivedRepoId = explicitRepoId
|
|
603
687
|
|| existingIdentity?.repoId
|
|
604
688
|
|| localIdentity.repoId
|
|
605
689
|
|| (canonicalRemote ? stableRemoteRepoId(canonicalRemote) : newLocalRepoId());
|
|
606
|
-
const
|
|
690
|
+
const existingByDerivedId = registry.repositories.find((record) => record.repoId === derivedRepoId);
|
|
691
|
+
// Repository identity is rooted in one Git checkout family, not merely one
|
|
692
|
+
// remote URL. Two independent clones of the same remote have different Git
|
|
693
|
+
// common directories and must remain separate Repository records. The one
|
|
694
|
+
// intentional exception is an explicit registration replacement; legacy
|
|
695
|
+
// repo-local identity may also restore a record whose old canonical root no
|
|
696
|
+
// longer exists after a filesystem move.
|
|
697
|
+
const explicitReplacement = Boolean(explicitRepoId && existingByDerivedId);
|
|
698
|
+
const legacyMovedRoot = Boolean(
|
|
699
|
+
!explicitRepoId
|
|
700
|
+
&& localIdentity.repoId
|
|
701
|
+
&& existingByDerivedId
|
|
702
|
+
&& !existsSync(existingByDerivedId.canonicalRoot),
|
|
703
|
+
);
|
|
704
|
+
const existing = existingIdentity ?? (explicitReplacement || legacyMovedRoot ? existingByDerivedId : undefined);
|
|
705
|
+
const repoId = existing?.repoId
|
|
706
|
+
?? (existingByDerivedId && !existingIdentity ? newLocalRepoId() : derivedRepoId);
|
|
607
707
|
const checkoutId = stableCheckoutId(repoId, canonicalRoot);
|
|
608
|
-
const existing = existingIdentity ?? registry.repositories.find((record) => record.repoId === repoId);
|
|
609
708
|
const checkout: RepositoryCheckout = {
|
|
610
709
|
checkoutId,
|
|
611
710
|
localRoot: canonicalRoot,
|
|
@@ -623,8 +722,8 @@ export function registerRepository(input: RegisterRepositoryInput): RepositoryRe
|
|
|
623
722
|
// A repository-scoped command may start from a managed checkout (for example
|
|
624
723
|
// immutable release construction). Registering that path must add/update the
|
|
625
724
|
// checkout only; it must never promote the ephemeral worktree to repository
|
|
626
|
-
// canonical authority.
|
|
627
|
-
//
|
|
725
|
+
// canonical authority. Active checkout selection is separate authority held
|
|
726
|
+
// by activeCheckoutId; canonicalRoot remains the repository registration root.
|
|
628
727
|
if (existing && worktree && existing.canonicalRemote && canonicalRemote !== existing.canonicalRemote) {
|
|
629
728
|
throw new Error(`CHECKOUT_REPOSITORY_MISMATCH: ${canonicalRoot}`);
|
|
630
729
|
}
|
|
@@ -645,13 +744,6 @@ export function registerRepository(input: RegisterRepositoryInput): RepositoryRe
|
|
|
645
744
|
registry.repositories[index] = next;
|
|
646
745
|
saveRepositoryRegistry(registry, home);
|
|
647
746
|
ensureRepositoryControllerLayout(home, next.repoId);
|
|
648
|
-
ensureHarnessRuntimeIgnored(canonicalRoot);
|
|
649
|
-
atomicJson(join(canonicalRoot, LOCAL_CONFIG), {
|
|
650
|
-
schemaVersion: 1,
|
|
651
|
-
repoId: next.repoId,
|
|
652
|
-
checkoutId,
|
|
653
|
-
stateStorageStrategy: next.stateStorageStrategy,
|
|
654
|
-
});
|
|
655
747
|
return selectRepositoryCheckout(next, checkoutId);
|
|
656
748
|
}
|
|
657
749
|
|
|
@@ -675,7 +767,7 @@ export function registerRepository(input: RegisterRepositoryInput): RepositoryRe
|
|
|
675
767
|
createdAt: existing?.createdAt ?? timestamp,
|
|
676
768
|
updatedAt: timestamp,
|
|
677
769
|
lastSeenAt: timestamp,
|
|
678
|
-
configurationPath:
|
|
770
|
+
configurationPath: registryPath(home),
|
|
679
771
|
stateStorageStrategy: input.stateStorageStrategy ?? existing?.stateStorageStrategy ?? 'hybrid',
|
|
680
772
|
disabledAt: enabled ? undefined : existing?.disabledAt,
|
|
681
773
|
removedAt: enabled ? undefined : existing?.removedAt,
|
|
@@ -687,7 +779,6 @@ export function registerRepository(input: RegisterRepositoryInput): RepositoryRe
|
|
|
687
779
|
];
|
|
688
780
|
saveRepositoryRegistry(registry, home);
|
|
689
781
|
ensureRepositoryControllerLayout(home, repoId);
|
|
690
|
-
writeLocalIdentity(record);
|
|
691
782
|
return record;
|
|
692
783
|
}
|
|
693
784
|
|
|
@@ -748,6 +839,9 @@ export function addRepositoryCheckout(input: AddRepositoryCheckoutInput): Reposi
|
|
|
748
839
|
if (current.canonicalRemote && canonicalRemote !== current.canonicalRemote) {
|
|
749
840
|
throw new Error(`CHECKOUT_REPOSITORY_MISMATCH: ${canonicalRoot}`);
|
|
750
841
|
}
|
|
842
|
+
if (!repositoryCheckoutRootMatches(current, canonicalRoot)) {
|
|
843
|
+
throw new Error(`CHECKOUT_REPOSITORY_MISMATCH: ${canonicalRoot}`);
|
|
844
|
+
}
|
|
751
845
|
const timestamp = now();
|
|
752
846
|
const checkoutId = stableCheckoutId(current.repoId, canonicalRoot);
|
|
753
847
|
const checkout: RepositoryCheckout = {
|
|
@@ -764,21 +858,14 @@ export function addRepositoryCheckout(input: AddRepositoryCheckoutInput): Reposi
|
|
|
764
858
|
const activate = input.activate === true;
|
|
765
859
|
const next: RepositoryRecord = {
|
|
766
860
|
...current,
|
|
767
|
-
...(activate ? {
|
|
861
|
+
...(activate ? { activeCheckoutId: checkoutId } : {}),
|
|
768
862
|
checkouts: [...current.checkouts.filter((value) => value.checkoutId !== checkoutId), checkout],
|
|
769
863
|
updatedAt: timestamp,
|
|
770
864
|
lastSeenAt: timestamp,
|
|
771
865
|
};
|
|
772
866
|
registry.repositories[index] = next;
|
|
773
867
|
saveRepositoryRegistry(registry, home);
|
|
774
|
-
|
|
775
|
-
atomicJson(join(canonicalRoot, LOCAL_CONFIG), {
|
|
776
|
-
schemaVersion: 1,
|
|
777
|
-
repoId: next.repoId,
|
|
778
|
-
checkoutId,
|
|
779
|
-
stateStorageStrategy: next.stateStorageStrategy,
|
|
780
|
-
});
|
|
781
|
-
return next;
|
|
868
|
+
return activate ? selectRepositoryCheckout(next, checkoutId) : next;
|
|
782
869
|
}
|
|
783
870
|
|
|
784
871
|
export function setRepositoryCheckoutLifecycle(input: SetRepositoryCheckoutLifecycleInput): RepositoryRecord {
|
|
@@ -868,7 +955,6 @@ export function updateRepository(repoId: string, patch: UpdateRepositoryInput, c
|
|
|
868
955
|
};
|
|
869
956
|
registry.repositories[index] = next;
|
|
870
957
|
saveRepositoryRegistry(registry, controllerHome);
|
|
871
|
-
writeLocalIdentity(next);
|
|
872
958
|
return next;
|
|
873
959
|
}
|
|
874
960
|
|
|
@@ -993,13 +1079,12 @@ export function refreshRepository(repoId: string, controllerHome?: string): Repo
|
|
|
993
1079
|
repositoryType: repositoryType(canonicalRoot, rawRemote),
|
|
994
1080
|
updatedAt: timestamp,
|
|
995
1081
|
lastSeenAt: timestamp,
|
|
996
|
-
configurationPath:
|
|
1082
|
+
configurationPath: registryPath(home),
|
|
997
1083
|
};
|
|
998
1084
|
registry.repositories[index] = refreshed;
|
|
999
1085
|
registry.repositories = retireCanonicalDuplicates(registry.repositories, canonicalRoot, repoId, timestamp);
|
|
1000
1086
|
saveRepositoryRegistry(registry, home);
|
|
1001
1087
|
ensureRepositoryControllerLayout(home, repoId);
|
|
1002
|
-
writeLocalIdentity(refreshed);
|
|
1003
1088
|
return refreshed;
|
|
1004
1089
|
}
|
|
1005
1090
|
|