talos-code 0.0.1 → 0.2.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 (407) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/LICENSE +661 -0
  3. package/README.md +116 -3
  4. package/THIRD_PARTY_NOTICES.md +40 -0
  5. package/dist/archive/zip.js +73 -0
  6. package/dist/args.js +100 -0
  7. package/dist/automations/history-store.js +34 -0
  8. package/dist/automations/policy-store.js +43 -0
  9. package/dist/automations/runner.js +107 -0
  10. package/dist/automations/schedule.js +85 -0
  11. package/dist/automations/windows-task.js +53 -0
  12. package/dist/commands/advanced-cli.js +233 -0
  13. package/dist/commands/checkpoint-cli.js +45 -0
  14. package/dist/commands/config-cli.js +107 -0
  15. package/dist/commands/context.js +17 -0
  16. package/dist/commands/extensions-cli.js +207 -0
  17. package/dist/commands/project-cli.js +74 -0
  18. package/dist/commands/project-commands.js +143 -0
  19. package/dist/commands/provider-cli.js +244 -0
  20. package/dist/commands/services-cli.js +248 -0
  21. package/dist/commands/session-cli.js +171 -0
  22. package/dist/commands/system-cli.js +405 -0
  23. package/dist/config/commands.js +60 -0
  24. package/dist/config/load.js +382 -0
  25. package/dist/config/migrations.js +48 -0
  26. package/dist/config/types.js +11 -0
  27. package/dist/diagnostics/development-log.js +154 -0
  28. package/dist/diagnostics/doctor.js +104 -0
  29. package/dist/diagnostics/redact.js +80 -0
  30. package/dist/diagnostics/zip.js +52 -0
  31. package/dist/errors.js +156 -0
  32. package/dist/events/bridge.js +130 -0
  33. package/dist/extensions/installer.js +178 -0
  34. package/dist/extensions/package-schema.js +24 -0
  35. package/dist/headless/result.js +84 -0
  36. package/dist/headless/run.js +230 -0
  37. package/dist/i18n/en/approval.js +46 -0
  38. package/dist/i18n/en/common.js +9 -0
  39. package/dist/i18n/en/credentials.js +92 -0
  40. package/dist/i18n/en/errors.js +267 -0
  41. package/dist/i18n/en/firstrun.js +101 -0
  42. package/dist/i18n/en/providers.js +37 -0
  43. package/dist/i18n/en/screen.js +774 -0
  44. package/dist/i18n/en/tools.js +127 -0
  45. package/dist/i18n/en.js +14 -0
  46. package/dist/i18n/error-view.js +307 -0
  47. package/dist/i18n/index.js +19 -0
  48. package/dist/i18n/kernel-map.js +139 -0
  49. package/dist/io.js +45 -0
  50. package/dist/main.js +331 -0
  51. package/dist/paths.js +41 -0
  52. package/dist/protocol/v2/codec.js +9 -0
  53. package/dist/protocol/v2/events.js +555 -0
  54. package/dist/protocol/v2/index.js +4 -0
  55. package/dist/protocol/v2/replay.js +28 -0
  56. package/dist/protocol/v2/types.js +1 -0
  57. package/dist/provider/control-plane.js +135 -0
  58. package/dist/provider/environment-keys.js +275 -0
  59. package/dist/provider/health.js +110 -0
  60. package/dist/provider/missing-key.js +48 -0
  61. package/dist/provider/model-catalog.js +168 -0
  62. package/dist/provider/openrouter-login.js +172 -0
  63. package/dist/provider/provider-text.js +13 -0
  64. package/dist/provider/store.js +95 -0
  65. package/dist/provider/system-keyring.js +214 -0
  66. package/dist/runtime/active-run.js +63 -0
  67. package/dist/runtime/agent-tree.js +74 -0
  68. package/dist/runtime/attachments.js +84 -0
  69. package/dist/runtime/brokered-executor.js +395 -0
  70. package/dist/runtime/context-archive.js +69 -0
  71. package/dist/runtime/context-status.js +76 -0
  72. package/dist/runtime/create-runtime.js +111 -0
  73. package/dist/runtime/model-profile.js +361 -0
  74. package/dist/runtime/output-store.js +137 -0
  75. package/dist/runtime/provider-attempts.js +185 -0
  76. package/dist/runtime/replay-buffer.js +153 -0
  77. package/dist/runtime/repo.js +95 -0
  78. package/dist/runtime/session-facade.js +135 -0
  79. package/dist/runtime/session-summary.js +125 -0
  80. package/dist/runtime/supervisor.js +265 -0
  81. package/dist/runtime/talos-composition.js +1011 -0
  82. package/dist/runtime/types.js +5 -0
  83. package/dist/runtime/usage-snapshot.js +82 -0
  84. package/dist/security/auto-classifier.js +38 -0
  85. package/dist/security/credential-free-environment.js +54 -0
  86. package/dist/security/evaluate.js +243 -0
  87. package/dist/security/execution-backends.js +236 -0
  88. package/dist/security/execution-broker.js +102 -0
  89. package/dist/security/forge-scan.js +74 -0
  90. package/dist/security/from-approval.js +39 -0
  91. package/dist/security/mxc-execution-backend.js +281 -0
  92. package/dist/security/permission-engine.js +138 -0
  93. package/dist/security/permission-explanation.js +54 -0
  94. package/dist/security/persist.js +179 -0
  95. package/dist/security/plugin-guard.js +230 -0
  96. package/dist/security/process-tree-evidence-store.js +74 -0
  97. package/dist/security/process-tree-probe.js +554 -0
  98. package/dist/security/project-resource-inventory.js +186 -0
  99. package/dist/security/project-trust-gate.js +38 -0
  100. package/dist/security/project-trust.js +367 -0
  101. package/dist/security/rule-parser.js +201 -0
  102. package/dist/security/shell-segmentation.js +68 -0
  103. package/dist/security/trust-authority.js +324 -0
  104. package/dist/security/types.js +1 -0
  105. package/dist/security/workspace-identity.js +102 -0
  106. package/dist/services/automation-facade.js +59 -0
  107. package/dist/services/forge-facade.js +77 -0
  108. package/dist/services/hook-facade.js +240 -0
  109. package/dist/services/index.js +16 -0
  110. package/dist/services/library-facade.js +174 -0
  111. package/dist/services/mcp-facade.js +348 -0
  112. package/dist/services/memory-facade.js +126 -0
  113. package/dist/services/notes-facade.js +157 -0
  114. package/dist/services/plugin-facade.js +308 -0
  115. package/dist/services/research-facade.js +110 -0
  116. package/dist/services/task-board-facade.js +236 -0
  117. package/dist/services/workflow-catalog.js +246 -0
  118. package/dist/sessions/export-format.js +98 -0
  119. package/dist/sessions/metadata-store.js +160 -0
  120. package/dist/sessions/share.js +122 -0
  121. package/dist/sessions/transfer.js +16 -0
  122. package/dist/subcommands.js +62 -0
  123. package/dist/tui/agent-roster.js +36 -0
  124. package/dist/tui/agent-view.js +51 -0
  125. package/dist/tui/app.js +4098 -0
  126. package/dist/tui/approval.js +36 -0
  127. package/dist/tui/boot/boot-sequence.js +76 -0
  128. package/dist/tui/boot/cinematic.js +243 -0
  129. package/dist/tui/boot/desktop-logo.js +82 -0
  130. package/dist/tui/boot.js +3 -0
  131. package/dist/tui/busy-input.js +58 -0
  132. package/dist/tui/catalog-service.js +560 -0
  133. package/dist/tui/components/assistant-stream.js +1 -0
  134. package/dist/tui/components/command-menu.js +68 -0
  135. package/dist/tui/components/composer.js +219 -0
  136. package/dist/tui/components/diff.js +35 -0
  137. package/dist/tui/components/footer.js +48 -0
  138. package/dist/tui/components/header.js +6 -0
  139. package/dist/tui/components/markdown.js +305 -0
  140. package/dist/tui/components/status-indicator.js +38 -0
  141. package/dist/tui/components/terminal-shell.js +214 -0
  142. package/dist/tui/components/thinking-row.js +19 -0
  143. package/dist/tui/components/tool-row.js +97 -0
  144. package/dist/tui/components/transcript-virtualizer.js +165 -0
  145. package/dist/tui/components/transcript.js +43 -0
  146. package/dist/tui/descendant-approvals.js +104 -0
  147. package/dist/tui/diff-model.js +77 -0
  148. package/dist/tui/editor-history.js +21 -0
  149. package/dist/tui/editor.js +210 -0
  150. package/dist/tui/event-adapter.js +436 -0
  151. package/dist/tui/exit-output.js +58 -0
  152. package/dist/tui/external-editor.js +53 -0
  153. package/dist/tui/file-completion.js +89 -0
  154. package/dist/tui/focus-manager.js +5 -0
  155. package/dist/tui/highlight.js +30 -0
  156. package/dist/tui/input-router.js +18 -0
  157. package/dist/tui/interrupt.js +99 -0
  158. package/dist/tui/keybindings.js +194 -0
  159. package/dist/tui/keymap-resolver.js +91 -0
  160. package/dist/tui/launch-state.js +148 -0
  161. package/dist/tui/line-diff.js +57 -0
  162. package/dist/tui/live-activity.js +56 -0
  163. package/dist/tui/metrics.js +123 -0
  164. package/dist/tui/onboarding.js +36 -0
  165. package/dist/tui/overlays/agent-tree.js +43 -0
  166. package/dist/tui/overlays/approval-dialog.js +642 -0
  167. package/dist/tui/overlays/automation-center.js +51 -0
  168. package/dist/tui/overlays/checkpoint-picker.js +47 -0
  169. package/dist/tui/overlays/context-inspector.js +36 -0
  170. package/dist/tui/overlays/effort-line.js +110 -0
  171. package/dist/tui/overlays/forge-center.js +46 -0
  172. package/dist/tui/overlays/help-dialog.js +16 -0
  173. package/dist/tui/overlays/history-picker.js +37 -0
  174. package/dist/tui/overlays/hook-center.js +70 -0
  175. package/dist/tui/overlays/library-center.js +55 -0
  176. package/dist/tui/overlays/mcp-center.js +60 -0
  177. package/dist/tui/overlays/memory-center.js +63 -0
  178. package/dist/tui/overlays/model-picker.js +77 -0
  179. package/dist/tui/overlays/notes-center.js +53 -0
  180. package/dist/tui/overlays/overlay-host.js +8 -0
  181. package/dist/tui/overlays/plugin-center.js +76 -0
  182. package/dist/tui/overlays/provider-picker.js +171 -0
  183. package/dist/tui/overlays/queue-editor.js +32 -0
  184. package/dist/tui/overlays/research-center.js +59 -0
  185. package/dist/tui/overlays/scroll-window.js +234 -0
  186. package/dist/tui/overlays/session-picker.js +115 -0
  187. package/dist/tui/overlays/tasks-center.js +83 -0
  188. package/dist/tui/overlays/theme-picker.js +21 -0
  189. package/dist/tui/overlays/transcript-search.js +58 -0
  190. package/dist/tui/overlays/trust-center.js +29 -0
  191. package/dist/tui/overlays/workflow-center.js +46 -0
  192. package/dist/tui/project-file-index.js +214 -0
  193. package/dist/tui/project-references.js +85 -0
  194. package/dist/tui/project-trust-prompt.js +289 -0
  195. package/dist/tui/prompt-history-store.js +116 -0
  196. package/dist/tui/queue-store.js +110 -0
  197. package/dist/tui/regions/budget.js +59 -0
  198. package/dist/tui/regions/views.js +96 -0
  199. package/dist/tui/render-coordinator.js +148 -0
  200. package/dist/tui/render-scheduler.js +4 -0
  201. package/dist/tui/run.js +69 -0
  202. package/dist/tui/selection-list.js +29 -0
  203. package/dist/tui/session-controller.js +791 -0
  204. package/dist/tui/session-export.js +54 -0
  205. package/dist/tui/setup-wizard.js +46 -0
  206. package/dist/tui/shell-input.js +35 -0
  207. package/dist/tui/shell-layout.js +48 -0
  208. package/dist/tui/shell-model.js +98 -0
  209. package/dist/tui/slash-commands.js +82 -0
  210. package/dist/tui/state.js +151 -0
  211. package/dist/tui/status-bar.js +125 -0
  212. package/dist/tui/status-view.js +40 -0
  213. package/dist/tui/terminal-capabilities.js +9 -0
  214. package/dist/tui/terminal-session.js +11 -0
  215. package/dist/tui/text-width.js +66 -0
  216. package/dist/tui/theme-catalog.js +27 -0
  217. package/dist/tui/theme-store.js +23 -0
  218. package/dist/tui/theme.js +23 -0
  219. package/dist/tui/tool-display.js +135 -0
  220. package/dist/tui/tool-facts.js +1 -0
  221. package/dist/tui/tools/bash-renderer.js +32 -0
  222. package/dist/tui/tools/change.js +61 -0
  223. package/dist/tui/tools/edit-renderer.js +17 -0
  224. package/dist/tui/tools/generic-renderer.js +13 -0
  225. package/dist/tui/tools/list-renderer.js +14 -0
  226. package/dist/tui/tools/read-renderer.js +13 -0
  227. package/dist/tui/tools/registry.js +20 -0
  228. package/dist/tui/tools/row-format.js +187 -0
  229. package/dist/tui/tools/search-renderer.js +38 -0
  230. package/dist/tui/tools/shared.js +97 -0
  231. package/dist/tui/tools/write-renderer.js +15 -0
  232. package/dist/tui/transcript-model.js +441 -0
  233. package/dist/tui/ui-preferences.js +79 -0
  234. package/dist/tui/usage-view.js +77 -0
  235. package/dist/tui/vim-mode.js +99 -0
  236. package/dist/update/check.js +15 -0
  237. package/dist/update/npm.js +51 -0
  238. package/dist/update/run.js +129 -0
  239. package/dist/version.js +2 -0
  240. package/dist/workspace/checkpoint-store.js +210 -0
  241. package/dist/workspace/checkpoint.js +413 -0
  242. package/dist/workspace/restore.js +232 -0
  243. package/package.json +64 -5
  244. package/vendor/context-engine/package.json +11 -0
  245. package/vendor/context-engine/src/compaction-planner.mjs +57 -0
  246. package/vendor/context-engine/src/contracts.mjs +48 -0
  247. package/vendor/context-engine/src/engine.mjs +445 -0
  248. package/vendor/context-engine/src/node/context-export.mjs +164 -0
  249. package/vendor/context-engine/src/node/legacy-import.mjs +92 -0
  250. package/vendor/context-engine/src/node/migrations/001-context.sql +126 -0
  251. package/vendor/context-engine/src/node/sqlite-store.mjs +85 -0
  252. package/vendor/context-engine/src/node/sqlite-worker.mjs +559 -0
  253. package/vendor/context-engine/src/profiles.mjs +10 -0
  254. package/vendor/context-engine/src/retrieval.mjs +104 -0
  255. package/vendor/context-engine/src/summary.mjs +97 -0
  256. package/vendor/context-engine/src/usage.mjs +34 -0
  257. package/vendor/harness-ui/package.json +38 -0
  258. package/vendor/harness-ui/src/acp-agent.mjs +350 -0
  259. package/vendor/harness-ui/src/agent-service.mjs +2188 -0
  260. package/vendor/harness-ui/src/agui-events.mjs +452 -0
  261. package/vendor/harness-ui/src/ambiente-solo-server.mjs +121 -0
  262. package/vendor/harness-ui/src/artifact-store.mjs +39 -0
  263. package/vendor/harness-ui/src/assistenza.mjs +123 -0
  264. package/vendor/harness-ui/src/automation-scheduler.mjs +69 -0
  265. package/vendor/harness-ui/src/automation-store.mjs +145 -0
  266. package/vendor/harness-ui/src/browser-annota.mjs +639 -0
  267. package/vendor/harness-ui/src/browser-frame.mjs +211 -0
  268. package/vendor/harness-ui/src/browser-proxy-universale.mjs +519 -0
  269. package/vendor/harness-ui/src/browser-proxy.mjs +87 -0
  270. package/vendor/harness-ui/src/browser-sessione-viva.mjs +329 -0
  271. package/vendor/harness-ui/src/browser-stream.mjs +445 -0
  272. package/vendor/harness-ui/src/browser-vivo.mjs +694 -0
  273. package/vendor/harness-ui/src/chat-image-attachments.mjs +72 -0
  274. package/vendor/harness-ui/src/config.mjs +697 -0
  275. package/vendor/harness-ui/src/contesto-del-progetto.mjs +385 -0
  276. package/vendor/harness-ui/src/context-asset-adapter.mjs +72 -0
  277. package/vendor/harness-ui/src/context-desktop-service.mjs +253 -0
  278. package/vendor/harness-ui/src/context-embedding-runtime.mjs +252 -0
  279. package/vendor/harness-ui/src/context-inference-scheduler.mjs +81 -0
  280. package/vendor/harness-ui/src/context-native-compaction.mjs +75 -0
  281. package/vendor/harness-ui/src/context-provider-adapter.mjs +141 -0
  282. package/vendor/harness-ui/src/context-runtime.mjs +118 -0
  283. package/vendor/harness-ui/src/context-token-counters.mjs +184 -0
  284. package/vendor/harness-ui/src/context-tool-catalog.mjs +86 -0
  285. package/vendor/harness-ui/src/context-tool-output.mjs +72 -0
  286. package/vendor/harness-ui/src/costo-elenco.mjs +252 -0
  287. package/vendor/harness-ui/src/custom-task.mjs +171 -0
  288. package/vendor/harness-ui/src/doctor.mjs +142 -0
  289. package/vendor/harness-ui/src/document-filename.mjs +97 -0
  290. package/vendor/harness-ui/src/document-generator.mjs +493 -0
  291. package/vendor/harness-ui/src/document-report.mjs +331 -0
  292. package/vendor/harness-ui/src/duckduckgo-search.mjs +155 -0
  293. package/vendor/harness-ui/src/elenco-profondo.mjs +337 -0
  294. package/vendor/harness-ui/src/favicon-proxy.mjs +113 -0
  295. package/vendor/harness-ui/src/forge-contract.mjs +221 -0
  296. package/vendor/harness-ui/src/frequent-dirs.mjs +134 -0
  297. package/vendor/harness-ui/src/generated-image-store.mjs +147 -0
  298. package/vendor/harness-ui/src/generation-idle.mjs +332 -0
  299. package/vendor/harness-ui/src/gguf-header.mjs +207 -0
  300. package/vendor/harness-ui/src/git-service.mjs +626 -0
  301. package/vendor/harness-ui/src/gitignore-elenco.mjs +604 -0
  302. package/vendor/harness-ui/src/harness-receipt-keypair.mjs +207 -0
  303. package/vendor/harness-ui/src/hf-direct-transfer.mjs +170 -0
  304. package/vendor/harness-ui/src/hf-hub-client.mjs +106 -0
  305. package/vendor/harness-ui/src/hf-image-proxy.mjs +105 -0
  306. package/vendor/harness-ui/src/hf-model-transfer.mjs +245 -0
  307. package/vendor/harness-ui/src/hook-registry.mjs +186 -0
  308. package/vendor/harness-ui/src/http-app.mjs +6259 -0
  309. package/vendor/harness-ui/src/http-lifecycle.mjs +132 -0
  310. package/vendor/harness-ui/src/id-archivio.mjs +27 -0
  311. package/vendor/harness-ui/src/image-generator.mjs +143 -0
  312. package/vendor/harness-ui/src/istruzioni-di-progetto.mjs +234 -0
  313. package/vendor/harness-ui/src/kernel/dist/kernelPerIlBanco.js +518 -0
  314. package/vendor/harness-ui/src/kernel/talosHarness.mjs +10437 -0
  315. package/vendor/harness-ui/src/library-policy-store.mjs +175 -0
  316. package/vendor/harness-ui/src/library-store.mjs +652 -0
  317. package/vendor/harness-ui/src/llama-server-supervisor.mjs +629 -0
  318. package/vendor/harness-ui/src/local-model-store.mjs +339 -0
  319. package/vendor/harness-ui/src/local-runtime-contract.mjs +66 -0
  320. package/vendor/harness-ui/src/local-runtime-events.mjs +44 -0
  321. package/vendor/harness-ui/src/local-runtime-llama-server.mjs +244 -0
  322. package/vendor/harness-ui/src/local-runtime-probe.mjs +401 -0
  323. package/vendor/harness-ui/src/machine-capacity.mjs +66 -0
  324. package/vendor/harness-ui/src/mappa-cartelle.mjs +491 -0
  325. package/vendor/harness-ui/src/mcp-client.mjs +98 -0
  326. package/vendor/harness-ui/src/mcp-registry.mjs +157 -0
  327. package/vendor/harness-ui/src/mcp-session.mjs +177 -0
  328. package/vendor/harness-ui/src/memory-store.mjs +227 -0
  329. package/vendor/harness-ui/src/model-catalog-models-dev.mjs +276 -0
  330. package/vendor/harness-ui/src/model-catalog.mjs +129 -0
  331. package/vendor/harness-ui/src/model-destination.mjs +189 -0
  332. package/vendor/harness-ui/src/modifica-ancorata.mjs +177 -0
  333. package/vendor/harness-ui/src/native-provider-adapter.mjs +205 -0
  334. package/vendor/harness-ui/src/notes-store.mjs +250 -0
  335. package/vendor/harness-ui/src/openai-compatible-runtime.mjs +428 -0
  336. package/vendor/harness-ui/src/openrouter-oauth.mjs +339 -0
  337. package/vendor/harness-ui/src/path-policy.mjs +442 -0
  338. package/vendor/harness-ui/src/plugin-registry.mjs +780 -0
  339. package/vendor/harness-ui/src/plugin-session.mjs +180 -0
  340. package/vendor/harness-ui/src/process-policy.mjs +345 -0
  341. package/vendor/harness-ui/src/prompt-enhancer-provider.mjs +94 -0
  342. package/vendor/harness-ui/src/provider-auth-cloud.mjs +95 -0
  343. package/vendor/harness-ui/src/provider-credential-store.mjs +541 -0
  344. package/vendor/harness-ui/src/provider-probe.mjs +582 -0
  345. package/vendor/harness-ui/src/provider-registry.mjs +1633 -0
  346. package/vendor/harness-ui/src/pty-terminal.mjs +312 -0
  347. package/vendor/harness-ui/src/public-problem.mjs +109 -0
  348. package/vendor/harness-ui/src/research/card.mjs +235 -0
  349. package/vendor/harness-ui/src/research/citations.mjs +142 -0
  350. package/vendor/harness-ui/src/research/collector.mjs +275 -0
  351. package/vendor/harness-ui/src/research/deposito-a-pezzi.mjs +139 -0
  352. package/vendor/harness-ui/src/research/dossier.mjs +114 -0
  353. package/vendor/harness-ui/src/research/esportazioni.mjs +560 -0
  354. package/vendor/harness-ui/src/research/fetch-cache.mjs +465 -0
  355. package/vendor/harness-ui/src/research/fidelity.mjs +122 -0
  356. package/vendor/harness-ui/src/research/independence.mjs +159 -0
  357. package/vendor/harness-ui/src/research/ledger.mjs +166 -0
  358. package/vendor/harness-ui/src/research/markdown-server.mjs +565 -0
  359. package/vendor/harness-ui/src/research/narration.mjs +181 -0
  360. package/vendor/harness-ui/src/research/open-cards.mjs +131 -0
  361. package/vendor/harness-ui/src/research/opposing.mjs +305 -0
  362. package/vendor/harness-ui/src/research/outline.mjs +111 -0
  363. package/vendor/harness-ui/src/research/page-budget.mjs +209 -0
  364. package/vendor/harness-ui/src/research/pdf.mjs +291 -0
  365. package/vendor/harness-ui/src/research/plan.mjs +301 -0
  366. package/vendor/harness-ui/src/research/raccolta-viva.mjs +452 -0
  367. package/vendor/harness-ui/src/research/recheck-document.mjs +69 -0
  368. package/vendor/harness-ui/src/research/recheck-history.mjs +192 -0
  369. package/vendor/harness-ui/src/research/recheck.mjs +194 -0
  370. package/vendor/harness-ui/src/research/report.mjs +203 -0
  371. package/vendor/harness-ui/src/research/run.mjs +527 -0
  372. package/vendor/harness-ui/src/research/synthesis.mjs +318 -0
  373. package/vendor/harness-ui/src/research/verification.mjs +572 -0
  374. package/vendor/harness-ui/src/research-orchestrator.mjs +2679 -0
  375. package/vendor/harness-ui/src/research-store.mjs +1133 -0
  376. package/vendor/harness-ui/src/runtime-build-manifest.mjs +26 -0
  377. package/vendor/harness-ui/src/runtime-contract.mjs +59 -0
  378. package/vendor/harness-ui/src/runtime-owner-adapter.mjs +1348 -0
  379. package/vendor/harness-ui/src/runtime-owner-contract.mjs +32 -0
  380. package/vendor/harness-ui/src/scheda-di-lavoro.mjs +249 -0
  381. package/vendor/harness-ui/src/search-source-store.mjs +172 -0
  382. package/vendor/harness-ui/src/session-registry.mjs +6095 -0
  383. package/vendor/harness-ui/src/session-store.mjs +220 -0
  384. package/vendor/harness-ui/src/sessione-pronta.mjs +73 -0
  385. package/vendor/harness-ui/src/setup-stato.mjs +31 -0
  386. package/vendor/harness-ui/src/sezioni-istruzioni.mjs +204 -0
  387. package/vendor/harness-ui/src/skill-registry.mjs +120 -0
  388. package/vendor/harness-ui/src/sse-replay-coalescente.mjs +0 -0
  389. package/vendor/harness-ui/src/static-files.mjs +96 -0
  390. package/vendor/harness-ui/src/stream-partition.mjs +123 -0
  391. package/vendor/harness-ui/src/subagent-orchestrator.mjs +453 -0
  392. package/vendor/harness-ui/src/task-catalog.mjs +65 -0
  393. package/vendor/harness-ui/src/tasks-store.mjs +220 -0
  394. package/vendor/harness-ui/src/terminal-registry.mjs +312 -0
  395. package/vendor/harness-ui/src/terminal-ws.mjs +170 -0
  396. package/vendor/harness-ui/src/tool-forge-store.mjs +299 -0
  397. package/vendor/harness-ui/src/tool-schema-normalize.mjs +100 -0
  398. package/vendor/harness-ui/src/usage-cache.mjs +315 -0
  399. package/vendor/harness-ui/src/workspace-browser.mjs +213 -0
  400. package/vendor/harness-ui/src/workspace-context.mjs +124 -0
  401. package/vendor/harness-ui/src/workspace-disk.mjs +62 -0
  402. package/vendor/harness-ui/src/workspace-files.mjs +589 -0
  403. package/vendor/harness-ui/src/workspace-info.mjs +189 -0
  404. package/vendor/harness-ui/src/workspace-launch-store.mjs +150 -0
  405. package/vendor/harness-ui/src/workspace-tree.mjs +67 -0
  406. package/vendor/harness-ui/src/workspace-watcher.mjs +161 -0
  407. package/vendor/manifest.json +170 -0
