talos-code 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +111 -3
  3. package/THIRD_PARTY_NOTICES.md +40 -0
  4. package/dist/archive/zip.js +73 -0
  5. package/dist/args.js +97 -0
  6. package/dist/automations/history-store.js +34 -0
  7. package/dist/automations/policy-store.js +43 -0
  8. package/dist/automations/runner.js +107 -0
  9. package/dist/automations/schedule.js +85 -0
  10. package/dist/automations/windows-task.js +53 -0
  11. package/dist/commands/advanced-cli.js +233 -0
  12. package/dist/commands/checkpoint-cli.js +45 -0
  13. package/dist/commands/config-cli.js +107 -0
  14. package/dist/commands/context.js +17 -0
  15. package/dist/commands/extensions-cli.js +207 -0
  16. package/dist/commands/project-cli.js +74 -0
  17. package/dist/commands/project-commands.js +143 -0
  18. package/dist/commands/provider-cli.js +185 -0
  19. package/dist/commands/services-cli.js +248 -0
  20. package/dist/commands/session-cli.js +171 -0
  21. package/dist/commands/system-cli.js +405 -0
  22. package/dist/config/commands.js +60 -0
  23. package/dist/config/load.js +382 -0
  24. package/dist/config/migrations.js +48 -0
  25. package/dist/config/types.js +11 -0
  26. package/dist/diagnostics/development-log.js +154 -0
  27. package/dist/diagnostics/doctor.js +104 -0
  28. package/dist/diagnostics/redact.js +80 -0
  29. package/dist/diagnostics/zip.js +52 -0
  30. package/dist/errors.js +156 -0
  31. package/dist/events/bridge.js +130 -0
  32. package/dist/extensions/installer.js +178 -0
  33. package/dist/extensions/package-schema.js +24 -0
  34. package/dist/headless/result.js +84 -0
  35. package/dist/headless/run.js +230 -0
  36. package/dist/i18n/en/approval.js +43 -0
  37. package/dist/i18n/en/common.js +9 -0
  38. package/dist/i18n/en/credentials.js +82 -0
  39. package/dist/i18n/en/errors.js +246 -0
  40. package/dist/i18n/en/firstrun.js +89 -0
  41. package/dist/i18n/en/providers.js +37 -0
  42. package/dist/i18n/en/screen.js +736 -0
  43. package/dist/i18n/en/tools.js +127 -0
  44. package/dist/i18n/en.js +14 -0
  45. package/dist/i18n/error-view.js +307 -0
  46. package/dist/i18n/index.js +19 -0
  47. package/dist/i18n/kernel-map.js +139 -0
  48. package/dist/io.js +45 -0
  49. package/dist/main.js +330 -0
  50. package/dist/paths.js +41 -0
  51. package/dist/protocol/v2/codec.js +9 -0
  52. package/dist/protocol/v2/events.js +555 -0
  53. package/dist/protocol/v2/index.js +4 -0
  54. package/dist/protocol/v2/replay.js +28 -0
  55. package/dist/protocol/v2/types.js +1 -0
  56. package/dist/provider/control-plane.js +135 -0
  57. package/dist/provider/environment-keys.js +275 -0
  58. package/dist/provider/health.js +110 -0
  59. package/dist/provider/missing-key.js +48 -0
  60. package/dist/provider/model-catalog.js +168 -0
  61. package/dist/provider/provider-text.js +13 -0
  62. package/dist/provider/store.js +95 -0
  63. package/dist/provider/system-keyring.js +214 -0
  64. package/dist/runtime/active-run.js +63 -0
  65. package/dist/runtime/agent-tree.js +74 -0
  66. package/dist/runtime/attachments.js +84 -0
  67. package/dist/runtime/brokered-executor.js +395 -0
  68. package/dist/runtime/context-status.js +76 -0
  69. package/dist/runtime/create-runtime.js +111 -0
  70. package/dist/runtime/model-profile.js +361 -0
  71. package/dist/runtime/output-store.js +137 -0
  72. package/dist/runtime/provider-attempts.js +185 -0
  73. package/dist/runtime/replay-buffer.js +153 -0
  74. package/dist/runtime/repo.js +95 -0
  75. package/dist/runtime/session-facade.js +135 -0
  76. package/dist/runtime/session-summary.js +125 -0
  77. package/dist/runtime/supervisor.js +262 -0
  78. package/dist/runtime/talos-composition.js +1006 -0
  79. package/dist/runtime/types.js +5 -0
  80. package/dist/runtime/usage-snapshot.js +82 -0
  81. package/dist/security/auto-classifier.js +38 -0
  82. package/dist/security/credential-free-environment.js +54 -0
  83. package/dist/security/evaluate.js +243 -0
  84. package/dist/security/execution-backends.js +236 -0
  85. package/dist/security/execution-broker.js +102 -0
  86. package/dist/security/forge-scan.js +74 -0
  87. package/dist/security/from-approval.js +39 -0
  88. package/dist/security/mxc-execution-backend.js +281 -0
  89. package/dist/security/permission-engine.js +138 -0
  90. package/dist/security/permission-explanation.js +54 -0
  91. package/dist/security/persist.js +179 -0
  92. package/dist/security/plugin-guard.js +230 -0
  93. package/dist/security/process-tree-evidence-store.js +74 -0
  94. package/dist/security/process-tree-probe.js +554 -0
  95. package/dist/security/project-resource-inventory.js +186 -0
  96. package/dist/security/project-trust-gate.js +38 -0
  97. package/dist/security/project-trust.js +367 -0
  98. package/dist/security/rule-parser.js +201 -0
  99. package/dist/security/shell-segmentation.js +68 -0
  100. package/dist/security/trust-authority.js +324 -0
  101. package/dist/security/types.js +1 -0
  102. package/dist/security/workspace-identity.js +102 -0
  103. package/dist/services/automation-facade.js +59 -0
  104. package/dist/services/forge-facade.js +77 -0
  105. package/dist/services/hook-facade.js +240 -0
  106. package/dist/services/index.js +16 -0
  107. package/dist/services/library-facade.js +174 -0
  108. package/dist/services/mcp-facade.js +348 -0
  109. package/dist/services/memory-facade.js +126 -0
  110. package/dist/services/notes-facade.js +157 -0
  111. package/dist/services/plugin-facade.js +308 -0
  112. package/dist/services/research-facade.js +110 -0
  113. package/dist/services/task-board-facade.js +236 -0
  114. package/dist/services/workflow-catalog.js +246 -0
  115. package/dist/sessions/export-format.js +98 -0
  116. package/dist/sessions/metadata-store.js +160 -0
  117. package/dist/sessions/share.js +122 -0
  118. package/dist/sessions/transfer.js +16 -0
  119. package/dist/subcommands.js +62 -0
  120. package/dist/tui/agent-roster.js +36 -0
  121. package/dist/tui/app.js +3761 -0
  122. package/dist/tui/approval.js +36 -0
  123. package/dist/tui/boot/boot-sequence.js +76 -0
  124. package/dist/tui/boot/cinematic.js +243 -0
  125. package/dist/tui/boot/desktop-logo.js +82 -0
  126. package/dist/tui/boot.js +3 -0
  127. package/dist/tui/busy-input.js +58 -0
  128. package/dist/tui/catalog-service.js +559 -0
  129. package/dist/tui/components/assistant-stream.js +1 -0
  130. package/dist/tui/components/command-menu.js +68 -0
  131. package/dist/tui/components/composer.js +219 -0
  132. package/dist/tui/components/diff.js +35 -0
  133. package/dist/tui/components/footer.js +48 -0
  134. package/dist/tui/components/header.js +6 -0
  135. package/dist/tui/components/markdown.js +305 -0
  136. package/dist/tui/components/status-indicator.js +32 -0
  137. package/dist/tui/components/terminal-shell.js +205 -0
  138. package/dist/tui/components/thinking-row.js +19 -0
  139. package/dist/tui/components/tool-row.js +97 -0
  140. package/dist/tui/components/transcript-virtualizer.js +165 -0
  141. package/dist/tui/components/transcript.js +43 -0
  142. package/dist/tui/diff-model.js +77 -0
  143. package/dist/tui/editor-history.js +21 -0
  144. package/dist/tui/editor.js +210 -0
  145. package/dist/tui/event-adapter.js +436 -0
  146. package/dist/tui/exit-output.js +58 -0
  147. package/dist/tui/external-editor.js +53 -0
  148. package/dist/tui/file-completion.js +89 -0
  149. package/dist/tui/focus-manager.js +5 -0
  150. package/dist/tui/highlight.js +30 -0
  151. package/dist/tui/input-router.js +18 -0
  152. package/dist/tui/interrupt.js +99 -0
  153. package/dist/tui/keybindings.js +194 -0
  154. package/dist/tui/keymap-resolver.js +91 -0
  155. package/dist/tui/launch-state.js +139 -0
  156. package/dist/tui/line-diff.js +57 -0
  157. package/dist/tui/live-activity.js +45 -0
  158. package/dist/tui/metrics.js +123 -0
  159. package/dist/tui/onboarding.js +36 -0
  160. package/dist/tui/overlays/agent-tree.js +39 -0
  161. package/dist/tui/overlays/approval-dialog.js +640 -0
  162. package/dist/tui/overlays/automation-center.js +51 -0
  163. package/dist/tui/overlays/checkpoint-picker.js +47 -0
  164. package/dist/tui/overlays/context-inspector.js +36 -0
  165. package/dist/tui/overlays/effort-line.js +110 -0
  166. package/dist/tui/overlays/forge-center.js +46 -0
  167. package/dist/tui/overlays/help-dialog.js +16 -0
  168. package/dist/tui/overlays/history-picker.js +37 -0
  169. package/dist/tui/overlays/hook-center.js +70 -0
  170. package/dist/tui/overlays/library-center.js +55 -0
  171. package/dist/tui/overlays/mcp-center.js +60 -0
  172. package/dist/tui/overlays/memory-center.js +63 -0
  173. package/dist/tui/overlays/model-picker.js +72 -0
  174. package/dist/tui/overlays/notes-center.js +53 -0
  175. package/dist/tui/overlays/overlay-host.js +8 -0
  176. package/dist/tui/overlays/plugin-center.js +76 -0
  177. package/dist/tui/overlays/provider-picker.js +145 -0
  178. package/dist/tui/overlays/queue-editor.js +32 -0
  179. package/dist/tui/overlays/research-center.js +59 -0
  180. package/dist/tui/overlays/scroll-window.js +234 -0
  181. package/dist/tui/overlays/session-picker.js +115 -0
  182. package/dist/tui/overlays/tasks-center.js +83 -0
  183. package/dist/tui/overlays/theme-picker.js +21 -0
  184. package/dist/tui/overlays/transcript-search.js +58 -0
  185. package/dist/tui/overlays/trust-center.js +29 -0
  186. package/dist/tui/overlays/workflow-center.js +46 -0
  187. package/dist/tui/project-file-index.js +214 -0
  188. package/dist/tui/project-references.js +85 -0
  189. package/dist/tui/project-trust-prompt.js +287 -0
  190. package/dist/tui/prompt-history-store.js +116 -0
  191. package/dist/tui/queue-store.js +110 -0
  192. package/dist/tui/regions/budget.js +59 -0
  193. package/dist/tui/regions/views.js +96 -0
  194. package/dist/tui/render-coordinator.js +148 -0
  195. package/dist/tui/render-scheduler.js +4 -0
  196. package/dist/tui/run.js +69 -0
  197. package/dist/tui/selection-list.js +29 -0
  198. package/dist/tui/session-controller.js +778 -0
  199. package/dist/tui/session-export.js +54 -0
  200. package/dist/tui/shell-input.js +35 -0
  201. package/dist/tui/shell-layout.js +48 -0
  202. package/dist/tui/shell-model.js +98 -0
  203. package/dist/tui/slash-commands.js +80 -0
  204. package/dist/tui/state.js +151 -0
  205. package/dist/tui/status-bar.js +125 -0
  206. package/dist/tui/status-view.js +40 -0
  207. package/dist/tui/terminal-capabilities.js +9 -0
  208. package/dist/tui/terminal-session.js +11 -0
  209. package/dist/tui/text-width.js +66 -0
  210. package/dist/tui/theme-catalog.js +25 -0
  211. package/dist/tui/theme-store.js +23 -0
  212. package/dist/tui/theme.js +23 -0
  213. package/dist/tui/tool-display.js +135 -0
  214. package/dist/tui/tool-facts.js +1 -0
  215. package/dist/tui/tools/bash-renderer.js +32 -0
  216. package/dist/tui/tools/change.js +61 -0
  217. package/dist/tui/tools/edit-renderer.js +17 -0
  218. package/dist/tui/tools/generic-renderer.js +13 -0
  219. package/dist/tui/tools/list-renderer.js +14 -0
  220. package/dist/tui/tools/read-renderer.js +13 -0
  221. package/dist/tui/tools/registry.js +20 -0
  222. package/dist/tui/tools/row-format.js +187 -0
  223. package/dist/tui/tools/search-renderer.js +38 -0
  224. package/dist/tui/tools/shared.js +97 -0
  225. package/dist/tui/tools/write-renderer.js +15 -0
  226. package/dist/tui/transcript-model.js +441 -0
  227. package/dist/tui/ui-preferences.js +79 -0
  228. package/dist/tui/usage-view.js +77 -0
  229. package/dist/tui/vim-mode.js +99 -0
  230. package/dist/update/check.js +15 -0
  231. package/dist/update/npm.js +51 -0
  232. package/dist/update/run.js +129 -0
  233. package/dist/version.js +2 -0
  234. package/dist/workspace/checkpoint-store.js +210 -0
  235. package/dist/workspace/checkpoint.js +413 -0
  236. package/dist/workspace/restore.js +232 -0
  237. package/package.json +63 -5
  238. package/vendor/context-engine/package.json +11 -0
  239. package/vendor/context-engine/src/compaction-planner.mjs +57 -0
  240. package/vendor/context-engine/src/contracts.mjs +48 -0
  241. package/vendor/context-engine/src/engine.mjs +445 -0
  242. package/vendor/context-engine/src/node/context-export.mjs +164 -0
  243. package/vendor/context-engine/src/node/legacy-import.mjs +92 -0
  244. package/vendor/context-engine/src/node/migrations/001-context.sql +126 -0
  245. package/vendor/context-engine/src/node/sqlite-store.mjs +85 -0
  246. package/vendor/context-engine/src/node/sqlite-worker.mjs +559 -0
  247. package/vendor/context-engine/src/profiles.mjs +10 -0
  248. package/vendor/context-engine/src/retrieval.mjs +104 -0
  249. package/vendor/context-engine/src/summary.mjs +97 -0
  250. package/vendor/context-engine/src/usage.mjs +34 -0
  251. package/vendor/harness-ui/package.json +38 -0
  252. package/vendor/harness-ui/src/acp-agent.mjs +350 -0
  253. package/vendor/harness-ui/src/agent-service.mjs +2188 -0
  254. package/vendor/harness-ui/src/agui-events.mjs +452 -0
  255. package/vendor/harness-ui/src/ambiente-solo-server.mjs +121 -0
  256. package/vendor/harness-ui/src/artifact-store.mjs +39 -0
  257. package/vendor/harness-ui/src/assistenza.mjs +123 -0
  258. package/vendor/harness-ui/src/automation-scheduler.mjs +69 -0
  259. package/vendor/harness-ui/src/automation-store.mjs +145 -0
  260. package/vendor/harness-ui/src/browser-annota.mjs +639 -0
  261. package/vendor/harness-ui/src/browser-frame.mjs +211 -0
  262. package/vendor/harness-ui/src/browser-proxy-universale.mjs +519 -0
  263. package/vendor/harness-ui/src/browser-proxy.mjs +87 -0
  264. package/vendor/harness-ui/src/browser-sessione-viva.mjs +329 -0
  265. package/vendor/harness-ui/src/browser-stream.mjs +445 -0
  266. package/vendor/harness-ui/src/browser-vivo.mjs +694 -0
  267. package/vendor/harness-ui/src/chat-image-attachments.mjs +72 -0
  268. package/vendor/harness-ui/src/config.mjs +697 -0
  269. package/vendor/harness-ui/src/contesto-del-progetto.mjs +385 -0
  270. package/vendor/harness-ui/src/context-asset-adapter.mjs +72 -0
  271. package/vendor/harness-ui/src/context-desktop-service.mjs +253 -0
  272. package/vendor/harness-ui/src/context-embedding-runtime.mjs +252 -0
  273. package/vendor/harness-ui/src/context-inference-scheduler.mjs +81 -0
  274. package/vendor/harness-ui/src/context-native-compaction.mjs +75 -0
  275. package/vendor/harness-ui/src/context-provider-adapter.mjs +141 -0
  276. package/vendor/harness-ui/src/context-runtime.mjs +118 -0
  277. package/vendor/harness-ui/src/context-token-counters.mjs +184 -0
  278. package/vendor/harness-ui/src/context-tool-catalog.mjs +86 -0
  279. package/vendor/harness-ui/src/context-tool-output.mjs +72 -0
  280. package/vendor/harness-ui/src/costo-elenco.mjs +252 -0
  281. package/vendor/harness-ui/src/custom-task.mjs +171 -0
  282. package/vendor/harness-ui/src/doctor.mjs +142 -0
  283. package/vendor/harness-ui/src/document-filename.mjs +97 -0
  284. package/vendor/harness-ui/src/document-generator.mjs +493 -0
  285. package/vendor/harness-ui/src/document-report.mjs +331 -0
  286. package/vendor/harness-ui/src/duckduckgo-search.mjs +155 -0
  287. package/vendor/harness-ui/src/elenco-profondo.mjs +337 -0
  288. package/vendor/harness-ui/src/favicon-proxy.mjs +113 -0
  289. package/vendor/harness-ui/src/forge-contract.mjs +221 -0
  290. package/vendor/harness-ui/src/frequent-dirs.mjs +134 -0
  291. package/vendor/harness-ui/src/generated-image-store.mjs +147 -0
  292. package/vendor/harness-ui/src/generation-idle.mjs +332 -0
  293. package/vendor/harness-ui/src/gguf-header.mjs +207 -0
  294. package/vendor/harness-ui/src/git-service.mjs +626 -0
  295. package/vendor/harness-ui/src/gitignore-elenco.mjs +604 -0
  296. package/vendor/harness-ui/src/harness-receipt-keypair.mjs +207 -0
  297. package/vendor/harness-ui/src/hf-direct-transfer.mjs +170 -0
  298. package/vendor/harness-ui/src/hf-hub-client.mjs +106 -0
  299. package/vendor/harness-ui/src/hf-image-proxy.mjs +105 -0
  300. package/vendor/harness-ui/src/hf-model-transfer.mjs +245 -0
  301. package/vendor/harness-ui/src/hook-registry.mjs +186 -0
  302. package/vendor/harness-ui/src/http-app.mjs +6259 -0
  303. package/vendor/harness-ui/src/http-lifecycle.mjs +132 -0
  304. package/vendor/harness-ui/src/id-archivio.mjs +27 -0
  305. package/vendor/harness-ui/src/image-generator.mjs +143 -0
  306. package/vendor/harness-ui/src/istruzioni-di-progetto.mjs +234 -0
  307. package/vendor/harness-ui/src/kernel/dist/kernelPerIlBanco.js +518 -0
  308. package/vendor/harness-ui/src/kernel/talosHarness.mjs +10437 -0
  309. package/vendor/harness-ui/src/library-policy-store.mjs +175 -0
  310. package/vendor/harness-ui/src/library-store.mjs +652 -0
  311. package/vendor/harness-ui/src/llama-server-supervisor.mjs +629 -0
  312. package/vendor/harness-ui/src/local-model-store.mjs +339 -0
  313. package/vendor/harness-ui/src/local-runtime-contract.mjs +66 -0
  314. package/vendor/harness-ui/src/local-runtime-events.mjs +44 -0
  315. package/vendor/harness-ui/src/local-runtime-llama-server.mjs +244 -0
  316. package/vendor/harness-ui/src/local-runtime-probe.mjs +401 -0
  317. package/vendor/harness-ui/src/machine-capacity.mjs +66 -0
  318. package/vendor/harness-ui/src/mappa-cartelle.mjs +491 -0
  319. package/vendor/harness-ui/src/mcp-client.mjs +98 -0
  320. package/vendor/harness-ui/src/mcp-registry.mjs +157 -0
  321. package/vendor/harness-ui/src/mcp-session.mjs +177 -0
  322. package/vendor/harness-ui/src/memory-store.mjs +227 -0
  323. package/vendor/harness-ui/src/model-catalog-models-dev.mjs +276 -0
  324. package/vendor/harness-ui/src/model-catalog.mjs +129 -0
  325. package/vendor/harness-ui/src/model-destination.mjs +189 -0
  326. package/vendor/harness-ui/src/modifica-ancorata.mjs +177 -0
  327. package/vendor/harness-ui/src/native-provider-adapter.mjs +205 -0
  328. package/vendor/harness-ui/src/notes-store.mjs +250 -0
  329. package/vendor/harness-ui/src/openai-compatible-runtime.mjs +428 -0
  330. package/vendor/harness-ui/src/openrouter-oauth.mjs +339 -0
  331. package/vendor/harness-ui/src/path-policy.mjs +442 -0
  332. package/vendor/harness-ui/src/plugin-registry.mjs +780 -0
  333. package/vendor/harness-ui/src/plugin-session.mjs +180 -0
  334. package/vendor/harness-ui/src/process-policy.mjs +345 -0
  335. package/vendor/harness-ui/src/prompt-enhancer-provider.mjs +94 -0
  336. package/vendor/harness-ui/src/provider-auth-cloud.mjs +95 -0
  337. package/vendor/harness-ui/src/provider-credential-store.mjs +541 -0
  338. package/vendor/harness-ui/src/provider-probe.mjs +582 -0
  339. package/vendor/harness-ui/src/provider-registry.mjs +1633 -0
  340. package/vendor/harness-ui/src/pty-terminal.mjs +312 -0
  341. package/vendor/harness-ui/src/public-problem.mjs +109 -0
  342. package/vendor/harness-ui/src/research/card.mjs +235 -0
  343. package/vendor/harness-ui/src/research/citations.mjs +142 -0
  344. package/vendor/harness-ui/src/research/collector.mjs +275 -0
  345. package/vendor/harness-ui/src/research/deposito-a-pezzi.mjs +139 -0
  346. package/vendor/harness-ui/src/research/dossier.mjs +114 -0
  347. package/vendor/harness-ui/src/research/esportazioni.mjs +560 -0
  348. package/vendor/harness-ui/src/research/fetch-cache.mjs +465 -0
  349. package/vendor/harness-ui/src/research/fidelity.mjs +122 -0
  350. package/vendor/harness-ui/src/research/independence.mjs +159 -0
  351. package/vendor/harness-ui/src/research/ledger.mjs +166 -0
  352. package/vendor/harness-ui/src/research/markdown-server.mjs +565 -0
  353. package/vendor/harness-ui/src/research/narration.mjs +181 -0
  354. package/vendor/harness-ui/src/research/open-cards.mjs +131 -0
  355. package/vendor/harness-ui/src/research/opposing.mjs +305 -0
  356. package/vendor/harness-ui/src/research/outline.mjs +111 -0
  357. package/vendor/harness-ui/src/research/page-budget.mjs +209 -0
  358. package/vendor/harness-ui/src/research/pdf.mjs +291 -0
  359. package/vendor/harness-ui/src/research/plan.mjs +301 -0
  360. package/vendor/harness-ui/src/research/raccolta-viva.mjs +452 -0
  361. package/vendor/harness-ui/src/research/recheck-document.mjs +69 -0
  362. package/vendor/harness-ui/src/research/recheck-history.mjs +192 -0
  363. package/vendor/harness-ui/src/research/recheck.mjs +194 -0
  364. package/vendor/harness-ui/src/research/report.mjs +203 -0
  365. package/vendor/harness-ui/src/research/run.mjs +527 -0
  366. package/vendor/harness-ui/src/research/synthesis.mjs +318 -0
  367. package/vendor/harness-ui/src/research/verification.mjs +572 -0
  368. package/vendor/harness-ui/src/research-orchestrator.mjs +2679 -0
  369. package/vendor/harness-ui/src/research-store.mjs +1133 -0
  370. package/vendor/harness-ui/src/runtime-build-manifest.mjs +26 -0
  371. package/vendor/harness-ui/src/runtime-contract.mjs +59 -0
  372. package/vendor/harness-ui/src/runtime-owner-adapter.mjs +1348 -0
  373. package/vendor/harness-ui/src/runtime-owner-contract.mjs +32 -0
  374. package/vendor/harness-ui/src/scheda-di-lavoro.mjs +249 -0
  375. package/vendor/harness-ui/src/search-source-store.mjs +172 -0
  376. package/vendor/harness-ui/src/session-registry.mjs +6095 -0
  377. package/vendor/harness-ui/src/session-store.mjs +220 -0
  378. package/vendor/harness-ui/src/sessione-pronta.mjs +73 -0
  379. package/vendor/harness-ui/src/setup-stato.mjs +31 -0
  380. package/vendor/harness-ui/src/sezioni-istruzioni.mjs +204 -0
  381. package/vendor/harness-ui/src/skill-registry.mjs +120 -0
  382. package/vendor/harness-ui/src/sse-replay-coalescente.mjs +0 -0
  383. package/vendor/harness-ui/src/static-files.mjs +96 -0
  384. package/vendor/harness-ui/src/stream-partition.mjs +123 -0
  385. package/vendor/harness-ui/src/subagent-orchestrator.mjs +453 -0
  386. package/vendor/harness-ui/src/task-catalog.mjs +65 -0
  387. package/vendor/harness-ui/src/tasks-store.mjs +220 -0
  388. package/vendor/harness-ui/src/terminal-registry.mjs +312 -0
  389. package/vendor/harness-ui/src/terminal-ws.mjs +170 -0
  390. package/vendor/harness-ui/src/tool-forge-store.mjs +299 -0
  391. package/vendor/harness-ui/src/tool-schema-normalize.mjs +100 -0
  392. package/vendor/harness-ui/src/usage-cache.mjs +315 -0
  393. package/vendor/harness-ui/src/workspace-browser.mjs +213 -0
  394. package/vendor/harness-ui/src/workspace-context.mjs +124 -0
  395. package/vendor/harness-ui/src/workspace-disk.mjs +62 -0
  396. package/vendor/harness-ui/src/workspace-files.mjs +589 -0
  397. package/vendor/harness-ui/src/workspace-info.mjs +189 -0
  398. package/vendor/harness-ui/src/workspace-launch-store.mjs +150 -0
  399. package/vendor/harness-ui/src/workspace-tree.mjs +67 -0
  400. package/vendor/harness-ui/src/workspace-watcher.mjs +161 -0
  401. package/vendor/manifest.json +170 -0
