@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,9 @@
1
+ export type CollectionConsent = Readonly<{
2
+ accepted: boolean;
3
+ acceptedAt?: string;
4
+ }>;
5
+ /** Installation data, shared across environments and independent of app versions or pairing. */
6
+ export declare function readCollectionConsent(rootDir: string): CollectionConsent;
7
+ /** Acknowledgment records awareness only; it does not change activity permissions or start collection. */
8
+ export declare function acceptCollectionConsent(rootDir: string): Promise<CollectionConsent>;
9
+ export declare function requireCollectionConsent(rootDir: string): void;
@@ -0,0 +1,47 @@
1
+ import { join } from "node:path";
2
+ import { ensurePrivateRuntimeDirectory } from "../runtime/local-host/private-directory.js";
3
+ import { hostStateDirectory, readHostPrivateJson, writeHostPrivateJson, } from "./companion/private-store.js";
4
+ function isSavedCollectionConsent(value) {
5
+ if (!value || typeof value !== "object" || Array.isArray(value))
6
+ return false;
7
+ const record = value;
8
+ if (record.version !== 1)
9
+ return false;
10
+ if (typeof record.acceptedAt !== "string")
11
+ return false;
12
+ return Number.isFinite(Date.parse(record.acceptedAt));
13
+ }
14
+ function collectionConsentPath(rootDir) {
15
+ return join(hostStateDirectory(rootDir), "collection-consent.json");
16
+ }
17
+ /** Installation data, shared across environments and independent of app versions or pairing. */
18
+ export function readCollectionConsent(rootDir) {
19
+ let record;
20
+ try {
21
+ record = readHostPrivateJson(collectionConsentPath(rootDir));
22
+ }
23
+ catch (error) {
24
+ // A malformed record never authorizes collection. Filesystem safety errors remain visible.
25
+ if (error instanceof SyntaxError)
26
+ return { accepted: false };
27
+ throw error;
28
+ }
29
+ if (!isSavedCollectionConsent(record))
30
+ return { accepted: false };
31
+ return { accepted: true, acceptedAt: record.acceptedAt };
32
+ }
33
+ /** Acknowledgment records awareness only; it does not change activity permissions or start collection. */
34
+ export async function acceptCollectionConsent(rootDir) {
35
+ await ensurePrivateRuntimeDirectory(hostStateDirectory(rootDir));
36
+ const existing = readCollectionConsent(rootDir);
37
+ if (existing.accepted)
38
+ return existing;
39
+ const acceptedAt = new Date().toISOString();
40
+ writeHostPrivateJson(collectionConsentPath(rootDir), { version: 1, acceptedAt });
41
+ return { accepted: true, acceptedAt };
42
+ }
43
+ export function requireCollectionConsent(rootDir) {
44
+ if (readCollectionConsent(rootDir).accepted)
45
+ return;
46
+ throw new Error("collection_consent_required");
47
+ }
@@ -10,8 +10,12 @@ export type SystemOutputReceipt = Readonly<{
10
10
  stdoutSha256?: string;
11
11
  stderrSha256?: string;
12
12
  }>;
