@vascend/talos 0.1.0 → 0.1.1

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 (66) hide show
  1. package/README.md +7 -3
  2. package/dist/backend/asset-events.js +9 -9
  3. package/dist/core/agent.js +3 -3
  4. package/dist/core/cli-args.js +50 -50
  5. package/dist/core/cli-installation.d.ts +4 -0
  6. package/dist/core/cli-installation.js +55 -0
  7. package/dist/core/compaction.js +26 -26
  8. package/dist/core/config.js +101 -101
  9. package/dist/core/execution-guidance.js +21 -21
  10. package/dist/core/package-update.d.ts +3 -1
  11. package/dist/core/package-update.js +19 -6
  12. package/dist/core/self-update.d.ts +1 -1
  13. package/dist/core/signed-release.d.ts +33 -0
  14. package/dist/core/signed-release.js +121 -0
  15. package/dist/core/update-check.d.ts +1 -1
  16. package/dist/core/update-check.js +15 -14
  17. package/dist/core/vibe-modes.js +13 -13
  18. package/dist/distribution/install.d.ts +1 -0
  19. package/dist/distribution/install.js +31 -0
  20. package/dist/install.mjs +271 -0
  21. package/dist/node-runtime.json +13 -0
  22. package/dist/providers/oauth-callback-server.js +32 -32
  23. package/dist/tools/capabilities.js +30 -30
  24. package/dist/tools/computer-capture.js +50 -50
  25. package/dist/tools/program.js +82 -82
  26. package/dist/tui/i18n-catalog.js +16 -0
  27. package/dist/tui/quick-help.js +31 -31
  28. package/dist/tui/repl.js +5 -5
  29. package/dist/tui/update-prompt.js +1 -0
  30. package/dist/vascend/code-events.js +9 -9
  31. package/dist/vascend/completeness.js +31 -31
  32. package/dist/vascend/context-fabric.js +16 -16
  33. package/dist/vascend/contract-memory.js +30 -30
  34. package/dist/vascend/council.js +82 -82
  35. package/dist/vascend/decision-promotion.js +23 -23
  36. package/dist/vascend/granular-kingdom.js +17 -17
  37. package/dist/vascend/granular-launcher.js +2 -2
  38. package/dist/vascend/kingdom-kpi.js +19 -19
  39. package/dist/vascend/kingdom-run.js +6 -6
  40. package/dist/vascend/kingdom.js +56 -56
  41. package/dist/vascend/mandate.js +21 -21
  42. package/dist/vascend/objective-revision.js +34 -34
  43. package/dist/vascend/patch-plan.js +22 -22
  44. package/dist/vascend/requirements.js +29 -29
  45. package/dist/vascend/reviewer.js +26 -26
  46. package/dist/vascend/room-memory.js +25 -25
  47. package/dist/vascend/runtime.js +44 -44
  48. package/dist/vascend/self-improve.js +39 -39
  49. package/dist/vascend/test-failure-memory.js +9 -9
  50. package/dist/vascend/vision.js +18 -18
  51. package/dist/vendor/computer-use/README.md +7 -7
  52. package/dist/vendor/computer-use/computer-desktop.js +211 -211
  53. package/dist/vendor/computer-use/computer-observe.js +315 -315
  54. package/dist/vendor/computer-use/computer-scripts.js +1230 -1230
  55. package/dist/vendor/computer-use/computer-tools.js +2136 -2136
  56. package/dist/vendor/computer-use/package.json +1 -1
  57. package/dist/vendor/computer-use/rac/atomic-input.js +91 -91
  58. package/dist/vendor/computer-use/rac/grammatica.js +101 -101
  59. package/dist/vendor/computer-use/rac/parser.js +185 -185
  60. package/dist/vendor/computer-use/rac/protocol.js +136 -136
  61. package/install.ps1 +374 -30
  62. package/install.sh +356 -43
  63. package/package.json +2 -2
  64. package/dist/core/kingdoms-mode-state.d.ts +0 -24
  65. package/dist/core/kingdoms-mode-state.js +0 -139
  66. package/dist/text-sanitize.js +0 -28