@@ -0,0 +1,639 @@
1
+ /**
2
+ * browser-annota.mjs — M4 (07/09/2026): la stessa annotazione che TALOS fa già dentro la pagina
3
+ * proxata, portata DENTRO il browser pilotato via CDP (il ripiego B: Chromium di sistema, profilo
4
+ * separato, schermo trasmesso). Lì non possiamo iniettare uno script con un tag `<script>` — il
5
+ * documento non passa più dalle nostre mani — quindi l'overlay entra con i comandi del protocollo.
6
+ *
7
+ * ⛔ CONTENUTO NON AFFIDABILE. Tutto ciò che torna da qui (selettore, HTML, testo, stili, indizi sul
8
+ * sorgente, righe di console) è scritto dalla pagina di terzi. NON diventa MAI un'istruzione per il
9
+ * modello: è un DATO dentro il pacchetto dei commenti (`annotazioni.js` → `impacchetta()`), sotto le
10
+ * etichette fisse di quel pacchetto, e le istruzioni restano quelle nostre. Brave ha dimostrato la
11
+ * prompt injection indiretta su Comet: una pagina che scrive «ignora le istruzioni precedenti» qui
12
+ * arriva come testo di un elemento, non come voce del turno.
13
+ *
14
+ * ── Le fonti lette il 07/09/2026, e cosa hanno cambiato ────────────────────────────────────────
15
+ * · CDP, dominio Page (chromedevtools.github.io/devtools-protocol/tot/Page/):
16
+ * `Page.addScriptToEvaluateOnNewDocument` «evaluates given script in every frame upon creation
17
+ * (before loading frame's scripts)» — è QUESTO che fa sopravvivere l'overlay alle navigazioni
18
+ * successive, e solo quello: sulla pagina GIÀ APERTA non gira, perché il documento è già creato.
19
+ * Il parametro `runImmediately` («runs the script immediately on existing execution contexts»)
20
+ * coprirebbe anche quel caso in una chiamata sola, ma è dichiarato **Experimental** e manca nei
21
+ * Chromium più vecchi ⇒ non ci si appoggia: per il documento aperto facciamo il giro esplicito
22
+ * `Page.createIsolatedWorld` + `Runtime.evaluate`, che sta nella 1-3 stabile.
23
+ * Anche `worldName` è Experimental, ma è l'unica via per nominare il mondo, e se un giorno
24
+ * sparisse il peggio è che l'overlay finisca nel mondo principale: funziona, e si vede.
25
+ * · CDP, dominio Runtime (…/tot/Runtime/): `Runtime.evaluate` accetta `contextId` — «If the
26
+ * parameter is omitted the evaluation will be performed in the context of the inspected page»
27
+ * ⇒ omesso = MONDO PRINCIPALE. Ci serve nei due versi: con `contextId` per l'overlay isolato,
28
+ * senza per leggere le proprietà che solo il mondo principale vede (vedi sotto).
29
+ * · MDN «Content scripts»: un mondo isolato «has access to the DOM of the page … but not to any
30
+ * JavaScript variables or functions created by the page».
31
+ *
32
+ * ── ⛔ COSA NON SI VEDE DA UN MONDO ISOLATO (il limite, scritto perché è quello che ci costa) ───
33
+ * Il DOM è condiviso, il mucchio JavaScript no. Quindi da qui NON si vedono:
34
+ * 1. le variabili globali della pagina — `window.__NEXT_DATA__`, `window.__NUXT__`,
35
+ * `window.__vite_plugin_react_preamble_installed__`: il riconoscimento del framework che
36
+ * l'overlay in pagina fa guardando `window` qui torna vuoto, e resta solo la parte che si
37
+ * legge dal DOM (`<script src="/@vite/client">`, le classi `svelte-*`);
38
+ * 2. ⛔ le proprietà appese ai nodi dal codice della pagina — `el.__reactFiber$…`,
39
+ * `el.__vueParentComponent`: lo stesso nodo esiste in tutti e due i mondi, ma gli espandi che
40
+ * ciascun mondo gli appende sono invisibili all'altro. Sono ESATTAMENTE gli indizi sul
41
+ * sorgente più preziosi (file e nome del componente) ⇒ per averli serve una seconda lettura
42
+ * nel mondo principale, che qui facciamo per selettore (`arricchisciDalMondoPrincipale`),
43
+ * di sola LETTURA e solo su richiesta.
44
+ * Al contrario, il DOM condiviso vuol dire anche che l'isolamento protegge il nostro JAVASCRIPT,
45
+ * non i nostri NODI: l'evidenza e gli spilli che appendiamo stanno nel DOM della pagina e un suo
46
+ * script potrebbe vederli. Per questo portano `data-talos-annota` e vengono saltati nel puntamento.
47
+ *
48
+ * ── Gli errori: perché UN evento solo non basta ─────────────────────────────────────────────────
49
+ * `Runtime.consoleAPICalled` scatta «when JS code calls console API»: prende `console.error` della
50
+ * pagina e nient'altro. `Log.entryAdded` è il registro del BROWSER — richieste di rete fallite
51
+ * (il 404 che appare in console senza che nessuno abbia chiamato `console.*`), avvisi di sicurezza,
52
+ * deprecazioni, interventi. `Runtime.exceptionThrown` è un terzo insieme ancora: le eccezioni non
53
+ * catturate, che non passano da nessuno dei due. Chi ne ascolta uno solo consegna all'agente una
54
+ * console mutilata proprio dove serviva — un 404 su un asset non è un `console.error`. Li prendiamo
55
+ * tutti e tre e li marchiamo per origine (`console` · `browser` · `eccezione` · `promessa`).
56
+ *
57
+ * ── Il selettore: uguale a quello in pagina, con UNA differenza dichiarata ──────────────────────
58
+ * Stessa forma di `frontend/src/assets/talos/browser-annota.js`: stessa fuga CSS, stessa prova di
59
+ * unicità, stesso filtro sulle classi generate, stesso `nth-of-type`, stessa profondità massima 12
60
+ * e — la cosa che NON si può cambiare — lo stesso separatore ` > `, perché `annotazioni.js`
61
+ * (`percorsoContenitore`, `raggruppa`) taglia il selettore su quello per raggruppare gli spilli per
62
+ * zona: un separatore diverso spegnerebbe il raggruppamento senza un errore.
63
+ * ⛔ La differenza voluta: qui `data-testid` viene PRIMA dell'`id`, mentre l'overlay in pagina prova
64
+ * l'`id` per primo. Motivo: un `data-testid` lo scrive una persona e sopravvive a un refactor, un
65
+ * `id` oggi è spesso generato — React `useId` produce identificatori nella forma `:r0:`, che come
66
+ * selettore CSS non è nemmeno valido senza `CSS.escape` (react/react#32001, «Use valid CSS selectors
67
+ * in useId format»; Stefan Judis, «How to escape CSS selectors in JavaScript», letti il 07/09/2026).
68
+ * Debito registrato: l'overlay in pagina andrebbe allineato a questo ordine, ma quel file non è di
69
+ * questo giro.
70
+ *
71
+ * ── Misurato dal vivo il 07/09/2026 (Edge di sistema headless, profilo separato, porta 4321) ────
72
+ * Non solo compilato: pilotato davvero. Il pulsante con `id="salva"` E `data-testid="salva-tutto"`
73
+ * ha dato `button[data-testid="salva-tutto"]` — la preferenza vale anche fuori dai test. Un `<p>`
74
+ * da 1.853 caratteri è tornato tagliato a 800 con la misura dichiarata in coda. Un elemento dentro
75
+ * uno shadow root aperto ha dato il selettore dell'OSPITE (`div[data-testid="scheda-ombra"]`, che
76
+ * `document.querySelector` ritrova) più `dentroShadow:"span"` e il testo di dentro. Un punto fuori
77
+ * dalla pagina ha dato `trovato:false` con tutti e 13 i campi. E le due cose che qui contano di più:
78
+ * · il limite del mondo isolato, misurato invece che raccontato — scritta `window.__prova = 42`
79
+ * nel mondo principale, dal mondo isolato resta `undefined`;
80
+ * · dopo un `Page.navigate` l'overlay è tornato DA SOLO (`h1[data-testid="titolo"]`), che è
81
+ * esattamente il lavoro di `Page.addScriptToEvaluateOnNewDocument`.
82
+ * Sul registro del browser: una richiesta fallita ha prodotto `Log.entryAdded` «Failed to load
83
+ * resource: net::ERR_UNSAFE_PORT» SENZA nessuna riga di console — la prova che un evento solo non
84
+ * basta non è un ragionamento, è quella riga.
85
+ *
86
+ * ⛔ NOTA PER CHI TOCCA QUESTO FILE: le funzioni pure qui sotto viaggiano nel browser serializzate
87
+ * con `Function.prototype.toString()` (così la stessa identica logica si prova in Node e gira nella
88
+ * pagina, invece di esistere in due copie che divergono). Perciò dentro di esse NON si può nominare
89
+ * nessuna variabile del modulo: le costanti vengono riscritte come letterali in testa all'IIFE da
90
+ * `sorgenteOverlay()`. E questo modulo non passa da nessun bundler: se un giorno ci passasse, la
91
+ * minificazione romperebbe la serializzazione.
92
+ */
93
+
94
+ /** Il nome del mondo isolato: compare come `ExecutionContextDescription::name`, utile a chi guarda. */
95
+ export const MONDO_OVERLAY = 'talos-annota';
96
+ /** L'attributo che marca i nostri nodi nel DOM condiviso, così il puntamento li salta. */
97
+ export const TAG_NOSTRO = 'data-talos-annota';
98
+ /** Misure dichiarate — le stesse dell'overlay in pagina, così i due pacchetti si somigliano. */
99
+ export const MASSIMO_HTML = 800;
100
+ export const MASSIMO_TESTO = 200;
101
+ export const MASSIMI_ANTENATI = 8;
102
+ export const PROFONDITA_MASSIMA = 12;
103
+ export const MASSIMO_ERRORI = 20;
104
+ export const MASSIMO_TESTO_ERRORE = 300;
105
+
106
+ /** Prima i testid (li scrive una persona), poi l'id, poi i nomi accessibili. Vedi la testa del file. */
107
+ export const ATTRIBUTI_STABILI = ['data-testid', 'data-test-id', 'data-test', 'data-cy', 'data-qa'];
108
+ export const ATTRIBUTI_DEBOLI = ['name', 'aria-label'];
109
+ /** Indizi sul sorgente che stanno negli ATTRIBUTI: questi sì che un mondo isolato li vede. */
110
+ export const ATTRIBUTI_SORGENTE = ['data-v-inspector', 'data-source', 'data-loc', 'data-inspector-file'];
111
+ export const STILI = ['display', 'position', 'width', 'height', 'margin', 'padding', 'color', 'background-color', 'font-family', 'font-size', 'font-weight', 'line-height', 'border', 'border-radius', 'opacity', 'z-index'];
112
+
113
+ /** I campi che il pacchetto ha SEMPRE: una pagina vuota non deve produrre un pacchetto sbilenco. */
114
+ export const CAMPI_PACCHETTO = ['trovato', 'selettore', 'tag', 'testo', 'html', 'htmlCaratteri', 'htmlTroncato', 'stili', 'rect', 'antenati', 'indiziSorgente', 'dentroShadow'];
115
+
116
+ /** Il pacchetto vuoto — la forma, quando sotto quel punto non c'è niente. */
117
+ export function pacchettoVuoto() {
118
+ return { trovato: false, selettore: '', tag: '', testo: '', html: '', htmlCaratteri: 0, htmlTroncato: false, stili: {}, rect: null, antenati: [], indiziSorgente: {}, dentroShadow: '' };
119
+ }
120
+
121
+ /* ══ Funzioni pure: girano in Node (i test le provano) e nel browser (serializzate) ══════════════ */
122
+
123
+ /** La fuga CSS: `CSS.escape` dove c'è, altrimenti la stessa rete di sicurezza dell'overlay in pagina. */
124
+ export function escapaCss(s) {
125
+ return (typeof CSS !== 'undefined' && CSS && CSS.escape) ? CSS.escape(String(s)) : String(s).replace(/([^a-zA-Z0-9_-])/g, '\\$1');
126
+ }
127
+
128
+ /** Una classe è stabile se non sembra generata: niente cifre lunghe, niente esadecimali, niente prefissi dei CSS-in-JS. */
129
+ export function classeStabile(c) {
130
+ return /^[a-zA-Z][a-zA-Z0-9_-]{2,40}$/.test(c) && !/\d{3,}|[a-f0-9]{6,}|^(css|sc|jsx|svelte|emotion)-/.test(c);
131
+ }
132
+
133
+ /**
134
+ * Un segmento del selettore. `unico(sel, el)` dice se quel selettore trova SOLO quell'elemento:
135
+ * nel browser interroga il documento, nei test è una funzione finta — così la scelta si prova.
136
+ * `assoluto:true` vuol dire «da qui non serve risalire»: il segmento identifica già l'elemento.
137
+ * ⛔ `forti` e `deboli` arrivano come argomenti e non come costanti del modulo perché questa
138
+ * funzione viaggia nel browser serializzata (vedi la nota in testa al file).
139
+ */
140
+ export function pezzoSelettore(el, unico, forti, deboli) {
141
+ var tag = String(el.tagName || '').toLowerCase();
142
+ var i, v, candidato;
143
+ for (i = 0; i < forti.length; i += 1) {
144
+ v = el.getAttribute ? el.getAttribute(forti[i]) : null;
145
+ if (v) { candidato = tag + '[' + forti[i] + '="' + String(v).replace(/"/g, '\\"') + '"]'; if (unico(candidato, el)) return { sel: candidato, assoluto: true }; }
146
+ }
147
+ if (el.id && /^[a-zA-Z][\w-]*$/.test(el.id)) { candidato = '#' + escapaCss(el.id); if (unico(candidato, el)) return { sel: candidato, assoluto: true }; }
148
+ for (i = 0; i < deboli.length; i += 1) {
149
+ v = el.getAttribute ? el.getAttribute(deboli[i]) : null;
150
+ if (v) { candidato = tag + '[' + deboli[i] + '="' + String(v).replace(/"/g, '\\"') + '"]'; if (unico(candidato, el)) return { sel: candidato, assoluto: true }; }
151
+ }
152
+ var classi = [];
153
+ var lista = el.classList ? Array.prototype.slice.call(el.classList) : [];
154
+ for (i = 0; i < lista.length && classi.length < 2; i += 1) if (classeStabile(lista[i])) classi.push(lista[i]);
155
+ var base = tag;
156
+ for (i = 0; i < classi.length; i += 1) base += '.' + escapaCss(classi[i]);
157
+ var padre = el.parentElement;
158
+ if (padre && padre.children) {
159
+ var fratelli = Array.prototype.filter.call(padre.children, function (f) { return f.tagName === el.tagName; });
160
+ if (fratelli.length > 1) base += ':nth-of-type(' + (fratelli.indexOf(el) + 1) + ')';
161
+ }
162
+ return { sel: base, assoluto: false };
163
+ }
164
+
165
+ /**
166
+ * Il selettore stabile: si risale finché il percorso non è unico, al massimo 12 gradini.
167
+ * ⛔ Il separatore è ` > ` e non si cambia: `annotazioni.js` ci taglia sopra per raggruppare.
168
+ * ⛔ Un elemento senza NIENTE (né attributi, né id, né classi, né fratelli) produce il suo tag e la
169
+ * sua catena, mai un attributo che non ha: se il percorso non è unico si consegna com'è, e chi legge
170
+ * vede un selettore generico invece di uno inventato che sembra preciso e punta altrove.
171
+ */
172
+ export function selettoreStabile(el, unico, forti, deboli) {
173
+ var parti = []; var corrente = el; var profondita = 0;
174
+ while (corrente && corrente.nodeType === 1 && corrente.tagName !== 'HTML' && profondita < 12) {
175
+ var p = pezzoSelettore(corrente, unico, forti, deboli);
176
+ parti.unshift(p.sel);
177
+ var candidato = parti.join(' > ');
178
+ if (p.assoluto || unico(candidato, el)) return candidato;
179
+ corrente = corrente.parentElement; profondita += 1;
180
+ }
181
+ return parti.join(' > ');
182
+ }
183
+
184
+ /** Il taglio dell'HTML con la MISURA DICHIARATA: chi legge sa che è tagliato e quanto era intero. */
185
+ export function tagliaHtml(html, massimo) {
186
+ var s = String(html || '');
187
+ if (s.length <= massimo) return { testo: s, troncato: false, caratteri: s.length };
188
+ return { testo: s.slice(0, massimo) + '… (troncato: ' + s.length + ' caratteri in tutto, mostrati i primi ' + massimo + ')', troncato: true, caratteri: s.length };
189
+ }
190
+
191
+ /** Il testo di un elemento, su una riga sola e corto. */
192
+ export function ripulisciTesto(testo, massimo) {
193
+ return String(testo || '').replace(/\s+/g, ' ').trim().slice(0, massimo);
194
+ }
195
+
196
+ /* ══ La sorgente dell'overlay ═══════════════════════════════════════════════════════════════════ */
197
+
198
+ /* La parte che esiste solo nel browser: puntamento, stili calcolati, evidenza, spilli. Sta come
199
+ * stringa perché parla con `document`, che in Node non c'è; le decisioni vere (selettore, tagli)
200
+ * stanno nelle funzioni sopra, provate dai test. */
201
+ const COLLA = `
202
+ function nostro(el) { return !!(el && el.getAttribute && el.getAttribute(TAG_NOSTRO)); }
203
+ function sottoIlPunto(x, y) {
204
+ var pila = document.elementsFromPoint ? document.elementsFromPoint(x, y) : [document.elementFromPoint(x, y)];
205
+ for (var i = 0; i < pila.length; i += 1) { var e = pila[i]; if (e && e.nodeType === 1 && !nostro(e) && e !== document.documentElement) return e; }
206
+ /* 07/9 - misurato su example.org: fuori dal contenuto elementsFromPoint torna SOLO ["HTML"], che
207
+ il filtro qui sopra scarta di proposito (annotare l'intera pagina non serve a nessuno). Il
208
+ risultato era un pacchetto vuoto identico a un guasto: chi guardava - io per primo - credeva
209
+ che l'annotazione fosse rotta, e invece aveva cliccato sullo sfondo. Il corpo della pagina e'
210
+ un elemento vero: si torna quello.
211
+ ATTENZIONE: questo commento vive DENTRO una stringa template, quindi niente apici inversi. */
212
+ if (pila.length && document.body) return document.body;
213
+ return null;
214
+ }
215
+ /* Shadow DOM APERTO: si scende per prendere i FATTI veri (html, testo, stili), ma il SELETTORE
216
+ resta quello dell'ospite — e' l'unico che document.querySelector puo' ritrovare. Il percorso
217
+ dentro l'ombra viaggia a parte, in dentroShadow: niente selettore inventato. */
218
+ function bersaglio(x, y) {
219
+ var el = sottoIlPunto(x, y); var ospite = null; var dentro = [];
220
+ while (el && el.shadowRoot && el.shadowRoot.elementFromPoint && dentro.length < 6) {
221
+ var giu = el.shadowRoot.elementFromPoint(x, y);
222
+ if (!giu || giu === el || giu.nodeType !== 1) break;
223
+ if (!ospite) ospite = el;
224
+ dentro.push(giu.tagName.toLowerCase());
225
+ el = giu;
226
+ }
227
+ return { el: el, ospite: ospite, dentro: dentro };
228
+ }
229
+ function unico(sel, el) { try { var t = document.querySelectorAll(sel); return t.length === 1 && t[0] === el; } catch (e) { return false; } }
230
+ function stiliCalcolati(el) {
231
+ var out = {};
232
+ try {
233
+ var cs = getComputedStyle(el);
234
+ for (var i = 0; i < STILI.length; i += 1) { var v = cs.getPropertyValue(STILI[i]); if (v && v !== 'none' && v !== 'normal' && v !== 'auto' && v !== '0px' && v !== 'static') out[STILI[i]] = v; }
235
+ } catch (e) { /* un elemento staccato non ha stili: non e' un errore */ }
236
+ return out;
237
+ }
238
+ function antenati(el) { var a = []; var e = el.parentElement; while (e && e.tagName !== 'HTML' && a.length < MASSIMI_ANTENATI) { a.unshift(e.tagName.toLowerCase() + (e.id ? '#' + e.id : '')); e = e.parentElement; } return a; }
239
+ /* Da un mondo isolato gli indizi arrivano SOLO dagli attributi e dal DOM: le proprieta' appese ai
240
+ nodi dal codice della pagina (__reactFiber$..., __vueParentComponent) e le globali (window.__NEXT_DATA__)
241
+ qui non esistono. Le prende il mondo principale, da server, con una seconda lettura. */
242
+ function indiziDagliAttributi(el) {
243
+ var out = {}; var e = el;
244
+ for (var g = 0; g < 6 && e; g += 1) {
245
+ for (var i = 0; i < ATTRIBUTI_SORGENTE.length; i += 1) {
246
+ var v = e.getAttribute ? e.getAttribute(ATTRIBUTI_SORGENTE[i]) : null;
247
+ if (v && !out.file) out.file = String(v).slice(0, 300);
248
+ }
249
+ e = e.parentElement;
250
+ }
251
+ var framework = null;
252
+ if (document.querySelector('script[src*="/@vite/client"]')) framework = 'Vite';
253
+ if (!framework && document.querySelector('[class*="svelte-"]')) framework = 'Svelte';
254
+ if (!framework && document.querySelector('script#__NEXT_DATA__')) framework = 'Next.js';
255
+ if (!framework && document.querySelector('[data-v-app], [data-v-inspector]')) framework = 'Vue';
256
+ if (framework) out.framework = framework;
257
+ return out;
258
+ }
259
+ function descrivi(x, y) {
260
+ var b = bersaglio(x, y);
261
+ if (!b.el) return VUOTO();
262
+ var perIlSelettore = b.ospite || b.el;
263
+ var h = tagliaHtml(b.el.outerHTML || '', MASSIMO_HTML);
264
+ var r = null;
265
+ try { var q = b.el.getBoundingClientRect(); r = { x: Math.round(q.left + window.scrollX), y: Math.round(q.top + window.scrollY), larghezza: Math.round(q.width), altezza: Math.round(q.height) }; } catch (e) { r = null; }
266
+ var p = VUOTO();
267
+ p.trovato = true;
268
+ p.selettore = selettoreStabile(perIlSelettore, unico, ATTRIBUTI_STABILI, ATTRIBUTI_DEBOLI);
269
+ p.tag = String(b.el.tagName || '').toLowerCase();
270
+ p.testo = ripulisciTesto(b.el.innerText || b.el.textContent || '', MASSIMO_TESTO);
271
+ p.html = h.testo; p.htmlCaratteri = h.caratteri; p.htmlTroncato = h.troncato;
272
+ p.stili = stiliCalcolati(b.el);
273
+ p.rect = r;
274
+ p.antenati = antenati(perIlSelettore);
275
+ p.indiziSorgente = indiziDagliAttributi(b.el);
276
+ p.dentroShadow = b.dentro.join(' > ');
277
+ return p;
278
+ }
279
+ /* L'evidenza e gli spilli: sono nel DOM CONDIVISO, quindi marcati e senza eventi propri. */
280
+ var evidenza = null; var spilli = []; var attivo = false; var ultimo = null;
281
+ function creaEvidenza() {
282
+ evidenza = document.createElement('div');
283
+ evidenza.setAttribute(TAG_NOSTRO, 'evidenza');
284
+ evidenza.style.cssText = 'position:absolute;pointer-events:none;z-index:2147483646;border:2px solid #c08b3c;background:rgba(192,139,60,.12);border-radius:4px;box-shadow:0 0 0 1px rgba(0,0,0,.35);display:none';
285
+ document.documentElement.appendChild(evidenza);
286
+ }
287
+ function evidenzia(x, y) {
288
+ var b = bersaglio(x, y); if (!b.el) return false;
289
+ if (!evidenza || !evidenza.isConnected) creaEvidenza();
290
+ var q = b.el.getBoundingClientRect();
291
+ evidenza.style.display = 'block';
292
+ evidenza.style.left = (q.left + window.scrollX) + 'px'; evidenza.style.top = (q.top + window.scrollY) + 'px';
293
+ evidenza.style.width = q.width + 'px'; evidenza.style.height = q.height + 'px';
294
+ return true;
295
+ }
296
+ function segna(numero, x, y) {
297
+ var b = bersaglio(x, y); if (!b.el) return false;
298
+ var q = b.el.getBoundingClientRect();
299
+ var s = document.createElement('div');
300
+ s.setAttribute(TAG_NOSTRO, 'spillo');
301
+ s.textContent = String(numero);
302
+ s.style.cssText = 'position:absolute;z-index:2147483647;left:' + (q.left + window.scrollX - 10) + 'px;top:' + (q.top + window.scrollY - 10) + 'px;min-width:20px;height:20px;padding:0 5px;border-radius:10px;background:#c08b3c;color:#fff;font:600 12px/20px system-ui,sans-serif;text-align:center;box-shadow:0 2px 6px rgba(0,0,0,.4);pointer-events:none';
303
+ document.documentElement.appendChild(s);
304
+ spilli.push(s);
305
+ return true;
306
+ }
307
+ function suMossa(e) { if (attivo) evidenzia(e.clientX, e.clientY); }
308
+ /* Il clic vero della persona (arriva come Input.dispatchMouseEvent dal server) si ferma qui:
309
+ mentre si annota, la pagina non deve navigare. Le coordinate restano a disposizione. */
310
+ function suClic(e) { if (!attivo) return; e.preventDefault(); e.stopPropagation(); ultimo = { x: e.clientX, y: e.clientY, quando: Date.now() }; }
311
+ function accendi() { attivo = true; if (!evidenza || !evidenza.isConnected) creaEvidenza(); try { document.documentElement.style.cursor = 'crosshair'; } catch (e) {} return true; }
312
+ function spegni() { attivo = false; try { document.documentElement.style.cursor = ''; } catch (e) {} if (evidenza) evidenza.style.display = 'none'; return true; }
313
+ function svuotaSpilli() { for (var i = 0; i < spilli.length; i += 1) { try { spilli[i].remove(); } catch (e) {} } spilli = []; return true; }
314
+ function smonta() {
315
+ spegni(); svuotaSpilli();
316
+ try { if (evidenza) evidenza.remove(); } catch (e) {}
317
+ document.removeEventListener('mousemove', suMossa, true);
318
+ document.removeEventListener('click', suClic, true);
319
+ try { delete window.__talosAnnotaCdp; } catch (e) { window.__talosAnnotaCdp = undefined; }
320
+ return true;
321
+ }
322
+ document.addEventListener('mousemove', suMossa, true);
323
+ document.addEventListener('click', suClic, true);
324
+ window.__talosAnnotaCdp = { versione: 1, mondo: MONDO, descrivi: descrivi, evidenzia: evidenzia, segna: segna, accendi: accendi, spegni: spegni, svuotaSpilli: svuotaSpilli, smonta: smonta, ultimoClic: function () { return ultimo; }, quantiSpilli: function () { return spilli.length; } };
325
+ `;
326
+
327
+ /**
328
+ * Lo script dell'overlay, senza dipendenze esterne: una funzione che si autoinvoca, sicura da
329
+ * rieseguire (se c'è già, esce). Le costanti sono letterali, le funzioni pure sono le stesse che i
330
+ * test provano in Node — serializzate, non riscritte a mano.
331
+ * @returns {string}
332
+ */
333
+ export function sorgenteOverlay() {
334
+ const costanti = [
335
+ `var MONDO=${JSON.stringify(MONDO_OVERLAY)};`,
336
+ `var TAG_NOSTRO=${JSON.stringify(TAG_NOSTRO)};`,
337
+ /* una `var` per riga, non tre sulla stessa: il controllo delle costanti orfane (nel test) legge
338
+ le dichiarazioni una per una, e con la forma a virgole le ultime due gli sfuggivano */
339
+ `var MASSIMO_HTML=${MASSIMO_HTML};`,
340
+ `var MASSIMO_TESTO=${MASSIMO_TESTO};`,
341
+ `var MASSIMI_ANTENATI=${MASSIMI_ANTENATI};`,
342
+ `var ATTRIBUTI_STABILI=${JSON.stringify(ATTRIBUTI_STABILI)};`,
343
+ `var ATTRIBUTI_DEBOLI=${JSON.stringify(ATTRIBUTI_DEBOLI)};`,
344
+ `var ATTRIBUTI_SORGENTE=${JSON.stringify(ATTRIBUTI_SORGENTE)};`,
345
+ `var STILI=${JSON.stringify(STILI)};`,
346
+ `var VUOTO=${pacchettoVuoto.toString()};`,
347
+ ].join('\n ');
348
+ const pure = [escapaCss, classeStabile, pezzoSelettore, selettoreStabile, tagliaHtml, ripulisciTesto].map((f) => f.toString()).join('\n ');
349
+ return `(function(){"use strict";\n if (window.__talosAnnotaCdp) return;\n ${costanti}\n ${pure}\n${COLLA}\n})();`;
350
+ }
351
+
352
+ /* ══ Il ponte col protocollo ════════════════════════════════════════════════════════════════════ */
353
+
354
+ /**
355
+ * Il client CDP arriva da fuori (nessuna dipendenza nuova: chi lo costruisce parla `ws`). Qui si
356
+ * accettano i due nomi che girano: `invia(metodo, parametri, sessionId)` o `send(...)`, `su`/`on`
357
+ * per gli eventi. Un client che non sa inviare è un errore subito, non un guasto misterioso dopo.
358
+ */
359
+ function porta(cdp) {
360
+ const invia = typeof cdp?.invia === 'function' ? cdp.invia.bind(cdp) : (typeof cdp?.send === 'function' ? cdp.send.bind(cdp) : null);
361
+ if (!invia) throw new TypeError('browser-annota: il client CDP deve avere «invia(metodo, parametri, sessionId)»');
362
+ const ascolta = typeof cdp?.su === 'function' ? cdp.su.bind(cdp) : (typeof cdp?.on === 'function' ? cdp.on.bind(cdp) : null);
363
+ const smettiDi = typeof cdp?.togli === 'function' ? cdp.togli.bind(cdp) : (typeof cdp?.off === 'function' ? cdp.off.bind(cdp) : null);
364
+ return { invia, ascolta, smettiDi };
365
+ }
366
+
367
+ /** Una risposta CDP può portare l'errore nel corpo invece di lanciarlo: i due casi diventano uno. */
368
+ async function chiama(invia, metodo, parametri, sessionId) {
369
+ const risposta = await invia(metodo, parametri || {}, sessionId);
370
+ if (risposta && risposta.error) { const e = new Error(`${metodo}: ${risposta.error.message || 'errore CDP'}`); e.codiceCdp = risposta.error.code; throw e; }
371
+ return risposta;
372
+ }
373
+
374
+ /** Il mondo isolato muore a ogni navigazione: lo si riconosce dal messaggio e si ricrea. */
375
+ function contestoPerduto(errore) {
376
+ return /cannot find context|context (was destroyed|with specified id)|execution context/i.test(String(errore?.message || ''));
377
+ }
378
+
379
+ /* Un installato per sessione: l'identificatore dello script permanente e il contesto del documento
380
+ * aperto. Chiave debole sul client, così due browser pilotati non si scambiano lo stato. */
381
+ const installati = new WeakMap();
382
+ function statoDi(cdp, sessionId) {
383
+ if (!installati.has(cdp)) installati.set(cdp, new Map());
384
+ const perSessione = installati.get(cdp);
385
+ const chiave = sessionId || '(radice)';
386
+ if (!perSessione.has(chiave)) perSessione.set(chiave, { identificatore: null, contesto: null, frameId: null });
387
+ return perSessione.get(chiave);
388
+ }
389
+
390
+ /** Il contesto del mondo isolato per il documento APERTO ADESSO: creato, e lo script valutato dentro. */
391
+ async function apriMondo(invia, sessionId, stato) {
392
+ const albero = await chiama(invia, 'Page.getFrameTree', {}, sessionId);
393
+ const frameId = albero?.frameTree?.frame?.id || stato.frameId;
394
+ if (!frameId) throw new Error('browser-annota: nessun frame principale da Page.getFrameTree');
395
+ const mondo = await chiama(invia, 'Page.createIsolatedWorld', { frameId, worldName: MONDO_OVERLAY, grantUniveralAccess: false }, sessionId);
396
+ const contesto = mondo?.executionContextId;
397
+ if (contesto == null) throw new Error('browser-annota: Page.createIsolatedWorld non ha dato un executionContextId');
398
+ await chiama(invia, 'Runtime.evaluate', { expression: sorgenteOverlay(), contextId: contesto, returnByValue: true, awaitPromise: false }, sessionId);
399
+ stato.frameId = frameId; stato.contesto = contesto;
400
+ return contesto;
401
+ }
402
+
403
+ /**
404
+ * Installa l'overlay e lo fa sopravvivere alle navigazioni successive.
405
+ * Due chiamate, non una, e servono tutte e due (vedi la testa del file):
406
+ * · `Page.addScriptToEvaluateOnNewDocument` con `worldName` → i documenti FUTURI, prima dei loro script;
407
+ * · `Page.createIsolatedWorld` + `Runtime.evaluate` → il documento GIÀ APERTO, che il primo non tocca.
408
+ * @param {{invia?:Function, send?:Function}} cdp
409
+ * @param {string|undefined} sessionId
410
+ * @returns {Promise<{identificatore:string|null, contesto:number}>}
411
+ */
412
+ export async function installaOverlay(cdp, sessionId, { sorgente = sorgenteOverlay() } = {}) {
413
+ const { invia } = porta(cdp);
414
+ const stato = statoDi(cdp, sessionId);
415
+ await chiama(invia, 'Page.enable', {}, sessionId);
416
+ if (!stato.identificatore) {
417
+ const aggiunto = await chiama(invia, 'Page.addScriptToEvaluateOnNewDocument', { source: sorgente, worldName: MONDO_OVERLAY }, sessionId);
418
+ stato.identificatore = aggiunto?.identifier || null;
419
+ }
420
+ const contesto = await apriMondo(invia, sessionId, stato);
421
+ return { identificatore: stato.identificatore, contesto };
422
+ }
423
+
424
+ /**
425
+ * Toglie l'overlay: prima lo script permanente (altrimenti torna alla prossima navigazione), poi i
426
+ * nodi già appesi al documento aperto. Lo smontaggio nella pagina è «meglio se riesce»: se il
427
+ * documento è cambiato sotto, quei nodi se ne sono già andati con lui.
428
+ */
429
+ export async function togliOverlay(cdp, sessionId) {
430
+ const { invia } = porta(cdp);
431
+ const stato = statoDi(cdp, sessionId);
432
+ let toltoScript = false;
433
+ if (stato.identificatore) {
434
+ await chiama(invia, 'Page.removeScriptToEvaluateOnNewDocument', { identifier: stato.identificatore }, sessionId);
435
+ toltoScript = true; stato.identificatore = null;
436
+ }
437
+ let smontato = false;
438
+ if (stato.contesto != null) {
439
+ try {
440
+ await chiama(invia, 'Runtime.evaluate', { expression: 'window.__talosAnnotaCdp ? window.__talosAnnotaCdp.smonta() : false', contextId: stato.contesto, returnByValue: true }, sessionId);
441
+ smontato = true;
442
+ } catch (errore) { if (!contestoPerduto(errore)) throw errore; }
443
+ stato.contesto = null;
444
+ }
445
+ return { toltoScript, smontato };
446
+ }
447
+
448
+ /* Il mondo principale è l'UNICO che vede le proprietà appese ai nodi dalla pagina: `_debugSource` e
449
+ * il nome del componente di React ≤18, `__vueParentComponent.type.__file` di Vue. Si entra per
450
+ * SELETTORE (niente attributi aggiunti alla pagina, nessuna modifica) e in sola lettura. Il testo
451
+ * che torna è della pagina: non affidabile, come tutto il resto. */
452
+ function sorgenteIndiziMondoPrincipale(selettore) {
453
+ return `(function(){try{
454
+ var el = document.querySelector(${JSON.stringify(selettore)});
455
+ if (!el) return {};
456
+ var out = {}; var e = el;
457
+ for (var g = 0; g < 6 && e; g++) {
458
+ var vue = e.__vueParentComponent;
459
+ if (vue && vue.type) { if (!out.componente) out.componente = vue.type.name || vue.type.__name || null; if (!out.file && vue.type.__file) out.file = vue.type.__file; }
460
+ for (var k in e) {
461
+ if (k.indexOf('__reactFiber$') !== 0) continue;
462
+ var fibra = e[k];
463
+ for (var j = 0; j < 8 && fibra; j++) {
464
+ if (fibra._debugSource && !out.file) out.file = fibra._debugSource.fileName + ':' + fibra._debugSource.lineNumber;
465
+ if (fibra.type && typeof fibra.type === 'function' && !out.componente) out.componente = fibra.type.displayName || fibra.type.name || null;
466
+ fibra = fibra._debugOwner || fibra.return;
467
+ }
468
+ }
469
+ e = e.parentElement;
470
+ }
471
+ var f = null;
472
+ if (window.__NEXT_DATA__) f = 'Next.js';
473
+ else if (window.__NUXT__) f = 'Nuxt';
474
+ else if (window.__vite_plugin_react_preamble_installed__) f = 'Vite';
475
+ if (f) out.framework = f;
476
+ if (out.componente) out.componente = String(out.componente).slice(0, 120);
477
+ if (out.file) out.file = String(out.file).slice(0, 300);
478
+ return out;
479
+ }catch(err){return {};}})()`;
480
+ }
481
+
482
+ async function arricchisciDalMondoPrincipale(invia, sessionId, pacchetto) {
483
+ if (!pacchetto.selettore) return pacchetto;
484
+ try {
485
+ /* niente `contextId`: omesso vuol dire mondo principale (CDP, Runtime.evaluate) */
486
+ const r = await chiama(invia, 'Runtime.evaluate', { expression: sorgenteIndiziMondoPrincipale(pacchetto.selettore), returnByValue: true, awaitPromise: false }, sessionId);
487
+ const indizi = r?.result?.value;
488
+ if (indizi && typeof indizi === 'object') pacchetto.indiziSorgente = { ...pacchetto.indiziSorgente, ...indizi };
489
+ } catch { /* il mondo principale è un di più: se non risponde, gli indizi restano quelli degli attributi */ }
490
+ return pacchetto;
491
+ }
492
+
493
+ /**
494
+ * Descrive l'elemento sotto un punto.
495
+ * ⛔ `x` e `y` sono pixel CSS del VIEWPORT — le stesse coordinate di `Input.dispatchMouseEvent` e
496
+ * quelle del fotogramma trasmesso una volta tolta la scala, NON coordinate di pagina: con la pagina
497
+ * scrollata i due sistemi non coincidono, e `elementFromPoint` vuole il viewport.
498
+ * @returns {Promise<{selettore:string, html:string, stili:object, antenati:string[], indiziSorgente:object, testo:string}>}
499
+ */
500
+ export async function descriviElemento(cdp, sessionId, { x, y } = {}, { mondoPrincipale = true } = {}) {
501
+ const { invia } = porta(cdp);
502
+ const stato = statoDi(cdp, sessionId);
503
+ const px = Number(x) || 0; const py = Number(y) || 0;
504
+ const espressione = `(function(){ if (!window.__talosAnnotaCdp) return { assente: true }; return window.__talosAnnotaCdp.descrivi(${px}, ${py}); })()`;
505
+
506
+ const unGiro = async (contesto) => chiama(invia, 'Runtime.evaluate', { expression: espressione, contextId: contesto, returnByValue: true, awaitPromise: false }, sessionId);
507
+
508
+ let contesto = stato.contesto;
509
+ if (contesto == null) contesto = await apriMondo(invia, sessionId, stato);
510
+ let risposta;
511
+ try { risposta = await unGiro(contesto); }
512
+ catch (errore) {
513
+ /* la pagina ha navigato: il mondo isolato di prima non esiste più. Una volta sola, poi si alza la mano. */
514
+ if (!contestoPerduto(errore)) throw errore;
515
+ contesto = await apriMondo(invia, sessionId, stato);
516
+ risposta = await unGiro(contesto);
517
+ }
518
+ let valore = risposta?.result?.value;
519
+ if (valore && valore.assente) {
520
+ /* il contesto c'è ma l'overlay no: un documento nuovo nato senza lo script permanente */
521
+ contesto = await apriMondo(invia, sessionId, stato);
522
+ valore = (await unGiro(contesto))?.result?.value;
523
+ }
524
+ const pacchetto = { ...pacchettoVuoto(), ...(valore && typeof valore === 'object' && !valore.assente ? valore : {}) };
525
+ delete pacchetto.assente;
526
+ if (mondoPrincipale && pacchetto.trovato) await arricchisciDalMondoPrincipale(invia, sessionId, pacchetto);
527
+ /* `sorgente` è il nome che `annotazioni.js` legge già nel pacchetto per il composer: lo stesso
528
+ oggetto sotto tutti e due i nomi, così quel codice non va toccato. */
529
+ pacchetto.sorgente = pacchetto.indiziSorgente;
530
+ return pacchetto;
531
+ }
532
+
533
+ /* ══ Gli errori della pagina ════════════════════════════════════════════════════════════════════ */
534
+
535
+ /** Un `Runtime.RemoteObject` → una riga leggibile, senza mai chiedere altro al browser. */
536
+ export function testoRemoto(oggetto) {
537
+ if (oggetto == null) return '';
538
+ if (typeof oggetto !== 'object') return String(oggetto);
539
+ if ('value' in oggetto && oggetto.value !== undefined) return typeof oggetto.value === 'string' ? oggetto.value : JSON.stringify(oggetto.value);
540
+ if (oggetto.unserializableValue) return String(oggetto.unserializableValue);
541
+ if (oggetto.description) return String(oggetto.description);
542
+ if (oggetto.preview?.description) return String(oggetto.preview.description);
543
+ return oggetto.className ? `[${oggetto.className}]` : `[${oggetto.type || 'oggetto'}]`;
544
+ }
545
+
546
+ /** I tipi di `console.*` che finiscono nel pacchetto: il resto (log, info, debug) è rumore. */
547
+ const CONSOLE_CHE_CONTANO = new Set(['error', 'warning', 'assert']);
548
+ /** I livelli del registro del browser che contano: `verbose` e `info` no. */
549
+ const LIVELLI_CHE_CONTANO = new Set(['error', 'warning']);
550
+
551
+ function riga(tipo, testo, origine) {
552
+ return { tipo, testo: String(testo || '').replace(/\s+/g, ' ').trim().slice(0, MASSIMO_TESTO_ERRORE), origine, quando: new Date().toISOString() };
553
+ }
554
+
555
+ /**
556
+ * Raccoglie gli errori della pagina. Torna SUBITO (sincrona) e si riempie mentre arrivano: gli
557
+ * ascolti si registrano prima delle `enable`, così nessun evento cade nel buco fra le due cose.
558
+ *
559
+ * ⛔ Tre eventi, non uno (il perché è in testa al file): `Runtime.consoleAPICalled` per le chiamate
560
+ * a `console.*`, `Runtime.exceptionThrown` per le eccezioni non catturate, `Log.entryAdded` per il
561
+ * registro del browser — le richieste di rete fallite, la CSP, le deprecazioni: cose che nessuno
562
+ * ha scritto con `console.error` e che senza questo evento non si vedrebbero mai.
563
+ *
564
+ * ⛔ SI CHIAMA PRIMA DI NAVIGARE. Misurato dal vivo il 07/09/2026: gli errori di una pagina GIÀ
565
+ * caricata non tornano indietro — il protocollo non rigioca quello che è successo prima che ci
566
+ * attaccassimo, e nella prima corsa il 404 dell'immagine era già passato quando abbiamo acceso i
567
+ * domini. Chi integra apre la raccolta appena ha la sessione, non quando la persona clicca «annota».
568
+ * @returns {{errori:Array<{tipo:string,testo:string,origine:string,quando:string}>, smetti:()=>void}}
569
+ */
570
+ export function raccogliErrori(cdp, sessionId) {
571
+ const { invia, ascolta, smettiDi } = porta(cdp);
572
+ if (!ascolta) throw new TypeError('browser-annota: il client CDP deve avere «su(evento, gestore)» per raccogliere gli errori');
573
+ const errori = [];
574
+ const disdette = [];
575
+ let vivo = true;
576
+
577
+ const aggiungi = (voce) => { if (vivo && errori.length < MASSIMO_ERRORI) errori.push(voce); };
578
+ /*
579
+ * ⛔ Il secondo argomento di un ascolto NON ha una forma sola. Il client CDP di `browser-vivo.mjs`
580
+ * (M2, letto il 07/09/2026) chiama `cb(params, { sessionId, metodo })` — un OGGETTO — mentre un
581
+ * client scritto a mano passa spesso il `sessionId` nudo. Confrontando l'oggetto con la stringa
582
+ * ogni evento risultava «di un'altra sessione» e veniva buttato: nessun errore, nessun avviso, e
583
+ * un pacchetto senza console. Si accettano tutte e tre le forme.
584
+ */
585
+ const miaSessione = (parametri, secondo) => {
586
+ if (!sessionId) return true;
587
+ const arrivata = typeof secondo === 'string' ? secondo : (secondo?.sessionId ?? parametri?.sessionId ?? null);
588
+ return !arrivata || arrivata === sessionId;
589
+ };
590
+
591
+ const gestori = {
592
+ 'Runtime.consoleAPICalled': (p, s) => {
593
+ if (!miaSessione(p, s)) return;
594
+ const tipo = String(p?.type || '');
595
+ if (!CONSOLE_CHE_CONTANO.has(tipo)) return;
596
+ const testo = (p?.args || []).map(testoRemoto).filter(Boolean).join(' ');
597
+ aggiungi(riga('console', testo || `console.${tipo}`, `console.${tipo}`));
598
+ },
599
+ 'Runtime.exceptionThrown': (p, s) => {
600
+ if (!miaSessione(p, s)) return;
601
+ const d = p?.exceptionDetails || {};
602
+ const testo = [d.text, testoRemoto(d.exception)].filter(Boolean).join(' ') || 'eccezione senza testo';
603
+ const dove = d.url ? ` — ${d.url}:${(d.lineNumber ?? 0) + 1}` : '';
604
+ /* un rifiuto di promessa non gestito arriva QUI, non fra le chiamate a console */
605
+ aggiungi(riga(/in promise/i.test(testo) ? 'promessa' : 'eccezione', testo + dove, 'Runtime.exceptionThrown'));
606
+ },
607
+ 'Log.entryAdded': (p, s) => {
608
+ if (!miaSessione(p, s)) return;
609
+ const e = p?.entry || {};
610
+ if (!LIVELLI_CHE_CONTANO.has(String(e.level || ''))) return;
611
+ const dove = e.url ? ` — ${e.url}` : '';
612
+ aggiungi(riga('browser', `${e.text || ''}${dove}`, `Log.${e.source || 'other'}`));
613
+ },
614
+ };
615
+
616
+ for (const [evento, gestore] of Object.entries(gestori)) {
617
+ const forse = ascolta(evento, gestore);
618
+ if (typeof forse === 'function') disdette.push(forse);
619
+ else if (smettiDi) disdette.push(() => smettiDi(evento, gestore));
620
+ }
621
+ /* le `enable` DOPO gli ascolti, e senza attendere: la funzione deve tornare sincrona (contratto) */
622
+ const acceso = Promise.all([
623
+ chiama(invia, 'Runtime.enable', {}, sessionId).catch(() => {}),
624
+ chiama(invia, 'Log.enable', {}, sessionId).catch(() => {}),
625
+ ]);
626
+
627
+ return {
628
+ errori,
629
+ smetti() {
630
+ if (!vivo) return;
631
+ vivo = false;
632
+ for (const d of disdette) { try { d(); } catch { /* un ascolto già chiuso non è un guasto */ } }
633
+ acceso.then(() => Promise.all([
634
+ chiama(invia, 'Log.disable', {}, sessionId).catch(() => {}),
635
+ chiama(invia, 'Runtime.disable', {}, sessionId).catch(() => {}),
636
+ ])).catch(() => {});
637
+ },
638
+ };
639
+ }