@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
@@ -8,11 +8,11 @@ function sessionIds(value) {
8
8
  function readEnvironments(storage) {
9
9
  try {
10
10
  const value = JSON.parse(storage.getItem(storageKey) || "{}");
11
- if (!value || typeof value !== "object") return {};
12
- if (Array.isArray(value)) return {};
13
- return value;
11
+ if (!value || typeof value !== "object") return Object.create(null);
12
+ if (Array.isArray(value)) return Object.create(null);
13
+ return Object.assign(Object.create(null), value);
14
14
  } catch {
15
- return {};
15
+ return Object.create(null);
16
16
  }
17
17
  }
18
18
 
@@ -36,7 +36,7 @@ export function createSessionSidebarPreferences(storage) {
36
36
  configurable: true,
37
37
  writable: true,
38
38
  });
39
- storage.setItem(storageKey, JSON.stringify(environments));
39
+ return storage.setItem(storageKey, JSON.stringify(environments));
40
40
  },
41
41
  };
42
42
  }
@@ -0,0 +1,116 @@
1
+ /** The in-memory view is a projection; only the server acknowledges persistence. */
2
+ export function createWorkspaceStateStorage({ fetchImpl = fetch, onError = () => {} } = {}) {
3
+ let snapshot = null;
4
+ const lanes = new Map();
5
+ const failures = new Map();
6
+ const pending = [];
7
+ const listeners = new Set();
8
+
9
+ async function request(input) {
10
+ let response;
11
+ let result;
12
+ try {
13
+ response = await fetchImpl("/web-ui-state", input ? {
14
+ method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(input),
15
+ } : { cache: "no-store" });
16
+ result = await response.json();
17
+ } catch (error) { throw uncertainMutationError(error, input); }
18
+ if (!response.ok) throw workspaceResponseFailure(response, result, input);
19
+ if (result.state?.version !== 1 || !Number.isSafeInteger(result.state.revision) ||
20
+ !result.state.preferences || typeof result.state.queue !== "string")
21
+ throw uncertainMutationError(new Error("The server returned invalid workspace state."), input);
22
+ if (!snapshot || result.state.revision >= snapshot.revision) snapshot = result.state;
23
+ return result.result;
24
+ }
25
+ function laneFor(input) {
26
+ if (input.kind === "preference") return `preference:${input.key}`;
27
+ if (input.kind === "queue") return `queue:${JSON.stringify([input.scope.environmentId, input.scope.sessionId])}`;
28
+ return input.kind;
29
+ }
30
+ function report(error, lane) {
31
+ failures.set(lane, error);
32
+ onError(error);
33
+ }
34
+ function execute(input, completed = () => {}) {
35
+ const lane = laneFor(input);
36
+ const result = (lanes.get(lane) || Promise.resolve()).then(async () => {
37
+ if (failures.has(lane)) throw failures.get(lane);
38
+ const previousPreferences = JSON.stringify(snapshot?.preferences);
39
+ const value = await request(input);
40
+ try {
41
+ completed();
42
+ if (JSON.stringify(snapshot.preferences) !== previousPreferences)
43
+ for (const listener of listeners) listener();
44
+ } catch (error) { throw uncertainMutationError(error, input); }
45
+ return value;
46
+ });
47
+ // Ordering/failure belongs to this preference or queue scope. The acknowledged
48
+ // server snapshot remains shared; an unrelated failure is never permission to retry.
49
+ lanes.set(lane, result.then(() => undefined, (error) => report(error, lane)));
50
+ return result;
51
+ }
52
+ function getItem(key) {
53
+ const queued = pending.findLast((entry) => entry.key === key);
54
+ if (queued) return queued.value;
55
+ return snapshot?.preferences[key] ?? null;
56
+ }
57
+ function write(key, value) {
58
+ if (!snapshot) throw new Error("Workspace settings have not loaded.");
59
+ if (failures.has(`preference:${key}`)) {
60
+ const rejected = Promise.reject(failures.get(`preference:${key}`));
61
+ void rejected.catch(() => {});
62
+ return rejected;
63
+ }
64
+ const before = getItem(key);
65
+ if (before === value) return Promise.resolve();
66
+ const entry = { key, before, value };
67
+ pending.push(entry);
68
+ const discardPending = () => {
69
+ const index = pending.indexOf(entry);
70
+ if (index >= 0) pending.splice(index, 1);
71
+ };
72
+ const result = execute({ kind: "preference", ...entry }, discardPending);
73
+ void result.catch(() => {
74
+ discardPending();
75
+ for (const listener of listeners) listener();
76
+ });
77
+ return result;
78
+ }
79
+ return {
80
+ getItem,
81
+ setItem: (key, value) => write(key, String(value)),
82
+ removeItem: (key) => write(key, null),
83
+ execute,
84
+ async flush() {
85
+ await Promise.all(lanes.values());
86
+ if (failures.size) throw failures.values().next().value;
87
+ },
88
+ async refresh() {
89
+ try {
90
+ const previous = snapshot?.revision;
91
+ await request();
92
+ if (snapshot.revision !== previous) for (const listener of listeners) listener();
93
+ } catch (error) { report(error, "refresh"); throw error; }
94
+ },
95
+ subscribe(listener) { listeners.add(listener); return () => listeners.delete(listener); },
96
+ snapshot: () => snapshot,
97
+ error: () => failures.values().next().value ?? null,
98
+ };
99
+ }
100
+
101
+ function uncertainMutationError(error, input) {
102
+ if (!input) return error;
103
+ const failure = error instanceof Error ? error : new Error(String(error));
104
+ // An absent acknowledgement cannot prove a POST had no durable effect.
105
+ failure.workspaceMutationMayHaveCommitted = true;
106
+ return failure;
107
+ }
108
+
109
+ function workspaceResponseFailure(response, result, input) {
110
+ const error = new Error(result.message || "Workspace state is unavailable.");
111
+ error.status = response.status;
112
+ error.code = result.error;
113
+ if (response.status < 500) return error;
114
+ // A server failure may follow durable publication, such as lock cleanup failure.
115
+ return uncertainMutationError(error, input);
116
+ }
@@ -0,0 +1,27 @@
1
+ import { createWorkspaceStateStorage } from "./workspace-state-storage.js";
2
+ import { createServerComposerQueue } from "./server-composer-queue.js";
3
+ import { acknowledgeWorkspaceStorage, showWorkspaceStorageFailure } from "../components/workspace-storage-notice.js";
4
+ import { createStartupScreen } from "../components/startup-screen.js";
5
+
6
+ let storage;
7
+ let queue;
8
+ export const workspaceStorage = () => storage;
9
+ export const workspaceQueue = () => queue;
10
+ export function observeWorkspaceStateChange(message) {
11
+ if (message.type !== "workspace_changed" || !message.resources?.includes("client-state")) return;
12
+ void storage?.refresh().catch(showWorkspaceStorageFailure);
13
+ }
14
+
15
+ export async function initializeWorkspaceState() {
16
+ storage = createWorkspaceStateStorage({ onError: showWorkspaceStorageFailure });
17
+ try {
18
+ await storage.refresh();
19
+ await acknowledgeWorkspaceStorage(storage);
20
+ queue = createServerComposerQueue(storage);
21
+ window.addEventListener("focus", () => void storage.refresh().catch(showWorkspaceStorageFailure));
22
+ document.addEventListener("visibilitychange", () => {
23
+ if (document.visibilityState === "visible") void storage.refresh().catch(showWorkspaceStorageFailure);
24
+ });
25
+ return storage;
26
+ } catch (error) { createStartupScreen().fail(error); throw error; }
27
+ }
@@ -1,16 +1,16 @@
1
+ import { canChooseReasoning } from "./lib/reasoning-controls.js";
2
+ import { createComposerFeature } from "./controllers/composer-feature.js";
3
+ import { createComposerDrafts } from "./controllers/composer-drafts.js";
4
+ import { createComposerDraftView } from "./controllers/composer-draft-view.js";
5
+ import { workspaceQueue } from "./services/workspace-state.js";
1
6
  import { createAppState } from "./app-state.js";
