@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
@@ -0,0 +1,48 @@
1
+ import {
2
+ desktopOperatorAllowsMissingProviderAction,
3
+ executeDesktopOperatorPolicyAction,
4
+ resolveDesktopOperatorAuthorizationContext,
5
+ } from './desktop-operator-external-policy';
6
+ import type { ExternalPluginRegistration } from './external-registration';
7
+ import type { DesktopApplicationIdentity, VerifiedDesktopApplicationActivation } from './local-system-adapter';
8
+ import type { AssistantPluginActionExecutionInput, AssistantPluginAuthorizationContext } from './types';
9
+
10
+ export interface ExternalProviderPolicyContext {
11
+ callProvider(
12
+ requestId: string,
13
+ actionId: string,
14
+ args: Record<string, unknown>,
15
+ timeoutMs?: number,
16
+ signal?: AbortSignal,
17
+ ): Promise<Record<string, unknown>>;
18
+ verifyProviderIdentity(requestId: string, signal?: AbortSignal): Promise<void>;
19
+ activateAndVerifyFrontmostApplication(identity: DesktopApplicationIdentity): Promise<VerifiedDesktopApplicationActivation>;
20
+ }
21
+
22
+ export interface ExternalProviderPolicyExecutionResult {
23
+ handled: boolean;
24
+ result?: Record<string, unknown>;
25
+ }
26
+
27
+ export interface ExternalProviderPolicy {
28
+ allowsMissingProviderAction?(actionId: string): boolean;
29
+ resolveAuthorizationContext?(
30
+ registration: ExternalPluginRegistration,
31
+ input: AssistantPluginActionExecutionInput,
32
+ context: ExternalProviderPolicyContext,
33
+ ): Promise<AssistantPluginAuthorizationContext | undefined>;
34
+ executeAction?(
35
+ input: AssistantPluginActionExecutionInput,
36
+ context: ExternalProviderPolicyContext,
37
+ ): Promise<ExternalProviderPolicyExecutionResult>;
38
+ }
39
+
40
+ const DESKTOP_OPERATOR_EXTERNAL_POLICY: ExternalProviderPolicy = {
41
+ allowsMissingProviderAction: desktopOperatorAllowsMissingProviderAction,
42
+ resolveAuthorizationContext: resolveDesktopOperatorAuthorizationContext,
43
+ executeAction: executeDesktopOperatorPolicyAction,
44
+ };
45
+
46
+ export function resolveExternalProviderPolicy(registration: ExternalPluginRegistration): ExternalProviderPolicy | undefined {
47
+ return registration.pluginId === 'desktop_operator' ? DESKTOP_OPERATOR_EXTERNAL_POLICY : undefined;
48
+ }
@@ -57,6 +57,8 @@ export interface ExternalPluginRegistration {
57
57
  protocolVersion: string;
58
58
  scope: AssistantPluginScope;
59
59
  enabled: boolean;
60
+ /** Product registrations appear in normal plugin listings; provider registrations are internal implementation bindings. */
61
+ exposure?: 'product' | 'provider';
60
62
  transport: ExternalPluginTransport;
61
63
  lifecycle?: ExternalPluginLifecycle;
62
64
  permissions: AssistantPluginPermissionScope[];
@@ -77,6 +79,8 @@ export interface ExternalPluginRegistrationInput {
77
79
  protocolVersion: string;
78
80
  scope: AssistantPluginScope;
79
81
  enabled?: boolean;
82
+ /** Defaults to product for backward compatibility with schema-v1 registrations. */
83
+ exposure?: 'product' | 'provider';
80
84
  transport: ExternalPluginTransport;
81
85
  lifecycle?: ExternalPluginLifecycle;
82
86
  permissions: AssistantPluginPermissionScope[];
@@ -103,7 +107,7 @@ function normalizedTransport(input: ExternalPluginTransport): ExternalPluginTran
103
107
  if (input.kind === 'unix_socket_jsonl') {
104
108
  const socketPath = input.socketPath.trim();
105
109
  if (!socketPath || !isAbsolute(socketPath)) {
106
- throw new Error('EXTERNAL_PLUGIN_SOCKET_PATH_INVALID: trusted registrations require an absolute Unix socket path');
110
+ throw new Error('EXTERNAL_PLUGIN_SOCKET_PATH_INVALID: trusted registrations require an absolute local socket or Windows named-pipe path');
107
111
  }
108
112
  return {
109
113
  kind: 'unix_socket_jsonl',
@@ -228,6 +232,9 @@ function normalizeRegistrationInput(input: ExternalPluginRegistrationInput): Omi
228
232
  const protocolVersion = normalizedString(input.protocolVersion, 'protocol_version', 32);
229
233
  if (!PROTOCOL_VERSION_PATTERN.test(protocolVersion)) throw new Error(`EXTERNAL_PLUGIN_PROTOCOL_VERSION_INVALID: ${protocolVersion}`);
230
234
  if (!['controller', 'repository'].includes(input.scope)) throw new Error(`EXTERNAL_PLUGIN_SCOPE_INVALID: ${String(input.scope)}`);
235
+ if (input.exposure !== undefined && !['product', 'provider'].includes(input.exposure)) {
236
+ throw new Error(`EXTERNAL_PLUGIN_EXPOSURE_INVALID: ${String(input.exposure)}`);
237
+ }
231
238
  return {
232
239
  schemaVersion: EXTERNAL_REGISTRATION_SCHEMA_VERSION,
233
240
  pluginId,
@@ -238,6 +245,7 @@ function normalizeRegistrationInput(input: ExternalPluginRegistrationInput): Omi
238
245
  protocolVersion,
239
246
  scope: input.scope,
240
247
  enabled: input.enabled !== false,
248
+ ...(input.exposure !== undefined ? { exposure: input.exposure } : {}),
241
249
  transport: normalizedTransport(input.transport),
242
250
  lifecycle: normalizedLifecycle(input.lifecycle),
243
251
  permissions: structuredClone(input.permissions),
@@ -5,8 +5,7 @@ const net = require('net');
5
5
  const path = require('path');
6
6
 
7
7
  function fail(message) {
8
- process.stderr.write(String(message).slice(0, 4000));
9
- process.exitCode = 1;
8
+ process.stderr.write(String(message).slice(0, 4000), () => process.exit(1));
10
9
  }
11
10
 
12
11
  function bounded(value, fallback, min, max) {
@@ -30,6 +29,10 @@ function main() {
30
29
  fail('EXTERNAL_PLUGIN_PROBE_REQUEST_INVALID');
31
30
  return;
32
31
  }
32
+ if (!/^[a-z][a-z0-9_]{0,127}$/.test(input.method)) {
33
+ fail('EXTERNAL_PLUGIN_METHOD_INVALID');
34
+ return;
35
+ }
33
36
  const timeoutMs = bounded(input.timeoutMs, 2000, 100, 10000);
34
37
  const maxRequestBytes = bounded(input.maxRequestBytes, 1048576, 1024, 4194304);
35
38
  const maxResponseBytes = bounded(input.maxResponseBytes, 1048576, 1024, 4194304);
@@ -57,7 +60,10 @@ function main() {
57
60
  if (settled) return;
58
61
  settled = true;
59
62
  cleanup();
60
- process.stdout.write(line);
63
+ // A named-pipe Socket can keep Bun's event loop alive well after destroy()
64
+ // on Windows. Exit only after stdout flushes so sync diagnostics stay
65
+ // bounded by the RPC, not delayed handle reclamation.
66
+ process.stdout.write(line, () => process.exit(0));
61
67
  }
62
68
  socket.once('connect', () => socket.write(envelope));
63
69
  socket.on('data', (chunk) => {
@@ -1,178 +1,47 @@
1
1
  import { spawnSync } from 'child_process';
2
2
  import { existsSync } from 'fs';
3
- import { createConnection, type Socket } from 'net';
4
- import { dirname, isAbsolute, join, resolve } from 'path';
3
+ import { dirname, join, resolve } from 'path';
5
4
  import { fileURLToPath } from 'url';
5
+ import {
6
+ callExternalUnixJsonl,
7
+ decodeExternalUnixJsonlResponse,
8
+ ExternalUnixJsonlTransportError,
9
+ normalizeExternalUnixJsonlCall,
10
+ type ExternalUnixJsonlCallOptions,
11
+ type ExternalUnixJsonlMethod,
12
+ } from '../../../packages/plugin-runtime/external/index';
6
13
  import { resolveBunExecutable } from '../shared/process-environment';
7
14
  import { AssistantPluginError } from './errors';
8
15
 
9
- const DEFAULT_TIMEOUT_MS = 30_000;
10
- const DEFAULT_HEALTH_TIMEOUT_MS = 2_000;
11
- const DEFAULT_MAX_REQUEST_BYTES = 1_048_576;
12
- const DEFAULT_MAX_RESPONSE_BYTES = 1_048_576;
13
- const MAX_TIMEOUT_MS = 120_000;
14
16
  const MAX_DIAGNOSTIC_CHARS = 4_000;
15
17
 
16
- export type ExternalUnixSocketMethod = 'handshake' | 'manifest' | 'health' | 'execute' | 'macos_browser_automation';
17
-
18
- export interface ExternalUnixSocketCallOptions {
19
- socketPath: string;
20
- requestId: string;
21
- method: ExternalUnixSocketMethod;
22
- params?: Record<string, unknown>;
23
- timeoutMs?: number;
24
- maxRequestBytes?: number;
25
- maxResponseBytes?: number;
26
- signal?: AbortSignal;
27
- }
28
-
29
- interface RpcSuccess {
30
- id: string;
31
- ok: true;
32
- result: unknown;
33
- }
34
-
35
- interface RpcFailure {
36
- id: string;
37
- ok: false;
38
- error: {
39
- code: string;
40
- message: string;
41
- retryable?: boolean;
42
- domain?: string;
43
- details?: unknown;
44
- };
45
- }
46
-
47
- type RpcResponse = RpcSuccess | RpcFailure;
48
-
49
- function boundedInteger(value: number | undefined, fallback: number, min: number, max: number): number {
50
- if (typeof value !== 'number' || !Number.isFinite(value)) return fallback;
51
- return Math.min(Math.max(Math.trunc(value), min), max);
52
- }
18
+ export type ExternalUnixSocketMethod = ExternalUnixJsonlMethod;
19
+ export interface ExternalUnixSocketCallOptions extends ExternalUnixJsonlCallOptions {}
53
20
 
54
21
  function transportError(code: string, message: string, options: { retryable?: boolean; details?: Record<string, unknown> } = {}): AssistantPluginError {
55
22
  return new AssistantPluginError(code, message.slice(0, 1_000), { retryable: options.retryable ?? true, details: options.details });
56
23
  }
57
24
 
58
- function validateSocketPath(socketPath: string): string {
59
- const normalized = socketPath.trim();
60
- if (!normalized || !isAbsolute(normalized)) throw transportError('EXTERNAL_PLUGIN_SOCKET_PATH_INVALID', 'External provider socket path must be absolute.', { retryable: false });
61
- return normalized;
62
- }
63
-
64
- function requestEnvelope(options: ExternalUnixSocketCallOptions): string {
65
- const envelope = JSON.stringify({ id: options.requestId, method: options.method, params: options.params ?? {} });
66
- const maxRequestBytes = boundedInteger(options.maxRequestBytes, DEFAULT_MAX_REQUEST_BYTES, 1_024, 4 * DEFAULT_MAX_REQUEST_BYTES);
67
- if (Buffer.byteLength(envelope, 'utf8') > maxRequestBytes) {
68
- throw transportError('EXTERNAL_PLUGIN_REQUEST_TOO_LARGE', 'External provider request exceeded the bounded input limit.', { retryable: false });
69
- }
70
- return `${envelope}\n`;
71
- }
72
-
73
- function parseRpcResponse(raw: string, requestId: string): unknown {
74
- let parsed: unknown;
75
- try {
76
- parsed = JSON.parse(raw);
77
- } catch {
78
- throw transportError('EXTERNAL_PLUGIN_PROTOCOL_ERROR', 'External provider returned invalid JSON.');
79
- }
80
- if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
81
- throw transportError('EXTERNAL_PLUGIN_PROTOCOL_ERROR', 'External provider returned an invalid response envelope.');
82
- }
83
- const response = parsed as Partial<RpcResponse>;
84
- if (response.id !== requestId || typeof response.ok !== 'boolean') {
85
- throw transportError('EXTERNAL_PLUGIN_PROTOCOL_ERROR', 'External provider returned a mismatched response id or status.');
86
- }
87
- if (response.ok === true) return (response as RpcSuccess).result;
88
- const failure = response as RpcFailure;
89
- if (!failure.error || typeof failure.error.code !== 'string' || typeof failure.error.message !== 'string') {
90
- throw transportError('EXTERNAL_PLUGIN_PROTOCOL_ERROR', 'External provider returned an invalid structured error.');
25
+ function toAssistantPluginError(error: unknown): AssistantPluginError {
26
+ if (error instanceof AssistantPluginError) return error;
27
+ if (error instanceof ExternalUnixJsonlTransportError) {
28
+ return new AssistantPluginError(error.code, error.detailMessage, {
29
+ retryable: error.retryable,
30
+ effectOutcome: error.effectOutcome,
31
+ details: error.details,
32
+ });
91
33
  }
92
- throw new AssistantPluginError(failure.error.code, failure.error.message, {
93
- retryable: failure.error.retryable === true,
94
- details: {
95
- ...(typeof failure.error.domain === 'string' ? { domain: failure.error.domain } : {}),
96
- ...(failure.error.details && typeof failure.error.details === 'object' && !Array.isArray(failure.error.details)
97
- ? { providerDetails: failure.error.details as Record<string, unknown> }
98
- : {}),
99
- },
100
- });
101
- }
102
-
103
- function normalizeResult(value: unknown): Record<string, unknown> {
104
- if (value && typeof value === 'object' && !Array.isArray(value)) return value as Record<string, unknown>;
105
- return { value };
106
- }
107
-
108
- function timeoutFor(options: ExternalUnixSocketCallOptions, health = false): number {
109
- return boundedInteger(options.timeoutMs, health ? DEFAULT_HEALTH_TIMEOUT_MS : DEFAULT_TIMEOUT_MS, 100, MAX_TIMEOUT_MS);
34
+ return transportError('EXTERNAL_PLUGIN_TRANSPORT_FAILED', error instanceof Error ? error.message : String(error));
110
35
  }
111
36
 
112
37
  export async function callExternalUnixSocket(
113
38
  options: ExternalUnixSocketCallOptions,
114
39
  ): Promise<Record<string, unknown>> {
115
- const socketPath = validateSocketPath(options.socketPath);
116
- const envelope = requestEnvelope(options);
117
- if (options.signal?.aborted) throw transportError('EXTERNAL_PLUGIN_ABORTED', 'External provider request was cancelled before connection.');
118
- const timeoutMs = timeoutFor(options, options.method === 'health' || options.method === 'handshake' || options.method === 'manifest');
119
- const maxResponseBytes = boundedInteger(options.maxResponseBytes, DEFAULT_MAX_RESPONSE_BYTES, 1_024, 4 * DEFAULT_MAX_RESPONSE_BYTES);
120
-
121
- return await new Promise<Record<string, unknown>>((resolve, reject) => {
122
- let socket: Socket | undefined;
123
- let timer: ReturnType<typeof setTimeout> | undefined;
124
- let settled = false;
125
- let buffer = Buffer.alloc(0);
126
-
127
- const cleanup = (): void => {
128
- if (timer) clearTimeout(timer);
129
- options.signal?.removeEventListener('abort', onAbort);
130
- if (socket && !socket.destroyed) socket.destroy();
131
- };
132
- const finish = (callback: () => void): void => {
133
- if (settled) return;
134
- settled = true;
135
- cleanup();
136
- callback();
137
- };
138
- const fail = (error: unknown): void => finish(() => reject(error instanceof AssistantPluginError
139
- ? error
140
- : transportError('EXTERNAL_PLUGIN_TRANSPORT_FAILED', error instanceof Error ? error.message : String(error))));
141
- const succeed = (value: unknown): void => finish(() => resolve(normalizeResult(value)));
142
- const onAbort = (): void => fail(transportError('EXTERNAL_PLUGIN_ABORTED', 'External provider request was cancelled.'));
143
-
144
- timer = setTimeout(() => fail(transportError('EXTERNAL_PLUGIN_TIMEOUT', `External provider request timed out after ${timeoutMs}ms.`)), timeoutMs);
145
- timer.unref?.();
146
- options.signal?.addEventListener('abort', onAbort, { once: true });
147
-
148
- try {
149
- socket = createConnection({ path: socketPath });
150
- } catch (error) {
151
- fail(error);
152
- return;
153
- }
154
- socket.once('connect', () => socket?.write(envelope));
155
- socket.on('data', (chunk: Buffer) => {
156
- if (settled) return;
157
- if (buffer.length + chunk.length > maxResponseBytes) {
158
- fail(transportError('EXTERNAL_PLUGIN_RESPONSE_TOO_LARGE', 'External provider response exceeded the bounded output limit.', { retryable: false }));
159
- return;
160
- }
161
- buffer = Buffer.concat([buffer, chunk]);
162
- const newline = buffer.indexOf(0x0A);
163
- if (newline < 0) return;
164
- const raw = buffer.subarray(0, newline).toString('utf8');
165
- try {
166
- succeed(parseRpcResponse(raw, options.requestId));
167
- } catch (error) {
168
- fail(error);
169
- }
170
- });
171
- socket.once('error', (error) => fail(transportError('EXTERNAL_PLUGIN_SOCKET_UNAVAILABLE', error.message)));
172
- socket.once('end', () => {
173
- if (!settled) fail(transportError('EXTERNAL_PLUGIN_PROTOCOL_ERROR', 'External provider closed the socket before returning a complete response.'));
174
- });
175
- });
40
+ try {
41
+ return await callExternalUnixJsonl(options);
42
+ } catch (error) {
43
+ throw toAssistantPluginError(error);
44
+ }
176
45
  }
177
46
 
178
47
  export function resolveExternalPluginProbeSidecarPath(
@@ -203,42 +72,44 @@ export function resolveExternalPluginProbeRuntime(
203
72
  export function probeExternalUnixSocketSync(
204
73
  options: ExternalUnixSocketCallOptions,
205
74
  ): Record<string, unknown> {
206
- validateSocketPath(options.socketPath);
207
- const sidecarPath = resolveExternalPluginProbeSidecarPath();
208
- const probeRuntime = resolveExternalPluginProbeRuntime();
209
- const timeoutMs = timeoutFor(options, true);
210
- const input = JSON.stringify({
211
- socketPath: options.socketPath,
212
- requestId: options.requestId,
213
- method: options.method,
214
- params: options.params ?? {},
215
- timeoutMs,
216
- maxRequestBytes: boundedInteger(options.maxRequestBytes, DEFAULT_MAX_REQUEST_BYTES, 1_024, 4 * DEFAULT_MAX_REQUEST_BYTES),
217
- maxResponseBytes: boundedInteger(options.maxResponseBytes, DEFAULT_MAX_RESPONSE_BYTES, 1_024, 4 * DEFAULT_MAX_RESPONSE_BYTES),
218
- });
219
- const execution = spawnSync(probeRuntime, [sidecarPath], {
220
- input,
221
- encoding: 'utf8',
222
- timeout: timeoutMs + 1_000,
223
- maxBuffer: boundedInteger(options.maxResponseBytes, DEFAULT_MAX_RESPONSE_BYTES, 1_024, 4 * DEFAULT_MAX_RESPONSE_BYTES) + 16_384,
224
- env: Object.fromEntries(Object.entries({
225
- PATH: process.env.PATH,
226
- HOME: process.env.HOME,
227
- TMPDIR: process.env.TMPDIR,
228
- TEMP: process.env.TEMP,
229
- TMP: process.env.TMP,
230
- LANG: process.env.LANG,
231
- LC_ALL: process.env.LC_ALL,
232
- FORGE_EXTERNAL_PLUGIN_PROBE: '1',
233
- }).filter((entry): entry is [string, string] => typeof entry[1] === 'string')),
234
- shell: false,
235
- windowsHide: true,
236
- });
237
- if (execution.error) throw transportError('EXTERNAL_PLUGIN_PROBE_FAILED', execution.error.message);
238
- if (execution.status !== 0) {
239
- const diagnostic = String(execution.stderr || execution.stdout || '').slice(-MAX_DIAGNOSTIC_CHARS);
240
- throw transportError('EXTERNAL_PLUGIN_PROBE_FAILED', diagnostic || `Probe sidecar exited with status ${String(execution.status)}.`);
75
+ try {
76
+ const normalized = normalizeExternalUnixJsonlCall(options, true);
77
+ const sidecarPath = resolveExternalPluginProbeSidecarPath();
78
+ const probeRuntime = resolveExternalPluginProbeRuntime();
79
+ const input = JSON.stringify({
80
+ socketPath: normalized.socketPath,
81
+ requestId: normalized.requestId,
82
+ method: normalized.method,
83
+ params: normalized.params,
84
+ timeoutMs: normalized.timeoutMs,
85
+ maxRequestBytes: normalized.maxRequestBytes,
86
+ maxResponseBytes: normalized.maxResponseBytes,
87
+ });
88
+ const execution = spawnSync(probeRuntime, [sidecarPath], {
89
+ input,
90
+ encoding: 'utf8',
91
+ timeout: normalized.timeoutMs + 1_000,
92
+ maxBuffer: normalized.maxResponseBytes + 16_384,
93
+ env: Object.fromEntries(Object.entries({
94
+ PATH: process.env.PATH,
95
+ HOME: process.env.HOME,
96
+ TMPDIR: process.env.TMPDIR,
97
+ TEMP: process.env.TEMP,
98
+ TMP: process.env.TMP,
99
+ LANG: process.env.LANG,
100
+ LC_ALL: process.env.LC_ALL,
101
+ FORGE_EXTERNAL_PLUGIN_PROBE: '1',
102
+ }).filter((entry): entry is [string, string] => typeof entry[1] === 'string')),
103
+ shell: false,
104
+ windowsHide: true,
105
+ });
106
+ if (execution.error) throw transportError('EXTERNAL_PLUGIN_PROBE_FAILED', execution.error.message);
107
+ if (execution.status !== 0) {
108
+ const diagnostic = String(execution.stderr || execution.stdout || '').slice(-MAX_DIAGNOSTIC_CHARS);
109
+ throw transportError('EXTERNAL_PLUGIN_PROBE_FAILED', diagnostic || `Probe sidecar exited with status ${String(execution.status)}.`);
110
+ }
111
+ return decodeExternalUnixJsonlResponse(String(execution.stdout ?? '').trim(), normalized.requestId);
112
+ } catch (error) {
113
+ throw toAssistantPluginError(error);
241
114
  }
242
- const raw = String(execution.stdout ?? '').trim();
243
- return normalizeResult(parseRpcResponse(raw, options.requestId));
244
115
  }
@@ -0,0 +1,163 @@
1
+ import { existsSync, readFileSync } from 'fs';
2
+ import { homedir } from 'os';
3
+ import { dirname, isAbsolute, join, resolve } from 'path';
4
+ import { createDesktopOperatorRegistrationInput } from './desktop-operator-registration';
5
+ import {
6
+ getExternalPluginRegistration,
7
+ installExternalPluginRegistration,
8
+ type ExternalPluginRegistration,
9
+ type ExternalPluginUnixSocketTransport,
10
+ } from './external-registration';
11
+
12
+ function isForgeDesktopOperatorBinding(
13
+ registration: ExternalPluginRegistration,
14
+ ): registration is ExternalPluginRegistration & { transport: ExternalPluginUnixSocketTransport } {
15
+ return registration.pluginId === 'desktop_operator'
16
+ && registration.providerPluginId === 'desktop_operator'
17
+ && registration.provider === 'local-macos'
18
+ && registration.scope === 'controller'
19
+ && registration.transport.kind === 'unix_socket_jsonl';
20
+ }
21
+
22
+ const DESKTOP_OPERATOR_BUNDLE_ID = 'com.moretea.forge.desktop-operator';
23
+ const DESKTOP_OPERATOR_APP_NAME = 'Forge Desktop Operator.app';
24
+
25
+ interface DesktopOperatorInstallReceipt {
26
+ schemaVersion: 1;
27
+ pluginId: string;
28
+ pluginVersion: string;
29
+ protocolVersion: string;
30
+ socketPath: string;
31
+ executablePath: string;
32
+ manifestPath: string;
33
+ serviceManager: string;
34
+ bundleIdentifier: string;
35
+ launchAgentLabel: string;
36
+ expectedProgramContains: string;
37
+ }
38
+
39
+ interface DesktopOperatorInstalledManifest {
40
+ id?: unknown;
41
+ version?: unknown;
42
+ protocolVersion?: unknown;
43
+ }
44
+
45
+ export interface FirstPartyExternalRegistrationReconcileOptions {
46
+ /** Test/repair seams only. Production uses the stable provider-owned installation paths. */
47
+ desktopOperatorInstallReceiptPath?: string;
48
+ desktopOperatorCanonicalSocketPath?: string;
49
+ desktopOperatorCanonicalExecutablePath?: string;
50
+ }
51
+
52
+ function canonicalDesktopOperatorSocketPath(): string {
53
+ return join(homedir(), 'Library', 'Caches', 'Forge', 'desktop-operator.sock');
54
+ }
55
+
56
+ function canonicalDesktopOperatorExecutablePath(): string {
57
+ return join(homedir(), 'Applications', DESKTOP_OPERATOR_APP_NAME, 'Contents', 'MacOS', 'desktop-operator');
58
+ }
59
+
60
+ function defaultDesktopOperatorInstallReceiptPath(): string {
61
+ return join(homedir(), 'Library', 'Application Support', 'Forge', 'DesktopOperator', 'registration', 'registration.json');
62
+ }
63
+
64
+ function parseJsonObject(path: string, code: string): Record<string, unknown> {
65
+ let value: unknown;
66
+ try {
67
+ value = JSON.parse(readFileSync(path, 'utf8'));
68
+ } catch (error) {
69
+ throw new Error(`${code}: ${error instanceof Error ? error.message : String(error)}`);
70
+ }
71
+ if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(code);
72
+ return value as Record<string, unknown>;
73
+ }
74
+
75
+ function installedDesktopOperatorReleaseIdentity(
76
+ existing: ExternalPluginRegistration & { transport: ExternalPluginUnixSocketTransport },
77
+ options: FirstPartyExternalRegistrationReconcileOptions,
78
+ ): { pluginVersion: string; protocolVersion: string } | undefined {
79
+ const lifecycle = existing.lifecycle?.kind === 'verified_user_launch_agent' ? existing.lifecycle : undefined;
80
+ if (!lifecycle) return undefined;
81
+
82
+ const expectedSocketPath = options.desktopOperatorCanonicalSocketPath?.trim() || canonicalDesktopOperatorSocketPath();
83
+ const expectedExecutablePath = options.desktopOperatorCanonicalExecutablePath?.trim() || canonicalDesktopOperatorExecutablePath();
84
+ // Only the stable first-party installation may contribute release metadata.
85
+ // Synthetic/custom registrations keep their existing version authority.
86
+ if (!isAbsolute(expectedSocketPath)
87
+ || !isAbsolute(expectedExecutablePath)
88
+ || resolve(existing.transport.socketPath) !== resolve(expectedSocketPath)
89
+ || lifecycle.label !== DESKTOP_OPERATOR_BUNDLE_ID
90
+ || !isAbsolute(lifecycle.expectedProgramContains)
91
+ || resolve(lifecycle.expectedProgramContains) !== resolve(expectedExecutablePath)) return undefined;
92
+
93
+ const receiptPath = resolve(options.desktopOperatorInstallReceiptPath?.trim() || defaultDesktopOperatorInstallReceiptPath());
94
+ if (!existsSync(receiptPath)) return undefined;
95
+ const raw = parseJsonObject(receiptPath, 'DESKTOP_OPERATOR_INSTALL_RECEIPT_INVALID');
96
+ const receipt = raw as unknown as DesktopOperatorInstallReceipt;
97
+
98
+ // The receipt is evidence for installed release metadata only. It may never
99
+ // replace the already-trusted endpoint or lifecycle identity.
100
+ if (receipt.schemaVersion !== 1
101
+ || receipt.pluginId !== 'desktop_operator'
102
+ || typeof receipt.pluginVersion !== 'string' || !receipt.pluginVersion.trim()
103
+ || typeof receipt.protocolVersion !== 'string' || !receipt.protocolVersion.trim()
104
+ || typeof receipt.socketPath !== 'string'
105
+ || resolve(receipt.socketPath) !== resolve(existing.transport.socketPath)
106
+ || receipt.bundleIdentifier !== DESKTOP_OPERATOR_BUNDLE_ID
107
+ || receipt.launchAgentLabel !== lifecycle.label
108
+ || typeof receipt.expectedProgramContains !== 'string' || !receipt.expectedProgramContains.trim()
109
+ || receipt.serviceManager !== 'launchd-user-agent'
110
+ || typeof receipt.executablePath !== 'string'
111
+ || !isAbsolute(receipt.executablePath)
112
+ || resolve(receipt.executablePath) !== resolve(lifecycle.expectedProgramContains)
113
+ || !receipt.executablePath.includes(receipt.expectedProgramContains)
114
+ || !receipt.executablePath.endsWith(`/${DESKTOP_OPERATOR_APP_NAME}/Contents/MacOS/desktop-operator`)
115
+ || typeof receipt.manifestPath !== 'string'
116
+ || resolve(receipt.manifestPath) !== resolve(join(dirname(receiptPath), 'forge-plugin.json'))) {
117
+ throw new Error('DESKTOP_OPERATOR_INSTALL_RECEIPT_IDENTITY_MISMATCH');
118
+ }
119
+
120
+ const manifest = parseJsonObject(receipt.manifestPath, 'DESKTOP_OPERATOR_INSTALLED_MANIFEST_INVALID') as DesktopOperatorInstalledManifest;
121
+ if (manifest.id !== 'desktop_operator'
122
+ || manifest.version !== receipt.pluginVersion
123
+ || manifest.protocolVersion !== receipt.protocolVersion) {
124
+ throw new Error('DESKTOP_OPERATOR_INSTALLED_MANIFEST_IDENTITY_MISMATCH');
125
+ }
126
+ return { pluginVersion: receipt.pluginVersion, protocolVersion: receipt.protocolVersion };
127
+ }
128
+
129
+ /**
130
+ * Reconcile one installed first-party external provider to the current Forge-owned
131
+ * policy contract while preserving installation/runtime identity. The external
132
+ * registration store remains the only persistence, fingerprint and revision
133
+ * authority; this layer only materializes desired state from current source.
134
+ */
135
+ export function reconcileFirstPartyExternalPluginRegistration(
136
+ controllerHome: string,
137
+ pluginId: string,
138
+ options: FirstPartyExternalRegistrationReconcileOptions = {},
139
+ ): ExternalPluginRegistration | undefined {
140
+ const existing = getExternalPluginRegistration(controllerHome, pluginId);
141
+ if (!existing) return undefined;
142
+ if (pluginId !== 'desktop_operator' || !isForgeDesktopOperatorBinding(existing)) return existing;
143
+
144
+ const lifecycle = existing.lifecycle?.kind === 'verified_user_launch_agent'
145
+ ? existing.lifecycle
146
+ : undefined;
147
+ const installedRelease = installedDesktopOperatorReleaseIdentity(existing, options);
148
+ const desired = createDesktopOperatorRegistrationInput({
149
+ socketPath: existing.transport.socketPath,
150
+ launchAgentLabel: lifecycle?.label,
151
+ expectedProgramContains: lifecycle?.expectedProgramContains,
152
+ pluginVersion: installedRelease?.pluginVersion ?? existing.pluginVersion,
153
+ protocolVersion: installedRelease?.protocolVersion ?? existing.protocolVersion,
154
+ enabled: existing.enabled,
155
+ });
156
+ return installExternalPluginRegistration(controllerHome, desired);
157
+ }
158
+
159
+ /** Reconcile every currently installed first-party external provider. */
160
+ export function reconcileFirstPartyExternalPluginRegistrations(controllerHome: string): ExternalPluginRegistration[] {
161
+ const desktop = reconcileFirstPartyExternalPluginRegistration(controllerHome, 'desktop_operator');
162
+ return desktop ? [desktop] : [];
163
+ }
@@ -1,5 +1,6 @@
1
1
  import { appStoreConnectPluginAdapter } from './app-store-connect-adapter';
2
- import { browserPluginAdapter } from './browser-adapter';
2
+ import { browserPluginAdapter } from './browser-registration';
3
+ import { computerPluginAdapter } from './computer-registration';
3
4
  import { githubPluginAdapter } from './github-adapter';
4
5
  import { gmailPluginAdapter } from './gmail-adapter';
5
6
  import { googleCalendarPluginAdapter } from './google-calendar-adapter';
@@ -13,6 +14,7 @@ import type { AssistantPluginAdapter } from './types';
13
14
 
14
15
  const FIRST_PARTY_PLUGIN_ADAPTERS: readonly AssistantPluginAdapter[] = [
15
16
  githubPluginAdapter,
17
+ computerPluginAdapter,
16
18
  browserPluginAdapter,
17
19
  appStoreConnectPluginAdapter,
18
20
  iosPluginAdapter,
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  closeIssueWithGitHubPlugin,
3
3
  getGitHubPluginStatus,
4
- githubPluginConfigPath,
5
4
  loadGitHubPluginConfig,
6
5
  publishIssueWithGitHubPlugin,
7
6
  refreshIssueWithGitHubPlugin,
@@ -295,7 +294,7 @@ export function buildGitHubPluginManifest(previousRevision = 0, previousUpdatedA
295
294
  authority: {
296
295
  strategy: 'derived',
297
296
  duplicateStateAllowed: false,
298
- sourceOfTruth: ['repository-registry:github', `repo-local:${githubPluginConfigPath()}`],
297
+ sourceOfTruth: ['repository-registry:github', 'legacy-import-only:.forge/plugins/github.json'],
299
298
  },
300
299
  enabled: config.enabled,
301
300
  lifecycle: {
@@ -1,6 +1,7 @@
1
1
  import type {
2
2
  AssistantPluginActionDescriptor,
3
3
  AssistantPluginActionExecutionInput,
4
+ AssistantPluginBuildContext,
4
5
  AssistantPluginCapability,
5
6
  AssistantPluginManifest,
6
7
  AssistantPluginPermissionScope,
@@ -9,7 +10,6 @@ import { AssistantPluginError } from './errors';
9
10
  import {
10
11
  type GmailPluginConfig,
11
12
  encodeBase64Url,
12
- gmailPluginConfigPath,
13
13
  googleApiRequest,
14
14
  googlePermission,
15
15
  loadGmailPluginConfig,
@@ -665,9 +665,9 @@ function gmailProvider(config: GmailPluginConfig, repoRoot?: string): GmailProvi
665
665
  return config.provider === 'mock' ? mockGmailProvider() : liveGmailProvider(config, repoRoot);
666
666
  }
667
667
 
668
- export function buildGmailPluginManifest(previousRevision = 0, previousUpdatedAt?: string, repoRoot?: string): AssistantPluginManifest {
668
+ export function buildGmailPluginManifest(previousRevision = 0, previousUpdatedAt?: string, repoRoot?: string, context?: AssistantPluginBuildContext): AssistantPluginManifest {
669
669
  const root = repoRoot ?? process.cwd();
670
- const config = loadGmailPluginConfig(root);
670
+ const config = loadGmailPluginConfig(root, context);
671
671
  const auth = resolveGoogleAuth('gmail', config, { repoRoot: root });
672
672
  const state = pluginStateFromGoogleAuth(config, auth);
673
673
  return {
@@ -681,7 +681,7 @@ export function buildGmailPluginManifest(previousRevision = 0, previousUpdatedAt
681
681
  authority: {
682
682
  strategy: 'derived',
683
683
  duplicateStateAllowed: false,
684
- sourceOfTruth: [`repo-local:${gmailPluginConfigPath()}`, 'env:FORGE_*_ACCESS_TOKEN'],
684
+ sourceOfTruth: ['controller-home:repositories/<repoId>/plugins/config/gmail.json', 'env:FORGE_*_ACCESS_TOKEN'],
685
685
  },
686
686
  enabled: config.enabled,
687
687
  lifecycle: {
@@ -701,11 +701,11 @@ export function buildGmailPluginManifest(previousRevision = 0, previousUpdatedAt
701
701
  }
702
702
 
703
703
  export async function executeGmailPluginAction(input: AssistantPluginActionExecutionInput): Promise<Record<string, unknown>> {
704
- const current = loadGmailPluginConfig(input.repoRoot);
704
+ const current = loadGmailPluginConfig(input.repoRoot, input);
705
705
  switch (input.actionId) {
706
706
  case 'configure': {
707
707
  const args = input.args;
708
- const config = saveGmailPluginConfig(input.repoRoot, {
708
+ const config = saveGmailPluginConfig(input, {
709
709
  enabled: typeof args.enabled === 'boolean' ? args.enabled : current.enabled,
710
710
  provider: args.provider === 'google-workspace' ? 'google-workspace' : args.provider === 'mock' ? 'mock' : current.provider,
711
711
  accountEmail: args.clear_account_email === true ? undefined : stringValue(args.account_email) ?? current.accountEmail,