@moretea-labs/forge 1.7.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +58 -62
- package/CHANGELOG.md +39 -0
- package/CLAUDE.md +42 -62
- package/README.md +2 -2
- package/SKILL.md +0 -1
- package/THIRD_PARTY_NOTICES.md +5 -2
- package/adapters/browser/index.ts +2 -0
- package/adapters/chatgpt/browser-delivery-host.ts +71 -0
- package/adapters/chatgpt/browser-delivery-runtime.ts +783 -0
- package/adapters/chatgpt/controller-binding-store.ts +55 -0
- package/adapters/chatgpt/controller-host.ts +119 -0
- package/adapters/chatgpt/controller-round-host.ts +78 -0
- package/adapters/chatgpt/controller-round-settlement-store.ts +45 -0
- package/adapters/chatgpt/provider-delivery.ts +113 -0
- package/adapters/chatgpt/work-conversation-binding-store.ts +192 -0
- package/adapters/chatgpt/wsl-bridge-delivery-host.ts +63 -0
- package/adapters/computer/desktop-operator-contract.ts +7 -0
- package/adapters/computer/desktop-operator-discovery.ts +201 -0
- package/adapters/computer/desktop-operator-negotiation.ts +174 -0
- package/adapters/computer/desktop-operator-provider.ts +312 -0
- package/adapters/computer/index.ts +1 -0
- package/adapters/computer/interaction-target-authority.ts +944 -0
- package/adapters/controller-process/binding-store.ts +34 -0
- package/adapters/controller-process/controller-host.ts +26 -0
- package/adapters/mcp/access-mode.ts +132 -0
- package/adapters/mcp/audit.ts +32 -0
- package/adapters/mcp/auth.ts +407 -0
- package/adapters/mcp/controller-round-compatibility.ts +184 -0
- package/adapters/mcp/frozen-client-semantic-compatibility.ts +292 -0
- package/adapters/mcp/instructions.ts +36 -0
- package/adapters/mcp/legacy-context.ts +18 -0
- package/adapters/mcp/multi-repository.ts +437 -0
- package/adapters/mcp/oauth.ts +391 -0
- package/adapters/mcp/paths.ts +140 -0
- package/adapters/mcp/policy.ts +232 -0
- package/adapters/mcp/proxy-env.ts +62 -0
- package/adapters/mcp/readiness-projection.ts +24 -0
- package/adapters/mcp/redaction.ts +21 -0
- package/adapters/mcp/repo.ts +24 -0
- package/adapters/mcp/runtime-gateway/artifact-adapter.ts +52 -0
- package/adapters/mcp/runtime-gateway/context-adapter.ts +829 -0
- package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +191 -0
- package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +147 -0
- package/adapters/mcp/runtime-gateway/execution-control-adapter.ts +28 -0
- package/adapters/mcp/runtime-gateway/execution-tools.ts +207 -0
- package/adapters/mcp/runtime-gateway/filesystem-adapter.ts +38 -0
- package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +411 -0
- package/adapters/mcp/runtime-gateway/legacy-ios-tool-adapter.ts +105 -0
- package/adapters/mcp/runtime-gateway/maintenance-adapter.ts +44 -0
- package/adapters/mcp/runtime-gateway/model-adapter.ts +63 -0
- package/adapters/mcp/runtime-gateway/persisted-check-process.ts +3 -0
- package/adapters/mcp/runtime-gateway/plugin-adapter.ts +308 -0
- package/adapters/mcp/runtime-gateway/process-tools.ts +289 -0
- package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +76 -0
- package/adapters/mcp/runtime-gateway/recovery-adapter.ts +268 -0
- package/adapters/mcp/runtime-gateway/recovery-client-adapter.ts +70 -0
- package/adapters/mcp/runtime-gateway/recovery-tool-contract.ts +99 -0
- package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +110 -0
- package/adapters/mcp/runtime-gateway/result-adapter.ts +108 -0
- package/adapters/mcp/runtime-gateway/router.ts +728 -0
- package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1251 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +634 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-shared.ts +27 -0
- package/adapters/mcp/runtime-gateway/runtime-tools.ts +68 -0
- package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +186 -0
- package/adapters/mcp/runtime-gateway/shared-adapter.ts +25 -0
- package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +870 -0
- package/adapters/mcp/runtime-gateway/work-adapter.ts +3186 -0
- package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +502 -0
- package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +1 -0
- package/adapters/mcp/server.ts +1048 -0
- package/adapters/mcp/setup.ts +791 -0
- package/adapters/mcp/tool-capability-cache.ts +87 -0
- package/adapters/mcp/tool-mapping/access-tools.ts +387 -0
- package/adapters/mcp/tool-mapping/legacy-tool-service.ts +5265 -0
- package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +150 -0
- package/adapters/mcp/tool-mapping/repository-tools.ts +1691 -0
- package/adapters/mcp/tool-mapping/tools.ts +9 -0
- package/adapters/mcp/tool-mapping/umbrella-tools.ts +117 -0
- package/adapters/mcp/toolset-names.ts +74 -0
- package/adapters/mcp/toolset-selection.ts +41 -0
- package/adapters/mcp/toolset.ts +336 -0
- package/adapters/mcp/transports/http.ts +1456 -0
- package/adapters/mcp/transports/session-registry.ts +513 -0
- package/adapters/mcp/transports/stdio.ts +8 -0
- package/adapters/mcp/tunnels/openai-secure-tunnel.ts +139 -0
- package/adapters/mcp/types.ts +41 -0
- package/assets/AGENTS.md +2 -16
- package/assets/CLAUDE.md +2 -16
- package/assets/hooks/AGENTS.md +3 -14
- package/assets/hooks/CLAUDE.md +3 -14
- package/assets/hooks/hook-input.sh +9 -2
- package/assets/hooks/lib/workflow-state.sh +28 -10
- package/assets/hooks/prompt-guard.sh +63 -37
- package/assets/hooks/security-sentinel.sh +2 -1
- package/assets/hooks/session-start-context.sh +7 -5
- package/assets/hooks/stop-orchestrator.sh +13 -3
- package/assets/initializer-question-pack.v4.json +11 -7
- package/assets/partials/05-workflow.partial.md +18 -73
- package/assets/partials/07-footer.partial.md +1 -1
- package/assets/partials-agents/02-operating-mode.partial.md +1 -2
- package/assets/partials-agents/04-task-protocol.partial.md +14 -59
- package/assets/partials-agents/06-quality-safety.partial.md +11 -16
- package/assets/partials-agents/08-deep-docs.partial.md +1 -2
- package/assets/plan-map.json +11 -11
- package/assets/plugin-registry.v1.json +9 -3
- package/assets/plugin-trust-policy.v1.json +6 -0
- package/assets/recovery/ForgeRecovery.ps1 +100 -0
- package/assets/recovery/forge-wsl-rescue +271 -0
- package/assets/reference-configs/development-protocol.md +11 -15
- package/assets/reference-configs/document-generation.md +1 -1
- package/assets/reference-configs/global-working-rules.md +9 -1
- package/assets/reference-configs/harness-overview.md +22 -112
- package/assets/reference-configs/hook-operations.md +1 -1
- package/assets/reference-configs/sprint-contracts.md +2 -2
- package/assets/skill-version.json +2 -2
- package/assets/templates/helpers/architecture-event.ts +3 -34
- package/assets/templates/helpers/architecture-queue.sh +61 -10
- package/assets/templates/helpers/archive-workflow.sh +90 -180
- package/assets/templates/helpers/capability-config.ts +8 -11
- package/assets/templates/helpers/capability-resolver.ts +37 -19
- package/assets/templates/helpers/capture-plan.sh +2 -2
- package/assets/templates/helpers/check-architecture-sync.sh +1 -9
- package/assets/templates/helpers/check-task-sync.sh +82 -11
- package/assets/templates/helpers/check-task-workflow.sh +1 -3
- package/assets/templates/helpers/context-contract-sync.sh +1 -12
- package/assets/templates/helpers/contract-worktree.sh +26 -24
- package/assets/templates/helpers/ensure-task-workflow.sh +6 -8
- package/assets/templates/helpers/inspect-project-state.ts +1 -1
- package/assets/templates/helpers/migrate-project-template.sh +1 -1
- package/assets/templates/helpers/migrate-workflow-docs.ts +53 -239
- package/assets/templates/helpers/new-plan.sh +2 -2
- package/assets/templates/helpers/plan-to-todo.sh +3 -31
- package/assets/templates/helpers/sprint-backlog.sh +1 -1
- package/assets/templates/helpers/switch-plan.sh +1 -1
- package/assets/templates/helpers/workflow-contract.ts +1 -0
- package/assets/workflow-contract.v1.json +63 -171
- package/assets/workflows/xiaohongshu/xiaohongshu.collect-metrics.v1.draft.json +118 -0
- package/assets/workflows/xiaohongshu/xiaohongshu.publish-image-note.v1.draft.json +316 -0
- package/assets/workflows/xiaohongshu/xiaohongshu.publish-long-text.v1.draft.json +324 -0
- package/docs/architecture/CURRENT.md +148 -13
- package/docs/architecture/EVOLUTION.md +13 -0
- package/docs/architecture/decisions/20260801-controller-home-sqlite-state.md +2 -1
- package/docs/architecture/decisions/20260831-independent-windows-wsl-host-rescue.md +59 -0
- package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +120 -0
- package/docs/architecture/decisions/20260904-repository-runtime-data-boundary.md +42 -0
- package/docs/architecture/decisions/20260907-assistant-learning-loop.md +35 -0
- package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +296 -0
- package/docs/architecture/decisions/20260907-maintenance-diagnosis-bounded-read.md +39 -0
- package/docs/architecture/domains/verification.md +7 -0
- package/docs/architecture/domains/workflow-engine.md +1 -1
- package/docs/architecture/index.md +3 -3
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +19 -8
- package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +124 -0
- package/docs/forge-chatgpt-mcp-setup.md +5 -3
- package/docs/forge-plugin-management.md +20 -4
- package/docs/forge-runtime-self-healing-loop.md +2 -0
- package/docs/operations/benchmark-cross-version-freeze.md +38 -0
- package/docs/operations/controller-browser-plugin.md +3 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/platform-support.md +16 -8
- package/docs/operations/platform-support.zh-CN.md +2 -2
- package/docs/operations/standalone-disaster-recovery.md +26 -1
- package/docs/operations/uu-remote-rescue.md +41 -0
- package/docs/operations/windows-wsl-host-rescue.md +133 -0
- package/docs/public-usage-guide.md +1 -1
- package/docs/public-usage-guide.zh-CN.md +1 -1
- package/docs/tutorials/01-install-and-start.md +1 -1
- package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
- package/docs/tutorials/02-connect-chatgpt.md +4 -4
- package/docs/tutorials/02-connect-chatgpt.zh-CN.md +4 -4
- package/docs/wiki/Implementation.md +1 -1
- package/package.json +23 -14
- package/packages/kernel/controller/api/index.ts +2 -0
- package/packages/kernel/controller/application/controller-round-service.ts +29 -0
- package/packages/kernel/controller/application/controller-service.ts +30 -0
- package/packages/kernel/controller/domain/controller-round-transition-policy.ts +308 -0
- package/packages/kernel/controller/domain/controller-round.ts +107 -0
- package/packages/kernel/controller/domain/execution-quality.ts +133 -0
- package/packages/kernel/controller/domain/types.ts +56 -0
- package/packages/kernel/controller/index.ts +1 -0
- package/packages/kernel/controller/infrastructure/controller-binding-store.ts +84 -0
- package/packages/kernel/controller/infrastructure/controller-round-store.ts +1384 -0
- package/packages/kernel/controller/infrastructure/controller-session-store.ts +578 -0
- package/packages/kernel/controller/ports/controller-host.ts +16 -0
- package/packages/kernel/goal/api/index.ts +1 -0
- package/packages/kernel/goal/domain/types.ts +40 -0
- package/packages/kernel/goal/index.ts +1 -0
- package/packages/kernel/identity/api/index.ts +5 -0
- package/packages/kernel/identity/application/identity-service.ts +67 -0
- package/packages/kernel/identity/domain/scope.ts +63 -0
- package/packages/kernel/identity/domain/semantic-sync.ts +81 -0
- package/packages/kernel/identity/domain/types.ts +44 -0
- package/packages/kernel/identity/domain/workspace.ts +56 -0
- package/packages/kernel/identity/index.ts +1 -0
- package/packages/kernel/identity/infrastructure/identity-store.ts +75 -0
- package/packages/kernel/memory/api/index.ts +5 -0
- package/packages/kernel/memory/application/experience-service.ts +118 -0
- package/packages/kernel/memory/application/outcome-service.ts +77 -0
- package/packages/kernel/memory/domain/experience.ts +103 -0
- package/packages/kernel/memory/domain/operational-prior.ts +92 -0
- package/packages/kernel/memory/index.ts +1 -0
- package/packages/kernel/progression/api/index.ts +2 -0
- package/packages/kernel/progression/application/projector.ts +211 -0
- package/packages/kernel/progression/domain/types.ts +116 -0
- package/packages/kernel/progression/index.ts +1 -0
- package/packages/kernel/scheduler/api/index.ts +6 -0
- package/packages/kernel/scheduler/application/continuation-service.ts +212 -0
- package/packages/kernel/scheduler/application/eligibility.ts +252 -0
- package/packages/kernel/scheduler/application/schedule-service.ts +24 -0
- package/packages/kernel/scheduler/application/settlement.ts +197 -0
- package/packages/kernel/scheduler/domain/continuation.ts +38 -0
- package/packages/kernel/scheduler/domain/schedule.ts +149 -0
- package/packages/kernel/scheduler/index.ts +1 -0
- package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +38 -0
- package/packages/kernel/scheduler/infrastructure/schedule-store.ts +785 -0
- package/packages/kernel/work/api/index.ts +15 -0
- package/packages/kernel/work/application/work-service.ts +148 -0
- package/packages/kernel/work/domain/admission-policy.ts +34 -0
- package/packages/kernel/work/domain/check-receipt.ts +43 -0
- package/packages/kernel/work/domain/context-closure-receipt.ts +32 -0
- package/packages/kernel/work/domain/engineering-contracts.ts +157 -0
- package/packages/kernel/work/domain/engineering-design.ts +281 -0
- package/packages/kernel/work/domain/engineering-profile.ts +242 -0
- package/packages/kernel/work/domain/execution-concurrency.ts +254 -0
- package/packages/kernel/work/domain/execution-snapshot.ts +33 -0
- package/packages/kernel/work/domain/implementation-review.ts +510 -0
- package/packages/kernel/work/domain/project-engineering-contract.ts +202 -0
- package/packages/kernel/work/domain/repository-completion-receipt.ts +73 -0
- package/packages/kernel/work/domain/state-machine.ts +259 -0
- package/packages/kernel/work/domain/types.ts +528 -0
- package/packages/kernel/work/index.ts +1 -0
- package/packages/kernel/work/infrastructure/work-contract-store.ts +1876 -0
- package/packages/kernel/work/ports/work-contract-store.ts +18 -0
- package/packages/plugin-runtime/browser/index.ts +3 -0
- package/packages/plugin-runtime/browser/provider-registry.ts +110 -0
- package/packages/plugin-runtime/browser/runtime-contract.ts +150 -0
- package/packages/plugin-runtime/browser/session-authority.ts +61 -0
- package/packages/plugin-runtime/computer/index.ts +6 -0
- package/packages/plugin-runtime/computer/provider-error.ts +26 -0
- package/packages/plugin-runtime/computer/provider-registration.ts +52 -0
- package/packages/plugin-runtime/computer/provider-registry.ts +63 -0
- package/packages/plugin-runtime/computer/provider.ts +19 -0
- package/packages/plugin-runtime/computer/target-authority.ts +190 -0
- package/packages/plugin-runtime/computer/target-persistence.ts +54 -0
- package/packages/plugin-runtime/external/index.ts +1 -0
- package/packages/plugin-runtime/external/unix-jsonl-transport.ts +457 -0
- package/packages/plugin-runtime/index.ts +3 -0
- package/packages/protocols/browser/index.ts +1 -0
- package/packages/protocols/browser/session.ts +98 -0
- package/packages/protocols/computer/contract.ts +199 -0
- package/packages/protocols/computer/index.ts +1 -0
- package/packages/protocols/failure/contract.ts +158 -0
- package/packages/protocols/failure/index.ts +1 -0
- package/packages/protocols/handoff/index.ts +1 -0
- package/packages/protocols/handoff/status.ts +22 -0
- package/packages/protocols/mcp/execution-context.ts +11 -0
- package/packages/protocols/mcp/index.ts +2 -0
- package/packages/protocols/mcp/tool-contract.ts +42 -0
- package/packages/workflow-runtime/api/index.ts +2 -0
- package/packages/workflow-runtime/application/interpreter.ts +342 -0
- package/packages/workflow-runtime/domain/workflow-asset.ts +223 -0
- package/packages/workflow-runtime/index.ts +1 -0
- package/scripts/assemble-template.ts +1 -1
- package/scripts/benchmark-computer-hotpath.ts +255 -0
- package/scripts/benchmark-controller-round2.ts +54 -2
- package/scripts/benchmark-ios-agent-device.ts +3 -6
- package/scripts/benchmark-mcp-transport.ts +3 -4
- package/scripts/benchmark-operational-memory-activation.ts +235 -0
- package/scripts/benchmark-operational-shadow.ts +28 -0
- package/scripts/bootstrap-runtime-maintenance-recovery.sh +4 -1
- package/scripts/canary-chatgpt-provider-delivery.ts +97 -0
- package/scripts/canary-controller-semantic-wait.ts +195 -0
- package/scripts/canary-global-hook.sh +2 -2
- package/scripts/check-mcp-compatibility.ts +173 -7
- package/scripts/check-platform-support.mjs +28 -2
- package/scripts/check-public-docs.sh +1 -1
- package/scripts/check-release-readiness.sh +1 -1
- package/scripts/check-repository-hygiene.mjs +92 -0
- package/scripts/check-runtime-architecture.mjs +1206 -95
- package/scripts/check-source-duplication.mjs +9 -1
- package/scripts/check-tarball-install-smoke.sh +98 -15
- package/scripts/controller-ngrok-rotation.sh +5 -4
- package/scripts/create-project-dirs.sh +10 -74
- package/scripts/forge-local-recovery-helper.mjs +204 -0
- package/scripts/forge-uu-remote-rescue-helper.d.mts +31 -0
- package/scripts/forge-uu-remote-rescue-helper.mjs +409 -0
- package/scripts/forge-windows-host-recovery-helper.mjs +136 -0
- package/scripts/hook-shim.sh +2 -2
- package/scripts/init-project.sh +12 -70
- package/scripts/install-desktop-operator-registration.ts +4 -2
- package/scripts/install-independent-windows-wsl-recovery.ts +125 -0
- package/scripts/install-standalone-recovery.ts +122 -10
- package/scripts/install-uu-remote-rescue-registration.ts +74 -0
- package/scripts/install-windows-host-recovery-registration.ts +22 -0
- package/scripts/lib/controller-home-env.sh +6 -3
- package/scripts/lib/project-init-lib.sh +39 -582
- package/scripts/migrate-chatgpt-automation-schedules.ts +2 -2
- package/scripts/migrate-windows-wsl-controller-home.ts +306 -0
- package/scripts/open-source-audit-allowlist.txt +12 -1
- package/scripts/portability-bindings.mjs +70 -0
- package/scripts/run-bounded-command.mjs +55 -0
- package/scripts/run-bun-test-file.ts +22 -6
- package/scripts/run-governed-gate.ts +4 -1
- package/scripts/smoke-mcp-http-runtime.ts +1 -1
- package/scripts/smoke-runtime-recovery.ts +34 -1
- package/scripts/smoke-schedule-engine.ts +1 -1
- package/scripts/stage-runtime-release.ts +6 -1
- package/scripts/test-governance.ts +51 -2
- package/src/cli/agent-jobs/job-manager.ts +10 -1
- package/src/cli/chatgpt-browser/bind-server.ts +2 -1
- package/src/cli/chatgpt-browser/binding.ts +20 -10
- package/src/cli/chatgpt-browser/bridge-extension.ts +75 -0
- package/src/cli/chatgpt-browser/bridge-provider.ts +376 -11
- package/src/cli/chatgpt-browser/engine.ts +10 -11
- package/src/cli/chatgpt-browser/native-provider.ts +24 -83
- package/src/cli/chatgpt-browser/oracle-provider.ts +5 -3
- package/src/cli/chatgpt-browser/types.ts +1 -0
- package/src/cli/commands/bootstrap-control.ts +334 -0
- package/src/cli/commands/brain-assistant.ts +38 -0
- package/src/cli/commands/brain.ts +193 -40
- package/src/cli/commands/chatgpt.ts +127 -0
- package/src/cli/commands/computer.ts +437 -0
- package/src/cli/commands/doctor.ts +18 -1
- package/src/cli/commands/init-hook.ts +71 -61
- package/src/cli/commands/init.ts +3 -1
- package/src/cli/commands/mcp.ts +16 -10
- package/src/cli/commands/plugin.ts +38 -12
- package/src/cli/commands/recovery.ts +493 -80
- package/src/cli/commands/runtime.ts +9 -4
- package/src/cli/commands/setup-profile.ts +89 -39
- package/src/cli/commands/status.ts +2 -1
- package/src/cli/controller/check-runner.ts +487 -98
- package/src/cli/controller/context/types.ts +7 -1
- package/src/cli/controller/context-pack.ts +23 -3
- package/src/cli/controller/issue-store.ts +1 -1
- package/src/cli/controller/systemd-user.ts +110 -0
- package/src/cli/controller/types.ts +10 -70
- package/src/cli/controller/worklog.ts +67 -13
- package/src/cli/editing/edit-operation-contract.ts +92 -0
- package/src/cli/editing/edit-session.ts +289 -13
- package/src/cli/github/plugin.ts +17 -12
- package/src/cli/hook/route-registry.ts +3 -5
- package/src/cli/hook/runtime.ts +49 -3
- package/src/cli/index.ts +3 -0
- package/src/cli/local-bridge/connector-freshness.ts +2 -2
- package/src/cli/local-bridge/console-automations.ts +2 -2
- package/src/cli/local-bridge/facade-api.ts +41 -14
- package/src/cli/local-bridge/job-store.ts +1 -1
- package/src/cli/local-bridge/server.ts +24 -27
- package/src/cli/mcp/access-mode.ts +2 -132
- package/src/cli/mcp/access-tools.ts +2 -387
- package/src/cli/mcp/audit.ts +2 -32
- package/src/cli/mcp/auth.ts +2 -404
- package/src/cli/mcp/instructions.ts +2 -34
- package/src/cli/mcp/legacy-context.ts +2 -16
- package/src/cli/mcp/legacy-tool-service.ts +2 -5308
- package/src/cli/mcp/multi-repository.ts +2 -436
- package/src/cli/mcp/oauth.ts +2 -375
- package/src/cli/mcp/openai-secure-tunnel.ts +2 -0
- package/src/cli/mcp/paths.ts +2 -140
- package/src/cli/mcp/policy.ts +2 -232
- package/src/cli/mcp/post-finalize-work-attribution.ts +2 -150
- package/src/cli/mcp/proxy-env.ts +2 -62
- package/src/cli/mcp/readiness-projection.ts +2 -24
- package/src/cli/mcp/redaction.ts +2 -21
- package/src/cli/mcp/repo.ts +2 -24
- package/src/cli/mcp/repository-tools.ts +2 -1585
- package/src/cli/mcp/server.ts +2 -951
- package/src/cli/mcp/setup.ts +2 -737
- package/src/cli/mcp/tool-capability-cache.ts +2 -87
- package/src/cli/mcp/tool-contract.ts +2 -14
- package/src/cli/mcp/tools.ts +2 -9
- package/src/cli/mcp/toolset-names.ts +2 -70
- package/src/cli/mcp/toolset-selection.ts +2 -41
- package/src/cli/mcp/toolset.ts +2 -336
- package/src/cli/mcp/transports/AGENTS.md +1 -10
- package/src/cli/mcp/transports/CLAUDE.md +1 -10
- package/src/cli/mcp/transports/http.ts +2 -1414
- package/src/cli/mcp/transports/session-registry.ts +2 -490
- package/src/cli/mcp/transports/stdio.ts +2 -8
- package/src/cli/mcp/types.ts +2 -41
- package/src/cli/mcp/umbrella-tools.ts +2 -117
- package/src/cli/repositories/command-executor.ts +64 -18
- package/src/cli/repositories/command-scope.ts +117 -1
- package/src/cli/repositories/controller-home.ts +119 -1
- package/src/cli/repositories/identity.ts +13 -0
- package/src/cli/repositories/registry.ts +68 -49
- package/src/cli/repositories/repository-snapshot.ts +53 -7
- package/src/cli/repositories/runtime-storage.ts +27 -2
- package/src/cli/repositories/safe-patch.ts +34 -38
- package/src/cli/repositories/selected-path-actions.ts +22 -2
- package/src/cli/repositories/structured-git.ts +105 -25
- package/src/cli/runtime/helper-runner.ts +7 -0
- package/src/cli/runtime-invocation.ts +8 -1
- package/src/cli/tools/codegraph.ts +44 -25
- package/src/core/adoption/manifest-templates.ts +1 -1
- package/src/core/adoption/plan.ts +3 -26
- package/src/core/adoption/workflow-contract-plan.ts +17 -9
- package/src/effects/process-runner.ts +8 -14
- package/src/runtime/context/assistant-context.ts +154 -0
- package/src/runtime/context/assistant-work-context.ts +147 -0
- package/src/runtime/context/codegraph-cache-boundary.ts +255 -0
- package/src/runtime/context/codegraph-read-provider.ts +55 -22
- package/src/runtime/context/codegraph-sidecar.cjs +8 -1
- package/src/runtime/context/context-closure.ts +268 -0
- package/src/runtime/context/context-plane.ts +211 -0
- package/src/runtime/context/project-engineering-contract.ts +60 -0
- package/src/runtime/control-plane/bootstrap/capability-provider.ts +74 -0
- package/src/runtime/control-plane/bootstrap/control-api.ts +57 -0
- package/src/runtime/control-plane/bootstrap/index.ts +5 -0
- package/src/runtime/control-plane/bootstrap/state-machine.ts +141 -0
- package/src/runtime/control-plane/bootstrap/store.ts +21 -0
- package/src/runtime/control-plane/bootstrap/types.ts +87 -0
- package/src/runtime/control-plane/cleanup-artifact-retention.ts +328 -0
- package/src/runtime/control-plane/codegraph-cache-retention.ts +164 -0
- package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +320 -0
- package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +169 -0
- package/src/runtime/control-plane/execution/controller-authority-recovery.ts +350 -0
- package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +85 -0
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +417 -100
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +103 -15
- package/src/runtime/control-plane/execution/implementation-review-content.ts +95 -0
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +2 -2
- package/src/runtime/control-plane/execution/retained-work-resume.ts +336 -6
- package/src/runtime/control-plane/execution/validation.ts +28 -3
- package/src/runtime/control-plane/execution/work-authority-reconciler.ts +116 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +44 -2
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +34 -3
- package/src/runtime/control-plane/execution/work-execution-support.ts +42 -22
- package/src/runtime/control-plane/execution/work-finalization-service.ts +1103 -166
- package/src/runtime/control-plane/execution/work-handle-authority.ts +267 -16
- package/src/runtime/control-plane/execution/work-handle-store.ts +77 -0
- package/src/runtime/control-plane/execution/work-head-settlement.ts +75 -0
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +145 -23
- package/src/runtime/control-plane/execution/work-operation-service.ts +49 -13
- package/src/runtime/control-plane/execution/work-preparation-service.ts +31 -15
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +1 -1
- package/src/runtime/control-plane/execution/work-task-receipt.ts +20 -1
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +407 -76
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +88 -18
- package/src/runtime/control-plane/execution/work-verification-context.ts +1 -1
- package/src/runtime/control-plane/execution/work-verification-service.ts +258 -4
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +200 -15
- package/src/runtime/control-plane/facade/capability-registry.ts +21 -10
- package/src/runtime/control-plane/facade/controller-round-relay.ts +3 -1118
- package/src/runtime/control-plane/facade/controller-session-store.ts +2 -488
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +6 -3
- package/src/runtime/control-plane/facade/goal-workloop.ts +972 -137
- package/src/runtime/control-plane/facade/handoff-inbox-application.ts +158 -0
- package/src/runtime/control-plane/facade/handoff-inbox-store.ts +10 -0
- package/src/runtime/control-plane/facade/index.ts +4 -2
- package/src/runtime/control-plane/facade/operation-digest.ts +22 -58
- package/src/runtime/control-plane/facade/plan-contract-store.ts +1004 -38
- package/src/runtime/control-plane/facade/repository-work-admission.ts +19 -1
- package/src/runtime/control-plane/facade/requirement-authority.ts +218 -0
- package/src/runtime/control-plane/facade/requirement-board.ts +6 -1
- package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +48 -0
- package/src/runtime/control-plane/facade/semantic-admission.ts +8 -16
- package/src/runtime/control-plane/facade/suggested-actions.ts +4 -1
- package/src/runtime/control-plane/facade/types.ts +189 -532
- package/src/runtime/control-plane/facade/work-admission-policy.ts +84 -35
- package/src/runtime/control-plane/facade/work-contract-store.ts +2 -1043
- package/src/runtime/control-plane/facade/work-implementation-review.ts +2 -0
- package/src/runtime/control-plane/facade/work-state-machine.ts +2 -250
- package/src/runtime/control-plane/generated-cache-retention.ts +239 -18
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +12 -1
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +76 -13
- package/src/runtime/control-plane/global-scheduler/periodic-cleanup-entry.ts +55 -0
- package/src/runtime/control-plane/global-scheduler/periodic-cleanup-process.ts +98 -0
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +1 -1
- package/src/runtime/control-plane/global-scheduler/scheduler-worker-entry.ts +10 -0
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +173 -81
- package/src/runtime/control-plane/global-scheduler/worker-launch.ts +18 -6
- package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +397 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +2 -177
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +301 -560
- package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +20 -4
- package/src/runtime/control-plane/launcher/thin-launcher.ts +50 -4
- package/src/runtime/control-plane/lifecycle-retention-metrics.ts +60 -0
- package/src/runtime/control-plane/persistence/experience-store.ts +169 -0
- package/src/runtime/control-plane/persistence/operational-prior-store.ts +348 -0
- package/src/runtime/control-plane/persistence/requirement-store.ts +30 -22
- package/src/runtime/control-plane/persistence/sqlite-store.ts +545 -76
- package/src/runtime/control-plane/persistence/workflow-content-store.ts +98 -0
- package/src/runtime/control-plane/persistence/workflow-registry-store.ts +186 -0
- package/src/runtime/control-plane/persistence/workflow-run-store.ts +123 -0
- package/src/runtime/control-plane/release-retention.ts +56 -16
- package/src/runtime/control-plane/repository-namespace-retention.ts +208 -0
- package/src/runtime/control-plane/routing/route-policy.ts +19 -0
- package/src/runtime/control-plane/runtime-cleanup.ts +574 -37
- package/src/runtime/control-plane/runtime-generation.ts +6 -0
- package/src/runtime/control-plane/workspace/semantic-sync-service.ts +465 -0
- package/src/runtime/control-plane/workspace/workspace-store.ts +80 -0
- package/src/runtime/diagnostics/incident-repair.ts +406 -0
- package/src/runtime/diagnostics/mcp-timing.ts +125 -6
- package/src/runtime/diagnostics/performance.ts +6 -14
- package/src/runtime/diagnostics/read-only-tool.ts +1 -1
- package/src/runtime/evidence/artifact-store.ts +65 -2
- package/src/runtime/evidence/operational-shadow.ts +38 -0
- package/src/runtime/evidence/process-check-receipt.ts +5 -43
- package/src/runtime/evidence/sensitive-output.ts +4 -4
- package/src/runtime/execution/jobs/receipt-recovery.ts +1 -1
- package/src/runtime/execution/jobs/store.ts +121 -2
- package/src/runtime/execution/managed-workspace.ts +55 -5
- package/src/runtime/execution/process-runtime/canary.ts +19 -5
- package/src/runtime/execution/process-runtime/check-classification.ts +48 -0
- package/src/runtime/execution/process-runtime/check-facade.ts +23 -9
- package/src/runtime/execution/process-runtime/check-receipt.ts +1 -1
- package/src/runtime/execution/process-runtime/check-result-retention.ts +132 -0
- package/src/runtime/execution/process-runtime/check-result.ts +73 -2
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +42 -3
- package/src/runtime/execution/process-runtime/check-storage.ts +187 -0
- package/src/runtime/execution/process-runtime/command-facade.ts +38 -87
- package/src/runtime/execution/process-runtime/index.ts +1 -0
- package/src/runtime/execution/process-runtime/interactive-admission.ts +2 -1
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +32 -1
- package/src/runtime/execution/process-runtime/persisted-check.ts +128 -21
- package/src/runtime/execution/process-runtime/resource-claims.ts +60 -3
- package/src/runtime/execution/process-runtime/runtime.ts +132 -15
- package/src/runtime/execution/process-runtime/types.ts +22 -0
- package/src/runtime/execution/workers/executor.ts +16 -13
- package/src/runtime/execution/workers/worker-entry.ts +1 -1
- package/src/runtime/gateway/mcp/execution-tools.ts +2 -207
- package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +2 -61
- package/src/runtime/gateway/mcp/persisted-check-process.ts +2 -3
- package/src/runtime/gateway/mcp/process-tools.ts +2 -289
- package/src/runtime/gateway/mcp/router.ts +2 -1125
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +2 -565
- package/src/runtime/gateway/mcp/runtime-tools.ts +2 -6651
- package/src/runtime/gateway/mcp/work-validation-reconciler.ts +2 -1
- package/src/runtime/maintenance/cleanup.ts +38 -24
- package/src/runtime/platform/browser-product-discovery.ts +174 -0
- package/src/runtime/platform/computer-platform.ts +14 -0
- package/src/runtime/platform/executable-discovery.ts +54 -0
- package/src/runtime/platform/fetch-http-server.ts +90 -0
- package/src/runtime/platform/service-manager.ts +138 -0
- package/src/runtime/platform/windows-host-discovery.ts +118 -0
- package/src/runtime/platform/windows-recovery-deployment.ts +67 -0
- package/src/runtime/plugins/action-application.ts +135 -0
- package/src/runtime/plugins/app-store-connect-adapter.ts +9 -21
- package/src/runtime/plugins/browser-adapter.ts +140 -100
- package/src/runtime/plugins/browser-automation-service.ts +15 -36
- package/src/runtime/plugins/browser-macos-bridge.ts +69 -21
- package/src/runtime/plugins/browser-manifest-surface.ts +30 -6
- package/src/runtime/plugins/browser-native-session-service.ts +1 -1
- package/src/runtime/plugins/browser-provider-registry.ts +2 -109
- package/src/runtime/plugins/browser-registration.ts +16 -0
- package/src/runtime/plugins/browser-runtime-contract.ts +2 -154
- package/src/runtime/plugins/browser-runtime.ts +41 -9
- package/src/runtime/plugins/browser-session-authority.ts +101 -291
- package/src/runtime/plugins/browser-session-legacy-migration.ts +203 -0
- package/src/runtime/plugins/browser-session-store.ts +229 -36
- package/src/runtime/plugins/browser-session-types.ts +2 -98
- package/src/runtime/plugins/capability-authorization-grants.ts +17 -0
- package/src/runtime/plugins/catalog-trust.ts +82 -0
- package/src/runtime/plugins/computer-registration.ts +839 -0
- package/src/runtime/plugins/config-store.ts +119 -0
- package/src/runtime/plugins/desktop-operator-external-policy.ts +932 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +111 -8
- package/src/runtime/plugins/errors.ts +8 -1
- package/src/runtime/plugins/external-adapter.ts +45 -322
- package/src/runtime/plugins/external-provider-policy.ts +48 -0
- package/src/runtime/plugins/external-registration.ts +9 -1
- package/src/runtime/plugins/external-unix-socket-probe.cjs +9 -3
- package/src/runtime/plugins/external-unix-socket.ts +64 -193
- package/src/runtime/plugins/first-party-external-registration.ts +163 -0
- package/src/runtime/plugins/first-party-registry.ts +3 -1
- package/src/runtime/plugins/github-adapter.ts +1 -2
- package/src/runtime/plugins/gmail-adapter.ts +6 -6
- package/src/runtime/plugins/google-calendar-adapter.ts +6 -6
- package/src/runtime/plugins/google-shared.ts +31 -46
- package/src/runtime/plugins/google-tasks-adapter.ts +6 -6
- package/src/runtime/plugins/ios-adapter.ts +1 -2
- package/src/runtime/plugins/local-system-adapter.ts +180 -0
- package/src/runtime/plugins/macos-capability-broker.ts +15 -105
- package/src/runtime/plugins/resend-adapter.ts +15 -24
- package/src/runtime/plugins/store.ts +493 -51
- package/src/runtime/plugins/types.ts +8 -1
- package/src/runtime/plugins/uu-remote-rescue-registration.ts +155 -0
- package/src/runtime/plugins/windows-host-recovery-install.ts +68 -0
- package/src/runtime/plugins/windows-host-recovery-registration.ts +85 -0
- package/src/runtime/plugins/xiaohongshu-publish.ts +86 -430
- package/src/runtime/projections/controller-context.ts +12 -6
- package/src/runtime/projections/git-status-sampler.ts +73 -22
- package/src/runtime/projections/materialized-view.ts +14 -8
- package/src/runtime/recovery/capability-action-application.ts +228 -0
- package/src/runtime/recovery/index.ts +3 -0
- package/src/runtime/recovery/lifecycle-inventory.ts +338 -0
- package/src/runtime/recovery/local-jobs-repair.ts +14 -14
- package/src/runtime/recovery/maintenance-executor.ts +358 -76
- package/src/runtime/recovery/quarantine-retention.ts +256 -0
- package/src/runtime/release/identity.ts +6 -0
- package/src/runtime/resources/leases/store.ts +1 -1
- package/src/runtime/root/active-execution-power-assertion.ts +139 -0
- package/src/runtime/root/assistant-learning-loop.ts +45 -0
- package/src/runtime/root/browser-session-composition.ts +59 -0
- package/src/runtime/root/computer-composition.ts +191 -0
- package/src/runtime/root/computer-target-composition.ts +16 -0
- package/src/runtime/root/computer-target-persistence.ts +39 -0
- package/src/runtime/root/controller-round-composition.ts +107 -0
- package/src/runtime/root/controller-services.ts +2 -0
- package/src/runtime/root/entry.ts +4 -3
- package/src/runtime/root/gateway-adapter.ts +3 -3
- package/src/runtime/root/local-bridge.ts +5 -2
- package/src/runtime/root/mcp-transport.ts +5 -5
- package/src/runtime/root/package-connector-service.ts +108 -56
- package/src/runtime/root/package-runtime-release.ts +86 -18
- package/src/runtime/root/package-runtime-service.ts +63 -86
- package/src/runtime/root/release-execution-canary.ts +71 -0
- package/src/runtime/root/release-loader.ts +68 -0
- package/src/runtime/root/release-manifest.ts +106 -2
- package/src/runtime/root/release-materialize.ts +103 -4
- package/src/runtime/root/release-store.ts +31 -2
- package/src/runtime/root/runtime.ts +240 -25
- package/src/runtime/root/scheduled-controller-composition.ts +51 -0
- package/src/runtime/root/scheduler.ts +12 -4
- package/src/runtime/root/service-runner.ts +1 -1
- package/src/runtime/root/service.ts +41 -16
- package/src/runtime/root/status.ts +1 -0
- package/src/runtime/root/types.ts +24 -1
- package/src/runtime/shared/local-bridge-surface.ts +1 -1
- package/src/runtime/shared/process-environment.ts +19 -4
- package/src/runtime/shared/storage-capacity.ts +68 -0
- package/src/runtime/standalone-recovery/controller-home-migration.ts +1116 -0
- package/src/runtime/standalone-recovery/core.ts +984 -230
- package/src/runtime/standalone-recovery/entry.ts +182 -51
- package/src/runtime/standalone-recovery/independent-host-rescue.ts +172 -0
- package/src/runtime/standalone-recovery/installer.ts +212 -104
- package/src/runtime/standalone-recovery/mcp-server.ts +243 -0
- package/src/runtime/standalone-recovery/mutation-identity-contract.ts +21 -0
- package/src/runtime/standalone-recovery/operation-lock.ts +160 -0
- package/src/runtime/standalone-recovery/performance.ts +135 -0
- package/src/runtime/standalone-recovery/release.ts +5 -0
- package/src/runtime/watchdog/workflow-watchdog.ts +1 -1
- package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +1 -1
- package/src/runtime/workflow/schedules/engine.ts +191 -343
- package/src/runtime/workflow/schedules/pending-activation.ts +1 -1
- package/src/runtime/workflow/schedules/settlement.ts +2 -191
- package/src/runtime/workflow/schedules/store.ts +2 -607
- package/src/runtime/workflow/schedules/types.ts +2 -127
- package/src/runtime/workflow/schedules/work-continuation.ts +180 -15
- package/src/runtime/workflows/first-party/xiaohongshu.ts +122 -0
- package/src/runtime/workflows/runtime.ts +486 -0
- package/src/testing/test-governance.ts +90 -29
- package/assets/templates/helpers/archive-architecture-request.sh +0 -244
- package/docs/architecture/history/README.md +0 -7
- package/docs/architecture/history/chatgpt-handoff-facade.md +0 -397
- package/docs/architecture/history/global-hook-runtime.md +0 -166
- package/docs/architecture/history/ios-semantic-automation-provider-v2.md +0 -170
- package/docs/architecture/requests/archive/2026/20260528-154740-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-154816-assets-hooks-assets-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-161851-ai-harness-workflow-contract-json-ai-harness-workflow-contract-json.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-161853-scripts-check-task-workflow-sh-scripts-check-task-workflow-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-161911-assets-workflow-contract-v1-json-assets-workflow-contract-v1-json.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222416-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222444-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222457-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222648-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222705-ai-hooks-ai-hooks-worktree-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222726-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222727-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-224736-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233259-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233335-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233456-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233457-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233637-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233638-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260529-000322-root-package-json.md +0 -59
- package/docs/architecture/requests/archive/2026/20260529-004238-ai-hooks-ai-hooks-lib-workflow-state-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260529-020654-ai-harness-policy-json-ai-harness-policy-json.md +0 -63
- package/docs/architecture/requests/archive/2026/20260529-094236-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094323-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094331-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094339-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094430-assets-hooks-assets-hooks-session-start-context-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094446-ai-hooks-ai-hooks-session-start-context-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260613-002040-runtime-harness-hook-adapters.md +0 -68
- package/docs/architecture/requests/archive/2026/root.md +0 -68
- package/docs/architecture/requests/archive/2026/runtime-harness-hook-adapters.md +0 -76
- package/docs/architecture/requests/archive/2026/verification-evals-checks.md +0 -68
- package/docs/architecture/requests/archive/2026/workflow-engine-contract-assets.md +0 -69
- package/scripts/archive-architecture-request.sh +0 -4
- package/scripts/run-skill-evals.ts +0 -1022
|
@@ -0,0 +1,791 @@
|
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
import { spawnSync } from "child_process";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
4
|
+
import { isIP } from "net";
|
|
5
|
+
import { homedir } from "os";
|
|
6
|
+
import { dirname, join, relative, resolve } from "path";
|
|
7
|
+
import {
|
|
8
|
+
ensureMcpControllerHomeBearerToken,
|
|
9
|
+
ensureMcpControllerHomeOAuthPassphrase,
|
|
10
|
+
loadMcpServiceLocalConfig,
|
|
11
|
+
loadMcpServiceRuntimeState,
|
|
12
|
+
mcpControllerHomeLocalConfigPath,
|
|
13
|
+
mcpControllerHomeOAuthPath,
|
|
14
|
+
mcpControllerHomeRuntimeStatePath,
|
|
15
|
+
mcpControllerHomeTokenPath,
|
|
16
|
+
mcpOAuthPath,
|
|
17
|
+
mcpRuntimeStatePath,
|
|
18
|
+
mcpTokenPath,
|
|
19
|
+
} from "./auth";
|
|
20
|
+
import { resolveMcpRepoRoot } from "./repo";
|
|
21
|
+
import {
|
|
22
|
+
FORGE_TOOL_SURFACE,
|
|
23
|
+
DEFAULT_AGENT_TIMEOUT_MS,
|
|
24
|
+
MAX_AGENT_TIMEOUT_MS,
|
|
25
|
+
} from "../../src/cli/controller/runtime-config";
|
|
26
|
+
import { ensureControllerHome, ensureRepoPreferredControllerHome } from "../../src/cli/repositories/controller-home";
|
|
27
|
+
import { accessModeForLegacyToolset } from "./access-mode";
|
|
28
|
+
import { migrateControllerToolsetConfig } from "./toolset-selection";
|
|
29
|
+
import { ensureForgeInstanceIdentity, normalizeConfiguredForgeInstanceId, readForgeInstanceIdentity } from "../../packages/kernel/identity/api/index";
|
|
30
|
+
import { discoverExecutable } from "../../src/runtime/platform/executable-discovery";
|
|
31
|
+
|
|
32
|
+
export interface McpSetupResult {
|
|
33
|
+
status: "ok";
|
|
34
|
+
repoRoot: string;
|
|
35
|
+
changed: string[];
|
|
36
|
+
forgeInstanceId?: string;
|
|
37
|
+
lines: string[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const REQUIRED_CODEX_TOOLS = [
|
|
41
|
+
"harness_status",
|
|
42
|
+
"read_workflow_file",
|
|
43
|
+
"latest_session_context",
|
|
44
|
+
"latest_checks",
|
|
45
|
+
"prepare_codex_goal_from_sprint",
|
|
46
|
+
"write_codex_goal",
|
|
47
|
+
"run_workflow_check",
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
const CHATGPT_MCP_ENDPOINT_PLACEHOLDER = "<https-tunnel-url>/mcp";
|
|
51
|
+
const CHATGPT_NAMED_TUNNEL_HOST_PLACEHOLDER = "<named-tunnel-host>";
|
|
52
|
+
const LEGACY_CHATGPT_MCP_SERVER_NAME = "forge";
|
|
53
|
+
const LEGACY_DEFAULT_SERVER_NAMES = new Set([
|
|
54
|
+
LEGACY_CHATGPT_MCP_SERVER_NAME,
|
|
55
|
+
"forge-controller-v1",
|
|
56
|
+
"forge-controller-v2",
|
|
57
|
+
"forge-controller-v3",
|
|
58
|
+
"forge-controller-v4",
|
|
59
|
+
"forge-controller-v5",
|
|
60
|
+
"forge-controller-v6",
|
|
61
|
+
]);
|
|
62
|
+
const ENDPOINT_ERROR =
|
|
63
|
+
"expected a public HTTPS URL exactly ending in /mcp with no username, password, query, or fragment";
|
|
64
|
+
const SERVER_NAME_ERROR =
|
|
65
|
+
"expected a ChatGPT MCP server name using 1-80 letters, numbers, spaces, dots, underscores, or hyphens";
|
|
66
|
+
|
|
67
|
+
function writeFileIfChanged(
|
|
68
|
+
path: string,
|
|
69
|
+
content: string,
|
|
70
|
+
changed: string[],
|
|
71
|
+
): void {
|
|
72
|
+
if (existsSync(path) && readFileSync(path, "utf-8") === content) return;
|
|
73
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
74
|
+
writeFileSync(path, content, "utf-8");
|
|
75
|
+
changed.push(path);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function ensureGitignoreEntries(
|
|
79
|
+
repoRoot: string,
|
|
80
|
+
entries: string[],
|
|
81
|
+
changed: string[],
|
|
82
|
+
): void {
|
|
83
|
+
const path = join(repoRoot, ".gitignore");
|
|
84
|
+
const current = existsSync(path) ? readFileSync(path, "utf-8") : "";
|
|
85
|
+
const lines = current.split(/\r?\n/);
|
|
86
|
+
let next = current.trimEnd();
|
|
87
|
+
for (const entry of entries) {
|
|
88
|
+
if (lines.includes(entry)) continue;
|
|
89
|
+
next += `${next.length > 0 ? "\n" : ""}${entry}`;
|
|
90
|
+
}
|
|
91
|
+
next += "\n";
|
|
92
|
+
writeFileIfChanged(path, next, changed);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function isPrivateOrLocalIPv4(hostname: string): boolean {
|
|
96
|
+
const parts = hostname.split(".").map((part) => Number(part));
|
|
97
|
+
if (
|
|
98
|
+
parts.length !== 4 ||
|
|
99
|
+
parts.some((part) => !Number.isInteger(part) || part < 0 || part > 255)
|
|
100
|
+
)
|
|
101
|
+
return true;
|
|
102
|
+
const [a, b] = parts;
|
|
103
|
+
return (
|
|
104
|
+
a === 0 ||
|
|
105
|
+
a === 10 ||
|
|
106
|
+
a === 127 ||
|
|
107
|
+
(a === 169 && b === 254) ||
|
|
108
|
+
(a === 172 && b >= 16 && b <= 31) ||
|
|
109
|
+
(a === 192 && b === 168) ||
|
|
110
|
+
(a === 100 && b >= 64 && b <= 127) ||
|
|
111
|
+
(a === 192 && b === 0) ||
|
|
112
|
+
(a === 198 && (b === 18 || b === 19)) ||
|
|
113
|
+
a >= 224
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function isPrivateOrLocalIPv6(hostname: string): boolean {
|
|
118
|
+
const normalized = hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
119
|
+
return (
|
|
120
|
+
normalized === "::" ||
|
|
121
|
+
normalized === "::1" ||
|
|
122
|
+
normalized.startsWith("fc") ||
|
|
123
|
+
normalized.startsWith("fd") ||
|
|
124
|
+
normalized.startsWith("fe8") ||
|
|
125
|
+
normalized.startsWith("fe9") ||
|
|
126
|
+
normalized.startsWith("fea") ||
|
|
127
|
+
normalized.startsWith("feb")
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function isPrivateOrLocalHost(hostname: string): boolean {
|
|
132
|
+
const normalized = hostname.toLowerCase().replace(/\.$/, "");
|
|
133
|
+
if (
|
|
134
|
+
!normalized ||
|
|
135
|
+
normalized === "localhost" ||
|
|
136
|
+
normalized.endsWith(".localhost") ||
|
|
137
|
+
normalized.endsWith(".local")
|
|
138
|
+
) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
const ipCandidate = normalized.replace(/^\[|\]$/g, "");
|
|
142
|
+
const ipVersion = isIP(ipCandidate);
|
|
143
|
+
if (ipVersion === 4) return isPrivateOrLocalIPv4(ipCandidate);
|
|
144
|
+
if (ipVersion === 6) return isPrivateOrLocalIPv6(ipCandidate);
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function normalizePublicMcpEndpoint(
|
|
149
|
+
endpoint: string | undefined,
|
|
150
|
+
): string | undefined {
|
|
151
|
+
if (endpoint === undefined) return undefined;
|
|
152
|
+
const trimmed = endpoint.trim();
|
|
153
|
+
if (trimmed.length === 0) return undefined;
|
|
154
|
+
let parsed: URL;
|
|
155
|
+
try {
|
|
156
|
+
parsed = new URL(trimmed);
|
|
157
|
+
} catch (_error) {
|
|
158
|
+
throw new Error(`invalid --endpoint "${endpoint}" (${ENDPOINT_ERROR})`);
|
|
159
|
+
}
|
|
160
|
+
if (
|
|
161
|
+
parsed.protocol !== "https:" ||
|
|
162
|
+
parsed.pathname !== "/mcp" ||
|
|
163
|
+
parsed.username !== "" ||
|
|
164
|
+
parsed.password !== "" ||
|
|
165
|
+
parsed.search !== "" ||
|
|
166
|
+
parsed.hash !== "" ||
|
|
167
|
+
isPrivateOrLocalHost(parsed.hostname)
|
|
168
|
+
) {
|
|
169
|
+
throw new Error(`invalid --endpoint "${endpoint}" (${ENDPOINT_ERROR})`);
|
|
170
|
+
}
|
|
171
|
+
return parsed.toString();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function defaultChatgptMcpServerName(forgeInstanceId: string): string {
|
|
175
|
+
const semanticInstanceId = forgeInstanceId.trim();
|
|
176
|
+
if (!semanticInstanceId) throw new Error('FORGE_INSTANCE_ID_REQUIRED');
|
|
177
|
+
const normalized = semanticInstanceId.toLowerCase();
|
|
178
|
+
const withoutForgePrefix = normalized.replace(/^forge[-_.:]/, '');
|
|
179
|
+
const stableToken = (withoutForgePrefix || normalized)
|
|
180
|
+
.replace(/[^a-z0-9._-]+/g, '-')
|
|
181
|
+
.replace(/^-+|-+$/g, '');
|
|
182
|
+
const token = stableToken || createHash('sha256').update(semanticInstanceId).digest('hex').slice(0, 12);
|
|
183
|
+
const candidate = `forge-${token}`;
|
|
184
|
+
if (candidate.length <= 80) return candidate;
|
|
185
|
+
return `${candidate.slice(0, 80 - 13)}-${createHash('sha256').update(semanticInstanceId).digest('hex').slice(0, 12)}`;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function normalizeChatgptMcpServerName(value: string | undefined): string {
|
|
189
|
+
const trimmed = (value ?? LEGACY_CHATGPT_MCP_SERVER_NAME).trim();
|
|
190
|
+
if (
|
|
191
|
+
trimmed.length < 1 ||
|
|
192
|
+
trimmed.length > 80 ||
|
|
193
|
+
!/^[A-Za-z0-9][A-Za-z0-9._ -]*$/.test(trimmed) ||
|
|
194
|
+
/ {2,}/.test(trimmed)
|
|
195
|
+
) {
|
|
196
|
+
throw new Error(
|
|
197
|
+
`invalid --server-name "${value ?? ""}" (${SERVER_NAME_ERROR})`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
return trimmed;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function chatgptGuideMarkdown(
|
|
204
|
+
endpoint = CHATGPT_MCP_ENDPOINT_PLACEHOLDER,
|
|
205
|
+
): string {
|
|
206
|
+
return `# Forge ChatGPT Controller — Low-level Reference
|
|
207
|
+
|
|
208
|
+
> For normal onboarding, start with \`forge setup\` and [Tutorial 2](tutorials/02-connect-chatgpt.md). This file is the lower-level MCP reference and may also be regenerated by repository-scoped compatibility setup.
|
|
209
|
+
|
|
210
|
+
## Product model
|
|
211
|
+
|
|
212
|
+
Forge has no internal AI brain. ChatGPT is one external controller option: ChatGPT decides semantic next steps, while Forge owns bounded execution, durable state, authorization, Runtime lifecycle, and evidence. Codex/Claude are optional and are not enabled merely because they are installed.
|
|
213
|
+
|
|
214
|
+
## Normal package path
|
|
215
|
+
|
|
216
|
+
A repository is not required for the user-level ChatGPT connection:
|
|
217
|
+
|
|
218
|
+
\`\`\`bash
|
|
219
|
+
forge setup configure --controller chatgpt --tunnel auto
|
|
220
|
+
forge setup next
|
|
221
|
+
\`\`\`
|
|
222
|
+
|
|
223
|
+
The corresponding low-level commands are:
|
|
224
|
+
|
|
225
|
+
\`\`\`bash
|
|
226
|
+
forge mcp setup chatgpt --user-level --connector-auth none --clear-endpoint
|
|
227
|
+
forge runtime service install-package
|
|
228
|
+
forge runtime status --json
|
|
229
|
+
\`\`\`
|
|
230
|
+
|
|
231
|
+
The Package Runtime does not require a Forge Git checkout, Bun compilation, CodeGraph, or Standalone Recovery. The older \`forge runtime service install --repo ...\` command is an advanced source/immutable-release path.
|
|
232
|
+
|
|
233
|
+
## Local boundaries
|
|
234
|
+
|
|
235
|
+
The bearer-only Canonical Runtime remains loopback-only, normally at:
|
|
236
|
+
|
|
237
|
+
\`\`\`text
|
|
238
|
+
http://127.0.0.1:8765/mcp
|
|
239
|
+
\`\`\`
|
|
240
|
+
|
|
241
|
+
ChatGPT uses a separate loopback Connector (normally \`127.0.0.1:8767/mcp\`). With OpenAI Secure MCP Tunnel the Connector uses tunnel/workspace authority (\`auth=none\` locally) and must remain loopback-only. Public HTTPS providers expose this Connector with OAuth; they must never expose the bearer-only Runtime directly.
|
|
242
|
+
|
|
243
|
+
The local Utility Console uses a separate loopback port (normally 8766). Never expose the Utility Console to the internet.
|
|
244
|
+
|
|
245
|
+
Service-level MCP configuration lives below \`Controller Home/mcp/\`. OAuth credentials and bearer fallback tokens are local secrets and must not be pasted into chat or committed. Repository-specific \`.forge/mcp.policy.json\` can narrow access when a repository is later adopted.
|
|
246
|
+
|
|
247
|
+
## Remote controller connection
|
|
248
|
+
|
|
249
|
+
The setup profile owns the connection choice. Supported paths are:
|
|
250
|
+
|
|
251
|
+
1. **OpenAI Secure MCP Tunnel** — preferred when the OpenAI organization/workspace has tunnel permission; no public inbound Forge endpoint is required. Forge stores only the non-secret \`tunnel_id\`. The runtime API key remains an \`env:\`/file reference owned by the official \`tunnel-client\`.
|
|
252
|
+
2. **Cloudflare Tunnel** — stable public/internet-reachable HTTPS endpoint.
|
|
253
|
+
3. **Tailscale Funnel** — HTTPS endpoint for compatible Tailscale environments.
|
|
254
|
+
4. **Existing HTTPS** — user-managed reverse proxy/tunnel ending in \`/mcp\`.
|
|
255
|
+
5. **None** — local setup only; remote connectivity can be configured later.
|
|
256
|
+
|
|
257
|
+
For OpenAI Secure MCP Tunnel, setup uses the official supervised runtime surface and considers it ready only when the local Connector is configured for Secure Tunnel authority and \`tunnel-client runtimes status forge --json\` reports the runtime running, healthy, and ready. The loopback Connector is not a browser-facing OAuth authorization server.
|
|
258
|
+
|
|
259
|
+
For public HTTPS paths, the configured connector URL is:
|
|
260
|
+
|
|
261
|
+
\`\`\`text
|
|
262
|
+
${endpoint}
|
|
263
|
+
\`\`\`
|
|
264
|
+
|
|
265
|
+
Record a stable endpoint with:
|
|
266
|
+
|
|
267
|
+
\`\`\`bash
|
|
268
|
+
forge setup configure --controller chatgpt --tunnel existing --endpoint https://forge.example.com/mcp
|
|
269
|
+
\`\`\`
|
|
270
|
+
|
|
271
|
+
Forge synchronizes an explicitly recorded endpoint into the user-level ChatGPT MCP configuration. A configured URL is not proof of live end-to-end connectivity; verify from ChatGPT with a real tool call.
|
|
272
|
+
|
|
273
|
+
## ChatGPT-side setup
|
|
274
|
+
|
|
275
|
+
ChatGPT developer-mode/MCP availability is controlled by the current ChatGPT plan and workspace policy. Follow OpenAI's current developer-mode documentation; Forge cannot bypass plan, administrator, RBAC, or tool-action restrictions.
|
|
276
|
+
|
|
277
|
+
- With **Secure MCP Tunnel**, create the ChatGPT app/connector using the Tunnel connection and the tunnel ID.
|
|
278
|
+
- With **HTTPS**, use the stable URL ending in \`/mcp\` and Forge's OAuth flow.
|
|
279
|
+
- Refresh/scan tools after Forge tool definitions change.
|
|
280
|
+
|
|
281
|
+
The bounded default surface intentionally exposes the preferred \`rh_*\` facade plus repository/source/check/process/plugin escape hatches. Do not switch to exhaustive compatibility mode merely to see more tool names.
|
|
282
|
+
|
|
283
|
+
## Verify
|
|
284
|
+
|
|
285
|
+
Local Runtime:
|
|
286
|
+
|
|
287
|
+
\`\`\`bash
|
|
288
|
+
forge runtime status --json
|
|
289
|
+
forge mcp doctor
|
|
290
|
+
\`\`\`
|
|
291
|
+
|
|
292
|
+
Then verify from the selected external controller:
|
|
293
|
+
|
|
294
|
+
\`\`\`text
|
|
295
|
+
Use Forge. Call rh_status and report whether the Runtime is ready. Do not modify anything yet.
|
|
296
|
+
\`\`\`
|
|
297
|
+
|
|
298
|
+
A successful controller-to-Forge tool call is the meaningful end-to-end setup milestone.
|
|
299
|
+
|
|
300
|
+
## Optional controller entries
|
|
301
|
+
|
|
302
|
+
Codex and Claude are configured only when explicitly selected:
|
|
303
|
+
|
|
304
|
+
\`\`\`bash
|
|
305
|
+
forge mcp setup codex --scope user --profile controller
|
|
306
|
+
forge mcp setup claude --scope user --profile controller
|
|
307
|
+
\`\`\`
|
|
308
|
+
|
|
309
|
+
Multiple controller entries may coexist, while one external controller remains the semantic owner at a time.
|
|
310
|
+
|
|
311
|
+
## Advanced source/Recovery path
|
|
312
|
+
|
|
313
|
+
Maintainers who intentionally need immutable Git/source releases and independent disaster recovery may use the source Runtime and Standalone Recovery documentation. Those mechanisms are not required by ordinary npm/package users and are deliberately excluded from normal setup.
|
|
314
|
+
`;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export function runMcpSetupChatgpt(opts: {
|
|
318
|
+
repo?: string;
|
|
319
|
+
controllerHome?: string;
|
|
320
|
+
userLevel?: boolean;
|
|
321
|
+
host?: string;
|
|
322
|
+
port?: string;
|
|
323
|
+
endpoint?: string;
|
|
324
|
+
serverName?: string;
|
|
325
|
+
instanceId?: string;
|
|
326
|
+
localControllerPort?: string;
|
|
327
|
+
connectorPort?: string;
|
|
328
|
+
connectorAuthMode?: string;
|
|
329
|
+
clearEndpoint?: boolean;
|
|
330
|
+
}): McpSetupResult {
|
|
331
|
+
const repoRoot = resolveMcpRepoRoot(opts.repo ?? ".");
|
|
332
|
+
const controllerHome = opts.userLevel
|
|
333
|
+
? ensureControllerHome(opts.controllerHome)
|
|
334
|
+
: ensureRepoPreferredControllerHome(repoRoot, opts.controllerHome);
|
|
335
|
+
const changed: string[] = [];
|
|
336
|
+
const configuredInstanceId = opts.instanceId !== undefined
|
|
337
|
+
? normalizeConfiguredForgeInstanceId(opts.instanceId)
|
|
338
|
+
: process.env.FORGE_INSTANCE_ID?.trim();
|
|
339
|
+
const forgeInstance = ensureForgeInstanceIdentity({
|
|
340
|
+
controllerHome,
|
|
341
|
+
preferredInstanceId: configuredInstanceId,
|
|
342
|
+
});
|
|
343
|
+
const existingConfig = loadMcpServiceLocalConfig(controllerHome, repoRoot);
|
|
344
|
+
const configuredForgeInstanceId = existingConfig?.identity?.forgeInstanceId?.trim();
|
|
345
|
+
if (configuredForgeInstanceId && configuredForgeInstanceId !== forgeInstance.instanceId) {
|
|
346
|
+
throw new Error(`MCP_FORGE_INSTANCE_ID_MISMATCH: config=${configuredForgeInstanceId} kernel=${forgeInstance.instanceId}`);
|
|
347
|
+
}
|
|
348
|
+
const host = opts.host ?? existingConfig?.server?.host ?? "127.0.0.1";
|
|
349
|
+
const port = opts.port ?? String(existingConfig?.server?.port ?? 8765);
|
|
350
|
+
const parsedPort = Number(port);
|
|
351
|
+
if (!Number.isInteger(parsedPort) || parsedPort < 1 || parsedPort > 65_535) throw new Error(`forge mcp setup chatgpt: invalid port ${port}`);
|
|
352
|
+
const localControllerPort = opts.localControllerPort !== undefined
|
|
353
|
+
? Number(opts.localControllerPort)
|
|
354
|
+
: existingConfig?.localController?.port ?? (parsedPort < 65_535 ? parsedPort + 1 : 8766);
|
|
355
|
+
if (!Number.isInteger(localControllerPort) || localControllerPort < 1 || localControllerPort > 65_535) throw new Error(`forge mcp setup chatgpt: invalid Local Controller port ${opts.localControllerPort}`);
|
|
356
|
+
if (localControllerPort === parsedPort) throw new Error('forge mcp setup chatgpt: Local Controller port must differ from MCP port');
|
|
357
|
+
const connectorPort = opts.connectorPort !== undefined
|
|
358
|
+
? Number(opts.connectorPort)
|
|
359
|
+
: parsedPort <= 65_533 ? parsedPort + 2 : 8767;
|
|
360
|
+
if (!Number.isInteger(connectorPort) || connectorPort < 1 || connectorPort > 65_535) throw new Error(`forge mcp setup chatgpt: invalid connector port ${opts.connectorPort}`);
|
|
361
|
+
if (connectorPort === parsedPort || connectorPort === localControllerPort) throw new Error('forge mcp setup chatgpt: connector port must differ from Runtime and Local Controller ports');
|
|
362
|
+
const existingServerName = existingConfig?.chatgpt?.serverName;
|
|
363
|
+
const migratedServerName =
|
|
364
|
+
existingServerName && !LEGACY_DEFAULT_SERVER_NAMES.has(existingServerName)
|
|
365
|
+
? existingServerName
|
|
366
|
+
: undefined;
|
|
367
|
+
const defaultServerName = defaultChatgptMcpServerName(forgeInstance.instanceId);
|
|
368
|
+
const serverName = normalizeChatgptMcpServerName(
|
|
369
|
+
opts.serverName ?? migratedServerName ?? defaultServerName,
|
|
370
|
+
);
|
|
371
|
+
const connectorAuthMode = opts.connectorAuthMode?.trim().toLowerCase();
|
|
372
|
+
if (connectorAuthMode !== undefined && connectorAuthMode !== "oauth" && connectorAuthMode !== "none") {
|
|
373
|
+
throw new Error(`forge mcp setup chatgpt: invalid connector auth "${opts.connectorAuthMode}" (expected: oauth, none)`);
|
|
374
|
+
}
|
|
375
|
+
const endpoint = opts.clearEndpoint === true
|
|
376
|
+
? undefined
|
|
377
|
+
: normalizePublicMcpEndpoint(opts.endpoint ?? existingConfig?.chatgpt?.endpoint);
|
|
378
|
+
const existingChatgpt = { ...(existingConfig?.chatgpt ?? {}) };
|
|
379
|
+
if (opts.clearEndpoint === true) delete existingChatgpt.endpoint;
|
|
380
|
+
const configPath = mcpControllerHomeLocalConfigPath(controllerHome);
|
|
381
|
+
const guidePath = opts.userLevel ? undefined : join(repoRoot, "docs", "forge-chatgpt-mcp-setup.md");
|
|
382
|
+
const token = ensureMcpControllerHomeBearerToken(controllerHome);
|
|
383
|
+
const oauth = ensureMcpControllerHomeOAuthPassphrase(controllerHome);
|
|
384
|
+
if (token.changed) changed.push(token.path);
|
|
385
|
+
if (oauth.changed) changed.push(oauth.path);
|
|
386
|
+
const migratedToolset = migrateControllerToolsetConfig(existingConfig);
|
|
387
|
+
const toolset = migratedToolset.toolset;
|
|
388
|
+
const config = {
|
|
389
|
+
version: Math.max(existingConfig?.version ?? 1, 3),
|
|
390
|
+
identity: { forgeInstanceId: forgeInstance.instanceId },
|
|
391
|
+
...(opts.userLevel ? (existingConfig?.repo ? { repo: existingConfig.repo } : {}) : { repo: repoRoot }),
|
|
392
|
+
server: {
|
|
393
|
+
...existingConfig?.server,
|
|
394
|
+
host,
|
|
395
|
+
port: parsedPort,
|
|
396
|
+
transport: existingConfig?.server?.transport ?? "http",
|
|
397
|
+
},
|
|
398
|
+
auth: {
|
|
399
|
+
...existingConfig?.auth,
|
|
400
|
+
mode: connectorAuthMode ?? existingConfig?.auth?.mode ?? "oauth",
|
|
401
|
+
oauthFile: existingConfig?.auth?.oauthFile ?? "mcp/mcp.oauth.json",
|
|
402
|
+
tokenFile: existingConfig?.auth?.tokenFile ?? "mcp/mcp.tokens.json",
|
|
403
|
+
},
|
|
404
|
+
chatgpt: {
|
|
405
|
+
...existingChatgpt,
|
|
406
|
+
serverName,
|
|
407
|
+
...(endpoint ? { endpoint } : {}),
|
|
408
|
+
localEndpoint: `http://127.0.0.1:${connectorPort}/mcp`,
|
|
409
|
+
},
|
|
410
|
+
profile: existingConfig?.profile ?? "controller",
|
|
411
|
+
toolset,
|
|
412
|
+
toolsetExplicit: migratedToolset.toolsetExplicit,
|
|
413
|
+
accessMode: existingConfig?.accessMode
|
|
414
|
+
?? accessModeForLegacyToolset(existingConfig?.toolset ?? toolset),
|
|
415
|
+
accessModeUpdatedAt: existingConfig?.accessModeUpdatedAt,
|
|
416
|
+
accessModeRevision: existingConfig?.accessModeRevision ?? 0,
|
|
417
|
+
localController: opts.userLevel && !existingConfig?.repo
|
|
418
|
+
? {
|
|
419
|
+
enabled: false,
|
|
420
|
+
host: existingConfig?.localController?.host ?? "127.0.0.1",
|
|
421
|
+
port: localControllerPort,
|
|
422
|
+
autoOpen: false,
|
|
423
|
+
mode: "disabled",
|
|
424
|
+
}
|
|
425
|
+
: {
|
|
426
|
+
...(existingConfig?.localController ?? { enabled: true, host: "127.0.0.1", autoOpen: false }),
|
|
427
|
+
port: localControllerPort,
|
|
428
|
+
},
|
|
429
|
+
devMode: {
|
|
430
|
+
...existingConfig?.devMode,
|
|
431
|
+
agentRunner: existingConfig?.devMode?.agentRunner ?? false,
|
|
432
|
+
allowedAgents: existingConfig?.devMode?.allowedAgents ?? [],
|
|
433
|
+
timeoutMs:
|
|
434
|
+
!existingConfig?.devMode?.timeoutMs ||
|
|
435
|
+
existingConfig.devMode.timeoutMs === 120_000
|
|
436
|
+
? DEFAULT_AGENT_TIMEOUT_MS
|
|
437
|
+
: existingConfig.devMode.timeoutMs,
|
|
438
|
+
maxTimeoutMs:
|
|
439
|
+
existingConfig?.devMode?.maxTimeoutMs ?? MAX_AGENT_TIMEOUT_MS,
|
|
440
|
+
},
|
|
441
|
+
};
|
|
442
|
+
writeFileIfChanged(
|
|
443
|
+
configPath,
|
|
444
|
+
`${JSON.stringify(config, null, 2)}\n`,
|
|
445
|
+
changed,
|
|
446
|
+
);
|
|
447
|
+
if (guidePath) {
|
|
448
|
+
writeFileIfChanged(guidePath, chatgptGuideMarkdown(), changed);
|
|
449
|
+
ensureGitignoreEntries(
|
|
450
|
+
repoRoot,
|
|
451
|
+
[
|
|
452
|
+
".forge/mcp.local.json",
|
|
453
|
+
".forge/mcp.tokens.json",
|
|
454
|
+
".forge/mcp.oauth.json",
|
|
455
|
+
".forge/mcp.oauth-tokens.json",
|
|
456
|
+
".forge/mcp.runtime.json",
|
|
457
|
+
".ai/harness/mcp/audit.log",
|
|
458
|
+
".ai/harness/local-jobs/",
|
|
459
|
+
".ai/harness/controller/",
|
|
460
|
+
],
|
|
461
|
+
changed,
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
return {
|
|
466
|
+
status: "ok",
|
|
467
|
+
repoRoot,
|
|
468
|
+
changed,
|
|
469
|
+
forgeInstanceId: forgeInstance.instanceId,
|
|
470
|
+
lines: [
|
|
471
|
+
`[forge mcp] Forge instance: ${forgeInstance.instanceId}`,
|
|
472
|
+
opts.userLevel ? `[forge mcp] Scope: user (${controllerHome})` : `[forge mcp] Repo: ${repoRoot}`,
|
|
473
|
+
"[forge mcp] Profile: controller",
|
|
474
|
+
`[forge mcp] Toolset: ${config.toolset}`,
|
|
475
|
+
`[forge mcp] ChatGPT MCP server name: ${serverName}`,
|
|
476
|
+
`[forge mcp] Internal Runtime endpoint: http://${host}:${port}/mcp`,
|
|
477
|
+
`[forge mcp] ChatGPT local OAuth endpoint: http://127.0.0.1:${connectorPort}/mcp`,
|
|
478
|
+
`[forge mcp] Local Controller: http://${config.localController.host}:${config.localController.port}/`,
|
|
479
|
+
`[forge mcp] Optional external delegation: ${config.devMode.agentRunner ? `enabled (${config.devMode.allowedAgents.join(',') || 'none'})` : 'disabled'}`,
|
|
480
|
+
endpoint
|
|
481
|
+
? `[forge mcp] ChatGPT endpoint: ${endpoint}`
|
|
482
|
+
: "[forge mcp] ChatGPT endpoint: requires stable HTTPS tunnel",
|
|
483
|
+
`[forge mcp] Auth: OAuth passphrase (${relative(repoRoot, oauth.path)})`,
|
|
484
|
+
`[forge mcp] Bearer fallback token: ${relative(repoRoot, token.path)}`,
|
|
485
|
+
`[forge mcp] Config: ${relative(repoRoot, configPath)}`,
|
|
486
|
+
...(guidePath ? [`[forge mcp] Guide: ${relative(repoRoot, guidePath)} (generic; endpoint stays in ignored local config)`] : []),
|
|
487
|
+
`[forge mcp] Runtime state: ${mcpControllerHomeRuntimeStatePath(controllerHome)}`,
|
|
488
|
+
opts.userLevel
|
|
489
|
+
? 'Next: forge setup next'
|
|
490
|
+
: `Next: forge runtime service install-package --controller-home ${controllerHome} --host ${host} --port ${port}`,
|
|
491
|
+
],
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
type LocalControllerProfile = 'controller' | 'executor';
|
|
496
|
+
|
|
497
|
+
function localControllerProfile(value: string | undefined, label: string, fallback: LocalControllerProfile): LocalControllerProfile {
|
|
498
|
+
const normalized = (value ?? fallback).trim().toLowerCase();
|
|
499
|
+
if (normalized !== 'controller' && normalized !== 'executor') {
|
|
500
|
+
throw new Error(`${label}: expected controller|executor`);
|
|
501
|
+
}
|
|
502
|
+
return normalized;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
export function codexMcpBlock(profile: LocalControllerProfile = 'executor'): string {
|
|
506
|
+
const lines = [
|
|
507
|
+
'[mcp_servers.forge]',
|
|
508
|
+
'command = "forge"',
|
|
509
|
+
'args = [',
|
|
510
|
+
' "mcp",',
|
|
511
|
+
' "serve",',
|
|
512
|
+
' "--repo",',
|
|
513
|
+
' ".",',
|
|
514
|
+
' "--transport",',
|
|
515
|
+
' "stdio",',
|
|
516
|
+
' "--profile",',
|
|
517
|
+
` "${profile}"`,
|
|
518
|
+
']',
|
|
519
|
+
];
|
|
520
|
+
if (profile === 'executor') {
|
|
521
|
+
lines.push(
|
|
522
|
+
'enabled_tools = [',
|
|
523
|
+
...REQUIRED_CODEX_TOOLS.map((tool) => ` "${tool}",`),
|
|
524
|
+
']',
|
|
525
|
+
'default_tools_approval_mode = "prompt"',
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
return `${lines.join('\n')}\n`;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
export function patchCodexConfigToml(current: string, profile: LocalControllerProfile = 'executor'): string {
|
|
532
|
+
const block = codexMcpBlock(profile);
|
|
533
|
+
const normalized = current.trimEnd();
|
|
534
|
+
const blockPattern = /\n?\[mcp_servers\.forge\][\s\S]*?(?=\n\[|$)/;
|
|
535
|
+
const prefix = normalized.length > 0 ? `${normalized}\n\n` : '';
|
|
536
|
+
if (!blockPattern.test(normalized)) return `${prefix}${block}`;
|
|
537
|
+
return `${normalized.replace(blockPattern, `\n${block}`.trimEnd())}\n`;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
export function runMcpSetupCodex(opts: {
|
|
541
|
+
repo?: string;
|
|
542
|
+
scope?: string;
|
|
543
|
+
profile?: string;
|
|
544
|
+
dryRun?: boolean;
|
|
545
|
+
}): McpSetupResult {
|
|
546
|
+
const scope = (opts.scope ?? 'project').trim().toLowerCase();
|
|
547
|
+
if (scope !== 'project' && scope !== 'user') {
|
|
548
|
+
throw new Error('forge mcp setup codex --scope: expected project|user');
|
|
549
|
+
}
|
|
550
|
+
const profile = localControllerProfile(opts.profile, 'forge mcp setup codex --profile', 'executor');
|
|
551
|
+
const repoRoot = resolveMcpRepoRoot(opts.repo ?? '.');
|
|
552
|
+
const configPath = scope === 'user' ? join(homedir(), '.codex', 'config.toml') : join(repoRoot, '.codex', 'config.toml');
|
|
553
|
+
const changed: string[] = [];
|
|
554
|
+
const current = existsSync(configPath) ? readFileSync(configPath, 'utf-8') : '';
|
|
555
|
+
const next = patchCodexConfigToml(current, profile);
|
|
556
|
+
if (opts.dryRun === true) {
|
|
557
|
+
return {
|
|
558
|
+
status: 'ok', repoRoot, changed: [],
|
|
559
|
+
lines: [`[forge mcp] Dry run: would patch ${scope === 'user' ? configPath : relative(repoRoot, configPath)}`, next],
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
if (existsSync(configPath) && current !== next) {
|
|
563
|
+
const backupPath = `${configPath}.bak`;
|
|
564
|
+
writeFileIfChanged(backupPath, current, changed);
|
|
565
|
+
}
|
|
566
|
+
writeFileIfChanged(configPath, next, changed);
|
|
567
|
+
return {
|
|
568
|
+
status: 'ok', repoRoot, changed,
|
|
569
|
+
lines: [
|
|
570
|
+
`[forge mcp] Codex config: ${scope === 'user' ? configPath : relative(repoRoot, configPath)}`,
|
|
571
|
+
'[forge mcp] Server: forge',
|
|
572
|
+
'[forge mcp] Transport: stdio',
|
|
573
|
+
`[forge mcp] Role: external ${profile === 'controller' ? 'primary controller' : 'executor/delegate'}`,
|
|
574
|
+
],
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export function claudeMcpSetupCommand(repoRoot: string, profile: LocalControllerProfile = 'controller', scope = 'user'): string[] {
|
|
579
|
+
return [
|
|
580
|
+
'claude', 'mcp', 'add', 'forge', '--scope', scope, '--',
|
|
581
|
+
'forge', 'mcp', 'serve', '--repo', repoRoot, '--transport', 'stdio', '--profile', profile,
|
|
582
|
+
];
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
export function runMcpSetupClaude(opts: {
|
|
586
|
+
repo?: string;
|
|
587
|
+
scope?: string;
|
|
588
|
+
profile?: string;
|
|
589
|
+
dryRun?: boolean;
|
|
590
|
+
}): McpSetupResult {
|
|
591
|
+
const repoRoot = resolveMcpRepoRoot(opts.repo ?? '.');
|
|
592
|
+
const scope = (opts.scope ?? 'user').trim().toLowerCase();
|
|
593
|
+
if (!['local', 'project', 'user'].includes(scope)) {
|
|
594
|
+
throw new Error('forge mcp setup claude --scope: expected local|project|user');
|
|
595
|
+
}
|
|
596
|
+
const profile = localControllerProfile(opts.profile, 'forge mcp setup claude --profile', 'controller');
|
|
597
|
+
const command = claudeMcpSetupCommand(scope === 'user' ? '.' : repoRoot, profile, scope);
|
|
598
|
+
if (opts.dryRun === true) {
|
|
599
|
+
return {
|
|
600
|
+
status: 'ok', repoRoot, changed: [],
|
|
601
|
+
lines: [`[forge mcp] Dry run: ${command.join(' ')}`],
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
const result = spawnSync(command[0], command.slice(1), { cwd: repoRoot, encoding: 'utf8', timeout: 30_000 });
|
|
605
|
+
if (result.error && (result.error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
606
|
+
throw new Error('Claude Code CLI is not installed. Install/authenticate Claude only if you selected it as a Forge controller.');
|
|
607
|
+
}
|
|
608
|
+
if (result.status !== 0) {
|
|
609
|
+
throw new Error(`Claude MCP configuration failed (${result.status ?? 'unknown'}): ${(result.stderr || result.stdout || result.error?.message || '').trim()}`);
|
|
610
|
+
}
|
|
611
|
+
return {
|
|
612
|
+
status: 'ok', repoRoot, changed: [],
|
|
613
|
+
lines: [
|
|
614
|
+
'[forge mcp] Claude Code MCP server configured through the Claude CLI.',
|
|
615
|
+
`[forge mcp] Scope: ${scope}`,
|
|
616
|
+
`[forge mcp] Role: external ${profile === 'controller' ? 'primary controller' : 'executor/delegate'}`,
|
|
617
|
+
'[forge mcp] Verify: claude mcp get forge',
|
|
618
|
+
],
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
export function runMcpPrintGuide(opts: {
|
|
623
|
+
repo?: string;
|
|
624
|
+
endpoint?: string;
|
|
625
|
+
write?: boolean;
|
|
626
|
+
}): McpSetupResult {
|
|
627
|
+
const repoRoot = resolveMcpRepoRoot(opts.repo ?? ".");
|
|
628
|
+
const changed: string[] = [];
|
|
629
|
+
const endpoint = normalizePublicMcpEndpoint(opts.endpoint);
|
|
630
|
+
const content = chatgptGuideMarkdown(
|
|
631
|
+
opts.write === true ? undefined : endpoint,
|
|
632
|
+
);
|
|
633
|
+
if (opts.write === true) {
|
|
634
|
+
writeFileIfChanged(
|
|
635
|
+
join(repoRoot, "docs", "forge-chatgpt-mcp-setup.md"),
|
|
636
|
+
chatgptGuideMarkdown(),
|
|
637
|
+
changed,
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
return {
|
|
641
|
+
status: "ok",
|
|
642
|
+
repoRoot,
|
|
643
|
+
changed,
|
|
644
|
+
lines: [
|
|
645
|
+
content.trimEnd(),
|
|
646
|
+
...(opts.write === true && endpoint
|
|
647
|
+
? [
|
|
648
|
+
"",
|
|
649
|
+
`[forge mcp] ChatGPT endpoint for this session: ${endpoint}`,
|
|
650
|
+
]
|
|
651
|
+
: []),
|
|
652
|
+
],
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
export function runMcpDoctor(opts: {
|
|
657
|
+
repo?: string;
|
|
658
|
+
json?: boolean;
|
|
659
|
+
}): McpSetupResult {
|
|
660
|
+
const repoRoot = resolveMcpRepoRoot(opts.repo ?? ".");
|
|
661
|
+
const controllerHome = ensureRepoPreferredControllerHome(repoRoot);
|
|
662
|
+
const localConfig = loadMcpServiceLocalConfig(controllerHome, repoRoot);
|
|
663
|
+
const runtimeState = loadMcpServiceRuntimeState(controllerHome, repoRoot);
|
|
664
|
+
const configuredServerName = localConfig?.chatgpt?.serverName;
|
|
665
|
+
const forgeInstanceId = localConfig?.identity?.forgeInstanceId?.trim()
|
|
666
|
+
|| readForgeInstanceIdentity(controllerHome)?.instanceId;
|
|
667
|
+
const defaultServerName = forgeInstanceId
|
|
668
|
+
? defaultChatgptMcpServerName(forgeInstanceId)
|
|
669
|
+
: LEGACY_CHATGPT_MCP_SERVER_NAME;
|
|
670
|
+
const serverNameNeedsMigration = Boolean(configuredServerName && LEGACY_DEFAULT_SERVER_NAMES.has(configuredServerName));
|
|
671
|
+
const host = localConfig?.server?.host ?? "127.0.0.1";
|
|
672
|
+
const port = localConfig?.server?.port ?? 8765;
|
|
673
|
+
const authMode = localConfig?.auth?.mode ?? "missing";
|
|
674
|
+
const codexConfigPath = join(repoRoot, ".codex", "config.toml");
|
|
675
|
+
const codexConfig = existsSync(codexConfigPath)
|
|
676
|
+
? readFileSync(codexConfigPath, "utf-8")
|
|
677
|
+
: "";
|
|
678
|
+
const codexHasServer = codexConfig.includes("[mcp_servers.forge]");
|
|
679
|
+
const missingTools = REQUIRED_CODEX_TOOLS.filter(
|
|
680
|
+
(tool) => !codexConfig.includes(`"${tool}"`),
|
|
681
|
+
);
|
|
682
|
+
const codexResolution = discoverExecutable({ id: "codex", candidates: ["codex"] });
|
|
683
|
+
const codexCommand = codexResolution.status === "ready" ? codexResolution.executable : undefined;
|
|
684
|
+
const report = {
|
|
685
|
+
status: existsSync(join(repoRoot, ".ai", "harness", "policy.json"))
|
|
686
|
+
? "ready_local"
|
|
687
|
+
: "not_adopted",
|
|
688
|
+
repo: repoRoot,
|
|
689
|
+
mcp: {
|
|
690
|
+
toolset: migrateControllerToolsetConfig(localConfig).toolset,
|
|
691
|
+
localConfig: existsSync(mcpControllerHomeLocalConfigPath(controllerHome)) || existsSync(
|
|
692
|
+
join(repoRoot, ".forge", "mcp.local.json"),
|
|
693
|
+
),
|
|
694
|
+
guide: existsSync(
|
|
695
|
+
join(repoRoot, "docs", "forge-chatgpt-mcp-setup.md"),
|
|
696
|
+
),
|
|
697
|
+
authConfigured:
|
|
698
|
+
(authMode === "oauth" && (existsSync(mcpControllerHomeOAuthPath(controllerHome)) || existsSync(mcpOAuthPath(repoRoot)))) ||
|
|
699
|
+
(authMode === "bearer" && (existsSync(mcpControllerHomeTokenPath(controllerHome)) || existsSync(mcpTokenPath(repoRoot)))),
|
|
700
|
+
localController: {
|
|
701
|
+
enabled: localConfig?.localController?.enabled ?? true,
|
|
702
|
+
host: localConfig?.localController?.host ?? "127.0.0.1",
|
|
703
|
+
port: localConfig?.localController?.port ?? 8766,
|
|
704
|
+
autoOpen: localConfig?.localController?.autoOpen ?? false,
|
|
705
|
+
},
|
|
706
|
+
devMode: {
|
|
707
|
+
agentRunner: localConfig?.devMode?.agentRunner === true,
|
|
708
|
+
allowedAgents: localConfig?.devMode?.allowedAgents ?? [],
|
|
709
|
+
timeoutMs: localConfig?.devMode?.timeoutMs ?? DEFAULT_AGENT_TIMEOUT_MS,
|
|
710
|
+
maxTimeoutMs:
|
|
711
|
+
localConfig?.devMode?.maxTimeoutMs ?? MAX_AGENT_TIMEOUT_MS,
|
|
712
|
+
},
|
|
713
|
+
},
|
|
714
|
+
codex: {
|
|
715
|
+
cliAvailable: codexCommand !== null,
|
|
716
|
+
configured: codexHasServer && missingTools.length === 0,
|
|
717
|
+
configPath: ".codex/config.toml",
|
|
718
|
+
hasServer: codexHasServer,
|
|
719
|
+
missingTools,
|
|
720
|
+
fix: "forge mcp setup codex --repo . --scope project",
|
|
721
|
+
},
|
|
722
|
+
chatgpt: {
|
|
723
|
+
...(configuredServerName ? { serverName: configuredServerName } : {}),
|
|
724
|
+
serverNameConfigured: Boolean(configuredServerName),
|
|
725
|
+
defaultServerName,
|
|
726
|
+
serverNameNeedsMigration,
|
|
727
|
+
expectedToolSurface: FORGE_TOOL_SURFACE,
|
|
728
|
+
localEndpoint: `http://${host}:${port}/mcp`,
|
|
729
|
+
localController: `http://${localConfig?.localController?.host ?? "127.0.0.1"}:${localConfig?.localController?.port ?? 8766}/`,
|
|
730
|
+
publicEndpoint: localConfig?.chatgpt?.endpoint,
|
|
731
|
+
authMode,
|
|
732
|
+
manualStepsRequired: true,
|
|
733
|
+
setup: "forge mcp setup chatgpt --repo .",
|
|
734
|
+
},
|
|
735
|
+
runtime: runtimeState
|
|
736
|
+
? {
|
|
737
|
+
status: runtimeState.status,
|
|
738
|
+
tunnelMode: runtimeState.tunnelMode,
|
|
739
|
+
localHealthy: runtimeState.server.healthy,
|
|
740
|
+
localPid: runtimeState.server.pid,
|
|
741
|
+
localRestartCount: runtimeState.server.restartCount,
|
|
742
|
+
publicEndpoint: runtimeState.tunnel?.publicEndpoint,
|
|
743
|
+
publicHealthy: runtimeState.tunnel?.healthy,
|
|
744
|
+
tunnelPid: runtimeState.tunnel?.pid,
|
|
745
|
+
tunnelRestartCount: runtimeState.tunnel?.restartCount,
|
|
746
|
+
connectorNeedsReconnect:
|
|
747
|
+
runtimeState.tunnel?.connectorNeedsReconnect === true,
|
|
748
|
+
updatedAt: runtimeState.updatedAt,
|
|
749
|
+
}
|
|
750
|
+
: null,
|
|
751
|
+
};
|
|
752
|
+
return {
|
|
753
|
+
status: "ok",
|
|
754
|
+
repoRoot,
|
|
755
|
+
changed: [],
|
|
756
|
+
lines:
|
|
757
|
+
opts.json === true
|
|
758
|
+
? [JSON.stringify(report, null, 2)]
|
|
759
|
+
: [
|
|
760
|
+
`[forge mcp] Repo: ${repoRoot}`,
|
|
761
|
+
`[forge mcp] Status: ${report.status}`,
|
|
762
|
+
`[forge mcp] ChatGPT MCP server name: ${
|
|
763
|
+
configuredServerName
|
|
764
|
+
? `${configuredServerName}${serverNameNeedsMigration ? ' (legacy shared name; rerun setup to disambiguate this Forge instance)' : ''}`
|
|
765
|
+
: `missing (run setup; default is ${defaultServerName})`
|
|
766
|
+
}`,
|
|
767
|
+
`[forge mcp] ChatGPT guide: ${report.mcp.guide ? "present" : "missing"}`,
|
|
768
|
+
`[forge mcp] Toolset: ${report.mcp.toolset}`,
|
|
769
|
+
`[forge mcp] Local Controller: ${report.mcp.localController.enabled ? report.chatgpt.localController : "disabled"}`,
|
|
770
|
+
`[forge mcp] ChatGPT auth: ${report.mcp.authConfigured ? `${authMode} present` : "missing"}`,
|
|
771
|
+
`[forge mcp] Runtime: ${
|
|
772
|
+
report.runtime
|
|
773
|
+
? `${report.runtime.status} (local=${report.runtime.localHealthy ? "ok" : "down"}${
|
|
774
|
+
report.runtime.tunnelMode !== "none"
|
|
775
|
+
? `, public=${report.runtime.publicHealthy ? "ok" : "down"} via ${report.runtime.tunnelMode}`
|
|
776
|
+
: ""
|
|
777
|
+
})`
|
|
778
|
+
: "not running"
|
|
779
|
+
}`,
|
|
780
|
+
...(report.runtime?.connectorNeedsReconnect === true
|
|
781
|
+
? [
|
|
782
|
+
"[forge mcp] Runtime note: public quick tunnel URL changed; update the ChatGPT connector or switch to a named tunnel",
|
|
783
|
+
]
|
|
784
|
+
: []),
|
|
785
|
+
`[forge mcp] Dev runner: ${report.mcp.devMode.agentRunner ? `enabled (${report.mcp.devMode.allowedAgents.join(",")})` : "disabled"}`,
|
|
786
|
+
`[forge mcp] Codex config: ${report.codex.configured ? "present" : "missing"}`,
|
|
787
|
+
`[forge mcp] Codex CLI: ${report.codex.cliAvailable ? "present" : "missing"}`,
|
|
788
|
+
`[forge mcp] Next ChatGPT setup: ${report.chatgpt.setup}`,
|
|
789
|
+
],
|
|
790
|
+
};
|
|
791
|
+
}
|