2
7
  import { createConversationViewFeature } from "./controllers/conversation-view-feature.js";
3
8
  import { createConversationSessionController } from "./controllers/conversation-session-controller.js";
4
- import { createChatRequestController } from "./controllers/chat-request-controller.js";
5
- import { createComposerQueueController } from "./controllers/composer-queue-controller.js";
6
- import { createComposerSubmitController } from "./controllers/composer-submit-controller.js";
7
- import { createComposerAttachmentsController } from "./controllers/composer-attachments-controller.js";
8
9
  import { createRealtimeEventController } from "./controllers/realtime-event-controller.js";
9
10
  import { createSteerController } from "./controllers/steer-controller.js";
10
11
  import { createToolApprovalController } from "./controllers/tool-approval-controller.js";
11
12
  import { createToolApprovalCard } from "./components/tool-approval-card.js";
12
13
  import { createComposerActions } from "./components/composer-actions.js";
13
- import { createSessionComposerQueue } from "./lib/session-composer-queue.js";
14
14
  import { normalizeRealtimeMessage } from "./lib/realtime-message.js";
15
15
  import { createSparkChatResults } from "./components/spark-chat/results.js";
16
16
  import { sparkMessageStatus, sparkWorkingStatus } from "./lib/spark-chat-presentation.js";