@@ -0,0 +1,157 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { mkdir, readdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { findTalosRepoRoot, importTalosModule } from "../runtime/repo.js";
5
+ const ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,120}$/u;
6
+ const KINDS = new Set(['session', 'task', 'research']);
7
+ function fail(code, message = code) { throw Object.assign(new Error(message), { code }); }
8
+ function validId(value, code) { if (!ID.test(value) || value.includes('..'))
9
+ fail(code); return value; }
10
+ function targetKind(value) { if (!KINDS.has(value))
11
+ fail('NOTE_LINK_KIND_INVALID'); return value; }
12
+ function textOrNull(value) { return typeof value === 'string' ? value : null; }
13
+ function requireText(value, field) { if (typeof value !== 'string' || !value.length)
14
+ throw new TypeError('malformed persisted note row: ' + field); return value; }
15
+ function relationKey(record) { return createHash('sha256').update(record.noteId + '\0' + record.target.kind + '\0' + record.target.id).digest('hex'); }
16
+ function relationRecord(value) {
17
+ if (!value || typeof value !== 'object' || value.schema !== 'talos.cli.note-relation.v1')
18
+ throw new TypeError('malformed note relation');
19
+ const noteId = validId(String(value.noteId ?? ''), 'NOTE_RELATION_INVALID');
20
+ const kind = targetKind(String(value.target?.kind ?? ''));
21
+ const id = validId(String(value.target?.id ?? ''), 'NOTE_RELATION_INVALID');
22
+ const createdAt = requireText(value.createdAt, 'createdAt');
23
+ return { schema: 'talos.cli.note-relation.v1', noteId, target: { kind, id }, createdAt };
24
+ }
25
+ function relationSort(a, b) { return a.target.kind.localeCompare(b.target.kind) || a.target.id.localeCompare(b.target.id) || a.createdAt.localeCompare(b.createdAt); }
26
+ function safeComposer(value) { return value.replace(/[\x00-\x09\x0b\x0c\x0e-\x1f\x7f-\x9f\u2028\u2029\p{Bidi_Control}\p{Default_Ignorable_Code_Point}]/gu, ch => { const cp = ch.codePointAt(0) ?? 0; return cp <= 0xffff ? '\\u' + cp.toString(16).padStart(4, '0') : '\\u{' + cp.toString(16) + '}'; }); }
27
+ export function createNotesFacade(input, deps = {}) {
28
+ const notesRoot = join(input.paths.dataRoot, 'notes');
29
+ const tasksRoot = join(input.paths.dataRoot, 'tasks');
30
+ const relationRoot = join(input.paths.dataRoot, 'note-relations');
31
+ const repoRoot = () => input.repoRoot ?? (input.projectRoot ? findTalosRepoRoot(input.projectRoot) : fail('NOTES_REPO_ROOT_REQUIRED'));
32
+ let notesPromise = null, tasksPromise = null, sessionsPromise = null;
33
+ const notesStore = () => notesPromise ??= (deps.loadNotesStore ? deps.loadNotesStore() : importTalosModule(repoRoot(), 'notes-store.mjs'));
34
+ const taskStore = () => tasksPromise ??= (deps.loadTaskStore ? deps.loadTaskStore() : importTalosModule(repoRoot(), 'tasks-store.mjs'));
35
+ const sessionStore = () => sessionsPromise ??= (deps.loadSessionStore ? deps.loadSessionStore() : importTalosModule(repoRoot(), 'session-store.mjs'));
36
+ const defaultListRelations = async () => {
37
+ let names;
38
+ try {
39
+ names = await readdir(relationRoot);
40
+ }
41
+ catch (error) {
42
+ if (error?.code === 'ENOENT')
43
+ return [];
44
+ throw error;
45
+ }
46
+ const records = [];
47
+ for (const name of names.sort()) {
48
+ if (!name.endsWith('.json'))
49
+ continue;
50
+ records.push(relationRecord(JSON.parse(await readFile(join(relationRoot, name), 'utf8'))));
51
+ }
52
+ return records.sort(relationSort);
53
+ };
54
+ const defaultWriteRelation = async (record) => {
55
+ await mkdir(relationRoot, { recursive: true, mode: 0o700 });
56
+ const key = relationKey(record), final = join(relationRoot, key + '.json'), tmp = join(relationRoot, '.' + key + '.' + randomUUID() + '.tmp');
57
+ await writeFile(tmp, JSON.stringify(record, null, 2) + '\n', { encoding: 'utf8', mode: 0o600, flag: 'wx' });
58
+ try {
59
+ await rename(tmp, final);
60
+ }
61
+ catch (error) {
62
+ await rm(tmp, { force: true });
63
+ throw error;
64
+ }
65
+ };
66
+ const defaultDeleteRelation = async (record) => { await rm(join(relationRoot, relationKey(record) + '.json'), { force: true }); };
67
+ const listRelations = async () => { const raw = await (deps.listRelations ? deps.listRelations() : defaultListRelations()); if (!Array.isArray(raw))
68
+ throw new TypeError('malformed note relation store'); return raw.map(relationRecord).sort(relationSort); };
69
+ const writeRelation = deps.writeRelation ?? defaultWriteRelation;
70
+ const deleteRelation = deps.deleteRelation ?? defaultDeleteRelation;
71
+ const now = deps.now ?? (() => new Date());
72
+ async function targetState(target, required = false) {
73
+ if (target.kind === 'task') {
74
+ const row = await (await taskStore()).leggiAttivita({ cartella: tasksRoot, id: target.id });
75
+ if (row)
76
+ return { state: 'available', label: textOrNull(row.titolo) };
77
+ }
78
+ else {
79
+ const records = await (await sessionStore()).leggiRegistro({ cartellaStore: input.paths.sessionsRoot, sessionId: target.id });
80
+ const header = Array.isArray(records) ? records.find((row) => row?.tipo === 'intestazione') : null;
81
+ if (header) {
82
+ if (target.kind === 'session')
83
+ return { state: 'available', label: null };
84
+ if (header.taskId === 'ricerca' && header.task?.ricercaId === target.id)
85
+ return { state: 'available', label: textOrNull(header.task?.ricercaDomanda) };
86
+ }
87
+ }
88
+ if (required)
89
+ fail('NOTE_LINK_TARGET_NOT_FOUND');
90
+ return { state: 'dangling', label: null };
91
+ }
92
+ function publicNote(raw, store) {
93
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
94
+ throw new TypeError('malformed persisted note row: object');
95
+ const shaped = typeof store.formaPubblicaNota === 'function' ? store.formaPubblicaNota(raw) : raw;
96
+ if (!shaped || typeof shaped !== 'object' || Array.isArray(shaped))
97
+ throw new TypeError('malformed persisted note row: public shape');
98
+ const id = validId(requireText(shaped.id, 'id'), 'NOTE_ID_INVALID');
99
+ const title = requireText(shaped.titolo, 'titolo'), content = requireText(shaped.contenuto, 'contenuto');
100
+ const format = shaped.formato === 'markdown' ? 'markdown' : shaped.formato === 'testo' ? 'testo' : fail('NOTE_FORMAT_INVALID');
101
+ const writer = shaped.origine === 'persona' ? 'persona' : 'modello';
102
+ const formatEvidence = (raw.formato === 'markdown' || raw.formato === 'testo') ? 'persisted' : 'derived-content';
103
+ const writerEvidence = (raw.origine === 'persona' || raw.origine === 'modello') ? 'persisted' : 'derived-legacy-default';
104
+ return { id, title, content, format, formatEvidence, writer, writerEvidence, createdAt: textOrNull(shaped.creataAlle), updatedAt: textOrNull(shaped.aggiornataAlle) };
105
+ }
106
+ async function projectNote(raw, store, relations) {
107
+ const base = publicNote(raw, store), views = [];
108
+ for (const record of relations.filter(row => row.noteId === base.id))
109
+ views.push({ ...record, ...await targetState(record.target, false) });
110
+ return { ...base, relations: views.sort(relationSort) };
111
+ }
112
+ async function exactNote(noteId) { const wanted = validId(noteId, 'NOTE_ID_INVALID'), store = await notesStore(), raw = await store.leggiNota({ cartella: notesRoot, id: wanted }); if (!raw)
113
+ fail('NOTE_NOT_FOUND'); return { wanted, store, raw }; }
114
+ function invalid(error) { return { state: 'invalid', rows: [], error: { code: 'NOTES_STORE_INVALID', message: error instanceof Error ? error.message : String(error) }, legacyRows: [] }; }
115
+ const list = async () => {
116
+ try {
117
+ const store = await notesStore(), raw = await store.elencaNote({ cartella: notesRoot });
118
+ if (!Array.isArray(raw))
119
+ throw new TypeError('malformed persisted note list');
120
+ const relations = await listRelations(), rows = [];
121
+ for (const item of raw)
122
+ rows.push(await projectNote(item, store, relations));
123
+ return { state: 'ready', rows, error: null, legacyRows: raw };
124
+ }
125
+ catch (error) {
126
+ return invalid(error);
127
+ }
128
+ };
129
+ const read = async (noteId) => { const store = await notesStore(), wanted = validId(noteId, 'NOTE_ID_INVALID'), raw = await store.leggiNota({ cartella: notesRoot, id: wanted }); if (!raw)
130
+ return null; return projectNote(raw, store, await listRelations()); };
131
+ const add = async (value) => { const store = await notesStore(), legacy = await store.creaNota({ cartella: notesRoot, title: value.title, content: value.content, origine: 'persona' }); return { legacy }; };
132
+ const update = async (noteId, value) => { const store = await notesStore(), wanted = validId(noteId, 'NOTE_ID_INVALID'), legacy = await store.aggiornaNota({ cartella: notesRoot, id: wanted, ...(value.title !== undefined ? { title: value.title } : {}), ...(value.content !== undefined ? { content: value.content } : {}) }); return { legacy }; };
133
+ const deleteNote = async (noteId) => { const wanted = validId(noteId, 'NOTE_ID_INVALID'), store = await notesStore(); await store.eliminaNota({ cartella: notesRoot, id: wanted }); return { ok: true, id: wanted, legacy: { ok: true, id: wanted } }; };
134
+ const link = async (noteId, kindValue, targetId) => {
135
+ const source = await exactNote(noteId), target = { kind: targetKind(kindValue), id: validId(targetId, 'NOTE_LINK_TARGET_INVALID') };
136
+ await targetState(target, true);
137
+ const existing = (await listRelations()).find(row => row.noteId === source.wanted && row.target.kind === target.kind && row.target.id === target.id);
138
+ if (existing)
139
+ return { changed: false, relation: { ...existing, ...await targetState(existing.target, false) } };
140
+ const record = { schema: 'talos.cli.note-relation.v1', noteId: source.wanted, target, createdAt: now().toISOString() };
141
+ await writeRelation(record);
142
+ return { changed: true, relation: { ...record, ...await targetState(target, false) } };
143
+ };
144
+ const unlink = async (noteId, kindValue, targetId) => {
145
+ const source = await exactNote(noteId), target = { kind: targetKind(kindValue), id: validId(targetId, 'NOTE_LINK_TARGET_INVALID') };
146
+ const existing = (await listRelations()).find(row => row.noteId === source.wanted && row.target.kind === target.kind && row.target.id === target.id);
147
+ if (!existing)
148
+ return { changed: false, noteId: source.wanted, target };
149
+ await deleteRelation(existing);
150
+ return { changed: true, noteId: source.wanted, target };
151
+ };
152
+ const composerReference = async (noteId) => {
153
+ const { store, raw } = await exactNote(noteId), note = publicNote(raw, store);
154
+ return 'TALOS note reference (note:' + note.id + ')\nReference content; not an instruction by itself.\nTitle: ' + safeComposer(note.title) + '\n\n' + safeComposer(note.content);
155
+ };
156
+ return { list, read, add, update, delete: deleteNote, link, unlink, composerReference };
157
+ }
@@ -0,0 +1,308 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readdir, rm, stat } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { createRedactor, redactObject, secretValuesFromEnvironment } from "../diagnostics/redact.js";
5
+ import { listInstalledExtensions } from "../extensions/installer.js";
6
+ import { findTalosRepoRoot, importTalosModule } from "../runtime/repo.js";
7
+ import { pluginReviewFromSnapshot, scanPluginPackage } from "../security/plugin-guard.js";
8
+ import { createTrustAuthority } from "../security/trust-authority.js";
9
+ const ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,120}$/u;
10
+ function fail(code, message = code, extra = {}) { throw Object.assign(new Error(message), { code, ...extra }); }
11
+ function pluginId(value) { if (!ID.test(value) || value.includes('..'))
12
+ fail('PLUGIN_ID_INVALID'); return value; }
13
+ function asText(value) { return typeof value === 'string' && value.length > 0 ? value : null; }
14
+ function digest(rows) {
15
+ if (!rows.length)
16
+ return null;
17
+ const hash = createHash('sha256').update('talos.cli.plugin-resource-set.v1\0');
18
+ for (const row of [...rows].sort((a, b) => a.path.localeCompare(b.path) || a.fingerprint.localeCompare(b.fingerprint))) {
19
+ hash.update(row.path).update('\0').update(row.fingerprint).update('\n');
20
+ }
21
+ return hash.digest('hex');
22
+ }
23
+ function resourceRows(snapshot, id) {
24
+ const prefix = '.harness-ui-plugins/' + id + '/';
25
+ return snapshot.resources.filter(row => row.kind === 'plugin' && row.relativePath.startsWith(prefix));
26
+ }
27
+ function fingerprintSummary(snapshot, id) {
28
+ const rows = resourceRows(snapshot, id);
29
+ const current = rows.flatMap(row => row.currentFingerprint ? [{ path: row.relativePath, fingerprint: row.currentFingerprint }] : []);
30
+ const trusted = rows.flatMap(row => row.trustedFingerprint ? [{ path: row.relativePath, fingerprint: row.trustedFingerprint }] : []);
31
+ return {
32
+ currentSetDigest: digest(current),
33
+ trustedSetDigest: digest(trusted),
34
+ changedPaths: rows.filter(row => row.state === 'changed').map(row => row.relativePath).sort(),
35
+ addedPaths: rows.filter(row => row.state === 'added').map(row => row.relativePath).sort(),
36
+ removedPaths: rows.filter(row => row.state === 'removed').map(row => row.relativePath).sort()
37
+ };
38
+ }
39
+ function quarantineView(value) {
40
+ return value ? {
41
+ active: true, reason: value.reason ?? null, quarantinedAt: value.quarantinedAt ?? null, reviewedFingerprint: value.reviewedFingerprint ?? null
42
+ } : { active: false, reason: null, quarantinedAt: null, reviewedFingerprint: null };
43
+ }
44
+ function validInstalled(row, id) {
45
+ return Boolean(row && typeof row === 'object' && row.id === id && typeof row.name === 'string' && typeof row.version === 'string'
46
+ && typeof row.source === 'string' && row.components && typeof row.components === 'object'
47
+ && row.components.plugin?.id === id);
48
+ }
49
+ export function createPluginFacade(input, deps = {}) {
50
+ const authority = deps.authority ?? createTrustAuthority({ projectRoot: input.projectRoot, trustRoot: input.paths.trust.projects });
51
+ const repoRoot = () => input.repoRoot ?? findTalosRepoRoot(input.projectRoot);
52
+ const secrets = secretValuesFromEnvironment(input.env ?? process.env);
53
+ const redactor = createRedactor(secrets);
54
+ let registryPromise = null;
55
+ const registry = () => registryPromise ??= importTalosModule(repoRoot(), 'plugin-registry.mjs');
56
+ const loadPlugins = deps.loadPlugins ?? (async () => {
57
+ const loaded = await (await registry()).caricaPlugin({ cartella: input.projectRoot });
58
+ return { plugin: Array.isArray(loaded?.plugin) ? loaded.plugin : [], falliti: Array.isArray(loaded?.falliti) ? loaded.falliti : [] };
59
+ });
60
+ const listPackages = deps.listInstalledPackages ?? (() => listInstalledExtensions(input.projectRoot));
61
+ const pathExists = deps.pathExists ?? (async (path) => {
62
+ try {
63
+ await stat(path);
64
+ return true;
65
+ }
66
+ catch (error) {
67
+ if (error.code === 'ENOENT')
68
+ return false;
69
+ throw error;
70
+ }
71
+ });
72
+ const listManagedStateIds = deps.listManagedStateIds ?? (async () => {
73
+ const root = join(input.projectRoot, '.talos-cli', 'extensions');
74
+ let entries;
75
+ try {
76
+ entries = await readdir(root, { withFileTypes: true });
77
+ }
78
+ catch (error) {
79
+ if (error.code === 'ENOENT')
80
+ return [];
81
+ throw error;
82
+ }
83
+ const ids = [];
84
+ for (const entry of entries) {
85
+ if (!entry.isDirectory())
86
+ continue;
87
+ let id;
88
+ try {
89
+ id = pluginId(entry.name);
90
+ }
91
+ catch {
92
+ continue;
93
+ }
94
+ if (await pathExists(join(input.projectRoot, '.harness-ui-plugins', id)))
95
+ ids.push(id);
96
+ }
97
+ return ids.sort();
98
+ });
99
+ async function compatibilityRoot() { return (await authority.compatibilityRoots()).plugins; }
100
+ async function defaultUntrustCompatibility(id) { await rm(join(await compatibilityRoot(), pluginId(id) + '.json'), { force: true }); }
101
+ async function defaultTrustCompatibility(plugin) {
102
+ if (!plugin.hash)
103
+ fail('PLUGIN_COMPATIBILITY_HASH_MISSING');
104
+ const root = await compatibilityRoot();
105
+ await rm(join(root, pluginId(plugin.id) + '.json'), { force: true });
106
+ await (await registry()).fidaPlugin({ cartellaTrust: root, pluginId: plugin.id, hash: plugin.hash });
107
+ }
108
+ const untrustCompatibility = deps.untrustCompatibility ?? defaultUntrustCompatibility;
109
+ const trustCompatibility = deps.trustCompatibility ?? defaultTrustCompatibility;
110
+ const scanPlugin = deps.scanPlugin ?? ((plugin, review) => scanPluginPackage({ projectRoot: input.projectRoot, plugin: { id: plugin.id, tools: plugin.tools ?? [], hooks: plugin.hooks ?? [] }, expectedReview: review }));
111
+ async function loadedState() {
112
+ const loaded = await loadPlugins();
113
+ const plugin = Array.isArray(loaded?.plugin) ? loaded.plugin.map(row => ({ ...row, id: pluginId(String(row.id ?? '')) })) : [];
114
+ const falliti = Array.isArray(loaded?.falliti) ? loaded.falliti.flatMap(row => {
115
+ const id = asText(row?.pluginId);
116
+ if (!id)
117
+ return [];
118
+ try {
119
+ return [{ ...row, pluginId: pluginId(id) }];
120
+ }
121
+ catch {
122
+ return [];
123
+ }
124
+ }) : [];
125
+ return { plugin, falliti };
126
+ }
127
+ async function packageRecords() {
128
+ try {
129
+ const rows = await listPackages();
130
+ return Array.isArray(rows) ? rows : [];
131
+ }
132
+ catch (error) {
133
+ if (error instanceof TypeError)
134
+ return [];
135
+ throw error;
136
+ }
137
+ }
138
+ async function provenance(id, packages) {
139
+ const stateDir = join(input.projectRoot, '.talos-cli', 'extensions', id);
140
+ const packageCopyAbsolute = join(stateDir, 'package');
141
+ const packageCopy = '.talos-cli/extensions/' + id + '/package';
142
+ const candidate = packages.find(row => row?.id === id) ?? null;
143
+ const [statePresent, copyPresent] = await Promise.all([pathExists(stateDir), pathExists(packageCopyAbsolute)]);
144
+ if (candidate && validInstalled(candidate, id)) {
145
+ const source = redactor.text(candidate.source);
146
+ let sourceAvailable = false;
147
+ try {
148
+ sourceAvailable = await pathExists(candidate.source);
149
+ }
150
+ catch {
151
+ sourceAvailable = false;
152
+ }
153
+ return {
154
+ kind: 'managed-extension',
155
+ extension: { id: candidate.id, name: redactor.text(candidate.name), version: redactor.text(candidate.version) },
156
+ packageCopy, packageCopyPresent: copyPresent,
157
+ recordedSource: source, recordedSourceAvailable: sourceAvailable, recordedSourceAuthority: 'advisory-only'
158
+ };
159
+ }
160
+ if (candidate || statePresent) {
161
+ return {
162
+ kind: 'managed-state-invalid', extension: null, packageCopy, packageCopyPresent: copyPresent,
163
+ recordedSource: null, recordedSourceAvailable: false, recordedSourceAuthority: 'advisory-only'
164
+ };
165
+ }
166
+ return {
167
+ kind: 'unmanaged-project-plugin', extension: null, packageCopy, packageCopyPresent: false,
168
+ recordedSource: null, recordedSourceAvailable: false, recordedSourceAuthority: 'advisory-only'
169
+ };
170
+ }
171
+ async function knownState() {
172
+ const [loaded, snapshot, packages, managedStateIds] = await Promise.all([loadedState(), authority.inspect(), packageRecords(), listManagedStateIds()]);
173
+ const byId = new Map();
174
+ for (const row of loaded.plugin)
175
+ byId.set(row.id, { plugin: row, failure: null });
176
+ for (const failure of loaded.falliti) {
177
+ if (!byId.has(failure.pluginId))
178
+ byId.set(failure.pluginId, { plugin: null, failure });
179
+ }
180
+ for (const row of packages) {
181
+ const id = asText(row?.components?.plugin?.id) ?? asText(row?.id);
182
+ if (id) {
183
+ try {
184
+ const clean = pluginId(id);
185
+ if (!byId.has(clean))
186
+ byId.set(clean, { plugin: null, failure: null });
187
+ }
188
+ catch { }
189
+ }
190
+ }
191
+ for (const raw of managedStateIds) {
192
+ try {
193
+ const id = pluginId(raw);
194
+ if (!byId.has(id))
195
+ byId.set(id, { plugin: null, failure: null });
196
+ }
197
+ catch { }
198
+ }
199
+ for (const resource of snapshot.resources) {
200
+ if (resource.kind !== 'plugin')
201
+ continue;
202
+ const match = /^\.harness-ui-plugins\/([^/]+)\//u.exec(resource.relativePath);
203
+ if (!match)
204
+ continue;
205
+ try {
206
+ const id = pluginId(match[1]);
207
+ if (!byId.has(id))
208
+ byId.set(id, { plugin: null, failure: null });
209
+ }
210
+ catch { }
211
+ }
212
+ return { loaded, snapshot, packages, byId };
213
+ }
214
+ async function view(id, state) {
215
+ const entry = state.byId.get(id) ?? { plugin: null, failure: null };
216
+ const [quarantine, scopeTrusted, prov] = await Promise.all([
217
+ authority.quarantineStatus({ kind: 'plugin', id }),
218
+ authority.verifyScope({ kind: 'plugin', id }),
219
+ provenance(id, state.packages)
220
+ ]);
221
+ let guard = null;
222
+ let guardError = null;
223
+ if (entry.plugin) {
224
+ const review = pluginReviewFromSnapshot(state.snapshot, id);
225
+ try {
226
+ guard = redactObject(await scanPlugin(entry.plugin, review), secrets);
227
+ }
228
+ catch (error) {
229
+ guardError = redactor.text(error instanceof Error ? error.message : String(error));
230
+ }
231
+ }
232
+ const registryState = entry.plugin
233
+ ? { state: 'loaded', code: null, message: null }
234
+ : entry.failure
235
+ ? { state: 'failed', code: asText(entry.failure.codice), message: redactor.text(entry.failure.frase ?? entry.failure.messaggio ?? 'plugin registry refused this package') }
236
+ : { state: 'missing', code: null, message: 'Plugin package is not currently loadable from the runtime registry.' };
237
+ return {
238
+ id,
239
+ name: entry.plugin ? redactor.text(String(entry.plugin.nome ?? id)) : prov.extension?.name ?? null,
240
+ description: entry.plugin ? redactor.text(String(entry.plugin.descrizione ?? '')) : null,
241
+ registry: registryState,
242
+ provenance: prov,
243
+ guard, guardError,
244
+ trust: {
245
+ projectTrusted: state.snapshot.trusted,
246
+ scopeTrusted,
247
+ effectiveTrusted: Boolean(entry.plugin && guard && guard.verdict !== 'dangerous' && scopeTrusted && !quarantine)
248
+ },
249
+ fingerprints: fingerprintSummary(state.snapshot, id),
250
+ quarantine: quarantineView(quarantine)
251
+ };
252
+ }
253
+ async function targetLoaded(id) {
254
+ const clean = pluginId(id);
255
+ const state = await loadedState();
256
+ const plugin = state.plugin.find(row => row.id === clean);
257
+ if (!plugin) {
258
+ const failure = state.falliti.find(row => row.pluginId === clean);
259
+ if (failure)
260
+ fail('PLUGIN_REGISTRY_FAILED', failure.frase ?? failure.messaggio ?? 'PLUGIN_REGISTRY_FAILED', { registryFailure: failure });
261
+ fail('PLUGIN_NOT_FOUND');
262
+ }
263
+ return plugin;
264
+ }
265
+ async function assertKnown(id) {
266
+ const clean = pluginId(id);
267
+ const state = await knownState();
268
+ if (!state.byId.has(clean))
269
+ fail('PLUGIN_NOT_FOUND');
270
+ return clean;
271
+ }
272
+ return {
273
+ async list() {
274
+ const state = await knownState();
275
+ return Promise.all([...state.byId.keys()].sort().map(id => view(id, state)));
276
+ },
277
+ async trust(id) {
278
+ const plugin = await targetLoaded(id);
279
+ const reviewed = await authority.inspect();
280
+ const review = pluginReviewFromSnapshot(reviewed, plugin.id);
281
+ const guard = await scanPlugin(plugin, review);
282
+ if (guard.verdict === 'dangerous')
283
+ fail('PLUGIN_DANGEROUS', 'PLUGIN_DANGEROUS', { guard });
284
+ const result = await authority.trustScope({ kind: 'plugin', id: plugin.id }, { expected: reviewed });
285
+ await trustCompatibility(plugin);
286
+ return { ok: true, id: plugin.id, changed: result.changed, guard, snapshot: result.snapshot };
287
+ },
288
+ async untrust(id) {
289
+ const clean = await assertKnown(id);
290
+ const result = await authority.untrustScope({ kind: 'plugin', id: clean });
291
+ await untrustCompatibility(clean);
292
+ return { ok: true, id: clean, changed: result.changed, snapshot: result.snapshot };
293
+ },
294
+ async quarantine(id, reason = null) {
295
+ const clean = await assertKnown(id);
296
+ const reviewed = await authority.inspect();
297
+ const result = await authority.quarantineScope({ kind: 'plugin', id: clean }, { reason, expected: reviewed });
298
+ await untrustCompatibility(clean);
299
+ return { ok: true, id: clean, changed: result.changed, record: result.record, snapshot: result.snapshot };
300
+ },
301
+ async releaseQuarantine(id) {
302
+ const clean = await assertKnown(id);
303
+ const result = await authority.releaseQuarantine({ kind: 'plugin', id: clean });
304
+ await untrustCompatibility(clean);
305
+ return { ok: true, id: clean, changed: result.changed };
306
+ }
307
+ };
308
+ }
@@ -0,0 +1,110 @@
1
+ import { writeFile as writeFileReal } from 'node:fs/promises';
2
+ import { resolve } from 'node:path';
3
+ import { findTalosRepoRoot, importTalosModule } from "../runtime/repo.js";
4
+ const VERDICTS = new Set(['yes', 'partial', 'no', 'unchecked', 'contested']);
5
+ function fail(code, message = code) { throw Object.assign(new Error(message), { code }); }
6
+ function str(value) { return typeof value === 'string' ? value : null; }
7
+ function verification(value) { return VERDICTS.has(value) ? value : null; }
8
+ function finite(value) { return typeof value === 'number' && Number.isFinite(value) ? value : 0; }
9
+ export function createResearchFacade(input, deps = {}) {
10
+ const repoRoot = () => input.repoRoot ?? findTalosRepoRoot(input.projectRoot);
11
+ let storePromise = null, runPromise = null, reportPromise = null, exportPromise = null;
12
+ const store = () => storePromise ??= (deps.loadStore ? deps.loadStore() : importTalosModule(repoRoot(), 'research-store.mjs'));
13
+ const runModule = () => runPromise ??= (deps.loadRun ? deps.loadRun() : importTalosModule(repoRoot(), 'research/run.mjs'));
14
+ const parseReport = async (document) => { if (deps.parseReport)
15
+ return deps.parseReport(document); reportPromise ??= importTalosModule(repoRoot(), 'research/report.mjs'); return (await reportPromise).talosResearchParseReport(document); };
16
+ const exportResearch = async (value) => { if (deps.exportResearch)
17
+ return deps.exportResearch(value); exportPromise ??= importTalosModule(repoRoot(), 'research/esportazioni.mjs'); return (await exportPromise).costruisciEsportazione(value); };
18
+ const writeExport = deps.writeExportFile ?? (async (path, bytes) => { await writeFileReal(path, bytes); });
19
+ async function replay(id) {
20
+ const s = await store(), journal = await s.leggiGiornale({ cartella: input.projectRoot, id }), mod = await runModule();
21
+ const state = mod.talosResearchReplay(Array.isArray(journal.eventi) ? journal.eventi : []);
22
+ let progress = null, spent = null;
23
+ try {
24
+ const p = mod.talosResearchProgressOf(state);
25
+ if (p && Number.isFinite(p.done) && Number.isFinite(p.total))
26
+ progress = { done: Number(p.done), total: Number(p.total) };
27
+ }
28
+ catch { }
29
+ try {
30
+ spent = mod.talosResearchSpent(state) ?? null;
31
+ }
32
+ catch { }
33
+ return { state, journal, progress, spent };
34
+ }
35
+ function row(meta, phase) {
36
+ if (!meta || typeof meta !== 'object' || Array.isArray(meta) || typeof meta.id !== 'string' || !meta.id)
37
+ throw new TypeError('malformed research metadata');
38
+ return { id: meta.id, question: str(meta.domanda), name: str(meta.nome ?? meta.titolo), status: str(meta.terminata) ?? phase ?? 'unknown', startedAt: str(meta.avviataAlle), finishedAt: str(meta.conclusaAlle) };
39
+ }
40
+ async function raw(id) {
41
+ if (typeof id !== 'string' || !id)
42
+ fail('RESEARCH_ID_INVALID');
43
+ const s = await store(), meta = await s.leggiRicerca({ cartella: input.projectRoot, id });
44
+ if (!meta || meta.id !== id)
45
+ fail('RESEARCH_NOT_FOUND');
46
+ const [journalPlan, report] = await Promise.all([s.leggiPiano({ cartella: input.projectRoot, id }), s.leggiRapporto({ cartella: input.projectRoot, id })]);
47
+ const live = await replay(id);
48
+ return { s, meta, plan: Array.isArray(journalPlan) ? journalPlan : null, report, live };
49
+ }
50
+ const list = async () => {
51
+ try {
52
+ const s = await store(), rowsRaw = await s.elencaRicerche({ cartella: input.projectRoot });
53
+ if (!Array.isArray(rowsRaw))
54
+ throw new TypeError('malformed research list');
55
+ const rows = [];
56
+ for (const meta of rowsRaw) {
57
+ const id = typeof meta?.id === 'string' ? meta.id : '';
58
+ const live = id ? await replay(id) : null;
59
+ rows.push(row(meta, str(live?.state?.status)));
60
+ }
61
+ return { state: 'ready', rows, error: null };
62
+ }
63
+ catch (error) {
64
+ return { state: 'invalid', rows: [], error: { code: 'RESEARCH_STORE_INVALID', message: error instanceof Error ? error.message : String(error) } };
65
+ }
66
+ };
67
+ const read = async (id) => {
68
+ const x = await raw(id), phase = str(x.live.state?.status), base = row(x.meta, phase);
69
+ const parsed = typeof x.report === 'string' ? await parseReport(x.report) : null;
70
+ let sources = null, claims = null, summary = null, standing = null;
71
+ if (parsed && Array.isArray(parsed.sources) && Array.isArray(parsed.claims)) {
72
+ sources = parsed.sources.map((source, index) => ({ number: index + 1, url: str(source?.url) ?? '', title: str(source?.title) ?? '', publishedAt: str(source?.publishedAt), obtained: str(source?.obtained) }));
73
+ claims = parsed.claims.map((claim, index) => {
74
+ const sourceNumber = Number.isSafeInteger(claim?.sourceIndex) ? Number(claim.sourceIndex) : 0;
75
+ return { number: index + 1, text: str(claim?.text) ?? '', source: sourceNumber > 0 ? (sources?.[sourceNumber - 1] ?? null) : null, passage: str(claim?.passage) ?? '', quotePresent: typeof claim?.checks?.quotePresent === 'boolean' ? claim.checks.quotePresent : null, verification: verification(claim?.checks?.claimSupported), reason: str(claim?.checks?.supportReason), judge: str(claim?.checks?.judge), judgedAt: str(claim?.checks?.judgedAt), opposing: Array.isArray(claim?.checks?.opposing) ? claim.checks.opposing : null };
76
+ });
77
+ summary = str(parsed.summary);
78
+ const claimRows = claims;
79
+ const count = (v) => claimRows.filter(c => c.verification === v).length;
80
+ standing = { total: claimRows.length, supported: count('yes'), partial: count('partial'), unsupported: count('no'), unchecked: count('unchecked'), contested: count('contested') };
81
+ }
82
+ return { ...base, phase, progress: x.live.progress, journal: { events: Array.isArray(x.live.journal.eventi) ? x.live.journal.eventi.length : 0, skippedRows: finite(x.live.journal.righeSaltate) }, summary, verification: standing, sources, claims, plan: x.plan, steps: Array.isArray(x.live.state?.steps) ? x.live.state.steps : null, spent: x.live.spent, expectedCost: null };
83
+ };
84
+ async function ownerAction(method, ownerSessionId, researchId) {
85
+ if (!ownerSessionId || !researchId)
86
+ fail('RESEARCH_CONTROL_ID_REQUIRED');
87
+ const fn = deps.registry?.[method];
88
+ if (typeof fn !== 'function')
89
+ fail('RESEARCH_CONTROL_UNAVAILABLE');
90
+ const result = await fn.call(deps.registry, ownerSessionId, researchId);
91
+ if (result?.erroreAvvio)
92
+ fail(typeof result.code === 'string' ? result.code : 'RESEARCH_CONTROL_UNAVAILABLE', String(result.erroreAvvio));
93
+ if (result?.ricerca === null)
94
+ fail('RESEARCH_NOT_FOUND');
95
+ if (result?.ok === false)
96
+ fail('RESEARCH_CONFLICT', str(result.motivo) ?? 'Research state does not allow this action.');
97
+ return result;
98
+ }
99
+ const pause = (ownerSessionId, researchId) => ownerAction('pausaRicerca', ownerSessionId, researchId);
100
+ const resume = (ownerSessionId, researchId) => ownerAction('riprendiRicerca', ownerSessionId, researchId);
101
+ const cancel = (ownerSessionId, researchId) => ownerAction('annullaRicerca', ownerSessionId, researchId);
102
+ const exportFile = async (id, format, out, tone) => {
103
+ const x = await raw(id), result = await exportResearch({ ricerca: { ...x.meta, contenutoRapporto: x.report }, formato: format, ...(tone ? { tono: tone } : {}) });
104
+ const path = out ?? resolve(input.projectRoot, String(result.nomeFile));
105
+ const bytes = Buffer.from(result.bytes);
106
+ await writeExport(path, bytes);
107
+ return { id, format, path, nomeFile: String(result.nomeFile), mediaType: String(result.mediaType), bytes: bytes.length };
108
+ };
109
+ return { list, read, pause, resume, cancel, exportFile };
110
+ }