@moretea-labs/forge 1.7.2 → 1.8.1

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 (900) hide show
  1. package/AGENTS.md +121 -62
  2. package/CHANGELOG.md +40 -0
  3. package/CLAUDE.md +57 -62
  4. package/CONTRIBUTING.md +3 -2
  5. package/README.md +2 -2
  6. package/SKILL.md +0 -1
  7. package/THIRD_PARTY_NOTICES.md +5 -2
  8. package/adapters/browser/index.ts +2 -0
  9. package/adapters/chatgpt/browser-delivery-host.ts +77 -0
  10. package/adapters/chatgpt/browser-delivery-runtime.ts +1256 -0
  11. package/adapters/chatgpt/controller-binding-store.ts +134 -0
  12. package/adapters/chatgpt/controller-round-host.ts +68 -0
  13. package/adapters/chatgpt/controller-round-settlement-store.ts +99 -0
  14. package/adapters/chatgpt/provider-delivery.ts +340 -0
  15. package/adapters/chatgpt/work-conversation-binding-store.ts +218 -0
  16. package/adapters/chatgpt/wsl-bridge-delivery-host.ts +63 -0
  17. package/adapters/computer/chatgpt-extension-target.ts +463 -0
  18. package/adapters/computer/chatgpt-target-router.ts +103 -0
  19. package/adapters/computer/chrome-extension/background.js +385 -0
  20. package/adapters/computer/chrome-extension/content.js +378 -0
  21. package/adapters/computer/chrome-extension/core.js +24 -0
  22. package/adapters/computer/chrome-extension/manifest.json +30 -0
  23. package/adapters/computer/desktop-operator-contract.ts +7 -0
  24. package/adapters/computer/desktop-operator-discovery.ts +181 -0
  25. package/adapters/computer/desktop-operator-negotiation.ts +174 -0
  26. package/adapters/computer/desktop-operator-provider.ts +312 -0
  27. package/adapters/computer/index.ts +1 -0
  28. package/adapters/computer/interaction-target-authority.ts +1068 -0
  29. package/adapters/controller-process/binding-store.ts +34 -0
  30. package/adapters/controller-process/controller-host.ts +26 -0
  31. package/adapters/mcp/access-mode.ts +132 -0
  32. package/adapters/mcp/audit.ts +32 -0
  33. package/adapters/mcp/auth.ts +406 -0
  34. package/adapters/mcp/instructions.ts +37 -0
  35. package/adapters/mcp/legacy-context.ts +18 -0
  36. package/adapters/mcp/multi-repository.ts +421 -0
  37. package/adapters/mcp/oauth.ts +464 -0
  38. package/adapters/mcp/paths.ts +143 -0
  39. package/adapters/mcp/policy.ts +232 -0
  40. package/adapters/mcp/proxy-env.ts +62 -0
  41. package/adapters/mcp/readiness-projection.ts +24 -0
  42. package/adapters/mcp/redaction.ts +21 -0
  43. package/adapters/mcp/repo.ts +24 -0
  44. package/adapters/mcp/runtime-gateway/artifact-adapter.ts +52 -0
  45. package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +87 -0
  46. package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
  47. package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
  48. package/adapters/mcp/runtime-gateway/context-adapter.ts +1167 -0
  49. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
  50. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +206 -0
  51. package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
  52. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +130 -0
  53. package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
  54. package/adapters/mcp/runtime-gateway/execution-control-adapter.ts +28 -0
  55. package/adapters/mcp/runtime-gateway/execution-tools.ts +173 -0
  56. package/adapters/mcp/runtime-gateway/filesystem-adapter.ts +38 -0
  57. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +412 -0
  58. package/adapters/mcp/runtime-gateway/legacy-ios-tool-adapter.ts +105 -0
  59. package/adapters/mcp/runtime-gateway/maintenance-adapter.ts +44 -0
  60. package/adapters/mcp/runtime-gateway/model-adapter.ts +63 -0
  61. package/adapters/mcp/runtime-gateway/persisted-check-process.ts +3 -0
  62. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +380 -0
  63. package/adapters/mcp/runtime-gateway/process-tools.ts +457 -0
  64. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +88 -0
  65. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +285 -0
  66. package/adapters/mcp/runtime-gateway/recovery-client-adapter.ts +70 -0
  67. package/adapters/mcp/runtime-gateway/recovery-tool-contract.ts +99 -0
  68. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +79 -0
  69. package/adapters/mcp/runtime-gateway/result-adapter.ts +114 -0
  70. package/adapters/mcp/runtime-gateway/router.ts +242 -0
  71. package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
  72. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1200 -0
  73. package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
  74. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +574 -0
  75. package/adapters/mcp/runtime-gateway/runtime-tool-shared.ts +27 -0
  76. package/adapters/mcp/runtime-gateway/runtime-tools.ts +78 -0
  77. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +187 -0
  78. package/adapters/mcp/runtime-gateway/shared-adapter.ts +45 -0
  79. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +962 -0
  80. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
  81. package/adapters/mcp/runtime-gateway/work-adapter.ts +325 -0
  82. package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
  83. package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
  84. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
  85. package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
  86. package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
  87. package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
  88. package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
  89. package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
  90. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
  91. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +1 -0
  92. package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
  93. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
  94. package/adapters/mcp/server.ts +1092 -0
  95. package/adapters/mcp/setup.ts +789 -0
  96. package/adapters/mcp/tool-capability-cache.ts +87 -0
  97. package/adapters/mcp/tool-mapping/access-tools.ts +387 -0
  98. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +5139 -0
  99. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +145 -0
  100. package/adapters/mcp/tool-mapping/repository-tools.ts +1682 -0
  101. package/adapters/mcp/tool-mapping/tools.ts +9 -0
  102. package/adapters/mcp/tool-mapping/umbrella-tools.ts +117 -0
  103. package/adapters/mcp/toolset-names.ts +79 -0
  104. package/adapters/mcp/toolset-selection.ts +41 -0
  105. package/adapters/mcp/toolset.ts +337 -0
  106. package/adapters/mcp/transports/http-observation.ts +365 -0
  107. package/adapters/mcp/transports/http.ts +933 -0
  108. package/adapters/mcp/transports/oauth-http.ts +322 -0
  109. package/adapters/mcp/transports/session-registry.ts +519 -0
  110. package/adapters/mcp/transports/stdio.ts +8 -0
  111. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +223 -0
  112. package/adapters/mcp/types.ts +41 -0
  113. package/assets/AGENTS.md +2 -16
  114. package/assets/CLAUDE.md +2 -16
  115. package/assets/hooks/AGENTS.md +3 -14
  116. package/assets/hooks/CLAUDE.md +3 -14
  117. package/assets/hooks/hook-input.sh +9 -2
  118. package/assets/hooks/lib/workflow-state.sh +28 -10
  119. package/assets/hooks/prompt-guard.sh +63 -37
  120. package/assets/hooks/security-sentinel.sh +2 -1
  121. package/assets/hooks/session-start-context.sh +7 -5
  122. package/assets/hooks/stop-orchestrator.sh +13 -3
  123. package/assets/initializer-question-pack.v4.json +11 -7
  124. package/assets/partials/05-workflow.partial.md +18 -73
  125. package/assets/partials/07-footer.partial.md +1 -1
  126. package/assets/partials-agents/02-operating-mode.partial.md +1 -2
  127. package/assets/partials-agents/04-task-protocol.partial.md +14 -59
  128. package/assets/partials-agents/06-quality-safety.partial.md +11 -16
  129. package/assets/partials-agents/08-deep-docs.partial.md +1 -2
  130. package/assets/plan-map.json +11 -11
  131. package/assets/plugin-registry.v1.json +11 -3
  132. package/assets/plugin-trust-policy.v1.json +6 -0
  133. package/assets/recovery/ForgeRecovery.ps1 +100 -0
  134. package/assets/recovery/forge-wsl-rescue +271 -0
  135. package/assets/reference-configs/agentic-development-flow.md +25 -0
  136. package/assets/reference-configs/development-protocol.md +11 -15
  137. package/assets/reference-configs/document-generation.md +1 -1
  138. package/assets/reference-configs/global-working-rules.md +28 -1
  139. package/assets/reference-configs/harness-overview.md +22 -112
  140. package/assets/reference-configs/hook-operations.md +1 -1
  141. package/assets/reference-configs/sprint-contracts.md +2 -2
  142. package/assets/skill-version.json +2 -2
  143. package/assets/templates/helpers/architecture-event.ts +3 -34
  144. package/assets/templates/helpers/architecture-queue.sh +61 -10
  145. package/assets/templates/helpers/archive-workflow.sh +90 -180
  146. package/assets/templates/helpers/capability-config.ts +8 -11
  147. package/assets/templates/helpers/capability-resolver.ts +37 -19
  148. package/assets/templates/helpers/capture-plan.sh +2 -2
  149. package/assets/templates/helpers/check-architecture-sync.sh +1 -9
  150. package/assets/templates/helpers/check-task-sync.sh +82 -11
  151. package/assets/templates/helpers/check-task-workflow.sh +1 -3
  152. package/assets/templates/helpers/context-contract-sync.sh +1 -12
  153. package/assets/templates/helpers/contract-worktree.sh +26 -24
  154. package/assets/templates/helpers/ensure-task-workflow.sh +6 -8
  155. package/assets/templates/helpers/inspect-project-state.ts +1 -1
  156. package/assets/templates/helpers/migrate-project-template.sh +1 -1
  157. package/assets/templates/helpers/migrate-workflow-docs.ts +53 -239
  158. package/assets/templates/helpers/new-plan.sh +2 -2
  159. package/assets/templates/helpers/plan-to-todo.sh +3 -31
  160. package/assets/templates/helpers/sprint-backlog.sh +1 -1
  161. package/assets/templates/helpers/switch-plan.sh +1 -1
  162. package/assets/templates/helpers/workflow-contract.ts +1 -0
  163. package/assets/workflow-contract.v1.json +63 -171
  164. package/assets/workflows/xiaohongshu/xiaohongshu.collect-metrics.v1.draft.json +118 -0
  165. package/assets/workflows/xiaohongshu/xiaohongshu.publish-image-note.v1.draft.json +316 -0
  166. package/assets/workflows/xiaohongshu/xiaohongshu.publish-long-text.v1.draft.json +324 -0
  167. package/docs/architecture/CURRENT.md +233 -28
  168. package/docs/architecture/EVOLUTION.md +13 -0
  169. package/docs/architecture/decisions/20260801-controller-home-sqlite-state.md +2 -1
  170. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
  171. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
  172. package/docs/architecture/decisions/20260831-independent-windows-wsl-host-rescue.md +59 -0
  173. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +120 -0
  174. package/docs/architecture/decisions/20260904-repository-runtime-data-boundary.md +42 -0
  175. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +37 -0
  176. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +311 -0
  177. package/docs/architecture/decisions/20260907-maintenance-diagnosis-bounded-read.md +39 -0
  178. package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
  179. package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
  180. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
  181. package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
  182. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
  183. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
  184. package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
  185. package/docs/architecture/domains/verification.md +8 -0
  186. package/docs/architecture/domains/workflow-engine.md +7 -1
  187. package/docs/architecture/index.md +3 -3
  188. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +19 -8
  189. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +124 -0
  190. package/docs/forge-chatgpt-mcp-setup.md +5 -3
  191. package/docs/forge-plugin-management.md +20 -4
  192. package/docs/forge-runtime-self-healing-loop.md +2 -0
  193. package/docs/operations/benchmark-cross-version-freeze.md +38 -0
  194. package/docs/operations/controller-browser-plugin.md +3 -1
  195. package/docs/operations/controller-performance-and-502.md +17 -0
  196. package/docs/operations/controller-reliability-runbook.md +2 -2
  197. package/docs/operations/features.md +1 -1
  198. package/docs/operations/features.zh-CN.md +1 -1
  199. package/docs/operations/homebrew.md +2 -2
  200. package/docs/operations/mcp-tool-exposure.md +2 -0
  201. package/docs/operations/platform-support.md +16 -8
  202. package/docs/operations/platform-support.zh-CN.md +2 -2
  203. package/docs/operations/releasing.md +2 -0
  204. package/docs/operations/standalone-disaster-recovery.md +38 -5
  205. package/docs/operations/uu-remote-rescue.md +41 -0
  206. package/docs/operations/windows-wsl-host-rescue.md +133 -0
  207. package/docs/public-usage-guide.md +1 -1
  208. package/docs/public-usage-guide.zh-CN.md +1 -1
  209. package/docs/tutorials/01-install-and-start.md +1 -1
  210. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  211. package/docs/tutorials/02-connect-chatgpt.md +4 -4
  212. package/docs/tutorials/02-connect-chatgpt.zh-CN.md +4 -4
  213. package/docs/wiki/Implementation.md +1 -1
  214. package/package.json +46 -26
  215. package/packages/kernel/cognition/api/index.ts +6 -0
  216. package/packages/kernel/cognition/application/activation-service.ts +451 -0
  217. package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
  218. package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
  219. package/packages/kernel/cognition/application/memory-service.ts +64 -0
  220. package/packages/kernel/cognition/domain/learning.ts +106 -0
  221. package/packages/kernel/cognition/domain/memory.ts +254 -0
  222. package/packages/kernel/controller/api/index.ts +3 -0
  223. package/packages/kernel/controller/application/continuation-service.ts +281 -0
  224. package/packages/kernel/controller/application/controller-round-service.ts +41 -0
  225. package/packages/kernel/controller/application/controller-service.ts +30 -0
  226. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +529 -0
  227. package/packages/kernel/controller/domain/controller-round.ts +110 -0
  228. package/packages/kernel/controller/domain/execution-quality.ts +135 -0
  229. package/packages/kernel/controller/domain/types.ts +56 -0
  230. package/packages/kernel/controller/index.ts +1 -0
  231. package/packages/kernel/controller/infrastructure/controller-binding-store.ts +84 -0
  232. package/packages/kernel/controller/infrastructure/controller-round-store.ts +1970 -0
  233. package/packages/kernel/controller/infrastructure/controller-session-store.ts +804 -0
  234. package/packages/kernel/controller/ports/controller-host.ts +18 -0
  235. package/packages/kernel/goal/api/index.ts +1 -0
  236. package/packages/kernel/goal/domain/types.ts +40 -0
  237. package/packages/kernel/goal/index.ts +1 -0
  238. package/packages/kernel/identity/api/index.ts +15 -0
  239. package/packages/kernel/identity/application/identity-service.ts +67 -0
  240. package/packages/kernel/identity/domain/activity-projection.ts +43 -0
  241. package/packages/kernel/identity/domain/capability-broker.ts +60 -0
  242. package/packages/kernel/identity/domain/grant.ts +72 -0
  243. package/packages/kernel/identity/domain/owned-resource.ts +116 -0
  244. package/packages/kernel/identity/domain/scope.ts +63 -0
  245. package/packages/kernel/identity/domain/semantic-sync.ts +81 -0
  246. package/packages/kernel/identity/domain/types.ts +44 -0
  247. package/packages/kernel/identity/domain/user-request.ts +93 -0
  248. package/packages/kernel/identity/domain/workspace.ts +56 -0
  249. package/packages/kernel/identity/index.ts +1 -0
  250. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
  251. package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
  252. package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
  253. package/packages/kernel/identity/infrastructure/identity-store.ts +75 -0
  254. package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
  255. package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
  256. package/packages/kernel/memory/api/index.ts +5 -0
  257. package/packages/kernel/memory/application/experience-service.ts +118 -0
  258. package/packages/kernel/memory/application/outcome-service.ts +77 -0
  259. package/packages/kernel/memory/domain/experience.ts +103 -0
  260. package/packages/kernel/memory/domain/operational-prior.ts +92 -0
  261. package/packages/kernel/memory/index.ts +1 -0
  262. package/packages/kernel/scheduler/api/index.ts +4 -0
  263. package/packages/kernel/scheduler/application/eligibility.ts +252 -0
  264. package/packages/kernel/scheduler/application/schedule-service.ts +27 -0
  265. package/packages/kernel/scheduler/application/settlement.ts +182 -0
  266. package/packages/kernel/scheduler/domain/schedule.ts +236 -0
  267. package/packages/kernel/scheduler/index.ts +1 -0
  268. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +805 -0
  269. package/packages/kernel/work/api/index.ts +16 -0
  270. package/packages/kernel/work/application/work-service.ts +123 -0
  271. package/packages/kernel/work/domain/check-receipt.ts +43 -0
  272. package/packages/kernel/work/domain/context-closure-receipt.ts +32 -0
  273. package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
  274. package/packages/kernel/work/domain/engineering-contracts.ts +157 -0
  275. package/packages/kernel/work/domain/engineering-design.ts +286 -0
  276. package/packages/kernel/work/domain/engineering-profile.ts +238 -0
  277. package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
  278. package/packages/kernel/work/domain/execution-concurrency.ts +247 -0
  279. package/packages/kernel/work/domain/execution-snapshot.ts +2 -0
  280. package/packages/kernel/work/domain/implementation-review.ts +193 -0
  281. package/packages/kernel/work/domain/objective-graph.ts +119 -0
  282. package/packages/kernel/work/domain/project-engineering-contract.ts +224 -0
  283. package/packages/kernel/work/domain/repository-completion-receipt.ts +73 -0
  284. package/{src/runtime/control-plane/facade/work-state-machine.ts → packages/kernel/work/domain/state-machine.ts} +37 -66
  285. package/packages/kernel/work/domain/types.ts +534 -0
  286. package/packages/kernel/work/index.ts +1 -0
  287. package/packages/kernel/work/infrastructure/work-contract-store.ts +1967 -0
  288. package/packages/kernel/work/ports/work-contract-store.ts +21 -0
  289. package/packages/plugin-runtime/browser/index.ts +3 -0
  290. package/packages/plugin-runtime/browser/provider-registry.ts +110 -0
  291. package/packages/plugin-runtime/browser/runtime-contract.ts +150 -0
  292. package/packages/plugin-runtime/browser/session-authority.ts +62 -0
  293. package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
  294. package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
  295. package/packages/plugin-runtime/computer/index.ts +8 -0
  296. package/packages/plugin-runtime/computer/provider-error.ts +26 -0
  297. package/packages/plugin-runtime/computer/provider-registration.ts +52 -0
  298. package/packages/plugin-runtime/computer/provider-registry.ts +63 -0
  299. package/packages/plugin-runtime/computer/provider.ts +19 -0
  300. package/packages/plugin-runtime/computer/target-authority.ts +215 -0
  301. package/packages/plugin-runtime/computer/target-persistence.ts +54 -0
  302. package/packages/plugin-runtime/external/index.ts +1 -0
  303. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +581 -0
  304. package/packages/plugin-runtime/index.ts +3 -0
  305. package/packages/protocols/browser/index.ts +1 -0
  306. package/packages/protocols/browser/session.ts +98 -0
  307. package/packages/protocols/computer/contract.ts +225 -0
  308. package/packages/protocols/computer/index.ts +1 -0
  309. package/packages/protocols/failure/contract.ts +158 -0
  310. package/packages/protocols/failure/index.ts +1 -0
  311. package/packages/protocols/handoff/index.ts +1 -0
  312. package/packages/protocols/handoff/status.ts +22 -0
  313. package/packages/protocols/mcp/execution-context.ts +11 -0
  314. package/packages/protocols/mcp/index.ts +2 -0
  315. package/packages/protocols/mcp/tool-contract.ts +42 -0
  316. package/packages/workflow-runtime/api/index.ts +2 -0
  317. package/packages/workflow-runtime/application/interpreter.ts +342 -0
  318. package/packages/workflow-runtime/domain/workflow-asset.ts +223 -0
  319. package/packages/workflow-runtime/index.ts +1 -0
  320. package/scripts/activate-source-baseline.ts +7 -9
  321. package/scripts/assemble-template.ts +1 -1
  322. package/scripts/bootstrap-runtime-maintenance-recovery.sh +4 -1
  323. package/scripts/canary-chatgpt-provider-delivery.ts +97 -0
  324. package/scripts/canary-controller-semantic-wait.ts +183 -0
  325. package/scripts/canary-global-hook.sh +2 -2
  326. package/scripts/check-mcp-compatibility.ts +85 -7
  327. package/scripts/check-platform-support.mjs +28 -2
  328. package/scripts/check-public-docs.sh +1 -1
  329. package/scripts/check-repository-hygiene.mjs +92 -0
  330. package/scripts/check-runtime-architecture.mjs +1643 -127
  331. package/scripts/check-source-duplication.mjs +9 -1
  332. package/scripts/controller-ngrok-rotation.sh +5 -4
  333. package/scripts/create-project-dirs.sh +10 -74
  334. package/scripts/forge-local-recovery-helper.mjs +282 -0
  335. package/scripts/forge-uu-remote-rescue-helper.d.mts +31 -0
  336. package/scripts/forge-uu-remote-rescue-helper.mjs +409 -0
  337. package/scripts/forge-windows-host-recovery-helper.mjs +136 -0
  338. package/scripts/hook-shim.sh +2 -2
  339. package/scripts/init-project.sh +12 -70
  340. package/scripts/install-desktop-operator-registration.ts +4 -2
  341. package/scripts/install-independent-windows-wsl-recovery.ts +125 -0
  342. package/scripts/install-standalone-recovery.ts +122 -10
  343. package/scripts/install-uu-remote-rescue-registration.ts +74 -0
  344. package/scripts/install-windows-host-recovery-registration.ts +22 -0
  345. package/scripts/lib/controller-home-env.sh +6 -3
  346. package/scripts/lib/project-init-lib.sh +42 -582
  347. package/scripts/migrate-chatgpt-automation-schedules.ts +2 -2
  348. package/scripts/migrate-windows-wsl-controller-home.ts +306 -0
  349. package/scripts/open-source-audit-allowlist.txt +11 -1
  350. package/scripts/portability-bindings.mjs +70 -0
  351. package/scripts/run-bounded-command.mjs +60 -0
  352. package/scripts/run-bun-test-file.ts +22 -6
  353. package/scripts/run-governed-gate.ts +4 -2
  354. package/scripts/run-mobile-monitor-bridge.ts +0 -1
  355. package/scripts/smoke-control-plane-failure-domain.ts +94 -0
  356. package/scripts/smoke-mcp-http-runtime.ts +6 -1
  357. package/scripts/smoke-runtime-recovery.ts +13 -11
  358. package/scripts/smoke-schedule-engine.ts +24 -16
  359. package/scripts/smoke-unattended-transport-recovery.ts +223 -0
  360. package/scripts/smoke-user-request-continuation-restart.ts +232 -0
  361. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
  362. package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
  363. package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
  364. package/scripts/smoke-workflow-supervisor.ts +103 -0
  365. package/scripts/test-governance.ts +51 -2
  366. package/scripts/verify-forge-runtime.sh +2 -1
  367. package/src/cli/agent-jobs/executor-health.ts +11 -34
  368. package/src/cli/agent-jobs/integration.ts +18 -49
  369. package/src/cli/agent-jobs/job-manager.ts +17 -4
  370. package/src/cli/chatgpt-browser/bind-server.ts +2 -1
  371. package/src/cli/chatgpt-browser/binding.ts +20 -10
  372. package/src/cli/chatgpt-browser/bridge-extension.ts +75 -0
  373. package/src/cli/chatgpt-browser/bridge-provider.ts +376 -11
  374. package/src/cli/chatgpt-browser/engine.ts +10 -11
  375. package/src/cli/chatgpt-browser/native-provider.ts +24 -83
  376. package/src/cli/chatgpt-browser/oracle-provider.ts +5 -3
  377. package/src/cli/chatgpt-browser/types.ts +1 -0
  378. package/src/cli/commands/bootstrap-control.ts +334 -0
  379. package/src/cli/commands/brain-assistant.ts +52 -0
  380. package/src/cli/commands/brain.ts +191 -40
  381. package/src/cli/commands/chatgpt.ts +32 -67
  382. package/src/cli/commands/computer.ts +437 -0
  383. package/src/cli/commands/doctor.ts +18 -1
  384. package/src/cli/commands/init-hook.ts +71 -61
  385. package/src/cli/commands/init.ts +3 -1
  386. package/src/cli/commands/mcp.ts +16 -10
  387. package/src/cli/commands/plugin.ts +38 -12
  388. package/src/cli/commands/recovery.ts +507 -80
  389. package/src/cli/commands/runtime.ts +12 -7
  390. package/src/cli/commands/setup-profile.ts +97 -39
  391. package/src/cli/commands/status.ts +2 -1
  392. package/src/cli/controller/check-runner.ts +500 -100
  393. package/src/cli/controller/completion-backlog.ts +3 -3
  394. package/src/cli/controller/completion-orchestrator.ts +4 -43
  395. package/src/cli/controller/completion-target.ts +3 -72
  396. package/src/cli/controller/context/source-materializer.ts +81 -100
  397. package/src/cli/controller/context/types.ts +7 -1
  398. package/src/cli/controller/context-pack.ts +28 -6
  399. package/src/cli/controller/execution-completion.ts +4 -7
  400. package/src/cli/controller/execution-policy.ts +36 -153
  401. package/src/cli/controller/governance.ts +2 -3
  402. package/src/cli/controller/issue-store.ts +4 -99
  403. package/src/cli/controller/launch-agents.ts +59 -18
  404. package/src/cli/controller/operational-plan.ts +24 -51
  405. package/src/cli/controller/runtime-config.ts +5 -1
  406. package/src/cli/controller/stuck-state-migration.ts +2 -3
  407. package/src/cli/controller/systemd-user.ts +148 -0
  408. package/src/cli/controller/types.ts +10 -70
  409. package/src/cli/controller/worklog.ts +67 -13
  410. package/src/cli/editing/edit-operation-contract.ts +92 -0
  411. package/src/cli/editing/edit-session.ts +290 -20
  412. package/src/cli/github/plugin.ts +17 -12
  413. package/src/cli/hook/route-registry.ts +3 -5
  414. package/src/cli/hook/runtime.ts +49 -3
  415. package/src/cli/index.ts +3 -0
  416. package/src/cli/local-bridge/connector-freshness.ts +2 -2
  417. package/src/cli/local-bridge/console-automations.ts +20 -15
  418. package/src/cli/local-bridge/console-view-models.ts +3 -12
  419. package/src/cli/local-bridge/facade-api.ts +105 -205
  420. package/src/cli/local-bridge/job-store.ts +1 -1
  421. package/src/cli/local-bridge/server.ts +48 -174
  422. package/src/cli/local-bridge/types.ts +0 -1
  423. package/src/cli/mcp/access-mode.ts +2 -132
  424. package/src/cli/mcp/access-tools.ts +2 -387
  425. package/src/cli/mcp/audit.ts +2 -32
  426. package/src/cli/mcp/auth.ts +2 -404
  427. package/src/cli/mcp/instructions.ts +2 -34
  428. package/src/cli/mcp/legacy-context.ts +2 -16
  429. package/src/cli/mcp/legacy-tool-service.ts +2 -5308
  430. package/src/cli/mcp/multi-repository.ts +2 -436
  431. package/src/cli/mcp/oauth-client-retirement.ts +74 -0
  432. package/src/cli/mcp/oauth.ts +2 -375
  433. package/src/cli/mcp/openai-secure-tunnel.ts +2 -0
  434. package/src/cli/mcp/paths.ts +2 -140
  435. package/src/cli/mcp/policy.ts +2 -232
  436. package/src/cli/mcp/post-finalize-work-attribution.ts +2 -150
  437. package/src/cli/mcp/proxy-env.ts +2 -62
  438. package/src/cli/mcp/readiness-projection.ts +2 -24
  439. package/src/cli/mcp/redaction.ts +2 -21
  440. package/src/cli/mcp/repo.ts +2 -24
  441. package/src/cli/mcp/repository-tools.ts +2 -1613
  442. package/src/cli/mcp/server.ts +2 -951
  443. package/src/cli/mcp/setup.ts +2 -737
  444. package/src/cli/mcp/tool-capability-cache.ts +2 -87
  445. package/src/cli/mcp/tool-contract.ts +2 -14
  446. package/src/cli/mcp/tools.ts +2 -9
  447. package/src/cli/mcp/toolset-names.ts +2 -70
  448. package/src/cli/mcp/toolset-selection.ts +2 -41
  449. package/src/cli/mcp/toolset.ts +2 -336
  450. package/src/cli/mcp/transports/AGENTS.md +1 -10
  451. package/src/cli/mcp/transports/CLAUDE.md +1 -10
  452. package/src/cli/mcp/transports/http.ts +2 -1414
  453. package/src/cli/mcp/transports/session-registry.ts +2 -490
  454. package/src/cli/mcp/transports/stdio.ts +2 -8
  455. package/src/cli/mcp/types.ts +2 -41
  456. package/src/cli/mcp/umbrella-tools.ts +2 -117
  457. package/src/cli/repositories/command-executor.ts +91 -39
  458. package/src/cli/repositories/command-scope.ts +139 -4
  459. package/src/cli/repositories/controller-home.ts +167 -1
  460. package/src/cli/repositories/ephemeral-workspace.ts +20 -30
  461. package/src/cli/repositories/git-command-executor.ts +2 -2
  462. package/src/cli/repositories/identity.ts +13 -0
  463. package/src/cli/repositories/registry.ts +145 -60
  464. package/src/cli/repositories/repository-snapshot.ts +53 -7
  465. package/src/cli/repositories/runtime-storage.ts +27 -2
  466. package/src/cli/repositories/safe-patch.ts +34 -38
  467. package/src/cli/repositories/selected-path-actions.ts +22 -2
  468. package/src/cli/repositories/structured-git.ts +167 -27
  469. package/src/cli/repository/session-cache.ts +92 -6
  470. package/src/cli/runtime/helper-runner.ts +7 -0
  471. package/src/cli/runtime-invocation.ts +8 -1
  472. package/src/cli/tools/codegraph.ts +44 -25
  473. package/src/core/adoption/manifest-templates.ts +1 -1
  474. package/src/core/adoption/plan.ts +3 -26
  475. package/src/core/adoption/workflow-contract-plan.ts +17 -9
  476. package/src/effects/process-runner.ts +8 -14
  477. package/src/runtime/context/assistant-context.ts +167 -0
  478. package/src/runtime/context/assistant-work-context.ts +209 -0
  479. package/src/runtime/context/automatic-learning.ts +565 -0
  480. package/src/runtime/context/codegraph-cache-boundary.ts +255 -0
  481. package/src/runtime/context/codegraph-read-provider.ts +55 -22
  482. package/src/runtime/context/codegraph-sidecar.cjs +8 -1
  483. package/src/runtime/context/cognitive-attention.ts +173 -0
  484. package/src/runtime/context/cognitive-skill-canary.ts +158 -0
  485. package/src/runtime/context/context-closure.ts +305 -0
  486. package/src/runtime/context/context-pack-process.ts +103 -0
  487. package/src/runtime/context/context-plane.ts +203 -0
  488. package/src/runtime/context/direct-controller-learning.ts +298 -0
  489. package/src/runtime/context/project-engineering-contract.ts +60 -0
  490. package/src/runtime/context/semantic-navigation-contract.ts +9 -0
  491. package/src/runtime/context/semantic-navigation.ts +6 -34
  492. package/src/runtime/context/typescript-navigation-process.ts +145 -0
  493. package/src/runtime/context/typescript-navigation.ts +89 -3
  494. package/src/runtime/control-plane/bootstrap/capability-provider.ts +74 -0
  495. package/src/runtime/control-plane/bootstrap/control-api.ts +57 -0
  496. package/src/runtime/control-plane/bootstrap/index.ts +5 -0
  497. package/src/runtime/control-plane/bootstrap/state-machine.ts +141 -0
  498. package/src/runtime/control-plane/bootstrap/store.ts +21 -0
  499. package/src/runtime/control-plane/bootstrap/types.ts +87 -0
  500. package/src/runtime/control-plane/cleanup-artifact-retention.ts +531 -0
  501. package/src/runtime/control-plane/codegraph-cache-retention.ts +164 -0
  502. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +282 -0
  503. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +380 -0
  504. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +113 -16
  505. package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
  506. package/src/runtime/control-plane/execution/implementation-review-content.ts +95 -0
  507. package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
  508. package/src/runtime/control-plane/execution/retained-work-resume.ts +439 -102
  509. package/src/runtime/control-plane/execution/session-store.ts +31 -1
  510. package/src/runtime/control-plane/execution/validation.ts +34 -11
  511. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +87 -0
  512. package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
  513. package/src/runtime/control-plane/execution/work-completion-authority.ts +31 -44
  514. package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
  515. package/src/runtime/control-plane/execution/work-evidence-policy.ts +46 -53
  516. package/src/runtime/control-plane/execution/work-execution-support.ts +85 -164
  517. package/src/runtime/control-plane/execution/work-handle-authority.ts +349 -73
  518. package/src/runtime/control-plane/execution/work-handle-store.ts +55 -2
  519. package/src/runtime/control-plane/execution/work-head-settlement.ts +108 -0
  520. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +173 -28
  521. package/src/runtime/control-plane/execution/work-operation-service.ts +92 -40
  522. package/src/runtime/control-plane/execution/work-preparation-service.ts +145 -269
  523. package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
  524. package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
  525. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +543 -225
  526. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +59 -45
  527. package/src/runtime/control-plane/execution/work-verification-context.ts +1 -1
  528. package/src/runtime/control-plane/execution/work-verification-service.ts +662 -52
  529. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +205 -16
  530. package/src/runtime/control-plane/facade/capability-registry.ts +380 -44
  531. package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
  532. package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
  533. package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
  534. package/src/runtime/control-plane/facade/controller-session-store.ts +2 -488
  535. package/src/runtime/control-plane/facade/goal-workloop-access.ts +6 -22
  536. package/src/runtime/control-plane/facade/goal-workloop.ts +565 -1202
  537. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +145 -0
  538. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +266 -52
  539. package/src/runtime/control-plane/facade/index.ts +4 -3
  540. package/src/runtime/control-plane/facade/operation-digest.ts +34 -73
  541. package/src/runtime/control-plane/facade/plan-contract-store.ts +671 -245
  542. package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
  543. package/src/runtime/control-plane/facade/repository-work-admission.ts +31 -23
  544. package/src/runtime/control-plane/facade/requirement-authority.ts +121 -0
  545. package/src/runtime/control-plane/facade/requirement-board.ts +9 -4
  546. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +85 -0
  547. package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
  548. package/src/runtime/control-plane/facade/semantic-admission.ts +8 -16
  549. package/src/runtime/control-plane/facade/suggested-actions.ts +15 -15
  550. package/src/runtime/control-plane/facade/types.ts +218 -620
  551. package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
  552. package/src/runtime/control-plane/facade/work-contract-store.ts +2 -1043
  553. package/src/runtime/control-plane/generated-cache-retention.ts +336 -19
  554. package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
  555. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +13 -2
  556. package/src/runtime/control-plane/global-scheduler/maintenance.ts +274 -84
  557. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-entry.ts +55 -0
  558. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-process.ts +98 -0
  559. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -2
  560. package/src/runtime/control-plane/global-scheduler/scheduler-worker-entry.ts +10 -0
  561. package/src/runtime/control-plane/global-scheduler/scheduler.ts +227 -109
  562. package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
  563. package/src/runtime/control-plane/global-scheduler/worker-launch.ts +18 -6
  564. package/src/runtime/control-plane/governance/access-policy.ts +19 -2
  565. package/src/runtime/control-plane/governance/authorization.ts +20 -3
  566. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +160 -0
  567. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +2 -177
  568. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +139 -670
  569. package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
  570. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +25 -6
  571. package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -194
  572. package/src/runtime/control-plane/lifecycle-retention-metrics.ts +60 -0
  573. package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
  574. package/src/runtime/control-plane/persistence/experience-store.ts +302 -0
  575. package/src/runtime/control-plane/persistence/operational-prior-store.ts +348 -0
  576. package/src/runtime/control-plane/persistence/requirement-store.ts +230 -80
  577. package/src/runtime/control-plane/persistence/sqlite-store.ts +654 -78
  578. package/src/runtime/control-plane/persistence/workflow-content-store.ts +98 -0
  579. package/src/runtime/control-plane/persistence/workflow-registry-store.ts +186 -0
  580. package/src/runtime/control-plane/persistence/workflow-run-store.ts +123 -0
  581. package/src/runtime/control-plane/release-retention.ts +154 -26
  582. package/src/runtime/control-plane/repository-namespace-retention.ts +208 -0
  583. package/src/runtime/control-plane/runtime-cleanup.ts +844 -38
  584. package/src/runtime/control-plane/runtime-generation.ts +6 -0
  585. package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
  586. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +479 -0
  587. package/src/runtime/control-plane/workspace/workspace-store.ts +249 -0
  588. package/src/runtime/diagnostics/incident-repair.ts +573 -0
  589. package/src/runtime/diagnostics/mcp-timing.ts +239 -6
  590. package/src/runtime/diagnostics/performance.ts +6 -14
  591. package/src/runtime/diagnostics/read-only-tool.ts +1 -1
  592. package/src/runtime/evidence/artifact-store.ts +216 -35
  593. package/src/runtime/evidence/evidence-store.ts +112 -8
  594. package/src/runtime/evidence/operational-shadow.ts +38 -0
  595. package/src/runtime/evidence/output-handle-index.ts +225 -0
  596. package/src/runtime/evidence/process-check-receipt.ts +5 -43
  597. package/src/runtime/evidence/result-store.ts +158 -44
  598. package/src/runtime/evidence/sensitive-output.ts +4 -4
  599. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -1
  600. package/src/runtime/execution/jobs/store.ts +124 -6
  601. package/src/runtime/execution/managed-workspace.ts +112 -5
  602. package/src/runtime/execution/process-runtime/canary.ts +19 -5
  603. package/src/runtime/execution/process-runtime/check-classification.ts +48 -0
  604. package/src/runtime/execution/process-runtime/check-facade.ts +24 -10
  605. package/src/runtime/execution/process-runtime/check-receipt.ts +1 -1
  606. package/src/runtime/execution/process-runtime/check-result-retention.ts +132 -0
  607. package/src/runtime/execution/process-runtime/check-result.ts +177 -2
  608. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +58 -9
  609. package/src/runtime/execution/process-runtime/check-storage.ts +187 -0
  610. package/src/runtime/execution/process-runtime/command-facade.ts +117 -114
  611. package/src/runtime/execution/process-runtime/gc.ts +15 -2
  612. package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
  613. package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
  614. package/src/runtime/execution/process-runtime/index.ts +4 -0
  615. package/src/runtime/execution/process-runtime/interactive-admission.ts +2 -1
  616. package/src/runtime/execution/process-runtime/lightweight-managed.ts +283 -73
  617. package/src/runtime/execution/process-runtime/persisted-check.ts +130 -23
  618. package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
  619. package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
  620. package/src/runtime/execution/process-runtime/resource-claims.ts +125 -64
  621. package/src/runtime/execution/process-runtime/runtime.ts +167 -17
  622. package/src/runtime/execution/process-runtime/store.ts +30 -2
  623. package/src/runtime/execution/process-runtime/types.ts +27 -0
  624. package/src/runtime/execution/workers/executor.ts +18 -19
  625. package/src/runtime/execution/workers/worker-entry.ts +1 -1
  626. package/src/runtime/gateway/mcp/execution-tools.ts +2 -207
  627. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +2 -61
  628. package/src/runtime/gateway/mcp/persisted-check-process.ts +2 -3
  629. package/src/runtime/gateway/mcp/process-tools.ts +2 -289
  630. package/src/runtime/gateway/mcp/router.ts +2 -1125
  631. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +2 -565
  632. package/src/runtime/gateway/mcp/runtime-tools.ts +2 -6655
  633. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +2 -1
  634. package/src/runtime/maintenance/cleanup.ts +38 -24
  635. package/src/runtime/platform/browser-product-discovery.ts +174 -0
  636. package/src/runtime/platform/computer-platform.ts +14 -0
  637. package/src/runtime/platform/executable-discovery.ts +54 -0
  638. package/src/runtime/platform/fetch-http-server.ts +90 -0
  639. package/src/runtime/platform/service-inventory.ts +130 -0
  640. package/src/runtime/platform/service-manager.ts +146 -0
  641. package/src/runtime/platform/windows-host-discovery.ts +118 -0
  642. package/src/runtime/platform/windows-recovery-deployment.ts +67 -0
  643. package/src/runtime/plugins/action-application.ts +192 -0
  644. package/src/runtime/plugins/app-store-connect-adapter.ts +47 -35
  645. package/src/runtime/plugins/browser-adapter.ts +898 -135
  646. package/src/runtime/plugins/browser-automation-service.ts +33 -34
  647. package/src/runtime/plugins/browser-macos-bridge.ts +386 -46
  648. package/src/runtime/plugins/browser-manifest-surface.ts +75 -17
  649. package/src/runtime/plugins/browser-native-session-service.ts +64 -14
  650. package/src/runtime/plugins/browser-provider-registry.ts +2 -109
  651. package/src/runtime/plugins/browser-registration.ts +32 -0
  652. package/src/runtime/plugins/browser-runtime-contract.ts +2 -154
  653. package/src/runtime/plugins/browser-runtime.ts +55 -10
  654. package/src/runtime/plugins/browser-session-authority.ts +101 -291
  655. package/src/runtime/plugins/browser-session-legacy-migration.ts +203 -0
  656. package/src/runtime/plugins/browser-session-store.ts +243 -80
  657. package/src/runtime/plugins/browser-session-types.ts +2 -98
  658. package/src/runtime/plugins/capability-authorization-grants.ts +272 -59
  659. package/src/runtime/plugins/catalog-trust.ts +82 -0
  660. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
  661. package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
  662. package/src/runtime/plugins/computer-registration.ts +1050 -0
  663. package/src/runtime/plugins/config-store.ts +119 -0
  664. package/src/runtime/plugins/desktop-operator-external-policy.ts +964 -0
  665. package/src/runtime/plugins/desktop-operator-registration.ts +123 -12
  666. package/src/runtime/plugins/errors.ts +8 -1
  667. package/src/runtime/plugins/external-adapter.ts +82 -323
  668. package/src/runtime/plugins/external-provider-policy.ts +48 -0
  669. package/src/runtime/plugins/external-registration.ts +30 -2
  670. package/src/runtime/plugins/external-unix-socket-probe.cjs +9 -3
  671. package/src/runtime/plugins/external-unix-socket.ts +64 -193
  672. package/src/runtime/plugins/first-party-external-registration.ts +163 -0
  673. package/src/runtime/plugins/first-party-registry.ts +3 -1
  674. package/src/runtime/plugins/github-adapter.ts +1 -2
  675. package/src/runtime/plugins/gmail-adapter.ts +29 -8
  676. package/src/runtime/plugins/google-calendar-adapter.ts +8 -8
  677. package/src/runtime/plugins/google-shared.ts +45 -53
  678. package/src/runtime/plugins/google-tasks-adapter.ts +8 -8
  679. package/src/runtime/plugins/ios-adapter.ts +2 -3
  680. package/src/runtime/plugins/lightweight-action.ts +208 -2
  681. package/src/runtime/plugins/local-system-adapter.ts +192 -2
  682. package/src/runtime/plugins/macos-capability-broker.ts +15 -105
  683. package/src/runtime/plugins/managed-process-adapter.ts +12 -5
  684. package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
  685. package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
  686. package/src/runtime/plugins/resend-adapter.ts +15 -24
  687. package/src/runtime/plugins/store.ts +1003 -387
  688. package/src/runtime/plugins/types.ts +28 -1
  689. package/src/runtime/plugins/uu-remote-rescue-registration.ts +155 -0
  690. package/src/runtime/plugins/windows-host-recovery-install.ts +68 -0
  691. package/src/runtime/plugins/windows-host-recovery-registration.ts +85 -0
  692. package/src/runtime/plugins/xiaohongshu-publish.ts +102 -430
  693. package/src/runtime/projections/controller-context.ts +12 -6
  694. package/src/runtime/projections/git-status-sampler.ts +73 -22
  695. package/src/runtime/projections/invalidation.ts +7 -3
  696. package/src/runtime/projections/materialized-view.ts +93 -43
  697. package/src/runtime/recovery/actions.ts +3 -3
  698. package/src/runtime/recovery/capability-action-application.ts +229 -0
  699. package/src/runtime/recovery/index.ts +3 -0
  700. package/src/runtime/recovery/lifecycle-inventory.ts +338 -0
  701. package/src/runtime/recovery/local-jobs-repair.ts +14 -14
  702. package/src/runtime/recovery/maintenance-executor.ts +701 -168
  703. package/src/runtime/recovery/quarantine-retention.ts +256 -0
  704. package/src/runtime/recovery/store.ts +29 -11
  705. package/src/runtime/release/identity.ts +6 -0
  706. package/src/runtime/release/release-coordinator.ts +296 -0
  707. package/src/runtime/release/release-session.ts +716 -0
  708. package/src/runtime/release/release-state-migration.ts +25 -0
  709. package/src/runtime/resources/leases/store.ts +56 -25
  710. package/src/runtime/root/active-execution-power-assertion.ts +139 -0
  711. package/src/runtime/root/assistant-learning-loop.ts +45 -0
  712. package/src/runtime/root/browser-session-composition.ts +59 -0
  713. package/src/runtime/root/computer-composition.ts +376 -0
  714. package/src/runtime/root/computer-target-composition.ts +16 -0
  715. package/src/runtime/root/computer-target-persistence.ts +39 -0
  716. package/src/runtime/root/controller-progression-composition.ts +192 -0
  717. package/src/runtime/root/controller-round-composition.ts +126 -0
  718. package/src/runtime/root/controller-services.ts +2 -0
  719. package/src/runtime/root/deployment-topology.ts +106 -0
  720. package/src/runtime/root/entry.ts +8 -6
  721. package/src/runtime/root/gateway-adapter.ts +3 -3
  722. package/src/runtime/root/known-good-recovery.ts +184 -0
  723. package/src/runtime/root/local-bridge.ts +5 -3
  724. package/src/runtime/root/mcp-transport.ts +116 -23
  725. package/src/runtime/root/ownership.ts +261 -9
  726. package/src/runtime/root/package-connector-service.ts +212 -74
  727. package/src/runtime/root/package-runtime-release.ts +199 -33
  728. package/src/runtime/root/package-runtime-service.ts +77 -108
  729. package/src/runtime/root/release-execution-canary.ts +103 -0
  730. package/src/runtime/root/release-loader.ts +150 -0
  731. package/src/runtime/root/release-manifest.ts +185 -7
  732. package/src/runtime/root/release-materialize.ts +474 -31
  733. package/src/runtime/root/release-store.ts +425 -37
  734. package/src/runtime/root/runtime-lane.ts +191 -0
  735. package/src/runtime/root/runtime.ts +379 -32
  736. package/src/runtime/root/scheduled-controller-composition.ts +76 -0
  737. package/src/runtime/root/scheduler.ts +12 -4
  738. package/src/runtime/root/service-runner.ts +3 -3
  739. package/src/runtime/root/service.ts +73 -45
  740. package/src/runtime/root/status.ts +49 -0
  741. package/src/runtime/root/types.ts +55 -3
  742. package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
  743. package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
  744. package/src/runtime/root/write-fence.ts +50 -2
  745. package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
  746. package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
  747. package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
  748. package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
  749. package/src/runtime/shared/local-bridge-surface.ts +1 -1
  750. package/src/runtime/shared/process-environment.ts +36 -10
  751. package/src/runtime/shared/response-budget.ts +1 -3
  752. package/src/runtime/shared/storage-capacity.ts +68 -0
  753. package/src/runtime/standalone-recovery/controller-home-migration.ts +1108 -0
  754. package/src/runtime/standalone-recovery/core.ts +4609 -495
  755. package/src/runtime/standalone-recovery/entry.ts +642 -81
  756. package/src/runtime/standalone-recovery/independent-host-rescue.ts +172 -0
  757. package/src/runtime/standalone-recovery/installer.ts +399 -177
  758. package/src/runtime/standalone-recovery/mcp-server.ts +79 -0
  759. package/src/runtime/standalone-recovery/mutation-identity-contract.ts +21 -0
  760. package/src/runtime/standalone-recovery/operation-lock.ts +160 -0
  761. package/src/runtime/standalone-recovery/performance.ts +173 -0
  762. package/src/runtime/standalone-recovery/release.ts +58 -5
  763. package/src/runtime/standalone-recovery/service-labels.ts +5 -2
  764. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
  765. package/src/runtime/watchdog/workflow-watchdog.ts +1 -1
  766. package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
  767. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +11 -4
  768. package/src/runtime/workflow/schedules/engine.ts +298 -484
  769. package/src/runtime/workflow/schedules/pending-activation.ts +1 -1
  770. package/src/runtime/workflow/schedules/settlement.ts +2 -191
  771. package/src/runtime/workflow/schedules/store.ts +2 -607
  772. package/src/runtime/workflow/schedules/types.ts +2 -127
  773. package/src/runtime/workflow/schedules/work-continuation.ts +220 -16
  774. package/src/runtime/workflows/first-party/xiaohongshu.ts +122 -0
  775. package/src/runtime/workflows/runtime.ts +482 -0
  776. package/src/testing/test-governance.ts +95 -30
  777. package/supervisor/chatgpt-conversation.ts +23 -0
  778. package/supervisor/client.ts +201 -0
  779. package/supervisor/control-plane.ts +868 -0
  780. package/supervisor/entry.ts +15 -0
  781. package/supervisor/forge-validators.ts +80 -0
  782. package/supervisor/index.ts +5 -0
  783. package/supervisor/native-browser-adapter.ts +786 -0
  784. package/supervisor/native-messaging/host.ts +39 -0
  785. package/supervisor/native-messaging/manifest.ts +26 -0
  786. package/supervisor/native-messaging/protocol.ts +27 -0
  787. package/supervisor/paths.ts +18 -0
  788. package/supervisor/protocol.ts +202 -0
  789. package/supervisor/server.ts +404 -0
  790. package/supervisor/store.ts +1451 -0
  791. package/supervisor/tsconfig.json +8 -0
  792. package/supervisor/types.ts +255 -0
  793. package/assets/templates/helpers/archive-architecture-request.sh +0 -244
  794. package/docs/architecture/history/README.md +0 -7
  795. package/docs/architecture/history/chatgpt-handoff-facade.md +0 -397
  796. package/docs/architecture/history/global-hook-runtime.md +0 -166
  797. package/docs/architecture/history/ios-semantic-automation-provider-v2.md +0 -170
  798. package/docs/architecture/requests/archive/2026/20260528-154740-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  799. package/docs/architecture/requests/archive/2026/20260528-154816-assets-hooks-assets-hooks-hook-input-sh.md +0 -59
  800. package/docs/architecture/requests/archive/2026/20260528-161851-ai-harness-workflow-contract-json-ai-harness-workflow-contract-json.md +0 -59
  801. package/docs/architecture/requests/archive/2026/20260528-161853-scripts-check-task-workflow-sh-scripts-check-task-workflow-sh.md +0 -59
  802. package/docs/architecture/requests/archive/2026/20260528-161911-assets-workflow-contract-v1-json-assets-workflow-contract-v1-json.md +0 -59
  803. package/docs/architecture/requests/archive/2026/20260528-222416-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  804. package/docs/architecture/requests/archive/2026/20260528-222444-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  805. package/docs/architecture/requests/archive/2026/20260528-222457-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  806. package/docs/architecture/requests/archive/2026/20260528-222648-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  807. package/docs/architecture/requests/archive/2026/20260528-222705-ai-hooks-ai-hooks-worktree-guard-sh.md +0 -59
  808. package/docs/architecture/requests/archive/2026/20260528-222726-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  809. package/docs/architecture/requests/archive/2026/20260528-222727-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  810. package/docs/architecture/requests/archive/2026/20260528-224736-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  811. package/docs/architecture/requests/archive/2026/20260528-233259-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  812. package/docs/architecture/requests/archive/2026/20260528-233335-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  813. package/docs/architecture/requests/archive/2026/20260528-233456-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  814. package/docs/architecture/requests/archive/2026/20260528-233457-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  815. package/docs/architecture/requests/archive/2026/20260528-233637-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  816. package/docs/architecture/requests/archive/2026/20260528-233638-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  817. package/docs/architecture/requests/archive/2026/20260529-000322-root-package-json.md +0 -59
  818. package/docs/architecture/requests/archive/2026/20260529-004238-ai-hooks-ai-hooks-lib-workflow-state-sh.md +0 -59
  819. package/docs/architecture/requests/archive/2026/20260529-020654-ai-harness-policy-json-ai-harness-policy-json.md +0 -63
  820. package/docs/architecture/requests/archive/2026/20260529-094236-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  821. package/docs/architecture/requests/archive/2026/20260529-094323-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  822. package/docs/architecture/requests/archive/2026/20260529-094331-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  823. package/docs/architecture/requests/archive/2026/20260529-094339-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  824. package/docs/architecture/requests/archive/2026/20260529-094430-assets-hooks-assets-hooks-session-start-context-sh.md +0 -60
  825. package/docs/architecture/requests/archive/2026/20260529-094446-ai-hooks-ai-hooks-session-start-context-sh.md +0 -60
  826. package/docs/architecture/requests/archive/2026/20260613-002040-runtime-harness-hook-adapters.md +0 -68
  827. package/docs/architecture/requests/archive/2026/root.md +0 -68
  828. package/docs/architecture/requests/archive/2026/runtime-harness-hook-adapters.md +0 -76
  829. package/docs/architecture/requests/archive/2026/verification-evals-checks.md +0 -68
  830. package/docs/architecture/requests/archive/2026/workflow-engine-contract-assets.md +0 -69
  831. package/scripts/archive-architecture-request.sh +0 -4
  832. package/scripts/benchmark-background-check-overlap.ts +0 -228
  833. package/scripts/benchmark-controller-hotpath.ts +0 -212
  834. package/scripts/benchmark-controller-round2.ts +0 -139
  835. package/scripts/benchmark-ios-agent-device.ts +0 -514
  836. package/scripts/benchmark-mcp-host.sh +0 -117
  837. package/scripts/benchmark-mcp-transport.ts +0 -170
  838. package/scripts/benchmark-quality-harness.ts +0 -146
  839. package/scripts/benchmark-route-session-concurrency.ts +0 -915
  840. package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
  841. package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
  842. package/scripts/benchmark-thin-harness.ts +0 -251
  843. package/scripts/benchmark-typescript-navigation.ts +0 -186
  844. package/scripts/benchmark-work-efficiency.ts +0 -334
  845. package/scripts/build-controller-ui.ts +0 -28
  846. package/scripts/check-npm-release.sh +0 -32
  847. package/scripts/check-public-release-surface.sh +0 -19
  848. package/scripts/check-release-published.sh +0 -57
  849. package/scripts/check-release-readiness.sh +0 -37
  850. package/scripts/check-release-version.mjs +0 -74
  851. package/scripts/check-tarball-install-smoke.sh +0 -67
  852. package/scripts/package-source-archive.sh +0 -147
  853. package/scripts/public-release-files.txt +0 -39
  854. package/scripts/public-release.ts +0 -174
  855. package/scripts/publish-release-tarball.sh +0 -27
  856. package/scripts/route-nl-vs-ts-eval.ts +0 -679
  857. package/scripts/run-skill-evals.ts +0 -1022
  858. package/scripts/stage-runtime-release.ts +0 -39
  859. package/src/cli/controller/progress.ts +0 -656
  860. package/src/cli/controller/work-mode.ts +0 -181
  861. package/src/cli/local-bridge/console-assets.ts +0 -17
  862. package/src/cli/local-bridge/dashboard.ts +0 -17
  863. package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
  864. package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
  865. package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
  866. package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
  867. package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
  868. package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
  869. package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
  870. package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
  871. package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
  872. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
  873. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
  874. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
  875. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
  876. package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
  877. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
  878. package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
  879. package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
  880. package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
  881. package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
  882. package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
  883. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
  884. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
  885. package/src/cli/local-bridge/frontend/src/styles.css +0 -28
  886. package/src/cli/local-bridge/frontend/src/types.ts +0 -15
  887. package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
  888. package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
  889. package/src/cli/local-bridge/ui-dist/app.css +0 -1
  890. package/src/cli/local-bridge/ui-dist/app.js +0 -11228
  891. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -385
  892. package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -1913
  893. package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
  894. package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -449
  895. package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -1118
  896. package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -93
  897. package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
  898. package/src/runtime/control-plane/routing/index.ts +0 -1
  899. package/src/runtime/control-plane/routing/route-policy.ts +0 -382
  900. package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
