@abot-ai/runtime 1.7.0 → 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 (443) hide show
  1. package/dist/src/capabilities/tool-request-resources.d.ts +3 -0
  2. package/dist/src/cli/abot.js +2 -0
  3. package/dist/src/cli/host-companion-bundle.mjs +751 -333
  4. package/dist/src/computer-access/collection-consent.d.ts +9 -0
  5. package/dist/src/computer-access/collection-consent.js +47 -0
  6. package/dist/src/computer-access/command-output-capture.d.ts +17 -6
  7. package/dist/src/computer-access/command-output-capture.js +134 -68
  8. package/dist/src/computer-access/command-output-protection.d.ts +17 -0
  9. package/dist/src/computer-access/command-output-protection.js +59 -0
  10. package/dist/src/computer-access/companion/command-output.d.ts +1 -0
  11. package/dist/src/computer-access/companion/command-output.js +23 -6
  12. package/dist/src/computer-access/companion/install-link-macos.js +2 -1
  13. package/dist/src/computer-access/companion/native-notifications.js +3 -2
  14. package/dist/src/computer-access/companion/native-session.js +6 -2
  15. package/dist/src/computer-access/companion/observation-filter.js +2 -26
  16. package/dist/src/computer-access/companion/observation-process.d.ts +2 -0
  17. package/dist/src/computer-access/companion/observation-process.js +51 -25
  18. package/dist/src/computer-access/companion/observation-redaction.d.ts +2 -7
  19. package/dist/src/computer-access/companion/observation-redaction.js +2 -111
  20. package/dist/src/computer-access/companion/secret-protection-protocol.d.ts +6 -0
  21. package/dist/src/computer-access/companion/secret-protection-protocol.js +6 -0
  22. package/dist/src/computer-access/computer/companion-sessions.js +7 -6
  23. package/dist/src/computer-access/computer/unix-native-process.js +23 -11
  24. package/dist/src/computer-access/handlers.d.ts +2 -1
  25. package/dist/src/computer-access/handlers.js +79 -11
  26. package/dist/src/computer-access/host-observation.d.ts +3 -3
  27. package/dist/src/computer-access/native-observation-connection.d.ts +12 -0
  28. package/dist/src/computer-access/native-observation-connection.js +78 -0
  29. package/dist/src/computer-access/native-observation-ownership.d.ts +6 -0
  30. package/dist/src/computer-access/native-observation-ownership.js +55 -0
  31. package/dist/src/computer-access/native-observation-shutdown.d.ts +7 -0
  32. package/dist/src/computer-access/native-observation-shutdown.js +58 -0
  33. package/dist/src/computer-access/observation-source.d.ts +6 -0
  34. package/dist/src/computer-access/observation-source.js +10 -0
  35. package/dist/src/computer-access/security/desktop-result.d.ts +8 -0
  36. package/dist/src/computer-access/security/desktop-result.js +146 -0
  37. package/dist/src/computer-access/security/observed-error.d.ts +2 -0
  38. package/dist/src/computer-access/security/observed-error.js +10 -0
  39. package/dist/src/computer-access/security/secret-text.d.ts +7 -0
  40. package/dist/src/computer-access/security/secret-text.js +111 -0
  41. package/dist/src/computer-access/security/system-results.d.ts +2 -0
  42. package/dist/src/computer-access/security/system-results.js +53 -0
  43. package/dist/src/computer-access/system-result-protection.d.ts +11 -0
  44. package/dist/src/computer-access/system-result-protection.js +1 -0
  45. package/dist/src/model-gateway/observability/provider-response-capture.d.ts +60 -0
  46. package/dist/src/model-gateway/observability/provider-response-capture.js +68 -0
  47. package/dist/src/model-gateway/observability/provider-response-prefix.d.ts +7 -0
  48. package/dist/src/model-gateway/observability/provider-response-prefix.js +14 -0
  49. package/dist/src/model-gateway/observability/provider-response-tail.d.ts +8 -0
  50. package/dist/src/model-gateway/observability/provider-response-tail.js +28 -0
  51. package/dist/src/model-gateway/observability/provider-sse-diagnostics.d.ts +30 -0
  52. package/dist/src/model-gateway/observability/provider-sse-diagnostics.js +119 -0
  53. package/dist/src/model-gateway/observability/provider-trace.js +30 -8
  54. package/dist/src/model-gateway/providers/ollama/adapter.js +8 -2
  55. package/dist/src/model-gateway/providers/ollama/stream-normalizer.js +70 -50
  56. package/dist/src/model-gateway/providers/ollama/stream-termination.d.ts +6 -0
  57. package/dist/src/model-gateway/providers/ollama/stream-termination.js +20 -0
  58. package/dist/src/model-gateway/providers/openai/adapter.js +9 -7
  59. package/dist/src/model-gateway/providers/openai/diagnostics.d.ts +0 -1
  60. package/dist/src/model-gateway/providers/openai/diagnostics.js +0 -9
  61. package/dist/src/model-gateway/providers/openai/function-output.d.ts +11 -0
  62. package/dist/src/model-gateway/providers/openai/function-output.js +37 -0
  63. package/dist/src/model-gateway/providers/openai/function-result.d.ts +7 -0
  64. package/dist/src/model-gateway/providers/openai/function-result.js +35 -0
  65. package/dist/src/model-gateway/providers/openai/message-output-policy.d.ts +3 -0
  66. package/dist/src/model-gateway/providers/openai/message-output-policy.js +16 -0
  67. package/dist/src/model-gateway/providers/openai/payload.d.ts +0 -2
  68. package/dist/src/model-gateway/providers/openai/payload.js +6 -23
  69. package/dist/src/model-gateway/providers/openai/response-lifetime.d.ts +2 -0
  70. package/dist/src/model-gateway/providers/openai/response-lifetime.js +64 -0
  71. package/dist/src/model-gateway/providers/openai/sse-data.d.ts +9 -0
  72. package/dist/src/model-gateway/providers/openai/sse-data.js +67 -0
  73. package/dist/src/model-gateway/providers/openai/stream-normalizer.d.ts +10 -22
  74. package/dist/src/model-gateway/providers/openai/stream-normalizer.js +78 -79
  75. package/dist/src/model-gateway/providers/openai/stream.js +13 -41
  76. package/dist/src/model-gateway/providers/openai/structured-message-output.d.ts +42 -0
  77. package/dist/src/model-gateway/providers/openai/structured-message-output.js +175 -0
  78. package/dist/src/model-gateway/server.js +5 -1
  79. package/dist/src/plugin-contract/index.d.ts +1 -0
  80. package/dist/src/plugin-contract/index.js +1 -0
  81. package/dist/src/plugin-contract/manifest.d.ts +2 -0
  82. package/dist/src/plugin-contract/manifest.js +1 -0
  83. package/dist/src/plugin-contract/platform-compatibility.d.ts +16 -0
  84. package/dist/src/plugin-contract/platform-compatibility.js +3 -0
  85. package/dist/src/plugin-sdk/computer-access.d.ts +4 -0
  86. package/dist/src/plugin-sdk/computer-access.js +1 -0
  87. package/dist/src/plugin-sdk/files-windows/process.d.ts +3 -0
  88. package/dist/src/plugin-sdk/files-windows/process.js +93 -0
  89. package/dist/src/plugin-sdk/files-windows/read-script.d.ts +1 -0
  90. package/dist/src/plugin-sdk/files-windows/read-script.js +43 -0
  91. package/dist/src/plugin-sdk/files-windows/read.d.ts +6 -0
  92. package/dist/src/plugin-sdk/files-windows/read.js +56 -0
  93. package/dist/src/plugin-sdk/files-windows/result.d.ts +4 -0
  94. package/dist/src/plugin-sdk/files-windows/result.js +67 -0
  95. package/dist/src/plugin-sdk/files.js +4 -0
  96. package/dist/src/plugin-sdk/index.d.ts +1 -0
  97. package/dist/src/plugin-sdk/index.js +1 -0
  98. package/dist/src/plugin-sdk/mutation-result.d.ts +7 -0
  99. package/dist/src/plugin-sdk/mutation-result.js +11 -0
  100. package/dist/src/runtime/adapters/long-term-memory/file-lock/acquisition.js +20 -3
  101. package/dist/src/runtime/adapters/long-term-memory/file-lock/owner-record.js +3 -1
  102. package/dist/src/runtime/adapters/long-term-memory/file-lock/path-observation.d.ts +3 -0
  103. package/dist/src/runtime/adapters/long-term-memory/file-lock/path-observation.js +20 -0
  104. package/dist/src/runtime/adapters/long-term-memory/file-lock/snapshot.js +7 -3
  105. package/dist/src/runtime/adapters/passive-learning-runtime.d.ts +1 -1
  106. package/dist/src/runtime/adapters/passive-learning-runtime.js +3 -3
  107. package/dist/src/runtime/adapters/runtime-observation-connection.d.ts +5 -0
  108. package/dist/src/runtime/adapters/runtime-observation-connection.js +13 -0
  109. package/dist/src/runtime/local-host/windows-private-access.js +2 -0
  110. package/dist/src/runtime/passive-learning/application-catalog.js +3 -1
  111. package/dist/src/runtime/passive-learning/collection-source.js +7 -0
  112. package/dist/src/runtime/passive-learning/service.js +2 -3
  113. package/dist/src/runtime/passive-learning/status-projection.d.ts +2 -0
  114. package/dist/src/runtime/passive-learning/status-projection.js +9 -0
  115. package/dist/src/runtime/plugins/installation/package.d.ts +8 -0
  116. package/dist/src/runtime/plugins/installation/package.js +2 -0
  117. package/dist/src/runtime/plugins/installation/service.d.ts +7 -0
  118. package/dist/src/runtime/plugins/loader.js +24 -14
  119. package/dist/src/runtime/plugins/manifest-platform-compatibility.d.ts +2 -0
  120. package/dist/src/runtime/plugins/manifest-platform-compatibility.js +39 -0
  121. package/dist/src/runtime/plugins/manifest-validator.js +9 -1
  122. package/dist/src/runtime/plugins/platform-compatibility.d.ts +4 -0
  123. package/dist/src/runtime/plugins/platform-compatibility.js +44 -0
  124. package/dist/src/runtime/request/approval-wait/activation-events.js +19 -7
  125. package/dist/src/runtime/request/approval-wait/execution-compaction-restore.d.ts +20 -0
  126. package/dist/src/runtime/request/approval-wait/execution-compaction-restore.js +118 -0
  127. package/dist/src/runtime/request/approval-wait/super-compaction-restore.js +2 -1
  128. package/dist/src/runtime/request/prepared-execution.js +3 -0
  129. package/dist/src/runtime/steps/execution-agent/capability-result-context.d.ts +6 -0
  130. package/dist/src/runtime/steps/execution-agent/capability-result-context.js +29 -0
  131. package/dist/src/runtime/steps/execution-agent/format.js +2 -3
  132. package/dist/src/runtime/steps/execution-agent/input.js +1 -1
  133. package/dist/src/runtime/steps/execution-agent/prompt.js +5 -5
  134. package/dist/src/runtime/steps/execution-agent/response-prompt.js +1 -0
  135. package/dist/src/runtime/steps/execution-agent/state-context.d.ts +2 -3
  136. package/dist/src/runtime/steps/execution-agent/state-context.js +26 -35
  137. package/dist/src/runtime/steps/execution-agent/work-plan-contract.d.ts +1 -3
  138. package/dist/src/runtime/steps/execution-agent/work-plan-contract.js +0 -55
  139. package/dist/src/runtime/steps/execution-agent/work-plan-schema.d.ts +3 -0
  140. package/dist/src/runtime/steps/execution-agent/work-plan-schema.js +61 -0
  141. package/dist/src/sessions/durable-session-commit.js +3 -3
  142. package/dist/src/sessions/prepared-session-replacement.d.ts +6 -0
  143. package/dist/src/sessions/prepared-session-replacement.js +46 -0
  144. package/dist/src/sessions/session-store.js +3 -3
  145. package/dist/src/shared/passive-observation-self-exclusion.d.ts +5 -0
  146. package/dist/src/shared/passive-observation-self-exclusion.js +37 -0
  147. package/dist/src/shared/windows-file-io/authority-script.d.ts +1 -0
  148. package/dist/src/shared/windows-file-io/authority-script.js +94 -0
  149. package/dist/src/shared/windows-file-io/native-script.d.ts +2 -0
  150. package/dist/src/shared/windows-file-io/native-script.js +120 -0
  151. package/dist/src/shared/windows-file-io/read-bytes-script.d.ts +1 -0
  152. package/dist/src/shared/windows-file-io/read-bytes-script.js +18 -0
  153. package/dist/src/shared/windows-job-object.d.ts +2 -0
  154. package/dist/src/shared/windows-job-object.js +66 -0
  155. package/dist/src/web-ui/app/app-bootstrap.js +14 -1
  156. package/dist/src/web-ui/app/app-state.js +0 -7
  157. package/dist/src/web-ui/app/app.js +53 -156
  158. package/dist/src/web-ui/app/components/automations/node-inspector.js +3 -2
  159. package/dist/src/web-ui/app/components/automations/step-editor-dialog.js +3 -0
  160. package/dist/src/web-ui/app/components/composer-submission-notice.js +50 -0
  161. package/dist/src/web-ui/app/components/config-workspace/model-plugin-permissions.js +7 -1
  162. package/dist/src/web-ui/app/components/config-workspace/workspace-mutations.js +22 -2
  163. package/dist/src/web-ui/app/components/home-guidance/daily-review.js +2 -2
  164. package/dist/src/web-ui/app/components/home-guidance/home-guidance.js +20 -6
  165. package/dist/src/web-ui/app/components/model-setup/context-window-feedback.js +53 -0
  166. package/dist/src/web-ui/app/components/model-setup/save-flow.js +3 -1
  167. package/dist/src/web-ui/app/components/model-setup/save-outcome.js +1 -0
  168. package/dist/src/web-ui/app/components/model-setup/wizard.js +12 -0
  169. package/dist/src/web-ui/app/components/passive-learning/activity-controls.js +4 -0
  170. package/dist/src/web-ui/app/components/passive-learning/collection-access.js +35 -0
  171. package/dist/src/web-ui/app/components/passive-learning/collection-consent-dialog.js +59 -0
  172. package/dist/src/web-ui/app/components/passive-learning/collection-consent-gate.js +94 -0
  173. package/dist/src/web-ui/app/components/passive-learning/computer-update-notice.js +6 -0
  174. package/dist/src/web-ui/app/components/passive-learning/failure-copy.js +1 -0
  175. package/dist/src/web-ui/app/components/passive-learning/home.js +7 -2
  176. package/dist/src/web-ui/app/components/passive-learning/macos-collection-restart-notice.js +1 -0
  177. package/dist/src/web-ui/app/components/passive-learning/memory.js +2 -4
  178. package/dist/src/web-ui/app/components/passive-learning/workspace-view.js +2 -2
  179. package/dist/src/web-ui/app/components/plugins/compatibility.js +13 -0
  180. package/dist/src/web-ui/app/components/plugins/discovery-rendering.js +9 -1
  181. package/dist/src/web-ui/app/components/plugins/installation-compatibility.js +7 -0
  182. package/dist/src/web-ui/app/components/plugins/installation.js +2 -1
  183. package/dist/src/web-ui/app/components/plugins/rendering.js +3 -0
  184. package/dist/src/web-ui/app/components/reasoning-override-prompt.js +82 -0
  185. package/dist/src/web-ui/app/components/runtime-config-activation.js +22 -8
  186. package/dist/src/web-ui/app/components/runtime-setup/optional-steps.js +7 -4
  187. package/dist/src/web-ui/app/components/runtime-setup/plugins.js +3 -1
  188. package/dist/src/web-ui/app/components/runtime-setup/rendering.js +6 -4
  189. package/dist/src/web-ui/app/components/runtime-setup-guide.d.ts +1 -0
  190. package/dist/src/web-ui/app/components/schedules/form.js +10 -8
  191. package/dist/src/web-ui/app/components/schedules/workspace.js +23 -4
  192. package/dist/src/web-ui/app/components/session-sidebar-sections.js +2 -2
  193. package/dist/src/web-ui/app/components/spark-chat/handoff-actions.js +9 -3
  194. package/dist/src/web-ui/app/components/spark-chat/placement.js +4 -7
  195. package/dist/src/web-ui/app/components/spark-chat/settings.js +7 -3
  196. package/dist/src/web-ui/app/components/system-host/macos-permissions.js +2 -0
  197. package/dist/src/web-ui/app/components/system-host/native-windows-access.js +50 -0
  198. package/dist/src/web-ui/app/components/system-host/rendering.js +3 -0
  199. package/dist/src/web-ui/app/components/workspace-storage-notice.js +37 -0
  200. package/dist/src/web-ui/app/configuration-environment-refresh.js +27 -34
  201. package/dist/src/web-ui/app/configuration-feature.js +9 -1
  202. package/dist/src/web-ui/app/controllers/app-event-bindings.js +38 -105
  203. package/dist/src/web-ui/app/controllers/chat-request-controller.d.ts +28 -0
  204. package/dist/src/web-ui/app/controllers/chat-request-controller.js +34 -66
  205. package/dist/src/web-ui/app/controllers/composer-attachments-controller.d.ts +15 -40
  206. package/dist/src/web-ui/app/controllers/composer-attachments-controller.js +26 -69
  207. package/dist/src/web-ui/app/controllers/composer-draft-view.d.ts +27 -0
  208. package/dist/src/web-ui/app/controllers/composer-draft-view.js +48 -0
  209. package/dist/src/web-ui/app/controllers/composer-drafts.d.ts +55 -0
  210. package/dist/src/web-ui/app/controllers/composer-drafts.js +120 -0
  211. package/dist/src/web-ui/app/controllers/composer-feature.d.ts +65 -0
  212. package/dist/src/web-ui/app/controllers/composer-feature.js +124 -0
  213. package/dist/src/web-ui/app/controllers/composer-queue-controller.d.ts +33 -94
  214. package/dist/src/web-ui/app/controllers/composer-queue-controller.js +185 -251
  215. package/dist/src/web-ui/app/controllers/composer-submission-lifecycle.d.ts +48 -0
  216. package/dist/src/web-ui/app/controllers/composer-submission-lifecycle.js +97 -0
  217. package/dist/src/web-ui/app/controllers/composer-submit-controller.d.ts +30 -61
  218. package/dist/src/web-ui/app/controllers/composer-submit-controller.js +56 -138
  219. package/dist/src/web-ui/app/controllers/composer-surface-controller.js +6 -0
  220. package/dist/src/web-ui/app/controllers/composer-workspace-controller.d.ts +22 -40
  221. package/dist/src/web-ui/app/controllers/composer-workspace-controller.js +49 -165
  222. package/dist/src/web-ui/app/controllers/conversation-navigation-intent.js +15 -0
  223. package/dist/src/web-ui/app/controllers/conversation-request-hydration.js +20 -17
  224. package/dist/src/web-ui/app/controllers/conversation-session-controller.d.ts +1 -2
  225. package/dist/src/web-ui/app/controllers/conversation-session-controller.js +49 -22
  226. package/dist/src/web-ui/app/controllers/conversation-workspace-activation.js +27 -0
  227. package/dist/src/web-ui/app/controllers/daily-memory-review.js +15 -16
  228. package/dist/src/web-ui/app/controllers/environment-transition.js +126 -0
  229. package/dist/src/web-ui/app/controllers/environment-workspace-preparation.js +18 -0
  230. package/dist/src/web-ui/app/controllers/home-composer-feature.d.ts +14 -36
  231. package/dist/src/web-ui/app/controllers/home-composer-feature.js +17 -114
  232. package/dist/src/web-ui/app/controllers/home-conversation-activation.js +6 -8
  233. package/dist/src/web-ui/app/controllers/passive-learning-controller.js +56 -0
  234. package/dist/src/web-ui/app/controllers/projects-controller.d.ts +1 -1
  235. package/dist/src/web-ui/app/controllers/projects-controller.js +6 -1
  236. package/dist/src/web-ui/app/controllers/reasoning-mode-controller.js +174 -0
  237. package/dist/src/web-ui/app/controllers/runtime-selection-controller.d.ts +7 -0
  238. package/dist/src/web-ui/app/controllers/runtime-selection-controller.js +20 -155
  239. package/dist/src/web-ui/app/controllers/session-controller.js +33 -17
  240. package/dist/src/web-ui/app/controllers/session-pin-updates.js +14 -0
  241. package/dist/src/web-ui/app/controllers/session-sidebar-controller.js +12 -14
  242. package/dist/src/web-ui/app/controllers/spark-chat-sync.js +2 -2
  243. package/dist/src/web-ui/app/controllers/steer-controller.js +9 -7
  244. package/dist/src/web-ui/app/controllers/tool-permission-mode-controller.js +1 -1
  245. package/dist/src/web-ui/app/controllers/workspace-conversation-opener.js +34 -0
  246. package/dist/src/web-ui/app/dashboard-feature.js +3 -2
  247. package/dist/src/web-ui/app/lib/reasoning-controls.js +35 -0
  248. package/dist/src/web-ui/app/lib/session-composer-queue-ownership.js +58 -0
  249. package/dist/src/web-ui/app/lib/session-composer-queue.d.ts +12 -0
  250. package/dist/src/web-ui/app/lib/session-composer-queue.js +25 -6
  251. package/dist/src/web-ui/app/passive-learning-feature.js +16 -3
  252. package/dist/src/web-ui/app/schedules-feature.js +5 -3
  253. package/dist/src/web-ui/app/services/client-preferences.d.ts +18 -10
  254. package/dist/src/web-ui/app/services/client-preferences.js +25 -16
  255. package/dist/src/web-ui/app/services/home-guidance-preferences.js +13 -13
  256. package/dist/src/web-ui/app/services/reasoning-override.js +12 -0
  257. package/dist/src/web-ui/app/services/runtime-web-client/automations.js +10 -2
  258. package/dist/src/web-ui/app/services/runtime-web-client/memory.js +7 -2
  259. package/dist/src/web-ui/app/services/runtime-web-client/system-host.js +2 -0
  260. package/dist/src/web-ui/app/services/runtime-web-client.d.ts +2 -0
  261. package/dist/src/web-ui/app/services/runtime-web-client.js +2 -0
  262. package/dist/src/web-ui/app/services/server-composer-queue.js +32 -0
  263. package/dist/src/web-ui/app/services/session-sidebar-preferences.js +5 -5
  264. package/dist/src/web-ui/app/services/workspace-state-storage.js +116 -0
  265. package/dist/src/web-ui/app/services/workspace-state.js +27 -0
  266. package/dist/src/web-ui/app/spark-chat-conversation.js +34 -45
  267. package/dist/src/web-ui/app/spark-chat-feature.js +10 -4
  268. package/dist/src/web-ui/app/styles/21-composer-controls.css +16 -0
  269. package/dist/src/web-ui/app/styles/41-plugin-management.css +8 -0
  270. package/dist/src/web-ui/app/styles/42-model-plugin-permissions.css +1 -0
  271. package/dist/src/web-ui/app/styles/49-collection-consent.css +30 -0
  272. package/dist/src/web-ui/app/styles/64-workspace-storage.css +23 -0
  273. package/dist/src/web-ui/app/styles.css +2 -0
  274. package/dist/src/web-ui/client-state/contracts.d.ts +15 -0
  275. package/dist/src/web-ui/client-state/contracts.js +13 -0
  276. package/dist/src/web-ui/client-state/preference-shapes.d.ts +2 -0
  277. package/dist/src/web-ui/client-state/preference-shapes.js +80 -0
  278. package/dist/src/web-ui/client-state/preferences.d.ts +3 -0
  279. package/dist/src/web-ui/client-state/preferences.js +84 -0
  280. package/dist/src/web-ui/client-state/queue.d.ts +3 -0
  281. package/dist/src/web-ui/client-state/queue.js +43 -0
  282. package/dist/src/web-ui/client-state/routes.d.ts +7 -0
  283. package/dist/src/web-ui/client-state/routes.js +58 -0
  284. package/dist/src/web-ui/client-state/store.d.ts +14 -0
  285. package/dist/src/web-ui/client-state/store.js +88 -0
  286. package/dist/src/web-ui/local-runtime/configuration-activation-source.js +2 -0
  287. package/dist/src/web-ui/local-runtime/http.js +11 -2
  288. package/dist/src/web-ui/local-runtime/model-context-capacity-error.d.ts +14 -0
  289. package/dist/src/web-ui/local-runtime/model-context-capacity-error.js +28 -0
  290. package/dist/src/web-ui/local-runtime/model-setup-context-window.d.ts +15 -0
  291. package/dist/src/web-ui/local-runtime/model-setup-context-window.js +25 -0
  292. package/dist/src/web-ui/local-runtime/model-setup-routes.js +2 -0
  293. package/dist/src/web-ui/local-runtime/model-setup-service.js +5 -2
  294. package/dist/src/web-ui/local-runtime/model-setup-validation.d.ts +1 -0
  295. package/dist/src/web-ui/local-runtime/model-setup-validation.js +14 -7
  296. package/dist/src/web-ui/local-runtime/request-body-error.d.ts +11 -0
  297. package/dist/src/web-ui/local-runtime/request-body-error.js +14 -0
  298. package/dist/src/web-ui/local-runtime/request-control-observation.js +2 -2
  299. package/dist/src/web-ui/local-runtime/request-execution.js +18 -18
  300. package/dist/src/web-ui/local-runtime/runtime-setup-connection-edit.d.ts +2 -0
  301. package/dist/src/web-ui/local-runtime/runtime-setup-connection-edit.js +35 -22
  302. package/dist/src/web-ui/local-runtime/runtime-setup-context-window.d.ts +2 -9
  303. package/dist/src/web-ui/local-runtime/runtime-setup-context-window.js +4 -27
  304. package/dist/src/web-ui/local-runtime/runtime-setup-credentials.d.ts +15 -1
  305. package/dist/src/web-ui/local-runtime/runtime-setup-credentials.js +30 -11
  306. package/dist/src/web-ui/local-runtime/runtime-setup-edit-files.d.ts +20 -0
  307. package/dist/src/web-ui/local-runtime/runtime-setup-edit-files.js +104 -0
  308. package/dist/src/web-ui/local-runtime/runtime-setup-edit-journal.d.ts +29 -0
  309. package/dist/src/web-ui/local-runtime/runtime-setup-edit-journal.js +151 -0
  310. package/dist/src/web-ui/local-runtime/runtime-setup-edit-recovery.d.ts +7 -0
  311. package/dist/src/web-ui/local-runtime/runtime-setup-edit-recovery.js +87 -0
  312. package/dist/src/web-ui/local-runtime/runtime-setup-edit-transaction.d.ts +3 -0
  313. package/dist/src/web-ui/local-runtime/runtime-setup-edit-transaction.js +37 -0
  314. package/dist/src/web-ui/local-runtime/runtime-setup-service.js +4 -0
  315. package/dist/src/web-ui/local-runtime-backend.js +14 -0
  316. package/dist/src/web-ui/plugin-management-catalog.d.ts +3 -1
  317. package/dist/src/web-ui/plugin-management-catalog.js +3 -1
  318. package/dist/src/web-ui/plugin-management-service.d.ts +1 -0
  319. package/dist/src/web-ui/plugin-removal-service.d.ts +1 -0
  320. package/dist/src/web-ui/server-readiness.d.ts +3 -0
  321. package/dist/src/web-ui/server-readiness.js +36 -0
  322. package/dist/src/web-ui/server.d.ts +2 -0
  323. package/dist/src/web-ui/server.js +23 -1
  324. package/dist/src/web-ui/system-host-service.js +13 -2
  325. package/dist/src/web-ui/system-host-setup/collection-consent-route.d.ts +3 -0
  326. package/dist/src/web-ui/system-host-setup/collection-consent-route.js +30 -0
  327. package/docs/installation.md +44 -5
  328. package/docs/plugins.md +145 -4
  329. package/docs/tool-execution-result-evidence-contract.md +57 -0
  330. package/docs/windows-companion-store.md +5 -0
  331. package/package.json +4 -2
  332. package/plugins/capability-brief/plugin.json +4 -0
  333. package/plugins/code-outline/README.md +20 -0
  334. package/plugins/code-outline/plugin.json +1 -0
  335. package/plugins/code-outline/source/index.ts +16 -20
  336. package/plugins/code-outline/source/read-failure.ts +40 -0
  337. package/plugins/code-outline/src/index.cjs +614 -29
  338. package/plugins/document-reader/README.md +33 -0
  339. package/plugins/document-reader/plugin.json +1 -0
  340. package/plugins/document-reader/source/pdf-contract.ts +57 -0
  341. package/plugins/document-reader/source/pdf-parser.ts +139 -0
  342. package/plugins/document-reader/source/pdf-process-main.ts +56 -0
  343. package/plugins/document-reader/source/pdf-process.ts +207 -0
  344. package/plugins/document-reader/source/pdf-result.ts +79 -0
  345. package/plugins/document-reader/source/pdf-worker.ts +39 -303
  346. package/plugins/document-reader/source/pdf.ts +4 -1
  347. package/plugins/document-reader/source/read-failure.ts +37 -0
  348. package/plugins/document-reader/source/reader.ts +3 -19
  349. package/plugins/document-reader/src/index.cjs +995 -211
  350. package/plugins/exec/README.md +19 -0
  351. package/plugins/exec/plugin.json +4 -3
  352. package/plugins/exec/skills/exec_skill/SKILL.md +3 -2
  353. package/plugins/exec/source/filesystem-file-observer.ts +98 -0
  354. package/plugins/exec/source/filesystem-observer.ts +8 -79
  355. package/plugins/exec/source/output-files.ts +12 -6
  356. package/plugins/exec/source/paths.ts +3 -1
  357. package/plugins/exec/source/process-manager.ts +8 -24
  358. package/plugins/exec/source/shell-platform.ts +19 -3
  359. package/plugins/exec/source/shell-process.ts +55 -0
  360. package/plugins/exec/source/windows-job-source.ts +1 -0
  361. package/plugins/exec/source/windows-shell-bootstrap.ts +20 -0
  362. package/plugins/exec/src/index.cjs +252 -96
  363. package/plugins/filesystem/README.md +65 -0
  364. package/plugins/filesystem/plugin.json +6 -2
  365. package/plugins/filesystem/source/atomic-write.ts +2 -0
  366. package/plugins/filesystem/source/bounded-io.ts +80 -306
  367. package/plugins/filesystem/source/directory-sample.ts +2 -0
  368. package/plugins/filesystem/source/errors.ts +14 -0
  369. package/plugins/filesystem/source/file-observation.ts +151 -0
  370. package/plugins/filesystem/source/file-version.ts +41 -0
  371. package/plugins/filesystem/source/index.ts +6 -0
  372. package/plugins/filesystem/source/mutation-coordinator.ts +1 -0
  373. package/plugins/filesystem/source/windows/authority-script.ts +1 -0
  374. package/plugins/filesystem/source/windows/native-script.ts +1 -0
  375. package/plugins/filesystem/source/windows/operations.ts +197 -0
  376. package/plugins/filesystem/source/windows/process.ts +214 -0
  377. package/plugins/filesystem/source/windows/publication-script.ts +29 -0
  378. package/plugins/filesystem/source/windows/read-script.ts +63 -0
  379. package/plugins/filesystem/source/windows/request-availability.ts +67 -0
  380. package/plugins/filesystem/source/windows/source.ts +42 -0
  381. package/plugins/filesystem/source/windows/storage-script.ts +11 -0
  382. package/plugins/filesystem/source/windows/streams-script.ts +24 -0
  383. package/plugins/filesystem/source/windows/write-script.ts +86 -0
  384. package/plugins/filesystem/src/index.cjs +1208 -322
  385. package/plugins/json-inspector/README.md +18 -0
  386. package/plugins/json-inspector/plugin.json +1 -0
  387. package/plugins/json-inspector/source/index.ts +16 -19
  388. package/plugins/json-inspector/source/read-failure.ts +42 -0
  389. package/plugins/json-inspector/src/index.cjs +612 -27
  390. package/plugins/local-search/README.md +29 -0
  391. package/plugins/local-search/plugin.json +1 -0
  392. package/plugins/local-search/source/errors.ts +2 -0
  393. package/plugins/local-search/source/paths.ts +3 -0
  394. package/plugins/local-search/source/ripgrep-process.ts +31 -5
  395. package/plugins/local-search/source/ripgrep.ts +3 -3
  396. package/plugins/local-search/source/windows-authority.ts +99 -0
  397. package/plugins/local-search/source/windows-search-lease.ts +49 -0
  398. package/plugins/local-search/source/windows-search-process.ts +91 -0
  399. package/plugins/local-search/source/windows-search-script.ts +52 -0
  400. package/plugins/local-search/src/index.cjs +595 -26
  401. package/plugins/memory/plugin.json +4 -0
  402. package/plugins/memory/source/lock-directory-claim.ts +56 -0
  403. package/plugins/memory/source/lock-owner-file.ts +71 -0
  404. package/plugins/memory/source/lock-path-observation.ts +26 -0
  405. package/plugins/memory/source/prepared-memory-replacement.ts +40 -0
  406. package/plugins/memory/source/store-lock.ts +12 -7
  407. package/plugins/memory/source/store.ts +3 -2
  408. package/plugins/memory/src/index.cjs +174 -25
  409. package/plugins/project-orientation/README.md +23 -0
  410. package/plugins/project-orientation/plugin.json +1 -0
  411. package/plugins/project-orientation/source/index.ts +12 -9
  412. package/plugins/project-orientation/source/inspection-failure.ts +70 -0
  413. package/plugins/project-orientation/source/manifest-summary.ts +9 -2
  414. package/plugins/project-orientation/source/tree.ts +6 -0
  415. package/plugins/project-orientation/src/index.cjs +647 -31
  416. package/plugins/system/README.md +51 -15
  417. package/plugins/system/plugin.json +5 -1
  418. package/plugins/system/skills/system_actions/SKILL.md +1 -1
  419. package/plugins/system/source/command-working-directory.ts +47 -0
  420. package/plugins/system/source/computer/handlers.ts +13 -9
  421. package/plugins/system/source/computer/observation-result.ts +10 -5
  422. package/plugins/system/source/computer/request-computers.ts +10 -3
  423. package/plugins/system/source/computer/request-modules.ts +3 -6
  424. package/plugins/system/source/computer/runtime-platform.ts +18 -0
  425. package/plugins/system/source/host-dispatch.ts +18 -2
  426. package/plugins/system/source/index.ts +5 -3
  427. package/plugins/system/source/local-command-output-retention.ts +16 -0
  428. package/plugins/system/source/local-command-output.ts +16 -8
  429. package/plugins/system/source/request-system-modules.ts +12 -2
  430. package/plugins/system/source/request-target-snapshot.ts +2 -1
  431. package/plugins/system/source/security/desktop-result.ts +177 -0
  432. package/plugins/system/source/security/observed-error.ts +10 -0
  433. package/plugins/system/source/security/secret-text.ts +118 -0
  434. package/plugins/system/source/security/system-results.ts +62 -0
  435. package/plugins/system/source/security/windows-output-directory.ts +82 -0
  436. package/plugins/system/src/index.cjs +837 -151
  437. package/plugins/system-probe/plugin.json +8 -2
  438. package/plugins/system-probe/source/disk-path.ts +8 -0
  439. package/plugins/system-probe/source/index.ts +10 -5
  440. package/plugins/system-probe/source/machine-load.ts +33 -0
  441. package/plugins/system-probe/source/metrics.ts +6 -8
  442. package/plugins/system-probe/src/index.cjs +49 -16
  443. package/plugins/web/plugin.json +4 -0
