@moretea-labs/forge 1.7.2 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (685) hide show
  1. package/AGENTS.md +58 -62
  2. package/CHANGELOG.md +26 -0
  3. package/CLAUDE.md +42 -62
  4. package/README.md +2 -2
  5. package/SKILL.md +0 -1
  6. package/THIRD_PARTY_NOTICES.md +5 -2
  7. package/adapters/browser/index.ts +2 -0
  8. package/adapters/chatgpt/browser-delivery-host.ts +71 -0
  9. package/adapters/chatgpt/browser-delivery-runtime.ts +783 -0
  10. package/adapters/chatgpt/controller-binding-store.ts +55 -0
  11. package/adapters/chatgpt/controller-host.ts +119 -0
  12. package/adapters/chatgpt/controller-round-host.ts +78 -0
  13. package/adapters/chatgpt/controller-round-settlement-store.ts +45 -0
  14. package/adapters/chatgpt/provider-delivery.ts +113 -0
  15. package/adapters/chatgpt/work-conversation-binding-store.ts +192 -0
  16. package/adapters/chatgpt/wsl-bridge-delivery-host.ts +63 -0
  17. package/adapters/computer/desktop-operator-contract.ts +7 -0
  18. package/adapters/computer/desktop-operator-discovery.ts +201 -0
  19. package/adapters/computer/desktop-operator-negotiation.ts +174 -0
  20. package/adapters/computer/desktop-operator-provider.ts +312 -0
  21. package/adapters/computer/index.ts +1 -0
  22. package/adapters/computer/interaction-target-authority.ts +944 -0
  23. package/adapters/controller-process/binding-store.ts +34 -0
  24. package/adapters/controller-process/controller-host.ts +26 -0
  25. package/adapters/mcp/access-mode.ts +132 -0
  26. package/adapters/mcp/audit.ts +32 -0
  27. package/adapters/mcp/auth.ts +407 -0
  28. package/adapters/mcp/controller-round-compatibility.ts +184 -0
  29. package/adapters/mcp/frozen-client-semantic-compatibility.ts +292 -0
  30. package/adapters/mcp/instructions.ts +36 -0
  31. package/adapters/mcp/legacy-context.ts +18 -0
  32. package/adapters/mcp/multi-repository.ts +437 -0
  33. package/adapters/mcp/oauth.ts +391 -0
  34. package/adapters/mcp/paths.ts +140 -0
  35. package/adapters/mcp/policy.ts +232 -0
  36. package/adapters/mcp/proxy-env.ts +62 -0
  37. package/adapters/mcp/readiness-projection.ts +24 -0
  38. package/adapters/mcp/redaction.ts +21 -0
  39. package/adapters/mcp/repo.ts +24 -0
  40. package/adapters/mcp/runtime-gateway/artifact-adapter.ts +52 -0
  41. package/adapters/mcp/runtime-gateway/context-adapter.ts +829 -0
  42. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +191 -0
  43. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +147 -0
  44. package/adapters/mcp/runtime-gateway/execution-control-adapter.ts +28 -0
  45. package/adapters/mcp/runtime-gateway/execution-tools.ts +207 -0
  46. package/adapters/mcp/runtime-gateway/filesystem-adapter.ts +38 -0
  47. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +411 -0
  48. package/adapters/mcp/runtime-gateway/legacy-ios-tool-adapter.ts +105 -0
  49. package/adapters/mcp/runtime-gateway/maintenance-adapter.ts +44 -0
  50. package/adapters/mcp/runtime-gateway/model-adapter.ts +63 -0
  51. package/adapters/mcp/runtime-gateway/persisted-check-process.ts +3 -0
  52. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +308 -0
  53. package/adapters/mcp/runtime-gateway/process-tools.ts +289 -0
  54. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +76 -0
  55. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +268 -0
  56. package/adapters/mcp/runtime-gateway/recovery-client-adapter.ts +70 -0
  57. package/adapters/mcp/runtime-gateway/recovery-tool-contract.ts +99 -0
  58. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +110 -0
  59. package/adapters/mcp/runtime-gateway/result-adapter.ts +108 -0
  60. package/adapters/mcp/runtime-gateway/router.ts +728 -0
  61. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1251 -0
  62. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +634 -0
  63. package/adapters/mcp/runtime-gateway/runtime-tool-shared.ts +27 -0
  64. package/adapters/mcp/runtime-gateway/runtime-tools.ts +68 -0
  65. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +186 -0
  66. package/adapters/mcp/runtime-gateway/shared-adapter.ts +25 -0
  67. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +870 -0
  68. package/adapters/mcp/runtime-gateway/work-adapter.ts +3186 -0
  69. package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +502 -0
  70. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +1 -0
  71. package/adapters/mcp/server.ts +1048 -0
  72. package/adapters/mcp/setup.ts +791 -0
  73. package/adapters/mcp/tool-capability-cache.ts +87 -0
  74. package/adapters/mcp/tool-mapping/access-tools.ts +387 -0
  75. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +5265 -0
  76. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +150 -0
  77. package/adapters/mcp/tool-mapping/repository-tools.ts +1691 -0
  78. package/adapters/mcp/tool-mapping/tools.ts +9 -0
  79. package/adapters/mcp/tool-mapping/umbrella-tools.ts +117 -0
  80. package/adapters/mcp/toolset-names.ts +74 -0
  81. package/adapters/mcp/toolset-selection.ts +41 -0
  82. package/adapters/mcp/toolset.ts +336 -0
  83. package/adapters/mcp/transports/http.ts +1456 -0
  84. package/adapters/mcp/transports/session-registry.ts +513 -0
  85. package/adapters/mcp/transports/stdio.ts +8 -0
  86. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +139 -0
  87. package/adapters/mcp/types.ts +41 -0
  88. package/assets/AGENTS.md +2 -16
  89. package/assets/CLAUDE.md +2 -16
  90. package/assets/hooks/AGENTS.md +3 -14
  91. package/assets/hooks/CLAUDE.md +3 -14
  92. package/assets/hooks/hook-input.sh +9 -2
  93. package/assets/hooks/lib/workflow-state.sh +28 -10
  94. package/assets/hooks/prompt-guard.sh +63 -37
  95. package/assets/hooks/security-sentinel.sh +2 -1
  96. package/assets/hooks/session-start-context.sh +7 -5
  97. package/assets/hooks/stop-orchestrator.sh +13 -3
  98. package/assets/initializer-question-pack.v4.json +11 -7
  99. package/assets/partials/05-workflow.partial.md +18 -73
  100. package/assets/partials/07-footer.partial.md +1 -1
  101. package/assets/partials-agents/02-operating-mode.partial.md +1 -2
  102. package/assets/partials-agents/04-task-protocol.partial.md +14 -59
  103. package/assets/partials-agents/06-quality-safety.partial.md +11 -16
  104. package/assets/partials-agents/08-deep-docs.partial.md +1 -2
  105. package/assets/plan-map.json +11 -11
  106. package/assets/plugin-registry.v1.json +9 -3
  107. package/assets/plugin-trust-policy.v1.json +6 -0
  108. package/assets/recovery/ForgeRecovery.ps1 +100 -0
  109. package/assets/recovery/forge-wsl-rescue +271 -0
  110. package/assets/reference-configs/development-protocol.md +11 -15
  111. package/assets/reference-configs/document-generation.md +1 -1
  112. package/assets/reference-configs/global-working-rules.md +9 -1
  113. package/assets/reference-configs/harness-overview.md +22 -112
  114. package/assets/reference-configs/hook-operations.md +1 -1
  115. package/assets/reference-configs/sprint-contracts.md +2 -2
  116. package/assets/skill-version.json +2 -2
  117. package/assets/templates/helpers/architecture-event.ts +3 -34
  118. package/assets/templates/helpers/architecture-queue.sh +61 -10
  119. package/assets/templates/helpers/archive-workflow.sh +90 -180
  120. package/assets/templates/helpers/capability-config.ts +8 -11
  121. package/assets/templates/helpers/capability-resolver.ts +37 -19
  122. package/assets/templates/helpers/capture-plan.sh +2 -2
  123. package/assets/templates/helpers/check-architecture-sync.sh +1 -9
  124. package/assets/templates/helpers/check-task-sync.sh +82 -11
  125. package/assets/templates/helpers/check-task-workflow.sh +1 -3
  126. package/assets/templates/helpers/context-contract-sync.sh +1 -12
  127. package/assets/templates/helpers/contract-worktree.sh +26 -24
  128. package/assets/templates/helpers/ensure-task-workflow.sh +6 -8
  129. package/assets/templates/helpers/inspect-project-state.ts +1 -1
  130. package/assets/templates/helpers/migrate-project-template.sh +1 -1
  131. package/assets/templates/helpers/migrate-workflow-docs.ts +53 -239
  132. package/assets/templates/helpers/new-plan.sh +2 -2
  133. package/assets/templates/helpers/plan-to-todo.sh +3 -31
  134. package/assets/templates/helpers/sprint-backlog.sh +1 -1
  135. package/assets/templates/helpers/switch-plan.sh +1 -1
  136. package/assets/templates/helpers/workflow-contract.ts +1 -0
  137. package/assets/workflow-contract.v1.json +63 -171
  138. package/assets/workflows/xiaohongshu/xiaohongshu.collect-metrics.v1.draft.json +118 -0
  139. package/assets/workflows/xiaohongshu/xiaohongshu.publish-image-note.v1.draft.json +316 -0
  140. package/assets/workflows/xiaohongshu/xiaohongshu.publish-long-text.v1.draft.json +324 -0
  141. package/docs/architecture/CURRENT.md +148 -13
  142. package/docs/architecture/EVOLUTION.md +13 -0
  143. package/docs/architecture/decisions/20260801-controller-home-sqlite-state.md +2 -1
  144. package/docs/architecture/decisions/20260831-independent-windows-wsl-host-rescue.md +59 -0
  145. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +120 -0
  146. package/docs/architecture/decisions/20260904-repository-runtime-data-boundary.md +42 -0
  147. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +35 -0
  148. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +296 -0
  149. package/docs/architecture/decisions/20260907-maintenance-diagnosis-bounded-read.md +39 -0
  150. package/docs/architecture/domains/verification.md +7 -0
  151. package/docs/architecture/domains/workflow-engine.md +1 -1
  152. package/docs/architecture/index.md +3 -3
  153. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +19 -8
  154. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +124 -0
  155. package/docs/forge-chatgpt-mcp-setup.md +5 -3
  156. package/docs/forge-plugin-management.md +20 -4
  157. package/docs/forge-runtime-self-healing-loop.md +2 -0
  158. package/docs/operations/benchmark-cross-version-freeze.md +38 -0
  159. package/docs/operations/controller-browser-plugin.md +3 -1
  160. package/docs/operations/homebrew.md +2 -2
  161. package/docs/operations/platform-support.md +16 -8
  162. package/docs/operations/platform-support.zh-CN.md +2 -2
  163. package/docs/operations/standalone-disaster-recovery.md +26 -1
  164. package/docs/operations/uu-remote-rescue.md +41 -0
  165. package/docs/operations/windows-wsl-host-rescue.md +133 -0
  166. package/docs/public-usage-guide.md +1 -1
  167. package/docs/public-usage-guide.zh-CN.md +1 -1
  168. package/docs/tutorials/01-install-and-start.md +1 -1
  169. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  170. package/docs/tutorials/02-connect-chatgpt.md +4 -4
  171. package/docs/tutorials/02-connect-chatgpt.zh-CN.md +4 -4
  172. package/docs/wiki/Implementation.md +1 -1
  173. package/package.json +23 -14
  174. package/packages/kernel/controller/api/index.ts +2 -0
  175. package/packages/kernel/controller/application/controller-round-service.ts +29 -0
  176. package/packages/kernel/controller/application/controller-service.ts +30 -0
  177. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +308 -0
  178. package/packages/kernel/controller/domain/controller-round.ts +107 -0
  179. package/packages/kernel/controller/domain/execution-quality.ts +133 -0
  180. package/packages/kernel/controller/domain/types.ts +56 -0
  181. package/packages/kernel/controller/index.ts +1 -0
  182. package/packages/kernel/controller/infrastructure/controller-binding-store.ts +84 -0
  183. package/packages/kernel/controller/infrastructure/controller-round-store.ts +1384 -0
  184. package/packages/kernel/controller/infrastructure/controller-session-store.ts +578 -0
  185. package/packages/kernel/controller/ports/controller-host.ts +16 -0
  186. package/packages/kernel/goal/api/index.ts +1 -0
  187. package/packages/kernel/goal/domain/types.ts +40 -0
  188. package/packages/kernel/goal/index.ts +1 -0
  189. package/packages/kernel/identity/api/index.ts +5 -0
  190. package/packages/kernel/identity/application/identity-service.ts +67 -0
  191. package/packages/kernel/identity/domain/scope.ts +63 -0
  192. package/packages/kernel/identity/domain/semantic-sync.ts +81 -0
  193. package/packages/kernel/identity/domain/types.ts +44 -0
  194. package/packages/kernel/identity/domain/workspace.ts +56 -0
  195. package/packages/kernel/identity/index.ts +1 -0
  196. package/packages/kernel/identity/infrastructure/identity-store.ts +75 -0
  197. package/packages/kernel/memory/api/index.ts +5 -0
  198. package/packages/kernel/memory/application/experience-service.ts +118 -0
  199. package/packages/kernel/memory/application/outcome-service.ts +77 -0
  200. package/packages/kernel/memory/domain/experience.ts +103 -0
  201. package/packages/kernel/memory/domain/operational-prior.ts +92 -0
  202. package/packages/kernel/memory/index.ts +1 -0
  203. package/packages/kernel/progression/api/index.ts +2 -0
  204. package/packages/kernel/progression/application/projector.ts +211 -0
  205. package/packages/kernel/progression/domain/types.ts +116 -0
  206. package/packages/kernel/progression/index.ts +1 -0
  207. package/packages/kernel/scheduler/api/index.ts +6 -0
  208. package/packages/kernel/scheduler/application/continuation-service.ts +212 -0
  209. package/packages/kernel/scheduler/application/eligibility.ts +252 -0
  210. package/packages/kernel/scheduler/application/schedule-service.ts +24 -0
  211. package/packages/kernel/scheduler/application/settlement.ts +197 -0
  212. package/packages/kernel/scheduler/domain/continuation.ts +38 -0
  213. package/packages/kernel/scheduler/domain/schedule.ts +149 -0
  214. package/packages/kernel/scheduler/index.ts +1 -0
  215. package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +38 -0
  216. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +785 -0
  217. package/packages/kernel/work/api/index.ts +15 -0
  218. package/packages/kernel/work/application/work-service.ts +148 -0
  219. package/packages/kernel/work/domain/admission-policy.ts +34 -0
  220. package/packages/kernel/work/domain/check-receipt.ts +43 -0
  221. package/packages/kernel/work/domain/context-closure-receipt.ts +32 -0
  222. package/packages/kernel/work/domain/engineering-contracts.ts +157 -0
  223. package/packages/kernel/work/domain/engineering-design.ts +281 -0
  224. package/packages/kernel/work/domain/engineering-profile.ts +242 -0
  225. package/packages/kernel/work/domain/execution-concurrency.ts +254 -0
  226. package/packages/kernel/work/domain/execution-snapshot.ts +33 -0
  227. package/packages/kernel/work/domain/implementation-review.ts +510 -0
  228. package/packages/kernel/work/domain/project-engineering-contract.ts +202 -0
  229. package/packages/kernel/work/domain/repository-completion-receipt.ts +73 -0
  230. package/packages/kernel/work/domain/state-machine.ts +259 -0
  231. package/packages/kernel/work/domain/types.ts +528 -0
  232. package/packages/kernel/work/index.ts +1 -0
  233. package/packages/kernel/work/infrastructure/work-contract-store.ts +1876 -0
  234. package/packages/kernel/work/ports/work-contract-store.ts +18 -0
  235. package/packages/plugin-runtime/browser/index.ts +3 -0
  236. package/packages/plugin-runtime/browser/provider-registry.ts +110 -0
  237. package/packages/plugin-runtime/browser/runtime-contract.ts +150 -0
  238. package/packages/plugin-runtime/browser/session-authority.ts +61 -0
  239. package/packages/plugin-runtime/computer/index.ts +6 -0
  240. package/packages/plugin-runtime/computer/provider-error.ts +26 -0
  241. package/packages/plugin-runtime/computer/provider-registration.ts +52 -0
  242. package/packages/plugin-runtime/computer/provider-registry.ts +63 -0
  243. package/packages/plugin-runtime/computer/provider.ts +19 -0
  244. package/packages/plugin-runtime/computer/target-authority.ts +190 -0
  245. package/packages/plugin-runtime/computer/target-persistence.ts +54 -0
  246. package/packages/plugin-runtime/external/index.ts +1 -0
  247. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +457 -0
  248. package/packages/plugin-runtime/index.ts +3 -0
  249. package/packages/protocols/browser/index.ts +1 -0
  250. package/packages/protocols/browser/session.ts +98 -0
  251. package/packages/protocols/computer/contract.ts +199 -0
  252. package/packages/protocols/computer/index.ts +1 -0
  253. package/packages/protocols/failure/contract.ts +158 -0
  254. package/packages/protocols/failure/index.ts +1 -0
  255. package/packages/protocols/handoff/index.ts +1 -0
  256. package/packages/protocols/handoff/status.ts +22 -0
  257. package/packages/protocols/mcp/execution-context.ts +11 -0
  258. package/packages/protocols/mcp/index.ts +2 -0
  259. package/packages/protocols/mcp/tool-contract.ts +42 -0
  260. package/packages/workflow-runtime/api/index.ts +2 -0
  261. package/packages/workflow-runtime/application/interpreter.ts +342 -0
  262. package/packages/workflow-runtime/domain/workflow-asset.ts +223 -0
  263. package/packages/workflow-runtime/index.ts +1 -0
  264. package/scripts/assemble-template.ts +1 -1
  265. package/scripts/benchmark-computer-hotpath.ts +255 -0
  266. package/scripts/benchmark-controller-round2.ts +54 -2
  267. package/scripts/benchmark-ios-agent-device.ts +3 -6
  268. package/scripts/benchmark-mcp-transport.ts +3 -4
  269. package/scripts/benchmark-operational-memory-activation.ts +235 -0
  270. package/scripts/benchmark-operational-shadow.ts +28 -0
  271. package/scripts/bootstrap-runtime-maintenance-recovery.sh +4 -1
  272. package/scripts/canary-chatgpt-provider-delivery.ts +97 -0
  273. package/scripts/canary-controller-semantic-wait.ts +195 -0
  274. package/scripts/canary-global-hook.sh +2 -2
  275. package/scripts/check-mcp-compatibility.ts +173 -7
  276. package/scripts/check-platform-support.mjs +28 -2
  277. package/scripts/check-public-docs.sh +1 -1
  278. package/scripts/check-release-readiness.sh +1 -1
  279. package/scripts/check-repository-hygiene.mjs +92 -0
  280. package/scripts/check-runtime-architecture.mjs +1206 -95
  281. package/scripts/check-source-duplication.mjs +9 -1
  282. package/scripts/check-tarball-install-smoke.sh +98 -15
  283. package/scripts/controller-ngrok-rotation.sh +5 -4
  284. package/scripts/create-project-dirs.sh +10 -74
  285. package/scripts/forge-local-recovery-helper.mjs +204 -0
  286. package/scripts/forge-uu-remote-rescue-helper.d.mts +31 -0
  287. package/scripts/forge-uu-remote-rescue-helper.mjs +409 -0
  288. package/scripts/forge-windows-host-recovery-helper.mjs +136 -0
  289. package/scripts/hook-shim.sh +2 -2
  290. package/scripts/init-project.sh +12 -70
  291. package/scripts/install-desktop-operator-registration.ts +4 -2
  292. package/scripts/install-independent-windows-wsl-recovery.ts +125 -0
  293. package/scripts/install-standalone-recovery.ts +122 -10
  294. package/scripts/install-uu-remote-rescue-registration.ts +74 -0
  295. package/scripts/install-windows-host-recovery-registration.ts +22 -0
  296. package/scripts/lib/controller-home-env.sh +6 -3
  297. package/scripts/lib/project-init-lib.sh +39 -582
  298. package/scripts/migrate-chatgpt-automation-schedules.ts +2 -2
  299. package/scripts/migrate-windows-wsl-controller-home.ts +306 -0
  300. package/scripts/open-source-audit-allowlist.txt +12 -1
  301. package/scripts/portability-bindings.mjs +70 -0
  302. package/scripts/run-bounded-command.mjs +55 -0
  303. package/scripts/run-bun-test-file.ts +22 -6
  304. package/scripts/run-governed-gate.ts +4 -1
  305. package/scripts/smoke-mcp-http-runtime.ts +1 -1
  306. package/scripts/smoke-runtime-recovery.ts +34 -1
  307. package/scripts/smoke-schedule-engine.ts +1 -1
  308. package/scripts/stage-runtime-release.ts +6 -1
  309. package/scripts/test-governance.ts +51 -2
  310. package/src/cli/agent-jobs/job-manager.ts +10 -1
  311. package/src/cli/chatgpt-browser/bind-server.ts +2 -1
  312. package/src/cli/chatgpt-browser/binding.ts +20 -10
  313. package/src/cli/chatgpt-browser/bridge-extension.ts +75 -0
  314. package/src/cli/chatgpt-browser/bridge-provider.ts +376 -11
  315. package/src/cli/chatgpt-browser/engine.ts +10 -11
  316. package/src/cli/chatgpt-browser/native-provider.ts +24 -83
  317. package/src/cli/chatgpt-browser/oracle-provider.ts +5 -3
  318. package/src/cli/chatgpt-browser/types.ts +1 -0
  319. package/src/cli/commands/bootstrap-control.ts +334 -0
  320. package/src/cli/commands/brain-assistant.ts +38 -0
  321. package/src/cli/commands/brain.ts +193 -40
  322. package/src/cli/commands/chatgpt.ts +127 -0
  323. package/src/cli/commands/computer.ts +437 -0
  324. package/src/cli/commands/doctor.ts +18 -1
  325. package/src/cli/commands/init-hook.ts +71 -61
  326. package/src/cli/commands/init.ts +3 -1
  327. package/src/cli/commands/mcp.ts +16 -10
  328. package/src/cli/commands/plugin.ts +38 -12
  329. package/src/cli/commands/recovery.ts +493 -80
  330. package/src/cli/commands/runtime.ts +9 -4
  331. package/src/cli/commands/setup-profile.ts +89 -39
  332. package/src/cli/commands/status.ts +2 -1
  333. package/src/cli/controller/check-runner.ts +487 -98
  334. package/src/cli/controller/context/types.ts +7 -1
  335. package/src/cli/controller/context-pack.ts +23 -3
  336. package/src/cli/controller/issue-store.ts +1 -1
  337. package/src/cli/controller/systemd-user.ts +110 -0
  338. package/src/cli/controller/types.ts +10 -70
  339. package/src/cli/controller/worklog.ts +67 -13
  340. package/src/cli/editing/edit-operation-contract.ts +92 -0
  341. package/src/cli/editing/edit-session.ts +289 -13
  342. package/src/cli/github/plugin.ts +17 -12
  343. package/src/cli/hook/route-registry.ts +3 -5
  344. package/src/cli/hook/runtime.ts +49 -3
  345. package/src/cli/index.ts +3 -0
  346. package/src/cli/local-bridge/connector-freshness.ts +2 -2
  347. package/src/cli/local-bridge/console-automations.ts +2 -2
  348. package/src/cli/local-bridge/facade-api.ts +41 -14
  349. package/src/cli/local-bridge/job-store.ts +1 -1
  350. package/src/cli/local-bridge/server.ts +24 -27
  351. package/src/cli/mcp/access-mode.ts +2 -132
  352. package/src/cli/mcp/access-tools.ts +2 -387
  353. package/src/cli/mcp/audit.ts +2 -32
  354. package/src/cli/mcp/auth.ts +2 -404
  355. package/src/cli/mcp/instructions.ts +2 -34
  356. package/src/cli/mcp/legacy-context.ts +2 -16
  357. package/src/cli/mcp/legacy-tool-service.ts +2 -5308
  358. package/src/cli/mcp/multi-repository.ts +2 -436
  359. package/src/cli/mcp/oauth.ts +2 -375
  360. package/src/cli/mcp/openai-secure-tunnel.ts +2 -0
  361. package/src/cli/mcp/paths.ts +2 -140
  362. package/src/cli/mcp/policy.ts +2 -232
  363. package/src/cli/mcp/post-finalize-work-attribution.ts +2 -150
  364. package/src/cli/mcp/proxy-env.ts +2 -62
  365. package/src/cli/mcp/readiness-projection.ts +2 -24
  366. package/src/cli/mcp/redaction.ts +2 -21
  367. package/src/cli/mcp/repo.ts +2 -24
  368. package/src/cli/mcp/repository-tools.ts +2 -1613
  369. package/src/cli/mcp/server.ts +2 -951
  370. package/src/cli/mcp/setup.ts +2 -737
  371. package/src/cli/mcp/tool-capability-cache.ts +2 -87
  372. package/src/cli/mcp/tool-contract.ts +2 -14
  373. package/src/cli/mcp/tools.ts +2 -9
  374. package/src/cli/mcp/toolset-names.ts +2 -70
  375. package/src/cli/mcp/toolset-selection.ts +2 -41
  376. package/src/cli/mcp/toolset.ts +2 -336
  377. package/src/cli/mcp/transports/AGENTS.md +1 -10
  378. package/src/cli/mcp/transports/CLAUDE.md +1 -10
  379. package/src/cli/mcp/transports/http.ts +2 -1414
  380. package/src/cli/mcp/transports/session-registry.ts +2 -490
  381. package/src/cli/mcp/transports/stdio.ts +2 -8
  382. package/src/cli/mcp/types.ts +2 -41
  383. package/src/cli/mcp/umbrella-tools.ts +2 -117
  384. package/src/cli/repositories/command-executor.ts +64 -18
  385. package/src/cli/repositories/command-scope.ts +117 -1
  386. package/src/cli/repositories/controller-home.ts +119 -1
  387. package/src/cli/repositories/identity.ts +13 -0
  388. package/src/cli/repositories/registry.ts +68 -49
  389. package/src/cli/repositories/repository-snapshot.ts +53 -7
  390. package/src/cli/repositories/runtime-storage.ts +27 -2
  391. package/src/cli/repositories/safe-patch.ts +34 -38
  392. package/src/cli/repositories/selected-path-actions.ts +22 -2
  393. package/src/cli/repositories/structured-git.ts +105 -25
  394. package/src/cli/runtime/helper-runner.ts +7 -0
  395. package/src/cli/runtime-invocation.ts +8 -1
  396. package/src/cli/tools/codegraph.ts +44 -25
  397. package/src/core/adoption/manifest-templates.ts +1 -1
  398. package/src/core/adoption/plan.ts +3 -26
  399. package/src/core/adoption/workflow-contract-plan.ts +17 -9
  400. package/src/effects/process-runner.ts +8 -14
  401. package/src/runtime/context/assistant-context.ts +154 -0
  402. package/src/runtime/context/assistant-work-context.ts +147 -0
  403. package/src/runtime/context/codegraph-cache-boundary.ts +255 -0
  404. package/src/runtime/context/codegraph-read-provider.ts +55 -22
  405. package/src/runtime/context/codegraph-sidecar.cjs +8 -1
  406. package/src/runtime/context/context-closure.ts +268 -0
  407. package/src/runtime/context/context-plane.ts +211 -0
  408. package/src/runtime/context/project-engineering-contract.ts +60 -0
  409. package/src/runtime/control-plane/bootstrap/capability-provider.ts +74 -0
  410. package/src/runtime/control-plane/bootstrap/control-api.ts +57 -0
  411. package/src/runtime/control-plane/bootstrap/index.ts +5 -0
  412. package/src/runtime/control-plane/bootstrap/state-machine.ts +141 -0
  413. package/src/runtime/control-plane/bootstrap/store.ts +21 -0
  414. package/src/runtime/control-plane/bootstrap/types.ts +87 -0
  415. package/src/runtime/control-plane/cleanup-artifact-retention.ts +328 -0
  416. package/src/runtime/control-plane/codegraph-cache-retention.ts +164 -0
  417. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +320 -0
  418. package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +169 -0
  419. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +350 -0
  420. package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +85 -0
  421. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +369 -99
  422. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +103 -15
  423. package/src/runtime/control-plane/execution/implementation-review-content.ts +95 -0
  424. package/src/runtime/control-plane/execution/repository-work-attribution.ts +2 -2
  425. package/src/runtime/control-plane/execution/retained-work-resume.ts +336 -6
  426. package/src/runtime/control-plane/execution/validation.ts +28 -3
  427. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +116 -0
  428. package/src/runtime/control-plane/execution/work-completion-authority.ts +44 -2
  429. package/src/runtime/control-plane/execution/work-evidence-policy.ts +34 -3
  430. package/src/runtime/control-plane/execution/work-execution-support.ts +42 -22
  431. package/src/runtime/control-plane/execution/work-finalization-service.ts +1103 -166
  432. package/src/runtime/control-plane/execution/work-handle-authority.ts +219 -22
  433. package/src/runtime/control-plane/execution/work-handle-store.ts +77 -0
  434. package/src/runtime/control-plane/execution/work-head-settlement.ts +75 -0
  435. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +145 -23
  436. package/src/runtime/control-plane/execution/work-operation-service.ts +49 -13
  437. package/src/runtime/control-plane/execution/work-preparation-service.ts +31 -15
  438. package/src/runtime/control-plane/execution/work-remote-delivery.ts +1 -1
  439. package/src/runtime/control-plane/execution/work-task-receipt.ts +20 -1
  440. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +407 -76
  441. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +88 -18
  442. package/src/runtime/control-plane/execution/work-verification-context.ts +1 -1
  443. package/src/runtime/control-plane/execution/work-verification-service.ts +258 -4
  444. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +200 -15
  445. package/src/runtime/control-plane/facade/capability-registry.ts +21 -10
  446. package/src/runtime/control-plane/facade/controller-round-relay.ts +3 -1118
  447. package/src/runtime/control-plane/facade/controller-session-store.ts +2 -488
  448. package/src/runtime/control-plane/facade/goal-workloop-access.ts +6 -3
  449. package/src/runtime/control-plane/facade/goal-workloop.ts +972 -137
  450. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +158 -0
  451. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +10 -0
  452. package/src/runtime/control-plane/facade/index.ts +4 -2
  453. package/src/runtime/control-plane/facade/operation-digest.ts +22 -58
  454. package/src/runtime/control-plane/facade/plan-contract-store.ts +1004 -38
  455. package/src/runtime/control-plane/facade/repository-work-admission.ts +19 -1
  456. package/src/runtime/control-plane/facade/requirement-authority.ts +218 -0
  457. package/src/runtime/control-plane/facade/requirement-board.ts +6 -1
  458. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +48 -0
  459. package/src/runtime/control-plane/facade/semantic-admission.ts +8 -16
  460. package/src/runtime/control-plane/facade/suggested-actions.ts +4 -1
  461. package/src/runtime/control-plane/facade/types.ts +189 -532
  462. package/src/runtime/control-plane/facade/work-admission-policy.ts +84 -35
  463. package/src/runtime/control-plane/facade/work-contract-store.ts +2 -1043
  464. package/src/runtime/control-plane/facade/work-implementation-review.ts +2 -0
  465. package/src/runtime/control-plane/facade/work-state-machine.ts +2 -250
  466. package/src/runtime/control-plane/generated-cache-retention.ts +239 -18
  467. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +12 -1
  468. package/src/runtime/control-plane/global-scheduler/maintenance.ts +76 -13
  469. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-entry.ts +55 -0
  470. package/src/runtime/control-plane/global-scheduler/periodic-cleanup-process.ts +98 -0
  471. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +1 -1
  472. package/src/runtime/control-plane/global-scheduler/scheduler-worker-entry.ts +10 -0
  473. package/src/runtime/control-plane/global-scheduler/scheduler.ts +173 -81
  474. package/src/runtime/control-plane/global-scheduler/worker-launch.ts +18 -6
  475. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +397 -0
  476. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +2 -177
  477. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +301 -560
  478. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +20 -4
  479. package/src/runtime/control-plane/launcher/thin-launcher.ts +50 -4
  480. package/src/runtime/control-plane/lifecycle-retention-metrics.ts +60 -0
  481. package/src/runtime/control-plane/persistence/experience-store.ts +169 -0
  482. package/src/runtime/control-plane/persistence/operational-prior-store.ts +348 -0
  483. package/src/runtime/control-plane/persistence/requirement-store.ts +30 -22
  484. package/src/runtime/control-plane/persistence/sqlite-store.ts +545 -76
  485. package/src/runtime/control-plane/persistence/workflow-content-store.ts +98 -0
  486. package/src/runtime/control-plane/persistence/workflow-registry-store.ts +186 -0
  487. package/src/runtime/control-plane/persistence/workflow-run-store.ts +123 -0
  488. package/src/runtime/control-plane/release-retention.ts +56 -16
  489. package/src/runtime/control-plane/repository-namespace-retention.ts +208 -0
  490. package/src/runtime/control-plane/routing/route-policy.ts +19 -0
  491. package/src/runtime/control-plane/runtime-cleanup.ts +574 -37
  492. package/src/runtime/control-plane/runtime-generation.ts +6 -0
  493. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +465 -0
  494. package/src/runtime/control-plane/workspace/workspace-store.ts +80 -0
  495. package/src/runtime/diagnostics/incident-repair.ts +406 -0
  496. package/src/runtime/diagnostics/mcp-timing.ts +125 -6
  497. package/src/runtime/diagnostics/performance.ts +6 -14
  498. package/src/runtime/diagnostics/read-only-tool.ts +1 -1
  499. package/src/runtime/evidence/artifact-store.ts +65 -2
  500. package/src/runtime/evidence/operational-shadow.ts +38 -0
  501. package/src/runtime/evidence/process-check-receipt.ts +5 -43
  502. package/src/runtime/evidence/sensitive-output.ts +4 -4
  503. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -1
  504. package/src/runtime/execution/jobs/store.ts +121 -2
  505. package/src/runtime/execution/managed-workspace.ts +55 -5
  506. package/src/runtime/execution/process-runtime/canary.ts +19 -5
  507. package/src/runtime/execution/process-runtime/check-classification.ts +48 -0
  508. package/src/runtime/execution/process-runtime/check-facade.ts +23 -9
  509. package/src/runtime/execution/process-runtime/check-receipt.ts +1 -1
  510. package/src/runtime/execution/process-runtime/check-result-retention.ts +132 -0
  511. package/src/runtime/execution/process-runtime/check-result.ts +73 -2
  512. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +42 -3
  513. package/src/runtime/execution/process-runtime/check-storage.ts +187 -0
  514. package/src/runtime/execution/process-runtime/command-facade.ts +38 -87
  515. package/src/runtime/execution/process-runtime/index.ts +1 -0
  516. package/src/runtime/execution/process-runtime/interactive-admission.ts +2 -1
  517. package/src/runtime/execution/process-runtime/lightweight-managed.ts +32 -1
  518. package/src/runtime/execution/process-runtime/persisted-check.ts +128 -21
  519. package/src/runtime/execution/process-runtime/resource-claims.ts +60 -3
  520. package/src/runtime/execution/process-runtime/runtime.ts +132 -15
  521. package/src/runtime/execution/process-runtime/types.ts +22 -0
  522. package/src/runtime/execution/workers/executor.ts +16 -13
  523. package/src/runtime/execution/workers/worker-entry.ts +1 -1
  524. package/src/runtime/gateway/mcp/execution-tools.ts +2 -207
  525. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +2 -61
  526. package/src/runtime/gateway/mcp/persisted-check-process.ts +2 -3
  527. package/src/runtime/gateway/mcp/process-tools.ts +2 -289
  528. package/src/runtime/gateway/mcp/router.ts +2 -1125
  529. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +2 -565
  530. package/src/runtime/gateway/mcp/runtime-tools.ts +2 -6655
  531. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +2 -1
  532. package/src/runtime/maintenance/cleanup.ts +38 -24
  533. package/src/runtime/platform/browser-product-discovery.ts +174 -0
  534. package/src/runtime/platform/computer-platform.ts +14 -0
  535. package/src/runtime/platform/executable-discovery.ts +54 -0
  536. package/src/runtime/platform/fetch-http-server.ts +90 -0
  537. package/src/runtime/platform/service-manager.ts +138 -0
  538. package/src/runtime/platform/windows-host-discovery.ts +118 -0
  539. package/src/runtime/platform/windows-recovery-deployment.ts +67 -0
  540. package/src/runtime/plugins/action-application.ts +135 -0
  541. package/src/runtime/plugins/app-store-connect-adapter.ts +9 -21
  542. package/src/runtime/plugins/browser-adapter.ts +140 -100
  543. package/src/runtime/plugins/browser-automation-service.ts +15 -36
  544. package/src/runtime/plugins/browser-macos-bridge.ts +69 -21
  545. package/src/runtime/plugins/browser-manifest-surface.ts +30 -6
  546. package/src/runtime/plugins/browser-native-session-service.ts +1 -1
  547. package/src/runtime/plugins/browser-provider-registry.ts +2 -109
  548. package/src/runtime/plugins/browser-registration.ts +16 -0
  549. package/src/runtime/plugins/browser-runtime-contract.ts +2 -154
  550. package/src/runtime/plugins/browser-runtime.ts +41 -9
  551. package/src/runtime/plugins/browser-session-authority.ts +101 -291
  552. package/src/runtime/plugins/browser-session-legacy-migration.ts +203 -0
  553. package/src/runtime/plugins/browser-session-store.ts +229 -36
  554. package/src/runtime/plugins/browser-session-types.ts +2 -98
  555. package/src/runtime/plugins/capability-authorization-grants.ts +17 -0
  556. package/src/runtime/plugins/catalog-trust.ts +82 -0
  557. package/src/runtime/plugins/computer-registration.ts +839 -0
  558. package/src/runtime/plugins/config-store.ts +119 -0
  559. package/src/runtime/plugins/desktop-operator-external-policy.ts +932 -0
  560. package/src/runtime/plugins/desktop-operator-registration.ts +111 -8
  561. package/src/runtime/plugins/errors.ts +8 -1
  562. package/src/runtime/plugins/external-adapter.ts +45 -322
  563. package/src/runtime/plugins/external-provider-policy.ts +48 -0
  564. package/src/runtime/plugins/external-registration.ts +9 -1
  565. package/src/runtime/plugins/external-unix-socket-probe.cjs +9 -3
  566. package/src/runtime/plugins/external-unix-socket.ts +64 -193
  567. package/src/runtime/plugins/first-party-external-registration.ts +163 -0
  568. package/src/runtime/plugins/first-party-registry.ts +3 -1
  569. package/src/runtime/plugins/github-adapter.ts +1 -2
  570. package/src/runtime/plugins/gmail-adapter.ts +6 -6
  571. package/src/runtime/plugins/google-calendar-adapter.ts +6 -6
  572. package/src/runtime/plugins/google-shared.ts +31 -46
  573. package/src/runtime/plugins/google-tasks-adapter.ts +6 -6
  574. package/src/runtime/plugins/ios-adapter.ts +1 -2
  575. package/src/runtime/plugins/local-system-adapter.ts +180 -0
  576. package/src/runtime/plugins/macos-capability-broker.ts +15 -105
  577. package/src/runtime/plugins/resend-adapter.ts +15 -24
  578. package/src/runtime/plugins/store.ts +493 -51
  579. package/src/runtime/plugins/types.ts +8 -1
  580. package/src/runtime/plugins/uu-remote-rescue-registration.ts +155 -0
  581. package/src/runtime/plugins/windows-host-recovery-install.ts +68 -0
  582. package/src/runtime/plugins/windows-host-recovery-registration.ts +85 -0
  583. package/src/runtime/plugins/xiaohongshu-publish.ts +86 -430
  584. package/src/runtime/projections/controller-context.ts +12 -6
  585. package/src/runtime/projections/git-status-sampler.ts +73 -22
  586. package/src/runtime/projections/materialized-view.ts +14 -8
  587. package/src/runtime/recovery/capability-action-application.ts +228 -0
  588. package/src/runtime/recovery/index.ts +3 -0
  589. package/src/runtime/recovery/lifecycle-inventory.ts +338 -0
  590. package/src/runtime/recovery/local-jobs-repair.ts +14 -14
  591. package/src/runtime/recovery/maintenance-executor.ts +358 -76
  592. package/src/runtime/recovery/quarantine-retention.ts +256 -0
  593. package/src/runtime/release/identity.ts +6 -0
  594. package/src/runtime/resources/leases/store.ts +1 -1
  595. package/src/runtime/root/active-execution-power-assertion.ts +139 -0
  596. package/src/runtime/root/assistant-learning-loop.ts +45 -0
  597. package/src/runtime/root/browser-session-composition.ts +59 -0
  598. package/src/runtime/root/computer-composition.ts +191 -0
  599. package/src/runtime/root/computer-target-composition.ts +16 -0
  600. package/src/runtime/root/computer-target-persistence.ts +39 -0
  601. package/src/runtime/root/controller-round-composition.ts +107 -0
  602. package/src/runtime/root/controller-services.ts +2 -0
  603. package/src/runtime/root/entry.ts +4 -3
  604. package/src/runtime/root/gateway-adapter.ts +3 -3
  605. package/src/runtime/root/local-bridge.ts +5 -2
  606. package/src/runtime/root/mcp-transport.ts +5 -5
  607. package/src/runtime/root/package-connector-service.ts +108 -56
  608. package/src/runtime/root/package-runtime-release.ts +85 -18
  609. package/src/runtime/root/package-runtime-service.ts +60 -97
  610. package/src/runtime/root/release-execution-canary.ts +71 -0
  611. package/src/runtime/root/release-loader.ts +68 -0
  612. package/src/runtime/root/release-manifest.ts +106 -2
  613. package/src/runtime/root/release-materialize.ts +103 -4
  614. package/src/runtime/root/release-store.ts +31 -2
  615. package/src/runtime/root/runtime.ts +240 -25
  616. package/src/runtime/root/scheduled-controller-composition.ts +51 -0
  617. package/src/runtime/root/scheduler.ts +12 -4
  618. package/src/runtime/root/service-runner.ts +1 -1
  619. package/src/runtime/root/service.ts +41 -16
  620. package/src/runtime/root/status.ts +1 -0
  621. package/src/runtime/root/types.ts +24 -1
  622. package/src/runtime/shared/local-bridge-surface.ts +1 -1
  623. package/src/runtime/shared/process-environment.ts +19 -4
  624. package/src/runtime/shared/storage-capacity.ts +68 -0
  625. package/src/runtime/standalone-recovery/controller-home-migration.ts +1116 -0
  626. package/src/runtime/standalone-recovery/core.ts +984 -230
  627. package/src/runtime/standalone-recovery/entry.ts +182 -51
  628. package/src/runtime/standalone-recovery/independent-host-rescue.ts +172 -0
  629. package/src/runtime/standalone-recovery/installer.ts +212 -104
  630. package/src/runtime/standalone-recovery/mcp-server.ts +243 -0
  631. package/src/runtime/standalone-recovery/mutation-identity-contract.ts +21 -0
  632. package/src/runtime/standalone-recovery/operation-lock.ts +160 -0
  633. package/src/runtime/standalone-recovery/performance.ts +135 -0
  634. package/src/runtime/standalone-recovery/release.ts +5 -0
  635. package/src/runtime/watchdog/workflow-watchdog.ts +1 -1
  636. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +1 -1
  637. package/src/runtime/workflow/schedules/engine.ts +191 -343
  638. package/src/runtime/workflow/schedules/pending-activation.ts +1 -1
  639. package/src/runtime/workflow/schedules/settlement.ts +2 -191
  640. package/src/runtime/workflow/schedules/store.ts +2 -607
  641. package/src/runtime/workflow/schedules/types.ts +2 -127
  642. package/src/runtime/workflow/schedules/work-continuation.ts +180 -15
  643. package/src/runtime/workflows/first-party/xiaohongshu.ts +122 -0
  644. package/src/runtime/workflows/runtime.ts +486 -0
  645. package/src/testing/test-governance.ts +90 -29
  646. package/assets/templates/helpers/archive-architecture-request.sh +0 -244
  647. package/docs/architecture/history/README.md +0 -7
  648. package/docs/architecture/history/chatgpt-handoff-facade.md +0 -397
  649. package/docs/architecture/history/global-hook-runtime.md +0 -166
  650. package/docs/architecture/history/ios-semantic-automation-provider-v2.md +0 -170
  651. package/docs/architecture/requests/archive/2026/20260528-154740-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  652. package/docs/architecture/requests/archive/2026/20260528-154816-assets-hooks-assets-hooks-hook-input-sh.md +0 -59
  653. package/docs/architecture/requests/archive/2026/20260528-161851-ai-harness-workflow-contract-json-ai-harness-workflow-contract-json.md +0 -59
  654. package/docs/architecture/requests/archive/2026/20260528-161853-scripts-check-task-workflow-sh-scripts-check-task-workflow-sh.md +0 -59
  655. package/docs/architecture/requests/archive/2026/20260528-161911-assets-workflow-contract-v1-json-assets-workflow-contract-v1-json.md +0 -59
  656. package/docs/architecture/requests/archive/2026/20260528-222416-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  657. package/docs/architecture/requests/archive/2026/20260528-222444-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  658. package/docs/architecture/requests/archive/2026/20260528-222457-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  659. package/docs/architecture/requests/archive/2026/20260528-222648-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
  660. package/docs/architecture/requests/archive/2026/20260528-222705-ai-hooks-ai-hooks-worktree-guard-sh.md +0 -59
  661. package/docs/architecture/requests/archive/2026/20260528-222726-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  662. package/docs/architecture/requests/archive/2026/20260528-222727-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  663. package/docs/architecture/requests/archive/2026/20260528-224736-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
  664. package/docs/architecture/requests/archive/2026/20260528-233259-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  665. package/docs/architecture/requests/archive/2026/20260528-233335-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  666. package/docs/architecture/requests/archive/2026/20260528-233456-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  667. package/docs/architecture/requests/archive/2026/20260528-233457-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  668. package/docs/architecture/requests/archive/2026/20260528-233637-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
  669. package/docs/architecture/requests/archive/2026/20260528-233638-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
  670. package/docs/architecture/requests/archive/2026/20260529-000322-root-package-json.md +0 -59
  671. package/docs/architecture/requests/archive/2026/20260529-004238-ai-hooks-ai-hooks-lib-workflow-state-sh.md +0 -59
  672. package/docs/architecture/requests/archive/2026/20260529-020654-ai-harness-policy-json-ai-harness-policy-json.md +0 -63
  673. package/docs/architecture/requests/archive/2026/20260529-094236-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  674. package/docs/architecture/requests/archive/2026/20260529-094323-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  675. package/docs/architecture/requests/archive/2026/20260529-094331-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
  676. package/docs/architecture/requests/archive/2026/20260529-094339-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
  677. package/docs/architecture/requests/archive/2026/20260529-094430-assets-hooks-assets-hooks-session-start-context-sh.md +0 -60
  678. package/docs/architecture/requests/archive/2026/20260529-094446-ai-hooks-ai-hooks-session-start-context-sh.md +0 -60
  679. package/docs/architecture/requests/archive/2026/20260613-002040-runtime-harness-hook-adapters.md +0 -68
  680. package/docs/architecture/requests/archive/2026/root.md +0 -68
  681. package/docs/architecture/requests/archive/2026/runtime-harness-hook-adapters.md +0 -76
  682. package/docs/architecture/requests/archive/2026/verification-evals-checks.md +0 -68
  683. package/docs/architecture/requests/archive/2026/workflow-engine-contract-assets.md +0 -69
  684. package/scripts/archive-architecture-request.sh +0 -4
  685. package/scripts/run-skill-evals.ts +0 -1022