13
- /** One synchronous command capture; no resumable-process or cursor state. */
14
- export declare function createSystemOutputCapture(root: string, retentionMs: number): Promise<{
13
+ type OutputStreams = {
14
+ stdout: string;
15
+ stderr: string;
16
+ };
17
+ /** Private backpressured capture. No read is admitted before complete checks. */
18
+ export declare function createSystemOutputCapture(root: string, retentionMs: number, redact: (text: string) => string): Promise<{
15
19
  capture: Readonly<{
16
20
  attach(stdout: Readable, stderr: Readable, onFailure: () => void): void;
17
21
  end(): void;
@@ -27,11 +31,18 @@ export declare function createSystemOutputCapture(root: string, retentionMs: num
27
31
  stderrSha256?: string;
28
32
  }> | undefined;
29
33
  readonly failure: string | undefined;
34
+ readonly failureKind: "storage" | "security" | undefined;
35
+ readonly processResult: Readonly<{
36
+ exitCode: number | null;
37
+ stdout: string;
38
+ stderr: string;
39
+ status: "completed" | "timeout" | "aborted" | "spawn_failed" | "output_failed";
40
+ outputTruncated: boolean;
41
+ spawnedProcess?: import("./contracts.js").SystemSpawnObservation;
42
+ }> | undefined;
30
43
  retain(): void;
31
44
  release(): void;
32
45
  read(stream: "stdout" | "stderr", offset: number, length: number): Promise<Buffer>;
33
- finish(result?: SystemProcessResult, materialize?: boolean): Promise<{
34
- stdout: string;
35
- stderr: string;
36
- }>;
46
+ finish(result?: SystemProcessResult, materialize?: boolean): Promise<OutputStreams>;
37
47
  }>;
48
+ export {};
@@ -1,14 +1,18 @@
1
1
  import { createHash, randomUUID } from "node:crypto";
2
2
  import { once } from "node:events";
3
3
  import { createWriteStream } from "node:fs";
4
- import { mkdir, open, readFile, rename, stat, writeFile } from "node:fs/promises";
4
+ import { mkdir, open, rename, writeFile } from "node:fs/promises";
5
5
  import { join } from "node:path";
6
6
  import { finished } from "node:stream/promises";
7
7
  import { SystemOperationError } from "./contracts.js";
8
+ import { CapturedOutputProtectionError, discardCapturedOutput, protectCapturedOutput } from "./command-output-protection.js";
8
9
  import { activeSystemCaptures, scheduleSystemOutputCleanup } from "./command-output-retention.js";
10
+ const STREAMS = ["stdout", "stderr"];
9
11
  const OUTPUT_IO_CHUNK_BYTES = 64 * 1024;
10
- /** One synchronous command capture; no resumable-process or cursor state. */
11
- export async function createSystemOutputCapture(root, retentionMs) {
12
+ /** Private backpressured capture. No read is admitted before complete checks. */
13
+ export async function createSystemOutputCapture(root, retentionMs, redact) {
14
+ if (!hasOutputProtection(redact))
15
+ throw new SystemOperationError("system_output_protection_failed", "Command output protection is unavailable. The command was not dispatched.");
12
16
  const id = randomUUID();
13
17
  const directory = join(root, id);
14
18
  activeSystemCaptures.add(directory);
@@ -19,19 +23,19 @@ export async function createSystemOutputCapture(root, retentionMs) {
19
23
  activeSystemCaptures.delete(directory);
20
24
  throw new SystemOperationError("system_output_storage_failed", "Output storage could not be prepared. The command was not dispatched.");
21
25
  }
22
- let failure;
26
+ let storageFailure, securityFailure;
23
27
  let stop;
24
- let ended = false;
25
- let retained = false;
28
+ let ended = false, retained = false, admitted = false;
29
+ let receipt;
30
+ let processResult;
31
+ let finishing;
26
32
  const sources = [];
27
- const streams = ["stdout", "stderr"].map((name) => {
28
- const path = join(directory, name + ".bytes");
29
- const sink = createWriteStream(path, { flags: "wx", mode: 0o600, highWaterMark: OUTPUT_IO_CHUNK_BYTES, flush: true });
30
- const completion = finished(sink).catch(() => {
31
- failure ??= "write_failed";
32
- stop?.();
33
- });
34
- return { name, path, sink, completion, hash: createHash("sha256") };
33
+ const completeStreams = new Set();
34
+ const paths = { stdout: join(directory, "stdout.bytes"), stderr: join(directory, "stderr.bytes") };
35
+ const streams = STREAMS.map((name) => {
36
+ const sink = createWriteStream(paths[name], { flags: "wx", mode: 0o600, highWaterMark: OUTPUT_IO_CHUNK_BYTES, flush: true });
37
+ const completion = finished(sink).catch(() => { storageFailure ??= "write_failed"; stop?.(); });
38
+ return { sink, completion };
35
39
  });
36
40
  try {
37
41
  await Promise.all(streams.map(({ sink }) => once(sink, "open")));
@@ -45,21 +49,30 @@ export async function createSystemOutputCapture(root, retentionMs) {
45
49
  throw new SystemOperationError("system_output_storage_failed", "Output files could not be opened. The command was not dispatched.");
46
50
  }
47
51
  scheduleSystemOutputCleanup(root, retentionMs);
52
+ const failure = () => storageFailure ?? securityFailure;
48
53
  const capture = {
49
54
  attach(stdout, stderr, onFailure) {
55
+ if (!canAttachCapture()) {
56
+ securityFailure ??= "output_protection_failed";
57
+ onFailure();
58
+ return;
59
+ }
50
60
  stop = onFailure;
51
61
  sources.push(stdout, stderr);
52
- stdout.on("data", (bytes) => streams[0].hash.update(bytes));
53
- stderr.on("data", (bytes) => streams[1].hash.update(bytes));
54
- stdout.pipe(streams[0].sink);
55
- stderr.pipe(streams[1].sink);
56
- if (failure)
62
+ for (const [index, source] of sources.entries()) {
63
+ source.once("end", () => completeStreams.add(STREAMS[index]));
64
+ source.once("error", () => { securityFailure ??= "output_incomplete"; stop?.(); });
65
+ source.pipe(streams[index].sink);
66
+ }
67
+ if (failure())
57
68
  onFailure();
58
69
  },
59
70
  end() {
60
71
  if (ended)
61
72
  return;
62
73
  ended = true;
74
+ if (!hasCompleteStreams())
75
+ securityFailure ??= "output_incomplete";
63
76
  for (const source of sources) {
64
77
  source.unpipe();
65
78
  source.destroy();
@@ -69,68 +82,121 @@ export async function createSystemOutputCapture(root, retentionMs) {
69
82
  sink.end();
70
83
  },
71
84
  };
72
- let receipt;
85
+ function canAttachCapture() { return sources.length === 0 && !ended; }
86
+ function hasCompleteStreams() { return completeStreams.size === 2; }
87
+ function protectProcess(result) {
88
+ if (!result)
89
+ return;
90
+ let spawnedProcess = result.spawnedProcess;
91
+ if (spawnedProcess) {
92
+ let executable = "[REDACTED]";
93
+ try {
94
+ executable = redact(spawnedProcess.executable);
95
+ if (!hasProtectedIdentity(executable))
96
+ throw new Error("output_protection_failed");
97
+ }
98
+ catch {
99
+ securityFailure ??= "output_protection_failed";
100
+ executable = "[REDACTED]";
101
+ }
102
+ spawnedProcess = { ...spawnedProcess, executable };
103
+ }
104
+ processResult = { exitCode: result.exitCode, status: result.status, outputTruncated: result.outputTruncated,
105
+ stdout: "", stderr: "", ...(spawnedProcess ? { spawnedProcess } : {}) };
106
+ }
107
+ async function finish(result, materialize = true) {
108
+ capture.end();
109
+ await Promise.all(streams.map(({ completion }) => completion));
110
+ protectProcess(result);
111
+ let protectedBytes;
112
+ try {
113
+ if (!failure()) {
114
+ try {
115
+ protectedBytes = await protectCapturedOutput(paths, redact);
116
+ }
117
+ catch (error) {
118
+ if (isOutputStorageFailure(error))
119
+ storageFailure ??= "write_failed";
120
+ else
121
+ securityFailure ??= "output_protection_failed";
122
+ }
123
+ }
124
+ if (failure() && !await discardCapturedOutput(paths))
125
+ storageFailure = "capture_purge_failed";
126
+ receipt = { id, stdoutBytes: protectedBytes?.stdout.length ?? 0, stderrBytes: protectedBytes?.stderr.length ?? 0,
127
+ completedAt: new Date().toISOString(), retentionMs, complete: !failure(), ...(!materialize && protectedBytes ? {
128
+ stdoutSha256: createHash("sha256").update(protectedBytes.stdout).digest("hex"),
129
+ stderrSha256: createHash("sha256").update(protectedBytes.stderr).digest("hex"),
130
+ } : {}) };
131
+ try {
132
+ const temporary = join(directory, "receipt.tmp");
133
+ await writeFile(temporary, JSON.stringify({ kind: "system_command_output_v1", ...receipt,
134
+ processStatus: processResult?.status, exitCode: processResult?.exitCode, spawnedProcess: processResult?.spawnedProcess,
135
+ ...(securityFailure ? { securityFailure } : {}), ...(storageFailure ? { storageFailure } : {}) }), { flag: "wx", mode: 0o600, flush: true });
136
+ await rename(temporary, join(directory, "receipt.json"));
137
+ }
138
+ catch {
139
+ storageFailure ??= "receipt_write_failed";
140
+ receipt = { ...receipt, complete: false };
141
+ }
142
+ admitted = receipt.complete;
143
+ if (!admitted || !materialize || !protectedBytes)
144
+ return { stdout: "", stderr: "" };
145
+ return { stdout: protectedBytes.stdout.toString("utf8"), stderr: protectedBytes.stderr.toString("utf8") };
146
+ }
147
+ finally {
148
+ protectedBytes?.stdout.fill(0);
149
+ protectedBytes?.stderr.fill(0);
150
+ if (!retained)
151
+ activeSystemCaptures.delete(directory);
152
+ }
153
+ }
73
154
  return {
74
155
  capture,
75
156
  get receipt() { return receipt; },
76
- get failure() { return failure; },
157
+ get failure() { return failure(); },
158
+ get failureKind() {
159
+ if (storageFailure)
160
+ return "storage";
161
+ return securityFailure ? "security" : undefined;
162
+ },
163
+ get processResult() { return processResult; },
77
164
  retain() { retained = true; activeSystemCaptures.add(directory); },
78
165
  release() { retained = false; activeSystemCaptures.delete(directory); },
79
166
  async read(stream, offset, length) {
80
- const path = streams.find((entry) => entry.name === stream).path;
81
- const file = await open(path, "r");
167
+ if (!admitted)
168
+ throw new Error("system_output_unavailable");
169
+ if (!isAdmittedOutputRead(stream, offset, length, receipt))
170
+ throw new Error("system_output_reference_invalid");
171
+ const file = await open(paths[stream], "r");
82
172
  try {
83
- const bytes = Buffer.alloc(length);
84
- const { bytesRead } = await file.read(bytes, 0, length, offset);
173
+ const size = stream === "stdout" ? receipt.stdoutBytes : receipt.stderrBytes;
174
+ const bytes = Buffer.alloc(Math.min(length, size - offset));
175
+ const { bytesRead } = await file.read(bytes, 0, bytes.length, offset);
85
176
  return bytes.subarray(0, bytesRead);
86
177
  }
87
178
  finally {
88
179
  await file.close();
89
180
  }
90
181
  },
91
- async finish(result, materialize = true) {
92
- capture.end();
93
- try {
94
- await Promise.all(streams.map(({ completion }) => completion));
95
- const sizes = await Promise.all(streams.map(async ({ path }) => {
96
- try {
97
- return (await stat(path)).size;
98
- }
99
- catch {
100
- failure ??= "read_failed";
101
- return 0;
102
- }
103
- }));
104
- let stdout = "", stderr = "";
105
- if (!failure && materialize) {
106
- try {
107
- [stdout, stderr] = await Promise.all(streams.map(({ path }) => readFile(path, "utf8")));
108
- }
109
- catch {
110
- failure = "read_failed";
111
- }
112
- }
113
- const completedAt = Date.now();
114
- receipt = { id, stdoutBytes: sizes[0], stderrBytes: sizes[1],
115
- completedAt: new Date(completedAt).toISOString(), retentionMs, complete: !failure,
116
- ...(!materialize ? { stdoutSha256: streams[0].hash.digest("hex"), stderrSha256: streams[1].hash.digest("hex") } : {}) };
117
- try {
118
- const temporary = join(directory, "receipt.tmp");
119
- await writeFile(temporary, JSON.stringify({ kind: "system_command_output_v1", ...receipt,
120
- processStatus: result?.status, exitCode: result?.exitCode, spawnedProcess: result?.spawnedProcess,
121
- ...(failure ? { storageFailure: failure } : {}) }), { flag: "wx", mode: 0o600, flush: true });
122
- await rename(temporary, join(directory, "receipt.json"));
123
- }
124
- catch {
125
- failure ??= "receipt_write_failed";
126
- receipt = { ...receipt, complete: false };
127
- }
128
- return { stdout, stderr };
129
- }
130
- finally {
131
- if (!retained)
132
- activeSystemCaptures.delete(directory);
133
- }
182
+ finish(result, materialize = true) {
183
+ finishing ??= finish(result, materialize);
184
+ return finishing;
134
185
  },
135
186
  };
136
187
  }
188
+ function hasOutputProtection(value) { return typeof value === "function"; }
189
+ function hasProtectedIdentity(value) { return typeof value === "string"; }
190
+ function isOutputStorageFailure(error) {
191
+ return error instanceof CapturedOutputProtectionError && error.reason === "output_storage_failed";
192
+ }
193
+ function isAdmittedOutputRead(stream, offset, length, receipt) {
194
+ if (stream !== "stdout" && stream !== "stderr")
195
+ return false;
196
+ if (!Number.isSafeInteger(offset) || offset < 0)
197
+ return false;
198
+ if (!Number.isSafeInteger(length) || length < 0)
199
+ return false;
200
+ const size = stream === "stdout" ? receipt.stdoutBytes : receipt.stderrBytes;
201
+ return offset <= size;
202
+ }
@@ -0,0 +1,17 @@
1
+ export type CapturedOutputPaths = Readonly<{
2
+ stdout: string;
3
+ stderr: string;
4
+ }>;
5
+ export type ProtectedOutputBytes = Readonly<{
6
+ stdout: Buffer;
7
+ stderr: Buffer;
8
+ }>;
9
+ export type OutputProtectionFailure = "output_protection_failed" | "output_storage_failed";
10
+ export declare class CapturedOutputProtectionError extends Error {
11
+ readonly reason: OutputProtectionFailure;
12
+ constructor(reason: OutputProtectionFailure);
13
+ }
14
+ /** Check both complete private streams before replacing either source. */
15
+ export declare function protectCapturedOutput(paths: CapturedOutputPaths, redact: (text: string) => string): Promise<ProtectedOutputBytes>;
16
+ /** A failed check makes the private sources unavailable, including later reads. */
17
+ export declare function discardCapturedOutput(paths: CapturedOutputPaths): Promise<boolean>;
@@ -0,0 +1,59 @@
1
+ import { readFile, rm, writeFile } from "node:fs/promises";
2
+ export class CapturedOutputProtectionError extends Error {
3
+ reason;
4
+ constructor(reason) {
5
+ super(reason);
6
+ this.reason = reason;
7
+ }
8
+ }
9
+ /** Check both complete private streams before replacing either source. */
10
+ export async function protectCapturedOutput(paths, redact) {
11
+ let stdout, stderr;
12
+ try {
13
+ stdout = await protectStream(paths.stdout, redact);
14
+ stderr = await protectStream(paths.stderr, redact);
15
+ const writes = await Promise.allSettled([
16
+ writeFile(paths.stdout, stdout, { flag: "w", mode: 0o600, flush: true }),
17
+ writeFile(paths.stderr, stderr, { flag: "w", mode: 0o600, flush: true }),
18
+ ]);
19
+ if (hasRejectedOutputWrite(writes))
20
+ throw new CapturedOutputProtectionError("output_storage_failed");
21
+ return { stdout, stderr };
22
+ }
23
+ catch (error) {
24
+ stdout?.fill(0);
25
+ stderr?.fill(0);
26
+ throw error;
27
+ }
28
+ }
29
+ async function protectStream(path, redact) {
30
+ let bytes;
31
+ try {
32
+ bytes = await readFile(path);
33
+ }
34
+ catch {
35
+ throw new CapturedOutputProtectionError("output_storage_failed");
36
+ }
37
+ try {
38
+ const text = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
39
+ const protectedText = redact(text);
40
+ if (!isProtectedOutputText(protectedText))
41
+ throw new Error("output_protection_failed");
42
+ return Buffer.from(protectedText, "utf8");
43
+ }
44
+ catch {
45
+ throw new CapturedOutputProtectionError("output_protection_failed");
46
+ }
47
+ finally {
48
+ bytes.fill(0);
49
+ }
50
+ }
51
+ /** A failed check makes the private sources unavailable, including later reads. */
52
+ export async function discardCapturedOutput(paths) {
53
+ const removed = await Promise.allSettled(Object.values(paths).map((path) => rm(path, { force: true })));
54
+ return removed.every((entry) => entry.status === "fulfilled");
55
+ }
56
+ function isProtectedOutputText(value) { return typeof value === "string"; }
57
+ function hasRejectedOutputWrite(writes) {
58
+ return writes.some((entry) => entry.status === "rejected");
59
+ }
@@ -9,5 +9,6 @@ export declare class CompanionCommandOutput {
9
9
  close(): void;
10
10
  handlers(): Record<string, ToolImplementation>;
11
11
  private command;
12
+ private hasRegisteredTransfer;
12
13
  private read;
13
14
  }
@@ -7,6 +7,8 @@ import { runSystemProcess } from "../process-runner.js";
7
7
  import { buildSystemProcessResult } from "../process-result.js";
8
8
  import { isHostIdentifier } from "./protocol.js";
9
9
  import { SYSTEM_OUTPUT_CAPABILITY, SYSTEM_OUTPUT_CHUNK_BYTES, readSystemOutputTransfer } from "./command-output-protocol.js";
10
+ import { redactSecretText } from "../security/secret-text.js";
11
+ import { systemResultProtection } from "../security/system-results.js";
10
12
  /** References belong to this authenticated connection; no arbitrary file access. */
11
13
  export class CompanionCommandOutput {
12
14
  stateDir;
@@ -55,12 +57,12 @@ export class CompanionCommandOutput {
55
57
  run: async (input) => {
56
58
  if (input.abortSignal?.aborted)
57
59
  return runSystemProcess(input);
58
- captured = await createSystemOutputCapture(join(this.stateDir, "command-output"), retentionMs);
60
+ captured = await createSystemOutputCapture(join(this.stateDir, "command-output"), retentionMs, redactSecretText);
59
61
  captured.retain();
60
62
  try {
61
63
  const result = await runSystemProcess(input, captured.capture);
62
64
  await captured.finish(result, false);
63
- return { ...result, outputTruncated: Boolean(captured.failure) };
65
+ return { ...captured.processResult, outputTruncated: Boolean(captured.failure) };
64
66
  }
65
67
  catch (error) {
66
68
  await captured.finish(undefined, false);
@@ -75,8 +77,11 @@ export class CompanionCommandOutput {
75
77
  const data = { ...receipt.data, outputCapture: captured.receipt };
76
78
  if (captured.failure) {
77
79
  captured.release();
78
- return failureResult({ errorCode: "system_output_storage_failed", message: "Command output storage failed after dispatch; inspect the process receipt before another action.",
79
- data: { ...data, storageFailure: captured.failure }, ...(result.exitCode !== null ? { exitCode: result.exitCode } : {}) });
80
+ const errorCode = captured.failureKind === "security" ? "system_output_protection_failed" : "system_output_storage_failed";
81
+ return failureResult({ errorCode, message: "Command output could not be admitted after dispatch; inspect the process receipt before another action. The command was not replayed.",
82
+ data: { ...data, ...(captured.failureKind === "security"
83
+ ? { securityFailure: captured.failure } : { storageFailure: captured.failure }) },
84
+ ...(result.exitCode !== null ? { exitCode: result.exitCode } : {}) });
80
85
  }
81
86
  if (this.closed || context?.abortSignal?.aborted) {
82
87
  captured.release();
@@ -87,9 +92,21 @@ export class CompanionCommandOutput {
87
92
  return { ...receipt, output: receipt.output.split("\nSTDOUT excerpt:")[0] + "\nSTDOUT excerpt:\nStreams retained for exact transfer.",
88
93
  data: { ...data, outputTransfer: transfer } };
89
94
  },
90
- }));
95
+ }), systemResultProtection);
91
96
  const { outputRetentionMs: _retention, ...command } = params;
92
- return handlers.system_command(command, context);
97
+ try {
98
+ return await handlers.system_command(command, context);
99
+ }
100
+ finally {
101
+ if (!this.hasRegisteredTransfer(captured))
102
+ captured?.release();
103
+ }
104
+ }
105
+ hasRegisteredTransfer(capture) {
106
+ const id = capture?.receipt?.id;
107
+ if (!id)
108
+ return false;
109
+ return this.captures.get(id) === capture;
93
110
  }
94
111
  async read(params) {
95
112
  if (!isHostIdentifier(params.captureId))
@@ -4,7 +4,8 @@ export function renderMacInstallLinkHandler(options) {
4
4
  const literal = (value) => JSON.stringify(value);
5
5
  return `ObjC.import('Foundation');
6
6
  function openDocuments() {}
7
- function openLocation(url) {
7
+ // JXA dispatches the macOS Get URL (GURL/GURL) AppleEvent to this exact name.
8
+ function GURLGURL(url) {
8
9
  var task = $.NSTask.alloc.init;
9
10
  task.launchPath = ${literal(options.nodePath)};
10
11
  task.arguments = [${literal(options.cliPath)}, 'host', 'open-link', String(url)];
@@ -1,4 +1,5 @@
1
1
  import { failureResult, successResult, } from "../../plugin-sdk/index.js";
2
+ import { redactSecretText } from "../security/secret-text.js";
2
3
  import { readDesktopNotification, } from "./notification-protocol.js";
3
4
  import { defaultNotificationLocations, } from "./notification-locations.js";
4
5
  import { sendWindowsNotification } from "./notification-windows.js";
@@ -49,7 +50,7 @@ export function createNotificationSession(platform, runtimeUrl, ready, renderer,
49
50
  ? "notification_outcome_unknown"
50
51
  : "notification_native_failed",
51
52
  message: error instanceof Error
52
- ? error.message.slice(0, 1000)
53
+ ? redactSecretText(error.message).slice(0, 1000)
53
54
  : "Desktop notification submission failed.",
54
55
  });
55
56
  }
@@ -76,7 +77,7 @@ export async function createNativeNotificationSession(platform, runtimeUrl, loca
76
77
  if (platform === "macos" && session.ready)
77
78
  await stopMacNotificationApp(locations, runNotificationProcess).catch((error) => {
78
79
  console.warn("Desktop notification helper could not stop: " +
79
- (error instanceof Error ? error.message : String(error)));
80
+ redactSecretText(error instanceof Error ? error.message : String(error)));
80
81
  });
81
82
  },
82
83
  }, (refreshSignal) => hasDesktopNotificationSupport(platform, locations, runNotificationProcess, refreshSignal));
@@ -1,6 +1,9 @@
1
1
  import WebSocket from "ws";
2
2
  import { CompanionCommandOutput } from "./command-output.js";
3
3
  import { SYSTEM_OUTPUT_CAPABILITY } from "./command-output-protocol.js";
4
+ import { HOST_SECRET_PROTECTION_CAPABILITY } from "./secret-protection-protocol.js";
5
+ import { systemResultProtection } from "../security/system-results.js";
6
+ import { redactSecretText } from "../security/secret-text.js";
4
7
  import { createNativePermissionHandlers } from "./native-permissions.js";
5
8
  import { MACOS_PERMISSION_CAPABILITY } from "./permission-protocol.js";
6
9
  import { nativeLoopbackSocketOptions } from "./native-loopback-lookup.js";
@@ -47,7 +50,7 @@ export async function connectNativeHost(options) {
47
50
  ? new CompanionCommandOutput(options.commandOutputStateDir) : undefined;
48
51
  const handlers = options.handlers ?? {
49
52
  ...commandOutput?.handlers(),
50
- ...createSystemHandlers(),
53
+ ...createSystemHandlers(undefined, undefined, undefined, systemResultProtection),
51
54
  ...computers.handlers(),
52
55
  ...notifications.handlers(),
53
56
  ...createNativePermissionHandlers(options.identity.os),
@@ -191,7 +194,7 @@ export async function connectNativeHost(options) {
191
194
  catch (error) {
192
195
  if (!(error instanceof NativeOperationInputError))
193
196
  throw error;
194
- sendResult(message.id, operationFailure(error.message, error.code));
197
+ sendResult(message.id, operationFailure(redactSecretText(error.message), error.code));
195
198
  return;
196
199
  }
197
200
  const handler = handlers[message.operation];
@@ -255,6 +258,7 @@ export async function connectNativeHost(options) {
255
258
  version: HOST_PROTOCOL_VERSION,
256
259
  identity: options.identity,
257
260
  capabilities: [
261
+ ...(options.handlers ? [] : [HOST_SECRET_PROTECTION_CAPABILITY]),
258
262
  OBSERVATION_CAPABILITY,
259
263
  COMPUTER_CAPABILITY,
260
264
  ...(commandOutput ? [SYSTEM_OUTPUT_CAPABILITY] : []),
@@ -1,32 +1,8 @@
1
1
  import { createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
2
2
  import { isHostRecord } from "./protocol.js";
3
+ import { isOwnApplicationObservation } from "../../shared/passive-observation-self-exclusion.js";
3
4
  import { redactObservationSource, redactObservationText, } from "./observation-redaction.js";
4
5
  import { isPassiveCollectorEvent, isObservationOwner, OBSERVATION_CONTENT_LIMIT, OBSERVATION_WIRE_LIMIT, } from "./observation-protocol.js";
5
- // Include the previous title so tabs opened before an update are also excluded.
6
- const OWN_WEB_UI_TITLES = ["ABot Runtime — Workspace", "ABot Runtime"];
7
- const BROWSER_WINDOW_NAMES = [
8
- "Mozilla Firefox",
9
- "Mozilla Firefox (Private Browsing)",
10
- "Google Chrome",
11
- "Chromium",
12
- "Microsoft Edge",
13
- "Brave",
14
- "Safari",
15
- ];
16
- const BROWSER_WINDOW_SUFFIXES = BROWSER_WINDOW_NAMES.flatMap((browser) => [
17
- ` — ${browser}`,
18
- ` - ${browser}`,
19
- ]);
20
- function isOwnWebUiWindowTitle(title) {
21
- if (typeof title !== "string")
22
- return false;
23
- if (OWN_WEB_UI_TITLES.includes(title))
24
- return true;
25
- const suffix = BROWSER_WINDOW_SUFFIXES.find((candidate) => title.endsWith(candidate));
26
- if (!suffix)
27
- return false;
28
- return OWN_WEB_UI_TITLES.includes(title.slice(0, -suffix.length));
29
- }
30
6
  function hasBoundedSourceMetadata(source) {
31
7
  if (!isObservationOwner(source.app))
32
8
  return false;
@@ -111,7 +87,7 @@ export class ObservationFilter {
111
87
  };
112
88
  if (!hasBoundedSourceMetadata(rawSource))
113
89
  return undefined;
114
- if (isOwnWebUiWindowTitle(rawSource.title)) {
90
+ if (isOwnApplicationObservation(rawSource)) {
115
91
  this.lastSource = undefined;
116
92
  return undefined;
117
93
  }
@@ -11,6 +11,8 @@ export declare function desktopCollectorCommand(platform: string): {
11
11
  export declare function startDesktopCollector(options: {
12
12
  excludedApplications: readonly string[];
13
13
  onEvent(event: PassiveCollectorEvent): void;
14
+ /** Confirms helper exit or that no helper was created; close alone does not confirm either. */
15
+ onStopped?(): void;
14
16
  platform?: string;
15
17
  spawnProcess?: typeof spawn;
16
18
  }): DesktopCollector;