@moretea-labs/forge 1.8.0 → 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 (528) hide show
  1. package/AGENTS.md +70 -7
  2. package/CHANGELOG.md +14 -0
  3. package/CLAUDE.md +17 -2
  4. package/CONTRIBUTING.md +3 -2
  5. package/THIRD_PARTY_NOTICES.md +1 -1
  6. package/adapters/chatgpt/browser-delivery-host.ts +7 -1
  7. package/adapters/chatgpt/browser-delivery-runtime.ts +529 -56
  8. package/adapters/chatgpt/controller-binding-store.ts +101 -22
  9. package/adapters/chatgpt/controller-round-host.ts +15 -25
  10. package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
  11. package/adapters/chatgpt/provider-delivery.ts +228 -1
  12. package/adapters/chatgpt/work-conversation-binding-store.ts +79 -53
  13. package/adapters/computer/chatgpt-extension-target.ts +463 -0
  14. package/adapters/computer/chatgpt-target-router.ts +103 -0
  15. package/adapters/computer/chrome-extension/background.js +385 -0
  16. package/adapters/computer/chrome-extension/content.js +378 -0
  17. package/adapters/computer/chrome-extension/core.js +24 -0
  18. package/adapters/computer/chrome-extension/manifest.json +30 -0
  19. package/adapters/computer/desktop-operator-discovery.ts +11 -31
  20. package/adapters/computer/interaction-target-authority.ts +142 -18
  21. package/adapters/mcp/auth.ts +0 -1
  22. package/adapters/mcp/instructions.ts +5 -4
  23. package/adapters/mcp/multi-repository.ts +3 -19
  24. package/adapters/mcp/oauth.ts +73 -0
  25. package/adapters/mcp/paths.ts +4 -1
  26. package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +87 -0
  27. package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
  28. package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
  29. package/adapters/mcp/runtime-gateway/context-adapter.ts +411 -73
  30. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
  31. package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
  32. package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
  33. package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
  34. package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
  35. package/adapters/mcp/runtime-gateway/execution-tools.ts +8 -42
  36. package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
  37. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +117 -45
  38. package/adapters/mcp/runtime-gateway/process-tools.ts +190 -22
  39. package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
  40. package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
  41. package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
  42. package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
  43. package/adapters/mcp/runtime-gateway/router.ts +18 -504
  44. package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
  45. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +14 -65
  46. package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
  47. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +113 -173
  48. package/adapters/mcp/runtime-gateway/runtime-tools.ts +15 -5
  49. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +1 -0
  50. package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
  51. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +358 -266
  52. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
  53. package/adapters/mcp/runtime-gateway/work-adapter.ts +261 -3122
  54. package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
  55. package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
  56. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
  57. package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
  58. package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
  59. package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
  60. package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
  61. package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
  62. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
  63. package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
  64. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
  65. package/adapters/mcp/server.ts +67 -23
  66. package/adapters/mcp/setup.ts +1 -3
  67. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +44 -170
  68. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +4 -9
  69. package/adapters/mcp/tool-mapping/repository-tools.ts +133 -142
  70. package/adapters/mcp/toolset-names.ts +5 -0
  71. package/adapters/mcp/toolset.ts +6 -5
  72. package/adapters/mcp/transports/http-observation.ts +365 -0
  73. package/adapters/mcp/transports/http.ts +154 -677
  74. package/adapters/mcp/transports/oauth-http.ts +322 -0
  75. package/adapters/mcp/transports/session-registry.ts +6 -0
  76. package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
  77. package/assets/plugin-registry.v1.json +6 -4
  78. package/assets/reference-configs/agentic-development-flow.md +25 -0
  79. package/assets/reference-configs/global-working-rules.md +19 -0
  80. package/assets/skill-version.json +2 -2
  81. package/docs/architecture/CURRENT.md +111 -41
  82. package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
  83. package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
  84. package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
  85. package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
  86. package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
  87. package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
  88. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
  89. package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
  90. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
  91. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
  92. package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
  93. package/docs/architecture/domains/verification.md +1 -0
  94. package/docs/architecture/domains/workflow-engine.md +6 -0
  95. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
  96. package/docs/forge-plugin-management.md +2 -2
  97. package/docs/operations/controller-performance-and-502.md +17 -0
  98. package/docs/operations/controller-reliability-runbook.md +2 -2
  99. package/docs/operations/features.md +1 -1
  100. package/docs/operations/features.zh-CN.md +1 -1
  101. package/docs/operations/homebrew.md +2 -2
  102. package/docs/operations/mcp-tool-exposure.md +2 -0
  103. package/docs/operations/releasing.md +2 -0
  104. package/docs/operations/standalone-disaster-recovery.md +14 -6
  105. package/docs/wiki/Implementation.md +1 -1
  106. package/package.json +25 -14
  107. package/packages/kernel/cognition/api/index.ts +6 -0
  108. package/packages/kernel/cognition/application/activation-service.ts +451 -0
  109. package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
  110. package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
  111. package/packages/kernel/cognition/application/memory-service.ts +64 -0
  112. package/packages/kernel/cognition/domain/learning.ts +106 -0
  113. package/packages/kernel/cognition/domain/memory.ts +254 -0
  114. package/packages/kernel/controller/api/index.ts +1 -0
  115. package/packages/kernel/controller/application/continuation-service.ts +281 -0
  116. package/packages/kernel/controller/application/controller-round-service.ts +12 -0
  117. package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
  118. package/packages/kernel/controller/domain/controller-round.ts +4 -1
  119. package/packages/kernel/controller/domain/execution-quality.ts +3 -1
  120. package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
  121. package/packages/kernel/controller/infrastructure/controller-session-store.ts +297 -71
  122. package/packages/kernel/controller/ports/controller-host.ts +2 -0
  123. package/packages/kernel/identity/api/index.ts +10 -0
  124. package/packages/kernel/identity/domain/activity-projection.ts +43 -0
  125. package/packages/kernel/identity/domain/capability-broker.ts +60 -0
  126. package/packages/kernel/identity/domain/grant.ts +72 -0
  127. package/packages/kernel/identity/domain/owned-resource.ts +116 -0
  128. package/packages/kernel/identity/domain/user-request.ts +93 -0
  129. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
  130. package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
  131. package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
  132. package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
  133. package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
  134. package/packages/kernel/scheduler/api/index.ts +0 -2
  135. package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
  136. package/packages/kernel/scheduler/application/settlement.ts +0 -15
  137. package/packages/kernel/scheduler/domain/schedule.ts +87 -0
  138. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +153 -133
  139. package/packages/kernel/work/api/index.ts +3 -2
  140. package/packages/kernel/work/application/work-service.ts +17 -42
  141. package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
  142. package/packages/kernel/work/domain/engineering-design.ts +10 -5
  143. package/packages/kernel/work/domain/engineering-profile.ts +8 -12
  144. package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
  145. package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
  146. package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
  147. package/packages/kernel/work/domain/implementation-review.ts +14 -331
  148. package/packages/kernel/work/domain/objective-graph.ts +119 -0
  149. package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
  150. package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
  151. package/packages/kernel/work/domain/state-machine.ts +25 -63
  152. package/packages/kernel/work/domain/types.ts +57 -51
  153. package/packages/kernel/work/infrastructure/work-contract-store.ts +819 -728
  154. package/packages/kernel/work/ports/work-contract-store.ts +5 -2
  155. package/packages/plugin-runtime/browser/session-authority.ts +2 -1
  156. package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
  157. package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
  158. package/packages/plugin-runtime/computer/index.ts +2 -0
  159. package/packages/plugin-runtime/computer/target-authority.ts +26 -1
  160. package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
  161. package/packages/protocols/computer/contract.ts +27 -1
  162. package/scripts/activate-source-baseline.ts +7 -9
  163. package/scripts/canary-controller-semantic-wait.ts +12 -24
  164. package/scripts/check-mcp-compatibility.ts +48 -136
  165. package/scripts/check-runtime-architecture.mjs +622 -217
  166. package/scripts/forge-local-recovery-helper.mjs +93 -15
  167. package/scripts/lib/project-init-lib.sh +3 -0
  168. package/scripts/open-source-audit-allowlist.txt +1 -2
  169. package/scripts/run-bounded-command.mjs +5 -0
  170. package/scripts/run-governed-gate.ts +0 -1
  171. package/scripts/run-mobile-monitor-bridge.ts +0 -1
  172. package/scripts/smoke-control-plane-failure-domain.ts +94 -0
  173. package/scripts/smoke-mcp-http-runtime.ts +5 -0
  174. package/scripts/smoke-runtime-recovery.ts +12 -43
  175. package/scripts/smoke-schedule-engine.ts +23 -15
  176. package/scripts/smoke-unattended-transport-recovery.ts +223 -0
  177. package/scripts/smoke-user-request-continuation-restart.ts +232 -0
  178. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
  179. package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
  180. package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
  181. package/scripts/smoke-workflow-supervisor.ts +103 -0
  182. package/scripts/verify-forge-runtime.sh +2 -1
  183. package/src/cli/agent-jobs/executor-health.ts +11 -34
  184. package/src/cli/agent-jobs/integration.ts +18 -49
  185. package/src/cli/agent-jobs/job-manager.ts +7 -3
  186. package/src/cli/commands/brain-assistant.ts +27 -13
  187. package/src/cli/commands/brain.ts +13 -15
  188. package/src/cli/commands/chatgpt.ts +1 -163
  189. package/src/cli/commands/recovery.ts +135 -121
  190. package/src/cli/commands/runtime.ts +3 -3
  191. package/src/cli/commands/setup-profile.ts +8 -0
  192. package/src/cli/controller/check-runner.ts +13 -2
  193. package/src/cli/controller/completion-backlog.ts +3 -3
  194. package/src/cli/controller/completion-orchestrator.ts +4 -43
  195. package/src/cli/controller/completion-target.ts +3 -72
  196. package/src/cli/controller/context/source-materializer.ts +81 -100
  197. package/src/cli/controller/context-pack.ts +10 -8
  198. package/src/cli/controller/execution-completion.ts +4 -7
  199. package/src/cli/controller/execution-policy.ts +36 -153
  200. package/src/cli/controller/governance.ts +2 -3
  201. package/src/cli/controller/issue-store.ts +4 -99
  202. package/src/cli/controller/launch-agents.ts +59 -18
  203. package/src/cli/controller/operational-plan.ts +24 -51
  204. package/src/cli/controller/runtime-config.ts +5 -1
  205. package/src/cli/controller/stuck-state-migration.ts +2 -3
  206. package/src/cli/controller/systemd-user.ts +39 -1
  207. package/src/cli/editing/edit-session.ts +1 -7
  208. package/src/cli/local-bridge/console-automations.ts +18 -13
  209. package/src/cli/local-bridge/console-view-models.ts +3 -12
  210. package/src/cli/local-bridge/facade-api.ts +64 -191
  211. package/src/cli/local-bridge/server.ts +24 -147
  212. package/src/cli/local-bridge/types.ts +0 -1
  213. package/src/cli/mcp/oauth-client-retirement.ts +74 -0
  214. package/src/cli/repositories/command-executor.ts +29 -23
  215. package/src/cli/repositories/command-scope.ts +35 -16
  216. package/src/cli/repositories/controller-home.ts +48 -0
  217. package/src/cli/repositories/ephemeral-workspace.ts +20 -30
  218. package/src/cli/repositories/git-command-executor.ts +2 -2
  219. package/src/cli/repositories/registry.ts +77 -11
  220. package/src/cli/repositories/structured-git.ts +62 -2
  221. package/src/cli/repository/session-cache.ts +92 -6
  222. package/src/runtime/context/assistant-context.ts +20 -7
  223. package/src/runtime/context/assistant-work-context.ts +89 -27
  224. package/src/runtime/context/automatic-learning.ts +565 -0
  225. package/src/runtime/context/cognitive-attention.ts +173 -0
  226. package/src/runtime/context/cognitive-skill-canary.ts +158 -0
  227. package/src/runtime/context/context-closure.ts +46 -9
  228. package/src/runtime/context/context-pack-process.ts +103 -0
  229. package/src/runtime/context/context-plane.ts +1 -9
  230. package/src/runtime/context/direct-controller-learning.ts +298 -0
  231. package/src/runtime/context/semantic-navigation-contract.ts +9 -0
  232. package/src/runtime/context/semantic-navigation.ts +6 -34
  233. package/src/runtime/context/typescript-navigation-process.ts +145 -0
  234. package/src/runtime/context/typescript-navigation.ts +89 -3
  235. package/src/runtime/control-plane/cleanup-artifact-retention.ts +212 -9
  236. package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
  237. package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
  238. package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
  239. package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
  240. package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
  241. package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
  242. package/src/runtime/control-plane/execution/session-store.ts +31 -1
  243. package/src/runtime/control-plane/execution/validation.ts +6 -8
  244. package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
  245. package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
  246. package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
  247. package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
  248. package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
  249. package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
  250. package/src/runtime/control-plane/execution/work-handle-authority.ts +188 -109
  251. package/src/runtime/control-plane/execution/work-handle-store.ts +19 -43
  252. package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
  253. package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
  254. package/src/runtime/control-plane/execution/work-operation-service.ts +43 -27
  255. package/src/runtime/control-plane/execution/work-preparation-service.ts +126 -266
  256. package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
  257. package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
  258. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +173 -186
  259. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +28 -84
  260. package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
  261. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
  262. package/src/runtime/control-plane/facade/capability-registry.ts +362 -37
  263. package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
  264. package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
  265. package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
  266. package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
  267. package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
  268. package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
  269. package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
  270. package/src/runtime/control-plane/facade/index.ts +0 -1
  271. package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
  272. package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
  273. package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
  274. package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
  275. package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
  276. package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
  277. package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
  278. package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
  279. package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
  280. package/src/runtime/control-plane/facade/types.ts +49 -108
  281. package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
  282. package/src/runtime/control-plane/generated-cache-retention.ts +97 -1
  283. package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
  284. package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
  285. package/src/runtime/control-plane/global-scheduler/maintenance.ts +239 -112
  286. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +2 -1
  287. package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
  288. package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
  289. package/src/runtime/control-plane/governance/access-policy.ts +19 -2
  290. package/src/runtime/control-plane/governance/authorization.ts +20 -3
  291. package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
  292. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +28 -300
  293. package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
  294. package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
  295. package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
  296. package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
  297. package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
  298. package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
  299. package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
  300. package/src/runtime/control-plane/release-retention.ts +135 -47
  301. package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
  302. package/src/runtime/control-plane/runtime-cleanup.ts +290 -21
  303. package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
  304. package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
  305. package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
  306. package/src/runtime/diagnostics/incident-repair.ts +313 -146
  307. package/src/runtime/diagnostics/mcp-timing.ts +114 -0
  308. package/src/runtime/evidence/artifact-store.ts +158 -40
  309. package/src/runtime/evidence/evidence-store.ts +112 -8
  310. package/src/runtime/evidence/output-handle-index.ts +225 -0
  311. package/src/runtime/evidence/result-store.ts +158 -44
  312. package/src/runtime/execution/jobs/store.ts +3 -4
  313. package/src/runtime/execution/managed-workspace.ts +57 -0
  314. package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
  315. package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
  316. package/src/runtime/execution/process-runtime/check-result.ts +105 -1
  317. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
  318. package/src/runtime/execution/process-runtime/command-facade.ts +79 -27
  319. package/src/runtime/execution/process-runtime/gc.ts +15 -2
  320. package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
  321. package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
  322. package/src/runtime/execution/process-runtime/index.ts +3 -0
  323. package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
  324. package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
  325. package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
  326. package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
  327. package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
  328. package/src/runtime/execution/process-runtime/runtime.ts +35 -2
  329. package/src/runtime/execution/process-runtime/store.ts +30 -2
  330. package/src/runtime/execution/process-runtime/types.ts +6 -1
  331. package/src/runtime/execution/workers/executor.ts +2 -6
  332. package/src/runtime/platform/service-inventory.ts +130 -0
  333. package/src/runtime/platform/service-manager.ts +8 -0
  334. package/src/runtime/plugins/action-application.ts +85 -28
  335. package/src/runtime/plugins/app-store-connect-adapter.ts +38 -14
  336. package/src/runtime/plugins/browser-adapter.ts +757 -34
  337. package/src/runtime/plugins/browser-automation-service.ts +23 -3
  338. package/src/runtime/plugins/browser-macos-bridge.ts +321 -29
  339. package/src/runtime/plugins/browser-manifest-surface.ts +45 -11
  340. package/src/runtime/plugins/browser-native-session-service.ts +63 -13
  341. package/src/runtime/plugins/browser-registration.ts +16 -0
  342. package/src/runtime/plugins/browser-runtime.ts +14 -1
  343. package/src/runtime/plugins/browser-session-authority.ts +2 -2
  344. package/src/runtime/plugins/browser-session-store.ts +46 -76
  345. package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
  346. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
  347. package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
  348. package/src/runtime/plugins/computer-registration.ts +222 -11
  349. package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
  350. package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
  351. package/src/runtime/plugins/external-adapter.ts +42 -6
  352. package/src/runtime/plugins/external-registration.ts +21 -1
  353. package/src/runtime/plugins/gmail-adapter.ts +23 -2
  354. package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
  355. package/src/runtime/plugins/google-shared.ts +14 -7
  356. package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
  357. package/src/runtime/plugins/ios-adapter.ts +1 -1
  358. package/src/runtime/plugins/lightweight-action.ts +208 -2
  359. package/src/runtime/plugins/local-system-adapter.ts +12 -2
  360. package/src/runtime/plugins/managed-process-adapter.ts +12 -5
  361. package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
  362. package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
  363. package/src/runtime/plugins/store.ts +602 -428
  364. package/src/runtime/plugins/types.ts +20 -0
  365. package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
  366. package/src/runtime/projections/invalidation.ts +7 -3
  367. package/src/runtime/projections/materialized-view.ts +80 -36
  368. package/src/runtime/recovery/actions.ts +3 -3
  369. package/src/runtime/recovery/capability-action-application.ts +46 -45
  370. package/src/runtime/recovery/lifecycle-inventory.ts +29 -29
  371. package/src/runtime/recovery/maintenance-executor.ts +374 -123
  372. package/src/runtime/recovery/store.ts +29 -11
  373. package/src/runtime/release/release-coordinator.ts +296 -0
  374. package/src/runtime/release/release-session.ts +716 -0
  375. package/src/runtime/release/release-state-migration.ts +25 -0
  376. package/src/runtime/resources/leases/store.ts +56 -25
  377. package/src/runtime/root/computer-composition.ts +191 -6
  378. package/src/runtime/root/controller-progression-composition.ts +192 -0
  379. package/src/runtime/root/controller-round-composition.ts +20 -1
  380. package/src/runtime/root/deployment-topology.ts +106 -0
  381. package/src/runtime/root/entry.ts +4 -3
  382. package/src/runtime/root/known-good-recovery.ts +184 -0
  383. package/src/runtime/root/local-bridge.ts +0 -1
  384. package/src/runtime/root/mcp-transport.ts +111 -18
  385. package/src/runtime/root/ownership.ts +261 -9
  386. package/src/runtime/root/package-connector-service.ts +105 -19
  387. package/src/runtime/root/package-runtime-release.ts +117 -18
  388. package/src/runtime/root/package-runtime-service.ts +17 -11
  389. package/src/runtime/root/release-execution-canary.ts +44 -12
  390. package/src/runtime/root/release-loader.ts +90 -8
  391. package/src/runtime/root/release-manifest.ts +80 -6
  392. package/src/runtime/root/release-materialize.ts +372 -28
  393. package/src/runtime/root/release-store.ts +395 -36
  394. package/src/runtime/root/runtime-lane.ts +191 -0
  395. package/src/runtime/root/runtime.ts +159 -27
  396. package/src/runtime/root/scheduled-controller-composition.ts +28 -3
  397. package/src/runtime/root/service-runner.ts +2 -2
  398. package/src/runtime/root/service.ts +36 -33
  399. package/src/runtime/root/status.ts +48 -0
  400. package/src/runtime/root/types.ts +32 -3
  401. package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
  402. package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
  403. package/src/runtime/root/write-fence.ts +50 -2
  404. package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
  405. package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
  406. package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
  407. package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
  408. package/src/runtime/shared/process-environment.ts +20 -9
  409. package/src/runtime/shared/response-budget.ts +1 -3
  410. package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
  411. package/src/runtime/standalone-recovery/core.ts +3702 -342
  412. package/src/runtime/standalone-recovery/entry.ts +469 -39
  413. package/src/runtime/standalone-recovery/installer.ts +262 -148
  414. package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
  415. package/src/runtime/standalone-recovery/operation-lock.ts +1 -1
  416. package/src/runtime/standalone-recovery/performance.ts +54 -16
  417. package/src/runtime/standalone-recovery/release.ts +53 -5
  418. package/src/runtime/standalone-recovery/service-labels.ts +5 -2
  419. package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
  420. package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
  421. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +10 -3
  422. package/src/runtime/workflow/schedules/engine.ts +138 -172
  423. package/src/runtime/workflow/schedules/work-continuation.ts +44 -5
  424. package/src/runtime/workflows/runtime.ts +15 -19
  425. package/src/testing/test-governance.ts +5 -1
  426. package/supervisor/chatgpt-conversation.ts +23 -0
  427. package/supervisor/client.ts +201 -0
  428. package/supervisor/control-plane.ts +868 -0
  429. package/supervisor/entry.ts +15 -0
  430. package/supervisor/forge-validators.ts +80 -0
  431. package/supervisor/index.ts +5 -0
  432. package/supervisor/native-browser-adapter.ts +786 -0
  433. package/supervisor/native-messaging/host.ts +39 -0
  434. package/supervisor/native-messaging/manifest.ts +26 -0
  435. package/supervisor/native-messaging/protocol.ts +27 -0
  436. package/supervisor/paths.ts +18 -0
  437. package/supervisor/protocol.ts +202 -0
  438. package/supervisor/server.ts +404 -0
  439. package/supervisor/store.ts +1451 -0
  440. package/supervisor/tsconfig.json +8 -0
  441. package/supervisor/types.ts +255 -0
  442. package/adapters/chatgpt/controller-host.ts +0 -119
  443. package/adapters/mcp/controller-round-compatibility.ts +0 -184
  444. package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
  445. package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
  446. package/packages/kernel/progression/api/index.ts +0 -2
  447. package/packages/kernel/progression/application/projector.ts +0 -211
  448. package/packages/kernel/progression/domain/types.ts +0 -116
  449. package/packages/kernel/progression/index.ts +0 -1
  450. package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
  451. package/packages/kernel/scheduler/domain/continuation.ts +0 -38
  452. package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
  453. package/packages/kernel/work/domain/admission-policy.ts +0 -34
  454. package/scripts/benchmark-background-check-overlap.ts +0 -228
  455. package/scripts/benchmark-computer-hotpath.ts +0 -255
  456. package/scripts/benchmark-controller-hotpath.ts +0 -212
  457. package/scripts/benchmark-controller-round2.ts +0 -191
  458. package/scripts/benchmark-ios-agent-device.ts +0 -511
  459. package/scripts/benchmark-mcp-host.sh +0 -117
  460. package/scripts/benchmark-mcp-transport.ts +0 -169
  461. package/scripts/benchmark-operational-memory-activation.ts +0 -235
  462. package/scripts/benchmark-operational-shadow.ts +0 -28
  463. package/scripts/benchmark-quality-harness.ts +0 -146
  464. package/scripts/benchmark-route-session-concurrency.ts +0 -915
  465. package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
  466. package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
  467. package/scripts/benchmark-thin-harness.ts +0 -251
  468. package/scripts/benchmark-typescript-navigation.ts +0 -186
  469. package/scripts/benchmark-work-efficiency.ts +0 -334
  470. package/scripts/build-controller-ui.ts +0 -28
  471. package/scripts/check-npm-release.sh +0 -32
  472. package/scripts/check-public-release-surface.sh +0 -19
  473. package/scripts/check-release-published.sh +0 -57
  474. package/scripts/check-release-readiness.sh +0 -37
  475. package/scripts/check-release-version.mjs +0 -74
  476. package/scripts/check-tarball-install-smoke.sh +0 -150
  477. package/scripts/package-source-archive.sh +0 -147
  478. package/scripts/public-release-files.txt +0 -39
  479. package/scripts/public-release.ts +0 -174
  480. package/scripts/publish-release-tarball.sh +0 -27
  481. package/scripts/route-nl-vs-ts-eval.ts +0 -679
  482. package/scripts/stage-runtime-release.ts +0 -44
  483. package/src/cli/controller/progress.ts +0 -656
  484. package/src/cli/controller/work-mode.ts +0 -181
  485. package/src/cli/local-bridge/console-assets.ts +0 -17
  486. package/src/cli/local-bridge/dashboard.ts +0 -17
  487. package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
  488. package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
  489. package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
  490. package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
  491. package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
  492. package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
  493. package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
  494. package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
  495. package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
  496. package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
  497. package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
  498. package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
  499. package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
  500. package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
  501. package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
  502. package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
  503. package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
  504. package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
  505. package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
  506. package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
  507. package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
  508. package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
  509. package/src/cli/local-bridge/frontend/src/styles.css +0 -28
  510. package/src/cli/local-bridge/frontend/src/types.ts +0 -15
  511. package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
  512. package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
  513. package/src/cli/local-bridge/ui-dist/app.css +0 -1
  514. package/src/cli/local-bridge/ui-dist/app.js +0 -11228
  515. package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
  516. package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
  517. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
  518. package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
  519. package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
  520. package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
  521. package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
  522. package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
  523. package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
  524. package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
  525. package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
  526. package/src/runtime/control-plane/routing/index.ts +0 -1
  527. package/src/runtime/control-plane/routing/route-policy.ts +0 -401
  528. package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
