@vascend/talos 0.1.4 → 0.1.6

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 (251) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +37 -12
  3. package/dist/core/agent.d.ts +16 -3
  4. package/dist/core/agent.js +170 -70
  5. package/dist/core/background.d.ts +10 -3
  6. package/dist/core/background.js +55 -9
  7. package/dist/core/bootstrap.js +1 -0
  8. package/dist/core/compaction.js +1 -1
  9. package/dist/core/config-storage.d.ts +5 -0
  10. package/dist/core/config-storage.js +83 -0
  11. package/dist/core/config.d.ts +11 -2
  12. package/dist/core/config.js +24 -8
  13. package/dist/core/context-ledger.js +2 -1
  14. package/dist/core/context-policy.d.ts +1 -1
  15. package/dist/core/context-policy.js +10 -7
  16. package/dist/core/credentials.js +29 -30
  17. package/dist/core/effort.d.ts +1 -1
  18. package/dist/core/effort.js +5 -1
  19. package/dist/core/execution-guidance.d.ts +1 -1
  20. package/dist/core/execution-guidance.js +2 -0
  21. package/dist/core/file-coordination.d.ts +3 -0
  22. package/dist/core/file-coordination.js +28 -0
  23. package/dist/core/file-lease-store.d.ts +3 -0
  24. package/dist/core/file-lease-store.js +28 -12
  25. package/dist/core/fusion.d.ts +24 -0
  26. package/dist/core/fusion.js +80 -0
  27. package/dist/core/model-limits.d.ts +1 -0
  28. package/dist/core/model-limits.js +5 -1
  29. package/dist/core/permission-queue.js +15 -15
  30. package/dist/core/request-plan.js +4 -3
  31. package/dist/core/session-naming.d.ts +3 -0
  32. package/dist/core/session-naming.js +47 -0
  33. package/dist/core/session-usage.js +4 -1
  34. package/dist/core/session.d.ts +5 -2
  35. package/dist/core/session.js +22 -7
  36. package/dist/core/settings.d.ts +2 -0
  37. package/dist/core/settings.js +5 -16
  38. package/dist/core/step-policy.d.ts +18 -0
  39. package/dist/core/step-policy.js +6 -0
  40. package/dist/core/storage-health.d.ts +24 -0
  41. package/dist/core/storage-health.js +72 -0
  42. package/dist/core/tool-artifacts.d.ts +2 -0
  43. package/dist/core/tool-artifacts.js +21 -3
  44. package/dist/core/tool-result-index.js +29 -33
  45. package/dist/core/tool-result-store.js +6 -5
  46. package/dist/core/types.d.ts +26 -2
  47. package/dist/core/user-inbox.d.ts +9 -0
  48. package/dist/core/user-inbox.js +22 -3
  49. package/dist/core/user-input.js +1 -1
  50. package/dist/fusion/autopilot-fast.d.ts +59 -0
  51. package/dist/fusion/autopilot-fast.js +213 -0
  52. package/dist/fusion/autopilot.d.ts +75 -0
  53. package/dist/fusion/autopilot.js +308 -0
  54. package/dist/fusion/focus.d.ts +30 -0
  55. package/dist/fusion/focus.js +122 -0
  56. package/dist/fusion/gate.d.ts +30 -0
  57. package/dist/fusion/gate.js +95 -0
  58. package/dist/fusion/jev.d.ts +71 -0
  59. package/dist/fusion/jev.js +164 -0
  60. package/dist/fusion/receipts.d.ts +25 -0
  61. package/dist/fusion/receipts.js +34 -0
  62. package/dist/fusion/route.d.ts +25 -0
  63. package/dist/fusion/route.js +84 -0
  64. package/dist/fusion/run.d.ts +4 -0
  65. package/dist/fusion/run.js +186 -0
  66. package/dist/horizon/engine.d.ts +20 -1
  67. package/dist/horizon/engine.js +57 -0
  68. package/dist/horizon/index.d.ts +2 -2
  69. package/dist/horizon/index.js +1 -1
  70. package/dist/horizon/types.d.ts +29 -0
  71. package/dist/index.js +12 -0
  72. package/dist/providers/anthropic-oauth.d.ts +8 -3
  73. package/dist/providers/anthropic-oauth.js +13 -10
  74. package/dist/providers/anthropic.d.ts +9 -2
  75. package/dist/providers/anthropic.js +64 -21
  76. package/dist/providers/cli-models.d.ts +30 -0
  77. package/dist/providers/cli-models.js +194 -0
  78. package/dist/providers/model-effort.js +1 -1
  79. package/dist/providers/openai-oauth.d.ts +8 -3
  80. package/dist/providers/openai-oauth.js +9 -3
  81. package/dist/providers/openrouter-manual-fallback.d.ts +3 -1
  82. package/dist/providers/openrouter-manual-fallback.js +20 -20
  83. package/dist/providers/registry.js +3 -2
  84. package/dist/providers/retry.d.ts +3 -0
  85. package/dist/providers/retry.js +44 -1
  86. package/dist/remote/cifratura.d.ts +12 -0
  87. package/dist/remote/cifratura.js +66 -0
  88. package/dist/remote/index.d.ts +15 -0
  89. package/dist/remote/index.js +65 -0
  90. package/dist/remote/relay-client.d.ts +58 -0
  91. package/dist/remote/relay-client.js +315 -0
  92. package/dist/remote/sessione-remota.d.ts +60 -0
  93. package/dist/remote/sessione-remota.js +266 -0
  94. package/dist/sdk.d.ts +7 -2
  95. package/dist/sdk.js +3 -1
  96. package/dist/tools/builtin.js +41 -20
  97. package/dist/tools/capabilities.d.ts +3 -1
  98. package/dist/tools/capabilities.js +5 -2
  99. package/dist/tools/computer-use.js +2 -1
  100. package/dist/tools/pagination.js +1 -1
  101. package/dist/tools/program.js +34 -21
  102. package/dist/tools/team-tools.js +11 -6
  103. package/dist/tui/account-entry.js +14 -9
  104. package/dist/tui/agent-label.d.ts +2 -0
  105. package/dist/tui/agent-label.js +5 -0
  106. package/dist/tui/agent-sessions-screen.d.ts +35 -0
  107. package/dist/tui/agent-sessions-screen.js +178 -0
  108. package/dist/tui/agent-sessions.d.ts +53 -0
  109. package/dist/tui/agent-sessions.js +236 -0
  110. package/dist/tui/bottom-input.d.ts +57 -2
  111. package/dist/tui/bottom-input.js +449 -54
  112. package/dist/tui/branding.js +8 -4
  113. package/dist/tui/capability-lists.d.ts +10 -0
  114. package/dist/tui/capability-lists.js +41 -0
  115. package/dist/tui/command-output-registry.js +4 -0
  116. package/dist/tui/command-transcript.d.ts +1 -1
  117. package/dist/tui/command-transcript.js +17 -21
  118. package/dist/tui/commands.js +6 -2
  119. package/dist/tui/compaction-status.d.ts +7 -0
  120. package/dist/tui/compaction-status.js +39 -0
  121. package/dist/tui/config-recovery.d.ts +12 -0
  122. package/dist/tui/config-recovery.js +54 -0
  123. package/dist/tui/context-meter.d.ts +3 -0
  124. package/dist/tui/context-meter.js +35 -8
  125. package/dist/tui/diff.d.ts +9 -0
  126. package/dist/tui/diff.js +43 -19
  127. package/dist/tui/fusion-menu.d.ts +5 -0
  128. package/dist/tui/fusion-menu.js +89 -0
  129. package/dist/tui/i18n-catalog.js +351 -2
  130. package/dist/tui/live-command.d.ts +1 -0
  131. package/dist/tui/live-command.js +9 -0
  132. package/dist/tui/live-output.d.ts +1 -0
  133. package/dist/tui/live-output.js +11 -0
  134. package/dist/tui/logo.js +3 -0
  135. package/dist/tui/model-details.js +13 -12
  136. package/dist/tui/model-picker.d.ts +2 -0
  137. package/dist/tui/model-picker.js +59 -0
  138. package/dist/tui/model-selection.js +19 -10
  139. package/dist/tui/native-scrollback.d.ts +2 -1
  140. package/dist/tui/native-scrollback.js +31 -6
  141. package/dist/tui/prompt-queue-store.d.ts +1 -0
  142. package/dist/tui/prompt-queue-store.js +4 -0
  143. package/dist/tui/prompt-queue.d.ts +3 -0
  144. package/dist/tui/prompt-queue.js +19 -1
  145. package/dist/tui/provider-label.d.ts +2 -0
  146. package/dist/tui/provider-label.js +9 -0
  147. package/dist/tui/provider-menu.js +25 -24
  148. package/dist/tui/queue-screen.js +2 -1
  149. package/dist/tui/queued-questions.js +2 -4
  150. package/dist/tui/quick-help.d.ts +1 -1
  151. package/dist/tui/quick-help.js +3 -0
  152. package/dist/tui/remote-command.d.ts +7 -0
  153. package/dist/tui/remote-command.js +79 -0
  154. package/dist/tui/repl.d.ts +11 -2
  155. package/dist/tui/repl.js +457 -327
  156. package/dist/tui/review-store.d.ts +8 -1
  157. package/dist/tui/review-store.js +64 -11
  158. package/dist/tui/review-team.js +4 -3
  159. package/dist/tui/runtime-error.d.ts +2 -0
  160. package/dist/tui/runtime-error.js +26 -0
  161. package/dist/tui/scrollback-archive.d.ts +16 -0
  162. package/dist/tui/scrollback-archive.js +90 -0
  163. package/dist/tui/selector-mouse.d.ts +1 -0
  164. package/dist/tui/selector-mouse.js +1 -1
  165. package/dist/tui/selector.d.ts +11 -0
  166. package/dist/tui/selector.js +28 -4
  167. package/dist/tui/session-controls.d.ts +26 -0
  168. package/dist/tui/session-controls.js +65 -0
  169. package/dist/tui/session-naming-notice.d.ts +14 -0
  170. package/dist/tui/session-naming-notice.js +59 -0
  171. package/dist/tui/session-picker.d.ts +2 -0
  172. package/dist/tui/session-picker.js +32 -0
  173. package/dist/tui/session-replay.d.ts +1 -0
  174. package/dist/tui/session-replay.js +101 -32
  175. package/dist/tui/session-transcript-layout.d.ts +9 -0
  176. package/dist/tui/session-transcript-layout.js +41 -0
  177. package/dist/tui/startup.js +63 -33
  178. package/dist/tui/status-line.d.ts +1 -1
  179. package/dist/tui/status-line.js +20 -12
  180. package/dist/tui/storage-warning.d.ts +2 -0
  181. package/dist/tui/storage-warning.js +35 -0
  182. package/dist/tui/talos-art-data.d.ts +1 -0
  183. package/dist/tui/talos-art-data.js +2 -0
  184. package/dist/tui/talos-art.d.ts +1 -0
  185. package/dist/tui/talos-art.js +9 -0
  186. package/dist/tui/task-labels.d.ts +1 -0
  187. package/dist/tui/task-labels.js +8 -0
  188. package/dist/tui/terminal-text.d.ts +2 -1
  189. package/dist/tui/terminal-text.js +28 -2
  190. package/dist/tui/theme.js +2 -2
  191. package/dist/tui/tool-presentation.d.ts +3 -0
  192. package/dist/tui/tool-presentation.js +98 -0
  193. package/dist/tui/tool-style.js +4 -0
  194. package/dist/tui/transcript-store.d.ts +25 -0
  195. package/dist/tui/transcript-store.js +151 -0
  196. package/dist/tui/usage-footer.d.ts +1 -1
  197. package/dist/tui/usage-footer.js +3 -1
  198. package/dist/tui/vascend-id.d.ts +49 -0
  199. package/dist/tui/vascend-id.js +321 -0
  200. package/dist/tui/web-login-screen.js +4 -3
  201. package/dist/tui/web-login.d.ts +7 -15
  202. package/dist/tui/web-login.js +38 -78
  203. package/dist/tui/worker-transcripts.d.ts +31 -0
  204. package/dist/tui/worker-transcripts.js +91 -0
  205. package/dist/vascend/candidate-collector.d.ts +6 -5
  206. package/dist/vascend/candidate-collector.js +44 -43
  207. package/dist/vascend/context-feedback-loop.js +2 -0
  208. package/dist/vascend/context-lint.js +32 -2
  209. package/dist/vascend/context-market-selection.js +12 -5
  210. package/dist/vascend/context-pack-render.js +10 -4
  211. package/dist/vascend/context-packet-mirrors.d.ts +8 -0
  212. package/dist/vascend/context-packet-mirrors.js +24 -0
  213. package/dist/vascend/context-plan-events.d.ts +4 -0
  214. package/dist/vascend/context-plan-events.js +44 -0
  215. package/dist/vascend/context-snapshot.d.ts +1 -0
  216. package/dist/vascend/context-snapshot.js +8 -5
  217. package/dist/vascend/context-store-reader.d.ts +20 -0
  218. package/dist/vascend/context-store-reader.js +46 -0
  219. package/dist/vascend/context-window-compiler.d.ts +1 -0
  220. package/dist/vascend/context-window-compiler.js +1 -0
  221. package/dist/vascend/file-lock.d.ts +1 -0
  222. package/dist/vascend/file-lock.js +26 -0
  223. package/dist/vascend/granular-kingdom.d.ts +1 -0
  224. package/dist/vascend/granular-kingdom.js +52 -17
  225. package/dist/vascend/kingdom-bus.d.ts +1 -0
  226. package/dist/vascend/kingdom-bus.js +3 -0
  227. package/dist/vascend/kingdom-channel.d.ts +2 -0
  228. package/dist/vascend/kingdom-channel.js +3 -0
  229. package/dist/vascend/kingdom-live.d.ts +32 -4
  230. package/dist/vascend/kingdom-live.js +149 -13
  231. package/dist/vascend/kingdom-run.d.ts +5 -1
  232. package/dist/vascend/kingdom-run.js +6 -2
  233. package/dist/vascend/kingdom.d.ts +3 -0
  234. package/dist/vascend/kingdom.js +22 -11
  235. package/dist/vascend/memory-packet.d.ts +2 -1
  236. package/dist/vascend/memory-packet.js +31 -44
  237. package/dist/vascend/memory-store.d.ts +1 -0
  238. package/dist/vascend/memory-store.js +12 -4
  239. package/dist/vascend/plan-store.d.ts +3 -1
  240. package/dist/vascend/plan-store.js +6 -4
  241. package/dist/vascend/room-memory.d.ts +13 -2
  242. package/dist/vascend/room-memory.js +48 -6
  243. package/dist/vascend/runtime.d.ts +3 -11
  244. package/dist/vascend/runtime.js +11 -123
  245. package/dist/vascend/session-search.js +2 -0
  246. package/dist/vascend/team-session.js +3 -2
  247. package/dist/vascend/vision.d.ts +3 -1
  248. package/dist/vascend/vision.js +6 -4
  249. package/dist/vascend/worker-session.d.ts +20 -0
  250. package/dist/vascend/worker-session.js +83 -0
  251. package/package.json +2 -2