@@ -5,34 +5,41 @@ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'pat
5
5
  import type {
6
6
  AssistantPluginActionExecutionInput,
7
7
  AssistantPluginAuthorizationContext,
8
+ AssistantPluginBuildContext,
8
9
  AssistantPluginHealth,
9
10
  AssistantPluginManifest,
10
11
  } from './types';
11
12
  import { AssistantPluginError, toAssistantPluginError } from './errors';
13
+ import { readRepositoryPluginConfig, writeRepositoryPluginConfig, type RepositoryPluginConfigContext } from './config-store';
12
14
  import {
13
15
  browserActions,
14
16
  browserCapabilities,
15
17
  browserPermissions,
16
18
  } from './browser-manifest-surface';
17
19
  import { executeBrowserActionThroughNode, shouldUseBrowserNodeBridge } from './browser-node-bridge';
18
- import { BrowserProviderUnavailableBeforeActionError } from './browser-provider-registry';
19
- import { MAX_BROWSER_CDP_ENDPOINT_CANDIDATES } from './browser-runtime-contract';
20
+ import { BrowserProviderUnavailableBeforeActionError } from '../../../packages/plugin-runtime/browser/provider-registry';
21
+ import { MAX_BROWSER_CDP_ENDPOINT_CANDIDATES } from '../../../packages/plugin-runtime/browser/runtime-contract';
20
22
  import {
21
23
  ALL_BROWSER_PROVIDER_CAPABILITIES,
22
24
  browserActionCanReplayAfterDispatch as canReplayBrowserActionAfterDispatch,
25
+ browserExplicitPostActionWaitMs,
26
+ browserNativeForegroundVerificationWaitMs,
23
27
  executeBrowserRuntimeAction,
24
28
  invalidateBrowserRuntime,
25
29
  } from './browser-runtime';