@@ -0,0 +1,378 @@
1
+ (() => {
2
+ const core = globalThis.ForgeComputerChatgptCore;
3
+ if (!core) throw new Error('FORGE_COMPUTER_CHATGPT_CORE_MISSING');
4
+ const ASSISTANT = '[data-message-author-role="assistant"], [data-chatgpt-search-unit-key$=":assistant"], [data-content-search-unit-key$=":assistant"]';
5
+ const USER = '[data-message-author-role="user"], [data-chatgpt-search-unit-key$=":user"], [data-content-search-unit-key$=":user"]';
6
+ const COMPOSER = '#prompt-textarea, [data-testid="prompt-textarea"], [data-testid="composer-text-input"], textarea[name="prompt"], textarea[placeholder*="Message"], textarea[placeholder*="消息"], form [contenteditable="true"], div[role="textbox"][contenteditable="true"]';
7
+ const SEND = 'button[data-testid="send-button"], button[aria-label*="Send"], button[aria-label*="发送"], button[data-testid*="send"]';
8
+ const STOP = '[data-testid="stop-button"], [data-testid*="stop-button"], button[aria-label="Stop"], button[aria-label="Stop generating"], button[aria-label="停止"], button[aria-label="停止生成"]';
9
+ const TURN = '[data-testid^="conversation-turn-"]';
10
+ const PROVIDER_ACTIVITY_CHARS = 64 * 1024;
11
+ const PROVIDER_FAILURE_CHARS = 250_000;
12
+ const absoluteChatgptUrl = (href) => {
13
+ try { const url = new URL(String(href ?? ''), location.href); return url.protocol === 'https:' && url.hostname === 'chatgpt.com' ? url.toString() : undefined; }
14
+ catch { return undefined; }
15
+ };
16
+ const visible = (node) => Boolean(node?.getClientRects?.().length);
17
+ /**
18
+ * The hydrated conversation surface is the visible `main`. ChatGPT also
19
+ * renders hidden SSR shells, and reading those into role/progress extraction
20
+ * reports turns that the signed-in page is not actually showing.
21
+ */
22
+ const conversationRoot = () => {
23
+ const mains = Array.from(document.querySelectorAll('main')).filter(visible);
24
+ return mains.length ? mains[mains.length - 1] : document;
25
+ };
26
+ const discoverProjectLinks = (titles) => {
27
+ const wanted = new Map((Array.isArray(titles) ? titles : []).map((title) => [core.normalizeText(title).toLocaleLowerCase(), core.normalizeText(title)]).filter(([key]) => key));
28
+ const seen = new Set();
29
+ const projects = [];
30
+ for (const anchor of document.querySelectorAll('a[href]')) {
31
+ const title = core.normalizeText(anchor.innerText ?? anchor.textContent);
32
+ const matched = wanted.get(title.toLocaleLowerCase());
33
+ const url = absoluteChatgptUrl(anchor.getAttribute('href'));
34
+ if (!matched || !url || seen.has(`${matched}\n${url}`)) continue;
35
+ seen.add(`${matched}\n${url}`);
36
+ projects.push({ title: matched, url });
37
+ }
38
+ return projects;
39
+ };
40
+ const discoverConversationLinks = () => {
41
+ const seen = new Set();
42
+ const conversations = [];
43
+ for (const anchor of document.querySelectorAll('a[href]')) {
44
+ const parsed = core.parseConversation(absoluteChatgptUrl(anchor.getAttribute('href')) ?? '');
45
+ if (!parsed || seen.has(parsed.conversationId)) continue;
46
+ seen.add(parsed.conversationId);
47
+ const title = core.normalizeText(anchor.innerText ?? anchor.textContent);
48
+ conversations.push({ conversationId: parsed.conversationId, canonicalUrl: parsed.canonicalUrl, ...(title ? { title: title.slice(0, 512) } : {}) });
49
+ }
50
+ return conversations;
51
+ };
52
+ const messageText = (node) => {
53
+ if (!node) return '';
54
+ const semanticContent = node.querySelector?.('[data-chatgpt-selection-message-id]');
55
+ return core.normalizeText(semanticContent?.innerText ?? semanticContent?.textContent ?? node.innerText ?? node.textContent);
56
+ };
57
+ const roleNodes = (selector) => {
58
+ const seen = new Set();
59
+ const result = [];
60
+ for (const node of conversationRoot().querySelectorAll(selector)) {
61
+ const semanticKey = String(node.getAttribute?.('data-chatgpt-search-unit-key') || node.getAttribute?.('data-content-search-unit-key') || '');
62
+ const messageIds = String(node.getAttribute?.('data-chatgpt-search-message-ids') || node.getAttribute?.('data-chatgpt-selection-message-id') || '');
63
+ if (semanticKey || messageIds) {
64
+ const key = `${semanticKey}|${messageIds}`;
65
+ if (seen.has(key)) continue;
66
+ seen.add(key);
67
+ }
68
+ result.push(node);
69
+ }
70
+ return result;
71
+ };
72
+ const latestTurnRole = () => {
73
+ const nodes = conversationRoot().querySelectorAll(`${USER}, ${ASSISTANT}`);
74
+ const node = nodes.item(nodes.length - 1);
75
+ const explicit = node?.getAttribute?.('data-message-author-role');
76
+ if (explicit === 'user' || explicit === 'assistant') return explicit;
77
+ const semanticKey = String(node?.getAttribute?.('data-chatgpt-search-unit-key') || node?.getAttribute?.('data-content-search-unit-key') || '');
78
+ if (semanticKey.endsWith(':user')) return 'user';
79
+ if (semanticKey.endsWith(':assistant')) return 'assistant';
80
+ return undefined;
81
+ };
82
+ /**
83
+ * Provider generation evidence. A visible stop/stream control is searched
84
+ * page-wide because missing it would allow a concurrent submission, but it
85
+ * must be *visible*: the previous query accepted hidden SSR controls, and a
86
+ * page-global `aria-busy` also fires for unrelated profile/route loading, so
87
+ * `aria-busy` is trusted only inside the current conversation turn.
88
+ */
89
+ const isGenerating = () => {
90
+ if (Array.from(document.querySelectorAll(`${STOP}, [data-is-streaming="true"]`)).some(visible)) return true;
91
+ const turns = conversationRoot().querySelectorAll(TURN);
92
+ const current = turns.length ? turns[turns.length - 1] : undefined;
93
+ if (current && Array.from(current.querySelectorAll('[aria-busy="true"]')).some(visible)) return true;
94
+ return latestTurnRole() === 'user';
95
+ };
96
+ /**
97
+ * Live progress of the running provider turn. The last *committed* assistant
98
+ * answer cannot change while a new turn runs, so liveness has to read the live
99
+ * turn surface. Without it every turn that outlasts the quiet window was
100
+ * misread as stalled and earned a duplicate provider prompt.
101
+ */
102
+ const providerActivityText = () => {
103
+ const turns = conversationRoot().querySelectorAll(TURN);
104
+ const current = turns.length ? turns[turns.length - 1] : undefined;
105
+ return core.normalizeText(current?.innerText ?? current?.textContent).slice(-PROVIDER_ACTIVITY_CHARS);
106
+ };
107
+ const providerFailureText = () => {
108
+ // The conversation-capacity banner is not always an ARIA alert.
109
+ // Read visible, short, non-message status nodes only; ordinary conversation
110
+ // history must never be interpreted as a current provider failure.
111
+ const status = Array.from(document.querySelectorAll('[role="alert"], [role="status"], [aria-live="assertive"], [aria-live="polite"]'))
112
+ .filter(visible);
113
+ const capacity = Array.from(conversationRoot().querySelectorAll('p, span, div'))
114
+ .filter((node) => visible(node) && !node.closest(TURN) && !node.closest('[data-message-author-role]'))
115
+ .filter((node) => {
116
+ const text = core.normalizeText(node.innerText ?? node.textContent);
117
+ return text.length <= 250 && /(?:你已达到此对话的长度上限|此对话已达到长度上限|you(?:'ve| have) reached the (?:maximum length for this conversation|conversation length limit)|this conversation has reached its maximum length)/i.test(text);
118
+ });
119
+ return [...status, ...capacity]
120
+ .map((node) => core.normalizeText(node.innerText ?? node.textContent))
121
+ .filter(Boolean).slice(-8).join('\n').slice(-PROVIDER_FAILURE_CHARS);
122
+ };
123
+ const composer = () => document.querySelector(COMPOSER);
124
+ const composerText = () => core.normalizeText(composer()?.value ?? composer()?.innerText ?? composer()?.textContent);
125
+ const pageSnapshot = (options = {}) => {
126
+ const userNodes = roleNodes(USER);
127
+ const assistantNodes = roleNodes(ASSISTANT);
128
+ const bodyText = String(document.body?.innerText ?? '');
129
+ return {
130
+ url: location.href,
131
+ title: document.title,
132
+ latestUserText: messageText(userNodes[userNodes.length - 1]),
133
+ latestAssistantResponse: messageText(assistantNodes[assistantNodes.length - 1]),
134
+ ...(options.includeUserHistory === true ? {
135
+ userMessages: userNodes.map(messageText).filter(Boolean),
136
+ assistantMessages: assistantNodes.map(messageText).filter(Boolean),
137
+ } : {}),
138
+ ...(composer() ? { composerText: composerText() } : {}),
139
+ providerActivityText: providerActivityText(),
140
+ providerFailureText: providerFailureText(),
141
+ ...(options.includePageText === true ? { pageText: bodyText.slice(-500000) } : {}),
142
+ latestTurnRole: latestTurnRole(),
143
+ isGenerating: isGenerating(),
144
+ };
145
+ };
146
+ const writeComposer = (node, prompt) => {
147
+ node.focus();
148
+ if (node instanceof HTMLTextAreaElement || node instanceof HTMLInputElement) {
149
+ const prototype = node instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
150
+ const setter = Object.getOwnPropertyDescriptor(prototype, 'value')?.set;
151
+ if (setter) setter.call(node, prompt); else node.value = prompt;
152
+ node.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'insertText', data: prompt }));
153
+ return;
154
+ }
155
+ if (node.isContentEditable) {
156
+ const selection = window.getSelection();
157
+ const range = document.createRange();
158
+ range.selectNodeContents(node);
159
+ selection?.removeAllRanges();
160
+ selection?.addRange(range);
161
+ if (!document.execCommand('insertText', false, prompt)) {
162
+ node.textContent = prompt;
163
+ node.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'insertText', data: prompt }));
164
+ }
165
+ selection?.removeAllRanges();
166
+ }
167
+ };
168
+ // Reasoning is a provider UI preference, not a Supervisor effect or workflow
169
+ // decision. Observe the concrete composer control and fail before inserting
170
+ // any prompt if the page does not acknowledge the requested level.
171
+ const reasoningLevel = (value) => {
172
+ const label = core.normalizeText(value).toLowerCase().replace(/[\s_-]+/g, '');
173
+ if (/extrahigh|xhigh|超高|极高/.test(label)) return 'xhigh';
174
+ if (/medium|中等/.test(label) || label === '中') return 'medium';
175
+ if (/high|高/.test(label)) return 'high';
176
+ return undefined;
177
+ };
178
+ const reasoningControl = () => {
179
+ const selectors = 'button[aria-haspopup="menu"], button[aria-haspopup="listbox"], [role="button"][aria-haspopup="menu"], button[data-testid*="model"], button[data-testid*="reasoning"]';
180
+ const candidates = Array.from(conversationRoot().querySelectorAll(selectors)).filter(visible);
181
+ return candidates.find((node) => {
182
+ const label = core.normalizeText((node.getAttribute?.('aria-label') ?? '') + ' ' + (node.innerText ?? node.textContent ?? ''));
183
+ const normalized = label.toLowerCase().replace(/[\s_-]+/g, '');
184
+ return /^gpt\d/.test(normalized) || normalized.includes('reasoning') || normalized.includes('thinking')
185
+ || normalized.includes('推理') || normalized.includes('思考') || reasoningLevel(label) !== undefined;
186
+ });
187
+ };
188
+ const reasoningControlLabel = (node) => core.normalizeText((node?.getAttribute?.('aria-label') ?? '') + ' ' + (node?.innerText ?? node?.textContent ?? ''));
189
+ const selectedReasoningOption = (level) => Array.from(document.querySelectorAll('[role="menuitemradio"], [role="option"], [role="radio"]'))
190
+ .filter(visible)
191
+ .find((node) => reasoningLevel(reasoningControlLabel(node)) === level
192
+ && (node.getAttribute('aria-checked') === 'true' || node.getAttribute('aria-selected') === 'true'));
193
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
194
+ const ensureReasoning = async (level) => {
195
+ if (level !== 'medium' && level !== 'high' && level !== 'xhigh') {
196
+ return { verified: false, reason: 'COMPUTER_CHATGPT_REASONING_INVALID' };
197
+ }
198
+ const control = reasoningControl();
199
+ if (!control) return { verified: false, reason: 'COMPUTER_CHATGPT_REASONING_CONTROL_UNAVAILABLE' };
200
+ if (reasoningLevel(reasoningControlLabel(control)) === level) return { verified: true, level };
201
+ control.click();
202
+ await sleep(80);
203
+ const menuOptions = Array.from(document.querySelectorAll('[role="menuitemradio"], [role="option"], [role="radio"]'))
204
+ .filter(visible)
205
+ .map((node) => ({ node, level: reasoningLevel(reasoningControlLabel(node)), disabled: node.hasAttribute('disabled') || node.getAttribute('aria-disabled') === 'true' }));
206
+ // xhigh means highest *available*, not a claim that every plan exposes
207
+ // Extra High. Prefer it, then High, then Medium; record the actual level.
208
+ const menuLevel = level === 'xhigh'
209
+ ? ['xhigh', 'high', 'medium'].find((candidate) => menuOptions.some((item) => item.level === candidate && !item.disabled))
210
+ : level;
211
+ const option = menuOptions.find((item) => item.level === menuLevel);
212
+ if (option) {
213
+ if (option.disabled) return { verified: false, reason: 'COMPUTER_CHATGPT_REASONING_OPTION_DISABLED' };
214
+ option.node.click();
215
+ await sleep(80);
216
+ if (reasoningLevel(reasoningControlLabel(reasoningControl())) === menuLevel || selectedReasoningOption(menuLevel)) {
217
+ return { verified: true, level: menuLevel };
218
+ }
219
+ return { verified: false, reason: 'COMPUTER_CHATGPT_REASONING_NOT_VERIFIED' };
220
+ }
221
+ // Older ChatGPT layouts expose a five-position slider in the model menu.
222
+ // React must acknowledge each navigation by changing aria-valuenow; writing
223
+ // our own attribute would be a false verification.
224
+ const sliders = Array.from(document.querySelectorAll('[role="slider"][aria-valuenow]')).filter(visible);
225
+ if (sliders.length !== 1) return { verified: false, reason: 'COMPUTER_CHATGPT_REASONING_OPTION_UNAVAILABLE' };
226
+ const slider = sliders[0];
227
+ const max = Number(slider.getAttribute('aria-valuemax'));
228
+ const min = Number(slider.getAttribute('aria-valuemin') ?? '0');
229
+ const target = level === 'xhigh' ? max : level === 'high' ? 3 : 2;
230
+ const actualLevel = target === 4 ? 'xhigh' : target === 3 ? 'high' : target === 2 ? 'medium' : undefined;
231
+ let current = Number(slider.getAttribute('aria-valuenow'));
232
+ if (![min, max, current, target].every(Number.isInteger) || min < 0 || max > 4 || max < 2
233
+ || current < min || current > max || target < min || target > max || !actualLevel) {
234
+ return { verified: false, reason: 'COMPUTER_CHATGPT_REASONING_STATE_UNAVAILABLE' };
235
+ }
236
+ for (let step = 0; step < Math.abs(target - current); step += 1) {
237
+ slider.focus?.();
238
+ slider.dispatchEvent(new KeyboardEvent('keydown', { key: target > current ? 'ArrowRight' : 'ArrowLeft', bubbles: true }));
239
+ await sleep(40);
240
+ const next = Number(slider.getAttribute('aria-valuenow'));
241
+ if (next !== current + (target > current ? 1 : -1)) {
242
+ return { verified: false, reason: 'COMPUTER_CHATGPT_REASONING_NOT_VERIFIED' };
243
+ }
244
+ current = next;
245
+ }
246
+ if (Number(slider.getAttribute('aria-valuenow')) !== target) {
247
+ return { verified: false, reason: 'COMPUTER_CHATGPT_REASONING_NOT_VERIFIED' };
248
+ }
249
+ const valueText = slider.getAttribute('aria-valuetext');
250
+ if (valueText && reasoningLevel(valueText) !== actualLevel) {
251
+ return { verified: false, reason: 'COMPUTER_CHATGPT_REASONING_NOT_VERIFIED' };
252
+ }
253
+ return { verified: true, level: actualLevel };
254
+ };
255
+ const dispatchPrompt = async (prompt, mode = 'send', reasoning, expectedConversationId, prepareOnly = false) => {
256
+ const exactConversationIsCurrent = () => !expectedConversationId
257
+ || core.parseConversation(location.href)?.conversationId === expectedConversationId;
258
+ if (!exactConversationIsCurrent()) return { dispatched: false, reason: 'target_identity_changed' };
259
+ if (typeof prompt !== 'string' || !prompt.trim()) return { dispatched: false, reason: 'prompt_required' };
260
+ if (mode === 'recover') {
261
+ const stop = document.querySelector(STOP);
262
+ if (prepareOnly && stop instanceof HTMLElement) return { prepared: false, reason: 'provider_recovery_stop_pending' };
263
+ if (stop instanceof HTMLElement) {
264
+ if (!exactConversationIsCurrent()) return { dispatched: false, reason: 'target_identity_changed' };
265
+ stop.click();
266
+ for (let attempt = 0; attempt < 20 && document.querySelector(STOP); attempt += 1) {
267
+ await new Promise((resolve) => setTimeout(resolve, 100));
268
+ if (!exactConversationIsCurrent()) return { dispatched: false, reason: 'target_identity_changed' };
269
+ }
270
+ if (document.querySelector(STOP)) return { dispatched: false, reason: 'provider_recovery_stop_unconfirmed' };
271
+ }
272
+ } else if (isGenerating()) return { dispatched: false, reason: 'provider_busy' };
273
+ const node = composer();
274
+ if (!node) return { dispatched: false, reason: 'composer_missing' };
275
+ const supervisor = /^@forge\s+<<<FORGE_WORKFLOW_EFFECT_V1:fx_[a-zA-Z0-9_-]+>>>/.test(prompt.trim());
276
+ const payload = supervisor ? prompt.trim().replace(/^@forge\s+/, '') : prompt;
277
+ const expected = core.normalizeText(payload);
278
+ const triggerDraft = `${payload}\n@`;
279
+ const triggerText = core.normalizeText(triggerDraft);
280
+ const boundText = core.normalizeText(`${payload} forge`);
281
+ const boundChip = () => {
282
+ const chips = Array.from(node.querySelectorAll('[plugin-mention-name], [app-mention-name]'));
283
+ return chips.length === 1
284
+ && chips[0]?.getAttribute('app-mention-name') === 'forge'
285
+ && chips[0]?.getAttribute('app-mention-path') === 'app://asdk_app_6ac09022b26081918f20ff868c773824'
286
+ && composerText() === boundText;
287
+ };
288
+ const existing = composerText();
289
+ if (existing && existing !== expected && !(supervisor && (existing === triggerText || boundChip()))) return { dispatched: false, reason: 'composer_not_empty' };
290
+ let reasoningVerified;
291
+ if (reasoning !== undefined) {
292
+ const checked = await ensureReasoning(reasoning);
293
+ if (!checked.verified) return { dispatched: false, reason: checked.reason };
294
+ reasoningVerified = checked.level;
295
+ }
296
+ if (!exactConversationIsCurrent()) return { dispatched: false, reason: 'target_identity_changed' };
297
+ if (supervisor && !boundChip()) writeComposer(node, triggerDraft);
298
+ else if (existing !== expected && !boundChip()) writeComposer(node, payload);
299
+ await new Promise((resolve) => setTimeout(resolve, 75));
300
+ if (!exactConversationIsCurrent()) return { dispatched: false, reason: 'target_identity_changed' };
301
+ if (supervisor) {
302
+ if (!boundChip()) {
303
+ if (composerText() !== triggerText) return { dispatched: false, reason: 'composer_write_unconfirmed' };
304
+ // The final standalone @ paragraph was inserted together with the
305
+ // payload; typing ` @` later drops the space in live ProseMirror.
306
+ node.focus();
307
+ const selection = window.getSelection();
308
+ if (!selection) return { dispatched: false, reason: 'COMPUTER_CHATGPT_PLUGIN_SELECTION_UNAVAILABLE' };
309
+ const range = document.createRange(); range.selectNodeContents(node); range.collapse(false);
310
+ selection.removeAllRanges(); selection.addRange(range);
311
+ if (!document.execCommand('insertText', false, 'forge')) return { dispatched: false, reason: 'COMPUTER_CHATGPT_PLUGIN_SELECTION_UNAVAILABLE' };
312
+ await sleep(150);
313
+ const entries = Array.from(document.querySelectorAll('[data-mention-section-items] > button'));
314
+ const selected = entries.filter((entry) => {
315
+ const label = core.normalizeText(entry.innerText ?? entry.textContent);
316
+ return label === 'forge' || label.startsWith('forge Current Forge 1.8.1');
317
+ });
318
+ if (selected.length !== 1) {
319
+ writeComposer(node, payload);
320
+ return { dispatched: false, reason: 'COMPUTER_CHATGPT_FORGE_PLUGIN_UNAVAILABLE' };
321
+ }
322
+ if (!exactConversationIsCurrent()) return { dispatched: false, reason: 'target_identity_changed' };
323
+ selected[0].click();
324
+ await sleep(150);
325
+ }
326
+ if (!boundChip()) return { dispatched: false, reason: 'COMPUTER_CHATGPT_FORGE_PLUGIN_CHIP_UNVERIFIED' };
327
+ } else if (composerText() !== expected) return { dispatched: false, reason: 'composer_write_unconfirmed' };
328
+ const send = document.querySelector(SEND);
329
+ if (!send) return { dispatched: false, reason: 'send_button_missing' };
330
+ if (send.disabled || send.getAttribute('aria-disabled') === 'true') return { dispatched: false, reason: 'send_button_disabled' };
331
+ if (!exactConversationIsCurrent()) return { dispatched: false, reason: 'target_identity_changed' };
332
+ if (prepareOnly) return { prepared: true };
333
+ send.click();
334
+ return { dispatched: true, ...(reasoningVerified ? { reasoningVerified } : {}) };
335
+ };
336
+ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
337
+ if (!message || message.type === 'forge-computer-chatgpt-scan') { notify(); sendResponse?.({ ok: true }); return false; }
338
+ if (message.type === 'forge-computer-chatgpt-discovery-scan') {
339
+ sendResponse({ projects: discoverProjectLinks(message.projectTitles), conversations: discoverConversationLinks(), pageUrl: location.href });
340
+ return false;
341
+ }
342
+ if (message.type === 'forge-computer-chatgpt-snapshot') { sendResponse(pageSnapshot(message.options ?? {})); return false; }
343
+ // Read-only exact-tab capability attestation. A stale content script must
344
+ // never receive an xhigh-required send that it would silently ignore.
345
+ if (message.type === 'forge-computer-chatgpt-capabilities') {
346
+ sendResponse({ reasoningPreflight: 'verified_before_send_v1' });
347
+ return false;
348
+ }
349
+ if (message.type === 'forge-computer-chatgpt-prepare') {
350
+ dispatchPrompt(String(message.prompt ?? ''), String(message.mode ?? 'send'), message.reasoning, message.expectedConversationId, true)
351
+ .then((result) => sendResponse(result?.prepared === true ? { prepared: true }
352
+ : { prepared: false, reason: String(result?.reason ?? 'COMPUTER_CHATGPT_PREPARE_REJECTED') }),
353
+ (error) => sendResponse({ prepared: false, reason: String(error?.message ?? error) }));
354
+ return true;
355
+ }
356
+ if (message.type === 'forge-computer-chatgpt-dispatch') {
357
+ dispatchPrompt(String(message.prompt ?? ''), String(message.mode ?? 'send'), message.reasoning, message.expectedConversationId)
358
+ .then(sendResponse, (error) => sendResponse({ dispatched: false, reason: String(error?.message ?? error) }));
359
+ return true;
360
+ }
361
+ return false;
362
+ });
363
+ let timer;
364
+ function notify() {
365
+ clearTimeout(timer);
366
+ timer = setTimeout(() => {
367
+ const current = core.parseConversation(location.href);
368
+ chrome.runtime.sendMessage({
369
+ type: 'forge-computer-chatgpt-page',
370
+ ...(current ?? {}),
371
+ pageUrl: location.href,
372
+ isGenerating: isGenerating(),
373
+ }, () => void chrome.runtime.lastError);
374
+ }, 200);
375
+ }
376
+ new MutationObserver(notify).observe(document.documentElement, { subtree: true, childList: true, characterData: true });
377
+ notify();
378
+ })();
@@ -0,0 +1,24 @@
1
+ (() => {
2
+ function normalizeText(value) { return String(value ?? '').replace(/\s+/g, ' ').trim(); }
3
+ function parseConversation(value) {
4
+ try {
5
+ const url = new URL(value);
6
+ if (url.protocol !== 'https:' || url.hostname !== 'chatgpt.com') return null;
7
+ const segments = url.pathname.split('/').filter(Boolean);
8
+ const marker = segments.lastIndexOf('c');
9
+ if (marker < 0 || marker + 2 !== segments.length) return null;
10
+ const conversationId = String(segments[marker + 1] ?? '').trim();
11
+ if (!conversationId || conversationId.length > 256) return null;
12
+ return { conversationId, canonicalUrl: `https://chatgpt.com/${segments.join('/')}` };
13
+ } catch { return null; }
14
+ }
15
+ function projectId(value) {
16
+ try {
17
+ const url = new URL(value);
18
+ if (url.protocol !== 'https:' || url.hostname !== 'chatgpt.com') return null;
19
+ return /^\/g\/(g-p-[a-z0-9]+)(?:-[^/]+)?\/(?:project\/?|c\/[^/]+\/?)$/i.exec(url.pathname)?.[1]?.toLowerCase() ?? null;
20
+ } catch { return null; }
21
+ }
22
+ function sameConversation(a, b) { return Boolean(a && b && a.conversationId === b.conversationId); }
23
+ globalThis.ForgeComputerChatgptCore = Object.freeze({ normalizeText, parseConversation, projectId, sameConversation });
24
+ })();
@@ -0,0 +1,30 @@
1
+ {
2
+ "manifest_version": 3,
3
+ "name": "Forge Computer ChatGPT Provider",
4
+ "version": "0.3.1",
5
+ "description": "Computer-owned stable ChatGPT target provider for Forge Runtime.",
6
+ "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxFzo1eixjsWsZbN1pBuyzdKinJSAAuzTRavD0xFQFwrTIEQ7hxxueEBEhifpGq9nplNnmxmZvIL7PJycEAYT8mrbyXBLCPR1jQBuL4YR775phnlNVpF3dHX5OWDHLWRnHRgOO1FibQ54fM2rKylr66+x+J6/4C7a9dpiSMuxf3fOStXA6wJb0d7A4E22Q1+GGfWgs0NCyVI5k4aczK+J5Ao61ZXKBr8Qw/FCmwhCcDgQdIpURgoMHkyvQH3ryYWocucjRhMVsU8H65adIIKFHkEhPJCiVY64L6bu6kNR2fpf0yJ1GvI5ota6Hf4NAEi7Yt7PL7i3ISyv3pPQWW1nIwIDAQAB",
7
+ "permissions": [
8
+ "nativeMessaging",
9
+ "tabs",
10
+ "alarms"
11
+ ],
12
+ "host_permissions": [
13
+ "https://chatgpt.com/*"
14
+ ],
15
+ "background": {
16
+ "service_worker": "background.js"
17
+ },
18
+ "content_scripts": [
19
+ {
20
+ "matches": [
21
+ "https://chatgpt.com/*"
22
+ ],
23
+ "js": [
24
+ "core.js",
25
+ "content.js"
26
+ ],
27
+ "run_at": "document_idle"
28
+ }
29
+ ]
30
+ }
@@ -20,12 +20,11 @@ import {
20
20
  } from './desktop-operator-contract';
