reasonix 0.5.6 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +358 -191
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +60 -1
- package/dist/index.js +108 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -2570,9 +2570,79 @@ function formatLoopError(err) {
|
|
|
2570
2570
|
}
|
|
2571
2571
|
|
|
2572
2572
|
// src/at-mentions.ts
|
|
2573
|
-
import { existsSync as existsSync4, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
|
|
2574
|
-
import { isAbsolute, relative, resolve } from "path";
|
|
2573
|
+
import { existsSync as existsSync4, readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
2574
|
+
import { isAbsolute, join as join5, relative, resolve } from "path";
|
|
2575
2575
|
var DEFAULT_AT_MENTION_MAX_BYTES = 64 * 1024;
|
|
2576
|
+
var DEFAULT_PICKER_IGNORE_DIRS = [
|
|
2577
|
+
"node_modules",
|
|
2578
|
+
".git",
|
|
2579
|
+
"dist",
|
|
2580
|
+
"build",
|
|
2581
|
+
".next",
|
|
2582
|
+
"out",
|
|
2583
|
+
"coverage",
|
|
2584
|
+
".cache",
|
|
2585
|
+
".vscode",
|
|
2586
|
+
".idea",
|
|
2587
|
+
"target",
|
|
2588
|
+
".venv",
|
|
2589
|
+
"venv",
|
|
2590
|
+
"__pycache__"
|
|
2591
|
+
];
|
|
2592
|
+
function listFilesSync(root, opts = {}) {
|
|
2593
|
+
const maxResults = Math.max(1, opts.maxResults ?? 500);
|
|
2594
|
+
const ignore = new Set(opts.ignoreDirs ?? DEFAULT_PICKER_IGNORE_DIRS);
|
|
2595
|
+
const rootAbs = resolve(root);
|
|
2596
|
+
const out = [];
|
|
2597
|
+
const walk2 = (dirAbs, dirRel) => {
|
|
2598
|
+
if (out.length >= maxResults) return;
|
|
2599
|
+
let entries;
|
|
2600
|
+
try {
|
|
2601
|
+
entries = readdirSync2(dirAbs, { withFileTypes: true });
|
|
2602
|
+
} catch {
|
|
2603
|
+
return;
|
|
2604
|
+
}
|
|
2605
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
2606
|
+
for (const ent of entries) {
|
|
2607
|
+
if (out.length >= maxResults) return;
|
|
2608
|
+
const relPath = dirRel ? `${dirRel}/${ent.name}` : ent.name;
|
|
2609
|
+
if (ent.isDirectory()) {
|
|
2610
|
+
if (ent.name.startsWith(".") || ignore.has(ent.name)) continue;
|
|
2611
|
+
walk2(join5(dirAbs, ent.name), relPath);
|
|
2612
|
+
} else if (ent.isFile()) {
|
|
2613
|
+
out.push(relPath);
|
|
2614
|
+
}
|
|
2615
|
+
}
|
|
2616
|
+
};
|
|
2617
|
+
walk2(rootAbs, "");
|
|
2618
|
+
return out;
|
|
2619
|
+
}
|
|
2620
|
+
var AT_PICKER_PREFIX = /(?:^|\s)@([a-zA-Z0-9_./\\-]*)$/;
|
|
2621
|
+
function detectAtPicker(input) {
|
|
2622
|
+
const m = AT_PICKER_PREFIX.exec(input);
|
|
2623
|
+
if (!m) return null;
|
|
2624
|
+
const query = m[1] ?? "";
|
|
2625
|
+
const atOffset = input.length - query.length - 1;
|
|
2626
|
+
return { query, atOffset };
|
|
2627
|
+
}
|
|
2628
|
+
function rankPickerCandidates(files, query, limit = 40) {
|
|
2629
|
+
if (!query) return files.slice(0, limit);
|
|
2630
|
+
const needle = query.toLowerCase();
|
|
2631
|
+
const scored = [];
|
|
2632
|
+
for (const f of files) {
|
|
2633
|
+
const lower = f.toLowerCase();
|
|
2634
|
+
const hit = lower.indexOf(needle);
|
|
2635
|
+
if (hit < 0) continue;
|
|
2636
|
+
const slash = lower.lastIndexOf("/");
|
|
2637
|
+
const base = slash >= 0 ? lower.slice(slash + 1) : lower;
|
|
2638
|
+
let score = 2;
|
|
2639
|
+
if (base.startsWith(needle)) score = 0;
|
|
2640
|
+
else if (lower.startsWith(needle)) score = 1;
|
|
2641
|
+
scored.push({ path: f, score: score * 1e4 + hit });
|
|
2642
|
+
}
|
|
2643
|
+
scored.sort((a, b) => a.score - b.score);
|
|
2644
|
+
return scored.slice(0, limit).map((s) => s.path);
|
|
2645
|
+
}
|
|
2576
2646
|
var AT_MENTION_PATTERN = /(?<=^|\s)@([a-zA-Z0-9_./\\-]+)/g;
|
|
2577
2647
|
function expandAtMentions(text, rootDir, opts = {}) {
|
|
2578
2648
|
const maxBytes = opts.maxBytes ?? DEFAULT_AT_MENTION_MAX_BYTES;
|
|
@@ -5309,7 +5379,7 @@ function sep() {
|
|
|
5309
5379
|
// src/version.ts
|
|
5310
5380
|
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "fs";
|
|
5311
5381
|
import { homedir as homedir4 } from "os";
|
|
5312
|
-
import { dirname as dirname6, join as
|
|
5382
|
+
import { dirname as dirname6, join as join7 } from "path";
|
|
5313
5383
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5314
5384
|
var REGISTRY_URL = "https://registry.npmjs.org/reasonix/latest";
|
|
5315
5385
|
var LATEST_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -5318,7 +5388,7 @@ function readPackageVersion() {
|
|
|
5318
5388
|
try {
|
|
5319
5389
|
let dir = dirname6(fileURLToPath2(import.meta.url));
|
|
5320
5390
|
for (let i = 0; i < 6; i++) {
|
|
5321
|
-
const p =
|
|
5391
|
+
const p = join7(dir, "package.json");
|
|
5322
5392
|
if (existsSync7(p)) {
|
|
5323
5393
|
const pkg = JSON.parse(readFileSync9(p, "utf8"));
|
|
5324
5394
|
if (pkg?.name === "reasonix" && typeof pkg.version === "string") {
|
|
@@ -5335,7 +5405,7 @@ function readPackageVersion() {
|
|
|
5335
5405
|
}
|
|
5336
5406
|
var VERSION = readPackageVersion();
|
|
5337
5407
|
function cachePath(homeDirOverride) {
|
|
5338
|
-
return
|
|
5408
|
+
return join7(homeDirOverride ?? homedir4(), ".reasonix", "version-cache.json");
|
|
5339
5409
|
}
|
|
5340
5410
|
function readCache(homeDirOverride) {
|
|
5341
5411
|
try {
|
|
@@ -5410,9 +5480,9 @@ function isNpxInstall() {
|
|
|
5410
5480
|
// src/usage.ts
|
|
5411
5481
|
import { appendFileSync as appendFileSync2, existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync10, statSync as statSync4 } from "fs";
|
|
5412
5482
|
import { homedir as homedir5 } from "os";
|
|
5413
|
-
import { dirname as dirname7, join as
|
|
5483
|
+
import { dirname as dirname7, join as join8 } from "path";
|
|
5414
5484
|
function defaultUsageLogPath(homeDirOverride) {
|
|
5415
|
-
return
|
|
5485
|
+
return join8(homeDirOverride ?? homedir5(), ".reasonix", "usage.jsonl");
|
|
5416
5486
|
}
|
|
5417
5487
|
function appendUsage(input) {
|
|
5418
5488
|
const record = {
|
|
@@ -5536,11 +5606,11 @@ function formatLogSize(path = defaultUsageLogPath()) {
|
|
|
5536
5606
|
// src/cli/commands/chat.tsx
|
|
5537
5607
|
import { existsSync as existsSync10, statSync as statSync6 } from "fs";
|
|
5538
5608
|
import { render } from "ink";
|
|
5539
|
-
import
|
|
5609
|
+
import React16, { useState as useState7 } from "react";
|
|
5540
5610
|
|
|
5541
5611
|
// src/cli/ui/App.tsx
|
|
5542
|
-
import { Box as
|
|
5543
|
-
import
|
|
5612
|
+
import { Box as Box12, Static, Text as Text12, useApp, useInput as useInput4 } from "ink";
|
|
5613
|
+
import React13, { useCallback, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState5 } from "react";
|
|
5544
5614
|
|
|
5545
5615
|
// src/tools/skills.ts
|
|
5546
5616
|
function registerSkillTools(registry, opts = {}) {
|
|
@@ -5611,13 +5681,44 @@ ${skill.body}${argsBlock}`;
|
|
|
5611
5681
|
return registry;
|
|
5612
5682
|
}
|
|
5613
5683
|
|
|
5684
|
+
// src/cli/ui/AtMentionSuggestions.tsx
|
|
5685
|
+
import { Box, Text } from "ink";
|
|
5686
|
+
import React from "react";
|
|
5687
|
+
function AtMentionSuggestions({
|
|
5688
|
+
matches,
|
|
5689
|
+
selectedIndex,
|
|
5690
|
+
query
|
|
5691
|
+
}) {
|
|
5692
|
+
if (matches === null) return null;
|
|
5693
|
+
if (matches.length === 0) {
|
|
5694
|
+
return /* @__PURE__ */ React.createElement(Box, { paddingX: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, 'no files match "@', query, '"'), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " ", "\u2014 keep typing, or Backspace to edit. Paths resolve from the code root."));
|
|
5695
|
+
}
|
|
5696
|
+
const MAX = 8;
|
|
5697
|
+
const total = matches.length;
|
|
5698
|
+
const windowStart = total <= MAX ? 0 : Math.max(0, Math.min(selectedIndex - Math.floor(MAX / 2), total - MAX));
|
|
5699
|
+
const shown = matches.slice(windowStart, windowStart + MAX);
|
|
5700
|
+
const hiddenAbove = windowStart;
|
|
5701
|
+
const hiddenBelow = total - windowStart - shown.length;
|
|
5702
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingX: 1 }, hiddenAbove > 0 ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((path, i) => /* @__PURE__ */ React.createElement(FileRow, { key: path, path, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick \xB7 file content inlined on send"));
|
|
5703
|
+
}
|
|
5704
|
+
function FileRow({ path, isSelected }) {
|
|
5705
|
+
const marker = isSelected ? "\u25B8" : " ";
|
|
5706
|
+
const slash = path.lastIndexOf("/");
|
|
5707
|
+
const dir = slash >= 0 ? `${path.slice(0, slash)}/` : "";
|
|
5708
|
+
const base = slash >= 0 ? path.slice(slash + 1) : path;
|
|
5709
|
+
if (isSelected) {
|
|
5710
|
+
return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { bold: true, color: "cyan" }, marker, " ", base), /* @__PURE__ */ React.createElement(Text, { color: "cyan" }, dir ? ` ${dir}` : ""));
|
|
5711
|
+
}
|
|
5712
|
+
return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, marker, " ", base, dir ? ` ${dir}` : ""));
|
|
5713
|
+
}
|
|
5714
|
+
|
|
5614
5715
|
// src/cli/ui/EventLog.tsx
|
|
5615
|
-
import { Box as
|
|
5616
|
-
import
|
|
5716
|
+
import { Box as Box4, Text as Text4, useStdout } from "ink";
|
|
5717
|
+
import React5 from "react";
|
|
5617
5718
|
|
|
5618
5719
|
// src/cli/ui/PlanStateBlock.tsx
|
|
5619
|
-
import { Box, Text } from "ink";
|
|
5620
|
-
import
|
|
5720
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
5721
|
+
import React2 from "react";
|
|
5621
5722
|
function PlanStateBlock({ planState }) {
|
|
5622
5723
|
const fields = [];
|
|
5623
5724
|
if (planState.subgoals.length) fields.push(["subgoals", planState.subgoals, "cyan", false]);
|
|
@@ -5628,14 +5729,14 @@ function PlanStateBlock({ planState }) {
|
|
|
5628
5729
|
if (planState.rejectedPaths.length)
|
|
5629
5730
|
fields.push(["rejected", planState.rejectedPaths, "red", true]);
|
|
5630
5731
|
if (fields.length === 0) return null;
|
|
5631
|
-
return /* @__PURE__ */
|
|
5732
|
+
return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", marginBottom: 1 }, fields.map(([label, items, color, dim]) => /* @__PURE__ */ React2.createElement(Text2, { key: label }, /* @__PURE__ */ React2.createElement(Text2, { color, bold: true, dimColor: dim }, "\u2039 ", label), /* @__PURE__ */ React2.createElement(Text2, { dimColor: true }, ` (${items.length})`), /* @__PURE__ */ React2.createElement(Text2, null, `: ${items.join(" \xB7 ")}`))));
|
|
5632
5733
|
}
|
|
5633
5734
|
|
|
5634
5735
|
// src/cli/ui/markdown.tsx
|
|
5635
5736
|
import { readFileSync as readFileSync11, statSync as statSync5 } from "fs";
|
|
5636
|
-
import { isAbsolute as isAbsolute4, join as
|
|
5637
|
-
import { Box as
|
|
5638
|
-
import
|
|
5737
|
+
import { isAbsolute as isAbsolute4, join as join9 } from "path";
|
|
5738
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
5739
|
+
import React3 from "react";
|
|
5639
5740
|
var SUPERSCRIPT = {
|
|
5640
5741
|
"0": "\u2070",
|
|
5641
5742
|
"1": "\xB9",
|
|
@@ -5711,7 +5812,7 @@ function parseCitationUrl(url) {
|
|
|
5711
5812
|
function validateCitation(url, projectRoot) {
|
|
5712
5813
|
const parts = parseCitationUrl(url);
|
|
5713
5814
|
if (!parts || !parts.path) return { ok: false, reason: "empty path" };
|
|
5714
|
-
const fullPath = isAbsolute4(parts.path) ? parts.path :
|
|
5815
|
+
const fullPath = isAbsolute4(parts.path) ? parts.path : join9(projectRoot, parts.path);
|
|
5715
5816
|
let stat;
|
|
5716
5817
|
try {
|
|
5717
5818
|
stat = statSync5(fullPath);
|
|
@@ -5759,57 +5860,57 @@ function InlineMd({
|
|
|
5759
5860
|
for (const m of text.matchAll(INLINE_RE)) {
|
|
5760
5861
|
const start = m.index ?? 0;
|
|
5761
5862
|
if (start > last) {
|
|
5762
|
-
parts.push(/* @__PURE__ */
|
|
5863
|
+
parts.push(/* @__PURE__ */ React3.createElement(Text3, { key: `t${idx++}` }, text.slice(last, start)));
|
|
5763
5864
|
}
|
|
5764
5865
|
if (m[2] !== void 0 && m[3] !== void 0) {
|
|
5765
5866
|
const linkText = m[2];
|
|
5766
5867
|
const url = m[3];
|
|
5767
5868
|
if (isExternalUrl(url)) {
|
|
5768
5869
|
parts.push(
|
|
5769
|
-
/* @__PURE__ */
|
|
5870
|
+
/* @__PURE__ */ React3.createElement(Text3, { key: `l${idx++}`, color: "blue", underline: true }, linkText)
|
|
5770
5871
|
);
|
|
5771
5872
|
} else {
|
|
5772
5873
|
const status = citations?.get(url);
|
|
5773
5874
|
if (status && !status.ok) {
|
|
5774
5875
|
parts.push(
|
|
5775
|
-
/* @__PURE__ */
|
|
5876
|
+
/* @__PURE__ */ React3.createElement(Text3, { key: `l${idx++}`, color: "red", strikethrough: true }, `${linkText} \u2717`)
|
|
5776
5877
|
);
|
|
5777
5878
|
} else {
|
|
5778
5879
|
parts.push(
|
|
5779
|
-
/* @__PURE__ */
|
|
5880
|
+
/* @__PURE__ */ React3.createElement(Text3, { key: `l${idx++}`, color: "cyan", underline: true }, linkText)
|
|
5780
5881
|
);
|
|
5781
5882
|
}
|
|
5782
5883
|
}
|
|
5783
5884
|
} else if (m[4] !== void 0) {
|
|
5784
5885
|
parts.push(
|
|
5785
|
-
/* @__PURE__ */
|
|
5886
|
+
/* @__PURE__ */ React3.createElement(Text3, { key: `b${idx++}`, bold: true }, m[4])
|
|
5786
5887
|
);
|
|
5787
5888
|
} else if (m[5] !== void 0) {
|
|
5788
5889
|
const stripped = m[5].replace(/^(\w+)\s+/, "");
|
|
5789
5890
|
parts.push(
|
|
5790
|
-
/* @__PURE__ */
|
|
5891
|
+
/* @__PURE__ */ React3.createElement(Text3, { key: `c${idx++}`, color: "yellow" }, stripped)
|
|
5791
5892
|
);
|
|
5792
5893
|
} else if (m[6] !== void 0) {
|
|
5793
5894
|
parts.push(
|
|
5794
|
-
/* @__PURE__ */
|
|
5895
|
+
/* @__PURE__ */ React3.createElement(Text3, { key: `c${idx++}`, color: "yellow" }, m[6])
|
|
5795
5896
|
);
|
|
5796
5897
|
} else if (m[7] !== void 0) {
|
|
5797
5898
|
parts.push(
|
|
5798
|
-
/* @__PURE__ */
|
|
5899
|
+
/* @__PURE__ */ React3.createElement(Text3, { key: `i${idx++}`, italic: true }, m[7])
|
|
5799
5900
|
);
|
|
5800
5901
|
}
|
|
5801
5902
|
last = start + m[0].length;
|
|
5802
5903
|
}
|
|
5803
5904
|
if (last < text.length) {
|
|
5804
|
-
parts.push(/* @__PURE__ */
|
|
5905
|
+
parts.push(/* @__PURE__ */ React3.createElement(Text3, { key: `t${idx++}` }, text.slice(last)));
|
|
5805
5906
|
}
|
|
5806
5907
|
if (padTo !== void 0) {
|
|
5807
5908
|
const seen = visibleWidth(text);
|
|
5808
5909
|
if (seen < padTo) {
|
|
5809
|
-
parts.push(/* @__PURE__ */
|
|
5910
|
+
parts.push(/* @__PURE__ */ React3.createElement(Text3, { key: `pad${idx++}` }, " ".repeat(padTo - seen)));
|
|
5810
5911
|
}
|
|
5811
5912
|
}
|
|
5812
|
-
return /* @__PURE__ */
|
|
5913
|
+
return /* @__PURE__ */ React3.createElement(Text3, null, parts);
|
|
5813
5914
|
}
|
|
5814
5915
|
function stripInlineMarkup(s) {
|
|
5815
5916
|
return s.replace(/\[([^\]\n]+)\]\(([^)\n]+)\)/g, "$1").replace(/\*\*([^*\n]+?)\*\*/g, "$1").replace(/```([^\n]+?)```/g, (_m, c) => c.replace(/^(\w+)\s+/, "")).replace(/`([^`\n]+?)`/g, "$1").replace(/(?<![*\w])\*([^*\n]+?)\*(?!\w)/g, "$1");
|
|
@@ -6005,19 +6106,19 @@ function parseBlocks(raw) {
|
|
|
6005
6106
|
function BlockView({ block, citations }) {
|
|
6006
6107
|
switch (block.kind) {
|
|
6007
6108
|
case "heading":
|
|
6008
|
-
return /* @__PURE__ */
|
|
6109
|
+
return /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "cyan" }, /* @__PURE__ */ React3.createElement(InlineMd, { text: block.text, citations }));
|
|
6009
6110
|
case "paragraph":
|
|
6010
|
-
return /* @__PURE__ */
|
|
6111
|
+
return /* @__PURE__ */ React3.createElement(InlineMd, { text: block.text, citations });
|
|
6011
6112
|
case "bullet":
|
|
6012
|
-
return /* @__PURE__ */
|
|
6113
|
+
return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, block.items.map((item, i) => /* @__PURE__ */ React3.createElement(Box3, { key: `${i}-${item.slice(0, 24)}` }, /* @__PURE__ */ React3.createElement(Text3, { color: "cyan" }, block.ordered ? ` ${block.start + i}. ` : " \u2022 "), /* @__PURE__ */ React3.createElement(InlineMd, { text: item, citations }))));
|
|
6013
6114
|
case "code":
|
|
6014
|
-
return /* @__PURE__ */
|
|
6115
|
+
return /* @__PURE__ */ React3.createElement(Box3, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "yellow" }, block.text));
|
|
6015
6116
|
case "edit-block":
|
|
6016
|
-
return /* @__PURE__ */
|
|
6117
|
+
return /* @__PURE__ */ React3.createElement(EditBlockRow, { block });
|
|
6017
6118
|
case "table":
|
|
6018
|
-
return /* @__PURE__ */
|
|
6119
|
+
return /* @__PURE__ */ React3.createElement(TableBlockRow, { block, citations });
|
|
6019
6120
|
case "hr":
|
|
6020
|
-
return /* @__PURE__ */
|
|
6121
|
+
return /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
6021
6122
|
}
|
|
6022
6123
|
}
|
|
6023
6124
|
function splitTableRow(line) {
|
|
@@ -6035,14 +6136,14 @@ function TableBlockRow({ block, citations }) {
|
|
|
6035
6136
|
widths.push(Math.min(40, Math.max(3, ...cellLengths)));
|
|
6036
6137
|
}
|
|
6037
6138
|
const separator = widths.map((w) => "\u2500".repeat(w)).join("\u2500\u253C\u2500");
|
|
6038
|
-
return /* @__PURE__ */
|
|
6139
|
+
return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Box3, null, block.header.map((cell, ci) => (
|
|
6039
6140
|
// biome-ignore lint/suspicious/noArrayIndexKey: table columns never reorder — derived from a static header array
|
|
6040
|
-
/* @__PURE__ */
|
|
6041
|
-
))), /* @__PURE__ */
|
|
6141
|
+
/* @__PURE__ */ React3.createElement(Text3, { key: `h-${ci}`, bold: true, color: "cyan" }, /* @__PURE__ */ React3.createElement(InlineMd, { text: cell, padTo: widths[ci] ?? 3, citations }), ci < colCount - 1 ? " \u2502 " : "")
|
|
6142
|
+
))), /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, separator), block.rows.map((row2, ri) => (
|
|
6042
6143
|
// biome-ignore lint/suspicious/noArrayIndexKey: table rows render in source order and don't reorder
|
|
6043
|
-
/* @__PURE__ */
|
|
6144
|
+
/* @__PURE__ */ React3.createElement(Box3, { key: `r-${ri}` }, Array.from({ length: colCount }).map((_, ci) => (
|
|
6044
6145
|
// biome-ignore lint/suspicious/noArrayIndexKey: same — column axis is fixed by the table shape
|
|
6045
|
-
/* @__PURE__ */
|
|
6146
|
+
/* @__PURE__ */ React3.createElement(Text3, { key: `c-${ri}-${ci}` }, /* @__PURE__ */ React3.createElement(InlineMd, { text: row2[ci] ?? "", padTo: widths[ci] ?? 3, citations }), ci < colCount - 1 ? " \u2502 " : "")
|
|
6046
6147
|
)))
|
|
6047
6148
|
)));
|
|
6048
6149
|
}
|
|
@@ -6062,28 +6163,28 @@ function EditBlockRow({ block }) {
|
|
|
6062
6163
|
const isNewFile = block.search.length === 0;
|
|
6063
6164
|
const searchLines = block.search.split("\n");
|
|
6064
6165
|
const replaceLines = block.replace.split("\n");
|
|
6065
|
-
return /* @__PURE__ */
|
|
6166
|
+
return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "cyan" }, block.filename), isNewFile ? /* @__PURE__ */ React3.createElement(Text3, { color: "green", bold: true }, " (new file)") : null), isNewFile ? null : /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", marginTop: 1 }, searchLines.map((line, i) => /* @__PURE__ */ React3.createElement(Text3, { key: `s-${i}-${line.length}`, color: "red" }, `- ${line}`))), /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", marginTop: isNewFile ? 1 : 0 }, replaceLines.map((line, i) => /* @__PURE__ */ React3.createElement(Text3, { key: `r-${i}-${line.length}`, color: "green" }, `+ ${line}`))));
|
|
6066
6167
|
}
|
|
6067
6168
|
function Markdown({ text, projectRoot }) {
|
|
6068
6169
|
const cleaned = stripMath(text);
|
|
6069
6170
|
const root = projectRoot ?? process.cwd();
|
|
6070
|
-
const citations =
|
|
6071
|
-
const blocks =
|
|
6171
|
+
const citations = React3.useMemo(() => collectCitations(cleaned, root), [cleaned, root]);
|
|
6172
|
+
const blocks = React3.useMemo(() => parseBlocks(cleaned), [cleaned]);
|
|
6072
6173
|
const broken = [];
|
|
6073
6174
|
for (const [url, status] of citations) {
|
|
6074
6175
|
if (!status.ok) broken.push({ url, reason: status.reason });
|
|
6075
6176
|
}
|
|
6076
|
-
return /* @__PURE__ */
|
|
6177
|
+
return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", gap: 1 }, blocks.map((b, i) => /* @__PURE__ */ React3.createElement(BlockView, { key: `${i}-${b.kind}`, block: b, citations })), broken.length > 0 ? /* @__PURE__ */ React3.createElement(BrokenCitationsBlock, { items: broken }) : null);
|
|
6077
6178
|
}
|
|
6078
6179
|
function BrokenCitationsBlock({ items }) {
|
|
6079
|
-
return /* @__PURE__ */
|
|
6180
|
+
return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "red", bold: true }, `\u26A0 ${items.length} broken citation${items.length > 1 ? "s" : ""} \u2014 the model referenced paths or lines that don't exist`), items.map((b, i) => (
|
|
6080
6181
|
// biome-ignore lint/suspicious/noArrayIndexKey: list is derived from a Map iteration order, stable per render
|
|
6081
|
-
/* @__PURE__ */
|
|
6182
|
+
/* @__PURE__ */ React3.createElement(Text3, { key: `bc-${i}`, color: "red" }, ` \u2717 ${b.url} \u2192 ${b.reason}`)
|
|
6082
6183
|
)));
|
|
6083
6184
|
}
|
|
6084
6185
|
|
|
6085
6186
|
// src/cli/ui/ticker.tsx
|
|
6086
|
-
import
|
|
6187
|
+
import React4, { createContext, useContext, useEffect, useState } from "react";
|
|
6087
6188
|
var TICK_MS = 120;
|
|
6088
6189
|
var TickContext = createContext(0);
|
|
6089
6190
|
function TickerProvider({ children, disabled }) {
|
|
@@ -6093,7 +6194,7 @@ function TickerProvider({ children, disabled }) {
|
|
|
6093
6194
|
const id = setInterval(() => setTick((t) => t + 1), TICK_MS);
|
|
6094
6195
|
return () => clearInterval(id);
|
|
6095
6196
|
}, [disabled]);
|
|
6096
|
-
return /* @__PURE__ */
|
|
6197
|
+
return /* @__PURE__ */ React4.createElement(TickContext.Provider, { value: tick }, children);
|
|
6097
6198
|
}
|
|
6098
6199
|
function useTick() {
|
|
6099
6200
|
return useContext(TickContext);
|
|
@@ -6119,18 +6220,18 @@ function RoleGlyph({
|
|
|
6119
6220
|
glyph,
|
|
6120
6221
|
color
|
|
6121
6222
|
}) {
|
|
6122
|
-
return /* @__PURE__ */
|
|
6223
|
+
return /* @__PURE__ */ React5.createElement(Text4, { color, bold: true }, glyph);
|
|
6123
6224
|
}
|
|
6124
|
-
var EventRow =
|
|
6225
|
+
var EventRow = React5.memo(function EventRow2({
|
|
6125
6226
|
event,
|
|
6126
6227
|
projectRoot
|
|
6127
6228
|
}) {
|
|
6128
6229
|
if (event.role === "user") {
|
|
6129
|
-
return /* @__PURE__ */
|
|
6230
|
+
return /* @__PURE__ */ React5.createElement(Box4, { marginTop: event.leadSeparator ? 1 : 0 }, /* @__PURE__ */ React5.createElement(RoleGlyph, { glyph: ROLE_GLYPH.user, color: "cyan" }), /* @__PURE__ */ React5.createElement(Text4, null, " ", event.text));
|
|
6130
6231
|
}
|
|
6131
6232
|
if (event.role === "assistant") {
|
|
6132
|
-
if (event.streaming) return /* @__PURE__ */
|
|
6133
|
-
return /* @__PURE__ */
|
|
6233
|
+
if (event.streaming) return /* @__PURE__ */ React5.createElement(StreamingAssistant, { event });
|
|
6234
|
+
return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(RoleGlyph, { glyph: ROLE_GLYPH.assistant, color: "green" }), event.stats ? /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, ` ${event.stats.model}`) : null), /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column", paddingLeft: 2, marginTop: 1 }, event.branch ? /* @__PURE__ */ React5.createElement(BranchBlock, { branch: event.branch }) : null, event.reasoning ? /* @__PURE__ */ React5.createElement(ReasoningBlock, { reasoning: event.reasoning }) : null, !isPlanStateEmpty(event.planState) ? /* @__PURE__ */ React5.createElement(PlanStateBlock, { planState: event.planState }) : null, event.text ? /* @__PURE__ */ React5.createElement(Markdown, { text: event.text, projectRoot }) : /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, "(no content)"), event.stats ? /* @__PURE__ */ React5.createElement(StatsLine, { stats: event.stats }) : null, event.repair ? /* @__PURE__ */ React5.createElement(Text4, { color: "magenta" }, event.repair) : null));
|
|
6134
6235
|
}
|
|
6135
6236
|
if (event.role === "tool") {
|
|
6136
6237
|
const isError = event.text.startsWith("ERROR:");
|
|
@@ -6138,31 +6239,31 @@ var EventRow = React4.memo(function EventRow2({
|
|
|
6138
6239
|
const glyph = isError ? ROLE_GLYPH.toolErr : ROLE_GLYPH.toolOk;
|
|
6139
6240
|
const marker = isError ? "\u2717" : "\u2192";
|
|
6140
6241
|
const isEditFile = (event.toolName === "edit_file" || event.toolName?.endsWith("_edit_file")) && !isError;
|
|
6141
|
-
return /* @__PURE__ */
|
|
6242
|
+
return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(RoleGlyph, { glyph, color }), /* @__PURE__ */ React5.createElement(Text4, { color, bold: true }, ` ${event.toolName ?? "?"}`), /* @__PURE__ */ React5.createElement(Text4, { color, dimColor: true }, ` ${marker}`)), /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column", paddingLeft: 2, marginTop: 1 }, isEditFile ? /* @__PURE__ */ React5.createElement(EditFileDiff, { text: event.text }) : /* @__PURE__ */ React5.createElement(Text4, { color: isError ? "red" : void 0, dimColor: !isError }, truncate2(event.text, 400))));
|
|
6142
6243
|
}
|
|
6143
6244
|
if (event.role === "error") {
|
|
6144
|
-
return /* @__PURE__ */
|
|
6245
|
+
return /* @__PURE__ */ React5.createElement(Box4, { marginTop: 1 }, /* @__PURE__ */ React5.createElement(RoleGlyph, { glyph: ROLE_GLYPH.error, color: "red" }), /* @__PURE__ */ React5.createElement(Text4, { color: "red" }, " ", event.text));
|
|
6145
6246
|
}
|
|
6146
6247
|
if (event.role === "info") {
|
|
6147
|
-
return /* @__PURE__ */
|
|
6248
|
+
return /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, event.text));
|
|
6148
6249
|
}
|
|
6149
6250
|
if (event.role === "warning") {
|
|
6150
|
-
return /* @__PURE__ */
|
|
6251
|
+
return /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(RoleGlyph, { glyph: ROLE_GLYPH.warning, color: "yellow" }), /* @__PURE__ */ React5.createElement(Text4, { color: "yellow" }, " ", event.text));
|
|
6151
6252
|
}
|
|
6152
|
-
return /* @__PURE__ */
|
|
6253
|
+
return /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text4, null, event.text));
|
|
6153
6254
|
});
|
|
6154
6255
|
function EditFileDiff({ text }) {
|
|
6155
6256
|
const lines = text.split(/\r?\n/);
|
|
6156
6257
|
const [statusHeader, hunkHeader, ...body] = lines;
|
|
6157
|
-
return /* @__PURE__ */
|
|
6258
|
+
return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, ` ${statusHeader ?? ""}`), hunkHeader !== void 0 ? /* @__PURE__ */ React5.createElement(Text4, { color: "cyan", bold: true }, hunkHeader) : null, body.map((line, i) => {
|
|
6158
6259
|
const key = `${i}-${line.slice(0, 32)}`;
|
|
6159
6260
|
if (line.startsWith("- ")) {
|
|
6160
|
-
return /* @__PURE__ */
|
|
6261
|
+
return /* @__PURE__ */ React5.createElement(Text4, { key, color: "red" }, line);
|
|
6161
6262
|
}
|
|
6162
6263
|
if (line.startsWith("+ ")) {
|
|
6163
|
-
return /* @__PURE__ */
|
|
6264
|
+
return /* @__PURE__ */ React5.createElement(Text4, { key, color: "green" }, line);
|
|
6164
6265
|
}
|
|
6165
|
-
return /* @__PURE__ */
|
|
6266
|
+
return /* @__PURE__ */ React5.createElement(Text4, { key, dimColor: true }, line);
|
|
6166
6267
|
}));
|
|
6167
6268
|
}
|
|
6168
6269
|
function BranchBlock({ branch }) {
|
|
@@ -6171,33 +6272,33 @@ function BranchBlock({ branch }) {
|
|
|
6171
6272
|
const t = (branch.temperatures[i] ?? 0).toFixed(1);
|
|
6172
6273
|
return `${marker} #${i} T=${t} u=${u}`;
|
|
6173
6274
|
}).join(" ");
|
|
6174
|
-
return /* @__PURE__ */
|
|
6275
|
+
return /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text4, { color: "blue" }, "\u2387 branched ", /* @__PURE__ */ React5.createElement(Text4, { bold: true }, branch.budget), ` samples \u2192 picked #${branch.chosenIndex} `, /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, per)));
|
|
6175
6276
|
}
|
|
6176
6277
|
function ReasoningBlock({ reasoning }) {
|
|
6177
6278
|
const max = 260;
|
|
6178
6279
|
const flat = reasoning.replace(/\s+/g, " ").trim();
|
|
6179
6280
|
const preview = flat.length <= max ? flat : `\u2026 (+${flat.length - max} earlier chars) ${flat.slice(-max)}`;
|
|
6180
|
-
return /* @__PURE__ */
|
|
6281
|
+
return /* @__PURE__ */ React5.createElement(Box4, { marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, "\u258F "), /* @__PURE__ */ React5.createElement(Text4, { dimColor: true, italic: true }, "thinking ", preview));
|
|
6181
6282
|
}
|
|
6182
6283
|
function Elapsed() {
|
|
6183
6284
|
const s = useElapsedSeconds();
|
|
6184
6285
|
const mm = String(Math.floor(s / 60)).padStart(2, "0");
|
|
6185
6286
|
const ss = String(s % 60).padStart(2, "0");
|
|
6186
|
-
return /* @__PURE__ */
|
|
6287
|
+
return /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, `${mm}:${ss}`);
|
|
6187
6288
|
}
|
|
6188
6289
|
function PulsingAssistantGlyph() {
|
|
6189
6290
|
const tick = useTick();
|
|
6190
6291
|
const on = Math.floor(tick / 4) % 2 === 0;
|
|
6191
|
-
return /* @__PURE__ */
|
|
6292
|
+
return /* @__PURE__ */ React5.createElement(Text4, { color: "green", bold: true }, on ? ROLE_GLYPH.assistant : ROLE_GLYPH.assistantPulse);
|
|
6192
6293
|
}
|
|
6193
6294
|
function StreamingAssistant({ event }) {
|
|
6194
6295
|
if (event.branchProgress) {
|
|
6195
6296
|
const p = event.branchProgress;
|
|
6196
6297
|
if (p.completed === 0) {
|
|
6197
|
-
return /* @__PURE__ */
|
|
6298
|
+
return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React5.createElement(Text4, { color: "blue" }, " \u2387 launching ", p.total, " parallel samples (R1 thinking in parallel)\u2026 "), /* @__PURE__ */ React5.createElement(Elapsed, null)), /* @__PURE__ */ React5.createElement(Text4, { color: "yellow" }, " ", "spread across T=0.0/0.5/1.0 \xB7 reasoner typically takes 30-90s \u2014 this is normal"));
|
|
6198
6299
|
}
|
|
6199
6300
|
const pct2 = Math.round(p.completed / p.total * 100);
|
|
6200
|
-
return /* @__PURE__ */
|
|
6301
|
+
return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React5.createElement(Text4, { color: "blue" }, " \u2387 branching ", p.completed, "/", p.total, " (", pct2, "%) "), /* @__PURE__ */ React5.createElement(Elapsed, null)), /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, " latest #", p.latestIndex, " T=", p.latestTemperature.toFixed(1), " u=", p.latestUncertainties, p.completed < p.total ? " \xB7 waiting for other samples\u2026" : " \xB7 selecting winner\u2026"));
|
|
6201
6302
|
}
|
|
6202
6303
|
const tail = lastLine(event.text, 140);
|
|
6203
6304
|
const reasoningTail = event.reasoning ? lastLine(event.reasoning, 120) : "";
|
|
@@ -6225,16 +6326,16 @@ function StreamingAssistant({ event }) {
|
|
|
6225
6326
|
label = parts.join(" \xB7 ");
|
|
6226
6327
|
labelColor = "green";
|
|
6227
6328
|
}
|
|
6228
|
-
return /* @__PURE__ */
|
|
6329
|
+
return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React5.createElement(Text4, null, " "), /* @__PURE__ */ React5.createElement(Pulse, null), /* @__PURE__ */ React5.createElement(Text4, { color: labelColor }, ` ${label} `), /* @__PURE__ */ React5.createElement(Elapsed, null)), reasoningTail ? /* @__PURE__ */ React5.createElement(Text4, { dimColor: true, italic: true }, "\u21B3 thinking: ", reasoningTail) : null, tail ? /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, "\u25B8 ", tail) : preFirstByte ? (
|
|
6229
6330
|
// Non-dim yellow: first-time users misread the dim version as
|
|
6230
6331
|
// "app frozen". The reassurance has to be VISIBLE to do its job.
|
|
6231
|
-
/* @__PURE__ */
|
|
6232
|
-
) : reasoningOnly ? /* @__PURE__ */
|
|
6332
|
+
/* @__PURE__ */ React5.createElement(Text4, { color: "yellow", italic: true }, " waiting for first byte \u2014 this is normal, typically 5-60s depending on model + load")
|
|
6333
|
+
) : reasoningOnly ? /* @__PURE__ */ React5.createElement(Text4, { color: "yellow", italic: true }, " R1 is thinking before it speaks \u2014 body text arrives when reasoning finishes (typically 20-90s, this is normal)") : toolCallOnly ? /* @__PURE__ */ React5.createElement(Text4, { color: "magenta", italic: true }, " tool-call arguments streaming \u2014 the model is about to dispatch a tool") : event.reasoning ? /* @__PURE__ */ React5.createElement(Text4, { color: "yellow", italic: true }, " R1 still reasoning \u2014 body text or tool call arrives when thinking finishes") : null);
|
|
6233
6334
|
}
|
|
6234
6335
|
function Pulse() {
|
|
6235
6336
|
const tick = useTick();
|
|
6236
6337
|
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
6237
|
-
return /* @__PURE__ */
|
|
6338
|
+
return /* @__PURE__ */ React5.createElement(Text4, { color: "cyan" }, frames[Math.floor(tick / 4) % frames.length]);
|
|
6238
6339
|
}
|
|
6239
6340
|
function lastLine(s, maxChars) {
|
|
6240
6341
|
const flat = s.replace(/\s+/g, " ").trim();
|
|
@@ -6243,7 +6344,7 @@ function lastLine(s, maxChars) {
|
|
|
6243
6344
|
}
|
|
6244
6345
|
function StatsLine({ stats }) {
|
|
6245
6346
|
const hit = (stats.cacheHitRatio * 100).toFixed(1);
|
|
6246
|
-
return /* @__PURE__ */
|
|
6347
|
+
return /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, "\u258F "), /* @__PURE__ */ React5.createElement(Text4, { dimColor: true }, "cache ", hit, "% \xB7 tokens ", stats.usage.promptTokens, " \u2192 ", stats.usage.completionTokens, " \xB7 $", stats.cost.toFixed(6)));
|
|
6247
6348
|
}
|
|
6248
6349
|
function truncate2(s, max) {
|
|
6249
6350
|
if (s.length <= max) return s;
|
|
@@ -6266,12 +6367,12 @@ ${s.slice(-max)}`;
|
|
|
6266
6367
|
}
|
|
6267
6368
|
|
|
6268
6369
|
// src/cli/ui/PlanConfirm.tsx
|
|
6269
|
-
import { Box as
|
|
6270
|
-
import
|
|
6370
|
+
import { Box as Box6, Text as Text6 } from "ink";
|
|
6371
|
+
import React7 from "react";
|
|
6271
6372
|
|
|
6272
6373
|
// src/cli/ui/Select.tsx
|
|
6273
|
-
import { Box as
|
|
6274
|
-
import
|
|
6374
|
+
import { Box as Box5, Text as Text5, useInput } from "ink";
|
|
6375
|
+
import React6, { useState as useState2 } from "react";
|
|
6275
6376
|
function SingleSelect({
|
|
6276
6377
|
items,
|
|
6277
6378
|
initialValue,
|
|
@@ -6296,7 +6397,7 @@ function SingleSelect({
|
|
|
6296
6397
|
onCancel();
|
|
6297
6398
|
}
|
|
6298
6399
|
});
|
|
6299
|
-
return /* @__PURE__ */
|
|
6400
|
+
return /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "column" }, items.map((item, i) => /* @__PURE__ */ React6.createElement(
|
|
6300
6401
|
SelectRow,
|
|
6301
6402
|
{
|
|
6302
6403
|
key: item.value,
|
|
@@ -6304,7 +6405,7 @@ function SingleSelect({
|
|
|
6304
6405
|
active: i === index,
|
|
6305
6406
|
marker: i === index ? "\u25B8" : " "
|
|
6306
6407
|
}
|
|
6307
|
-
)), footer ? /* @__PURE__ */
|
|
6408
|
+
)), footer ? /* @__PURE__ */ React6.createElement(Box5, { marginTop: 1 }, /* @__PURE__ */ React6.createElement(Text5, { dimColor: true }, footer)) : null);
|
|
6308
6409
|
}
|
|
6309
6410
|
function MultiSelect({
|
|
6310
6411
|
items,
|
|
@@ -6339,10 +6440,10 @@ function MultiSelect({
|
|
|
6339
6440
|
onCancel();
|
|
6340
6441
|
}
|
|
6341
6442
|
});
|
|
6342
|
-
return /* @__PURE__ */
|
|
6443
|
+
return /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "column" }, items.map((item, i) => {
|
|
6343
6444
|
const checked = selected.has(item.value);
|
|
6344
6445
|
const marker = checked ? "[x]" : "[ ]";
|
|
6345
|
-
return /* @__PURE__ */
|
|
6446
|
+
return /* @__PURE__ */ React6.createElement(
|
|
6346
6447
|
SelectRow,
|
|
6347
6448
|
{
|
|
6348
6449
|
key: item.value,
|
|
@@ -6351,7 +6452,7 @@ function MultiSelect({
|
|
|
6351
6452
|
marker: `${i === index ? "\u25B8" : " "} ${marker}`
|
|
6352
6453
|
}
|
|
6353
6454
|
);
|
|
6354
|
-
}), footer ? /* @__PURE__ */
|
|
6455
|
+
}), footer ? /* @__PURE__ */ React6.createElement(Box5, { marginTop: 1 }, /* @__PURE__ */ React6.createElement(Text5, { dimColor: true }, footer)) : null);
|
|
6355
6456
|
}
|
|
6356
6457
|
function SelectRow({
|
|
6357
6458
|
item,
|
|
@@ -6359,7 +6460,7 @@ function SelectRow({
|
|
|
6359
6460
|
marker
|
|
6360
6461
|
}) {
|
|
6361
6462
|
const color = item.disabled ? "gray" : active ? "cyan" : void 0;
|
|
6362
|
-
return /* @__PURE__ */
|
|
6463
|
+
return /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Box5, null, /* @__PURE__ */ React6.createElement(Text5, { color }, marker, " ", item.label)), item.hint ? /* @__PURE__ */ React6.createElement(Box5, { paddingLeft: marker.length + 1 }, /* @__PURE__ */ React6.createElement(Text5, { dimColor: true }, item.hint)) : null);
|
|
6363
6464
|
}
|
|
6364
6465
|
function findNextEnabled(items, from, step) {
|
|
6365
6466
|
if (items.length === 0) return 0;
|
|
@@ -6380,7 +6481,7 @@ function PlanConfirm({ plan, onChoose, maxRenderedChars, projectRoot }) {
|
|
|
6380
6481
|
|
|
6381
6482
|
\u2026 (${plan.length - cap} chars truncated \u2014 use /tool to view the full proposal)` : plan;
|
|
6382
6483
|
const hasOpenQuestions = /^#{1,6}\s*(open[-\s]?questions?|risks?|unknowns?|assumptions?|unclear)/im.test(plan) || /^#{1,6}\s*(待确认|开放问题|风险|未知|假设|不确定)/im.test(plan);
|
|
6383
|
-
return /* @__PURE__ */
|
|
6484
|
+
return /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React7.createElement(Box6, null, /* @__PURE__ */ React7.createElement(Text6, { bold: true, color: "cyan" }, "\u25B8 plan submitted \u2014 awaiting your review")), /* @__PURE__ */ React7.createElement(Box6, null, /* @__PURE__ */ React7.createElement(Text6, { color: "cyan", dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")), /* @__PURE__ */ React7.createElement(Box6, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Markdown, { text: visible, projectRoot })), hasOpenQuestions ? /* @__PURE__ */ React7.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React7.createElement(Text6, { color: "yellow" }, "\u25B2 the plan has open questions or flagged risks \u2014 pick", " ", /* @__PURE__ */ React7.createElement(Text6, { bold: true }, "Refine / answer questions"), " to write concrete answers before the model moves on.")) : null, /* @__PURE__ */ React7.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React7.createElement(
|
|
6384
6485
|
SingleSelect,
|
|
6385
6486
|
{
|
|
6386
6487
|
initialValue: hasOpenQuestions ? "refine" : "approve",
|
|
@@ -6409,8 +6510,8 @@ function PlanConfirm({ plan, onChoose, maxRenderedChars, projectRoot }) {
|
|
|
6409
6510
|
}
|
|
6410
6511
|
|
|
6411
6512
|
// src/cli/ui/PlanRefineInput.tsx
|
|
6412
|
-
import { Box as
|
|
6413
|
-
import
|
|
6513
|
+
import { Box as Box7, Text as Text7, useInput as useInput2 } from "ink";
|
|
6514
|
+
import React8, { useState as useState3 } from "react";
|
|
6414
6515
|
function PlanRefineInput({ mode, onSubmit, onCancel }) {
|
|
6415
6516
|
const [value, setValue] = useState3("");
|
|
6416
6517
|
useInput2((input, key) => {
|
|
@@ -6433,12 +6534,12 @@ function PlanRefineInput({ mode, onSubmit, onCancel }) {
|
|
|
6433
6534
|
const title = mode === "approve" ? "\u25B8 approving \u2014 any last instructions or answers to open questions?" : "\u25B8 refining \u2014 what should the model change?";
|
|
6434
6535
|
const hint = mode === "approve" ? "Answer questions the plan raised, add constraints, or just press Enter to approve as-is." : "Describe what's wrong or missing, or answer questions the plan raised.";
|
|
6435
6536
|
const blankHint = mode === "approve" ? " (Enter with blank = approve without extra instructions.)" : " (Enter with blank = ask the model to list concrete questions.)";
|
|
6436
|
-
return /* @__PURE__ */
|
|
6537
|
+
return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React8.createElement(Box7, null, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "yellow" }, title)), /* @__PURE__ */ React8.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, hint, " Enter to send \xB7 Esc to return to the picker.", value === "" ? blankHint : "")), /* @__PURE__ */ React8.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "\u203A "), /* @__PURE__ */ React8.createElement(Text7, null, value || " "), /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "\u258D"))));
|
|
6437
6538
|
}
|
|
6438
6539
|
|
|
6439
6540
|
// src/cli/ui/PromptInput.tsx
|
|
6440
|
-
import { Box as
|
|
6441
|
-
import
|
|
6541
|
+
import { Box as Box8, Text as Text8, useInput as useInput3 } from "ink";
|
|
6542
|
+
import React9, { useRef, useState as useState4 } from "react";
|
|
6442
6543
|
|
|
6443
6544
|
// src/cli/ui/multiline-keys.ts
|
|
6444
6545
|
var BACKSLASH_SUFFIX = /\\$/;
|
|
@@ -6598,13 +6699,13 @@ function PromptInput({
|
|
|
6598
6699
|
const lines = value.length > 0 ? value.split("\n") : [""];
|
|
6599
6700
|
const borderColor = disabled ? "gray" : "cyan";
|
|
6600
6701
|
const { line: cursorLine, col: cursorCol } = lineAndColumn(value, cursor);
|
|
6601
|
-
return /* @__PURE__ */
|
|
6702
|
+
return /* @__PURE__ */ React9.createElement(Box8, { borderStyle: "round", borderColor, paddingX: 1, flexDirection: "column" }, lines.map((line, i) => {
|
|
6602
6703
|
const isFirst = i === 0;
|
|
6603
6704
|
const showPlaceholder = isFirst && value.length === 0;
|
|
6604
6705
|
const isCursorLine = i === cursorLine;
|
|
6605
6706
|
return (
|
|
6606
6707
|
// biome-ignore lint/suspicious/noArrayIndexKey: stable by construction — lines are derived from `value.split("\n")` and never reordered
|
|
6607
|
-
/* @__PURE__ */
|
|
6708
|
+
/* @__PURE__ */ React9.createElement(Box8, { key: i }, isFirst ? /* @__PURE__ */ React9.createElement(Text8, { bold: true, color: borderColor }, "you \u203A", " ") : /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, " "), showPlaceholder ? /* @__PURE__ */ React9.createElement(React9.Fragment, null, isCursorLine && !disabled ? /* @__PURE__ */ React9.createElement(Text8, { color: borderColor }, showCursor ? "\u258C" : " ") : null, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, effectivePlaceholder)) : isCursorLine && !disabled ? /* @__PURE__ */ React9.createElement(
|
|
6608
6709
|
LineWithCursor,
|
|
6609
6710
|
{
|
|
6610
6711
|
line,
|
|
@@ -6612,7 +6713,7 @@ function PromptInput({
|
|
|
6612
6713
|
showCursor,
|
|
6613
6714
|
borderColor
|
|
6614
6715
|
}
|
|
6615
|
-
) : /* @__PURE__ */
|
|
6716
|
+
) : /* @__PURE__ */ React9.createElement(Text8, null, line))
|
|
6616
6717
|
);
|
|
6617
6718
|
}));
|
|
6618
6719
|
}
|
|
@@ -6626,16 +6727,16 @@ function LineWithCursor({
|
|
|
6626
6727
|
const atCursor = line.slice(col, col + 1);
|
|
6627
6728
|
const after = line.slice(col + 1);
|
|
6628
6729
|
if (atCursor.length === 0) {
|
|
6629
|
-
return /* @__PURE__ */
|
|
6730
|
+
return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(Text8, null, before), /* @__PURE__ */ React9.createElement(Text8, { color: borderColor }, showCursor ? "\u258C" : " "));
|
|
6630
6731
|
}
|
|
6631
|
-
return /* @__PURE__ */
|
|
6732
|
+
return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(Text8, null, before), /* @__PURE__ */ React9.createElement(Text8, { inverse: showCursor }, atCursor), /* @__PURE__ */ React9.createElement(Text8, null, after));
|
|
6632
6733
|
}
|
|
6633
6734
|
|
|
6634
6735
|
// src/cli/ui/ShellConfirm.tsx
|
|
6635
|
-
import { Box as
|
|
6636
|
-
import
|
|
6736
|
+
import { Box as Box9, Text as Text9 } from "ink";
|
|
6737
|
+
import React10 from "react";
|
|
6637
6738
|
function ShellConfirm({ command, allowPrefix, onChoose }) {
|
|
6638
|
-
return /* @__PURE__ */
|
|
6739
|
+
return /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: "yellow" }, "\u25B8 model wants to run a shell command")), /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text9, { color: "yellow", dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text9, null, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "$ "), /* @__PURE__ */ React10.createElement(Text9, { color: "cyan" }, command))), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(
|
|
6639
6740
|
SingleSelect,
|
|
6640
6741
|
{
|
|
6641
6742
|
initialValue: "run_once",
|
|
@@ -6692,15 +6793,15 @@ function derivePrefix(command) {
|
|
|
6692
6793
|
}
|
|
6693
6794
|
|
|
6694
6795
|
// src/cli/ui/SlashSuggestions.tsx
|
|
6695
|
-
import { Box as
|
|
6696
|
-
import
|
|
6796
|
+
import { Box as Box10, Text as Text10 } from "ink";
|
|
6797
|
+
import React11 from "react";
|
|
6697
6798
|
function SlashSuggestions({
|
|
6698
6799
|
matches,
|
|
6699
6800
|
selectedIndex
|
|
6700
6801
|
}) {
|
|
6701
6802
|
if (matches === null) return null;
|
|
6702
6803
|
if (matches.length === 0) {
|
|
6703
|
-
return /* @__PURE__ */
|
|
6804
|
+
return /* @__PURE__ */ React11.createElement(Box10, { paddingX: 1 }, /* @__PURE__ */ React11.createElement(Text10, { color: "yellow" }, "no slash command matches that prefix"), /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, " \u2014 Backspace to edit, or /help for the full list"));
|
|
6704
6805
|
}
|
|
6705
6806
|
const MAX = 8;
|
|
6706
6807
|
const total = matches.length;
|
|
@@ -6708,21 +6809,21 @@ function SlashSuggestions({
|
|
|
6708
6809
|
const shown = matches.slice(windowStart, windowStart + MAX);
|
|
6709
6810
|
const hiddenAbove = windowStart;
|
|
6710
6811
|
const hiddenBelow = total - windowStart - shown.length;
|
|
6711
|
-
return /* @__PURE__ */
|
|
6812
|
+
return /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column", paddingX: 1 }, hiddenAbove > 0 ? /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, " \u2191 ", hiddenAbove, " more above") : null, shown.map((spec, i) => /* @__PURE__ */ React11.createElement(SuggestionRow, { key: spec.cmd, spec, isSelected: windowStart + i === selectedIndex })), hiddenBelow > 0 ? /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, " \u2193 ", hiddenBelow, " more below") : null, /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, " [\u2191\u2193] navigate \xB7 [Tab]/[Enter] pick"));
|
|
6712
6813
|
}
|
|
6713
6814
|
function SuggestionRow({ spec, isSelected }) {
|
|
6714
6815
|
const marker = isSelected ? "\u25B8" : " ";
|
|
6715
6816
|
const name = `/${spec.cmd}`;
|
|
6716
6817
|
const argsSuffix = spec.argsHint ? ` ${spec.argsHint}` : "";
|
|
6717
6818
|
if (isSelected) {
|
|
6718
|
-
return /* @__PURE__ */
|
|
6819
|
+
return /* @__PURE__ */ React11.createElement(Box10, null, /* @__PURE__ */ React11.createElement(Text10, { bold: true, color: "cyan" }, marker, " ", name.padEnd(12), argsSuffix.padEnd(16)), /* @__PURE__ */ React11.createElement(Text10, { color: "cyan" }, " ", spec.summary));
|
|
6719
6820
|
}
|
|
6720
|
-
return /* @__PURE__ */
|
|
6821
|
+
return /* @__PURE__ */ React11.createElement(Box10, null, /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, marker, " ", name.padEnd(12), argsSuffix.padEnd(16), " ", spec.summary));
|
|
6721
6822
|
}
|
|
6722
6823
|
|
|
6723
6824
|
// src/cli/ui/StatsPanel.tsx
|
|
6724
|
-
import { Box as
|
|
6725
|
-
import
|
|
6825
|
+
import { Box as Box11, Text as Text11, useStdout as useStdout2 } from "ink";
|
|
6826
|
+
import React12 from "react";
|
|
6726
6827
|
var WORDMARK_STYLES = [
|
|
6727
6828
|
{ ch: "\u25C8", color: "#5eead4", isLogo: true },
|
|
6728
6829
|
// teal — brand mark
|
|
@@ -6748,7 +6849,7 @@ function Wordmark({ busy }) {
|
|
|
6748
6849
|
const tick = useTick();
|
|
6749
6850
|
const period = busy ? 5 : 12;
|
|
6750
6851
|
const bright = Math.floor(tick / period) % 2 === 0;
|
|
6751
|
-
return /* @__PURE__ */
|
|
6852
|
+
return /* @__PURE__ */ React12.createElement(Text11, null, WORDMARK_STYLES.map((c) => /* @__PURE__ */ React12.createElement(Text11, { key: `${c.ch}-${c.color}`, color: c.color, bold: c.isLogo ? bright : true }, c.ch)));
|
|
6752
6853
|
}
|
|
6753
6854
|
var NARROW_BREAKPOINT = 120;
|
|
6754
6855
|
var COLD_START_TURNS = 3;
|
|
@@ -6770,7 +6871,7 @@ function StatsPanel({
|
|
|
6770
6871
|
const columns = stdout2?.columns ?? 80;
|
|
6771
6872
|
const narrow = columns < NARROW_BREAKPOINT;
|
|
6772
6873
|
const coldStart = summary.turns <= COLD_START_TURNS;
|
|
6773
|
-
return /* @__PURE__ */
|
|
6874
|
+
return /* @__PURE__ */ React12.createElement(Box11, { borderStyle: "round", borderColor: "cyan", flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React12.createElement(
|
|
6774
6875
|
Header,
|
|
6775
6876
|
{
|
|
6776
6877
|
model,
|
|
@@ -6784,7 +6885,7 @@ function StatsPanel({
|
|
|
6784
6885
|
narrow,
|
|
6785
6886
|
busy: busy ?? false
|
|
6786
6887
|
}
|
|
6787
|
-
), narrow ? /* @__PURE__ */
|
|
6888
|
+
), narrow ? /* @__PURE__ */ React12.createElement(
|
|
6788
6889
|
StackedMetrics,
|
|
6789
6890
|
{
|
|
6790
6891
|
summary,
|
|
@@ -6793,7 +6894,7 @@ function StatsPanel({
|
|
|
6793
6894
|
balance,
|
|
6794
6895
|
coldStart
|
|
6795
6896
|
}
|
|
6796
|
-
) : /* @__PURE__ */
|
|
6897
|
+
) : /* @__PURE__ */ React12.createElement(
|
|
6797
6898
|
InlineMetrics,
|
|
6798
6899
|
{
|
|
6799
6900
|
summary,
|
|
@@ -6816,7 +6917,7 @@ function Header({
|
|
|
6816
6917
|
narrow,
|
|
6817
6918
|
busy
|
|
6818
6919
|
}) {
|
|
6819
|
-
return /* @__PURE__ */
|
|
6920
|
+
return /* @__PURE__ */ React12.createElement(Box11, { justifyContent: "space-between" }, /* @__PURE__ */ React12.createElement(Box11, null, /* @__PURE__ */ React12.createElement(Wordmark, { busy }), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, ` v${VERSION}`), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React12.createElement(Text11, { color: "yellow" }, model), narrow ? null : /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, prefixHash)), harvestOn ? /* @__PURE__ */ React12.createElement(Text11, { color: "magenta" }, " \xB7 harvest") : null, branchOn ? /* @__PURE__ */ React12.createElement(Text11, { color: "blue" }, " \xB7 branch", branchBudget) : null, planMode ? /* @__PURE__ */ React12.createElement(Text11, { color: "red", bold: true }, " \xB7 PLAN") : null), /* @__PURE__ */ React12.createElement(Text11, null, updateAvailable ? /* @__PURE__ */ React12.createElement(Text11, { color: "yellow", bold: true }, `update: ${updateAvailable} \xB7 `) : null, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, narrow ? `turn ${turns}` : `turn ${turns} \xB7 /help`)));
|
|
6820
6921
|
}
|
|
6821
6922
|
function InlineMetrics({
|
|
6822
6923
|
summary,
|
|
@@ -6825,7 +6926,7 @@ function InlineMetrics({
|
|
|
6825
6926
|
balance,
|
|
6826
6927
|
coldStart
|
|
6827
6928
|
}) {
|
|
6828
|
-
return /* @__PURE__ */
|
|
6929
|
+
return /* @__PURE__ */ React12.createElement(Box11, { marginTop: 1, gap: 3 }, /* @__PURE__ */ React12.createElement(ContextCell, { ratio: ctxRatio, promptTokens: summary.lastPromptTokens, ctxMax }), /* @__PURE__ */ React12.createElement(CacheCell, { hitRatio: summary.cacheHitRatio, coldStart, turns: summary.turns }), /* @__PURE__ */ React12.createElement(CostCell, { summary, coldStart }), balance ? /* @__PURE__ */ React12.createElement(BalanceCell, { balance }) : null);
|
|
6829
6930
|
}
|
|
6830
6931
|
function StackedMetrics({
|
|
6831
6932
|
summary,
|
|
@@ -6834,7 +6935,7 @@ function StackedMetrics({
|
|
|
6834
6935
|
balance,
|
|
6835
6936
|
coldStart
|
|
6836
6937
|
}) {
|
|
6837
|
-
return /* @__PURE__ */
|
|
6938
|
+
return /* @__PURE__ */ React12.createElement(Box11, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React12.createElement(
|
|
6838
6939
|
ContextCell,
|
|
6839
6940
|
{
|
|
6840
6941
|
ratio: ctxRatio,
|
|
@@ -6842,7 +6943,7 @@ function StackedMetrics({
|
|
|
6842
6943
|
ctxMax,
|
|
6843
6944
|
showBar: true
|
|
6844
6945
|
}
|
|
6845
|
-
), balance ? /* @__PURE__ */
|
|
6946
|
+
), balance ? /* @__PURE__ */ React12.createElement(BalanceCell, { balance }) : null, /* @__PURE__ */ React12.createElement(CacheCell, { hitRatio: summary.cacheHitRatio, coldStart, turns: summary.turns }), /* @__PURE__ */ React12.createElement(CostCell, { summary, coldStart }));
|
|
6846
6947
|
}
|
|
6847
6948
|
function ContextCell({
|
|
6848
6949
|
ratio,
|
|
@@ -6851,11 +6952,11 @@ function ContextCell({
|
|
|
6851
6952
|
showBar
|
|
6852
6953
|
}) {
|
|
6853
6954
|
if (promptTokens === 0) {
|
|
6854
|
-
return /* @__PURE__ */
|
|
6955
|
+
return /* @__PURE__ */ React12.createElement(Text11, null, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "ctx "), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "\u2014 (no turns yet)"));
|
|
6855
6956
|
}
|
|
6856
6957
|
const color = ratio >= 0.8 ? "red" : ratio >= 0.6 ? "yellow" : "green";
|
|
6857
6958
|
const pct2 = Math.round(ratio * 100);
|
|
6858
|
-
return /* @__PURE__ */
|
|
6959
|
+
return /* @__PURE__ */ React12.createElement(Text11, null, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "ctx "), showBar ? /* @__PURE__ */ React12.createElement(Bar, { ratio, color }) : null, showBar ? /* @__PURE__ */ React12.createElement(Text11, null, " ") : null, /* @__PURE__ */ React12.createElement(Text11, { color, bold: true }, formatTokens(promptTokens), "/", formatTokens(ctxMax)), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, " (", pct2, "%)"), ratio >= 0.8 ? /* @__PURE__ */ React12.createElement(Text11, { color: "red", bold: true }, " \xB7 /compact") : null);
|
|
6859
6960
|
}
|
|
6860
6961
|
function CacheCell({
|
|
6861
6962
|
hitRatio,
|
|
@@ -6864,33 +6965,33 @@ function CacheCell({
|
|
|
6864
6965
|
}) {
|
|
6865
6966
|
const pct2 = (hitRatio * 100).toFixed(1);
|
|
6866
6967
|
if (turns === 0) {
|
|
6867
|
-
return /* @__PURE__ */
|
|
6968
|
+
return /* @__PURE__ */ React12.createElement(Text11, null, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "cache "), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "\u2014"));
|
|
6868
6969
|
}
|
|
6869
6970
|
if (coldStart) {
|
|
6870
|
-
return /* @__PURE__ */
|
|
6971
|
+
return /* @__PURE__ */ React12.createElement(Text11, null, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "cache "), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, pct2, "% "), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true, italic: true }, "(cold start)"));
|
|
6871
6972
|
}
|
|
6872
6973
|
const color = hitRatio >= 0.7 ? "green" : hitRatio >= 0.4 ? "yellow" : "red";
|
|
6873
|
-
return /* @__PURE__ */
|
|
6974
|
+
return /* @__PURE__ */ React12.createElement(Text11, null, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "cache "), /* @__PURE__ */ React12.createElement(Text11, { color, bold: true }, pct2, "%"));
|
|
6874
6975
|
}
|
|
6875
6976
|
function CostCell({
|
|
6876
6977
|
summary,
|
|
6877
6978
|
coldStart
|
|
6878
6979
|
}) {
|
|
6879
6980
|
if (summary.turns === 0) {
|
|
6880
|
-
return /* @__PURE__ */
|
|
6981
|
+
return /* @__PURE__ */ React12.createElement(Text11, null, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "cost "), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "\u2014"));
|
|
6881
6982
|
}
|
|
6882
6983
|
const primaryColor = coldStart ? void 0 : "green";
|
|
6883
|
-
return /* @__PURE__ */
|
|
6984
|
+
return /* @__PURE__ */ React12.createElement(Text11, null, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "cost "), /* @__PURE__ */ React12.createElement(Text11, { color: primaryColor, bold: !coldStart, dimColor: coldStart }, "$", summary.totalCostUsd.toFixed(6)), /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, " (in ", "$", summary.totalInputCostUsd.toFixed(6), " \xB7 out ", "$", summary.totalOutputCostUsd.toFixed(6), ")"));
|
|
6884
6985
|
}
|
|
6885
6986
|
function BalanceCell({ balance }) {
|
|
6886
6987
|
const color = balance.total < 1 ? "red" : balance.total < 5 ? "yellow" : "green";
|
|
6887
|
-
return /* @__PURE__ */
|
|
6988
|
+
return /* @__PURE__ */ React12.createElement(Text11, null, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "balance "), /* @__PURE__ */ React12.createElement(Text11, { color, bold: true }, balance.currency === "USD" ? "$" : "", balance.total.toFixed(2), balance.currency !== "USD" ? ` ${balance.currency}` : ""));
|
|
6888
6989
|
}
|
|
6889
6990
|
function Bar({ ratio, color }) {
|
|
6890
6991
|
const cells = 10;
|
|
6891
6992
|
const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));
|
|
6892
6993
|
const bar = "\u2588".repeat(filled) + "\u2591".repeat(cells - filled);
|
|
6893
|
-
return /* @__PURE__ */
|
|
6994
|
+
return /* @__PURE__ */ React12.createElement(Text11, { color }, bar);
|
|
6894
6995
|
}
|
|
6895
6996
|
function formatTokens(n) {
|
|
6896
6997
|
if (n < 1024) return String(n);
|
|
@@ -8051,6 +8152,39 @@ function App({
|
|
|
8051
8152
|
return prev;
|
|
8052
8153
|
});
|
|
8053
8154
|
}, [slashMatches]);
|
|
8155
|
+
const [atSelected, setAtSelected] = useState5(0);
|
|
8156
|
+
const atFiles = useMemo(() => {
|
|
8157
|
+
if (!codeMode?.rootDir) return [];
|
|
8158
|
+
try {
|
|
8159
|
+
return listFilesSync(codeMode.rootDir, { maxResults: 500 });
|
|
8160
|
+
} catch {
|
|
8161
|
+
return [];
|
|
8162
|
+
}
|
|
8163
|
+
}, [codeMode?.rootDir]);
|
|
8164
|
+
const atPicker = useMemo(() => {
|
|
8165
|
+
if (!codeMode?.rootDir) return null;
|
|
8166
|
+
if (slashMatches !== null) return null;
|
|
8167
|
+
return detectAtPicker(input);
|
|
8168
|
+
}, [codeMode?.rootDir, input, slashMatches]);
|
|
8169
|
+
const atMatches = useMemo(() => {
|
|
8170
|
+
if (!atPicker) return null;
|
|
8171
|
+
return rankPickerCandidates(atFiles, atPicker.query, 40);
|
|
8172
|
+
}, [atPicker, atFiles]);
|
|
8173
|
+
useEffect2(() => {
|
|
8174
|
+
setAtSelected((prev) => {
|
|
8175
|
+
if (!atMatches || atMatches.length === 0) return 0;
|
|
8176
|
+
if (prev >= atMatches.length) return atMatches.length - 1;
|
|
8177
|
+
return prev;
|
|
8178
|
+
});
|
|
8179
|
+
}, [atMatches]);
|
|
8180
|
+
const pickAtMention = useCallback(
|
|
8181
|
+
(chosenPath) => {
|
|
8182
|
+
if (!atPicker) return;
|
|
8183
|
+
const before = input.slice(0, atPicker.atOffset);
|
|
8184
|
+
setInput(`${before}@${chosenPath} `);
|
|
8185
|
+
},
|
|
8186
|
+
[atPicker, input]
|
|
8187
|
+
);
|
|
8054
8188
|
const loopRef = useRef2(null);
|
|
8055
8189
|
const subagentSinkRef = useRef2({ current: null });
|
|
8056
8190
|
const loop = useMemo(() => {
|
|
@@ -8220,6 +8354,21 @@ function App({
|
|
|
8220
8354
|
}
|
|
8221
8355
|
if (busy) return;
|
|
8222
8356
|
if (pendingShell) return;
|
|
8357
|
+
if (atMatches && atMatches.length > 0) {
|
|
8358
|
+
if (key.upArrow) {
|
|
8359
|
+
setAtSelected((i) => Math.max(0, i - 1));
|
|
8360
|
+
return;
|
|
8361
|
+
}
|
|
8362
|
+
if (key.downArrow) {
|
|
8363
|
+
setAtSelected((i) => Math.min(atMatches.length - 1, i + 1));
|
|
8364
|
+
return;
|
|
8365
|
+
}
|
|
8366
|
+
if (key.tab) {
|
|
8367
|
+
const sel = atMatches[atSelected] ?? atMatches[0];
|
|
8368
|
+
if (sel) pickAtMention(sel);
|
|
8369
|
+
return;
|
|
8370
|
+
}
|
|
8371
|
+
}
|
|
8223
8372
|
if (slashMatches && slashMatches.length > 0) {
|
|
8224
8373
|
if (key.upArrow) {
|
|
8225
8374
|
setSlashSelected((i) => Math.max(0, i - 1));
|
|
@@ -8305,6 +8454,13 @@ function App({
|
|
|
8305
8454
|
async (raw) => {
|
|
8306
8455
|
let text = raw.trim();
|
|
8307
8456
|
if (!text || busy) return;
|
|
8457
|
+
if (atMatches && atMatches.length > 0 && atPicker) {
|
|
8458
|
+
const sel = atMatches[atSelected] ?? atMatches[0];
|
|
8459
|
+
if (sel) {
|
|
8460
|
+
pickAtMention(sel);
|
|
8461
|
+
return;
|
|
8462
|
+
}
|
|
8463
|
+
}
|
|
8308
8464
|
if (text.startsWith("/") && !text.includes(" ")) {
|
|
8309
8465
|
const typed = text.slice(1).toLowerCase();
|
|
8310
8466
|
const matches = suggestSlashCommands(typed, !!codeMode);
|
|
@@ -8659,6 +8815,10 @@ function App({
|
|
|
8659
8815
|
planMode,
|
|
8660
8816
|
session,
|
|
8661
8817
|
slashSelected,
|
|
8818
|
+
atMatches,
|
|
8819
|
+
atPicker,
|
|
8820
|
+
atSelected,
|
|
8821
|
+
pickAtMention,
|
|
8662
8822
|
togglePlanMode,
|
|
8663
8823
|
writeTranscript
|
|
8664
8824
|
]
|
|
@@ -8809,7 +8969,7 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
8809
8969
|
if (stagedInput?.plan) setPendingPlan(stagedInput.plan);
|
|
8810
8970
|
setStagedInput(null);
|
|
8811
8971
|
}, [stagedInput]);
|
|
8812
|
-
return /* @__PURE__ */
|
|
8972
|
+
return /* @__PURE__ */ React13.createElement(TickerProvider, { disabled: PLAIN_UI }, /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React13.createElement(
|
|
8813
8973
|
StatsPanel,
|
|
8814
8974
|
{
|
|
8815
8975
|
summary,
|
|
@@ -8822,21 +8982,21 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
8822
8982
|
busy,
|
|
8823
8983
|
updateAvailable
|
|
8824
8984
|
}
|
|
8825
|
-
), /* @__PURE__ */
|
|
8985
|
+
), /* @__PURE__ */ React13.createElement(Static, { items: historical }, (item) => /* @__PURE__ */ React13.createElement(EventRow, { key: item.id, event: item, projectRoot: hookCwd })), !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && streaming ? /* @__PURE__ */ React13.createElement(Box12, { marginY: 1 }, /* @__PURE__ */ React13.createElement(EventRow, { event: streaming, projectRoot: hookCwd })) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && ongoingTool ? /* @__PURE__ */ React13.createElement(OngoingToolRow, { tool: ongoingTool, progress: toolProgress }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && subagentActivity ? /* @__PURE__ */ React13.createElement(SubagentRow, { activity: subagentActivity }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && !ongoingTool && statusLine ? /* @__PURE__ */ React13.createElement(StatusRow, { text: statusLine }) : null, !PLAIN_UI && !pendingShell && !pendingPlan && !stagedInput && busy && !streaming && !ongoingTool && !statusLine ? /* @__PURE__ */ React13.createElement(StatusRow, { text: "processing\u2026" }) : null, stagedInput ? /* @__PURE__ */ React13.createElement(
|
|
8826
8986
|
PlanRefineInput,
|
|
8827
8987
|
{
|
|
8828
8988
|
mode: stagedInput.mode,
|
|
8829
8989
|
onSubmit: handleStagedInputSubmit,
|
|
8830
8990
|
onCancel: handleStagedInputCancel
|
|
8831
8991
|
}
|
|
8832
|
-
) : pendingPlan ? /* @__PURE__ */
|
|
8992
|
+
) : pendingPlan ? /* @__PURE__ */ React13.createElement(PlanConfirm, { plan: pendingPlan, onChoose: handlePlanConfirm, projectRoot: hookCwd }) : pendingShell ? /* @__PURE__ */ React13.createElement(
|
|
8833
8993
|
ShellConfirm,
|
|
8834
8994
|
{
|
|
8835
8995
|
command: pendingShell,
|
|
8836
8996
|
allowPrefix: derivePrefix(pendingShell),
|
|
8837
8997
|
onChoose: handleShellConfirm
|
|
8838
8998
|
}
|
|
8839
|
-
) : /* @__PURE__ */
|
|
8999
|
+
) : /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(
|
|
8840
9000
|
PromptInput,
|
|
8841
9001
|
{
|
|
8842
9002
|
value: input,
|
|
@@ -8844,20 +9004,27 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
8844
9004
|
onSubmit: handleSubmit,
|
|
8845
9005
|
disabled: busy
|
|
8846
9006
|
}
|
|
8847
|
-
), /* @__PURE__ */
|
|
9007
|
+
), /* @__PURE__ */ React13.createElement(SlashSuggestions, { matches: slashMatches, selectedIndex: slashSelected }), /* @__PURE__ */ React13.createElement(
|
|
9008
|
+
AtMentionSuggestions,
|
|
9009
|
+
{
|
|
9010
|
+
matches: atMatches,
|
|
9011
|
+
selectedIndex: atSelected,
|
|
9012
|
+
query: atPicker?.query ?? ""
|
|
9013
|
+
}
|
|
9014
|
+
))));
|
|
8848
9015
|
}
|
|
8849
9016
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
8850
9017
|
function StatusRow({ text }) {
|
|
8851
9018
|
const tick = useTick();
|
|
8852
9019
|
const elapsed = useElapsedSeconds();
|
|
8853
|
-
return /* @__PURE__ */
|
|
9020
|
+
return /* @__PURE__ */ React13.createElement(Box12, { marginY: 1 }, /* @__PURE__ */ React13.createElement(Text12, { color: "magenta" }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React13.createElement(Text12, { color: "magenta" }, ` ${text}`), /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, ` ${elapsed}s`));
|
|
8854
9021
|
}
|
|
8855
9022
|
function SubagentRow({
|
|
8856
9023
|
activity
|
|
8857
9024
|
}) {
|
|
8858
9025
|
const tick = useTick();
|
|
8859
9026
|
const seconds = (activity.elapsedMs / 1e3).toFixed(1);
|
|
8860
|
-
return /* @__PURE__ */
|
|
9027
|
+
return /* @__PURE__ */ React13.createElement(Box12, { paddingLeft: 2 }, /* @__PURE__ */ React13.createElement(Text12, { color: "magenta" }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React13.createElement(Text12, { color: "magenta" }, ` \u232C subagent: ${activity.task}`), /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, ` \xB7 iter ${activity.iter} \xB7 ${seconds}s`));
|
|
8861
9028
|
}
|
|
8862
9029
|
function OngoingToolRow({
|
|
8863
9030
|
tool,
|
|
@@ -8866,7 +9033,7 @@ function OngoingToolRow({
|
|
|
8866
9033
|
const tick = useTick();
|
|
8867
9034
|
const elapsed = useElapsedSeconds();
|
|
8868
9035
|
const summary = summarizeToolArgs(tool.name, tool.args);
|
|
8869
|
-
return /* @__PURE__ */
|
|
9036
|
+
return /* @__PURE__ */ React13.createElement(Box12, { marginY: 1, flexDirection: "column" }, /* @__PURE__ */ React13.createElement(Box12, null, /* @__PURE__ */ React13.createElement(Text12, { color: "cyan" }, SPINNER_FRAMES[tick % SPINNER_FRAMES.length]), /* @__PURE__ */ React13.createElement(Text12, { color: "yellow" }, ` tool<${tool.name}> running\u2026`), /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, ` ${elapsed}s`)), progress ? /* @__PURE__ */ React13.createElement(Box12, { paddingLeft: 2 }, /* @__PURE__ */ React13.createElement(Text12, { color: "cyan" }, renderProgressLine(progress))) : null, summary ? /* @__PURE__ */ React13.createElement(Box12, { paddingLeft: 2 }, /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, summary)) : null);
|
|
8870
9037
|
}
|
|
8871
9038
|
function renderProgressLine(p) {
|
|
8872
9039
|
const msg = p.message ? ` ${p.message}` : "";
|
|
@@ -8962,15 +9129,15 @@ function describeRepair(repair) {
|
|
|
8962
9129
|
}
|
|
8963
9130
|
|
|
8964
9131
|
// src/cli/ui/SessionPicker.tsx
|
|
8965
|
-
import { Box as
|
|
8966
|
-
import
|
|
9132
|
+
import { Box as Box13, Text as Text13 } from "ink";
|
|
9133
|
+
import React14 from "react";
|
|
8967
9134
|
function SessionPicker({
|
|
8968
9135
|
sessionName,
|
|
8969
9136
|
messageCount,
|
|
8970
9137
|
lastActive,
|
|
8971
9138
|
onChoose
|
|
8972
9139
|
}) {
|
|
8973
|
-
return /* @__PURE__ */
|
|
9140
|
+
return /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React14.createElement(Box13, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text13, { bold: true, color: "cyan" }, `Session "${sessionName}" has ${messageCount} prior message${messageCount === 1 ? "" : "s"}`), /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, ` \xB7 last active ${relativeTime(lastActive)}`)), /* @__PURE__ */ React14.createElement(
|
|
8974
9141
|
SingleSelect,
|
|
8975
9142
|
{
|
|
8976
9143
|
initialValue: "new",
|
|
@@ -8993,7 +9160,7 @@ function SessionPicker({
|
|
|
8993
9160
|
],
|
|
8994
9161
|
onSubmit: (v) => onChoose(v)
|
|
8995
9162
|
}
|
|
8996
|
-
), /* @__PURE__ */
|
|
9163
|
+
), /* @__PURE__ */ React14.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, "\u2191\u2193 to move \xB7 Enter to pick")));
|
|
8997
9164
|
}
|
|
8998
9165
|
function relativeTime(date) {
|
|
8999
9166
|
const ms = Date.now() - date.getTime();
|
|
@@ -9009,9 +9176,9 @@ function relativeTime(date) {
|
|
|
9009
9176
|
}
|
|
9010
9177
|
|
|
9011
9178
|
// src/cli/ui/Setup.tsx
|
|
9012
|
-
import { Box as
|
|
9179
|
+
import { Box as Box14, Text as Text14, useApp as useApp2 } from "ink";
|
|
9013
9180
|
import TextInput from "ink-text-input";
|
|
9014
|
-
import
|
|
9181
|
+
import React15, { useState as useState6 } from "react";
|
|
9015
9182
|
function Setup({ onReady }) {
|
|
9016
9183
|
const [value, setValue] = useState6("");
|
|
9017
9184
|
const [error, setError] = useState6(null);
|
|
@@ -9035,7 +9202,7 @@ function Setup({ onReady }) {
|
|
|
9035
9202
|
}
|
|
9036
9203
|
onReady(trimmed);
|
|
9037
9204
|
};
|
|
9038
|
-
return /* @__PURE__ */
|
|
9205
|
+
return /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React15.createElement(Text14, { bold: true, color: "cyan" }, "Welcome to Reasonix."), /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text14, null, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, "Get one (free credit on signup): https://platform.deepseek.com/api_keys"), /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, "Saved locally to ", defaultConfigPath()), /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text14, { bold: true, color: "cyan" }, "key \u203A "), /* @__PURE__ */ React15.createElement(
|
|
9039
9206
|
TextInput,
|
|
9040
9207
|
{
|
|
9041
9208
|
value,
|
|
@@ -9044,7 +9211,7 @@ function Setup({ onReady }) {
|
|
|
9044
9211
|
mask: "\u2022",
|
|
9045
9212
|
placeholder: "sk-..."
|
|
9046
9213
|
}
|
|
9047
|
-
)), error ? /* @__PURE__ */
|
|
9214
|
+
)), error ? /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text14, { color: "red" }, error)) : value ? /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, "preview: ", redactKey(value))) : null, /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, "(Type /exit to abort.)")));
|
|
9048
9215
|
}
|
|
9049
9216
|
|
|
9050
9217
|
// src/cli/commands/chat.tsx
|
|
@@ -9060,7 +9227,7 @@ function Root({
|
|
|
9060
9227
|
const [key, setKey] = useState7(initialKey);
|
|
9061
9228
|
const [pending, setPending] = useState7(sessionPreview);
|
|
9062
9229
|
if (!key) {
|
|
9063
|
-
return /* @__PURE__ */
|
|
9230
|
+
return /* @__PURE__ */ React16.createElement(
|
|
9064
9231
|
Setup,
|
|
9065
9232
|
{
|
|
9066
9233
|
onReady: (k) => {
|
|
@@ -9072,7 +9239,7 @@ function Root({
|
|
|
9072
9239
|
}
|
|
9073
9240
|
process.env.DEEPSEEK_API_KEY = key;
|
|
9074
9241
|
if (pending && appProps.session) {
|
|
9075
|
-
return /* @__PURE__ */
|
|
9242
|
+
return /* @__PURE__ */ React16.createElement(
|
|
9076
9243
|
SessionPicker,
|
|
9077
9244
|
{
|
|
9078
9245
|
sessionName: appProps.session,
|
|
@@ -9087,7 +9254,7 @@ function Root({
|
|
|
9087
9254
|
}
|
|
9088
9255
|
);
|
|
9089
9256
|
}
|
|
9090
|
-
return /* @__PURE__ */
|
|
9257
|
+
return /* @__PURE__ */ React16.createElement(
|
|
9091
9258
|
App,
|
|
9092
9259
|
{
|
|
9093
9260
|
model: appProps.model,
|
|
@@ -9190,7 +9357,7 @@ async function chatCommand(opts) {
|
|
|
9190
9357
|
rewriteSession(opts.session, []);
|
|
9191
9358
|
}
|
|
9192
9359
|
const { waitUntilExit } = render(
|
|
9193
|
-
/* @__PURE__ */
|
|
9360
|
+
/* @__PURE__ */ React16.createElement(
|
|
9194
9361
|
Root,
|
|
9195
9362
|
{
|
|
9196
9363
|
initialKey,
|
|
@@ -9253,34 +9420,34 @@ async function codeCommand(opts = {}) {
|
|
|
9253
9420
|
import { writeFileSync as writeFileSync5 } from "fs";
|
|
9254
9421
|
import { basename as basename2 } from "path";
|
|
9255
9422
|
import { render as render2 } from "ink";
|
|
9256
|
-
import
|
|
9423
|
+
import React19 from "react";
|
|
9257
9424
|
|
|
9258
9425
|
// src/cli/ui/DiffApp.tsx
|
|
9259
|
-
import { Box as
|
|
9260
|
-
import
|
|
9426
|
+
import { Box as Box16, Static as Static2, Text as Text16, useApp as useApp3, useInput as useInput5 } from "ink";
|
|
9427
|
+
import React18, { useState as useState8 } from "react";
|
|
9261
9428
|
|
|
9262
9429
|
// src/cli/ui/RecordView.tsx
|
|
9263
|
-
import { Box as
|
|
9264
|
-
import
|
|
9430
|
+
import { Box as Box15, Text as Text15 } from "ink";
|
|
9431
|
+
import React17 from "react";
|
|
9265
9432
|
function RecordView({ rec, compact = false }) {
|
|
9266
9433
|
const toolArgsMax = compact ? 120 : 200;
|
|
9267
9434
|
const toolContentMax = compact ? 200 : 400;
|
|
9268
9435
|
if (rec.role === "user") {
|
|
9269
|
-
return /* @__PURE__ */
|
|
9436
|
+
return /* @__PURE__ */ React17.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text15, { bold: true, color: "cyan" }, "you \u203A", " "), /* @__PURE__ */ React17.createElement(Text15, null, rec.content));
|
|
9270
9437
|
}
|
|
9271
9438
|
if (rec.role === "assistant_final") {
|
|
9272
|
-
return /* @__PURE__ */
|
|
9439
|
+
return /* @__PURE__ */ React17.createElement(Box15, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React17.createElement(Box15, null, /* @__PURE__ */ React17.createElement(Text15, { bold: true, color: "green" }, "assistant"), rec.cost !== void 0 ? /* @__PURE__ */ React17.createElement(Text15, { dimColor: true }, " $", rec.cost.toFixed(6)) : null, rec.usage ? /* @__PURE__ */ React17.createElement(CacheBadge, { usage: rec.usage }) : null), rec.planState ? /* @__PURE__ */ React17.createElement(PlanStateBlock, { planState: rec.planState }) : null, rec.content ? /* @__PURE__ */ React17.createElement(Text15, null, rec.content) : /* @__PURE__ */ React17.createElement(Text15, { dimColor: true, italic: true }, "(tool-call response only)"));
|
|
9273
9440
|
}
|
|
9274
9441
|
if (rec.role === "tool") {
|
|
9275
|
-
return /* @__PURE__ */
|
|
9442
|
+
return /* @__PURE__ */ React17.createElement(Box15, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text15, { color: "yellow" }, "tool<", rec.tool ?? "?", ">"), rec.args ? /* @__PURE__ */ React17.createElement(Text15, { dimColor: true }, " args: ", truncate3(rec.args, toolArgsMax)) : null, /* @__PURE__ */ React17.createElement(Text15, { dimColor: true }, " \u2192 ", truncate3(rec.content, toolContentMax)));
|
|
9276
9443
|
}
|
|
9277
9444
|
if (rec.role === "error") {
|
|
9278
|
-
return /* @__PURE__ */
|
|
9445
|
+
return /* @__PURE__ */ React17.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text15, { color: "red", bold: true }, "error", " "), /* @__PURE__ */ React17.createElement(Text15, { color: "red" }, rec.error ?? rec.content));
|
|
9279
9446
|
}
|
|
9280
9447
|
if (rec.role === "done" || rec.role === "assistant_delta") {
|
|
9281
9448
|
return null;
|
|
9282
9449
|
}
|
|
9283
|
-
return /* @__PURE__ */
|
|
9450
|
+
return /* @__PURE__ */ React17.createElement(Box15, null, /* @__PURE__ */ React17.createElement(Text15, { dimColor: true }, "[", rec.role, "] ", rec.content));
|
|
9284
9451
|
}
|
|
9285
9452
|
function CacheBadge({ usage }) {
|
|
9286
9453
|
const hit = usage.prompt_cache_hit_tokens ?? 0;
|
|
@@ -9289,7 +9456,7 @@ function CacheBadge({ usage }) {
|
|
|
9289
9456
|
if (total === 0) return null;
|
|
9290
9457
|
const pct2 = hit / total * 100;
|
|
9291
9458
|
const color = pct2 >= 70 ? "green" : pct2 >= 40 ? "yellow" : "red";
|
|
9292
|
-
return /* @__PURE__ */
|
|
9459
|
+
return /* @__PURE__ */ React17.createElement(Text15, null, /* @__PURE__ */ React17.createElement(Text15, { dimColor: true }, " \xB7 cache "), /* @__PURE__ */ React17.createElement(Text15, { color }, pct2.toFixed(1), "%"));
|
|
9293
9460
|
}
|
|
9294
9461
|
function truncate3(s, max) {
|
|
9295
9462
|
return s.length <= max ? s : `${s.slice(0, max)}\u2026 (+${s.length - max} chars)`;
|
|
@@ -9323,7 +9490,7 @@ function DiffApp({ report }) {
|
|
|
9323
9490
|
}
|
|
9324
9491
|
});
|
|
9325
9492
|
const pair = report.pairs[idx];
|
|
9326
|
-
return /* @__PURE__ */
|
|
9493
|
+
return /* @__PURE__ */ React18.createElement(Box16, { flexDirection: "column" }, /* @__PURE__ */ React18.createElement(DiffHeader, { report }), /* @__PURE__ */ React18.createElement(Box16, { marginTop: 1, paddingX: 1, justifyContent: "space-between" }, /* @__PURE__ */ React18.createElement(Text16, { color: "cyan", bold: true }, "turn ", pair?.turn ?? "?", " (", idx + 1, " / ", report.pairs.length, ")"), /* @__PURE__ */ React18.createElement(Text16, null, pair ? /* @__PURE__ */ React18.createElement(KindBadge, { kind: pair.kind }) : null)), /* @__PURE__ */ React18.createElement(Box16, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ React18.createElement(Pane, { label: report.a.label, headerColor: "blue", records: paneRecords(pair, "a") }), /* @__PURE__ */ React18.createElement(Pane, { label: report.b.label, headerColor: "magenta", records: paneRecords(pair, "b") })), pair?.divergenceNote ? /* @__PURE__ */ React18.createElement(Box16, { marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React18.createElement(Text16, { color: "yellow" }, "\u2605 "), /* @__PURE__ */ React18.createElement(Text16, null, pair.divergenceNote)) : null, /* @__PURE__ */ React18.createElement(Box16, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "j"), "/", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "\u2193"), " next \xB7 ", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "k"), "/", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "\u2191"), " ", "prev \xB7 ", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "n"), " next-diverge \xB7 ", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "N"), "/", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "p"), " ", "prev-diverge \xB7 ", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "g"), "/", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "G"), " first/last \xB7 ", /* @__PURE__ */ React18.createElement(Text16, { bold: true }, "q"), " ", "quit")));
|
|
9327
9494
|
}
|
|
9328
9495
|
function DiffHeader({ report }) {
|
|
9329
9496
|
const a = report.a;
|
|
@@ -9341,15 +9508,15 @@ function DiffHeader({ report }) {
|
|
|
9341
9508
|
} else if (a.stats.prefixHashes[0] && a.stats.prefixHashes[0] === b.stats.prefixHashes[0]) {
|
|
9342
9509
|
prefixLine = `shared prefix hash ${a.stats.prefixHashes[0].slice(0, 12)}\u2026 \u2014 cache delta attributable to log stability, not prompt change.`;
|
|
9343
9510
|
}
|
|
9344
|
-
return /* @__PURE__ */
|
|
9511
|
+
return /* @__PURE__ */ React18.createElement(Box16, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React18.createElement(Box16, { justifyContent: "space-between" }, /* @__PURE__ */ React18.createElement(Text16, null, /* @__PURE__ */ React18.createElement(Text16, { color: "cyan", bold: true }, "reasonix diff"), /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, " \xB7 A="), /* @__PURE__ */ React18.createElement(Text16, { color: "blue" }, a.label), /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, " vs B="), /* @__PURE__ */ React18.createElement(Text16, { color: "magenta" }, b.label)), /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, report.pairs.length, " turns aligned")), /* @__PURE__ */ React18.createElement(Box16, { marginTop: 1, gap: 3 }, /* @__PURE__ */ React18.createElement(Text16, null, /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, "cache "), /* @__PURE__ */ React18.createElement(Text16, null, (a.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React18.createElement(Text16, null, (b.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ React18.createElement(Text16, { color: cacheDelta >= 0 ? "green" : "red", bold: true }, " ", cacheDelta >= 0 ? "+" : "", (cacheDelta * 100).toFixed(1), "pp")), /* @__PURE__ */ React18.createElement(Text16, null, /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, "cost "), /* @__PURE__ */ React18.createElement(Text16, null, "$", a.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, " \u2192 "), /* @__PURE__ */ React18.createElement(Text16, null, "$", b.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ React18.createElement(Text16, { color: costDelta2 <= 0 ? "green" : "red", bold: true }, " ", costDelta2 >= 0 ? "+" : "", costDelta2.toFixed(1), "%")), /* @__PURE__ */ React18.createElement(Text16, null, /* @__PURE__ */ React18.createElement(Text16, { dimColor: true }, "model calls "), /* @__PURE__ */ React18.createElement(Text16, null, a.stats.turns, " \u2192 ", b.stats.turns))), prefixLine ? /* @__PURE__ */ React18.createElement(Box16, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text16, { dimColor: true, italic: true }, prefixLine)) : null);
|
|
9345
9512
|
}
|
|
9346
9513
|
function Pane({
|
|
9347
9514
|
label,
|
|
9348
9515
|
headerColor,
|
|
9349
9516
|
records
|
|
9350
9517
|
}) {
|
|
9351
|
-
return /* @__PURE__ */
|
|
9352
|
-
|
|
9518
|
+
return /* @__PURE__ */ React18.createElement(
|
|
9519
|
+
Box16,
|
|
9353
9520
|
{
|
|
9354
9521
|
flexDirection: "column",
|
|
9355
9522
|
flexGrow: 1,
|
|
@@ -9357,21 +9524,21 @@ function Pane({
|
|
|
9357
9524
|
borderStyle: "single",
|
|
9358
9525
|
borderColor: headerColor
|
|
9359
9526
|
},
|
|
9360
|
-
/* @__PURE__ */
|
|
9361
|
-
records.length === 0 ? /* @__PURE__ */
|
|
9527
|
+
/* @__PURE__ */ React18.createElement(Text16, { color: headerColor, bold: true }, label),
|
|
9528
|
+
records.length === 0 ? /* @__PURE__ */ React18.createElement(Box16, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text16, { dimColor: true, italic: true }, "(no records on this side for this turn)")) : /* @__PURE__ */ React18.createElement(Static2, { items: records.map((rec, i) => ({ key: `${label}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React18.createElement(RecordView, { key, rec, compact: true }))
|
|
9362
9529
|
);
|
|
9363
9530
|
}
|
|
9364
9531
|
function KindBadge({ kind }) {
|
|
9365
9532
|
if (kind === "match") {
|
|
9366
|
-
return /* @__PURE__ */
|
|
9533
|
+
return /* @__PURE__ */ React18.createElement(Text16, { color: "green" }, "\u2713 match");
|
|
9367
9534
|
}
|
|
9368
9535
|
if (kind === "diverge") {
|
|
9369
|
-
return /* @__PURE__ */
|
|
9536
|
+
return /* @__PURE__ */ React18.createElement(Text16, { color: "yellow" }, "\u2605 diverge");
|
|
9370
9537
|
}
|
|
9371
9538
|
if (kind === "only_in_a") {
|
|
9372
|
-
return /* @__PURE__ */
|
|
9539
|
+
return /* @__PURE__ */ React18.createElement(Text16, { color: "blue" }, "\u2190 only in A");
|
|
9373
9540
|
}
|
|
9374
|
-
return /* @__PURE__ */
|
|
9541
|
+
return /* @__PURE__ */ React18.createElement(Text16, { color: "magenta" }, "\u2192 only in B");
|
|
9375
9542
|
}
|
|
9376
9543
|
function paneRecords(pair, side) {
|
|
9377
9544
|
if (!pair) return [];
|
|
@@ -9402,7 +9569,7 @@ markdown report written to ${opts.mdPath}`);
|
|
|
9402
9569
|
return;
|
|
9403
9570
|
}
|
|
9404
9571
|
if (wantTui) {
|
|
9405
|
-
const { waitUntilExit } = render2(
|
|
9572
|
+
const { waitUntilExit } = render2(React19.createElement(DiffApp, { report }), {
|
|
9406
9573
|
exitOnCtrlC: true,
|
|
9407
9574
|
patchConsole: false
|
|
9408
9575
|
});
|
|
@@ -9543,11 +9710,11 @@ function pad2(s, width) {
|
|
|
9543
9710
|
|
|
9544
9711
|
// src/cli/commands/replay.ts
|
|
9545
9712
|
import { render as render3 } from "ink";
|
|
9546
|
-
import
|
|
9713
|
+
import React21 from "react";
|
|
9547
9714
|
|
|
9548
9715
|
// src/cli/ui/ReplayApp.tsx
|
|
9549
|
-
import { Box as
|
|
9550
|
-
import
|
|
9716
|
+
import { Box as Box17, Static as Static3, Text as Text17, useApp as useApp4, useInput as useInput6 } from "ink";
|
|
9717
|
+
import React20, { useMemo as useMemo2, useState as useState9 } from "react";
|
|
9551
9718
|
function ReplayApp({ meta, pages }) {
|
|
9552
9719
|
const { exit } = useApp4();
|
|
9553
9720
|
const maxIdx = Math.max(0, pages.length - 1);
|
|
@@ -9586,14 +9753,14 @@ function ReplayApp({ meta, pages }) {
|
|
|
9586
9753
|
const prefixHash = cumStats.prefixHashes.length === 1 ? cumStats.prefixHashes[0].slice(0, 16) : cumStats.prefixHashes.length === 0 ? "(untracked)" : `(churned \xD7${cumStats.prefixHashes.length})`;
|
|
9587
9754
|
const currentPage = pages[idx];
|
|
9588
9755
|
const progressLabel = pages.length === 0 ? "empty transcript" : `turn ${idx + 1} / ${pages.length}`;
|
|
9589
|
-
return /* @__PURE__ */
|
|
9756
|
+
return /* @__PURE__ */ React20.createElement(Box17, { flexDirection: "column" }, /* @__PURE__ */ React20.createElement(
|
|
9590
9757
|
StatsPanel,
|
|
9591
9758
|
{
|
|
9592
9759
|
summary,
|
|
9593
9760
|
model: cumStats.models[0] ?? meta?.model ?? "?",
|
|
9594
9761
|
prefixHash
|
|
9595
9762
|
}
|
|
9596
|
-
), /* @__PURE__ */
|
|
9763
|
+
), /* @__PURE__ */ React20.createElement(Box17, { flexDirection: "column", marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React20.createElement(Box17, { justifyContent: "space-between" }, /* @__PURE__ */ React20.createElement(Text17, { color: "cyan", bold: true }, progressLabel), meta ? /* @__PURE__ */ React20.createElement(Text17, { dimColor: true }, meta.source, meta.task ? ` \xB7 ${meta.task}` : "", meta.mode ? ` \xB7 ${meta.mode}` : "") : null), currentPage ? /* @__PURE__ */ React20.createElement(Static3, { items: currentPage.records.map((rec, i) => ({ key: `${idx}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ React20.createElement(RecordView, { key, rec })) : /* @__PURE__ */ React20.createElement(Text17, { dimColor: true, italic: true }, "no records")), /* @__PURE__ */ React20.createElement(Box17, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ React20.createElement(Text17, { dimColor: true }, /* @__PURE__ */ React20.createElement(Text17, { bold: true }, "j"), "/", /* @__PURE__ */ React20.createElement(Text17, { bold: true }, "\u2193"), "/", /* @__PURE__ */ React20.createElement(Text17, { bold: true }, "space"), " next \xB7 ", /* @__PURE__ */ React20.createElement(Text17, { bold: true }, "k"), "/", /* @__PURE__ */ React20.createElement(Text17, { bold: true }, "\u2191"), " prev \xB7 ", /* @__PURE__ */ React20.createElement(Text17, { bold: true }, "g"), " first \xB7 ", /* @__PURE__ */ React20.createElement(Text17, { bold: true }, "G"), " last \xB7", " ", /* @__PURE__ */ React20.createElement(Text17, { bold: true }, "q"), " quit")));
|
|
9597
9764
|
}
|
|
9598
9765
|
|
|
9599
9766
|
// src/cli/commands/replay.ts
|
|
@@ -9605,7 +9772,7 @@ async function replayCommand(opts) {
|
|
|
9605
9772
|
}
|
|
9606
9773
|
const { parsed } = replayFromFile(opts.path);
|
|
9607
9774
|
const pages = groupRecordsByTurn(parsed.records);
|
|
9608
|
-
const { waitUntilExit } = render3(
|
|
9775
|
+
const { waitUntilExit } = render3(React21.createElement(ReplayApp, { meta: parsed.meta, pages }), {
|
|
9609
9776
|
exitOnCtrlC: true,
|
|
9610
9777
|
patchConsole: false
|
|
9611
9778
|
});
|
|
@@ -9910,12 +10077,12 @@ function truncate4(s, max) {
|
|
|
9910
10077
|
|
|
9911
10078
|
// src/cli/commands/setup.tsx
|
|
9912
10079
|
import { render as render4 } from "ink";
|
|
9913
|
-
import
|
|
10080
|
+
import React23 from "react";
|
|
9914
10081
|
|
|
9915
10082
|
// src/cli/ui/Wizard.tsx
|
|
9916
|
-
import { Box as
|
|
10083
|
+
import { Box as Box18, Text as Text18, useApp as useApp5, useInput as useInput7 } from "ink";
|
|
9917
10084
|
import TextInput2 from "ink-text-input";
|
|
9918
|
-
import
|
|
10085
|
+
import React22, { useState as useState10 } from "react";
|
|
9919
10086
|
|
|
9920
10087
|
// src/cli/ui/presets.ts
|
|
9921
10088
|
var PRESETS = {
|
|
@@ -9954,7 +10121,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
9954
10121
|
if (key.escape && step !== "saved" && onCancel) onCancel();
|
|
9955
10122
|
});
|
|
9956
10123
|
if (step === "apiKey") {
|
|
9957
|
-
return /* @__PURE__ */
|
|
10124
|
+
return /* @__PURE__ */ React22.createElement(
|
|
9958
10125
|
ApiKeyStep,
|
|
9959
10126
|
{
|
|
9960
10127
|
onSubmit: (key) => {
|
|
@@ -9968,7 +10135,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
9968
10135
|
);
|
|
9969
10136
|
}
|
|
9970
10137
|
if (step === "preset") {
|
|
9971
|
-
return /* @__PURE__ */
|
|
10138
|
+
return /* @__PURE__ */ React22.createElement(StepFrame, { title: "Pick a preset", step: 1, total: 3 }, /* @__PURE__ */ React22.createElement(
|
|
9972
10139
|
SingleSelect,
|
|
9973
10140
|
{
|
|
9974
10141
|
items: presetItems(),
|
|
@@ -9978,10 +10145,10 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
9978
10145
|
setStep("mcp");
|
|
9979
10146
|
}
|
|
9980
10147
|
}
|
|
9981
|
-
), /* @__PURE__ */
|
|
10148
|
+
), /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, "\u2191/\u2193 move \xB7 enter confirm \xB7 esc cancel")));
|
|
9982
10149
|
}
|
|
9983
10150
|
if (step === "mcp") {
|
|
9984
|
-
return /* @__PURE__ */
|
|
10151
|
+
return /* @__PURE__ */ React22.createElement(StepFrame, { title: "Which MCP servers should Reasonix wire up for you?", step: 2, total: 3 }, /* @__PURE__ */ React22.createElement(
|
|
9985
10152
|
MultiSelect,
|
|
9986
10153
|
{
|
|
9987
10154
|
items: mcpItems(),
|
|
@@ -10006,7 +10173,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
10006
10173
|
}
|
|
10007
10174
|
const currentName = pending[0];
|
|
10008
10175
|
const entry = CATALOG_BY_NAME.get(currentName);
|
|
10009
|
-
return /* @__PURE__ */
|
|
10176
|
+
return /* @__PURE__ */ React22.createElement(
|
|
10010
10177
|
McpArgsStep,
|
|
10011
10178
|
{
|
|
10012
10179
|
entry,
|
|
@@ -10024,7 +10191,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
10024
10191
|
}
|
|
10025
10192
|
if (step === "review") {
|
|
10026
10193
|
const specs = data.selectedCatalog.map((name) => buildSpec(name, data.catalogArgs));
|
|
10027
|
-
return /* @__PURE__ */
|
|
10194
|
+
return /* @__PURE__ */ React22.createElement(StepFrame, { title: "Ready to save", step: 3, total: 3 }, /* @__PURE__ */ React22.createElement(Box18, { flexDirection: "column" }, /* @__PURE__ */ React22.createElement(SummaryLine, { label: "API key", value: redactKey(data.apiKey) }), /* @__PURE__ */ React22.createElement(SummaryLine, { label: "Preset", value: data.preset }), /* @__PURE__ */ React22.createElement(
|
|
10028
10195
|
SummaryLine,
|
|
10029
10196
|
{
|
|
10030
10197
|
label: "MCP",
|
|
@@ -10032,8 +10199,8 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
10032
10199
|
}
|
|
10033
10200
|
), specs.map((spec, i) => (
|
|
10034
10201
|
// biome-ignore lint/suspicious/noArrayIndexKey: review-only render, order fixed
|
|
10035
|
-
/* @__PURE__ */
|
|
10036
|
-
)), /* @__PURE__ */
|
|
10202
|
+
/* @__PURE__ */ React22.createElement(Box18, { key: i, paddingLeft: 14 }, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, "\xB7 ", spec))
|
|
10203
|
+
)), /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, null, "Saves to ", defaultConfigPath())), error ? /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { color: "red" }, error)) : null, /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, "enter save \xB7 esc cancel"))), /* @__PURE__ */ React22.createElement(
|
|
10037
10204
|
ReviewConfirm,
|
|
10038
10205
|
{
|
|
10039
10206
|
onConfirm: () => {
|
|
@@ -10059,7 +10226,7 @@ function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
|
10059
10226
|
}
|
|
10060
10227
|
));
|
|
10061
10228
|
}
|
|
10062
|
-
return /* @__PURE__ */
|
|
10229
|
+
return /* @__PURE__ */ React22.createElement(Box18, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: "green" }, "\u25B8 Saved."), /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, null, "Run `reasonix` any time to start chatting \u2014 your settings are remembered.")), /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, "Press enter to exit.")), /* @__PURE__ */ React22.createElement(ExitOnEnter, { onExit: exit }));
|
|
10063
10230
|
}
|
|
10064
10231
|
function ApiKeyStep({
|
|
10065
10232
|
onSubmit,
|
|
@@ -10067,7 +10234,7 @@ function ApiKeyStep({
|
|
|
10067
10234
|
onError
|
|
10068
10235
|
}) {
|
|
10069
10236
|
const [value, setValue] = useState10("");
|
|
10070
|
-
return /* @__PURE__ */
|
|
10237
|
+
return /* @__PURE__ */ React22.createElement(Box18, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: "cyan" }, "Welcome to Reasonix."), /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, null, "Paste your DeepSeek API key to get started.")), /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, "Get one (free credit on signup): https://platform.deepseek.com/api_keys"), /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, "Saved locally to ", defaultConfigPath()), /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: "cyan" }, "key \u203A "), /* @__PURE__ */ React22.createElement(
|
|
10071
10238
|
TextInput2,
|
|
10072
10239
|
{
|
|
10073
10240
|
value,
|
|
@@ -10084,7 +10251,7 @@ function ApiKeyStep({
|
|
|
10084
10251
|
mask: "\u2022",
|
|
10085
10252
|
placeholder: "sk-..."
|
|
10086
10253
|
}
|
|
10087
|
-
)), error ? /* @__PURE__ */
|
|
10254
|
+
)), error ? /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { color: "red" }, error)) : value ? /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, "preview: ", redactKey(value))) : null);
|
|
10088
10255
|
}
|
|
10089
10256
|
function McpArgsStep({
|
|
10090
10257
|
entry,
|
|
@@ -10093,7 +10260,7 @@ function McpArgsStep({
|
|
|
10093
10260
|
onError
|
|
10094
10261
|
}) {
|
|
10095
10262
|
const [value, setValue] = useState10("");
|
|
10096
|
-
return /* @__PURE__ */
|
|
10263
|
+
return /* @__PURE__ */ React22.createElement(StepFrame, { title: `Configure ${entry.name}`, step: 2, total: 3 }, /* @__PURE__ */ React22.createElement(Box18, { flexDirection: "column" }, /* @__PURE__ */ React22.createElement(Text18, null, entry.summary), entry.note ? /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, entry.note)) : null, /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, null, "Required parameter: "), /* @__PURE__ */ React22.createElement(Text18, { bold: true }, entry.userArgs)), /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: "cyan" }, entry.userArgs, " \u203A "), /* @__PURE__ */ React22.createElement(
|
|
10097
10264
|
TextInput2,
|
|
10098
10265
|
{
|
|
10099
10266
|
value,
|
|
@@ -10109,7 +10276,7 @@ function McpArgsStep({
|
|
|
10109
10276
|
},
|
|
10110
10277
|
placeholder: placeholderFor(entry)
|
|
10111
10278
|
}
|
|
10112
|
-
)), error ? /* @__PURE__ */
|
|
10279
|
+
)), error ? /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { color: "red" }, error)) : null));
|
|
10113
10280
|
}
|
|
10114
10281
|
function ReviewConfirm({ onConfirm }) {
|
|
10115
10282
|
useInput7((_i, key) => {
|
|
@@ -10129,10 +10296,10 @@ function StepFrame({
|
|
|
10129
10296
|
total,
|
|
10130
10297
|
children
|
|
10131
10298
|
}) {
|
|
10132
|
-
return /* @__PURE__ */
|
|
10299
|
+
return /* @__PURE__ */ React22.createElement(Box18, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React22.createElement(Box18, null, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, "Step ", step, "/", total, " \xB7", " "), /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: "cyan" }, title)), /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1, flexDirection: "column" }, children));
|
|
10133
10300
|
}
|
|
10134
10301
|
function SummaryLine({ label, value }) {
|
|
10135
|
-
return /* @__PURE__ */
|
|
10302
|
+
return /* @__PURE__ */ React22.createElement(Box18, null, /* @__PURE__ */ React22.createElement(Text18, null, label.padEnd(12)), /* @__PURE__ */ React22.createElement(Text18, { bold: true }, value));
|
|
10136
10303
|
}
|
|
10137
10304
|
function presetItems() {
|
|
10138
10305
|
return ["fast", "smart", "max"].map((name) => ({
|
|
@@ -10188,7 +10355,7 @@ async function setupCommand(_opts = {}) {
|
|
|
10188
10355
|
const existingKey = loadApiKey();
|
|
10189
10356
|
const existing = readConfig();
|
|
10190
10357
|
const { waitUntilExit, unmount } = render4(
|
|
10191
|
-
/* @__PURE__ */
|
|
10358
|
+
/* @__PURE__ */ React23.createElement(
|
|
10192
10359
|
Wizard,
|
|
10193
10360
|
{
|
|
10194
10361
|
existingApiKey: existingKey,
|