@@ -80,15 +80,39 @@ export function padLine(value, width) {
80
80
  const fitted = fitLine(value, width);
81
81
  return fitted + " ".repeat(Math.max(0, width - terminalWidth(fitted)));
82
82
  }
83
- export function wrapText(value, width, wordWrap = false) {
83
+ // Count hard-wrapped rows without allocating or painting the hidden text.
84
+ export function wrappedLineCount(value, width) {
85
+ const max = Math.max(2, width);
86
+ let count = 0;
87
+ for (const line of plainText(value).split("\n")) {
88
+ if (printableAscii.test(line)) {
89
+ count += Math.max(1, Math.ceil(line.length / Math.floor(max)));
90
+ continue;
91
+ }
92
+ count++;
93
+ let used = 0;
94
+ for (const { segment } of graphemes.segment(line)) {
95
+ const size = cellWidth(segment);
96
+ if (used + size > max) {
97
+ count++;
98
+ used = 0;
99
+ }
100
+ used += size;
101
+ }
102
+ }
103
+ return count;
104
+ }
105
+ export function wrapText(value, width, wordWrap = false, maxLines = Infinity) {
84
106
  const max = Math.max(2, width);
85
107
  const lines = [];
86
108
  for (const line of plainText(value).split("\n")) {
109
+ if (lines.length >= maxLines)
110
+ break;
87
111
  if (!wordWrap && printableAscii.test(line)) {
88
112
  const chunk = Math.max(1, Math.floor(max));
89
113
  if (!line.length)
90
114
  lines.push("");
91
- for (let i = 0; i < line.length; i += chunk)
115
+ for (let i = 0; i < line.length && lines.length < maxLines; i += chunk)
92
116
  lines.push(line.slice(i, i + chunk));
93
117
  continue;
94
118
  }
@@ -108,6 +132,8 @@ export function wrapText(value, width, wordWrap = false) {
108
132
  row = "";
109
133
  used = 0;
110
134
  }
135
+ if (lines.length >= maxLines)
136
+ return lines;
111
137
  if (wordWrap && !row && segment === " ")
112
138
  continue;
113
139
  }
package/dist/tui/theme.js CHANGED
@@ -86,8 +86,8 @@ const VASCEND_DARK_COLORS = {
86
86
  dim: "dimSilver",
87
87
  text: CHAT_TEXT,
88
88
  thinkingText: "darkSilver",
89
- selectedBg: "#30445e",
90
- userMessageBg: "#252c19",
89
+ selectedBg: "#292929",
90
+ userMessageBg: "#2b2b2b",
91
91
  userMessageText: CHAT_TEXT,
92
92
  attachmentRef: "#28aacc",
93
93
  customMessageBg: "#12151b",
@@ -0,0 +1,3 @@
1
+ import type { ToolCallPart } from "../core/types.js";
2
+ export declare function toolLabel(name: string): string;
3
+ export declare function toolArg(call: ToolCallPart): string;
@@ -0,0 +1,98 @@
1
+ import { tr } from "./i18n.js";
2
+ import { oneLine } from "./terminal-text.js";
3
+ function truncate(value, max) {
4
+ if (value.length <= max)
5
+ return value;
6
+ if (max <= 1)
7
+ return value.slice(0, max);
8
+ return `${value.slice(0, max - 1)}…`;
9
+ }
10
+ function compactArgs(input) {
11
+ const value = JSON.stringify(input);
12
+ return value.length > 80 ? value.slice(0, 77) + "..." : value;
13
+ }
14
+ function vascendArg(call) {
15
+ const input = call.input;
16
+ const castle = typeof input["castle"] === "string" && input["castle"] && input["castle"] !== "master"
17
+ ? ` @${input["castle"]}` : "";
18
+ switch (call.name) {
19
+ case "vascend_mark": {
20
+ const task = String(input["task"] ?? "");
21
+ const status = String(input["status"] ?? "completed");
22
+ return truncate(`${task} → ${status}${castle}`, 56);
23
+ }
24
+ case "vascend_plan": {
25
+ const tasks = Array.isArray(input["tasks"]) ? input["tasks"].length : 0;
26
+ const title = typeof input["title"] === "string" ? input["title"] : "";
27
+ const count = tr("{count} attività", "{count} tasks", { count: tasks });
28
+ return truncate(title ? `${title} · ${count}${castle}` : `${count}${castle}`, 60);
29
+ }
30
+ case "vascend_addtasks": {
31
+ const tasks = Array.isArray(input["tasks"]) ? input["tasks"].length : 0;
32
+ return truncate("+" + tr("{count} attività", "{count} tasks", { count: tasks }) + castle, 56);
33
+ }
34
+ case "vascend_note": {
35
+ const task = typeof input["task"] === "string" && input["task"] ? `${input["task"]}: ` : "";
36
+ return truncate(`${task}${String(input["text"] ?? input["note"] ?? "")}`, 56);
37
+ }
38
+ case "vascend_skill": {
39
+ const task = typeof input["task"] === "string" && input["task"] ? `${input["task"]}: ` : "";
40
+ const skills = Array.isArray(input["skills"])
41
+ ? input["skills"].join(", ") : String(input["skills"] ?? input["skill"] ?? "");
42
+ return truncate(`${task}${skills}`, 56);
43
+ }
44
+ default:
45
+ return null;
46
+ }
47
+ }
48
+ export function toolLabel(name) {
49
+ if (/(?:^|_)(?:widget_)?read_me$/.test(name))
50
+ return tr('Istruzioni visuali', 'Visual instructions');
51
+ if (/(?:^|_)(?:visualize|show_widget)$/.test(name))
52
+ return tr('Artifact', 'Artifact');
53
+ const labels = {
54
+ read_file: "Read", write_file: "Write", edit_file: "Update", list_dir: "List",
55
+ bash: "Bash", bash_output: tr("Processo in background", "Background process"), web_fetch: "Fetch", ask_user: "Ask",
56
+ wait: "Wait", tool_search: "ToolSearch", tool_invoke: "Invoke", skill_search: "SkillSearch",
57
+ skill_load: "SkillLoad", output_page: "Page", kingdoms_warm: tr("Collaboratori", "Collaborators"),
58
+ kingdom_send: "Send", kingdom_inbox: "Inbox", kingdom_wait: "WaitMsg", glob: "Glob",
59
+ grep: "Grep", recall: "Recall", image_generate: "Image",
60
+ vascend_plan: tr("Lista attività", "Task list"), vascend_mark: tr("Stato attività", "Task status"),
61
+ vascend_note: "Note", vascend_skill: "Skill",
62
+ vascend_addtasks: tr("Aggiungi attività", "Add tasks"),
63
+ vascend_addrooms: tr("Aggiungi attività", "Add tasks"),
64
+ vascend_status: tr("Lista attività", "Task list"),
65
+ };
66
+ return labels[name] ?? name;
67
+ }
68
+ export function toolArg(call) {
69
+ const path = call.input["path"];
70
+ if (call.name === "run_program") {
71
+ const code = String(call.input["code"] ?? "");
72
+ return tr("JavaScript · {count} righe · Ctrl+R dettagli", "JavaScript · {count} lines · Ctrl+R details", { count: code.split("\n").length });
73
+ }
74
+ if (call.name === "tool_invoke") {
75
+ const inner = String(call.input["name"] ?? "");
76
+ const args = call.input["args"] && typeof call.input["args"] === "object"
77
+ ? compactArgs(call.input["args"]) : "";
78
+ return truncate(`${inner}${args && args !== "{}" ? ` ${args}` : ""}`, 56);
79
+ }
80
+ if (call.name === "tool_search" || call.name === "skill_search")
81
+ return truncate(String(call.input["query"] ?? ""), 50);
82
+ if (call.name === "skill_load")
83
+ return String(call.input["name"] ?? "");
84
+ if (call.name === "grep" || call.name === "glob")
85
+ return truncate(String(call.input["pattern"] ?? ""), 50);
86
+ if (call.name === "wait") {
87
+ const until = call.input["until"];
88
+ return typeof until === "string" && until ? `until ${truncate(until, 44)}` : `${call.input["seconds"] ?? 5}s`;
89
+ }
90
+ const danilov = vascendArg(call);
91
+ if (danilov !== null)
92
+ return danilov;
93
+ if (typeof path === "string" && path)
94
+ return path;
95
+ if (call.name === "bash")
96
+ return truncate(oneLine(String(call.input["command"] ?? "")), 60);
97
+ return compactArgs(call.input);
98
+ }
@@ -39,6 +39,10 @@ const CATEGORY = {
39
39
  image_generate: "image",
40
40
  };
41
41
  export function toolCategory(name) {
42
+ if (/(?:^|_)(?:widget_)?read_me$/.test(name))
43
+ return 'search';
44
+ if (/(?:^|_)(?:visualize|show_widget)$/.test(name))
45
+ return 'image';
42
46
  return CATEGORY[name] ?? "misc";
43
47
  }
44
48
  // Colore PIENO di ogni categoria (tinta a cui punta il pulse), come tripla RGB.
@@ -0,0 +1,25 @@
1
+ export declare class TranscriptStore<T> {
2
+ private readonly maxChars;
3
+ private readonly maxItems;
4
+ private tail;
5
+ private tailChars;
6
+ private stored;
7
+ private chunks;
8
+ private cache;
9
+ private directory?;
10
+ private fd?;
11
+ private bytes;
12
+ constructor(maxChars?: number, maxItems?: number);
13
+ get length(): number;
14
+ get retainedChars(): number;
15
+ push(value: T): void;
16
+ get(index: number): T | undefined;
17
+ set(index: number, value: T): void;
18
+ slice(start?: number, end?: number): T[];
19
+ from(start?: number, end?: number): IterableIterator<T>;
20
+ clear(): void;
21
+ private chunkAt;
22
+ private spill;
23
+ private write;
24
+ private load;
25
+ }
@@ -0,0 +1,151 @@
1
+ import { closeSync, mkdtempSync, openSync, readSync, rmSync, writeSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ // Disposable UI history, not model memory. Keep a small mutable tail and spill
5
+ // complete chunks to disk. Indexed slices read only the visible chunks; resize
6
+ // can replay original events without retaining their entire payload in the heap.
7
+ export class TranscriptStore {
8
+ maxChars;
9
+ maxItems;
10
+ tail = [];
11
+ tailChars = 0;
12
+ stored = 0;
13
+ chunks = [];
14
+ cache = new Map();
15
+ directory;
16
+ fd;
17
+ bytes = 0;
18
+ constructor(maxChars = 256_000, maxItems = 512) {
19
+ this.maxChars = maxChars;
20
+ this.maxItems = maxItems;
21
+ }
22
+ get length() { return this.stored + this.tail.length; }
23
+ get retainedChars() { return this.tailChars; }
24
+ push(value) {
25
+ const size = JSON.stringify(value).length;
26
+ if (this.tail.length && (this.tail.length >= this.maxItems || this.tailChars + size > this.maxChars))
27
+ this.spill();
28
+ this.tail.push(value);
29
+ this.tailChars += size;
30
+ if (this.tailChars >= this.maxChars)
31
+ this.spill();
32
+ }
33
+ get(index) {
34
+ if (index < 0 || index >= this.length)
35
+ return undefined;
36
+ if (index >= this.stored)
37
+ return this.tail[index - this.stored];
38
+ const chunk = this.chunkAt(index);
39
+ return this.load(chunk)[index - this.chunks[chunk].start];
40
+ }
41
+ set(index, value) {
42
+ if (index < 0 || index >= this.length)
43
+ return;
44
+ if (index >= this.stored) {
45
+ const at = index - this.stored;
46
+ this.tailChars += JSON.stringify(value).length - JSON.stringify(this.tail[at]).length;
47
+ this.tail[at] = value;
48
+ if (this.tailChars >= this.maxChars)
49
+ this.spill();
50
+ return;
51
+ }
52
+ const chunk = this.chunkAt(index), previous = this.chunks[chunk];
53
+ const values = [...this.load(chunk)];
54
+ values[index - previous.start] = value;
55
+ this.chunks[chunk] = this.write(values, previous.start);
56
+ this.cache.delete(chunk);
57
+ }
58
+ slice(start = 0, end = this.length) {
59
+ const rows = [];
60
+ for (const value of this.from(start, end))
61
+ rows.push(value);
62
+ return rows;
63
+ }
64
+ *from(start = 0, end = this.length) {
65
+ let index = Math.max(0, start);
66
+ const limit = Math.min(end, this.length);
67
+ while (index < Math.min(limit, this.stored)) {
68
+ const chunk = this.chunkAt(index), info = this.chunks[chunk];
69
+ const values = this.load(chunk), stop = Math.min(limit, info.start + info.count);
70
+ while (index < stop)
71
+ yield values[index++ - info.start];
72
+ }
73
+ while (index < limit)
74
+ yield this.tail[index++ - this.stored];
75
+ }
76
+ clear() {
77
+ this.tail = [];
78
+ this.tailChars = 0;
79
+ this.stored = 0;
80
+ this.chunks = [];
81
+ this.cache.clear();
82
+ this.bytes = 0;
83
+ if (this.fd !== undefined) {
84
+ closeSync(this.fd);
85
+ this.fd = undefined;
86
+ }
87
+ if (this.directory) {
88
+ const directory = this.directory;
89
+ this.directory = undefined;
90
+ try {
91
+ rmSync(directory, { recursive: true, force: true });
92
+ }
93
+ catch { /* Disposable cache may be held by a scanner. */ }
94
+ }
95
+ }
96
+ chunkAt(index) {
97
+ let low = 0, high = this.chunks.length - 1;
98
+ while (low < high) {
99
+ const mid = Math.ceil((low + high) / 2);
100
+ if (this.chunks[mid].start <= index)
101
+ low = mid;
102
+ else
103
+ high = mid - 1;
104
+ }
105
+ return low;
106
+ }
107
+ spill() {
108
+ this.chunks.push(this.write(this.tail, this.stored));
109
+ this.stored += this.tail.length;
110
+ this.tail = [];
111
+ this.tailChars = 0;
112
+ }
113
+ write(values, start) {
114
+ if (this.fd === undefined) {
115
+ this.directory = mkdtempSync(join(tmpdir(), "talos-transcript-"));
116
+ this.fd = openSync(join(this.directory, "chunks.json"), "w+", 0o600);
117
+ }
118
+ const buffer = Buffer.from(JSON.stringify(values));
119
+ const offset = this.bytes;
120
+ let written = 0;
121
+ while (written < buffer.length) {
122
+ const size = writeSync(this.fd, buffer, written, buffer.length - written, offset + written);
123
+ if (!size)
124
+ throw new Error("Unable to write transcript cache");
125
+ written += size;
126
+ }
127
+ this.bytes += written;
128
+ return { start, count: values.length, offset, bytes: written };
129
+ }
130
+ load(index) {
131
+ const cached = this.cache.get(index);
132
+ if (cached)
133
+ return cached;
134
+ const chunk = this.chunks[index], buffer = Buffer.allocUnsafe(chunk.bytes);
135
+ let read = 0;
136
+ while (read < buffer.length) {
137
+ const size = readSync(this.fd, buffer, read, buffer.length - read, chunk.offset + read);
138
+ if (!size)
139
+ throw new Error("Unable to read transcript cache");
140
+ read += size;
141
+ }
142
+ const values = JSON.parse(buffer.toString("utf8"));
143
+ // Oversized single events are read on demand, never retained in the cache.
144
+ if (chunk.bytes <= this.maxChars * 2) {
145
+ this.cache.set(index, values);
146
+ if (this.cache.size > 2)
147
+ this.cache.delete(this.cache.keys().next().value);
148
+ }
149
+ return values;
150
+ }
151
+ }
@@ -2,7 +2,7 @@ import type { PlanLimits } from "../core/types.js";
2
2
  import type { TuiTheme } from "./branding.js";
3
3
  import { type SessionUsageState } from "./session-usage.js";
4
4
  import { type StatusData, type StatusOptions } from "./status-line.js";
5
- export declare const SESSION_USAGE_EXPLANATION = "I token cumulati sono la somma delle chiamate della sessione, inclusi input ripetuti e cache: non sono il contesto di una singola richiesta. Talos seleziona informazioni rilevanti e gestisce la cronologia con recupero e compattazione secondo la configurazione. Questo non annulla i consumi registrati dal provider. \u2265 indica un totale parziale: il consumo noto \u00E8 almeno quello mostrato. Il contesto indicato \u00E8 una stima locale, non una misura esatta del payload inviato.";
5
+ export declare function sessionUsageExplanation(): string;
6
6
  type UsageState = Pick<SessionUsageState, "limits" | "incomplete" | "missing" | "unsaved">;
7
7
  export declare function subscriptionDetails(providerId: string, limits: PlanLimits | undefined, t: TuiTheme, now?: number): string[];
8
8
  export declare function buildUsageFooter(d: StatusData, t: TuiTheme, state: UsageState, providerId: string, opts?: StatusOptions, now?: number): readonly string[];
@@ -4,7 +4,9 @@ import { buildStatusLine, DEFAULT_ORDER } from "./status-line.js";
4
4
  import { fitLine, oneLine, terminalWidth } from "./terminal-text.js";
5
5
  import { buildContextBar } from "./context-bar.js";
6
6
  import { getLanguage, tr } from "./i18n.js";
7
- export const SESSION_USAGE_EXPLANATION = "I token cumulati sono la somma delle chiamate della sessione, inclusi input ripetuti e cache: non sono il contesto di una singola richiesta. Talos seleziona informazioni rilevanti e gestisce la cronologia con recupero e compattazione secondo la configurazione. Questo non annulla i consumi registrati dal provider. ≥ indica un totale parziale: il consumo noto è almeno quello mostrato. Il contesto indicato è una stima locale, non una misura esatta del payload inviato.";
7
+ export function sessionUsageExplanation() {
8
+ return tr("I token cumulati sono la somma delle chiamate della sessione, inclusi input ripetuti e cache: non sono il contesto di una singola richiesta. Talos seleziona informazioni rilevanti e gestisce la cronologia con recupero e compattazione secondo la configurazione. Questo non annulla i consumi registrati dal provider. ≥ indica un totale parziale: il consumo noto è almeno quello mostrato. Il contesto indicato è una stima locale, non una misura esatta del payload inviato.", "Cumulative tokens sum the session's calls, including repeated input and cache: they are not the context of a single request. Talos selects relevant information and manages history through retrieval and compaction according to configuration. This does not erase usage recorded by the provider. ≥ indicates a partial total: known usage is at least the amount shown. The displayed context is a local estimate, not an exact measurement of the payload sent.");
9
+ }
8
10
  const shortLabel = (label) => label.replace("Limite 5 ore", "5h").replace("Settimanale", tr("7g", "7d")).replace("Finestra ", "");
9
11
  const remainingPercent = (window) => window.status === "rejected" ? "0%"
10
12
  : window.utilization !== undefined ? `${Math.round(Math.max(0, Math.min(1, 1 - window.utilization)) * 100)}%` : undefined;
@@ -0,0 +1,49 @@
1
+ export declare const VASCEND_ID_ISSUER = "https://id.vascend.it";
2
+ export declare const VASCEND_ID_CLIENT = "talos";
3
+ export declare const AGENT_RESOURCE = "https://api.vascend.it/agent";
4
+ export declare const RELAY_RESOURCE = "https://relay.vascend.it";
5
+ export declare const LOGIN_RESOURCES: readonly ["https://api.vascend.it/agent", "https://relay.vascend.it"];
6
+ export declare const VASCEND_ID_SCOPE = "openid email offline_access agent sessions";
7
+ type FetchLike = (url: string, init?: RequestInit) => Promise<Response>;
8
+ export interface IdDeps {
9
+ readonly fetchImpl?: FetchLike;
10
+ readonly now?: () => number;
11
+ }
12
+ export interface TokenRisorsa {
13
+ readonly token: string;
14
+ readonly scade: number;
15
+ }
16
+ export interface SessioneId {
17
+ readonly accessToken: string;
18
+ readonly refreshToken: string;
19
+ readonly scade: number;
20
+ readonly email: string;
21
+ readonly risorse?: Readonly<Record<string, TokenRisorsa>>;
22
+ }
23
+ export declare class VascendIdError extends Error {
24
+ readonly code: string;
25
+ constructor(code: string);
26
+ }
27
+ export declare function issuerOf(env: NodeJS.ProcessEnv): string;
28
+ export declare function tokenPlausibile(token: unknown, max?: number): token is string;
29
+ export declare function claimNonVerificati(token: string): Record<string, unknown>;
30
+ export declare function chiamaId(env: NodeJS.ProcessEnv, path: string, campi: Record<string, string | readonly string[]>, deps?: IdDeps, signal?: AbortSignal): Promise<Record<string, unknown>>;
31
+ export declare function sessioneDaRisposta(data: Record<string, unknown>, now: number): SessioneId;
32
+ export declare function sessionePath(env: NodeJS.ProcessEnv): string | null;
33
+ export declare function leggiSessione(env: NodeJS.ProcessEnv): SessioneId | null;
34
+ export declare function salvaSessione(env: NodeJS.ProcessEnv, sessione: SessioneId): boolean;
35
+ export declare function rimuoviSessione(env: NodeJS.ProcessEnv): void;
36
+ export interface EsitoToken {
37
+ readonly token: string;
38
+ readonly email?: string;
39
+ readonly errore?: "assente" | "respinta" | "rete";
40
+ }
41
+ export declare function tokenAgente(env: NodeJS.ProcessEnv, deps?: IdDeps): Promise<EsitoToken>;
42
+ export interface EsitoTokenRisorsa {
43
+ readonly token: string;
44
+ readonly email?: string;
45
+ readonly errore?: "assente" | "respinta" | "rete" | "risorsa";
46
+ }
47
+ export declare function tokenRisorsa(env: NodeJS.ProcessEnv, risorsa: string, deps?: IdDeps): Promise<EsitoTokenRisorsa>;
48
+ export declare function revocaSessioneId(env: NodeJS.ProcessEnv, deps?: IdDeps): Promise<void>;
49
+ export {};