miii-agent 0.1.19 → 0.1.21
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/README.md +78 -247
- package/dist/cli.js +987 -169
- package/package.json +4 -2
package/dist/cli.js
CHANGED
|
@@ -34,7 +34,8 @@ function migrate(raw) {
|
|
|
34
34
|
model: raw.model,
|
|
35
35
|
provider: raw.provider,
|
|
36
36
|
effort: raw.effort,
|
|
37
|
-
providers
|
|
37
|
+
providers,
|
|
38
|
+
modelContexts: raw.modelContexts
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
41
|
function readRawConfig() {
|
|
@@ -79,13 +80,17 @@ function setEffort(effort) {
|
|
|
79
80
|
function setProvider(provider) {
|
|
80
81
|
saveConfig({ ...readRawConfig(), provider });
|
|
81
82
|
}
|
|
83
|
+
function setModelContexts(contexts) {
|
|
84
|
+
const raw = readRawConfig();
|
|
85
|
+
saveConfig({ ...raw, modelContexts: { ...raw.modelContexts, ...contexts } });
|
|
86
|
+
}
|
|
82
87
|
var EFFORT_OPTIONS, CONFIG_DIR, CONFIG_PATH;
|
|
83
88
|
var init_config = __esm({
|
|
84
89
|
"src/config.ts"() {
|
|
85
90
|
"use strict";
|
|
86
91
|
EFFORT_OPTIONS = {
|
|
87
|
-
low: { temperature: 0.2, num_predict:
|
|
88
|
-
medium: { temperature: 0.7, num_predict:
|
|
92
|
+
low: { temperature: 0.2, num_predict: 8192 },
|
|
93
|
+
medium: { temperature: 0.7, num_predict: 16384 },
|
|
89
94
|
high: { temperature: 1, num_predict: -1 }
|
|
90
95
|
};
|
|
91
96
|
CONFIG_DIR = join(homedir(), ".miii");
|
|
@@ -158,30 +163,6 @@ async function modelContext(entry, model) {
|
|
|
158
163
|
throw err;
|
|
159
164
|
}
|
|
160
165
|
}
|
|
161
|
-
async function paramCountB(entry, model) {
|
|
162
|
-
try {
|
|
163
|
-
const info = await makeClient(entry).show({ model });
|
|
164
|
-
const details = info.details;
|
|
165
|
-
if (details?.parameter_size) {
|
|
166
|
-
const m = details.parameter_size.match(/([\d.]+)\s*([BM])/i);
|
|
167
|
-
if (m) {
|
|
168
|
-
const n = parseFloat(m[1]);
|
|
169
|
-
if (!isNaN(n)) return m[2].toUpperCase() === "M" ? n / 1e3 : n;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
const modelInfo = info.model_info;
|
|
173
|
-
if (modelInfo) {
|
|
174
|
-
const key = Object.keys(modelInfo).find((k) => k.endsWith("parameter_count"));
|
|
175
|
-
if (key) {
|
|
176
|
-
const val = Number(modelInfo[key]);
|
|
177
|
-
if (!isNaN(val) && val > 0) return val / 1e9;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
return null;
|
|
181
|
-
} catch {
|
|
182
|
-
return null;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
166
|
async function* chat(entry, model, messages, tools, opts) {
|
|
186
167
|
if (opts?.signal?.aborted) return;
|
|
187
168
|
const signal = opts?.signal;
|
|
@@ -211,9 +192,21 @@ async function* chat(entry, model, messages, tools, opts) {
|
|
|
211
192
|
};
|
|
212
193
|
if (opts?.format) req.format = opts.format;
|
|
213
194
|
else if (tools) req.tools = tools;
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
195
|
+
try {
|
|
196
|
+
stream = await client.chat(
|
|
197
|
+
req
|
|
198
|
+
);
|
|
199
|
+
} catch (err) {
|
|
200
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
201
|
+
if (!signal?.aborted && msg.toLowerCase().includes("does not support thinking")) {
|
|
202
|
+
delete req.think;
|
|
203
|
+
stream = await client.chat(
|
|
204
|
+
req
|
|
205
|
+
);
|
|
206
|
+
} else {
|
|
207
|
+
throw err;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
217
210
|
} catch (err) {
|
|
218
211
|
if (signal?.aborted) return;
|
|
219
212
|
if (isConnectionError(err)) {
|
|
@@ -232,6 +225,7 @@ async function* chat(entry, model, messages, tools, opts) {
|
|
|
232
225
|
content: stripHarmony(chunk.message.content),
|
|
233
226
|
thinking: stripHarmony(chunk.message.thinking),
|
|
234
227
|
done: chunk.done,
|
|
228
|
+
done_reason: chunk.done_reason,
|
|
235
229
|
tool_calls: chunk.message.tool_calls,
|
|
236
230
|
prompt_eval_count: chunk.prompt_eval_count,
|
|
237
231
|
eval_count: chunk.eval_count
|
|
@@ -243,6 +237,11 @@ async function* chat(entry, model, messages, tools, opts) {
|
|
|
243
237
|
if (isConnectionError(err)) {
|
|
244
238
|
throw new Error(NOT_RUNNING);
|
|
245
239
|
}
|
|
240
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
241
|
+
if (msg.includes("Did not receive done or success response in stream")) {
|
|
242
|
+
yield { content: "", done: true, prompt_eval_count: 0, eval_count: 0 };
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
246
245
|
throw err;
|
|
247
246
|
} finally {
|
|
248
247
|
if (opts?.signal) opts.signal.removeEventListener("abort", onAbort);
|
|
@@ -362,6 +361,7 @@ async function* chat2(entry, model, messages, tools, opts) {
|
|
|
362
361
|
if (oaTools) body.tools = oaTools;
|
|
363
362
|
if (opts?.num_predict && opts.num_predict > 0) body.max_tokens = opts.num_predict;
|
|
364
363
|
const toolCallAccum = /* @__PURE__ */ new Map();
|
|
364
|
+
let lastFinishReason;
|
|
365
365
|
const TIMEOUT_MS = 18e4;
|
|
366
366
|
const timeoutSignal = AbortSignal.timeout(TIMEOUT_MS);
|
|
367
367
|
const combinedSignal = opts?.signal && typeof AbortSignal.any === "function" ? AbortSignal.any([opts.signal, timeoutSignal]) : opts?.signal ?? timeoutSignal;
|
|
@@ -401,6 +401,7 @@ async function* chat2(entry, model, messages, tools, opts) {
|
|
|
401
401
|
if (!choices || choices.length === 0) continue;
|
|
402
402
|
const delta = choices[0].delta ?? {};
|
|
403
403
|
const finishReason = choices[0].finish_reason;
|
|
404
|
+
if (finishReason) lastFinishReason = finishReason;
|
|
404
405
|
if (delta.content) {
|
|
405
406
|
yield { content: delta.content, done: false };
|
|
406
407
|
}
|
|
@@ -465,6 +466,9 @@ async function* chat2(entry, model, messages, tools, opts) {
|
|
|
465
466
|
yield {
|
|
466
467
|
content: "",
|
|
467
468
|
done: true,
|
|
469
|
+
// OpenAI signals a hit token cap as finish_reason 'length'; normalize to the
|
|
470
|
+
// Ollama spelling so the agent loop can detect truncation uniformly.
|
|
471
|
+
done_reason: lastFinishReason === "length" ? "length" : lastFinishReason ?? void 0,
|
|
468
472
|
tool_calls: toolCalls.length > 0 ? toolCalls : void 0
|
|
469
473
|
};
|
|
470
474
|
}
|
|
@@ -480,9 +484,6 @@ var init_openai = __esm({
|
|
|
480
484
|
function active() {
|
|
481
485
|
return resolveProvider();
|
|
482
486
|
}
|
|
483
|
-
function providerName() {
|
|
484
|
-
return active().name;
|
|
485
|
-
}
|
|
486
487
|
function isAvailable3() {
|
|
487
488
|
const { entry } = active();
|
|
488
489
|
return entry.type === "ollama" ? isAvailable(entry) : isAvailable2(entry);
|
|
@@ -499,16 +500,6 @@ async function modelContext3(model) {
|
|
|
499
500
|
const { entry } = active();
|
|
500
501
|
return entry.type === "ollama" ? modelContext(entry, model) : modelContext2(entry, model);
|
|
501
502
|
}
|
|
502
|
-
async function modelParamCountB(model) {
|
|
503
|
-
const { entry } = active();
|
|
504
|
-
if (entry.type !== "ollama") return null;
|
|
505
|
-
const key = `${entry.baseUrl}:${model}`;
|
|
506
|
-
const cached = paramCountCache.get(key);
|
|
507
|
-
if (cached !== void 0) return cached;
|
|
508
|
-
const params = await paramCountB(entry, model);
|
|
509
|
-
paramCountCache.set(key, params);
|
|
510
|
-
return params;
|
|
511
|
-
}
|
|
512
503
|
async function* chat3(model, messages, tools, opts) {
|
|
513
504
|
const { entry } = active();
|
|
514
505
|
if (entry.type === "ollama") {
|
|
@@ -517,14 +508,12 @@ async function* chat3(model, messages, tools, opts) {
|
|
|
517
508
|
yield* chat2(entry, model, messages, tools, opts);
|
|
518
509
|
}
|
|
519
510
|
}
|
|
520
|
-
var paramCountCache;
|
|
521
511
|
var init_client = __esm({
|
|
522
512
|
"src/llm/client.ts"() {
|
|
523
513
|
"use strict";
|
|
524
514
|
init_config();
|
|
525
515
|
init_ollama();
|
|
526
516
|
init_openai();
|
|
527
|
-
paramCountCache = /* @__PURE__ */ new Map();
|
|
528
517
|
}
|
|
529
518
|
});
|
|
530
519
|
|
|
@@ -727,7 +716,10 @@ var init_edit_file = __esm({
|
|
|
727
716
|
handler: ({ path, old_str, new_str, replace_all }) => {
|
|
728
717
|
try {
|
|
729
718
|
if (old_str === new_str) {
|
|
730
|
-
return {
|
|
719
|
+
return {
|
|
720
|
+
content: `old_str and new_str are identical \u2014 nothing to change in ${path}. If the file is already correct, do NOT edit again: finish with the respond action and tell the user it is done.`,
|
|
721
|
+
is_error: true
|
|
722
|
+
};
|
|
731
723
|
}
|
|
732
724
|
const abs = confinePath(path);
|
|
733
725
|
const src = readFileSync3(abs, "utf-8");
|
|
@@ -1196,6 +1188,31 @@ function toZod(schema) {
|
|
|
1196
1188
|
}
|
|
1197
1189
|
return z.object(shape).passthrough();
|
|
1198
1190
|
}
|
|
1191
|
+
function exampleValue(spec) {
|
|
1192
|
+
if (spec.enum && spec.enum.length) return spec.enum[0];
|
|
1193
|
+
switch (spec.type) {
|
|
1194
|
+
case "number":
|
|
1195
|
+
case "integer":
|
|
1196
|
+
return 0;
|
|
1197
|
+
case "boolean":
|
|
1198
|
+
return false;
|
|
1199
|
+
case "array":
|
|
1200
|
+
return [];
|
|
1201
|
+
case "object":
|
|
1202
|
+
return {};
|
|
1203
|
+
default:
|
|
1204
|
+
return "...";
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
function exampleInput(schema) {
|
|
1208
|
+
const required = schema.required ?? [];
|
|
1209
|
+
const obj = {};
|
|
1210
|
+
for (const key of required) {
|
|
1211
|
+
const spec = schema.properties[key];
|
|
1212
|
+
if (spec) obj[key] = exampleValue(spec);
|
|
1213
|
+
}
|
|
1214
|
+
return JSON.stringify(obj);
|
|
1215
|
+
}
|
|
1199
1216
|
function validateInput(schema, input) {
|
|
1200
1217
|
const result = toZod(schema).safeParse(input ?? {});
|
|
1201
1218
|
if (result.success) return null;
|
|
@@ -1300,9 +1317,9 @@ After each tool result, answer silently: "Does this result move me toward GOAL?"
|
|
|
1300
1317
|
This prevents drift. Each step attends to the original goal, not just the previous step.
|
|
1301
1318
|
|
|
1302
1319
|
# Output format
|
|
1303
|
-
-
|
|
1304
|
-
-
|
|
1305
|
-
-
|
|
1320
|
+
- Your reply is rendered as Markdown in the terminal. You may use the Markdown the renderer supports: \`#\` headings, \`**bold**\` / \`*italic*\`, \`-\` bullet and numbered lists, fenced \`\`\` code blocks (with a language tag for syntax highlighting), inline backticks, blockquotes, links, and tables.
|
|
1321
|
+
- Use it sparingly and only where it aids clarity. Wrap code, paths, commands, and identifiers in inline backticks; put multi-line code in fenced blocks with a language tag. Keep prose plain \u2014 no decorative formatting.
|
|
1322
|
+
- This does NOT apply to your reasoning/thinking. Write internal thoughts in plain text \u2014 no Markdown headings, bold, lists, or code fences there.
|
|
1306
1323
|
- Keep prose terse.
|
|
1307
1324
|
|
|
1308
1325
|
# Tone and voice
|
|
@@ -1592,8 +1609,22 @@ function parseGrammarAction(content, knownToolNames) {
|
|
|
1592
1609
|
}
|
|
1593
1610
|
}
|
|
1594
1611
|
const name = typeof obj.name === "string" ? obj.name : void 0;
|
|
1595
|
-
const args2 = obj.arguments ?? {};
|
|
1596
1612
|
if (!name) return null;
|
|
1613
|
+
let args2;
|
|
1614
|
+
const wrapped = obj.arguments ?? obj.parameters ?? obj.input ?? obj.args;
|
|
1615
|
+
if (typeof wrapped === "string") {
|
|
1616
|
+
try {
|
|
1617
|
+
const parsed = JSON.parse(wrapped);
|
|
1618
|
+
args2 = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
1619
|
+
} catch {
|
|
1620
|
+
args2 = {};
|
|
1621
|
+
}
|
|
1622
|
+
} else if (wrapped && typeof wrapped === "object" && !Array.isArray(wrapped)) {
|
|
1623
|
+
args2 = wrapped;
|
|
1624
|
+
} else {
|
|
1625
|
+
const { name: _n, ...rest } = obj;
|
|
1626
|
+
args2 = rest;
|
|
1627
|
+
}
|
|
1597
1628
|
if (name === "respond") {
|
|
1598
1629
|
const message = typeof args2.message === "string" ? args2.message : "";
|
|
1599
1630
|
return { kind: "respond", message };
|
|
@@ -1685,6 +1716,30 @@ function readGuard(name, input, seen) {
|
|
|
1685
1716
|
const verb = name === "edit_file" ? "edit" : "overwrite";
|
|
1686
1717
|
return `Refusing to ${verb} ${p}: you have not read it this turn. Call read_file on ${p} first, then retry the ${name}.`;
|
|
1687
1718
|
}
|
|
1719
|
+
function unwrapEnvelope(name, input) {
|
|
1720
|
+
if (!("arguments" in input)) return input;
|
|
1721
|
+
if ("name" in input && input.name !== name) return input;
|
|
1722
|
+
let args2 = input.arguments;
|
|
1723
|
+
if (typeof args2 === "string") {
|
|
1724
|
+
try {
|
|
1725
|
+
args2 = JSON.parse(args2);
|
|
1726
|
+
} catch {
|
|
1727
|
+
return input;
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
if (args2 && typeof args2 === "object" && !Array.isArray(args2)) return args2;
|
|
1731
|
+
return input;
|
|
1732
|
+
}
|
|
1733
|
+
function splitWriteHint(name, cause) {
|
|
1734
|
+
const lead = cause === "truncated" ? `Your response was cut off at the output token limit, so this ${name} call is incomplete and was NOT run.` : `Your ${name} call arrived with missing or garbled arguments \u2014 usually the response was cut off or mangled while writing a large value. It was NOT run.`;
|
|
1735
|
+
return `${lead} Do not resend the whole file in one call. Instead create the file with write_file containing only the first portion, then append the rest with successive edit_file calls. Keep each call small.`;
|
|
1736
|
+
}
|
|
1737
|
+
function looksTruncatedWrite(name, input) {
|
|
1738
|
+
if (!BIG_WRITE_TOOLS.has(name)) return false;
|
|
1739
|
+
if (typeof input.path !== "string" || !input.path) return true;
|
|
1740
|
+
if (name === "write_file" && typeof input.content !== "string") return true;
|
|
1741
|
+
return false;
|
|
1742
|
+
}
|
|
1688
1743
|
function markSeen(name, input, seen) {
|
|
1689
1744
|
if (name !== "read_file" && name !== "edit_file" && name !== "write_file") return;
|
|
1690
1745
|
const p = input.path;
|
|
@@ -1697,11 +1752,7 @@ function markSeen(name, input, seen) {
|
|
|
1697
1752
|
async function* runAgent(opts) {
|
|
1698
1753
|
const { model, cwd, permissions, hooks, signal, num_ctx } = opts;
|
|
1699
1754
|
const startTime = Date.now();
|
|
1700
|
-
|
|
1701
|
-
if (providerName() === "ollama") {
|
|
1702
|
-
const params = await modelParamCountB(model);
|
|
1703
|
-
useGrammar = params == null || params <= GRAMMAR_MAX_PARAMS_B;
|
|
1704
|
-
}
|
|
1755
|
+
const useGrammar = false;
|
|
1705
1756
|
const system = buildSystemPrompt(TOOLS, cwd, loadProjectContext(cwd), useGrammar);
|
|
1706
1757
|
const grammar = useGrammar ? buildToolGrammar(TOOLS) : void 0;
|
|
1707
1758
|
const ollamaTools = toOllamaTools(TOOLS);
|
|
@@ -1721,9 +1772,11 @@ async function* runAgent(opts) {
|
|
|
1721
1772
|
let tool_calls;
|
|
1722
1773
|
let respondEmitted = 0;
|
|
1723
1774
|
let streamedRespond = false;
|
|
1775
|
+
let emittedText = false;
|
|
1724
1776
|
let lastTail = "";
|
|
1725
1777
|
let tailRepeats = 0;
|
|
1726
1778
|
let streamLooped = false;
|
|
1779
|
+
let truncated = false;
|
|
1727
1780
|
const ac = new AbortController();
|
|
1728
1781
|
const composedSignal = signal ? AbortSignal.any ? AbortSignal.any([signal, ac.signal]) : ac.signal : ac.signal;
|
|
1729
1782
|
if (signal) signal.addEventListener("abort", () => ac.abort(), { once: true });
|
|
@@ -1733,12 +1786,14 @@ async function* runAgent(opts) {
|
|
|
1733
1786
|
if (chunk.content) {
|
|
1734
1787
|
text += chunk.content;
|
|
1735
1788
|
if (!useGrammar) {
|
|
1789
|
+
emittedText = true;
|
|
1736
1790
|
yield { type: "text-delta", text: chunk.content };
|
|
1737
1791
|
} else {
|
|
1738
1792
|
const r = streamRespondMessage(text);
|
|
1739
1793
|
if (r) {
|
|
1740
1794
|
streamedRespond = true;
|
|
1741
1795
|
if (r.message.length > respondEmitted) {
|
|
1796
|
+
emittedText = true;
|
|
1742
1797
|
yield { type: "text-delta", text: r.message.slice(respondEmitted) };
|
|
1743
1798
|
respondEmitted = r.message.length;
|
|
1744
1799
|
}
|
|
@@ -1759,7 +1814,7 @@ async function* runAgent(opts) {
|
|
|
1759
1814
|
}
|
|
1760
1815
|
}
|
|
1761
1816
|
}
|
|
1762
|
-
if (chunk.thinking) {
|
|
1817
|
+
if (chunk.thinking && !emittedText) {
|
|
1763
1818
|
yield { type: "thinking-delta", text: chunk.thinking };
|
|
1764
1819
|
}
|
|
1765
1820
|
if (chunk.tool_calls && chunk.tool_calls.length > 0) {
|
|
@@ -1768,6 +1823,7 @@ async function* runAgent(opts) {
|
|
|
1768
1823
|
if (chunk.done) {
|
|
1769
1824
|
promptTokens += chunk.prompt_eval_count ?? 0;
|
|
1770
1825
|
evalTokens += chunk.eval_count ?? 0;
|
|
1826
|
+
if (chunk.done_reason === "length") truncated = true;
|
|
1771
1827
|
}
|
|
1772
1828
|
}
|
|
1773
1829
|
} catch (err) {
|
|
@@ -1806,6 +1862,19 @@ async function* runAgent(opts) {
|
|
|
1806
1862
|
}
|
|
1807
1863
|
const tool_uses = blocks.filter((b) => b.type === "tool_use");
|
|
1808
1864
|
history.push({ role: "assistant", content: blocks });
|
|
1865
|
+
if (truncated && tool_uses.length > 0) {
|
|
1866
|
+
const results2 = tool_uses.map((use) => ({
|
|
1867
|
+
type: "tool_result",
|
|
1868
|
+
tool_use_id: use.id,
|
|
1869
|
+
content: splitWriteHint(use.name, "truncated"),
|
|
1870
|
+
is_error: true
|
|
1871
|
+
}));
|
|
1872
|
+
for (const u of tool_uses) yield { type: "tool-use", block: u };
|
|
1873
|
+
for (const r of results2) yield { type: "tool-result", block: r };
|
|
1874
|
+
history.push({ role: "user", content: results2 });
|
|
1875
|
+
yield { type: "turn-end", stop_reason: "tool_use" };
|
|
1876
|
+
continue;
|
|
1877
|
+
}
|
|
1809
1878
|
if (tool_uses.length === 0) {
|
|
1810
1879
|
yield { type: "turn-end", stop_reason: "end_turn" };
|
|
1811
1880
|
break;
|
|
@@ -1840,12 +1909,14 @@ async function* runAgent(opts) {
|
|
|
1840
1909
|
yield { type: "tool-result", block: r2 };
|
|
1841
1910
|
continue;
|
|
1842
1911
|
}
|
|
1912
|
+
use.input = unwrapEnvelope(use.name, use.input);
|
|
1843
1913
|
const invalid = validateInput(tool.input_schema, use.input);
|
|
1844
1914
|
if (invalid) {
|
|
1915
|
+
const content = looksTruncatedWrite(use.name, use.input) ? splitWriteHint(use.name, "garbled") : `${invalid} for ${use.name}. Pass the arguments directly as the tool input \u2014 do NOT wrap them in {"name":...,"arguments":...}. Correct shape: ${exampleInput(tool.input_schema)}. Retry with all required fields.`;
|
|
1845
1916
|
const r2 = {
|
|
1846
1917
|
type: "tool_result",
|
|
1847
1918
|
tool_use_id: use.id,
|
|
1848
|
-
content
|
|
1919
|
+
content,
|
|
1849
1920
|
is_error: true
|
|
1850
1921
|
};
|
|
1851
1922
|
results.push(r2);
|
|
@@ -1912,7 +1983,7 @@ async function* runAgent(opts) {
|
|
|
1912
1983
|
yield { type: "done", prompt_tokens: promptTokens, eval_tokens: evalTokens };
|
|
1913
1984
|
return history;
|
|
1914
1985
|
}
|
|
1915
|
-
var MAX_TURNS, REPEAT_TAIL, REPEAT_KILL,
|
|
1986
|
+
var MAX_TURNS, REPEAT_TAIL, REPEAT_KILL, BIG_WRITE_TOOLS;
|
|
1916
1987
|
var init_loop = __esm({
|
|
1917
1988
|
"src/agent/loop.ts"() {
|
|
1918
1989
|
"use strict";
|
|
@@ -1929,7 +2000,7 @@ var init_loop = __esm({
|
|
|
1929
2000
|
MAX_TURNS = 25;
|
|
1930
2001
|
REPEAT_TAIL = 120;
|
|
1931
2002
|
REPEAT_KILL = 4;
|
|
1932
|
-
|
|
2003
|
+
BIG_WRITE_TOOLS = /* @__PURE__ */ new Set(["write_file", "edit_file"]);
|
|
1933
2004
|
}
|
|
1934
2005
|
});
|
|
1935
2006
|
|
|
@@ -2159,7 +2230,7 @@ import { createElement } from "react";
|
|
|
2159
2230
|
init_client();
|
|
2160
2231
|
init_config();
|
|
2161
2232
|
import { useState as useState5, useEffect as useEffect4, useRef as useRef2 } from "react";
|
|
2162
|
-
import { Box as
|
|
2233
|
+
import { Box as Box13, Text as Text13, useApp } from "ink";
|
|
2163
2234
|
import { homedir as homedir6 } from "os";
|
|
2164
2235
|
import { sep as sep2 } from "path";
|
|
2165
2236
|
|
|
@@ -2201,7 +2272,7 @@ import { memo, useEffect, useState } from "react";
|
|
|
2201
2272
|
import { Box as Box2, Text as Text2 } from "ink";
|
|
2202
2273
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2203
2274
|
var SPIN = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
2204
|
-
var InputBar = memo(function InputBar2({ input, disabled, processingLabel }) {
|
|
2275
|
+
var InputBar = memo(function InputBar2({ input, caret, disabled, processingLabel }) {
|
|
2205
2276
|
const [frame, setFrame] = useState(0);
|
|
2206
2277
|
useEffect(() => {
|
|
2207
2278
|
if (!disabled) return;
|
|
@@ -2224,8 +2295,17 @@ var InputBar = memo(function InputBar2({ input, disabled, processingLabel }) {
|
|
|
2224
2295
|
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " (esc to cancel)" })
|
|
2225
2296
|
] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
2226
2297
|
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "> " }),
|
|
2227
|
-
|
|
2228
|
-
|
|
2298
|
+
(() => {
|
|
2299
|
+
const pos = Math.max(0, Math.min(caret ?? input.length, input.length));
|
|
2300
|
+
const before = input.slice(0, pos);
|
|
2301
|
+
const at = input.slice(pos, pos + 1) || " ";
|
|
2302
|
+
const after = input.slice(pos + 1);
|
|
2303
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
2304
|
+
/* @__PURE__ */ jsx2(Text2, { children: before }),
|
|
2305
|
+
/* @__PURE__ */ jsx2(Text2, { inverse: true, children: at }),
|
|
2306
|
+
/* @__PURE__ */ jsx2(Text2, { children: after })
|
|
2307
|
+
] });
|
|
2308
|
+
})()
|
|
2229
2309
|
] })
|
|
2230
2310
|
}
|
|
2231
2311
|
);
|
|
@@ -2634,9 +2714,565 @@ function FilePicker({ matches: matches2, cursor }) {
|
|
|
2634
2714
|
}
|
|
2635
2715
|
|
|
2636
2716
|
// src/ui/ChatView.tsx
|
|
2637
|
-
import {
|
|
2638
|
-
|
|
2639
|
-
|
|
2717
|
+
import { Box as Box12, Text as Text12, Static } from "ink";
|
|
2718
|
+
|
|
2719
|
+
// src/ui/markdown.ts
|
|
2720
|
+
import { Marked } from "marked";
|
|
2721
|
+
import { markedTerminal } from "marked-terminal";
|
|
2722
|
+
import { highlight, supportsLanguage } from "cli-highlight";
|
|
2723
|
+
|
|
2724
|
+
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
2725
|
+
var ANSI_BACKGROUND_OFFSET = 10;
|
|
2726
|
+
var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
|
|
2727
|
+
var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
|
|
2728
|
+
var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
|
|
2729
|
+
var styles = {
|
|
2730
|
+
modifier: {
|
|
2731
|
+
reset: [0, 0],
|
|
2732
|
+
// 21 isn't widely supported and 22 does the same thing
|
|
2733
|
+
bold: [1, 22],
|
|
2734
|
+
dim: [2, 22],
|
|
2735
|
+
italic: [3, 23],
|
|
2736
|
+
underline: [4, 24],
|
|
2737
|
+
overline: [53, 55],
|
|
2738
|
+
inverse: [7, 27],
|
|
2739
|
+
hidden: [8, 28],
|
|
2740
|
+
strikethrough: [9, 29]
|
|
2741
|
+
},
|
|
2742
|
+
color: {
|
|
2743
|
+
black: [30, 39],
|
|
2744
|
+
red: [31, 39],
|
|
2745
|
+
green: [32, 39],
|
|
2746
|
+
yellow: [33, 39],
|
|
2747
|
+
blue: [34, 39],
|
|
2748
|
+
magenta: [35, 39],
|
|
2749
|
+
cyan: [36, 39],
|
|
2750
|
+
white: [37, 39],
|
|
2751
|
+
// Bright color
|
|
2752
|
+
blackBright: [90, 39],
|
|
2753
|
+
gray: [90, 39],
|
|
2754
|
+
// Alias of `blackBright`
|
|
2755
|
+
grey: [90, 39],
|
|
2756
|
+
// Alias of `blackBright`
|
|
2757
|
+
redBright: [91, 39],
|
|
2758
|
+
greenBright: [92, 39],
|
|
2759
|
+
yellowBright: [93, 39],
|
|
2760
|
+
blueBright: [94, 39],
|
|
2761
|
+
magentaBright: [95, 39],
|
|
2762
|
+
cyanBright: [96, 39],
|
|
2763
|
+
whiteBright: [97, 39]
|
|
2764
|
+
},
|
|
2765
|
+
bgColor: {
|
|
2766
|
+
bgBlack: [40, 49],
|
|
2767
|
+
bgRed: [41, 49],
|
|
2768
|
+
bgGreen: [42, 49],
|
|
2769
|
+
bgYellow: [43, 49],
|
|
2770
|
+
bgBlue: [44, 49],
|
|
2771
|
+
bgMagenta: [45, 49],
|
|
2772
|
+
bgCyan: [46, 49],
|
|
2773
|
+
bgWhite: [47, 49],
|
|
2774
|
+
// Bright color
|
|
2775
|
+
bgBlackBright: [100, 49],
|
|
2776
|
+
bgGray: [100, 49],
|
|
2777
|
+
// Alias of `bgBlackBright`
|
|
2778
|
+
bgGrey: [100, 49],
|
|
2779
|
+
// Alias of `bgBlackBright`
|
|
2780
|
+
bgRedBright: [101, 49],
|
|
2781
|
+
bgGreenBright: [102, 49],
|
|
2782
|
+
bgYellowBright: [103, 49],
|
|
2783
|
+
bgBlueBright: [104, 49],
|
|
2784
|
+
bgMagentaBright: [105, 49],
|
|
2785
|
+
bgCyanBright: [106, 49],
|
|
2786
|
+
bgWhiteBright: [107, 49]
|
|
2787
|
+
}
|
|
2788
|
+
};
|
|
2789
|
+
var modifierNames = Object.keys(styles.modifier);
|
|
2790
|
+
var foregroundColorNames = Object.keys(styles.color);
|
|
2791
|
+
var backgroundColorNames = Object.keys(styles.bgColor);
|
|
2792
|
+
var colorNames = [...foregroundColorNames, ...backgroundColorNames];
|
|
2793
|
+
function assembleStyles() {
|
|
2794
|
+
const codes = /* @__PURE__ */ new Map();
|
|
2795
|
+
for (const [groupName, group] of Object.entries(styles)) {
|
|
2796
|
+
for (const [styleName, style] of Object.entries(group)) {
|
|
2797
|
+
styles[styleName] = {
|
|
2798
|
+
open: `\x1B[${style[0]}m`,
|
|
2799
|
+
close: `\x1B[${style[1]}m`
|
|
2800
|
+
};
|
|
2801
|
+
group[styleName] = styles[styleName];
|
|
2802
|
+
codes.set(style[0], style[1]);
|
|
2803
|
+
}
|
|
2804
|
+
Object.defineProperty(styles, groupName, {
|
|
2805
|
+
value: group,
|
|
2806
|
+
enumerable: false
|
|
2807
|
+
});
|
|
2808
|
+
}
|
|
2809
|
+
Object.defineProperty(styles, "codes", {
|
|
2810
|
+
value: codes,
|
|
2811
|
+
enumerable: false
|
|
2812
|
+
});
|
|
2813
|
+
styles.color.close = "\x1B[39m";
|
|
2814
|
+
styles.bgColor.close = "\x1B[49m";
|
|
2815
|
+
styles.color.ansi = wrapAnsi16();
|
|
2816
|
+
styles.color.ansi256 = wrapAnsi256();
|
|
2817
|
+
styles.color.ansi16m = wrapAnsi16m();
|
|
2818
|
+
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
|
2819
|
+
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
|
2820
|
+
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
2821
|
+
Object.defineProperties(styles, {
|
|
2822
|
+
rgbToAnsi256: {
|
|
2823
|
+
value(red, green, blue) {
|
|
2824
|
+
if (red === green && green === blue) {
|
|
2825
|
+
if (red < 8) {
|
|
2826
|
+
return 16;
|
|
2827
|
+
}
|
|
2828
|
+
if (red > 248) {
|
|
2829
|
+
return 231;
|
|
2830
|
+
}
|
|
2831
|
+
return Math.round((red - 8) / 247 * 24) + 232;
|
|
2832
|
+
}
|
|
2833
|
+
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
2834
|
+
},
|
|
2835
|
+
enumerable: false
|
|
2836
|
+
},
|
|
2837
|
+
hexToRgb: {
|
|
2838
|
+
value(hex) {
|
|
2839
|
+
const matches2 = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
|
2840
|
+
if (!matches2) {
|
|
2841
|
+
return [0, 0, 0];
|
|
2842
|
+
}
|
|
2843
|
+
let [colorString] = matches2;
|
|
2844
|
+
if (colorString.length === 3) {
|
|
2845
|
+
colorString = [...colorString].map((character) => character + character).join("");
|
|
2846
|
+
}
|
|
2847
|
+
const integer = Number.parseInt(colorString, 16);
|
|
2848
|
+
return [
|
|
2849
|
+
/* eslint-disable no-bitwise */
|
|
2850
|
+
integer >> 16 & 255,
|
|
2851
|
+
integer >> 8 & 255,
|
|
2852
|
+
integer & 255
|
|
2853
|
+
/* eslint-enable no-bitwise */
|
|
2854
|
+
];
|
|
2855
|
+
},
|
|
2856
|
+
enumerable: false
|
|
2857
|
+
},
|
|
2858
|
+
hexToAnsi256: {
|
|
2859
|
+
value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
|
2860
|
+
enumerable: false
|
|
2861
|
+
},
|
|
2862
|
+
ansi256ToAnsi: {
|
|
2863
|
+
value(code) {
|
|
2864
|
+
if (code < 8) {
|
|
2865
|
+
return 30 + code;
|
|
2866
|
+
}
|
|
2867
|
+
if (code < 16) {
|
|
2868
|
+
return 90 + (code - 8);
|
|
2869
|
+
}
|
|
2870
|
+
let red;
|
|
2871
|
+
let green;
|
|
2872
|
+
let blue;
|
|
2873
|
+
if (code >= 232) {
|
|
2874
|
+
red = ((code - 232) * 10 + 8) / 255;
|
|
2875
|
+
green = red;
|
|
2876
|
+
blue = red;
|
|
2877
|
+
} else {
|
|
2878
|
+
code -= 16;
|
|
2879
|
+
const remainder = code % 36;
|
|
2880
|
+
red = Math.floor(code / 36) / 5;
|
|
2881
|
+
green = Math.floor(remainder / 6) / 5;
|
|
2882
|
+
blue = remainder % 6 / 5;
|
|
2883
|
+
}
|
|
2884
|
+
const value = Math.max(red, green, blue) * 2;
|
|
2885
|
+
if (value === 0) {
|
|
2886
|
+
return 30;
|
|
2887
|
+
}
|
|
2888
|
+
let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
|
|
2889
|
+
if (value === 2) {
|
|
2890
|
+
result += 60;
|
|
2891
|
+
}
|
|
2892
|
+
return result;
|
|
2893
|
+
},
|
|
2894
|
+
enumerable: false
|
|
2895
|
+
},
|
|
2896
|
+
rgbToAnsi: {
|
|
2897
|
+
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
2898
|
+
enumerable: false
|
|
2899
|
+
},
|
|
2900
|
+
hexToAnsi: {
|
|
2901
|
+
value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
2902
|
+
enumerable: false
|
|
2903
|
+
}
|
|
2904
|
+
});
|
|
2905
|
+
return styles;
|
|
2906
|
+
}
|
|
2907
|
+
var ansiStyles = assembleStyles();
|
|
2908
|
+
var ansi_styles_default = ansiStyles;
|
|
2909
|
+
|
|
2910
|
+
// node_modules/chalk/source/vendor/supports-color/index.js
|
|
2911
|
+
import process2 from "process";
|
|
2912
|
+
import os from "os";
|
|
2913
|
+
import tty from "tty";
|
|
2914
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
|
|
2915
|
+
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
2916
|
+
const position = argv.indexOf(prefix + flag);
|
|
2917
|
+
const terminatorPosition = argv.indexOf("--");
|
|
2918
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
2919
|
+
}
|
|
2920
|
+
var { env } = process2;
|
|
2921
|
+
var flagForceColor;
|
|
2922
|
+
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
2923
|
+
flagForceColor = 0;
|
|
2924
|
+
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
2925
|
+
flagForceColor = 1;
|
|
2926
|
+
}
|
|
2927
|
+
function envForceColor() {
|
|
2928
|
+
if ("FORCE_COLOR" in env) {
|
|
2929
|
+
if (env.FORCE_COLOR === "true") {
|
|
2930
|
+
return 1;
|
|
2931
|
+
}
|
|
2932
|
+
if (env.FORCE_COLOR === "false") {
|
|
2933
|
+
return 0;
|
|
2934
|
+
}
|
|
2935
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
function translateLevel(level) {
|
|
2939
|
+
if (level === 0) {
|
|
2940
|
+
return false;
|
|
2941
|
+
}
|
|
2942
|
+
return {
|
|
2943
|
+
level,
|
|
2944
|
+
hasBasic: true,
|
|
2945
|
+
has256: level >= 2,
|
|
2946
|
+
has16m: level >= 3
|
|
2947
|
+
};
|
|
2948
|
+
}
|
|
2949
|
+
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
2950
|
+
const noFlagForceColor = envForceColor();
|
|
2951
|
+
if (noFlagForceColor !== void 0) {
|
|
2952
|
+
flagForceColor = noFlagForceColor;
|
|
2953
|
+
}
|
|
2954
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
2955
|
+
if (forceColor === 0) {
|
|
2956
|
+
return 0;
|
|
2957
|
+
}
|
|
2958
|
+
if (sniffFlags) {
|
|
2959
|
+
if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
|
|
2960
|
+
return 3;
|
|
2961
|
+
}
|
|
2962
|
+
if (hasFlag("color=256")) {
|
|
2963
|
+
return 2;
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
if ("TF_BUILD" in env && "AGENT_NAME" in env) {
|
|
2967
|
+
return 1;
|
|
2968
|
+
}
|
|
2969
|
+
if (haveStream && !streamIsTTY && forceColor === void 0) {
|
|
2970
|
+
return 0;
|
|
2971
|
+
}
|
|
2972
|
+
const min = forceColor || 0;
|
|
2973
|
+
if (env.TERM === "dumb") {
|
|
2974
|
+
return min;
|
|
2975
|
+
}
|
|
2976
|
+
if (process2.platform === "win32") {
|
|
2977
|
+
const osRelease = os.release().split(".");
|
|
2978
|
+
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
2979
|
+
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
2980
|
+
}
|
|
2981
|
+
return 1;
|
|
2982
|
+
}
|
|
2983
|
+
if ("CI" in env) {
|
|
2984
|
+
if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => key in env)) {
|
|
2985
|
+
return 3;
|
|
2986
|
+
}
|
|
2987
|
+
if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
|
|
2988
|
+
return 1;
|
|
2989
|
+
}
|
|
2990
|
+
return min;
|
|
2991
|
+
}
|
|
2992
|
+
if ("TEAMCITY_VERSION" in env) {
|
|
2993
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
2994
|
+
}
|
|
2995
|
+
if (env.COLORTERM === "truecolor") {
|
|
2996
|
+
return 3;
|
|
2997
|
+
}
|
|
2998
|
+
if (env.TERM === "xterm-kitty") {
|
|
2999
|
+
return 3;
|
|
3000
|
+
}
|
|
3001
|
+
if (env.TERM === "xterm-ghostty") {
|
|
3002
|
+
return 3;
|
|
3003
|
+
}
|
|
3004
|
+
if (env.TERM === "wezterm") {
|
|
3005
|
+
return 3;
|
|
3006
|
+
}
|
|
3007
|
+
if ("TERM_PROGRAM" in env) {
|
|
3008
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
3009
|
+
switch (env.TERM_PROGRAM) {
|
|
3010
|
+
case "iTerm.app": {
|
|
3011
|
+
return version >= 3 ? 3 : 2;
|
|
3012
|
+
}
|
|
3013
|
+
case "Apple_Terminal": {
|
|
3014
|
+
return 2;
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
3018
|
+
if (/-256(color)?$/i.test(env.TERM)) {
|
|
3019
|
+
return 2;
|
|
3020
|
+
}
|
|
3021
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
3022
|
+
return 1;
|
|
3023
|
+
}
|
|
3024
|
+
if ("COLORTERM" in env) {
|
|
3025
|
+
return 1;
|
|
3026
|
+
}
|
|
3027
|
+
return min;
|
|
3028
|
+
}
|
|
3029
|
+
function createSupportsColor(stream, options = {}) {
|
|
3030
|
+
const level = _supportsColor(stream, {
|
|
3031
|
+
streamIsTTY: stream && stream.isTTY,
|
|
3032
|
+
...options
|
|
3033
|
+
});
|
|
3034
|
+
return translateLevel(level);
|
|
3035
|
+
}
|
|
3036
|
+
var supportsColor = {
|
|
3037
|
+
stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
|
|
3038
|
+
stderr: createSupportsColor({ isTTY: tty.isatty(2) })
|
|
3039
|
+
};
|
|
3040
|
+
var supports_color_default = supportsColor;
|
|
3041
|
+
|
|
3042
|
+
// node_modules/chalk/source/utilities.js
|
|
3043
|
+
function stringReplaceAll(string, substring, replacer) {
|
|
3044
|
+
let index = string.indexOf(substring);
|
|
3045
|
+
if (index === -1) {
|
|
3046
|
+
return string;
|
|
3047
|
+
}
|
|
3048
|
+
const substringLength = substring.length;
|
|
3049
|
+
let endIndex = 0;
|
|
3050
|
+
let returnValue = "";
|
|
3051
|
+
do {
|
|
3052
|
+
returnValue += string.slice(endIndex, index) + substring + replacer;
|
|
3053
|
+
endIndex = index + substringLength;
|
|
3054
|
+
index = string.indexOf(substring, endIndex);
|
|
3055
|
+
} while (index !== -1);
|
|
3056
|
+
returnValue += string.slice(endIndex);
|
|
3057
|
+
return returnValue;
|
|
3058
|
+
}
|
|
3059
|
+
function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
|
|
3060
|
+
let endIndex = 0;
|
|
3061
|
+
let returnValue = "";
|
|
3062
|
+
do {
|
|
3063
|
+
const gotCR = string[index - 1] === "\r";
|
|
3064
|
+
returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
|
|
3065
|
+
endIndex = index + 1;
|
|
3066
|
+
index = string.indexOf("\n", endIndex);
|
|
3067
|
+
} while (index !== -1);
|
|
3068
|
+
returnValue += string.slice(endIndex);
|
|
3069
|
+
return returnValue;
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
// node_modules/chalk/source/index.js
|
|
3073
|
+
var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
|
|
3074
|
+
var GENERATOR = /* @__PURE__ */ Symbol("GENERATOR");
|
|
3075
|
+
var STYLER = /* @__PURE__ */ Symbol("STYLER");
|
|
3076
|
+
var IS_EMPTY = /* @__PURE__ */ Symbol("IS_EMPTY");
|
|
3077
|
+
var levelMapping = [
|
|
3078
|
+
"ansi",
|
|
3079
|
+
"ansi",
|
|
3080
|
+
"ansi256",
|
|
3081
|
+
"ansi16m"
|
|
3082
|
+
];
|
|
3083
|
+
var styles2 = /* @__PURE__ */ Object.create(null);
|
|
3084
|
+
var applyOptions = (object, options = {}) => {
|
|
3085
|
+
if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
|
|
3086
|
+
throw new Error("The `level` option should be an integer from 0 to 3");
|
|
3087
|
+
}
|
|
3088
|
+
const colorLevel = stdoutColor ? stdoutColor.level : 0;
|
|
3089
|
+
object.level = options.level === void 0 ? colorLevel : options.level;
|
|
3090
|
+
};
|
|
3091
|
+
var chalkFactory = (options) => {
|
|
3092
|
+
const chalk2 = (...strings) => strings.join(" ");
|
|
3093
|
+
applyOptions(chalk2, options);
|
|
3094
|
+
Object.setPrototypeOf(chalk2, createChalk.prototype);
|
|
3095
|
+
return chalk2;
|
|
3096
|
+
};
|
|
3097
|
+
function createChalk(options) {
|
|
3098
|
+
return chalkFactory(options);
|
|
3099
|
+
}
|
|
3100
|
+
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
|
|
3101
|
+
for (const [styleName, style] of Object.entries(ansi_styles_default)) {
|
|
3102
|
+
styles2[styleName] = {
|
|
3103
|
+
get() {
|
|
3104
|
+
const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
|
|
3105
|
+
Object.defineProperty(this, styleName, { value: builder });
|
|
3106
|
+
return builder;
|
|
3107
|
+
}
|
|
3108
|
+
};
|
|
3109
|
+
}
|
|
3110
|
+
styles2.visible = {
|
|
3111
|
+
get() {
|
|
3112
|
+
const builder = createBuilder(this, this[STYLER], true);
|
|
3113
|
+
Object.defineProperty(this, "visible", { value: builder });
|
|
3114
|
+
return builder;
|
|
3115
|
+
}
|
|
3116
|
+
};
|
|
3117
|
+
var getModelAnsi = (model, level, type, ...arguments_) => {
|
|
3118
|
+
if (model === "rgb") {
|
|
3119
|
+
if (level === "ansi16m") {
|
|
3120
|
+
return ansi_styles_default[type].ansi16m(...arguments_);
|
|
3121
|
+
}
|
|
3122
|
+
if (level === "ansi256") {
|
|
3123
|
+
return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
|
|
3124
|
+
}
|
|
3125
|
+
return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
|
|
3126
|
+
}
|
|
3127
|
+
if (model === "hex") {
|
|
3128
|
+
return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
|
|
3129
|
+
}
|
|
3130
|
+
return ansi_styles_default[type][model](...arguments_);
|
|
3131
|
+
};
|
|
3132
|
+
var usedModels = ["rgb", "hex", "ansi256"];
|
|
3133
|
+
for (const model of usedModels) {
|
|
3134
|
+
styles2[model] = {
|
|
3135
|
+
get() {
|
|
3136
|
+
const { level } = this;
|
|
3137
|
+
return function(...arguments_) {
|
|
3138
|
+
const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
|
|
3139
|
+
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
3140
|
+
};
|
|
3141
|
+
}
|
|
3142
|
+
};
|
|
3143
|
+
const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
|
|
3144
|
+
styles2[bgModel] = {
|
|
3145
|
+
get() {
|
|
3146
|
+
const { level } = this;
|
|
3147
|
+
return function(...arguments_) {
|
|
3148
|
+
const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
|
|
3149
|
+
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
3150
|
+
};
|
|
3151
|
+
}
|
|
3152
|
+
};
|
|
3153
|
+
}
|
|
3154
|
+
var proto = Object.defineProperties(() => {
|
|
3155
|
+
}, {
|
|
3156
|
+
...styles2,
|
|
3157
|
+
level: {
|
|
3158
|
+
enumerable: true,
|
|
3159
|
+
get() {
|
|
3160
|
+
return this[GENERATOR].level;
|
|
3161
|
+
},
|
|
3162
|
+
set(level) {
|
|
3163
|
+
this[GENERATOR].level = level;
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
});
|
|
3167
|
+
var createStyler = (open, close, parent) => {
|
|
3168
|
+
let openAll;
|
|
3169
|
+
let closeAll;
|
|
3170
|
+
if (parent === void 0) {
|
|
3171
|
+
openAll = open;
|
|
3172
|
+
closeAll = close;
|
|
3173
|
+
} else {
|
|
3174
|
+
openAll = parent.openAll + open;
|
|
3175
|
+
closeAll = close + parent.closeAll;
|
|
3176
|
+
}
|
|
3177
|
+
return {
|
|
3178
|
+
open,
|
|
3179
|
+
close,
|
|
3180
|
+
openAll,
|
|
3181
|
+
closeAll,
|
|
3182
|
+
parent
|
|
3183
|
+
};
|
|
3184
|
+
};
|
|
3185
|
+
var createBuilder = (self, _styler, _isEmpty) => {
|
|
3186
|
+
const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
|
|
3187
|
+
Object.setPrototypeOf(builder, proto);
|
|
3188
|
+
builder[GENERATOR] = self;
|
|
3189
|
+
builder[STYLER] = _styler;
|
|
3190
|
+
builder[IS_EMPTY] = _isEmpty;
|
|
3191
|
+
return builder;
|
|
3192
|
+
};
|
|
3193
|
+
var applyStyle = (self, string) => {
|
|
3194
|
+
if (self.level <= 0 || !string) {
|
|
3195
|
+
return self[IS_EMPTY] ? "" : string;
|
|
3196
|
+
}
|
|
3197
|
+
let styler = self[STYLER];
|
|
3198
|
+
if (styler === void 0) {
|
|
3199
|
+
return string;
|
|
3200
|
+
}
|
|
3201
|
+
const { openAll, closeAll } = styler;
|
|
3202
|
+
if (string.includes("\x1B")) {
|
|
3203
|
+
while (styler !== void 0) {
|
|
3204
|
+
string = stringReplaceAll(string, styler.close, styler.open);
|
|
3205
|
+
styler = styler.parent;
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3208
|
+
const lfIndex = string.indexOf("\n");
|
|
3209
|
+
if (lfIndex !== -1) {
|
|
3210
|
+
string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
|
|
3211
|
+
}
|
|
3212
|
+
return openAll + string + closeAll;
|
|
3213
|
+
};
|
|
3214
|
+
Object.defineProperties(createChalk.prototype, styles2);
|
|
3215
|
+
var chalk = createChalk();
|
|
3216
|
+
var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
3217
|
+
var source_default = chalk;
|
|
3218
|
+
|
|
3219
|
+
// src/ui/markdown.ts
|
|
3220
|
+
var theme = {
|
|
3221
|
+
heading: source_default.hex("#7fa8d4").bold,
|
|
3222
|
+
// dusty blue
|
|
3223
|
+
firstHeading: source_default.hex("#9ab8de").bold,
|
|
3224
|
+
// slightly lighter for h1
|
|
3225
|
+
strong: source_default.hex("#d6c9a8").bold,
|
|
3226
|
+
// warm sand
|
|
3227
|
+
em: source_default.hex("#b59ec4").italic,
|
|
3228
|
+
// soft mauve
|
|
3229
|
+
del: source_default.hex("#6b7280").strikethrough,
|
|
3230
|
+
// dim gray
|
|
3231
|
+
codespan: source_default.hex("#c8a98a"),
|
|
3232
|
+
// muted clay
|
|
3233
|
+
link: source_default.hex("#83b3a6").underline,
|
|
3234
|
+
// sage teal
|
|
3235
|
+
href: source_default.hex("#83b3a6").underline,
|
|
3236
|
+
blockquote: source_default.hex("#8a9aa8").italic,
|
|
3237
|
+
// slate
|
|
3238
|
+
listitem: source_default.hex("#c4c9cf"),
|
|
3239
|
+
// off-white
|
|
3240
|
+
paragraph: source_default.hex("#c4c9cf"),
|
|
3241
|
+
// off-white body text
|
|
3242
|
+
hr: source_default.hex("#4b5563")
|
|
3243
|
+
// faint rule
|
|
3244
|
+
};
|
|
3245
|
+
function highlightCode(code, lang) {
|
|
3246
|
+
if (!lang || !supportsLanguage(lang)) return code;
|
|
3247
|
+
try {
|
|
3248
|
+
return highlight(code, { language: lang, ignoreIllegals: true });
|
|
3249
|
+
} catch {
|
|
3250
|
+
return code;
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
var md = new Marked();
|
|
3254
|
+
md.use(
|
|
3255
|
+
markedTerminal({
|
|
3256
|
+
// Drop the literal `#` prefix on headings; render them styled instead.
|
|
3257
|
+
showSectionPrefix: false,
|
|
3258
|
+
// marked-terminal calls this for ``` blocks; fall back to plain on unknown lang.
|
|
3259
|
+
code: (code, lang) => highlightCode(code, lang),
|
|
3260
|
+
...theme
|
|
3261
|
+
})
|
|
3262
|
+
);
|
|
3263
|
+
function renderMarkdown(content) {
|
|
3264
|
+
try {
|
|
3265
|
+
const out = md.parse(content, { async: false });
|
|
3266
|
+
return out.replace(/\n+$/, "");
|
|
3267
|
+
} catch {
|
|
3268
|
+
return content;
|
|
3269
|
+
}
|
|
3270
|
+
}
|
|
3271
|
+
function renderMarkdownStreaming(content) {
|
|
3272
|
+
const fences = (content.match(/^```/gm) ?? []).length;
|
|
3273
|
+
const balanced = fences % 2 === 1 ? content + "\n```" : content;
|
|
3274
|
+
return renderMarkdown(balanced);
|
|
3275
|
+
}
|
|
2640
3276
|
|
|
2641
3277
|
// src/ui/ThinkingBlock.tsx
|
|
2642
3278
|
import { useState as useState2, useEffect as useEffect2 } from "react";
|
|
@@ -2680,7 +3316,12 @@ function ThinkingBlock({ content }) {
|
|
|
2680
3316
|
" thoughts"
|
|
2681
3317
|
] })
|
|
2682
3318
|
] }),
|
|
2683
|
-
visible && content ?
|
|
3319
|
+
visible && content ? (() => {
|
|
3320
|
+
const max = Math.max(4, (process.stdout.rows ?? 24) - 10);
|
|
3321
|
+
const lines = content.split("\n");
|
|
3322
|
+
const shown = lines.length > max ? lines.slice(-max) : lines;
|
|
3323
|
+
return /* @__PURE__ */ jsx8(Box8, { marginLeft: 2, children: /* @__PURE__ */ jsx8(Text8, { dimColor: true, italic: true, children: shown.join("\n") }) });
|
|
3324
|
+
})() : null
|
|
2684
3325
|
] });
|
|
2685
3326
|
}
|
|
2686
3327
|
|
|
@@ -2694,9 +3335,16 @@ var EMPTY_STATE_HINTS = [
|
|
|
2694
3335
|
];
|
|
2695
3336
|
var EMPTY_STATE_TITLE = "Ask anything, or try:";
|
|
2696
3337
|
|
|
2697
|
-
// src/ui/
|
|
2698
|
-
import {
|
|
2699
|
-
|
|
3338
|
+
// src/ui/Message.tsx
|
|
3339
|
+
import { memo as memo2 } from "react";
|
|
3340
|
+
import { Box as Box10, Text as Text10 } from "ink";
|
|
3341
|
+
|
|
3342
|
+
// src/ui/ToolBlock.tsx
|
|
3343
|
+
import { Box as Box9, Text as Text9 } from "ink";
|
|
3344
|
+
import { highlight as highlight2, supportsLanguage as supportsLanguage2 } from "cli-highlight";
|
|
3345
|
+
|
|
3346
|
+
// src/ui/toolExpand.ts
|
|
3347
|
+
import { useState as useState3, useEffect as useEffect3 } from "react";
|
|
2700
3348
|
var globalToolExpanded = false;
|
|
2701
3349
|
var toolExpandListeners = /* @__PURE__ */ new Set();
|
|
2702
3350
|
function toggleToolExpanded() {
|
|
@@ -2714,6 +3362,8 @@ function useToolExpanded() {
|
|
|
2714
3362
|
}, []);
|
|
2715
3363
|
return expanded;
|
|
2716
3364
|
}
|
|
3365
|
+
|
|
3366
|
+
// src/ui/layout.ts
|
|
2717
3367
|
function formatTokens(n) {
|
|
2718
3368
|
if (n >= 1e3) return (n / 1e3).toFixed(n >= 1e4 ? 0 : 1) + "k";
|
|
2719
3369
|
return String(n);
|
|
@@ -2729,6 +3379,61 @@ function countLines(s) {
|
|
|
2729
3379
|
if (!s) return 0;
|
|
2730
3380
|
return s.split("\n").length;
|
|
2731
3381
|
}
|
|
3382
|
+
function truncate2(s, max) {
|
|
3383
|
+
if (s.length <= max) return s;
|
|
3384
|
+
return s.slice(0, max - 1) + "\u2026";
|
|
3385
|
+
}
|
|
3386
|
+
function clipTail(rendered, max) {
|
|
3387
|
+
const lines = rendered.split("\n");
|
|
3388
|
+
if (lines.length <= max) return { text: rendered, clipped: 0 };
|
|
3389
|
+
return { text: lines.slice(-max).join("\n"), clipped: lines.length - max };
|
|
3390
|
+
}
|
|
3391
|
+
function liveFrameRows() {
|
|
3392
|
+
const rows = process.stdout.rows ?? 24;
|
|
3393
|
+
return Math.max(6, rows - 8);
|
|
3394
|
+
}
|
|
3395
|
+
var COLLAPSED_LINES = 3;
|
|
3396
|
+
function estimateToolRows(use, result) {
|
|
3397
|
+
const input = use.input ?? {};
|
|
3398
|
+
const noErr = !result?.is_error;
|
|
3399
|
+
if (use.name === "write_file" && noErr) {
|
|
3400
|
+
const total = countLines(String(input.content ?? ""));
|
|
3401
|
+
const shown = Math.min(total, COLLAPSED_LINES);
|
|
3402
|
+
return 2 + shown + (total > shown ? 1 : 0);
|
|
3403
|
+
}
|
|
3404
|
+
if (use.name === "edit_file" && noErr) {
|
|
3405
|
+
const total = countLines(String(input.old_str ?? "")) + countLines(String(input.new_str ?? ""));
|
|
3406
|
+
const shown = Math.min(total, COLLAPSED_LINES);
|
|
3407
|
+
return 2 + shown + (total > shown ? 1 : 0);
|
|
3408
|
+
}
|
|
3409
|
+
let rows = 1;
|
|
3410
|
+
if (result) {
|
|
3411
|
+
const lines = (result.content ?? "").split("\n");
|
|
3412
|
+
const multi = (use.name === "run_bash" || use.name === "grep" || use.name === "glob" || result.is_error) && lines.length > 1;
|
|
3413
|
+
if (multi) {
|
|
3414
|
+
const shown = Math.min(lines.length, COLLAPSED_LINES);
|
|
3415
|
+
rows += 1 + shown + (lines.length > shown ? 1 : 0);
|
|
3416
|
+
} else {
|
|
3417
|
+
rows += 1;
|
|
3418
|
+
}
|
|
3419
|
+
}
|
|
3420
|
+
return rows;
|
|
3421
|
+
}
|
|
3422
|
+
function contentWidth() {
|
|
3423
|
+
return Math.max(20, (process.stdout.columns ?? 80) - 4);
|
|
3424
|
+
}
|
|
3425
|
+
|
|
3426
|
+
// src/ui/ToolBlock.tsx
|
|
3427
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3428
|
+
var COLLAPSED_LINES2 = 3;
|
|
3429
|
+
var TOOL_LABEL = {
|
|
3430
|
+
write_file: "Write",
|
|
3431
|
+
edit_file: "Update",
|
|
3432
|
+
read_file: "Read",
|
|
3433
|
+
run_bash: "Bash",
|
|
3434
|
+
glob: "Glob",
|
|
3435
|
+
grep: "Grep"
|
|
3436
|
+
};
|
|
2732
3437
|
var EXT_LANG = {
|
|
2733
3438
|
ts: "typescript",
|
|
2734
3439
|
tsx: "typescript",
|
|
@@ -2771,9 +3476,9 @@ function langFromPath(path) {
|
|
|
2771
3476
|
return ext ? EXT_LANG[ext] : void 0;
|
|
2772
3477
|
}
|
|
2773
3478
|
function highlightLine(text, lang) {
|
|
2774
|
-
if (!lang) return text;
|
|
3479
|
+
if (!lang || !supportsLanguage2(lang)) return text;
|
|
2775
3480
|
try {
|
|
2776
|
-
return
|
|
3481
|
+
return highlight2(text, { language: lang, ignoreIllegals: true });
|
|
2777
3482
|
} catch {
|
|
2778
3483
|
return text;
|
|
2779
3484
|
}
|
|
@@ -2786,7 +3491,7 @@ function FileEditBlock({
|
|
|
2786
3491
|
previewLines
|
|
2787
3492
|
}) {
|
|
2788
3493
|
const expanded = useToolExpanded();
|
|
2789
|
-
const shown = expanded ? previewLines : previewLines.slice(0,
|
|
3494
|
+
const shown = expanded ? previewLines : previewLines.slice(0, COLLAPSED_LINES2);
|
|
2790
3495
|
const extra = previewLines.length - shown.length;
|
|
2791
3496
|
const lang = langFromPath(path);
|
|
2792
3497
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", marginLeft: 2, children: [
|
|
@@ -2829,18 +3534,6 @@ function FileEditBlock({
|
|
|
2829
3534
|
] }) })
|
|
2830
3535
|
] });
|
|
2831
3536
|
}
|
|
2832
|
-
var TOOL_LABEL = {
|
|
2833
|
-
write_file: "Write",
|
|
2834
|
-
edit_file: "Update",
|
|
2835
|
-
read_file: "Read",
|
|
2836
|
-
run_bash: "Bash",
|
|
2837
|
-
glob: "Glob",
|
|
2838
|
-
grep: "Grep"
|
|
2839
|
-
};
|
|
2840
|
-
function truncate2(s, max) {
|
|
2841
|
-
if (s.length <= max) return s;
|
|
2842
|
-
return s.slice(0, max - 1) + "\u2026";
|
|
2843
|
-
}
|
|
2844
3537
|
function toolHeader(use) {
|
|
2845
3538
|
const label = TOOL_LABEL[use.name] ?? use.name;
|
|
2846
3539
|
const input = use.input ?? {};
|
|
@@ -2902,7 +3595,7 @@ function ToolResultBlock({ result, toolName }) {
|
|
|
2902
3595
|
] }) });
|
|
2903
3596
|
}
|
|
2904
3597
|
const MAX_LINE_WIDTH = 200;
|
|
2905
|
-
const visible = expanded ? lines : lines.slice(0,
|
|
3598
|
+
const visible = expanded ? lines : lines.slice(0, COLLAPSED_LINES2);
|
|
2906
3599
|
const shown = visible.map((l) => truncate2(l, MAX_LINE_WIDTH));
|
|
2907
3600
|
const extra = lines.length - shown.length;
|
|
2908
3601
|
const header = toolName === "grep" || toolName === "glob" ? summarizeResult(result, toolName) : `${lines.length} line${lines.length === 1 ? "" : "s"}`;
|
|
@@ -2954,28 +3647,35 @@ function ToolUseLine({ use, result }) {
|
|
|
2954
3647
|
result && /* @__PURE__ */ jsx9(ToolResultBlock, { result, toolName: use.name })
|
|
2955
3648
|
] });
|
|
2956
3649
|
}
|
|
3650
|
+
|
|
3651
|
+
// src/ui/Message.tsx
|
|
3652
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2957
3653
|
var UserMessage = memo2(function UserMessage2({ msg }) {
|
|
2958
|
-
return /* @__PURE__ */
|
|
2959
|
-
/* @__PURE__ */
|
|
2960
|
-
/* @__PURE__ */
|
|
3654
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "row", marginBottom: 1, children: [
|
|
3655
|
+
/* @__PURE__ */ jsx10(Text10, { color: "gray", children: "\u276F " }),
|
|
3656
|
+
/* @__PURE__ */ jsx10(Box10, { flexGrow: 1, children: /* @__PURE__ */ jsx10(Text10, { children: msg.content }) })
|
|
2961
3657
|
] });
|
|
2962
3658
|
});
|
|
2963
3659
|
var AssistantMessage = memo2(function AssistantMessage2({ msg }) {
|
|
2964
|
-
return /* @__PURE__ */
|
|
2965
|
-
msg.content && /* @__PURE__ */
|
|
2966
|
-
/* @__PURE__ */
|
|
2967
|
-
/* @__PURE__ */
|
|
3660
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginBottom: 1, children: [
|
|
3661
|
+
msg.content && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "row", children: [
|
|
3662
|
+
/* @__PURE__ */ jsx10(Text10, { color: "blue", children: "\u25CF " }),
|
|
3663
|
+
/* @__PURE__ */ jsx10(Box10, { width: contentWidth(), children: /* @__PURE__ */ jsx10(Text10, { wrap: "wrap", children: renderMarkdown(msg.content) }) })
|
|
2968
3664
|
] }),
|
|
2969
3665
|
msg.tool_uses?.map((u) => {
|
|
2970
3666
|
const r = msg.tool_results?.find((x) => x.tool_use_id === u.id);
|
|
2971
|
-
return /* @__PURE__ */
|
|
3667
|
+
return /* @__PURE__ */ jsx10(ToolUseLine, { use: u, result: r }, u.id);
|
|
2972
3668
|
}),
|
|
2973
|
-
msg.tokens && /* @__PURE__ */
|
|
3669
|
+
msg.tokens && /* @__PURE__ */ jsx10(Box10, { marginLeft: 2, children: /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2974
3670
|
`\u21B3 Completed \xB7 ${formatTokens(msg.tokens.prompt_eval + msg.tokens.eval)} tokens`,
|
|
2975
3671
|
msg.duration != null ? ` \xB7 ${formatDuration(msg.duration)}` : ""
|
|
2976
3672
|
] }) })
|
|
2977
3673
|
] });
|
|
2978
3674
|
});
|
|
3675
|
+
|
|
3676
|
+
// src/ui/PermissionPrompt.tsx
|
|
3677
|
+
import { Box as Box11, Text as Text11 } from "ink";
|
|
3678
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2979
3679
|
function summarizeInput(input) {
|
|
2980
3680
|
if (!input || typeof input !== "object") return "";
|
|
2981
3681
|
const obj = input;
|
|
@@ -3002,15 +3702,15 @@ function PermissionPrompt({ req, cursor }) {
|
|
|
3002
3702
|
{ label: "No", key: "no" }
|
|
3003
3703
|
];
|
|
3004
3704
|
const summary = summarizeInput(req.input);
|
|
3005
|
-
return /* @__PURE__ */
|
|
3006
|
-
/* @__PURE__ */
|
|
3007
|
-
/* @__PURE__ */
|
|
3705
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", marginBottom: 1, borderStyle: "round", borderColor: "blue", paddingX: 1, children: [
|
|
3706
|
+
/* @__PURE__ */ jsx11(Text11, { color: "blue", bold: true, children: "Tool use" }),
|
|
3707
|
+
/* @__PURE__ */ jsx11(Box11, { marginTop: 1, children: /* @__PURE__ */ jsxs11(Text11, { children: [
|
|
3008
3708
|
"Allow ",
|
|
3009
|
-
/* @__PURE__ */
|
|
3709
|
+
/* @__PURE__ */ jsx11(Text11, { bold: true, children: label }),
|
|
3010
3710
|
"?"
|
|
3011
3711
|
] }) }),
|
|
3012
|
-
summary && /* @__PURE__ */
|
|
3013
|
-
/* @__PURE__ */
|
|
3712
|
+
summary && /* @__PURE__ */ jsx11(Box11, { marginLeft: 2, children: /* @__PURE__ */ jsx11(Text11, { wrap: "truncate", dimColor: true, children: summary }) }),
|
|
3713
|
+
/* @__PURE__ */ jsx11(Box11, { flexDirection: "column", marginTop: 1, children: options.map((opt, i) => /* @__PURE__ */ jsxs11(Text11, { color: i === cursor ? "blue" : void 0, children: [
|
|
3014
3714
|
i === cursor ? "\u276F " : " ",
|
|
3015
3715
|
i + 1,
|
|
3016
3716
|
". ",
|
|
@@ -3018,6 +3718,9 @@ function PermissionPrompt({ req, cursor }) {
|
|
|
3018
3718
|
] }, opt.key)) })
|
|
3019
3719
|
] });
|
|
3020
3720
|
}
|
|
3721
|
+
|
|
3722
|
+
// src/ui/ChatView.tsx
|
|
3723
|
+
import { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3021
3724
|
function ChatView({
|
|
3022
3725
|
messages,
|
|
3023
3726
|
streaming,
|
|
@@ -3028,33 +3731,70 @@ function ChatView({
|
|
|
3028
3731
|
pendingPermission,
|
|
3029
3732
|
permissionCursor = 0,
|
|
3030
3733
|
activeToolUses,
|
|
3031
|
-
activeToolResults
|
|
3734
|
+
activeToolResults,
|
|
3735
|
+
header
|
|
3032
3736
|
}) {
|
|
3033
3737
|
const empty = messages.length === 0 && !streaming && !thinking && !pendingPermission && !error;
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3738
|
+
const log = [];
|
|
3739
|
+
if (header) log.push({ key: "header", node: header });
|
|
3740
|
+
messages.forEach((msg, i) => {
|
|
3741
|
+
log.push({
|
|
3742
|
+
key: `msg-${i}`,
|
|
3743
|
+
node: msg.role === "user" ? /* @__PURE__ */ jsx12(UserMessage, { msg }) : /* @__PURE__ */ jsx12(AssistantMessage, { msg })
|
|
3744
|
+
});
|
|
3745
|
+
});
|
|
3746
|
+
const liveBudget = liveFrameRows();
|
|
3747
|
+
let streamNode = null;
|
|
3748
|
+
let streamRows = 0;
|
|
3749
|
+
if (streaming && streamingContent) {
|
|
3750
|
+
const { text, clipped } = clipTail(renderMarkdownStreaming(streamingContent), liveBudget);
|
|
3751
|
+
streamRows = text.split("\n").length + (clipped > 0 ? 1 : 0);
|
|
3752
|
+
streamNode = /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginBottom: 1, children: [
|
|
3753
|
+
clipped > 0 && /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: `\u2191 ${clipped} more line${clipped === 1 ? "" : "s"} above \u2014 streaming\u2026` }),
|
|
3754
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", children: [
|
|
3755
|
+
/* @__PURE__ */ jsx12(Text12, { color: "blue", children: "\u25CF " }),
|
|
3756
|
+
/* @__PURE__ */ jsx12(Box12, { width: contentWidth(), children: /* @__PURE__ */ jsx12(Text12, { wrap: "wrap", children: text }) })
|
|
3757
|
+
] })
|
|
3758
|
+
] });
|
|
3759
|
+
}
|
|
3760
|
+
let toolNode = null;
|
|
3761
|
+
if (activeToolUses?.length) {
|
|
3762
|
+
const remaining = Math.max(4, liveBudget - streamRows);
|
|
3763
|
+
const resultById = new Map(activeToolResults?.map((r) => [r.tool_use_id, r]));
|
|
3764
|
+
const kept = [];
|
|
3765
|
+
let rows = 0;
|
|
3766
|
+
for (let i = activeToolUses.length - 1; i >= 0; i--) {
|
|
3767
|
+
const u = activeToolUses[i];
|
|
3768
|
+
const r = resultById.get(u.id);
|
|
3769
|
+
const h = estimateToolRows(u, r);
|
|
3770
|
+
if (rows + h > remaining && kept.length) break;
|
|
3771
|
+
rows += h;
|
|
3772
|
+
kept.unshift({ u, r });
|
|
3773
|
+
}
|
|
3774
|
+
const hidden = activeToolUses.length - kept.length;
|
|
3775
|
+
toolNode = /* @__PURE__ */ jsxs12(Fragment2, { children: [
|
|
3776
|
+
hidden > 0 && /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: `\u2191 ${hidden} earlier tool call${hidden === 1 ? "" : "s"} above` }),
|
|
3777
|
+
kept.map(({ u, r }) => /* @__PURE__ */ jsx12(ToolUseLine, { use: u, result: r }, u.id))
|
|
3778
|
+
] });
|
|
3779
|
+
}
|
|
3780
|
+
return /* @__PURE__ */ jsxs12(Fragment2, { children: [
|
|
3781
|
+
/* @__PURE__ */ jsx12(Static, { items: log, children: (item) => item.key === "header" ? /* @__PURE__ */ jsx12(Box12, { children: item.node }, item.key) : /* @__PURE__ */ jsx12(Box12, { marginLeft: 1, children: item.node }, item.key) }),
|
|
3782
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginLeft: 1, marginBottom: 1, children: [
|
|
3783
|
+
empty && /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginBottom: 1, children: [
|
|
3784
|
+
/* @__PURE__ */ jsx12(Text12, { dimColor: true, children: EMPTY_STATE_TITLE }),
|
|
3785
|
+
EMPTY_STATE_HINTS.map((h, i) => /* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
|
|
3786
|
+
" ",
|
|
3787
|
+
h
|
|
3788
|
+
] }, i))
|
|
3789
|
+
] }),
|
|
3790
|
+
thinking && /* @__PURE__ */ jsx12(ThinkingBlock, { content: thinkingContent }),
|
|
3791
|
+
streamNode,
|
|
3792
|
+
toolNode,
|
|
3793
|
+
pendingPermission && /* @__PURE__ */ jsx12(PermissionPrompt, { req: pendingPermission, cursor: permissionCursor }),
|
|
3794
|
+
error && /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", marginBottom: 1, children: [
|
|
3795
|
+
/* @__PURE__ */ jsx12(Text12, { color: "red", children: "\u25CF " }),
|
|
3796
|
+
/* @__PURE__ */ jsx12(Text12, { color: "red", children: error })
|
|
3797
|
+
] })
|
|
3058
3798
|
] })
|
|
3059
3799
|
] });
|
|
3060
3800
|
}
|
|
@@ -3294,6 +4034,14 @@ function clearPasteStore() {
|
|
|
3294
4034
|
pasteStore.clear();
|
|
3295
4035
|
pasteCounter = 0;
|
|
3296
4036
|
}
|
|
4037
|
+
var inputHistory = [];
|
|
4038
|
+
var historyIndex = -1;
|
|
4039
|
+
var historyDraft = "";
|
|
4040
|
+
function pushHistory(line) {
|
|
4041
|
+
if (!line) return;
|
|
4042
|
+
if (inputHistory[inputHistory.length - 1] === line) return;
|
|
4043
|
+
inputHistory.push(line);
|
|
4044
|
+
}
|
|
3297
4045
|
function expandPastes(text) {
|
|
3298
4046
|
let out = text;
|
|
3299
4047
|
for (const [chip, full] of pasteStore) out = out.split(chip).join(full);
|
|
@@ -3331,6 +4079,8 @@ function useKeyboard(opts) {
|
|
|
3331
4079
|
agent,
|
|
3332
4080
|
input,
|
|
3333
4081
|
setInput,
|
|
4082
|
+
caret,
|
|
4083
|
+
setCaret,
|
|
3334
4084
|
paletteCursor,
|
|
3335
4085
|
setPaletteCursor,
|
|
3336
4086
|
filePickerCursor,
|
|
@@ -3538,36 +4288,43 @@ function useKeyboard(opts) {
|
|
|
3538
4288
|
const mention = !paletteOpen ? parseMention(input) : null;
|
|
3539
4289
|
const fileMatches = mention ? searchFiles(process.cwd(), mention.query) : [];
|
|
3540
4290
|
const fileOpen = mention !== null && fileMatches.length > 0;
|
|
3541
|
-
if (paletteOpen && key.upArrow) {
|
|
4291
|
+
if (paletteOpen && historyIndex === -1 && key.upArrow) {
|
|
3542
4292
|
setPaletteCursor((i) => Math.max(0, i - 1));
|
|
3543
4293
|
return;
|
|
3544
4294
|
}
|
|
3545
|
-
if (paletteOpen && key.downArrow) {
|
|
4295
|
+
if (paletteOpen && historyIndex === -1 && key.downArrow) {
|
|
3546
4296
|
setPaletteCursor((i) => Math.min(matches2.length - 1, i + 1));
|
|
3547
4297
|
return;
|
|
3548
4298
|
}
|
|
3549
4299
|
if (paletteOpen && (key.tab || key.return) && matches2[paletteCursor] && input !== matches2[paletteCursor].name) {
|
|
3550
|
-
|
|
4300
|
+
const name = matches2[paletteCursor].name;
|
|
4301
|
+
setInput(() => name);
|
|
4302
|
+
setCaret(() => name.length);
|
|
3551
4303
|
setPaletteCursor(() => 0);
|
|
3552
4304
|
return;
|
|
3553
4305
|
}
|
|
3554
4306
|
if (paletteOpen && key.escape) {
|
|
3555
4307
|
clearPasteStore();
|
|
3556
4308
|
setInput(() => "");
|
|
4309
|
+
setCaret(() => 0);
|
|
3557
4310
|
setPaletteCursor(() => 0);
|
|
3558
4311
|
return;
|
|
3559
4312
|
}
|
|
3560
|
-
if (fileOpen && key.upArrow) {
|
|
4313
|
+
if (fileOpen && historyIndex === -1 && key.upArrow) {
|
|
3561
4314
|
setFilePickerCursor((i) => Math.max(0, i - 1));
|
|
3562
4315
|
return;
|
|
3563
4316
|
}
|
|
3564
|
-
if (fileOpen && key.downArrow) {
|
|
4317
|
+
if (fileOpen && historyIndex === -1 && key.downArrow) {
|
|
3565
4318
|
setFilePickerCursor((i) => Math.min(fileMatches.length - 1, i + 1));
|
|
3566
4319
|
return;
|
|
3567
4320
|
}
|
|
3568
4321
|
if (fileOpen && key.tab && fileMatches[filePickerCursor]) {
|
|
3569
4322
|
const picked = fileMatches[filePickerCursor];
|
|
3570
|
-
setInput((s) =>
|
|
4323
|
+
setInput((s) => {
|
|
4324
|
+
const next = s.slice(0, mention.start) + "@" + picked + " ";
|
|
4325
|
+
setCaret(() => next.length);
|
|
4326
|
+
return next;
|
|
4327
|
+
});
|
|
3571
4328
|
setFilePickerCursor(() => 0);
|
|
3572
4329
|
return;
|
|
3573
4330
|
}
|
|
@@ -3575,8 +4332,36 @@ function useKeyboard(opts) {
|
|
|
3575
4332
|
setFilePickerCursor(() => 0);
|
|
3576
4333
|
return;
|
|
3577
4334
|
}
|
|
4335
|
+
if ((historyIndex !== -1 || !paletteOpen && !fileOpen) && key.upArrow) {
|
|
4336
|
+
if (inputHistory.length === 0) return;
|
|
4337
|
+
if (historyIndex === -1) {
|
|
4338
|
+
historyDraft = input;
|
|
4339
|
+
historyIndex = inputHistory.length - 1;
|
|
4340
|
+
} else if (historyIndex > 0) historyIndex--;
|
|
4341
|
+
const val = inputHistory[historyIndex];
|
|
4342
|
+
setInput(() => val);
|
|
4343
|
+
setCaret(() => val.length);
|
|
4344
|
+
return;
|
|
4345
|
+
}
|
|
4346
|
+
if ((historyIndex !== -1 || !paletteOpen && !fileOpen) && key.downArrow) {
|
|
4347
|
+
if (historyIndex === -1) return;
|
|
4348
|
+
if (historyIndex < inputHistory.length - 1) {
|
|
4349
|
+
historyIndex++;
|
|
4350
|
+
const val = inputHistory[historyIndex];
|
|
4351
|
+
setInput(() => val);
|
|
4352
|
+
setCaret(() => val.length);
|
|
4353
|
+
} else {
|
|
4354
|
+
historyIndex = -1;
|
|
4355
|
+
setInput(() => historyDraft);
|
|
4356
|
+
setCaret(() => historyDraft.length);
|
|
4357
|
+
}
|
|
4358
|
+
return;
|
|
4359
|
+
}
|
|
3578
4360
|
if (key.return) {
|
|
3579
4361
|
const trimmed = input.trim();
|
|
4362
|
+
pushHistory(trimmed);
|
|
4363
|
+
historyIndex = -1;
|
|
4364
|
+
historyDraft = "";
|
|
3580
4365
|
if (trimmed === "/models") {
|
|
3581
4366
|
setPickerQuery("");
|
|
3582
4367
|
setCursor(() => Math.max(0, models.findIndex((m) => m === cfg.model)));
|
|
@@ -3613,30 +4398,49 @@ function useKeyboard(opts) {
|
|
|
3613
4398
|
}
|
|
3614
4399
|
clearPasteStore();
|
|
3615
4400
|
setInput(() => "");
|
|
4401
|
+
setCaret(() => 0);
|
|
3616
4402
|
setPaletteCursor(() => 0);
|
|
3617
4403
|
return;
|
|
3618
4404
|
}
|
|
4405
|
+
if (key.leftArrow) {
|
|
4406
|
+
setCaret((i) => Math.max(0, i - 1));
|
|
4407
|
+
return;
|
|
4408
|
+
}
|
|
4409
|
+
if (key.rightArrow) {
|
|
4410
|
+
setCaret((i) => Math.min(input.length, i + 1));
|
|
4411
|
+
return;
|
|
4412
|
+
}
|
|
4413
|
+
if (key.ctrl && char === "a") {
|
|
4414
|
+
setCaret(() => 0);
|
|
4415
|
+
return;
|
|
4416
|
+
}
|
|
4417
|
+
if (key.ctrl && char === "e") {
|
|
4418
|
+
setCaret(() => input.length);
|
|
4419
|
+
return;
|
|
4420
|
+
}
|
|
3619
4421
|
if (key.backspace || key.delete) {
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
if (match)
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
4422
|
+
historyIndex = -1;
|
|
4423
|
+
setPaletteCursor(() => 0);
|
|
4424
|
+
setFilePickerCursor(() => 0);
|
|
4425
|
+
if (caret <= 0) return;
|
|
4426
|
+
const before = input.slice(0, caret);
|
|
4427
|
+
let match = "";
|
|
4428
|
+
for (const chip of pasteStore.keys()) {
|
|
4429
|
+
if (before.endsWith(chip) && chip.length > match.length) match = chip;
|
|
4430
|
+
}
|
|
4431
|
+
const cut = match ? match.length : 1;
|
|
4432
|
+
if (match) pasteStore.delete(match);
|
|
4433
|
+
setInput((s) => s.slice(0, caret - cut) + s.slice(caret));
|
|
4434
|
+
setCaret((i) => Math.max(0, i - cut));
|
|
3633
4435
|
} else if (char && !key.ctrl && !key.meta && !key.tab) {
|
|
3634
4436
|
const text = sanitizePaste(char);
|
|
3635
|
-
if (text)
|
|
4437
|
+
if (text) {
|
|
4438
|
+
historyIndex = -1;
|
|
3636
4439
|
setPaletteCursor(() => 0);
|
|
3637
4440
|
setFilePickerCursor(() => 0);
|
|
3638
|
-
|
|
3639
|
-
|
|
4441
|
+
setInput((s) => s.slice(0, caret) + text + s.slice(caret));
|
|
4442
|
+
setCaret((i) => i + text.length);
|
|
4443
|
+
}
|
|
3640
4444
|
}
|
|
3641
4445
|
}
|
|
3642
4446
|
});
|
|
@@ -3678,14 +4482,16 @@ async function checkForUpdate() {
|
|
|
3678
4482
|
}
|
|
3679
4483
|
|
|
3680
4484
|
// src/ui/App.tsx
|
|
3681
|
-
import { Fragment as
|
|
4485
|
+
import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3682
4486
|
function App() {
|
|
3683
4487
|
const { exit } = useApp();
|
|
3684
4488
|
const cwd = process.cwd().replace(homedir6(), "~").split(sep2).join("/");
|
|
3685
4489
|
const [cfg, setCfg] = useState5(loadConfig());
|
|
3686
4490
|
const [models, setModels] = useState5([]);
|
|
3687
|
-
const [contexts, setContexts] = useState5({});
|
|
3688
|
-
const [activeCtx, setActiveCtx] = useState5(
|
|
4491
|
+
const [contexts, setContexts] = useState5(() => cfg.modelContexts ?? {});
|
|
4492
|
+
const [activeCtx, setActiveCtx] = useState5(
|
|
4493
|
+
() => cfg.model ? cfg.modelContexts?.[cfg.model] ?? null : null
|
|
4494
|
+
);
|
|
3689
4495
|
const [state, setState] = useState5("loading");
|
|
3690
4496
|
const [cursor, setCursor] = useState5(0);
|
|
3691
4497
|
const [pickerQuery, setPickerQuery] = useState5("");
|
|
@@ -3695,6 +4501,7 @@ function App() {
|
|
|
3695
4501
|
const [sessions, setSessions] = useState5([]);
|
|
3696
4502
|
const [notice, setNotice] = useState5(null);
|
|
3697
4503
|
const [input, setInput] = useState5("");
|
|
4504
|
+
const [caret, setCaret] = useState5(0);
|
|
3698
4505
|
const [paletteCursor, setPaletteCursor] = useState5(0);
|
|
3699
4506
|
const [filePickerCursor, setFilePickerCursor] = useState5(0);
|
|
3700
4507
|
const agent = useAgentRunner(cfg.model, activeCtx);
|
|
@@ -3736,12 +4543,20 @@ function App() {
|
|
|
3736
4543
|
} else {
|
|
3737
4544
|
setState(hasModel ? "ready" : "select-model");
|
|
3738
4545
|
}
|
|
3739
|
-
Promise.all(
|
|
4546
|
+
Promise.all(
|
|
4547
|
+
m.map(
|
|
4548
|
+
(name) => modelContext3(name).then((ctx) => [name, ctx]).catch(() => [name, null])
|
|
4549
|
+
)
|
|
4550
|
+
).then((pairs) => {
|
|
3740
4551
|
if (stale()) return;
|
|
3741
4552
|
const map = Object.fromEntries(pairs);
|
|
3742
4553
|
setContexts(map);
|
|
4554
|
+
const resolved = Object.fromEntries(
|
|
4555
|
+
pairs.filter((p) => p[1] != null)
|
|
4556
|
+
);
|
|
4557
|
+
if (Object.keys(resolved).length) setModelContexts(resolved);
|
|
3743
4558
|
const active2 = (hasModel ? cfg.model : void 0) ?? m[0];
|
|
3744
|
-
if (active2 && map[active2]) setActiveCtx(map[active2]);
|
|
4559
|
+
if (active2 && map[active2] != null) setActiveCtx(map[active2]);
|
|
3745
4560
|
}).catch(() => {
|
|
3746
4561
|
});
|
|
3747
4562
|
}).catch((err) => {
|
|
@@ -3786,6 +4601,8 @@ function App() {
|
|
|
3786
4601
|
agent,
|
|
3787
4602
|
input,
|
|
3788
4603
|
setInput,
|
|
4604
|
+
caret,
|
|
4605
|
+
setCaret,
|
|
3789
4606
|
paletteCursor,
|
|
3790
4607
|
setPaletteCursor,
|
|
3791
4608
|
filePickerCursor,
|
|
@@ -3806,10 +4623,10 @@ function App() {
|
|
|
3806
4623
|
if (used < activeCtx * 0.7) return null;
|
|
3807
4624
|
return Math.round(used / activeCtx * 100);
|
|
3808
4625
|
})();
|
|
3809
|
-
return /* @__PURE__ */
|
|
3810
|
-
/* @__PURE__ */
|
|
3811
|
-
state === "loading" && !agent.error && /* @__PURE__ */
|
|
3812
|
-
agent.error && state !== "ready" && /* @__PURE__ */
|
|
4626
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingX: 1, children: [
|
|
4627
|
+
state !== "ready" && /* @__PURE__ */ jsx13(WelcomeBlock, { model: cfg.model, activeCtx, effort, cwd, error: agent.error, updateAvailable }),
|
|
4628
|
+
state === "loading" && !agent.error && /* @__PURE__ */ jsx13(Box13, { marginLeft: 2, marginBottom: 1, children: /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: `connecting to ${provName}\u2026` }) }),
|
|
4629
|
+
agent.error && state !== "ready" && /* @__PURE__ */ jsx13(
|
|
3813
4630
|
ChatView,
|
|
3814
4631
|
{
|
|
3815
4632
|
messages: [],
|
|
@@ -3819,7 +4636,7 @@ function App() {
|
|
|
3819
4636
|
error: agent.error
|
|
3820
4637
|
}
|
|
3821
4638
|
),
|
|
3822
|
-
(state === "select-model" || state === "models") && /* @__PURE__ */
|
|
4639
|
+
(state === "select-model" || state === "models") && /* @__PURE__ */ jsx13(
|
|
3823
4640
|
ModelsView,
|
|
3824
4641
|
{
|
|
3825
4642
|
models: filteredModels,
|
|
@@ -3832,7 +4649,7 @@ function App() {
|
|
|
3832
4649
|
requireSelection: state === "select-model"
|
|
3833
4650
|
}
|
|
3834
4651
|
),
|
|
3835
|
-
state === "providers" && /* @__PURE__ */
|
|
4652
|
+
state === "providers" && /* @__PURE__ */ jsx13(
|
|
3836
4653
|
ProviderPicker,
|
|
3837
4654
|
{
|
|
3838
4655
|
entries: filteredProviders,
|
|
@@ -3841,10 +4658,10 @@ function App() {
|
|
|
3841
4658
|
query: pickerQuery
|
|
3842
4659
|
}
|
|
3843
4660
|
),
|
|
3844
|
-
state === "sessions" && /* @__PURE__ */
|
|
3845
|
-
state === "ready" && /* @__PURE__ */
|
|
3846
|
-
notice && /* @__PURE__ */
|
|
3847
|
-
/* @__PURE__ */
|
|
4661
|
+
state === "sessions" && /* @__PURE__ */ jsx13(SessionsView, { sessions, cursor }),
|
|
4662
|
+
state === "ready" && /* @__PURE__ */ jsxs13(Fragment3, { children: [
|
|
4663
|
+
notice && /* @__PURE__ */ jsx13(Box13, { marginLeft: 2, marginBottom: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "green", children: `\u2713 ${notice}` }) }),
|
|
4664
|
+
/* @__PURE__ */ jsx13(
|
|
3848
4665
|
ChatView,
|
|
3849
4666
|
{
|
|
3850
4667
|
messages: agent.messages,
|
|
@@ -3856,18 +4673,19 @@ function App() {
|
|
|
3856
4673
|
pendingPermission: agent.pendingPermission,
|
|
3857
4674
|
permissionCursor: agent.permissionCursor,
|
|
3858
4675
|
activeToolUses: agent.activeToolUses,
|
|
3859
|
-
activeToolResults: agent.activeToolResults
|
|
4676
|
+
activeToolResults: agent.activeToolResults,
|
|
4677
|
+
header: /* @__PURE__ */ jsx13(WelcomeBlock, { model: cfg.model, activeCtx, effort, cwd })
|
|
3860
4678
|
}
|
|
3861
4679
|
),
|
|
3862
|
-
input.startsWith("/") && /* @__PURE__ */
|
|
3863
|
-
contextWarning !== null && /* @__PURE__ */
|
|
4680
|
+
input.startsWith("/") && /* @__PURE__ */ jsx13(CommandPalette, { filter: input, cursor: paletteCursor }),
|
|
4681
|
+
contextWarning !== null && /* @__PURE__ */ jsx13(Box13, { marginLeft: 2, marginBottom: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "yellow", children: `\u26A0 context ${contextWarning}% full \u2014 run /clear and start fresh` }) }),
|
|
3864
4682
|
!input.startsWith("/") && (() => {
|
|
3865
4683
|
const m = parseMention(input);
|
|
3866
4684
|
if (!m) return null;
|
|
3867
|
-
return /* @__PURE__ */
|
|
4685
|
+
return /* @__PURE__ */ jsx13(FilePicker, { matches: searchFiles(process.cwd(), m.query), cursor: filePickerCursor });
|
|
3868
4686
|
})(),
|
|
3869
|
-
/* @__PURE__ */
|
|
3870
|
-
!agent.busy && /* @__PURE__ */
|
|
4687
|
+
/* @__PURE__ */ jsx13(InputBar, { input, caret, disabled: agent.busy, processingLabel: agent.processingLabel }),
|
|
4688
|
+
!agent.busy && /* @__PURE__ */ jsx13(Box13, { marginLeft: 2, marginBottom: 1, children: /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: providerDown ? "provider unavailable \u2014 /provider to switch \xB7 /models to pick a model" : "type / to see commands" }) })
|
|
3871
4689
|
] })
|
|
3872
4690
|
] });
|
|
3873
4691
|
}
|