@@ -1,10 +1,8 @@
1
+ import { createComposerFeature } from "./controllers/composer-feature.js";
1
2
  import { isWorkspaceChange } from "./lib/workspace-change.js";
3
+ import { prepareEnvironmentWorkspaceChanges } from "./controllers/environment-workspace-preparation.js";
2
4
  import { createAppState } from "./app-state.js";
3
5
  import { createProjectsFeature } from "./projects-feature.js";
4
- import {
5
- captureComposerSubmissionScope,
6
- isCurrentComposerSubmissionScope,
7
- } from "./lib/composer-submission-scope.js";
8
6
  import { createComposerSurfaceController } from "./controllers/composer-surface-controller.js";
9
7
  import { startWebApp } from "./app-bootstrap.js";
10
8
  import { createNotificationsFeature } from "./notifications-feature.js";
@@ -26,34 +24,35 @@ import { createSessionActionsMenu } from "./components/session-actions-menu.js";
26
24
  import { createToolApprovalCard } from "./components/tool-approval-card.js";
27
25
  import { textOf } from "./lib/text-format.js";
28
26
  import { createConversationViewFeature as createConversationView } from "./controllers/conversation-view-feature.js";
29
- import { createSessionComposerQueue } from "./lib/session-composer-queue.js";
27
+ import { initializeWorkspaceState, workspaceQueue, observeWorkspaceStateChange } from "./services/workspace-state.js";
30
28
  import { createRuntimeWebClient } from "./services/runtime-web-client.js";
