@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.
Files changed (685) hide show
  1. package/AGENTS.md +58 -62
  2. package/CHANGELOG.md +39 -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 -1585
  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 +417 -100
  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 +267 -16
  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 -6651
  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 +86 -18
  609. package/src/runtime/root/package-runtime-service.ts +63 -86
  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
@@ -16,16 +16,16 @@ import { fileURLToPath } from 'url';
16
16
  import { Command } from 'commander';
17
17
  import { runDoctor, type CheckStatus, type DoctorReport } from './doctor';
18
18
  import { runStatus, type StatusReport } from './status';
19
- import { runMcpSetupChatgpt } from '../mcp/setup';
19
+ import { runMcpSetupChatgpt } from '../../../adapters/mcp/setup';
20
20
  import { resolveControllerHome } from '../repositories/controller-home';
21
+ import { createSetupBootstrapControlApi } from './bootstrap-control';
22
+ import type { BootstrapSnapshot } from '../../runtime/control-plane/bootstrap';
21
23
  import {
22
24
  configureSetupProfile,
23
25
  detectSetupPlatform,
24
26
  formatSetupProfile,
25
27
  readSetupProfile,
26
- resolveControllerGuidance,
27
- resolveRuntimeGuidance,
28
- resolveTunnelGuidance,
28
+ setupConnectorAuthMode,
29
29
  setupHostTarget,
30
30
  type SetupHostTarget,
31
31
  type SetupPlatformSnapshot,
@@ -686,6 +686,8 @@ export interface SetupSession {
686
686
  closedAt?: string;
687
687
  lastReport: InitHookReport;
688
688
  nextAction?: InitHookAction;
689
+ /** Compatibility projection now backed by the instance-level V2 bootstrap authority. */
690
+ bootstrap?: BootstrapSnapshot;
689
691
  }
690
692
 
691
693
  export interface SetupSessionOptions extends InitHookOptions {
@@ -733,55 +735,29 @@ function setupStatus(report: InitHookReport, nextAction?: InitHookAction): Setup
733
735
  return 'open';
734
736
  }
735
737
 
736
- function profileNextAction(profile: SetupProfile | undefined, platform: SetupPlatformSnapshot, options: { controllerHome?: string; accountHome?: string } = {}): InitHookAction | undefined {
737
- if (!profile) {
738
- return {
739
- id: 'controller.select',
740
- status: 'needs_agent',
741
- reason: 'Choose the external controller that will act as Forge’s brain. ChatGPT is recommended; Codex, Claude, or another MCP client can be primary instead.',
742
- requires_agent: true,
743
- risk: 'Writes only the local Forge setup profile. It does not install or authenticate third-party software.',
744
- command: 'forge setup configure --controller chatgpt',
745
- verification: 'forge setup next',
746
- };
747
- }
748
- const controller = resolveControllerGuidance(profile, { controllerHome: options.controllerHome, home: options.accountHome });
749
- if (controller && !controller.ready) {
750
- return {
751
- id: `controller.${controller.controller}.configure`,
752
- status: 'needs_agent',
753
- reason: `${controller.title}: ${controller.detail}`,
754
- requires_agent: true,
755
- risk: 'Configures only the explicitly selected external controller entry. Unselected Codex/Claude providers remain untouched.',
756
- ...(controller.command ? { command: controller.command } : {}),
757
- verification: 'forge setup next',
758
- };
759
- }
760
- const runtime = resolveRuntimeGuidance(profile, { controllerHome: options.controllerHome });
761
- if (runtime && !runtime.ready) {
762
- return {
763
- id: 'runtime.package.install',
764
- status: 'needs_agent',
765
- reason: `${runtime.title}: ${runtime.detail}`,
766
- requires_agent: true,
767
- risk: 'Installs or diagnoses the user-level Forge Runtime only. Standalone Recovery and source-release activation are not part of normal setup.',
768
- ...(runtime.command ? { command: runtime.command } : {}),
769
- verification: 'forge setup next',
770
- };
771
- }
772
- const tunnel = resolveTunnelGuidance(profile, platform, { controllerHome: options.controllerHome });
773
- if (!tunnel.ready) {
774
- return {
775
- id: `tunnel.${tunnel.provider}.configure`,
776
- status: 'needs_agent',
777
- reason: `${tunnel.title}: ${tunnel.detail}`,
778
- requires_agent: true,
779
- risk: 'Remote connectivity is provider-owned. Forge keeps its MCP listener on loopback; credentials, authentication, and account changes remain explicit.',
780
- ...(tunnel.command ? { command: tunnel.command } : {}),
781
- verification: 'forge setup next',
782
- };
783
- }
784
- return undefined;
738
+ function bootstrapNextAction(snapshot: BootstrapSnapshot): InitHookAction | undefined {
739
+ const stateById = new Map(snapshot.steps.map((entry) => [entry.id, entry.state]));
740
+ const dependenciesReady = (entry: BootstrapSnapshot['steps'][number]): boolean => entry.dependsOn.every((dependency) => {
741
+ const state = stateById.get(dependency);
742
+ return state === 'ready' || state === 'skipped';
743
+ });
744
+ const step = snapshot.steps.find((entry) => entry.state === 'blocked' && entry.actionIds.length > 0 && dependenciesReady(entry))
745
+ ?? snapshot.steps.find((entry) => entry.state === 'pending' && entry.actionIds.length > 0 && dependenciesReady(entry));
746
+ const actionId = step?.actionIds[0];
747
+ if (!actionId) return undefined;
748
+ const action = snapshot.actions.find((entry) => entry.id === actionId);
749
+ if (!action) return undefined;
750
+ return {
751
+ id: action.id,
752
+ status: 'needs_agent',
753
+ reason: action.owner === 'user' ? `User action required: ${action.summary}` : action.summary,
754
+ requires_agent: true,
755
+ risk: action.risk ?? (action.owner === 'user'
756
+ ? 'This action crosses a user/account boundary and cannot be completed silently by Forge.'
757
+ : 'This action is scoped to the local Forge bootstrap lifecycle.'),
758
+ ...(action.command ? { command: action.command } : {}),
759
+ verification: action.verification ?? 'forge setup next',
760
+ };
785
761
  }
786
762
 
787
763
  export function openSetupSession(options: SetupSessionOptions = {}): SetupSession {
@@ -792,7 +768,10 @@ export function openSetupSession(options: SetupSessionOptions = {}): SetupSessio
792
768
  const target = options.target ?? setupHostTarget(profile);
793
769
  const report = options.report ?? runInitHook({ ...options, target });
794
770
  const controllerHome = resolveControllerHome(options.controllerHome);
795
- const nextAction = profileNextAction(profile, platform, { controllerHome, accountHome: options.accountHome }) ?? report.agent_actions[0];
771
+ const bootstrap = createSetupBootstrapControlApi({
772
+ setupRoot: options.setupRoot, env: options.env, now: options.now, controllerHome, accountHome: options.accountHome, profile, platform,
773
+ }).refreshSync();
774
+ const nextAction = bootstrapNextAction(bootstrap) ?? report.agent_actions[0];
796
775
  const now = (options.now ?? (() => new Date()))().toISOString();
797
776
  const reuse = previous && previous.status !== 'closed';
798
777
  return writeSetupSessionAt(path, {
@@ -806,6 +785,7 @@ export function openSetupSession(options: SetupSessionOptions = {}): SetupSessio
806
785
  createdAt: reuse ? previous.createdAt : now,
807
786
  updatedAt: now,
808
787
  lastReport: report,
788
+ bootstrap,
809
789
  ...(nextAction ? { nextAction } : {}),
810
790
  });
811
791
  }
@@ -855,6 +835,7 @@ interface SetupCycleRawOptions {
855
835
  target?: string;
856
836
  controller?: string;
857
837
  addController?: string[];
838
+ capability?: string[];
858
839
  tunnel?: string;
859
840
  endpoint?: string;
860
841
  tunnelId?: string;
@@ -866,24 +847,30 @@ function collectOption(value: string, previous: string[] = []): string[] {
866
847
  return [...previous, value];
867
848
  }
868
849
 
869
- function syncExplicitRemoteControllerEndpoint(profile: SetupProfile | undefined, endpoint: string | undefined): void {
870
- if (!profile || !endpoint || !profile.controllers.some((controller) => controller === 'chatgpt' || controller === 'mcp')) return;
871
- runMcpSetupChatgpt({ userLevel: true, endpoint });
850
+ function syncRemoteControllerTransport(profile: SetupProfile | undefined): void {
851
+ if (!profile || !profile.controllers.some((controller) => controller === 'chatgpt' || controller === 'mcp')) return;
852
+ runMcpSetupChatgpt({
853
+ userLevel: true,
854
+ ...(profile.tunnel.endpoint ? { endpoint: profile.tunnel.endpoint } : {}),
855
+ clearEndpoint: !profile.tunnel.endpoint,
856
+ connectorAuthMode: setupConnectorAuthMode(profile),
857
+ });
872
858
  }
873
859
 
874
860
  function setupCycle(rawOpts: SetupCycleRawOptions, surface: string): void {
875
861
  try {
876
862
  let profile = readSetupProfile();
877
- if (rawOpts.controller || rawOpts.addController?.length || rawOpts.tunnel || rawOpts.endpoint || rawOpts.tunnelId) {
863
+ if (rawOpts.controller || rawOpts.addController?.length || rawOpts.capability?.length || rawOpts.tunnel || rawOpts.endpoint || rawOpts.tunnelId) {
878
864
  profile = configureSetupProfile({
879
865
  controller: rawOpts.controller,
880
866
  addControllers: rawOpts.addController,
867
+ capabilities: rawOpts.capability,
881
868
  tunnel: rawOpts.tunnel,
882
869
  endpoint: rawOpts.endpoint,
883
870
  tunnelId: rawOpts.tunnelId,
884
871
  });
885
- syncExplicitRemoteControllerEndpoint(profile, rawOpts.endpoint);
886
872
  }
873
+ syncRemoteControllerTransport(profile);
887
874
  const session = openSetupSession({
888
875
  profile,
889
876
  target: setupTarget(rawOpts.target, surface) ?? setupHostTarget(profile),
@@ -901,6 +888,7 @@ function addSetupSelectionOptions(command: Command): Command {
901
888
  return command
902
889
  .option('--controller <controller>', 'Primary external controller: chatgpt|codex|claude|mcp')
903
890
  .option('--add-controller <controller>', 'Also configure another external controller entry (repeatable)', collectOption, [])
891
+ .option('--capability <capability-id>', 'Require a provider-neutral semantic capability (repeatable)', collectOption, [])
904
892
  .option('--tunnel <provider>', 'Remote connection: auto|openai|cloudflare|tailscale|existing|none')
905
893
  .option('--tunnel-id <id>', 'OpenAI Secure MCP Tunnel id (non-secret tunnel_...)')
906
894
  .option('--endpoint <url>', 'Existing/stable public HTTPS URL ending in /mcp')
@@ -929,20 +917,22 @@ export function buildSetupCommand(): Command {
929
917
  .description('Choose the primary external controller, optional additional controllers, and public access provider')
930
918
  .requiredOption('--controller <controller>', 'Primary external controller: chatgpt|codex|claude|mcp')
931
919
  .option('--add-controller <controller>', 'Also configure another external controller entry (repeatable)', collectOption, [])
920
+ .option('--capability <capability-id>', 'Require a provider-neutral semantic capability (repeatable)', collectOption, [])
932
921
  .option('--tunnel <provider>', 'Remote connection: auto|openai|cloudflare|tailscale|existing|none')
933
922
  .option('--tunnel-id <id>', 'OpenAI Secure MCP Tunnel id (non-secret tunnel_...)')
934
923
  .option('--endpoint <url>', 'Existing/stable public HTTPS URL ending in /mcp')
935
924
  .option('--json', 'Output JSON instead of human-readable text')
936
- .action((rawOpts: { controller: string; addController?: string[]; tunnel?: string; tunnelId?: string; endpoint?: string; json?: boolean }) => {
925
+ .action((rawOpts: { controller: string; addController?: string[]; capability?: string[]; tunnel?: string; tunnelId?: string; endpoint?: string; json?: boolean }) => {
937
926
  try {
938
927
  const profile = configureSetupProfile({
939
928
  controller: rawOpts.controller,
940
929
  addControllers: rawOpts.addController,
930
+ capabilities: rawOpts.capability,
941
931
  tunnel: rawOpts.tunnel,
942
932
  endpoint: rawOpts.endpoint,
943
933
  tunnelId: rawOpts.tunnelId,
944
934
  });
945
- syncExplicitRemoteControllerEndpoint(profile, rawOpts.endpoint);
935
+ syncRemoteControllerTransport(profile);
946
936
  console.log(rawOpts.json ? JSON.stringify(profile, null, 2) : `${formatSetupProfile(profile)}\n\nNext: forge setup next`);
947
937
  } catch (error) {
948
938
  console.error(error instanceof Error ? error.message : String(error));
@@ -950,6 +940,26 @@ export function buildSetupCommand(): Command {
950
940
  }
951
941
  });
952
942
 
943
+ command
944
+ .command('bridge-browser')
945
+ .description('Provision or repair the dedicated WSL Windows Chromium profile used by the ChatGPT bridge')
946
+ .option('--json', 'Output JSON instead of human-readable text')
947
+ .action(async (rawOpts: { json?: boolean }) => {
948
+ try {
949
+ const profile = readSetupProfile();
950
+ const api = createSetupBootstrapControlApi({ profile });
951
+ const snapshot = await api.act('chatgpt.bridge.bootstrap');
952
+ if (rawOpts.json) console.log(JSON.stringify(snapshot, null, 2));
953
+ else console.log(snapshot.status === 'ready'
954
+ ? 'Forge WSL ChatGPT bridge browser is ready.'
955
+ : `${snapshot.blockers.find((entry) => entry.stepId === 'chatgpt-wsl-bridge')?.summary ?? 'Dedicated bridge browser was provisioned. Complete any visible ChatGPT login step, then run forge setup next.'}\nNext: forge setup next`);
956
+ process.exitCode = snapshot.status === 'ready' ? 0 : 1;
957
+ } catch (error) {
958
+ console.error(error instanceof Error ? error.message : String(error));
959
+ process.exitCode = 2;
960
+ }
961
+ });
962
+
953
963
  command
954
964
  .command('status')
955
965
  .description('Read the persisted setup session and external-controller profile')
@@ -382,9 +382,11 @@ export function runInit(opts: InitCommandOptions = {}): InitCommandResult {
382
382
  const syncSkill = opts.syncSkill !== false;
383
383
  const hostAdapters = opts.hostAdapters !== false;
384
384
  const externalSkills = opts.externalSkills === true;
385
- const codegraph = opts.codegraph !== false;
386
385
  const configureCgMcp = opts.configureCodegraphMcp === true;
387
386
  const syncCodegraph = opts.syncCodegraph === true;
387
+ // CodeGraph is an optional rebuildable tool cache. Ordinary adoption leaves it
388
+ // disabled; any explicit CodeGraph operation opts in and uses the Controller Home-backed compatibility link.
389
+ const codegraph = opts.codegraph === true || configureCgMcp || syncCodegraph;
388
390
  const brainMode = opts.brainMode ?? "skip";
389
391
  const target = opts.target ?? "both";
390
392
  const steps: InitStep[] = [];
@@ -1,10 +1,10 @@
1
1
  import { Command } from 'commander';
2
2
  import { isAbsolute, relative } from 'path';
3
- import { createMcpToolContext } from '../mcp/server';
4
- import { startMcpHttp } from '../mcp/transports/http';
5
- import { startMcpStdio } from '../mcp/transports/stdio';
6
- import { callMcpTool } from '../mcp/tools';
7
- import { callAccessTool } from '../mcp/access-tools';
3
+ import { createMcpToolContext } from '../../../adapters/mcp/server';
4
+ import { startMcpHttp } from '../../../adapters/mcp/transports/http';
5
+ import { startMcpStdio } from '../../../adapters/mcp/transports/stdio';
6
+ import { callMcpTool } from '../../../adapters/mcp/tool-mapping/tools';
7
+ import { callAccessTool } from '../../../adapters/mcp/tool-mapping/access-tools';
8
8
  import { assertControllerLifecycleOwner } from '../controller/lifecycle-authority';
9
9
  import { bindInheritedRuntimeWriteClaimFromEnvironment } from '../../runtime/root/write-fence';
10
10
  import {
@@ -13,7 +13,7 @@ import {
13
13
  runMcpSetupChatgpt,
14
14
  runMcpSetupCodex,
15
15
  runMcpSetupClaude,
16
- } from '../mcp/setup';
16
+ } from '../../../adapters/mcp/setup';
17
17
 
18
18
  export interface McpServeOptions {
19
19
  repo?: string;
@@ -49,8 +49,11 @@ interface McpSetupChatgptOptions {
49
49
  port?: string;
50
50
  endpoint?: string;
51
51
  serverName?: string;
52
+ instanceId?: string;
52
53
  localControllerPort?: string;
53
54
  connectorPort?: string;
55
+ connectorAuthMode?: string;
56
+ clearEndpoint?: boolean;
54
57
  }
55
58
 
56
59
  interface McpSetupLocalControllerOptions {
@@ -162,7 +165,7 @@ export function buildMcpCommand(): Command {
162
165
  .command('serve')
163
166
  .description('Start the forge MCP server')
164
167
  .option('--repo <path>', 'Repository root to expose through the selected MCP profile')
165
- .option('--controller-home <path>', 'Controller state root; defaults to repo _ops/controller-home when present')
168
+ .option('--controller-home <path>', 'Controller state root; defaults to FORGE_CONTROLLER_HOME/XDG state or ~/.forge/controller')
166
169
  .option('--transport <transport>', 'Transport: stdio|http', 'stdio')
167
170
  .option('--host <host>', 'HTTP bind host', '127.0.0.1')
168
171
  .option('--port <port>', 'HTTP bind port', '8765')
@@ -242,9 +245,12 @@ export function buildMcpCommand(): Command {
242
245
  .option('--host <host>', 'Local MCP HTTP bind host', '127.0.0.1')
243
246
  .option('--port <port>', 'Local MCP HTTP bind port', '8765')
244
247
  .option('--local-controller-port <port>', 'Local-only Utility Console port; defaults to MCP port + 1')
245
- .option('--connector-port <port>', 'Loopback OAuth connector port for ChatGPT tunnels; defaults to MCP port + 2')
248
+ .option('--connector-port <port>', 'Loopback ChatGPT connector port; defaults to MCP port + 2')
249
+ .option('--connector-auth <mode>', 'Connector authorization boundary: oauth|none; none is only for an externally authorized private transport such as OpenAI Secure MCP Tunnel')
246
250
  .option('--endpoint <url>', 'Stable public HTTPS /mcp endpoint to store in ignored local config')
251
+ .option('--clear-endpoint', 'Remove a previously stored public HTTPS endpoint when switching to a private transport')
247
252
  .option('--server-name <name>', 'ChatGPT Connector/MCP server name to record in ignored local config')
253
+ .option('--instance-id <id>', 'Stable installation identity exposed by the ChatGPT Connector (for example forge-wsl)')
248
254
  .action((rawOpts: McpSetupChatgptOptions) => {
249
255
  void runMcpAction(() => {
250
256
  const result = runMcpSetupChatgpt(rawOpts);
@@ -289,7 +295,7 @@ export function buildMcpCommand(): Command {
289
295
  .command('get')
290
296
  .description('Read the access mode for one registered repository')
291
297
  .option('--repo <path>', 'Repository root used to resolve controllerHome', '.')
292
- .option('--controller-home <path>', 'Controller state root; defaults to repo _ops/controller-home when present')
298
+ .option('--controller-home <path>', 'Controller state root; defaults to FORGE_CONTROLLER_HOME/XDG state or ~/.forge/controller')
293
299
  .option('--repo-id <id>', 'Stable registered repository id')
294
300
  .action((rawOpts: McpAccessOptions) => {
295
301
  void runMcpAction(() => runRepositoryAccessCommand('repository_access_get', rawOpts));
@@ -299,7 +305,7 @@ export function buildMcpCommand(): Command {
299
305
  .command('set')
300
306
  .description('Set Request or Full Access for one repository or every enabled repository')
301
307
  .option('--repo <path>', 'Repository root used to resolve controllerHome', '.')
302
- .option('--controller-home <path>', 'Controller state root; defaults to repo _ops/controller-home when present')
308
+ .option('--controller-home <path>', 'Controller state root; defaults to FORGE_CONTROLLER_HOME/XDG state or ~/.forge/controller')
303
309
  .option('--repo-id <id>', 'Stable registered repository id; cannot be combined with --all-repositories')
304
310
  .option('--all-repositories', 'Apply to every enabled registered repository')
305
311
  .requiredOption('--mode <mode>', 'Access mode: request|full_access')
@@ -5,31 +5,37 @@ import { dirname, isAbsolute, join, resolve, sep } from 'path';
5
5
  import { fileURLToPath } from 'url';
6
6
  import { Command } from 'commander';
7
7
  import { resolveControllerHome, controllerSystemRoot } from '../repositories/controller-home';
8
+ import { withControllerLock, type ControllerLockKey } from '../repositories/locks';
8
9
  import { installExternalPluginRegistration, listExternalPluginRegistrations, type ExternalPluginRegistration, type ExternalPluginRegistrationInput } from '../../runtime/plugins/external-registration';
9
10
  import { createDesktopOperatorRegistrationInput } from '../../runtime/plugins/desktop-operator-registration';
10
- import { controllerPluginRepository, getAssistantPluginManifest, syncAssistantPluginRegistry } from '../../runtime/plugins/store';
11
+ import { getControllerPluginManifest, syncControllerPluginRegistry } from '../../runtime/plugins/store';
12
+ import { assertExternalPluginRepositoryTrusted, assertFirstPartyPluginRepositoryTrusted, readControllerPluginTrustPolicy, trustExternalPluginRepository, untrustExternalPluginRepository } from '../../runtime/plugins/catalog-trust';
11
13
 
12
- export interface RegistryEntry { id:string; name:string; version:string; description:string; repository:string; ref:string; installer:string; providerVersion?:string; protocolVersion?:string; platforms:NodeJS.Platform[]; }
14
+ export interface RegistryEntry { id:string; name:string; version:string; description:string; repository:string; ref:string; installer:string; providerVersion?:string; protocolVersion?:string; platforms:NodeJS.Platform[]; semanticCapabilities?:string[]; }
13
15
  interface Registry { schemaVersion:1; plugins:RegistryEntry[]; }
14
- interface CliOptions { json?:boolean; controllerHome?:string; refresh?:boolean; }
16
+ interface CliOptions { json?:boolean; controllerHome?:string; refresh?:boolean; catalog?:string; }
15
17
  const packageRoot=resolve(dirname(fileURLToPath(import.meta.url)),'../../..');
16
18
  const registryPath=join(packageRoot,'assets','plugin-registry.v1.json');
19
+ const trustPolicyPath=join(packageRoot,'assets','plugin-trust-policy.v1.json');
17
20
 
18
- function registry():Registry{
19
- const value=JSON.parse(readFileSync(registryPath,'utf8')) as Registry;
21
+ function registryFromPath(path:string,trustRepository:(repository:string)=>string):Registry{
22
+ const value=JSON.parse(readFileSync(path,'utf8')) as Registry;
20
23
  if(value.schemaVersion!==1||!Array.isArray(value.plugins))throw new Error('PLUGIN_CATALOG_INVALID');
21
24
  const ids=new Set<string>();
22
25
  for(const plugin of value.plugins){
23
26
  if(!/^[a-z][a-z0-9_]{1,63}$/.test(plugin.id)||ids.has(plugin.id))throw new Error(`PLUGIN_CATALOG_INVALID_ID: ${plugin.id}`);
24
- if(!plugin.repository.startsWith('https://github.com/moretea-labs/')||!plugin.repository.endsWith('.git'))throw new Error(`PLUGIN_CATALOG_UNTRUSTED_REPOSITORY: ${plugin.id}`);
27
+ plugin.repository=trustRepository(plugin.repository);
25
28
  if(!/^v\d+\.\d+\.\d+(?:[-+][A-Za-z0-9.-]+)?$/.test(plugin.ref))throw new Error(`PLUGIN_CATALOG_UNPINNED_REF: ${plugin.id}`);
26
29
  if(plugin.installer!=='forge-plugin-install.mjs')throw new Error(`PLUGIN_CATALOG_INSTALLER_INVALID: ${plugin.id}`);
27
30
  if(plugin.providerVersion!==undefined&&!/^\d+\.\d+\.\d+(?:[-+][A-Za-z0-9.-]+)?$/.test(plugin.providerVersion))throw new Error(`PLUGIN_CATALOG_PROVIDER_VERSION_INVALID: ${plugin.id}`);
28
31
  if(plugin.protocolVersion!==undefined&&!/^\d+\.\d+$/.test(plugin.protocolVersion))throw new Error(`PLUGIN_CATALOG_PROTOCOL_VERSION_INVALID: ${plugin.id}`);
32
+ if(plugin.semanticCapabilities!==undefined&&(!Array.isArray(plugin.semanticCapabilities)||plugin.semanticCapabilities.some(capability=>!/^[-a-z0-9_.]{3,128}$/.test(capability))))throw new Error(`PLUGIN_CATALOG_SEMANTIC_CAPABILITY_INVALID: ${plugin.id}`);
29
33
  ids.add(plugin.id);
30
34
  }
31
35
  return value;
32
36
  }
37
+ function registry():Registry{return registryFromPath(registryPath,repository=>assertFirstPartyPluginRepositoryTrusted(repository,trustPolicyPath));}
38
+ function trustedExternalRegistry(path:string,controllerHome:string):Registry{return registryFromPath(resolve(path),repository=>assertExternalPluginRepositoryTrusted(controllerHome,repository));}
33
39
  function within(root:string,relative:string):string{const target=resolve(root,relative);const base=`${resolve(root)}${sep}`;if(target!==resolve(root)&&!target.startsWith(base))throw new Error('PLUGIN_INSTALL_PATH_ESCAPE');return target;}
34
40
  export function pluginCatalogCompatibility(entry:RegistryEntry,platform:NodeJS.Platform=process.platform):{compatible:boolean;reason?:string}{
35
41
  if(!entry.platforms.includes(platform))return{compatible:false,reason:`unsupported platform: ${platform}`};
@@ -37,15 +43,20 @@ export function pluginCatalogCompatibility(entry:RegistryEntry,platform:NodeJS.P
37
43
  return{compatible:true};
38
44
  }
39
45
  export function officialPluginCatalogItems(platform:NodeJS.Platform=process.platform){return registry().plugins.map(entry=>({...entry,...pluginCatalogCompatibility(entry,platform)}));}
46
+ export function officialPluginCatalogEntry(pluginId:string):RegistryEntry|undefined{return registry().plugins.find(entry=>entry.id===pluginId);}
47
+ export function trustedExternalPluginCatalogEntry(pluginId:string,catalogPath:string,controllerHome:string):RegistryEntry|undefined{return trustedExternalRegistry(catalogPath,controllerHome).plugins.find(entry=>entry.id===pluginId);}
48
+ export function officialPluginLifecycleLockKey(pluginId:string):ControllerLockKey{return{scope:'global',resource:`external-plugin:${pluginId}`};}
49
+ export function withOfficialPluginLifecycleLock<T>(controllerHome:string,pluginId:string,operation:()=>T):T{
50
+ return withControllerLock(controllerHome,officialPluginLifecycleLockKey(pluginId),`official-plugin-lifecycle:${pluginId}:${process.pid}`,operation);
51
+ }
40
52
  export function externalPluginListItem(controllerHome:string,registration:ExternalPluginRegistration){
41
53
  const base={pluginId:registration.pluginId,version:registration.pluginVersion,provider:registration.provider,enabled:registration.enabled,scope:registration.scope,transport:registration.transport.kind};
42
54
  if(registration.scope==='repository')return{...base,healthScope:'repository_context_required' as const};
43
- const repository=controllerPluginRepository(controllerHome);
44
- try{return{...base,health:getAssistantPluginManifest(controllerHome,repository,registration.pluginId).health};}
55
+ try{return{...base,health:getControllerPluginManifest(controllerHome,registration.pluginId).health};}
45
56
  catch(error){return{...base,health:{state:'error',message:error instanceof Error?error.message:String(error)}};}
46
57
  }
47
58
  function run(command:string,args:string[],cwd:string,timeoutMs=120000):string{
48
- const result=spawnSync(command,args,{cwd,encoding:'utf8',timeout:timeoutMs,maxBuffer:32*1024*1024,shell:false,windowsHide:true});
59
+ const result=spawnSync(command,args,{cwd,encoding:'utf8',env:process.env,timeout:timeoutMs,maxBuffer:32*1024*1024,shell:false,windowsHide:true});
49
60
  if(result.error)throw new Error(`PLUGIN_INSTALL_COMMAND_FAILED: ${result.error.message}`);
50
61
  if(result.status!==0)throw new Error(`PLUGIN_INSTALL_COMMAND_FAILED: ${command} exited ${result.status}: ${String(result.stderr||result.stdout).slice(-4000)}`);
51
62
  return String(result.stdout??'');
@@ -96,15 +107,30 @@ function install(entry:RegistryEntry,controllerHome:string):Record<string,unknow
96
107
  // useful diagnostics, but must not strand a verified package when that
97
108
  // helper field is stale.
98
109
  const installed=installExternalPluginRegistration(controllerHome,registrationFrom(result,entry,{packageIdentityVerified:true}));
99
- const repository=controllerPluginRepository(controllerHome);syncAssistantPluginRegistry(controllerHome,repository);const plugin=getAssistantPluginManifest(controllerHome,repository,entry.id);
110
+ syncControllerPluginRegistry(controllerHome);const plugin=getControllerPluginManifest(controllerHome,entry.id);
100
111
  if(backed)rmSync(backup,{recursive:true,force:true});
101
112
  return{pluginId:entry.id,version:entry.version,packageRoot:finalRoot,registrationRevision:installed.revision,enabled:plugin.enabled,health:plugin.health,nextSteps:installerNextSteps(result)};
102
113
  }catch(error){rmSync(stage,{recursive:true,force:true});if(backed&&existsSync(finalRoot))rmSync(finalRoot,{recursive:true,force:true});if(backed&&existsSync(backup))renameSync(backup,finalRoot);throw error;}
103
114
  }
115
+ export function installOfficialPlugin(pluginId:string,controllerHome:string):Record<string,unknown>{
116
+ const entry=officialPluginCatalogEntry(pluginId);
117
+ if(!entry)throw new Error(`PLUGIN_NOT_IN_OFFICIAL_CATALOG: ${pluginId}`);
118
+ return withOfficialPluginLifecycleLock(controllerHome,pluginId,()=>install(entry,controllerHome));
119
+ }
120
+ export function installTrustedExternalPlugin(pluginId:string,catalogPath:string,controllerHome:string):Record<string,unknown>{
121
+ const entry=trustedExternalPluginCatalogEntry(pluginId,catalogPath,controllerHome);
122
+ if(!entry)throw new Error(`PLUGIN_NOT_IN_TRUSTED_CATALOG: ${pluginId}`);
123
+ return withOfficialPluginLifecycleLock(controllerHome,pluginId,()=>install(entry,controllerHome));
124
+ }
125
+
104
126
  export function buildPluginCommand():Command{
105
127
  const root=new Command('plugin').description('Discover and install trusted Forge plugins');
106
128
  root.command('catalog').description('List official plugins').option('--json','Output JSON').action((o:CliOptions)=>{const items=officialPluginCatalogItems();if(o.json)console.log(JSON.stringify({schemaVersion:1,platform:process.platform,plugins:items},null,2));else items.forEach(x=>console.log(`${x.id}\t${x.version}\t${x.compatible?'compatible':`incompatible (${x.reason})`}\t${x.name}`));});
107
- root.command('list').description('List installed external plugins').option('--json','Output JSON').option('--controller-home <path>','Override Controller Home').option('--refresh','Probe controller-scoped providers').action((o:CliOptions)=>{const home=resolveControllerHome(o.controllerHome),repo=controllerPluginRepository(home);if(o.refresh)syncAssistantPluginRegistry(home,repo);const items=listExternalPluginRegistrations(home).map(r=>externalPluginListItem(home,r));if(o.json)console.log(JSON.stringify({schemaVersion:1,plugins:items},null,2));else if(!items.length)console.log('No external Forge plugins installed.');else items.forEach(x=>console.log(`${x.pluginId}\t${x.version}\t${x.enabled?'enabled':'disabled'}\t${'healthScope' in x?'repository-context-required':((x.health as {state?:string})?.state??'unknown')}`));});
108
- root.command('install <plugin-id>').description('Install/update an official plugin from a pinned public release').option('--json','Output JSON').option('--controller-home <path>','Override Controller Home').action((id:string,o:CliOptions)=>{const entry=registry().plugins.find(x=>x.id===id);if(!entry)throw new Error(`PLUGIN_NOT_IN_OFFICIAL_CATALOG: ${id}`);const result=install(entry,resolveControllerHome(o.controllerHome));if(o.json)console.log(JSON.stringify(result,null,2));else{console.log(`Installed ${entry.name} ${entry.version} (${(result.health as {state?:string})?.state??'unknown'}).`);for(const step of (result.nextSteps as string[]|undefined)??[])console.log(`- ${step}`);}});
129
+ root.command('list').description('List installed external plugins').option('--json','Output JSON').option('--controller-home <path>','Override Controller Home').option('--refresh','Probe controller-scoped providers').action((o:CliOptions)=>{const home=resolveControllerHome(o.controllerHome);if(o.refresh)syncControllerPluginRegistry(home);const items=listExternalPluginRegistrations(home).map(r=>externalPluginListItem(home,r));if(o.json)console.log(JSON.stringify({schemaVersion:1,plugins:items},null,2));else if(!items.length)console.log('No external Forge plugins installed.');else items.forEach(x=>console.log(`${x.pluginId}\t${x.version}\t${x.enabled?'enabled':'disabled'}\t${'healthScope' in x?'repository-context-required':((x.health as {state?:string})?.state??'unknown')}`));});
130
+ const trust=root.command('trust').description('Manage exact third-party plugin repository trust in Controller Home');
131
+ trust.command('list').option('--json','Output JSON').option('--controller-home <path>','Override Controller Home').action((o:CliOptions)=>{const policy=readControllerPluginTrustPolicy(resolveControllerHome(o.controllerHome));if(o.json)console.log(JSON.stringify(policy,null,2));else policy.trustedRepositories.forEach(repository=>console.log(repository));});
132
+ trust.command('add <repository-url>').option('--controller-home <path>','Override Controller Home').action((repository:string,o:CliOptions)=>{const policy=trustExternalPluginRepository(resolveControllerHome(o.controllerHome),repository);console.log(`Trusted exact plugin repository: ${policy.trustedRepositories.find(entry=>entry===new URL(repository).toString())??repository}`);});
133
+ trust.command('remove <repository-url>').option('--controller-home <path>','Override Controller Home').action((repository:string,o:CliOptions)=>{untrustExternalPluginRepository(resolveControllerHome(o.controllerHome),repository);console.log(`Removed plugin repository trust: ${repository}`);});
134
+ root.command('install <plugin-id>').description('Install/update a pinned plugin from the first-party catalog or an explicitly trusted external catalog').option('--json','Output JSON').option('--controller-home <path>','Override Controller Home').option('--catalog <path>','External catalog file; every repository must already be explicitly trusted').action((id:string,o:CliOptions)=>{const home=resolveControllerHome(o.controllerHome);const entry=o.catalog?trustedExternalPluginCatalogEntry(id,o.catalog,home):officialPluginCatalogEntry(id);if(!entry)throw new Error(o.catalog?`PLUGIN_NOT_IN_TRUSTED_CATALOG: ${id}`:`PLUGIN_NOT_IN_OFFICIAL_CATALOG: ${id}`);const result=o.catalog?installTrustedExternalPlugin(id,o.catalog,home):installOfficialPlugin(id,home);if(o.json)console.log(JSON.stringify(result,null,2));else{console.log(`Installed ${entry.name} ${entry.version} (${(result.health as {state?:string})?.state??'unknown'}).`);for(const step of (result.nextSteps as string[]|undefined)??[])console.log(`- ${step}`);}});
109
135
  return root;
110
136
  }