@@ -12,38 +12,38 @@ function escapeHtml(s) {
12
12
  // funziona anche offline e senza ulteriori richieste verso il server.
13
13
  function page(title, message, ok) {
14
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>
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
47
  </html>`;
48
48
  }
49
49
  const DEFAULT_SUCCESS_HTML = page("Autorizzazione completata", "Puoi chiudere questa scheda e tornare al terminale.", true);
@@ -22,34 +22,34 @@ export const BUILTIN_CONTINUATIONS = {
22
22
  bash: ["bash_output"], vascend_plan: ["vascend_mark", "vascend_status"],
23
23
  skill_search: ["skill_load"], team_engage: ["team_say", "team_inbox", "team_report"],
24
24
  };
25
- export const COMPACT_TOOL_GUIDANCE = `Tool protocol: resolve and execute
26
- All operation names mentioned elsewhere (bash, read_file, vascend_plan, ask_user, etc.)
27
- are internal tools. Use execute to call them; only tools in the native list can be
28
- called at top level. Interpret the user's language yourself and emit stable capability
29
- IDs; never translate file paths, search patterns or user data to discover a tool.
30
- resolve({capabilities:["process.run","files.edit"]}) returns exact tools, full input
31
- contracts, continuations and a catalog revision. Reuse that revision and the contracts
32
- until stale_contract; do not resolve again for tools you already know.
33
- Families: files, process, output, plan, memory, user, workspace, code, web, image,
34
- skills, team, branches, market. resolve({namespace:"files"}) lists that family's
35
- operations; resolve({namespace:"tools"}) lists all installed tools in pages, including
36
- extensions. resolve({names:["read_file","output_page"]}) gets known names in one call.
37
- Common capabilities: files.read/write/edit/search/find/list, process.run/observe,
38
- plan.create/update/inspect/note, user.ask, memory.recall, output.read.
39
- For one operation: execute({mode:"call",revision,tool:"read_file",args:{path:"src/a.ts"}}).
40
- Prefer call mode for shell scripts and file edits. Use write_file/edit_file for UTF-8
41
- source changes. In Python always specify encoding="utf-8" when reading/writing text.
42
- For sequences, pass payloads in data: execute({mode:"program",revision,data:{path:"src/a.ts"},code:"return await tools.read_file({path:tools.$data.path});"}).
43
- Keep scripts, file content and multiline text in data, never inside JavaScript
44
- string literals; tools.$data contains this invocation's data, default {}.
45
- Programs have tools, state, console and await; state persists per session, return emits
46
- the result. Tools return text; tools.$result(name,args) also returns structuredContent,
47
- content and isError. Keep intermediate data in state and return only useful evidence.
48
- Await dependent writes and approvals sequentially; use bounded Promise.allSettled for
49
- independent work and inspect every outcome. Do not repeat a completed action on error.
50
- Prefer process.run with bash for rg, rg --files and git. Follow background processes
51
- with bash_output through execute until the final exit status. Unknown or unavailable
52
- capabilities require catalog inspection or independent work, never invented tool names.
53
- The revision checks catalog freshness, not permission. All existing permission gates
54
- still apply. Tools marked native must be called directly, including for images or
25
+ export const COMPACT_TOOL_GUIDANCE = `Tool protocol: resolve and execute
26
+ All operation names mentioned elsewhere (bash, read_file, vascend_plan, ask_user, etc.)
27
+ are internal tools. Use execute to call them; only tools in the native list can be
28
+ called at top level. Interpret the user's language yourself and emit stable capability
29
+ IDs; never translate file paths, search patterns or user data to discover a tool.
30
+ resolve({capabilities:["process.run","files.edit"]}) returns exact tools, full input
31
+ contracts, continuations and a catalog revision. Reuse that revision and the contracts
32
+ until stale_contract; do not resolve again for tools you already know.
33
+ Families: files, process, output, plan, memory, user, workspace, code, web, image,
34
+ skills, team, branches, market. resolve({namespace:"files"}) lists that family's
35
+ operations; resolve({namespace:"tools"}) lists all installed tools in pages, including
36
+ extensions. resolve({names:["read_file","output_page"]}) gets known names in one call.
37
+ Common capabilities: files.read/write/edit/search/find/list, process.run/observe,
38
+ plan.create/update/inspect/note, user.ask, memory.recall, output.read.
39
+ For one operation: execute({mode:"call",revision,tool:"read_file",args:{path:"src/a.ts"}}).
40
+ Prefer call mode for shell scripts and file edits. Use write_file/edit_file for UTF-8
41
+ source changes. In Python always specify encoding="utf-8" when reading/writing text.
42
+ For sequences, pass payloads in data: execute({mode:"program",revision,data:{path:"src/a.ts"},code:"return await tools.read_file({path:tools.$data.path});"}).
43
+ Keep scripts, file content and multiline text in data, never inside JavaScript
44
+ string literals; tools.$data contains this invocation's data, default {}.
45
+ Programs have tools, state, console and await; state persists per session, return emits
46
+ the result. Tools return text; tools.$result(name,args) also returns structuredContent,
47
+ content and isError. Keep intermediate data in state and return only useful evidence.
48
+ Await dependent writes and approvals sequentially; use bounded Promise.allSettled for
49
+ independent work and inspect every outcome. Do not repeat a completed action on error.
50
+ Prefer process.run with bash for rg, rg --files and git. Follow background processes
51
+ with bash_output through execute until the final exit status. Unknown or unavailable
52
+ capabilities require catalog inspection or independent work, never invented tool names.
53
+ The revision checks catalog freshness, not permission. All existing permission gates
54
+ still apply. Tools marked native must be called directly, including for images or
55
55
  incremental computer control when their contract requires it.`;
@@ -1,55 +1,55 @@
1
1
  import { spawn } from "node:child_process";
2
2
  // Fixed program; untrusted coordinates travel as JSON on stdin, never as code.
3
- export const CAPTURE_SCRIPT = String.raw `
4
- $ErrorActionPreference = 'Stop'
5
- Add-Type -AssemblyName System.Drawing
6
- Add-Type -AssemblyName System.Windows.Forms
7
- Add-Type @'
8
- using System;
9
- using System.Runtime.InteropServices;
10
- public static class TalosCapture {
11
- [StructLayout(LayoutKind.Sequential)] public struct Rect { public int Left, Top, Right, Bottom; }
12
- [DllImport("user32.dll")] public static extern bool SetProcessDPIAware();
13
- [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();
14
- [DllImport("user32.dll")] public static extern bool IsIconic(IntPtr window);
15
- [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr window, out Rect rect);
16
- }
17
- '@
18
- [void][TalosCapture]::SetProcessDPIAware()
19
- $p = [Console]::In.ReadToEnd() | ConvertFrom-Json
20
- $b = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds
21
- if ($p.display) {
22
- $screens = [System.Windows.Forms.Screen]::AllScreens
23
- $selected = $null
24
- for ($i = 0; $i -lt $screens.Length; $i++) {
25
- if ([string]$i -eq [string]$p.display -or $screens[$i].DeviceName -eq [string]$p.display) { $selected = $screens[$i]; break }
26
- }
27
- if ($null -eq $selected) { throw 'Unknown display: use zero-based index or device name' }
28
- $b = $selected.Bounds
29
- }
30
- if ($p.windowId) {
31
- $window = [IntPtr]::new([long]$p.windowId)
32
- if ([TalosCapture]::GetForegroundWindow() -ne $window -or [TalosCapture]::IsIconic($window)) { throw 'Attached window must be visible and in foreground' }
33
- $r = New-Object TalosCapture+Rect
34
- if (-not [TalosCapture]::GetWindowRect($window,[ref]$r)) { throw 'Window is no longer available' }
35
- $b = New-Object System.Drawing.Rectangle($r.Left,$r.Top,($r.Right-$r.Left),($r.Bottom-$r.Top))
36
- }
37
- if ($b.Width -lt 1 -or $b.Height -lt 1 -or ([long]$b.Width*$b.Height) -gt 32000000) { throw 'Invalid capture bounds' }
38
- $bitmap = New-Object System.Drawing.Bitmap($b.Width,$b.Height)
39
- $graphics = [System.Drawing.Graphics]::FromImage($bitmap)
40
- $stream = New-Object System.IO.MemoryStream
41
- $scaled = $null
42
- try {
43
- $graphics.CopyFromScreen($b.Location,[System.Drawing.Point]::Empty,$b.Size)
44
- $scale = [Math]::Min(1,[Math]::Min(1600.0/$b.Width,1000.0/$b.Height))
45
- $w = [Math]::Max(1,[int]($b.Width*$scale)); $h = [Math]::Max(1,[int]($b.Height*$scale))
46
- $scaled = New-Object System.Drawing.Bitmap($bitmap,$w,$h)
47
- $scaled.Save($stream,[System.Drawing.Imaging.ImageFormat]::Png)
48
- @{data=[Convert]::ToBase64String($stream.ToArray());width=$w;height=$h;bounds=@{x=$b.X;y=$b.Y;width=$b.Width;height=$b.Height}} | ConvertTo-Json -Compress
49
- } finally {
50
- if ($null -ne $scaled) { $scaled.Dispose() }
51
- $stream.Dispose(); $graphics.Dispose(); $bitmap.Dispose()
52
- }
3
+ export const CAPTURE_SCRIPT = String.raw `
4
+ $ErrorActionPreference = 'Stop'
5
+ Add-Type -AssemblyName System.Drawing
6
+ Add-Type -AssemblyName System.Windows.Forms
7
+ Add-Type @'
8
+ using System;
9
+ using System.Runtime.InteropServices;
10
+ public static class TalosCapture {
11
+ [StructLayout(LayoutKind.Sequential)] public struct Rect { public int Left, Top, Right, Bottom; }
12
+ [DllImport("user32.dll")] public static extern bool SetProcessDPIAware();
13
+ [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();
14
+ [DllImport("user32.dll")] public static extern bool IsIconic(IntPtr window);
15
+ [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr window, out Rect rect);
16
+ }
17
+ '@
18
+ [void][TalosCapture]::SetProcessDPIAware()
19
+ $p = [Console]::In.ReadToEnd() | ConvertFrom-Json
20
+ $b = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds
21
+ if ($p.display) {
22
+ $screens = [System.Windows.Forms.Screen]::AllScreens
23
+ $selected = $null
24
+ for ($i = 0; $i -lt $screens.Length; $i++) {
25
+ if ([string]$i -eq [string]$p.display -or $screens[$i].DeviceName -eq [string]$p.display) { $selected = $screens[$i]; break }
26
+ }
27
+ if ($null -eq $selected) { throw 'Unknown display: use zero-based index or device name' }
28
+ $b = $selected.Bounds
29
+ }
30
+ if ($p.windowId) {
31
+ $window = [IntPtr]::new([long]$p.windowId)
32
+ if ([TalosCapture]::GetForegroundWindow() -ne $window -or [TalosCapture]::IsIconic($window)) { throw 'Attached window must be visible and in foreground' }
33
+ $r = New-Object TalosCapture+Rect
34
+ if (-not [TalosCapture]::GetWindowRect($window,[ref]$r)) { throw 'Window is no longer available' }
35
+ $b = New-Object System.Drawing.Rectangle($r.Left,$r.Top,($r.Right-$r.Left),($r.Bottom-$r.Top))
36
+ }
37
+ if ($b.Width -lt 1 -or $b.Height -lt 1 -or ([long]$b.Width*$b.Height) -gt 32000000) { throw 'Invalid capture bounds' }
38
+ $bitmap = New-Object System.Drawing.Bitmap($b.Width,$b.Height)
39
+ $graphics = [System.Drawing.Graphics]::FromImage($bitmap)
40
+ $stream = New-Object System.IO.MemoryStream
41
+ $scaled = $null
42
+ try {
43
+ $graphics.CopyFromScreen($b.Location,[System.Drawing.Point]::Empty,$b.Size)
44
+ $scale = [Math]::Min(1,[Math]::Min(1600.0/$b.Width,1000.0/$b.Height))
45
+ $w = [Math]::Max(1,[int]($b.Width*$scale)); $h = [Math]::Max(1,[int]($b.Height*$scale))
46
+ $scaled = New-Object System.Drawing.Bitmap($bitmap,$w,$h)
47
+ $scaled.Save($stream,[System.Drawing.Imaging.ImageFormat]::Png)
48
+ @{data=[Convert]::ToBase64String($stream.ToArray());width=$w;height=$h;bounds=@{x=$b.X;y=$b.Y;width=$b.Width;height=$b.Height}} | ConvertTo-Json -Compress
49
+ } finally {
50
+ if ($null -ne $scaled) { $scaled.Dispose() }
51
+ $stream.Dispose(); $graphics.Dispose(); $bitmap.Dispose()
52
+ }
53
53
  `;
54
54
  export function captureComputerDesktop(input, signal) {
55
55
  if (process.platform !== "win32")
@@ -62,88 +62,88 @@ const BRIDGE_DENYLIST = new Set([
62
62
  // temporaneo content-addressed: niente asset da impacchettare in dist, stesso
63
63
  // comportamento sotto bun, node ed Electron main.
64
64
  // ---------------------------------------------------------------------------
65
- const KERNEL_SOURCE = `"use strict";
66
- const util = require("node:util");
67
- let buf = "";
68
- let seq = 0;
69
- const pending = new Map();
70
- const state = {};
71
- let inputData = {};
72
-
73
- function send(msg) { process.stdout.write(JSON.stringify(msg) + "\\n"); }
74
-
75
- function render(value) {
76
- if (value === undefined) return "";
77
- if (typeof value === "string") return value;
78
- try { return util.inspect(value, { depth: 5, maxArrayLength: 200, maxStringLength: 8000 }); }
79
- catch { return String(value); }
80
- }
81
-
82
- function callTool(name, args, structured = false) {
83
- return new Promise((resolve, reject) => {
84
- seq += 1;
85
- pending.set(seq, { resolve, reject, structured });
86
- send({ t: "call", seq, name, args: args === undefined ? {} : args });
87
- });
88
- }
89
-
90
- // Qualsiasi proprieta' e' una funzione-tool: tools.read_file({...}),
91
- // tools["nome-con-trattini"]({...}). "then" escluso per non sembrare thenable.
92
- const tools = new Proxy({}, {
93
- get(_t, prop) {
94
- if (typeof prop !== "string" || prop === "then" || prop === "toJSON") return undefined;
95
- if (prop === "$data") return inputData;
96
- if (prop === "$result") return (name, args) => callTool(name, args, true);
97
- return (args) => callTool(prop, args);
98
- },
99
- });
100
-
101
- const fakeConsole = {};
102
- for (const level of ["log", "info", "warn", "error", "debug", "trace"]) {
103
- fakeConsole[level] = (...parts) => send({
104
- t: "log",
105
- line: parts.map((p) => (typeof p === "string" ? p : render(p))).join(" "),
106
- });
107
- }
108
-
109
- async function execute(msg) {
110
- inputData = msg.data ?? {};
111
- const AsyncFunction = (async () => {}).constructor;
112
- try {
113
- // require/process oscurati: e' un invito a passare dai tool (che portano i
114
- // permessi), non un confine di sicurezza — il confine e' la conferma utente.
115
- const fn = new AsyncFunction("tools", "state", "console", "require", "process", msg.code);
116
- const value = await fn(tools, state, fakeConsole, undefined, undefined);
117
- send({ t: "done", id: msg.id, value: render(value) });
118
- } catch (err) {
119
- send({ t: "done", id: msg.id, error: err instanceof Error ? (err.stack || err.message) : String(err) });
120
- }
121
- }
122
-
123
- process.stdin.setEncoding("utf8");
124
- process.stdin.on("data", (chunk) => {
125
- buf += chunk;
126
- let idx;
127
- while ((idx = buf.indexOf("\\n")) >= 0) {
128
- const line = buf.slice(0, idx);
129
- buf = buf.slice(idx + 1);
130
- if (!line.trim()) continue;
131
- let msg;
132
- try { msg = JSON.parse(line); } catch { continue; }
133
- if (msg.t === "exec") void execute(msg);
134
- else if (msg.t === "call_result") {
135
- const p = pending.get(msg.seq);
136
- if (!p) continue;
137
- pending.delete(msg.seq);
138
- if (p.structured) p.resolve(msg.result);
139
- else if (msg.isError) p.reject(new Error(String(msg.output ?? "errore tool")));
140
- else p.resolve(String(msg.output ?? ""));
141
- }
142
- }
143
- });
144
- // Il parent muore -> stdin si chiude -> il kernel esce: nessun orfano.
145
- process.stdin.on("end", () => process.exit(0));
146
- process.stdin.resume();
65
+ const KERNEL_SOURCE = `"use strict";
66
+ const util = require("node:util");
67
+ let buf = "";
68
+ let seq = 0;
69
+ const pending = new Map();
70
+ const state = {};
71
+ let inputData = {};
72
+
73
+ function send(msg) { process.stdout.write(JSON.stringify(msg) + "\\n"); }
74
+
75
+ function render(value) {
76
+ if (value === undefined) return "";
77
+ if (typeof value === "string") return value;
78
+ try { return util.inspect(value, { depth: 5, maxArrayLength: 200, maxStringLength: 8000 }); }
79
+ catch { return String(value); }
80
+ }
81
+
82
+ function callTool(name, args, structured = false) {
83
+ return new Promise((resolve, reject) => {
84
+ seq += 1;
85
+ pending.set(seq, { resolve, reject, structured });
86
+ send({ t: "call", seq, name, args: args === undefined ? {} : args });
87
+ });
88
+ }
89
+
90
+ // Qualsiasi proprieta' e' una funzione-tool: tools.read_file({...}),
91
+ // tools["nome-con-trattini"]({...}). "then" escluso per non sembrare thenable.
92
+ const tools = new Proxy({}, {
93
+ get(_t, prop) {
94
+ if (typeof prop !== "string" || prop === "then" || prop === "toJSON") return undefined;
95
+ if (prop === "$data") return inputData;
96
+ if (prop === "$result") return (name, args) => callTool(name, args, true);
97
+ return (args) => callTool(prop, args);
98
+ },
99
+ });
100
+
101
+ const fakeConsole = {};
102
+ for (const level of ["log", "info", "warn", "error", "debug", "trace"]) {
103
+ fakeConsole[level] = (...parts) => send({
104
+ t: "log",
105
+ line: parts.map((p) => (typeof p === "string" ? p : render(p))).join(" "),
106
+ });
107
+ }
108
+
109
+ async function execute(msg) {
110
+ inputData = msg.data ?? {};
111
+ const AsyncFunction = (async () => {}).constructor;
112
+ try {
113
+ // require/process oscurati: e' un invito a passare dai tool (che portano i
114
+ // permessi), non un confine di sicurezza — il confine e' la conferma utente.
115
+ const fn = new AsyncFunction("tools", "state", "console", "require", "process", msg.code);
116
+ const value = await fn(tools, state, fakeConsole, undefined, undefined);
117
+ send({ t: "done", id: msg.id, value: render(value) });
118
+ } catch (err) {
119
+ send({ t: "done", id: msg.id, error: err instanceof Error ? (err.stack || err.message) : String(err) });
120
+ }
121
+ }
122
+
123
+ process.stdin.setEncoding("utf8");
124
+ process.stdin.on("data", (chunk) => {
125
+ buf += chunk;
126
+ let idx;
127
+ while ((idx = buf.indexOf("\\n")) >= 0) {
128
+ const line = buf.slice(0, idx);
129
+ buf = buf.slice(idx + 1);
130
+ if (!line.trim()) continue;
131
+ let msg;
132
+ try { msg = JSON.parse(line); } catch { continue; }
133
+ if (msg.t === "exec") void execute(msg);
134
+ else if (msg.t === "call_result") {
135
+ const p = pending.get(msg.seq);
136
+ if (!p) continue;
137
+ pending.delete(msg.seq);
138
+ if (p.structured) p.resolve(msg.result);
139
+ else if (msg.isError) p.reject(new Error(String(msg.output ?? "errore tool")));
140
+ else p.resolve(String(msg.output ?? ""));
141
+ }
142
+ }
143
+ });
144
+ // Il parent muore -> stdin si chiude -> il kernel esce: nessun orfano.
145
+ process.stdin.on("end", () => process.exit(0));
146
+ process.stdin.resume();
147
147
  `;
148
148
  function unrefStream(stream) {
149
149
  stream?.unref?.();
@@ -1,6 +1,22 @@
1
1
  // English keys correspond to tr()'s stable fallback. User text, tool output,
2
2
  // command names and model identifiers never pass through this catalogue.
3
3
  export const TRANSLATION_ROWS = [
4
+ ["Talos update available", "Actualización de Talos disponible", "Talos-Update verfügbar"],
5
+ ["Skip for now", "Omitir por ahora", "Vorerst überspringen"],
6
+ ["Update now", "Actualizar ahora", "Jetzt aktualisieren"],
7
+ ["Choose", "Elige", "Auswählen"],
8
+ ["Enter 1 or 2.", "Introduce 1 o 2.", "1 oder 2 eingeben."],
9
+ ["Release unavailable or signature verification failed. No files installed. Try again later.", "Versión no disponible o firma no válida. No se ha instalado ningún archivo. Inténtalo más tarde.", "Version nicht verfügbar oder Signaturprüfung fehlgeschlagen. Es wurden keine Dateien installiert. Später erneut versuchen."],
10
+ ["The Talos repository has local changes. Save them before updating.", "El repositorio de Talos tiene cambios locales. Guárdalos antes de actualizar.", "Das Talos-Repository enthält lokale Änderungen. Vor dem Update speichern."],
11
+ ["The Talos repository has diverged from this release. Update it manually.", "El historial del repositorio de Talos ha divergido de esta versión. Actualízalo manualmente.", "Der Verlauf des Talos-Repositorys weicht von dieser Version ab. Manuell aktualisieren."],
12
+ ["Installation not recognized. Update Talos with the package manager used to install it.", "Instalación no reconocida. Actualiza Talos con el gestor de paquetes que usaste para instalarlo.", "Installation nicht erkannt. Talos mit dem Paketmanager aktualisieren, der zur Installation verwendet wurde."],
13
+ ["Installation did not complete. Retry the update with the package manager used to install Talos, then restart talos.", "La instalación no se completó. Reintenta la actualización con el gestor de paquetes que usaste para instalar Talos y reinicia talos.", "Installation nicht abgeschlossen. Das Update mit dem ursprünglichen Paketmanager erneut versuchen und talos neu starten."],
14
+ ["The release does not contain the requested Talos package version.", "La versión publicada no contiene la versión solicitada del paquete Talos.", "Die Veröffentlichung enthält nicht die angeforderte Version des Talos-Pakets."],
15
+ ["Update failed. Check your connection and GitHub access, then try again.", "La actualización falló. Comprueba la conexión y el acceso a GitHub e inténtalo de nuevo.", "Update fehlgeschlagen. Verbindung und GitHub-Zugriff prüfen und erneut versuchen."],
16
+ ["Release downloaded, but installation did not complete. In the Talos repository run bun install --frozen-lockfile and bun run install:cli, then restart talos.", "Versión descargada, pero la instalación no se completó. En el repositorio de Talos ejecuta bun install --frozen-lockfile y bun run install:cli y reinicia talos.", "Version heruntergeladen, aber Installation nicht abgeschlossen. Im Talos-Repository bun install --frozen-lockfile und bun run install:cli ausführen und talos neu starten."],
17
+ ["Updating Talos to {version}…", "Actualizando Talos a {version}…", "Talos wird auf {version} aktualisiert…"],
18
+ ["Talos updated to {version}. Restarting…", "Talos actualizado a {version}. Reiniciando…", "Talos wurde auf {version} aktualisiert. Neustart…"],
19
+ ["Restart talos to use the new version.", "Reinicia talos para usar la nueva versión.", "talos neu starten, um die neue Version zu verwenden."],
4
20
  ["Set reasoning depth", "Ajusta la profundidad del razonamiento", "Denktiefe festlegen"],
5
21
  ["7d n/a", "7d n/d", "7T k. A."],
6
22
  ["Queued follow-up inputs", "Solicitudes en cola", "Anfragen in der Warteschlange"],
@@ -1,28 +1,28 @@
1
1
  // Guida orientata alle azioni; /commands resta il catalogo completo ricercabile.
2
- export const QUICK_HELP = `## Inizia qui
3
- Scrivi una richiesta e premi **Invio**. Talos mostra la risposta nella chat; l'input resta in basso.
4
-
5
- ### Token e contesto
2
+ export const QUICK_HELP = `## Inizia qui
3
+ Scrivi una richiesta e premi **Invio**. Talos mostra la risposta nella chat; l'input resta in basso.
4
+
5
+ ### Token e contesto
6
6
  - **Contesto~** mostra una barra breve con token e percentuale **attivi** e **archiviati**, stimati rispetto alla finestra del modello. Il valore dopo **/** è la capacità della finestra. Sotto l'input, **7g** è la quota settimanale residua e **reset** il tempo rimasto; **~** davanti alla quota indica un dato non recente. Tutte le finestre e i consumi restano in **/usage**.
7
7
  - I blocchi **lime** rappresentano il contesto attivo; i **grigi** la quantità originale archiviata, dal più vecchio (scuro) al più recente (chiaro). **Archiviato** e **attivo** hanno percentuali separate rispetto alla finestra del modello. Il materiale grigio è conservato fuori dalla finestra viva; riassunti e riferimenti fanno parte dell'attivo. **×N** indica la scala della barra quando il totale supera una finestra. Dettagli in **/context**.
8
- - Il totale in **/usage** somma i token delle chiamate della sessione, anche input ripetuti e cache: non indica il contesto di una singola richiesta. **≥** significa totale parziale.
9
- - Talos seleziona informazioni rilevanti e gestisce la cronologia con recupero e compattazione secondo la configurazione; i consumi del provider restano reali.
10
- - **ctx~** è una stima locale del contesto, non la misura esatta del payload inviato. La quota ChatGPT è separata. **/usage** mostra dettagli, cache e ultima chiamata.
11
-
12
- ### Copiare e incollare
13
- - **/copy** copia l'ultima risposta testuale, senza colori del terminale (mantiene il Markdown).
14
- - **/copy una frase** copia soltanto il testo scritto dopo il comando.
15
- - Per selezionare una frase dalla chat: trascina il mouse senza tenere Shift, poi usa **Ctrl+Shift+C** (Windows/Linux) o **Cmd+C** (macOS). Dipende dalle impostazioni del terminale.
8
+ - Il totale in **/usage** somma i token delle chiamate della sessione, anche input ripetuti e cache: non indica il contesto di una singola richiesta. **≥** significa totale parziale.
9
+ - Talos seleziona informazioni rilevanti e gestisce la cronologia con recupero e compattazione secondo la configurazione; i consumi del provider restano reali.
10
+ - **ctx~** è una stima locale del contesto, non la misura esatta del payload inviato. La quota ChatGPT è separata. **/usage** mostra dettagli, cache e ultima chiamata.
11
+
12
+ ### Copiare e incollare
13
+ - **/copy** copia l'ultima risposta testuale, senza colori del terminale (mantiene il Markdown).
14
+ - **/copy una frase** copia soltanto il testo scritto dopo il comando.
15
+ - Per selezionare una frase dalla chat: trascina il mouse senza tenere Shift, poi usa **Ctrl+Shift+C** (Windows/Linux) o **Cmd+C** (macOS). Dipende dalle impostazioni del terminale.
16
16
  - Incolla testo con **Ctrl+Shift+V** o **Cmd+V**. **Alt+V** legge un'immagine dagli appunti; puoi anche usare **/img percorso**.
17
17
  - I riferimenti **img #N** e **txt #N** sono evidenziati in ciano nel campo di input e nella chat; il contenuto completo viene allegato all'invio.
18
- - **Ctrl+C non è il comando di copia di Talos.**
19
-
20
- ### Fermare senza perdere il controllo
21
- - Primo **Ctrl+C**: avviso, nessuna azione. Secondo **Ctrl+C entro 2 secondi**: conferma l'azione indicata (fermare il lavoro, svuotare la bozza o uscire).
22
- - Un altro tasto annulla la conferma. **Esc** ferma subito il lavoro; in un menu o una domanda chiude solo quel pannello.
18
+ - **Ctrl+C non è il comando di copia di Talos.**
19
+
20
+ ### Fermare senza perdere il controllo
21
+ - Primo **Ctrl+C**: avviso, nessuna azione. Secondo **Ctrl+C entro 2 secondi**: conferma l'azione indicata (fermare il lavoro, svuotare la bozza o uscire).
22
+ - Un altro tasto annulla la conferma. **Esc** ferma subito il lavoro; in un menu o una domanda chiude solo quel pannello.
23
23
  - Fermare il lavoro conserva i messaggi in coda e li mette in pausa. **Alt+Q** apre la gestione per riprenderli o eliminarli. I processi in background si gestiscono con **/bg**.
24
- - **/quit** esce direttamente. Le chat già inviate restano salvate; le bozze non sono salvate.
25
-
24
+ - **/quit** esce direttamente. Le chat già inviate restano salvate; le bozze non sono salvate.
25
+
26
26
  ### Messaggi in attesa
27
27
  - Sopra l'input, il punto **•** indica i messaggi in attesa e quando verranno consegnati; la riga rientrata **↳** mostra il prossimo messaggio. Normalmente partono in ordine dopo la risposta corrente; **Alt+Q** mostra tutti i messaggi.
28
28
  - **Alt+Q** o **/queue** (anche **/coda**) apre subito la coda: frecce per scegliere, **Invio** modifica, **Canc** elimina, **Shift+Su/Giù** riordina, **p** mette in pausa o riprende.
@@ -38,16 +38,16 @@ Scrivi una richiesta e premi **Invio**. Talos mostra la risposta nella chat; l'i
38
38
  - Fast richiede il relativo supporto del modello e del provider e può aumentare i consumi.
39
39
 
40
40
  ### Ritrovare le chat
41
- - **/new** apre una chat vuota: la precedente resta salvata.
42
- - **/chats** (o **/resume**) apre la ricerca delle chat salvate; scrivi per filtrare, usa le frecce e Invio, Esc per annullare.
43
- - **/rename Titolo** assegna un nome riconoscibile alla chat corrente.
44
- - **/sessions** mostra gli ID; **/resume ID** riprende una chat specifica.
45
-
46
- ### Leggere e navigare
47
- - **PageUp / PageDown**, rotella o **Shift+Su/Giù** scorrono la conversazione senza spostare l'input.
48
- - **Su/Giù** in fondo alla chat richiamano le richieste precedenti. **Tab** completa i comandi.
49
- - **Ctrl+R** apre la revisione delle attività; **Ctrl+O** apre l'elenco dei file modificati: frecce per scegliere, Invio per leggere il confronto, Esc per tornare. **Ctrl+G** o **/todo** apre la lista delle attività, con gruppi e stati: da fare, in corso, completata e fallita.
50
- - **/commands** apre tutti i comandi, con ricerca. **/help** riapre questa guida.
51
-
52
- Le scorciatoie descritte valgono nella TUI interattiva. In terminali remoti, copia e selezione dipendono anche dal client; /copy usa gli appunti della macchina dove gira Talos.
41
+ - **/new** apre una chat vuota: la precedente resta salvata.
42
+ - **/chats** (o **/resume**) apre la ricerca delle chat salvate; scrivi per filtrare, usa le frecce e Invio, Esc per annullare.
43
+ - **/rename Titolo** assegna un nome riconoscibile alla chat corrente.
44
+ - **/sessions** mostra gli ID; **/resume ID** riprende una chat specifica.
45
+
46
+ ### Leggere e navigare
47
+ - **PageUp / PageDown**, rotella o **Shift+Su/Giù** scorrono la conversazione senza spostare l'input.
48
+ - **Su/Giù** in fondo alla chat richiamano le richieste precedenti. **Tab** completa i comandi.
49
+ - **Ctrl+R** apre la revisione delle attività; **Ctrl+O** apre l'elenco dei file modificati: frecce per scegliere, Invio per leggere il confronto, Esc per tornare. **Ctrl+G** o **/todo** apre la lista delle attività, con gruppi e stati: da fare, in corso, completata e fallita.
50
+ - **/commands** apre tutti i comandi, con ricerca. **/help** riapre questa guida.
51
+
52
+ Le scorciatoie descritte valgono nella TUI interattiva. In terminali remoti, copia e selezione dipendono anche dal client; /copy usa gli appunti della macchina dove gira Talos.
53
53
  `;
package/dist/tui/repl.js CHANGED
@@ -966,12 +966,12 @@ async function drive(deps, input, ctl, theme, terminalColumns, stats, signal, ge
966
966
  const conflicts = collectConflicts(reports);
967
967
  const stashList = formatConflictList(conflicts);
968
968
  const gitNote = isolated
969
- ? `\n\n[NOTA_GIT]
970
- @stato[rami]: ogni collaboratore in worktree isolato; rami merge-ati nel ramo base
971
- @conflitti[merge]: ${conflicts.length ? `${conflicts.map((r) => r.slug).join(", ")} NON merge-ati (rami conservati, risoluzione manuale)` : "nessuno"}
969
+ ? `\n\n[NOTA_GIT]
970
+ @stato[rami]: ogni collaboratore in worktree isolato; rami merge-ati nel ramo base
971
+ @conflitti[merge]: ${conflicts.length ? `${conflicts.map((r) => r.slug).join(", ")} NON merge-ati (rami conservati, risoluzione manuale)` : "nessuno"}
972
972
  @azione[consegna]: verifica diff e controlli nel ramo base; push solo se richiesto dall'utente`
973
- : `\n\n[NOTA_GIT]
974
- @stato[modifiche]: nel working tree, NON committate (i collaboratori non fanno git: working dir condivisa)
973
+ : `\n\n[NOTA_GIT]
974
+ @stato[modifiche]: nel working tree, NON committate (i collaboratori non fanno git: working dir condivisa)
975
975
  @azione[consegna]: verifica diff e controlli; commit e push solo se richiesti dall'utente`;
976
976
  const stashNote = stashList ? `\n\n${stashList}` : "";
977
977
  // GATE KPI DI REGNO (opt-in: solo se self-improve e' abilitato). Misura
@@ -46,6 +46,7 @@ export function promptForUpdate(update, input = stdin, output = stdout) {
46
46
  }
47
47
  function failureMessage(reason) {
48
48
  switch (reason) {
49
+ case "verification": return tr("Release non disponibile o verifica della firma fallita. Nessun file installato. Riprova piu' tardi.", "Release unavailable or signature verification failed. No files installed. Try again later.");
49
50
  case "modified": return tr("Il repository di Talos contiene modifiche locali. Salvale prima di aggiornare.", "The Talos repository has local changes. Save them before updating.");
50
51
  case "diverged": return tr("Il repository di Talos ha una cronologia divergente dalla release. Aggiornalo manualmente.", "The Talos repository has diverged from this release. Update it manually.");
51
52
  case "unsupported": return tr("Installazione non riconosciuta. Aggiorna Talos con il gestore usato per installarlo.", "Installation not recognized. Update Talos with the package manager used to install it.");
@@ -133,15 +133,15 @@ export function codeEventToMemoryInput(event) {
133
133
  links.push({ rel: "covers", target: c, domain: "code" });
134
134
  }
135
135
  const rel = `@R: ${event.file} -> ${event.type} -> ${subject} [ ${action} ]`;
136
- const body = `INDICE
137
- ${uniqTerms.map((t, i) => `${i + 1} = ${t}`).join("\n")}
138
-
139
- DEFINIZIONI
140
- ${def.join("\n")}
141
-
142
- RELAZIONI
143
- ${rel}
144
-
136
+ const body = `INDICE
137
+ ${uniqTerms.map((t, i) => `${i + 1} = ${t}`).join("\n")}
138
+
139
+ DEFINIZIONI
140
+ ${def.join("\n")}
141
+
142
+ RELAZIONI
143
+ ${rel}
144
+
145
145
  OUTPUT: ${summary}; richiamabile via recall.`;
146
146
  // I test falliti e i contratti cambiati sono prerequisiti caldi: confidence
147
147
  // alta cosi' lo scorer del Context Window Compiler li privilegia.