@vascend/talos 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (620) hide show
  1. package/README.md +202 -0
  2. package/dist/backend/asset-events.d.ts +31 -0
  3. package/dist/backend/asset-events.js +149 -0
  4. package/dist/backend/assets.d.ts +31 -0
  5. package/dist/backend/assets.js +210 -0
  6. package/dist/backend/auth.d.ts +18 -0
  7. package/dist/backend/auth.js +59 -0
  8. package/dist/backend/config.d.ts +14 -0
  9. package/dist/backend/config.js +41 -0
  10. package/dist/backend/conversations.d.ts +21 -0
  11. package/dist/backend/conversations.js +141 -0
  12. package/dist/backend/crypto.d.ts +9 -0
  13. package/dist/backend/crypto.js +68 -0
  14. package/dist/backend/engine.d.ts +13 -0
  15. package/dist/backend/engine.js +78 -0
  16. package/dist/backend/http.d.ts +25 -0
  17. package/dist/backend/http.js +112 -0
  18. package/dist/backend/index.d.ts +1 -0
  19. package/dist/backend/index.js +24 -0
  20. package/dist/backend/routes.d.ts +14 -0
  21. package/dist/backend/routes.js +169 -0
  22. package/dist/backend/sdk.d.ts +12 -0
  23. package/dist/backend/sdk.js +11 -0
  24. package/dist/backend/server.d.ts +12 -0
  25. package/dist/backend/server.js +91 -0
  26. package/dist/backend/temp-image-store.d.ts +46 -0
  27. package/dist/backend/temp-image-store.js +197 -0
  28. package/dist/backend/types.d.ts +103 -0
  29. package/dist/backend/types.js +29 -0
  30. package/dist/backend/users.d.ts +13 -0
  31. package/dist/backend/users.js +76 -0
  32. package/dist/backend/ws-handler.d.ts +14 -0
  33. package/dist/backend/ws-handler.js +72 -0
  34. package/dist/backend/ws.d.ts +19 -0
  35. package/dist/backend/ws.js +146 -0
  36. package/dist/core/agent.d.ts +56 -0
  37. package/dist/core/agent.js +1783 -0
  38. package/dist/core/background.d.ts +45 -0
  39. package/dist/core/background.js +140 -0
  40. package/dist/core/bootstrap.d.ts +45 -0
  41. package/dist/core/bootstrap.js +294 -0
  42. package/dist/core/cli-args.d.ts +41 -0
  43. package/dist/core/cli-args.js +282 -0
  44. package/dist/core/collapsible-output.d.ts +38 -0
  45. package/dist/core/collapsible-output.js +143 -0
  46. package/dist/core/compaction-checkpoint.d.ts +9 -0
  47. package/dist/core/compaction-checkpoint.js +58 -0
  48. package/dist/core/compaction.d.ts +42 -0
  49. package/dist/core/compaction.js +270 -0
  50. package/dist/core/config.d.ts +49 -0
  51. package/dist/core/config.js +417 -0
  52. package/dist/core/context-ledger.d.ts +99 -0
  53. package/dist/core/context-ledger.js +222 -0
  54. package/dist/core/context-policy.d.ts +17 -0
  55. package/dist/core/context-policy.js +81 -0
  56. package/dist/core/continuation-review.d.ts +23 -0
  57. package/dist/core/continuation-review.js +64 -0
  58. package/dist/core/crash-report.d.ts +3 -0
  59. package/dist/core/crash-report.js +27 -0
  60. package/dist/core/credentials.d.ts +11 -0
  61. package/dist/core/credentials.js +183 -0
  62. package/dist/core/doctor.d.ts +24 -0
  63. package/dist/core/doctor.js +125 -0
  64. package/dist/core/effort.d.ts +5 -0
  65. package/dist/core/effort.js +42 -0
  66. package/dist/core/env-paths.d.ts +3 -0
  67. package/dist/core/env-paths.js +38 -0
  68. package/dist/core/execution-guidance.d.ts +9 -0
  69. package/dist/core/execution-guidance.js +73 -0
  70. package/dist/core/execution-target.d.ts +41 -0
  71. package/dist/core/execution-target.js +69 -0
  72. package/dist/core/file-coordination.d.ts +66 -0
  73. package/dist/core/file-coordination.js +176 -0
  74. package/dist/core/file-lease-store.d.ts +14 -0
  75. package/dist/core/file-lease-store.js +89 -0
  76. package/dist/core/image-limits.d.ts +26 -0
  77. package/dist/core/image-limits.js +205 -0
  78. package/dist/core/interruptible-completion.d.ts +3 -0
  79. package/dist/core/interruptible-completion.js +42 -0
  80. package/dist/core/kingdoms-mode-state.d.ts +24 -0
  81. package/dist/core/kingdoms-mode-state.js +139 -0
  82. package/dist/core/licenza.d.ts +38 -0
  83. package/dist/core/licenza.js +125 -0
  84. package/dist/core/model-limits.d.ts +2 -0
  85. package/dist/core/model-limits.js +36 -0
  86. package/dist/core/output-lifecycle.d.ts +44 -0
  87. package/dist/core/output-lifecycle.js +190 -0
  88. package/dist/core/package-update.d.ts +15 -0
  89. package/dist/core/package-update.js +121 -0
  90. package/dist/core/permission-queue.d.ts +2 -0
  91. package/dist/core/permission-queue.js +20 -0
  92. package/dist/core/prompt-attachment.d.ts +21 -0
  93. package/dist/core/prompt-attachment.js +123 -0
  94. package/dist/core/request-plan.d.ts +16 -0
  95. package/dist/core/request-plan.js +36 -0
  96. package/dist/core/run-timing.d.ts +17 -0
  97. package/dist/core/run-timing.js +123 -0
  98. package/dist/core/self-update.d.ts +17 -0
  99. package/dist/core/self-update.js +54 -0
  100. package/dist/core/session-refs.d.ts +27 -0
  101. package/dist/core/session-refs.js +126 -0
  102. package/dist/core/session-storage.d.ts +4 -0
  103. package/dist/core/session-storage.js +48 -0
  104. package/dist/core/session-title.d.ts +1 -0
  105. package/dist/core/session-title.js +21 -0
  106. package/dist/core/session-usage.d.ts +17 -0
  107. package/dist/core/session-usage.js +74 -0
  108. package/dist/core/session.d.ts +58 -0
  109. package/dist/core/session.js +296 -0
  110. package/dist/core/settings.d.ts +17 -0
  111. package/dist/core/settings.js +107 -0
  112. package/dist/core/storage-retention.d.ts +21 -0
  113. package/dist/core/storage-retention.js +227 -0
  114. package/dist/core/text-sanitize.d.ts +1 -0
  115. package/dist/core/text-sanitize.js +35 -0
  116. package/dist/core/tool-artifacts.d.ts +6 -0
  117. package/dist/core/tool-artifacts.js +51 -0
  118. package/dist/core/tool-compress.d.ts +8 -0
  119. package/dist/core/tool-compress.js +111 -0
  120. package/dist/core/tool-executor.d.ts +16 -0
  121. package/dist/core/tool-executor.js +97 -0
  122. package/dist/core/tool-result-index.d.ts +52 -0
  123. package/dist/core/tool-result-index.js +327 -0
  124. package/dist/core/tool-result-store.d.ts +38 -0
  125. package/dist/core/tool-result-store.js +190 -0
  126. package/dist/core/tool-scheduler.d.ts +16 -0
  127. package/dist/core/tool-scheduler.js +35 -0
  128. package/dist/core/trust.d.ts +21 -0
  129. package/dist/core/trust.js +95 -0
  130. package/dist/core/types.d.ts +402 -0
  131. package/dist/core/types.js +1 -0
  132. package/dist/core/update-check.d.ts +26 -0
  133. package/dist/core/update-check.js +89 -0
  134. package/dist/core/update-process.d.ts +10 -0
  135. package/dist/core/update-process.js +31 -0
  136. package/dist/core/user-inbox.d.ts +23 -0
  137. package/dist/core/user-inbox.js +56 -0
  138. package/dist/core/user-input.d.ts +10 -0
  139. package/dist/core/user-input.js +35 -0
  140. package/dist/core/version.d.ts +1 -0
  141. package/dist/core/version.js +10 -0
  142. package/dist/core/vibe-modes.d.ts +38 -0
  143. package/dist/core/vibe-modes.js +383 -0
  144. package/dist/core/workspace-roots.d.ts +13 -0
  145. package/dist/core/workspace-roots.js +91 -0
  146. package/dist/core/workspace-sessions.d.ts +51 -0
  147. package/dist/core/workspace-sessions.js +243 -0
  148. package/dist/cowork/client.d.ts +29 -0
  149. package/dist/cowork/client.js +49 -0
  150. package/dist/cowork/engine-bridge.d.ts +22 -0
  151. package/dist/cowork/engine-bridge.js +98 -0
  152. package/dist/cowork/index.d.ts +11 -0
  153. package/dist/cowork/index.js +16 -0
  154. package/dist/cowork/ipc.d.ts +97 -0
  155. package/dist/cowork/ipc.js +96 -0
  156. package/dist/cowork/manager.d.ts +66 -0
  157. package/dist/cowork/manager.js +325 -0
  158. package/dist/cowork/store.d.ts +23 -0
  159. package/dist/cowork/store.js +182 -0
  160. package/dist/cowork/sync.d.ts +20 -0
  161. package/dist/cowork/sync.js +164 -0
  162. package/dist/cowork/types.d.ts +78 -0
  163. package/dist/cowork/types.js +21 -0
  164. package/dist/extensions/ext-tools.d.ts +3 -0
  165. package/dist/extensions/ext-tools.js +73 -0
  166. package/dist/extensions/loader.d.ts +91 -0
  167. package/dist/extensions/loader.js +474 -0
  168. package/dist/extensions/settings.d.ts +20 -0
  169. package/dist/extensions/settings.js +86 -0
  170. package/dist/extensions/types.d.ts +219 -0
  171. package/dist/extensions/types.js +1 -0
  172. package/dist/horizon/async-queue.d.ts +9 -0
  173. package/dist/horizon/async-queue.js +46 -0
  174. package/dist/horizon/engine.d.ts +85 -0
  175. package/dist/horizon/engine.js +603 -0
  176. package/dist/horizon/index.d.ts +4 -0
  177. package/dist/horizon/index.js +2 -0
  178. package/dist/horizon/main-team.d.ts +163 -0
  179. package/dist/horizon/main-team.js +774 -0
  180. package/dist/horizon/types.d.ts +233 -0
  181. package/dist/horizon/types.js +1 -0
  182. package/dist/index.d.ts +2 -0
  183. package/dist/index.js +233 -0
  184. package/dist/mcp/protocol.d.ts +81 -0
  185. package/dist/mcp/protocol.js +122 -0
  186. package/dist/package.json +1 -0
  187. package/dist/packages/packages.d.ts +12 -0
  188. package/dist/packages/packages.js +323 -0
  189. package/dist/prompts/templates.d.ts +13 -0
  190. package/dist/prompts/templates.js +139 -0
  191. package/dist/providers/anthropic-oauth.d.ts +13 -0
  192. package/dist/providers/anthropic-oauth.js +124 -0
  193. package/dist/providers/anthropic.d.ts +27 -0
  194. package/dist/providers/anthropic.js +526 -0
  195. package/dist/providers/catalog.d.ts +15 -0
  196. package/dist/providers/catalog.js +166 -0
  197. package/dist/providers/effort.d.ts +12 -0
  198. package/dist/providers/effort.js +102 -0
  199. package/dist/providers/model-catalog.d.ts +43 -0
  200. package/dist/providers/model-catalog.js +70 -0
  201. package/dist/providers/model-effort.d.ts +5 -0
  202. package/dist/providers/model-effort.js +43 -0
  203. package/dist/providers/model-registry.d.ts +39 -0
  204. package/dist/providers/model-registry.js +142 -0
  205. package/dist/providers/models-dev.d.ts +9 -0
  206. package/dist/providers/models-dev.js +97 -0
  207. package/dist/providers/oauth-callback-server.d.ts +28 -0
  208. package/dist/providers/oauth-callback-server.js +184 -0
  209. package/dist/providers/oauth-orchestrator.d.ts +58 -0
  210. package/dist/providers/oauth-orchestrator.js +159 -0
  211. package/dist/providers/oauth-store.d.ts +12 -0
  212. package/dist/providers/oauth-store.js +139 -0
  213. package/dist/providers/open-browser.d.ts +20 -0
  214. package/dist/providers/open-browser.js +92 -0
  215. package/dist/providers/openai-compat.d.ts +14 -0
  216. package/dist/providers/openai-compat.js +523 -0
  217. package/dist/providers/openai-oauth.d.ts +15 -0
  218. package/dist/providers/openai-oauth.js +382 -0
  219. package/dist/providers/openrouter-auth.d.ts +73 -0
  220. package/dist/providers/openrouter-auth.js +321 -0
  221. package/dist/providers/openrouter-manual-fallback.d.ts +25 -0
  222. package/dist/providers/openrouter-manual-fallback.js +161 -0
  223. package/dist/providers/openrouter.d.ts +15 -0
  224. package/dist/providers/openrouter.js +107 -0
  225. package/dist/providers/plan-limits.d.ts +6 -0
  226. package/dist/providers/plan-limits.js +175 -0
  227. package/dist/providers/provider-reset.d.ts +4 -0
  228. package/dist/providers/provider-reset.js +83 -0
  229. package/dist/providers/quota-limits.d.ts +4 -0
  230. package/dist/providers/quota-limits.js +33 -0
  231. package/dist/providers/registry.d.ts +33 -0
  232. package/dist/providers/registry.js +213 -0
  233. package/dist/providers/retry.d.ts +37 -0
  234. package/dist/providers/retry.js +347 -0
  235. package/dist/rpc/server.d.ts +23 -0
  236. package/dist/rpc/server.js +222 -0
  237. package/dist/sdk.d.ts +67 -0
  238. package/dist/sdk.js +64 -0
  239. package/dist/skills/skills.d.ts +17 -0
  240. package/dist/skills/skills.js +155 -0
  241. package/dist/text-sanitize.js +28 -0
  242. package/dist/tools/ask-user.d.ts +2 -0
  243. package/dist/tools/ask-user.js +60 -0
  244. package/dist/tools/builtin.d.ts +48 -0
  245. package/dist/tools/builtin.js +2494 -0
  246. package/dist/tools/capabilities.d.ts +5 -0
  247. package/dist/tools/capabilities.js +55 -0
  248. package/dist/tools/computer-capture.d.ts +2 -0
  249. package/dist/tools/computer-capture.js +91 -0
  250. package/dist/tools/computer-posix.d.ts +5 -0
  251. package/dist/tools/computer-posix.js +136 -0
  252. package/dist/tools/computer-use.d.ts +14 -0
  253. package/dist/tools/computer-use.js +108 -0
  254. package/dist/tools/discovery.d.ts +12 -0
  255. package/dist/tools/discovery.js +205 -0
  256. package/dist/tools/execute.d.ts +2 -0
  257. package/dist/tools/execute.js +73 -0
  258. package/dist/tools/normalize-input.d.ts +17 -0
  259. package/dist/tools/normalize-input.js +174 -0
  260. package/dist/tools/output-artifact.d.ts +3 -0
  261. package/dist/tools/output-artifact.js +80 -0
  262. package/dist/tools/pagination.d.ts +15 -0
  263. package/dist/tools/pagination.js +93 -0
  264. package/dist/tools/plan-status.d.ts +2 -0
  265. package/dist/tools/plan-status.js +109 -0
  266. package/dist/tools/program-input.d.ts +3 -0
  267. package/dist/tools/program-input.js +19 -0
  268. package/dist/tools/program.d.ts +3 -0
  269. package/dist/tools/program.js +567 -0
  270. package/dist/tools/protocol-catalog.d.ts +12 -0
  271. package/dist/tools/protocol-catalog.js +46 -0
  272. package/dist/tools/ramification-tools.d.ts +12 -0
  273. package/dist/tools/ramification-tools.js +528 -0
  274. package/dist/tools/regex-compat.d.ts +9 -0
  275. package/dist/tools/regex-compat.js +96 -0
  276. package/dist/tools/registry.d.ts +51 -0
  277. package/dist/tools/registry.js +185 -0
  278. package/dist/tools/resolve.d.ts +2 -0
  279. package/dist/tools/resolve.js +107 -0
  280. package/dist/tools/shell-env.d.ts +2 -0
  281. package/dist/tools/shell-env.js +7 -0
  282. package/dist/tools/team-input.d.ts +3 -0
  283. package/dist/tools/team-input.js +129 -0
  284. package/dist/tools/team-tools.d.ts +7 -0
  285. package/dist/tools/team-tools.js +348 -0
  286. package/dist/tools/workspace-sessions.d.ts +2 -0
  287. package/dist/tools/workspace-sessions.js +35 -0
  288. package/dist/tui/account-entry.d.ts +1 -0
  289. package/dist/tui/account-entry.js +93 -0
  290. package/dist/tui/attachment-highlight.d.ts +1 -0
  291. package/dist/tui/attachment-highlight.js +24 -0
  292. package/dist/tui/attachment-refs.d.ts +2 -0
  293. package/dist/tui/attachment-refs.js +3 -0
  294. package/dist/tui/bottom-input.d.ts +219 -0
  295. package/dist/tui/bottom-input.js +1958 -0
  296. package/dist/tui/branding.d.ts +107 -0
  297. package/dist/tui/branding.js +750 -0
  298. package/dist/tui/clipboard-image.d.ts +10 -0
  299. package/dist/tui/clipboard-image.js +163 -0
  300. package/dist/tui/clipboard-text.d.ts +9 -0
  301. package/dist/tui/clipboard-text.js +51 -0
  302. package/dist/tui/clipboard-windows.d.ts +8 -0
  303. package/dist/tui/clipboard-windows.js +84 -0
  304. package/dist/tui/collapsible-command.d.ts +15 -0
  305. package/dist/tui/collapsible-command.js +48 -0
  306. package/dist/tui/command-feedback.d.ts +10 -0
  307. package/dist/tui/command-feedback.js +46 -0
  308. package/dist/tui/command-output-registry.d.ts +28 -0
  309. package/dist/tui/command-output-registry.js +103 -0
  310. package/dist/tui/command-transcript.d.ts +12 -0
  311. package/dist/tui/command-transcript.js +90 -0
  312. package/dist/tui/commands.d.ts +20 -0
  313. package/dist/tui/commands.js +131 -0
  314. package/dist/tui/context-bar.d.ts +4 -0
  315. package/dist/tui/context-bar.js +74 -0
  316. package/dist/tui/context-meter.d.ts +25 -0
  317. package/dist/tui/context-meter.js +81 -0
  318. package/dist/tui/cost-binding.d.ts +8 -0
  319. package/dist/tui/cost-binding.js +43 -0
  320. package/dist/tui/cost-tracker.d.ts +49 -0
  321. package/dist/tui/cost-tracker.js +122 -0
  322. package/dist/tui/diff.d.ts +9 -0
  323. package/dist/tui/diff.js +119 -0
  324. package/dist/tui/i18n-catalog.d.ts +5 -0
  325. package/dist/tui/i18n-catalog.js +184 -0
  326. package/dist/tui/i18n.d.ts +6 -0
  327. package/dist/tui/i18n.js +10 -0
  328. package/dist/tui/image-attachments.d.ts +46 -0
  329. package/dist/tui/image-attachments.js +167 -0
  330. package/dist/tui/images.d.ts +12 -0
  331. package/dist/tui/images.js +87 -0
  332. package/dist/tui/intro.d.ts +13 -0
  333. package/dist/tui/intro.js +109 -0
  334. package/dist/tui/language-preference.d.ts +6 -0
  335. package/dist/tui/language-preference.js +24 -0
  336. package/dist/tui/live-output.d.ts +2 -0
  337. package/dist/tui/live-output.js +18 -0
  338. package/dist/tui/locales.d.ts +19 -0
  339. package/dist/tui/locales.js +22 -0
  340. package/dist/tui/login-menu.d.ts +17 -0
  341. package/dist/tui/login-menu.js +58 -0
  342. package/dist/tui/logo.d.ts +8 -0
  343. package/dist/tui/logo.js +305 -0
  344. package/dist/tui/markdown-inline.d.ts +3 -0
  345. package/dist/tui/markdown-inline.js +99 -0
  346. package/dist/tui/markdown-table.d.ts +4 -0
  347. package/dist/tui/markdown-table.js +63 -0
  348. package/dist/tui/markdown.d.ts +11 -0
  349. package/dist/tui/markdown.js +257 -0
  350. package/dist/tui/mcp-transcript.d.ts +7 -0
  351. package/dist/tui/mcp-transcript.js +40 -0
  352. package/dist/tui/model-details.d.ts +2 -0
  353. package/dist/tui/model-details.js +21 -0
  354. package/dist/tui/model-selection.d.ts +7 -0
  355. package/dist/tui/model-selection.js +41 -0
  356. package/dist/tui/native-scrollback.d.ts +27 -0
  357. package/dist/tui/native-scrollback.js +134 -0
  358. package/dist/tui/onboarding.d.ts +72 -0
  359. package/dist/tui/onboarding.js +207 -0
  360. package/dist/tui/paste-collapse.d.ts +39 -0
  361. package/dist/tui/paste-collapse.js +117 -0
  362. package/dist/tui/perm-mode.d.ts +8 -0
  363. package/dist/tui/perm-mode.js +41 -0
  364. package/dist/tui/prompt-queue-store.d.ts +26 -0
  365. package/dist/tui/prompt-queue-store.js +87 -0
  366. package/dist/tui/prompt-queue.d.ts +47 -0
  367. package/dist/tui/prompt-queue.js +187 -0
  368. package/dist/tui/provider-menu.d.ts +33 -0
  369. package/dist/tui/provider-menu.js +175 -0
  370. package/dist/tui/question.d.ts +24 -0
  371. package/dist/tui/question.js +32 -0
  372. package/dist/tui/queue-screen.d.ts +25 -0
  373. package/dist/tui/queue-screen.js +152 -0
  374. package/dist/tui/queue-team.d.ts +3 -0
  375. package/dist/tui/queue-team.js +28 -0
  376. package/dist/tui/queued-questions.d.ts +20 -0
  377. package/dist/tui/queued-questions.js +163 -0
  378. package/dist/tui/quick-help.d.ts +1 -0
  379. package/dist/tui/quick-help.js +53 -0
  380. package/dist/tui/repl.d.ts +78 -0
  381. package/dist/tui/repl.js +4130 -0
  382. package/dist/tui/restore-queued-input.d.ts +3 -0
  383. package/dist/tui/restore-queued-input.js +20 -0
  384. package/dist/tui/review-detail.d.ts +6 -0
  385. package/dist/tui/review-detail.js +56 -0
  386. package/dist/tui/review-files.d.ts +3 -0
  387. package/dist/tui/review-files.js +22 -0
  388. package/dist/tui/review-render.d.ts +22 -0
  389. package/dist/tui/review-render.js +98 -0
  390. package/dist/tui/review-screen.d.ts +38 -0
  391. package/dist/tui/review-screen.js +358 -0
  392. package/dist/tui/review-store.d.ts +60 -0
  393. package/dist/tui/review-store.js +270 -0
  394. package/dist/tui/review-team.d.ts +2 -0
  395. package/dist/tui/review-team.js +27 -0
  396. package/dist/tui/selector-mouse.d.ts +26 -0
  397. package/dist/tui/selector-mouse.js +65 -0
  398. package/dist/tui/selector.d.ts +51 -0
  399. package/dist/tui/selector.js +299 -0
  400. package/dist/tui/session-replay.d.ts +10 -0
  401. package/dist/tui/session-replay.js +78 -0
  402. package/dist/tui/session-usage.d.ts +22 -0
  403. package/dist/tui/session-usage.js +55 -0
  404. package/dist/tui/skill-transcript.d.ts +5 -0
  405. package/dist/tui/skill-transcript.js +31 -0
  406. package/dist/tui/startup.d.ts +5 -0
  407. package/dist/tui/startup.js +61 -0
  408. package/dist/tui/status-line-loader.d.ts +8 -0
  409. package/dist/tui/status-line-loader.js +33 -0
  410. package/dist/tui/status-line.d.ts +38 -0
  411. package/dist/tui/status-line.js +213 -0
  412. package/dist/tui/system-language.d.ts +8 -0
  413. package/dist/tui/system-language.js +41 -0
  414. package/dist/tui/task-labels.d.ts +2 -0
  415. package/dist/tui/task-labels.js +7 -0
  416. package/dist/tui/term-bg.d.ts +4 -0
  417. package/dist/tui/term-bg.js +67 -0
  418. package/dist/tui/terminal-screen.d.ts +12 -0
  419. package/dist/tui/terminal-screen.js +1 -0
  420. package/dist/tui/terminal-text.d.ts +7 -0
  421. package/dist/tui/terminal-text.js +123 -0
  422. package/dist/tui/theme.d.ts +25 -0
  423. package/dist/tui/theme.js +383 -0
  424. package/dist/tui/tool-style.d.ts +7 -0
  425. package/dist/tui/tool-style.js +119 -0
  426. package/dist/tui/update-prompt.d.ts +14 -0
  427. package/dist/tui/update-prompt.js +104 -0
  428. package/dist/tui/usage-footer.d.ts +9 -0
  429. package/dist/tui/usage-footer.js +123 -0
  430. package/dist/tui/vascend-login.d.ts +68 -0
  431. package/dist/tui/vascend-login.js +355 -0
  432. package/dist/tui/web-login.d.ts +28 -0
  433. package/dist/tui/web-login.js +115 -0
  434. package/dist/vascend/activity-status.d.ts +12 -0
  435. package/dist/vascend/activity-status.js +68 -0
  436. package/dist/vascend/architecture-map.d.ts +73 -0
  437. package/dist/vascend/architecture-map.js +424 -0
  438. package/dist/vascend/attention-layout.d.ts +19 -0
  439. package/dist/vascend/attention-layout.js +141 -0
  440. package/dist/vascend/budget-allocator.d.ts +31 -0
  441. package/dist/vascend/budget-allocator.js +79 -0
  442. package/dist/vascend/candidate-collector.d.ts +20 -0
  443. package/dist/vascend/candidate-collector.js +220 -0
  444. package/dist/vascend/code-events.d.ts +24 -0
  445. package/dist/vascend/code-events.js +304 -0
  446. package/dist/vascend/code-graph-memory.d.ts +38 -0
  447. package/dist/vascend/code-graph-memory.js +334 -0
  448. package/dist/vascend/code-graph-runtime.d.ts +19 -0
  449. package/dist/vascend/code-graph-runtime.js +190 -0
  450. package/dist/vascend/code-graph-types.d.ts +58 -0
  451. package/dist/vascend/code-graph-types.js +50 -0
  452. package/dist/vascend/code-parser.d.ts +4 -0
  453. package/dist/vascend/code-parser.js +257 -0
  454. package/dist/vascend/competitor-knowledge.d.ts +53 -0
  455. package/dist/vascend/competitor-knowledge.js +262 -0
  456. package/dist/vascend/completeness.d.ts +16 -0
  457. package/dist/vascend/completeness.js +90 -0
  458. package/dist/vascend/context-autotuner.d.ts +45 -0
  459. package/dist/vascend/context-autotuner.js +231 -0
  460. package/dist/vascend/context-candidate.d.ts +45 -0
  461. package/dist/vascend/context-candidate.js +150 -0
  462. package/dist/vascend/context-capsule.d.ts +51 -0
  463. package/dist/vascend/context-capsule.js +133 -0
  464. package/dist/vascend/context-fabric.d.ts +108 -0
  465. package/dist/vascend/context-fabric.js +480 -0
  466. package/dist/vascend/context-feedback-loop.d.ts +56 -0
  467. package/dist/vascend/context-feedback-loop.js +204 -0
  468. package/dist/vascend/context-learning-identity.d.ts +4 -0
  469. package/dist/vascend/context-learning-identity.js +8 -0
  470. package/dist/vascend/context-links.d.ts +14 -0
  471. package/dist/vascend/context-links.js +83 -0
  472. package/dist/vascend/context-lint.d.ts +22 -0
  473. package/dist/vascend/context-lint.js +91 -0
  474. package/dist/vascend/context-market-selection.d.ts +17 -0
  475. package/dist/vascend/context-market-selection.js +50 -0
  476. package/dist/vascend/context-metrics.d.ts +25 -0
  477. package/dist/vascend/context-metrics.js +57 -0
  478. package/dist/vascend/context-pack-render.d.ts +16 -0
  479. package/dist/vascend/context-pack-render.js +52 -0
  480. package/dist/vascend/context-pareto.d.ts +33 -0
  481. package/dist/vascend/context-pareto.js +165 -0
  482. package/dist/vascend/context-pattern-explorer.d.ts +41 -0
  483. package/dist/vascend/context-pattern-explorer.js +276 -0
  484. package/dist/vascend/context-regret.d.ts +32 -0
  485. package/dist/vascend/context-regret.js +93 -0
  486. package/dist/vascend/context-retriever.d.ts +22 -0
  487. package/dist/vascend/context-retriever.js +243 -0
  488. package/dist/vascend/context-scope-index.d.ts +5 -0
  489. package/dist/vascend/context-scope-index.js +96 -0
  490. package/dist/vascend/context-scorer.d.ts +35 -0
  491. package/dist/vascend/context-scorer.js +162 -0
  492. package/dist/vascend/context-search-index.d.ts +12 -0
  493. package/dist/vascend/context-search-index.js +25 -0
  494. package/dist/vascend/context-snapshot.d.ts +22 -0
  495. package/dist/vascend/context-snapshot.js +135 -0
  496. package/dist/vascend/context-window-compiler.d.ts +42 -0
  497. package/dist/vascend/context-window-compiler.js +237 -0
  498. package/dist/vascend/contract-memory.d.ts +61 -0
  499. package/dist/vascend/contract-memory.js +435 -0
  500. package/dist/vascend/council.d.ts +58 -0
  501. package/dist/vascend/council.js +337 -0
  502. package/dist/vascend/decision-promotion.d.ts +48 -0
  503. package/dist/vascend/decision-promotion.js +410 -0
  504. package/dist/vascend/delta-context.d.ts +12 -0
  505. package/dist/vascend/delta-context.js +36 -0
  506. package/dist/vascend/dev-context-compiler.d.ts +27 -0
  507. package/dist/vascend/dev-context-compiler.js +133 -0
  508. package/dist/vascend/dev-context-layout.d.ts +30 -0
  509. package/dist/vascend/dev-context-layout.js +262 -0
  510. package/dist/vascend/evidence-slots.d.ts +14 -0
  511. package/dist/vascend/evidence-slots.js +55 -0
  512. package/dist/vascend/expansion-levels.d.ts +15 -0
  513. package/dist/vascend/expansion-levels.js +178 -0
  514. package/dist/vascend/file-lock.d.ts +7 -0
  515. package/dist/vascend/file-lock.js +95 -0
  516. package/dist/vascend/granular-kingdom.d.ts +25 -0
  517. package/dist/vascend/granular-kingdom.js +259 -0
  518. package/dist/vascend/granular-launcher.d.ts +48 -0
  519. package/dist/vascend/granular-launcher.js +202 -0
  520. package/dist/vascend/kingdom-bus.d.ts +25 -0
  521. package/dist/vascend/kingdom-bus.js +54 -0
  522. package/dist/vascend/kingdom-channel.d.ts +22 -0
  523. package/dist/vascend/kingdom-channel.js +180 -0
  524. package/dist/vascend/kingdom-kpi.d.ts +48 -0
  525. package/dist/vascend/kingdom-kpi.js +172 -0
  526. package/dist/vascend/kingdom-live.d.ts +28 -0
  527. package/dist/vascend/kingdom-live.js +61 -0
  528. package/dist/vascend/kingdom-run.d.ts +18 -0
  529. package/dist/vascend/kingdom-run.js +506 -0
  530. package/dist/vascend/kingdom-scribe.d.ts +20 -0
  531. package/dist/vascend/kingdom-scribe.js +52 -0
  532. package/dist/vascend/kingdom.d.ts +79 -0
  533. package/dist/vascend/kingdom.js +870 -0
  534. package/dist/vascend/lexical-index.d.ts +10 -0
  535. package/dist/vascend/lexical-index.js +99 -0
  536. package/dist/vascend/lexical-search.d.ts +29 -0
  537. package/dist/vascend/lexical-search.js +262 -0
  538. package/dist/vascend/long-term-context.d.ts +51 -0
  539. package/dist/vascend/long-term-context.js +194 -0
  540. package/dist/vascend/mandate.d.ts +33 -0
  541. package/dist/vascend/mandate.js +107 -0
  542. package/dist/vascend/memory-packet.d.ts +13 -0
  543. package/dist/vascend/memory-packet.js +155 -0
  544. package/dist/vascend/memory-status.d.ts +22 -0
  545. package/dist/vascend/memory-status.js +73 -0
  546. package/dist/vascend/memory-store.d.ts +62 -0
  547. package/dist/vascend/memory-store.js +273 -0
  548. package/dist/vascend/objective-revision.d.ts +69 -0
  549. package/dist/vascend/objective-revision.js +319 -0
  550. package/dist/vascend/patch-plan-store.d.ts +33 -0
  551. package/dist/vascend/patch-plan-store.js +240 -0
  552. package/dist/vascend/patch-plan.d.ts +97 -0
  553. package/dist/vascend/patch-plan.js +345 -0
  554. package/dist/vascend/plan-progress.d.ts +11 -0
  555. package/dist/vascend/plan-progress.js +68 -0
  556. package/dist/vascend/plan-store.d.ts +64 -0
  557. package/dist/vascend/plan-store.js +460 -0
  558. package/dist/vascend/proof-chains.d.ts +19 -0
  559. package/dist/vascend/proof-chains.js +120 -0
  560. package/dist/vascend/ramification-store.d.ts +25 -0
  561. package/dist/vascend/ramification-store.js +94 -0
  562. package/dist/vascend/ramification.d.ts +193 -0
  563. package/dist/vascend/ramification.js +583 -0
  564. package/dist/vascend/recall-planner.d.ts +17 -0
  565. package/dist/vascend/recall-planner.js +109 -0
  566. package/dist/vascend/requirements.d.ts +31 -0
  567. package/dist/vascend/requirements.js +151 -0
  568. package/dist/vascend/reviewer.d.ts +9 -0
  569. package/dist/vascend/reviewer.js +93 -0
  570. package/dist/vascend/room-graph.d.ts +29 -0
  571. package/dist/vascend/room-graph.js +242 -0
  572. package/dist/vascend/room-memory.d.ts +57 -0
  573. package/dist/vascend/room-memory.js +631 -0
  574. package/dist/vascend/runtime.d.ts +84 -0
  575. package/dist/vascend/runtime.js +286 -0
  576. package/dist/vascend/self-improve.d.ts +104 -0
  577. package/dist/vascend/self-improve.js +396 -0
  578. package/dist/vascend/session-search.d.ts +52 -0
  579. package/dist/vascend/session-search.js +349 -0
  580. package/dist/vascend/supersession-graph.d.ts +14 -0
  581. package/dist/vascend/supersession-graph.js +70 -0
  582. package/dist/vascend/team-areas.d.ts +9 -0
  583. package/dist/vascend/team-areas.js +28 -0
  584. package/dist/vascend/team-handoff.d.ts +24 -0
  585. package/dist/vascend/team-handoff.js +37 -0
  586. package/dist/vascend/team-scheduler.d.ts +13 -0
  587. package/dist/vascend/team-scheduler.js +74 -0
  588. package/dist/vascend/team-session.d.ts +42 -0
  589. package/dist/vascend/team-session.js +142 -0
  590. package/dist/vascend/test-failure-memory.d.ts +76 -0
  591. package/dist/vascend/test-failure-memory.js +354 -0
  592. package/dist/vascend/token-market.d.ts +42 -0
  593. package/dist/vascend/token-market.js +144 -0
  594. package/dist/vascend/tuner-baseline-store.d.ts +52 -0
  595. package/dist/vascend/tuner-baseline-store.js +446 -0
  596. package/dist/vascend/user-profile.d.ts +44 -0
  597. package/dist/vascend/user-profile.js +131 -0
  598. package/dist/vascend/vision.d.ts +94 -0
  599. package/dist/vascend/vision.js +375 -0
  600. package/dist/vascend/work-agent.d.ts +12 -0
  601. package/dist/vascend/work-agent.js +83 -0
  602. package/dist/vascend/work-queue.d.ts +62 -0
  603. package/dist/vascend/work-queue.js +255 -0
  604. package/dist/vascend/work-runner.d.ts +64 -0
  605. package/dist/vascend/work-runner.js +137 -0
  606. package/dist/vascend/worktree.d.ts +38 -0
  607. package/dist/vascend/worktree.js +206 -0
  608. package/dist/vendor/computer-use/README.md +7 -0
  609. package/dist/vendor/computer-use/computer-desktop.js +211 -0
  610. package/dist/vendor/computer-use/computer-observe.js +315 -0
  611. package/dist/vendor/computer-use/computer-scripts.js +1230 -0
  612. package/dist/vendor/computer-use/computer-tools.js +2136 -0
  613. package/dist/vendor/computer-use/package.json +1 -0
  614. package/dist/vendor/computer-use/rac/atomic-input.js +91 -0
  615. package/dist/vendor/computer-use/rac/grammatica.js +101 -0
  616. package/dist/vendor/computer-use/rac/parser.js +185 -0
  617. package/dist/vendor/computer-use/rac/protocol.js +136 -0
  618. package/install.ps1 +30 -0
  619. package/install.sh +50 -0
  620. package/package.json +56 -0