26
- import { getExternalPluginAdapter } from './external-adapter';
30
+ import { activateRuntimeComputerBrowserApplication } from '../root/computer-composition';
27
31
  import {
28
- currentBrowserSessionAuthorityContext,
29
32
  DEFAULT_BROWSER_SESSION_LIST_LIMIT,
30
33
  MAX_BROWSER_SESSION_LIST_LIMIT,
31
- withBrowserSessionAuthorityContext,
32
- } from './browser-session-authority';
34
+ } from '../../../packages/plugin-runtime/browser/session-authority';
35
+ import {
36
+ currentRuntimeBrowserSessionAuthorityContext as currentBrowserSessionAuthorityContext,
37
+ withRuntimeBrowserSessionAuthorityContext as withBrowserSessionAuthorityContext,
38
+ } from '../root/browser-session-composition';
33
39
  import {
34
40
  closeMacOsBrowserOwnedTab,
35
41
  createMacOsBrowserOwnedPage,
42
+ createMacOsBrowserOwnedPageForProduct,
36
43
  reattachMacOsBrowserOwnedPage,
37
44
  discoverMacOsBrowserAttachment,
38
45
  invalidateMacOsBrowserPageHandle,
@@ -87,13 +94,11 @@ import type {
87
94
  BrowserTabMatchReason,
88
95
  BrowserTabResumeState,
89
96
  CdpAttachAttempt,
90
- } from './browser-session-types';
97
+ } from '../../../packages/protocols/browser/index';
91
98
 
