@abot-ai/runtime 1.7.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (532) hide show
  1. package/README.md +216 -222
  2. package/dist/src/capabilities/tool-definition-validator/definition-parser.js +8 -0
  3. package/dist/src/capabilities/tool-request-resources.d.ts +3 -0
  4. package/dist/src/capabilities/tool-types.d.ts +4 -0
  5. package/dist/src/cli/abot.js +2 -0
  6. package/dist/src/cli/host-companion-bundle.mjs +751 -333
  7. package/dist/src/computer-access/collection-consent.d.ts +9 -0
  8. package/dist/src/computer-access/collection-consent.js +47 -0
  9. package/dist/src/computer-access/command-output-capture.d.ts +17 -6
  10. package/dist/src/computer-access/command-output-capture.js +134 -68
  11. package/dist/src/computer-access/command-output-protection.d.ts +17 -0
  12. package/dist/src/computer-access/command-output-protection.js +59 -0
  13. package/dist/src/computer-access/companion/command-output.d.ts +1 -0
  14. package/dist/src/computer-access/companion/command-output.js +23 -6
  15. package/dist/src/computer-access/companion/install-link-macos.js +2 -1
  16. package/dist/src/computer-access/companion/native-notifications.js +3 -2
  17. package/dist/src/computer-access/companion/native-session.js +6 -2
  18. package/dist/src/computer-access/companion/observation-filter.js +2 -26
  19. package/dist/src/computer-access/companion/observation-process.d.ts +2 -0
  20. package/dist/src/computer-access/companion/observation-process.js +51 -25
  21. package/dist/src/computer-access/companion/observation-redaction.d.ts +2 -7
  22. package/dist/src/computer-access/companion/observation-redaction.js +2 -111
  23. package/dist/src/computer-access/companion/secret-protection-protocol.d.ts +6 -0
  24. package/dist/src/computer-access/companion/secret-protection-protocol.js +6 -0
  25. package/dist/src/computer-access/computer/companion-sessions.js +7 -6
  26. package/dist/src/computer-access/computer/unix-native-process.js +23 -11
  27. package/dist/src/computer-access/handlers.d.ts +2 -1
  28. package/dist/src/computer-access/handlers.js +79 -11
  29. package/dist/src/computer-access/host-observation.d.ts +3 -3
  30. package/dist/src/computer-access/native-observation-connection.d.ts +12 -0
  31. package/dist/src/computer-access/native-observation-connection.js +78 -0
  32. package/dist/src/computer-access/native-observation-ownership.d.ts +6 -0
  33. package/dist/src/computer-access/native-observation-ownership.js +55 -0
  34. package/dist/src/computer-access/native-observation-shutdown.d.ts +7 -0
  35. package/dist/src/computer-access/native-observation-shutdown.js +58 -0
  36. package/dist/src/computer-access/observation-source.d.ts +6 -0
  37. package/dist/src/computer-access/observation-source.js +10 -0
  38. package/dist/src/computer-access/security/desktop-result.d.ts +8 -0
  39. package/dist/src/computer-access/security/desktop-result.js +146 -0
  40. package/dist/src/computer-access/security/observed-error.d.ts +2 -0
  41. package/dist/src/computer-access/security/observed-error.js +10 -0
  42. package/dist/src/computer-access/security/secret-text.d.ts +7 -0
  43. package/dist/src/computer-access/security/secret-text.js +111 -0
  44. package/dist/src/computer-access/security/system-results.d.ts +2 -0
  45. package/dist/src/computer-access/security/system-results.js +53 -0
  46. package/dist/src/computer-access/system-result-protection.d.ts +11 -0
  47. package/dist/src/computer-access/system-result-protection.js +1 -0
  48. package/dist/src/model-gateway/observability/provider-response-capture.d.ts +60 -0
  49. package/dist/src/model-gateway/observability/provider-response-capture.js +68 -0
  50. package/dist/src/model-gateway/observability/provider-response-prefix.d.ts +7 -0
  51. package/dist/src/model-gateway/observability/provider-response-prefix.js +14 -0
  52. package/dist/src/model-gateway/observability/provider-response-tail.d.ts +8 -0
  53. package/dist/src/model-gateway/observability/provider-response-tail.js +28 -0
  54. package/dist/src/model-gateway/observability/provider-sse-diagnostics.d.ts +30 -0
  55. package/dist/src/model-gateway/observability/provider-sse-diagnostics.js +119 -0
  56. package/dist/src/model-gateway/observability/provider-trace.js +30 -8
  57. package/dist/src/model-gateway/protocol/message-contract.d.ts +1 -0
  58. package/dist/src/model-gateway/protocol/message-contract.js +1 -1
  59. package/dist/src/model-gateway/providers/ollama/adapter.js +8 -2
  60. package/dist/src/model-gateway/providers/ollama/stream-normalizer.js +70 -50
  61. package/dist/src/model-gateway/providers/ollama/stream-termination.d.ts +6 -0
  62. package/dist/src/model-gateway/providers/ollama/stream-termination.js +20 -0
  63. package/dist/src/model-gateway/providers/openai/adapter.js +9 -7
  64. package/dist/src/model-gateway/providers/openai/diagnostics.d.ts +0 -1
  65. package/dist/src/model-gateway/providers/openai/diagnostics.js +0 -9
  66. package/dist/src/model-gateway/providers/openai/function-output.d.ts +11 -0
  67. package/dist/src/model-gateway/providers/openai/function-output.js +37 -0
  68. package/dist/src/model-gateway/providers/openai/function-result.d.ts +7 -0
  69. package/dist/src/model-gateway/providers/openai/function-result.js +35 -0
  70. package/dist/src/model-gateway/providers/openai/message-output-policy.d.ts +3 -0
  71. package/dist/src/model-gateway/providers/openai/message-output-policy.js +16 -0
  72. package/dist/src/model-gateway/providers/openai/payload.d.ts +0 -2
  73. package/dist/src/model-gateway/providers/openai/payload.js +6 -23
  74. package/dist/src/model-gateway/providers/openai/response-lifetime.d.ts +2 -0
  75. package/dist/src/model-gateway/providers/openai/response-lifetime.js +64 -0
  76. package/dist/src/model-gateway/providers/openai/sse-data.d.ts +9 -0
  77. package/dist/src/model-gateway/providers/openai/sse-data.js +67 -0
  78. package/dist/src/model-gateway/providers/openai/stream-normalizer.d.ts +10 -22
  79. package/dist/src/model-gateway/providers/openai/stream-normalizer.js +78 -79
  80. package/dist/src/model-gateway/providers/openai/stream.js +13 -41
  81. package/dist/src/model-gateway/providers/openai/structured-message-output.d.ts +42 -0
  82. package/dist/src/model-gateway/providers/openai/structured-message-output.js +175 -0
  83. package/dist/src/model-gateway/server/chat-handler.js +5 -7
  84. package/dist/src/model-gateway/server/chat-stream-response.d.ts +7 -0
  85. package/dist/src/model-gateway/server/chat-stream-response.js +25 -0
  86. package/dist/src/model-gateway/server.js +5 -1
  87. package/dist/src/plugin-contract/index.d.ts +1 -0
  88. package/dist/src/plugin-contract/index.js +1 -0
  89. package/dist/src/plugin-contract/manifest.d.ts +2 -0
  90. package/dist/src/plugin-contract/manifest.js +1 -0
  91. package/dist/src/plugin-contract/platform-compatibility.d.ts +16 -0
  92. package/dist/src/plugin-contract/platform-compatibility.js +3 -0
  93. package/dist/src/plugin-sdk/computer-access.d.ts +4 -0
  94. package/dist/src/plugin-sdk/computer-access.js +1 -0
  95. package/dist/src/plugin-sdk/files-windows/process.d.ts +3 -0
  96. package/dist/src/plugin-sdk/files-windows/process.js +93 -0
  97. package/dist/src/plugin-sdk/files-windows/read-script.d.ts +1 -0
  98. package/dist/src/plugin-sdk/files-windows/read-script.js +43 -0
  99. package/dist/src/plugin-sdk/files-windows/read.d.ts +6 -0
  100. package/dist/src/plugin-sdk/files-windows/read.js +56 -0
  101. package/dist/src/plugin-sdk/files-windows/result.d.ts +4 -0
  102. package/dist/src/plugin-sdk/files-windows/result.js +67 -0
  103. package/dist/src/plugin-sdk/files.js +4 -0
  104. package/dist/src/plugin-sdk/index.d.ts +1 -0
  105. package/dist/src/plugin-sdk/index.js +1 -0
  106. package/dist/src/plugin-sdk/mutation-result.d.ts +7 -0
  107. package/dist/src/plugin-sdk/mutation-result.js +11 -0
  108. package/dist/src/runtime/adapters/long-term-memory/file-lock/acquisition.js +20 -3
  109. package/dist/src/runtime/adapters/long-term-memory/file-lock/owner-record.js +3 -1
  110. package/dist/src/runtime/adapters/long-term-memory/file-lock/path-observation.d.ts +3 -0
  111. package/dist/src/runtime/adapters/long-term-memory/file-lock/path-observation.js +20 -0
  112. package/dist/src/runtime/adapters/long-term-memory/file-lock/snapshot.js +7 -3
  113. package/dist/src/runtime/adapters/passive-learning-runtime.d.ts +1 -1
  114. package/dist/src/runtime/adapters/passive-learning-runtime.js +3 -3
  115. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-rejection.d.ts +2 -2
  116. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-rejection.js +2 -2
  117. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/prepared-execution.js +17 -11
  118. package/dist/src/runtime/adapters/runtime-observation-connection.d.ts +5 -0
  119. package/dist/src/runtime/adapters/runtime-observation-connection.js +13 -0
  120. package/dist/src/runtime/capabilities/tool-availability.js +6 -0
  121. package/dist/src/runtime/context/capability-brief.d.ts +2 -2
  122. package/dist/src/runtime/context/capability-brief.js +3 -3
  123. package/dist/src/runtime/context/capability-descriptions.d.ts +3 -2
  124. package/dist/src/runtime/context/capability-descriptions.js +57 -20
  125. package/dist/src/runtime/local-host/windows-private-access.js +2 -0
  126. package/dist/src/runtime/long-term-memory/conversation-authoring/context.d.ts +6 -1
  127. package/dist/src/runtime/long-term-memory/conversation-authoring/context.js +51 -25
  128. package/dist/src/runtime/long-term-memory/initial-context.d.ts +17 -0
  129. package/dist/src/runtime/long-term-memory/initial-context.js +57 -0
  130. package/dist/src/runtime/long-term-memory/projection.js +1 -1
  131. package/dist/src/runtime/orchestration/role-calls/candidate-validation.js +2 -1
  132. package/dist/src/runtime/orchestration/role-calls/checkpoint-state.d.ts +1 -1
  133. package/dist/src/runtime/orchestration/role-calls/checkpoint-state.js +5 -2
  134. package/dist/src/runtime/orchestration/role-calls/contracts.d.ts +2 -1
  135. package/dist/src/runtime/orchestration/role-calls/ledger.d.ts +2 -1
  136. package/dist/src/runtime/orchestration/role-calls/ledger.js +2 -2
  137. package/dist/src/runtime/orchestration/role-calls/memory-recall-contract.d.ts +7 -0
  138. package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.d.ts +2 -0
  139. package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.js +88 -0
  140. package/dist/src/runtime/orchestration/role-calls/reducer.d.ts +1 -1
  141. package/dist/src/runtime/orchestration/role-calls/reducer.js +2 -1
  142. package/dist/src/runtime/orchestration/worker-capabilities/contracts.d.ts +3 -1
  143. package/dist/src/runtime/orchestration/worker-capabilities/contracts.js +1 -1
  144. package/dist/src/runtime/orchestration/worker-capabilities/execution/approval-group.js +5 -1
  145. package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.d.ts +5 -0
  146. package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.js +31 -0
  147. package/dist/src/runtime/passive-learning/application-catalog.js +3 -1
  148. package/dist/src/runtime/passive-learning/collection-source.js +7 -0
  149. package/dist/src/runtime/passive-learning/service.js +2 -3
  150. package/dist/src/runtime/passive-learning/status-projection.d.ts +2 -0
  151. package/dist/src/runtime/passive-learning/status-projection.js +9 -0
  152. package/dist/src/runtime/plugins/installation/package.d.ts +8 -0
  153. package/dist/src/runtime/plugins/installation/package.js +2 -0
  154. package/dist/src/runtime/plugins/installation/service.d.ts +7 -0
  155. package/dist/src/runtime/plugins/loader.js +24 -14
  156. package/dist/src/runtime/plugins/manifest-platform-compatibility.d.ts +2 -0
  157. package/dist/src/runtime/plugins/manifest-platform-compatibility.js +39 -0
  158. package/dist/src/runtime/plugins/manifest-projection.js +3 -0
  159. package/dist/src/runtime/plugins/manifest-validator.js +9 -1
  160. package/dist/src/runtime/plugins/platform-compatibility.d.ts +4 -0
  161. package/dist/src/runtime/plugins/platform-compatibility.js +44 -0
  162. package/dist/src/runtime/request/approval-wait/activation-events.js +19 -7
  163. package/dist/src/runtime/request/approval-wait/execution-compaction-restore.d.ts +20 -0
  164. package/dist/src/runtime/request/approval-wait/execution-compaction-restore.js +118 -0
  165. package/dist/src/runtime/request/approval-wait/super-compaction-restore.js +2 -1
  166. package/dist/src/runtime/request/capability-execution-freshness.js +6 -1
  167. package/dist/src/runtime/request/execution-agent-root-execution.js +11 -1
  168. package/dist/src/runtime/request/prepared-execution.js +3 -0
  169. package/dist/src/runtime/request/root-contract.d.ts +2 -0
  170. package/dist/src/runtime/request/root-execution-kernel.js +1 -0
  171. package/dist/src/runtime/request/runner.js +9 -3
  172. package/dist/src/runtime/request/supervisor-root-execution.js +6 -0
  173. package/dist/src/runtime/steps/execution-agent/capability-result-context.d.ts +6 -0
  174. package/dist/src/runtime/steps/execution-agent/capability-result-context.js +29 -0
  175. package/dist/src/runtime/steps/execution-agent/contracts.d.ts +10 -0
  176. package/dist/src/runtime/steps/execution-agent/decision-parsing.js +13 -1
  177. package/dist/src/runtime/steps/execution-agent/direct-response-configuration.d.ts +3 -0
  178. package/dist/src/runtime/steps/execution-agent/direct-response-configuration.js +64 -0
  179. package/dist/src/runtime/steps/execution-agent/direct-response-contract.d.ts +7 -0
  180. package/dist/src/runtime/steps/execution-agent/direct-response-contract.js +56 -0
  181. package/dist/src/runtime/steps/execution-agent/direct-response-policy.d.ts +9 -0
  182. package/dist/src/runtime/steps/execution-agent/direct-response-policy.js +30 -0
  183. package/dist/src/runtime/steps/execution-agent/direct-response-prompt.d.ts +7 -0
  184. package/dist/src/runtime/steps/execution-agent/direct-response-prompt.js +43 -0
  185. package/dist/src/runtime/steps/execution-agent/format.js +4 -3
  186. package/dist/src/runtime/steps/execution-agent/input.d.ts +2 -0
  187. package/dist/src/runtime/steps/execution-agent/input.js +22 -1
  188. package/dist/src/runtime/steps/execution-agent/plugin-catalog.d.ts +4 -0
  189. package/dist/src/runtime/steps/execution-agent/plugin-catalog.js +8 -0
  190. package/dist/src/runtime/steps/execution-agent/prompt.d.ts +1 -0
  191. package/dist/src/runtime/steps/execution-agent/prompt.js +7 -8
  192. package/dist/src/runtime/steps/execution-agent/response-prompt.js +1 -0
  193. package/dist/src/runtime/steps/execution-agent/response-run.js +5 -11
  194. package/dist/src/runtime/steps/execution-agent/run.js +4 -1
  195. package/dist/src/runtime/steps/execution-agent/state-context.d.ts +3 -5
  196. package/dist/src/runtime/steps/execution-agent/state-context.js +5 -51
  197. package/dist/src/runtime/steps/execution-agent/work-plan-contract.d.ts +1 -3
  198. package/dist/src/runtime/steps/execution-agent/work-plan-contract.js +0 -55
  199. package/dist/src/runtime/steps/execution-agent/work-plan-schema.d.ts +3 -0
  200. package/dist/src/runtime/steps/execution-agent/work-plan-schema.js +61 -0
  201. package/dist/src/runtime/steps/planner-decision/capability-brief.d.ts +2 -0
  202. package/dist/src/runtime/steps/planner-decision/prompt.js +26 -49
  203. package/dist/src/runtime/steps/supervisor-decision/input.d.ts +1 -0
  204. package/dist/src/runtime/steps/supervisor-decision/input.js +5 -0
  205. package/dist/src/runtime/steps/supervisor-decision/prompt.d.ts +1 -0
  206. package/dist/src/runtime/steps/supervisor-decision/prompt.js +6 -2
  207. package/dist/src/runtime/steps/supervisor-decision/run.d.ts +1 -0
  208. package/dist/src/runtime/steps/supervisor-decision/run.js +4 -0
  209. package/dist/src/runtime/steps/supervisor-response/run.d.ts +2 -0
  210. package/dist/src/runtime/steps/supervisor-response/run.js +3 -6
  211. package/dist/src/sessions/durable-session-commit.js +3 -3
  212. package/dist/src/sessions/prepared-session-replacement.d.ts +6 -0
  213. package/dist/src/sessions/prepared-session-replacement.js +46 -0
  214. package/dist/src/sessions/session-store.js +3 -3
  215. package/dist/src/shared/passive-observation-self-exclusion.d.ts +5 -0
  216. package/dist/src/shared/passive-observation-self-exclusion.js +37 -0
  217. package/dist/src/shared/windows-file-io/authority-script.d.ts +1 -0
  218. package/dist/src/shared/windows-file-io/authority-script.js +94 -0
  219. package/dist/src/shared/windows-file-io/native-script.d.ts +2 -0
  220. package/dist/src/shared/windows-file-io/native-script.js +120 -0
  221. package/dist/src/shared/windows-file-io/read-bytes-script.d.ts +1 -0
  222. package/dist/src/shared/windows-file-io/read-bytes-script.js +18 -0
  223. package/dist/src/shared/windows-job-object.d.ts +2 -0
  224. package/dist/src/shared/windows-job-object.js +66 -0
  225. package/dist/src/web-ui/app/ARCHITECTURE.md +1 -1
  226. package/dist/src/web-ui/app/app-bootstrap.js +14 -1
  227. package/dist/src/web-ui/app/app-state.js +0 -7
  228. package/dist/src/web-ui/app/app.js +54 -156
  229. package/dist/src/web-ui/app/components/automations/node-inspector.js +3 -2
  230. package/dist/src/web-ui/app/components/automations/step-editor-dialog.js +3 -0
  231. package/dist/src/web-ui/app/components/automations/timeline.js +3 -2
  232. package/dist/src/web-ui/app/components/composer-submission-notice.js +50 -0
  233. package/dist/src/web-ui/app/components/config-workspace/model-plugin-permissions.js +7 -1
  234. package/dist/src/web-ui/app/components/config-workspace/workspace-mutations.js +22 -2
  235. package/dist/src/web-ui/app/components/dashboard/compact-layout.js +137 -0
  236. package/dist/src/web-ui/app/components/dashboard/icons.js +5 -0
  237. package/dist/src/web-ui/app/components/dashboard/widget-card.js +85 -0
  238. package/dist/src/web-ui/app/components/dashboard/widget-dialog.js +83 -0
  239. package/dist/src/web-ui/app/components/dashboard/widget-summaries.js +155 -0
  240. package/dist/src/web-ui/app/components/dashboard/workspace.js +28 -4
  241. package/dist/src/web-ui/app/components/home-guidance/daily-review.js +2 -2
  242. package/dist/src/web-ui/app/components/home-guidance/home-guidance.js +20 -6
  243. package/dist/src/web-ui/app/components/model-setup/context-window-feedback.js +53 -0
  244. package/dist/src/web-ui/app/components/model-setup/save-flow.js +3 -1
  245. package/dist/src/web-ui/app/components/model-setup/save-outcome.js +1 -0
  246. package/dist/src/web-ui/app/components/model-setup/wizard.js +12 -0
  247. package/dist/src/web-ui/app/components/operations-summary.js +2 -1
  248. package/dist/src/web-ui/app/components/passive-learning/activity-controls.js +4 -0
  249. package/dist/src/web-ui/app/components/passive-learning/collection-access.js +35 -0
  250. package/dist/src/web-ui/app/components/passive-learning/collection-consent-dialog.js +59 -0
  251. package/dist/src/web-ui/app/components/passive-learning/collection-consent-gate.js +94 -0
  252. package/dist/src/web-ui/app/components/passive-learning/computer-update-notice.js +6 -0
  253. package/dist/src/web-ui/app/components/passive-learning/failure-copy.js +1 -0
  254. package/dist/src/web-ui/app/components/passive-learning/home-widget-preview.js +32 -0
  255. package/dist/src/web-ui/app/components/passive-learning/home.js +11 -3
  256. package/dist/src/web-ui/app/components/passive-learning/macos-collection-restart-notice.js +1 -0
  257. package/dist/src/web-ui/app/components/passive-learning/memory.js +2 -4
  258. package/dist/src/web-ui/app/components/passive-learning/workspace-view.js +2 -2
  259. package/dist/src/web-ui/app/components/plugins/compatibility.js +13 -0
  260. package/dist/src/web-ui/app/components/plugins/discovery-rendering.js +9 -1
  261. package/dist/src/web-ui/app/components/plugins/installation-compatibility.js +7 -0
  262. package/dist/src/web-ui/app/components/plugins/installation.js +2 -1
  263. package/dist/src/web-ui/app/components/plugins/rendering.js +3 -0
  264. package/dist/src/web-ui/app/components/reasoning-override-prompt.js +82 -0
  265. package/dist/src/web-ui/app/components/runtime-config-activation.js +22 -8
  266. package/dist/src/web-ui/app/components/runtime-setup/optional-steps.js +7 -4
  267. package/dist/src/web-ui/app/components/runtime-setup/plugins.js +3 -1
  268. package/dist/src/web-ui/app/components/runtime-setup/rendering.js +6 -4
  269. package/dist/src/web-ui/app/components/runtime-setup-guide.d.ts +1 -0
  270. package/dist/src/web-ui/app/components/schedules/details.js +3 -2
  271. package/dist/src/web-ui/app/components/schedules/form.js +10 -8
  272. package/dist/src/web-ui/app/components/schedules/workspace.js +23 -4
  273. package/dist/src/web-ui/app/components/session-sidebar-sections.js +2 -2
  274. package/dist/src/web-ui/app/components/spark-chat/handoff-actions.js +9 -3
  275. package/dist/src/web-ui/app/components/spark-chat/panel.js +1 -1
  276. package/dist/src/web-ui/app/components/spark-chat/placement.js +4 -7
  277. package/dist/src/web-ui/app/components/spark-chat/settings.js +8 -4
  278. package/dist/src/web-ui/app/components/system-host/home-widget-permission-preview.js +75 -0
  279. package/dist/src/web-ui/app/components/system-host/home-widget-summary.js +93 -0
  280. package/dist/src/web-ui/app/components/system-host/macos-permission-rendering.js +2 -2
  281. package/dist/src/web-ui/app/components/system-host/macos-permissions.js +2 -0
  282. package/dist/src/web-ui/app/components/system-host/native-windows-access.js +50 -0
  283. package/dist/src/web-ui/app/components/system-host/rendering.js +6 -3
  284. package/dist/src/web-ui/app/components/system-host/windows-store-setup.js +2 -2
  285. package/dist/src/web-ui/app/components/workspace-storage-notice.js +37 -0
  286. package/dist/src/web-ui/app/computer-access-feature.js +13 -1
  287. package/dist/src/web-ui/app/configuration-environment-refresh.js +27 -34
  288. package/dist/src/web-ui/app/configuration-feature.js +11 -1
  289. package/dist/src/web-ui/app/controllers/app-event-bindings.js +38 -105
  290. package/dist/src/web-ui/app/controllers/chat-request-controller.d.ts +28 -0
  291. package/dist/src/web-ui/app/controllers/chat-request-controller.js +34 -66
  292. package/dist/src/web-ui/app/controllers/composer-attachments-controller.d.ts +15 -40
  293. package/dist/src/web-ui/app/controllers/composer-attachments-controller.js +26 -69
  294. package/dist/src/web-ui/app/controllers/composer-draft-view.d.ts +27 -0
  295. package/dist/src/web-ui/app/controllers/composer-draft-view.js +48 -0
  296. package/dist/src/web-ui/app/controllers/composer-drafts.d.ts +55 -0
  297. package/dist/src/web-ui/app/controllers/composer-drafts.js +120 -0
  298. package/dist/src/web-ui/app/controllers/composer-feature.d.ts +65 -0
  299. package/dist/src/web-ui/app/controllers/composer-feature.js +124 -0
  300. package/dist/src/web-ui/app/controllers/composer-queue-controller.d.ts +33 -94
  301. package/dist/src/web-ui/app/controllers/composer-queue-controller.js +185 -251
  302. package/dist/src/web-ui/app/controllers/composer-submission-lifecycle.d.ts +48 -0
  303. package/dist/src/web-ui/app/controllers/composer-submission-lifecycle.js +97 -0
  304. package/dist/src/web-ui/app/controllers/composer-submit-controller.d.ts +30 -61
  305. package/dist/src/web-ui/app/controllers/composer-submit-controller.js +56 -138
  306. package/dist/src/web-ui/app/controllers/composer-surface-controller.js +6 -0
  307. package/dist/src/web-ui/app/controllers/composer-workspace-controller.d.ts +22 -40
  308. package/dist/src/web-ui/app/controllers/composer-workspace-controller.js +49 -165
  309. package/dist/src/web-ui/app/controllers/conversation-navigation-intent.js +15 -0
  310. package/dist/src/web-ui/app/controllers/conversation-request-hydration.js +20 -17
  311. package/dist/src/web-ui/app/controllers/conversation-session-controller.d.ts +1 -2
  312. package/dist/src/web-ui/app/controllers/conversation-session-controller.js +49 -22
  313. package/dist/src/web-ui/app/controllers/conversation-workspace-activation.js +27 -0
  314. package/dist/src/web-ui/app/controllers/daily-memory-review.js +15 -16
  315. package/dist/src/web-ui/app/controllers/environment-transition.js +126 -0
  316. package/dist/src/web-ui/app/controllers/environment-workspace-preparation.js +18 -0
  317. package/dist/src/web-ui/app/controllers/home-composer-feature.d.ts +14 -36
  318. package/dist/src/web-ui/app/controllers/home-composer-feature.js +17 -114
  319. package/dist/src/web-ui/app/controllers/home-conversation-activation.js +6 -8
  320. package/dist/src/web-ui/app/controllers/operations-controller.js +2 -1
  321. package/dist/src/web-ui/app/controllers/passive-learning-controller.js +56 -0
  322. package/dist/src/web-ui/app/controllers/projects-controller.d.ts +1 -1
  323. package/dist/src/web-ui/app/controllers/projects-controller.js +6 -1
  324. package/dist/src/web-ui/app/controllers/reasoning-mode-controller.js +174 -0
  325. package/dist/src/web-ui/app/controllers/runtime-selection-controller.d.ts +7 -0
  326. package/dist/src/web-ui/app/controllers/runtime-selection-controller.js +20 -155
  327. package/dist/src/web-ui/app/controllers/session-controller.js +33 -17
  328. package/dist/src/web-ui/app/controllers/session-pin-updates.js +14 -0
  329. package/dist/src/web-ui/app/controllers/session-sidebar-controller.js +12 -14
  330. package/dist/src/web-ui/app/controllers/spark-chat-sync.js +2 -2
  331. package/dist/src/web-ui/app/controllers/steer-controller.js +9 -7
  332. package/dist/src/web-ui/app/controllers/tool-permission-mode-controller.js +1 -1
  333. package/dist/src/web-ui/app/controllers/workspace-conversation-opener.js +34 -0
  334. package/dist/src/web-ui/app/dashboard-feature.js +12 -2
  335. package/dist/src/web-ui/app/lib/reasoning-controls.js +40 -0
  336. package/dist/src/web-ui/app/lib/session-composer-queue-ownership.js +58 -0
  337. package/dist/src/web-ui/app/lib/session-composer-queue.d.ts +12 -0
  338. package/dist/src/web-ui/app/lib/session-composer-queue.js +25 -6
  339. package/dist/src/web-ui/app/passive-learning-feature.js +18 -5
  340. package/dist/src/web-ui/app/schedules-feature.js +5 -3
  341. package/dist/src/web-ui/app/services/client-preferences.d.ts +18 -10
  342. package/dist/src/web-ui/app/services/client-preferences.js +25 -16
  343. package/dist/src/web-ui/app/services/home-guidance-preferences.js +13 -13
  344. package/dist/src/web-ui/app/services/reasoning-override.js +12 -0
  345. package/dist/src/web-ui/app/services/runtime-web-client/automations.js +10 -2
  346. package/dist/src/web-ui/app/services/runtime-web-client/memory.js +7 -2
  347. package/dist/src/web-ui/app/services/runtime-web-client/system-host.js +2 -0
  348. package/dist/src/web-ui/app/services/runtime-web-client.d.ts +2 -0
  349. package/dist/src/web-ui/app/services/runtime-web-client.js +2 -0
  350. package/dist/src/web-ui/app/services/server-composer-queue.js +32 -0
  351. package/dist/src/web-ui/app/services/session-sidebar-preferences.js +5 -5
  352. package/dist/src/web-ui/app/services/workspace-state-storage.js +116 -0
  353. package/dist/src/web-ui/app/services/workspace-state.js +27 -0
  354. package/dist/src/web-ui/app/spark-chat-conversation.js +34 -45
  355. package/dist/src/web-ui/app/spark-chat-feature.js +10 -4
  356. package/dist/src/web-ui/app/styles/21-composer-controls.css +16 -0
  357. package/dist/src/web-ui/app/styles/41-plugin-management.css +8 -0
  358. package/dist/src/web-ui/app/styles/42-model-plugin-permissions.css +1 -0
  359. package/dist/src/web-ui/app/styles/49-collection-consent.css +30 -0
  360. package/dist/src/web-ui/app/styles/64-workspace-storage.css +23 -0
  361. package/dist/src/web-ui/app/styles/95-home-widgets.css +109 -0
  362. package/dist/src/web-ui/app/styles.css +3 -0
  363. package/dist/src/web-ui/client-state/contracts.d.ts +15 -0
  364. package/dist/src/web-ui/client-state/contracts.js +13 -0
  365. package/dist/src/web-ui/client-state/preference-shapes.d.ts +2 -0
  366. package/dist/src/web-ui/client-state/preference-shapes.js +80 -0
  367. package/dist/src/web-ui/client-state/preferences.d.ts +3 -0
  368. package/dist/src/web-ui/client-state/preferences.js +84 -0
  369. package/dist/src/web-ui/client-state/queue.d.ts +3 -0
  370. package/dist/src/web-ui/client-state/queue.js +43 -0
  371. package/dist/src/web-ui/client-state/routes.d.ts +7 -0
  372. package/dist/src/web-ui/client-state/routes.js +58 -0
  373. package/dist/src/web-ui/client-state/store.d.ts +14 -0
  374. package/dist/src/web-ui/client-state/store.js +88 -0
  375. package/dist/src/web-ui/local-runtime/configuration-activation-source.js +2 -0
  376. package/dist/src/web-ui/local-runtime/http.js +11 -2
  377. package/dist/src/web-ui/local-runtime/model-context-capacity-error.d.ts +14 -0
  378. package/dist/src/web-ui/local-runtime/model-context-capacity-error.js +28 -0
  379. package/dist/src/web-ui/local-runtime/model-setup-context-window.d.ts +15 -0
  380. package/dist/src/web-ui/local-runtime/model-setup-context-window.js +25 -0
  381. package/dist/src/web-ui/local-runtime/model-setup-routes.js +2 -0
  382. package/dist/src/web-ui/local-runtime/model-setup-service.js +5 -2
  383. package/dist/src/web-ui/local-runtime/model-setup-validation.d.ts +1 -0
  384. package/dist/src/web-ui/local-runtime/model-setup-validation.js +14 -7
  385. package/dist/src/web-ui/local-runtime/request-body-error.d.ts +11 -0
  386. package/dist/src/web-ui/local-runtime/request-body-error.js +14 -0
  387. package/dist/src/web-ui/local-runtime/request-control-observation.js +2 -2
  388. package/dist/src/web-ui/local-runtime/request-execution.js +18 -18
  389. package/dist/src/web-ui/local-runtime/runtime-setup-connection-edit.d.ts +2 -0
  390. package/dist/src/web-ui/local-runtime/runtime-setup-connection-edit.js +35 -22
  391. package/dist/src/web-ui/local-runtime/runtime-setup-context-window.d.ts +2 -9
  392. package/dist/src/web-ui/local-runtime/runtime-setup-context-window.js +4 -27
  393. package/dist/src/web-ui/local-runtime/runtime-setup-credentials.d.ts +15 -1
  394. package/dist/src/web-ui/local-runtime/runtime-setup-credentials.js +30 -11
  395. package/dist/src/web-ui/local-runtime/runtime-setup-edit-files.d.ts +20 -0
  396. package/dist/src/web-ui/local-runtime/runtime-setup-edit-files.js +104 -0
  397. package/dist/src/web-ui/local-runtime/runtime-setup-edit-journal.d.ts +29 -0
  398. package/dist/src/web-ui/local-runtime/runtime-setup-edit-journal.js +151 -0
  399. package/dist/src/web-ui/local-runtime/runtime-setup-edit-recovery.d.ts +7 -0
  400. package/dist/src/web-ui/local-runtime/runtime-setup-edit-recovery.js +87 -0
  401. package/dist/src/web-ui/local-runtime/runtime-setup-edit-transaction.d.ts +3 -0
  402. package/dist/src/web-ui/local-runtime/runtime-setup-edit-transaction.js +37 -0
  403. package/dist/src/web-ui/local-runtime/runtime-setup-service.js +4 -0
  404. package/dist/src/web-ui/local-runtime-backend.js +14 -0
  405. package/dist/src/web-ui/plugin-management-catalog.d.ts +3 -1
  406. package/dist/src/web-ui/plugin-management-catalog.js +3 -1
  407. package/dist/src/web-ui/plugin-management-service.d.ts +1 -0
  408. package/dist/src/web-ui/plugin-removal-service.d.ts +1 -0
  409. package/dist/src/web-ui/server-readiness.d.ts +3 -0
  410. package/dist/src/web-ui/server-readiness.js +36 -0
  411. package/dist/src/web-ui/server.d.ts +2 -0
  412. package/dist/src/web-ui/server.js +23 -1
  413. package/dist/src/web-ui/system-host-service.js +13 -2
  414. package/dist/src/web-ui/system-host-setup/collection-consent-route.d.ts +3 -0
  415. package/dist/src/web-ui/system-host-setup/collection-consent-route.js +30 -0
  416. package/docs/installation.md +44 -5
  417. package/docs/plugins.md +174 -28
  418. package/docs/tool-execution-result-evidence-contract.md +57 -0
  419. package/docs/windows-companion-store.md +5 -0
  420. package/package.json +4 -2
  421. package/plugins/capability-brief/plugin.json +5 -1
  422. package/plugins/code-outline/README.md +20 -0
  423. package/plugins/code-outline/plugin.json +2 -1
  424. package/plugins/code-outline/source/index.ts +16 -20
  425. package/plugins/code-outline/source/read-failure.ts +40 -0
  426. package/plugins/code-outline/src/index.cjs +614 -29
  427. package/plugins/document-reader/README.md +33 -0
  428. package/plugins/document-reader/plugin.json +2 -1
  429. package/plugins/document-reader/source/pdf-contract.ts +57 -0
  430. package/plugins/document-reader/source/pdf-parser.ts +139 -0
  431. package/plugins/document-reader/source/pdf-process-main.ts +56 -0
  432. package/plugins/document-reader/source/pdf-process.ts +207 -0
  433. package/plugins/document-reader/source/pdf-result.ts +79 -0
  434. package/plugins/document-reader/source/pdf-worker.ts +39 -303
  435. package/plugins/document-reader/source/pdf.ts +4 -1
  436. package/plugins/document-reader/source/read-failure.ts +37 -0
  437. package/plugins/document-reader/source/reader.ts +3 -19
  438. package/plugins/document-reader/src/index.cjs +995 -211
  439. package/plugins/exec/README.md +19 -0
  440. package/plugins/exec/plugin.json +4 -3
  441. package/plugins/exec/skills/exec_skill/SKILL.md +3 -2
  442. package/plugins/exec/source/filesystem-file-observer.ts +98 -0
  443. package/plugins/exec/source/filesystem-observer.ts +8 -79
  444. package/plugins/exec/source/output-files.ts +12 -6
  445. package/plugins/exec/source/paths.ts +3 -1
  446. package/plugins/exec/source/process-manager.ts +8 -24
  447. package/plugins/exec/source/shell-platform.ts +19 -3
  448. package/plugins/exec/source/shell-process.ts +55 -0
  449. package/plugins/exec/source/windows-job-source.ts +1 -0
  450. package/plugins/exec/source/windows-shell-bootstrap.ts +20 -0
  451. package/plugins/exec/src/index.cjs +252 -96
  452. package/plugins/filesystem/README.md +65 -0
  453. package/plugins/filesystem/plugin.json +7 -3
  454. package/plugins/filesystem/source/atomic-write.ts +2 -0
  455. package/plugins/filesystem/source/bounded-io.ts +80 -306
  456. package/plugins/filesystem/source/directory-sample.ts +2 -0
  457. package/plugins/filesystem/source/errors.ts +14 -0
  458. package/plugins/filesystem/source/file-observation.ts +151 -0
  459. package/plugins/filesystem/source/file-version.ts +41 -0
  460. package/plugins/filesystem/source/index.ts +6 -0
  461. package/plugins/filesystem/source/mutation-coordinator.ts +1 -0
  462. package/plugins/filesystem/source/windows/authority-script.ts +1 -0
  463. package/plugins/filesystem/source/windows/native-script.ts +1 -0
  464. package/plugins/filesystem/source/windows/operations.ts +197 -0
  465. package/plugins/filesystem/source/windows/process.ts +214 -0
  466. package/plugins/filesystem/source/windows/publication-script.ts +29 -0
  467. package/plugins/filesystem/source/windows/read-script.ts +63 -0
  468. package/plugins/filesystem/source/windows/request-availability.ts +67 -0
  469. package/plugins/filesystem/source/windows/source.ts +42 -0
  470. package/plugins/filesystem/source/windows/storage-script.ts +11 -0
  471. package/plugins/filesystem/source/windows/streams-script.ts +24 -0
  472. package/plugins/filesystem/source/windows/write-script.ts +86 -0
  473. package/plugins/filesystem/src/index.cjs +1208 -322
  474. package/plugins/json-inspector/README.md +18 -0
  475. package/plugins/json-inspector/plugin.json +2 -1
  476. package/plugins/json-inspector/source/index.ts +16 -19
  477. package/plugins/json-inspector/source/read-failure.ts +42 -0
  478. package/plugins/json-inspector/src/index.cjs +612 -27
  479. package/plugins/local-search/README.md +29 -0
  480. package/plugins/local-search/plugin.json +2 -1
  481. package/plugins/local-search/source/errors.ts +2 -0
  482. package/plugins/local-search/source/paths.ts +3 -0
  483. package/plugins/local-search/source/ripgrep-process.ts +31 -5
  484. package/plugins/local-search/source/ripgrep.ts +3 -3
  485. package/plugins/local-search/source/windows-authority.ts +99 -0
  486. package/plugins/local-search/source/windows-search-lease.ts +49 -0
  487. package/plugins/local-search/source/windows-search-process.ts +91 -0
  488. package/plugins/local-search/source/windows-search-script.ts +52 -0
  489. package/plugins/local-search/src/index.cjs +595 -26
  490. package/plugins/memory/plugin.json +5 -1
  491. package/plugins/memory/source/lock-directory-claim.ts +56 -0
  492. package/plugins/memory/source/lock-owner-file.ts +71 -0
  493. package/plugins/memory/source/lock-path-observation.ts +26 -0
  494. package/plugins/memory/source/prepared-memory-replacement.ts +40 -0
  495. package/plugins/memory/source/store-lock.ts +12 -7
  496. package/plugins/memory/source/store.ts +3 -2
  497. package/plugins/memory/src/index.cjs +174 -25
  498. package/plugins/project-orientation/README.md +23 -0
  499. package/plugins/project-orientation/plugin.json +2 -1
  500. package/plugins/project-orientation/source/index.ts +12 -9
  501. package/plugins/project-orientation/source/inspection-failure.ts +70 -0
  502. package/plugins/project-orientation/source/manifest-summary.ts +9 -2
  503. package/plugins/project-orientation/source/tree.ts +6 -0
  504. package/plugins/project-orientation/src/index.cjs +647 -31
  505. package/plugins/system/README.md +51 -15
  506. package/plugins/system/plugin.json +6 -2
  507. package/plugins/system/skills/system_actions/SKILL.md +1 -1
  508. package/plugins/system/source/command-working-directory.ts +47 -0
  509. package/plugins/system/source/computer/handlers.ts +13 -9
  510. package/plugins/system/source/computer/observation-result.ts +10 -5
  511. package/plugins/system/source/computer/request-computers.ts +10 -3
  512. package/plugins/system/source/computer/request-modules.ts +3 -6
  513. package/plugins/system/source/computer/runtime-platform.ts +18 -0
  514. package/plugins/system/source/host-dispatch.ts +18 -2
  515. package/plugins/system/source/index.ts +5 -3
  516. package/plugins/system/source/local-command-output-retention.ts +16 -0
  517. package/plugins/system/source/local-command-output.ts +16 -8
  518. package/plugins/system/source/request-system-modules.ts +12 -2
  519. package/plugins/system/source/request-target-snapshot.ts +2 -1
  520. package/plugins/system/source/security/desktop-result.ts +177 -0
  521. package/plugins/system/source/security/observed-error.ts +10 -0
  522. package/plugins/system/source/security/secret-text.ts +118 -0
  523. package/plugins/system/source/security/system-results.ts +62 -0
  524. package/plugins/system/source/security/windows-output-directory.ts +82 -0
  525. package/plugins/system/src/index.cjs +837 -151
  526. package/plugins/system-probe/plugin.json +9 -3
  527. package/plugins/system-probe/source/disk-path.ts +8 -0
  528. package/plugins/system-probe/source/index.ts +10 -5
  529. package/plugins/system-probe/source/machine-load.ts +33 -0
  530. package/plugins/system-probe/source/metrics.ts +6 -8
  531. package/plugins/system-probe/src/index.cjs +49 -16
  532. package/plugins/web/plugin.json +5 -1
