@tokscale/cli 1.2.1 → 1.2.2
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.
- package/dist/native-runner.d.ts +1 -1
- package/dist/native-runner.js +6 -6
- package/dist/native-runner.js.map +1 -1
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js +32 -59
- package/dist/native.js.map +1 -1
- package/dist/tui/config/settings.d.ts +1 -0
- package/dist/tui/config/settings.d.ts.map +1 -1
- package/dist/tui/config/settings.js +10 -2
- package/dist/tui/config/settings.js.map +1 -1
- package/package.json +2 -2
- package/src/native-runner.ts +17 -17
- package/src/native.ts +31 -76
- package/src/tui/config/settings.ts +13 -2
package/dist/native-runner.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* This script runs in a separate process to keep the main event loop free
|
|
6
6
|
* for UI rendering (e.g., spinner animation).
|
|
7
7
|
*
|
|
8
|
-
* Communication:
|
|
8
|
+
* Communication: tmpfile (JSON input) -> tmpfile (JSON output)
|
|
9
9
|
*/
|
|
10
10
|
export {};
|
|
11
11
|
//# sourceMappingURL=native-runner.d.ts.map
|
package/dist/native-runner.js
CHANGED
|
@@ -5,14 +5,15 @@
|
|
|
5
5
|
* This script runs in a separate process to keep the main event loop free
|
|
6
6
|
* for UI rendering (e.g., spinner animation).
|
|
7
7
|
*
|
|
8
|
-
* Communication:
|
|
8
|
+
* Communication: tmpfile (JSON input) -> tmpfile (JSON output)
|
|
9
9
|
*/
|
|
10
10
|
import nativeCore from "@tokscale/core";
|
|
11
|
-
import { readFileSync } from "node:fs";
|
|
11
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
12
12
|
async function main() {
|
|
13
13
|
const inputFile = process.argv[2];
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const outputFile = process.argv[3];
|
|
15
|
+
if (!inputFile || !outputFile) {
|
|
16
|
+
process.stderr.write(JSON.stringify({ error: "Usage: native-runner <inputFile> <outputFile>" }));
|
|
16
17
|
process.exit(1);
|
|
17
18
|
}
|
|
18
19
|
const input = readFileSync(inputFile, "utf-8");
|
|
@@ -47,8 +48,7 @@ async function main() {
|
|
|
47
48
|
default:
|
|
48
49
|
throw new Error(`Unknown method: ${method}`);
|
|
49
50
|
}
|
|
50
|
-
|
|
51
|
-
process.stdout.write(JSON.stringify(result));
|
|
51
|
+
writeFileSync(outputFile, JSON.stringify(result), "utf-8");
|
|
52
52
|
}
|
|
53
53
|
main().catch((e) => {
|
|
54
54
|
const error = e;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-runner.js","sourceRoot":"","sources":["../src/native-runner.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAEH,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"native-runner.js","sourceRoot":"","sources":["../src/native-runner.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAEH,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAOtD,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,+CAA+C,EAAE,CAAC,CAAC,CAAC;QACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAE/C,IAAI,OAA4B,CAAC;IACjC,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAwB,CAAC;IACrD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,yBAA0B,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAEjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,iCAAiC,CAAC,CAAC;IACvF,CAAC;IAED,IAAI,MAAe,CAAC;IAEpB,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,mBAAmB;YACtB,MAAM,GAAG,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAuD,CAAC,CAAC;YACrG,MAAM;QACR,KAAK,gBAAgB;YACnB,MAAM,GAAG,MAAM,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAoD,CAAC,CAAC;YACrG,MAAM;QACR,KAAK,uBAAuB;YAC1B,MAAM,GAAG,MAAM,UAAU,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAA2D,CAAC,CAAC;YACnH,MAAM;QACR,KAAK,eAAe;YAClB,MAAM,GAAG,MAAM,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAmD,CAAC,CAAC;YACnG,MAAM;QACR,KAAK,wBAAwB;YAC3B,MAAM,GAAG,MAAM,UAAU,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAA4D,CAAC,CAAC;YACrH,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;AAC7D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACjB,MAAM,KAAK,GAAG,CAAU,CAAC;IACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;QAClC,KAAK,EAAE,KAAK,CAAC,OAAO;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC,CAAC,CAAC;IACJ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/native.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,qBAAqB,EAErB,UAAU,EACX,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,qBAAqB,EAErB,UAAU,EACX,MAAM,kBAAkB,CAAC;AAoM1B;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEhD;AAuED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAMD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,KAAK,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,cAAc,CAAC;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA0ID,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAchG;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAexF;AAED,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,CAejG;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAgBjG;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,qBAAqB,CAAC;CAC9B;AAOD,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAmBnG"}
|
package/dist/native.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Exposes all Rust functions with proper TypeScript types.
|
|
5
5
|
* Native module is REQUIRED - no TypeScript fallback.
|
|
6
6
|
*/
|
|
7
|
+
import { loadSettings } from "./tui/config/settings.js";
|
|
7
8
|
// =============================================================================
|
|
8
9
|
// Module loading
|
|
9
10
|
// =============================================================================
|
|
@@ -101,16 +102,18 @@ function fromNativeResult(result) {
|
|
|
101
102
|
// =============================================================================
|
|
102
103
|
import { fileURLToPath } from "node:url";
|
|
103
104
|
import { dirname, join } from "node:path";
|
|
104
|
-
import { writeFileSync, unlinkSync, mkdirSync } from "node:fs";
|
|
105
|
+
import { writeFileSync, readFileSync, unlinkSync, mkdirSync, existsSync } from "node:fs";
|
|
105
106
|
import { tmpdir } from "node:os";
|
|
106
107
|
import { randomUUID } from "node:crypto";
|
|
107
108
|
const __filename = fileURLToPath(import.meta.url);
|
|
108
109
|
const __dirname = dirname(__filename);
|
|
109
|
-
const DEFAULT_TIMEOUT_MS = 300_000;
|
|
110
|
-
const NATIVE_TIMEOUT_MS = parseInt(process.env.TOKSCALE_NATIVE_TIMEOUT_MS || String(DEFAULT_TIMEOUT_MS), 10);
|
|
111
110
|
const SIGKILL_GRACE_MS = 500;
|
|
112
|
-
|
|
113
|
-
const
|
|
111
|
+
function getNativeTimeoutMs() {
|
|
112
|
+
const settings = loadSettings();
|
|
113
|
+
return process.env.TOKSCALE_NATIVE_TIMEOUT_MS
|
|
114
|
+
? parseInt(process.env.TOKSCALE_NATIVE_TIMEOUT_MS, 10)
|
|
115
|
+
: (settings.nativeTimeoutMs ?? 300_000);
|
|
116
|
+
}
|
|
114
117
|
function safeKill(proc, signal) {
|
|
115
118
|
try {
|
|
116
119
|
proc.kill(signal);
|
|
@@ -118,28 +121,33 @@ function safeKill(proc, signal) {
|
|
|
118
121
|
catch { }
|
|
119
122
|
}
|
|
120
123
|
async function runInSubprocess(method, args) {
|
|
124
|
+
const NATIVE_TIMEOUT_MS = getNativeTimeoutMs();
|
|
121
125
|
const runnerPath = join(__dirname, "native-runner.js");
|
|
122
126
|
const input = JSON.stringify({ method, args });
|
|
123
127
|
const tmpDir = join(tmpdir(), "tokscale");
|
|
124
128
|
mkdirSync(tmpDir, { recursive: true });
|
|
125
|
-
const
|
|
129
|
+
const id = randomUUID();
|
|
130
|
+
const inputFile = join(tmpDir, `input-${id}.json`);
|
|
131
|
+
const outputFile = join(tmpDir, `output-${id}.json`);
|
|
126
132
|
writeFileSync(inputFile, input, "utf-8");
|
|
127
133
|
const BunGlobal = globalThis.Bun;
|
|
128
134
|
let proc;
|
|
129
135
|
try {
|
|
130
|
-
proc = BunGlobal.spawn([process.execPath, runnerPath, inputFile], {
|
|
131
|
-
stdout: "
|
|
136
|
+
proc = BunGlobal.spawn([process.execPath, runnerPath, inputFile, outputFile], {
|
|
137
|
+
stdout: "ignore",
|
|
132
138
|
stderr: "pipe",
|
|
133
139
|
});
|
|
134
140
|
}
|
|
135
141
|
catch (e) {
|
|
136
|
-
|
|
142
|
+
try {
|
|
143
|
+
unlinkSync(inputFile);
|
|
144
|
+
}
|
|
145
|
+
catch { }
|
|
137
146
|
throw new Error(`Failed to spawn subprocess: ${e.message}`);
|
|
138
147
|
}
|
|
139
148
|
let timeoutId = null;
|
|
140
149
|
let sigkillId = null;
|
|
141
150
|
let weInitiatedKill = false;
|
|
142
|
-
let aborted = false;
|
|
143
151
|
const cleanup = async () => {
|
|
144
152
|
if (timeoutId)
|
|
145
153
|
clearTimeout(timeoutId);
|
|
@@ -149,51 +157,15 @@ async function runInSubprocess(method, args) {
|
|
|
149
157
|
unlinkSync(inputFile);
|
|
150
158
|
}
|
|
151
159
|
catch { }
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
await proc.exited.catch(() => { });
|
|
160
|
+
try {
|
|
161
|
+
unlinkSync(outputFile);
|
|
155
162
|
}
|
|
156
|
-
|
|
157
|
-
const abort = () => {
|
|
158
|
-
aborted = true;
|
|
159
|
-
weInitiatedKill = true;
|
|
163
|
+
catch { }
|
|
160
164
|
};
|
|
161
165
|
try {
|
|
162
|
-
const stdoutChunks = [];
|
|
163
|
-
const stderrChunks = [];
|
|
164
|
-
let stdoutBytes = 0;
|
|
165
|
-
let stderrBytes = 0;
|
|
166
|
-
const readStream = async (stream, chunks, getBytesRef, setBytesRef) => {
|
|
167
|
-
const reader = stream.getReader();
|
|
168
|
-
try {
|
|
169
|
-
while (!aborted) {
|
|
170
|
-
const { done, value } = await reader.read();
|
|
171
|
-
if (done)
|
|
172
|
-
break;
|
|
173
|
-
const newTotal = getBytesRef() + value.length;
|
|
174
|
-
if (newTotal > MAX_OUTPUT_BYTES) {
|
|
175
|
-
abort();
|
|
176
|
-
throw new Error(`Output exceeded ${MAX_OUTPUT_BYTES} bytes`);
|
|
177
|
-
}
|
|
178
|
-
setBytesRef(newTotal);
|
|
179
|
-
chunks.push(value);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
finally {
|
|
183
|
-
await reader.cancel().catch(() => { });
|
|
184
|
-
reader.releaseLock();
|
|
185
|
-
}
|
|
186
|
-
const combined = new Uint8Array(getBytesRef());
|
|
187
|
-
let offset = 0;
|
|
188
|
-
for (const chunk of chunks) {
|
|
189
|
-
combined.set(chunk, offset);
|
|
190
|
-
offset += chunk.length;
|
|
191
|
-
}
|
|
192
|
-
return new TextDecoder().decode(combined);
|
|
193
|
-
};
|
|
194
166
|
const timeoutPromise = new Promise((_, reject) => {
|
|
195
167
|
timeoutId = setTimeout(() => {
|
|
196
|
-
|
|
168
|
+
weInitiatedKill = true;
|
|
197
169
|
safeKill(proc, "SIGTERM");
|
|
198
170
|
sigkillId = setTimeout(() => {
|
|
199
171
|
safeKill(proc, "SIGKILL");
|
|
@@ -201,17 +173,14 @@ async function runInSubprocess(method, args) {
|
|
|
201
173
|
}, SIGKILL_GRACE_MS);
|
|
202
174
|
}, NATIVE_TIMEOUT_MS);
|
|
203
175
|
});
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
proc.exited,
|
|
208
|
-
]);
|
|
209
|
-
const [stdout, stderr, exitCode] = await Promise.race([workPromise, timeoutPromise]);
|
|
210
|
-
// Note: proc.killed is always true after exit in Bun (even for normal exits), so we only check signalCode
|
|
176
|
+
const exitCode = await Promise.race([proc.exited, timeoutPromise]);
|
|
177
|
+
if (timeoutId)
|
|
178
|
+
clearTimeout(timeoutId);
|
|
211
179
|
if (weInitiatedKill || proc.signalCode) {
|
|
212
180
|
throw new Error(`Subprocess '${method}' was killed (signal: ${proc.signalCode || "SIGTERM"})`);
|
|
213
181
|
}
|
|
214
182
|
if (exitCode !== 0) {
|
|
183
|
+
const stderr = await proc.stderr.text();
|
|
215
184
|
let errorMsg = stderr || `Process exited with code ${exitCode}`;
|
|
216
185
|
try {
|
|
217
186
|
const parsed = JSON.parse(stderr);
|
|
@@ -221,11 +190,15 @@ async function runInSubprocess(method, args) {
|
|
|
221
190
|
catch { }
|
|
222
191
|
throw new Error(`Subprocess '${method}' failed: ${errorMsg}`);
|
|
223
192
|
}
|
|
193
|
+
if (!existsSync(outputFile)) {
|
|
194
|
+
throw new Error(`Subprocess '${method}' did not produce output file`);
|
|
195
|
+
}
|
|
224
196
|
try {
|
|
225
|
-
|
|
197
|
+
const output = readFileSync(outputFile, "utf-8");
|
|
198
|
+
return JSON.parse(output);
|
|
226
199
|
}
|
|
227
200
|
catch (e) {
|
|
228
|
-
throw new Error(`Failed to parse subprocess output: ${e.message}
|
|
201
|
+
throw new Error(`Failed to parse subprocess output: ${e.message}`);
|
|
229
202
|
}
|
|
230
203
|
}
|
|
231
204
|
finally {
|
package/dist/native.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.js","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"native.js","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ export interface TokscaleSettings {
|
|
|
4
4
|
autoRefreshEnabled?: boolean;
|
|
5
5
|
autoRefreshMs?: number;
|
|
6
6
|
includeUnusedModels?: boolean;
|
|
7
|
+
nativeTimeoutMs?: number;
|
|
7
8
|
}
|
|
8
9
|
export declare function loadSettings(): TokscaleSettings;
|
|
9
10
|
export declare function saveSettings(updates: Partial<TokscaleSettings>): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/tui/config/settings.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAuB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/tui/config/settings.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAuB,MAAM,mBAAmB,CAAC;AAiBtE,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAyCD,wBAAgB,YAAY,IAAI,gBAAgB,CAa/C;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAUrE;AAeD,wBAAgB,cAAc,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,GAAG,IAAI,CAuB1E;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAmB/E;AAED,wBAAgB,YAAY,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAiBjE;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAUjD"}
|
|
@@ -10,12 +10,16 @@ const CACHE_STALE_THRESHOLD_MS = 60 * 1000;
|
|
|
10
10
|
const MIN_AUTO_REFRESH_MS = 30000;
|
|
11
11
|
const MAX_AUTO_REFRESH_MS = 3600000;
|
|
12
12
|
const DEFAULT_AUTO_REFRESH_MS = 60000;
|
|
13
|
+
const DEFAULT_NATIVE_TIMEOUT_MS = 300_000; // 5 minutes
|
|
14
|
+
const MIN_NATIVE_TIMEOUT_MS = 5_000; // 5 seconds
|
|
15
|
+
const MAX_NATIVE_TIMEOUT_MS = 3_600_000; // 1 hour
|
|
13
16
|
function validateSettings(raw) {
|
|
14
17
|
const defaults = {
|
|
15
18
|
colorPalette: "blue",
|
|
16
19
|
autoRefreshEnabled: false,
|
|
17
20
|
autoRefreshMs: DEFAULT_AUTO_REFRESH_MS,
|
|
18
21
|
includeUnusedModels: false,
|
|
22
|
+
nativeTimeoutMs: DEFAULT_NATIVE_TIMEOUT_MS,
|
|
19
23
|
};
|
|
20
24
|
if (!raw || typeof raw !== "object")
|
|
21
25
|
return defaults;
|
|
@@ -27,7 +31,11 @@ function validateSettings(raw) {
|
|
|
27
31
|
autoRefreshMs = Math.min(MAX_AUTO_REFRESH_MS, Math.max(MIN_AUTO_REFRESH_MS, obj.autoRefreshMs));
|
|
28
32
|
}
|
|
29
33
|
const includeUnusedModels = typeof obj.includeUnusedModels === "boolean" ? obj.includeUnusedModels : defaults.includeUnusedModels;
|
|
30
|
-
|
|
34
|
+
let nativeTimeoutMs = defaults.nativeTimeoutMs;
|
|
35
|
+
if (typeof obj.nativeTimeoutMs === "number" && Number.isFinite(obj.nativeTimeoutMs)) {
|
|
36
|
+
nativeTimeoutMs = Math.min(MAX_NATIVE_TIMEOUT_MS, Math.max(MIN_NATIVE_TIMEOUT_MS, obj.nativeTimeoutMs));
|
|
37
|
+
}
|
|
38
|
+
return { colorPalette, autoRefreshEnabled, autoRefreshMs, includeUnusedModels, nativeTimeoutMs };
|
|
31
39
|
}
|
|
32
40
|
export function loadSettings() {
|
|
33
41
|
try {
|
|
@@ -42,7 +50,7 @@ export function loadSettings() {
|
|
|
42
50
|
}
|
|
43
51
|
catch {
|
|
44
52
|
}
|
|
45
|
-
return { colorPalette: "blue", autoRefreshEnabled: false, autoRefreshMs: DEFAULT_AUTO_REFRESH_MS, includeUnusedModels: false };
|
|
53
|
+
return { colorPalette: "blue", autoRefreshEnabled: false, autoRefreshMs: DEFAULT_AUTO_REFRESH_MS, includeUnusedModels: false, nativeTimeoutMs: DEFAULT_NATIVE_TIMEOUT_MS };
|
|
46
54
|
}
|
|
47
55
|
export function saveSettings(updates) {
|
|
48
56
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/tui/config/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAGxE,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AACxD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;AACtD,MAAM,kBAAkB,GAAG,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;AACjE,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;AAE1D,MAAM,wBAAwB,GAAG,EAAE,GAAG,IAAI,CAAC;AAC3C,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAClC,MAAM,mBAAmB,GAAG,OAAO,CAAC;AACpC,MAAM,uBAAuB,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/tui/config/settings.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokscale/cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "A high-performance CLI tool and visualization dashboard for tracking AI coding assistant token usage and costs across multiple platforms.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@opentui/core": "0.1.60",
|
|
32
32
|
"@opentui/solid": "^0.1.60",
|
|
33
33
|
"@resvg/resvg-js": "^2.6.2",
|
|
34
|
-
"@tokscale/core": "1.2.
|
|
34
|
+
"@tokscale/core": "1.2.2",
|
|
35
35
|
"cli-table3": "^0.6.5",
|
|
36
36
|
"clipboardy": "^5.0.2",
|
|
37
37
|
"commander": "^14.0.2",
|
package/src/native-runner.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
/**
|
|
3
3
|
* Native Runner - Subprocess for non-blocking native Rust calls
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
* This script runs in a separate process to keep the main event loop free
|
|
6
6
|
* for UI rendering (e.g., spinner animation).
|
|
7
|
-
*
|
|
8
|
-
* Communication:
|
|
7
|
+
*
|
|
8
|
+
* Communication: tmpfile (JSON input) -> tmpfile (JSON output)
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import nativeCore from "@tokscale/core";
|
|
12
|
-
import { readFileSync } from "node:fs";
|
|
12
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
13
13
|
|
|
14
14
|
interface NativeRunnerRequest {
|
|
15
15
|
method: string;
|
|
@@ -18,29 +18,30 @@ interface NativeRunnerRequest {
|
|
|
18
18
|
|
|
19
19
|
async function main() {
|
|
20
20
|
const inputFile = process.argv[2];
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
const outputFile = process.argv[3];
|
|
22
|
+
|
|
23
|
+
if (!inputFile || !outputFile) {
|
|
24
|
+
process.stderr.write(JSON.stringify({ error: "Usage: native-runner <inputFile> <outputFile>" }));
|
|
24
25
|
process.exit(1);
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
+
|
|
27
28
|
const input = readFileSync(inputFile, "utf-8");
|
|
28
|
-
|
|
29
|
+
|
|
29
30
|
let request: NativeRunnerRequest;
|
|
30
31
|
try {
|
|
31
32
|
request = JSON.parse(input) as NativeRunnerRequest;
|
|
32
33
|
} catch (e) {
|
|
33
34
|
throw new Error(`Malformed JSON input: ${(e as Error).message}`);
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
+
|
|
36
37
|
const { method, args } = request;
|
|
37
|
-
|
|
38
|
+
|
|
38
39
|
if (!Array.isArray(args) || args.length === 0) {
|
|
39
40
|
throw new Error(`Invalid args for method '${method}': expected at least 1 argument`);
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
+
|
|
42
43
|
let result: unknown;
|
|
43
|
-
|
|
44
|
+
|
|
44
45
|
switch (method) {
|
|
45
46
|
case "parseLocalSources":
|
|
46
47
|
result = nativeCore.parseLocalSources(args[0] as Parameters<typeof nativeCore.parseLocalSources>[0]);
|
|
@@ -60,14 +61,13 @@ async function main() {
|
|
|
60
61
|
default:
|
|
61
62
|
throw new Error(`Unknown method: ${method}`);
|
|
62
63
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
process.stdout.write(JSON.stringify(result));
|
|
64
|
+
|
|
65
|
+
writeFileSync(outputFile, JSON.stringify(result), "utf-8");
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
main().catch((e) => {
|
|
69
69
|
const error = e as Error;
|
|
70
|
-
process.stderr.write(JSON.stringify({
|
|
70
|
+
process.stderr.write(JSON.stringify({
|
|
71
71
|
error: error.message,
|
|
72
72
|
stack: error.stack,
|
|
73
73
|
}));
|
package/src/native.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
GraphOptions as TSGraphOptions,
|
|
11
11
|
SourceType,
|
|
12
12
|
} from "./graph-types.js";
|
|
13
|
+
import { loadSettings } from "./tui/config/settings.js";
|
|
13
14
|
|
|
14
15
|
// =============================================================================
|
|
15
16
|
// Types matching Rust exports
|
|
@@ -381,25 +382,21 @@ export interface FinalizeOptions {
|
|
|
381
382
|
|
|
382
383
|
import { fileURLToPath } from "node:url";
|
|
383
384
|
import { dirname, join } from "node:path";
|
|
384
|
-
import { writeFileSync, unlinkSync, mkdirSync } from "node:fs";
|
|
385
|
+
import { writeFileSync, readFileSync, unlinkSync, mkdirSync, existsSync } from "node:fs";
|
|
385
386
|
import { tmpdir } from "node:os";
|
|
386
387
|
import { randomUUID } from "node:crypto";
|
|
387
388
|
|
|
388
389
|
const __filename = fileURLToPath(import.meta.url);
|
|
389
390
|
const __dirname = dirname(__filename);
|
|
390
391
|
|
|
391
|
-
const DEFAULT_TIMEOUT_MS = 300_000;
|
|
392
|
-
const NATIVE_TIMEOUT_MS = parseInt(
|
|
393
|
-
process.env.TOKSCALE_NATIVE_TIMEOUT_MS || String(DEFAULT_TIMEOUT_MS),
|
|
394
|
-
10
|
|
395
|
-
);
|
|
396
|
-
|
|
397
392
|
const SIGKILL_GRACE_MS = 500;
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
)
|
|
393
|
+
|
|
394
|
+
function getNativeTimeoutMs(): number {
|
|
395
|
+
const settings = loadSettings();
|
|
396
|
+
return process.env.TOKSCALE_NATIVE_TIMEOUT_MS
|
|
397
|
+
? parseInt(process.env.TOKSCALE_NATIVE_TIMEOUT_MS, 10)
|
|
398
|
+
: (settings.nativeTimeoutMs ?? 300_000);
|
|
399
|
+
}
|
|
403
400
|
|
|
404
401
|
interface BunSubprocess {
|
|
405
402
|
stdout: { text: () => Promise<string> };
|
|
@@ -411,8 +408,8 @@ interface BunSubprocess {
|
|
|
411
408
|
}
|
|
412
409
|
|
|
413
410
|
interface BunSpawnOptions {
|
|
414
|
-
stdout:
|
|
415
|
-
stderr:
|
|
411
|
+
stdout: "pipe" | "ignore";
|
|
412
|
+
stderr: "pipe" | "ignore";
|
|
416
413
|
}
|
|
417
414
|
|
|
418
415
|
interface BunGlobalType {
|
|
@@ -426,89 +423,46 @@ function safeKill(proc: unknown, signal?: string): void {
|
|
|
426
423
|
}
|
|
427
424
|
|
|
428
425
|
async function runInSubprocess<T>(method: string, args: unknown[]): Promise<T> {
|
|
426
|
+
const NATIVE_TIMEOUT_MS = getNativeTimeoutMs();
|
|
429
427
|
const runnerPath = join(__dirname, "native-runner.js");
|
|
430
428
|
const input = JSON.stringify({ method, args });
|
|
431
429
|
|
|
432
430
|
const tmpDir = join(tmpdir(), "tokscale");
|
|
433
431
|
mkdirSync(tmpDir, { recursive: true });
|
|
434
|
-
const
|
|
435
|
-
|
|
432
|
+
const id = randomUUID();
|
|
433
|
+
const inputFile = join(tmpDir, `input-${id}.json`);
|
|
434
|
+
const outputFile = join(tmpDir, `output-${id}.json`);
|
|
435
|
+
|
|
436
436
|
writeFileSync(inputFile, input, "utf-8");
|
|
437
437
|
|
|
438
438
|
const BunGlobal = (globalThis as Record<string, unknown>).Bun as BunGlobalType;
|
|
439
439
|
|
|
440
440
|
let proc: BunSubprocess;
|
|
441
441
|
try {
|
|
442
|
-
proc = BunGlobal.spawn([process.execPath, runnerPath, inputFile], {
|
|
443
|
-
stdout: "
|
|
442
|
+
proc = BunGlobal.spawn([process.execPath, runnerPath, inputFile, outputFile], {
|
|
443
|
+
stdout: "ignore",
|
|
444
444
|
stderr: "pipe",
|
|
445
445
|
});
|
|
446
446
|
} catch (e) {
|
|
447
|
-
unlinkSync(inputFile);
|
|
447
|
+
try { unlinkSync(inputFile); } catch {}
|
|
448
448
|
throw new Error(`Failed to spawn subprocess: ${(e as Error).message}`);
|
|
449
449
|
}
|
|
450
450
|
|
|
451
451
|
let timeoutId: ReturnType<typeof setTimeout> | null = null;
|
|
452
452
|
let sigkillId: ReturnType<typeof setTimeout> | null = null;
|
|
453
453
|
let weInitiatedKill = false;
|
|
454
|
-
let aborted = false;
|
|
455
454
|
|
|
456
455
|
const cleanup = async () => {
|
|
457
456
|
if (timeoutId) clearTimeout(timeoutId);
|
|
458
457
|
if (sigkillId) clearTimeout(sigkillId);
|
|
459
458
|
try { unlinkSync(inputFile); } catch {}
|
|
460
|
-
|
|
461
|
-
safeKill(proc, "SIGKILL");
|
|
462
|
-
await proc.exited.catch(() => {});
|
|
463
|
-
}
|
|
464
|
-
};
|
|
465
|
-
|
|
466
|
-
const abort = () => {
|
|
467
|
-
aborted = true;
|
|
468
|
-
weInitiatedKill = true;
|
|
459
|
+
try { unlinkSync(outputFile); } catch {}
|
|
469
460
|
};
|
|
470
461
|
|
|
471
462
|
try {
|
|
472
|
-
const stdoutChunks: Uint8Array[] = [];
|
|
473
|
-
const stderrChunks: Uint8Array[] = [];
|
|
474
|
-
let stdoutBytes = 0;
|
|
475
|
-
let stderrBytes = 0;
|
|
476
|
-
|
|
477
|
-
const readStream = async (
|
|
478
|
-
stream: BunSubprocess["stdout"],
|
|
479
|
-
chunks: Uint8Array[],
|
|
480
|
-
getBytesRef: () => number,
|
|
481
|
-
setBytesRef: (n: number) => void
|
|
482
|
-
): Promise<string> => {
|
|
483
|
-
const reader = (stream as unknown as ReadableStream<Uint8Array>).getReader();
|
|
484
|
-
try {
|
|
485
|
-
while (!aborted) {
|
|
486
|
-
const { done, value } = await reader.read();
|
|
487
|
-
if (done) break;
|
|
488
|
-
const newTotal = getBytesRef() + value.length;
|
|
489
|
-
if (newTotal > MAX_OUTPUT_BYTES) {
|
|
490
|
-
abort();
|
|
491
|
-
throw new Error(`Output exceeded ${MAX_OUTPUT_BYTES} bytes`);
|
|
492
|
-
}
|
|
493
|
-
setBytesRef(newTotal);
|
|
494
|
-
chunks.push(value);
|
|
495
|
-
}
|
|
496
|
-
} finally {
|
|
497
|
-
await reader.cancel().catch(() => {});
|
|
498
|
-
reader.releaseLock();
|
|
499
|
-
}
|
|
500
|
-
const combined = new Uint8Array(getBytesRef());
|
|
501
|
-
let offset = 0;
|
|
502
|
-
for (const chunk of chunks) {
|
|
503
|
-
combined.set(chunk, offset);
|
|
504
|
-
offset += chunk.length;
|
|
505
|
-
}
|
|
506
|
-
return new TextDecoder().decode(combined);
|
|
507
|
-
};
|
|
508
|
-
|
|
509
463
|
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
510
464
|
timeoutId = setTimeout(() => {
|
|
511
|
-
|
|
465
|
+
weInitiatedKill = true;
|
|
512
466
|
safeKill(proc, "SIGTERM");
|
|
513
467
|
sigkillId = setTimeout(() => {
|
|
514
468
|
safeKill(proc, "SIGKILL");
|
|
@@ -519,15 +473,10 @@ async function runInSubprocess<T>(method: string, args: unknown[]): Promise<T> {
|
|
|
519
473
|
}, NATIVE_TIMEOUT_MS);
|
|
520
474
|
});
|
|
521
475
|
|
|
522
|
-
const
|
|
523
|
-
readStream(proc.stdout, stdoutChunks, () => stdoutBytes, (n) => { stdoutBytes = n; }),
|
|
524
|
-
readStream(proc.stderr, stderrChunks, () => stderrBytes, (n) => { stderrBytes = n; }),
|
|
525
|
-
proc.exited,
|
|
526
|
-
]);
|
|
476
|
+
const exitCode = await Promise.race([proc.exited, timeoutPromise]);
|
|
527
477
|
|
|
528
|
-
|
|
478
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
529
479
|
|
|
530
|
-
// Note: proc.killed is always true after exit in Bun (even for normal exits), so we only check signalCode
|
|
531
480
|
if (weInitiatedKill || proc.signalCode) {
|
|
532
481
|
throw new Error(
|
|
533
482
|
`Subprocess '${method}' was killed (signal: ${proc.signalCode || "SIGTERM"})`
|
|
@@ -535,6 +484,7 @@ async function runInSubprocess<T>(method: string, args: unknown[]): Promise<T> {
|
|
|
535
484
|
}
|
|
536
485
|
|
|
537
486
|
if (exitCode !== 0) {
|
|
487
|
+
const stderr = await proc.stderr.text();
|
|
538
488
|
let errorMsg = stderr || `Process exited with code ${exitCode}`;
|
|
539
489
|
try {
|
|
540
490
|
const parsed = JSON.parse(stderr);
|
|
@@ -543,11 +493,16 @@ async function runInSubprocess<T>(method: string, args: unknown[]): Promise<T> {
|
|
|
543
493
|
throw new Error(`Subprocess '${method}' failed: ${errorMsg}`);
|
|
544
494
|
}
|
|
545
495
|
|
|
496
|
+
if (!existsSync(outputFile)) {
|
|
497
|
+
throw new Error(`Subprocess '${method}' did not produce output file`);
|
|
498
|
+
}
|
|
499
|
+
|
|
546
500
|
try {
|
|
547
|
-
|
|
501
|
+
const output = readFileSync(outputFile, "utf-8");
|
|
502
|
+
return JSON.parse(output) as T;
|
|
548
503
|
} catch (e) {
|
|
549
504
|
throw new Error(
|
|
550
|
-
`Failed to parse subprocess output: ${(e as Error).message}
|
|
505
|
+
`Failed to parse subprocess output: ${(e as Error).message}`
|
|
551
506
|
);
|
|
552
507
|
}
|
|
553
508
|
} finally {
|
|
@@ -14,11 +14,16 @@ const MIN_AUTO_REFRESH_MS = 30000;
|
|
|
14
14
|
const MAX_AUTO_REFRESH_MS = 3600000;
|
|
15
15
|
const DEFAULT_AUTO_REFRESH_MS = 60000;
|
|
16
16
|
|
|
17
|
+
const DEFAULT_NATIVE_TIMEOUT_MS = 300_000; // 5 minutes
|
|
18
|
+
const MIN_NATIVE_TIMEOUT_MS = 5_000; // 5 seconds
|
|
19
|
+
const MAX_NATIVE_TIMEOUT_MS = 3_600_000; // 1 hour
|
|
20
|
+
|
|
17
21
|
export interface TokscaleSettings {
|
|
18
22
|
colorPalette: string;
|
|
19
23
|
autoRefreshEnabled?: boolean;
|
|
20
24
|
autoRefreshMs?: number;
|
|
21
25
|
includeUnusedModels?: boolean;
|
|
26
|
+
nativeTimeoutMs?: number;
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
function validateSettings(raw: unknown): TokscaleSettings {
|
|
@@ -27,6 +32,7 @@ function validateSettings(raw: unknown): TokscaleSettings {
|
|
|
27
32
|
autoRefreshEnabled: false,
|
|
28
33
|
autoRefreshMs: DEFAULT_AUTO_REFRESH_MS,
|
|
29
34
|
includeUnusedModels: false,
|
|
35
|
+
nativeTimeoutMs: DEFAULT_NATIVE_TIMEOUT_MS,
|
|
30
36
|
};
|
|
31
37
|
|
|
32
38
|
if (!raw || typeof raw !== "object") return defaults;
|
|
@@ -43,7 +49,12 @@ function validateSettings(raw: unknown): TokscaleSettings {
|
|
|
43
49
|
|
|
44
50
|
const includeUnusedModels = typeof obj.includeUnusedModels === "boolean" ? obj.includeUnusedModels : defaults.includeUnusedModels;
|
|
45
51
|
|
|
46
|
-
|
|
52
|
+
let nativeTimeoutMs = defaults.nativeTimeoutMs;
|
|
53
|
+
if (typeof obj.nativeTimeoutMs === "number" && Number.isFinite(obj.nativeTimeoutMs)) {
|
|
54
|
+
nativeTimeoutMs = Math.min(MAX_NATIVE_TIMEOUT_MS, Math.max(MIN_NATIVE_TIMEOUT_MS, obj.nativeTimeoutMs));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return { colorPalette, autoRefreshEnabled, autoRefreshMs, includeUnusedModels, nativeTimeoutMs };
|
|
47
58
|
}
|
|
48
59
|
|
|
49
60
|
interface CachedTUIData {
|
|
@@ -66,7 +77,7 @@ export function loadSettings(): TokscaleSettings {
|
|
|
66
77
|
}
|
|
67
78
|
} catch {
|
|
68
79
|
}
|
|
69
|
-
return { colorPalette: "blue", autoRefreshEnabled: false, autoRefreshMs: DEFAULT_AUTO_REFRESH_MS, includeUnusedModels: false };
|
|
80
|
+
return { colorPalette: "blue", autoRefreshEnabled: false, autoRefreshMs: DEFAULT_AUTO_REFRESH_MS, includeUnusedModels: false, nativeTimeoutMs: DEFAULT_NATIVE_TIMEOUT_MS };
|
|
70
81
|
}
|
|
71
82
|
|
|
72
83
|
export function saveSettings(updates: Partial<TokscaleSettings>): void {
|