kimiflare 0.45.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1012 -591
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -346,6 +346,38 @@ var init_lsp_config = __esm({
|
|
|
346
346
|
}
|
|
347
347
|
});
|
|
348
348
|
|
|
349
|
+
// src/util/logger.ts
|
|
350
|
+
function log(level, event, data) {
|
|
351
|
+
if (LEVEL_ORDER[level] < LEVEL_ORDER[globalMinLevel]) return;
|
|
352
|
+
const entry = {
|
|
353
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
354
|
+
level,
|
|
355
|
+
event,
|
|
356
|
+
data
|
|
357
|
+
};
|
|
358
|
+
console.error(JSON.stringify(entry));
|
|
359
|
+
}
|
|
360
|
+
var globalMinLevel, LEVEL_ORDER, logger;
|
|
361
|
+
var init_logger = __esm({
|
|
362
|
+
"src/util/logger.ts"() {
|
|
363
|
+
"use strict";
|
|
364
|
+
globalMinLevel = process.env.KIMIFLARE_LOG_LEVEL ?? "off";
|
|
365
|
+
LEVEL_ORDER = {
|
|
366
|
+
debug: 0,
|
|
367
|
+
info: 1,
|
|
368
|
+
warn: 2,
|
|
369
|
+
error: 3,
|
|
370
|
+
off: 4
|
|
371
|
+
};
|
|
372
|
+
logger = {
|
|
373
|
+
debug: (event, data) => log("debug", event, data),
|
|
374
|
+
info: (event, data) => log("info", event, data),
|
|
375
|
+
warn: (event, data) => log("warn", event, data),
|
|
376
|
+
error: (event, data) => log("error", event, data)
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
|
|
349
381
|
// src/util/sse.ts
|
|
350
382
|
async function* readSSE(stream, signal, idleTimeoutMs) {
|
|
351
383
|
const reader = stream.getReader();
|
|
@@ -357,16 +389,30 @@ async function* readSSE(stream, signal, idleTimeoutMs) {
|
|
|
357
389
|
});
|
|
358
390
|
};
|
|
359
391
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
392
|
+
const abortRace = (promise) => {
|
|
393
|
+
if (!signal) return promise;
|
|
394
|
+
return Promise.race([
|
|
395
|
+
promise,
|
|
396
|
+
new Promise((_, reject) => {
|
|
397
|
+
if (signal.aborted) {
|
|
398
|
+
reject(new DOMException("aborted", "AbortError"));
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
signal.addEventListener("abort", () => reject(new DOMException("aborted", "AbortError")), { once: true });
|
|
402
|
+
})
|
|
403
|
+
]);
|
|
404
|
+
};
|
|
360
405
|
try {
|
|
361
406
|
while (true) {
|
|
362
407
|
if (signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
363
408
|
if (idleTimeoutMs !== void 0 && Date.now() - lastDataAt > idleTimeoutMs) {
|
|
409
|
+
logger.warn("sse:idle_timeout", { idleTimeoutMs });
|
|
364
410
|
throw new DOMException(
|
|
365
411
|
`kimiflare: stream idle for ${idleTimeoutMs}ms \u2014 no data received from API`,
|
|
366
412
|
"TimeoutError"
|
|
367
413
|
);
|
|
368
414
|
}
|
|
369
|
-
const { done, value } = await reader.read();
|
|
415
|
+
const { done, value } = await abortRace(reader.read());
|
|
370
416
|
if (done) break;
|
|
371
417
|
lastDataAt = Date.now();
|
|
372
418
|
buffer += decoder.decode(value, { stream: true });
|
|
@@ -399,10 +445,14 @@ function extractData(event) {
|
|
|
399
445
|
var init_sse = __esm({
|
|
400
446
|
"src/util/sse.ts"() {
|
|
401
447
|
"use strict";
|
|
448
|
+
init_logger();
|
|
402
449
|
}
|
|
403
450
|
});
|
|
404
451
|
|
|
405
452
|
// src/util/errors.ts
|
|
453
|
+
function isCloudQuotaExhaustedError(err) {
|
|
454
|
+
return err instanceof KimiApiError && err.httpStatus === 429 && /token quota exhausted/i.test(err.message);
|
|
455
|
+
}
|
|
406
456
|
var KimiApiError;
|
|
407
457
|
var init_errors = __esm({
|
|
408
458
|
"src/util/errors.ts"() {
|
|
@@ -531,6 +581,7 @@ async function* runKimi(opts2) {
|
|
|
531
581
|
if (opts2.reasoningEffort) {
|
|
532
582
|
body.reasoning_effort = opts2.reasoningEffort;
|
|
533
583
|
}
|
|
584
|
+
logger.debug("runKimi:request", { requestId, attempt: 0, model: opts2.model });
|
|
534
585
|
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
|
|
535
586
|
let res;
|
|
536
587
|
try {
|
|
@@ -553,6 +604,7 @@ async function* runKimi(opts2) {
|
|
|
553
604
|
});
|
|
554
605
|
} catch (fetchErr) {
|
|
555
606
|
const msg = fetchErr instanceof Error ? fetchErr.message : String(fetchErr);
|
|
607
|
+
logger.warn("runKimi:fetch_error", { requestId, attempt, error: msg });
|
|
556
608
|
if (attempt < MAX_ATTEMPTS - 1) {
|
|
557
609
|
const delay = 500 * 2 ** attempt + Math.random() * 250;
|
|
558
610
|
await sleep(delay, opts2.signal);
|
|
@@ -583,10 +635,12 @@ async function* runKimi(opts2) {
|
|
|
583
635
|
const meta = readGatewayMeta(res.headers);
|
|
584
636
|
if (meta) yield { type: "gateway_meta", meta };
|
|
585
637
|
let lastUsage = null;
|
|
638
|
+
logger.debug("runKimi:stream_start", { requestId });
|
|
586
639
|
for await (const ev of parseStream(res.body, opts2.signal, opts2.idleTimeoutMs)) {
|
|
587
640
|
if (ev.type === "usage") lastUsage = ev.usage;
|
|
588
641
|
yield ev;
|
|
589
642
|
}
|
|
643
|
+
logger.debug("runKimi:stream_end", { requestId });
|
|
590
644
|
if (opts2.cloudMode && lastUsage && opts2.cloudToken) {
|
|
591
645
|
const reportUrl = "https://api.kimiflare.com/v1/usage/report";
|
|
592
646
|
const reportHeaders = {
|
|
@@ -808,6 +862,7 @@ var init_client = __esm({
|
|
|
808
862
|
init_errors();
|
|
809
863
|
init_version();
|
|
810
864
|
init_messages();
|
|
865
|
+
init_logger();
|
|
811
866
|
RETRYABLE_CODES = /* @__PURE__ */ new Set([3040]);
|
|
812
867
|
MAX_ATTEMPTS = 5;
|
|
813
868
|
DEFAULT_IDLE_TIMEOUT_MS = 6e4;
|
|
@@ -1879,6 +1934,7 @@ function isHighSignalMemory(memory) {
|
|
|
1879
1934
|
}
|
|
1880
1935
|
async function runAgentTurn(opts2) {
|
|
1881
1936
|
const turnStart = performance.now();
|
|
1937
|
+
logger.info("turn:start", { sessionId: opts2.sessionId, codeMode: opts2.codeMode ?? false });
|
|
1882
1938
|
const max = opts2.maxToolIterations ?? 50;
|
|
1883
1939
|
const codeMode = opts2.codeMode ?? false;
|
|
1884
1940
|
let toolDefs;
|
|
@@ -2009,6 +2065,7 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
2009
2065
|
if (opts2.keepLastImageTurns !== void 0) {
|
|
2010
2066
|
apiMessages = stripOldImages(apiMessages, opts2.keepLastImageTurns);
|
|
2011
2067
|
}
|
|
2068
|
+
logger.debug("turn:api_request", { sessionId: opts2.sessionId, messageCount: apiMessages.length });
|
|
2012
2069
|
const events = runKimi({
|
|
2013
2070
|
accountId: opts2.accountId,
|
|
2014
2071
|
apiToken: opts2.apiToken,
|
|
@@ -2023,9 +2080,15 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
2023
2080
|
gateway: opts2.gateway,
|
|
2024
2081
|
cloudMode: opts2.cloudMode,
|
|
2025
2082
|
cloudToken: opts2.cloudToken,
|
|
2026
|
-
cloudDeviceId: opts2.cloudDeviceId
|
|
2083
|
+
cloudDeviceId: opts2.cloudDeviceId,
|
|
2084
|
+
idleTimeoutMs: 6e4
|
|
2027
2085
|
});
|
|
2086
|
+
let gotFirstChunk = false;
|
|
2028
2087
|
for await (const ev of events) {
|
|
2088
|
+
if (!gotFirstChunk) {
|
|
2089
|
+
gotFirstChunk = true;
|
|
2090
|
+
logger.debug("turn:api_first_chunk", { sessionId: opts2.sessionId });
|
|
2091
|
+
}
|
|
2029
2092
|
switch (ev.type) {
|
|
2030
2093
|
case "gateway_meta":
|
|
2031
2094
|
gatewayMeta = ev.meta;
|
|
@@ -2103,6 +2166,7 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
2103
2166
|
if (budgetExhausted) {
|
|
2104
2167
|
throw new BudgetExhaustedError();
|
|
2105
2168
|
}
|
|
2169
|
+
logger.info("turn:complete", { sessionId: opts2.sessionId, durationMs: Math.round(performance.now() - turnStart) });
|
|
2106
2170
|
return;
|
|
2107
2171
|
}
|
|
2108
2172
|
for (const tc of toolCalls) {
|
|
@@ -2226,12 +2290,14 @@ ${sandboxResult.output}` : `${warningPrefix}${sandboxResult.output}`;
|
|
|
2226
2290
|
recentToolCalls.push(loopSignature);
|
|
2227
2291
|
if (recentToolCalls.length > LOOP_WINDOW) recentToolCalls.shift();
|
|
2228
2292
|
} else {
|
|
2293
|
+
logger.debug("turn:tool_start", { sessionId: opts2.sessionId, tool: tc.function.name, toolCallId: tc.id });
|
|
2229
2294
|
const result = await opts2.executor.run(
|
|
2230
2295
|
{ id: tc.id, name: tc.function.name, arguments: tc.function.arguments },
|
|
2231
2296
|
opts2.callbacks.askPermission,
|
|
2232
2297
|
{ cwd: opts2.cwd, signal: opts2.signal, onTasks: opts2.callbacks.onTasks, coauthor: opts2.coauthor, memoryManager: opts2.memoryManager, sessionId: opts2.sessionId, githubToken: opts2.githubToken },
|
|
2233
2298
|
opts2.onFileChange
|
|
2234
2299
|
);
|
|
2300
|
+
logger.debug("turn:tool_end", { sessionId: opts2.sessionId, tool: tc.function.name, toolCallId: tc.id, ok: result.ok });
|
|
2235
2301
|
toolResults.push(result);
|
|
2236
2302
|
opts2.messages.push({
|
|
2237
2303
|
role: "tool",
|
|
@@ -2346,6 +2412,7 @@ var init_loop = __esm({
|
|
|
2346
2412
|
init_extractors();
|
|
2347
2413
|
init_strip_reasoning();
|
|
2348
2414
|
init_code_mode();
|
|
2415
|
+
init_logger();
|
|
2349
2416
|
BudgetExhaustedError = class extends Error {
|
|
2350
2417
|
constructor(message2 = "Cumulative input token budget exhausted") {
|
|
2351
2418
|
super(message2);
|
|
@@ -2883,9 +2950,9 @@ function runBash(args, ctx) {
|
|
|
2883
2950
|
const timeout = Math.min(Math.max(1e3, args.timeout_ms ?? DEFAULT_TIMEOUT), MAX_TIMEOUT);
|
|
2884
2951
|
const command = injectCoauthor(args.command, ctx.coauthor);
|
|
2885
2952
|
return new Promise((resolve2, reject) => {
|
|
2953
|
+
logger.debug("bash:spawn", { command: args.command.slice(0, 200), cwd: ctx.cwd });
|
|
2886
2954
|
const child = spawn("bash", ["-lc", command], {
|
|
2887
2955
|
cwd: ctx.cwd,
|
|
2888
|
-
signal: ctx.signal,
|
|
2889
2956
|
env: {
|
|
2890
2957
|
...process.env,
|
|
2891
2958
|
GIT_EDITOR: "true"
|
|
@@ -2894,10 +2961,18 @@ function runBash(args, ctx) {
|
|
|
2894
2961
|
let stdout = "";
|
|
2895
2962
|
let stderr = "";
|
|
2896
2963
|
let killedByTimeout = false;
|
|
2964
|
+
let killedByAbort = false;
|
|
2897
2965
|
const timer = setTimeout(() => {
|
|
2898
2966
|
killedByTimeout = true;
|
|
2967
|
+
logger.warn("bash:kill_timeout", { command: args.command.slice(0, 200) });
|
|
2899
2968
|
child.kill("SIGKILL");
|
|
2900
2969
|
}, timeout);
|
|
2970
|
+
const onAbort = () => {
|
|
2971
|
+
killedByAbort = true;
|
|
2972
|
+
logger.warn("bash:kill_abort", { command: args.command.slice(0, 200) });
|
|
2973
|
+
child.kill("SIGKILL");
|
|
2974
|
+
};
|
|
2975
|
+
ctx.signal?.addEventListener("abort", onAbort, { once: true });
|
|
2901
2976
|
child.stdout.on("data", (d) => {
|
|
2902
2977
|
stdout += d.toString("utf8");
|
|
2903
2978
|
});
|
|
@@ -2906,11 +2981,15 @@ function runBash(args, ctx) {
|
|
|
2906
2981
|
});
|
|
2907
2982
|
child.on("error", (e) => {
|
|
2908
2983
|
clearTimeout(timer);
|
|
2984
|
+
ctx.signal?.removeEventListener("abort", onAbort);
|
|
2985
|
+
logger.error("bash:error", { error: e.message });
|
|
2909
2986
|
reject(e);
|
|
2910
2987
|
});
|
|
2911
2988
|
child.on("close", (code, signal) => {
|
|
2912
2989
|
clearTimeout(timer);
|
|
2913
|
-
|
|
2990
|
+
ctx.signal?.removeEventListener("abort", onAbort);
|
|
2991
|
+
logger.debug("bash:close", { code, signal, killedByTimeout, killedByAbort });
|
|
2992
|
+
const header = killedByTimeout ? `(timed out after ${timeout}ms)` : killedByAbort ? `(aborted \u2014 sent SIGKILL)` : `exit=${code ?? "?"}${signal ? ` signal=${signal}` : ""}`;
|
|
2914
2993
|
const parts = [header];
|
|
2915
2994
|
if (stdout) parts.push(`--- stdout ---
|
|
2916
2995
|
${stdout.trimEnd()}`);
|
|
@@ -2930,6 +3009,7 @@ var DEFAULT_TIMEOUT, MAX_TIMEOUT, bashTool;
|
|
|
2930
3009
|
var init_bash = __esm({
|
|
2931
3010
|
"src/tools/bash.ts"() {
|
|
2932
3011
|
"use strict";
|
|
3012
|
+
init_logger();
|
|
2933
3013
|
DEFAULT_TIMEOUT = 12e4;
|
|
2934
3014
|
MAX_TIMEOUT = 6e5;
|
|
2935
3015
|
bashTool = {
|
|
@@ -5333,7 +5413,7 @@ function filterSessions(sessions, start, end) {
|
|
|
5333
5413
|
return sessions.filter((s) => s.date >= start && s.date <= end);
|
|
5334
5414
|
}
|
|
5335
5415
|
async function runCostCommand(opts2) {
|
|
5336
|
-
const
|
|
5416
|
+
const log2 = await loadLog();
|
|
5337
5417
|
let startDate;
|
|
5338
5418
|
let endDate;
|
|
5339
5419
|
let prevStart;
|
|
@@ -5355,7 +5435,7 @@ async function runCostCommand(opts2) {
|
|
|
5355
5435
|
prevEnd = daysAgo(8);
|
|
5356
5436
|
}
|
|
5357
5437
|
if (opts2.session) {
|
|
5358
|
-
const session =
|
|
5438
|
+
const session = log2.sessions.find((s) => s.id === opts2.session);
|
|
5359
5439
|
if (!session) {
|
|
5360
5440
|
console.error(`Session ${opts2.session} not found.`);
|
|
5361
5441
|
process.exit(1);
|
|
@@ -5363,8 +5443,8 @@ async function runCostCommand(opts2) {
|
|
|
5363
5443
|
console.log(JSON.stringify(session, null, 2));
|
|
5364
5444
|
return;
|
|
5365
5445
|
}
|
|
5366
|
-
const sessions = filterSessions(
|
|
5367
|
-
const prevSessions = filterSessions(
|
|
5446
|
+
const sessions = filterSessions(log2.sessions, startDate, endDate);
|
|
5447
|
+
const prevSessions = filterSessions(log2.sessions, prevStart, prevEnd);
|
|
5368
5448
|
for (const s of sessions) {
|
|
5369
5449
|
if (!s.category || opts2.reclassify) {
|
|
5370
5450
|
const result = await classifyFromSessionFile(s.id);
|
|
@@ -5631,6 +5711,69 @@ var init_tui_auth = __esm({
|
|
|
5631
5711
|
}
|
|
5632
5712
|
});
|
|
5633
5713
|
|
|
5714
|
+
// src/agent/supervisor.ts
|
|
5715
|
+
var TurnSupervisor;
|
|
5716
|
+
var init_supervisor = __esm({
|
|
5717
|
+
"src/agent/supervisor.ts"() {
|
|
5718
|
+
"use strict";
|
|
5719
|
+
init_loop();
|
|
5720
|
+
init_logger();
|
|
5721
|
+
TurnSupervisor = class {
|
|
5722
|
+
currentTurn = null;
|
|
5723
|
+
_phase = "idle";
|
|
5724
|
+
_killRequested = false;
|
|
5725
|
+
get phase() {
|
|
5726
|
+
return this._phase;
|
|
5727
|
+
}
|
|
5728
|
+
get isRunning() {
|
|
5729
|
+
return this._phase !== "idle";
|
|
5730
|
+
}
|
|
5731
|
+
get killRequested() {
|
|
5732
|
+
return this._killRequested;
|
|
5733
|
+
}
|
|
5734
|
+
startTurn(opts2, callbacks) {
|
|
5735
|
+
if (this.isRunning) {
|
|
5736
|
+
logger.warn("supervisor:start_rejected", { reason: "turn_already_running", phase: this._phase });
|
|
5737
|
+
throw new Error("TurnSupervisor: turn already in progress");
|
|
5738
|
+
}
|
|
5739
|
+
this._phase = "streaming";
|
|
5740
|
+
this._killRequested = false;
|
|
5741
|
+
logger.debug("supervisor:turn_start", { sessionId: opts2.sessionId });
|
|
5742
|
+
this.currentTurn = runAgentTurn(opts2).then(async () => {
|
|
5743
|
+
this._phase = "idle";
|
|
5744
|
+
if (this._killRequested) {
|
|
5745
|
+
logger.debug("supervisor:turn_killed", { sessionId: opts2.sessionId });
|
|
5746
|
+
} else {
|
|
5747
|
+
logger.debug("supervisor:turn_done", { sessionId: opts2.sessionId });
|
|
5748
|
+
}
|
|
5749
|
+
await callbacks?.onDone?.();
|
|
5750
|
+
}).catch(async (error) => {
|
|
5751
|
+
this._phase = "idle";
|
|
5752
|
+
const err = error;
|
|
5753
|
+
logger.warn("supervisor:turn_error", {
|
|
5754
|
+
sessionId: opts2.sessionId,
|
|
5755
|
+
error: err.message ?? String(err),
|
|
5756
|
+
name: err.name
|
|
5757
|
+
});
|
|
5758
|
+
await callbacks?.onError?.(err);
|
|
5759
|
+
}).finally(() => {
|
|
5760
|
+
this.currentTurn = null;
|
|
5761
|
+
this._killRequested = false;
|
|
5762
|
+
});
|
|
5763
|
+
}
|
|
5764
|
+
/** Request that the current turn be killed. This does NOT directly abort
|
|
5765
|
+
* the turn — the caller must abort the AbortScope that was passed to
|
|
5766
|
+
* `startTurn`. This method only records the intent so the supervisor
|
|
5767
|
+
* knows the turn was intentionally killed rather than failing. */
|
|
5768
|
+
killTurn() {
|
|
5769
|
+
if (!this.isRunning) return;
|
|
5770
|
+
this._killRequested = true;
|
|
5771
|
+
logger.debug("supervisor:kill_requested", { phase: this._phase });
|
|
5772
|
+
}
|
|
5773
|
+
};
|
|
5774
|
+
}
|
|
5775
|
+
});
|
|
5776
|
+
|
|
5634
5777
|
// src/agent/compact.ts
|
|
5635
5778
|
function indexOfNthUserFromEnd(messages, n) {
|
|
5636
5779
|
let seen = 0;
|
|
@@ -5686,7 +5829,8 @@ ${transcript}` }
|
|
|
5686
5829
|
signal: opts2.signal,
|
|
5687
5830
|
temperature: 0.1,
|
|
5688
5831
|
reasoningEffort: "low",
|
|
5689
|
-
gateway: opts2.gateway
|
|
5832
|
+
gateway: opts2.gateway,
|
|
5833
|
+
idleTimeoutMs: 6e4
|
|
5690
5834
|
});
|
|
5691
5835
|
for await (const ev of events) {
|
|
5692
5836
|
if (ev.type === "text") summary += ev.delta;
|
|
@@ -7174,6 +7318,75 @@ var init_lsp = __esm({
|
|
|
7174
7318
|
}
|
|
7175
7319
|
});
|
|
7176
7320
|
|
|
7321
|
+
// src/util/abort-scope.ts
|
|
7322
|
+
var AbortScope;
|
|
7323
|
+
var init_abort_scope = __esm({
|
|
7324
|
+
"src/util/abort-scope.ts"() {
|
|
7325
|
+
"use strict";
|
|
7326
|
+
AbortScope = class _AbortScope {
|
|
7327
|
+
controller;
|
|
7328
|
+
parent;
|
|
7329
|
+
children = /* @__PURE__ */ new Set();
|
|
7330
|
+
parentListener;
|
|
7331
|
+
_isAborted = false;
|
|
7332
|
+
_reason;
|
|
7333
|
+
constructor(parent) {
|
|
7334
|
+
this.controller = new AbortController();
|
|
7335
|
+
this.parent = parent;
|
|
7336
|
+
if (parent) {
|
|
7337
|
+
this.parentListener = () => {
|
|
7338
|
+
this.abort(parent.reason ?? "parent_aborted");
|
|
7339
|
+
};
|
|
7340
|
+
parent.signal.addEventListener("abort", this.parentListener, { once: true });
|
|
7341
|
+
parent.children.add(this);
|
|
7342
|
+
}
|
|
7343
|
+
}
|
|
7344
|
+
get signal() {
|
|
7345
|
+
return this.controller.signal;
|
|
7346
|
+
}
|
|
7347
|
+
get isAborted() {
|
|
7348
|
+
return this._isAborted;
|
|
7349
|
+
}
|
|
7350
|
+
get reason() {
|
|
7351
|
+
return this._reason;
|
|
7352
|
+
}
|
|
7353
|
+
abort(reason) {
|
|
7354
|
+
if (this._isAborted) return;
|
|
7355
|
+
this._isAborted = true;
|
|
7356
|
+
this._reason = reason;
|
|
7357
|
+
for (const child of this.children) {
|
|
7358
|
+
child.abort(reason ?? "parent_aborted");
|
|
7359
|
+
}
|
|
7360
|
+
this.children.clear();
|
|
7361
|
+
this.controller.abort(reason);
|
|
7362
|
+
if (this.parent && this.parentListener) {
|
|
7363
|
+
this.parent.signal.removeEventListener("abort", this.parentListener);
|
|
7364
|
+
this.parent.children.delete(this);
|
|
7365
|
+
this.parent = void 0;
|
|
7366
|
+
}
|
|
7367
|
+
}
|
|
7368
|
+
createChild() {
|
|
7369
|
+
if (this._isAborted) {
|
|
7370
|
+
const child = new _AbortScope();
|
|
7371
|
+
child._isAborted = true;
|
|
7372
|
+
child._reason = this._reason ?? "parent_already_aborted";
|
|
7373
|
+
child.controller.abort(child._reason);
|
|
7374
|
+
return child;
|
|
7375
|
+
}
|
|
7376
|
+
return new _AbortScope(this);
|
|
7377
|
+
}
|
|
7378
|
+
/** Detach from parent without aborting. Useful when a child outlives its parent. */
|
|
7379
|
+
detach() {
|
|
7380
|
+
if (this.parent && this.parentListener) {
|
|
7381
|
+
this.parent.signal.removeEventListener("abort", this.parentListener);
|
|
7382
|
+
this.parent.children.delete(this);
|
|
7383
|
+
this.parent = void 0;
|
|
7384
|
+
}
|
|
7385
|
+
}
|
|
7386
|
+
};
|
|
7387
|
+
}
|
|
7388
|
+
});
|
|
7389
|
+
|
|
7177
7390
|
// src/ui/theme-context.tsx
|
|
7178
7391
|
import { createContext, useContext } from "react";
|
|
7179
7392
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -7423,9 +7636,16 @@ function humanizeInfo(text, tier) {
|
|
|
7423
7636
|
}
|
|
7424
7637
|
if (text === "(interrupted)") {
|
|
7425
7638
|
return pick(tier, {
|
|
7426
|
-
light: "Stopped",
|
|
7427
|
-
medium: "Interrupted",
|
|
7428
|
-
heavy: "Halted"
|
|
7639
|
+
light: "Stopped \u2014 say 'go on' if you want me to continue",
|
|
7640
|
+
medium: "Interrupted \u2014 say 'go on' if you want me to continue",
|
|
7641
|
+
heavy: "Halted \u2014 say 'go on' if you want me to resume"
|
|
7642
|
+
});
|
|
7643
|
+
}
|
|
7644
|
+
if (text === "(preempted)") {
|
|
7645
|
+
return pick(tier, {
|
|
7646
|
+
light: "Switching gears\u2026",
|
|
7647
|
+
medium: "Switching to your new message\u2026",
|
|
7648
|
+
heavy: "Switching to your new message\u2026"
|
|
7429
7649
|
});
|
|
7430
7650
|
}
|
|
7431
7651
|
if (text.startsWith("mode: ")) {
|
|
@@ -7896,11 +8116,68 @@ var init_markdown = __esm({
|
|
|
7896
8116
|
}
|
|
7897
8117
|
});
|
|
7898
8118
|
|
|
8119
|
+
// src/ui/cloud-quota-message.tsx
|
|
8120
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
8121
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
8122
|
+
function formatTokens(n) {
|
|
8123
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
8124
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
8125
|
+
return String(n);
|
|
8126
|
+
}
|
|
8127
|
+
function CloudQuotaMessage({ used, limit, expiresAt }) {
|
|
8128
|
+
const theme = useTheme();
|
|
8129
|
+
const expires = expiresAt ? new Date(expiresAt) : null;
|
|
8130
|
+
const start = expires ? new Date(expires.getTime() - 7 * 24 * 60 * 60 * 1e3) : null;
|
|
8131
|
+
const fmt = (d) => d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
8132
|
+
const dateRange = start && expires ? `${fmt(start)} \u2192 ${fmt(expires)}` : "this week";
|
|
8133
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginY: 1, children: [
|
|
8134
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, color: theme.accent, children: "You've used your free allocation for this week." }),
|
|
8135
|
+
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
8136
|
+
/* @__PURE__ */ jsxs4(Text4, { color: theme.info.color, children: [
|
|
8137
|
+
"Free tier ran from ",
|
|
8138
|
+
dateRange,
|
|
8139
|
+
", courtesy of Cloudflare"
|
|
8140
|
+
] }),
|
|
8141
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.info.color, children: "Workers AI credits. Thanks for trying kimiflare." })
|
|
8142
|
+
] }),
|
|
8143
|
+
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
8144
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, children: "Keep going with your own Cloudflare API key:" }),
|
|
8145
|
+
/* @__PURE__ */ jsxs4(Box4, { paddingLeft: 2, flexDirection: "column", children: [
|
|
8146
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.info.color, children: "\u2192 Set one: kimiflare config set-key <your-key>" }),
|
|
8147
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.info.color, children: "\u2192 Get one: https://dash.cloudflare.com/profile/api-tokens" }),
|
|
8148
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.info.color, children: "\u2192 Pricing: https://developers.cloudflare.com/workers-ai/platform/pricing/" }),
|
|
8149
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.muted?.color ?? theme.info.color, dimColor: theme.muted?.dim ?? true, children: "(~$0.95/M input tokens, ~$4.00/M output tokens)" })
|
|
8150
|
+
] })
|
|
8151
|
+
] }),
|
|
8152
|
+
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
8153
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.info.color, children: "Or wait for hosted plans \u2014 drop your email at" }),
|
|
8154
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.info.color, children: "kimiflare.dev/notify and I'll ping you when they're live." })
|
|
8155
|
+
] }),
|
|
8156
|
+
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
8157
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.info.color, children: "Want a bit more credit? DM me on X: x.com/sinasanm" }),
|
|
8158
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.info.color, children: "Chances are I might be able to hook you up." })
|
|
8159
|
+
] }),
|
|
8160
|
+
/* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: /* @__PURE__ */ jsxs4(Text4, { color: theme.muted?.color ?? theme.info.color, dimColor: theme.muted?.dim ?? true, children: [
|
|
8161
|
+
"Used: ",
|
|
8162
|
+
formatTokens(used),
|
|
8163
|
+
" / ",
|
|
8164
|
+
formatTokens(limit),
|
|
8165
|
+
" tokens this week."
|
|
8166
|
+
] }) })
|
|
8167
|
+
] });
|
|
8168
|
+
}
|
|
8169
|
+
var init_cloud_quota_message = __esm({
|
|
8170
|
+
"src/ui/cloud-quota-message.tsx"() {
|
|
8171
|
+
"use strict";
|
|
8172
|
+
init_theme_context();
|
|
8173
|
+
}
|
|
8174
|
+
});
|
|
8175
|
+
|
|
7899
8176
|
// src/ui/chat.tsx
|
|
7900
8177
|
import React4 from "react";
|
|
7901
|
-
import { Box as
|
|
8178
|
+
import { Box as Box5, Text as Text5, Static } from "ink";
|
|
7902
8179
|
import Spinner2 from "ink-spinner";
|
|
7903
|
-
import { jsx as
|
|
8180
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
7904
8181
|
function toolSignature(name, args) {
|
|
7905
8182
|
return `${name}:${args}`;
|
|
7906
8183
|
}
|
|
@@ -7912,6 +8189,7 @@ var init_chat = __esm({
|
|
|
7912
8189
|
init_markdown();
|
|
7913
8190
|
init_theme_context();
|
|
7914
8191
|
init_narrator();
|
|
8192
|
+
init_cloud_quota_message();
|
|
7915
8193
|
ChatView = React4.memo(function ChatView2({ events, showReasoning, verbose, intentTier }) {
|
|
7916
8194
|
const theme = useTheme();
|
|
7917
8195
|
const finalized = [];
|
|
@@ -7938,17 +8216,17 @@ var init_chat = __esm({
|
|
|
7938
8216
|
finalized.push({ id: e.key, evt: e, showSeparator });
|
|
7939
8217
|
}
|
|
7940
8218
|
}
|
|
7941
|
-
return /* @__PURE__ */
|
|
7942
|
-
/* @__PURE__ */
|
|
7943
|
-
item.showSeparator && /* @__PURE__ */
|
|
7944
|
-
/* @__PURE__ */
|
|
8219
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
8220
|
+
/* @__PURE__ */ jsx6(Static, { items: finalized, children: (item) => /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
8221
|
+
item.showSeparator && /* @__PURE__ */ jsx6(Box5, { marginY: 1, children: /* @__PURE__ */ jsx6(Text5, { color: theme.info.color, children: "\u2500".repeat(40) }) }),
|
|
8222
|
+
/* @__PURE__ */ jsx6(EventView, { evt: item.evt, showReasoning, verbose, repeatedSigs, intentTier })
|
|
7945
8223
|
] }, item.id) }),
|
|
7946
8224
|
active.map((e, i) => {
|
|
7947
8225
|
const prevEvt = i > 0 ? active[i - 1] : finalized[finalized.length - 1]?.evt;
|
|
7948
8226
|
const showSeparator = e.kind === "user" && prevEvt && (prevEvt.kind === "assistant" || prevEvt.kind === "tool");
|
|
7949
|
-
return /* @__PURE__ */
|
|
7950
|
-
showSeparator && /* @__PURE__ */
|
|
7951
|
-
/* @__PURE__ */
|
|
8227
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
8228
|
+
showSeparator && /* @__PURE__ */ jsx6(Box5, { marginY: 1, children: /* @__PURE__ */ jsx6(Text5, { color: theme.info.color, children: "\u2500".repeat(40) }) }),
|
|
8229
|
+
/* @__PURE__ */ jsx6(EventView, { evt: e, showReasoning, verbose, repeatedSigs, intentTier })
|
|
7952
8230
|
] }, e.key);
|
|
7953
8231
|
})
|
|
7954
8232
|
] });
|
|
@@ -7962,47 +8240,71 @@ var init_chat = __esm({
|
|
|
7962
8240
|
}) {
|
|
7963
8241
|
const theme = useTheme();
|
|
7964
8242
|
if (evt.kind === "user") {
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
8243
|
+
if (evt.queued) {
|
|
8244
|
+
const mutedColor = theme.muted?.color ?? theme.info.color;
|
|
8245
|
+
return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
8246
|
+
/* @__PURE__ */ jsxs5(Text5, { italic: true, color: mutedColor, children: [
|
|
8247
|
+
"\xB7\xB7\xB7",
|
|
8248
|
+
" "
|
|
8249
|
+
] }),
|
|
8250
|
+
/* @__PURE__ */ jsx6(Text5, { italic: true, color: mutedColor, children: evt.text }),
|
|
8251
|
+
/* @__PURE__ */ jsxs5(Text5, { italic: true, color: mutedColor, children: [
|
|
8252
|
+
" ",
|
|
8253
|
+
"(queued)"
|
|
8254
|
+
] })
|
|
8255
|
+
] }) });
|
|
8256
|
+
}
|
|
8257
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
8258
|
+
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
8259
|
+
/* @__PURE__ */ jsxs5(Text5, { bold: true, color: theme.user, children: [
|
|
7968
8260
|
"\u203A",
|
|
7969
8261
|
" "
|
|
7970
8262
|
] }),
|
|
7971
|
-
/* @__PURE__ */
|
|
8263
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, children: evt.text })
|
|
7972
8264
|
] }),
|
|
7973
|
-
evt.images && evt.images.length > 0 && /* @__PURE__ */
|
|
8265
|
+
evt.images && evt.images.length > 0 && /* @__PURE__ */ jsx6(Box5, { paddingLeft: 2, children: /* @__PURE__ */ jsxs5(Text5, { color: theme.info.color, children: [
|
|
7974
8266
|
"\u{1F5BC}\uFE0F ",
|
|
7975
8267
|
evt.images.join(", ")
|
|
7976
8268
|
] }) })
|
|
7977
8269
|
] });
|
|
7978
8270
|
}
|
|
7979
8271
|
if (evt.kind === "assistant") {
|
|
7980
|
-
return /* @__PURE__ */
|
|
7981
|
-
showReasoning && evt.reasoning ? /* @__PURE__ */
|
|
8272
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingLeft: 2, children: [
|
|
8273
|
+
showReasoning && evt.reasoning ? /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs5(Text5, { color: theme.reasoning.color, children: [
|
|
7982
8274
|
"thinking\u2026",
|
|
7983
8275
|
" ",
|
|
7984
8276
|
evt.reasoning.length > 400 ? evt.reasoning.slice(0, 400) + "\u2026" : evt.reasoning
|
|
7985
8277
|
] }) }) : null,
|
|
7986
|
-
evt.text ? /* @__PURE__ */
|
|
7987
|
-
evt.streaming && /* @__PURE__ */
|
|
8278
|
+
evt.text ? /* @__PURE__ */ jsx6(MD, { text: evt.text }) : null,
|
|
8279
|
+
evt.streaming && /* @__PURE__ */ jsx6(Text5, { color: theme.spinner, children: /* @__PURE__ */ jsx6(Spinner2, { type: "dots" }) })
|
|
7988
8280
|
] });
|
|
7989
8281
|
}
|
|
7990
8282
|
if (evt.kind === "tool") {
|
|
7991
8283
|
const isRepeated = repeatedSigs?.has(toolSignature(evt.name, evt.args)) ?? false;
|
|
7992
|
-
return /* @__PURE__ */
|
|
8284
|
+
return /* @__PURE__ */ jsx6(ToolView, { evt, verbose, isRepeated, intentTier });
|
|
7993
8285
|
}
|
|
7994
8286
|
if (evt.kind === "info") {
|
|
7995
|
-
return /* @__PURE__ */
|
|
8287
|
+
return /* @__PURE__ */ jsxs5(Text5, { color: theme.info.color, children: [
|
|
7996
8288
|
"\xB7 ",
|
|
7997
8289
|
humanizeInfo(evt.text, intentTier)
|
|
7998
8290
|
] });
|
|
7999
8291
|
}
|
|
8000
8292
|
if (evt.kind === "memory") {
|
|
8001
|
-
return /* @__PURE__ */
|
|
8293
|
+
return /* @__PURE__ */ jsxs5(Text5, { color: theme.info.color, children: [
|
|
8002
8294
|
"\u25C8 ",
|
|
8003
8295
|
humanizeMemory(evt.text, intentTier)
|
|
8004
8296
|
] });
|
|
8005
8297
|
}
|
|
8298
|
+
if (evt.kind === "cloud_quota_exhausted") {
|
|
8299
|
+
return /* @__PURE__ */ jsx6(
|
|
8300
|
+
CloudQuotaMessage,
|
|
8301
|
+
{
|
|
8302
|
+
used: evt.used,
|
|
8303
|
+
limit: evt.limit,
|
|
8304
|
+
expiresAt: evt.expiresAt
|
|
8305
|
+
}
|
|
8306
|
+
);
|
|
8307
|
+
}
|
|
8006
8308
|
if (evt.kind === "meta") {
|
|
8007
8309
|
const metaParts = [];
|
|
8008
8310
|
if (evt.skillsActive !== void 0 && evt.skillsActive > 0) {
|
|
@@ -8013,9 +8315,9 @@ var init_chat = __esm({
|
|
|
8013
8315
|
}
|
|
8014
8316
|
const metaText = humanizeMeta(metaParts, intentTier ?? evt.intentTier);
|
|
8015
8317
|
if (!metaText) return null;
|
|
8016
|
-
return /* @__PURE__ */
|
|
8318
|
+
return /* @__PURE__ */ jsx6(Text5, { color: theme.info.color, dimColor: true, children: metaText });
|
|
8017
8319
|
}
|
|
8018
|
-
return /* @__PURE__ */
|
|
8320
|
+
return /* @__PURE__ */ jsxs5(Text5, { color: theme.error, children: [
|
|
8019
8321
|
"! ",
|
|
8020
8322
|
evt.text
|
|
8021
8323
|
] });
|
|
@@ -8043,9 +8345,9 @@ var init_pricing = __esm({
|
|
|
8043
8345
|
|
|
8044
8346
|
// src/ui/status.tsx
|
|
8045
8347
|
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
8046
|
-
import { Box as
|
|
8348
|
+
import { Box as Box6, Text as Text6 } from "ink";
|
|
8047
8349
|
import Spinner3 from "ink-spinner";
|
|
8048
|
-
import { jsx as
|
|
8350
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
8049
8351
|
function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode, effort, contextLimit, hasUpdate, latestVersion, gatewayMeta, codeMode, cloudMode, cloudBudget, skillsActive, memoryRecalled, phase, currentTool, lastActivityAt, kimiMdStale, gitBranch, intentTier }) {
|
|
8050
8352
|
const theme = useTheme();
|
|
8051
8353
|
const [now2, setNow] = useState2(Date.now());
|
|
@@ -8071,44 +8373,44 @@ function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode,
|
|
|
8071
8373
|
const phaseLabel = phase === "generating" ? humanizePhase("generating", intentTier) : phase === "executing" ? `${humanizePhase("executing", intentTier)} ${currentTool ?? ""}` : phase === "waiting" ? humanizePhase("waiting", intentTier) : humanizePhase("generating", intentTier);
|
|
8072
8374
|
const idleMs = lastActivityAt && thinking ? now2 - lastActivityAt : 0;
|
|
8073
8375
|
const idleLabel = idleMs > 3e4 ? ` (idle ${formatElapsed2(Math.floor(idleMs / 1e3))})` : "";
|
|
8074
|
-
return /* @__PURE__ */
|
|
8075
|
-
/* @__PURE__ */
|
|
8076
|
-
/* @__PURE__ */
|
|
8376
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
8377
|
+
/* @__PURE__ */ jsxs6(Box6, { children: [
|
|
8378
|
+
/* @__PURE__ */ jsxs6(Text6, { color: modeColor, bold: true, children: [
|
|
8077
8379
|
"[",
|
|
8078
8380
|
mode,
|
|
8079
8381
|
"]"
|
|
8080
8382
|
] }),
|
|
8081
|
-
/* @__PURE__ */
|
|
8082
|
-
thinking ? /* @__PURE__ */
|
|
8083
|
-
/* @__PURE__ */
|
|
8383
|
+
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
8384
|
+
thinking ? /* @__PURE__ */ jsxs6(Text6, { color: theme.spinner, children: [
|
|
8385
|
+
/* @__PURE__ */ jsx7(Spinner3, { type: "dots" }),
|
|
8084
8386
|
" ",
|
|
8085
8387
|
phaseLabel,
|
|
8086
8388
|
elapsed ? ` \xB7 ${elapsed}` : "",
|
|
8087
8389
|
idleLabel
|
|
8088
|
-
] }) : /* @__PURE__ */
|
|
8390
|
+
] }) : /* @__PURE__ */ jsxs6(Text6, { color: theme.info.color, children: [
|
|
8089
8391
|
leftParts.join(" \xB7 "),
|
|
8090
8392
|
" \xB7 ready"
|
|
8091
8393
|
] })
|
|
8092
8394
|
] }),
|
|
8093
|
-
labelParts.length > 0 && /* @__PURE__ */
|
|
8094
|
-
usage && /* @__PURE__ */
|
|
8095
|
-
/* @__PURE__ */
|
|
8096
|
-
warn ? /* @__PURE__ */
|
|
8395
|
+
labelParts.length > 0 && /* @__PURE__ */ jsx7(Box6, { children: /* @__PURE__ */ jsx7(Text6, { color: theme.info.color, dimColor: true, children: labelParts.join(" \xB7 ") }) }),
|
|
8396
|
+
usage && /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
8397
|
+
/* @__PURE__ */ jsx7(Text6, { color: theme.info.color, children: buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget).join(" \xB7 ") }),
|
|
8398
|
+
warn ? /* @__PURE__ */ jsxs6(Text6, { color: theme.warn, bold: true, children: [
|
|
8097
8399
|
" \xB7 ",
|
|
8098
8400
|
"/compact recommended"
|
|
8099
8401
|
] }) : null,
|
|
8100
|
-
hasUpdate ? /* @__PURE__ */
|
|
8402
|
+
hasUpdate ? /* @__PURE__ */ jsxs6(Text6, { color: theme.warn, bold: true, children: [
|
|
8101
8403
|
" \xB7 ",
|
|
8102
8404
|
"update available",
|
|
8103
8405
|
latestVersion ? ` \u2192 ${latestVersion}` : "",
|
|
8104
8406
|
" \xB7 run /update"
|
|
8105
8407
|
] }) : null,
|
|
8106
|
-
kimiMdStale ? /* @__PURE__ */
|
|
8408
|
+
kimiMdStale ? /* @__PURE__ */ jsxs6(Text6, { color: theme.warn, bold: true, children: [
|
|
8107
8409
|
" \xB7 ",
|
|
8108
8410
|
"\u26A0 KIMI.md stale \xB7 run /init"
|
|
8109
8411
|
] }) : null
|
|
8110
8412
|
] }),
|
|
8111
|
-
!thinking && /* @__PURE__ */
|
|
8413
|
+
!thinking && /* @__PURE__ */ jsx7(Box6, { children: /* @__PURE__ */ jsx7(Text6, { color: theme.muted?.color ?? theme.info.color, dimColor: theme.muted?.dim, children: "tip: shift+tab cycles mode" }) })
|
|
8112
8414
|
] });
|
|
8113
8415
|
}
|
|
8114
8416
|
function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget) {
|
|
@@ -8137,13 +8439,13 @@ function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMo
|
|
|
8137
8439
|
}
|
|
8138
8440
|
}
|
|
8139
8441
|
if (cloudMode && cloudBudget) {
|
|
8140
|
-
parts.push(`${
|
|
8442
|
+
parts.push(`${formatTokens2(cloudBudget.remaining)}/${formatTokens2(cloudBudget.limit)} tokens`);
|
|
8141
8443
|
}
|
|
8142
8444
|
const gatewayCache = formatGatewayCacheStatus(gatewayMeta);
|
|
8143
8445
|
if (gatewayCache) parts.push(gatewayCache);
|
|
8144
8446
|
return parts;
|
|
8145
8447
|
}
|
|
8146
|
-
function
|
|
8448
|
+
function formatTokens2(n) {
|
|
8147
8449
|
if (n >= 1e9) return `${(n / 1e9).toFixed(1)}B`;
|
|
8148
8450
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
8149
8451
|
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
@@ -8174,9 +8476,9 @@ var init_status = __esm({
|
|
|
8174
8476
|
});
|
|
8175
8477
|
|
|
8176
8478
|
// src/ui/permission.tsx
|
|
8177
|
-
import { Box as
|
|
8479
|
+
import { Box as Box7, Text as Text7 } from "ink";
|
|
8178
8480
|
import SelectInput from "ink-select-input";
|
|
8179
|
-
import { jsx as
|
|
8481
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
8180
8482
|
function PermissionModal({ tool, args, onDecide }) {
|
|
8181
8483
|
const theme = useTheme();
|
|
8182
8484
|
const render2 = tool.render?.(args);
|
|
@@ -8185,21 +8487,21 @@ function PermissionModal({ tool, args, onDecide }) {
|
|
|
8185
8487
|
{ label: "Allow for this session", value: "allow_session" },
|
|
8186
8488
|
{ label: "Deny", value: "deny" }
|
|
8187
8489
|
];
|
|
8188
|
-
return /* @__PURE__ */
|
|
8189
|
-
/* @__PURE__ */
|
|
8190
|
-
/* @__PURE__ */
|
|
8490
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: theme.permission, paddingX: 1, children: [
|
|
8491
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.permission, bold: true, children: "Permission requested" }),
|
|
8492
|
+
/* @__PURE__ */ jsxs7(Text7, { children: [
|
|
8191
8493
|
"tool: ",
|
|
8192
|
-
/* @__PURE__ */
|
|
8494
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.tool, children: tool.name })
|
|
8193
8495
|
] }),
|
|
8194
|
-
render2?.title ? /* @__PURE__ */
|
|
8496
|
+
render2?.title ? /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
8195
8497
|
"action: ",
|
|
8196
8498
|
render2.title
|
|
8197
8499
|
] }) : null,
|
|
8198
|
-
render2?.diff ? /* @__PURE__ */
|
|
8500
|
+
render2?.diff ? /* @__PURE__ */ jsx8(Box7, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx8(DiffView, { ...render2.diff }) }) : /* @__PURE__ */ jsxs7(Text7, { color: theme.info.color, children: [
|
|
8199
8501
|
"args: ",
|
|
8200
8502
|
JSON.stringify(args)
|
|
8201
8503
|
] }),
|
|
8202
|
-
/* @__PURE__ */
|
|
8504
|
+
/* @__PURE__ */ jsx8(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx8(SelectInput, { items, onSelect: (item) => onDecide(item.value) }) })
|
|
8203
8505
|
] });
|
|
8204
8506
|
}
|
|
8205
8507
|
var init_permission = __esm({
|
|
@@ -8211,27 +8513,27 @@ var init_permission = __esm({
|
|
|
8211
8513
|
});
|
|
8212
8514
|
|
|
8213
8515
|
// src/ui/limit-modal.tsx
|
|
8214
|
-
import { Box as
|
|
8516
|
+
import { Box as Box8, Text as Text8 } from "ink";
|
|
8215
8517
|
import SelectInput2 from "ink-select-input";
|
|
8216
|
-
import { jsx as
|
|
8518
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
8217
8519
|
function LimitModal({ limit, onDecide }) {
|
|
8218
8520
|
const theme = useTheme();
|
|
8219
8521
|
const items = [
|
|
8220
8522
|
{ label: "Continue", value: "continue" },
|
|
8221
8523
|
{ label: "Stop", value: "stop" }
|
|
8222
8524
|
];
|
|
8223
|
-
return /* @__PURE__ */
|
|
8224
|
-
/* @__PURE__ */
|
|
8525
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: theme.error, paddingX: 1, children: [
|
|
8526
|
+
/* @__PURE__ */ jsxs8(Text8, { color: theme.error, bold: true, children: [
|
|
8225
8527
|
"Tool-call limit reached (",
|
|
8226
8528
|
limit,
|
|
8227
8529
|
")"
|
|
8228
8530
|
] }),
|
|
8229
|
-
/* @__PURE__ */
|
|
8531
|
+
/* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
8230
8532
|
"This session has made ",
|
|
8231
8533
|
limit,
|
|
8232
8534
|
" tool calls. What would you like to do?"
|
|
8233
8535
|
] }),
|
|
8234
|
-
/* @__PURE__ */
|
|
8536
|
+
/* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx9(
|
|
8235
8537
|
SelectInput2,
|
|
8236
8538
|
{
|
|
8237
8539
|
items,
|
|
@@ -8249,9 +8551,9 @@ var init_limit_modal = __esm({
|
|
|
8249
8551
|
|
|
8250
8552
|
// src/ui/resume-picker.tsx
|
|
8251
8553
|
import { useState as useState3 } from "react";
|
|
8252
|
-
import { Box as
|
|
8554
|
+
import { Box as Box9, Text as Text9, useWindowSize } from "ink";
|
|
8253
8555
|
import SelectInput3 from "ink-select-input";
|
|
8254
|
-
import { jsx as
|
|
8556
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
8255
8557
|
function ResumePicker({ sessions, onPick }) {
|
|
8256
8558
|
const theme = useTheme();
|
|
8257
8559
|
const { rows } = useWindowSize();
|
|
@@ -8260,10 +8562,10 @@ function ResumePicker({ sessions, onPick }) {
|
|
|
8260
8562
|
const totalPages = Math.max(1, Math.ceil(sessions.length / pageSize));
|
|
8261
8563
|
const safePage = Math.min(page, totalPages - 1);
|
|
8262
8564
|
if (sessions.length === 0) {
|
|
8263
|
-
return /* @__PURE__ */
|
|
8264
|
-
/* @__PURE__ */
|
|
8265
|
-
/* @__PURE__ */
|
|
8266
|
-
/* @__PURE__ */
|
|
8565
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
8566
|
+
/* @__PURE__ */ jsx10(Text9, { color: theme.accent, bold: true, children: "Resume a session" }),
|
|
8567
|
+
/* @__PURE__ */ jsx10(Text9, { color: theme.info.color, children: "No saved sessions yet. Press Enter to dismiss." }),
|
|
8568
|
+
/* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(
|
|
8267
8569
|
SelectInput3,
|
|
8268
8570
|
{
|
|
8269
8571
|
items: [{ label: "(back)", value: "__cancel__" }],
|
|
@@ -8286,9 +8588,9 @@ function ResumePicker({ sessions, onPick }) {
|
|
|
8286
8588
|
items.push({ label: "\u2192 next page", value: "__next__" });
|
|
8287
8589
|
}
|
|
8288
8590
|
items.push({ label: "(cancel)", value: "__cancel__" });
|
|
8289
|
-
return /* @__PURE__ */
|
|
8290
|
-
/* @__PURE__ */
|
|
8291
|
-
/* @__PURE__ */
|
|
8591
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
8592
|
+
/* @__PURE__ */ jsx10(Text9, { color: theme.accent, bold: true, children: "Resume a session" }),
|
|
8593
|
+
/* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, children: [
|
|
8292
8594
|
"Arrow keys to select, Enter to confirm. Page ",
|
|
8293
8595
|
safePage + 1,
|
|
8294
8596
|
" of ",
|
|
@@ -8297,7 +8599,7 @@ function ResumePicker({ sessions, onPick }) {
|
|
|
8297
8599
|
sessions.length,
|
|
8298
8600
|
" total)"
|
|
8299
8601
|
] }),
|
|
8300
|
-
/* @__PURE__ */
|
|
8602
|
+
/* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(
|
|
8301
8603
|
SelectInput3,
|
|
8302
8604
|
{
|
|
8303
8605
|
items,
|
|
@@ -8338,9 +8640,9 @@ var init_resume_picker = __esm({
|
|
|
8338
8640
|
|
|
8339
8641
|
// src/ui/task-list.tsx
|
|
8340
8642
|
import { useEffect as useEffect3, useRef, useState as useState4 } from "react";
|
|
8341
|
-
import { Box as
|
|
8643
|
+
import { Box as Box10, Text as Text10 } from "ink";
|
|
8342
8644
|
import Spinner4 from "ink-spinner";
|
|
8343
|
-
import { jsx as
|
|
8645
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
8344
8646
|
function TaskList({ tasks, startedAt, tokensDelta }) {
|
|
8345
8647
|
const theme = useTheme();
|
|
8346
8648
|
const [now2, setNow] = useState4(Date.now());
|
|
@@ -8364,21 +8666,21 @@ function TaskList({ tasks, startedAt, tokensDelta }) {
|
|
|
8364
8666
|
const allDone = done === total;
|
|
8365
8667
|
const header = active ? active.title : allDone ? `${total} tasks done` : `${done}/${total}`;
|
|
8366
8668
|
const elapsed = startedAt ? formatElapsed3(now2 - startedAt) : null;
|
|
8367
|
-
const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${
|
|
8669
|
+
const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${formatTokens3(tokensDelta)} tokens` : null].filter(Boolean).join(" \xB7 ");
|
|
8368
8670
|
const visibleTasks = tasks.slice(0, MAX_VISIBLE);
|
|
8369
8671
|
const hiddenPending = Math.max(0, tasks.length - visibleTasks.length);
|
|
8370
|
-
return /* @__PURE__ */
|
|
8371
|
-
/* @__PURE__ */
|
|
8372
|
-
/* @__PURE__ */
|
|
8373
|
-
headerStats && /* @__PURE__ */
|
|
8672
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginBottom: 1, children: [
|
|
8673
|
+
/* @__PURE__ */ jsxs10(Box10, { children: [
|
|
8674
|
+
/* @__PURE__ */ jsx11(Text10, { color: allDone ? "green" : theme.accent, bold: true, children: header }),
|
|
8675
|
+
headerStats && /* @__PURE__ */ jsxs10(Text10, { color: theme.info.color, children: [
|
|
8374
8676
|
" ",
|
|
8375
8677
|
"(",
|
|
8376
8678
|
headerStats,
|
|
8377
8679
|
")"
|
|
8378
8680
|
] })
|
|
8379
8681
|
] }),
|
|
8380
|
-
visibleTasks.map((t) => /* @__PURE__ */
|
|
8381
|
-
hiddenPending > 0 && /* @__PURE__ */
|
|
8682
|
+
visibleTasks.map((t) => /* @__PURE__ */ jsx11(TaskRow, { task: t }, t.id)),
|
|
8683
|
+
hiddenPending > 0 && /* @__PURE__ */ jsxs10(Text10, { color: theme.info.color, children: [
|
|
8382
8684
|
" ",
|
|
8383
8685
|
"\u2026 +",
|
|
8384
8686
|
hiddenPending,
|
|
@@ -8389,21 +8691,21 @@ function TaskList({ tasks, startedAt, tokensDelta }) {
|
|
|
8389
8691
|
function TaskRow({ task }) {
|
|
8390
8692
|
const theme = useTheme();
|
|
8391
8693
|
if (task.status === "completed") {
|
|
8392
|
-
return /* @__PURE__ */
|
|
8694
|
+
return /* @__PURE__ */ jsxs10(Text10, { color: theme.info.color, children: [
|
|
8393
8695
|
" ",
|
|
8394
8696
|
"\u2713 ",
|
|
8395
|
-
/* @__PURE__ */
|
|
8697
|
+
/* @__PURE__ */ jsx11(Text10, { strikethrough: true, children: task.title })
|
|
8396
8698
|
] });
|
|
8397
8699
|
}
|
|
8398
8700
|
if (task.status === "in_progress") {
|
|
8399
|
-
return /* @__PURE__ */
|
|
8701
|
+
return /* @__PURE__ */ jsxs10(Text10, { color: theme.accent, bold: true, children: [
|
|
8400
8702
|
" ",
|
|
8401
|
-
/* @__PURE__ */
|
|
8703
|
+
/* @__PURE__ */ jsx11(Spinner4, { type: "dots" }),
|
|
8402
8704
|
" ",
|
|
8403
8705
|
task.title
|
|
8404
8706
|
] });
|
|
8405
8707
|
}
|
|
8406
|
-
return /* @__PURE__ */
|
|
8708
|
+
return /* @__PURE__ */ jsxs10(Text10, { color: theme.info.color, children: [
|
|
8407
8709
|
" ",
|
|
8408
8710
|
"\u2610 ",
|
|
8409
8711
|
task.title
|
|
@@ -8416,7 +8718,7 @@ function formatElapsed3(ms) {
|
|
|
8416
8718
|
if (m === 0) return `${s}s`;
|
|
8417
8719
|
return `${m}m ${s}s`;
|
|
8418
8720
|
}
|
|
8419
|
-
function
|
|
8721
|
+
function formatTokens3(n) {
|
|
8420
8722
|
if (n < 1e3) return String(n);
|
|
8421
8723
|
return `${(n / 1e3).toFixed(1)}k`;
|
|
8422
8724
|
}
|
|
@@ -8951,8 +9253,8 @@ var init_source = __esm({
|
|
|
8951
9253
|
|
|
8952
9254
|
// src/ui/text-input.tsx
|
|
8953
9255
|
import { useState as useState5, useEffect as useEffect4, useRef as useRef2 } from "react";
|
|
8954
|
-
import { Text as
|
|
8955
|
-
import { jsx as
|
|
9256
|
+
import { Text as Text11, useInput } from "ink";
|
|
9257
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
8956
9258
|
function shouldTreatAsPaste(input) {
|
|
8957
9259
|
if (input.length >= PASTE_CHAR_THRESHOLD) return true;
|
|
8958
9260
|
const newlines = (input.match(/\n/g) ?? []).length;
|
|
@@ -9162,7 +9464,7 @@ function CustomTextInput({
|
|
|
9162
9464
|
} else if (cursorOffset === displayValue.length) {
|
|
9163
9465
|
renderedValue += source_default.inverse(" ");
|
|
9164
9466
|
}
|
|
9165
|
-
return /* @__PURE__ */
|
|
9467
|
+
return /* @__PURE__ */ jsx12(Text11, { children: renderedValue });
|
|
9166
9468
|
}
|
|
9167
9469
|
function findPasteTokenEndingAt(value, pos, pastes) {
|
|
9168
9470
|
if (pos <= 0 || value[pos - 1] !== "]") return -1;
|
|
@@ -9185,12 +9487,12 @@ var init_text_input = __esm({
|
|
|
9185
9487
|
|
|
9186
9488
|
// src/ui/onboarding.tsx
|
|
9187
9489
|
import { useState as useState6, useEffect as useEffect5, useCallback } from "react";
|
|
9188
|
-
import { Box as
|
|
9490
|
+
import { Box as Box11, Text as Text12, useInput as useInput2 } from "ink";
|
|
9189
9491
|
import SelectInput4 from "ink-select-input";
|
|
9190
9492
|
import Spinner5 from "ink-spinner";
|
|
9191
9493
|
import { exec } from "child_process";
|
|
9192
9494
|
import { promisify as promisify2 } from "util";
|
|
9193
|
-
import { Fragment, jsx as
|
|
9495
|
+
import { Fragment, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
9194
9496
|
function openBrowser(url) {
|
|
9195
9497
|
const platform3 = process.platform;
|
|
9196
9498
|
const cmd = platform3 === "darwin" ? `open "${url}"` : platform3 === "win32" ? `start "" "${url}"` : `xdg-open "${url}"`;
|
|
@@ -9346,24 +9648,24 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
9346
9648
|
const byokSteps = ["accountId", "apiToken", "model", "confirm"];
|
|
9347
9649
|
const stepIndex = step === "mode" ? 1 : step === "cloudAuth" ? 2 : byokSteps.indexOf(step) + 2;
|
|
9348
9650
|
const totalSteps = mode === "cloud" ? 2 : byokSteps.length + 1;
|
|
9349
|
-
return /* @__PURE__ */
|
|
9350
|
-
/* @__PURE__ */
|
|
9351
|
-
/* @__PURE__ */
|
|
9352
|
-
/* @__PURE__ */
|
|
9651
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingY: 1, children: [
|
|
9652
|
+
/* @__PURE__ */ jsxs11(Box11, { marginBottom: 1, children: [
|
|
9653
|
+
/* @__PURE__ */ jsx13(Text12, { bold: true, color: theme.palette.primary, children: "kimiflare" }),
|
|
9654
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
9353
9655
|
" ",
|
|
9354
9656
|
"Terminal coding agent"
|
|
9355
9657
|
] })
|
|
9356
9658
|
] }),
|
|
9357
|
-
/* @__PURE__ */
|
|
9659
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
9358
9660
|
"Step ",
|
|
9359
9661
|
stepIndex,
|
|
9360
9662
|
" of ",
|
|
9361
9663
|
totalSteps
|
|
9362
9664
|
] }),
|
|
9363
|
-
/* @__PURE__ */
|
|
9364
|
-
step === "mode" && /* @__PURE__ */
|
|
9365
|
-
/* @__PURE__ */
|
|
9366
|
-
/* @__PURE__ */
|
|
9665
|
+
/* @__PURE__ */ jsxs11(Box11, { marginTop: 1, flexDirection: "column", children: [
|
|
9666
|
+
step === "mode" && /* @__PURE__ */ jsxs11(Fragment, { children: [
|
|
9667
|
+
/* @__PURE__ */ jsx13(Text12, { children: "How do you want to connect?" }),
|
|
9668
|
+
/* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx13(
|
|
9367
9669
|
SelectInput4,
|
|
9368
9670
|
{
|
|
9369
9671
|
items: [
|
|
@@ -9374,19 +9676,19 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
9374
9676
|
}
|
|
9375
9677
|
) })
|
|
9376
9678
|
] }),
|
|
9377
|
-
step === "cloudAuth" && cloudAuth?.phase === "ready" && /* @__PURE__ */
|
|
9378
|
-
/* @__PURE__ */
|
|
9379
|
-
/* @__PURE__ */
|
|
9380
|
-
/* @__PURE__ */
|
|
9381
|
-
/* @__PURE__ */
|
|
9679
|
+
step === "cloudAuth" && cloudAuth?.phase === "ready" && /* @__PURE__ */ jsxs11(Fragment, { children: [
|
|
9680
|
+
/* @__PURE__ */ jsx13(Text12, { children: "Authenticating with Kimiflare Cloud..." }),
|
|
9681
|
+
/* @__PURE__ */ jsxs11(Box11, { marginTop: 1, flexDirection: "column", children: [
|
|
9682
|
+
/* @__PURE__ */ jsx13(Text12, { children: "1. Open this URL in your browser:" }),
|
|
9683
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.palette.primary, children: cloudAuth.codes.authUrl })
|
|
9382
9684
|
] }),
|
|
9383
|
-
/* @__PURE__ */
|
|
9384
|
-
/* @__PURE__ */
|
|
9385
|
-
/* @__PURE__ */
|
|
9685
|
+
/* @__PURE__ */ jsxs11(Box11, { marginTop: 1, children: [
|
|
9686
|
+
/* @__PURE__ */ jsx13(Text12, { children: "2. " }),
|
|
9687
|
+
/* @__PURE__ */ jsx13(Text12, { bold: true, children: "[Press Enter to open browser]" })
|
|
9386
9688
|
] }),
|
|
9387
|
-
/* @__PURE__ */
|
|
9388
|
-
/* @__PURE__ */
|
|
9389
|
-
/* @__PURE__ */
|
|
9689
|
+
/* @__PURE__ */ jsxs11(Box11, { marginTop: 1, children: [
|
|
9690
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.palette.primary, children: "\u203A " }),
|
|
9691
|
+
/* @__PURE__ */ jsx13(
|
|
9390
9692
|
CustomTextInput,
|
|
9391
9693
|
{
|
|
9392
9694
|
value: "",
|
|
@@ -9397,28 +9699,28 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
9397
9699
|
)
|
|
9398
9700
|
] })
|
|
9399
9701
|
] }),
|
|
9400
|
-
step === "cloudAuth" && cloudAuth?.phase === "polling" && /* @__PURE__ */
|
|
9401
|
-
/* @__PURE__ */
|
|
9402
|
-
/* @__PURE__ */
|
|
9702
|
+
step === "cloudAuth" && cloudAuth?.phase === "polling" && /* @__PURE__ */ jsxs11(Fragment, { children: [
|
|
9703
|
+
/* @__PURE__ */ jsxs11(Text12, { children: [
|
|
9704
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.spinner, children: /* @__PURE__ */ jsx13(Spinner5, { type: "dots" }) }),
|
|
9403
9705
|
" ",
|
|
9404
9706
|
"Waiting for authentication..."
|
|
9405
9707
|
] }),
|
|
9406
|
-
/* @__PURE__ */
|
|
9708
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
9407
9709
|
"Expires in ",
|
|
9408
9710
|
formatRemaining(POLL_TIMEOUT_MS - (Date.now() - cloudAuth.startTime))
|
|
9409
9711
|
] }),
|
|
9410
|
-
/* @__PURE__ */
|
|
9712
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
9411
9713
|
"URL: ",
|
|
9412
9714
|
cloudAuth.codes.authUrl
|
|
9413
9715
|
] })
|
|
9414
9716
|
] }),
|
|
9415
|
-
step === "cloudAuth" && cloudAuth?.phase === "success" && /* @__PURE__ */
|
|
9416
|
-
/* @__PURE__ */
|
|
9417
|
-
/* @__PURE__ */
|
|
9418
|
-
/* @__PURE__ */
|
|
9717
|
+
step === "cloudAuth" && cloudAuth?.phase === "success" && /* @__PURE__ */ jsxs11(Fragment, { children: [
|
|
9718
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.palette.success, children: "Authenticated!" }),
|
|
9719
|
+
/* @__PURE__ */ jsxs11(Box11, { marginTop: 1, flexDirection: "column", children: [
|
|
9720
|
+
/* @__PURE__ */ jsxs11(Text12, { children: [
|
|
9419
9721
|
"Token budget:",
|
|
9420
9722
|
" ",
|
|
9421
|
-
/* @__PURE__ */
|
|
9723
|
+
/* @__PURE__ */ jsxs11(Text12, { bold: true, children: [
|
|
9422
9724
|
cloudAuth.usage.remaining.toLocaleString(),
|
|
9423
9725
|
" /",
|
|
9424
9726
|
" ",
|
|
@@ -9427,15 +9729,15 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
9427
9729
|
" ",
|
|
9428
9730
|
"remaining"
|
|
9429
9731
|
] }),
|
|
9430
|
-
/* @__PURE__ */
|
|
9732
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
9431
9733
|
"Grant expires: ",
|
|
9432
9734
|
cloudAuth.usage.expires_at
|
|
9433
9735
|
] })
|
|
9434
9736
|
] }),
|
|
9435
|
-
/* @__PURE__ */
|
|
9436
|
-
/* @__PURE__ */
|
|
9437
|
-
/* @__PURE__ */
|
|
9438
|
-
/* @__PURE__ */
|
|
9737
|
+
/* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text12, { children: "[Press Enter to continue]" }) }),
|
|
9738
|
+
/* @__PURE__ */ jsxs11(Box11, { marginTop: 1, children: [
|
|
9739
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.palette.primary, children: "\u203A " }),
|
|
9740
|
+
/* @__PURE__ */ jsx13(
|
|
9439
9741
|
CustomTextInput,
|
|
9440
9742
|
{
|
|
9441
9743
|
value: "",
|
|
@@ -9446,10 +9748,10 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
9446
9748
|
)
|
|
9447
9749
|
] })
|
|
9448
9750
|
] }),
|
|
9449
|
-
step === "cloudAuth" && cloudAuth?.phase === "error" && /* @__PURE__ */
|
|
9450
|
-
/* @__PURE__ */
|
|
9451
|
-
/* @__PURE__ */
|
|
9452
|
-
/* @__PURE__ */
|
|
9751
|
+
step === "cloudAuth" && cloudAuth?.phase === "error" && /* @__PURE__ */ jsxs11(Fragment, { children: [
|
|
9752
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.palette.error, children: "Authentication failed" }),
|
|
9753
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.info.color, children: cloudAuth.message }),
|
|
9754
|
+
/* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx13(
|
|
9453
9755
|
SelectInput4,
|
|
9454
9756
|
{
|
|
9455
9757
|
items: [
|
|
@@ -9465,11 +9767,11 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
9465
9767
|
}
|
|
9466
9768
|
) })
|
|
9467
9769
|
] }),
|
|
9468
|
-
step === "accountId" && /* @__PURE__ */
|
|
9469
|
-
/* @__PURE__ */
|
|
9470
|
-
/* @__PURE__ */
|
|
9471
|
-
/* @__PURE__ */
|
|
9472
|
-
/* @__PURE__ */
|
|
9770
|
+
step === "accountId" && /* @__PURE__ */ jsxs11(Fragment, { children: [
|
|
9771
|
+
/* @__PURE__ */ jsx13(Text12, { children: "Enter your Cloudflare Account ID" }),
|
|
9772
|
+
/* @__PURE__ */ jsxs11(Box11, { marginTop: 1, children: [
|
|
9773
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.palette.primary, children: "\u203A " }),
|
|
9774
|
+
/* @__PURE__ */ jsx13(
|
|
9473
9775
|
CustomTextInput,
|
|
9474
9776
|
{
|
|
9475
9777
|
value: accountId,
|
|
@@ -9479,12 +9781,12 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
9479
9781
|
)
|
|
9480
9782
|
] })
|
|
9481
9783
|
] }),
|
|
9482
|
-
step === "apiToken" && /* @__PURE__ */
|
|
9483
|
-
/* @__PURE__ */
|
|
9484
|
-
/* @__PURE__ */
|
|
9485
|
-
/* @__PURE__ */
|
|
9486
|
-
/* @__PURE__ */
|
|
9487
|
-
/* @__PURE__ */
|
|
9784
|
+
step === "apiToken" && /* @__PURE__ */ jsxs11(Fragment, { children: [
|
|
9785
|
+
/* @__PURE__ */ jsx13(Text12, { children: "Enter your Cloudflare API Token" }),
|
|
9786
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.info.color, children: "Create one at https://dash.cloudflare.com/profile/api-tokens" }),
|
|
9787
|
+
/* @__PURE__ */ jsxs11(Box11, { marginTop: 1, children: [
|
|
9788
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.palette.primary, children: "\u203A " }),
|
|
9789
|
+
/* @__PURE__ */ jsx13(
|
|
9488
9790
|
CustomTextInput,
|
|
9489
9791
|
{
|
|
9490
9792
|
value: apiToken,
|
|
@@ -9495,15 +9797,15 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
9495
9797
|
)
|
|
9496
9798
|
] })
|
|
9497
9799
|
] }),
|
|
9498
|
-
step === "model" && /* @__PURE__ */
|
|
9499
|
-
/* @__PURE__ */
|
|
9500
|
-
/* @__PURE__ */
|
|
9800
|
+
step === "model" && /* @__PURE__ */ jsxs11(Fragment, { children: [
|
|
9801
|
+
/* @__PURE__ */ jsx13(Text12, { children: "Model ID (press Enter for default)" }),
|
|
9802
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
9501
9803
|
"default: ",
|
|
9502
9804
|
DEFAULT_MODEL
|
|
9503
9805
|
] }),
|
|
9504
|
-
/* @__PURE__ */
|
|
9505
|
-
/* @__PURE__ */
|
|
9506
|
-
/* @__PURE__ */
|
|
9806
|
+
/* @__PURE__ */ jsxs11(Box11, { marginTop: 1, children: [
|
|
9807
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.palette.primary, children: "\u203A " }),
|
|
9808
|
+
/* @__PURE__ */ jsx13(
|
|
9507
9809
|
CustomTextInput,
|
|
9508
9810
|
{
|
|
9509
9811
|
value: model,
|
|
@@ -9513,10 +9815,10 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
9513
9815
|
)
|
|
9514
9816
|
] })
|
|
9515
9817
|
] }),
|
|
9516
|
-
step === "confirm" && /* @__PURE__ */
|
|
9517
|
-
/* @__PURE__ */
|
|
9518
|
-
/* @__PURE__ */
|
|
9519
|
-
|
|
9818
|
+
step === "confirm" && /* @__PURE__ */ jsxs11(Fragment, { children: [
|
|
9819
|
+
/* @__PURE__ */ jsx13(Text12, { children: "Ready to save configuration" }),
|
|
9820
|
+
/* @__PURE__ */ jsxs11(
|
|
9821
|
+
Box11,
|
|
9520
9822
|
{
|
|
9521
9823
|
flexDirection: "column",
|
|
9522
9824
|
marginTop: 1,
|
|
@@ -9525,25 +9827,25 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
9525
9827
|
borderColor: theme.info.color,
|
|
9526
9828
|
paddingX: 1,
|
|
9527
9829
|
children: [
|
|
9528
|
-
/* @__PURE__ */
|
|
9830
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
9529
9831
|
"Account ID: ",
|
|
9530
9832
|
accountId
|
|
9531
9833
|
] }),
|
|
9532
|
-
/* @__PURE__ */
|
|
9834
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
9533
9835
|
"API Token: ",
|
|
9534
9836
|
"\u2022".repeat(apiToken.length)
|
|
9535
9837
|
] }),
|
|
9536
|
-
/* @__PURE__ */
|
|
9838
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
9537
9839
|
"Model: ",
|
|
9538
9840
|
model
|
|
9539
9841
|
] })
|
|
9540
9842
|
]
|
|
9541
9843
|
}
|
|
9542
9844
|
),
|
|
9543
|
-
/* @__PURE__ */
|
|
9544
|
-
/* @__PURE__ */
|
|
9545
|
-
/* @__PURE__ */
|
|
9546
|
-
/* @__PURE__ */
|
|
9845
|
+
/* @__PURE__ */ jsx13(Text12, { children: "Press Enter to confirm, or Ctrl+C to cancel" }),
|
|
9846
|
+
/* @__PURE__ */ jsxs11(Box11, { marginTop: 1, children: [
|
|
9847
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.palette.primary, children: "\u203A " }),
|
|
9848
|
+
/* @__PURE__ */ jsx13(
|
|
9547
9849
|
CustomTextInput,
|
|
9548
9850
|
{
|
|
9549
9851
|
value: "",
|
|
@@ -9554,7 +9856,7 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
9554
9856
|
)
|
|
9555
9857
|
] })
|
|
9556
9858
|
] }),
|
|
9557
|
-
savedPath && /* @__PURE__ */
|
|
9859
|
+
savedPath && /* @__PURE__ */ jsxs11(Text12, { color: theme.palette.success, children: [
|
|
9558
9860
|
"Config saved to ",
|
|
9559
9861
|
savedPath
|
|
9560
9862
|
] })
|
|
@@ -9574,34 +9876,34 @@ var init_onboarding = __esm({
|
|
|
9574
9876
|
});
|
|
9575
9877
|
|
|
9576
9878
|
// src/ui/welcome.tsx
|
|
9577
|
-
import { Box as
|
|
9578
|
-
import { jsx as
|
|
9879
|
+
import { Box as Box12, Text as Text13 } from "ink";
|
|
9880
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
9579
9881
|
function Welcome({ accountId, cloudMode }) {
|
|
9580
9882
|
const theme = useTheme();
|
|
9581
|
-
return /* @__PURE__ */
|
|
9582
|
-
/* @__PURE__ */
|
|
9583
|
-
/* @__PURE__ */
|
|
9584
|
-
/* @__PURE__ */
|
|
9883
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginBottom: 1, children: [
|
|
9884
|
+
/* @__PURE__ */ jsxs12(Box12, { marginBottom: 1, children: [
|
|
9885
|
+
/* @__PURE__ */ jsx14(Text13, { bold: true, color: theme.accent, children: "kimiflare" }),
|
|
9886
|
+
/* @__PURE__ */ jsxs12(Text13, { color: theme.info.color, children: [
|
|
9585
9887
|
" ",
|
|
9586
9888
|
"Ready when you are."
|
|
9587
9889
|
] })
|
|
9588
9890
|
] }),
|
|
9589
|
-
accountId && !cloudMode && /* @__PURE__ */
|
|
9891
|
+
accountId && !cloudMode && /* @__PURE__ */ jsx14(Box12, { marginBottom: 1, children: /* @__PURE__ */ jsxs12(Text13, { color: theme.info.color, children: [
|
|
9590
9892
|
" ",
|
|
9591
9893
|
"Check your Cloudflare billing: https://dash.cloudflare.com/",
|
|
9592
9894
|
accountId,
|
|
9593
9895
|
"/billing/billable-usage"
|
|
9594
9896
|
] }) }),
|
|
9595
|
-
/* @__PURE__ */
|
|
9596
|
-
/* @__PURE__ */
|
|
9897
|
+
/* @__PURE__ */ jsx14(Box12, { flexDirection: "column", children: SUGGESTIONS.map((s, i) => /* @__PURE__ */ jsxs12(Box12, { children: [
|
|
9898
|
+
/* @__PURE__ */ jsxs12(Text13, { color: theme.info.color, children: [
|
|
9597
9899
|
" ",
|
|
9598
9900
|
"\u203A",
|
|
9599
9901
|
" "
|
|
9600
9902
|
] }),
|
|
9601
|
-
/* @__PURE__ */
|
|
9903
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.user, children: s })
|
|
9602
9904
|
] }, i)) }),
|
|
9603
|
-
/* @__PURE__ */
|
|
9604
|
-
/* @__PURE__ */
|
|
9905
|
+
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, children: "Type a message or /help for commands \xB7 ctrl-c to exit \xB7 shift+tab to cycle modes" }) }),
|
|
9906
|
+
/* @__PURE__ */ jsx14(Box12, { children: /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, children: "Tip: type /hello to send feedback to the creator" }) })
|
|
9605
9907
|
] });
|
|
9606
9908
|
}
|
|
9607
9909
|
var SUGGESTIONS;
|
|
@@ -9722,9 +10024,9 @@ var init_tui_deploy = __esm({
|
|
|
9722
10024
|
|
|
9723
10025
|
// src/ui/remote-dashboard.tsx
|
|
9724
10026
|
import { useEffect as useEffect6, useState as useState7 } from "react";
|
|
9725
|
-
import { Box as
|
|
10027
|
+
import { Box as Box13, Text as Text14, useInput as useInput3 } from "ink";
|
|
9726
10028
|
import SelectInput5 from "ink-select-input";
|
|
9727
|
-
import { jsx as
|
|
10029
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
9728
10030
|
function RemoteDashboard({ onSelect, onCancel }) {
|
|
9729
10031
|
const theme = useTheme();
|
|
9730
10032
|
const [sessions, setSessions] = useState7([]);
|
|
@@ -9780,30 +10082,30 @@ function RemoteDashboard({ onSelect, onCancel }) {
|
|
|
9780
10082
|
value: s.sessionId
|
|
9781
10083
|
}));
|
|
9782
10084
|
if (loading) {
|
|
9783
|
-
return /* @__PURE__ */
|
|
10085
|
+
return /* @__PURE__ */ jsx15(Box13, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx15(Text14, { color: theme.accent, children: "Loading remote sessions..." }) });
|
|
9784
10086
|
}
|
|
9785
10087
|
if (error) {
|
|
9786
|
-
return /* @__PURE__ */
|
|
9787
|
-
/* @__PURE__ */
|
|
10088
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
10089
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.error, children: [
|
|
9788
10090
|
"Error: ",
|
|
9789
10091
|
error
|
|
9790
10092
|
] }),
|
|
9791
|
-
/* @__PURE__ */
|
|
10093
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Press R to retry, Esc to close" })
|
|
9792
10094
|
] });
|
|
9793
10095
|
}
|
|
9794
10096
|
if (sessions.length === 0) {
|
|
9795
|
-
return /* @__PURE__ */
|
|
9796
|
-
/* @__PURE__ */
|
|
9797
|
-
/* @__PURE__ */
|
|
9798
|
-
/* @__PURE__ */
|
|
10097
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
10098
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.accent, children: "No remote sessions yet." }),
|
|
10099
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Type /remote <prompt> to start one." }),
|
|
10100
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Press Esc to close" })
|
|
9799
10101
|
] });
|
|
9800
10102
|
}
|
|
9801
|
-
return /* @__PURE__ */
|
|
9802
|
-
/* @__PURE__ */
|
|
10103
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
10104
|
+
/* @__PURE__ */ jsxs13(Text14, { bold: true, color: theme.accent, children: [
|
|
9803
10105
|
"Recent remote tasks ",
|
|
9804
10106
|
refreshing ? "(refreshing...)" : ""
|
|
9805
10107
|
] }),
|
|
9806
|
-
/* @__PURE__ */
|
|
10108
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
9807
10109
|
SelectInput5,
|
|
9808
10110
|
{
|
|
9809
10111
|
items,
|
|
@@ -9813,7 +10115,7 @@ function RemoteDashboard({ onSelect, onCancel }) {
|
|
|
9813
10115
|
}
|
|
9814
10116
|
}
|
|
9815
10117
|
) }),
|
|
9816
|
-
/* @__PURE__ */
|
|
10118
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "\u2191\u2193 navigate \u2022 Enter select \u2022 R refresh \u2022 Esc close" }) })
|
|
9817
10119
|
] });
|
|
9818
10120
|
}
|
|
9819
10121
|
function formatSessionLine(s) {
|
|
@@ -9821,7 +10123,7 @@ function formatSessionLine(s) {
|
|
|
9821
10123
|
const ago = formatAgo(new Date(s.updatedAt));
|
|
9822
10124
|
const prompt = s.prompt.slice(0, 30) + (s.prompt.length > 30 ? "\u2026" : "");
|
|
9823
10125
|
const outcome = s.prUrl ? `PR ${s.prUrl.split("/").pop()}` : s.status;
|
|
9824
|
-
const cost = s.tokensUsed && s.tokensBudget ? ` (${
|
|
10126
|
+
const cost = s.tokensUsed && s.tokensBudget ? ` (${formatTokens4(s.tokensUsed)}/${formatTokens4(s.tokensBudget)})` : s.tokensUsed ? ` (${formatTokens4(s.tokensUsed)})` : "";
|
|
9825
10127
|
return `${icon} ${prompt} \u2192 ${outcome} ${ago}${cost}`;
|
|
9826
10128
|
}
|
|
9827
10129
|
function formatAgo(date) {
|
|
@@ -9834,7 +10136,7 @@ function formatAgo(date) {
|
|
|
9834
10136
|
if (minutes > 0) return `${minutes}m ago`;
|
|
9835
10137
|
return "just now";
|
|
9836
10138
|
}
|
|
9837
|
-
function
|
|
10139
|
+
function formatTokens4(n) {
|
|
9838
10140
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
9839
10141
|
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
9840
10142
|
return String(n);
|
|
@@ -9866,50 +10168,50 @@ function RemoteSessionDetail({
|
|
|
9866
10168
|
}
|
|
9867
10169
|
}
|
|
9868
10170
|
const isRunning = session.status === "running" || session.status === "pending";
|
|
9869
|
-
return /* @__PURE__ */
|
|
9870
|
-
/* @__PURE__ */
|
|
9871
|
-
/* @__PURE__ */
|
|
9872
|
-
/* @__PURE__ */
|
|
10171
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
10172
|
+
/* @__PURE__ */ jsx15(Text14, { bold: true, color: theme.accent, children: "Remote Session" }),
|
|
10173
|
+
/* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
|
|
10174
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
9873
10175
|
"ID: ",
|
|
9874
10176
|
session.sessionId
|
|
9875
10177
|
] }),
|
|
9876
|
-
/* @__PURE__ */
|
|
10178
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
9877
10179
|
"Repo: ",
|
|
9878
10180
|
session.repo
|
|
9879
10181
|
] }),
|
|
9880
|
-
/* @__PURE__ */
|
|
10182
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
9881
10183
|
"Status: ",
|
|
9882
10184
|
session.status
|
|
9883
10185
|
] }),
|
|
9884
|
-
/* @__PURE__ */
|
|
10186
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
9885
10187
|
"Prompt: ",
|
|
9886
10188
|
session.prompt
|
|
9887
10189
|
] }),
|
|
9888
|
-
session.prUrl && /* @__PURE__ */
|
|
10190
|
+
session.prUrl && /* @__PURE__ */ jsxs13(Text14, { children: [
|
|
9889
10191
|
"PR: ",
|
|
9890
10192
|
session.prUrl
|
|
9891
10193
|
] }),
|
|
9892
|
-
session.errorMessage && /* @__PURE__ */
|
|
10194
|
+
session.errorMessage && /* @__PURE__ */ jsxs13(Text14, { color: theme.error, children: [
|
|
9893
10195
|
"Error: ",
|
|
9894
10196
|
session.errorMessage
|
|
9895
10197
|
] }),
|
|
9896
|
-
session.tokensUsed !== void 0 && /* @__PURE__ */
|
|
10198
|
+
session.tokensUsed !== void 0 && /* @__PURE__ */ jsxs13(Text14, { children: [
|
|
9897
10199
|
"Tokens: ",
|
|
9898
|
-
|
|
9899
|
-
session.tokensBudget ? ` / ${
|
|
10200
|
+
formatTokens4(session.tokensUsed),
|
|
10201
|
+
session.tokensBudget ? ` / ${formatTokens4(session.tokensBudget)}` : ""
|
|
9900
10202
|
] }),
|
|
9901
|
-
/* @__PURE__ */
|
|
10203
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
9902
10204
|
"Created: ",
|
|
9903
10205
|
new Date(session.createdAt).toLocaleString()
|
|
9904
10206
|
] }),
|
|
9905
|
-
session.finishedAt && /* @__PURE__ */
|
|
10207
|
+
session.finishedAt && /* @__PURE__ */ jsxs13(Text14, { children: [
|
|
9906
10208
|
"Finished: ",
|
|
9907
10209
|
new Date(session.finishedAt).toLocaleString()
|
|
9908
10210
|
] })
|
|
9909
10211
|
] }),
|
|
9910
|
-
/* @__PURE__ */
|
|
9911
|
-
isRunning && onCancel && /* @__PURE__ */
|
|
9912
|
-
/* @__PURE__ */
|
|
10212
|
+
/* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "row", gap: 2, children: [
|
|
10213
|
+
isRunning && onCancel && /* @__PURE__ */ jsx15(Text14, { color: theme.error, children: cancelling ? "Cancelling..." : "[C] Cancel session" }),
|
|
10214
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Esc back" })
|
|
9913
10215
|
] })
|
|
9914
10216
|
] });
|
|
9915
10217
|
}
|
|
@@ -10345,23 +10647,23 @@ async function loadLog2() {
|
|
|
10345
10647
|
}
|
|
10346
10648
|
return { version: LOG_VERSION2, days: [], sessions: [] };
|
|
10347
10649
|
}
|
|
10348
|
-
async function saveLog(
|
|
10650
|
+
async function saveLog(log2) {
|
|
10349
10651
|
await mkdir10(usageDir2(), { recursive: true });
|
|
10350
|
-
await writeFile11(usagePath2(), JSON.stringify(
|
|
10652
|
+
await writeFile11(usagePath2(), JSON.stringify(log2, null, 2), "utf8");
|
|
10351
10653
|
}
|
|
10352
|
-
function getOrCreateDay(
|
|
10353
|
-
let day =
|
|
10654
|
+
function getOrCreateDay(log2, date) {
|
|
10655
|
+
let day = log2.days.find((d) => d.date === date);
|
|
10354
10656
|
if (!day) {
|
|
10355
10657
|
day = { date, promptTokens: 0, completionTokens: 0, cachedTokens: 0, cost: 0 };
|
|
10356
|
-
|
|
10658
|
+
log2.days.push(day);
|
|
10357
10659
|
}
|
|
10358
10660
|
return day;
|
|
10359
10661
|
}
|
|
10360
|
-
function getOrCreateSession(
|
|
10361
|
-
let session =
|
|
10662
|
+
function getOrCreateSession(log2, sessionId, date) {
|
|
10663
|
+
let session = log2.sessions.find((s) => s.id === sessionId);
|
|
10362
10664
|
if (!session) {
|
|
10363
10665
|
session = { id: sessionId, date, promptTokens: 0, completionTokens: 0, cachedTokens: 0, cost: 0 };
|
|
10364
|
-
|
|
10666
|
+
log2.sessions.push(session);
|
|
10365
10667
|
}
|
|
10366
10668
|
return session;
|
|
10367
10669
|
}
|
|
@@ -10410,23 +10712,23 @@ async function fetchGatewayUsageSnapshot(lookup) {
|
|
|
10410
10712
|
}) : void 0;
|
|
10411
10713
|
return toGatewaySnapshot(match, lookup.meta);
|
|
10412
10714
|
}
|
|
10413
|
-
function pruneUsageLog(
|
|
10715
|
+
function pruneUsageLog(log2) {
|
|
10414
10716
|
const dayCutoff = cutoffDate(RETENTION.usageDayMaxAgeDays);
|
|
10415
10717
|
const sessionCutoff = cutoffDate(RETENTION.usageSessionMaxAgeDays);
|
|
10416
|
-
const days =
|
|
10417
|
-
let sessions =
|
|
10718
|
+
const days = log2.days.filter((d) => d.date >= dayCutoff);
|
|
10719
|
+
let sessions = log2.sessions.filter((s) => s.date >= sessionCutoff);
|
|
10418
10720
|
if (sessions.length > RETENTION.usageSessionMaxCount) {
|
|
10419
10721
|
sessions = sessions.sort((a, b) => b.date < a.date ? -1 : b.date > a.date ? 1 : 0).slice(0, RETENTION.usageSessionMaxCount);
|
|
10420
10722
|
}
|
|
10421
|
-
return { ...
|
|
10723
|
+
return { ...log2, days, sessions };
|
|
10422
10724
|
}
|
|
10423
10725
|
async function recordUsage(sessionId, usage, gateway) {
|
|
10424
|
-
const
|
|
10726
|
+
const log2 = pruneUsageLog(await loadLog2());
|
|
10425
10727
|
const date = today2();
|
|
10426
10728
|
const gatewaySnapshot = gateway ? await fetchGatewayUsageSnapshot(gateway).catch(() => gatewaySnapshotFromMeta(gateway.meta)) : void 0;
|
|
10427
10729
|
const cost = calculateCost(usage.prompt_tokens, usage.completion_tokens, usage.prompt_tokens_details?.cached_tokens ?? 0);
|
|
10428
10730
|
const totalCost = gatewaySnapshot?.cost ?? cost.total;
|
|
10429
|
-
const day = getOrCreateDay(
|
|
10731
|
+
const day = getOrCreateDay(log2, date);
|
|
10430
10732
|
day.promptTokens += usage.prompt_tokens;
|
|
10431
10733
|
day.completionTokens += usage.completion_tokens;
|
|
10432
10734
|
day.cachedTokens += usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
@@ -10436,7 +10738,7 @@ async function recordUsage(sessionId, usage, gateway) {
|
|
|
10436
10738
|
day.gatewayCachedRequests = (day.gatewayCachedRequests ?? 0) + (gatewaySnapshot.cached ? 1 : 0);
|
|
10437
10739
|
day.gatewayCost = (day.gatewayCost ?? 0) + (gatewaySnapshot.cost ?? 0);
|
|
10438
10740
|
}
|
|
10439
|
-
const session = getOrCreateSession(
|
|
10741
|
+
const session = getOrCreateSession(log2, sessionId, date);
|
|
10440
10742
|
session.promptTokens += usage.prompt_tokens;
|
|
10441
10743
|
session.completionTokens += usage.completion_tokens;
|
|
10442
10744
|
session.cachedTokens += usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
@@ -10447,14 +10749,14 @@ async function recordUsage(sessionId, usage, gateway) {
|
|
|
10447
10749
|
session.gatewayCost = (session.gatewayCost ?? 0) + (gatewaySnapshot.cost ?? 0);
|
|
10448
10750
|
session.gatewayLogs = [...session.gatewayLogs ?? [], gatewaySnapshot].slice(-100);
|
|
10449
10751
|
}
|
|
10450
|
-
await saveLog(
|
|
10752
|
+
await saveLog(log2);
|
|
10451
10753
|
}
|
|
10452
10754
|
async function getCostReport(sessionId) {
|
|
10453
|
-
const
|
|
10755
|
+
const log2 = pruneUsageLog(await loadLog2());
|
|
10454
10756
|
const date = today2();
|
|
10455
10757
|
const currentMonth = date.slice(0, 7);
|
|
10456
|
-
const session = sessionId ?
|
|
10457
|
-
const todayUsage =
|
|
10758
|
+
const session = sessionId ? log2.sessions.find((s) => s.id === sessionId) ?? { date, promptTokens: 0, completionTokens: 0, cachedTokens: 0, cost: 0 } : { date, promptTokens: 0, completionTokens: 0, cachedTokens: 0, cost: 0 };
|
|
10759
|
+
const todayUsage = log2.days.find((d) => d.date === date) ?? { date, promptTokens: 0, completionTokens: 0, cachedTokens: 0, cost: 0 };
|
|
10458
10760
|
const monthUsage = {
|
|
10459
10761
|
date: currentMonth,
|
|
10460
10762
|
promptTokens: 0,
|
|
@@ -10462,7 +10764,7 @@ async function getCostReport(sessionId) {
|
|
|
10462
10764
|
cachedTokens: 0,
|
|
10463
10765
|
cost: 0
|
|
10464
10766
|
};
|
|
10465
|
-
for (const d of
|
|
10767
|
+
for (const d of log2.days) {
|
|
10466
10768
|
if (d.date.startsWith(currentMonth)) {
|
|
10467
10769
|
monthUsage.promptTokens += d.promptTokens;
|
|
10468
10770
|
monthUsage.completionTokens += d.completionTokens;
|
|
@@ -10480,7 +10782,7 @@ async function getCostReport(sessionId) {
|
|
|
10480
10782
|
cachedTokens: 0,
|
|
10481
10783
|
cost: 0
|
|
10482
10784
|
};
|
|
10483
|
-
for (const d of
|
|
10785
|
+
for (const d of log2.days) {
|
|
10484
10786
|
allTime.promptTokens += d.promptTokens;
|
|
10485
10787
|
allTime.completionTokens += d.completionTokens;
|
|
10486
10788
|
allTime.cachedTokens += d.cachedTokens;
|
|
@@ -12148,9 +12450,9 @@ var init_save = __esm({
|
|
|
12148
12450
|
|
|
12149
12451
|
// src/ui/command-wizard.tsx
|
|
12150
12452
|
import { useState as useState8 } from "react";
|
|
12151
|
-
import { Box as
|
|
12453
|
+
import { Box as Box14, Text as Text15, useInput as useInput4, useWindowSize as useWindowSize2 } from "ink";
|
|
12152
12454
|
import SelectInput6 from "ink-select-input";
|
|
12153
|
-
import { Fragment as Fragment2, jsx as
|
|
12455
|
+
import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
12154
12456
|
function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onSave }) {
|
|
12155
12457
|
const theme = useTheme();
|
|
12156
12458
|
const [step, setStep] = useState8("name");
|
|
@@ -12274,8 +12576,8 @@ ${template}`;
|
|
|
12274
12576
|
const renderStep = () => {
|
|
12275
12577
|
switch (step) {
|
|
12276
12578
|
case "name":
|
|
12277
|
-
return /* @__PURE__ */
|
|
12278
|
-
/* @__PURE__ */
|
|
12579
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
12580
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
12279
12581
|
mode === "create" ? "Create" : "Edit",
|
|
12280
12582
|
" custom command \u2014 Name (",
|
|
12281
12583
|
stepIndex,
|
|
@@ -12283,8 +12585,8 @@ ${template}`;
|
|
|
12283
12585
|
totalSteps,
|
|
12284
12586
|
")"
|
|
12285
12587
|
] }),
|
|
12286
|
-
error && /* @__PURE__ */
|
|
12287
|
-
/* @__PURE__ */
|
|
12588
|
+
error && /* @__PURE__ */ jsx16(Text15, { color: theme.error, children: error }),
|
|
12589
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
12288
12590
|
CustomTextInput,
|
|
12289
12591
|
{
|
|
12290
12592
|
value: name,
|
|
@@ -12293,11 +12595,11 @@ ${template}`;
|
|
|
12293
12595
|
focus: true
|
|
12294
12596
|
}
|
|
12295
12597
|
) }),
|
|
12296
|
-
/* @__PURE__ */
|
|
12598
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "letters, numbers, _ - / only; must start with a letter" })
|
|
12297
12599
|
] });
|
|
12298
12600
|
case "description":
|
|
12299
|
-
return /* @__PURE__ */
|
|
12300
|
-
/* @__PURE__ */
|
|
12601
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
12602
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
12301
12603
|
mode === "create" ? "Create" : "Edit",
|
|
12302
12604
|
" custom command \u2014 Description (",
|
|
12303
12605
|
stepIndex,
|
|
@@ -12305,7 +12607,7 @@ ${template}`;
|
|
|
12305
12607
|
totalSteps,
|
|
12306
12608
|
")"
|
|
12307
12609
|
] }),
|
|
12308
|
-
/* @__PURE__ */
|
|
12610
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
12309
12611
|
CustomTextInput,
|
|
12310
12612
|
{
|
|
12311
12613
|
value: description,
|
|
@@ -12314,49 +12616,49 @@ ${template}`;
|
|
|
12314
12616
|
focus: true
|
|
12315
12617
|
}
|
|
12316
12618
|
) }),
|
|
12317
|
-
/* @__PURE__ */
|
|
12619
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Press Enter to skip" })
|
|
12318
12620
|
] });
|
|
12319
12621
|
case "template": {
|
|
12320
|
-
const guide = /* @__PURE__ */
|
|
12321
|
-
/* @__PURE__ */
|
|
12322
|
-
/* @__PURE__ */
|
|
12323
|
-
/* @__PURE__ */
|
|
12622
|
+
const guide = /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", paddingLeft: 1, children: [
|
|
12623
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "What is this?" }),
|
|
12624
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "A prompt template \u2014 instructions to the AI." }),
|
|
12625
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
12324
12626
|
"When you type /",
|
|
12325
12627
|
name || "yourcommand",
|
|
12326
12628
|
" later, this gets sent to the model."
|
|
12327
12629
|
] }),
|
|
12328
|
-
/* @__PURE__ */
|
|
12329
|
-
/* @__PURE__ */
|
|
12330
|
-
/* @__PURE__ */
|
|
12630
|
+
/* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
|
|
12631
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Variables" }),
|
|
12632
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
12331
12633
|
" ",
|
|
12332
12634
|
"$1, $2 ... \u2192 arguments you type"
|
|
12333
12635
|
] }),
|
|
12334
|
-
/* @__PURE__ */
|
|
12636
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
12335
12637
|
" ",
|
|
12336
12638
|
"$ARGUMENTS \u2192 everything after the command"
|
|
12337
12639
|
] })
|
|
12338
12640
|
] }),
|
|
12339
|
-
/* @__PURE__ */
|
|
12340
|
-
/* @__PURE__ */
|
|
12341
|
-
/* @__PURE__ */
|
|
12641
|
+
/* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
|
|
12642
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Dynamic inlines" }),
|
|
12643
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
12342
12644
|
" ",
|
|
12343
12645
|
"!`git diff` \u2192 shell output inlined"
|
|
12344
12646
|
] }),
|
|
12345
|
-
/* @__PURE__ */
|
|
12647
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
12346
12648
|
" ",
|
|
12347
12649
|
"@README.md \u2192 file contents inlined"
|
|
12348
12650
|
] })
|
|
12349
12651
|
] }),
|
|
12350
|
-
/* @__PURE__ */
|
|
12351
|
-
/* @__PURE__ */
|
|
12352
|
-
/* @__PURE__ */
|
|
12353
|
-
/* @__PURE__ */
|
|
12354
|
-
/* @__PURE__ */
|
|
12652
|
+
/* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
|
|
12653
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Example" }),
|
|
12654
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Review this PR diff:" }),
|
|
12655
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "!`git diff main...HEAD`" }),
|
|
12656
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Focus on: $1" })
|
|
12355
12657
|
] })
|
|
12356
12658
|
] });
|
|
12357
|
-
const inputArea = /* @__PURE__ */
|
|
12358
|
-
error && /* @__PURE__ */
|
|
12359
|
-
/* @__PURE__ */
|
|
12659
|
+
const inputArea = /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", flexGrow: 1, children: [
|
|
12660
|
+
error && /* @__PURE__ */ jsx16(Text15, { color: theme.error, children: error }),
|
|
12661
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
12360
12662
|
CustomTextInput,
|
|
12361
12663
|
{
|
|
12362
12664
|
value: template,
|
|
@@ -12366,13 +12668,13 @@ ${template}`;
|
|
|
12366
12668
|
enablePaste: true
|
|
12367
12669
|
}
|
|
12368
12670
|
) }),
|
|
12369
|
-
columns < 100 && /* @__PURE__ */
|
|
12370
|
-
/* @__PURE__ */
|
|
12371
|
-
/* @__PURE__ */
|
|
12671
|
+
columns < 100 && /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
12672
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Paste multi-line templates with Ctrl+V." }),
|
|
12673
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Variables: $1 $2 ... $ARGUMENTS Shell: !`cmd` File: @path" })
|
|
12372
12674
|
] })
|
|
12373
12675
|
] });
|
|
12374
|
-
return /* @__PURE__ */
|
|
12375
|
-
/* @__PURE__ */
|
|
12676
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
12677
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
12376
12678
|
mode === "create" ? "Create" : "Edit",
|
|
12377
12679
|
" custom command \u2014 Template (",
|
|
12378
12680
|
stepIndex,
|
|
@@ -12380,10 +12682,10 @@ ${template}`;
|
|
|
12380
12682
|
totalSteps,
|
|
12381
12683
|
")"
|
|
12382
12684
|
] }),
|
|
12383
|
-
columns >= 100 ? /* @__PURE__ */
|
|
12384
|
-
/* @__PURE__ */
|
|
12385
|
-
/* @__PURE__ */
|
|
12386
|
-
] }) : /* @__PURE__ */
|
|
12685
|
+
columns >= 100 ? /* @__PURE__ */ jsxs14(Box14, { flexDirection: "row", marginTop: 1, children: [
|
|
12686
|
+
/* @__PURE__ */ jsx16(Box14, { flexDirection: "column", width: "50%", children: inputArea }),
|
|
12687
|
+
/* @__PURE__ */ jsx16(Box14, { flexDirection: "column", width: "50%", children: guide })
|
|
12688
|
+
] }) : /* @__PURE__ */ jsx16(Box14, { flexDirection: "column", marginTop: 1, children: inputArea })
|
|
12387
12689
|
] });
|
|
12388
12690
|
}
|
|
12389
12691
|
case "advanced": {
|
|
@@ -12392,8 +12694,8 @@ ${template}`;
|
|
|
12392
12694
|
{ label: "Skip", value: "skip", key: "skip" },
|
|
12393
12695
|
{ label: "\u2190 Cancel", value: "cancel", key: "cancel" }
|
|
12394
12696
|
];
|
|
12395
|
-
return /* @__PURE__ */
|
|
12396
|
-
/* @__PURE__ */
|
|
12697
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
12698
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
12397
12699
|
mode === "create" ? "Create" : "Edit",
|
|
12398
12700
|
" custom command \u2014 Options (",
|
|
12399
12701
|
stepIndex,
|
|
@@ -12401,7 +12703,7 @@ ${template}`;
|
|
|
12401
12703
|
totalSteps,
|
|
12402
12704
|
")"
|
|
12403
12705
|
] }),
|
|
12404
|
-
/* @__PURE__ */
|
|
12706
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
12405
12707
|
SelectInput6,
|
|
12406
12708
|
{
|
|
12407
12709
|
items,
|
|
@@ -12421,16 +12723,16 @@ ${template}`;
|
|
|
12421
12723
|
{ label: cmdMode === "auto" ? "auto \xB7 current" : "auto", value: "auto", key: "auto" },
|
|
12422
12724
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
12423
12725
|
];
|
|
12424
|
-
return /* @__PURE__ */
|
|
12425
|
-
/* @__PURE__ */
|
|
12726
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
12727
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
12426
12728
|
"Mode override (",
|
|
12427
12729
|
stepIndex,
|
|
12428
12730
|
"/",
|
|
12429
12731
|
totalSteps,
|
|
12430
12732
|
")"
|
|
12431
12733
|
] }),
|
|
12432
|
-
/* @__PURE__ */
|
|
12433
|
-
/* @__PURE__ */
|
|
12734
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Saved to file but not yet enforced at runtime" }),
|
|
12735
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
12434
12736
|
SelectInput6,
|
|
12435
12737
|
{
|
|
12436
12738
|
items,
|
|
@@ -12450,15 +12752,15 @@ ${template}`;
|
|
|
12450
12752
|
{ label: cmdEffort === "high" ? "high \xB7 current" : "high", value: "high", key: "high" },
|
|
12451
12753
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
12452
12754
|
];
|
|
12453
|
-
return /* @__PURE__ */
|
|
12454
|
-
/* @__PURE__ */
|
|
12755
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
12756
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
12455
12757
|
"Reasoning effort (",
|
|
12456
12758
|
stepIndex,
|
|
12457
12759
|
"/",
|
|
12458
12760
|
totalSteps,
|
|
12459
12761
|
")"
|
|
12460
12762
|
] }),
|
|
12461
|
-
/* @__PURE__ */
|
|
12763
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
12462
12764
|
SelectInput6,
|
|
12463
12765
|
{
|
|
12464
12766
|
items,
|
|
@@ -12471,15 +12773,15 @@ ${template}`;
|
|
|
12471
12773
|
] });
|
|
12472
12774
|
}
|
|
12473
12775
|
case "model":
|
|
12474
|
-
return /* @__PURE__ */
|
|
12475
|
-
/* @__PURE__ */
|
|
12776
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
12777
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
12476
12778
|
"Model override (",
|
|
12477
12779
|
stepIndex,
|
|
12478
12780
|
"/",
|
|
12479
12781
|
totalSteps,
|
|
12480
12782
|
")"
|
|
12481
12783
|
] }),
|
|
12482
|
-
/* @__PURE__ */
|
|
12784
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
12483
12785
|
CustomTextInput,
|
|
12484
12786
|
{
|
|
12485
12787
|
value: cmdModel ?? "",
|
|
@@ -12488,7 +12790,7 @@ ${template}`;
|
|
|
12488
12790
|
focus: true
|
|
12489
12791
|
}
|
|
12490
12792
|
) }),
|
|
12491
|
-
/* @__PURE__ */
|
|
12793
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Press Enter to skip" })
|
|
12492
12794
|
] });
|
|
12493
12795
|
case "location": {
|
|
12494
12796
|
const items = [
|
|
@@ -12496,15 +12798,15 @@ ${template}`;
|
|
|
12496
12798
|
{ label: source === "global" ? "Global \xB7 current" : "Global", value: "global", key: "global" },
|
|
12497
12799
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
12498
12800
|
];
|
|
12499
|
-
return /* @__PURE__ */
|
|
12500
|
-
/* @__PURE__ */
|
|
12801
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
12802
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
12501
12803
|
"Save location (",
|
|
12502
12804
|
stepIndex,
|
|
12503
12805
|
"/",
|
|
12504
12806
|
totalSteps,
|
|
12505
12807
|
")"
|
|
12506
12808
|
] }),
|
|
12507
|
-
/* @__PURE__ */
|
|
12809
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
12508
12810
|
SelectInput6,
|
|
12509
12811
|
{
|
|
12510
12812
|
items,
|
|
@@ -12514,7 +12816,7 @@ ${template}`;
|
|
|
12514
12816
|
}
|
|
12515
12817
|
}
|
|
12516
12818
|
) }),
|
|
12517
|
-
/* @__PURE__ */
|
|
12819
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Project: .kimiflare/commands/ Global: ~/.config/kimiflare/commands/" })
|
|
12518
12820
|
] });
|
|
12519
12821
|
}
|
|
12520
12822
|
case "confirm": {
|
|
@@ -12522,8 +12824,8 @@ ${template}`;
|
|
|
12522
12824
|
{ label: "Save", value: "save", key: "save" },
|
|
12523
12825
|
{ label: "Cancel", value: "cancel", key: "cancel" }
|
|
12524
12826
|
];
|
|
12525
|
-
return /* @__PURE__ */
|
|
12526
|
-
/* @__PURE__ */
|
|
12827
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
12828
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
12527
12829
|
mode === "create" ? "Create" : "Edit",
|
|
12528
12830
|
" custom command \u2014 Confirm (",
|
|
12529
12831
|
stepIndex,
|
|
@@ -12531,13 +12833,13 @@ ${template}`;
|
|
|
12531
12833
|
totalSteps,
|
|
12532
12834
|
")"
|
|
12533
12835
|
] }),
|
|
12534
|
-
/* @__PURE__ */
|
|
12836
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
12535
12837
|
source === "project" ? ".kimiflare/commands/" : "~/.config/kimiflare/commands/",
|
|
12536
12838
|
name,
|
|
12537
12839
|
".md"
|
|
12538
12840
|
] }),
|
|
12539
|
-
/* @__PURE__ */
|
|
12540
|
-
/* @__PURE__ */
|
|
12841
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, flexDirection: "column", children: previewContent().split("\n").map((line, i) => /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: line || " " }, i)) }),
|
|
12842
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
12541
12843
|
SelectInput6,
|
|
12542
12844
|
{
|
|
12543
12845
|
items,
|
|
@@ -12548,7 +12850,7 @@ ${template}`;
|
|
|
12548
12850
|
}
|
|
12549
12851
|
}
|
|
12550
12852
|
};
|
|
12551
|
-
return /* @__PURE__ */
|
|
12853
|
+
return /* @__PURE__ */ jsx16(Box14, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: renderStep() });
|
|
12552
12854
|
}
|
|
12553
12855
|
var NAME_RE;
|
|
12554
12856
|
var init_command_wizard = __esm({
|
|
@@ -12993,9 +13295,9 @@ var init_context_generator = __esm({
|
|
|
12993
13295
|
});
|
|
12994
13296
|
|
|
12995
13297
|
// src/ui/command-picker.tsx
|
|
12996
|
-
import { Box as
|
|
13298
|
+
import { Box as Box15, Text as Text16 } from "ink";
|
|
12997
13299
|
import SelectInput7 from "ink-select-input";
|
|
12998
|
-
import { jsx as
|
|
13300
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
12999
13301
|
function CommandPicker({ commands, title, onPick }) {
|
|
13000
13302
|
const theme = useTheme();
|
|
13001
13303
|
const items = commands.map((cmd) => ({
|
|
@@ -13004,10 +13306,10 @@ function CommandPicker({ commands, title, onPick }) {
|
|
|
13004
13306
|
key: cmd.name
|
|
13005
13307
|
}));
|
|
13006
13308
|
items.push({ label: "\u2190 Cancel", value: null, key: "__cancel__" });
|
|
13007
|
-
return /* @__PURE__ */
|
|
13008
|
-
/* @__PURE__ */
|
|
13009
|
-
/* @__PURE__ */
|
|
13010
|
-
/* @__PURE__ */
|
|
13309
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13310
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.accent, bold: true, children: title }),
|
|
13311
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
|
|
13312
|
+
/* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(
|
|
13011
13313
|
SelectInput7,
|
|
13012
13314
|
{
|
|
13013
13315
|
items,
|
|
@@ -13030,8 +13332,8 @@ var init_command_picker = __esm({
|
|
|
13030
13332
|
});
|
|
13031
13333
|
|
|
13032
13334
|
// src/ui/command-list.tsx
|
|
13033
|
-
import { Box as
|
|
13034
|
-
import { jsx as
|
|
13335
|
+
import { Box as Box16, Text as Text17, useInput as useInput5 } from "ink";
|
|
13336
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
13035
13337
|
function CommandList({ commands, onDone }) {
|
|
13036
13338
|
const theme = useTheme();
|
|
13037
13339
|
useInput5((_input, key) => {
|
|
@@ -13039,55 +13341,55 @@ function CommandList({ commands, onDone }) {
|
|
|
13039
13341
|
onDone();
|
|
13040
13342
|
}
|
|
13041
13343
|
});
|
|
13042
|
-
return /* @__PURE__ */
|
|
13043
|
-
/* @__PURE__ */
|
|
13044
|
-
/* @__PURE__ */
|
|
13045
|
-
/* @__PURE__ */
|
|
13046
|
-
commands.length === 0 && /* @__PURE__ */
|
|
13047
|
-
commands.map((cmd) => /* @__PURE__ */
|
|
13048
|
-
/* @__PURE__ */
|
|
13344
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13345
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Custom commands" }),
|
|
13346
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Esc to close." }),
|
|
13347
|
+
/* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
|
|
13348
|
+
commands.length === 0 && /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No custom commands found." }),
|
|
13349
|
+
commands.map((cmd) => /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", marginBottom: 1, children: [
|
|
13350
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
|
|
13049
13351
|
"/",
|
|
13050
13352
|
cmd.name
|
|
13051
13353
|
] }),
|
|
13052
|
-
/* @__PURE__ */
|
|
13354
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
13053
13355
|
" ",
|
|
13054
13356
|
"source: ",
|
|
13055
13357
|
cmd.source
|
|
13056
13358
|
] }),
|
|
13057
|
-
/* @__PURE__ */
|
|
13359
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
13058
13360
|
" ",
|
|
13059
13361
|
"path: ",
|
|
13060
13362
|
cmd.filepath
|
|
13061
13363
|
] }),
|
|
13062
|
-
cmd.description && /* @__PURE__ */
|
|
13364
|
+
cmd.description && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
13063
13365
|
" ",
|
|
13064
13366
|
"desc: ",
|
|
13065
13367
|
cmd.description
|
|
13066
13368
|
] }),
|
|
13067
|
-
cmd.mode && /* @__PURE__ */
|
|
13369
|
+
cmd.mode && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
13068
13370
|
" ",
|
|
13069
13371
|
"mode: ",
|
|
13070
13372
|
cmd.mode
|
|
13071
13373
|
] }),
|
|
13072
|
-
cmd.effort && /* @__PURE__ */
|
|
13374
|
+
cmd.effort && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
13073
13375
|
" ",
|
|
13074
13376
|
"effort: ",
|
|
13075
13377
|
cmd.effort
|
|
13076
13378
|
] }),
|
|
13077
|
-
cmd.model && /* @__PURE__ */
|
|
13379
|
+
cmd.model && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
13078
13380
|
" ",
|
|
13079
13381
|
"model: ",
|
|
13080
13382
|
cmd.model
|
|
13081
13383
|
] }),
|
|
13082
|
-
/* @__PURE__ */
|
|
13384
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
13083
13385
|
" ",
|
|
13084
13386
|
"template:"
|
|
13085
13387
|
] }),
|
|
13086
|
-
cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */
|
|
13388
|
+
cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
13087
13389
|
" ",
|
|
13088
13390
|
line || " "
|
|
13089
13391
|
] }, i)),
|
|
13090
|
-
cmd.template.split("\n").length > 5 && /* @__PURE__ */
|
|
13392
|
+
cmd.template.split("\n").length > 5 && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
13091
13393
|
" ",
|
|
13092
13394
|
"..."
|
|
13093
13395
|
] })
|
|
@@ -13104,10 +13406,10 @@ var init_command_list = __esm({
|
|
|
13104
13406
|
|
|
13105
13407
|
// src/ui/lsp-wizard.tsx
|
|
13106
13408
|
import { useState as useState9 } from "react";
|
|
13107
|
-
import { Box as
|
|
13409
|
+
import { Box as Box17, Text as Text18 } from "ink";
|
|
13108
13410
|
import SelectInput8 from "ink-select-input";
|
|
13109
13411
|
import { spawn as spawn3 } from "child_process";
|
|
13110
|
-
import { jsx as
|
|
13412
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
13111
13413
|
function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
13112
13414
|
const theme = useTheme();
|
|
13113
13415
|
const [page, setPage] = useState9("main");
|
|
@@ -13218,10 +13520,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13218
13520
|
{ label: "(close)", value: "__close__", key: "__close__" }
|
|
13219
13521
|
];
|
|
13220
13522
|
if (page === "main") {
|
|
13221
|
-
return /* @__PURE__ */
|
|
13222
|
-
/* @__PURE__ */
|
|
13223
|
-
/* @__PURE__ */
|
|
13224
|
-
/* @__PURE__ */
|
|
13523
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13524
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "LSP Servers" }),
|
|
13525
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
|
|
13526
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
13225
13527
|
SelectInput8,
|
|
13226
13528
|
{
|
|
13227
13529
|
items: mainItems,
|
|
@@ -13249,10 +13551,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13249
13551
|
}),
|
|
13250
13552
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
13251
13553
|
];
|
|
13252
|
-
return /* @__PURE__ */
|
|
13253
|
-
/* @__PURE__ */
|
|
13254
|
-
/* @__PURE__ */
|
|
13255
|
-
/* @__PURE__ */
|
|
13554
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13555
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Add LSP Server" }),
|
|
13556
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a language server to configure." }),
|
|
13557
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
13256
13558
|
SelectInput8,
|
|
13257
13559
|
{
|
|
13258
13560
|
items,
|
|
@@ -13280,18 +13582,18 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13280
13582
|
{ label: isSuccess ? "Save to config \u2713" : "Save anyway", value: "save", key: "save" },
|
|
13281
13583
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
13282
13584
|
];
|
|
13283
|
-
return /* @__PURE__ */
|
|
13284
|
-
/* @__PURE__ */
|
|
13585
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13586
|
+
/* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
|
|
13285
13587
|
"Install ",
|
|
13286
13588
|
selectedPreset.name
|
|
13287
13589
|
] }),
|
|
13288
|
-
/* @__PURE__ */
|
|
13289
|
-
/* @__PURE__ */
|
|
13290
|
-
/* @__PURE__ */
|
|
13291
|
-
/* @__PURE__ */
|
|
13590
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: selectedPreset.installHint }),
|
|
13591
|
+
/* @__PURE__ */ jsxs17(Box17, { marginTop: 1, flexDirection: "column", children: [
|
|
13592
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Command:" }),
|
|
13593
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: selectedPreset.installCommand || "(none required)" })
|
|
13292
13594
|
] }),
|
|
13293
|
-
installState.output && /* @__PURE__ */
|
|
13294
|
-
/* @__PURE__ */
|
|
13595
|
+
installState.output && /* @__PURE__ */ jsx19(Box17, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx19(Text18, { color: isSuccess ? theme.accent : theme.error, children: installState.output.slice(-500) }) }),
|
|
13596
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
13295
13597
|
SelectInput8,
|
|
13296
13598
|
{
|
|
13297
13599
|
items,
|
|
@@ -13309,16 +13611,16 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13309
13611
|
}
|
|
13310
13612
|
}
|
|
13311
13613
|
) }),
|
|
13312
|
-
isSuccess && /* @__PURE__ */
|
|
13614
|
+
isSuccess && /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "Server saved. Run /lsp reload to start it." }) })
|
|
13313
13615
|
] });
|
|
13314
13616
|
}
|
|
13315
13617
|
if (page === "custom-name") {
|
|
13316
|
-
return /* @__PURE__ */
|
|
13317
|
-
/* @__PURE__ */
|
|
13318
|
-
/* @__PURE__ */
|
|
13319
|
-
/* @__PURE__ */
|
|
13320
|
-
/* @__PURE__ */
|
|
13321
|
-
/* @__PURE__ */
|
|
13618
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13619
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Name" }),
|
|
13620
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Enter a name for this server (e.g., my-server)." }),
|
|
13621
|
+
/* @__PURE__ */ jsxs17(Box17, { marginTop: 1, children: [
|
|
13622
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "\u203A " }),
|
|
13623
|
+
/* @__PURE__ */ jsx19(
|
|
13322
13624
|
CustomTextInput,
|
|
13323
13625
|
{
|
|
13324
13626
|
value: customName,
|
|
@@ -13332,7 +13634,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13332
13634
|
}
|
|
13333
13635
|
)
|
|
13334
13636
|
] }),
|
|
13335
|
-
/* @__PURE__ */
|
|
13637
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
13336
13638
|
SelectInput8,
|
|
13337
13639
|
{
|
|
13338
13640
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
@@ -13342,12 +13644,12 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13342
13644
|
] });
|
|
13343
13645
|
}
|
|
13344
13646
|
if (page === "custom-command") {
|
|
13345
|
-
return /* @__PURE__ */
|
|
13346
|
-
/* @__PURE__ */
|
|
13347
|
-
/* @__PURE__ */
|
|
13348
|
-
/* @__PURE__ */
|
|
13349
|
-
/* @__PURE__ */
|
|
13350
|
-
/* @__PURE__ */
|
|
13647
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13648
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Command" }),
|
|
13649
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Enter the command to start the server (space-separated)." }),
|
|
13650
|
+
/* @__PURE__ */ jsxs17(Box17, { marginTop: 1, children: [
|
|
13651
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "\u203A " }),
|
|
13652
|
+
/* @__PURE__ */ jsx19(
|
|
13351
13653
|
CustomTextInput,
|
|
13352
13654
|
{
|
|
13353
13655
|
value: customCommand,
|
|
@@ -13361,7 +13663,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13361
13663
|
}
|
|
13362
13664
|
)
|
|
13363
13665
|
] }),
|
|
13364
|
-
/* @__PURE__ */
|
|
13666
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
13365
13667
|
SelectInput8,
|
|
13366
13668
|
{
|
|
13367
13669
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
@@ -13385,10 +13687,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13385
13687
|
},
|
|
13386
13688
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
13387
13689
|
];
|
|
13388
|
-
return /* @__PURE__ */
|
|
13389
|
-
/* @__PURE__ */
|
|
13390
|
-
/* @__PURE__ */
|
|
13391
|
-
/* @__PURE__ */
|
|
13690
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13691
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Save LSP Config" }),
|
|
13692
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Where should this server configuration be saved?" }),
|
|
13693
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
13392
13694
|
SelectInput8,
|
|
13393
13695
|
{
|
|
13394
13696
|
items,
|
|
@@ -13407,10 +13709,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13407
13709
|
if (page === "edit") {
|
|
13408
13710
|
const keys = Object.keys(servers);
|
|
13409
13711
|
if (keys.length === 0) {
|
|
13410
|
-
return /* @__PURE__ */
|
|
13411
|
-
/* @__PURE__ */
|
|
13412
|
-
/* @__PURE__ */
|
|
13413
|
-
/* @__PURE__ */
|
|
13712
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13713
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
|
|
13714
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "No servers configured." }),
|
|
13715
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
13414
13716
|
SelectInput8,
|
|
13415
13717
|
{
|
|
13416
13718
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
@@ -13431,10 +13733,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13431
13733
|
}),
|
|
13432
13734
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
13433
13735
|
];
|
|
13434
|
-
return /* @__PURE__ */
|
|
13435
|
-
/* @__PURE__ */
|
|
13436
|
-
/* @__PURE__ */
|
|
13437
|
-
/* @__PURE__ */
|
|
13736
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13737
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
|
|
13738
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a server to toggle enabled/disabled." }),
|
|
13739
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
13438
13740
|
SelectInput8,
|
|
13439
13741
|
{
|
|
13440
13742
|
items,
|
|
@@ -13452,10 +13754,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13452
13754
|
if (page === "delete") {
|
|
13453
13755
|
const keys = Object.keys(servers);
|
|
13454
13756
|
if (keys.length === 0) {
|
|
13455
|
-
return /* @__PURE__ */
|
|
13456
|
-
/* @__PURE__ */
|
|
13457
|
-
/* @__PURE__ */
|
|
13458
|
-
/* @__PURE__ */
|
|
13757
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13758
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
|
|
13759
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "No servers configured." }),
|
|
13760
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
13459
13761
|
SelectInput8,
|
|
13460
13762
|
{
|
|
13461
13763
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
@@ -13472,10 +13774,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13472
13774
|
})),
|
|
13473
13775
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
13474
13776
|
];
|
|
13475
|
-
return /* @__PURE__ */
|
|
13476
|
-
/* @__PURE__ */
|
|
13477
|
-
/* @__PURE__ */
|
|
13478
|
-
/* @__PURE__ */
|
|
13777
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13778
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
|
|
13779
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a server to remove from config." }),
|
|
13780
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
13479
13781
|
SelectInput8,
|
|
13480
13782
|
{
|
|
13481
13783
|
items,
|
|
@@ -13492,14 +13794,14 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
13492
13794
|
}
|
|
13493
13795
|
if (page === "list") {
|
|
13494
13796
|
const keys = Object.keys(servers);
|
|
13495
|
-
return /* @__PURE__ */
|
|
13496
|
-
/* @__PURE__ */
|
|
13497
|
-
keys.length === 0 ? /* @__PURE__ */
|
|
13797
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
13798
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Configured LSP Servers" }),
|
|
13799
|
+
keys.length === 0 ? /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "No servers configured." }) : /* @__PURE__ */ jsx19(Box17, { marginTop: 1, flexDirection: "column", children: keys.map((k) => {
|
|
13498
13800
|
const s = servers[k];
|
|
13499
13801
|
const status = s.enabled !== false ? "enabled" : "disabled";
|
|
13500
|
-
return /* @__PURE__ */
|
|
13802
|
+
return /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: ` ${k.padEnd(16)} ${status} ${s.command.join(" ")}` }, k);
|
|
13501
13803
|
}) }),
|
|
13502
|
-
/* @__PURE__ */
|
|
13804
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
13503
13805
|
SelectInput8,
|
|
13504
13806
|
{
|
|
13505
13807
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
@@ -13626,9 +13928,9 @@ var init_lsp_wizard = __esm({
|
|
|
13626
13928
|
});
|
|
13627
13929
|
|
|
13628
13930
|
// src/ui/theme-picker.tsx
|
|
13629
|
-
import { Box as
|
|
13931
|
+
import { Box as Box18, Text as Text19 } from "ink";
|
|
13630
13932
|
import SelectInput9 from "ink-select-input";
|
|
13631
|
-
import { jsx as
|
|
13933
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
13632
13934
|
function PaletteSwatches({ palette }) {
|
|
13633
13935
|
const colors = [
|
|
13634
13936
|
palette.primary,
|
|
@@ -13636,7 +13938,7 @@ function PaletteSwatches({ palette }) {
|
|
|
13636
13938
|
palette.success,
|
|
13637
13939
|
palette.error
|
|
13638
13940
|
];
|
|
13639
|
-
return /* @__PURE__ */
|
|
13941
|
+
return /* @__PURE__ */ jsx20(Box18, { children: colors.map((c, i) => /* @__PURE__ */ jsx20(Text19, { color: c, children: "\u2588" }, i)) });
|
|
13640
13942
|
}
|
|
13641
13943
|
function ThemePicker({ themes, onPick }) {
|
|
13642
13944
|
const current = useTheme();
|
|
@@ -13644,9 +13946,9 @@ function ThemePicker({ themes, onPick }) {
|
|
|
13644
13946
|
...themes.map((t) => ({ label: t.label, value: t.name })),
|
|
13645
13947
|
{ label: "< Back", value: "__back__" }
|
|
13646
13948
|
];
|
|
13647
|
-
return /* @__PURE__ */
|
|
13648
|
-
/* @__PURE__ */
|
|
13649
|
-
/* @__PURE__ */
|
|
13949
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", borderStyle: "round", borderColor: current.accent, paddingX: 1, children: [
|
|
13950
|
+
/* @__PURE__ */ jsx20(Text19, { color: current.accent, bold: true, children: "Pick a theme (restart to apply)" }),
|
|
13951
|
+
/* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
|
|
13650
13952
|
SelectInput9,
|
|
13651
13953
|
{
|
|
13652
13954
|
items,
|
|
@@ -13661,9 +13963,9 @@ function ThemePicker({ themes, onPick }) {
|
|
|
13661
13963
|
itemComponent: ({ label, isSelected }) => {
|
|
13662
13964
|
const t = themes.find((x) => x.label === label);
|
|
13663
13965
|
const color = t?.accent ?? current.accent;
|
|
13664
|
-
return /* @__PURE__ */
|
|
13665
|
-
/* @__PURE__ */
|
|
13666
|
-
t && /* @__PURE__ */
|
|
13966
|
+
return /* @__PURE__ */ jsxs18(Box18, { children: [
|
|
13967
|
+
/* @__PURE__ */ jsx20(Text19, { color, bold: isSelected, dimColor: !isSelected, children: label }),
|
|
13968
|
+
t && /* @__PURE__ */ jsx20(Box18, { marginLeft: 1, children: /* @__PURE__ */ jsx20(PaletteSwatches, { palette: t.palette }) })
|
|
13667
13969
|
] });
|
|
13668
13970
|
}
|
|
13669
13971
|
}
|
|
@@ -14850,8 +15152,8 @@ var init_lsp_nudge = __esm({
|
|
|
14850
15152
|
});
|
|
14851
15153
|
|
|
14852
15154
|
// src/ui/file-picker.tsx
|
|
14853
|
-
import { Box as
|
|
14854
|
-
import { jsx as
|
|
15155
|
+
import { Box as Box19, Text as Text20 } from "ink";
|
|
15156
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
14855
15157
|
function FilePicker({ items, selectedIndex, query }) {
|
|
14856
15158
|
const theme = useTheme();
|
|
14857
15159
|
let startIndex = 0;
|
|
@@ -14861,12 +15163,12 @@ function FilePicker({ items, selectedIndex, query }) {
|
|
|
14861
15163
|
const visible = items.slice(startIndex, startIndex + VISIBLE_LIMIT);
|
|
14862
15164
|
const hasMoreAbove = startIndex > 0;
|
|
14863
15165
|
const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT;
|
|
14864
|
-
return /* @__PURE__ */
|
|
14865
|
-
/* @__PURE__ */
|
|
14866
|
-
/* @__PURE__ */
|
|
14867
|
-
/* @__PURE__ */
|
|
14868
|
-
visible.length === 0 && /* @__PURE__ */
|
|
14869
|
-
hasMoreAbove && /* @__PURE__ */
|
|
15166
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
15167
|
+
/* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: query ? `Files matching "${query}"` : "Mention a file" }),
|
|
15168
|
+
/* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
|
|
15169
|
+
/* @__PURE__ */ jsxs19(Box19, { marginTop: 1, flexDirection: "column", children: [
|
|
15170
|
+
visible.length === 0 && /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "No matches" }),
|
|
15171
|
+
hasMoreAbove && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
|
|
14870
15172
|
"\u2026 ",
|
|
14871
15173
|
startIndex,
|
|
14872
15174
|
" more above"
|
|
@@ -14875,12 +15177,12 @@ function FilePicker({ items, selectedIndex, query }) {
|
|
|
14875
15177
|
const actualIndex = startIndex + i;
|
|
14876
15178
|
const isSelected = actualIndex === selectedIndex;
|
|
14877
15179
|
const label = item.isDirectory ? `${item.name}/` : item.name;
|
|
14878
|
-
return /* @__PURE__ */
|
|
15180
|
+
return /* @__PURE__ */ jsxs19(Text20, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
|
|
14879
15181
|
isSelected ? "\u203A " : " ",
|
|
14880
15182
|
label
|
|
14881
15183
|
] }, item.name);
|
|
14882
15184
|
}),
|
|
14883
|
-
hasMoreBelow && /* @__PURE__ */
|
|
15185
|
+
hasMoreBelow && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
|
|
14884
15186
|
"\u2026 ",
|
|
14885
15187
|
items.length - (startIndex + VISIBLE_LIMIT),
|
|
14886
15188
|
" more below"
|
|
@@ -14898,8 +15200,8 @@ var init_file_picker = __esm({
|
|
|
14898
15200
|
});
|
|
14899
15201
|
|
|
14900
15202
|
// src/ui/slash-picker.tsx
|
|
14901
|
-
import { Box as
|
|
14902
|
-
import { jsx as
|
|
15203
|
+
import { Box as Box20, Text as Text21 } from "ink";
|
|
15204
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
14903
15205
|
function sourceBadge(source) {
|
|
14904
15206
|
if (source === "builtin") return "";
|
|
14905
15207
|
if (source === "project") return "project";
|
|
@@ -14919,12 +15221,12 @@ function SlashPicker({ items, selectedIndex, query }) {
|
|
|
14919
15221
|
const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT2;
|
|
14920
15222
|
const longestLabel = visible.reduce((m, it) => Math.max(m, commandLabel(it).length), 0);
|
|
14921
15223
|
const nameColWidth = Math.max(NAME_COL_MIN_WIDTH, longestLabel + NAME_DESC_GAP);
|
|
14922
|
-
return /* @__PURE__ */
|
|
14923
|
-
/* @__PURE__ */
|
|
14924
|
-
/* @__PURE__ */
|
|
14925
|
-
/* @__PURE__ */
|
|
14926
|
-
visible.length === 0 && /* @__PURE__ */
|
|
14927
|
-
hasMoreAbove && /* @__PURE__ */
|
|
15224
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
15225
|
+
/* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: query ? `Commands matching "/${query}"` : "Slash commands" }),
|
|
15226
|
+
/* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
|
|
15227
|
+
/* @__PURE__ */ jsxs20(Box20, { marginTop: 1, flexDirection: "column", children: [
|
|
15228
|
+
visible.length === 0 && /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: "No matches" }),
|
|
15229
|
+
hasMoreAbove && /* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
|
|
14928
15230
|
"\u2026 ",
|
|
14929
15231
|
startIndex,
|
|
14930
15232
|
" more above"
|
|
@@ -14934,16 +15236,16 @@ function SlashPicker({ items, selectedIndex, query }) {
|
|
|
14934
15236
|
const isSelected = actualIndex === selectedIndex;
|
|
14935
15237
|
const nameCol = commandLabel(item).padEnd(nameColWidth);
|
|
14936
15238
|
const badge = sourceBadge(item.source);
|
|
14937
|
-
return /* @__PURE__ */
|
|
15239
|
+
return /* @__PURE__ */ jsxs20(Text21, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
|
|
14938
15240
|
isSelected ? "\u203A " : " ",
|
|
14939
15241
|
nameCol,
|
|
14940
|
-
/* @__PURE__ */
|
|
15242
|
+
/* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
|
|
14941
15243
|
item.description,
|
|
14942
15244
|
badge && ` [${badge}]`
|
|
14943
15245
|
] })
|
|
14944
15246
|
] }, item.name);
|
|
14945
15247
|
}),
|
|
14946
|
-
hasMoreBelow && /* @__PURE__ */
|
|
15248
|
+
hasMoreBelow && /* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
|
|
14947
15249
|
"\u2026 ",
|
|
14948
15250
|
items.length - (startIndex + VISIBLE_LIMIT2),
|
|
14949
15251
|
" more below"
|
|
@@ -15066,15 +15368,15 @@ function filterSessions2(sessions, start, end) {
|
|
|
15066
15368
|
return sessions.filter((s) => s.date >= start && s.date <= end);
|
|
15067
15369
|
}
|
|
15068
15370
|
async function getCategoryReportText(sessionId) {
|
|
15069
|
-
const
|
|
15371
|
+
const log2 = await loadLog3();
|
|
15070
15372
|
const startDate = daysAgo2(7);
|
|
15071
15373
|
const endDate = today3();
|
|
15072
15374
|
const prevStart = daysAgo2(14);
|
|
15073
15375
|
const prevEnd = daysAgo2(8);
|
|
15074
|
-
const sessions = filterSessions2(
|
|
15075
|
-
const prevSessions = filterSessions2(
|
|
15376
|
+
const sessions = filterSessions2(log2.sessions, startDate, endDate);
|
|
15377
|
+
const prevSessions = filterSessions2(log2.sessions, prevStart, prevEnd);
|
|
15076
15378
|
if (sessionId) {
|
|
15077
|
-
const session =
|
|
15379
|
+
const session = log2.sessions.find((s) => s.id === sessionId);
|
|
15078
15380
|
if (session && !session.category) {
|
|
15079
15381
|
const result = await classifyFromSessionFile(sessionId);
|
|
15080
15382
|
session.category = result.category;
|
|
@@ -15123,7 +15425,7 @@ __export(app_exports, {
|
|
|
15123
15425
|
shouldOpenSlashPicker: () => shouldOpenSlashPicker
|
|
15124
15426
|
});
|
|
15125
15427
|
import React13, { useState as useState10, useRef as useRef3, useEffect as useEffect7, useCallback as useCallback2 } from "react";
|
|
15126
|
-
import { Box as
|
|
15428
|
+
import { Box as Box21, Text as Text22, useApp, useInput as useInput6, render } from "ink";
|
|
15127
15429
|
import SelectInput10 from "ink-select-input";
|
|
15128
15430
|
import { existsSync as existsSync3, statSync as statSync4 } from "fs";
|
|
15129
15431
|
import { join as join26 } from "path";
|
|
@@ -15133,7 +15435,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
15133
15435
|
import { platform as platform2 } from "os";
|
|
15134
15436
|
import fg4 from "fast-glob";
|
|
15135
15437
|
import { readFileSync as readFileSync3 } from "fs";
|
|
15136
|
-
import { jsx as
|
|
15438
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
15137
15439
|
function buildFilePickerIgnoreList(cwd) {
|
|
15138
15440
|
const hardcoded = [
|
|
15139
15441
|
// Dependencies
|
|
@@ -15299,7 +15601,7 @@ function detectGitBranch() {
|
|
|
15299
15601
|
return null;
|
|
15300
15602
|
}
|
|
15301
15603
|
}
|
|
15302
|
-
function
|
|
15604
|
+
function formatTokens5(n) {
|
|
15303
15605
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
15304
15606
|
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
15305
15607
|
return String(n);
|
|
@@ -15482,7 +15784,11 @@ ${wcagWarnings.join("\n")}` }
|
|
|
15482
15784
|
);
|
|
15483
15785
|
const executorRef = useRef3(new ToolExecutor(ALL_TOOLS));
|
|
15484
15786
|
const activeAsstIdRef = useRef3(null);
|
|
15485
|
-
const
|
|
15787
|
+
const sessionScopeRef = useRef3(new AbortScope());
|
|
15788
|
+
const activeScopeRef = useRef3(null);
|
|
15789
|
+
const supervisorRef = useRef3(new TurnSupervisor());
|
|
15790
|
+
const isAbortingRef = useRef3(false);
|
|
15791
|
+
const lastEscapeAtRef = useRef3(0);
|
|
15486
15792
|
const permResolveRef = useRef3(null);
|
|
15487
15793
|
const limitResolveRef = useRef3(null);
|
|
15488
15794
|
const pendingToolCallsRef = useRef3(/* @__PURE__ */ new Map());
|
|
@@ -15515,9 +15821,6 @@ ${wcagWarnings.join("\n")}` }
|
|
|
15515
15821
|
const flushTimeoutRef = useRef3(null);
|
|
15516
15822
|
const customCommandsRef = useRef3([]);
|
|
15517
15823
|
const pickerCancelRef = useRef3(null);
|
|
15518
|
-
useEffect7(() => {
|
|
15519
|
-
busyRef.current = busy;
|
|
15520
|
-
}, [busy]);
|
|
15521
15824
|
const pickerAnchor = activePicker?.anchor ?? null;
|
|
15522
15825
|
const pickerKind = activePicker?.kind ?? null;
|
|
15523
15826
|
const pickerQuery = React13.useMemo(() => {
|
|
@@ -16156,18 +16459,28 @@ ${wcagWarnings.join("\n")}` }
|
|
|
16156
16459
|
limitResolveRef.current = null;
|
|
16157
16460
|
setLimitModal(null);
|
|
16158
16461
|
}
|
|
16159
|
-
if (busyRef.current &&
|
|
16160
|
-
|
|
16462
|
+
if (busyRef.current && activeScopeRef.current && !isAbortingRef.current) {
|
|
16463
|
+
isAbortingRef.current = true;
|
|
16464
|
+
supervisorRef.current.killTurn();
|
|
16465
|
+
activeScopeRef.current.abort("user_stopped");
|
|
16161
16466
|
setQueue([]);
|
|
16162
16467
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
|
|
16468
|
+
setTasks([]);
|
|
16469
|
+
setTasksStartedAt(null);
|
|
16470
|
+
setTasksStartTokens(0);
|
|
16471
|
+
tasksRef.current = [];
|
|
16163
16472
|
} else if (!hadPerm && !hadLimit) {
|
|
16164
16473
|
void lspManagerRef.current.stopAll().finally(() => exit());
|
|
16165
16474
|
}
|
|
16166
16475
|
return;
|
|
16167
16476
|
}
|
|
16168
16477
|
if (key.escape) {
|
|
16478
|
+
const now2 = Date.now();
|
|
16169
16479
|
const modalOpen = perm !== null || limitModal !== null || showLspWizard || showCommandList || commandWizard !== null || commandToDelete !== null || resumeSessions !== null || showThemePicker;
|
|
16170
|
-
if (!modalOpen && busyRef.current &&
|
|
16480
|
+
if (!modalOpen && busyRef.current && activeScopeRef.current && !isAbortingRef.current && now2 - lastEscapeAtRef.current > 500) {
|
|
16481
|
+
lastEscapeAtRef.current = now2;
|
|
16482
|
+
isAbortingRef.current = true;
|
|
16483
|
+
supervisorRef.current.killTurn();
|
|
16171
16484
|
if (permResolveRef.current) {
|
|
16172
16485
|
permResolveRef.current("deny");
|
|
16173
16486
|
permResolveRef.current = null;
|
|
@@ -16178,9 +16491,13 @@ ${wcagWarnings.join("\n")}` }
|
|
|
16178
16491
|
limitResolveRef.current = null;
|
|
16179
16492
|
setLimitModal(null);
|
|
16180
16493
|
}
|
|
16181
|
-
|
|
16494
|
+
activeScopeRef.current.abort("user_stopped");
|
|
16182
16495
|
setQueue([]);
|
|
16183
16496
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
|
|
16497
|
+
setTasks([]);
|
|
16498
|
+
setTasksStartedAt(null);
|
|
16499
|
+
setTasksStartTokens(0);
|
|
16500
|
+
tasksRef.current = [];
|
|
16184
16501
|
return;
|
|
16185
16502
|
}
|
|
16186
16503
|
}
|
|
@@ -16265,9 +16582,10 @@ ${wcagWarnings.join("\n")}` }
|
|
|
16265
16582
|
return;
|
|
16266
16583
|
}
|
|
16267
16584
|
setBusy(true);
|
|
16585
|
+
busyRef.current = true;
|
|
16268
16586
|
setTurnStartedAt(Date.now());
|
|
16269
|
-
const
|
|
16270
|
-
|
|
16587
|
+
const turnScope = sessionScopeRef.current.createChild();
|
|
16588
|
+
activeScopeRef.current = turnScope;
|
|
16271
16589
|
try {
|
|
16272
16590
|
if (compiledContextRef.current) {
|
|
16273
16591
|
const store = artifactStoreRef.current;
|
|
@@ -16305,7 +16623,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
16305
16623
|
apiToken: cfg.apiToken,
|
|
16306
16624
|
model: cfg.model,
|
|
16307
16625
|
messages: messagesRef.current,
|
|
16308
|
-
signal:
|
|
16626
|
+
signal: turnScope.signal,
|
|
16309
16627
|
gateway: gatewayFromConfig(cfg)
|
|
16310
16628
|
});
|
|
16311
16629
|
if (result.replacedCount === 0) {
|
|
@@ -16340,11 +16658,12 @@ ${wcagWarnings.join("\n")}` }
|
|
|
16340
16658
|
}
|
|
16341
16659
|
} finally {
|
|
16342
16660
|
setBusy(false);
|
|
16661
|
+
busyRef.current = false;
|
|
16343
16662
|
setTurnStartedAt(null);
|
|
16344
16663
|
setTurnPhase("waiting");
|
|
16345
16664
|
setCurrentToolName(null);
|
|
16346
16665
|
setLastActivityAt(null);
|
|
16347
|
-
|
|
16666
|
+
activeScopeRef.current = null;
|
|
16348
16667
|
permResolveRef.current = null;
|
|
16349
16668
|
limitResolveRef.current = null;
|
|
16350
16669
|
pendingToolCallsRef.current.clear();
|
|
@@ -16365,9 +16684,10 @@ ${wcagWarnings.join("\n")}` }
|
|
|
16365
16684
|
setEvents((e) => [...e, { kind: "user", key: mkKey(), text: isRefresh ? `/init (refreshing ${targetFilename})` : "/init" }]);
|
|
16366
16685
|
messagesRef.current.push({ role: "user", content: sanitizeString(prompt) });
|
|
16367
16686
|
setBusy(true);
|
|
16687
|
+
busyRef.current = true;
|
|
16368
16688
|
setTurnStartedAt(Date.now());
|
|
16369
|
-
const
|
|
16370
|
-
|
|
16689
|
+
const turnScope = sessionScopeRef.current.createChild();
|
|
16690
|
+
activeScopeRef.current = turnScope;
|
|
16371
16691
|
const initClassification = classifyIntent(prompt);
|
|
16372
16692
|
const initEffortForTier = {
|
|
16373
16693
|
light: "low",
|
|
@@ -16387,7 +16707,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
16387
16707
|
tools: [...ALL_TOOLS, ...mcpToolsRef.current, ...lspToolsRef.current],
|
|
16388
16708
|
executor: executorRef.current,
|
|
16389
16709
|
cwd,
|
|
16390
|
-
signal:
|
|
16710
|
+
signal: turnScope.signal,
|
|
16391
16711
|
reasoningEffort: initReasoningEffort,
|
|
16392
16712
|
intentClassification: initClassification,
|
|
16393
16713
|
coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
@@ -16555,13 +16875,42 @@ ${wcagWarnings.join("\n")}` }
|
|
|
16555
16875
|
messagesRef.current.push({
|
|
16556
16876
|
role: "tool",
|
|
16557
16877
|
tool_call_id: tcId,
|
|
16558
|
-
content: "(
|
|
16878
|
+
content: "(stopped)",
|
|
16559
16879
|
name: tcName
|
|
16560
16880
|
});
|
|
16561
16881
|
}
|
|
16562
16882
|
setEvents(
|
|
16563
|
-
(evts) => evts.map((e2) => e2.kind === "tool" && e2.status === "running" ? { ...e2, status: "error", result: "(
|
|
16883
|
+
(evts) => evts.map((e2) => e2.kind === "tool" && e2.status === "running" ? { ...e2, status: "error", result: "(stopped)" } : e2)
|
|
16564
16884
|
);
|
|
16885
|
+
} else if (cfg?.cloudMode && isCloudQuotaExhaustedError(e)) {
|
|
16886
|
+
const token = cloudToken ?? initialCloudToken;
|
|
16887
|
+
const did = cloudDeviceId ?? initialCloudDeviceId;
|
|
16888
|
+
let used = 0;
|
|
16889
|
+
let limit = 0;
|
|
16890
|
+
let expiresAt = "";
|
|
16891
|
+
if (token) {
|
|
16892
|
+
try {
|
|
16893
|
+
const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
16894
|
+
const usage2 = await fetchCloudUsage2(token, did);
|
|
16895
|
+
if (usage2) {
|
|
16896
|
+
used = usage2.input_tokens_used;
|
|
16897
|
+
limit = usage2.input_token_limit;
|
|
16898
|
+
expiresAt = usage2.expires_at;
|
|
16899
|
+
}
|
|
16900
|
+
} catch {
|
|
16901
|
+
}
|
|
16902
|
+
}
|
|
16903
|
+
if (!limit) {
|
|
16904
|
+
const m = e.message.match(/Used ([\d,]+)\s*\/\s*([\d,]+)/);
|
|
16905
|
+
if (m && m[1] && m[2]) {
|
|
16906
|
+
used = parseInt(m[1].replace(/,/g, ""), 10);
|
|
16907
|
+
limit = parseInt(m[2].replace(/,/g, ""), 10);
|
|
16908
|
+
}
|
|
16909
|
+
}
|
|
16910
|
+
setEvents((es) => [
|
|
16911
|
+
...es,
|
|
16912
|
+
{ kind: "cloud_quota_exhausted", key: mkKey(), used, limit, expiresAt }
|
|
16913
|
+
]);
|
|
16565
16914
|
} else {
|
|
16566
16915
|
setEvents((es) => [
|
|
16567
16916
|
...es,
|
|
@@ -16573,12 +16922,13 @@ ${wcagWarnings.join("\n")}` }
|
|
|
16573
16922
|
const asstId = activeAsstIdRef.current;
|
|
16574
16923
|
if (asstId !== null) updateAssistant(asstId, () => ({ streaming: false }));
|
|
16575
16924
|
setBusy(false);
|
|
16925
|
+
busyRef.current = false;
|
|
16576
16926
|
setTurnStartedAt(null);
|
|
16577
16927
|
setTurnPhase("waiting");
|
|
16578
16928
|
setCurrentToolName(null);
|
|
16579
16929
|
setLastActivityAt(null);
|
|
16580
16930
|
activeAsstIdRef.current = null;
|
|
16581
|
-
|
|
16931
|
+
activeScopeRef.current = null;
|
|
16582
16932
|
permResolveRef.current = null;
|
|
16583
16933
|
limitResolveRef.current = null;
|
|
16584
16934
|
pendingToolCallsRef.current.clear();
|
|
@@ -17385,7 +17735,7 @@ ${lines.join("\n")}` }]);
|
|
|
17385
17735
|
setEvents((e) => [
|
|
17386
17736
|
...e,
|
|
17387
17737
|
{ kind: "info", key: mkKey(), text: `Starting remote session for ${repo.owner}/${repo.name}...` },
|
|
17388
|
-
{ kind: "info", key: mkKey(), text: `Budget: ${
|
|
17738
|
+
{ kind: "info", key: mkKey(), text: `Budget: ${formatTokens5(budget)} tokens. TTL: ${ttl} min.` }
|
|
17389
17739
|
]);
|
|
17390
17740
|
try {
|
|
17391
17741
|
const data = await startRemoteSession({
|
|
@@ -17402,7 +17752,7 @@ ${lines.join("\n")}` }]);
|
|
|
17402
17752
|
for await (const ev of streamRemoteProgress(
|
|
17403
17753
|
finalCfg.remoteWorkerUrl,
|
|
17404
17754
|
data.sessionId,
|
|
17405
|
-
|
|
17755
|
+
activeScopeRef.current?.signal
|
|
17406
17756
|
)) {
|
|
17407
17757
|
const event = ev;
|
|
17408
17758
|
if (event.type === "text_delta") {
|
|
@@ -17529,7 +17879,7 @@ ${lines.join("\n")}` }]);
|
|
|
17529
17879
|
[reloadCustomCommands, setEvents]
|
|
17530
17880
|
);
|
|
17531
17881
|
const processMessage = useCallback2(
|
|
17532
|
-
async (text, displayText) => {
|
|
17882
|
+
async (text, displayText, opts2) => {
|
|
17533
17883
|
if (!cfg) return;
|
|
17534
17884
|
let trimmed = text.trim();
|
|
17535
17885
|
if (!trimmed) return;
|
|
@@ -17597,7 +17947,15 @@ ${lines.join("\n")}` }]);
|
|
|
17597
17947
|
await sessionStartRecallRef.current;
|
|
17598
17948
|
sessionStartRecallRef.current = null;
|
|
17599
17949
|
}
|
|
17600
|
-
|
|
17950
|
+
if (opts2?.queuedKey) {
|
|
17951
|
+
setEvents(
|
|
17952
|
+
(evts) => evts.map(
|
|
17953
|
+
(e) => e.kind === "user" && e.key === opts2.queuedKey ? { ...e, text: display, images: images.length > 0 ? images : void 0, queued: false } : e
|
|
17954
|
+
)
|
|
17955
|
+
);
|
|
17956
|
+
} else {
|
|
17957
|
+
setEvents((e) => [...e, { kind: "user", key: mkKey(), text: display, images: images.length > 0 ? images : void 0 }]);
|
|
17958
|
+
}
|
|
17601
17959
|
const nudge = maybeLspNudge(display, cfg?.lspEnabled ?? false, cfg?.lspServers ?? {});
|
|
17602
17960
|
if (nudge) {
|
|
17603
17961
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: nudge }]);
|
|
@@ -17622,6 +17980,7 @@ ${lines.join("\n")}` }]);
|
|
|
17622
17980
|
]);
|
|
17623
17981
|
}
|
|
17624
17982
|
setBusy(true);
|
|
17983
|
+
busyRef.current = true;
|
|
17625
17984
|
gatewayMetaRef.current = null;
|
|
17626
17985
|
setGatewayMeta(null);
|
|
17627
17986
|
setTurnStartedAt(Date.now());
|
|
@@ -17684,8 +18043,8 @@ ${lines.join("\n")}` }]);
|
|
|
17684
18043
|
memoryRecalled: false
|
|
17685
18044
|
}
|
|
17686
18045
|
]);
|
|
17687
|
-
const
|
|
17688
|
-
|
|
18046
|
+
const turnScope = sessionScopeRef.current.createChild();
|
|
18047
|
+
activeScopeRef.current = turnScope;
|
|
17689
18048
|
const sharedCallbacks = {
|
|
17690
18049
|
onAssistantStart: () => {
|
|
17691
18050
|
const id = nextAssistantId++;
|
|
@@ -17825,8 +18184,32 @@ ${lines.join("\n")}` }]);
|
|
|
17825
18184
|
}
|
|
17826
18185
|
}
|
|
17827
18186
|
};
|
|
17828
|
-
|
|
17829
|
-
|
|
18187
|
+
const cleanupTurn = () => {
|
|
18188
|
+
setCodeMode(false);
|
|
18189
|
+
const asstId = activeAsstIdRef.current;
|
|
18190
|
+
if (asstId !== null) updateAssistant(asstId, () => ({ streaming: false }));
|
|
18191
|
+
setBusy(false);
|
|
18192
|
+
busyRef.current = false;
|
|
18193
|
+
setTurnStartedAt(null);
|
|
18194
|
+
setTurnPhase("waiting");
|
|
18195
|
+
setCurrentToolName(null);
|
|
18196
|
+
setLastActivityAt(null);
|
|
18197
|
+
activeAsstIdRef.current = null;
|
|
18198
|
+
activeScopeRef.current = null;
|
|
18199
|
+
isAbortingRef.current = false;
|
|
18200
|
+
permResolveRef.current = null;
|
|
18201
|
+
limitResolveRef.current = null;
|
|
18202
|
+
pendingToolCallsRef.current.clear();
|
|
18203
|
+
setTasks([]);
|
|
18204
|
+
setTasksStartedAt(null);
|
|
18205
|
+
setTasksStartTokens(0);
|
|
18206
|
+
tasksRef.current = [];
|
|
18207
|
+
setEvents(
|
|
18208
|
+
(evts) => evts.map((e) => e.kind === "tool" && e.status === "running" ? { ...e, status: "error", result: "(stopped)" } : e)
|
|
18209
|
+
);
|
|
18210
|
+
};
|
|
18211
|
+
supervisorRef.current.startTurn(
|
|
18212
|
+
{
|
|
17830
18213
|
accountId: cfg.accountId,
|
|
17831
18214
|
apiToken: cfg.apiToken,
|
|
17832
18215
|
model: overrideModel ?? cfg.model,
|
|
@@ -17835,7 +18218,7 @@ ${lines.join("\n")}` }]);
|
|
|
17835
18218
|
tools: [...ALL_TOOLS, ...mcpToolsRef.current, ...lspToolsRef.current],
|
|
17836
18219
|
executor: executorRef.current,
|
|
17837
18220
|
cwd: process.cwd(),
|
|
17838
|
-
signal:
|
|
18221
|
+
signal: turnScope.signal,
|
|
17839
18222
|
reasoningEffort: turnReasoningEffort,
|
|
17840
18223
|
coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
17841
18224
|
sessionId: ensureSessionId(),
|
|
@@ -17860,146 +18243,170 @@ ${lines.join("\n")}` }]);
|
|
|
17860
18243
|
}
|
|
17861
18244
|
},
|
|
17862
18245
|
callbacks: sharedCallbacks
|
|
17863
|
-
}
|
|
17864
|
-
|
|
17865
|
-
|
|
17866
|
-
|
|
17867
|
-
|
|
17868
|
-
|
|
17869
|
-
|
|
17870
|
-
|
|
17871
|
-
|
|
17872
|
-
|
|
17873
|
-
|
|
17874
|
-
|
|
17875
|
-
|
|
17876
|
-
|
|
17877
|
-
|
|
17878
|
-
|
|
17879
|
-
|
|
17880
|
-
|
|
17881
|
-
|
|
18246
|
+
},
|
|
18247
|
+
{
|
|
18248
|
+
onDone: async () => {
|
|
18249
|
+
await saveSessionSafe();
|
|
18250
|
+
if (turnScope.signal.aborted) {
|
|
18251
|
+
cleanupTurn();
|
|
18252
|
+
return;
|
|
18253
|
+
}
|
|
18254
|
+
if (shouldCompact({ messages: messagesRef.current })) {
|
|
18255
|
+
if (compiledContextRef.current) {
|
|
18256
|
+
const store = artifactStoreRef.current;
|
|
18257
|
+
const result = compactMessages2({
|
|
18258
|
+
messages: messagesRef.current,
|
|
18259
|
+
state: sessionStateRef.current,
|
|
18260
|
+
store
|
|
18261
|
+
});
|
|
18262
|
+
if (result.metrics.rawTurnsRemoved > 0) {
|
|
18263
|
+
messagesRef.current = result.newMessages;
|
|
18264
|
+
sessionStateRef.current = result.newState;
|
|
18265
|
+
setEvents((e) => [
|
|
18266
|
+
...e,
|
|
18267
|
+
{
|
|
18268
|
+
kind: "info",
|
|
18269
|
+
key: mkKey(),
|
|
18270
|
+
text: `auto-compacted: ${result.metrics.estimatedTokensBefore} \u2192 ${result.metrics.estimatedTokensAfter} tokens (${result.metrics.archivedArtifacts} artifacts)`
|
|
18271
|
+
}
|
|
18272
|
+
]);
|
|
18273
|
+
await saveSessionSafe();
|
|
17882
18274
|
}
|
|
17883
|
-
|
|
17884
|
-
|
|
18275
|
+
} else {
|
|
18276
|
+
try {
|
|
18277
|
+
const result = await compactMessages({
|
|
18278
|
+
accountId: cfg.accountId,
|
|
18279
|
+
apiToken: cfg.apiToken,
|
|
18280
|
+
model: cfg.model,
|
|
18281
|
+
messages: messagesRef.current,
|
|
18282
|
+
signal: turnScope.signal,
|
|
18283
|
+
gateway: gatewayFromConfig(cfg)
|
|
18284
|
+
});
|
|
18285
|
+
if (result.replacedCount > 0) {
|
|
18286
|
+
messagesRef.current = result.newMessages;
|
|
18287
|
+
setEvents((e) => [
|
|
18288
|
+
...e,
|
|
18289
|
+
{
|
|
18290
|
+
kind: "info",
|
|
18291
|
+
key: mkKey(),
|
|
18292
|
+
text: `auto-compacted: ${result.replacedCount} messages summarized`
|
|
18293
|
+
}
|
|
18294
|
+
]);
|
|
18295
|
+
await saveSessionSafe();
|
|
18296
|
+
}
|
|
18297
|
+
} catch (compactErr) {
|
|
18298
|
+
if (compactErr.name !== "AbortError") {
|
|
18299
|
+
setEvents((es) => [
|
|
18300
|
+
...es,
|
|
18301
|
+
{
|
|
18302
|
+
kind: "info",
|
|
18303
|
+
key: mkKey(),
|
|
18304
|
+
text: `auto-compact failed: ${compactErr.message ?? String(compactErr)}`
|
|
18305
|
+
}
|
|
18306
|
+
]);
|
|
18307
|
+
}
|
|
18308
|
+
}
|
|
18309
|
+
}
|
|
17885
18310
|
}
|
|
17886
|
-
|
|
17887
|
-
|
|
17888
|
-
|
|
17889
|
-
|
|
17890
|
-
|
|
17891
|
-
|
|
17892
|
-
|
|
17893
|
-
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
|
|
17899
|
-
|
|
17900
|
-
|
|
17901
|
-
|
|
17902
|
-
|
|
17903
|
-
|
|
18311
|
+
const manager = memoryManagerRef.current;
|
|
18312
|
+
if (manager) {
|
|
18313
|
+
try {
|
|
18314
|
+
const cwd = process.cwd();
|
|
18315
|
+
const queryText = sessionStateRef.current.task || cwd;
|
|
18316
|
+
const results = await manager.recall({ text: queryText, repoPath: cwd, limit: 5 });
|
|
18317
|
+
if (results.length > 0) {
|
|
18318
|
+
const text2 = await manager.synthesizeRecalled(results);
|
|
18319
|
+
const lastSystemIdx = messagesRef.current.findLastIndex((m) => m.role === "system");
|
|
18320
|
+
const insertIdx = lastSystemIdx >= 0 ? lastSystemIdx + 1 : messagesRef.current.length;
|
|
18321
|
+
messagesRef.current.splice(insertIdx, 0, { role: "system", content: text2 });
|
|
18322
|
+
setEvents((e) => [
|
|
18323
|
+
...e,
|
|
18324
|
+
{
|
|
18325
|
+
kind: "memory",
|
|
18326
|
+
key: mkKey(),
|
|
18327
|
+
text: `recalled ${results.length} memory${results.length === 1 ? "" : "ies"} after compaction`
|
|
18328
|
+
}
|
|
18329
|
+
]);
|
|
18330
|
+
await saveSessionSafe();
|
|
18331
|
+
}
|
|
18332
|
+
} catch {
|
|
18333
|
+
}
|
|
18334
|
+
}
|
|
18335
|
+
cleanupTurn();
|
|
18336
|
+
},
|
|
18337
|
+
onError: async (e) => {
|
|
18338
|
+
if (e.name === "AbortError") {
|
|
18339
|
+
for (const [tcId, tcName] of pendingToolCallsRef.current) {
|
|
18340
|
+
messagesRef.current.push({
|
|
18341
|
+
role: "tool",
|
|
18342
|
+
tool_call_id: tcId,
|
|
18343
|
+
content: "(stopped)",
|
|
18344
|
+
name: tcName
|
|
18345
|
+
});
|
|
18346
|
+
}
|
|
18347
|
+
setEvents(
|
|
18348
|
+
(evts) => evts.map((e2) => e2.kind === "tool" && e2.status === "running" ? { ...e2, status: "error", result: "(stopped)" } : e2)
|
|
18349
|
+
);
|
|
18350
|
+
} else if (cfg?.cloudMode && isCloudQuotaExhaustedError(e)) {
|
|
18351
|
+
const token = cloudToken ?? initialCloudToken;
|
|
18352
|
+
const did = cloudDeviceId ?? initialCloudDeviceId;
|
|
18353
|
+
let used = 0;
|
|
18354
|
+
let limit = 0;
|
|
18355
|
+
let expiresAt = "";
|
|
18356
|
+
if (token) {
|
|
18357
|
+
try {
|
|
18358
|
+
const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
18359
|
+
const usage2 = await fetchCloudUsage2(token, did);
|
|
18360
|
+
if (usage2) {
|
|
18361
|
+
used = usage2.input_tokens_used;
|
|
18362
|
+
limit = usage2.input_token_limit;
|
|
18363
|
+
expiresAt = usage2.expires_at;
|
|
17904
18364
|
}
|
|
17905
|
-
|
|
17906
|
-
|
|
18365
|
+
} catch {
|
|
18366
|
+
}
|
|
18367
|
+
}
|
|
18368
|
+
if (!limit) {
|
|
18369
|
+
const m = e.message.match(/Used ([\d,]+)\s*\/\s*([\d,]+)/);
|
|
18370
|
+
if (m && m[1] && m[2]) {
|
|
18371
|
+
used = parseInt(m[1].replace(/,/g, ""), 10);
|
|
18372
|
+
limit = parseInt(m[2].replace(/,/g, ""), 10);
|
|
18373
|
+
}
|
|
17907
18374
|
}
|
|
17908
|
-
|
|
17909
|
-
|
|
18375
|
+
setEvents((es) => [
|
|
18376
|
+
...es,
|
|
18377
|
+
{ kind: "cloud_quota_exhausted", key: mkKey(), used, limit, expiresAt }
|
|
18378
|
+
]);
|
|
18379
|
+
} else {
|
|
18380
|
+
const isInvalidJson400 = e instanceof KimiApiError && e.httpStatus === 400 && e.message.includes("invalid escaped character");
|
|
18381
|
+
if (isInvalidJson400) {
|
|
18382
|
+
messagesRef.current.pop();
|
|
17910
18383
|
setEvents((es) => [
|
|
17911
18384
|
...es,
|
|
17912
18385
|
{
|
|
17913
|
-
kind: "
|
|
18386
|
+
kind: "error",
|
|
17914
18387
|
key: mkKey(),
|
|
17915
|
-
text:
|
|
18388
|
+
text: "API rejected request (invalid JSON in conversation history). Retrying may work; run /clear to reset if it persists."
|
|
17916
18389
|
}
|
|
17917
18390
|
]);
|
|
17918
18391
|
} else {
|
|
17919
|
-
|
|
18392
|
+
setEvents((es) => [
|
|
18393
|
+
...es,
|
|
18394
|
+
{ kind: "error", key: mkKey(), text: e.message ?? String(e) }
|
|
18395
|
+
]);
|
|
17920
18396
|
}
|
|
17921
18397
|
}
|
|
18398
|
+
cleanupTurn();
|
|
17922
18399
|
}
|
|
17923
18400
|
}
|
|
17924
|
-
|
|
17925
|
-
if (manager) {
|
|
17926
|
-
try {
|
|
17927
|
-
const cwd = process.cwd();
|
|
17928
|
-
const queryText = sessionStateRef.current.task || cwd;
|
|
17929
|
-
const results = await manager.recall({ text: queryText, repoPath: cwd, limit: 5 });
|
|
17930
|
-
if (results.length > 0) {
|
|
17931
|
-
const text2 = await manager.synthesizeRecalled(results);
|
|
17932
|
-
const lastSystemIdx = messagesRef.current.findLastIndex((m) => m.role === "system");
|
|
17933
|
-
const insertIdx = lastSystemIdx >= 0 ? lastSystemIdx + 1 : messagesRef.current.length;
|
|
17934
|
-
messagesRef.current.splice(insertIdx, 0, { role: "system", content: text2 });
|
|
17935
|
-
setEvents((e) => [
|
|
17936
|
-
...e,
|
|
17937
|
-
{
|
|
17938
|
-
kind: "memory",
|
|
17939
|
-
key: mkKey(),
|
|
17940
|
-
text: `recalled ${results.length} memory${results.length === 1 ? "" : "ies"} after compaction`
|
|
17941
|
-
}
|
|
17942
|
-
]);
|
|
17943
|
-
await saveSessionSafe();
|
|
17944
|
-
}
|
|
17945
|
-
} catch {
|
|
17946
|
-
}
|
|
17947
|
-
}
|
|
17948
|
-
} catch (e) {
|
|
17949
|
-
if (e.name === "AbortError") {
|
|
17950
|
-
for (const [tcId, tcName] of pendingToolCallsRef.current) {
|
|
17951
|
-
messagesRef.current.push({
|
|
17952
|
-
role: "tool",
|
|
17953
|
-
tool_call_id: tcId,
|
|
17954
|
-
content: "(interrupted)",
|
|
17955
|
-
name: tcName
|
|
17956
|
-
});
|
|
17957
|
-
}
|
|
17958
|
-
setEvents(
|
|
17959
|
-
(evts) => evts.map((e2) => e2.kind === "tool" && e2.status === "running" ? { ...e2, status: "error", result: "(interrupted)" } : e2)
|
|
17960
|
-
);
|
|
17961
|
-
} else {
|
|
17962
|
-
const isInvalidJson400 = e instanceof KimiApiError && e.httpStatus === 400 && e.message.includes("invalid escaped character");
|
|
17963
|
-
if (isInvalidJson400) {
|
|
17964
|
-
messagesRef.current.pop();
|
|
17965
|
-
setEvents((es) => [
|
|
17966
|
-
...es,
|
|
17967
|
-
{
|
|
17968
|
-
kind: "error",
|
|
17969
|
-
key: mkKey(),
|
|
17970
|
-
text: "API rejected request (invalid JSON in conversation history). Retrying may work; run /clear to reset if it persists."
|
|
17971
|
-
}
|
|
17972
|
-
]);
|
|
17973
|
-
} else {
|
|
17974
|
-
setEvents((es) => [
|
|
17975
|
-
...es,
|
|
17976
|
-
{ kind: "error", key: mkKey(), text: e.message ?? String(e) }
|
|
17977
|
-
]);
|
|
17978
|
-
}
|
|
17979
|
-
}
|
|
17980
|
-
} finally {
|
|
17981
|
-
setCodeMode(false);
|
|
17982
|
-
const asstId = activeAsstIdRef.current;
|
|
17983
|
-
if (asstId !== null) updateAssistant(asstId, () => ({ streaming: false }));
|
|
17984
|
-
setBusy(false);
|
|
17985
|
-
setTurnStartedAt(null);
|
|
17986
|
-
setTurnPhase("waiting");
|
|
17987
|
-
setCurrentToolName(null);
|
|
17988
|
-
setLastActivityAt(null);
|
|
17989
|
-
activeAsstIdRef.current = null;
|
|
17990
|
-
activeControllerRef.current = null;
|
|
17991
|
-
permResolveRef.current = null;
|
|
17992
|
-
limitResolveRef.current = null;
|
|
17993
|
-
pendingToolCallsRef.current.clear();
|
|
17994
|
-
}
|
|
18401
|
+
);
|
|
17995
18402
|
},
|
|
17996
18403
|
[cfg, handleSlash, updateAssistant, updateTool, saveSessionSafe, updateGatewayMeta]
|
|
17997
18404
|
);
|
|
17998
18405
|
useEffect7(() => {
|
|
17999
|
-
if (!busy && queue.length > 0) {
|
|
18406
|
+
if (!busy && queue.length > 0 && supervisorRef.current.phase === "idle") {
|
|
18000
18407
|
const next = queue[0];
|
|
18001
18408
|
setQueue((q) => q.slice(1));
|
|
18002
|
-
processMessage(next.full, next.display);
|
|
18409
|
+
processMessage(next.full, next.display, { queuedKey: next.key });
|
|
18003
18410
|
}
|
|
18004
18411
|
}, [busy, queue, processMessage]);
|
|
18005
18412
|
const submit = useCallback2(
|
|
@@ -18008,8 +18415,20 @@ ${lines.join("\n")}` }]);
|
|
|
18008
18415
|
if (!trimmedFull) return;
|
|
18009
18416
|
const trimmedDisplay = (display ?? full).trim() || trimmedFull;
|
|
18010
18417
|
const historyEntry = trimmedDisplay;
|
|
18011
|
-
if (
|
|
18012
|
-
|
|
18418
|
+
if (busyRef.current) {
|
|
18419
|
+
if (activeScopeRef.current && !isAbortingRef.current) {
|
|
18420
|
+
isAbortingRef.current = true;
|
|
18421
|
+
supervisorRef.current.killTurn();
|
|
18422
|
+
activeScopeRef.current.abort("new_message");
|
|
18423
|
+
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(preempted)" }]);
|
|
18424
|
+
setTasks([]);
|
|
18425
|
+
setTasksStartedAt(null);
|
|
18426
|
+
setTasksStartTokens(0);
|
|
18427
|
+
tasksRef.current = [];
|
|
18428
|
+
}
|
|
18429
|
+
const key = mkKey();
|
|
18430
|
+
setEvents((e) => [...e, { kind: "user", key, text: trimmedDisplay, queued: true }]);
|
|
18431
|
+
setQueue((q) => [...q, { full: trimmedFull, display: trimmedDisplay, key }]);
|
|
18013
18432
|
setHistory((h) => h.length > 0 && h[h.length - 1] === historyEntry ? h : [...h, historyEntry]);
|
|
18014
18433
|
setInput("");
|
|
18015
18434
|
setHistoryIndex(-1);
|
|
@@ -18020,7 +18439,7 @@ ${lines.join("\n")}` }]);
|
|
|
18020
18439
|
setHistoryIndex(-1);
|
|
18021
18440
|
processMessage(trimmedFull, trimmedDisplay !== trimmedFull ? trimmedDisplay : void 0);
|
|
18022
18441
|
},
|
|
18023
|
-
[
|
|
18442
|
+
[processMessage]
|
|
18024
18443
|
);
|
|
18025
18444
|
submitRef.current = submit;
|
|
18026
18445
|
useEffect7(() => {
|
|
@@ -18038,7 +18457,7 @@ ${lines.join("\n")}` }]);
|
|
|
18038
18457
|
}
|
|
18039
18458
|
}, [usage]);
|
|
18040
18459
|
if (!cfg) {
|
|
18041
|
-
return /* @__PURE__ */
|
|
18460
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(
|
|
18042
18461
|
Onboarding,
|
|
18043
18462
|
{
|
|
18044
18463
|
onCancel: () => exit(),
|
|
@@ -18070,10 +18489,10 @@ ${lines.join("\n")}` }]);
|
|
|
18070
18489
|
) });
|
|
18071
18490
|
}
|
|
18072
18491
|
if (resumeSessions !== null) {
|
|
18073
|
-
return /* @__PURE__ */
|
|
18492
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(ResumePicker, { sessions: resumeSessions, onPick: handleResumePick }) }) });
|
|
18074
18493
|
}
|
|
18075
18494
|
if (showRemoteDashboard) {
|
|
18076
|
-
return /* @__PURE__ */
|
|
18495
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: selectedRemoteSession ? /* @__PURE__ */ jsx23(
|
|
18077
18496
|
RemoteSessionDetail,
|
|
18078
18497
|
{
|
|
18079
18498
|
session: selectedRemoteSession,
|
|
@@ -18096,7 +18515,7 @@ ${lines.join("\n")}` }]);
|
|
|
18096
18515
|
setShowRemoteDashboard(false);
|
|
18097
18516
|
}
|
|
18098
18517
|
}
|
|
18099
|
-
) : /* @__PURE__ */
|
|
18518
|
+
) : /* @__PURE__ */ jsx23(
|
|
18100
18519
|
RemoteDashboard,
|
|
18101
18520
|
{
|
|
18102
18521
|
onSelect: (session) => setSelectedRemoteSession(session),
|
|
@@ -18105,7 +18524,7 @@ ${lines.join("\n")}` }]);
|
|
|
18105
18524
|
) }) });
|
|
18106
18525
|
}
|
|
18107
18526
|
if (showLspWizard) {
|
|
18108
|
-
return /* @__PURE__ */
|
|
18527
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
18109
18528
|
LspWizard,
|
|
18110
18529
|
{
|
|
18111
18530
|
servers: cfg?.lspServers ?? {},
|
|
@@ -18142,7 +18561,7 @@ ${lines.join("\n")}` }]);
|
|
|
18142
18561
|
) }) });
|
|
18143
18562
|
}
|
|
18144
18563
|
if (commandWizard) {
|
|
18145
|
-
return /* @__PURE__ */
|
|
18564
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
18146
18565
|
CommandWizard,
|
|
18147
18566
|
{
|
|
18148
18567
|
mode: commandWizard.mode,
|
|
@@ -18155,7 +18574,7 @@ ${lines.join("\n")}` }]);
|
|
|
18155
18574
|
) }) });
|
|
18156
18575
|
}
|
|
18157
18576
|
if (commandPicker) {
|
|
18158
|
-
return /* @__PURE__ */
|
|
18577
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
18159
18578
|
CommandPicker,
|
|
18160
18579
|
{
|
|
18161
18580
|
commands: customCommandsRef.current,
|
|
@@ -18173,14 +18592,14 @@ ${lines.join("\n")}` }]);
|
|
|
18173
18592
|
) }) });
|
|
18174
18593
|
}
|
|
18175
18594
|
if (commandToDelete) {
|
|
18176
|
-
return /* @__PURE__ */
|
|
18177
|
-
/* @__PURE__ */
|
|
18595
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
18596
|
+
/* @__PURE__ */ jsxs21(Text22, { color: theme.accent, bold: true, children: [
|
|
18178
18597
|
"Delete /",
|
|
18179
18598
|
commandToDelete.name,
|
|
18180
18599
|
"?"
|
|
18181
18600
|
] }),
|
|
18182
|
-
/* @__PURE__ */
|
|
18183
|
-
/* @__PURE__ */
|
|
18601
|
+
/* @__PURE__ */ jsx23(Text22, { color: theme.info.color, children: commandToDelete.filepath }),
|
|
18602
|
+
/* @__PURE__ */ jsx23(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx23(
|
|
18184
18603
|
SelectInput10,
|
|
18185
18604
|
{
|
|
18186
18605
|
items: [
|
|
@@ -18199,7 +18618,7 @@ ${lines.join("\n")}` }]);
|
|
|
18199
18618
|
] }) });
|
|
18200
18619
|
}
|
|
18201
18620
|
if (showCommandList) {
|
|
18202
|
-
return /* @__PURE__ */
|
|
18621
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
18203
18622
|
CommandList,
|
|
18204
18623
|
{
|
|
18205
18624
|
commands: customCommandsRef.current,
|
|
@@ -18208,12 +18627,12 @@ ${lines.join("\n")}` }]);
|
|
|
18208
18627
|
) }) });
|
|
18209
18628
|
}
|
|
18210
18629
|
if (showThemePicker) {
|
|
18211
|
-
return /* @__PURE__ */
|
|
18630
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(ThemePicker, { themes: themeList(), onPick: handleThemePick }) }) });
|
|
18212
18631
|
}
|
|
18213
18632
|
const hasConversation = events.some((e) => e.kind === "user" || e.kind === "assistant");
|
|
18214
|
-
return /* @__PURE__ */
|
|
18215
|
-
!hasConversation && events.length === 0 ? /* @__PURE__ */
|
|
18216
|
-
perm ? /* @__PURE__ */
|
|
18633
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
18634
|
+
!hasConversation && events.length === 0 ? /* @__PURE__ */ jsx23(Welcome, { accountId: cfg.accountId, cloudMode: cfg.cloudMode }) : /* @__PURE__ */ jsx23(ChatView, { events, showReasoning, verbose, intentTier: intentTier ?? void 0 }),
|
|
18635
|
+
perm ? /* @__PURE__ */ jsx23(
|
|
18217
18636
|
PermissionModal,
|
|
18218
18637
|
{
|
|
18219
18638
|
tool: perm.tool,
|
|
@@ -18224,7 +18643,7 @@ ${lines.join("\n")}` }]);
|
|
|
18224
18643
|
setPerm(null);
|
|
18225
18644
|
}
|
|
18226
18645
|
}
|
|
18227
|
-
) : limitModal ? /* @__PURE__ */
|
|
18646
|
+
) : limitModal ? /* @__PURE__ */ jsx23(
|
|
18228
18647
|
LimitModal,
|
|
18229
18648
|
{
|
|
18230
18649
|
limit: limitModal.limit,
|
|
@@ -18234,8 +18653,8 @@ ${lines.join("\n")}` }]);
|
|
|
18234
18653
|
setLimitModal(null);
|
|
18235
18654
|
}
|
|
18236
18655
|
}
|
|
18237
|
-
) : /* @__PURE__ */
|
|
18238
|
-
tasks.length > 0 && /* @__PURE__ */
|
|
18656
|
+
) : /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
18657
|
+
tasks.length > 0 && /* @__PURE__ */ jsx23(
|
|
18239
18658
|
TaskList,
|
|
18240
18659
|
{
|
|
18241
18660
|
tasks,
|
|
@@ -18243,11 +18662,11 @@ ${lines.join("\n")}` }]);
|
|
|
18243
18662
|
tokensDelta: Math.max(0, (usage?.prompt_tokens ?? 0) - tasksStartTokens)
|
|
18244
18663
|
}
|
|
18245
18664
|
),
|
|
18246
|
-
queue.length > 0 && /* @__PURE__ */
|
|
18665
|
+
queue.length > 0 && /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", marginBottom: 1, children: queue.map((q, i) => /* @__PURE__ */ jsxs21(Text22, { color: theme.info.color, dimColor: theme.info.dim, children: [
|
|
18247
18666
|
"\u23F3 ",
|
|
18248
18667
|
q.display
|
|
18249
18668
|
] }, `queue_${i}`)) }),
|
|
18250
|
-
/* @__PURE__ */
|
|
18669
|
+
/* @__PURE__ */ jsx23(
|
|
18251
18670
|
StatusBar,
|
|
18252
18671
|
{
|
|
18253
18672
|
model: cfg.model,
|
|
@@ -18274,7 +18693,7 @@ ${lines.join("\n")}` }]);
|
|
|
18274
18693
|
intentTier: intentTier ?? void 0
|
|
18275
18694
|
}
|
|
18276
18695
|
),
|
|
18277
|
-
activePicker?.kind === "file" && /* @__PURE__ */
|
|
18696
|
+
activePicker?.kind === "file" && /* @__PURE__ */ jsx23(
|
|
18278
18697
|
FilePicker,
|
|
18279
18698
|
{
|
|
18280
18699
|
items: filteredFileItems,
|
|
@@ -18282,7 +18701,7 @@ ${lines.join("\n")}` }]);
|
|
|
18282
18701
|
query: pickerQuery ?? ""
|
|
18283
18702
|
}
|
|
18284
18703
|
),
|
|
18285
|
-
activePicker?.kind === "slash" && /* @__PURE__ */
|
|
18704
|
+
activePicker?.kind === "slash" && /* @__PURE__ */ jsx23(
|
|
18286
18705
|
SlashPicker,
|
|
18287
18706
|
{
|
|
18288
18707
|
items: filteredSlashItems,
|
|
@@ -18290,9 +18709,9 @@ ${lines.join("\n")}` }]);
|
|
|
18290
18709
|
query: pickerQuery ?? ""
|
|
18291
18710
|
}
|
|
18292
18711
|
),
|
|
18293
|
-
/* @__PURE__ */
|
|
18294
|
-
/* @__PURE__ */
|
|
18295
|
-
/* @__PURE__ */
|
|
18712
|
+
/* @__PURE__ */ jsxs21(Box21, { marginTop: 1, children: [
|
|
18713
|
+
/* @__PURE__ */ jsx23(Text22, { color: theme.prompt ?? theme.accent, children: "\u203A " }),
|
|
18714
|
+
/* @__PURE__ */ jsx23(
|
|
18296
18715
|
CustomTextInput,
|
|
18297
18716
|
{
|
|
18298
18717
|
value: input,
|
|
@@ -18349,7 +18768,7 @@ ${lines.join("\n")}` }]);
|
|
|
18349
18768
|
}
|
|
18350
18769
|
async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath = null, cloudToken, cloudDeviceId) {
|
|
18351
18770
|
const instance = render(
|
|
18352
|
-
/* @__PURE__ */
|
|
18771
|
+
/* @__PURE__ */ jsx23(
|
|
18353
18772
|
App,
|
|
18354
18773
|
{
|
|
18355
18774
|
initialCfg: cfg,
|
|
@@ -18371,6 +18790,7 @@ var init_app = __esm({
|
|
|
18371
18790
|
"src/app.tsx"() {
|
|
18372
18791
|
"use strict";
|
|
18373
18792
|
init_loop();
|
|
18793
|
+
init_supervisor();
|
|
18374
18794
|
init_system_prompt();
|
|
18375
18795
|
init_compact();
|
|
18376
18796
|
init_compaction();
|
|
@@ -18381,6 +18801,7 @@ var init_app = __esm({
|
|
|
18381
18801
|
init_lsp();
|
|
18382
18802
|
init_messages();
|
|
18383
18803
|
init_errors();
|
|
18804
|
+
init_abort_scope();
|
|
18384
18805
|
init_chat();
|
|
18385
18806
|
init_status();
|
|
18386
18807
|
init_permission();
|