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,174 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { basename, extname } from 'node:path';
3
+ import { readFile as readFileReal, writeFile as writeFileReal } from 'node:fs/promises';
4
+ import { findTalosRepoRoot, importTalosModule } from "../runtime/repo.js";
5
+ import { TEXT_ATTACHMENT_MAX_BYTES, imageMimeFromBytes, validateCliAttachments } from "../runtime/attachments.js";
6
+ const PREVIEW_CHARS = 4_000;
7
+ function fail(code, message = code) { throw Object.assign(new Error(message), { code }); }
8
+ function required(value, field) { if (typeof value !== 'string' || !value.length)
9
+ throw new TypeError('malformed Library entry: ' + field); return value; }
10
+ function optional(value) { return typeof value === 'string' ? value : null; }
11
+ function textMedia(mediaType) { const value = mediaType.toLowerCase(); return value.startsWith('text/') || value === 'application/json' || value.endsWith('+json') || value === 'application/xml' || value.endsWith('+xml') || value === 'application/yaml' || value === 'application/x-yaml' || value === 'application/javascript' || value === 'application/x-javascript'; }
12
+ function mediaFor(file) { const e = extname(file).toLowerCase(); return { '.md': 'text/markdown', '.txt': 'text/plain', '.json': 'application/json', '.xml': 'application/xml', '.yaml': 'application/yaml', '.yml': 'application/yaml', '.pdf': 'application/pdf', '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.webp': 'image/webp', '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', '.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation' }[e] ?? 'application/octet-stream'; }
13
+ function digest(bytes) { return createHash('sha256').update(bytes).digest('hex'); }
14
+ function fatalText(bytes) { let text; try {
15
+ text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
16
+ }
17
+ catch {
18
+ fail('LIBRARY_CONTEXT_UNSUPPORTED', 'Library content is not valid UTF-8 text.');
19
+ } if (text.includes('\0'))
20
+ fail('LIBRARY_CONTEXT_UNSUPPORTED', 'Library content is binary.'); return text; }
21
+ function legacyRow(raw) { if (!raw || typeof raw !== 'object' || Array.isArray(raw))
22
+ return raw; const { cartella, percorso, creatoDa, sessione, ...rest } = raw; return rest; }
23
+ function exactManagedLine(text, token) { return text.split('\n').some(line => line.trim() === token); }
24
+ export function attachLibraryContextToken(text, token) { if (exactManagedLine(text, token))
25
+ return text; return text.length ? text.replace(/\n+$/u, '') + '\n' + token : token; }
26
+ export function detachLibraryContextToken(text, token) { return text.split('\n').filter(line => line.trim() !== token).join('\n'); }
27
+ export function createLibraryFacade(input, deps = {}) {
28
+ const repoRoot = () => input.repoRoot ?? findTalosRepoRoot(input.projectRoot);
29
+ let storePromise = null;
30
+ const store = () => storePromise ??= (deps.loadStore ? deps.loadStore() : importTalosModule(repoRoot(), 'library-store.mjs'));
31
+ const readImport = deps.readImportFile ?? (async (file) => readFileReal(file));
32
+ const writeExport = deps.writeExportFile ?? (async (file, bytes) => { await writeFileReal(file, bytes); });
33
+ function projectRow(raw, mod) {
34
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
35
+ throw new TypeError('malformed Library entry: object');
36
+ const id = required(raw.id, 'id'), name = required(raw.nome, 'nome'), mediaType = required(raw.mediaType, 'mediaType');
37
+ const fileType = raw.fileType === 'image' ? 'image' : raw.fileType === 'document' ? 'document' : (() => { throw new TypeError('malformed Library entry: fileType'); })();
38
+ const origin = raw.origine === 'generated' ? 'generated' : raw.origine === 'uploaded' ? 'uploaded' : (() => { throw new TypeError('malformed Library entry: origine'); })();
39
+ const created = raw.creatoDa;
40
+ if (!created || typeof created !== 'object')
41
+ throw new TypeError('malformed Library entry: creatoDa');
42
+ const creator = created.tipo === 'persona'
43
+ ? { type: 'persona', model: null, provider: null }
44
+ : created.tipo === 'modello'
45
+ ? { type: 'modello', model: optional(created.modello), provider: optional(created.provider) }
46
+ : (() => { throw new TypeError('malformed Library entry: creatoDa.tipo'); })();
47
+ const session = raw.sessione && typeof raw.sessione === 'object' && typeof raw.sessione.id === 'string' && raw.sessione.id
48
+ ? { id: raw.sessione.id, name: optional(raw.sessione.nome) } : null;
49
+ const relative = mod.percorsoContenutoVoce(id);
50
+ const token = relative && typeof relative === 'string' && !/[\0\r\n\s]/u.test(relative) ? '@' + relative : null;
51
+ return { id, name, mediaType, fileType, origin, creator, session, createdAt: optional(raw.creatoIl), updatedAt: optional(raw.aggiornatoIl), context: { token, mode: 'explicit-visible-reference', autoAttach: false, autoSubmit: false, persistence: 'composer-only-until-send' } };
52
+ }
53
+ async function metadata() {
54
+ const mod = await store(), raw = await mod.elencaVoci({ cartella: input.projectRoot, conProvenienza: true });
55
+ if (!Array.isArray(raw))
56
+ throw new TypeError('malformed Library list');
57
+ return { mod, raw, rows: raw.map(row => projectRow(row, mod)) };
58
+ }
59
+ async function exact(id) {
60
+ const all = await metadata(), index = all.rows.findIndex(row => row.id === id);
61
+ if (index < 0)
62
+ fail('LIBRARY_NOT_FOUND');
63
+ return { ...all, row: all.rows[index], raw: all.raw[index] };
64
+ }
65
+ async function bytesFor(id) {
66
+ const mod = await store(), value = await mod.leggiBytesVoce({ cartella: input.projectRoot, id });
67
+ if (!value)
68
+ fail('LIBRARY_NOT_FOUND');
69
+ return { ...value, bytes: Buffer.from(value.bytes) };
70
+ }
71
+ async function scanBytes(source, excludeId) {
72
+ const mod = await store(), rows = await mod.elencaVoci({ cartella: input.projectRoot });
73
+ if (!Array.isArray(rows))
74
+ throw new TypeError('malformed Library list');
75
+ const wanted = digest(source), duplicates = [], unreadable = [];
76
+ for (const row of rows) {
77
+ const id = typeof row?.id === 'string' ? row.id : null;
78
+ if (!id || id === excludeId)
79
+ continue;
80
+ try {
81
+ const value = await mod.leggiBytesVoce({ cartella: input.projectRoot, id });
82
+ if (!value) {
83
+ unreadable.push(id);
84
+ continue;
85
+ }
86
+ if (digest(value.bytes) === wanted)
87
+ duplicates.push(id);
88
+ }
89
+ catch {
90
+ unreadable.push(id);
91
+ }
92
+ }
93
+ duplicates.sort();
94
+ unreadable.sort();
95
+ return { sha256: wanted, duplicateIds: duplicates, unreadableIds: unreadable, state: unreadable.length ? 'partial' : 'complete' };
96
+ }
97
+ const list = async () => {
98
+ try {
99
+ const x = await metadata();
100
+ return { state: 'ready', rows: x.rows, error: null, legacyRows: x.raw.map(legacyRow) };
101
+ }
102
+ catch (error) {
103
+ return { state: 'invalid', rows: [], error: { code: 'LIBRARY_STORE_INVALID', message: error instanceof Error ? error.message : String(error) }, legacyRows: [] };
104
+ }
105
+ };
106
+ const search = async (query) => { const mod = await store(), rows = await mod.elencaVociConTesto({ cartella: input.projectRoot }); const legacy = mod.cercaVoci(rows, { query }); return { legacy }; };
107
+ const read = async (id) => { const mod = await store(), legacy = await mod.leggiVoce({ cartella: input.projectRoot, id }); return { legacy }; };
108
+ const preview = async (id) => {
109
+ const entry = await exact(id), value = await bytesFor(id), size = Number.isFinite(value.dimensione) ? Number(value.dimensione) : value.bytes.length;
110
+ if (entry.row.fileType === 'image' || entry.row.mediaType.startsWith('image/'))
111
+ return { id, name: entry.row.name, mediaType: entry.row.mediaType, size, mode: 'metadata', text: null, truncated: false, reason: 'image' };
112
+ if (!textMedia(entry.row.mediaType))
113
+ return { id, name: entry.row.name, mediaType: entry.row.mediaType, size, mode: 'metadata', text: null, truncated: false, reason: 'unsupported-binary' };
114
+ if (value.bytes.length > TEXT_ATTACHMENT_MAX_BYTES)
115
+ return { id, name: entry.row.name, mediaType: entry.row.mediaType, size, mode: 'metadata', text: null, truncated: false, reason: 'text-too-large' };
116
+ let decoded;
117
+ try {
118
+ decoded = new TextDecoder('utf-8', { fatal: true }).decode(value.bytes);
119
+ }
120
+ catch {
121
+ return { id, name: entry.row.name, mediaType: entry.row.mediaType, size, mode: 'metadata', text: null, truncated: false, reason: 'unsupported-binary' };
122
+ }
123
+ if (decoded.includes('\0'))
124
+ return { id, name: entry.row.name, mediaType: entry.row.mediaType, size, mode: 'metadata', text: null, truncated: false, reason: 'unsupported-binary' };
125
+ return { id, name: entry.row.name, mediaType: entry.row.mediaType, size, mode: 'text', text: decoded.slice(0, PREVIEW_CHARS), truncated: decoded.length > PREVIEW_CHARS, reason: null };
126
+ };
127
+ const duplicates = async (id) => {
128
+ await exact(id);
129
+ let target;
130
+ try {
131
+ target = await bytesFor(id);
132
+ }
133
+ catch {
134
+ return { id, state: 'unavailable', sha256: null, duplicateIds: [], unreadableIds: [id], verifiedUnique: false };
135
+ }
136
+ const scan = await scanBytes(target.bytes, id);
137
+ return { id, state: scan.state, sha256: scan.sha256, duplicateIds: scan.duplicateIds, unreadableIds: scan.unreadableIds, verifiedUnique: scan.state === 'complete' && scan.duplicateIds.length === 0 };
138
+ };
139
+ const importFile = async (file) => {
140
+ const bytes = Buffer.from(await readImport(file)), name = basename(file), mediaType = mediaFor(file), scan = await scanBytes(bytes);
141
+ if (scan.duplicateIds.length) {
142
+ return { id: scan.duplicateIds[0], nome: name, mediaType, duplicateDecision: 'existing-exact', scanState: scan.state, duplicateIds: scan.duplicateIds, unreadableIds: scan.unreadableIds };
143
+ }
144
+ const mod = await store(), id = await mod.salvaVoce({ cartella: input.projectRoot, nome: name, mediaType, origine: 'uploaded', base64: bytes.toString('base64') });
145
+ return { id, nome: name, mediaType, duplicateDecision: scan.state === 'complete' ? 'created' : 'scan-incomplete-created', scanState: scan.state, duplicateIds: [], unreadableIds: scan.unreadableIds };
146
+ };
147
+ const exportFile = async (id, out) => { const value = await bytesFor(id); await writeExport(out, value.bytes); return { legacy: { ok: true, id, out, nome: value.nome, mediaType: value.mediaType } }; };
148
+ const rename = async (id, name) => { const mod = await store(), legacy = await mod.rinominaVoce({ cartella: input.projectRoot, id, nome: name }); return { legacy }; };
149
+ const deleteEntry = async (id) => { const mod = await store(), legacy = await mod.eliminaVoce({ cartella: input.projectRoot, id }); return { legacy }; };
150
+ const prepareContextReference = async (id) => {
151
+ const entry = await exact(id), relative = entry.mod.percorsoContenutoVoce(id);
152
+ if (!relative || /[\0\r\n\s]/u.test(relative))
153
+ fail('LIBRARY_CONTEXT_UNSUPPORTED', 'Library content path cannot be attached safely.');
154
+ const value = await bytesFor(id);
155
+ let attachment;
156
+ if (entry.row.fileType === 'image' || entry.row.mediaType.startsWith('image/')) {
157
+ const mime = imageMimeFromBytes(value.bytes);
158
+ if (!mime)
159
+ fail('LIBRARY_CONTEXT_UNSUPPORTED', 'This image format is not supported by the current CLI attachment model.');
160
+ attachment = { kind: 'image', path: relative, mimeType: mime, bytes: value.bytes.length, dataBase64: value.bytes.toString('base64') };
161
+ }
162
+ else {
163
+ if (!textMedia(entry.row.mediaType))
164
+ fail('LIBRARY_CONTEXT_UNSUPPORTED', 'This Library file type is not supported by the current CLI attachment model.');
165
+ if (value.bytes.length > TEXT_ATTACHMENT_MAX_BYTES)
166
+ fail('LIBRARY_CONTEXT_UNSUPPORTED', 'This Library text file exceeds the current CLI attachment limit.');
167
+ const text = fatalText(value.bytes);
168
+ attachment = { kind: 'text', path: relative, mimeType: 'text/plain', bytes: value.bytes.length, text };
169
+ }
170
+ validateCliAttachments([attachment]);
171
+ return { id, token: '@' + relative, path: relative, kind: attachment.kind, bytes: attachment.bytes };
172
+ };
173
+ return { list, search, read, preview, duplicates, importFile, exportFile, rename, delete: deleteEntry, prepareContextReference };
174
+ }
@@ -0,0 +1,348 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import { createRequire } from 'node:module';
10
+ import { rm } from 'node:fs/promises';
11
+ import { join } from 'node:path';
12
+ import { pathToFileURL } from 'node:url';
13
+ import { createRedactor, redactObject, secretValuesFromEnvironment } from "../diagnostics/redact.js";
14
+ import { findTalosRepoRoot, importTalosModule } from "../runtime/repo.js";
15
+ import { fingerprintExecutableResourceContent } from "../security/project-trust.js";
16
+ import { createTrustAuthority } from "../security/trust-authority.js";
17
+ const ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,120}$/u;
18
+ const MAX_LOGS = 100;
19
+ const MAX_LOG_TEXT = 4096;
20
+ const UNSAFE = /[\\\x00-\x1f\x7f-\x9f\u2028\u2029\p{Bidi_Control}\p{Default_Ignorable_Code_Point}]/gu;
21
+ const BACKSLASH = String.fromCharCode(92);
22
+ function fail(code, message = code) { throw Object.assign(new Error(message), { code }); }
23
+ function serverId(value) { if (!ID.test(value) || value.includes('..'))
24
+ fail('MCP_SERVER_ID_INVALID'); return value; }
25
+ function objectValue(value) { return value && typeof value === 'object' && !Array.isArray(value) ? value : null; }
26
+ function textValue(value) { return typeof value === 'string' && value.length > 0 ? value : null; }
27
+ function inert(value) {
28
+ return String(value).replace(UNSAFE, character => {
29
+ if (character === BACKSLASH)
30
+ return BACKSLASH + BACKSLASH;
31
+ const code = character.codePointAt(0);
32
+ return code > 0xffff ? BACKSLASH + 'u{' + code.toString(16) + '}' : BACKSLASH + 'u' + code.toString(16).padStart(4, '0');
33
+ });
34
+ }
35
+ function safeText(value, redact) { return inert(redact(String(value ?? ''))).slice(0, MAX_LOG_TEXT); }
36
+ function normalizeCapabilities(value, redact) {
37
+ const row = objectValue(value);
38
+ if (!row)
39
+ return null;
40
+ const experimental = objectValue(row.experimental);
41
+ return {
42
+ tools: Boolean(row.tools),
43
+ resources: Boolean(row.resources),
44
+ prompts: Boolean(row.prompts),
45
+ logging: Boolean(row.logging),
46
+ completions: Boolean(row.completions),
47
+ tasks: Boolean(row.tasks),
48
+ experimental: experimental ? Object.keys(experimental).map(value => safeText(value, redact)).sort() : []
49
+ };
50
+ }
51
+ function boundedLogs(rows, redact) {
52
+ return rows.slice(-MAX_LOGS).map(row => ({
53
+ source: row.source,
54
+ level: row.level ? safeText(row.level, redact) : null,
55
+ text: safeText(row.text, redact)
56
+ }));
57
+ }
58
+ function configuredServer(value) {
59
+ if (!value || typeof value !== 'object')
60
+ fail('MCP_CONFIG_MALFORMED');
61
+ const id = serverId(String(value.id ?? ''));
62
+ const args = value.argomenti ?? [];
63
+ if (typeof value.comando !== 'string' || !value.comando
64
+ || !Array.isArray(args) || !args.every((row) => typeof row === 'string')
65
+ || !Array.isArray(value.allowlist) || !value.allowlist.length
66
+ || !value.allowlist.every((row) => typeof row === 'string' && row.length > 0))
67
+ fail('MCP_CONFIG_MALFORMED');
68
+ return {
69
+ id, comando: value.comando, argomenti: [...args], allowlist: [...value.allowlist],
70
+ ...(typeof value.hash === 'string' ? { hash: value.hash } : {}),
71
+ ...(typeof value.nome === 'string' ? { nome: value.nome } : {}),
72
+ ...(typeof value.versione === 'string' ? { versione: value.versione } : {})
73
+ };
74
+ }
75
+ export function createMcpFacade(input, deps = {}) {
76
+ const authority = deps.authority ?? createTrustAuthority({ projectRoot: input.projectRoot, trustRoot: input.paths.trust.projects });
77
+ const clock = input.clock ?? (() => new Date().toISOString());
78
+ const now = input.now ?? (() => Date.now());
79
+ const secrets = deps.secretValues ?? secretValuesFromEnvironment(input.env ?? process.env);
80
+ const redactor = createRedactor(secrets);
81
+ const repoRoot = () => input.repoRoot ?? findTalosRepoRoot(input.projectRoot);
82
+ let registryPromise = null;
83
+ let clientPromise = null;
84
+ const registry = () => registryPromise ??= importTalosModule(repoRoot(), 'mcp-registry.mjs');
85
+ const clientModule = () => clientPromise ??= importTalosModule(repoRoot(), 'mcp-client.mjs');
86
+ async function defaultLoadServers() {
87
+ try {
88
+ const loaded = await (await registry()).caricaServerMcp({ cartella: input.projectRoot });
89
+ if (!loaded || !Array.isArray(loaded.server))
90
+ fail('MCP_CONFIG_MALFORMED');
91
+ return { server: loaded.server.map(configuredServer) };
92
+ }
93
+ catch (error) {
94
+ if (error?.code === 'RESOURCE_CONFIG_MALFORMED')
95
+ fail('MCP_CONFIG_MALFORMED');
96
+ throw error;
97
+ }
98
+ }
99
+ const loadServers = deps.loadServers ?? defaultLoadServers;
100
+ async function compatibilityRoot() { return (await authority.compatibilityRoots()).mcp; }
101
+ async function defaultUntrustCompatibility(id) { await rm(join(await compatibilityRoot(), serverId(id) + '.json'), { force: true }); }
102
+ async function defaultTrustCompatibility(server) {
103
+ if (!server.hash)
104
+ fail('MCP_COMPATIBILITY_HASH_MISSING');
105
+ const root = await compatibilityRoot();
106
+ await rm(join(root, serverId(server.id) + '.json'), { force: true });
107
+ await (await registry()).fidaServerMcp({ cartellaTrust: root, serverId: server.id, hash: server.hash });
108
+ }
109
+ const untrustCompatibility = deps.untrustCompatibility ?? defaultUntrustCompatibility;
110
+ const trustCompatibility = deps.trustCompatibility ?? defaultTrustCompatibility;
111
+ async function defaultFingerprintServer(server, snapshot) {
112
+ const resource = await fingerprintExecutableResourceContent({
113
+ workspace: snapshot.workspace,
114
+ kind: 'mcp',
115
+ id: server.id,
116
+ path: join(snapshot.workspace.canonicalRoot, '.harness-ui-mcp.json'),
117
+ content: JSON.stringify({ comando: server.comando, argomenti: server.argomenti ?? [], allowlist: server.allowlist })
118
+ });
119
+ return resource.fingerprint;
120
+ }
121
+ const fingerprintServer = deps.fingerprintServer ?? defaultFingerprintServer;
122
+ async function defaultProbeServer(server) {
123
+ const rawLogs = [];
124
+ const push = (entry) => {
125
+ if (rawLogs.length >= MAX_LOGS)
126
+ return;
127
+ rawLogs.push({ ...entry, text: String(entry.text).slice(0, MAX_LOG_TEXT) });
128
+ };
129
+ const requireFromHarness = createRequire(join(repoRoot(), 'harness-ui', 'package.json'));
130
+ const [clientSdk, stdioSdk] = await Promise.all([
131
+ import(__rewriteRelativeImportExtension(pathToFileURL(requireFromHarness.resolve('@modelcontextprotocol/client')).href)),
132
+ import(__rewriteRelativeImportExtension(pathToFileURL(requireFromHarness.resolve('@modelcontextprotocol/client/stdio')).href))
133
+ ]);
134
+ const ClientBase = clientSdk.Client;
135
+ const TransportBase = stdioSdk.StdioClientTransport;
136
+ class CapturingClient extends ClientBase {
137
+ constructor(...args) {
138
+ super(...args);
139
+ this.setNotificationHandler?.('notifications/message', (notification) => {
140
+ const params = notification?.params ?? {};
141
+ let text;
142
+ try {
143
+ text = typeof params.data === 'string' ? params.data : JSON.stringify(redactObject(params.data, secrets) ?? '');
144
+ }
145
+ catch {
146
+ text = String(redactObject(params.data, secrets) ?? '');
147
+ }
148
+ push({ source: 'protocol', level: typeof params.level === 'string' ? params.level : null, text });
149
+ });
150
+ }
151
+ async connect(transport, options) {
152
+ try {
153
+ return options === undefined ? await super.connect(transport) : await super.connect(transport, options);
154
+ }
155
+ catch (error) {
156
+ try {
157
+ await this.close();
158
+ }
159
+ catch { /* The original connect failure remains authoritative. */ }
160
+ throw error;
161
+ }
162
+ }
163
+ }
164
+ class CapturingTransport extends TransportBase {
165
+ constructor(params) {
166
+ super({ ...params, stderr: 'pipe' });
167
+ this.stderr?.on?.('data', (chunk) => push({
168
+ source: 'stderr', level: 'stderr',
169
+ text: Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk)
170
+ }));
171
+ }
172
+ }
173
+ const mcp = await clientModule();
174
+ let connection = null;
175
+ let phase = 'connect';
176
+ const started = now();
177
+ try {
178
+ connection = await mcp.connettiServerMcp(server, { ClientCls: CapturingClient, TransportCls: CapturingTransport });
179
+ phase = 'discovery';
180
+ const tools = await mcp.elencaToolMcp(connection);
181
+ const client = connection.client;
182
+ return {
183
+ latencyMs: Math.max(0, now() - started),
184
+ serverInfo: client.getServerVersion?.() ?? null,
185
+ protocolVersion: client.getNegotiatedProtocolVersion?.() ?? null,
186
+ protocolEra: client.getProtocolEra?.() ?? null,
187
+ capabilities: client.getServerCapabilities?.() ?? null,
188
+ tools: Array.isArray(tools) ? tools : [],
189
+ logs: rawLogs
190
+ };
191
+ }
192
+ catch (error) {
193
+ throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), {
194
+ code: typeof error?.code === 'string' ? error.code : 'MCP_PROBE_FAILED',
195
+ mcpProbePhase: phase,
196
+ mcpProbeLogs: rawLogs
197
+ });
198
+ }
199
+ finally {
200
+ try {
201
+ await connection?.chiudi?.();
202
+ }
203
+ catch (error) {
204
+ push({ source: 'probe', level: 'warning', text: 'close failed: ' + (error instanceof Error ? error.message : String(error)) });
205
+ }
206
+ }
207
+ }
208
+ const probeServer = deps.probeServer ?? defaultProbeServer;
209
+ async function servers() {
210
+ try {
211
+ const loaded = await loadServers();
212
+ if (!loaded || !Array.isArray(loaded.server))
213
+ fail('MCP_CONFIG_MALFORMED');
214
+ const rows = loaded.server.map(configuredServer);
215
+ const seen = new Set();
216
+ for (const server of rows) {
217
+ if (seen.has(server.id))
218
+ fail('MCP_CONFIG_MALFORMED');
219
+ seen.add(server.id);
220
+ }
221
+ return rows;
222
+ }
223
+ catch (error) {
224
+ if (error?.code === 'RESOURCE_CONFIG_MALFORMED')
225
+ fail('MCP_CONFIG_MALFORMED');
226
+ throw error;
227
+ }
228
+ }
229
+ function trustRow(snapshot, id) {
230
+ return snapshot.resources.find(row => row.kind === 'mcp' && row.id === id && row.current);
231
+ }
232
+ function view(server, snapshot) {
233
+ const row = trustRow(snapshot, server.id);
234
+ const state = (row?.state ?? 'added');
235
+ const current = row?.currentFingerprint ?? null;
236
+ const trusted = row?.trustedFingerprint ?? null;
237
+ return {
238
+ id: server.id,
239
+ launch: { command: safeText(server.comando, redactor.text), argumentCount: server.argomenti?.length ?? 0 },
240
+ trust: {
241
+ projectTrusted: snapshot.trusted, state, trusted: state === 'trusted',
242
+ currentFingerprint: current, trustedFingerprint: trusted,
243
+ changed: state === 'changed' || Boolean(current && trusted && current !== trusted)
244
+ },
245
+ permission: {
246
+ configuredAllowlist: server.allowlist.map(value => safeText(value, redactor.text)),
247
+ effectiveTools: [], missingAllowlistedTools: [], perCallApproval: 'not-applied'
248
+ },
249
+ health: { state: 'not-probed', checkedAt: null, latencyMs: null, phase: null, message: null },
250
+ server: null, protocol: null, capabilities: null, logs: []
251
+ };
252
+ }
253
+ async function target(id) {
254
+ const wanted = serverId(id);
255
+ const rows = await servers();
256
+ const server = rows.find(row => row.id === wanted);
257
+ if (!server)
258
+ fail('MCP_SERVER_NOT_FOUND');
259
+ return server;
260
+ }
261
+ async function assertTrustedLoaded(server, snapshot) {
262
+ const row = trustRow(snapshot, server.id);
263
+ if (!row || row.state !== 'trusted')
264
+ fail('MCP_TRUST_REQUIRED');
265
+ if (!snapshot.trusted)
266
+ fail('PROJECT_TRUST_REQUIRED');
267
+ const loadedFingerprint = await fingerprintServer(server, snapshot);
268
+ if (!loadedFingerprint || loadedFingerprint !== row.currentFingerprint)
269
+ fail('MCP_TRUST_INVALIDATED');
270
+ }
271
+ return {
272
+ async list() {
273
+ const [rows, snapshot] = await Promise.all([servers(), authority.inspect()]);
274
+ return rows.map(server => view(server, snapshot));
275
+ },
276
+ async probe(id) {
277
+ const server = await target(id);
278
+ const snapshot = await authority.inspect();
279
+ const base = view(server, snapshot);
280
+ await assertTrustedLoaded(server, snapshot);
281
+ try {
282
+ const measured = await probeServer(server);
283
+ const advertised = [...new Set((measured.tools ?? [])
284
+ .map(row => textValue(row?.name))
285
+ .filter((row) => Boolean(row)))];
286
+ const allowedRaw = server.allowlist.filter(name => advertised.includes(name));
287
+ const missingRaw = server.allowlist.filter(name => !advertised.includes(name));
288
+ const effective = allowedRaw.map(name => safeText(name, redactor.text));
289
+ const missing = missingRaw.map(name => safeText(name, redactor.text));
290
+ const info = objectValue(measured.serverInfo);
291
+ return {
292
+ ...base,
293
+ permission: { ...base.permission, effectiveTools: effective, missingAllowlistedTools: missing },
294
+ health: {
295
+ state: missing.length ? 'degraded' : 'healthy',
296
+ checkedAt: clock(),
297
+ latencyMs: typeof measured.latencyMs === 'number' && Number.isFinite(measured.latencyMs) ? Math.max(0, measured.latencyMs) : null,
298
+ phase: null,
299
+ message: missing.length ? 'Configured tools not advertised: ' + missing.join(', ') : null
300
+ },
301
+ server: info && textValue(info.name) ? {
302
+ name: safeText(info.name, redactor.text),
303
+ version: textValue(info.version) ? safeText(info.version, redactor.text) : null
304
+ } : null,
305
+ protocol: {
306
+ version: textValue(measured.protocolVersion) ? safeText(measured.protocolVersion, redactor.text) : null,
307
+ era: textValue(measured.protocolEra) ? safeText(measured.protocolEra, redactor.text) : null
308
+ },
309
+ capabilities: normalizeCapabilities(measured.capabilities, redactor.text),
310
+ logs: boundedLogs(measured.logs ?? [], redactor.text)
311
+ };
312
+ }
313
+ catch (error) {
314
+ const raw = error?.mcpProbeLogs;
315
+ const logs = Array.isArray(raw) ? [...raw] : [];
316
+ logs.push({ source: 'probe', level: 'error', text: error instanceof Error ? error.message : String(error) });
317
+ return {
318
+ ...base,
319
+ health: {
320
+ state: 'failed', checkedAt: clock(), latencyMs: null,
321
+ phase: textValue(error?.mcpProbePhase),
322
+ message: safeText(error instanceof Error ? error.message : String(error), redactor.text)
323
+ },
324
+ logs: boundedLogs(logs, redactor.text)
325
+ };
326
+ }
327
+ },
328
+ async trust(id) {
329
+ const server = await target(id);
330
+ const reviewed = await authority.inspect();
331
+ const row = trustRow(reviewed, server.id);
332
+ if (!row?.current)
333
+ fail('MCP_RESOURCE_NOT_FOUND');
334
+ const loadedFingerprint = await fingerprintServer(server, reviewed);
335
+ if (!loadedFingerprint || loadedFingerprint !== row.currentFingerprint)
336
+ fail('MCP_TRUST_INVALIDATED');
337
+ const result = await authority.trustScope({ kind: 'mcp', id: server.id }, { expected: reviewed });
338
+ await trustCompatibility(server);
339
+ return { ok: true, id: server.id, changed: result.changed, snapshot: result.snapshot };
340
+ },
341
+ async untrust(id) {
342
+ const server = await target(id);
343
+ const result = await authority.untrustScope({ kind: 'mcp', id: server.id });
344
+ await untrustCompatibility(server.id);
345
+ return { ok: true, id: server.id, changed: result.changed, snapshot: result.snapshot };
346
+ }
347
+ };
348
+ }
@@ -0,0 +1,126 @@
1
+ import { join } from 'node:path';
2
+ import { findTalosRepoRoot, importTalosModule } from "../runtime/repo.js";
3
+ const KINDS = new Set(['preference', 'project_fact', 'procedure', 'policy_note']);
4
+ const SCOPE = { kind: 'global', evidence: 'derived-store-contract', projectId: null, sessionId: null };
5
+ const DUPLICATE_POLICY = {
6
+ mode: 'create-title-normalized',
7
+ normalization: 'trim-lowercase',
8
+ onCreateDuplicate: 'return-existing-no-write',
9
+ onUpdate: 'not-checked',
10
+ semanticDetection: false,
11
+ merge: false
12
+ };
13
+ const USAGE = { status: 'unavailable', reason: 'store-does-not-persist-memory-usage' };
14
+ const COST = { status: 'unavailable', reason: 'store-does-not-persist-memory-cost' };
15
+ function stringOrNull(value) { return typeof value === 'string' ? value : null; }
16
+ function requiredString(value, field) {
17
+ if (typeof value !== 'string' || value.length === 0)
18
+ throw new TypeError('malformed persisted memory row: ' + field);
19
+ return value;
20
+ }
21
+ function invalid(error) {
22
+ return { state: 'invalid', scope: { ...SCOPE }, rows: [], error: { code: 'MEMORY_STORE_INVALID', message: error instanceof Error ? error.message : String(error) }, legacyRows: [] };
23
+ }
24
+ function projectRow(raw, store) {
25
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
26
+ throw new TypeError('malformed persisted memory row: object required');
27
+ const shaped = typeof store.formaPubblicaMemoria === 'function' ? store.formaPubblicaMemoria(raw) : raw;
28
+ if (!shaped || typeof shaped !== 'object' || Array.isArray(shaped))
29
+ throw new TypeError('malformed persisted memory row: public shape');
30
+ const id = requiredString(shaped.id, 'id');
31
+ const title = requiredString(shaped.titolo, 'titolo');
32
+ const content = requiredString(shaped.contenuto, 'contenuto');
33
+ const kind = KINDS.has(shaped.genere) ? shaped.genere : null;
34
+ const writerPersisted = raw.origine === 'persona' || raw.origine === 'modello';
35
+ const writer = shaped.origine === 'persona' || shaped.origine === 'modello' ? shaped.origine : 'modello';
36
+ return {
37
+ id, title, content, kind,
38
+ createdAt: stringOrNull(shaped.creataAlle),
39
+ updatedAt: stringOrNull(shaped.aggiornataAlle),
40
+ provenance: {
41
+ writer,
42
+ writerEvidence: writerPersisted ? 'persisted' : 'derived-legacy-default',
43
+ scope: 'global',
44
+ scopeEvidence: 'derived-store-contract',
45
+ projectId: null,
46
+ sessionId: null,
47
+ source: null
48
+ },
49
+ duplicateControl: { ...DUPLICATE_POLICY },
50
+ usage: { ...USAGE },
51
+ cost: { ...COST }
52
+ };
53
+ }
54
+ export function createMemoryFacade(input, deps = {}) {
55
+ const memoryRoot = () => {
56
+ if (input.memoryRoot)
57
+ return input.memoryRoot;
58
+ const dataRoot = input.paths?.dataRoot;
59
+ if (!dataRoot)
60
+ throw new Error('MEMORY_DATA_ROOT_REQUIRED');
61
+ return join(dataRoot, 'memory');
62
+ };
63
+ const repoRoot = () => {
64
+ if (input.repoRoot)
65
+ return input.repoRoot;
66
+ if (input.projectRoot)
67
+ return findTalosRepoRoot(input.projectRoot);
68
+ throw new Error('MEMORY_REPO_ROOT_REQUIRED');
69
+ };
70
+ let loaded = null;
71
+ const load = () => loaded ??= (deps.loadStore ? deps.loadStore() : importTalosModule(repoRoot(), 'memory-store.mjs'));
72
+ const list = async () => {
73
+ try {
74
+ const store = await load();
75
+ const raw = await store.elencaMemorie({ cartella: memoryRoot() });
76
+ if (!Array.isArray(raw))
77
+ throw new TypeError('malformed persisted memory list');
78
+ const rows = raw.map(row => projectRow(row, store));
79
+ return { state: 'ready', scope: { ...SCOPE }, rows, error: null, legacyRows: raw };
80
+ }
81
+ catch (error) {
82
+ return invalid(error);
83
+ }
84
+ };
85
+ const search = async (query, limit = 5) => {
86
+ try {
87
+ const store = await load();
88
+ const raw = await store.elencaMemorie({ cartella: memoryRoot() });
89
+ if (!Array.isArray(raw))
90
+ throw new TypeError('malformed persisted memory list');
91
+ const found = store.cercaMemorie(raw, { query, limit });
92
+ if (!found || !Array.isArray(found.memorie) || !Number.isFinite(found.totale))
93
+ throw new TypeError('malformed memory search result');
94
+ const rows = found.memorie.map(row => projectRow(row, store));
95
+ return {
96
+ state: 'ready', scope: { ...SCOPE }, rows, error: null, legacyRows: raw,
97
+ total: found.totale,
98
+ legacy: { memorie: found.memorie, totale: found.totale }
99
+ };
100
+ }
101
+ catch (error) {
102
+ return { ...invalid(error), total: 0, legacy: null };
103
+ }
104
+ };
105
+ const add = async (value) => {
106
+ const store = await load();
107
+ const result = await store.creaMemoria({ cartella: memoryRoot(), title: value.title, content: value.content, kind: value.kind ?? 'preference', origine: 'persona' });
108
+ return {
109
+ memory: projectRow(result.voce, store),
110
+ duplicateDecision: result.duplicato ? 'existing-title-no-write' : 'created',
111
+ legacy: result
112
+ };
113
+ };
114
+ const update = async (id, value) => {
115
+ const store = await load();
116
+ const row = await store.aggiornaMemoria({ cartella: memoryRoot(), id, ...(value.title !== undefined ? { title: value.title } : {}), ...(value.content !== undefined ? { content: value.content } : {}), ...(value.kind !== undefined ? { kind: value.kind } : {}) });
117
+ return { memory: projectRow(row, store), duplicateDecision: 'not-checked-on-update', legacy: row };
118
+ };
119
+ const deleteMemory = async (id) => {
120
+ const store = await load();
121
+ await store.eliminaMemoria({ cartella: memoryRoot(), id });
122
+ const legacy = { ok: true, id };
123
+ return { ok: true, id, legacy };
124
+ };
125
+ return { list, search, add, update, delete: deleteMemory };
126
+ }