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,244 @@
1
+ import { kernelProbeDetail } from "../i18n/kernel-map.js";
2
+ import { assertNoUnknownOptions, takeFlag, takeOption, writeValue } from "./context.js";
3
+ import { REASONING_EFFORTS } from "../config/types.js";
4
+ import { importTalosModule } from "../runtime/repo.js";
5
+ import { createEnvironmentKeyConsent, providerOfModel } from "../provider/environment-keys.js";
6
+ import { t } from "../i18n/index.js";
7
+ /*
8
+ * B1 slice 18 — the command line follows the rules of `/provider`: the store sees an environment key only after it
9
+ * was approved (`talos provider env-key <id> --use`; nothing said means No), and `set-key` tests the key against its
10
+ * own provider and saves it only when the test passes. The key is read through the hidden prompt, never from argv.
11
+ */
12
+ async function runtimeContext(ctx) { return ctx.createRuntimeContext({ projectRoot: ctx.projectRoot, paths: ctx.paths, repoRoot: ctx.repoRoot, model: ctx.invocation.model ?? 'openai:gpt-5-mini', environmentKeys: 'consent' }); }
13
+ function environmentKeyOf(row) { return row && row.environmentVariable ? { variable: String(row.environmentVariable), state: row.keySource === 'environment' ? 'approved' : row.keySource === 'environment-declined' ? 'declined' : 'unanswered' } : null; }
14
+ export async function runProviderCommand(ctx, args0) {
15
+ const args = [...args0];
16
+ const op = args.shift() ?? 'list';
17
+ const rc = await runtimeContext(ctx);
18
+ const store = rc.providerStore;
19
+ const catalog = rc.tuiCatalog;
20
+ if (op === 'list') {
21
+ assertNoUnknownOptions(args);
22
+ if (typeof rc.providerControlPlane?.list === 'function') {
23
+ writeValue(ctx, rc.providerControlPlane.list());
24
+ return 0;
25
+ }
26
+ const rows = store.listPublic();
27
+ let providers = [];
28
+ try {
29
+ providers = await catalog?.listProviders?.() ?? [];
30
+ }
31
+ catch {
32
+ providers = [];
33
+ }
34
+ writeValue(ctx, rows.map((row) => ({ ...row, environmentKey: environmentKeyOf(providers.find((p) => p.id === row?.id)) })));
35
+ return 0;
36
+ }
37
+ const id = args.shift();
38
+ if (!id)
39
+ throw new Error('PROVIDER_REQUIRED');
40
+ /* P21 (owner decisions 2026-09-26): `talos provider login openrouter` signs in in the browser (the loopback waits for it);
41
+ `--paste`, or a remote session, uses the code OpenRouter shows. Interactive only (clig.dev: never require a prompt in a
42
+ script). The key that comes back is tested and saved like `set-key`'s; it is never printed. */
43
+ if (op === 'login') {
44
+ const paste = takeFlag(args, '--paste');
45
+ assertNoUnknownOptions(args);
46
+ if (id !== 'openrouter')
47
+ throw Object.assign(new Error('PROVIDER_LOGIN_UNSUPPORTED'), { code: 'PROVIDER_LOGIN_UNSUPPORTED' });
48
+ if (typeof catalog?.startOpenRouterLogin !== 'function' || typeof catalog?.setProviderKey !== 'function')
49
+ throw Object.assign(new Error('PROVIDER_LOGIN_UNAVAILABLE'), { code: 'PROVIDER_LOGIN_UNAVAILABLE' });
50
+ if (!ctx.io.stdinIsTTY || !ctx.io.stdoutIsTTY)
51
+ throw Object.assign(new Error('LOGIN_REQUIRES_TTY'), { code: 'LOGIN_REQUIRES_TTY' });
52
+ const login = await catalog.startOpenRouterLogin(paste ? { paste: true } : {});
53
+ if (login.mode === 'paste')
54
+ ctx.io.writeErr(`${t('key.login.paste')}\n${login.url}\n`);
55
+ else
56
+ ctx.io.writeErr(`${t(login.opened ? 'key.login.opened' : 'key.login.open')}\n${login.url}\n${t('key.login.waiting')}\n`);
57
+ let key = '';
58
+ try {
59
+ if (login.mode === 'paste') {
60
+ if (!ctx.io.readSecret)
61
+ throw Object.assign(new Error('SECRET_INPUT_REQUIRES_TTY'), { code: 'SECRET_INPUT_REQUIRES_TTY' });
62
+ key = await login.submit(await ctx.io.readSecret(t('key.login.codePrompt')));
63
+ }
64
+ else
65
+ key = await login.key;
66
+ }
67
+ catch (error) {
68
+ login.cancel();
69
+ const code = String(error?.code ?? 'OAUTH_FAILED');
70
+ writeValue(ctx, { ok: false, provider: id, code, ...(error?.status ? { httpStatus: error.status } : {}) }, `${t('key.login.failed', { code })}\n`);
71
+ return 11;
72
+ }
73
+ let result;
74
+ try {
75
+ result = await catalog.setProviderKey(id, key);
76
+ }
77
+ finally {
78
+ key = '';
79
+ }
80
+ const saved = result.saved === true;
81
+ writeValue(ctx, { ok: saved, provider: id, outcome: result.outcome, httpStatus: result.httpStatus, saved }, `${t('key.login.signedIn', { message: result.message, saved: t(saved ? 'key.login.saved' : 'key.login.notSaved') })}\n`);
82
+ return saved ? 0 : 11;
83
+ }
84
+ if (op === 'set-key') {
85
+ assertNoUnknownOptions(args);
86
+ if (!ctx.io.readSecret)
87
+ throw new Error('SECRET_INPUT_REQUIRES_TTY');
88
+ if (typeof catalog?.setProviderKey !== 'function')
89
+ throw Object.assign(new Error('PROVIDER_KEY_TEST_UNAVAILABLE'), { code: 'PROVIDER_KEY_TEST_UNAVAILABLE' }); /* a one-token key test is stated before the key is read, so before anything is sent; nothing further is asked */
90
+ const notice = typeof catalog.keyTestNotice === 'function' ? catalog.keyTestNotice(id) : null;
91
+ if (notice)
92
+ ctx.io.writeErr(`${notice}\n`);
93
+ let secret = await ctx.io.readSecret(`Key for ${id}: `);
94
+ let result;
95
+ try {
96
+ result = await catalog.setProviderKey(id, secret);
97
+ }
98
+ finally {
99
+ secret = '';
100
+ }
101
+ const saved = result.saved === true;
102
+ writeValue(ctx, { ok: saved, provider: id, outcome: result.outcome, httpStatus: result.httpStatus, saved }, `${result.message} ${saved ? 'Saved.' : 'The key was not saved.'}\n`);
103
+ return saved ? 0 : 11;
104
+ }
105
+ if (op === 'env-key') {
106
+ const use = takeFlag(args, '--use');
107
+ const decline = takeFlag(args, '--decline');
108
+ assertNoUnknownOptions(args);
109
+ if (use && decline)
110
+ throw new Error('Use either --use or --decline');
111
+ const row = (await catalog.listProviders()).find((p) => p.id === id);
112
+ if (!row)
113
+ throw Object.assign(new Error('PROVIDER_INVALID'), { code: 'PROVIDER_INVALID' });
114
+ const answering = use || decline;
115
+ if (answering && row.environmentVariable)
116
+ await catalog.answerEnvironmentKey(id, use ? 'yes' : 'no');
117
+ const after = answering ? (await catalog.listProviders()).find((p) => p.id === id) : row;
118
+ const state = environmentKeyOf(after);
119
+ if (!state) {
120
+ writeValue(ctx, { ok: !answering, provider: id, environmentKey: null }, `No key for ${after?.label ?? id} was found in the environment.\n`);
121
+ return answering ? 2 : 0;
122
+ }
123
+ writeValue(ctx, { ok: true, provider: id, environmentKey: state }, `${state.variable}: ${state.state === 'approved' ? 'used for ' + after.label : state.state === 'declined' ? 'declined, not used' : 'not used until approved (talos provider env-key ' + id + ' --use)'}\n`);
124
+ return 0;
125
+ }
126
+ if (op === 'remove-key') {
127
+ assertNoUnknownOptions(args);
128
+ store.clearKey(id);
129
+ rc.providerControlPlane?.invalidate?.(id);
130
+ writeValue(ctx, { ok: true, provider: id }, `Removed key for ${id}\n`);
131
+ return 0;
132
+ }
133
+ if (op === 'configure') {
134
+ const endpoint = takeOption(args, '--endpoint');
135
+ const timeoutRaw = takeOption(args, '--timeout');
136
+ assertNoUnknownOptions(args);
137
+ const current = store.getRuntime(id) ?? {};
138
+ const timeoutSeconds = timeoutRaw === undefined ? current.timeoutSeconds : Number(timeoutRaw);
139
+ if (timeoutRaw !== undefined && (!Number.isInteger(timeoutSeconds) || timeoutSeconds < 5 || timeoutSeconds > 300))
140
+ throw new Error('PROVIDER_TIMEOUT_INVALID');
141
+ if (endpoint === undefined && timeoutRaw === undefined)
142
+ throw new Error('PROVIDER_CONFIG_REQUIRED');
143
+ store.setRuntime(id, { ...current, ...(endpoint !== undefined ? { endpoint } : {}), ...(timeoutSeconds !== undefined ? { timeoutSeconds } : {}) });
144
+ rc.providerControlPlane?.invalidate?.(id);
145
+ writeValue(ctx, { ok: true, provider: id, runtime: store.getRuntime(id) }, `Configured ${id}\n`);
146
+ return 0;
147
+ }
148
+ if (op === 'test') {
149
+ assertNoUnknownOptions(args); /* M5-A/M5-C: ordinary health testing never opts into token generation, and remediation is the control-plane decision. */
150
+ if (typeof rc.providerControlPlane?.probe === 'function') {
151
+ const profile = await rc.providerControlPlane.probe(id);
152
+ const health = profile.lastHealth ?? {};
153
+ const latency = Number.isFinite(health.latencyMs) ? ` · ${health.latencyMs} ms` : ''; /* R2 (E8 / Q-R2-7): a missing key is the one sentence, as a line of its own; the probe's free-text reason (the kernel's, Italian) is mapped by the remediation code and not printed. */
154
+ const missingKey = profile.remediation?.code === 'add-key';
155
+ const remedy = missingKey ? `${profile.remediation.message}\n` : profile.remediation?.code && profile.remediation.code !== 'none' ? `Remedy: ${profile.remediation.message}\n` : ''; /* R4 Q-R4-16 (a): the kernel's sentence in English by a pinned template, or not printed. */
156
+ const mapped = health.detail && !missingKey ? kernelProbeDetail(String(health.detail), { label: String(profile.label ?? id) }) : null;
157
+ const detail = mapped ? `${mapped}\n` : '';
158
+ writeValue(ctx, missingKey ? { ...profile, code: 'PROVIDER_KEY_MISSING' } : profile, `${profile.label ?? id}: ${health.state ?? 'unknown'}${latency}\n${detail}${remedy}`);
159
+ return health.state === 'available' ? 0 : 11;
160
+ }
161
+ const probe = typeof rc.providerProbe === 'function' ? rc.providerProbe() : (await importTalosModule(ctx.repoRoot, 'provider-probe.mjs')).createProviderProbe({ leggiChiave: (p) => store.getKey(p), leggiRuntime: (p) => store.getRuntime(p) });
162
+ const result = await probe.prova(id);
163
+ writeValue(ctx, result);
164
+ return result?.esito === 'collegato' ? 0 : 11;
165
+ }
166
+ throw new Error(`Unsupported provider operation: ${op}`);
167
+ }
168
+ /*
169
+ * R2 (gate E14, E-03): `talos model list` for a person — one row per model under English columns, never the raw JSON array; the
170
+ * MODEL column is exactly what `talos model use` takes (OpenCode `opencode models` prints one id per line and JSON only with
171
+ * --verbose: `packages/opencode/src/cli/cmd/models.ts:36-46` at 1d6c3c0, 2026-09-24). `--json` keeps the rows unchanged.
172
+ */
173
+ function contextText(value) {
174
+ if (!Number.isFinite(value) || Number(value) <= 0)
175
+ return t('key.models.unknown');
176
+ const n = Number(value);
177
+ return n >= 1_000_000 ? `${Number((n / 1_000_000).toFixed(1))}M` : n >= 1000 ? `${Math.round(n / 1000)}K` : String(n);
178
+ }
179
+ function flagText(value) { return value === true ? t('key.models.yes') : value === false ? t('key.models.no') : t('key.models.unknown'); }
180
+ function sourceText(value) { return t(value === 'live' ? 'key.models.source.live' : value === 'configured' ? 'key.models.source.configured' : value === 'documented' ? 'key.models.source.documented' : 'key.models.source.unknown'); }
181
+ export function modelListText(rows, notice) {
182
+ const head = notice ? `${notice}\n` : '';
183
+ if (!rows.length)
184
+ return `${head}${t('key.models.none')}\n`;
185
+ const table = [[t('key.models.column.model'), t('key.models.column.context'), t('key.models.column.tools'), t('key.models.column.reasoning'), t('key.models.column.availability')],
186
+ ...rows.map(row => [String(row?.id ?? ''), contextText(row?.contextWindow), flagText(row?.toolCalling), flagText(row?.reasoning), sourceText(row?.source ?? row?.available)])];
187
+ const widths = table[0].map((_, column) => Math.max(...table.map(line => line[column].length)));
188
+ const lines = table.map(line => line.map((cell, column) => column === line.length - 1 ? cell : cell.padEnd(widths[column])).join(' '));
189
+ return `${head}${lines.join('\n')}\n${t('key.models.use')}\n`;
190
+ }
191
+ export async function runModelCommand(ctx, args0) { const args = [...args0]; const op = args.shift() ?? 'list'; if (op === 'effort') {
192
+ const effort = args.shift();
193
+ if (!effort)
194
+ throw new Error('REASONING_EFFORT_REQUIRED');
195
+ const scope = (takeOption(args, '--scope') ?? 'user');
196
+ if (!['user', 'project-user'].includes(scope))
197
+ throw new Error('CONFIG_SCOPE_INVALID');
198
+ assertNoUnknownOptions(args);
199
+ const { configSet, configUnset } = await import("../config/commands.js");
200
+ if (effort === 'default') {
201
+ await configUnset({ paths: ctx.paths, projectRoot: ctx.projectRoot, scope, path: 'reasoningEffort' });
202
+ writeValue(ctx, { ok: true, reasoningEffort: null, scope }, `Cleared the ${scope} reasoning-effort override; a lower-precedence setting may still apply, otherwise the model default is used.\n`);
203
+ return 0;
204
+ }
205
+ if (!REASONING_EFFORTS.includes(effort))
206
+ throw new Error('CONFIG_INVALID_REASONING_EFFORT');
207
+ await configSet({ paths: ctx.paths, projectRoot: ctx.projectRoot, scope, path: 'reasoningEffort', value: effort });
208
+ writeValue(ctx, { ok: true, reasoningEffort: effort, scope }, `Using reasoning effort ${effort} (${scope})\n`);
209
+ return 0;
210
+ } if (op === 'use') {
211
+ const id = args.shift();
212
+ if (!id)
213
+ throw new Error('MODEL_REQUIRED');
214
+ const scope = (takeOption(args, '--scope') ?? 'user');
215
+ if (!['user', 'project', 'project-user'].includes(scope))
216
+ throw new Error('CONFIG_SCOPE_INVALID');
217
+ assertNoUnknownOptions(args);
218
+ const provider = providerOfModel(id);
219
+ const registryModule = await importTalosModule(ctx.repoRoot, 'provider-registry.mjs');
220
+ if (!provider || !registryModule.REGISTRO_FORNITORI?.[provider])
221
+ throw Object.assign(new Error('MODEL_PROVIDER_INVALID'), { code: 'MODEL_PROVIDER_INVALID' });
222
+ const { configSet } = await import("../config/commands.js");
223
+ await configSet({ paths: ctx.paths, projectRoot: ctx.projectRoot, scope, path: 'model', value: id }); /* choosing a model chooses its provider: the interactive screen starts from the same choice */
224
+ createEnvironmentKeyConsent({ dataRoot: ctx.paths.dataRoot, registry: registryModule.REGISTRO_FORNITORI, env: {} }).chooseProvider(provider);
225
+ writeValue(ctx, { ok: true, model: id, scope }, `Using ${id} (${scope})\n`);
226
+ return 0;
227
+ } if (op === 'list') {
228
+ const provider = takeOption(args, '--provider');
229
+ assertNoUnknownOptions(args);
230
+ const rc = await runtimeContext(ctx);
231
+ const catalog = rc.tuiCatalog;
232
+ if (provider) {
233
+ if (typeof catalog?.providerModels !== 'function')
234
+ throw Object.assign(new Error('PROVIDER_CATALOG_UNAVAILABLE'), { code: 'PROVIDER_CATALOG_UNAVAILABLE' });
235
+ const list = await catalog.providerModels(provider);
236
+ writeValue(ctx, list.rows, modelListText(list.rows, list.notice));
237
+ return 0;
238
+ }
239
+ if (typeof catalog?.listModels !== 'function')
240
+ throw Object.assign(new Error('PROVIDER_CATALOG_UNAVAILABLE'), { code: 'PROVIDER_CATALOG_UNAVAILABLE' });
241
+ const rows = await catalog.listModels();
242
+ writeValue(ctx, rows, modelListText(rows));
243
+ return 0;
244
+ } throw new Error(`Unsupported model operation: ${op}`); }
@@ -0,0 +1,248 @@
1
+ import { join } from 'node:path';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { assertNoUnknownOptions, takeOption, writeValue } from "./context.js";
4
+ import { importTalosModule } from "../runtime/repo.js";
5
+ import { createMemoryFacade } from "../services/memory-facade.js";
6
+ import { createNotesFacade } from "../services/notes-facade.js";
7
+ import { createTaskBoardFacade } from "../services/task-board-facade.js";
8
+ import { createLibraryFacade } from "../services/library-facade.js";
9
+ import { createForgeFacade } from "../services/forge-facade.js";
10
+ const clean = (v) => { if (Array.isArray(v))
11
+ return v.map(clean); if (v && typeof v === 'object') {
12
+ const o = {};
13
+ for (const [k, x] of Object.entries(v)) {
14
+ if (/percorso|path/iu.test(k))
15
+ continue;
16
+ o[k] = clean(x);
17
+ }
18
+ return o;
19
+ } return v; };
20
+ function req(args, what) { const v = args.shift(); if (!v)
21
+ throw new Error(`${what}_REQUIRED`); return v; }
22
+ export async function runNotesCommand(ctx, args0) { const a = [...args0], op = a.shift() ?? 'list'; const notes = createNotesFacade({ projectRoot: ctx.projectRoot, paths: ctx.paths, repoRoot: ctx.repoRoot }); let r; if (op === 'list') {
23
+ assertNoUnknownOptions(a);
24
+ const x = await notes.list();
25
+ r = x.state === 'ready' ? x.legacyRows : x;
26
+ }
27
+ else if (op === 'add') {
28
+ const title = req(a, 'TITLE'), body = req(a, 'BODY');
29
+ assertNoUnknownOptions(a);
30
+ r = (await notes.add({ title, content: body })).legacy;
31
+ }
32
+ else if (op === 'update') {
33
+ const id = req(a, 'ID');
34
+ const title = takeOption(a, '--title'), content = takeOption(a, '--body');
35
+ assertNoUnknownOptions(a);
36
+ r = (await notes.update(id, { ...(title !== undefined ? { title } : {}), ...(content !== undefined ? { content } : {}) })).legacy;
37
+ }
38
+ else if (op === 'delete') {
39
+ const id = req(a, 'ID');
40
+ assertNoUnknownOptions(a);
41
+ r = (await notes.delete(id)).legacy;
42
+ }
43
+ else if (op === 'link' || op === 'unlink') {
44
+ const noteId = req(a, 'NOTE_ID'), targetKind = req(a, 'TARGET_KIND'), targetId = req(a, 'TARGET_ID');
45
+ assertNoUnknownOptions(a);
46
+ r = op === 'link' ? await notes.link(noteId, targetKind, targetId) : await notes.unlink(noteId, targetKind, targetId);
47
+ }
48
+ else
49
+ throw new Error(`Unsupported notes operation: ${op}`); writeValue(ctx, clean(r)); return 0; }
50
+ export async function runTasksCommand(ctx, args0) { const a = [...args0], op = a.shift() ?? 'list'; const tasks = createTaskBoardFacade({ projectRoot: ctx.projectRoot, paths: ctx.paths, repoRoot: ctx.repoRoot }); let r; if (op === 'list') {
51
+ assertNoUnknownOptions(a);
52
+ const x = await tasks.list();
53
+ r = x.state === 'ready' ? x.legacyRows : x;
54
+ }
55
+ else if (op === 'add') {
56
+ const title = req(a, 'TITLE'), description = req(a, 'DESCRIPTION'), priority = (takeOption(a, '--priority') ?? 'normal');
57
+ assertNoUnknownOptions(a);
58
+ r = (await tasks.add({ title, description, priority })).legacy;
59
+ }
60
+ else if (op === 'update') {
61
+ const id = req(a, 'ID');
62
+ const title = takeOption(a, '--title'), description = takeOption(a, '--description'), priority = takeOption(a, '--priority');
63
+ assertNoUnknownOptions(a);
64
+ r = (await tasks.update(id, { ...(title !== undefined ? { title } : {}), ...(description !== undefined ? { description } : {}), ...(priority !== undefined ? { priority } : {}) })).legacy;
65
+ }
66
+ else if (op === 'complete') {
67
+ const id = req(a, 'ID'), status = (a.shift() ?? 'done');
68
+ assertNoUnknownOptions(a);
69
+ r = (await tasks.complete(id, status)).legacy;
70
+ }
71
+ else if (op === 'delete') {
72
+ const id = req(a, 'ID');
73
+ assertNoUnknownOptions(a);
74
+ r = (await tasks.delete(id)).legacy;
75
+ }
76
+ else if (op === 'depend' || op === 'undepend') {
77
+ const id = req(a, 'TASK_ID'), target = req(a, 'DEPENDENCY_TASK_ID');
78
+ assertNoUnknownOptions(a);
79
+ r = op === 'depend' ? await tasks.depend(id, target) : await tasks.undepend(id, target);
80
+ }
81
+ else if (op === 'evidence' || op === 'unevidence') {
82
+ const id = req(a, 'TASK_ID'), sessionId = req(a, 'SESSION_ID');
83
+ assertNoUnknownOptions(a);
84
+ r = op === 'evidence' ? await tasks.addEvidence(id, sessionId) : await tasks.removeEvidence(id, sessionId);
85
+ }
86
+ else if (op === 'assign' || op === 'unassign') {
87
+ const id = req(a, 'TASK_ID'), sessionId = req(a, 'AGENT_SESSION_ID');
88
+ assertNoUnknownOptions(a);
89
+ r = op === 'assign' ? await tasks.assignAgent(id, sessionId) : await tasks.unassignAgent(id, sessionId);
90
+ }
91
+ else if (op === 'schedule' || op === 'unschedule') {
92
+ const id = req(a, 'TASK_ID'), automationId = req(a, 'AUTOMATION_ID');
93
+ assertNoUnknownOptions(a);
94
+ r = op === 'schedule' ? await tasks.attachSchedule(id, automationId) : await tasks.detachSchedule(id, automationId);
95
+ }
96
+ else
97
+ throw new Error(`Unsupported tasks operation: ${op}`); writeValue(ctx, clean(r)); return 0; }
98
+ export async function runMemoryCommand(ctx, args0) { const a = [...args0], op = a.shift() ?? 'list'; const memory = createMemoryFacade({ projectRoot: ctx.projectRoot, paths: ctx.paths, repoRoot: ctx.repoRoot }); let r; if (op === 'list') {
99
+ assertNoUnknownOptions(a);
100
+ const x = await memory.list();
101
+ r = x.state === 'ready' ? x.legacyRows : x;
102
+ }
103
+ else if (op === 'search') {
104
+ const query = req(a, 'QUERY');
105
+ assertNoUnknownOptions(a);
106
+ const x = await memory.search(query);
107
+ r = x.state === 'ready' ? x.legacy : x;
108
+ }
109
+ else if (op === 'add') {
110
+ const title = req(a, 'TITLE'), content = req(a, 'CONTENT'), kind = (takeOption(a, '--kind') ?? 'preference');
111
+ assertNoUnknownOptions(a);
112
+ r = (await memory.add({ title, content, kind })).legacy;
113
+ }
114
+ else if (op === 'update') {
115
+ const id = req(a, 'ID'), title = takeOption(a, '--title'), content = takeOption(a, '--content'), kind = takeOption(a, '--kind');
116
+ assertNoUnknownOptions(a);
117
+ r = (await memory.update(id, { ...(title !== undefined ? { title } : {}), ...(content !== undefined ? { content } : {}), ...(kind !== undefined ? { kind } : {}) })).legacy;
118
+ }
119
+ else if (op === 'delete') {
120
+ const id = req(a, 'ID');
121
+ assertNoUnknownOptions(a);
122
+ r = (await memory.delete(id)).legacy;
123
+ }
124
+ else
125
+ throw new Error(`Unsupported memory operation: ${op}`); writeValue(ctx, clean(r)); return 0; }
126
+ export async function runLibraryCommand(ctx, args0) { const a = [...args0], op = a.shift() ?? 'list'; const library = createLibraryFacade({ projectRoot: ctx.projectRoot, paths: ctx.paths, repoRoot: ctx.repoRoot }); let r; if (op === 'list') {
127
+ assertNoUnknownOptions(a);
128
+ const x = await library.list();
129
+ r = x.state === 'ready' ? x.legacyRows : x;
130
+ }
131
+ else if (op === 'search') {
132
+ const query = req(a, 'QUERY');
133
+ assertNoUnknownOptions(a);
134
+ r = (await library.search(query)).legacy;
135
+ }
136
+ else if (op === 'read') {
137
+ const id = req(a, 'ID');
138
+ assertNoUnknownOptions(a);
139
+ r = (await library.read(id)).legacy;
140
+ }
141
+ else if (op === 'preview') {
142
+ const id = req(a, 'ID');
143
+ assertNoUnknownOptions(a);
144
+ r = await library.preview(id);
145
+ }
146
+ else if (op === 'duplicates') {
147
+ const id = req(a, 'ID');
148
+ assertNoUnknownOptions(a);
149
+ r = await library.duplicates(id);
150
+ }
151
+ else if (op === 'context-ref') {
152
+ const id = req(a, 'ID');
153
+ assertNoUnknownOptions(a);
154
+ r = await library.prepareContextReference(id);
155
+ }
156
+ else if (op === 'import') {
157
+ const file = req(a, 'FILE');
158
+ assertNoUnknownOptions(a);
159
+ r = await library.importFile(file);
160
+ }
161
+ else if (op === 'export') {
162
+ const id = req(a, 'ID'), out = takeOption(a, '--out');
163
+ assertNoUnknownOptions(a);
164
+ if (!out)
165
+ throw new Error('LIBRARY_EXPORT_OUT_REQUIRED');
166
+ r = (await library.exportFile(id, out)).legacy;
167
+ }
168
+ else if (op === 'rename') {
169
+ const id = req(a, 'ID'), name = req(a, 'NAME');
170
+ assertNoUnknownOptions(a);
171
+ r = (await library.rename(id, name)).legacy;
172
+ }
173
+ else if (op === 'delete') {
174
+ const id = req(a, 'ID');
175
+ assertNoUnknownOptions(a);
176
+ r = (await library.delete(id)).legacy;
177
+ }
178
+ else
179
+ throw new Error(`Unsupported library operation: ${op}`); writeValue(ctx, clean(r)); return 0; }
180
+ export async function runForgeCommand(ctx, args0) {
181
+ const a = [...args0], op = a.shift() ?? 'list', forgeRoot = join(ctx.paths.dataRoot, 'forge');
182
+ const base = createForgeFacade({ forgeRoot, repoRoot: ctx.repoRoot });
183
+ let r;
184
+ const packageFrom = async () => JSON.parse(await readFile(req(a, 'PACKAGE_FILE'), 'utf8'));
185
+ const owner = async (sessionId) => { const rc = await ctx.createRuntimeContext({ projectRoot: ctx.projectRoot, paths: ctx.paths, repoRoot: ctx.repoRoot, model: ctx.invocation.model ?? 'openai:gpt-5-mini', environmentKeys: 'consent' }); await rc.registry?.ripristina?.(); return createForgeFacade({ forgeRoot, repoRoot: ctx.repoRoot }, { registry: rc.registry }); };
186
+ if (op === 'list') {
187
+ assertNoUnknownOptions(a);
188
+ const x = await base.list();
189
+ r = x.state === 'ready' ? x.rows : x;
190
+ }
191
+ else if (op === 'inspect') {
192
+ const id = req(a, 'ID');
193
+ assertNoUnknownOptions(a);
194
+ r = await base.read(id);
195
+ }
196
+ else if (op === 'validate') {
197
+ const pkg = await packageFrom();
198
+ assertNoUnknownOptions(a);
199
+ r = base.validatePackage(pkg);
200
+ }
201
+ else if (op === 'scan') {
202
+ const pkg = await packageFrom();
203
+ assertNoUnknownOptions(a);
204
+ r = await base.scanPackage(pkg);
205
+ }
206
+ else if (op === 'simulate') {
207
+ const pkg = await packageFrom();
208
+ assertNoUnknownOptions(a);
209
+ r = await base.analyzePackage(pkg);
210
+ }
211
+ else if (op === 'install') {
212
+ const session = takeOption(a, '--session'), pkg = await packageFrom();
213
+ assertNoUnknownOptions(a);
214
+ if (!session)
215
+ throw new Error('FORGE_SESSION_REQUIRED');
216
+ r = await (await owner(session)).installPackage(session, pkg);
217
+ }
218
+ else if (op === 'versions') {
219
+ const id = req(a, 'ID'), session = takeOption(a, '--session');
220
+ assertNoUnknownOptions(a);
221
+ if (!session)
222
+ throw new Error('FORGE_SESSION_REQUIRED');
223
+ r = await (await owner(session)).versions(session, id);
224
+ }
225
+ else if (op === 'rollback') {
226
+ const id = req(a, 'ID'), revision = Number(req(a, 'REVISION')), session = takeOption(a, '--session');
227
+ assertNoUnknownOptions(a);
228
+ if (!Number.isSafeInteger(revision) || revision < 1)
229
+ throw new Error('FORGE_REVISION_INVALID');
230
+ if (!session)
231
+ throw new Error('FORGE_SESSION_REQUIRED');
232
+ r = await (await owner(session)).rollback(session, id, revision);
233
+ }
234
+ else if (op === 'enable' || op === 'disable') {
235
+ const id = req(a, 'ID'), session = takeOption(a, '--session');
236
+ assertNoUnknownOptions(a);
237
+ if (session)
238
+ r = await (await owner(session)).setEnabled(session, id, op === 'enable');
239
+ else {
240
+ const m = await importTalosModule(ctx.repoRoot, 'tool-forge-store.mjs');
241
+ r = await m.abilitaToolForgiato({ cartella: forgeRoot, id, abilitato: op === 'enable' });
242
+ }
243
+ }
244
+ else
245
+ throw new Error(`Unsupported forge operation: ${op}`);
246
+ writeValue(ctx, clean(r));
247
+ return 0;
248
+ }
@@ -0,0 +1,171 @@
1
+ import { chmod, mkdir, readFile, stat, writeFile } from 'node:fs/promises';
2
+ import { dirname, join, resolve } from 'node:path';
3
+ import { deleteSessionToolOutput } from "../runtime/output-store.js";
4
+ import { exportMarkdown } from "../sessions/export-format.js";
5
+ import { t } from "../i18n/index.js";
6
+ import { secretValuesFromEnvironment } from "../diagnostics/redact.js";
7
+ import { assertNoUnknownOptions, takeOption, writeValue } from "./context.js";
8
+ import { importTalosModule } from "../runtime/repo.js";
9
+ import { keyOriginForEntry, stateKeyOrigin } from "../provider/environment-keys.js";
10
+ import { createSessionMetadataStore, sessionMetadataRoot } from "../sessions/metadata-store.js";
11
+ import { buildSafeSessionShare, writeSafeSessionShare } from "../sessions/share.js";
12
+ /* B1 slice 18: the entry decides. Resuming runs a model, so an environment key is used without asking and its origin is stated; reading sessions asks. */
13
+ async function rc(ctx, environmentKeys) { const c = await ctx.createRuntimeContext({ projectRoot: ctx.projectRoot, paths: ctx.paths, repoRoot: ctx.repoRoot, model: ctx.invocation.model ?? 'openai:gpt-5-mini', environmentKeys }); if (typeof c.runtime?.restore === 'function')
14
+ await c.runtime.restore();
15
+ else
16
+ await c.registry.ripristina?.(); return c; }
17
+ async function sessionSummaries(c) { if (typeof c.runtime?.listSessions === 'function')
18
+ return c.runtime.listSessions(); const { normalizeSessionSummaries } = await import("../runtime/session-summary.js"); return normalizeSessionSummaries(c.registry.elenca?.() ?? []); }
19
+ function metadataStore(ctx) { return createSessionMetadataStore({ rootDir: sessionMetadataRoot(ctx.paths.dataRoot) }); }
20
+ async function summariesWithMetadata(ctx, c) { const store = metadataStore(ctx); const rows = await sessionSummaries(c); return Promise.all(rows.map(async (row) => { const metadata = await store.get(row.id ?? row.sessionId); return { ...row, ...(metadata?.name ? { name: metadata.name } : {}), tags: metadata?.tags ?? [], pinned: metadata?.pinned ?? false }; })); }
21
+ function matchesSearch(row, query) { const q = query.trim().toLowerCase(); return [row.id, row.sessionId, row.name, row.project, ...(Array.isArray(row.tags) ? row.tags : [])].some(value => typeof value === 'string' && value.toLowerCase().includes(q)); }
22
+ async function requireSession(c, id) { const row = (await sessionSummaries(c)).find((x) => x.id === id || x.sessionId === id); if (!row)
23
+ throw new Error('SESSION_NOT_FOUND'); return row; }
24
+ /* R5b D1 (Q-R5-12): the Markdown export is sessions/export-format.ts, shared with the TUI's /export. */
25
+ async function writeExport(out, format, payload) { await mkdir(dirname(resolve(out)), { recursive: true }); let body; if (format === 'json')
26
+ body = `${JSON.stringify(payload, null, 2)}\n`;
27
+ else if (format === 'jsonl')
28
+ body = (payload.eventi ?? []).map((e) => JSON.stringify(e)).join('\n') + ((payload.eventi ?? []).length ? '\n' : '');
29
+ else if (format === 'md')
30
+ body = exportMarkdown(payload, { secrets: secretValuesFromEnvironment(process.env) });
31
+ else
32
+ throw new Error('SESSION_EXPORT_FORMAT_INVALID'); await writeFile(out, body, { encoding: 'utf8', mode: 0o600 }); try {
33
+ await chmod(resolve(out), 0o600);
34
+ }
35
+ catch (error) {
36
+ if (process.platform !== 'win32')
37
+ throw error;
38
+ } }
39
+ export async function runSessionCommand(ctx, args0) { const args = [...args0]; const op = args.shift() ?? 'list'; const c = await rc(ctx, op === 'resume' ? 'use' : 'consent'); const registry = c.registry; if (op === 'list') {
40
+ assertNoUnknownOptions(args);
41
+ writeValue(ctx, await summariesWithMetadata(ctx, c));
42
+ return 0;
43
+ } if (op === 'search') {
44
+ const query = args.join(' ').trim();
45
+ if (!query)
46
+ throw new Error('SESSION_SEARCH_QUERY_REQUIRED');
47
+ writeValue(ctx, (await summariesWithMetadata(ctx, c)).filter((row) => matchesSearch(row, query)));
48
+ return 0;
49
+ } const id = args.shift(); if (!id && op !== 'import')
50
+ throw new Error('SESSION_ID_REQUIRED'); if (op === 'tag' || op === 'untag' || op === 'pin' || op === 'unpin') {
51
+ await requireSession(c, id);
52
+ const store = metadataStore(ctx);
53
+ let metadata;
54
+ if (op === 'tag' || op === 'untag') {
55
+ const tag = args.join(' ');
56
+ if (!tag.trim())
57
+ throw new Error('SESSION_TAG_REQUIRED');
58
+ metadata = op === 'tag' ? await store.addTag(id, tag) : await store.removeTag(id, tag);
59
+ }
60
+ else {
61
+ assertNoUnknownOptions(args);
62
+ metadata = await store.setPinned(id, op === 'pin');
63
+ }
64
+ writeValue(ctx, { ok: true, sessionId: id, tags: metadata.tags, pinned: metadata.pinned });
65
+ return 0;
66
+ } /* R5b D2 (Q-R5-12): the same name as the TUI's /rename; no name clears it. */ /* R5b D2 (Q-R5-12): the same name as the TUI's /rename; no name clears it. */ if (op === 'rename') {
67
+ await requireSession(c, id);
68
+ const name = args.join(' ').trim();
69
+ const metadata = await metadataStore(ctx).setName(id, name ? name : null);
70
+ writeValue(ctx, { ok: true, sessionId: id, name: metadata.name ?? null }, `${metadata.name ? t('screen.session.renamedCli', { id: String(id), name: metadata.name }) : t('screen.session.nameClearedCli', { id: String(id) })}\n`);
71
+ return 0;
72
+ } if (op === 'context') {
73
+ assertNoUnknownOptions(args);
74
+ await requireSession(c, id);
75
+ if (typeof c.runtime?.contextStatus !== 'function')
76
+ throw new Error('SESSION_CONTEXT_UNAVAILABLE');
77
+ writeValue(ctx, await c.runtime.contextStatus(id));
78
+ return 0;
79
+ } if (op === 'show') {
80
+ assertNoUnknownOptions(args);
81
+ const row = (await summariesWithMetadata(ctx, c)).find((x) => x.id === id || x.sessionId === id);
82
+ if (!row)
83
+ throw new Error('SESSION_NOT_FOUND');
84
+ const payload = registry.esporta?.(id);
85
+ writeValue(ctx, { ...row, eventCount: payload?.eventi?.length ?? 0 });
86
+ return 0;
87
+ } if (op === 'fork') {
88
+ assertNoUnknownOptions(args);
89
+ const x = registry.forka(id);
90
+ if (x?.erroreAvvio)
91
+ throw Object.assign(new Error(x.erroreAvvio), { code: x.code });
92
+ writeValue(ctx, { sessionId: x.sessionId, forkedFrom: id }, `${x.sessionId}\n`);
93
+ return 0;
94
+ } if (op === 'resume') {
95
+ const prompt = args.length ? args.join(' ') : undefined;
96
+ const sessionModel = (await sessionSummaries(c)).find((x) => x.id === id || x.sessionId === id)?.model;
97
+ const origin = prompt?.trim() ? stateKeyOrigin(ctx.io, ctx.invocation.outputFormat, keyOriginForEntry(c.runtime, typeof sessionModel === 'string' && sessionModel ? sessionModel : ctx.invocation.model ?? 'openai:gpt-5-mini', { refuseMissing: true })) : {};
98
+ const sid = await c.runtime.resume(id, prompt);
99
+ writeValue(ctx, { sessionId: sid, resumed: true, ...origin }, `${sid}\n`);
100
+ return 0;
101
+ } if (op === 'share') {
102
+ const out = takeOption(args, '--out');
103
+ assertNoUnknownOptions(args);
104
+ if (!out)
105
+ throw new Error('SESSION_SHARE_OUT_REQUIRED');
106
+ const row = await requireSession(c, id);
107
+ const payload = registry.esporta?.(id);
108
+ if (!payload)
109
+ throw new Error('SESSION_NOT_FOUND');
110
+ const store = metadataStore(ctx);
111
+ const metadata = await store.get(id);
112
+ const share = buildSafeSessionShare({ summary: row, metadata, payload, secrets: secretValuesFromEnvironment(process.env) });
113
+ await writeSafeSessionShare(out, share);
114
+ writeValue(ctx, { ok: true, sessionId: id, schema: share.schema, redacted: true, out: resolve(out) }, `Shared redacted ${id} to ${out}\n`);
115
+ return 0;
116
+ } if (op === 'export') {
117
+ const format = takeOption(args, '--format') ?? 'json';
118
+ const out = takeOption(args, '--out');
119
+ assertNoUnknownOptions(args);
120
+ if (!out)
121
+ throw new Error('SESSION_EXPORT_OUT_REQUIRED');
122
+ const payload = registry.esporta?.(id);
123
+ if (!payload)
124
+ throw new Error('SESSION_NOT_FOUND');
125
+ await writeExport(out, format, payload);
126
+ writeValue(ctx, { ok: true, sessionId: id, format, out: resolve(out) }, `Exported ${id} to ${out}\n`);
127
+ return 0;
128
+ } if (op === 'delete') {
129
+ assertNoUnknownOptions(args);
130
+ const sm = await importTalosModule(ctx.repoRoot, 'session-store.mjs');
131
+ await sm.eliminaSessionePersistita({ cartellaStore: ctx.paths.sessionsRoot, sessionId: id }); /* R5a E6 (Q-R5-10): the session's kept command outputs go with it. */
132
+ await deleteSessionToolOutput(ctx.paths.dataRoot, String(id));
133
+ writeValue(ctx, { ok: true, sessionId: id }, `Deleted ${id}\n`);
134
+ return 0;
135
+ } if (op === 'import') {
136
+ const file = id ?? args.shift();
137
+ if (!file)
138
+ throw new Error('SESSION_IMPORT_FILE_REQUIRED');
139
+ assertNoUnknownOptions(args);
140
+ let info;
141
+ try {
142
+ info = await stat(file);
143
+ }
144
+ catch {
145
+ throw new Error('SESSION_IMPORT_INVALID');
146
+ }
147
+ if (!info.isFile() || info.size > 256 * 1024 * 1024)
148
+ throw new Error('SESSION_IMPORT_INVALID');
149
+ let data;
150
+ try {
151
+ data = JSON.parse(await readFile(file, 'utf8'));
152
+ }
153
+ catch {
154
+ throw new Error('SESSION_IMPORT_INVALID');
155
+ }
156
+ const sourceSchema = data?.schema ?? data?.header?.schema;
157
+ if (sourceSchema !== 'talos.harness-ui.session-export.v1' && sourceSchema !== 'talos.cli.session.v1')
158
+ throw new Error('SESSION_SCHEMA_UNSUPPORTED');
159
+ const rawEvents = data.eventi ?? data.events ?? [];
160
+ if (!Array.isArray(rawEvents))
161
+ throw new Error('SESSION_IMPORT_INVALID');
162
+ const safeEvents = rawEvents.filter((e) => e && typeof e === 'object' && e.type !== 'ApprovalRequested');
163
+ const importId = String(data.sessionId ?? data.header?.sessionId ?? 'imported');
164
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(importId) || importId.includes('..'))
165
+ throw new Error('SESSION_IMPORT_ID_INVALID');
166
+ const target = join(ctx.paths.dataRoot, 'imports', `${importId}.json`);
167
+ await mkdir(dirname(target), { recursive: true });
168
+ await writeFile(target, `${JSON.stringify({ ...data, eventi: safeEvents, events: undefined, sourceSchema, importedBy: 'talos-cli', importedAt: new Date().toISOString() }, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
169
+ writeValue(ctx, { ok: true, sessionId: importId, file: target, pendingApprovalsDropped: rawEvents.length - safeEvents.length, runnable: false }, `Imported archive ${importId}\n`);
170
+ return 0;
171
+ } throw new Error(`Unsupported session operation: ${op}`); }