@raegent/earshot 0.1.0 → 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/dist/main.js +1072 -196
- package/dist/main.js.map +13 -9
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -17094,6 +17094,7 @@ class Agent {
|
|
|
17094
17094
|
readFiles = new Set;
|
|
17095
17095
|
queued = [];
|
|
17096
17096
|
rules;
|
|
17097
|
+
resolved;
|
|
17097
17098
|
mode;
|
|
17098
17099
|
totalCostUsd = 0;
|
|
17099
17100
|
maxCostUsd;
|
|
@@ -17129,6 +17130,18 @@ class Agent {
|
|
|
17129
17130
|
this.askFn = options.ask;
|
|
17130
17131
|
this.systemPrompt = options.system;
|
|
17131
17132
|
this.maxCostUsd = options.maxCostUsd;
|
|
17133
|
+
this.resolved = options.model;
|
|
17134
|
+
}
|
|
17135
|
+
get model() {
|
|
17136
|
+
return this.resolved;
|
|
17137
|
+
}
|
|
17138
|
+
async changeModel(ref) {
|
|
17139
|
+
const resolved = await resolveModel(this.options.registry, ref);
|
|
17140
|
+
this.resolved = resolved;
|
|
17141
|
+
return resolved;
|
|
17142
|
+
}
|
|
17143
|
+
get permissionRules() {
|
|
17144
|
+
return [...this.rules];
|
|
17132
17145
|
}
|
|
17133
17146
|
get budgetUsd() {
|
|
17134
17147
|
return this.maxCostUsd;
|
|
@@ -17176,7 +17189,7 @@ ${renderPlan(this.plan)}`;
|
|
|
17176
17189
|
this.options.onCost?.(costUsd);
|
|
17177
17190
|
}
|
|
17178
17191
|
get contextUse() {
|
|
17179
|
-
return { tokens: this.lastRequestTokens, window: this.
|
|
17192
|
+
return { tokens: this.lastRequestTokens, window: this.resolved.model.contextWindow ?? 0 };
|
|
17180
17193
|
}
|
|
17181
17194
|
get touchedFiles() {
|
|
17182
17195
|
return [...this.readFiles];
|
|
@@ -17204,12 +17217,12 @@ ${renderPlan(this.plan)}`;
|
|
|
17204
17217
|
this.checksThisTurn = 0;
|
|
17205
17218
|
const promptText = userPromptText(prompt);
|
|
17206
17219
|
const promptParts = typeof prompt === "string" ? [{ type: "text", text: prompt }] : prompt.map((part) => ({ ...part }));
|
|
17207
|
-
if (promptParts.some((part) => part.type === "image") && !this.
|
|
17220
|
+
if (promptParts.some((part) => part.type === "image") && !this.resolved.model.capabilities.vision) {
|
|
17208
17221
|
yield {
|
|
17209
17222
|
type: "error",
|
|
17210
17223
|
error: {
|
|
17211
17224
|
kind: "invalid_request",
|
|
17212
|
-
message: `${this.
|
|
17225
|
+
message: `${this.resolved.model.name} does not support image input`,
|
|
17213
17226
|
retryable: false
|
|
17214
17227
|
}
|
|
17215
17228
|
};
|
|
@@ -17254,7 +17267,7 @@ ${context.join(`
|
|
|
17254
17267
|
content
|
|
17255
17268
|
});
|
|
17256
17269
|
const maxSteps = this.options.maxSteps ?? DEFAULT_MAX_STEPS;
|
|
17257
|
-
const modelName = `${this.
|
|
17270
|
+
const modelName = `${this.resolved.provider.id}/${this.resolved.model.id}`;
|
|
17258
17271
|
for (let step = 0;step < maxSteps; step++) {
|
|
17259
17272
|
if (signal.aborted) {
|
|
17260
17273
|
yield { type: "turn_end", reason: "aborted" };
|
|
@@ -17278,7 +17291,7 @@ ${context.join(`
|
|
|
17278
17291
|
yield { type: "model_start", model: modelName };
|
|
17279
17292
|
let assistant;
|
|
17280
17293
|
let failed;
|
|
17281
|
-
for await (const event of streamModel(this.options.registry, this.
|
|
17294
|
+
for await (const event of streamModel(this.options.registry, this.resolved, {
|
|
17282
17295
|
system: this.effectiveSystem,
|
|
17283
17296
|
messages,
|
|
17284
17297
|
tools: this.offeredTools(),
|
|
@@ -17293,7 +17306,7 @@ ${context.join(`
|
|
|
17293
17306
|
break;
|
|
17294
17307
|
case "finish": {
|
|
17295
17308
|
assistant = event.message;
|
|
17296
|
-
const costUsd = turnCost(this.
|
|
17309
|
+
const costUsd = turnCost(this.resolved.model, event.usage);
|
|
17297
17310
|
this.addCost(costUsd);
|
|
17298
17311
|
yield { type: "usage", usage: event.usage, costUsd };
|
|
17299
17312
|
break;
|
|
@@ -17598,11 +17611,20 @@ If something is failing, fix it or say what is ` + `failing and why - do not des
|
|
|
17598
17611
|
return shapeMessages(base, { ...DEFAULT_SHAPER_OPTIONS, ...this.options.shapers });
|
|
17599
17612
|
}
|
|
17600
17613
|
async* prepareRequest(signal) {
|
|
17601
|
-
const window = this.
|
|
17614
|
+
const window = this.resolved.model.contextWindow ?? 0;
|
|
17602
17615
|
const policy = { threshold: 0.8, keepRecentMessages: 8, ...this.options.compaction };
|
|
17603
17616
|
const shaped = this.requestMessages();
|
|
17604
17617
|
if (!shouldCompact(shaped, this.effectiveSystem, window, policy))
|
|
17605
17618
|
return;
|
|
17619
|
+
yield* this.runCompaction(signal);
|
|
17620
|
+
}
|
|
17621
|
+
async* compactNow(signal) {
|
|
17622
|
+
yield* this.runCompaction(signal);
|
|
17623
|
+
}
|
|
17624
|
+
async* runCompaction(signal) {
|
|
17625
|
+
const window = this.resolved.model.contextWindow ?? 0;
|
|
17626
|
+
const policy = { threshold: 0.8, keepRecentMessages: 8, ...this.options.compaction };
|
|
17627
|
+
const shaped = this.requestMessages();
|
|
17606
17628
|
const result = await compact({
|
|
17607
17629
|
messages: shaped,
|
|
17608
17630
|
system: this.effectiveSystem,
|
|
@@ -17625,7 +17647,7 @@ If something is failing, fix it or say what is ` + `failing and why - do not des
|
|
|
17625
17647
|
}
|
|
17626
17648
|
async summarise(messages, signal) {
|
|
17627
17649
|
let text2 = "";
|
|
17628
|
-
for await (const event of streamModel(this.options.registry, this.
|
|
17650
|
+
for await (const event of streamModel(this.options.registry, this.resolved, {
|
|
17629
17651
|
system: SUMMARY_PROMPT,
|
|
17630
17652
|
messages: [...messages, { role: "user", content: [{ type: "text", text: SUMMARY_PROMPT }] }],
|
|
17631
17653
|
abortSignal: signal
|
|
@@ -18359,7 +18381,7 @@ class ShadowGit {
|
|
|
18359
18381
|
}
|
|
18360
18382
|
|
|
18361
18383
|
// packages/core/src/version.ts
|
|
18362
|
-
var VERSION = "0.
|
|
18384
|
+
var VERSION = "0.2.0";
|
|
18363
18385
|
|
|
18364
18386
|
// packages/core/src/session/repair.ts
|
|
18365
18387
|
var REPAIR_TEXT = "No result was recorded for this call: earshot exited before the tool finished. " + "The call may or may not have run, so treat its effect as unknown and check " + "the current state rather than assuming either outcome.";
|
|
@@ -20256,10 +20278,124 @@ run \`earshot models\` to see what is available
|
|
|
20256
20278
|
}
|
|
20257
20279
|
|
|
20258
20280
|
// packages/tui/src/app.tsx
|
|
20259
|
-
import { Box as
|
|
20281
|
+
import { Box as Box9, Static, Text as Text10, useApp, useInput as useInput4 } from "ink";
|
|
20260
20282
|
import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
|
|
20261
20283
|
|
|
20262
|
-
// packages/tui/src/
|
|
20284
|
+
// packages/tui/src/commands.ts
|
|
20285
|
+
var SPECS = [
|
|
20286
|
+
{
|
|
20287
|
+
name: "help",
|
|
20288
|
+
summary: "List the commands you can type"
|
|
20289
|
+
},
|
|
20290
|
+
{
|
|
20291
|
+
name: "model",
|
|
20292
|
+
args: "[ref]",
|
|
20293
|
+
summary: "Show the model in use, or switch to another for the rest of the session"
|
|
20294
|
+
},
|
|
20295
|
+
{
|
|
20296
|
+
name: "mode",
|
|
20297
|
+
args: "<plan|ask|accept-edits|auto|yolo>",
|
|
20298
|
+
summary: "Change the permission mode"
|
|
20299
|
+
},
|
|
20300
|
+
{
|
|
20301
|
+
name: "plan",
|
|
20302
|
+
args: "<task>",
|
|
20303
|
+
summary: "Draft a plan in plan mode and write it to a file",
|
|
20304
|
+
idleOnly: true,
|
|
20305
|
+
verbs: [
|
|
20306
|
+
{ name: "edit", summary: "Open the plan in $VISUAL/$EDITOR, or print its path" },
|
|
20307
|
+
{ name: "approve", summary: "Pin the plan as the file now reads for the rest of the run" },
|
|
20308
|
+
{ name: "show", summary: "Read the plan back" },
|
|
20309
|
+
{ name: "clear", summary: "Unpin the plan" }
|
|
20310
|
+
]
|
|
20311
|
+
},
|
|
20312
|
+
{
|
|
20313
|
+
name: "compact",
|
|
20314
|
+
summary: "Summarise the session so far and free up the context window",
|
|
20315
|
+
idleOnly: true
|
|
20316
|
+
},
|
|
20317
|
+
{
|
|
20318
|
+
name: "context",
|
|
20319
|
+
summary: "Show what is in the context window and what compaction has dropped"
|
|
20320
|
+
},
|
|
20321
|
+
{
|
|
20322
|
+
name: "cost",
|
|
20323
|
+
args: "[usd]",
|
|
20324
|
+
summary: "Show what this session has spent, or set the budget ceiling; 0 removes it"
|
|
20325
|
+
},
|
|
20326
|
+
{
|
|
20327
|
+
name: "todo",
|
|
20328
|
+
summary: "Show the agent's current todo list"
|
|
20329
|
+
},
|
|
20330
|
+
{
|
|
20331
|
+
name: "permissions",
|
|
20332
|
+
summary: "Show the permission mode and the rules in force"
|
|
20333
|
+
},
|
|
20334
|
+
{
|
|
20335
|
+
name: "init",
|
|
20336
|
+
summary: "Write an AGENTS.md describing this project",
|
|
20337
|
+
idleOnly: true
|
|
20338
|
+
},
|
|
20339
|
+
{
|
|
20340
|
+
name: "skills",
|
|
20341
|
+
summary: "List discovered skills and user-defined commands"
|
|
20342
|
+
},
|
|
20343
|
+
{
|
|
20344
|
+
name: "memory",
|
|
20345
|
+
summary: "List remembered preferences, each with the sentence it came from",
|
|
20346
|
+
verbs: [{ name: "forget", args: "<id>", summary: "Delete one remembered preference" }]
|
|
20347
|
+
},
|
|
20348
|
+
{
|
|
20349
|
+
name: "tree",
|
|
20350
|
+
summary: "List this session's prompts, numbered",
|
|
20351
|
+
idleOnly: true
|
|
20352
|
+
},
|
|
20353
|
+
{
|
|
20354
|
+
name: "rewind",
|
|
20355
|
+
args: "<n>",
|
|
20356
|
+
summary: "Go back to the state before prompt n; nothing is deleted",
|
|
20357
|
+
idleOnly: true
|
|
20358
|
+
},
|
|
20359
|
+
{
|
|
20360
|
+
name: "fork",
|
|
20361
|
+
args: "<n>",
|
|
20362
|
+
summary: "Branch from prompt n into a new transcript",
|
|
20363
|
+
idleOnly: true
|
|
20364
|
+
},
|
|
20365
|
+
{
|
|
20366
|
+
name: "undo",
|
|
20367
|
+
summary: "Revert the last tool batch's file changes; again to step back further"
|
|
20368
|
+
},
|
|
20369
|
+
{
|
|
20370
|
+
name: "exit",
|
|
20371
|
+
aliases: ["quit"],
|
|
20372
|
+
summary: "Quit"
|
|
20373
|
+
}
|
|
20374
|
+
];
|
|
20375
|
+
var COMMANDS = SPECS;
|
|
20376
|
+
function findCommand(name) {
|
|
20377
|
+
return COMMANDS.find((command) => command.name === name || command.aliases?.includes(name));
|
|
20378
|
+
}
|
|
20379
|
+
function commandRows() {
|
|
20380
|
+
const rows = [];
|
|
20381
|
+
for (const spec of COMMANDS) {
|
|
20382
|
+
rows.push({
|
|
20383
|
+
command: spec.args ? `/${spec.name} ${spec.args}` : `/${spec.name}`,
|
|
20384
|
+
summary: spec.summary,
|
|
20385
|
+
spec
|
|
20386
|
+
});
|
|
20387
|
+
for (const verb of spec.verbs ?? []) {
|
|
20388
|
+
rows.push({
|
|
20389
|
+
command: `/${spec.name} ${verb.name}${verb.args ? ` ${verb.args}` : ""}`,
|
|
20390
|
+
summary: verb.summary,
|
|
20391
|
+
spec
|
|
20392
|
+
});
|
|
20393
|
+
}
|
|
20394
|
+
}
|
|
20395
|
+
return rows;
|
|
20396
|
+
}
|
|
20397
|
+
|
|
20398
|
+
// packages/tui/src/components/command-menu.tsx
|
|
20263
20399
|
import { Box, Text } from "ink";
|
|
20264
20400
|
|
|
20265
20401
|
// packages/tui/src/theme.ts
|
|
@@ -20292,13 +20428,123 @@ var MODE_COLOR = {
|
|
|
20292
20428
|
yolo: theme.danger
|
|
20293
20429
|
};
|
|
20294
20430
|
|
|
20431
|
+
// packages/tui/src/components/command-menu.tsx
|
|
20432
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
20433
|
+
var SUMMARY_WIDTH = 58;
|
|
20434
|
+
var VISIBLE = 10;
|
|
20435
|
+
function menuEntries(query, commands, busy) {
|
|
20436
|
+
const entries = [];
|
|
20437
|
+
for (const spec of ranked(COMMANDS, query)) {
|
|
20438
|
+
if (!matches2(spec.name, query))
|
|
20439
|
+
continue;
|
|
20440
|
+
const disabled = busy && spec.idleOnly === true;
|
|
20441
|
+
const expanded = query !== "" && spec.name.startsWith(query);
|
|
20442
|
+
for (const row of commandRows()) {
|
|
20443
|
+
if (row.spec.name !== spec.name)
|
|
20444
|
+
continue;
|
|
20445
|
+
const isBase = row.command === (spec.args ? `/${spec.name} ${spec.args}` : `/${spec.name}`);
|
|
20446
|
+
if (!isBase && !expanded)
|
|
20447
|
+
continue;
|
|
20448
|
+
entries.push({
|
|
20449
|
+
insert: insertFor(row.command, spec),
|
|
20450
|
+
label: row.command,
|
|
20451
|
+
summary: row.summary,
|
|
20452
|
+
...disabled ? { disabled: true } : {}
|
|
20453
|
+
});
|
|
20454
|
+
}
|
|
20455
|
+
}
|
|
20456
|
+
for (const command of ranked(commands, query)) {
|
|
20457
|
+
if (!matches2(command.name, query))
|
|
20458
|
+
continue;
|
|
20459
|
+
entries.push({
|
|
20460
|
+
insert: `/${command.name}`,
|
|
20461
|
+
label: `/${command.name}`,
|
|
20462
|
+
summary: command.description,
|
|
20463
|
+
scope: command.scope
|
|
20464
|
+
});
|
|
20465
|
+
}
|
|
20466
|
+
return entries;
|
|
20467
|
+
}
|
|
20468
|
+
function insertFor(command, spec) {
|
|
20469
|
+
const withoutArgs = spec.args ? command.replace(` ${spec.args}`, "") : command;
|
|
20470
|
+
return withoutArgs.replace(/\s<[^>]*>$/, "");
|
|
20471
|
+
}
|
|
20472
|
+
var clamp = (text2) => text2.length <= SUMMARY_WIDTH ? text2 : `${text2.slice(0, SUMMARY_WIDTH - 1)}…`;
|
|
20473
|
+
function rowColor(entry, active) {
|
|
20474
|
+
if (entry.disabled)
|
|
20475
|
+
return { color: theme.muted };
|
|
20476
|
+
if (active)
|
|
20477
|
+
return { color: theme.user };
|
|
20478
|
+
return {};
|
|
20479
|
+
}
|
|
20480
|
+
function matches2(name, query) {
|
|
20481
|
+
return query === "" || name.includes(query);
|
|
20482
|
+
}
|
|
20483
|
+
function ranked(items, query) {
|
|
20484
|
+
if (query === "")
|
|
20485
|
+
return [...items];
|
|
20486
|
+
return [
|
|
20487
|
+
...items.filter((item) => item.name.startsWith(query)),
|
|
20488
|
+
...items.filter((item) => !item.name.startsWith(query))
|
|
20489
|
+
];
|
|
20490
|
+
}
|
|
20491
|
+
function CommandMenu({ entries, selected }) {
|
|
20492
|
+
if (entries.length === 0) {
|
|
20493
|
+
return /* @__PURE__ */ jsxDEV(Box, {
|
|
20494
|
+
marginTop: 1,
|
|
20495
|
+
children: /* @__PURE__ */ jsxDEV(Text, {
|
|
20496
|
+
color: theme.muted,
|
|
20497
|
+
children: "no command matches"
|
|
20498
|
+
}, undefined, false, undefined, this)
|
|
20499
|
+
}, undefined, false, undefined, this);
|
|
20500
|
+
}
|
|
20501
|
+
const start = Math.min(Math.max(0, selected - VISIBLE + 1), Math.max(0, entries.length - VISIBLE));
|
|
20502
|
+
const shown = entries.slice(start, start + VISIBLE);
|
|
20503
|
+
const hidden = entries.length - shown.length;
|
|
20504
|
+
return /* @__PURE__ */ jsxDEV(Box, {
|
|
20505
|
+
flexDirection: "column",
|
|
20506
|
+
marginTop: 1,
|
|
20507
|
+
children: [
|
|
20508
|
+
shown.map((entry, index) => {
|
|
20509
|
+
const active = start + index === selected;
|
|
20510
|
+
return /* @__PURE__ */ jsxDEV(Box, {
|
|
20511
|
+
children: [
|
|
20512
|
+
/* @__PURE__ */ jsxDEV(Text, {
|
|
20513
|
+
color: active ? theme.user : theme.muted,
|
|
20514
|
+
children: active ? "› " : " "
|
|
20515
|
+
}, undefined, false, undefined, this),
|
|
20516
|
+
/* @__PURE__ */ jsxDEV(Text, {
|
|
20517
|
+
...rowColor(entry, active),
|
|
20518
|
+
children: entry.label.padEnd(34)
|
|
20519
|
+
}, undefined, false, undefined, this),
|
|
20520
|
+
/* @__PURE__ */ jsxDEV(Text, {
|
|
20521
|
+
color: theme.muted,
|
|
20522
|
+
children: clamp(`${entry.scope ? `[${entry.scope}] ` : ""}${entry.summary}${entry.disabled ? " (not while a turn is running)" : ""}`)
|
|
20523
|
+
}, undefined, false, undefined, this)
|
|
20524
|
+
]
|
|
20525
|
+
}, entry.label, true, undefined, this);
|
|
20526
|
+
}),
|
|
20527
|
+
/* @__PURE__ */ jsxDEV(Box, {
|
|
20528
|
+
children: /* @__PURE__ */ jsxDEV(Text, {
|
|
20529
|
+
color: theme.muted,
|
|
20530
|
+
children: [
|
|
20531
|
+
hidden > 0 ? ` ${hidden} more · ` : " ",
|
|
20532
|
+
"↑↓ choose · tab complete · enter run · esc close"
|
|
20533
|
+
]
|
|
20534
|
+
}, undefined, true, undefined, this)
|
|
20535
|
+
}, undefined, false, undefined, this)
|
|
20536
|
+
]
|
|
20537
|
+
}, undefined, true, undefined, this);
|
|
20538
|
+
}
|
|
20539
|
+
|
|
20295
20540
|
// packages/tui/src/components/markdown.tsx
|
|
20296
|
-
import {
|
|
20541
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
20542
|
+
import { jsxDEV as jsxDEV2, Fragment } from "react/jsx-dev-runtime";
|
|
20297
20543
|
function Markdown({ text: text2 }) {
|
|
20298
20544
|
const blocks = splitBlocks(text2);
|
|
20299
|
-
return /* @__PURE__ */
|
|
20545
|
+
return /* @__PURE__ */ jsxDEV2(Box2, {
|
|
20300
20546
|
flexDirection: "column",
|
|
20301
|
-
children: blocks.map((block, index) => /* @__PURE__ */
|
|
20547
|
+
children: blocks.map((block, index) => /* @__PURE__ */ jsxDEV2(Block, {
|
|
20302
20548
|
block
|
|
20303
20549
|
}, index, false, undefined, this))
|
|
20304
20550
|
}, undefined, false, undefined, this);
|
|
@@ -20377,19 +20623,19 @@ function splitBlocks(text2) {
|
|
|
20377
20623
|
function Block({ block }) {
|
|
20378
20624
|
switch (block.kind) {
|
|
20379
20625
|
case "code":
|
|
20380
|
-
return /* @__PURE__ */
|
|
20626
|
+
return /* @__PURE__ */ jsxDEV2(Box2, {
|
|
20381
20627
|
flexDirection: "column",
|
|
20382
20628
|
marginY: 1,
|
|
20383
20629
|
paddingLeft: 2,
|
|
20384
|
-
children: block.lines.map((line, index) => /* @__PURE__ */
|
|
20630
|
+
children: block.lines.map((line, index) => /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20385
20631
|
color: theme.tool,
|
|
20386
20632
|
children: line
|
|
20387
20633
|
}, index, false, undefined, this))
|
|
20388
20634
|
}, undefined, false, undefined, this);
|
|
20389
20635
|
case "heading":
|
|
20390
|
-
return /* @__PURE__ */
|
|
20636
|
+
return /* @__PURE__ */ jsxDEV2(Box2, {
|
|
20391
20637
|
marginTop: block.level <= 2 ? 1 : 0,
|
|
20392
|
-
children: /* @__PURE__ */
|
|
20638
|
+
children: /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20393
20639
|
bold: true,
|
|
20394
20640
|
underline: block.level === 1,
|
|
20395
20641
|
color: theme.assistant,
|
|
@@ -20397,29 +20643,29 @@ function Block({ block }) {
|
|
|
20397
20643
|
}, undefined, false, undefined, this)
|
|
20398
20644
|
}, undefined, false, undefined, this);
|
|
20399
20645
|
case "rule":
|
|
20400
|
-
return /* @__PURE__ */
|
|
20646
|
+
return /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20401
20647
|
color: theme.muted,
|
|
20402
20648
|
children: "─".repeat(40)
|
|
20403
20649
|
}, undefined, false, undefined, this);
|
|
20404
20650
|
case "list":
|
|
20405
|
-
return /* @__PURE__ */
|
|
20651
|
+
return /* @__PURE__ */ jsxDEV2(Box2, {
|
|
20406
20652
|
flexDirection: "column",
|
|
20407
|
-
children: block.items.map((item, index) => /* @__PURE__ */
|
|
20653
|
+
children: block.items.map((item, index) => /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20408
20654
|
children: [
|
|
20409
20655
|
" ",
|
|
20410
20656
|
block.ordered ? `${index + 1}.` : "-",
|
|
20411
20657
|
" ",
|
|
20412
|
-
/* @__PURE__ */
|
|
20658
|
+
/* @__PURE__ */ jsxDEV2(Inline, {
|
|
20413
20659
|
text: item
|
|
20414
20660
|
}, undefined, false, undefined, this)
|
|
20415
20661
|
]
|
|
20416
20662
|
}, index, true, undefined, this))
|
|
20417
20663
|
}, undefined, false, undefined, this);
|
|
20418
20664
|
case "quote":
|
|
20419
|
-
return /* @__PURE__ */
|
|
20665
|
+
return /* @__PURE__ */ jsxDEV2(Box2, {
|
|
20420
20666
|
flexDirection: "column",
|
|
20421
20667
|
paddingLeft: 1,
|
|
20422
|
-
children: block.lines.map((line, index) => /* @__PURE__ */
|
|
20668
|
+
children: block.lines.map((line, index) => /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20423
20669
|
color: theme.muted,
|
|
20424
20670
|
italic: true,
|
|
20425
20671
|
children: [
|
|
@@ -20429,8 +20675,8 @@ function Block({ block }) {
|
|
|
20429
20675
|
}, index, true, undefined, this))
|
|
20430
20676
|
}, undefined, false, undefined, this);
|
|
20431
20677
|
default:
|
|
20432
|
-
return /* @__PURE__ */
|
|
20433
|
-
children: /* @__PURE__ */
|
|
20678
|
+
return /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20679
|
+
children: /* @__PURE__ */ jsxDEV2(Inline, {
|
|
20434
20680
|
text: block.text
|
|
20435
20681
|
}, undefined, false, undefined, this)
|
|
20436
20682
|
}, undefined, false, undefined, this);
|
|
@@ -20442,41 +20688,41 @@ function inlineToText(text2) {
|
|
|
20442
20688
|
function Inline({ text: text2 }) {
|
|
20443
20689
|
const pattern = /(\*\*.+?\*\*|__.+?__|`.+?`|\*.+?\*|_.+?_)/g;
|
|
20444
20690
|
const parts = text2.split(pattern);
|
|
20445
|
-
return /* @__PURE__ */
|
|
20691
|
+
return /* @__PURE__ */ jsxDEV2(Fragment, {
|
|
20446
20692
|
children: parts.map((part, index) => {
|
|
20447
20693
|
if (part === "")
|
|
20448
20694
|
return null;
|
|
20449
20695
|
if (part.startsWith("**") && part.endsWith("**")) {
|
|
20450
|
-
return /* @__PURE__ */
|
|
20696
|
+
return /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20451
20697
|
bold: true,
|
|
20452
20698
|
children: part.slice(2, -2)
|
|
20453
20699
|
}, index, false, undefined, this);
|
|
20454
20700
|
}
|
|
20455
20701
|
if (part.startsWith("__") && part.endsWith("__")) {
|
|
20456
|
-
return /* @__PURE__ */
|
|
20702
|
+
return /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20457
20703
|
bold: true,
|
|
20458
20704
|
children: part.slice(2, -2)
|
|
20459
20705
|
}, index, false, undefined, this);
|
|
20460
20706
|
}
|
|
20461
20707
|
if (part.startsWith("`") && part.endsWith("`")) {
|
|
20462
|
-
return /* @__PURE__ */
|
|
20708
|
+
return /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20463
20709
|
color: theme.tool,
|
|
20464
20710
|
children: part.slice(1, -1)
|
|
20465
20711
|
}, index, false, undefined, this);
|
|
20466
20712
|
}
|
|
20467
20713
|
if (part.startsWith("*") && part.endsWith("*")) {
|
|
20468
|
-
return /* @__PURE__ */
|
|
20714
|
+
return /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20469
20715
|
italic: true,
|
|
20470
20716
|
children: part.slice(1, -1)
|
|
20471
20717
|
}, index, false, undefined, this);
|
|
20472
20718
|
}
|
|
20473
20719
|
if (part.startsWith("_") && part.endsWith("_")) {
|
|
20474
|
-
return /* @__PURE__ */
|
|
20720
|
+
return /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20475
20721
|
italic: true,
|
|
20476
20722
|
children: part.slice(1, -1)
|
|
20477
20723
|
}, index, false, undefined, this);
|
|
20478
20724
|
}
|
|
20479
|
-
return /* @__PURE__ */
|
|
20725
|
+
return /* @__PURE__ */ jsxDEV2(Text2, {
|
|
20480
20726
|
children: part
|
|
20481
20727
|
}, index, false, undefined, this);
|
|
20482
20728
|
})
|
|
@@ -20484,24 +20730,24 @@ function Inline({ text: text2 }) {
|
|
|
20484
20730
|
}
|
|
20485
20731
|
|
|
20486
20732
|
// packages/tui/src/components/memory-capture.tsx
|
|
20487
|
-
import { Box as
|
|
20488
|
-
import { jsxDEV as
|
|
20733
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
20734
|
+
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
20489
20735
|
function MemoryCapture({ candidate }) {
|
|
20490
|
-
return /* @__PURE__ */
|
|
20736
|
+
return /* @__PURE__ */ jsxDEV3(Box3, {
|
|
20491
20737
|
marginTop: 1,
|
|
20492
20738
|
children: [
|
|
20493
|
-
/* @__PURE__ */
|
|
20739
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
20494
20740
|
color: theme.accent,
|
|
20495
20741
|
children: "remember "
|
|
20496
20742
|
}, undefined, false, undefined, this),
|
|
20497
|
-
/* @__PURE__ */
|
|
20743
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
20498
20744
|
children: [
|
|
20499
20745
|
"“",
|
|
20500
20746
|
candidate.text,
|
|
20501
20747
|
"”"
|
|
20502
20748
|
]
|
|
20503
20749
|
}, undefined, true, undefined, this),
|
|
20504
|
-
/* @__PURE__ */
|
|
20750
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
20505
20751
|
color: theme.muted,
|
|
20506
20752
|
children: "? ctrl+r for this project · ctrl+g everywhere"
|
|
20507
20753
|
}, undefined, false, undefined, this)
|
|
@@ -20510,12 +20756,12 @@ function MemoryCapture({ candidate }) {
|
|
|
20510
20756
|
}
|
|
20511
20757
|
|
|
20512
20758
|
// packages/tui/src/components/permission.tsx
|
|
20513
|
-
import { Box as
|
|
20759
|
+
import { Box as Box5, Text as Text5, useInput } from "ink";
|
|
20514
20760
|
import { useState } from "react";
|
|
20515
20761
|
|
|
20516
20762
|
// packages/tui/src/components/diff.tsx
|
|
20517
|
-
import { Box as
|
|
20518
|
-
import { jsxDEV as
|
|
20763
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
20764
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
20519
20765
|
var MAX_LINES = 60;
|
|
20520
20766
|
function DiffView({ diff: diff2, maxLines = MAX_LINES }) {
|
|
20521
20767
|
const lines = diff2.split(`
|
|
@@ -20523,15 +20769,15 @@ function DiffView({ diff: diff2, maxLines = MAX_LINES }) {
|
|
|
20523
20769
|
const body = lines.filter((line) => !line.startsWith("---") && !line.startsWith("+++"));
|
|
20524
20770
|
const shown = body.slice(0, maxLines);
|
|
20525
20771
|
const hidden = body.length - shown.length;
|
|
20526
|
-
return /* @__PURE__ */
|
|
20772
|
+
return /* @__PURE__ */ jsxDEV4(Box4, {
|
|
20527
20773
|
flexDirection: "column",
|
|
20528
20774
|
children: [
|
|
20529
|
-
shown.map((line, index) => /* @__PURE__ */
|
|
20775
|
+
shown.map((line, index) => /* @__PURE__ */ jsxDEV4(Text4, {
|
|
20530
20776
|
color: colorFor(line),
|
|
20531
20777
|
wrap: "truncate-end",
|
|
20532
20778
|
children: line === "" ? " " : line
|
|
20533
20779
|
}, index, false, undefined, this)),
|
|
20534
|
-
hidden > 0 && /* @__PURE__ */
|
|
20780
|
+
hidden > 0 && /* @__PURE__ */ jsxDEV4(Text4, {
|
|
20535
20781
|
color: theme.muted,
|
|
20536
20782
|
children: [
|
|
20537
20783
|
" ",
|
|
@@ -20566,7 +20812,7 @@ function diffStat(diff2) {
|
|
|
20566
20812
|
}
|
|
20567
20813
|
|
|
20568
20814
|
// packages/tui/src/components/permission.tsx
|
|
20569
|
-
import { jsxDEV as
|
|
20815
|
+
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
20570
20816
|
function PermissionPrompt({ request, reason, onChoice }) {
|
|
20571
20817
|
const [selected, setSelected] = useState(0);
|
|
20572
20818
|
const options = [
|
|
@@ -20594,32 +20840,32 @@ function PermissionPrompt({ request, reason, onChoice }) {
|
|
|
20594
20840
|
});
|
|
20595
20841
|
const isDiff = request.detail.includes(`
|
|
20596
20842
|
@@`) || request.detail.startsWith("---");
|
|
20597
|
-
return /* @__PURE__ */
|
|
20843
|
+
return /* @__PURE__ */ jsxDEV5(Box5, {
|
|
20598
20844
|
flexDirection: "column",
|
|
20599
20845
|
borderStyle: "round",
|
|
20600
20846
|
borderColor: theme.warning,
|
|
20601
20847
|
paddingX: 1,
|
|
20602
20848
|
children: [
|
|
20603
|
-
/* @__PURE__ */
|
|
20849
|
+
/* @__PURE__ */ jsxDEV5(Text5, {
|
|
20604
20850
|
bold: true,
|
|
20605
20851
|
color: theme.warning,
|
|
20606
20852
|
children: request.title
|
|
20607
20853
|
}, undefined, false, undefined, this),
|
|
20608
|
-
/* @__PURE__ */
|
|
20854
|
+
/* @__PURE__ */ jsxDEV5(Text5, {
|
|
20609
20855
|
color: theme.muted,
|
|
20610
20856
|
children: reason
|
|
20611
20857
|
}, undefined, false, undefined, this),
|
|
20612
|
-
/* @__PURE__ */
|
|
20858
|
+
/* @__PURE__ */ jsxDEV5(Box5, {
|
|
20613
20859
|
marginY: 1,
|
|
20614
20860
|
flexDirection: "column",
|
|
20615
|
-
children: isDiff ? /* @__PURE__ */
|
|
20861
|
+
children: isDiff ? /* @__PURE__ */ jsxDEV5(DiffView, {
|
|
20616
20862
|
diff: request.detail
|
|
20617
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
20863
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV5(Text5, {
|
|
20618
20864
|
wrap: "wrap",
|
|
20619
20865
|
children: request.detail
|
|
20620
20866
|
}, undefined, false, undefined, this)
|
|
20621
20867
|
}, undefined, false, undefined, this),
|
|
20622
|
-
options.map((option, index) => /* @__PURE__ */
|
|
20868
|
+
options.map((option, index) => /* @__PURE__ */ jsxDEV5(Text5, {
|
|
20623
20869
|
color: index === selected ? theme.accent : option.color,
|
|
20624
20870
|
children: [
|
|
20625
20871
|
index === selected ? "❯ " : " ",
|
|
@@ -20634,13 +20880,13 @@ function truncate2(value, max) {
|
|
|
20634
20880
|
}
|
|
20635
20881
|
|
|
20636
20882
|
// packages/tui/src/components/question.tsx
|
|
20637
|
-
import { Box as
|
|
20883
|
+
import { Box as Box6, Text as Text7, useInput as useInput3 } from "ink";
|
|
20638
20884
|
import { useState as useState2 } from "react";
|
|
20639
20885
|
|
|
20640
20886
|
// packages/tui/src/components/text-input.tsx
|
|
20641
|
-
import { Text as
|
|
20887
|
+
import { Text as Text6, useInput as useInput2 } from "ink";
|
|
20642
20888
|
import { useEffect, useRef } from "react";
|
|
20643
|
-
import { jsxDEV as
|
|
20889
|
+
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
20644
20890
|
function TextInput({
|
|
20645
20891
|
value,
|
|
20646
20892
|
onChange,
|
|
@@ -20674,23 +20920,23 @@ function TextInput({
|
|
|
20674
20920
|
}
|
|
20675
20921
|
}, { isActive });
|
|
20676
20922
|
if (value === "") {
|
|
20677
|
-
return /* @__PURE__ */
|
|
20923
|
+
return /* @__PURE__ */ jsxDEV6(Text6, {
|
|
20678
20924
|
children: [
|
|
20679
|
-
/* @__PURE__ */
|
|
20925
|
+
/* @__PURE__ */ jsxDEV6(Text6, {
|
|
20680
20926
|
inverse: true,
|
|
20681
20927
|
children: " "
|
|
20682
20928
|
}, undefined, false, undefined, this),
|
|
20683
|
-
/* @__PURE__ */
|
|
20929
|
+
/* @__PURE__ */ jsxDEV6(Text6, {
|
|
20684
20930
|
color: theme.muted,
|
|
20685
20931
|
children: placeholder
|
|
20686
20932
|
}, undefined, false, undefined, this)
|
|
20687
20933
|
]
|
|
20688
20934
|
}, undefined, true, undefined, this);
|
|
20689
20935
|
}
|
|
20690
|
-
return /* @__PURE__ */
|
|
20936
|
+
return /* @__PURE__ */ jsxDEV6(Text6, {
|
|
20691
20937
|
children: [
|
|
20692
20938
|
value,
|
|
20693
|
-
/* @__PURE__ */
|
|
20939
|
+
/* @__PURE__ */ jsxDEV6(Text6, {
|
|
20694
20940
|
inverse: true,
|
|
20695
20941
|
children: " "
|
|
20696
20942
|
}, undefined, false, undefined, this)
|
|
@@ -20699,7 +20945,7 @@ function TextInput({
|
|
|
20699
20945
|
}
|
|
20700
20946
|
|
|
20701
20947
|
// packages/tui/src/components/question.tsx
|
|
20702
|
-
import { jsxDEV as
|
|
20948
|
+
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
20703
20949
|
function QuestionPrompt({ question, options = [], onAnswer }) {
|
|
20704
20950
|
const [selected, setSelected] = useState2(0);
|
|
20705
20951
|
const [typing, setTyping] = useState2(options.length === 0);
|
|
@@ -20716,29 +20962,29 @@ function QuestionPrompt({ question, options = [], onAnswer }) {
|
|
|
20716
20962
|
setValue(input);
|
|
20717
20963
|
}
|
|
20718
20964
|
}, { isActive: !typing });
|
|
20719
|
-
return /* @__PURE__ */
|
|
20965
|
+
return /* @__PURE__ */ jsxDEV7(Box6, {
|
|
20720
20966
|
flexDirection: "column",
|
|
20721
20967
|
borderStyle: "round",
|
|
20722
20968
|
borderColor: theme.accent,
|
|
20723
20969
|
paddingX: 1,
|
|
20724
20970
|
children: [
|
|
20725
|
-
/* @__PURE__ */
|
|
20971
|
+
/* @__PURE__ */ jsxDEV7(Text7, {
|
|
20726
20972
|
bold: true,
|
|
20727
20973
|
color: theme.accent,
|
|
20728
20974
|
children: question
|
|
20729
20975
|
}, undefined, false, undefined, this),
|
|
20730
|
-
!typing && options.map((option, index) => /* @__PURE__ */
|
|
20976
|
+
!typing && options.map((option, index) => /* @__PURE__ */ jsxDEV7(Text7, {
|
|
20731
20977
|
color: index === selected ? theme.accent : theme.muted,
|
|
20732
20978
|
children: [
|
|
20733
20979
|
index === selected ? "❯ " : " ",
|
|
20734
20980
|
option
|
|
20735
20981
|
]
|
|
20736
20982
|
}, option, true, undefined, this)),
|
|
20737
|
-
!typing && /* @__PURE__ */
|
|
20983
|
+
!typing && /* @__PURE__ */ jsxDEV7(Text7, {
|
|
20738
20984
|
color: theme.muted,
|
|
20739
20985
|
children: "or start typing to answer in your own words"
|
|
20740
20986
|
}, undefined, false, undefined, this),
|
|
20741
|
-
typing && /* @__PURE__ */
|
|
20987
|
+
typing && /* @__PURE__ */ jsxDEV7(TextInput, {
|
|
20742
20988
|
value,
|
|
20743
20989
|
onChange: setValue,
|
|
20744
20990
|
onSubmit: (answer) => onAnswer(answer.trim()),
|
|
@@ -20749,8 +20995,8 @@ function QuestionPrompt({ question, options = [], onAnswer }) {
|
|
|
20749
20995
|
}
|
|
20750
20996
|
|
|
20751
20997
|
// packages/tui/src/components/status.tsx
|
|
20752
|
-
import { Box as
|
|
20753
|
-
import { jsxDEV as
|
|
20998
|
+
import { Box as Box7, Text as Text8 } from "ink";
|
|
20999
|
+
import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
|
|
20754
21000
|
function StatusLine({
|
|
20755
21001
|
model: model2,
|
|
20756
21002
|
mode,
|
|
@@ -20764,27 +21010,27 @@ function StatusLine({
|
|
|
20764
21010
|
const done = todos.filter((todo2) => todo2.status === "done").length;
|
|
20765
21011
|
const current = todos.find((todo2) => todo2.status === "in_progress");
|
|
20766
21012
|
const used = context2.window > 0 ? Math.min(100, context2.tokens / context2.window * 100) : 0;
|
|
20767
|
-
return /* @__PURE__ */
|
|
21013
|
+
return /* @__PURE__ */ jsxDEV8(Box7, {
|
|
20768
21014
|
children: [
|
|
20769
|
-
/* @__PURE__ */
|
|
21015
|
+
/* @__PURE__ */ jsxDEV8(Text8, {
|
|
20770
21016
|
color: MODE_COLOR[mode] ?? theme.muted,
|
|
20771
21017
|
children: MODE_LABEL[mode] ?? mode
|
|
20772
21018
|
}, undefined, false, undefined, this),
|
|
20773
|
-
/* @__PURE__ */
|
|
21019
|
+
/* @__PURE__ */ jsxDEV8(Text8, {
|
|
20774
21020
|
color: theme.muted,
|
|
20775
21021
|
children: [
|
|
20776
21022
|
" · ",
|
|
20777
21023
|
model2
|
|
20778
21024
|
]
|
|
20779
21025
|
}, undefined, true, undefined, this),
|
|
20780
|
-
/* @__PURE__ */
|
|
21026
|
+
/* @__PURE__ */ jsxDEV8(Text8, {
|
|
20781
21027
|
color: theme.muted,
|
|
20782
21028
|
children: [
|
|
20783
21029
|
" · $",
|
|
20784
21030
|
costUsd.toFixed(4)
|
|
20785
21031
|
]
|
|
20786
21032
|
}, undefined, true, undefined, this),
|
|
20787
|
-
context2.window > 0 && /* @__PURE__ */
|
|
21033
|
+
context2.window > 0 && /* @__PURE__ */ jsxDEV8(Text8, {
|
|
20788
21034
|
color: used >= 80 ? theme.warning : theme.muted,
|
|
20789
21035
|
children: [
|
|
20790
21036
|
" · ",
|
|
@@ -20792,7 +21038,7 @@ function StatusLine({
|
|
|
20792
21038
|
"% ctx"
|
|
20793
21039
|
]
|
|
20794
21040
|
}, undefined, true, undefined, this),
|
|
20795
|
-
compacted > 0 && /* @__PURE__ */
|
|
21041
|
+
compacted > 0 && /* @__PURE__ */ jsxDEV8(Text8, {
|
|
20796
21042
|
color: theme.muted,
|
|
20797
21043
|
children: [
|
|
20798
21044
|
" · ",
|
|
@@ -20800,7 +21046,7 @@ function StatusLine({
|
|
|
20800
21046
|
" summarised"
|
|
20801
21047
|
]
|
|
20802
21048
|
}, undefined, true, undefined, this),
|
|
20803
|
-
todos.length > 0 && /* @__PURE__ */
|
|
21049
|
+
todos.length > 0 && /* @__PURE__ */ jsxDEV8(Text8, {
|
|
20804
21050
|
color: theme.muted,
|
|
20805
21051
|
children: [
|
|
20806
21052
|
" ",
|
|
@@ -20811,11 +21057,11 @@ function StatusLine({
|
|
|
20811
21057
|
current ? ` ${truncate3(current.text, 40)}` : ""
|
|
20812
21058
|
]
|
|
20813
21059
|
}, undefined, true, undefined, this),
|
|
20814
|
-
busy && /* @__PURE__ */
|
|
21060
|
+
busy && /* @__PURE__ */ jsxDEV8(Text8, {
|
|
20815
21061
|
color: theme.warning,
|
|
20816
21062
|
children: " · working (esc to interrupt)"
|
|
20817
21063
|
}, undefined, false, undefined, this),
|
|
20818
|
-
queued > 0 && /* @__PURE__ */
|
|
21064
|
+
queued > 0 && /* @__PURE__ */ jsxDEV8(Text8, {
|
|
20819
21065
|
color: theme.accent,
|
|
20820
21066
|
children: [
|
|
20821
21067
|
" · ",
|
|
@@ -20831,8 +21077,8 @@ function truncate3(value, max) {
|
|
|
20831
21077
|
}
|
|
20832
21078
|
|
|
20833
21079
|
// packages/tui/src/components/tool-block.tsx
|
|
20834
|
-
import { Box as
|
|
20835
|
-
import { jsxDEV as
|
|
21080
|
+
import { Box as Box8, Text as Text9 } from "ink";
|
|
21081
|
+
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
20836
21082
|
var PREVIEW_LINES = 8;
|
|
20837
21083
|
function ToolBlock({
|
|
20838
21084
|
name,
|
|
@@ -20851,27 +21097,27 @@ function ToolBlock({
|
|
|
20851
21097
|
const showAll = expanded || isError;
|
|
20852
21098
|
const shown = showAll ? lines : lines.slice(0, PREVIEW_LINES);
|
|
20853
21099
|
const hidden = lines.length - shown.length;
|
|
20854
|
-
return /* @__PURE__ */
|
|
21100
|
+
return /* @__PURE__ */ jsxDEV9(Box8, {
|
|
20855
21101
|
flexDirection: "column",
|
|
20856
21102
|
marginTop: 1,
|
|
20857
21103
|
children: [
|
|
20858
|
-
/* @__PURE__ */
|
|
21104
|
+
/* @__PURE__ */ jsxDEV9(Text9, {
|
|
20859
21105
|
color,
|
|
20860
21106
|
children: [
|
|
20861
21107
|
marker2,
|
|
20862
21108
|
" ",
|
|
20863
|
-
/* @__PURE__ */
|
|
21109
|
+
/* @__PURE__ */ jsxDEV9(Text9, {
|
|
20864
21110
|
bold: true,
|
|
20865
21111
|
children: name
|
|
20866
21112
|
}, undefined, false, undefined, this),
|
|
20867
|
-
title ? /* @__PURE__ */
|
|
21113
|
+
title ? /* @__PURE__ */ jsxDEV9(Text9, {
|
|
20868
21114
|
color: theme.muted,
|
|
20869
21115
|
children: [
|
|
20870
21116
|
" ",
|
|
20871
21117
|
title
|
|
20872
21118
|
]
|
|
20873
21119
|
}, undefined, true, undefined, this) : null,
|
|
20874
|
-
isDiff && !showAll ? /* @__PURE__ */
|
|
21120
|
+
isDiff && !showAll ? /* @__PURE__ */ jsxDEV9(Text9, {
|
|
20875
21121
|
color: theme.muted,
|
|
20876
21122
|
children: [
|
|
20877
21123
|
" ",
|
|
@@ -20880,12 +21126,12 @@ function ToolBlock({
|
|
|
20880
21126
|
}, undefined, true, undefined, this) : null
|
|
20881
21127
|
]
|
|
20882
21128
|
}, undefined, true, undefined, this),
|
|
20883
|
-
isDiff && showAll ? /* @__PURE__ */
|
|
21129
|
+
isDiff && showAll ? /* @__PURE__ */ jsxDEV9(Box8, {
|
|
20884
21130
|
marginLeft: 2,
|
|
20885
|
-
children: /* @__PURE__ */
|
|
21131
|
+
children: /* @__PURE__ */ jsxDEV9(DiffView, {
|
|
20886
21132
|
diff: output
|
|
20887
21133
|
}, undefined, false, undefined, this)
|
|
20888
|
-
}, undefined, false, undefined, this) : shown.map((line, index) => /* @__PURE__ */
|
|
21134
|
+
}, undefined, false, undefined, this) : shown.map((line, index) => /* @__PURE__ */ jsxDEV9(Text9, {
|
|
20889
21135
|
color: theme.muted,
|
|
20890
21136
|
wrap: "truncate-end",
|
|
20891
21137
|
children: [
|
|
@@ -20893,7 +21139,7 @@ function ToolBlock({
|
|
|
20893
21139
|
line
|
|
20894
21140
|
]
|
|
20895
21141
|
}, index, true, undefined, this)),
|
|
20896
|
-
hidden > 0 && !isDiff && /* @__PURE__ */
|
|
21142
|
+
hidden > 0 && !isDiff && /* @__PURE__ */ jsxDEV9(Text9, {
|
|
20897
21143
|
color: theme.muted,
|
|
20898
21144
|
children: [
|
|
20899
21145
|
" ",
|
|
@@ -20907,7 +21153,7 @@ function ToolBlock({
|
|
|
20907
21153
|
}
|
|
20908
21154
|
|
|
20909
21155
|
// packages/tui/src/app.tsx
|
|
20910
|
-
import { jsxDEV as
|
|
21156
|
+
import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
|
|
20911
21157
|
var sequence = 0;
|
|
20912
21158
|
var nextId = () => `item_${sequence++}`;
|
|
20913
21159
|
function promptLabel(prompt) {
|
|
@@ -20916,9 +21162,10 @@ function promptLabel(prompt) {
|
|
|
20916
21162
|
return prompt.map((part) => part.type === "text" ? part.text : `[attached ${part.mediaType} image]`).join(`
|
|
20917
21163
|
`);
|
|
20918
21164
|
}
|
|
20919
|
-
function App({ session: session2, model:
|
|
21165
|
+
function App({ session: session2, model: initialModel, initialPrompt }) {
|
|
20920
21166
|
const { exit } = useApp();
|
|
20921
21167
|
const agent3 = session2.agent;
|
|
21168
|
+
const [model2, setModel] = useState3(initialModel);
|
|
20922
21169
|
const [items, setItems] = useState3(() => session2.problems.map((problem) => ({
|
|
20923
21170
|
kind: "notice",
|
|
20924
21171
|
id: nextId(),
|
|
@@ -20928,6 +21175,7 @@ function App({ session: session2, model: model2, initialPrompt }) {
|
|
|
20928
21175
|
const [live, setLive] = useState3("");
|
|
20929
21176
|
const [runningTool, setRunningTool] = useState3();
|
|
20930
21177
|
const [input, setInput] = useState3("");
|
|
21178
|
+
const [menuIndex, setMenuIndex] = useState3(0);
|
|
20931
21179
|
const [busy, setBusy] = useState3(false);
|
|
20932
21180
|
const [mode, setMode] = useState3(agent3.permissionMode);
|
|
20933
21181
|
const [cost, setCost] = useState3(0);
|
|
@@ -21154,8 +21402,8 @@ function App({ session: session2, model: model2, initialPrompt }) {
|
|
|
21154
21402
|
});
|
|
21155
21403
|
}, [agent3, candidate, model2, push, session2.skills]);
|
|
21156
21404
|
const sessionTree = useCallback(async (name, argument) => {
|
|
21157
|
-
const
|
|
21158
|
-
const prompts =
|
|
21405
|
+
const entries2 = await session2.branch();
|
|
21406
|
+
const prompts = entries2.filter((entry) => entry.type === "message" && entry.message.role === "user" && entry.message.content.some((part) => part.type === "text" && !part.text.startsWith("<self-check>")));
|
|
21159
21407
|
if (name === "tree" || !argument) {
|
|
21160
21408
|
if (prompts.length === 0) {
|
|
21161
21409
|
push({ kind: "notice", id: nextId(), text: "nothing in this session yet" });
|
|
@@ -21187,7 +21435,7 @@ function App({ session: session2, model: model2, initialPrompt }) {
|
|
|
21187
21435
|
});
|
|
21188
21436
|
return;
|
|
21189
21437
|
}
|
|
21190
|
-
const previous =
|
|
21438
|
+
const previous = entries2[entries2.indexOf(target) - 1] ?? target;
|
|
21191
21439
|
if (name === "rewind") {
|
|
21192
21440
|
const kept = await session2.rewindTo(previous.id);
|
|
21193
21441
|
push({
|
|
@@ -21304,16 +21552,149 @@ ${PLAN_PROMPT}`);
|
|
|
21304
21552
|
/plan edit to change it, /plan approve to pin it`
|
|
21305
21553
|
});
|
|
21306
21554
|
}, [agent3, push, runTurn, session2.store]);
|
|
21307
|
-
const
|
|
21308
|
-
|
|
21309
|
-
|
|
21310
|
-
|
|
21311
|
-
|
|
21312
|
-
|
|
21313
|
-
|
|
21555
|
+
const switchModel = useCallback(async (ref) => {
|
|
21556
|
+
if (!ref) {
|
|
21557
|
+
const current = agent3.model;
|
|
21558
|
+
const price = current.model.cost;
|
|
21559
|
+
push({
|
|
21560
|
+
kind: "notice",
|
|
21561
|
+
id: nextId(),
|
|
21562
|
+
text: [
|
|
21563
|
+
` ${current.provider.id}/${current.model.id}`,
|
|
21564
|
+
` context ${(current.model.contextWindow ?? 0).toLocaleString()} tokens`,
|
|
21565
|
+
` price $${price?.input ?? "?"} in / $${price?.output ?? "?"} out per million`,
|
|
21566
|
+
"",
|
|
21567
|
+
" /model <provider/model> switches; `earshot models` lists them"
|
|
21568
|
+
].join(`
|
|
21569
|
+
`)
|
|
21570
|
+
});
|
|
21314
21571
|
return;
|
|
21315
21572
|
}
|
|
21316
|
-
|
|
21573
|
+
try {
|
|
21574
|
+
const resolved = await agent3.changeModel(ref);
|
|
21575
|
+
const next = `${resolved.provider.id}/${resolved.model.id}`;
|
|
21576
|
+
setModel(next);
|
|
21577
|
+
await refreshSystemPrompt(agent3, next, session2.skills);
|
|
21578
|
+
push({ kind: "notice", id: nextId(), text: `model: ${next}` });
|
|
21579
|
+
} catch (error) {
|
|
21580
|
+
push({
|
|
21581
|
+
kind: "notice",
|
|
21582
|
+
id: nextId(),
|
|
21583
|
+
text: `${error.message}`,
|
|
21584
|
+
color: theme.warning
|
|
21585
|
+
});
|
|
21586
|
+
}
|
|
21587
|
+
}, [agent3, push, session2.skills]);
|
|
21588
|
+
const compactNow = useCallback(async () => {
|
|
21589
|
+
const abort = new AbortController;
|
|
21590
|
+
controller.current = abort;
|
|
21591
|
+
setBusy(true);
|
|
21592
|
+
try {
|
|
21593
|
+
let compactedAnything = false;
|
|
21594
|
+
for await (const event of agent3.compactNow(abort.signal)) {
|
|
21595
|
+
if (event.type === "compacted") {
|
|
21596
|
+
compactedAnything = true;
|
|
21597
|
+
setCompacted((count) => count + event.replaced);
|
|
21598
|
+
push({
|
|
21599
|
+
kind: "notice",
|
|
21600
|
+
id: nextId(),
|
|
21601
|
+
text: `compacted: ${event.replaced} earlier messages are now a summary`
|
|
21602
|
+
});
|
|
21603
|
+
}
|
|
21604
|
+
}
|
|
21605
|
+
if (!compactedAnything) {
|
|
21606
|
+
push({ kind: "notice", id: nextId(), text: "nothing to compact yet" });
|
|
21607
|
+
}
|
|
21608
|
+
} catch (error) {
|
|
21609
|
+
push({
|
|
21610
|
+
kind: "notice",
|
|
21611
|
+
id: nextId(),
|
|
21612
|
+
text: `could not compact: ${error.message}`,
|
|
21613
|
+
color: theme.warning
|
|
21614
|
+
});
|
|
21615
|
+
} finally {
|
|
21616
|
+
setBusy(false);
|
|
21617
|
+
setContext(agent3.contextUse);
|
|
21618
|
+
controller.current = undefined;
|
|
21619
|
+
}
|
|
21620
|
+
}, [agent3, push]);
|
|
21621
|
+
const handlers = {
|
|
21622
|
+
exit: () => exit(),
|
|
21623
|
+
help: () => push({ kind: "notice", id: nextId(), text: describeCommands(session2) }),
|
|
21624
|
+
model: (argument) => void switchModel(argument),
|
|
21625
|
+
compact: () => void compactNow(),
|
|
21626
|
+
context: () => {
|
|
21627
|
+
const { tokens, window } = agent3.contextUse;
|
|
21628
|
+
const percent = window > 0 ? Math.round(tokens / window * 100) : 0;
|
|
21629
|
+
const files = agent3.touchedFiles;
|
|
21630
|
+
push({
|
|
21631
|
+
kind: "notice",
|
|
21632
|
+
id: nextId(),
|
|
21633
|
+
text: [
|
|
21634
|
+
` model ${model2}`,
|
|
21635
|
+
` context ~${tokens.toLocaleString()} of ${window.toLocaleString()} tokens (${percent}%)`,
|
|
21636
|
+
` dropped ${compacted} earlier message${compacted === 1 ? "" : "s"} replaced by a summary`,
|
|
21637
|
+
` files ${files.length === 0 ? "none touched yet" : files.join(", ")}`,
|
|
21638
|
+
"",
|
|
21639
|
+
" /compact summarises now rather than waiting for 80%"
|
|
21640
|
+
].join(`
|
|
21641
|
+
`)
|
|
21642
|
+
});
|
|
21643
|
+
},
|
|
21644
|
+
cost: (argument) => {
|
|
21645
|
+
if (argument !== undefined && argument !== "") {
|
|
21646
|
+
const amount = Number.parseFloat(argument.replace(/^\$/, ""));
|
|
21647
|
+
if (Number.isNaN(amount)) {
|
|
21648
|
+
push({
|
|
21649
|
+
kind: "notice",
|
|
21650
|
+
id: nextId(),
|
|
21651
|
+
text: `usage: /cost [usd] - "${argument}" is not an amount`,
|
|
21652
|
+
color: theme.warning
|
|
21653
|
+
});
|
|
21654
|
+
return;
|
|
21655
|
+
}
|
|
21656
|
+
agent3.setBudget(amount > 0 ? amount : undefined);
|
|
21657
|
+
push({
|
|
21658
|
+
kind: "notice",
|
|
21659
|
+
id: nextId(),
|
|
21660
|
+
text: amount > 0 ? `budget: $${amount.toFixed(2)}` : "budget removed"
|
|
21661
|
+
});
|
|
21662
|
+
return;
|
|
21663
|
+
}
|
|
21664
|
+
const budget = agent3.budgetUsd;
|
|
21665
|
+
push({
|
|
21666
|
+
kind: "notice",
|
|
21667
|
+
id: nextId(),
|
|
21668
|
+
text: ` spent $${agent3.costUsd.toFixed(4)}
|
|
21669
|
+
` + ` budget ${budget === undefined ? "none - /cost <usd> sets one" : `$${budget.toFixed(2)}`}`
|
|
21670
|
+
});
|
|
21671
|
+
},
|
|
21672
|
+
todo: () => {
|
|
21673
|
+
const todos2 = agent3.todos.list();
|
|
21674
|
+
push({
|
|
21675
|
+
kind: "notice",
|
|
21676
|
+
id: nextId(),
|
|
21677
|
+
text: todos2.length === 0 ? "no todos in this session" : todos2.map((todo2) => ` ${todo2.status === "done" ? "x" : todo2.status === "in_progress" ? ">" : " "} ${todo2.text}`).join(`
|
|
21678
|
+
`)
|
|
21679
|
+
});
|
|
21680
|
+
},
|
|
21681
|
+
permissions: () => {
|
|
21682
|
+
const rules2 = agent3.permissionRules;
|
|
21683
|
+
push({
|
|
21684
|
+
kind: "notice",
|
|
21685
|
+
id: nextId(),
|
|
21686
|
+
text: [
|
|
21687
|
+
` mode ${agent3.permissionMode} (/mode changes it)`,
|
|
21688
|
+
...rules2.length === 0 ? [" rules none configured"] : [
|
|
21689
|
+
" rules (deny always wins, whatever the mode or scope)",
|
|
21690
|
+
...rules2.map((rule) => ` ${rule.effect.padEnd(5)} ${rule.source} [${rule.scope}]`)
|
|
21691
|
+
]
|
|
21692
|
+
].join(`
|
|
21693
|
+
`)
|
|
21694
|
+
});
|
|
21695
|
+
},
|
|
21696
|
+
init: () => void runTurn(INIT_PROMPT),
|
|
21697
|
+
mode: (argument) => {
|
|
21317
21698
|
if (argument && isPermissionMode(argument)) {
|
|
21318
21699
|
agent3.setPermissionMode(argument);
|
|
21319
21700
|
setMode(argument);
|
|
@@ -21326,31 +21707,25 @@ ${PLAN_PROMPT}`);
|
|
|
21326
21707
|
color: theme.warning
|
|
21327
21708
|
});
|
|
21328
21709
|
}
|
|
21329
|
-
|
|
21330
|
-
|
|
21331
|
-
|
|
21332
|
-
|
|
21333
|
-
|
|
21334
|
-
|
|
21335
|
-
|
|
21336
|
-
|
|
21337
|
-
|
|
21338
|
-
|
|
21339
|
-
|
|
21340
|
-
|
|
21341
|
-
|
|
21342
|
-
|
|
21343
|
-
|
|
21344
|
-
|
|
21345
|
-
|
|
21346
|
-
|
|
21347
|
-
|
|
21348
|
-
if (name === "undo") {
|
|
21349
|
-
undoLast();
|
|
21350
|
-
return;
|
|
21351
|
-
}
|
|
21352
|
-
if (name === "plan") {
|
|
21353
|
-
if (busy) {
|
|
21710
|
+
},
|
|
21711
|
+
memory: (argument) => void showMemories(argument),
|
|
21712
|
+
tree: (argument) => void sessionTree("tree", argument),
|
|
21713
|
+
rewind: (argument) => void sessionTree("rewind", argument),
|
|
21714
|
+
fork: (argument) => void sessionTree("fork", argument),
|
|
21715
|
+
undo: () => void undoLast(),
|
|
21716
|
+
plan: (argument) => void plan2(argument),
|
|
21717
|
+
skills: () => push({ kind: "notice", id: nextId(), text: describeExtensions(session2) })
|
|
21718
|
+
};
|
|
21719
|
+
const handlersRef = useRef2(handlers);
|
|
21720
|
+
handlersRef.current = handlers;
|
|
21721
|
+
const handleCommand = useCallback((command) => {
|
|
21722
|
+
const body = command.slice(1).trim();
|
|
21723
|
+
const space = body.search(/\s/);
|
|
21724
|
+
const name = space === -1 ? body : body.slice(0, space);
|
|
21725
|
+
const argument = space === -1 ? undefined : body.slice(space + 1).trim();
|
|
21726
|
+
const spec = findCommand(name);
|
|
21727
|
+
if (spec) {
|
|
21728
|
+
if (spec.idleOnly && busy) {
|
|
21354
21729
|
push({
|
|
21355
21730
|
kind: "notice",
|
|
21356
21731
|
id: nextId(),
|
|
@@ -21359,15 +21734,7 @@ ${PLAN_PROMPT}`);
|
|
|
21359
21734
|
});
|
|
21360
21735
|
return;
|
|
21361
21736
|
}
|
|
21362
|
-
|
|
21363
|
-
return;
|
|
21364
|
-
}
|
|
21365
|
-
if (name === "skills") {
|
|
21366
|
-
push({
|
|
21367
|
-
kind: "notice",
|
|
21368
|
-
id: nextId(),
|
|
21369
|
-
text: describeExtensions(session2)
|
|
21370
|
-
});
|
|
21737
|
+
handlersRef.current[spec.name](argument);
|
|
21371
21738
|
return;
|
|
21372
21739
|
}
|
|
21373
21740
|
const custom = session2.commands.find((entry) => entry.name === name);
|
|
@@ -21397,8 +21764,15 @@ ${PLAN_PROMPT}`);
|
|
|
21397
21764
|
text: `unknown command "${name}"`,
|
|
21398
21765
|
color: theme.warning
|
|
21399
21766
|
});
|
|
21400
|
-
}, [agent3, busy,
|
|
21767
|
+
}, [agent3, busy, push, runTurn, session2]);
|
|
21401
21768
|
const submit = useCallback((text2) => {
|
|
21769
|
+
const entry = menuOpenRef.current ? menuEntriesRef.current[selectedRef.current] : undefined;
|
|
21770
|
+
if (entry) {
|
|
21771
|
+
setInput("");
|
|
21772
|
+
setMenuIndex(0);
|
|
21773
|
+
handleCommand(entry.insert);
|
|
21774
|
+
return;
|
|
21775
|
+
}
|
|
21402
21776
|
const trimmed = text2.trim();
|
|
21403
21777
|
setInput("");
|
|
21404
21778
|
if (trimmed === "")
|
|
@@ -21417,7 +21791,38 @@ ${PLAN_PROMPT}`);
|
|
|
21417
21791
|
runTurn(trimmed);
|
|
21418
21792
|
}, [agent3, busy, push, runTurn, handleCommand]);
|
|
21419
21793
|
const inputActive = !pending && !question;
|
|
21794
|
+
const menuOpen = inputActive && input.startsWith("/") && !input.includes(" ");
|
|
21795
|
+
const entries = menuOpen ? menuEntries(input.slice(1), session2.commands, busy) : [];
|
|
21796
|
+
const selected = Math.min(menuIndex, Math.max(0, entries.length - 1));
|
|
21797
|
+
const menuOpenRef = useRef2(menuOpen);
|
|
21798
|
+
menuOpenRef.current = menuOpen;
|
|
21799
|
+
const menuEntriesRef = useRef2(entries);
|
|
21800
|
+
menuEntriesRef.current = entries;
|
|
21801
|
+
const selectedRef = useRef2(selected);
|
|
21802
|
+
selectedRef.current = selected;
|
|
21420
21803
|
useInput4((input_, key2) => {
|
|
21804
|
+
if (menuOpen && entries.length > 0) {
|
|
21805
|
+
if (key2.upArrow) {
|
|
21806
|
+
setMenuIndex((current) => current <= 0 ? entries.length - 1 : current - 1);
|
|
21807
|
+
return;
|
|
21808
|
+
}
|
|
21809
|
+
if (key2.downArrow) {
|
|
21810
|
+
setMenuIndex((current) => current >= entries.length - 1 ? 0 : current + 1);
|
|
21811
|
+
return;
|
|
21812
|
+
}
|
|
21813
|
+
if (key2.tab) {
|
|
21814
|
+
const entry = entries[selected];
|
|
21815
|
+
if (entry)
|
|
21816
|
+
setInput(`${entry.insert} `);
|
|
21817
|
+
setMenuIndex(0);
|
|
21818
|
+
return;
|
|
21819
|
+
}
|
|
21820
|
+
if (key2.escape) {
|
|
21821
|
+
setInput("");
|
|
21822
|
+
setMenuIndex(0);
|
|
21823
|
+
return;
|
|
21824
|
+
}
|
|
21825
|
+
}
|
|
21421
21826
|
if (key2.escape) {
|
|
21422
21827
|
setCandidate(undefined);
|
|
21423
21828
|
if (busy)
|
|
@@ -21428,26 +21833,26 @@ ${PLAN_PROMPT}`);
|
|
|
21428
21833
|
remember(input_ === "r" ? "project" : "user");
|
|
21429
21834
|
}
|
|
21430
21835
|
}, { isActive: inputActive });
|
|
21431
|
-
return /* @__PURE__ */
|
|
21836
|
+
return /* @__PURE__ */ jsxDEV10(Box9, {
|
|
21432
21837
|
flexDirection: "column",
|
|
21433
21838
|
children: [
|
|
21434
|
-
/* @__PURE__ */
|
|
21839
|
+
/* @__PURE__ */ jsxDEV10(Static, {
|
|
21435
21840
|
items,
|
|
21436
|
-
children: (item) => /* @__PURE__ */
|
|
21841
|
+
children: (item) => /* @__PURE__ */ jsxDEV10(ScrollRow, {
|
|
21437
21842
|
item
|
|
21438
21843
|
}, item.id, false, undefined, this)
|
|
21439
21844
|
}, undefined, false, undefined, this),
|
|
21440
|
-
live !== "" && /* @__PURE__ */
|
|
21845
|
+
live !== "" && /* @__PURE__ */ jsxDEV10(Box9, {
|
|
21441
21846
|
marginTop: 1,
|
|
21442
|
-
children: /* @__PURE__ */
|
|
21847
|
+
children: /* @__PURE__ */ jsxDEV10(Markdown, {
|
|
21443
21848
|
text: live
|
|
21444
21849
|
}, undefined, false, undefined, this)
|
|
21445
21850
|
}, undefined, false, undefined, this),
|
|
21446
|
-
runningTool && /* @__PURE__ */
|
|
21851
|
+
runningTool && /* @__PURE__ */ jsxDEV10(ToolBlock, {
|
|
21447
21852
|
name: runningTool,
|
|
21448
21853
|
running: true
|
|
21449
21854
|
}, undefined, false, undefined, this),
|
|
21450
|
-
pending && /* @__PURE__ */
|
|
21855
|
+
pending && /* @__PURE__ */ jsxDEV10(PermissionPrompt, {
|
|
21451
21856
|
request: pending.request,
|
|
21452
21857
|
reason: pending.reason,
|
|
21453
21858
|
onChoice: (choice) => {
|
|
@@ -21455,7 +21860,7 @@ ${PLAN_PROMPT}`);
|
|
|
21455
21860
|
pending.resolve(choice);
|
|
21456
21861
|
}
|
|
21457
21862
|
}, undefined, false, undefined, this),
|
|
21458
|
-
question && /* @__PURE__ */
|
|
21863
|
+
question && /* @__PURE__ */ jsxDEV10(QuestionPrompt, {
|
|
21459
21864
|
question: question.question,
|
|
21460
21865
|
...question.options ? { options: question.options } : {},
|
|
21461
21866
|
onAnswer: (answer) => {
|
|
@@ -21463,25 +21868,32 @@ ${PLAN_PROMPT}`);
|
|
|
21463
21868
|
question.resolve(answer);
|
|
21464
21869
|
}
|
|
21465
21870
|
}, undefined, false, undefined, this),
|
|
21466
|
-
candidate && inputActive && /* @__PURE__ */
|
|
21871
|
+
candidate && inputActive && /* @__PURE__ */ jsxDEV10(MemoryCapture, {
|
|
21467
21872
|
candidate
|
|
21468
21873
|
}, undefined, false, undefined, this),
|
|
21469
|
-
|
|
21874
|
+
menuOpen && /* @__PURE__ */ jsxDEV10(CommandMenu, {
|
|
21875
|
+
entries,
|
|
21876
|
+
selected
|
|
21877
|
+
}, undefined, false, undefined, this),
|
|
21878
|
+
inputActive && /* @__PURE__ */ jsxDEV10(Box9, {
|
|
21470
21879
|
marginTop: 1,
|
|
21471
21880
|
children: [
|
|
21472
|
-
/* @__PURE__ */
|
|
21881
|
+
/* @__PURE__ */ jsxDEV10(Text10, {
|
|
21473
21882
|
color: theme.user,
|
|
21474
21883
|
children: "> "
|
|
21475
21884
|
}, undefined, false, undefined, this),
|
|
21476
|
-
/* @__PURE__ */
|
|
21885
|
+
/* @__PURE__ */ jsxDEV10(TextInput, {
|
|
21477
21886
|
value: input,
|
|
21478
|
-
onChange:
|
|
21887
|
+
onChange: (value) => {
|
|
21888
|
+
setInput(value);
|
|
21889
|
+
setMenuIndex(0);
|
|
21890
|
+
},
|
|
21479
21891
|
onSubmit: submit,
|
|
21480
21892
|
placeholder: busy ? "steer the agent, or esc to interrupt" : "what should I do?"
|
|
21481
21893
|
}, undefined, false, undefined, this)
|
|
21482
21894
|
]
|
|
21483
21895
|
}, undefined, true, undefined, this),
|
|
21484
|
-
/* @__PURE__ */
|
|
21896
|
+
/* @__PURE__ */ jsxDEV10(StatusLine, {
|
|
21485
21897
|
model: model2,
|
|
21486
21898
|
mode,
|
|
21487
21899
|
costUsd: cost,
|
|
@@ -21496,43 +21908,58 @@ ${PLAN_PROMPT}`);
|
|
|
21496
21908
|
}
|
|
21497
21909
|
function ScrollRow({ item }) {
|
|
21498
21910
|
if (item.kind === "user") {
|
|
21499
|
-
return /* @__PURE__ */
|
|
21911
|
+
return /* @__PURE__ */ jsxDEV10(Box9, {
|
|
21500
21912
|
marginTop: 1,
|
|
21501
21913
|
children: [
|
|
21502
|
-
/* @__PURE__ */
|
|
21914
|
+
/* @__PURE__ */ jsxDEV10(Text10, {
|
|
21503
21915
|
color: theme.user,
|
|
21504
21916
|
children: "> "
|
|
21505
21917
|
}, undefined, false, undefined, this),
|
|
21506
|
-
/* @__PURE__ */
|
|
21918
|
+
/* @__PURE__ */ jsxDEV10(Text10, {
|
|
21507
21919
|
children: item.text
|
|
21508
21920
|
}, undefined, false, undefined, this)
|
|
21509
21921
|
]
|
|
21510
21922
|
}, undefined, true, undefined, this);
|
|
21511
21923
|
}
|
|
21512
21924
|
if (item.kind === "assistant") {
|
|
21513
|
-
return /* @__PURE__ */
|
|
21925
|
+
return /* @__PURE__ */ jsxDEV10(Box9, {
|
|
21514
21926
|
marginTop: 1,
|
|
21515
|
-
children: /* @__PURE__ */
|
|
21927
|
+
children: /* @__PURE__ */ jsxDEV10(Markdown, {
|
|
21516
21928
|
text: item.text
|
|
21517
21929
|
}, undefined, false, undefined, this)
|
|
21518
21930
|
}, undefined, false, undefined, this);
|
|
21519
21931
|
}
|
|
21520
21932
|
if (item.kind === "tool") {
|
|
21521
|
-
return /* @__PURE__ */
|
|
21933
|
+
return /* @__PURE__ */ jsxDEV10(ToolBlock, {
|
|
21522
21934
|
name: item.name,
|
|
21523
21935
|
...item.title ? { title: item.title } : {},
|
|
21524
21936
|
...item.output ? { output: item.output } : {},
|
|
21525
21937
|
...item.isError ? { isError: true } : {}
|
|
21526
21938
|
}, undefined, false, undefined, this);
|
|
21527
21939
|
}
|
|
21528
|
-
return /* @__PURE__ */
|
|
21940
|
+
return /* @__PURE__ */ jsxDEV10(Box9, {
|
|
21529
21941
|
marginTop: 1,
|
|
21530
|
-
children: /* @__PURE__ */
|
|
21942
|
+
children: /* @__PURE__ */ jsxDEV10(Text10, {
|
|
21531
21943
|
color: item.color ?? theme.muted,
|
|
21532
21944
|
children: item.text
|
|
21533
21945
|
}, undefined, false, undefined, this)
|
|
21534
21946
|
}, undefined, false, undefined, this);
|
|
21535
21947
|
}
|
|
21948
|
+
function describeCommands(session2) {
|
|
21949
|
+
const lines = commandRows().map((row) => ` ${row.command.padEnd(34)} ${row.summary}`);
|
|
21950
|
+
if (session2.commands.length > 0) {
|
|
21951
|
+
lines.push("", " commands from this directory:");
|
|
21952
|
+
for (const command of session2.commands) {
|
|
21953
|
+
lines.push(` ${`/${command.name}`.padEnd(34)} ${command.description}`);
|
|
21954
|
+
}
|
|
21955
|
+
}
|
|
21956
|
+
lines.push("", " type / at the prompt to filter this list and pick one");
|
|
21957
|
+
return lines.join(`
|
|
21958
|
+
`);
|
|
21959
|
+
}
|
|
21960
|
+
var INIT_PROMPT = `Write an AGENTS.md at the root of this project for a coding agent that has never seen it.
|
|
21961
|
+
|
|
21962
|
+
Read enough of the repository first to be accurate. Cover: what the project is, how it is laid out, the commands to build, test and lint it, and the conventions and rules that are not obvious from the code. Prefer rules that prevent a specific failure, and say what the failure is. If an AGENTS.md or CLAUDE.md already exists, improve it in place rather than replacing it.`;
|
|
21536
21963
|
function describeExtensions(session2) {
|
|
21537
21964
|
const lines = [];
|
|
21538
21965
|
if (session2.skills.length > 0) {
|
|
@@ -21552,14 +21979,347 @@ function describeExtensions(session2) {
|
|
|
21552
21979
|
return lines.length === 0 ? "no skills or commands found in .earshot/skills, .earshot/commands or your config directory" : lines.join(`
|
|
21553
21980
|
`);
|
|
21554
21981
|
}
|
|
21982
|
+
// packages/tui/src/onboarding.tsx
|
|
21983
|
+
import { Box as Box10, Text as Text11, useApp as useApp2, useInput as useInput5 } from "ink";
|
|
21984
|
+
import { useCallback as useCallback2, useRef as useRef3, useState as useState4 } from "react";
|
|
21985
|
+
import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
|
|
21986
|
+
function Onboarding({ onDone, ...rest }) {
|
|
21987
|
+
const { exit } = useApp2();
|
|
21988
|
+
const options = useRef3(rest);
|
|
21989
|
+
options.current = rest;
|
|
21990
|
+
const [screen, setScreen] = useState4({ name: "choose" });
|
|
21991
|
+
const [cursor, setCursor] = useState4(0);
|
|
21992
|
+
const [input, setInput] = useState4("");
|
|
21993
|
+
const [error, setError] = useState4();
|
|
21994
|
+
const secret = useRef3("");
|
|
21995
|
+
const providers = order(rest.providers, rest.wanted);
|
|
21996
|
+
const finish = useCallback2((result) => {
|
|
21997
|
+
onDone(result);
|
|
21998
|
+
exit();
|
|
21999
|
+
}, [exit, onDone]);
|
|
22000
|
+
const verify2 = useCallback2(async (provider) => {
|
|
22001
|
+
setScreen({ name: "probing", provider });
|
|
22002
|
+
const result = await options.current.probe(provider.id);
|
|
22003
|
+
if (result.ok) {
|
|
22004
|
+
setScreen({ name: "ready", provider });
|
|
22005
|
+
return;
|
|
22006
|
+
}
|
|
22007
|
+
if (result.reason === "rejected")
|
|
22008
|
+
await options.current.forgetKey(provider.id).catch(() => {});
|
|
22009
|
+
setScreen({ name: "failed", provider, result });
|
|
22010
|
+
}, []);
|
|
22011
|
+
const submitKey = useCallback2(async () => {
|
|
22012
|
+
const provider = screen.name === "key" ? screen.provider : undefined;
|
|
22013
|
+
const key2 = secret.current;
|
|
22014
|
+
secret.current = "";
|
|
22015
|
+
setInput("");
|
|
22016
|
+
if (!provider)
|
|
22017
|
+
return;
|
|
22018
|
+
if (key2.trim() === "") {
|
|
22019
|
+
setError("a key is needed, or press esc to go back");
|
|
22020
|
+
return;
|
|
22021
|
+
}
|
|
22022
|
+
setError(undefined);
|
|
22023
|
+
await options.current.storeKey(provider.id, key2.trim());
|
|
22024
|
+
await verify2(provider);
|
|
22025
|
+
}, [screen, verify2]);
|
|
22026
|
+
const startSignIn = useCallback2(async (provider) => {
|
|
22027
|
+
setScreen({ name: "oauth", provider });
|
|
22028
|
+
try {
|
|
22029
|
+
await options.current.signIn(provider.id, (url) => setScreen({ name: "oauth", provider, url }));
|
|
22030
|
+
} catch (failure) {
|
|
22031
|
+
setScreen({
|
|
22032
|
+
name: "failed",
|
|
22033
|
+
provider,
|
|
22034
|
+
result: { ok: false, reason: "other", message: failure.message }
|
|
22035
|
+
});
|
|
22036
|
+
return;
|
|
22037
|
+
}
|
|
22038
|
+
await verify2(provider);
|
|
22039
|
+
}, [verify2]);
|
|
22040
|
+
const choose = useCallback2((provider) => {
|
|
22041
|
+
setError(undefined);
|
|
22042
|
+
if (provider.kind === "oauth")
|
|
22043
|
+
startSignIn(provider);
|
|
22044
|
+
else
|
|
22045
|
+
setScreen({ name: "key", provider });
|
|
22046
|
+
}, [startSignIn]);
|
|
22047
|
+
useInput5((key2, meta) => {
|
|
22048
|
+
if (meta.ctrl && key2 === "c") {
|
|
22049
|
+
finish({ outcome: "quit" });
|
|
22050
|
+
return;
|
|
22051
|
+
}
|
|
22052
|
+
if (screen.name === "choose") {
|
|
22053
|
+
if (key2 === "q") {
|
|
22054
|
+
finish({ outcome: "quit" });
|
|
22055
|
+
return;
|
|
22056
|
+
}
|
|
22057
|
+
if (meta.upArrow)
|
|
22058
|
+
setCursor((c) => c <= 0 ? providers.length - 1 : c - 1);
|
|
22059
|
+
if (meta.downArrow)
|
|
22060
|
+
setCursor((c) => c >= providers.length - 1 ? 0 : c + 1);
|
|
22061
|
+
if (meta.return) {
|
|
22062
|
+
const provider = providers[cursor];
|
|
22063
|
+
if (provider)
|
|
22064
|
+
choose(provider);
|
|
22065
|
+
}
|
|
22066
|
+
return;
|
|
22067
|
+
}
|
|
22068
|
+
if (screen.name === "key" && !meta.escape) {
|
|
22069
|
+
if (meta.return) {
|
|
22070
|
+
submitKey();
|
|
22071
|
+
return;
|
|
22072
|
+
}
|
|
22073
|
+
if (meta.backspace || meta.delete) {
|
|
22074
|
+
secret.current = secret.current.slice(0, -1);
|
|
22075
|
+
setInput(secret.current);
|
|
22076
|
+
return;
|
|
22077
|
+
}
|
|
22078
|
+
if (meta.ctrl || meta.meta || meta.tab)
|
|
22079
|
+
return;
|
|
22080
|
+
if (key2) {
|
|
22081
|
+
secret.current += key2;
|
|
22082
|
+
setInput(secret.current);
|
|
22083
|
+
}
|
|
22084
|
+
return;
|
|
22085
|
+
}
|
|
22086
|
+
if (meta.escape) {
|
|
22087
|
+
secret.current = "";
|
|
22088
|
+
setInput("");
|
|
22089
|
+
setError(undefined);
|
|
22090
|
+
setScreen({ name: "choose" });
|
|
22091
|
+
return;
|
|
22092
|
+
}
|
|
22093
|
+
if (screen.name === "failed" && key2 === "k" && screen.result.reason === "unreachable") {
|
|
22094
|
+
setScreen({ name: "ready", provider: screen.provider });
|
|
22095
|
+
}
|
|
22096
|
+
});
|
|
22097
|
+
if (screen.name === "choose") {
|
|
22098
|
+
return /* @__PURE__ */ jsxDEV11(Box10, {
|
|
22099
|
+
flexDirection: "column",
|
|
22100
|
+
children: [
|
|
22101
|
+
/* @__PURE__ */ jsxDEV11(Header, {}, undefined, false, undefined, this),
|
|
22102
|
+
providers.map((provider, index) => /* @__PURE__ */ jsxDEV11(Box10, {
|
|
22103
|
+
children: [
|
|
22104
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22105
|
+
color: index === cursor ? theme.user : theme.muted,
|
|
22106
|
+
children: index === cursor ? "› " : " "
|
|
22107
|
+
}, undefined, false, undefined, this),
|
|
22108
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22109
|
+
...index === cursor ? { color: theme.user } : {},
|
|
22110
|
+
children: provider.id.padEnd(14)
|
|
22111
|
+
}, undefined, false, undefined, this),
|
|
22112
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22113
|
+
color: theme.muted,
|
|
22114
|
+
children: hint(provider)
|
|
22115
|
+
}, undefined, false, undefined, this)
|
|
22116
|
+
]
|
|
22117
|
+
}, provider.id, true, undefined, this)),
|
|
22118
|
+
/* @__PURE__ */ jsxDEV11(Box10, {
|
|
22119
|
+
marginTop: 1,
|
|
22120
|
+
children: /* @__PURE__ */ jsxDEV11(Text11, {
|
|
22121
|
+
color: theme.muted,
|
|
22122
|
+
children: "↑↓ choose · enter select · q quit"
|
|
22123
|
+
}, undefined, false, undefined, this)
|
|
22124
|
+
}, undefined, false, undefined, this),
|
|
22125
|
+
error ? /* @__PURE__ */ jsxDEV11(Text11, {
|
|
22126
|
+
color: theme.warning,
|
|
22127
|
+
children: error
|
|
22128
|
+
}, undefined, false, undefined, this) : null
|
|
22129
|
+
]
|
|
22130
|
+
}, undefined, true, undefined, this);
|
|
22131
|
+
}
|
|
22132
|
+
if (screen.name === "key") {
|
|
22133
|
+
return /* @__PURE__ */ jsxDEV11(Box10, {
|
|
22134
|
+
flexDirection: "column",
|
|
22135
|
+
children: [
|
|
22136
|
+
/* @__PURE__ */ jsxDEV11(Header, {}, undefined, false, undefined, this),
|
|
22137
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22138
|
+
children: [
|
|
22139
|
+
"paste an api key for ",
|
|
22140
|
+
screen.provider.id
|
|
22141
|
+
]
|
|
22142
|
+
}, undefined, true, undefined, this),
|
|
22143
|
+
/* @__PURE__ */ jsxDEV11(Box10, {
|
|
22144
|
+
marginTop: 1,
|
|
22145
|
+
children: /* @__PURE__ */ jsxDEV11(Text11, {
|
|
22146
|
+
color: theme.muted,
|
|
22147
|
+
children: [
|
|
22148
|
+
screen.provider.envVars?.length ? `or set ${screen.provider.envVars.join(" or ")} instead and restart.
|
|
22149
|
+
` : "",
|
|
22150
|
+
"stored in your config directory, readable only by you, and never printed."
|
|
22151
|
+
]
|
|
22152
|
+
}, undefined, true, undefined, this)
|
|
22153
|
+
}, undefined, false, undefined, this),
|
|
22154
|
+
/* @__PURE__ */ jsxDEV11(Box10, {
|
|
22155
|
+
marginTop: 1,
|
|
22156
|
+
children: [
|
|
22157
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22158
|
+
color: theme.user,
|
|
22159
|
+
children: "> "
|
|
22160
|
+
}, undefined, false, undefined, this),
|
|
22161
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22162
|
+
children: "•".repeat(input.length)
|
|
22163
|
+
}, undefined, false, undefined, this),
|
|
22164
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22165
|
+
inverse: true,
|
|
22166
|
+
children: " "
|
|
22167
|
+
}, undefined, false, undefined, this)
|
|
22168
|
+
]
|
|
22169
|
+
}, undefined, true, undefined, this),
|
|
22170
|
+
error ? /* @__PURE__ */ jsxDEV11(Text11, {
|
|
22171
|
+
color: theme.warning,
|
|
22172
|
+
children: error
|
|
22173
|
+
}, undefined, false, undefined, this) : null,
|
|
22174
|
+
/* @__PURE__ */ jsxDEV11(Box10, {
|
|
22175
|
+
marginTop: 1,
|
|
22176
|
+
children: /* @__PURE__ */ jsxDEV11(Text11, {
|
|
22177
|
+
color: theme.muted,
|
|
22178
|
+
children: "enter continue · esc back"
|
|
22179
|
+
}, undefined, false, undefined, this)
|
|
22180
|
+
}, undefined, false, undefined, this)
|
|
22181
|
+
]
|
|
22182
|
+
}, undefined, true, undefined, this);
|
|
22183
|
+
}
|
|
22184
|
+
if (screen.name === "oauth") {
|
|
22185
|
+
return /* @__PURE__ */ jsxDEV11(Box10, {
|
|
22186
|
+
flexDirection: "column",
|
|
22187
|
+
children: [
|
|
22188
|
+
/* @__PURE__ */ jsxDEV11(Header, {}, undefined, false, undefined, this),
|
|
22189
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22190
|
+
children: [
|
|
22191
|
+
"signing in to ",
|
|
22192
|
+
screen.provider.id,
|
|
22193
|
+
" in your browser…"
|
|
22194
|
+
]
|
|
22195
|
+
}, undefined, true, undefined, this),
|
|
22196
|
+
screen.url ? /* @__PURE__ */ jsxDEV11(Box10, {
|
|
22197
|
+
marginTop: 1,
|
|
22198
|
+
flexDirection: "column",
|
|
22199
|
+
children: [
|
|
22200
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22201
|
+
color: theme.muted,
|
|
22202
|
+
children: "if it did not open, use this link:"
|
|
22203
|
+
}, undefined, false, undefined, this),
|
|
22204
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22205
|
+
children: screen.url
|
|
22206
|
+
}, undefined, false, undefined, this)
|
|
22207
|
+
]
|
|
22208
|
+
}, undefined, true, undefined, this) : null,
|
|
22209
|
+
/* @__PURE__ */ jsxDEV11(Box10, {
|
|
22210
|
+
marginTop: 1,
|
|
22211
|
+
children: /* @__PURE__ */ jsxDEV11(Text11, {
|
|
22212
|
+
color: theme.muted,
|
|
22213
|
+
children: "esc cancel"
|
|
22214
|
+
}, undefined, false, undefined, this)
|
|
22215
|
+
}, undefined, false, undefined, this)
|
|
22216
|
+
]
|
|
22217
|
+
}, undefined, true, undefined, this);
|
|
22218
|
+
}
|
|
22219
|
+
if (screen.name === "probing") {
|
|
22220
|
+
return /* @__PURE__ */ jsxDEV11(Box10, {
|
|
22221
|
+
flexDirection: "column",
|
|
22222
|
+
children: [
|
|
22223
|
+
/* @__PURE__ */ jsxDEV11(Header, {}, undefined, false, undefined, this),
|
|
22224
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22225
|
+
color: theme.muted,
|
|
22226
|
+
children: [
|
|
22227
|
+
"checking the credentials with ",
|
|
22228
|
+
screen.provider.id,
|
|
22229
|
+
"…"
|
|
22230
|
+
]
|
|
22231
|
+
}, undefined, true, undefined, this)
|
|
22232
|
+
]
|
|
22233
|
+
}, undefined, true, undefined, this);
|
|
22234
|
+
}
|
|
22235
|
+
if (screen.name === "failed") {
|
|
22236
|
+
return /* @__PURE__ */ jsxDEV11(Box10, {
|
|
22237
|
+
flexDirection: "column",
|
|
22238
|
+
children: [
|
|
22239
|
+
/* @__PURE__ */ jsxDEV11(Header, {}, undefined, false, undefined, this),
|
|
22240
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22241
|
+
color: theme.warning,
|
|
22242
|
+
children: screen.result.reason === "rejected" ? `${screen.provider.id} rejected that credential. It has not been kept.` : screen.result.reason === "unreachable" ? `could not reach ${screen.provider.id}.` : `${screen.provider.id} said:`
|
|
22243
|
+
}, undefined, false, undefined, this),
|
|
22244
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22245
|
+
color: theme.muted,
|
|
22246
|
+
children: screen.result.message
|
|
22247
|
+
}, undefined, false, undefined, this),
|
|
22248
|
+
/* @__PURE__ */ jsxDEV11(Box10, {
|
|
22249
|
+
marginTop: 1,
|
|
22250
|
+
children: /* @__PURE__ */ jsxDEV11(Text11, {
|
|
22251
|
+
color: theme.muted,
|
|
22252
|
+
children: screen.result.reason === "unreachable" ? "k keep it anyway and carry on · esc start over · ctrl-c quit" : "esc start over · ctrl-c quit"
|
|
22253
|
+
}, undefined, false, undefined, this)
|
|
22254
|
+
}, undefined, false, undefined, this)
|
|
22255
|
+
]
|
|
22256
|
+
}, undefined, true, undefined, this);
|
|
22257
|
+
}
|
|
22258
|
+
return /* @__PURE__ */ jsxDEV11(Box10, {
|
|
22259
|
+
flexDirection: "column",
|
|
22260
|
+
children: [
|
|
22261
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22262
|
+
color: theme.user,
|
|
22263
|
+
children: [
|
|
22264
|
+
"ready: ",
|
|
22265
|
+
screen.provider.id
|
|
22266
|
+
]
|
|
22267
|
+
}, undefined, true, undefined, this),
|
|
22268
|
+
/* @__PURE__ */ jsxDEV11(Box10, {
|
|
22269
|
+
marginTop: 1,
|
|
22270
|
+
children: /* @__PURE__ */ jsxDEV11(Text11, {
|
|
22271
|
+
color: theme.muted,
|
|
22272
|
+
children: "what should I do? (enter to start with nothing)"
|
|
22273
|
+
}, undefined, false, undefined, this)
|
|
22274
|
+
}, undefined, false, undefined, this),
|
|
22275
|
+
/* @__PURE__ */ jsxDEV11(Box10, {
|
|
22276
|
+
children: [
|
|
22277
|
+
/* @__PURE__ */ jsxDEV11(Text11, {
|
|
22278
|
+
color: theme.user,
|
|
22279
|
+
children: "> "
|
|
22280
|
+
}, undefined, false, undefined, this),
|
|
22281
|
+
/* @__PURE__ */ jsxDEV11(TextInput, {
|
|
22282
|
+
value: input,
|
|
22283
|
+
onChange: setInput,
|
|
22284
|
+
onSubmit: (text2) => finish({ outcome: "ready", providerId: screen.provider.id, firstPrompt: text2.trim() })
|
|
22285
|
+
}, undefined, false, undefined, this)
|
|
22286
|
+
]
|
|
22287
|
+
}, undefined, true, undefined, this)
|
|
22288
|
+
]
|
|
22289
|
+
}, undefined, true, undefined, this);
|
|
22290
|
+
}
|
|
22291
|
+
function Header() {
|
|
22292
|
+
return /* @__PURE__ */ jsxDEV11(Box10, {
|
|
22293
|
+
flexDirection: "column",
|
|
22294
|
+
marginBottom: 1,
|
|
22295
|
+
children: /* @__PURE__ */ jsxDEV11(Text11, {
|
|
22296
|
+
children: "earshot needs a model provider before it can do anything."
|
|
22297
|
+
}, undefined, false, undefined, this)
|
|
22298
|
+
}, undefined, false, undefined, this);
|
|
22299
|
+
}
|
|
22300
|
+
function hint(provider) {
|
|
22301
|
+
if (provider.configured)
|
|
22302
|
+
return provider.configured;
|
|
22303
|
+
if (provider.kind === "oauth")
|
|
22304
|
+
return "sign in with a browser - no key to paste";
|
|
22305
|
+
return provider.envVars?.length ? provider.envVars.join(" or ") : "api key";
|
|
22306
|
+
}
|
|
22307
|
+
function order(providers, wanted) {
|
|
22308
|
+
if (!wanted)
|
|
22309
|
+
return providers;
|
|
22310
|
+
return [
|
|
22311
|
+
...providers.filter((provider) => provider.id === wanted),
|
|
22312
|
+
...providers.filter((provider) => provider.id !== wanted)
|
|
22313
|
+
];
|
|
22314
|
+
}
|
|
21555
22315
|
// packages/tui/src/run.tsx
|
|
21556
22316
|
import { platform as platform6 } from "node:os";
|
|
21557
22317
|
import { render } from "ink";
|
|
21558
|
-
import { jsxDEV as
|
|
22318
|
+
import { jsxDEV as jsxDEV12 } from "react/jsx-dev-runtime";
|
|
21559
22319
|
var WINDOWS_MAX_FPS = 30;
|
|
21560
22320
|
async function runTui(options) {
|
|
21561
22321
|
const isWindows = platform6() === "win32";
|
|
21562
|
-
const instance = render(/* @__PURE__ */
|
|
22322
|
+
const instance = render(/* @__PURE__ */ jsxDEV12(App, {
|
|
21563
22323
|
session: options.session,
|
|
21564
22324
|
model: options.model,
|
|
21565
22325
|
...options.initialPrompt ? { initialPrompt: options.initialPrompt } : {}
|
|
@@ -21575,6 +22335,105 @@ async function runTui(options) {
|
|
|
21575
22335
|
}
|
|
21576
22336
|
return 0;
|
|
21577
22337
|
}
|
|
22338
|
+
async function runOnboarding(options) {
|
|
22339
|
+
const isWindows = platform6() === "win32";
|
|
22340
|
+
let result = { outcome: "quit" };
|
|
22341
|
+
const instance = render(/* @__PURE__ */ jsxDEV12(Onboarding, {
|
|
22342
|
+
...options,
|
|
22343
|
+
onDone: (decided) => {
|
|
22344
|
+
result = decided;
|
|
22345
|
+
}
|
|
22346
|
+
}, undefined, false, undefined, this), {
|
|
22347
|
+
exitOnCtrlC: false,
|
|
22348
|
+
patchConsole: true,
|
|
22349
|
+
...isWindows ? { maxFps: WINDOWS_MAX_FPS } : {}
|
|
22350
|
+
});
|
|
22351
|
+
await instance.waitUntilExit();
|
|
22352
|
+
return result;
|
|
22353
|
+
}
|
|
22354
|
+
// packages/cli/src/onboard.ts
|
|
22355
|
+
async function buildOnboardingOptions(wanted) {
|
|
22356
|
+
const registry2 = buildRegistry();
|
|
22357
|
+
const store3 = new AuthStore;
|
|
22358
|
+
const providers = [];
|
|
22359
|
+
for (const provider of registry2.list()) {
|
|
22360
|
+
if (provider.auth.kind === "none")
|
|
22361
|
+
continue;
|
|
22362
|
+
providers.push(await describe3(provider, store3));
|
|
22363
|
+
}
|
|
22364
|
+
providers.sort((a, b) => Number(b.kind === "oauth") - Number(a.kind === "oauth"));
|
|
22365
|
+
return {
|
|
22366
|
+
providers,
|
|
22367
|
+
...wanted ? { wanted } : {},
|
|
22368
|
+
storeKey: (providerId, key2) => store3.set(providerId, { type: "api-key", apiKey: key2 }),
|
|
22369
|
+
forgetKey: (providerId) => store3.remove(providerId),
|
|
22370
|
+
signIn: async (providerId, onUrl) => {
|
|
22371
|
+
const credentials = await loginToOpenRouter({ onUrl });
|
|
22372
|
+
await store3.set(providerId, credentials);
|
|
22373
|
+
},
|
|
22374
|
+
probe: (providerId) => probe(registry2, providerId)
|
|
22375
|
+
};
|
|
22376
|
+
}
|
|
22377
|
+
async function describe3(provider, store3) {
|
|
22378
|
+
const configured = await resolveCredentials(provider, { store: store3 }).catch(() => {
|
|
22379
|
+
return;
|
|
22380
|
+
});
|
|
22381
|
+
return {
|
|
22382
|
+
id: provider.id,
|
|
22383
|
+
kind: provider.auth.kind === "oauth" ? "oauth" : "api-key",
|
|
22384
|
+
...envVarsOf2(provider.auth).length ? { envVars: envVarsOf2(provider.auth) } : {},
|
|
22385
|
+
...configured ? { configured: describeConfigured(configured.type) } : {}
|
|
22386
|
+
};
|
|
22387
|
+
}
|
|
22388
|
+
function envVarsOf2(auth2) {
|
|
22389
|
+
return auth2.kind === "api-key" || auth2.kind === "oauth" ? auth2.envVars ?? [] : [];
|
|
22390
|
+
}
|
|
22391
|
+
function describeConfigured(kind) {
|
|
22392
|
+
return kind === "ambient" ? "ambient credentials" : kind === "oauth" ? "signed in" : "api key set";
|
|
22393
|
+
}
|
|
22394
|
+
async function probe(registry2, providerId) {
|
|
22395
|
+
const listed = registry2.list().find((provider) => provider.id === providerId);
|
|
22396
|
+
if (!listed)
|
|
22397
|
+
return { ok: false, reason: "other", message: `unknown provider "${providerId}"` };
|
|
22398
|
+
const model2 = listed.models()[0];
|
|
22399
|
+
if (!model2) {
|
|
22400
|
+
return {
|
|
22401
|
+
ok: false,
|
|
22402
|
+
reason: "other",
|
|
22403
|
+
message: `${providerId} publishes no models to check against`
|
|
22404
|
+
};
|
|
22405
|
+
}
|
|
22406
|
+
let resolved;
|
|
22407
|
+
try {
|
|
22408
|
+
resolved = await resolveModel(registry2, `${providerId}/${model2.id}`);
|
|
22409
|
+
} catch (error) {
|
|
22410
|
+
return { ok: false, reason: "other", message: error.message };
|
|
22411
|
+
}
|
|
22412
|
+
const controller = new AbortController;
|
|
22413
|
+
const timeout = setTimeout(() => controller.abort(), 1e4);
|
|
22414
|
+
try {
|
|
22415
|
+
for await (const event of streamModel(registry2, resolved, {
|
|
22416
|
+
system: "Reply with one word.",
|
|
22417
|
+
messages: [{ role: "user", content: [{ type: "text", text: "hi" }] }],
|
|
22418
|
+
maxOutputTokens: 1,
|
|
22419
|
+
abortSignal: controller.signal
|
|
22420
|
+
})) {
|
|
22421
|
+
controller.abort();
|
|
22422
|
+
if (event.type === "error") {
|
|
22423
|
+
return event.error.kind === "auth" ? { ok: false, reason: "rejected", message: event.error.message } : event.error.kind === "network" ? { ok: false, reason: "unreachable", message: event.error.message } : { ok: false, reason: "other", message: event.error.message };
|
|
22424
|
+
}
|
|
22425
|
+
return { ok: true };
|
|
22426
|
+
}
|
|
22427
|
+
return { ok: true };
|
|
22428
|
+
} catch (error) {
|
|
22429
|
+
const message = error.message;
|
|
22430
|
+
const timedOut = controller.signal.aborted && error.name === "AbortError";
|
|
22431
|
+
return timedOut ? { ok: false, reason: "unreachable", message: "timed out waiting for a response" } : { ok: false, reason: "other", message };
|
|
22432
|
+
} finally {
|
|
22433
|
+
clearTimeout(timeout);
|
|
22434
|
+
}
|
|
22435
|
+
}
|
|
22436
|
+
|
|
21578
22437
|
// packages/cli/src/commands/interactive.ts
|
|
21579
22438
|
var DEFAULT_MODEL3 = "anthropic/claude-opus-5";
|
|
21580
22439
|
async function interactiveCommand(args) {
|
|
@@ -21617,46 +22476,63 @@ async function interactiveCommand(args) {
|
|
|
21617
22476
|
return 2;
|
|
21618
22477
|
}
|
|
21619
22478
|
const extensions = await startExtensions(process.cwd());
|
|
21620
|
-
|
|
21621
|
-
|
|
21622
|
-
|
|
21623
|
-
|
|
21624
|
-
|
|
21625
|
-
|
|
21626
|
-
|
|
21627
|
-
|
|
21628
|
-
|
|
21629
|
-
|
|
21630
|
-
|
|
21631
|
-
|
|
21632
|
-
|
|
21633
|
-
|
|
21634
|
-
|
|
21635
|
-
|
|
21636
|
-
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
|
|
21640
|
-
|
|
21641
|
-
|
|
21642
|
-
|
|
21643
|
-
|
|
22479
|
+
const model2 = typeof flags.model === "string" ? flags.model : DEFAULT_MODEL3;
|
|
22480
|
+
const onboardingAllowed = flags["no-onboarding"] !== true;
|
|
22481
|
+
let firstPrompt = initialPrompt;
|
|
22482
|
+
let attempted = false;
|
|
22483
|
+
for (;; ) {
|
|
22484
|
+
try {
|
|
22485
|
+
const session2 = await createSession({
|
|
22486
|
+
cwd: process.cwd(),
|
|
22487
|
+
extraTools: extensions.tools,
|
|
22488
|
+
problems: extensions.problems,
|
|
22489
|
+
onDispose: () => extensions.close(),
|
|
22490
|
+
model: model2,
|
|
22491
|
+
...mode ? { mode } : {},
|
|
22492
|
+
...typeof flags["api-key"] === "string" ? { apiKey: flags["api-key"] } : {},
|
|
22493
|
+
...curiosity ? { curiosity } : {},
|
|
22494
|
+
...maxCostUsd !== undefined ? { maxCostUsd } : {},
|
|
22495
|
+
...resumeFrom2(flags)
|
|
22496
|
+
});
|
|
22497
|
+
return await runTui({
|
|
22498
|
+
session: session2,
|
|
22499
|
+
model: model2,
|
|
22500
|
+
...firstPrompt !== "" || image ? {
|
|
22501
|
+
initialPrompt: image ? [...firstPrompt ? [{ type: "text", text: firstPrompt }] : [], image] : firstPrompt
|
|
22502
|
+
} : {}
|
|
22503
|
+
});
|
|
22504
|
+
} catch (error) {
|
|
22505
|
+
if (error instanceof MissingCredentialsError && onboardingAllowed && !attempted) {
|
|
22506
|
+
attempted = true;
|
|
22507
|
+
const result = await runOnboarding(await buildOnboardingOptions(error.provider.id));
|
|
22508
|
+
if (result.outcome === "quit") {
|
|
22509
|
+
process.stdout.write("nothing was stored. run `earshot auth login <provider>` when you are ready.\n");
|
|
22510
|
+
await extensions.close();
|
|
22511
|
+
return 0;
|
|
22512
|
+
}
|
|
22513
|
+
firstPrompt = result.firstPrompt ?? firstPrompt;
|
|
22514
|
+
continue;
|
|
22515
|
+
}
|
|
22516
|
+
await extensions.close();
|
|
22517
|
+
if (error instanceof UnknownModelError) {
|
|
22518
|
+
process.stderr.write(`${error.message}
|
|
21644
22519
|
|
|
21645
22520
|
run \`earshot models\` to see what is available
|
|
21646
22521
|
`);
|
|
21647
|
-
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
|
|
22522
|
+
return 2;
|
|
22523
|
+
}
|
|
22524
|
+
if (error instanceof MissingCredentialsError) {
|
|
22525
|
+
process.stderr.write(`${error.message}
|
|
21651
22526
|
`);
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
22527
|
+
return 3;
|
|
22528
|
+
}
|
|
22529
|
+
if (error instanceof NoSessionToResumeError) {
|
|
22530
|
+
process.stderr.write(`${error.message}
|
|
21656
22531
|
`);
|
|
21657
|
-
|
|
22532
|
+
return 2;
|
|
22533
|
+
}
|
|
22534
|
+
throw error;
|
|
21658
22535
|
}
|
|
21659
|
-
throw error;
|
|
21660
22536
|
}
|
|
21661
22537
|
}
|
|
21662
22538
|
function resumeFrom2(flags) {
|
|
@@ -21843,5 +22719,5 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
21843
22719
|
var code = await main();
|
|
21844
22720
|
process.exitCode = code;
|
|
21845
22721
|
|
|
21846
|
-
//# debugId=
|
|
22722
|
+
//# debugId=B062C0361E20E53764756E2164756E21
|
|
21847
22723
|
//# sourceMappingURL=main.js.map
|