@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,53 @@
1
+ import { readSetupContextWindowFeedback } from "../runtime-setup/context-window-feedback.js";
2
+ import { MODEL_SETUP_ID } from "./rendering.js";
3
+
4
+ const CONTEXT_FIELD = '[data-runtime-setup-field="context-window"]';
5
+ const CONTEXT_ERROR_ID = `${MODEL_SETUP_ID}Error-context-window`;
6
+ const CONTEXT_HELP_ID = `${MODEL_SETUP_ID}Help-context-window`;
7
+
8
+ export function receiveModelContextWindowFeedback(state, error) {
9
+ if (state.busy !== "saving" || state.saved) return false;
10
+ if (error?.payload?.contextWindow?.profileId !== state.profileId)
11
+ return false;
12
+ const feedback = readSetupContextWindowFeedback(error);
13
+ if (!feedback) return false;
14
+ state.contextWindowFeedback = feedback;
15
+ state.step = 1;
16
+ state.error = "";
17
+ return true;
18
+ }
19
+
20
+ /** Remove only this feedback; preserve the draft and its secret input element. */
21
+ export function clearModelContextWindowFeedback(state, form) {
22
+ if (!state.contextWindowFeedback) return;
23
+ state.contextWindowFeedback = null;
24
+ const field = form.querySelector(CONTEXT_FIELD);
25
+ field?.removeAttribute("aria-invalid");
26
+ field?.setAttribute("aria-describedby", CONTEXT_HELP_ID);
27
+ field?.setAttribute("min", "1");
28
+ form.querySelector(`[id="${CONTEXT_ERROR_ID}"]`)?.remove();
29
+ }
30
+
31
+ export function renderModelContextWindowFeedback(state, form, restoreFocus) {
32
+ const feedback = state.contextWindowFeedback;
33
+ if (!feedback) return;
34
+ const field = form.querySelector(CONTEXT_FIELD);
35
+ if (!field) return;
36
+ field.setAttribute("aria-invalid", "true");
37
+ field.setAttribute(
38
+ "aria-describedby",
39
+ `${CONTEXT_HELP_ID} ${CONTEXT_ERROR_ID}`,
40
+ );
41
+ field.setAttribute("min", String(feedback.minimumTokens));
42
+ let message = form.querySelector(`[id="${CONTEXT_ERROR_ID}"]`);
43
+ if (!message) {
44
+ message = form.ownerDocument.createElement("small");
45
+ message.setAttribute("id", CONTEXT_ERROR_ID);
46
+ message.setAttribute("class", "runtime-setup-feedback error");
47
+ message.setAttribute("role", "alert");
48
+ field.parentElement.append(message);
49
+ }
50
+ message.textContent = feedback.message;
51
+ if (state.busy || state.step !== 1 || !restoreFocus) return;
52
+ field.focus();
53
+ }
@@ -1,3 +1,4 @@
1
+ import { receiveModelContextWindowFeedback } from "./context-window-feedback.js";
1
2
  import { selectedModelProvider } from "./validation.js";
