@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
@@ -6,10 +6,12 @@ import {
6
6
  callBrowserAutomationBroker,
7
7
  captureBrowserAutomationRegion,
8
8
  type BrowserAutomationBrokerAction,
9
+ type BrowserAutomationSemanticTargetProof,
9
10
  type BrowserAutomationTrustedInput,
11
+ type BrowserAutomationTrustedInputRequest,
10
12
  } from './browser-automation-service';
11
13
  import { AssistantPluginError } from './errors';
12
- import type { BrowserNativeAttachAttempt, BrowserNativeProduct } from './browser-session-types';
14
+ import type { BrowserNativeAttachAttempt, BrowserNativeProduct } from '../../../packages/protocols/browser/index';
13
15
 
14
16
  const RECORD_SEPARATOR = String.fromCharCode(30);
15
17
  const DEFAULT_NATIVE_TIMEOUT_MS = 5_000;
@@ -64,6 +66,8 @@ export interface MacOsBrowserTabInventoryEntry {
64
66
  url: string;
65
67
  title: string;
66
68
  active: boolean;
69
+ /** True when this tab is active in the frontmost browser window. */
70
+ frontmost?: boolean;
67
71
  }
68
72
 
69
73
  export interface MacOsBrowserTabInventory {
@@ -119,7 +123,7 @@ function execFileText(file: string, args: string[], timeoutMs: number): Promise<
119
123
  }, (error, stdout, stderr) => {
120
124
  if (error) {
121
125
  const diagnostic = String(stderr || error.message).trim().slice(-2_000);
122
- reject(new Error(diagnostic || error.message));
126
+ reject(new Error(diagnostic || error.message, { cause: error }));
123
127
  return;
124
128
  }
125
129
  resolve(String(stdout).trim());
@@ -134,8 +138,12 @@ const defaultRuntimeHooks: MacOsBrowserRuntimeHooks = {
134
138
  try {
135
139
  await execFileText('/usr/bin/pgrep', ['-x', processName], timeoutMs);
136
140
  return true;
137
- } catch {
138
- return false;
141
+ } catch (error) {
142
+ // pgrep's no-match exit is absence; timeout/permission/transport failure
143
+ // cannot prove that an application's tabs are absent.
144
+ const cause = error instanceof Error ? error.cause : undefined;
145
+ if (cause && typeof cause === 'object' && 'code' in cause && cause.code === 1) return false;
146
+ throw error;
139
147
  }
140
148
  },
141
149
  };
