@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
@@ -1,3 +1,11 @@
1
+ import {
2
+ COMPUTER_CAPTURE_CAPABILITY,
3
+ COMPUTER_CONSOLE_UNLOCK_CAPABILITY,
4
+ COMPUTER_ELEMENT_ACTION_CAPABILITY,
5
+ COMPUTER_ELEMENT_OBSERVE_CAPABILITY,
6
+ COMPUTER_INPUT_CAPABILITY,
7
+ COMPUTER_OBSERVE_CAPABILITY,
8
+ } from '../../../packages/protocols/computer/index';
1
9
  import type { ExternalPluginRegistrationInput } from './external-registration';
2
10
  import type { AssistantPluginActionDescriptor } from './types';
3
11
 
@@ -19,7 +27,7 @@ const SELECTOR_SCHEMA = {
19
27
  additionalProperties: false,
20
28
  };
21
29
 
22
- function desktopOperatorActions(): AssistantPluginActionDescriptor[] {
30
+ export function desktopOperatorActions(): AssistantPluginActionDescriptor[] {
23
31
  return [
24
32
  {
25
33
  actionId: 'desktop_status',
@@ -143,6 +151,94 @@ function desktopOperatorActions(): AssistantPluginActionDescriptor[] {
143
151
  additionalProperties: false,
144
152
  },
145
153
  },
154
+ {
155
+ actionId: 'desktop_select_rows',
156
+ title: 'Select desktop rows',
157
+ description: 'Select one bounded contiguous row range in a semantic Accessibility list or table. Selection stays inside the bound desktop session and does not activate the application or use coordinates.',
158
+ readOnly: false,
159
+ risk: 'workspace_write',
160
+ confirmation: 'authorization',
161
+ defaultTimeoutMs: 10_000,
162
+ cancellable: true,
163
+ idempotent: false,
164
+ scopes: ['desktop.interact'],
165
+ resourceClaims: CONTROLLER_WRITE,
166
+ argumentsSchema: {
167
+ type: 'object',
168
+ properties: {
169
+ interaction_id: { type: 'string' },
170
+ selector: SELECTOR_SCHEMA,
171
+ start_index: { type: 'integer', minimum: 0 },
172
+ end_index: { type: 'integer', minimum: 0 },
173
+ },
174
+ required: ['interaction_id', 'selector', 'start_index'],
175
+ additionalProperties: false,
176
+ },
177
+ },
178
+ {
179
+ actionId: 'desktop_pointer_click',
180
+ title: 'Click observed desktop element',
181
+ description: 'Click one previously observed Accessibility element by ref inside an exact observed window. Forge re-resolves the ref, fences it to the source window, rebinds it after verified application activation, derives fresh bounded geometry and visual revision internally, and fails closed on stale refs/windows; raw coordinates are never accepted.',
182
+ readOnly: false,
183
+ risk: 'workspace_write',
184
+ confirmation: 'authorization',
185
+ defaultTimeoutMs: 10_000,
186
+ cancellable: true,
187
+ idempotent: false,
188
+ scopes: ['desktop.interact', 'desktop.capture'],
189
+ resourceClaims: CONTROLLER_WRITE,
190
+ argumentsSchema: {
191
+ type: 'object',
192
+ properties: {
193
+ interaction_id: { type: 'string' },
194
+ selector: {
195
+ type: 'object',
196
+ properties: { ref: { type: 'string' } },
197
+ required: ['ref'],
198
+ additionalProperties: false,
199
+ },
200
+ window_id: { type: 'integer', minimum: 1 },
201
+ label: { type: 'string' },
202
+ },
203
+ required: ['interaction_id', 'selector', 'window_id'],
204
+ additionalProperties: false,
205
+ },
206
+ },
207
+ {
208
+ actionId: 'desktop_pointer_drag',
209
+ title: 'Drag observed desktop element',
210
+ description: 'Drag one previously observed Accessibility element to another by ref inside the same exact observed window. Forge re-resolves both refs, rebinds both after verified activation only when both have stable selectors, derives fresh bounded centers and visual revision internally, and never accepts raw coordinates.',
211
+ readOnly: false,
212
+ risk: 'workspace_write',
213
+ confirmation: 'authorization',
214
+ defaultTimeoutMs: 10_000,
215
+ cancellable: true,
216
+ idempotent: false,
217
+ scopes: ['desktop.interact', 'desktop.capture'],
218
+ resourceClaims: CONTROLLER_WRITE,
219
+ argumentsSchema: {
220
+ type: 'object',
221
+ properties: {
222
+ interaction_id: { type: 'string' },
223
+ source_selector: {
224
+ type: 'object',
225
+ properties: { ref: { type: 'string' } },
226
+ required: ['ref'],
227
+ additionalProperties: false,
228
+ },
229
+ target_selector: {
230
+ type: 'object',
231
+ properties: { ref: { type: 'string' } },
232
+ required: ['ref'],
233
+ additionalProperties: false,
234
+ },
235
+ window_id: { type: 'integer', minimum: 1 },
236
+ label: { type: 'string' },
237
+ },
238
+ required: ['interaction_id', 'source_selector', 'target_selector', 'window_id'],
239
+ additionalProperties: false,
240
+ },
241
+ },
146
242
  {
147
243
  actionId: 'desktop_type_text',
148
244
  title: 'Type desktop text',
@@ -170,7 +266,7 @@ function desktopOperatorActions(): AssistantPluginActionDescriptor[] {
170
266
  {
171
267
  actionId: 'desktop_key',
172
268
  title: 'Press desktop keys',
173
- description: 'Send one bounded key chord to the exact target session after Forge independently re-establishes and verifies that application as system-frontmost at the action boundary.',
269
+ description: 'Send one bounded key chord only after Forge verifies that the exact session is already system-frontmost and that its uniquely focused Accessibility window remains the same CGWindow; Forge never reactivates the application bundle at this boundary.',
174
270
  readOnly: false,
175
271
  risk: 'workspace_write',
176
272
  confirmation: 'authorization',
@@ -244,7 +340,7 @@ function desktopOperatorActions(): AssistantPluginActionDescriptor[] {
244
340
  {
245
341
  actionId: 'desktop_paste',
246
342
  title: 'Paste into desktop session',
247
- description: 'Send Command+V only when the explicit target session is already foreground; the operator never activates it.',
343
+ description: 'Send Command+V only after Forge verifies that the explicit target session is already system-frontmost and its exact focused window remains stable; the operator never reactivates the application bundle.',
248
344
  readOnly: false,
249
345
  risk: 'workspace_write',
250
346
  confirmation: 'authorization',
@@ -305,7 +401,7 @@ function desktopOperatorActions(): AssistantPluginActionDescriptor[] {
305
401
  {
306
402
  actionId: 'desktop_batch',
307
403
  title: 'Run desktop batch',
308
- description: 'Run at most 50 non-batch Desktop Operator steps under one authorized interaction request.',
404
+ description: 'Run at most 50 non-batch Desktop Operator steps under one authorized interaction request; nested key/copy/paste input is exact-window verified for one foreground session and rejects conflicting activation or multi-session focus.',
309
405
  readOnly: false,
310
406
  risk: 'workspace_write',
311
407
  confirmation: 'authorization',
@@ -363,7 +459,7 @@ export interface DesktopOperatorRegistrationOptions {
363
459
  socketPath: string;
364
460
  launchAgentLabel?: string;
365
461
  expectedProgramContains?: string;
366
- pluginVersion?: string;
462
+ pluginVersion: string;
367
463
  protocolVersion?: string;
368
464
  enabled?: boolean;
369
465
  }
@@ -387,17 +483,18 @@ export function createDesktopOperatorRegistrationInput(
387
483
  providerPluginId: 'desktop_operator',
388
484
  displayName: 'Forge Desktop Operator',
389
485
  provider: 'local-macos',
390
- pluginVersion: options.pluginVersion ?? '0.2.1',
486
+ pluginVersion: options.pluginVersion,
391
487
  protocolVersion: options.protocolVersion ?? '1.0',
392
488
  scope: 'controller',
393
489
  enabled: options.enabled !== false,
490
+ exposure: 'provider',
394
491
  transport: {
395
492
  kind: 'unix_socket_jsonl',
396
493
  socketPath: options.socketPath,
397
494
  healthTimeoutMs: 2_000,
398
495
  actionTimeoutMs: 30_000,
399
496
  maxRequestBytes: 1_048_576,
400
- maxResponseBytes: 1_048_576,
497
+ maxResponseBytes: 4 * 1_048_576,
401
498
  },
402
499
  lifecycle: options.launchAgentLabel && options.expectedProgramContains ? {
403
500
  kind: 'verified_user_launch_agent',
@@ -410,10 +507,16 @@ export function createDesktopOperatorRegistrationInput(
410
507
  { capabilityId: 'desktop.permissions', title: 'Desktop permissions', description: 'Request the official macOS permissions required by Desktop Operator capabilities.', scopes: ['desktop.permissions'], actions: ['desktop_permissions_request'] },
411
508
  { capabilityId: 'desktop.session', title: 'Desktop sessions', description: 'Create and close application interaction sessions.', scopes: ['desktop.session'], actions: ['desktop_session_open', 'desktop_session_close'] },
412
509
  { capabilityId: 'desktop.observe', title: 'Desktop observation', description: 'Read bounded Accessibility and window state.', scopes: ['desktop.observe'], actions: ['desktop_observe'] },
413
- { capabilityId: 'desktop.interact', title: 'Desktop interaction', description: 'Press controls, type text, send keys, and open URLs.', scopes: ['desktop.interact'], actions: ['desktop_press', 'desktop_type_text', 'desktop_key', 'desktop_open_url'] },
510
+ { capabilityId: 'desktop.interact', title: 'Desktop interaction', description: 'Press controls, click previously observed controls, type text, send keys, and open URLs.', scopes: ['desktop.interact', 'desktop.capture'], actions: ['desktop_press', 'desktop_select_rows', 'desktop_pointer_click', 'desktop_pointer_drag', 'desktop_type_text', 'desktop_key', 'desktop_open_url'] },
414
511
  { capabilityId: 'desktop.capture', title: 'Desktop capture', description: 'Capture authorized screenshots.', scopes: ['desktop.capture'], actions: ['desktop_screenshot'] },
415
512
  { capabilityId: 'desktop.clipboard', title: 'Desktop clipboard', description: 'Read or replace plain-text clipboard content and issue explicit copy/paste in a bound session.', scopes: ['desktop.clipboard'], actions: ['desktop_clipboard_read', 'desktop_clipboard_write', 'desktop_copy', 'desktop_paste'] },
416
513
  { capabilityId: 'desktop.batch', title: 'Desktop batch', description: 'Run bounded desktop action batches.', scopes: ['desktop.batch'], actions: ['desktop_batch'] },
514
+ { capabilityId: COMPUTER_OBSERVE_CAPABILITY, title: 'Computer observation', description: 'Provider-neutral bounded computer observation implemented by Desktop Operator.', scopes: ['desktop.observe'], actions: ['desktop_observe'] },
515
+ { capabilityId: COMPUTER_INPUT_CAPABILITY, title: 'Computer input', description: 'Provider-neutral bounded computer input implemented by Desktop Operator.', scopes: ['desktop.interact'], actions: ['desktop_press', 'desktop_select_rows', 'desktop_type_text', 'desktop_key', 'desktop_open_url'] },
516
+ { capabilityId: COMPUTER_CONSOLE_UNLOCK_CAPABILITY, title: 'Protected console unlock', description: 'Provider-neutral protected console unlock. Invocation is intentionally absent from the generic Assistant Plugin action registry so credentials cannot enter durable plugin receipts.', scopes: [], actions: [] },
517
+ { capabilityId: COMPUTER_CAPTURE_CAPABILITY, title: 'Computer capture', description: 'Provider-neutral authorized computer capture implemented by Desktop Operator.', scopes: ['desktop.capture'], actions: ['desktop_screenshot'] },
518
+ { capabilityId: COMPUTER_ELEMENT_OBSERVE_CAPABILITY, title: 'Computer element observation', description: 'Provider-neutral element snapshot observation with exact observation-epoch target identity. Provider semantic actions are negotiated through the Computer handshake, not the Assistant Plugin action registry.', scopes: ['desktop.observe'], actions: [] },
519
+ { capabilityId: COMPUTER_ELEMENT_ACTION_CAPABILITY, title: 'Computer semantic element actions', description: 'Provider-neutral semantic actions against exact observed element targets. The provider handshake is the action-set authority.', scopes: ['desktop.interact'], actions: [] },
417
520
  ],
418
521
  actions,
419
522
  legacyIdentities: ['Repo Harness Desktop Operator'],
@@ -1,11 +1,15 @@
1
+ export type AssistantPluginEffectOutcome = 'failed' | 'outcome_unknown';
2
+
1
3
  export interface AssistantPluginErrorOptions {
2
4
  retryable?: boolean;
5
+ effectOutcome?: AssistantPluginEffectOutcome;
3
6
  details?: Record<string, unknown>;
4
7
  }
5
8
 
6
9
  export class AssistantPluginError extends Error {
7
10
  readonly code: string;
8
11
  readonly retryable: boolean;
12
+ readonly effectOutcome: AssistantPluginEffectOutcome;
9
13
  readonly details?: Record<string, unknown>;
10
14
 
11
15
  constructor(code: string, message: string, options: AssistantPluginErrorOptions = {}) {
@@ -13,6 +17,7 @@ export class AssistantPluginError extends Error {
13
17
  this.name = 'AssistantPluginError';
14
18
  this.code = code;
15
19
  this.retryable = options.retryable === true;
20
+ this.effectOutcome = options.effectOutcome ?? 'failed';
16
21
  this.details = options.details;
17
22
  }
18
23
  }
@@ -23,17 +28,19 @@ export function isAssistantPluginError(error: unknown): error is AssistantPlugin
23
28
 
24
29
  export function toAssistantPluginError(
25
30
  error: unknown,
26
- fallback: { code: string; message: string; retryable?: boolean; details?: Record<string, unknown> },
31
+ fallback: { code: string; message: string; retryable?: boolean; effectOutcome?: AssistantPluginEffectOutcome; details?: Record<string, unknown> },
27
32
  ): AssistantPluginError {
28
33
  if (isAssistantPluginError(error)) return error;
29
34
  if (error instanceof Error) {
30
35
  return new AssistantPluginError(fallback.code, error.message, {
31
36
  retryable: fallback.retryable,
37
+ effectOutcome: fallback.effectOutcome,
32
38
  details: fallback.details,
33
39
  });
34
40
  }
35
41
  return new AssistantPluginError(fallback.code, fallback.message, {
36
42
  retryable: fallback.retryable,
43
+ effectOutcome: fallback.effectOutcome,
37
44
  details: fallback.details,
38
45
  });
39
46
  }
@@ -1,9 +1,12 @@
1
- import { createHash } from 'crypto';
2
1
  import { AssistantPluginError } from './errors';
3
2
  import { getExternalPluginRegistration, listExternalPluginRegistrations, type ExternalPluginRegistration } from './external-registration';
4
3
  import { callExternalUnixSocket, probeExternalUnixSocketSync, type ExternalUnixSocketCallOptions } from './external-unix-socket';
5
4
  import { executeManagedPluginProcess, executeManagedPluginProcessSync, type ManagedPluginProcessSpec } from './managed-process-adapter';
6
5
  import { activateAndVerifyFrontmostApplication, restartVerifiedUserLaunchAgent, startVerifiedUserLaunchAgent, stopVerifiedUserLaunchAgent } from './local-system-adapter';
6
+ import {
7
+ resolveExternalProviderPolicy,
8
+ type ExternalProviderPolicyContext,
9
+ } from './external-provider-policy';
7
10
  import type { AssistantPluginActionDescriptor, AssistantPluginAdapter, AssistantPluginAuthorizationContext, AssistantPluginCapability, AssistantPluginHealth, AssistantPluginManifest, AssistantPluginPermissionScope } from './types';
8
11
 
9
12
  interface ProviderManifest {
@@ -61,9 +64,10 @@ function parseProviderManifest(value: Record<string, unknown>, registration: Ext
61
64
  if (manifest.protocolVersion !== registration.protocolVersion) throw providerError('EXTERNAL_PLUGIN_PROTOCOL_MISMATCH', `Expected provider protocol ${registration.protocolVersion}, received ${manifest.protocolVersion || 'unknown'}.`);
62
65
  if (manifest.scope !== registration.scope) throw providerError('EXTERNAL_PLUGIN_SCOPE_MISMATCH', `Expected provider scope ${registration.scope}, received ${manifest.scope || 'unknown'}.`);
63
66
  if (manifest.provider !== registration.provider) throw providerError('EXTERNAL_PLUGIN_PROVIDER_MISMATCH', `Expected provider ${registration.provider}, received ${manifest.provider || 'unknown'}.`);
67
+ const providerPolicy = resolveExternalProviderPolicy(registration);
64
68
  const missingActions = registration.actions
65
69
  .map((action) => action.actionId)
66
- .filter((actionId) => !(registration.pluginId === 'desktop_operator' && ['desktop_pointer_click', 'desktop_foreground_pointer_click'].includes(actionId)))
70
+ .filter((actionId) => !(providerPolicy?.allowsMissingProviderAction?.(actionId) ?? false))
67
71
  .filter((actionId) => !manifest.actions.includes(actionId));
68
72
  if (missingActions.length > 0) throw providerError('EXTERNAL_PLUGIN_ACTION_MISMATCH', `Provider is missing registered actions: ${missingActions.join(', ')}.`);
69
73
  return manifest;
@@ -205,199 +209,51 @@ function externalProviderAuthorizationContext(registration: ExternalPluginRegist
205
209
  };
206
210
  }
207
211
 
208
- function desktopApplicationAuthorizationContext(
212
+ async function resolveExternalAuthorizationContext(
209
213
  registration: ExternalPluginRegistration,
210
- stableApplicationId: string,
211
- ): AssistantPluginAuthorizationContext {
212
- const normalized = stableApplicationId.trim();
213
- return {
214
- target: {
215
- kind: 'desktop-application',
216
- id: normalized,
217
- identityFingerprint: createHash('sha256')
218
- .update(`${registration.registrationFingerprint}\0${normalized}`)
219
- .digest('hex'),
220
- },
221
- expiresInMinutes: 30 * 24 * 60,
222
- };
223
- }
224
-
225
- function recordArray(value: unknown): Record<string, unknown>[] {
226
- return Array.isArray(value)
227
- ? value.filter((entry): entry is Record<string, unknown> => Boolean(entry) && typeof entry === 'object' && !Array.isArray(entry))
228
- : [];
229
- }
230
-
231
- function firstString(record: Record<string, unknown>, ...keys: string[]): string {
232
- for (const key of keys) {
233
- const value = record[key];
234
- if (typeof value === 'string' && value.trim()) return value.trim();
235
- }
236
- return '';
237
- }
238
-
239
- function firstNumber(record: Record<string, unknown>, ...keys: string[]): number | undefined {
240
- for (const key of keys) {
241
- const value = record[key];
242
- if (typeof value === 'number' && Number.isFinite(value)) return value;
243
- }
244
- return undefined;
245
- }
246
-
247
- function desktopSession(status: Record<string, unknown>, interactionId: string): Record<string, unknown> | undefined {
248
- return recordArray(status.sessions).find((session) => firstString(session, 'interactionId', 'interaction_id') === interactionId);
249
- }
250
-
251
- async function independentlyEnsureExactFrontmostDesktopApplication(
252
- bundleId: string,
253
- appName: string,
214
+ input: Parameters<NonNullable<AssistantPluginAdapter['resolveAuthorizationContext']>>[0],
254
215
  dependencies: ExternalPluginAdapterDependencies,
255
- ): Promise<void> {
256
- const activateAndVerify = dependencies.activateAndVerifyFrontmostApplication ?? activateAndVerifyFrontmostApplication;
257
- const proof = await activateAndVerify({ bundleId: bundleId || undefined, appName: appName || undefined });
258
- const proofBundleId = typeof proof.bundleId === 'string' ? proof.bundleId.trim() : '';
259
- const proofAppName = typeof proof.appName === 'string' ? proof.appName.trim() : '';
260
- const proofMatches = bundleId ? proofBundleId === bundleId : proofAppName === appName;
261
- if (proof.activated !== true || proof.verified !== true || !proofMatches) {
262
- throw new AssistantPluginError(
263
- 'DESKTOP_ACTIVATION_FALLBACK_IDENTITY_MISMATCH',
264
- `Forge did not prove the exact requested application ${bundleId || appName} as frontmost.`,
265
- { retryable: true, details: { target: { bundleId, appName }, observed: { bundleId: proofBundleId, appName: proofAppName } } },
266
- );
216
+ ): Promise<AssistantPluginAuthorizationContext | undefined> {
217
+ if (EXTERNAL_PROVIDER_LIFECYCLE_ACTIONS.has(input.actionId)) {
218
+ return externalProviderAuthorizationContext(registration);
267
219
  }
220
+ const providerPolicy = resolveExternalProviderPolicy(registration);
221
+ if (!providerPolicy?.resolveAuthorizationContext) return undefined;
222
+ return await providerPolicy.resolveAuthorizationContext(
223
+ registration,
224
+ input,
225
+ externalProviderPolicyContext(registration, dependencies),
226
+ );
268
227
  }
269
228
 
270
- async function openVerifiedDesktopSession(
229
+ function externalProviderPolicyContext(
271
230
  registration: ExternalPluginRegistration,
272
- requestId: string,
273
- args: Record<string, unknown>,
274
- timeoutMs: number | undefined,
275
- signal: AbortSignal | undefined,
276
231
  dependencies: ExternalPluginAdapterDependencies,
277
- ): Promise<Record<string, unknown>> {
278
- const bundleId = typeof args.bundle_id === 'string' ? args.bundle_id.trim() : '';
279
- const appName = typeof args.app_name === 'string' ? args.app_name.trim() : '';
280
- if (!bundleId && !appName) {
281
- throw providerError('DESKTOP_ACTIVATION_TARGET_UNAVAILABLE', 'Activated desktop sessions require an exact bundle id or application name.');
282
- }
283
-
284
- let result: Record<string, unknown>;
285
- let providerActivationError: AssistantPluginError | undefined;
286
- try {
287
- result = await callProvider(
232
+ ): ExternalProviderPolicyContext {
233
+ return {
234
+ callProvider: (requestId, actionId, args, timeoutMs, signal) => callProvider(
288
235
  registration,
289
236
  requestId,
290
- 'desktop_session_open',
237
+ actionId,
291
238
  args,
292
239
  timeoutMs,
293
240
  signal,
294
241
  dependencies,
295
- );
296
- } catch (error) {
297
- if (!(error instanceof AssistantPluginError) || error.code !== 'APP_ACTIVATION_FAILED') throw error;
298
- providerActivationError = error;
299
- result = await callProvider(
300
- registration,
301
- `${requestId}:fallback-session`,
302
- 'desktop_session_open',
303
- { ...(bundleId ? { bundle_id: bundleId } : { app_name: appName }), launch: false, activate: false },
304
- timeoutMs,
305
- signal,
306
- dependencies,
307
- );
308
- }
309
-
310
- try {
311
- await independentlyEnsureExactFrontmostDesktopApplication(bundleId, appName, dependencies);
312
- } catch (verificationError) {
313
- const wrappedCode = providerActivationError ? 'DESKTOP_ACTIVATION_FALLBACK_FAILED' : 'DESKTOP_ACTIVATION_NOT_CONFIRMED';
314
- const wrappedMessage = providerActivationError
315
- ? `Desktop Operator activation failed and Forge could not independently verify ${bundleId || appName} as frontmost.`
316
- : `Desktop Operator returned an activated session, but Forge could not independently verify ${bundleId || appName} as frontmost.`;
317
- if (verificationError instanceof AssistantPluginError) {
318
- throw new AssistantPluginError(wrappedCode, wrappedMessage, {
319
- retryable: verificationError.retryable,
320
- details: {
321
- ...(providerActivationError ? { providerErrorCode: providerActivationError.code } : {}),
322
- verificationErrorCode: verificationError.code,
323
- verificationErrorMessage: verificationError.message,
324
- target: bundleId || appName,
325
- },
326
- });
327
- }
328
- throw new AssistantPluginError(wrappedCode, wrappedMessage, {
329
- retryable: true,
330
- details: {
331
- ...(providerActivationError ? { providerErrorCode: providerActivationError.code } : {}),
332
- verificationErrorMessage: String(verificationError),
333
- target: bundleId || appName,
334
- },
335
- });
336
- }
337
-
338
- return result;
339
- }
340
-
341
- async function resolveExternalAuthorizationContext(
342
- registration: ExternalPluginRegistration,
343
- input: Parameters<NonNullable<AssistantPluginAdapter['resolveAuthorizationContext']>>[0],
344
- dependencies: ExternalPluginAdapterDependencies,
345
- ): Promise<AssistantPluginAuthorizationContext | undefined> {
346
- if (EXTERNAL_PROVIDER_LIFECYCLE_ACTIONS.has(input.actionId)) {
347
- return externalProviderAuthorizationContext(registration);
348
- }
349
- if (registration.pluginId !== 'desktop_operator') return undefined;
350
- if (input.actionId === 'desktop_permissions_request') {
351
- return externalProviderAuthorizationContext(registration);
352
- }
353
- if (input.actionId === 'desktop_session_open') {
354
- const bundleId = typeof input.args.bundle_id === 'string' ? input.args.bundle_id.trim() : '';
355
- return bundleId ? desktopApplicationAuthorizationContext(registration, bundleId) : undefined;
356
- }
357
-
358
- const interactionId = typeof input.args.interaction_id === 'string' ? input.args.interaction_id.trim() : '';
359
- if (!interactionId) return undefined;
360
-
361
- const providerManifest = await callProvider(
362
- registration,
363
- `${input.requestId}:authorization-target:manifest`,
364
- 'manifest',
365
- {},
366
- undefined,
367
- input.signal,
368
- dependencies,
369
- );
370
- parseProviderManifest(providerManifest, registration);
371
- const status = await callProvider(
372
- registration,
373
- `${input.requestId}:authorization-target:desktop-status`,
374
- 'desktop_status',
375
- { limit: 500 },
376
- input.timeoutMs,
377
- input.signal,
378
- dependencies,
379
- );
380
- const sessions = Array.isArray(status.sessions) ? status.sessions : [];
381
- const session = sessions.find((entry) => {
382
- if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return false;
383
- const record = entry as Record<string, unknown>;
384
- const id = typeof record.interactionId === 'string' ? record.interactionId : typeof record.interaction_id === 'string' ? record.interaction_id : '';
385
- return id === interactionId;
386
- }) as Record<string, unknown> | undefined;
387
- if (!session) {
388
- throw providerError('EXTERNAL_PLUGIN_AUTHORIZATION_TARGET_UNAVAILABLE', `Desktop session ${interactionId} was not found while resolving its stable authorization target.`, false);
389
- }
390
- const bundleId = typeof session.bundleIdentifier === 'string' ? session.bundleIdentifier.trim()
391
- : typeof session.bundle_identifier === 'string' ? session.bundle_identifier.trim()
392
- : '';
393
- const appName = typeof session.appName === 'string' ? session.appName.trim()
394
- : typeof session.app_name === 'string' ? session.app_name.trim()
395
- : '';
396
- const stableApplicationId = bundleId || (appName ? `name:${appName.toLowerCase()}` : '');
397
- if (!stableApplicationId) {
398
- throw providerError('EXTERNAL_PLUGIN_AUTHORIZATION_TARGET_UNAVAILABLE', `Desktop session ${interactionId} has no stable application identity.`, false);
399
- }
400
- return desktopApplicationAuthorizationContext(registration, stableApplicationId);
242
+ ),
243
+ verifyProviderIdentity: async (requestId, signal) => {
244
+ const providerManifest = await callProvider(
245
+ registration,
246
+ requestId,
247
+ 'manifest',
248
+ {},
249
+ undefined,
250
+ signal,
251
+ dependencies,
252
+ );
253
+ parseProviderManifest(providerManifest, registration);
254
+ },
255
+ activateAndVerifyFrontmostApplication: dependencies.activateAndVerifyFrontmostApplication ?? activateAndVerifyFrontmostApplication,
256
+ };
401
257
  }
402
258
 
403
259
  export function getExternalPluginAdapter(controllerHome: string, pluginId: string): AssistantPluginAdapter | undefined {
@@ -422,6 +278,7 @@ export function createExternalPluginAdapter(
422
278
  return {
423
279
  pluginId: registration.pluginId,
424
280
  scope: registration.scope,
281
+ exposure: registration.exposure === 'provider' ? 'internal' : 'product',
425
282
  resolveAuthorizationContext: (input) => resolveExternalAuthorizationContext(registration, input, dependencies),
426
283
  buildManifest(previousRevision = 0, previousUpdatedAt?: string): AssistantPluginManifest {
427
284
  const checkedAt = now().toISOString();
@@ -517,149 +374,15 @@ export function createExternalPluginAdapter(
517
374
  );
518
375
  parseProviderManifest(providerManifest, registration);
519
376
  }
520
- if (registration.pluginId === 'desktop_operator' && input.actionId === 'desktop_foreground_pointer_click') {
521
- const sourceInteractionId = typeof input.args.interaction_id === 'string' ? input.args.interaction_id.trim() : '';
522
- const requestedWindowId = typeof input.args.window_id === 'number' && Number.isInteger(input.args.window_id) ? input.args.window_id : undefined;
523
- const x = typeof input.args.x === 'number' && Number.isFinite(input.args.x) ? input.args.x : undefined;
524
- const y = typeof input.args.y === 'number' && Number.isFinite(input.args.y) ? input.args.y : undefined;
525
- if (!sourceInteractionId || !requestedWindowId || x === undefined || y === undefined) {
526
- throw providerError('DESKTOP_FOREGROUND_POINTER_ARGUMENT_INVALID', 'desktop_foreground_pointer_click requires interaction_id, window_id, x, and y.');
527
- }
528
-
529
- const sourceStatus = await callProvider(
530
- registration,
531
- `${input.requestId}:source-status`,
532
- 'desktop_status',
533
- { limit: 500 },
534
- input.timeoutMs,
535
- input.signal,
536
- dependencies,
537
- );
538
- const sourceSession = desktopSession(sourceStatus, sourceInteractionId);
539
- if (!sourceSession) {
540
- throw providerError('DESKTOP_FOREGROUND_POINTER_SESSION_NOT_FOUND', `Desktop session ${sourceInteractionId} is no longer available.`, true);
541
- }
542
- const bundleId = firstString(sourceSession, 'bundleIdentifier', 'bundle_id');
543
- const appName = firstString(sourceSession, 'appName', 'app_name');
544
- if (!bundleId && !appName) {
545
- throw providerError('DESKTOP_FOREGROUND_POINTER_TARGET_UNAVAILABLE', `Desktop session ${sourceInteractionId} has no stable application identity.`);
546
- }
547
-
548
- const activation = await openVerifiedDesktopSession(
549
- registration,
550
- `${input.requestId}:activate`,
551
- { ...(bundleId ? { bundle_id: bundleId } : { app_name: appName }), launch: false, activate: true },
552
- input.timeoutMs,
553
- input.signal,
554
- dependencies,
555
- );
556
- const activationInteractionId = firstString(activation, 'interactionId', 'interaction_id');
557
- if (!activationInteractionId) {
558
- throw providerError('DESKTOP_ACTIVATION_SESSION_MISSING', 'Desktop Operator activated the application without returning a bound interaction session.', true);
559
- }
560
-
561
- const screenshot = await callProvider(
562
- registration,
563
- `${input.requestId}:screenshot`,
564
- 'desktop_screenshot',
565
- {
566
- interaction_id: activationInteractionId,
567
- scope: 'window',
568
- window_id: requestedWindowId,
569
- ...(typeof input.args.label === 'string' && input.args.label.trim() ? { label: input.args.label.trim() } : {}),
570
- },
571
- input.timeoutMs,
572
- input.signal,
573
- dependencies,
574
- );
575
- const visualRevision = firstNumber(screenshot, 'visual_revision', 'visualRevision');
576
- const capturedWindowId = firstNumber(screenshot, 'windowId', 'window_id') ?? requestedWindowId;
577
- if (!visualRevision || !capturedWindowId) {
578
- throw providerError('DESKTOP_FOREGROUND_CAPTURE_INVALID', 'Desktop Operator did not return a fresh visual revision for the foreground window.', true);
579
- }
580
-
581
- const click = await callProvider(
582
- registration,
583
- `${input.requestId}:click`,
584
- 'desktop_pointer_click',
585
- {
586
- interaction_id: activationInteractionId,
587
- window_id: capturedWindowId,
588
- visual_revision: visualRevision,
589
- x,
590
- y,
591
- },
592
- input.timeoutMs,
593
- input.signal,
594
- dependencies,
595
- );
596
- return {
597
- interactionId: activationInteractionId,
598
- activationVerified: true,
599
- windowId: capturedWindowId,
600
- visualRevision,
601
- screenshot,
602
- click,
603
- };
604
- }
605
-
606
- if (registration.pluginId === 'desktop_operator' && input.actionId === 'desktop_key') {
607
- const sourceInteractionId = typeof input.args.interaction_id === 'string' ? input.args.interaction_id.trim() : '';
608
- const keys = Array.isArray(input.args.keys) ? input.args.keys : [];
609
- if (!sourceInteractionId || keys.length === 0) {
610
- throw providerError('DESKTOP_FOREGROUND_KEY_ARGUMENT_INVALID', 'desktop_key requires interaction_id and at least one key.');
611
- }
612
- const sourceStatus = await callProvider(
613
- registration,
614
- `${input.requestId}:source-status`,
615
- 'desktop_status',
616
- { limit: 500 },
617
- input.timeoutMs,
618
- input.signal,
619
- dependencies,
620
- );
621
- const sourceSession = desktopSession(sourceStatus, sourceInteractionId);
622
- if (!sourceSession) {
623
- throw providerError('DESKTOP_FOREGROUND_KEY_SESSION_NOT_FOUND', `Desktop session ${sourceInteractionId} is no longer available.`, true);
624
- }
625
- const bundleId = firstString(sourceSession, 'bundleIdentifier', 'bundle_id');
626
- const appName = firstString(sourceSession, 'appName', 'app_name');
627
- if (!bundleId && !appName) {
628
- throw providerError('DESKTOP_FOREGROUND_KEY_TARGET_UNAVAILABLE', `Desktop session ${sourceInteractionId} has no stable application identity.`);
629
- }
630
- const activation = await openVerifiedDesktopSession(
631
- registration,
632
- `${input.requestId}:activate`,
633
- { ...(bundleId ? { bundle_id: bundleId } : { app_name: appName }), launch: false, activate: true },
634
- input.timeoutMs,
635
- input.signal,
636
- dependencies,
637
- );
638
- const activationInteractionId = firstString(activation, 'interactionId', 'interaction_id');
639
- if (!activationInteractionId) {
640
- throw providerError('DESKTOP_ACTIVATION_SESSION_MISSING', 'Desktop Operator activated the application without returning a bound interaction session.', true);
641
- }
642
- return await callProvider(
643
- registration,
644
- `${input.requestId}:key`,
645
- 'desktop_key',
646
- { interaction_id: activationInteractionId, keys },
647
- input.timeoutMs,
648
- input.signal,
649
- dependencies,
377
+ const providerPolicy = resolveExternalProviderPolicy(registration);
378
+ if (providerPolicy?.executeAction) {
379
+ const policyResult = await providerPolicy.executeAction(
380
+ input,
381
+ externalProviderPolicyContext(registration, dependencies),
650
382
  );
383
+ if (policyResult.handled) return policyResult.result ?? {};
651
384
  }
652
385
 
653
- if (registration.pluginId === 'desktop_operator' && input.actionId === 'desktop_session_open' && input.args.activate === true) {
654
- return await openVerifiedDesktopSession(
655
- registration,
656
- input.requestId,
657
- input.args,
658
- input.timeoutMs,
659
- input.signal,
660
- dependencies,
661
- );
662
- }
663
386
  return await callProvider(
664
387
  registration,
665
388
  input.requestId,