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,139 @@
1
+ /*
2
+ * R2 lane E (gate E4, E5, E15): the kernel's identifiers → the CLI's English. The kernel is not edited in R2 (Q-R2-8), and it
3
+ * speaks Italian; what crosses into the CLI and is stable is mapped here and nowhere else.
4
+ *
5
+ * ⛔ Two exact-text tables exist because the kernel DROPS the structured fields at the RunError boundary: the public
6
+ * provider error carries `classe`/`stato` (`runtime-owner-adapter.mjs:717-727`), but `agent-service.mjs:1991` forwards only
7
+ * `{message, code}`, so the CLI sees `PROVIDER_REQUEST_ERROR` plus one of eight fixed sentences. Those sentences are kernel
8
+ * CONSTANTS, compared whole (never searched for a word), and `test/i18n/errors-view.test.ts` pins every one of them
9
+ * against the kernel source, as `brokered-executor.ts` pins its three markers: a reworded kernel turns the test red
10
+ * instead of silently falling back to the generic words.
11
+ */
12
+ import { t, tn } from "./index.js";
13
+ /** `erroreFornitorePubblico` (runtime-owner-adapter.mjs:718-725): the eight public sentences and the class each one names. */
14
+ export const KERNEL_PROVIDER_MESSAGES = Object.freeze({
15
+ 'Troppo traffico presso il fornitore.': 'rate-limited',
16
+ 'Credenziale rifiutata dal fornitore.': 'credential',
17
+ 'Credito non disponibile presso il fornitore.': 'credit',
18
+ 'Connessione con il fornitore interrotta.': 'network',
19
+ 'Il fornitore ha superato il tempo massimo.': 'timeout',
20
+ 'Il fornitore non risponde.': 'server-error',
21
+ 'La risposta del fornitore si è interrotta.': 'stream-cut',
22
+ 'Il fornitore non ha accettato la richiesta.': 'not-accepted',
23
+ });
24
+ /** The kernel's `classe` values (research-orchestrator.mjs `classificaErroreDiCorsa`), for errors that still carry them. */
25
+ export const KERNEL_CLASSES = Object.freeze({
26
+ traffico: 'rate-limited', credenziale: 'credential', credito: 'credit', rete: 'network', 'timeout-fornitore': 'timeout',
27
+ 'guasto-fornitore': 'server-error', 'flusso-interrotto': 'stream-cut', 'richiesta-non-valida': 'not-accepted', contesto: 'context', ignoto: 'not-accepted',
28
+ });
29
+ /** Transport codes the kernel names itself (runtime-owner-adapter.mjs:769-774, :705) and Node's undici codes. */
30
+ export const TRANSPORT_CODES = Object.freeze({
31
+ PROVIDER_NETWORK_ERROR: 'network', PROVIDER_SILENCE: 'network', UND_ERR_BODY_TIMEOUT: 'network', UND_ERR_SOCKET: 'network',
32
+ ECONNRESET: 'network', ECONNREFUSED: 'network', ENOTFOUND: 'network', EAI_AGAIN: 'network',
33
+ PROVIDER_FIRST_RESPONSE_TIMEOUT: 'timeout', UND_ERR_HEADERS_TIMEOUT: 'timeout', UND_ERR_CONNECT_TIMEOUT: 'timeout',
34
+ });
35
+ /** RunError codes that are task OUTCOMES (agent-service.mjs:160-185), not service failures. */
36
+ export const RUN_OUTCOMES = Object.freeze({ fermato: 'stopped', 'giri-esauriti': 'turns-exhausted', ripetizione: 'repetition', 'premesse-negate': 'premise-denied' });
37
+ /** The kernel's lowercase outcome codes are Italian words; the screen shows these English codes instead (D-05). The JSON
38
+ * envelope keeps the kernel's code unchanged (v1 frozen, gate E11). */
39
+ export const DISPLAY_CODES = Object.freeze({
40
+ fermato: 'INTERRUPTED', 'giri-esauriti': 'TURNS_EXHAUSTED', ripetizione: 'REPEATED_TOOL_CALL', 'premesse-negate': 'PREMISE_DENIED', 'internal-error': 'INTERNAL_ERROR',
41
+ /* Kernel codes spelled in Italian (plugin-registry.mjs:460-665, http-app.mjs:89-90): a code on screen is a word on screen. */
42
+ PLUGIN_COMANDO_ESEGUE_CODICE: 'PLUGIN_COMMAND_RUNS_CODE', PLUGIN_COMANDO_FUORI_DAL_PACCHETTO: 'PLUGIN_COMMAND_OUTSIDE_PACKAGE',
43
+ PLUGIN_COMANDO_NON_LEGGIBILE: 'PLUGIN_COMMAND_UNREADABLE', PLUGIN_ID_AMBIGUO: 'PLUGIN_ID_AMBIGUOUS', DOVE_NON_VALIDO: 'LOCATION_INVALID',
44
+ SCELTA_NON_VALIDA: 'CHOICE_INVALID',
45
+ });
46
+ /** Kernel run texts compared whole. `fermato` covers both the person's stop and a generation that stopped by itself
47
+ * (talosHarness.mjs:1472 vs :10207); only this constant tells the second apart. */
48
+ export const KERNEL_RUN_TEXT = Object.freeze({
49
+ stoppedWithoutAnswer: '⛔ la generazione si e fermata senza risposta e senza esaurire i giri.',
50
+ });
51
+ /*
52
+ * Kernel notices sent as a whole assistant chat message, not as an event with a code (`agent-service.mjs:1926-1930`
53
+ * `onAvviso`, `:1938-1940` provider switch): `runtime-owner-adapter.mjs:857, 968-969`. Matched only as the WHOLE message
54
+ * against the kernel template (anchored, the provider labels as the only variables), pinned by errors-view.test.ts; a
55
+ * model's own answer in Italian never matches and is never rewritten.
56
+ */
57
+ export const KERNEL_NOTICES = Object.freeze([
58
+ { pattern: /^Una chiave di (?<provider>.+?) è stata rifiutata: controlla Fornitori e accessi\.$/u, id: 'error.notice.keyRefused', fragment: 'è stata rifiutata: controlla Fornitori e accessi.' },
59
+ { pattern: /^Il fornitore (?<from>.+?) limita il traffico: continuo con (?<to>.+?) · modello (?<model>.+)$/u, id: 'error.notice.switchRateLimited', fragment: 'limita il traffico: continuo con' },
60
+ { pattern: /^Il fornitore (?<from>.+?) non risponde: continuo con (?<to>.+?) · modello (?<model>.+)$/u, id: 'error.notice.switchNotAnswering', fragment: 'non risponde: continuo con' },
61
+ ]);
62
+ /** Permission `via` of a refused tool receipt (talosHarness.mjs:6512-8597) → the dictionary id of its English. The five
63
+ * "asked" vias (`viaRichiesta`, :6608) refused mean the person said no. */
64
+ export const REFUSAL_VIA = Object.freeze({
65
+ 'segreto-forza-conferma': 'notApproved', 'attrezzo-sempre-da-confermare': 'notApproved', 'trifecta-forza-conferma': 'notApproved',
66
+ 'livello-su-richiesta': 'notApproved', 'permesso-per-attrezzo-chiedi': 'notApproved',
67
+ 'permesso-per-attrezzo-nega': 'toolOff', 'livello-lettura': 'readOnly', 'livello-ricerca': 'research', 'livello-scrittura-area': 'workspaceWrite',
68
+ 'fermato-su-richiesta': 'stopped', 'floor-comando-senza-recupero': 'noRecovery', 'pre-mutation-guard': 'checkpoint',
69
+ });
70
+ export const KERNEL_REFUSAL_REASONS = Object.freeze([
71
+ { pattern: /^l'owner non ha approvato questa azione\.$/u, id: 'error.refusalReason.notApproved', fragment: "motivo: 'l\\'owner non ha approvato questa azione.'" },
72
+ { pattern: /^la sessione è in sola lettura: nessuna scrittura, comando o documento è permesso in questo momento\.$/u, id: 'error.refusalReason.readOnly', fragment: "la sessione è in sola lettura: nessuna scrittura, comando o documento è permesso in questo momento." },
73
+ { pattern: /^l'attrezzo "(?<tool>[^"]+)" è disattivato per questa sessione \(permesso per-attrezzo: nega\)\.$/u, id: 'error.refusalReason.toolOff', fragment: '" è disattivato per questa sessione (permesso per-attrezzo: nega).' },
74
+ { pattern: /^questa è una ricerca approfondita: può leggere, cercare e navigare, ma l'unica scrittura permessa è il deposito del proprio rapporto con "research_deposit" — "(?<tool>[^"]+)" resta negato\.$/u, id: 'error.refusalReason.research', fragment: `questa è una ricerca approfondita: può leggere, cercare e navigare, ma l'unica scrittura permessa è il deposito del proprio rapporto con "research_deposit" — "` },
75
+ { pattern: /^il rapporto di una ricerca si deposita solo nella cartella di quella ricerca: "(?<path>[^"]*)" non ci risolve dentro\.$/u, id: 'error.refusalReason.researchPath', fragment: 'il rapporto di una ricerca si deposita solo nella cartella di quella ricerca: "' },
76
+ { pattern: /^la sessione è limitata alla scrittura nel workspace: "(?<tool>[^"]+)" resta negato \(solo "scrivi" e "file_edit", che portano un percorso verificabile, sono ammessi a questo livello\)\.$/u, id: 'error.refusalReason.workspaceTool', fragment: '" resta negato (solo "scrivi" e "file_edit", che portano un percorso verificabile, sono ammessi a questo livello).' },
77
+ { pattern: /^"(?<path>[^"]*)" non risolve dentro il workspace corrente: la sessione è limitata alla scrittura nel workspace\.$/u, id: 'error.refusalReason.workspacePath', fragment: '" non risolve dentro il workspace corrente: la sessione è limitata alla scrittura nel workspace.' },
78
+ { pattern: /^l'attrezzo "(?<tool>[^"]+)" richiede approvazione \(.+\), ma questa sessione non ha un canale di approvazione attivo\.$/u, id: 'error.refusalReason.noChannel', fragment: '), ma questa sessione non ha un canale di approvazione attivo.' },
79
+ { pattern: /^fermato su richiesta mentre aspettavo la tua approvazione per "(?<tool>[^"]+)"\.$/u, id: 'error.refusalReason.stoppedAsking', fragment: "const MOTIVO_FERMATO_CHIEDENDO = 'fermato su richiesta mentre aspettavo la tua approvazione'" },
80
+ ]);
81
+ /*
82
+ * The display guard of Q-R2-2: a message with no mapping may appear on the default lines ONLY when it is not kernel prose.
83
+ * The kernel writes Italian; the CLI writes English. This decides nothing about MEANING (that is the code's job, E4): it only
84
+ * keeps an untranslated sentence off the screen, where D-05 forbids it, and sends it to `raw` (expanded detail and the log).
85
+ * One Italian-only word (`è` included) or two short Italian function words mark it; English words that look alike
86
+ * ("non-interactive", "per request") are not in either list. An accent alone does not: "café" or a name is not Italian.
87
+ */
88
+ const ITALIAN_ONLY = new Set([
89
+ 'della', 'delle', 'dello', 'degli', 'nella', 'nelle', 'nello', 'negli', 'dalla', 'dalle', 'questo', 'questa', 'questi', 'queste', 'nessun', 'nessuna',
90
+ 'nessuno', 'fornitore', 'fornitori', 'chiave', 'chiavi', 'richiesta', 'sessione', 'giro', 'giri', 'attrezzo', 'attrezzi', 'modello', 'modelli',
91
+ 'cartella', 'percorso', 'comando', 'interrotto', 'interrotta', 'rifiutata', 'rifiutato', 'approvato', 'agente', 'esterno', 'esterna', 'sono',
92
+ 'manca', 'mancano', 'controlla', 'riprova', 'inserisci', 'trovato', 'trovata', 'valido', 'valida', 'raggiungere', 'risposta', 'disponibile',
93
+ 'impossibile', 'errore', 'ancora', 'anche', 'ambiguo', 'ambigua', 'scelta', 'fuori', 'pacchetto', 'leggibile', 'codice', 'esegue', 'perché', 'quando', 'dopo', 'prima', 'ogni', 'senza', 'traffico', 'credenziale', 'catalogo', 'è', 'già', 'può', 'più',
94
+ /* CE alignment (2026-09-25): the Context Engine's own words; «Preparazione del contesto non riuscita.» passed as English. */
95
+ 'contesto', 'preparazione', 'riuscita', 'riuscito', 'sintesi', 'compattazione', 'compattare', 'finestra',
96
+ ]);
97
+ const ITALIAN_SHORT = new Set(['il', 'lo', 'la', 'le', 'gli', 'di', 'del', 'al', 'alla', 'che', 'una', 'uno', 'con', 'ha', 'hai', 'sei', 'è', 'e']);
98
+ export function looksItalian(text) {
99
+ const value = String(text);
100
+ const words = value.toLowerCase().split(/[^\p{L}']+/u).map(word => word.replace(/^(?:l|un|dell|all|nell|dall|sull)'/u, '')).filter(Boolean);
101
+ if (words.some(word => ITALIAN_ONLY.has(word)))
102
+ return true;
103
+ return words.filter(word => ITALIAN_SHORT.has(word) && word !== 'e').length >= 2;
104
+ }
105
+ export const KERNEL_PROBE_REASONS = Object.freeze([
106
+ { pattern: /^(?<provider>.+?): catalogo raggiunto, (?<count>\d+) modelli visibili nella prima pagina\. La generazione non è stata provata\.$/u, id: 'firstrun.probe.catalogFirstPage', plural: true, fragment: " nella prima pagina' : ''}. La generazione non è stata provata." },
107
+ { pattern: /^(?<provider>.+?): catalogo raggiunto, (?<count>\d+) modelli visibili\. La generazione non è stata provata\.$/u, id: 'firstrun.probe.catalog', plural: true, fragment: ': catalogo raggiunto, ' },
108
+ { pattern: /^(?<provider>.+?): catalogo pubblico raggiunto, (?<count>\d+) modelli visibili; chiave non verificata\. La generazione non è stata provata\.$/u, id: 'firstrun.probe.publicCatalog', plural: true, fragment: ' modelli visibili; chiave non verificata. La generazione non è stata provata.' },
109
+ { pattern: /^(?<provider>.+?): credenziale accettata\.$/u, id: 'firstrun.probe.keyAccepted', fragment: ': credenziale accettata.' },
110
+ { pattern: /^Non è stato possibile raggiungere (?<provider>.+?)\.$/u, id: 'firstrun.probe.unreachable', fragment: 'Non è stato possibile raggiungere ' },
111
+ { pattern: /^(?<provider>.+?): nessuna risposta entro (?<seconds>\d+) secondi\.$/u, id: 'firstrun.probe.timeout', fragment: ': nessuna risposta entro ' },
112
+ { pattern: /^(?<provider>.+?): la risposta rinvia a un altro indirizzo, e non lo seguiamo\. Controlla l'indirizzo impostato per questo fornitore\.$/u, id: 'firstrun.probe.redirect', fragment: ": la risposta rinvia a un altro indirizzo, e non lo seguiamo. Controlla l'indirizzo impostato per questo fornitore." },
113
+ { pattern: /^(?<provider>.+?) ha rifiutato la credenziale \(HTTP (?<status>\d+)\)\.$/u, id: 'firstrun.probe.keyRefused', fragment: ' ha rifiutato la credenziale (HTTP ' },
114
+ { pattern: /^(?<provider>.+?): credenziale non accettata \(HTTP 401\)\.$/u, id: 'firstrun.probe.keyNotAccepted', fragment: ': credenziale non accettata (HTTP 401).' },
115
+ { pattern: /^(?<provider>.+?): accesso negato \(HTTP 403\); controlla i permessi\.$/u, id: 'firstrun.probe.accessDenied', fragment: ': accesso negato (HTTP 403); controlla i permessi.' },
116
+ { pattern: /^(?<provider>.+?) ha risposto HTTP (?<status>\d+)\.$/u, id: 'firstrun.probe.httpStatus', fragment: ' ha risposto HTTP ' },
117
+ { pattern: /^(?<provider>.+?): elenco modelli non trovato \(HTTP 404\)\. La validità della chiave non è verificata da questa risposta\.$/u, id: 'firstrun.probe.listNotFound', fragment: ': elenco modelli non trovato (HTTP 404). La validità della chiave non è verificata da questa risposta.' },
118
+ { pattern: /^Manca l'indirizzo di (?<provider>.+?)\.$/u, id: 'firstrun.probe.noAddress', fragment: "Manca l'indirizzo di " },
119
+ { pattern: /^Nessuna chiave salvata per (?<provider>.+?)\.$/u, id: 'firstrun.probe.noKey', fragment: 'Nessuna chiave salvata per ' },
120
+ { pattern: /^(?<provider>.+?): richiesta minima di generazione riuscita; elenco modelli non verificato\.$/u, id: 'firstrun.probe.minimalOk', fragment: ': richiesta minima di generazione riuscita; elenco modelli non verificato.' },
121
+ { pattern: /^(?<provider>.+?): risposta HTTP (?<status>\d+) senza un elenco modelli valido; credenziale non verificata\.$/u, id: 'firstrun.probe.invalidList', fragment: ' senza un elenco modelli valido; credenziale non verificata.' },
122
+ { pattern: /^(?<provider>.+?): risposta HTTP (?<status>\d+) senza un messaggio valido; credenziale non verificata\.$/u, id: 'firstrun.probe.invalidMessage', fragment: ' senza un messaggio valido; credenziale non verificata.' },
123
+ { pattern: /^(?<provider>.+?): la risposta dichiara un errore, quindi la chiave non è confermata\.$/u, id: 'firstrun.probe.declaredError', fragment: ': la risposta dichiara un errore, quindi la chiave non è confermata.' },
124
+ ]);
125
+ /** The kernel probe's sentence in English, or null when no template matches it WHOLE (then nothing is printed). `label`, when
126
+ * given, replaces the kernel's label (the kernel's registry still has Italian labels, R2 §1.4). */
127
+ export function kernelProbeDetail(detail, { label } = {}) {
128
+ const text = String(detail ?? '').trim();
129
+ for (const row of KERNEL_PROBE_REASONS) {
130
+ const match = row.pattern.exec(text);
131
+ if (!match)
132
+ continue;
133
+ const groups = match.groups ?? {};
134
+ const provider = label ?? groups.provider ?? '';
135
+ const params = { provider, ...(groups.status ? { status: groups.status } : {}), ...(groups.seconds ? { seconds: groups.seconds } : {}) };
136
+ return row.plural ? tn(row.id, Number(groups.count), params) : t(`${row.id}`, params);
137
+ }
138
+ return null;
139
+ }
package/dist/io.js ADDED
@@ -0,0 +1,45 @@
1
+ export const MAX_STDIN_BYTES = 16 * 1024 * 1024;
2
+ export async function readStreamLimited(stream, maxBytes = MAX_STDIN_BYTES) {
3
+ const chunks = [];
4
+ let total = 0;
5
+ for await (const c of stream) {
6
+ const chunk = Buffer.isBuffer(c) ? c : Buffer.from(c);
7
+ total += chunk.byteLength;
8
+ if (total > maxBytes)
9
+ throw Object.assign(new Error(`STDIN_TOO_LARGE:${maxBytes}`), { code: 'STDIN_TOO_LARGE' });
10
+ chunks.push(chunk);
11
+ }
12
+ return Buffer.concat(chunks, total).toString('utf8');
13
+ }
14
+ async function readAllStdin() { return readStreamLimited(process.stdin); }
15
+ async function readSecretTty(prompt) { if (!process.stdin.isTTY || typeof process.stdin.setRawMode !== 'function')
16
+ throw new Error('SECRET_INPUT_REQUIRES_TTY'); process.stderr.write(prompt); return new Promise((resolve, reject) => { let value = ''; const done = (error) => { process.stdin.off('data', onData); try {
17
+ process.stdin.setRawMode(false);
18
+ }
19
+ catch { } process.stdin.pause(); process.stderr.write('\n'); if (error)
20
+ reject(error);
21
+ else
22
+ resolve(value); }; const onData = (buf) => { for (const b of buf) {
23
+ if (b === 3) {
24
+ done(Object.assign(new Error('INTERRUPTED'), { code: 'INTERRUPTED' }));
25
+ return;
26
+ }
27
+ if (b === 13 || b === 10) {
28
+ done();
29
+ return;
30
+ }
31
+ if (b === 8 || b === 127) {
32
+ value = value.slice(0, -1);
33
+ continue;
34
+ }
35
+ if (b >= 32)
36
+ value += Buffer.from([b]).toString('utf8');
37
+ } }; try {
38
+ process.stdin.setRawMode(true);
39
+ process.stdin.resume();
40
+ process.stdin.on('data', onData);
41
+ }
42
+ catch (e) {
43
+ done(e);
44
+ } }); }
45
+ export const stdio = { writeOut: s => process.stdout.write(s), writeErr: s => process.stderr.write(s), stdinIsTTY: Boolean(process.stdin.isTTY), stdoutIsTTY: Boolean(process.stdout.isTTY), readStdin: readAllStdin, readSecret: readSecretTty };
package/dist/main.js ADDED
@@ -0,0 +1,331 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { pathToFileURL } from 'node:url';
5
+ import { stdio } from "./io.js";
6
+ import { parseCliArgs } from "./args.js";
7
+ import { CLI_VERSION } from "./version.js";
8
+ import { resolveCliPaths, ensureCliPaths } from "./paths.js";
9
+ import { loadEffectiveConfig, readConfigScope } from "./config/load.js";
10
+ import { createSessionFacade } from "./runtime/session-facade.js";
11
+ import { collectHeadlessFork, collectHeadlessResume, collectHeadlessRun } from "./headless/run.js";
12
+ import { renderJson, renderText, exitCodeForResult, withRunWarnings } from "./headless/result.js";
13
+ import { createLocalAutoClassifier } from "./security/auto-classifier.js";
14
+ import { abortIsolationChecks, cliShellIsolation } from "./security/execution-backends.js";
15
+ import { inertTerminalText, renderSafeTalosFailure } from "./errors.js";
16
+ import { registerActiveRun } from "./runtime/active-run.js";
17
+ import { isFirstLaunch } from "./tui/launch-state.js"; /* P17: the first launch's trust question is step 1 of the setup */
18
+ import { initializeDevelopmentLogging, developmentLog, developmentLogError, closeDevelopmentLogging, developmentTextEvidence } from "./diagnostics/development-log.js";
19
+ import { assessProjectTrust, assertProjectTrusted, needsTrustQuestion, nestedRepositoriesForProjectTrust, projectTrustFailure, trustProjectAssessment } from "./security/project-trust-gate.js";
20
+ import { findTalosRepoRoot, importTalosModule } from "./runtime/repo.js";
21
+ import { providerOfModel } from "./provider/environment-keys.js";
22
+ import { assertValidKeymap } from "./tui/keymap-resolver.js";
23
+ import { createV2FailureEvent, createV2RunResultAccumulator, createV2SyntheticEvent, withV2RunWarnings } from "./protocol/v2/events.js";
24
+ import { encodeV2Event, encodeV2Result, exitCodeForV2Result } from "./protocol/v2/codec.js";
25
+ /* R3 Q-R3-8b: the first Ctrl+C of `talos -p` stops the run and lets it print a complete interrupted result (exit 130);
26
+ a second one exits at once with 130. Injected so tests never touch the real process signal. */
27
+ function defaultOnInterrupt(handler) { process.on('SIGINT', handler); return () => { process.off('SIGINT', handler); }; }
28
+ async function defaultCreateRuntime(x) { const { createCliRuntime } = await import("./runtime/create-runtime.js"); return createCliRuntime(x); }
29
+ async function defaultCreateRuntimeContext(x) { const { createCliRuntimeContext } = await import("./runtime/create-runtime.js"); return createCliRuntimeContext(x); }
30
+ async function defaultRunTui(x) { const { runInkTui } = await import("./tui/run.js"); return runInkTui(x); }
31
+ async function defaultPromptProjectTrust(x) { const { runProjectTrustPrompt } = await import("./tui/project-trust-prompt.js"); return runProjectTrustPrompt(x); }
32
+ /* R4 Q-R4-13 (`Loaded AGENTS.md`): the instruction files the kernel reads for this folder, found by the kernel's own function
33
+ (AGENTS.md or CLAUDE.md, one per folder, from the repository root down), named relative to that root. Read only after
34
+ trust is settled (E1); a failure only means nothing is announced. */
35
+ async function defaultLoadedFiles(projectRoot) {
36
+ const m = await importTalosModule(findTalosRepoRoot(process.cwd()), 'istruzioni-di-progetto.mjs');
37
+ const found = await m.trovaIstruzioniDiProgetto(projectRoot);
38
+ return Array.isArray(found) ? found.map((row) => String(row?.etichetta ?? '')).filter(Boolean) : [];
39
+ }
40
+ /* R4 Q-R4-1/2: which folder decision a choice saves. The home folder and a drive root save none (session only). */
41
+ function folderTargetFor(choice, assessment) {
42
+ if (assessment.folder?.sessionOnly)
43
+ return 'none';
44
+ return choice === 'trust-parent' ? 'parent' : 'this';
45
+ }
46
+ function help() { return `TALOS CLI ${CLI_VERSION}\nUsage:\n talos [prompt...]\n talos -p "prompt" [--json|--output-format stream-json]\n talos --resume <id|last> [-p "prompt"]\n talos --fork <id> [-p "prompt"]\n talos <project|config|provider|model|session|mcp|hook|plugin|command|memory|notes|tasks|library|research|automation|forge|checkpoint|doctor|logs|diagnostic|update|init> ...\n\nGlobal options:\n --project PATH --model PROVIDER:MODEL --permission-mode MODE\n --protocol v1|v2 --resume ID --fork ID --timeout SECONDS --verbose --no-color\n`; }
47
+ async function sessionId(runtime, id) { if (id !== 'last')
48
+ return id; const rows = await runtime.listSessions(); const first = rows.at(-1); if (!first?.sessionId)
49
+ throw Object.assign(new Error('SESSION_NOT_FOUND'), { code: 'SESSION_NOT_FOUND' }); return String(first.sessionId); }
50
+ function outputFormatHint(argv) {
51
+ let format = argv.includes('--json') ? 'json' : 'text';
52
+ for (let i = 0; i < argv.length; i++) {
53
+ const token = argv[i];
54
+ const inline = token.startsWith('--output-format=') ? token.slice('--output-format='.length) : undefined;
55
+ const value = inline ?? (token === '--output-format' ? argv[i + 1] : undefined);
56
+ if (value === 'text' || value === 'json' || value === 'stream-json')
57
+ format = value;
58
+ if (token === '--output-format')
59
+ i += 1;
60
+ }
61
+ return format;
62
+ }
63
+ function protocolVersionHint(argv) {
64
+ for (let i = 0; i < argv.length; i++) {
65
+ const token = argv[i];
66
+ const inline = token.startsWith('--protocol=') ? token.slice('--protocol='.length) : undefined;
67
+ const value = inline ?? (token === '--protocol' ? argv[i + 1] : undefined);
68
+ if (value === 'v2')
69
+ return 'v2';
70
+ if (token === '--protocol')
71
+ i += 1;
72
+ }
73
+ return 'v1';
74
+ }
75
+ function renderFailureForProtocol(format, protocolVersion, error, notices = [], verbose = false) {
76
+ if (protocolVersion === 'v2' && format !== 'text') {
77
+ const accumulator = createV2RunResultAccumulator();
78
+ const events = notices.map((notice, index) => createV2SyntheticEvent({
79
+ sessionId: '',
80
+ eventId: 'talos:none:config-notice:' + (index + 1),
81
+ type: 'warning',
82
+ data: { code: notice.code, message: notice.message }
83
+ }));
84
+ for (const event of events)
85
+ accumulator.add(event);
86
+ const failed = createV2FailureEvent({ sessionId: '', error, component: 'cli' });
87
+ accumulator.add(failed);
88
+ const result = accumulator.result();
89
+ return {
90
+ toStderr: false,
91
+ text: format === 'stream-json' ? [...events, failed].map(encodeV2Event).join('') : encodeV2Result(result),
92
+ exitCode: exitCodeForV2Result(result)
93
+ };
94
+ }
95
+ return renderSafeTalosFailure(format, error, { component: 'cli', notices, verbose }); /* R2 E6: trace id only with --verbose (or JSON) */
96
+ }
97
+ async function resolveReasoningDefault(catalog, model, configured) {
98
+ if (configured === undefined)
99
+ return { effort: null, notice: null };
100
+ if (!catalog || typeof catalog.listModels !== 'function')
101
+ return { effort: null, notice: { code: 'REASONING_EFFORT_CAPABILITY_UNKNOWN', message: `Configured reasoning effort "${configured}" was not applied because TALOS could not verify ${model} capabilities; using model default.` } };
102
+ try {
103
+ const provider = providerOfModel(model);
104
+ const rows = await catalog.listModels(provider ? { provider } : {});
105
+ const row = rows.find((candidate) => candidate?.id === model);
106
+ if (row?.reasoning === true && Array.isArray(row.reasoningEfforts) && row.reasoningEfforts.includes(configured))
107
+ return { effort: configured, notice: null };
108
+ return { effort: null, notice: { code: 'REASONING_EFFORT_UNSUPPORTED', message: `Configured reasoning effort "${configured}" is not affirmed for ${model}; using model default and sending no effort override.` } };
109
+ }
110
+ catch {
111
+ return { effort: null, notice: { code: 'REASONING_EFFORT_CAPABILITY_UNKNOWN', message: `Configured reasoning effort "${configured}" was not applied because ${model} capabilities could not be read; using model default.` } };
112
+ }
113
+ }
114
+ function configNoticeEvent(sessionId, seq, notice) { return { schema: 'talos.cli.event.v1', seq, ts: new Date().toISOString(), sessionId, type: 'warning', data: { code: notice.code, message: notice.message } }; }
115
+ function output(io, format, protocolVersion, collected) { if (format === 'json')
116
+ io.writeOut(protocolVersion === 'v2' ? encodeV2Result(collected.result) : renderJson(collected.result));
117
+ else if (format !== 'stream-json')
118
+ io.writeOut(renderText(collected.result)); return protocolVersion === 'v2' ? exitCodeForV2Result(collected.result) : exitCodeForResult(collected.result); }
119
+ /* R5b D4 (Q-R5-14): the trust question is drawn in the person's theme. It is asked before the folder is trusted, so only the
120
+ USER configuration is read here (migrated, as every read is); a theme in the folder's own config is not. Unreadable: Calm. */
121
+ async function userThemeForTrust(paths, projectRoot) {
122
+ try {
123
+ const theme = (await readConfigScope({ paths, projectRoot, scope: 'user' })).ui?.theme;
124
+ return theme ? { theme } : {};
125
+ }
126
+ catch {
127
+ return {};
128
+ }
129
+ }
130
+ export async function main(argv, deps = {}) {
131
+ const io = deps.io ?? stdio;
132
+ initializeDevelopmentLogging({ ...(process.env.TALOS_CLI_DEV_LOG_DIR ? { logDir: process.env.TALOS_CLI_DEV_LOG_DIR } : {}), argv, component: 'cli-main' });
133
+ developmentLog('cli.main.enter', { argv: argv.map(developmentTextEvidence) });
134
+ let inv;
135
+ try {
136
+ inv = parseCliArgs(argv);
137
+ }
138
+ catch (error) {
139
+ developmentLogError('cli.args.failure', error, { argv: argv.map(developmentTextEvidence) }, 'cli-main');
140
+ const format = outputFormatHint(argv);
141
+ const failure = renderFailureForProtocol(format, format === 'text' ? 'v1' : protocolVersionHint(argv), error);
142
+ if (failure.toStderr)
143
+ io.writeErr(failure.text);
144
+ else
145
+ io.writeOut(failure.text);
146
+ closeDevelopmentLogging({ exitCode: failure.exitCode, reason: 'args' });
147
+ return failure.exitCode;
148
+ }
149
+ if (inv.command === 'version') {
150
+ io.writeOut(`${CLI_VERSION}\n`);
151
+ closeDevelopmentLogging({ exitCode: 0, reason: 'version' });
152
+ return 0;
153
+ }
154
+ if (inv.command === 'help') {
155
+ io.writeOut(help());
156
+ closeDevelopmentLogging({ exitCode: 0, reason: 'help' });
157
+ return 0;
158
+ }
159
+ if (inv.command === 'subcommand') {
160
+ const { runSubcommand } = await import("./subcommands.js");
161
+ const code = await runSubcommand(inv, { io, createRuntimeContext: deps.createRuntimeContext ?? defaultCreateRuntimeContext });
162
+ closeDevelopmentLogging({ exitCode: code, reason: 'subcommand' });
163
+ return code;
164
+ }
165
+ let runtime = null;
166
+ let releaseActiveRun = null;
167
+ let releaseInterrupt = null;
168
+ let notices = [];
169
+ let noticesStreamed = false;
170
+ try {
171
+ const projectRoot = resolve(inv.project ?? process.cwd());
172
+ const paths = resolveCliPaths(process.env, process.platform, homedir());
173
+ await ensureCliPaths(paths);
174
+ initializeDevelopmentLogging({ paths, projectRoot, argv, component: 'cli-main' });
175
+ developmentLog('cli.paths.ready', { projectRoot, paths }, 'info', 'cli-main');
176
+ const interactive = inv.interactive && io.stdinIsTTY && io.stdoutIsTTY;
177
+ const injectedRuntime = Boolean(deps.createRuntime || deps.createRuntimeContext);
178
+ const trustInjected = Boolean(deps.assertProjectTrusted || deps.assessProjectTrust || deps.trustProjectAssessment || deps.promptProjectTrust);
179
+ if (trustInjected || !injectedRuntime) {
180
+ const trustInput = { projectRoot, trustRoot: paths.trust.projects };
181
+ if (interactive) {
182
+ const assessment = await (deps.assessProjectTrust ?? assessProjectTrust)(trustInput); /* R4 Q-R4-1: every folder with no saved decision is asked, with or without project files; headless keeps its rule (E3). */
183
+ if (needsTrustQuestion(assessment)) {
184
+ const nestedRepositories = await nestedRepositoriesForProjectTrust(assessment);
185
+ const choice = await (deps.promptProjectTrust ?? defaultPromptProjectTrust)({ assessment, nestedRepositories, color: inv.color !== false, ...await userThemeForTrust(paths, projectRoot), ...(isFirstLaunch(paths.dataRoot) ? { setupStep: true } : {}) });
186
+ if (choice !== 'trust' && choice !== 'trust-parent')
187
+ throw projectTrustFailure(assessment);
188
+ const folder = folderTargetFor(choice, assessment); /* Session only with nothing to trust: nothing is written. */
189
+ if (!assessment.trusted || folder !== 'none')
190
+ await (deps.trustProjectAssessment ?? trustProjectAssessment)({ assessment, trustRoot: paths.trust.projects, nestedRepositories, ...(assessment.folder ? { folder } : {}), /* Q-R4-17: the home folder's grant is for this process only. */ ...(assessment.folder?.sessionOnly ? { sessionOnly: true } : {}) });
191
+ }
192
+ }
193
+ else
194
+ await (deps.assertProjectTrusted ?? assertProjectTrusted)(trustInput);
195
+ }
196
+ const effective = await loadEffectiveConfig({ paths, projectRoot, cli: { ...(inv.model ? { model: inv.model } : {}), ...(inv.permissionMode ? { permissionMode: inv.permissionMode } : {}) } });
197
+ const selectedModel = effective.value.model ?? 'openai:gpt-5-mini';
198
+ const selectedMode = inv.permissionMode ?? effective.value.permissionMode ?? 'default';
199
+ const rules = effective.value.permissions ?? { allow: [], ask: [], deny: [] };
200
+ const effectiveKeymap = interactive ? assertValidKeymap(effective.value.ui?.keymap) : undefined;
201
+ notices = effective.ignored.map(({ code, message }) => ({ code, message }));
202
+ if (interactive || inv.outputFormat === 'text')
203
+ for (const notice of notices)
204
+ io.writeErr(`Warning: ${inertTerminalText(notice.message)}\n`);
205
+ let prompt = inv.prompt;
206
+ if (!prompt && !interactive && !io.stdinIsTTY)
207
+ prompt = (await io.readStdin()).trim();
208
+ let activeRuntime;
209
+ let catalog = undefined;
210
+ let liveRegistry = undefined;
211
+ if (interactive) {
212
+ const contextFactory = deps.createRuntimeContext ?? defaultCreateRuntimeContext;
213
+ const context = await contextFactory({ projectRoot, paths, model: selectedModel, trustVerified: true, environmentKeys: 'consent' });
214
+ activeRuntime = context.runtime;
215
+ catalog = context.tuiCatalog;
216
+ liveRegistry = context.registry;
217
+ }
218
+ else if (effective.value.reasoningEffort !== undefined && (!deps.createRuntime || deps.createRuntimeContext)) {
219
+ const contextFactory = deps.createRuntimeContext ?? defaultCreateRuntimeContext;
220
+ const context = await contextFactory({ projectRoot, paths, model: selectedModel, trustVerified: true, environmentKeys: 'use' });
221
+ activeRuntime = context.runtime;
222
+ catalog = context.tuiCatalog;
223
+ }
224
+ else {
225
+ const factory = deps.createRuntime ?? defaultCreateRuntime; /* B1 slice 18: the entry decides. The screen asks before using an environment key; -p uses it and states its origin. */
226
+ const raw = await factory({ projectRoot, paths, model: selectedModel, trustVerified: true, environmentKeys: 'use' });
227
+ activeRuntime = (raw && typeof raw.start === 'function') ? raw : createSessionFacade(raw.registry, { model: selectedModel });
228
+ }
229
+ const reasoningDefault = await resolveReasoningDefault(catalog, selectedModel, effective.value.reasoningEffort);
230
+ let appliedReasoningEffort = reasoningDefault.effort;
231
+ let reasoningNotice = reasoningDefault.notice;
232
+ if (typeof activeRuntime.setDefaultReasoningEffort === 'function')
233
+ activeRuntime.setDefaultReasoningEffort(appliedReasoningEffort);
234
+ else if (appliedReasoningEffort !== null) {
235
+ appliedReasoningEffort = null;
236
+ reasoningNotice = { code: 'REASONING_EFFORT_RUNTIME_UNAVAILABLE', message: `Configured reasoning effort could not be applied by this runtime; using model default.` };
237
+ }
238
+ if (reasoningNotice) {
239
+ notices = [...notices, reasoningNotice];
240
+ if (interactive || inv.outputFormat === 'text')
241
+ io.writeErr(`Warning: ${inertTerminalText(reasoningNotice.message)}\n`);
242
+ }
243
+ runtime = activeRuntime;
244
+ releaseActiveRun = await registerActiveRun(paths, { projectRoot });
245
+ if (interactive) { /* R4 Q-R4-13: what the first frame says was loaded (lane N renders it through onboardingSteps). */
246
+ let loadedFiles = [];
247
+ try {
248
+ loadedFiles = await (deps.loadedFiles ?? defaultLoadedFiles)(projectRoot);
249
+ }
250
+ catch (error) {
251
+ developmentLogError('cli.loaded_files.failure', error, {}, 'cli-main');
252
+ }
253
+ await (deps.runTui ?? defaultRunTui)({ loadedFiles, runtime: activeRuntime, registry: liveRegistry, catalog, invocation: { ...inv, model: selectedModel, permissionMode: selectedMode }, projectRoot, paths, permissionRules: rules, keymap: effectiveKeymap, uiTheme: effective.value.ui?.theme, exitOutput: effective.value.ui?.exitOutput, initialReasoningEffort: appliedReasoningEffort, autoClassifier: selectedMode === 'auto' ? createLocalAutoClassifier({ shellIsolation: cliShellIsolation({ paths: { cacheRoot: paths.cacheRoot } }) }) : undefined, shellIsolation: cliShellIsolation({ paths: { cacheRoot: paths.cacheRoot } }), initialPrompt: prompt });
254
+ return 0;
255
+ } /* R3 Q-R3-13: the TUI asks the same shared probe once after the boot (No sandbox, (unsandboxed)). */
256
+ const machineProtocol = inv.outputFormat === 'text' ? 'v1' : (inv.protocolVersion ?? 'v1');
257
+ const headlessStop = new AbortController();
258
+ releaseInterrupt = (deps.onInterrupt ?? defaultOnInterrupt)(() => { if (headlessStop.signal.aborted)
259
+ process.exit(130); headlessStop.abort(); });
260
+ const common = { projectRoot, model: selectedModel, permissionMode: selectedMode, permissionRules: rules, ...(paths.checkpointsRoot ? { checkpointsRoot: paths.checkpointsRoot } : {}), protocolVersion: machineProtocol, ...(inv.timeoutSeconds !== undefined ? { timeoutSeconds: inv.timeoutSeconds } : {}), ...(selectedMode === 'auto' ? { autoClassifier: createLocalAutoClassifier({ shellIsolation: cliShellIsolation({ paths: { cacheRoot: paths.cacheRoot } }) }) } : {}), signal: headlessStop.signal };
261
+ const streamNotices = (sessionId) => { if (noticesStreamed)
262
+ return; noticesStreamed = true; notices.forEach((notice, index) => { if (machineProtocol === 'v2')
263
+ io.writeOut(encodeV2Event(createV2SyntheticEvent({ sessionId, eventId: 'talos:' + encodeURIComponent(sessionId || 'none') + ':config-notice:' + (index + 1), type: 'warning', data: { code: notice.code, message: notice.message } })));
264
+ else
265
+ io.writeOut(JSON.stringify(configNoticeEvent(sessionId, index + 1, notice)) + '\n'); }); };
266
+ const onStreamEvent = inv.outputFormat === 'stream-json' ? (event) => { streamNotices(String(event?.sessionId ?? '')); if (machineProtocol === 'v2')
267
+ io.writeOut(encodeV2Event(event));
268
+ else
269
+ io.writeOut(JSON.stringify(notices.length ? { ...event, seq: Number(event.seq) + notices.length } : event) + '\n'); } : undefined;
270
+ let collected;
271
+ if (inv.resume) {
272
+ await activeRuntime.restore();
273
+ const id = await sessionId(activeRuntime, inv.resume);
274
+ const previous = activeRuntime.export(id);
275
+ const from = Array.isArray(previous?.eventi) ? previous.eventi.length : Array.isArray(previous?.events) ? previous.events.length : 0;
276
+ collected = await collectHeadlessResume(activeRuntime, id, prompt, { ...common, from }, onStreamEvent);
277
+ }
278
+ else if (inv.fork) {
279
+ await activeRuntime.restore();
280
+ const id = await sessionId(activeRuntime, inv.fork);
281
+ collected = await collectHeadlessFork(activeRuntime, id, prompt, { ...common, from: 0 }, onStreamEvent);
282
+ }
283
+ else {
284
+ if (!prompt)
285
+ throw Object.assign(new Error('A prompt is required for headless mode'), { code: 'CLI_USAGE_ERROR' });
286
+ collected = await collectHeadlessRun(activeRuntime, { ...common, prompt }, onStreamEvent);
287
+ }
288
+ if (inv.outputFormat === 'stream-json')
289
+ streamNotices(String(collected.result.sessionId ?? ''));
290
+ const result = notices.length ? (machineProtocol === 'v2' ? withV2RunWarnings(collected.result, [...notices.map(notice => notice.message), ...collected.result.warnings]) : withRunWarnings(collected.result, [...notices.map(notice => notice.message), ...collected.result.warnings])) : collected.result;
291
+ return output(io, inv.outputFormat, machineProtocol, { ...collected, result });
292
+ }
293
+ catch (error) {
294
+ developmentLogError('cli.main.failure', error, { notices }, 'cli-main');
295
+ const protocol = inv.outputFormat === 'text' ? 'v1' : (inv.protocolVersion ?? 'v1');
296
+ const failure = renderFailureForProtocol(inv.outputFormat, protocol, error, inv.outputFormat === 'json' || (inv.outputFormat === 'stream-json' && !noticesStreamed) ? notices : [], inv.verbose);
297
+ if (failure.toStderr)
298
+ io.writeErr(failure.text);
299
+ else
300
+ io.writeOut(failure.text);
301
+ return failure.exitCode;
302
+ }
303
+ finally { /* R3 (owner, 2026-09-24): quitting aborts a sandbox check still running (the TUI's startup check or the broker's first probe); it ends what it started and leaves no verdict. */
304
+ try {
305
+ const left = await abortIsolationChecks(); /* ⛔ R3: a process a check could not prove its own was left running, never ended on trust: stated here. */
306
+ if (left.length > 0)
307
+ developmentLog('cli.isolation.left_running', { pids: left, why: 'the sandbox check could not prove at kill time that these pids were its own processes, so it did not end them' }, 'warning', 'cli-main');
308
+ }
309
+ catch { }
310
+ try {
311
+ await runtime?.close();
312
+ }
313
+ catch (error) {
314
+ developmentLogError('cli.runtime.close.failure', error, {}, 'cli-main');
315
+ }
316
+ try {
317
+ releaseInterrupt?.();
318
+ }
319
+ catch { /* the handler is gone with the process */ }
320
+ try {
321
+ await releaseActiveRun?.();
322
+ }
323
+ catch (error) {
324
+ developmentLogError('cli.active_run.release.failure', error, {}, 'cli-main');
325
+ }
326
+ closeDevelopmentLogging({ runtimeClosed: true });
327
+ }
328
+ }
329
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
330
+ main(process.argv.slice(2)).then(c => { process.exitCode = c; }, e => { developmentLogError('cli.process.fatal', e, {}, 'cli-main'); console.error(e); process.exitCode = 70; });
331
+ }
package/dist/paths.js ADDED
@@ -0,0 +1,41 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { mkdir } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ export class CliPathError extends Error {
5
+ code;
6
+ constructor(code) { super(code); this.name = 'CliPathError'; this.code = code; }
7
+ }
8
+ export function resolveCliPaths(env, platform, home) {
9
+ if (platform === 'win32') {
10
+ if (!env.APPDATA || !env.LOCALAPPDATA)
11
+ throw new CliPathError('PROFILE_PATH_UNAVAILABLE');
12
+ const w = path.win32;
13
+ const configRoot = w.join(env.APPDATA, 'TALOS-CLI');
14
+ const dataRoot = w.join(env.LOCALAPPDATA, 'TALOS-CLI');
15
+ const cacheRoot = w.join(dataRoot, 'cache');
16
+ return { configRoot, dataRoot, cacheRoot, sessionsRoot: w.join(dataRoot, 'sessions'), logsRoot: w.join(dataRoot, 'logs'), projectOverridesRoot: w.join(dataRoot, 'projects'), queueRoot: w.join(dataRoot, 'queues'), checkpointsRoot: w.join(dataRoot, 'checkpoints'), trust: { hooks: w.join(dataRoot, 'trust', 'hooks'), mcp: w.join(dataRoot, 'trust', 'mcp'), plugins: w.join(dataRoot, 'trust', 'plugins'), projects: w.join(dataRoot, 'trust', 'projects') } };
17
+ }
18
+ if (!home)
19
+ throw new CliPathError('PROFILE_PATH_UNAVAILABLE');
20
+ const p = path.posix;
21
+ const configRoot = env.XDG_CONFIG_HOME || p.join(home, '.config', 'talos-cli');
22
+ const dataRoot = env.XDG_STATE_HOME || p.join(home, '.local', 'state', 'talos-cli');
23
+ const cacheRoot = env.XDG_CACHE_HOME || p.join(home, '.cache', 'talos-cli');
24
+ return { configRoot, dataRoot, cacheRoot, sessionsRoot: p.join(dataRoot, 'sessions'), logsRoot: p.join(dataRoot, 'logs'), projectOverridesRoot: p.join(dataRoot, 'projects'), queueRoot: p.join(dataRoot, 'queues'), checkpointsRoot: p.join(dataRoot, 'checkpoints'), trust: { hooks: p.join(dataRoot, 'trust', 'hooks'), mcp: p.join(dataRoot, 'trust', 'mcp'), plugins: p.join(dataRoot, 'trust', 'plugins'), projects: p.join(dataRoot, 'trust', 'projects') } };
25
+ }
26
+ export function normalizeProjectRoot(root, platform = process.platform) {
27
+ const api = platform === 'win32' ? path.win32 : path.posix;
28
+ let normalized = api.normalize(root);
29
+ const parsed = api.parse(normalized);
30
+ while (normalized.length > parsed.root.length && normalized.endsWith(api.sep))
31
+ normalized = normalized.slice(0, -1);
32
+ if (platform === 'win32')
33
+ normalized = normalized.replace(/^([A-Z]):/u, (_, d) => `${d.toLowerCase()}:`).toLowerCase();
34
+ return normalized;
35
+ }
36
+ export function projectId(root, platform = process.platform) { return createHash('sha256').update(normalizeProjectRoot(root, platform)).digest('hex').slice(0, 32); }
37
+ export async function ensureCliPaths(paths) {
38
+ const dirs = [paths.configRoot, paths.dataRoot, paths.cacheRoot, paths.sessionsRoot, paths.logsRoot, paths.projectOverridesRoot, paths.queueRoot, ...(paths.checkpointsRoot ? [paths.checkpointsRoot] : []), ...Object.values(paths.trust)];
39
+ for (const dir of dirs)
40
+ await mkdir(dir, { recursive: true, mode: 0o700 });
41
+ }
@@ -0,0 +1,9 @@
1
+ import { exitCodeForEnvelope } from "../../errors.js";
2
+ export function encodeV2Event(event) { return JSON.stringify(event) + '\n'; }
3
+ export function encodeV2Stream(events) {
4
+ return events.length ? events.map(encodeV2Event).join('') : '';
5
+ }
6
+ export function encodeV2Result(result) { return JSON.stringify(result) + '\n'; }
7
+ export function exitCodeForV2Result(result) {
8
+ return result.ok ? 0 : exitCodeForEnvelope(result.error?.envelope ?? { code: result.outcome === 'cancelled' ? 'CANCELLED' : 'INTERNAL_ERROR' });
9
+ }