@moretea-labs/forge 1.7.2 → 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.
Files changed (685) hide show
  1. package/AGENTS.md +58 -62
  2. package/CHANGELOG.md +26 -0
  3. package/CLAUDE.md +42 -62
  4. package/README.md +2 -2
  5. package/SKILL.md +0 -1
  6. package/THIRD_PARTY_NOTICES.md +5 -2
  7. package/adapters/browser/index.ts +2 -0
  8. package/adapters/chatgpt/browser-delivery-host.ts +71 -0
  9. package/adapters/chatgpt/browser-delivery-runtime.ts +783 -0
  10. package/adapters/chatgpt/controller-binding-store.ts +55 -0
  11. package/adapters/chatgpt/controller-host.ts +119 -0
  12. package/adapters/chatgpt/controller-round-host.ts +78 -0
  13. package/adapters/chatgpt/controller-round-settlement-store.ts +45 -0
  14. package/adapters/chatgpt/provider-delivery.ts +113 -0
  15. package/adapters/chatgpt/work-conversation-binding-store.ts +192 -0
  16. package/adapters/chatgpt/wsl-bridge-delivery-host.ts +63 -0
  17. package/adapters/computer/desktop-operator-contract.ts +7 -0
  18. package/adapters/computer/desktop-operator-discovery.ts +201 -0
  19. package/adapters/computer/desktop-operator-negotiation.ts +174 -0
  20. package/adapters/computer/desktop-operator-provider.ts +312 -0
  21. package/adapters/computer/index.ts +1 -0
  22. package/adapters/computer/interaction-target-authority.ts +944 -0
  23. package/adapters/controller-process/binding-store.ts +34 -0
  24. package/adapters/controller-process/controller-host.ts +26 -0
  25. package/adapters/mcp/access-mode.ts +132 -0
  26. package/adapters/mcp/audit.ts +32 -0
  27. package/adapters/mcp/auth.ts +407 -0
  28. package/adapters/mcp/controller-round-compatibility.ts +184 -0
  29. package/adapters/mcp/frozen-client-semantic-compatibility.ts +292 -0
  30. package/adapters/mcp/instructions.ts +36 -0
  31. package/adapters/mcp/legacy-context.ts +18 -0
  32. package/adapters/mcp/multi-repository.ts +437 -0
  33. package/adapters/mcp/oauth.ts +391 -0
  34. package/adapters/mcp/paths.ts +140 -0
  35. package/adapters/mcp/policy.ts +232 -0
  36. package/adapters/mcp/proxy-env.ts +62 -0
  37. package/adapters/mcp/readiness-projection.ts +24 -0
  38. package/adapters/mcp/redaction.ts +21 -0
  39. package/adapters/mcp/repo.ts +24 -0
  40. package/adapters/mcp/runtime-gateway/artifact-adapter.ts +52 -0
  41. package/adapters/mcp/runtime-gateway/context-adapter.ts +829 -0
  42. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +191 -0
  43. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +147 -0
  44. package/adapters/mcp/runtime-gateway/execution-control-adapter.ts +28 -0
  45. package/adapters/mcp/runtime-gateway/execution-tools.ts +207 -0
  46. package/adapters/mcp/runtime-gateway/filesystem-adapter.ts +38 -0
  47. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +411 -0
  48. package/adapters/mcp/runtime-gateway/legacy-ios-tool-adapter.ts +105 -0
  49. package/adapters/mcp/runtime-gateway/maintenance-adapter.ts +44 -0
  50. package/adapters/mcp/runtime-gateway/model-adapter.ts +63 -0
  51. package/adapters/mcp/runtime-gateway/persisted-check-process.ts +3 -0
  52. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +308 -0
  53. package/adapters/mcp/runtime-gateway/process-tools.ts +289 -0
  54. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +76 -0
  55. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +268 -0
  56. package/adapters/mcp/runtime-gateway/recovery-client-adapter.ts +70 -0
  57. package/adapters/mcp/runtime-gateway/recovery-tool-contract.ts +99 -0
  58. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +110 -0
  59. package/adapters/mcp/runtime-gateway/result-adapter.ts +108 -0
  60. package/adapters/mcp/runtime-gateway/router.ts +728 -0
  61. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1251 -0
  62. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +634 -0
  63. package/adapters/mcp/runtime-gateway/runtime-tool-shared.ts +27 -0
  64. package/adapters/mcp/runtime-gateway/runtime-tools.ts +68 -0
  65. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +186 -0
  66. package/adapters/mcp/runtime-gateway/shared-adapter.ts +25 -0
  67. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +870 -0
  68. package/adapters/mcp/runtime-gateway/work-adapter.ts +3186 -0
  69. package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +502 -0
  70. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +1 -0
  71. package/adapters/mcp/server.ts +1048 -0
  72. package/adapters/mcp/setup.ts +791 -0
  73. package/adapters/mcp/tool-capability-cache.ts +87 -0
  74. package/adapters/mcp/tool-mapping/access-tools.ts +387 -0
  75. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +5265 -0
  76. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +150 -0
  77. package/adapters/mcp/tool-mapping/repository-tools.ts +1691 -0
  78. package/adapters/mcp/tool-mapping/tools.ts +9 -0
  79. package/adapters/mcp/tool-mapping/umbrella-tools.ts +117 -0
  80. package/adapters/mcp/toolset-names.ts +74 -0
  81. package/adapters/mcp/toolset-selection.ts +41 -0
  82. package/adapters/mcp/toolset.ts +336 -0
  83. package/adapters/mcp/transports/http.ts +1456 -0
  84. package/adapters/mcp/transports/session-registry.ts +513 -0
  85. package/adapters/mcp/transports/stdio.ts +8 -0
  86. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +139 -0
  87. package/adapters/mcp/types.ts +41 -0
  88. package/assets/AGENTS.md +2 -16
  89. package/assets/CLAUDE.md +2 -16
  90. package/assets/hooks/AGENTS.md +3 -14
  91. package/assets/hooks/CLAUDE.md +3 -14
  92. package/assets/hooks/hook-input.sh +9 -2
  93. package/assets/hooks/lib/workflow-state.sh +28 -10
  94. package/assets/hooks/prompt-guard.sh +63 -37
  95. package/assets/hooks/security-sentinel.sh +2 -1
  96. package/assets/hooks/session-start-context.sh +7 -5
  97. package/assets/hooks/stop-orchestrator.sh +13 -3
  98. package/assets/initializer-question-pack.v4.json +11 -7
  99. package/assets/partials/05-workflow.partial.md +18 -73
  100. package/assets/partials/07-footer.partial.md +1 -1
  101. package/assets/partials-agents/02-operating-mode.partial.md +1 -2
  102. package/assets/partials-agents/04-task-protocol.partial.md +14 -59
  103. package/assets/partials-agents/06-quality-safety.partial.md +11 -16
  104. package/assets/partials-agents/08-deep-docs.partial.md +1 -2
  105. package/assets/plan-map.json +11 -11
  106. package/assets/plugin-registry.v1.json +9 -3
  107. package/assets/plugin-trust-policy.v1.json +6 -0
  108. package/assets/recovery/ForgeRecovery.ps1 +100 -0
  109. package/assets/recovery/forge-wsl-rescue +271 -0
  110. package/assets/reference-configs/development-protocol.md +11 -15
  111. package/assets/reference-configs/document-generation.md +1 -1
  112. package/assets/reference-configs/global-working-rules.md +9 -1
  113. package/assets/reference-configs/harness-overview.md +22 -112
  114. package/assets/reference-configs/hook-operations.md +1 -1
  115. package/assets/reference-configs/sprint-contracts.md +2 -2
  116. package/assets/skill-version.json +2 -2
  117. package/assets/templates/helpers/architecture-event.ts +3 -34
  118. package/assets/templates/helpers/architecture-queue.sh +61 -10
  119. package/assets/templates/helpers/archive-workflow.sh +90 -180
  120. package/assets/templates/helpers/capability-config.ts +8 -11
  121. package/assets/templates/helpers/capability-resolver.ts +37 -19
  122. package/assets/templates/helpers/capture-plan.sh +2 -2
  123. package/assets/templates/helpers/check-architecture-sync.sh +1 -9
  124. package/assets/templates/helpers/check-task-sync.sh +82 -11
  125. package/assets/templates/helpers/check-task-workflow.sh +1 -3
  126. package/assets/templates/helpers/context-contract-sync.sh +1 -12
  127. package/assets/templates/helpers/contract-worktree.sh +26 -24
  128. package/assets/templates/helpers/ensure-task-workflow.sh +6 -8
  129. package/assets/templates/helpers/inspect-project-state.ts +1 -1
  130. package/assets/templates/helpers/migrate-project-template.sh +1 -1
  131. package/assets/templates/helpers/migrate-workflow-docs.ts +53 -239
  132. package/assets/templates/helpers/new-plan.sh +2 -2
  133. package/assets/templates/helpers/plan-to-todo.sh +3 -31
  134. package/assets/templates/helpers/sprint-backlog.sh +1 -1
  135. package/assets/templates/helpers/switch-plan.sh +1 -1
  136. package/assets/templates/helpers/workflow-contract.ts +1 -0
  137. package/assets/workflow-contract.v1.json +63 -171
  138. package/assets/workflows/xiaohongshu/xiaohongshu.collect-metrics.v1.draft.json +118 -0
  139. package/assets/workflows/xiaohongshu/xiaohongshu.publish-image-note.v1.draft.json +316 -0
  140. package/assets/workflows/xiaohongshu/xiaohongshu.publish-long-text.v1.draft.json +324 -0
  141. package/docs/architecture/CURRENT.md +148 -13
  142. package/docs/architecture/EVOLUTION.md +13 -0
  143. package/docs/architecture/decisions/20260801-controller-home-sqlite-state.md +2 -1
  144. package/docs/architecture/decisions/20260831-independent-windows-wsl-host-rescue.md +59 -0
  145. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +120 -0
  146. package/docs/architecture/decisions/20260904-repository-runtime-data-boundary.md +42 -0
  147. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +35 -0
  148. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +296 -0
  149. package/docs/architecture/decisions/20260907-maintenance-diagnosis-bounded-read.md +39 -0
  150. package/docs/architecture/domains/verification.md +7 -0
  151. package/docs/architecture/domains/workflow-engine.md +1 -1
  152. package/docs/architecture/index.md +3 -3
  153. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +19 -8
  154. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +124 -0
  155. package/docs/forge-chatgpt-mcp-setup.md +5 -3
  156. package/docs/forge-plugin-management.md +20 -4
  157. package/docs/forge-runtime-self-healing-loop.md +2 -0
  158. package/docs/operations/benchmark-cross-version-freeze.md +38 -0
  159. package/docs/operations/controller-browser-plugin.md +3 -1
  160. package/docs/operations/homebrew.md +2 -2
  161. package/docs/operations/platform-support.md +16 -8
  162. package/docs/operations/platform-support.zh-CN.md +2 -2
  163. package/docs/operations/standalone-disaster-recovery.md +26 -1
  164. package/docs/operations/uu-remote-rescue.md +41 -0
  165. package/docs/operations/windows-wsl-host-rescue.md +133 -0
  166. package/docs/public-usage-guide.md +1 -1
  167. package/docs/public-usage-guide.zh-CN.md +1 -1
  168. package/docs/tutorials/01-install-and-start.md +1 -1
  169. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  170. package/docs/tutorials/02-connect-chatgpt.md +4 -4
  171. package/docs/tutorials/02-connect-chatgpt.zh-CN.md +4 -4
  172. package/docs/wiki/Implementation.md +1 -1
  173. package/package.json +23 -14
  174. package/packages/kernel/controller/api/index.ts +2 -0
  175. package/packages/kernel/controller/application/controller-round-service.ts +29 -0
  176. package/packages/kernel/controller/application/controller-service.ts +30 -0
  177. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +308 -0
  178. package/packages/kernel/controller/domain/controller-round.ts +107 -0
  179. package/packages/kernel/controller/domain/execution-quality.ts +133 -0
  180. package/packages/kernel/controller/domain/types.ts +56 -0
  181. package/packages/kernel/controller/index.ts +1 -0
  182. package/packages/kernel/controller/infrastructure/controller-binding-store.ts +84 -0
  183. package/packages/kernel/controller/infrastructure/controller-round-store.ts +1384 -0
  184. package/packages/kernel/controller/infrastructure/controller-session-store.ts +578 -0
  185. package/packages/kernel/controller/ports/controller-host.ts +16 -0
  186. package/packages/kernel/goal/api/index.ts +1 -0
  187. package/packages/kernel/goal/domain/types.ts +40 -0
  188. package/packages/kernel/goal/index.ts +1 -0
  189. package/packages/kernel/identity/api/index.ts +5 -0
  190. package/packages/kernel/identity/application/identity-service.ts +67 -0
  191. package/packages/kernel/identity/domain/scope.ts +63 -0
  192. package/packages/kernel/identity/domain/semantic-sync.ts +81 -0
  193. package/packages/kernel/identity/domain/types.ts +44 -0
  194. package/packages/kernel/identity/domain/workspace.ts +56 -0
  195. package/packages/kernel/identity/index.ts +1 -0
  196. package/packages/kernel/identity/infrastructure/identity-store.ts +75 -0
  197. package/packages/kernel/memory/api/index.ts +5 -0
  198. package/packages/kernel/memory/application/experience-service.ts +118 -0
  199. package/packages/kernel/memory/application/outcome-service.ts +77 -0
  200. package/packages/kernel/memory/domain/experience.ts +103 -0
  201. package/packages/kernel/memory/domain/operational-prior.ts +92 -0
  202. package/packages/kernel/memory/index.ts +1 -0
  203. package/packages/kernel/progression/api/index.ts +2 -0
  204. package/packages/kernel/progression/application/projector.ts +211 -0
  205. package/packages/kernel/progression/domain/types.ts +116 -0
  206. package/packages/kernel/progression/index.ts +1 -0
  207. package/packages/kernel/scheduler/api/index.ts +6 -0
  208. package/packages/kernel/scheduler/application/continuation-service.ts +212 -0
  209. package/packages/kernel/scheduler/application/eligibility.ts +252 -0
  210. package/packages/kernel/scheduler/application/schedule-service.ts +24 -0
  211. package/packages/kernel/scheduler/application/settlement.ts +197 -0
  212. package/packages/kernel/scheduler/domain/continuation.ts +38 -0
  213. package/packages/kernel/scheduler/domain/schedule.ts +149 -0
  214. package/packages/kernel/scheduler/index.ts +1 -0
  215. package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +38 -0
  216. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +785 -0
  217. package/packages/kernel/work/api/index.ts +15 -0
  218. package/packages/kernel/work/application/work-service.ts +148 -0
  219. package/packages/kernel/work/domain/admission-policy.ts +34 -0
  220. package/packages/kernel/work/domain/check-receipt.ts +43 -0
  221. package/packages/kernel/work/domain/context-closure-receipt.ts +32 -0
  222. package/packages/kernel/work/domain/engineering-contracts.ts +157 -0
  223. package/packages/kernel/work/domain/engineering-design.ts +281 -0
  224. package/packages/kernel/work/domain/engineering-profile.ts +242 -0
  225. package/packages/kernel/work/domain/execution-concurrency.ts +254 -0
  226. package/packages/kernel/work/domain/execution-snapshot.ts +33 -0
  227. package/packages/kernel/work/domain/implementation-review.ts +510 -0
  228. package/packages/kernel/work/domain/project-engineering-contract.ts +202 -0
  229. package/packages/kernel/work/domain/repository-completion-receipt.ts +73 -0
  230. package/packages/kernel/work/domain/state-machine.ts +259 -0
  231. package/packages/kernel/work/domain/types.ts +528 -0
  232. package/packages/kernel/work/index.ts +1 -0
  233. package/packages/kernel/work/infrastructure/work-contract-store.ts +1876 -0
  234. package/packages/kernel/work/ports/work-contract-store.ts +18 -0
  235. package/packages/plugin-runtime/browser/index.ts +3 -0
  236. package/packages/plugin-runtime/browser/provider-registry.ts +110 -0
  237. package/packages/plugin-runtime/browser/runtime-contract.ts +150 -0
  238. package/packages/plugin-runtime/browser/session-authority.ts +61 -0
  239. package/packages/plugin-runtime/computer/index.ts +6 -0
  240. package/packages/plugin-runtime/computer/provider-error.ts +26 -0
  241. package/packages/plugin-runtime/computer/provider-registration.ts +52 -0
  242. package/packages/plugin-runtime/computer/provider-registry.ts +63 -0
  243. package/packages/plugin-runtime/computer/provider.ts +19 -0
  244. package/packages/plugin-runtime/computer/target-authority.ts +190 -0
  245. package/packages/plugin-runtime/computer/target-persistence.ts +54 -0
  246. package/packages/plugin-runtime/external/index.ts +1 -0
  247. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +457 -0
  248. package/packages/plugin-runtime/index.ts +3 -0
  249. package/packages/protocols/browser/index.ts +1 -0
  250. package/packages/protocols/browser/session.ts +98 -0
  251. package/packages/protocols/computer/contract.ts +199 -0
  252. package/packages/protocols/computer/index.ts +1 -0
  253. package/packages/protocols/failure/contract.ts +158 -0
  254. package/packages/protocols/failure/index.ts +1 -0
  255. package/packages/protocols/handoff/index.ts +1 -0
  256. package/packages/protocols/handoff/status.ts +22 -0
  257. package/packages/protocols/mcp/execution-context.ts +11 -0
  258. package/packages/protocols/mcp/index.ts +2 -0
  259. package/packages/protocols/mcp/tool-contract.ts +42 -0
  260. package/packages/workflow-runtime/api/index.ts +2 -0
  261. package/packages/workflow-runtime/application/interpreter.ts +342 -0
  262. package/packages/workflow-runtime/domain/workflow-asset.ts +223 -0
  263. package/packages/workflow-runtime/index.ts +1 -0
  264. package/scripts/assemble-template.ts +1 -1
  265. package/scripts/benchmark-computer-hotpath.ts +255 -0
  266. package/scripts/benchmark-controller-round2.ts +54 -2
  267. package/scripts/benchmark-ios-agent-device.ts +3 -6
  268. package/scripts/benchmark-mcp-transport.ts +3 -4
  269. package/scripts/benchmark-operational-memory-activation.ts +235 -0
  270. package/scripts/benchmark-operational-shadow.ts +28 -0
  271. package/scripts/bootstrap-runtime-maintenance-recovery.sh +4 -1
  272. package/scripts/canary-chatgpt-provider-delivery.ts +97 -0
  273. package/scripts/canary-controller-semantic-wait.ts +195 -0
  274. package/scripts/canary-global-hook.sh +2 -2
  275. package/scripts/check-mcp-compatibility.ts +173 -7
  276. package/scripts/check-platform-support.mjs +28 -2
  277. package/scripts/check-public-docs.sh +1 -1
  278. package/scripts/check-release-readiness.sh +1 -1
  279. package/scripts/check-repository-hygiene.mjs +92 -0
  280. package/scripts/check-runtime-architecture.mjs +1206 -95
  281. package/scripts/check-source-duplication.mjs +9 -1
  282. package/scripts/check-tarball-install-smoke.sh +98 -15
  283. package/scripts/controller-ngrok-rotation.sh +5 -4
  284. package/scripts/create-project-dirs.sh +10 -74
  285. package/scripts/forge-local-recovery-helper.mjs +204 -0
  286. package/scripts/forge-uu-remote-rescue-helper.d.mts +31 -0
  287. package/scripts/forge-uu-remote-rescue-helper.mjs +409 -0
  288. package/scripts/forge-windows-host-recovery-helper.mjs +136 -0
  289. package/scripts/hook-shim.sh +2 -2
  290. package/scripts/init-project.sh +12 -70
  291. package/scripts/install-desktop-operator-registration.ts +4 -2
  292. package/scripts/install-independent-windows-wsl-recovery.ts +125 -0
  293. package/scripts/install-standalone-recovery.ts +122 -10
  294. package/scripts/install-uu-remote-rescue-registration.ts +74 -0
  295. package/scripts/install-windows-host-recovery-registration.ts +22 -0
  296. package/scripts/lib/controller-home-env.sh +6 -3
  297. package/scripts/lib/project-init-lib.sh +39 -582
  298. package/scripts/migrate-chatgpt-automation-schedules.ts +2 -2
  299. package/scripts/migrate-windows-wsl-controller-home.ts +306 -0
  300. package/scripts/open-source-audit-allowlist.txt +12 -1
  301. package/scripts/portability-bindings.mjs +70 -0
  302. package/scripts/run-bounded-command.mjs +55 -0
  303. package/scripts/run-bun-test-file.ts +22 -6
  304. package/scripts/run-governed-gate.ts +4 -1
  305. package/scripts/smoke-mcp-http-runtime.ts +1 -1
  306. package/scripts/smoke-runtime-recovery.ts +34 -1
  307. package/scripts/smoke-schedule-engine.ts +1 -1
  308. package/scripts/stage-runtime-release.ts +6 -1
  309. package/scripts/test-governance.ts +51 -2
  310. package/src/cli/agent-jobs/job-manager.ts +10 -1
  311. package/src/cli/chatgpt-browser/bind-server.ts +2 -1
  312. package/src/cli/chatgpt-browser/binding.ts +20 -10
  313. package/src/cli/chatgpt-browser/bridge-extension.ts +75 -0
  314. package/src/cli/chatgpt-browser/bridge-provider.ts +376 -11
  315. package/src/cli/chatgpt-browser/engine.ts +10 -11
  316. package/src/cli/chatgpt-browser/native-provider.ts +24 -83
  317. package/src/cli/chatgpt-browser/oracle-provider.ts +5 -3
  318. package/src/cli/chatgpt-browser/types.ts +1 -0
  319. package/src/cli/commands/bootstrap-control.ts +334 -0
  320. package/src/cli/commands/brain-assistant.ts +38 -0
  321. package/src/cli/commands/brain.ts +193 -40
  322. package/src/cli/commands/chatgpt.ts +127 -0
  323. package/src/cli/commands/computer.ts +437 -0
  324. package/src/cli/commands/doctor.ts +18 -1
  325. package/src/cli/commands/init-hook.ts +71 -61
  326. package/src/cli/commands/init.ts +3 -1
  327. package/src/cli/commands/mcp.ts +16 -10
  328. package/src/cli/commands/plugin.ts +38 -12
  329. package/src/cli/commands/recovery.ts +493 -80
  330. package/src/cli/commands/runtime.ts +9 -4
  331. package/src/cli/commands/setup-profile.ts +89 -39
  332. package/src/cli/commands/status.ts +2 -1
  333. package/src/cli/controller/check-runner.ts +487 -98
  334. package/src/cli/controller/context/types.ts +7 -1
  335. package/src/cli/controller/context-pack.ts +23 -3
  336. package/src/cli/controller/issue-store.ts +1 -1
  337. package/src/cli/controller/systemd-user.ts +110 -0
  338. package/src/cli/controller/types.ts +10 -70
  339. package/src/cli/controller/worklog.ts +67 -13
  340. package/src/cli/editing/edit-operation-contract.ts +92 -0
  341. package/src/cli/editing/edit-session.ts +289 -13
  342. package/src/cli/github/plugin.ts +17 -12
  343. package/src/cli/hook/route-registry.ts +3 -5
  344. package/src/cli/hook/runtime.ts +49 -3
  345. package/src/cli/index.ts +3 -0
  346. package/src/cli/local-bridge/connector-freshness.ts +2 -2
  347. package/src/cli/local-bridge/console-automations.ts +2 -2
  348. package/src/cli/local-bridge/facade-api.ts +41 -14
  349. package/src/cli/local-bridge/job-store.ts +1 -1
  350. package/src/cli/local-bridge/server.ts +24 -27
  351. package/src/cli/mcp/access-mode.ts +2 -132
  352. package/src/cli/mcp/access-tools.ts +2 -387
  353. package/src/cli/mcp/audit.ts +2 -32
  354. package/src/cli/mcp/auth.ts +2 -404
  355. package/src/cli/mcp/instructions.ts +2 -34
  356. package/src/cli/mcp/legacy-context.ts +2 -16
  357. package/src/cli/mcp/legacy-tool-service.ts +2 -5308
  358. package/src/cli/mcp/multi-repository.ts +2 -436
  359. package/src/cli/mcp/oauth.ts +2 -375
  360. package/src/cli/mcp/openai-secure-tunnel.ts +2 -0
  361. package/src/cli/mcp/paths.ts +2 -140
  362. package/src/cli/mcp/policy.ts +2 -232
  363. package/src/cli/mcp/post-finalize-work-attribution.ts +2 -150
  364. package/src/cli/mcp/proxy-env.ts +2 -62
  365. package/src/cli/mcp/readiness-projection.ts +2 -24
  366. package/src/cli/mcp/redaction.ts +2 -21
  367. package/src/cli/mcp/repo.ts +2 -24
  368. package/src/cli/mcp/repository-tools.ts +2 -1613
  369. package/src/cli/mcp/server.ts +2 -951
  370. package/src/cli/mcp/setup.ts +2 -737
  371. package/src/cli/mcp/tool-capability-cache.ts +2 -87
  372. package/src/cli/mcp/tool-contract.ts +2 -14
  373. package/src/cli/mcp/tools.ts +2 -9
  374. package/src/cli/mcp/toolset-names.ts +2 -70
  375. package/src/cli/mcp/toolset-selection.ts +2 -41
  376. package/src/cli/mcp/toolset.ts +2 -336
  377. package/src/cli/mcp/transports/AGENTS.md +1 -10
  378. package/src/cli/mcp/transports/CLAUDE.md +1 -10
  379. package/src/cli/mcp/transports/http.ts +2 -1414
  380. package/src/cli/mcp/transports/session-registry.ts +2 -490
  381. package/src/cli/mcp/transports/stdio.ts +2 -8
  382. package/src/cli/mcp/types.ts +2 -41
  383. package/src/cli/mcp/umbrella-tools.ts +2 -117
  384. package/src/cli/repositories/command-executor.ts +64 -18
  385. package/src/cli/repositories/command-scope.ts +117 -1
  386. package/src/cli/repositories/controller-home.ts +119 -1
  387. package/src/cli/repositories/identity.ts +13 -0
  388. package/src/cli/repositories/registry.ts +68 -49
  389. package/src/cli/repositories/repository-snapshot.ts +53 -7
  390. package/src/cli/repositories/runtime-storage.ts +27 -2
  391. package/src/cli/repositories/safe-patch.ts +34 -38
  392. package/src/cli/repositories/selected-path-actions.ts +22 -2
  393. package/src/cli/repositories/structured-git.ts +105 -25
  394. package/src/cli/runtime/helper-runner.ts +7 -0
  395. package/src/cli/runtime-invocation.ts +8 -1
  396. package/src/cli/tools/codegraph.ts +44 -25
  397. package/src/core/adoption/manifest-templates.ts +1 -1
  398. package/src/core/adoption/plan.ts +3 -26
  399. package/src/core/adoption/workflow-contract-plan.ts +17 -9
  400. package/src/effects/process-runner.ts +8 -14
  401. package/src/runtime/context/assistant-context.ts +154 -0
  402. package/src/runtime/context/assistant-work-context.ts +147 -0
  403. package/src/runtime/context/codegraph-cache-boundary.ts +255 -0
  404. package/src/runtime/context/codegraph-read-provider.ts +55 -22
  405. package/src/runtime/context/codegraph-sidecar.cjs +8 -1
  406. package/src/runtime/context/context-closure.ts +268 -0
  407. package/src/runtime/context/context-plane.ts +211 -0
  408. package/src/runtime/context/project-engineering-contract.ts +60 -0
  409. package/src/runtime/control-plane/bootstrap/capability-provider.ts +74 -0
  410. package/src/runtime/control-plane/bootstrap/control-api.ts +57 -0
  411. package/src/runtime/control-plane/bootstrap/index.ts +5 -0
  412. package/src/runtime/control-plane/bootstrap/state-machine.ts +141 -0
  413. package/src/runtime/control-plane/bootstrap/store.ts +21 -0
  414. package/src/runtime/control-plane/bootstrap/types.ts +87 -0
  415. package/src/runtime/control-plane/cleanup-artifact-retention.ts +328 -0
  416. package/src/runtime/control-plane/codegraph-cache-retention.ts +164 -0
  417. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +320 -0
  418. package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +169 -0
  419. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +350 -0
  420. package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +85 -0
  421. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +369 -99
  422. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +103 -15
  423. package/src/runtime/control-plane/execution/implementation-review-content.ts +95 -0
  424. package/src/runtime/control-plane/execution/repository-work-attribution.ts +2 -2
  425. package/src/runtime/control-plane/execution/retained-work-resume.ts +336 -6
  426. package/src/runtime/control-plane/execution/validation.ts +28 -3
  427. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +116 -0
  428. package/src/runtime/control-plane/execution/work-completion-authority.ts +44 -2
  429. package/src/runtime/control-plane/execution/work-evidence-policy.ts +34 -3
  430. package/src/runtime/control-plane/execution/work-execution-support.ts +42 -22
  431. package/src/runtime/control-plane/execution/work-finalization-service.ts +1103 -166
  432. package/src/runtime/control-plane/execution/work-handle-authority.ts +219 -22
  433. package/src/runtime/control-plane/execution/work-handle-store.ts +77 -0
  434. package/src/runtime/control-plane/execution/work-head-settlement.ts +75 -0
  435. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +145 -23
  436. package/src/runtime/control-plane/execution/work-operation-service.ts +49 -13
  437. package/src/runtime/control-plane/execution/work-preparation-service.ts +31 -15
  438. package/src/runtime/control-plane/execution/work-remote-delivery.ts +1 -1
  439. package/src/runtime/control-plane/execution/work-task-receipt.ts +20 -1
  440. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +407 -76
  441. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +88 -18
  442. package/src/runtime/control-plane/execution/work-verification-context.ts +1 -1
  443. package/src/runtime/control-plane/execution/work-verification-service.ts +258 -4
  444. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +200 -15
  445. package/src/runtime/control-plane/facade/capability-registry.ts +21 -10
  446. package/src/runtime/control-plane/facade/controller-round-relay.ts +3 -1118
  447. package/src/runtime/control-plane/facade/controller-session-store.ts +2 -488
  448. package/src/runtime/control-plane/facade/goal-workloop-access.ts +6 -3
  449. package/src/runtime/control-plane/facade/goal-workloop.ts +972 -137
  450. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +158 -0
  451. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +10 -0
  452. package/src/runtime/control-plane/facade/index.ts +4 -2
  453. package/src/runtime/control-plane/facade/operation-digest.ts +22 -58
  454. package/src/runtime/control-plane/facade/plan-contract-store.ts +1004 -38
  455. package/src/runtime/control-plane/facade/repository-work-admission.ts +19 -1
  456. package/src/runtime/control-plane/facade/requirement-authority.ts +218 -0
  457. package/src/runtime/control-plane/facade/requirement-board.ts +6 -1
  458. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +48 -0
  459. package/src/runtime/control-plane/facade/semantic-admission.ts +8 -16
  460. package/src/runtime/control-plane/facade/suggested-actions.ts +4 -1
  461. package/src/runtime/control-plane/facade/types.ts +189 -532
  462. package/src/runtime/control-plane/facade/work-admission-policy.ts +84 -35
  463. package/src/runtime/control-plane/facade/work-contract-store.ts +2 -1043
  464. package/src/runtime/control-plane/facade/work-implementation-review.ts +2 -0
  465. package/src/runtime/control-plane/facade/work-state-machine.ts +2 -250
  466. package/src/runtime/control-plane/generated-cache-retention.ts +239 -18
  467. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +12 -1
  468. package/src/runtime/control-plane/global-scheduler/maintenance.ts +76 -13
  469. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-entry.ts +55 -0
  470. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-process.ts +98 -0
  471. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +1 -1
  472. package/src/runtime/control-plane/global-scheduler/scheduler-worker-entry.ts +10 -0
  473. package/src/runtime/control-plane/global-scheduler/scheduler.ts +173 -81
  474. package/src/runtime/control-plane/global-scheduler/worker-launch.ts +18 -6
  475. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +397 -0
  476. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +2 -177
  477. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +301 -560
  478. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +20 -4
  479. package/src/runtime/control-plane/launcher/thin-launcher.ts +50 -4
  480. package/src/runtime/control-plane/lifecycle-retention-metrics.ts +60 -0
  481. package/src/runtime/control-plane/persistence/experience-store.ts +169 -0
  482. package/src/runtime/control-plane/persistence/operational-prior-store.ts +348 -0
  483. package/src/runtime/control-plane/persistence/requirement-store.ts +30 -22
  484. package/src/runtime/control-plane/persistence/sqlite-store.ts +545 -76
  485. package/src/runtime/control-plane/persistence/workflow-content-store.ts +98 -0
  486. package/src/runtime/control-plane/persistence/workflow-registry-store.ts +186 -0
  487. package/src/runtime/control-plane/persistence/workflow-run-store.ts +123 -0
  488. package/src/runtime/control-plane/release-retention.ts +56 -16
  489. package/src/runtime/control-plane/repository-namespace-retention.ts +208 -0
  490. package/src/runtime/control-plane/routing/route-policy.ts +19 -0
  491. package/src/runtime/control-plane/runtime-cleanup.ts +574 -37
  492. package/src/runtime/control-plane/runtime-generation.ts +6 -0
  493. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +465 -0
  494. package/src/runtime/control-plane/workspace/workspace-store.ts +80 -0
  495. package/src/runtime/diagnostics/incident-repair.ts +406 -0
  496. package/src/runtime/diagnostics/mcp-timing.ts +125 -6
  497. package/src/runtime/diagnostics/performance.ts +6 -14
  498. package/src/runtime/diagnostics/read-only-tool.ts +1 -1
  499. package/src/runtime/evidence/artifact-store.ts +65 -2
  500. package/src/runtime/evidence/operational-shadow.ts +38 -0
  501. package/src/runtime/evidence/process-check-receipt.ts +5 -43
  502. package/src/runtime/evidence/sensitive-output.ts +4 -4
  503. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -1
  504. package/src/runtime/execution/jobs/store.ts +121 -2
  505. package/src/runtime/execution/managed-workspace.ts +55 -5
  506. package/src/runtime/execution/process-runtime/canary.ts +19 -5
  507. package/src/runtime/execution/process-runtime/check-classification.ts +48 -0
  508. package/src/runtime/execution/process-runtime/check-facade.ts +23 -9
  509. package/src/runtime/execution/process-runtime/check-receipt.ts +1 -1
  510. package/src/runtime/execution/process-runtime/check-result-retention.ts +132 -0
  511. package/src/runtime/execution/process-runtime/check-result.ts +73 -2
  512. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +42 -3
  513. package/src/runtime/execution/process-runtime/check-storage.ts +187 -0
  514. package/src/runtime/execution/process-runtime/command-facade.ts +38 -87
  515. package/src/runtime/execution/process-runtime/index.ts +1 -0
  516. package/src/runtime/execution/process-runtime/interactive-admission.ts +2 -1
  517. package/src/runtime/execution/process-runtime/lightweight-managed.ts +32 -1
  518. package/src/runtime/execution/process-runtime/persisted-check.ts +128 -21
  519. package/src/runtime/execution/process-runtime/resource-claims.ts +60 -3
  520. package/src/runtime/execution/process-runtime/runtime.ts +132 -15
  521. package/src/runtime/execution/process-runtime/types.ts +22 -0
  522. package/src/runtime/execution/workers/executor.ts +16 -13
  523. package/src/runtime/execution/workers/worker-entry.ts +1 -1
  524. package/src/runtime/gateway/mcp/execution-tools.ts +2 -207
  525. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +2 -61
  526. package/src/runtime/gateway/mcp/persisted-check-process.ts +2 -3
  527. package/src/runtime/gateway/mcp/process-tools.ts +2 -289
  528. package/src/runtime/gateway/mcp/router.ts +2 -1125
  529. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +2 -565
  530. package/src/runtime/gateway/mcp/runtime-tools.ts +2 -6655
  531. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +2 -1
  532. package/src/runtime/maintenance/cleanup.ts +38 -24
  533. package/src/runtime/platform/browser-product-discovery.ts +174 -0
  534. package/src/runtime/platform/computer-platform.ts +14 -0
  535. package/src/runtime/platform/executable-discovery.ts +54 -0
  536. package/src/runtime/platform/fetch-http-server.ts +90 -0
  537. package/src/runtime/platform/service-manager.ts +138 -0
  538. package/src/runtime/platform/windows-host-discovery.ts +118 -0
  539. package/src/runtime/platform/windows-recovery-deployment.ts +67 -0
  540. package/src/runtime/plugins/action-application.ts +135 -0
  541. package/src/runtime/plugins/app-store-connect-adapter.ts +9 -21
  542. package/src/runtime/plugins/browser-adapter.ts +140 -100
  543. package/src/runtime/plugins/browser-automation-service.ts +15 -36
  544. package/src/runtime/plugins/browser-macos-bridge.ts +69 -21
  545. package/src/runtime/plugins/browser-manifest-surface.ts +30 -6
  546. package/src/runtime/plugins/browser-native-session-service.ts +1 -1
  547. package/src/runtime/plugins/browser-provider-registry.ts +2 -109
  548. package/src/runtime/plugins/browser-registration.ts +16 -0
  549. package/src/runtime/plugins/browser-runtime-contract.ts +2 -154
  550. package/src/runtime/plugins/browser-runtime.ts +41 -9
  551. package/src/runtime/plugins/browser-session-authority.ts +101 -291
  552. package/src/runtime/plugins/browser-session-legacy-migration.ts +203 -0
  553. package/src/runtime/plugins/browser-session-store.ts +229 -36
  554. package/src/runtime/plugins/browser-session-types.ts +2 -98
  555. package/src/runtime/plugins/capability-authorization-grants.ts +17 -0
  556. package/src/runtime/plugins/catalog-trust.ts +82 -0
  557. package/src/runtime/plugins/computer-registration.ts +839 -0
  558. package/src/runtime/plugins/config-store.ts +119 -0
  559. package/src/runtime/plugins/desktop-operator-external-policy.ts +932 -0
  560. package/src/runtime/plugins/desktop-operator-registration.ts +111 -8
  561. package/src/runtime/plugins/errors.ts +8 -1
  562. package/src/runtime/plugins/external-adapter.ts +45 -322
  563. package/src/runtime/plugins/external-provider-policy.ts +48 -0
  564. package/src/runtime/plugins/external-registration.ts +9 -1
  565. package/src/runtime/plugins/external-unix-socket-probe.cjs +9 -3
  566. package/src/runtime/plugins/external-unix-socket.ts +64 -193
  567. package/src/runtime/plugins/first-party-external-registration.ts +163 -0
  568. package/src/runtime/plugins/first-party-registry.ts +3 -1
  569. package/src/runtime/plugins/github-adapter.ts +1 -2
  570. package/src/runtime/plugins/gmail-adapter.ts +6 -6
  571. package/src/runtime/plugins/google-calendar-adapter.ts +6 -6
  572. package/src/runtime/plugins/google-shared.ts +31 -46
  573. package/src/runtime/plugins/google-tasks-adapter.ts +6 -6
  574. package/src/runtime/plugins/ios-adapter.ts +1 -2
  575. package/src/runtime/plugins/local-system-adapter.ts +180 -0
  576. package/src/runtime/plugins/macos-capability-broker.ts +15 -105
  577. package/src/runtime/plugins/resend-adapter.ts +15 -24
  578. package/src/runtime/plugins/store.ts +493 -51
  579. package/src/runtime/plugins/types.ts +8 -1
  580. package/src/runtime/plugins/uu-remote-rescue-registration.ts +155 -0
  581. package/src/runtime/plugins/windows-host-recovery-install.ts +68 -0
  582. package/src/runtime/plugins/windows-host-recovery-registration.ts +85 -0
  583. package/src/runtime/plugins/xiaohongshu-publish.ts +86 -430
  584. package/src/runtime/projections/controller-context.ts +12 -6
  585. package/src/runtime/projections/git-status-sampler.ts +73 -22
  586. package/src/runtime/projections/materialized-view.ts +14 -8
  587. package/src/runtime/recovery/capability-action-application.ts +228 -0
  588. package/src/runtime/recovery/index.ts +3 -0
  589. package/src/runtime/recovery/lifecycle-inventory.ts +338 -0
  590. package/src/runtime/recovery/local-jobs-repair.ts +14 -14
  591. package/src/runtime/recovery/maintenance-executor.ts +358 -76
  592. package/src/runtime/recovery/quarantine-retention.ts +256 -0
  593. package/src/runtime/release/identity.ts +6 -0
  594. package/src/runtime/resources/leases/store.ts +1 -1
  595. package/src/runtime/root/active-execution-power-assertion.ts +139 -0
  596. package/src/runtime/root/assistant-learning-loop.ts +45 -0
  597. package/src/runtime/root/browser-session-composition.ts +59 -0
  598. package/src/runtime/root/computer-composition.ts +191 -0
  599. package/src/runtime/root/computer-target-composition.ts +16 -0
  600. package/src/runtime/root/computer-target-persistence.ts +39 -0
  601. package/src/runtime/root/controller-round-composition.ts +107 -0
  602. package/src/runtime/root/controller-services.ts +2 -0
  603. package/src/runtime/root/entry.ts +4 -3
  604. package/src/runtime/root/gateway-adapter.ts +3 -3
  605. package/src/runtime/root/local-bridge.ts +5 -2
  606. package/src/runtime/root/mcp-transport.ts +5 -5
  607. package/src/runtime/root/package-connector-service.ts +108 -56
  608. package/src/runtime/root/package-runtime-release.ts +85 -18
  609. package/src/runtime/root/package-runtime-service.ts +60 -97
  610. package/src/runtime/root/release-execution-canary.ts +71 -0
  611. package/src/runtime/root/release-loader.ts +68 -0
  612. package/src/runtime/root/release-manifest.ts +106 -2
  613. package/src/runtime/root/release-materialize.ts +103 -4
  614. package/src/runtime/root/release-store.ts +31 -2
  615. package/src/runtime/root/runtime.ts +240 -25
  616. package/src/runtime/root/scheduled-controller-composition.ts +51 -0
  617. package/src/runtime/root/scheduler.ts +12 -4
  618. package/src/runtime/root/service-runner.ts +1 -1
  619. package/src/runtime/root/service.ts +41 -16
  620. package/src/runtime/root/status.ts +1 -0
  621. package/src/runtime/root/types.ts +24 -1
  622. package/src/runtime/shared/local-bridge-surface.ts +1 -1
  623. package/src/runtime/shared/process-environment.ts +19 -4
  624. package/src/runtime/shared/storage-capacity.ts +68 -0
  625. package/src/runtime/standalone-recovery/controller-home-migration.ts +1116 -0
  626. package/src/runtime/standalone-recovery/core.ts +984 -230
  627. package/src/runtime/standalone-recovery/entry.ts +182 -51
  628. package/src/runtime/standalone-recovery/independent-host-rescue.ts +172 -0
  629. package/src/runtime/standalone-recovery/installer.ts +212 -104
  630. package/src/runtime/standalone-recovery/mcp-server.ts +243 -0
  631. package/src/runtime/standalone-recovery/mutation-identity-contract.ts +21 -0
  632. package/src/runtime/standalone-recovery/operation-lock.ts +160 -0
  633. package/src/runtime/standalone-recovery/performance.ts +135 -0
  634. package/src/runtime/standalone-recovery/release.ts +5 -0
  635. package/src/runtime/watchdog/workflow-watchdog.ts +1 -1
  636. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +1 -1
  637. package/src/runtime/workflow/schedules/engine.ts +191 -343
  638. package/src/runtime/workflow/schedules/pending-activation.ts +1 -1
  639. package/src/runtime/workflow/schedules/settlement.ts +2 -191
  640. package/src/runtime/workflow/schedules/store.ts +2 -607
  641. package/src/runtime/workflow/schedules/types.ts +2 -127
  642. package/src/runtime/workflow/schedules/work-continuation.ts +180 -15
  643. package/src/runtime/workflows/first-party/xiaohongshu.ts +122 -0
  644. package/src/runtime/workflows/runtime.ts +486 -0
  645. package/src/testing/test-governance.ts +90 -29
  646. package/assets/templates/helpers/archive-architecture-request.sh +0 -244
  647. package/docs/architecture/history/README.md +0 -7
  648. package/docs/architecture/history/chatgpt-handoff-facade.md +0 -397
  649. package/docs/architecture/history/global-hook-runtime.md +0 -166
  650. package/docs/architecture/history/ios-semantic-automation-provider-v2.md +0 -170
  651. package/docs/architecture/requests/archive/2026/20260528-154740-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  652. package/docs/architecture/requests/archive/2026/20260528-154816-assets-hooks-assets-hooks-hook-input-sh.md +0 -59
  653. package/docs/architecture/requests/archive/2026/20260528-161851-ai-harness-workflow-contract-json-ai-harness-workflow-contract-json.md +0 -59
  654. package/docs/architecture/requests/archive/2026/20260528-161853-scripts-check-task-workflow-sh-scripts-check-task-workflow-sh.md +0 -59
  655. package/docs/architecture/requests/archive/2026/20260528-161911-assets-workflow-contract-v1-json-assets-workflow-contract-v1-json.md +0 -59
  656. package/docs/architecture/requests/archive/2026/20260528-222416-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  657. package/docs/architecture/requests/archive/2026/20260528-222444-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  658. package/docs/architecture/requests/archive/2026/20260528-222457-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  659. package/docs/architecture/requests/archive/2026/20260528-222648-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  660. package/docs/architecture/requests/archive/2026/20260528-222705-ai-hooks-ai-hooks-worktree-guard-sh.md +0 -59
  661. package/docs/architecture/requests/archive/2026/20260528-222726-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  662. package/docs/architecture/requests/archive/2026/20260528-222727-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  663. package/docs/architecture/requests/archive/2026/20260528-224736-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  664. package/docs/architecture/requests/archive/2026/20260528-233259-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  665. package/docs/architecture/requests/archive/2026/20260528-233335-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  666. package/docs/architecture/requests/archive/2026/20260528-233456-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  667. package/docs/architecture/requests/archive/2026/20260528-233457-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  668. package/docs/architecture/requests/archive/2026/20260528-233637-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  669. package/docs/architecture/requests/archive/2026/20260528-233638-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  670. package/docs/architecture/requests/archive/2026/20260529-000322-root-package-json.md +0 -59
  671. package/docs/architecture/requests/archive/2026/20260529-004238-ai-hooks-ai-hooks-lib-workflow-state-sh.md +0 -59
  672. package/docs/architecture/requests/archive/2026/20260529-020654-ai-harness-policy-json-ai-harness-policy-json.md +0 -63
  673. package/docs/architecture/requests/archive/2026/20260529-094236-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  674. package/docs/architecture/requests/archive/2026/20260529-094323-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  675. package/docs/architecture/requests/archive/2026/20260529-094331-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  676. package/docs/architecture/requests/archive/2026/20260529-094339-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  677. package/docs/architecture/requests/archive/2026/20260529-094430-assets-hooks-assets-hooks-session-start-context-sh.md +0 -60
  678. package/docs/architecture/requests/archive/2026/20260529-094446-ai-hooks-ai-hooks-session-start-context-sh.md +0 -60
  679. package/docs/architecture/requests/archive/2026/20260613-002040-runtime-harness-hook-adapters.md +0 -68
  680. package/docs/architecture/requests/archive/2026/root.md +0 -68
  681. package/docs/architecture/requests/archive/2026/runtime-harness-hook-adapters.md +0 -76
  682. package/docs/architecture/requests/archive/2026/verification-evals-checks.md +0 -68
  683. package/docs/architecture/requests/archive/2026/workflow-engine-contract-assets.md +0 -69
  684. package/scripts/archive-architecture-request.sh +0 -4
  685. 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
+ }