2
3
  import {
3
4
  isDefinitiveModelSaveRejection,
@@ -97,7 +98,8 @@ export function createModelSaveFlow({
97
98
  if (credentialSaved)
98
99
  state.credentialSavedFor =
99
100
  selectedModelProvider(state)?.id || state.newProviderId;
100
- state.error = modelSaveErrorMessage(state, error);
101
+ if (!receiveModelContextWindowFeedback(state, error))
102
+ state.error = modelSaveErrorMessage(state, error);
101
103
  if (credentialSaved)
102
104
  state.error +=
103
105
  " Your API key was saved privately and will be reused on retry.";
@@ -19,6 +19,7 @@ export function modelSaveFailureMessage(state) {
19
19
 
20
20
  export function modelSaveErrorMessage(state, error) {
21
21
  const fallback = modelSaveFailureMessage(state);
22
+ if (error?.payload?.error === "context_window_too_small") return fallback;
22
23
  const detail = error?.payload?.message;
23
24
  if (!detail) return fallback;
24
25
  if (state.saved) return `${fallback} ${detail}`;
@@ -7,6 +7,10 @@ import {
7
7
  import { renderWizardProgress } from "../runtime-setup/wizard-shell.js";
8
8
  import { DEFAULT_OLLAMA_BASE_URL } from "../runtime-setup/validation.js";
9
9
  import { createSetupViewState } from "../runtime-setup/view-state.js";
10
+ import {
11
+ clearModelContextWindowFeedback,
12
+ renderModelContextWindowFeedback,
13
+ } from "./context-window-feedback.js";
10
14
  import { createModelSaveFlow } from "./save-flow.js";
11
15
  import {
12
16
  MODEL_SETUP_ID,
@@ -70,6 +74,7 @@ export function createModelSetupWizard({
70
74
  choice: "",
71
75
  model: "",
72
76
  contextWindowTokens: "",
77
+ contextWindowFeedback: null,
73
78
  profileId: "",
74
79
  profileEdited: false,
75
80
  newProviderId: "",
@@ -201,6 +206,11 @@ export function createModelSetupWizard({
201
206
  .querySelector(".runtime-setup-panel")
202
207
  .setAttribute("aria-busy", Boolean(state.busy).toString());
203
208
  viewState.restore({ focus, busy: Boolean(state.busy) });
209
+ renderModelContextWindowFeedback(
210
+ state,
211
+ modelForm,
212
+ viewState.canRestoreFocus(),
213
+ );
204
214
  }
205
215
 
206
216
  async function load() {
@@ -280,6 +290,7 @@ export function createModelSetupWizard({
280
290
  event.target.removeAttribute("aria-invalid");
281
291
  return;
282
292
  }
293
+ clearModelContextWindowFeedback(state, modelForm);
283
294
  state.saveOutcomeUncertain = false;
284
295
  const value = textOf(event.target.value);
285
296
  if (field === "model-id") {
@@ -315,6 +326,7 @@ export function createModelSetupWizard({
315
326
  )
316
327
  return;
317
328
  clearSecret();
329
+ clearModelContextWindowFeedback(state, modelForm);
318
330
  state.saveOutcomeUncertain = false;
319
331
  const providerChanged = state.choice !== event.target.value;
320
332
  if (providerChanged) state.model = "";
@@ -1,3 +1,4 @@
1
+ import { displayReasoningMode } from "../lib/reasoning-controls.js";
1
2
  import { formatTime, textOf } from "../lib/text-format.js";
2
3
  import { getNumber } from "../lib/event-presentation.js";
3
4
 
@@ -91,7 +92,7 @@ function healthSummary(read) {
91
92
  label: "System health · all environments",
92
93
  items: [
93
94
  { label: "Health · all environments", value: unavailable || healthValue(payload.ok), status: true },
94
- { label: "Runtime mode", value: unavailable || textOf(payload.agentMode, "-") || "-" },
95
+ { label: "Runtime mode", value: unavailable || textOf(displayReasoningMode(payload.agentMode), "-") || "-" },
95
96
  { label: "Active streams", value: unavailable || activeStreamCount(payload) },
96
97
  { label: "Latest event", value: unavailable || textOf(latest?.lastEventName || latest?.lastEventType, "-") || "-" },
97
98
  ],
@@ -1,3 +1,5 @@
1
+ import { needsCollectionConsentReview } from "./collection-access.js";
2
+
1
3
  const activities = Object.freeze({
2
4
  collection: { label: "collection", permissionField: "collectionEnabled", selector: "[data-learning-toggle]" },
3
5
  learning: { label: "learning", permissionField: "processingEnabled", selector: "[data-learning-processing-toggle]" },
@@ -42,6 +44,8 @@ export function activityStatePatch(activity, preferences, running) {
42
44
  export function activityControl(activity, snapshot) {
43
45
  const definition = activities[activity];
44
46
  const preferences = snapshot.status?.preferences || {};
47
+ if (activity === "collection" && needsCollectionConsentReview(snapshot.status))
48
+ return { action: "start", label: "Review collection access", tone: "setup" };
45
49
  if (isActivityRunning(activity, preferences))
46
50
  return { action: "stop", label: `Stop ${definition.label}`, tone: "danger" };
47
51
  if (!hasActivityModel(activity, preferences, snapshot.models))
@@ -0,0 +1,35 @@
1
+ import { hostSetupIsReady } from "../system-host/rendering.js";
2
+ import { isNativeWindowsLocalAccess } from "../system-host/native-windows-access.js";
3
+
4
+ export function hasCollectionAccess(hostConnection) {
5
+ if (isNativeWindowsLocalAccess(hostConnection)) return true;
6
+ return hostSetupIsReady(hostConnection);
7
+ }
8
+
9
+ export function needsCollectionConsentReview(status) {
10
+ if (status?.preferences?.enabled !== true) return false;
11
+ const reason = status.collectionReason || status.reason;
12
+ return reason === "collection_consent_required";
13
+ }
14
+
15
+ function collectionCompanionVersion(host) {
16
+ if (isNativeWindowsLocalAccess(host)) return "";
17
+ const companion = host?.companion;
18
+ if (!companion) return "Connect your computer to check its companion version.";
19
+ return `Installed version: ${companion.installedVersion ?? "unversioned"} · Available: ${companion.availableVersion}`;
20
+ }
21
+
22
+ /** Display the actual collection source without treating Companion identity as Runtime identity. */
23
+ export function renderCollectionAccess(root, snapshot) {
24
+ const native = isNativeWindowsLocalAccess(snapshot.hostConnection);
25
+ const version = root.querySelector("[data-learning-companion-version]");
26
+ version.hidden = native;
27
+ version.textContent = collectionCompanionVersion(snapshot.hostConnection);
28
+ root.querySelector("[data-learning-computer-access]").hidden = native;
29
+ root.querySelector("[data-learning-connection-title]").textContent = native ? "Local collection" : "Computer connection";
30
+ root.querySelector("[data-learning-connection-description]").textContent = native
31
+ ? "Spark collects activity directly on this Windows computer after your consent. Collection and learning have separate permission and Start controls."
32
+ : "Collection uses the shared Computer access connection. Computer tools have their own controls.";
33
+ root.querySelector("[data-learning-device]").textContent = native
34
+ ? "This Windows computer" : snapshot.status?.deviceId || "Not connected now";
35
+ }
@@ -0,0 +1,59 @@
1
+ /** One explicit, initially unchecked acknowledgment before saving installation consent. */
2
+ export function createCollectionConsentDialog({ container }) {
3
+ const documentRoot = container.ownerDocument;
4
+ const dialog = documentRoot.createElement("dialog");
5
+ dialog.className = "mac-permission-dialog collection-consent-dialog";
6
+ dialog.setAttribute("aria-labelledby", "collectionConsentTitle");
7
+ dialog.setAttribute("aria-describedby", "collectionConsentDescription");
8
+ dialog.innerHTML = `<div class="mac-permission-content">
9
+ <div class="mac-permission-top"><span class="mac-permission-eyebrow">ABot Spark · Activity collection</span>
10
+ <button type="button" class="mac-permission-close" data-collection-consent-cancel aria-label="Cancel and close">×</button></div>
11
+ <h2 id="collectionConsentTitle" tabindex="-1">Before allowing activity collection</h2>
12
+ <p id="collectionConsentDescription" class="mac-permission-description">Spark can read accessible text and activity from your applications, including window titles and URLs. This may include personal or sensitive information.</p>
13
+ <p class="mac-permission-usage">When learning is enabled, collected content is sent to your selected learning model. A remote model provider receives that content outside this computer.</p>
14
+ <p class="mac-permission-usage">Collection and learning have separate controls. You can stop collection, exclude applications, or delete pending activity in Spark. Stopping collection does not recall content already sent to model providers. Saving this acknowledgment alone does not start collection.</p>
15
+ <p class="mac-permission-path-note">This acknowledgment is saved for this ABot installation and kept across updates.</p>
16
+ <label class="collection-consent-acknowledgment"><input type="checkbox" data-collection-consent-acknowledged />
17
+ <span>I understand and agree to the <a href="https://abot-ai.com/terms/#software" target="_blank" rel="noopener noreferrer">Software Terms</a> and <a href="https://abot-ai.com/privacy/#software" target="_blank" rel="noopener noreferrer">Software Privacy Policy</a>.</span></label>
18
+ </div><div class="mac-permission-footer"><span>Collection starts only through Spark controls.</span>
19
+ <div><button type="button" data-collection-consent-cancel>Cancel</button>
20
+ <button type="button" class="mac-permission-continue" data-collection-consent-continue disabled>Continue</button></div>
21
+ </div>`;
22
+ (documentRoot.body ?? container).append(dialog);
23
+ const checkbox = dialog.querySelector("[data-collection-consent-acknowledged]");
24
+ const proceed = dialog.querySelector("[data-collection-consent-continue]");
25
+ let pending;
26
+ let returnFocus;
27
+
28
+ function finish(approved) {
29
+ if (!pending) return;
30
+ const resolve = pending;
31
+ pending = undefined;
32
+ dialog.close();
33
+ if (returnFocus?.isConnected && !returnFocus.closest("[hidden]")) returnFocus.focus();
34
+ resolve(approved);
35
+ }
36
+ checkbox.addEventListener("change", () => { proceed.disabled = !checkbox.checked; });
37
+ proceed.addEventListener("click", () => {
38
+ if (!checkbox.checked || proceed.disabled) return;
39
+ finish(true);
40
+ });
41
+ for (const button of dialog.querySelectorAll("[data-collection-consent-cancel]"))
42
+ button.addEventListener("click", () => finish(false));
43
+ dialog.addEventListener("cancel", (event) => { event.preventDefault(); finish(false); });
44
+ dialog.addEventListener("close", () => finish(false));
45
+ return {
46
+ confirm() {
47
+ if (pending) return Promise.resolve(false);
48
+ checkbox.checked = false;
49
+ proceed.disabled = true;
50
+ returnFocus = documentRoot.activeElement;
51
+ return new Promise((resolve) => {
52
+ pending = resolve;
53
+ dialog.showModal();
54
+ dialog.querySelector("h2").focus();
55
+ });
56
+ },
57
+ cancel() { finish(false); },
58
+ };
59
+ }
@@ -0,0 +1,94 @@
1
+ import { createCollectionConsentDialog } from "./collection-consent-dialog.js";
2
+ import { hasCollectionAccess, needsCollectionConsentReview } from "./collection-access.js";
3
+ import { readActivityPermissions } from "./activity-controls.js";
4
+
5
+ function requestsCollectionAccess(preferences, snapshot) {
6
+ if (preferences.enabled === false || preferences.activityPermissions?.collection === false) return false;
7
+ if (preferences.enabled === true) return true;
8
+ if (preferences.activityPermissions?.collection !== true) return false;
9
+ return !readActivityPermissions(snapshot.status?.preferences).collection;
10
+ }
11
+
12
+ function collectionRequestContext(snapshot) {
13
+ const host = snapshot.hostConnection;
14
+ return JSON.stringify([
15
+ snapshot.environmentId, host?.collectionSource, host?.hostId,
16
+ host?.connected, host?.connectionId, snapshot.status?.preferences?.modelProfileId,
17
+ snapshot.status?.preferences?.enabled,
18
+ ]);
19
+ }
20
+
21
+ /** Installation consent precedes platform permission preparation and explicit activation. */
22
+ export function createCollectionConsentGate({
23
+ actions, container, openComputerAccess = () => {}, createDialog = createCollectionConsentDialog,
24
+ }) {
25
+ let dialog;
26
+ let pending;
27
+ let revision = 0;
28
+ function cancel() {
29
+ revision += 1;
30
+ pending = undefined;
31
+ dialog?.cancel();
32
+ }
33
+ function requestIsCurrent(request) {
34
+ if (pending !== request) return false;
35
+ return collectionRequestContext(actions.snapshot()) === request.context;
36
+ }
37
+ async function continueRequest(preferences, request) {
38
+ try {
39
+ if (actions.snapshot().hostConnection?.collectionConsent?.accepted !== true) {
40
+ const freshHost = await actions.refreshCollectionAccess();
41
+ if (!freshHost || !requestIsCurrent(request)) return;
42
+ }
43
+ if (actions.snapshot().hostConnection?.collectionConsent?.accepted !== true) {
44
+ dialog ??= createDialog({ container });
45
+ const approved = await dialog.confirm();
46
+ if (!approved || !requestIsCurrent(request)) return;
47
+ request.acknowledging = true;
48
+ const host = await actions.acceptCollectionConsent();
49
+ request.acknowledging = false;
50
+ if (!requestIsCurrent(request)) return;
51
+ if (host?.collectionConsent?.accepted !== true) return;
52
+ }
53
+ if (!requestIsCurrent(request)) return;
54
+ const snapshot = actions.snapshot();
55
+ if (preferences.enabled === true && !hasCollectionAccess(snapshot.hostConnection)) {
56
+ pending = undefined;
57
+ openComputerAccess();
58
+ return;
59
+ }
60
+ pending = undefined;
61
+ if (request.restart) return actions.restartCollection();
62
+ const restartAfterConsent = preferences.enabled === true && needsCollectionConsentReview(snapshot.status);
63
+ const status = await actions.configure(preferences);
64
+ if (!restartAfterConsent || !status?.preferences?.enabled) return status;
65
+ if (request.revision !== revision) return status;
66
+ if (collectionRequestContext(actions.snapshot()) !== request.context) return status;
67
+ return actions.restartCollection();
68
+ } finally {
69
+ if (pending === request) pending = undefined;
70
+ }
71
+ }
72
+ function configure(preferences, restart = false) {
73
+ const snapshot = actions.snapshot();
74
+ if (!requestsCollectionAccess(preferences, snapshot)) {
75
+ cancel();
76
+ return actions.configure(preferences);
77
+ }
78
+ if (pending) return;
79
+ if (snapshot.saving || snapshot.loadingStatus || !snapshot.status) return;
80
+ const request = { context: collectionRequestContext(snapshot), acknowledging: false, restart, revision };
81
+ pending = request;
82
+ return continueRequest(preferences, request);
83
+ }
84
+ return {
85
+ configure,
86
+ restartCollection: () => configure({ enabled: true }, true),
87
+ update(snapshot) {
88
+ if (!pending) return;
89
+ if (collectionRequestContext(snapshot) !== pending.context) return cancel();
90
+ if (snapshot.saving && !pending.acknowledging) cancel();
91
+ },
92
+ cancel,
93
+ };
94
+ }
@@ -1,3 +1,5 @@
1
+ import { isNativeWindowsLocalAccess } from "../system-host/native-windows-access.js";
2
+
1
3
  export function computerUpdateNoticeMarkup() {
2
4
  return `<div class="co-worker-computer-update" data-learning-update hidden role="status">
3
5
  <span class="co-worker-computer-update-icon" aria-hidden="true">↑</span>
@@ -8,6 +10,10 @@ export function computerUpdateNoticeMarkup() {
8
10
  }
9
11
 
10
12
  export function renderComputerUpdateNotice(root, snapshot) {
13
+ if (isNativeWindowsLocalAccess(snapshot.hostConnection)) {
14
+ root.querySelector("[data-learning-update]").hidden = true;
15
+ return;
16
+ }
11
17
  root.querySelector("[data-learning-update]").hidden =
12
18
  !snapshot.hostConnection?.companion?.updateAvailable;
13
19
  }
@@ -2,6 +2,7 @@ const genericMessage = "ABot Spark could not complete this review. No specific c
2
2
 
3
3
  // Exact content-free codes only. Never turn an arbitrary provider error into UI copy.
4
4
  const groups = [
5
+ ["Review and acknowledge Spark activity collection before starting it. No activity is collected until you continue.", ["collection_consent_required"]],
5
6
  ["macOS Accessibility permission is required. Open Computer access for the exact companion executable to approve. Spark waits up to two minutes for your consent.", ["macos_accessibility_permission_required"]],
6
7
  ["macOS Accessibility permission was removed. Re-enable access for the companion in Computer access, then stop and start collection.", ["macos_accessibility_permission_revoked"]],
7
8
  ["macOS Accessibility permission was not granted within two minutes. Complete permission setup in Computer access, then stop and start collection to check again.", ["macos_accessibility_permission_timeout"]],
@@ -0,0 +1,32 @@
1
+ import { coWorkerActivityStates, coWorkerActivityTones } from "./agent-state.js";
2
+
3
+ const indicators = {
4
+ off: { icon: "paused", tone: "neutral" },
5
+ waiting: { icon: "active", tone: "neutral" },
6
+ ready: { icon: "success", tone: "success" },
7
+ active: { icon: "active", tone: "active" },
8
+ attention: { icon: "failed", tone: "attention" },
9
+ };
10
+
11
+ /** Read-only projection of the same activity states used by the expanded owner. */
12
+ export function learningWidgetPreview(status) {
13
+ if (!status?.preferences) return null;
14
+ const states = coWorkerActivityStates(status);
15
+ const tones = coWorkerActivityTones(status);
16
+ return {
17
+ kind: "metrics",
18
+ items: [
19
+ ["collection", "Collection"],
20
+ ["processing", "Learning"],
21
+ ["proactive", "Proactive"],
22
+ ].map(([key, label]) => {
23
+ const indicator = { ...(indicators[tones[key]] || indicators.off) };
24
+ indicator.label = [label, ...states[key]].filter(Boolean).join(": ");
25
+ if (key === "collection" && tones[key] === "active") indicator.icon = "collecting";
26
+ if (key === "processing" && ["ready", "waiting"].includes(tones[key])
27
+ && Number.isFinite(status.pendingObservations) && status.pendingObservations > 0)
28
+ indicator.value = status.pendingObservations;
29
+ return { label, indicator };
30
+ }),
31
+ };
32
+ }
@@ -1,4 +1,4 @@
1
- import { hostSetupIsReady } from "../system-host/rendering.js";
1
+ import { hasCollectionAccess, needsCollectionConsentReview } from "./collection-access.js";
2
2
  import { agentMarkup, renderAgent } from "./agent-view.js";
3
3
  import { createAgentMotion } from "./agent-motion.js";
4
4
  import { learningFailurePresentation } from "./presentation.js";
@@ -10,11 +10,12 @@ function canStartHomeLearning(snapshot) {
10
10
  if (snapshot.statusError || learningFailurePresentation(snapshot.status))
11
11
  return false;
12
12
  if (readActivityPermissions(snapshot.status.preferences).collection)
13
- return hostSetupIsReady(snapshot.hostConnection);
13
+ return hasCollectionAccess(snapshot.hostConnection);
14
14
  return true;
15
15
  }
16
16
 
17
17
  function homeLearningActionLabel(snapshot) {
18
+ if (needsCollectionConsentReview(snapshot.status)) return "Review collection access";
18
19
  if (hasIndependentHomeActivity(snapshot.status)) return "Open ABot Spark";
19
20
  return canStartHomeLearning(snapshot)
20
21
  ? "Start ABot Spark"
@@ -36,8 +37,10 @@ export function createPassiveLearningHome({
36
37
  let root = null;
37
38
  let renderedSnapshot = {};
38
39
  let motion;
40
+ let onRendered = () => {};
39
41
 
40
- function mount(nextRoot) {
42
+ function mount(nextRoot, notify = () => {}) {
43
+ onRendered = notify;
41
44
  if (root === nextRoot) return;
42
45
  motion?.dispose();
43
46
  root?.removeEventListener("click", handleClick);
@@ -59,6 +62,10 @@ export function createPassiveLearningHome({
59
62
  if (!button || !root.contains(button) || button.disabled) return;
60
63
  const snapshot = actions?.snapshot?.() ?? renderedSnapshot;
61
64
  if (snapshot.saving || snapshot.loadingStatus) return;
65
+ if (needsCollectionConsentReview(snapshot.status)) {
66
+ void actions.configure({ enabled: true });
67
+ return;
68
+ }
62
69
  if (hasIndependentHomeActivity(snapshot.status)) {
63
70
  openLearning();
64
71
  return;
@@ -83,6 +90,7 @@ export function createPassiveLearningHome({
83
90
  const error = root.querySelector("[data-learning-status]");
84
91
  error.textContent = snapshot.statusError || "";
85
92
  error.hidden = !snapshot.statusError;
93
+ onRendered();
86
94
  }
87
95
 
88
96
  return Object.freeze({ mount, render });
@@ -5,6 +5,7 @@ const permissionReasons = new Set([
5
5
  ]);
6
6
 
7
7
  function hasEnabledMacCollection(snapshot) {
8
+ if (snapshot.hostConnection?.collectionSource?.mode === "native") return false;
8
9
  if (snapshot.hostConnection?.identity?.os !== "macos") return false;
9
10
  return snapshot.status?.preferences?.enabled === true;
10
11
  }
@@ -1,3 +1,4 @@
1
+ import { renderCollectionAccess } from "./collection-access.js";
1
2
  import { renderAgent } from "./agent-view.js";
2
3
  import { renderComputerUpdateNotice } from "./computer-update-notice.js";
3
4
  import { renderMacCollectionRestartNotice, handleMacCollectionRestartClick } from "./macos-collection-restart-notice.js";
@@ -133,11 +134,9 @@ export function createPassiveLearningMemory({
133
134
 
134
135
  function renderStatus(snapshot) {
135
136
  const status = snapshot.status;
136
- const companion = snapshot.hostConnection?.companion;
137
+ renderCollectionAccess(root, snapshot);
137
138
  renderComputerUpdateNotice(root, snapshot);
138
139
  renderMacCollectionRestartNotice(root, snapshot);
139
- root.querySelector("[data-learning-companion-version]").textContent = companion
140
- ? `Installed version: ${companion.installedVersion ?? "unversioned"} · Available: ${companion.availableVersion}` : "Connect your computer to check its companion version.";
141
140
  const attention = learningFailurePresentation(status);
142
141
  const coverage = learningCoveragePresentation(status);
143
142
  root.querySelector("[data-learning-attention]").hidden = !attention;
@@ -150,7 +149,6 @@ export function createPassiveLearningMemory({
150
149
  root.querySelector("[data-learning-schedule-summary]").textContent = modelId
151
150
  ? `${model?.label || modelId} · ${learningCadenceLabel(status.preferences)}`
152
151
  : "Choose a model in Settings to get started.";
153
- root.querySelector("[data-learning-device]").textContent = status?.deviceId || "Not connected now";
154
152
  root.querySelector("[data-learning-coverage]").textContent = coverage.label;
155
153
  root.querySelector("[data-learning-coverage-detail]").textContent = coverage.detail;
156
154
  const reasons = [status?.collectionReason, status?.processingReason, status?.reason, status?.proactive?.reason, status?.reassessment?.reason, status?.maintenanceReason].filter(Boolean);
@@ -36,9 +36,9 @@ export function learningWorkspaceMarkup(timeZone) {
36
36
  <section class="passive-learning-panel" id="learning-chat-panel" role="tabpanel" tabindex="0" aria-labelledby="learning-chat-tab" data-learning-panel="chat" hidden></section>
37
37
  <section class="passive-learning-panel" id="learning-settings-panel" role="tabpanel" tabindex="0" aria-labelledby="learning-settings-tab" data-learning-panel="settings" hidden>
38
38
  ${learningSettingsMarkup(timeZone)}
39
- <details class="passive-learning-setup" data-learning-setup><summary>Computer connection</summary>
39
+ <details class="passive-learning-setup" data-learning-setup><summary data-learning-connection-title>Computer connection</summary>
40
40
  <dl class="passive-learning-facts co-worker-connection-facts"><div><dt>Computer</dt><dd data-learning-device>—</dd></div><div><dt>Collection access</dt><dd><span data-learning-coverage>—</span><small data-learning-coverage-detail></small></dd></div></dl>
41
- <p data-learning-companion-version></p><p>Collection uses the shared Computer access connection. Computer tools have their own controls.</p><button type="button" data-learning-computer-access>Manage Computer access</button></details>
41
+ <p data-learning-companion-version></p><p data-learning-connection-description></p><button type="button" data-learning-computer-access>Manage Computer access</button></details>
42
42
  </section>
43
43
  <section class="passive-learning-panel" id="learning-usage-panel" role="tabpanel" tabindex="0" aria-labelledby="learning-usage-tab" data-learning-panel="usage" hidden>${learningUsageMarkup()}</section>
44
44
  </section>`;
@@ -0,0 +1,13 @@
1
+ import { escapeAttribute, escapeHtml } from "../../lib/text-format.js";
2
+
3
+ export function isPluginPlatformUnavailable(compatibility) {
4
+ return compatibility?.supported === false;
5
+ }
6
+
7
+ export function renderPluginPlatformNotice(compatibility) {
8
+ if (!isPluginPlatformUnavailable(compatibility)) return "";
9
+ const platform = compatibility.runtimePlatform || "this host";
10
+ const reason =
11
+ compatibility.reason || "This plugin cannot load on this host.";
12
+ return `<p class="plugin-capability-policy plugin-platform-notice" data-plugin-platform="${escapeAttribute(platform)}"><strong>Unavailable on this host.</strong> ${escapeHtml(reason)}</p>`;
13
+ }
@@ -1,12 +1,20 @@
1
+ import {
2
+ isPluginPlatformUnavailable,
3
+ renderPluginPlatformNotice,
4
+ } from "./compatibility.js";
1
5
  import { renderPluginConfigurationFields } from "./configuration-fields.js";
2
6
  import { escapeAttribute, escapeHtml } from "../../lib/text-format.js";
3
7
 
4
8
  function renderPluginReview(review, busy) {
5
9
  if (!review) return "";
6
- const installButton = `<button type="button" class="primary-button" data-plugin-install-confirm ${busy ? "disabled" : ""}>${busy ? "Installing…" : "Install and enable"}</button>`;
10
+ const installLabel = isPluginPlatformUnavailable(review.compatibility)
11
+ ? "Install"
12
+ : "Install and enable";
13
+ const installButton = `<button type="button" class="primary-button" data-plugin-install-confirm ${busy ? "disabled" : ""}>${busy ? "Installing…" : installLabel}</button>`;
7
14
  return `<section class="plugin-install-review" aria-label="Plugin installation review">
8
15
  <header class="plugin-install-heading"><div><h3>${escapeHtml(review.id)} ${review.version ? `<small>v${escapeHtml(review.version)}</small>` : ""}</h3><p>Not installed yet.</p></div>${installButton}</header>
9
16
  <p>${escapeHtml(review.description)}</p>
17
+ ${renderPluginPlatformNotice(review.compatibility)}
10
18
  <dl><dt>Source</dt><dd>${escapeHtml(review.source.repository)}</dd><dt>Commit</dt><dd><code>${escapeHtml(review.source.ref)}</code></dd></dl>
11
19
  <ul class="plugin-install-capabilities">${review.capabilities.map((capability) => `<li><strong>${escapeHtml(capability.id)}</strong><p>${escapeHtml(capability.description)}</p><span>${capability.operations.map((operation) => escapeHtml(`${operation.name} · ${operation.effect}`)).join(" / ")}</span></li>`).join("")}</ul>
12
20
  ${renderPluginConfigurationFields(review.configuration, busy)}
@@ -0,0 +1,7 @@
1
+ import { isPluginPlatformUnavailable } from "./compatibility.js";
2
+
3
+ export function pluginInstallationMessage(review) {
4
+ if (isPluginPlatformUnavailable(review.compatibility))
5
+ return `${review.id} installed. It will not load on this Runtime: ${review.compatibility.reason}`;
6
+ return `${review.id} installed. Apply changes to make it available.`;
7
+ }
@@ -1,3 +1,4 @@
1
+ import { pluginInstallationMessage } from "./installation-compatibility.js";
1
2
  import { createPluginConfigurationDraft } from "./configuration-draft.js";
2
3
  import {
3
4
  bindPluginConfigurationFields,
@@ -125,7 +126,7 @@ export function createPluginInstallation({
125
126
  state.dirty = false;
126
127
  state.review = null;
127
128
  state.installedPluginId = review.id;
128
- state.message = `${review.id} installed. Apply changes to make it available.`;
129
+ state.message = pluginInstallationMessage(review);
129
130
  onInstalled(result);
130
131
  onConfigurationSaved();
131
132
  const refreshed = await refreshRuntimeConfig(
@@ -1,3 +1,4 @@
1
+ import { renderPluginPlatformNotice } from "./compatibility.js";
1
2
  import { escapeAttribute, escapeHtml } from "../../lib/text-format.js";
2
3
 
3
4
  function pluginMasterIsEnabled(plugin) {
@@ -50,6 +51,7 @@ function renderCapabilities(plugin, busy, open) {
50
51
  <button type="button" data-plugin-tools-back="${escapeAttribute(plugin.id)}" aria-label="${escapeAttribute(`Back to ${plugin.id}`)}">Back</button>
51
52
  <div><h4 title="${escapeAttribute(plugin.id)}">${escapeHtml(plugin.id)}</h4><span>Tools (${capabilities.length})</span></div>
52
53
  </header>
54
+ ${renderPluginPlatformNotice(plugin.compatibility)}
53
55
  <ul class="plugin-capability-list" data-plugin-tools-scroll="${escapeAttribute(plugin.id)}">
54
56
  ${capabilities.length ? capabilities.map((capability) => renderCapabilityRow(plugin, capability, busy)).join("") : '<li class="plugin-capability-empty">This plugin does not expose any tools.</li>'}
55
57
  </ul>
@@ -78,6 +80,7 @@ function renderPluginCard(
78
80
  <span class="plugin-selection-state" data-plugin-state="${escapeAttribute(plugin.state)}">${configuredPluginLabel(plugin)}</span>
79
81
  </div>
80
82
  <p class="plugin-description" title="${escapeAttribute(plugin.description || "Installed Runtime plugin.")}">${escapeHtml(plugin.description || "Installed Runtime plugin.")}</p>
83
+ ${renderPluginPlatformNotice(plugin.compatibility)}
81
84
  <div class="plugin-card-footer">
82
85
  <span>${plugin.selectedCapabilityCount} of ${plugin.capabilityCount} capabilities selected</span>
83
86
  <div class="plugin-card-actions">