29
+ import { createHomeGuidancePreferences } from "./services/home-guidance-preferences.js";
31
30
  import { createClientPreferences } from "./services/client-preferences.js";
31
+ import { createConversationWorkspaceActivation } from "./controllers/conversation-workspace-activation.js";
32
32
  import { createOperationsController } from "./controllers/operations-controller.js";
33
33
  import { createAppRealtimeTransport } from "./app-realtime-transport.js";
34
34
  import { createSteerController } from "./controllers/steer-controller.js";
35
35
  import { createSessionController } from "./controllers/session-controller.js";
36
- import { createComposerAttachmentsController } from "./controllers/composer-attachments-controller.js";
37
- import { createComposerQueueController } from "./controllers/composer-queue-controller.js";
38
36
  import { createRealtimeEventController } from "./controllers/realtime-event-controller.js";
39
37
  import { createRuntimeSelectionController } from "./controllers/runtime-selection-controller.js";
40
38
  import { createAppEventBindings } from "./controllers/app-event-bindings.js";
41
39
  import { createConversationSessionController } from "./controllers/conversation-session-controller.js";
42
- import { createChatRequestController } from "./controllers/chat-request-controller.js";
43
40
  import { createToolApprovalController } from "./controllers/tool-approval-controller.js";
44
- import { createComposerSubmitController } from "./controllers/composer-submit-controller.js";
45
41
 