@@ -0,0 +1,1050 @@
1
+ import { createHash, randomUUID } from 'crypto';
2
+ import type {
3
+ ComputerApplicationLaunchProvenance,
4
+ ComputerApplicationTarget,
5
+ ComputerApplicationStableIdentity,
6
+ ComputerApplicationTargetLease,
7
+ } from '../../../packages/plugin-runtime/computer/target-authority';
8
+ import {
9
+ COMPUTER_CAPTURE_CAPABILITY,
10
+ COMPUTER_CONSOLE_UNLOCK_CAPABILITY,
11
+ COMPUTER_ELEMENT_ACTION_CAPABILITY,
12
+ COMPUTER_ELEMENT_OBSERVE_CAPABILITY,
13
+ COMPUTER_INPUT_CAPABILITY,
14
+ COMPUTER_OBSERVE_CAPABILITY,
15
+ type ComputerConsoleUnlockCommandRequest,
16
+ type ComputerConsoleUnlockPrepareRequest,
17
+ type ComputerConsoleUnlockRequest,
18
+ type ComputerElementSemanticAction,
19
+ type ComputerElementTarget,
20
+ type ComputerRuntimeExecutionRequest,
21
+ type ComputerSemanticSelector,
22
+ } from '../../../packages/protocols/computer/index';
23
+ import { executeRuntimeComputer, executeRuntimeComputerConsoleUnlock } from '../root/computer-composition';
24
+ import { runtimeComputerInteractionTargetAuthority } from '../root/computer-target-composition';
25
+ import { currentComputerPlatform } from '../platform/computer-platform';
26
+ import {
27
+ buildBrowserPluginManifest,
28
+ executeBrowserPluginAction,
29
+ resolveBrowserPluginAuthorizationContext,
30
+ } from './browser-adapter';
31
+ import { desktopOperatorActions } from './desktop-operator-registration';
32
+ import { getExternalPluginAdapter } from './external-adapter';
33
+ import { AssistantPluginError } from './errors';
34
+ import type {
35
+ AssistantPluginActionDescriptor,
36
+ AssistantPluginActionExecutionInput,
37
+ AssistantPluginAdapter,
38
+ AssistantPluginAuthorizationContext,
39
+ AssistantPluginBuildContext,
40
+ AssistantPluginCapability,
41
+ AssistantPluginManifest,
42
+ AssistantPluginPermissionScope,
43
+ } from './types';
44
+
45
+ const DESKTOP_PROVIDER_ID = 'desktop_operator';
46
+ const computerTargetAuthority = runtimeComputerInteractionTargetAuthority();
47
+ const DESKTOP_TARGET_OPEN_ACTION = 'desktop_target_open';
48
+ const DESKTOP_TARGET_CLOSE_ACTION = 'desktop_target_close';
49
+ const DESKTOP_ELEMENT_OBSERVE_ACTION = 'desktop_element_observe';
50
+ const DESKTOP_ELEMENT_ACTION_ACTION = 'desktop_element_action';
51
+ export const COMPUTER_CONSOLE_UNLOCK_PREPARE_ACTION = 'console_unlock_prepare';
52
+ export const COMPUTER_CONSOLE_UNLOCK_ACTION = 'console_unlock';
53
+ export const COMPUTER_CONSOLE_UNLOCK_ENROLL_ACTION = 'console_unlock_enroll';
54
+ export const COMPUTER_CONSOLE_UNLOCK_STATUS_ACTION = 'console_unlock_status';
55
+ export const COMPUTER_CONSOLE_UNLOCK_RECOVER_ACTION = 'console_unlock_recover';
56
+ export const COMPUTER_CONSOLE_UNLOCK_REVOKE_ACTION = 'console_unlock_revoke';
57
+ const DEFAULT_CONSOLE_UNLOCK_TIMEOUT_MS = 15_000;
58
+ const MAX_CONSOLE_UNLOCK_TIMEOUT_MS = 30_000;
59
+ const CONSOLE_CREDENTIAL_HANDLE_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
60
+ const COMPUTER_ELEMENT_SEMANTIC_ACTIONS = ['invoke', 'focus', 'set_value', 'toggle', 'expand', 'collapse', 'select', 'open', 'show_menu', 'scroll_page_down', 'scroll_page_up'] as const;
61
+ const DESKTOP_SEMANTIC_ACTION_IDS = new Set([
62
+ 'desktop_observe',
63
+ 'desktop_press',
64
+ 'desktop_select_rows',
65
+ 'desktop_type_text',
66
+ 'desktop_key',
67
+ 'desktop_open_url',
68
+ 'desktop_screenshot',
69
+ ]);
70
+ const DESKTOP_PRODUCT_ACTION_IDS = new Set([
71
+ DESKTOP_TARGET_OPEN_ACTION,
72
+ DESKTOP_TARGET_CLOSE_ACTION,
73
+ ...DESKTOP_SEMANTIC_ACTION_IDS,
74
+ DESKTOP_ELEMENT_OBSERVE_ACTION,
75
+ DESKTOP_ELEMENT_ACTION_ACTION,
76
+ COMPUTER_CONSOLE_UNLOCK_PREPARE_ACTION,
77
+ COMPUTER_CONSOLE_UNLOCK_ACTION,
78
+ COMPUTER_CONSOLE_UNLOCK_ENROLL_ACTION,
79
+ COMPUTER_CONSOLE_UNLOCK_STATUS_ACTION,
80
+ COMPUTER_CONSOLE_UNLOCK_RECOVER_ACTION,
81
+ COMPUTER_CONSOLE_UNLOCK_REVOKE_ACTION,
82
+ ]);
83
+
84
+ function providerActionDescriptor(actionId: string): AssistantPluginActionDescriptor {
85
+ const descriptor = desktopOperatorActions().find((action) => action.actionId === actionId);
86
+ if (!descriptor) throw new Error(`COMPUTER_DESKTOP_ACTION_DESCRIPTOR_MISSING: ${actionId}`);
87
+ return structuredClone(descriptor);
88
+ }
89
+
90
+ function targetBoundDescriptor(actionId: string): AssistantPluginActionDescriptor {
91
+ const descriptor = providerActionDescriptor(actionId);
92
+ const schema = structuredClone(descriptor.argumentsSchema) as Record<string, unknown>;
93
+ const properties = schema.properties && typeof schema.properties === 'object'
94
+ ? { ...(schema.properties as Record<string, unknown>) }
95
+ : {};
96
+ if ('interaction_id' in properties) {
97
+ delete properties.interaction_id;
98
+ properties.target_id = { type: 'string', description: 'Forge-owned durable Computer target id.' };
99
+ schema.properties = properties;
100
+ if (Array.isArray(schema.required)) {
101
+ schema.required = schema.required.map((value) => value === 'interaction_id' ? 'target_id' : value);
102
+ }
103
+ }
104
+ return { ...descriptor, argumentsSchema: schema };
105
+ }
106
+
107
+ export interface ProtectedConsoleUnlockPreparationInput {
108
+ confirmAuthorization: boolean;
109
+ timeoutMs?: number;
110
+ }
111
+
112
+ export interface ProtectedConsoleUnlockInvocationInput {
113
+ credentialHandle: string;
114
+ confirmAuthorization: boolean;
115
+ timeoutMs?: number;
116
+ }
117
+
118
+ function boundedConsoleUnlockTimeoutMs(value: number | undefined): number {
119
+ if (!Number.isFinite(value)) return DEFAULT_CONSOLE_UNLOCK_TIMEOUT_MS;
120
+ return Math.min(MAX_CONSOLE_UNLOCK_TIMEOUT_MS, Math.max(1_000, Math.trunc(value!)));
121
+ }
122
+
123
+ function requireConsoleUnlockAuthorization(confirmed: boolean): void {
124
+ if (confirmed !== true) {
125
+ throw new Error('COMPUTER_CONSOLE_UNLOCK_EXPLICIT_AUTHORIZATION_REQUIRED: confirm_authorization=true is required for this one invocation.');
126
+ }
127
+ }
128
+
129
+ export async function executeProtectedConsoleUnlockPreparation(
130
+ input: ProtectedConsoleUnlockPreparationInput,
131
+ controllerHome: string,
132
+ ): Promise<Record<string, unknown>> {
133
+ requireConsoleUnlockAuthorization(input.confirmAuthorization);
134
+ const invocationId = randomUUID();
135
+ const request: ComputerConsoleUnlockPrepareRequest = {
136
+ capability: COMPUTER_CONSOLE_UNLOCK_CAPABILITY,
137
+ action: 'prepare_unlock_console',
138
+ };
139
+ const providerResult = await executeRuntimeComputerConsoleUnlock(
140
+ request,
141
+ { kind: 'explicit_single_use', confirmed: true, invocationId },
142
+ boundedConsoleUnlockTimeoutMs(input.timeoutMs),
143
+ controllerHome,
144
+ );
145
+ const credentialHandle = typeof providerResult.credential_handle === 'string'
146
+ ? providerResult.credential_handle
147
+ : undefined;
148
+ if (!credentialHandle || !CONSOLE_CREDENTIAL_HANDLE_PATTERN.test(credentialHandle)) {
149
+ throw new Error('COMPUTER_CONSOLE_UNLOCK_PREPARATION_INVALID: provider did not return a valid opaque credential handle.');
150
+ }
151
+ return {
152
+ capability: COMPUTER_CONSOLE_UNLOCK_CAPABILITY,
153
+ action: 'prepare_unlock_console',
154
+ invocationId,
155
+ prepared: providerResult.prepared === true,
156
+ credentialHandle,
157
+ ...(typeof providerResult.expires_in_ms === 'number' ? { expiresInMs: providerResult.expires_in_ms } : {}),
158
+ };
159
+ }
160
+
161
+ export async function executeProtectedConsoleUnlockInvocation(
162
+ input: ProtectedConsoleUnlockInvocationInput,
163
+ controllerHome: string,
164
+ ): Promise<Record<string, unknown>> {
165
+ requireConsoleUnlockAuthorization(input.confirmAuthorization);
166
+ if (!CONSOLE_CREDENTIAL_HANDLE_PATTERN.test(input.credentialHandle)) {
167
+ throw new Error('COMPUTER_CONSOLE_UNLOCK_CREDENTIAL_HANDLE_REQUIRED: a provider-local opaque credential handle is required.');
168
+ }
169
+ const invocationId = randomUUID();
170
+ const request: ComputerConsoleUnlockRequest = {
171
+ capability: COMPUTER_CONSOLE_UNLOCK_CAPABILITY,
172
+ action: 'unlock_console',
173
+ credentialHandle: input.credentialHandle,
174
+ };
175
+ const providerResult = await executeRuntimeComputerConsoleUnlock(
176
+ request,
177
+ { kind: 'explicit_single_use', confirmed: true, invocationId },
178
+ boundedConsoleUnlockTimeoutMs(input.timeoutMs),
179
+ controllerHome,
180
+ );
181
+ return {
182
+ capability: COMPUTER_CONSOLE_UNLOCK_CAPABILITY,
183
+ action: 'unlock_console',
184
+ invocationId,
185
+ unlocked: providerResult.unlocked === true,
186
+ verified: providerResult.verified === true,
187
+ ...(typeof providerResult.postcondition === 'string' ? { postcondition: providerResult.postcondition } : {}),
188
+ };
189
+ }
190
+
191
+ export async function executeProtectedConsoleUnlockLifecycle(
192
+ action: 'console_unlock_enroll' | 'console_unlock_status' | 'console_unlock_recover' | 'console_unlock_revoke',
193
+ input: ProtectedConsoleUnlockPreparationInput,
194
+ controllerHome: string,
195
+ ): Promise<Record<string, unknown>> {
196
+ requireConsoleUnlockAuthorization(input.confirmAuthorization);
197
+ const invocationId = randomUUID();
198
+ const request: ComputerConsoleUnlockCommandRequest = {
199
+ capability: COMPUTER_CONSOLE_UNLOCK_CAPABILITY,
200
+ action,
201
+ };
202
+ const providerResult = await executeRuntimeComputerConsoleUnlock(
203
+ request,
204
+ { kind: 'explicit_single_use', confirmed: true, invocationId },
205
+ boundedConsoleUnlockTimeoutMs(input.timeoutMs),
206
+ controllerHome,
207
+ );
208
+ return {
209
+ capability: COMPUTER_CONSOLE_UNLOCK_CAPABILITY,
210
+ action,
211
+ invocationId,
212
+ ...providerResult,
213
+ };
214
+ }
215
+
216
+ function desktopProductActions(): AssistantPluginActionDescriptor[] {
217
+ const open = providerActionDescriptor('desktop_session_open');
218
+ const close = providerActionDescriptor('desktop_session_close');
219
+ return [
220
+ {
221
+ ...open,
222
+ actionId: DESKTOP_TARGET_OPEN_ACTION,
223
+ title: 'Open Computer desktop target',
224
+ description: 'Bind one application as a Forge-owned durable Computer target. Native provider session ids remain internal rebuildable bindings.',
225
+ },
226
+ {
227
+ ...close,
228
+ actionId: DESKTOP_TARGET_CLOSE_ACTION,
229
+ title: 'Close Computer desktop target',
230
+ description: 'Retire one Forge-owned Computer target after its live provider binding is closed or confirmed absent.',
231
+ argumentsSchema: {
232
+ type: 'object',
233
+ properties: { target_id: { type: 'string' } },
234
+ required: ['target_id'],
235
+ additionalProperties: false,
236
+ },
237
+ },
238
+ ...[...DESKTOP_SEMANTIC_ACTION_IDS].map(targetBoundDescriptor),
239
+ {
240
+ actionId: COMPUTER_CONSOLE_UNLOCK_PREPARE_ACTION,
241
+ title: 'Prepare protected console unlock',
242
+ description: 'Ask the native Computer provider to collect a console credential locally and return only a short-lived opaque single-use handle.',
243
+ readOnly: false,
244
+ risk: 'workspace_write',
245
+ confirmation: 'authorization',
246
+ defaultTimeoutMs: DEFAULT_CONSOLE_UNLOCK_TIMEOUT_MS,
247
+ cancellable: true,
248
+ idempotent: false,
249
+ executionMode: 'direct_non_persistent',
250
+ foregroundEffect: 'required',
251
+ scopes: ['console.unlock'],
252
+ resourceClaims: [],
253
+ argumentsSchema: { type: 'object', properties: {}, additionalProperties: false },
254
+ },
255
+ {
256
+ actionId: COMPUTER_CONSOLE_UNLOCK_ACTION,
257
+ title: 'Unlock protected console',
258
+ description: 'Consume one provider-local opaque credential handle to perform and verify one console unlock without durable replay state.',
259
+ readOnly: false,
260
+ risk: 'workspace_write',
261
+ confirmation: 'authorization',
262
+ defaultTimeoutMs: DEFAULT_CONSOLE_UNLOCK_TIMEOUT_MS,
263
+ cancellable: true,
264
+ idempotent: false,
265
+ executionMode: 'direct_non_persistent',
266
+ foregroundEffect: 'required',
267
+ scopes: ['console.unlock'],
268
+ resourceClaims: [],
269
+ argumentsSchema: {
270
+ type: 'object',
271
+ properties: {
272
+ credential_handle: { type: 'string', minLength: 36, maxLength: 64, description: 'Opaque short-lived single-use handle returned by console_unlock_prepare.' },
273
+ },
274
+ required: ['credential_handle'],
275
+ additionalProperties: false,
276
+ },
277
+ },
278
+ {
279
+ actionId: COMPUTER_CONSOLE_UNLOCK_ENROLL_ACTION,
280
+ title: 'Enable unattended console recovery',
281
+ description: 'Enroll provider-local unattended console recovery. Credential collection and Keychain persistence remain entirely inside the native provider.',
282
+ readOnly: false,
283
+ risk: 'workspace_write',
284
+ confirmation: 'authorization',
285
+ defaultTimeoutMs: DEFAULT_CONSOLE_UNLOCK_TIMEOUT_MS,
286
+ cancellable: true,
287
+ idempotent: false,
288
+ executionMode: 'direct_non_persistent',
289
+ foregroundEffect: 'required',
290
+ scopes: ['console.unlock'],
291
+ resourceClaims: [],
292
+ argumentsSchema: { type: 'object', properties: {}, additionalProperties: false },
293
+ },
294
+ {
295
+ actionId: COMPUTER_CONSOLE_UNLOCK_STATUS_ACTION,
296
+ title: 'Read unattended console recovery status',
297
+ description: 'Read whether provider-local unattended console recovery is enrolled and available without exposing credential material.',
298
+ readOnly: true,
299
+ risk: 'readonly',
300
+ confirmation: 'authorization',
301
+ defaultTimeoutMs: DEFAULT_CONSOLE_UNLOCK_TIMEOUT_MS,
302
+ cancellable: true,
303
+ idempotent: true,
304
+ executionMode: 'direct_non_persistent',
305
+ foregroundEffect: 'none',
306
+ scopes: ['console.unlock'],
307
+ resourceClaims: [],
308
+ argumentsSchema: { type: 'object', properties: {}, additionalProperties: false },
309
+ },
310
+ {
311
+ actionId: COMPUTER_CONSOLE_UNLOCK_RECOVER_ACTION,
312
+ title: 'Recover locked macOS console',
313
+ description: 'Recover an already-locked console using only the provider-local enrolled credential. No password or credential handle enters Forge.',
314
+ readOnly: false,
315
+ risk: 'workspace_write',
316
+ confirmation: 'authorization',
317
+ defaultTimeoutMs: DEFAULT_CONSOLE_UNLOCK_TIMEOUT_MS,
318
+ cancellable: true,
319
+ idempotent: false,
320
+ executionMode: 'direct_non_persistent',
321
+ foregroundEffect: 'required',
322
+ scopes: ['console.unlock'],
323
+ resourceClaims: [],
324
+ argumentsSchema: { type: 'object', properties: {}, additionalProperties: false },
325
+ },
326
+ {
327
+ actionId: COMPUTER_CONSOLE_UNLOCK_REVOKE_ACTION,
328
+ title: 'Disable unattended console recovery',
329
+ description: 'Delete the provider-local unattended console recovery credential and disable future recovery.',
330
+ readOnly: false,
331
+ risk: 'workspace_write',
332
+ confirmation: 'authorization',
333
+ defaultTimeoutMs: DEFAULT_CONSOLE_UNLOCK_TIMEOUT_MS,
334
+ cancellable: true,
335
+ idempotent: true,
336
+ executionMode: 'direct_non_persistent',
337
+ foregroundEffect: 'none',
338
+ scopes: ['console.unlock'],
339
+ resourceClaims: [],
340
+ argumentsSchema: { type: 'object', properties: {}, additionalProperties: false },
341
+ },
342
+ {
343
+ actionId: DESKTOP_ELEMENT_OBSERVE_ACTION,
344
+ title: 'Observe Computer elements',
345
+ description: 'Observe provider-neutral semantic elements for one Forge-owned desktop target. Returned refs and target context are valid only for the returned observation epoch.',
346
+ readOnly: true,
347
+ risk: 'readonly',
348
+ confirmation: 'none',
349
+ defaultTimeoutMs: 10_000,
350
+ cancellable: true,
351
+ idempotent: true,
352
+ foregroundEffect: 'none',
353
+ scopes: ['desktop.observe'],
354
+ resourceClaims: [],
355
+ argumentsSchema: {
356
+ type: 'object',
357
+ properties: {
358
+ target_id: { type: 'string', description: 'Forge-owned durable Computer target id.' },
359
+ max_depth: { type: 'integer', minimum: 1, maximum: 20 },
360
+ max_nodes: { type: 'integer', minimum: 1, maximum: 5_000 },
361
+ include_values: { type: 'boolean' },
362
+ root_selector: {
363
+ type: 'object',
364
+ properties: { ref: { type: 'string' }, role: { type: 'string' }, title: { type: 'string' }, identifier: { type: 'string' } },
365
+ anyOf: [{ required: ['ref'] }, { required: ['role'] }, { required: ['title'] }, { required: ['identifier'] }],
366
+ additionalProperties: false,
367
+ },
368
+ },
369
+ required: ['target_id'],
370
+ additionalProperties: false,
371
+ },
372
+ },
373
+ {
374
+ actionId: DESKTOP_ELEMENT_ACTION_ACTION,
375
+ title: 'Act on observed Computer element',
376
+ description: 'Perform one provider-neutral semantic action against an exact element ref and observation target returned by desktop_element_observe. Stale or rebound observations fail closed.',
377
+ readOnly: false,
378
+ risk: 'workspace_write',
379
+ confirmation: 'authorization',
380
+ defaultTimeoutMs: 10_000,
381
+ cancellable: true,
382
+ idempotent: false,
383
+ foregroundEffect: 'none',
384
+ scopes: ['desktop.interact'],
385
+ resourceClaims: [],
386
+ argumentsSchema: {
387
+ type: 'object',
388
+ properties: {
389
+ target_id: { type: 'string', description: 'Forge-owned durable Computer target id.' },
390
+ target: {
391
+ type: 'object',
392
+ properties: {
393
+ interactionId: { type: 'string' },
394
+ pid: { type: 'integer' },
395
+ bundleIdentifier: { type: 'string' },
396
+ appName: { type: 'string' },
397
+ windowRef: { type: 'string' },
398
+ snapshotRevision: { type: 'integer', minimum: 1 },
399
+ },
400
+ required: ['interactionId', 'pid', 'appName', 'snapshotRevision'],
401
+ additionalProperties: false,
402
+ },
403
+ ref: { type: 'string' },
404
+ action: { type: 'string', enum: [...COMPUTER_ELEMENT_SEMANTIC_ACTIONS] },
405
+ value: { anyOf: [{ type: 'string' }, { type: 'number' }, { type: 'boolean' }, { type: 'null' }] },
406
+ },
407
+ required: ['target_id', 'target', 'ref', 'action'],
408
+ additionalProperties: false,
409
+ },
410
+ },
411
+ ];
412
+ }
413
+
414
+ function desktopProductPermissions(ready: boolean): AssistantPluginPermissionScope[] {
415
+ return [
416
+ { scope: 'desktop.session', mode: 'write', description: 'Bind a desktop application target for Computer interaction.', granted: ready, required: false },
417
+ { scope: 'desktop.observe', mode: 'read', description: 'Observe bounded desktop accessibility state.', granted: ready, required: false },
418
+ { scope: 'desktop.interact', mode: 'write', description: 'Perform bounded semantic desktop interaction.', granted: ready, required: false },
419
+ { scope: 'desktop.capture', mode: 'read', description: 'Capture an authorized desktop target.', granted: ready, required: false },
420
+ { scope: 'console.unlock', mode: 'write', description: 'Use provider-local temporary unlock or explicitly enrolled unattended console recovery.', granted: ready, required: false },
421
+ ];
422
+ }
423
+
424
+ function desktopProductCapabilities(): AssistantPluginCapability[] {
425
+ return [
426
+ { capabilityId: 'computer.desktop_target.v1', title: 'Desktop targets', description: 'Bind and retire Forge-owned desktop application targets.', scopes: ['desktop.session'], actions: [DESKTOP_TARGET_OPEN_ACTION, DESKTOP_TARGET_CLOSE_ACTION] },
427
+ { capabilityId: 'computer.observe.v1', title: 'Computer observation', description: 'Observe bounded desktop semantic state.', scopes: ['desktop.observe'], actions: ['desktop_observe'] },
428
+ { capabilityId: 'computer.input.v1', title: 'Computer input', description: 'Perform bounded semantic desktop input.', scopes: ['desktop.interact'], actions: ['desktop_press', 'desktop_select_rows', 'desktop_type_text', 'desktop_key', 'desktop_open_url'] },
429
+ { capabilityId: 'computer.capture.v1', title: 'Computer capture', description: 'Capture authorized desktop state.', scopes: ['desktop.capture'], actions: ['desktop_screenshot'] },
430
+ { capabilityId: COMPUTER_ELEMENT_OBSERVE_CAPABILITY, title: 'Computer element observation', description: 'Observe exact provider-neutral semantic element snapshots for a Forge-owned target.', scopes: ['desktop.observe'], actions: [DESKTOP_ELEMENT_OBSERVE_ACTION] },
431
+ { capabilityId: COMPUTER_ELEMENT_ACTION_CAPABILITY, title: 'Computer element action', description: 'Act on exact observed element refs with observation-epoch fencing.', scopes: ['desktop.interact'], actions: [DESKTOP_ELEMENT_ACTION_ACTION] },
432
+ { capabilityId: COMPUTER_CONSOLE_UNLOCK_CAPABILITY, title: 'Protected console unlock', description: 'Keep console credential material provider-local while supporting temporary one-shot unlock and opt-in unattended recovery.', scopes: ['console.unlock'], actions: [COMPUTER_CONSOLE_UNLOCK_PREPARE_ACTION, COMPUTER_CONSOLE_UNLOCK_ACTION, COMPUTER_CONSOLE_UNLOCK_ENROLL_ACTION, COMPUTER_CONSOLE_UNLOCK_STATUS_ACTION, COMPUTER_CONSOLE_UNLOCK_RECOVER_ACTION, COMPUTER_CONSOLE_UNLOCK_REVOKE_ACTION] },
433
+ ];
434
+ }
435
+
436
+ function desktopProviderManifest(context: AssistantPluginBuildContext | undefined): AssistantPluginManifest | undefined {
437
+ if (!context) return undefined;
438
+ const adapter = getExternalPluginAdapter(context.controllerHome, DESKTOP_PROVIDER_ID);
439
+ return adapter?.buildManifest(0, undefined, context.repoRoot, context);
440
+ }
441
+
442
+ function buildComputerManifest(
443
+ previousRevision = 0,
444
+ previousUpdatedAt?: string,
445
+ repoRoot?: string,
446
+ context?: AssistantPluginBuildContext,
447
+ ): AssistantPluginManifest {
448
+ const browser = buildBrowserPluginManifest(previousRevision, previousUpdatedAt, repoRoot, context);
449
+ const desktop = desktopProviderManifest(context);
450
+ const platform = currentComputerPlatform();
451
+ const desktopSupported = platform === 'darwin';
452
+ const browserReady = browser.enabled && browser.health.ready;
453
+ const desktopReady = desktopSupported && desktop?.enabled === true && desktop.health.ready;
454
+ const ready = browserReady && desktopReady;
455
+ const partial = browserReady || desktopReady;
456
+ const checkedAt = new Date().toISOString();
457
+ return {
458
+ ...browser,
459
+ pluginId: 'computer',
460
+ provider: 'forge-computer',
461
+ displayName: 'Forge Computer',
462
+ pluginVersion: '1.0.0',
463
+ authority: {
464
+ strategy: 'derived',
465
+ duplicateStateAllowed: false,
466
+ sourceOfTruth: [
467
+ ...browser.authority.sourceOfTruth,
468
+ 'controllerHome:sqlite/computer_interaction_target',
469
+ ],
470
+ },
471
+ enabled: browser.enabled || desktop?.enabled === true,
472
+ lifecycle: {
473
+ state: ready ? 'enabled' : partial ? 'degraded' : 'error',
474
+ reason: ready
475
+ ? 'Computer Browser and native Desktop semantic capabilities are ready.'
476
+ : desktopSupported
477
+ ? 'Computer is only partially ready; inspect Browser and native Desktop capability health.'
478
+ : `Computer has partial Browser-only support on ${platform}; native Desktop capabilities are unsupported on this platform.`,
479
+ },
480
+ health: {
481
+ state: ready ? 'ready' : partial ? 'degraded' : 'error',
482
+ checkedAt,
483
+ ready,
484
+ probed: browser.health.probed || desktop?.health.probed === true,
485
+ errors: ready ? [] : [
486
+ ...browser.health.errors,
487
+ ...(desktopSupported && !desktopReady ? ['Native Computer capabilities are unavailable or not ready.'] : []),
488
+ ],
489
+ warnings: [
490
+ ...browser.health.warnings,
491
+ ...(desktopSupported
492
+ ? (desktopReady ? [] : ['Native Computer capability diagnostics are available through the internal platform provider.'])
493
+ : [`Native Desktop Computer capabilities are unsupported on ${platform}.`]),
494
+ ],
495
+ details: {
496
+ partial: !ready && partial,
497
+ browser: { ready: browserReady, state: browser.health.state },
498
+ desktop: { supported: desktopSupported, ready: desktopReady, state: desktop?.health.state ?? (desktopSupported ? 'not_installed' : 'unsupported') },
499
+ },
500
+ },
501
+ permissions: [...browser.permissions, ...desktopProductPermissions(desktopReady)],
502
+ capabilities: [...browser.capabilities, ...desktopProductCapabilities()],
503
+ actions: [...browser.actions, ...desktopProductActions()],
504
+ updatedAt: previousUpdatedAt ?? checkedAt,
505
+ };
506
+ }
507
+
508
+ function isDesktopProductAction(actionId: string): boolean {
509
+ return DESKTOP_PRODUCT_ACTION_IDS.has(actionId);
510
+ }
511
+
512
+ function optionalDesktopProvider(input: AssistantPluginActionExecutionInput): AssistantPluginAdapter | undefined {
513
+ return getExternalPluginAdapter(input.controllerHome, DESKTOP_PROVIDER_ID);
514
+ }
515
+
516
+ function desktopProvider(input: AssistantPluginActionExecutionInput): AssistantPluginAdapter {
517
+ const platform = currentComputerPlatform();
518
+ if (platform !== 'darwin') {
519
+ throw new AssistantPluginError(
520
+ 'PLUGIN_COMPUTER_DESKTOP_PLATFORM_UNSUPPORTED',
521
+ `Computer native Desktop capabilities are unavailable on ${platform} until a platform provider is installed.`,
522
+ { retryable: false, details: { platform, actionId: input.actionId } },
523
+ );
524
+ }
525
+ const provider = optionalDesktopProvider(input);
526
+ if (!provider) {
527
+ throw new AssistantPluginError(
528
+ 'PLUGIN_COMPUTER_DESKTOP_PROVIDER_UNAVAILABLE',
529
+ 'Computer native Desktop capabilities require the registered platform provider.',
530
+ { retryable: true, details: { providerId: DESKTOP_PROVIDER_ID, actionId: input.actionId } },
531
+ );
532
+ }
533
+ return provider;
534
+ }
535
+
536
+ function firstString(value: unknown, ...keys: string[]): string | undefined {
537
+ if (!value || typeof value !== 'object') return undefined;
538
+ const record = value as Record<string, unknown>;
539
+ for (const key of keys) {
540
+ const candidate = record[key];
541
+ if (typeof candidate === 'string' && candidate.trim()) return candidate.trim();
542
+ }
543
+ return undefined;
544
+ }
545
+
546
+ function stableIdentityFromArgs(args: Record<string, unknown>): ComputerApplicationStableIdentity {
547
+ const bundleId = typeof args.bundle_id === 'string' ? args.bundle_id.trim() : '';
548
+ const appName = typeof args.app_name === 'string' ? args.app_name.trim() : '';
549
+ if (!bundleId && !appName) throw new AssistantPluginError('PLUGIN_COMPUTER_TARGET_IDENTITY_REQUIRED', 'Desktop target requires bundle_id or app_name.', { retryable: false });
550
+ return { ...(bundleId ? { bundleId } : {}), ...(appName ? { appName } : {}) };
551
+ }
552
+
553
+ function targetMatchesProviderSession(target: ComputerApplicationTarget, session: Record<string, unknown>): boolean {
554
+ const bundleId = firstString(session, 'bundleIdentifier', 'bundle_id');
555
+ const appName = firstString(session, 'appName', 'app_name');
556
+ if (target.stableIdentity.bundleId) return bundleId === target.stableIdentity.bundleId;
557
+ return Boolean(target.stableIdentity.appName && appName === target.stableIdentity.appName);
558
+ }
559
+
560
+ function providerInput(
561
+ input: AssistantPluginActionExecutionInput,
562
+ actionId: string,
563
+ args: Record<string, unknown>,
564
+ suffix = actionId,
565
+ ): AssistantPluginActionExecutionInput {
566
+ return { ...input, pluginId: DESKTOP_PROVIDER_ID, actionId, args, requestId: `${input.requestId}:${suffix}` };
567
+ }
568
+
569
+ function providerSessionId(result: Record<string, unknown>): string {
570
+ const interactionId = firstString(result, 'interactionId', 'interaction_id');
571
+ if (!interactionId) throw new AssistantPluginError('PLUGIN_COMPUTER_PROVIDER_BINDING_MISSING', 'Native Computer provider did not return a live interaction binding.', { retryable: true });
572
+ return interactionId;
573
+ }
574
+
575
+ function desktopComputerRequest(
576
+ actionId: string,
577
+ args: Record<string, unknown>,
578
+ interactionId?: string,
579
+ ): ComputerRuntimeExecutionRequest {
580
+ const requireInteractionId = (): string => {
581
+ if (interactionId) return interactionId;
582
+ throw new AssistantPluginError('PLUGIN_COMPUTER_PROVIDER_BINDING_MISSING', `${actionId} requires a live provider interaction binding.`, { retryable: true });
583
+ };
584
+ if (actionId === 'desktop_observe') {
585
+ return {
586
+ capability: COMPUTER_OBSERVE_CAPABILITY,
587
+ action: 'observe',
588
+ interactionId: requireInteractionId(),
589
+ ...(typeof args.max_depth === 'number' ? { maxDepth: args.max_depth } : {}),
590
+ ...(typeof args.max_nodes === 'number' ? { maxNodes: args.max_nodes } : {}),
591
+ ...(typeof args.include_values === 'boolean' ? { includeValues: args.include_values } : {}),
592
+ ...(typeof args.include_actions === 'boolean' ? { includeActions: args.include_actions } : {}),
593
+ ...(typeof args.include_windows === 'boolean' ? { includeWindows: args.include_windows } : {}),
594
+ ...(args.root_selector && typeof args.root_selector === 'object' ? { rootSelector: args.root_selector as ComputerSemanticSelector } : {}),
595
+ };
596
+ }
597
+ if (actionId === 'desktop_press') {
598
+ return {
599
+ capability: COMPUTER_INPUT_CAPABILITY,
600
+ action: 'press',
601
+ interactionId: requireInteractionId(),
602
+ selector: args.selector as ComputerSemanticSelector,
603
+ ...(typeof args.semantic_action === 'string' ? { semanticAction: args.semantic_action } : {}),
604
+ } as ComputerRuntimeExecutionRequest;
605
+ }
606
+ if (actionId === 'desktop_select_rows') {
607
+ return {
608
+ capability: COMPUTER_INPUT_CAPABILITY,
609
+ action: 'select_rows',
610
+ interactionId: requireInteractionId(),
611
+ selector: args.selector as ComputerSemanticSelector,
612
+ startIndex: args.start_index as number,
613
+ ...(typeof args.end_index === 'number' ? { endIndex: args.end_index } : {}),
614
+ };
615
+ }
616
+ if (actionId === 'desktop_type_text') {
617
+ return {
618
+ capability: COMPUTER_INPUT_CAPABILITY,
619
+ action: 'type_text',
620
+ interactionId: requireInteractionId(),
621
+ selector: args.selector as ComputerSemanticSelector,
622
+ text: String(args.text ?? ''),
623
+ ...(typeof args.replace === 'boolean' ? { replace: args.replace } : {}),
624
+ };
625
+ }
626
+ if (actionId === 'desktop_key') {
627
+ return {
628
+ capability: COMPUTER_INPUT_CAPABILITY,
629
+ action: 'key',
630
+ interactionId: requireInteractionId(),
631
+ keys: Array.isArray(args.keys) ? args.keys.filter((value): value is string => typeof value === 'string') : [],
632
+ };
633
+ }
634
+ if (actionId === 'desktop_open_url') {
635
+ return { capability: COMPUTER_INPUT_CAPABILITY, action: 'open_url', url: String(args.url ?? '') };
636
+ }
637
+ if (actionId === 'desktop_screenshot') {
638
+ return {
639
+ capability: COMPUTER_CAPTURE_CAPABILITY,
640
+ action: 'screenshot',
641
+ ...(args.scope === 'display' || args.scope === 'window' ? { scope: args.scope } : {}),
642
+ ...(interactionId ? { interactionId } : {}),
643
+ ...(typeof args.window_id === 'number' ? { windowId: args.window_id } : {}),
644
+ ...(typeof args.label === 'string' ? { label: args.label } : {}),
645
+ };
646
+ }
647
+ if (actionId === DESKTOP_ELEMENT_OBSERVE_ACTION) {
648
+ return {
649
+ capability: COMPUTER_ELEMENT_OBSERVE_CAPABILITY,
650
+ action: 'observe_elements',
651
+ interactionId: requireInteractionId(),
652
+ ...(typeof args.max_depth === 'number' ? { maxDepth: args.max_depth } : {}),
653
+ ...(typeof args.max_nodes === 'number' ? { maxNodes: args.max_nodes } : {}),
654
+ ...(typeof args.include_values === 'boolean' ? { includeValues: args.include_values } : {}),
655
+ ...(args.root_selector && typeof args.root_selector === 'object' ? { rootSelector: args.root_selector as ComputerSemanticSelector } : {}),
656
+ };
657
+ }
658
+ if (actionId === DESKTOP_ELEMENT_ACTION_ACTION) {
659
+ const semanticAction = typeof args.action === 'string' && (COMPUTER_ELEMENT_SEMANTIC_ACTIONS as readonly string[]).includes(args.action)
660
+ ? args.action as ComputerElementSemanticAction
661
+ : undefined;
662
+ if (!semanticAction || !args.target || typeof args.target !== 'object' || typeof args.ref !== 'string') {
663
+ throw new AssistantPluginError('PLUGIN_COMPUTER_ELEMENT_ACTION_INVALID', 'desktop_element_action requires target, ref, and one declared semantic action.', { retryable: false });
664
+ }
665
+ return {
666
+ capability: COMPUTER_ELEMENT_ACTION_CAPABILITY,
667
+ action: semanticAction,
668
+ target: args.target as ComputerElementTarget,
669
+ ref: args.ref,
670
+ ...(args.value !== undefined ? { value: args.value } : {}),
671
+ };
672
+ }
673
+ throw new AssistantPluginError('PLUGIN_COMPUTER_DESKTOP_ACTION_UNSUPPORTED', `Unsupported retained Desktop Computer action ${actionId}.`, { retryable: false });
674
+ }
675
+
676
+ async function executeRetainedDesktopAction(
677
+ input: AssistantPluginActionExecutionInput,
678
+ args: Record<string, unknown>,
679
+ interactionId?: string,
680
+ ): Promise<Record<string, unknown>> {
681
+ const descriptor = desktopProductActions().find((action) => action.actionId === input.actionId);
682
+ if (!descriptor) throw new AssistantPluginError('PLUGIN_COMPUTER_DESKTOP_ACTION_UNSUPPORTED', `Computer product action ${input.actionId} is not registered.`, { retryable: false });
683
+ return await executeRuntimeComputer(
684
+ desktopComputerRequest(input.actionId, args, interactionId),
685
+ input.timeoutMs ?? descriptor.defaultTimeoutMs ?? 30_000,
686
+ input.controllerHome,
687
+ );
688
+ }
689
+
690
+ function isMissingProviderSessionFailure(error: unknown): error is AssistantPluginError {
691
+ return error instanceof AssistantPluginError
692
+ && error.code === 'SESSION_NOT_FOUND'
693
+ && error.effectOutcome === 'failed';
694
+ }
695
+
696
+ async function rebindProviderSession(
697
+ input: AssistantPluginActionExecutionInput,
698
+ lease: ComputerApplicationTargetLease,
699
+ provider: AssistantPluginAdapter,
700
+ ): Promise<string> {
701
+ const target = lease.current();
702
+ const rebound = await provider.executeAction(providerInput(input, 'desktop_session_open', {
703
+ ...(target.stableIdentity.bundleId ? { bundle_id: target.stableIdentity.bundleId } : { app_name: target.stableIdentity.appName }),
704
+ launch: false,
705
+ activate: false,
706
+ }, 'binding-reopen'));
707
+ const interactionId = providerSessionId(rebound);
708
+ if (!targetMatchesProviderSession(target, rebound)) {
709
+ try {
710
+ await provider.executeAction(providerInput(input, 'desktop_session_close', { interaction_id: interactionId }, 'binding-reopen-identity-compensate'));
711
+ } catch (cleanupError) {
712
+ throw new AssistantPluginError(
713
+ 'PLUGIN_COMPUTER_TARGET_REBIND_IDENTITY_CLEANUP_UNKNOWN',
714
+ 'Computer target rebind returned an unverifiable application identity and provider-session cleanup could not be confirmed.',
715
+ { retryable: false, details: { targetId: target.targetId, cleanupCause: cleanupError instanceof Error ? cleanupError.message : String(cleanupError) } },
716
+ );
717
+ }
718
+ throw new AssistantPluginError(
719
+ 'PLUGIN_COMPUTER_TARGET_REBIND_IDENTITY_MISMATCH',
720
+ 'Computer target rebind did not return the durable target application identity.',
721
+ { retryable: false, details: { targetId: target.targetId, stableIdentity: target.stableIdentity } },
722
+ );
723
+ }
724
+ const processId = providerProcessId(rebound);
725
+ lease.bind({
726
+ providerId: DESKTOP_PROVIDER_ID,
727
+ providerSessionId: interactionId,
728
+ observedAt: new Date().toISOString(),
729
+ ...(processId !== undefined ? { processId } : {}),
730
+ });
731
+ return interactionId;
732
+ }
733
+
734
+ async function ensureProviderBinding(
735
+ input: AssistantPluginActionExecutionInput,
736
+ lease: ComputerApplicationTargetLease,
737
+ provider: AssistantPluginAdapter,
738
+ ): Promise<string> {
739
+ const target = lease.current();
740
+ if (target.providerBinding?.providerId === DESKTOP_PROVIDER_ID) {
741
+ return target.providerBinding.providerSessionId;
742
+ }
743
+ return rebindProviderSession(input, lease, provider);
744
+ }
745
+
746
+ function providerProcessId(result: Record<string, unknown>): number | undefined {
747
+ const value = result.pid ?? result.process_id;
748
+ if (value === undefined) return undefined;
749
+ if (typeof value !== 'number' || !Number.isInteger(value) || value <= 0 || value > 2_147_483_647) {
750
+ throw new AssistantPluginError(
751
+ 'PLUGIN_COMPUTER_TARGET_PROCESS_ID_INVALID',
752
+ 'Native Computer provider returned an invalid application process identifier.',
753
+ { retryable: false, details: { processId: value } },
754
+ );
755
+ }
756
+ return value;
757
+ }
758
+
759
+ function explicitLaunchProvenanceFromProviderResult(
760
+ result: Record<string, unknown>,
761
+ processId: number | undefined,
762
+ ): ComputerApplicationLaunchProvenance | undefined {
763
+ const rawOwnership = result.applicationOwnership ?? result.application_ownership;
764
+ const rawOwnedPid = result.ownedProcessIdentifier ?? result.owned_process_identifier;
765
+ if (rawOwnership === undefined && rawOwnedPid === undefined) return undefined;
766
+ if (rawOwnership === 'preexisting' && rawOwnedPid === undefined) return { kind: 'preexisting' };
767
+ if (rawOwnership === 'provider_launched'
768
+ && typeof rawOwnedPid === 'number'
769
+ && Number.isInteger(rawOwnedPid)
770
+ && rawOwnedPid > 0
771
+ && rawOwnedPid <= 2_147_483_647
772
+ && processId === rawOwnedPid) {
773
+ return { kind: 'provider_launched', processId: rawOwnedPid };
774
+ }
775
+ throw new AssistantPluginError(
776
+ 'PLUGIN_COMPUTER_TARGET_LAUNCH_PROVENANCE_INVALID',
777
+ 'Native Computer provider returned inconsistent application launch provenance.',
778
+ { retryable: false, details: { applicationOwnership: rawOwnership, ownedProcessIdentifier: rawOwnedPid, processId } },
779
+ );
780
+ }
781
+
782
+ function inheritedLaunchProvenance(
783
+ controllerHome: string,
784
+ processId: number | undefined,
785
+ ): ComputerApplicationLaunchProvenance | undefined {
786
+ if (processId === undefined) return undefined;
787
+ const owner = computerTargetAuthority.listAllApplications(controllerHome).find((target) =>
788
+ target.launchProvenance?.kind === 'provider_launched'
789
+ && target.launchProvenance.processId === processId
790
+ && target.providerBinding?.processId === processId,
791
+ );
792
+ return owner ? { kind: 'provider_launched', processId } : undefined;
793
+ }
794
+
795
+ function stableIdentityFromProviderResult(
796
+ result: Record<string, unknown>,
797
+ requested: ComputerApplicationStableIdentity,
798
+ ): ComputerApplicationStableIdentity {
799
+ const returnedBundleId = firstString(result, 'bundleIdentifier', 'bundle_id');
800
+ const returnedAppName = firstString(result, 'appName', 'app_name');
801
+ if (requested.bundleId && returnedBundleId !== requested.bundleId) {
802
+ throw new AssistantPluginError(
803
+ returnedBundleId ? 'PLUGIN_COMPUTER_TARGET_IDENTITY_MISMATCH' : 'PLUGIN_COMPUTER_TARGET_IDENTITY_UNVERIFIED',
804
+ returnedBundleId
805
+ ? 'Native Computer provider opened a different application bundle than the authorized target.'
806
+ : 'Native Computer provider did not return the application bundle required to verify the authorized target.',
807
+ { retryable: false, details: { requestedBundleId: requested.bundleId, returnedBundleId } },
808
+ );
809
+ }
810
+ if (!requested.bundleId && requested.appName && returnedAppName !== requested.appName) {
811
+ throw new AssistantPluginError(
812
+ returnedAppName ? 'PLUGIN_COMPUTER_TARGET_IDENTITY_MISMATCH' : 'PLUGIN_COMPUTER_TARGET_IDENTITY_UNVERIFIED',
813
+ returnedAppName
814
+ ? 'Native Computer provider opened a different application name than the authorized target.'
815
+ : 'Native Computer provider did not return the application name required to verify the authorized target.',
816
+ { retryable: false, details: { requestedAppName: requested.appName, returnedAppName } },
817
+ );
818
+ }
819
+ return {
820
+ ...(returnedBundleId ? { bundleId: returnedBundleId } : requested.bundleId ? { bundleId: requested.bundleId } : {}),
821
+ ...(returnedAppName ? { appName: returnedAppName } : requested.appName ? { appName: requested.appName } : {}),
822
+ };
823
+ }
824
+
825
+ async function openDesktopTarget(
826
+ input: AssistantPluginActionExecutionInput,
827
+ provider: AssistantPluginAdapter,
828
+ ): Promise<Record<string, unknown>> {
829
+ const opened = await provider.executeAction(providerInput(input, 'desktop_session_open', input.args, 'target-open'));
830
+ const interactionId = providerSessionId(opened);
831
+ const requested = stableIdentityFromArgs(input.args);
832
+ let stableIdentity: ComputerApplicationStableIdentity;
833
+ try {
834
+ stableIdentity = stableIdentityFromProviderResult(opened, requested);
835
+ } catch (error) {
836
+ try {
837
+ await provider.executeAction(providerInput(input, 'desktop_session_close', { interaction_id: interactionId }, 'target-open-identity-compensate'));
838
+ } catch (cleanupError) {
839
+ throw new AssistantPluginError('PLUGIN_COMPUTER_TARGET_IDENTITY_MISMATCH_CLEANUP_UNKNOWN', 'Computer target identity drift was detected but provider-session cleanup could not be confirmed.', {
840
+ retryable: false,
841
+ details: { cause: error instanceof Error ? error.message : String(error), cleanupCause: cleanupError instanceof Error ? cleanupError.message : String(cleanupError) },
842
+ });
843
+ }
844
+ throw error;
845
+ }
846
+ let processId: number | undefined;
847
+ let explicitProvenance: ComputerApplicationLaunchProvenance | undefined;
848
+ try {
849
+ processId = providerProcessId(opened);
850
+ explicitProvenance = explicitLaunchProvenanceFromProviderResult(opened, processId);
851
+ } catch (error) {
852
+ try {
853
+ await provider.executeAction(providerInput(input, 'desktop_session_close', { interaction_id: interactionId }, 'target-open-provenance-compensate'));
854
+ } catch (cleanupError) {
855
+ throw new AssistantPluginError('PLUGIN_COMPUTER_TARGET_LAUNCH_PROVENANCE_CLEANUP_UNKNOWN', 'Computer target launch provenance was invalid and provider-session cleanup could not be confirmed.', {
856
+ retryable: false,
857
+ details: { cause: error instanceof Error ? error.message : String(error), cleanupCause: cleanupError instanceof Error ? cleanupError.message : String(cleanupError) },
858
+ });
859
+ }
860
+ throw error;
861
+ }
862
+ try {
863
+ const launchProvenance = explicitProvenance?.kind === 'provider_launched'
864
+ ? explicitProvenance
865
+ : inheritedLaunchProvenance(input.controllerHome, processId) ?? explicitProvenance;
866
+ const target = computerTargetAuthority.create(input.controllerHome, {
867
+ stableIdentity,
868
+ ...(launchProvenance ? { launchProvenance } : {}),
869
+ providerBinding: {
870
+ providerId: DESKTOP_PROVIDER_ID,
871
+ providerSessionId: interactionId,
872
+ observedAt: new Date().toISOString(),
873
+ ...(processId !== undefined ? { processId } : {}),
874
+ },
875
+ });
876
+ return {
877
+ targetId: target.targetId,
878
+ kind: target.kind,
879
+ stableIdentity: target.stableIdentity,
880
+ providerBound: true,
881
+ };
882
+ } catch (error) {
883
+ try {
884
+ await provider.executeAction(providerInput(input, 'desktop_session_close', { interaction_id: interactionId }, 'target-open-compensate'));
885
+ } catch (cleanupError) {
886
+ throw new AssistantPluginError('PLUGIN_COMPUTER_TARGET_PERSIST_FAILED', 'Computer target persistence failed and provider-session cleanup could not be confirmed.', {
887
+ retryable: false,
888
+ details: { cause: error instanceof Error ? error.message : String(error), cleanupCause: cleanupError instanceof Error ? cleanupError.message : String(cleanupError) },
889
+ });
890
+ }
891
+ throw error;
892
+ }
893
+ }
894
+
895
+ async function closeDesktopTarget(
896
+ input: AssistantPluginActionExecutionInput,
897
+ provider: AssistantPluginAdapter | undefined,
898
+ ): Promise<Record<string, unknown>> {
899
+ const targetId = typeof input.args.target_id === 'string' ? input.args.target_id.trim() : '';
900
+ if (!targetId) throw new AssistantPluginError('PLUGIN_COMPUTER_TARGET_REQUIRED', 'desktop_target_close requires target_id.', { retryable: false });
901
+ return computerTargetAuthority.withLease(input.controllerHome, targetId, async (lease) => {
902
+ const target = lease.current();
903
+ if (target.providerBinding) {
904
+ if (target.providerBinding.providerId !== DESKTOP_PROVIDER_ID) {
905
+ throw new AssistantPluginError(
906
+ 'PLUGIN_COMPUTER_TARGET_PROVIDER_MISMATCH',
907
+ 'Computer target is bound to a different provider and cannot be retired through the current Desktop provider.',
908
+ { retryable: false, details: { targetId, providerId: target.providerBinding.providerId, expectedProviderId: DESKTOP_PROVIDER_ID } },
909
+ );
910
+ }
911
+ if (provider) {
912
+ const activeTargets = computerTargetAuthority.listAllApplications(input.controllerHome);
913
+ const anotherActiveTargetUsesBinding = activeTargets.some((candidate) =>
914
+ candidate.targetId !== target.targetId
915
+ && candidate.providerBinding?.providerId === target.providerBinding?.providerId
916
+ && candidate.providerBinding?.providerSessionId === target.providerBinding?.providerSessionId,
917
+ );
918
+ if (!anotherActiveTargetUsesBinding) {
919
+ const ownedProcessId = target.launchProvenance?.kind === 'provider_launched'
920
+ ? target.launchProvenance.processId
921
+ : undefined;
922
+ const anotherActiveTargetUsesOwnedProcess = ownedProcessId !== undefined
923
+ && activeTargets.some((candidate) =>
924
+ candidate.targetId !== target.targetId && candidate.providerBinding?.processId === ownedProcessId,
925
+ );
926
+ await provider.executeAction(providerInput(input, 'desktop_session_close', {
927
+ interaction_id: target.providerBinding.providerSessionId,
928
+ ...(ownedProcessId !== undefined && !anotherActiveTargetUsesOwnedProcess
929
+ ? { terminate_owned_pid: ownedProcessId }
930
+ : {}),
931
+ }, 'target-close-provider'));
932
+ }
933
+ }
934
+ // A missing registration is authoritative absence only because provider uninstall
935
+ // must stop/remove its native lifecycle before the registration is deleted.
936
+ }
937
+ const retired = lease.tombstone();
938
+ return { targetId: retired.targetId, retired: true, stableIdentity: retired.stableIdentity };
939
+ });
940
+ }
941
+
942
+ async function executeDesktopSemanticAction(
943
+ input: AssistantPluginActionExecutionInput,
944
+ provider: AssistantPluginAdapter,
945
+ ): Promise<Record<string, unknown>> {
946
+ if (input.actionId === 'desktop_open_url') {
947
+ return executeRetainedDesktopAction(input, input.args);
948
+ }
949
+ const targetId = typeof input.args.target_id === 'string' ? input.args.target_id.trim() : '';
950
+ if (input.actionId === DESKTOP_ELEMENT_ACTION_ACTION) {
951
+ if (!targetId) throw new AssistantPluginError('PLUGIN_COMPUTER_TARGET_REQUIRED', 'desktop_element_action requires target_id.', { retryable: false });
952
+ return computerTargetAuthority.withLease(input.controllerHome, targetId, async (lease) => {
953
+ const current = lease.current();
954
+ const observedTarget = input.args.target && typeof input.args.target === 'object' ? input.args.target as Record<string, unknown> : undefined;
955
+ const observedInteractionId = typeof observedTarget?.interactionId === 'string' ? observedTarget.interactionId : '';
956
+ const binding = current.providerBinding;
957
+ if (!binding || binding.providerId !== DESKTOP_PROVIDER_ID || !observedInteractionId || binding.providerSessionId !== observedInteractionId) {
958
+ throw new AssistantPluginError(
959
+ 'COMPUTER_ELEMENT_OBSERVATION_STALE',
960
+ 'Observed element target no longer matches the current provider binding. Re-observe the Forge Computer target instead of replaying an old element ref after rebind.',
961
+ { retryable: true, details: { targetId, providerBound: Boolean(binding), observedInteractionId: observedInteractionId || undefined } },
962
+ );
963
+ }
964
+ const { target_id: _targetId, ...rest } = input.args;
965
+ return await executeRetainedDesktopAction(input, rest, binding.providerSessionId);
966
+ });
967
+ }
968
+ if (!targetId) {
969
+ if (input.actionId === 'desktop_screenshot') {
970
+ return executeRetainedDesktopAction(input, input.args);
971
+ }
972
+ throw new AssistantPluginError('PLUGIN_COMPUTER_TARGET_REQUIRED', `${input.actionId} requires target_id.`, { retryable: false });
973
+ }
974
+ return computerTargetAuthority.withLease(input.controllerHome, targetId, async (lease) => {
975
+ let interactionId = await ensureProviderBinding(input, lease, provider);
976
+ const { target_id: _targetId, ...rest } = input.args;
977
+ const dispatch = () => executeRetainedDesktopAction(input, rest, interactionId);
978
+ try {
979
+ return await dispatch();
980
+ } catch (error) {
981
+ // SESSION_NOT_FOUND is emitted by Desktop Operator before UI/input dispatch.
982
+ // It is the only provider failure that permits one binding rebuild + retry.
983
+ // Transport/timeout/outcome-unknown failures remain fenced and are never replayed.
984
+ if (!isMissingProviderSessionFailure(error)) throw error;
985
+ interactionId = await rebindProviderSession(input, lease, provider);
986
+ return await dispatch();
987
+ }
988
+ });
989
+ }
990
+
991
+ function targetAuthorization(identity: ComputerApplicationStableIdentity): AssistantPluginAuthorizationContext {
992
+ const id = identity.bundleId ?? `app-name:${identity.appName}`;
993
+ const identityFingerprint = createHash('sha256').update(JSON.stringify(identity)).digest('hex');
994
+ return { target: { kind: 'desktop-application', id, identityFingerprint } };
995
+ }
996
+
997
+ async function resolveDesktopAuthorizationContext(input: AssistantPluginActionExecutionInput): Promise<AssistantPluginAuthorizationContext | undefined> {
998
+ if ([COMPUTER_CONSOLE_UNLOCK_PREPARE_ACTION, COMPUTER_CONSOLE_UNLOCK_ACTION, COMPUTER_CONSOLE_UNLOCK_ENROLL_ACTION, COMPUTER_CONSOLE_UNLOCK_STATUS_ACTION, COMPUTER_CONSOLE_UNLOCK_RECOVER_ACTION, COMPUTER_CONSOLE_UNLOCK_REVOKE_ACTION].includes(input.actionId)) return undefined;
999
+ if (input.actionId === DESKTOP_TARGET_OPEN_ACTION) return targetAuthorization(stableIdentityFromArgs(input.args));
1000
+ const targetId = typeof input.args.target_id === 'string' ? input.args.target_id.trim() : '';
1001
+ if (targetId) return targetAuthorization(computerTargetAuthority.require(input.controllerHome, targetId).stableIdentity);
1002
+ const provider = desktopProvider(input);
1003
+ return provider.resolveAuthorizationContext?.(providerInput(input, input.actionId, input.args));
1004
+ }
1005
+
1006
+ export const computerPluginAdapter: AssistantPluginAdapter = {
1007
+ pluginId: 'computer',
1008
+ scope: 'controller_with_repository_overlay',
1009
+ buildManifest: buildComputerManifest,
1010
+ async resolveAuthorizationContext(input) {
1011
+ if (!isDesktopProductAction(input.actionId)) {
1012
+ return resolveBrowserPluginAuthorizationContext({ ...input, pluginId: 'browser' });
1013
+ }
1014
+ return resolveDesktopAuthorizationContext(input);
1015
+ },
1016
+ async executeAction(input) {
1017
+ if (!isDesktopProductAction(input.actionId)) {
1018
+ return executeBrowserPluginAction({ ...input, pluginId: 'browser' });
1019
+ }
1020
+ if (input.actionId === COMPUTER_CONSOLE_UNLOCK_PREPARE_ACTION) {
1021
+ return executeProtectedConsoleUnlockPreparation({ confirmAuthorization: input.confirmAuthorization === true, timeoutMs: input.timeoutMs }, input.controllerHome);
1022
+ }
1023
+ if (input.actionId === COMPUTER_CONSOLE_UNLOCK_ACTION) {
1024
+ return executeProtectedConsoleUnlockInvocation({
1025
+ credentialHandle: typeof input.args.credential_handle === 'string' ? input.args.credential_handle : '',
1026
+ confirmAuthorization: input.confirmAuthorization === true,
1027
+ timeoutMs: input.timeoutMs,
1028
+ }, input.controllerHome);
1029
+ }
1030
+ if (input.actionId === COMPUTER_CONSOLE_UNLOCK_ENROLL_ACTION) {
1031
+ return executeProtectedConsoleUnlockLifecycle('console_unlock_enroll', { confirmAuthorization: input.confirmAuthorization === true, timeoutMs: input.timeoutMs }, input.controllerHome);
1032
+ }
1033
+ if (input.actionId === COMPUTER_CONSOLE_UNLOCK_STATUS_ACTION) {
1034
+ return executeProtectedConsoleUnlockLifecycle('console_unlock_status', { confirmAuthorization: input.confirmAuthorization === true, timeoutMs: input.timeoutMs }, input.controllerHome);
1035
+ }
1036
+ if (input.actionId === COMPUTER_CONSOLE_UNLOCK_RECOVER_ACTION) {
1037
+ return executeProtectedConsoleUnlockLifecycle('console_unlock_recover', { confirmAuthorization: input.confirmAuthorization === true, timeoutMs: input.timeoutMs }, input.controllerHome);
1038
+ }
1039
+ if (input.actionId === COMPUTER_CONSOLE_UNLOCK_REVOKE_ACTION) {
1040
+ return executeProtectedConsoleUnlockLifecycle('console_unlock_revoke', { confirmAuthorization: input.confirmAuthorization === true, timeoutMs: input.timeoutMs }, input.controllerHome);
1041
+ }
1042
+ if (input.actionId === DESKTOP_TARGET_CLOSE_ACTION) return closeDesktopTarget(input, optionalDesktopProvider(input));
1043
+ const provider = desktopProvider(input);
1044
+ if (input.actionId === DESKTOP_TARGET_OPEN_ACTION) return openDesktopTarget(input, provider);
1045
+ return executeDesktopSemanticAction(input, provider);
1046
+ },
1047
+ shouldRefreshManifestAfterAction(actionId) {
1048
+ return actionId === 'configure';
1049
+ },
1050
+ };