@kmugalkhod/lightcode 0.1.3 → 0.3.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/LICENSE +21 -0
- package/README.md +10 -0
- package/cli.js +1540 -542
- package/package.json +4 -2
- package/server.js +1141 -194
package/cli.js
CHANGED
|
@@ -45,6 +45,14 @@ function getErrorMessage(error, fallback = "Unknown error") {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// packages/shared/src/logger.ts
|
|
48
|
+
import {
|
|
49
|
+
appendFileSync,
|
|
50
|
+
existsSync,
|
|
51
|
+
mkdirSync,
|
|
52
|
+
readdirSync,
|
|
53
|
+
unlinkSync
|
|
54
|
+
} from "fs";
|
|
55
|
+
import path2 from "path";
|
|
48
56
|
function resolveConfiguredLevel() {
|
|
49
57
|
const raw = process.env.LIGHTCODE_LOG_LEVEL?.trim().toLowerCase();
|
|
50
58
|
if (raw === "debug" || raw === "info" || raw === "warn" || raw === "error") {
|
|
@@ -52,6 +60,34 @@ function resolveConfiguredLevel() {
|
|
|
52
60
|
}
|
|
53
61
|
return "info";
|
|
54
62
|
}
|
|
63
|
+
function currentDateStamp() {
|
|
64
|
+
return new Date().toISOString().slice(0, 10);
|
|
65
|
+
}
|
|
66
|
+
function pruneOldLogFiles(directory) {
|
|
67
|
+
try {
|
|
68
|
+
const logFiles = readdirSync(directory).filter((name) => logFilePattern.test(name)).sort();
|
|
69
|
+
for (const name of logFiles.slice(0, -maxLogFilesKept)) {
|
|
70
|
+
unlinkSync(path2.join(directory, name));
|
|
71
|
+
}
|
|
72
|
+
} catch {}
|
|
73
|
+
}
|
|
74
|
+
function writeToFileSink(line) {
|
|
75
|
+
if (!fileSinkPrefix) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const date = currentDateStamp();
|
|
80
|
+
if (!fileSinkState || fileSinkState.date !== date) {
|
|
81
|
+
fileSinkState = {
|
|
82
|
+
date,
|
|
83
|
+
filePath: path2.join(fileSinkPrefix, `server-${date}.log`)
|
|
84
|
+
};
|
|
85
|
+
pruneOldLogFiles(fileSinkPrefix);
|
|
86
|
+
}
|
|
87
|
+
appendFileSync(fileSinkState.filePath, `${line}
|
|
88
|
+
`);
|
|
89
|
+
} catch {}
|
|
90
|
+
}
|
|
55
91
|
function createLogger(name) {
|
|
56
92
|
const write = (level, event, fields) => {
|
|
57
93
|
if (levelOrder[level] < levelOrder[resolveConfiguredLevel()]) {
|
|
@@ -66,6 +102,7 @@ function createLogger(name) {
|
|
|
66
102
|
});
|
|
67
103
|
process.stderr.write(`${line}
|
|
68
104
|
`);
|
|
105
|
+
writeToFileSink(line);
|
|
69
106
|
};
|
|
70
107
|
return {
|
|
71
108
|
debug: (event, fields) => write("debug", event, fields),
|
|
@@ -74,18 +111,20 @@ function createLogger(name) {
|
|
|
74
111
|
error: (event, fields) => write("error", event, fields)
|
|
75
112
|
};
|
|
76
113
|
}
|
|
77
|
-
var levelOrder;
|
|
114
|
+
var levelOrder, maxLogFilesKept = 5, logFilePattern, fileSinkPrefix = null, fileSinkState = null;
|
|
78
115
|
var init_logger = __esm(() => {
|
|
116
|
+
init_data_dir();
|
|
79
117
|
levelOrder = {
|
|
80
118
|
debug: 10,
|
|
81
119
|
info: 20,
|
|
82
120
|
warn: 30,
|
|
83
121
|
error: 40
|
|
84
122
|
};
|
|
123
|
+
logFilePattern = /^server-\d{4}-\d{2}-\d{2}\.log$/;
|
|
85
124
|
});
|
|
86
125
|
|
|
87
126
|
// packages/shared/src/version.ts
|
|
88
|
-
var lightcodeVersion = "0.
|
|
127
|
+
var lightcodeVersion = "0.3.0";
|
|
89
128
|
|
|
90
129
|
// packages/shared/src/index.ts
|
|
91
130
|
var productName = "Lightcode";
|
|
@@ -97,7 +136,7 @@ var init_src = __esm(() => {
|
|
|
97
136
|
// apps/cli/src/lib/api-base-url.ts
|
|
98
137
|
var apiBaseUrl;
|
|
99
138
|
var init_api_base_url = __esm(() => {
|
|
100
|
-
apiBaseUrl = Bun.env.LIGHTCODE_API_URL ?? "http://
|
|
139
|
+
apiBaseUrl = Bun.env.LIGHTCODE_API_URL ?? "http://127.0.0.1:4983";
|
|
101
140
|
});
|
|
102
141
|
|
|
103
142
|
// apps/cli/src/lib/server-launcher.ts
|
|
@@ -107,9 +146,9 @@ __export(exports_server_launcher, {
|
|
|
107
146
|
getOwnedServerProcess: () => getOwnedServerProcess,
|
|
108
147
|
ensureServerRunning: () => ensureServerRunning
|
|
109
148
|
});
|
|
110
|
-
import { existsSync, mkdirSync } from "fs";
|
|
149
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
111
150
|
import { homedir as homedir2, platform as platform2 } from "os";
|
|
112
|
-
import
|
|
151
|
+
import path3 from "path";
|
|
113
152
|
import { fileURLToPath } from "url";
|
|
114
153
|
function getOwnedServerProcess() {
|
|
115
154
|
return currentOwnedProcess;
|
|
@@ -129,22 +168,30 @@ async function restartOwnedServer() {
|
|
|
129
168
|
function getLightcodeDataDir2() {
|
|
130
169
|
const configuredHome = process.env.LIGHTCODE_HOME?.trim();
|
|
131
170
|
if (configuredHome) {
|
|
132
|
-
return
|
|
171
|
+
return path3.resolve(configuredHome);
|
|
133
172
|
}
|
|
134
173
|
if (platform2() === "win32") {
|
|
135
174
|
const appData = process.env.APPDATA || process.env.LOCALAPPDATA;
|
|
136
|
-
return appData ?
|
|
175
|
+
return appData ? path3.join(appData, "lightcode") : path3.join(homedir2(), "AppData", "Roaming", "lightcode");
|
|
137
176
|
}
|
|
138
|
-
return
|
|
177
|
+
return path3.join(homedir2(), ".lightcode");
|
|
139
178
|
}
|
|
140
|
-
async function
|
|
179
|
+
async function checkServer(url) {
|
|
141
180
|
try {
|
|
142
181
|
const response = await fetch(new URL("/config/status", url), {
|
|
143
182
|
signal: AbortSignal.timeout(healthCheckTimeoutMs)
|
|
144
183
|
});
|
|
145
|
-
|
|
184
|
+
if (!response.ok) {
|
|
185
|
+
return "foreign";
|
|
186
|
+
}
|
|
187
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
188
|
+
if (!contentType.includes("application/json")) {
|
|
189
|
+
return "foreign";
|
|
190
|
+
}
|
|
191
|
+
const payload = await response.json();
|
|
192
|
+
return payload && typeof payload === "object" && "selectedProvider" in payload ? "healthy" : "foreign";
|
|
146
193
|
} catch {
|
|
147
|
-
return
|
|
194
|
+
return "down";
|
|
148
195
|
}
|
|
149
196
|
}
|
|
150
197
|
function resolveServerEntry() {
|
|
@@ -152,20 +199,28 @@ function resolveServerEntry() {
|
|
|
152
199
|
fileURLToPath(new URL("./server.js", import.meta.url)),
|
|
153
200
|
fileURLToPath(new URL("../../../server/src/index.ts", import.meta.url))
|
|
154
201
|
];
|
|
155
|
-
return candidates.find((candidate) =>
|
|
202
|
+
return candidates.find((candidate) => existsSync2(candidate)) ?? null;
|
|
156
203
|
}
|
|
157
204
|
async function ensureServerRunning() {
|
|
158
|
-
|
|
205
|
+
const port = new URL(apiBaseUrl).port || "4983";
|
|
206
|
+
const initialHealth = await checkServer(apiBaseUrl);
|
|
207
|
+
if (initialHealth === "healthy") {
|
|
159
208
|
return { url: apiBaseUrl, ownedProcess: null };
|
|
160
209
|
}
|
|
210
|
+
if (initialHealth === "foreign") {
|
|
211
|
+
return {
|
|
212
|
+
url: apiBaseUrl,
|
|
213
|
+
ownedProcess: null,
|
|
214
|
+
error: `Port ${port} is in use by another application (not Lightcode). ` + "Free the port, or point Lightcode elsewhere with " + "LIGHTCODE_API_URL (CLI) and PORT (server)."
|
|
215
|
+
};
|
|
216
|
+
}
|
|
161
217
|
const serverEntry = resolveServerEntry();
|
|
162
218
|
if (!serverEntry) {
|
|
163
219
|
return { url: apiBaseUrl, ownedProcess: null };
|
|
164
220
|
}
|
|
165
|
-
const logDirectory =
|
|
166
|
-
|
|
167
|
-
const logFile = Bun.file(
|
|
168
|
-
const port = new URL(apiBaseUrl).port || "3000";
|
|
221
|
+
const logDirectory = path3.join(getLightcodeDataDir2(), "logs");
|
|
222
|
+
mkdirSync2(logDirectory, { recursive: true });
|
|
223
|
+
const logFile = Bun.file(path3.join(logDirectory, "server.log"));
|
|
169
224
|
const ownedProcess = Bun.spawn([process.execPath, serverEntry], {
|
|
170
225
|
stdout: logFile,
|
|
171
226
|
stderr: logFile,
|
|
@@ -175,12 +230,16 @@ async function ensureServerRunning() {
|
|
|
175
230
|
}
|
|
176
231
|
});
|
|
177
232
|
for (let attempt = 0;attempt < startupPollAttempts; attempt += 1) {
|
|
178
|
-
if (await
|
|
233
|
+
if (await checkServer(apiBaseUrl) === "healthy") {
|
|
179
234
|
currentOwnedProcess = ownedProcess;
|
|
180
235
|
return { url: apiBaseUrl, ownedProcess };
|
|
181
236
|
}
|
|
182
237
|
if (ownedProcess.exitCode !== null) {
|
|
183
|
-
return {
|
|
238
|
+
return {
|
|
239
|
+
url: apiBaseUrl,
|
|
240
|
+
ownedProcess: null,
|
|
241
|
+
error: "The Lightcode server exited during startup. Check the log at " + `${path3.join(logDirectory, "server.log")} \u2014 a port conflict or ` + "invalid settings.json are the usual causes."
|
|
242
|
+
};
|
|
184
243
|
}
|
|
185
244
|
await Bun.sleep(startupPollIntervalMs);
|
|
186
245
|
}
|
|
@@ -435,7 +494,8 @@ var init_help_overlay = __esm(() => {
|
|
|
435
494
|
screenHints = [
|
|
436
495
|
{ context: "Chat", hint: "Tab/Ctrl+T switch mode | @ attach files | /compact, /undo actions" },
|
|
437
496
|
{ context: "Chat", hint: "Ctrl+O expand tool output | Enter send | Ctrl+Enter newline" },
|
|
438
|
-
{ context: "
|
|
497
|
+
{ context: "Copy", hint: "Ctrl+Y copy mode (\u2191/\u2193 pick, Enter copy, c code) | /copy [last|code|all]" },
|
|
498
|
+
{ context: "Sessions", hint: "Enter resume | r rename | f fork | / filter | e export (.md) | d delete" }
|
|
439
499
|
];
|
|
440
500
|
});
|
|
441
501
|
|
|
@@ -513,12 +573,19 @@ var init_route_registry = __esm(() => {
|
|
|
513
573
|
shortcut: "/config"
|
|
514
574
|
},
|
|
515
575
|
{
|
|
516
|
-
id: "model",
|
|
517
|
-
label: "Model",
|
|
518
|
-
description: "
|
|
576
|
+
id: "model-select",
|
|
577
|
+
label: "Switch Model",
|
|
578
|
+
description: "Pick any OpenRouter model; applies immediately and persists to settings.json",
|
|
519
579
|
path: "/model",
|
|
520
580
|
shortcut: "/model"
|
|
521
581
|
},
|
|
582
|
+
{
|
|
583
|
+
id: "model",
|
|
584
|
+
label: "Model Info",
|
|
585
|
+
description: "Show provider, model, base URL, and key hints",
|
|
586
|
+
path: "/model-info",
|
|
587
|
+
shortcut: "/model-info"
|
|
588
|
+
},
|
|
522
589
|
{
|
|
523
590
|
id: "latest-session",
|
|
524
591
|
label: "Resume Latest",
|
|
@@ -2403,6 +2470,63 @@ var init_agent_tools = __esm(() => {
|
|
|
2403
2470
|
});
|
|
2404
2471
|
});
|
|
2405
2472
|
|
|
2473
|
+
// packages/ai/src/chat-error.ts
|
|
2474
|
+
function formatChatStreamError(info) {
|
|
2475
|
+
const payload = {
|
|
2476
|
+
...info,
|
|
2477
|
+
message: info.message.slice(0, maxTransportMessageLength)
|
|
2478
|
+
};
|
|
2479
|
+
return `${chatStreamErrorPrefix}${JSON.stringify(payload)}`;
|
|
2480
|
+
}
|
|
2481
|
+
function parseChatStreamError(message) {
|
|
2482
|
+
if (!message || !message.startsWith(chatStreamErrorPrefix)) {
|
|
2483
|
+
return null;
|
|
2484
|
+
}
|
|
2485
|
+
try {
|
|
2486
|
+
const parsed = JSON.parse(message.slice(chatStreamErrorPrefix.length));
|
|
2487
|
+
if (typeof parsed !== "object" || parsed === null || typeof parsed.message !== "string" || typeof parsed.retryable !== "boolean" || typeof parsed.kind !== "string" || !chatErrorKinds.has(parsed.kind)) {
|
|
2488
|
+
return null;
|
|
2489
|
+
}
|
|
2490
|
+
return {
|
|
2491
|
+
kind: parsed.kind,
|
|
2492
|
+
statusCode: typeof parsed.statusCode === "number" ? parsed.statusCode : undefined,
|
|
2493
|
+
retryable: parsed.retryable,
|
|
2494
|
+
message: parsed.message
|
|
2495
|
+
};
|
|
2496
|
+
} catch {
|
|
2497
|
+
return null;
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
function describeChatStreamError(info) {
|
|
2501
|
+
const status = info.statusCode ? ` (HTTP ${info.statusCode})` : "";
|
|
2502
|
+
return `${chatErrorKindLabels[info.kind]}${status}: ${info.message}`;
|
|
2503
|
+
}
|
|
2504
|
+
var chatStreamErrorPrefix = "LIGHTCODE_ERROR:", maxTransportMessageLength = 500, chatErrorKinds, chatErrorKindLabels;
|
|
2505
|
+
var init_chat_error = __esm(() => {
|
|
2506
|
+
chatErrorKinds = new Set([
|
|
2507
|
+
"auth",
|
|
2508
|
+
"billing",
|
|
2509
|
+
"rate_limit",
|
|
2510
|
+
"invalid_request",
|
|
2511
|
+
"context_overflow",
|
|
2512
|
+
"provider_unavailable",
|
|
2513
|
+
"network",
|
|
2514
|
+
"aborted",
|
|
2515
|
+
"unknown"
|
|
2516
|
+
]);
|
|
2517
|
+
chatErrorKindLabels = {
|
|
2518
|
+
auth: "Authentication error",
|
|
2519
|
+
billing: "Billing or quota error",
|
|
2520
|
+
rate_limit: "Rate limited",
|
|
2521
|
+
invalid_request: "Provider rejected the request",
|
|
2522
|
+
context_overflow: "Context window exceeded",
|
|
2523
|
+
provider_unavailable: "Provider unavailable",
|
|
2524
|
+
network: "Connection error",
|
|
2525
|
+
aborted: "Request aborted",
|
|
2526
|
+
unknown: "Provider error"
|
|
2527
|
+
};
|
|
2528
|
+
});
|
|
2529
|
+
|
|
2406
2530
|
// packages/ai/src/context/context-state.ts
|
|
2407
2531
|
import { z as z22 } from "zod";
|
|
2408
2532
|
var contextStateTierSchema, sessionContextStateSchema;
|
|
@@ -2735,7 +2859,9 @@ var init_coding_agent_prompt = __esm(() => {
|
|
|
2735
2859
|
init_coding_agent_modes();
|
|
2736
2860
|
defaultCodingAgentSystemPrompt = "You are a basic coding agent. Use tools for filesystem and codebase tasks instead of guessing. " + "Respect the user's intent, explain changes clearly, and prefer incremental, auditable actions. " + "You can only interact with files under this working directory: {cwd}. " + "Use glob_search for path discovery, grep for text search, structured git tools for repository inspection, and bash only when dedicated tools are not enough. " + "Use todo_write to keep multi-step implementation work visible and current. " + "For risky or uncertain operations, inspect context first and be explicit about assumptions. " + "While working, emit brief progress notes in natural language before major tool actions and after important findings. " + `Keep them short, human, and concrete. Vary wording naturally and avoid repetitive templates or rigid labels.
|
|
2737
2861
|
|
|
2738
|
-
` + "You are an agent \u2014 keep working until the user's request is fully resolved before ending your turn. " + "Never stop with a partial answer. If you say you will do something, do it in the same turn by calling a tool. " + "Use todo_write to track multi-step work and do not finish while any todo is pending or in_progress. " +
|
|
2862
|
+
` + "You are an agent \u2014 keep working until the user's request is fully resolved before ending your turn. " + "Never stop with a partial answer. If you say you will do something, do it in the same turn by calling a tool. " + "Use todo_write to track multi-step work and do not finish while any todo is pending or in_progress. " + `Only end your turn when the task is complete or you are blocked on input that only the user can provide.
|
|
2863
|
+
|
|
2864
|
+
` + "Long-running processes: never run dev servers, watchers, or other non-exiting commands as plain foreground bash \u2014 " + "the bash tool enforces a timeout and the command will be killed. Start them detached with output redirected to a " + 'log file (e.g. on Windows: start /B cmd /c "npm run dev > dev.log 2>&1"; on Unix: nohup npm run dev > dev.log 2>&1 &), ' + "wait briefly, then verify by reading the log file or with a bounded probe like curl --max-time 5. " + "Dev servers do not always get their default port \u2014 read the actual port from the startup log instead of assuming it. " + "Never kill processes or free ports you did not open yourself; other tools (including this agent's own backend) may be using them.";
|
|
2739
2865
|
toolCallingDisciplineAddendum = "Invoke tools only through the function-calling interface. " + "Never write tool calls as XML or plain text such as <tool_call>, <function_call>, <invoke>, or bare JSON in your message. " + "Tool arguments must be valid JSON matching the tool's schema. " + "Call one tool at a time and wait for its result before deciding the next step.";
|
|
2740
2866
|
});
|
|
2741
2867
|
|
|
@@ -3380,6 +3506,7 @@ function createCodingAgent({
|
|
|
3380
3506
|
promptOverride,
|
|
3381
3507
|
maxOutputTokens = 16384,
|
|
3382
3508
|
maxSteps = 30,
|
|
3509
|
+
maxRetries = 5,
|
|
3383
3510
|
providerOptions,
|
|
3384
3511
|
includeToolDiscipline = false
|
|
3385
3512
|
}) {
|
|
@@ -3389,6 +3516,7 @@ function createCodingAgent({
|
|
|
3389
3516
|
tools,
|
|
3390
3517
|
stopWhen: stepCountIs(maxSteps),
|
|
3391
3518
|
maxOutputTokens,
|
|
3519
|
+
maxRetries,
|
|
3392
3520
|
providerOptions,
|
|
3393
3521
|
experimental_repairToolCall: repairCodingAgentToolCall,
|
|
3394
3522
|
callOptionsSchema: codingAgentCallOptionsSchema,
|
|
@@ -3442,20 +3570,20 @@ var init_coding_agent = __esm(() => {
|
|
|
3442
3570
|
});
|
|
3443
3571
|
|
|
3444
3572
|
// packages/ai/src/config/credentials.ts
|
|
3445
|
-
import { chmodSync, existsSync as
|
|
3573
|
+
import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync, writeFileSync } from "fs";
|
|
3446
3574
|
import os from "os";
|
|
3447
|
-
import
|
|
3575
|
+
import path4 from "path";
|
|
3448
3576
|
import { z as z25 } from "zod";
|
|
3449
3577
|
function getCredentialsPath(env = process.env) {
|
|
3450
3578
|
const configuredPath = env.LIGHTCODE_CREDENTIALS?.trim();
|
|
3451
3579
|
if (configuredPath) {
|
|
3452
|
-
return
|
|
3580
|
+
return path4.resolve(configuredPath);
|
|
3453
3581
|
}
|
|
3454
|
-
return
|
|
3582
|
+
return path4.join(os.homedir(), ".lightcode", "credentials.json");
|
|
3455
3583
|
}
|
|
3456
3584
|
function readStoredCredentials(env = process.env) {
|
|
3457
3585
|
const credentialsPath = getCredentialsPath(env);
|
|
3458
|
-
if (!
|
|
3586
|
+
if (!existsSync3(credentialsPath)) {
|
|
3459
3587
|
return {};
|
|
3460
3588
|
}
|
|
3461
3589
|
try {
|
|
@@ -3471,7 +3599,7 @@ function writeStoredCredentials(credentials, env = process.env) {
|
|
|
3471
3599
|
...readStoredCredentials(env),
|
|
3472
3600
|
...credentials
|
|
3473
3601
|
});
|
|
3474
|
-
|
|
3602
|
+
mkdirSync3(path4.dirname(credentialsPath), { recursive: true });
|
|
3475
3603
|
writeFileSync(credentialsPath, `${JSON.stringify(merged, null, 2)}
|
|
3476
3604
|
`, "utf8");
|
|
3477
3605
|
try {
|
|
@@ -3850,11 +3978,11 @@ function normalizeReadPathKey(input) {
|
|
|
3850
3978
|
if (!isRecord3(input)) {
|
|
3851
3979
|
return null;
|
|
3852
3980
|
}
|
|
3853
|
-
const
|
|
3854
|
-
if (typeof
|
|
3981
|
+
const path5 = input.path;
|
|
3982
|
+
if (typeof path5 !== "string" || !path5.trim()) {
|
|
3855
3983
|
return null;
|
|
3856
3984
|
}
|
|
3857
|
-
return
|
|
3985
|
+
return path5.trim().replaceAll("\\", "/").toLowerCase();
|
|
3858
3986
|
}
|
|
3859
3987
|
function getPartState(part) {
|
|
3860
3988
|
const state = isRecord3(part) ? Reflect.get(part, "state") : undefined;
|
|
@@ -4045,6 +4173,43 @@ var init_build_provider_view = __esm(() => {
|
|
|
4045
4173
|
init_tier1_prune();
|
|
4046
4174
|
});
|
|
4047
4175
|
|
|
4176
|
+
// packages/ai/src/context/normalize-provider-messages.ts
|
|
4177
|
+
import { isToolUIPart } from "ai";
|
|
4178
|
+
function hasDanglingToolParts(messages) {
|
|
4179
|
+
return messages.some((message) => message.parts.some((part) => isToolUIPart(part) && !terminalToolStates.has(part.state)));
|
|
4180
|
+
}
|
|
4181
|
+
function resolveDanglingToolParts(messages, errorText = interruptedToolErrorText) {
|
|
4182
|
+
return messages.map((message) => {
|
|
4183
|
+
if (message.role !== "assistant") {
|
|
4184
|
+
return message;
|
|
4185
|
+
}
|
|
4186
|
+
let changed = false;
|
|
4187
|
+
const parts = message.parts.map((part) => {
|
|
4188
|
+
if (!isToolUIPart(part) || terminalToolStates.has(part.state)) {
|
|
4189
|
+
return part;
|
|
4190
|
+
}
|
|
4191
|
+
changed = true;
|
|
4192
|
+
return {
|
|
4193
|
+
...part,
|
|
4194
|
+
state: "output-error",
|
|
4195
|
+
errorText
|
|
4196
|
+
};
|
|
4197
|
+
});
|
|
4198
|
+
return changed ? { ...message, parts } : message;
|
|
4199
|
+
});
|
|
4200
|
+
}
|
|
4201
|
+
function normalizeProviderMessages(messages) {
|
|
4202
|
+
return resolveDanglingToolParts(messages);
|
|
4203
|
+
}
|
|
4204
|
+
var terminalToolStates, interruptedToolErrorText = "Tool call was interrupted by a connection retry. Re-issue the tool call if it is still needed.";
|
|
4205
|
+
var init_normalize_provider_messages = __esm(() => {
|
|
4206
|
+
terminalToolStates = new Set([
|
|
4207
|
+
"output-available",
|
|
4208
|
+
"output-error",
|
|
4209
|
+
"output-denied"
|
|
4210
|
+
]);
|
|
4211
|
+
});
|
|
4212
|
+
|
|
4048
4213
|
// packages/ai/src/context/index.ts
|
|
4049
4214
|
var init_context = __esm(() => {
|
|
4050
4215
|
init_build_provider_view();
|
|
@@ -4053,22 +4218,23 @@ var init_context = __esm(() => {
|
|
|
4053
4218
|
init_estimate();
|
|
4054
4219
|
init_heuristic_summary();
|
|
4055
4220
|
init_message_parts();
|
|
4221
|
+
init_normalize_provider_messages();
|
|
4056
4222
|
init_tier1_prune();
|
|
4057
4223
|
});
|
|
4058
4224
|
|
|
4059
4225
|
// packages/ai/src/config/lightcode-config.ts
|
|
4060
|
-
import { existsSync as
|
|
4226
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
4061
4227
|
import os2 from "os";
|
|
4062
|
-
import
|
|
4228
|
+
import path5 from "path";
|
|
4063
4229
|
import { z as z28 } from "zod";
|
|
4064
4230
|
function getDefaultUserConfigPath(env) {
|
|
4065
4231
|
if (env.LIGHTCODE_USER_CONFIG) {
|
|
4066
4232
|
return env.LIGHTCODE_USER_CONFIG;
|
|
4067
4233
|
}
|
|
4068
|
-
return
|
|
4234
|
+
return path5.join(os2.homedir(), ".lightcode", "settings.json");
|
|
4069
4235
|
}
|
|
4070
4236
|
function readConfigFile(scope, configPath) {
|
|
4071
|
-
if (!
|
|
4237
|
+
if (!existsSync4(configPath)) {
|
|
4072
4238
|
return {
|
|
4073
4239
|
config: {},
|
|
4074
4240
|
file: {
|
|
@@ -4151,6 +4317,12 @@ function readEnvConfig(env) {
|
|
|
4151
4317
|
summaryMaxChars: parseNumberEnv(env.LIGHTCODE_CONTEXT_SUMMARY_MAX_CHARS, "LIGHTCODE_CONTEXT_SUMMARY_MAX_CHARS")
|
|
4152
4318
|
};
|
|
4153
4319
|
const compactContextConfig = Object.fromEntries(Object.entries(contextConfig).filter(([, value]) => value !== undefined));
|
|
4320
|
+
const headroomConfig = {
|
|
4321
|
+
enabled: parseBooleanEnv(env.LIGHTCODE_HEADROOM_ENABLED, "LIGHTCODE_HEADROOM_ENABLED"),
|
|
4322
|
+
proxyUrl: env.LIGHTCODE_HEADROOM_PROXY_URL?.trim() || undefined,
|
|
4323
|
+
failOpen: parseBooleanEnv(env.LIGHTCODE_HEADROOM_FAIL_OPEN, "LIGHTCODE_HEADROOM_FAIL_OPEN")
|
|
4324
|
+
};
|
|
4325
|
+
const compactHeadroomConfig = Object.fromEntries(Object.entries(headroomConfig).filter(([, value]) => value !== undefined));
|
|
4154
4326
|
const rawConfig = {
|
|
4155
4327
|
provider: env.LIGHTCODE_PROVIDER,
|
|
4156
4328
|
model: env.LIGHTCODE_CHAT_MODEL,
|
|
@@ -4159,7 +4331,9 @@ function readEnvConfig(env) {
|
|
|
4159
4331
|
permissionMode: env.LIGHTCODE_PERMISSION_MODE,
|
|
4160
4332
|
maxOutputTokens: parseNumberEnv(env.LIGHTCODE_MAX_OUTPUT_TOKENS, "LIGHTCODE_MAX_OUTPUT_TOKENS"),
|
|
4161
4333
|
maxSteps: parseNumberEnv(env.LIGHTCODE_MAX_STEPS, "LIGHTCODE_MAX_STEPS"),
|
|
4162
|
-
|
|
4334
|
+
maxRetries: parseNumberEnv(env.LIGHTCODE_MAX_RETRIES, "LIGHTCODE_MAX_RETRIES"),
|
|
4335
|
+
context: Object.keys(compactContextConfig).length > 0 ? compactContextConfig : undefined,
|
|
4336
|
+
headroom: Object.keys(compactHeadroomConfig).length > 0 ? compactHeadroomConfig : undefined
|
|
4163
4337
|
};
|
|
4164
4338
|
const compactConfig = Object.fromEntries(Object.entries(rawConfig).filter(([, value]) => value !== undefined));
|
|
4165
4339
|
const parsedConfig = lightcodeConfigSchema.safeParse(compactConfig);
|
|
@@ -4183,13 +4357,37 @@ function mergeConfig(...configs) {
|
|
|
4183
4357
|
...mergedConfig.autoContinue,
|
|
4184
4358
|
...config2.autoContinue
|
|
4185
4359
|
} : mergedConfig.autoContinue,
|
|
4360
|
+
headroom: config2.headroom ? {
|
|
4361
|
+
...mergedConfig.headroom,
|
|
4362
|
+
...config2.headroom
|
|
4363
|
+
} : mergedConfig.headroom,
|
|
4186
4364
|
allowedTools: config2.allowedTools ?? mergedConfig.allowedTools
|
|
4187
4365
|
}), {});
|
|
4188
4366
|
}
|
|
4367
|
+
function updateUserSettings(update, env = process.env) {
|
|
4368
|
+
const configPath = getDefaultUserConfigPath(env);
|
|
4369
|
+
const existing = readConfigFile("user", configPath).config;
|
|
4370
|
+
const merged = { ...existing };
|
|
4371
|
+
for (const [key, value] of Object.entries(update)) {
|
|
4372
|
+
if (value === undefined || value === null) {
|
|
4373
|
+
delete merged[key];
|
|
4374
|
+
} else {
|
|
4375
|
+
Reflect.set(merged, key, value);
|
|
4376
|
+
}
|
|
4377
|
+
}
|
|
4378
|
+
const parsed = lightcodeConfigSchema.safeParse(merged);
|
|
4379
|
+
if (!parsed.success) {
|
|
4380
|
+
throw new LightcodeConfigError(`Invalid settings update: ${parsed.error.message}`);
|
|
4381
|
+
}
|
|
4382
|
+
mkdirSync4(path5.dirname(configPath), { recursive: true });
|
|
4383
|
+
writeFileSync2(configPath, `${JSON.stringify(parsed.data, null, 2)}
|
|
4384
|
+
`, "utf8");
|
|
4385
|
+
return { path: configPath, config: parsed.data };
|
|
4386
|
+
}
|
|
4189
4387
|
function loadLightcodeConfig({
|
|
4190
4388
|
cwd = process.cwd(),
|
|
4191
4389
|
env = process.env,
|
|
4192
|
-
projectConfigPath =
|
|
4390
|
+
projectConfigPath = path5.join(cwd, ".lightcode", "settings.json"),
|
|
4193
4391
|
userConfigPath = getDefaultUserConfigPath(env)
|
|
4194
4392
|
} = {}) {
|
|
4195
4393
|
const userConfig = readConfigFile("user", userConfigPath);
|
|
@@ -4203,6 +4401,10 @@ function loadLightcodeConfig({
|
|
|
4203
4401
|
autoContinue: {
|
|
4204
4402
|
...defaultAutoContinueConfig,
|
|
4205
4403
|
...mergedConfig.autoContinue
|
|
4404
|
+
},
|
|
4405
|
+
headroom: {
|
|
4406
|
+
...defaultHeadroomConfig,
|
|
4407
|
+
...mergedConfig.headroom
|
|
4206
4408
|
}
|
|
4207
4409
|
};
|
|
4208
4410
|
return lightcodeConfigLoadResultSchema.parse({
|
|
@@ -4210,7 +4412,7 @@ function loadLightcodeConfig({
|
|
|
4210
4412
|
loadedFiles: [userConfig.file, projectConfig.file]
|
|
4211
4413
|
});
|
|
4212
4414
|
}
|
|
4213
|
-
var lightcodeProviderSchema, autoContinueConfigSchema, resolvedAutoContinueConfigSchema, defaultAutoContinueConfig, lightcodeConfigSchema, lightcodeConfigDefaults, loadedConfigFileSchema, lightcodeResolvedConfigSchema, lightcodeConfigLoadResultSchema, lightcodeConfigStatusSchema, LightcodeConfigError;
|
|
4415
|
+
var lightcodeProviderSchema, autoContinueConfigSchema, resolvedAutoContinueConfigSchema, defaultAutoContinueConfig, headroomConfigSchema, resolvedHeadroomConfigSchema, defaultHeadroomConfig, lightcodeConfigSchema, lightcodeConfigDefaults, loadedConfigFileSchema, lightcodeResolvedConfigSchema, lightcodeConfigLoadResultSchema, lightcodeConfigStatusSchema, LightcodeConfigError;
|
|
4214
4416
|
var init_lightcode_config = __esm(() => {
|
|
4215
4417
|
init_coding_agent_modes();
|
|
4216
4418
|
init_coding_agent_modes();
|
|
@@ -4240,7 +4442,25 @@ var init_lightcode_config = __esm(() => {
|
|
|
4240
4442
|
enabled: true,
|
|
4241
4443
|
maxAutoContinues: 50,
|
|
4242
4444
|
maxErrorRetries: 5,
|
|
4243
|
-
stallTimeoutSeconds:
|
|
4445
|
+
stallTimeoutSeconds: 180
|
|
4446
|
+
};
|
|
4447
|
+
headroomConfigSchema = z28.object({
|
|
4448
|
+
enabled: z28.boolean().optional(),
|
|
4449
|
+
proxyUrl: z28.string().min(1).max(4096).optional(),
|
|
4450
|
+
providers: z28.array(lightcodeProviderSchema).optional(),
|
|
4451
|
+
failOpen: z28.boolean().optional()
|
|
4452
|
+
}).strict();
|
|
4453
|
+
resolvedHeadroomConfigSchema = z28.object({
|
|
4454
|
+
enabled: z28.boolean(),
|
|
4455
|
+
proxyUrl: z28.string().min(1).max(4096),
|
|
4456
|
+
providers: z28.array(lightcodeProviderSchema).nullable(),
|
|
4457
|
+
failOpen: z28.boolean()
|
|
4458
|
+
});
|
|
4459
|
+
defaultHeadroomConfig = {
|
|
4460
|
+
enabled: false,
|
|
4461
|
+
proxyUrl: "http://127.0.0.1:8787",
|
|
4462
|
+
providers: null,
|
|
4463
|
+
failOpen: true
|
|
4244
4464
|
};
|
|
4245
4465
|
lightcodeConfigSchema = z28.object({
|
|
4246
4466
|
provider: lightcodeProviderSchema.optional(),
|
|
@@ -4253,9 +4473,11 @@ var init_lightcode_config = __esm(() => {
|
|
|
4253
4473
|
sandbox: sandboxConfigSchema.optional(),
|
|
4254
4474
|
mcp: mcpConfigSchema.optional(),
|
|
4255
4475
|
context: contextOptimizerConfigSchema.optional(),
|
|
4256
|
-
maxOutputTokens: z28.number().int().min(1).max(
|
|
4476
|
+
maxOutputTokens: z28.number().int().min(1).max(1e6).optional(),
|
|
4257
4477
|
maxSteps: z28.number().int().min(1).max(100).optional(),
|
|
4258
|
-
|
|
4478
|
+
maxRetries: z28.number().int().min(0).max(10).optional(),
|
|
4479
|
+
autoContinue: autoContinueConfigSchema.optional(),
|
|
4480
|
+
headroom: headroomConfigSchema.optional()
|
|
4259
4481
|
}).strict();
|
|
4260
4482
|
lightcodeConfigDefaults = {
|
|
4261
4483
|
provider: "anthropic",
|
|
@@ -4263,7 +4485,9 @@ var init_lightcode_config = __esm(() => {
|
|
|
4263
4485
|
context: defaultContextOptimizerConfig,
|
|
4264
4486
|
maxOutputTokens: 32768,
|
|
4265
4487
|
maxSteps: 30,
|
|
4266
|
-
|
|
4488
|
+
maxRetries: 5,
|
|
4489
|
+
autoContinue: defaultAutoContinueConfig,
|
|
4490
|
+
headroom: defaultHeadroomConfig
|
|
4267
4491
|
};
|
|
4268
4492
|
loadedConfigFileSchema = z28.object({
|
|
4269
4493
|
scope: z28.enum(["user", "project"]),
|
|
@@ -4275,9 +4499,11 @@ var init_lightcode_config = __esm(() => {
|
|
|
4275
4499
|
provider: lightcodeProviderSchema,
|
|
4276
4500
|
defaultMode: codingAgentModeSchema,
|
|
4277
4501
|
context: resolvedContextOptimizerConfigSchema,
|
|
4278
|
-
maxOutputTokens: z28.number().int().min(1).max(
|
|
4502
|
+
maxOutputTokens: z28.number().int().min(1).max(1e6),
|
|
4279
4503
|
maxSteps: z28.number().int().min(1).max(100),
|
|
4280
|
-
|
|
4504
|
+
maxRetries: z28.number().int().min(0).max(10),
|
|
4505
|
+
autoContinue: resolvedAutoContinueConfigSchema,
|
|
4506
|
+
headroom: resolvedHeadroomConfigSchema.optional()
|
|
4281
4507
|
});
|
|
4282
4508
|
lightcodeConfigLoadResultSchema = z28.object({
|
|
4283
4509
|
config: lightcodeResolvedConfigSchema,
|
|
@@ -4291,10 +4517,15 @@ var init_lightcode_config = __esm(() => {
|
|
|
4291
4517
|
baseUrl: z28.string().nullable(),
|
|
4292
4518
|
defaultMode: codingAgentModeSchema,
|
|
4293
4519
|
permissionMode: permissionModeSchema.nullable(),
|
|
4294
|
-
maxOutputTokens: z28.number().int().min(1).max(
|
|
4520
|
+
maxOutputTokens: z28.number().int().min(1).max(1e6),
|
|
4295
4521
|
maxSteps: z28.number().int().min(1).max(100),
|
|
4296
4522
|
autoContinue: resolvedAutoContinueConfigSchema,
|
|
4297
4523
|
contextWindow: z28.number().int().positive(),
|
|
4524
|
+
headroom: z28.object({
|
|
4525
|
+
enabled: z28.boolean(),
|
|
4526
|
+
proxyUrl: z28.string().nullable(),
|
|
4527
|
+
routed: z28.boolean()
|
|
4528
|
+
}),
|
|
4298
4529
|
missingCredentialHints: z28.array(z28.string())
|
|
4299
4530
|
});
|
|
4300
4531
|
LightcodeConfigError = class LightcodeConfigError extends Error {
|
|
@@ -4553,6 +4784,21 @@ var init_runtime = __esm(() => {
|
|
|
4553
4784
|
init_schema13();
|
|
4554
4785
|
});
|
|
4555
4786
|
|
|
4787
|
+
// packages/ai/src/providers/clamp-output-tokens.ts
|
|
4788
|
+
function clampMaxOutputTokens(configured, modelMaxCompletionTokens) {
|
|
4789
|
+
if (typeof modelMaxCompletionTokens === "number" && Number.isFinite(modelMaxCompletionTokens) && modelMaxCompletionTokens > 0) {
|
|
4790
|
+
return Math.min(configured, modelMaxCompletionTokens);
|
|
4791
|
+
}
|
|
4792
|
+
return configured;
|
|
4793
|
+
}
|
|
4794
|
+
function resolveMaxOutputTokens(configured, defaultValue, modelMaxCompletionTokens) {
|
|
4795
|
+
const hasModelCap = typeof modelMaxCompletionTokens === "number" && Number.isFinite(modelMaxCompletionTokens) && modelMaxCompletionTokens > 0;
|
|
4796
|
+
if (configured === defaultValue) {
|
|
4797
|
+
return hasModelCap ? modelMaxCompletionTokens : configured;
|
|
4798
|
+
}
|
|
4799
|
+
return clampMaxOutputTokens(configured, modelMaxCompletionTokens);
|
|
4800
|
+
}
|
|
4801
|
+
|
|
4556
4802
|
// packages/ai/src/providers/model-metadata.ts
|
|
4557
4803
|
function getModelContextWindow(provider, modelId) {
|
|
4558
4804
|
if (provider === "anthropic") {
|
|
@@ -5184,27 +5430,27 @@ var init_schema16 = __esm(() => {
|
|
|
5184
5430
|
});
|
|
5185
5431
|
|
|
5186
5432
|
// packages/ai/src/plugins/runtime.ts
|
|
5187
|
-
import { existsSync as
|
|
5433
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, readdirSync as readdirSync2 } from "fs";
|
|
5188
5434
|
import os3 from "os";
|
|
5189
|
-
import
|
|
5435
|
+
import path6 from "path";
|
|
5190
5436
|
function pluginRoots(cwd) {
|
|
5191
5437
|
return [
|
|
5192
|
-
|
|
5193
|
-
|
|
5438
|
+
path6.join(cwd, ".lightcode", "plugins"),
|
|
5439
|
+
path6.join(os3.homedir(), ".lightcode", "plugins")
|
|
5194
5440
|
];
|
|
5195
5441
|
}
|
|
5196
5442
|
function listPlugins({ cwd = process.cwd() } = {}) {
|
|
5197
5443
|
const plugins = [];
|
|
5198
5444
|
for (const root of pluginRoots(cwd)) {
|
|
5199
|
-
if (!
|
|
5445
|
+
if (!existsSync5(root)) {
|
|
5200
5446
|
continue;
|
|
5201
5447
|
}
|
|
5202
|
-
for (const entry of
|
|
5448
|
+
for (const entry of readdirSync2(root, { withFileTypes: true })) {
|
|
5203
5449
|
if (!entry.isDirectory()) {
|
|
5204
5450
|
continue;
|
|
5205
5451
|
}
|
|
5206
|
-
const manifestPath =
|
|
5207
|
-
if (!
|
|
5452
|
+
const manifestPath = path6.join(root, entry.name, "plugin.json");
|
|
5453
|
+
if (!existsSync5(manifestPath)) {
|
|
5208
5454
|
continue;
|
|
5209
5455
|
}
|
|
5210
5456
|
const manifest = pluginManifestSchema.parse(JSON.parse(readFileSync3(manifestPath, "utf8")));
|
|
@@ -5243,7 +5489,7 @@ async function runPluginHooks({
|
|
|
5243
5489
|
for (const hook of manifest.hooks.filter((candidate) => candidate.event === event)) {
|
|
5244
5490
|
hooksRun += 1;
|
|
5245
5491
|
const child = Bun.spawn([hook.command, ...hook.args], {
|
|
5246
|
-
cwd:
|
|
5492
|
+
cwd: path6.dirname(plugin.path),
|
|
5247
5493
|
stdout: "pipe",
|
|
5248
5494
|
stderr: "pipe"
|
|
5249
5495
|
});
|
|
@@ -5283,14 +5529,14 @@ var init_runtime2 = __esm(() => {
|
|
|
5283
5529
|
});
|
|
5284
5530
|
|
|
5285
5531
|
// packages/ai/src/skills/runtime.ts
|
|
5286
|
-
import { existsSync as
|
|
5532
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, readdirSync as readdirSync3, statSync } from "fs";
|
|
5287
5533
|
import os4 from "os";
|
|
5288
|
-
import
|
|
5534
|
+
import path7 from "path";
|
|
5289
5535
|
function defaultSkillRoots(cwd) {
|
|
5290
5536
|
return [
|
|
5291
|
-
{ source: "project", path:
|
|
5292
|
-
{ source: "project", path:
|
|
5293
|
-
{ source: "user", path:
|
|
5537
|
+
{ source: "project", path: path7.join(cwd, ".lightcode", "skills") },
|
|
5538
|
+
{ source: "project", path: path7.join(cwd, ".agents", "skills") },
|
|
5539
|
+
{ source: "user", path: path7.join(os4.homedir(), ".lightcode", "skills") }
|
|
5294
5540
|
];
|
|
5295
5541
|
}
|
|
5296
5542
|
function normalizeSkillName(value) {
|
|
@@ -5312,7 +5558,7 @@ function parseBasicFrontmatter(content) {
|
|
|
5312
5558
|
]));
|
|
5313
5559
|
}
|
|
5314
5560
|
function findSkillFiles(root) {
|
|
5315
|
-
if (!
|
|
5561
|
+
if (!existsSync6(root.path)) {
|
|
5316
5562
|
return [];
|
|
5317
5563
|
}
|
|
5318
5564
|
const files = [];
|
|
@@ -5320,8 +5566,8 @@ function findSkillFiles(root) {
|
|
|
5320
5566
|
if (depth > 4) {
|
|
5321
5567
|
return;
|
|
5322
5568
|
}
|
|
5323
|
-
for (const entry of
|
|
5324
|
-
const entryPath =
|
|
5569
|
+
for (const entry of readdirSync3(directory)) {
|
|
5570
|
+
const entryPath = path7.join(directory, entry);
|
|
5325
5571
|
const stat = statSync(entryPath);
|
|
5326
5572
|
if (stat.isDirectory()) {
|
|
5327
5573
|
visit(entryPath, depth + 1);
|
|
@@ -5342,7 +5588,7 @@ function listSkills({
|
|
|
5342
5588
|
for (const skillPath of findSkillFiles(root)) {
|
|
5343
5589
|
const content = readFileSync4(skillPath, "utf8");
|
|
5344
5590
|
const frontmatter = parseBasicFrontmatter(content);
|
|
5345
|
-
const fallbackName =
|
|
5591
|
+
const fallbackName = path7.basename(path7.dirname(skillPath));
|
|
5346
5592
|
const name = normalizeSkillName(frontmatter.name ?? fallbackName);
|
|
5347
5593
|
if (!name || seen.has(name)) {
|
|
5348
5594
|
continue;
|
|
@@ -5417,6 +5663,7 @@ var init_subagent_schemas = __esm(() => {
|
|
|
5417
5663
|
// packages/ai/src/index.ts
|
|
5418
5664
|
var init_src2 = __esm(() => {
|
|
5419
5665
|
init_agent_tools();
|
|
5666
|
+
init_chat_error();
|
|
5420
5667
|
init_chat_interaction_schemas();
|
|
5421
5668
|
init_plan_block();
|
|
5422
5669
|
init_chat_schemas();
|
|
@@ -5453,8 +5700,27 @@ var init_client = __esm(() => {
|
|
|
5453
5700
|
client = hc(apiBaseUrl);
|
|
5454
5701
|
});
|
|
5455
5702
|
|
|
5703
|
+
// apps/cli/src/utils/markdown-code.ts
|
|
5704
|
+
function extractCodeBlocks(text) {
|
|
5705
|
+
const blocks = [];
|
|
5706
|
+
FENCE_RE.lastIndex = 0;
|
|
5707
|
+
let match;
|
|
5708
|
+
while ((match = FENCE_RE.exec(text)) !== null) {
|
|
5709
|
+
const lang = match[1]?.trim();
|
|
5710
|
+
const code = (match[2] ?? "").replace(/\r?\n$/, "");
|
|
5711
|
+
if (code.trim()) {
|
|
5712
|
+
blocks.push({ lang: lang ? lang : undefined, code });
|
|
5713
|
+
}
|
|
5714
|
+
}
|
|
5715
|
+
return blocks;
|
|
5716
|
+
}
|
|
5717
|
+
var FENCE_RE;
|
|
5718
|
+
var init_markdown_code = __esm(() => {
|
|
5719
|
+
FENCE_RE = /```([^\n`]*)\r?\n([\s\S]*?)```/g;
|
|
5720
|
+
});
|
|
5721
|
+
|
|
5456
5722
|
// apps/cli/src/commands/export-session-markdown.ts
|
|
5457
|
-
import
|
|
5723
|
+
import path8 from "path";
|
|
5458
5724
|
function escapeMarkdown(text) {
|
|
5459
5725
|
return text.replace(/```/g, "\\`\\`\\`").replace(/`/g, "\\`").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/__([^_]+)__/g, "$1").replace(/_([^_]+)_/g, "$1");
|
|
5460
5726
|
}
|
|
@@ -5571,33 +5837,33 @@ function getExportDirectory() {
|
|
|
5571
5837
|
return process.cwd();
|
|
5572
5838
|
}
|
|
5573
5839
|
function getExportPath(sessionTitle, sessionId) {
|
|
5574
|
-
return
|
|
5840
|
+
return path8.join(getExportDirectory(), generateExportFilename(sessionTitle, sessionId));
|
|
5575
5841
|
}
|
|
5576
5842
|
var init_export_session_markdown = () => {};
|
|
5577
5843
|
|
|
5578
5844
|
// packages/ai/src/common/resolve-within-workspace.ts
|
|
5579
|
-
import
|
|
5845
|
+
import path9 from "path";
|
|
5580
5846
|
import {
|
|
5581
|
-
existsSync as
|
|
5847
|
+
existsSync as existsSync7,
|
|
5582
5848
|
lstatSync,
|
|
5583
5849
|
realpathSync,
|
|
5584
5850
|
statSync as statSync2
|
|
5585
5851
|
} from "fs";
|
|
5586
5852
|
function stripTrailingSeparator(value) {
|
|
5587
|
-
const parsed =
|
|
5853
|
+
const parsed = path9.parse(value);
|
|
5588
5854
|
if (value === parsed.root) {
|
|
5589
5855
|
return value;
|
|
5590
5856
|
}
|
|
5591
5857
|
return value.replace(/[\\/]+$/, "");
|
|
5592
5858
|
}
|
|
5593
5859
|
function normalizeForComparison(value) {
|
|
5594
|
-
const normalized = stripTrailingSeparator(
|
|
5860
|
+
const normalized = stripTrailingSeparator(path9.resolve(value));
|
|
5595
5861
|
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
5596
5862
|
}
|
|
5597
5863
|
function isWithinWorkspace(absolutePath, context2) {
|
|
5598
5864
|
const workspace = normalizeForComparison(context2.root);
|
|
5599
5865
|
const target = normalizeForComparison(absolutePath);
|
|
5600
|
-
return target === workspace || target.startsWith(`${workspace}${
|
|
5866
|
+
return target === workspace || target.startsWith(`${workspace}${path9.sep}`);
|
|
5601
5867
|
}
|
|
5602
5868
|
function assertWithinWorkspace(absolutePath, context2, input) {
|
|
5603
5869
|
if (!isWithinWorkspace(absolutePath, context2)) {
|
|
@@ -5612,17 +5878,17 @@ function getExistingRealPath(absolutePath) {
|
|
|
5612
5878
|
}
|
|
5613
5879
|
}
|
|
5614
5880
|
function findNearestExistingParent(absolutePath, context2, input) {
|
|
5615
|
-
let currentPath =
|
|
5881
|
+
let currentPath = path9.dirname(absolutePath);
|
|
5616
5882
|
while (true) {
|
|
5617
5883
|
assertWithinWorkspace(currentPath, context2, input);
|
|
5618
|
-
if (
|
|
5884
|
+
if (existsSync7(currentPath)) {
|
|
5619
5885
|
const realParentPath = getExistingRealPath(currentPath);
|
|
5620
5886
|
if (!realParentPath) {
|
|
5621
5887
|
throw new Error(`Unable to resolve existing parent for path: ${input}`);
|
|
5622
5888
|
}
|
|
5623
5889
|
return realParentPath;
|
|
5624
5890
|
}
|
|
5625
|
-
const parentPath =
|
|
5891
|
+
const parentPath = path9.dirname(currentPath);
|
|
5626
5892
|
if (parentPath === currentPath) {
|
|
5627
5893
|
throw new Error(`Unable to find an existing workspace parent for path: ${input}`);
|
|
5628
5894
|
}
|
|
@@ -5642,7 +5908,7 @@ function getDefaultWorkspaceContext() {
|
|
|
5642
5908
|
}
|
|
5643
5909
|
function resolveWithinWorkspace(input, options = {}) {
|
|
5644
5910
|
const context2 = options.context ?? defaultWorkspaceContext;
|
|
5645
|
-
const resolved =
|
|
5911
|
+
const resolved = path9.resolve(context2.root, input);
|
|
5646
5912
|
assertWithinWorkspace(resolved, context2, input);
|
|
5647
5913
|
const realPath = getExistingRealPath(resolved);
|
|
5648
5914
|
if (realPath) {
|
|
@@ -5667,13 +5933,13 @@ function resolveWithinWorkspace(input, options = {}) {
|
|
|
5667
5933
|
return resolved;
|
|
5668
5934
|
}
|
|
5669
5935
|
function toWorkspaceRelativePath(absolutePath, context2 = defaultWorkspaceContext) {
|
|
5670
|
-
const resolved =
|
|
5936
|
+
const resolved = path9.resolve(absolutePath);
|
|
5671
5937
|
assertWithinWorkspace(resolved, context2, absolutePath);
|
|
5672
|
-
const relativePath =
|
|
5938
|
+
const relativePath = path9.relative(context2.root, resolved);
|
|
5673
5939
|
if (relativePath === "") {
|
|
5674
5940
|
return ".";
|
|
5675
5941
|
}
|
|
5676
|
-
return relativePath.split(
|
|
5942
|
+
return relativePath.split(path9.sep).join("/");
|
|
5677
5943
|
}
|
|
5678
5944
|
var nativeRealpathSync, defaultWorkspaceContext, WORKSPACE;
|
|
5679
5945
|
var init_resolve_within_workspace = __esm(() => {
|
|
@@ -5781,16 +6047,16 @@ var init_runtime4 = __esm(() => {
|
|
|
5781
6047
|
// packages/ai/src/checkpoints/runtime.ts
|
|
5782
6048
|
import { createHash } from "crypto";
|
|
5783
6049
|
import { promises as fs } from "fs";
|
|
5784
|
-
import
|
|
6050
|
+
import path10 from "path";
|
|
5785
6051
|
import { z as z32 } from "zod";
|
|
5786
6052
|
function safeSessionDirName(sessionId) {
|
|
5787
6053
|
return sessionId.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 120);
|
|
5788
6054
|
}
|
|
5789
6055
|
function getCheckpointsDir(sessionId) {
|
|
5790
|
-
return
|
|
6056
|
+
return path10.join(getLightcodeDataDir(), "checkpoints", safeSessionDirName(sessionId));
|
|
5791
6057
|
}
|
|
5792
6058
|
function getManifestPath(sessionId) {
|
|
5793
|
-
return
|
|
6059
|
+
return path10.join(getCheckpointsDir(sessionId), "manifest.json");
|
|
5794
6060
|
}
|
|
5795
6061
|
async function loadManifest(sessionId) {
|
|
5796
6062
|
try {
|
|
@@ -5803,7 +6069,7 @@ async function loadManifest(sessionId) {
|
|
|
5803
6069
|
}
|
|
5804
6070
|
async function saveManifest(sessionId, manifest) {
|
|
5805
6071
|
const manifestPath = getManifestPath(sessionId);
|
|
5806
|
-
await fs.mkdir(
|
|
6072
|
+
await fs.mkdir(path10.dirname(manifestPath), { recursive: true });
|
|
5807
6073
|
await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
5808
6074
|
`, "utf8");
|
|
5809
6075
|
}
|
|
@@ -5828,8 +6094,8 @@ async function recordFileCheckpoint({
|
|
|
5828
6094
|
if (previousContent !== null) {
|
|
5829
6095
|
const pathHash = createHash("sha1").update(workspaceRelativePath).digest("hex").slice(0, 12);
|
|
5830
6096
|
snapshotFile = `${turnKey}-${pathHash}.snap`;
|
|
5831
|
-
const snapshotPath =
|
|
5832
|
-
await fs.mkdir(
|
|
6097
|
+
const snapshotPath = path10.join(getCheckpointsDir(sessionId), snapshotFile);
|
|
6098
|
+
await fs.mkdir(path10.dirname(snapshotPath), { recursive: true });
|
|
5833
6099
|
await fs.writeFile(snapshotPath, previousContent, "utf8");
|
|
5834
6100
|
}
|
|
5835
6101
|
turn.files.push({ workspaceRelativePath, absolutePath, snapshotFile });
|
|
@@ -5849,9 +6115,9 @@ async function undoLastTurn({
|
|
|
5849
6115
|
if (file.snapshotFile === null) {
|
|
5850
6116
|
await fs.rm(file.absolutePath, { force: true });
|
|
5851
6117
|
} else {
|
|
5852
|
-
const snapshotPath =
|
|
6118
|
+
const snapshotPath = path10.join(getCheckpointsDir(sessionId), file.snapshotFile);
|
|
5853
6119
|
const snapshotContent = await fs.readFile(snapshotPath, "utf8");
|
|
5854
|
-
await fs.mkdir(
|
|
6120
|
+
await fs.mkdir(path10.dirname(file.absolutePath), { recursive: true });
|
|
5855
6121
|
await fs.writeFile(file.absolutePath, snapshotContent, "utf8");
|
|
5856
6122
|
await fs.rm(snapshotPath, { force: true });
|
|
5857
6123
|
}
|
|
@@ -5963,7 +6229,7 @@ var init_runtime6 = __esm(() => {
|
|
|
5963
6229
|
// packages/ai/src/grep/runtime.ts
|
|
5964
6230
|
import { execFile } from "child_process";
|
|
5965
6231
|
import { readdir, readFile, stat } from "fs/promises";
|
|
5966
|
-
import
|
|
6232
|
+
import path11 from "path";
|
|
5967
6233
|
import { promisify as promisify2 } from "util";
|
|
5968
6234
|
function isRecord6(value) {
|
|
5969
6235
|
return typeof value === "object" && value !== null;
|
|
@@ -6020,7 +6286,7 @@ function parseRgMatches(stdout, maxResults, workspaceContext) {
|
|
|
6020
6286
|
if (!event) {
|
|
6021
6287
|
continue;
|
|
6022
6288
|
}
|
|
6023
|
-
const absolutePath =
|
|
6289
|
+
const absolutePath = path11.isAbsolute(event.rawPath) ? event.rawPath : path11.resolve(workspaceContext.root, event.rawPath);
|
|
6024
6290
|
let relativePath;
|
|
6025
6291
|
try {
|
|
6026
6292
|
relativePath = toWorkspaceRelativePath(absolutePath, workspaceContext);
|
|
@@ -6080,7 +6346,7 @@ async function collectSearchFiles(searchRootPath) {
|
|
|
6080
6346
|
if (entry.isDirectory() && fallbackIgnoredDirectories.has(entry.name)) {
|
|
6081
6347
|
continue;
|
|
6082
6348
|
}
|
|
6083
|
-
const entryPath =
|
|
6349
|
+
const entryPath = path11.join(searchRootPath, entry.name);
|
|
6084
6350
|
if (entry.isDirectory()) {
|
|
6085
6351
|
files.push(...await collectSearchFiles(entryPath));
|
|
6086
6352
|
continue;
|
|
@@ -6205,7 +6471,7 @@ var init_runtime7 = __esm(() => {
|
|
|
6205
6471
|
|
|
6206
6472
|
// packages/ai/src/glob-search/runtime.ts
|
|
6207
6473
|
import { lstat, readdir as readdir2, stat as stat2 } from "fs/promises";
|
|
6208
|
-
import
|
|
6474
|
+
import path12 from "path";
|
|
6209
6475
|
function normalizeGlobPath(value) {
|
|
6210
6476
|
return value.replaceAll("\\", "/").replace(/^\.\//, "");
|
|
6211
6477
|
}
|
|
@@ -6263,7 +6529,7 @@ function entryTypeFromStats(stats) {
|
|
|
6263
6529
|
return "other";
|
|
6264
6530
|
}
|
|
6265
6531
|
async function collectEntry(absolutePath, searchRoot, parsedInput, matcher, workspaceContext) {
|
|
6266
|
-
const relativeToSearchRoot = normalizeGlobPath(
|
|
6532
|
+
const relativeToSearchRoot = normalizeGlobPath(path12.relative(searchRoot, absolutePath));
|
|
6267
6533
|
const comparablePath = relativeToSearchRoot === "" ? "." : relativeToSearchRoot;
|
|
6268
6534
|
if (!parsedInput.includeHidden && isHiddenPath(comparablePath)) {
|
|
6269
6535
|
return null;
|
|
@@ -6293,7 +6559,7 @@ async function executeGlobSearch(input, workspaceContext = getDefaultWorkspaceCo
|
|
|
6293
6559
|
const matches = [];
|
|
6294
6560
|
let truncated = false;
|
|
6295
6561
|
if (searchRootStats.isFile()) {
|
|
6296
|
-
const match = await collectEntry(searchRoot,
|
|
6562
|
+
const match = await collectEntry(searchRoot, path12.dirname(searchRoot), parsedInput, matcher, workspaceContext);
|
|
6297
6563
|
if (match) {
|
|
6298
6564
|
matches.push(match);
|
|
6299
6565
|
}
|
|
@@ -6314,7 +6580,7 @@ async function executeGlobSearch(input, workspaceContext = getDefaultWorkspaceCo
|
|
|
6314
6580
|
if (directoryEntry.isDirectory() && shouldSkipDirectory(directoryEntry.name, parsedInput.includeHidden)) {
|
|
6315
6581
|
continue;
|
|
6316
6582
|
}
|
|
6317
|
-
const absoluteEntryPath =
|
|
6583
|
+
const absoluteEntryPath = path12.join(currentDirectory, directoryEntry.name);
|
|
6318
6584
|
const match = await collectEntry(absoluteEntryPath, searchRoot, parsedInput, matcher, workspaceContext);
|
|
6319
6585
|
if (match) {
|
|
6320
6586
|
matches.push(match);
|
|
@@ -6600,7 +6866,7 @@ var init_runtime9 = __esm(() => {
|
|
|
6600
6866
|
|
|
6601
6867
|
// packages/ai/src/list-files/runtime.ts
|
|
6602
6868
|
import { promises as fs3 } from "fs";
|
|
6603
|
-
import
|
|
6869
|
+
import path13 from "path";
|
|
6604
6870
|
function entryTypeFromStats2(stats) {
|
|
6605
6871
|
if (stats.isFile()) {
|
|
6606
6872
|
return "file";
|
|
@@ -6646,7 +6912,7 @@ async function executeListFiles(input, workspaceContext = getDefaultWorkspaceCon
|
|
|
6646
6912
|
if (!parsedInput.includeHidden && isHidden) {
|
|
6647
6913
|
continue;
|
|
6648
6914
|
}
|
|
6649
|
-
const absoluteEntryPath =
|
|
6915
|
+
const absoluteEntryPath = path13.join(currentDirectoryPath, dirEntry.name);
|
|
6650
6916
|
const relativeEntryPath = toWorkspaceRelativePath(absoluteEntryPath, workspaceContext);
|
|
6651
6917
|
const entryStats = await fs3.lstat(absoluteEntryPath);
|
|
6652
6918
|
const entryType = entryTypeFromStats2(entryStats);
|
|
@@ -6724,7 +6990,7 @@ var init_runtime11 = __esm(() => {
|
|
|
6724
6990
|
|
|
6725
6991
|
// packages/ai/src/todo-write/runtime.ts
|
|
6726
6992
|
import { mkdir, readFile as readFile2, writeFile } from "fs/promises";
|
|
6727
|
-
import
|
|
6993
|
+
import path14 from "path";
|
|
6728
6994
|
import { z as z33 } from "zod";
|
|
6729
6995
|
function safeTodoSessionId(sessionId) {
|
|
6730
6996
|
const trimmed = sessionId?.trim();
|
|
@@ -6734,7 +7000,7 @@ function safeTodoSessionId(sessionId) {
|
|
|
6734
7000
|
return trimmed.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 120);
|
|
6735
7001
|
}
|
|
6736
7002
|
function getTodoFilePath(sessionId, workspaceContext) {
|
|
6737
|
-
return resolveWithinWorkspace(
|
|
7003
|
+
return resolveWithinWorkspace(path14.join(".lightcode", "todos", `${safeTodoSessionId(sessionId)}.json`), {
|
|
6738
7004
|
context: workspaceContext,
|
|
6739
7005
|
allowMissing: true
|
|
6740
7006
|
});
|
|
@@ -6770,7 +7036,7 @@ async function executeTodoWrite(input, {
|
|
|
6770
7036
|
...todo,
|
|
6771
7037
|
id: todo.id ?? `todo-${index + 1}`
|
|
6772
7038
|
}));
|
|
6773
|
-
await mkdir(
|
|
7039
|
+
await mkdir(path14.dirname(todoFilePath), { recursive: true });
|
|
6774
7040
|
await writeFile(todoFilePath, JSON.stringify(todos, null, 2), "utf8");
|
|
6775
7041
|
return todoWriteOutputSchema.parse({
|
|
6776
7042
|
sessionId: safeTodoSessionId(sessionId),
|
|
@@ -7135,7 +7401,7 @@ var init_runtime15 = __esm(() => {
|
|
|
7135
7401
|
|
|
7136
7402
|
// packages/ai/src/write-file/runtime.ts
|
|
7137
7403
|
import { promises as fs5 } from "fs";
|
|
7138
|
-
import
|
|
7404
|
+
import path15 from "path";
|
|
7139
7405
|
async function executeWriteFile(input, workspaceContext = getDefaultWorkspaceContext(), editContext = {}) {
|
|
7140
7406
|
const parsedInput = writeFileInputSchema.parse(input);
|
|
7141
7407
|
const resolvedPath = resolveWithinWorkspace(parsedInput.path, {
|
|
@@ -7172,7 +7438,7 @@ async function executeWriteFile(input, workspaceContext = getDefaultWorkspaceCon
|
|
|
7172
7438
|
previousContent
|
|
7173
7439
|
});
|
|
7174
7440
|
}
|
|
7175
|
-
await fs5.mkdir(
|
|
7441
|
+
await fs5.mkdir(path15.dirname(resolvedPath), { recursive: true });
|
|
7176
7442
|
await fs5.writeFile(resolvedPath, parsedInput.content, "utf8");
|
|
7177
7443
|
const bytesWritten = Buffer.byteLength(parsedInput.content, "utf8");
|
|
7178
7444
|
return writeFileOutputSchema.parse({
|
|
@@ -7292,6 +7558,7 @@ __export(exports_runtime, {
|
|
|
7292
7558
|
xmlToolCallMiddleware: () => xmlToolCallMiddleware,
|
|
7293
7559
|
writeStoredCredentials: () => writeStoredCredentials,
|
|
7294
7560
|
withXmlToolCallSupport: () => withXmlToolCallSupport,
|
|
7561
|
+
updateUserSettings: () => updateUserSettings,
|
|
7295
7562
|
undoLastTurn: () => undoLastTurn,
|
|
7296
7563
|
truncateText: () => truncateText,
|
|
7297
7564
|
toolCallingDisciplineAddendum: () => toolCallingDisciplineAddendum,
|
|
@@ -7342,9 +7609,12 @@ __export(exports_runtime, {
|
|
|
7342
7609
|
sandboxConfigSchema: () => sandboxConfigSchema,
|
|
7343
7610
|
safeStringify: () => safeStringify,
|
|
7344
7611
|
runPluginHooks: () => runPluginHooks,
|
|
7612
|
+
resolvedHeadroomConfigSchema: () => resolvedHeadroomConfigSchema,
|
|
7345
7613
|
resolvedContextOptimizerConfigSchema: () => resolvedContextOptimizerConfigSchema,
|
|
7346
7614
|
resolvedAutoContinueConfigSchema: () => resolvedAutoContinueConfigSchema,
|
|
7347
7615
|
resolveWithinWorkspace: () => resolveWithinWorkspace,
|
|
7616
|
+
resolveMaxOutputTokens: () => resolveMaxOutputTokens,
|
|
7617
|
+
resolveDanglingToolParts: () => resolveDanglingToolParts,
|
|
7348
7618
|
resolveContextWindowTokens: () => resolveContextWindowTokens,
|
|
7349
7619
|
resolveCodingPermissionMode: () => resolveCodingPermissionMode,
|
|
7350
7620
|
requestUserInputToolProviderInputSchema: () => requestUserInputToolProviderInputSchema,
|
|
@@ -7372,7 +7642,9 @@ __export(exports_runtime, {
|
|
|
7372
7642
|
permissionModeMeets: () => permissionModeMeets,
|
|
7373
7643
|
permissionDecisionSchema: () => permissionDecisionSchema,
|
|
7374
7644
|
parseCodingToolInput: () => parseCodingToolInput,
|
|
7645
|
+
parseChatStreamError: () => parseChatStreamError,
|
|
7375
7646
|
normalizeSandboxConfig: () => normalizeSandboxConfig,
|
|
7647
|
+
normalizeProviderMessages: () => normalizeProviderMessages,
|
|
7376
7648
|
normalizeContextOptimizerConfig: () => normalizeContextOptimizerConfig,
|
|
7377
7649
|
messageUsageMetadataSchema: () => messageUsageMetadataSchema,
|
|
7378
7650
|
mcpStdioServerConfigSchema: () => mcpStdioServerConfigSchema,
|
|
@@ -7403,7 +7675,10 @@ __export(exports_runtime, {
|
|
|
7403
7675
|
isRecord: () => isRecord3,
|
|
7404
7676
|
isPermissionDeniedError: () => isPermissionDeniedError,
|
|
7405
7677
|
isElidedToolOutput: () => isElidedToolOutput,
|
|
7678
|
+
interruptedToolErrorText: () => interruptedToolErrorText,
|
|
7679
|
+
headroomConfigSchema: () => headroomConfigSchema,
|
|
7406
7680
|
hasUnresolvedToolWork: () => hasUnresolvedToolWork,
|
|
7681
|
+
hasDanglingToolParts: () => hasDanglingToolParts,
|
|
7407
7682
|
getToolNameFromPart: () => getToolNameFromPart,
|
|
7408
7683
|
getTextPartContent: () => getTextPartContent,
|
|
7409
7684
|
getSandboxRuntimeStatus: () => getSandboxRuntimeStatus,
|
|
@@ -7415,6 +7690,7 @@ __export(exports_runtime, {
|
|
|
7415
7690
|
getCodingAgentModeDefinition: () => getCodingAgentModeDefinition,
|
|
7416
7691
|
getActiveCodingToolsForPolicy: () => getActiveCodingToolsForPolicy,
|
|
7417
7692
|
formatPermissionDecision: () => formatPermissionDecision,
|
|
7693
|
+
formatChatStreamError: () => formatChatStreamError,
|
|
7418
7694
|
extractProposedPlanBlocks: () => extractProposedPlanBlocks,
|
|
7419
7695
|
extractLatestProposedPlan: () => extractLatestProposedPlan,
|
|
7420
7696
|
executeWriteFile: () => executeWriteFile,
|
|
@@ -7450,8 +7726,10 @@ __export(exports_runtime, {
|
|
|
7450
7726
|
diagnosticsDatabaseSchema: () => diagnosticsDatabaseSchema,
|
|
7451
7727
|
diagnosticStatusSchema: () => diagnosticStatusSchema,
|
|
7452
7728
|
diagnosticCheckSchema: () => diagnosticCheckSchema,
|
|
7729
|
+
describeChatStreamError: () => describeChatStreamError,
|
|
7453
7730
|
defaultSubagentTaskMode: () => defaultSubagentTaskMode,
|
|
7454
7731
|
defaultPermissionModeForCodingMode: () => defaultPermissionModeForCodingMode,
|
|
7732
|
+
defaultHeadroomConfig: () => defaultHeadroomConfig,
|
|
7455
7733
|
defaultContextOptimizerConfig: () => defaultContextOptimizerConfig,
|
|
7456
7734
|
defaultCodingAgentSystemPrompt: () => defaultCodingAgentSystemPrompt,
|
|
7457
7735
|
defaultCodingAgentMode: () => defaultCodingAgentMode,
|
|
@@ -7487,6 +7765,7 @@ __export(exports_runtime, {
|
|
|
7487
7765
|
codingAgentModeSchema: () => codingAgentModeSchema,
|
|
7488
7766
|
codingAgentModeOrder: () => codingAgentModeOrder,
|
|
7489
7767
|
codingAgentCallOptionsSchema: () => codingAgentCallOptionsSchema,
|
|
7768
|
+
clampMaxOutputTokens: () => clampMaxOutputTokens,
|
|
7490
7769
|
chatInteractionUserPromptPayloadSchema: () => chatInteractionUserPromptPayloadSchema,
|
|
7491
7770
|
chatInteractionUpsertRequestSchema: () => chatInteractionUpsertRequestSchema,
|
|
7492
7771
|
chatInteractionToolCallIdSchema: () => chatInteractionToolCallIdSchema,
|
|
@@ -7616,9 +7895,74 @@ async function runExportAction({
|
|
|
7616
7895
|
notify(`Export failed: ${error instanceof Error ? error.message : "unknown error"}`, "error");
|
|
7617
7896
|
}
|
|
7618
7897
|
}
|
|
7898
|
+
function latestAssistantText(messages) {
|
|
7899
|
+
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
7900
|
+
const message = messages[index];
|
|
7901
|
+
if (message?.role === "assistant") {
|
|
7902
|
+
const text = collectMessageText(message);
|
|
7903
|
+
if (text.trim()) {
|
|
7904
|
+
return text;
|
|
7905
|
+
}
|
|
7906
|
+
}
|
|
7907
|
+
}
|
|
7908
|
+
return null;
|
|
7909
|
+
}
|
|
7910
|
+
function conversationTranscript(messages) {
|
|
7911
|
+
return messages.filter((message) => message.role === "user" || message.role === "assistant").map((message) => {
|
|
7912
|
+
const text = collectMessageText(message);
|
|
7913
|
+
if (!text.trim()) {
|
|
7914
|
+
return null;
|
|
7915
|
+
}
|
|
7916
|
+
const label = message.role === "user" ? "You" : "Assistant";
|
|
7917
|
+
return `## ${label}
|
|
7918
|
+
|
|
7919
|
+
${text}`;
|
|
7920
|
+
}).filter((entry) => entry !== null).join(`
|
|
7921
|
+
|
|
7922
|
+
`);
|
|
7923
|
+
}
|
|
7924
|
+
async function runCopyAction({
|
|
7925
|
+
args,
|
|
7926
|
+
messages,
|
|
7927
|
+
notify,
|
|
7928
|
+
copyToClipboard
|
|
7929
|
+
}) {
|
|
7930
|
+
const scope = args.trim().toLowerCase() || "last";
|
|
7931
|
+
let payload = null;
|
|
7932
|
+
let label;
|
|
7933
|
+
if (scope === "all") {
|
|
7934
|
+
const transcript = conversationTranscript(messages);
|
|
7935
|
+
payload = transcript.trim() ? transcript : null;
|
|
7936
|
+
label = "conversation";
|
|
7937
|
+
} else if (scope === "code") {
|
|
7938
|
+
const lastText = latestAssistantText(messages);
|
|
7939
|
+
const blocks = lastText ? extractCodeBlocks(lastText) : [];
|
|
7940
|
+
payload = blocks.length > 0 ? blocks.map((block) => block.code).join(`
|
|
7941
|
+
|
|
7942
|
+
`) : null;
|
|
7943
|
+
label = blocks.length === 1 ? "code block" : "code blocks";
|
|
7944
|
+
} else if (scope === "last") {
|
|
7945
|
+
payload = latestAssistantText(messages);
|
|
7946
|
+
label = "last reply";
|
|
7947
|
+
} else {
|
|
7948
|
+
notify("Usage: /copy [last|code|all]", "error");
|
|
7949
|
+
return;
|
|
7950
|
+
}
|
|
7951
|
+
if (!payload) {
|
|
7952
|
+
notify(scope === "code" ? "No code blocks found in the last reply." : "Nothing to copy yet.", "error");
|
|
7953
|
+
return;
|
|
7954
|
+
}
|
|
7955
|
+
const copied = await copyToClipboard(payload);
|
|
7956
|
+
notify(copied ? `Copied ${label} to clipboard (${payload.length} chars).` : "Copy failed: clipboard unavailable in this terminal.", copied ? "info" : "error");
|
|
7957
|
+
}
|
|
7619
7958
|
function findChatSlashAction(text) {
|
|
7620
|
-
const
|
|
7621
|
-
return chatSlashActions.find((action) => action.shortcut ===
|
|
7959
|
+
const command = text.trim().split(/\s+/)[0]?.toLowerCase() ?? "";
|
|
7960
|
+
return chatSlashActions.find((action) => action.shortcut === command) ?? null;
|
|
7961
|
+
}
|
|
7962
|
+
function parseChatSlashArgs(text) {
|
|
7963
|
+
const trimmed = text.trim();
|
|
7964
|
+
const firstSpace = trimmed.search(/\s/);
|
|
7965
|
+
return firstSpace === -1 ? "" : trimmed.slice(firstSpace + 1).trim();
|
|
7622
7966
|
}
|
|
7623
7967
|
function getChatSlashActionById(id) {
|
|
7624
7968
|
return chatSlashActions.find((action) => action.id === id) ?? null;
|
|
@@ -7634,8 +7978,17 @@ var chatSlashActions;
|
|
|
7634
7978
|
var init_chat_slash_actions = __esm(() => {
|
|
7635
7979
|
init_src2();
|
|
7636
7980
|
init_client();
|
|
7981
|
+
init_markdown_code();
|
|
7637
7982
|
init_export_session_markdown();
|
|
7638
7983
|
chatSlashActions = [
|
|
7984
|
+
{
|
|
7985
|
+
kind: "chat-action",
|
|
7986
|
+
id: "copy",
|
|
7987
|
+
label: "Copy",
|
|
7988
|
+
description: "Copy chat content to the clipboard: /copy [last|code|all]",
|
|
7989
|
+
shortcut: "/copy",
|
|
7990
|
+
run: runCopyAction
|
|
7991
|
+
},
|
|
7639
7992
|
{
|
|
7640
7993
|
kind: "chat-action",
|
|
7641
7994
|
id: "export",
|
|
@@ -7776,7 +8129,7 @@ var init_auto_continue = __esm(() => {
|
|
|
7776
8129
|
import { useChat } from "@ai-sdk/react";
|
|
7777
8130
|
import {
|
|
7778
8131
|
DefaultChatTransport,
|
|
7779
|
-
isToolUIPart,
|
|
8132
|
+
isToolUIPart as isToolUIPart2,
|
|
7780
8133
|
lastAssistantMessageIsCompleteWithToolCalls,
|
|
7781
8134
|
safeValidateUIMessages
|
|
7782
8135
|
} from "ai";
|
|
@@ -7841,12 +8194,20 @@ function isTodoWriteOutput(toolName, output) {
|
|
|
7841
8194
|
return toolName === "todo_write" && typeof output === "object" && output !== null && Array.isArray(Reflect.get(output, "todos"));
|
|
7842
8195
|
}
|
|
7843
8196
|
function normalizeChatErrorMessage(message) {
|
|
8197
|
+
const structured = parseChatStreamError(message);
|
|
8198
|
+
if (structured) {
|
|
8199
|
+
return describeChatStreamError(structured);
|
|
8200
|
+
}
|
|
7844
8201
|
if (disconnectErrorPattern.test(message)) {
|
|
7845
8202
|
return recoverableDisconnectMessage;
|
|
7846
8203
|
}
|
|
7847
8204
|
return message;
|
|
7848
8205
|
}
|
|
7849
8206
|
function isRecoverableChatErrorMessage(message) {
|
|
8207
|
+
const structured = parseChatStreamError(message);
|
|
8208
|
+
if (structured) {
|
|
8209
|
+
return structured.retryable;
|
|
8210
|
+
}
|
|
7850
8211
|
return disconnectErrorPattern.test(message) || transientProviderErrorPattern.test(message);
|
|
7851
8212
|
}
|
|
7852
8213
|
function isRetryCommand(input) {
|
|
@@ -7860,30 +8221,38 @@ function queueToolOutput(outputResult) {
|
|
|
7860
8221
|
console.warn("Failed to add tool output.", outputError);
|
|
7861
8222
|
});
|
|
7862
8223
|
}
|
|
7863
|
-
function
|
|
7864
|
-
if (
|
|
7865
|
-
return false;
|
|
7866
|
-
}
|
|
7867
|
-
if (message.parts.length === 0) {
|
|
8224
|
+
function isIncompletePart(part) {
|
|
8225
|
+
if ((part.type === "text" || part.type === "reasoning") && Reflect.get(part, "state") === "streaming") {
|
|
7868
8226
|
return true;
|
|
7869
8227
|
}
|
|
7870
|
-
return
|
|
7871
|
-
if ((part.type === "text" || part.type === "reasoning") && Reflect.get(part, "state") === "streaming") {
|
|
7872
|
-
return true;
|
|
7873
|
-
}
|
|
7874
|
-
return isToolUIPart(part) && part.state === "input-streaming";
|
|
7875
|
-
});
|
|
8228
|
+
return isToolUIPart2(part) && part.state === "input-streaming";
|
|
7876
8229
|
}
|
|
7877
|
-
function
|
|
7878
|
-
let
|
|
7879
|
-
while (
|
|
7880
|
-
|
|
8230
|
+
function pruneIncompleteTrailingAssistantParts(messages) {
|
|
8231
|
+
let result = messages;
|
|
8232
|
+
while (result.length > 0) {
|
|
8233
|
+
const lastIndex = result.length - 1;
|
|
8234
|
+
const last = result[lastIndex];
|
|
8235
|
+
if (last.role !== "assistant") {
|
|
8236
|
+
break;
|
|
8237
|
+
}
|
|
8238
|
+
const completeParts = last.parts.filter((part) => !isIncompletePart(part));
|
|
8239
|
+
if (completeParts.length === last.parts.length) {
|
|
8240
|
+
break;
|
|
8241
|
+
}
|
|
8242
|
+
if (completeParts.length === 0) {
|
|
8243
|
+
result = result.slice(0, lastIndex);
|
|
8244
|
+
continue;
|
|
8245
|
+
}
|
|
8246
|
+
const next = result.slice();
|
|
8247
|
+
next[lastIndex] = { ...last, parts: completeParts };
|
|
8248
|
+
result = next;
|
|
8249
|
+
break;
|
|
7881
8250
|
}
|
|
7882
|
-
return
|
|
8251
|
+
return result;
|
|
7883
8252
|
}
|
|
7884
8253
|
function hasUnresolvedToolParts(messages) {
|
|
7885
8254
|
return messages.some((message) => message.parts.some((part) => {
|
|
7886
|
-
if (!
|
|
8255
|
+
if (!isToolUIPart2(part)) {
|
|
7887
8256
|
return false;
|
|
7888
8257
|
}
|
|
7889
8258
|
return ![
|
|
@@ -7893,6 +8262,22 @@ function hasUnresolvedToolParts(messages) {
|
|
|
7893
8262
|
].includes(part.state);
|
|
7894
8263
|
}));
|
|
7895
8264
|
}
|
|
8265
|
+
function countCompletedWork(messages) {
|
|
8266
|
+
let total = 0;
|
|
8267
|
+
for (const message of messages) {
|
|
8268
|
+
for (const part of message.parts) {
|
|
8269
|
+
if ((part.type === "text" || part.type === "reasoning") && Reflect.get(part, "state") !== "streaming") {
|
|
8270
|
+
total += 1;
|
|
8271
|
+
} else if (isToolUIPart2(part) && terminalToolPartStates.has(part.state)) {
|
|
8272
|
+
total += 1;
|
|
8273
|
+
}
|
|
8274
|
+
}
|
|
8275
|
+
}
|
|
8276
|
+
return total;
|
|
8277
|
+
}
|
|
8278
|
+
function sanitizeMessagesForRetry(messages) {
|
|
8279
|
+
return resolveDanglingToolParts(pruneIncompleteTrailingAssistantParts(messages));
|
|
8280
|
+
}
|
|
7896
8281
|
function hasActiveClientToolWork({
|
|
7897
8282
|
messages,
|
|
7898
8283
|
pendingApprovals,
|
|
@@ -7901,7 +8286,7 @@ function hasActiveClientToolWork({
|
|
|
7901
8286
|
const pendingApprovalIds = new Set(pendingApprovals.map((approval) => approval.toolCallId));
|
|
7902
8287
|
const pendingPromptIds = new Set(pendingUserPrompts.map((prompt) => prompt.toolCallId));
|
|
7903
8288
|
return messages.some((message) => message.parts.some((part) => {
|
|
7904
|
-
if (!
|
|
8289
|
+
if (!isToolUIPart2(part)) {
|
|
7905
8290
|
return false;
|
|
7906
8291
|
}
|
|
7907
8292
|
if (part.state === "input-streaming" || part.state === "approval-responded") {
|
|
@@ -8024,11 +8409,14 @@ function useCodingSessionChat({
|
|
|
8024
8409
|
maxAutoContinues: autoContinue?.maxAutoContinues ?? defaultAutoContinueLimits.maxAutoContinues
|
|
8025
8410
|
};
|
|
8026
8411
|
const maxErrorRetries = autoContinue?.maxErrorRetries ?? 5;
|
|
8027
|
-
const stallTimeoutMs = (autoContinue?.stallTimeoutSeconds ??
|
|
8412
|
+
const stallTimeoutMs = (autoContinue?.stallTimeoutSeconds ?? 180) * 1000;
|
|
8028
8413
|
const autoContinueLimitsRef = useRef(autoContinueLimits);
|
|
8029
8414
|
autoContinueLimitsRef.current = autoContinueLimits;
|
|
8030
8415
|
const maxErrorRetriesRef = useRef(maxErrorRetries);
|
|
8031
8416
|
maxErrorRetriesRef.current = maxErrorRetries;
|
|
8417
|
+
const maxNoProgressRetries = maxErrorRetries + 3;
|
|
8418
|
+
const maxNoProgressRetriesRef = useRef(maxNoProgressRetries);
|
|
8419
|
+
maxNoProgressRetriesRef.current = maxNoProgressRetries;
|
|
8032
8420
|
const stallTimeoutMsRef = useRef(stallTimeoutMs);
|
|
8033
8421
|
stallTimeoutMsRef.current = stallTimeoutMs;
|
|
8034
8422
|
const lastStreamActivityRef = useRef(Date.now());
|
|
@@ -8037,11 +8425,18 @@ function useCodingSessionChat({
|
|
|
8037
8425
|
const errorRetriesRef = useRef(0);
|
|
8038
8426
|
const errorRetryTimerRef = useRef(null);
|
|
8039
8427
|
const lastDecidedAssistantIdRef = useRef(null);
|
|
8428
|
+
const lastProgressMarkerRef = useRef(0);
|
|
8429
|
+
const noProgressRetriesRef = useRef(0);
|
|
8430
|
+
const taskStuckRef = useRef(false);
|
|
8431
|
+
const messagesRef = useRef([]);
|
|
8040
8432
|
const advanceTurnKey = useCallback(() => {
|
|
8041
8433
|
turnCounterRef.current += 1;
|
|
8042
8434
|
turnKeyRef.current = `turn-${Date.now()}-${turnCounterRef.current}`;
|
|
8043
8435
|
autoContinuesRef.current = 0;
|
|
8044
8436
|
errorRetriesRef.current = 0;
|
|
8437
|
+
lastProgressMarkerRef.current = 0;
|
|
8438
|
+
noProgressRetriesRef.current = 0;
|
|
8439
|
+
taskStuckRef.current = false;
|
|
8045
8440
|
lastDecidedAssistantIdRef.current = null;
|
|
8046
8441
|
if (errorRetryTimerRef.current) {
|
|
8047
8442
|
clearTimeout(errorRetryTimerRef.current);
|
|
@@ -8049,6 +8444,20 @@ function useCodingSessionChat({
|
|
|
8049
8444
|
}
|
|
8050
8445
|
setAutoContinueState(null);
|
|
8051
8446
|
}, []);
|
|
8447
|
+
const registerRetryProgress = useCallback((currentMessages) => {
|
|
8448
|
+
const marker = countCompletedWork(currentMessages);
|
|
8449
|
+
if (marker > lastProgressMarkerRef.current) {
|
|
8450
|
+
lastProgressMarkerRef.current = marker;
|
|
8451
|
+
noProgressRetriesRef.current = 0;
|
|
8452
|
+
return true;
|
|
8453
|
+
}
|
|
8454
|
+
noProgressRetriesRef.current += 1;
|
|
8455
|
+
if (noProgressRetriesRef.current > maxNoProgressRetriesRef.current) {
|
|
8456
|
+
taskStuckRef.current = true;
|
|
8457
|
+
return false;
|
|
8458
|
+
}
|
|
8459
|
+
return true;
|
|
8460
|
+
}, []);
|
|
8052
8461
|
modeRef.current = mode;
|
|
8053
8462
|
cwdRef.current = cwd;
|
|
8054
8463
|
permissionModeRef.current = permissionMode;
|
|
@@ -8058,8 +8467,27 @@ function useCodingSessionChat({
|
|
|
8058
8467
|
loadPersistedMessagesRef.current = loadPersistedMessages;
|
|
8059
8468
|
loadPersistedInteractionsRef.current = loadPersistedInteractions;
|
|
8060
8469
|
const transport = useMemo(() => {
|
|
8470
|
+
const monitoredFetch = async (input, init) => {
|
|
8471
|
+
const response = await globalThis.fetch(input, init);
|
|
8472
|
+
lastStreamActivityRef.current = Date.now();
|
|
8473
|
+
if (!response.body) {
|
|
8474
|
+
return response;
|
|
8475
|
+
}
|
|
8476
|
+
const monitoredBody = response.body.pipeThrough(new TransformStream({
|
|
8477
|
+
transform(chunk, controller) {
|
|
8478
|
+
lastStreamActivityRef.current = Date.now();
|
|
8479
|
+
controller.enqueue(chunk);
|
|
8480
|
+
}
|
|
8481
|
+
}));
|
|
8482
|
+
return new Response(monitoredBody, {
|
|
8483
|
+
status: response.status,
|
|
8484
|
+
statusText: response.statusText,
|
|
8485
|
+
headers: response.headers
|
|
8486
|
+
});
|
|
8487
|
+
};
|
|
8061
8488
|
return new DefaultChatTransport({
|
|
8062
8489
|
api: chatApi,
|
|
8490
|
+
fetch: monitoredFetch,
|
|
8063
8491
|
body: () => ({
|
|
8064
8492
|
cwd: cwdRef.current,
|
|
8065
8493
|
mode: modeRef.current,
|
|
@@ -8381,11 +8809,11 @@ function useCodingSessionChat({
|
|
|
8381
8809
|
setToolExecutionError("No recoverable response is waiting to retry.");
|
|
8382
8810
|
return;
|
|
8383
8811
|
}
|
|
8384
|
-
if (pendingApprovals.length > 0 || pendingUserPrompts.length > 0
|
|
8812
|
+
if (pendingApprovals.length > 0 || pendingUserPrompts.length > 0) {
|
|
8385
8813
|
setToolExecutionError("Resolve pending tool approvals or user prompts before retrying.");
|
|
8386
8814
|
return;
|
|
8387
8815
|
}
|
|
8388
|
-
const retryMessages =
|
|
8816
|
+
const retryMessages = sanitizeMessagesForRetry(messages);
|
|
8389
8817
|
setMessages(retryMessages);
|
|
8390
8818
|
clearError();
|
|
8391
8819
|
setToolExecutionError(null);
|
|
@@ -8400,15 +8828,18 @@ function useCodingSessionChat({
|
|
|
8400
8828
|
setMessages
|
|
8401
8829
|
]);
|
|
8402
8830
|
useEffect(() => {
|
|
8403
|
-
if (status === "
|
|
8831
|
+
if (status === "ready" && !error) {
|
|
8404
8832
|
errorRetriesRef.current = 0;
|
|
8405
8833
|
}
|
|
8406
|
-
}, [status]);
|
|
8834
|
+
}, [error, status]);
|
|
8407
8835
|
useEffect(() => {
|
|
8408
8836
|
if (status === "streaming" || status === "submitted") {
|
|
8409
8837
|
lastStreamActivityRef.current = Date.now();
|
|
8410
8838
|
}
|
|
8411
8839
|
}, [messages, status]);
|
|
8840
|
+
useEffect(() => {
|
|
8841
|
+
messagesRef.current = messages;
|
|
8842
|
+
}, [messages]);
|
|
8412
8843
|
useEffect(() => {
|
|
8413
8844
|
if (status !== "streaming" && status !== "submitted") {
|
|
8414
8845
|
return;
|
|
@@ -8421,7 +8852,15 @@ function useCodingSessionChat({
|
|
|
8421
8852
|
})) {
|
|
8422
8853
|
return;
|
|
8423
8854
|
}
|
|
8424
|
-
if (stallRecoveryInFlightRef.current || errorRetriesRef.current >= maxErrorRetriesRef.current) {
|
|
8855
|
+
if (taskStuckRef.current || stallRecoveryInFlightRef.current || errorRetriesRef.current >= maxErrorRetriesRef.current) {
|
|
8856
|
+
return;
|
|
8857
|
+
}
|
|
8858
|
+
if (!registerRetryProgress(messagesRef.current)) {
|
|
8859
|
+
setAutoContinueState({
|
|
8860
|
+
attempt: errorRetriesRef.current,
|
|
8861
|
+
kind: "none",
|
|
8862
|
+
guardTripped: "no-progress"
|
|
8863
|
+
});
|
|
8425
8864
|
return;
|
|
8426
8865
|
}
|
|
8427
8866
|
stallRecoveryInFlightRef.current = true;
|
|
@@ -8433,7 +8872,7 @@ function useCodingSessionChat({
|
|
|
8433
8872
|
(async () => {
|
|
8434
8873
|
try {
|
|
8435
8874
|
await stop();
|
|
8436
|
-
setMessages((current) =>
|
|
8875
|
+
setMessages((current) => sanitizeMessagesForRetry(current));
|
|
8437
8876
|
clearError();
|
|
8438
8877
|
setToolExecutionError(null);
|
|
8439
8878
|
await sendMessage();
|
|
@@ -8443,12 +8882,12 @@ function useCodingSessionChat({
|
|
|
8443
8882
|
})();
|
|
8444
8883
|
}, 15000);
|
|
8445
8884
|
return () => clearInterval(intervalId);
|
|
8446
|
-
}, [clearError, sendMessage, setMessages, status, stop]);
|
|
8885
|
+
}, [clearError, registerRetryProgress, sendMessage, setMessages, status, stop]);
|
|
8447
8886
|
useEffect(() => {
|
|
8448
8887
|
if (status !== "ready" || error) {
|
|
8449
8888
|
return;
|
|
8450
8889
|
}
|
|
8451
|
-
if (isHistoryLoading || pendingApprovals.length > 0 || pendingUserPrompts.length > 0 || hasUnresolvedToolParts(messages)) {
|
|
8890
|
+
if (taskStuckRef.current || isHistoryLoading || pendingApprovals.length > 0 || pendingUserPrompts.length > 0 || hasUnresolvedToolParts(messages)) {
|
|
8452
8891
|
return;
|
|
8453
8892
|
}
|
|
8454
8893
|
const lastMessage = messages[messages.length - 1];
|
|
@@ -8500,20 +8939,25 @@ function useCodingSessionChat({
|
|
|
8500
8939
|
if (!error?.message || !isRecoverableChatErrorMessage(error.message)) {
|
|
8501
8940
|
return;
|
|
8502
8941
|
}
|
|
8503
|
-
if (pendingApprovals.length > 0 || pendingUserPrompts.length > 0 || errorRetryTimerRef.current || stallRecoveryInFlightRef.current) {
|
|
8942
|
+
if (taskStuckRef.current || pendingApprovals.length > 0 || pendingUserPrompts.length > 0 || errorRetryTimerRef.current || stallRecoveryInFlightRef.current) {
|
|
8504
8943
|
return;
|
|
8505
8944
|
}
|
|
8506
8945
|
if (errorRetriesRef.current >= maxErrorRetriesRef.current) {
|
|
8507
8946
|
return;
|
|
8508
8947
|
}
|
|
8509
|
-
const retryMessages =
|
|
8510
|
-
if (hasUnresolvedToolParts(retryMessages)) {
|
|
8511
|
-
return;
|
|
8512
|
-
}
|
|
8948
|
+
const retryMessages = sanitizeMessagesForRetry(messages);
|
|
8513
8949
|
const attempt = errorRetriesRef.current + 1;
|
|
8514
8950
|
const delay = Math.min(errorRetryBaseDelayMs * 2 ** (attempt - 1), errorRetryMaxDelayMs);
|
|
8515
8951
|
errorRetryTimerRef.current = setTimeout(() => {
|
|
8516
8952
|
errorRetryTimerRef.current = null;
|
|
8953
|
+
if (!registerRetryProgress(messagesRef.current)) {
|
|
8954
|
+
setAutoContinueState({
|
|
8955
|
+
attempt: errorRetriesRef.current,
|
|
8956
|
+
kind: "none",
|
|
8957
|
+
guardTripped: "no-progress"
|
|
8958
|
+
});
|
|
8959
|
+
return;
|
|
8960
|
+
}
|
|
8517
8961
|
errorRetriesRef.current = attempt;
|
|
8518
8962
|
setAutoContinueState({ attempt, kind: "retry-error" });
|
|
8519
8963
|
setMessages(retryMessages);
|
|
@@ -8533,6 +8977,7 @@ function useCodingSessionChat({
|
|
|
8533
8977
|
messages,
|
|
8534
8978
|
pendingApprovals.length,
|
|
8535
8979
|
pendingUserPrompts.length,
|
|
8980
|
+
registerRetryProgress,
|
|
8536
8981
|
sendMessage,
|
|
8537
8982
|
setMessages
|
|
8538
8983
|
]);
|
|
@@ -8611,7 +9056,7 @@ function useCodingSessionChat({
|
|
|
8611
9056
|
if (cancelled) {
|
|
8612
9057
|
return;
|
|
8613
9058
|
}
|
|
8614
|
-
const resumableMessages = restoredApprovals.length === 0 && restoredPrompts.length === 0 ?
|
|
9059
|
+
const resumableMessages = restoredApprovals.length === 0 && restoredPrompts.length === 0 ? pruneIncompleteTrailingAssistantParts(validatedMessages) : validatedMessages;
|
|
8615
9060
|
setMessagesRef.current(resumableMessages);
|
|
8616
9061
|
setPendingApprovals(restoredApprovals);
|
|
8617
9062
|
setPendingUserPrompts(restoredPrompts);
|
|
@@ -8732,9 +9177,10 @@ function useCodingSessionChat({
|
|
|
8732
9177
|
isSessionIdValid
|
|
8733
9178
|
};
|
|
8734
9179
|
}
|
|
8735
|
-
var recoverableDisconnectMessage = "Connection interrupted. Please retry or regenerate your last message.", buildModeAutoPromptResponse = "Proceed with implementation in Build mode. Continue without additional plan questions.", chatMessageUpdateThrottleMs = 50, retryCommandPattern, codingToolNameSet, errorRetryBaseDelayMs = 1000, errorRetryMaxDelayMs = 8000, disconnectErrorPattern, transientProviderErrorPattern;
|
|
9180
|
+
var recoverableDisconnectMessage = "Connection interrupted. Please retry or regenerate your last message.", buildModeAutoPromptResponse = "Proceed with implementation in Build mode. Continue without additional plan questions.", chatMessageUpdateThrottleMs = 50, retryCommandPattern, codingToolNameSet, errorRetryBaseDelayMs = 1000, errorRetryMaxDelayMs = 8000, disconnectErrorPattern, transientProviderErrorPattern, terminalToolPartStates;
|
|
8736
9181
|
var init_use_coding_session_chat = __esm(() => {
|
|
8737
9182
|
init_agent_tools();
|
|
9183
|
+
init_chat_error();
|
|
8738
9184
|
init_chat_interaction_schemas();
|
|
8739
9185
|
init_output_utils();
|
|
8740
9186
|
init_resolve_within_workspace();
|
|
@@ -8744,10 +9190,16 @@ var init_use_coding_session_chat = __esm(() => {
|
|
|
8744
9190
|
init_schema9();
|
|
8745
9191
|
init_runtime12();
|
|
8746
9192
|
init_auto_continue();
|
|
9193
|
+
init_normalize_provider_messages();
|
|
8747
9194
|
retryCommandPattern = /^\/?(retry|regenerate)$/i;
|
|
8748
9195
|
codingToolNameSet = new Set(Object.keys(codingToolInputSchemas));
|
|
8749
9196
|
disconnectErrorPattern = /(failed to fetch|networkerror|socket|connection|aborted|terminated|timed?\s?out|timeout|econnreset)/i;
|
|
8750
9197
|
transientProviderErrorPattern = /(rate.?limit|too many requests|\b429\b|overloaded|quota)/i;
|
|
9198
|
+
terminalToolPartStates = new Set([
|
|
9199
|
+
"output-available",
|
|
9200
|
+
"output-error",
|
|
9201
|
+
"output-denied"
|
|
9202
|
+
]);
|
|
8751
9203
|
});
|
|
8752
9204
|
|
|
8753
9205
|
// packages/ai/src/react/index.ts
|
|
@@ -8755,6 +9207,59 @@ var init_react = __esm(() => {
|
|
|
8755
9207
|
init_use_coding_session_chat();
|
|
8756
9208
|
});
|
|
8757
9209
|
|
|
9210
|
+
// apps/cli/src/lib/clipboard.ts
|
|
9211
|
+
import { platform as platform3 } from "os";
|
|
9212
|
+
async function copyText(renderer, text) {
|
|
9213
|
+
if (!text) {
|
|
9214
|
+
return false;
|
|
9215
|
+
}
|
|
9216
|
+
let copied = false;
|
|
9217
|
+
try {
|
|
9218
|
+
if (renderer?.copyToClipboardOSC52?.(text)) {
|
|
9219
|
+
copied = true;
|
|
9220
|
+
}
|
|
9221
|
+
} catch {}
|
|
9222
|
+
if (await copyViaNativeTool(text)) {
|
|
9223
|
+
copied = true;
|
|
9224
|
+
}
|
|
9225
|
+
return copied;
|
|
9226
|
+
}
|
|
9227
|
+
function nativeClipboardCommand() {
|
|
9228
|
+
switch (platform3()) {
|
|
9229
|
+
case "win32":
|
|
9230
|
+
return ["clip"];
|
|
9231
|
+
case "darwin":
|
|
9232
|
+
return ["pbcopy"];
|
|
9233
|
+
default:
|
|
9234
|
+
return null;
|
|
9235
|
+
}
|
|
9236
|
+
}
|
|
9237
|
+
async function copyViaNativeTool(text) {
|
|
9238
|
+
const direct = nativeClipboardCommand();
|
|
9239
|
+
if (direct) {
|
|
9240
|
+
return spawnCopy(direct, text);
|
|
9241
|
+
}
|
|
9242
|
+
if (await spawnCopy(["wl-copy"], text)) {
|
|
9243
|
+
return true;
|
|
9244
|
+
}
|
|
9245
|
+
return spawnCopy(["xclip", "-selection", "clipboard"], text);
|
|
9246
|
+
}
|
|
9247
|
+
async function spawnCopy(command, text) {
|
|
9248
|
+
try {
|
|
9249
|
+
const proc = Bun.spawn(command, {
|
|
9250
|
+
stdin: "pipe",
|
|
9251
|
+
stdout: "ignore",
|
|
9252
|
+
stderr: "ignore"
|
|
9253
|
+
});
|
|
9254
|
+
proc.stdin.write(text);
|
|
9255
|
+
await proc.stdin.end();
|
|
9256
|
+
return await proc.exited === 0;
|
|
9257
|
+
} catch {
|
|
9258
|
+
return false;
|
|
9259
|
+
}
|
|
9260
|
+
}
|
|
9261
|
+
var init_clipboard = () => {};
|
|
9262
|
+
|
|
8758
9263
|
// apps/cli/src/utils/text-utils.ts
|
|
8759
9264
|
function truncateInline2(text, maxLength = 96) {
|
|
8760
9265
|
const normalized = text.replace(/\s+/g, " ").trim();
|
|
@@ -9575,7 +10080,7 @@ function collapseDiff(diff) {
|
|
|
9575
10080
|
hiddenLines: lines.length - cut
|
|
9576
10081
|
};
|
|
9577
10082
|
}
|
|
9578
|
-
function ChatDiffCard({ path:
|
|
10083
|
+
function ChatDiffCard({ path: path16, diff }) {
|
|
9579
10084
|
const wasPreTruncated = diff.trimEnd().endsWith(TRUNCATION_MARKER);
|
|
9580
10085
|
const cleanDiff = wasPreTruncated ? diff.trimEnd().slice(0, -TRUNCATION_MARKER.length).trimEnd() : diff;
|
|
9581
10086
|
const { text, hiddenLines } = collapseDiff(cleanDiff);
|
|
@@ -9594,14 +10099,14 @@ function ChatDiffCard({ path: path15, diff }) {
|
|
|
9594
10099
|
children: /* @__PURE__ */ jsxDEV11("text", {
|
|
9595
10100
|
fg: cliTheme.text.secondary,
|
|
9596
10101
|
attributes: TextAttributes7.BOLD,
|
|
9597
|
-
children:
|
|
10102
|
+
children: path16
|
|
9598
10103
|
}, undefined, false, undefined, this)
|
|
9599
10104
|
}, undefined, false, undefined, this),
|
|
9600
10105
|
/* @__PURE__ */ jsxDEV11("diff", {
|
|
9601
10106
|
width: "100%",
|
|
9602
10107
|
diff: text,
|
|
9603
10108
|
view: "unified",
|
|
9604
|
-
filetype: inferFiletype(
|
|
10109
|
+
filetype: inferFiletype(path16),
|
|
9605
10110
|
syntaxStyle: codeSyntaxStyle,
|
|
9606
10111
|
showLineNumbers: true,
|
|
9607
10112
|
addedBg,
|
|
@@ -9674,11 +10179,11 @@ function getFileEditDiff(part) {
|
|
|
9674
10179
|
return null;
|
|
9675
10180
|
}
|
|
9676
10181
|
const diff = Reflect.get(output, "diff");
|
|
9677
|
-
const
|
|
9678
|
-
if (typeof diff !== "string" || !diff.trim() || typeof
|
|
10182
|
+
const path16 = Reflect.get(output, "path");
|
|
10183
|
+
if (typeof diff !== "string" || !diff.trim() || typeof path16 !== "string") {
|
|
9679
10184
|
return null;
|
|
9680
10185
|
}
|
|
9681
|
-
return { path:
|
|
10186
|
+
return { path: path16, diff };
|
|
9682
10187
|
}
|
|
9683
10188
|
function getSecondaryParams(input, target) {
|
|
9684
10189
|
if (!input || typeof input !== "object") {
|
|
@@ -9802,7 +10307,7 @@ var init_chat_message_tool_invocation_part = __esm(() => {
|
|
|
9802
10307
|
});
|
|
9803
10308
|
|
|
9804
10309
|
// apps/cli/src/components/chat/chat-message.tsx
|
|
9805
|
-
import { isToolUIPart as
|
|
10310
|
+
import { isToolUIPart as isToolUIPart3 } from "ai";
|
|
9806
10311
|
import { TextAttributes as TextAttributes9 } from "@opentui/core";
|
|
9807
10312
|
import { jsxDEV as jsxDEV13 } from "@opentui/react/jsx-dev-runtime";
|
|
9808
10313
|
function ChatMessage({ message, pendingApprovalIds }) {
|
|
@@ -9819,7 +10324,7 @@ function ChatMessage({ message, pendingApprovalIds }) {
|
|
|
9819
10324
|
part
|
|
9820
10325
|
}, key, false, undefined, this);
|
|
9821
10326
|
}
|
|
9822
|
-
if (
|
|
10327
|
+
if (isToolUIPart3(part)) {
|
|
9823
10328
|
return /* @__PURE__ */ jsxDEV13(ChatMessageToolInvocationPart, {
|
|
9824
10329
|
part,
|
|
9825
10330
|
pendingApprovalIds
|
|
@@ -10674,6 +11179,60 @@ var init_loading_timer = __esm(() => {
|
|
|
10674
11179
|
init_cli_theme();
|
|
10675
11180
|
});
|
|
10676
11181
|
|
|
11182
|
+
// apps/cli/src/components/chat/copy-mode-overlay.tsx
|
|
11183
|
+
import { TextAttributes as TextAttributes15 } from "@opentui/core";
|
|
11184
|
+
import { jsxDEV as jsxDEV20 } from "@opentui/react/jsx-dev-runtime";
|
|
11185
|
+
function previewOf(message) {
|
|
11186
|
+
const text = collectMessageText(message).replace(/\s+/g, " ").trim();
|
|
11187
|
+
return text.length > 0 ? text : "(no text)";
|
|
11188
|
+
}
|
|
11189
|
+
function CopyModeOverlay({ messages, selectedIndex }) {
|
|
11190
|
+
const total = messages.length;
|
|
11191
|
+
const half = Math.floor(WINDOW_SIZE / 2);
|
|
11192
|
+
const end = Math.min(total, Math.max(selectedIndex + half + 1, WINDOW_SIZE));
|
|
11193
|
+
const start = Math.max(0, end - WINDOW_SIZE);
|
|
11194
|
+
const visible = messages.slice(start, end);
|
|
11195
|
+
return /* @__PURE__ */ jsxDEV20("box", {
|
|
11196
|
+
flexDirection: "column",
|
|
11197
|
+
paddingX: 1,
|
|
11198
|
+
paddingY: 1,
|
|
11199
|
+
borderStyle: "single",
|
|
11200
|
+
borderColor: cliTheme.accent.primary,
|
|
11201
|
+
children: [
|
|
11202
|
+
/* @__PURE__ */ jsxDEV20("text", {
|
|
11203
|
+
fg: cliTheme.accent.primary,
|
|
11204
|
+
attributes: TextAttributes15.BOLD,
|
|
11205
|
+
children: "Copy mode \u2014 \u2191/\u2193 select \xB7 Enter copy \xB7 c code blocks \xB7 Esc exit"
|
|
11206
|
+
}, undefined, false, undefined, this),
|
|
11207
|
+
visible.map((message, offset) => {
|
|
11208
|
+
const index = start + offset;
|
|
11209
|
+
const isSelected = index === selectedIndex;
|
|
11210
|
+
const rowColors = getOverlayRowColors(isSelected);
|
|
11211
|
+
const role = message.role === "user" ? "You" : "Assistant";
|
|
11212
|
+
return /* @__PURE__ */ jsxDEV20("box", {
|
|
11213
|
+
paddingX: 1,
|
|
11214
|
+
backgroundColor: rowColors.backgroundColor,
|
|
11215
|
+
children: /* @__PURE__ */ jsxDEV20("text", {
|
|
11216
|
+
fg: rowColors.primaryTextColor,
|
|
11217
|
+
children: `${role}: ${truncateInline2(previewOf(message), 80)}`
|
|
11218
|
+
}, undefined, false, undefined, this)
|
|
11219
|
+
}, message.id, false, undefined, this);
|
|
11220
|
+
}),
|
|
11221
|
+
total > visible.length ? /* @__PURE__ */ jsxDEV20("text", {
|
|
11222
|
+
fg: cliTheme.text.muted,
|
|
11223
|
+
attributes: TextAttributes15.DIM,
|
|
11224
|
+
children: `${selectedIndex + 1}/${total}`
|
|
11225
|
+
}, undefined, false, undefined, this) : null
|
|
11226
|
+
]
|
|
11227
|
+
}, undefined, true, undefined, this);
|
|
11228
|
+
}
|
|
11229
|
+
var WINDOW_SIZE = 7;
|
|
11230
|
+
var init_copy_mode_overlay = __esm(() => {
|
|
11231
|
+
init_src2();
|
|
11232
|
+
init_cli_theme();
|
|
11233
|
+
init_text_utils();
|
|
11234
|
+
});
|
|
11235
|
+
|
|
10677
11236
|
// apps/cli/src/hooks/use-auto-continue-config.ts
|
|
10678
11237
|
import { useEffect as useEffect5, useState as useState7 } from "react";
|
|
10679
11238
|
function useAutoContinueConfig() {
|
|
@@ -10813,7 +11372,7 @@ var init_chat_context_utils = __esm(() => {
|
|
|
10813
11372
|
|
|
10814
11373
|
// apps/cli/src/utils/file-mentions.ts
|
|
10815
11374
|
import { promises as fs6 } from "fs";
|
|
10816
|
-
import
|
|
11375
|
+
import path16 from "path";
|
|
10817
11376
|
function extractFileMentions(text) {
|
|
10818
11377
|
const mentions = new Set;
|
|
10819
11378
|
for (const match of text.matchAll(mentionTokenPattern)) {
|
|
@@ -10835,8 +11394,8 @@ async function appendMentionAttachments(text, cwd) {
|
|
|
10835
11394
|
}
|
|
10836
11395
|
const attachmentBlocks = [];
|
|
10837
11396
|
for (const mentionPath of mentionPaths) {
|
|
10838
|
-
const absolutePath =
|
|
10839
|
-
if (!absolutePath.startsWith(
|
|
11397
|
+
const absolutePath = path16.resolve(cwd, mentionPath);
|
|
11398
|
+
if (!absolutePath.startsWith(path16.resolve(cwd))) {
|
|
10840
11399
|
continue;
|
|
10841
11400
|
}
|
|
10842
11401
|
try {
|
|
@@ -10893,10 +11452,10 @@ var init_file_mentions = __esm(() => {
|
|
|
10893
11452
|
});
|
|
10894
11453
|
|
|
10895
11454
|
// apps/cli/src/screens/chat-screen.tsx
|
|
10896
|
-
import { useKeyboard as useKeyboard4 } from "@opentui/react";
|
|
11455
|
+
import { useKeyboard as useKeyboard4, useRenderer } from "@opentui/react";
|
|
10897
11456
|
import { Fragment, useCallback as useCallback4, useEffect as useEffect8, useMemo as useMemo4, useRef as useRef4, useState as useState10 } from "react";
|
|
10898
11457
|
import { useLocation, useNavigate, useParams } from "react-router";
|
|
10899
|
-
import { jsxDEV as
|
|
11458
|
+
import { jsxDEV as jsxDEV21 } from "@opentui/react/jsx-dev-runtime";
|
|
10900
11459
|
function shouldImplementApprovedPlan(response) {
|
|
10901
11460
|
if (response.selectedValue === "yes") {
|
|
10902
11461
|
return true;
|
|
@@ -11139,14 +11698,44 @@ function ChatScreen() {
|
|
|
11139
11698
|
const notifyChatAction = useCallback4((text, tone = "info") => {
|
|
11140
11699
|
setActionNotice({ text, tone });
|
|
11141
11700
|
}, []);
|
|
11142
|
-
const
|
|
11143
|
-
|
|
11144
|
-
|
|
11145
|
-
|
|
11146
|
-
|
|
11147
|
-
|
|
11701
|
+
const renderer = useRenderer();
|
|
11702
|
+
const [copyModeOpen, setCopyModeOpen] = useState10(false);
|
|
11703
|
+
const [copyModeIndex, setCopyModeIndex] = useState10(0);
|
|
11704
|
+
const copyableMessages = useMemo4(() => messages.filter((message) => (message.role === "user" || message.role === "assistant") && collectMessageText(message).trim().length > 0), [messages]);
|
|
11705
|
+
const copySelectedMessage = useCallback4(async (kind) => {
|
|
11706
|
+
const message = copyableMessages[copyModeIndex];
|
|
11707
|
+
if (!message) {
|
|
11708
|
+
return;
|
|
11709
|
+
}
|
|
11710
|
+
const fullText = collectMessageText(message);
|
|
11711
|
+
let payload = fullText;
|
|
11712
|
+
let label = "message";
|
|
11713
|
+
if (kind === "code") {
|
|
11714
|
+
const blocks = extractCodeBlocks(fullText);
|
|
11715
|
+
if (blocks.length === 0) {
|
|
11716
|
+
notifyChatAction("No code blocks in this message.", "error");
|
|
11717
|
+
return;
|
|
11718
|
+
}
|
|
11719
|
+
payload = blocks.map((block) => block.code).join(`
|
|
11720
|
+
|
|
11721
|
+
`);
|
|
11722
|
+
label = blocks.length === 1 ? "code block" : "code blocks";
|
|
11723
|
+
}
|
|
11724
|
+
const copied = await copyText(renderer, payload);
|
|
11725
|
+
notifyChatAction(copied ? `Copied ${label} to clipboard (${payload.length} chars).` : "Copy failed: clipboard unavailable in this terminal.", copied ? "info" : "error");
|
|
11726
|
+
setCopyModeOpen(false);
|
|
11727
|
+
}, [copyModeIndex, copyableMessages, notifyChatAction, renderer]);
|
|
11728
|
+
const runChatSlashAction = useCallback4((action, args = "") => {
|
|
11729
|
+
action.run({
|
|
11730
|
+
sessionId,
|
|
11731
|
+
args,
|
|
11732
|
+
messages,
|
|
11733
|
+
setContextState,
|
|
11734
|
+
notify: notifyChatAction,
|
|
11735
|
+
setPermissionMode: setPermissionModeToState,
|
|
11736
|
+
copyToClipboard: (text) => copyText(renderer, text)
|
|
11148
11737
|
});
|
|
11149
|
-
}, [notifyChatAction, sessionId]);
|
|
11738
|
+
}, [messages, notifyChatAction, renderer, sessionId]);
|
|
11150
11739
|
const updatePermissionMode = useCallback4(async (newMode) => {
|
|
11151
11740
|
setPermissionMode(newMode);
|
|
11152
11741
|
setPermissionSelectorOpen(false);
|
|
@@ -11221,7 +11810,11 @@ function ChatScreen() {
|
|
|
11221
11810
|
const action = findChatSlashAction(text);
|
|
11222
11811
|
if (action) {
|
|
11223
11812
|
closeSlashMenu();
|
|
11224
|
-
|
|
11813
|
+
if (action.id === "permission") {
|
|
11814
|
+
setPermissionSelectorOpen(true);
|
|
11815
|
+
return;
|
|
11816
|
+
}
|
|
11817
|
+
runChatSlashAction(action, parseChatSlashArgs(text));
|
|
11225
11818
|
return;
|
|
11226
11819
|
}
|
|
11227
11820
|
if (navigateIfSlashRoute(text)) {
|
|
@@ -11279,6 +11872,50 @@ function ChatScreen() {
|
|
|
11279
11872
|
}, [mode, queuedImplementationInstruction, sendDirectMessage]);
|
|
11280
11873
|
useKeyboard4((keyEvent) => {
|
|
11281
11874
|
const keyName = keyEvent.name.toLowerCase();
|
|
11875
|
+
if (copyModeOpen) {
|
|
11876
|
+
if (isEscapeKey(keyName)) {
|
|
11877
|
+
keyEvent.preventDefault();
|
|
11878
|
+
keyEvent.stopPropagation();
|
|
11879
|
+
setCopyModeOpen(false);
|
|
11880
|
+
return;
|
|
11881
|
+
}
|
|
11882
|
+
if (isUpKey(keyName, { vim: true })) {
|
|
11883
|
+
keyEvent.preventDefault();
|
|
11884
|
+
keyEvent.stopPropagation();
|
|
11885
|
+
setCopyModeIndex((index) => Math.max(0, index - 1));
|
|
11886
|
+
return;
|
|
11887
|
+
}
|
|
11888
|
+
if (isDownKey(keyName, { vim: true })) {
|
|
11889
|
+
keyEvent.preventDefault();
|
|
11890
|
+
keyEvent.stopPropagation();
|
|
11891
|
+
setCopyModeIndex((index) => Math.min(copyableMessages.length - 1, index + 1));
|
|
11892
|
+
return;
|
|
11893
|
+
}
|
|
11894
|
+
if (isEnterKey(keyName) || keyName === "y") {
|
|
11895
|
+
keyEvent.preventDefault();
|
|
11896
|
+
keyEvent.stopPropagation();
|
|
11897
|
+
copySelectedMessage("text");
|
|
11898
|
+
return;
|
|
11899
|
+
}
|
|
11900
|
+
if (keyName === "c") {
|
|
11901
|
+
keyEvent.preventDefault();
|
|
11902
|
+
keyEvent.stopPropagation();
|
|
11903
|
+
copySelectedMessage("code");
|
|
11904
|
+
return;
|
|
11905
|
+
}
|
|
11906
|
+
return;
|
|
11907
|
+
}
|
|
11908
|
+
const isCtrlY = keyName === "y" && keyEvent.ctrl && !keyEvent.meta && !keyEvent.super && !keyEvent.hyper && !keyEvent.shift;
|
|
11909
|
+
if (isCtrlY) {
|
|
11910
|
+
if (!isSessionIdValid || hasBlockingPopup || slashMenuOpen || copyableMessages.length === 0) {
|
|
11911
|
+
return;
|
|
11912
|
+
}
|
|
11913
|
+
keyEvent.preventDefault();
|
|
11914
|
+
keyEvent.stopPropagation();
|
|
11915
|
+
setCopyModeIndex(copyableMessages.length - 1);
|
|
11916
|
+
setCopyModeOpen(true);
|
|
11917
|
+
return;
|
|
11918
|
+
}
|
|
11282
11919
|
const isPlainTab = (keyName === "tab" || keyEvent.sequence === "\t") && !keyEvent.ctrl && !keyEvent.meta && !keyEvent.super && !keyEvent.hyper && !keyEvent.shift;
|
|
11283
11920
|
const isCtrlT = keyName === "t" && keyEvent.ctrl && !keyEvent.meta && !keyEvent.super && !keyEvent.hyper && !keyEvent.shift;
|
|
11284
11921
|
if (!isPlainTab && !isCtrlT) {
|
|
@@ -11291,74 +11928,77 @@ function ChatScreen() {
|
|
|
11291
11928
|
keyEvent.stopPropagation();
|
|
11292
11929
|
setMode((currentMode) => cycleCodingAgentMode(currentMode));
|
|
11293
11930
|
});
|
|
11294
|
-
return /* @__PURE__ */
|
|
11931
|
+
return /* @__PURE__ */ jsxDEV21("box", {
|
|
11295
11932
|
width: "100%",
|
|
11296
11933
|
height: "100%",
|
|
11297
|
-
children: /* @__PURE__ */
|
|
11934
|
+
children: /* @__PURE__ */ jsxDEV21(ChatShell, {
|
|
11298
11935
|
hasMessages: messages.length > 0 || isStreaming || pendingApprovals.length > 0 || activeUserPrompt !== null || planConfirmationOpen,
|
|
11299
11936
|
messageCount: messages.length,
|
|
11300
11937
|
errorMessage,
|
|
11301
|
-
inputArea: /* @__PURE__ */
|
|
11938
|
+
inputArea: /* @__PURE__ */ jsxDEV21(ChatTextArea, {
|
|
11302
11939
|
placeholder: isLoading ? "Waiting for response..." : "Reply... (@ to attach files)",
|
|
11303
|
-
focused: canTypeInChat,
|
|
11304
|
-
disabled: !canTypeInChat,
|
|
11940
|
+
focused: canTypeInChat && !copyModeOpen,
|
|
11941
|
+
disabled: !canTypeInChat || copyModeOpen,
|
|
11305
11942
|
slashMenuOpen,
|
|
11306
11943
|
mentionCandidates,
|
|
11307
11944
|
onTextChange: syncSlashMenuFromInput,
|
|
11308
|
-
beforeInput: slashMenuOpen ? /* @__PURE__ */
|
|
11945
|
+
beforeInput: slashMenuOpen ? /* @__PURE__ */ jsxDEV21(SlashPageMenu, {
|
|
11309
11946
|
query: slashMenuQuery,
|
|
11310
11947
|
selectedIndex: selectedSlashRouteIndex,
|
|
11311
11948
|
routes: slashRoutes
|
|
11312
11949
|
}, undefined, false, undefined, this) : null,
|
|
11313
|
-
footer: /* @__PURE__ */
|
|
11950
|
+
footer: /* @__PURE__ */ jsxDEV21("box", {
|
|
11314
11951
|
flexDirection: "row",
|
|
11315
11952
|
justifyContent: "space-between",
|
|
11316
11953
|
children: [
|
|
11317
|
-
|
|
11954
|
+
copyModeOpen ? /* @__PURE__ */ jsxDEV21("text", {
|
|
11955
|
+
fg: cliTheme.text.muted,
|
|
11956
|
+
children: "Copy mode: \u2191/\u2193 select \xB7 Enter copy \xB7 c code \xB7 Esc exit"
|
|
11957
|
+
}, undefined, false, undefined, this) : canRetryRecoverableResponse ? /* @__PURE__ */ jsxDEV21("text", {
|
|
11318
11958
|
fg: cliTheme.text.muted,
|
|
11319
11959
|
children: "Type retry or regenerate to try again"
|
|
11320
|
-
}, undefined, false, undefined, this) : pendingApprovals.length > 0 ? /* @__PURE__ */
|
|
11960
|
+
}, undefined, false, undefined, this) : pendingApprovals.length > 0 ? /* @__PURE__ */ jsxDEV21("text", {
|
|
11321
11961
|
fg: cliTheme.text.muted,
|
|
11322
11962
|
children: "Use approval card or approve/deny commands"
|
|
11323
|
-
}, undefined, false, undefined, this) : hasBlockingPopup ? /* @__PURE__ */
|
|
11963
|
+
}, undefined, false, undefined, this) : hasBlockingPopup ? /* @__PURE__ */ jsxDEV21("text", {
|
|
11324
11964
|
fg: cliTheme.text.muted,
|
|
11325
11965
|
children: "Complete the inline prompt to continue"
|
|
11326
|
-
}, undefined, false, undefined, this) : slashMenuOpen ? /* @__PURE__ */
|
|
11966
|
+
}, undefined, false, undefined, this) : slashMenuOpen ? /* @__PURE__ */ jsxDEV21("text", {
|
|
11327
11967
|
fg: cliTheme.text.muted,
|
|
11328
11968
|
children: "Choose a page or press Esc"
|
|
11329
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
11969
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV21("text", {
|
|
11330
11970
|
fg: cliTheme.text.muted,
|
|
11331
|
-
children: "Tab/Ctrl+T
|
|
11971
|
+
children: "Tab/Ctrl+T mode | Ctrl+Y copy | Ctrl+P commands"
|
|
11332
11972
|
}, undefined, false, undefined, this),
|
|
11333
|
-
/* @__PURE__ */
|
|
11973
|
+
/* @__PURE__ */ jsxDEV21("box", {
|
|
11334
11974
|
flexDirection: "row",
|
|
11335
11975
|
gap: 1,
|
|
11336
11976
|
alignItems: "center",
|
|
11337
11977
|
children: [
|
|
11338
|
-
/* @__PURE__ */
|
|
11978
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
11339
11979
|
fg: contextMeterColor,
|
|
11340
11980
|
children: contextEstimate.displayText
|
|
11341
11981
|
}, undefined, false, undefined, this),
|
|
11342
|
-
/* @__PURE__ */
|
|
11982
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
11343
11983
|
children: [
|
|
11344
|
-
/* @__PURE__ */
|
|
11984
|
+
/* @__PURE__ */ jsxDEV21("span", {
|
|
11345
11985
|
fg: cliTheme.accent.primary,
|
|
11346
11986
|
children: modeDefinition.label
|
|
11347
11987
|
}, undefined, false, undefined, this),
|
|
11348
|
-
/* @__PURE__ */
|
|
11988
|
+
/* @__PURE__ */ jsxDEV21("span", {
|
|
11349
11989
|
fg: cliTheme.text.muted,
|
|
11350
11990
|
children: " mode"
|
|
11351
11991
|
}, undefined, false, undefined, this)
|
|
11352
11992
|
]
|
|
11353
11993
|
}, undefined, true, undefined, this),
|
|
11354
|
-
/* @__PURE__ */
|
|
11355
|
-
children: /* @__PURE__ */
|
|
11994
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
11995
|
+
children: /* @__PURE__ */ jsxDEV21("span", {
|
|
11356
11996
|
fg: cliTheme.semantic.warning,
|
|
11357
11997
|
children: "|"
|
|
11358
11998
|
}, undefined, false, undefined, this)
|
|
11359
11999
|
}, undefined, false, undefined, this),
|
|
11360
|
-
/* @__PURE__ */
|
|
11361
|
-
children: /* @__PURE__ */
|
|
12000
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
12001
|
+
children: /* @__PURE__ */ jsxDEV21("span", {
|
|
11362
12002
|
fg: permissionMode === "danger-full-access" ? cliTheme.semantic.error : permissionMode === "read-only" ? cliTheme.text.muted : cliTheme.text.primary,
|
|
11363
12003
|
children: permissionMode ?? "default"
|
|
11364
12004
|
}, undefined, false, undefined, this)
|
|
@@ -11371,30 +12011,30 @@ function ChatScreen() {
|
|
|
11371
12011
|
onSubmit: submitChatInput
|
|
11372
12012
|
}, undefined, false, undefined, this),
|
|
11373
12013
|
children: [
|
|
11374
|
-
contextState && !anchorVisibleInMessages ? /* @__PURE__ */
|
|
12014
|
+
contextState && !anchorVisibleInMessages ? /* @__PURE__ */ jsxDEV21(ChatContextStateCard, {
|
|
11375
12015
|
contextState
|
|
11376
12016
|
}, undefined, false, undefined, this) : null,
|
|
11377
|
-
messages.map((message) => /* @__PURE__ */
|
|
12017
|
+
messages.map((message) => /* @__PURE__ */ jsxDEV21(Fragment, {
|
|
11378
12018
|
children: [
|
|
11379
|
-
isAutoContinueMessage(message) ? null : isContextSummaryMessage(message) ? /* @__PURE__ */
|
|
12019
|
+
isAutoContinueMessage(message) ? null : isContextSummaryMessage(message) ? /* @__PURE__ */ jsxDEV21(ChatContextSummaryCard, {
|
|
11380
12020
|
message
|
|
11381
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
12021
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV21(ChatMessage, {
|
|
11382
12022
|
message,
|
|
11383
12023
|
pendingApprovalIds
|
|
11384
12024
|
}, undefined, false, undefined, this),
|
|
11385
|
-
contextState && contextState.anchorMessageId === message.id ? /* @__PURE__ */
|
|
12025
|
+
contextState && contextState.anchorMessageId === message.id ? /* @__PURE__ */ jsxDEV21(ChatContextStateCard, {
|
|
11386
12026
|
contextState
|
|
11387
12027
|
}, undefined, false, undefined, this) : null
|
|
11388
12028
|
]
|
|
11389
12029
|
}, message.id, true, undefined, this)),
|
|
11390
|
-
actionNotice ? /* @__PURE__ */
|
|
12030
|
+
actionNotice ? /* @__PURE__ */ jsxDEV21("box", {
|
|
11391
12031
|
paddingX: 1,
|
|
11392
|
-
children: /* @__PURE__ */
|
|
12032
|
+
children: /* @__PURE__ */ jsxDEV21("text", {
|
|
11393
12033
|
fg: actionNotice.tone === "error" ? cliTheme.semantic.error : cliTheme.semantic.info,
|
|
11394
12034
|
children: actionNotice.text
|
|
11395
12035
|
}, undefined, false, undefined, this)
|
|
11396
12036
|
}, undefined, false, undefined, this) : null,
|
|
11397
|
-
modelHasToolCallXmlLeak ? /* @__PURE__ */
|
|
12037
|
+
modelHasToolCallXmlLeak ? /* @__PURE__ */ jsxDEV21("box", {
|
|
11398
12038
|
paddingX: 1,
|
|
11399
12039
|
paddingY: 1,
|
|
11400
12040
|
borderStyle: "single",
|
|
@@ -11402,47 +12042,47 @@ function ChatScreen() {
|
|
|
11402
12042
|
flexDirection: "column",
|
|
11403
12043
|
gap: 1,
|
|
11404
12044
|
children: [
|
|
11405
|
-
/* @__PURE__ */
|
|
12045
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
11406
12046
|
fg: cliTheme.semantic.warning,
|
|
11407
12047
|
children: "Model compatibility issue: this model output raw tool call XML instead of invoking tools."
|
|
11408
12048
|
}, undefined, false, undefined, this),
|
|
11409
|
-
/* @__PURE__ */
|
|
12049
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
11410
12050
|
fg: cliTheme.text.muted,
|
|
11411
12051
|
children: "Switch to a model with native function calling (Claude, GPT-4, Llama 3) via /model."
|
|
11412
12052
|
}, undefined, false, undefined, this)
|
|
11413
12053
|
]
|
|
11414
|
-
}, undefined, true, undefined, this) : autoContinueState?.guardTripped ? /* @__PURE__ */
|
|
12054
|
+
}, undefined, true, undefined, this) : autoContinueState?.guardTripped ? /* @__PURE__ */ jsxDEV21("box", {
|
|
11415
12055
|
paddingX: 1,
|
|
11416
|
-
children: /* @__PURE__ */
|
|
12056
|
+
children: /* @__PURE__ */ jsxDEV21("text", {
|
|
11417
12057
|
fg: cliTheme.semantic.warning,
|
|
11418
|
-
children: autoContinueState.guardTripped === "doom-loop" ? "Agent appears stuck repeating itself \u2014 automatic continuation stopped. Send a message to resume." : `Reached the automatic continuation limit (${autoContinueState.attempt}). Send a message to resume.`
|
|
12058
|
+
children: autoContinueState.guardTripped === "doom-loop" ? "Agent appears stuck repeating itself \u2014 automatic continuation stopped. Send a message to resume." : autoContinueState.guardTripped === "no-progress" ? "The connection keeps dropping without making progress \u2014 automatic retry stopped. Send a message to resume." : `Reached the automatic continuation limit (${autoContinueState.attempt}). Send a message to resume.`
|
|
11419
12059
|
}, undefined, false, undefined, this)
|
|
11420
|
-
}, undefined, false, undefined, this) : autoContinueState ? /* @__PURE__ */
|
|
12060
|
+
}, undefined, false, undefined, this) : autoContinueState ? /* @__PURE__ */ jsxDEV21("box", {
|
|
11421
12061
|
paddingX: 1,
|
|
11422
|
-
children: /* @__PURE__ */
|
|
12062
|
+
children: /* @__PURE__ */ jsxDEV21("text", {
|
|
11423
12063
|
fg: cliTheme.semantic.info,
|
|
11424
12064
|
children: autoContinueState.kind === "continue-length" ? `Output limit hit \u2014 continuing automatically (${autoContinueState.attempt})...` : autoContinueState.kind === "retry-error" ? `Connection dropped \u2014 retrying automatically (${autoContinueState.attempt})...` : `Agent stopped early \u2014 continuing automatically (${autoContinueState.attempt})...`
|
|
11425
12065
|
}, undefined, false, undefined, this)
|
|
11426
12066
|
}, undefined, false, undefined, this) : null,
|
|
11427
|
-
isLoading || isStreaming ? /* @__PURE__ */
|
|
12067
|
+
isLoading || isStreaming ? /* @__PURE__ */ jsxDEV21(LoadingTimer, {
|
|
11428
12068
|
elapsedSeconds
|
|
11429
12069
|
}, undefined, false, undefined, this) : null,
|
|
11430
|
-
isStreaming ? /* @__PURE__ */
|
|
12070
|
+
isStreaming ? /* @__PURE__ */ jsxDEV21("box", {
|
|
11431
12071
|
paddingX: 1,
|
|
11432
|
-
children: /* @__PURE__ */
|
|
12072
|
+
children: /* @__PURE__ */ jsxDEV21("text", {
|
|
11433
12073
|
fg: cliTheme.semantic.info,
|
|
11434
12074
|
children: "Assistant is thinking..."
|
|
11435
12075
|
}, undefined, false, undefined, this)
|
|
11436
12076
|
}, undefined, false, undefined, this) : null,
|
|
11437
|
-
pendingApprovals.length > 0 ? /* @__PURE__ */
|
|
12077
|
+
pendingApprovals.length > 0 ? /* @__PURE__ */ jsxDEV21(ChatToolApprovalCard, {
|
|
11438
12078
|
approvals: pendingApprovals,
|
|
11439
12079
|
onResolve: resolveToolApproval,
|
|
11440
12080
|
onResolveAll: resolveAllToolApprovals
|
|
11441
12081
|
}, undefined, false, undefined, this) : null,
|
|
11442
|
-
todos.length > 0 ? /* @__PURE__ */
|
|
12082
|
+
todos.length > 0 ? /* @__PURE__ */ jsxDEV21(ChatTodoStatusCard, {
|
|
11443
12083
|
todos
|
|
11444
12084
|
}, undefined, false, undefined, this) : null,
|
|
11445
|
-
activeUserPrompt ? /* @__PURE__ */
|
|
12085
|
+
activeUserPrompt ? /* @__PURE__ */ jsxDEV21(ChatInteractionPopup, {
|
|
11446
12086
|
title: activeUserPrompt.header ?? "Question",
|
|
11447
12087
|
question: activeUserPrompt.question,
|
|
11448
12088
|
options: activeUserPrompt.options.map((option) => ({
|
|
@@ -11473,7 +12113,7 @@ function ChatScreen() {
|
|
|
11473
12113
|
});
|
|
11474
12114
|
}
|
|
11475
12115
|
}, undefined, false, undefined, this) : null,
|
|
11476
|
-
planConfirmationOpen ? /* @__PURE__ */
|
|
12116
|
+
planConfirmationOpen ? /* @__PURE__ */ jsxDEV21(ChatInteractionPopup, {
|
|
11477
12117
|
title: "Plan review",
|
|
11478
12118
|
question: "Implement this plan now?",
|
|
11479
12119
|
options: [
|
|
@@ -11521,10 +12161,14 @@ function ChatScreen() {
|
|
|
11521
12161
|
sendDirectMessage(defaultPlanRevisionRequest);
|
|
11522
12162
|
}
|
|
11523
12163
|
}, undefined, false, undefined, this) : null,
|
|
11524
|
-
permissionSelectorOpen ? /* @__PURE__ */
|
|
12164
|
+
permissionSelectorOpen ? /* @__PURE__ */ jsxDEV21(PermissionModeSelector, {
|
|
11525
12165
|
currentMode: permissionMode,
|
|
11526
12166
|
onSelect: updatePermissionMode,
|
|
11527
12167
|
onClose: () => setPermissionSelectorOpen(false)
|
|
12168
|
+
}, undefined, false, undefined, this) : null,
|
|
12169
|
+
copyModeOpen ? /* @__PURE__ */ jsxDEV21(CopyModeOverlay, {
|
|
12170
|
+
messages: copyableMessages,
|
|
12171
|
+
selectedIndex: Math.min(copyModeIndex, Math.max(copyableMessages.length - 1, 0))
|
|
11528
12172
|
}, undefined, false, undefined, this) : null
|
|
11529
12173
|
]
|
|
11530
12174
|
}, undefined, true, undefined, this)
|
|
@@ -11535,6 +12179,7 @@ var init_chat_screen = __esm(() => {
|
|
|
11535
12179
|
init_src2();
|
|
11536
12180
|
init_react();
|
|
11537
12181
|
init_chat_slash_actions();
|
|
12182
|
+
init_clipboard();
|
|
11538
12183
|
init_slash_menu_items();
|
|
11539
12184
|
init_slash_page_menu();
|
|
11540
12185
|
init_chat_context_summary_card();
|
|
@@ -11547,6 +12192,7 @@ var init_chat_screen = __esm(() => {
|
|
|
11547
12192
|
init_chat_todo_status_card();
|
|
11548
12193
|
init_chat_tool_approval_card();
|
|
11549
12194
|
init_loading_timer();
|
|
12195
|
+
init_copy_mode_overlay();
|
|
11550
12196
|
init_use_auto_continue_config();
|
|
11551
12197
|
init_use_context_window();
|
|
11552
12198
|
init_use_loading_timer();
|
|
@@ -11557,6 +12203,7 @@ var init_chat_screen = __esm(() => {
|
|
|
11557
12203
|
init_cli_theme();
|
|
11558
12204
|
init_chat_context_utils();
|
|
11559
12205
|
init_file_mentions();
|
|
12206
|
+
init_markdown_code();
|
|
11560
12207
|
planConfirmationAcceptKeywords = [
|
|
11561
12208
|
"yes",
|
|
11562
12209
|
"y",
|
|
@@ -11584,12 +12231,12 @@ var init_chat_screen = __esm(() => {
|
|
|
11584
12231
|
});
|
|
11585
12232
|
|
|
11586
12233
|
// apps/cli/src/screens/diagnostics-screen.tsx
|
|
11587
|
-
import { TextAttributes as
|
|
12234
|
+
import { TextAttributes as TextAttributes16 } from "@opentui/core";
|
|
11588
12235
|
import { useKeyboard as useKeyboard5 } from "@opentui/react";
|
|
11589
12236
|
import { useCallback as useCallback5, useEffect as useEffect9, useMemo as useMemo5, useState as useState11 } from "react";
|
|
11590
12237
|
import { useLocation as useLocation2 } from "react-router";
|
|
11591
12238
|
import { z as z35 } from "zod";
|
|
11592
|
-
import { jsxDEV as
|
|
12239
|
+
import { jsxDEV as jsxDEV22, Fragment as Fragment2 } from "@opentui/react/jsx-dev-runtime";
|
|
11593
12240
|
function getStatusColor2(status) {
|
|
11594
12241
|
if (status === "ok") {
|
|
11595
12242
|
return cliTheme.semantic.success;
|
|
@@ -11611,16 +12258,16 @@ function InfoRow({
|
|
|
11611
12258
|
tone
|
|
11612
12259
|
}) {
|
|
11613
12260
|
const valueColor = tone === "muted" || tone === undefined ? cliTheme.text.secondary : getStatusColor2(tone);
|
|
11614
|
-
return /* @__PURE__ */
|
|
12261
|
+
return /* @__PURE__ */ jsxDEV22("box", {
|
|
11615
12262
|
flexDirection: "row",
|
|
11616
12263
|
gap: 1,
|
|
11617
12264
|
children: [
|
|
11618
|
-
/* @__PURE__ */
|
|
12265
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11619
12266
|
fg: cliTheme.text.muted,
|
|
11620
12267
|
width: 24,
|
|
11621
12268
|
children: label
|
|
11622
12269
|
}, undefined, false, undefined, this),
|
|
11623
|
-
/* @__PURE__ */
|
|
12270
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11624
12271
|
fg: valueColor,
|
|
11625
12272
|
children: formatNullable(value)
|
|
11626
12273
|
}, undefined, false, undefined, this)
|
|
@@ -11631,7 +12278,7 @@ function Section({
|
|
|
11631
12278
|
title,
|
|
11632
12279
|
children
|
|
11633
12280
|
}) {
|
|
11634
|
-
return /* @__PURE__ */
|
|
12281
|
+
return /* @__PURE__ */ jsxDEV22("box", {
|
|
11635
12282
|
flexDirection: "column",
|
|
11636
12283
|
gap: 1,
|
|
11637
12284
|
paddingX: 1,
|
|
@@ -11640,9 +12287,9 @@ function Section({
|
|
|
11640
12287
|
borderColor: cliTheme.borders.subtle,
|
|
11641
12288
|
backgroundColor: cliTheme.surfaces.panel,
|
|
11642
12289
|
children: [
|
|
11643
|
-
/* @__PURE__ */
|
|
12290
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11644
12291
|
fg: cliTheme.accent.primary,
|
|
11645
|
-
attributes:
|
|
12292
|
+
attributes: TextAttributes16.BOLD,
|
|
11646
12293
|
children: title
|
|
11647
12294
|
}, undefined, false, undefined, this),
|
|
11648
12295
|
children
|
|
@@ -11653,123 +12300,123 @@ function renderStatus(payload, routeState) {
|
|
|
11653
12300
|
const parsedRouteState = diagnosticsRouteStateSchema.safeParse(routeState);
|
|
11654
12301
|
const currentSession = parsedRouteState.success ? parsedRouteState.data : {};
|
|
11655
12302
|
const latestSession = payload.sessions.latest;
|
|
11656
|
-
return /* @__PURE__ */
|
|
12303
|
+
return /* @__PURE__ */ jsxDEV22(Fragment2, {
|
|
11657
12304
|
children: [
|
|
11658
|
-
/* @__PURE__ */
|
|
12305
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11659
12306
|
title: "Current Chat",
|
|
11660
12307
|
children: [
|
|
11661
|
-
/* @__PURE__ */
|
|
12308
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11662
12309
|
label: "Session",
|
|
11663
12310
|
value: currentSession.sessionId ?? "not in chat"
|
|
11664
12311
|
}, undefined, false, undefined, this),
|
|
11665
|
-
/* @__PURE__ */
|
|
12312
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11666
12313
|
label: "Mode",
|
|
11667
12314
|
value: currentSession.mode ?? "not set"
|
|
11668
12315
|
}, undefined, false, undefined, this),
|
|
11669
|
-
/* @__PURE__ */
|
|
12316
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11670
12317
|
label: "Permission mode",
|
|
11671
12318
|
value: currentSession.permissionMode ?? "not set"
|
|
11672
12319
|
}, undefined, false, undefined, this),
|
|
11673
|
-
/* @__PURE__ */
|
|
12320
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11674
12321
|
label: "CWD",
|
|
11675
12322
|
value: currentSession.cwd ?? payload.server.cwd
|
|
11676
12323
|
}, undefined, false, undefined, this),
|
|
11677
|
-
/* @__PURE__ */
|
|
12324
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11678
12325
|
label: "Messages",
|
|
11679
12326
|
value: currentSession.messageCount ?? null
|
|
11680
12327
|
}, undefined, false, undefined, this),
|
|
11681
|
-
/* @__PURE__ */
|
|
12328
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11682
12329
|
label: "Pending approvals",
|
|
11683
12330
|
value: currentSession.pendingApprovalCount ?? 0,
|
|
11684
12331
|
tone: (currentSession.pendingApprovalCount ?? 0) > 0 ? "warn" : "ok"
|
|
11685
12332
|
}, undefined, false, undefined, this)
|
|
11686
12333
|
]
|
|
11687
12334
|
}, undefined, true, undefined, this),
|
|
11688
|
-
/* @__PURE__ */
|
|
12335
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11689
12336
|
title: "Runtime",
|
|
11690
12337
|
children: [
|
|
11691
|
-
/* @__PURE__ */
|
|
12338
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11692
12339
|
label: "Server",
|
|
11693
12340
|
value: payload.server.status,
|
|
11694
12341
|
tone: payload.server.status
|
|
11695
12342
|
}, undefined, false, undefined, this),
|
|
11696
|
-
/* @__PURE__ */
|
|
12343
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11697
12344
|
label: "Provider",
|
|
11698
12345
|
value: payload.provider.provider,
|
|
11699
12346
|
tone: payload.provider.status
|
|
11700
12347
|
}, undefined, false, undefined, this),
|
|
11701
|
-
/* @__PURE__ */
|
|
12348
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11702
12349
|
label: "Model",
|
|
11703
12350
|
value: payload.provider.model
|
|
11704
12351
|
}, undefined, false, undefined, this),
|
|
11705
|
-
/* @__PURE__ */
|
|
12352
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11706
12353
|
label: "Database",
|
|
11707
12354
|
value: payload.database.status,
|
|
11708
12355
|
tone: payload.database.status
|
|
11709
12356
|
}, undefined, false, undefined, this),
|
|
11710
|
-
/* @__PURE__ */
|
|
12357
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11711
12358
|
label: "Tool count",
|
|
11712
12359
|
value: payload.tools.total
|
|
11713
12360
|
}, undefined, false, undefined, this),
|
|
11714
|
-
/* @__PURE__ */
|
|
12361
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11715
12362
|
label: "Schema status",
|
|
11716
12363
|
value: payload.tools.providerSchemaStatus,
|
|
11717
12364
|
tone: payload.tools.providerSchemaStatus
|
|
11718
12365
|
}, undefined, false, undefined, this)
|
|
11719
12366
|
]
|
|
11720
12367
|
}, undefined, true, undefined, this),
|
|
11721
|
-
/* @__PURE__ */
|
|
12368
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11722
12369
|
title: "Extensions",
|
|
11723
12370
|
children: [
|
|
11724
|
-
/* @__PURE__ */
|
|
12371
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11725
12372
|
label: "Skills",
|
|
11726
12373
|
value: payload.extensions.skills.count
|
|
11727
12374
|
}, undefined, false, undefined, this),
|
|
11728
|
-
/* @__PURE__ */
|
|
12375
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11729
12376
|
label: "MCP servers",
|
|
11730
12377
|
value: payload.extensions.mcp.configuredServers
|
|
11731
12378
|
}, undefined, false, undefined, this),
|
|
11732
|
-
/* @__PURE__ */
|
|
12379
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11733
12380
|
label: "MCP running",
|
|
11734
12381
|
value: payload.extensions.mcp.runningServers
|
|
11735
12382
|
}, undefined, false, undefined, this),
|
|
11736
|
-
/* @__PURE__ */
|
|
12383
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11737
12384
|
label: "MCP degraded",
|
|
11738
12385
|
value: payload.extensions.mcp.degradedServers,
|
|
11739
12386
|
tone: payload.extensions.mcp.degradedServers > 0 ? "warn" : "ok"
|
|
11740
12387
|
}, undefined, false, undefined, this),
|
|
11741
|
-
/* @__PURE__ */
|
|
12388
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11742
12389
|
label: "Plugins",
|
|
11743
12390
|
value: payload.extensions.plugins.count
|
|
11744
12391
|
}, undefined, false, undefined, this),
|
|
11745
|
-
/* @__PURE__ */
|
|
12392
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11746
12393
|
label: "Plugin hooks",
|
|
11747
12394
|
value: payload.extensions.plugins.hooks
|
|
11748
12395
|
}, undefined, false, undefined, this)
|
|
11749
12396
|
]
|
|
11750
12397
|
}, undefined, true, undefined, this),
|
|
11751
|
-
/* @__PURE__ */
|
|
12398
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11752
12399
|
title: "Latest Saved Session",
|
|
11753
|
-
children: latestSession ? /* @__PURE__ */
|
|
12400
|
+
children: latestSession ? /* @__PURE__ */ jsxDEV22(Fragment2, {
|
|
11754
12401
|
children: [
|
|
11755
|
-
/* @__PURE__ */
|
|
12402
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11756
12403
|
label: "Session",
|
|
11757
12404
|
value: latestSession.id
|
|
11758
12405
|
}, undefined, false, undefined, this),
|
|
11759
|
-
/* @__PURE__ */
|
|
12406
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11760
12407
|
label: "Title",
|
|
11761
12408
|
value: latestSession.title ?? latestSession.latestUserPromptPreview
|
|
11762
12409
|
}, undefined, false, undefined, this),
|
|
11763
|
-
/* @__PURE__ */
|
|
12410
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11764
12411
|
label: "Messages",
|
|
11765
12412
|
value: latestSession.messageCount
|
|
11766
12413
|
}, undefined, false, undefined, this),
|
|
11767
|
-
/* @__PURE__ */
|
|
12414
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11768
12415
|
label: "Updated",
|
|
11769
12416
|
value: formatDate2(latestSession.updatedAt)
|
|
11770
12417
|
}, undefined, false, undefined, this)
|
|
11771
12418
|
]
|
|
11772
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */
|
|
12419
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV22("text", {
|
|
11773
12420
|
fg: cliTheme.text.muted,
|
|
11774
12421
|
children: "No saved sessions yet."
|
|
11775
12422
|
}, undefined, false, undefined, this)
|
|
@@ -11778,36 +12425,36 @@ function renderStatus(payload, routeState) {
|
|
|
11778
12425
|
}, undefined, true, undefined, this);
|
|
11779
12426
|
}
|
|
11780
12427
|
function renderDoctor(payload) {
|
|
11781
|
-
return /* @__PURE__ */
|
|
12428
|
+
return /* @__PURE__ */ jsxDEV22(Section, {
|
|
11782
12429
|
title: `Overall: ${payload.status}`,
|
|
11783
|
-
children: payload.checks.map((check) => /* @__PURE__ */
|
|
12430
|
+
children: payload.checks.map((check) => /* @__PURE__ */ jsxDEV22("box", {
|
|
11784
12431
|
flexDirection: "column",
|
|
11785
12432
|
paddingY: 1,
|
|
11786
12433
|
children: [
|
|
11787
|
-
/* @__PURE__ */
|
|
12434
|
+
/* @__PURE__ */ jsxDEV22("box", {
|
|
11788
12435
|
flexDirection: "row",
|
|
11789
12436
|
gap: 1,
|
|
11790
12437
|
children: [
|
|
11791
|
-
/* @__PURE__ */
|
|
12438
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11792
12439
|
fg: getStatusColor2(check.status),
|
|
11793
|
-
attributes:
|
|
12440
|
+
attributes: TextAttributes16.BOLD,
|
|
11794
12441
|
width: 8,
|
|
11795
12442
|
children: check.status.toUpperCase()
|
|
11796
12443
|
}, undefined, false, undefined, this),
|
|
11797
|
-
/* @__PURE__ */
|
|
12444
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11798
12445
|
fg: cliTheme.text.primary,
|
|
11799
|
-
attributes:
|
|
12446
|
+
attributes: TextAttributes16.BOLD,
|
|
11800
12447
|
children: check.label
|
|
11801
12448
|
}, undefined, false, undefined, this)
|
|
11802
12449
|
]
|
|
11803
12450
|
}, undefined, true, undefined, this),
|
|
11804
|
-
/* @__PURE__ */
|
|
12451
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11805
12452
|
fg: cliTheme.text.secondary,
|
|
11806
12453
|
children: check.summary
|
|
11807
12454
|
}, undefined, false, undefined, this),
|
|
11808
|
-
check.details.map((detail) => /* @__PURE__ */
|
|
12455
|
+
check.details.map((detail) => /* @__PURE__ */ jsxDEV22("text", {
|
|
11809
12456
|
fg: cliTheme.text.muted,
|
|
11810
|
-
attributes:
|
|
12457
|
+
attributes: TextAttributes16.DIM,
|
|
11811
12458
|
children: detail
|
|
11812
12459
|
}, detail, false, undefined, this))
|
|
11813
12460
|
]
|
|
@@ -11817,111 +12464,111 @@ function renderDoctor(payload) {
|
|
|
11817
12464
|
function renderPermissions(payload, routeState) {
|
|
11818
12465
|
const parsedRouteState = diagnosticsRouteStateSchema.safeParse(routeState);
|
|
11819
12466
|
const currentSession = parsedRouteState.success ? parsedRouteState.data : {};
|
|
11820
|
-
return /* @__PURE__ */
|
|
12467
|
+
return /* @__PURE__ */ jsxDEV22(Fragment2, {
|
|
11821
12468
|
children: [
|
|
11822
|
-
/* @__PURE__ */
|
|
12469
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11823
12470
|
title: "Current Chat",
|
|
11824
12471
|
children: [
|
|
11825
|
-
/* @__PURE__ */
|
|
12472
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11826
12473
|
label: "Mode",
|
|
11827
12474
|
value: currentSession.mode ?? payload.defaultMode
|
|
11828
12475
|
}, undefined, false, undefined, this),
|
|
11829
|
-
/* @__PURE__ */
|
|
12476
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11830
12477
|
label: "Permission mode",
|
|
11831
12478
|
value: currentSession.permissionMode ?? payload.effectivePermissionMode
|
|
11832
12479
|
}, undefined, false, undefined, this),
|
|
11833
|
-
/* @__PURE__ */
|
|
12480
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11834
12481
|
label: "Pending approvals",
|
|
11835
12482
|
value: currentSession.pendingApprovalCount ?? 0,
|
|
11836
12483
|
tone: (currentSession.pendingApprovalCount ?? 0) > 0 ? "warn" : "ok"
|
|
11837
12484
|
}, undefined, false, undefined, this),
|
|
11838
|
-
/* @__PURE__ */
|
|
12485
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11839
12486
|
label: "Persisted pending",
|
|
11840
12487
|
value: payload.pendingInteractions.total,
|
|
11841
12488
|
tone: payload.pendingInteractions.total > 0 ? "warn" : "ok"
|
|
11842
12489
|
}, undefined, false, undefined, this)
|
|
11843
12490
|
]
|
|
11844
12491
|
}, undefined, true, undefined, this),
|
|
11845
|
-
/* @__PURE__ */
|
|
12492
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11846
12493
|
title: "Policy",
|
|
11847
12494
|
children: [
|
|
11848
|
-
/* @__PURE__ */
|
|
12495
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11849
12496
|
label: "Default mode",
|
|
11850
12497
|
value: payload.defaultMode
|
|
11851
12498
|
}, undefined, false, undefined, this),
|
|
11852
|
-
/* @__PURE__ */
|
|
12499
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11853
12500
|
label: "Configured permission",
|
|
11854
12501
|
value: payload.configuredPermissionMode
|
|
11855
12502
|
}, undefined, false, undefined, this),
|
|
11856
|
-
/* @__PURE__ */
|
|
12503
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11857
12504
|
label: "Effective permission",
|
|
11858
12505
|
value: payload.effectivePermissionMode
|
|
11859
12506
|
}, undefined, false, undefined, this),
|
|
11860
|
-
/* @__PURE__ */
|
|
12507
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11861
12508
|
label: "Allowed tools",
|
|
11862
12509
|
value: payload.allowedTools ? payload.allowedTools.join(", ") : "all policy-allowed tools"
|
|
11863
12510
|
}, undefined, false, undefined, this),
|
|
11864
|
-
/* @__PURE__ */
|
|
12511
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11865
12512
|
label: "Allow rules",
|
|
11866
12513
|
value: payload.rules.allow?.length ?? 0
|
|
11867
12514
|
}, undefined, false, undefined, this),
|
|
11868
|
-
/* @__PURE__ */
|
|
12515
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11869
12516
|
label: "Ask rules",
|
|
11870
12517
|
value: payload.rules.ask?.length ?? 0
|
|
11871
12518
|
}, undefined, false, undefined, this),
|
|
11872
|
-
/* @__PURE__ */
|
|
12519
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11873
12520
|
label: "Deny rules",
|
|
11874
12521
|
value: payload.rules.deny?.length ?? 0
|
|
11875
12522
|
}, undefined, false, undefined, this)
|
|
11876
12523
|
]
|
|
11877
12524
|
}, undefined, true, undefined, this),
|
|
11878
|
-
/* @__PURE__ */
|
|
12525
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11879
12526
|
title: "Recovery",
|
|
11880
12527
|
children: [
|
|
11881
|
-
/* @__PURE__ */
|
|
12528
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11882
12529
|
label: "Tool approvals",
|
|
11883
12530
|
value: payload.pendingInteractions.toolApprovals
|
|
11884
12531
|
}, undefined, false, undefined, this),
|
|
11885
|
-
/* @__PURE__ */
|
|
12532
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11886
12533
|
label: "User prompts",
|
|
11887
12534
|
value: payload.pendingInteractions.userPrompts
|
|
11888
12535
|
}, undefined, false, undefined, this),
|
|
11889
|
-
/* @__PURE__ */
|
|
12536
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11890
12537
|
label: "Stale pending",
|
|
11891
12538
|
value: payload.pendingInteractions.stale,
|
|
11892
12539
|
tone: payload.pendingInteractions.stale > 0 ? "warn" : "ok"
|
|
11893
12540
|
}, undefined, false, undefined, this),
|
|
11894
|
-
/* @__PURE__ */
|
|
12541
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11895
12542
|
label: "Recoverable",
|
|
11896
12543
|
value: payload.pendingInteractions.recoverable
|
|
11897
12544
|
}, undefined, false, undefined, this)
|
|
11898
12545
|
]
|
|
11899
12546
|
}, undefined, true, undefined, this),
|
|
11900
|
-
/* @__PURE__ */
|
|
12547
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11901
12548
|
title: "Sandbox",
|
|
11902
12549
|
children: [
|
|
11903
|
-
/* @__PURE__ */
|
|
12550
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11904
12551
|
label: "Enabled",
|
|
11905
12552
|
value: payload.sandbox.enabled ? "yes" : "no"
|
|
11906
12553
|
}, undefined, false, undefined, this),
|
|
11907
|
-
/* @__PURE__ */
|
|
12554
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11908
12555
|
label: "Mode",
|
|
11909
12556
|
value: payload.sandbox.mode
|
|
11910
12557
|
}, undefined, false, undefined, this),
|
|
11911
|
-
/* @__PURE__ */
|
|
12558
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11912
12559
|
label: "Supported",
|
|
11913
12560
|
value: payload.sandbox.supported ? "yes" : "no",
|
|
11914
12561
|
tone: payload.sandbox.supported ? "ok" : "warn"
|
|
11915
12562
|
}, undefined, false, undefined, this),
|
|
11916
|
-
payload.sandbox.unsupportedReason ? /* @__PURE__ */
|
|
12563
|
+
payload.sandbox.unsupportedReason ? /* @__PURE__ */ jsxDEV22("text", {
|
|
11917
12564
|
fg: cliTheme.semantic.warning,
|
|
11918
12565
|
children: payload.sandbox.unsupportedReason
|
|
11919
12566
|
}, undefined, false, undefined, this) : null
|
|
11920
12567
|
]
|
|
11921
12568
|
}, undefined, true, undefined, this),
|
|
11922
|
-
/* @__PURE__ */
|
|
12569
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11923
12570
|
title: "Notes",
|
|
11924
|
-
children: payload.notes.map((note) => /* @__PURE__ */
|
|
12571
|
+
children: payload.notes.map((note) => /* @__PURE__ */ jsxDEV22("text", {
|
|
11925
12572
|
fg: cliTheme.text.muted,
|
|
11926
12573
|
children: note
|
|
11927
12574
|
}, note, false, undefined, this))
|
|
@@ -11930,62 +12577,62 @@ function renderPermissions(payload, routeState) {
|
|
|
11930
12577
|
}, undefined, true, undefined, this);
|
|
11931
12578
|
}
|
|
11932
12579
|
function renderTools(payload) {
|
|
11933
|
-
return /* @__PURE__ */
|
|
12580
|
+
return /* @__PURE__ */ jsxDEV22(Fragment2, {
|
|
11934
12581
|
children: [
|
|
11935
|
-
/* @__PURE__ */
|
|
12582
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11936
12583
|
title: "Summary",
|
|
11937
12584
|
children: [
|
|
11938
|
-
/* @__PURE__ */
|
|
12585
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11939
12586
|
label: "Total",
|
|
11940
12587
|
value: payload.summary.total
|
|
11941
12588
|
}, undefined, false, undefined, this),
|
|
11942
|
-
/* @__PURE__ */
|
|
12589
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11943
12590
|
label: "Read-only",
|
|
11944
12591
|
value: payload.summary.readOnly
|
|
11945
12592
|
}, undefined, false, undefined, this),
|
|
11946
|
-
/* @__PURE__ */
|
|
12593
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11947
12594
|
label: "Workspace-write",
|
|
11948
12595
|
value: payload.summary.workspaceWrite
|
|
11949
12596
|
}, undefined, false, undefined, this),
|
|
11950
|
-
/* @__PURE__ */
|
|
12597
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11951
12598
|
label: "Danger-full-access",
|
|
11952
12599
|
value: payload.summary.dangerFullAccess
|
|
11953
12600
|
}, undefined, false, undefined, this),
|
|
11954
|
-
/* @__PURE__ */
|
|
12601
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11955
12602
|
label: "Schema status",
|
|
11956
12603
|
value: payload.summary.providerSchemaStatus,
|
|
11957
12604
|
tone: payload.summary.providerSchemaStatus
|
|
11958
12605
|
}, undefined, false, undefined, this)
|
|
11959
12606
|
]
|
|
11960
12607
|
}, undefined, true, undefined, this),
|
|
11961
|
-
/* @__PURE__ */
|
|
12608
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11962
12609
|
title: "Tool Catalog",
|
|
11963
|
-
children: payload.tools.map((tool2) => /* @__PURE__ */
|
|
12610
|
+
children: payload.tools.map((tool2) => /* @__PURE__ */ jsxDEV22("box", {
|
|
11964
12611
|
flexDirection: "column",
|
|
11965
12612
|
paddingY: 1,
|
|
11966
12613
|
children: [
|
|
11967
|
-
/* @__PURE__ */
|
|
12614
|
+
/* @__PURE__ */ jsxDEV22("box", {
|
|
11968
12615
|
flexDirection: "row",
|
|
11969
12616
|
justifyContent: "space-between",
|
|
11970
12617
|
children: [
|
|
11971
|
-
/* @__PURE__ */
|
|
12618
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11972
12619
|
fg: cliTheme.text.primary,
|
|
11973
|
-
attributes:
|
|
12620
|
+
attributes: TextAttributes16.BOLD,
|
|
11974
12621
|
children: tool2.name
|
|
11975
12622
|
}, undefined, false, undefined, this),
|
|
11976
|
-
/* @__PURE__ */
|
|
12623
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11977
12624
|
fg: getStatusColor2(tool2.providerSchemaStatus),
|
|
11978
12625
|
children: tool2.permissionMode
|
|
11979
12626
|
}, undefined, false, undefined, this)
|
|
11980
12627
|
]
|
|
11981
12628
|
}, undefined, true, undefined, this),
|
|
11982
|
-
/* @__PURE__ */
|
|
12629
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11983
12630
|
fg: cliTheme.text.secondary,
|
|
11984
12631
|
children: tool2.description
|
|
11985
12632
|
}, undefined, false, undefined, this),
|
|
11986
|
-
/* @__PURE__ */
|
|
12633
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11987
12634
|
fg: cliTheme.text.muted,
|
|
11988
|
-
attributes:
|
|
12635
|
+
attributes: TextAttributes16.DIM,
|
|
11989
12636
|
children: [
|
|
11990
12637
|
"Modes: ",
|
|
11991
12638
|
tool2.activeInModes.join(", ") || "none",
|
|
@@ -12000,51 +12647,51 @@ function renderTools(payload) {
|
|
|
12000
12647
|
}, undefined, true, undefined, this);
|
|
12001
12648
|
}
|
|
12002
12649
|
function renderConfig(payload) {
|
|
12003
|
-
return /* @__PURE__ */
|
|
12650
|
+
return /* @__PURE__ */ jsxDEV22(Fragment2, {
|
|
12004
12651
|
children: [
|
|
12005
|
-
/* @__PURE__ */
|
|
12652
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
12006
12653
|
title: "Effective Config",
|
|
12007
12654
|
children: [
|
|
12008
|
-
/* @__PURE__ */
|
|
12655
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12009
12656
|
label: "Provider",
|
|
12010
12657
|
value: payload.selectedProvider
|
|
12011
12658
|
}, undefined, false, undefined, this),
|
|
12012
|
-
/* @__PURE__ */
|
|
12659
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12013
12660
|
label: "Configured model",
|
|
12014
12661
|
value: payload.configuredModel
|
|
12015
12662
|
}, undefined, false, undefined, this),
|
|
12016
|
-
/* @__PURE__ */
|
|
12663
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12017
12664
|
label: "Selected model",
|
|
12018
12665
|
value: payload.selectedModel
|
|
12019
12666
|
}, undefined, false, undefined, this),
|
|
12020
|
-
/* @__PURE__ */
|
|
12667
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12021
12668
|
label: "Base URL",
|
|
12022
12669
|
value: payload.baseUrl ? "configured" : "default"
|
|
12023
12670
|
}, undefined, false, undefined, this),
|
|
12024
|
-
/* @__PURE__ */
|
|
12671
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12025
12672
|
label: "Default mode",
|
|
12026
12673
|
value: payload.defaultMode
|
|
12027
12674
|
}, undefined, false, undefined, this),
|
|
12028
|
-
/* @__PURE__ */
|
|
12675
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12029
12676
|
label: "Permission mode",
|
|
12030
12677
|
value: payload.permissionMode
|
|
12031
12678
|
}, undefined, false, undefined, this),
|
|
12032
|
-
/* @__PURE__ */
|
|
12679
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12033
12680
|
label: "Max output tokens",
|
|
12034
12681
|
value: payload.maxOutputTokens
|
|
12035
12682
|
}, undefined, false, undefined, this),
|
|
12036
|
-
/* @__PURE__ */
|
|
12683
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12037
12684
|
label: "Max steps",
|
|
12038
12685
|
value: payload.maxSteps
|
|
12039
12686
|
}, undefined, false, undefined, this)
|
|
12040
12687
|
]
|
|
12041
12688
|
}, undefined, true, undefined, this),
|
|
12042
|
-
/* @__PURE__ */
|
|
12689
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
12043
12690
|
title: "Loaded Files",
|
|
12044
|
-
children: payload.loadedFiles.map((file) => /* @__PURE__ */
|
|
12691
|
+
children: payload.loadedFiles.map((file) => /* @__PURE__ */ jsxDEV22("box", {
|
|
12045
12692
|
flexDirection: "column",
|
|
12046
12693
|
children: [
|
|
12047
|
-
/* @__PURE__ */
|
|
12694
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
12048
12695
|
fg: file.loaded ? cliTheme.semantic.success : cliTheme.text.muted,
|
|
12049
12696
|
children: [
|
|
12050
12697
|
file.scope,
|
|
@@ -12052,17 +12699,17 @@ function renderConfig(payload) {
|
|
|
12052
12699
|
file.loaded ? "loaded" : file.exists ? "not loaded" : "missing"
|
|
12053
12700
|
]
|
|
12054
12701
|
}, undefined, true, undefined, this),
|
|
12055
|
-
/* @__PURE__ */
|
|
12702
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
12056
12703
|
fg: cliTheme.text.muted,
|
|
12057
|
-
attributes:
|
|
12704
|
+
attributes: TextAttributes16.DIM,
|
|
12058
12705
|
children: file.path
|
|
12059
12706
|
}, undefined, false, undefined, this)
|
|
12060
12707
|
]
|
|
12061
12708
|
}, `${file.scope}:${file.path}`, true, undefined, this))
|
|
12062
12709
|
}, undefined, false, undefined, this),
|
|
12063
|
-
payload.missingCredentialHints.length > 0 ? /* @__PURE__ */
|
|
12710
|
+
payload.missingCredentialHints.length > 0 ? /* @__PURE__ */ jsxDEV22(Section, {
|
|
12064
12711
|
title: "Credential Hints",
|
|
12065
|
-
children: payload.missingCredentialHints.map((hint) => /* @__PURE__ */
|
|
12712
|
+
children: payload.missingCredentialHints.map((hint) => /* @__PURE__ */ jsxDEV22("text", {
|
|
12066
12713
|
fg: cliTheme.semantic.warning,
|
|
12067
12714
|
children: hint
|
|
12068
12715
|
}, hint, false, undefined, this))
|
|
@@ -12136,36 +12783,36 @@ function DiagnosticsScreen({ kind }) {
|
|
|
12136
12783
|
}
|
|
12137
12784
|
return renderConfig(payload);
|
|
12138
12785
|
}, [kind, location.state, payload]);
|
|
12139
|
-
return /* @__PURE__ */
|
|
12786
|
+
return /* @__PURE__ */ jsxDEV22("box", {
|
|
12140
12787
|
width: "100%",
|
|
12141
12788
|
height: "100%",
|
|
12142
12789
|
flexDirection: "column",
|
|
12143
12790
|
gap: 1,
|
|
12144
12791
|
children: [
|
|
12145
|
-
/* @__PURE__ */
|
|
12792
|
+
/* @__PURE__ */ jsxDEV22("box", {
|
|
12146
12793
|
flexDirection: "row",
|
|
12147
12794
|
justifyContent: "space-between",
|
|
12148
12795
|
paddingX: 1,
|
|
12149
12796
|
children: [
|
|
12150
|
-
/* @__PURE__ */
|
|
12797
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
12151
12798
|
fg: cliTheme.text.primary,
|
|
12152
|
-
attributes:
|
|
12799
|
+
attributes: TextAttributes16.BOLD,
|
|
12153
12800
|
children: title
|
|
12154
12801
|
}, undefined, false, undefined, this),
|
|
12155
|
-
/* @__PURE__ */
|
|
12802
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
12156
12803
|
fg: cliTheme.text.muted,
|
|
12157
12804
|
children: isLoading ? "loading..." : "press r to refresh"
|
|
12158
12805
|
}, undefined, false, undefined, this)
|
|
12159
12806
|
]
|
|
12160
12807
|
}, undefined, true, undefined, this),
|
|
12161
|
-
errorMessage ? /* @__PURE__ */
|
|
12808
|
+
errorMessage ? /* @__PURE__ */ jsxDEV22("box", {
|
|
12162
12809
|
paddingX: 1,
|
|
12163
|
-
children: /* @__PURE__ */
|
|
12810
|
+
children: /* @__PURE__ */ jsxDEV22("text", {
|
|
12164
12811
|
fg: cliTheme.semantic.error,
|
|
12165
12812
|
children: errorMessage
|
|
12166
12813
|
}, undefined, false, undefined, this)
|
|
12167
12814
|
}, undefined, false, undefined, this) : null,
|
|
12168
|
-
/* @__PURE__ */
|
|
12815
|
+
/* @__PURE__ */ jsxDEV22("scrollbox", {
|
|
12169
12816
|
flexGrow: 1,
|
|
12170
12817
|
flexDirection: "column",
|
|
12171
12818
|
gap: 1,
|
|
@@ -12198,12 +12845,12 @@ var init_diagnostics_screen = __esm(() => {
|
|
|
12198
12845
|
});
|
|
12199
12846
|
|
|
12200
12847
|
// apps/cli/src/components/home-ascii-art.tsx
|
|
12201
|
-
import { jsxDEV as
|
|
12848
|
+
import { jsxDEV as jsxDEV23 } from "@opentui/react/jsx-dev-runtime";
|
|
12202
12849
|
function HomeAsciiArt() {
|
|
12203
|
-
return /* @__PURE__ */
|
|
12850
|
+
return /* @__PURE__ */ jsxDEV23("box", {
|
|
12204
12851
|
flexDirection: "column",
|
|
12205
12852
|
alignItems: "center",
|
|
12206
|
-
children: /* @__PURE__ */
|
|
12853
|
+
children: /* @__PURE__ */ jsxDEV23("ascii-font", {
|
|
12207
12854
|
text: "lightcode",
|
|
12208
12855
|
font: "block",
|
|
12209
12856
|
color: logoColors
|
|
@@ -12221,7 +12868,7 @@ var init_home_ascii_art = __esm(() => {
|
|
|
12221
12868
|
import { useKeyboard as useKeyboard6 } from "@opentui/react";
|
|
12222
12869
|
import { useState as useState12 } from "react";
|
|
12223
12870
|
import { useNavigate as useNavigate2 } from "react-router";
|
|
12224
|
-
import { jsxDEV as
|
|
12871
|
+
import { jsxDEV as jsxDEV24 } from "@opentui/react/jsx-dev-runtime";
|
|
12225
12872
|
function HomeTextArea() {
|
|
12226
12873
|
const navigate = useNavigate2();
|
|
12227
12874
|
const {
|
|
@@ -12299,14 +12946,14 @@ function HomeTextArea() {
|
|
|
12299
12946
|
setIsCreatingSession(false);
|
|
12300
12947
|
}
|
|
12301
12948
|
}
|
|
12302
|
-
return /* @__PURE__ */
|
|
12949
|
+
return /* @__PURE__ */ jsxDEV24("box", {
|
|
12303
12950
|
width: "66%",
|
|
12304
12951
|
maxWidth: 104,
|
|
12305
12952
|
minWidth: 64,
|
|
12306
12953
|
flexDirection: "column",
|
|
12307
12954
|
gap: 1,
|
|
12308
12955
|
children: [
|
|
12309
|
-
/* @__PURE__ */
|
|
12956
|
+
/* @__PURE__ */ jsxDEV24(ChatTextArea, {
|
|
12310
12957
|
containerHeight: 7,
|
|
12311
12958
|
allowEmpty: true,
|
|
12312
12959
|
trimOnSubmit: false,
|
|
@@ -12316,7 +12963,7 @@ function HomeTextArea() {
|
|
|
12316
12963
|
modeToggleHint: true,
|
|
12317
12964
|
slashMenuOpen,
|
|
12318
12965
|
onTextChange: syncSlashMenuFromInput,
|
|
12319
|
-
beforeInput: slashMenuOpen ? /* @__PURE__ */
|
|
12966
|
+
beforeInput: slashMenuOpen ? /* @__PURE__ */ jsxDEV24(SlashPageMenu, {
|
|
12320
12967
|
query: slashMenuQuery,
|
|
12321
12968
|
selectedIndex,
|
|
12322
12969
|
routes: slashRoutes
|
|
@@ -12324,21 +12971,21 @@ function HomeTextArea() {
|
|
|
12324
12971
|
onSubmit: (text) => {
|
|
12325
12972
|
createSessionAndNavigate(text);
|
|
12326
12973
|
},
|
|
12327
|
-
footer: /* @__PURE__ */
|
|
12974
|
+
footer: /* @__PURE__ */ jsxDEV24("box", {
|
|
12328
12975
|
flexDirection: "row",
|
|
12329
12976
|
justifyContent: "space-between",
|
|
12330
12977
|
children: [
|
|
12331
|
-
/* @__PURE__ */
|
|
12978
|
+
/* @__PURE__ */ jsxDEV24("text", {
|
|
12332
12979
|
fg: cliTheme.text.muted,
|
|
12333
12980
|
children: isCreatingSession ? "Creating session..." : "Tab/Ctrl+T switch mode | Ctrl+P commands"
|
|
12334
12981
|
}, undefined, false, undefined, this),
|
|
12335
|
-
/* @__PURE__ */
|
|
12982
|
+
/* @__PURE__ */ jsxDEV24("text", {
|
|
12336
12983
|
children: [
|
|
12337
|
-
/* @__PURE__ */
|
|
12984
|
+
/* @__PURE__ */ jsxDEV24("span", {
|
|
12338
12985
|
fg: cliTheme.accent.primary,
|
|
12339
12986
|
children: modeDefinition.label
|
|
12340
12987
|
}, undefined, false, undefined, this),
|
|
12341
|
-
/* @__PURE__ */
|
|
12988
|
+
/* @__PURE__ */ jsxDEV24("span", {
|
|
12342
12989
|
fg: cliTheme.text.muted,
|
|
12343
12990
|
children: " mode"
|
|
12344
12991
|
}, undefined, false, undefined, this)
|
|
@@ -12347,9 +12994,9 @@ function HomeTextArea() {
|
|
|
12347
12994
|
]
|
|
12348
12995
|
}, undefined, true, undefined, this)
|
|
12349
12996
|
}, undefined, false, undefined, this),
|
|
12350
|
-
sessionCreateError ? /* @__PURE__ */
|
|
12997
|
+
sessionCreateError ? /* @__PURE__ */ jsxDEV24("box", {
|
|
12351
12998
|
paddingX: 1,
|
|
12352
|
-
children: /* @__PURE__ */
|
|
12999
|
+
children: /* @__PURE__ */ jsxDEV24("text", {
|
|
12353
13000
|
fg: cliTheme.semantic.error,
|
|
12354
13001
|
children: sessionCreateError
|
|
12355
13002
|
}, undefined, false, undefined, this)
|
|
@@ -12370,12 +13017,12 @@ var init_home_text_area = __esm(() => {
|
|
|
12370
13017
|
|
|
12371
13018
|
// apps/cli/src/components/server-status.tsx
|
|
12372
13019
|
import { useEffect as useEffect10, useState as useState13 } from "react";
|
|
12373
|
-
import { jsxDEV as
|
|
13020
|
+
import { jsxDEV as jsxDEV25 } from "@opentui/react/jsx-dev-runtime";
|
|
12374
13021
|
function ServerStatus() {
|
|
12375
13022
|
const [status, setStatus] = useState13("checking");
|
|
12376
13023
|
useEffect10(() => {
|
|
12377
13024
|
let cancelled = false;
|
|
12378
|
-
async function
|
|
13025
|
+
async function checkServer2() {
|
|
12379
13026
|
try {
|
|
12380
13027
|
if (!cancelled) {
|
|
12381
13028
|
const response = await fetch(apiBaseUrl);
|
|
@@ -12387,12 +13034,12 @@ function ServerStatus() {
|
|
|
12387
13034
|
}
|
|
12388
13035
|
}
|
|
12389
13036
|
}
|
|
12390
|
-
|
|
13037
|
+
checkServer2();
|
|
12391
13038
|
return () => {
|
|
12392
13039
|
cancelled = true;
|
|
12393
13040
|
};
|
|
12394
13041
|
}, []);
|
|
12395
|
-
return /* @__PURE__ */
|
|
13042
|
+
return /* @__PURE__ */ jsxDEV25("text", {
|
|
12396
13043
|
fg: serverStatusColors[status],
|
|
12397
13044
|
children: [
|
|
12398
13045
|
"Server: ",
|
|
@@ -12406,9 +13053,9 @@ var init_server_status = __esm(() => {
|
|
|
12406
13053
|
});
|
|
12407
13054
|
|
|
12408
13055
|
// apps/cli/src/screens/home-screen.tsx
|
|
12409
|
-
import { jsxDEV as
|
|
13056
|
+
import { jsxDEV as jsxDEV26 } from "@opentui/react/jsx-dev-runtime";
|
|
12410
13057
|
function HomeScreen() {
|
|
12411
|
-
return /* @__PURE__ */
|
|
13058
|
+
return /* @__PURE__ */ jsxDEV26("box", {
|
|
12412
13059
|
width: "100%",
|
|
12413
13060
|
height: "100%",
|
|
12414
13061
|
flexDirection: "column",
|
|
@@ -12419,9 +13066,9 @@ function HomeScreen() {
|
|
|
12419
13066
|
paddingY: 1,
|
|
12420
13067
|
backgroundColor: cliTheme.surfaces.base,
|
|
12421
13068
|
children: [
|
|
12422
|
-
/* @__PURE__ */
|
|
12423
|
-
/* @__PURE__ */
|
|
12424
|
-
/* @__PURE__ */
|
|
13069
|
+
/* @__PURE__ */ jsxDEV26(HomeAsciiArt, {}, undefined, false, undefined, this),
|
|
13070
|
+
/* @__PURE__ */ jsxDEV26(ServerStatus, {}, undefined, false, undefined, this),
|
|
13071
|
+
/* @__PURE__ */ jsxDEV26(HomeTextArea, {}, undefined, false, undefined, this)
|
|
12425
13072
|
]
|
|
12426
13073
|
}, undefined, true, undefined, this);
|
|
12427
13074
|
}
|
|
@@ -12433,10 +13080,10 @@ var init_home_screen = __esm(() => {
|
|
|
12433
13080
|
});
|
|
12434
13081
|
|
|
12435
13082
|
// apps/cli/src/screens/model-screen.tsx
|
|
12436
|
-
import { TextAttributes as
|
|
13083
|
+
import { TextAttributes as TextAttributes17 } from "@opentui/core";
|
|
12437
13084
|
import { useKeyboard as useKeyboard7 } from "@opentui/react";
|
|
12438
13085
|
import { useCallback as useCallback6, useEffect as useEffect11, useState as useState14 } from "react";
|
|
12439
|
-
import { jsxDEV as
|
|
13086
|
+
import { jsxDEV as jsxDEV27 } from "@opentui/react/jsx-dev-runtime";
|
|
12440
13087
|
function ModelScreen() {
|
|
12441
13088
|
const [isLoading, setIsLoading] = useState14(true);
|
|
12442
13089
|
const [payload, setPayload] = useState14(null);
|
|
@@ -12468,42 +13115,42 @@ function ModelScreen() {
|
|
|
12468
13115
|
keyEvent.stopPropagation();
|
|
12469
13116
|
loadModelConfig();
|
|
12470
13117
|
});
|
|
12471
|
-
return /* @__PURE__ */
|
|
13118
|
+
return /* @__PURE__ */ jsxDEV27("box", {
|
|
12472
13119
|
width: "100%",
|
|
12473
13120
|
height: "100%",
|
|
12474
13121
|
flexDirection: "column",
|
|
12475
13122
|
gap: 1,
|
|
12476
13123
|
paddingX: 1,
|
|
12477
13124
|
children: [
|
|
12478
|
-
/* @__PURE__ */
|
|
13125
|
+
/* @__PURE__ */ jsxDEV27("box", {
|
|
12479
13126
|
flexDirection: "row",
|
|
12480
13127
|
justifyContent: "space-between",
|
|
12481
13128
|
children: [
|
|
12482
|
-
/* @__PURE__ */
|
|
13129
|
+
/* @__PURE__ */ jsxDEV27("text", {
|
|
12483
13130
|
fg: cliTheme.text.primary,
|
|
12484
|
-
attributes:
|
|
13131
|
+
attributes: TextAttributes17.BOLD,
|
|
12485
13132
|
children: "Model"
|
|
12486
13133
|
}, undefined, false, undefined, this),
|
|
12487
|
-
/* @__PURE__ */
|
|
13134
|
+
/* @__PURE__ */ jsxDEV27("text", {
|
|
12488
13135
|
fg: cliTheme.text.muted,
|
|
12489
13136
|
children: isLoading ? "loading..." : "press r to refresh"
|
|
12490
13137
|
}, undefined, false, undefined, this)
|
|
12491
13138
|
]
|
|
12492
13139
|
}, undefined, true, undefined, this),
|
|
12493
|
-
errorMessage ? /* @__PURE__ */
|
|
12494
|
-
children: /* @__PURE__ */
|
|
13140
|
+
errorMessage ? /* @__PURE__ */ jsxDEV27("box", {
|
|
13141
|
+
children: /* @__PURE__ */ jsxDEV27("text", {
|
|
12495
13142
|
fg: cliTheme.semantic.error,
|
|
12496
13143
|
children: errorMessage
|
|
12497
13144
|
}, undefined, false, undefined, this)
|
|
12498
|
-
}, undefined, false, undefined, this) : payload ? /* @__PURE__ */
|
|
13145
|
+
}, undefined, false, undefined, this) : payload ? /* @__PURE__ */ jsxDEV27("scrollbox", {
|
|
12499
13146
|
flexGrow: 1,
|
|
12500
13147
|
flexDirection: "column",
|
|
12501
13148
|
gap: 1,
|
|
12502
13149
|
children: [
|
|
12503
|
-
/* @__PURE__ */
|
|
13150
|
+
/* @__PURE__ */ jsxDEV27(ModelInfo, {
|
|
12504
13151
|
payload
|
|
12505
13152
|
}, undefined, false, undefined, this),
|
|
12506
|
-
payload.missingCredentialHints.length > 0 ? /* @__PURE__ */
|
|
13153
|
+
payload.missingCredentialHints.length > 0 ? /* @__PURE__ */ jsxDEV27(CredentialHints, {
|
|
12507
13154
|
hints: payload.missingCredentialHints
|
|
12508
13155
|
}, undefined, false, undefined, this) : null
|
|
12509
13156
|
]
|
|
@@ -12513,7 +13160,7 @@ function ModelScreen() {
|
|
|
12513
13160
|
}
|
|
12514
13161
|
function ModelInfo({ payload }) {
|
|
12515
13162
|
const baseUrlStatus = payload.baseUrl ? "configured" : "default";
|
|
12516
|
-
return /* @__PURE__ */
|
|
13163
|
+
return /* @__PURE__ */ jsxDEV27("box", {
|
|
12517
13164
|
flexDirection: "column",
|
|
12518
13165
|
gap: 2,
|
|
12519
13166
|
paddingY: 1,
|
|
@@ -12521,19 +13168,19 @@ function ModelInfo({ payload }) {
|
|
|
12521
13168
|
borderColor: cliTheme.borders.subtle,
|
|
12522
13169
|
backgroundColor: cliTheme.surfaces.panel,
|
|
12523
13170
|
children: [
|
|
12524
|
-
/* @__PURE__ */
|
|
13171
|
+
/* @__PURE__ */ jsxDEV27(InfoRow2, {
|
|
12525
13172
|
label: "Provider",
|
|
12526
13173
|
value: payload.selectedProvider ?? "not set"
|
|
12527
13174
|
}, undefined, false, undefined, this),
|
|
12528
|
-
/* @__PURE__ */
|
|
13175
|
+
/* @__PURE__ */ jsxDEV27(InfoRow2, {
|
|
12529
13176
|
label: "Model",
|
|
12530
13177
|
value: payload.selectedModel ?? "not set"
|
|
12531
13178
|
}, undefined, false, undefined, this),
|
|
12532
|
-
/* @__PURE__ */
|
|
13179
|
+
/* @__PURE__ */ jsxDEV27(InfoRow2, {
|
|
12533
13180
|
label: "Base URL",
|
|
12534
13181
|
value: `${baseUrlStatus}${payload.baseUrl ? ` (${payload.baseUrl})` : ""}`
|
|
12535
13182
|
}, undefined, false, undefined, this),
|
|
12536
|
-
/* @__PURE__ */
|
|
13183
|
+
/* @__PURE__ */ jsxDEV27(InfoRow2, {
|
|
12537
13184
|
label: "Configured model",
|
|
12538
13185
|
value: payload.configuredModel ?? "not set"
|
|
12539
13186
|
}, undefined, false, undefined, this)
|
|
@@ -12541,16 +13188,16 @@ function ModelInfo({ payload }) {
|
|
|
12541
13188
|
}, undefined, true, undefined, this);
|
|
12542
13189
|
}
|
|
12543
13190
|
function InfoRow2({ label, value }) {
|
|
12544
|
-
return /* @__PURE__ */
|
|
13191
|
+
return /* @__PURE__ */ jsxDEV27("box", {
|
|
12545
13192
|
flexDirection: "row",
|
|
12546
13193
|
gap: 2,
|
|
12547
13194
|
children: [
|
|
12548
|
-
/* @__PURE__ */
|
|
13195
|
+
/* @__PURE__ */ jsxDEV27("text", {
|
|
12549
13196
|
fg: cliTheme.text.muted,
|
|
12550
13197
|
width: 18,
|
|
12551
13198
|
children: label
|
|
12552
13199
|
}, undefined, false, undefined, this),
|
|
12553
|
-
/* @__PURE__ */
|
|
13200
|
+
/* @__PURE__ */ jsxDEV27("text", {
|
|
12554
13201
|
fg: cliTheme.text.primary,
|
|
12555
13202
|
children: value
|
|
12556
13203
|
}, undefined, false, undefined, this)
|
|
@@ -12558,7 +13205,7 @@ function InfoRow2({ label, value }) {
|
|
|
12558
13205
|
}, undefined, true, undefined, this);
|
|
12559
13206
|
}
|
|
12560
13207
|
function CredentialHints({ hints }) {
|
|
12561
|
-
return /* @__PURE__ */
|
|
13208
|
+
return /* @__PURE__ */ jsxDEV27("box", {
|
|
12562
13209
|
flexDirection: "column",
|
|
12563
13210
|
gap: 1,
|
|
12564
13211
|
paddingY: 1,
|
|
@@ -12566,12 +13213,12 @@ function CredentialHints({ hints }) {
|
|
|
12566
13213
|
borderColor: cliTheme.borders.subtle,
|
|
12567
13214
|
backgroundColor: cliTheme.surfaces.panel,
|
|
12568
13215
|
children: [
|
|
12569
|
-
/* @__PURE__ */
|
|
13216
|
+
/* @__PURE__ */ jsxDEV27("text", {
|
|
12570
13217
|
fg: cliTheme.semantic.warning,
|
|
12571
|
-
attributes:
|
|
13218
|
+
attributes: TextAttributes17.BOLD,
|
|
12572
13219
|
children: "Missing Credentials"
|
|
12573
13220
|
}, undefined, false, undefined, this),
|
|
12574
|
-
hints.map((hint, index) => /* @__PURE__ */
|
|
13221
|
+
hints.map((hint, index) => /* @__PURE__ */ jsxDEV27("text", {
|
|
12575
13222
|
fg: cliTheme.text.secondary,
|
|
12576
13223
|
children: [
|
|
12577
13224
|
"- ",
|
|
@@ -12588,23 +13235,302 @@ var init_model_screen = __esm(() => {
|
|
|
12588
13235
|
init_text_utils();
|
|
12589
13236
|
});
|
|
12590
13237
|
|
|
12591
|
-
// apps/cli/src/
|
|
12592
|
-
import { TextAttributes as
|
|
13238
|
+
// apps/cli/src/components/chat/model-selector.tsx
|
|
13239
|
+
import { TextAttributes as TextAttributes18 } from "@opentui/core";
|
|
12593
13240
|
import { useKeyboard as useKeyboard8 } from "@opentui/react";
|
|
12594
|
-
import {
|
|
12595
|
-
import
|
|
12596
|
-
|
|
12597
|
-
|
|
13241
|
+
import { useEffect as useEffect12, useMemo as useMemo6, useState as useState15 } from "react";
|
|
13242
|
+
import { jsxDEV as jsxDEV28 } from "@opentui/react/jsx-dev-runtime";
|
|
13243
|
+
function formatContextLength(contextLength) {
|
|
13244
|
+
if (!contextLength) {
|
|
13245
|
+
return "ctx ?";
|
|
13246
|
+
}
|
|
13247
|
+
return `ctx ${Math.round(contextLength / 1000)}k`;
|
|
13248
|
+
}
|
|
13249
|
+
function ModelSelector({ onClose, notify }) {
|
|
13250
|
+
const [models, setModels] = useState15([]);
|
|
13251
|
+
const [currentModel, setCurrentModel] = useState15(null);
|
|
13252
|
+
const [loadError, setLoadError] = useState15(null);
|
|
13253
|
+
const [isLoading, setIsLoading] = useState15(true);
|
|
13254
|
+
const [isApplying, setIsApplying] = useState15(false);
|
|
13255
|
+
const [filter, setFilter] = useState15("");
|
|
13256
|
+
const [selectedIndex, setSelectedIndex] = useState15(0);
|
|
13257
|
+
useEffect12(() => {
|
|
13258
|
+
let cancelled = false;
|
|
13259
|
+
async function loadModels() {
|
|
13260
|
+
try {
|
|
13261
|
+
const [modelsResponse, statusResponse] = await Promise.all([
|
|
13262
|
+
client.config.models.$get({ query: { provider: "openrouter" } }),
|
|
13263
|
+
client.config.status.$get()
|
|
13264
|
+
]);
|
|
13265
|
+
if (!modelsResponse.ok) {
|
|
13266
|
+
throw new Error(`Server returned HTTP ${modelsResponse.status}`);
|
|
13267
|
+
}
|
|
13268
|
+
const payload = await modelsResponse.json();
|
|
13269
|
+
const loadedModels = "models" in payload ? payload.models : [];
|
|
13270
|
+
let activeModel = null;
|
|
13271
|
+
if (statusResponse.ok) {
|
|
13272
|
+
const status = await statusResponse.json();
|
|
13273
|
+
activeModel = status.selectedModel ?? null;
|
|
13274
|
+
}
|
|
13275
|
+
if (!cancelled) {
|
|
13276
|
+
setModels(loadedModels);
|
|
13277
|
+
setCurrentModel(activeModel);
|
|
13278
|
+
setIsLoading(false);
|
|
13279
|
+
}
|
|
13280
|
+
} catch (error) {
|
|
13281
|
+
if (!cancelled) {
|
|
13282
|
+
setLoadError(error instanceof Error ? error.message : "Unable to load models.");
|
|
13283
|
+
setIsLoading(false);
|
|
13284
|
+
}
|
|
13285
|
+
}
|
|
13286
|
+
}
|
|
13287
|
+
loadModels();
|
|
13288
|
+
return () => {
|
|
13289
|
+
cancelled = true;
|
|
13290
|
+
};
|
|
13291
|
+
}, []);
|
|
13292
|
+
const filteredModels = useMemo6(() => {
|
|
13293
|
+
const normalized = filter.trim().toLowerCase();
|
|
13294
|
+
if (!normalized) {
|
|
13295
|
+
return models;
|
|
13296
|
+
}
|
|
13297
|
+
return models.filter((model) => model.id.toLowerCase().includes(normalized) || model.name.toLowerCase().includes(normalized));
|
|
13298
|
+
}, [filter, models]);
|
|
13299
|
+
useEffect12(() => {
|
|
13300
|
+
setSelectedIndex((current) => Math.min(current, Math.max(filteredModels.length - 1, 0)));
|
|
13301
|
+
}, [filteredModels.length]);
|
|
13302
|
+
const applyModel = async (model) => {
|
|
13303
|
+
setIsApplying(true);
|
|
13304
|
+
try {
|
|
13305
|
+
const response = await client.config.model.$put({
|
|
13306
|
+
json: { provider: "openrouter", model: model.id }
|
|
13307
|
+
});
|
|
13308
|
+
if (!response.ok) {
|
|
13309
|
+
const body = await response.json().catch(() => null);
|
|
13310
|
+
throw new Error(body?.error ?? `Server returned HTTP ${response.status}`);
|
|
13311
|
+
}
|
|
13312
|
+
notify(`Model switched to ${model.id} (saved to settings.json).`);
|
|
13313
|
+
onClose();
|
|
13314
|
+
} catch (error) {
|
|
13315
|
+
notify(`Model switch failed: ${error instanceof Error ? error.message : "unknown error"}`, "error");
|
|
13316
|
+
setIsApplying(false);
|
|
13317
|
+
}
|
|
13318
|
+
};
|
|
13319
|
+
useKeyboard8((keyEvent) => {
|
|
13320
|
+
const keyName = keyEvent.name.toLowerCase();
|
|
13321
|
+
if (isEscapeKey(keyName)) {
|
|
13322
|
+
keyEvent.preventDefault();
|
|
13323
|
+
keyEvent.stopPropagation();
|
|
13324
|
+
onClose();
|
|
13325
|
+
return;
|
|
13326
|
+
}
|
|
13327
|
+
if (isApplying) {
|
|
13328
|
+
return;
|
|
13329
|
+
}
|
|
13330
|
+
if (isDownKey(keyName)) {
|
|
13331
|
+
keyEvent.preventDefault();
|
|
13332
|
+
keyEvent.stopPropagation();
|
|
13333
|
+
setSelectedIndex((current) => Math.min(current + 1, Math.max(filteredModels.length - 1, 0)));
|
|
13334
|
+
return;
|
|
13335
|
+
}
|
|
13336
|
+
if (isUpKey(keyName)) {
|
|
13337
|
+
keyEvent.preventDefault();
|
|
13338
|
+
keyEvent.stopPropagation();
|
|
13339
|
+
setSelectedIndex((current) => Math.max(current - 1, 0));
|
|
13340
|
+
return;
|
|
13341
|
+
}
|
|
13342
|
+
if (isEnterKey(keyName)) {
|
|
13343
|
+
keyEvent.preventDefault();
|
|
13344
|
+
keyEvent.stopPropagation();
|
|
13345
|
+
const selected = filteredModels[selectedIndex];
|
|
13346
|
+
if (selected) {
|
|
13347
|
+
applyModel(selected);
|
|
13348
|
+
}
|
|
13349
|
+
return;
|
|
13350
|
+
}
|
|
13351
|
+
if (isBackspaceKey(keyName, keyEvent.sequence)) {
|
|
13352
|
+
keyEvent.preventDefault();
|
|
13353
|
+
keyEvent.stopPropagation();
|
|
13354
|
+
setFilter((current) => current.slice(0, -1));
|
|
13355
|
+
return;
|
|
13356
|
+
}
|
|
13357
|
+
const sequence = keyEvent.sequence ?? "";
|
|
13358
|
+
if (sequence.length === 1 && !keyEvent.ctrl && !keyEvent.meta && sequence >= " " && sequence !== "\x7F") {
|
|
13359
|
+
keyEvent.preventDefault();
|
|
13360
|
+
keyEvent.stopPropagation();
|
|
13361
|
+
setFilter((current) => current + sequence);
|
|
13362
|
+
}
|
|
13363
|
+
});
|
|
13364
|
+
const windowStart = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisibleRows / 2), filteredModels.length - maxVisibleRows));
|
|
13365
|
+
const visibleModels = filteredModels.slice(windowStart, windowStart + maxVisibleRows);
|
|
13366
|
+
return /* @__PURE__ */ jsxDEV28("box", {
|
|
13367
|
+
width: "100%",
|
|
13368
|
+
flexDirection: "column",
|
|
13369
|
+
borderStyle: "single",
|
|
13370
|
+
borderColor: cliTheme.overlay.border,
|
|
13371
|
+
backgroundColor: cliTheme.overlay.surface,
|
|
13372
|
+
children: [
|
|
13373
|
+
/* @__PURE__ */ jsxDEV28("box", {
|
|
13374
|
+
width: "100%",
|
|
13375
|
+
flexDirection: "row",
|
|
13376
|
+
justifyContent: "space-between",
|
|
13377
|
+
paddingX: 2,
|
|
13378
|
+
paddingY: 1,
|
|
13379
|
+
borderStyle: "single",
|
|
13380
|
+
border: ["bottom"],
|
|
13381
|
+
borderColor: cliTheme.overlay.border,
|
|
13382
|
+
children: [
|
|
13383
|
+
/* @__PURE__ */ jsxDEV28("text", {
|
|
13384
|
+
fg: cliTheme.accent.primary,
|
|
13385
|
+
attributes: TextAttributes18.BOLD,
|
|
13386
|
+
children: "Switch Model (OpenRouter)"
|
|
13387
|
+
}, undefined, false, undefined, this),
|
|
13388
|
+
/* @__PURE__ */ jsxDEV28("text", {
|
|
13389
|
+
fg: cliTheme.overlay.footerText,
|
|
13390
|
+
children: "type to filter | \u2191/\u2193 select | Enter confirm | Esc cancel"
|
|
13391
|
+
}, undefined, false, undefined, this)
|
|
13392
|
+
]
|
|
13393
|
+
}, undefined, true, undefined, this),
|
|
13394
|
+
/* @__PURE__ */ jsxDEV28("box", {
|
|
13395
|
+
width: "100%",
|
|
13396
|
+
paddingX: 2,
|
|
13397
|
+
paddingY: 1,
|
|
13398
|
+
children: /* @__PURE__ */ jsxDEV28("text", {
|
|
13399
|
+
fg: cliTheme.text.primary,
|
|
13400
|
+
children: `Filter: ${filter}\u2588`
|
|
13401
|
+
}, undefined, false, undefined, this)
|
|
13402
|
+
}, undefined, false, undefined, this),
|
|
13403
|
+
isLoading ? /* @__PURE__ */ jsxDEV28("box", {
|
|
13404
|
+
paddingX: 2,
|
|
13405
|
+
paddingY: 1,
|
|
13406
|
+
children: /* @__PURE__ */ jsxDEV28("text", {
|
|
13407
|
+
fg: cliTheme.text.muted,
|
|
13408
|
+
children: "Loading models..."
|
|
13409
|
+
}, undefined, false, undefined, this)
|
|
13410
|
+
}, undefined, false, undefined, this) : loadError ? /* @__PURE__ */ jsxDEV28("box", {
|
|
13411
|
+
paddingX: 2,
|
|
13412
|
+
paddingY: 1,
|
|
13413
|
+
children: /* @__PURE__ */ jsxDEV28("text", {
|
|
13414
|
+
fg: cliTheme.semantic.error,
|
|
13415
|
+
children: loadError
|
|
13416
|
+
}, undefined, false, undefined, this)
|
|
13417
|
+
}, undefined, false, undefined, this) : filteredModels.length === 0 ? /* @__PURE__ */ jsxDEV28("box", {
|
|
13418
|
+
paddingX: 2,
|
|
13419
|
+
paddingY: 1,
|
|
13420
|
+
children: /* @__PURE__ */ jsxDEV28("text", {
|
|
13421
|
+
fg: cliTheme.text.muted,
|
|
13422
|
+
children: `No models match "${filter}".`
|
|
13423
|
+
}, undefined, false, undefined, this)
|
|
13424
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV28("box", {
|
|
13425
|
+
flexDirection: "column",
|
|
13426
|
+
paddingY: 1,
|
|
13427
|
+
children: [
|
|
13428
|
+
visibleModels.map((model, visibleIndex) => {
|
|
13429
|
+
const index = windowStart + visibleIndex;
|
|
13430
|
+
const isSelected = index === selectedIndex;
|
|
13431
|
+
const rowColors = getOverlayRowColors(isSelected);
|
|
13432
|
+
return /* @__PURE__ */ jsxDEV28("box", {
|
|
13433
|
+
width: "100%",
|
|
13434
|
+
flexDirection: "row",
|
|
13435
|
+
paddingX: 2,
|
|
13436
|
+
backgroundColor: rowColors.backgroundColor,
|
|
13437
|
+
children: [
|
|
13438
|
+
/* @__PURE__ */ jsxDEV28("text", {
|
|
13439
|
+
width: 2,
|
|
13440
|
+
fg: isSelected ? cliTheme.accent.primary : cliTheme.text.muted,
|
|
13441
|
+
attributes: TextAttributes18.BOLD,
|
|
13442
|
+
children: isSelected ? ">" : " "
|
|
13443
|
+
}, undefined, false, undefined, this),
|
|
13444
|
+
/* @__PURE__ */ jsxDEV28("text", {
|
|
13445
|
+
fg: isSelected ? cliTheme.overlay.selectedRowText : cliTheme.text.primary,
|
|
13446
|
+
attributes: isSelected ? TextAttributes18.BOLD : TextAttributes18.NONE,
|
|
13447
|
+
children: model.id
|
|
13448
|
+
}, undefined, false, undefined, this),
|
|
13449
|
+
/* @__PURE__ */ jsxDEV28("text", {
|
|
13450
|
+
fg: cliTheme.text.muted,
|
|
13451
|
+
marginLeft: 2,
|
|
13452
|
+
children: `${formatContextLength(model.contextLength)}${model.supportsTools ? " | tools" : ""}${model.supportsReasoning ? " | reasoning" : ""}`
|
|
13453
|
+
}, undefined, false, undefined, this),
|
|
13454
|
+
model.id === currentModel && /* @__PURE__ */ jsxDEV28("text", {
|
|
13455
|
+
fg: cliTheme.accent.primary,
|
|
13456
|
+
marginLeft: 2,
|
|
13457
|
+
children: "(current)"
|
|
13458
|
+
}, undefined, false, undefined, this)
|
|
13459
|
+
]
|
|
13460
|
+
}, model.id, true, undefined, this);
|
|
13461
|
+
}),
|
|
13462
|
+
/* @__PURE__ */ jsxDEV28("box", {
|
|
13463
|
+
paddingX: 2,
|
|
13464
|
+
marginTop: 1,
|
|
13465
|
+
children: /* @__PURE__ */ jsxDEV28("text", {
|
|
13466
|
+
fg: cliTheme.overlay.footerText,
|
|
13467
|
+
children: `${filteredModels.length} model${filteredModels.length === 1 ? "" : "s"}${isApplying ? " | switching..." : ""}`
|
|
13468
|
+
}, undefined, false, undefined, this)
|
|
13469
|
+
}, undefined, false, undefined, this)
|
|
13470
|
+
]
|
|
13471
|
+
}, undefined, true, undefined, this)
|
|
13472
|
+
]
|
|
13473
|
+
}, undefined, true, undefined, this);
|
|
13474
|
+
}
|
|
13475
|
+
var maxVisibleRows = 8;
|
|
13476
|
+
var init_model_selector = __esm(() => {
|
|
13477
|
+
init_client();
|
|
13478
|
+
init_cli_theme();
|
|
13479
|
+
});
|
|
13480
|
+
|
|
13481
|
+
// apps/cli/src/screens/model-select-screen.tsx
|
|
13482
|
+
import { TextAttributes as TextAttributes19 } from "@opentui/core";
|
|
13483
|
+
import { useState as useState16 } from "react";
|
|
12598
13484
|
import { useNavigate as useNavigate3 } from "react-router";
|
|
12599
|
-
import { jsxDEV as
|
|
13485
|
+
import { jsxDEV as jsxDEV29 } from "@opentui/react/jsx-dev-runtime";
|
|
13486
|
+
function ModelSelectScreen() {
|
|
13487
|
+
const navigate = useNavigate3();
|
|
13488
|
+
const [notice, setNotice] = useState16(null);
|
|
13489
|
+
return /* @__PURE__ */ jsxDEV29("box", {
|
|
13490
|
+
width: "100%",
|
|
13491
|
+
height: "100%",
|
|
13492
|
+
flexDirection: "column",
|
|
13493
|
+
gap: 1,
|
|
13494
|
+
paddingX: 1,
|
|
13495
|
+
children: [
|
|
13496
|
+
/* @__PURE__ */ jsxDEV29("text", {
|
|
13497
|
+
fg: cliTheme.text.primary,
|
|
13498
|
+
attributes: TextAttributes19.BOLD,
|
|
13499
|
+
children: "Switch Model"
|
|
13500
|
+
}, undefined, false, undefined, this),
|
|
13501
|
+
notice ? /* @__PURE__ */ jsxDEV29("text", {
|
|
13502
|
+
fg: notice.tone === "error" ? cliTheme.semantic.error : cliTheme.accent.primary,
|
|
13503
|
+
children: notice.text
|
|
13504
|
+
}, undefined, false, undefined, this) : null,
|
|
13505
|
+
/* @__PURE__ */ jsxDEV29(ModelSelector, {
|
|
13506
|
+
notify: (text, tone = "info") => setNotice({ text, tone }),
|
|
13507
|
+
onClose: () => navigate(-1)
|
|
13508
|
+
}, undefined, false, undefined, this)
|
|
13509
|
+
]
|
|
13510
|
+
}, undefined, true, undefined, this);
|
|
13511
|
+
}
|
|
13512
|
+
var init_model_select_screen = __esm(() => {
|
|
13513
|
+
init_model_selector();
|
|
13514
|
+
init_cli_theme();
|
|
13515
|
+
});
|
|
13516
|
+
|
|
13517
|
+
// apps/cli/src/screens/onboarding-screen.tsx
|
|
13518
|
+
import { TextAttributes as TextAttributes20 } from "@opentui/core";
|
|
13519
|
+
import { useKeyboard as useKeyboard9 } from "@opentui/react";
|
|
13520
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
13521
|
+
import os5 from "os";
|
|
13522
|
+
import path17 from "path";
|
|
13523
|
+
import { useCallback as useCallback7, useState as useState17 } from "react";
|
|
13524
|
+
import { useNavigate as useNavigate4 } from "react-router";
|
|
13525
|
+
import { jsxDEV as jsxDEV30 } from "@opentui/react/jsx-dev-runtime";
|
|
12600
13526
|
function getUserSettingsPath() {
|
|
12601
13527
|
const configured = process.env.LIGHTCODE_USER_CONFIG?.trim();
|
|
12602
|
-
return configured ??
|
|
13528
|
+
return configured ?? path17.join(os5.homedir(), ".lightcode", "settings.json");
|
|
12603
13529
|
}
|
|
12604
13530
|
function mergeUserSettings(update) {
|
|
12605
13531
|
const settingsPath = getUserSettingsPath();
|
|
12606
13532
|
let existing = {};
|
|
12607
|
-
if (
|
|
13533
|
+
if (existsSync8(settingsPath)) {
|
|
12608
13534
|
try {
|
|
12609
13535
|
const parsed = JSON.parse(readFileSync5(settingsPath, "utf8"));
|
|
12610
13536
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
@@ -12612,20 +13538,20 @@ function mergeUserSettings(update) {
|
|
|
12612
13538
|
}
|
|
12613
13539
|
} catch {}
|
|
12614
13540
|
}
|
|
12615
|
-
|
|
12616
|
-
|
|
13541
|
+
mkdirSync5(path17.dirname(settingsPath), { recursive: true });
|
|
13542
|
+
writeFileSync3(settingsPath, `${JSON.stringify({ ...existing, ...update }, null, 2)}
|
|
12617
13543
|
`, "utf8");
|
|
12618
13544
|
return settingsPath;
|
|
12619
13545
|
}
|
|
12620
13546
|
function OnboardingScreen() {
|
|
12621
|
-
const navigate =
|
|
13547
|
+
const navigate = useNavigate4();
|
|
12622
13548
|
const { bumpConfigRefresh } = useAppState();
|
|
12623
|
-
const [step, setStep] =
|
|
12624
|
-
const [selectedIndex, setSelectedIndex] =
|
|
12625
|
-
const [apiKey, setApiKey] =
|
|
12626
|
-
const [model, setModel] =
|
|
12627
|
-
const [errorText, setErrorText] =
|
|
12628
|
-
const [serverRestarted, setServerRestarted] =
|
|
13549
|
+
const [step, setStep] = useState17("provider");
|
|
13550
|
+
const [selectedIndex, setSelectedIndex] = useState17(0);
|
|
13551
|
+
const [apiKey, setApiKey] = useState17("");
|
|
13552
|
+
const [model, setModel] = useState17("");
|
|
13553
|
+
const [errorText, setErrorText] = useState17(null);
|
|
13554
|
+
const [serverRestarted, setServerRestarted] = useState17(false);
|
|
12629
13555
|
const provider = providerChoices[selectedIndex];
|
|
12630
13556
|
const completeSetup = useCallback7(async ({
|
|
12631
13557
|
finalModel,
|
|
@@ -12650,7 +13576,7 @@ function OnboardingScreen() {
|
|
|
12650
13576
|
setStep("apiKey");
|
|
12651
13577
|
}
|
|
12652
13578
|
}, [bumpConfigRefresh, provider]);
|
|
12653
|
-
|
|
13579
|
+
useKeyboard9((keyEvent) => {
|
|
12654
13580
|
if (step === "provider") {
|
|
12655
13581
|
if (isDownKey(keyEvent.name)) {
|
|
12656
13582
|
keyEvent.preventDefault();
|
|
@@ -12669,36 +13595,36 @@ function OnboardingScreen() {
|
|
|
12669
13595
|
navigate("/");
|
|
12670
13596
|
}
|
|
12671
13597
|
});
|
|
12672
|
-
return /* @__PURE__ */
|
|
13598
|
+
return /* @__PURE__ */ jsxDEV30("box", {
|
|
12673
13599
|
width: "100%",
|
|
12674
13600
|
height: "100%",
|
|
12675
13601
|
flexDirection: "column",
|
|
12676
13602
|
alignItems: "center",
|
|
12677
13603
|
paddingTop: 2,
|
|
12678
|
-
children: /* @__PURE__ */
|
|
13604
|
+
children: /* @__PURE__ */ jsxDEV30("box", {
|
|
12679
13605
|
width: 72,
|
|
12680
13606
|
flexDirection: "column",
|
|
12681
13607
|
gap: 1,
|
|
12682
13608
|
children: [
|
|
12683
|
-
/* @__PURE__ */
|
|
13609
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12684
13610
|
fg: cliTheme.accent.primary,
|
|
12685
|
-
attributes:
|
|
13611
|
+
attributes: TextAttributes20.BOLD,
|
|
12686
13612
|
children: "Welcome to Lightcode"
|
|
12687
13613
|
}, undefined, false, undefined, this),
|
|
12688
|
-
/* @__PURE__ */
|
|
13614
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12689
13615
|
fg: cliTheme.text.secondary,
|
|
12690
13616
|
children: "One-time setup: pick a model provider and store an API key."
|
|
12691
13617
|
}, undefined, false, undefined, this),
|
|
12692
|
-
/* @__PURE__ */
|
|
13618
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12693
13619
|
fg: cliTheme.text.muted,
|
|
12694
|
-
attributes:
|
|
13620
|
+
attributes: TextAttributes20.DIM,
|
|
12695
13621
|
children: "Keys are stored in ~/.lightcode/credentials.json (environment variables always take precedence)."
|
|
12696
13622
|
}, undefined, false, undefined, this),
|
|
12697
|
-
errorText ? /* @__PURE__ */
|
|
13623
|
+
errorText ? /* @__PURE__ */ jsxDEV30("text", {
|
|
12698
13624
|
fg: cliTheme.semantic.error,
|
|
12699
13625
|
children: errorText
|
|
12700
13626
|
}, undefined, false, undefined, this) : null,
|
|
12701
|
-
step === "provider" ? /* @__PURE__ */
|
|
13627
|
+
step === "provider" ? /* @__PURE__ */ jsxDEV30("box", {
|
|
12702
13628
|
flexDirection: "column",
|
|
12703
13629
|
borderStyle: "single",
|
|
12704
13630
|
borderColor: cliTheme.borders.default,
|
|
@@ -12706,53 +13632,53 @@ function OnboardingScreen() {
|
|
|
12706
13632
|
paddingX: 1,
|
|
12707
13633
|
paddingY: 1,
|
|
12708
13634
|
children: [
|
|
12709
|
-
/* @__PURE__ */
|
|
13635
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12710
13636
|
fg: cliTheme.text.primary,
|
|
12711
|
-
attributes:
|
|
13637
|
+
attributes: TextAttributes20.BOLD,
|
|
12712
13638
|
children: "Choose a provider"
|
|
12713
13639
|
}, undefined, false, undefined, this),
|
|
12714
|
-
providerChoices.map((choice, index) => /* @__PURE__ */
|
|
13640
|
+
providerChoices.map((choice, index) => /* @__PURE__ */ jsxDEV30("box", {
|
|
12715
13641
|
flexDirection: "row",
|
|
12716
13642
|
gap: 1,
|
|
12717
13643
|
backgroundColor: index === selectedIndex ? cliTheme.overlay.selectedRowBackground : undefined,
|
|
12718
13644
|
paddingX: 1,
|
|
12719
13645
|
children: [
|
|
12720
|
-
/* @__PURE__ */
|
|
13646
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12721
13647
|
fg: index === selectedIndex ? cliTheme.accent.primary : cliTheme.text.muted,
|
|
12722
13648
|
children: index === selectedIndex ? ">" : " "
|
|
12723
13649
|
}, undefined, false, undefined, this),
|
|
12724
|
-
/* @__PURE__ */
|
|
13650
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12725
13651
|
fg: index === selectedIndex ? cliTheme.overlay.selectedRowText : cliTheme.text.primary,
|
|
12726
|
-
attributes: index === selectedIndex ?
|
|
13652
|
+
attributes: index === selectedIndex ? TextAttributes20.BOLD : TextAttributes20.NONE,
|
|
12727
13653
|
children: choice.label
|
|
12728
13654
|
}, undefined, false, undefined, this),
|
|
12729
|
-
/* @__PURE__ */
|
|
13655
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12730
13656
|
fg: cliTheme.overlay.description,
|
|
12731
13657
|
children: choice.description
|
|
12732
13658
|
}, undefined, false, undefined, this)
|
|
12733
13659
|
]
|
|
12734
13660
|
}, choice.id, true, undefined, this)),
|
|
12735
|
-
/* @__PURE__ */
|
|
13661
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12736
13662
|
fg: cliTheme.text.muted,
|
|
12737
|
-
attributes:
|
|
13663
|
+
attributes: TextAttributes20.DIM,
|
|
12738
13664
|
children: "Up/Down select - Enter continue"
|
|
12739
13665
|
}, undefined, false, undefined, this)
|
|
12740
13666
|
]
|
|
12741
13667
|
}, undefined, true, undefined, this) : null,
|
|
12742
|
-
step === "apiKey" ? /* @__PURE__ */
|
|
13668
|
+
step === "apiKey" ? /* @__PURE__ */ jsxDEV30("box", {
|
|
12743
13669
|
flexDirection: "column",
|
|
12744
13670
|
gap: 1,
|
|
12745
13671
|
children: [
|
|
12746
|
-
/* @__PURE__ */
|
|
13672
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12747
13673
|
fg: cliTheme.text.primary,
|
|
12748
13674
|
children: `Paste your ${provider.label} API key and press Enter`
|
|
12749
13675
|
}, undefined, false, undefined, this),
|
|
12750
|
-
/* @__PURE__ */
|
|
13676
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12751
13677
|
fg: cliTheme.text.muted,
|
|
12752
|
-
attributes:
|
|
13678
|
+
attributes: TextAttributes20.DIM,
|
|
12753
13679
|
children: provider.keyHint
|
|
12754
13680
|
}, undefined, false, undefined, this),
|
|
12755
|
-
/* @__PURE__ */
|
|
13681
|
+
/* @__PURE__ */ jsxDEV30(ChatTextArea, {
|
|
12756
13682
|
placeholder: "API key...",
|
|
12757
13683
|
onSubmit: (text) => {
|
|
12758
13684
|
const trimmedKey = text.trim();
|
|
@@ -12769,15 +13695,15 @@ function OnboardingScreen() {
|
|
|
12769
13695
|
}, undefined, false, undefined, this)
|
|
12770
13696
|
]
|
|
12771
13697
|
}, undefined, true, undefined, this) : null,
|
|
12772
|
-
step === "model" ? /* @__PURE__ */
|
|
13698
|
+
step === "model" ? /* @__PURE__ */ jsxDEV30("box", {
|
|
12773
13699
|
flexDirection: "column",
|
|
12774
13700
|
gap: 1,
|
|
12775
13701
|
children: [
|
|
12776
|
-
/* @__PURE__ */
|
|
13702
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12777
13703
|
fg: cliTheme.text.primary,
|
|
12778
13704
|
children: `Model id for ${provider.label} (e.g. ${provider.id === "openrouter" ? "anthropic/claude-sonnet-4-6" : "your model id"})`
|
|
12779
13705
|
}, undefined, false, undefined, this),
|
|
12780
|
-
/* @__PURE__ */
|
|
13706
|
+
/* @__PURE__ */ jsxDEV30(ChatTextArea, {
|
|
12781
13707
|
placeholder: "Model id...",
|
|
12782
13708
|
onSubmit: (text) => {
|
|
12783
13709
|
const trimmedModel = text.trim();
|
|
@@ -12798,15 +13724,15 @@ function OnboardingScreen() {
|
|
|
12798
13724
|
}, undefined, false, undefined, this)
|
|
12799
13725
|
]
|
|
12800
13726
|
}, undefined, true, undefined, this) : null,
|
|
12801
|
-
step === "baseUrl" ? /* @__PURE__ */
|
|
13727
|
+
step === "baseUrl" ? /* @__PURE__ */ jsxDEV30("box", {
|
|
12802
13728
|
flexDirection: "column",
|
|
12803
13729
|
gap: 1,
|
|
12804
13730
|
children: [
|
|
12805
|
-
/* @__PURE__ */
|
|
13731
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12806
13732
|
fg: cliTheme.text.primary,
|
|
12807
13733
|
children: "Base URL of the OpenAI-compatible endpoint"
|
|
12808
13734
|
}, undefined, false, undefined, this),
|
|
12809
|
-
/* @__PURE__ */
|
|
13735
|
+
/* @__PURE__ */ jsxDEV30(ChatTextArea, {
|
|
12810
13736
|
placeholder: "https://...",
|
|
12811
13737
|
onSubmit: (text) => {
|
|
12812
13738
|
const trimmedBaseUrl = text.trim();
|
|
@@ -12822,24 +13748,24 @@ function OnboardingScreen() {
|
|
|
12822
13748
|
}, undefined, false, undefined, this)
|
|
12823
13749
|
]
|
|
12824
13750
|
}, undefined, true, undefined, this) : null,
|
|
12825
|
-
step === "saving" ? /* @__PURE__ */
|
|
13751
|
+
step === "saving" ? /* @__PURE__ */ jsxDEV30("text", {
|
|
12826
13752
|
fg: cliTheme.semantic.info,
|
|
12827
13753
|
children: "Saving configuration and restarting the server..."
|
|
12828
13754
|
}, undefined, false, undefined, this) : null,
|
|
12829
|
-
step === "done" ? /* @__PURE__ */
|
|
13755
|
+
step === "done" ? /* @__PURE__ */ jsxDEV30("box", {
|
|
12830
13756
|
flexDirection: "column",
|
|
12831
13757
|
gap: 1,
|
|
12832
13758
|
children: [
|
|
12833
|
-
/* @__PURE__ */
|
|
13759
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12834
13760
|
fg: cliTheme.semantic.success,
|
|
12835
|
-
attributes:
|
|
13761
|
+
attributes: TextAttributes20.BOLD,
|
|
12836
13762
|
children: "Setup complete"
|
|
12837
13763
|
}, undefined, false, undefined, this),
|
|
12838
|
-
/* @__PURE__ */
|
|
13764
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12839
13765
|
fg: cliTheme.text.secondary,
|
|
12840
13766
|
children: serverRestarted ? "The local server was restarted with your new configuration." : "Restart the Lightcode server to pick up the new configuration."
|
|
12841
13767
|
}, undefined, false, undefined, this),
|
|
12842
|
-
/* @__PURE__ */
|
|
13768
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12843
13769
|
fg: cliTheme.text.muted,
|
|
12844
13770
|
children: "Press Enter to start coding."
|
|
12845
13771
|
}, undefined, false, undefined, this)
|
|
@@ -12898,12 +13824,11 @@ var init_onboarding_screen = __esm(() => {
|
|
|
12898
13824
|
});
|
|
12899
13825
|
|
|
12900
13826
|
// apps/cli/src/screens/session-list-screen.tsx
|
|
12901
|
-
import { TextAttributes as
|
|
12902
|
-
import { useKeyboard as
|
|
12903
|
-
import
|
|
12904
|
-
import {
|
|
12905
|
-
import {
|
|
12906
|
-
import { jsxDEV as jsxDEV28 } from "@opentui/react/jsx-dev-runtime";
|
|
13827
|
+
import { TextAttributes as TextAttributes21 } from "@opentui/core";
|
|
13828
|
+
import { useKeyboard as useKeyboard10 } from "@opentui/react";
|
|
13829
|
+
import { useCallback as useCallback8, useEffect as useEffect13, useMemo as useMemo7, useState as useState18 } from "react";
|
|
13830
|
+
import { useNavigate as useNavigate5 } from "react-router";
|
|
13831
|
+
import { jsxDEV as jsxDEV31 } from "@opentui/react/jsx-dev-runtime";
|
|
12907
13832
|
function getSessionLabel(session) {
|
|
12908
13833
|
return session.title ?? session.latestUserPromptPreview ?? session.id;
|
|
12909
13834
|
}
|
|
@@ -12915,20 +13840,25 @@ function sessionMatchesFilter(session, query) {
|
|
|
12915
13840
|
return (session.title ?? "").toLowerCase().includes(normalized) || (session.latestUserPromptPreview ?? "").toLowerCase().includes(normalized) || session.id.toLowerCase().includes(normalized);
|
|
12916
13841
|
}
|
|
12917
13842
|
function SessionListScreen() {
|
|
12918
|
-
const navigate =
|
|
12919
|
-
const [sessions, setSessions] =
|
|
12920
|
-
const [selectedIndex, setSelectedIndex] =
|
|
12921
|
-
const [isLoading, setIsLoading] =
|
|
12922
|
-
const [errorMessage, setErrorMessage] =
|
|
12923
|
-
const [actionMessage, setActionMessage] =
|
|
12924
|
-
const [pendingDeleteId, setPendingDeleteId] =
|
|
12925
|
-
const [filterQuery, setFilterQuery] =
|
|
12926
|
-
const [filterOpen, setFilterOpen] =
|
|
12927
|
-
const [renamingSessionId, setRenamingSessionId] =
|
|
12928
|
-
const visibleSessions =
|
|
13843
|
+
const navigate = useNavigate5();
|
|
13844
|
+
const [sessions, setSessions] = useState18([]);
|
|
13845
|
+
const [selectedIndex, setSelectedIndex] = useState18(0);
|
|
13846
|
+
const [isLoading, setIsLoading] = useState18(true);
|
|
13847
|
+
const [errorMessage, setErrorMessage] = useState18(null);
|
|
13848
|
+
const [actionMessage, setActionMessage] = useState18(null);
|
|
13849
|
+
const [pendingDeleteId, setPendingDeleteId] = useState18(null);
|
|
13850
|
+
const [filterQuery, setFilterQuery] = useState18("");
|
|
13851
|
+
const [filterOpen, setFilterOpen] = useState18(false);
|
|
13852
|
+
const [renamingSessionId, setRenamingSessionId] = useState18(null);
|
|
13853
|
+
const visibleSessions = useMemo7(() => sessions.filter((session) => sessionMatchesFilter(session, filterQuery)), [filterQuery, sessions]);
|
|
12929
13854
|
const safeSelectedIndex = Math.min(selectedIndex, Math.max(visibleSessions.length - 1, 0));
|
|
12930
13855
|
const selectedSession = visibleSessions[safeSelectedIndex] ?? null;
|
|
12931
13856
|
const inputActive = filterOpen || renamingSessionId !== null;
|
|
13857
|
+
const applyLoadedSessions = useCallback8((loadedSessions, droppedCount) => {
|
|
13858
|
+
setSessions(loadedSessions);
|
|
13859
|
+
setSelectedIndex((currentIndex) => Math.min(currentIndex, Math.max(loadedSessions.length - 1, 0)));
|
|
13860
|
+
setErrorMessage(droppedCount > 0 ? `${droppedCount} session${droppedCount === 1 ? "" : "s"} could not be read and ${droppedCount === 1 ? "was" : "were"} skipped.` : null);
|
|
13861
|
+
}, []);
|
|
12932
13862
|
const loadSessions = useCallback8(async () => {
|
|
12933
13863
|
setIsLoading(true);
|
|
12934
13864
|
setErrorMessage(null);
|
|
@@ -12939,17 +13869,31 @@ function SessionListScreen() {
|
|
|
12939
13869
|
}
|
|
12940
13870
|
const rawPayload = await response.json();
|
|
12941
13871
|
const parsedPayload = sessionListResponseSchema.safeParse(rawPayload);
|
|
12942
|
-
if (
|
|
13872
|
+
if (parsedPayload.success) {
|
|
13873
|
+
applyLoadedSessions(parsedPayload.data.sessions, 0);
|
|
13874
|
+
return;
|
|
13875
|
+
}
|
|
13876
|
+
const rawSessions = rawPayload && typeof rawPayload === "object" && Array.isArray(rawPayload.sessions) ? rawPayload.sessions : null;
|
|
13877
|
+
if (!rawSessions) {
|
|
12943
13878
|
throw new Error("Server returned an invalid session list response.");
|
|
12944
13879
|
}
|
|
12945
|
-
|
|
12946
|
-
|
|
13880
|
+
const validSessions = [];
|
|
13881
|
+
let droppedCount = 0;
|
|
13882
|
+
for (const rawSession of rawSessions) {
|
|
13883
|
+
const parsedSession = sessionSummarySchema.safeParse(rawSession);
|
|
13884
|
+
if (parsedSession.success) {
|
|
13885
|
+
validSessions.push(parsedSession.data);
|
|
13886
|
+
} else {
|
|
13887
|
+
droppedCount += 1;
|
|
13888
|
+
}
|
|
13889
|
+
}
|
|
13890
|
+
applyLoadedSessions(validSessions, droppedCount);
|
|
12947
13891
|
} catch (error) {
|
|
12948
|
-
setErrorMessage(getErrorMessage(error, "Unable to
|
|
13892
|
+
setErrorMessage(getErrorMessage(error, "Unable to reach the Lightcode server."));
|
|
12949
13893
|
} finally {
|
|
12950
13894
|
setIsLoading(false);
|
|
12951
13895
|
}
|
|
12952
|
-
}, []);
|
|
13896
|
+
}, [applyLoadedSessions]);
|
|
12953
13897
|
const resumeSelectedSession = useCallback8(() => {
|
|
12954
13898
|
if (!selectedSession) {
|
|
12955
13899
|
setActionMessage("No session selected.");
|
|
@@ -13009,9 +13953,9 @@ function SessionListScreen() {
|
|
|
13009
13953
|
if (!parsedPayload.success) {
|
|
13010
13954
|
throw new Error("Server returned an invalid export response.");
|
|
13011
13955
|
}
|
|
13012
|
-
const exportPath =
|
|
13013
|
-
await Bun.write(exportPath,
|
|
13014
|
-
setActionMessage(`Exported
|
|
13956
|
+
const exportPath = getExportPath(parsedPayload.data.session.title, parsedPayload.data.session.id);
|
|
13957
|
+
await Bun.write(exportPath, sessionToMarkdown(parsedPayload.data));
|
|
13958
|
+
setActionMessage(`Exported Markdown to ${exportPath.replace(/\\/g, "/")}`);
|
|
13015
13959
|
} catch (error) {
|
|
13016
13960
|
setActionMessage(getErrorMessage(error, "Unable to export session."));
|
|
13017
13961
|
}
|
|
@@ -13062,10 +14006,10 @@ function SessionListScreen() {
|
|
|
13062
14006
|
setActionMessage(getErrorMessage(error, "Unable to rename session."));
|
|
13063
14007
|
}
|
|
13064
14008
|
}, [loadSessions]);
|
|
13065
|
-
|
|
14009
|
+
useEffect13(() => {
|
|
13066
14010
|
loadSessions();
|
|
13067
14011
|
}, [loadSessions]);
|
|
13068
|
-
|
|
14012
|
+
useKeyboard10((keyEvent) => {
|
|
13069
14013
|
const keyName = keyEvent.name.toLowerCase();
|
|
13070
14014
|
if (inputActive) {
|
|
13071
14015
|
if (isEscapeKey(keyName)) {
|
|
@@ -13147,55 +14091,55 @@ function SessionListScreen() {
|
|
|
13147
14091
|
exportSelectedSession();
|
|
13148
14092
|
}
|
|
13149
14093
|
});
|
|
13150
|
-
const footerText =
|
|
14094
|
+
const footerText = useMemo7(() => {
|
|
13151
14095
|
if (sessions.length === 0) {
|
|
13152
14096
|
return `u refresh | l resume latest | ${BACK_SHORTCUT_LABEL} back`;
|
|
13153
14097
|
}
|
|
13154
14098
|
return "Enter resume | r rename | f fork | / filter | e export | d delete | u refresh";
|
|
13155
14099
|
}, [sessions.length]);
|
|
13156
|
-
return /* @__PURE__ */
|
|
14100
|
+
return /* @__PURE__ */ jsxDEV31("box", {
|
|
13157
14101
|
width: "100%",
|
|
13158
14102
|
height: "100%",
|
|
13159
14103
|
flexDirection: "column",
|
|
13160
14104
|
gap: 1,
|
|
13161
14105
|
children: [
|
|
13162
|
-
/* @__PURE__ */
|
|
14106
|
+
/* @__PURE__ */ jsxDEV31("box", {
|
|
13163
14107
|
flexDirection: "row",
|
|
13164
14108
|
justifyContent: "space-between",
|
|
13165
14109
|
paddingX: 1,
|
|
13166
14110
|
children: [
|
|
13167
|
-
/* @__PURE__ */
|
|
14111
|
+
/* @__PURE__ */ jsxDEV31("text", {
|
|
13168
14112
|
fg: cliTheme.text.primary,
|
|
13169
|
-
attributes:
|
|
14113
|
+
attributes: TextAttributes21.BOLD,
|
|
13170
14114
|
children: "Sessions"
|
|
13171
14115
|
}, undefined, false, undefined, this),
|
|
13172
|
-
/* @__PURE__ */
|
|
14116
|
+
/* @__PURE__ */ jsxDEV31("text", {
|
|
13173
14117
|
fg: cliTheme.text.muted,
|
|
13174
14118
|
children: isLoading ? "loading..." : `${sessions.length} saved`
|
|
13175
14119
|
}, undefined, false, undefined, this)
|
|
13176
14120
|
]
|
|
13177
14121
|
}, undefined, true, undefined, this),
|
|
13178
|
-
errorMessage ? /* @__PURE__ */
|
|
14122
|
+
errorMessage ? /* @__PURE__ */ jsxDEV31("box", {
|
|
13179
14123
|
paddingX: 1,
|
|
13180
|
-
children: /* @__PURE__ */
|
|
14124
|
+
children: /* @__PURE__ */ jsxDEV31("text", {
|
|
13181
14125
|
fg: cliTheme.semantic.error,
|
|
13182
14126
|
children: errorMessage
|
|
13183
14127
|
}, undefined, false, undefined, this)
|
|
13184
14128
|
}, undefined, false, undefined, this) : null,
|
|
13185
|
-
filterQuery && !filterOpen ? /* @__PURE__ */
|
|
14129
|
+
filterQuery && !filterOpen ? /* @__PURE__ */ jsxDEV31("box", {
|
|
13186
14130
|
paddingX: 1,
|
|
13187
|
-
children: /* @__PURE__ */
|
|
14131
|
+
children: /* @__PURE__ */ jsxDEV31("text", {
|
|
13188
14132
|
fg: cliTheme.accent.primary,
|
|
13189
14133
|
children: `Filter: "${filterQuery}" (${visibleSessions.length} match${visibleSessions.length === 1 ? "" : "es"}) - Esc clears`
|
|
13190
14134
|
}, undefined, false, undefined, this)
|
|
13191
14135
|
}, undefined, false, undefined, this) : null,
|
|
13192
|
-
/* @__PURE__ */
|
|
14136
|
+
/* @__PURE__ */ jsxDEV31("box", {
|
|
13193
14137
|
flexDirection: "column",
|
|
13194
14138
|
flexGrow: 1,
|
|
13195
14139
|
children: [
|
|
13196
|
-
visibleSessions.length === 0 && !isLoading ? /* @__PURE__ */
|
|
14140
|
+
visibleSessions.length === 0 && !isLoading ? /* @__PURE__ */ jsxDEV31("box", {
|
|
13197
14141
|
paddingX: 1,
|
|
13198
|
-
children: /* @__PURE__ */
|
|
14142
|
+
children: /* @__PURE__ */ jsxDEV31("text", {
|
|
13199
14143
|
fg: cliTheme.text.muted,
|
|
13200
14144
|
children: sessions.length === 0 ? "No saved sessions yet." : "No sessions match the filter."
|
|
13201
14145
|
}, undefined, false, undefined, this)
|
|
@@ -13204,34 +14148,34 @@ function SessionListScreen() {
|
|
|
13204
14148
|
const isSelected = index === safeSelectedIndex;
|
|
13205
14149
|
const rowColors = getOverlayRowColors(isSelected);
|
|
13206
14150
|
const selectedForDelete = pendingDeleteId === session.id;
|
|
13207
|
-
return /* @__PURE__ */
|
|
14151
|
+
return /* @__PURE__ */ jsxDEV31("box", {
|
|
13208
14152
|
flexDirection: "column",
|
|
13209
14153
|
paddingX: 1,
|
|
13210
14154
|
backgroundColor: rowColors.backgroundColor,
|
|
13211
14155
|
children: [
|
|
13212
|
-
/* @__PURE__ */
|
|
14156
|
+
/* @__PURE__ */ jsxDEV31("box", {
|
|
13213
14157
|
flexDirection: "row",
|
|
13214
14158
|
justifyContent: "space-between",
|
|
13215
14159
|
children: [
|
|
13216
|
-
/* @__PURE__ */
|
|
14160
|
+
/* @__PURE__ */ jsxDEV31("text", {
|
|
13217
14161
|
fg: selectedForDelete ? cliTheme.semantic.error : rowColors.primaryTextColor,
|
|
13218
|
-
attributes:
|
|
14162
|
+
attributes: TextAttributes21.BOLD,
|
|
13219
14163
|
children: [
|
|
13220
14164
|
index + 1,
|
|
13221
14165
|
". ",
|
|
13222
14166
|
truncateInline2(getSessionLabel(session), 64)
|
|
13223
14167
|
]
|
|
13224
14168
|
}, undefined, true, undefined, this),
|
|
13225
|
-
/* @__PURE__ */
|
|
14169
|
+
/* @__PURE__ */ jsxDEV31("text", {
|
|
13226
14170
|
fg: rowColors.secondaryTextColor,
|
|
13227
|
-
attributes:
|
|
14171
|
+
attributes: TextAttributes21.DIM,
|
|
13228
14172
|
children: `${session.messageCount} msgs - ${session.mode} - ${formatDate2(session.updatedAt)}`
|
|
13229
14173
|
}, undefined, false, undefined, this)
|
|
13230
14174
|
]
|
|
13231
14175
|
}, undefined, true, undefined, this),
|
|
13232
|
-
isSelected && session.latestUserPromptPreview ? /* @__PURE__ */
|
|
14176
|
+
isSelected && session.latestUserPromptPreview ? /* @__PURE__ */ jsxDEV31("text", {
|
|
13233
14177
|
fg: rowColors.secondaryTextColor,
|
|
13234
|
-
attributes:
|
|
14178
|
+
attributes: TextAttributes21.DIM,
|
|
13235
14179
|
children: truncateInline2(session.latestUserPromptPreview, 110)
|
|
13236
14180
|
}, undefined, false, undefined, this) : null
|
|
13237
14181
|
]
|
|
@@ -13239,28 +14183,28 @@ function SessionListScreen() {
|
|
|
13239
14183
|
})
|
|
13240
14184
|
]
|
|
13241
14185
|
}, undefined, true, undefined, this),
|
|
13242
|
-
actionMessage ? /* @__PURE__ */
|
|
14186
|
+
actionMessage ? /* @__PURE__ */ jsxDEV31("box", {
|
|
13243
14187
|
paddingX: 1,
|
|
13244
|
-
children: /* @__PURE__ */
|
|
14188
|
+
children: /* @__PURE__ */ jsxDEV31("text", {
|
|
13245
14189
|
fg: cliTheme.semantic.info,
|
|
13246
14190
|
children: actionMessage
|
|
13247
14191
|
}, undefined, false, undefined, this)
|
|
13248
14192
|
}, undefined, false, undefined, this) : null,
|
|
13249
|
-
filterOpen ? /* @__PURE__ */
|
|
14193
|
+
filterOpen ? /* @__PURE__ */ jsxDEV31(ChatTextArea, {
|
|
13250
14194
|
placeholder: "Filter sessions...",
|
|
13251
14195
|
allowEmpty: true,
|
|
13252
14196
|
onTextChange: setFilterQuery,
|
|
13253
14197
|
onSubmit: () => setFilterOpen(false)
|
|
13254
14198
|
}, undefined, false, undefined, this) : null,
|
|
13255
|
-
renamingSessionId !== null ? /* @__PURE__ */
|
|
14199
|
+
renamingSessionId !== null ? /* @__PURE__ */ jsxDEV31(ChatTextArea, {
|
|
13256
14200
|
placeholder: "New session title...",
|
|
13257
14201
|
onSubmit: (title) => void renameSession(renamingSessionId, title)
|
|
13258
14202
|
}, undefined, false, undefined, this) : null,
|
|
13259
|
-
/* @__PURE__ */
|
|
14203
|
+
/* @__PURE__ */ jsxDEV31("box", {
|
|
13260
14204
|
paddingX: 1,
|
|
13261
|
-
children: /* @__PURE__ */
|
|
14205
|
+
children: /* @__PURE__ */ jsxDEV31("text", {
|
|
13262
14206
|
fg: cliTheme.text.muted,
|
|
13263
|
-
attributes:
|
|
14207
|
+
attributes: TextAttributes21.DIM,
|
|
13264
14208
|
children: inputActive ? "Enter confirm | Esc cancel" : footerText
|
|
13265
14209
|
}, undefined, false, undefined, this)
|
|
13266
14210
|
}, undefined, false, undefined, this)
|
|
@@ -13271,16 +14215,17 @@ var init_session_list_screen = __esm(() => {
|
|
|
13271
14215
|
init_src2();
|
|
13272
14216
|
init_client();
|
|
13273
14217
|
init_keymap();
|
|
14218
|
+
init_export_session_markdown();
|
|
13274
14219
|
init_chat_text_area();
|
|
13275
14220
|
init_cli_theme();
|
|
13276
14221
|
init_text_utils();
|
|
13277
14222
|
});
|
|
13278
14223
|
|
|
13279
14224
|
// apps/cli/src/hooks/use-config-badge.ts
|
|
13280
|
-
import { useEffect as
|
|
14225
|
+
import { useEffect as useEffect14, useState as useState19 } from "react";
|
|
13281
14226
|
function useConfigBadge(refreshNonce = 0) {
|
|
13282
|
-
const [state, setState] =
|
|
13283
|
-
|
|
14227
|
+
const [state, setState] = useState19({ status: "loading" });
|
|
14228
|
+
useEffect14(() => {
|
|
13284
14229
|
let cancelled = false;
|
|
13285
14230
|
async function loadConfig() {
|
|
13286
14231
|
try {
|
|
@@ -13326,11 +14271,11 @@ var exports_app = {};
|
|
|
13326
14271
|
__export(exports_app, {
|
|
13327
14272
|
App: () => App
|
|
13328
14273
|
});
|
|
13329
|
-
import { TextAttributes as
|
|
13330
|
-
import { useKeyboard as
|
|
13331
|
-
import { useEffect as
|
|
13332
|
-
import { MemoryRouter, Navigate, Route, Routes, useLocation as useLocation3, useNavigate as
|
|
13333
|
-
import { jsxDEV as
|
|
14274
|
+
import { TextAttributes as TextAttributes22 } from "@opentui/core";
|
|
14275
|
+
import { useKeyboard as useKeyboard11, useRenderer as useRenderer2 } from "@opentui/react";
|
|
14276
|
+
import { useEffect as useEffect15, useRef as useRef5, useState as useState20 } from "react";
|
|
14277
|
+
import { MemoryRouter, Navigate, Route, Routes, useLocation as useLocation3, useNavigate as useNavigate6 } from "react-router";
|
|
14278
|
+
import { jsxDEV as jsxDEV32 } from "@opentui/react/jsx-dev-runtime";
|
|
13334
14279
|
function getCurrentViewLabel(pathname) {
|
|
13335
14280
|
if (pathname === "/" || pathname === "/home") {
|
|
13336
14281
|
return "home";
|
|
@@ -13356,14 +14301,17 @@ function getCurrentViewLabel(pathname) {
|
|
|
13356
14301
|
if (pathname === "/config") {
|
|
13357
14302
|
return "config";
|
|
13358
14303
|
}
|
|
13359
|
-
if (pathname === "/model") {
|
|
14304
|
+
if (pathname === "/model-info") {
|
|
13360
14305
|
return "model";
|
|
13361
14306
|
}
|
|
14307
|
+
if (pathname === "/model") {
|
|
14308
|
+
return "model-select";
|
|
14309
|
+
}
|
|
13362
14310
|
return pathname;
|
|
13363
14311
|
}
|
|
13364
14312
|
function AppContent() {
|
|
13365
|
-
const renderer =
|
|
13366
|
-
const navigate =
|
|
14313
|
+
const renderer = useRenderer2();
|
|
14314
|
+
const navigate = useNavigate6();
|
|
13367
14315
|
const location = useLocation3();
|
|
13368
14316
|
const {
|
|
13369
14317
|
paletteOpen,
|
|
@@ -13383,7 +14331,45 @@ function AppContent() {
|
|
|
13383
14331
|
configRefreshNonce,
|
|
13384
14332
|
toggleToolOutputExpansion
|
|
13385
14333
|
} = useAppState();
|
|
13386
|
-
const [helpOpen, setHelpOpen] =
|
|
14334
|
+
const [helpOpen, setHelpOpen] = useState20(false);
|
|
14335
|
+
const [ctrlCNotice, setCtrlCNotice] = useState20(null);
|
|
14336
|
+
const ctrlCArmedRef = useRef5(false);
|
|
14337
|
+
const ctrlCTimerRef = useRef5(null);
|
|
14338
|
+
const showCtrlCNotice = (text) => {
|
|
14339
|
+
setCtrlCNotice(text);
|
|
14340
|
+
if (ctrlCTimerRef.current) {
|
|
14341
|
+
clearTimeout(ctrlCTimerRef.current);
|
|
14342
|
+
}
|
|
14343
|
+
ctrlCTimerRef.current = setTimeout(() => {
|
|
14344
|
+
setCtrlCNotice(null);
|
|
14345
|
+
ctrlCArmedRef.current = false;
|
|
14346
|
+
ctrlCTimerRef.current = null;
|
|
14347
|
+
}, 2000);
|
|
14348
|
+
};
|
|
14349
|
+
const handleCtrlC = () => {
|
|
14350
|
+
const selection = renderer.getSelection();
|
|
14351
|
+
const selectedText = selection ? selection.getSelectedText() : "";
|
|
14352
|
+
if (selectedText.trim().length > 0) {
|
|
14353
|
+
copyText(renderer, selectedText);
|
|
14354
|
+
renderer.clearSelection();
|
|
14355
|
+
ctrlCArmedRef.current = false;
|
|
14356
|
+
showCtrlCNotice(`Copied ${selectedText.length} chars to clipboard`);
|
|
14357
|
+
return;
|
|
14358
|
+
}
|
|
14359
|
+
if (ctrlCArmedRef.current) {
|
|
14360
|
+
renderer.destroy();
|
|
14361
|
+
return;
|
|
14362
|
+
}
|
|
14363
|
+
ctrlCArmedRef.current = true;
|
|
14364
|
+
showCtrlCNotice("Press Ctrl+C again to exit");
|
|
14365
|
+
};
|
|
14366
|
+
useEffect15(() => {
|
|
14367
|
+
return () => {
|
|
14368
|
+
if (ctrlCTimerRef.current) {
|
|
14369
|
+
clearTimeout(ctrlCTimerRef.current);
|
|
14370
|
+
}
|
|
14371
|
+
};
|
|
14372
|
+
}, []);
|
|
13387
14373
|
const canGoBack = location.pathname !== "/" && location.pathname !== "/home";
|
|
13388
14374
|
const currentView = getCurrentViewLabel(location.pathname);
|
|
13389
14375
|
const inChatSession = location.pathname.startsWith("/sessions/");
|
|
@@ -13494,7 +14480,11 @@ function AppContent() {
|
|
|
13494
14480
|
closeSlashMenu();
|
|
13495
14481
|
}
|
|
13496
14482
|
};
|
|
13497
|
-
|
|
14483
|
+
useKeyboard11((keyEvent) => {
|
|
14484
|
+
if (keyEvent.ctrl && keyEvent.name === "c") {
|
|
14485
|
+
handleCtrlC();
|
|
14486
|
+
return;
|
|
14487
|
+
}
|
|
13498
14488
|
if (slashMenuOpen) {
|
|
13499
14489
|
handleSlashMenuKeyDown(keyEvent);
|
|
13500
14490
|
return;
|
|
@@ -13504,10 +14494,6 @@ function AppContent() {
|
|
|
13504
14494
|
return;
|
|
13505
14495
|
}
|
|
13506
14496
|
const normalizedKey = normalizeKeyName(keyEvent.name, keyEvent.ctrl, false, false);
|
|
13507
|
-
if (keyEvent.ctrl && keyEvent.name === "c") {
|
|
13508
|
-
handleAction("system:quit");
|
|
13509
|
-
return;
|
|
13510
|
-
}
|
|
13511
14497
|
if (isEscapeKey2(keyEvent)) {
|
|
13512
14498
|
handleAction("system:cancel");
|
|
13513
14499
|
return;
|
|
@@ -13524,7 +14510,7 @@ function AppContent() {
|
|
|
13524
14510
|
});
|
|
13525
14511
|
const configBadge = useConfigBadge(configRefreshNonce);
|
|
13526
14512
|
const needsOnboarding = configBadge.status === "available" && configBadge.missingCredentialHints.length > 0;
|
|
13527
|
-
|
|
14513
|
+
useEffect15(() => {
|
|
13528
14514
|
if (needsOnboarding && location.pathname !== "/onboarding") {
|
|
13529
14515
|
navigate("/onboarding");
|
|
13530
14516
|
}
|
|
@@ -13536,12 +14522,12 @@ function AppContent() {
|
|
|
13536
14522
|
const backHint = canGoBack ? ` | Esc/${BACK_SHORTCUT_LABEL} Back` : "";
|
|
13537
14523
|
return "/ Pages | Ctrl+P Cmd | F1 Help | Ctrl+C Quit" + backHint;
|
|
13538
14524
|
};
|
|
13539
|
-
return /* @__PURE__ */
|
|
14525
|
+
return /* @__PURE__ */ jsxDEV32("box", {
|
|
13540
14526
|
flexDirection: "column",
|
|
13541
14527
|
flexGrow: 1,
|
|
13542
14528
|
backgroundColor: cliTheme.surfaces.base,
|
|
13543
14529
|
children: [
|
|
13544
|
-
/* @__PURE__ */
|
|
14530
|
+
/* @__PURE__ */ jsxDEV32("box", {
|
|
13545
14531
|
flexDirection: "row",
|
|
13546
14532
|
justifyContent: "space-between",
|
|
13547
14533
|
paddingLeft: 1,
|
|
@@ -13550,17 +14536,17 @@ function AppContent() {
|
|
|
13550
14536
|
border: ["bottom"],
|
|
13551
14537
|
borderColor: cliTheme.borders.default,
|
|
13552
14538
|
children: [
|
|
13553
|
-
/* @__PURE__ */
|
|
14539
|
+
/* @__PURE__ */ jsxDEV32("box", {
|
|
13554
14540
|
flexDirection: "row",
|
|
13555
14541
|
gap: 2,
|
|
13556
14542
|
alignItems: "center",
|
|
13557
14543
|
children: [
|
|
13558
|
-
/* @__PURE__ */
|
|
14544
|
+
/* @__PURE__ */ jsxDEV32("text", {
|
|
13559
14545
|
fg: cliTheme.text.primary,
|
|
13560
|
-
attributes:
|
|
14546
|
+
attributes: TextAttributes22.BOLD,
|
|
13561
14547
|
children: "Lightcode"
|
|
13562
14548
|
}, undefined, false, undefined, this),
|
|
13563
|
-
configBadge.status === "available" ? /* @__PURE__ */
|
|
14549
|
+
configBadge.status === "available" ? /* @__PURE__ */ jsxDEV32("text", {
|
|
13564
14550
|
fg: cliTheme.text.secondary,
|
|
13565
14551
|
children: [
|
|
13566
14552
|
"| ",
|
|
@@ -13568,122 +14554,126 @@ function AppContent() {
|
|
|
13568
14554
|
" | ",
|
|
13569
14555
|
configBadge.model
|
|
13570
14556
|
]
|
|
13571
|
-
}, undefined, true, undefined, this) : configBadge.status === "loading" ? /* @__PURE__ */
|
|
14557
|
+
}, undefined, true, undefined, this) : configBadge.status === "loading" ? /* @__PURE__ */ jsxDEV32("text", {
|
|
13572
14558
|
fg: cliTheme.text.muted,
|
|
13573
14559
|
children: "| loading..."
|
|
13574
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
14560
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV32("text", {
|
|
13575
14561
|
fg: cliTheme.text.muted,
|
|
13576
14562
|
children: "| provider unavailable"
|
|
13577
14563
|
}, undefined, false, undefined, this)
|
|
13578
14564
|
]
|
|
13579
14565
|
}, undefined, true, undefined, this),
|
|
13580
|
-
/* @__PURE__ */
|
|
14566
|
+
/* @__PURE__ */ jsxDEV32("text", {
|
|
13581
14567
|
fg: cliTheme.text.muted,
|
|
13582
14568
|
children: currentView
|
|
13583
14569
|
}, undefined, false, undefined, this)
|
|
13584
14570
|
]
|
|
13585
14571
|
}, undefined, true, undefined, this),
|
|
13586
|
-
/* @__PURE__ */
|
|
14572
|
+
/* @__PURE__ */ jsxDEV32("box", {
|
|
13587
14573
|
flexGrow: 1,
|
|
13588
14574
|
padding: 1,
|
|
13589
14575
|
position: "relative",
|
|
13590
14576
|
children: [
|
|
13591
|
-
/* @__PURE__ */
|
|
14577
|
+
/* @__PURE__ */ jsxDEV32(Routes, {
|
|
13592
14578
|
children: [
|
|
13593
|
-
/* @__PURE__ */
|
|
14579
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13594
14580
|
path: "/",
|
|
13595
|
-
element: /* @__PURE__ */
|
|
14581
|
+
element: /* @__PURE__ */ jsxDEV32(HomeScreen, {}, undefined, false, undefined, this)
|
|
13596
14582
|
}, undefined, false, undefined, this),
|
|
13597
|
-
/* @__PURE__ */
|
|
14583
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13598
14584
|
path: "/home",
|
|
13599
|
-
element: /* @__PURE__ */
|
|
14585
|
+
element: /* @__PURE__ */ jsxDEV32(Navigate, {
|
|
13600
14586
|
to: "/",
|
|
13601
14587
|
replace: true
|
|
13602
14588
|
}, undefined, false, undefined, this)
|
|
13603
14589
|
}, undefined, false, undefined, this),
|
|
13604
|
-
/* @__PURE__ */
|
|
14590
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13605
14591
|
path: "/status",
|
|
13606
|
-
element: /* @__PURE__ */
|
|
14592
|
+
element: /* @__PURE__ */ jsxDEV32(DiagnosticsScreen, {
|
|
13607
14593
|
kind: "status"
|
|
13608
14594
|
}, undefined, false, undefined, this)
|
|
13609
14595
|
}, undefined, false, undefined, this),
|
|
13610
|
-
/* @__PURE__ */
|
|
14596
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13611
14597
|
path: "/doctor",
|
|
13612
|
-
element: /* @__PURE__ */
|
|
14598
|
+
element: /* @__PURE__ */ jsxDEV32(DiagnosticsScreen, {
|
|
13613
14599
|
kind: "doctor"
|
|
13614
14600
|
}, undefined, false, undefined, this)
|
|
13615
14601
|
}, undefined, false, undefined, this),
|
|
13616
|
-
/* @__PURE__ */
|
|
14602
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13617
14603
|
path: "/permissions",
|
|
13618
|
-
element: /* @__PURE__ */
|
|
14604
|
+
element: /* @__PURE__ */ jsxDEV32(DiagnosticsScreen, {
|
|
13619
14605
|
kind: "permissions"
|
|
13620
14606
|
}, undefined, false, undefined, this)
|
|
13621
14607
|
}, undefined, false, undefined, this),
|
|
13622
|
-
/* @__PURE__ */
|
|
14608
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13623
14609
|
path: "/sessions",
|
|
13624
|
-
element: /* @__PURE__ */
|
|
14610
|
+
element: /* @__PURE__ */ jsxDEV32(SessionListScreen, {}, undefined, false, undefined, this)
|
|
13625
14611
|
}, undefined, false, undefined, this),
|
|
13626
|
-
/* @__PURE__ */
|
|
14612
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13627
14613
|
path: "/sessions/:id",
|
|
13628
|
-
element: /* @__PURE__ */
|
|
14614
|
+
element: /* @__PURE__ */ jsxDEV32(ChatScreen, {}, undefined, false, undefined, this)
|
|
13629
14615
|
}, undefined, false, undefined, this),
|
|
13630
|
-
/* @__PURE__ */
|
|
14616
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13631
14617
|
path: "/tools",
|
|
13632
|
-
element: /* @__PURE__ */
|
|
14618
|
+
element: /* @__PURE__ */ jsxDEV32(DiagnosticsScreen, {
|
|
13633
14619
|
kind: "tools"
|
|
13634
14620
|
}, undefined, false, undefined, this)
|
|
13635
14621
|
}, undefined, false, undefined, this),
|
|
13636
|
-
/* @__PURE__ */
|
|
14622
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13637
14623
|
path: "/config",
|
|
13638
|
-
element: /* @__PURE__ */
|
|
14624
|
+
element: /* @__PURE__ */ jsxDEV32(DiagnosticsScreen, {
|
|
13639
14625
|
kind: "config"
|
|
13640
14626
|
}, undefined, false, undefined, this)
|
|
13641
14627
|
}, undefined, false, undefined, this),
|
|
13642
|
-
/* @__PURE__ */
|
|
14628
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
14629
|
+
path: "/model-info",
|
|
14630
|
+
element: /* @__PURE__ */ jsxDEV32(ModelScreen, {}, undefined, false, undefined, this)
|
|
14631
|
+
}, undefined, false, undefined, this),
|
|
14632
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13643
14633
|
path: "/model",
|
|
13644
|
-
element: /* @__PURE__ */
|
|
14634
|
+
element: /* @__PURE__ */ jsxDEV32(ModelSelectScreen, {}, undefined, false, undefined, this)
|
|
13645
14635
|
}, undefined, false, undefined, this),
|
|
13646
|
-
/* @__PURE__ */
|
|
14636
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13647
14637
|
path: "/onboarding",
|
|
13648
|
-
element: /* @__PURE__ */
|
|
14638
|
+
element: /* @__PURE__ */ jsxDEV32(OnboardingScreen, {}, undefined, false, undefined, this)
|
|
13649
14639
|
}, undefined, false, undefined, this),
|
|
13650
|
-
/* @__PURE__ */
|
|
14640
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13651
14641
|
path: "*",
|
|
13652
|
-
element: /* @__PURE__ */
|
|
14642
|
+
element: /* @__PURE__ */ jsxDEV32(Navigate, {
|
|
13653
14643
|
to: "/",
|
|
13654
14644
|
replace: true
|
|
13655
14645
|
}, undefined, false, undefined, this)
|
|
13656
14646
|
}, undefined, false, undefined, this)
|
|
13657
14647
|
]
|
|
13658
14648
|
}, undefined, true, undefined, this),
|
|
13659
|
-
paletteOpen ? /* @__PURE__ */
|
|
14649
|
+
paletteOpen ? /* @__PURE__ */ jsxDEV32(CommandPalette, {
|
|
13660
14650
|
query: paletteQuery,
|
|
13661
14651
|
setQuery: setPaletteQuery,
|
|
13662
14652
|
selectedIndex: paletteSelected
|
|
13663
14653
|
}, undefined, false, undefined, this) : null,
|
|
13664
|
-
slashMenuOpen && !inputHostsSlashMenu ? /* @__PURE__ */
|
|
14654
|
+
slashMenuOpen && !inputHostsSlashMenu ? /* @__PURE__ */ jsxDEV32("box", {
|
|
13665
14655
|
position: "absolute",
|
|
13666
14656
|
top: 1,
|
|
13667
14657
|
left: 2,
|
|
13668
14658
|
right: 2,
|
|
13669
14659
|
zIndex: 20,
|
|
13670
|
-
children: /* @__PURE__ */
|
|
14660
|
+
children: /* @__PURE__ */ jsxDEV32(SlashPageMenu, {
|
|
13671
14661
|
query: slashMenuQuery,
|
|
13672
14662
|
selectedIndex: selectedSlashRouteIndex,
|
|
13673
14663
|
routes: filteredSlashRoutes
|
|
13674
14664
|
}, undefined, false, undefined, this)
|
|
13675
14665
|
}, undefined, false, undefined, this) : null,
|
|
13676
|
-
helpOpen ? /* @__PURE__ */
|
|
14666
|
+
helpOpen ? /* @__PURE__ */ jsxDEV32("box", {
|
|
13677
14667
|
position: "absolute",
|
|
13678
14668
|
top: 1,
|
|
13679
14669
|
left: 4,
|
|
13680
14670
|
right: 4,
|
|
13681
14671
|
zIndex: 30,
|
|
13682
|
-
children: /* @__PURE__ */
|
|
14672
|
+
children: /* @__PURE__ */ jsxDEV32(HelpOverlay, {}, undefined, false, undefined, this)
|
|
13683
14673
|
}, undefined, false, undefined, this) : null
|
|
13684
14674
|
]
|
|
13685
14675
|
}, undefined, true, undefined, this),
|
|
13686
|
-
/* @__PURE__ */
|
|
14676
|
+
/* @__PURE__ */ jsxDEV32("box", {
|
|
13687
14677
|
flexDirection: "row",
|
|
13688
14678
|
justifyContent: "center",
|
|
13689
14679
|
gap: 2,
|
|
@@ -13692,19 +14682,19 @@ function AppContent() {
|
|
|
13692
14682
|
borderStyle: "single",
|
|
13693
14683
|
border: ["top"],
|
|
13694
14684
|
borderColor: cliTheme.borders.default,
|
|
13695
|
-
children: /* @__PURE__ */
|
|
13696
|
-
fg: cliTheme.text.muted,
|
|
13697
|
-
children: getFooterStatus()
|
|
14685
|
+
children: /* @__PURE__ */ jsxDEV32("text", {
|
|
14686
|
+
fg: ctrlCNotice ? cliTheme.semantic.warning : cliTheme.text.muted,
|
|
14687
|
+
children: ctrlCNotice ?? getFooterStatus()
|
|
13698
14688
|
}, undefined, false, undefined, this)
|
|
13699
14689
|
}, undefined, false, undefined, this)
|
|
13700
14690
|
]
|
|
13701
14691
|
}, undefined, true, undefined, this);
|
|
13702
14692
|
}
|
|
13703
14693
|
function App() {
|
|
13704
|
-
return /* @__PURE__ */
|
|
14694
|
+
return /* @__PURE__ */ jsxDEV32(MemoryRouter, {
|
|
13705
14695
|
initialEntries: ["/"],
|
|
13706
|
-
children: /* @__PURE__ */
|
|
13707
|
-
children: /* @__PURE__ */
|
|
14696
|
+
children: /* @__PURE__ */ jsxDEV32(AppStateProvider, {
|
|
14697
|
+
children: /* @__PURE__ */ jsxDEV32(AppContent, {}, undefined, false, undefined, this)
|
|
13708
14698
|
}, undefined, false, undefined, this)
|
|
13709
14699
|
}, undefined, false, undefined, this);
|
|
13710
14700
|
}
|
|
@@ -13720,16 +14710,18 @@ var init_app = __esm(() => {
|
|
|
13720
14710
|
init_diagnostics_screen();
|
|
13721
14711
|
init_home_screen();
|
|
13722
14712
|
init_model_screen();
|
|
14713
|
+
init_model_select_screen();
|
|
13723
14714
|
init_onboarding_screen();
|
|
13724
14715
|
init_session_list_screen();
|
|
13725
14716
|
init_app_state();
|
|
13726
14717
|
init_use_config_badge();
|
|
13727
14718
|
init_cli_theme();
|
|
14719
|
+
init_clipboard();
|
|
13728
14720
|
});
|
|
13729
14721
|
|
|
13730
14722
|
// apps/cli/src/index.tsx
|
|
13731
14723
|
init_src();
|
|
13732
|
-
import { jsxDEV as
|
|
14724
|
+
import { jsxDEV as jsxDEV33 } from "@opentui/react/jsx-dev-runtime";
|
|
13733
14725
|
var cliArgs = Bun.argv.slice(2);
|
|
13734
14726
|
if (cliArgs.includes("--version") || cliArgs.includes("-v")) {
|
|
13735
14727
|
console.log(`${productName} v${lightcodeVersion}`);
|
|
@@ -13737,11 +14729,17 @@ if (cliArgs.includes("--version") || cliArgs.includes("-v")) {
|
|
|
13737
14729
|
}
|
|
13738
14730
|
var { ensureServerRunning: ensureServerRunning2 } = await Promise.resolve().then(() => (init_server_launcher(), exports_server_launcher));
|
|
13739
14731
|
var serverLaunch = await ensureServerRunning2();
|
|
14732
|
+
if (serverLaunch.error) {
|
|
14733
|
+
console.error(`
|
|
14734
|
+
${serverLaunch.error}
|
|
14735
|
+
`);
|
|
14736
|
+
process.exit(1);
|
|
14737
|
+
}
|
|
13740
14738
|
var { createCliRenderer } = await import("@opentui/core");
|
|
13741
14739
|
var { createRoot } = await import("@opentui/react");
|
|
13742
14740
|
var { App: App2 } = await Promise.resolve().then(() => (init_app(), exports_app));
|
|
13743
14741
|
var renderer = await createCliRenderer({
|
|
13744
|
-
exitOnCtrlC:
|
|
14742
|
+
exitOnCtrlC: false
|
|
13745
14743
|
});
|
|
13746
14744
|
if (serverLaunch.ownedProcess) {
|
|
13747
14745
|
const ownedProcess = serverLaunch.ownedProcess;
|
|
@@ -13751,4 +14749,4 @@ if (serverLaunch.ownedProcess) {
|
|
|
13751
14749
|
} catch {}
|
|
13752
14750
|
});
|
|
13753
14751
|
}
|
|
13754
|
-
createRoot(renderer).render(/* @__PURE__ */
|
|
14752
|
+
createRoot(renderer).render(/* @__PURE__ */ jsxDEV33(App2, {}, undefined, false, undefined, this));
|