92
99
  const BROWSER_PLUGIN_ID = 'browser';
93
- const CONFIG_ROOT = '.forge/plugins';
94
100
  const DEFAULT_TIMEOUT_MS = 30_000;
95
101
  const DEFAULT_MAX_TEXT_CHARS = 20_000;
96
- const DEFAULT_POST_ACTION_WAIT_MS = 750;
97
102
  const DEFAULT_CDP_DISCOVERY_TIMEOUT_MS = 1_500;
98
103
  const MAX_CDP_DISCOVERY_TIMEOUT_MS = 5_000;
99
104
 
@@ -149,6 +154,15 @@ interface BrowserActionTarget {
149
154
  existingSession?: BrowserSessionState;
150
155
  }
151
156
 
157
+ export function browserExplicitSessionRequiresExistingResource(
158
+ actionId: string,
159
+ explicitSessionId: string | undefined,
160
+ existingSessionPresent: boolean,
161
+ ): boolean {
162
+ if (!explicitSessionId) return false;
163
+ return actionId === 'navigate' || existingSessionPresent;
164
+ }
165
+
152
166
  interface BrowserActionScreenshot {
153
167
  path: string;
154
168
  relativePath: string;
@@ -245,39 +259,6 @@ interface BrowserPluginRuntimeHooks {
245
259
  activateNativeBrowserApplication(input: AssistantPluginActionExecutionInput, product: MacOsBrowserProduct): Promise<void>;
246
260
  }
247
261
 
248
- const NATIVE_BROWSER_BUNDLE_IDS: Record<MacOsBrowserProduct, string> = {
249
- chrome: 'com.google.Chrome',
250
- vivaldi: 'com.vivaldi.Vivaldi',
251
- };
252
-
253
- async function activateNativeBrowserApplicationViaDesktopOperator(
254
- input: AssistantPluginActionExecutionInput,
255
- product: MacOsBrowserProduct,
256
- ): Promise<void> {
257
- const desktopOperator = getExternalPluginAdapter(input.controllerHome, 'desktop_operator');
258
- if (!desktopOperator) {
259
- throw new AssistantPluginError(
260
- 'PLUGIN_BROWSER_NATIVE_FOREGROUND_ACTIVATOR_UNAVAILABLE',
261
- 'Native browser foreground activation requires the registered Forge Desktop Operator.',
262
- { retryable: true, details: { browserProduct: product } },
263
- );
264
- }
265
- await desktopOperator.executeAction({
266
- controllerHome: input.controllerHome,
267
- repoId: input.repoId,
268
- repoRoot: input.repoRoot,
269
- pluginId: 'desktop_operator',
270
- actionId: 'desktop_session_open',
271
- requestId: `${input.requestId}:native-browser-foreground:${product}`,
272
- args: { bundle_id: NATIVE_BROWSER_BUNDLE_IDS[product], launch: false, activate: true },
273
- origin: input.origin,
274
- jobId: input.jobId,
275
- timeoutMs: input.timeoutMs,
276
- signal: input.signal,
277
- deadlineAtMs: input.deadlineAtMs,
278
- });
279
- }
280
-
281
262
  const defaultRuntimeHooks: BrowserPluginRuntimeHooks = {
282
263
  now: () => new Date().toISOString(),
283
264
  moduleAvailable: (name: string, repoRoot?: string) => {
@@ -318,7 +299,7 @@ const defaultRuntimeHooks: BrowserPluginRuntimeHooks = {
318
299
  clearTimeout(timer);
319
300
  }
320
301
  },
321
- activateNativeBrowserApplication: activateNativeBrowserApplicationViaDesktopOperator,
302
+ activateNativeBrowserApplication: activateRuntimeComputerBrowserApplication,
322
303
  };
323
304
 
324
305
  let runtimeHooks: BrowserPluginRuntimeHooks = { ...defaultRuntimeHooks };
@@ -406,10 +387,6 @@ function stringList(value: unknown): string[] | undefined {
406
387
  return normalized.length > 0 ? Array.from(new Set(normalized)) : undefined;
407
388
  }
408
389
 
409
- function configPath(repoRoot: string): string {
410
- return join(repoRoot, CONFIG_ROOT, 'browser.json');
411
- }
412
-
413
390
  function defaultProfileDir(repoRoot: string): string {
414
391
  return join(browserStateDir(repoRoot, 'profiles'), 'default');
415
392
  }
@@ -501,8 +478,10 @@ function writeJson(path: string, value: unknown): void {
501
478
  writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`, 'utf-8');
502
479
  }
503
480
 
504
- function loadConfig(repoRoot: string): BrowserPluginConfig {
505
- const persisted = readJson<PersistedBrowserPluginConfig>(configPath(repoRoot));
481
+ function loadConfig(repoRoot: string, context?: Pick<RepositoryPluginConfigContext, 'controllerHome' | 'repoId'>): BrowserPluginConfig {
482
+ const persisted = context
483
+ ? readRepositoryPluginConfig<PersistedBrowserPluginConfig>({ ...context, repoRoot }, BROWSER_PLUGIN_ID)
484
+ : undefined;
506
485
  if (!persisted) return normalizeConfig({});
507
486
  return normalizeConfig(migrateLegacyRepositoryConfig(persisted));
508
487
  }
@@ -513,7 +492,7 @@ async function resolveBrowserPluginAuthorizationContextInternal(
513
492
  const action = browserActions().find((entry) => entry.actionId === input.actionId);
514
493
  if (!action || action.confirmation !== 'authorization' || !action.scopes.includes('browser.interact')) return undefined;
515
494
 
516
- const persistedConfig = loadConfig(input.repoRoot);
495
+ const persistedConfig = loadConfig(input.repoRoot, input);
517
496
  const sessionId = stringValue(input.args.session_id);
518
497
  const authorizationBrowserMode = parseBrowserModeInput(input.args.browser_mode) ?? persistedConfig.browserMode;
519
498
  if (!sessionId || authorizationBrowserMode === 'isolated') return undefined;
@@ -568,15 +547,9 @@ export async function resolveBrowserPluginAuthorizationContext(
568
547
  );
569
548
  }
570
549
 
571
- export function readBrowserPluginConfiguration(repoRoot: string): { enabled: boolean } {
572
- const config = loadConfig(repoRoot);
573
- return { enabled: config.enabled };
574
- }
575
-
576
- function saveConfig(repoRoot: string, patch: Partial<BrowserPluginConfig>): BrowserPluginConfig {
577
- const next = normalizeConfig({ ...loadConfig(repoRoot), ...patch });
578
- writeJson(configPath(repoRoot), next);
579
- return next;
550
+ function saveConfig(input: Pick<AssistantPluginActionExecutionInput, 'controllerHome' | 'repoId' | 'repoRoot'>, patch: Partial<BrowserPluginConfig>): BrowserPluginConfig {
551
+ const next = normalizeConfig({ ...loadConfig(input.repoRoot, input), ...patch });
552
+ return writeRepositoryPluginConfig(input, BROWSER_PLUGIN_ID, next);
580
553
  }
581
554
 
582
555
  function parsedAbsoluteUrl(value: unknown): { raw: string; parsed: URL } {
@@ -1054,7 +1027,7 @@ async function establishAuthoritativeNativeForeground(
1054
1027
  const cause = error instanceof Error ? error.message : String(error);
1055
1028
  throw new AssistantPluginError(
1056
1029
  'PLUGIN_BROWSER_ACTIVATION_FAILED',
1057
- 'Native browser exact-tab activation could not establish macOS system foreground authority through Forge Desktop Operator.',
1030
+ 'Native browser exact-tab activation could not establish system foreground authority through the configured Computer provider.',
1058
1031
  { retryable: true, details: { sessionId: target.sessionId, browserProduct: product, ...state, ...(causeCode ? { causeCode } : {}), cause: cause.slice(0, 500) } },
1059
1032
  );
1060
1033
  }
@@ -2127,14 +2100,36 @@ async function openNativeAttachedContext(
2127
2100
  : { sessionId: target.sessionId, status: 'no_saved_tab', reason: 'Created one plugin-owned tab while preserving the user active tab.' };
2128
2101
  }
2129
2102
 
2103
+ let createdThisCallRef: MacOsBrowserTabRef | undefined;
2130
2104
  if (!discovered?.attachment) {
2131
2105
  const candidates = savedProduct ? [savedProduct] : (config.nativeBrowserCandidates ?? [...DEFAULT_USER_NATIVE_BROWSER_CANDIDATES]);
2132
2106
  discovered = await discoverMacOsBrowserAttachment(candidates, Math.min(timeout, MAX_CDP_DISCOVERY_TIMEOUT_MS));
2107
+ const zeroWindowAttempt = args.__forge_require_existing_resource !== true
2108
+ ? discovered.attempts.find((attempt) => attempt.status === 'unavailable' && attempt.error?.includes('FORGE_NO_BROWSER_WINDOW'))
2109
+ : undefined;
2110
+ if (!discovered.attachment && zeroWindowAttempt) {
2111
+ const created = await createMacOsBrowserOwnedPageForProduct(
2112
+ zeroWindowAttempt.product,
2113
+ target.url,
2114
+ discovered.attempts,
2115
+ timeout,
2116
+ );
2117
+ page = created.page as unknown as PageLike;
2118
+ discovered = { attachment: created.attachment, attempts: created.attachment.attempts };
2119
+ createdThisCallRef = created.page.tabRef();
2120
+ matchedBy = 'owned_token';
2121
+ effectiveOwnership = 'plugin_owned';
2122
+ sessionResume = {
2123
+ sessionId: target.sessionId,
2124
+ status: 'stale_tab',
2125
+ reason: 'Browser process had no window; created the first Forge-owned tab through the existing create_tab Computer capability.',
2126
+ savedTab,
2127
+ };
2128
+ }
2133
2129
  }
2134
2130
  if (!discovered.attachment) return { attempts: discovered.attempts };
2135
2131
  let activeAttachment = discovered.attachment;
2136
2132
 
2137
- let createdThisCallRef: MacOsBrowserTabRef | undefined;
2138
2133
  let navigationUsedReplacement = false;
2139
2134
  const navigateNativePageWithReplacement = async (candidate: PageLike): Promise<PageLike> => {
2140
2135
  const obsoleteRef = (candidate as unknown as { tabRef?: () => MacOsBrowserTabRef | undefined }).tabRef?.();
@@ -2486,11 +2481,13 @@ async function withPage<T>(
2486
2481
  let lastError: unknown;
2487
2482
  for (let attempt = 1; attempt <= retries; attempt += 1) {
2488
2483
  let handle: BrowserOpenHandle | undefined;
2489
- // Opening a browser resource may itself create or navigate a tab before a
2490
- // handle is returned. Replay is safe only for an observation action that is
2491
- // fenced to an already-existing resource. Anything else is potentially
2492
- // externally mutating from the outset.
2493
- let actionDispatched = !postDispatchReplaySafe;
2484
+ // A provider/readiness failure before openBrowser returns a handle has not
2485
+ // crossed the action dispatch boundary. Native open-page creation is itself
2486
+ // transactional: its bridge either returns an exact created-tab receipt or
2487
+ // cleans up the created tab before propagating failure. Mark dispatch only
2488
+ // after a usable handle exists; subsequent goto/click/fill failures retain
2489
+ // outcome-unknown fencing for non-replay-safe actions.
2490
+ let actionDispatched = false;
2494
2491
  try {
2495
2492
  if (target.existingSession) assertBrowserSessionAvailable(repoRoot, target.sessionId);
2496
2493
  const browserArgs = requireExistingResource
@@ -2537,7 +2534,7 @@ async function withPage<T>(
2537
2534
  throw new AssistantPluginError(
2538
2535
  'PLUGIN_BROWSER_MUTATION_OUTCOME_UNKNOWN',
2539
2536
  `Browser action ${actionId} reported a transient failure after dispatch. Forge refused automatic replay because the external mutation outcome is unknown; verify current browser state before retrying.`,
2540
- { retryable: false, details: { actionId, requestedRetries: retries } },
2537
+ { retryable: false, effectOutcome: 'outcome_unknown', details: { actionId, requestedRetries: retries } },
2541
2538
  );
2542
2539
  }
2543
2540
  if (attempt >= retries) throw error;
@@ -2733,9 +2730,10 @@ const STABLE_SELECTOR_HELPERS = `
2733
2730
  `;
2734
2731
 
2735
2732
  const EXTRACTION_SCRIPTS = {
2736
- query: (selector: string, limit: number) => `(() => {
2733
+ query: (selector: string, limit: number, fromEnd = false) => `(() => {
2737
2734
  ${STABLE_SELECTOR_HELPERS}
2738
- const nodes = ${openShadowSelectorExpression(selector, true)}.slice(0, ${limit});
2735
+ const allNodes = ${openShadowSelectorExpression(selector, true)};
2736
+ const nodes = ${fromEnd ? `allNodes.slice(-${limit})` : `allNodes.slice(0, ${limit})`};
2739
2737
  return nodes.map((el) => {
2740
2738
  const role = el.getAttribute('role');
2741
2739
  const text = (el.innerText || el.textContent || '').trim().slice(0, 120);
@@ -3223,9 +3221,9 @@ function health(config: BrowserPluginConfig, repoRoot?: string): AssistantPlugin
3223
3221
  };
3224
3222
  }
3225
3223
 
3226
- export function buildBrowserPluginManifest(previousRevision = 0, previousUpdatedAt?: string, repoRoot?: string): AssistantPluginManifest {
3224
+ export function buildBrowserPluginManifest(previousRevision = 0, previousUpdatedAt?: string, repoRoot?: string, context?: AssistantPluginBuildContext): AssistantPluginManifest {
3227
3225
  const root = repoRoot ?? process.cwd();
3228
- const config = loadConfig(root);
3226
+ const config = loadConfig(root, context);
3229
3227
  const state = health(config, root);
3230
3228
  return {
3231
3229
  schemaVersion: 1,
@@ -3238,7 +3236,7 @@ export function buildBrowserPluginManifest(previousRevision = 0, previousUpdated
3238
3236
  authority: {
3239
3237
  strategy: 'derived',
3240
3238
  duplicateStateAllowed: false,
3241
- sourceOfTruth: ['repo-local:.forge/plugins/browser.json', 'controller-home:sqlite/browser_session', 'repo-local:.forge/browser/{screenshots,downloads,diagnostics}'],
3239
+ sourceOfTruth: ['controller-home:repositories/<repoId>/plugins/config/browser.json', 'controller-home:sqlite/computer_interaction_target', 'controller-home:repository browser artifacts'],
3242
3240
  },
3243
3241
  enabled: config.enabled,
3244
3242
  lifecycle: {
@@ -3278,7 +3276,7 @@ async function executeBrowserPluginActionInternal(
3278
3276
  input: AssistantPluginActionExecutionInput,
3279
3277
  runtimeAlreadyRouted = false,
3280
3278
  ): Promise<Record<string, unknown>> {
3281
- const persisted = loadConfig(input.repoRoot);
3279
+ const persisted = loadConfig(input.repoRoot, input);
3282
3280
  const actionSessionId = input.actionId === 'configure' ? undefined : stringValue(input.args.session_id);
3283
3281
  const actionSession = actionSessionId ? findBrowserSession(input.repoRoot, actionSessionId) : undefined;
3284
3282
  const current = input.actionId === 'configure' ? persisted : effectiveBrowserActionConfig(persisted, input.args, actionSession);
@@ -3360,7 +3358,7 @@ async function executeBrowserPluginActionInternal(
3360
3358
  const nextCdpAttachFallback = parseCdpAttachFallbackInput(args.cdp_attach_fallback) ?? current.cdpAttachFallback;
3361
3359
  const nextNativeAttachMode = parseNativeAttachModeInput(args.native_attach_mode) ?? current.nativeAttachMode;
3362
3360
  const nextNativeBrowserCandidates = parseNativeBrowserCandidatesInput(args.native_browser_candidates) ?? current.nativeBrowserCandidates;
3363
- const config = saveConfig(input.repoRoot, {
3361
+ const config = saveConfig(input, {
3364
3362
  enabled: typeof args.enabled === 'boolean' ? args.enabled : current.enabled,
3365
3363
  browserMode: nextBrowserMode,
3366
3364
  profileMode: nextProfileMode,
@@ -3807,7 +3805,13 @@ async function executeBrowserPluginActionInternal(
3807
3805
  ? { text: await extractText(page, undefined, positiveNumber(input.args.max_chars, DEFAULT_MAX_TEXT_CHARS)) }
3808
3806
  : {}),
3809
3807
  };
3810
- }, { requireExistingResource: Boolean(existingSessionId) });
3808
+ }, {
3809
+ requireExistingResource: browserExplicitSessionRequiresExistingResource(
3810
+ input.actionId,
3811
+ existingSessionId,
3812
+ Boolean(target.existingSession),
3813
+ ),
3814
+ });
3811
3815
  }
3812
3816
  case 'reload':
3813
3817
  case 'go_back':
@@ -3877,7 +3881,11 @@ async function executeBrowserPluginActionInternal(
3877
3881
  const limit = Math.min(positiveNumber(input.args.limit, 25), 100);
3878
3882
  return await withPage(input.actionId, input.repoRoot, current, target, input.args, async (page, _diagnostics, connection) => {
3879
3883
  const selection = resolveBrowserEvaluationScope(page, input.args, connection);
3880
- const matches = await selection.scope.evaluate<Array<Record<string, unknown>>>(EXTRACTION_SCRIPTS.query(selector, input.actionId === 'query_selector' ? 1 : limit));
3884
+ const matches = await selection.scope.evaluate<Array<Record<string, unknown>>>(EXTRACTION_SCRIPTS.query(
3885
+ selector,
3886
+ input.actionId === 'query_selector' ? 1 : limit,
3887
+ input.actionId === 'query_all' && input.args.from_end === true,
3888
+ ));
3881
3889
  return {
3882
3890
  provider: browserResultProvider(connection.provider),
3883
3891
  sessionId: target.sessionId,
@@ -3932,17 +3940,50 @@ async function executeBrowserPluginActionInternal(
3932
3940
  };
3933
3941
  }, { persistSession: true });
3934
3942
  }
3943
+ case 'reconcile_effect': {
3944
+ const effectRequestId = requiredString(input.args.effect_request_id, 'effect_request_id');
3945
+ requiredString(input.args.session_id, 'session_id');
3946
+ const observationArgs = (prefix: 'applied' | 'not_applied'): Record<string, unknown> => ({
3947
+ session_id: input.args.session_id,
3948
+ ...(input.args.url !== undefined ? { url: input.args.url } : {}),
3949
+ ...(input.args.max_chars !== undefined ? { max_chars: input.args.max_chars } : {}),
3950
+ ...(input.args.frame_url !== undefined ? { frame_url: input.args.frame_url } : {}),
3951
+ ...(input.args.frame_name !== undefined ? { frame_name: input.args.frame_name } : {}),
3952
+ ...(input.args.frame_index !== undefined ? { frame_index: input.args.frame_index } : {}),
3953
+ ...(input.args[`${prefix}_url_contains_any`] !== undefined ? { url_contains_any: input.args[`${prefix}_url_contains_any`] } : {}),
3954
+ ...(input.args[`${prefix}_url_contains_none`] !== undefined ? { url_contains_none: input.args[`${prefix}_url_contains_none`] } : {}),
3955
+ ...(input.args[`${prefix}_text_contains_any`] !== undefined ? { text_contains_any: input.args[`${prefix}_text_contains_any`] } : {}),
3956
+ ...(input.args[`${prefix}_text_contains_none`] !== undefined ? { text_contains_none: input.args[`${prefix}_text_contains_none`] } : {}),
3957
+ ...(input.args[`${prefix}_selector`] !== undefined ? { selector: input.args[`${prefix}_selector`] } : {}),
3958
+ });
3959
+ const hasCriteria = (args: Record<string, unknown>) => Object.keys(args).some((key) => !['session_id', 'url', 'max_chars', 'frame_url', 'frame_name', 'frame_index'].includes(key));
3960
+ const appliedArgs = observationArgs('applied');
3961
+ if (!hasCriteria(appliedArgs)) throw new AssistantPluginError('PLUGIN_ACTION_ARGUMENT_INVALID', 'reconcile_effect requires at least one applied_* observation criterion.', { retryable: false });
3962
+ const applied = await executeBrowserPluginAction({ ...input, actionId: 'verify_state', args: appliedArgs });
3963
+ if (applied.matched === true) return { effectRequestId, outcome: 'applied', output: applied, observation: applied };
3964
+ const notAppliedArgs = observationArgs('not_applied');
3965
+ if (hasCriteria(notAppliedArgs)) {
3966
+ const notApplied = await executeBrowserPluginAction({ ...input, actionId: 'verify_state', args: notAppliedArgs });
3967
+ if (notApplied.matched === true) return { effectRequestId, outcome: 'not_applied', observation: notApplied };
3968
+ return { effectRequestId, outcome: 'unknown', observation: { applied, notApplied } };
3969
+ }
3970
+ return { effectRequestId, outcome: 'unknown', observation: { applied } };
3971
+ }
3935
3972
  case 'verify_state': {
3936
3973
  requiredString(input.args.session_id, 'session_id');
3937
3974
  const target = resolveActionTarget(input.repoRoot, input.args);
3938
3975
  const expectedUrlRaw = stringValue(input.args.expected_url);
3939
3976
  const expectedUrl = expectedUrlRaw ? normalizedUrl(expectedUrlRaw) : undefined;
3940
3977
  const urlContains = stringValue(input.args.url_contains);
3978
+ const urlContainsAny = stringList(input.args.url_contains_any);
3979
+ const urlContainsNone = stringList(input.args.url_contains_none);
3941
3980
  const selector = stringValue(input.args.selector);
3942
3981
  const requireVisible = input.args.require_visible === true;
3943
3982
  const textContains = stringValue(input.args.text_contains);
3944
- if (!expectedUrl && !urlContains && !selector && !textContains) {
3945
- throw new AssistantPluginError('PLUGIN_ACTION_ARGUMENT_INVALID', 'verify_state requires at least one of expected_url, url_contains, selector, or text_contains.', { retryable: false });
3983
+ const textContainsAny = stringList(input.args.text_contains_any);
3984
+ const textContainsNone = stringList(input.args.text_contains_none);
3985
+ if (!expectedUrl && !urlContains && !urlContainsAny && !urlContainsNone && !selector && !textContains && !textContainsAny && !textContainsNone) {
3986
+ throw new AssistantPluginError('PLUGIN_ACTION_ARGUMENT_INVALID', 'verify_state requires at least one URL, selector, or text criterion.', { retryable: false });
3946
3987
  }
3947
3988
  if (requireVisible && !selector) {
3948
3989
  throw new AssistantPluginError('PLUGIN_ACTION_ARGUMENT_INVALID', 'require_visible requires selector.', { retryable: false });
@@ -3953,9 +3994,11 @@ async function executeBrowserPluginActionInternal(
3953
3994
  const checks: Array<Record<string, unknown>> = [];
3954
3995
  if (expectedUrl) checks.push({ criterion: 'url_exact', expected: expectedUrl, observed: observedUrl, matched: observedUrl === expectedUrl });
3955
3996
  if (urlContains) checks.push({ criterion: 'url_contains', expected: urlContains, observed: observedUrl, matched: observedUrl.includes(urlContains) });
3997
+ if (urlContainsAny) checks.push({ criterion: 'url_contains_any', expected: urlContainsAny, observed: observedUrl, matched: urlContainsAny.some((value) => observedUrl.includes(value)) });
3998
+ if (urlContainsNone) checks.push({ criterion: 'url_contains_none', expected: urlContainsNone, observed: observedUrl, matched: urlContainsNone.every((value) => !observedUrl.includes(value)) });
3956
3999
  let observation: { verificationVersion?: unknown; selectorExists?: unknown; visible?: unknown; textContains?: unknown; textSample?: unknown; textLength?: unknown; truncated?: unknown } | undefined;
3957
- if (selector || textContains) {
3958
- observation = await selection.scope.evaluate(verifyStateObservationScript(selector, textContains, Math.min(positiveNumber(input.args.max_chars, 2_000), 100_000)));
4000
+ if (selector || textContains || textContainsAny || textContainsNone) {
4001
+ observation = await selection.scope.evaluate(verifyStateObservationScript(selector, textContains, Math.min(positiveNumber(input.args.max_chars, 12_000), 100_000)));
3959
4002
  if (observation?.verificationVersion !== 1) {
3960
4003
  throw new AssistantPluginError('PLUGIN_BROWSER_VERIFY_STATE_UNAVAILABLE', 'Browser state observation returned an unsupported result.', { retryable: true });
3961
4004
  }
@@ -3973,6 +4016,9 @@ async function executeBrowserPluginActionInternal(
3973
4016
  ...(selector ? { selector } : {}),
3974
4017
  });
3975
4018
  }
4019
+ const textSample = typeof observation?.textSample === 'string' ? observation.textSample : '';
4020
+ if (textContainsAny) checks.push({ criterion: 'text_contains_any', expected: textContainsAny, observed: textSample, matched: textContainsAny.some((value) => textSample.includes(value)), textLength: observation?.textLength, truncated: observation?.truncated });
4021
+ if (textContainsNone) checks.push({ criterion: 'text_contains_none', expected: textContainsNone, observed: textSample, matched: textContainsNone.every((value) => !textSample.includes(value)), textLength: observation?.textLength, truncated: observation?.truncated });
3976
4022
  return {
3977
4023
  provider: browserResultProvider(connection.provider),
3978
4024
  sessionId: target.sessionId,
@@ -4086,15 +4132,16 @@ async function executeBrowserPluginActionInternal(
4086
4132
  case 'activate_page': {
4087
4133
  const target = resolveActionTarget(input.repoRoot, input.args);
4088
4134
  return await withPage(input.actionId, input.repoRoot, current, target, input.args, async (page, _diagnostics, connection) => {
4089
- const waitMs = positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS);
4090
4135
  if (connection.provider === 'macos-apple-events') {
4091
- await establishAuthoritativeNativeForeground(input, page, connection, target, waitMs);
4136
+ await establishAuthoritativeNativeForeground(
4137
+ input, page, connection, target, browserNativeForegroundVerificationWaitMs(input.args.post_action_wait_ms),
4138
+ );
4092
4139
  } else {
4093
4140
  if (!page.bringToFront) {
4094
4141
  throw new AssistantPluginError('PLUGIN_BROWSER_ACTIVATION_UNSUPPORTED', 'The selected browser provider cannot bring the saved page to the foreground.', { retryable: false });
4095
4142
  }
4096
4143
  await page.bringToFront();
4097
- await delay(waitMs);
4144
+ await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
4098
4145
  }
4099
4146
  return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'activate_page', 'Activated the exact saved browser page in authoritative foreground state.', {});
4100
4147
  });
@@ -4137,7 +4184,7 @@ async function executeBrowserPluginActionInternal(
4137
4184
  element.click();
4138
4185
  return { tag: element.tagName.toLowerCase(), className: element.className || '', text: normalize(element.innerText || element.textContent || '') };
4139
4186
  }, { text });
4140
- await delay(positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS));
4187
+ await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
4141
4188
  return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'click_text', `Clicked exact visible text ${text}.`, { text, clicked });
4142
4189
  });
4143
4190
  }
@@ -4182,7 +4229,7 @@ async function executeBrowserPluginActionInternal(
4182
4229
  if (page.uncheck) await page.uncheck(selector, { timeout: timeoutMs });
4183
4230
  else await page.click(selector, { timeout: timeoutMs });
4184
4231
  }
4185
- await delay(positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS));
4232
+ await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
4186
4233
  const summary = input.actionId === 'click'
4187
4234
  ? `Clicked ${selector}.`
4188
4235
  : input.actionId === 'double_click'
@@ -4213,7 +4260,7 @@ async function executeBrowserPluginActionInternal(
4213
4260
  return await withPage(input.actionId, input.repoRoot, current, target, input.args, async (page, _diagnostics, connection) => {
4214
4261
  if (input.actionId === 'fill' || !page.type) await page.fill(selector, text, { timeout: timeoutMs });
4215
4262
  else await page.type(selector, text, { timeout: timeoutMs });
4216
- await delay(positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS));
4263
+ await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
4217
4264
  return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, input.actionId, `${input.actionId} ${selector} with ${text.length} characters.`, {
4218
4265
  selector,
4219
4266
  textLength: text.length,
@@ -4233,7 +4280,7 @@ async function executeBrowserPluginActionInternal(
4233
4280
  if (!Array.isArray(selectedValues) || selectedValues.length === 0) {
4234
4281
  throw new AssistantPluginError('PLUGIN_BROWSER_SELECT_OPTION_FAILED', 'The browser provider did not retain any requested option selection.', { retryable: true, details: { selector, requestedCount: values.length } });
4235
4282
  }
4236
- await delay(positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS));
4283
+ await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
4237
4284
  return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'select_option', `Selected ${values.length} option(s) on ${selector}.`, { selector, values, selectedValues });
4238
4285
  });
4239
4286
  }
@@ -4243,7 +4290,7 @@ async function executeBrowserPluginActionInternal(
4243
4290
  const key = requiredString(input.args.key, 'key');
4244
4291
  return await withPage(input.actionId, input.repoRoot, current, target, input.args, async (page, _diagnostics, connection) => {
4245
4292
  await page.press(selector, key, { timeout: positiveNumber(input.args.timeout_ms, current.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS) });
4246
- await delay(positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS));
4293
+ await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
4247
4294
  return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'press', `Pressed ${key} on ${selector}.`, {
4248
4295
  selector,
4249
4296
  key,
@@ -4256,7 +4303,7 @@ async function executeBrowserPluginActionInternal(
4256
4303
  return await withPage(input.actionId, input.repoRoot, current, target, input.args, async (page, _diagnostics, connection) => {
4257
4304
  if (page.keyboard?.press) await page.keyboard.press(key);
4258
4305
  else await page.press('body', key, { timeout: positiveNumber(input.args.timeout_ms, current.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS) });
4259
- await delay(positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS));
4306
+ await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
4260
4307
  return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'keyboard_shortcut', `Pressed shortcut ${key}.`, { key });
4261
4308
  });
4262
4309
  }
@@ -4398,7 +4445,7 @@ async function executeBrowserPluginActionInternal(
4398
4445
  }
4399
4446
  }
4400
4447
  if (nativeTrustedInput) await page.trustedInput!(trustedRequest);
4401
- await delay(positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS));
4448
+ await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
4402
4449
  return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'trusted_input', `Sent trusted browser input (${kind}).`, { kind, ...(guard ? { guard } : {}) });
4403
4450
  });
4404
4451
  }
@@ -4418,7 +4465,7 @@ async function executeBrowserPluginActionInternal(
4418
4465
  const accepted = element.dispatchEvent(domEvent);
4419
4466
  return { accepted, defaultPrevented: domEvent.defaultPrevented };
4420
4467
  }, { selector, event });
4421
- await delay(positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS));
4468
+ await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
4422
4469
  return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'dispatch_event', `Dispatched ${event} on ${selector}.`, {
4423
4470
  selector,
4424
4471
  event,
@@ -4488,7 +4535,7 @@ async function executeBrowserPluginActionInternal(
4488
4535
  throw new AssistantPluginError('PLUGIN_BROWSER_FILE_ATTACH_UNSUPPORTED', 'The selected browser provider does not support local file attachment.', { retryable: false });
4489
4536
  }
4490
4537
  await page.setInputFiles(selector, resolved.length === 1 ? resolved[0] : resolved);
4491
- await delay(positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS));
4538
+ await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
4492
4539
  const fileNames = resolved.map((path) => basename(path));
4493
4540
  return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'attach_local_file', `Attached ${resolved.length} local file(s) to ${selector}.`, {
4494
4541
  selector,
@@ -4549,7 +4596,7 @@ async function executeBrowserPluginActionInternal(
4549
4596
  if (!existsSync(dest)) {
4550
4597
  throw new AssistantPluginError('PLUGIN_BROWSER_DOWNLOAD_FAILED', 'Browser download save completed without producing an artifact; refusing false success.', { retryable: true, details: { selector } });
4551
4598
  }
4552
- await delay(positiveNumber(input.args.post_action_wait_ms, DEFAULT_POST_ACTION_WAIT_MS));
4599
+ await delay(browserExplicitPostActionWaitMs(input.args.post_action_wait_ms));
4553
4600
  return finalizeInteractiveAction(input.repoRoot, current, page, target, connection, 'await_file_transfer', `Captured download artifact for ${selector}.`, {
4554
4601
  selector,
4555
4602
  download: {
@@ -4588,10 +4635,3 @@ export async function executeBrowserPluginAction(input: AssistantPluginActionExe
4588
4635
  () => executeBrowserPluginActionInternal(input),
4589
4636
  );
4590
4637
  }
4591
-
4592
- export const browserPluginAdapter = {
4593
- pluginId: BROWSER_PLUGIN_ID,
4594
- buildManifest: buildBrowserPluginManifest,
4595
- executeAction: executeBrowserPluginAction,
4596
- resolveAuthorizationContext: resolveBrowserPluginAuthorizationContext,
4597
- };
@@ -1,45 +1,24 @@
1
- import { callMacOsCapabilityBroker } from './macos-capability-broker';
1
+ import type {
2
+ ComputerBrowserAutomationRequest,
3
+ ComputerBrowserProduct,
4
+ ComputerBrowserTabRef,
5
+ ComputerCaptureRegion,
6
+ ComputerTrustedInput,
7
+ } from '../../../packages/protocols/computer/index';
8
+ import { executeRuntimeComputerBrowserAutomation } from '../root/computer-composition';
2
9
  import { AssistantPluginError } from './errors';
3
10
 
4
- const BROWSER_AUTOMATION_PROTOCOL_VERSION = 1;
5
-
6
- export type BrowserAutomationProduct = 'chrome' | 'vivaldi';
7
- export interface BrowserAutomationTabRef {
8
- windowId: string;
9
- tabId: string;
10
- }
11
- export interface BrowserAutomationRegion {
12
- x: number;
13
- y: number;
14
- width: number;
15
- height: number;
16
- }
17
-
18
- export type BrowserAutomationTrustedInput =
19
- | { kind: 'click'; x: number; y: number; button: 'left' | 'middle' | 'right'; clickCount: number }
20
- | { kind: 'move'; x: number; y: number; steps: number }
21
- | { kind: 'wheel'; deltaX: number; deltaY: number }
22
- | { kind: 'drag'; fromX: number; fromY: number; toX: number; toY: number; button: 'left' | 'middle' | 'right'; steps: number }
23
- | { kind: 'key'; key: string }
24
- | { kind: 'text'; text: string };
25
-
26
- export type BrowserAutomationBrokerAction =
27
- | { action: 'metadata'; product: BrowserAutomationProduct; ref?: BrowserAutomationTabRef }
28
- | { action: 'list_tabs'; product: BrowserAutomationProduct }
29
- | { action: 'create_tab'; product: BrowserAutomationProduct; url: string }
30
- | { action: 'close_tab'; product: BrowserAutomationProduct; ref: BrowserAutomationTabRef }
31
- | { action: 'navigate'; product: BrowserAutomationProduct; ref?: BrowserAutomationTabRef; url: string }
32
- | { action: 'reload'; product: BrowserAutomationProduct; ref?: BrowserAutomationTabRef }
33
- | { action: 'execute_javascript'; product: BrowserAutomationProduct; ref?: BrowserAutomationTabRef; source: string }
34
- | { action: 'activate'; product: BrowserAutomationProduct; ref?: BrowserAutomationTabRef }
35
- | { action: 'trusted_input'; product: BrowserAutomationProduct; ref: BrowserAutomationTabRef; input: BrowserAutomationTrustedInput }
36
- | { action: 'capture_region'; region: BrowserAutomationRegion };
11
+ export type BrowserAutomationProduct = ComputerBrowserProduct;
12
+ export type BrowserAutomationTabRef = ComputerBrowserTabRef;
13
+ export type BrowserAutomationRegion = ComputerCaptureRegion;
14
+ export type BrowserAutomationTrustedInput = ComputerTrustedInput;
15
+ export type BrowserAutomationBrokerAction = ComputerBrowserAutomationRequest;
37
16
 
38
17
  export async function callBrowserAutomationBroker(
39
18
  request: BrowserAutomationBrokerAction,
40
19
  timeoutMs: number,
41
20
  ): Promise<Record<string, unknown>> {
42
- return await callMacOsCapabilityBroker({ ...request, timeoutMs, protocolVersion: BROWSER_AUTOMATION_PROTOCOL_VERSION }, timeoutMs);
21
+ return await executeRuntimeComputerBrowserAutomation(request, timeoutMs);
43
22
  }
44
23
 
45
24
  export async function captureBrowserAutomationRegion(region: BrowserAutomationRegion, timeoutMs: number): Promise<Buffer> {
@@ -48,7 +27,7 @@ export async function captureBrowserAutomationRegion(region: BrowserAutomationRe
48
27
  if (!base64) {
49
28
  throw new AssistantPluginError(
50
29
  'PLUGIN_MACOS_CAPABILITY_BROKER_PROTOCOL_ERROR',
51
- 'Stable Forge macOS capability broker returned an invalid screenshot payload.',
30
+ 'Computer capture provider returned an invalid screenshot payload.',
52
31
  { retryable: true },
53
32
  );
54
33
  }