@@ -0,0 +1,97 @@
1
+ import { mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
2
+ import { dirname, resolve } from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { talosConfigDir } from "../core/env-paths.js";
5
+ import { ModelCatalog, parseModelCatalog } from "./model-catalog.js";
6
+ const MAX_BYTES = 24 * 1024 * 1024;
7
+ const TTL = 24 * 60 * 60 * 1000;
8
+ const states = new Map();
9
+ function pathFor(env) { return resolve(talosConfigDir(env), "cache", "models.dev.json"); }
10
+ function stateFor(env) {
11
+ const path = pathFor(env);
12
+ let state = states.get(path);
13
+ if (state)
14
+ return state;
15
+ state = { catalog: new ModelCatalog(), fetchedAt: 0, retryAt: 0 };
16
+ try {
17
+ if (statSync(path).size <= MAX_BYTES) {
18
+ const saved = JSON.parse(readFileSync(path, "utf8"));
19
+ const catalog = parseModelCatalog(saved.data);
20
+ if (catalog.models.length)
21
+ state = { catalog, fetchedAt: Number(saved.fetchedAt) || 0, retryAt: 0 };
22
+ }
23
+ }
24
+ catch { /* Missing or corrupt cache: keep the built-in model suggestions. */ }
25
+ states.set(path, state);
26
+ return state;
27
+ }
28
+ export function cachedModelCatalog(env = process.env) {
29
+ return env["TALOS_MODELS_DEV"] === "0" ? new ModelCatalog() : stateFor(env).catalog;
30
+ }
31
+ export function modelCapabilities(model, env = process.env) {
32
+ return cachedModelCatalog(env).get(model);
33
+ }
34
+ // A single bounded snapshot per user, replaced atomically once a day. Failures
35
+ // preserve the last valid snapshot; no credentials or conversation are sent.
36
+ export async function loadModelsDev(env = process.env, opts = {}) {
37
+ if (env["TALOS_MODELS_DEV"] === "0")
38
+ return new ModelCatalog();
39
+ const state = stateFor(env), now = opts.now ?? Date.now();
40
+ if (state.pending)
41
+ return state.pending;
42
+ if (!opts.force && (now < state.retryAt || (state.fetchedAt > 0 && now - state.fetchedAt < TTL)))
43
+ return state.catalog;
44
+ const run = async () => {
45
+ let temp;
46
+ try {
47
+ const response = await (opts.fetch ?? fetch)("https://models.dev/api.json", {
48
+ signal: AbortSignal.timeout(opts.timeoutMs ?? 5000), headers: { accept: "application/json" },
49
+ });
50
+ if (!response.ok || !response.body)
51
+ throw new Error("catalog unavailable");
52
+ const reader = response.body.getReader(), chunks = [];
53
+ let bytes = 0;
54
+ try {
55
+ for (;;) {
56
+ const { done, value } = await reader.read();
57
+ if (done)
58
+ break;
59
+ bytes += value.byteLength;
60
+ if (bytes > MAX_BYTES - 1024)
61
+ throw new Error("catalog too large");
62
+ chunks.push(value);
63
+ }
64
+ }
65
+ finally {
66
+ await reader.cancel().catch(() => { });
67
+ reader.releaseLock();
68
+ }
69
+ const data = JSON.parse(Buffer.concat(chunks).toString("utf8"));
70
+ const catalog = parseModelCatalog(data);
71
+ if (!catalog.models.length)
72
+ throw new Error("empty catalog");
73
+ state.catalog = catalog;
74
+ state.fetchedAt = now;
75
+ state.retryAt = 0;
76
+ const path = pathFor(env);
77
+ mkdirSync(dirname(path), { recursive: true });
78
+ temp = `${path}.${randomUUID()}.tmp`;
79
+ writeFileSync(temp, JSON.stringify({ fetchedAt: now, data }), { encoding: "utf8", mode: 0o600 });
80
+ renameSync(temp, path);
81
+ }
82
+ catch {
83
+ state.retryAt = now + 5 * 60 * 1000;
84
+ }
85
+ finally {
86
+ if (temp)
87
+ try {
88
+ unlinkSync(temp);
89
+ }
90
+ catch { /* Already renamed. */ }
91
+ state.pending = undefined;
92
+ }
93
+ return state.catalog;
94
+ };
95
+ state.pending = run();
96
+ return state.pending;
97
+ }
@@ -0,0 +1,28 @@
1
+ export interface CallbackResult {
2
+ readonly code?: string;
3
+ readonly state?: string;
4
+ readonly error?: string;
5
+ readonly errorDescription?: string;
6
+ readonly raw: Readonly<Record<string, string>>;
7
+ }
8
+ export interface StartCallbackServerOptions {
9
+ readonly host?: string;
10
+ readonly port?: number;
11
+ readonly path?: string;
12
+ readonly successHtml?: string;
13
+ readonly errorHtml?: string;
14
+ readonly expectedState?: string;
15
+ }
16
+ export interface WaitForCodeOptions {
17
+ readonly timeoutMs?: number;
18
+ readonly signal?: AbortSignal;
19
+ }
20
+ export interface CallbackServer {
21
+ readonly redirectUri: string;
22
+ readonly port: number;
23
+ readonly host: string;
24
+ readonly path: string;
25
+ waitForCode(opts?: WaitForCodeOptions): Promise<CallbackResult>;
26
+ close(): Promise<void>;
27
+ }
28
+ export declare function startCallbackServer(opts?: StartCallbackServerOptions): Promise<CallbackServer>;
@@ -0,0 +1,184 @@
1
+ import { createServer } from "node:http";
2
+ const DEFAULT_PATH = "/callback";
3
+ function escapeHtml(s) {
4
+ return s
5
+ .replace(/&/g, "&amp;")
6
+ .replace(/</g, "&lt;")
7
+ .replace(/>/g, "&gt;")
8
+ .replace(/"/g, "&quot;")
9
+ .replace(/'/g, "&#39;");
10
+ }
11
+ // Pagina minimale di conferma. Niente risorse esterne: tutto inline, cosi'
12
+ // funziona anche offline e senza ulteriori richieste verso il server.
13
+ function page(title, message, ok) {
14
+ const accent = ok ? "#2e7d32" : "#c62828";
15
+ return `<!doctype html>
16
+ <html lang="it">
17
+ <head>
18
+ <meta charset="utf-8">
19
+ <meta name="viewport" content="width=device-width, initial-scale=1">
20
+ <title>${escapeHtml(title)}</title>
21
+ <style>
22
+ :root { color-scheme: light dark; }
23
+ body { font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
24
+ display: flex; min-height: 100vh; margin: 0; align-items: center;
25
+ justify-content: center; background: #f5f5f5; }
26
+ .card { background: #fff; border-radius: 12px; padding: 2.5rem 3rem;
27
+ box-shadow: 0 8px 30px rgba(0,0,0,.08); max-width: 26rem; text-align: center; }
28
+ .badge { width: 3rem; height: 3rem; border-radius: 50%; margin: 0 auto 1rem;
29
+ display: flex; align-items: center; justify-content: center;
30
+ font-size: 1.6rem; color: #fff; background: ${accent}; }
31
+ h1 { font-size: 1.25rem; margin: 0 0 .5rem; color: ${accent}; }
32
+ p { color: #555; line-height: 1.5; margin: 0; }
33
+ @media (prefers-color-scheme: dark) {
34
+ body { background: #1b1b1b; }
35
+ .card { background: #262626; }
36
+ p { color: #bbb; }
37
+ }
38
+ </style>
39
+ </head>
40
+ <body>
41
+ <div class="card">
42
+ <div class="badge">${ok ? "&#10003;" : "&#33;"}</div>
43
+ <h1>${escapeHtml(title)}</h1>
44
+ <p>${escapeHtml(message)}</p>
45
+ </div>
46
+ </body>
47
+ </html>`;
48
+ }
49
+ const DEFAULT_SUCCESS_HTML = page("Autorizzazione completata", "Puoi chiudere questa scheda e tornare al terminale.", true);
50
+ const DEFAULT_ERROR_HTML = page("Autorizzazione non riuscita", "Qualcosa e' andato storto. Torna al terminale per i dettagli.", false);
51
+ // ---------------------------------------------------------------------------
52
+ // Avvio del server
53
+ // ---------------------------------------------------------------------------
54
+ // Parsa la query string di una richiesta in una mappa piatta. Usa l'URL nativo
55
+ // con una base loopback fittizia (il path/query e' tutto cio' che ci serve).
56
+ function parseQuery(reqUrl, host, port) {
57
+ const url = new URL(reqUrl, `http://${host}:${port}`);
58
+ const params = {};
59
+ for (const [k, v] of url.searchParams)
60
+ params[k] = v;
61
+ return { path: url.pathname, params };
62
+ }
63
+ // Costruisce il CallbackResult dai parametri, applicando il controllo di state.
64
+ function toResult(params, expectedState) {
65
+ const code = params["code"]?.trim() || undefined;
66
+ const state = params["state"];
67
+ const error = params["error"]?.trim() || undefined;
68
+ const errorDescription = params["error_description"]?.trim() || undefined;
69
+ if (expectedState !== undefined && state !== expectedState) {
70
+ return {
71
+ error: "state_mismatch",
72
+ errorDescription: "Il parametro state non combacia con quello atteso.",
73
+ state,
74
+ raw: params,
75
+ };
76
+ }
77
+ return { code, state, error, errorDescription, raw: params };
78
+ }
79
+ // Avvia il server di callback e attende che sia in ascolto.
80
+ export function startCallbackServer(opts = {}) {
81
+ const host = opts.host ?? "127.0.0.1";
82
+ const port = opts.port ?? 0;
83
+ const cbPath = opts.path ?? DEFAULT_PATH;
84
+ const successHtml = opts.successHtml ?? DEFAULT_SUCCESS_HTML;
85
+ const errorHtml = opts.errorHtml ?? DEFAULT_ERROR_HTML;
86
+ // Stato condiviso tra handler e waitForCode.
87
+ let settled = false;
88
+ let captured = null;
89
+ let onCapture = null;
90
+ const deliver = (r) => {
91
+ captured = r;
92
+ if (onCapture) {
93
+ const cb = onCapture;
94
+ onCapture = null;
95
+ cb(r);
96
+ }
97
+ };
98
+ const handler = (req, res) => {
99
+ const addr = server.address();
100
+ const actualPort = addr ? addr.port : port;
101
+ const { path: reqPath, params } = parseQuery(req.url ?? "/", host, actualPort);
102
+ // Ignora richieste accessorie del browser senza disturbare il flusso.
103
+ if (reqPath === "/favicon.ico") {
104
+ res.writeHead(204);
105
+ res.end();
106
+ return;
107
+ }
108
+ // Solo il path di callback ci interessa.
109
+ if (reqPath !== cbPath) {
110
+ res.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
111
+ res.end("Not found");
112
+ return;
113
+ }
114
+ const result = toResult(params, opts.expectedState);
115
+ const isOk = !result.error && !!result.code;
116
+ res.writeHead(isOk ? 200 : 400, { "content-type": "text/html; charset=utf-8" });
117
+ res.end(isOk ? successHtml : errorHtml);
118
+ // Cattura solo il primo callback "deciso" (con code o con errore). Una
119
+ // richiesta sul path senza ne' code ne' error (raro) non risolve l'attesa.
120
+ if (!settled && (result.code || result.error)) {
121
+ settled = true;
122
+ deliver(result);
123
+ }
124
+ };
125
+ const server = createServer(handler);
126
+ return new Promise((resolve, reject) => {
127
+ server.once("error", reject);
128
+ server.listen(port, host, () => {
129
+ server.removeListener("error", reject);
130
+ const addr = server.address();
131
+ const actualPort = addr.port;
132
+ const redirectUri = `http://${host}:${actualPort}${cbPath}`;
133
+ const close = () => new Promise((res) => {
134
+ if (!server.listening) {
135
+ res();
136
+ return;
137
+ }
138
+ server.close(() => res());
139
+ // Chiudi eventuali keep-alive pendenti (Node >= 18.2).
140
+ server.closeAllConnections?.();
141
+ });
142
+ const waitForCode = (waitOpts = {}) => {
143
+ // Se il callback e' gia' arrivato, risolvi subito.
144
+ if (captured) {
145
+ const c = captured;
146
+ return close().then(() => c);
147
+ }
148
+ return new Promise((resolveWait, rejectWait) => {
149
+ let timer = null;
150
+ const cleanup = () => {
151
+ if (timer)
152
+ clearTimeout(timer);
153
+ if (waitOpts.signal)
154
+ waitOpts.signal.removeEventListener("abort", onAbort);
155
+ return close();
156
+ };
157
+ const onAbort = () => {
158
+ onCapture = null;
159
+ void cleanup().then(() => rejectWait(new Error("callback annullato")));
160
+ };
161
+ if (waitOpts.signal) {
162
+ if (waitOpts.signal.aborted) {
163
+ onAbort();
164
+ return;
165
+ }
166
+ waitOpts.signal.addEventListener("abort", onAbort, { once: true });
167
+ }
168
+ if (waitOpts.timeoutMs && waitOpts.timeoutMs > 0) {
169
+ timer = setTimeout(() => {
170
+ onCapture = null;
171
+ void cleanup().then(() => rejectWait(new Error(`timeout in attesa del callback OAuth (${waitOpts.timeoutMs}ms)`)));
172
+ }, waitOpts.timeoutMs);
173
+ // Non tenere vivo il processo solo per questo timer.
174
+ timer.unref?.();
175
+ }
176
+ onCapture = (r) => {
177
+ void cleanup().then(() => resolveWait(r));
178
+ };
179
+ });
180
+ };
181
+ resolve({ redirectUri, port: actualPort, host, path: cbPath, waitForCode, close });
182
+ });
183
+ });
184
+ }
@@ -0,0 +1,58 @@
1
+ import { type PkceChallenge } from "./openrouter-auth.js";
2
+ export interface CallbackResult {
3
+ readonly code?: string;
4
+ readonly state?: string;
5
+ readonly error?: string;
6
+ readonly errorDescription?: string;
7
+ readonly raw?: unknown;
8
+ }
9
+ export interface CallbackServer {
10
+ readonly redirectUri: string;
11
+ readonly port: number;
12
+ readonly host: string;
13
+ readonly path: string;
14
+ waitForCode(opts?: {
15
+ readonly timeoutMs?: number;
16
+ readonly signal?: AbortSignal;
17
+ }): Promise<CallbackResult>;
18
+ close(): Promise<void> | void;
19
+ }
20
+ export type StartCallbackServer = (opts?: {
21
+ readonly host?: string;
22
+ readonly port?: number;
23
+ readonly path?: string;
24
+ readonly expectedState?: string;
25
+ }) => Promise<CallbackServer>;
26
+ export type OpenBrowser = (url: string) => Promise<{
27
+ readonly opened: boolean;
28
+ readonly error?: string;
29
+ }>;
30
+ export type BuildAuthUrl = (redirectUri: string, challenge: PkceChallenge) => string;
31
+ export type OrchestratorPhase = "server_started" | "url_built" | "browser_opened" | "browser_failed" | "awaiting_code" | "code_received" | "server_closed" | "exchanging" | "done" | "error";
32
+ export interface OrchestratorEvent {
33
+ readonly phase: OrchestratorPhase;
34
+ readonly detail?: string;
35
+ }
36
+ export interface OrchestrateOptions {
37
+ readonly startServer: StartCallbackServer;
38
+ readonly buildAuthUrl: BuildAuthUrl;
39
+ readonly openBrowser?: OpenBrowser;
40
+ readonly timeoutMs?: number;
41
+ readonly signal?: AbortSignal;
42
+ readonly host?: string;
43
+ readonly port?: number;
44
+ readonly path?: string;
45
+ readonly fetchImpl?: typeof fetch;
46
+ readonly rand?: (n: number) => Buffer;
47
+ readonly persist?: boolean;
48
+ readonly onEvent?: (ev: OrchestratorEvent) => void;
49
+ }
50
+ export interface OrchestrateResult {
51
+ readonly ok: boolean;
52
+ readonly apiKey?: string;
53
+ readonly errorKind?: "browser" | "timeout" | "aborted" | "callback" | "exchange" | "server" | "unknown";
54
+ readonly error?: string;
55
+ readonly authUrl?: string;
56
+ readonly browserOpened?: boolean;
57
+ }
58
+ export declare function orchestrateOAuth(env: NodeJS.ProcessEnv, opts: OrchestrateOptions): Promise<OrchestrateResult>;
@@ -0,0 +1,159 @@
1
+ // Orchestratore del flusso OAuth PKCE di OpenRouter, end-to-end.
2
+ //
3
+ // Compone i pezzi prodotti dagli altri moduli (vassalli):
4
+ // - oauth-callback-server.ts -> startCallbackServer(): server locale che
5
+ // riceve la redirect e cattura il `code`.
6
+ // - openrouter-auth.ts -> buildAuthUrlForPort()/callbackUrlForPort()
7
+ // (URL di autorizzazione) e startOAuthFlow().complete(code) (scambio +
8
+ // persistenza credenziali).
9
+ // - auto-open-browser -> openBrowser(url): apre il browser di sistema
10
+ // (iniettato come dipendenza, best-effort).
11
+ //
12
+ // Sequenza orchestrata:
13
+ // 1. start server locale (porta effimera, redirectUri noto).
14
+ // 2. genera PKCE challenge e costruisci l'authUrl col redirectUri del server.
15
+ // 3. apri il browser sull'authUrl (best-effort; se fallisce -> fallback
16
+ // manuale: l'utente apre l'URL a mano).
17
+ // 4. attendi il `code` dal callback, con timeout e gestione errori
18
+ // (access_denied, mismatch state, timeout, abort).
19
+ // 5. chiudi SEMPRE il server (anche su errore).
20
+ // 6. scambia il `code` per la API key e persisti.
21
+ //
22
+ // Il modulo e' a zero dipendenze runtime e tutte le collaborazioni esterne
23
+ // sono iniettabili, per restare testabile in isolamento.
24
+ import { startOAuthFlow, } from "./openrouter-auth.js";
25
+ const DEFAULT_TIMEOUT_MS = 5 * 60 * 1000;
26
+ function emit(opts, phase, detail) {
27
+ try {
28
+ opts.onEvent?.({ phase, detail });
29
+ }
30
+ catch {
31
+ // un onEvent difettoso non deve rompere il flusso.
32
+ }
33
+ }
34
+ // ---------------------------------------------------------------------------
35
+ // Orchestrazione
36
+ // ---------------------------------------------------------------------------
37
+ // Esegue l'intero flusso OAuth PKCE. Garantisce la chiusura del server in ogni
38
+ // percorso (successo, errore, timeout, abort). Non lancia: ritorna sempre un
39
+ // OrchestrateResult con esito e categoria d'errore.
40
+ export async function orchestrateOAuth(env, opts) {
41
+ // Abort precoce: se gia' annullato, non avviare nulla.
42
+ if (opts.signal?.aborted) {
43
+ return { ok: false, errorKind: "aborted", error: "operazione annullata" };
44
+ }
45
+ let server = null;
46
+ let authUrl;
47
+ let browserOpened = false;
48
+ try {
49
+ // 1. Avvio server locale.
50
+ try {
51
+ server = await opts.startServer({
52
+ host: opts.host,
53
+ port: opts.port,
54
+ path: opts.path,
55
+ });
56
+ }
57
+ catch (err) {
58
+ const msg = err instanceof Error ? err.message : String(err);
59
+ emit(opts, "error", msg);
60
+ return { ok: false, errorKind: "server", error: `avvio server callback fallito: ${msg}` };
61
+ }
62
+ emit(opts, "server_started", server.redirectUri);
63
+ // 2. PKCE + authUrl col redirectUri reale del server.
64
+ const flow = startOAuthFlow(env, server.redirectUri, {
65
+ rand: opts.rand,
66
+ persist: opts.persist,
67
+ });
68
+ // Usa il builder iniettato (puo' differire da quello interno di startOAuthFlow,
69
+ // es. buildAuthUrlForPort): prevale il builder esplicito.
70
+ authUrl = opts.buildAuthUrl(server.redirectUri, flow.challenge);
71
+ emit(opts, "url_built", authUrl);
72
+ // 3. Apertura browser best-effort. Il fallimento NON interrompe: l'utente
73
+ // puo' aprire l'URL manualmente (lo riportiamo nel risultato).
74
+ if (opts.openBrowser) {
75
+ try {
76
+ const res = await opts.openBrowser(authUrl);
77
+ browserOpened = res.opened;
78
+ if (res.opened)
79
+ emit(opts, "browser_opened", authUrl);
80
+ else
81
+ emit(opts, "browser_failed", res.error ?? "browser non aperto");
82
+ }
83
+ catch (err) {
84
+ const msg = err instanceof Error ? err.message : String(err);
85
+ emit(opts, "browser_failed", msg);
86
+ }
87
+ }
88
+ else {
89
+ emit(opts, "browser_failed", "nessun opener: apertura manuale");
90
+ }
91
+ // 4. Attesa del code con timeout + abort.
92
+ emit(opts, "awaiting_code");
93
+ let cb;
94
+ try {
95
+ cb = await server.waitForCode({
96
+ timeoutMs: opts.timeoutMs ?? DEFAULT_TIMEOUT_MS,
97
+ signal: opts.signal,
98
+ });
99
+ }
100
+ catch (err) {
101
+ // waitForCode puo' rigettare su timeout/abort a seconda dell'implementazione.
102
+ const msg = err instanceof Error ? err.message : String(err);
103
+ const aborted = opts.signal?.aborted || /abort/i.test(msg);
104
+ const kind = aborted ? "aborted" : /timeout|timed out|scadut/i.test(msg) ? "timeout" : "callback";
105
+ emit(opts, "error", msg);
106
+ return { ok: false, errorKind: kind, error: msg, authUrl, browserOpened };
107
+ }
108
+ // Errore applicativo riportato dal provider nel callback (es. access_denied).
109
+ if (cb.error) {
110
+ const detail = cb.errorDescription ? `${cb.error}: ${cb.errorDescription}` : cb.error;
111
+ emit(opts, "error", detail);
112
+ return { ok: false, errorKind: "callback", error: detail, authUrl, browserOpened };
113
+ }
114
+ const code = (cb.code ?? "").trim();
115
+ if (!code) {
116
+ emit(opts, "error", "callback senza code");
117
+ return { ok: false, errorKind: "callback", error: "callback senza code", authUrl, browserOpened };
118
+ }
119
+ emit(opts, "code_received");
120
+ // 5. Chiudi il server appena ho il code (lo scambio non ne ha piu' bisogno).
121
+ await safeClose(server);
122
+ server = null;
123
+ emit(opts, "server_closed");
124
+ // 6. Scambio code -> API key (+ persistenza dentro flow.complete).
125
+ emit(opts, "exchanging");
126
+ const exchange = await flow.complete(code, {
127
+ signal: opts.signal,
128
+ fetchImpl: opts.fetchImpl,
129
+ });
130
+ if (!exchange.ok || !exchange.apiKey) {
131
+ const msg = exchange.error ?? "scambio token fallito";
132
+ emit(opts, "error", msg);
133
+ return { ok: false, errorKind: "exchange", error: msg, authUrl, browserOpened };
134
+ }
135
+ emit(opts, "done");
136
+ return { ok: true, apiKey: exchange.apiKey, authUrl, browserOpened };
137
+ }
138
+ catch (err) {
139
+ const msg = err instanceof Error ? err.message : String(err);
140
+ emit(opts, "error", msg);
141
+ return { ok: false, errorKind: "unknown", error: msg, authUrl, browserOpened };
142
+ }
143
+ finally {
144
+ // Cleanup garantito: se il server e' ancora aperto, chiudilo.
145
+ if (server) {
146
+ await safeClose(server);
147
+ emit(opts, "server_closed");
148
+ }
149
+ }
150
+ }
151
+ // Chiusura difensiva: non propaga errori di close (best-effort).
152
+ async function safeClose(server) {
153
+ try {
154
+ await server.close();
155
+ }
156
+ catch {
157
+ // ignora: la chiusura e' best-effort.
158
+ }
159
+ }
@@ -0,0 +1,12 @@
1
+ export interface OAuthCreds {
2
+ accessToken: string;
3
+ refreshToken: string;
4
+ expiresAt: number;
5
+ accountId?: string;
6
+ }
7
+ export declare function jwtExpiresAt(token: string): number;
8
+ export declare function readClaudeCreds(env: NodeJS.ProcessEnv): OAuthCreds | null;
9
+ export declare function readCodexCreds(env: NodeJS.ProcessEnv): OAuthCreds | null;
10
+ export declare function writeClaudeCreds(env: NodeJS.ProcessEnv, creds: OAuthCreds): void;
11
+ export declare function writeCodexCreds(env: NodeJS.ProcessEnv, creds: OAuthCreds): void;
12
+ export declare function isExpired(creds: OAuthCreds, now: number): boolean;
@@ -0,0 +1,139 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ function numericEpoch(value) {
5
+ if (typeof value === "number" && Number.isFinite(value) && value > 0)
6
+ return value;
7
+ if (typeof value !== "string" || !value.trim())
8
+ return 0;
9
+ const numeric = Number(value);
10
+ return Number.isFinite(numeric) && numeric > 0 ? numeric : 0;
11
+ }
12
+ // I token Codex sono JWT. `last_refresh` nel file ufficiale e' l'istante del
13
+ // refresh, non la scadenza: usarlo come expiresAt rendeva ogni login
14
+ // immediatamente "scaduto". Leggiamo invece il claim `exp`, senza verificare
15
+ // la firma (la verifica resta responsabilita' del server quando il token viene
16
+ // usato).
17
+ export function jwtExpiresAt(token) {
18
+ const payload = String(token || "").split(".")[1];
19
+ if (!payload)
20
+ return 0;
21
+ try {
22
+ const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
23
+ const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "=");
24
+ const parsed = JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
25
+ const seconds = numericEpoch(parsed["exp"]);
26
+ return seconds > 0 ? seconds * 1000 : 0;
27
+ }
28
+ catch {
29
+ return 0;
30
+ }
31
+ }
32
+ function claudeFile(env) {
33
+ const dir = env["CLAUDE_CONFIG_DIR"] || join(homedir(), ".claude");
34
+ return join(dir, ".credentials.json");
35
+ }
36
+ function codexFile(env) {
37
+ const dir = env["CODEX_HOME"] || join(homedir(), ".codex");
38
+ return join(dir, "auth.json");
39
+ }
40
+ function readJson(path) {
41
+ try {
42
+ if (!existsSync(path))
43
+ return null;
44
+ const data = JSON.parse(readFileSync(path, "utf8"));
45
+ return typeof data === "object" && data !== null
46
+ ? data
47
+ : null;
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ // Credenziali Claude Code. Priorita': token diretto da env (claude setup-token),
54
+ // poi il file .credentials.json (campo claudeAiOauth).
55
+ export function readClaudeCreds(env) {
56
+ const direct = String(env["CLAUDE_CODE_OAUTH_TOKEN"] ?? "").trim();
57
+ if (direct)
58
+ return { accessToken: direct, refreshToken: "", expiresAt: 0 };
59
+ const json = readJson(claudeFile(env));
60
+ const o = json?.["claudeAiOauth"];
61
+ if (!o)
62
+ return null;
63
+ const accessToken = String(o["accessToken"] ?? "");
64
+ if (!accessToken)
65
+ return null;
66
+ return {
67
+ accessToken,
68
+ refreshToken: String(o["refreshToken"] ?? ""),
69
+ expiresAt: Number(o["expiresAt"] ?? 0),
70
+ };
71
+ }
72
+ // Credenziali ChatGPT/Codex (subscription). Il file ha { tokens: {...} } oppure
73
+ // una OPENAI_API_KEY (che NON e' un abbonamento: la ignoriamo qui).
74
+ export function readCodexCreds(env) {
75
+ const json = readJson(codexFile(env));
76
+ const authMode = String(json?.["auth_mode"] ?? "").trim().toLowerCase().replace(/[_\s-]+/g, "");
77
+ // Dopo l'unificazione di Codex con ChatGPT il provider resta OpenAI, mentre
78
+ // questo campo e' l'autorita' sul tipo di consumo. Token rimasti da un login
79
+ // precedente non devono trasformare `apiKey` in un falso abbonamento.
80
+ if (authMode && authMode !== "chatgpt" && authMode !== "chatgptauthtokens")
81
+ return null;
82
+ const t = json?.["tokens"];
83
+ if (!t)
84
+ return null;
85
+ const accessToken = String(t["access_token"] ?? "");
86
+ if (!accessToken)
87
+ return null;
88
+ return {
89
+ accessToken,
90
+ refreshToken: String(t["refresh_token"] ?? ""),
91
+ // `expires_at` e' il campo Talos best-effort; per i file creati dal CLI
92
+ // ufficiale ricaviamo la scadenza dal JWT. `last_refresh` non va usato.
93
+ expiresAt: numericEpoch(json?.["expires_at"]) || jwtExpiresAt(accessToken),
94
+ accountId: String(t["account_id"] ?? "") || undefined,
95
+ };
96
+ }
97
+ // Persiste i token Claude rinnovati nel file (best-effort).
98
+ export function writeClaudeCreds(env, creds) {
99
+ try {
100
+ const path = claudeFile(env);
101
+ const json = readJson(path) ?? {};
102
+ json["claudeAiOauth"] = {
103
+ ...json["claudeAiOauth"],
104
+ accessToken: creds.accessToken,
105
+ refreshToken: creds.refreshToken,
106
+ expiresAt: creds.expiresAt,
107
+ };
108
+ writeFileSync(path, JSON.stringify(json, null, 2), "utf8");
109
+ }
110
+ catch {
111
+ /* persistenza best-effort: se fallisce, si rifa' refresh al prossimo giro */
112
+ }
113
+ }
114
+ export function writeCodexCreds(env, creds) {
115
+ try {
116
+ const path = codexFile(env);
117
+ const json = readJson(path) ?? {};
118
+ const prev = json["tokens"] ?? {};
119
+ json["auth_mode"] = "chatgpt";
120
+ json["tokens"] = {
121
+ ...prev,
122
+ access_token: creds.accessToken,
123
+ refresh_token: creds.refreshToken,
124
+ account_id: creds.accountId ?? prev["account_id"],
125
+ };
126
+ // Mantiene il formato usato dal CLI Codex e conserva separatamente la
127
+ // scadenza calcolata da Talos.
128
+ json["last_refresh"] = new Date().toISOString();
129
+ json["expires_at"] = creds.expiresAt;
130
+ writeFileSync(path, JSON.stringify(json, null, 2), "utf8");
131
+ }
132
+ catch {
133
+ /* best-effort */
134
+ }
135
+ }
136
+ // True se il token e' scaduto (o lo sara' entro 60s). expiresAt 0 = non lo sappiamo.
137
+ export function isExpired(creds, now) {
138
+ return creds.expiresAt > 0 && creds.expiresAt - 60_000 <= now;
139
+ }