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,572 @@
1
+ /*
2
+ * PORTO FEDELE di AVM/mobile/src/lib/research/researchVerification.ts (544 righe, 11/09/2026).
3
+ *
4
+ * I tre livelli, e il rifiuto che li regge.
5
+ *
6
+ * R-4. Quello che il campo misura davvero, sugli agenti di ricerca approfondita
7
+ * in particolare (arXiv 2605.06635): il link risolve più del 94% delle volte, la
8
+ * fonte è in tema più dell'80% delle volte, e la fonte SOSTIENE davvero
9
+ * l'affermazione fra il 39% e il 77% delle volte. Quindi il link morto — la cosa
10
+ * che ogni prodotto controlla — non è il problema. Il problema è il link vivo che
11
+ * non dice quello che il rapporto dichiara dica. Peggio: quell'accuratezza cala
12
+ * di circa il 42% quando un agente passa da 2 recuperi a 150, cioè la modalità
13
+ * più profonda è quella le cui citazioni sono meno affidabili, che è esattamente
14
+ * il contrario di quello che un lettore dà per scontato.
15
+ *
16
+ * Da qui la forma:
17
+ *
18
+ * L1 Come la fonte è stata ottenuta. Registrato dalla lettura, non richiesto di
19
+ * nuovo: un secondo scaricamento pochi istanti dopo il primo conferma solo
20
+ * quello che abbiamo appena visto, e uno stato HTTP mente comunque (i soft
21
+ * 404 rispondono 200 con una pagina d'errore). La domanda onesta più tardi
22
+ * — «dice ancora questo?» — è quella di R12, ed è rispondibile solo perché
23
+ * abbiamo tenuto il testo.
24
+ * L2 Il passaggio è davvero nel testo che abbiamo tenuto, e DOVE. Meccanico,
25
+ * gratis, nessun modello, nessuna opinione. Prende da solo la categoria
26
+ * peggiore: la citazione che non è mai stata sulla pagina. Gli offset sono
27
+ * ciò che permette al rapporto di mostrare al lettore il pezzo esatto.
28
+ * L3 Quel passaggio sostiene quell'affermazione. Questo costa un modello, ed è
29
+ * giudicato una affermazione contro un passaggio — mai il rapporto intero,
30
+ * perché un valutatore di implicazione pronto all'uso che arriva a AUROC
31
+ * 0,90 su affermazioni corte crolla a 0,53 (il caso) sulle risposte lunghe
32
+ * (arXiv 2606.23915). La granularità non è un dettaglio; è la differenza
33
+ * fra un controllo e una decorazione.
34
+ *
35
+ * E il rifiuto: il modello che ha scritto l'affermazione non la giudica mai. Un
36
+ * modello che valuta la propria uscita ha fino al 50% di probabilità in più di
37
+ * marcare come soddisfatto un criterio che in realtà ha fallito (arXiv
38
+ * 2604.06996). Una promozione auto-rilasciata vale meno di nessuna promozione,
39
+ * perché ne ha l'aspetto.
40
+ */
41
+
42
+ import {
43
+ talosResearchOpposingCandidate,
44
+ talosResearchParseOpposingVerdict,
45
+ } from './opposing.mjs';
46
+
47
+ /**
48
+ * @typedef {import('./collector.mjs').TalosResearchSource} TalosResearchSource
49
+ * @typedef {import('./synthesis.mjs').TalosResearchClaim} TalosResearchClaim
50
+ */
51
+
52
+ /**
53
+ * ⛔⛔ CONTESA-01 — «contesa» non è «parziale», e confonderle mente.
54
+ *
55
+ * - **parziale**: la fonte dice una parte di quello che si afferma. Una
56
+ * fonte, un verdetto a metà.
57
+ * - **contesa**: una fonte dice di sì e un'altra dice di no. Due fonti, due
58
+ * verdetti opposti, e nessuna metà da nessuna parte.
59
+ *
60
+ * Registrarle come la stessa cosa lusinga il rapporto proprio dove è più
61
+ * fragile: una contesa segnata «parziale» si legge come «quasi sostenuta»,
62
+ * mentre vuol dire che il mondo non è d'accordo.
63
+ *
64
+ * ⛔ Ricerca del 2026-08-20: i conflitti sono di tre tipi distinti — nelle
65
+ * prove, fra le fonti sulle prove, dentro la stessa fonte — e la pratica
66
+ * concorde è mostrare **entrambe** le versioni col perché differiscono
67
+ * (metodo, portata, data, disciplina). Non si media, e non si sceglie in
68
+ * silenzio la più comoda.
69
+ *
70
+ * @typedef {'yes' | 'partial' | 'no' | 'unchecked' | 'contested'} TalosResearchSupport
71
+ */
72
+
73
+ /**
74
+ * Una fonte che dice il CONTRARIO, col suo passaggio: la scheda le affianca.
75
+ *
76
+ * @typedef {object} TalosResearchOpposing
77
+ * @property {string} url
78
+ * @property {string} title
79
+ * @property {string} passage Il passaggio come sta nella fonte, non come il modello lo ha riscritto.
80
+ * @property {TalosResearchSpan | null} span
81
+ */
82
+
83
+ /**
84
+ * Dove sta il passaggio nel testo tenuto, così il lettore lo può vedere.
85
+ *
86
+ * @typedef {object} TalosResearchSpan
87
+ * @property {number} from
88
+ * @property {number} to
89
+ */
90
+
91
+ /**
92
+ * Quanto basta a distinguere due giudici, e a riconoscere l'autore fra loro.
93
+ *
94
+ * @typedef {object} TalosResearchJudgeIdentity
95
+ * @property {string} id
96
+ * @property {string} provider
97
+ * @property {string} model
98
+ */
99
+
100
+ /**
101
+ * @typedef {object} TalosResearchChecks
102
+ * @property {'page' | 'snippet' | 'missing'} resolved L1: letta dalla pagina, presa da un estratto di ricerca, o citata nel vuoto.
103
+ * @property {boolean} quotePresent L2
104
+ * @property {TalosResearchSpan | null} quoteSpan
105
+ * @property {TalosResearchSupport} claimSupported L3
106
+ * @property {string} supportReason
107
+ * @property {string | null} judge Chi ha reso il verdetto, e quando. Null quando nessuno l'ha fatto — e il perché sta nel motivo.
108
+ * @property {string | null} judgedAt
109
+ * @property {readonly TalosResearchOpposing[]} [opposing]
110
+ * ⛔ CONTESA-01 — le fonti che dicono il contrario, col loro passaggio.
111
+ * Opzionale perché una verifica vecchia non le ha: assente vuol dire «non
112
+ * guardato», non «non ce ne sono». Le due cose si leggono uguali solo se non
113
+ * ti importa di sbagliare.
114
+ */
115
+
116
+ /**
117
+ * @typedef {object} TalosResearchVerifiedClaim
118
+ * @property {TalosResearchClaim} claim
119
+ * @property {string} passage Il passaggio com'è nella fonte, non come il modello l'ha ribattuto.
120
+ * @property {TalosResearchChecks} checks
121
+ */
122
+
123
+ /**
124
+ * @typedef {object} TalosResearchVerifyDeps
125
+ * @property {TalosResearchJudgeIdentity | null} judge Il giudice indipendente, o null quando non ce n'è. Scelto da `talosResearchPickJudge`.
126
+ * @property {(claim: string, passage: string) => Promise<string>} ask
127
+ * Chiede al giudice di UNA affermazione e UN passaggio. La firma È
128
+ * l'isolamento: non c'è modo di passargli la domanda, il riassunto o le altre
129
+ * affermazioni, perché tutto ciò che aggiungi spinge la risposta verso «sì,
130
+ * quadra».
131
+ * @property {(claim: string, passage: string) => Promise<string>} [askOpposing]
132
+ * ⛔ CONTESA-02 — chiede allo stesso giudice se un passaggio di un'ALTRA fonte
133
+ * contraddice l'affermazione. Opzionale, e assente vuol dire «non guardato»:
134
+ * senza, il verdetto resta quello di prima e `opposing` non c'è. È la stessa
135
+ * distinzione che il campo `opposing` porta nella scheda — «non guardato» non
136
+ * è «non ce ne sono», e le due cose si leggono uguali solo se non importa
137
+ * sbagliare.
138
+ * @property {() => string} at
139
+ */
140
+
141
+ /* -------------------------------------------------------------------------- */
142
+ /* L2 */
143
+ /* -------------------------------------------------------------------------- */
144
+
145
+ /**
146
+ * Normalizza un testo ricordandosi da dove viene ogni carattere.
147
+ *
148
+ * Una pagina e un modello non sono d'accordo su spazi e virgolette e sono
149
+ * d'accordo sul significato, quindi il confronto deve essere lasco. Ma il
150
+ * RAPPORTO deve poter puntare al testo originale, e un confronto lasco che
151
+ * perde la posizione è inutile. Tenere la mappa è ciò che fa funzionare «tocca
152
+ * la citazione, vedi le parole esatte».
153
+ *
154
+ * @param {string} text
155
+ * @returns {{flat: string, at: {s:number, e:number}[]}}
156
+ */
157
+ function mapped(text) {
158
+ /** @type {string[]} */
159
+ const out = [];
160
+ /** @type {{s:number, e:number}[]} */
161
+ const at = [];
162
+
163
+ for (let index = 0; index < text.length;) {
164
+ const char = text[index];
165
+ if (/\s/.test(char)) {
166
+ let end = index;
167
+ while (end < text.length && /\s/.test(text[end])) end += 1;
168
+ out.push(' ');
169
+ at.push({ s: index, e: end });
170
+ index = end;
171
+ continue;
172
+ }
173
+
174
+ const plain = char === '‘' || char === '’' ? "'"
175
+ : char === '“' || char === '”' ? '"'
176
+ : char.toLowerCase();
177
+ // Un carattere della fonte può diventare più caratteri in minuscolo; tutti
178
+ // puntano indietro allo stesso carattere, così gli offset restano onesti.
179
+ for (const produced of plain) {
180
+ out.push(produced);
181
+ at.push({ s: index, e: index + 1 });
182
+ }
183
+ index += 1;
184
+ }
185
+
186
+ return { flat: out.join(''), at };
187
+ }
188
+
189
+ /**
190
+ * Trova il passaggio nel testo tenuto e dice dov'è, oppure null.
191
+ *
192
+ * Null è una risposta vera: il modello ha citato qualcosa che non c'è. Qui
193
+ * dentro niente cerca la frase simile più vicina — un verificatore che
194
+ * gentilmente trova un'approssimazione è un verificatore che fabbrica
195
+ * attribuzioni, che è esattamente il guasto per cui questo file esiste.
196
+ *
197
+ * @param {string} text
198
+ * @param {string} quote
199
+ * @returns {TalosResearchSpan | null}
200
+ */
201
+ export function talosResearchLocate(text, quote) {
202
+ const haystack = mapped(text);
203
+ const needle = mapped(quote).flat.trim();
204
+ if (needle.length === 0) return null;
205
+
206
+ const found = haystack.flat.indexOf(needle);
207
+ if (found < 0) return null;
208
+
209
+ return {
210
+ from: haystack.at[found].s,
211
+ to: haystack.at[found + needle.length - 1].e,
212
+ };
213
+ }
214
+
215
+ /* -------------------------------------------------------------------------- */
216
+ /* L3 */
217
+ /* -------------------------------------------------------------------------- */
218
+
219
+ /**
220
+ * Il giudice, scelto per eliminazione: chiunque tranne l'autore.
221
+ *
222
+ * I candidati arrivano nell'ordine che il chiamante preferisce — il motore sul
223
+ * dispositivo per primo, perché non costa niente, non ha bisogno di rete e non
224
+ * appartiene alla famiglia di nessun modello in cloud. Se ogni candidato è
225
+ * l'autore, questa torna null e le affermazioni escono marcate `unchecked` col
226
+ * motivo scritto. È tutto il punto: un'affermazione non giudicata è onesta, una
227
+ * auto-giudicata no.
228
+ *
229
+ * Generico perché il chiamante tenga quello che aveva attaccato al candidato —
230
+ * l'oggetto modello, le credenziali — invece di scegliere un giudice e poi
231
+ * doverlo ricercare per nome, che è il modo in cui si finisce per chiamare
232
+ * quello sbagliato.
233
+ *
234
+ * @template {TalosResearchJudgeIdentity} T
235
+ * @param {TalosResearchJudgeIdentity} author
236
+ * @param {readonly T[]} candidates
237
+ * @returns {T | null}
238
+ */
239
+ export function talosResearchPickJudge(author, candidates) {
240
+ return candidates.find((candidate) => !(
241
+ candidate.provider === author.provider && candidate.model === author.model
242
+ )) ?? null;
243
+ }
244
+
245
+ /**
246
+ * Quali case interpellare, e in che ordine.
247
+ *
248
+ * Sul dispositivo per primo: gratis, senza rete, e imparentato con nessun
249
+ * modello in cloud. Poi qualunque fornitore che non sia quello dell'autore,
250
+ * perché la preferenza per sé è misurata estendersi alla famiglia di un modello
251
+ * e non solo a sé stesso. Il fornitore dell'autore viene per ultimo, e ci si
252
+ * arriva solo con un modello diverso — un'indipendenza reale ma più debole, ed
253
+ * è per questo che il nome del giudice finisce nel rapporto, perché il lettore
254
+ * lo possa pesare.
255
+ *
256
+ * @template {string} P
257
+ * @param {P} authorProvider
258
+ * @param {readonly P[]} providers
259
+ * @param {P} onDevice
260
+ * @returns {readonly P[]}
261
+ */
262
+ export function talosResearchJudgeOrder(authorProvider, providers, onDevice) {
263
+ return [
264
+ ...providers.filter((provider) => provider === onDevice),
265
+ ...providers.filter((provider) => provider !== onDevice && provider !== authorProvider),
266
+ ...providers.filter((provider) => provider !== onDevice && provider === authorProvider),
267
+ ];
268
+ }
269
+
270
+ /**
271
+ * Quello che si chiede al giudice, e nient'altro.
272
+ *
273
+ * L'istruzione a usare solo il passaggio è la riga portante: senza, il modello
274
+ * risponde da quello che già sa, e un'affermazione che si dà il caso sia vera
275
+ * raccoglie una promozione da un passaggio che non l'ha mai detta — che è
276
+ * precisamente il guasto che un controllo delle citazioni dovrebbe prendere.
277
+ *
278
+ * @param {string} claim
279
+ * @param {string} passage
280
+ * @returns {string}
281
+ */
282
+ export function talosResearchJudgePrompt(claim, passage) {
283
+ return [
284
+ 'Passaggio, copiato dalla fonte:',
285
+ '"""',
286
+ passage,
287
+ '"""',
288
+ '',
289
+ 'Affermazione da verificare:',
290
+ claim,
291
+ '',
292
+ 'Il passaggio, DA SOLO, sostiene l’affermazione?',
293
+ 'Non usare altro: né quello che sai, né quello che ti sembra probabile.',
294
+ '',
295
+ // ⛔⛔ IL MENU CON LE BARRE lo faceva RICOPIARE.
296
+ //
297
+ // MISURATO sul Pad il 2026-08-20 con gemma-3-4b come giudice: la
298
+ // risposta arrivava come «Sì | PARZIALE | Il passaggio indica che…»,
299
+ // cioè due voci del menu invece di una. Il parser prendeva la prima
300
+ // e quei rapporti risultavano al 100%: erano verdetti che il giudice
301
+ // non aveva dato.
302
+ //
303
+ // ⇒ Le tre parole si elencano una per riga, senza barre, e si mostra
304
+ // com’è fatta una risposta buona. Non c’è più niente da ricopiare.
305
+ 'Rispondi con UNA riga sola. Comincia con UNA di queste tre parole:',
306
+ 'SI',
307
+ 'PARZIALE',
308
+ 'NO',
309
+ 'Poi un trattino e il motivo, massimo quindici parole.',
310
+ '',
311
+ 'Esempio di risposta: SI — il passaggio lo dice testualmente.',
312
+ '',
313
+ 'PARZIALE significa: il passaggio riguarda l’argomento ma non sostiene',
314
+ 'tutta l’affermazione (per esempio ne sostiene il fatto ma non la misura).',
315
+ ].join('\n');
316
+ }
317
+
318
+ /**
319
+ * `\b` qui non serve a niente: i verdetti italiani finiscono con lettere
320
+ * accentate, che JavaScript non conta come caratteri di parola, quindi «Sì»
321
+ * fallirebbe un test di confine di parola.
322
+ *
323
+ * ⛔ Le barre in testa si saltano: un modello che risponde «| PARZIALE |
324
+ * motivo» ha dato il verdetto, con addosso la punteggiatura del menu.
325
+ */
326
+ const VERDICT = /^[\s|]*(s[iì]|parziale|no)(?![\p{L}\p{N}])/iu;
327
+
328
+ /** Un pezzo che è SOLO una parola di verdetto, senza niente attorno. */
329
+ const SOLO_VERDETTO = /^\s*(s[iì]|parziale|no)\s*$/iu;
330
+
331
+ /**
332
+ * Legge il verdetto, o ammette che non ce n'era uno.
333
+ *
334
+ * Una risposta che non si analizza è `unchecked`, mai una promozione.
335
+ * L'alternativa — trattare una risposta confusa come un assenso — metterebbe un
336
+ * segno di verifica sulle affermazioni che il giudice ha trovato più difficili,
337
+ * che è il posto peggiore possibile dove metterlo.
338
+ *
339
+ * @param {string} answer
340
+ * @returns {{support: TalosResearchSupport, reason: string}}
341
+ */
342
+ export function talosResearchParseVerdict(answer) {
343
+ for (const line of answer.split('\n')) {
344
+ const match = VERDICT.exec(line);
345
+ if (!match) continue;
346
+
347
+ /*
348
+ * ⛔⛔ IL MENU RICOPIATO non è una scelta.
349
+ *
350
+ * MISURATO sul Pad il 2026-08-20: il giudice ha risposto «Sì |
351
+ * PARZIALE | Il passaggio indica che…», cioè ha ricopiato due voci
352
+ * del formato invece di sceglierne una. Il parser prendeva la prima
353
+ * e attaccava il resto — barre comprese — come «motivo»: a schermo
354
+ * si leggeva «contesa» sopra e «| PARZIALE |» sotto, due parole
355
+ * diverse per lo stesso stato, e il verdetto era il più generoso
356
+ * dei due.
357
+ *
358
+ * ⇒ Due voci del menu in una riga = nessun verdetto. Sceglierne una
359
+ * al posto suo sarebbe inventare la parte che non ha detto.
360
+ */
361
+ const pezzi = line.split('|').map((pezzo) => pezzo.trim());
362
+ if (pezzi.filter((pezzo) => SOLO_VERDETTO.test(pezzo)).length >= 2) {
363
+ return { support: 'unchecked', reason: '' };
364
+ }
365
+
366
+ const word = match[1].toLowerCase();
367
+ return {
368
+ support: word === 'parziale' ? 'partial' : word === 'no' ? 'no' : 'yes',
369
+ // La barra sta fra i separatori: «SI | motivo» è la stessa cosa
370
+ // di «SI — motivo», e la barra non è parte del motivo.
371
+ reason: line.slice(match[0].length).replace(/^[\s|—–\-:,.]+/, '').trim(),
372
+ };
373
+ }
374
+ return { support: 'unchecked', reason: '' };
375
+ }
376
+
377
+ /* -------------------------------------------------------------------------- */
378
+ /* I tre livelli insieme */
379
+ /* -------------------------------------------------------------------------- */
380
+
381
+ const NO_SOURCE = 'la fonte citata non esiste fra quelle raccolte';
382
+ const NO_QUOTE = 'il passaggio non è nel testo della fonte';
383
+ const NO_JUDGE = 'nessun giudice indipendente disponibile: l’autore non può verificare sé stesso';
384
+
385
+ /**
386
+ * Cerca chi dice il contrario, e chiede al giudice se lo dice davvero.
387
+ *
388
+ * ⛔ UNA sola candidata per affermazione: è una chiamata al giudice in più,
389
+ * e sul motore del telefono le chiamate sono in fila. Cercarne tre
390
+ * raddoppierebbe il tempo di un rapporto per trovare, quasi sempre, la
391
+ * stessa cosa.
392
+ *
393
+ * ⛔ E un guasto qui NON porta via l'affermazione: torna vuoto, il verdetto
394
+ * resta quello del primo giro. Una contesa che non si è potuta cercare non
395
+ * è una contesa che non c'è, ma è comunque meglio di un rapporto perso.
396
+ *
397
+ * @param {TalosResearchVerifyDeps} deps
398
+ * @param {TalosResearchClaim} claim
399
+ * @param {readonly TalosResearchSource[]} sources
400
+ * @param {TalosResearchSupport} support
401
+ * @param {string} passage Quello che il giudice ha appena approvato: chi lo ripete non lo nega.
402
+ * @returns {Promise<readonly TalosResearchOpposing[]>}
403
+ */
404
+ async function contrarie(deps, claim, sources, support, passage) {
405
+ // La contesa è disaccordo: senza un accordo prima non c'è niente con cui
406
+ // essere in disaccordo, e chiedere costerebbe per nulla.
407
+ if (!deps.askOpposing) return [];
408
+ if (support !== 'yes' && support !== 'partial') return [];
409
+
410
+ const candidata = talosResearchOpposingCandidate(claim.text, claim.sourceIndex - 1, sources, passage);
411
+ if (!candidata) return [];
412
+
413
+ try {
414
+ const risposta = await deps.askOpposing(claim.text, candidata.passage);
415
+ if (!talosResearchParseOpposingVerdict(risposta)) return [];
416
+ return [{
417
+ url: candidata.url,
418
+ title: candidata.title,
419
+ passage: candidata.passage,
420
+ span: candidata.span,
421
+ }];
422
+ } catch {
423
+ return [];
424
+ }
425
+ }
426
+
427
+ /**
428
+ * Fa girare i tre livelli su ogni affermazione.
429
+ *
430
+ * IN SEQUENZA, e non per caso: il motore sul dispositivo risponde a una
431
+ * richiesta per volta e rifiuta la seconda, quindi una verifica che si
432
+ * aprisse a ventaglio farebbe fallire ogni affermazione tranne la prima —
433
+ * proprio sul giudice che non costa niente ed è quindi quello predefinito.
434
+ *
435
+ * L3 si salta quando L2 è fallito. Chiedere a un modello se un passaggio
436
+ * inventato sostiene un'affermazione è chiedergli di qualcosa che non è una
437
+ * prova; la citazione è già rotta, e pagare per farla discutere produrrebbe
438
+ * solo un secondo parere su una fabbricazione.
439
+ *
440
+ * @param {TalosResearchVerifyDeps} deps
441
+ * @param {readonly TalosResearchClaim[]} claims
442
+ * @param {readonly TalosResearchSource[]} sources
443
+ * @returns {Promise<readonly TalosResearchVerifiedClaim[]>}
444
+ */
445
+ export async function talosResearchVerify(deps, claims, sources) {
446
+ /** @type {TalosResearchVerifiedClaim[]} */
447
+ const verified = [];
448
+
449
+ for (const claim of claims) {
450
+ const source = sources[claim.sourceIndex - 1];
451
+ const span = source ? talosResearchLocate(source.text, claim.quote) : null;
452
+ const passage = source && span ? source.text.slice(span.from, span.to) : '';
453
+
454
+ const base = {
455
+ resolved: source ? source.obtained : 'missing',
456
+ quotePresent: span !== null,
457
+ quoteSpan: span,
458
+ };
459
+
460
+ if (!source || !span) {
461
+ verified.push({
462
+ claim,
463
+ passage,
464
+ checks: {
465
+ ...base,
466
+ claimSupported: 'unchecked',
467
+ supportReason: source ? NO_QUOTE : NO_SOURCE,
468
+ judge: null,
469
+ judgedAt: null,
470
+ },
471
+ });
472
+ continue;
473
+ }
474
+
475
+ if (!deps.judge) {
476
+ verified.push({
477
+ claim,
478
+ passage,
479
+ checks: { ...base, claimSupported: 'unchecked', supportReason: NO_JUDGE, judge: null, judgedAt: null },
480
+ });
481
+ continue;
482
+ }
483
+
484
+ try {
485
+ // Il passaggio mandato è quello ritagliato dalla fonte, quindi un modello
486
+ // non può far passare una citazione ritoccata davanti al controllo che la
487
+ // legge.
488
+ const verdict = talosResearchParseVerdict(await deps.ask(claim.text, passage));
489
+ const judged = verdict.support !== 'unchecked';
490
+ const opposing = judged ? await contrarie(deps, claim, sources, verdict.support, passage) : [];
491
+ verified.push({
492
+ claim,
493
+ passage,
494
+ checks: {
495
+ ...base,
496
+ // ⛔ La contesa NON sostituisce il verdetto a mano: la regola
497
+ // («era un sì o un in parte, e qualcuno dice di no») sta in
498
+ // un posto solo, con i suoi test.
499
+ claimSupported: talosResearchContestedVerdict(verdict.support, opposing),
500
+ supportReason: judged ? verdict.reason : 'il giudice non ha dato un verdetto leggibile',
501
+ judge: judged ? deps.judge.id : null,
502
+ judgedAt: judged ? deps.at() : null,
503
+ ...(opposing.length ? { opposing } : {}),
504
+ },
505
+ });
506
+ } catch (failure) {
507
+ // Un giudice che cade non deve portarsi via il rapporto: le altre
508
+ // affermazioni restano controllabili, e questa dice perché non lo è.
509
+ verified.push({
510
+ claim,
511
+ passage,
512
+ checks: {
513
+ ...base,
514
+ claimSupported: 'unchecked',
515
+ supportReason: failure instanceof Error ? failure.message : 'il giudice non ha risposto',
516
+ judge: null,
517
+ judgedAt: null,
518
+ },
519
+ });
520
+ }
521
+ }
522
+
523
+ return verified;
524
+ }
525
+
526
+ /**
527
+ * ⛔ CONTESA-01 — il verdetto FINALE, dopo aver guardato anche le contrarie.
528
+ *
529
+ * Contesa vuol dire **disaccordo**, e il disaccordo esiste solo se il
530
+ * giudice aveva detto di sì (o in parte) e qualcuno dice di no. Se il
531
+ * giudice ha già detto «no», una fonte contraria non è un conflitto: è la
532
+ * stessa cosa detta due volte, e chiamarla contesa toglierebbe forza a un
533
+ * «no» che invece è solido.
534
+ *
535
+ * ⛔ E una NON verificata non diventa contesa: se nessuno ha giudicato non
536
+ * c'è niente con cui l'altra fonte possa essere in disaccordo.
537
+ *
538
+ * @param {TalosResearchSupport} support
539
+ * @param {readonly TalosResearchOpposing[] | undefined} opposing
540
+ * @returns {TalosResearchSupport}
541
+ */
542
+ export function talosResearchContestedVerdict(support, opposing) {
543
+ if (!opposing?.length) return support;
544
+ return support === 'yes' || support === 'partial' ? 'contested' : support;
545
+ }
546
+
547
+ /**
548
+ * La riga in cima al rapporto: quanto di questo ha davvero retto.
549
+ *
550
+ * @param {readonly TalosResearchVerifiedClaim[]} claims
551
+ * @returns {{total:number, supported:number, partial:number, unsupported:number, unchecked:number, contested:number}}
552
+ */
553
+ export function talosResearchVerifiedStanding(claims) {
554
+ /** @param {TalosResearchSupport} support */
555
+ const count = (support) =>
556
+ claims.filter((entry) => entry.checks.claimSupported === support).length;
557
+
558
+ return {
559
+ total: claims.length,
560
+ supported: count('yes'),
561
+ partial: count('partial'),
562
+ unsupported: count('no'),
563
+ // Tenuto a parte da `unsupported` di proposito: «non abbiamo potuto
564
+ // controllarlo» e «abbiamo controllato, e la fonte non lo dice» sono due
565
+ // ammissioni diverse, e fonderle lusingherebbe la seconda.
566
+ unchecked: count('unchecked'),
567
+ // ⛔ E la contesa sta fuori da tutte e tre: non è una sostenuta con
568
+ // una riserva, non è una parziale, e non è un'ammissione di non
569
+ // sapere. È il mondo che non concorda, ed è un esito suo.
570
+ contested: count('contested'),
571
+ };
572
+ }