@moretea-labs/forge 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -0
- package/CHANGELOG.md +26 -0
- package/CLAUDE.md +2 -0
- package/README.md +2 -2
- package/README.zh-CN.md +1 -1
- package/SKILL.md +2 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/agents/openai.yaml +1 -1
- package/assets/hooks/hook-input.sh +11 -8
- package/assets/hooks/lib/session-state.sh +10 -7
- package/assets/hooks/lib/workflow-state.sh +13 -177
- package/assets/hooks/post-tool-observer.sh +8 -2
- package/assets/hooks/prompt-guard.sh +5 -81
- package/assets/hooks/session-start-context.sh +56 -1
- package/assets/partials/05-workflow.partial.md +1 -1
- package/assets/partials-agents/03-orchestration.partial.md +1 -1
- package/assets/plugin-registry.v1.json +1 -1
- package/assets/reference-configs/document-generation.md +1 -1
- package/assets/reference-configs/harness-overview.md +1 -1
- package/assets/reference-configs/sprint-contracts.md +3 -3
- package/assets/skill-version.json +2 -2
- package/assets/templates/contract.template.md +2 -7
- package/assets/templates/helpers/capture-plan.sh +2 -2
- package/assets/templates/helpers/check-task-workflow.sh +4 -4
- package/assets/templates/helpers/contract-worktree.sh +1 -21
- package/assets/templates/helpers/ensure-task-workflow.sh +11 -36
- package/assets/templates/helpers/migrate-project-template.sh +22 -45
- package/assets/templates/helpers/new-plan.sh +1 -1
- package/assets/templates/helpers/plan-to-todo.sh +12 -37
- package/assets/templates/helpers/ship-worktrees.sh +2 -29
- package/assets/templates/helpers/verify-contract.sh +1 -111
- package/assets/templates/helpers/verify-sprint.sh +3 -180
- package/assets/templates/plan.template.md +1 -1
- package/assets/templates/review.template.md +9 -34
- package/assets/workflow-contract.v1.json +10 -19
- package/docs/README.md +10 -10
- package/docs/architecture/CURRENT.md +170 -0
- package/docs/architecture/EVOLUTION.md +42 -0
- package/docs/architecture/current/README.md +4 -156
- package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +2 -2
- package/docs/architecture/decisions/20260823-immediate-controller-relay.md +53 -0
- package/docs/architecture/decisions/20260826-browser-runtime-v2.md +73 -0
- package/docs/architecture/history/README.md +7 -0
- package/docs/architecture/{chatgpt-handoff-facade.md → history/chatgpt-handoff-facade.md} +4 -0
- package/docs/architecture/{global-hook-runtime.md → history/global-hook-runtime.md} +7 -3
- package/docs/architecture/{ios-semantic-automation-provider-v2.md → history/ios-semantic-automation-provider-v2.md} +6 -2
- package/docs/architecture/history.md +3 -34
- package/docs/architecture/index.md +15 -98
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
- package/docs/architecture/reviews/2026-08-22-semantic-harness-convergence-acceptance.md +39 -0
- package/docs/architecture/versions/1.6.md +38 -0
- package/docs/architecture/versions/1.7.md +41 -0
- package/docs/forge-chatgpt-browser-engine.md +2 -2
- package/docs/forge-chatgpt-mcp-setup.md +4 -28
- package/docs/forge-chatgpt-supervised-automation.md +3 -3
- package/docs/forge-github-issue-launcher.md +1 -1
- package/docs/forge-runtime-self-healing-loop.md +1 -1
- package/docs/operations/controller-browser-plugin.md +26 -6
- package/docs/operations/controller-performance-and-502.md +124 -0
- package/docs/operations/controller-reliability-runbook.md +1 -1
- package/docs/operations/features.md +2 -2
- package/docs/operations/github-repository.md +1 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +5 -3
- package/docs/wiki/Architecture.md +6 -6
- package/docs/wiki/Implementation.md +2 -2
- package/docs/wiki/Integrations.md +2 -2
- package/docs/wiki/Work-Lifecycle.md +1 -1
- package/package.json +29 -10
- package/scripts/activate-source-baseline.ts +17 -13
- package/scripts/benchmark-background-check-overlap.ts +228 -0
- package/scripts/benchmark-mcp-host.sh +117 -0
- package/scripts/benchmark-mcp-transport.ts +170 -0
- package/scripts/benchmark-quality-harness.ts +146 -0
- package/scripts/benchmark-route-session-concurrency.ts +207 -6
- package/scripts/benchmark-thin-harness-mcp-e2e.ts +7 -1
- package/scripts/benchmark-typescript-navigation.ts +186 -0
- package/scripts/benchmark-work-efficiency.ts +334 -0
- package/scripts/capture-plan.sh +3 -3
- package/scripts/check-agent-tooling.sh +8 -35
- package/scripts/check-architecture-sync.sh +17 -86
- package/scripts/check-mcp-compatibility.ts +14 -0
- package/scripts/check-runtime-architecture.mjs +107 -64
- package/scripts/check-stable-baseline.ts +92 -0
- package/scripts/check-task-workflow.sh +4 -4
- package/scripts/contract-worktree.sh +1 -21
- package/scripts/ensure-task-workflow.sh +22 -55
- package/scripts/host-temporary-cloud-mcp-e2e.sh +265 -0
- package/scripts/install-standalone-recovery.ts +24 -0
- package/scripts/lib/project-init-lib.sh +15 -44
- package/scripts/migrate-project-template.sh +23 -1179
- package/scripts/new-plan.sh +1 -1
- package/scripts/plan-to-todo.sh +11 -36
- package/scripts/run-governed-gate.ts +2 -1
- package/scripts/ship-worktrees.sh +2 -29
- package/scripts/smoke-ios-physical-device.ts +4 -2
- package/scripts/smoke-runtime-recovery.ts +1 -35
- package/scripts/smoke-schedule-engine.ts +1 -20
- package/scripts/verify-contract.sh +1 -111
- package/scripts/verify-forge-runtime.sh +0 -1
- package/scripts/verify-sprint.sh +3 -180
- package/scripts/workflow-contract.ts +1 -5
- package/src/cli/commands/init-hook.ts +3 -3
- package/src/cli/commands/mcp.ts +9 -5
- package/src/cli/commands/plugin.ts +1 -1
- package/src/cli/commands/recovery.ts +25 -3
- package/src/cli/commands/runtime.ts +55 -3
- package/src/cli/commands/security.ts +12 -1
- package/src/cli/commands/setup-profile.ts +31 -21
- package/src/cli/controller/check-runner.ts +106 -3
- package/src/cli/controller/composite-result.ts +1 -1
- package/src/cli/controller/context/focus.ts +51 -0
- package/src/cli/controller/context/instruction-context.ts +114 -0
- package/src/cli/controller/context/known-paths.ts +76 -0
- package/src/cli/controller/context/query-planning.ts +110 -0
- package/src/cli/controller/context/rule-resolution.ts +532 -0
- package/src/cli/controller/context/source-materializer.ts +278 -0
- package/src/cli/controller/context/structural.ts +16 -0
- package/src/cli/controller/context/types.ts +286 -0
- package/src/cli/controller/context-pack.ts +785 -469
- package/src/cli/controller/launch-agents.ts +77 -2
- package/src/cli/controller/operational-plan.ts +2 -2
- package/src/cli/controller/work-mode.ts +6 -4
- package/src/cli/editing/edit-session.ts +60 -7
- package/src/cli/github/github.ts +133 -0
- package/src/cli/installer/managed-entries.ts +15 -1
- package/src/cli/local-bridge/console-automations.ts +54 -78
- package/src/cli/local-bridge/console-view-models.ts +1 -35
- package/src/cli/local-bridge/facade-api.ts +0 -217
- package/src/cli/local-bridge/frontend/src/App.tsx +3 -3
- package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +23 -13
- package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +37 -4
- package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +6 -4
- package/src/cli/local-bridge/frontend/src/lib/api.ts +1 -6
- package/src/cli/local-bridge/frontend/src/lib/routes.ts +1 -1
- package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +2 -2
- package/src/cli/local-bridge/frontend/src/styles.css +1 -1
- package/src/cli/local-bridge/frontend/src/types.ts +5 -8
- package/src/cli/local-bridge/job-store.ts +1 -490
- package/src/cli/local-bridge/server.ts +0 -513
- package/src/cli/local-bridge/ui-dist/app.css +1 -1
- package/src/cli/local-bridge/ui-dist/app.js +3703 -3757
- package/src/cli/mcp/auth.ts +5 -5
- package/src/cli/mcp/instructions.ts +3 -2
- package/src/cli/mcp/legacy-tool-service.ts +0 -189
- package/src/cli/mcp/multi-repository.ts +16 -5
- package/src/cli/mcp/oauth.ts +175 -26
- package/src/cli/mcp/repository-tools.ts +247 -107
- package/src/cli/mcp/server.ts +537 -111
- package/src/cli/mcp/tool-capability-cache.ts +1 -1
- package/src/cli/mcp/toolset-selection.ts +1 -1
- package/src/cli/mcp/toolset.ts +42 -5
- package/src/cli/mcp/transports/http.ts +101 -14
- package/src/cli/mcp/transports/session-registry.ts +43 -5
- package/src/cli/mcp/types.ts +3 -3
- package/src/cli/repositories/command-classifier.ts +101 -19
- package/src/cli/repositories/command-executor.ts +55 -521
- package/src/cli/repositories/command-process.ts +108 -0
- package/src/cli/repositories/command-scope.ts +99 -41
- package/src/cli/repositories/controller-home.ts +7 -8
- package/src/cli/repositories/git-command-executor.ts +2 -0
- package/src/cli/repositories/locks.ts +53 -16
- package/src/cli/repositories/repository-snapshot.ts +121 -0
- package/src/cli/repositories/selected-path-actions.ts +17 -9
- package/src/cli/repositories/structured-git.ts +61 -3
- package/src/cli/repository/inspector.ts +553 -63
- package/src/cli/repository/session-cache.ts +58 -17
- package/src/cli/v81-entry.ts +1 -4
- package/src/effects/fs-transaction.ts +85 -17
- package/src/runtime/context/codegraph-read-provider.ts +233 -2
- package/src/runtime/context/codegraph-sidecar.cjs +74 -40
- package/src/runtime/context/generic-lsp-provider.ts +355 -0
- package/src/runtime/context/lsp-client.ts +283 -0
- package/src/runtime/context/semantic-navigation.ts +275 -0
- package/src/runtime/context/swift-navigation.ts +565 -0
- package/src/runtime/context/typescript-navigation.ts +226 -0
- package/src/runtime/control-plane/dispatch-priority.ts +28 -0
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +47 -8
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +86 -24
- package/src/runtime/control-plane/execution/session-store.ts +18 -0
- package/src/runtime/control-plane/execution/verification-evidence.ts +58 -3
- package/src/runtime/control-plane/execution/work-handle-store.ts +27 -2
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +258 -0
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +215 -0
- package/src/runtime/control-plane/execution/work-task-receipt.ts +54 -11
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +143 -8
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +22 -14
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +85 -8
- package/src/runtime/control-plane/facade/capability-registry.ts +129 -25
- package/src/runtime/control-plane/facade/controller-round-relay.ts +991 -0
- package/src/runtime/control-plane/facade/controller-session-store.ts +132 -1
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +2 -0
- package/src/runtime/control-plane/facade/goal-workloop.ts +686 -129
- package/src/runtime/control-plane/facade/index.ts +1 -0
- package/src/runtime/control-plane/facade/plan-contract-store.ts +185 -20
- package/src/runtime/control-plane/facade/semantic-admission.ts +205 -0
- package/src/runtime/control-plane/facade/suggested-actions.ts +5 -1
- package/src/runtime/control-plane/facade/types.ts +22 -5
- package/src/runtime/control-plane/facade/work-contract-store.ts +175 -73
- package/src/runtime/control-plane/generated-cache-retention.ts +271 -0
- package/src/runtime/control-plane/global-scheduler/config.ts +44 -0
- package/src/runtime/control-plane/global-scheduler/dispatch-capacity.ts +80 -0
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +46 -0
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +145 -0
- package/src/runtime/control-plane/global-scheduler/projection-refresh.ts +84 -0
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -3
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +273 -542
- package/src/runtime/control-plane/global-scheduler/source-scan.ts +59 -0
- package/src/runtime/control-plane/global-scheduler/state.ts +88 -0
- package/src/runtime/control-plane/global-scheduler/worker-attachment.ts +57 -0
- package/src/runtime/control-plane/global-scheduler/worker-exit-decision.ts +38 -0
- package/src/runtime/control-plane/global-scheduler/worker-exit-reconciler.ts +175 -0
- package/src/runtime/control-plane/global-scheduler/worker-launch.ts +111 -0
- package/src/runtime/control-plane/global-scheduler/worker-lifecycle-store.ts +64 -0
- package/src/runtime/control-plane/global-scheduler/worker-lifecycle.ts +150 -0
- package/src/runtime/control-plane/global-scheduler/worker-process.ts +119 -0
- package/src/runtime/control-plane/global-scheduler/worker-stderr.ts +60 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +50 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +355 -116
- package/src/runtime/control-plane/launcher/launch-reservation-store.ts +40 -0
- package/src/runtime/control-plane/launcher/thin-launcher.ts +194 -10
- package/src/runtime/control-plane/persistence/controller-home-migration.ts +487 -0
- package/src/runtime/control-plane/persistence/sqlite-store.ts +33 -2
- package/src/runtime/control-plane/release-retention.ts +62 -2
- package/src/runtime/control-plane/routing/route-policy.ts +7 -16
- package/src/runtime/control-plane/runtime-status-client.ts +0 -2
- package/src/runtime/diagnostics/mcp-timing.ts +13 -0
- package/src/runtime/diagnostics/mcp-transport-benchmark.ts +129 -0
- package/src/runtime/diagnostics/performance.ts +24 -1
- package/src/runtime/evidence/event-ledger.ts +1 -1
- package/src/runtime/execution/jobs/store.ts +58 -4
- package/src/runtime/execution/jobs/types.ts +1 -1
- package/src/runtime/execution/managed-workspace.ts +203 -1
- package/src/runtime/execution/process-runtime/check-facade.ts +51 -4
- package/src/runtime/execution/process-runtime/check-result.ts +53 -0
- package/src/runtime/execution/process-runtime/check-scheduling.ts +114 -0
- package/src/runtime/execution/process-runtime/command-facade.ts +345 -40
- package/src/runtime/execution/process-runtime/gc.ts +38 -6
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +1184 -0
- package/src/runtime/execution/process-runtime/persisted-check.ts +47 -4
- package/src/runtime/execution/process-runtime/resource-claims.ts +10 -6
- package/src/runtime/execution/process-runtime/runtime.ts +43 -3
- package/src/runtime/execution/process-runtime/store.ts +1 -0
- package/src/runtime/execution/process-runtime/types.ts +2 -0
- package/src/runtime/execution/thin-harness/async-process.ts +12 -2
- package/src/runtime/execution/thin-harness/search-worker.ts +54 -5
- package/src/runtime/execution/workers/executor.ts +0 -48
- package/src/runtime/gateway/mcp/execution-tools.ts +1192 -114
- package/src/runtime/gateway/mcp/process-tools.ts +83 -37
- package/src/runtime/gateway/mcp/router.ts +184 -82
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +546 -0
- package/src/runtime/gateway/mcp/runtime-tools.ts +2224 -1589
- package/src/runtime/plugins/app-store-connect-adapter.ts +123 -19
- package/src/runtime/plugins/browser-adapter.ts +2901 -241
- package/src/runtime/plugins/browser-automation-service.ts +10 -0
- package/src/runtime/plugins/browser-handoff.ts +92 -2
- package/src/runtime/plugins/browser-macos-bridge.ts +582 -49
- package/src/runtime/plugins/browser-node-bridge.ts +6 -34
- package/src/runtime/plugins/browser-provider-registry.ts +109 -0
- package/src/runtime/plugins/browser-runtime-contract.ts +152 -0
- package/src/runtime/plugins/browser-runtime.ts +183 -0
- package/src/runtime/plugins/browser-session-authority.ts +332 -0
- package/src/runtime/plugins/capability-authorization-grants.ts +354 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +8 -2
- package/src/runtime/plugins/external-adapter.ts +324 -3
- package/src/runtime/plugins/external-unix-socket.ts +7 -1
- package/src/runtime/plugins/first-party-registry.ts +2 -0
- package/src/runtime/plugins/github-adapter.ts +125 -0
- package/src/runtime/plugins/ios/agent-device-provider.ts +1 -1
- package/src/runtime/plugins/ios/agent-device-typed-provider.ts +52 -9
- package/src/runtime/plugins/ios/remote-xpc-hid.ts +1171 -0
- package/src/runtime/plugins/ios-adapter.ts +106 -16
- package/src/runtime/plugins/ios-agent-device.ts +234 -64
- package/src/runtime/plugins/ios-physical-device.ts +1143 -392
- package/src/runtime/plugins/lightweight-action.ts +153 -0
- package/src/runtime/plugins/local-system-adapter.ts +123 -6
- package/src/runtime/plugins/macos-capability-broker.ts +55 -9
- package/src/runtime/plugins/plugin-action-sidecar.ts +59 -0
- package/src/runtime/plugins/plugin-management-adapter.ts +49 -8
- package/src/runtime/plugins/resend-adapter.ts +1 -1
- package/src/runtime/plugins/store.ts +269 -29
- package/src/runtime/plugins/types.ts +35 -2
- package/src/runtime/plugins/xiaohongshu-publish.ts +515 -0
- package/src/runtime/projections/git-status-sampler.ts +16 -16
- package/src/runtime/projections/materialized-view.ts +28 -10
- package/src/runtime/recovery/maintenance-executor.ts +393 -28
- package/src/runtime/root/mcp-transport.ts +180 -10
- package/src/runtime/root/package-connector-service.ts +186 -8
- package/src/runtime/root/package-runtime-release.ts +143 -17
- package/src/runtime/root/package-runtime-service.ts +430 -22
- package/src/runtime/root/release-manifest.ts +7 -2
- package/src/runtime/root/release-materialize.ts +19 -0
- package/src/runtime/root/release-store.ts +48 -11
- package/src/runtime/root/runtime.ts +23 -5
- package/src/runtime/root/service.ts +100 -29
- package/src/runtime/root/types.ts +2 -0
- package/src/runtime/safe-tooling/ios-development.ts +321 -63
- package/src/runtime/shared/trusted-executable.ts +62 -0
- package/src/runtime/shared/trusted-node-executable.ts +48 -0
- package/src/runtime/standalone-recovery/core.ts +700 -92
- package/src/runtime/standalone-recovery/entry.ts +99 -23
- package/src/runtime/standalone-recovery/installer.ts +19 -3
- package/src/runtime/standalone-recovery/service-labels.ts +2 -0
- package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +160 -0
- package/src/runtime/workflow/schedules/browser-probe.ts +81 -3
- package/src/runtime/workflow/schedules/engine.ts +287 -151
- package/src/runtime/workflow/schedules/github-issue-watch.ts +158 -0
- package/src/runtime/workflow/schedules/settlement.ts +48 -4
- package/src/runtime/workflow/schedules/store.ts +131 -10
- package/src/runtime/workflow/schedules/types.ts +2 -4
- package/src/runtime/workflow/schedules/work-continuation.ts +26 -13
- package/src/testing/test-governance.ts +8 -40
- package/assets/reference-configs/heartbeat-triage.md +0 -57
- package/assets/templates/helpers/harness-trace-grade.sh +0 -150
- package/assets/templates/helpers/heartbeat-triage.sh +0 -361
- package/assets/templates/helpers/maintenance-triage.sh +0 -167
- package/docs/architecture/current/approved-target-architecture.zh-CN.md +0 -1501
- package/docs/architecture/current/architecture-invariants.md +0 -331
- package/docs/architecture/current/automation-and-schedule-engine.md +0 -459
- package/docs/architecture/current/codegraph-context-provider.md +0 -238
- package/docs/architecture/current/control-plane-authority-inventory.md +0 -94
- package/docs/architecture/current/controller-repository-decoupling.md +0 -148
- package/docs/architecture/current/dispatch-and-agent-strategy.md +0 -373
- package/docs/architecture/current/entity-model.md +0 -612
- package/docs/architecture/current/external-plugin-governance.md +0 -396
- package/docs/architecture/current/failure-recovery.md +0 -447
- package/docs/architecture/current/governance.md +0 -213
- package/docs/architecture/current/human-interaction-plane.md +0 -87
- package/docs/architecture/current/implementation-status.md +0 -128
- package/docs/architecture/current/job-and-run-lifecycle.md +0 -413
- package/docs/architecture/current/legacy-governance.md +0 -58
- package/docs/architecture/current/local-workspace-target-grants.md +0 -70
- package/docs/architecture/current/migration-roadmap.md +0 -105
- package/docs/architecture/current/multi-repository-execution.md +0 -371
- package/docs/architecture/current/operations-runbook.md +0 -45
- package/docs/architecture/current/peer-supercontroller-runtime.md +0 -32
- package/docs/architecture/current/personal-assistant-plugin-baseline.md +0 -206
- package/docs/architecture/current/repository-access-modes.md +0 -102
- package/docs/architecture/current/route-policy.md +0 -15
- package/docs/architecture/current/route-session-concurrency.md +0 -85
- package/docs/architecture/current/runtime-architecture-simplification.md +0 -214
- package/docs/architecture/current/runtime-directory-map.md +0 -49
- package/docs/architecture/current/runtime-health-and-resource-lifecycle.md +0 -85
- package/docs/architecture/current/scheduler-and-resource-claims.md +0 -422
- package/docs/architecture/current/session-aware-execution-and-authorization.md +0 -77
- package/docs/architecture/current/system-overview.md +0 -169
- package/docs/architecture/current/target-requirements-traceability.md +0 -202
- package/docs/architecture/current/thin-harness-governance-policy.md +0 -32
- package/docs/architecture/current/thin-harness-v1.md +0 -321
- package/docs/architecture/current/verification-and-release-gates.md +0 -391
- package/docs/forge-autonomous-goal-loop.md +0 -9
- package/docs/forge-provider-configuration.md +0 -7
- package/docs/operations/chatgpt-personal-assistant-runtime.md +0 -93
- package/docs/operations/gmail-assistant-routines.md +0 -186
- package/docs/operations/personal-assistant-operator-guide.md +0 -61
- package/docs/operations/provider-configuration.md +0 -31
- package/scripts/harness-trace-grade.sh +0 -150
- package/scripts/heartbeat-triage.sh +0 -361
- package/scripts/maintenance-triage.sh +0 -167
- package/src/cli/local-bridge/frontend/src/features/settings/SettingsView.tsx +0 -2
- package/src/cli/repositories/goal-registry.ts +0 -239
- package/src/runtime/assistant/action-proposals.ts +0 -279
- package/src/runtime/assistant/intent.ts +0 -395
- package/src/runtime/assistant/model-provider.ts +0 -460
- package/src/runtime/assistant/openapi.ts +0 -223
- package/src/runtime/assistant/policy.ts +0 -89
- package/src/runtime/assistant/readiness.ts +0 -258
- package/src/runtime/assistant/routine-runtime.ts +0 -477
- package/src/runtime/assistant/schedule-binding.ts +0 -171
- package/src/runtime/assistant/standing-grants.ts +0 -375
- package/src/runtime/assistant/store.ts +0 -243
- package/src/runtime/assistant/types.ts +0 -135
- package/src/runtime/control-plane/goal-loop/config-facade.ts +0 -700
- package/src/runtime/control-plane/goal-loop/config-store.ts +0 -570
- package/src/runtime/control-plane/goal-loop/config-types.ts +0 -213
- package/src/runtime/control-plane/goal-loop/executor-router.ts +0 -109
- package/src/runtime/control-plane/goal-loop/failure-taxonomy.ts +0 -149
- package/src/runtime/control-plane/goal-loop/goal-contract-store.ts +0 -304
- package/src/runtime/control-plane/goal-loop/goal-loop-engine.ts +0 -1001
- package/src/runtime/control-plane/goal-loop/handoff-packet.ts +0 -160
- package/src/runtime/control-plane/goal-loop/index.ts +0 -13
- package/src/runtime/control-plane/goal-loop/local-tools.ts +0 -290
- package/src/runtime/control-plane/goal-loop/policy-gates.ts +0 -203
- package/src/runtime/control-plane/goal-loop/provider-dispatch.ts +0 -93
- package/src/runtime/control-plane/goal-loop/provider-registry.ts +0 -545
- package/src/runtime/control-plane/goal-loop/types.ts +0 -378
- package/src/runtime/control-plane/startup-recovery.ts +0 -198
- package/src/runtime/gateway/mcp/resource-policy.ts +0 -186
- package/src/runtime/personal-assistant/gmail-triage-manager.ts +0 -231
- package/src/runtime/personal-assistant/reporting-runtime.ts +0 -344
- package/src/runtime/personal-assistant/triage-runtime.ts +0 -748
- package/src/runtime/workflow/findings/store.ts +0 -204
- package/src/runtime/workflow/findings/types.ts +0 -58
- package/src/runtime/workflow/portfolio/engine.ts +0 -20
- package/src/runtime/workflow/portfolio/store.ts +0 -185
- package/src/runtime/workflow/portfolio/types.ts +0 -29
package/scripts/verify-sprint.sh
CHANGED
|
@@ -20,54 +20,6 @@ json_escape() {
|
|
|
20
20
|
printf '%s' "$value"
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
review_card_field() {
|
|
24
|
-
local file="$1"
|
|
25
|
-
local label="$2"
|
|
26
|
-
[[ -n "$file" && -f "$file" ]] || return 1
|
|
27
|
-
awk -v wanted="$label" '
|
|
28
|
-
function trim(s) {
|
|
29
|
-
gsub(/^[[:space:]]+/, "", s)
|
|
30
|
-
gsub(/[[:space:]]+$/, "", s)
|
|
31
|
-
return s
|
|
32
|
-
}
|
|
33
|
-
BEGIN { wanted = tolower(wanted) }
|
|
34
|
-
/^##[[:space:]]+Human Review Card[[:space:]]*$/ { in_section = 1; next }
|
|
35
|
-
in_section && /^##[[:space:]]+/ { exit }
|
|
36
|
-
!in_section { next }
|
|
37
|
-
/^[[:space:]]*-[[:space:]]*/ {
|
|
38
|
-
line = $0
|
|
39
|
-
sub(/^[[:space:]]*-[[:space:]]*/, "", line)
|
|
40
|
-
key = line
|
|
41
|
-
sub(/:.*/, "", key)
|
|
42
|
-
key = tolower(trim(key))
|
|
43
|
-
if (key == wanted) {
|
|
44
|
-
sub(/^[^:]*:[[:space:]]*/, "", line)
|
|
45
|
-
print trim(line)
|
|
46
|
-
exit
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
' "$file"
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
normalize_status_token() {
|
|
53
|
-
local value="$1"
|
|
54
|
-
value="$(printf '%s' "$value" | sed -E 's/[;,].*$//; s/[[:space:]].*$//; s/^[[:space:]]+//; s/[[:space:]]+$//' | tr '[:upper:]' '[:lower:]')"
|
|
55
|
-
printf '%s' "$value"
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
field_has_concrete_value() {
|
|
59
|
-
local value="$1"
|
|
60
|
-
local token
|
|
61
|
-
token="$(normalize_status_token "$value")"
|
|
62
|
-
[[ -n "$token" ]] || return 1
|
|
63
|
-
case "$token" in
|
|
64
|
-
tbd|todo|n/a|na|none|unknown|unavailable|pending|...)
|
|
65
|
-
return 1
|
|
66
|
-
;;
|
|
67
|
-
esac
|
|
68
|
-
return 0
|
|
69
|
-
}
|
|
70
|
-
|
|
71
23
|
read_contract_task_profile() {
|
|
72
24
|
local file="$1"
|
|
73
25
|
awk '/^> \*\*Task Profile\*\*:/ {sub(/^.*> \*\*Task Profile\*\*:[[:space:]]*/, ""); gsub(/\r/, ""); print; exit}' "$file" | xargs
|
|
@@ -304,25 +256,14 @@ if [[ -f ".ai/hooks/lib/workflow-state.sh" ]]; then
|
|
|
304
256
|
# shellcheck source=/dev/null
|
|
305
257
|
. ".ai/hooks/lib/workflow-state.sh"
|
|
306
258
|
contract_file="$(workflow_active_contract || true)"
|
|
307
|
-
review_file="$(workflow_active_review || true)"
|
|
308
259
|
checks_file="$(workflow_checks_file)"
|
|
309
260
|
else
|
|
310
261
|
contract_file="$(find tasks/contracts -maxdepth 1 -name '*.contract.md' -type f 2>/dev/null | sort | head -n 1)"
|
|
311
|
-
if [[ -n "$contract_file" ]]; then
|
|
312
|
-
contract_slug="$(basename "$contract_file" | sed -E 's/\.contract\.md$//')"
|
|
313
|
-
review_file="tasks/reviews/${contract_slug}.review.md"
|
|
314
|
-
else
|
|
315
|
-
review_file=""
|
|
316
|
-
fi
|
|
317
262
|
checks_file=".ai/harness/checks/latest.json"
|
|
318
263
|
fi
|
|
319
264
|
if [[ -z "$contract_file" || ! -f "$contract_file" ]]; then
|
|
320
265
|
contract_file="$(active_plan_declared_path "Task Contract" || active_plan_declared_path "Sprint Contract" || true)"
|
|
321
266
|
fi
|
|
322
|
-
if [[ -z "$review_file" || ! -f "$review_file" ]]; then
|
|
323
|
-
review_file="$(active_plan_declared_path "Task Review" || active_plan_declared_path "Sprint Review" || true)"
|
|
324
|
-
fi
|
|
325
|
-
|
|
326
267
|
[[ -n "$contract_file" && -f "$contract_file" ]] || { echo "No active sprint contract found" >&2; exit 1; }
|
|
327
268
|
|
|
328
269
|
generated_at="$(date '+%Y-%m-%dT%H:%M:%S%z')"
|
|
@@ -378,74 +319,9 @@ if [[ -n "$contract_output" ]]; then
|
|
|
378
319
|
printf '%s\n' "$contract_output"
|
|
379
320
|
fi
|
|
380
321
|
|
|
381
|
-
review_status="fail"
|
|
382
|
-
review_message="Task review recommends pass and Human Review Card verdict is pass."
|
|
383
|
-
review_card_verdict=""
|
|
384
|
-
review_card_external=""
|
|
385
|
-
review_card_change_type=""
|
|
386
|
-
review_card_rollback=""
|
|
387
|
-
if [[ -z "$review_file" || ! -f "$review_file" ]]; then
|
|
388
|
-
review_message="Missing task review file."
|
|
389
|
-
echo "Missing task review file" >&2
|
|
390
|
-
else
|
|
391
|
-
review_card_verdict="$(normalize_status_token "$(review_card_field "$review_file" "Verdict" || true)")"
|
|
392
|
-
review_card_external="$(review_card_field "$review_file" "External acceptance" || true)"
|
|
393
|
-
review_card_change_type="$(normalize_status_token "$(review_card_field "$review_file" "Change type" || true)")"
|
|
394
|
-
review_card_rollback="$(review_card_field "$review_file" "Rollback" || true)"
|
|
395
|
-
fi
|
|
396
|
-
|
|
397
|
-
if [[ -n "$review_file" && -f "$review_file" ]]; then
|
|
398
|
-
if ! grep -Eq '^> \*\*Recommendation\*\*:[[:space:]]*pass([[:space:]]*)$' "$review_file"; then
|
|
399
|
-
review_message="Task review does not recommend pass."
|
|
400
|
-
echo "Task review does not recommend pass" >&2
|
|
401
|
-
elif [[ -z "$review_card_verdict" ]]; then
|
|
402
|
-
review_message="Task review is missing Human Review Card verdict."
|
|
403
|
-
echo "Task review is missing Human Review Card verdict" >&2
|
|
404
|
-
elif [[ "$review_card_verdict" != "pass" ]]; then
|
|
405
|
-
review_message="Human Review Card verdict is not pass: $review_card_verdict"
|
|
406
|
-
echo "Human Review Card verdict is not pass: $review_card_verdict" >&2
|
|
407
|
-
elif [[ -n "$task_profile" && "$review_card_change_type" != "$task_profile" ]]; then
|
|
408
|
-
review_message="Human Review Card change type does not match task_profile: ${review_card_change_type:-missing} != $task_profile"
|
|
409
|
-
echo "$review_message" >&2
|
|
410
|
-
elif ! field_has_concrete_value "$review_card_rollback"; then
|
|
411
|
-
review_message="Human Review Card rollback is missing or not concrete."
|
|
412
|
-
echo "$review_message" >&2
|
|
413
|
-
else
|
|
414
|
-
review_status="pass"
|
|
415
|
-
fi
|
|
416
|
-
fi
|
|
417
|
-
|
|
418
|
-
external_status="missing"
|
|
419
|
-
external_reviewer=""
|
|
420
|
-
external_source=""
|
|
421
|
-
external_message="External acceptance status is unavailable."
|
|
422
|
-
if declare -F workflow_external_acceptance_status >/dev/null 2>&1; then
|
|
423
|
-
external_row="$(workflow_external_acceptance_status "$review_file")"
|
|
424
|
-
IFS=$'\t' read -r external_status external_reviewer external_source external_message <<< "$external_row"
|
|
425
|
-
fi
|
|
426
|
-
card_external_status="$(normalize_status_token "$review_card_external")"
|
|
427
|
-
case "$external_status" in
|
|
428
|
-
missing|unavailable|"")
|
|
429
|
-
case "$card_external_status" in
|
|
430
|
-
pass|manual_override|not_required)
|
|
431
|
-
external_status="$card_external_status"
|
|
432
|
-
external_message="Human Review Card external acceptance: $review_card_external"
|
|
433
|
-
;;
|
|
434
|
-
esac
|
|
435
|
-
;;
|
|
436
|
-
esac
|
|
437
|
-
|
|
438
322
|
status="fail"
|
|
439
323
|
exit_code=1
|
|
440
|
-
|
|
441
|
-
pass|manual_override|not_required)
|
|
442
|
-
external_gate="pass"
|
|
443
|
-
;;
|
|
444
|
-
*)
|
|
445
|
-
external_gate="fail"
|
|
446
|
-
;;
|
|
447
|
-
esac
|
|
448
|
-
if [[ "$contract_exit" -eq 0 && "$review_status" == "pass" && "$external_gate" == "pass" && "$allowed_paths_status" == "pass" ]]; then
|
|
324
|
+
if [[ "$contract_exit" -eq 0 && "$allowed_paths_status" == "pass" ]]; then
|
|
449
325
|
status="pass"
|
|
450
326
|
exit_code=0
|
|
451
327
|
fi
|
|
@@ -456,10 +332,6 @@ fi
|
|
|
456
332
|
if [[ -z "$failure_class" && "$status" != "pass" ]]; then
|
|
457
333
|
if [[ "$contract_exit" -ne 0 ]]; then
|
|
458
334
|
failure_class="contract"
|
|
459
|
-
elif [[ "$review_status" != "pass" ]]; then
|
|
460
|
-
failure_class="review"
|
|
461
|
-
elif [[ "$external_gate" != "pass" ]]; then
|
|
462
|
-
failure_class="external_acceptance"
|
|
463
335
|
elif [[ "$allowed_paths_status" != "pass" ]]; then
|
|
464
336
|
failure_class="allowed_paths"
|
|
465
337
|
else
|
|
@@ -467,9 +339,9 @@ if [[ -z "$failure_class" && "$status" != "pass" ]]; then
|
|
|
467
339
|
fi
|
|
468
340
|
fi
|
|
469
341
|
if [[ "$status" == "pass" ]]; then
|
|
470
|
-
next_step="finish contract worktree or archive completed task"
|
|
342
|
+
next_step="perform a fresh semantic impact review, then finish contract worktree or archive completed task"
|
|
471
343
|
else
|
|
472
|
-
next_step="resolve failing contract
|
|
344
|
+
next_step="resolve failing contract or allowed_paths evidence"
|
|
473
345
|
fi
|
|
474
346
|
handoff_current_exists=false
|
|
475
347
|
handoff_resume_exists=false
|
|
@@ -492,17 +364,6 @@ if command -v jq >/dev/null 2>&1 && jq -e . "$contract_report" >/dev/null 2>&1;
|
|
|
492
364
|
--arg contract_status "$([[ "$contract_exit" -eq 0 ]] && printf pass || printf fail)" \
|
|
493
365
|
--arg contract_command "$contract_command" \
|
|
494
366
|
--argjson contract_exit "$contract_exit" \
|
|
495
|
-
--arg review_file "${review_file:-}" \
|
|
496
|
-
--arg review_status "$review_status" \
|
|
497
|
-
--arg review_message "$review_message" \
|
|
498
|
-
--arg review_card_verdict "$review_card_verdict" \
|
|
499
|
-
--arg review_card_change_type "$review_card_change_type" \
|
|
500
|
-
--arg review_card_external "$review_card_external" \
|
|
501
|
-
--arg review_card_rollback "$review_card_rollback" \
|
|
502
|
-
--arg external_status "$external_status" \
|
|
503
|
-
--arg external_reviewer "$external_reviewer" \
|
|
504
|
-
--arg external_source "$external_source" \
|
|
505
|
-
--arg external_message "$external_message" \
|
|
506
367
|
--arg worktree "$worktree_path" \
|
|
507
368
|
--arg branch "$branch_name" \
|
|
508
369
|
--arg diff_base_ref "$diff_base_ref" \
|
|
@@ -538,8 +399,6 @@ if command -v jq >/dev/null 2>&1 && jq -e . "$contract_report" >/dev/null 2>&1;
|
|
|
538
399
|
],
|
|
539
400
|
guards: [
|
|
540
401
|
{name: "contract", status: $contract_status},
|
|
541
|
-
{name: "review", status: $review_status},
|
|
542
|
-
{name: "external_acceptance", status: $external_status},
|
|
543
402
|
{name: "allowed_paths", status: ($allowed_paths_check.status // "unavailable")}
|
|
544
403
|
],
|
|
545
404
|
handoffs: [
|
|
@@ -563,23 +422,6 @@ if command -v jq >/dev/null 2>&1 && jq -e . "$contract_report" >/dev/null 2>&1;
|
|
|
563
422
|
report: ($contract_report[0] // {}),
|
|
564
423
|
task_profile: $task_profile,
|
|
565
424
|
allowed_paths: $allowed_paths
|
|
566
|
-
},
|
|
567
|
-
review: {
|
|
568
|
-
file: $review_file,
|
|
569
|
-
status: $review_status,
|
|
570
|
-
message: $review_message,
|
|
571
|
-
card: {
|
|
572
|
-
verdict: $review_card_verdict,
|
|
573
|
-
change_type: $review_card_change_type,
|
|
574
|
-
external_acceptance: $review_card_external,
|
|
575
|
-
rollback: $review_card_rollback
|
|
576
|
-
}
|
|
577
|
-
},
|
|
578
|
-
external_acceptance: {
|
|
579
|
-
status: $external_status,
|
|
580
|
-
reviewer: $external_reviewer,
|
|
581
|
-
source: $external_source,
|
|
582
|
-
message: $external_message
|
|
583
425
|
}
|
|
584
426
|
}' > "$checks_report"
|
|
585
427
|
else
|
|
@@ -617,8 +459,6 @@ else
|
|
|
617
459
|
],
|
|
618
460
|
"guards": [
|
|
619
461
|
{"name": "contract", "status": "$([[ "$contract_exit" -eq 0 ]] && printf pass || printf fail)"},
|
|
620
|
-
{"name": "review", "status": "$(json_escape "$review_status")"},
|
|
621
|
-
{"name": "external_acceptance", "status": "$(json_escape "$external_status")"},
|
|
622
462
|
{"name": "allowed_paths", "status": "$(json_escape "$allowed_paths_status")"}
|
|
623
463
|
],
|
|
624
464
|
"handoffs": [
|
|
@@ -644,23 +484,6 @@ else
|
|
|
644
484
|
"exit_code": $contract_exit,
|
|
645
485
|
"task_profile": "$(json_escape "$task_profile")",
|
|
646
486
|
"allowed_paths": []
|
|
647
|
-
},
|
|
648
|
-
"review": {
|
|
649
|
-
"file": "$(json_escape "${review_file:-}")",
|
|
650
|
-
"status": "$(json_escape "$review_status")",
|
|
651
|
-
"message": "$(json_escape "$review_message")",
|
|
652
|
-
"card": {
|
|
653
|
-
"verdict": "$(json_escape "$review_card_verdict")",
|
|
654
|
-
"change_type": "$(json_escape "$review_card_change_type")",
|
|
655
|
-
"external_acceptance": "$(json_escape "$review_card_external")",
|
|
656
|
-
"rollback": "$(json_escape "$review_card_rollback")"
|
|
657
|
-
}
|
|
658
|
-
},
|
|
659
|
-
"external_acceptance": {
|
|
660
|
-
"status": "$(json_escape "$external_status")",
|
|
661
|
-
"reviewer": "$(json_escape "$external_reviewer")",
|
|
662
|
-
"source": "$(json_escape "$external_source")",
|
|
663
|
-
"message": "$(json_escape "$external_message")"
|
|
664
487
|
}
|
|
665
488
|
}
|
|
666
489
|
EOF_CHECKS
|
|
@@ -185,11 +185,7 @@ export function getHelperScripts(contract: WorkflowContract): string[] {
|
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
export function getHelperRuntimeDir(contract: WorkflowContract): string {
|
|
188
|
-
return
|
|
189
|
-
contract.helpers.runtimeDirectory ??
|
|
190
|
-
contract.helpers.compatibilityDirectory ??
|
|
191
|
-
"scripts"
|
|
192
|
-
);
|
|
188
|
+
return contract.helpers.runtimeDirectory ?? contract.helpers.compatibilityDirectory ?? "scripts";
|
|
193
189
|
}
|
|
194
190
|
|
|
195
191
|
export function getRequiredDirectories(contract: WorkflowContract): string[] {
|
|
@@ -17,7 +17,7 @@ import { Command } from 'commander';
|
|
|
17
17
|
import { runDoctor, type CheckStatus, type DoctorReport } from './doctor';
|
|
18
18
|
import { runStatus, type StatusReport } from './status';
|
|
19
19
|
import { runMcpSetupChatgpt } from '../mcp/setup';
|
|
20
|
-
import {
|
|
20
|
+
import { resolveControllerHome } from '../repositories/controller-home';
|
|
21
21
|
import {
|
|
22
22
|
configureSetupProfile,
|
|
23
23
|
detectSetupPlatform,
|
|
@@ -791,7 +791,7 @@ export function openSetupSession(options: SetupSessionOptions = {}): SetupSessio
|
|
|
791
791
|
const platform = options.platform ?? detectSetupPlatform({ env: options.env });
|
|
792
792
|
const target = options.target ?? setupHostTarget(profile);
|
|
793
793
|
const report = options.report ?? runInitHook({ ...options, target });
|
|
794
|
-
const controllerHome =
|
|
794
|
+
const controllerHome = resolveControllerHome(options.controllerHome);
|
|
795
795
|
const nextAction = profileNextAction(profile, platform, { controllerHome, accountHome: options.accountHome }) ?? report.agent_actions[0];
|
|
796
796
|
const now = (options.now ?? (() => new Date()))().toISOString();
|
|
797
797
|
const reuse = previous && previous.status !== 'closed';
|
|
@@ -1010,4 +1010,4 @@ export function buildSetupCommand(): Command {
|
|
|
1010
1010
|
});
|
|
1011
1011
|
|
|
1012
1012
|
return command;
|
|
1013
|
-
}
|
|
1013
|
+
}
|
package/src/cli/commands/mcp.ts
CHANGED
|
@@ -28,7 +28,7 @@ export interface McpServeOptions {
|
|
|
28
28
|
devRunnerAgents?: string;
|
|
29
29
|
devRunnerTimeoutMs?: string;
|
|
30
30
|
devRunnerMaxTimeoutMs?: string;
|
|
31
|
-
toolset?: 'core' | 'advanced' | 'full';
|
|
31
|
+
toolset?: 'facade' | 'core' | 'advanced' | 'full';
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
interface McpAccessOptions {
|
|
@@ -161,14 +161,14 @@ export function buildMcpCommand(): Command {
|
|
|
161
161
|
mcp
|
|
162
162
|
.command('serve')
|
|
163
163
|
.description('Start the forge MCP server')
|
|
164
|
-
.option('--repo <path>', 'Repository root to expose through the selected MCP profile'
|
|
164
|
+
.option('--repo <path>', 'Repository root to expose through the selected MCP profile')
|
|
165
165
|
.option('--controller-home <path>', 'Controller state root; defaults to repo _ops/controller-home when present')
|
|
166
166
|
.option('--transport <transport>', 'Transport: stdio|http', 'stdio')
|
|
167
167
|
.option('--host <host>', 'HTTP bind host', '127.0.0.1')
|
|
168
168
|
.option('--port <port>', 'HTTP bind port', '8765')
|
|
169
169
|
.option('--profile <profile>', 'MCP profile: planner|executor|orchestrator|controller', 'controller')
|
|
170
|
-
.option('--toolset <toolset>', 'Controller toolset: core|advanced|full (default
|
|
171
|
-
.option('--auth <mode>', 'HTTP auth mode: oauth|bearer', 'oauth')
|
|
170
|
+
.option('--toolset <toolset>', 'Controller toolset: facade|core|advanced|full (default advanced; facade is an explicit five-tool ChatGPT surface)')
|
|
171
|
+
.option('--auth <mode>', 'HTTP auth mode: oauth|bearer|none', 'oauth')
|
|
172
172
|
.option('--enable-chatgpt-browser', 'Expose tools that operate the user logged-in ChatGPT Web browser session')
|
|
173
173
|
.option('--enable-dev-runner', 'Enable local Codex/Claude task runners for controller or orchestrator profiles')
|
|
174
174
|
.option('--dev-runner-agents <agents>', 'Comma-separated dev runner agents: codex,claude')
|
|
@@ -181,7 +181,11 @@ export function buildMcpCommand(): Command {
|
|
|
181
181
|
const devRunnerMaxTimeoutMs = parsePositiveIntegerOption('dev-runner-max-timeout-ms', rawOpts.devRunnerMaxTimeoutMs);
|
|
182
182
|
if (rawOpts.transport === 'stdio') {
|
|
183
183
|
await startMcpStdio({
|
|
184
|
-
|
|
184
|
+
// stdio preserves its historical current-directory default.
|
|
185
|
+
// The HTTP controller Gateway deliberately leaves this unset so
|
|
186
|
+
// it can serve Controller Home without registering a launchd
|
|
187
|
+
// working directory as a repository.
|
|
188
|
+
repo: rawOpts.repo ?? '.',
|
|
185
189
|
controllerHome: rawOpts.controllerHome,
|
|
186
190
|
profile: rawOpts.profile,
|
|
187
191
|
toolset: rawOpts.toolset,
|
|
@@ -63,7 +63,7 @@ export function installerNextSteps(result:Record<string,unknown>):string[]{
|
|
|
63
63
|
.filter(Boolean)
|
|
64
64
|
.slice(0,10);
|
|
65
65
|
}
|
|
66
|
-
function registrationFrom(result:Record<string,unknown>,entry:RegistryEntry):ExternalPluginRegistrationInput{
|
|
66
|
+
export function registrationFrom(result:Record<string,unknown>,entry:RegistryEntry):ExternalPluginRegistrationInput{
|
|
67
67
|
if(result.registration){const input=result.registration as ExternalPluginRegistrationInput;if(input.pluginId!==entry.id)throw new Error('PLUGIN_INSTALLER_ID_MISMATCH');if(input.pluginVersion!==entry.version)throw new Error('PLUGIN_INSTALLER_VERSION_MISMATCH');return input;}
|
|
68
68
|
const facts=result.providerInstall as Record<string,unknown>|undefined;
|
|
69
69
|
if(!facts||facts.kind!=='desktop_operator'||entry.id!=='desktop_operator')throw new Error('PLUGIN_INSTALLER_REGISTRATION_MISSING');
|
|
@@ -310,7 +310,10 @@ export async function verifyRecoveryConnector(
|
|
|
310
310
|
body: initializeBody,
|
|
311
311
|
});
|
|
312
312
|
const challenge = response.headers.get('www-authenticate') ?? '';
|
|
313
|
-
const ok = response.status === 401
|
|
313
|
+
const ok = response.status === 401
|
|
314
|
+
&& /\bBearer\b/i.test(challenge)
|
|
315
|
+
&& challenge.includes('error="invalid_token"')
|
|
316
|
+
&& challenge.includes('oauth-protected-resource');
|
|
314
317
|
probes.unauthenticatedChallenge = { ok, status: response.status };
|
|
315
318
|
if (!ok) failures.push('unauthenticatedChallenge: Recovery MCP did not return the expected OAuth Bearer challenge.');
|
|
316
319
|
} catch (error) {
|
|
@@ -514,11 +517,15 @@ export function buildRecoveryCommand(): Command {
|
|
|
514
517
|
const home = resolveControllerHome(opts.controllerHome);
|
|
515
518
|
const repoRoot = resolve(opts.repo);
|
|
516
519
|
const current = loadRecoveryConfig(home);
|
|
517
|
-
const
|
|
520
|
+
const primaryConnectorBase = launchdService(
|
|
518
521
|
opts.primaryConnectorServiceLabel,
|
|
519
522
|
opts.primaryConnectorServicePlist,
|
|
520
523
|
'RECOVERY_PRIMARY_CONNECTOR',
|
|
521
524
|
) as PrimaryConnectorServiceConfig;
|
|
525
|
+
const primaryConnectorService: PrimaryConnectorServiceConfig = {
|
|
526
|
+
...primaryConnectorBase,
|
|
527
|
+
...(current.primaryConnectorService?.localMcpUrl ? { localMcpUrl: current.primaryConnectorService.localMcpUrl } : {}),
|
|
528
|
+
};
|
|
522
529
|
const installed = await installStandaloneRecovery({
|
|
523
530
|
controllerHome: home,
|
|
524
531
|
repoRoot,
|
|
@@ -526,6 +533,7 @@ export function buildRecoveryCommand(): Command {
|
|
|
526
533
|
publicMcpUrl: current.publicMcpUrl,
|
|
527
534
|
recoveryPublicUrl: current.recoveryPublicUrl,
|
|
528
535
|
recoveryTunnelService: current.recoveryTunnelService,
|
|
536
|
+
primaryPublicTunnelService: current.primaryPublicTunnelService,
|
|
529
537
|
primaryRuntimeService: current.primaryRuntimeService ?? { platform: 'launchd' },
|
|
530
538
|
primaryConnectorService,
|
|
531
539
|
});
|
|
@@ -622,6 +630,9 @@ export function buildRecoveryCommand(): Command {
|
|
|
622
630
|
.option('--recovery-tunnel-service-plist <path>', 'Absolute Recovery tunnel launchd plist path')
|
|
623
631
|
.option('--primary-connector-service-label <label>', 'Primary OAuth/Connector launchd label managed by standalone Recovery')
|
|
624
632
|
.option('--primary-connector-service-plist <path>', 'Absolute primary OAuth/Connector launchd plist path')
|
|
633
|
+
.option('--primary-connector-local-url <url>', 'Local primary OAuth/Connector MCP endpoint used to distinguish Connector from tunnel failures')
|
|
634
|
+
.option('--primary-tunnel-service-label <label>', 'Primary public MCP tunnel launchd label managed by standalone Recovery')
|
|
635
|
+
.option('--primary-tunnel-service-plist <path>', 'Absolute primary public MCP tunnel launchd plist path')
|
|
625
636
|
.option('--stage-only', 'Build and canary the Recovery release without activating services')
|
|
626
637
|
.action(async (opts: {
|
|
627
638
|
controllerHome: string;
|
|
@@ -632,13 +643,23 @@ export function buildRecoveryCommand(): Command {
|
|
|
632
643
|
recoveryTunnelServicePlist?: string;
|
|
633
644
|
primaryConnectorServiceLabel?: string;
|
|
634
645
|
primaryConnectorServicePlist?: string;
|
|
646
|
+
primaryConnectorLocalUrl?: string;
|
|
647
|
+
primaryTunnelServiceLabel?: string;
|
|
648
|
+
primaryTunnelServicePlist?: string;
|
|
635
649
|
stageOnly?: boolean;
|
|
636
650
|
}) => {
|
|
637
651
|
const home = resolveControllerHome(opts.controllerHome);
|
|
638
652
|
const port = Number(opts.port);
|
|
639
653
|
if (!Number.isInteger(port) || port < 1024 || port > 65535) throw new Error('RECOVERY_PORT_INVALID');
|
|
640
654
|
const recoveryTunnelService = launchdService(opts.recoveryTunnelServiceLabel, opts.recoveryTunnelServicePlist, 'RECOVERY_TUNNEL') as PublicTunnelServiceConfig | undefined;
|
|
641
|
-
const
|
|
655
|
+
const primaryConnectorBase = launchdService(opts.primaryConnectorServiceLabel, opts.primaryConnectorServicePlist, 'RECOVERY_PRIMARY_CONNECTOR') as PrimaryConnectorServiceConfig | undefined;
|
|
656
|
+
const primaryConnectorLocalUrl = endpoint(opts.primaryConnectorLocalUrl, 'RECOVERY_PRIMARY_CONNECTOR_LOCAL_URL');
|
|
657
|
+
if (primaryConnectorLocalUrl && !primaryConnectorBase) throw new Error('RECOVERY_PRIMARY_CONNECTOR_LABEL_REQUIRED_FOR_LOCAL_URL');
|
|
658
|
+
const primaryConnectorService = primaryConnectorBase
|
|
659
|
+
? { ...primaryConnectorBase, ...(primaryConnectorLocalUrl ? { localMcpUrl: primaryConnectorLocalUrl } : {}) }
|
|
660
|
+
: undefined;
|
|
661
|
+
const primaryPublicTunnelService = launchdService(opts.primaryTunnelServiceLabel, opts.primaryTunnelServicePlist, 'RECOVERY_PRIMARY_TUNNEL') as PublicTunnelServiceConfig | undefined;
|
|
662
|
+
if (primaryPublicTunnelService && !primaryConnectorService) throw new Error('RECOVERY_PRIMARY_CONNECTOR_REQUIRED_FOR_PRIMARY_TUNNEL');
|
|
642
663
|
const recoveryPublicUrl = endpoint(opts.recoveryPublicUrl, 'RECOVERY_PUBLIC_URL');
|
|
643
664
|
if (Boolean(recoveryTunnelService) !== Boolean(recoveryPublicUrl)) {
|
|
644
665
|
throw new Error('RECOVERY_PUBLIC_URL_AND_TUNNEL_SERVICE_MUST_BE_CONFIGURED_TOGETHER');
|
|
@@ -653,6 +674,7 @@ export function buildRecoveryCommand(): Command {
|
|
|
653
674
|
publicMcpUrl: endpoint(opts.publicMcpUrl, 'PUBLIC_MCP_URL'),
|
|
654
675
|
recoveryPublicUrl,
|
|
655
676
|
recoveryTunnelService,
|
|
677
|
+
primaryPublicTunnelService,
|
|
656
678
|
primaryConnectorService,
|
|
657
679
|
});
|
|
658
680
|
output({
|
|
@@ -13,8 +13,14 @@ import { observeRuntimeStatus } from '../../runtime/root/status';
|
|
|
13
13
|
import { readMcpServiceBearerToken } from '../mcp/auth';
|
|
14
14
|
import { publishRuntimeRelease } from '../../runtime/root/release-store';
|
|
15
15
|
import { installForgeRuntimeService } from '../../runtime/root/service';
|
|
16
|
-
import { installPackageRuntimeService } from '../../runtime/root/package-runtime-service';
|
|
16
|
+
import { activateScheduledPackageRuntimeServiceFromPath, installPackageRuntimeService, readPackageRuntimeActivationReceipt } from '../../runtime/root/package-runtime-service';
|
|
17
17
|
import { assertRuntimeReleaseFiles, stageRuntimeReleaseFromCandidateSource } from '../../runtime/root/release-materialize';
|
|
18
|
+
import {
|
|
19
|
+
applyControllerHomeMigration,
|
|
20
|
+
previewControllerHomeMigration,
|
|
21
|
+
rollbackControllerHomeMigration,
|
|
22
|
+
archiveUnroutableMigratedWork,
|
|
23
|
+
} from '../../runtime/control-plane/persistence/controller-home-migration';
|
|
18
24
|
|
|
19
25
|
function output(value: unknown, json = true): void {
|
|
20
26
|
console.log(json ? JSON.stringify(value, null, 2) : String(value));
|
|
@@ -30,6 +36,22 @@ export function buildRuntimeCommand(): Command {
|
|
|
30
36
|
const service = command.command('service')
|
|
31
37
|
.description('Install or inspect the user-level Forge Runtime owner');
|
|
32
38
|
|
|
39
|
+
service.command('activate-package', { hidden: true })
|
|
40
|
+
.description('Internal one-shot activation helper for a staged package Runtime release')
|
|
41
|
+
.requiredOption('--request <path>', 'Activation request path')
|
|
42
|
+
.action(async (opts: { request: string }) => {
|
|
43
|
+
output(await activateScheduledPackageRuntimeServiceFromPath(opts.request));
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
service.command('activation-status')
|
|
47
|
+
.description('Read a durable package Runtime activation receipt')
|
|
48
|
+
.requiredOption('--receipt <path>', 'Activation receipt path returned by install-package')
|
|
49
|
+
.action((opts: { receipt: string }) => {
|
|
50
|
+
const receipt = readPackageRuntimeActivationReceipt(resolve(opts.receipt));
|
|
51
|
+
if (!receipt) throw new Error('RUNTIME_PACKAGE_ACTIVATION_RECEIPT_NOT_FOUND');
|
|
52
|
+
output(receipt);
|
|
53
|
+
});
|
|
54
|
+
|
|
33
55
|
service.command('install-package')
|
|
34
56
|
.description('Install the current packaged Forge Runtime without requiring a Git checkout, Bun compilation, CodeGraph, or Standalone Recovery')
|
|
35
57
|
.option('--controller-home <path>', 'Controller Home; defaults to the user-level Forge Controller Home')
|
|
@@ -37,7 +59,8 @@ export function buildRuntimeCommand(): Command {
|
|
|
37
59
|
.option('--port <port>', 'MCP listener port', '8765')
|
|
38
60
|
.option('--auth-token-file <path>', 'Raw bearer token file (created from user-level MCP config when missing)')
|
|
39
61
|
.option('--portable', 'Force a detached session process instead of launchd/systemd user persistence')
|
|
40
|
-
.
|
|
62
|
+
.option('--refresh-connector', 'Explicitly replace/restart the persistent public MCP Gateway instead of reusing a healthy existing Gateway')
|
|
63
|
+
.action(async (opts: { controllerHome?: string; host: string; port: string; authTokenFile?: string; portable?: boolean; refreshConnector?: boolean }) => {
|
|
41
64
|
const home = resolveControllerHome(opts.controllerHome);
|
|
42
65
|
const port = Number(opts.port);
|
|
43
66
|
if (!Number.isInteger(port) || port < 1 || port > 65_535) throw new Error('RUNTIME_SERVICE_PORT_INVALID');
|
|
@@ -56,6 +79,7 @@ export function buildRuntimeCommand(): Command {
|
|
|
56
79
|
port,
|
|
57
80
|
authTokenFile: tokenPath,
|
|
58
81
|
forcePortable: opts.portable === true,
|
|
82
|
+
refreshConnector: opts.refreshConnector === true,
|
|
59
83
|
});
|
|
60
84
|
output({
|
|
61
85
|
status: result.status,
|
|
@@ -73,8 +97,11 @@ export function buildRuntimeCommand(): Command {
|
|
|
73
97
|
servicePath: result.servicePath,
|
|
74
98
|
pid: result.pid,
|
|
75
99
|
connector: result.connector,
|
|
100
|
+
activation: result.activation,
|
|
76
101
|
warnings: result.warnings,
|
|
77
|
-
next:
|
|
102
|
+
next: result.activation
|
|
103
|
+
? `forge runtime service activation-status --receipt ${result.activation.receiptPath}`
|
|
104
|
+
: `forge runtime status --controller-home ${home}`,
|
|
78
105
|
});
|
|
79
106
|
});
|
|
80
107
|
|
|
@@ -163,6 +190,31 @@ export function buildRuntimeCommand(): Command {
|
|
|
163
190
|
});
|
|
164
191
|
});
|
|
165
192
|
|
|
193
|
+
command.command('migrate-controller-home')
|
|
194
|
+
.description('Preview or transactionally migrate non-terminal business state from an explicitly selected retired Controller Home')
|
|
195
|
+
.requiredOption('--source <path>', 'Retired Controller Home to inspect; repository presence never selects this implicitly')
|
|
196
|
+
.option('--destination <path>', 'Canonical Controller Home; defaults to the installed user-level authority')
|
|
197
|
+
.option('--apply', 'Apply the reviewed migration and freeze the source SQLite as a read-only archive')
|
|
198
|
+
.option('--rollback <migration-id>', 'Rollback one migration only when none of its imported records changed')
|
|
199
|
+
.option('--archive-unroutable <migration-id>', 'Archive imported nonterminal Work whose repository is not registered in the canonical Home')
|
|
200
|
+
.action(async (opts: { source: string; destination?: string; apply?: boolean; rollback?: string; archiveUnroutable?: string }) => {
|
|
201
|
+
const destination = resolveControllerHome(opts.destination);
|
|
202
|
+
if (opts.archiveUnroutable?.trim()) {
|
|
203
|
+
output(archiveUnroutableMigratedWork({ destinationHome: destination, migrationId: opts.archiveUnroutable.trim() }));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (opts.rollback?.trim()) {
|
|
207
|
+
output(rollbackControllerHomeMigration({ destinationHome: destination, migrationId: opts.rollback.trim() }));
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const input = { sourceHome: resolve(opts.source), destinationHome: destination };
|
|
211
|
+
if (opts.apply === true) {
|
|
212
|
+
output(await applyControllerHomeMigration(input));
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
output(await previewControllerHomeMigration(input));
|
|
216
|
+
});
|
|
217
|
+
|
|
166
218
|
command.command('status')
|
|
167
219
|
.description('Read the Runtime Root status projection, active durable Jobs, and materialized repository projections')
|
|
168
220
|
.requiredOption('--controller-home <path>', 'Explicit Controller Home')
|
|
@@ -8,7 +8,7 @@ import * as fs from 'fs';
|
|
|
8
8
|
import * as os from 'os';
|
|
9
9
|
import * as path from 'path';
|
|
10
10
|
import { execFileSync } from 'child_process';
|
|
11
|
-
import { MANAGED_TAG, type HookEntry } from '../installer/managed-entries';
|
|
11
|
+
import { MANAGED_TAG, isLegacyRepoHarnessCommand, type HookEntry } from '../installer/managed-entries';
|
|
12
12
|
|
|
13
13
|
export type SecurityStatus = 'ok' | 'warn' | 'fail';
|
|
14
14
|
export type SecuritySeverity = 'warn' | 'high' | 'fail';
|
|
@@ -273,6 +273,17 @@ function scanHookConfig(
|
|
|
273
273
|
if (!command) continue;
|
|
274
274
|
const suspicious = suspiciousMatch(command);
|
|
275
275
|
if (command.includes(MANAGED_TAG) && suspicious === null) continue;
|
|
276
|
+
if (isLegacyRepoHarnessCommand(command)) {
|
|
277
|
+
findings.push({
|
|
278
|
+
filePath,
|
|
279
|
+
ruleId: 'legacy-repo-harness-hook-adapter',
|
|
280
|
+
severity: 'warn',
|
|
281
|
+
summary: `${hostLabel} ${event} hook uses the retired repo-harness adapter`,
|
|
282
|
+
recommendation: 'Run forge install --target codex --location global to replace retired adapters with forge-hook.',
|
|
283
|
+
command,
|
|
284
|
+
});
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
276
287
|
findings.push({
|
|
277
288
|
filePath,
|
|
278
289
|
ruleId: suspicious?.ruleId ?? 'unmanaged-hook-command',
|