46
42
  const state = createAppState();
47
43
 
48
44
  const dom = findAppDom();
49
45
 
50
- const preferences = createClientPreferences(localStorage);
46
+ const storage = await initializeWorkspaceState();
47
+ const preferences = createClientPreferences(storage);
51
48
  const runtimeClient = createRuntimeWebClient({
52
49
  getConfig: () => state.config,
53
50
  getEnvironmentId: selectedEnvironmentId,
51
+ onMemoryDeleted: (environment, id) => createHomeGuidancePreferences(storage).forgetReviewed(environment, id),
54
52
  });
55
53
  let conversationSession;
56
- let chatRequests;
54
+ let composerFeature;
55
+ let composerAttachments;
57
56
  let composerQueueController;
58
57
  let composerSubmitController;
59
58
  let realtimeEvents;
@@ -159,7 +158,7 @@ const composerActions = createComposerActions({
159
158
  onSendNext: () => dispatchComposerMessage("send_next"),
160
159
  });
161
160
  schedulesFeature = createSchedulesFeature({
162
- dom,
161
+ dom, state,
163
162
  onNavigationChange: () => workspaceRoutes?.sync(),
164
163
  client: runtimeClient,
165
164
  shell,
@@ -208,6 +207,7 @@ const {
208
207
  renderAttachmentComposer,
209
208
  removeUnsupportedPendingImages,
210
209
  updateComposerSendState,
210
+ refreshComposerSubmissionState,
211
211
  uploadComposerAttachment,
212
212
  resizeComposerInput,
213
213
  dispatchComposerMessage,
@@ -216,12 +216,11 @@ const {
216
216
  getHomeComposer: () => homeComposer,
217
217
  getChatAttachments: () => composerAttachments,
218
218
  getChatSubmit: () => composerSubmitController,
219
+ refreshComposerSurfaces: () => composerFeature?.changed(),
219
220
  rememberModelSelection: rememberCurrentModelSelection,
220
221
  showToast: shell.showToast,
221
222
  });
222
- const sessionComposerQueue = createSessionComposerQueue({
223
- storage: localStorage,
224
- });
223
+ const sessionComposerQueue = workspaceQueue();
225
224
  const sessionActionsMenu = createSessionActionsMenu({
226
225
  container: dom.sessionsList,
227
226
  });
@@ -243,30 +242,12 @@ const sessionController = createSessionController({
243
242
  }
244
243
  conversationSession.clearSessionMessagesView();
245
244
  },
245
+ onSessionAttachmentsCleared: (scope) => composerWorkspace.drafts.clearAttachments(scope),
246
246
  onClearSessionMode: clearSessionMode,
247
247
  onSaveModelPreferences: saveModelPreferences,
248
248
  onReload: () => conversationSession.loadSessions(),
249
249
  onControlEvent: recordControlEvent,
250
250
  });
