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,405 @@
1
+ import { access, mkdir, open, readdir, readFile, stat, writeFile } from 'node:fs/promises';
2
+ import { constants } from 'node:fs';
3
+ import { join, resolve } from 'node:path';
4
+ import { homedir } from 'node:os';
5
+ import { spawn, spawnSync } from 'node:child_process';
6
+ import { assertNoUnknownOptions, takeFlag, takeOption, writeValue } from "./context.js";
7
+ import { doctorVerdict, runDoctor, turnReadiness } from "../diagnostics/doctor.js";
8
+ import { createPathPseudonymizer, redactObject, secretValuesFromEnvironment } from "../diagnostics/redact.js";
9
+ import { writeStoredZip } from "../diagnostics/zip.js";
10
+ import { loadEffectiveConfig } from "../config/load.js";
11
+ import { CLI_VERSION } from "../version.js";
12
+ import { performUpdateCheck, downloadVerifiedUpdate, discoverGitHubReleaseManifest } from "../update/run.js";
13
+ import { checkNpmRegistry, installedWithNpm } from "../update/npm.js";
14
+ import { describeKeyringProbeFailure, describeKeyringProblem, diagnoseKeyringProbe, systemKeyringModuleLoads } from "../provider/system-keyring.js";
15
+ import { credentialStoreName, credentialStoreSourceText, isTestProfile, openCredentialStore } from "../provider/store.js";
16
+ import { MODELS_DEV_CACHE_HOURS, MODELS_DEV_URL, modelsDevSwitch } from "../runtime/model-profile.js";
17
+ import { providerOfModel } from "../provider/environment-keys.js";
18
+ import { t } from "../i18n/index.js";
19
+ import { hasActiveRuns } from "../runtime/active-run.js";
20
+ import { importTalosModule } from "../runtime/repo.js";
21
+ import { detectTerminalCapabilities } from "../tui/terminal-capabilities.js";
22
+ import { createTerminalSessionPlan } from "../tui/terminal-session.js";
23
+ import { shellDimensions } from "../tui/shell-layout.js";
24
+ import { currentProcessPerformanceSnapshot } from "../tui/metrics.js";
25
+ import { createTrustAuthority } from "../security/trust-authority.js";
26
+ import { createProcessTreeEvidenceStore } from "../security/process-tree-evidence-store.js";
27
+ import * as updateCheck from "../update/check.js";
28
+ export async function pathAccessible(p, { writable = true, accessImpl = access } = {}) { try {
29
+ await accessImpl(p, writable ? constants.R_OK | constants.W_OK : constants.R_OK);
30
+ return true;
31
+ }
32
+ catch {
33
+ return false;
34
+ } }
35
+ function doctorStore(ctx, config, deps) {
36
+ try {
37
+ return { opened: openCredentialStore({ repoRoot: ctx.repoRoot, scope: ctx.paths.dataRoot, env: process.env, config, ...(deps ? { loader: deps } : {}) }), refusal: null };
38
+ }
39
+ catch (error) {
40
+ return { opened: null, refusal: error };
41
+ }
42
+ }
43
+ async function keyringAvailable(store) {
44
+ if (!store.opened)
45
+ throw store.refusal;
46
+ if (store.opened.problem)
47
+ throw new Error(describeKeyringProblem(store.opened.problem));
48
+ const outcome = await diagnoseKeyringProbe(store.opened.keyring);
49
+ if (!outcome.ok)
50
+ throw new Error(describeKeyringProbeFailure(outcome));
51
+ return true;
52
+ }
53
+ /** R2 (gate E13, Q-R2-9: wording only, `ok` stays R4's): which store is active, and whether this doctor run loaded the native module. */
54
+ function credentialsSection(store, loadsBefore) {
55
+ const nativeModuleLoaded = systemKeyringModuleLoads() > loadsBefore;
56
+ if (!store.opened) {
57
+ const error = store.refusal;
58
+ return { state: 'unavailable', store: error?.details?.store ?? null, source: error?.details?.source ?? null, nativeModuleLoaded, code: String(error?.code ?? 'CREDENTIAL_STORE_UNAVAILABLE'), detail: error instanceof Error ? error.message : String(error) };
59
+ }
60
+ const { kind, source, problem } = store.opened;
61
+ return problem ? { state: 'unavailable', store: kind, source, nativeModuleLoaded, detail: describeKeyringProblem(problem) } : { state: 'healthy', store: kind, source, nativeModuleLoaded };
62
+ }
63
+ /* R4 Q-R4-15 (a): the system store is one per operating-system user, so every TALOS of that user reads the same keys; the line
64
+ says so. The JSON section is unchanged (R2 E13 pins it). */
65
+ /* R5b: whether models.dev is used, why not, and how to change it (the one outbound request for sizes and prices, gate E7). */
66
+ export function catalogLine(section) {
67
+ if (section?.state === 'on')
68
+ return t('firstrun.doctor.catalogOn', { source: String(section.source ?? ''), hours: Number(section.cacheHours ?? 0) });
69
+ return t(section?.reason === 'environment' ? 'firstrun.doctor.catalogOffEnvironment' : section?.reason === 'test' ? 'firstrun.doctor.catalogOffTest' : 'firstrun.doctor.catalogOffConfig');
70
+ }
71
+ export function credentialsLine(section, platform = process.platform) {
72
+ if (section?.state !== 'healthy' && section?.detail)
73
+ return t('store.refused.line', { message: String(section.detail) });
74
+ const memory = section?.store === 'memory';
75
+ const line = t('store.line', { store: credentialStoreName(memory ? 'memory' : 'system', platform), source: credentialStoreSourceText({ source: section?.source }) });
76
+ return memory ? line : `${line} — ${t(platform === 'win32' ? 'store.shared.win32' : platform === 'darwin' ? 'store.shared.darwin' : 'store.shared.other')}`;
77
+ }
78
+ /** The readiness of the provider of the model a run would use: the one sentence a person acts on (E8 for a missing key). */
79
+ function activeModelReadiness(control, model) {
80
+ const provider = model ? providerOfModel(model) : null;
81
+ if (!provider || typeof control?.readiness !== 'function')
82
+ return null;
83
+ try {
84
+ const decision = control.readiness(provider);
85
+ return { model, provider, ready: decision?.ready === true, code: decision?.ready ? null : String(decision?.code ?? ''), message: decision?.ready ? null : String(decision?.message ?? '') };
86
+ }
87
+ catch {
88
+ return null;
89
+ }
90
+ }
91
+ function platformId() { return `${process.platform}-${process.arch}`; }
92
+ function providerView(row) { return { id: String(row?.id ?? ''), label: String(row?.label ?? row?.id ?? ''), auth: { required: row?.auth?.required === true, source: String(row?.auth?.source ?? 'missing'), configured: row?.auth?.configured === true, usable: row?.auth?.usable === true }, endpoint: { host: typeof row?.endpoint?.host === 'string' ? row.endpoint.host : null, configured: row?.endpoint?.configured === true, valid: row?.endpoint?.valid === true }, runtimeConfigured: row?.runtimeConfigured !== false, local: row?.local === true, cooldown: { active: row?.cooldown?.active === true, cause: typeof row?.cooldown?.cause === 'string' ? row.cooldown.cause : null, until: Number.isFinite(row?.cooldown?.until) ? Number(row.cooldown.until) : null }, lastHealth: { state: String(row?.lastHealth?.state ?? 'unknown'), latencyMs: Number.isFinite(row?.lastHealth?.latencyMs) ? Number(row.lastHealth.latencyMs) : null, observedAt: Number.isFinite(row?.lastHealth?.observedAt) ? Number(row.lastHealth.observedAt) : null, httpStatus: Number.isFinite(row?.lastHealth?.httpStatus) ? Number(row.lastHealth.httpStatus) : null }, ready: row?.ready === true }; }
93
+ async function doctorData(ctx, deps = {}, options = {}) {
94
+ const profile = options.profile === true;
95
+ const loadsBefore = systemKeyringModuleLoads();
96
+ let config = null;
97
+ try {
98
+ config = (await loadEffectiveConfig({ paths: ctx.paths, projectRoot: ctx.projectRoot })).value;
99
+ }
100
+ catch {
101
+ config = null;
102
+ }
103
+ const store = doctorStore(ctx, config, deps.keyring);
104
+ const activeModel = ctx.invocation.model ?? (typeof config?.model === 'string' ? config.model : null);
105
+ const base = await runDoctor({
106
+ paths: ctx.paths,
107
+ fsAccess: (p) => pathAccessible(p, { writable: true }),
108
+ gitProbe: async () => spawnSync('git', ['--version'], { stdio: 'ignore' }).status === 0,
109
+ keyringProbe: () => keyringAvailable(store),
110
+ credentialsProbe: async () => credentialsSection(store, loadsBefore),
111
+ catalogProbe: async () => { const decided = modelsDevSwitch({ env: process.env, config, testProfile: isTestProfile(process.env) }); return { state: decided.enabled ? 'on' : 'off', reason: decided.reason, source: MODELS_DEV_URL, cacheHours: MODELS_DEV_CACHE_HOURS }; },
112
+ profile,
113
+ terminalProbe: async () => {
114
+ const color = typeof process.stdout.hasColors === 'function' ? Boolean(process.stdout.hasColors()) : ctx.io.stdoutIsTTY;
115
+ const capabilities = detectTerminalCapabilities({ stdinIsTTY: ctx.io.stdinIsTTY, stdoutIsTTY: ctx.io.stdoutIsTTY, color, env: process.env });
116
+ const session = createTerminalSessionPlan({ capabilities, env: process.env, supportsAlternateScreen: true });
117
+ const terminalRows = Number(process.stdout.rows ?? 30), terminalColumns = Number(process.stdout.columns ?? 100);
118
+ return { state: 'healthy', capabilities, session, layout: shellDimensions(terminalRows, terminalColumns), terminal: { rows: terminalRows, columns: terminalColumns, term: process.env.TERM ?? null } };
119
+ },
120
+ runtimeProbe: async () => {
121
+ const runtimeFile = join(ctx.repoRoot, 'harness-ui', 'src', 'session-registry.mjs');
122
+ const layout = { runtimeReadable: await pathAccessible(runtimeFile, { writable: false }), projectWritable: await pathAccessible(ctx.projectRoot, { writable: true }), sessionsRoot: await pathAccessible(ctx.paths.sessionsRoot, { writable: true }), configRoot: await pathAccessible(ctx.paths.configRoot, { writable: true }), cacheRoot: await pathAccessible(ctx.paths.cacheRoot, { writable: true }) };
123
+ return { state: Object.values(layout).every(Boolean) ? 'healthy' : 'degraded', layout, roots: { project: ctx.projectRoot, repo: ctx.repoRoot, sessions: ctx.paths.sessionsRoot, config: ctx.paths.configRoot, cache: ctx.paths.cacheRoot } };
124
+ },
125
+ trustProbe: async () => {
126
+ try {
127
+ const snapshot = await createTrustAuthority({ projectRoot: ctx.projectRoot, trustRoot: ctx.paths.trust.projects }).inspect();
128
+ return { state: snapshot.trusted ? 'healthy' : 'degraded', trusted: snapshot.trusted === true, reason: String(snapshot.reason ?? 'UNKNOWN'), storeSchema: snapshot.storeSchema ?? null, resources: Array.isArray(snapshot.resources) ? snapshot.resources.length : 0, nestedRepositories: Array.isArray(snapshot.nestedRepositories) ? snapshot.nestedRepositories.length : 0, rollbackAvailable: snapshot.rollbackAvailable === true };
129
+ }
130
+ catch (error) {
131
+ return { state: 'unavailable', trusted: false, reason: error instanceof Error ? error.message : String(error) };
132
+ }
133
+ },
134
+ providerProbe: async ({ active }) => {
135
+ let runtimeContext = null;
136
+ try {
137
+ runtimeContext = await ctx.createRuntimeContext({ projectRoot: ctx.projectRoot, paths: ctx.paths, repoRoot: ctx.repoRoot, model: ctx.invocation.model ?? 'openai:gpt-5-mini', environmentKeys: 'consent' });
138
+ const control = runtimeContext?.providerControlPlane;
139
+ /* R4 Q-R4-14: whether a turn could run now, asked the way a send asks it; the chosen local engine must answer. */
140
+ const turn = await turnReadiness({ catalog: runtimeContext?.tuiCatalog, control, model: activeModel });
141
+ if (!control || typeof control.list !== 'function')
142
+ return { state: 'unavailable', profiles: [], turn };
143
+ const rows = control.list().slice(0, 16);
144
+ const profiles = [];
145
+ let activeCount = 0;
146
+ for (const row of rows) {
147
+ let current = row;
148
+ const eligible = row?.runtimeConfigured !== false && (row?.auth?.required !== true || row?.auth?.usable === true);
149
+ if (active && eligible && activeCount < 8 && typeof control.probe === 'function') {
150
+ activeCount++;
151
+ try {
152
+ current = await control.probe(String(row.id));
153
+ }
154
+ catch (error) {
155
+ current = { ...row, lastHealth: { state: 'error', detail: error instanceof Error ? error.message : String(error), latencyMs: null, observedAt: Date.now(), httpStatus: null } };
156
+ }
157
+ }
158
+ profiles.push(providerView(current));
159
+ }
160
+ const readiness = activeModelReadiness(control, activeModel);
161
+ return { state: active ? 'healthy' : 'unknown', active, profiles, ...(readiness ? { activeModel: readiness } : {}), turn };
162
+ }
163
+ catch (error) {
164
+ return { state: 'unavailable', active, profiles: [], detail: error instanceof Error ? error.message : String(error) };
165
+ }
166
+ finally {
167
+ try {
168
+ await runtimeContext?.runtime?.close?.();
169
+ }
170
+ catch { }
171
+ }
172
+ },
173
+ brokerProbe: async () => {
174
+ const result = await createProcessTreeEvidenceStore({ cacheRoot: ctx.paths.cacheRoot }).read();
175
+ if (!result)
176
+ return { state: 'absent', processTree: { verified: false, source: 'none' } };
177
+ return { state: result.verified ? 'verified' : 'unverified', processTree: { verified: result.verified === true, source: 'cached-host-bound', reason: typeof result.reason === 'string' ? result.reason : null, scope: result.evidence?.scope ?? null, observedAtMs: Number.isFinite(result.evidence?.observedAtMs) ? Number(result.evidence.observedAtMs) : null, durationMs: Number.isFinite(result.evidence?.durationMs) ? Number(result.evidence.durationMs) : null, signals: result.evidence?.signals ?? null } };
178
+ },
179
+ contextProbe: async () => {
180
+ const database = join(ctx.paths.dataRoot, 'context', 'context.sqlite');
181
+ try {
182
+ const info = await stat(database);
183
+ if (!info.isFile())
184
+ return { state: 'degraded', database: 'not-file', format: 'unknown', bytes: info.size };
185
+ const handle = await open(database, 'r');
186
+ const header = Buffer.alloc(16);
187
+ let bytesRead = 0;
188
+ try {
189
+ ({ bytesRead } = await handle.read(header, 0, 16, 0));
190
+ }
191
+ finally {
192
+ await handle.close();
193
+ }
194
+ const sqlite = bytesRead === 16 && header.toString('utf8') === 'SQLite format 3\u0000';
195
+ return { state: sqlite ? 'healthy' : 'degraded', database: 'present', format: sqlite ? 'sqlite3' : 'unknown', bytes: info.size };
196
+ }
197
+ catch (error) {
198
+ if (error?.code === 'ENOENT')
199
+ return { state: 'absent', database: 'absent', format: null, bytes: 0 };
200
+ return { state: 'unavailable', database: 'unreadable', format: null, bytes: null, detail: error instanceof Error ? error.message : String(error) };
201
+ }
202
+ },
203
+ sessionProbe: async () => {
204
+ const mod = await importTalosModule(ctx.repoRoot, 'session-store.mjs');
205
+ const ids = await mod.elencaSessioniPersistite({ cartellaStore: ctx.paths.sessionsRoot });
206
+ const limit = 64, maxFileBytes = 2 * 1024 * 1024, maxTotalBytes = 8 * 1024 * 1024;
207
+ let readable = 0, corrupt = 0, skipped = 0, totalBytes = 0;
208
+ for (const id of ids.slice(0, limit)) {
209
+ const file = join(ctx.paths.sessionsRoot, String(id) + '.jsonl');
210
+ let info;
211
+ try {
212
+ info = await stat(file);
213
+ }
214
+ catch {
215
+ skipped++;
216
+ continue;
217
+ }
218
+ if (!info.isFile() || info.size > maxFileBytes || totalBytes + info.size > maxTotalBytes) {
219
+ skipped++;
220
+ continue;
221
+ }
222
+ totalBytes += info.size;
223
+ try {
224
+ const row = await mod.leggiRegistro({ cartellaStore: ctx.paths.sessionsRoot, sessionId: id });
225
+ if (row === null)
226
+ skipped++;
227
+ else
228
+ readable++;
229
+ }
230
+ catch {
231
+ corrupt++;
232
+ }
233
+ }
234
+ skipped += Math.max(0, ids.length - limit);
235
+ return { state: corrupt ? 'degraded' : 'healthy', persisted: ids.length, readable, corrupt, skipped, capped: ids.length > limit || skipped > 0, inspectedBytes: totalBytes };
236
+ },
237
+ updateProbe: async () => ({ state: typeof updateCheck.verifyReleaseManifestSignature === 'function' ? 'unknown' : 'degraded', manifestSchema: 'talos.cli.release.v1', checksum: typeof updateCheck.verifyDownloadedAsset === 'function' ? 'sha256' : 'unavailable', signature: typeof updateCheck.verifyReleaseManifestSignature === 'function' ? 'available' : 'unavailable' }),
238
+ performanceProbe: async () => currentProcessPerformanceSnapshot(),
239
+ });
240
+ const extra = [];
241
+ for (const [id, file] of [['talos-runtime', join(ctx.repoRoot, 'harness-ui', 'src', 'session-registry.mjs')], ['project', ctx.projectRoot]]) {
242
+ extra.push({ id, ok: await pathAccessible(file, { writable: id === 'project' }) });
243
+ }
244
+ for (const [id, file] of [['mcp', join(ctx.projectRoot, '.harness-ui-mcp.json')], ['hooks', join(ctx.projectRoot, '.harness-ui-hooks.json')]]) {
245
+ try {
246
+ await stat(file);
247
+ JSON.parse(await readFile(file, 'utf8'));
248
+ extra.push({ id, ok: true });
249
+ }
250
+ catch (e) {
251
+ extra.push({ id, ok: e?.code === 'ENOENT', detail: e?.code === 'ENOENT' ? 'not configured' : 'invalid JSON' });
252
+ }
253
+ }
254
+ const checks = [...base.checks, ...extra];
255
+ const ok = checks.every((x) => x.ok);
256
+ /* R4 Q-R4-14 (a): `ok` keeps its meaning; `ready`, `status` and `reasons` are added. */
257
+ const turn = base.sections?.providers?.turn ?? { ready: false, reasons: [{ code: 'RUNTIME_NOT_AVAILABLE', message: t('firstrun.doctor.unknown') }] };
258
+ const verdict = doctorVerdict({ ok, checks, turn });
259
+ return { ...base, ok, ready: verdict.ready, status: verdict.status, reasons: verdict.reasons, checks, version: CLI_VERSION, platform: platformId(), telemetry: false };
260
+ }
261
+ const MAX_LOG_FILES = 8, MAX_LOG_TAIL_BYTES = 32 * 1024, MAX_LOG_LINE_CHARS = 4096;
262
+ function boundedLine(value) { return value.length <= MAX_LOG_LINE_CHARS ? value : value.slice(0, MAX_LOG_LINE_CHARS - 1) + '…'; }
263
+ async function readLogs(root, tail, bounded = false) {
264
+ let files = [];
265
+ try {
266
+ files = (await readdir(root)).filter(f => f.endsWith('.log')).sort();
267
+ }
268
+ catch {
269
+ return [];
270
+ }
271
+ if (bounded)
272
+ files = files.slice(-MAX_LOG_FILES);
273
+ const rows = [];
274
+ for (const file of files) {
275
+ const target = join(root, file);
276
+ try {
277
+ if (!bounded) {
278
+ const text = await readFile(target, 'utf8');
279
+ const lines = text.split(/\r?\n/u).filter(Boolean).slice(-tail);
280
+ rows.push({ file, lines });
281
+ continue;
282
+ }
283
+ const info = await stat(target);
284
+ if (!info.isFile())
285
+ continue;
286
+ const bytes = Math.min(info.size, MAX_LOG_TAIL_BYTES), start = Math.max(0, info.size - bytes), buffer = Buffer.alloc(bytes), handle = await open(target, 'r');
287
+ try {
288
+ await handle.read(buffer, 0, bytes, start);
289
+ }
290
+ finally {
291
+ await handle.close();
292
+ }
293
+ let text = buffer.toString('utf8');
294
+ if (start > 0) {
295
+ const cut = text.indexOf('\n');
296
+ text = cut >= 0 ? text.slice(cut + 1) : '';
297
+ }
298
+ const lines = text.split(/\r?\n/u).filter(Boolean).slice(-tail).map(boundedLine);
299
+ rows.push({ file, lines, truncated: start > 0 });
300
+ }
301
+ catch {
302
+ continue;
303
+ }
304
+ }
305
+ return rows;
306
+ }
307
+ async function diagnosticBundle(ctx, args, deps = {}) {
308
+ const out = takeOption(args, '--out');
309
+ if (!out)
310
+ throw new Error('DIAGNOSTIC_OUT_REQUIRED');
311
+ if (takeFlag(args, '--include-content'))
312
+ throw new Error('DIAGNOSTIC_CONTENT_EXPORT_DISABLED');
313
+ assertNoUnknownOptions(args);
314
+ const doctor = await doctorData(ctx, deps, { profile: false });
315
+ const config = await loadEffectiveConfig({ paths: ctx.paths, projectRoot: ctx.projectRoot });
316
+ const logs = await readLogs(ctx.paths.logsRoot, 200, true);
317
+ const secrets = secretValuesFromEnvironment(process.env);
318
+ const pseudonymizer = createPathPseudonymizer([homedir(), process.cwd(), ctx.projectRoot, ctx.repoRoot, ctx.paths.configRoot, ctx.paths.dataRoot, ctx.paths.cacheRoot, ctx.paths.sessionsRoot, ctx.paths.logsRoot]);
319
+ const safe = (value) => pseudonymizer.value(redactObject(value, secrets));
320
+ const entries = [
321
+ { name: 'manifest.json', data: JSON.stringify({ schema: 'talos.cli.diagnostic.v1', createdAt: new Date().toISOString(), version: CLI_VERSION, platform: platformId(), includesContent: false, pathPseudonymized: true, logLimits: { files: MAX_LOG_FILES, tailBytesPerFile: MAX_LOG_TAIL_BYTES, lineChars: MAX_LOG_LINE_CHARS } }, null, 2) },
322
+ { name: 'doctor.json', data: JSON.stringify(safe(doctor), null, 2) },
323
+ { name: 'config.json', data: JSON.stringify(safe(config.value), null, 2) },
324
+ { name: 'logs.json', data: JSON.stringify(safe(logs), null, 2) },
325
+ ];
326
+ await mkdir(resolve(out, '..'), { recursive: true });
327
+ await writeStoredZip(resolve(out), entries);
328
+ writeValue(ctx, { ok: true, file: resolve(out), includeContent: false }, `Diagnostic bundle: ${resolve(out)}\n`);
329
+ return 0;
330
+ }
331
+ async function updateCommand(ctx, args, deps = {}) {
332
+ if (await hasActiveRuns(ctx.paths))
333
+ throw Object.assign(new Error('UPDATE_ACTIVE_RUN'), { code: 'UPDATE_ACTIVE_RUN' });
334
+ const checkOnly = takeFlag(args, '--check');
335
+ const channel = (takeOption(args, '--channel') ?? process.env.TALOS_CLI_UPDATE_CHANNEL ?? 'stable');
336
+ if (channel !== 'stable' && channel !== 'preview')
337
+ throw new Error('UPDATE_CHANNEL_INVALID');
338
+ assertNoUnknownOptions(args);
339
+ /* R7 (owner 2026-09-25): an npm install asks the registry and says the npm command; nothing is downloaded or changed. */
340
+ if (installedWithNpm(deps.update?.packageRoot)) {
341
+ const npm = await checkNpmRegistry({ currentVersion: CLI_VERSION, channel, ...(deps.update?.fetchFn ? { fetchFn: deps.update.fetchFn } : {}) });
342
+ writeValue(ctx, npm, `${npm.available ? t('common.update.npmAvailable', { version: npm.version, current: npm.currentVersion, command: npm.command }) : t('common.update.upToDate')}\n`);
343
+ return 0;
344
+ }
345
+ const url = process.env.TALOS_CLI_UPDATE_MANIFEST_URL ?? await discoverGitHubReleaseManifest({ channel });
346
+ const result = await performUpdateCheck({ currentVersion: CLI_VERSION, channel, platform: platformId(), manifestUrl: url });
347
+ if (checkOnly || !result.available) {
348
+ writeValue(ctx, { ...result, manifest: undefined }, result.available ? `Update ${result.version} available\n` : 'TALOS CLI is up to date\n');
349
+ return 0;
350
+ }
351
+ if (!result.asset)
352
+ throw new Error('UPDATE_ASSET_NOT_FOUND');
353
+ const file = await downloadVerifiedUpdate({ asset: result.asset, cacheDir: join(ctx.paths.cacheRoot, 'updates') });
354
+ if (process.platform === 'win32' && result.asset.kind === 'installer') {
355
+ const child = spawn(file, ['/S', '/UPDATE=1'], { detached: true, stdio: 'ignore', windowsHide: true });
356
+ child.unref();
357
+ writeValue(ctx, { ok: true, version: result.version, installer: file, launched: true }, `Launching TALOS CLI ${result.version} installer\n`);
358
+ return 0;
359
+ }
360
+ writeValue(ctx, { ok: true, version: result.version, file, launched: false }, `Verified update downloaded to ${file}; install it manually on this platform\n`);
361
+ return 0;
362
+ }
363
+ async function initProject(ctx, args) { assertNoUnknownOptions(args); const dir = join(ctx.projectRoot, '.talos-cli'); await mkdir(join(dir, 'commands'), { recursive: true }); await mkdir(join(dir, 'extensions'), { recursive: true }); const file = join(dir, 'config.json'); try {
364
+ await stat(file);
365
+ }
366
+ catch {
367
+ await writeFile(file, '{}\n', { encoding: 'utf8', mode: 0o600 });
368
+ } writeValue(ctx, { ok: true, directory: dir }, `Initialized ${dir}\n`); return 0; }
369
+ export async function runSystemCommand(ctx, family, args0, deps = {}) { const args = [...args0]; if (family === 'doctor') {
370
+ const json = takeFlag(args, '--json'), profile = takeFlag(args, '--profile');
371
+ assertNoUnknownOptions(args);
372
+ const r = await doctorData(ctx, deps, { profile });
373
+ if (json || ctx.invocation.outputFormat === 'json')
374
+ ctx.io.writeOut(`${JSON.stringify(r)}\n`);
375
+ else {
376
+ const verdict = doctorVerdict({ ok: r.ok, checks: r.checks, turn: { ready: r.ready, reasons: r.reasons } });
377
+ ctx.io.writeOut(`${verdict.headline}${profile ? ' · profiled' : ''}\n`);
378
+ for (const c of r.checks)
379
+ ctx.io.writeOut(`${c.ok ? 'OK ' : 'ERR'} ${c.id}${c.detail ? `: ${c.detail}` : ''}\n`);
380
+ for (const [name, section] of Object.entries(r.sections))
381
+ ctx.io.writeOut(`INFO ${name}: ${name === 'credentials' ? credentialsLine(section) : name === 'catalog' ? catalogLine(section) : String(section?.state ?? 'unknown')}\n`);
382
+ const readiness = r.sections.providers?.activeModel;
383
+ if (readiness && !readiness.ready && readiness.message)
384
+ ctx.io.writeOut(`INFO provider: ${readiness.message}\n`);
385
+ if (r.performance)
386
+ ctx.io.writeOut(`INFO performance: rss=${r.performance.rssBytes} bytes\n`);
387
+ }
388
+ return doctorVerdict({ ok: r.ok, checks: r.checks, turn: { ready: r.ready, reasons: r.reasons } }).exitCode;
389
+ } if (family === 'logs') {
390
+ const tailRaw = takeOption(args, '--tail') ?? '100';
391
+ assertNoUnknownOptions(args);
392
+ const tail = Number(tailRaw);
393
+ if (!Number.isSafeInteger(tail) || tail < 1 || tail > 10000)
394
+ throw new Error('LOG_TAIL_INVALID');
395
+ const rows = await readLogs(ctx.paths.logsRoot, tail);
396
+ writeValue(ctx, rows, rows.flatMap(r => [`== ${r.file} ==`, ...r.lines]).join('\n') + (rows.length ? '\n' : ''));
397
+ return 0;
398
+ } if (family === 'diagnostic') {
399
+ const op = args.shift();
400
+ if (op !== 'bundle')
401
+ throw new Error('DIAGNOSTIC_OPERATION_REQUIRED');
402
+ return diagnosticBundle(ctx, args, deps);
403
+ } if (family === 'update')
404
+ return updateCommand(ctx, args, deps); if (family === 'init')
405
+ return initProject(ctx, args); throw new Error(`Unsupported system command: ${family}`); }
@@ -0,0 +1,60 @@
1
+ import { readConfigScope, replaceConfigScope } from "./load.js";
2
+ /* R5a (Q-R5-3): `models.<id>.<key>` — a model id has `:` and often `.` (`openai:gpt-4.1`), the separator itself, so for this
3
+ one branch everything between `models.` and the last key is the id. Every other path keeps the strict segment rule. */
4
+ const MODEL_ID = /^[A-Za-z0-9][A-Za-z0-9:._/-]*$/u, SEGMENT = /^[A-Za-z][A-Za-z0-9_-]*$/u;
5
+ function parts(path) {
6
+ const raw = String(path ?? '');
7
+ if (raw.startsWith('models.')) {
8
+ const rest = raw.slice('models.'.length), cut = rest.lastIndexOf('.');
9
+ if (cut > 0) {
10
+ const id = rest.slice(0, cut), key = rest.slice(cut + 1);
11
+ if (MODEL_ID.test(id) && !id.includes('..') && SEGMENT.test(key))
12
+ return ['models', id, key];
13
+ }
14
+ if (rest && MODEL_ID.test(rest) && !rest.includes('..') && !rest.endsWith('.'))
15
+ return ['models', rest];
16
+ throw new Error('CONFIG_PATH_INVALID');
17
+ }
18
+ const p = raw.split('.').filter(Boolean);
19
+ if (!p.length || p.some(x => !SEGMENT.test(x)))
20
+ throw new Error('CONFIG_PATH_INVALID');
21
+ return p;
22
+ }
23
+ export function configGet(value, path) { let cursor = value; for (const p of parts(path)) {
24
+ if (!cursor || typeof cursor !== 'object' || Array.isArray(cursor) || !Object.hasOwn(cursor, p))
25
+ throw new Error('CONFIG_PATH_NOT_FOUND');
26
+ cursor = cursor[p];
27
+ } return structuredClone(cursor); }
28
+ function setAt(root, path, value) { const ps = parts(path); let c = root; for (const p of ps.slice(0, -1)) {
29
+ const old = c[p];
30
+ if (old === undefined)
31
+ c[p] = {};
32
+ else if (!old || typeof old !== 'object' || Array.isArray(old))
33
+ throw new Error('CONFIG_PATH_CONFLICT');
34
+ c = c[p];
35
+ } c[ps.at(-1)] = structuredClone(value); }
36
+ function unsetAt(root, path) { const ps = parts(path); const stack = []; let c = root; for (const p of ps.slice(0, -1)) {
37
+ if (!c[p] || typeof c[p] !== 'object' || Array.isArray(c[p]))
38
+ return;
39
+ stack.push([c, p]);
40
+ c = c[p];
41
+ } delete c[ps.at(-1)]; for (let i = stack.length - 1; i >= 0; i--) {
42
+ const [parent, key] = stack[i];
43
+ const node = parent[key];
44
+ if (node && typeof node === 'object' && !Array.isArray(node) && Object.keys(node).length === 0)
45
+ delete parent[key];
46
+ else
47
+ break;
48
+ } }
49
+ export async function configSet({ paths, projectRoot, scope, path, value }) { const current = await readConfigScope({ paths, projectRoot, scope }); const next = structuredClone(current); setAt(next, path, value); await replaceConfigScope({ paths, projectRoot, scope, value: next }); }
50
+ export async function configUnset({ paths, projectRoot, scope, path }) { const current = await readConfigScope({ paths, projectRoot, scope }); const next = structuredClone(current); unsetAt(next, path); await replaceConfigScope({ paths, projectRoot, scope, value: next }); }
51
+ function leaves(v, prefix = '') { if (v && typeof v === 'object' && !Array.isArray(v)) {
52
+ return Object.entries(v).flatMap(([k, x]) => leaves(x, prefix ? `${prefix}.${k}` : k));
53
+ } return prefix ? [{ path: prefix, value: v }] : []; }
54
+ /** The origin of a leaf: its own, else the NEAREST recorded ancestor's (R0: was the top-level key's, which named user keymap overrides `default`). */
55
+ function originOf(effective, path) { const p = path.split('.'); for (let i = p.length; i > 0; i--) {
56
+ const found = effective.origins.get(p.slice(0, i).join('.'));
57
+ if (found !== undefined)
58
+ return found;
59
+ } return 'default'; }
60
+ export function configOrigins(effective) { return leaves(effective.value).map(row => ({ ...row, origin: originOf(effective, row.path) })); }