reasonix 0.30.3 → 0.30.5
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 +17 -0
- package/README.zh-CN.md +17 -0
- package/dist/cli/{chunk-COFBA5FV.js → chunk-VWFJNLIK.js} +50 -8
- package/dist/cli/chunk-VWFJNLIK.js.map +1 -0
- package/dist/cli/index.js +901 -642
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{prompt-VF7B6BWR.js → prompt-XHICFAYN.js} +2 -2
- package/dist/index.d.ts +28 -2
- package/dist/index.js +185 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-COFBA5FV.js.map +0 -1
- /package/dist/cli/{prompt-VF7B6BWR.js.map → prompt-XHICFAYN.js.map} +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
memoryEnabled,
|
|
13
13
|
readProjectMemory,
|
|
14
14
|
sanitizeMemoryName
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-VWFJNLIK.js";
|
|
16
16
|
|
|
17
17
|
// src/cli/index.ts
|
|
18
18
|
import { Command } from "commander";
|
|
@@ -858,6 +858,7 @@ var EN = {
|
|
|
858
858
|
statusBudget: " budget ${spent} / ${cap} ({pct}%){tag}",
|
|
859
859
|
statusSession: ' session "{name}" \xB7 {count} messages in log (resumed {resumed})',
|
|
860
860
|
statusSessionEphemeral: " session (ephemeral \u2014 no persistence)",
|
|
861
|
+
statusWorkspace: " workspace {path} \xB7 pinned at launch (relaunch with --dir <path> to switch)",
|
|
861
862
|
statusMcp: " mcp {servers} server(s), {tools} tool(s) in registry",
|
|
862
863
|
statusEdits: " edits {count} pending (/apply to commit, /discard to drop)",
|
|
863
864
|
statusPlan: " plan ON \u2014 writes gated (submit_plan + approval)",
|
|
@@ -951,11 +952,15 @@ var EN = {
|
|
|
951
952
|
listFrontmatter: "Each file's frontmatter needs at least `name` and `description`.",
|
|
952
953
|
listInvoke: "Invoke a skill with `/skill <name> [args]` or by asking the model to call `run_skill`.",
|
|
953
954
|
listHeader: "User skills ({count}):",
|
|
954
|
-
listFooter: "View
|
|
955
|
+
listFooter: "View: /skill show <name> Run: /skill <name> [args] New: /skill new <name>",
|
|
956
|
+
listEmptyNewHint: "Scaffold one with: /skill new <name> (project scope) \u2014 there's no remote registry yet; you author skills directly.",
|
|
955
957
|
showUsage: "usage: /skill show <name>",
|
|
956
958
|
showNotFound: "no skill found: {name}",
|
|
957
959
|
runNotFound: "no skill found: {name} (try /skill list)",
|
|
958
|
-
runInfo: "\u25B8 running skill: {name}{args}"
|
|
960
|
+
runInfo: "\u25B8 running skill: {name}{args}",
|
|
961
|
+
newUsage: "usage: /skill new <name> [--global]",
|
|
962
|
+
newCreated: "\u25B8 created skill: {name}\n {path}\n edit it, then `/skill {name}` to invoke",
|
|
963
|
+
newError: "\u25B2 /skill new failed: {reason}"
|
|
959
964
|
}
|
|
960
965
|
}
|
|
961
966
|
};
|
|
@@ -1545,6 +1550,7 @@ var zhCN = {
|
|
|
1545
1550
|
statusBudget: " \u9884\u7B97 ${spent} / ${cap}\uFF08{pct}%\uFF09{tag}",
|
|
1546
1551
|
statusSession: ' \u4F1A\u8BDD "{name}" \xB7 \u65E5\u5FD7\u4E2D {count} \u6761\u6D88\u606F\uFF08\u6062\u590D\u4E86 {resumed} \u6761\uFF09',
|
|
1547
1552
|
statusSessionEphemeral: " \u4F1A\u8BDD \uFF08\u4E34\u65F6 \u2014 \u65E0\u6301\u4E45\u5316\uFF09",
|
|
1553
|
+
statusWorkspace: " \u5DE5\u4F5C\u533A {path} \xB7 \u542F\u52A8\u65F6\u9501\u5B9A\uFF08\u7528 --dir <path> \u91CD\u65B0\u542F\u52A8\u4EE5\u5207\u6362\uFF09",
|
|
1548
1554
|
statusMcp: " MCP {servers} \u4E2A\u670D\u52A1\u5668\uFF0C\u6CE8\u518C\u8868\u4E2D {tools} \u4E2A\u5DE5\u5177",
|
|
1549
1555
|
statusEdits: " \u7F16\u8F91 {count} \u4E2A\u5F85\u5904\u7406\uFF08/apply \u63D0\u4EA4\uFF0C/discard \u4E22\u5F03\uFF09",
|
|
1550
1556
|
statusPlan: " \u8BA1\u5212 \u5F00\u542F \u2014 \u5199\u5165\u53D7\u9650\uFF08submit_plan + \u5BA1\u6279\uFF09",
|
|
@@ -1638,11 +1644,15 @@ var zhCN = {
|
|
|
1638
1644
|
listFrontmatter: "\u6BCF\u4E2A\u6587\u4EF6\u7684 frontmatter \u81F3\u5C11\u9700\u8981 `name` \u548C `description`\u3002",
|
|
1639
1645
|
listInvoke: "\u4F7F\u7528 `/skill <name> [args]` \u8C03\u7528\u6280\u80FD\uFF0C\u6216\u8BA9\u6A21\u578B\u8C03\u7528 `run_skill`\u3002",
|
|
1640
1646
|
listHeader: "\u7528\u6237\u6280\u80FD\uFF08{count}\uFF09\uFF1A",
|
|
1641
|
-
listFooter: "\u67E5\u770B\
|
|
1647
|
+
listFooter: "\u67E5\u770B\uFF1A/skill show <name> \u8FD0\u884C\uFF1A/skill <name> [args] \u65B0\u5EFA\uFF1A/skill new <name>",
|
|
1648
|
+
listEmptyNewHint: "\u7528 `/skill new <name>` \u5728\u9879\u76EE\u8303\u56F4\u4E0B\u751F\u6210\u4E00\u4E2A\u7A7A\u767D\u6A21\u677F \u2014 \u6682\u65E0\u5728\u7EBF\u5E02\u573A\uFF0C\u6280\u80FD\u9700\u8981\u81EA\u5DF1\u5199\u3002",
|
|
1642
1649
|
showUsage: "\u7528\u6CD5\uFF1A/skill show <name>",
|
|
1643
1650
|
showNotFound: "\u672A\u627E\u5230\u6280\u80FD\uFF1A{name}",
|
|
1644
1651
|
runNotFound: "\u672A\u627E\u5230\u6280\u80FD\uFF1A{name} \uFF08\u5C1D\u8BD5 /skill list\uFF09",
|
|
1645
|
-
runInfo: "\u25B8 \u6B63\u5728\u8FD0\u884C\u6280\u80FD\uFF1A{name}{args}"
|
|
1652
|
+
runInfo: "\u25B8 \u6B63\u5728\u8FD0\u884C\u6280\u80FD\uFF1A{name}{args}",
|
|
1653
|
+
newUsage: "\u7528\u6CD5\uFF1A/skill new <name> [--global]",
|
|
1654
|
+
newCreated: "\u25B8 \u5DF2\u521B\u5EFA\u6280\u80FD\uFF1A{name}\n {path}\n \u7F16\u8F91\u540E\u7528 `/skill {name}` \u8C03\u7528",
|
|
1655
|
+
newError: "\u25B2 /skill new \u5931\u8D25\uFF1A{reason}"
|
|
1646
1656
|
}
|
|
1647
1657
|
}
|
|
1648
1658
|
};
|
|
@@ -2577,7 +2587,7 @@ function encode(text) {
|
|
|
2577
2587
|
if (!text) return [];
|
|
2578
2588
|
const t3 = loadTokenizer();
|
|
2579
2589
|
const ids = [];
|
|
2580
|
-
const
|
|
2590
|
+
const process3 = (segment) => {
|
|
2581
2591
|
if (!segment) return;
|
|
2582
2592
|
let chunks = [segment];
|
|
2583
2593
|
for (const re of t3.splitRegexes) chunks = applySplit(chunks, re);
|
|
@@ -2596,14 +2606,14 @@ function encode(text) {
|
|
|
2596
2606
|
let last = 0;
|
|
2597
2607
|
for (const m of text.matchAll(t3.addedPattern)) {
|
|
2598
2608
|
const idx = m.index ?? 0;
|
|
2599
|
-
if (idx > last)
|
|
2609
|
+
if (idx > last) process3(text.slice(last, idx));
|
|
2600
2610
|
const id = t3.addedMap.get(m[0]);
|
|
2601
2611
|
if (id !== void 0) ids.push(id);
|
|
2602
2612
|
last = idx + m[0].length;
|
|
2603
2613
|
}
|
|
2604
|
-
if (last < text.length)
|
|
2614
|
+
if (last < text.length) process3(text.slice(last));
|
|
2605
2615
|
} else {
|
|
2606
|
-
|
|
2616
|
+
process3(text);
|
|
2607
2617
|
}
|
|
2608
2618
|
return ids;
|
|
2609
2619
|
}
|
|
@@ -3283,6 +3293,10 @@ var SessionStats = class {
|
|
|
3283
3293
|
_carryoverCost = 0;
|
|
3284
3294
|
/** Turn count from prior runs of a resumed session. */
|
|
3285
3295
|
_carryoverTurns = 0;
|
|
3296
|
+
_carryoverCacheHit = 0;
|
|
3297
|
+
_carryoverCacheMiss = 0;
|
|
3298
|
+
/** Last turn's promptTokens before exit — surfaced via summary() until the next live turn lands. */
|
|
3299
|
+
_carryoverLastPromptTokens = 0;
|
|
3286
3300
|
/** Seed totals from a resumed session's persisted meta — only call once at construction. */
|
|
3287
3301
|
seedCarryover(opts) {
|
|
3288
3302
|
if (typeof opts.totalCostUsd === "number" && opts.totalCostUsd > 0) {
|
|
@@ -3291,6 +3305,15 @@ var SessionStats = class {
|
|
|
3291
3305
|
if (typeof opts.turnCount === "number" && opts.turnCount > 0) {
|
|
3292
3306
|
this._carryoverTurns = opts.turnCount;
|
|
3293
3307
|
}
|
|
3308
|
+
if (typeof opts.cacheHitTokens === "number" && opts.cacheHitTokens > 0) {
|
|
3309
|
+
this._carryoverCacheHit = opts.cacheHitTokens;
|
|
3310
|
+
}
|
|
3311
|
+
if (typeof opts.cacheMissTokens === "number" && opts.cacheMissTokens > 0) {
|
|
3312
|
+
this._carryoverCacheMiss = opts.cacheMissTokens;
|
|
3313
|
+
}
|
|
3314
|
+
if (typeof opts.lastPromptTokens === "number" && opts.lastPromptTokens > 0) {
|
|
3315
|
+
this._carryoverLastPromptTokens = opts.lastPromptTokens;
|
|
3316
|
+
}
|
|
3294
3317
|
}
|
|
3295
3318
|
record(turn, model2, usage) {
|
|
3296
3319
|
const cost2 = costUsd(model2, usage);
|
|
@@ -3321,8 +3344,8 @@ var SessionStats = class {
|
|
|
3321
3344
|
return this.turns.reduce((sum, t3) => sum + outputCostUsd(t3.model, t3.usage), 0);
|
|
3322
3345
|
}
|
|
3323
3346
|
get aggregateCacheHitRatio() {
|
|
3324
|
-
let hit =
|
|
3325
|
-
let miss =
|
|
3347
|
+
let hit = this._carryoverCacheHit;
|
|
3348
|
+
let miss = this._carryoverCacheMiss;
|
|
3326
3349
|
for (const t3 of this.turns) {
|
|
3327
3350
|
hit += t3.usage.promptCacheHitTokens;
|
|
3328
3351
|
miss += t3.usage.promptCacheMissTokens;
|
|
@@ -3340,7 +3363,7 @@ var SessionStats = class {
|
|
|
3340
3363
|
claudeEquivalentUsd: round(this.totalClaudeEquivalent, 6),
|
|
3341
3364
|
savingsVsClaudePct: round(this.savingsVsClaude * 100, 2),
|
|
3342
3365
|
cacheHitRatio: round(this.aggregateCacheHitRatio, 4),
|
|
3343
|
-
lastPromptTokens: last?.usage.promptTokens ??
|
|
3366
|
+
lastPromptTokens: last?.usage.promptTokens ?? this._carryoverLastPromptTokens,
|
|
3344
3367
|
lastTurnCostUsd: round(last?.cost ?? 0, 6)
|
|
3345
3368
|
};
|
|
3346
3369
|
}
|
|
@@ -4072,15 +4095,18 @@ var StormBreaker = class {
|
|
|
4072
4095
|
windowSize;
|
|
4073
4096
|
threshold;
|
|
4074
4097
|
isMutating;
|
|
4098
|
+
isStormExempt;
|
|
4075
4099
|
recent = [];
|
|
4076
|
-
constructor(windowSize = 6, threshold = 3, isMutating) {
|
|
4100
|
+
constructor(windowSize = 6, threshold = 3, isMutating, isStormExempt) {
|
|
4077
4101
|
this.windowSize = windowSize;
|
|
4078
4102
|
this.threshold = threshold;
|
|
4079
4103
|
this.isMutating = isMutating;
|
|
4104
|
+
this.isStormExempt = isStormExempt;
|
|
4080
4105
|
}
|
|
4081
4106
|
inspect(call) {
|
|
4082
4107
|
const name = call.function?.name;
|
|
4083
4108
|
if (!name) return { suppress: false };
|
|
4109
|
+
if (this.isStormExempt?.(call)) return { suppress: false };
|
|
4084
4110
|
const args = call.function?.arguments ?? "";
|
|
4085
4111
|
const mutating = this.isMutating ? this.isMutating(call) : false;
|
|
4086
4112
|
const readOnly = !mutating;
|
|
@@ -4181,7 +4207,12 @@ var ToolCallRepair = class {
|
|
|
4181
4207
|
opts;
|
|
4182
4208
|
constructor(opts) {
|
|
4183
4209
|
this.opts = opts;
|
|
4184
|
-
this.storm = new StormBreaker(
|
|
4210
|
+
this.storm = new StormBreaker(
|
|
4211
|
+
opts.stormWindow ?? 6,
|
|
4212
|
+
opts.stormThreshold ?? 3,
|
|
4213
|
+
opts.isMutating,
|
|
4214
|
+
opts.isStormExempt
|
|
4215
|
+
);
|
|
4185
4216
|
}
|
|
4186
4217
|
/** Called at start of every user turn — fresh intent shouldn't inherit old repetition state. */
|
|
4187
4218
|
resetStorm() {
|
|
@@ -4324,9 +4355,15 @@ var CacheFirstLoop = class {
|
|
|
4324
4355
|
}
|
|
4325
4356
|
return def2.readOnly !== true;
|
|
4326
4357
|
};
|
|
4358
|
+
const isStormExempt = (call) => {
|
|
4359
|
+
const name = call.function?.name;
|
|
4360
|
+
if (!name) return false;
|
|
4361
|
+
return registry.get(name)?.stormExempt === true;
|
|
4362
|
+
};
|
|
4327
4363
|
this.repair = new ToolCallRepair({
|
|
4328
4364
|
allowedToolNames: allowedNames,
|
|
4329
4365
|
isMutating,
|
|
4366
|
+
isStormExempt,
|
|
4330
4367
|
stormThreshold: parsePositiveIntEnv(process.env.REASONIX_STORM_THRESHOLD),
|
|
4331
4368
|
stormWindow: parsePositiveIntEnv(process.env.REASONIX_STORM_WINDOW)
|
|
4332
4369
|
});
|
|
@@ -4344,7 +4381,10 @@ var CacheFirstLoop = class {
|
|
|
4344
4381
|
const meta = loadSessionMeta(this.sessionName);
|
|
4345
4382
|
this.stats.seedCarryover({
|
|
4346
4383
|
totalCostUsd: meta.totalCostUsd,
|
|
4347
|
-
turnCount: meta.turnCount
|
|
4384
|
+
turnCount: meta.turnCount,
|
|
4385
|
+
cacheHitTokens: meta.cacheHitTokens,
|
|
4386
|
+
cacheMissTokens: meta.cacheMissTokens,
|
|
4387
|
+
lastPromptTokens: meta.lastPromptTokens
|
|
4348
4388
|
});
|
|
4349
4389
|
}
|
|
4350
4390
|
if (healedCount > 0) {
|
|
@@ -5701,7 +5741,9 @@ function registerFilesystemTools(registry, opts) {
|
|
|
5701
5741
|
const normRoot = pathMod3.resolve(rootDir);
|
|
5702
5742
|
const rel = pathMod3.relative(normRoot, resolved);
|
|
5703
5743
|
if (rel.startsWith("..") || pathMod3.isAbsolute(rel)) {
|
|
5704
|
-
throw new Error(
|
|
5744
|
+
throw new Error(
|
|
5745
|
+
`path escapes sandbox root (${normRoot}): ${raw} \u2014 workspace is pinned at launch; quit and relaunch with \`reasonix code --dir <path>\` to work in a different folder`
|
|
5746
|
+
);
|
|
5705
5747
|
}
|
|
5706
5748
|
return resolved;
|
|
5707
5749
|
};
|
|
@@ -5714,6 +5756,7 @@ function registerFilesystemTools(registry, opts) {
|
|
|
5714
5756
|
- range: "A-B" \u2192 inclusive line range A..B, 1-indexed (e.g. "120-180" around an edit site)
|
|
5715
5757
|
When none of these is given AND the file is longer than ${DEFAULT_AUTO_PREVIEW_LINES} lines, the tool auto-returns a head+tail preview with an "N lines omitted" marker rather than dumping everything. If you need the middle, re-call with a range. Prefer search_content to locate a symbol first, then read_file with a range around the hit \u2014 one scoped read beats three full-file reads.`,
|
|
5716
5758
|
readOnly: true,
|
|
5759
|
+
stormExempt: true,
|
|
5717
5760
|
parameters: {
|
|
5718
5761
|
type: "object",
|
|
5719
5762
|
properties: {
|
|
@@ -5794,6 +5837,7 @@ ${slice.join("\n")}`;
|
|
|
5794
5837
|
parallelSafe: true,
|
|
5795
5838
|
description: "List entries in a directory under the sandbox root. Returns one line per entry, marking directories with a trailing slash. Not recursive \u2014 use directory_tree for that.",
|
|
5796
5839
|
readOnly: true,
|
|
5840
|
+
stormExempt: true,
|
|
5797
5841
|
parameters: {
|
|
5798
5842
|
type: "object",
|
|
5799
5843
|
properties: {
|
|
@@ -6839,7 +6883,8 @@ var JobRegistry = class {
|
|
|
6839
6883
|
},
|
|
6840
6884
|
closedPromise: Promise.resolve(),
|
|
6841
6885
|
signalClosed: () => {
|
|
6842
|
-
}
|
|
6886
|
+
},
|
|
6887
|
+
outputWaiters: /* @__PURE__ */ new Set()
|
|
6843
6888
|
};
|
|
6844
6889
|
this.jobs.set(id2, job2);
|
|
6845
6890
|
return {
|
|
@@ -6875,7 +6920,8 @@ var JobRegistry = class {
|
|
|
6875
6920
|
readyPromise,
|
|
6876
6921
|
signalReady: readyResolve,
|
|
6877
6922
|
closedPromise,
|
|
6878
|
-
signalClosed: closedResolve
|
|
6923
|
+
signalClosed: closedResolve,
|
|
6924
|
+
outputWaiters: /* @__PURE__ */ new Set()
|
|
6879
6925
|
};
|
|
6880
6926
|
this.jobs.set(id, job);
|
|
6881
6927
|
let readyMatched = false;
|
|
@@ -6902,6 +6948,11 @@ ${job.output.slice(start)}`;
|
|
|
6902
6948
|
}
|
|
6903
6949
|
}
|
|
6904
6950
|
}
|
|
6951
|
+
if (job.outputWaiters.size > 0) {
|
|
6952
|
+
const waiters = [...job.outputWaiters];
|
|
6953
|
+
job.outputWaiters.clear();
|
|
6954
|
+
for (const wake of waiters) wake();
|
|
6955
|
+
}
|
|
6905
6956
|
};
|
|
6906
6957
|
child.stdout?.on("data", onData);
|
|
6907
6958
|
child.stderr?.on("data", onData);
|
|
@@ -6963,6 +7014,39 @@ ${job.output.slice(start)}`;
|
|
|
6963
7014
|
spawnError: job.spawnError
|
|
6964
7015
|
};
|
|
6965
7016
|
}
|
|
7017
|
+
async waitForJob(id, opts = {}) {
|
|
7018
|
+
const job = this.jobs.get(id);
|
|
7019
|
+
if (!job) return null;
|
|
7020
|
+
if (!job.running) {
|
|
7021
|
+
return {
|
|
7022
|
+
exited: true,
|
|
7023
|
+
exitCode: job.exitCode,
|
|
7024
|
+
latestOutput: job.output
|
|
7025
|
+
};
|
|
7026
|
+
}
|
|
7027
|
+
const timeoutMs = Math.max(0, Math.min(3e4, opts.timeoutMs ?? 5e3));
|
|
7028
|
+
const startOutput = job.output;
|
|
7029
|
+
let wakeOutput = null;
|
|
7030
|
+
const outputPromise = new Promise((resolve12) => {
|
|
7031
|
+
wakeOutput = resolve12;
|
|
7032
|
+
job.outputWaiters.add(resolve12);
|
|
7033
|
+
});
|
|
7034
|
+
let timer = null;
|
|
7035
|
+
await Promise.race([
|
|
7036
|
+
job.closedPromise,
|
|
7037
|
+
outputPromise,
|
|
7038
|
+
new Promise((resolve12) => {
|
|
7039
|
+
timer = setTimeout(resolve12, timeoutMs);
|
|
7040
|
+
})
|
|
7041
|
+
]);
|
|
7042
|
+
if (timer) clearTimeout(timer);
|
|
7043
|
+
if (wakeOutput) job.outputWaiters.delete(wakeOutput);
|
|
7044
|
+
return {
|
|
7045
|
+
exited: !job.running,
|
|
7046
|
+
exitCode: job.exitCode,
|
|
7047
|
+
latestOutput: latestOutputSince(startOutput, job.output)
|
|
7048
|
+
};
|
|
7049
|
+
}
|
|
6966
7050
|
/** SIGTERM, wait graceMs, then SIGKILL. Idempotent on already-exited jobs. */
|
|
6967
7051
|
async stop(id, opts = {}) {
|
|
6968
7052
|
const job = this.jobs.get(id);
|
|
@@ -7042,6 +7126,11 @@ function snapshot(job) {
|
|
|
7042
7126
|
spawnError: job.spawnError
|
|
7043
7127
|
};
|
|
7044
7128
|
}
|
|
7129
|
+
function latestOutputSince(before, after) {
|
|
7130
|
+
if (!before) return after;
|
|
7131
|
+
if (after.startsWith(before)) return after.slice(before.length);
|
|
7132
|
+
return after;
|
|
7133
|
+
}
|
|
7045
7134
|
|
|
7046
7135
|
// src/tools/shell/exec.ts
|
|
7047
7136
|
import { spawn as spawn4, spawnSync } from "child_process";
|
|
@@ -8011,6 +8100,7 @@ function registerShellTools(registry, opts) {
|
|
|
8011
8100
|
description: "Read the latest output of a background job started with `run_background`. By default returns the tail of the buffer (last 80 lines). Pass `since` (the `byteLength` from a previous call) to stream only new content incrementally. Tells you whether the job is still running, so you can stop polling when it's done.",
|
|
8012
8101
|
readOnly: true,
|
|
8013
8102
|
parallelSafe: true,
|
|
8103
|
+
stormExempt: true,
|
|
8014
8104
|
parameters: {
|
|
8015
8105
|
type: "object",
|
|
8016
8106
|
properties: {
|
|
@@ -8035,6 +8125,32 @@ function registerShellTools(registry, opts) {
|
|
|
8035
8125
|
return formatJobRead(args.jobId, out);
|
|
8036
8126
|
}
|
|
8037
8127
|
});
|
|
8128
|
+
registry.register({
|
|
8129
|
+
name: "wait_for_job",
|
|
8130
|
+
description: "Block until a background job exits or produces new output, bounded by `timeoutMs`. Use this instead of polling `job_output` with identical args when you're intentionally waiting for state to change. Returns JSON with `exited`, `exitCode`, and `latestOutput`.",
|
|
8131
|
+
readOnly: true,
|
|
8132
|
+
parameters: {
|
|
8133
|
+
type: "object",
|
|
8134
|
+
properties: {
|
|
8135
|
+
jobId: { type: "integer", description: "Job id returned by run_background." },
|
|
8136
|
+
timeoutMs: {
|
|
8137
|
+
type: "integer",
|
|
8138
|
+
description: "Max time to block before returning if nothing changes. Clamped to 0..30000. Default 5000."
|
|
8139
|
+
}
|
|
8140
|
+
},
|
|
8141
|
+
required: ["jobId"]
|
|
8142
|
+
},
|
|
8143
|
+
fn: async (args) => {
|
|
8144
|
+
const out = await jobs2.waitForJob(args.jobId, { timeoutMs: args.timeoutMs });
|
|
8145
|
+
if (!out) return `job ${args.jobId}: not found (use list_jobs)`;
|
|
8146
|
+
return {
|
|
8147
|
+
jobId: args.jobId,
|
|
8148
|
+
exited: out.exited,
|
|
8149
|
+
exitCode: out.exitCode,
|
|
8150
|
+
latestOutput: out.latestOutput
|
|
8151
|
+
};
|
|
8152
|
+
}
|
|
8153
|
+
});
|
|
8038
8154
|
registry.register({
|
|
8039
8155
|
name: "stop_job",
|
|
8040
8156
|
description: "Stop a background job started with `run_background`. SIGTERM first; SIGKILL after a short grace period if it doesn't exit cleanly. Returns the final output + exit code. Safe to call on an already-exited job.",
|
|
@@ -8056,6 +8172,7 @@ function registerShellTools(registry, opts) {
|
|
|
8056
8172
|
description: "List every background job started this session \u2014 running and exited \u2014 with id, command, pid, status. Use when you've lost track of which job_id corresponds to which process, or to see what's still alive.",
|
|
8057
8173
|
readOnly: true,
|
|
8058
8174
|
parallelSafe: true,
|
|
8175
|
+
stormExempt: true,
|
|
8059
8176
|
parameters: { type: "object", properties: {} },
|
|
8060
8177
|
fn: async () => {
|
|
8061
8178
|
const all = jobs2.list();
|
|
@@ -10267,7 +10384,7 @@ function formatLogSize(path6 = defaultUsageLogPath()) {
|
|
|
10267
10384
|
|
|
10268
10385
|
// src/cli/commands/chat.tsx
|
|
10269
10386
|
import { render } from "ink";
|
|
10270
|
-
import
|
|
10387
|
+
import React65, { useState as useState22 } from "react";
|
|
10271
10388
|
|
|
10272
10389
|
// src/mcp/preflight.ts
|
|
10273
10390
|
import { statSync as statSync5 } from "fs";
|
|
@@ -10310,8 +10427,8 @@ function buildMcpServerSummary(opts) {
|
|
|
10310
10427
|
}
|
|
10311
10428
|
|
|
10312
10429
|
// src/cli/ui/App.tsx
|
|
10313
|
-
import { Box as
|
|
10314
|
-
import
|
|
10430
|
+
import { Box as Box49, Text as Text53, useStdout as useStdout15 } from "ink";
|
|
10431
|
+
import React62, { useCallback as useCallback11, useEffect as useEffect12, useMemo as useMemo7, useRef as useRef9, useState as useState20 } from "react";
|
|
10315
10432
|
|
|
10316
10433
|
// src/adapters/event-sink-jsonl.ts
|
|
10317
10434
|
import { chmodSync as chmodSync3, createWriteStream as createWriteStream2, mkdirSync as mkdirSync6 } from "fs";
|
|
@@ -14551,8 +14668,8 @@ var SLASH_COMMANDS = [
|
|
|
14551
14668
|
},
|
|
14552
14669
|
{
|
|
14553
14670
|
cmd: "skill",
|
|
14554
|
-
argsHint: "[list|show <name>|<name> [args]]",
|
|
14555
|
-
summary: "list / run user skills (<project>/.reasonix/skills + ~/.reasonix/skills)"
|
|
14671
|
+
argsHint: "[list|show <name>|new <name>|<name> [args]]",
|
|
14672
|
+
summary: "list / run / scaffold user skills (<project>/.reasonix/skills + ~/.reasonix/skills)"
|
|
14556
14673
|
},
|
|
14557
14674
|
{
|
|
14558
14675
|
cmd: "hooks",
|
|
@@ -15346,17 +15463,23 @@ var CSI_TAIL_MAP = [
|
|
|
15346
15463
|
{ tail: "6~", ev: { input: "", pageDown: true } },
|
|
15347
15464
|
{ tail: "3~", ev: { input: "", delete: true } },
|
|
15348
15465
|
{ tail: "Z", ev: { input: "", shift: true, tab: true } },
|
|
15349
|
-
//
|
|
15350
|
-
//
|
|
15466
|
+
// Some Windows hosts (PowerShell 7.x conhost path) emit the
|
|
15467
|
+
// modifier-encoded back-tab `\x1b[1;2Z` instead of bare `\x1b[Z`.
|
|
15468
|
+
// Issue #373 — without this entry Shift+Tab is silently dropped.
|
|
15469
|
+
{ tail: "1;2Z", ev: { input: "", shift: true, tab: true } },
|
|
15470
|
+
// modifyOtherKeys (xterm CSI > 4 ; 2 m) sequences for Enter / Tab
|
|
15471
|
+
// with modifiers. Only fired when App.tsx has enabled the mode at
|
|
15351
15472
|
// startup; otherwise Shift+Enter stays indistinguishable from Enter.
|
|
15352
15473
|
// Modifier encoding: 2=shift, 3=alt, 4=alt+shift, 5=ctrl,
|
|
15353
|
-
// 6=ctrl+shift, 7=ctrl+alt, 8=ctrl+alt+shift.
|
|
15474
|
+
// 6=ctrl+shift, 7=ctrl+alt, 8=ctrl+alt+shift. Keycodes: 9=Tab, 13=Enter.
|
|
15475
|
+
{ tail: "27;2;9~", ev: { input: "", tab: true, shift: true } },
|
|
15354
15476
|
{ tail: "27;2;13~", ev: { input: "", return: true, shift: true } },
|
|
15355
15477
|
{ tail: "27;5;13~", ev: { input: "", return: true, ctrl: true } },
|
|
15356
15478
|
{ tail: "27;6;13~", ev: { input: "", return: true, ctrl: true, shift: true } },
|
|
15357
15479
|
// Kitty keyboard protocol — same idea, different envelope:
|
|
15358
15480
|
// `\x1b[<keycode>;<mod>u`. Some terminals (kitty, recent Windows
|
|
15359
15481
|
// Terminal previews) prefer this shape. Harmless to map here too.
|
|
15482
|
+
{ tail: "9;2u", ev: { input: "", tab: true, shift: true } },
|
|
15360
15483
|
{ tail: "13;2u", ev: { input: "", return: true, shift: true } },
|
|
15361
15484
|
{ tail: "13;5u", ev: { input: "", return: true, ctrl: true } },
|
|
15362
15485
|
{ tail: "13;6u", ev: { input: "", return: true, ctrl: true, shift: true } }
|
|
@@ -16984,17 +17107,108 @@ function TabPill({ label, count, active }) {
|
|
|
16984
17107
|
return /* @__PURE__ */ React12.createElement(Text9, { dimColor: true }, ` ${text} `);
|
|
16985
17108
|
}
|
|
16986
17109
|
|
|
17110
|
+
// src/cli/ui/ModelPicker.tsx
|
|
17111
|
+
import { Box as Box10, Text as Text11, useStdout as useStdout4 } from "ink";
|
|
17112
|
+
import React14, { useState as useState7 } from "react";
|
|
17113
|
+
|
|
17114
|
+
// src/cli/ui/primitives/Pill.tsx
|
|
17115
|
+
import { Text as Text10 } from "ink";
|
|
17116
|
+
import React13 from "react";
|
|
17117
|
+
function Pill({ label, bg, fg, bold = true }) {
|
|
17118
|
+
return /* @__PURE__ */ React13.createElement(Text10, { backgroundColor: bg, color: fg, bold }, ` ${label} `);
|
|
17119
|
+
}
|
|
17120
|
+
var PILL_SECTION = {
|
|
17121
|
+
reason: { bg: "#2a1f3d", fg: "#d2a8ff" },
|
|
17122
|
+
output: { bg: "#0d1d2e", fg: "#79c0ff" },
|
|
17123
|
+
tool: { bg: "#0f2230", fg: "#79c0ff" },
|
|
17124
|
+
shell: { bg: "#0f2230", fg: "#79c0ff" },
|
|
17125
|
+
task: { bg: "#0d1d2e", fg: "#79c0ff" },
|
|
17126
|
+
taskDone: { bg: "#102815", fg: "#7ee787" },
|
|
17127
|
+
taskFailed: { bg: "#2c1416", fg: "#ff8b81" },
|
|
17128
|
+
plan: { bg: "#2a1f3d", fg: "#d2a8ff" },
|
|
17129
|
+
user: { bg: "#11141a", fg: "#8b949e" }
|
|
17130
|
+
};
|
|
17131
|
+
var PILL_MODEL = {
|
|
17132
|
+
flash: { bg: "#11141a", fg: "#79c0ff" },
|
|
17133
|
+
pro: { bg: "#11141a", fg: "#d2a8ff" },
|
|
17134
|
+
r1: { bg: "#11141a", fg: "#b395f5" },
|
|
17135
|
+
unknown: { bg: "#11141a", fg: "#8b949e" }
|
|
17136
|
+
};
|
|
17137
|
+
function modelBadgeFor(model2) {
|
|
17138
|
+
if (!model2) return { label: "?", kind: "unknown" };
|
|
17139
|
+
const stripped = model2.replace(/^deepseek-/, "");
|
|
17140
|
+
if (stripped === "v4-flash" || stripped === "chat") return { label: "v4-flash", kind: "flash" };
|
|
17141
|
+
if (stripped === "v4-pro") return { label: "v4-pro", kind: "pro" };
|
|
17142
|
+
if (stripped === "r1" || stripped === "reasoner") return { label: "r1", kind: "r1" };
|
|
17143
|
+
return { label: stripped, kind: "unknown" };
|
|
17144
|
+
}
|
|
17145
|
+
|
|
17146
|
+
// src/cli/ui/ModelPicker.tsx
|
|
17147
|
+
var PAGE_MARGIN = 6;
|
|
17148
|
+
function ModelPicker({
|
|
17149
|
+
models: models2,
|
|
17150
|
+
current,
|
|
17151
|
+
onChoose,
|
|
17152
|
+
onRefresh
|
|
17153
|
+
}) {
|
|
17154
|
+
const list2 = (models2 && models2.length > 0 ? models2 : FALLBACK_MODELS).slice();
|
|
17155
|
+
if (!list2.includes(current)) list2.unshift(current);
|
|
17156
|
+
const initialIndex = Math.max(0, list2.indexOf(current));
|
|
17157
|
+
const [focus, setFocus] = useState7(initialIndex);
|
|
17158
|
+
const { stdout: stdout4 } = useStdout4();
|
|
17159
|
+
const rows = stdout4?.rows ?? 40;
|
|
17160
|
+
const visibleCount = Math.max(3, rows - PAGE_MARGIN);
|
|
17161
|
+
useKeystroke((ev) => {
|
|
17162
|
+
if (ev.escape) return onChoose({ kind: "quit" });
|
|
17163
|
+
if (ev.upArrow) return setFocus((f) => Math.max(0, f - 1));
|
|
17164
|
+
if (ev.downArrow) return setFocus((f) => Math.min(list2.length - 1, f + 1));
|
|
17165
|
+
if (ev.return) {
|
|
17166
|
+
const target = list2[focus];
|
|
17167
|
+
if (target) onChoose({ kind: "select", id: target });
|
|
17168
|
+
return;
|
|
17169
|
+
}
|
|
17170
|
+
if (!ev.input) return;
|
|
17171
|
+
if (ev.input === "q") return onChoose({ kind: "quit" });
|
|
17172
|
+
if (ev.input === "r") onRefresh?.();
|
|
17173
|
+
});
|
|
17174
|
+
const start = Math.max(
|
|
17175
|
+
0,
|
|
17176
|
+
Math.min(focus - Math.floor(visibleCount / 2), list2.length - visibleCount)
|
|
17177
|
+
);
|
|
17178
|
+
const end = Math.min(list2.length, start + visibleCount);
|
|
17179
|
+
const shown = list2.slice(start, end);
|
|
17180
|
+
const hiddenAbove = start;
|
|
17181
|
+
const hiddenBelow = list2.length - end;
|
|
17182
|
+
const loading = models2 === null;
|
|
17183
|
+
const empty = models2 !== null && models2.length === 0;
|
|
17184
|
+
return /* @__PURE__ */ React14.createElement(Box10, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React14.createElement(Box10, null, /* @__PURE__ */ React14.createElement(Text11, { bold: true, color: TONE.brand }, " \u25C8 REASONIX \xB7 pick a model "), /* @__PURE__ */ React14.createElement(Text11, { color: FG.meta }, loading ? " \xB7 loading catalog\u2026" : empty ? " \xB7 catalog empty \u2014 using known fallbacks" : ` \xB7 ${list2.length} available`)), /* @__PURE__ */ React14.createElement(Box10, { height: 1 }), hiddenAbove > 0 ? /* @__PURE__ */ React14.createElement(Box10, null, /* @__PURE__ */ React14.createElement(Text11, { color: FG.faint }, ` \u2026 ${hiddenAbove} earlier`)) : null, shown.map((id, i) => /* @__PURE__ */ React14.createElement(ModelRow, { key: id, id, focused: start + i === focus, active: id === current })), hiddenBelow > 0 ? /* @__PURE__ */ React14.createElement(Box10, null, /* @__PURE__ */ React14.createElement(Text11, { color: FG.faint }, ` \u2026 ${hiddenBelow} more`)) : null, /* @__PURE__ */ React14.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text11, { color: FG.faint }, " \u2191\u2193 pick \xB7 \u23CE confirm \xB7 [r] refresh \xB7 esc cancel")));
|
|
17185
|
+
}
|
|
17186
|
+
function ModelRow({
|
|
17187
|
+
id,
|
|
17188
|
+
focused,
|
|
17189
|
+
active
|
|
17190
|
+
}) {
|
|
17191
|
+
const badge2 = modelBadgeFor(id);
|
|
17192
|
+
return /* @__PURE__ */ React14.createElement(Box10, null, /* @__PURE__ */ React14.createElement(Text11, { color: focused ? TONE.brand : FG.faint }, focused ? " \u25B8 " : " "), /* @__PURE__ */ React14.createElement(Text11, { bold: focused, color: focused ? FG.strong : FG.sub }, id.padEnd(24)), /* @__PURE__ */ React14.createElement(Text11, null, " "), /* @__PURE__ */ React14.createElement(Pill, { label: badge2.label, ...PILL_MODEL[badge2.kind], bold: false }), active ? /* @__PURE__ */ React14.createElement(Text11, { color: TONE.brand }, " \xB7 current") : null);
|
|
17193
|
+
}
|
|
17194
|
+
var FALLBACK_MODELS = [
|
|
17195
|
+
"deepseek-v4-flash",
|
|
17196
|
+
"deepseek-v4-pro",
|
|
17197
|
+
"deepseek-chat",
|
|
17198
|
+
"deepseek-reasoner"
|
|
17199
|
+
];
|
|
17200
|
+
|
|
16987
17201
|
// src/cli/ui/PlanCheckpointConfirm.tsx
|
|
16988
|
-
import { Box as
|
|
16989
|
-
import
|
|
17202
|
+
import { Box as Box13 } from "ink";
|
|
17203
|
+
import React17 from "react";
|
|
16990
17204
|
|
|
16991
17205
|
// src/cli/ui/PlanStepList.tsx
|
|
16992
|
-
import { Box as
|
|
16993
|
-
import
|
|
17206
|
+
import { Box as Box12, Text as Text13 } from "ink";
|
|
17207
|
+
import React16 from "react";
|
|
16994
17208
|
|
|
16995
17209
|
// src/cli/ui/char-bar.tsx
|
|
16996
|
-
import { Box as
|
|
16997
|
-
import
|
|
17210
|
+
import { Box as Box11, Text as Text12 } from "ink";
|
|
17211
|
+
import React15 from "react";
|
|
16998
17212
|
function CharBar({
|
|
16999
17213
|
pct: pct2,
|
|
17000
17214
|
width = 24,
|
|
@@ -17006,7 +17220,7 @@ function CharBar({
|
|
|
17006
17220
|
const total = Math.max(4, width);
|
|
17007
17221
|
const clamped = Math.max(0, Math.min(100, Number.isFinite(pct2) ? pct2 : 0));
|
|
17008
17222
|
const filled = Math.round(total * clamped / 100);
|
|
17009
|
-
return /* @__PURE__ */
|
|
17223
|
+
return /* @__PURE__ */ React15.createElement(Box11, null, /* @__PURE__ */ React15.createElement(Text12, { color: color2 }, GLYPH.block.repeat(filled)), /* @__PURE__ */ React15.createElement(Text12, { color: emptyColor ?? COLOR.info, dimColor: true }, GLYPH.shade1.repeat(total - filled)), showLabel ? /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, ` ${label ?? `${Math.round(clamped)}%`}`) : null);
|
|
17010
17224
|
}
|
|
17011
17225
|
|
|
17012
17226
|
// src/cli/ui/PlanStepList.tsx
|
|
@@ -17036,25 +17250,25 @@ function PlanStepListInner({ steps, statuses, focusStepId }) {
|
|
|
17036
17250
|
const doneCount = statusList.filter((s) => s === "done").length;
|
|
17037
17251
|
const pct2 = Math.round(doneCount / total * 100);
|
|
17038
17252
|
const showProgress = doneCount > 0;
|
|
17039
|
-
return /* @__PURE__ */
|
|
17253
|
+
return /* @__PURE__ */ React16.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Box12, null, /* @__PURE__ */ React16.createElement(Text13, { dimColor: true }, showProgress ? `${doneCount}/${total} done (${pct2}%) \xB7 ${total} step${total === 1 ? "" : "s"}` : `${total} step${total === 1 ? "" : "s"}`)), /* @__PURE__ */ React16.createElement(Box12, { flexDirection: "column" }, steps.map((step, i) => {
|
|
17040
17254
|
const status3 = statusList[i];
|
|
17041
17255
|
const isLast = i === total - 1;
|
|
17042
17256
|
const isCur = focusStepId === step.id;
|
|
17043
17257
|
const sg = statusGlyph(status3, isCur);
|
|
17044
17258
|
const risk = riskLabel(step.risk);
|
|
17045
17259
|
const titleDim = status3 === "done" || status3 === "skipped";
|
|
17046
|
-
return /* @__PURE__ */
|
|
17047
|
-
|
|
17260
|
+
return /* @__PURE__ */ React16.createElement(Box12, { key: step.id }, /* @__PURE__ */ React16.createElement(Text13, { color: COLOR.info, dimColor: true }, isLast ? GLYPH.branchEnd : GLYPH.branch), /* @__PURE__ */ React16.createElement(Text13, null, " "), /* @__PURE__ */ React16.createElement(Text13, { color: sg.color, bold: status3 === "running" || isCur }, sg.glyph), /* @__PURE__ */ React16.createElement(Text13, null, " "), /* @__PURE__ */ React16.createElement(
|
|
17261
|
+
Text13,
|
|
17048
17262
|
{
|
|
17049
17263
|
dimColor: titleDim,
|
|
17050
17264
|
bold: isCur || status3 === "running",
|
|
17051
17265
|
strikethrough: status3 === "done" || status3 === "skipped"
|
|
17052
17266
|
},
|
|
17053
17267
|
`${step.id} \xB7 ${step.title}`
|
|
17054
|
-
), risk ? /* @__PURE__ */
|
|
17055
|
-
})), showProgress ? /* @__PURE__ */
|
|
17268
|
+
), risk ? /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Text13, null, " "), /* @__PURE__ */ React16.createElement(Text13, { color: risk.color }, risk.text)) : null);
|
|
17269
|
+
})), showProgress ? /* @__PURE__ */ React16.createElement(Box12, null, /* @__PURE__ */ React16.createElement(Text13, null, " "), /* @__PURE__ */ React16.createElement(CharBar, { pct: pct2, width: 24 })) : null);
|
|
17056
17270
|
}
|
|
17057
|
-
var PlanStepList =
|
|
17271
|
+
var PlanStepList = React16.memo(PlanStepListInner);
|
|
17058
17272
|
|
|
17059
17273
|
// src/cli/ui/PlanCheckpointConfirm.tsx
|
|
17060
17274
|
function PlanCheckpointConfirmInner({
|
|
@@ -17073,7 +17287,7 @@ function PlanCheckpointConfirmInner({
|
|
|
17073
17287
|
const isLast = total > 0 && completed >= total;
|
|
17074
17288
|
const statuses = buildStatusMap(steps, completedStepIds, stepId, isLast);
|
|
17075
17289
|
const subtitle = counter ? `${counter} \xB7 ${label}` : label;
|
|
17076
|
-
return /* @__PURE__ */
|
|
17290
|
+
return /* @__PURE__ */ React17.createElement(ApprovalCard, { tone: "ok", glyph: "\u26C1", title: "Checkpoint \u2014 step done", metaRight: subtitle }, steps && steps.length > 0 ? /* @__PURE__ */ React17.createElement(Box13, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(PlanStepList, { steps, statuses, focusStepId: stepId })) : null, /* @__PURE__ */ React17.createElement(
|
|
17077
17291
|
SingleSelect,
|
|
17078
17292
|
{
|
|
17079
17293
|
initialValue: isLast ? "stop" : "continue",
|
|
@@ -17099,7 +17313,7 @@ function PlanCheckpointConfirmInner({
|
|
|
17099
17313
|
}
|
|
17100
17314
|
));
|
|
17101
17315
|
}
|
|
17102
|
-
var PlanCheckpointConfirm =
|
|
17316
|
+
var PlanCheckpointConfirm = React17.memo(PlanCheckpointConfirmInner);
|
|
17103
17317
|
function buildStatusMap(steps, completedStepIds, currentStepId, isLast) {
|
|
17104
17318
|
const map = /* @__PURE__ */ new Map();
|
|
17105
17319
|
if (!steps) return map;
|
|
@@ -17115,12 +17329,12 @@ function buildStatusMap(steps, completedStepIds, currentStepId, isLast) {
|
|
|
17115
17329
|
}
|
|
17116
17330
|
|
|
17117
17331
|
// src/cli/ui/PlanConfirm.tsx
|
|
17118
|
-
import { Box as
|
|
17119
|
-
import
|
|
17332
|
+
import { Box as Box15, Text as Text15 } from "ink";
|
|
17333
|
+
import React19 from "react";
|
|
17120
17334
|
|
|
17121
17335
|
// src/cli/ui/markdown-view.tsx
|
|
17122
|
-
import { Box as
|
|
17123
|
-
import
|
|
17336
|
+
import { Box as Box14, Text as Text14 } from "ink";
|
|
17337
|
+
import React18 from "react";
|
|
17124
17338
|
|
|
17125
17339
|
// node_modules/marked/lib/marked.esm.js
|
|
17126
17340
|
function _getDefaults() {
|
|
@@ -19466,33 +19680,33 @@ var TONE_BRAND = "#79c0ff";
|
|
|
19466
19680
|
var TONE_OK = "#7ee787";
|
|
19467
19681
|
var SURFACE_ELEV = "#161b22";
|
|
19468
19682
|
function MarkdownView({ text }) {
|
|
19469
|
-
return /* @__PURE__ */
|
|
19683
|
+
return /* @__PURE__ */ React18.createElement(MarkdownLines, { lines: markdownToLines(text) });
|
|
19470
19684
|
}
|
|
19471
19685
|
function MarkdownLines({
|
|
19472
19686
|
lines
|
|
19473
19687
|
}) {
|
|
19474
|
-
return /* @__PURE__ */
|
|
19688
|
+
return /* @__PURE__ */ React18.createElement(Box14, { flexDirection: "column" }, lines.map((line, i) => /* @__PURE__ */ React18.createElement(LineRow, { key: `md-${i}-${line.kind}`, line })));
|
|
19475
19689
|
}
|
|
19476
19690
|
function LineRow({ line }) {
|
|
19477
19691
|
switch (line.kind) {
|
|
19478
19692
|
case "blank":
|
|
19479
|
-
return /* @__PURE__ */
|
|
19693
|
+
return /* @__PURE__ */ React18.createElement(Text14, null, " ");
|
|
19480
19694
|
case "hr":
|
|
19481
|
-
return /* @__PURE__ */
|
|
19695
|
+
return /* @__PURE__ */ React18.createElement(Text14, { color: FG_FAINT }, "\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
19482
19696
|
case "heading":
|
|
19483
|
-
return /* @__PURE__ */
|
|
19697
|
+
return /* @__PURE__ */ React18.createElement(Box14, null, /* @__PURE__ */ React18.createElement(Text14, { bold: true, color: FG_STRONG }, `${"#".repeat(line.level)} `), /* @__PURE__ */ React18.createElement(Spans, { spans: line.spans, bold: true, strongColor: true }));
|
|
19484
19698
|
case "paragraph":
|
|
19485
|
-
return /* @__PURE__ */
|
|
19699
|
+
return /* @__PURE__ */ React18.createElement(Box14, null, /* @__PURE__ */ React18.createElement(Spans, { spans: line.spans }));
|
|
19486
19700
|
case "list": {
|
|
19487
19701
|
const indent = " ".repeat(line.depth * 2);
|
|
19488
19702
|
const marker = line.task === "done" ? "\u2713" : line.task === "todo" ? "\u25CB" : line.ordered ? `${line.index}.` : "\xB7";
|
|
19489
19703
|
const markerColor = line.task === "done" ? TONE_OK : line.task === "todo" ? FG_FAINT : FG_META;
|
|
19490
|
-
return /* @__PURE__ */
|
|
19704
|
+
return /* @__PURE__ */ React18.createElement(Box14, null, /* @__PURE__ */ React18.createElement(Text14, { color: markerColor }, `${indent}${marker} `), /* @__PURE__ */ React18.createElement(Spans, { spans: line.spans, dim: line.task === "done", strike: line.task === "done" }));
|
|
19491
19705
|
}
|
|
19492
19706
|
case "code":
|
|
19493
|
-
return /* @__PURE__ */
|
|
19707
|
+
return /* @__PURE__ */ React18.createElement(CodeBlock, { lang: line.lang, text: line.text });
|
|
19494
19708
|
case "blockquote":
|
|
19495
|
-
return /* @__PURE__ */
|
|
19709
|
+
return /* @__PURE__ */ React18.createElement(Box14, null, /* @__PURE__ */ React18.createElement(Text14, { color: TONE_BRAND }, "\u258E "), /* @__PURE__ */ React18.createElement(Spans, { spans: line.spans, italic: true }));
|
|
19496
19710
|
}
|
|
19497
19711
|
}
|
|
19498
19712
|
function spanKey(span, i) {
|
|
@@ -19500,14 +19714,14 @@ function spanKey(span, i) {
|
|
|
19500
19714
|
}
|
|
19501
19715
|
function CodeBlock({ lang, text }) {
|
|
19502
19716
|
const lines = text.split("\n");
|
|
19503
|
-
return /* @__PURE__ */
|
|
19717
|
+
return /* @__PURE__ */ React18.createElement(Box14, { flexDirection: "column" }, lang.length > 0 ? /* @__PURE__ */ React18.createElement(Text14, { color: FG_META }, ` ${lang}`) : null, lines.map((ln, i) => (
|
|
19504
19718
|
// biome-ignore lint/suspicious/noArrayIndexKey: code lines are positional + stable per render
|
|
19505
|
-
/* @__PURE__ */
|
|
19719
|
+
/* @__PURE__ */ React18.createElement(Text14, { key: `code-${i}`, backgroundColor: SURFACE_ELEV }, ` ${ln} `)
|
|
19506
19720
|
)));
|
|
19507
19721
|
}
|
|
19508
19722
|
function Spans({ spans, bold, italic, dim, strike, strongColor }) {
|
|
19509
|
-
if (spans.length === 0) return /* @__PURE__ */
|
|
19510
|
-
return /* @__PURE__ */
|
|
19723
|
+
if (spans.length === 0) return /* @__PURE__ */ React18.createElement(Text14, null, " ");
|
|
19724
|
+
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, spans.map((span, i) => /* @__PURE__ */ React18.createElement(
|
|
19511
19725
|
SpanText,
|
|
19512
19726
|
{
|
|
19513
19727
|
key: spanKey(span, i),
|
|
@@ -19529,11 +19743,11 @@ function SpanText({
|
|
|
19529
19743
|
strongColor
|
|
19530
19744
|
}) {
|
|
19531
19745
|
if (span.code) {
|
|
19532
|
-
return /* @__PURE__ */
|
|
19746
|
+
return /* @__PURE__ */ React18.createElement(Text14, { color: FG_STRONG, backgroundColor: SURFACE_ELEV }, ` ${span.text} `);
|
|
19533
19747
|
}
|
|
19534
19748
|
const color2 = span.fileRef ? TONE_BRAND : span.link ? TONE_BRAND : strongColor ? FG_STRONG : FG_BODY;
|
|
19535
|
-
return /* @__PURE__ */
|
|
19536
|
-
|
|
19749
|
+
return /* @__PURE__ */ React18.createElement(
|
|
19750
|
+
Text14,
|
|
19537
19751
|
{
|
|
19538
19752
|
color: color2,
|
|
19539
19753
|
bold: !!(span.bold || ambientBold),
|
|
@@ -19558,7 +19772,7 @@ function PlanConfirmInner({ plan: plan3, steps, onChoose }) {
|
|
|
19558
19772
|
const reservedFor = hasSteps ? stepRows : previewRows;
|
|
19559
19773
|
useReserveRows("modal", { min: 10, max: Math.max(16, reservedFor + 14) });
|
|
19560
19774
|
const hasOpenQuestions = /^#{1,6}\s*(open[-\s]?questions?|risks?|unknowns?|assumptions?|unclear)/im.test(plan3) || /^#{1,6}\s*(待确认|开放问题|风险|未知|假设|不确定)/im.test(plan3);
|
|
19561
|
-
return /* @__PURE__ */
|
|
19775
|
+
return /* @__PURE__ */ React19.createElement(
|
|
19562
19776
|
ApprovalCard,
|
|
19563
19777
|
{
|
|
19564
19778
|
tone: "accent",
|
|
@@ -19567,9 +19781,9 @@ function PlanConfirmInner({ plan: plan3, steps, onChoose }) {
|
|
|
19567
19781
|
metaRight: "awaiting",
|
|
19568
19782
|
metaRightColor: CARD.plan.color
|
|
19569
19783
|
},
|
|
19570
|
-
hasOpenQuestions ? /* @__PURE__ */
|
|
19571
|
-
hasSteps ? /* @__PURE__ */
|
|
19572
|
-
/* @__PURE__ */
|
|
19784
|
+
hasOpenQuestions ? /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Text15, { color: TONE.warn }, "\u25B2 the plan flags open questions or risks \u2014 pick ", /* @__PURE__ */ React19.createElement(Text15, { bold: true }, "refine"), " to write concrete answers before the model moves on.")) : null,
|
|
19785
|
+
hasSteps ? /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React19.createElement(PlanStepList, { steps })) : plan3.trim().length > 0 ? /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React19.createElement(MarkdownView, { text: previewBody }), truncatedBody ? /* @__PURE__ */ React19.createElement(Text15, { color: FG.faint }, `\u2026 ${planLines.length - PLAN_BODY_PREVIEW_LINES} more line${planLines.length - PLAN_BODY_PREVIEW_LINES === 1 ? "" : "s"} above in scrollback`) : null) : null,
|
|
19786
|
+
/* @__PURE__ */ React19.createElement(
|
|
19573
19787
|
SingleSelect,
|
|
19574
19788
|
{
|
|
19575
19789
|
initialValue: hasOpenQuestions ? "refine" : "approve",
|
|
@@ -19601,20 +19815,20 @@ function PlanConfirmInner({ plan: plan3, steps, onChoose }) {
|
|
|
19601
19815
|
)
|
|
19602
19816
|
);
|
|
19603
19817
|
}
|
|
19604
|
-
var PlanConfirm =
|
|
19818
|
+
var PlanConfirm = React19.memo(PlanConfirmInner);
|
|
19605
19819
|
|
|
19606
19820
|
// src/cli/ui/PlanRefineInput.tsx
|
|
19607
|
-
import { Box as
|
|
19608
|
-
import
|
|
19821
|
+
import { Box as Box16, Text as Text16 } from "ink";
|
|
19822
|
+
import React21, { useState as useState9 } from "react";
|
|
19609
19823
|
|
|
19610
19824
|
// src/cli/ui/ticker.tsx
|
|
19611
19825
|
import { useAnimation } from "ink";
|
|
19612
|
-
import
|
|
19826
|
+
import React20, { createContext as createContext3, useContext as useContext3, useState as useState8 } from "react";
|
|
19613
19827
|
var FAST_TICK_MS = 120;
|
|
19614
19828
|
var SLOW_TICK_MS = 1e3;
|
|
19615
19829
|
var TickerActiveContext = createContext3(true);
|
|
19616
19830
|
function TickerProvider({ children, disabled }) {
|
|
19617
|
-
return /* @__PURE__ */
|
|
19831
|
+
return /* @__PURE__ */ React20.createElement(TickerActiveContext.Provider, { value: !disabled }, children);
|
|
19618
19832
|
}
|
|
19619
19833
|
function useTickerActive() {
|
|
19620
19834
|
return useContext3(TickerActiveContext);
|
|
@@ -19628,7 +19842,7 @@ function useSlowTick() {
|
|
|
19628
19842
|
return useAnimation({ interval: SLOW_TICK_MS, isActive }).frame;
|
|
19629
19843
|
}
|
|
19630
19844
|
function useElapsedSeconds() {
|
|
19631
|
-
const [start] =
|
|
19845
|
+
const [start] = useState8(() => Date.now());
|
|
19632
19846
|
useSlowTick();
|
|
19633
19847
|
return Math.floor((Date.now() - start) / 1e3);
|
|
19634
19848
|
}
|
|
@@ -19677,7 +19891,7 @@ var MODES = {
|
|
|
19677
19891
|
}
|
|
19678
19892
|
};
|
|
19679
19893
|
function PlanRefineInput({ mode: mode2, onSubmit, onCancel }) {
|
|
19680
|
-
const [value, setValue] =
|
|
19894
|
+
const [value, setValue] = useState9("");
|
|
19681
19895
|
useKeystroke((ev) => {
|
|
19682
19896
|
if (ev.paste) {
|
|
19683
19897
|
setValue((v) => v + ev.input.replace(/\r?\n/g, " "));
|
|
@@ -19702,7 +19916,7 @@ function PlanRefineInput({ mode: mode2, onSubmit, onCancel }) {
|
|
|
19702
19916
|
const tick = useTick();
|
|
19703
19917
|
const cursorOn = Math.floor(tick / 4) % 2 === 0;
|
|
19704
19918
|
const meta = MODES[mode2];
|
|
19705
|
-
return /* @__PURE__ */
|
|
19919
|
+
return /* @__PURE__ */ React21.createElement(
|
|
19706
19920
|
ApprovalCard,
|
|
19707
19921
|
{
|
|
19708
19922
|
tone: meta.tone,
|
|
@@ -19710,14 +19924,14 @@ function PlanRefineInput({ mode: mode2, onSubmit, onCancel }) {
|
|
|
19710
19924
|
title: meta.title,
|
|
19711
19925
|
footerHint: "\u23CE send \xB7 esc return to picker"
|
|
19712
19926
|
},
|
|
19713
|
-
/* @__PURE__ */
|
|
19714
|
-
/* @__PURE__ */
|
|
19927
|
+
/* @__PURE__ */ React21.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: FG.sub }, meta.hint, value === "" ? meta.blankHint : "")),
|
|
19928
|
+
/* @__PURE__ */ React21.createElement(Box16, null, /* @__PURE__ */ React21.createElement(Text16, { color: meta.cursorColor, bold: true }, "\u203A "), /* @__PURE__ */ React21.createElement(Text16, null, value), /* @__PURE__ */ React21.createElement(Text16, { color: meta.cursorColor, bold: true }, cursorOn ? "\u258D" : " "))
|
|
19715
19929
|
);
|
|
19716
19930
|
}
|
|
19717
19931
|
|
|
19718
19932
|
// src/cli/ui/PlanReviseConfirm.tsx
|
|
19719
|
-
import { Box as
|
|
19720
|
-
import
|
|
19933
|
+
import { Box as Box17, Text as Text17 } from "ink";
|
|
19934
|
+
import React22 from "react";
|
|
19721
19935
|
function computeDiff(oldSteps, newSteps) {
|
|
19722
19936
|
const oldIds = new Set(oldSteps.map((s) => s.id));
|
|
19723
19937
|
const newIds = new Set(newSteps.map((s) => s.id));
|
|
@@ -19753,7 +19967,7 @@ function PlanReviseConfirmInner({
|
|
|
19753
19967
|
const removedCount = rows.filter((r) => r.kind === "removed").length;
|
|
19754
19968
|
const addedCount = rows.filter((r) => r.kind === "added").length;
|
|
19755
19969
|
const keptCount = rows.filter((r) => r.kind === "kept").length;
|
|
19756
|
-
return /* @__PURE__ */
|
|
19970
|
+
return /* @__PURE__ */ React22.createElement(
|
|
19757
19971
|
ApprovalCard,
|
|
19758
19972
|
{
|
|
19759
19973
|
tone: "warn",
|
|
@@ -19761,17 +19975,17 @@ function PlanReviseConfirmInner({
|
|
|
19761
19975
|
title: "plan revision proposed",
|
|
19762
19976
|
metaRight: `\u2212${removedCount} +${addedCount} \xB7 ${keptCount} kept`
|
|
19763
19977
|
},
|
|
19764
|
-
/* @__PURE__ */
|
|
19765
|
-
summary ? /* @__PURE__ */
|
|
19766
|
-
/* @__PURE__ */
|
|
19978
|
+
/* @__PURE__ */ React22.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React22.createElement(Text17, null, reason)),
|
|
19979
|
+
summary ? /* @__PURE__ */ React22.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React22.createElement(Text17, { dimColor: true }, `updated summary: ${summary}`)) : null,
|
|
19980
|
+
/* @__PURE__ */ React22.createElement(Box17, { marginBottom: 1, flexDirection: "column" }, rows.map((row3) => {
|
|
19767
19981
|
const risk = riskDots(row3.step.risk);
|
|
19768
19982
|
const prefix = row3.kind === "removed" ? "\u2212" : row3.kind === "added" ? "+" : " ";
|
|
19769
19983
|
const prefixColor = row3.kind === "removed" ? "#f87171" : row3.kind === "added" ? "#4ade80" : "#94a3b8";
|
|
19770
19984
|
const dim = row3.kind === "kept";
|
|
19771
19985
|
const strike = row3.kind === "removed";
|
|
19772
|
-
return /* @__PURE__ */
|
|
19986
|
+
return /* @__PURE__ */ React22.createElement(Box17, { key: `${row3.kind}-${row3.step.id}` }, /* @__PURE__ */ React22.createElement(Text17, { color: prefixColor, bold: true }, `${prefix} `), /* @__PURE__ */ React22.createElement(Text17, { color: risk.color, bold: true, dimColor: dim }, risk.dots), /* @__PURE__ */ React22.createElement(Text17, { dimColor: dim, strikethrough: strike }, ` ${row3.step.id} \xB7 ${row3.step.title}`));
|
|
19773
19987
|
})),
|
|
19774
|
-
/* @__PURE__ */
|
|
19988
|
+
/* @__PURE__ */ React22.createElement(
|
|
19775
19989
|
SingleSelect,
|
|
19776
19990
|
{
|
|
19777
19991
|
initialValue: "accept",
|
|
@@ -19793,22 +20007,22 @@ function PlanReviseConfirmInner({
|
|
|
19793
20007
|
)
|
|
19794
20008
|
);
|
|
19795
20009
|
}
|
|
19796
|
-
var PlanReviseConfirm =
|
|
20010
|
+
var PlanReviseConfirm = React22.memo(PlanReviseConfirmInner);
|
|
19797
20011
|
|
|
19798
20012
|
// src/cli/ui/PlanReviseEditor.tsx
|
|
19799
|
-
import { Box as
|
|
19800
|
-
import
|
|
20013
|
+
import { Box as Box18, Text as Text18 } from "ink";
|
|
20014
|
+
import React23, { useState as useState10 } from "react";
|
|
19801
20015
|
function PlanReviseEditor({
|
|
19802
20016
|
steps,
|
|
19803
20017
|
completedStepIds,
|
|
19804
20018
|
onAccept,
|
|
19805
20019
|
onCancel
|
|
19806
20020
|
}) {
|
|
19807
|
-
const [rows, setRows] =
|
|
20021
|
+
const [rows, setRows] = useState10(
|
|
19808
20022
|
() => steps.map((s) => ({ step: s, done: completedStepIds?.has(s.id) ?? false, skipped: false }))
|
|
19809
20023
|
);
|
|
19810
20024
|
const firstEditableIndex = rows.findIndex((r) => !r.done);
|
|
19811
|
-
const [focus, setFocus] =
|
|
20025
|
+
const [focus, setFocus] = useState10(firstEditableIndex < 0 ? 0 : firstEditableIndex);
|
|
19812
20026
|
useKeystroke((ev) => {
|
|
19813
20027
|
if (ev.paste) return;
|
|
19814
20028
|
if (ev.escape) {
|
|
@@ -19869,7 +20083,7 @@ function PlanReviseEditor({
|
|
|
19869
20083
|
return;
|
|
19870
20084
|
}
|
|
19871
20085
|
});
|
|
19872
|
-
return /* @__PURE__ */
|
|
20086
|
+
return /* @__PURE__ */ React23.createElement(
|
|
19873
20087
|
ApprovalCard,
|
|
19874
20088
|
{
|
|
19875
20089
|
tone: "accent",
|
|
@@ -19878,7 +20092,7 @@ function PlanReviseEditor({
|
|
|
19878
20092
|
metaRight: `${rows.length} steps`,
|
|
19879
20093
|
footerHint: "\u2191\u2193 focus \xB7 space toggle skip \xB7 k/j move \xB7 \u23CE accept \xB7 esc cancel"
|
|
19880
20094
|
},
|
|
19881
|
-
rows.map((r, i) => /* @__PURE__ */
|
|
20095
|
+
rows.map((r, i) => /* @__PURE__ */ React23.createElement(ReviseRow, { key: r.step.id, row: r, index: i, focused: i === focus }))
|
|
19882
20096
|
);
|
|
19883
20097
|
}
|
|
19884
20098
|
function ReviseRow({
|
|
@@ -19889,13 +20103,13 @@ function ReviseRow({
|
|
|
19889
20103
|
const marker = row3.done ? "[\u2713]" : row3.skipped ? "[s]" : focused ? "[ ]" : "[ ]";
|
|
19890
20104
|
const markerColor = row3.done ? TONE.ok : row3.skipped ? FG.faint : focused ? TONE.brand : FG.faint;
|
|
19891
20105
|
const titleColor = row3.done ? FG.sub : row3.skipped ? FG.faint : focused ? FG.strong : FG.sub;
|
|
19892
|
-
const focusGlyph = focused ? /* @__PURE__ */
|
|
19893
|
-
return /* @__PURE__ */
|
|
20106
|
+
const focusGlyph = focused ? /* @__PURE__ */ React23.createElement(Text18, { color: TONE.brand }, "\u25B8 ") : /* @__PURE__ */ React23.createElement(Text18, null, " ");
|
|
20107
|
+
return /* @__PURE__ */ React23.createElement(Box18, null, focusGlyph, /* @__PURE__ */ React23.createElement(Text18, { color: markerColor }, marker), /* @__PURE__ */ React23.createElement(Text18, { color: titleColor, bold: focused, italic: row3.skipped, strikethrough: row3.skipped }, ` ${index + 1}. ${row3.step.title}`), row3.skipped ? /* @__PURE__ */ React23.createElement(Text18, { color: TONE.warn }, " \u2190 skipped") : null);
|
|
19894
20108
|
}
|
|
19895
20109
|
|
|
19896
20110
|
// src/cli/ui/PromptInput.tsx
|
|
19897
|
-
import { Box as
|
|
19898
|
-
import
|
|
20111
|
+
import { Box as Box19, Text as Text19, useStdout as useStdout5 } from "ink";
|
|
20112
|
+
import React24, { useRef as useRef2, useState as useState11 } from "react";
|
|
19899
20113
|
|
|
19900
20114
|
// src/cli/ui/key-normalize.ts
|
|
19901
20115
|
var CSI_TAIL_TO_FLAGS = [
|
|
@@ -19910,7 +20124,13 @@ var CSI_TAIL_TO_FLAGS = [
|
|
|
19910
20124
|
// Forward-delete (the key labelled Delete on most keyboards).
|
|
19911
20125
|
{ tail: "[3~", flags: { delete: true } },
|
|
19912
20126
|
// Shift+Tab — terminal sends `\x1b[Z` rather than tab-with-shift.
|
|
19913
|
-
|
|
20127
|
+
// `[1;2Z` is the modifier-encoded variant some Windows PowerShell
|
|
20128
|
+
// hosts emit; `[27;2;9~` and `[9;2u` cover modifyOtherKeys / Kitty
|
|
20129
|
+
// forms. Issue #373.
|
|
20130
|
+
{ tail: "[Z", flags: { shift: true, tab: true } },
|
|
20131
|
+
{ tail: "[1;2Z", flags: { shift: true, tab: true } },
|
|
20132
|
+
{ tail: "[27;2;9~", flags: { shift: true, tab: true } },
|
|
20133
|
+
{ tail: "[9;2u", flags: { shift: true, tab: true } }
|
|
19914
20134
|
];
|
|
19915
20135
|
function alreadyStructured(flags) {
|
|
19916
20136
|
return Boolean(
|
|
@@ -20330,7 +20550,7 @@ function PromptInput({
|
|
|
20330
20550
|
const inputLineCount = value.length > 0 ? value.split("\n").length : 1;
|
|
20331
20551
|
const reserveMax = Math.min(Math.ceil(inputLineCount / 4) * 4 + 3, 24);
|
|
20332
20552
|
useReserveRows("input", { min: 1, max: reserveMax });
|
|
20333
|
-
const [cursor, setCursor] =
|
|
20553
|
+
const [cursor, setCursor] = useState11(value.length);
|
|
20334
20554
|
const pastesRef = useRef2(/* @__PURE__ */ new Map());
|
|
20335
20555
|
const nextPasteIdRef = useRef2(0);
|
|
20336
20556
|
const lastLocalValueRef = useRef2(value);
|
|
@@ -20408,7 +20628,7 @@ function PromptInput({
|
|
|
20408
20628
|
if (action.chatScrollHandoff === "up") onChatScrollUp?.();
|
|
20409
20629
|
if (action.chatScrollHandoff === "down") onChatScrollDown?.();
|
|
20410
20630
|
}, !disabled);
|
|
20411
|
-
const { stdout: stdout4 } =
|
|
20631
|
+
const { stdout: stdout4 } = useStdout5();
|
|
20412
20632
|
const cols = stdout4?.columns ?? 80;
|
|
20413
20633
|
const promptPrefix = "\u203A ";
|
|
20414
20634
|
const continuationIndent = " ";
|
|
@@ -20421,14 +20641,14 @@ function PromptInput({
|
|
|
20421
20641
|
const { line: cursorLine, col: cursorCol } = lineAndColumn(value, cursor);
|
|
20422
20642
|
const renderItems = collapseLinesForDisplay(lines, cursorLine);
|
|
20423
20643
|
const showHugeBufferHints = lines.length > 20;
|
|
20424
|
-
return /* @__PURE__ */
|
|
20644
|
+
return /* @__PURE__ */ React24.createElement(Box19, { flexDirection: "column", paddingX: 1 }, (() => {
|
|
20425
20645
|
const rows = [];
|
|
20426
20646
|
let firstRowEmitted = false;
|
|
20427
20647
|
for (let renderIdx = 0; renderIdx < renderItems.length; renderIdx++) {
|
|
20428
20648
|
const item = renderItems[renderIdx];
|
|
20429
20649
|
if (item.kind === "skip") {
|
|
20430
20650
|
rows.push(
|
|
20431
|
-
/* @__PURE__ */
|
|
20651
|
+
/* @__PURE__ */ React24.createElement(Box19, { key: `skip-${renderIdx}` }, /* @__PURE__ */ React24.createElement(Text19, { color: FG.faint }, continuationIndent), /* @__PURE__ */ React24.createElement(Text19, { color: FG.faint }, `[\u2026 ${item.linesHidden} line${item.linesHidden === 1 ? "" : "s"} hidden \u2014 full content kept, submitted on Enter \u2026]`))
|
|
20432
20652
|
);
|
|
20433
20653
|
continue;
|
|
20434
20654
|
}
|
|
@@ -20438,7 +20658,7 @@ function PromptInput({
|
|
|
20438
20658
|
const showPlaceholder = i === 0 && value.length === 0;
|
|
20439
20659
|
if (showPlaceholder) {
|
|
20440
20660
|
rows.push(
|
|
20441
|
-
/* @__PURE__ */
|
|
20661
|
+
/* @__PURE__ */ React24.createElement(
|
|
20442
20662
|
PromptLine,
|
|
20443
20663
|
{
|
|
20444
20664
|
key: `ln-${i}-text-0`,
|
|
@@ -20469,7 +20689,7 @@ function PromptInput({
|
|
|
20469
20689
|
if (seg.kind === "paste") {
|
|
20470
20690
|
const cursorOnIt = isCursorLine && cursorCol >= seg.startOffset && cursorCol <= seg.startOffset + 1;
|
|
20471
20691
|
rows.push(
|
|
20472
|
-
/* @__PURE__ */
|
|
20692
|
+
/* @__PURE__ */ React24.createElement(
|
|
20473
20693
|
PasteChipRow,
|
|
20474
20694
|
{
|
|
20475
20695
|
key: `ln-${i}-paste-${segIdx}`,
|
|
@@ -20486,7 +20706,7 @@ function PromptInput({
|
|
|
20486
20706
|
}
|
|
20487
20707
|
const segHasCursor = isCursorLine && cursorCol >= seg.startOffset && cursorCol <= seg.startOffset + seg.text.length;
|
|
20488
20708
|
rows.push(
|
|
20489
|
-
/* @__PURE__ */
|
|
20709
|
+
/* @__PURE__ */ React24.createElement(
|
|
20490
20710
|
PromptLine,
|
|
20491
20711
|
{
|
|
20492
20712
|
key: `ln-${i}-text-${segIdx}`,
|
|
@@ -20511,7 +20731,7 @@ function PromptInput({
|
|
|
20511
20731
|
const isFirst = !firstRowEmitted;
|
|
20512
20732
|
firstRowEmitted = true;
|
|
20513
20733
|
rows.push(
|
|
20514
|
-
/* @__PURE__ */
|
|
20734
|
+
/* @__PURE__ */ React24.createElement(
|
|
20515
20735
|
PromptLine,
|
|
20516
20736
|
{
|
|
20517
20737
|
key: `ln-${i}-empty`,
|
|
@@ -20534,7 +20754,7 @@ function PromptInput({
|
|
|
20534
20754
|
}
|
|
20535
20755
|
}
|
|
20536
20756
|
return rows;
|
|
20537
|
-
})(), showHugeBufferHints && !disabled ? /* @__PURE__ */
|
|
20757
|
+
})(), showHugeBufferHints && !disabled ? /* @__PURE__ */ React24.createElement(Box19, null, /* @__PURE__ */ React24.createElement(Text19, { color: FG.faint }, ` [${lines.length} lines \xB7 PgUp/PgDn jump \xB7 Ctrl+U clear \xB7 Ctrl+W del word]`)) : null, !disabled ? /* @__PURE__ */ React24.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: FG.faint }, " \u23CE send \xB7 shift/alt+\u23CE newline \xB7 \u2191\u2193 history \xB7 esc abort \xB7 ctrl-c quit")) : /* @__PURE__ */ React24.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: FG.faint }, " esc to stop")));
|
|
20538
20758
|
}
|
|
20539
20759
|
function splitLineByPastes(line) {
|
|
20540
20760
|
const out = [];
|
|
@@ -20571,9 +20791,9 @@ function PasteChipRow({
|
|
|
20571
20791
|
const leadColor = isFirst ? accentColor : FG.faint;
|
|
20572
20792
|
const labelText = formatChipLabel(entry, pasteId, visibleCells - 6);
|
|
20573
20793
|
if (active) {
|
|
20574
|
-
return /* @__PURE__ */
|
|
20794
|
+
return /* @__PURE__ */ React24.createElement(Box19, null, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: leadColor }, lead), /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: accentColor }, "\u25B8 "), /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: "black", backgroundColor: accentColor }, ` ${labelText} `));
|
|
20575
20795
|
}
|
|
20576
|
-
return /* @__PURE__ */
|
|
20796
|
+
return /* @__PURE__ */ React24.createElement(Box19, null, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: leadColor }, lead), /* @__PURE__ */ React24.createElement(Text19, { color: FG.faint }, " "), /* @__PURE__ */ React24.createElement(Text19, { color: FG.meta }, "\u250C "), /* @__PURE__ */ React24.createElement(Text19, { color: FG.body, backgroundColor: SURFACE.bgElev }, `${labelText} `), /* @__PURE__ */ React24.createElement(Text19, { color: FG.meta }, " \u2510"));
|
|
20577
20797
|
}
|
|
20578
20798
|
function formatChipLabel(entry, pasteId, budget3) {
|
|
20579
20799
|
if (!entry) return `\u{1F4CB} paste #${pasteId + 1} \xB7 (missing)`;
|
|
@@ -20617,10 +20837,10 @@ function PromptLine({
|
|
|
20617
20837
|
disabled
|
|
20618
20838
|
}) {
|
|
20619
20839
|
if (showPlaceholder) {
|
|
20620
|
-
return /* @__PURE__ */
|
|
20840
|
+
return /* @__PURE__ */ React24.createElement(Box19, null, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: accentColor }, promptPrefix), !disabled ? /* @__PURE__ */ React24.createElement(Text19, { color: accentColor }, cursorVisible ? "\u258C" : " ") : null, /* @__PURE__ */ React24.createElement(Text19, { color: FG.faint }, placeholderText));
|
|
20621
20841
|
}
|
|
20622
20842
|
const viewport = buildViewport(line, isCursorLine ? cursorCol : null, visibleCells, pastes);
|
|
20623
|
-
return /* @__PURE__ */
|
|
20843
|
+
return /* @__PURE__ */ React24.createElement(Box19, null, isFirst ? /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: accentColor }, promptPrefix) : /* @__PURE__ */ React24.createElement(Text19, { color: FG.faint }, continuationIndent), viewport.hiddenLeft ? /* @__PURE__ */ React24.createElement(Text19, { color: FG.faint }, "\u2039") : null, /* @__PURE__ */ React24.createElement(
|
|
20624
20844
|
ViewportContent,
|
|
20625
20845
|
{
|
|
20626
20846
|
segments: viewport.segments,
|
|
@@ -20628,7 +20848,7 @@ function PromptLine({
|
|
|
20628
20848
|
accentColor,
|
|
20629
20849
|
cursorVisible
|
|
20630
20850
|
}
|
|
20631
|
-
), viewport.hiddenRight ? /* @__PURE__ */
|
|
20851
|
+
), viewport.hiddenRight ? /* @__PURE__ */ React24.createElement(Text19, { color: FG.faint }, "\u203A") : null);
|
|
20632
20852
|
}
|
|
20633
20853
|
function ViewportContent({
|
|
20634
20854
|
segments,
|
|
@@ -20637,7 +20857,7 @@ function ViewportContent({
|
|
|
20637
20857
|
cursorVisible
|
|
20638
20858
|
}) {
|
|
20639
20859
|
if (cursorCell === null) {
|
|
20640
|
-
return /* @__PURE__ */
|
|
20860
|
+
return /* @__PURE__ */ React24.createElement(React24.Fragment, null, segments.map((seg, i) => renderSegment(seg, i, false)));
|
|
20641
20861
|
}
|
|
20642
20862
|
const out = [];
|
|
20643
20863
|
let cells = 0;
|
|
@@ -20656,8 +20876,8 @@ function ViewportContent({
|
|
|
20656
20876
|
}
|
|
20657
20877
|
if (seg.kind === "paste") {
|
|
20658
20878
|
out.push(
|
|
20659
|
-
/* @__PURE__ */
|
|
20660
|
-
|
|
20879
|
+
/* @__PURE__ */ React24.createElement(
|
|
20880
|
+
Text19,
|
|
20661
20881
|
{
|
|
20662
20882
|
key: `p-${i}-cursor`,
|
|
20663
20883
|
color: FG.body,
|
|
@@ -20674,29 +20894,29 @@ function ViewportContent({
|
|
|
20674
20894
|
const offsetIntoSeg = cursorCell - cells;
|
|
20675
20895
|
const split = splitTextByCells(seg.text, offsetIntoSeg);
|
|
20676
20896
|
if (split.before.length > 0) {
|
|
20677
|
-
out.push(/* @__PURE__ */
|
|
20897
|
+
out.push(/* @__PURE__ */ React24.createElement(Text19, { key: `t-${i}-b` }, split.before));
|
|
20678
20898
|
}
|
|
20679
20899
|
if (split.atCursor.length > 0) {
|
|
20680
20900
|
out.push(
|
|
20681
|
-
/* @__PURE__ */
|
|
20901
|
+
/* @__PURE__ */ React24.createElement(Text19, { key: `t-${i}-c`, inverse: cursorVisible, color: accentColor }, split.atCursor)
|
|
20682
20902
|
);
|
|
20683
20903
|
} else {
|
|
20684
20904
|
out.push(
|
|
20685
|
-
/* @__PURE__ */
|
|
20905
|
+
/* @__PURE__ */ React24.createElement(Text19, { key: `t-${i}-c-eol`, color: accentColor }, cursorVisible ? "\u258C" : " ")
|
|
20686
20906
|
);
|
|
20687
20907
|
}
|
|
20688
20908
|
if (split.after.length > 0) {
|
|
20689
|
-
out.push(/* @__PURE__ */
|
|
20909
|
+
out.push(/* @__PURE__ */ React24.createElement(Text19, { key: `t-${i}-a` }, split.after));
|
|
20690
20910
|
}
|
|
20691
20911
|
placed = true;
|
|
20692
20912
|
cells += segCells;
|
|
20693
20913
|
}
|
|
20694
20914
|
if (!placed) {
|
|
20695
20915
|
out.push(
|
|
20696
|
-
/* @__PURE__ */
|
|
20916
|
+
/* @__PURE__ */ React24.createElement(Text19, { key: "cursor-eol", color: accentColor }, cursorVisible ? "\u258C" : " ")
|
|
20697
20917
|
);
|
|
20698
20918
|
}
|
|
20699
|
-
return /* @__PURE__ */
|
|
20919
|
+
return /* @__PURE__ */ React24.createElement(React24.Fragment, null, out);
|
|
20700
20920
|
}
|
|
20701
20921
|
function segmentCells(seg) {
|
|
20702
20922
|
if (seg.kind === "paste") return seg.label.length;
|
|
@@ -20736,9 +20956,9 @@ function charCellsForText(ch) {
|
|
|
20736
20956
|
}
|
|
20737
20957
|
function renderSegment(seg, key, _inverse) {
|
|
20738
20958
|
if (seg.kind === "text") {
|
|
20739
|
-
return /* @__PURE__ */
|
|
20959
|
+
return /* @__PURE__ */ React24.createElement(Text19, { key: `s-${key}` }, seg.text);
|
|
20740
20960
|
}
|
|
20741
|
-
return /* @__PURE__ */
|
|
20961
|
+
return /* @__PURE__ */ React24.createElement(Text19, { key: `s-${key}`, backgroundColor: SURFACE.bgElev, color: FG.body }, seg.label);
|
|
20742
20962
|
}
|
|
20743
20963
|
var COLLAPSE_THRESHOLD = 20;
|
|
20744
20964
|
var COLLAPSE_HEAD_LINES = 3;
|
|
@@ -20765,20 +20985,20 @@ function collapseLinesForDisplay(lines, cursorLine) {
|
|
|
20765
20985
|
}
|
|
20766
20986
|
|
|
20767
20987
|
// src/cli/ui/SessionPicker.tsx
|
|
20768
|
-
import { Box as
|
|
20769
|
-
import
|
|
20770
|
-
var
|
|
20988
|
+
import { Box as Box20, Text as Text20, useStdout as useStdout6 } from "ink";
|
|
20989
|
+
import React25, { useState as useState12 } from "react";
|
|
20990
|
+
var PAGE_MARGIN2 = 6;
|
|
20771
20991
|
function SessionPicker({
|
|
20772
20992
|
sessions: sessions2,
|
|
20773
20993
|
workspace: workspace2,
|
|
20774
20994
|
onChoose,
|
|
20775
20995
|
walletCurrency
|
|
20776
20996
|
}) {
|
|
20777
|
-
const [focus, setFocus] =
|
|
20778
|
-
const [renaming, setRenaming] =
|
|
20779
|
-
const { stdout: stdout4 } =
|
|
20997
|
+
const [focus, setFocus] = useState12(0);
|
|
20998
|
+
const [renaming, setRenaming] = useState12(null);
|
|
20999
|
+
const { stdout: stdout4 } = useStdout6();
|
|
20780
21000
|
const rows = stdout4?.rows ?? 40;
|
|
20781
|
-
const visibleCount = Math.max(3, rows -
|
|
21001
|
+
const visibleCount = Math.max(3, rows - PAGE_MARGIN2);
|
|
20782
21002
|
useKeystroke((ev) => {
|
|
20783
21003
|
if (ev.paste) {
|
|
20784
21004
|
if (renaming) setRenaming({ ...renaming, buf: renaming.buf + ev.input });
|
|
@@ -20829,7 +21049,7 @@ function SessionPicker({
|
|
|
20829
21049
|
const end = Math.min(sessions2.length, start + visibleCount);
|
|
20830
21050
|
const shown = sessions2.slice(start, end);
|
|
20831
21051
|
const hiddenBelow = sessions2.length - end;
|
|
20832
|
-
return /* @__PURE__ */
|
|
21052
|
+
return /* @__PURE__ */ React25.createElement(Box20, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React25.createElement(Box20, null, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: TONE.brand }, " \u25C8 REASONIX \xB7 pick a session "), /* @__PURE__ */ React25.createElement(Text20, { color: FG.meta }, ` \xB7 ${workspace2}`)), /* @__PURE__ */ React25.createElement(Box20, { height: 1 }), sessions2.length === 0 ? /* @__PURE__ */ React25.createElement(Box20, null, /* @__PURE__ */ React25.createElement(Text20, { color: FG.faint }, " no saved sessions in this workspace yet \u2014 press "), /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: TONE.brand }, "\u23CE"), /* @__PURE__ */ React25.createElement(Text20, { color: FG.faint }, " to start a new one")) : shown.map((s, i) => /* @__PURE__ */ React25.createElement(
|
|
20833
21053
|
SessionRow,
|
|
20834
21054
|
{
|
|
20835
21055
|
key: s.name,
|
|
@@ -20837,7 +21057,7 @@ function SessionPicker({
|
|
|
20837
21057
|
focused: start + i === focus,
|
|
20838
21058
|
walletCurrency
|
|
20839
21059
|
}
|
|
20840
|
-
)), hiddenBelow > 0 ? /* @__PURE__ */
|
|
21060
|
+
)), hiddenBelow > 0 ? /* @__PURE__ */ React25.createElement(Box20, null, /* @__PURE__ */ React25.createElement(Text20, { color: FG.faint }, ` \u2026 ${hiddenBelow} more`)) : null, renaming ? /* @__PURE__ */ React25.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: FG.faint }, ` rename "${renaming.from}" \u2192 `), /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: TONE.brand }, renaming.buf), /* @__PURE__ */ React25.createElement(Text20, { backgroundColor: TONE.brand, color: "black" }, " ")) : null, /* @__PURE__ */ React25.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: FG.faint }, renaming ? " \u23CE confirm rename \xB7 esc cancel" : sessions2.length === 0 ? " \u23CE new session \xB7 esc quit" : " \u2191\u2193 pick \xB7 \u23CE open \xB7 [n] new \xB7 [d] delete \xB7 [r] rename \xB7 esc quit")));
|
|
20841
21061
|
}
|
|
20842
21062
|
function SessionRow({
|
|
20843
21063
|
info,
|
|
@@ -20850,7 +21070,7 @@ function SessionRow({
|
|
|
20850
21070
|
const currency = walletCurrency ?? info.meta.balanceCurrency;
|
|
20851
21071
|
const costLabel = info.meta.totalCostUsd !== void 0 ? formatCost(info.meta.totalCostUsd, currency, 2) : "";
|
|
20852
21072
|
const time = relativeTime2(info.mtime);
|
|
20853
|
-
return /* @__PURE__ */
|
|
21073
|
+
return /* @__PURE__ */ React25.createElement(Box20, null, /* @__PURE__ */ React25.createElement(Text20, { color: focused ? TONE.brand : FG.faint }, focused ? " \u25B8 " : " "), /* @__PURE__ */ React25.createElement(Text20, { bold: focused, color: focused ? FG.strong : FG.sub }, info.name.padEnd(12)), /* @__PURE__ */ React25.createElement(Text20, { color: FG.meta }, ` \xB7 ${branch2.padEnd(8)} \xB7 `), /* @__PURE__ */ React25.createElement(Text20, { color: focused ? FG.body : FG.sub }, truncate2(summary, 40)), /* @__PURE__ */ React25.createElement(Box20, { flexGrow: 1 }), /* @__PURE__ */ React25.createElement(Text20, { color: FG.faint }, `${time.padStart(11)} `), /* @__PURE__ */ React25.createElement(Text20, { color: FG.faint }, `${turns} turns`), costLabel ? /* @__PURE__ */ React25.createElement(Text20, { color: FG.faint }, ` \xB7 ${costLabel}`) : null);
|
|
20854
21074
|
}
|
|
20855
21075
|
function truncate2(s, max) {
|
|
20856
21076
|
if (s.length <= max) return s;
|
|
@@ -20870,15 +21090,15 @@ function relativeTime2(date) {
|
|
|
20870
21090
|
}
|
|
20871
21091
|
|
|
20872
21092
|
// src/cli/ui/ShellConfirm.tsx
|
|
20873
|
-
import { Box as
|
|
20874
|
-
import
|
|
21093
|
+
import { Box as Box21, Text as Text21 } from "ink";
|
|
21094
|
+
import React26, { useState as useState13 } from "react";
|
|
20875
21095
|
function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
|
|
20876
21096
|
useReserveRows("modal", { min: 8, max: 14 });
|
|
20877
21097
|
const isBackground = kind === "run_background";
|
|
20878
21098
|
const subtitle = isBackground ? "long-running process \u2014 keeps running after approval, /kill to stop" : "model wants to run a shell command";
|
|
20879
|
-
const [phase, setPhase] =
|
|
21099
|
+
const [phase, setPhase] = useState13("pick");
|
|
20880
21100
|
if (phase === "deny") {
|
|
20881
|
-
return /* @__PURE__ */
|
|
21101
|
+
return /* @__PURE__ */ React26.createElement(
|
|
20882
21102
|
ApprovalCard,
|
|
20883
21103
|
{
|
|
20884
21104
|
tone: "error",
|
|
@@ -20887,7 +21107,7 @@ function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
|
|
|
20887
21107
|
metaRight: "optional",
|
|
20888
21108
|
footerHint: "type context \xB7 \u23CE submit with reason \xB7 esc skip (deny without reason)"
|
|
20889
21109
|
},
|
|
20890
|
-
/* @__PURE__ */
|
|
21110
|
+
/* @__PURE__ */ React26.createElement(
|
|
20891
21111
|
DenyContextInput,
|
|
20892
21112
|
{
|
|
20893
21113
|
onSubmit: (context2) => onChoose("deny", context2 || void 0),
|
|
@@ -20896,7 +21116,7 @@ function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
|
|
|
20896
21116
|
)
|
|
20897
21117
|
);
|
|
20898
21118
|
}
|
|
20899
|
-
return /* @__PURE__ */
|
|
21119
|
+
return /* @__PURE__ */ React26.createElement(
|
|
20900
21120
|
ApprovalCard,
|
|
20901
21121
|
{
|
|
20902
21122
|
tone: "warn",
|
|
@@ -20905,9 +21125,9 @@ function ShellConfirm({ command, allowPrefix, kind, onChoose }) {
|
|
|
20905
21125
|
metaRight: "awaiting",
|
|
20906
21126
|
footerHint: "\u2191\u2193 pick \xB7 \u23CE confirm \xB7 Tab add context \xB7 esc cancel"
|
|
20907
21127
|
},
|
|
20908
|
-
/* @__PURE__ */
|
|
20909
|
-
/* @__PURE__ */
|
|
20910
|
-
/* @__PURE__ */
|
|
21128
|
+
/* @__PURE__ */ React26.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React26.createElement(Text21, { color: FG.faint }, subtitle)),
|
|
21129
|
+
/* @__PURE__ */ React26.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React26.createElement(Text21, { bold: true, color: TONE.err }, "$ "), /* @__PURE__ */ React26.createElement(Text21, { bold: true, color: FG.strong }, command)),
|
|
21130
|
+
/* @__PURE__ */ React26.createElement(
|
|
20911
21131
|
SingleSelect,
|
|
20912
21132
|
{
|
|
20913
21133
|
initialValue: "run_once",
|
|
@@ -20970,8 +21190,8 @@ function derivePrefix(command) {
|
|
|
20970
21190
|
}
|
|
20971
21191
|
|
|
20972
21192
|
// src/cli/ui/SlashArgPicker.tsx
|
|
20973
|
-
import { Box as
|
|
20974
|
-
import
|
|
21193
|
+
import { Box as Box22, Text as Text22 } from "ink";
|
|
21194
|
+
import React27 from "react";
|
|
20975
21195
|
function SlashArgPicker({
|
|
20976
21196
|
matches,
|
|
20977
21197
|
selectedIndex,
|
|
@@ -20979,13 +21199,13 @@ function SlashArgPicker({
|
|
|
20979
21199
|
kind,
|
|
20980
21200
|
partial
|
|
20981
21201
|
}) {
|
|
20982
|
-
const headerRow = /* @__PURE__ */
|
|
21202
|
+
const headerRow = /* @__PURE__ */ React27.createElement(Box22, null, /* @__PURE__ */ React27.createElement(Text22, { color: COLOR.accent, bold: true }, "/ "), /* @__PURE__ */ React27.createElement(Text22, { color: COLOR.accent, bold: true }, `/${spec.cmd}`), spec.argsHint ? /* @__PURE__ */ React27.createElement(Text22, { dimColor: true }, ` ${spec.argsHint}`) : null, /* @__PURE__ */ React27.createElement(Text22, { dimColor: true }, ` ${spec.summary}`));
|
|
20983
21203
|
if (kind === "hint") {
|
|
20984
|
-
return /* @__PURE__ */
|
|
21204
|
+
return /* @__PURE__ */ React27.createElement(Box22, { paddingX: 1, marginTop: 1 }, headerRow);
|
|
20985
21205
|
}
|
|
20986
21206
|
if (matches === null) return null;
|
|
20987
21207
|
if (matches.length === 0) {
|
|
20988
|
-
return /* @__PURE__ */
|
|
21208
|
+
return /* @__PURE__ */ React27.createElement(Box22, { flexDirection: "column", paddingX: 1, marginTop: 1 }, headerRow, /* @__PURE__ */ React27.createElement(Box22, null, /* @__PURE__ */ React27.createElement(Text22, { color: COLOR.warn, bold: true }, GLYPH.warn), /* @__PURE__ */ React27.createElement(Text22, { color: COLOR.warn }, ` no match for "${partial}"`), /* @__PURE__ */ React27.createElement(Text22, { dimColor: true }, " \u2014 keep typing, or Backspace to edit")));
|
|
20989
21209
|
}
|
|
20990
21210
|
const MAX = 8;
|
|
20991
21211
|
const total = matches.length;
|
|
@@ -20993,22 +21213,22 @@ function SlashArgPicker({
|
|
|
20993
21213
|
const shown = matches.slice(windowStart, windowStart + MAX);
|
|
20994
21214
|
const hiddenAbove = windowStart;
|
|
20995
21215
|
const hiddenBelow = total - windowStart - shown.length;
|
|
20996
|
-
return /* @__PURE__ */
|
|
21216
|
+
return /* @__PURE__ */ React27.createElement(Box22, { flexDirection: "column", paddingX: 1, marginTop: 1 }, headerRow, hiddenAbove > 0 ? /* @__PURE__ */ React27.createElement(Text22, { dimColor: true }, ` \u2191 ${hiddenAbove} above`) : null, shown.map((value, i) => /* @__PURE__ */ React27.createElement(ArgRow, { key: value, value, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React27.createElement(Text22, { dimColor: true }, ` \u2193 ${hiddenBelow} below`) : null, /* @__PURE__ */ React27.createElement(Box22, { marginTop: 0 }, /* @__PURE__ */ React27.createElement(Text22, { dimColor: true }, " \u2191\u2193 navigate \xB7 Tab / \u23CE pick \xB7 esc cancel")));
|
|
20997
21217
|
}
|
|
20998
21218
|
function ArgRow({ value, isSelected }) {
|
|
20999
|
-
return /* @__PURE__ */
|
|
21219
|
+
return /* @__PURE__ */ React27.createElement(Box22, null, /* @__PURE__ */ React27.createElement(Text22, { color: isSelected ? COLOR.primary : COLOR.info, bold: isSelected }, isSelected ? `${GLYPH.cur} ` : " "), /* @__PURE__ */ React27.createElement(Text22, { color: isSelected ? COLOR.user : COLOR.info, bold: isSelected, dimColor: !isSelected }, value));
|
|
21000
21220
|
}
|
|
21001
21221
|
|
|
21002
21222
|
// src/cli/ui/SlashSuggestions.tsx
|
|
21003
|
-
import { Box as
|
|
21004
|
-
import
|
|
21223
|
+
import { Box as Box23, Text as Text23 } from "ink";
|
|
21224
|
+
import React28 from "react";
|
|
21005
21225
|
function SlashSuggestions({
|
|
21006
21226
|
matches,
|
|
21007
21227
|
selectedIndex
|
|
21008
21228
|
}) {
|
|
21009
21229
|
if (matches === null) return null;
|
|
21010
21230
|
if (matches.length === 0) {
|
|
21011
|
-
return /* @__PURE__ */
|
|
21231
|
+
return /* @__PURE__ */ React28.createElement(Box23, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React28.createElement(Text23, { color: COLOR.warn, bold: true }, GLYPH.warn), /* @__PURE__ */ React28.createElement(Text23, null, " "), /* @__PURE__ */ React28.createElement(Text23, { color: COLOR.warn }, "no slash command matches that prefix"), /* @__PURE__ */ React28.createElement(Text23, { dimColor: true }, " \u2014 Backspace to edit, or /help for the full list"));
|
|
21012
21232
|
}
|
|
21013
21233
|
const MAX = 8;
|
|
21014
21234
|
const total = matches.length;
|
|
@@ -21016,7 +21236,7 @@ function SlashSuggestions({
|
|
|
21016
21236
|
const shown = matches.slice(windowStart, windowStart + MAX);
|
|
21017
21237
|
const hiddenAbove = windowStart;
|
|
21018
21238
|
const hiddenBelow = total - windowStart - shown.length;
|
|
21019
|
-
return /* @__PURE__ */
|
|
21239
|
+
return /* @__PURE__ */ React28.createElement(Box23, { flexDirection: "column", paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React28.createElement(Box23, null, /* @__PURE__ */ React28.createElement(Text23, { color: COLOR.accent, bold: true }, "/ "), /* @__PURE__ */ React28.createElement(Text23, { dimColor: true }, `${total} command${total === 1 ? "" : "s"}`), hiddenAbove > 0 ? /* @__PURE__ */ React28.createElement(Text23, { dimColor: true }, ` \u2191 ${hiddenAbove} above`) : null), shown.map((spec, i) => /* @__PURE__ */ React28.createElement(SuggestionRow, { key: spec.cmd, spec, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React28.createElement(Text23, { dimColor: true }, ` \u2193 ${hiddenBelow} below`) : null, /* @__PURE__ */ React28.createElement(Box23, { marginTop: 0 }, /* @__PURE__ */ React28.createElement(Text23, { dimColor: true }, " \u2191\u2193 navigate \xB7 Tab / \u23CE pick \xB7 esc cancel")));
|
|
21020
21240
|
}
|
|
21021
21241
|
function SuggestionRow({ spec, isSelected }) {
|
|
21022
21242
|
const name = `/${spec.cmd}`;
|
|
@@ -21025,22 +21245,23 @@ function SuggestionRow({ spec, isSelected }) {
|
|
|
21025
21245
|
const translated = t(key);
|
|
21026
21246
|
const summary = translated === key ? spec.summary : translated;
|
|
21027
21247
|
const aliasHint = spec.aliases?.length ? ` \xB7 /${spec.aliases.join(" /")}` : "";
|
|
21028
|
-
return /* @__PURE__ */
|
|
21248
|
+
return /* @__PURE__ */ React28.createElement(Box23, null, /* @__PURE__ */ React28.createElement(Text23, { color: isSelected ? COLOR.primary : COLOR.info, bold: isSelected }, isSelected ? `${GLYPH.cur} ` : " "), /* @__PURE__ */ React28.createElement(Text23, { color: COLOR.accent, bold: isSelected }, name.padEnd(14)), /* @__PURE__ */ React28.createElement(Text23, { dimColor: true }, argsSuffix.padEnd(14)), /* @__PURE__ */ React28.createElement(Text23, null, " "), /* @__PURE__ */ React28.createElement(Text23, { color: isSelected ? COLOR.user : COLOR.info, dimColor: !isSelected }, summary), aliasHint ? /* @__PURE__ */ React28.createElement(Text23, { dimColor: true }, aliasHint) : null);
|
|
21029
21249
|
}
|
|
21030
21250
|
|
|
21031
21251
|
// src/cli/ui/WelcomeBanner.tsx
|
|
21032
|
-
import { Box as
|
|
21033
|
-
import
|
|
21252
|
+
import { Box as Box24, Text as Text24 } from "ink";
|
|
21253
|
+
import React29 from "react";
|
|
21034
21254
|
var HINTS = ["/help", "/init", "/memory", "/cost"];
|
|
21035
21255
|
function WelcomeBanner({
|
|
21036
21256
|
inCodeMode,
|
|
21257
|
+
workspaceRoot,
|
|
21037
21258
|
dashboardUrl
|
|
21038
21259
|
}) {
|
|
21039
21260
|
const tagline = inCodeMode ? t("ui.taglineCode") : t("ui.taglineChat");
|
|
21040
21261
|
const taglineSub = t("ui.taglineSub");
|
|
21041
21262
|
const startTextRaw = t("ui.startSessionHint");
|
|
21042
|
-
return /* @__PURE__ */
|
|
21043
|
-
|
|
21263
|
+
return /* @__PURE__ */ React29.createElement(Box24, { flexDirection: "column", alignItems: "center", marginY: 1 }, /* @__PURE__ */ React29.createElement(
|
|
21264
|
+
Box24,
|
|
21044
21265
|
{
|
|
21045
21266
|
flexDirection: "column",
|
|
21046
21267
|
alignItems: "center",
|
|
@@ -21049,9 +21270,9 @@ function WelcomeBanner({
|
|
|
21049
21270
|
paddingX: 4,
|
|
21050
21271
|
paddingY: 1
|
|
21051
21272
|
},
|
|
21052
|
-
/* @__PURE__ */
|
|
21053
|
-
/* @__PURE__ */
|
|
21054
|
-
), /* @__PURE__ */
|
|
21273
|
+
/* @__PURE__ */ React29.createElement(Box24, { flexDirection: "row", gap: 2 }, /* @__PURE__ */ React29.createElement(Text24, { color: TONE.brand, bold: true }, "REASONIX"), /* @__PURE__ */ React29.createElement(Text24, { color: FG.faint }, "\xD7"), /* @__PURE__ */ React29.createElement(Box24, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React29.createElement(Text24, null, "\u{1F40B}"), /* @__PURE__ */ React29.createElement(Text24, { color: TONE.accent, bold: true }, "DeepSeek"))),
|
|
21274
|
+
/* @__PURE__ */ React29.createElement(Box24, { marginTop: 1, flexDirection: "column", alignItems: "center" }, /* @__PURE__ */ React29.createElement(Text24, { color: FG.body }, tagline), /* @__PURE__ */ React29.createElement(Text24, { color: FG.meta }, taglineSub))
|
|
21275
|
+
), /* @__PURE__ */ React29.createElement(Box24, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: FG.sub }, startTextRaw)), /* @__PURE__ */ React29.createElement(Box24, { marginTop: 1, flexDirection: "row", gap: 3 }, HINTS.map((cmd) => /* @__PURE__ */ React29.createElement(Text24, { key: cmd, color: FG.meta }, cmd))), inCodeMode && workspaceRoot ? /* @__PURE__ */ React29.createElement(Box24, { marginTop: 1, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: TONE.brand }, "\u25B8 workspace"), /* @__PURE__ */ React29.createElement(Text24, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React29.createElement(Text24, { color: FG.body }, workspaceRoot), /* @__PURE__ */ React29.createElement(Text24, { color: FG.faint }, " (relaunch with --dir <path> to switch)")) : null, dashboardUrl ? /* @__PURE__ */ React29.createElement(Box24, { marginTop: 1, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: TONE.brand, bold: true }, "\u25B8 web"), /* @__PURE__ */ React29.createElement(Text24, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React29.createElement(Text24, { color: TONE.accent }, dashboardUrl)) : null);
|
|
21055
21276
|
}
|
|
21056
21277
|
|
|
21057
21278
|
// src/cli/ui/bang.ts
|
|
@@ -21437,12 +21658,12 @@ function useAgentSession({
|
|
|
21437
21658
|
}
|
|
21438
21659
|
|
|
21439
21660
|
// src/cli/ui/hooks/useChatScroll.ts
|
|
21440
|
-
import { useCallback as useCallback2, useEffect as useEffect4, useState as
|
|
21661
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useState as useState14 } from "react";
|
|
21441
21662
|
var SCROLL_PAGE_ROWS = 3;
|
|
21442
21663
|
function useChatScroll() {
|
|
21443
|
-
const [scrollRows, setScrollRows] =
|
|
21444
|
-
const [pinned, setPinned] =
|
|
21445
|
-
const [maxScroll, setMaxScrollState] =
|
|
21664
|
+
const [scrollRows, setScrollRows] = useState14(0);
|
|
21665
|
+
const [pinned, setPinned] = useState14(true);
|
|
21666
|
+
const [maxScroll, setMaxScrollState] = useState14(0);
|
|
21446
21667
|
useEffect4(() => {
|
|
21447
21668
|
if (pinned) setScrollRows(maxScroll);
|
|
21448
21669
|
}, [pinned, maxScroll]);
|
|
@@ -21545,10 +21766,10 @@ function useInputRecall(setInput) {
|
|
|
21545
21766
|
}
|
|
21546
21767
|
|
|
21547
21768
|
// src/cli/ui/hooks/useLoopMode.ts
|
|
21548
|
-
import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef4, useState as
|
|
21769
|
+
import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef4, useState as useState15 } from "react";
|
|
21549
21770
|
function useLoopMode(opts) {
|
|
21550
21771
|
const { log, busyRef, handleSubmitRef } = opts;
|
|
21551
|
-
const [activeLoop, setActiveLoop] =
|
|
21772
|
+
const [activeLoop, setActiveLoop] = useState15(null);
|
|
21552
21773
|
const activeLoopRef = useRef4(null);
|
|
21553
21774
|
const loopTimerRef = useRef4(null);
|
|
21554
21775
|
const loopFiringRef = useRef4(false);
|
|
@@ -21651,7 +21872,7 @@ function useQuit(transcriptRef) {
|
|
|
21651
21872
|
import { useMemo as useMemo5 } from "react";
|
|
21652
21873
|
|
|
21653
21874
|
// src/cli/ui/state/provider.tsx
|
|
21654
|
-
import
|
|
21875
|
+
import React30 from "react";
|
|
21655
21876
|
|
|
21656
21877
|
// src/cli/ui/state/reducer.ts
|
|
21657
21878
|
function reduce(state, event) {
|
|
@@ -21741,6 +21962,8 @@ function reduce(state, event) {
|
|
|
21741
21962
|
return { ...state, lang: event.lang };
|
|
21742
21963
|
case "session.update":
|
|
21743
21964
|
return { ...state, status: { ...state.status, ...event.patch } };
|
|
21965
|
+
case "session.model.change":
|
|
21966
|
+
return state.session.model === event.model ? state : { ...state, session: { ...state.session, model: event.model } };
|
|
21744
21967
|
case "focus.move":
|
|
21745
21968
|
return {
|
|
21746
21969
|
...state,
|
|
@@ -22030,26 +22253,26 @@ function createStore(session, initialCards) {
|
|
|
22030
22253
|
}
|
|
22031
22254
|
|
|
22032
22255
|
// src/cli/ui/state/provider.tsx
|
|
22033
|
-
var StoreCtx =
|
|
22256
|
+
var StoreCtx = React30.createContext(null);
|
|
22034
22257
|
function AgentStoreProvider({
|
|
22035
22258
|
session,
|
|
22036
22259
|
initialCards,
|
|
22037
22260
|
children
|
|
22038
22261
|
}) {
|
|
22039
|
-
const initialCardsRef =
|
|
22040
|
-
const store =
|
|
22041
|
-
return /* @__PURE__ */
|
|
22262
|
+
const initialCardsRef = React30.useRef(initialCards);
|
|
22263
|
+
const store = React30.useMemo(() => createStore(session, initialCardsRef.current), [session]);
|
|
22264
|
+
return /* @__PURE__ */ React30.createElement(StoreCtx.Provider, { value: store }, children);
|
|
22042
22265
|
}
|
|
22043
22266
|
function useAgentStore() {
|
|
22044
|
-
const store =
|
|
22267
|
+
const store = React30.useContext(StoreCtx);
|
|
22045
22268
|
if (!store) throw new Error("useAgentStore must be used inside AgentStoreProvider");
|
|
22046
22269
|
return store;
|
|
22047
22270
|
}
|
|
22048
22271
|
function useAgentState(selector) {
|
|
22049
22272
|
const store = useAgentStore();
|
|
22050
|
-
const subscribe =
|
|
22051
|
-
const getSnapshot =
|
|
22052
|
-
return
|
|
22273
|
+
const subscribe = React30.useCallback((cb) => store.subscribe(cb), [store]);
|
|
22274
|
+
const getSnapshot = React30.useCallback(() => selector(store.getState()), [store, selector]);
|
|
22275
|
+
return React30.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
22053
22276
|
}
|
|
22054
22277
|
function useDispatch() {
|
|
22055
22278
|
return useAgentStore().dispatch;
|
|
@@ -22289,21 +22512,21 @@ function useTranscriptWriter(transcriptRef, model2, prefixHash) {
|
|
|
22289
22512
|
}
|
|
22290
22513
|
|
|
22291
22514
|
// src/cli/ui/layout/CardStream.tsx
|
|
22292
|
-
import { Box as
|
|
22293
|
-
import
|
|
22515
|
+
import { Box as Box44, Text as Text46, useBoxMetrics } from "ink";
|
|
22516
|
+
import React54, { useEffect as useEffect7, useRef as useRef5 } from "react";
|
|
22294
22517
|
|
|
22295
22518
|
// src/cli/ui/cards/CardRenderer.tsx
|
|
22296
|
-
import { Box as
|
|
22297
|
-
import
|
|
22519
|
+
import { Box as Box43, Text as Text45 } from "ink";
|
|
22520
|
+
import React53 from "react";
|
|
22298
22521
|
|
|
22299
22522
|
// src/cli/ui/cards/BranchCard.tsx
|
|
22300
|
-
import { Box as
|
|
22301
|
-
import
|
|
22523
|
+
import { Box as Box27, Text as Text26 } from "ink";
|
|
22524
|
+
import React33 from "react";
|
|
22302
22525
|
|
|
22303
22526
|
// src/cli/ui/primitives/Card.tsx
|
|
22304
|
-
import { Box as
|
|
22305
|
-
import
|
|
22306
|
-
var ActiveCardContext =
|
|
22527
|
+
import { Box as Box25 } from "ink";
|
|
22528
|
+
import React31, { useContext as useContext4 } from "react";
|
|
22529
|
+
var ActiveCardContext = React31.createContext(true);
|
|
22307
22530
|
var STRIPE_BORDER = {
|
|
22308
22531
|
topLeft: " ",
|
|
22309
22532
|
top: " ",
|
|
@@ -22317,10 +22540,10 @@ var STRIPE_BORDER = {
|
|
|
22317
22540
|
function Card({ tone, children }) {
|
|
22318
22541
|
const active = useContext4(ActiveCardContext);
|
|
22319
22542
|
if (!active) {
|
|
22320
|
-
return /* @__PURE__ */
|
|
22543
|
+
return /* @__PURE__ */ React31.createElement(Box25, { flexDirection: "column", marginTop: 1 }, children);
|
|
22321
22544
|
}
|
|
22322
|
-
return /* @__PURE__ */
|
|
22323
|
-
|
|
22545
|
+
return /* @__PURE__ */ React31.createElement(
|
|
22546
|
+
Box25,
|
|
22324
22547
|
{
|
|
22325
22548
|
flexDirection: "column",
|
|
22326
22549
|
borderStyle: STRIPE_BORDER,
|
|
@@ -22337,8 +22560,8 @@ function Card({ tone, children }) {
|
|
|
22337
22560
|
}
|
|
22338
22561
|
|
|
22339
22562
|
// src/cli/ui/primitives/CardHeader.tsx
|
|
22340
|
-
import { Box as
|
|
22341
|
-
import
|
|
22563
|
+
import { Box as Box26, Text as Text25 } from "ink";
|
|
22564
|
+
import React32 from "react";
|
|
22342
22565
|
function CardHeader({
|
|
22343
22566
|
glyph,
|
|
22344
22567
|
tone,
|
|
@@ -22349,13 +22572,13 @@ function CardHeader({
|
|
|
22349
22572
|
meta,
|
|
22350
22573
|
right
|
|
22351
22574
|
}) {
|
|
22352
|
-
return /* @__PURE__ */
|
|
22575
|
+
return /* @__PURE__ */ React32.createElement(Box26, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React32.createElement(Text25, { color: tone }, glyph), titleBg ? /* @__PURE__ */ React32.createElement(Text25, { backgroundColor: titleBg, color: titleColor ?? tone, bold: true }, ` ${title} `) : /* @__PURE__ */ React32.createElement(Text25, { bold: true, color: titleColor ?? tone }, title), subtitle ? /* @__PURE__ */ React32.createElement(Text25, { color: FG.body }, subtitle) : null, meta?.map((item, i) => {
|
|
22353
22576
|
const isStr = typeof item === "string";
|
|
22354
22577
|
const text = isStr ? item : item.text;
|
|
22355
22578
|
const color2 = isStr ? FG.faint : item.color;
|
|
22356
22579
|
return (
|
|
22357
22580
|
// biome-ignore lint/suspicious/noArrayIndexKey: meta items are positional
|
|
22358
|
-
/* @__PURE__ */
|
|
22581
|
+
/* @__PURE__ */ React32.createElement(React32.Fragment, { key: `m-${i}` }, /* @__PURE__ */ React32.createElement(Text25, { color: FG.faint }, "\xB7"), /* @__PURE__ */ React32.createElement(Text25, { color: color2 }, text))
|
|
22359
22582
|
);
|
|
22360
22583
|
}), right);
|
|
22361
22584
|
}
|
|
@@ -22366,7 +22589,7 @@ function BranchCard({ card }) {
|
|
|
22366
22589
|
const ratio = card.total > 0 ? card.completed / card.total : 0;
|
|
22367
22590
|
const filled = Math.max(0, Math.min(BAR_CELLS, Math.round(ratio * BAR_CELLS)));
|
|
22368
22591
|
const tone = card.done ? TONE.ok : CARD.branch.color;
|
|
22369
|
-
return /* @__PURE__ */
|
|
22592
|
+
return /* @__PURE__ */ React33.createElement(Card, { tone }, /* @__PURE__ */ React33.createElement(
|
|
22370
22593
|
CardHeader,
|
|
22371
22594
|
{
|
|
22372
22595
|
glyph: "\u2387",
|
|
@@ -22374,22 +22597,22 @@ function BranchCard({ card }) {
|
|
|
22374
22597
|
title: card.done ? "branching done" : "branching",
|
|
22375
22598
|
meta: [`${card.completed} of ${card.total} samples`]
|
|
22376
22599
|
}
|
|
22377
|
-
), /* @__PURE__ */
|
|
22600
|
+
), /* @__PURE__ */ React33.createElement(Box27, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React33.createElement(Text26, { color: tone }, "\u2588".repeat(filled)), /* @__PURE__ */ React33.createElement(Text26, { color: FG.faint }, "\u2591".repeat(BAR_CELLS - filled)), /* @__PURE__ */ React33.createElement(Text26, { color: FG.faint }, `${(ratio * 100).toFixed(0)}%`)), !card.done && card.completed > 0 ? /* @__PURE__ */ React33.createElement(Text26, { color: FG.faint }, `latest \xB7 #${card.latestIndex} \xB7 T=${card.latestTemperature.toFixed(2)} \xB7 ${card.latestUncertainties} unc`) : null);
|
|
22378
22601
|
}
|
|
22379
22602
|
|
|
22380
22603
|
// src/cli/ui/cards/CtxCard.tsx
|
|
22381
|
-
import { Box as
|
|
22382
|
-
import
|
|
22604
|
+
import { Box as Box28, Text as Text27 } from "ink";
|
|
22605
|
+
import React34 from "react";
|
|
22383
22606
|
var BAR_CELLS2 = 32;
|
|
22384
22607
|
function row2(label, tokens, ratio, color2) {
|
|
22385
22608
|
const filled = Math.max(0, Math.min(BAR_CELLS2, Math.round(ratio * BAR_CELLS2)));
|
|
22386
|
-
return /* @__PURE__ */
|
|
22609
|
+
return /* @__PURE__ */ React34.createElement(Box28, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React34.createElement(Text27, { color: FG.sub }, label.padEnd(7)), /* @__PURE__ */ React34.createElement(Text27, { color: color2 }, "\u2588".repeat(filled)), /* @__PURE__ */ React34.createElement(Text27, { color: FG.faint }, "\u2591".repeat(BAR_CELLS2 - filled)), /* @__PURE__ */ React34.createElement(Text27, { bold: true, color: FG.body }, tokens.toLocaleString()), /* @__PURE__ */ React34.createElement(Text27, { color: FG.faint }, `\xB7 ${(ratio * 100).toFixed(1)}%`));
|
|
22387
22610
|
}
|
|
22388
22611
|
function CtxCard({ card }) {
|
|
22389
22612
|
const cap = Math.max(1, card.ctxMax);
|
|
22390
22613
|
const used = card.systemTokens + card.toolsTokens + card.logTokens + card.inputTokens;
|
|
22391
22614
|
const usedPct = used / cap * 100;
|
|
22392
|
-
return /* @__PURE__ */
|
|
22615
|
+
return /* @__PURE__ */ React34.createElement(Card, { tone: TONE.brand }, /* @__PURE__ */ React34.createElement(
|
|
22393
22616
|
CardHeader,
|
|
22394
22617
|
{
|
|
22395
22618
|
glyph: "\u2318",
|
|
@@ -22397,12 +22620,12 @@ function CtxCard({ card }) {
|
|
|
22397
22620
|
title: "context",
|
|
22398
22621
|
meta: [`${used.toLocaleString()} / ${cap.toLocaleString()} (${usedPct.toFixed(1)}%)`]
|
|
22399
22622
|
}
|
|
22400
|
-
), row2("system", card.systemTokens, card.systemTokens / cap, TONE.brand), row2("tools", card.toolsTokens, card.toolsTokens / cap, TONE.warn), row2("log", card.logTokens, card.logTokens / cap, TONE.ok), row2("input", card.inputTokens, card.inputTokens / cap, TONE.accent), card.topTools.length > 0 ? /* @__PURE__ */
|
|
22623
|
+
), row2("system", card.systemTokens, card.systemTokens / cap, TONE.brand), row2("tools", card.toolsTokens, card.toolsTokens / cap, TONE.warn), row2("log", card.logTokens, card.logTokens / cap, TONE.ok), row2("input", card.inputTokens, card.inputTokens / cap, TONE.accent), card.topTools.length > 0 ? /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(Text27, { color: FG.faint }, `top tools \xB7 ${card.toolsCount} total \xB7 ${card.logMessages} log msgs`), card.topTools.slice(0, 5).map((t3) => /* @__PURE__ */ React34.createElement(Box28, { key: `${t3.turn}-${t3.name}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React34.createElement(Text27, { color: FG.sub }, t3.name), /* @__PURE__ */ React34.createElement(Text27, { color: FG.faint }, `\xB7 turn ${t3.turn} \xB7 ${t3.tokens.toLocaleString()}`)))) : null);
|
|
22401
22624
|
}
|
|
22402
22625
|
|
|
22403
22626
|
// src/cli/ui/cards/DiffCard.tsx
|
|
22404
|
-
import { Box as
|
|
22405
|
-
import
|
|
22627
|
+
import { Box as Box29, Text as Text28 } from "ink";
|
|
22628
|
+
import React35 from "react";
|
|
22406
22629
|
var LINE_COLOR = {
|
|
22407
22630
|
ctx: FG.sub,
|
|
22408
22631
|
add: TONE.ok,
|
|
@@ -22417,7 +22640,7 @@ var LINE_GLYPH = {
|
|
|
22417
22640
|
};
|
|
22418
22641
|
function DiffCard({ card }) {
|
|
22419
22642
|
const showFooter = card.hunks.length > 0;
|
|
22420
|
-
return /* @__PURE__ */
|
|
22643
|
+
return /* @__PURE__ */ React35.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ React35.createElement(
|
|
22421
22644
|
CardHeader,
|
|
22422
22645
|
{
|
|
22423
22646
|
glyph: "\xB1",
|
|
@@ -22429,12 +22652,12 @@ function DiffCard({ card }) {
|
|
|
22429
22652
|
{ text: `-${card.stats.del}`, color: TONE.err }
|
|
22430
22653
|
]
|
|
22431
22654
|
}
|
|
22432
|
-
), card.hunks.map((hunk) => /* @__PURE__ */
|
|
22655
|
+
), card.hunks.map((hunk) => /* @__PURE__ */ React35.createElement(Box29, { key: `${card.id}:${hunk.header}`, flexDirection: "column" }, /* @__PURE__ */ React35.createElement(Text28, { italic: true, color: FG.faint }, hunk.header), hunk.lines.map((line, li) => /* @__PURE__ */ React35.createElement(Box29, { key: `${card.id}:${hunk.header}:${li}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React35.createElement(Text28, { color: LINE_COLOR[line.kind] }, LINE_GLYPH[line.kind]), /* @__PURE__ */ React35.createElement(Text28, { color: LINE_COLOR[line.kind], dimColor: line.kind === "ctx" }, line.text))))), showFooter && /* @__PURE__ */ React35.createElement(Box29, { flexDirection: "row", gap: 2 }, /* @__PURE__ */ React35.createElement(Text28, { bold: true, color: TONE.ok }, "[a] apply"), /* @__PURE__ */ React35.createElement(Text28, { color: FG.sub }, "[s] skip"), /* @__PURE__ */ React35.createElement(Text28, { bold: true, color: TONE.err }, "[r] reject")));
|
|
22433
22656
|
}
|
|
22434
22657
|
|
|
22435
22658
|
// src/cli/ui/cards/DoctorCard.tsx
|
|
22436
|
-
import { Box as
|
|
22437
|
-
import
|
|
22659
|
+
import { Box as Box30, Text as Text29 } from "ink";
|
|
22660
|
+
import React36 from "react";
|
|
22438
22661
|
var LEVEL_COLOR = {
|
|
22439
22662
|
ok: TONE.ok,
|
|
22440
22663
|
warn: TONE.warn,
|
|
@@ -22456,12 +22679,12 @@ function DoctorCard({ card }) {
|
|
|
22456
22679
|
const fail = card.checks.filter((c) => c.level === "fail").length;
|
|
22457
22680
|
const labelWidth = card.checks.reduce((m, c) => Math.max(m, c.label.length), 0);
|
|
22458
22681
|
const summary = `${card.checks.length} checks \xB7 ${ok} passed${warn > 0 ? ` \xB7 ${warn} warn` : ""}${fail > 0 ? ` \xB7 ${fail} fail` : ""}`;
|
|
22459
|
-
return /* @__PURE__ */
|
|
22682
|
+
return /* @__PURE__ */ React36.createElement(Card, { tone: CARD.tool.color }, /* @__PURE__ */ React36.createElement(CardHeader, { glyph: "\u2695", tone: CARD.tool.color, title: "doctor", meta: [summary] }), card.checks.map((c) => /* @__PURE__ */ React36.createElement(Box30, { key: c.label, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React36.createElement(Text29, { color: LEVEL_COLOR[c.level] }, LEVEL_GLYPH[c.level]), /* @__PURE__ */ React36.createElement(Text29, { bold: true, color: FG.body }, c.label.padEnd(labelWidth + 1)), /* @__PURE__ */ React36.createElement(Text29, { color: FG.sub }, c.detail), /* @__PURE__ */ React36.createElement(Text29, { color: LEVEL_COLOR[c.level] }, LEVEL_TAG[c.level]))));
|
|
22460
22683
|
}
|
|
22461
22684
|
|
|
22462
22685
|
// src/cli/ui/cards/ErrorCard.tsx
|
|
22463
|
-
import { Box as
|
|
22464
|
-
import
|
|
22686
|
+
import { Box as Box31, Text as Text30 } from "ink";
|
|
22687
|
+
import React37 from "react";
|
|
22465
22688
|
var STACK_TAIL = 5;
|
|
22466
22689
|
function ErrorCard({ card }) {
|
|
22467
22690
|
const retryNote = card.retries !== void 0 && card.retries > 0 ? `${card.retries} retr${card.retries === 1 ? "y" : "ies"}` : null;
|
|
@@ -22471,7 +22694,7 @@ function ErrorCard({ card }) {
|
|
|
22471
22694
|
const stackHidden = stackTrunc ? stackLines.length - stackVisible.length : 0;
|
|
22472
22695
|
const hasStack = stackVisible.length > 0;
|
|
22473
22696
|
const messageLines = card.message.split("\n");
|
|
22474
|
-
return /* @__PURE__ */
|
|
22697
|
+
return /* @__PURE__ */ React37.createElement(Card, { tone: TONE.err }, /* @__PURE__ */ React37.createElement(
|
|
22475
22698
|
CardHeader,
|
|
22476
22699
|
{
|
|
22477
22700
|
glyph: "\u2716",
|
|
@@ -22479,16 +22702,16 @@ function ErrorCard({ card }) {
|
|
|
22479
22702
|
title: card.title || "error",
|
|
22480
22703
|
meta: retryNote ? [retryNote] : void 0
|
|
22481
22704
|
}
|
|
22482
|
-
), messageLines.map((line, i) => /* @__PURE__ */
|
|
22705
|
+
), messageLines.map((line, i) => /* @__PURE__ */ React37.createElement(Text30, { key: `${card.id}:msg:${i}`, color: TONE.err }, line || " ")), hasStack ? /* @__PURE__ */ React37.createElement(Box31, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React37.createElement(Text30, { color: FG.meta }, "stack trace"), stackHidden > 0 ? /* @__PURE__ */ React37.createElement(Text30, { color: FG.faint }, `\u22EE ${stackHidden} earlier stack line${stackHidden === 1 ? "" : "s"} hidden`) : null, stackVisible.map((line, i) => /* @__PURE__ */ React37.createElement(Text30, { key: `${card.id}:stk:${stackHidden + i}`, color: FG.meta }, line || " "))) : null);
|
|
22483
22706
|
}
|
|
22484
22707
|
|
|
22485
22708
|
// src/cli/ui/cards/LiveCard.tsx
|
|
22486
|
-
import { Box as
|
|
22487
|
-
import
|
|
22709
|
+
import { Box as Box32, Text as Text32 } from "ink";
|
|
22710
|
+
import React39 from "react";
|
|
22488
22711
|
|
|
22489
22712
|
// src/cli/ui/primitives/Spinner.tsx
|
|
22490
|
-
import { Text as
|
|
22491
|
-
import
|
|
22713
|
+
import { Text as Text31 } from "ink";
|
|
22714
|
+
import React38 from "react";
|
|
22492
22715
|
var FRAMES = {
|
|
22493
22716
|
circle: ["\u25D0", "\u25D3", "\u25D1", "\u25D2"],
|
|
22494
22717
|
braille: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827"]
|
|
@@ -22497,7 +22720,7 @@ function Spinner({ kind = "circle", color: color2, bold }) {
|
|
|
22497
22720
|
const frames = FRAMES[kind];
|
|
22498
22721
|
const tick = useTick();
|
|
22499
22722
|
const frame = tick % frames.length;
|
|
22500
|
-
return /* @__PURE__ */
|
|
22723
|
+
return /* @__PURE__ */ React38.createElement(Text31, { bold, color: color2 }, frames[frame]);
|
|
22501
22724
|
}
|
|
22502
22725
|
|
|
22503
22726
|
// src/cli/ui/cards/LiveCard.tsx
|
|
@@ -22524,12 +22747,12 @@ var VARIANT_GLYPH = {
|
|
|
22524
22747
|
function LiveCard({ card }) {
|
|
22525
22748
|
const color2 = TONE_TO_COLOR[card.tone];
|
|
22526
22749
|
const glyph = VARIANT_GLYPH[card.variant];
|
|
22527
|
-
return /* @__PURE__ */
|
|
22750
|
+
return /* @__PURE__ */ React39.createElement(Box32, { paddingLeft: 2, flexDirection: "row", gap: 1 }, card.variant === "thinking" ? /* @__PURE__ */ React39.createElement(Spinner, { kind: "circle", color: color2, bold: true }) : /* @__PURE__ */ React39.createElement(Text32, { bold: true, color: color2 }, glyph), /* @__PURE__ */ React39.createElement(Text32, { color: FG.body }, card.text), card.meta !== void 0 ? /* @__PURE__ */ React39.createElement(Text32, { color: FG.faint }, `\xB7 ${card.meta}`) : null);
|
|
22528
22751
|
}
|
|
22529
22752
|
|
|
22530
22753
|
// src/cli/ui/cards/MemoryCard.tsx
|
|
22531
|
-
import { Box as
|
|
22532
|
-
import
|
|
22754
|
+
import { Box as Box33, Text as Text33 } from "ink";
|
|
22755
|
+
import React40 from "react";
|
|
22533
22756
|
var CATEGORY_ORDER = [
|
|
22534
22757
|
"user",
|
|
22535
22758
|
"feedback",
|
|
@@ -22558,7 +22781,7 @@ function MemoryCard({ card }) {
|
|
|
22558
22781
|
const counts = countByCategory(card.entries);
|
|
22559
22782
|
const summary = CATEGORY_ORDER.filter((c) => counts[c] > 0).map((c) => `${counts[c]} ${c}`).join(" \xB7 ");
|
|
22560
22783
|
const tokens = card.tokens > 1024 ? `~${(card.tokens / 1024).toFixed(1)}K tok` : `~${card.tokens} tok`;
|
|
22561
|
-
return /* @__PURE__ */
|
|
22784
|
+
return /* @__PURE__ */ React40.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ React40.createElement(
|
|
22562
22785
|
CardHeader,
|
|
22563
22786
|
{
|
|
22564
22787
|
glyph: "\u2311",
|
|
@@ -22571,7 +22794,7 @@ function MemoryCard({ card }) {
|
|
|
22571
22794
|
const all = card.entries.filter((e) => e.category === category);
|
|
22572
22795
|
const shown = all.slice(0, 5);
|
|
22573
22796
|
const remaining = all.length - shown.length;
|
|
22574
|
-
return /* @__PURE__ */
|
|
22797
|
+
return /* @__PURE__ */ React40.createElement(Box33, { key: category, flexDirection: "column" }, /* @__PURE__ */ React40.createElement(Text33, { color: FG.faint }, `${CATEGORY_LABEL[category]} (${counts[category]})`), shown.map((entry) => /* @__PURE__ */ React40.createElement(Box33, { key: `${category}:${entry.summary}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React40.createElement(Text33, { color: CATEGORY_GLYPH_COLOR[category] }, CATEGORY_GLYPH[category]), /* @__PURE__ */ React40.createElement(Text33, { color: FG.sub }, entry.summary))), remaining > 0 ? /* @__PURE__ */ React40.createElement(Text33, { color: FG.faint }, `\u22EE +${remaining} more`) : null);
|
|
22575
22798
|
}));
|
|
22576
22799
|
}
|
|
22577
22800
|
function countByCategory(entries) {
|
|
@@ -22586,8 +22809,8 @@ function countByCategory(entries) {
|
|
|
22586
22809
|
}
|
|
22587
22810
|
|
|
22588
22811
|
// src/cli/ui/cards/PlanCard.tsx
|
|
22589
|
-
import { Box as
|
|
22590
|
-
import
|
|
22812
|
+
import { Box as Box34, Text as Text34 } from "ink";
|
|
22813
|
+
import React41 from "react";
|
|
22591
22814
|
var STATUS_GLYPH = {
|
|
22592
22815
|
queued: "\u25CB",
|
|
22593
22816
|
running: "\u25B6",
|
|
@@ -22612,11 +22835,11 @@ function PlanCard({ card }) {
|
|
|
22612
22835
|
const hasRunning = card.steps.some((s) => s.status === "running");
|
|
22613
22836
|
const tone = hasRunning ? TONE_ACTIVE.accent : TONE.accent;
|
|
22614
22837
|
const window = pickWindow(card.steps);
|
|
22615
|
-
return /* @__PURE__ */
|
|
22838
|
+
return /* @__PURE__ */ React41.createElement(Card, { tone }, /* @__PURE__ */ React41.createElement(CardHeader, { glyph: "\u229E", tone, title: card.title, meta: [progress] }), window.hiddenBefore > 0 ? /* @__PURE__ */ React41.createElement(Box34, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React41.createElement(Text34, { color: TONE.ok }, "\u2713"), /* @__PURE__ */ React41.createElement(Text34, { color: FG.faint }, `\u22EF ${window.hiddenBefore} done`)) : null, window.steps.map((step) => {
|
|
22616
22839
|
const isActive = step.status === "running";
|
|
22617
22840
|
const titleColor = isActive ? FG.strong : FG.sub;
|
|
22618
|
-
return /* @__PURE__ */
|
|
22619
|
-
}), window.hiddenAfter > 0 ? /* @__PURE__ */
|
|
22841
|
+
return /* @__PURE__ */ React41.createElement(Box34, { key: step.id, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React41.createElement(Text34, { color: STATUS_COLOR[step.status] }, STATUS_GLYPH[step.status]), /* @__PURE__ */ React41.createElement(Text34, { bold: isActive, color: titleColor }, `${step.indexLabel}. ${step.title}`), isActive ? /* @__PURE__ */ React41.createElement(Text34, { color: TONE_ACTIVE.brand }, "\u2190 in progress") : null);
|
|
22842
|
+
}), window.hiddenAfter > 0 ? /* @__PURE__ */ React41.createElement(Box34, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React41.createElement(Text34, { color: FG.faint }, "\u25CB"), /* @__PURE__ */ React41.createElement(Text34, { color: FG.faint }, `\u22EF ${window.hiddenAfter} upcoming`)) : null);
|
|
22620
22843
|
}
|
|
22621
22844
|
function pickWindow(steps) {
|
|
22622
22845
|
if (steps.length <= VISIBLE_WINDOW) {
|
|
@@ -22644,8 +22867,8 @@ function anchorIndex(steps) {
|
|
|
22644
22867
|
}
|
|
22645
22868
|
|
|
22646
22869
|
// src/cli/ui/cards/ReasoningCard.tsx
|
|
22647
|
-
import { Box as
|
|
22648
|
-
import
|
|
22870
|
+
import { Box as Box35, Text as Text36, useStdout as useStdout7 } from "ink";
|
|
22871
|
+
import React43 from "react";
|
|
22649
22872
|
|
|
22650
22873
|
// src/frame/width.ts
|
|
22651
22874
|
import stringWidthLib from "string-width";
|
|
@@ -22696,44 +22919,12 @@ function wrapToCells(s, maxCells) {
|
|
|
22696
22919
|
}
|
|
22697
22920
|
|
|
22698
22921
|
// src/cli/ui/primitives/CursorBlock.tsx
|
|
22699
|
-
import { Text as
|
|
22700
|
-
import
|
|
22922
|
+
import { Text as Text35 } from "ink";
|
|
22923
|
+
import React42 from "react";
|
|
22701
22924
|
function CursorBlock() {
|
|
22702
22925
|
const tick = useTick();
|
|
22703
22926
|
const on = Math.floor(tick / 4) % 2 === 0;
|
|
22704
|
-
return /* @__PURE__ */
|
|
22705
|
-
}
|
|
22706
|
-
|
|
22707
|
-
// src/cli/ui/primitives/Pill.tsx
|
|
22708
|
-
import { Text as Text34 } from "ink";
|
|
22709
|
-
import React41 from "react";
|
|
22710
|
-
function Pill({ label, bg, fg, bold = true }) {
|
|
22711
|
-
return /* @__PURE__ */ React41.createElement(Text34, { backgroundColor: bg, color: fg, bold }, ` ${label} `);
|
|
22712
|
-
}
|
|
22713
|
-
var PILL_SECTION = {
|
|
22714
|
-
reason: { bg: "#2a1f3d", fg: "#d2a8ff" },
|
|
22715
|
-
output: { bg: "#0d1d2e", fg: "#79c0ff" },
|
|
22716
|
-
tool: { bg: "#0f2230", fg: "#79c0ff" },
|
|
22717
|
-
shell: { bg: "#0f2230", fg: "#79c0ff" },
|
|
22718
|
-
task: { bg: "#0d1d2e", fg: "#79c0ff" },
|
|
22719
|
-
taskDone: { bg: "#102815", fg: "#7ee787" },
|
|
22720
|
-
taskFailed: { bg: "#2c1416", fg: "#ff8b81" },
|
|
22721
|
-
plan: { bg: "#2a1f3d", fg: "#d2a8ff" },
|
|
22722
|
-
user: { bg: "#11141a", fg: "#8b949e" }
|
|
22723
|
-
};
|
|
22724
|
-
var PILL_MODEL = {
|
|
22725
|
-
flash: { bg: "#11141a", fg: "#79c0ff" },
|
|
22726
|
-
pro: { bg: "#11141a", fg: "#d2a8ff" },
|
|
22727
|
-
r1: { bg: "#11141a", fg: "#b395f5" },
|
|
22728
|
-
unknown: { bg: "#11141a", fg: "#8b949e" }
|
|
22729
|
-
};
|
|
22730
|
-
function modelBadgeFor(model2) {
|
|
22731
|
-
if (!model2) return { label: "?", kind: "unknown" };
|
|
22732
|
-
const stripped = model2.replace(/^deepseek-/, "");
|
|
22733
|
-
if (stripped === "v4-flash" || stripped === "chat") return { label: "v4-flash", kind: "flash" };
|
|
22734
|
-
if (stripped === "v4-pro") return { label: "v4-pro", kind: "pro" };
|
|
22735
|
-
if (stripped === "r1" || stripped === "reasoner") return { label: "r1", kind: "r1" };
|
|
22736
|
-
return { label: stripped, kind: "unknown" };
|
|
22927
|
+
return /* @__PURE__ */ React42.createElement(Text35, { inverse: on, color: CARD.streaming.color }, " ");
|
|
22737
22928
|
}
|
|
22738
22929
|
|
|
22739
22930
|
// src/cli/ui/cards/ReasoningCard.tsx
|
|
@@ -22743,13 +22934,13 @@ function ReasoningCard({
|
|
|
22743
22934
|
card,
|
|
22744
22935
|
expanded
|
|
22745
22936
|
}) {
|
|
22746
|
-
const { stdout: stdout4 } =
|
|
22937
|
+
const { stdout: stdout4 } = useStdout7();
|
|
22747
22938
|
const cols = stdout4?.columns ?? 80;
|
|
22748
22939
|
const lineCells = Math.max(20, cols - 4);
|
|
22749
22940
|
const allLines = card.text.length > 0 ? card.text.split("\n") : [];
|
|
22750
22941
|
const showBody = expanded && (allLines.length > 0 || card.streaming);
|
|
22751
22942
|
const tone = card.aborted ? TONE.err : card.streaming ? TONE_ACTIVE.accent : TONE.accent;
|
|
22752
|
-
return /* @__PURE__ */
|
|
22943
|
+
return /* @__PURE__ */ React43.createElement(Card, { tone }, /* @__PURE__ */ React43.createElement(ReasoningHeader, { card }), showBody && (card.streaming ? /* @__PURE__ */ React43.createElement(StreamingPreview, { card, allLines, lineCells }) : /* @__PURE__ */ React43.createElement(SettledPreview, { card, allLines, lineCells })));
|
|
22753
22944
|
}
|
|
22754
22945
|
function ReasoningHeader({ card }) {
|
|
22755
22946
|
const streamingActive = card.streaming && !card.aborted;
|
|
@@ -22762,7 +22953,7 @@ function ReasoningHeader({ card }) {
|
|
|
22762
22953
|
const duration = headerDuration(card);
|
|
22763
22954
|
if (duration) meta.push(duration);
|
|
22764
22955
|
const modelBadge = card.model ? modelBadgeFor(card.model) : null;
|
|
22765
|
-
return /* @__PURE__ */
|
|
22956
|
+
return /* @__PURE__ */ React43.createElement(
|
|
22766
22957
|
CardHeader,
|
|
22767
22958
|
{
|
|
22768
22959
|
glyph,
|
|
@@ -22771,7 +22962,7 @@ function ReasoningHeader({ card }) {
|
|
|
22771
22962
|
titleColor: PILL_SECTION.reason.fg,
|
|
22772
22963
|
titleBg: PILL_SECTION.reason.bg,
|
|
22773
22964
|
meta: meta.length > 0 ? meta : void 0,
|
|
22774
|
-
right: /* @__PURE__ */
|
|
22965
|
+
right: /* @__PURE__ */ React43.createElement(React43.Fragment, null, streamingActive ? /* @__PURE__ */ React43.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.accent }) : null, modelBadge ? /* @__PURE__ */ React43.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null)
|
|
22775
22966
|
}
|
|
22776
22967
|
);
|
|
22777
22968
|
}
|
|
@@ -22792,13 +22983,13 @@ function headerDuration(card) {
|
|
|
22792
22983
|
function StreamingPreview({ card, allLines, lineCells }) {
|
|
22793
22984
|
const visualLines = allLines.flatMap((l) => wrapToCells(l, lineCells));
|
|
22794
22985
|
const visible = visualLines.slice(-STREAMING_PREVIEW_LINES);
|
|
22795
|
-
return /* @__PURE__ */
|
|
22986
|
+
return /* @__PURE__ */ React43.createElement(BodyLines, { card, lines: visible, lineCells, cursorOnLast: true });
|
|
22796
22987
|
}
|
|
22797
22988
|
function SettledPreview({ card, allLines, lineCells }) {
|
|
22798
22989
|
const visualLines = allLines.flatMap((l) => wrapToCells(l, lineCells));
|
|
22799
22990
|
const visible = visualLines.slice(-SETTLED_TAIL_LINES);
|
|
22800
22991
|
const droppedLines = Math.max(0, visualLines.length - visible.length);
|
|
22801
|
-
return /* @__PURE__ */
|
|
22992
|
+
return /* @__PURE__ */ React43.createElement(React43.Fragment, null, droppedLines > 0 ? /* @__PURE__ */ React43.createElement(ElisionHint, { droppedLines, card }) : null, /* @__PURE__ */ React43.createElement(BodyLines, { card, lines: visible, lineCells, indexOffset: droppedLines }));
|
|
22802
22993
|
}
|
|
22803
22994
|
function BodyLines({
|
|
22804
22995
|
card,
|
|
@@ -22807,9 +22998,9 @@ function BodyLines({
|
|
|
22807
22998
|
cursorOnLast = false,
|
|
22808
22999
|
indexOffset = 0
|
|
22809
23000
|
}) {
|
|
22810
|
-
return /* @__PURE__ */
|
|
23001
|
+
return /* @__PURE__ */ React43.createElement(React43.Fragment, null, lines.map((line, i) => {
|
|
22811
23002
|
const isLast = i === lines.length - 1;
|
|
22812
|
-
return /* @__PURE__ */
|
|
23003
|
+
return /* @__PURE__ */ React43.createElement(Box35, { key: `${card.id}:b:${indexOffset + i}`, flexDirection: "row" }, /* @__PURE__ */ React43.createElement(Text36, { italic: true, color: FG.meta }, clipToCells(line, lineCells)), isLast && cursorOnLast && /* @__PURE__ */ React43.createElement(CursorBlock, null));
|
|
22813
23004
|
}));
|
|
22814
23005
|
}
|
|
22815
23006
|
function ElisionHint({
|
|
@@ -22823,18 +23014,18 @@ function ElisionHint({
|
|
|
22823
23014
|
parts.push(`${droppedLines} line${droppedLines === 1 ? "" : "s"}`);
|
|
22824
23015
|
}
|
|
22825
23016
|
if (card.tokens > 0) parts.push(`${card.tokens.toLocaleString()} tok`);
|
|
22826
|
-
return /* @__PURE__ */
|
|
23017
|
+
return /* @__PURE__ */ React43.createElement(Text36, { color: FG.faint }, `\u22EF ${parts.join(" \xB7 ")} above \xB7 /reasoning last`);
|
|
22827
23018
|
}
|
|
22828
23019
|
|
|
22829
23020
|
// src/cli/ui/cards/SearchCard.tsx
|
|
22830
|
-
import { Box as
|
|
22831
|
-
import
|
|
23021
|
+
import { Box as Box36, Text as Text37 } from "ink";
|
|
23022
|
+
import React44 from "react";
|
|
22832
23023
|
function SearchCard({ card }) {
|
|
22833
23024
|
const fileCount = new Set(card.hits.map((h) => h.file)).size;
|
|
22834
23025
|
const elapsed = `${(card.elapsedMs / 1e3).toFixed(2)}s`;
|
|
22835
23026
|
const stats2 = `${card.hits.length} hit${card.hits.length === 1 ? "" : "s"} \xB7 ${fileCount} file${fileCount === 1 ? "" : "s"}`;
|
|
22836
23027
|
const grouped = groupByFile(card.hits.slice(0, 10));
|
|
22837
|
-
return /* @__PURE__ */
|
|
23028
|
+
return /* @__PURE__ */ React44.createElement(Card, { tone: TONE.info }, /* @__PURE__ */ React44.createElement(
|
|
22838
23029
|
CardHeader,
|
|
22839
23030
|
{
|
|
22840
23031
|
glyph: "\u2299",
|
|
@@ -22843,7 +23034,7 @@ function SearchCard({ card }) {
|
|
|
22843
23034
|
subtitle: `"${card.query}"`,
|
|
22844
23035
|
meta: [stats2, elapsed]
|
|
22845
23036
|
}
|
|
22846
|
-
), grouped.map(([file, hits]) => /* @__PURE__ */
|
|
23037
|
+
), grouped.map(([file, hits]) => /* @__PURE__ */ React44.createElement(Box36, { key: file, flexDirection: "column" }, /* @__PURE__ */ React44.createElement(Text37, { bold: true, color: FG.strong }, file), hits.map((h, i) => /* @__PURE__ */ React44.createElement(Box36, { key: `${file}:${h.line}:${i}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React44.createElement(Text37, { color: FG.faint }, `${h.line.toString().padStart(4)} \u2502`), /* @__PURE__ */ React44.createElement(HighlightedLine, { text: h.preview, start: h.matchStart, end: h.matchEnd }))))), card.hits.length > 10 ? /* @__PURE__ */ React44.createElement(Text37, { color: FG.faint }, `\u22EE +${card.hits.length - 10} more hits`) : null);
|
|
22847
23038
|
}
|
|
22848
23039
|
function HighlightedLine({
|
|
22849
23040
|
text,
|
|
@@ -22851,9 +23042,9 @@ function HighlightedLine({
|
|
|
22851
23042
|
end
|
|
22852
23043
|
}) {
|
|
22853
23044
|
if (start < 0 || end <= start || end > text.length) {
|
|
22854
|
-
return /* @__PURE__ */
|
|
23045
|
+
return /* @__PURE__ */ React44.createElement(Text37, { color: FG.sub }, text);
|
|
22855
23046
|
}
|
|
22856
|
-
return /* @__PURE__ */
|
|
23047
|
+
return /* @__PURE__ */ React44.createElement(React44.Fragment, null, /* @__PURE__ */ React44.createElement(Text37, { color: FG.sub }, text.slice(0, start)), /* @__PURE__ */ React44.createElement(Text37, { bold: true, inverse: true }, text.slice(start, end)), /* @__PURE__ */ React44.createElement(Text37, { color: FG.sub }, text.slice(end)));
|
|
22857
23048
|
}
|
|
22858
23049
|
function groupByFile(hits) {
|
|
22859
23050
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -22866,8 +23057,8 @@ function groupByFile(hits) {
|
|
|
22866
23057
|
}
|
|
22867
23058
|
|
|
22868
23059
|
// src/cli/ui/cards/StreamingCard.tsx
|
|
22869
|
-
import { Box as
|
|
22870
|
-
import
|
|
23060
|
+
import { Box as Box38, Text as Text39, useStdout as useStdout9 } from "ink";
|
|
23061
|
+
import React46, { useContext as useContext5 } from "react";
|
|
22871
23062
|
|
|
22872
23063
|
// src/cli/ui/layout/LiveExpandContext.ts
|
|
22873
23064
|
import { createContext as createContext4 } from "react";
|
|
@@ -22875,54 +23066,54 @@ var LiveExpandContext = createContext4(false);
|
|
|
22875
23066
|
|
|
22876
23067
|
// src/cli/ui/markdown.tsx
|
|
22877
23068
|
import { highlight, supportsLanguage } from "cli-highlight";
|
|
22878
|
-
import { Box as
|
|
22879
|
-
import
|
|
23069
|
+
import { Box as Box37, Text as Text38, useStdout as useStdout8 } from "ink";
|
|
23070
|
+
import React45 from "react";
|
|
22880
23071
|
import stringWidth from "string-width";
|
|
22881
23072
|
var BODY_LEFT_CELLS = 7;
|
|
22882
|
-
var MarkdownWidthCtx =
|
|
23073
|
+
var MarkdownWidthCtx = React45.createContext(void 0);
|
|
22883
23074
|
function useWidth() {
|
|
22884
|
-
const ctx =
|
|
23075
|
+
const ctx = React45.useContext(MarkdownWidthCtx);
|
|
22885
23076
|
if (ctx !== void 0) return ctx;
|
|
22886
|
-
return (
|
|
23077
|
+
return (useStdout8()?.stdout?.columns ?? process.stdout.columns ?? 80) - BODY_LEFT_CELLS;
|
|
22887
23078
|
}
|
|
22888
23079
|
marked.setOptions({ gfm: true, breaks: false });
|
|
22889
23080
|
function Markdown({ text, width }) {
|
|
22890
|
-
const tokens =
|
|
23081
|
+
const tokens = React45.useMemo(() => marked.lexer(text), [text]);
|
|
22891
23082
|
const ctxWidth = width !== void 0 ? Math.max(1, width) : void 0;
|
|
22892
|
-
return /* @__PURE__ */
|
|
23083
|
+
return /* @__PURE__ */ React45.createElement(MarkdownWidthCtx.Provider, { value: ctxWidth }, /* @__PURE__ */ React45.createElement(Box37, { flexDirection: "column", gap: 1 }, tokens.map((token, i) => /* @__PURE__ */ React45.createElement(BlockToken, { key: `${i}-${token.type}`, token }))));
|
|
22893
23084
|
}
|
|
22894
23085
|
function BlockToken({ token }) {
|
|
22895
23086
|
switch (token.type) {
|
|
22896
23087
|
case "heading":
|
|
22897
|
-
return /* @__PURE__ */
|
|
23088
|
+
return /* @__PURE__ */ React45.createElement(Heading, { token });
|
|
22898
23089
|
case "paragraph":
|
|
22899
|
-
return /* @__PURE__ */
|
|
23090
|
+
return /* @__PURE__ */ React45.createElement(Paragraph, { token });
|
|
22900
23091
|
case "list":
|
|
22901
|
-
return /* @__PURE__ */
|
|
23092
|
+
return /* @__PURE__ */ React45.createElement(List, { token, depth: 0 });
|
|
22902
23093
|
case "code":
|
|
22903
|
-
return /* @__PURE__ */
|
|
23094
|
+
return /* @__PURE__ */ React45.createElement(CodeBlock2, { token });
|
|
22904
23095
|
case "blockquote":
|
|
22905
|
-
return /* @__PURE__ */
|
|
23096
|
+
return /* @__PURE__ */ React45.createElement(Blockquote, { token });
|
|
22906
23097
|
case "hr":
|
|
22907
|
-
return /* @__PURE__ */
|
|
23098
|
+
return /* @__PURE__ */ React45.createElement(HorizontalRule, null);
|
|
22908
23099
|
case "table":
|
|
22909
|
-
return /* @__PURE__ */
|
|
23100
|
+
return /* @__PURE__ */ React45.createElement(Table, { token });
|
|
22910
23101
|
case "html":
|
|
22911
|
-
return /* @__PURE__ */
|
|
23102
|
+
return /* @__PURE__ */ React45.createElement(Text38, { color: FG.body }, token.text);
|
|
22912
23103
|
case "space":
|
|
22913
23104
|
return null;
|
|
22914
23105
|
default:
|
|
22915
|
-
return /* @__PURE__ */
|
|
23106
|
+
return /* @__PURE__ */ React45.createElement(Text38, { color: FG.body }, token.raw ?? "");
|
|
22916
23107
|
}
|
|
22917
23108
|
}
|
|
22918
23109
|
function Heading({ token }) {
|
|
22919
|
-
return /* @__PURE__ */
|
|
23110
|
+
return /* @__PURE__ */ React45.createElement(Box37, null, /* @__PURE__ */ React45.createElement(Text38, { bold: true, color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${plainText(token.tokens)} `));
|
|
22920
23111
|
}
|
|
22921
23112
|
function Paragraph({ token }) {
|
|
22922
|
-
return /* @__PURE__ */
|
|
23113
|
+
return /* @__PURE__ */ React45.createElement(Text38, { color: FG.body }, /* @__PURE__ */ React45.createElement(Inline, { tokens: token.tokens ?? [] }));
|
|
22923
23114
|
}
|
|
22924
23115
|
function List({ token, depth }) {
|
|
22925
|
-
return /* @__PURE__ */
|
|
23116
|
+
return /* @__PURE__ */ React45.createElement(Box37, { flexDirection: "column" }, token.items.map((item, i) => /* @__PURE__ */ React45.createElement(
|
|
22926
23117
|
ListItem,
|
|
22927
23118
|
{
|
|
22928
23119
|
key: `${i}-${item.text.slice(0, 24)}`,
|
|
@@ -22943,27 +23134,27 @@ function ListItem({
|
|
|
22943
23134
|
const markerColor = item.task ? item.checked ? TONE.ok : FG.faint : FG.meta;
|
|
22944
23135
|
const dim = item.task && item.checked === true;
|
|
22945
23136
|
const indent = " ".repeat(depth + 1);
|
|
22946
|
-
return /* @__PURE__ */
|
|
23137
|
+
return /* @__PURE__ */ React45.createElement(Box37, null, /* @__PURE__ */ React45.createElement(Text38, { color: markerColor }, `${indent}${marker} `), /* @__PURE__ */ React45.createElement(Box37, { flexDirection: "column" }, item.tokens.map((tok, i) => {
|
|
22947
23138
|
if (tok.type === "text") {
|
|
22948
23139
|
const inner = tok.tokens;
|
|
22949
23140
|
return (
|
|
22950
23141
|
// biome-ignore lint/suspicious/noArrayIndexKey: list-item children are positional and stable per render
|
|
22951
|
-
/* @__PURE__ */
|
|
23142
|
+
/* @__PURE__ */ React45.createElement(Text38, { key: `t-${i}`, color: dim ? FG.faint : FG.body, strikethrough: dim }, inner ? /* @__PURE__ */ React45.createElement(Inline, { tokens: inner }) : tok.text)
|
|
22952
23143
|
);
|
|
22953
23144
|
}
|
|
22954
23145
|
if (tok.type === "list") {
|
|
22955
|
-
return /* @__PURE__ */
|
|
23146
|
+
return /* @__PURE__ */ React45.createElement(List, { key: `l-${i}`, token: tok, depth: depth + 1 });
|
|
22956
23147
|
}
|
|
22957
|
-
return /* @__PURE__ */
|
|
23148
|
+
return /* @__PURE__ */ React45.createElement(BlockToken, { key: `b-${i}-${tok.type}`, token: tok });
|
|
22958
23149
|
})));
|
|
22959
23150
|
}
|
|
22960
23151
|
function CodeBlock2({ token }) {
|
|
22961
23152
|
const lang = token.lang?.split(/\s+/)[0] ?? "";
|
|
22962
23153
|
const colored = highlightCode(token.text, lang);
|
|
22963
23154
|
const lines = colored.split("\n");
|
|
22964
|
-
return /* @__PURE__ */
|
|
23155
|
+
return /* @__PURE__ */ React45.createElement(Box37, { flexDirection: "column" }, lang ? /* @__PURE__ */ React45.createElement(Box37, null, /* @__PURE__ */ React45.createElement(Text38, { color: FG.meta }, ` ${lang}`)) : null, /* @__PURE__ */ React45.createElement(Box37, { flexDirection: "column" }, lines.map((line, i) => (
|
|
22965
23156
|
// biome-ignore lint/suspicious/noArrayIndexKey: code lines are positional and stable per render
|
|
22966
|
-
/* @__PURE__ */
|
|
23157
|
+
/* @__PURE__ */ React45.createElement(Text38, { key: `code-${i}`, backgroundColor: SURFACE.bgElev }, ` ${line} `)
|
|
22967
23158
|
))));
|
|
22968
23159
|
}
|
|
22969
23160
|
function highlightCode(source, lang) {
|
|
@@ -22976,7 +23167,7 @@ function highlightCode(source, lang) {
|
|
|
22976
23167
|
}
|
|
22977
23168
|
}
|
|
22978
23169
|
function Blockquote({ token }) {
|
|
22979
|
-
return /* @__PURE__ */
|
|
23170
|
+
return /* @__PURE__ */ React45.createElement(Box37, { flexDirection: "column" }, (token.tokens ?? []).map((child, i) => /* @__PURE__ */ React45.createElement(Box37, { key: `${i}-${child.type}`, flexDirection: "row" }, /* @__PURE__ */ React45.createElement(Text38, { color: TONE.brand }, " \u258E "), /* @__PURE__ */ React45.createElement(Box37, { flexDirection: "column", flexGrow: 1 }, child.type === "paragraph" ? /* @__PURE__ */ React45.createElement(Text38, { italic: true, color: FG.sub }, /* @__PURE__ */ React45.createElement(Inline, { tokens: child.tokens ?? [] })) : /* @__PURE__ */ React45.createElement(BlockToken, { token: child })))));
|
|
22980
23171
|
}
|
|
22981
23172
|
function padToCells(text, cells) {
|
|
22982
23173
|
const w = stringWidth(text);
|
|
@@ -22986,7 +23177,7 @@ function padToCells(text, cells) {
|
|
|
22986
23177
|
function HorizontalRule() {
|
|
22987
23178
|
const width = useWidth();
|
|
22988
23179
|
const rule = "\u2500".repeat(Math.max(width, 1));
|
|
22989
|
-
return /* @__PURE__ */
|
|
23180
|
+
return /* @__PURE__ */ React45.createElement(Text38, { color: FG.faint }, ` ${rule}`);
|
|
22990
23181
|
}
|
|
22991
23182
|
function tableLayout(headerCells, bodyCells, availableWidth) {
|
|
22992
23183
|
const colCount = headerCells.length;
|
|
@@ -23014,7 +23205,7 @@ function Table({ token }) {
|
|
|
23014
23205
|
const bodyCells = token.rows.map((row3) => row3.map((c) => plainText(c.tokens)));
|
|
23015
23206
|
const layout = tableLayout(headerCells, bodyCells, width);
|
|
23016
23207
|
if (!layout.fallback)
|
|
23017
|
-
return /* @__PURE__ */
|
|
23208
|
+
return /* @__PURE__ */ React45.createElement(
|
|
23018
23209
|
ColumnarTable,
|
|
23019
23210
|
{
|
|
23020
23211
|
headerCells,
|
|
@@ -23024,7 +23215,7 @@ function Table({ token }) {
|
|
|
23024
23215
|
gap: layout.gap
|
|
23025
23216
|
}
|
|
23026
23217
|
);
|
|
23027
|
-
return /* @__PURE__ */
|
|
23218
|
+
return /* @__PURE__ */ React45.createElement(
|
|
23028
23219
|
FallbackTable,
|
|
23029
23220
|
{
|
|
23030
23221
|
headerCells,
|
|
@@ -23042,14 +23233,14 @@ function ColumnarTable({
|
|
|
23042
23233
|
gap
|
|
23043
23234
|
}) {
|
|
23044
23235
|
const ruleRow = widths.map((w) => "\u2500".repeat(w)).join(gap);
|
|
23045
|
-
return /* @__PURE__ */
|
|
23236
|
+
return /* @__PURE__ */ React45.createElement(Box37, { flexDirection: "column" }, /* @__PURE__ */ React45.createElement(Box37, null, /* @__PURE__ */ React45.createElement(Text38, null, " "), headerCells.map((cell, i) => (
|
|
23046
23237
|
// biome-ignore lint/suspicious/noArrayIndexKey: header cells positional
|
|
23047
|
-
/* @__PURE__ */
|
|
23048
|
-
))), /* @__PURE__ */
|
|
23238
|
+
/* @__PURE__ */ React45.createElement(React45.Fragment, { key: `h-${i}` }, /* @__PURE__ */ React45.createElement(Text38, { bold: true, color: FG.sub }, padToCells(cell, widths[i])), i < colCount - 1 ? /* @__PURE__ */ React45.createElement(Text38, null, gap) : null)
|
|
23239
|
+
))), /* @__PURE__ */ React45.createElement(Box37, null, /* @__PURE__ */ React45.createElement(Text38, null, " "), /* @__PURE__ */ React45.createElement(Text38, { color: FG.faint }, ruleRow)), bodyCells.map((row3, ri) => (
|
|
23049
23240
|
// biome-ignore lint/suspicious/noArrayIndexKey: body rows positional
|
|
23050
|
-
/* @__PURE__ */
|
|
23241
|
+
/* @__PURE__ */ React45.createElement(Box37, { key: `tr-${ri}` }, /* @__PURE__ */ React45.createElement(Text38, null, " "), row3.map((cell, i) => (
|
|
23051
23242
|
// biome-ignore lint/suspicious/noArrayIndexKey: cells positional
|
|
23052
|
-
/* @__PURE__ */
|
|
23243
|
+
/* @__PURE__ */ React45.createElement(React45.Fragment, { key: `c-${ri}-${i}` }, /* @__PURE__ */ React45.createElement(Text38, { color: FG.body }, padToCells(cell ?? "", widths[i])), i < colCount - 1 ? /* @__PURE__ */ React45.createElement(Text38, null, gap) : null)
|
|
23053
23244
|
)))
|
|
23054
23245
|
)));
|
|
23055
23246
|
}
|
|
@@ -23059,20 +23250,20 @@ function FallbackTable({
|
|
|
23059
23250
|
labelPad,
|
|
23060
23251
|
valueCells
|
|
23061
23252
|
}) {
|
|
23062
|
-
return /* @__PURE__ */
|
|
23253
|
+
return /* @__PURE__ */ React45.createElement(Box37, { flexDirection: "column" }, bodyCells.map((row3, ri) => (
|
|
23063
23254
|
// biome-ignore lint/suspicious/noArrayIndexKey: body rows positional
|
|
23064
|
-
/* @__PURE__ */
|
|
23255
|
+
/* @__PURE__ */ React45.createElement(Box37, { key: `fr-${ri}`, flexDirection: "column" }, ri > 0 ? /* @__PURE__ */ React45.createElement(Text38, null, " ") : null, headerCells.map((h, ci) => {
|
|
23065
23256
|
const label = `${padToCells(h, labelPad - 2)}: `;
|
|
23066
23257
|
const lines = wrapToCells(row3[ci] ?? "", valueCells);
|
|
23067
23258
|
return lines.map((line, li) => (
|
|
23068
23259
|
// biome-ignore lint/suspicious/noArrayIndexKey: fallback table lines are positional
|
|
23069
|
-
/* @__PURE__ */
|
|
23260
|
+
/* @__PURE__ */ React45.createElement(Box37, { key: `fc-${ri}-${ci}-${li}` }, li === 0 ? /* @__PURE__ */ React45.createElement(Text38, { bold: true, color: FG.sub }, label) : /* @__PURE__ */ React45.createElement(Text38, null, padToCells("", labelPad)), /* @__PURE__ */ React45.createElement(Text38, { color: FG.body }, line))
|
|
23070
23261
|
));
|
|
23071
23262
|
}))
|
|
23072
23263
|
)));
|
|
23073
23264
|
}
|
|
23074
23265
|
function Inline({ tokens }) {
|
|
23075
|
-
return /* @__PURE__ */
|
|
23266
|
+
return /* @__PURE__ */ React45.createElement(React45.Fragment, null, tokens.map((tok, i) => /* @__PURE__ */ React45.createElement(InlineToken, { key: `${i}-${tok.type}`, token: tok })));
|
|
23076
23267
|
}
|
|
23077
23268
|
var FILE_REF_RE2 = /\b([A-Za-z0-9_./@\-]+\.[A-Za-z0-9]{1,6})(?::(\d+)(?:-(\d+))?)?\b/g;
|
|
23078
23269
|
var MENTION_RE = /(?<![A-Za-z0-9_])@([A-Za-z0-9_./\-]+\.[A-Za-z0-9]{1,6})/g;
|
|
@@ -23083,10 +23274,10 @@ function looksLikeFileRef(path6, hasLine) {
|
|
|
23083
23274
|
return ext.length >= 2;
|
|
23084
23275
|
}
|
|
23085
23276
|
function osc8(label, _target, color2) {
|
|
23086
|
-
return /* @__PURE__ */
|
|
23277
|
+
return /* @__PURE__ */ React45.createElement(Text38, { color: color2, underline: true }, label);
|
|
23087
23278
|
}
|
|
23088
23279
|
function renderInlineText(raw) {
|
|
23089
|
-
if (!raw) return /* @__PURE__ */
|
|
23280
|
+
if (!raw) return /* @__PURE__ */ React45.createElement(Text38, null, raw);
|
|
23090
23281
|
const out = [];
|
|
23091
23282
|
let cursor = 0;
|
|
23092
23283
|
const hits = [];
|
|
@@ -23097,7 +23288,7 @@ function renderInlineText(raw) {
|
|
|
23097
23288
|
hits.push({
|
|
23098
23289
|
start,
|
|
23099
23290
|
end,
|
|
23100
|
-
node: /* @__PURE__ */
|
|
23291
|
+
node: /* @__PURE__ */ React45.createElement(Text38, { color: TONE.warn, underline: true }, `@${path6}`)
|
|
23101
23292
|
});
|
|
23102
23293
|
}
|
|
23103
23294
|
for (const m of raw.matchAll(FILE_REF_RE2)) {
|
|
@@ -23114,44 +23305,44 @@ function renderInlineText(raw) {
|
|
|
23114
23305
|
let key = 0;
|
|
23115
23306
|
for (const h of hits) {
|
|
23116
23307
|
if (h.start > cursor) {
|
|
23117
|
-
out.push(/* @__PURE__ */
|
|
23308
|
+
out.push(/* @__PURE__ */ React45.createElement(Text38, { key: `t-${key++}` }, raw.slice(cursor, h.start)));
|
|
23118
23309
|
}
|
|
23119
|
-
out.push(/* @__PURE__ */
|
|
23310
|
+
out.push(/* @__PURE__ */ React45.createElement(React45.Fragment, { key: `r-${key++}` }, h.node));
|
|
23120
23311
|
cursor = h.end;
|
|
23121
23312
|
}
|
|
23122
|
-
if (cursor < raw.length) out.push(/* @__PURE__ */
|
|
23123
|
-
return /* @__PURE__ */
|
|
23313
|
+
if (cursor < raw.length) out.push(/* @__PURE__ */ React45.createElement(Text38, { key: `t-${key++}` }, raw.slice(cursor)));
|
|
23314
|
+
return /* @__PURE__ */ React45.createElement(React45.Fragment, null, out);
|
|
23124
23315
|
}
|
|
23125
23316
|
function InlineToken({ token }) {
|
|
23126
23317
|
switch (token.type) {
|
|
23127
23318
|
case "text": {
|
|
23128
23319
|
const t3 = token;
|
|
23129
|
-
return t3.tokens ? /* @__PURE__ */
|
|
23320
|
+
return t3.tokens ? /* @__PURE__ */ React45.createElement(Inline, { tokens: t3.tokens }) : renderInlineText(t3.text);
|
|
23130
23321
|
}
|
|
23131
23322
|
case "strong":
|
|
23132
|
-
return /* @__PURE__ */
|
|
23323
|
+
return /* @__PURE__ */ React45.createElement(Text38, { bold: true, color: FG.strong }, /* @__PURE__ */ React45.createElement(Inline, { tokens: token.tokens }));
|
|
23133
23324
|
case "em":
|
|
23134
|
-
return /* @__PURE__ */
|
|
23325
|
+
return /* @__PURE__ */ React45.createElement(Text38, { italic: true }, /* @__PURE__ */ React45.createElement(Inline, { tokens: token.tokens }));
|
|
23135
23326
|
case "codespan":
|
|
23136
|
-
return /* @__PURE__ */
|
|
23327
|
+
return /* @__PURE__ */ React45.createElement(Text38, { color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${token.text} `);
|
|
23137
23328
|
case "del":
|
|
23138
|
-
return /* @__PURE__ */
|
|
23329
|
+
return /* @__PURE__ */ React45.createElement(Text38, { color: TONE.err, strikethrough: true }, /* @__PURE__ */ React45.createElement(Inline, { tokens: token.tokens }));
|
|
23139
23330
|
case "link": {
|
|
23140
23331
|
const l = token;
|
|
23141
|
-
return /* @__PURE__ */
|
|
23332
|
+
return /* @__PURE__ */ React45.createElement(Text38, { color: TONE.brand, underline: true }, /* @__PURE__ */ React45.createElement(Inline, { tokens: l.tokens }));
|
|
23142
23333
|
}
|
|
23143
23334
|
case "image": {
|
|
23144
23335
|
const im = token;
|
|
23145
|
-
return /* @__PURE__ */
|
|
23336
|
+
return /* @__PURE__ */ React45.createElement(Text38, { color: TONE.brand }, `[image: ${im.text || im.href}]`);
|
|
23146
23337
|
}
|
|
23147
23338
|
case "br":
|
|
23148
|
-
return /* @__PURE__ */
|
|
23339
|
+
return /* @__PURE__ */ React45.createElement(Text38, null, "\n");
|
|
23149
23340
|
case "escape":
|
|
23150
|
-
return /* @__PURE__ */
|
|
23341
|
+
return /* @__PURE__ */ React45.createElement(Text38, null, token.text);
|
|
23151
23342
|
case "html":
|
|
23152
|
-
return /* @__PURE__ */
|
|
23343
|
+
return /* @__PURE__ */ React45.createElement(Text38, null, token.text);
|
|
23153
23344
|
default:
|
|
23154
|
-
return /* @__PURE__ */
|
|
23345
|
+
return /* @__PURE__ */ React45.createElement(Text38, null, token.raw ?? "");
|
|
23155
23346
|
}
|
|
23156
23347
|
}
|
|
23157
23348
|
function plainText(tokens) {
|
|
@@ -23204,7 +23395,7 @@ function tokenRate(text, startTs, endTs) {
|
|
|
23204
23395
|
}
|
|
23205
23396
|
var PILL_RATE = { bg: "#11141a", fg: "#8b949e" };
|
|
23206
23397
|
function StreamingCard({ card }) {
|
|
23207
|
-
const { stdout: stdout4 } =
|
|
23398
|
+
const { stdout: stdout4 } = useStdout9();
|
|
23208
23399
|
const cols = stdout4?.columns ?? 80;
|
|
23209
23400
|
const expanded = useContext5(LiveExpandContext);
|
|
23210
23401
|
const reserveCap = expanded ? EXPANDED_MAX_LINES + 2 : STREAMING_PREVIEW_LINES2 + 2;
|
|
@@ -23214,19 +23405,19 @@ function StreamingCard({ card }) {
|
|
|
23214
23405
|
});
|
|
23215
23406
|
useSlowTick();
|
|
23216
23407
|
const modelBadge = card.model ? modelBadgeFor(card.model) : null;
|
|
23217
|
-
const modelPill = modelBadge ? /* @__PURE__ */
|
|
23408
|
+
const modelPill = modelBadge ? /* @__PURE__ */ React46.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null;
|
|
23218
23409
|
if (card.done && !card.aborted) {
|
|
23219
23410
|
const { tokens, tps } = tokenRate(card.text, card.ts, card.endedAt ?? Date.now());
|
|
23220
|
-
const ratePill = tokens >= MIN_TOKENS_FOR_RATE && tps !== null ? /* @__PURE__ */
|
|
23221
|
-
return /* @__PURE__ */
|
|
23411
|
+
const ratePill = tokens >= MIN_TOKENS_FOR_RATE && tps !== null ? /* @__PURE__ */ React46.createElement(Pill, { label: `${formatTokenCount(tokens)} tok \xB7 ${tps} t/s`, ...PILL_RATE, bold: false }) : null;
|
|
23412
|
+
return /* @__PURE__ */ React46.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ React46.createElement(
|
|
23222
23413
|
CardHeader,
|
|
23223
23414
|
{
|
|
23224
23415
|
glyph: "\u2039",
|
|
23225
23416
|
tone: TONE.ok,
|
|
23226
23417
|
title: "reply",
|
|
23227
|
-
right: /* @__PURE__ */
|
|
23418
|
+
right: /* @__PURE__ */ React46.createElement(React46.Fragment, null, ratePill, modelPill)
|
|
23228
23419
|
}
|
|
23229
|
-
), /* @__PURE__ */
|
|
23420
|
+
), /* @__PURE__ */ React46.createElement(Markdown, { text: card.text }));
|
|
23230
23421
|
}
|
|
23231
23422
|
const lineCells = Math.max(20, cols - 4);
|
|
23232
23423
|
const allLines = card.text.length > 0 ? card.text.split("\n") : [""];
|
|
@@ -23239,28 +23430,28 @@ function StreamingCard({ card }) {
|
|
|
23239
23430
|
const glyph = aborted ? "\u2039" : "\u25C8";
|
|
23240
23431
|
const headLabel = aborted ? "aborted" : "writing\u2026";
|
|
23241
23432
|
const { tokens: liveTokens, tps: liveTps } = tokenRate(card.text, card.ts, Date.now());
|
|
23242
|
-
const liveRatePill = !aborted && liveTokens >= MIN_TOKENS_FOR_RATE && liveTps !== null ? /* @__PURE__ */
|
|
23243
|
-
const expandPill = !aborted ? /* @__PURE__ */
|
|
23244
|
-
return /* @__PURE__ */
|
|
23433
|
+
const liveRatePill = !aborted && liveTokens >= MIN_TOKENS_FOR_RATE && liveTps !== null ? /* @__PURE__ */ React46.createElement(Pill, { label: `${liveTps} t/s`, ...PILL_RATE, bold: false }) : null;
|
|
23434
|
+
const expandPill = !aborted ? /* @__PURE__ */ React46.createElement(Pill, { label: expanded ? "expanded \u2303o" : "preview \u2303o", ...PILL_RATE, bold: false }) : null;
|
|
23435
|
+
return /* @__PURE__ */ React46.createElement(Card, { tone: headColor }, /* @__PURE__ */ React46.createElement(
|
|
23245
23436
|
CardHeader,
|
|
23246
23437
|
{
|
|
23247
23438
|
glyph,
|
|
23248
23439
|
tone: headColor,
|
|
23249
23440
|
title: headLabel,
|
|
23250
|
-
right: /* @__PURE__ */
|
|
23441
|
+
right: /* @__PURE__ */ React46.createElement(React46.Fragment, null, liveRatePill, expandPill, aborted ? null : /* @__PURE__ */ React46.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand }), modelPill)
|
|
23251
23442
|
}
|
|
23252
|
-
), expanded && droppedAbove > 0 ? /* @__PURE__ */
|
|
23253
|
-
|
|
23443
|
+
), expanded && droppedAbove > 0 ? /* @__PURE__ */ React46.createElement(
|
|
23444
|
+
Text39,
|
|
23254
23445
|
{
|
|
23255
23446
|
color: FG.faint
|
|
23256
23447
|
},
|
|
23257
23448
|
`\u22EF ${droppedAbove} earlier line${droppedAbove === 1 ? "" : "s"} above`
|
|
23258
|
-
) : null, visible.map((line, i) => /* @__PURE__ */
|
|
23449
|
+
) : null, visible.map((line, i) => /* @__PURE__ */ React46.createElement(Box38, { key: `${card.id}:${visualLines.length - visible.length + i}`, flexDirection: "row" }, /* @__PURE__ */ React46.createElement(Text39, { color: aborted ? FG.meta : FG.body }, clipToCells(line, lineCells)))), aborted ? /* @__PURE__ */ React46.createElement(Text39, { color: FG.faint }, "[truncated by esc]") : null);
|
|
23259
23450
|
}
|
|
23260
23451
|
|
|
23261
23452
|
// src/cli/ui/cards/SubAgentCard.tsx
|
|
23262
|
-
import { Box as
|
|
23263
|
-
import
|
|
23453
|
+
import { Box as Box39, Text as Text40 } from "ink";
|
|
23454
|
+
import React47, { useContext as useContext6 } from "react";
|
|
23264
23455
|
var STATUS_COLOR2 = {
|
|
23265
23456
|
running: TONE_ACTIVE.violet,
|
|
23266
23457
|
done: TONE.ok,
|
|
@@ -23273,7 +23464,7 @@ function SubAgentCard({ card }) {
|
|
|
23273
23464
|
const isRunning = card.status === "running";
|
|
23274
23465
|
const inLive = useContext6(ActiveCardContext);
|
|
23275
23466
|
const headerMeta2 = isRunning ? runningChildren > 0 ? [`${runningChildren} running`] : ["working"] : [{ text: card.status, color: headColor }];
|
|
23276
|
-
return /* @__PURE__ */
|
|
23467
|
+
return /* @__PURE__ */ React47.createElement(Card, { tone: headColor }, /* @__PURE__ */ React47.createElement(
|
|
23277
23468
|
CardHeader,
|
|
23278
23469
|
{
|
|
23279
23470
|
glyph: headGlyph,
|
|
@@ -23283,7 +23474,7 @@ function SubAgentCard({ card }) {
|
|
|
23283
23474
|
subtitle: card.task,
|
|
23284
23475
|
meta: headerMeta2
|
|
23285
23476
|
}
|
|
23286
|
-
), card.name ? /* @__PURE__ */
|
|
23477
|
+
), card.name ? /* @__PURE__ */ React47.createElement(Text40, { color: FG.faint }, `agent \xB7 ${card.name}`) : null, card.tools && card.tools.length > 0 && /* @__PURE__ */ React47.createElement(Text40, { color: FG.faint }, `tools \xB7 ${card.tools.join(", ")}`), card.children.map((child) => /* @__PURE__ */ React47.createElement(Box39, { key: child.id, flexDirection: "row", gap: 1 }, inLive ? null : /* @__PURE__ */ React47.createElement(Text40, { color: TONE.violet }, "\u258E"), /* @__PURE__ */ React47.createElement(ChildRow, { card: child }))));
|
|
23287
23478
|
}
|
|
23288
23479
|
function isChildDone(card) {
|
|
23289
23480
|
switch (card.kind) {
|
|
@@ -23299,16 +23490,16 @@ function isChildDone(card) {
|
|
|
23299
23490
|
function ChildRow({ card }) {
|
|
23300
23491
|
const v = childVisual(card);
|
|
23301
23492
|
const isDone = isChildDone(card);
|
|
23302
|
-
return /* @__PURE__ */
|
|
23493
|
+
return /* @__PURE__ */ React47.createElement(React47.Fragment, null, v.statusGlyph, /* @__PURE__ */ React47.createElement(Text40, { color: v.kindColor }, v.kindGlyph), /* @__PURE__ */ React47.createElement(Text40, { dimColor: isDone, color: FG.body }, v.text));
|
|
23303
23494
|
}
|
|
23304
23495
|
function runningGlyph(color2) {
|
|
23305
|
-
return /* @__PURE__ */
|
|
23496
|
+
return /* @__PURE__ */ React47.createElement(Spinner, { kind: "circle", color: color2 });
|
|
23306
23497
|
}
|
|
23307
23498
|
function doneGlyph(color2) {
|
|
23308
|
-
return /* @__PURE__ */
|
|
23499
|
+
return /* @__PURE__ */ React47.createElement(Text40, { color: color2 }, "\u2713");
|
|
23309
23500
|
}
|
|
23310
23501
|
function failedGlyph() {
|
|
23311
|
-
return /* @__PURE__ */
|
|
23502
|
+
return /* @__PURE__ */ React47.createElement(Text40, { color: TONE.err }, "\u2716");
|
|
23312
23503
|
}
|
|
23313
23504
|
function childVisual(card) {
|
|
23314
23505
|
switch (card.kind) {
|
|
@@ -23353,7 +23544,7 @@ function childVisual(card) {
|
|
|
23353
23544
|
};
|
|
23354
23545
|
default:
|
|
23355
23546
|
return {
|
|
23356
|
-
statusGlyph: /* @__PURE__ */
|
|
23547
|
+
statusGlyph: /* @__PURE__ */ React47.createElement(Text40, { color: FG.faint }, "\xB7"),
|
|
23357
23548
|
kindGlyph: "\xB7",
|
|
23358
23549
|
kindColor: FG.faint,
|
|
23359
23550
|
text: card.kind
|
|
@@ -23362,8 +23553,8 @@ function childVisual(card) {
|
|
|
23362
23553
|
}
|
|
23363
23554
|
|
|
23364
23555
|
// src/cli/ui/cards/TaskCard.tsx
|
|
23365
|
-
import { Box as
|
|
23366
|
-
import
|
|
23556
|
+
import { Box as Box40, Text as Text41 } from "ink";
|
|
23557
|
+
import React48 from "react";
|
|
23367
23558
|
var STEP_GLYPH = {
|
|
23368
23559
|
queued: "\u25CB",
|
|
23369
23560
|
running: "\u25B6",
|
|
@@ -23388,7 +23579,7 @@ var TASK_GLYPH = {
|
|
|
23388
23579
|
};
|
|
23389
23580
|
function TaskCard({ card }) {
|
|
23390
23581
|
const elapsed = `${(card.elapsedMs / 1e3).toFixed(1)}s`;
|
|
23391
|
-
return /* @__PURE__ */
|
|
23582
|
+
return /* @__PURE__ */ React48.createElement(Card, { tone: TASK_COLOR[card.status] }, /* @__PURE__ */ React48.createElement(
|
|
23392
23583
|
CardHeader,
|
|
23393
23584
|
{
|
|
23394
23585
|
glyph: TASK_GLYPH[card.status],
|
|
@@ -23397,12 +23588,12 @@ function TaskCard({ card }) {
|
|
|
23397
23588
|
subtitle: card.title,
|
|
23398
23589
|
meta: [elapsed, card.status]
|
|
23399
23590
|
}
|
|
23400
|
-
), card.steps.map((step) => /* @__PURE__ */
|
|
23591
|
+
), card.steps.map((step) => /* @__PURE__ */ React48.createElement(Box40, { key: step.id, flexDirection: "row", gap: 1 }, /* @__PURE__ */ React48.createElement(Text41, { color: STEP_COLOR[step.status] }, STEP_GLYPH[step.status]), /* @__PURE__ */ React48.createElement(Text41, { bold: true, color: FG.body }, (step.toolName ?? "step").padEnd(7)), /* @__PURE__ */ React48.createElement(Text41, { color: FG.sub }, step.title), step.detail ? /* @__PURE__ */ React48.createElement(Text41, { color: FG.faint }, step.detail) : null, step.elapsedMs !== void 0 ? /* @__PURE__ */ React48.createElement(Text41, { color: FG.faint }, `${(step.elapsedMs / 1e3).toFixed(2)}s`) : null)));
|
|
23401
23592
|
}
|
|
23402
23593
|
|
|
23403
23594
|
// src/cli/ui/cards/ToolCard.tsx
|
|
23404
|
-
import { Text as
|
|
23405
|
-
import
|
|
23595
|
+
import { Text as Text42, useStdout as useStdout10 } from "ink";
|
|
23596
|
+
import React49 from "react";
|
|
23406
23597
|
var READ_TAIL = 2;
|
|
23407
23598
|
var OTHER_TAIL = 5;
|
|
23408
23599
|
function tailLinesFor(name) {
|
|
@@ -23410,7 +23601,7 @@ function tailLinesFor(name) {
|
|
|
23410
23601
|
return /(?:^|_)(read|search|list|tree|get|status|diff|fetch|grep)(_|$)/.test(lower) || lower === "job_output" ? READ_TAIL : OTHER_TAIL;
|
|
23411
23602
|
}
|
|
23412
23603
|
function ToolCard({ card }) {
|
|
23413
|
-
const { stdout: stdout4 } =
|
|
23604
|
+
const { stdout: stdout4 } = useStdout10();
|
|
23414
23605
|
const cols = stdout4?.columns ?? 80;
|
|
23415
23606
|
const lineCells = Math.max(20, cols - 4);
|
|
23416
23607
|
const argsLabel = formatArgsSummary(card.args);
|
|
@@ -23431,7 +23622,7 @@ function ToolCard({ card }) {
|
|
|
23431
23622
|
meta.push({ text: "rejected", color: TONE.err });
|
|
23432
23623
|
}
|
|
23433
23624
|
for (const part of metaTrail(card)) meta.push(part);
|
|
23434
|
-
return /* @__PURE__ */
|
|
23625
|
+
return /* @__PURE__ */ React49.createElement(Card, { tone: headColor }, /* @__PURE__ */ React49.createElement(
|
|
23435
23626
|
CardHeader,
|
|
23436
23627
|
{
|
|
23437
23628
|
glyph: statusGlyph2(status3),
|
|
@@ -23439,10 +23630,10 @@ function ToolCard({ card }) {
|
|
|
23439
23630
|
title: card.name,
|
|
23440
23631
|
subtitle: argsLabel || void 0,
|
|
23441
23632
|
meta: meta.length > 0 ? meta : void 0,
|
|
23442
|
-
right: status3 === "running" ? /* @__PURE__ */
|
|
23633
|
+
right: status3 === "running" ? /* @__PURE__ */ React49.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand, bold: true }) : void 0
|
|
23443
23634
|
}
|
|
23444
|
-
), showBody && /* @__PURE__ */
|
|
23445
|
-
|
|
23635
|
+
), showBody && /* @__PURE__ */ React49.createElement(React49.Fragment, null, hidden > 0 ? /* @__PURE__ */ React49.createElement(Text42, { color: FG.faint }, `\u22EE ${hidden} earlier line${hidden === 1 ? "" : "s"} (use /tool to read full)`) : null, visible.map((line, i) => /* @__PURE__ */ React49.createElement(
|
|
23636
|
+
Text42,
|
|
23446
23637
|
{
|
|
23447
23638
|
key: `${card.id}:${hidden + i}`,
|
|
23448
23639
|
color: errColor,
|
|
@@ -23528,8 +23719,8 @@ function formatBytes(n) {
|
|
|
23528
23719
|
}
|
|
23529
23720
|
|
|
23530
23721
|
// src/cli/ui/cards/UsageCard.tsx
|
|
23531
|
-
import { Box as
|
|
23532
|
-
import
|
|
23722
|
+
import { Box as Box42, Text as Text43 } from "ink";
|
|
23723
|
+
import React50 from "react";
|
|
23533
23724
|
var BAR_CELLS3 = 30;
|
|
23534
23725
|
function compactNum(n) {
|
|
23535
23726
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
@@ -23539,25 +23730,25 @@ function compactNum(n) {
|
|
|
23539
23730
|
function bar(ratio, color2) {
|
|
23540
23731
|
const filled = Math.max(0, Math.min(BAR_CELLS3, Math.round(ratio * BAR_CELLS3)));
|
|
23541
23732
|
const empty = BAR_CELLS3 - filled;
|
|
23542
|
-
return /* @__PURE__ */
|
|
23733
|
+
return /* @__PURE__ */ React50.createElement(React50.Fragment, null, /* @__PURE__ */ React50.createElement(Text43, { color: color2 }, "\u2588".repeat(filled)), /* @__PURE__ */ React50.createElement(Text43, { color: FG.faint }, "\u2591".repeat(empty)));
|
|
23543
23734
|
}
|
|
23544
23735
|
function UsageCard({ card }) {
|
|
23545
|
-
if (card.compact) return /* @__PURE__ */
|
|
23736
|
+
if (card.compact) return /* @__PURE__ */ React50.createElement(CompactUsageRow, { card });
|
|
23546
23737
|
const cap = Math.max(1, card.tokens.promptCap);
|
|
23547
23738
|
const promptRatio = card.tokens.prompt / cap;
|
|
23548
23739
|
const reasonRatio = card.tokens.reason / cap;
|
|
23549
23740
|
const outputRatio = card.tokens.output / cap;
|
|
23550
23741
|
const headerMeta2 = [`turn ${card.turn}`, formatCost(card.cost, card.balanceCurrency)];
|
|
23551
23742
|
if (card.elapsedMs !== void 0) headerMeta2.push(`${(card.elapsedMs / 1e3).toFixed(1)}s`);
|
|
23552
|
-
return /* @__PURE__ */
|
|
23743
|
+
return /* @__PURE__ */ React50.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ React50.createElement(CardHeader, { glyph: "\u03A3", tone: FG.meta, title: "usage", meta: headerMeta2 }), /* @__PURE__ */ React50.createElement(Box42, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React50.createElement(Text43, { color: FG.sub }, "prompt"), bar(promptRatio, TONE.brand), /* @__PURE__ */ React50.createElement(Text43, { bold: true, color: FG.body }, card.tokens.prompt.toLocaleString()), /* @__PURE__ */ React50.createElement(Text43, { color: FG.faint }, `/ 1M \xB7 ${(promptRatio * 100).toFixed(1)}%`)), /* @__PURE__ */ React50.createElement(Box42, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React50.createElement(Text43, { color: FG.sub }, "reason"), bar(reasonRatio, TONE.accent), /* @__PURE__ */ React50.createElement(Text43, { bold: true, color: FG.body }, card.tokens.reason.toLocaleString())), /* @__PURE__ */ React50.createElement(Box42, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React50.createElement(Text43, { color: FG.sub }, "output"), bar(outputRatio, TONE.brand), /* @__PURE__ */ React50.createElement(Text43, { bold: true, color: FG.body }, card.tokens.output.toLocaleString())), /* @__PURE__ */ React50.createElement(Box42, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React50.createElement(Text43, { color: FG.sub }, "cache "), bar(card.cacheHit, TONE.ok), /* @__PURE__ */ React50.createElement(Text43, { bold: true, color: TONE.ok }, `${(card.cacheHit * 100).toFixed(1)}%`)), /* @__PURE__ */ React50.createElement(Box42, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React50.createElement(Text43, { color: FG.faint }, "session"), /* @__PURE__ */ React50.createElement(Text43, { bold: true, color: FG.body }, `\u26C1 ${formatCost(card.sessionCost, card.balanceCurrency, 3)}`), card.balance !== void 0 ? /* @__PURE__ */ React50.createElement(React50.Fragment, null, /* @__PURE__ */ React50.createElement(Text43, { color: FG.faint }, "\xB7 balance"), /* @__PURE__ */ React50.createElement(Text43, { bold: true, color: TONE.brand }, formatBalance(card.balance, card.balanceCurrency))) : null));
|
|
23553
23744
|
}
|
|
23554
23745
|
function CompactUsageRow({ card }) {
|
|
23555
23746
|
const elapsed = card.elapsedMs !== void 0 ? ` \xB7 ${(card.elapsedMs / 1e3).toFixed(1)}s` : "";
|
|
23556
|
-
return /* @__PURE__ */
|
|
23747
|
+
return /* @__PURE__ */ React50.createElement(Box42, { flexDirection: "row", gap: 1, marginTop: 1 }, /* @__PURE__ */ React50.createElement(Text43, { color: FG.meta }, "\u03A3"), /* @__PURE__ */ React50.createElement(Text43, { color: FG.faint }, `turn ${card.turn}`), /* @__PURE__ */ React50.createElement(Text43, { color: FG.meta }, `\xB7 ${compactNum(card.tokens.prompt)} prompt \xB7 ${compactNum(card.tokens.output)} out`), /* @__PURE__ */ React50.createElement(Text43, { color: FG.faint }, "\xB7 cache"), /* @__PURE__ */ React50.createElement(Text43, { color: TONE.ok }, `${(card.cacheHit * 100).toFixed(0)}%`), /* @__PURE__ */ React50.createElement(Text43, { color: FG.faint }, `\xB7 ${formatCost(card.cost, card.balanceCurrency)}${elapsed}`), card.balance !== void 0 ? /* @__PURE__ */ React50.createElement(Text43, { color: TONE.brand }, `\xB7 ${formatBalance(card.balance, card.balanceCurrency)}`) : null);
|
|
23557
23748
|
}
|
|
23558
23749
|
|
|
23559
23750
|
// src/cli/ui/cards/UserCard.tsx
|
|
23560
|
-
import
|
|
23751
|
+
import React51 from "react";
|
|
23561
23752
|
|
|
23562
23753
|
// src/cli/ui/cards/time.ts
|
|
23563
23754
|
function formatRelativeTime(ts, now = Date.now()) {
|
|
@@ -23574,7 +23765,7 @@ function formatRelativeTime(ts, now = Date.now()) {
|
|
|
23574
23765
|
|
|
23575
23766
|
// src/cli/ui/cards/UserCard.tsx
|
|
23576
23767
|
function UserCard({ card }) {
|
|
23577
|
-
return /* @__PURE__ */
|
|
23768
|
+
return /* @__PURE__ */ React51.createElement(Card, { tone: TONE.accent }, /* @__PURE__ */ React51.createElement(
|
|
23578
23769
|
CardHeader,
|
|
23579
23770
|
{
|
|
23580
23771
|
glyph: "\u203A",
|
|
@@ -23583,15 +23774,15 @@ function UserCard({ card }) {
|
|
|
23583
23774
|
titleColor: FG.sub,
|
|
23584
23775
|
meta: [formatRelativeTime(card.ts)]
|
|
23585
23776
|
}
|
|
23586
|
-
), /* @__PURE__ */
|
|
23777
|
+
), /* @__PURE__ */ React51.createElement(Markdown, { text: card.text }));
|
|
23587
23778
|
}
|
|
23588
23779
|
|
|
23589
23780
|
// src/cli/ui/cards/WarnCard.tsx
|
|
23590
|
-
import { Text as
|
|
23591
|
-
import
|
|
23781
|
+
import { Text as Text44 } from "ink";
|
|
23782
|
+
import React52 from "react";
|
|
23592
23783
|
function WarnCard({ card }) {
|
|
23593
23784
|
const messageLines = card.message.length > 0 ? card.message.split("\n") : [];
|
|
23594
|
-
return /* @__PURE__ */
|
|
23785
|
+
return /* @__PURE__ */ React52.createElement(Card, { tone: TONE.warn }, /* @__PURE__ */ React52.createElement(
|
|
23595
23786
|
CardHeader,
|
|
23596
23787
|
{
|
|
23597
23788
|
glyph: "\u26A0",
|
|
@@ -23599,57 +23790,57 @@ function WarnCard({ card }) {
|
|
|
23599
23790
|
title: card.title,
|
|
23600
23791
|
meta: card.detail ? [card.detail] : void 0
|
|
23601
23792
|
}
|
|
23602
|
-
), messageLines.map((line, i) => /* @__PURE__ */
|
|
23793
|
+
), messageLines.map((line, i) => /* @__PURE__ */ React52.createElement(Text44, { key: `${card.id}:${i}`, color: FG.body }, line || " ")));
|
|
23603
23794
|
}
|
|
23604
23795
|
|
|
23605
23796
|
// src/cli/ui/cards/CardRenderer.tsx
|
|
23606
|
-
var CardRenderer =
|
|
23797
|
+
var CardRenderer = React53.memo(function CardRenderer2({
|
|
23607
23798
|
card
|
|
23608
23799
|
}) {
|
|
23609
|
-
return /* @__PURE__ */
|
|
23800
|
+
return /* @__PURE__ */ React53.createElement(Box43, { flexDirection: "column" }, renderCard(card));
|
|
23610
23801
|
});
|
|
23611
23802
|
function renderCard(card) {
|
|
23612
23803
|
switch (card.kind) {
|
|
23613
23804
|
case "user":
|
|
23614
|
-
return /* @__PURE__ */
|
|
23805
|
+
return /* @__PURE__ */ React53.createElement(UserCard, { card });
|
|
23615
23806
|
case "reasoning":
|
|
23616
|
-
return /* @__PURE__ */
|
|
23807
|
+
return /* @__PURE__ */ React53.createElement(ReasoningCard, { card, expanded: true });
|
|
23617
23808
|
case "streaming":
|
|
23618
|
-
return /* @__PURE__ */
|
|
23809
|
+
return /* @__PURE__ */ React53.createElement(StreamingCard, { card });
|
|
23619
23810
|
case "tool":
|
|
23620
|
-
return /* @__PURE__ */
|
|
23811
|
+
return /* @__PURE__ */ React53.createElement(ToolCard, { card });
|
|
23621
23812
|
case "task":
|
|
23622
|
-
return /* @__PURE__ */
|
|
23813
|
+
return /* @__PURE__ */ React53.createElement(TaskCard, { card });
|
|
23623
23814
|
case "plan":
|
|
23624
|
-
return /* @__PURE__ */
|
|
23815
|
+
return /* @__PURE__ */ React53.createElement(PlanCard, { card });
|
|
23625
23816
|
case "diff":
|
|
23626
|
-
return /* @__PURE__ */
|
|
23817
|
+
return /* @__PURE__ */ React53.createElement(DiffCard, { card });
|
|
23627
23818
|
case "error":
|
|
23628
|
-
return /* @__PURE__ */
|
|
23819
|
+
return /* @__PURE__ */ React53.createElement(ErrorCard, { card });
|
|
23629
23820
|
case "warn":
|
|
23630
|
-
return /* @__PURE__ */
|
|
23821
|
+
return /* @__PURE__ */ React53.createElement(WarnCard, { card });
|
|
23631
23822
|
case "usage":
|
|
23632
|
-
return /* @__PURE__ */
|
|
23823
|
+
return /* @__PURE__ */ React53.createElement(UsageCard, { card });
|
|
23633
23824
|
case "memory":
|
|
23634
|
-
return /* @__PURE__ */
|
|
23825
|
+
return /* @__PURE__ */ React53.createElement(MemoryCard, { card });
|
|
23635
23826
|
case "subagent":
|
|
23636
|
-
return /* @__PURE__ */
|
|
23827
|
+
return /* @__PURE__ */ React53.createElement(SubAgentCard, { card });
|
|
23637
23828
|
case "search":
|
|
23638
|
-
return /* @__PURE__ */
|
|
23829
|
+
return /* @__PURE__ */ React53.createElement(SearchCard, { card });
|
|
23639
23830
|
case "live":
|
|
23640
|
-
return /* @__PURE__ */
|
|
23831
|
+
return /* @__PURE__ */ React53.createElement(LiveCard, { card });
|
|
23641
23832
|
case "ctx":
|
|
23642
|
-
return /* @__PURE__ */
|
|
23833
|
+
return /* @__PURE__ */ React53.createElement(CtxCard, { card });
|
|
23643
23834
|
case "doctor":
|
|
23644
|
-
return /* @__PURE__ */
|
|
23835
|
+
return /* @__PURE__ */ React53.createElement(DoctorCard, { card });
|
|
23645
23836
|
case "branch":
|
|
23646
|
-
return /* @__PURE__ */
|
|
23837
|
+
return /* @__PURE__ */ React53.createElement(BranchCard, { card });
|
|
23647
23838
|
default:
|
|
23648
|
-
return /* @__PURE__ */
|
|
23839
|
+
return /* @__PURE__ */ React53.createElement(FallbackCard, { card });
|
|
23649
23840
|
}
|
|
23650
23841
|
}
|
|
23651
23842
|
function FallbackCard({ card }) {
|
|
23652
|
-
return /* @__PURE__ */
|
|
23843
|
+
return /* @__PURE__ */ React53.createElement(Box43, { flexDirection: "row" }, /* @__PURE__ */ React53.createElement(Text45, { color: FG.faint }, ` \xB7 ${card.kind} card \xB7 not yet migrated`));
|
|
23653
23844
|
}
|
|
23654
23845
|
|
|
23655
23846
|
// src/cli/ui/layout/CardStream.tsx
|
|
@@ -23671,7 +23862,7 @@ function CardStream({
|
|
|
23671
23862
|
if (suppressLive && cards.length > 0 && !isFullySettled(cards[cards.length - 1])) {
|
|
23672
23863
|
visible = cards.slice(0, -1);
|
|
23673
23864
|
}
|
|
23674
|
-
return /* @__PURE__ */
|
|
23865
|
+
return /* @__PURE__ */ React54.createElement(React54.Fragment, null, scrollRows > 0 ? /* @__PURE__ */ React54.createElement(Text46, { color: FG.faint }, " \u2191 earlier \u2014 PgUp / wheel / \u2191") : null, /* @__PURE__ */ React54.createElement(Box44, { ref: outerRef, flexDirection: "column", flexGrow: 1, overflow: "hidden" }, /* @__PURE__ */ React54.createElement(Box44, { ref: innerRef, flexDirection: "column", marginTop: -scrollRows, flexShrink: 0 }, visible.map((card) => /* @__PURE__ */ React54.createElement(CardRenderer, { key: card.id, card })))));
|
|
23675
23866
|
}
|
|
23676
23867
|
function isFullySettled(card) {
|
|
23677
23868
|
switch (card.kind) {
|
|
@@ -23692,12 +23883,12 @@ function isFullySettled(card) {
|
|
|
23692
23883
|
}
|
|
23693
23884
|
|
|
23694
23885
|
// src/cli/ui/layout/LiveRows.tsx
|
|
23695
|
-
import { Box as
|
|
23696
|
-
import
|
|
23886
|
+
import { Box as Box45, Text as Text47, useStdout as useStdout11 } from "ink";
|
|
23887
|
+
import React55 from "react";
|
|
23697
23888
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
23698
23889
|
function ThinkingRow({ text }) {
|
|
23699
23890
|
const elapsed = useElapsedSeconds();
|
|
23700
|
-
return /* @__PURE__ */
|
|
23891
|
+
return /* @__PURE__ */ React55.createElement(Box45, { marginY: 1, paddingX: 1, gap: 1 }, /* @__PURE__ */ React55.createElement(Spinner, { kind: "circle", color: TONE.accent }), /* @__PURE__ */ React55.createElement(Text47, { italic: true, color: FG.sub }, text), /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, `${elapsed}s`));
|
|
23701
23892
|
}
|
|
23702
23893
|
function ModeStatusBar({
|
|
23703
23894
|
editMode,
|
|
@@ -23709,27 +23900,27 @@ function ModeStatusBar({
|
|
|
23709
23900
|
}) {
|
|
23710
23901
|
useSlowTick();
|
|
23711
23902
|
const running = jobs2?.runningCount() ?? 0;
|
|
23712
|
-
const jobsTag = running > 0 ? /* @__PURE__ */
|
|
23903
|
+
const jobsTag = running > 0 ? /* @__PURE__ */ React55.createElement(Text47, { color: TONE.warn, bold: true }, ` \xB7 \u23F5 ${running} job${running === 1 ? "" : "s"}`) : null;
|
|
23713
23904
|
if (planMode) {
|
|
23714
|
-
return /* @__PURE__ */
|
|
23905
|
+
return /* @__PURE__ */ React55.createElement(ModeBarFrame, null, /* @__PURE__ */ React55.createElement(ModePill, { label: "PLAN MODE", color: TONE.err, flash }), /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, " writes gated \xB7 /plan off to leave"), jobsTag);
|
|
23715
23906
|
}
|
|
23716
23907
|
const label = editMode === "yolo" ? "YOLO" : editMode === "auto" ? "AUTO" : "REVIEW";
|
|
23717
23908
|
const pillColor = editMode === "yolo" ? TONE.err : editMode === "auto" ? TONE.accent : TONE.brand;
|
|
23718
23909
|
const mid = editMode === "yolo" ? "edits + shell auto \xB7 /undo to roll back" : editMode === "auto" ? "edits land now \xB7 u to undo" : pendingCount > 0 ? `${pendingCount} queued \xB7 y apply \xB7 n discard` : "edits queued \xB7 y apply \xB7 n discard";
|
|
23719
|
-
return /* @__PURE__ */
|
|
23910
|
+
return /* @__PURE__ */ React55.createElement(ModeBarFrame, null, /* @__PURE__ */ React55.createElement(ModePill, { label, color: pillColor, flash }), /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, ` ${mid} \xB7 Shift+Tab to flip`), jobsTag);
|
|
23720
23911
|
}
|
|
23721
23912
|
function ModeBarFrame({ children }) {
|
|
23722
|
-
const { stdout: stdout4 } =
|
|
23913
|
+
const { stdout: stdout4 } = useStdout11();
|
|
23723
23914
|
const cols = stdout4?.columns ?? 80;
|
|
23724
23915
|
const ruleWidth = Math.max(20, cols - 2);
|
|
23725
|
-
return /* @__PURE__ */
|
|
23916
|
+
return /* @__PURE__ */ React55.createElement(Box45, { flexDirection: "column" }, /* @__PURE__ */ React55.createElement(Box45, { paddingX: 1 }, /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, "\u254C".repeat(ruleWidth))), /* @__PURE__ */ React55.createElement(Box45, { paddingX: 1 }, children));
|
|
23726
23917
|
}
|
|
23727
23918
|
function ModePill({
|
|
23728
23919
|
label,
|
|
23729
23920
|
color: color2,
|
|
23730
23921
|
flash
|
|
23731
23922
|
}) {
|
|
23732
|
-
return /* @__PURE__ */
|
|
23923
|
+
return /* @__PURE__ */ React55.createElement(Text47, { color: color2, bold: true, inverse: flash }, `[${label}]`);
|
|
23733
23924
|
}
|
|
23734
23925
|
function UndoBanner({
|
|
23735
23926
|
banner
|
|
@@ -23744,7 +23935,7 @@ function UndoBanner({
|
|
|
23744
23935
|
const urgent = !paused && remainingSec <= 1;
|
|
23745
23936
|
const pct2 = remainingMs / totalMs * 100;
|
|
23746
23937
|
const tone = paused ? TONE.warn : urgent ? TONE.err : TONE.accent;
|
|
23747
|
-
return /* @__PURE__ */
|
|
23938
|
+
return /* @__PURE__ */ React55.createElement(Box45, { marginY: 1, paddingX: 1 }, /* @__PURE__ */ React55.createElement(Text47, { backgroundColor: TONE.accent, color: "black", bold: true }, ` \u2713 AUTO-APPLIED ${ok}/${total} `), /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, " press "), /* @__PURE__ */ React55.createElement(Text47, { backgroundColor: TONE.brand, color: "black", bold: true }, " u "), /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, paused ? " to undo \xB7 " : " to undo \xB7 "), /* @__PURE__ */ React55.createElement(Text47, { backgroundColor: paused ? TONE.warn : FG.faint, color: "black", bold: true }, " space "), /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, paused ? " to resume " : " to pause "), /* @__PURE__ */ React55.createElement(CharBar, { pct: pct2, width: 20, color: tone, showLabel: false }), /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, " "), /* @__PURE__ */ React55.createElement(Text47, { color: tone, bold: urgent || paused }, paused ? `${remainingSec}s \xB7 paused` : `${remainingSec}s`));
|
|
23748
23939
|
}
|
|
23749
23940
|
function subagentPhaseLabel(phase, iter, elapsedMs) {
|
|
23750
23941
|
if (phase === "summarising") return "summarising findings\u2026";
|
|
@@ -23759,7 +23950,7 @@ function SubagentRow({ activity }) {
|
|
|
23759
23950
|
const last = activity.lastInner;
|
|
23760
23951
|
const subtitle = activity.skillName ?? truncate3(activity.task, 48);
|
|
23761
23952
|
const modelBadge = activity.model ? modelBadgeFor(activity.model) : null;
|
|
23762
|
-
return /* @__PURE__ */
|
|
23953
|
+
return /* @__PURE__ */ React55.createElement(Card, { tone: CARD.subagent.color }, /* @__PURE__ */ React55.createElement(
|
|
23763
23954
|
CardHeader,
|
|
23764
23955
|
{
|
|
23765
23956
|
glyph: "\u232C",
|
|
@@ -23769,9 +23960,9 @@ function SubagentRow({ activity }) {
|
|
|
23769
23960
|
titleBg: PILL_SECTION.plan.bg,
|
|
23770
23961
|
subtitle,
|
|
23771
23962
|
meta: [`iter ${activity.iter}`, `${seconds}s`],
|
|
23772
|
-
right: /* @__PURE__ */
|
|
23963
|
+
right: /* @__PURE__ */ React55.createElement(React55.Fragment, null, modelBadge ? /* @__PURE__ */ React55.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null, /* @__PURE__ */ React55.createElement(Spinner, { kind: "braille", color: CARD.subagent.color }))
|
|
23773
23964
|
}
|
|
23774
|
-
), /* @__PURE__ */
|
|
23965
|
+
), /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, "task ", /* @__PURE__ */ React55.createElement(Text47, { color: FG.sub }, activity.task)), /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, "last ", last ? /* @__PURE__ */ React55.createElement(React55.Fragment, null, /* @__PURE__ */ React55.createElement(Text47, { color: last.color }, `${last.glyph} `), /* @__PURE__ */ React55.createElement(Text47, { color: FG.body }, last.label), last.meta ? /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, ` ${last.meta}`) : null) : /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, "queued\u2026")), /* @__PURE__ */ React55.createElement(Text47, { color: TONE.brand }, "\u25B6 ", phase));
|
|
23775
23966
|
}
|
|
23776
23967
|
function SubagentLiveStack({
|
|
23777
23968
|
activities,
|
|
@@ -23779,13 +23970,13 @@ function SubagentLiveStack({
|
|
|
23779
23970
|
}) {
|
|
23780
23971
|
const tick = useTick();
|
|
23781
23972
|
if (activities.length === 0) return null;
|
|
23782
|
-
if (activities.length === 1) return /* @__PURE__ */
|
|
23973
|
+
if (activities.length === 1) return /* @__PURE__ */ React55.createElement(SubagentRow, { activity: activities[0] });
|
|
23783
23974
|
const visible = activities.slice(0, max);
|
|
23784
23975
|
const overflow = activities.length - visible.length;
|
|
23785
23976
|
const summarising = activities.filter((a) => a.phase === "summarising").length;
|
|
23786
23977
|
const metaParts = [`${activities.length} running`];
|
|
23787
23978
|
if (summarising > 0) metaParts.push(`${summarising} summarising`);
|
|
23788
|
-
return /* @__PURE__ */
|
|
23979
|
+
return /* @__PURE__ */ React55.createElement(Card, { tone: CARD.subagent.color }, /* @__PURE__ */ React55.createElement(
|
|
23789
23980
|
CardHeader,
|
|
23790
23981
|
{
|
|
23791
23982
|
glyph: "\u232C",
|
|
@@ -23794,9 +23985,9 @@ function SubagentLiveStack({
|
|
|
23794
23985
|
titleColor: PILL_SECTION.plan.fg,
|
|
23795
23986
|
titleBg: PILL_SECTION.plan.bg,
|
|
23796
23987
|
subtitle: metaParts.join(" \xB7 "),
|
|
23797
|
-
right: /* @__PURE__ */
|
|
23988
|
+
right: /* @__PURE__ */ React55.createElement(Spinner, { kind: "braille", color: CARD.subagent.color })
|
|
23798
23989
|
}
|
|
23799
|
-
), visible.map((a, i) => /* @__PURE__ */
|
|
23990
|
+
), visible.map((a, i) => /* @__PURE__ */ React55.createElement(CompactSubagentLine, { key: a.runId, activity: a, tick, index: i })), overflow > 0 ? /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, ` +${overflow} more running\u2026`) : null);
|
|
23800
23991
|
}
|
|
23801
23992
|
function CompactSubagentLine({
|
|
23802
23993
|
activity,
|
|
@@ -23811,7 +24002,7 @@ function CompactSubagentLine({
|
|
|
23811
24002
|
const title = activity.skillName ?? truncate3(activity.task, 28);
|
|
23812
24003
|
const titlePadded = title.padEnd(28);
|
|
23813
24004
|
const last = activity.lastInner;
|
|
23814
|
-
return /* @__PURE__ */
|
|
24005
|
+
return /* @__PURE__ */ React55.createElement(Box45, { flexDirection: "row" }, /* @__PURE__ */ React55.createElement(Text47, { color: glyphColor, bold: true }, ` ${glyph} `), /* @__PURE__ */ React55.createElement(Text47, { color: FG.body }, titlePadded), /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, ` iter ${String(activity.iter).padStart(2)} \xB7 ${seconds}s \xB7 `), last ? /* @__PURE__ */ React55.createElement(React55.Fragment, null, /* @__PURE__ */ React55.createElement(Text47, { color: last.color }, `${last.glyph} `), /* @__PURE__ */ React55.createElement(Text47, { color: FG.body }, truncate3(last.label, 18)), last.meta ? /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, ` ${last.meta}`) : null) : /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, "queued\u2026"));
|
|
23815
24006
|
}
|
|
23816
24007
|
function truncate3(text, max) {
|
|
23817
24008
|
return text.length > max ? `${text.slice(0, max)}\u2026` : text;
|
|
@@ -23823,7 +24014,7 @@ function OngoingToolRow({
|
|
|
23823
24014
|
const tick = useTick();
|
|
23824
24015
|
const elapsed = useElapsedSeconds();
|
|
23825
24016
|
const summary = summarizeToolArgs(tool2.name, tool2.args);
|
|
23826
|
-
return /* @__PURE__ */
|
|
24017
|
+
return /* @__PURE__ */ React55.createElement(Box45, { marginY: 1, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React55.createElement(Box45, null, /* @__PURE__ */ React55.createElement(Text47, { color: CARD.tool.color, bold: true }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React55.createElement(Text47, null, " "), /* @__PURE__ */ React55.createElement(Text47, { color: CARD.tool.color, bold: true }, `\u25A3 ${tool2.name}`), /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, ` running \xB7 ${elapsed}s`)), progress ? /* @__PURE__ */ React55.createElement(Box45, { paddingLeft: 3 }, /* @__PURE__ */ React55.createElement(Text47, { color: TONE.brand }, renderProgressLine(progress))) : null, summary ? /* @__PURE__ */ React55.createElement(Box45, { paddingLeft: 3 }, /* @__PURE__ */ React55.createElement(Text47, { color: FG.faint }, summary)) : null);
|
|
23827
24018
|
}
|
|
23828
24019
|
function renderProgressLine(p) {
|
|
23829
24020
|
const msg = p.message ? ` ${p.message}` : "";
|
|
@@ -23879,16 +24070,16 @@ function summarizeToolArgs(name, args) {
|
|
|
23879
24070
|
}
|
|
23880
24071
|
|
|
23881
24072
|
// src/cli/ui/layout/StatusRow.tsx
|
|
23882
|
-
import { Box as
|
|
23883
|
-
import
|
|
24073
|
+
import { Box as Box46, Text as Text49, useStdout as useStdout12 } from "ink";
|
|
24074
|
+
import React57 from "react";
|
|
23884
24075
|
|
|
23885
24076
|
// src/cli/ui/primitives/Countdown.tsx
|
|
23886
|
-
import { Text as
|
|
23887
|
-
import
|
|
24077
|
+
import { Text as Text48 } from "ink";
|
|
24078
|
+
import React56 from "react";
|
|
23888
24079
|
function Countdown({ endsAt, color: color2 = TONE.brand }) {
|
|
23889
24080
|
useSlowTick();
|
|
23890
24081
|
const remainingSec = Math.max(0, Math.ceil((endsAt - Date.now()) / 1e3));
|
|
23891
|
-
return /* @__PURE__ */
|
|
24082
|
+
return /* @__PURE__ */ React56.createElement(Text48, { bold: true, color: color2 }, String(remainingSec));
|
|
23892
24083
|
}
|
|
23893
24084
|
|
|
23894
24085
|
// src/cli/ui/layout/StatusRow.tsx
|
|
@@ -23897,17 +24088,17 @@ var RULE_MIN = 20;
|
|
|
23897
24088
|
function StatusRow() {
|
|
23898
24089
|
const status3 = useAgentState((s) => s.status);
|
|
23899
24090
|
const session = useAgentState((s) => s.session);
|
|
23900
|
-
const { stdout: stdout4 } =
|
|
24091
|
+
const { stdout: stdout4 } = useStdout12();
|
|
23901
24092
|
const cols = stdout4?.columns ?? 80;
|
|
23902
24093
|
const ruleWidth = Math.max(RULE_MIN, cols - RULE_PAD);
|
|
23903
24094
|
const hasTurn = status3.cost > 0;
|
|
23904
|
-
return /* @__PURE__ */
|
|
23905
|
-
|
|
24095
|
+
return /* @__PURE__ */ React57.createElement(Box46, { flexDirection: "column" }, /* @__PURE__ */ React57.createElement(Box46, null, /* @__PURE__ */ React57.createElement(Text49, null, " "), /* @__PURE__ */ React57.createElement(Text49, { color: FG.faint }, "\u2500".repeat(ruleWidth))), /* @__PURE__ */ React57.createElement(Box46, { flexDirection: "row" }, /* @__PURE__ */ React57.createElement(Text49, null, " "), status3.recording ? /* @__PURE__ */ React57.createElement(RecordingPill, { rec: status3.recording }) : status3.countdownSeconds !== void 0 ? /* @__PURE__ */ React57.createElement(CountdownRow, { mode: status3.mode, secondsLeft: status3.countdownSeconds }) : /* @__PURE__ */ React57.createElement(ModePill2, { mode: status3.mode, network: status3.network, detail: status3.networkDetail }), /* @__PURE__ */ React57.createElement(Sep, null), /* @__PURE__ */ React57.createElement(Text49, { color: FG.sub }, `${session.id} \xB7 ${session.branch}`), hasTurn && /* @__PURE__ */ React57.createElement(React57.Fragment, null, /* @__PURE__ */ React57.createElement(Sep, null), /* @__PURE__ */ React57.createElement(Text49, { bold: true, color: TONE.brand }, "\u25B8 "), /* @__PURE__ */ React57.createElement(Text49, { bold: true, color: FG.body }, `${formatCost(status3.cost, status3.balanceCurrency)} turn`)), /* @__PURE__ */ React57.createElement(Sep, null), /* @__PURE__ */ React57.createElement(
|
|
24096
|
+
Text49,
|
|
23906
24097
|
{
|
|
23907
24098
|
color: FG.sub
|
|
23908
24099
|
},
|
|
23909
24100
|
`${formatCost(status3.sessionCost, status3.balanceCurrency, 3)} session`
|
|
23910
|
-
), status3.balance !== void 0 && /* @__PURE__ */
|
|
24101
|
+
), status3.balance !== void 0 && /* @__PURE__ */ React57.createElement(React57.Fragment, null, /* @__PURE__ */ React57.createElement(Sep, null), /* @__PURE__ */ React57.createElement(Text49, { color: FG.faint }, "wallet "), /* @__PURE__ */ React57.createElement(Text49, { bold: true, color: balanceColor(status3.balance, status3.balanceCurrency) }, formatBalance(status3.balance, status3.balanceCurrency))), /* @__PURE__ */ React57.createElement(Sep, null), /* @__PURE__ */ React57.createElement(Text49, { color: TONE.accent }, `cache ${Math.round(status3.cacheHit * 100)}%`)));
|
|
23911
24102
|
}
|
|
23912
24103
|
function ModePill2({
|
|
23913
24104
|
mode: mode2,
|
|
@@ -23916,18 +24107,18 @@ function ModePill2({
|
|
|
23916
24107
|
}) {
|
|
23917
24108
|
if (network === "online") {
|
|
23918
24109
|
const pill = modeGlyph(mode2);
|
|
23919
|
-
return /* @__PURE__ */
|
|
24110
|
+
return /* @__PURE__ */ React57.createElement(Box46, { flexDirection: "row" }, /* @__PURE__ */ React57.createElement(Text49, { color: pill.color }, pill.glyph), /* @__PURE__ */ React57.createElement(Text49, { color: FG.sub }, ` ${mode2}`));
|
|
23920
24111
|
}
|
|
23921
24112
|
const dot2 = networkDot(network);
|
|
23922
24113
|
if (network === "slow") {
|
|
23923
24114
|
const tail = detail ? ` \xB7 ${detail}` : "";
|
|
23924
|
-
return /* @__PURE__ */
|
|
24115
|
+
return /* @__PURE__ */ React57.createElement(Box46, { flexDirection: "row" }, /* @__PURE__ */ React57.createElement(Text49, { color: dot2.color }, dot2.glyph), /* @__PURE__ */ React57.createElement(Text49, { color: dot2.color }, ` ${mode2} \xB7 slow${tail}`));
|
|
23925
24116
|
}
|
|
23926
24117
|
if (network === "disconnected") {
|
|
23927
24118
|
const tail = detail ? ` \xB7 ${detail}` : "";
|
|
23928
|
-
return /* @__PURE__ */
|
|
24119
|
+
return /* @__PURE__ */ React57.createElement(Box46, { flexDirection: "row" }, /* @__PURE__ */ React57.createElement(Text49, { color: dot2.color }, dot2.glyph), /* @__PURE__ */ React57.createElement(Text49, { color: dot2.color }, ` disconnect${tail}`));
|
|
23929
24120
|
}
|
|
23930
|
-
return /* @__PURE__ */
|
|
24121
|
+
return /* @__PURE__ */ React57.createElement(Box46, { flexDirection: "row" }, /* @__PURE__ */ React57.createElement(Text49, { color: dot2.color }, dot2.glyph), /* @__PURE__ */ React57.createElement(Text49, { color: dot2.color }, " reconnecting\u2026"));
|
|
23931
24122
|
}
|
|
23932
24123
|
function CountdownRow({
|
|
23933
24124
|
mode: mode2,
|
|
@@ -23935,14 +24126,14 @@ function CountdownRow({
|
|
|
23935
24126
|
}) {
|
|
23936
24127
|
const pill = modeGlyph(mode2);
|
|
23937
24128
|
const endsAt = Date.now() + secondsLeft * 1e3;
|
|
23938
|
-
return /* @__PURE__ */
|
|
24129
|
+
return /* @__PURE__ */ React57.createElement(Box46, { flexDirection: "row" }, /* @__PURE__ */ React57.createElement(Text49, { color: pill.color }, pill.glyph), /* @__PURE__ */ React57.createElement(Text49, { color: FG.sub }, ` ${mode2} \xB7 `), /* @__PURE__ */ React57.createElement(Text49, { color: TONE.warn }, "approving in "), /* @__PURE__ */ React57.createElement(Countdown, { endsAt }), /* @__PURE__ */ React57.createElement(Text49, { color: TONE.warn }, "s \xB7 esc to interrupt"));
|
|
23939
24130
|
}
|
|
23940
24131
|
function RecordingPill({ rec }) {
|
|
23941
24132
|
const sizeMb = (rec.sizeBytes / (1024 * 1024)).toFixed(1);
|
|
23942
|
-
return /* @__PURE__ */
|
|
24133
|
+
return /* @__PURE__ */ React57.createElement(Box46, { flexDirection: "row" }, /* @__PURE__ */ React57.createElement(Text49, { bold: true, color: TONE.err }, "\u25CFREC"), /* @__PURE__ */ React57.createElement(Text49, { color: TONE.err }, ` ${sizeMb} MB \xB7 ${rec.events} evt`));
|
|
23943
24134
|
}
|
|
23944
24135
|
function Sep() {
|
|
23945
|
-
return /* @__PURE__ */
|
|
24136
|
+
return /* @__PURE__ */ React57.createElement(Text49, { color: FG.meta }, " \xB7 ");
|
|
23946
24137
|
}
|
|
23947
24138
|
function modeGlyph(mode2) {
|
|
23948
24139
|
switch (mode2) {
|
|
@@ -23970,8 +24161,8 @@ function networkDot(state) {
|
|
|
23970
24161
|
}
|
|
23971
24162
|
|
|
23972
24163
|
// src/cli/ui/layout/ToastRail.tsx
|
|
23973
|
-
import { Box as
|
|
23974
|
-
import
|
|
24164
|
+
import { Box as Box47, Text as Text50, useStdout as useStdout13 } from "ink";
|
|
24165
|
+
import React58, { useEffect as useEffect8 } from "react";
|
|
23975
24166
|
var TONE_COLOR = {
|
|
23976
24167
|
ok: TONE.ok,
|
|
23977
24168
|
info: TONE.brand,
|
|
@@ -23993,7 +24184,7 @@ function ToastRail() {
|
|
|
23993
24184
|
const toasts = useAgentState((s) => s.toasts);
|
|
23994
24185
|
const dispatch2 = useDispatch();
|
|
23995
24186
|
useSlowTick();
|
|
23996
|
-
const { stdout: stdout4 } =
|
|
24187
|
+
const { stdout: stdout4 } = useStdout13();
|
|
23997
24188
|
const cols = stdout4?.columns ?? 80;
|
|
23998
24189
|
const rule = "\u2501".repeat(Math.max(20, cols - 4));
|
|
23999
24190
|
const now = Date.now();
|
|
@@ -24009,17 +24200,17 @@ function ToastRail() {
|
|
|
24009
24200
|
}, [toasts, dispatch2]);
|
|
24010
24201
|
const visible = toasts.filter((t3) => now - t3.bornAt < t3.ttlMs);
|
|
24011
24202
|
if (visible.length === 0) return null;
|
|
24012
|
-
return /* @__PURE__ */
|
|
24203
|
+
return /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "column" }, visible.map((t3) => {
|
|
24013
24204
|
const color2 = TONE_COLOR[t3.tone];
|
|
24014
24205
|
const glyph = TONE_GLYPH[t3.tone];
|
|
24015
24206
|
const body = bodyColor(t3, now);
|
|
24016
24207
|
const remainingSec = Math.max(0, Math.ceil((t3.ttlMs - (now - t3.bornAt)) / 1e3));
|
|
24017
|
-
return /* @__PURE__ */
|
|
24208
|
+
return /* @__PURE__ */ React58.createElement(Box47, { key: t3.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React58.createElement(Text50, { color: color2 }, rule), /* @__PURE__ */ React58.createElement(Box47, { flexDirection: "row" }, /* @__PURE__ */ React58.createElement(Text50, { color: color2 }, glyph), /* @__PURE__ */ React58.createElement(Text50, { bold: true, color: body }, ` ${t3.title}`), t3.detail !== void 0 && /* @__PURE__ */ React58.createElement(Text50, { color: FG.sub }, ` \xB7 ${t3.detail}`), /* @__PURE__ */ React58.createElement(Box47, { flexGrow: 1 }), /* @__PURE__ */ React58.createElement(Text50, { color: FG.faint }, `${remainingSec}s`)));
|
|
24018
24209
|
}));
|
|
24019
24210
|
}
|
|
24020
24211
|
|
|
24021
24212
|
// src/cli/ui/layout/plan-live-row.tsx
|
|
24022
|
-
import
|
|
24213
|
+
import React59 from "react";
|
|
24023
24214
|
function isActivePlanInFlight(card) {
|
|
24024
24215
|
if (card.kind !== "plan") return false;
|
|
24025
24216
|
if (card.variant !== "active") return false;
|
|
@@ -24034,7 +24225,7 @@ function PlanLiveRow() {
|
|
|
24034
24225
|
return null;
|
|
24035
24226
|
});
|
|
24036
24227
|
if (!planCard) return null;
|
|
24037
|
-
return /* @__PURE__ */
|
|
24228
|
+
return /* @__PURE__ */ React59.createElement(PlanCard, { card: planCard });
|
|
24038
24229
|
}
|
|
24039
24230
|
|
|
24040
24231
|
// src/cli/ui/loop.ts
|
|
@@ -25957,10 +26148,10 @@ var model = (args, loop2, ctx) => {
|
|
|
25957
26148
|
const id = args[0];
|
|
25958
26149
|
const known = ctx.models ?? null;
|
|
25959
26150
|
if (!id) {
|
|
25960
|
-
|
|
25961
|
-
return { info: t("handlers.model.modelUsage", { hint }) };
|
|
26151
|
+
return { openModelPicker: true };
|
|
25962
26152
|
}
|
|
25963
26153
|
loop2.configure({ model: id });
|
|
26154
|
+
ctx.dispatch?.({ type: "session.model.change", model: id });
|
|
25964
26155
|
if (known && known.length > 0 && !known.includes(id)) {
|
|
25965
26156
|
return {
|
|
25966
26157
|
info: t("handlers.model.modelNotInCatalog", { id, list: known.join(", ") })
|
|
@@ -26000,7 +26191,7 @@ var harvest2 = (args, loop2) => {
|
|
|
26000
26191
|
}
|
|
26001
26192
|
return { info: t("handlers.model.harvestOff") };
|
|
26002
26193
|
};
|
|
26003
|
-
var preset = (args, loop2) => {
|
|
26194
|
+
var preset = (args, loop2, ctx) => {
|
|
26004
26195
|
const name = (args[0] ?? "").toLowerCase();
|
|
26005
26196
|
const applyAndPersist = (effort2) => {
|
|
26006
26197
|
try {
|
|
@@ -26008,8 +26199,7 @@ var preset = (args, loop2) => {
|
|
|
26008
26199
|
} catch {
|
|
26009
26200
|
}
|
|
26010
26201
|
};
|
|
26011
|
-
|
|
26012
|
-
const p = PRESETS.auto;
|
|
26202
|
+
const apply3 = (p) => {
|
|
26013
26203
|
loop2.configure({
|
|
26014
26204
|
model: p.model,
|
|
26015
26205
|
autoEscalate: p.autoEscalate,
|
|
@@ -26017,31 +26207,19 @@ var preset = (args, loop2) => {
|
|
|
26017
26207
|
harvest: p.harvest,
|
|
26018
26208
|
branch: p.branch
|
|
26019
26209
|
});
|
|
26210
|
+
ctx.dispatch?.({ type: "session.model.change", model: p.model });
|
|
26020
26211
|
applyAndPersist(p.reasoningEffort);
|
|
26212
|
+
};
|
|
26213
|
+
if (name === "auto") {
|
|
26214
|
+
apply3(PRESETS.auto);
|
|
26021
26215
|
return { info: t("handlers.model.presetAuto") };
|
|
26022
26216
|
}
|
|
26023
26217
|
if (name === "flash") {
|
|
26024
|
-
|
|
26025
|
-
loop2.configure({
|
|
26026
|
-
model: p.model,
|
|
26027
|
-
autoEscalate: p.autoEscalate,
|
|
26028
|
-
reasoningEffort: p.reasoningEffort,
|
|
26029
|
-
harvest: p.harvest,
|
|
26030
|
-
branch: p.branch
|
|
26031
|
-
});
|
|
26032
|
-
applyAndPersist(p.reasoningEffort);
|
|
26218
|
+
apply3(PRESETS.flash);
|
|
26033
26219
|
return { info: t("handlers.model.presetFlash") };
|
|
26034
26220
|
}
|
|
26035
26221
|
if (name === "pro") {
|
|
26036
|
-
|
|
26037
|
-
loop2.configure({
|
|
26038
|
-
model: p.model,
|
|
26039
|
-
autoEscalate: p.autoEscalate,
|
|
26040
|
-
reasoningEffort: p.reasoningEffort,
|
|
26041
|
-
harvest: p.harvest,
|
|
26042
|
-
branch: p.branch
|
|
26043
|
-
});
|
|
26044
|
-
applyAndPersist(p.reasoningEffort);
|
|
26222
|
+
apply3(PRESETS.pro);
|
|
26045
26223
|
return { info: t("handlers.model.presetPro") };
|
|
26046
26224
|
}
|
|
26047
26225
|
return { info: t("handlers.model.presetUsage") };
|
|
@@ -26151,17 +26329,17 @@ var handlers10 = {
|
|
|
26151
26329
|
};
|
|
26152
26330
|
|
|
26153
26331
|
// src/cli/ui/ctx-breakdown.tsx
|
|
26154
|
-
import { Box as
|
|
26155
|
-
import
|
|
26332
|
+
import { Box as Box48, Text as Text52 } from "ink";
|
|
26333
|
+
import React61 from "react";
|
|
26156
26334
|
|
|
26157
26335
|
// src/cli/ui/primitives.tsx
|
|
26158
|
-
import { Text as
|
|
26159
|
-
import
|
|
26336
|
+
import { Text as Text51, useStdout as useStdout14 } from "ink";
|
|
26337
|
+
import React60 from "react";
|
|
26160
26338
|
function ChromeRule() {
|
|
26161
|
-
const { stdout: stdout4 } =
|
|
26339
|
+
const { stdout: stdout4 } = useStdout14();
|
|
26162
26340
|
const cols = stdout4?.columns ?? 80;
|
|
26163
26341
|
const w = Math.max(20, cols - 2);
|
|
26164
|
-
return /* @__PURE__ */
|
|
26342
|
+
return /* @__PURE__ */ React60.createElement(Text51, { dimColor: true }, "\u2500".repeat(w));
|
|
26165
26343
|
}
|
|
26166
26344
|
function Bar({
|
|
26167
26345
|
ratio,
|
|
@@ -26170,7 +26348,7 @@ function Bar({
|
|
|
26170
26348
|
dim
|
|
26171
26349
|
}) {
|
|
26172
26350
|
const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));
|
|
26173
|
-
return /* @__PURE__ */
|
|
26351
|
+
return /* @__PURE__ */ React60.createElement(Text51, null, /* @__PURE__ */ React60.createElement(Text51, { color: color2, dimColor: dim }, "\u25B0".repeat(filled)), /* @__PURE__ */ React60.createElement(Text51, { dimColor: true }, "\u25B1".repeat(cells - filled)));
|
|
26174
26352
|
}
|
|
26175
26353
|
|
|
26176
26354
|
// src/cli/ui/ctx-breakdown.tsx
|
|
@@ -26317,6 +26495,7 @@ var status = (_args, loop2, ctx) => {
|
|
|
26317
26495
|
const modeLine = ctx.editMode === "yolo" ? t("handlers.observability.statusModeYolo") : ctx.editMode === "auto" ? t("handlers.observability.statusModeAuto") : ctx.editMode === "review" ? t("handlers.observability.statusModeReview") : "";
|
|
26318
26496
|
const dashUrl = ctx.getDashboardUrl?.();
|
|
26319
26497
|
const dashLine = dashUrl ? t("handlers.observability.statusDash", { url: dashUrl }) : "";
|
|
26498
|
+
const workspaceLine = ctx.codeRoot ? t("handlers.observability.statusWorkspace", { path: ctx.codeRoot }) : "";
|
|
26320
26499
|
const lines = [
|
|
26321
26500
|
t("handlers.observability.statusModel", { model: loop2.model }),
|
|
26322
26501
|
t("handlers.observability.statusFlags", {
|
|
@@ -26330,6 +26509,7 @@ var status = (_args, loop2, ctx) => {
|
|
|
26330
26509
|
mcpLine,
|
|
26331
26510
|
sessionLine
|
|
26332
26511
|
];
|
|
26512
|
+
if (workspaceLine) lines.push(workspaceLine);
|
|
26333
26513
|
if (budgetLine) lines.push(budgetLine);
|
|
26334
26514
|
if (pendingLine) lines.push(pendingLine);
|
|
26335
26515
|
if (planLine) lines.push(planLine);
|
|
@@ -26887,6 +27067,16 @@ var handlers15 = {
|
|
|
26887
27067
|
var skill = (args, _loop, ctx) => {
|
|
26888
27068
|
const store = new SkillStore({ projectRoot: ctx.codeRoot });
|
|
26889
27069
|
const sub = (args[0] ?? "").toLowerCase();
|
|
27070
|
+
if (sub === "new" || sub === "init") {
|
|
27071
|
+
const name2 = args[1];
|
|
27072
|
+
if (!name2) return { info: t("handlers.skill.newUsage") };
|
|
27073
|
+
const wantsGlobal = args.slice(2).includes("--global") || !ctx.codeRoot;
|
|
27074
|
+
const result = store.create(name2, wantsGlobal ? "global" : "project");
|
|
27075
|
+
if ("error" in result) {
|
|
27076
|
+
return { info: t("handlers.skill.newError", { reason: result.error }) };
|
|
27077
|
+
}
|
|
27078
|
+
return { info: t("handlers.skill.newCreated", { name: name2, path: result.path }) };
|
|
27079
|
+
}
|
|
26890
27080
|
if (sub === "" || sub === "list" || sub === "ls") {
|
|
26891
27081
|
const skills = store.list();
|
|
26892
27082
|
if (skills.length === 0) {
|
|
@@ -26898,7 +27088,13 @@ var skill = (args, _loop, ctx) => {
|
|
|
26898
27088
|
if (!store.hasProjectScope()) {
|
|
26899
27089
|
lines2.push(t("handlers.skill.listProjectOnly"));
|
|
26900
27090
|
}
|
|
26901
|
-
lines2.push(
|
|
27091
|
+
lines2.push(
|
|
27092
|
+
"",
|
|
27093
|
+
t("handlers.skill.listFrontmatter"),
|
|
27094
|
+
t("handlers.skill.listInvoke"),
|
|
27095
|
+
"",
|
|
27096
|
+
t("handlers.skill.listEmptyNewHint")
|
|
27097
|
+
);
|
|
26902
27098
|
return { info: lines2.join("\n") };
|
|
26903
27099
|
}
|
|
26904
27100
|
const lines = [t("handlers.skill.listHeader", { count: skills.length })];
|
|
@@ -27239,7 +27435,7 @@ function hydrateCardsFromMessages(messages) {
|
|
|
27239
27435
|
}
|
|
27240
27436
|
|
|
27241
27437
|
// src/cli/ui/useCompletionPickers.ts
|
|
27242
|
-
import { useCallback as useCallback8, useEffect as useEffect9, useMemo as useMemo6, useRef as useRef6, useState as
|
|
27438
|
+
import { useCallback as useCallback8, useEffect as useEffect9, useMemo as useMemo6, useRef as useRef6, useState as useState16 } from "react";
|
|
27243
27439
|
function useCompletionPickers({
|
|
27244
27440
|
input,
|
|
27245
27441
|
setInput,
|
|
@@ -27248,7 +27444,7 @@ function useCompletionPickers({
|
|
|
27248
27444
|
models: models2,
|
|
27249
27445
|
mcpServers
|
|
27250
27446
|
}) {
|
|
27251
|
-
const [slashSelected, setSlashSelected] =
|
|
27447
|
+
const [slashSelected, setSlashSelected] = useState16(0);
|
|
27252
27448
|
const slashMatches = useMemo6(() => {
|
|
27253
27449
|
if (!input.startsWith("/") || input.includes(" ")) return null;
|
|
27254
27450
|
return suggestSlashCommands(input.slice(1), !!codeMode);
|
|
@@ -27260,8 +27456,8 @@ function useCompletionPickers({
|
|
|
27260
27456
|
return prev;
|
|
27261
27457
|
});
|
|
27262
27458
|
}, [slashMatches]);
|
|
27263
|
-
const [atSelected, setAtSelected] =
|
|
27264
|
-
const [atFiles, setAtFiles] =
|
|
27459
|
+
const [atSelected, setAtSelected] = useState16(0);
|
|
27460
|
+
const [atFiles, setAtFiles] = useState16([]);
|
|
27265
27461
|
useEffect9(() => {
|
|
27266
27462
|
if (!codeMode) {
|
|
27267
27463
|
setAtFiles([]);
|
|
@@ -27312,7 +27508,7 @@ function useCompletionPickers({
|
|
|
27312
27508
|
},
|
|
27313
27509
|
[atPicker, input, setInput]
|
|
27314
27510
|
);
|
|
27315
|
-
const [slashArgSelected, setSlashArgSelected] =
|
|
27511
|
+
const [slashArgSelected, setSlashArgSelected] = useState16(0);
|
|
27316
27512
|
const slashArgContext = useMemo6(() => {
|
|
27317
27513
|
if (!input.startsWith("/")) return null;
|
|
27318
27514
|
if (slashMatches !== null) return null;
|
|
@@ -27392,12 +27588,12 @@ function useCompletionPickers({
|
|
|
27392
27588
|
}
|
|
27393
27589
|
|
|
27394
27590
|
// src/cli/ui/useEditHistory.ts
|
|
27395
|
-
import { useCallback as useCallback9, useRef as useRef7, useState as
|
|
27591
|
+
import { useCallback as useCallback9, useRef as useRef7, useState as useState17 } from "react";
|
|
27396
27592
|
function useEditHistory(codeMode) {
|
|
27397
27593
|
const editHistory = useRef7([]);
|
|
27398
27594
|
const nextHistoryId = useRef7(1);
|
|
27399
27595
|
const currentTurnEntry = useRef7(null);
|
|
27400
|
-
const [undoBanner, setUndoBanner] =
|
|
27596
|
+
const [undoBanner, setUndoBanner] = useState17(null);
|
|
27401
27597
|
const undoTimeoutRef = useRef7(null);
|
|
27402
27598
|
const recordEdit = useCallback9(
|
|
27403
27599
|
(source, blocks, results, snaps) => {
|
|
@@ -27622,11 +27818,11 @@ function useEditHistory(codeMode) {
|
|
|
27622
27818
|
}
|
|
27623
27819
|
|
|
27624
27820
|
// src/cli/ui/useSessionInfo.ts
|
|
27625
|
-
import { useCallback as useCallback10, useEffect as useEffect10, useState as
|
|
27821
|
+
import { useCallback as useCallback10, useEffect as useEffect10, useState as useState18 } from "react";
|
|
27626
27822
|
function useSessionInfo(loop2) {
|
|
27627
|
-
const [balance, setBalance] =
|
|
27628
|
-
const [models2, setModels] =
|
|
27629
|
-
const [latestVersion, setLatestVersion] =
|
|
27823
|
+
const [balance, setBalance] = useState18(null);
|
|
27824
|
+
const [models2, setModels] = useState18(null);
|
|
27825
|
+
const [latestVersion, setLatestVersion] = useState18(null);
|
|
27630
27826
|
useEffect10(() => {
|
|
27631
27827
|
let cancelled = false;
|
|
27632
27828
|
void (async () => {
|
|
@@ -27695,7 +27891,7 @@ function useSessionInfo(loop2) {
|
|
|
27695
27891
|
}
|
|
27696
27892
|
|
|
27697
27893
|
// src/cli/ui/useSubagent.ts
|
|
27698
|
-
import { useEffect as useEffect11, useRef as useRef8, useState as
|
|
27894
|
+
import { useEffect as useEffect11, useRef as useRef8, useState as useState19 } from "react";
|
|
27699
27895
|
function summariseInner(ev) {
|
|
27700
27896
|
if (ev.role === "tool_start") {
|
|
27701
27897
|
return {
|
|
@@ -27726,7 +27922,7 @@ function useSubagent({
|
|
|
27726
27922
|
log,
|
|
27727
27923
|
getWalletCurrency
|
|
27728
27924
|
}) {
|
|
27729
|
-
const [activities, setActivities] =
|
|
27925
|
+
const [activities, setActivities] = useState19([]);
|
|
27730
27926
|
const sinkRef = useRef8({ current: null });
|
|
27731
27927
|
const getWalletCurrencyRef = useRef8(getWalletCurrency);
|
|
27732
27928
|
useEffect11(() => {
|
|
@@ -27814,13 +28010,13 @@ var PLAIN_UI = process.env.REASONIX_UI === "plain";
|
|
|
27814
28010
|
function LoopStatusRow({
|
|
27815
28011
|
loop: loop2
|
|
27816
28012
|
}) {
|
|
27817
|
-
const [, setTick] =
|
|
27818
|
-
|
|
28013
|
+
const [, setTick] = React62.useState(0);
|
|
28014
|
+
React62.useEffect(() => {
|
|
27819
28015
|
const id = setInterval(() => setTick((t3) => t3 + 1), 1e3);
|
|
27820
28016
|
return () => clearInterval(id);
|
|
27821
28017
|
}, []);
|
|
27822
28018
|
const nextFireMs = Math.max(0, loop2.nextFireAt - Date.now());
|
|
27823
|
-
return /* @__PURE__ */
|
|
28019
|
+
return /* @__PURE__ */ React62.createElement(Box49, null, /* @__PURE__ */ React62.createElement(Text53, { color: "cyan" }, `\u25B8 ${formatLoopStatus(loop2.prompt, nextFireMs, loop2.iter)} \xB7 /loop stop or type to cancel`));
|
|
27824
28020
|
}
|
|
27825
28021
|
function App(props) {
|
|
27826
28022
|
const session = useAgentSession({
|
|
@@ -27828,11 +28024,11 @@ function App(props) {
|
|
|
27828
28024
|
model: props.model,
|
|
27829
28025
|
workspace: props.codeMode?.rootDir ?? process.cwd()
|
|
27830
28026
|
});
|
|
27831
|
-
const initialCards =
|
|
28027
|
+
const initialCards = React62.useMemo(
|
|
27832
28028
|
() => props.session ? hydrateCardsFromMessages(loadSessionMessages(props.session)) : [],
|
|
27833
28029
|
[props.session]
|
|
27834
28030
|
);
|
|
27835
|
-
return /* @__PURE__ */
|
|
28031
|
+
return /* @__PURE__ */ React62.createElement(AgentStoreProvider, { session, initialCards }, /* @__PURE__ */ React62.createElement(AppInner, { ...props }));
|
|
27836
28032
|
}
|
|
27837
28033
|
function AppInner({
|
|
27838
28034
|
model: model2,
|
|
@@ -27858,22 +28054,22 @@ function AppInner({
|
|
|
27858
28054
|
);
|
|
27859
28055
|
const isStreaming = useAgentState((s) => s.cards.some((c) => c.kind === "streaming" && !c.done));
|
|
27860
28056
|
const chatScroll = useChatScroll();
|
|
27861
|
-
const [input, setInput] =
|
|
27862
|
-
const [busy, setBusy] =
|
|
27863
|
-
const [liveExpand, setLiveExpand] =
|
|
28057
|
+
const [input, setInput] = useState20("");
|
|
28058
|
+
const [busy, setBusy] = useState20(false);
|
|
28059
|
+
const [liveExpand, setLiveExpand] = useState20(false);
|
|
27864
28060
|
useEffect12(() => {
|
|
27865
28061
|
if (!isStreaming && liveExpand) setLiveExpand(false);
|
|
27866
28062
|
}, [isStreaming, liveExpand]);
|
|
27867
|
-
const [languageVersion, setLanguageVersion] =
|
|
28063
|
+
const [languageVersion, setLanguageVersion] = useState20(0);
|
|
27868
28064
|
useEffect12(() => onLanguageChange(() => setLanguageVersion((v) => v + 1)), []);
|
|
27869
|
-
const [liveMcpServers, setLiveMcpServers] =
|
|
28065
|
+
const [liveMcpServers, setLiveMcpServers] = useState20(() => mcpServers ?? []);
|
|
27870
28066
|
const abortedThisTurn = useRef9(false);
|
|
27871
28067
|
useEffect12(() => {
|
|
27872
28068
|
busyRef.current = busy;
|
|
27873
28069
|
}, [busy]);
|
|
27874
|
-
const [ongoingTool, setOngoingTool] =
|
|
27875
|
-
const [toolProgress, setToolProgress] =
|
|
27876
|
-
const { stdout: stdout4 } =
|
|
28070
|
+
const [ongoingTool, setOngoingTool] = useState20(null);
|
|
28071
|
+
const [toolProgress, setToolProgress] = useState20(null);
|
|
28072
|
+
const { stdout: stdout4 } = useStdout15();
|
|
27877
28073
|
useEffect12(() => {
|
|
27878
28074
|
if (!stdout4 || !stdout4.isTTY) return;
|
|
27879
28075
|
stdout4.write("\x1B[?2004h");
|
|
@@ -27889,9 +28085,9 @@ function AppInner({
|
|
|
27889
28085
|
log,
|
|
27890
28086
|
getWalletCurrency: () => walletCurrencyRef.current
|
|
27891
28087
|
});
|
|
27892
|
-
const [statusLine, setStatusLine] =
|
|
27893
|
-
const [currentRootDir] =
|
|
27894
|
-
const [hookList, setHookList] =
|
|
28088
|
+
const [statusLine, setStatusLine] = useState20(null);
|
|
28089
|
+
const [currentRootDir] = useState20(() => codeMode?.rootDir ?? process.cwd());
|
|
28090
|
+
const [hookList, setHookList] = useState20(
|
|
27895
28091
|
() => loadHooks({ projectRoot: codeMode?.rootDir })
|
|
27896
28092
|
);
|
|
27897
28093
|
const {
|
|
@@ -27907,13 +28103,13 @@ function AppInner({
|
|
|
27907
28103
|
touchedPaths
|
|
27908
28104
|
} = useEditHistory(codeMode);
|
|
27909
28105
|
const pendingEdits = useRef9([]);
|
|
27910
|
-
const [pendingCount, setPendingCount] =
|
|
28106
|
+
const [pendingCount, setPendingCount] = useState20(0);
|
|
27911
28107
|
const syncPendingCount = useCallback11(() => {
|
|
27912
28108
|
setPendingCount(pendingEdits.current.length);
|
|
27913
28109
|
setPendingTick((t3) => t3 + 1);
|
|
27914
28110
|
}, []);
|
|
27915
|
-
const [editMode, setEditMode] =
|
|
27916
|
-
const [preset2, setPreset] =
|
|
28111
|
+
const [editMode, setEditMode] = useState20(() => codeMode ? loadEditMode() : "review");
|
|
28112
|
+
const [preset2, setPreset] = useState20(() => {
|
|
27917
28113
|
if (model2 === "deepseek-v4-pro") return "pro";
|
|
27918
28114
|
return "auto";
|
|
27919
28115
|
});
|
|
@@ -27925,12 +28121,12 @@ function AppInner({
|
|
|
27925
28121
|
const planModeRef = useRef9(false);
|
|
27926
28122
|
const currentRootDirRef = useRef9("");
|
|
27927
28123
|
const latestVersionRef = useRef9(null);
|
|
27928
|
-
const [pendingEditReview, setPendingEditReview] =
|
|
27929
|
-
const [walkthroughActive, setWalkthroughActive] =
|
|
27930
|
-
const [pendingTick, setPendingTick] =
|
|
28124
|
+
const [pendingEditReview, setPendingEditReview] = useState20(null);
|
|
28125
|
+
const [walkthroughActive, setWalkthroughActive] = useState20(false);
|
|
28126
|
+
const [pendingTick, setPendingTick] = useState20(0);
|
|
27931
28127
|
const editReviewResolveRef = useRef9(null);
|
|
27932
28128
|
const turnEditPolicyRef = useRef9("ask");
|
|
27933
|
-
const [modeFlash, setModeFlash] =
|
|
28129
|
+
const [modeFlash, setModeFlash] = useState20(false);
|
|
27934
28130
|
const modeFlashTimeoutRef = useRef9(null);
|
|
27935
28131
|
const prevEditModeRef = useRef9(editMode);
|
|
27936
28132
|
useEffect12(() => {
|
|
@@ -27943,23 +28139,24 @@ function AppInner({
|
|
|
27943
28139
|
modeFlashTimeoutRef.current = null;
|
|
27944
28140
|
}, 1200);
|
|
27945
28141
|
}, [editMode]);
|
|
27946
|
-
const [pendingShell, setPendingShell] =
|
|
27947
|
-
const [pendingPlan, setPendingPlan] =
|
|
27948
|
-
const [pendingReviseEditor, setPendingReviseEditor] =
|
|
27949
|
-
const [pendingSessionsPicker, setPendingSessionsPicker] =
|
|
27950
|
-
const [sessionsPickerList, setSessionsPickerList] =
|
|
27951
|
-
const [pendingMcpHub, setPendingMcpHub] =
|
|
27952
|
-
const [
|
|
27953
|
-
const [
|
|
27954
|
-
const [
|
|
27955
|
-
const [
|
|
27956
|
-
const [
|
|
27957
|
-
const [
|
|
27958
|
-
const
|
|
27959
|
-
const
|
|
27960
|
-
const [
|
|
27961
|
-
const [
|
|
27962
|
-
const [
|
|
28142
|
+
const [pendingShell, setPendingShell] = useState20(null);
|
|
28143
|
+
const [pendingPlan, setPendingPlan] = useState20(null);
|
|
28144
|
+
const [pendingReviseEditor, setPendingReviseEditor] = useState20(null);
|
|
28145
|
+
const [pendingSessionsPicker, setPendingSessionsPicker] = useState20(false);
|
|
28146
|
+
const [sessionsPickerList, setSessionsPickerList] = useState20([]);
|
|
28147
|
+
const [pendingMcpHub, setPendingMcpHub] = useState20(null);
|
|
28148
|
+
const [pendingModelPicker, setPendingModelPicker] = useState20(false);
|
|
28149
|
+
const [stagedInput, setStagedInput] = useState20(null);
|
|
28150
|
+
const [pendingCheckpoint, setPendingCheckpoint] = useState20(null);
|
|
28151
|
+
const [stagedCheckpointRevise, setStagedCheckpointRevise] = useState20(null);
|
|
28152
|
+
const [pendingRevision, setPendingRevision] = useState20(null);
|
|
28153
|
+
const [pendingChoice, setPendingChoice] = useState20(null);
|
|
28154
|
+
const [stagedChoiceCustom, setStagedChoiceCustom] = useState20(null);
|
|
28155
|
+
const modalOpen = !!pendingShell || !!pendingPlan || !!pendingReviseEditor || !!pendingSessionsPicker || !!pendingMcpHub || pendingModelPicker || !!stagedInput || !!pendingEditReview || walkthroughActive || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision || !!stagedCheckpointRevise || !!pendingCheckpoint;
|
|
28156
|
+
const [planMode, setPlanMode] = useState20(false);
|
|
28157
|
+
const [proArmed, setProArmed] = useState20(false);
|
|
28158
|
+
const [turnOnPro, setTurnOnPro] = useState20(false);
|
|
28159
|
+
const [queuedSubmit, setQueuedSubmit] = useState20(null);
|
|
27963
28160
|
const { recallPrev, recallNext, pushHistory, resetCursor } = useInputRecall(setInput);
|
|
27964
28161
|
const assistantIterCounter = useRef9(0);
|
|
27965
28162
|
const atUrlCache = useRef9(/* @__PURE__ */ new Map());
|
|
@@ -27986,7 +28183,7 @@ function AppInner({
|
|
|
27986
28183
|
if (planSummaryRef.current) extras.summary = planSummaryRef.current;
|
|
27987
28184
|
savePlanState(session, steps, completedStepIdsRef.current, extras);
|
|
27988
28185
|
}, [session]);
|
|
27989
|
-
const [summary, setSummary] =
|
|
28186
|
+
const [summary, setSummary] = useState20({
|
|
27990
28187
|
turns: 0,
|
|
27991
28188
|
totalCostUsd: 0,
|
|
27992
28189
|
totalInputCostUsd: 0,
|
|
@@ -28762,7 +28959,7 @@ function AppInner({
|
|
|
28762
28959
|
const getDashboardUrl = useCallback11(() => {
|
|
28763
28960
|
return dashboardRef.current?.url ?? null;
|
|
28764
28961
|
}, []);
|
|
28765
|
-
const [dashboardUrl, setDashboardUrlState] =
|
|
28962
|
+
const [dashboardUrl, setDashboardUrlState] = useState20(null);
|
|
28766
28963
|
useEffect12(() => {
|
|
28767
28964
|
if (noDashboard) return;
|
|
28768
28965
|
if (dashboardRef.current) return;
|
|
@@ -28965,6 +29162,11 @@ function AppInner({
|
|
|
28965
29162
|
pushHistory(text);
|
|
28966
29163
|
return;
|
|
28967
29164
|
}
|
|
29165
|
+
if (result.openModelPicker) {
|
|
29166
|
+
setPendingModelPicker(true);
|
|
29167
|
+
pushHistory(text);
|
|
29168
|
+
return;
|
|
29169
|
+
}
|
|
28968
29170
|
if (result.openArgPickerFor) {
|
|
28969
29171
|
pushHistory(text);
|
|
28970
29172
|
setInput(`/${result.openArgPickerFor} `);
|
|
@@ -29158,9 +29360,15 @@ function AppInner({
|
|
|
29158
29360
|
const cost2 = (m.totalCostUsd ?? 0) + (ev.stats?.cost ?? 0);
|
|
29159
29361
|
const turn = (m.turnCount ?? 0) + 1;
|
|
29160
29362
|
const currency = walletCurrencyRef.current;
|
|
29363
|
+
const u = ev.stats?.usage;
|
|
29364
|
+
const cacheHitTokens = (m.cacheHitTokens ?? 0) + (u?.promptCacheHitTokens ?? 0);
|
|
29365
|
+
const cacheMissTokens = (m.cacheMissTokens ?? 0) + (u?.promptCacheMissTokens ?? 0);
|
|
29161
29366
|
patchSessionMeta(session, {
|
|
29162
29367
|
totalCostUsd: cost2,
|
|
29163
29368
|
turnCount: turn,
|
|
29369
|
+
cacheHitTokens,
|
|
29370
|
+
cacheMissTokens,
|
|
29371
|
+
...u?.promptTokens ? { lastPromptTokens: u.promptTokens } : {},
|
|
29164
29372
|
...currency ? { balanceCurrency: currency } : {}
|
|
29165
29373
|
});
|
|
29166
29374
|
}
|
|
@@ -29657,42 +29865,43 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29657
29865
|
[]
|
|
29658
29866
|
);
|
|
29659
29867
|
const tickerSuspended = PLAIN_UI || modalOpen || !busy && !isStreaming;
|
|
29660
|
-
return /* @__PURE__ */
|
|
29868
|
+
return /* @__PURE__ */ React62.createElement(React62.Fragment, null, /* @__PURE__ */ React62.createElement(TickerProvider, { disabled: tickerSuspended }, /* @__PURE__ */ React62.createElement(ViewportBudgetProvider, null, /* @__PURE__ */ React62.createElement(Box49, { flexDirection: "row", height: stdout4?.rows ?? 24 }, /* @__PURE__ */ React62.createElement(Box49, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ React62.createElement(Box49, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ React62.createElement(LiveExpandContext.Provider, { value: liveExpand }, /* @__PURE__ */ React62.createElement(
|
|
29661
29869
|
CardStream,
|
|
29662
29870
|
{
|
|
29663
29871
|
suppressLive: modalOpen,
|
|
29664
29872
|
scrollRows: chatScroll.scrollRows,
|
|
29665
29873
|
onMaxScrollChange: chatScroll.setMaxScroll
|
|
29666
29874
|
}
|
|
29667
|
-
)), !hasConversation && !busy && !isStreaming ? /* @__PURE__ */
|
|
29875
|
+
)), !hasConversation && !busy && !isStreaming ? /* @__PURE__ */ React62.createElement(
|
|
29668
29876
|
WelcomeBanner,
|
|
29669
29877
|
{
|
|
29670
29878
|
inCodeMode: !!codeMode,
|
|
29879
|
+
workspaceRoot: codeMode ? currentRootDir : void 0,
|
|
29671
29880
|
dashboardUrl,
|
|
29672
29881
|
languageVersion
|
|
29673
29882
|
}
|
|
29674
|
-
) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && ongoingTool ? /* @__PURE__ */
|
|
29883
|
+
) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && ongoingTool ? /* @__PURE__ */ React62.createElement(OngoingToolRow, { tool: ongoingTool, progress: toolProgress }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && subagentActivities.length > 0 ? /* @__PURE__ */ React62.createElement(SubagentLiveStack, { activities: subagentActivities, max: 3 }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && !ongoingTool && statusLine ? /* @__PURE__ */ React62.createElement(ThinkingRow, { text: statusLine }) : null, !PLAIN_UI && undoBanner && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && !pendingChoice && !stagedChoiceCustom && !pendingRevision && !stagedCheckpointRevise && !pendingCheckpoint ? /* @__PURE__ */ React62.createElement(UndoBanner, { banner: undoBanner }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && busy && !isStreaming && !ongoingTool && !statusLine ? /* @__PURE__ */ React62.createElement(ThinkingRow, { text: "processing\u2026" }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingMcpHub && !stagedInput && !pendingEditReview ? /* @__PURE__ */ React62.createElement(PlanLiveRow, null) : null, /* @__PURE__ */ React62.createElement(ToastRail, null)), stagedInput ? /* @__PURE__ */ React62.createElement(
|
|
29675
29884
|
PlanRefineInput,
|
|
29676
29885
|
{
|
|
29677
29886
|
mode: stagedInput.mode,
|
|
29678
29887
|
onSubmit: handleStagedInputSubmit,
|
|
29679
29888
|
onCancel: handleStagedInputCancel
|
|
29680
29889
|
}
|
|
29681
|
-
) : stagedChoiceCustom ? /* @__PURE__ */
|
|
29890
|
+
) : stagedChoiceCustom ? /* @__PURE__ */ React62.createElement(
|
|
29682
29891
|
PlanRefineInput,
|
|
29683
29892
|
{
|
|
29684
29893
|
mode: "choice-custom",
|
|
29685
29894
|
onSubmit: handleChoiceCustomSubmit,
|
|
29686
29895
|
onCancel: handleChoiceCustomCancel
|
|
29687
29896
|
}
|
|
29688
|
-
) : stagedCheckpointRevise ? /* @__PURE__ */
|
|
29897
|
+
) : stagedCheckpointRevise ? /* @__PURE__ */ React62.createElement(
|
|
29689
29898
|
PlanRefineInput,
|
|
29690
29899
|
{
|
|
29691
29900
|
mode: "checkpoint-revise",
|
|
29692
29901
|
onSubmit: (text) => handleCheckpointReviseSubmit(text, stagedCheckpointRevise),
|
|
29693
29902
|
onCancel: handleCheckpointReviseCancel
|
|
29694
29903
|
}
|
|
29695
|
-
) : pendingChoice ? /* @__PURE__ */
|
|
29904
|
+
) : pendingChoice ? /* @__PURE__ */ React62.createElement(
|
|
29696
29905
|
ChoiceConfirm,
|
|
29697
29906
|
{
|
|
29698
29907
|
question: pendingChoice.question,
|
|
@@ -29700,7 +29909,7 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29700
29909
|
allowCustom: pendingChoice.allowCustom,
|
|
29701
29910
|
onChoose: stableHandleChoiceConfirm
|
|
29702
29911
|
}
|
|
29703
|
-
) : pendingRevision ? /* @__PURE__ */
|
|
29912
|
+
) : pendingRevision ? /* @__PURE__ */ React62.createElement(
|
|
29704
29913
|
PlanReviseConfirm,
|
|
29705
29914
|
{
|
|
29706
29915
|
reason: pendingRevision.reason,
|
|
@@ -29711,7 +29920,7 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29711
29920
|
summary: pendingRevision.summary,
|
|
29712
29921
|
onChoose: stableHandleReviseConfirm
|
|
29713
29922
|
}
|
|
29714
|
-
) : pendingCheckpoint ? /* @__PURE__ */
|
|
29923
|
+
) : pendingCheckpoint ? /* @__PURE__ */ React62.createElement(
|
|
29715
29924
|
PlanCheckpointConfirm,
|
|
29716
29925
|
{
|
|
29717
29926
|
stepId: pendingCheckpoint.stepId,
|
|
@@ -29722,7 +29931,7 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29722
29931
|
completedStepIds: completedStepIdsRef.current,
|
|
29723
29932
|
onChoose: stableHandleCheckpointConfirm
|
|
29724
29933
|
}
|
|
29725
|
-
) : pendingSessionsPicker ? /* @__PURE__ */
|
|
29934
|
+
) : pendingSessionsPicker ? /* @__PURE__ */ React62.createElement(
|
|
29726
29935
|
SessionPicker,
|
|
29727
29936
|
{
|
|
29728
29937
|
sessions: sessionsPickerList,
|
|
@@ -29766,7 +29975,22 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29766
29975
|
}
|
|
29767
29976
|
}
|
|
29768
29977
|
}
|
|
29769
|
-
) :
|
|
29978
|
+
) : pendingModelPicker ? /* @__PURE__ */ React62.createElement(
|
|
29979
|
+
ModelPicker,
|
|
29980
|
+
{
|
|
29981
|
+
models: models2,
|
|
29982
|
+
current: loop2.model,
|
|
29983
|
+
onRefresh: refreshModels,
|
|
29984
|
+
onChoose: (outcome) => {
|
|
29985
|
+
setPendingModelPicker(false);
|
|
29986
|
+
if (outcome.kind === "select") {
|
|
29987
|
+
loop2.configure({ model: outcome.id });
|
|
29988
|
+
agentStore.dispatch({ type: "session.model.change", model: outcome.id });
|
|
29989
|
+
log.pushInfo(`\u25B8 model: ${outcome.id}`);
|
|
29990
|
+
}
|
|
29991
|
+
}
|
|
29992
|
+
}
|
|
29993
|
+
) : pendingMcpHub ? /* @__PURE__ */ React62.createElement(
|
|
29770
29994
|
McpHub,
|
|
29771
29995
|
{
|
|
29772
29996
|
initialTab: pendingMcpHub.tab,
|
|
@@ -29785,7 +30009,7 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29785
30009
|
return r;
|
|
29786
30010
|
} : void 0
|
|
29787
30011
|
}
|
|
29788
|
-
) : pendingPlan ? /* @__PURE__ */
|
|
30012
|
+
) : pendingPlan ? /* @__PURE__ */ React62.createElement(
|
|
29789
30013
|
PlanConfirm,
|
|
29790
30014
|
{
|
|
29791
30015
|
plan: pendingPlan,
|
|
@@ -29794,7 +30018,7 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29794
30018
|
onChoose: stableHandlePlanConfirm,
|
|
29795
30019
|
projectRoot: currentRootDir
|
|
29796
30020
|
}
|
|
29797
|
-
) : pendingReviseEditor ? /* @__PURE__ */
|
|
30021
|
+
) : pendingReviseEditor ? /* @__PURE__ */ React62.createElement(
|
|
29798
30022
|
PlanReviseEditor,
|
|
29799
30023
|
{
|
|
29800
30024
|
steps: planStepsRef.current ?? [],
|
|
@@ -29813,7 +30037,7 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29813
30037
|
setPendingPlan(planText);
|
|
29814
30038
|
}
|
|
29815
30039
|
}
|
|
29816
|
-
) : pendingShell ? /* @__PURE__ */
|
|
30040
|
+
) : pendingShell ? /* @__PURE__ */ React62.createElement(
|
|
29817
30041
|
ShellConfirm,
|
|
29818
30042
|
{
|
|
29819
30043
|
command: pendingShell.command,
|
|
@@ -29821,7 +30045,7 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29821
30045
|
kind: pendingShell.kind,
|
|
29822
30046
|
onChoose: handleShellConfirm
|
|
29823
30047
|
}
|
|
29824
|
-
) : pendingEditReview ? /* @__PURE__ */
|
|
30048
|
+
) : pendingEditReview ? /* @__PURE__ */ React62.createElement(
|
|
29825
30049
|
EditConfirm,
|
|
29826
30050
|
{
|
|
29827
30051
|
block: pendingEditReview,
|
|
@@ -29833,14 +30057,14 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29833
30057
|
}
|
|
29834
30058
|
}
|
|
29835
30059
|
}
|
|
29836
|
-
) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */
|
|
30060
|
+
) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */ React62.createElement(
|
|
29837
30061
|
EditConfirm,
|
|
29838
30062
|
{
|
|
29839
30063
|
key: `walk-${pendingTick}`,
|
|
29840
30064
|
block: pendingEdits.current[0],
|
|
29841
30065
|
onChoose: handleWalkChoice
|
|
29842
30066
|
}
|
|
29843
|
-
) : !chatScroll.pinned ? /* @__PURE__ */
|
|
30067
|
+
) : !chatScroll.pinned ? /* @__PURE__ */ React62.createElement(Text53, { color: FG.faint }, " \u{1F4D6} reading history \u2014 End / PgDn to return \xB7 \u2193 to advance one line") : /* @__PURE__ */ React62.createElement(React62.Fragment, null, codeMode ? /* @__PURE__ */ React62.createElement(
|
|
29844
30068
|
ModeStatusBar,
|
|
29845
30069
|
{
|
|
29846
30070
|
editMode,
|
|
@@ -29850,7 +30074,7 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29850
30074
|
undoArmed: !!undoBanner || hasUndoable(),
|
|
29851
30075
|
jobs: codeMode.jobs
|
|
29852
30076
|
}
|
|
29853
|
-
) : null, activeLoop ? /* @__PURE__ */
|
|
30077
|
+
) : null, activeLoop ? /* @__PURE__ */ React62.createElement(LoopStatusRow, { loop: activeLoop }) : null, /* @__PURE__ */ React62.createElement(StatusRow, null), /* @__PURE__ */ React62.createElement(
|
|
29854
30078
|
PromptInput,
|
|
29855
30079
|
{
|
|
29856
30080
|
value: input,
|
|
@@ -29862,14 +30086,14 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29862
30086
|
onChatScrollUp: chatScroll.scrollUp,
|
|
29863
30087
|
onChatScrollDown: chatScroll.scrollDown
|
|
29864
30088
|
}
|
|
29865
|
-
), slashMatches !== null ? /* @__PURE__ */
|
|
30089
|
+
), slashMatches !== null ? /* @__PURE__ */ React62.createElement(SlashSuggestions, { matches: slashMatches, selectedIndex: slashSelected }) : null, atMatches !== null ? /* @__PURE__ */ React62.createElement(
|
|
29866
30090
|
AtMentionSuggestions,
|
|
29867
30091
|
{
|
|
29868
30092
|
matches: atMatches,
|
|
29869
30093
|
selectedIndex: atSelected,
|
|
29870
30094
|
query: atPicker?.query ?? ""
|
|
29871
30095
|
}
|
|
29872
|
-
) : null, slashArgContext ? /* @__PURE__ */
|
|
30096
|
+
) : null, slashArgContext ? /* @__PURE__ */ React62.createElement(
|
|
29873
30097
|
SlashArgPicker,
|
|
29874
30098
|
{
|
|
29875
30099
|
matches: slashArgMatches,
|
|
@@ -29882,12 +30106,12 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
29882
30106
|
}
|
|
29883
30107
|
|
|
29884
30108
|
// src/cli/ui/Setup.tsx
|
|
29885
|
-
import { Box as
|
|
29886
|
-
import
|
|
30109
|
+
import { Box as Box50, Text as Text55, useApp } from "ink";
|
|
30110
|
+
import React64, { useState as useState21 } from "react";
|
|
29887
30111
|
|
|
29888
30112
|
// src/cli/ui/MaskedInput.tsx
|
|
29889
|
-
import { Text as
|
|
29890
|
-
import
|
|
30113
|
+
import { Text as Text54, useInput as useInput2 } from "ink";
|
|
30114
|
+
import React63, { useRef as useRef10 } from "react";
|
|
29891
30115
|
function stripPasteMarkers(s) {
|
|
29892
30116
|
return s.replace(/\u001b?\[20[01]~/g, "").replace(/\u001b/g, "");
|
|
29893
30117
|
}
|
|
@@ -29922,17 +30146,17 @@ function MaskedInput({
|
|
|
29922
30146
|
});
|
|
29923
30147
|
if (value.length === 0) {
|
|
29924
30148
|
if (placeholder.length === 0) {
|
|
29925
|
-
return /* @__PURE__ */
|
|
30149
|
+
return /* @__PURE__ */ React63.createElement(Text54, { inverse: true }, " ");
|
|
29926
30150
|
}
|
|
29927
|
-
return /* @__PURE__ */
|
|
30151
|
+
return /* @__PURE__ */ React63.createElement(React63.Fragment, null, /* @__PURE__ */ React63.createElement(Text54, { inverse: true }, placeholder[0]), /* @__PURE__ */ React63.createElement(Text54, { color: FG.faint }, placeholder.slice(1)));
|
|
29928
30152
|
}
|
|
29929
|
-
return /* @__PURE__ */
|
|
30153
|
+
return /* @__PURE__ */ React63.createElement(React63.Fragment, null, /* @__PURE__ */ React63.createElement(Text54, null, mask.repeat(value.length)), /* @__PURE__ */ React63.createElement(Text54, { inverse: true }, " "));
|
|
29930
30154
|
}
|
|
29931
30155
|
|
|
29932
30156
|
// src/cli/ui/Setup.tsx
|
|
29933
30157
|
function Setup({ onReady }) {
|
|
29934
|
-
const [value, setValue] =
|
|
29935
|
-
const [error, setError] =
|
|
30158
|
+
const [value, setValue] = useState21("");
|
|
30159
|
+
const [error, setError] = useState21(null);
|
|
29936
30160
|
const { exit: exit2 } = useApp();
|
|
29937
30161
|
const handleSubmit2 = (raw) => {
|
|
29938
30162
|
const trimmed = raw.trim();
|
|
@@ -29953,7 +30177,7 @@ function Setup({ onReady }) {
|
|
|
29953
30177
|
}
|
|
29954
30178
|
onReady(trimmed);
|
|
29955
30179
|
};
|
|
29956
|
-
return /* @__PURE__ */
|
|
30180
|
+
return /* @__PURE__ */ React64.createElement(Box50, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React64.createElement(Box50, null, /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: GRADIENT[0] }, GLYPH.brand), /* @__PURE__ */ React64.createElement(Text55, null, " "), /* @__PURE__ */ React64.createElement(Text55, { bold: true }, "Welcome to "), /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: GRADIENT[2] }, "REASONIX")), /* @__PURE__ */ React64.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.info }, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React64.createElement(Box50, null, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, " sign up at \xB7 "), /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.primary }, "https://platform.deepseek.com/api_keys")), /* @__PURE__ */ React64.createElement(Box50, null, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, " saved to "), /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, defaultConfigPath())), /* @__PURE__ */ React64.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: COLOR.brand }, GLYPH.bar), /* @__PURE__ */ React64.createElement(Text55, { bold: true, color: COLOR.primary }, " \u203A "), /* @__PURE__ */ React64.createElement(
|
|
29957
30181
|
MaskedInput,
|
|
29958
30182
|
{
|
|
29959
30183
|
value,
|
|
@@ -29962,7 +30186,41 @@ function Setup({ onReady }) {
|
|
|
29962
30186
|
mask: "\u2022",
|
|
29963
30187
|
placeholder: "sk-..."
|
|
29964
30188
|
}
|
|
29965
|
-
)), error ? /* @__PURE__ */
|
|
30189
|
+
)), error ? /* @__PURE__ */ React64.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.err, bold: true }, GLYPH.err), /* @__PURE__ */ React64.createElement(Text55, { color: COLOR.err }, ` ${error}`)) : value ? /* @__PURE__ */ React64.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, ` preview \xB7 ${redactKey(value)}`)) : null, /* @__PURE__ */ React64.createElement(Box50, { marginTop: 1 }, /* @__PURE__ */ React64.createElement(Text55, { dimColor: true }, " /exit to abort")));
|
|
30190
|
+
}
|
|
30191
|
+
|
|
30192
|
+
// src/cli/ui/drain-tty.ts
|
|
30193
|
+
import process2 from "process";
|
|
30194
|
+
async function drainTtyResponses(timeoutMs = 50) {
|
|
30195
|
+
const stdin5 = process2.stdin;
|
|
30196
|
+
if (!stdin5.isTTY && typeof stdin5.setRawMode !== "function") {
|
|
30197
|
+
return;
|
|
30198
|
+
}
|
|
30199
|
+
let raised = false;
|
|
30200
|
+
try {
|
|
30201
|
+
stdin5.setRawMode(true);
|
|
30202
|
+
raised = true;
|
|
30203
|
+
} catch {
|
|
30204
|
+
return;
|
|
30205
|
+
}
|
|
30206
|
+
stdin5.resume();
|
|
30207
|
+
await new Promise((resolve12) => {
|
|
30208
|
+
const onData = (_chunk) => {
|
|
30209
|
+
};
|
|
30210
|
+
stdin5.on("data", onData);
|
|
30211
|
+
const timer = setTimeout(() => {
|
|
30212
|
+
stdin5.off("data", onData);
|
|
30213
|
+
stdin5.pause();
|
|
30214
|
+
if (raised) {
|
|
30215
|
+
try {
|
|
30216
|
+
stdin5.setRawMode(false);
|
|
30217
|
+
} catch {
|
|
30218
|
+
}
|
|
30219
|
+
}
|
|
30220
|
+
resolve12();
|
|
30221
|
+
}, timeoutMs);
|
|
30222
|
+
timer.unref();
|
|
30223
|
+
});
|
|
29966
30224
|
}
|
|
29967
30225
|
|
|
29968
30226
|
// src/cli/ui/mcp-toast.ts
|
|
@@ -30139,13 +30397,13 @@ function Root({
|
|
|
30139
30397
|
mcpRuntime,
|
|
30140
30398
|
...appProps
|
|
30141
30399
|
}) {
|
|
30142
|
-
const [key, setKey] =
|
|
30143
|
-
const [pickerOpen, setPickerOpen] =
|
|
30144
|
-
const [activeSession, setActiveSession] =
|
|
30400
|
+
const [key, setKey] = useState22(initialKey);
|
|
30401
|
+
const [pickerOpen, setPickerOpen] = useState22(showPicker);
|
|
30402
|
+
const [activeSession, setActiveSession] = useState22(appProps.session);
|
|
30145
30403
|
const workspaceRoot = appProps.codeMode?.rootDir ?? process.cwd();
|
|
30146
|
-
const [sessions2, setSessions] =
|
|
30404
|
+
const [sessions2, setSessions] = useState22(() => listSessionsForWorkspace(workspaceRoot));
|
|
30147
30405
|
if (!key) {
|
|
30148
|
-
return /* @__PURE__ */
|
|
30406
|
+
return /* @__PURE__ */ React65.createElement(
|
|
30149
30407
|
Setup,
|
|
30150
30408
|
{
|
|
30151
30409
|
onReady: (k) => {
|
|
@@ -30157,7 +30415,7 @@ function Root({
|
|
|
30157
30415
|
}
|
|
30158
30416
|
process.env.DEEPSEEK_API_KEY = key;
|
|
30159
30417
|
if (pickerOpen) {
|
|
30160
|
-
return /* @__PURE__ */
|
|
30418
|
+
return /* @__PURE__ */ React65.createElement(KeystrokeProvider, null, /* @__PURE__ */ React65.createElement(
|
|
30161
30419
|
SessionPicker,
|
|
30162
30420
|
{
|
|
30163
30421
|
sessions: sessions2,
|
|
@@ -30190,7 +30448,7 @@ function Root({
|
|
|
30190
30448
|
}
|
|
30191
30449
|
));
|
|
30192
30450
|
}
|
|
30193
|
-
return /* @__PURE__ */
|
|
30451
|
+
return /* @__PURE__ */ React65.createElement(KeystrokeProvider, null, /* @__PURE__ */ React65.createElement(
|
|
30194
30452
|
App,
|
|
30195
30453
|
{
|
|
30196
30454
|
key: activeSession ?? "__new__",
|
|
@@ -30255,7 +30513,7 @@ async function chatCommand(opts) {
|
|
|
30255
30513
|
const launchWorkspace = opts.codeMode?.rootDir ?? process.cwd();
|
|
30256
30514
|
const showPicker = !opts.session && !opts.forceResume && listSessionsForWorkspace(launchWorkspace).length > 0;
|
|
30257
30515
|
const { waitUntilExit } = render(
|
|
30258
|
-
/* @__PURE__ */
|
|
30516
|
+
/* @__PURE__ */ React65.createElement(
|
|
30259
30517
|
Root,
|
|
30260
30518
|
{
|
|
30261
30519
|
initialKey,
|
|
@@ -30284,6 +30542,7 @@ async function chatCommand(opts) {
|
|
|
30284
30542
|
await waitUntilExit();
|
|
30285
30543
|
} finally {
|
|
30286
30544
|
await runtime.closeAll();
|
|
30545
|
+
await drainTtyResponses();
|
|
30287
30546
|
}
|
|
30288
30547
|
}
|
|
30289
30548
|
|
|
@@ -30291,7 +30550,7 @@ async function chatCommand(opts) {
|
|
|
30291
30550
|
import { readFileSync as readFileSync24 } from "fs";
|
|
30292
30551
|
import { basename as basename2, resolve as resolve10 } from "path";
|
|
30293
30552
|
async function codeCommand(opts = {}) {
|
|
30294
|
-
const { codeSystemPrompt: codeSystemPrompt2 } = await import("./prompt-
|
|
30553
|
+
const { codeSystemPrompt: codeSystemPrompt2 } = await import("./prompt-XHICFAYN.js");
|
|
30295
30554
|
const rootDir = resolve10(opts.dir ?? process.cwd());
|
|
30296
30555
|
const session = opts.noSession ? void 0 : `code-${sanitizeName(basename2(rootDir))}`;
|
|
30297
30556
|
const tools = new ToolRegistry();
|
|
@@ -30641,19 +30900,19 @@ async function commitCommand(opts = {}) {
|
|
|
30641
30900
|
import { writeFileSync as writeFileSync14 } from "fs";
|
|
30642
30901
|
import { basename as basename3 } from "path";
|
|
30643
30902
|
import { render as render2 } from "ink";
|
|
30644
|
-
import
|
|
30903
|
+
import React69 from "react";
|
|
30645
30904
|
|
|
30646
30905
|
// src/cli/ui/DiffApp.tsx
|
|
30647
|
-
import { Box as
|
|
30648
|
-
import
|
|
30906
|
+
import { Box as Box53, Static, Text as Text58, useApp as useApp2, useInput as useInput3 } from "ink";
|
|
30907
|
+
import React68, { useState as useState23 } from "react";
|
|
30649
30908
|
|
|
30650
30909
|
// src/cli/ui/RecordView.tsx
|
|
30651
|
-
import { Box as
|
|
30652
|
-
import
|
|
30910
|
+
import { Box as Box52, Text as Text57 } from "ink";
|
|
30911
|
+
import React67 from "react";
|
|
30653
30912
|
|
|
30654
30913
|
// src/cli/ui/PlanStateBlock.tsx
|
|
30655
|
-
import { Box as
|
|
30656
|
-
import
|
|
30914
|
+
import { Box as Box51, Text as Text56 } from "ink";
|
|
30915
|
+
import React66 from "react";
|
|
30657
30916
|
function PlanStateBlock({ planState }) {
|
|
30658
30917
|
const fields = [];
|
|
30659
30918
|
if (planState.subgoals.length)
|
|
@@ -30665,7 +30924,7 @@ function PlanStateBlock({ planState }) {
|
|
|
30665
30924
|
if (planState.rejectedPaths.length)
|
|
30666
30925
|
fields.push(["rejected", planState.rejectedPaths, COLOR.info, true]);
|
|
30667
30926
|
if (fields.length === 0) return null;
|
|
30668
|
-
return /* @__PURE__ */
|
|
30927
|
+
return /* @__PURE__ */ React66.createElement(Box51, { flexDirection: "column", marginBottom: 1 }, fields.map(([label, items, color2, dim]) => /* @__PURE__ */ React66.createElement(Box51, { key: label }, /* @__PURE__ */ React66.createElement(Text56, { color: color2, bold: true, dimColor: dim }, label), /* @__PURE__ */ React66.createElement(Text56, { dimColor: true }, ` (${items.length})`), /* @__PURE__ */ React66.createElement(Text56, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React66.createElement(Text56, { dimColor: dim, color: dim ? void 0 : COLOR.info }, items.join(" \xB7 ")))));
|
|
30669
30928
|
}
|
|
30670
30929
|
|
|
30671
30930
|
// src/cli/ui/RecordView.tsx
|
|
@@ -30674,21 +30933,21 @@ function RecordView({ rec, compact: compact2 = false }) {
|
|
|
30674
30933
|
const toolContentMax = compact2 ? 200 : 400;
|
|
30675
30934
|
if (rec.role === "user") {
|
|
30676
30935
|
const content = rec.content.includes("\n") ? rec.content.split("\n").join("\n ") : rec.content;
|
|
30677
|
-
return /* @__PURE__ */
|
|
30936
|
+
return /* @__PURE__ */ React67.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React67.createElement(Text57, { bold: true, color: "cyan" }, "you \u203A", " "), /* @__PURE__ */ React67.createElement(Text57, null, content));
|
|
30678
30937
|
}
|
|
30679
30938
|
if (rec.role === "assistant_final") {
|
|
30680
|
-
return /* @__PURE__ */
|
|
30939
|
+
return /* @__PURE__ */ React67.createElement(Box52, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React67.createElement(Box52, null, /* @__PURE__ */ React67.createElement(Text57, { bold: true, color: "green" }, "assistant"), rec.cost !== void 0 ? /* @__PURE__ */ React67.createElement(Text57, { dimColor: true }, " $", rec.cost.toFixed(6)) : null, rec.usage ? /* @__PURE__ */ React67.createElement(CacheBadge, { usage: rec.usage }) : null), rec.planState ? /* @__PURE__ */ React67.createElement(PlanStateBlock, { planState: rec.planState }) : null, rec.content ? /* @__PURE__ */ React67.createElement(Text57, null, rec.content) : /* @__PURE__ */ React67.createElement(Text57, { dimColor: true, italic: true }, "(tool-call response only)"));
|
|
30681
30940
|
}
|
|
30682
30941
|
if (rec.role === "tool") {
|
|
30683
|
-
return /* @__PURE__ */
|
|
30942
|
+
return /* @__PURE__ */ React67.createElement(Box52, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React67.createElement(Text57, { color: "yellow" }, "tool<", rec.tool ?? "?", ">"), rec.args ? /* @__PURE__ */ React67.createElement(Text57, { dimColor: true }, " args: ", truncate4(rec.args, toolArgsMax)) : null, /* @__PURE__ */ React67.createElement(Text57, { dimColor: true }, " \u2192 ", truncate4(rec.content, toolContentMax)));
|
|
30684
30943
|
}
|
|
30685
30944
|
if (rec.role === "error") {
|
|
30686
|
-
return /* @__PURE__ */
|
|
30945
|
+
return /* @__PURE__ */ React67.createElement(Box52, { marginTop: 1 }, /* @__PURE__ */ React67.createElement(Text57, { color: "red", bold: true }, "error", " "), /* @__PURE__ */ React67.createElement(Text57, { color: "red" }, rec.error ?? rec.content));
|
|
30687
30946
|
}
|
|
30688
30947
|
if (rec.role === "done" || rec.role === "assistant_delta") {
|
|
30689
30948
|
return null;
|
|
30690
30949
|
}
|
|
30691
|
-
return /* @__PURE__ */
|
|
30950
|
+
return /* @__PURE__ */ React67.createElement(Box52, null, /* @__PURE__ */ React67.createElement(Text57, { dimColor: true }, "[", rec.role, "] ", rec.content));
|
|
30692
30951
|
}
|
|
30693
30952
|
function CacheBadge({ usage }) {
|
|
30694
30953
|
const hit = usage.prompt_cache_hit_tokens ?? 0;
|
|
@@ -30697,7 +30956,7 @@ function CacheBadge({ usage }) {
|
|
|
30697
30956
|
if (total === 0) return null;
|
|
30698
30957
|
const pct2 = hit / total * 100;
|
|
30699
30958
|
const color2 = pct2 >= 70 ? "green" : pct2 >= 40 ? "yellow" : "red";
|
|
30700
|
-
return /* @__PURE__ */
|
|
30959
|
+
return /* @__PURE__ */ React67.createElement(Text57, null, /* @__PURE__ */ React67.createElement(Text57, { dimColor: true }, " \xB7 cache "), /* @__PURE__ */ React67.createElement(Text57, { color: color2 }, pct2.toFixed(1), "%"));
|
|
30701
30960
|
}
|
|
30702
30961
|
function truncate4(s, max) {
|
|
30703
30962
|
return s.length <= max ? s : `${s.slice(0, max)}\u2026 (+${s.length - max} chars)`;
|
|
@@ -30708,7 +30967,7 @@ function DiffApp({ report }) {
|
|
|
30708
30967
|
const { exit: exit2 } = useApp2();
|
|
30709
30968
|
const maxIdx = Math.max(0, report.pairs.length - 1);
|
|
30710
30969
|
const initialIdx = report.firstDivergenceTurn ? report.pairs.findIndex((p) => p.turn === report.firstDivergenceTurn) : 0;
|
|
30711
|
-
const [idx, setIdx] =
|
|
30970
|
+
const [idx, setIdx] = useState23(Math.max(0, initialIdx));
|
|
30712
30971
|
useInput3((input, key) => {
|
|
30713
30972
|
if (input === "q" || key.ctrl && input === "c") {
|
|
30714
30973
|
exit2();
|
|
@@ -30731,7 +30990,7 @@ function DiffApp({ report }) {
|
|
|
30731
30990
|
}
|
|
30732
30991
|
});
|
|
30733
30992
|
const pair = report.pairs[idx];
|
|
30734
|
-
return /* @__PURE__ */
|
|
30993
|
+
return /* @__PURE__ */ React68.createElement(Box53, { flexDirection: "column" }, /* @__PURE__ */ React68.createElement(DiffHeader, { report }), /* @__PURE__ */ React68.createElement(Box53, { marginTop: 1, paddingX: 1, justifyContent: "space-between" }, /* @__PURE__ */ React68.createElement(Text58, { color: "cyan", bold: true }, "turn ", pair?.turn ?? "?", " (", idx + 1, " / ", report.pairs.length, ")"), /* @__PURE__ */ React68.createElement(Text58, null, pair ? /* @__PURE__ */ React68.createElement(KindBadge, { kind: pair.kind }) : null)), /* @__PURE__ */ React68.createElement(Box53, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ React68.createElement(Pane, { label: report.a.label, headerColor: "blue", records: paneRecords(pair, "a") }), /* @__PURE__ */ React68.createElement(Pane, { label: report.b.label, headerColor: "magenta", records: paneRecords(pair, "b") })), pair?.divergenceNote ? /* @__PURE__ */ React68.createElement(Box53, { marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React68.createElement(Text58, { color: "yellow" }, "\u2605 "), /* @__PURE__ */ React68.createElement(Text58, null, pair.divergenceNote)) : null, /* @__PURE__ */ React68.createElement(Box53, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React68.createElement(Text58, { dimColor: true }, /* @__PURE__ */ React68.createElement(Text58, { bold: true }, "j"), "/", /* @__PURE__ */ React68.createElement(Text58, { bold: true }, "\u2193"), " next \xB7 ", /* @__PURE__ */ React68.createElement(Text58, { bold: true }, "k"), "/", /* @__PURE__ */ React68.createElement(Text58, { bold: true }, "\u2191"), " ", "prev \xB7 ", /* @__PURE__ */ React68.createElement(Text58, { bold: true }, "n"), " next-diverge \xB7 ", /* @__PURE__ */ React68.createElement(Text58, { bold: true }, "N"), "/", /* @__PURE__ */ React68.createElement(Text58, { bold: true }, "p"), " ", "prev-diverge \xB7 ", /* @__PURE__ */ React68.createElement(Text58, { bold: true }, "g"), "/", /* @__PURE__ */ React68.createElement(Text58, { bold: true }, "G"), " first/last \xB7 ", /* @__PURE__ */ React68.createElement(Text58, { bold: true }, "q"), " ", "quit")));
|
|
30735
30994
|
}
|
|
30736
30995
|
function DiffHeader({ report }) {
|
|
30737
30996
|
const a = report.a;
|
|
@@ -30749,15 +31008,15 @@ function DiffHeader({ report }) {
|
|
|
30749
31008
|
} else if (a.stats.prefixHashes[0] && a.stats.prefixHashes[0] === b.stats.prefixHashes[0]) {
|
|
30750
31009
|
prefixLine = `shared prefix hash ${a.stats.prefixHashes[0].slice(0, 12)}\u2026 \u2014 cache delta attributable to log stability, not prompt change.`;
|
|
30751
31010
|
}
|
|
30752
|
-
return /* @__PURE__ */
|
|
31011
|
+
return /* @__PURE__ */ React68.createElement(Box53, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React68.createElement(Box53, { justifyContent: "space-between" }, /* @__PURE__ */ React68.createElement(Text58, null, /* @__PURE__ */ React68.createElement(Text58, { color: "cyan", bold: true }, "reasonix diff"), /* @__PURE__ */ React68.createElement(Text58, { dimColor: true }, " \xB7 A="), /* @__PURE__ */ React68.createElement(Text58, { color: "blue" }, a.label), /* @__PURE__ */ React68.createElement(Text58, { dimColor: true }, " vs B="), /* @__PURE__ */ React68.createElement(Text58, { color: "magenta" }, b.label)), /* @__PURE__ */ React68.createElement(Text58, { dimColor: true }, report.pairs.length, " turns aligned")), /* @__PURE__ */ React68.createElement(Box53, { marginTop: 1, gap: 3 }, /* @__PURE__ */ React68.createElement(Text58, null, /* @__PURE__ */ React68.createElement(Text58, { dimColor: true }, "cache "), /* @__PURE__ */ React68.createElement(Text58, null, (a.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React68.createElement(Text58, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React68.createElement(Text58, null, (b.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React68.createElement(Text58, { color: cacheDelta >= 0 ? "green" : "red", bold: true }, " ", cacheDelta >= 0 ? "+" : "", (cacheDelta * 100).toFixed(1), "pp")), /* @__PURE__ */ React68.createElement(Text58, null, /* @__PURE__ */ React68.createElement(Text58, { dimColor: true }, "cost "), /* @__PURE__ */ React68.createElement(Text58, null, "$", a.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React68.createElement(Text58, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React68.createElement(Text58, null, "$", b.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React68.createElement(Text58, { color: costDelta2 <= 0 ? "green" : "red", bold: true }, " ", costDelta2 >= 0 ? "+" : "", costDelta2.toFixed(1), "%")), /* @__PURE__ */ React68.createElement(Text58, null, /* @__PURE__ */ React68.createElement(Text58, { dimColor: true }, "model calls "), /* @__PURE__ */ React68.createElement(Text58, null, a.stats.turns, " \u2192 ", b.stats.turns))), prefixLine ? /* @__PURE__ */ React68.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React68.createElement(Text58, { dimColor: true, italic: true }, prefixLine)) : null);
|
|
30753
31012
|
}
|
|
30754
31013
|
function Pane({
|
|
30755
31014
|
label,
|
|
30756
31015
|
headerColor,
|
|
30757
31016
|
records
|
|
30758
31017
|
}) {
|
|
30759
|
-
return /* @__PURE__ */
|
|
30760
|
-
|
|
31018
|
+
return /* @__PURE__ */ React68.createElement(
|
|
31019
|
+
Box53,
|
|
30761
31020
|
{
|
|
30762
31021
|
flexDirection: "column",
|
|
30763
31022
|
flexGrow: 1,
|
|
@@ -30765,21 +31024,21 @@ function Pane({
|
|
|
30765
31024
|
borderStyle: "single",
|
|
30766
31025
|
borderColor: headerColor
|
|
30767
31026
|
},
|
|
30768
|
-
/* @__PURE__ */
|
|
30769
|
-
records.length === 0 ? /* @__PURE__ */
|
|
31027
|
+
/* @__PURE__ */ React68.createElement(Text58, { color: headerColor, bold: true }, label),
|
|
31028
|
+
records.length === 0 ? /* @__PURE__ */ React68.createElement(Box53, { marginTop: 1 }, /* @__PURE__ */ React68.createElement(Text58, { dimColor: true, italic: true }, "(no records on this side for this turn)")) : /* @__PURE__ */ React68.createElement(Static, { items: records.map((rec, i) => ({ key: `${label}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React68.createElement(RecordView, { key, rec, compact: true }))
|
|
30770
31029
|
);
|
|
30771
31030
|
}
|
|
30772
31031
|
function KindBadge({ kind }) {
|
|
30773
31032
|
if (kind === "match") {
|
|
30774
|
-
return /* @__PURE__ */
|
|
31033
|
+
return /* @__PURE__ */ React68.createElement(Text58, { color: "green" }, "\u2713 match");
|
|
30775
31034
|
}
|
|
30776
31035
|
if (kind === "diverge") {
|
|
30777
|
-
return /* @__PURE__ */
|
|
31036
|
+
return /* @__PURE__ */ React68.createElement(Text58, { color: "yellow" }, "\u2605 diverge");
|
|
30778
31037
|
}
|
|
30779
31038
|
if (kind === "only_in_a") {
|
|
30780
|
-
return /* @__PURE__ */
|
|
31039
|
+
return /* @__PURE__ */ React68.createElement(Text58, { color: "blue" }, "\u2190 only in A");
|
|
30781
31040
|
}
|
|
30782
|
-
return /* @__PURE__ */
|
|
31041
|
+
return /* @__PURE__ */ React68.createElement(Text58, { color: "magenta" }, "\u2192 only in B");
|
|
30783
31042
|
}
|
|
30784
31043
|
function paneRecords(pair, side) {
|
|
30785
31044
|
if (!pair) return [];
|
|
@@ -30810,7 +31069,7 @@ markdown report written to ${opts.mdPath}`);
|
|
|
30810
31069
|
return;
|
|
30811
31070
|
}
|
|
30812
31071
|
if (wantTui) {
|
|
30813
|
-
const { waitUntilExit } = render2(
|
|
31072
|
+
const { waitUntilExit } = render2(React69.createElement(DiffApp, { report }), {
|
|
30814
31073
|
exitOnCtrlC: true,
|
|
30815
31074
|
patchConsole: false
|
|
30816
31075
|
});
|
|
@@ -31359,8 +31618,8 @@ function makeTtyWriter() {
|
|
|
31359
31618
|
}
|
|
31360
31619
|
|
|
31361
31620
|
// src/cli/commands/mcp-browse.tsx
|
|
31362
|
-
import { Box as
|
|
31363
|
-
import
|
|
31621
|
+
import { Box as Box54, Text as Text59, render as render3, useApp as useApp3, useInput as useInput4 } from "ink";
|
|
31622
|
+
import React70, { useCallback as useCallback12, useEffect as useEffect13, useMemo as useMemo8, useState as useState24 } from "react";
|
|
31364
31623
|
var VISIBLE_ROWS2 = 12;
|
|
31365
31624
|
function rankAndFilter2(entries, query) {
|
|
31366
31625
|
const q = query.trim().toLowerCase();
|
|
@@ -31374,7 +31633,7 @@ function rankAndFilter2(entries, query) {
|
|
|
31374
31633
|
}
|
|
31375
31634
|
function McpBrowseApp() {
|
|
31376
31635
|
const app = useApp3();
|
|
31377
|
-
const [state, setState] =
|
|
31636
|
+
const [state, setState] = useState24({
|
|
31378
31637
|
handle: null,
|
|
31379
31638
|
loading: true,
|
|
31380
31639
|
query: "",
|
|
@@ -31486,17 +31745,17 @@ function McpBrowseApp() {
|
|
|
31486
31745
|
Math.min(state.selected - Math.floor(VISIBLE_ROWS2 / 2), filtered.length - VISIBLE_ROWS2)
|
|
31487
31746
|
);
|
|
31488
31747
|
const window = filtered.slice(Math.max(0, start), Math.max(0, start) + VISIBLE_ROWS2);
|
|
31489
|
-
return /* @__PURE__ */
|
|
31748
|
+
return /* @__PURE__ */ React70.createElement(Box54, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React70.createElement(Box54, null, /* @__PURE__ */ React70.createElement(Text59, { bold: true, color: "cyan" }, "\u25C8 MCP marketplace"), /* @__PURE__ */ React70.createElement(Text59, { dimColor: true }, ` \xB7 ${state.status}`)), /* @__PURE__ */ React70.createElement(Box54, { marginTop: 1 }, /* @__PURE__ */ React70.createElement(Text59, null, "search: "), /* @__PURE__ */ React70.createElement(Text59, { color: "white" }, state.query || "(type to filter)"), /* @__PURE__ */ React70.createElement(Text59, { dimColor: true }, ` ${filtered.length} match${filtered.length === 1 ? "" : "es"}`)), /* @__PURE__ */ React70.createElement(Box54, { marginTop: 1, flexDirection: "column" }, window.length === 0 ? /* @__PURE__ */ React70.createElement(Text59, { dimColor: true }, state.loading ? "loading\u2026" : "no entries") : window.map((e, i) => {
|
|
31490
31749
|
const idx = (start || 0) + i;
|
|
31491
31750
|
const active = idx === state.selected;
|
|
31492
31751
|
const tag2 = e.source === "official" ? "[off]" : e.source === "smithery" ? "[smt]" : "[loc]";
|
|
31493
31752
|
const pop = e.popularity !== void 0 ? ` \xB7 ${e.popularity.toLocaleString()}` : "";
|
|
31494
|
-
return /* @__PURE__ */
|
|
31495
|
-
})), selected ? /* @__PURE__ */
|
|
31753
|
+
return /* @__PURE__ */ React70.createElement(Box54, { key: e.name }, /* @__PURE__ */ React70.createElement(Text59, { color: active ? "cyan" : void 0 }, active ? "\u25B8 " : " "), /* @__PURE__ */ React70.createElement(Text59, { bold: active }, e.name.padEnd(40).slice(0, 40)), /* @__PURE__ */ React70.createElement(Text59, { dimColor: true }, ` ${tag2}${pop}`));
|
|
31754
|
+
})), selected ? /* @__PURE__ */ React70.createElement(Box54, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React70.createElement(Text59, { bold: true, color: "white" }, selected.title), selected.description ? /* @__PURE__ */ React70.createElement(Text59, { dimColor: true }, selected.description.slice(0, 160)) : null, selected.install ? /* @__PURE__ */ React70.createElement(Text59, { dimColor: true }, `spec: ${selected.install.runtime} ${selected.install.packageId ?? selected.install.url ?? "\u2014"} \xB7 ${selected.install.transport}`) : /* @__PURE__ */ React70.createElement(Text59, { dimColor: true }, "(smithery listing \u2014 install info not exposed)"), selected.install?.requiredEnv?.length ? /* @__PURE__ */ React70.createElement(Text59, { color: "yellow" }, `needs: ${selected.install.requiredEnv.join(", ")}`) : null) : null, /* @__PURE__ */ React70.createElement(Box54, { marginTop: 1 }, /* @__PURE__ */ React70.createElement(Text59, { dimColor: true }, "type to filter \xB7 \u2191\u2193 pick \xB7 enter install \xB7 tab load more \xB7 esc quit")));
|
|
31496
31755
|
}
|
|
31497
31756
|
async function mcpBrowseCommand(_opts = {}) {
|
|
31498
31757
|
loadDotenv();
|
|
31499
|
-
const { waitUntilExit } = render3(/* @__PURE__ */
|
|
31758
|
+
const { waitUntilExit } = render3(/* @__PURE__ */ React70.createElement(McpBrowseApp, null), {
|
|
31500
31759
|
exitOnCtrlC: true,
|
|
31501
31760
|
patchConsole: false
|
|
31502
31761
|
});
|
|
@@ -31867,16 +32126,16 @@ function pruneSessionsCommand(opts) {
|
|
|
31867
32126
|
|
|
31868
32127
|
// src/cli/commands/replay.ts
|
|
31869
32128
|
import { render as render4 } from "ink";
|
|
31870
|
-
import
|
|
32129
|
+
import React73 from "react";
|
|
31871
32130
|
|
|
31872
32131
|
// src/cli/ui/ReplayApp.tsx
|
|
31873
|
-
import { Box as
|
|
31874
|
-
import
|
|
32132
|
+
import { Box as Box56, Static as Static2, Text as Text61, useApp as useApp4, useInput as useInput5 } from "ink";
|
|
32133
|
+
import React72, { useMemo as useMemo9, useState as useState25 } from "react";
|
|
31875
32134
|
|
|
31876
32135
|
// src/cli/ui/StatsPanel.tsx
|
|
31877
32136
|
import { basename as basename4 } from "path";
|
|
31878
|
-
import { Box as
|
|
31879
|
-
import
|
|
32137
|
+
import { Box as Box55, Text as Text60, useStdout as useStdout16 } from "ink";
|
|
32138
|
+
import React71 from "react";
|
|
31880
32139
|
import stringWidth2 from "string-width";
|
|
31881
32140
|
var COLD_START_TURNS = 3;
|
|
31882
32141
|
function StatsPanel({
|
|
@@ -31892,7 +32151,7 @@ function StatsPanel({
|
|
|
31892
32151
|
sessionName
|
|
31893
32152
|
}) {
|
|
31894
32153
|
const coldStart = summary.turns <= COLD_START_TURNS;
|
|
31895
|
-
return /* @__PURE__ */
|
|
32154
|
+
return /* @__PURE__ */ React71.createElement(Box55, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React71.createElement(
|
|
31896
32155
|
ChromeRow,
|
|
31897
32156
|
{
|
|
31898
32157
|
editMode,
|
|
@@ -31906,7 +32165,7 @@ function StatsPanel({
|
|
|
31906
32165
|
updateAvailable,
|
|
31907
32166
|
balance: balance ?? null
|
|
31908
32167
|
}
|
|
31909
|
-
), /* @__PURE__ */
|
|
32168
|
+
), /* @__PURE__ */ React71.createElement(ChromeRule, null), budgetUsd !== null && budgetUsd !== void 0 ? /* @__PURE__ */ React71.createElement(BudgetRow, { spent: summary.totalCostUsd, cap: budgetUsd }) : null);
|
|
31910
32169
|
}
|
|
31911
32170
|
function ChromeRow({
|
|
31912
32171
|
editMode,
|
|
@@ -31929,7 +32188,7 @@ function ChromeRow({
|
|
|
31929
32188
|
const costLabel = `[${formatCost(summary.totalCostUsd, balance?.currency)}]`;
|
|
31930
32189
|
const cacheLabel = "[c \u25B0\u25B0\u25B0\u25B0\u25B0\u25B0 100%]";
|
|
31931
32190
|
const updateLabel = updateAvailable ? `\u2191 ${updateAvailable}` : "";
|
|
31932
|
-
const { stdout: stdout4 } =
|
|
32191
|
+
const { stdout: stdout4 } = useStdout16();
|
|
31933
32192
|
const cols = (stdout4?.columns ?? 80) - 2;
|
|
31934
32193
|
const SEP_DOT = stringWidth2(" \xB7 ");
|
|
31935
32194
|
const SEP_ARROW = stringWidth2(" \u203A ");
|
|
@@ -31951,15 +32210,15 @@ function ChromeRow({
|
|
|
31951
32210
|
if (showSession) budget3 -= sessionW;
|
|
31952
32211
|
const showUpdate = updateW > 0 && budget3 >= updateW;
|
|
31953
32212
|
if (showUpdate) budget3 -= updateW;
|
|
31954
|
-
return /* @__PURE__ */
|
|
31955
|
-
|
|
32213
|
+
return /* @__PURE__ */ React71.createElement(Box55, null, /* @__PURE__ */ React71.createElement(Text60, { bold: true, color: GRADIENT[0] }, "\u25C8 "), /* @__PURE__ */ React71.createElement(Text60, { color: COLOR.brand, bold: true }, "reasonix"), projectName ? /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement(Text60, { color: COLOR.info, dimColor: true }, " \xB7 "), /* @__PURE__ */ React71.createElement(Text60, null, projectName), showSession && sessionName ? /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement(Text60, { color: COLOR.info, dimColor: true }, " \u203A "), /* @__PURE__ */ React71.createElement(Text60, { color: COLOR.info }, sessionName)) : null) : null, /* @__PURE__ */ React71.createElement(Box55, { flexGrow: 1 }), showUpdate ? /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement(Text60, { color: COLOR.warn, bold: true }, updateLabel), /* @__PURE__ */ React71.createElement(Text60, null, " ")) : null, modePill ? /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement(Text60, { color: modePill.color, bold: true }, `[${modePill.label}]`), /* @__PURE__ */ React71.createElement(Text60, null, " ")) : null, proPill ? /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement(Text60, { color: proPill.color, bold: true }, `[${proPill.label}]`), /* @__PURE__ */ React71.createElement(Text60, null, " ")) : null, /* @__PURE__ */ React71.createElement(
|
|
32214
|
+
Text60,
|
|
31956
32215
|
{
|
|
31957
32216
|
color: summary.turns === 0 || coldStart ? COLOR.info : sessionCostColor(summary.totalCostUsd),
|
|
31958
32217
|
bold: summary.turns > 0 && !coldStart,
|
|
31959
32218
|
dimColor: summary.turns === 0 || coldStart
|
|
31960
32219
|
},
|
|
31961
32220
|
costLabel
|
|
31962
|
-
), showBalance && balance ? /* @__PURE__ */
|
|
32221
|
+
), showBalance && balance ? /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement(Text60, null, " "), /* @__PURE__ */ React71.createElement(Text60, { color: balance.total < 1 ? COLOR.err : balance.total < 5 ? COLOR.warn : COLOR.ok }, balanceLabel)) : null, showCache ? /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement(Text60, null, " "), /* @__PURE__ */ React71.createElement(Text60, { dimColor: true }, "["), /* @__PURE__ */ React71.createElement(Text60, { dimColor: true }, "c "), /* @__PURE__ */ React71.createElement(
|
|
31963
32222
|
Bar,
|
|
31964
32223
|
{
|
|
31965
32224
|
ratio: summary.cacheHitRatio,
|
|
@@ -31967,7 +32226,7 @@ function ChromeRow({
|
|
|
31967
32226
|
cells: 6,
|
|
31968
32227
|
dim: coldStart
|
|
31969
32228
|
}
|
|
31970
|
-
), /* @__PURE__ */
|
|
32229
|
+
), /* @__PURE__ */ React71.createElement(Text60, null, " "), /* @__PURE__ */ React71.createElement(Text60, { color: coldStart ? void 0 : cacheColor, dimColor: coldStart }, coldStart && summary.turns === 0 ? "\u2014" : `${cachePct}%`), /* @__PURE__ */ React71.createElement(Text60, { dimColor: true }, "]")) : null);
|
|
31971
32230
|
}
|
|
31972
32231
|
function pickModePill(planMode, editMode) {
|
|
31973
32232
|
if (planMode) return { label: "PLAN", color: COLOR.err };
|
|
@@ -31979,7 +32238,7 @@ function pickModePill(planMode, editMode) {
|
|
|
31979
32238
|
function BudgetRow({ spent, cap }) {
|
|
31980
32239
|
const pct2 = Math.max(0, spent / cap * 100);
|
|
31981
32240
|
const color2 = pct2 >= 100 ? "#f87171" : pct2 >= 80 ? "#fbbf24" : "#94a3b8";
|
|
31982
|
-
return /* @__PURE__ */
|
|
32241
|
+
return /* @__PURE__ */ React71.createElement(Box55, null, /* @__PURE__ */ React71.createElement(Text60, { dimColor: true }, " budget "), /* @__PURE__ */ React71.createElement(Text60, { color: color2 }, `$${spent.toFixed(4)} / $${cap.toFixed(2)}`, /* @__PURE__ */ React71.createElement(Text60, { dimColor: true }, ` (${pct2.toFixed(0)}%)`)));
|
|
31983
32242
|
}
|
|
31984
32243
|
function sessionCostColor(cost2) {
|
|
31985
32244
|
if (cost2 <= 0) return void 0;
|
|
@@ -31992,7 +32251,7 @@ function sessionCostColor(cost2) {
|
|
|
31992
32251
|
function ReplayApp({ meta, pages }) {
|
|
31993
32252
|
const { exit: exit2 } = useApp4();
|
|
31994
32253
|
const maxIdx = Math.max(0, pages.length - 1);
|
|
31995
|
-
const [idx, setIdx] =
|
|
32254
|
+
const [idx, setIdx] = useState25(maxIdx);
|
|
31996
32255
|
useInput5((input, key) => {
|
|
31997
32256
|
if (input === "q" || key.ctrl && input === "c") {
|
|
31998
32257
|
exit2();
|
|
@@ -32028,7 +32287,7 @@ function ReplayApp({ meta, pages }) {
|
|
|
32028
32287
|
const prefixHash = cumStats.prefixHashes.length === 1 ? cumStats.prefixHashes[0].slice(0, 16) : cumStats.prefixHashes.length === 0 ? "(untracked)" : `(churned \xD7${cumStats.prefixHashes.length})`;
|
|
32029
32288
|
const currentPage = pages[idx];
|
|
32030
32289
|
const progressLabel = pages.length === 0 ? "empty transcript" : `turn ${idx + 1} / ${pages.length}`;
|
|
32031
|
-
return /* @__PURE__ */
|
|
32290
|
+
return /* @__PURE__ */ React72.createElement(Box56, { flexDirection: "column" }, /* @__PURE__ */ React72.createElement(StatsPanel, { summary }), /* @__PURE__ */ React72.createElement(Box56, { flexDirection: "column", marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React72.createElement(Box56, { justifyContent: "space-between" }, /* @__PURE__ */ React72.createElement(Text61, { color: "cyan", bold: true }, progressLabel), meta ? /* @__PURE__ */ React72.createElement(Text61, { dimColor: true }, meta.source, meta.task ? ` \xB7 ${meta.task}` : "", meta.mode ? ` \xB7 ${meta.mode}` : "") : null), currentPage ? /* @__PURE__ */ React72.createElement(Static2, { items: currentPage.records.map((rec, i) => ({ key: `${idx}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React72.createElement(RecordView, { key, rec })) : /* @__PURE__ */ React72.createElement(Text61, { dimColor: true, italic: true }, "no records")), /* @__PURE__ */ React72.createElement(Box56, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React72.createElement(Text61, { dimColor: true }, /* @__PURE__ */ React72.createElement(Text61, { bold: true }, "j"), "/", /* @__PURE__ */ React72.createElement(Text61, { bold: true }, "\u2193"), "/", /* @__PURE__ */ React72.createElement(Text61, { bold: true }, "space"), " next \xB7 ", /* @__PURE__ */ React72.createElement(Text61, { bold: true }, "k"), "/", /* @__PURE__ */ React72.createElement(Text61, { bold: true }, "\u2191"), " prev \xB7 ", /* @__PURE__ */ React72.createElement(Text61, { bold: true }, "g"), " first \xB7 ", /* @__PURE__ */ React72.createElement(Text61, { bold: true }, "G"), " last \xB7", " ", /* @__PURE__ */ React72.createElement(Text61, { bold: true }, "q"), " quit")));
|
|
32032
32291
|
}
|
|
32033
32292
|
|
|
32034
32293
|
// src/cli/commands/replay.ts
|
|
@@ -32040,7 +32299,7 @@ async function replayCommand(opts) {
|
|
|
32040
32299
|
}
|
|
32041
32300
|
const { parsed } = replayFromFile(opts.path);
|
|
32042
32301
|
const pages = groupRecordsByTurn(parsed.records);
|
|
32043
|
-
const { waitUntilExit } = render4(
|
|
32302
|
+
const { waitUntilExit } = render4(React73.createElement(ReplayApp, { meta: parsed.meta, pages }), {
|
|
32044
32303
|
exitOnCtrlC: true,
|
|
32045
32304
|
patchConsole: false
|
|
32046
32305
|
});
|
|
@@ -32372,29 +32631,29 @@ function truncate6(s, max) {
|
|
|
32372
32631
|
|
|
32373
32632
|
// src/cli/commands/setup.tsx
|
|
32374
32633
|
import { render as render5 } from "ink";
|
|
32375
|
-
import
|
|
32634
|
+
import React75 from "react";
|
|
32376
32635
|
|
|
32377
32636
|
// src/cli/ui/Wizard.tsx
|
|
32378
32637
|
import { mkdirSync as mkdirSync15, statSync as statSync12 } from "fs";
|
|
32379
|
-
import { Box as
|
|
32638
|
+
import { Box as Box57, Text as Text62, useApp as useApp5, useInput as useInput6 } from "ink";
|
|
32380
32639
|
import TextInput from "ink-text-input";
|
|
32381
|
-
import
|
|
32640
|
+
import React74, { useState as useState26 } from "react";
|
|
32382
32641
|
var CATALOG_BY_NAME = new Map(MCP_CATALOG.map((e) => [e.name, e]));
|
|
32383
32642
|
function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
32384
32643
|
const { exit: exit2 } = useApp5();
|
|
32385
|
-
const [step, setStep] =
|
|
32386
|
-
const [data, setData] =
|
|
32644
|
+
const [step, setStep] = useState26(existingApiKey ? "preset" : "apiKey");
|
|
32645
|
+
const [data, setData] = useState26({
|
|
32387
32646
|
apiKey: existingApiKey ?? "",
|
|
32388
32647
|
preset: initial?.preset ?? "auto",
|
|
32389
32648
|
selectedCatalog: deriveInitialCatalog(initial?.mcp ?? []),
|
|
32390
32649
|
catalogArgs: {}
|
|
32391
32650
|
});
|
|
32392
|
-
const [error, setError] =
|
|
32651
|
+
const [error, setError] = useState26(null);
|
|
32393
32652
|
useInput6((_input, key) => {
|
|
32394
32653
|
if (key.escape && step !== "saved" && onCancel) onCancel();
|
|
32395
32654
|
});
|
|
32396
32655
|
if (step === "apiKey") {
|
|
32397
|
-
return /* @__PURE__ */
|
|
32656
|
+
return /* @__PURE__ */ React74.createElement(
|
|
32398
32657
|
ApiKeyStep,
|
|
32399
32658
|
{
|
|
32400
32659
|
onSubmit: (key) => {
|
|
@@ -32408,7 +32667,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
32408
32667
|
);
|
|
32409
32668
|
}
|
|
32410
32669
|
if (step === "preset") {
|
|
32411
|
-
return /* @__PURE__ */
|
|
32670
|
+
return /* @__PURE__ */ React74.createElement(StepFrame, { title: "Pick a preset", step: 1, total: 3 }, /* @__PURE__ */ React74.createElement(
|
|
32412
32671
|
SingleSelect,
|
|
32413
32672
|
{
|
|
32414
32673
|
items: presetItems(),
|
|
@@ -32418,10 +32677,10 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
32418
32677
|
setStep("mcp");
|
|
32419
32678
|
}
|
|
32420
32679
|
}
|
|
32421
|
-
), /* @__PURE__ */
|
|
32680
|
+
), /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { dimColor: true }, "[\u2191\u2193] navigate \xB7 [Enter] confirm \xB7 [Esc] cancel")));
|
|
32422
32681
|
}
|
|
32423
32682
|
if (step === "mcp") {
|
|
32424
|
-
return /* @__PURE__ */
|
|
32683
|
+
return /* @__PURE__ */ React74.createElement(StepFrame, { title: "Which MCP servers should Reasonix wire up for you?", step: 2, total: 3 }, /* @__PURE__ */ React74.createElement(
|
|
32425
32684
|
MultiSelect,
|
|
32426
32685
|
{
|
|
32427
32686
|
items: mcpItems(),
|
|
@@ -32446,7 +32705,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
32446
32705
|
}
|
|
32447
32706
|
const currentName = pending[0];
|
|
32448
32707
|
const entry = CATALOG_BY_NAME.get(currentName);
|
|
32449
|
-
return /* @__PURE__ */
|
|
32708
|
+
return /* @__PURE__ */ React74.createElement(
|
|
32450
32709
|
McpArgsStep,
|
|
32451
32710
|
{
|
|
32452
32711
|
entry,
|
|
@@ -32464,7 +32723,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
32464
32723
|
}
|
|
32465
32724
|
if (step === "review") {
|
|
32466
32725
|
const specs = data.selectedCatalog.map((name) => buildSpec(name, data.catalogArgs));
|
|
32467
|
-
return /* @__PURE__ */
|
|
32726
|
+
return /* @__PURE__ */ React74.createElement(StepFrame, { title: "Ready to save", step: 3, total: 3 }, /* @__PURE__ */ React74.createElement(Box57, { flexDirection: "column" }, /* @__PURE__ */ React74.createElement(SummaryLine, { label: "API key", value: redactKey(data.apiKey) }), /* @__PURE__ */ React74.createElement(SummaryLine, { label: "Preset", value: data.preset }), /* @__PURE__ */ React74.createElement(
|
|
32468
32727
|
SummaryLine,
|
|
32469
32728
|
{
|
|
32470
32729
|
label: "MCP",
|
|
@@ -32472,8 +32731,8 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
32472
32731
|
}
|
|
32473
32732
|
), specs.map((spec, i) => (
|
|
32474
32733
|
// biome-ignore lint/suspicious/noArrayIndexKey: review-only render, order fixed
|
|
32475
|
-
/* @__PURE__ */
|
|
32476
|
-
)), /* @__PURE__ */
|
|
32734
|
+
/* @__PURE__ */ React74.createElement(Box57, { key: i, paddingLeft: 14 }, /* @__PURE__ */ React74.createElement(Text62, { dimColor: true }, "\xB7 ", spec))
|
|
32735
|
+
)), /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, null, "Saves to ", defaultConfigPath())), error ? /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { color: "red" }, error)) : null, /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { dimColor: true }, "[Enter] save \xB7 [Esc] cancel"))), /* @__PURE__ */ React74.createElement(
|
|
32477
32736
|
ReviewConfirm,
|
|
32478
32737
|
{
|
|
32479
32738
|
onConfirm: () => {
|
|
@@ -32499,15 +32758,15 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
32499
32758
|
}
|
|
32500
32759
|
));
|
|
32501
32760
|
}
|
|
32502
|
-
return /* @__PURE__ */
|
|
32761
|
+
return /* @__PURE__ */ React74.createElement(Box57, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React74.createElement(Text62, { bold: true, color: "green" }, "\u25B8 Saved."), /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, null, "Run `reasonix` any time to start chatting \u2014 your settings are remembered.")), /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { dimColor: true }, "[Enter] to exit")), /* @__PURE__ */ React74.createElement(ExitOnEnter, { onExit: exit2 }));
|
|
32503
32762
|
}
|
|
32504
32763
|
function ApiKeyStep({
|
|
32505
32764
|
onSubmit,
|
|
32506
32765
|
error,
|
|
32507
32766
|
onError
|
|
32508
32767
|
}) {
|
|
32509
|
-
const [value, setValue] =
|
|
32510
|
-
return /* @__PURE__ */
|
|
32768
|
+
const [value, setValue] = useState26("");
|
|
32769
|
+
return /* @__PURE__ */ React74.createElement(Box57, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React74.createElement(Text62, { bold: true, color: "cyan" }, "Welcome to Reasonix."), /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, null, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React74.createElement(Text62, { dimColor: true }, "Get one at: https://platform.deepseek.com/api_keys"), /* @__PURE__ */ React74.createElement(Text62, { dimColor: true }, "Saved locally to ", defaultConfigPath()), /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { bold: true, color: "cyan" }, "key \u203A "), /* @__PURE__ */ React74.createElement(
|
|
32511
32770
|
TextInput,
|
|
32512
32771
|
{
|
|
32513
32772
|
value,
|
|
@@ -32524,7 +32783,7 @@ function ApiKeyStep({
|
|
|
32524
32783
|
mask: "\u2022",
|
|
32525
32784
|
placeholder: "sk-..."
|
|
32526
32785
|
}
|
|
32527
|
-
)), error ? /* @__PURE__ */
|
|
32786
|
+
)), error ? /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { color: "red" }, error)) : value ? /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { dimColor: true }, "preview: ", redactKey(value))) : null);
|
|
32528
32787
|
}
|
|
32529
32788
|
function McpArgsStep({
|
|
32530
32789
|
entry,
|
|
@@ -32532,8 +32791,8 @@ function McpArgsStep({
|
|
|
32532
32791
|
onSubmit,
|
|
32533
32792
|
onError
|
|
32534
32793
|
}) {
|
|
32535
|
-
const [value, setValue] =
|
|
32536
|
-
const [pendingCreate, setPendingCreate] =
|
|
32794
|
+
const [value, setValue] = useState26("");
|
|
32795
|
+
const [pendingCreate, setPendingCreate] = useState26(null);
|
|
32537
32796
|
useInput6((input, key) => {
|
|
32538
32797
|
if (!pendingCreate) return;
|
|
32539
32798
|
const ch = input.toLowerCase();
|
|
@@ -32555,9 +32814,9 @@ function McpArgsStep({
|
|
|
32555
32814
|
}
|
|
32556
32815
|
});
|
|
32557
32816
|
if (pendingCreate) {
|
|
32558
|
-
return /* @__PURE__ */
|
|
32817
|
+
return /* @__PURE__ */ React74.createElement(StepFrame, { title: `Configure ${entry.name}`, step: 2, total: 3 }, /* @__PURE__ */ React74.createElement(Box57, { flexDirection: "column" }, /* @__PURE__ */ React74.createElement(Text62, null, "Directory ", /* @__PURE__ */ React74.createElement(Text62, { bold: true }, pendingCreate), " doesn't exist."), /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { dimColor: true }, "[Y/Enter] create it (mkdir -p) \xB7 [N/Esc] enter a different path")), error ? /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { color: "red" }, error)) : null));
|
|
32559
32818
|
}
|
|
32560
|
-
return /* @__PURE__ */
|
|
32819
|
+
return /* @__PURE__ */ React74.createElement(StepFrame, { title: `Configure ${entry.name}`, step: 2, total: 3 }, /* @__PURE__ */ React74.createElement(Box57, { flexDirection: "column" }, /* @__PURE__ */ React74.createElement(Text62, null, entry.summary), entry.note ? /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { dimColor: true }, entry.note)) : null, /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, null, "Required parameter: "), /* @__PURE__ */ React74.createElement(Text62, { bold: true }, entry.userArgs)), /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { bold: true, color: "cyan" }, entry.userArgs, " \u203A "), /* @__PURE__ */ React74.createElement(
|
|
32561
32820
|
TextInput,
|
|
32562
32821
|
{
|
|
32563
32822
|
value,
|
|
@@ -32584,7 +32843,7 @@ function McpArgsStep({
|
|
|
32584
32843
|
},
|
|
32585
32844
|
placeholder: placeholderFor(entry)
|
|
32586
32845
|
}
|
|
32587
|
-
)), error ? /* @__PURE__ */
|
|
32846
|
+
)), error ? /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1 }, /* @__PURE__ */ React74.createElement(Text62, { color: "red" }, error)) : null));
|
|
32588
32847
|
}
|
|
32589
32848
|
function checkFilesystemPath(p) {
|
|
32590
32849
|
try {
|
|
@@ -32611,10 +32870,10 @@ function StepFrame({
|
|
|
32611
32870
|
total,
|
|
32612
32871
|
children
|
|
32613
32872
|
}) {
|
|
32614
|
-
return /* @__PURE__ */
|
|
32873
|
+
return /* @__PURE__ */ React74.createElement(Box57, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React74.createElement(Box57, null, /* @__PURE__ */ React74.createElement(Text62, { dimColor: true }, "Step ", step, "/", total, " \xB7", " "), /* @__PURE__ */ React74.createElement(Text62, { bold: true, color: "cyan" }, title)), /* @__PURE__ */ React74.createElement(Box57, { marginTop: 1, flexDirection: "column" }, children));
|
|
32615
32874
|
}
|
|
32616
32875
|
function SummaryLine({ label, value }) {
|
|
32617
|
-
return /* @__PURE__ */
|
|
32876
|
+
return /* @__PURE__ */ React74.createElement(Box57, null, /* @__PURE__ */ React74.createElement(Text62, null, label.padEnd(12)), /* @__PURE__ */ React74.createElement(Text62, { bold: true }, value));
|
|
32618
32877
|
}
|
|
32619
32878
|
function presetItems() {
|
|
32620
32879
|
return ["auto", "flash", "pro"].map((name) => ({
|
|
@@ -32670,7 +32929,7 @@ async function setupCommand(_opts = {}) {
|
|
|
32670
32929
|
const existingKey = loadApiKey();
|
|
32671
32930
|
const existing = readConfig();
|
|
32672
32931
|
const { waitUntilExit, unmount } = render5(
|
|
32673
|
-
/* @__PURE__ */
|
|
32932
|
+
/* @__PURE__ */ React75.createElement(
|
|
32674
32933
|
Wizard,
|
|
32675
32934
|
{
|
|
32676
32935
|
existingApiKey: existingKey,
|