@@ -227,6 +235,12 @@ async function runBrowserAutomationText(
227
235
  testArgs: string[],
228
236
  timeoutMs: number,
229
237
  ): Promise<string> {
238
+ // AppleScript `tell application` starts an application that is not already
239
+ // running while it compiles the script. Every browser entry point therefore
240
+ // fails closed unless the exact browser process is already live, so routine
241
+ // inventory/reconcile work can never launch the user's browser or hand Forge
242
+ // an unauthenticated profile.
243
+ if ('product' in request) await assertMacOsBrowserApplicationRunning(request.product, timeoutMs);
230
244
  if (runtimeHooks.runAppleScript) return await runtimeHooks.runAppleScript(testScript, testArgs, timeoutMs);
231
245
  const result = await callBrowserAutomationBroker(request, timeoutMs);
232
246
  if (typeof result.value !== 'string') {
@@ -239,6 +253,76 @@ async function runBrowserAutomationText(
239
253
  return result.value;
240
254
  }
241
255
 
256
+ /**
257
+ * Non-launching precondition for every Apple Events browser operation.
258
+ * Path existence is checked without scripting the application, and process
259
+ * liveness comes from the process table, so neither probe can start a browser.
260
+ */
261
+ export async function assertMacOsBrowserApplicationRunning(
262
+ product: MacOsBrowserProduct,
263
+ timeoutMs = DEFAULT_NATIVE_TIMEOUT_MS,
264
+ ): Promise<void> {
265
+ const browser = browserDefinition(product);
266
+ const details = { browserProduct: product, bundleId: browser.bundleId, appName: browser.appName };
267
+ if (runtimeHooks.platform !== 'darwin') {
268
+ throw new AssistantPluginError(
269
+ 'PLUGIN_BROWSER_NATIVE_APP_UNSUPPORTED_PLATFORM',
270
+ `Native ${browser.appName} Apple Events are unavailable on ${runtimeHooks.platform}.`,
271
+ { retryable: false, details },
272
+ );
273
+ }
274
+ if (!browser.appPaths.some((path) => runtimeHooks.appExists(path))) {
275
+ throw new AssistantPluginError(
276
+ 'PLUGIN_BROWSER_NATIVE_APP_NOT_INSTALLED',
277
+ `${browser.appName} is not installed; Forge never installs or substitutes a browser application.`,
278
+ { retryable: false, details },
279
+ );
280
+ }
281
+ if (!(await runtimeHooks.processRunning(browser.processName, timeoutMs))) {
282
+ throw new AssistantPluginError(
283
+ 'PLUGIN_BROWSER_NATIVE_APP_NOT_RUNNING',
284
+ `${browser.appName} is not running; Forge never launches a browser application implicitly.`,
285
+ { retryable: true, details },
286
+ );
287
+ }
288
+ }
289
+
290
+ /**
291
+ * Start only the browser family already chosen by the Computer target. This
292
+ * is deliberately narrower than a generic browser launch: it never guesses a
293
+ * product, profile, or authentication identity. The caller must have a
294
+ * durable preferred product and must still verify the resulting ChatGPT page
295
+ * before any provider mutation.
296
+ */
297
+ export async function ensureMacOsBrowserApplicationRunning(
298
+ product: MacOsBrowserProduct,
299
+ timeoutMs = DEFAULT_NATIVE_TIMEOUT_MS,
300
+ ): Promise<void> {
301
+ const browser = browserDefinition(product);
302
+ if (runtimeHooks.platform !== 'darwin') throw new AssistantPluginError(
303
+ 'PLUGIN_BROWSER_NATIVE_APP_UNSUPPORTED_PLATFORM',
304
+ `Native ${browser.appName} Apple Events are unavailable on ${runtimeHooks.platform}.`,
305
+ { retryable: false, details: { browserProduct: product } },
306
+ );
307
+ if (!browser.appPaths.some((path) => runtimeHooks.appExists(path))) throw new AssistantPluginError(
308
+ 'PLUGIN_BROWSER_NATIVE_APP_NOT_INSTALLED',
309
+ `${browser.appName} is not installed.`,
310
+ { retryable: false, details: { browserProduct: product } },
311
+ );
312
+ if (await runtimeHooks.processRunning(browser.processName, timeoutMs)) return;
313
+ await execFileText('/usr/bin/open', ['-a', browser.appName], timeoutMs);
314
+ const deadline = Date.now() + Math.max(1_000, timeoutMs);
315
+ while (Date.now() < deadline) {
316
+ if (await runtimeHooks.processRunning(browser.processName, Math.min(1_000, timeoutMs))) return;
317
+ await new Promise((resolve) => setTimeout(resolve, 100));
318
+ }
319
+ throw new AssistantPluginError(
320
+ 'PLUGIN_BROWSER_NATIVE_APP_START_TIMEOUT',
321
+ `${browser.appName} did not become available after Forge started the remembered browser family.`,
322
+ { retryable: true, details: { browserProduct: product } },
323
+ );
324
+ }
325
+
242
326
  async function captureBrowserAutomation(
243
327
  region: { x: number; y: number; width: number; height: number },
244
328
  path: string,
@@ -251,7 +335,7 @@ async function captureBrowserAutomation(
251
335
  }
252
336
 
253
337
  async function sendBrowserTrustedInput(
254
- request: Extract<BrowserAutomationBrokerAction, { action: 'trusted_input' }>,
338
+ request: BrowserAutomationTrustedInputRequest,
255
339
  timeoutMs: number,
256
340
  ): Promise<void> {
257
341
  if (runtimeHooks.trustedInput) {
@@ -267,7 +351,7 @@ async function sendBrowserTrustedInput(
267
351
  || /\bBROWSER_AUTOMATION_ACTION_UNSUPPORTED\b/.test(message)) {
268
352
  throw new AssistantPluginError(
269
353
  'PLUGIN_BROWSER_TRUSTED_INPUT_UNAVAILABLE',
270
- 'Installed Forge Desktop Operator does not support native browser trusted input. Keep the exact tab explicitly foregrounded and use a separately grounded Desktop Operator interaction, or upgrade the stable Desktop Operator provider.',
354
+ 'The configured Computer input provider does not support native browser trusted input. Keep the exact tab explicitly foregrounded and use a separately grounded Computer interaction, or upgrade the configured provider.',
271
355
  { retryable: false, details: { browserProduct: request.product, requiredProviderAction: 'trusted_input' } },
272
356
  );
273
357
  }
@@ -333,6 +417,15 @@ export function getMacOsBrowserAttachObservation(): MacOsBrowserAttachObservatio
333
417
  : undefined;
334
418
  }
335
419
 
420
+ function recordSuccessfulMacOsBrowserAttachment(attachment: MacOsBrowserAttachment): void {
421
+ lastAttachObservation = {
422
+ checkedAt: new Date().toISOString(),
423
+ ready: true,
424
+ selectedProduct: attachment.metadata.product,
425
+ attempts: attachment.attempts.map((attempt) => ({ ...attempt })),
426
+ };
427
+ }
428
+
336
429
  const BROWSERS: Record<MacOsBrowserProduct, MacOsBrowserDefinition> = {
337
430
  chrome: {
338
431
  product: 'chrome',
@@ -396,6 +489,8 @@ set maxTabs to 256
396
489
  set returnedCount to 0
397
490
  set truncatedInventory to false
398
491
  set outputText to "false"
492
+ set frontWindowId to ""
493
+ if (count of windows) is greater than 0 then set frontWindowId to ((id of front window) as text)
399
494
  repeat with candidateWindow in windows
400
495
  set activeTabId to ""
401
496
  try
@@ -408,10 +503,11 @@ repeat with candidateWindow in windows
408
503
  end if
409
504
  set candidateWindowId to ((id of candidateWindow) as text)
410
505
  set candidateTabId to ((id of candidateTab) as text)
506
+ set candidateFrontmost to (candidateWindowId is frontWindowId)
411
507
  set candidateURL to my cleanField((URL of candidateTab as text), recordSeparator, fieldSeparator)
412
508
  set candidateTitle to my cleanField((title of candidateTab as text), recordSeparator, fieldSeparator)
413
509
  set candidateActive to (candidateTabId is activeTabId)
414
- set outputText to outputText & recordSeparator & candidateWindowId & fieldSeparator & candidateTabId & fieldSeparator & (candidateActive as text) & fieldSeparator & candidateURL & fieldSeparator & candidateTitle
510
+ set outputText to outputText & recordSeparator & candidateWindowId & fieldSeparator & candidateTabId & fieldSeparator & (candidateActive as text) & fieldSeparator & (candidateFrontmost as text) & fieldSeparator & candidateURL & fieldSeparator & candidateTitle
415
511
  set returnedCount to returnedCount + 1
416
512
  end repeat
417
513
  if truncatedInventory then exit repeat
@@ -449,14 +545,23 @@ function parseTabInventory(product: MacOsBrowserProduct, raw: string): MacOsBrow
449
545
  const windowId = (fields[0] ?? '').trim();
450
546
  const tabId = (fields[1] ?? '').trim();
451
547
  const activeText = (fields[2] ?? '').trim().toLowerCase();
452
- if (!windowId || !tabId || (activeText !== 'true' && activeText !== 'false')) {
548
+ const hasFrontmostField = fields.length >= 6 && ['true', 'false'].includes((fields[3] ?? '').trim().toLowerCase());
549
+ const frontmostText = hasFrontmostField ? (fields[3] ?? '').trim().toLowerCase() : undefined;
550
+ if (!windowId || !tabId || (activeText !== 'true' && activeText !== 'false') || (fields.length >= 6 && !hasFrontmostField)) {
453
551
  throw new AssistantPluginError(
454
552
  'PLUGIN_MACOS_CAPABILITY_BROKER_PROTOCOL_ERROR',
455
553
  'Stable Forge macOS capability broker returned invalid browser tab inventory metadata.',
456
554
  { retryable: true },
457
555
  );
458
556
  }
459
- tabs.push({ windowId, tabId, active: activeText === 'true', url: fields[3] ?? '', title: fields.slice(4).join(fieldSeparator) });
557
+ tabs.push({
558
+ windowId,
559
+ tabId,
560
+ active: activeText === 'true',
561
+ ...(frontmostText ? { frontmost: frontmostText === 'true' } : {}),
562
+ url: fields[hasFrontmostField ? 4 : 3] ?? '',
563
+ title: fields.slice(hasFrontmostField ? 5 : 4).join(fieldSeparator),
564
+ });
460
565
  if (tabs.length > 256) {
461
566
  throw new AssistantPluginError(
462
567
  'PLUGIN_MACOS_CAPABILITY_BROKER_PROTOCOL_ERROR',
@@ -498,27 +603,78 @@ return (frontmost as text) & separator & (URL of targetTab as text) & separator
498
603
  function activateTargetTabScript(browser: MacOsBrowserDefinition, ref: MacOsBrowserTabRef): string {
499
604
  return browserTellScript(browser, `
500
605
  ${targetTabPreamble(ref)}
501
- set targetTabIndex to 1
502
- repeat with candidateTab in tabs of targetWindow
503
- if ((id of candidateTab) as text) is ((id of targetTab) as text) then exit repeat
504
- set targetTabIndex to targetTabIndex + 1
606
+ -- Activating by position is only safe inside the same enumeration that produced
607
+ -- the index. A tab created or closed by the provider between those two steps
608
+ -- makes the positional write fail with -1719 ("Can't get item N of every tab"),
609
+ -- so each attempt re-reads the tab list, bounds the index and verifies the exact
610
+ -- tab became active before it is reported as done.
611
+ set targetTabIdText to ((id of targetTab) as text)
612
+ set activationConfirmed to false
613
+ repeat 3 times
614
+ set targetTabIndex to 0
615
+ set candidateIndex to 0
616
+ repeat with candidateTab in tabs of targetWindow
617
+ set candidateIndex to candidateIndex + 1
618
+ if ((id of candidateTab) as text) is targetTabIdText then set targetTabIndex to candidateIndex
619
+ end repeat
620
+ if targetTabIndex is greater than 0 then
621
+ try
622
+ if targetTabIndex is less than or equal to (count of tabs of targetWindow) then
623
+ set active tab index of targetWindow to targetTabIndex
624
+ if ((id of active tab of targetWindow) as text) is targetTabIdText then set activationConfirmed to true
625
+ end if
626
+ end try
627
+ end if
628
+ if activationConfirmed then exit repeat
629
+ delay 0.05
505
630
  end repeat
506
- set active tab index of targetWindow to targetTabIndex
507
631
  set index of targetWindow to 1
508
632
  activate
509
633
  `);
510
634
  }
511
635
 
512
- function createOwnedTabScript(browser: MacOsBrowserDefinition): string {
636
+ function createOwnedTabScript(browser: MacOsBrowserDefinition, preferredWindowId?: string): string {
513
637
  return `on run argv
514
638
  set targetUrl to item 1 of argv
515
639
  ${browserTellScript(browser, `
516
- if (count of windows) is 0 then error "FORGE_NO_BROWSER_WINDOW"
517
- set targetWindow to front window
518
- set originalActiveIndex to active tab index of targetWindow
519
- set targetTab to make new tab at end of tabs of targetWindow with properties {URL:targetUrl}
640
+ set preferredWindowId to "${preferredWindowId ?? ''}"
641
+ set targetWindow to missing value
642
+ if preferredWindowId is not "" then
643
+ repeat with candidateWindow in windows
644
+ if ((id of candidateWindow) as text) is preferredWindowId then
645
+ set targetWindow to candidateWindow
646
+ exit repeat
647
+ end if
648
+ end repeat
649
+ end if
650
+ if targetWindow is missing value and (count of windows) is greater than 0 then set targetWindow to front window
651
+ if targetWindow is missing value then
652
+ set targetWindow to make new window
653
+ set targetTab to active tab of targetWindow
654
+ set URL of targetTab to targetUrl
655
+ else
656
+ set targetWindow to front window
657
+ set originalActiveTabId to ((id of active tab of targetWindow) as text)
658
+ set targetTab to make new tab at end of tabs of targetWindow with properties {URL:targetUrl}
659
+ -- Restore the previously active tab by identity, never by a stale position:
660
+ -- the new tab can shift Chrome's tab order and make a pre-create index invalid.
661
+ repeat 3 times
662
+ if ((id of active tab of targetWindow) as text) is originalActiveTabId then exit repeat
663
+ set restoreIndex to 0
664
+ set candidateIndex to 0
665
+ repeat with candidateTab in tabs of targetWindow
666
+ set candidateIndex to candidateIndex + 1
667
+ if ((id of candidateTab) as text) is originalActiveTabId then set restoreIndex to candidateIndex
668
+ end repeat
669
+ if restoreIndex is 0 then exit repeat
670
+ try
671
+ if restoreIndex is less than or equal to (count of tabs of targetWindow) then set active tab index of targetWindow to restoreIndex
672
+ end try
673
+ if ((id of active tab of targetWindow) as text) is originalActiveTabId then exit repeat
674
+ delay 0.05
675
+ end repeat
676
+ end if
520
677
  set targetTabId to id of targetTab
521
- set active tab index of targetWindow to originalActiveIndex
522
678
  set separator to ASCII character 30
523
679
  return ((id of targetWindow) as text) & separator & (targetTabId as text)
524
680
  `)}
@@ -674,18 +830,14 @@ export async function discoverMacOsBrowserAttachment(
674
830
  }
675
831
  const selectedAttempt = attempts.find((entry) => entry.product === selected.metadata.product);
676
832
  if (selectedAttempt) selectedAttempt.status = 'selected';
677
- lastAttachObservation = {
678
- checkedAt: new Date().toISOString(),
679
- ready: true,
680
- selectedProduct: selected.metadata.product,
681
- attempts: attempts.map((attempt) => ({ ...attempt })),
833
+ const attachment: MacOsBrowserAttachment = {
834
+ metadata: selected.metadata,
835
+ attempts,
682
836
  };
837
+ recordSuccessfulMacOsBrowserAttachment(attachment);
683
838
  return {
684
839
  attempts,
685
- attachment: {
686
- metadata: selected.metadata,
687
- attempts,
688
- },
840
+ attachment,
689
841
  };
690
842
  }
691
843
 
@@ -794,7 +946,11 @@ export class MacOsAppleEventsPage {
794
946
  return await runBrowserAutomationText(effectiveRequest, effectiveScript, args, timeoutMs);
795
947
  } catch (error) {
796
948
  const message = error instanceof Error ? error.message : String(error);
797
- throw new AssistantPluginError('PLUGIN_BROWSER_NATIVE_OPERATION_FAILED', `${this.browser.appName} Apple Events operation failed: ${message}`, {
949
+ // Keep the broker's bounded timeout/serialization identity visible to
950
+ // the sole Supervisor retry policy. Flattening both to the generic
951
+ // operation error makes a blocked tab hot-loop against the global lane.
952
+ const brokerFailure = /\b(BROWSER_AUTOMATION_TIMEOUT|BROWSER_AUTOMATION_SERIALIZATION_BUSY)\b/.exec(message)?.[1];
953
+ throw new AssistantPluginError(brokerFailure ?? 'PLUGIN_BROWSER_NATIVE_OPERATION_FAILED', `${this.browser.appName} Apple Events operation failed: ${message}`, {
798
954
  retryable: true,
799
955
  details: { browserProduct: this.browser.product, bundleId: this.browser.bundleId },
800
956
  });
@@ -1113,6 +1269,57 @@ export class MacOsAppleEventsPage {
1113
1269
  await this.refreshMetadata();
1114
1270
  }
1115
1271
 
1272
+ /**
1273
+ * Supervisor-only semantic text boundary. Browser owns exact tab + DOM focus;
1274
+ * Computer receives only a one-shot semantic target proof and remains the OS
1275
+ * mutation transport. Generic Browser trusted text keeps its compatibility
1276
+ * semantics and does not implicitly become ChatGPT-specific.
1277
+ */
1278
+ async trustedSemanticTextInput(text: string): Promise<void> {
1279
+ if (!this.targetRef) {
1280
+ throw new AssistantPluginError('PLUGIN_BROWSER_TRUSTED_INPUT_UNAVAILABLE', 'Semantic trusted text requires an exact saved browser tab.', { retryable: false });
1281
+ }
1282
+ this.targetRef = await resolveCurrentMacOsBrowserTabRef(this.browser.product, this.targetRef, this.timeoutMs);
1283
+ const metadata = await readResolvedMacOsBrowserOwnedTabMetadata(this.browser.product, this.targetRef, this.timeoutMs);
1284
+ if (!metadata.frontmost || metadata.active !== true) {
1285
+ throw new AssistantPluginError(
1286
+ 'PLUGIN_BROWSER_FOREGROUND_REQUIRED',
1287
+ 'Semantic trusted text requires the exact saved browser tab to be frontmost and active.',
1288
+ { retryable: true, details: { browserProduct: this.browser.product, windowId: this.targetRef.windowId, tabId: this.targetRef.tabId } },
1289
+ );
1290
+ }
1291
+ const semanticTarget = await this.evaluate<BrowserAutomationSemanticTargetProof & { valid?: boolean }>(`(() => {
1292
+ const element = document.activeElement;
1293
+ if (!(element instanceof HTMLElement)) return { valid: false };
1294
+ const tag = element.tagName.toLowerCase();
1295
+ const inputType = element instanceof HTMLInputElement ? String(element.type || 'text').toLowerCase() : '';
1296
+ const textInput = element instanceof HTMLTextAreaElement
1297
+ || element.isContentEditable
1298
+ || (element instanceof HTMLInputElement && !['button','checkbox','color','file','hidden','image','radio','range','reset','submit'].includes(inputType));
1299
+ const accessibleName = String(element.getAttribute('aria-label') || element.getAttribute('placeholder') || element.getAttribute('title') || element.getAttribute('name') || '').trim();
1300
+ const domRole = String(element.getAttribute('role') || (textInput ? 'textbox' : '')).trim();
1301
+ const multiline = element instanceof HTMLTextAreaElement || element.isContentEditable || element.getAttribute('aria-multiline') === 'true';
1302
+ return { valid: textInput && document.activeElement === element && Boolean(domRole) && Boolean(accessibleName), domRole, accessibleName, editable: true, focused: true, multiline };
1303
+ })()`);
1304
+ if (semanticTarget.valid !== true || semanticTarget.editable !== true || semanticTarget.focused !== true
1305
+ || !semanticTarget.domRole || !semanticTarget.accessibleName) {
1306
+ throw new AssistantPluginError(
1307
+ 'PLUGIN_BROWSER_TRUSTED_INPUT_SEMANTIC_TARGET_UNPROVEN',
1308
+ 'Browser could not prove one focused editable DOM target with an accessible identity before trusted text mutation.',
1309
+ { retryable: true, details: { browserProduct: this.browser.product, windowId: this.targetRef.windowId, tabId: this.targetRef.tabId } },
1310
+ );
1311
+ }
1312
+ const { valid: _valid, ...proof } = semanticTarget;
1313
+ await sendBrowserTrustedInput({
1314
+ action: 'trusted_input',
1315
+ product: this.browser.product,
1316
+ ref: this.targetRef,
1317
+ input: { kind: 'text', text },
1318
+ semanticTarget: proof,
1319
+ }, this.timeoutMs);
1320
+ await this.refreshMetadata();
1321
+ }
1322
+
1116
1323
  async screenshot(options: Record<string, unknown>): Promise<Buffer> {
1117
1324
  const path = typeof options.path === 'string' ? options.path : undefined;
1118
1325
  if (!path) throw new Error('Native browser screenshot requires an output path.');
@@ -1181,8 +1388,15 @@ export class MacOsAppleEventsPage {
1181
1388
  const prototype = element instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
1182
1389
  const setter = Object.getOwnPropertyDescriptor(prototype, 'value')?.set;
1183
1390
  if (setter) setter.call(element, ${JSON.stringify(value)}); else element.value = ${JSON.stringify(value)};
1184
- } else if (element.isContentEditable) element.textContent = ${JSON.stringify(value)};
1185
- else throw new Error('Element does not accept text input.');
1391
+ } else if (element.isContentEditable) {
1392
+ element.focus();
1393
+ const selection = window.getSelection();
1394
+ if (!selection) throw new Error('Contenteditable selection unavailable.');
1395
+ const range = document.createRange();
1396
+ range.selectNodeContents(element); selection.removeAllRanges(); selection.addRange(range);
1397
+ if (!document.execCommand('insertText', false, ${JSON.stringify(value)})) throw new Error('Contenteditable insertion rejected.');
1398
+ return true;
1399
+ } else throw new Error('Element does not accept text input.');
1186
1400
  element.dispatchEvent(new Event('input', { bubbles: true }));
1187
1401
  element.dispatchEvent(new Event('change', { bubbles: true }));
1188
1402
  return true;
@@ -1190,8 +1404,26 @@ export class MacOsAppleEventsPage {
1190
1404
  }
1191
1405
 
1192
1406
  async type(selector: string, text: string): Promise<void> {
1193
- const current = await this.evaluate<string>(selectorSource(selector, `return 'value' in element ? String(element.value || '') : String(element.textContent || '');`));
1194
- await this.fill(selector, `${current}${text}`);
1407
+ await this.evaluate(selectorSource(selector, `
1408
+ if ('value' in element) {
1409
+ element.focus();
1410
+ const value = String(element.value || '');
1411
+ const prototype = element instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
1412
+ const setter = Object.getOwnPropertyDescriptor(prototype, 'value')?.set;
1413
+ if (setter) setter.call(element, value + ${JSON.stringify(text)}); else element.value = value + ${JSON.stringify(text)};
1414
+ element.dispatchEvent(new Event('input', { bubbles: true }));
1415
+ return true;
1416
+ }
1417
+ if (!element.isContentEditable) throw new Error('Element does not accept text input.');
1418
+ element.focus();
1419
+ const selection = window.getSelection();
1420
+ if (!selection) throw new Error('Contenteditable selection unavailable.');
1421
+ const range = document.createRange();
1422
+ range.selectNodeContents(element); range.collapse(false);
1423
+ selection.removeAllRanges(); selection.addRange(range);
1424
+ if (!document.execCommand('insertText', false, ${JSON.stringify(text)})) throw new Error('Contenteditable insertion rejected.');
1425
+ return true;
1426
+ `));
1195
1427
  }
1196
1428
 
1197
1429
  async press(selector: string, key: string): Promise<void> {
@@ -1230,10 +1462,13 @@ export class MacOsAppleEventsPage {
1230
1462
 
1231
1463
  private async setChecked(selector: string, checked: boolean): Promise<void> {
1232
1464
  await this.evaluate(selectorSource(selector, `
1233
- if (!('checked' in element)) throw new Error('Element is not checkable.');
1234
- element.checked = ${checked};
1235
- element.dispatchEvent(new Event('input', { bubbles: true }));
1236
- element.dispatchEvent(new Event('change', { bubbles: true }));
1465
+ if (!('checked' in element) || typeof element.click !== 'function') {
1466
+ throw new Error('Element is not checkable.');
1467
+ }
1468
+ if (element.checked !== ${checked}) element.click();
1469
+ if (element.checked !== ${checked}) {
1470
+ throw new Error('Requested checked state did not persist.');
1471
+ }
1237
1472
  return true;
1238
1473
  `));
1239
1474
  }
@@ -1341,7 +1576,7 @@ async function resolveCurrentMacOsBrowserTabRef(
1341
1576
  ): Promise<MacOsBrowserTabRef> {
1342
1577
  // Existing unit-level AppleScript hooks historically model one exact script at a time.
1343
1578
  // Preserve that narrow test seam unless a live inventory hook is explicitly supplied;
1344
- // production always resolves through the stable Desktop Operator broker inventory.
1579
+ // production always resolves through the configured Computer provider inventory.
1345
1580
  const inventory = runtimeHooks.tabInventory
1346
1581
  ? await runtimeHooks.tabInventory(product, timeoutMs)
1347
1582
  : runtimeHooks.runAppleScript
@@ -1375,18 +1610,58 @@ async function resolveCurrentMacOsBrowserTabRef(
1375
1610
  return { windowId: match.windowId, tabId: match.tabId };
1376
1611
  }
1377
1612
 
1613
+ export interface MacOsBrowserTabInventoryOptions {
1614
+ /**
1615
+ * Correct stale active/frontmost bits through one extra foreground metadata
1616
+ * read. Exact-target callers that only need stable windowId/tabId/url identity
1617
+ * can disable this optional probe so a blocked foreground Apple Events read
1618
+ * cannot starve the inventory itself.
1619
+ */
1620
+ correctFrontmost?: boolean;
1621
+ }
1622
+
1378
1623
  export async function listMacOsBrowserTabs(
1379
1624
  product: MacOsBrowserProduct,
1380
1625
  timeoutMs = DEFAULT_NATIVE_TIMEOUT_MS,
1626
+ options: MacOsBrowserTabInventoryOptions = {},
1381
1627
  ): Promise<MacOsBrowserTabInventory> {
1382
1628
  const browser = browserDefinition(product);
1629
+ // Capture the frontmost tab before reading the stable inventory when callers
1630
+ // need corrected UI-current metadata. Exact-target identity does not depend on
1631
+ // this optional foreground probe.
1632
+ const inspected = options.correctFrontmost === false
1633
+ ? undefined
1634
+ : await inspectBrowser(product, timeoutMs);
1383
1635
  const raw = await runBrowserAutomationText(
1384
1636
  { action: 'list_tabs', product },
1385
1637
  listTabsScript(browser),
1386
1638
  [],
1387
1639
  timeoutMs,
1388
1640
  );
1389
- return parseTabInventory(product, raw);
1641
+ const inventory = parseTabInventory(product, raw);
1642
+ if (!inspected) return inventory;
1643
+ const metadata = inspected.metadata;
1644
+ const current = metadata?.frontmost === true && metadata.active !== false
1645
+ ? { windowId: metadata.windowId, tabId: metadata.tabId, url: metadata.url.trim() }
1646
+ : undefined;
1647
+ if (!current) return inventory;
1648
+ const hasIdentity = Boolean(current.windowId && current.tabId);
1649
+ const currentMatches = inventory.tabs.filter(tab => (
1650
+ hasIdentity
1651
+ ? tab.windowId === current.windowId && tab.tabId === current.tabId
1652
+ : Boolean(current.url) && tab.url.trim() === current.url
1653
+ ));
1654
+ const currentMatch = currentMatches.length === 1 ? currentMatches[0] : undefined;
1655
+ if (!currentMatch) return inventory;
1656
+ return {
1657
+ ...inventory,
1658
+ tabs: inventory.tabs.map(tab => ({
1659
+ ...tab,
1660
+ ...(currentMatch.windowId === tab.windowId && currentMatch.tabId === tab.tabId
1661
+ ? { active: true, frontmost: true }
1662
+ : { frontmost: false }),
1663
+ })),
1664
+ };
1390
1665
  }
1391
1666
 
1392
1667
  export async function readMacOsBrowserOwnedTabMetadata(
@@ -1394,11 +1669,24 @@ export async function readMacOsBrowserOwnedTabMetadata(
1394
1669
  ref: MacOsBrowserTabRef,
1395
1670
  timeoutMs = DEFAULT_NATIVE_TIMEOUT_MS,
1396
1671
  ): Promise<MacOsBrowserMetadata> {
1397
- const browser = browserDefinition(product);
1398
1672
  const resolvedRef = await resolveCurrentMacOsBrowserTabRef(product, ref, timeoutMs);
1673
+ return await readResolvedMacOsBrowserOwnedTabMetadata(product, resolvedRef, timeoutMs);
1674
+ }
1675
+
1676
+ /**
1677
+ * Read one exact native tab whose stable identity is already authoritative for
1678
+ * the caller. The targeted AppleScript still fails closed when that tab id is
1679
+ * gone, but does not perform another full browser inventory.
1680
+ */
1681
+ export async function readResolvedMacOsBrowserOwnedTabMetadata(
1682
+ product: MacOsBrowserProduct,
1683
+ ref: MacOsBrowserTabRef,
1684
+ timeoutMs = DEFAULT_NATIVE_TIMEOUT_MS,
1685
+ ): Promise<MacOsBrowserMetadata> {
1686
+ const browser = browserDefinition(product);
1399
1687
  return parseMetadata(product, await runBrowserAutomationText(
1400
- { action: 'metadata', product, ref: resolvedRef },
1401
- targetMetadataScript(browser, resolvedRef),
1688
+ { action: 'metadata', product, ref },
1689
+ targetMetadataScript(browser, ref),
1402
1690
  [],
1403
1691
  timeoutMs,
1404
1692
  ));
@@ -1464,6 +1752,41 @@ export async function createMacOsBrowserOwnedPage(
1464
1752
  return page;
1465
1753
  }
1466
1754
 
1755
+ export async function createMacOsBrowserOwnedPageForProduct(
1756
+ product: MacOsBrowserProduct,
1757
+ url: string,
1758
+ attempts: MacOsBrowserAttachAttempt[],
1759
+ preferredWindowId?: string,
1760
+ timeoutMs = DEFAULT_NATIVE_TIMEOUT_MS,
1761
+ ): Promise<{ page: MacOsAppleEventsPage; attachment: MacOsBrowserAttachment }> {
1762
+ const browser = browserDefinition(product);
1763
+ const creationEvidence = await runCreateTabAutomation(
1764
+ { action: 'create_tab', product, url },
1765
+ createOwnedTabScript(browser, preferredWindowId),
1766
+ [url],
1767
+ timeoutMs,
1768
+ );
1769
+ const ref = creationEvidence.ref;
1770
+ const attachment: MacOsBrowserAttachment = {
1771
+ attempts: attempts.map((attempt) => ({ ...attempt })),
1772
+ metadata: {
1773
+ product,
1774
+ appName: browser.appName,
1775
+ bundleId: browser.bundleId,
1776
+ frontmost: false,
1777
+ url,
1778
+ title: '',
1779
+ bounds: { x: 0, y: 0, width: 0, height: 0 },
1780
+ windowId: ref.windowId,
1781
+ tabId: ref.tabId,
1782
+ active: false,
1783
+ },
1784
+ };
1785
+ const page = new MacOsAppleEventsPage(attachment, timeoutMs, ref, creationEvidence);
1786
+ rememberMacOsBrowserPageHandle(product, ref, page);
1787
+ return { page, attachment };
1788
+ }
1789
+
1467
1790
  export async function reattachMacOsBrowserOwnedPage(
1468
1791
  product: MacOsBrowserProduct,
1469
1792
  ref: MacOsBrowserTabRef,
@@ -1488,6 +1811,7 @@ export async function reattachMacOsBrowserOwnedPage(
1488
1811
  : ref;
1489
1812
  const page = new MacOsAppleEventsPage(attachment, timeoutMs, resolvedRef);
1490
1813
  rememberMacOsBrowserPageHandle(product, resolvedRef, page);
1814
+ recordSuccessfulMacOsBrowserAttachment(attachment);
1491
1815
  return { page, attachment };
1492
1816
  }
1493
1817
 
@@ -1496,12 +1820,28 @@ export async function closeMacOsBrowserOwnedTab(
1496
1820
  ref: MacOsBrowserTabRef,
1497
1821
  timeoutMs = DEFAULT_NATIVE_TIMEOUT_MS,
1498
1822
  ): Promise<void> {
1499
- const browser = browserDefinition(product);
1500
1823
  try {
1501
1824
  const resolvedRef = await resolveCurrentMacOsBrowserTabRef(product, ref, timeoutMs);
1825
+ await closeResolvedMacOsBrowserOwnedTab(product, resolvedRef, timeoutMs);
1826
+ } finally {
1827
+ invalidateMacOsBrowserPageHandle(product, ref);
1828
+ }
1829
+ }
1830
+
1831
+ /**
1832
+ * Close one exact native tab whose stable identity was already proven by the
1833
+ * caller's live inventory snapshot. This deliberately does not inventory again.
1834
+ */
1835
+ export async function closeResolvedMacOsBrowserOwnedTab(
1836
+ product: MacOsBrowserProduct,
1837
+ ref: MacOsBrowserTabRef,
1838
+ timeoutMs = DEFAULT_NATIVE_TIMEOUT_MS,
1839
+ ): Promise<void> {
1840
+ const browser = browserDefinition(product);
1841
+ try {
1502
1842
  await runBrowserAutomationText(
1503
- { action: 'close_tab', product, ref: resolvedRef },
1504
- closeOwnedTabScript(browser, resolvedRef),
1843
+ { action: 'close_tab', product, ref },
1844
+ closeOwnedTabScript(browser, ref),
1505
1845
  [],
1506
1846
  timeoutMs,
1507
1847
  );