251
- const composerAttachments = createComposerAttachmentsController({
252
- state,
253
- dom,
254
- shell,
255
- client: runtimeClient,
256
- selectedEnvironmentId,
257
- selectedModelSupportsImageInput: () =>
258
- runtimeSelection.selectedModelSupportsImageInput(
259
- composerWorkspace.isChatVisible()
260
- ? dom.modelSelect.value
261
- : state.sessionModels[state.currentSessionId] ||
262
- state.defaultModelProfileId,
263
- ),
264
- ensureSession: () => conversationSession.ensureSession(),
265
- onSendStateChange: updateComposerSendState,
266
- onControlEvent: recordControlEvent,
267
- isComposerAvailable: runtimeOnboarding.isReady,
268
- isComposerVisible: composerWorkspace.isChatVisible,
269
- });
270
251
  const toolApprovalController = createToolApprovalController({
271
252
  state,
272
253
  selectedEnvironmentId,
@@ -315,7 +296,6 @@ conversationSession = createConversationSessionController({
315
296
  !dom.chatPanel.inert &&
316
297
  document.visibilityState === "visible",
317
298
  onSessionListState: dashboardFeature.sessionsChanged,
318
- clearPendingAttachments,
319
299
  applyConversationChrome: applyConversationModeChrome,
320
300
  applyModelSelection: applyModelSelectionForCurrentSession,
321
301
  renderSessions,
@@ -329,13 +309,36 @@ conversationSession = createConversationSessionController({
329
309
  reportQueueFailure: (scope, summary) =>
330
310
  composerQueueController.reportFailure(scope, summary),
331
311
  drainQueuedMessage: (input) => composerQueueController.drain(input),
332
- suspendQueueRecovery: () =>
333
- composerQueueController.suspendRecoveryForNavigation(),
312
+ suspendQueueRecovery: (canNavigate) =>
313
+ composerQueueController.suspendRecoveryForNavigation(canNavigate),
334
314
  recoverBlockedQueue: (scope) =>
335
315
  composerQueueController.recoverForManualSend(scope),
336
316
  isCurrentComposerScope: (scope) =>
337
317
  composerQueueController.isCurrentScope(scope),
338
318
  });
319
+ composerFeature = createComposerFeature({
320
+ state, dom: composerWorkspace.chatDom, shell, client: runtimeClient,
321
+ sessionQueue: sessionComposerQueue, conversationSession, conversationView,
322
+ drafts: composerWorkspace.drafts, getDraft: composerWorkspace.chatView.current,
323
+ getEnvironmentId: selectedEnvironmentId,
324
+ ensureSession: () => conversationSession.ensureSession(),
325
+ getSettings: () => {
326
+ rememberCurrentModelSelection();
327
+ return { agentMode: state.agentMode, toolPermissionMode: currentToolPermissionMode(), modelPreference: selectedModelPreference() };
328
+ },
329
+ steer: steerController.steer, composerActions,
330
+ selectedModelSupportsImageInput: () => runtimeSelection.selectedModelSupportsImageInput(
331
+ composerWorkspace.isChatVisible() ? dom.modelSelect.value : state.sessionModels[state.currentSessionId] || state.defaultModelProfileId),
332
+ isComposerAvailable: runtimeOnboarding.isReady,
333
+ getSubmissionBlock: runtimeOnboarding.submissionBlock,
334
+ onSubmissionBlocked: runtimeOnboarding.presentSubmissionBlock,
335
+ isVisible: composerWorkspace.isChatVisible, renderSessions, renderMessages,
336
+ applyConversationChrome: applyConversationModeChrome,
337
+ setMessageStatus: setMessageActivityStatus, recordControlEvent,
338
+ });
339
+ composerAttachments = composerFeature.attachments;
340
+ composerQueueController = composerFeature.queue;
341
+ composerSubmitController = composerFeature.submit;
339
342
  projectsFeature = createProjectsFeature({
340
343
  isRuntimeReady: runtimeOnboarding.isReady,
341
344
  onSessionCreated: (sessionId) =>
@@ -348,65 +351,7 @@ projectsFeature = createProjectsFeature({
348
351
  conversationSession,
349
352
  renderSessions,
350
353
  closeFilePreview: conversationView.closeFilePreview,
351
- prepareConversation: () => {
352
- const activate = shell.prepareWorkspaceActivation("chat", { focus: false });
353
- if (!activate) return false;
354
- if (!composerQueueController.suspendRecoveryForNavigation()) return false;
355
- return activate() !== false;
356
- },
357
- });
358
- chatRequests = createChatRequestController({
359
- state,
360
- client: runtimeClient,
361
- sessionQueue: sessionComposerQueue,
362
- conversationView,
363
- conversationSession,
364
- attachments: composerAttachments,
365
- currentComposerScope: () => composerQueueController.currentScope(),
366
- isCurrentComposerScope: (scope) =>
367
- composerQueueController.isCurrentScope(scope),
368
- rememberModelSelection: rememberCurrentModelSelection,
369
- applyConversationChrome: applyConversationModeChrome,
370
- renderSessions,
371
- renderAttachments: renderAttachmentComposer,
372
- getToolPermissionMode: currentToolPermissionMode,
373
- getModelPreference: selectedModelPreference,
374
- clearQueueRecovery: (scope) => composerQueueController.clearRecovery(scope),
375
- reportQueueFailure: (scope, summary) =>
376
- composerQueueController.reportFailure(scope, summary),
377
- });
378
- composerQueueController = createComposerQueueController({
379
- state,
380
- dom: composerWorkspace.chatDom,
381
- queue: sessionComposerQueue,
382
- selectedEnvironmentId,
383
- getToolPermissionMode: currentToolPermissionMode,
384
- getModelPreference: selectedModelPreference,
385
- rememberModelSelection: rememberCurrentModelSelection,
386
- attachments: composerAttachments,
387
- updateSendState: updateComposerSendState,
388
- postChatMessage: chatRequests.postChatMessage,
389
- appendLocalUserMessage: conversationSession.appendLocalUserMessage,
390
- activateRequestForScope: conversationSession.activateRequestForScope,
391
- renderMessages,
392
- setMessageStatus: setMessageActivityStatus,
393
- recordControlEvent,
394
- resizeComposer: resizeComposerInput,
395
- });
396
- composerSubmitController = createComposerSubmitController({
397
- state,
398
- dom: composerWorkspace.chatDom,
399
- composerActions,
400
- attachments: composerAttachments,
401
- queue: composerQueueController,
402
- steer: (text) => steerController.steer(text),
403
- chatRequests,
404
- conversationSession,
405
- selectedEnvironmentId,
406
- setMessageStatus: setMessageActivityStatus,
407
- getSubmissionBlock: runtimeOnboarding.submissionBlock,
408
- onSubmissionBlocked: runtimeOnboarding.presentSubmissionBlock,
409
- isComposerVisible: composerWorkspace.isChatVisible,
354
+ prepareConversation: createConversationWorkspaceActivation({ state, shell, composerQueue: composerQueueController, selectedEnvironmentId }),
410
355
  });
411
356
  realtimeEvents = createRealtimeEventController({
412
357
  state,
@@ -453,6 +398,7 @@ runtimeSelection = createRuntimeSelectionController({
453
398
  client: runtimeClient,
454
399
  recordControlEvent,
455
400
  onAttachmentPolicyChange: renderAttachmentComposer,
401
+ onReasoningConfigurationApplied: () => configWorkspace.reloadAppliedEnvironmentModels(),
456
402
  onModelCatalogLoading: runtimeOnboarding.beginCatalogLoad,
457
403
  onModelCatalogLoaded: runtimeOnboarding.applyCatalog,
458
404
  onModelCatalogUnavailable: runtimeOnboarding.catalogUnavailable,
@@ -460,59 +406,15 @@ runtimeSelection = createRuntimeSelectionController({
460
406
  });
461
407
  homeComposer = createHomeComposerFeature({
462
408
  workspace: composerWorkspace,
463
- shell,
464
- client: runtimeClient,
465
- composerActions,
466
- selectedEnvironmentId,
467
- selectedModelSupportsImageInput: () =>
468
- runtimeSelection.selectedModelSupportsImageInput(
469
- composerWorkspace.isHome()
470
- ? dom.modelSelect.value
471
- : state.sessionModels[composerWorkspace.homeState.currentSessionId] ||
472
- state.defaultModelProfileId,
473
- ),
474
- isComposerAvailable: runtimeOnboarding.isReady,
475
- getSubmissionBlock: runtimeOnboarding.submissionBlock,
476
- onSubmissionBlocked: runtimeOnboarding.presentSubmissionBlock,
477
- onControlEvent: recordControlEvent,
478
- onStateChange: updateComposerSendState,
409
+ composer: composerFeature,
410
+ selectedModelSupportsImageInput: () => runtimeSelection.selectedModelSupportsImageInput(
411
+ composerWorkspace.isHome() ? dom.modelSelect.value : state.sessionModels[composerWorkspace.ensureHomeSession()] || state.defaultModelProfileId),
479
412
  activateHomeSession: createHomeConversationActivation({
480
- state,
481
- shell,
482
- conversationSession,
483
- composerQueue: composerQueueController,
484
- preferences,
485
- selectedEnvironmentId,
486
- renderSessions,
487
- renderMessages,
413
+ state, shell, conversationSession, composerQueue: composerQueueController,
414
+ preferences, selectedEnvironmentId, renderSessions, renderMessages,
488
415
  applyModelSelection: applyModelSelectionForCurrentSession,
489
- setCurrentTitle: setCurrentSessionTitle,
490
- updateComposerSendState,
416
+ setCurrentTitle: setCurrentSessionTitle, updateComposerSendState,
491
417
  }),
492
- sendMessage: async (text) => {
493
- const scope = captureComposerSubmissionScope(
494
- state,
495
- selectedEnvironmentId(),
496
- );
497
- state.composerSending = true;
498
- updateComposerSendState();
499
- try {
500
- await chatRequests.sendMessage(text);
501
- } catch (error) {
502
- if (
503
- !isCurrentComposerSubmissionScope(scope, state, selectedEnvironmentId())
504
- )
505
- return;
506
- conversationSession.appendRequestError(error);
507
- } finally {
508
- if (
509
- isCurrentComposerSubmissionScope(scope, state, selectedEnvironmentId())
510
- ) {
511
- state.composerSending = false;
512
- updateComposerSendState();
513
- }
514
- }
515
- },
516
418
  });
517
419
  const appEventBindings = createAppEventBindings({
518
420
  onNavigationChange: () => workspaceRoutes?.sync(),
@@ -538,11 +440,7 @@ const appEventBindings = createAppEventBindings({
538
440
  subscribeSession,
539
441
  renderMessages,
540
442
  renderAgentPicker,
541
- savedEnvironmentId,
542
- beforeEnvironmentChange: () => {
543
- if (!schedulesFeature.prepareLeave()) return false;
544
- return configWorkspace.prepareDiscardChanges("change environment");
545
- },
443
+ beforeEnvironmentChange: () => prepareEnvironmentWorkspaceChanges(schedulesFeature, configWorkspace),
546
444
  saveEnvironmentId,
547
445
  loadModels,
548
446
  loadAgentMode,
@@ -557,6 +455,7 @@ const appEventBindings = createAppEventBindings({
557
455
  dispatchComposerMessage,
558
456
  resizeComposer: resizeComposerInput,
559
457
  updateComposerSendState,
458
+ refreshComposerSubmissionState,
560
459
  loadRuntimeStatus,
561
460
  loadRuntimeLogs,
562
461
  loadSystemHealth,
@@ -571,6 +470,7 @@ configWorkspace = createConfigurationFeature({
571
470
  onNavigationChange: () => workspaceRoutes?.sync(),
572
471
  state,
573
472
  selection: runtimeSelection,
473
+ changeEnvironment: (...args) => appEventBindings.changeEnvironment(...args),
574
474
  onConfigurationApplied: loadModels,
575
475
  dom,
576
476
  runtimeClient,
@@ -640,12 +540,8 @@ function renderPermissionModeControl() {
640
540
  runtimeSelection.renderPermissionMode();
641
541
  }
642
542
 
643
- function savedEnvironmentId() {
644
- return preferences.environmentId();
645
- }
646
-
647
543
  function saveEnvironmentId(environmentId) {
648
- preferences.saveEnvironmentId(environmentId);
544
+ return preferences.saveEnvironmentId(environmentId);
649
545
  }
650
546
 
651
547
  function saveSessionIdForEnvironment(environmentId, sessionId) {
@@ -716,6 +612,7 @@ function rejectPendingSteers(reason) {
716
612
  }
717
613
 
718
614
  function handleRealtimeMessage(message) {
615
+ observeWorkspaceStateChange(message);
719
616
  dashboardFeature?.handleRealtime(message);
720
617
  schedulesFeature?.handleRealtime(message);
721
618
  passiveLearning?.handleRealtime(message);
@@ -1,3 +1,4 @@
1
+ import { renderReasoningModeField, retainedReasoningMode } from "../../lib/reasoning-controls.js";
1
2
  import { escapeHtml } from "../../lib/text-format.js";
2
3
  import { readBindingFields, renderBindingFields } from "./binding-fields.js";
3
4
  import { hasConnectedAutomationResultInput } from "../../lib/automation-binding-producers.js";
@@ -134,7 +135,7 @@ function renderAgentEditor(node, catalog, producers) {
134
135
  return `${producers.length ? `<p class="automation-input-notice" data-input-connection="${connected ? "connected" : "none"}"${connected ? " hidden" : ""}>No earlier step output is connected. Connect an output below if this agent should use it.</p>` : ""}
135
136
  ${renderBindingFields(node.inputs, null, { name: "inputs", allowAdd: true, producers })}
136
137
  ${renderModelChoice(node, catalog)}
137
- <label>Mode<select name="agentMode"><option value="fast"${node.agentMode === "fast" ? " selected" : ""}>Fast</option><option value="reasoning"${node.agentMode === "reasoning" ? " selected" : ""}>Reasoning</option><option value="deep"${node.agentMode === "deep" ? " selected" : ""}>Deep</option></select></label>
138
+ ${renderReasoningModeField(node.agentMode || "fast", catalog?.models?.find((model) => model.id === node.modelProfileId))}
138
139
  <label>Role instructions<textarea name="roleInstructions" dir="auto">${escapeHtml(node.roleInstructions || "")}</textarea></label>
139
140
  <label>Prompt<textarea name="prompt" dir="auto" required>${escapeHtml(node.prompt || "")}</textarea></label>
140
141
  <details class="automation-node-contract"><summary>Result contract · ${node.result?.kind === "json" ? "Structured JSON" : "Text"}</summary>
@@ -217,7 +218,7 @@ export function readAutomationNodePatch(form, node, catalog) {
217
218
  };
218
219
  if (node.kind === "agent") {
219
220
  patch.modelProfileId = String(fields.get("modelProfileId") || "");
220
- patch.agentMode = String(fields.get("agentMode") || "fast");
221
+ patch.agentMode = retainedReasoningMode(form, node.agentMode || "fast");
221
222
  patch.roleInstructions = String(fields.get("roleInstructions") || "");
222
223
  patch.prompt = String(fields.get("prompt") || "");
223
224
  patch.inputs = readBindingFields(form, "inputs");
@@ -1,3 +1,4 @@
1
+ import { syncReasoningModeField } from "../../lib/reasoning-controls.js";
1
2
  import { escapeHtml } from "../../lib/text-format.js";
2
3
  import { listAvailableAutomationProducers } from "../../lib/automation-binding-producers.js";
3
4
  import { findAutomationNode } from "./timeline.js";
@@ -164,6 +165,8 @@ export function createAutomationStepEditorDialog({ root, actions, documentRoot,
164
165
  if (target.matches("[data-agent-tool-search]")) { updateAgentToolPicker(form); return; }
165
166
  if (!form.contains(target) || entry.saving) return;
166
167
  entry.dirty = true;
168
+ if (event.type === "change" && target.matches('[name="modelProfileId"]'))
169
+ syncReasoningModeField(form, entry.catalog?.models);
167
170
  if (target.matches("[data-agent-tool]")) updateAgentToolPicker(form);
168
171
  if (event.type === "change" && target.matches('[name="toolOperation"]')) {
169
172
  const operations = entry.catalog?.grantableOperations || entry.catalog?.operations || [];
@@ -0,0 +1,50 @@
1
+ /** Manual review is explicit; displaying an uncertain outcome never retries it. */
2
+ export function createComposerSubmissionNotice({ form, review, recover }) {
3
+ const root = form.ownerDocument.createElement("div");
4
+ root.className = "composer-submission-notice";
5
+ root.setAttribute("role", "status");
6
+ root.hidden = true;
7
+ form.appendChild(root);
8
+ return {
9
+ render(attempts, recovery) {
10
+ root.replaceChildren();
11
+ root.hidden = attempts.length === 0 && !recovery;
12
+ for (const attempt of attempts) {
13
+ const row = form.ownerDocument.createElement("div");
14
+ const label = form.ownerDocument.createElement("span");
15
+ label.textContent = attempt.action === "send_next"
16
+ ? "Queue save could not be confirmed. Reload and check Send next before repeating this message."
17
+ : "A message could not be confirmed. Check the conversation before sending it again.";
18
+ row.appendChild(label);
19
+ if (attempt.action !== "send_next") {
20
+ const button = form.ownerDocument.createElement("button");
21
+ button.type = "button";
22
+ button.textContent = "Review message";
23
+ button.addEventListener("click", async () => {
24
+ button.disabled = true;
25
+ try { await review(attempt); }
26
+ finally { button.disabled = false; }
27
+ });
28
+ row.appendChild(button);
29
+ }
30
+ root.appendChild(row);
31
+ }
32
+ if (!recovery) return;
33
+ const row = form.ownerDocument.createElement("div");
34
+ const label = form.ownerDocument.createElement("span");
35
+ label.textContent = recovery.draftEmpty
36
+ ? "A queued message is paused and ready for manual review."
37
+ : "Finish or clear your current draft to review the paused queued message.";
38
+ const button = form.ownerDocument.createElement("button");
39
+ button.type = "button";
40
+ button.textContent = "Review queued message";
41
+ button.disabled = !recovery.draftEmpty;
42
+ button.addEventListener("click", async () => {
43
+ button.disabled = true;
44
+ try { await recover(recovery.scope); }
45
+ finally { button.disabled = !recovery.draftEmpty; }
46
+ });
47
+ row.appendChild(label); row.appendChild(button); root.appendChild(row);
48
+ },
49
+ };
50
+ }
@@ -1,3 +1,7 @@
1
+ import {
2
+ isPluginPlatformUnavailable,
3
+ renderPluginPlatformNotice,
4
+ } from "../plugins/compatibility.js";
1
5
  import { escapeAttribute, escapeHtml } from "../../lib/text-format.js";
2
6
  import {
3
7
  modelPluginRulesNeedRepair,
@@ -58,10 +62,12 @@ function renderPluginRow(file, plugin, globalPlugin, viewState) {
58
62
  <summary id="${escapeAttribute(summaryId)}">
59
63
  <span class="model-plugin-name" title="${escapeAttribute(plugin.id)}">${escapeHtml(plugin.id)}</span>
60
64
  <span class="model-plugin-row-status">
65
+ ${isPluginPlatformUnavailable(plugin.compatibility) ? '<span class="model-plugin-platform-note">Unavailable on this host</span>' : ""}
61
66
  ${globallyRestricted ? '<span class="model-plugin-global-note">Global restrictions</span>' : ""}
62
67
  <span class="plugin-selection-state" data-plugin-state="${escapeAttribute(plugin.state)}">${plugin.selectedCapabilityCount}/${count} tools</span>
63
68
  </span>
64
69
  </summary>
70
+ ${renderPluginPlatformNotice(plugin.compatibility)}
65
71
  <div class="model-plugin-details-body">
66
72
  ${plugin.description ? `<p class="model-plugin-description">${escapeHtml(plugin.description)}</p>` : ""}
67
73
  ${reason ? `<p class="plugin-capability-policy model-plugin-policy" id="${escapeAttribute(reasonId)}">${escapeHtml(reason)}</p>` : ""}
@@ -116,7 +122,7 @@ export function renderModelPluginPermissions(file, catalog, viewState = {}) {
116
122
  return `<details class="model-plugin-permissions" data-model-plugin-section="${escapeAttribute(file.id)}" aria-label="${escapeAttribute(`Plugin access for ${modelLabel(file)}`)}" ${open ? "open" : ""}>
117
123
  <summary id="${escapeAttribute(summaryId)}">
118
124
  <span>Plugin access</span>
119
- <span class="model-plugin-summary-count">${plugins.length} plugins · ${selectedCount}/${capabilityCount} tools available</span>
125
+ <span class="model-plugin-summary-count">${plugins.length} plugins · ${selectedCount}/${capabilityCount} tools selected</span>
120
126
  </summary>
121
127
  <div class="model-plugin-permissions-body">
122
128
  <p class="model-plugin-help">Allow plugins and individual tools for <strong>${escapeHtml(modelLabel(file))}</strong>. Global restrictions still apply. Save this model, then apply changes.</p>
@@ -95,7 +95,7 @@ export function createConfigWorkspaceMutations({
95
95
  return null;
96
96
  }
97
97
  const changed = dirtyFiles();
98
- if (!changed.length) return () => {};
98
+ if (!changed.length) return prepareConfigDiscardCommit(false);
99
99
  const count = changed.length;
100
100
  const confirmed = confirmDiscard(
101
101
  `Discard unsaved changes in ${count} config ${
@@ -103,7 +103,27 @@ export function createConfigWorkspaceMutations({
103
103
  } and ${reason}?`,
104
104
  );
105
105
  if (!confirmed) return null;
106
- return discardAllChanges;
106
+ return prepareConfigDiscardCommit(true);
107
+ }
108
+
109
+ function configDraftFingerprint() {
110
+ return JSON.stringify(configFileEntries().map((file) => {
111
+ const key = configFileKey(file);
112
+ return [key, file.config, state.rawDraftsByKey.get(key), state.baselinesByKey.get(key), state.appliedJsonRepairKeys.has(key)];
113
+ }));
114
+ }
115
+
116
+ function prepareConfigDiscardCommit(hasChanges) {
117
+ const dashboard = state.configDashboard;
118
+ const fingerprint = configDraftFingerprint();
119
+ const commit = () => { if (hasChanges) discardAllChanges(); };
120
+ commit.canCommit = () => {
121
+ if (state.externalRuntimeMutationInFlight) return false;
122
+ if (state.savingKeys.size > 0) return false;
123
+ if (state.configDashboard !== dashboard) return false;
124
+ return configDraftFingerprint() === fingerprint;
125
+ };
126
+ return commit;
107
127
  }
108
128
 
109
129
  function confirmDiscardChanges(reason = "leave configuration") {
@@ -14,7 +14,7 @@ export function createDailyReviewDialog({ container, onDecision, onDismiss }) {
14
14
  <p class="daily-review-error" role="alert" data-review-error hidden></p>
15
15
  <div class="daily-review-actions"><button type="button" data-review-delete>Delete memory</button>
16
16
  <button type="button" data-review-keep>Keep memory</button></div>
17
- <p class="daily-review-note">These memories are already saved. Keep marks them as reviewed in this browser.</p>
17
+ <p class="daily-review-note">These memories are already saved. Keep marks them as reviewed in this ABot installation.</p>
18
18
  <button type="button" class="daily-review-later" data-review-later>Not now</button>`;
19
19
  container.append(dialog);
20
20
  let returnFocus;
@@ -53,7 +53,7 @@ export function createDailyReviewDialog({ container, onDecision, onDismiss }) {
53
53
  dialog.querySelector("[data-review-error]").hidden = !error;
54
54
  dialog.querySelector(".daily-review-actions").hidden = !record;
55
55
  for (const button of dialog.querySelectorAll(".daily-review-actions button")) button.disabled = busy;
56
- dialog.querySelector("[data-review-delete]").textContent = busy ? "Deleting…" : "Delete memory";
56
+ dialog.querySelector("[data-review-delete]").textContent = busy ? "Saving…" : "Delete memory";
57
57
  const later = dialog.querySelector("[data-review-later]");
58
58
  later.textContent = record ? "Not now" : "Done";
59
59
  if (hasReviewLoadError) later.textContent = "Close";
@@ -5,14 +5,14 @@ import { createHomeGuidancePreferences } from "../../services/home-guidance-pref
5
5
  import { createDailyMemoryReview } from "../../controllers/daily-memory-review.js";
6
6
  import { createDailyReviewDialog } from "./daily-review.js";
7
7
  import { createDailyReviewEntry } from "./daily-review-entry.js";
8
+ import { workspaceStorage } from "../../services/workspace-state.js";
8
9
 
9
10
  export function createHomeGuidance({ container, homeRegion, client, getEnvironmentId,
10
11
  getLearningSnapshot, getConnectionState, supportsConnection, refreshConnection,
11
12
  onOpen, isRuntimeReady = () => true, storage }) {
12
13
  const documentRoot = container?.ownerDocument;
13
14
  if (!documentRoot) return { render() {}, dispose() {} };
14
- let preferenceStorage = storage;
15
- try { preferenceStorage ??= documentRoot.defaultView?.localStorage; } catch { /* Session-only preferences. */ }
15
+ const preferenceStorage = storage ?? workspaceStorage();
16
16
  const preferences = createHomeGuidancePreferences(preferenceStorage);
17
17
  const root = documentRoot.createElement("aside");
18
18
  root.className = "home-guidance";
@@ -42,16 +42,19 @@ export function createHomeGuidance({ container, homeRegion, client, getEnvironme
42
42
  });
43
43
  review = createDailyMemoryReview({ client, getEnvironmentId, preferences, render: (snapshot) => {
44
44
  dialog.render(snapshot);
45
- if (canOfferDailyReview(snapshot) && dialog.canOpen() && review.markOffered()) dialog.open();
45
+ if (canOfferDailyReview(snapshot) && dialog.canOpen()) void offerReview();
46
46
  renderSuggestion();
47
47
  } });
48
48
  root.querySelector("[data-guidance-open]").addEventListener("click", () => {
49
49
  if (root.hidden || !selected) return;
50
50
  onOpen(selected.id);
51
51
  });
52
- root.querySelector("[data-guidance-dismiss]").addEventListener("click", () => {
52
+ root.querySelector("[data-guidance-dismiss]").addEventListener("click", async () => {
53
53
  if (!selected) return;
54
- preferences.dismiss(environment, selected.id);
54
+ const target = environment;
55
+ try { await preferences.dismiss(environment, selected.id); }
56
+ catch { return; }
57
+ if (target !== environment || disposed) return;
55
58
  hiddenThisVisit = true;
56
59
  renderSuggestion();
57
60
  });
@@ -105,6 +108,14 @@ export function createHomeGuidance({ container, homeRegion, client, getEnvironme
105
108
  if (!visible || reviewDismissed || !snapshot.remaining) return false;
106
109
  return hasCurrentLearningActivity();
107
110
  }
111
+ async function offerReview() {
112
+ const target = environment;
113
+ try {
114
+ if (!await review.markOffered()) return;
115
+ if (target !== getEnvironmentId() || !canOfferDailyReview(review.snapshot())) return;
116
+ if (dialog.canOpen()) dialog.open();
117
+ } catch { /* The shared storage failure remains visible; no success is claimed. */ }
118
+ }
108
119
  async function openMemoryReview() {
109
120
  if (openingReview || !canReviewSavedMemories() || !dialog.canOpen()) return;
110
121
  const operation = revision;
@@ -115,7 +126,10 @@ export function createHomeGuidance({ container, homeRegion, client, getEnvironme
115
126
  if (disposed || operation !== revision || target !== getEnvironmentId()) return;
116
127
  openingReview = false;
117
128
  if (loadedReview && canReviewSavedMemories() && dialog.canOpen()) {
118
- review.markOffered();
129
+ try { await review.markOffered(); }
130
+ catch { return; }
131
+ if (disposed || operation !== revision || target !== getEnvironmentId()) return;
132
+ if (!canReviewSavedMemories() || !dialog.canOpen()) return;
119
133
  dialog.open();
120
134
  }
121
135
  renderSuggestion();
@@ -0,0 +1,53 @@
1
+ import { readSetupContextWindowFeedback } from "../runtime-setup/context-window-feedback.js";
2
+ import { MODEL_SETUP_ID } from "./rendering.js";
3
+
4
+ const CONTEXT_FIELD = '[data-runtime-setup-field="context-window"]';
5
+ const CONTEXT_ERROR_ID = `${MODEL_SETUP_ID}Error-context-window`;
6
+ const CONTEXT_HELP_ID = `${MODEL_SETUP_ID}Help-context-window`;
7
+
8
+ export function receiveModelContextWindowFeedback(state, error) {
9
+ if (state.busy !== "saving" || state.saved) return false;
10
+ if (error?.payload?.contextWindow?.profileId !== state.profileId)
11
+ return false;
12
+ const feedback = readSetupContextWindowFeedback(error);
13
+ if (!feedback) return false;
14
+ state.contextWindowFeedback = feedback;
15
+ state.step = 1;
16
+ state.error = "";
17
+ return true;
18
+ }
19
+
20
+ /** Remove only this feedback; preserve the draft and its secret input element. */
21
+ export function clearModelContextWindowFeedback(state, form) {
22
+ if (!state.contextWindowFeedback) return;
23
+ state.contextWindowFeedback = null;
24
+ const field = form.querySelector(CONTEXT_FIELD);
25
+ field?.removeAttribute("aria-invalid");
26
+ field?.setAttribute("aria-describedby", CONTEXT_HELP_ID);
27
+ field?.setAttribute("min", "1");
28
+ form.querySelector(`[id="${CONTEXT_ERROR_ID}"]`)?.remove();
29
+ }
30
+
31
+ export function renderModelContextWindowFeedback(state, form, restoreFocus) {
32
+ const feedback = state.contextWindowFeedback;
33
+ if (!feedback) return;
34
+ const field = form.querySelector(CONTEXT_FIELD);
35
+ if (!field) return;
36
+ field.setAttribute("aria-invalid", "true");
37
+ field.setAttribute(
38
+ "aria-describedby",
39
+ `${CONTEXT_HELP_ID} ${CONTEXT_ERROR_ID}`,
40
+ );
41
+ field.setAttribute("min", String(feedback.minimumTokens));
42
+ let message = form.querySelector(`[id="${CONTEXT_ERROR_ID}"]`);
43
+ if (!message) {
44
+ message = form.ownerDocument.createElement("small");
45
+ message.setAttribute("id", CONTEXT_ERROR_ID);
46
+ message.setAttribute("class", "runtime-setup-feedback error");
47
+ message.setAttribute("role", "alert");
48
+ field.parentElement.append(message);
49
+ }
50
+ message.textContent = feedback.message;
51
+ if (state.busy || state.step !== 1 || !restoreFocus) return;
52
+ field.focus();
53
+ }