@@ -23,24 +23,29 @@ export function createSparkChatConversation({
23
23
  dom, client, shell, getEnvironmentId, getConfiguration, isOpen, isConnected,
24
24
  getSubmissionBlock, scrollBehavior, refresh, onReadState, onRender,
25
25
  onOpenSchedule = () => {}, onOpenModelSettings = () => {},
26
- sendRealtime, onComposerStateChange = () => {}, storage = localStorage,
26
+ sendRealtime, onComposerStateChange = () => {}, sessionQueue = workspaceQueue(),
27
27
  captureHandoffNavigation, onHandoffOpened,
28
28
  }) {
29
29
  const state = createAppState();
30
- const sessionQueue = createSessionComposerQueue({ storage });
30
+ const drafts = createComposerDrafts();
31
+ const draftView = createComposerDraftView({ input: dom.composerInput,
32
+ getDraft: () => drafts.open({ environmentId: getEnvironmentId(), sessionId: state.currentSessionId }), isVisible: isOpen });
33
+ drafts.subscribe(draftView.refresh);
34
+ draftView.display();
31
35
  const mascotActivity = createSparkMascotActivity({ state, dom, isConnected });
32
36
  let session;
33
37
  let view;
34
38
  let realtime;
35
39
  let queue;
36
40
  let submit;
41
+ let attachments;
37
42
  const status = (text, busy = false) => {
38
43
  dom.messagesList.setAttribute("aria-busy", String(busy));
39
44
  dom.messageStatusRegion.textContent = sparkMessageStatus(text);
40
45
  };
41
46
  const render = () => { view?.render(); mascotActivity.render(); onRender?.(); };
42
47
  const renderActivityStatus = () => { view?.renderActivityStatus(); mascotActivity.render(); };
43
- const updateSendState = () => { submit?.updateSendState(); mascotActivity.render(); onComposerStateChange(state.composerSending); };
48
+ const updateSendState = () => { draftView.display(); submit?.updateSendState(); mascotActivity.render(); onComposerStateChange(state.composerSending); };
44
49
  const recordControlEvent = (event) => realtime?.recordControlEvent(event);
45
50
  const getToolPermissionMode = () => getConfiguration()?.toolPermissionMode || "ask";
46
51
  const getModelPreference = () => {
@@ -56,13 +61,6 @@ export function createSparkChatConversation({
56
61
  onAccepted: (message) => session.insertSteerMessage(message),
57
62
  });
58
63
  const actions = createComposerActions({ dom, onSendNext: () => submit.dispatch("send_next") });
59
- const attachments = createComposerAttachmentsController({
60
- state, dom, shell, client, selectedEnvironmentId: getEnvironmentId,
61
- selectedModelSupportsImageInput: () => getConfiguration()?.supportsImageInput === true,
62
- ensureSession: () => session.ensureSession(), onSendStateChange: updateSendState,
63
- onControlEvent: recordControlEvent,
64
- isComposerAvailable: () => !getSubmissionBlock(), isComposerVisible: isOpen,
65
- });
66
64
  const approvals = createToolApprovalController({
67
65
  state, selectedEnvironmentId: getEnvironmentId, sendRealtime,
68
66
  renderMessages: render, recordControlEvent, createCard: createToolApprovalCard,
@@ -88,7 +86,7 @@ export function createSparkChatConversation({
88
86
  getPendingApproval: approvals.pendingEvent, getPendingApprovals: approvals.pendingEvents,
89
87
  createApprovalCard: approvals.createCard,
90
88
  copyText: (text) => navigator.clipboard.writeText(text),
91
- notify: shell.showToast, resolveAttachmentUrl: attachments.previewUrl,
89
+ notify: shell.showToast, resolveAttachmentUrl: (file) => attachments.previewUrl(file),
92
90
  onOpenSchedule, canOpenSchedule: () => client.supportsSchedules?.() === true,
93
91
  scrollBehavior,
94
92
  sparkActions: createSparkHandoffActions({
@@ -113,41 +111,32 @@ export function createSparkChatConversation({
113
111
  sessionQueue, conversationView: view, selectedEnvironmentId: getEnvironmentId,
114
112
  // Reading belongs to actual visible rows in the popup, never to session activation.
115
113
  isConversationVisible: () => false,
116
- clearPendingAttachments() {}, applyConversationChrome() {}, applyModelSelection() {}, renderSessions() {},
114
+ applyConversationChrome() {}, applyModelSelection() {}, renderSessions() {},
117
115
  renderMessages: render, updateComposerSendState: updateSendState, setMessageStatus: status,
118
116
  sendRealtime, handleRealtimeMessage: (message) => realtime.handle(message),
119
117
  recordEvent: (message) => realtime.recordEvent(message), recordControlEvent,
120
118
  reportQueueFailure: (...args) => queue.reportFailure(...args),
121
119
  drainQueuedMessage: (...args) => queue.drain(...args),
122
- suspendQueueRecovery: () => queue.suspendRecoveryForNavigation(),
120
+ suspendQueueRecovery: (canNavigate) => queue.suspendRecoveryForNavigation(canNavigate),
123
121
  recoverBlockedQueue: (...args) => queue.recoverForManualSend(...args),
124
122
  isCurrentComposerScope: isScopeCurrent,
125
123
  createSessionId() { throw new Error("SPARK conversation is not ready yet."); },
126
124
  });
127
- const requests = createChatRequestController({
128
- state, client, sessionQueue, conversationView: view, conversationSession: session,
129
- attachments, currentComposerScope: scope, isCurrentComposerScope: isScopeCurrent,
130
- rememberModelSelection() {}, applyConversationChrome() {}, renderSessions() {},
131
- renderAttachments: attachments.render, getToolPermissionMode, getModelPreference,
132
- clearQueueRecovery: (...args) => queue.clearRecovery(...args),
133
- reportQueueFailure: (...args) => queue.reportFailure(...args),
134
- });
135
- queue = createComposerQueueController({
136
- state, dom, queue: sessionQueue, selectedEnvironmentId: getEnvironmentId,
137
- getToolPermissionMode, getModelPreference, rememberModelSelection() {}, attachments,
138
- updateSendState, postChatMessage: requests.postChatMessage,
139
- appendLocalUserMessage: session.appendLocalUserMessage,
140
- activateRequestForScope: session.activateRequestForScope,
141
- renderMessages: render, setMessageStatus: status, recordControlEvent,
142
- resizeComposer: () => submit.resize(),
143
- });
144
- submit = createComposerSubmitController({
145
- state, dom, composerActions: actions, attachments, queue, steer: steer.steer,
146
- chatRequests: requests, conversationSession: session,
147
- selectedEnvironmentId: getEnvironmentId, setMessageStatus: status,
148
- getSubmissionBlock, onSubmissionBlocked: (block) => shell.showToast(block.message || "SPARK is not ready.", "failed"),
149
- isComposerVisible: isOpen,
125
+ const composer = createComposerFeature({
126
+ state, dom: { ...dom, composerInput: draftView.surface }, shell, client, sessionQueue,
127
+ drafts, getDraft: draftView.current, conversationSession: session, conversationView: view,
128
+ getEnvironmentId, ensureSession: () => session.ensureSession(),
129
+ getSettings: () => ({ agentMode: state.agentMode, toolPermissionMode: getToolPermissionMode(), modelPreference: getModelPreference() }),
130
+ steer: steer.steer, composerActions: actions,
131
+ selectedModelSupportsImageInput: () => getConfiguration()?.supportsImageInput === true,
132
+ isComposerAvailable: () => !getSubmissionBlock(), getSubmissionBlock,
133
+ onSubmissionBlocked: (block) => shell.showToast(block.message || "SPARK is not ready.", "failed"),
134
+ isVisible: isOpen, renderSessions() {}, renderMessages: render, applyConversationChrome() {},
135
+ setMessageStatus: status, recordControlEvent, onChange: () => onComposerStateChange(state.composerSending),
150
136
  });
137
+ attachments = composer.attachments;
138
+ queue = composer.queue;
139
+ submit = composer.submit;
151
140
  realtime = createRealtimeEventController({
152
141
  state, shell, selectedEnvironmentId: getEnvironmentId,
153
142
  handleSteerAcknowledgement: steer.handleAcknowledgement,
@@ -201,16 +190,16 @@ export function createSparkChatConversation({
201
190
  return {
202
191
  state, session, view, attachments, render, handleRealtime, bind, queue,
203
192
  prepareEnvironmentChange: () => queue.prepareRecoveryForNavigation(),
204
- setAgentMode(mode) { state.agentMode = mode; },
193
+ setAgentMode(mode) { if (canChooseReasoning(getConfiguration())) state.agentMode = mode; },
205
194
  update() {
206
195
  state.connected = isConnected();
207
- attachments.render(); updateSendState(); renderActivityStatus();
196
+ draftView.display(); composer.changed(); updateSendState(); renderActivityStatus();
208
197
  if (!state.messages.length) render();
209
198
  },
210
199
  reset() {
211
200
  steer.rejectAll("SPARK environment changed.");
212
- attachments.clear(); session.invalidateEnvironmentLoads(); session.clearCurrentSessionView();
213
- dom.composerInput.value = "";
201
+ draftView.saveDisplayed(); session.invalidateEnvironmentLoads(); session.clearCurrentSessionView();
202
+ draftView.display();
214
203
  },
215
204
  status,
216
205
  };
@@ -122,7 +122,11 @@ export function createSparkChatFeature({ dom, state: appState, client, shell, re
122
122
  });
123
123
  panel.dom.settingsButton.addEventListener("click", openSettings);
124
124
  panel.onToggle((opened) => {
125
- if (!opened) { conversation.view.closeFilePreview(); return; }
125
+ if (!opened) {
126
+ accessRevision += 1;
127
+ conversation.view.closeFilePreview();
128
+ return;
129
+ }
126
130
  if (!isSparkAvailable()) { panel.setOpen(false, { focus: false }); return; }
127
131
  if (!restoringOpen) void open();
128
132
  });
@@ -131,7 +135,7 @@ export function createSparkChatFeature({ dom, state: appState, client, shell, re
131
135
  if (!isSparkAvailable()) return false;
132
136
  const scope = getEnvironmentId();
133
137
  const revision = accessRevision;
134
- try { await sync.refresh({ wait: true }); }
138
+ try { await sync.refresh({ wait: true, consolidated: true }); }
135
139
  catch (error) {
136
140
  if (!canCompleteSparkOpening(scope, revision)) return false;
137
141
  shell.showToast(`SPARK could not be opened: ${error.message}`, "failed");
@@ -219,13 +223,15 @@ export function createSparkChatFeature({ dom, state: appState, client, shell, re
219
223
  const revision = accessRevision;
220
224
  try { if (!configuration) await sync.refresh({ wait: true }); }
221
225
  catch (error) {
222
- if (!canCompleteSparkOpening(scope, revision)) return false;
226
+ if (!canCompleteSparkOpening(scope, revision)) return true;
223
227
  shell.showToast(`SPARK could not be opened: ${error.message}`, "failed");
224
228
  return true;
225
229
  }
226
230
  if (!canCompleteSparkOpening(scope, revision)) return true;
227
231
  if (sessionId !== configuration?.sessionId) return false;
228
- return open(messageId, reference);
232
+ const opened = await open(messageId, reference);
233
+ if (!canCompleteSparkOpening(scope, revision)) return true;
234
+ return opened;
229
235
  },
230
236
  bind() {
231
237
  conversation.bind();
@@ -366,3 +366,19 @@
366
366
  display: none;
367
367
  }
368
368
  }
369
+
370
+ /* The reasoning permission prompt shares the composer's anchored menu surface. */
371
+ .agent-mode-menu.reasoning-override-menu {
372
+ width: min(340px, calc(100vw - 32px));
373
+ padding: 16px;
374
+ }
375
+ .reasoning-override-prompt { display: grid; gap: 12px; }
376
+ .reasoning-override-prompt p { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.55; }
377
+ .reasoning-override-prompt strong { font-size: 13px; }
378
+ .reasoning-override-prompt small { color: var(--muted); font-size: 11px; line-height: 1.5; }
379
+ .reasoning-override-actions { display: grid; gap: 8px; }
380
+ .reasoning-override-actions button { padding: 8px 12px; text-align: left; border: 1px solid var(--line); border-radius: 7px; background: transparent; color: var(--text); font: inherit; font-size: 12px; }
381
+ .reasoning-override-actions button:first-child { color: var(--accent); }
382
+ .reasoning-override-actions button:hover:not(:disabled) { background: var(--panel); }
383
+ .reasoning-override-actions button:disabled { opacity: .5; cursor: default; }
384
+ .reasoning-override-prompt .error-text { color: var(--danger); }
@@ -381,3 +381,11 @@
381
381
  gap: 8px;
382
382
  flex-wrap: wrap;
383
383
  }
384
+
385
+ .plugin-platform-notice {
386
+ margin: 8px 0;
387
+ color: var(--amber);
388
+ font-size: var(--font-size-xs);
389
+ line-height: 1.5;
390
+ overflow-wrap: anywhere;
391
+ }
@@ -37,6 +37,7 @@
37
37
  }
38
38
 
39
39
  .model-plugin-summary-count,
40
+ .model-plugin-platform-note,
40
41
  .model-plugin-global-note {
41
42
  color: var(--muted);
42
43
  font-size: var(--font-size-xs);
@@ -0,0 +1,30 @@
1
+ .collection-consent-dialog .collection-consent-acknowledgment {
2
+ display: flex;
3
+ align-items: flex-start;
4
+ gap: 10px;
5
+ margin-top: 18px;
6
+ color: var(--text);
7
+ font-size: 13px;
8
+ line-height: 1.5;
9
+ cursor: pointer;
10
+ }
11
+ .collection-consent-acknowledgment input[type="checkbox"] {
12
+ appearance: auto;
13
+ flex: 0 0 16px;
14
+ width: 16px;
15
+ height: 16px;
16
+ min-height: 16px;
17
+ margin: 2px 0 0;
18
+ border-radius: 2px;
19
+ accent-color: var(--accent);
20
+ cursor: pointer;
21
+ }
22
+ .collection-consent-acknowledgment span {
23
+ min-width: 0;
24
+ overflow-wrap: anywhere;
25
+ }
26
+ .collection-consent-acknowledgment a {
27
+ color: var(--accent);
28
+ text-decoration: underline;
29
+ text-underline-offset: 2px;
30
+ }
@@ -0,0 +1,23 @@
1
+ .workspace-storage-notice {
2
+ color: var(--text); background: var(--bg); border: 1px solid var(--line);
3
+ border-radius: 12px; padding: 24px; max-width: min(540px, calc(100vw - 40px));
4
+ line-height: 1.6;
5
+ }
6
+ .workspace-storage-notice::backdrop { background: #0009; }
7
+ .workspace-storage-notice h2 { margin-top: 0; }
8
+ .workspace-storage-notice button { margin-top: 8px; }
9
+ .workspace-storage-failure {
10
+ position: fixed; z-index: 10000; bottom: 16px; left: 16px; right: 16px;
11
+ padding: 12px 16px; color: var(--text); background: var(--panel);
12
+ border: 1px solid #ed9b91; border-radius: 8px;
13
+ }
14
+
15
+ .composer-submission-notice {
16
+ grid-column: 1 / -1; width: 100%; color: var(--text-muted); font-size: 12px;
17
+ }
18
+ .composer-submission-notice[hidden] { display: none; }
19
+ .composer-submission-notice > div {
20
+ display: flex; align-items: center; gap: 12px; justify-content: space-between;
21
+ padding: 8px 12px; border: 1px solid var(--line); border-radius: 8px;
22
+ }
23
+ .composer-submission-notice button { flex-shrink: 0; }
@@ -53,6 +53,7 @@
53
53
  @import url("./styles/43-co-worker-applications.css");
54
54
  @import url("./styles/48-notifications.css");
55
55
  @import url("./styles/49-macos-permission.css");
56
+ @import url("./styles/49-collection-consent.css");
56
57
  @import url("./styles/50-automations.css");
57
58
  @import url("./styles/51-automation-editor-actions.css");
58
59
  @import url("./styles/51-automation-templates.css");
@@ -61,3 +62,4 @@
61
62
  @import url("./styles/53-automation-schema-inputs.css");
62
63
  @import url("./styles/54-spark-chat.css");
63
64
  @import url("./styles/94-automations-responsive.css");
65
+ @import url("./styles/64-workspace-storage.css");
@@ -0,0 +1,15 @@
1
+ /** Installation-owned UI state. These records never become model context. */
2
+ export type ClientPreferences = Record<string, string>;
3
+ export type ClientState = {
4
+ version: 1;
5
+ revision: number;
6
+ introductionSeen: boolean;
7
+ preferences: ClientPreferences;
8
+ queue: string;
9
+ };
10
+ export declare function emptyClientState(): ClientState;
11
+ export declare class ClientStateError extends Error {
12
+ readonly code: string;
13
+ readonly status: number;
14
+ constructor(code: string, message: string, status?: number);
15
+ }
@@ -0,0 +1,13 @@
1
+ export function emptyClientState() {
2
+ return { version: 1, revision: 0, introductionSeen: false,
3
+ preferences: { "abot-web.lastToolPermissionMode": "ask" }, queue: "" };
4
+ }
5
+ export class ClientStateError extends Error {
6
+ code;
7
+ status;
8
+ constructor(code, message, status = 400) {
9
+ super(message);
10
+ this.code = code;
11
+ this.status = status;
12
+ }
13
+ }
@@ -0,0 +1,2 @@
1
+ export declare function isPreferenceObject(value: unknown): value is Record<string, unknown>;
2
+ export declare function assertPreferenceShape(key: string, value: unknown): void;
@@ -0,0 +1,80 @@
1
+ import { ClientStateError } from "./contracts.js";
2
+ const modes = new Set(["ask", "full_access", "full_plus"]);
3
+ export function isPreferenceObject(value) {
4
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5
+ }
6
+ function isStringList(value) {
7
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
8
+ }
9
+ function hasOnlyFields(value, fields) {
10
+ return Object.keys(value).every((key) => fields.includes(key));
11
+ }
12
+ function isSessionMode(value) {
13
+ if (!isPreferenceObject(value))
14
+ return false;
15
+ if (!hasOnlyFields(value, ["toolPermissionMode", "savedAt"]))
16
+ return false;
17
+ if (typeof value.toolPermissionMode !== "string" || !modes.has(value.toolPermissionMode))
18
+ return false;
19
+ return Number.isFinite(value.savedAt);
20
+ }
21
+ function isSidebarPreference(value) {
22
+ if (!isPreferenceObject(value))
23
+ return false;
24
+ if (!hasOnlyFields(value, ["archivedSessionIds", "orderedSessionIds"]))
25
+ return false;
26
+ return isStringList(value.archivedSessionIds) && isStringList(value.orderedSessionIds);
27
+ }
28
+ function isLauncherPosition(value) {
29
+ if (!isPreferenceObject(value))
30
+ return false;
31
+ if (!hasOnlyFields(value, ["x", "y"]))
32
+ return false;
33
+ return Number.isFinite(value.x) && Number.isFinite(value.y);
34
+ }
35
+ function isGuidancePreference(value) {
36
+ if (!isPreferenceObject(value))
37
+ return false;
38
+ if (!hasOnlyFields(value, ["offeredOn", "dismissed", "reviewed"]))
39
+ return false;
40
+ if (value.offeredOn !== undefined && typeof value.offeredOn !== "string")
41
+ return false;
42
+ if (value.dismissed !== undefined && (!isStringList(value.dismissed) || value.dismissed.length > 8))
43
+ return false;
44
+ if (value.reviewed === undefined)
45
+ return true;
46
+ if (!Array.isArray(value.reviewed) || value.reviewed.length > 200)
47
+ return false;
48
+ const seen = new Set();
49
+ for (const item of value.reviewed) {
50
+ if (!isPreferenceObject(item))
51
+ return false;
52
+ if (!hasOnlyFields(item, ["id", "updatedAt"]))
53
+ return false;
54
+ if (typeof item.id !== "string" || typeof item.updatedAt !== "string")
55
+ return false;
56
+ if (seen.has(item.id))
57
+ return false;
58
+ seen.add(item.id);
59
+ }
60
+ return true;
61
+ }
62
+ function hasPreferenceShape(key, value) {
63
+ if (key === "abot-web.pinnedSessions")
64
+ return isStringList(value);
65
+ if (key === "abot.spark.launcher.position.v1")
66
+ return isLauncherPosition(value);
67
+ if (key.startsWith("abot-web.homeGuidance."))
68
+ return isGuidancePreference(value);
69
+ if (!isPreferenceObject(value))
70
+ return false;
71
+ if (key === "abot-web.sessionModes")
72
+ return Object.values(value).every(isSessionMode);
73
+ if (key === "abot-web.sessionSidebarByEnvironment")
74
+ return Object.values(value).every(isSidebarPreference);
75
+ return Object.values(value).every((item) => typeof item === "string");
76
+ }
77
+ export function assertPreferenceShape(key, value) {
78
+ if (!hasPreferenceShape(key, value))
79
+ throw new ClientStateError("invalid_preferences", "Invalid workspace preferences or unbounded memory review receipts.");
80
+ }
@@ -0,0 +1,3 @@
1
+ import { type ClientPreferences } from "./contracts.js";
2
+ export declare function decodePreference(key: string, value: unknown): unknown;
3
+ export declare function updatePreference(preferences: ClientPreferences, input: Record<string, unknown>): void;