@kmugalkhod/lightcode 0.1.3 → 0.2.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 +1350 -503
- package/package.json +4 -2
- package/server.js +917 -181
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.2.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;
|
|
@@ -4057,18 +4185,18 @@ var init_context = __esm(() => {
|
|
|
4057
4185
|
});
|
|
4058
4186
|
|
|
4059
4187
|
// packages/ai/src/config/lightcode-config.ts
|
|
4060
|
-
import { existsSync as
|
|
4188
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
4061
4189
|
import os2 from "os";
|
|
4062
|
-
import
|
|
4190
|
+
import path5 from "path";
|
|
4063
4191
|
import { z as z28 } from "zod";
|
|
4064
4192
|
function getDefaultUserConfigPath(env) {
|
|
4065
4193
|
if (env.LIGHTCODE_USER_CONFIG) {
|
|
4066
4194
|
return env.LIGHTCODE_USER_CONFIG;
|
|
4067
4195
|
}
|
|
4068
|
-
return
|
|
4196
|
+
return path5.join(os2.homedir(), ".lightcode", "settings.json");
|
|
4069
4197
|
}
|
|
4070
4198
|
function readConfigFile(scope, configPath) {
|
|
4071
|
-
if (!
|
|
4199
|
+
if (!existsSync4(configPath)) {
|
|
4072
4200
|
return {
|
|
4073
4201
|
config: {},
|
|
4074
4202
|
file: {
|
|
@@ -4159,6 +4287,7 @@ function readEnvConfig(env) {
|
|
|
4159
4287
|
permissionMode: env.LIGHTCODE_PERMISSION_MODE,
|
|
4160
4288
|
maxOutputTokens: parseNumberEnv(env.LIGHTCODE_MAX_OUTPUT_TOKENS, "LIGHTCODE_MAX_OUTPUT_TOKENS"),
|
|
4161
4289
|
maxSteps: parseNumberEnv(env.LIGHTCODE_MAX_STEPS, "LIGHTCODE_MAX_STEPS"),
|
|
4290
|
+
maxRetries: parseNumberEnv(env.LIGHTCODE_MAX_RETRIES, "LIGHTCODE_MAX_RETRIES"),
|
|
4162
4291
|
context: Object.keys(compactContextConfig).length > 0 ? compactContextConfig : undefined
|
|
4163
4292
|
};
|
|
4164
4293
|
const compactConfig = Object.fromEntries(Object.entries(rawConfig).filter(([, value]) => value !== undefined));
|
|
@@ -4186,10 +4315,30 @@ function mergeConfig(...configs) {
|
|
|
4186
4315
|
allowedTools: config2.allowedTools ?? mergedConfig.allowedTools
|
|
4187
4316
|
}), {});
|
|
4188
4317
|
}
|
|
4318
|
+
function updateUserSettings(update, env = process.env) {
|
|
4319
|
+
const configPath = getDefaultUserConfigPath(env);
|
|
4320
|
+
const existing = readConfigFile("user", configPath).config;
|
|
4321
|
+
const merged = { ...existing };
|
|
4322
|
+
for (const [key, value] of Object.entries(update)) {
|
|
4323
|
+
if (value === undefined || value === null) {
|
|
4324
|
+
delete merged[key];
|
|
4325
|
+
} else {
|
|
4326
|
+
Reflect.set(merged, key, value);
|
|
4327
|
+
}
|
|
4328
|
+
}
|
|
4329
|
+
const parsed = lightcodeConfigSchema.safeParse(merged);
|
|
4330
|
+
if (!parsed.success) {
|
|
4331
|
+
throw new LightcodeConfigError(`Invalid settings update: ${parsed.error.message}`);
|
|
4332
|
+
}
|
|
4333
|
+
mkdirSync4(path5.dirname(configPath), { recursive: true });
|
|
4334
|
+
writeFileSync2(configPath, `${JSON.stringify(parsed.data, null, 2)}
|
|
4335
|
+
`, "utf8");
|
|
4336
|
+
return { path: configPath, config: parsed.data };
|
|
4337
|
+
}
|
|
4189
4338
|
function loadLightcodeConfig({
|
|
4190
4339
|
cwd = process.cwd(),
|
|
4191
4340
|
env = process.env,
|
|
4192
|
-
projectConfigPath =
|
|
4341
|
+
projectConfigPath = path5.join(cwd, ".lightcode", "settings.json"),
|
|
4193
4342
|
userConfigPath = getDefaultUserConfigPath(env)
|
|
4194
4343
|
} = {}) {
|
|
4195
4344
|
const userConfig = readConfigFile("user", userConfigPath);
|
|
@@ -4240,7 +4389,7 @@ var init_lightcode_config = __esm(() => {
|
|
|
4240
4389
|
enabled: true,
|
|
4241
4390
|
maxAutoContinues: 50,
|
|
4242
4391
|
maxErrorRetries: 5,
|
|
4243
|
-
stallTimeoutSeconds:
|
|
4392
|
+
stallTimeoutSeconds: 180
|
|
4244
4393
|
};
|
|
4245
4394
|
lightcodeConfigSchema = z28.object({
|
|
4246
4395
|
provider: lightcodeProviderSchema.optional(),
|
|
@@ -4255,6 +4404,7 @@ var init_lightcode_config = __esm(() => {
|
|
|
4255
4404
|
context: contextOptimizerConfigSchema.optional(),
|
|
4256
4405
|
maxOutputTokens: z28.number().int().min(1).max(200000).optional(),
|
|
4257
4406
|
maxSteps: z28.number().int().min(1).max(100).optional(),
|
|
4407
|
+
maxRetries: z28.number().int().min(0).max(10).optional(),
|
|
4258
4408
|
autoContinue: autoContinueConfigSchema.optional()
|
|
4259
4409
|
}).strict();
|
|
4260
4410
|
lightcodeConfigDefaults = {
|
|
@@ -4263,6 +4413,7 @@ var init_lightcode_config = __esm(() => {
|
|
|
4263
4413
|
context: defaultContextOptimizerConfig,
|
|
4264
4414
|
maxOutputTokens: 32768,
|
|
4265
4415
|
maxSteps: 30,
|
|
4416
|
+
maxRetries: 5,
|
|
4266
4417
|
autoContinue: defaultAutoContinueConfig
|
|
4267
4418
|
};
|
|
4268
4419
|
loadedConfigFileSchema = z28.object({
|
|
@@ -4277,6 +4428,7 @@ var init_lightcode_config = __esm(() => {
|
|
|
4277
4428
|
context: resolvedContextOptimizerConfigSchema,
|
|
4278
4429
|
maxOutputTokens: z28.number().int().min(1).max(200000),
|
|
4279
4430
|
maxSteps: z28.number().int().min(1).max(100),
|
|
4431
|
+
maxRetries: z28.number().int().min(0).max(10),
|
|
4280
4432
|
autoContinue: resolvedAutoContinueConfigSchema
|
|
4281
4433
|
});
|
|
4282
4434
|
lightcodeConfigLoadResultSchema = z28.object({
|
|
@@ -5184,27 +5336,27 @@ var init_schema16 = __esm(() => {
|
|
|
5184
5336
|
});
|
|
5185
5337
|
|
|
5186
5338
|
// packages/ai/src/plugins/runtime.ts
|
|
5187
|
-
import { existsSync as
|
|
5339
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, readdirSync as readdirSync2 } from "fs";
|
|
5188
5340
|
import os3 from "os";
|
|
5189
|
-
import
|
|
5341
|
+
import path6 from "path";
|
|
5190
5342
|
function pluginRoots(cwd) {
|
|
5191
5343
|
return [
|
|
5192
|
-
|
|
5193
|
-
|
|
5344
|
+
path6.join(cwd, ".lightcode", "plugins"),
|
|
5345
|
+
path6.join(os3.homedir(), ".lightcode", "plugins")
|
|
5194
5346
|
];
|
|
5195
5347
|
}
|
|
5196
5348
|
function listPlugins({ cwd = process.cwd() } = {}) {
|
|
5197
5349
|
const plugins = [];
|
|
5198
5350
|
for (const root of pluginRoots(cwd)) {
|
|
5199
|
-
if (!
|
|
5351
|
+
if (!existsSync5(root)) {
|
|
5200
5352
|
continue;
|
|
5201
5353
|
}
|
|
5202
|
-
for (const entry of
|
|
5354
|
+
for (const entry of readdirSync2(root, { withFileTypes: true })) {
|
|
5203
5355
|
if (!entry.isDirectory()) {
|
|
5204
5356
|
continue;
|
|
5205
5357
|
}
|
|
5206
|
-
const manifestPath =
|
|
5207
|
-
if (!
|
|
5358
|
+
const manifestPath = path6.join(root, entry.name, "plugin.json");
|
|
5359
|
+
if (!existsSync5(manifestPath)) {
|
|
5208
5360
|
continue;
|
|
5209
5361
|
}
|
|
5210
5362
|
const manifest = pluginManifestSchema.parse(JSON.parse(readFileSync3(manifestPath, "utf8")));
|
|
@@ -5243,7 +5395,7 @@ async function runPluginHooks({
|
|
|
5243
5395
|
for (const hook of manifest.hooks.filter((candidate) => candidate.event === event)) {
|
|
5244
5396
|
hooksRun += 1;
|
|
5245
5397
|
const child = Bun.spawn([hook.command, ...hook.args], {
|
|
5246
|
-
cwd:
|
|
5398
|
+
cwd: path6.dirname(plugin.path),
|
|
5247
5399
|
stdout: "pipe",
|
|
5248
5400
|
stderr: "pipe"
|
|
5249
5401
|
});
|
|
@@ -5283,14 +5435,14 @@ var init_runtime2 = __esm(() => {
|
|
|
5283
5435
|
});
|
|
5284
5436
|
|
|
5285
5437
|
// packages/ai/src/skills/runtime.ts
|
|
5286
|
-
import { existsSync as
|
|
5438
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, readdirSync as readdirSync3, statSync } from "fs";
|
|
5287
5439
|
import os4 from "os";
|
|
5288
|
-
import
|
|
5440
|
+
import path7 from "path";
|
|
5289
5441
|
function defaultSkillRoots(cwd) {
|
|
5290
5442
|
return [
|
|
5291
|
-
{ source: "project", path:
|
|
5292
|
-
{ source: "project", path:
|
|
5293
|
-
{ source: "user", path:
|
|
5443
|
+
{ source: "project", path: path7.join(cwd, ".lightcode", "skills") },
|
|
5444
|
+
{ source: "project", path: path7.join(cwd, ".agents", "skills") },
|
|
5445
|
+
{ source: "user", path: path7.join(os4.homedir(), ".lightcode", "skills") }
|
|
5294
5446
|
];
|
|
5295
5447
|
}
|
|
5296
5448
|
function normalizeSkillName(value) {
|
|
@@ -5312,7 +5464,7 @@ function parseBasicFrontmatter(content) {
|
|
|
5312
5464
|
]));
|
|
5313
5465
|
}
|
|
5314
5466
|
function findSkillFiles(root) {
|
|
5315
|
-
if (!
|
|
5467
|
+
if (!existsSync6(root.path)) {
|
|
5316
5468
|
return [];
|
|
5317
5469
|
}
|
|
5318
5470
|
const files = [];
|
|
@@ -5320,8 +5472,8 @@ function findSkillFiles(root) {
|
|
|
5320
5472
|
if (depth > 4) {
|
|
5321
5473
|
return;
|
|
5322
5474
|
}
|
|
5323
|
-
for (const entry of
|
|
5324
|
-
const entryPath =
|
|
5475
|
+
for (const entry of readdirSync3(directory)) {
|
|
5476
|
+
const entryPath = path7.join(directory, entry);
|
|
5325
5477
|
const stat = statSync(entryPath);
|
|
5326
5478
|
if (stat.isDirectory()) {
|
|
5327
5479
|
visit(entryPath, depth + 1);
|
|
@@ -5342,7 +5494,7 @@ function listSkills({
|
|
|
5342
5494
|
for (const skillPath of findSkillFiles(root)) {
|
|
5343
5495
|
const content = readFileSync4(skillPath, "utf8");
|
|
5344
5496
|
const frontmatter = parseBasicFrontmatter(content);
|
|
5345
|
-
const fallbackName =
|
|
5497
|
+
const fallbackName = path7.basename(path7.dirname(skillPath));
|
|
5346
5498
|
const name = normalizeSkillName(frontmatter.name ?? fallbackName);
|
|
5347
5499
|
if (!name || seen.has(name)) {
|
|
5348
5500
|
continue;
|
|
@@ -5417,6 +5569,7 @@ var init_subagent_schemas = __esm(() => {
|
|
|
5417
5569
|
// packages/ai/src/index.ts
|
|
5418
5570
|
var init_src2 = __esm(() => {
|
|
5419
5571
|
init_agent_tools();
|
|
5572
|
+
init_chat_error();
|
|
5420
5573
|
init_chat_interaction_schemas();
|
|
5421
5574
|
init_plan_block();
|
|
5422
5575
|
init_chat_schemas();
|
|
@@ -5453,8 +5606,27 @@ var init_client = __esm(() => {
|
|
|
5453
5606
|
client = hc(apiBaseUrl);
|
|
5454
5607
|
});
|
|
5455
5608
|
|
|
5609
|
+
// apps/cli/src/utils/markdown-code.ts
|
|
5610
|
+
function extractCodeBlocks(text) {
|
|
5611
|
+
const blocks = [];
|
|
5612
|
+
FENCE_RE.lastIndex = 0;
|
|
5613
|
+
let match;
|
|
5614
|
+
while ((match = FENCE_RE.exec(text)) !== null) {
|
|
5615
|
+
const lang = match[1]?.trim();
|
|
5616
|
+
const code = (match[2] ?? "").replace(/\r?\n$/, "");
|
|
5617
|
+
if (code.trim()) {
|
|
5618
|
+
blocks.push({ lang: lang ? lang : undefined, code });
|
|
5619
|
+
}
|
|
5620
|
+
}
|
|
5621
|
+
return blocks;
|
|
5622
|
+
}
|
|
5623
|
+
var FENCE_RE;
|
|
5624
|
+
var init_markdown_code = __esm(() => {
|
|
5625
|
+
FENCE_RE = /```([^\n`]*)\r?\n([\s\S]*?)```/g;
|
|
5626
|
+
});
|
|
5627
|
+
|
|
5456
5628
|
// apps/cli/src/commands/export-session-markdown.ts
|
|
5457
|
-
import
|
|
5629
|
+
import path8 from "path";
|
|
5458
5630
|
function escapeMarkdown(text) {
|
|
5459
5631
|
return text.replace(/```/g, "\\`\\`\\`").replace(/`/g, "\\`").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/__([^_]+)__/g, "$1").replace(/_([^_]+)_/g, "$1");
|
|
5460
5632
|
}
|
|
@@ -5571,33 +5743,33 @@ function getExportDirectory() {
|
|
|
5571
5743
|
return process.cwd();
|
|
5572
5744
|
}
|
|
5573
5745
|
function getExportPath(sessionTitle, sessionId) {
|
|
5574
|
-
return
|
|
5746
|
+
return path8.join(getExportDirectory(), generateExportFilename(sessionTitle, sessionId));
|
|
5575
5747
|
}
|
|
5576
5748
|
var init_export_session_markdown = () => {};
|
|
5577
5749
|
|
|
5578
5750
|
// packages/ai/src/common/resolve-within-workspace.ts
|
|
5579
|
-
import
|
|
5751
|
+
import path9 from "path";
|
|
5580
5752
|
import {
|
|
5581
|
-
existsSync as
|
|
5753
|
+
existsSync as existsSync7,
|
|
5582
5754
|
lstatSync,
|
|
5583
5755
|
realpathSync,
|
|
5584
5756
|
statSync as statSync2
|
|
5585
5757
|
} from "fs";
|
|
5586
5758
|
function stripTrailingSeparator(value) {
|
|
5587
|
-
const parsed =
|
|
5759
|
+
const parsed = path9.parse(value);
|
|
5588
5760
|
if (value === parsed.root) {
|
|
5589
5761
|
return value;
|
|
5590
5762
|
}
|
|
5591
5763
|
return value.replace(/[\\/]+$/, "");
|
|
5592
5764
|
}
|
|
5593
5765
|
function normalizeForComparison(value) {
|
|
5594
|
-
const normalized = stripTrailingSeparator(
|
|
5766
|
+
const normalized = stripTrailingSeparator(path9.resolve(value));
|
|
5595
5767
|
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
5596
5768
|
}
|
|
5597
5769
|
function isWithinWorkspace(absolutePath, context2) {
|
|
5598
5770
|
const workspace = normalizeForComparison(context2.root);
|
|
5599
5771
|
const target = normalizeForComparison(absolutePath);
|
|
5600
|
-
return target === workspace || target.startsWith(`${workspace}${
|
|
5772
|
+
return target === workspace || target.startsWith(`${workspace}${path9.sep}`);
|
|
5601
5773
|
}
|
|
5602
5774
|
function assertWithinWorkspace(absolutePath, context2, input) {
|
|
5603
5775
|
if (!isWithinWorkspace(absolutePath, context2)) {
|
|
@@ -5612,17 +5784,17 @@ function getExistingRealPath(absolutePath) {
|
|
|
5612
5784
|
}
|
|
5613
5785
|
}
|
|
5614
5786
|
function findNearestExistingParent(absolutePath, context2, input) {
|
|
5615
|
-
let currentPath =
|
|
5787
|
+
let currentPath = path9.dirname(absolutePath);
|
|
5616
5788
|
while (true) {
|
|
5617
5789
|
assertWithinWorkspace(currentPath, context2, input);
|
|
5618
|
-
if (
|
|
5790
|
+
if (existsSync7(currentPath)) {
|
|
5619
5791
|
const realParentPath = getExistingRealPath(currentPath);
|
|
5620
5792
|
if (!realParentPath) {
|
|
5621
5793
|
throw new Error(`Unable to resolve existing parent for path: ${input}`);
|
|
5622
5794
|
}
|
|
5623
5795
|
return realParentPath;
|
|
5624
5796
|
}
|
|
5625
|
-
const parentPath =
|
|
5797
|
+
const parentPath = path9.dirname(currentPath);
|
|
5626
5798
|
if (parentPath === currentPath) {
|
|
5627
5799
|
throw new Error(`Unable to find an existing workspace parent for path: ${input}`);
|
|
5628
5800
|
}
|
|
@@ -5642,7 +5814,7 @@ function getDefaultWorkspaceContext() {
|
|
|
5642
5814
|
}
|
|
5643
5815
|
function resolveWithinWorkspace(input, options = {}) {
|
|
5644
5816
|
const context2 = options.context ?? defaultWorkspaceContext;
|
|
5645
|
-
const resolved =
|
|
5817
|
+
const resolved = path9.resolve(context2.root, input);
|
|
5646
5818
|
assertWithinWorkspace(resolved, context2, input);
|
|
5647
5819
|
const realPath = getExistingRealPath(resolved);
|
|
5648
5820
|
if (realPath) {
|
|
@@ -5667,13 +5839,13 @@ function resolveWithinWorkspace(input, options = {}) {
|
|
|
5667
5839
|
return resolved;
|
|
5668
5840
|
}
|
|
5669
5841
|
function toWorkspaceRelativePath(absolutePath, context2 = defaultWorkspaceContext) {
|
|
5670
|
-
const resolved =
|
|
5842
|
+
const resolved = path9.resolve(absolutePath);
|
|
5671
5843
|
assertWithinWorkspace(resolved, context2, absolutePath);
|
|
5672
|
-
const relativePath =
|
|
5844
|
+
const relativePath = path9.relative(context2.root, resolved);
|
|
5673
5845
|
if (relativePath === "") {
|
|
5674
5846
|
return ".";
|
|
5675
5847
|
}
|
|
5676
|
-
return relativePath.split(
|
|
5848
|
+
return relativePath.split(path9.sep).join("/");
|
|
5677
5849
|
}
|
|
5678
5850
|
var nativeRealpathSync, defaultWorkspaceContext, WORKSPACE;
|
|
5679
5851
|
var init_resolve_within_workspace = __esm(() => {
|
|
@@ -5781,16 +5953,16 @@ var init_runtime4 = __esm(() => {
|
|
|
5781
5953
|
// packages/ai/src/checkpoints/runtime.ts
|
|
5782
5954
|
import { createHash } from "crypto";
|
|
5783
5955
|
import { promises as fs } from "fs";
|
|
5784
|
-
import
|
|
5956
|
+
import path10 from "path";
|
|
5785
5957
|
import { z as z32 } from "zod";
|
|
5786
5958
|
function safeSessionDirName(sessionId) {
|
|
5787
5959
|
return sessionId.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 120);
|
|
5788
5960
|
}
|
|
5789
5961
|
function getCheckpointsDir(sessionId) {
|
|
5790
|
-
return
|
|
5962
|
+
return path10.join(getLightcodeDataDir(), "checkpoints", safeSessionDirName(sessionId));
|
|
5791
5963
|
}
|
|
5792
5964
|
function getManifestPath(sessionId) {
|
|
5793
|
-
return
|
|
5965
|
+
return path10.join(getCheckpointsDir(sessionId), "manifest.json");
|
|
5794
5966
|
}
|
|
5795
5967
|
async function loadManifest(sessionId) {
|
|
5796
5968
|
try {
|
|
@@ -5803,7 +5975,7 @@ async function loadManifest(sessionId) {
|
|
|
5803
5975
|
}
|
|
5804
5976
|
async function saveManifest(sessionId, manifest) {
|
|
5805
5977
|
const manifestPath = getManifestPath(sessionId);
|
|
5806
|
-
await fs.mkdir(
|
|
5978
|
+
await fs.mkdir(path10.dirname(manifestPath), { recursive: true });
|
|
5807
5979
|
await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
5808
5980
|
`, "utf8");
|
|
5809
5981
|
}
|
|
@@ -5828,8 +6000,8 @@ async function recordFileCheckpoint({
|
|
|
5828
6000
|
if (previousContent !== null) {
|
|
5829
6001
|
const pathHash = createHash("sha1").update(workspaceRelativePath).digest("hex").slice(0, 12);
|
|
5830
6002
|
snapshotFile = `${turnKey}-${pathHash}.snap`;
|
|
5831
|
-
const snapshotPath =
|
|
5832
|
-
await fs.mkdir(
|
|
6003
|
+
const snapshotPath = path10.join(getCheckpointsDir(sessionId), snapshotFile);
|
|
6004
|
+
await fs.mkdir(path10.dirname(snapshotPath), { recursive: true });
|
|
5833
6005
|
await fs.writeFile(snapshotPath, previousContent, "utf8");
|
|
5834
6006
|
}
|
|
5835
6007
|
turn.files.push({ workspaceRelativePath, absolutePath, snapshotFile });
|
|
@@ -5849,9 +6021,9 @@ async function undoLastTurn({
|
|
|
5849
6021
|
if (file.snapshotFile === null) {
|
|
5850
6022
|
await fs.rm(file.absolutePath, { force: true });
|
|
5851
6023
|
} else {
|
|
5852
|
-
const snapshotPath =
|
|
6024
|
+
const snapshotPath = path10.join(getCheckpointsDir(sessionId), file.snapshotFile);
|
|
5853
6025
|
const snapshotContent = await fs.readFile(snapshotPath, "utf8");
|
|
5854
|
-
await fs.mkdir(
|
|
6026
|
+
await fs.mkdir(path10.dirname(file.absolutePath), { recursive: true });
|
|
5855
6027
|
await fs.writeFile(file.absolutePath, snapshotContent, "utf8");
|
|
5856
6028
|
await fs.rm(snapshotPath, { force: true });
|
|
5857
6029
|
}
|
|
@@ -5963,7 +6135,7 @@ var init_runtime6 = __esm(() => {
|
|
|
5963
6135
|
// packages/ai/src/grep/runtime.ts
|
|
5964
6136
|
import { execFile } from "child_process";
|
|
5965
6137
|
import { readdir, readFile, stat } from "fs/promises";
|
|
5966
|
-
import
|
|
6138
|
+
import path11 from "path";
|
|
5967
6139
|
import { promisify as promisify2 } from "util";
|
|
5968
6140
|
function isRecord6(value) {
|
|
5969
6141
|
return typeof value === "object" && value !== null;
|
|
@@ -6020,7 +6192,7 @@ function parseRgMatches(stdout, maxResults, workspaceContext) {
|
|
|
6020
6192
|
if (!event) {
|
|
6021
6193
|
continue;
|
|
6022
6194
|
}
|
|
6023
|
-
const absolutePath =
|
|
6195
|
+
const absolutePath = path11.isAbsolute(event.rawPath) ? event.rawPath : path11.resolve(workspaceContext.root, event.rawPath);
|
|
6024
6196
|
let relativePath;
|
|
6025
6197
|
try {
|
|
6026
6198
|
relativePath = toWorkspaceRelativePath(absolutePath, workspaceContext);
|
|
@@ -6080,7 +6252,7 @@ async function collectSearchFiles(searchRootPath) {
|
|
|
6080
6252
|
if (entry.isDirectory() && fallbackIgnoredDirectories.has(entry.name)) {
|
|
6081
6253
|
continue;
|
|
6082
6254
|
}
|
|
6083
|
-
const entryPath =
|
|
6255
|
+
const entryPath = path11.join(searchRootPath, entry.name);
|
|
6084
6256
|
if (entry.isDirectory()) {
|
|
6085
6257
|
files.push(...await collectSearchFiles(entryPath));
|
|
6086
6258
|
continue;
|
|
@@ -6205,7 +6377,7 @@ var init_runtime7 = __esm(() => {
|
|
|
6205
6377
|
|
|
6206
6378
|
// packages/ai/src/glob-search/runtime.ts
|
|
6207
6379
|
import { lstat, readdir as readdir2, stat as stat2 } from "fs/promises";
|
|
6208
|
-
import
|
|
6380
|
+
import path12 from "path";
|
|
6209
6381
|
function normalizeGlobPath(value) {
|
|
6210
6382
|
return value.replaceAll("\\", "/").replace(/^\.\//, "");
|
|
6211
6383
|
}
|
|
@@ -6263,7 +6435,7 @@ function entryTypeFromStats(stats) {
|
|
|
6263
6435
|
return "other";
|
|
6264
6436
|
}
|
|
6265
6437
|
async function collectEntry(absolutePath, searchRoot, parsedInput, matcher, workspaceContext) {
|
|
6266
|
-
const relativeToSearchRoot = normalizeGlobPath(
|
|
6438
|
+
const relativeToSearchRoot = normalizeGlobPath(path12.relative(searchRoot, absolutePath));
|
|
6267
6439
|
const comparablePath = relativeToSearchRoot === "" ? "." : relativeToSearchRoot;
|
|
6268
6440
|
if (!parsedInput.includeHidden && isHiddenPath(comparablePath)) {
|
|
6269
6441
|
return null;
|
|
@@ -6293,7 +6465,7 @@ async function executeGlobSearch(input, workspaceContext = getDefaultWorkspaceCo
|
|
|
6293
6465
|
const matches = [];
|
|
6294
6466
|
let truncated = false;
|
|
6295
6467
|
if (searchRootStats.isFile()) {
|
|
6296
|
-
const match = await collectEntry(searchRoot,
|
|
6468
|
+
const match = await collectEntry(searchRoot, path12.dirname(searchRoot), parsedInput, matcher, workspaceContext);
|
|
6297
6469
|
if (match) {
|
|
6298
6470
|
matches.push(match);
|
|
6299
6471
|
}
|
|
@@ -6314,7 +6486,7 @@ async function executeGlobSearch(input, workspaceContext = getDefaultWorkspaceCo
|
|
|
6314
6486
|
if (directoryEntry.isDirectory() && shouldSkipDirectory(directoryEntry.name, parsedInput.includeHidden)) {
|
|
6315
6487
|
continue;
|
|
6316
6488
|
}
|
|
6317
|
-
const absoluteEntryPath =
|
|
6489
|
+
const absoluteEntryPath = path12.join(currentDirectory, directoryEntry.name);
|
|
6318
6490
|
const match = await collectEntry(absoluteEntryPath, searchRoot, parsedInput, matcher, workspaceContext);
|
|
6319
6491
|
if (match) {
|
|
6320
6492
|
matches.push(match);
|
|
@@ -6600,7 +6772,7 @@ var init_runtime9 = __esm(() => {
|
|
|
6600
6772
|
|
|
6601
6773
|
// packages/ai/src/list-files/runtime.ts
|
|
6602
6774
|
import { promises as fs3 } from "fs";
|
|
6603
|
-
import
|
|
6775
|
+
import path13 from "path";
|
|
6604
6776
|
function entryTypeFromStats2(stats) {
|
|
6605
6777
|
if (stats.isFile()) {
|
|
6606
6778
|
return "file";
|
|
@@ -6646,7 +6818,7 @@ async function executeListFiles(input, workspaceContext = getDefaultWorkspaceCon
|
|
|
6646
6818
|
if (!parsedInput.includeHidden && isHidden) {
|
|
6647
6819
|
continue;
|
|
6648
6820
|
}
|
|
6649
|
-
const absoluteEntryPath =
|
|
6821
|
+
const absoluteEntryPath = path13.join(currentDirectoryPath, dirEntry.name);
|
|
6650
6822
|
const relativeEntryPath = toWorkspaceRelativePath(absoluteEntryPath, workspaceContext);
|
|
6651
6823
|
const entryStats = await fs3.lstat(absoluteEntryPath);
|
|
6652
6824
|
const entryType = entryTypeFromStats2(entryStats);
|
|
@@ -6724,7 +6896,7 @@ var init_runtime11 = __esm(() => {
|
|
|
6724
6896
|
|
|
6725
6897
|
// packages/ai/src/todo-write/runtime.ts
|
|
6726
6898
|
import { mkdir, readFile as readFile2, writeFile } from "fs/promises";
|
|
6727
|
-
import
|
|
6899
|
+
import path14 from "path";
|
|
6728
6900
|
import { z as z33 } from "zod";
|
|
6729
6901
|
function safeTodoSessionId(sessionId) {
|
|
6730
6902
|
const trimmed = sessionId?.trim();
|
|
@@ -6734,7 +6906,7 @@ function safeTodoSessionId(sessionId) {
|
|
|
6734
6906
|
return trimmed.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 120);
|
|
6735
6907
|
}
|
|
6736
6908
|
function getTodoFilePath(sessionId, workspaceContext) {
|
|
6737
|
-
return resolveWithinWorkspace(
|
|
6909
|
+
return resolveWithinWorkspace(path14.join(".lightcode", "todos", `${safeTodoSessionId(sessionId)}.json`), {
|
|
6738
6910
|
context: workspaceContext,
|
|
6739
6911
|
allowMissing: true
|
|
6740
6912
|
});
|
|
@@ -6770,7 +6942,7 @@ async function executeTodoWrite(input, {
|
|
|
6770
6942
|
...todo,
|
|
6771
6943
|
id: todo.id ?? `todo-${index + 1}`
|
|
6772
6944
|
}));
|
|
6773
|
-
await mkdir(
|
|
6945
|
+
await mkdir(path14.dirname(todoFilePath), { recursive: true });
|
|
6774
6946
|
await writeFile(todoFilePath, JSON.stringify(todos, null, 2), "utf8");
|
|
6775
6947
|
return todoWriteOutputSchema.parse({
|
|
6776
6948
|
sessionId: safeTodoSessionId(sessionId),
|
|
@@ -7135,7 +7307,7 @@ var init_runtime15 = __esm(() => {
|
|
|
7135
7307
|
|
|
7136
7308
|
// packages/ai/src/write-file/runtime.ts
|
|
7137
7309
|
import { promises as fs5 } from "fs";
|
|
7138
|
-
import
|
|
7310
|
+
import path15 from "path";
|
|
7139
7311
|
async function executeWriteFile(input, workspaceContext = getDefaultWorkspaceContext(), editContext = {}) {
|
|
7140
7312
|
const parsedInput = writeFileInputSchema.parse(input);
|
|
7141
7313
|
const resolvedPath = resolveWithinWorkspace(parsedInput.path, {
|
|
@@ -7172,7 +7344,7 @@ async function executeWriteFile(input, workspaceContext = getDefaultWorkspaceCon
|
|
|
7172
7344
|
previousContent
|
|
7173
7345
|
});
|
|
7174
7346
|
}
|
|
7175
|
-
await fs5.mkdir(
|
|
7347
|
+
await fs5.mkdir(path15.dirname(resolvedPath), { recursive: true });
|
|
7176
7348
|
await fs5.writeFile(resolvedPath, parsedInput.content, "utf8");
|
|
7177
7349
|
const bytesWritten = Buffer.byteLength(parsedInput.content, "utf8");
|
|
7178
7350
|
return writeFileOutputSchema.parse({
|
|
@@ -7292,6 +7464,7 @@ __export(exports_runtime, {
|
|
|
7292
7464
|
xmlToolCallMiddleware: () => xmlToolCallMiddleware,
|
|
7293
7465
|
writeStoredCredentials: () => writeStoredCredentials,
|
|
7294
7466
|
withXmlToolCallSupport: () => withXmlToolCallSupport,
|
|
7467
|
+
updateUserSettings: () => updateUserSettings,
|
|
7295
7468
|
undoLastTurn: () => undoLastTurn,
|
|
7296
7469
|
truncateText: () => truncateText,
|
|
7297
7470
|
toolCallingDisciplineAddendum: () => toolCallingDisciplineAddendum,
|
|
@@ -7372,6 +7545,7 @@ __export(exports_runtime, {
|
|
|
7372
7545
|
permissionModeMeets: () => permissionModeMeets,
|
|
7373
7546
|
permissionDecisionSchema: () => permissionDecisionSchema,
|
|
7374
7547
|
parseCodingToolInput: () => parseCodingToolInput,
|
|
7548
|
+
parseChatStreamError: () => parseChatStreamError,
|
|
7375
7549
|
normalizeSandboxConfig: () => normalizeSandboxConfig,
|
|
7376
7550
|
normalizeContextOptimizerConfig: () => normalizeContextOptimizerConfig,
|
|
7377
7551
|
messageUsageMetadataSchema: () => messageUsageMetadataSchema,
|
|
@@ -7415,6 +7589,7 @@ __export(exports_runtime, {
|
|
|
7415
7589
|
getCodingAgentModeDefinition: () => getCodingAgentModeDefinition,
|
|
7416
7590
|
getActiveCodingToolsForPolicy: () => getActiveCodingToolsForPolicy,
|
|
7417
7591
|
formatPermissionDecision: () => formatPermissionDecision,
|
|
7592
|
+
formatChatStreamError: () => formatChatStreamError,
|
|
7418
7593
|
extractProposedPlanBlocks: () => extractProposedPlanBlocks,
|
|
7419
7594
|
extractLatestProposedPlan: () => extractLatestProposedPlan,
|
|
7420
7595
|
executeWriteFile: () => executeWriteFile,
|
|
@@ -7450,6 +7625,7 @@ __export(exports_runtime, {
|
|
|
7450
7625
|
diagnosticsDatabaseSchema: () => diagnosticsDatabaseSchema,
|
|
7451
7626
|
diagnosticStatusSchema: () => diagnosticStatusSchema,
|
|
7452
7627
|
diagnosticCheckSchema: () => diagnosticCheckSchema,
|
|
7628
|
+
describeChatStreamError: () => describeChatStreamError,
|
|
7453
7629
|
defaultSubagentTaskMode: () => defaultSubagentTaskMode,
|
|
7454
7630
|
defaultPermissionModeForCodingMode: () => defaultPermissionModeForCodingMode,
|
|
7455
7631
|
defaultContextOptimizerConfig: () => defaultContextOptimizerConfig,
|
|
@@ -7616,9 +7792,74 @@ async function runExportAction({
|
|
|
7616
7792
|
notify(`Export failed: ${error instanceof Error ? error.message : "unknown error"}`, "error");
|
|
7617
7793
|
}
|
|
7618
7794
|
}
|
|
7795
|
+
function latestAssistantText(messages) {
|
|
7796
|
+
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
7797
|
+
const message = messages[index];
|
|
7798
|
+
if (message?.role === "assistant") {
|
|
7799
|
+
const text = collectMessageText(message);
|
|
7800
|
+
if (text.trim()) {
|
|
7801
|
+
return text;
|
|
7802
|
+
}
|
|
7803
|
+
}
|
|
7804
|
+
}
|
|
7805
|
+
return null;
|
|
7806
|
+
}
|
|
7807
|
+
function conversationTranscript(messages) {
|
|
7808
|
+
return messages.filter((message) => message.role === "user" || message.role === "assistant").map((message) => {
|
|
7809
|
+
const text = collectMessageText(message);
|
|
7810
|
+
if (!text.trim()) {
|
|
7811
|
+
return null;
|
|
7812
|
+
}
|
|
7813
|
+
const label = message.role === "user" ? "You" : "Assistant";
|
|
7814
|
+
return `## ${label}
|
|
7815
|
+
|
|
7816
|
+
${text}`;
|
|
7817
|
+
}).filter((entry) => entry !== null).join(`
|
|
7818
|
+
|
|
7819
|
+
`);
|
|
7820
|
+
}
|
|
7821
|
+
async function runCopyAction({
|
|
7822
|
+
args,
|
|
7823
|
+
messages,
|
|
7824
|
+
notify,
|
|
7825
|
+
copyToClipboard
|
|
7826
|
+
}) {
|
|
7827
|
+
const scope = args.trim().toLowerCase() || "last";
|
|
7828
|
+
let payload = null;
|
|
7829
|
+
let label;
|
|
7830
|
+
if (scope === "all") {
|
|
7831
|
+
const transcript = conversationTranscript(messages);
|
|
7832
|
+
payload = transcript.trim() ? transcript : null;
|
|
7833
|
+
label = "conversation";
|
|
7834
|
+
} else if (scope === "code") {
|
|
7835
|
+
const lastText = latestAssistantText(messages);
|
|
7836
|
+
const blocks = lastText ? extractCodeBlocks(lastText) : [];
|
|
7837
|
+
payload = blocks.length > 0 ? blocks.map((block) => block.code).join(`
|
|
7838
|
+
|
|
7839
|
+
`) : null;
|
|
7840
|
+
label = blocks.length === 1 ? "code block" : "code blocks";
|
|
7841
|
+
} else if (scope === "last") {
|
|
7842
|
+
payload = latestAssistantText(messages);
|
|
7843
|
+
label = "last reply";
|
|
7844
|
+
} else {
|
|
7845
|
+
notify("Usage: /copy [last|code|all]", "error");
|
|
7846
|
+
return;
|
|
7847
|
+
}
|
|
7848
|
+
if (!payload) {
|
|
7849
|
+
notify(scope === "code" ? "No code blocks found in the last reply." : "Nothing to copy yet.", "error");
|
|
7850
|
+
return;
|
|
7851
|
+
}
|
|
7852
|
+
const copied = await copyToClipboard(payload);
|
|
7853
|
+
notify(copied ? `Copied ${label} to clipboard (${payload.length} chars).` : "Copy failed: clipboard unavailable in this terminal.", copied ? "info" : "error");
|
|
7854
|
+
}
|
|
7619
7855
|
function findChatSlashAction(text) {
|
|
7620
|
-
const
|
|
7621
|
-
return chatSlashActions.find((action) => action.shortcut ===
|
|
7856
|
+
const command = text.trim().split(/\s+/)[0]?.toLowerCase() ?? "";
|
|
7857
|
+
return chatSlashActions.find((action) => action.shortcut === command) ?? null;
|
|
7858
|
+
}
|
|
7859
|
+
function parseChatSlashArgs(text) {
|
|
7860
|
+
const trimmed = text.trim();
|
|
7861
|
+
const firstSpace = trimmed.search(/\s/);
|
|
7862
|
+
return firstSpace === -1 ? "" : trimmed.slice(firstSpace + 1).trim();
|
|
7622
7863
|
}
|
|
7623
7864
|
function getChatSlashActionById(id) {
|
|
7624
7865
|
return chatSlashActions.find((action) => action.id === id) ?? null;
|
|
@@ -7634,8 +7875,17 @@ var chatSlashActions;
|
|
|
7634
7875
|
var init_chat_slash_actions = __esm(() => {
|
|
7635
7876
|
init_src2();
|
|
7636
7877
|
init_client();
|
|
7878
|
+
init_markdown_code();
|
|
7637
7879
|
init_export_session_markdown();
|
|
7638
7880
|
chatSlashActions = [
|
|
7881
|
+
{
|
|
7882
|
+
kind: "chat-action",
|
|
7883
|
+
id: "copy",
|
|
7884
|
+
label: "Copy",
|
|
7885
|
+
description: "Copy chat content to the clipboard: /copy [last|code|all]",
|
|
7886
|
+
shortcut: "/copy",
|
|
7887
|
+
run: runCopyAction
|
|
7888
|
+
},
|
|
7639
7889
|
{
|
|
7640
7890
|
kind: "chat-action",
|
|
7641
7891
|
id: "export",
|
|
@@ -7841,12 +8091,20 @@ function isTodoWriteOutput(toolName, output) {
|
|
|
7841
8091
|
return toolName === "todo_write" && typeof output === "object" && output !== null && Array.isArray(Reflect.get(output, "todos"));
|
|
7842
8092
|
}
|
|
7843
8093
|
function normalizeChatErrorMessage(message) {
|
|
8094
|
+
const structured = parseChatStreamError(message);
|
|
8095
|
+
if (structured) {
|
|
8096
|
+
return describeChatStreamError(structured);
|
|
8097
|
+
}
|
|
7844
8098
|
if (disconnectErrorPattern.test(message)) {
|
|
7845
8099
|
return recoverableDisconnectMessage;
|
|
7846
8100
|
}
|
|
7847
8101
|
return message;
|
|
7848
8102
|
}
|
|
7849
8103
|
function isRecoverableChatErrorMessage(message) {
|
|
8104
|
+
const structured = parseChatStreamError(message);
|
|
8105
|
+
if (structured) {
|
|
8106
|
+
return structured.retryable;
|
|
8107
|
+
}
|
|
7850
8108
|
return disconnectErrorPattern.test(message) || transientProviderErrorPattern.test(message);
|
|
7851
8109
|
}
|
|
7852
8110
|
function isRetryCommand(input) {
|
|
@@ -7893,6 +8151,27 @@ function hasUnresolvedToolParts(messages) {
|
|
|
7893
8151
|
].includes(part.state);
|
|
7894
8152
|
}));
|
|
7895
8153
|
}
|
|
8154
|
+
function sanitizeMessagesForRetry(messages) {
|
|
8155
|
+
const trimmed = trimIncompleteTrailingAssistantMessages(messages);
|
|
8156
|
+
return trimmed.map((message) => {
|
|
8157
|
+
if (message.role !== "assistant") {
|
|
8158
|
+
return message;
|
|
8159
|
+
}
|
|
8160
|
+
let changed = false;
|
|
8161
|
+
const parts = message.parts.map((part) => {
|
|
8162
|
+
if (!isToolUIPart(part) || terminalToolPartStates.has(part.state)) {
|
|
8163
|
+
return part;
|
|
8164
|
+
}
|
|
8165
|
+
changed = true;
|
|
8166
|
+
return {
|
|
8167
|
+
...part,
|
|
8168
|
+
state: "output-error",
|
|
8169
|
+
errorText: interruptedToolRetryErrorText
|
|
8170
|
+
};
|
|
8171
|
+
});
|
|
8172
|
+
return changed ? { ...message, parts } : message;
|
|
8173
|
+
});
|
|
8174
|
+
}
|
|
7896
8175
|
function hasActiveClientToolWork({
|
|
7897
8176
|
messages,
|
|
7898
8177
|
pendingApprovals,
|
|
@@ -8024,7 +8303,7 @@ function useCodingSessionChat({
|
|
|
8024
8303
|
maxAutoContinues: autoContinue?.maxAutoContinues ?? defaultAutoContinueLimits.maxAutoContinues
|
|
8025
8304
|
};
|
|
8026
8305
|
const maxErrorRetries = autoContinue?.maxErrorRetries ?? 5;
|
|
8027
|
-
const stallTimeoutMs = (autoContinue?.stallTimeoutSeconds ??
|
|
8306
|
+
const stallTimeoutMs = (autoContinue?.stallTimeoutSeconds ?? 180) * 1000;
|
|
8028
8307
|
const autoContinueLimitsRef = useRef(autoContinueLimits);
|
|
8029
8308
|
autoContinueLimitsRef.current = autoContinueLimits;
|
|
8030
8309
|
const maxErrorRetriesRef = useRef(maxErrorRetries);
|
|
@@ -8058,8 +8337,27 @@ function useCodingSessionChat({
|
|
|
8058
8337
|
loadPersistedMessagesRef.current = loadPersistedMessages;
|
|
8059
8338
|
loadPersistedInteractionsRef.current = loadPersistedInteractions;
|
|
8060
8339
|
const transport = useMemo(() => {
|
|
8340
|
+
const monitoredFetch = async (input, init) => {
|
|
8341
|
+
const response = await globalThis.fetch(input, init);
|
|
8342
|
+
lastStreamActivityRef.current = Date.now();
|
|
8343
|
+
if (!response.body) {
|
|
8344
|
+
return response;
|
|
8345
|
+
}
|
|
8346
|
+
const monitoredBody = response.body.pipeThrough(new TransformStream({
|
|
8347
|
+
transform(chunk, controller) {
|
|
8348
|
+
lastStreamActivityRef.current = Date.now();
|
|
8349
|
+
controller.enqueue(chunk);
|
|
8350
|
+
}
|
|
8351
|
+
}));
|
|
8352
|
+
return new Response(monitoredBody, {
|
|
8353
|
+
status: response.status,
|
|
8354
|
+
statusText: response.statusText,
|
|
8355
|
+
headers: response.headers
|
|
8356
|
+
});
|
|
8357
|
+
};
|
|
8061
8358
|
return new DefaultChatTransport({
|
|
8062
8359
|
api: chatApi,
|
|
8360
|
+
fetch: monitoredFetch,
|
|
8063
8361
|
body: () => ({
|
|
8064
8362
|
cwd: cwdRef.current,
|
|
8065
8363
|
mode: modeRef.current,
|
|
@@ -8381,11 +8679,11 @@ function useCodingSessionChat({
|
|
|
8381
8679
|
setToolExecutionError("No recoverable response is waiting to retry.");
|
|
8382
8680
|
return;
|
|
8383
8681
|
}
|
|
8384
|
-
if (pendingApprovals.length > 0 || pendingUserPrompts.length > 0
|
|
8682
|
+
if (pendingApprovals.length > 0 || pendingUserPrompts.length > 0) {
|
|
8385
8683
|
setToolExecutionError("Resolve pending tool approvals or user prompts before retrying.");
|
|
8386
8684
|
return;
|
|
8387
8685
|
}
|
|
8388
|
-
const retryMessages =
|
|
8686
|
+
const retryMessages = sanitizeMessagesForRetry(messages);
|
|
8389
8687
|
setMessages(retryMessages);
|
|
8390
8688
|
clearError();
|
|
8391
8689
|
setToolExecutionError(null);
|
|
@@ -8400,10 +8698,10 @@ function useCodingSessionChat({
|
|
|
8400
8698
|
setMessages
|
|
8401
8699
|
]);
|
|
8402
8700
|
useEffect(() => {
|
|
8403
|
-
if (status === "
|
|
8701
|
+
if (status === "ready" && !error) {
|
|
8404
8702
|
errorRetriesRef.current = 0;
|
|
8405
8703
|
}
|
|
8406
|
-
}, [status]);
|
|
8704
|
+
}, [error, status]);
|
|
8407
8705
|
useEffect(() => {
|
|
8408
8706
|
if (status === "streaming" || status === "submitted") {
|
|
8409
8707
|
lastStreamActivityRef.current = Date.now();
|
|
@@ -8433,7 +8731,7 @@ function useCodingSessionChat({
|
|
|
8433
8731
|
(async () => {
|
|
8434
8732
|
try {
|
|
8435
8733
|
await stop();
|
|
8436
|
-
setMessages((current) =>
|
|
8734
|
+
setMessages((current) => sanitizeMessagesForRetry(current));
|
|
8437
8735
|
clearError();
|
|
8438
8736
|
setToolExecutionError(null);
|
|
8439
8737
|
await sendMessage();
|
|
@@ -8506,10 +8804,7 @@ function useCodingSessionChat({
|
|
|
8506
8804
|
if (errorRetriesRef.current >= maxErrorRetriesRef.current) {
|
|
8507
8805
|
return;
|
|
8508
8806
|
}
|
|
8509
|
-
const retryMessages =
|
|
8510
|
-
if (hasUnresolvedToolParts(retryMessages)) {
|
|
8511
|
-
return;
|
|
8512
|
-
}
|
|
8807
|
+
const retryMessages = sanitizeMessagesForRetry(messages);
|
|
8513
8808
|
const attempt = errorRetriesRef.current + 1;
|
|
8514
8809
|
const delay = Math.min(errorRetryBaseDelayMs * 2 ** (attempt - 1), errorRetryMaxDelayMs);
|
|
8515
8810
|
errorRetryTimerRef.current = setTimeout(() => {
|
|
@@ -8732,9 +9027,10 @@ function useCodingSessionChat({
|
|
|
8732
9027
|
isSessionIdValid
|
|
8733
9028
|
};
|
|
8734
9029
|
}
|
|
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;
|
|
9030
|
+
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, interruptedToolRetryErrorText = "Tool call was interrupted by a connection retry. Re-issue the tool call if it is still needed.", terminalToolPartStates;
|
|
8736
9031
|
var init_use_coding_session_chat = __esm(() => {
|
|
8737
9032
|
init_agent_tools();
|
|
9033
|
+
init_chat_error();
|
|
8738
9034
|
init_chat_interaction_schemas();
|
|
8739
9035
|
init_output_utils();
|
|
8740
9036
|
init_resolve_within_workspace();
|
|
@@ -8748,6 +9044,11 @@ var init_use_coding_session_chat = __esm(() => {
|
|
|
8748
9044
|
codingToolNameSet = new Set(Object.keys(codingToolInputSchemas));
|
|
8749
9045
|
disconnectErrorPattern = /(failed to fetch|networkerror|socket|connection|aborted|terminated|timed?\s?out|timeout|econnreset)/i;
|
|
8750
9046
|
transientProviderErrorPattern = /(rate.?limit|too many requests|\b429\b|overloaded|quota)/i;
|
|
9047
|
+
terminalToolPartStates = new Set([
|
|
9048
|
+
"output-available",
|
|
9049
|
+
"output-error",
|
|
9050
|
+
"output-denied"
|
|
9051
|
+
]);
|
|
8751
9052
|
});
|
|
8752
9053
|
|
|
8753
9054
|
// packages/ai/src/react/index.ts
|
|
@@ -8755,6 +9056,59 @@ var init_react = __esm(() => {
|
|
|
8755
9056
|
init_use_coding_session_chat();
|
|
8756
9057
|
});
|
|
8757
9058
|
|
|
9059
|
+
// apps/cli/src/lib/clipboard.ts
|
|
9060
|
+
import { platform as platform3 } from "os";
|
|
9061
|
+
async function copyText(renderer, text) {
|
|
9062
|
+
if (!text) {
|
|
9063
|
+
return false;
|
|
9064
|
+
}
|
|
9065
|
+
let copied = false;
|
|
9066
|
+
try {
|
|
9067
|
+
if (renderer?.copyToClipboardOSC52?.(text)) {
|
|
9068
|
+
copied = true;
|
|
9069
|
+
}
|
|
9070
|
+
} catch {}
|
|
9071
|
+
if (await copyViaNativeTool(text)) {
|
|
9072
|
+
copied = true;
|
|
9073
|
+
}
|
|
9074
|
+
return copied;
|
|
9075
|
+
}
|
|
9076
|
+
function nativeClipboardCommand() {
|
|
9077
|
+
switch (platform3()) {
|
|
9078
|
+
case "win32":
|
|
9079
|
+
return ["clip"];
|
|
9080
|
+
case "darwin":
|
|
9081
|
+
return ["pbcopy"];
|
|
9082
|
+
default:
|
|
9083
|
+
return null;
|
|
9084
|
+
}
|
|
9085
|
+
}
|
|
9086
|
+
async function copyViaNativeTool(text) {
|
|
9087
|
+
const direct = nativeClipboardCommand();
|
|
9088
|
+
if (direct) {
|
|
9089
|
+
return spawnCopy(direct, text);
|
|
9090
|
+
}
|
|
9091
|
+
if (await spawnCopy(["wl-copy"], text)) {
|
|
9092
|
+
return true;
|
|
9093
|
+
}
|
|
9094
|
+
return spawnCopy(["xclip", "-selection", "clipboard"], text);
|
|
9095
|
+
}
|
|
9096
|
+
async function spawnCopy(command, text) {
|
|
9097
|
+
try {
|
|
9098
|
+
const proc = Bun.spawn(command, {
|
|
9099
|
+
stdin: "pipe",
|
|
9100
|
+
stdout: "ignore",
|
|
9101
|
+
stderr: "ignore"
|
|
9102
|
+
});
|
|
9103
|
+
proc.stdin.write(text);
|
|
9104
|
+
await proc.stdin.end();
|
|
9105
|
+
return await proc.exited === 0;
|
|
9106
|
+
} catch {
|
|
9107
|
+
return false;
|
|
9108
|
+
}
|
|
9109
|
+
}
|
|
9110
|
+
var init_clipboard = () => {};
|
|
9111
|
+
|
|
8758
9112
|
// apps/cli/src/utils/text-utils.ts
|
|
8759
9113
|
function truncateInline2(text, maxLength = 96) {
|
|
8760
9114
|
const normalized = text.replace(/\s+/g, " ").trim();
|
|
@@ -9575,7 +9929,7 @@ function collapseDiff(diff) {
|
|
|
9575
9929
|
hiddenLines: lines.length - cut
|
|
9576
9930
|
};
|
|
9577
9931
|
}
|
|
9578
|
-
function ChatDiffCard({ path:
|
|
9932
|
+
function ChatDiffCard({ path: path16, diff }) {
|
|
9579
9933
|
const wasPreTruncated = diff.trimEnd().endsWith(TRUNCATION_MARKER);
|
|
9580
9934
|
const cleanDiff = wasPreTruncated ? diff.trimEnd().slice(0, -TRUNCATION_MARKER.length).trimEnd() : diff;
|
|
9581
9935
|
const { text, hiddenLines } = collapseDiff(cleanDiff);
|
|
@@ -9594,14 +9948,14 @@ function ChatDiffCard({ path: path15, diff }) {
|
|
|
9594
9948
|
children: /* @__PURE__ */ jsxDEV11("text", {
|
|
9595
9949
|
fg: cliTheme.text.secondary,
|
|
9596
9950
|
attributes: TextAttributes7.BOLD,
|
|
9597
|
-
children:
|
|
9951
|
+
children: path16
|
|
9598
9952
|
}, undefined, false, undefined, this)
|
|
9599
9953
|
}, undefined, false, undefined, this),
|
|
9600
9954
|
/* @__PURE__ */ jsxDEV11("diff", {
|
|
9601
9955
|
width: "100%",
|
|
9602
9956
|
diff: text,
|
|
9603
9957
|
view: "unified",
|
|
9604
|
-
filetype: inferFiletype(
|
|
9958
|
+
filetype: inferFiletype(path16),
|
|
9605
9959
|
syntaxStyle: codeSyntaxStyle,
|
|
9606
9960
|
showLineNumbers: true,
|
|
9607
9961
|
addedBg,
|
|
@@ -9674,11 +10028,11 @@ function getFileEditDiff(part) {
|
|
|
9674
10028
|
return null;
|
|
9675
10029
|
}
|
|
9676
10030
|
const diff = Reflect.get(output, "diff");
|
|
9677
|
-
const
|
|
9678
|
-
if (typeof diff !== "string" || !diff.trim() || typeof
|
|
10031
|
+
const path16 = Reflect.get(output, "path");
|
|
10032
|
+
if (typeof diff !== "string" || !diff.trim() || typeof path16 !== "string") {
|
|
9679
10033
|
return null;
|
|
9680
10034
|
}
|
|
9681
|
-
return { path:
|
|
10035
|
+
return { path: path16, diff };
|
|
9682
10036
|
}
|
|
9683
10037
|
function getSecondaryParams(input, target) {
|
|
9684
10038
|
if (!input || typeof input !== "object") {
|
|
@@ -10674,6 +11028,60 @@ var init_loading_timer = __esm(() => {
|
|
|
10674
11028
|
init_cli_theme();
|
|
10675
11029
|
});
|
|
10676
11030
|
|
|
11031
|
+
// apps/cli/src/components/chat/copy-mode-overlay.tsx
|
|
11032
|
+
import { TextAttributes as TextAttributes15 } from "@opentui/core";
|
|
11033
|
+
import { jsxDEV as jsxDEV20 } from "@opentui/react/jsx-dev-runtime";
|
|
11034
|
+
function previewOf(message) {
|
|
11035
|
+
const text = collectMessageText(message).replace(/\s+/g, " ").trim();
|
|
11036
|
+
return text.length > 0 ? text : "(no text)";
|
|
11037
|
+
}
|
|
11038
|
+
function CopyModeOverlay({ messages, selectedIndex }) {
|
|
11039
|
+
const total = messages.length;
|
|
11040
|
+
const half = Math.floor(WINDOW_SIZE / 2);
|
|
11041
|
+
const end = Math.min(total, Math.max(selectedIndex + half + 1, WINDOW_SIZE));
|
|
11042
|
+
const start = Math.max(0, end - WINDOW_SIZE);
|
|
11043
|
+
const visible = messages.slice(start, end);
|
|
11044
|
+
return /* @__PURE__ */ jsxDEV20("box", {
|
|
11045
|
+
flexDirection: "column",
|
|
11046
|
+
paddingX: 1,
|
|
11047
|
+
paddingY: 1,
|
|
11048
|
+
borderStyle: "single",
|
|
11049
|
+
borderColor: cliTheme.accent.primary,
|
|
11050
|
+
children: [
|
|
11051
|
+
/* @__PURE__ */ jsxDEV20("text", {
|
|
11052
|
+
fg: cliTheme.accent.primary,
|
|
11053
|
+
attributes: TextAttributes15.BOLD,
|
|
11054
|
+
children: "Copy mode \u2014 \u2191/\u2193 select \xB7 Enter copy \xB7 c code blocks \xB7 Esc exit"
|
|
11055
|
+
}, undefined, false, undefined, this),
|
|
11056
|
+
visible.map((message, offset) => {
|
|
11057
|
+
const index = start + offset;
|
|
11058
|
+
const isSelected = index === selectedIndex;
|
|
11059
|
+
const rowColors = getOverlayRowColors(isSelected);
|
|
11060
|
+
const role = message.role === "user" ? "You" : "Assistant";
|
|
11061
|
+
return /* @__PURE__ */ jsxDEV20("box", {
|
|
11062
|
+
paddingX: 1,
|
|
11063
|
+
backgroundColor: rowColors.backgroundColor,
|
|
11064
|
+
children: /* @__PURE__ */ jsxDEV20("text", {
|
|
11065
|
+
fg: rowColors.primaryTextColor,
|
|
11066
|
+
children: `${role}: ${truncateInline2(previewOf(message), 80)}`
|
|
11067
|
+
}, undefined, false, undefined, this)
|
|
11068
|
+
}, message.id, false, undefined, this);
|
|
11069
|
+
}),
|
|
11070
|
+
total > visible.length ? /* @__PURE__ */ jsxDEV20("text", {
|
|
11071
|
+
fg: cliTheme.text.muted,
|
|
11072
|
+
attributes: TextAttributes15.DIM,
|
|
11073
|
+
children: `${selectedIndex + 1}/${total}`
|
|
11074
|
+
}, undefined, false, undefined, this) : null
|
|
11075
|
+
]
|
|
11076
|
+
}, undefined, true, undefined, this);
|
|
11077
|
+
}
|
|
11078
|
+
var WINDOW_SIZE = 7;
|
|
11079
|
+
var init_copy_mode_overlay = __esm(() => {
|
|
11080
|
+
init_src2();
|
|
11081
|
+
init_cli_theme();
|
|
11082
|
+
init_text_utils();
|
|
11083
|
+
});
|
|
11084
|
+
|
|
10677
11085
|
// apps/cli/src/hooks/use-auto-continue-config.ts
|
|
10678
11086
|
import { useEffect as useEffect5, useState as useState7 } from "react";
|
|
10679
11087
|
function useAutoContinueConfig() {
|
|
@@ -10813,7 +11221,7 @@ var init_chat_context_utils = __esm(() => {
|
|
|
10813
11221
|
|
|
10814
11222
|
// apps/cli/src/utils/file-mentions.ts
|
|
10815
11223
|
import { promises as fs6 } from "fs";
|
|
10816
|
-
import
|
|
11224
|
+
import path16 from "path";
|
|
10817
11225
|
function extractFileMentions(text) {
|
|
10818
11226
|
const mentions = new Set;
|
|
10819
11227
|
for (const match of text.matchAll(mentionTokenPattern)) {
|
|
@@ -10835,8 +11243,8 @@ async function appendMentionAttachments(text, cwd) {
|
|
|
10835
11243
|
}
|
|
10836
11244
|
const attachmentBlocks = [];
|
|
10837
11245
|
for (const mentionPath of mentionPaths) {
|
|
10838
|
-
const absolutePath =
|
|
10839
|
-
if (!absolutePath.startsWith(
|
|
11246
|
+
const absolutePath = path16.resolve(cwd, mentionPath);
|
|
11247
|
+
if (!absolutePath.startsWith(path16.resolve(cwd))) {
|
|
10840
11248
|
continue;
|
|
10841
11249
|
}
|
|
10842
11250
|
try {
|
|
@@ -10893,10 +11301,10 @@ var init_file_mentions = __esm(() => {
|
|
|
10893
11301
|
});
|
|
10894
11302
|
|
|
10895
11303
|
// apps/cli/src/screens/chat-screen.tsx
|
|
10896
|
-
import { useKeyboard as useKeyboard4 } from "@opentui/react";
|
|
11304
|
+
import { useKeyboard as useKeyboard4, useRenderer } from "@opentui/react";
|
|
10897
11305
|
import { Fragment, useCallback as useCallback4, useEffect as useEffect8, useMemo as useMemo4, useRef as useRef4, useState as useState10 } from "react";
|
|
10898
11306
|
import { useLocation, useNavigate, useParams } from "react-router";
|
|
10899
|
-
import { jsxDEV as
|
|
11307
|
+
import { jsxDEV as jsxDEV21 } from "@opentui/react/jsx-dev-runtime";
|
|
10900
11308
|
function shouldImplementApprovedPlan(response) {
|
|
10901
11309
|
if (response.selectedValue === "yes") {
|
|
10902
11310
|
return true;
|
|
@@ -11139,14 +11547,44 @@ function ChatScreen() {
|
|
|
11139
11547
|
const notifyChatAction = useCallback4((text, tone = "info") => {
|
|
11140
11548
|
setActionNotice({ text, tone });
|
|
11141
11549
|
}, []);
|
|
11142
|
-
const
|
|
11550
|
+
const renderer = useRenderer();
|
|
11551
|
+
const [copyModeOpen, setCopyModeOpen] = useState10(false);
|
|
11552
|
+
const [copyModeIndex, setCopyModeIndex] = useState10(0);
|
|
11553
|
+
const copyableMessages = useMemo4(() => messages.filter((message) => (message.role === "user" || message.role === "assistant") && collectMessageText(message).trim().length > 0), [messages]);
|
|
11554
|
+
const copySelectedMessage = useCallback4(async (kind) => {
|
|
11555
|
+
const message = copyableMessages[copyModeIndex];
|
|
11556
|
+
if (!message) {
|
|
11557
|
+
return;
|
|
11558
|
+
}
|
|
11559
|
+
const fullText = collectMessageText(message);
|
|
11560
|
+
let payload = fullText;
|
|
11561
|
+
let label = "message";
|
|
11562
|
+
if (kind === "code") {
|
|
11563
|
+
const blocks = extractCodeBlocks(fullText);
|
|
11564
|
+
if (blocks.length === 0) {
|
|
11565
|
+
notifyChatAction("No code blocks in this message.", "error");
|
|
11566
|
+
return;
|
|
11567
|
+
}
|
|
11568
|
+
payload = blocks.map((block) => block.code).join(`
|
|
11569
|
+
|
|
11570
|
+
`);
|
|
11571
|
+
label = blocks.length === 1 ? "code block" : "code blocks";
|
|
11572
|
+
}
|
|
11573
|
+
const copied = await copyText(renderer, payload);
|
|
11574
|
+
notifyChatAction(copied ? `Copied ${label} to clipboard (${payload.length} chars).` : "Copy failed: clipboard unavailable in this terminal.", copied ? "info" : "error");
|
|
11575
|
+
setCopyModeOpen(false);
|
|
11576
|
+
}, [copyModeIndex, copyableMessages, notifyChatAction, renderer]);
|
|
11577
|
+
const runChatSlashAction = useCallback4((action, args = "") => {
|
|
11143
11578
|
action.run({
|
|
11144
11579
|
sessionId,
|
|
11580
|
+
args,
|
|
11581
|
+
messages,
|
|
11145
11582
|
setContextState,
|
|
11146
11583
|
notify: notifyChatAction,
|
|
11147
|
-
setPermissionMode: setPermissionModeToState
|
|
11584
|
+
setPermissionMode: setPermissionModeToState,
|
|
11585
|
+
copyToClipboard: (text) => copyText(renderer, text)
|
|
11148
11586
|
});
|
|
11149
|
-
}, [notifyChatAction, sessionId]);
|
|
11587
|
+
}, [messages, notifyChatAction, renderer, sessionId]);
|
|
11150
11588
|
const updatePermissionMode = useCallback4(async (newMode) => {
|
|
11151
11589
|
setPermissionMode(newMode);
|
|
11152
11590
|
setPermissionSelectorOpen(false);
|
|
@@ -11221,7 +11659,11 @@ function ChatScreen() {
|
|
|
11221
11659
|
const action = findChatSlashAction(text);
|
|
11222
11660
|
if (action) {
|
|
11223
11661
|
closeSlashMenu();
|
|
11224
|
-
|
|
11662
|
+
if (action.id === "permission") {
|
|
11663
|
+
setPermissionSelectorOpen(true);
|
|
11664
|
+
return;
|
|
11665
|
+
}
|
|
11666
|
+
runChatSlashAction(action, parseChatSlashArgs(text));
|
|
11225
11667
|
return;
|
|
11226
11668
|
}
|
|
11227
11669
|
if (navigateIfSlashRoute(text)) {
|
|
@@ -11279,6 +11721,50 @@ function ChatScreen() {
|
|
|
11279
11721
|
}, [mode, queuedImplementationInstruction, sendDirectMessage]);
|
|
11280
11722
|
useKeyboard4((keyEvent) => {
|
|
11281
11723
|
const keyName = keyEvent.name.toLowerCase();
|
|
11724
|
+
if (copyModeOpen) {
|
|
11725
|
+
if (isEscapeKey(keyName)) {
|
|
11726
|
+
keyEvent.preventDefault();
|
|
11727
|
+
keyEvent.stopPropagation();
|
|
11728
|
+
setCopyModeOpen(false);
|
|
11729
|
+
return;
|
|
11730
|
+
}
|
|
11731
|
+
if (isUpKey(keyName, { vim: true })) {
|
|
11732
|
+
keyEvent.preventDefault();
|
|
11733
|
+
keyEvent.stopPropagation();
|
|
11734
|
+
setCopyModeIndex((index) => Math.max(0, index - 1));
|
|
11735
|
+
return;
|
|
11736
|
+
}
|
|
11737
|
+
if (isDownKey(keyName, { vim: true })) {
|
|
11738
|
+
keyEvent.preventDefault();
|
|
11739
|
+
keyEvent.stopPropagation();
|
|
11740
|
+
setCopyModeIndex((index) => Math.min(copyableMessages.length - 1, index + 1));
|
|
11741
|
+
return;
|
|
11742
|
+
}
|
|
11743
|
+
if (isEnterKey(keyName) || keyName === "y") {
|
|
11744
|
+
keyEvent.preventDefault();
|
|
11745
|
+
keyEvent.stopPropagation();
|
|
11746
|
+
copySelectedMessage("text");
|
|
11747
|
+
return;
|
|
11748
|
+
}
|
|
11749
|
+
if (keyName === "c") {
|
|
11750
|
+
keyEvent.preventDefault();
|
|
11751
|
+
keyEvent.stopPropagation();
|
|
11752
|
+
copySelectedMessage("code");
|
|
11753
|
+
return;
|
|
11754
|
+
}
|
|
11755
|
+
return;
|
|
11756
|
+
}
|
|
11757
|
+
const isCtrlY = keyName === "y" && keyEvent.ctrl && !keyEvent.meta && !keyEvent.super && !keyEvent.hyper && !keyEvent.shift;
|
|
11758
|
+
if (isCtrlY) {
|
|
11759
|
+
if (!isSessionIdValid || hasBlockingPopup || slashMenuOpen || copyableMessages.length === 0) {
|
|
11760
|
+
return;
|
|
11761
|
+
}
|
|
11762
|
+
keyEvent.preventDefault();
|
|
11763
|
+
keyEvent.stopPropagation();
|
|
11764
|
+
setCopyModeIndex(copyableMessages.length - 1);
|
|
11765
|
+
setCopyModeOpen(true);
|
|
11766
|
+
return;
|
|
11767
|
+
}
|
|
11282
11768
|
const isPlainTab = (keyName === "tab" || keyEvent.sequence === "\t") && !keyEvent.ctrl && !keyEvent.meta && !keyEvent.super && !keyEvent.hyper && !keyEvent.shift;
|
|
11283
11769
|
const isCtrlT = keyName === "t" && keyEvent.ctrl && !keyEvent.meta && !keyEvent.super && !keyEvent.hyper && !keyEvent.shift;
|
|
11284
11770
|
if (!isPlainTab && !isCtrlT) {
|
|
@@ -11291,74 +11777,77 @@ function ChatScreen() {
|
|
|
11291
11777
|
keyEvent.stopPropagation();
|
|
11292
11778
|
setMode((currentMode) => cycleCodingAgentMode(currentMode));
|
|
11293
11779
|
});
|
|
11294
|
-
return /* @__PURE__ */
|
|
11780
|
+
return /* @__PURE__ */ jsxDEV21("box", {
|
|
11295
11781
|
width: "100%",
|
|
11296
11782
|
height: "100%",
|
|
11297
|
-
children: /* @__PURE__ */
|
|
11783
|
+
children: /* @__PURE__ */ jsxDEV21(ChatShell, {
|
|
11298
11784
|
hasMessages: messages.length > 0 || isStreaming || pendingApprovals.length > 0 || activeUserPrompt !== null || planConfirmationOpen,
|
|
11299
11785
|
messageCount: messages.length,
|
|
11300
11786
|
errorMessage,
|
|
11301
|
-
inputArea: /* @__PURE__ */
|
|
11787
|
+
inputArea: /* @__PURE__ */ jsxDEV21(ChatTextArea, {
|
|
11302
11788
|
placeholder: isLoading ? "Waiting for response..." : "Reply... (@ to attach files)",
|
|
11303
|
-
focused: canTypeInChat,
|
|
11304
|
-
disabled: !canTypeInChat,
|
|
11789
|
+
focused: canTypeInChat && !copyModeOpen,
|
|
11790
|
+
disabled: !canTypeInChat || copyModeOpen,
|
|
11305
11791
|
slashMenuOpen,
|
|
11306
11792
|
mentionCandidates,
|
|
11307
11793
|
onTextChange: syncSlashMenuFromInput,
|
|
11308
|
-
beforeInput: slashMenuOpen ? /* @__PURE__ */
|
|
11794
|
+
beforeInput: slashMenuOpen ? /* @__PURE__ */ jsxDEV21(SlashPageMenu, {
|
|
11309
11795
|
query: slashMenuQuery,
|
|
11310
11796
|
selectedIndex: selectedSlashRouteIndex,
|
|
11311
11797
|
routes: slashRoutes
|
|
11312
11798
|
}, undefined, false, undefined, this) : null,
|
|
11313
|
-
footer: /* @__PURE__ */
|
|
11799
|
+
footer: /* @__PURE__ */ jsxDEV21("box", {
|
|
11314
11800
|
flexDirection: "row",
|
|
11315
11801
|
justifyContent: "space-between",
|
|
11316
11802
|
children: [
|
|
11317
|
-
|
|
11803
|
+
copyModeOpen ? /* @__PURE__ */ jsxDEV21("text", {
|
|
11804
|
+
fg: cliTheme.text.muted,
|
|
11805
|
+
children: "Copy mode: \u2191/\u2193 select \xB7 Enter copy \xB7 c code \xB7 Esc exit"
|
|
11806
|
+
}, undefined, false, undefined, this) : canRetryRecoverableResponse ? /* @__PURE__ */ jsxDEV21("text", {
|
|
11318
11807
|
fg: cliTheme.text.muted,
|
|
11319
11808
|
children: "Type retry or regenerate to try again"
|
|
11320
|
-
}, undefined, false, undefined, this) : pendingApprovals.length > 0 ? /* @__PURE__ */
|
|
11809
|
+
}, undefined, false, undefined, this) : pendingApprovals.length > 0 ? /* @__PURE__ */ jsxDEV21("text", {
|
|
11321
11810
|
fg: cliTheme.text.muted,
|
|
11322
11811
|
children: "Use approval card or approve/deny commands"
|
|
11323
|
-
}, undefined, false, undefined, this) : hasBlockingPopup ? /* @__PURE__ */
|
|
11812
|
+
}, undefined, false, undefined, this) : hasBlockingPopup ? /* @__PURE__ */ jsxDEV21("text", {
|
|
11324
11813
|
fg: cliTheme.text.muted,
|
|
11325
11814
|
children: "Complete the inline prompt to continue"
|
|
11326
|
-
}, undefined, false, undefined, this) : slashMenuOpen ? /* @__PURE__ */
|
|
11815
|
+
}, undefined, false, undefined, this) : slashMenuOpen ? /* @__PURE__ */ jsxDEV21("text", {
|
|
11327
11816
|
fg: cliTheme.text.muted,
|
|
11328
11817
|
children: "Choose a page or press Esc"
|
|
11329
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
11818
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV21("text", {
|
|
11330
11819
|
fg: cliTheme.text.muted,
|
|
11331
|
-
children: "Tab/Ctrl+T
|
|
11820
|
+
children: "Tab/Ctrl+T mode | Ctrl+Y copy | Ctrl+P commands"
|
|
11332
11821
|
}, undefined, false, undefined, this),
|
|
11333
|
-
/* @__PURE__ */
|
|
11822
|
+
/* @__PURE__ */ jsxDEV21("box", {
|
|
11334
11823
|
flexDirection: "row",
|
|
11335
11824
|
gap: 1,
|
|
11336
11825
|
alignItems: "center",
|
|
11337
11826
|
children: [
|
|
11338
|
-
/* @__PURE__ */
|
|
11827
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
11339
11828
|
fg: contextMeterColor,
|
|
11340
11829
|
children: contextEstimate.displayText
|
|
11341
11830
|
}, undefined, false, undefined, this),
|
|
11342
|
-
/* @__PURE__ */
|
|
11831
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
11343
11832
|
children: [
|
|
11344
|
-
/* @__PURE__ */
|
|
11833
|
+
/* @__PURE__ */ jsxDEV21("span", {
|
|
11345
11834
|
fg: cliTheme.accent.primary,
|
|
11346
11835
|
children: modeDefinition.label
|
|
11347
11836
|
}, undefined, false, undefined, this),
|
|
11348
|
-
/* @__PURE__ */
|
|
11837
|
+
/* @__PURE__ */ jsxDEV21("span", {
|
|
11349
11838
|
fg: cliTheme.text.muted,
|
|
11350
11839
|
children: " mode"
|
|
11351
11840
|
}, undefined, false, undefined, this)
|
|
11352
11841
|
]
|
|
11353
11842
|
}, undefined, true, undefined, this),
|
|
11354
|
-
/* @__PURE__ */
|
|
11355
|
-
children: /* @__PURE__ */
|
|
11843
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
11844
|
+
children: /* @__PURE__ */ jsxDEV21("span", {
|
|
11356
11845
|
fg: cliTheme.semantic.warning,
|
|
11357
11846
|
children: "|"
|
|
11358
11847
|
}, undefined, false, undefined, this)
|
|
11359
11848
|
}, undefined, false, undefined, this),
|
|
11360
|
-
/* @__PURE__ */
|
|
11361
|
-
children: /* @__PURE__ */
|
|
11849
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
11850
|
+
children: /* @__PURE__ */ jsxDEV21("span", {
|
|
11362
11851
|
fg: permissionMode === "danger-full-access" ? cliTheme.semantic.error : permissionMode === "read-only" ? cliTheme.text.muted : cliTheme.text.primary,
|
|
11363
11852
|
children: permissionMode ?? "default"
|
|
11364
11853
|
}, undefined, false, undefined, this)
|
|
@@ -11371,30 +11860,30 @@ function ChatScreen() {
|
|
|
11371
11860
|
onSubmit: submitChatInput
|
|
11372
11861
|
}, undefined, false, undefined, this),
|
|
11373
11862
|
children: [
|
|
11374
|
-
contextState && !anchorVisibleInMessages ? /* @__PURE__ */
|
|
11863
|
+
contextState && !anchorVisibleInMessages ? /* @__PURE__ */ jsxDEV21(ChatContextStateCard, {
|
|
11375
11864
|
contextState
|
|
11376
11865
|
}, undefined, false, undefined, this) : null,
|
|
11377
|
-
messages.map((message) => /* @__PURE__ */
|
|
11866
|
+
messages.map((message) => /* @__PURE__ */ jsxDEV21(Fragment, {
|
|
11378
11867
|
children: [
|
|
11379
|
-
isAutoContinueMessage(message) ? null : isContextSummaryMessage(message) ? /* @__PURE__ */
|
|
11868
|
+
isAutoContinueMessage(message) ? null : isContextSummaryMessage(message) ? /* @__PURE__ */ jsxDEV21(ChatContextSummaryCard, {
|
|
11380
11869
|
message
|
|
11381
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
11870
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV21(ChatMessage, {
|
|
11382
11871
|
message,
|
|
11383
11872
|
pendingApprovalIds
|
|
11384
11873
|
}, undefined, false, undefined, this),
|
|
11385
|
-
contextState && contextState.anchorMessageId === message.id ? /* @__PURE__ */
|
|
11874
|
+
contextState && contextState.anchorMessageId === message.id ? /* @__PURE__ */ jsxDEV21(ChatContextStateCard, {
|
|
11386
11875
|
contextState
|
|
11387
11876
|
}, undefined, false, undefined, this) : null
|
|
11388
11877
|
]
|
|
11389
11878
|
}, message.id, true, undefined, this)),
|
|
11390
|
-
actionNotice ? /* @__PURE__ */
|
|
11879
|
+
actionNotice ? /* @__PURE__ */ jsxDEV21("box", {
|
|
11391
11880
|
paddingX: 1,
|
|
11392
|
-
children: /* @__PURE__ */
|
|
11881
|
+
children: /* @__PURE__ */ jsxDEV21("text", {
|
|
11393
11882
|
fg: actionNotice.tone === "error" ? cliTheme.semantic.error : cliTheme.semantic.info,
|
|
11394
11883
|
children: actionNotice.text
|
|
11395
11884
|
}, undefined, false, undefined, this)
|
|
11396
11885
|
}, undefined, false, undefined, this) : null,
|
|
11397
|
-
modelHasToolCallXmlLeak ? /* @__PURE__ */
|
|
11886
|
+
modelHasToolCallXmlLeak ? /* @__PURE__ */ jsxDEV21("box", {
|
|
11398
11887
|
paddingX: 1,
|
|
11399
11888
|
paddingY: 1,
|
|
11400
11889
|
borderStyle: "single",
|
|
@@ -11402,47 +11891,47 @@ function ChatScreen() {
|
|
|
11402
11891
|
flexDirection: "column",
|
|
11403
11892
|
gap: 1,
|
|
11404
11893
|
children: [
|
|
11405
|
-
/* @__PURE__ */
|
|
11894
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
11406
11895
|
fg: cliTheme.semantic.warning,
|
|
11407
11896
|
children: "Model compatibility issue: this model output raw tool call XML instead of invoking tools."
|
|
11408
11897
|
}, undefined, false, undefined, this),
|
|
11409
|
-
/* @__PURE__ */
|
|
11898
|
+
/* @__PURE__ */ jsxDEV21("text", {
|
|
11410
11899
|
fg: cliTheme.text.muted,
|
|
11411
11900
|
children: "Switch to a model with native function calling (Claude, GPT-4, Llama 3) via /model."
|
|
11412
11901
|
}, undefined, false, undefined, this)
|
|
11413
11902
|
]
|
|
11414
|
-
}, undefined, true, undefined, this) : autoContinueState?.guardTripped ? /* @__PURE__ */
|
|
11903
|
+
}, undefined, true, undefined, this) : autoContinueState?.guardTripped ? /* @__PURE__ */ jsxDEV21("box", {
|
|
11415
11904
|
paddingX: 1,
|
|
11416
|
-
children: /* @__PURE__ */
|
|
11905
|
+
children: /* @__PURE__ */ jsxDEV21("text", {
|
|
11417
11906
|
fg: cliTheme.semantic.warning,
|
|
11418
11907
|
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.`
|
|
11419
11908
|
}, undefined, false, undefined, this)
|
|
11420
|
-
}, undefined, false, undefined, this) : autoContinueState ? /* @__PURE__ */
|
|
11909
|
+
}, undefined, false, undefined, this) : autoContinueState ? /* @__PURE__ */ jsxDEV21("box", {
|
|
11421
11910
|
paddingX: 1,
|
|
11422
|
-
children: /* @__PURE__ */
|
|
11911
|
+
children: /* @__PURE__ */ jsxDEV21("text", {
|
|
11423
11912
|
fg: cliTheme.semantic.info,
|
|
11424
11913
|
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
11914
|
}, undefined, false, undefined, this)
|
|
11426
11915
|
}, undefined, false, undefined, this) : null,
|
|
11427
|
-
isLoading || isStreaming ? /* @__PURE__ */
|
|
11916
|
+
isLoading || isStreaming ? /* @__PURE__ */ jsxDEV21(LoadingTimer, {
|
|
11428
11917
|
elapsedSeconds
|
|
11429
11918
|
}, undefined, false, undefined, this) : null,
|
|
11430
|
-
isStreaming ? /* @__PURE__ */
|
|
11919
|
+
isStreaming ? /* @__PURE__ */ jsxDEV21("box", {
|
|
11431
11920
|
paddingX: 1,
|
|
11432
|
-
children: /* @__PURE__ */
|
|
11921
|
+
children: /* @__PURE__ */ jsxDEV21("text", {
|
|
11433
11922
|
fg: cliTheme.semantic.info,
|
|
11434
11923
|
children: "Assistant is thinking..."
|
|
11435
11924
|
}, undefined, false, undefined, this)
|
|
11436
11925
|
}, undefined, false, undefined, this) : null,
|
|
11437
|
-
pendingApprovals.length > 0 ? /* @__PURE__ */
|
|
11926
|
+
pendingApprovals.length > 0 ? /* @__PURE__ */ jsxDEV21(ChatToolApprovalCard, {
|
|
11438
11927
|
approvals: pendingApprovals,
|
|
11439
11928
|
onResolve: resolveToolApproval,
|
|
11440
11929
|
onResolveAll: resolveAllToolApprovals
|
|
11441
11930
|
}, undefined, false, undefined, this) : null,
|
|
11442
|
-
todos.length > 0 ? /* @__PURE__ */
|
|
11931
|
+
todos.length > 0 ? /* @__PURE__ */ jsxDEV21(ChatTodoStatusCard, {
|
|
11443
11932
|
todos
|
|
11444
11933
|
}, undefined, false, undefined, this) : null,
|
|
11445
|
-
activeUserPrompt ? /* @__PURE__ */
|
|
11934
|
+
activeUserPrompt ? /* @__PURE__ */ jsxDEV21(ChatInteractionPopup, {
|
|
11446
11935
|
title: activeUserPrompt.header ?? "Question",
|
|
11447
11936
|
question: activeUserPrompt.question,
|
|
11448
11937
|
options: activeUserPrompt.options.map((option) => ({
|
|
@@ -11473,7 +11962,7 @@ function ChatScreen() {
|
|
|
11473
11962
|
});
|
|
11474
11963
|
}
|
|
11475
11964
|
}, undefined, false, undefined, this) : null,
|
|
11476
|
-
planConfirmationOpen ? /* @__PURE__ */
|
|
11965
|
+
planConfirmationOpen ? /* @__PURE__ */ jsxDEV21(ChatInteractionPopup, {
|
|
11477
11966
|
title: "Plan review",
|
|
11478
11967
|
question: "Implement this plan now?",
|
|
11479
11968
|
options: [
|
|
@@ -11521,10 +12010,14 @@ function ChatScreen() {
|
|
|
11521
12010
|
sendDirectMessage(defaultPlanRevisionRequest);
|
|
11522
12011
|
}
|
|
11523
12012
|
}, undefined, false, undefined, this) : null,
|
|
11524
|
-
permissionSelectorOpen ? /* @__PURE__ */
|
|
12013
|
+
permissionSelectorOpen ? /* @__PURE__ */ jsxDEV21(PermissionModeSelector, {
|
|
11525
12014
|
currentMode: permissionMode,
|
|
11526
12015
|
onSelect: updatePermissionMode,
|
|
11527
12016
|
onClose: () => setPermissionSelectorOpen(false)
|
|
12017
|
+
}, undefined, false, undefined, this) : null,
|
|
12018
|
+
copyModeOpen ? /* @__PURE__ */ jsxDEV21(CopyModeOverlay, {
|
|
12019
|
+
messages: copyableMessages,
|
|
12020
|
+
selectedIndex: Math.min(copyModeIndex, Math.max(copyableMessages.length - 1, 0))
|
|
11528
12021
|
}, undefined, false, undefined, this) : null
|
|
11529
12022
|
]
|
|
11530
12023
|
}, undefined, true, undefined, this)
|
|
@@ -11535,6 +12028,7 @@ var init_chat_screen = __esm(() => {
|
|
|
11535
12028
|
init_src2();
|
|
11536
12029
|
init_react();
|
|
11537
12030
|
init_chat_slash_actions();
|
|
12031
|
+
init_clipboard();
|
|
11538
12032
|
init_slash_menu_items();
|
|
11539
12033
|
init_slash_page_menu();
|
|
11540
12034
|
init_chat_context_summary_card();
|
|
@@ -11547,6 +12041,7 @@ var init_chat_screen = __esm(() => {
|
|
|
11547
12041
|
init_chat_todo_status_card();
|
|
11548
12042
|
init_chat_tool_approval_card();
|
|
11549
12043
|
init_loading_timer();
|
|
12044
|
+
init_copy_mode_overlay();
|
|
11550
12045
|
init_use_auto_continue_config();
|
|
11551
12046
|
init_use_context_window();
|
|
11552
12047
|
init_use_loading_timer();
|
|
@@ -11557,6 +12052,7 @@ var init_chat_screen = __esm(() => {
|
|
|
11557
12052
|
init_cli_theme();
|
|
11558
12053
|
init_chat_context_utils();
|
|
11559
12054
|
init_file_mentions();
|
|
12055
|
+
init_markdown_code();
|
|
11560
12056
|
planConfirmationAcceptKeywords = [
|
|
11561
12057
|
"yes",
|
|
11562
12058
|
"y",
|
|
@@ -11584,12 +12080,12 @@ var init_chat_screen = __esm(() => {
|
|
|
11584
12080
|
});
|
|
11585
12081
|
|
|
11586
12082
|
// apps/cli/src/screens/diagnostics-screen.tsx
|
|
11587
|
-
import { TextAttributes as
|
|
12083
|
+
import { TextAttributes as TextAttributes16 } from "@opentui/core";
|
|
11588
12084
|
import { useKeyboard as useKeyboard5 } from "@opentui/react";
|
|
11589
12085
|
import { useCallback as useCallback5, useEffect as useEffect9, useMemo as useMemo5, useState as useState11 } from "react";
|
|
11590
12086
|
import { useLocation as useLocation2 } from "react-router";
|
|
11591
12087
|
import { z as z35 } from "zod";
|
|
11592
|
-
import { jsxDEV as
|
|
12088
|
+
import { jsxDEV as jsxDEV22, Fragment as Fragment2 } from "@opentui/react/jsx-dev-runtime";
|
|
11593
12089
|
function getStatusColor2(status) {
|
|
11594
12090
|
if (status === "ok") {
|
|
11595
12091
|
return cliTheme.semantic.success;
|
|
@@ -11611,16 +12107,16 @@ function InfoRow({
|
|
|
11611
12107
|
tone
|
|
11612
12108
|
}) {
|
|
11613
12109
|
const valueColor = tone === "muted" || tone === undefined ? cliTheme.text.secondary : getStatusColor2(tone);
|
|
11614
|
-
return /* @__PURE__ */
|
|
12110
|
+
return /* @__PURE__ */ jsxDEV22("box", {
|
|
11615
12111
|
flexDirection: "row",
|
|
11616
12112
|
gap: 1,
|
|
11617
12113
|
children: [
|
|
11618
|
-
/* @__PURE__ */
|
|
12114
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11619
12115
|
fg: cliTheme.text.muted,
|
|
11620
12116
|
width: 24,
|
|
11621
12117
|
children: label
|
|
11622
12118
|
}, undefined, false, undefined, this),
|
|
11623
|
-
/* @__PURE__ */
|
|
12119
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11624
12120
|
fg: valueColor,
|
|
11625
12121
|
children: formatNullable(value)
|
|
11626
12122
|
}, undefined, false, undefined, this)
|
|
@@ -11631,7 +12127,7 @@ function Section({
|
|
|
11631
12127
|
title,
|
|
11632
12128
|
children
|
|
11633
12129
|
}) {
|
|
11634
|
-
return /* @__PURE__ */
|
|
12130
|
+
return /* @__PURE__ */ jsxDEV22("box", {
|
|
11635
12131
|
flexDirection: "column",
|
|
11636
12132
|
gap: 1,
|
|
11637
12133
|
paddingX: 1,
|
|
@@ -11640,9 +12136,9 @@ function Section({
|
|
|
11640
12136
|
borderColor: cliTheme.borders.subtle,
|
|
11641
12137
|
backgroundColor: cliTheme.surfaces.panel,
|
|
11642
12138
|
children: [
|
|
11643
|
-
/* @__PURE__ */
|
|
12139
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11644
12140
|
fg: cliTheme.accent.primary,
|
|
11645
|
-
attributes:
|
|
12141
|
+
attributes: TextAttributes16.BOLD,
|
|
11646
12142
|
children: title
|
|
11647
12143
|
}, undefined, false, undefined, this),
|
|
11648
12144
|
children
|
|
@@ -11653,123 +12149,123 @@ function renderStatus(payload, routeState) {
|
|
|
11653
12149
|
const parsedRouteState = diagnosticsRouteStateSchema.safeParse(routeState);
|
|
11654
12150
|
const currentSession = parsedRouteState.success ? parsedRouteState.data : {};
|
|
11655
12151
|
const latestSession = payload.sessions.latest;
|
|
11656
|
-
return /* @__PURE__ */
|
|
12152
|
+
return /* @__PURE__ */ jsxDEV22(Fragment2, {
|
|
11657
12153
|
children: [
|
|
11658
|
-
/* @__PURE__ */
|
|
12154
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11659
12155
|
title: "Current Chat",
|
|
11660
12156
|
children: [
|
|
11661
|
-
/* @__PURE__ */
|
|
12157
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11662
12158
|
label: "Session",
|
|
11663
12159
|
value: currentSession.sessionId ?? "not in chat"
|
|
11664
12160
|
}, undefined, false, undefined, this),
|
|
11665
|
-
/* @__PURE__ */
|
|
12161
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11666
12162
|
label: "Mode",
|
|
11667
12163
|
value: currentSession.mode ?? "not set"
|
|
11668
12164
|
}, undefined, false, undefined, this),
|
|
11669
|
-
/* @__PURE__ */
|
|
12165
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11670
12166
|
label: "Permission mode",
|
|
11671
12167
|
value: currentSession.permissionMode ?? "not set"
|
|
11672
12168
|
}, undefined, false, undefined, this),
|
|
11673
|
-
/* @__PURE__ */
|
|
12169
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11674
12170
|
label: "CWD",
|
|
11675
12171
|
value: currentSession.cwd ?? payload.server.cwd
|
|
11676
12172
|
}, undefined, false, undefined, this),
|
|
11677
|
-
/* @__PURE__ */
|
|
12173
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11678
12174
|
label: "Messages",
|
|
11679
12175
|
value: currentSession.messageCount ?? null
|
|
11680
12176
|
}, undefined, false, undefined, this),
|
|
11681
|
-
/* @__PURE__ */
|
|
12177
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11682
12178
|
label: "Pending approvals",
|
|
11683
12179
|
value: currentSession.pendingApprovalCount ?? 0,
|
|
11684
12180
|
tone: (currentSession.pendingApprovalCount ?? 0) > 0 ? "warn" : "ok"
|
|
11685
12181
|
}, undefined, false, undefined, this)
|
|
11686
12182
|
]
|
|
11687
12183
|
}, undefined, true, undefined, this),
|
|
11688
|
-
/* @__PURE__ */
|
|
12184
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11689
12185
|
title: "Runtime",
|
|
11690
12186
|
children: [
|
|
11691
|
-
/* @__PURE__ */
|
|
12187
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11692
12188
|
label: "Server",
|
|
11693
12189
|
value: payload.server.status,
|
|
11694
12190
|
tone: payload.server.status
|
|
11695
12191
|
}, undefined, false, undefined, this),
|
|
11696
|
-
/* @__PURE__ */
|
|
12192
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11697
12193
|
label: "Provider",
|
|
11698
12194
|
value: payload.provider.provider,
|
|
11699
12195
|
tone: payload.provider.status
|
|
11700
12196
|
}, undefined, false, undefined, this),
|
|
11701
|
-
/* @__PURE__ */
|
|
12197
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11702
12198
|
label: "Model",
|
|
11703
12199
|
value: payload.provider.model
|
|
11704
12200
|
}, undefined, false, undefined, this),
|
|
11705
|
-
/* @__PURE__ */
|
|
12201
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11706
12202
|
label: "Database",
|
|
11707
12203
|
value: payload.database.status,
|
|
11708
12204
|
tone: payload.database.status
|
|
11709
12205
|
}, undefined, false, undefined, this),
|
|
11710
|
-
/* @__PURE__ */
|
|
12206
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11711
12207
|
label: "Tool count",
|
|
11712
12208
|
value: payload.tools.total
|
|
11713
12209
|
}, undefined, false, undefined, this),
|
|
11714
|
-
/* @__PURE__ */
|
|
12210
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11715
12211
|
label: "Schema status",
|
|
11716
12212
|
value: payload.tools.providerSchemaStatus,
|
|
11717
12213
|
tone: payload.tools.providerSchemaStatus
|
|
11718
12214
|
}, undefined, false, undefined, this)
|
|
11719
12215
|
]
|
|
11720
12216
|
}, undefined, true, undefined, this),
|
|
11721
|
-
/* @__PURE__ */
|
|
12217
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11722
12218
|
title: "Extensions",
|
|
11723
12219
|
children: [
|
|
11724
|
-
/* @__PURE__ */
|
|
12220
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11725
12221
|
label: "Skills",
|
|
11726
12222
|
value: payload.extensions.skills.count
|
|
11727
12223
|
}, undefined, false, undefined, this),
|
|
11728
|
-
/* @__PURE__ */
|
|
12224
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11729
12225
|
label: "MCP servers",
|
|
11730
12226
|
value: payload.extensions.mcp.configuredServers
|
|
11731
12227
|
}, undefined, false, undefined, this),
|
|
11732
|
-
/* @__PURE__ */
|
|
12228
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11733
12229
|
label: "MCP running",
|
|
11734
12230
|
value: payload.extensions.mcp.runningServers
|
|
11735
12231
|
}, undefined, false, undefined, this),
|
|
11736
|
-
/* @__PURE__ */
|
|
12232
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11737
12233
|
label: "MCP degraded",
|
|
11738
12234
|
value: payload.extensions.mcp.degradedServers,
|
|
11739
12235
|
tone: payload.extensions.mcp.degradedServers > 0 ? "warn" : "ok"
|
|
11740
12236
|
}, undefined, false, undefined, this),
|
|
11741
|
-
/* @__PURE__ */
|
|
12237
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11742
12238
|
label: "Plugins",
|
|
11743
12239
|
value: payload.extensions.plugins.count
|
|
11744
12240
|
}, undefined, false, undefined, this),
|
|
11745
|
-
/* @__PURE__ */
|
|
12241
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11746
12242
|
label: "Plugin hooks",
|
|
11747
12243
|
value: payload.extensions.plugins.hooks
|
|
11748
12244
|
}, undefined, false, undefined, this)
|
|
11749
12245
|
]
|
|
11750
12246
|
}, undefined, true, undefined, this),
|
|
11751
|
-
/* @__PURE__ */
|
|
12247
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11752
12248
|
title: "Latest Saved Session",
|
|
11753
|
-
children: latestSession ? /* @__PURE__ */
|
|
12249
|
+
children: latestSession ? /* @__PURE__ */ jsxDEV22(Fragment2, {
|
|
11754
12250
|
children: [
|
|
11755
|
-
/* @__PURE__ */
|
|
12251
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11756
12252
|
label: "Session",
|
|
11757
12253
|
value: latestSession.id
|
|
11758
12254
|
}, undefined, false, undefined, this),
|
|
11759
|
-
/* @__PURE__ */
|
|
12255
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11760
12256
|
label: "Title",
|
|
11761
12257
|
value: latestSession.title ?? latestSession.latestUserPromptPreview
|
|
11762
12258
|
}, undefined, false, undefined, this),
|
|
11763
|
-
/* @__PURE__ */
|
|
12259
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11764
12260
|
label: "Messages",
|
|
11765
12261
|
value: latestSession.messageCount
|
|
11766
12262
|
}, undefined, false, undefined, this),
|
|
11767
|
-
/* @__PURE__ */
|
|
12263
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11768
12264
|
label: "Updated",
|
|
11769
12265
|
value: formatDate2(latestSession.updatedAt)
|
|
11770
12266
|
}, undefined, false, undefined, this)
|
|
11771
12267
|
]
|
|
11772
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */
|
|
12268
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV22("text", {
|
|
11773
12269
|
fg: cliTheme.text.muted,
|
|
11774
12270
|
children: "No saved sessions yet."
|
|
11775
12271
|
}, undefined, false, undefined, this)
|
|
@@ -11778,36 +12274,36 @@ function renderStatus(payload, routeState) {
|
|
|
11778
12274
|
}, undefined, true, undefined, this);
|
|
11779
12275
|
}
|
|
11780
12276
|
function renderDoctor(payload) {
|
|
11781
|
-
return /* @__PURE__ */
|
|
12277
|
+
return /* @__PURE__ */ jsxDEV22(Section, {
|
|
11782
12278
|
title: `Overall: ${payload.status}`,
|
|
11783
|
-
children: payload.checks.map((check) => /* @__PURE__ */
|
|
12279
|
+
children: payload.checks.map((check) => /* @__PURE__ */ jsxDEV22("box", {
|
|
11784
12280
|
flexDirection: "column",
|
|
11785
12281
|
paddingY: 1,
|
|
11786
12282
|
children: [
|
|
11787
|
-
/* @__PURE__ */
|
|
12283
|
+
/* @__PURE__ */ jsxDEV22("box", {
|
|
11788
12284
|
flexDirection: "row",
|
|
11789
12285
|
gap: 1,
|
|
11790
12286
|
children: [
|
|
11791
|
-
/* @__PURE__ */
|
|
12287
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11792
12288
|
fg: getStatusColor2(check.status),
|
|
11793
|
-
attributes:
|
|
12289
|
+
attributes: TextAttributes16.BOLD,
|
|
11794
12290
|
width: 8,
|
|
11795
12291
|
children: check.status.toUpperCase()
|
|
11796
12292
|
}, undefined, false, undefined, this),
|
|
11797
|
-
/* @__PURE__ */
|
|
12293
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11798
12294
|
fg: cliTheme.text.primary,
|
|
11799
|
-
attributes:
|
|
12295
|
+
attributes: TextAttributes16.BOLD,
|
|
11800
12296
|
children: check.label
|
|
11801
12297
|
}, undefined, false, undefined, this)
|
|
11802
12298
|
]
|
|
11803
12299
|
}, undefined, true, undefined, this),
|
|
11804
|
-
/* @__PURE__ */
|
|
12300
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11805
12301
|
fg: cliTheme.text.secondary,
|
|
11806
12302
|
children: check.summary
|
|
11807
12303
|
}, undefined, false, undefined, this),
|
|
11808
|
-
check.details.map((detail) => /* @__PURE__ */
|
|
12304
|
+
check.details.map((detail) => /* @__PURE__ */ jsxDEV22("text", {
|
|
11809
12305
|
fg: cliTheme.text.muted,
|
|
11810
|
-
attributes:
|
|
12306
|
+
attributes: TextAttributes16.DIM,
|
|
11811
12307
|
children: detail
|
|
11812
12308
|
}, detail, false, undefined, this))
|
|
11813
12309
|
]
|
|
@@ -11817,111 +12313,111 @@ function renderDoctor(payload) {
|
|
|
11817
12313
|
function renderPermissions(payload, routeState) {
|
|
11818
12314
|
const parsedRouteState = diagnosticsRouteStateSchema.safeParse(routeState);
|
|
11819
12315
|
const currentSession = parsedRouteState.success ? parsedRouteState.data : {};
|
|
11820
|
-
return /* @__PURE__ */
|
|
12316
|
+
return /* @__PURE__ */ jsxDEV22(Fragment2, {
|
|
11821
12317
|
children: [
|
|
11822
|
-
/* @__PURE__ */
|
|
12318
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11823
12319
|
title: "Current Chat",
|
|
11824
12320
|
children: [
|
|
11825
|
-
/* @__PURE__ */
|
|
12321
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11826
12322
|
label: "Mode",
|
|
11827
12323
|
value: currentSession.mode ?? payload.defaultMode
|
|
11828
12324
|
}, undefined, false, undefined, this),
|
|
11829
|
-
/* @__PURE__ */
|
|
12325
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11830
12326
|
label: "Permission mode",
|
|
11831
12327
|
value: currentSession.permissionMode ?? payload.effectivePermissionMode
|
|
11832
12328
|
}, undefined, false, undefined, this),
|
|
11833
|
-
/* @__PURE__ */
|
|
12329
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11834
12330
|
label: "Pending approvals",
|
|
11835
12331
|
value: currentSession.pendingApprovalCount ?? 0,
|
|
11836
12332
|
tone: (currentSession.pendingApprovalCount ?? 0) > 0 ? "warn" : "ok"
|
|
11837
12333
|
}, undefined, false, undefined, this),
|
|
11838
|
-
/* @__PURE__ */
|
|
12334
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11839
12335
|
label: "Persisted pending",
|
|
11840
12336
|
value: payload.pendingInteractions.total,
|
|
11841
12337
|
tone: payload.pendingInteractions.total > 0 ? "warn" : "ok"
|
|
11842
12338
|
}, undefined, false, undefined, this)
|
|
11843
12339
|
]
|
|
11844
12340
|
}, undefined, true, undefined, this),
|
|
11845
|
-
/* @__PURE__ */
|
|
12341
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11846
12342
|
title: "Policy",
|
|
11847
12343
|
children: [
|
|
11848
|
-
/* @__PURE__ */
|
|
12344
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11849
12345
|
label: "Default mode",
|
|
11850
12346
|
value: payload.defaultMode
|
|
11851
12347
|
}, undefined, false, undefined, this),
|
|
11852
|
-
/* @__PURE__ */
|
|
12348
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11853
12349
|
label: "Configured permission",
|
|
11854
12350
|
value: payload.configuredPermissionMode
|
|
11855
12351
|
}, undefined, false, undefined, this),
|
|
11856
|
-
/* @__PURE__ */
|
|
12352
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11857
12353
|
label: "Effective permission",
|
|
11858
12354
|
value: payload.effectivePermissionMode
|
|
11859
12355
|
}, undefined, false, undefined, this),
|
|
11860
|
-
/* @__PURE__ */
|
|
12356
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11861
12357
|
label: "Allowed tools",
|
|
11862
12358
|
value: payload.allowedTools ? payload.allowedTools.join(", ") : "all policy-allowed tools"
|
|
11863
12359
|
}, undefined, false, undefined, this),
|
|
11864
|
-
/* @__PURE__ */
|
|
12360
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11865
12361
|
label: "Allow rules",
|
|
11866
12362
|
value: payload.rules.allow?.length ?? 0
|
|
11867
12363
|
}, undefined, false, undefined, this),
|
|
11868
|
-
/* @__PURE__ */
|
|
12364
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11869
12365
|
label: "Ask rules",
|
|
11870
12366
|
value: payload.rules.ask?.length ?? 0
|
|
11871
12367
|
}, undefined, false, undefined, this),
|
|
11872
|
-
/* @__PURE__ */
|
|
12368
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11873
12369
|
label: "Deny rules",
|
|
11874
12370
|
value: payload.rules.deny?.length ?? 0
|
|
11875
12371
|
}, undefined, false, undefined, this)
|
|
11876
12372
|
]
|
|
11877
12373
|
}, undefined, true, undefined, this),
|
|
11878
|
-
/* @__PURE__ */
|
|
12374
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11879
12375
|
title: "Recovery",
|
|
11880
12376
|
children: [
|
|
11881
|
-
/* @__PURE__ */
|
|
12377
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11882
12378
|
label: "Tool approvals",
|
|
11883
12379
|
value: payload.pendingInteractions.toolApprovals
|
|
11884
12380
|
}, undefined, false, undefined, this),
|
|
11885
|
-
/* @__PURE__ */
|
|
12381
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11886
12382
|
label: "User prompts",
|
|
11887
12383
|
value: payload.pendingInteractions.userPrompts
|
|
11888
12384
|
}, undefined, false, undefined, this),
|
|
11889
|
-
/* @__PURE__ */
|
|
12385
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11890
12386
|
label: "Stale pending",
|
|
11891
12387
|
value: payload.pendingInteractions.stale,
|
|
11892
12388
|
tone: payload.pendingInteractions.stale > 0 ? "warn" : "ok"
|
|
11893
12389
|
}, undefined, false, undefined, this),
|
|
11894
|
-
/* @__PURE__ */
|
|
12390
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11895
12391
|
label: "Recoverable",
|
|
11896
12392
|
value: payload.pendingInteractions.recoverable
|
|
11897
12393
|
}, undefined, false, undefined, this)
|
|
11898
12394
|
]
|
|
11899
12395
|
}, undefined, true, undefined, this),
|
|
11900
|
-
/* @__PURE__ */
|
|
12396
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11901
12397
|
title: "Sandbox",
|
|
11902
12398
|
children: [
|
|
11903
|
-
/* @__PURE__ */
|
|
12399
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11904
12400
|
label: "Enabled",
|
|
11905
12401
|
value: payload.sandbox.enabled ? "yes" : "no"
|
|
11906
12402
|
}, undefined, false, undefined, this),
|
|
11907
|
-
/* @__PURE__ */
|
|
12403
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11908
12404
|
label: "Mode",
|
|
11909
12405
|
value: payload.sandbox.mode
|
|
11910
12406
|
}, undefined, false, undefined, this),
|
|
11911
|
-
/* @__PURE__ */
|
|
12407
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11912
12408
|
label: "Supported",
|
|
11913
12409
|
value: payload.sandbox.supported ? "yes" : "no",
|
|
11914
12410
|
tone: payload.sandbox.supported ? "ok" : "warn"
|
|
11915
12411
|
}, undefined, false, undefined, this),
|
|
11916
|
-
payload.sandbox.unsupportedReason ? /* @__PURE__ */
|
|
12412
|
+
payload.sandbox.unsupportedReason ? /* @__PURE__ */ jsxDEV22("text", {
|
|
11917
12413
|
fg: cliTheme.semantic.warning,
|
|
11918
12414
|
children: payload.sandbox.unsupportedReason
|
|
11919
12415
|
}, undefined, false, undefined, this) : null
|
|
11920
12416
|
]
|
|
11921
12417
|
}, undefined, true, undefined, this),
|
|
11922
|
-
/* @__PURE__ */
|
|
12418
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11923
12419
|
title: "Notes",
|
|
11924
|
-
children: payload.notes.map((note) => /* @__PURE__ */
|
|
12420
|
+
children: payload.notes.map((note) => /* @__PURE__ */ jsxDEV22("text", {
|
|
11925
12421
|
fg: cliTheme.text.muted,
|
|
11926
12422
|
children: note
|
|
11927
12423
|
}, note, false, undefined, this))
|
|
@@ -11930,62 +12426,62 @@ function renderPermissions(payload, routeState) {
|
|
|
11930
12426
|
}, undefined, true, undefined, this);
|
|
11931
12427
|
}
|
|
11932
12428
|
function renderTools(payload) {
|
|
11933
|
-
return /* @__PURE__ */
|
|
12429
|
+
return /* @__PURE__ */ jsxDEV22(Fragment2, {
|
|
11934
12430
|
children: [
|
|
11935
|
-
/* @__PURE__ */
|
|
12431
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11936
12432
|
title: "Summary",
|
|
11937
12433
|
children: [
|
|
11938
|
-
/* @__PURE__ */
|
|
12434
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11939
12435
|
label: "Total",
|
|
11940
12436
|
value: payload.summary.total
|
|
11941
12437
|
}, undefined, false, undefined, this),
|
|
11942
|
-
/* @__PURE__ */
|
|
12438
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11943
12439
|
label: "Read-only",
|
|
11944
12440
|
value: payload.summary.readOnly
|
|
11945
12441
|
}, undefined, false, undefined, this),
|
|
11946
|
-
/* @__PURE__ */
|
|
12442
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11947
12443
|
label: "Workspace-write",
|
|
11948
12444
|
value: payload.summary.workspaceWrite
|
|
11949
12445
|
}, undefined, false, undefined, this),
|
|
11950
|
-
/* @__PURE__ */
|
|
12446
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11951
12447
|
label: "Danger-full-access",
|
|
11952
12448
|
value: payload.summary.dangerFullAccess
|
|
11953
12449
|
}, undefined, false, undefined, this),
|
|
11954
|
-
/* @__PURE__ */
|
|
12450
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
11955
12451
|
label: "Schema status",
|
|
11956
12452
|
value: payload.summary.providerSchemaStatus,
|
|
11957
12453
|
tone: payload.summary.providerSchemaStatus
|
|
11958
12454
|
}, undefined, false, undefined, this)
|
|
11959
12455
|
]
|
|
11960
12456
|
}, undefined, true, undefined, this),
|
|
11961
|
-
/* @__PURE__ */
|
|
12457
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
11962
12458
|
title: "Tool Catalog",
|
|
11963
|
-
children: payload.tools.map((tool2) => /* @__PURE__ */
|
|
12459
|
+
children: payload.tools.map((tool2) => /* @__PURE__ */ jsxDEV22("box", {
|
|
11964
12460
|
flexDirection: "column",
|
|
11965
12461
|
paddingY: 1,
|
|
11966
12462
|
children: [
|
|
11967
|
-
/* @__PURE__ */
|
|
12463
|
+
/* @__PURE__ */ jsxDEV22("box", {
|
|
11968
12464
|
flexDirection: "row",
|
|
11969
12465
|
justifyContent: "space-between",
|
|
11970
12466
|
children: [
|
|
11971
|
-
/* @__PURE__ */
|
|
12467
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11972
12468
|
fg: cliTheme.text.primary,
|
|
11973
|
-
attributes:
|
|
12469
|
+
attributes: TextAttributes16.BOLD,
|
|
11974
12470
|
children: tool2.name
|
|
11975
12471
|
}, undefined, false, undefined, this),
|
|
11976
|
-
/* @__PURE__ */
|
|
12472
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11977
12473
|
fg: getStatusColor2(tool2.providerSchemaStatus),
|
|
11978
12474
|
children: tool2.permissionMode
|
|
11979
12475
|
}, undefined, false, undefined, this)
|
|
11980
12476
|
]
|
|
11981
12477
|
}, undefined, true, undefined, this),
|
|
11982
|
-
/* @__PURE__ */
|
|
12478
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11983
12479
|
fg: cliTheme.text.secondary,
|
|
11984
12480
|
children: tool2.description
|
|
11985
12481
|
}, undefined, false, undefined, this),
|
|
11986
|
-
/* @__PURE__ */
|
|
12482
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
11987
12483
|
fg: cliTheme.text.muted,
|
|
11988
|
-
attributes:
|
|
12484
|
+
attributes: TextAttributes16.DIM,
|
|
11989
12485
|
children: [
|
|
11990
12486
|
"Modes: ",
|
|
11991
12487
|
tool2.activeInModes.join(", ") || "none",
|
|
@@ -12000,51 +12496,51 @@ function renderTools(payload) {
|
|
|
12000
12496
|
}, undefined, true, undefined, this);
|
|
12001
12497
|
}
|
|
12002
12498
|
function renderConfig(payload) {
|
|
12003
|
-
return /* @__PURE__ */
|
|
12499
|
+
return /* @__PURE__ */ jsxDEV22(Fragment2, {
|
|
12004
12500
|
children: [
|
|
12005
|
-
/* @__PURE__ */
|
|
12501
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
12006
12502
|
title: "Effective Config",
|
|
12007
12503
|
children: [
|
|
12008
|
-
/* @__PURE__ */
|
|
12504
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12009
12505
|
label: "Provider",
|
|
12010
12506
|
value: payload.selectedProvider
|
|
12011
12507
|
}, undefined, false, undefined, this),
|
|
12012
|
-
/* @__PURE__ */
|
|
12508
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12013
12509
|
label: "Configured model",
|
|
12014
12510
|
value: payload.configuredModel
|
|
12015
12511
|
}, undefined, false, undefined, this),
|
|
12016
|
-
/* @__PURE__ */
|
|
12512
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12017
12513
|
label: "Selected model",
|
|
12018
12514
|
value: payload.selectedModel
|
|
12019
12515
|
}, undefined, false, undefined, this),
|
|
12020
|
-
/* @__PURE__ */
|
|
12516
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12021
12517
|
label: "Base URL",
|
|
12022
12518
|
value: payload.baseUrl ? "configured" : "default"
|
|
12023
12519
|
}, undefined, false, undefined, this),
|
|
12024
|
-
/* @__PURE__ */
|
|
12520
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12025
12521
|
label: "Default mode",
|
|
12026
12522
|
value: payload.defaultMode
|
|
12027
12523
|
}, undefined, false, undefined, this),
|
|
12028
|
-
/* @__PURE__ */
|
|
12524
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12029
12525
|
label: "Permission mode",
|
|
12030
12526
|
value: payload.permissionMode
|
|
12031
12527
|
}, undefined, false, undefined, this),
|
|
12032
|
-
/* @__PURE__ */
|
|
12528
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12033
12529
|
label: "Max output tokens",
|
|
12034
12530
|
value: payload.maxOutputTokens
|
|
12035
12531
|
}, undefined, false, undefined, this),
|
|
12036
|
-
/* @__PURE__ */
|
|
12532
|
+
/* @__PURE__ */ jsxDEV22(InfoRow, {
|
|
12037
12533
|
label: "Max steps",
|
|
12038
12534
|
value: payload.maxSteps
|
|
12039
12535
|
}, undefined, false, undefined, this)
|
|
12040
12536
|
]
|
|
12041
12537
|
}, undefined, true, undefined, this),
|
|
12042
|
-
/* @__PURE__ */
|
|
12538
|
+
/* @__PURE__ */ jsxDEV22(Section, {
|
|
12043
12539
|
title: "Loaded Files",
|
|
12044
|
-
children: payload.loadedFiles.map((file) => /* @__PURE__ */
|
|
12540
|
+
children: payload.loadedFiles.map((file) => /* @__PURE__ */ jsxDEV22("box", {
|
|
12045
12541
|
flexDirection: "column",
|
|
12046
12542
|
children: [
|
|
12047
|
-
/* @__PURE__ */
|
|
12543
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
12048
12544
|
fg: file.loaded ? cliTheme.semantic.success : cliTheme.text.muted,
|
|
12049
12545
|
children: [
|
|
12050
12546
|
file.scope,
|
|
@@ -12052,17 +12548,17 @@ function renderConfig(payload) {
|
|
|
12052
12548
|
file.loaded ? "loaded" : file.exists ? "not loaded" : "missing"
|
|
12053
12549
|
]
|
|
12054
12550
|
}, undefined, true, undefined, this),
|
|
12055
|
-
/* @__PURE__ */
|
|
12551
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
12056
12552
|
fg: cliTheme.text.muted,
|
|
12057
|
-
attributes:
|
|
12553
|
+
attributes: TextAttributes16.DIM,
|
|
12058
12554
|
children: file.path
|
|
12059
12555
|
}, undefined, false, undefined, this)
|
|
12060
12556
|
]
|
|
12061
12557
|
}, `${file.scope}:${file.path}`, true, undefined, this))
|
|
12062
12558
|
}, undefined, false, undefined, this),
|
|
12063
|
-
payload.missingCredentialHints.length > 0 ? /* @__PURE__ */
|
|
12559
|
+
payload.missingCredentialHints.length > 0 ? /* @__PURE__ */ jsxDEV22(Section, {
|
|
12064
12560
|
title: "Credential Hints",
|
|
12065
|
-
children: payload.missingCredentialHints.map((hint) => /* @__PURE__ */
|
|
12561
|
+
children: payload.missingCredentialHints.map((hint) => /* @__PURE__ */ jsxDEV22("text", {
|
|
12066
12562
|
fg: cliTheme.semantic.warning,
|
|
12067
12563
|
children: hint
|
|
12068
12564
|
}, hint, false, undefined, this))
|
|
@@ -12136,36 +12632,36 @@ function DiagnosticsScreen({ kind }) {
|
|
|
12136
12632
|
}
|
|
12137
12633
|
return renderConfig(payload);
|
|
12138
12634
|
}, [kind, location.state, payload]);
|
|
12139
|
-
return /* @__PURE__ */
|
|
12635
|
+
return /* @__PURE__ */ jsxDEV22("box", {
|
|
12140
12636
|
width: "100%",
|
|
12141
12637
|
height: "100%",
|
|
12142
12638
|
flexDirection: "column",
|
|
12143
12639
|
gap: 1,
|
|
12144
12640
|
children: [
|
|
12145
|
-
/* @__PURE__ */
|
|
12641
|
+
/* @__PURE__ */ jsxDEV22("box", {
|
|
12146
12642
|
flexDirection: "row",
|
|
12147
12643
|
justifyContent: "space-between",
|
|
12148
12644
|
paddingX: 1,
|
|
12149
12645
|
children: [
|
|
12150
|
-
/* @__PURE__ */
|
|
12646
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
12151
12647
|
fg: cliTheme.text.primary,
|
|
12152
|
-
attributes:
|
|
12648
|
+
attributes: TextAttributes16.BOLD,
|
|
12153
12649
|
children: title
|
|
12154
12650
|
}, undefined, false, undefined, this),
|
|
12155
|
-
/* @__PURE__ */
|
|
12651
|
+
/* @__PURE__ */ jsxDEV22("text", {
|
|
12156
12652
|
fg: cliTheme.text.muted,
|
|
12157
12653
|
children: isLoading ? "loading..." : "press r to refresh"
|
|
12158
12654
|
}, undefined, false, undefined, this)
|
|
12159
12655
|
]
|
|
12160
12656
|
}, undefined, true, undefined, this),
|
|
12161
|
-
errorMessage ? /* @__PURE__ */
|
|
12657
|
+
errorMessage ? /* @__PURE__ */ jsxDEV22("box", {
|
|
12162
12658
|
paddingX: 1,
|
|
12163
|
-
children: /* @__PURE__ */
|
|
12659
|
+
children: /* @__PURE__ */ jsxDEV22("text", {
|
|
12164
12660
|
fg: cliTheme.semantic.error,
|
|
12165
12661
|
children: errorMessage
|
|
12166
12662
|
}, undefined, false, undefined, this)
|
|
12167
12663
|
}, undefined, false, undefined, this) : null,
|
|
12168
|
-
/* @__PURE__ */
|
|
12664
|
+
/* @__PURE__ */ jsxDEV22("scrollbox", {
|
|
12169
12665
|
flexGrow: 1,
|
|
12170
12666
|
flexDirection: "column",
|
|
12171
12667
|
gap: 1,
|
|
@@ -12198,12 +12694,12 @@ var init_diagnostics_screen = __esm(() => {
|
|
|
12198
12694
|
});
|
|
12199
12695
|
|
|
12200
12696
|
// apps/cli/src/components/home-ascii-art.tsx
|
|
12201
|
-
import { jsxDEV as
|
|
12697
|
+
import { jsxDEV as jsxDEV23 } from "@opentui/react/jsx-dev-runtime";
|
|
12202
12698
|
function HomeAsciiArt() {
|
|
12203
|
-
return /* @__PURE__ */
|
|
12699
|
+
return /* @__PURE__ */ jsxDEV23("box", {
|
|
12204
12700
|
flexDirection: "column",
|
|
12205
12701
|
alignItems: "center",
|
|
12206
|
-
children: /* @__PURE__ */
|
|
12702
|
+
children: /* @__PURE__ */ jsxDEV23("ascii-font", {
|
|
12207
12703
|
text: "lightcode",
|
|
12208
12704
|
font: "block",
|
|
12209
12705
|
color: logoColors
|
|
@@ -12221,7 +12717,7 @@ var init_home_ascii_art = __esm(() => {
|
|
|
12221
12717
|
import { useKeyboard as useKeyboard6 } from "@opentui/react";
|
|
12222
12718
|
import { useState as useState12 } from "react";
|
|
12223
12719
|
import { useNavigate as useNavigate2 } from "react-router";
|
|
12224
|
-
import { jsxDEV as
|
|
12720
|
+
import { jsxDEV as jsxDEV24 } from "@opentui/react/jsx-dev-runtime";
|
|
12225
12721
|
function HomeTextArea() {
|
|
12226
12722
|
const navigate = useNavigate2();
|
|
12227
12723
|
const {
|
|
@@ -12299,14 +12795,14 @@ function HomeTextArea() {
|
|
|
12299
12795
|
setIsCreatingSession(false);
|
|
12300
12796
|
}
|
|
12301
12797
|
}
|
|
12302
|
-
return /* @__PURE__ */
|
|
12798
|
+
return /* @__PURE__ */ jsxDEV24("box", {
|
|
12303
12799
|
width: "66%",
|
|
12304
12800
|
maxWidth: 104,
|
|
12305
12801
|
minWidth: 64,
|
|
12306
12802
|
flexDirection: "column",
|
|
12307
12803
|
gap: 1,
|
|
12308
12804
|
children: [
|
|
12309
|
-
/* @__PURE__ */
|
|
12805
|
+
/* @__PURE__ */ jsxDEV24(ChatTextArea, {
|
|
12310
12806
|
containerHeight: 7,
|
|
12311
12807
|
allowEmpty: true,
|
|
12312
12808
|
trimOnSubmit: false,
|
|
@@ -12316,7 +12812,7 @@ function HomeTextArea() {
|
|
|
12316
12812
|
modeToggleHint: true,
|
|
12317
12813
|
slashMenuOpen,
|
|
12318
12814
|
onTextChange: syncSlashMenuFromInput,
|
|
12319
|
-
beforeInput: slashMenuOpen ? /* @__PURE__ */
|
|
12815
|
+
beforeInput: slashMenuOpen ? /* @__PURE__ */ jsxDEV24(SlashPageMenu, {
|
|
12320
12816
|
query: slashMenuQuery,
|
|
12321
12817
|
selectedIndex,
|
|
12322
12818
|
routes: slashRoutes
|
|
@@ -12324,21 +12820,21 @@ function HomeTextArea() {
|
|
|
12324
12820
|
onSubmit: (text) => {
|
|
12325
12821
|
createSessionAndNavigate(text);
|
|
12326
12822
|
},
|
|
12327
|
-
footer: /* @__PURE__ */
|
|
12823
|
+
footer: /* @__PURE__ */ jsxDEV24("box", {
|
|
12328
12824
|
flexDirection: "row",
|
|
12329
12825
|
justifyContent: "space-between",
|
|
12330
12826
|
children: [
|
|
12331
|
-
/* @__PURE__ */
|
|
12827
|
+
/* @__PURE__ */ jsxDEV24("text", {
|
|
12332
12828
|
fg: cliTheme.text.muted,
|
|
12333
12829
|
children: isCreatingSession ? "Creating session..." : "Tab/Ctrl+T switch mode | Ctrl+P commands"
|
|
12334
12830
|
}, undefined, false, undefined, this),
|
|
12335
|
-
/* @__PURE__ */
|
|
12831
|
+
/* @__PURE__ */ jsxDEV24("text", {
|
|
12336
12832
|
children: [
|
|
12337
|
-
/* @__PURE__ */
|
|
12833
|
+
/* @__PURE__ */ jsxDEV24("span", {
|
|
12338
12834
|
fg: cliTheme.accent.primary,
|
|
12339
12835
|
children: modeDefinition.label
|
|
12340
12836
|
}, undefined, false, undefined, this),
|
|
12341
|
-
/* @__PURE__ */
|
|
12837
|
+
/* @__PURE__ */ jsxDEV24("span", {
|
|
12342
12838
|
fg: cliTheme.text.muted,
|
|
12343
12839
|
children: " mode"
|
|
12344
12840
|
}, undefined, false, undefined, this)
|
|
@@ -12347,9 +12843,9 @@ function HomeTextArea() {
|
|
|
12347
12843
|
]
|
|
12348
12844
|
}, undefined, true, undefined, this)
|
|
12349
12845
|
}, undefined, false, undefined, this),
|
|
12350
|
-
sessionCreateError ? /* @__PURE__ */
|
|
12846
|
+
sessionCreateError ? /* @__PURE__ */ jsxDEV24("box", {
|
|
12351
12847
|
paddingX: 1,
|
|
12352
|
-
children: /* @__PURE__ */
|
|
12848
|
+
children: /* @__PURE__ */ jsxDEV24("text", {
|
|
12353
12849
|
fg: cliTheme.semantic.error,
|
|
12354
12850
|
children: sessionCreateError
|
|
12355
12851
|
}, undefined, false, undefined, this)
|
|
@@ -12370,12 +12866,12 @@ var init_home_text_area = __esm(() => {
|
|
|
12370
12866
|
|
|
12371
12867
|
// apps/cli/src/components/server-status.tsx
|
|
12372
12868
|
import { useEffect as useEffect10, useState as useState13 } from "react";
|
|
12373
|
-
import { jsxDEV as
|
|
12869
|
+
import { jsxDEV as jsxDEV25 } from "@opentui/react/jsx-dev-runtime";
|
|
12374
12870
|
function ServerStatus() {
|
|
12375
12871
|
const [status, setStatus] = useState13("checking");
|
|
12376
12872
|
useEffect10(() => {
|
|
12377
12873
|
let cancelled = false;
|
|
12378
|
-
async function
|
|
12874
|
+
async function checkServer2() {
|
|
12379
12875
|
try {
|
|
12380
12876
|
if (!cancelled) {
|
|
12381
12877
|
const response = await fetch(apiBaseUrl);
|
|
@@ -12387,12 +12883,12 @@ function ServerStatus() {
|
|
|
12387
12883
|
}
|
|
12388
12884
|
}
|
|
12389
12885
|
}
|
|
12390
|
-
|
|
12886
|
+
checkServer2();
|
|
12391
12887
|
return () => {
|
|
12392
12888
|
cancelled = true;
|
|
12393
12889
|
};
|
|
12394
12890
|
}, []);
|
|
12395
|
-
return /* @__PURE__ */
|
|
12891
|
+
return /* @__PURE__ */ jsxDEV25("text", {
|
|
12396
12892
|
fg: serverStatusColors[status],
|
|
12397
12893
|
children: [
|
|
12398
12894
|
"Server: ",
|
|
@@ -12406,9 +12902,9 @@ var init_server_status = __esm(() => {
|
|
|
12406
12902
|
});
|
|
12407
12903
|
|
|
12408
12904
|
// apps/cli/src/screens/home-screen.tsx
|
|
12409
|
-
import { jsxDEV as
|
|
12905
|
+
import { jsxDEV as jsxDEV26 } from "@opentui/react/jsx-dev-runtime";
|
|
12410
12906
|
function HomeScreen() {
|
|
12411
|
-
return /* @__PURE__ */
|
|
12907
|
+
return /* @__PURE__ */ jsxDEV26("box", {
|
|
12412
12908
|
width: "100%",
|
|
12413
12909
|
height: "100%",
|
|
12414
12910
|
flexDirection: "column",
|
|
@@ -12419,9 +12915,9 @@ function HomeScreen() {
|
|
|
12419
12915
|
paddingY: 1,
|
|
12420
12916
|
backgroundColor: cliTheme.surfaces.base,
|
|
12421
12917
|
children: [
|
|
12422
|
-
/* @__PURE__ */
|
|
12423
|
-
/* @__PURE__ */
|
|
12424
|
-
/* @__PURE__ */
|
|
12918
|
+
/* @__PURE__ */ jsxDEV26(HomeAsciiArt, {}, undefined, false, undefined, this),
|
|
12919
|
+
/* @__PURE__ */ jsxDEV26(ServerStatus, {}, undefined, false, undefined, this),
|
|
12920
|
+
/* @__PURE__ */ jsxDEV26(HomeTextArea, {}, undefined, false, undefined, this)
|
|
12425
12921
|
]
|
|
12426
12922
|
}, undefined, true, undefined, this);
|
|
12427
12923
|
}
|
|
@@ -12433,10 +12929,10 @@ var init_home_screen = __esm(() => {
|
|
|
12433
12929
|
});
|
|
12434
12930
|
|
|
12435
12931
|
// apps/cli/src/screens/model-screen.tsx
|
|
12436
|
-
import { TextAttributes as
|
|
12932
|
+
import { TextAttributes as TextAttributes17 } from "@opentui/core";
|
|
12437
12933
|
import { useKeyboard as useKeyboard7 } from "@opentui/react";
|
|
12438
12934
|
import { useCallback as useCallback6, useEffect as useEffect11, useState as useState14 } from "react";
|
|
12439
|
-
import { jsxDEV as
|
|
12935
|
+
import { jsxDEV as jsxDEV27 } from "@opentui/react/jsx-dev-runtime";
|
|
12440
12936
|
function ModelScreen() {
|
|
12441
12937
|
const [isLoading, setIsLoading] = useState14(true);
|
|
12442
12938
|
const [payload, setPayload] = useState14(null);
|
|
@@ -12468,42 +12964,42 @@ function ModelScreen() {
|
|
|
12468
12964
|
keyEvent.stopPropagation();
|
|
12469
12965
|
loadModelConfig();
|
|
12470
12966
|
});
|
|
12471
|
-
return /* @__PURE__ */
|
|
12967
|
+
return /* @__PURE__ */ jsxDEV27("box", {
|
|
12472
12968
|
width: "100%",
|
|
12473
12969
|
height: "100%",
|
|
12474
12970
|
flexDirection: "column",
|
|
12475
12971
|
gap: 1,
|
|
12476
12972
|
paddingX: 1,
|
|
12477
12973
|
children: [
|
|
12478
|
-
/* @__PURE__ */
|
|
12974
|
+
/* @__PURE__ */ jsxDEV27("box", {
|
|
12479
12975
|
flexDirection: "row",
|
|
12480
12976
|
justifyContent: "space-between",
|
|
12481
12977
|
children: [
|
|
12482
|
-
/* @__PURE__ */
|
|
12978
|
+
/* @__PURE__ */ jsxDEV27("text", {
|
|
12483
12979
|
fg: cliTheme.text.primary,
|
|
12484
|
-
attributes:
|
|
12980
|
+
attributes: TextAttributes17.BOLD,
|
|
12485
12981
|
children: "Model"
|
|
12486
12982
|
}, undefined, false, undefined, this),
|
|
12487
|
-
/* @__PURE__ */
|
|
12983
|
+
/* @__PURE__ */ jsxDEV27("text", {
|
|
12488
12984
|
fg: cliTheme.text.muted,
|
|
12489
12985
|
children: isLoading ? "loading..." : "press r to refresh"
|
|
12490
12986
|
}, undefined, false, undefined, this)
|
|
12491
12987
|
]
|
|
12492
12988
|
}, undefined, true, undefined, this),
|
|
12493
|
-
errorMessage ? /* @__PURE__ */
|
|
12494
|
-
children: /* @__PURE__ */
|
|
12989
|
+
errorMessage ? /* @__PURE__ */ jsxDEV27("box", {
|
|
12990
|
+
children: /* @__PURE__ */ jsxDEV27("text", {
|
|
12495
12991
|
fg: cliTheme.semantic.error,
|
|
12496
12992
|
children: errorMessage
|
|
12497
12993
|
}, undefined, false, undefined, this)
|
|
12498
|
-
}, undefined, false, undefined, this) : payload ? /* @__PURE__ */
|
|
12994
|
+
}, undefined, false, undefined, this) : payload ? /* @__PURE__ */ jsxDEV27("scrollbox", {
|
|
12499
12995
|
flexGrow: 1,
|
|
12500
12996
|
flexDirection: "column",
|
|
12501
12997
|
gap: 1,
|
|
12502
12998
|
children: [
|
|
12503
|
-
/* @__PURE__ */
|
|
12999
|
+
/* @__PURE__ */ jsxDEV27(ModelInfo, {
|
|
12504
13000
|
payload
|
|
12505
13001
|
}, undefined, false, undefined, this),
|
|
12506
|
-
payload.missingCredentialHints.length > 0 ? /* @__PURE__ */
|
|
13002
|
+
payload.missingCredentialHints.length > 0 ? /* @__PURE__ */ jsxDEV27(CredentialHints, {
|
|
12507
13003
|
hints: payload.missingCredentialHints
|
|
12508
13004
|
}, undefined, false, undefined, this) : null
|
|
12509
13005
|
]
|
|
@@ -12513,7 +13009,7 @@ function ModelScreen() {
|
|
|
12513
13009
|
}
|
|
12514
13010
|
function ModelInfo({ payload }) {
|
|
12515
13011
|
const baseUrlStatus = payload.baseUrl ? "configured" : "default";
|
|
12516
|
-
return /* @__PURE__ */
|
|
13012
|
+
return /* @__PURE__ */ jsxDEV27("box", {
|
|
12517
13013
|
flexDirection: "column",
|
|
12518
13014
|
gap: 2,
|
|
12519
13015
|
paddingY: 1,
|
|
@@ -12521,19 +13017,19 @@ function ModelInfo({ payload }) {
|
|
|
12521
13017
|
borderColor: cliTheme.borders.subtle,
|
|
12522
13018
|
backgroundColor: cliTheme.surfaces.panel,
|
|
12523
13019
|
children: [
|
|
12524
|
-
/* @__PURE__ */
|
|
13020
|
+
/* @__PURE__ */ jsxDEV27(InfoRow2, {
|
|
12525
13021
|
label: "Provider",
|
|
12526
13022
|
value: payload.selectedProvider ?? "not set"
|
|
12527
13023
|
}, undefined, false, undefined, this),
|
|
12528
|
-
/* @__PURE__ */
|
|
13024
|
+
/* @__PURE__ */ jsxDEV27(InfoRow2, {
|
|
12529
13025
|
label: "Model",
|
|
12530
13026
|
value: payload.selectedModel ?? "not set"
|
|
12531
13027
|
}, undefined, false, undefined, this),
|
|
12532
|
-
/* @__PURE__ */
|
|
13028
|
+
/* @__PURE__ */ jsxDEV27(InfoRow2, {
|
|
12533
13029
|
label: "Base URL",
|
|
12534
13030
|
value: `${baseUrlStatus}${payload.baseUrl ? ` (${payload.baseUrl})` : ""}`
|
|
12535
13031
|
}, undefined, false, undefined, this),
|
|
12536
|
-
/* @__PURE__ */
|
|
13032
|
+
/* @__PURE__ */ jsxDEV27(InfoRow2, {
|
|
12537
13033
|
label: "Configured model",
|
|
12538
13034
|
value: payload.configuredModel ?? "not set"
|
|
12539
13035
|
}, undefined, false, undefined, this)
|
|
@@ -12541,16 +13037,16 @@ function ModelInfo({ payload }) {
|
|
|
12541
13037
|
}, undefined, true, undefined, this);
|
|
12542
13038
|
}
|
|
12543
13039
|
function InfoRow2({ label, value }) {
|
|
12544
|
-
return /* @__PURE__ */
|
|
13040
|
+
return /* @__PURE__ */ jsxDEV27("box", {
|
|
12545
13041
|
flexDirection: "row",
|
|
12546
13042
|
gap: 2,
|
|
12547
13043
|
children: [
|
|
12548
|
-
/* @__PURE__ */
|
|
13044
|
+
/* @__PURE__ */ jsxDEV27("text", {
|
|
12549
13045
|
fg: cliTheme.text.muted,
|
|
12550
13046
|
width: 18,
|
|
12551
13047
|
children: label
|
|
12552
13048
|
}, undefined, false, undefined, this),
|
|
12553
|
-
/* @__PURE__ */
|
|
13049
|
+
/* @__PURE__ */ jsxDEV27("text", {
|
|
12554
13050
|
fg: cliTheme.text.primary,
|
|
12555
13051
|
children: value
|
|
12556
13052
|
}, undefined, false, undefined, this)
|
|
@@ -12558,7 +13054,7 @@ function InfoRow2({ label, value }) {
|
|
|
12558
13054
|
}, undefined, true, undefined, this);
|
|
12559
13055
|
}
|
|
12560
13056
|
function CredentialHints({ hints }) {
|
|
12561
|
-
return /* @__PURE__ */
|
|
13057
|
+
return /* @__PURE__ */ jsxDEV27("box", {
|
|
12562
13058
|
flexDirection: "column",
|
|
12563
13059
|
gap: 1,
|
|
12564
13060
|
paddingY: 1,
|
|
@@ -12566,12 +13062,12 @@ function CredentialHints({ hints }) {
|
|
|
12566
13062
|
borderColor: cliTheme.borders.subtle,
|
|
12567
13063
|
backgroundColor: cliTheme.surfaces.panel,
|
|
12568
13064
|
children: [
|
|
12569
|
-
/* @__PURE__ */
|
|
13065
|
+
/* @__PURE__ */ jsxDEV27("text", {
|
|
12570
13066
|
fg: cliTheme.semantic.warning,
|
|
12571
|
-
attributes:
|
|
13067
|
+
attributes: TextAttributes17.BOLD,
|
|
12572
13068
|
children: "Missing Credentials"
|
|
12573
13069
|
}, undefined, false, undefined, this),
|
|
12574
|
-
hints.map((hint, index) => /* @__PURE__ */
|
|
13070
|
+
hints.map((hint, index) => /* @__PURE__ */ jsxDEV27("text", {
|
|
12575
13071
|
fg: cliTheme.text.secondary,
|
|
12576
13072
|
children: [
|
|
12577
13073
|
"- ",
|
|
@@ -12588,23 +13084,302 @@ var init_model_screen = __esm(() => {
|
|
|
12588
13084
|
init_text_utils();
|
|
12589
13085
|
});
|
|
12590
13086
|
|
|
12591
|
-
// apps/cli/src/
|
|
12592
|
-
import { TextAttributes as
|
|
13087
|
+
// apps/cli/src/components/chat/model-selector.tsx
|
|
13088
|
+
import { TextAttributes as TextAttributes18 } from "@opentui/core";
|
|
12593
13089
|
import { useKeyboard as useKeyboard8 } from "@opentui/react";
|
|
12594
|
-
import {
|
|
12595
|
-
import
|
|
12596
|
-
|
|
12597
|
-
|
|
13090
|
+
import { useEffect as useEffect12, useMemo as useMemo6, useState as useState15 } from "react";
|
|
13091
|
+
import { jsxDEV as jsxDEV28 } from "@opentui/react/jsx-dev-runtime";
|
|
13092
|
+
function formatContextLength(contextLength) {
|
|
13093
|
+
if (!contextLength) {
|
|
13094
|
+
return "ctx ?";
|
|
13095
|
+
}
|
|
13096
|
+
return `ctx ${Math.round(contextLength / 1000)}k`;
|
|
13097
|
+
}
|
|
13098
|
+
function ModelSelector({ onClose, notify }) {
|
|
13099
|
+
const [models, setModels] = useState15([]);
|
|
13100
|
+
const [currentModel, setCurrentModel] = useState15(null);
|
|
13101
|
+
const [loadError, setLoadError] = useState15(null);
|
|
13102
|
+
const [isLoading, setIsLoading] = useState15(true);
|
|
13103
|
+
const [isApplying, setIsApplying] = useState15(false);
|
|
13104
|
+
const [filter, setFilter] = useState15("");
|
|
13105
|
+
const [selectedIndex, setSelectedIndex] = useState15(0);
|
|
13106
|
+
useEffect12(() => {
|
|
13107
|
+
let cancelled = false;
|
|
13108
|
+
async function loadModels() {
|
|
13109
|
+
try {
|
|
13110
|
+
const [modelsResponse, statusResponse] = await Promise.all([
|
|
13111
|
+
client.config.models.$get({ query: { provider: "openrouter" } }),
|
|
13112
|
+
client.config.status.$get()
|
|
13113
|
+
]);
|
|
13114
|
+
if (!modelsResponse.ok) {
|
|
13115
|
+
throw new Error(`Server returned HTTP ${modelsResponse.status}`);
|
|
13116
|
+
}
|
|
13117
|
+
const payload = await modelsResponse.json();
|
|
13118
|
+
const loadedModels = "models" in payload ? payload.models : [];
|
|
13119
|
+
let activeModel = null;
|
|
13120
|
+
if (statusResponse.ok) {
|
|
13121
|
+
const status = await statusResponse.json();
|
|
13122
|
+
activeModel = status.selectedModel ?? null;
|
|
13123
|
+
}
|
|
13124
|
+
if (!cancelled) {
|
|
13125
|
+
setModels(loadedModels);
|
|
13126
|
+
setCurrentModel(activeModel);
|
|
13127
|
+
setIsLoading(false);
|
|
13128
|
+
}
|
|
13129
|
+
} catch (error) {
|
|
13130
|
+
if (!cancelled) {
|
|
13131
|
+
setLoadError(error instanceof Error ? error.message : "Unable to load models.");
|
|
13132
|
+
setIsLoading(false);
|
|
13133
|
+
}
|
|
13134
|
+
}
|
|
13135
|
+
}
|
|
13136
|
+
loadModels();
|
|
13137
|
+
return () => {
|
|
13138
|
+
cancelled = true;
|
|
13139
|
+
};
|
|
13140
|
+
}, []);
|
|
13141
|
+
const filteredModels = useMemo6(() => {
|
|
13142
|
+
const normalized = filter.trim().toLowerCase();
|
|
13143
|
+
if (!normalized) {
|
|
13144
|
+
return models;
|
|
13145
|
+
}
|
|
13146
|
+
return models.filter((model) => model.id.toLowerCase().includes(normalized) || model.name.toLowerCase().includes(normalized));
|
|
13147
|
+
}, [filter, models]);
|
|
13148
|
+
useEffect12(() => {
|
|
13149
|
+
setSelectedIndex((current) => Math.min(current, Math.max(filteredModels.length - 1, 0)));
|
|
13150
|
+
}, [filteredModels.length]);
|
|
13151
|
+
const applyModel = async (model) => {
|
|
13152
|
+
setIsApplying(true);
|
|
13153
|
+
try {
|
|
13154
|
+
const response = await client.config.model.$put({
|
|
13155
|
+
json: { provider: "openrouter", model: model.id }
|
|
13156
|
+
});
|
|
13157
|
+
if (!response.ok) {
|
|
13158
|
+
const body = await response.json().catch(() => null);
|
|
13159
|
+
throw new Error(body?.error ?? `Server returned HTTP ${response.status}`);
|
|
13160
|
+
}
|
|
13161
|
+
notify(`Model switched to ${model.id} (saved to settings.json).`);
|
|
13162
|
+
onClose();
|
|
13163
|
+
} catch (error) {
|
|
13164
|
+
notify(`Model switch failed: ${error instanceof Error ? error.message : "unknown error"}`, "error");
|
|
13165
|
+
setIsApplying(false);
|
|
13166
|
+
}
|
|
13167
|
+
};
|
|
13168
|
+
useKeyboard8((keyEvent) => {
|
|
13169
|
+
const keyName = keyEvent.name.toLowerCase();
|
|
13170
|
+
if (isEscapeKey(keyName)) {
|
|
13171
|
+
keyEvent.preventDefault();
|
|
13172
|
+
keyEvent.stopPropagation();
|
|
13173
|
+
onClose();
|
|
13174
|
+
return;
|
|
13175
|
+
}
|
|
13176
|
+
if (isApplying) {
|
|
13177
|
+
return;
|
|
13178
|
+
}
|
|
13179
|
+
if (isDownKey(keyName)) {
|
|
13180
|
+
keyEvent.preventDefault();
|
|
13181
|
+
keyEvent.stopPropagation();
|
|
13182
|
+
setSelectedIndex((current) => Math.min(current + 1, Math.max(filteredModels.length - 1, 0)));
|
|
13183
|
+
return;
|
|
13184
|
+
}
|
|
13185
|
+
if (isUpKey(keyName)) {
|
|
13186
|
+
keyEvent.preventDefault();
|
|
13187
|
+
keyEvent.stopPropagation();
|
|
13188
|
+
setSelectedIndex((current) => Math.max(current - 1, 0));
|
|
13189
|
+
return;
|
|
13190
|
+
}
|
|
13191
|
+
if (isEnterKey(keyName)) {
|
|
13192
|
+
keyEvent.preventDefault();
|
|
13193
|
+
keyEvent.stopPropagation();
|
|
13194
|
+
const selected = filteredModels[selectedIndex];
|
|
13195
|
+
if (selected) {
|
|
13196
|
+
applyModel(selected);
|
|
13197
|
+
}
|
|
13198
|
+
return;
|
|
13199
|
+
}
|
|
13200
|
+
if (isBackspaceKey(keyName, keyEvent.sequence)) {
|
|
13201
|
+
keyEvent.preventDefault();
|
|
13202
|
+
keyEvent.stopPropagation();
|
|
13203
|
+
setFilter((current) => current.slice(0, -1));
|
|
13204
|
+
return;
|
|
13205
|
+
}
|
|
13206
|
+
const sequence = keyEvent.sequence ?? "";
|
|
13207
|
+
if (sequence.length === 1 && !keyEvent.ctrl && !keyEvent.meta && sequence >= " " && sequence !== "\x7F") {
|
|
13208
|
+
keyEvent.preventDefault();
|
|
13209
|
+
keyEvent.stopPropagation();
|
|
13210
|
+
setFilter((current) => current + sequence);
|
|
13211
|
+
}
|
|
13212
|
+
});
|
|
13213
|
+
const windowStart = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisibleRows / 2), filteredModels.length - maxVisibleRows));
|
|
13214
|
+
const visibleModels = filteredModels.slice(windowStart, windowStart + maxVisibleRows);
|
|
13215
|
+
return /* @__PURE__ */ jsxDEV28("box", {
|
|
13216
|
+
width: "100%",
|
|
13217
|
+
flexDirection: "column",
|
|
13218
|
+
borderStyle: "single",
|
|
13219
|
+
borderColor: cliTheme.overlay.border,
|
|
13220
|
+
backgroundColor: cliTheme.overlay.surface,
|
|
13221
|
+
children: [
|
|
13222
|
+
/* @__PURE__ */ jsxDEV28("box", {
|
|
13223
|
+
width: "100%",
|
|
13224
|
+
flexDirection: "row",
|
|
13225
|
+
justifyContent: "space-between",
|
|
13226
|
+
paddingX: 2,
|
|
13227
|
+
paddingY: 1,
|
|
13228
|
+
borderStyle: "single",
|
|
13229
|
+
border: ["bottom"],
|
|
13230
|
+
borderColor: cliTheme.overlay.border,
|
|
13231
|
+
children: [
|
|
13232
|
+
/* @__PURE__ */ jsxDEV28("text", {
|
|
13233
|
+
fg: cliTheme.accent.primary,
|
|
13234
|
+
attributes: TextAttributes18.BOLD,
|
|
13235
|
+
children: "Switch Model (OpenRouter)"
|
|
13236
|
+
}, undefined, false, undefined, this),
|
|
13237
|
+
/* @__PURE__ */ jsxDEV28("text", {
|
|
13238
|
+
fg: cliTheme.overlay.footerText,
|
|
13239
|
+
children: "type to filter | \u2191/\u2193 select | Enter confirm | Esc cancel"
|
|
13240
|
+
}, undefined, false, undefined, this)
|
|
13241
|
+
]
|
|
13242
|
+
}, undefined, true, undefined, this),
|
|
13243
|
+
/* @__PURE__ */ jsxDEV28("box", {
|
|
13244
|
+
width: "100%",
|
|
13245
|
+
paddingX: 2,
|
|
13246
|
+
paddingY: 1,
|
|
13247
|
+
children: /* @__PURE__ */ jsxDEV28("text", {
|
|
13248
|
+
fg: cliTheme.text.primary,
|
|
13249
|
+
children: `Filter: ${filter}\u2588`
|
|
13250
|
+
}, undefined, false, undefined, this)
|
|
13251
|
+
}, undefined, false, undefined, this),
|
|
13252
|
+
isLoading ? /* @__PURE__ */ jsxDEV28("box", {
|
|
13253
|
+
paddingX: 2,
|
|
13254
|
+
paddingY: 1,
|
|
13255
|
+
children: /* @__PURE__ */ jsxDEV28("text", {
|
|
13256
|
+
fg: cliTheme.text.muted,
|
|
13257
|
+
children: "Loading models..."
|
|
13258
|
+
}, undefined, false, undefined, this)
|
|
13259
|
+
}, undefined, false, undefined, this) : loadError ? /* @__PURE__ */ jsxDEV28("box", {
|
|
13260
|
+
paddingX: 2,
|
|
13261
|
+
paddingY: 1,
|
|
13262
|
+
children: /* @__PURE__ */ jsxDEV28("text", {
|
|
13263
|
+
fg: cliTheme.semantic.error,
|
|
13264
|
+
children: loadError
|
|
13265
|
+
}, undefined, false, undefined, this)
|
|
13266
|
+
}, undefined, false, undefined, this) : filteredModels.length === 0 ? /* @__PURE__ */ jsxDEV28("box", {
|
|
13267
|
+
paddingX: 2,
|
|
13268
|
+
paddingY: 1,
|
|
13269
|
+
children: /* @__PURE__ */ jsxDEV28("text", {
|
|
13270
|
+
fg: cliTheme.text.muted,
|
|
13271
|
+
children: `No models match "${filter}".`
|
|
13272
|
+
}, undefined, false, undefined, this)
|
|
13273
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV28("box", {
|
|
13274
|
+
flexDirection: "column",
|
|
13275
|
+
paddingY: 1,
|
|
13276
|
+
children: [
|
|
13277
|
+
visibleModels.map((model, visibleIndex) => {
|
|
13278
|
+
const index = windowStart + visibleIndex;
|
|
13279
|
+
const isSelected = index === selectedIndex;
|
|
13280
|
+
const rowColors = getOverlayRowColors(isSelected);
|
|
13281
|
+
return /* @__PURE__ */ jsxDEV28("box", {
|
|
13282
|
+
width: "100%",
|
|
13283
|
+
flexDirection: "row",
|
|
13284
|
+
paddingX: 2,
|
|
13285
|
+
backgroundColor: rowColors.backgroundColor,
|
|
13286
|
+
children: [
|
|
13287
|
+
/* @__PURE__ */ jsxDEV28("text", {
|
|
13288
|
+
width: 2,
|
|
13289
|
+
fg: isSelected ? cliTheme.accent.primary : cliTheme.text.muted,
|
|
13290
|
+
attributes: TextAttributes18.BOLD,
|
|
13291
|
+
children: isSelected ? ">" : " "
|
|
13292
|
+
}, undefined, false, undefined, this),
|
|
13293
|
+
/* @__PURE__ */ jsxDEV28("text", {
|
|
13294
|
+
fg: isSelected ? cliTheme.overlay.selectedRowText : cliTheme.text.primary,
|
|
13295
|
+
attributes: isSelected ? TextAttributes18.BOLD : TextAttributes18.NONE,
|
|
13296
|
+
children: model.id
|
|
13297
|
+
}, undefined, false, undefined, this),
|
|
13298
|
+
/* @__PURE__ */ jsxDEV28("text", {
|
|
13299
|
+
fg: cliTheme.text.muted,
|
|
13300
|
+
marginLeft: 2,
|
|
13301
|
+
children: `${formatContextLength(model.contextLength)}${model.supportsTools ? " | tools" : ""}${model.supportsReasoning ? " | reasoning" : ""}`
|
|
13302
|
+
}, undefined, false, undefined, this),
|
|
13303
|
+
model.id === currentModel && /* @__PURE__ */ jsxDEV28("text", {
|
|
13304
|
+
fg: cliTheme.accent.primary,
|
|
13305
|
+
marginLeft: 2,
|
|
13306
|
+
children: "(current)"
|
|
13307
|
+
}, undefined, false, undefined, this)
|
|
13308
|
+
]
|
|
13309
|
+
}, model.id, true, undefined, this);
|
|
13310
|
+
}),
|
|
13311
|
+
/* @__PURE__ */ jsxDEV28("box", {
|
|
13312
|
+
paddingX: 2,
|
|
13313
|
+
marginTop: 1,
|
|
13314
|
+
children: /* @__PURE__ */ jsxDEV28("text", {
|
|
13315
|
+
fg: cliTheme.overlay.footerText,
|
|
13316
|
+
children: `${filteredModels.length} model${filteredModels.length === 1 ? "" : "s"}${isApplying ? " | switching..." : ""}`
|
|
13317
|
+
}, undefined, false, undefined, this)
|
|
13318
|
+
}, undefined, false, undefined, this)
|
|
13319
|
+
]
|
|
13320
|
+
}, undefined, true, undefined, this)
|
|
13321
|
+
]
|
|
13322
|
+
}, undefined, true, undefined, this);
|
|
13323
|
+
}
|
|
13324
|
+
var maxVisibleRows = 8;
|
|
13325
|
+
var init_model_selector = __esm(() => {
|
|
13326
|
+
init_client();
|
|
13327
|
+
init_cli_theme();
|
|
13328
|
+
});
|
|
13329
|
+
|
|
13330
|
+
// apps/cli/src/screens/model-select-screen.tsx
|
|
13331
|
+
import { TextAttributes as TextAttributes19 } from "@opentui/core";
|
|
13332
|
+
import { useState as useState16 } from "react";
|
|
12598
13333
|
import { useNavigate as useNavigate3 } from "react-router";
|
|
12599
|
-
import { jsxDEV as
|
|
13334
|
+
import { jsxDEV as jsxDEV29 } from "@opentui/react/jsx-dev-runtime";
|
|
13335
|
+
function ModelSelectScreen() {
|
|
13336
|
+
const navigate = useNavigate3();
|
|
13337
|
+
const [notice, setNotice] = useState16(null);
|
|
13338
|
+
return /* @__PURE__ */ jsxDEV29("box", {
|
|
13339
|
+
width: "100%",
|
|
13340
|
+
height: "100%",
|
|
13341
|
+
flexDirection: "column",
|
|
13342
|
+
gap: 1,
|
|
13343
|
+
paddingX: 1,
|
|
13344
|
+
children: [
|
|
13345
|
+
/* @__PURE__ */ jsxDEV29("text", {
|
|
13346
|
+
fg: cliTheme.text.primary,
|
|
13347
|
+
attributes: TextAttributes19.BOLD,
|
|
13348
|
+
children: "Switch Model"
|
|
13349
|
+
}, undefined, false, undefined, this),
|
|
13350
|
+
notice ? /* @__PURE__ */ jsxDEV29("text", {
|
|
13351
|
+
fg: notice.tone === "error" ? cliTheme.semantic.error : cliTheme.accent.primary,
|
|
13352
|
+
children: notice.text
|
|
13353
|
+
}, undefined, false, undefined, this) : null,
|
|
13354
|
+
/* @__PURE__ */ jsxDEV29(ModelSelector, {
|
|
13355
|
+
notify: (text, tone = "info") => setNotice({ text, tone }),
|
|
13356
|
+
onClose: () => navigate(-1)
|
|
13357
|
+
}, undefined, false, undefined, this)
|
|
13358
|
+
]
|
|
13359
|
+
}, undefined, true, undefined, this);
|
|
13360
|
+
}
|
|
13361
|
+
var init_model_select_screen = __esm(() => {
|
|
13362
|
+
init_model_selector();
|
|
13363
|
+
init_cli_theme();
|
|
13364
|
+
});
|
|
13365
|
+
|
|
13366
|
+
// apps/cli/src/screens/onboarding-screen.tsx
|
|
13367
|
+
import { TextAttributes as TextAttributes20 } from "@opentui/core";
|
|
13368
|
+
import { useKeyboard as useKeyboard9 } from "@opentui/react";
|
|
13369
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
13370
|
+
import os5 from "os";
|
|
13371
|
+
import path17 from "path";
|
|
13372
|
+
import { useCallback as useCallback7, useState as useState17 } from "react";
|
|
13373
|
+
import { useNavigate as useNavigate4 } from "react-router";
|
|
13374
|
+
import { jsxDEV as jsxDEV30 } from "@opentui/react/jsx-dev-runtime";
|
|
12600
13375
|
function getUserSettingsPath() {
|
|
12601
13376
|
const configured = process.env.LIGHTCODE_USER_CONFIG?.trim();
|
|
12602
|
-
return configured ??
|
|
13377
|
+
return configured ?? path17.join(os5.homedir(), ".lightcode", "settings.json");
|
|
12603
13378
|
}
|
|
12604
13379
|
function mergeUserSettings(update) {
|
|
12605
13380
|
const settingsPath = getUserSettingsPath();
|
|
12606
13381
|
let existing = {};
|
|
12607
|
-
if (
|
|
13382
|
+
if (existsSync8(settingsPath)) {
|
|
12608
13383
|
try {
|
|
12609
13384
|
const parsed = JSON.parse(readFileSync5(settingsPath, "utf8"));
|
|
12610
13385
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
@@ -12612,20 +13387,20 @@ function mergeUserSettings(update) {
|
|
|
12612
13387
|
}
|
|
12613
13388
|
} catch {}
|
|
12614
13389
|
}
|
|
12615
|
-
|
|
12616
|
-
|
|
13390
|
+
mkdirSync5(path17.dirname(settingsPath), { recursive: true });
|
|
13391
|
+
writeFileSync3(settingsPath, `${JSON.stringify({ ...existing, ...update }, null, 2)}
|
|
12617
13392
|
`, "utf8");
|
|
12618
13393
|
return settingsPath;
|
|
12619
13394
|
}
|
|
12620
13395
|
function OnboardingScreen() {
|
|
12621
|
-
const navigate =
|
|
13396
|
+
const navigate = useNavigate4();
|
|
12622
13397
|
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] =
|
|
13398
|
+
const [step, setStep] = useState17("provider");
|
|
13399
|
+
const [selectedIndex, setSelectedIndex] = useState17(0);
|
|
13400
|
+
const [apiKey, setApiKey] = useState17("");
|
|
13401
|
+
const [model, setModel] = useState17("");
|
|
13402
|
+
const [errorText, setErrorText] = useState17(null);
|
|
13403
|
+
const [serverRestarted, setServerRestarted] = useState17(false);
|
|
12629
13404
|
const provider = providerChoices[selectedIndex];
|
|
12630
13405
|
const completeSetup = useCallback7(async ({
|
|
12631
13406
|
finalModel,
|
|
@@ -12650,7 +13425,7 @@ function OnboardingScreen() {
|
|
|
12650
13425
|
setStep("apiKey");
|
|
12651
13426
|
}
|
|
12652
13427
|
}, [bumpConfigRefresh, provider]);
|
|
12653
|
-
|
|
13428
|
+
useKeyboard9((keyEvent) => {
|
|
12654
13429
|
if (step === "provider") {
|
|
12655
13430
|
if (isDownKey(keyEvent.name)) {
|
|
12656
13431
|
keyEvent.preventDefault();
|
|
@@ -12669,36 +13444,36 @@ function OnboardingScreen() {
|
|
|
12669
13444
|
navigate("/");
|
|
12670
13445
|
}
|
|
12671
13446
|
});
|
|
12672
|
-
return /* @__PURE__ */
|
|
13447
|
+
return /* @__PURE__ */ jsxDEV30("box", {
|
|
12673
13448
|
width: "100%",
|
|
12674
13449
|
height: "100%",
|
|
12675
13450
|
flexDirection: "column",
|
|
12676
13451
|
alignItems: "center",
|
|
12677
13452
|
paddingTop: 2,
|
|
12678
|
-
children: /* @__PURE__ */
|
|
13453
|
+
children: /* @__PURE__ */ jsxDEV30("box", {
|
|
12679
13454
|
width: 72,
|
|
12680
13455
|
flexDirection: "column",
|
|
12681
13456
|
gap: 1,
|
|
12682
13457
|
children: [
|
|
12683
|
-
/* @__PURE__ */
|
|
13458
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12684
13459
|
fg: cliTheme.accent.primary,
|
|
12685
|
-
attributes:
|
|
13460
|
+
attributes: TextAttributes20.BOLD,
|
|
12686
13461
|
children: "Welcome to Lightcode"
|
|
12687
13462
|
}, undefined, false, undefined, this),
|
|
12688
|
-
/* @__PURE__ */
|
|
13463
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12689
13464
|
fg: cliTheme.text.secondary,
|
|
12690
13465
|
children: "One-time setup: pick a model provider and store an API key."
|
|
12691
13466
|
}, undefined, false, undefined, this),
|
|
12692
|
-
/* @__PURE__ */
|
|
13467
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12693
13468
|
fg: cliTheme.text.muted,
|
|
12694
|
-
attributes:
|
|
13469
|
+
attributes: TextAttributes20.DIM,
|
|
12695
13470
|
children: "Keys are stored in ~/.lightcode/credentials.json (environment variables always take precedence)."
|
|
12696
13471
|
}, undefined, false, undefined, this),
|
|
12697
|
-
errorText ? /* @__PURE__ */
|
|
13472
|
+
errorText ? /* @__PURE__ */ jsxDEV30("text", {
|
|
12698
13473
|
fg: cliTheme.semantic.error,
|
|
12699
13474
|
children: errorText
|
|
12700
13475
|
}, undefined, false, undefined, this) : null,
|
|
12701
|
-
step === "provider" ? /* @__PURE__ */
|
|
13476
|
+
step === "provider" ? /* @__PURE__ */ jsxDEV30("box", {
|
|
12702
13477
|
flexDirection: "column",
|
|
12703
13478
|
borderStyle: "single",
|
|
12704
13479
|
borderColor: cliTheme.borders.default,
|
|
@@ -12706,53 +13481,53 @@ function OnboardingScreen() {
|
|
|
12706
13481
|
paddingX: 1,
|
|
12707
13482
|
paddingY: 1,
|
|
12708
13483
|
children: [
|
|
12709
|
-
/* @__PURE__ */
|
|
13484
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12710
13485
|
fg: cliTheme.text.primary,
|
|
12711
|
-
attributes:
|
|
13486
|
+
attributes: TextAttributes20.BOLD,
|
|
12712
13487
|
children: "Choose a provider"
|
|
12713
13488
|
}, undefined, false, undefined, this),
|
|
12714
|
-
providerChoices.map((choice, index) => /* @__PURE__ */
|
|
13489
|
+
providerChoices.map((choice, index) => /* @__PURE__ */ jsxDEV30("box", {
|
|
12715
13490
|
flexDirection: "row",
|
|
12716
13491
|
gap: 1,
|
|
12717
13492
|
backgroundColor: index === selectedIndex ? cliTheme.overlay.selectedRowBackground : undefined,
|
|
12718
13493
|
paddingX: 1,
|
|
12719
13494
|
children: [
|
|
12720
|
-
/* @__PURE__ */
|
|
13495
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12721
13496
|
fg: index === selectedIndex ? cliTheme.accent.primary : cliTheme.text.muted,
|
|
12722
13497
|
children: index === selectedIndex ? ">" : " "
|
|
12723
13498
|
}, undefined, false, undefined, this),
|
|
12724
|
-
/* @__PURE__ */
|
|
13499
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12725
13500
|
fg: index === selectedIndex ? cliTheme.overlay.selectedRowText : cliTheme.text.primary,
|
|
12726
|
-
attributes: index === selectedIndex ?
|
|
13501
|
+
attributes: index === selectedIndex ? TextAttributes20.BOLD : TextAttributes20.NONE,
|
|
12727
13502
|
children: choice.label
|
|
12728
13503
|
}, undefined, false, undefined, this),
|
|
12729
|
-
/* @__PURE__ */
|
|
13504
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12730
13505
|
fg: cliTheme.overlay.description,
|
|
12731
13506
|
children: choice.description
|
|
12732
13507
|
}, undefined, false, undefined, this)
|
|
12733
13508
|
]
|
|
12734
13509
|
}, choice.id, true, undefined, this)),
|
|
12735
|
-
/* @__PURE__ */
|
|
13510
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12736
13511
|
fg: cliTheme.text.muted,
|
|
12737
|
-
attributes:
|
|
13512
|
+
attributes: TextAttributes20.DIM,
|
|
12738
13513
|
children: "Up/Down select - Enter continue"
|
|
12739
13514
|
}, undefined, false, undefined, this)
|
|
12740
13515
|
]
|
|
12741
13516
|
}, undefined, true, undefined, this) : null,
|
|
12742
|
-
step === "apiKey" ? /* @__PURE__ */
|
|
13517
|
+
step === "apiKey" ? /* @__PURE__ */ jsxDEV30("box", {
|
|
12743
13518
|
flexDirection: "column",
|
|
12744
13519
|
gap: 1,
|
|
12745
13520
|
children: [
|
|
12746
|
-
/* @__PURE__ */
|
|
13521
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12747
13522
|
fg: cliTheme.text.primary,
|
|
12748
13523
|
children: `Paste your ${provider.label} API key and press Enter`
|
|
12749
13524
|
}, undefined, false, undefined, this),
|
|
12750
|
-
/* @__PURE__ */
|
|
13525
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12751
13526
|
fg: cliTheme.text.muted,
|
|
12752
|
-
attributes:
|
|
13527
|
+
attributes: TextAttributes20.DIM,
|
|
12753
13528
|
children: provider.keyHint
|
|
12754
13529
|
}, undefined, false, undefined, this),
|
|
12755
|
-
/* @__PURE__ */
|
|
13530
|
+
/* @__PURE__ */ jsxDEV30(ChatTextArea, {
|
|
12756
13531
|
placeholder: "API key...",
|
|
12757
13532
|
onSubmit: (text) => {
|
|
12758
13533
|
const trimmedKey = text.trim();
|
|
@@ -12769,15 +13544,15 @@ function OnboardingScreen() {
|
|
|
12769
13544
|
}, undefined, false, undefined, this)
|
|
12770
13545
|
]
|
|
12771
13546
|
}, undefined, true, undefined, this) : null,
|
|
12772
|
-
step === "model" ? /* @__PURE__ */
|
|
13547
|
+
step === "model" ? /* @__PURE__ */ jsxDEV30("box", {
|
|
12773
13548
|
flexDirection: "column",
|
|
12774
13549
|
gap: 1,
|
|
12775
13550
|
children: [
|
|
12776
|
-
/* @__PURE__ */
|
|
13551
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12777
13552
|
fg: cliTheme.text.primary,
|
|
12778
13553
|
children: `Model id for ${provider.label} (e.g. ${provider.id === "openrouter" ? "anthropic/claude-sonnet-4-6" : "your model id"})`
|
|
12779
13554
|
}, undefined, false, undefined, this),
|
|
12780
|
-
/* @__PURE__ */
|
|
13555
|
+
/* @__PURE__ */ jsxDEV30(ChatTextArea, {
|
|
12781
13556
|
placeholder: "Model id...",
|
|
12782
13557
|
onSubmit: (text) => {
|
|
12783
13558
|
const trimmedModel = text.trim();
|
|
@@ -12798,15 +13573,15 @@ function OnboardingScreen() {
|
|
|
12798
13573
|
}, undefined, false, undefined, this)
|
|
12799
13574
|
]
|
|
12800
13575
|
}, undefined, true, undefined, this) : null,
|
|
12801
|
-
step === "baseUrl" ? /* @__PURE__ */
|
|
13576
|
+
step === "baseUrl" ? /* @__PURE__ */ jsxDEV30("box", {
|
|
12802
13577
|
flexDirection: "column",
|
|
12803
13578
|
gap: 1,
|
|
12804
13579
|
children: [
|
|
12805
|
-
/* @__PURE__ */
|
|
13580
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12806
13581
|
fg: cliTheme.text.primary,
|
|
12807
13582
|
children: "Base URL of the OpenAI-compatible endpoint"
|
|
12808
13583
|
}, undefined, false, undefined, this),
|
|
12809
|
-
/* @__PURE__ */
|
|
13584
|
+
/* @__PURE__ */ jsxDEV30(ChatTextArea, {
|
|
12810
13585
|
placeholder: "https://...",
|
|
12811
13586
|
onSubmit: (text) => {
|
|
12812
13587
|
const trimmedBaseUrl = text.trim();
|
|
@@ -12822,24 +13597,24 @@ function OnboardingScreen() {
|
|
|
12822
13597
|
}, undefined, false, undefined, this)
|
|
12823
13598
|
]
|
|
12824
13599
|
}, undefined, true, undefined, this) : null,
|
|
12825
|
-
step === "saving" ? /* @__PURE__ */
|
|
13600
|
+
step === "saving" ? /* @__PURE__ */ jsxDEV30("text", {
|
|
12826
13601
|
fg: cliTheme.semantic.info,
|
|
12827
13602
|
children: "Saving configuration and restarting the server..."
|
|
12828
13603
|
}, undefined, false, undefined, this) : null,
|
|
12829
|
-
step === "done" ? /* @__PURE__ */
|
|
13604
|
+
step === "done" ? /* @__PURE__ */ jsxDEV30("box", {
|
|
12830
13605
|
flexDirection: "column",
|
|
12831
13606
|
gap: 1,
|
|
12832
13607
|
children: [
|
|
12833
|
-
/* @__PURE__ */
|
|
13608
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12834
13609
|
fg: cliTheme.semantic.success,
|
|
12835
|
-
attributes:
|
|
13610
|
+
attributes: TextAttributes20.BOLD,
|
|
12836
13611
|
children: "Setup complete"
|
|
12837
13612
|
}, undefined, false, undefined, this),
|
|
12838
|
-
/* @__PURE__ */
|
|
13613
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12839
13614
|
fg: cliTheme.text.secondary,
|
|
12840
13615
|
children: serverRestarted ? "The local server was restarted with your new configuration." : "Restart the Lightcode server to pick up the new configuration."
|
|
12841
13616
|
}, undefined, false, undefined, this),
|
|
12842
|
-
/* @__PURE__ */
|
|
13617
|
+
/* @__PURE__ */ jsxDEV30("text", {
|
|
12843
13618
|
fg: cliTheme.text.muted,
|
|
12844
13619
|
children: "Press Enter to start coding."
|
|
12845
13620
|
}, undefined, false, undefined, this)
|
|
@@ -12898,12 +13673,11 @@ var init_onboarding_screen = __esm(() => {
|
|
|
12898
13673
|
});
|
|
12899
13674
|
|
|
12900
13675
|
// 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";
|
|
13676
|
+
import { TextAttributes as TextAttributes21 } from "@opentui/core";
|
|
13677
|
+
import { useKeyboard as useKeyboard10 } from "@opentui/react";
|
|
13678
|
+
import { useCallback as useCallback8, useEffect as useEffect13, useMemo as useMemo7, useState as useState18 } from "react";
|
|
13679
|
+
import { useNavigate as useNavigate5 } from "react-router";
|
|
13680
|
+
import { jsxDEV as jsxDEV31 } from "@opentui/react/jsx-dev-runtime";
|
|
12907
13681
|
function getSessionLabel(session) {
|
|
12908
13682
|
return session.title ?? session.latestUserPromptPreview ?? session.id;
|
|
12909
13683
|
}
|
|
@@ -12915,20 +13689,25 @@ function sessionMatchesFilter(session, query) {
|
|
|
12915
13689
|
return (session.title ?? "").toLowerCase().includes(normalized) || (session.latestUserPromptPreview ?? "").toLowerCase().includes(normalized) || session.id.toLowerCase().includes(normalized);
|
|
12916
13690
|
}
|
|
12917
13691
|
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 =
|
|
13692
|
+
const navigate = useNavigate5();
|
|
13693
|
+
const [sessions, setSessions] = useState18([]);
|
|
13694
|
+
const [selectedIndex, setSelectedIndex] = useState18(0);
|
|
13695
|
+
const [isLoading, setIsLoading] = useState18(true);
|
|
13696
|
+
const [errorMessage, setErrorMessage] = useState18(null);
|
|
13697
|
+
const [actionMessage, setActionMessage] = useState18(null);
|
|
13698
|
+
const [pendingDeleteId, setPendingDeleteId] = useState18(null);
|
|
13699
|
+
const [filterQuery, setFilterQuery] = useState18("");
|
|
13700
|
+
const [filterOpen, setFilterOpen] = useState18(false);
|
|
13701
|
+
const [renamingSessionId, setRenamingSessionId] = useState18(null);
|
|
13702
|
+
const visibleSessions = useMemo7(() => sessions.filter((session) => sessionMatchesFilter(session, filterQuery)), [filterQuery, sessions]);
|
|
12929
13703
|
const safeSelectedIndex = Math.min(selectedIndex, Math.max(visibleSessions.length - 1, 0));
|
|
12930
13704
|
const selectedSession = visibleSessions[safeSelectedIndex] ?? null;
|
|
12931
13705
|
const inputActive = filterOpen || renamingSessionId !== null;
|
|
13706
|
+
const applyLoadedSessions = useCallback8((loadedSessions, droppedCount) => {
|
|
13707
|
+
setSessions(loadedSessions);
|
|
13708
|
+
setSelectedIndex((currentIndex) => Math.min(currentIndex, Math.max(loadedSessions.length - 1, 0)));
|
|
13709
|
+
setErrorMessage(droppedCount > 0 ? `${droppedCount} session${droppedCount === 1 ? "" : "s"} could not be read and ${droppedCount === 1 ? "was" : "were"} skipped.` : null);
|
|
13710
|
+
}, []);
|
|
12932
13711
|
const loadSessions = useCallback8(async () => {
|
|
12933
13712
|
setIsLoading(true);
|
|
12934
13713
|
setErrorMessage(null);
|
|
@@ -12939,17 +13718,31 @@ function SessionListScreen() {
|
|
|
12939
13718
|
}
|
|
12940
13719
|
const rawPayload = await response.json();
|
|
12941
13720
|
const parsedPayload = sessionListResponseSchema.safeParse(rawPayload);
|
|
12942
|
-
if (
|
|
13721
|
+
if (parsedPayload.success) {
|
|
13722
|
+
applyLoadedSessions(parsedPayload.data.sessions, 0);
|
|
13723
|
+
return;
|
|
13724
|
+
}
|
|
13725
|
+
const rawSessions = rawPayload && typeof rawPayload === "object" && Array.isArray(rawPayload.sessions) ? rawPayload.sessions : null;
|
|
13726
|
+
if (!rawSessions) {
|
|
12943
13727
|
throw new Error("Server returned an invalid session list response.");
|
|
12944
13728
|
}
|
|
12945
|
-
|
|
12946
|
-
|
|
13729
|
+
const validSessions = [];
|
|
13730
|
+
let droppedCount = 0;
|
|
13731
|
+
for (const rawSession of rawSessions) {
|
|
13732
|
+
const parsedSession = sessionSummarySchema.safeParse(rawSession);
|
|
13733
|
+
if (parsedSession.success) {
|
|
13734
|
+
validSessions.push(parsedSession.data);
|
|
13735
|
+
} else {
|
|
13736
|
+
droppedCount += 1;
|
|
13737
|
+
}
|
|
13738
|
+
}
|
|
13739
|
+
applyLoadedSessions(validSessions, droppedCount);
|
|
12947
13740
|
} catch (error) {
|
|
12948
|
-
setErrorMessage(getErrorMessage(error, "Unable to
|
|
13741
|
+
setErrorMessage(getErrorMessage(error, "Unable to reach the Lightcode server."));
|
|
12949
13742
|
} finally {
|
|
12950
13743
|
setIsLoading(false);
|
|
12951
13744
|
}
|
|
12952
|
-
}, []);
|
|
13745
|
+
}, [applyLoadedSessions]);
|
|
12953
13746
|
const resumeSelectedSession = useCallback8(() => {
|
|
12954
13747
|
if (!selectedSession) {
|
|
12955
13748
|
setActionMessage("No session selected.");
|
|
@@ -13009,9 +13802,9 @@ function SessionListScreen() {
|
|
|
13009
13802
|
if (!parsedPayload.success) {
|
|
13010
13803
|
throw new Error("Server returned an invalid export response.");
|
|
13011
13804
|
}
|
|
13012
|
-
const exportPath =
|
|
13013
|
-
await Bun.write(exportPath,
|
|
13014
|
-
setActionMessage(`Exported
|
|
13805
|
+
const exportPath = getExportPath(parsedPayload.data.session.title, parsedPayload.data.session.id);
|
|
13806
|
+
await Bun.write(exportPath, sessionToMarkdown(parsedPayload.data));
|
|
13807
|
+
setActionMessage(`Exported Markdown to ${exportPath.replace(/\\/g, "/")}`);
|
|
13015
13808
|
} catch (error) {
|
|
13016
13809
|
setActionMessage(getErrorMessage(error, "Unable to export session."));
|
|
13017
13810
|
}
|
|
@@ -13062,10 +13855,10 @@ function SessionListScreen() {
|
|
|
13062
13855
|
setActionMessage(getErrorMessage(error, "Unable to rename session."));
|
|
13063
13856
|
}
|
|
13064
13857
|
}, [loadSessions]);
|
|
13065
|
-
|
|
13858
|
+
useEffect13(() => {
|
|
13066
13859
|
loadSessions();
|
|
13067
13860
|
}, [loadSessions]);
|
|
13068
|
-
|
|
13861
|
+
useKeyboard10((keyEvent) => {
|
|
13069
13862
|
const keyName = keyEvent.name.toLowerCase();
|
|
13070
13863
|
if (inputActive) {
|
|
13071
13864
|
if (isEscapeKey(keyName)) {
|
|
@@ -13147,55 +13940,55 @@ function SessionListScreen() {
|
|
|
13147
13940
|
exportSelectedSession();
|
|
13148
13941
|
}
|
|
13149
13942
|
});
|
|
13150
|
-
const footerText =
|
|
13943
|
+
const footerText = useMemo7(() => {
|
|
13151
13944
|
if (sessions.length === 0) {
|
|
13152
13945
|
return `u refresh | l resume latest | ${BACK_SHORTCUT_LABEL} back`;
|
|
13153
13946
|
}
|
|
13154
13947
|
return "Enter resume | r rename | f fork | / filter | e export | d delete | u refresh";
|
|
13155
13948
|
}, [sessions.length]);
|
|
13156
|
-
return /* @__PURE__ */
|
|
13949
|
+
return /* @__PURE__ */ jsxDEV31("box", {
|
|
13157
13950
|
width: "100%",
|
|
13158
13951
|
height: "100%",
|
|
13159
13952
|
flexDirection: "column",
|
|
13160
13953
|
gap: 1,
|
|
13161
13954
|
children: [
|
|
13162
|
-
/* @__PURE__ */
|
|
13955
|
+
/* @__PURE__ */ jsxDEV31("box", {
|
|
13163
13956
|
flexDirection: "row",
|
|
13164
13957
|
justifyContent: "space-between",
|
|
13165
13958
|
paddingX: 1,
|
|
13166
13959
|
children: [
|
|
13167
|
-
/* @__PURE__ */
|
|
13960
|
+
/* @__PURE__ */ jsxDEV31("text", {
|
|
13168
13961
|
fg: cliTheme.text.primary,
|
|
13169
|
-
attributes:
|
|
13962
|
+
attributes: TextAttributes21.BOLD,
|
|
13170
13963
|
children: "Sessions"
|
|
13171
13964
|
}, undefined, false, undefined, this),
|
|
13172
|
-
/* @__PURE__ */
|
|
13965
|
+
/* @__PURE__ */ jsxDEV31("text", {
|
|
13173
13966
|
fg: cliTheme.text.muted,
|
|
13174
13967
|
children: isLoading ? "loading..." : `${sessions.length} saved`
|
|
13175
13968
|
}, undefined, false, undefined, this)
|
|
13176
13969
|
]
|
|
13177
13970
|
}, undefined, true, undefined, this),
|
|
13178
|
-
errorMessage ? /* @__PURE__ */
|
|
13971
|
+
errorMessage ? /* @__PURE__ */ jsxDEV31("box", {
|
|
13179
13972
|
paddingX: 1,
|
|
13180
|
-
children: /* @__PURE__ */
|
|
13973
|
+
children: /* @__PURE__ */ jsxDEV31("text", {
|
|
13181
13974
|
fg: cliTheme.semantic.error,
|
|
13182
13975
|
children: errorMessage
|
|
13183
13976
|
}, undefined, false, undefined, this)
|
|
13184
13977
|
}, undefined, false, undefined, this) : null,
|
|
13185
|
-
filterQuery && !filterOpen ? /* @__PURE__ */
|
|
13978
|
+
filterQuery && !filterOpen ? /* @__PURE__ */ jsxDEV31("box", {
|
|
13186
13979
|
paddingX: 1,
|
|
13187
|
-
children: /* @__PURE__ */
|
|
13980
|
+
children: /* @__PURE__ */ jsxDEV31("text", {
|
|
13188
13981
|
fg: cliTheme.accent.primary,
|
|
13189
13982
|
children: `Filter: "${filterQuery}" (${visibleSessions.length} match${visibleSessions.length === 1 ? "" : "es"}) - Esc clears`
|
|
13190
13983
|
}, undefined, false, undefined, this)
|
|
13191
13984
|
}, undefined, false, undefined, this) : null,
|
|
13192
|
-
/* @__PURE__ */
|
|
13985
|
+
/* @__PURE__ */ jsxDEV31("box", {
|
|
13193
13986
|
flexDirection: "column",
|
|
13194
13987
|
flexGrow: 1,
|
|
13195
13988
|
children: [
|
|
13196
|
-
visibleSessions.length === 0 && !isLoading ? /* @__PURE__ */
|
|
13989
|
+
visibleSessions.length === 0 && !isLoading ? /* @__PURE__ */ jsxDEV31("box", {
|
|
13197
13990
|
paddingX: 1,
|
|
13198
|
-
children: /* @__PURE__ */
|
|
13991
|
+
children: /* @__PURE__ */ jsxDEV31("text", {
|
|
13199
13992
|
fg: cliTheme.text.muted,
|
|
13200
13993
|
children: sessions.length === 0 ? "No saved sessions yet." : "No sessions match the filter."
|
|
13201
13994
|
}, undefined, false, undefined, this)
|
|
@@ -13204,34 +13997,34 @@ function SessionListScreen() {
|
|
|
13204
13997
|
const isSelected = index === safeSelectedIndex;
|
|
13205
13998
|
const rowColors = getOverlayRowColors(isSelected);
|
|
13206
13999
|
const selectedForDelete = pendingDeleteId === session.id;
|
|
13207
|
-
return /* @__PURE__ */
|
|
14000
|
+
return /* @__PURE__ */ jsxDEV31("box", {
|
|
13208
14001
|
flexDirection: "column",
|
|
13209
14002
|
paddingX: 1,
|
|
13210
14003
|
backgroundColor: rowColors.backgroundColor,
|
|
13211
14004
|
children: [
|
|
13212
|
-
/* @__PURE__ */
|
|
14005
|
+
/* @__PURE__ */ jsxDEV31("box", {
|
|
13213
14006
|
flexDirection: "row",
|
|
13214
14007
|
justifyContent: "space-between",
|
|
13215
14008
|
children: [
|
|
13216
|
-
/* @__PURE__ */
|
|
14009
|
+
/* @__PURE__ */ jsxDEV31("text", {
|
|
13217
14010
|
fg: selectedForDelete ? cliTheme.semantic.error : rowColors.primaryTextColor,
|
|
13218
|
-
attributes:
|
|
14011
|
+
attributes: TextAttributes21.BOLD,
|
|
13219
14012
|
children: [
|
|
13220
14013
|
index + 1,
|
|
13221
14014
|
". ",
|
|
13222
14015
|
truncateInline2(getSessionLabel(session), 64)
|
|
13223
14016
|
]
|
|
13224
14017
|
}, undefined, true, undefined, this),
|
|
13225
|
-
/* @__PURE__ */
|
|
14018
|
+
/* @__PURE__ */ jsxDEV31("text", {
|
|
13226
14019
|
fg: rowColors.secondaryTextColor,
|
|
13227
|
-
attributes:
|
|
14020
|
+
attributes: TextAttributes21.DIM,
|
|
13228
14021
|
children: `${session.messageCount} msgs - ${session.mode} - ${formatDate2(session.updatedAt)}`
|
|
13229
14022
|
}, undefined, false, undefined, this)
|
|
13230
14023
|
]
|
|
13231
14024
|
}, undefined, true, undefined, this),
|
|
13232
|
-
isSelected && session.latestUserPromptPreview ? /* @__PURE__ */
|
|
14025
|
+
isSelected && session.latestUserPromptPreview ? /* @__PURE__ */ jsxDEV31("text", {
|
|
13233
14026
|
fg: rowColors.secondaryTextColor,
|
|
13234
|
-
attributes:
|
|
14027
|
+
attributes: TextAttributes21.DIM,
|
|
13235
14028
|
children: truncateInline2(session.latestUserPromptPreview, 110)
|
|
13236
14029
|
}, undefined, false, undefined, this) : null
|
|
13237
14030
|
]
|
|
@@ -13239,28 +14032,28 @@ function SessionListScreen() {
|
|
|
13239
14032
|
})
|
|
13240
14033
|
]
|
|
13241
14034
|
}, undefined, true, undefined, this),
|
|
13242
|
-
actionMessage ? /* @__PURE__ */
|
|
14035
|
+
actionMessage ? /* @__PURE__ */ jsxDEV31("box", {
|
|
13243
14036
|
paddingX: 1,
|
|
13244
|
-
children: /* @__PURE__ */
|
|
14037
|
+
children: /* @__PURE__ */ jsxDEV31("text", {
|
|
13245
14038
|
fg: cliTheme.semantic.info,
|
|
13246
14039
|
children: actionMessage
|
|
13247
14040
|
}, undefined, false, undefined, this)
|
|
13248
14041
|
}, undefined, false, undefined, this) : null,
|
|
13249
|
-
filterOpen ? /* @__PURE__ */
|
|
14042
|
+
filterOpen ? /* @__PURE__ */ jsxDEV31(ChatTextArea, {
|
|
13250
14043
|
placeholder: "Filter sessions...",
|
|
13251
14044
|
allowEmpty: true,
|
|
13252
14045
|
onTextChange: setFilterQuery,
|
|
13253
14046
|
onSubmit: () => setFilterOpen(false)
|
|
13254
14047
|
}, undefined, false, undefined, this) : null,
|
|
13255
|
-
renamingSessionId !== null ? /* @__PURE__ */
|
|
14048
|
+
renamingSessionId !== null ? /* @__PURE__ */ jsxDEV31(ChatTextArea, {
|
|
13256
14049
|
placeholder: "New session title...",
|
|
13257
14050
|
onSubmit: (title) => void renameSession(renamingSessionId, title)
|
|
13258
14051
|
}, undefined, false, undefined, this) : null,
|
|
13259
|
-
/* @__PURE__ */
|
|
14052
|
+
/* @__PURE__ */ jsxDEV31("box", {
|
|
13260
14053
|
paddingX: 1,
|
|
13261
|
-
children: /* @__PURE__ */
|
|
14054
|
+
children: /* @__PURE__ */ jsxDEV31("text", {
|
|
13262
14055
|
fg: cliTheme.text.muted,
|
|
13263
|
-
attributes:
|
|
14056
|
+
attributes: TextAttributes21.DIM,
|
|
13264
14057
|
children: inputActive ? "Enter confirm | Esc cancel" : footerText
|
|
13265
14058
|
}, undefined, false, undefined, this)
|
|
13266
14059
|
}, undefined, false, undefined, this)
|
|
@@ -13271,16 +14064,17 @@ var init_session_list_screen = __esm(() => {
|
|
|
13271
14064
|
init_src2();
|
|
13272
14065
|
init_client();
|
|
13273
14066
|
init_keymap();
|
|
14067
|
+
init_export_session_markdown();
|
|
13274
14068
|
init_chat_text_area();
|
|
13275
14069
|
init_cli_theme();
|
|
13276
14070
|
init_text_utils();
|
|
13277
14071
|
});
|
|
13278
14072
|
|
|
13279
14073
|
// apps/cli/src/hooks/use-config-badge.ts
|
|
13280
|
-
import { useEffect as
|
|
14074
|
+
import { useEffect as useEffect14, useState as useState19 } from "react";
|
|
13281
14075
|
function useConfigBadge(refreshNonce = 0) {
|
|
13282
|
-
const [state, setState] =
|
|
13283
|
-
|
|
14076
|
+
const [state, setState] = useState19({ status: "loading" });
|
|
14077
|
+
useEffect14(() => {
|
|
13284
14078
|
let cancelled = false;
|
|
13285
14079
|
async function loadConfig() {
|
|
13286
14080
|
try {
|
|
@@ -13326,11 +14120,11 @@ var exports_app = {};
|
|
|
13326
14120
|
__export(exports_app, {
|
|
13327
14121
|
App: () => App
|
|
13328
14122
|
});
|
|
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
|
|
14123
|
+
import { TextAttributes as TextAttributes22 } from "@opentui/core";
|
|
14124
|
+
import { useKeyboard as useKeyboard11, useRenderer as useRenderer2 } from "@opentui/react";
|
|
14125
|
+
import { useEffect as useEffect15, useRef as useRef5, useState as useState20 } from "react";
|
|
14126
|
+
import { MemoryRouter, Navigate, Route, Routes, useLocation as useLocation3, useNavigate as useNavigate6 } from "react-router";
|
|
14127
|
+
import { jsxDEV as jsxDEV32 } from "@opentui/react/jsx-dev-runtime";
|
|
13334
14128
|
function getCurrentViewLabel(pathname) {
|
|
13335
14129
|
if (pathname === "/" || pathname === "/home") {
|
|
13336
14130
|
return "home";
|
|
@@ -13356,14 +14150,17 @@ function getCurrentViewLabel(pathname) {
|
|
|
13356
14150
|
if (pathname === "/config") {
|
|
13357
14151
|
return "config";
|
|
13358
14152
|
}
|
|
13359
|
-
if (pathname === "/model") {
|
|
14153
|
+
if (pathname === "/model-info") {
|
|
13360
14154
|
return "model";
|
|
13361
14155
|
}
|
|
14156
|
+
if (pathname === "/model") {
|
|
14157
|
+
return "model-select";
|
|
14158
|
+
}
|
|
13362
14159
|
return pathname;
|
|
13363
14160
|
}
|
|
13364
14161
|
function AppContent() {
|
|
13365
|
-
const renderer =
|
|
13366
|
-
const navigate =
|
|
14162
|
+
const renderer = useRenderer2();
|
|
14163
|
+
const navigate = useNavigate6();
|
|
13367
14164
|
const location = useLocation3();
|
|
13368
14165
|
const {
|
|
13369
14166
|
paletteOpen,
|
|
@@ -13383,7 +14180,45 @@ function AppContent() {
|
|
|
13383
14180
|
configRefreshNonce,
|
|
13384
14181
|
toggleToolOutputExpansion
|
|
13385
14182
|
} = useAppState();
|
|
13386
|
-
const [helpOpen, setHelpOpen] =
|
|
14183
|
+
const [helpOpen, setHelpOpen] = useState20(false);
|
|
14184
|
+
const [ctrlCNotice, setCtrlCNotice] = useState20(null);
|
|
14185
|
+
const ctrlCArmedRef = useRef5(false);
|
|
14186
|
+
const ctrlCTimerRef = useRef5(null);
|
|
14187
|
+
const showCtrlCNotice = (text) => {
|
|
14188
|
+
setCtrlCNotice(text);
|
|
14189
|
+
if (ctrlCTimerRef.current) {
|
|
14190
|
+
clearTimeout(ctrlCTimerRef.current);
|
|
14191
|
+
}
|
|
14192
|
+
ctrlCTimerRef.current = setTimeout(() => {
|
|
14193
|
+
setCtrlCNotice(null);
|
|
14194
|
+
ctrlCArmedRef.current = false;
|
|
14195
|
+
ctrlCTimerRef.current = null;
|
|
14196
|
+
}, 2000);
|
|
14197
|
+
};
|
|
14198
|
+
const handleCtrlC = () => {
|
|
14199
|
+
const selection = renderer.getSelection();
|
|
14200
|
+
const selectedText = selection ? selection.getSelectedText() : "";
|
|
14201
|
+
if (selectedText.trim().length > 0) {
|
|
14202
|
+
copyText(renderer, selectedText);
|
|
14203
|
+
renderer.clearSelection();
|
|
14204
|
+
ctrlCArmedRef.current = false;
|
|
14205
|
+
showCtrlCNotice(`Copied ${selectedText.length} chars to clipboard`);
|
|
14206
|
+
return;
|
|
14207
|
+
}
|
|
14208
|
+
if (ctrlCArmedRef.current) {
|
|
14209
|
+
renderer.destroy();
|
|
14210
|
+
return;
|
|
14211
|
+
}
|
|
14212
|
+
ctrlCArmedRef.current = true;
|
|
14213
|
+
showCtrlCNotice("Press Ctrl+C again to exit");
|
|
14214
|
+
};
|
|
14215
|
+
useEffect15(() => {
|
|
14216
|
+
return () => {
|
|
14217
|
+
if (ctrlCTimerRef.current) {
|
|
14218
|
+
clearTimeout(ctrlCTimerRef.current);
|
|
14219
|
+
}
|
|
14220
|
+
};
|
|
14221
|
+
}, []);
|
|
13387
14222
|
const canGoBack = location.pathname !== "/" && location.pathname !== "/home";
|
|
13388
14223
|
const currentView = getCurrentViewLabel(location.pathname);
|
|
13389
14224
|
const inChatSession = location.pathname.startsWith("/sessions/");
|
|
@@ -13494,7 +14329,11 @@ function AppContent() {
|
|
|
13494
14329
|
closeSlashMenu();
|
|
13495
14330
|
}
|
|
13496
14331
|
};
|
|
13497
|
-
|
|
14332
|
+
useKeyboard11((keyEvent) => {
|
|
14333
|
+
if (keyEvent.ctrl && keyEvent.name === "c") {
|
|
14334
|
+
handleCtrlC();
|
|
14335
|
+
return;
|
|
14336
|
+
}
|
|
13498
14337
|
if (slashMenuOpen) {
|
|
13499
14338
|
handleSlashMenuKeyDown(keyEvent);
|
|
13500
14339
|
return;
|
|
@@ -13504,10 +14343,6 @@ function AppContent() {
|
|
|
13504
14343
|
return;
|
|
13505
14344
|
}
|
|
13506
14345
|
const normalizedKey = normalizeKeyName(keyEvent.name, keyEvent.ctrl, false, false);
|
|
13507
|
-
if (keyEvent.ctrl && keyEvent.name === "c") {
|
|
13508
|
-
handleAction("system:quit");
|
|
13509
|
-
return;
|
|
13510
|
-
}
|
|
13511
14346
|
if (isEscapeKey2(keyEvent)) {
|
|
13512
14347
|
handleAction("system:cancel");
|
|
13513
14348
|
return;
|
|
@@ -13524,7 +14359,7 @@ function AppContent() {
|
|
|
13524
14359
|
});
|
|
13525
14360
|
const configBadge = useConfigBadge(configRefreshNonce);
|
|
13526
14361
|
const needsOnboarding = configBadge.status === "available" && configBadge.missingCredentialHints.length > 0;
|
|
13527
|
-
|
|
14362
|
+
useEffect15(() => {
|
|
13528
14363
|
if (needsOnboarding && location.pathname !== "/onboarding") {
|
|
13529
14364
|
navigate("/onboarding");
|
|
13530
14365
|
}
|
|
@@ -13536,12 +14371,12 @@ function AppContent() {
|
|
|
13536
14371
|
const backHint = canGoBack ? ` | Esc/${BACK_SHORTCUT_LABEL} Back` : "";
|
|
13537
14372
|
return "/ Pages | Ctrl+P Cmd | F1 Help | Ctrl+C Quit" + backHint;
|
|
13538
14373
|
};
|
|
13539
|
-
return /* @__PURE__ */
|
|
14374
|
+
return /* @__PURE__ */ jsxDEV32("box", {
|
|
13540
14375
|
flexDirection: "column",
|
|
13541
14376
|
flexGrow: 1,
|
|
13542
14377
|
backgroundColor: cliTheme.surfaces.base,
|
|
13543
14378
|
children: [
|
|
13544
|
-
/* @__PURE__ */
|
|
14379
|
+
/* @__PURE__ */ jsxDEV32("box", {
|
|
13545
14380
|
flexDirection: "row",
|
|
13546
14381
|
justifyContent: "space-between",
|
|
13547
14382
|
paddingLeft: 1,
|
|
@@ -13550,17 +14385,17 @@ function AppContent() {
|
|
|
13550
14385
|
border: ["bottom"],
|
|
13551
14386
|
borderColor: cliTheme.borders.default,
|
|
13552
14387
|
children: [
|
|
13553
|
-
/* @__PURE__ */
|
|
14388
|
+
/* @__PURE__ */ jsxDEV32("box", {
|
|
13554
14389
|
flexDirection: "row",
|
|
13555
14390
|
gap: 2,
|
|
13556
14391
|
alignItems: "center",
|
|
13557
14392
|
children: [
|
|
13558
|
-
/* @__PURE__ */
|
|
14393
|
+
/* @__PURE__ */ jsxDEV32("text", {
|
|
13559
14394
|
fg: cliTheme.text.primary,
|
|
13560
|
-
attributes:
|
|
14395
|
+
attributes: TextAttributes22.BOLD,
|
|
13561
14396
|
children: "Lightcode"
|
|
13562
14397
|
}, undefined, false, undefined, this),
|
|
13563
|
-
configBadge.status === "available" ? /* @__PURE__ */
|
|
14398
|
+
configBadge.status === "available" ? /* @__PURE__ */ jsxDEV32("text", {
|
|
13564
14399
|
fg: cliTheme.text.secondary,
|
|
13565
14400
|
children: [
|
|
13566
14401
|
"| ",
|
|
@@ -13568,122 +14403,126 @@ function AppContent() {
|
|
|
13568
14403
|
" | ",
|
|
13569
14404
|
configBadge.model
|
|
13570
14405
|
]
|
|
13571
|
-
}, undefined, true, undefined, this) : configBadge.status === "loading" ? /* @__PURE__ */
|
|
14406
|
+
}, undefined, true, undefined, this) : configBadge.status === "loading" ? /* @__PURE__ */ jsxDEV32("text", {
|
|
13572
14407
|
fg: cliTheme.text.muted,
|
|
13573
14408
|
children: "| loading..."
|
|
13574
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
14409
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV32("text", {
|
|
13575
14410
|
fg: cliTheme.text.muted,
|
|
13576
14411
|
children: "| provider unavailable"
|
|
13577
14412
|
}, undefined, false, undefined, this)
|
|
13578
14413
|
]
|
|
13579
14414
|
}, undefined, true, undefined, this),
|
|
13580
|
-
/* @__PURE__ */
|
|
14415
|
+
/* @__PURE__ */ jsxDEV32("text", {
|
|
13581
14416
|
fg: cliTheme.text.muted,
|
|
13582
14417
|
children: currentView
|
|
13583
14418
|
}, undefined, false, undefined, this)
|
|
13584
14419
|
]
|
|
13585
14420
|
}, undefined, true, undefined, this),
|
|
13586
|
-
/* @__PURE__ */
|
|
14421
|
+
/* @__PURE__ */ jsxDEV32("box", {
|
|
13587
14422
|
flexGrow: 1,
|
|
13588
14423
|
padding: 1,
|
|
13589
14424
|
position: "relative",
|
|
13590
14425
|
children: [
|
|
13591
|
-
/* @__PURE__ */
|
|
14426
|
+
/* @__PURE__ */ jsxDEV32(Routes, {
|
|
13592
14427
|
children: [
|
|
13593
|
-
/* @__PURE__ */
|
|
14428
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13594
14429
|
path: "/",
|
|
13595
|
-
element: /* @__PURE__ */
|
|
14430
|
+
element: /* @__PURE__ */ jsxDEV32(HomeScreen, {}, undefined, false, undefined, this)
|
|
13596
14431
|
}, undefined, false, undefined, this),
|
|
13597
|
-
/* @__PURE__ */
|
|
14432
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13598
14433
|
path: "/home",
|
|
13599
|
-
element: /* @__PURE__ */
|
|
14434
|
+
element: /* @__PURE__ */ jsxDEV32(Navigate, {
|
|
13600
14435
|
to: "/",
|
|
13601
14436
|
replace: true
|
|
13602
14437
|
}, undefined, false, undefined, this)
|
|
13603
14438
|
}, undefined, false, undefined, this),
|
|
13604
|
-
/* @__PURE__ */
|
|
14439
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13605
14440
|
path: "/status",
|
|
13606
|
-
element: /* @__PURE__ */
|
|
14441
|
+
element: /* @__PURE__ */ jsxDEV32(DiagnosticsScreen, {
|
|
13607
14442
|
kind: "status"
|
|
13608
14443
|
}, undefined, false, undefined, this)
|
|
13609
14444
|
}, undefined, false, undefined, this),
|
|
13610
|
-
/* @__PURE__ */
|
|
14445
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13611
14446
|
path: "/doctor",
|
|
13612
|
-
element: /* @__PURE__ */
|
|
14447
|
+
element: /* @__PURE__ */ jsxDEV32(DiagnosticsScreen, {
|
|
13613
14448
|
kind: "doctor"
|
|
13614
14449
|
}, undefined, false, undefined, this)
|
|
13615
14450
|
}, undefined, false, undefined, this),
|
|
13616
|
-
/* @__PURE__ */
|
|
14451
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13617
14452
|
path: "/permissions",
|
|
13618
|
-
element: /* @__PURE__ */
|
|
14453
|
+
element: /* @__PURE__ */ jsxDEV32(DiagnosticsScreen, {
|
|
13619
14454
|
kind: "permissions"
|
|
13620
14455
|
}, undefined, false, undefined, this)
|
|
13621
14456
|
}, undefined, false, undefined, this),
|
|
13622
|
-
/* @__PURE__ */
|
|
14457
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13623
14458
|
path: "/sessions",
|
|
13624
|
-
element: /* @__PURE__ */
|
|
14459
|
+
element: /* @__PURE__ */ jsxDEV32(SessionListScreen, {}, undefined, false, undefined, this)
|
|
13625
14460
|
}, undefined, false, undefined, this),
|
|
13626
|
-
/* @__PURE__ */
|
|
14461
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13627
14462
|
path: "/sessions/:id",
|
|
13628
|
-
element: /* @__PURE__ */
|
|
14463
|
+
element: /* @__PURE__ */ jsxDEV32(ChatScreen, {}, undefined, false, undefined, this)
|
|
13629
14464
|
}, undefined, false, undefined, this),
|
|
13630
|
-
/* @__PURE__ */
|
|
14465
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13631
14466
|
path: "/tools",
|
|
13632
|
-
element: /* @__PURE__ */
|
|
14467
|
+
element: /* @__PURE__ */ jsxDEV32(DiagnosticsScreen, {
|
|
13633
14468
|
kind: "tools"
|
|
13634
14469
|
}, undefined, false, undefined, this)
|
|
13635
14470
|
}, undefined, false, undefined, this),
|
|
13636
|
-
/* @__PURE__ */
|
|
14471
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13637
14472
|
path: "/config",
|
|
13638
|
-
element: /* @__PURE__ */
|
|
14473
|
+
element: /* @__PURE__ */ jsxDEV32(DiagnosticsScreen, {
|
|
13639
14474
|
kind: "config"
|
|
13640
14475
|
}, undefined, false, undefined, this)
|
|
13641
14476
|
}, undefined, false, undefined, this),
|
|
13642
|
-
/* @__PURE__ */
|
|
14477
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
14478
|
+
path: "/model-info",
|
|
14479
|
+
element: /* @__PURE__ */ jsxDEV32(ModelScreen, {}, undefined, false, undefined, this)
|
|
14480
|
+
}, undefined, false, undefined, this),
|
|
14481
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13643
14482
|
path: "/model",
|
|
13644
|
-
element: /* @__PURE__ */
|
|
14483
|
+
element: /* @__PURE__ */ jsxDEV32(ModelSelectScreen, {}, undefined, false, undefined, this)
|
|
13645
14484
|
}, undefined, false, undefined, this),
|
|
13646
|
-
/* @__PURE__ */
|
|
14485
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13647
14486
|
path: "/onboarding",
|
|
13648
|
-
element: /* @__PURE__ */
|
|
14487
|
+
element: /* @__PURE__ */ jsxDEV32(OnboardingScreen, {}, undefined, false, undefined, this)
|
|
13649
14488
|
}, undefined, false, undefined, this),
|
|
13650
|
-
/* @__PURE__ */
|
|
14489
|
+
/* @__PURE__ */ jsxDEV32(Route, {
|
|
13651
14490
|
path: "*",
|
|
13652
|
-
element: /* @__PURE__ */
|
|
14491
|
+
element: /* @__PURE__ */ jsxDEV32(Navigate, {
|
|
13653
14492
|
to: "/",
|
|
13654
14493
|
replace: true
|
|
13655
14494
|
}, undefined, false, undefined, this)
|
|
13656
14495
|
}, undefined, false, undefined, this)
|
|
13657
14496
|
]
|
|
13658
14497
|
}, undefined, true, undefined, this),
|
|
13659
|
-
paletteOpen ? /* @__PURE__ */
|
|
14498
|
+
paletteOpen ? /* @__PURE__ */ jsxDEV32(CommandPalette, {
|
|
13660
14499
|
query: paletteQuery,
|
|
13661
14500
|
setQuery: setPaletteQuery,
|
|
13662
14501
|
selectedIndex: paletteSelected
|
|
13663
14502
|
}, undefined, false, undefined, this) : null,
|
|
13664
|
-
slashMenuOpen && !inputHostsSlashMenu ? /* @__PURE__ */
|
|
14503
|
+
slashMenuOpen && !inputHostsSlashMenu ? /* @__PURE__ */ jsxDEV32("box", {
|
|
13665
14504
|
position: "absolute",
|
|
13666
14505
|
top: 1,
|
|
13667
14506
|
left: 2,
|
|
13668
14507
|
right: 2,
|
|
13669
14508
|
zIndex: 20,
|
|
13670
|
-
children: /* @__PURE__ */
|
|
14509
|
+
children: /* @__PURE__ */ jsxDEV32(SlashPageMenu, {
|
|
13671
14510
|
query: slashMenuQuery,
|
|
13672
14511
|
selectedIndex: selectedSlashRouteIndex,
|
|
13673
14512
|
routes: filteredSlashRoutes
|
|
13674
14513
|
}, undefined, false, undefined, this)
|
|
13675
14514
|
}, undefined, false, undefined, this) : null,
|
|
13676
|
-
helpOpen ? /* @__PURE__ */
|
|
14515
|
+
helpOpen ? /* @__PURE__ */ jsxDEV32("box", {
|
|
13677
14516
|
position: "absolute",
|
|
13678
14517
|
top: 1,
|
|
13679
14518
|
left: 4,
|
|
13680
14519
|
right: 4,
|
|
13681
14520
|
zIndex: 30,
|
|
13682
|
-
children: /* @__PURE__ */
|
|
14521
|
+
children: /* @__PURE__ */ jsxDEV32(HelpOverlay, {}, undefined, false, undefined, this)
|
|
13683
14522
|
}, undefined, false, undefined, this) : null
|
|
13684
14523
|
]
|
|
13685
14524
|
}, undefined, true, undefined, this),
|
|
13686
|
-
/* @__PURE__ */
|
|
14525
|
+
/* @__PURE__ */ jsxDEV32("box", {
|
|
13687
14526
|
flexDirection: "row",
|
|
13688
14527
|
justifyContent: "center",
|
|
13689
14528
|
gap: 2,
|
|
@@ -13692,19 +14531,19 @@ function AppContent() {
|
|
|
13692
14531
|
borderStyle: "single",
|
|
13693
14532
|
border: ["top"],
|
|
13694
14533
|
borderColor: cliTheme.borders.default,
|
|
13695
|
-
children: /* @__PURE__ */
|
|
13696
|
-
fg: cliTheme.text.muted,
|
|
13697
|
-
children: getFooterStatus()
|
|
14534
|
+
children: /* @__PURE__ */ jsxDEV32("text", {
|
|
14535
|
+
fg: ctrlCNotice ? cliTheme.semantic.warning : cliTheme.text.muted,
|
|
14536
|
+
children: ctrlCNotice ?? getFooterStatus()
|
|
13698
14537
|
}, undefined, false, undefined, this)
|
|
13699
14538
|
}, undefined, false, undefined, this)
|
|
13700
14539
|
]
|
|
13701
14540
|
}, undefined, true, undefined, this);
|
|
13702
14541
|
}
|
|
13703
14542
|
function App() {
|
|
13704
|
-
return /* @__PURE__ */
|
|
14543
|
+
return /* @__PURE__ */ jsxDEV32(MemoryRouter, {
|
|
13705
14544
|
initialEntries: ["/"],
|
|
13706
|
-
children: /* @__PURE__ */
|
|
13707
|
-
children: /* @__PURE__ */
|
|
14545
|
+
children: /* @__PURE__ */ jsxDEV32(AppStateProvider, {
|
|
14546
|
+
children: /* @__PURE__ */ jsxDEV32(AppContent, {}, undefined, false, undefined, this)
|
|
13708
14547
|
}, undefined, false, undefined, this)
|
|
13709
14548
|
}, undefined, false, undefined, this);
|
|
13710
14549
|
}
|
|
@@ -13720,16 +14559,18 @@ var init_app = __esm(() => {
|
|
|
13720
14559
|
init_diagnostics_screen();
|
|
13721
14560
|
init_home_screen();
|
|
13722
14561
|
init_model_screen();
|
|
14562
|
+
init_model_select_screen();
|
|
13723
14563
|
init_onboarding_screen();
|
|
13724
14564
|
init_session_list_screen();
|
|
13725
14565
|
init_app_state();
|
|
13726
14566
|
init_use_config_badge();
|
|
13727
14567
|
init_cli_theme();
|
|
14568
|
+
init_clipboard();
|
|
13728
14569
|
});
|
|
13729
14570
|
|
|
13730
14571
|
// apps/cli/src/index.tsx
|
|
13731
14572
|
init_src();
|
|
13732
|
-
import { jsxDEV as
|
|
14573
|
+
import { jsxDEV as jsxDEV33 } from "@opentui/react/jsx-dev-runtime";
|
|
13733
14574
|
var cliArgs = Bun.argv.slice(2);
|
|
13734
14575
|
if (cliArgs.includes("--version") || cliArgs.includes("-v")) {
|
|
13735
14576
|
console.log(`${productName} v${lightcodeVersion}`);
|
|
@@ -13737,11 +14578,17 @@ if (cliArgs.includes("--version") || cliArgs.includes("-v")) {
|
|
|
13737
14578
|
}
|
|
13738
14579
|
var { ensureServerRunning: ensureServerRunning2 } = await Promise.resolve().then(() => (init_server_launcher(), exports_server_launcher));
|
|
13739
14580
|
var serverLaunch = await ensureServerRunning2();
|
|
14581
|
+
if (serverLaunch.error) {
|
|
14582
|
+
console.error(`
|
|
14583
|
+
${serverLaunch.error}
|
|
14584
|
+
`);
|
|
14585
|
+
process.exit(1);
|
|
14586
|
+
}
|
|
13740
14587
|
var { createCliRenderer } = await import("@opentui/core");
|
|
13741
14588
|
var { createRoot } = await import("@opentui/react");
|
|
13742
14589
|
var { App: App2 } = await Promise.resolve().then(() => (init_app(), exports_app));
|
|
13743
14590
|
var renderer = await createCliRenderer({
|
|
13744
|
-
exitOnCtrlC:
|
|
14591
|
+
exitOnCtrlC: false
|
|
13745
14592
|
});
|
|
13746
14593
|
if (serverLaunch.ownedProcess) {
|
|
13747
14594
|
const ownedProcess = serverLaunch.ownedProcess;
|
|
@@ -13751,4 +14598,4 @@ if (serverLaunch.ownedProcess) {
|
|
|
13751
14598
|
} catch {}
|
|
13752
14599
|
});
|
|
13753
14600
|
}
|
|
13754
|
-
createRoot(renderer).render(/* @__PURE__ */
|
|
14601
|
+
createRoot(renderer).render(/* @__PURE__ */ jsxDEV33(App2, {}, undefined, false, undefined, this));
|