kimiflare 0.64.0 → 0.66.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 +611 -386
- package/dist/index.js.map +1 -1
- package/dist/sdk/index.js +167 -47
- package/dist/sdk/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -401,11 +401,12 @@ var init_logger = __esm({
|
|
|
401
401
|
});
|
|
402
402
|
|
|
403
403
|
// src/util/sse.ts
|
|
404
|
-
async function* readSSE(stream, signal, idleTimeoutMs) {
|
|
404
|
+
async function* readSSE(stream, signal, idleTimeoutMs, postFirstByteIdleTimeoutMs) {
|
|
405
405
|
const reader = stream.getReader();
|
|
406
406
|
const decoder = new TextDecoder("utf-8");
|
|
407
407
|
let buffer = "";
|
|
408
408
|
let lastDataAt = Date.now();
|
|
409
|
+
let gotFirstByte = false;
|
|
409
410
|
const onAbort = () => {
|
|
410
411
|
reader.cancel(new DOMException("aborted", "AbortError")).catch(() => {
|
|
411
412
|
});
|
|
@@ -427,16 +428,18 @@ async function* readSSE(stream, signal, idleTimeoutMs) {
|
|
|
427
428
|
try {
|
|
428
429
|
while (true) {
|
|
429
430
|
if (signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
430
|
-
|
|
431
|
-
|
|
431
|
+
const activeIdleTimeoutMs = gotFirstByte && postFirstByteIdleTimeoutMs !== void 0 ? postFirstByteIdleTimeoutMs : idleTimeoutMs;
|
|
432
|
+
if (activeIdleTimeoutMs !== void 0 && Date.now() - lastDataAt > activeIdleTimeoutMs) {
|
|
433
|
+
logger.warn("sse:idle_timeout", { idleTimeoutMs: activeIdleTimeoutMs, gotFirstByte });
|
|
432
434
|
throw new DOMException(
|
|
433
|
-
`kimiflare: stream idle for ${
|
|
435
|
+
`kimiflare: stream idle for ${activeIdleTimeoutMs}ms \u2014 no data received from API`,
|
|
434
436
|
"TimeoutError"
|
|
435
437
|
);
|
|
436
438
|
}
|
|
437
439
|
const { done, value } = await abortRace(reader.read());
|
|
438
440
|
if (done) break;
|
|
439
441
|
lastDataAt = Date.now();
|
|
442
|
+
gotFirstByte = true;
|
|
440
443
|
buffer += decoder.decode(value, { stream: true });
|
|
441
444
|
buffer = buffer.replace(/\r\n/g, "\n");
|
|
442
445
|
let sep3;
|
|
@@ -717,7 +720,7 @@ async function* runKimi(opts2) {
|
|
|
717
720
|
if (meta) yield { type: "gateway_meta", meta };
|
|
718
721
|
let lastUsage = null;
|
|
719
722
|
logger.debug("runKimi:stream_start", { requestId });
|
|
720
|
-
for await (const ev of parseStream(res.body, opts2.signal, opts2.idleTimeoutMs)) {
|
|
723
|
+
for await (const ev of parseStream(res.body, opts2.signal, opts2.idleTimeoutMs, opts2.postFirstByteIdleTimeoutMs)) {
|
|
721
724
|
if (ev.type === "usage") lastUsage = ev.usage;
|
|
722
725
|
yield ev;
|
|
723
726
|
}
|
|
@@ -799,12 +802,11 @@ function readGatewayMeta(headers) {
|
|
|
799
802
|
if (model) meta.model = model;
|
|
800
803
|
return Object.keys(meta).length > 0 ? meta : null;
|
|
801
804
|
}
|
|
802
|
-
async function* parseStream(body, signal, idleTimeoutMs = DEFAULT_IDLE_TIMEOUT_MS) {
|
|
805
|
+
async function* parseStream(body, signal, idleTimeoutMs = DEFAULT_IDLE_TIMEOUT_MS, postFirstByteIdleTimeoutMs = DEFAULT_POST_FIRST_BYTE_IDLE_TIMEOUT_MS) {
|
|
803
806
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
804
807
|
let lastUsage = null;
|
|
805
808
|
let finishReason = null;
|
|
806
|
-
|
|
807
|
-
for await (const dataStr of readSSE(body, signal, idleTimeoutMs)) {
|
|
809
|
+
for await (const dataStr of readSSE(body, signal, idleTimeoutMs, postFirstByteIdleTimeoutMs)) {
|
|
808
810
|
if (dataStr === "[DONE]") break;
|
|
809
811
|
let chunk = null;
|
|
810
812
|
try {
|
|
@@ -942,7 +944,7 @@ function sleep(ms, signal) {
|
|
|
942
944
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
943
945
|
});
|
|
944
946
|
}
|
|
945
|
-
var RETRYABLE_CODES, MAX_ATTEMPTS, DEFAULT_IDLE_TIMEOUT_MS;
|
|
947
|
+
var RETRYABLE_CODES, MAX_ATTEMPTS, DEFAULT_IDLE_TIMEOUT_MS, DEFAULT_POST_FIRST_BYTE_IDLE_TIMEOUT_MS;
|
|
946
948
|
var init_client = __esm({
|
|
947
949
|
"src/agent/client.ts"() {
|
|
948
950
|
"use strict";
|
|
@@ -954,6 +956,7 @@ var init_client = __esm({
|
|
|
954
956
|
RETRYABLE_CODES = /* @__PURE__ */ new Set([3040]);
|
|
955
957
|
MAX_ATTEMPTS = 5;
|
|
956
958
|
DEFAULT_IDLE_TIMEOUT_MS = 6e4;
|
|
959
|
+
DEFAULT_POST_FIRST_BYTE_IDLE_TIMEOUT_MS = 3e4;
|
|
957
960
|
}
|
|
958
961
|
});
|
|
959
962
|
|
|
@@ -2155,7 +2158,7 @@ var init_session_state = __esm({
|
|
|
2155
2158
|
}
|
|
2156
2159
|
add(a) {
|
|
2157
2160
|
while (this.totalChars() + a.raw.length > this.maxTotalChars && this.artifacts.size > 0) {
|
|
2158
|
-
this.
|
|
2161
|
+
this.evictSizeWeighted();
|
|
2159
2162
|
}
|
|
2160
2163
|
while (this.artifacts.size >= this.maxArtifacts) {
|
|
2161
2164
|
this.evictOldest();
|
|
@@ -2196,6 +2199,21 @@ var init_session_state = __esm({
|
|
|
2196
2199
|
}
|
|
2197
2200
|
if (oldest) this.artifacts.delete(oldest.id);
|
|
2198
2201
|
}
|
|
2202
|
+
/** Evict the largest artifact among the oldest quartile (by timestamp).
|
|
2203
|
+
* Bounded by the oldest quartile so we never evict freshly-added artifacts;
|
|
2204
|
+
* size-weighted within that window so one big artifact gets dropped instead
|
|
2205
|
+
* of many small ones. */
|
|
2206
|
+
evictSizeWeighted() {
|
|
2207
|
+
const sorted = [...this.artifacts.values()].sort((a, b) => a.ts < b.ts ? -1 : 1);
|
|
2208
|
+
if (sorted.length === 0) return;
|
|
2209
|
+
const quartile = Math.max(1, Math.ceil(sorted.length / 4));
|
|
2210
|
+
const candidates = sorted.slice(0, quartile);
|
|
2211
|
+
let pick3 = candidates[0];
|
|
2212
|
+
for (const a of candidates) {
|
|
2213
|
+
if (a.raw.length > pick3.raw.length) pick3 = a;
|
|
2214
|
+
}
|
|
2215
|
+
this.artifacts.delete(pick3.id);
|
|
2216
|
+
}
|
|
2199
2217
|
};
|
|
2200
2218
|
}
|
|
2201
2219
|
});
|
|
@@ -3404,7 +3422,8 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
3404
3422
|
cloudMode: opts2.cloudMode,
|
|
3405
3423
|
cloudToken: opts2.cloudToken,
|
|
3406
3424
|
cloudDeviceId: opts2.cloudDeviceId,
|
|
3407
|
-
idleTimeoutMs: 6e4
|
|
3425
|
+
idleTimeoutMs: opts2.idleTimeoutMs ?? 6e4,
|
|
3426
|
+
postFirstByteIdleTimeoutMs: opts2.postFirstByteIdleTimeoutMs
|
|
3408
3427
|
});
|
|
3409
3428
|
let gotFirstChunk = false;
|
|
3410
3429
|
for await (const ev of events) {
|
|
@@ -3454,7 +3473,7 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
3454
3473
|
if (lastUsage) {
|
|
3455
3474
|
opts2.callbacks.onUsageFinal?.(lastUsage, gatewayMeta);
|
|
3456
3475
|
cumulativePromptTokens += lastUsage.prompt_tokens;
|
|
3457
|
-
if (!budgetExhausted && opts2.maxInputTokens !== void 0 && opts2.maxInputTokens > 0 && cumulativePromptTokens >= opts2.maxInputTokens
|
|
3476
|
+
if (!budgetExhausted && opts2.maxInputTokens !== void 0 && opts2.maxInputTokens > 0 && cumulativePromptTokens >= opts2.maxInputTokens) {
|
|
3458
3477
|
budgetExhausted = true;
|
|
3459
3478
|
}
|
|
3460
3479
|
}
|
|
@@ -3693,7 +3712,22 @@ ${sandboxResult.output}` : sandboxResult.output;
|
|
|
3693
3712
|
}
|
|
3694
3713
|
}
|
|
3695
3714
|
}
|
|
3696
|
-
} catch {
|
|
3715
|
+
} catch (err) {
|
|
3716
|
+
const sid = opts2.sessionId ?? "default";
|
|
3717
|
+
const next = (memoryExtractionErrorCounts.get(sid) ?? 0) + 1;
|
|
3718
|
+
memoryExtractionErrorCounts.set(sid, next);
|
|
3719
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3720
|
+
logger.debug("memory:extract_error", {
|
|
3721
|
+
sessionId: opts2.sessionId,
|
|
3722
|
+
tool: tc.function.name,
|
|
3723
|
+
count: next,
|
|
3724
|
+
error: msg
|
|
3725
|
+
});
|
|
3726
|
+
if (next === 1) {
|
|
3727
|
+
opts2.callbacks.onWarning?.(
|
|
3728
|
+
`[memory] auto-extraction failed (${msg}). Subsequent failures will be counted silently; check /memory health.`
|
|
3729
|
+
);
|
|
3730
|
+
}
|
|
3697
3731
|
}
|
|
3698
3732
|
})();
|
|
3699
3733
|
}
|
|
@@ -3770,7 +3804,7 @@ function validateToolArguments(raw) {
|
|
|
3770
3804
|
return "{}";
|
|
3771
3805
|
}
|
|
3772
3806
|
}
|
|
3773
|
-
var BudgetExhaustedError, AgentLoopError, codeModeApiCache, driftAccumulator, DRIFT_THRESHOLD, MAX_PROMPT_TOKENS, MAX_TOOL_CONTENT_CHARS;
|
|
3807
|
+
var BudgetExhaustedError, AgentLoopError, codeModeApiCache, driftAccumulator, DRIFT_THRESHOLD, memoryExtractionErrorCounts, MAX_PROMPT_TOKENS, MAX_TOOL_CONTENT_CHARS;
|
|
3774
3808
|
var init_loop = __esm({
|
|
3775
3809
|
"src/agent/loop.ts"() {
|
|
3776
3810
|
"use strict";
|
|
@@ -3800,6 +3834,7 @@ var init_loop = __esm({
|
|
|
3800
3834
|
codeModeApiCache = /* @__PURE__ */ new Map();
|
|
3801
3835
|
driftAccumulator = /* @__PURE__ */ new Map();
|
|
3802
3836
|
DRIFT_THRESHOLD = 5;
|
|
3837
|
+
memoryExtractionErrorCounts = /* @__PURE__ */ new Map();
|
|
3803
3838
|
MAX_PROMPT_TOKENS = 24e4;
|
|
3804
3839
|
MAX_TOOL_CONTENT_CHARS = 1e4;
|
|
3805
3840
|
}
|
|
@@ -3867,10 +3902,13 @@ var init_read = __esm({
|
|
|
3867
3902
|
needsPermission: false,
|
|
3868
3903
|
render: ({ path }) => ({ title: `read ${collapsePath(path, process.cwd())}` }),
|
|
3869
3904
|
async run(args, ctx) {
|
|
3905
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
3870
3906
|
const abs = resolvePath(ctx.cwd, args.path);
|
|
3871
3907
|
const st = await stat2(abs);
|
|
3872
3908
|
if (st.size > MAX_BYTES) throw new Error(`file too large: ${st.size} bytes (max ${MAX_BYTES})`);
|
|
3873
|
-
|
|
3909
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
3910
|
+
const text = await readFile3(abs, { encoding: "utf8", signal: ctx.signal });
|
|
3911
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
3874
3912
|
const lines = text.split("\n");
|
|
3875
3913
|
const start = Math.max(0, (args.offset ?? 1) - 1);
|
|
3876
3914
|
const end = args.limit ? Math.min(lines.length, start + args.limit) : lines.length;
|
|
@@ -4162,14 +4200,31 @@ var init_glob = __esm({
|
|
|
4162
4200
|
needsPermission: false,
|
|
4163
4201
|
render: (args) => ({ title: `glob ${args.pattern ?? ""}${args.path ? ` in ${collapsePath(String(args.path), process.cwd())}` : ""}` }),
|
|
4164
4202
|
async run(args, ctx) {
|
|
4203
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
4165
4204
|
const root = args.path ? resolvePath(ctx.cwd, args.path) : ctx.cwd;
|
|
4166
|
-
const
|
|
4205
|
+
const stream = fg.stream(args.pattern, {
|
|
4167
4206
|
cwd: root,
|
|
4168
4207
|
absolute: true,
|
|
4169
4208
|
dot: false,
|
|
4170
4209
|
onlyFiles: false,
|
|
4171
4210
|
stats: true
|
|
4172
4211
|
});
|
|
4212
|
+
const entries = [];
|
|
4213
|
+
const onAbort = () => {
|
|
4214
|
+
try {
|
|
4215
|
+
stream.destroy(new DOMException("aborted", "AbortError"));
|
|
4216
|
+
} catch {
|
|
4217
|
+
}
|
|
4218
|
+
};
|
|
4219
|
+
ctx.signal?.addEventListener("abort", onAbort, { once: true });
|
|
4220
|
+
try {
|
|
4221
|
+
for await (const entry of stream) {
|
|
4222
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
4223
|
+
entries.push(entry);
|
|
4224
|
+
}
|
|
4225
|
+
} finally {
|
|
4226
|
+
ctx.signal?.removeEventListener("abort", onAbort);
|
|
4227
|
+
}
|
|
4173
4228
|
entries.sort((a, b) => (b.stats?.mtimeMs ?? 0) - (a.stats?.mtimeMs ?? 0));
|
|
4174
4229
|
const paths = entries.slice(0, 200).map((e) => e.path);
|
|
4175
4230
|
return paths.length ? paths.join("\n") : "(no matches)";
|
|
@@ -4193,14 +4248,14 @@ async function hasRipgrep() {
|
|
|
4193
4248
|
}
|
|
4194
4249
|
return cachedHasRg;
|
|
4195
4250
|
}
|
|
4196
|
-
async function runRipgrep(args, root, mode) {
|
|
4251
|
+
async function runRipgrep(args, root, mode, signal) {
|
|
4197
4252
|
const rgArgs = ["--no-heading", "--color=never", "--line-number"];
|
|
4198
4253
|
if (args.case_insensitive) rgArgs.push("-i");
|
|
4199
4254
|
if (args.glob) rgArgs.push("--glob", args.glob);
|
|
4200
4255
|
if (mode === "files") rgArgs.push("-l");
|
|
4201
4256
|
rgArgs.push("--", args.pattern, root);
|
|
4202
4257
|
try {
|
|
4203
|
-
const { stdout } = await pExecFile("rg", rgArgs, { maxBuffer: 10 * 1024 * 1024 });
|
|
4258
|
+
const { stdout } = await pExecFile("rg", rgArgs, { maxBuffer: 10 * 1024 * 1024, signal });
|
|
4204
4259
|
const trimmed = stdout.trim();
|
|
4205
4260
|
if (!trimmed) return { content: "(no matches)", rawBytes: 0, reducedBytes: 0 };
|
|
4206
4261
|
return {
|
|
@@ -4214,7 +4269,7 @@ async function runRipgrep(args, root, mode) {
|
|
|
4214
4269
|
throw new Error(err.stderr || String(e));
|
|
4215
4270
|
}
|
|
4216
4271
|
}
|
|
4217
|
-
async function runJsFallback(args, root, mode) {
|
|
4272
|
+
async function runJsFallback(args, root, mode, signal) {
|
|
4218
4273
|
const re = new RegExp(args.pattern, args.case_insensitive ? "i" : "");
|
|
4219
4274
|
const globPattern = args.glob ? `**/${args.glob}` : "**/*";
|
|
4220
4275
|
const files = await fg2(globPattern, {
|
|
@@ -4225,7 +4280,9 @@ async function runJsFallback(args, root, mode) {
|
|
|
4225
4280
|
ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**"]
|
|
4226
4281
|
});
|
|
4227
4282
|
const out = [];
|
|
4228
|
-
for (
|
|
4283
|
+
for (let fi = 0; fi < Math.min(files.length, 5e3); fi++) {
|
|
4284
|
+
if (signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
4285
|
+
const file = files[fi];
|
|
4229
4286
|
try {
|
|
4230
4287
|
const content = await readFile6(file, "utf8");
|
|
4231
4288
|
if (mode === "files") {
|
|
@@ -4280,10 +4337,11 @@ var init_grep = __esm({
|
|
|
4280
4337
|
needsPermission: false,
|
|
4281
4338
|
render: (args) => ({ title: `grep ${args.pattern ?? ""}${args.glob ? ` (${args.glob})` : ""}` }),
|
|
4282
4339
|
async run(args, ctx) {
|
|
4340
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
4283
4341
|
const root = args.path ? resolvePath(ctx.cwd, args.path) : ctx.cwd;
|
|
4284
4342
|
const mode = args.output_mode ?? "content";
|
|
4285
|
-
if (await hasRipgrep()) return runRipgrep(args, root, mode);
|
|
4286
|
-
return runJsFallback(args, root, mode);
|
|
4343
|
+
if (await hasRipgrep()) return runRipgrep(args, root, mode, ctx.signal);
|
|
4344
|
+
return runJsFallback(args, root, mode, ctx.signal);
|
|
4287
4345
|
}
|
|
4288
4346
|
};
|
|
4289
4347
|
}
|
|
@@ -9098,6 +9156,8 @@ var init_pricing = __esm({
|
|
|
9098
9156
|
import { readFile as readFile13, writeFile as writeFile10, mkdir as mkdir10 } from "fs/promises";
|
|
9099
9157
|
import { homedir as homedir11 } from "os";
|
|
9100
9158
|
import { join as join18 } from "path";
|
|
9159
|
+
import { EventEmitter as EventEmitter2 } from "events";
|
|
9160
|
+
import { randomUUID } from "crypto";
|
|
9101
9161
|
function usageDir2() {
|
|
9102
9162
|
const xdg = process.env.XDG_DATA_HOME || join18(homedir11(), ".local", "share");
|
|
9103
9163
|
return join18(xdg, "kimiflare");
|
|
@@ -9128,6 +9188,11 @@ async function saveLog(log2) {
|
|
|
9128
9188
|
await mkdir10(usageDir2(), { recursive: true });
|
|
9129
9189
|
await writeFile10(usagePath2(), JSON.stringify(log2, null, 2), "utf8");
|
|
9130
9190
|
}
|
|
9191
|
+
function withLock(fn) {
|
|
9192
|
+
const next = writeChain.then(fn, fn);
|
|
9193
|
+
writeChain = next.catch(() => void 0);
|
|
9194
|
+
return next;
|
|
9195
|
+
}
|
|
9131
9196
|
async function loadHistory() {
|
|
9132
9197
|
try {
|
|
9133
9198
|
const raw = await readFile13(historyPath(), "utf8");
|
|
@@ -9229,34 +9294,100 @@ function pruneUsageLog(log2) {
|
|
|
9229
9294
|
return { ...log2, days, sessions };
|
|
9230
9295
|
}
|
|
9231
9296
|
async function recordUsage(sessionId, usage, gateway) {
|
|
9232
|
-
const
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
|
|
9236
|
-
|
|
9237
|
-
const
|
|
9238
|
-
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
|
|
9244
|
-
day
|
|
9245
|
-
day.
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
|
|
9253
|
-
session.
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
|
|
9257
|
-
|
|
9258
|
-
|
|
9259
|
-
|
|
9297
|
+
const cost = calculateCost(
|
|
9298
|
+
usage.prompt_tokens,
|
|
9299
|
+
usage.completion_tokens,
|
|
9300
|
+
usage.prompt_tokens_details?.cached_tokens ?? 0
|
|
9301
|
+
);
|
|
9302
|
+
const estimatedCost = cost.total;
|
|
9303
|
+
const cachedTokens = usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
9304
|
+
const turnId = randomUUID();
|
|
9305
|
+
const logId = gateway?.meta.logId;
|
|
9306
|
+
await withLock(async () => {
|
|
9307
|
+
const log2 = pruneUsageLog(await loadLog2());
|
|
9308
|
+
const date = today2();
|
|
9309
|
+
const day = getOrCreateDay(log2, date);
|
|
9310
|
+
day.promptTokens += usage.prompt_tokens;
|
|
9311
|
+
day.completionTokens += usage.completion_tokens;
|
|
9312
|
+
day.cachedTokens += cachedTokens;
|
|
9313
|
+
day.cost += estimatedCost;
|
|
9314
|
+
const session = getOrCreateSession(log2, sessionId, date);
|
|
9315
|
+
session.promptTokens += usage.prompt_tokens;
|
|
9316
|
+
session.completionTokens += usage.completion_tokens;
|
|
9317
|
+
session.cachedTokens += cachedTokens;
|
|
9318
|
+
session.cost += estimatedCost;
|
|
9319
|
+
const turn = {
|
|
9320
|
+
turnId,
|
|
9321
|
+
logId,
|
|
9322
|
+
estimatedCost,
|
|
9323
|
+
cacheStatus: gateway?.meta.cacheStatus
|
|
9324
|
+
};
|
|
9325
|
+
session.turns = [...session.turns ?? [], turn].slice(-MAX_TURNS_PER_SESSION);
|
|
9326
|
+
if (gateway) {
|
|
9327
|
+
const stub = gatewaySnapshotFromMeta(gateway.meta);
|
|
9328
|
+
if (stub) {
|
|
9329
|
+
session.gatewayRequests = (session.gatewayRequests ?? 0) + 1;
|
|
9330
|
+
session.gatewayCachedRequests = (session.gatewayCachedRequests ?? 0) + (stub.cached ? 1 : 0);
|
|
9331
|
+
session.gatewayLogs = [...session.gatewayLogs ?? [], stub].slice(-100);
|
|
9332
|
+
day.gatewayRequests = (day.gatewayRequests ?? 0) + 1;
|
|
9333
|
+
day.gatewayCachedRequests = (day.gatewayCachedRequests ?? 0) + (stub.cached ? 1 : 0);
|
|
9334
|
+
}
|
|
9335
|
+
}
|
|
9336
|
+
await saveLog(log2);
|
|
9337
|
+
await upsertHistoryDay(day);
|
|
9338
|
+
});
|
|
9339
|
+
usageEvents.emit("update", sessionId);
|
|
9340
|
+
if (gateway && logId) {
|
|
9341
|
+
void reconcileTurnCost(sessionId, turnId, gateway).catch(() => void 0);
|
|
9342
|
+
}
|
|
9343
|
+
}
|
|
9344
|
+
async function reconcileTurnCost(sessionId, turnId, gateway) {
|
|
9345
|
+
for (const delay of RECONCILE_DELAYS_MS) {
|
|
9346
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
9347
|
+
let snapshot;
|
|
9348
|
+
try {
|
|
9349
|
+
snapshot = await fetchGatewayUsageSnapshot(gateway);
|
|
9350
|
+
} catch {
|
|
9351
|
+
continue;
|
|
9352
|
+
}
|
|
9353
|
+
if (!snapshot || typeof snapshot.cost !== "number") continue;
|
|
9354
|
+
const patched = await withLock(async () => {
|
|
9355
|
+
const log2 = pruneUsageLog(await loadLog2());
|
|
9356
|
+
const session = log2.sessions.find((s) => s.id === sessionId);
|
|
9357
|
+
const turn = session?.turns?.find((t) => t.turnId === turnId);
|
|
9358
|
+
if (!session || !turn || turn.confirmedCost !== void 0) return false;
|
|
9359
|
+
const delta = snapshot.cost - turn.estimatedCost;
|
|
9360
|
+
turn.confirmedCost = snapshot.cost;
|
|
9361
|
+
turn.durationMs = snapshot.duration;
|
|
9362
|
+
turn.cacheStatus = snapshot.cacheStatus ?? turn.cacheStatus;
|
|
9363
|
+
turn.reconciledAt = Date.now();
|
|
9364
|
+
session.cost += delta;
|
|
9365
|
+
session.gatewayCost = (session.gatewayCost ?? 0) + snapshot.cost;
|
|
9366
|
+
const day = getOrCreateDay(log2, session.date);
|
|
9367
|
+
day.cost += delta;
|
|
9368
|
+
day.gatewayCost = (day.gatewayCost ?? 0) + snapshot.cost;
|
|
9369
|
+
const logs = session.gatewayLogs ?? [];
|
|
9370
|
+
const idx = snapshot.logId ? logs.findIndex((l) => l.logId === snapshot.logId) : -1;
|
|
9371
|
+
if (idx >= 0) logs[idx] = snapshot;
|
|
9372
|
+
else logs.push(snapshot);
|
|
9373
|
+
session.gatewayLogs = logs.slice(-100);
|
|
9374
|
+
await saveLog(log2);
|
|
9375
|
+
await upsertHistoryDay(day);
|
|
9376
|
+
return true;
|
|
9377
|
+
});
|
|
9378
|
+
if (patched) {
|
|
9379
|
+
usageEvents.emit("update", sessionId);
|
|
9380
|
+
}
|
|
9381
|
+
return;
|
|
9382
|
+
}
|
|
9383
|
+
await withLock(async () => {
|
|
9384
|
+
const log2 = await loadLog2();
|
|
9385
|
+
const turn = log2.sessions.find((s) => s.id === sessionId)?.turns?.find((t) => t.turnId === turnId);
|
|
9386
|
+
if (!turn || turn.confirmedCost !== void 0) return;
|
|
9387
|
+
turn.reconcileFailed = true;
|
|
9388
|
+
await saveLog(log2);
|
|
9389
|
+
});
|
|
9390
|
+
usageEvents.emit("update", sessionId);
|
|
9260
9391
|
}
|
|
9261
9392
|
function mergeDays(usageDays, historyDays) {
|
|
9262
9393
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -9270,7 +9401,18 @@ async function getCostReport(sessionId) {
|
|
|
9270
9401
|
const allDays = mergeDays(log2.days, history);
|
|
9271
9402
|
const date = today2();
|
|
9272
9403
|
const currentMonth = date.slice(0, 7);
|
|
9273
|
-
const
|
|
9404
|
+
const rawSession = sessionId ? log2.sessions.find((s) => s.id === sessionId) : void 0;
|
|
9405
|
+
const session = rawSession ? {
|
|
9406
|
+
date: rawSession.date,
|
|
9407
|
+
promptTokens: rawSession.promptTokens,
|
|
9408
|
+
completionTokens: rawSession.completionTokens,
|
|
9409
|
+
cachedTokens: rawSession.cachedTokens,
|
|
9410
|
+
cost: rawSession.cost,
|
|
9411
|
+
gatewayRequests: rawSession.gatewayRequests,
|
|
9412
|
+
gatewayCachedRequests: rawSession.gatewayCachedRequests,
|
|
9413
|
+
gatewayCost: rawSession.gatewayCost,
|
|
9414
|
+
reconcilePending: hasPendingReconcile(rawSession)
|
|
9415
|
+
} : { date, promptTokens: 0, completionTokens: 0, cachedTokens: 0, cost: 0 };
|
|
9274
9416
|
const todayUsage = log2.days.find((d) => d.date === date) ?? { date, promptTokens: 0, completionTokens: 0, cachedTokens: 0, cost: 0 };
|
|
9275
9417
|
const monthUsage = {
|
|
9276
9418
|
date: currentMonth,
|
|
@@ -9308,6 +9450,12 @@ async function getCostReport(sessionId) {
|
|
|
9308
9450
|
}
|
|
9309
9451
|
return { session, today: todayUsage, month: monthUsage, allTime };
|
|
9310
9452
|
}
|
|
9453
|
+
function hasPendingReconcile(session) {
|
|
9454
|
+
if (!session.turns) return false;
|
|
9455
|
+
return session.turns.some(
|
|
9456
|
+
(t) => t.logId && t.confirmedCost === void 0 && !t.reconcileFailed
|
|
9457
|
+
);
|
|
9458
|
+
}
|
|
9311
9459
|
async function getSessionGatewayLogs(sessionId) {
|
|
9312
9460
|
const log2 = await loadLog2();
|
|
9313
9461
|
const session = log2.sessions.find((s) => s.id === sessionId);
|
|
@@ -9367,7 +9515,7 @@ function formatCostReport(report) {
|
|
|
9367
9515
|
add("All time", report.allTime);
|
|
9368
9516
|
return lines.join("\n");
|
|
9369
9517
|
}
|
|
9370
|
-
var LOG_VERSION2;
|
|
9518
|
+
var LOG_VERSION2, usageEvents, MAX_TURNS_PER_SESSION, RECONCILE_DELAYS_MS, writeChain;
|
|
9371
9519
|
var init_usage_tracker = __esm({
|
|
9372
9520
|
"src/usage-tracker.ts"() {
|
|
9373
9521
|
"use strict";
|
|
@@ -9375,6 +9523,10 @@ var init_usage_tracker = __esm({
|
|
|
9375
9523
|
init_pricing();
|
|
9376
9524
|
init_storage_limits();
|
|
9377
9525
|
LOG_VERSION2 = 1;
|
|
9526
|
+
usageEvents = new EventEmitter2();
|
|
9527
|
+
MAX_TURNS_PER_SESSION = 50;
|
|
9528
|
+
RECONCILE_DELAYS_MS = [500, 1e3, 2e3, 4e3];
|
|
9529
|
+
writeChain = Promise.resolve();
|
|
9378
9530
|
}
|
|
9379
9531
|
});
|
|
9380
9532
|
|
|
@@ -11523,6 +11675,10 @@ function StatusBar({ usage, sessionUsage, thinking, turnStartedAt, mode, context
|
|
|
11523
11675
|
] }),
|
|
11524
11676
|
usage && /* @__PURE__ */ jsxs8(Box8, { children: [
|
|
11525
11677
|
/* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget).join(" \xB7 ") }),
|
|
11678
|
+
sessionUsage?.reconcilePending ? /* @__PURE__ */ jsxs8(Text8, { color: theme.muted?.color ?? theme.info.color, dimColor: theme.muted?.dim ?? true, children: [
|
|
11679
|
+
" ",
|
|
11680
|
+
/* @__PURE__ */ jsx9(Spinner3, { type: "dots" })
|
|
11681
|
+
] }) : null,
|
|
11526
11682
|
warn ? /* @__PURE__ */ jsxs8(Text8, { color: theme.warn, bold: true, children: [
|
|
11527
11683
|
" \xB7 ",
|
|
11528
11684
|
"/compact recommended"
|
|
@@ -11542,10 +11698,11 @@ function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMo
|
|
|
11542
11698
|
const cached = sessionUsage.cachedTokens;
|
|
11543
11699
|
parts.push(`in ${sessionUsage.promptTokens}${cached ? ` (${cached} cached)` : ""}`);
|
|
11544
11700
|
parts.push(`ctx ${pct}%`);
|
|
11701
|
+
const prefix = sessionUsage.reconcilePending ? "\u2248$" : "$";
|
|
11545
11702
|
if (cloudMode) {
|
|
11546
|
-
parts.push(`\x1B[9m
|
|
11703
|
+
parts.push(`\x1B[9m${prefix}${sessionUsage.cost.toFixed(2)}\x1B[29m`);
|
|
11547
11704
|
} else {
|
|
11548
|
-
parts.push(
|
|
11705
|
+
parts.push(`${prefix}${sessionUsage.cost.toFixed(2)}`);
|
|
11549
11706
|
}
|
|
11550
11707
|
} else {
|
|
11551
11708
|
const cached = usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
@@ -17804,6 +17961,210 @@ var init_slash_picker = __esm({
|
|
|
17804
17961
|
}
|
|
17805
17962
|
});
|
|
17806
17963
|
|
|
17964
|
+
// src/ui/use-picker-controller.ts
|
|
17965
|
+
import { useCallback as useCallback5, useEffect as useEffect7, useMemo as useMemo2, useRef as useRef4, useState as useState14 } from "react";
|
|
17966
|
+
function filterPickerItems(items, query) {
|
|
17967
|
+
return fuzzyFilter(items, query, (item) => item.name).slice(0, 50);
|
|
17968
|
+
}
|
|
17969
|
+
function shouldOpenMentionPicker(input, cursorOffset, pickerCancelOffset) {
|
|
17970
|
+
if (pickerCancelOffset === cursorOffset) return false;
|
|
17971
|
+
if (cursorOffset > 0 && input[cursorOffset - 1] === "@") {
|
|
17972
|
+
const beforeAt = cursorOffset - 2;
|
|
17973
|
+
return beforeAt < 0 || /\s/.test(input[beforeAt]);
|
|
17974
|
+
}
|
|
17975
|
+
return false;
|
|
17976
|
+
}
|
|
17977
|
+
function shouldOpenSlashPicker(input, cursorOffset, cancelOffset) {
|
|
17978
|
+
if (cancelOffset === cursorOffset) return false;
|
|
17979
|
+
if (cursorOffset === 0 || input[cursorOffset - 1] !== "/") return false;
|
|
17980
|
+
return /^\s*$/.test(input.slice(0, cursorOffset - 1));
|
|
17981
|
+
}
|
|
17982
|
+
function insertSlashCommand(input, anchor, name) {
|
|
17983
|
+
let tokenEnd = anchor + 1;
|
|
17984
|
+
while (tokenEnd < input.length && !/\s/.test(input[tokenEnd])) tokenEnd++;
|
|
17985
|
+
const head = input.slice(0, anchor + 1) + name;
|
|
17986
|
+
const tail = " " + input.slice(tokenEnd).replace(/^\s+/, "");
|
|
17987
|
+
return { value: head + tail, cursor: head.length + 1 };
|
|
17988
|
+
}
|
|
17989
|
+
function decidePickerTransition(active, input, cursorOffset, pickerCancelOffset, filePickerEnabled) {
|
|
17990
|
+
if (active !== null) {
|
|
17991
|
+
const trigger = active.kind === "file" ? "@" : "/";
|
|
17992
|
+
if (cursorOffset < active.anchor) return { kind: "close" };
|
|
17993
|
+
if (input[active.anchor] !== trigger) return { kind: "close" };
|
|
17994
|
+
const query = input.slice(active.anchor + 1, cursorOffset);
|
|
17995
|
+
if (/\s/.test(query)) return { kind: "close" };
|
|
17996
|
+
return { kind: "none" };
|
|
17997
|
+
}
|
|
17998
|
+
if (pickerCancelOffset === cursorOffset) {
|
|
17999
|
+
return { kind: "dropCancel" };
|
|
18000
|
+
}
|
|
18001
|
+
if (filePickerEnabled && shouldOpenMentionPicker(input, cursorOffset, pickerCancelOffset)) {
|
|
18002
|
+
return {
|
|
18003
|
+
kind: "open",
|
|
18004
|
+
picker: { kind: "file", anchor: cursorOffset - 1, selected: 0 },
|
|
18005
|
+
loadFiles: true
|
|
18006
|
+
};
|
|
18007
|
+
}
|
|
18008
|
+
if (shouldOpenSlashPicker(input, cursorOffset, pickerCancelOffset)) {
|
|
18009
|
+
return {
|
|
18010
|
+
kind: "open",
|
|
18011
|
+
picker: { kind: "slash", anchor: cursorOffset - 1, selected: 0 },
|
|
18012
|
+
loadFiles: false
|
|
18013
|
+
};
|
|
18014
|
+
}
|
|
18015
|
+
return { kind: "none" };
|
|
18016
|
+
}
|
|
18017
|
+
function usePickerController(opts2) {
|
|
18018
|
+
const {
|
|
18019
|
+
input,
|
|
18020
|
+
cursorOffset,
|
|
18021
|
+
setInput,
|
|
18022
|
+
setCursorOffset,
|
|
18023
|
+
filePickerEnabled,
|
|
18024
|
+
allSlashCommands,
|
|
18025
|
+
modalActive,
|
|
18026
|
+
loadFilePickerItems,
|
|
18027
|
+
onFileSelected,
|
|
18028
|
+
onSlashSelected,
|
|
18029
|
+
getRecentFiles
|
|
18030
|
+
} = opts2;
|
|
18031
|
+
const [active, setActive] = useState14(null);
|
|
18032
|
+
const [fileItemsRaw, setFileItemsRaw] = useState14([]);
|
|
18033
|
+
const filesLoadedRef = useRef4(false);
|
|
18034
|
+
const cancelOffsetRef = useRef4(null);
|
|
18035
|
+
const onFileSelectedRef = useRef4(onFileSelected);
|
|
18036
|
+
onFileSelectedRef.current = onFileSelected;
|
|
18037
|
+
const onSlashSelectedRef = useRef4(onSlashSelected);
|
|
18038
|
+
onSlashSelectedRef.current = onSlashSelected;
|
|
18039
|
+
const getRecentFilesRef = useRef4(getRecentFiles);
|
|
18040
|
+
getRecentFilesRef.current = getRecentFiles;
|
|
18041
|
+
const loadFilePickerItemsRef = useRef4(loadFilePickerItems);
|
|
18042
|
+
loadFilePickerItemsRef.current = loadFilePickerItems;
|
|
18043
|
+
const activeAnchor = active?.anchor ?? null;
|
|
18044
|
+
const activeKind = active?.kind ?? null;
|
|
18045
|
+
const query = useMemo2(() => {
|
|
18046
|
+
if (activeAnchor === null) return "";
|
|
18047
|
+
return input.slice(activeAnchor + 1, cursorOffset);
|
|
18048
|
+
}, [input, cursorOffset, activeAnchor]);
|
|
18049
|
+
const fileItems = useMemo2(() => {
|
|
18050
|
+
if (activeKind !== "file") return [];
|
|
18051
|
+
const items = filterPickerItems(fileItemsRaw, query).slice();
|
|
18052
|
+
const recents = getRecentFilesRef.current();
|
|
18053
|
+
return items.sort((a, b) => {
|
|
18054
|
+
const aRecent = recents.get(a.name) ?? 0;
|
|
18055
|
+
const bRecent = recents.get(b.name) ?? 0;
|
|
18056
|
+
if (aRecent && !bRecent) return -1;
|
|
18057
|
+
if (!aRecent && bRecent) return 1;
|
|
18058
|
+
if (aRecent && bRecent) return bRecent - aRecent;
|
|
18059
|
+
if (a.isDirectory && !b.isDirectory) return -1;
|
|
18060
|
+
if (!a.isDirectory && b.isDirectory) return 1;
|
|
18061
|
+
return a.name.localeCompare(b.name);
|
|
18062
|
+
});
|
|
18063
|
+
}, [activeKind, fileItemsRaw, query]);
|
|
18064
|
+
const slashItems = useMemo2(() => {
|
|
18065
|
+
if (activeKind !== "slash") return [];
|
|
18066
|
+
return fuzzyFilter(allSlashCommands, query, (c) => c.name).slice(0, 50);
|
|
18067
|
+
}, [activeKind, allSlashCommands, query]);
|
|
18068
|
+
useEffect7(() => {
|
|
18069
|
+
const t = decidePickerTransition(
|
|
18070
|
+
active,
|
|
18071
|
+
input,
|
|
18072
|
+
cursorOffset,
|
|
18073
|
+
cancelOffsetRef.current,
|
|
18074
|
+
filePickerEnabled
|
|
18075
|
+
);
|
|
18076
|
+
if (t.kind === "close") {
|
|
18077
|
+
setActive(null);
|
|
18078
|
+
return;
|
|
18079
|
+
}
|
|
18080
|
+
if (t.kind === "dropCancel") {
|
|
18081
|
+
cancelOffsetRef.current = null;
|
|
18082
|
+
return;
|
|
18083
|
+
}
|
|
18084
|
+
if (t.kind === "open") {
|
|
18085
|
+
setActive(t.picker);
|
|
18086
|
+
if (t.loadFiles && !filesLoadedRef.current) {
|
|
18087
|
+
filesLoadedRef.current = true;
|
|
18088
|
+
void loadFilePickerItemsRef.current().then((items) => setFileItemsRaw(items)).catch(() => setFileItemsRaw([]));
|
|
18089
|
+
}
|
|
18090
|
+
}
|
|
18091
|
+
}, [input, cursorOffset, active, filePickerEnabled]);
|
|
18092
|
+
useEffect7(() => {
|
|
18093
|
+
if (active?.kind !== "file") return;
|
|
18094
|
+
const max = Math.max(0, fileItems.length - 1);
|
|
18095
|
+
if (active.selected > max) {
|
|
18096
|
+
setActive({ ...active, selected: max });
|
|
18097
|
+
}
|
|
18098
|
+
}, [fileItems.length, active]);
|
|
18099
|
+
useEffect7(() => {
|
|
18100
|
+
if (active?.kind !== "slash") return;
|
|
18101
|
+
const max = Math.max(0, slashItems.length - 1);
|
|
18102
|
+
if (active.selected > max) {
|
|
18103
|
+
setActive({ ...active, selected: max });
|
|
18104
|
+
}
|
|
18105
|
+
}, [slashItems.length, active]);
|
|
18106
|
+
useEffect7(() => {
|
|
18107
|
+
if (modalActive && active !== null) {
|
|
18108
|
+
setActive(null);
|
|
18109
|
+
}
|
|
18110
|
+
}, [modalActive, active]);
|
|
18111
|
+
const onUp = useCallback5(() => {
|
|
18112
|
+
setActive((p) => {
|
|
18113
|
+
if (!p) return null;
|
|
18114
|
+
const next = Math.max(0, p.selected - 1);
|
|
18115
|
+
return next === p.selected ? p : { ...p, selected: next };
|
|
18116
|
+
});
|
|
18117
|
+
}, []);
|
|
18118
|
+
const onDown = useCallback5(() => {
|
|
18119
|
+
setActive((p) => {
|
|
18120
|
+
if (!p) return null;
|
|
18121
|
+
const max = p.kind === "file" ? Math.max(0, fileItems.length - 1) : Math.max(0, slashItems.length - 1);
|
|
18122
|
+
const next = Math.min(max, p.selected + 1);
|
|
18123
|
+
return next === p.selected ? p : { ...p, selected: next };
|
|
18124
|
+
});
|
|
18125
|
+
}, [fileItems.length, slashItems.length]);
|
|
18126
|
+
const onSelect = useCallback5(() => {
|
|
18127
|
+
if (!active) return;
|
|
18128
|
+
if (active.kind === "file") {
|
|
18129
|
+
const item2 = fileItems[active.selected];
|
|
18130
|
+
if (!item2) return;
|
|
18131
|
+
onFileSelectedRef.current?.(item2.name);
|
|
18132
|
+
const insert = item2.name + (item2.isDirectory ? "/" : " ");
|
|
18133
|
+
const newInput = input.slice(0, active.anchor) + insert + input.slice(cursorOffset);
|
|
18134
|
+
setInput(newInput);
|
|
18135
|
+
setCursorOffset(active.anchor + insert.length);
|
|
18136
|
+
setActive(null);
|
|
18137
|
+
return;
|
|
18138
|
+
}
|
|
18139
|
+
const item = slashItems[active.selected];
|
|
18140
|
+
if (!item) return;
|
|
18141
|
+
const { value } = insertSlashCommand(input, active.anchor, item.name);
|
|
18142
|
+
setActive(null);
|
|
18143
|
+
onSlashSelectedRef.current(value);
|
|
18144
|
+
}, [active, fileItems, slashItems, input, cursorOffset, setInput, setCursorOffset]);
|
|
18145
|
+
const onCancel = useCallback5(() => {
|
|
18146
|
+
cancelOffsetRef.current = cursorOffset;
|
|
18147
|
+
setActive(null);
|
|
18148
|
+
}, [cursorOffset]);
|
|
18149
|
+
return {
|
|
18150
|
+
active,
|
|
18151
|
+
isActive: active !== null,
|
|
18152
|
+
query,
|
|
18153
|
+
fileItems,
|
|
18154
|
+
slashItems,
|
|
18155
|
+
onUp,
|
|
18156
|
+
onDown,
|
|
18157
|
+
onSelect,
|
|
18158
|
+
onCancel
|
|
18159
|
+
};
|
|
18160
|
+
}
|
|
18161
|
+
var init_use_picker_controller = __esm({
|
|
18162
|
+
"src/ui/use-picker-controller.ts"() {
|
|
18163
|
+
"use strict";
|
|
18164
|
+
init_fuzzy();
|
|
18165
|
+
}
|
|
18166
|
+
});
|
|
18167
|
+
|
|
17807
18168
|
// src/cost-attribution/tui-report.ts
|
|
17808
18169
|
var tui_report_exports = {};
|
|
17809
18170
|
__export(tui_report_exports, {
|
|
@@ -17889,13 +18250,9 @@ var init_tui_report = __esm({
|
|
|
17889
18250
|
var app_exports = {};
|
|
17890
18251
|
__export(app_exports, {
|
|
17891
18252
|
buildFilePickerIgnoreList: () => buildFilePickerIgnoreList,
|
|
17892
|
-
|
|
17893
|
-
insertSlashCommand: () => insertSlashCommand,
|
|
17894
|
-
renderApp: () => renderApp,
|
|
17895
|
-
shouldOpenMentionPicker: () => shouldOpenMentionPicker,
|
|
17896
|
-
shouldOpenSlashPicker: () => shouldOpenSlashPicker
|
|
18253
|
+
renderApp: () => renderApp
|
|
17897
18254
|
});
|
|
17898
|
-
import React15, { useState as
|
|
18255
|
+
import React15, { useState as useState15, useRef as useRef5, useEffect as useEffect8, useCallback as useCallback6 } from "react";
|
|
17899
18256
|
import { Box as Box25, Text as Text26, useApp, useInput as useInput10, render } from "ink";
|
|
17900
18257
|
import SelectInput9 from "ink-select-input";
|
|
17901
18258
|
import { existsSync as existsSync4, statSync as statSync4 } from "fs";
|
|
@@ -18004,29 +18361,6 @@ function buildFilePickerIgnoreList(cwd) {
|
|
|
18004
18361
|
}
|
|
18005
18362
|
return [...hardcoded, ...gitignorePatterns];
|
|
18006
18363
|
}
|
|
18007
|
-
function filterPickerItems(items, query) {
|
|
18008
|
-
return fuzzyFilter(items, query, (item) => item.name).slice(0, 50);
|
|
18009
|
-
}
|
|
18010
|
-
function shouldOpenMentionPicker(input, cursorOffset, pickerCancelOffset) {
|
|
18011
|
-
if (pickerCancelOffset === cursorOffset) return false;
|
|
18012
|
-
if (cursorOffset > 0 && input[cursorOffset - 1] === "@") {
|
|
18013
|
-
const beforeAt = cursorOffset - 2;
|
|
18014
|
-
return beforeAt < 0 || /\s/.test(input[beforeAt]);
|
|
18015
|
-
}
|
|
18016
|
-
return false;
|
|
18017
|
-
}
|
|
18018
|
-
function shouldOpenSlashPicker(input, cursorOffset, cancelOffset) {
|
|
18019
|
-
if (cancelOffset === cursorOffset) return false;
|
|
18020
|
-
if (cursorOffset === 0 || input[cursorOffset - 1] !== "/") return false;
|
|
18021
|
-
return /^\s*$/.test(input.slice(0, cursorOffset - 1));
|
|
18022
|
-
}
|
|
18023
|
-
function insertSlashCommand(input, anchor, name) {
|
|
18024
|
-
let tokenEnd = anchor + 1;
|
|
18025
|
-
while (tokenEnd < input.length && !/\s/.test(input[tokenEnd])) tokenEnd++;
|
|
18026
|
-
const head = input.slice(0, anchor + 1) + name;
|
|
18027
|
-
const tail = " " + input.slice(tokenEnd).replace(/^\s+/, "");
|
|
18028
|
-
return { value: head + tail, cursor: head.length + 1 };
|
|
18029
|
-
}
|
|
18030
18364
|
function gatewayFromConfig(cfg) {
|
|
18031
18365
|
if (process.env.KIMIFLARE_DISABLE_AI_GATEWAY === "1") return void 0;
|
|
18032
18366
|
if (!cfg.aiGatewayId) return void 0;
|
|
@@ -18158,13 +18492,13 @@ function App({
|
|
|
18158
18492
|
initialCloudDeviceId
|
|
18159
18493
|
}) {
|
|
18160
18494
|
const { exit } = useApp();
|
|
18161
|
-
const [cfg, setCfg] =
|
|
18162
|
-
const [lspScope, setLspScope] =
|
|
18163
|
-
const [lspProjectPath, setLspProjectPath] =
|
|
18164
|
-
const [cloudToken, setCloudToken] =
|
|
18165
|
-
const [cloudDeviceId, setCloudDeviceId] =
|
|
18166
|
-
const [events, setRawEvents] =
|
|
18167
|
-
const setEvents =
|
|
18495
|
+
const [cfg, setCfg] = useState15(initialCfg);
|
|
18496
|
+
const [lspScope, setLspScope] = useState15(initialLspScope);
|
|
18497
|
+
const [lspProjectPath, setLspProjectPath] = useState15(initialLspProjectPath);
|
|
18498
|
+
const [cloudToken, setCloudToken] = useState15(initialCloudToken);
|
|
18499
|
+
const [cloudDeviceId, setCloudDeviceId] = useState15(initialCloudDeviceId);
|
|
18500
|
+
const [events, setRawEvents] = useState15([]);
|
|
18501
|
+
const setEvents = useCallback6(
|
|
18168
18502
|
(updater) => {
|
|
18169
18503
|
setRawEvents((prev) => {
|
|
18170
18504
|
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
@@ -18173,13 +18507,24 @@ function App({
|
|
|
18173
18507
|
},
|
|
18174
18508
|
[]
|
|
18175
18509
|
);
|
|
18176
|
-
const [input, setInput] =
|
|
18177
|
-
const [busy, setBusy] =
|
|
18178
|
-
const [usage, setUsage] =
|
|
18179
|
-
const [sessionUsage, setSessionUsage] =
|
|
18180
|
-
|
|
18181
|
-
|
|
18182
|
-
|
|
18510
|
+
const [input, setInput] = useState15("");
|
|
18511
|
+
const [busy, setBusy] = useState15(false);
|
|
18512
|
+
const [usage, setUsage] = useState15(null);
|
|
18513
|
+
const [sessionUsage, setSessionUsage] = useState15(null);
|
|
18514
|
+
useEffect8(() => {
|
|
18515
|
+
const handler = (sid) => {
|
|
18516
|
+
if (sessionIdRef.current && sid === sessionIdRef.current) {
|
|
18517
|
+
void getCostReport(sid).then((report) => setSessionUsage(report.session));
|
|
18518
|
+
}
|
|
18519
|
+
};
|
|
18520
|
+
usageEvents.on("update", handler);
|
|
18521
|
+
return () => {
|
|
18522
|
+
usageEvents.off("update", handler);
|
|
18523
|
+
};
|
|
18524
|
+
}, []);
|
|
18525
|
+
const [gatewayMeta, setGatewayMeta] = useState15(null);
|
|
18526
|
+
const [cloudBudget, setCloudBudget] = useState15(null);
|
|
18527
|
+
const [showReasoning, setShowReasoning] = useState15(false);
|
|
18183
18528
|
const {
|
|
18184
18529
|
pending: perm,
|
|
18185
18530
|
askPermission: askForPermission,
|
|
@@ -18200,52 +18545,52 @@ function App({
|
|
|
18200
18545
|
]);
|
|
18201
18546
|
}
|
|
18202
18547
|
);
|
|
18203
|
-
const [limitModal, setLimitModal] =
|
|
18204
|
-
const [loopModal, setLoopModal] =
|
|
18205
|
-
const [queue, setQueue] =
|
|
18206
|
-
const [history, setHistory] =
|
|
18207
|
-
const [historyIndex, setHistoryIndex] =
|
|
18208
|
-
const [draftInput, setDraftInput] =
|
|
18209
|
-
const [mode, setMode] =
|
|
18210
|
-
const [codeMode, setCodeMode] =
|
|
18548
|
+
const [limitModal, setLimitModal] = useState15(null);
|
|
18549
|
+
const [loopModal, setLoopModal] = useState15(null);
|
|
18550
|
+
const [queue, setQueue] = useState15([]);
|
|
18551
|
+
const [history, setHistory] = useState15([]);
|
|
18552
|
+
const [historyIndex, setHistoryIndex] = useState15(-1);
|
|
18553
|
+
const [draftInput, setDraftInput] = useState15("");
|
|
18554
|
+
const [mode, setMode] = useState15("edit");
|
|
18555
|
+
const [codeMode, setCodeMode] = useState15(false);
|
|
18211
18556
|
const filePickerEnabled = initialCfg?.filePicker ?? true;
|
|
18212
|
-
const [effort, setEffort] =
|
|
18557
|
+
const [effort, setEffort] = useState15(
|
|
18213
18558
|
initialCfg?.reasoningEffort ?? DEFAULT_REASONING_EFFORT
|
|
18214
18559
|
);
|
|
18215
|
-
const [resumeSessions, setResumeSessions] =
|
|
18216
|
-
const [checkpointSession, setCheckpointSession] =
|
|
18217
|
-
const [checkpointList, setCheckpointList] =
|
|
18218
|
-
const [commandWizard, setCommandWizard] =
|
|
18219
|
-
const [commandPicker, setCommandPicker] =
|
|
18220
|
-
const [commandToDelete, setCommandToDelete] =
|
|
18221
|
-
const [showCommandList, setShowCommandList] =
|
|
18222
|
-
const [showLspWizard, setShowLspWizard] =
|
|
18223
|
-
const [showRemoteDashboard, setShowRemoteDashboard] =
|
|
18224
|
-
const [selectedRemoteSession, setSelectedRemoteSession] =
|
|
18225
|
-
const [showInboxModal, setShowInboxModal] =
|
|
18226
|
-
const [tasks, setTasks] =
|
|
18227
|
-
const [tasksStartedAt, setTasksStartedAt] =
|
|
18228
|
-
const [tasksStartTokens, setTasksStartTokens] =
|
|
18229
|
-
const [turnStartedAt, setTurnStartedAt] =
|
|
18230
|
-
const [turnPhase, setTurnPhase] =
|
|
18231
|
-
const [currentToolName, setCurrentToolName] =
|
|
18232
|
-
const [lastActivityAt, setLastActivityAt] =
|
|
18233
|
-
const [verbose, setVerbose] =
|
|
18234
|
-
const [hasUpdate, setHasUpdate] =
|
|
18235
|
-
const [latestVersion, setLatestVersion] =
|
|
18236
|
-
const [theme, setTheme] =
|
|
18237
|
-
const [showThemePicker, setShowThemePicker] =
|
|
18238
|
-
const [originalTheme, setOriginalTheme] =
|
|
18239
|
-
const [skillsActive, setSkillsActive] =
|
|
18240
|
-
const [memoryRecalled, setMemoryRecalled] =
|
|
18241
|
-
const [intentTier, setIntentTier] =
|
|
18242
|
-
const [kimiMdStale, setKimiMdStale] =
|
|
18243
|
-
const [gitBranch, setGitBranch] =
|
|
18244
|
-
const [lastSessionTopic, setLastSessionTopic] =
|
|
18245
|
-
|
|
18560
|
+
const [resumeSessions, setResumeSessions] = useState15(null);
|
|
18561
|
+
const [checkpointSession, setCheckpointSession] = useState15(null);
|
|
18562
|
+
const [checkpointList, setCheckpointList] = useState15([]);
|
|
18563
|
+
const [commandWizard, setCommandWizard] = useState15(null);
|
|
18564
|
+
const [commandPicker, setCommandPicker] = useState15(null);
|
|
18565
|
+
const [commandToDelete, setCommandToDelete] = useState15(null);
|
|
18566
|
+
const [showCommandList, setShowCommandList] = useState15(false);
|
|
18567
|
+
const [showLspWizard, setShowLspWizard] = useState15(false);
|
|
18568
|
+
const [showRemoteDashboard, setShowRemoteDashboard] = useState15(false);
|
|
18569
|
+
const [selectedRemoteSession, setSelectedRemoteSession] = useState15(null);
|
|
18570
|
+
const [showInboxModal, setShowInboxModal] = useState15(false);
|
|
18571
|
+
const [tasks, setTasks] = useState15([]);
|
|
18572
|
+
const [tasksStartedAt, setTasksStartedAt] = useState15(null);
|
|
18573
|
+
const [tasksStartTokens, setTasksStartTokens] = useState15(0);
|
|
18574
|
+
const [turnStartedAt, setTurnStartedAt] = useState15(null);
|
|
18575
|
+
const [turnPhase, setTurnPhase] = useState15("waiting");
|
|
18576
|
+
const [currentToolName, setCurrentToolName] = useState15(null);
|
|
18577
|
+
const [lastActivityAt, setLastActivityAt] = useState15(null);
|
|
18578
|
+
const [verbose, setVerbose] = useState15(false);
|
|
18579
|
+
const [hasUpdate, setHasUpdate] = useState15(initialUpdateResult?.hasUpdate ?? false);
|
|
18580
|
+
const [latestVersion, setLatestVersion] = useState15(initialUpdateResult?.latestVersion ?? null);
|
|
18581
|
+
const [theme, setTheme] = useState15(resolveTheme(initialCfg?.theme));
|
|
18582
|
+
const [showThemePicker, setShowThemePicker] = useState15(false);
|
|
18583
|
+
const [originalTheme, setOriginalTheme] = useState15(null);
|
|
18584
|
+
const [skillsActive, setSkillsActive] = useState15(0);
|
|
18585
|
+
const [memoryRecalled, setMemoryRecalled] = useState15(false);
|
|
18586
|
+
const [intentTier, setIntentTier] = useState15(null);
|
|
18587
|
+
const [kimiMdStale, setKimiMdStale] = useState15(false);
|
|
18588
|
+
const [gitBranch, setGitBranch] = useState15(null);
|
|
18589
|
+
const [lastSessionTopic, setLastSessionTopic] = useState15(null);
|
|
18590
|
+
useEffect8(() => {
|
|
18246
18591
|
setGitBranch(detectGitBranch());
|
|
18247
18592
|
}, []);
|
|
18248
|
-
|
|
18593
|
+
useEffect8(() => {
|
|
18249
18594
|
void Promise.resolve().then(() => (init_sessions(), sessions_exports)).then(
|
|
18250
18595
|
({ listSessions: listSessions2 }) => listSessions2(1).then((sessions) => {
|
|
18251
18596
|
const last = sessions[0];
|
|
@@ -18255,7 +18600,7 @@ function App({
|
|
|
18255
18600
|
})
|
|
18256
18601
|
);
|
|
18257
18602
|
}, []);
|
|
18258
|
-
|
|
18603
|
+
useEffect8(() => {
|
|
18259
18604
|
const onSigint = () => {
|
|
18260
18605
|
logger.info("sigint:fired", {
|
|
18261
18606
|
hasHandler: sigintHandlerRef.current !== null
|
|
@@ -18267,7 +18612,7 @@ function App({
|
|
|
18267
18612
|
process.off("SIGINT", onSigint);
|
|
18268
18613
|
};
|
|
18269
18614
|
}, []);
|
|
18270
|
-
|
|
18615
|
+
useEffect8(() => {
|
|
18271
18616
|
let cancelled = false;
|
|
18272
18617
|
loadAndMergeThemes().then(({ errors, wcagWarnings }) => {
|
|
18273
18618
|
if (cancelled) return;
|
|
@@ -18291,7 +18636,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18291
18636
|
cancelled = true;
|
|
18292
18637
|
};
|
|
18293
18638
|
}, []);
|
|
18294
|
-
|
|
18639
|
+
useEffect8(() => {
|
|
18295
18640
|
if (!cfg?.cloudMode || !initialCloudToken) return;
|
|
18296
18641
|
let cancelled = false;
|
|
18297
18642
|
const fetchBudget = async () => {
|
|
@@ -18317,81 +18662,56 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18317
18662
|
cancelled = true;
|
|
18318
18663
|
};
|
|
18319
18664
|
}, [cfg?.cloudMode, initialCloudToken]);
|
|
18320
|
-
const [cursorOffset, setCursorOffset] =
|
|
18321
|
-
const [
|
|
18322
|
-
const
|
|
18323
|
-
const
|
|
18324
|
-
const [customCommandsVersion, setCustomCommandsVersion] = useState14(0);
|
|
18325
|
-
const cacheStableRef = useRef4(initialCfg?.cacheStablePrompts !== false);
|
|
18326
|
-
const messagesRef = useRef4(
|
|
18665
|
+
const [cursorOffset, setCursorOffset] = useState15(0);
|
|
18666
|
+
const [customCommandsVersion, setCustomCommandsVersion] = useState15(0);
|
|
18667
|
+
const cacheStableRef = useRef5(initialCfg?.cacheStablePrompts !== false);
|
|
18668
|
+
const messagesRef = useRef5(
|
|
18327
18669
|
makePrefixMessages(cacheStableRef.current, cfg?.model ?? DEFAULT_MODEL, "edit", ALL_TOOLS)
|
|
18328
18670
|
);
|
|
18329
|
-
const executorRef =
|
|
18330
|
-
const activeAsstIdRef =
|
|
18331
|
-
const sessionScopeRef =
|
|
18332
|
-
const activeScopeRef =
|
|
18333
|
-
const supervisorRef =
|
|
18334
|
-
const isAbortingRef =
|
|
18335
|
-
const lastEscapeAtRef =
|
|
18336
|
-
const sigintHandlerRef =
|
|
18337
|
-
const limitResolveRef =
|
|
18338
|
-
const loopResolveRef =
|
|
18339
|
-
const pendingToolCallsRef =
|
|
18340
|
-
const sessionIdRef =
|
|
18341
|
-
const sessionCreatedAtRef =
|
|
18342
|
-
const sessionTitleRef =
|
|
18343
|
-
const modeRef =
|
|
18344
|
-
const effortRef =
|
|
18345
|
-
const tasksRef =
|
|
18346
|
-
const usageRef =
|
|
18347
|
-
const gatewayMetaRef =
|
|
18348
|
-
const lastApiErrorRef =
|
|
18349
|
-
const updateCheckedRef =
|
|
18350
|
-
const sessionStateRef =
|
|
18351
|
-
const artifactStoreRef =
|
|
18352
|
-
const compiledContextRef =
|
|
18353
|
-
const updateNudgedRef =
|
|
18354
|
-
const compactSuggestedRef =
|
|
18355
|
-
const mcpManagerRef =
|
|
18356
|
-
const mcpToolsRef =
|
|
18357
|
-
const mcpInitRef =
|
|
18358
|
-
const submitRef =
|
|
18671
|
+
const executorRef = useRef5(new ToolExecutor(ALL_TOOLS));
|
|
18672
|
+
const activeAsstIdRef = useRef5(null);
|
|
18673
|
+
const sessionScopeRef = useRef5(new AbortScope());
|
|
18674
|
+
const activeScopeRef = useRef5(null);
|
|
18675
|
+
const supervisorRef = useRef5(new TurnSupervisor());
|
|
18676
|
+
const isAbortingRef = useRef5(false);
|
|
18677
|
+
const lastEscapeAtRef = useRef5(0);
|
|
18678
|
+
const sigintHandlerRef = useRef5(null);
|
|
18679
|
+
const limitResolveRef = useRef5(null);
|
|
18680
|
+
const loopResolveRef = useRef5(null);
|
|
18681
|
+
const pendingToolCallsRef = useRef5(/* @__PURE__ */ new Map());
|
|
18682
|
+
const sessionIdRef = useRef5(null);
|
|
18683
|
+
const sessionCreatedAtRef = useRef5(null);
|
|
18684
|
+
const sessionTitleRef = useRef5(null);
|
|
18685
|
+
const modeRef = useRef5(mode);
|
|
18686
|
+
const effortRef = useRef5(effort);
|
|
18687
|
+
const tasksRef = useRef5([]);
|
|
18688
|
+
const usageRef = useRef5(null);
|
|
18689
|
+
const gatewayMetaRef = useRef5(null);
|
|
18690
|
+
const lastApiErrorRef = useRef5(null);
|
|
18691
|
+
const updateCheckedRef = useRef5(false);
|
|
18692
|
+
const sessionStateRef = useRef5(emptySessionState());
|
|
18693
|
+
const artifactStoreRef = useRef5(new ArtifactStore());
|
|
18694
|
+
const compiledContextRef = useRef5(initialCfg?.compiledContext === true);
|
|
18695
|
+
const updateNudgedRef = useRef5(false);
|
|
18696
|
+
const compactSuggestedRef = useRef5(false);
|
|
18697
|
+
const mcpManagerRef = useRef5(new McpManager());
|
|
18698
|
+
const mcpToolsRef = useRef5([]);
|
|
18699
|
+
const mcpInitRef = useRef5(false);
|
|
18700
|
+
const submitRef = useRef5(() => {
|
|
18359
18701
|
});
|
|
18360
|
-
const lspManagerRef =
|
|
18361
|
-
const lspToolsRef =
|
|
18362
|
-
const lspInitRef =
|
|
18363
|
-
const busyRef =
|
|
18364
|
-
const memoryManagerRef =
|
|
18365
|
-
const sessionStartRecallRef =
|
|
18366
|
-
const kimiMdStaleNudgedRef =
|
|
18367
|
-
const turnCounterRef =
|
|
18368
|
-
const pendingTextRef =
|
|
18369
|
-
const flushTimeoutRef =
|
|
18370
|
-
const customCommandsRef =
|
|
18371
|
-
const
|
|
18372
|
-
const recentFilesRef = useRef4(/* @__PURE__ */ new Map());
|
|
18702
|
+
const lspManagerRef = useRef5(new LspManager());
|
|
18703
|
+
const lspToolsRef = useRef5([]);
|
|
18704
|
+
const lspInitRef = useRef5(false);
|
|
18705
|
+
const busyRef = useRef5(busy);
|
|
18706
|
+
const memoryManagerRef = useRef5(null);
|
|
18707
|
+
const sessionStartRecallRef = useRef5(null);
|
|
18708
|
+
const kimiMdStaleNudgedRef = useRef5(false);
|
|
18709
|
+
const turnCounterRef = useRef5(0);
|
|
18710
|
+
const pendingTextRef = useRef5(/* @__PURE__ */ new Map());
|
|
18711
|
+
const flushTimeoutRef = useRef5(null);
|
|
18712
|
+
const customCommandsRef = useRef5([]);
|
|
18713
|
+
const recentFilesRef = useRef5(/* @__PURE__ */ new Map());
|
|
18373
18714
|
const MAX_RECENT_FILES = 10;
|
|
18374
|
-
const pickerAnchor = activePicker?.anchor ?? null;
|
|
18375
|
-
const pickerKind = activePicker?.kind ?? null;
|
|
18376
|
-
const pickerQuery = React15.useMemo(() => {
|
|
18377
|
-
if (pickerAnchor === null) return null;
|
|
18378
|
-
return input.slice(pickerAnchor + 1, cursorOffset);
|
|
18379
|
-
}, [input, cursorOffset, pickerAnchor]);
|
|
18380
|
-
const filteredFileItems = React15.useMemo(() => {
|
|
18381
|
-
if (pickerKind !== "file" || pickerQuery === null) return [];
|
|
18382
|
-
const items = filterPickerItems(filePickerItems, pickerQuery).slice();
|
|
18383
|
-
const now2 = Date.now();
|
|
18384
|
-
return items.sort((a, b) => {
|
|
18385
|
-
const aRecent = recentFilesRef.current.get(a.name) ?? 0;
|
|
18386
|
-
const bRecent = recentFilesRef.current.get(b.name) ?? 0;
|
|
18387
|
-
if (aRecent && !bRecent) return -1;
|
|
18388
|
-
if (!aRecent && bRecent) return 1;
|
|
18389
|
-
if (aRecent && bRecent) return bRecent - aRecent;
|
|
18390
|
-
if (a.isDirectory && !b.isDirectory) return -1;
|
|
18391
|
-
if (!a.isDirectory && b.isDirectory) return 1;
|
|
18392
|
-
return a.name.localeCompare(b.name);
|
|
18393
|
-
});
|
|
18394
|
-
}, [pickerKind, filePickerItems, pickerQuery]);
|
|
18395
18715
|
const allSlashCommands = React15.useMemo(() => {
|
|
18396
18716
|
const customs = customCommandsRef.current.filter((c) => !BUILTIN_COMMAND_NAMES.has(c.name.toLowerCase())).map((c) => ({
|
|
18397
18717
|
name: c.name,
|
|
@@ -18400,138 +18720,43 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18400
18720
|
}));
|
|
18401
18721
|
return [...BUILTIN_COMMANDS, ...customs];
|
|
18402
18722
|
}, [customCommandsVersion]);
|
|
18403
|
-
const
|
|
18404
|
-
|
|
18405
|
-
|
|
18406
|
-
|
|
18407
|
-
|
|
18408
|
-
|
|
18409
|
-
|
|
18410
|
-
|
|
18411
|
-
|
|
18412
|
-
|
|
18413
|
-
}
|
|
18414
|
-
if (input[activePicker.anchor] !== trigger) {
|
|
18415
|
-
setActivePicker(null);
|
|
18416
|
-
return;
|
|
18417
|
-
}
|
|
18418
|
-
const query = input.slice(activePicker.anchor + 1, cursorOffset);
|
|
18419
|
-
if (/\s/.test(query)) {
|
|
18420
|
-
setActivePicker(null);
|
|
18421
|
-
return;
|
|
18422
|
-
}
|
|
18423
|
-
return;
|
|
18424
|
-
}
|
|
18425
|
-
if (pickerCancelRef.current === cursorOffset) {
|
|
18426
|
-
pickerCancelRef.current = null;
|
|
18427
|
-
return;
|
|
18428
|
-
}
|
|
18429
|
-
if (filePickerEnabled && shouldOpenMentionPicker(input, cursorOffset, pickerCancelRef.current)) {
|
|
18430
|
-
setActivePicker({ kind: "file", anchor: cursorOffset - 1, selected: 0 });
|
|
18431
|
-
if (!filePickerLoadedRef.current) {
|
|
18432
|
-
filePickerLoadedRef.current = true;
|
|
18433
|
-
const cwd = process.cwd();
|
|
18434
|
-
void fg4("**/*", {
|
|
18435
|
-
cwd,
|
|
18436
|
-
ignore: buildFilePickerIgnoreList(cwd),
|
|
18437
|
-
dot: false,
|
|
18438
|
-
absolute: false,
|
|
18439
|
-
onlyFiles: false,
|
|
18440
|
-
markDirectories: true
|
|
18441
|
-
}).then((entries) => {
|
|
18442
|
-
const strings = entries.slice(0, 300);
|
|
18443
|
-
const items = strings.map((e) => ({
|
|
18444
|
-
name: e.endsWith("/") ? e.slice(0, -1) : e,
|
|
18445
|
-
isDirectory: e.endsWith("/")
|
|
18446
|
-
}));
|
|
18447
|
-
items.sort((a, b) => {
|
|
18448
|
-
if (a.isDirectory && !b.isDirectory) return -1;
|
|
18449
|
-
if (!a.isDirectory && b.isDirectory) return 1;
|
|
18450
|
-
return a.name.localeCompare(b.name);
|
|
18451
|
-
});
|
|
18452
|
-
setFilePickerItems(items);
|
|
18453
|
-
}).catch(() => {
|
|
18454
|
-
setFilePickerItems([]);
|
|
18455
|
-
});
|
|
18456
|
-
}
|
|
18457
|
-
return;
|
|
18458
|
-
}
|
|
18459
|
-
if (shouldOpenSlashPicker(input, cursorOffset, pickerCancelRef.current)) {
|
|
18460
|
-
setActivePicker({ kind: "slash", anchor: cursorOffset - 1, selected: 0 });
|
|
18461
|
-
return;
|
|
18462
|
-
}
|
|
18463
|
-
}, [input, cursorOffset, activePicker, filePickerEnabled]);
|
|
18464
|
-
useEffect7(() => {
|
|
18465
|
-
if (activePicker?.kind !== "file") return;
|
|
18466
|
-
const max = Math.max(0, filteredFileItems.length - 1);
|
|
18467
|
-
if (activePicker.selected > max) {
|
|
18468
|
-
setActivePicker({ ...activePicker, selected: max });
|
|
18469
|
-
}
|
|
18470
|
-
}, [filteredFileItems.length, activePicker]);
|
|
18471
|
-
useEffect7(() => {
|
|
18472
|
-
if (activePicker?.kind !== "slash") return;
|
|
18473
|
-
const max = Math.max(0, filteredSlashItems.length - 1);
|
|
18474
|
-
if (activePicker.selected > max) {
|
|
18475
|
-
setActivePicker({ ...activePicker, selected: max });
|
|
18476
|
-
}
|
|
18477
|
-
}, [filteredSlashItems.length, activePicker]);
|
|
18478
|
-
const handlePickerUp = useCallback5(() => {
|
|
18479
|
-
setActivePicker((p) => {
|
|
18480
|
-
if (!p) return null;
|
|
18481
|
-
const next = Math.max(0, p.selected - 1);
|
|
18482
|
-
return next === p.selected ? p : { ...p, selected: next };
|
|
18723
|
+
const modalActive = commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || checkpointSession !== null || perm !== null || limitModal !== null || loopModal !== null || showInboxModal;
|
|
18724
|
+
const loadFilePickerItems = useCallback6(async () => {
|
|
18725
|
+
const cwd = process.cwd();
|
|
18726
|
+
const entries = await fg4("**/*", {
|
|
18727
|
+
cwd,
|
|
18728
|
+
ignore: buildFilePickerIgnoreList(cwd),
|
|
18729
|
+
dot: false,
|
|
18730
|
+
absolute: false,
|
|
18731
|
+
onlyFiles: false,
|
|
18732
|
+
markDirectories: true
|
|
18483
18733
|
});
|
|
18484
|
-
|
|
18485
|
-
|
|
18486
|
-
|
|
18487
|
-
|
|
18488
|
-
|
|
18489
|
-
|
|
18490
|
-
|
|
18734
|
+
const strings = entries.slice(0, 300);
|
|
18735
|
+
const items = strings.map((e) => ({
|
|
18736
|
+
name: e.endsWith("/") ? e.slice(0, -1) : e,
|
|
18737
|
+
isDirectory: e.endsWith("/")
|
|
18738
|
+
}));
|
|
18739
|
+
items.sort((a, b) => {
|
|
18740
|
+
if (a.isDirectory && !b.isDirectory) return -1;
|
|
18741
|
+
if (!a.isDirectory && b.isDirectory) return 1;
|
|
18742
|
+
return a.name.localeCompare(b.name);
|
|
18491
18743
|
});
|
|
18492
|
-
|
|
18493
|
-
|
|
18494
|
-
|
|
18495
|
-
|
|
18496
|
-
|
|
18497
|
-
|
|
18498
|
-
|
|
18499
|
-
|
|
18500
|
-
|
|
18501
|
-
|
|
18502
|
-
|
|
18503
|
-
|
|
18504
|
-
|
|
18505
|
-
|
|
18506
|
-
|
|
18507
|
-
|
|
18508
|
-
const { value } = insertSlashCommand(input, activePicker.anchor, item.name);
|
|
18509
|
-
setActivePicker(null);
|
|
18510
|
-
submitRef.current(value);
|
|
18511
|
-
}, [activePicker, filteredFileItems, filteredSlashItems, input, cursorOffset]);
|
|
18512
|
-
const handlePickerCancel = useCallback5(() => {
|
|
18513
|
-
pickerCancelRef.current = cursorOffset;
|
|
18514
|
-
setActivePicker(null);
|
|
18515
|
-
}, [cursorOffset]);
|
|
18516
|
-
useEffect7(() => {
|
|
18517
|
-
const modalActive = commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || checkpointSession !== null || perm !== null || limitModal !== null || loopModal !== null || showInboxModal;
|
|
18518
|
-
if (modalActive && activePicker !== null) {
|
|
18519
|
-
setActivePicker(null);
|
|
18520
|
-
}
|
|
18521
|
-
}, [
|
|
18522
|
-
commandWizard,
|
|
18523
|
-
commandPicker,
|
|
18524
|
-
commandToDelete,
|
|
18525
|
-
showCommandList,
|
|
18526
|
-
showLspWizard,
|
|
18527
|
-
resumeSessions,
|
|
18528
|
-
perm,
|
|
18529
|
-
limitModal,
|
|
18530
|
-
loopModal,
|
|
18531
|
-
showInboxModal,
|
|
18532
|
-
activePicker
|
|
18533
|
-
]);
|
|
18534
|
-
useEffect7(() => {
|
|
18744
|
+
return items;
|
|
18745
|
+
}, []);
|
|
18746
|
+
const picker = usePickerController({
|
|
18747
|
+
input,
|
|
18748
|
+
cursorOffset,
|
|
18749
|
+
setInput,
|
|
18750
|
+
setCursorOffset,
|
|
18751
|
+
filePickerEnabled,
|
|
18752
|
+
allSlashCommands,
|
|
18753
|
+
modalActive,
|
|
18754
|
+
loadFilePickerItems,
|
|
18755
|
+
onFileSelected: (name) => trackRecentFile(recentFilesRef, name, MAX_RECENT_FILES),
|
|
18756
|
+
onSlashSelected: (value) => submitRef.current(value),
|
|
18757
|
+
getRecentFiles: () => recentFilesRef.current
|
|
18758
|
+
});
|
|
18759
|
+
useEffect8(() => {
|
|
18535
18760
|
if (!cfg) return;
|
|
18536
18761
|
void Promise.resolve().then(() => (init_sessions(), sessions_exports)).then(
|
|
18537
18762
|
({ pruneSessions: pruneSessions2 }) => pruneSessions2().then((removed) => {
|
|
@@ -18643,7 +18868,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18643
18868
|
}
|
|
18644
18869
|
});
|
|
18645
18870
|
}, [cfg, setEvents]);
|
|
18646
|
-
|
|
18871
|
+
useEffect8(() => {
|
|
18647
18872
|
const id = setInterval(() => {
|
|
18648
18873
|
try {
|
|
18649
18874
|
performance.clearMarks();
|
|
@@ -18653,7 +18878,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18653
18878
|
}, 3e5);
|
|
18654
18879
|
return () => clearInterval(id);
|
|
18655
18880
|
}, []);
|
|
18656
|
-
const reloadCustomCommands =
|
|
18881
|
+
const reloadCustomCommands = useCallback6(async () => {
|
|
18657
18882
|
const { commands, warnings } = await loadCustomCommands(process.cwd());
|
|
18658
18883
|
customCommandsRef.current = commands;
|
|
18659
18884
|
setCustomCommandsVersion((v) => v + 1);
|
|
@@ -18668,7 +18893,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18668
18893
|
]);
|
|
18669
18894
|
}
|
|
18670
18895
|
}, [setEvents]);
|
|
18671
|
-
|
|
18896
|
+
useEffect8(() => {
|
|
18672
18897
|
if (!cfg || updateCheckedRef.current) return;
|
|
18673
18898
|
updateCheckedRef.current = true;
|
|
18674
18899
|
if (initialUpdateResult) {
|
|
@@ -18719,7 +18944,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18719
18944
|
}
|
|
18720
18945
|
});
|
|
18721
18946
|
}, [cfg, initialUpdateResult]);
|
|
18722
|
-
|
|
18947
|
+
useEffect8(() => {
|
|
18723
18948
|
modeRef.current = mode;
|
|
18724
18949
|
if (cacheStableRef.current) {
|
|
18725
18950
|
messagesRef.current[1] = {
|
|
@@ -18746,10 +18971,10 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18746
18971
|
executorRef.current.clearSessionPermissions();
|
|
18747
18972
|
}
|
|
18748
18973
|
}, [mode, cfg?.model]);
|
|
18749
|
-
|
|
18974
|
+
useEffect8(() => {
|
|
18750
18975
|
effortRef.current = effort;
|
|
18751
18976
|
}, [effort]);
|
|
18752
|
-
|
|
18977
|
+
useEffect8(() => {
|
|
18753
18978
|
if (!cfg) return;
|
|
18754
18979
|
const id = setInterval(() => {
|
|
18755
18980
|
void checkForUpdate().then((result) => {
|
|
@@ -18780,7 +19005,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18780
19005
|
}, 30 * 60 * 1e3);
|
|
18781
19006
|
return () => clearInterval(id);
|
|
18782
19007
|
}, [cfg]);
|
|
18783
|
-
const initMcp =
|
|
19008
|
+
const initMcp = useCallback6(async () => {
|
|
18784
19009
|
if (!cfg?.mcpServers || mcpInitRef.current) return;
|
|
18785
19010
|
mcpInitRef.current = true;
|
|
18786
19011
|
const manager = mcpManagerRef.current;
|
|
@@ -18845,7 +19070,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18845
19070
|
]);
|
|
18846
19071
|
}
|
|
18847
19072
|
}, [cfg]);
|
|
18848
|
-
const initLsp =
|
|
19073
|
+
const initLsp = useCallback6(async () => {
|
|
18849
19074
|
if (!cfg?.lspEnabled || !cfg?.lspServers || lspInitRef.current) {
|
|
18850
19075
|
if (lspInitRef.current) return;
|
|
18851
19076
|
if (!cfg?.lspEnabled) {
|
|
@@ -18908,7 +19133,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18908
19133
|
]);
|
|
18909
19134
|
}
|
|
18910
19135
|
}, [cfg]);
|
|
18911
|
-
|
|
19136
|
+
useEffect8(() => {
|
|
18912
19137
|
if (cfg && !mcpInitRef.current) {
|
|
18913
19138
|
void initMcp();
|
|
18914
19139
|
}
|
|
@@ -18916,7 +19141,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18916
19141
|
void initLsp();
|
|
18917
19142
|
}
|
|
18918
19143
|
}, [cfg, initMcp, initLsp]);
|
|
18919
|
-
const ensureSessionId =
|
|
19144
|
+
const ensureSessionId = useCallback6(() => {
|
|
18920
19145
|
if (sessionIdRef.current) return sessionIdRef.current;
|
|
18921
19146
|
const firstUser = messagesRef.current.find((m) => m.role === "user");
|
|
18922
19147
|
let firstText = "session";
|
|
@@ -18929,7 +19154,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18929
19154
|
sessionIdRef.current = makeSessionId(firstText);
|
|
18930
19155
|
return sessionIdRef.current;
|
|
18931
19156
|
}, []);
|
|
18932
|
-
const saveSessionSafe =
|
|
19157
|
+
const saveSessionSafe = useCallback6(async () => {
|
|
18933
19158
|
if (!cfg) return;
|
|
18934
19159
|
ensureSessionId();
|
|
18935
19160
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -18955,7 +19180,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
18955
19180
|
]);
|
|
18956
19181
|
}
|
|
18957
19182
|
}, [cfg, ensureSessionId]);
|
|
18958
|
-
const onIterationEnd =
|
|
19183
|
+
const onIterationEnd = useCallback6(
|
|
18959
19184
|
async (messages, signal) => {
|
|
18960
19185
|
if (signal.aborted) return messages;
|
|
18961
19186
|
if (!shouldCompact({ messages })) return messages;
|
|
@@ -19156,7 +19381,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19156
19381
|
void lspManagerRef.current.stopAll().finally(() => exit());
|
|
19157
19382
|
}
|
|
19158
19383
|
};
|
|
19159
|
-
const flushAssistantUpdates =
|
|
19384
|
+
const flushAssistantUpdates = useCallback6(() => {
|
|
19160
19385
|
flushTimeoutRef.current = null;
|
|
19161
19386
|
const pending = pendingTextRef.current;
|
|
19162
19387
|
if (pending.size === 0) return;
|
|
@@ -19174,7 +19399,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19174
19399
|
})
|
|
19175
19400
|
);
|
|
19176
19401
|
}, []);
|
|
19177
|
-
const updateAssistant =
|
|
19402
|
+
const updateAssistant = useCallback6(
|
|
19178
19403
|
(id, patch) => {
|
|
19179
19404
|
const result = patch({ text: "", reasoning: "" });
|
|
19180
19405
|
const assistantResult = result;
|
|
@@ -19203,7 +19428,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19203
19428
|
},
|
|
19204
19429
|
[flushAssistantUpdates]
|
|
19205
19430
|
);
|
|
19206
|
-
const updateTool =
|
|
19431
|
+
const updateTool = useCallback6(
|
|
19207
19432
|
(id, patch) => {
|
|
19208
19433
|
setEvents(
|
|
19209
19434
|
(evts) => evts.map(
|
|
@@ -19213,11 +19438,11 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19213
19438
|
},
|
|
19214
19439
|
[]
|
|
19215
19440
|
);
|
|
19216
|
-
const updateGatewayMeta =
|
|
19441
|
+
const updateGatewayMeta = useCallback6((meta) => {
|
|
19217
19442
|
gatewayMetaRef.current = meta;
|
|
19218
19443
|
setGatewayMeta(meta);
|
|
19219
19444
|
}, []);
|
|
19220
|
-
const runCompact =
|
|
19445
|
+
const runCompact = useCallback6(async () => {
|
|
19221
19446
|
if (!cfg) return;
|
|
19222
19447
|
if (busy) {
|
|
19223
19448
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "can't compact while model is running" }]);
|
|
@@ -19313,11 +19538,11 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19313
19538
|
pendingToolCallsRef.current.clear();
|
|
19314
19539
|
}
|
|
19315
19540
|
}, [cfg, busy, saveSessionSafe]);
|
|
19316
|
-
const openResumePicker =
|
|
19541
|
+
const openResumePicker = useCallback6(async () => {
|
|
19317
19542
|
const sessions = await listSessions(200, process.cwd());
|
|
19318
19543
|
setResumeSessions(sessions);
|
|
19319
19544
|
}, []);
|
|
19320
|
-
const runInit =
|
|
19545
|
+
const runInit = useCallback6(async () => {
|
|
19321
19546
|
if (!cfg) return;
|
|
19322
19547
|
if (busy) {
|
|
19323
19548
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "can't /init while model is running" }]);
|
|
@@ -19612,7 +19837,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19612
19837
|
pendingToolCallsRef.current.clear();
|
|
19613
19838
|
}
|
|
19614
19839
|
}, [cfg, busy, updateAssistant, updateTool, updateGatewayMeta]);
|
|
19615
|
-
const handleThemePick =
|
|
19840
|
+
const handleThemePick = useCallback6(
|
|
19616
19841
|
(picked) => {
|
|
19617
19842
|
setShowThemePicker(false);
|
|
19618
19843
|
if (!picked) return;
|
|
@@ -19630,7 +19855,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19630
19855
|
},
|
|
19631
19856
|
[]
|
|
19632
19857
|
);
|
|
19633
|
-
const doResumeSession =
|
|
19858
|
+
const doResumeSession = useCallback6(
|
|
19634
19859
|
async (filePath, checkpointId) => {
|
|
19635
19860
|
try {
|
|
19636
19861
|
const file = checkpointId ? (await loadSessionFromCheckpoint(filePath, checkpointId)).file : await loadSession(filePath);
|
|
@@ -19682,7 +19907,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19682
19907
|
},
|
|
19683
19908
|
[]
|
|
19684
19909
|
);
|
|
19685
|
-
const handleResumePick =
|
|
19910
|
+
const handleResumePick = useCallback6(
|
|
19686
19911
|
async (picked) => {
|
|
19687
19912
|
setResumeSessions(null);
|
|
19688
19913
|
if (!picked) return;
|
|
@@ -19704,7 +19929,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19704
19929
|
},
|
|
19705
19930
|
[doResumeSession]
|
|
19706
19931
|
);
|
|
19707
|
-
const handleCheckpointPick =
|
|
19932
|
+
const handleCheckpointPick = useCallback6(
|
|
19708
19933
|
async (checkpointId) => {
|
|
19709
19934
|
const session = checkpointSession;
|
|
19710
19935
|
setCheckpointSession(null);
|
|
@@ -19723,7 +19948,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19723
19948
|
},
|
|
19724
19949
|
[checkpointSession, doResumeSession]
|
|
19725
19950
|
);
|
|
19726
|
-
const handleSlash =
|
|
19951
|
+
const handleSlash = useCallback6(
|
|
19727
19952
|
(cmd) => {
|
|
19728
19953
|
const raw = cmd.trim();
|
|
19729
19954
|
const [head, ...rest] = raw.split(/\s+/);
|
|
@@ -20696,7 +20921,7 @@ ${lines.join("\n")}` }]);
|
|
|
20696
20921
|
},
|
|
20697
20922
|
[cfg, exit, usage, theme, mode, openResumePicker, runCompact, runInit, initMcp, setCfg, setShowRemoteDashboard, setSelectedRemoteSession]
|
|
20698
20923
|
);
|
|
20699
|
-
const handleCommandSave =
|
|
20924
|
+
const handleCommandSave = useCallback6(
|
|
20700
20925
|
async (opts2) => {
|
|
20701
20926
|
setCommandWizard(null);
|
|
20702
20927
|
try {
|
|
@@ -20718,7 +20943,7 @@ ${lines.join("\n")}` }]);
|
|
|
20718
20943
|
},
|
|
20719
20944
|
[commandWizard, reloadCustomCommands, setEvents]
|
|
20720
20945
|
);
|
|
20721
|
-
const handleCommandDelete =
|
|
20946
|
+
const handleCommandDelete = useCallback6(
|
|
20722
20947
|
async (cmd) => {
|
|
20723
20948
|
setCommandToDelete(null);
|
|
20724
20949
|
try {
|
|
@@ -20737,7 +20962,7 @@ ${lines.join("\n")}` }]);
|
|
|
20737
20962
|
},
|
|
20738
20963
|
[reloadCustomCommands, setEvents]
|
|
20739
20964
|
);
|
|
20740
|
-
const processMessage =
|
|
20965
|
+
const processMessage = useCallback6(
|
|
20741
20966
|
async (text, displayText, opts2) => {
|
|
20742
20967
|
if (!cfg) return;
|
|
20743
20968
|
let trimmed = text.trim();
|
|
@@ -21254,14 +21479,14 @@ ${lines.join("\n")}` }]);
|
|
|
21254
21479
|
},
|
|
21255
21480
|
[cfg, handleSlash, updateAssistant, updateTool, saveSessionSafe, updateGatewayMeta]
|
|
21256
21481
|
);
|
|
21257
|
-
|
|
21482
|
+
useEffect8(() => {
|
|
21258
21483
|
if (!busy && queue.length > 0 && supervisorRef.current.phase === "idle") {
|
|
21259
21484
|
const next = queue[0];
|
|
21260
21485
|
setQueue((q) => q.slice(1));
|
|
21261
21486
|
processMessage(next.full, next.display, { queuedKey: next.key });
|
|
21262
21487
|
}
|
|
21263
21488
|
}, [busy, queue, processMessage]);
|
|
21264
|
-
const submit =
|
|
21489
|
+
const submit = useCallback6(
|
|
21265
21490
|
(full, display) => {
|
|
21266
21491
|
const trimmedFull = full.trim();
|
|
21267
21492
|
if (!trimmedFull) return;
|
|
@@ -21284,7 +21509,7 @@ ${lines.join("\n")}` }]);
|
|
|
21284
21509
|
[processMessage]
|
|
21285
21510
|
);
|
|
21286
21511
|
submitRef.current = submit;
|
|
21287
|
-
|
|
21512
|
+
useEffect8(() => {
|
|
21288
21513
|
if (compactSuggestedRef.current) return;
|
|
21289
21514
|
if (usage && usage.prompt_tokens / CONTEXT_LIMIT >= AUTO_COMPACT_SUGGEST_PCT) {
|
|
21290
21515
|
compactSuggestedRef.current = true;
|
|
@@ -21548,21 +21773,21 @@ ${lines.join("\n")}` }]);
|
|
|
21548
21773
|
intentTier: intentTier ?? void 0
|
|
21549
21774
|
}
|
|
21550
21775
|
),
|
|
21551
|
-
|
|
21776
|
+
picker.active?.kind === "file" && /* @__PURE__ */ jsx27(
|
|
21552
21777
|
FilePicker,
|
|
21553
21778
|
{
|
|
21554
|
-
items:
|
|
21555
|
-
selectedIndex:
|
|
21556
|
-
query:
|
|
21779
|
+
items: picker.fileItems,
|
|
21780
|
+
selectedIndex: picker.active.selected,
|
|
21781
|
+
query: picker.query,
|
|
21557
21782
|
recentFiles: new Set(recentFilesRef.current.keys())
|
|
21558
21783
|
}
|
|
21559
21784
|
),
|
|
21560
|
-
|
|
21785
|
+
picker.active?.kind === "slash" && /* @__PURE__ */ jsx27(
|
|
21561
21786
|
SlashPicker,
|
|
21562
21787
|
{
|
|
21563
|
-
items:
|
|
21564
|
-
selectedIndex:
|
|
21565
|
-
query:
|
|
21788
|
+
items: picker.slashItems,
|
|
21789
|
+
selectedIndex: picker.active.selected,
|
|
21790
|
+
query: picker.query
|
|
21566
21791
|
}
|
|
21567
21792
|
),
|
|
21568
21793
|
/* @__PURE__ */ jsxs25(Box25, { marginTop: 1, children: [
|
|
@@ -21576,11 +21801,11 @@ ${lines.join("\n")}` }]);
|
|
|
21576
21801
|
enablePaste: true,
|
|
21577
21802
|
cursorOffset,
|
|
21578
21803
|
onCursorChange: setCursorOffset,
|
|
21579
|
-
pickerActive:
|
|
21580
|
-
onPickerUp:
|
|
21581
|
-
onPickerDown:
|
|
21582
|
-
onPickerSelect:
|
|
21583
|
-
onPickerCancel:
|
|
21804
|
+
pickerActive: picker.isActive,
|
|
21805
|
+
onPickerUp: picker.onUp,
|
|
21806
|
+
onPickerDown: picker.onDown,
|
|
21807
|
+
onPickerSelect: picker.onSelect,
|
|
21808
|
+
onPickerCancel: picker.onCancel,
|
|
21584
21809
|
onHistoryUp: () => {
|
|
21585
21810
|
if (history.length === 0) return;
|
|
21586
21811
|
if (historyIndex === -1) {
|
|
@@ -21718,7 +21943,7 @@ var init_app = __esm({
|
|
|
21718
21943
|
init_lsp_nudge();
|
|
21719
21944
|
init_file_picker();
|
|
21720
21945
|
init_slash_picker();
|
|
21721
|
-
|
|
21946
|
+
init_use_picker_controller();
|
|
21722
21947
|
MAX_GITIGNORE_SIZE = 1 * 1024 * 1024;
|
|
21723
21948
|
FEEDBACK_WORKER_URL2 = "https://hello.kimiflare.com";
|
|
21724
21949
|
CONTEXT_LIMIT = 262e3;
|