21
21
 
22
22
  export const DESKTOP_OPERATOR_MAX_RESPONSE_BYTES = 4 * 1_048_576;
23
- const LEGACY_REGISTRATION_CAPABILITIES = ['desktop.observe', 'desktop.interact', 'desktop.capture'] as const;
24
23
  let testSocketPath: string | undefined;
25
24
 
26
25
  export interface DesktopOperatorComputerEndpoint {
27
26
  socketPath: string;
28
- source: 'registration' | 'legacy_fallback' | 'test_override';
27
+ source: 'registration' | 'test_override';
29
28
  healthTimeoutMs: number;
30
29
  actionTimeoutMs: number;
31
30
  maxResponseBytes: number;
@@ -33,11 +32,8 @@ export interface DesktopOperatorComputerEndpoint {
33
32
  capabilityIds: ComputerRuntimeProviderCapabilityId[];
34
33
  }
35
34
 
36
- export type DesktopOperatorLegacyFallbackMode = 'disabled' | 'unregistered_v0_2';
37
-
38
35
  export interface DesktopOperatorComputerProviderOptions {
39
36
  lookupRegistration?: ComputerProviderRegistrationLookup;
40
- legacyFallback?: DesktopOperatorLegacyFallbackMode;
41
37
  }
42
38
 
43
39
  export function desktopOperatorComputerSocketPath(accountHome = process.env.HOME?.trim() || homedir()): string {
@@ -95,16 +91,14 @@ function declaredComputerCapabilities(
95
91
  COMPUTER_ELEMENT_OBSERVE_CAPABILITY,
96
92
  COMPUTER_ELEMENT_ACTION_CAPABILITY,
97
93
  ].filter((capability): capability is ComputerRuntimeProviderCapabilityId => capabilityIds.has(capability));
98
- const legacyRegistrationCompatible = LEGACY_REGISTRATION_CAPABILITIES.every((capability) => capabilityIds.has(capability));
99
- if (recognized.length === 0 && !legacyRegistrationCompatible) {
94
+ if (recognized.length === 0) {
100
95
  throw new ComputerProviderError(
101
96
  'PLUGIN_COMPUTER_PROVIDER_CAPABILITY_UNDECLARED',
102
- 'Forge Desktop Operator registration does not declare a supported Computer capability or the bounded legacy Desktop capability set required for compatibility.',
97
+ 'Forge Desktop Operator registration does not declare a supported Unified Computer capability.',
103
98
  {
104
99
  retryable: false,
105
100
  details: {
106
101
  supportedComputerCapabilities: [COMPUTER_OBSERVE_CAPABILITY, COMPUTER_INPUT_CAPABILITY, COMPUTER_CONSOLE_UNLOCK_CAPABILITY, COMPUTER_CAPTURE_CAPABILITY, COMPUTER_ELEMENT_OBSERVE_CAPABILITY, COMPUTER_ELEMENT_ACTION_CAPABILITY],
107
- legacyRequiredCapabilities: [...LEGACY_REGISTRATION_CAPABILITIES],
108
102
  registrationRevision: registration.revision,
109
103
  },
110
104
  },
@@ -161,27 +155,14 @@ export function resolveDesktopOperatorComputerEndpoint(
161
155
  const registered = registeredEndpoint(options.lookupRegistration);
162
156
  if (registered) return registered;
163
157
  }
164
- if (options.legacyFallback !== 'unregistered_v0_2') {
165
- throw new ComputerProviderError(
166
- 'PLUGIN_COMPUTER_PROVIDER_REGISTRATION_REQUIRED',
167
- 'Computer provider registration is required unless the Runtime composition explicitly enables the bounded Desktop Operator 0.2.x compatibility fallback.',
168
- {
169
- retryable: false,
170
- details: {
171
- providerPluginId: DESKTOP_OPERATOR_PROVIDER_PLUGIN_ID,
172
- legacyFallback: options.legacyFallback ?? 'disabled',
173
- },
174
- },
175
- );
176
- }
177
- return {
178
- socketPath: desktopOperatorComputerSocketPath(),
179
- source: 'legacy_fallback',
180
- healthTimeoutMs: 2_000,
181
- actionTimeoutMs: 30_000,
182
- maxResponseBytes: DESKTOP_OPERATOR_MAX_RESPONSE_BYTES,
183
- capabilityIds: [],
184
- };
158
+ throw new ComputerProviderError(
159
+ 'PLUGIN_COMPUTER_PROVIDER_REGISTRATION_REQUIRED',
160
+ 'Computer provider registration is required before Forge can use the Desktop Operator.',
161
+ {
162
+ retryable: false,
163
+ details: { providerPluginId: DESKTOP_OPERATOR_PROVIDER_PLUGIN_ID },
164
+ },
165
+ );
185
166
  }
186
167
 
187
168
  export function desktopOperatorComputerProviderCapabilities(
@@ -192,7 +173,6 @@ export function desktopOperatorComputerProviderCapabilities(
192
173
  const registration = readRegisteredProvider(options.lookupRegistration);
193
174
  if (registration) return declaredComputerCapabilities(registration);
194
175
  }
195
- if (options.legacyFallback === 'unregistered_v0_2') return [];
196
176
  throw new ComputerProviderError(
197
177
  'PLUGIN_COMPUTER_PROVIDER_REGISTRATION_REQUIRED',
198
178
  'Computer provider registration is required before capabilities can be declared.',