@@ -0,0 +1,82 @@
1
+ import { escapeHtml } from "../lib/text-format.js";
2
+ import { enableModelReasoning } from "../services/reasoning-override.js";
3
+
4
+ /** A non-modal prompt anchored in the existing composer mode menu. */
5
+ export function createReasoningOverridePrompt({ root, client, getEnvironmentId, getProfile, refreshModels, render }) {
6
+ let context = "";
7
+ let revision = 0;
8
+ let busy = false;
9
+ let saved = false;
10
+ let message = "";
11
+ let failed = false;
12
+ let wasOpen = false;
13
+ const currentContext = () => JSON.stringify([getEnvironmentId(), getProfile()?.id]);
14
+ const ownsReasoningPrompt = (captured) => revision === captured.revision && context === captured.key && currentContext() === captured.key;
15
+
16
+ function reset() {
17
+ revision += 1;
18
+ context = ""; busy = false; saved = false; message = ""; failed = false; wasOpen = false;
19
+ }
20
+
21
+ async function enable(applyNow) {
22
+ if (busy || !getProfile()) return;
23
+ const captured = { key: currentContext(), revision };
24
+ const environmentId = getEnvironmentId();
25
+ const profileId = getProfile().id;
26
+ busy = true; failed = false; message = "Saving…"; render();
27
+ try {
28
+ await enableModelReasoning(client, profileId, environmentId);
29
+ if (!ownsReasoningPrompt(captured)) return;
30
+ saved = true;
31
+ message = "Saved. Reasoning controls will be available after Runtime restarts.";
32
+ if (!applyNow) return;
33
+ message = "Applying saved configuration…"; render();
34
+ const result = await client.applyRuntimeConfiguration(environmentId);
35
+ if (!ownsReasoningPrompt(captured)) return;
36
+ if (result?.activation?.status !== "ready") {
37
+ message = result?.activation?.message || "Saved. Apply again when Runtime is idle, or restart it later.";
38
+ return;
39
+ }
40
+ const refreshed = await refreshModels();
41
+ if (!ownsReasoningPrompt(captured)) return;
42
+ if (!refreshed) throw new Error("Configuration applied. Reload to refresh the model's reasoning controls.");
43
+ message = "Configuration applied. Reload if this model still uses provider defaults.";
44
+ } catch (error) {
45
+ if (!ownsReasoningPrompt(captured)) return;
46
+ failed = true;
47
+ message = `${saved ? "Saved; not confirmed active. " : ""}${error.message || String(error)}`;
48
+ } finally {
49
+ if (ownsReasoningPrompt(captured)) { busy = false; render(); }
50
+ }
51
+ }
52
+
53
+ function renderPrompt(open) {
54
+ const next = currentContext();
55
+ if (context !== next) { reset(); context = next; }
56
+ const restoreFocus = Boolean(root.contains?.(root.ownerDocument?.activeElement));
57
+ const focusOnOpen = open && !wasOpen;
58
+ wasOpen = open;
59
+ if (!open) { root.innerHTML = ""; return; }
60
+ const profile = getProfile();
61
+ const canSave = Boolean(profile) && typeof client.loadConfigDashboard === "function" && typeof client.saveConfigFile === "function";
62
+ root.innerHTML = `<section class="reasoning-override-prompt">
63
+ <strong>Enable reasoning controls?</strong>
64
+ <p><span>${escapeHtml(profile?.label || profile?.id || "This model")}</span> currently uses the provider’s default. Enable this only if the model supports reasoning controls.</p>
65
+ <div class="reasoning-override-actions">
66
+ <button type="button" data-reasoning-enable="now"${busy || !canSave || typeof client.applyRuntimeConfiguration !== "function" ? " disabled" : ""}>${saved ? "Apply now" : "Enable and apply now"}</button>
67
+ <button type="button" data-reasoning-enable="later"${busy || saved || !canSave ? " disabled" : ""}>Enable on next start</button>
68
+ </div>
69
+ <small>Apply now restarts idle Runtime environments with all saved settings. Active work will not be interrupted.</small>
70
+ <p class="reasoning-override-status${failed ? " error-text" : ""}" role="status" aria-live="polite"${message ? "" : " hidden"}>${escapeHtml(message)}</p>
71
+ </section>`;
72
+ for (const button of root.querySelectorAll("[data-reasoning-enable]")) {
73
+ button.addEventListener("click", () => void enable(button.dataset.reasoningEnable === "now"));
74
+ }
75
+ if (focusOnOpen || restoreFocus) {
76
+ const target = root.querySelector?.("button:not(:disabled)");
77
+ root.tabIndex = -1;
78
+ (target || root).focus();
79
+ }
80
+ }
81
+ return { render: renderPrompt, reset };
82
+ }
@@ -33,10 +33,30 @@ export function createRuntimeConfigActivation({
33
33
  const workspace = getWorkspace();
34
34
  if (!workspace?.beginExternalRuntimeMutation("saved configuration")) return;
35
35
  const environment = getEnvironmentId();
36
- let activated = false;
37
36
  busy = true;
38
37
  button.disabled = true;
39
38
  status.textContent = "Restarting with saved settings…";
39
+ try {
40
+ const activated = await restartSavedConfiguration(workspace, environment);
41
+ if (!activated) return;
42
+ if (environment !== getEnvironmentId()) return;
43
+ const settled = await onAppliedSettled();
44
+ if (settled !== false) return;
45
+ if (environment !== getEnvironmentId()) return;
46
+ status.textContent =
47
+ "Runtime restarted. Finish your current edits, then refresh configuration to update environments.";
48
+ } catch {
49
+ if (environment !== getEnvironmentId()) return;
50
+ status.textContent =
51
+ "Runtime restarted. Refresh configuration to update this view.";
52
+ } finally {
53
+ busy = false;
54
+ button.disabled = false;
55
+ }
56
+ }
57
+
58
+ async function restartSavedConfiguration(workspace, environment) {
59
+ let activated = false;
40
60
  try {
41
61
  const result = await apply();
42
62
  if (environment !== getEnvironmentId()) return;
@@ -65,8 +85,6 @@ export function createRuntimeConfigActivation({
65
85
  : "The runtime could not restart. Try again.";
66
86
  }
67
87
  } finally {
68
- busy = false;
69
- button.disabled = false;
70
88
  if (activated) button.textContent = "Restart runtime";
71
89
  workspace.endExternalRuntimeMutation();
72
90
  if (environment !== getEnvironmentId()) {
@@ -75,11 +93,7 @@ export function createRuntimeConfigActivation({
75
93
  button.textContent = "Restart runtime";
76
94
  }
77
95
  }
78
- if (!activated) return;
79
- if (environment !== getEnvironmentId()) return;
80
- if (onAppliedSettled() === false)
81
- status.textContent =
82
- "Runtime restarted. Finish your current edits, then refresh configuration to update environments.";
96
+ return activated;
83
97
  }
84
98
 
85
99
  button.addEventListener("click", applySavedConfiguration);
@@ -2,6 +2,7 @@ import { createEmbeddingSetupStep } from "./embedding.js";
2
2
  import { createSetupPluginStep } from "./plugins.js";
3
3
  import { createSystemHostConnectionManager } from "../system-host/manager.js";
4
4
  import { hostSetupIsReady } from "../system-host/rendering.js";
5
+ import { isNativeWindowsLocalAccess } from "../system-host/native-windows-access.js";
5
6
 
6
7
  /** Optional setup steps retain their owning services and never apply the Runtime. */
7
8
  export function createSetupOptionalSteps({
@@ -57,9 +58,10 @@ export function createSetupOptionalSteps({
57
58
  })
58
59
  : null;
59
60
  const readyStep = computer ? 5 : 4;
60
- function hasFreshComputerReadiness() {
61
+ function hasFreshComputerSetup() {
61
62
  if (!computer) return false;
62
63
  if (computer.state.busy || computer.state.statusUnavailable) return false;
64
+ if (isNativeWindowsLocalAccess(computer.state.snapshot)) return true;
63
65
  return hostSetupIsReady(computer.state.snapshot);
64
66
  }
65
67
  function projection(step) {
@@ -71,7 +73,8 @@ export function createSetupOptionalSteps({
71
73
  plugins: plugins.state.snapshot,
72
74
  hasComputerStep: Boolean(computer),
73
75
  readyStep,
74
- computer: hasFreshComputerReadiness() ? computer.state.snapshot : null,
76
+ computer: hasFreshComputerSetup() ? computer.state.snapshot : null,
77
+ nativeWindowsAccess: hasFreshComputerSetup() && isNativeWindowsLocalAccess(computer.state.snapshot),
75
78
  };
76
79
  if (step === 2)
77
80
  return {
@@ -90,7 +93,7 @@ export function createSetupOptionalSteps({
90
93
  return {
91
94
  ...common,
92
95
  content: `<div data-onboarding-computer>${computer.markup()}</div>`,
93
- canContinue: hasFreshComputerReadiness(),
96
+ canContinue: hasFreshComputerSetup(),
94
97
  };
95
98
  return common;
96
99
  }
@@ -111,7 +114,7 @@ export function createSetupOptionalSteps({
111
114
  }
112
115
  function canContinueComputer(step) {
113
116
  if (step !== 4) return false;
114
- return hasFreshComputerReadiness();
117
+ return hasFreshComputerSetup();
115
118
  }
116
119
  return {
117
120
  embedding,
@@ -1,3 +1,4 @@
1
+ import { renderPluginPlatformNotice } from "../plugins/compatibility.js";
1
2
  import { escapeAttribute, escapeHtml } from "../../lib/text-format.js";
2
3
 
3
4
  function blockReason(plugin, capability) {
@@ -33,6 +34,7 @@ function renderPluginCard(plugin, busy) {
33
34
  return `<li class="runtime-plugin-card">
34
35
  ${checkbox(plugin, null, busy)}
35
36
  <p class="runtime-plugin-summary" title="${escapeAttribute(plugin.description || "")}">${escapeHtml(plugin.description || "Installed Runtime plugin.")}</p>
37
+ ${renderPluginPlatformNotice(plugin.compatibility)}
36
38
  <div class="runtime-plugin-tools-heading"><span>Tools</span><span>${plugin.selectedCapabilityCount} of ${capabilities.length} selected</span></div>
37
39
  <ul class="runtime-plugin-capabilities" aria-label="${escapeAttribute(`Tools in ${plugin.id}`)}">${capabilities.map((capability) => `<li>${checkbox(plugin, capability, busy)}</li>`).join("")}</ul>
38
40
  </li>`;
@@ -144,7 +146,7 @@ export function createSetupPluginStep({
144
146
  state.snapshot?.selection?.enabled === false ||
145
147
  state.snapshot?.selection?.deny?.includes("*");
146
148
  return `<div class="runtime-setup-plugins">
147
- <p class="runtime-setup-feedback">All installed plugins start enabled in a new setup. Turn off anything you do not need.</p>
149
+ <p class="runtime-setup-feedback">All installed plugins start selected in a new setup. Host compatibility determines which plugins can load. Turn off anything you do not need.</p>
148
150
  ${globalBlocked ? '<p class="runtime-setup-feedback">An existing global policy blocks plugins. Your saved policy is preserved.</p>' : ""}
149
151
  ${state.error ? `<p class="runtime-setup-feedback error" role="alert">${escapeHtml(state.error)}</p><button type="button" class="runtime-setup-inline-action" data-runtime-setup-action="plugins-reload">Reload selection</button>` : state.message ? `<p class="runtime-setup-feedback" role="status">${escapeHtml(state.message)}</p>` : ""}
150
152
  ${state.busy ? '<p class="runtime-setup-feedback" role="status">Saving or loading plugin selection…</p>' : ""}
@@ -28,7 +28,7 @@ function readyMarkup(state, optional) {
28
28
  <div><dt>Model</dt><dd>${escapeHtml(state.modelId)}</dd></div>
29
29
  <div><dt>Context window</dt><dd>${escapeHtml(formatContextWindowTokens(state.contextWindowTokens))}</dd></div>
30
30
  <div><dt>Embedding</dt><dd>${escapeHtml(optional.memory?.enabled ? optional.memory.model || "Configured" : "Set up later")}</dd></div>
31
- <div><dt>Plugins</dt><dd>${selectedPlugins} enabled</dd></div>
31
+ <div><dt>Plugins</dt><dd>${selectedPlugins} selected</dd></div>
32
32
  </dl></div>`;
33
33
  }
34
34
 
@@ -79,7 +79,7 @@ function footerMarkup(state, availability, optional) {
79
79
  if (state.step === 3)
80
80
  return `<button type="button" class="runtime-setup-secondary" data-runtime-setup-action="back" ${disabled}>Back</button><button type="submit" class="runtime-setup-action" ${busy || !optional.canContinue ? "disabled" : ""}>Continue</button>`;
81
81
  if (state.step === 4 && optional.hasComputerStep)
82
- return `<button type="button" class="runtime-setup-secondary" data-runtime-setup-action="back">Back</button><div class="runtime-setup-footer-actions"><button type="button" class="runtime-setup-secondary" data-runtime-setup-action="skip-computer">Skip for now</button><button type="submit" class="runtime-setup-action" ${!optional.canContinue ? "disabled" : ""}>Continue</button></div>`;
82
+ return `<button type="button" class="runtime-setup-secondary" data-runtime-setup-action="back">Back</button><div class="runtime-setup-footer-actions">${optional.nativeWindowsAccess ? "" : '<button type="button" class="runtime-setup-secondary" data-runtime-setup-action="skip-computer">Skip for now</button>'}<button type="submit" class="runtime-setup-action" ${!optional.canContinue ? "disabled" : ""}>Continue</button></div>`;
83
83
  const secondary =
84
84
  state.step === 1 && canEditSetupConnection(state)
85
85
  ? `<button type="button" class="runtime-setup-secondary" data-runtime-setup-action="back" ${disabled}>Back</button>`
@@ -112,11 +112,13 @@ export function renderRuntimeSetup(state, availability, optional = {}) {
112
112
  const steps = [...STEP_LABELS];
113
113
  if (optional.hasComputerStep) {
114
114
  steps.splice(4, 0, "Computer");
115
- titles.splice(4, 0, "Set up computer access");
115
+ titles.splice(4, 0, optional.nativeWindowsAccess ? "Your Windows computer" : "Set up computer access");
116
116
  descriptions.splice(
117
117
  4,
118
118
  0,
119
- "Optional. Use applications on your computer, or set up access later in Settings.",
119
+ optional.nativeWindowsAccess
120
+ ? ""
121
+ : "Optional. Use applications on your computer, or set up access later in Settings.",
120
122
  );
121
123
  }
122
124
  const content =
@@ -73,6 +73,7 @@ export interface RuntimeSetupGuideDependencies {
73
73
  readonly loadHostConnection?: () => Promise<Record<string, unknown>>;
74
74
  readonly connectLocalHost?: () => Promise<Record<string, unknown>>;
75
75
  readonly createHostPairing?: () => Promise<Record<string, unknown>>;
76
+ readonly requestHostStoreConnection?: () => Promise<Record<string, unknown>>;
76
77
  readonly requestHostPermissions?: (input: Record<string, unknown>) => Promise<Record<string, unknown>>;
77
78
  readonly downloadHostSetup?: (
78
79
  platform: "windows" | "macos" | "linux",
@@ -1,3 +1,4 @@
1
+ import { displayReasoningMode } from "../../lib/reasoning-controls.js";
1
2
  import { toolPermissionModeMeta } from "../../lib/tool-permission-mode.js";
2
3
  import { updateLiveRegion } from "../../lib/live-region.js";
3
4
  import { escapeHtml } from "../../lib/text-format.js";
@@ -33,7 +34,7 @@ function runMarkup(run) {
33
34
  return `<article class="schedule-run" data-run-id="${escapeHtml(run.id)}">
34
35
  <div class="schedule-run-heading"><strong>${scheduleTimeLabel(run.scheduledAt, timeZone)}</strong><span class="schedule-badge" data-state="${escapeHtml(run.status)}">${escapeHtml(run.status)}</span></div>
35
36
  <div class="schedule-run-meta">${run.trigger === "manual" ? "Manual run" : "Scheduled run"}${run.startedAt ? ` · Started ${scheduleTimeLabel(run.startedAt, timeZone)}` : ""}${run.finishedAt ? ` · Finished ${scheduleTimeLabel(run.finishedAt, timeZone)}` : ""}</div>
36
- <dl class="schedule-run-settings">${fact("Model", run.modelProfileId)}${fact("Mode", run.agentMode)}${fact("Tool access", toolPermissionModeMeta(run.toolPermissionMode).label)}${fact("Time zone", run.timeZone)}${fact("Job revision", String(run.jobRevision ?? "—"))}</dl>
37
+ <dl class="schedule-run-settings">${fact("Model", run.modelProfileId)}${fact("Mode", displayReasoningMode(run.agentMode))}${fact("Tool access", toolPermissionModeMeta(run.toolPermissionMode).label)}${fact("Time zone", run.timeZone)}${fact("Job revision", String(run.jobRevision ?? "—"))}</dl>
37
38
  ${run.error ? `<p class="schedule-error" dir="auto">${escapeHtml(run.error)}</p>` : ""}
38
39
  ${run.resultText ? `<details class="schedule-result" data-disclosure-id="result:${escapeHtml(run.id)}"><summary>View result</summary><pre dir="auto">${escapeHtml(run.resultText)}</pre></details>` : ""}
39
40
  <details class="schedule-prompt-disclosure" data-disclosure-id="run:${escapeHtml(run.id)}"><summary>View invocation prompt</summary><pre dir="auto">${escapeHtml(run.prompt)}</pre></details>
@@ -67,7 +68,7 @@ export function renderScheduleDetails({ root, snapshot, actions }) {
67
68
  const conversationLabel = scheduleConversationLabel(job.sessionId, snapshot.sessions);
68
69
  const markup = `<div class="schedule-detail-heading"><span class="schedule-eyebrow">Scheduled task</span><h3 dir="auto">${escapeHtml(job.title)}</h3><span class="schedule-badge" data-state="${job.state}">${job.state}</span></div>
69
70
  <div class="schedule-action-row">${actionsMarkup(job, snapshot.mutation)}</div>
70
- <dl class="schedule-facts">${fact("Schedule", scheduleDescription(job))}${fact("Next run", scheduleTimeLabel(job.nextRunAt, job.timeZone))}${fact("Time zone", job.timeZone)}${fact("Model", job.modelProfileId)}${fact("Mode", job.agentMode)}${fact("Tool access", toolPermissionModeMeta(job.toolPermissionMode).label)}${fact("Created", scheduleTimeLabel(job.createdAt, job.timeZone))}${fact("Updated", scheduleTimeLabel(job.updatedAt, job.timeZone))}</dl>
71
+ <dl class="schedule-facts">${fact("Schedule", scheduleDescription(job))}${fact("Next run", scheduleTimeLabel(job.nextRunAt, job.timeZone))}${fact("Time zone", job.timeZone)}${fact("Model", job.modelProfileId)}${fact("Mode", displayReasoningMode(job.agentMode))}${fact("Tool access", toolPermissionModeMeta(job.toolPermissionMode).label)}${fact("Created", scheduleTimeLabel(job.createdAt, job.timeZone))}${fact("Updated", scheduleTimeLabel(job.updatedAt, job.timeZone))}</dl>
71
72
  <button type="button" class="schedule-conversation-link" data-open-conversation>↗ <span dir="auto">${escapeHtml(conversationLabel)}</span></button>
72
73
  <details class="schedule-prompt-disclosure" data-disclosure-id="job:${escapeHtml(job.id)}"><summary>View task prompt</summary><pre dir="auto">${escapeHtml(job.prompt)}</pre></details>
73
74
  <small class="schedule-id">Job ${escapeHtml(job.id)} · Revision ${job.revision}</small>
@@ -1,3 +1,4 @@
1
+ import { renderReasoningModeField, syncReasoningModeField, retainedReasoningMode } from "../../lib/reasoning-controls.js";
1
2
  import { escapeHtml } from "../../lib/text-format.js";
2
3
  import { SCHEDULE_WEEKDAYS } from "../../lib/schedule-presentation.js";
3
4
  import { scheduleErrorMessage } from "../../lib/schedule-errors.js";
@@ -88,12 +89,7 @@ export function createScheduleForm({
88
89
  <label>Task prompt<textarea name="prompt" rows="5" required dir="auto" placeholder="What should ABot do when this schedule runs?">${escapeHtml(values.prompt || "")}</textarea></label>
89
90
  <div class="schedule-form-grid">${scheduleFields(values)}</div>
90
91
  <div class="schedule-form-grid"><label>Model<select name="modelProfileId" required><option value="">Choose a model</option>${options(modelOptions, values.modelProfileId)}</select></label>
91
- <label>Mode<select name="agentMode">${options(
92
- modes
93
- .filter((mode) => mode !== "auto")
94
- .map((mode) => ({ value: mode, label: mode })),
95
- values.agentMode || "reasoning",
96
- )}</select></label></div>
92
+ ${renderReasoningModeField(values.agentMode || "reasoning", models.find((model) => model.id === values.modelProfileId), modes.filter((mode) => mode !== "auto"))}</div>
97
93
  <label>Tool access<select name="toolPermissionMode">${options(
98
94
  [
99
95
  { value: "full_access", label: "Full" },
@@ -116,6 +112,12 @@ export function createScheduleForm({
116
112
  }
117
113
  }
118
114
 
115
+ const readInput = () => {
116
+ const data = new FormData(form);
117
+ data.set("agentMode", retainedReasoningMode(form, values.agentMode || "reasoning"));
118
+ return scheduleFormInput(data, job?.schedule);
119
+ };
120
+ fields.namedItem("modelProfileId").addEventListener("change", () => syncReasoningModeField(form, models, modes.filter((mode) => mode !== "auto")));
119
121
  let initialInput;
120
122
  form.querySelector("[data-cancel]").addEventListener("click", onCancel);
121
123
  fields.namedItem("kind").addEventListener("change", syncKind);
@@ -125,7 +127,7 @@ export function createScheduleForm({
125
127
  submit.disabled = true;
126
128
  feedback.hidden = true;
127
129
  try {
128
- const currentInput = scheduleFormInput(new FormData(form), job?.schedule);
130
+ const currentInput = readInput();
129
131
  const input = job
130
132
  ? scheduleUpdateInput(currentInput, initialInput)
131
133
  : currentInput;
@@ -137,7 +139,7 @@ export function createScheduleForm({
137
139
  }
138
140
  });
139
141
  syncKind();
140
- if (job) initialInput = scheduleFormInput(new FormData(form), job.schedule);
142
+ if (job) initialInput = readInput();
141
143
  const initialFields = JSON.stringify([...new FormData(form)]);
142
144
  function trackScheduleDraft() {
143
145
  form.dataset.dirty = String(
@@ -48,12 +48,31 @@ export function createSchedulesWorkspace({
48
48
  });
49
49
 
50
50
  function prepareLeave() {
51
- if (!actions.snapshot().editor) return true;
52
- if (!canDiscardScheduleDraft()) return false;
53
- actions.cancelEdit();
51
+ const prepared = prepareEnvironmentChange();
52
+ if (!prepared) return false;
53
+ prepared();
54
54
  return true;
55
55
  }
56
56
 
57
+ function prepareEnvironmentChange() {
58
+ const editor = actions.snapshot().editor;
59
+ if (editor && !canDiscardScheduleDraft()) return null;
60
+ const form = details.querySelector(".schedule-editor");
61
+ const fingerprint = scheduleDraftFingerprint(form);
62
+ const commit = () => { if (editor) actions.cancelEdit(); };
63
+ commit.canCommit = () => {
64
+ if (actions.snapshot().mutation) return false;
65
+ if (actions.snapshot().editor !== editor) return false;
66
+ if (details.querySelector(".schedule-editor") !== form) return false;
67
+ return scheduleDraftFingerprint(form) === fingerprint;
68
+ };
69
+ return commit;
70
+ }
71
+
72
+ function scheduleDraftFingerprint(form) {
73
+ return form ? JSON.stringify([...new FormData(form)]) : "";
74
+ }
75
+
57
76
  function canDiscardScheduleDraft() {
58
77
  const form = details.querySelector(".schedule-editor");
59
78
  if (form?.dataset.dirty !== "true") return true;
@@ -156,5 +175,5 @@ export function createSchedulesWorkspace({
156
175
  editorIdentity = null;
157
176
  renderScheduleDetails({ root: details, snapshot, actions });
158
177
  }
159
- return { render, prepareLeave };
178
+ return { render, prepareLeave, prepareEnvironmentChange };
160
179
  }
@@ -7,7 +7,7 @@ export function renderSessionSidebarSections({
7
7
  if (showingArchived) {
8
8
  const notice = document.createElement("p");
9
9
  notice.className = "session-archive-notice";
10
- notice.textContent = "Archived in this browser and environment. Restore a conversation from its menu.";
10
+ notice.textContent = "Archived in this ABot installation and environment. Restore a conversation from its menu.";
11
11
  root.appendChild(notice);
12
12
  }
13
13
  const pinned = sessions.filter((session) => isPinned(session.id));
@@ -35,7 +35,7 @@ export function renderSessionSidebarSections({
35
35
  const toggle = document.createElement("button");
36
36
  toggle.type = "button";
37
37
  toggle.className = "session-archive-toggle";
38
- toggle.title = "Conversations archived in this browser and environment";
38
+ toggle.title = "Conversations archived in this ABot installation and environment";
39
39
  toggle.textContent = showingArchived ? "Back to conversations" : `Archived (${archivedCount})`;
40
40
  toggle.setAttribute("aria-pressed", String(showingArchived));
41
41
  toggle.addEventListener("click", onToggleArchived);
@@ -12,7 +12,7 @@ function sameSourceMessage(current, source) {
12
12
 
13
13
  export function createSparkHandoffActions({
14
14
  getScope, getMessages, client, captureNavigation, onOpened, onChange = () => {},
15
- notify, documentRoot = document,
15
+ notify, documentRoot = document, canOpen = () => true,
16
16
  }) {
17
17
  const pending = new Set();
18
18
  function createNode(message) {
@@ -25,7 +25,12 @@ export function createSparkHandoffActions({
25
25
  button.type = "button";
26
26
  button.className = "spark-handoff-button";
27
27
  button.textContent = "Open a session about this";
28
- button.disabled = !message.sparkHandoffAvailable || pending.has(identity);
28
+ function canStartHandoff() {
29
+ if (!canOpen()) return false;
30
+ if (!message.sparkHandoffAvailable) return false;
31
+ return !pending.has(identity);
32
+ }
33
+ button.disabled = !canStartHandoff();
29
34
  row.appendChild(button);
30
35
  if (!message.sparkHandoffAvailable) {
31
36
  const explanation = documentRoot.createElement("p");
@@ -39,7 +44,8 @@ export function createSparkHandoffActions({
39
44
  return getMessages().some((candidate) => sameSourceMessage(candidate, message));
40
45
  }
41
46
  async function open() {
42
- if (button.disabled || pending.has(identity) || !sourceIsCurrent()) return;
47
+ if (!canStartHandoff()) return;
48
+ if (!sourceIsCurrent()) return;
43
49
  const navigate = captureNavigation();
44
50
  pending.add(identity); button.disabled = true;
45
51
  try {
@@ -66,7 +66,7 @@ export function createSparkChatPanel({ documentRoot = document, launcherAnchor }
66
66
  placement.refresh();
67
67
  onToggle(value);
68
68
  if (!focus) return;
69
- if (value) dom.messagesList.focus({ preventScroll: true });
69
+ if (value) dom.composerInput.focus({ preventScroll: true });
70
70
  else (previousFocus?.isConnected ? previousFocus : dom.launcherButton)?.focus({ preventScroll: true });
71
71
  }
72
72
 
@@ -1,14 +1,11 @@
1
1
  import { createSparkPlacementMotion } from "./motion.js";
2
+ import { workspaceStorage } from "../../services/workspace-state.js";
2
3
 
3
4
  const storageKey = "abot.spark.launcher.position.v1";
4
5
  const margin = 12;
5
6
  const dragThreshold = 5;
6
7
  const positionGrid = 16;
7
8
 
8
- function readBrowserStorage(windowRoot) {
9
- try { return windowRoot.localStorage; } catch { return null; }
10
- }
11
-
12
9
  function readPosition(storage) {
13
10
  try {
14
11
  const value = JSON.parse(storage?.getItem(storageKey) ?? "null");
@@ -31,9 +28,9 @@ function hasMovedPastDragThreshold(pointer, event) {
31
28
  return Math.hypot(event.clientX - pointer.x, event.clientY - pointer.y) >= dragThreshold;
32
29
  }
33
30
 
34
- /** Browser-only launcher placement; conversation and environment state stay untouched. */
31
+ /** Installation-owned launcher placement, clamped to the current screen. */
35
32
  export function createSparkChatPlacement({ root, launcher, panel, notice, dockAnchor, storage, windowRoot = window }) {
36
- const positionStorage = storage === undefined ? readBrowserStorage(windowRoot) : storage;
33
+ const positionStorage = storage === undefined ? workspaceStorage() : storage;
37
34
  let position = readPosition(positionStorage);
38
35
  let pointer = null;
39
36
  let suppressClick = false;
@@ -45,7 +42,7 @@ export function createSparkChatPlacement({ root, launcher, panel, notice, dockAn
45
42
  try {
46
43
  if (position) positionStorage?.setItem(storageKey, JSON.stringify(position));
47
44
  else positionStorage?.removeItem(storageKey);
48
- } catch { /* Placement remains usable when browser storage is unavailable. */ }
45
+ } catch { /* The shared storage owner reports persistence failures. */ }
49
46
  }
50
47
 
51
48
  function placePopup(node, anchor) {
@@ -1,3 +1,4 @@
1
+ import { canChooseReasoning, reasoningModeOptions } from "../../lib/reasoning-controls.js";
1
2
  import { supportsFullPlus } from "../../lib/tool-permission-mode.js";
2
3
 
3
4
  export function createSparkChatSettings({ root, onSave, onClear, onOpen, onResetPosition, onOpenModelSettings, getAgentMode, onAgentModeChange, getWebConfig, documentRoot = document }) {
@@ -13,7 +14,7 @@ export function createSparkChatSettings({ root, onSave, onClear, onOpen, onReset
13
14
  </form>
14
15
  <div class="spark-settings-row">
15
16
  <label for="spark-agent-mode"><strong>Thinking mode</strong><span>Choose how deeply SPARK thinks before replying.</span></label>
16
- <select id="spark-agent-mode" data-spark-agent-mode aria-label="SPARK thinking mode"><option value="fast">Fast</option><option value="reasoning" selected>Reasoning</option><option value="deep">Deep</option></select>
17
+ <select id="spark-agent-mode" data-spark-agent-mode aria-label="SPARK thinking mode"><option value="fast">Low</option><option value="reasoning" selected>Reasoning</option><option value="deep">Deep</option></select>
17
18
  </div>
18
19
  <div class="spark-settings-row"><div><strong>Chat shortcut</strong><p>Drag SPARK wherever feels right. Use Alt + arrow keys to move it.</p></div>
19
20
  <button type="button" data-spark-reset-position>Return to sidebar</button></div>
@@ -29,11 +30,12 @@ export function createSparkChatSettings({ root, onSave, onClear, onOpen, onReset
29
30
  const feedback = card.querySelector("[data-spark-settings-feedback]");
30
31
  let saved = "ask";
31
32
  let ready = false;
33
+ let reasoningEnabled = false;
32
34
  let busy = false;
33
35
  let environmentId;
34
36
  function controls() {
35
37
  select.disabled = busy || !ready;
36
- agentModeSelect.disabled = !ready;
38
+ agentModeSelect.disabled = !ready || !reasoningEnabled;
37
39
  save.disabled = busy || !ready || select.value === saved;
38
40
  clear.disabled = busy || !ready;
39
41
  }
@@ -52,7 +54,7 @@ export function createSparkChatSettings({ root, onSave, onClear, onOpen, onReset
52
54
  finally { if (environment === environmentId) { busy = false; controls(); } }
53
55
  }
54
56
  select.addEventListener("change", controls);
55
- agentModeSelect.addEventListener("change", () => onAgentModeChange(agentModeSelect.value));
57
+ agentModeSelect.addEventListener("change", () => { if (reasoningEnabled) onAgentModeChange(agentModeSelect.value); });
56
58
  card.querySelector("form").addEventListener("submit", (event) => {
57
59
  event.preventDefault();
58
60
  if (save.disabled) return;
@@ -73,7 +75,9 @@ export function createSparkChatSettings({ root, onSave, onClear, onOpen, onReset
73
75
  environmentId = nextEnvironmentId; busy = false; ready = false; feedback.textContent = "";
74
76
  select.value = configuration?.toolPermissionMode || "ask";
75
77
  }
76
- agentModeSelect.value = getAgentMode();
78
+ reasoningEnabled = canChooseReasoning(configuration);
79
+ agentModeSelect.innerHTML = reasoningModeOptions(getAgentMode(), reasoningEnabled);
80
+ agentModeSelect.title = reasoningEnabled ? "Reasoning depth" : "Enable reasoning controls for this model in Models.";
77
81
  const next = configuration?.toolPermissionMode || "ask";
78
82
  if (!ready || select.value === saved || busy) select.value = next;
79
83
  saved = next; ready = Boolean(configuration?.sessionId);
@@ -0,0 +1,75 @@
1
+ import { hostSetupIsReady } from "./rendering.js";
2
+ import { hasNativePermissionSurface, permissionSummary } from "./macos-permission-rendering.js";
3
+ import { canCheckMacPermissions, canCheckNativePermissions, permissionsMatchConnection, permissionsMatchNativeOwner } from "./macos-permission-scopes.js";
4
+
5
+ function currentPermissionScopes(state) {
6
+ const snapshot = state.snapshot;
7
+ const scopes = [];
8
+ if (snapshot.identity?.os === "macos") {
9
+ scopes.push({
10
+ available: canCheckMacPermissions(snapshot),
11
+ current: permissionsMatchConnection(state.macPermissions, snapshot),
12
+ receipt: state.macPermissions,
13
+ });
14
+ }
15
+ if (hasNativePermissionSurface(snapshot)) {
16
+ const environmentId = snapshot.nativePermissions?.environmentId;
17
+ scopes.push({
18
+ available: canCheckNativePermissions(snapshot, environmentId),
19
+ current: permissionsMatchNativeOwner(state.nativeMacPermissions, snapshot, environmentId),
20
+ receipt: state.nativeMacPermissions,
21
+ });
22
+ }
23
+ return scopes;
24
+ }
25
+
26
+ function scopeRequiresPermission(scope) {
27
+ if (!scope.current) return false;
28
+ return permissionSummary(scope.receipt) === "action needed";
29
+ }
30
+
31
+ function scopeHasGrantedPermissions(scope) {
32
+ if (!scope.current) return false;
33
+ return permissionSummary(scope.receipt) === "granted";
34
+ }
35
+
36
+ function scopeCannotCheckPermissions(scope) {
37
+ return !scope.available;
38
+ }
39
+
40
+ function computerPermissionIndicator(state) {
41
+ const scopes = currentPermissionScopes(state);
42
+ if (scopes.some(scopeRequiresPermission))
43
+ return { icon: "failed", label: "Required", tone: "attention" };
44
+ if (!scopes.length)
45
+ return { icon: "neutral", label: "Unavailable", tone: "neutral" };
46
+ if (scopes.some(scopeCannotCheckPermissions))
47
+ return { icon: "paused", label: "Unavailable", tone: "neutral" };
48
+ if (scopes.every(scopeHasGrantedPermissions))
49
+ return { icon: "success", label: "Granted", tone: "success" };
50
+ return { icon: "unknown", label: "Not checked", tone: "neutral" };
51
+ }
52
+
53
+ function canPreviewConnectedComputer(state) {
54
+ if (state.snapshot?.connected !== true) return false;
55
+ if (!hostSetupIsReady(state.snapshot)) return false;
56
+ if (state.busy) return false;
57
+ if (state.downloaded) return false;
58
+ if (state.manualMac) return false;
59
+ return true;
60
+ }
61
+
62
+ /** Project current receipts without requesting permissions or changing connection state. */
63
+ export function computerWidgetPreview(state, title, status) {
64
+ if (!canPreviewConnectedComputer(state)) return null;
65
+ const os = state.snapshot.identity?.os;
66
+ return {
67
+ kind: "computer",
68
+ title,
69
+ detail: { macos: "macOS", windows: "Windows", linux: "Linux" }[os] || os || "Unknown OS",
70
+ items: [
71
+ { label: "Connection", indicator: { icon: "success", label: status, tone: "success" } },
72
+ { label: "Permissions", indicator: computerPermissionIndicator(state) },
73
+ ],
74
+ };
75
+ }