reasonix 0.12.20 → 0.12.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +373 -63
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -181,8 +181,8 @@ function computeWait(attempt, initial, cap, retryAfter) {
|
|
|
181
181
|
}
|
|
182
182
|
function sleep(ms, signal) {
|
|
183
183
|
if (ms <= 0) return Promise.resolve();
|
|
184
|
-
return new Promise((
|
|
185
|
-
const timer = setTimeout(
|
|
184
|
+
return new Promise((resolve14, reject) => {
|
|
185
|
+
const timer = setTimeout(resolve14, ms);
|
|
186
186
|
if (signal) {
|
|
187
187
|
const onAbort = () => {
|
|
188
188
|
clearTimeout(timer);
|
|
@@ -668,7 +668,7 @@ function matchesTool(hook, toolName) {
|
|
|
668
668
|
}
|
|
669
669
|
var HOOK_OUTPUT_CAP_BYTES = 256 * 1024;
|
|
670
670
|
function defaultSpawner(input) {
|
|
671
|
-
return new Promise((
|
|
671
|
+
return new Promise((resolve14) => {
|
|
672
672
|
const child = spawn(input.command, {
|
|
673
673
|
cwd: input.cwd,
|
|
674
674
|
shell: true,
|
|
@@ -713,7 +713,7 @@ function defaultSpawner(input) {
|
|
|
713
713
|
child.stderr.on("data", (chunk) => onChunk("stderr", chunk));
|
|
714
714
|
child.once("error", (err) => {
|
|
715
715
|
clearTimeout(timer);
|
|
716
|
-
|
|
716
|
+
resolve14({
|
|
717
717
|
exitCode: null,
|
|
718
718
|
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
|
|
719
719
|
stderr: Buffer.concat(stderrChunks).toString("utf8"),
|
|
@@ -724,7 +724,7 @@ function defaultSpawner(input) {
|
|
|
724
724
|
});
|
|
725
725
|
child.once("close", (code) => {
|
|
726
726
|
clearTimeout(timer);
|
|
727
|
-
|
|
727
|
+
resolve14({
|
|
728
728
|
exitCode: code,
|
|
729
729
|
stdout: Buffer.concat(stdoutChunks).toString("utf8").trim(),
|
|
730
730
|
stderr: Buffer.concat(stderrChunks).toString("utf8").trim(),
|
|
@@ -2646,8 +2646,8 @@ var CacheFirstLoop = class {
|
|
|
2646
2646
|
}
|
|
2647
2647
|
);
|
|
2648
2648
|
for (let k = 0; k < budget2; k++) {
|
|
2649
|
-
const sample = queue.shift() ?? await new Promise((
|
|
2650
|
-
waiter =
|
|
2649
|
+
const sample = queue.shift() ?? await new Promise((resolve14) => {
|
|
2650
|
+
waiter = resolve14;
|
|
2651
2651
|
});
|
|
2652
2652
|
yield {
|
|
2653
2653
|
turn: this._turn,
|
|
@@ -5444,7 +5444,7 @@ async function runCommand(cmd, opts) {
|
|
|
5444
5444
|
};
|
|
5445
5445
|
const { bin, args, spawnOverrides } = prepareSpawn(argv);
|
|
5446
5446
|
const effectiveSpawnOpts = { ...spawnOpts, ...spawnOverrides };
|
|
5447
|
-
return await new Promise((
|
|
5447
|
+
return await new Promise((resolve14, reject) => {
|
|
5448
5448
|
let child;
|
|
5449
5449
|
try {
|
|
5450
5450
|
child = spawn3(bin, args, effectiveSpawnOpts);
|
|
@@ -5489,7 +5489,7 @@ async function runCommand(cmd, opts) {
|
|
|
5489
5489
|
const output = buf.length > maxChars ? `${buf.slice(0, maxChars)}
|
|
5490
5490
|
|
|
5491
5491
|
[\u2026 truncated ${buf.length - maxChars} chars \u2026]` : buf;
|
|
5492
|
-
|
|
5492
|
+
resolve14({ exitCode: code, output, timedOut });
|
|
5493
5493
|
});
|
|
5494
5494
|
});
|
|
5495
5495
|
}
|
|
@@ -6832,7 +6832,7 @@ var McpClient = class {
|
|
|
6832
6832
|
const id = this.nextId++;
|
|
6833
6833
|
const frame = { jsonrpc: "2.0", id, method, params };
|
|
6834
6834
|
let abortHandler = null;
|
|
6835
|
-
const promise = new Promise((
|
|
6835
|
+
const promise = new Promise((resolve14, reject) => {
|
|
6836
6836
|
const timeout = setTimeout(() => {
|
|
6837
6837
|
this.pending.delete(id);
|
|
6838
6838
|
if (abortHandler && signal) signal.removeEventListener("abort", abortHandler);
|
|
@@ -6841,7 +6841,7 @@ var McpClient = class {
|
|
|
6841
6841
|
);
|
|
6842
6842
|
}, this.requestTimeoutMs);
|
|
6843
6843
|
this.pending.set(id, {
|
|
6844
|
-
resolve:
|
|
6844
|
+
resolve: resolve14,
|
|
6845
6845
|
reject,
|
|
6846
6846
|
timeout
|
|
6847
6847
|
});
|
|
@@ -6964,12 +6964,12 @@ var StdioTransport = class {
|
|
|
6964
6964
|
}
|
|
6965
6965
|
async send(message) {
|
|
6966
6966
|
if (this.closed) throw new Error("MCP transport is closed");
|
|
6967
|
-
return new Promise((
|
|
6967
|
+
return new Promise((resolve14, reject) => {
|
|
6968
6968
|
const line = `${JSON.stringify(message)}
|
|
6969
6969
|
`;
|
|
6970
6970
|
this.child.stdin.write(line, "utf8", (err) => {
|
|
6971
6971
|
if (err) reject(err);
|
|
6972
|
-
else
|
|
6972
|
+
else resolve14();
|
|
6973
6973
|
});
|
|
6974
6974
|
});
|
|
6975
6975
|
}
|
|
@@ -6980,8 +6980,8 @@ var StdioTransport = class {
|
|
|
6980
6980
|
continue;
|
|
6981
6981
|
}
|
|
6982
6982
|
if (this.closed) return;
|
|
6983
|
-
const next = await new Promise((
|
|
6984
|
-
this.waiters.push(
|
|
6983
|
+
const next = await new Promise((resolve14) => {
|
|
6984
|
+
this.waiters.push(resolve14);
|
|
6985
6985
|
});
|
|
6986
6986
|
if (next === null) return;
|
|
6987
6987
|
yield next;
|
|
@@ -7047,8 +7047,8 @@ var SseTransport = class {
|
|
|
7047
7047
|
constructor(opts) {
|
|
7048
7048
|
this.url = opts.url;
|
|
7049
7049
|
this.headers = opts.headers ?? {};
|
|
7050
|
-
this.endpointReady = new Promise((
|
|
7051
|
-
this.resolveEndpoint =
|
|
7050
|
+
this.endpointReady = new Promise((resolve14, reject) => {
|
|
7051
|
+
this.resolveEndpoint = resolve14;
|
|
7052
7052
|
this.rejectEndpoint = reject;
|
|
7053
7053
|
});
|
|
7054
7054
|
this.endpointReady.catch(() => void 0);
|
|
@@ -7075,8 +7075,8 @@ var SseTransport = class {
|
|
|
7075
7075
|
continue;
|
|
7076
7076
|
}
|
|
7077
7077
|
if (this.closed) return;
|
|
7078
|
-
const next = await new Promise((
|
|
7079
|
-
this.waiters.push(
|
|
7078
|
+
const next = await new Promise((resolve14) => {
|
|
7079
|
+
this.waiters.push(resolve14);
|
|
7080
7080
|
});
|
|
7081
7081
|
if (next === null) return;
|
|
7082
7082
|
yield next;
|
|
@@ -7263,8 +7263,8 @@ var StreamableHttpTransport = class {
|
|
|
7263
7263
|
continue;
|
|
7264
7264
|
}
|
|
7265
7265
|
if (this.closed) return;
|
|
7266
|
-
const next = await new Promise((
|
|
7267
|
-
this.waiters.push(
|
|
7266
|
+
const next = await new Promise((resolve14) => {
|
|
7267
|
+
this.waiters.push(resolve14);
|
|
7268
7268
|
});
|
|
7269
7269
|
if (next === null) return;
|
|
7270
7270
|
yield next;
|
|
@@ -9732,7 +9732,7 @@ async function startOllamaDaemon(opts = {}) {
|
|
|
9732
9732
|
return { ready: false, pid };
|
|
9733
9733
|
}
|
|
9734
9734
|
async function pullOllamaModel(modelName, opts = {}) {
|
|
9735
|
-
return new Promise((
|
|
9735
|
+
return new Promise((resolve14) => {
|
|
9736
9736
|
const child = spawn5("ollama", ["pull", modelName], {
|
|
9737
9737
|
stdio: ["ignore", "pipe", "pipe"],
|
|
9738
9738
|
windowsHide: true
|
|
@@ -9744,8 +9744,8 @@ async function pullOllamaModel(modelName, opts = {}) {
|
|
|
9744
9744
|
}
|
|
9745
9745
|
streamLines(child.stdout, (l) => opts.onLine?.(l, "stdout"));
|
|
9746
9746
|
streamLines(child.stderr, (l) => opts.onLine?.(l, "stderr"));
|
|
9747
|
-
child.once("exit", (code) =>
|
|
9748
|
-
child.once("error", () =>
|
|
9747
|
+
child.once("exit", (code) => resolve14(code ?? -1));
|
|
9748
|
+
child.once("error", () => resolve14(-1));
|
|
9749
9749
|
});
|
|
9750
9750
|
}
|
|
9751
9751
|
function streamLines(stream, cb) {
|
|
@@ -10590,7 +10590,7 @@ var MAX_BODY_BYTES = 256 * 1024;
|
|
|
10590
10590
|
async function readBody(req) {
|
|
10591
10591
|
let total = 0;
|
|
10592
10592
|
const chunks = [];
|
|
10593
|
-
return new Promise((
|
|
10593
|
+
return new Promise((resolve14, reject) => {
|
|
10594
10594
|
req.on("data", (chunk) => {
|
|
10595
10595
|
total += chunk.length;
|
|
10596
10596
|
if (total > MAX_BODY_BYTES) {
|
|
@@ -10600,7 +10600,7 @@ async function readBody(req) {
|
|
|
10600
10600
|
}
|
|
10601
10601
|
chunks.push(chunk);
|
|
10602
10602
|
});
|
|
10603
|
-
req.on("end", () =>
|
|
10603
|
+
req.on("end", () => resolve14(Buffer.concat(chunks).toString("utf8")));
|
|
10604
10604
|
req.on("error", reject);
|
|
10605
10605
|
});
|
|
10606
10606
|
}
|
|
@@ -10677,7 +10677,7 @@ function startDashboardServer(ctx, opts = {}) {
|
|
|
10677
10677
|
const token = opts.token ?? mintToken();
|
|
10678
10678
|
const host = opts.host ?? "127.0.0.1";
|
|
10679
10679
|
const port = opts.port ?? 0;
|
|
10680
|
-
return new Promise((
|
|
10680
|
+
return new Promise((resolve14, reject) => {
|
|
10681
10681
|
const server = createServer((req, res) => {
|
|
10682
10682
|
dispatch(req, res, ctx, token).catch((err) => {
|
|
10683
10683
|
if (!res.headersSent) {
|
|
@@ -10698,7 +10698,7 @@ function startDashboardServer(ctx, opts = {}) {
|
|
|
10698
10698
|
server.close(() => doneResolve());
|
|
10699
10699
|
setTimeout(() => server.closeAllConnections?.(), 1e3).unref();
|
|
10700
10700
|
});
|
|
10701
|
-
|
|
10701
|
+
resolve14({ url, token, port: finalPort, close });
|
|
10702
10702
|
});
|
|
10703
10703
|
});
|
|
10704
10704
|
}
|
|
@@ -11314,8 +11314,8 @@ function SelectRow({
|
|
|
11314
11314
|
active,
|
|
11315
11315
|
marker
|
|
11316
11316
|
}) {
|
|
11317
|
-
const
|
|
11318
|
-
return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React4.createElement(Box3, null, /* @__PURE__ */ React4.createElement(Text3, { color }, marker, " ", item.label)), item.hint ? /* @__PURE__ */ React4.createElement(Box3, { paddingLeft: marker.length + 1 }, /* @__PURE__ */ React4.createElement(Text3, { dimColor: true }, item.hint)) : null);
|
|
11317
|
+
const color2 = item.disabled ? "gray" : active ? "cyan" : void 0;
|
|
11318
|
+
return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React4.createElement(Box3, null, /* @__PURE__ */ React4.createElement(Text3, { color: color2 }, marker, " ", item.label)), item.hint ? /* @__PURE__ */ React4.createElement(Box3, { paddingLeft: marker.length + 1 }, /* @__PURE__ */ React4.createElement(Text3, { dimColor: true }, item.hint)) : null);
|
|
11319
11319
|
}
|
|
11320
11320
|
function findNextEnabled(items, from, step) {
|
|
11321
11321
|
if (items.length === 0) return 0;
|
|
@@ -11530,13 +11530,13 @@ function EditConfirm({ block, onChoose }) {
|
|
|
11530
11530
|
) : null,
|
|
11531
11531
|
/* @__PURE__ */ React6.createElement(Box5, { flexDirection: "column" }, visibleLines.map((line, i) => {
|
|
11532
11532
|
const trimmed = line.trimStart();
|
|
11533
|
-
const
|
|
11534
|
-
const dim = !
|
|
11533
|
+
const color2 = trimmed.startsWith("+") ? "#4ade80" : trimmed.startsWith("-") ? "#f87171" : void 0;
|
|
11534
|
+
const dim = !color2;
|
|
11535
11535
|
return /* @__PURE__ */ React6.createElement(
|
|
11536
11536
|
Text4,
|
|
11537
11537
|
{
|
|
11538
11538
|
key: `diff-${effectiveScroll}-${i}`,
|
|
11539
|
-
color,
|
|
11539
|
+
color: color2,
|
|
11540
11540
|
dimColor: dim
|
|
11541
11541
|
},
|
|
11542
11542
|
line
|
|
@@ -11570,7 +11570,7 @@ function PlanStateBlock({ planState }) {
|
|
|
11570
11570
|
if (planState.rejectedPaths.length)
|
|
11571
11571
|
fields.push(["rejected", planState.rejectedPaths, "#94a3b8", true]);
|
|
11572
11572
|
if (fields.length === 0) return null;
|
|
11573
|
-
return /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", marginBottom: 1 }, fields.map(([label, items,
|
|
11573
|
+
return /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", marginBottom: 1 }, fields.map(([label, items, color2, dim]) => /* @__PURE__ */ React7.createElement(Box6, { key: label }, /* @__PURE__ */ React7.createElement(Text5, { backgroundColor: color2, color: "black", bold: true, dimColor: dim }, ` ${label} ${items.length} `), /* @__PURE__ */ React7.createElement(Text5, null, " "), /* @__PURE__ */ React7.createElement(Text5, { dimColor: dim }, items.join(" \xB7 ")))));
|
|
11574
11574
|
}
|
|
11575
11575
|
|
|
11576
11576
|
// src/cli/ui/PlanStepList.tsx
|
|
@@ -12481,8 +12481,8 @@ function gradientCells(width, glyph = GLYPH.block) {
|
|
|
12481
12481
|
const t2 = width === 1 ? 0 : i * last / (width - 1);
|
|
12482
12482
|
const lo = Math.floor(t2);
|
|
12483
12483
|
const hi = Math.min(last, lo + 1);
|
|
12484
|
-
const
|
|
12485
|
-
cells.push({ ch: glyph, color });
|
|
12484
|
+
const color2 = t2 - lo < 0.5 ? GRADIENT[lo] : GRADIENT[hi];
|
|
12485
|
+
cells.push({ ch: glyph, color: color2 });
|
|
12486
12486
|
}
|
|
12487
12487
|
return cells;
|
|
12488
12488
|
}
|
|
@@ -12659,9 +12659,9 @@ var ROLE_GLYPH = {
|
|
|
12659
12659
|
};
|
|
12660
12660
|
function RoleGlyph({
|
|
12661
12661
|
glyph,
|
|
12662
|
-
color
|
|
12662
|
+
color: color2
|
|
12663
12663
|
}) {
|
|
12664
|
-
return /* @__PURE__ */ React11.createElement(Text8, { color, bold: true }, glyph);
|
|
12664
|
+
return /* @__PURE__ */ React11.createElement(Text8, { color: color2, bold: true }, glyph);
|
|
12665
12665
|
}
|
|
12666
12666
|
function ToolPill({ label, status: status2 }) {
|
|
12667
12667
|
const bg = status2 === "err" ? "red" : "yellow";
|
|
@@ -14175,8 +14175,8 @@ function StatsPanel({
|
|
|
14175
14175
|
}
|
|
14176
14176
|
function BudgetRow({ spent, cap }) {
|
|
14177
14177
|
const pct2 = Math.max(0, spent / cap * 100);
|
|
14178
|
-
const
|
|
14179
|
-
return /* @__PURE__ */ React21.createElement(Box19, null, /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " budget "), /* @__PURE__ */ React21.createElement(Text17, { color }, `$${spent.toFixed(4)} / $${cap.toFixed(2)}`, /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, ` (${pct2.toFixed(0)}%)`)));
|
|
14178
|
+
const color2 = pct2 >= 100 ? "#f87171" : pct2 >= 80 ? "#fbbf24" : "#94a3b8";
|
|
14179
|
+
return /* @__PURE__ */ React21.createElement(Box19, null, /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " budget "), /* @__PURE__ */ React21.createElement(Text17, { color: color2 }, `$${spent.toFixed(4)} / $${cap.toFixed(2)}`, /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, ` (${pct2.toFixed(0)}%)`)));
|
|
14180
14180
|
}
|
|
14181
14181
|
function Header({
|
|
14182
14182
|
model: model2,
|
|
@@ -14246,9 +14246,9 @@ function ContextCell({
|
|
|
14246
14246
|
if (promptTokens === 0) {
|
|
14247
14247
|
return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info, dimColor: true }, "\u25A3 ctx "), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, "\u2014 (no turns yet)"));
|
|
14248
14248
|
}
|
|
14249
|
-
const
|
|
14249
|
+
const color2 = ratio >= 0.8 ? COLOR.err : ratio >= 0.6 ? COLOR.warn : COLOR.ok;
|
|
14250
14250
|
const pct2 = Math.round(ratio * 100);
|
|
14251
|
-
return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info }, "\u25A3 ctx "), /* @__PURE__ */ React21.createElement(Bar, { ratio, color, cells: showBar ? 14 : 10 }), /* @__PURE__ */ React21.createElement(Text17, null, " "), /* @__PURE__ */ React21.createElement(Text17, { color, bold: true }, formatTokens(promptTokens), "/", formatTokens(ctxMax)), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " (", pct2, "%)"), ratio >= 0.8 ? /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.err, bold: true }, " \xB7 /compact") : null);
|
|
14251
|
+
return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info }, "\u25A3 ctx "), /* @__PURE__ */ React21.createElement(Bar, { ratio, color: color2, cells: showBar ? 14 : 10 }), /* @__PURE__ */ React21.createElement(Text17, null, " "), /* @__PURE__ */ React21.createElement(Text17, { color: color2, bold: true }, formatTokens(promptTokens), "/", formatTokens(ctxMax)), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " (", pct2, "%)"), ratio >= 0.8 ? /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.err, bold: true }, " \xB7 /compact") : null);
|
|
14252
14252
|
}
|
|
14253
14253
|
function CacheCell({
|
|
14254
14254
|
hitRatio,
|
|
@@ -14262,8 +14262,8 @@ function CacheCell({
|
|
|
14262
14262
|
if (coldStart) {
|
|
14263
14263
|
return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info, dimColor: true }, "\u232C cache "), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, pct2, "% "), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true, italic: true }, "(cold start)"));
|
|
14264
14264
|
}
|
|
14265
|
-
const
|
|
14266
|
-
return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info }, "\u232C cache "), /* @__PURE__ */ React21.createElement(Text17, { color, bold: true }, pct2, "%"));
|
|
14265
|
+
const color2 = hitRatio >= 0.7 ? COLOR.ok : hitRatio >= 0.4 ? COLOR.warn : COLOR.err;
|
|
14266
|
+
return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info }, "\u232C cache "), /* @__PURE__ */ React21.createElement(Text17, { color: color2, bold: true }, pct2, "%"));
|
|
14267
14267
|
}
|
|
14268
14268
|
function turnCostColor(cost) {
|
|
14269
14269
|
if (cost <= 0) return void 0;
|
|
@@ -14289,16 +14289,16 @@ function CostCell({
|
|
|
14289
14289
|
return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info }, "\u25F4 turn "), /* @__PURE__ */ React21.createElement(Text17, { color: turnColor, bold: !coldStart, dimColor: coldStart }, "$", summary.lastTurnCostUsd.toFixed(4)), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " \xB7 session "), /* @__PURE__ */ React21.createElement(Text17, { color: sessionColor, bold: !coldStart, dimColor: coldStart }, "$", summary.totalCostUsd.toFixed(4)));
|
|
14290
14290
|
}
|
|
14291
14291
|
function BalanceCell({ balance }) {
|
|
14292
|
-
const
|
|
14293
|
-
return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info }, "\u25D0 balance "), /* @__PURE__ */ React21.createElement(Text17, { color, bold: true }, balance.currency === "USD" ? "$" : "", balance.total.toFixed(2), balance.currency !== "USD" ? ` ${balance.currency}` : ""));
|
|
14292
|
+
const color2 = balance.total < 1 ? COLOR.err : balance.total < 5 ? COLOR.warn : COLOR.ok;
|
|
14293
|
+
return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: COLOR.info }, "\u25D0 balance "), /* @__PURE__ */ React21.createElement(Text17, { color: color2, bold: true }, balance.currency === "USD" ? "$" : "", balance.total.toFixed(2), balance.currency !== "USD" ? ` ${balance.currency}` : ""));
|
|
14294
14294
|
}
|
|
14295
14295
|
function Bar({
|
|
14296
14296
|
ratio,
|
|
14297
|
-
color,
|
|
14297
|
+
color: color2,
|
|
14298
14298
|
cells = 14
|
|
14299
14299
|
}) {
|
|
14300
14300
|
const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));
|
|
14301
|
-
return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color }, "\u25B0".repeat(filled)), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, "\u25B1".repeat(cells - filled)));
|
|
14301
|
+
return /* @__PURE__ */ React21.createElement(Text17, null, /* @__PURE__ */ React21.createElement(Text17, { color: color2 }, "\u25B0".repeat(filled)), /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, "\u25B1".repeat(cells - filled)));
|
|
14302
14302
|
}
|
|
14303
14303
|
function formatTokens(n) {
|
|
14304
14304
|
if (n < 1024) return String(n);
|
|
@@ -18224,11 +18224,11 @@ function App({
|
|
|
18224
18224
|
if (key.escape && busy) {
|
|
18225
18225
|
if (abortedThisTurn.current) return;
|
|
18226
18226
|
abortedThisTurn.current = true;
|
|
18227
|
-
const
|
|
18228
|
-
if (
|
|
18227
|
+
const resolve14 = editReviewResolveRef.current;
|
|
18228
|
+
if (resolve14) {
|
|
18229
18229
|
editReviewResolveRef.current = null;
|
|
18230
18230
|
setPendingEditReview(null);
|
|
18231
|
-
|
|
18231
|
+
resolve14("reject");
|
|
18232
18232
|
}
|
|
18233
18233
|
if (activeLoopRef.current) stopLoop();
|
|
18234
18234
|
loop2.abort();
|
|
@@ -18694,11 +18694,11 @@ function App({
|
|
|
18694
18694
|
handleStagedInputSubmitRef.current(text ?? "", { plan: plan2, mode: choice }).catch(() => void 0);
|
|
18695
18695
|
},
|
|
18696
18696
|
resolveEditReview: (choice) => {
|
|
18697
|
-
const
|
|
18698
|
-
if (
|
|
18697
|
+
const resolve14 = editReviewResolveRef.current;
|
|
18698
|
+
if (resolve14) {
|
|
18699
18699
|
editReviewResolveRef.current = null;
|
|
18700
18700
|
setPendingEditReview(null);
|
|
18701
|
-
|
|
18701
|
+
resolve14(choice);
|
|
18702
18702
|
}
|
|
18703
18703
|
},
|
|
18704
18704
|
resolveWorkspaceConfirm: (choice) => {
|
|
@@ -20224,10 +20224,10 @@ Continue executing from the next pending step. Call mark_step_complete after eac
|
|
|
20224
20224
|
{
|
|
20225
20225
|
block: pendingEditReview,
|
|
20226
20226
|
onChoose: (choice) => {
|
|
20227
|
-
const
|
|
20228
|
-
if (
|
|
20227
|
+
const resolve14 = editReviewResolveRef.current;
|
|
20228
|
+
if (resolve14) {
|
|
20229
20229
|
editReviewResolveRef.current = null;
|
|
20230
|
-
|
|
20230
|
+
resolve14(choice);
|
|
20231
20231
|
}
|
|
20232
20232
|
}
|
|
20233
20233
|
}
|
|
@@ -20626,8 +20626,8 @@ function CacheBadge({ usage }) {
|
|
|
20626
20626
|
const total = hit + miss;
|
|
20627
20627
|
if (total === 0) return null;
|
|
20628
20628
|
const pct2 = hit / total * 100;
|
|
20629
|
-
const
|
|
20630
|
-
return /* @__PURE__ */ React28.createElement(Text23, null, /* @__PURE__ */ React28.createElement(Text23, { dimColor: true }, " \xB7 cache "), /* @__PURE__ */ React28.createElement(Text23, { color }, pct2.toFixed(1), "%"));
|
|
20629
|
+
const color2 = pct2 >= 70 ? "green" : pct2 >= 40 ? "yellow" : "red";
|
|
20630
|
+
return /* @__PURE__ */ React28.createElement(Text23, null, /* @__PURE__ */ React28.createElement(Text23, { dimColor: true }, " \xB7 cache "), /* @__PURE__ */ React28.createElement(Text23, { color: color2 }, pct2.toFixed(1), "%"));
|
|
20631
20631
|
}
|
|
20632
20632
|
function truncate2(s, max) {
|
|
20633
20633
|
return s.length <= max ? s : `${s.slice(0, max)}\u2026 (+${s.length - max} chars)`;
|
|
@@ -20750,8 +20750,313 @@ markdown report written to ${opts.mdPath}`);
|
|
|
20750
20750
|
console.log(renderSummaryTable(report));
|
|
20751
20751
|
}
|
|
20752
20752
|
|
|
20753
|
+
// src/cli/commands/doctor.ts
|
|
20754
|
+
import { existsSync as existsSync23, statSync as statSync14 } from "fs";
|
|
20755
|
+
import { homedir as homedir10 } from "os";
|
|
20756
|
+
import { dirname as dirname16, join as join21, resolve as resolve12 } from "path";
|
|
20757
|
+
var TTY = process.stdout.isTTY && process.env.TERM !== "dumb";
|
|
20758
|
+
function color(text, code) {
|
|
20759
|
+
if (!TTY) return text;
|
|
20760
|
+
return `\x1B[${code}m${text}\x1B[0m`;
|
|
20761
|
+
}
|
|
20762
|
+
function badge(level) {
|
|
20763
|
+
if (level === "ok") return color("\u2713", "32");
|
|
20764
|
+
if (level === "warn") return color("\u26A0", "33");
|
|
20765
|
+
return color("\u2717", "31");
|
|
20766
|
+
}
|
|
20767
|
+
function tail4(s) {
|
|
20768
|
+
return s.length <= 4 ? s : `\u2026${s.slice(-4)}`;
|
|
20769
|
+
}
|
|
20770
|
+
function fmtBytes(n) {
|
|
20771
|
+
if (n < 1024) return `${n} B`;
|
|
20772
|
+
if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
|
|
20773
|
+
return `${(n / 1024 / 1024).toFixed(1)} MB`;
|
|
20774
|
+
}
|
|
20775
|
+
async function checkApiKey() {
|
|
20776
|
+
const fromEnv = process.env.DEEPSEEK_API_KEY;
|
|
20777
|
+
if (fromEnv) {
|
|
20778
|
+
return {
|
|
20779
|
+
label: "api key ",
|
|
20780
|
+
level: "ok",
|
|
20781
|
+
detail: `set via env DEEPSEEK_API_KEY (${tail4(fromEnv)})`
|
|
20782
|
+
};
|
|
20783
|
+
}
|
|
20784
|
+
try {
|
|
20785
|
+
const cfg = readConfig();
|
|
20786
|
+
if (cfg.apiKey) {
|
|
20787
|
+
return {
|
|
20788
|
+
label: "api key ",
|
|
20789
|
+
level: "ok",
|
|
20790
|
+
detail: `from ${defaultConfigPath()} (${tail4(cfg.apiKey)})`
|
|
20791
|
+
};
|
|
20792
|
+
}
|
|
20793
|
+
} catch {
|
|
20794
|
+
}
|
|
20795
|
+
return {
|
|
20796
|
+
label: "api key ",
|
|
20797
|
+
level: "fail",
|
|
20798
|
+
detail: "not set \u2014 `reasonix setup` to save one, or export DEEPSEEK_API_KEY. Get a key at https://platform.deepseek.com/api_keys"
|
|
20799
|
+
};
|
|
20800
|
+
}
|
|
20801
|
+
async function checkConfig() {
|
|
20802
|
+
const path5 = defaultConfigPath();
|
|
20803
|
+
if (!existsSync23(path5)) {
|
|
20804
|
+
return {
|
|
20805
|
+
label: "config ",
|
|
20806
|
+
level: "warn",
|
|
20807
|
+
detail: "missing \u2014 running with library defaults. `reasonix setup` writes one."
|
|
20808
|
+
};
|
|
20809
|
+
}
|
|
20810
|
+
try {
|
|
20811
|
+
const cfg = readConfig(path5);
|
|
20812
|
+
const parts = [];
|
|
20813
|
+
if (cfg.preset) parts.push(`preset=${cfg.preset}`);
|
|
20814
|
+
if (cfg.editMode) parts.push(`editMode=${cfg.editMode}`);
|
|
20815
|
+
if (cfg.mcp && cfg.mcp.length > 0) parts.push(`mcp=${cfg.mcp.length}`);
|
|
20816
|
+
return {
|
|
20817
|
+
label: "config ",
|
|
20818
|
+
level: "ok",
|
|
20819
|
+
detail: `${path5}${parts.length ? ` (${parts.join(", ")})` : ""}`
|
|
20820
|
+
};
|
|
20821
|
+
} catch (err) {
|
|
20822
|
+
return {
|
|
20823
|
+
label: "config ",
|
|
20824
|
+
level: "fail",
|
|
20825
|
+
detail: `${path5} unreadable \u2014 ${err.message}`
|
|
20826
|
+
};
|
|
20827
|
+
}
|
|
20828
|
+
}
|
|
20829
|
+
async function checkApiReach() {
|
|
20830
|
+
const key = process.env.DEEPSEEK_API_KEY ?? readConfig().apiKey;
|
|
20831
|
+
if (!key) {
|
|
20832
|
+
return {
|
|
20833
|
+
label: "api reach ",
|
|
20834
|
+
level: "warn",
|
|
20835
|
+
detail: "skipped \u2014 no api key to test with"
|
|
20836
|
+
};
|
|
20837
|
+
}
|
|
20838
|
+
try {
|
|
20839
|
+
const client = new DeepSeekClient({ apiKey: key });
|
|
20840
|
+
const ctl = new AbortController();
|
|
20841
|
+
const timer = setTimeout(() => ctl.abort(), 8e3);
|
|
20842
|
+
let balance;
|
|
20843
|
+
try {
|
|
20844
|
+
balance = await client.getBalance({ signal: ctl.signal });
|
|
20845
|
+
} finally {
|
|
20846
|
+
clearTimeout(timer);
|
|
20847
|
+
}
|
|
20848
|
+
if (!balance) {
|
|
20849
|
+
return {
|
|
20850
|
+
label: "api reach ",
|
|
20851
|
+
level: "fail",
|
|
20852
|
+
detail: "/user/balance returned null \u2014 auth failed or network blocked"
|
|
20853
|
+
};
|
|
20854
|
+
}
|
|
20855
|
+
if (!balance.is_available) {
|
|
20856
|
+
const info2 = balance.balance_infos[0];
|
|
20857
|
+
return {
|
|
20858
|
+
label: "api reach ",
|
|
20859
|
+
level: "warn",
|
|
20860
|
+
detail: `account flagged not-available${info2 ? ` (${info2.total_balance} ${info2.currency})` : ""} \u2014 top up or check your dashboard`
|
|
20861
|
+
};
|
|
20862
|
+
}
|
|
20863
|
+
const info = balance.balance_infos[0];
|
|
20864
|
+
return {
|
|
20865
|
+
label: "api reach ",
|
|
20866
|
+
level: "ok",
|
|
20867
|
+
detail: info ? `/user/balance ok \u2014 ${info.total_balance} ${info.currency}` : "/user/balance ok"
|
|
20868
|
+
};
|
|
20869
|
+
} catch (err) {
|
|
20870
|
+
return {
|
|
20871
|
+
label: "api reach ",
|
|
20872
|
+
level: "fail",
|
|
20873
|
+
detail: `${err.message}`
|
|
20874
|
+
};
|
|
20875
|
+
}
|
|
20876
|
+
}
|
|
20877
|
+
async function checkTokenizer() {
|
|
20878
|
+
const candidates = [
|
|
20879
|
+
join21(
|
|
20880
|
+
dirname16(new URL(import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, "$1")),
|
|
20881
|
+
"..",
|
|
20882
|
+
"..",
|
|
20883
|
+
"..",
|
|
20884
|
+
"data",
|
|
20885
|
+
"deepseek-tokenizer.json.gz"
|
|
20886
|
+
),
|
|
20887
|
+
join21(process.cwd(), "data", "deepseek-tokenizer.json.gz")
|
|
20888
|
+
];
|
|
20889
|
+
for (const p of candidates) {
|
|
20890
|
+
if (existsSync23(p)) {
|
|
20891
|
+
try {
|
|
20892
|
+
const stat2 = statSync14(p);
|
|
20893
|
+
return {
|
|
20894
|
+
label: "tokenizer ",
|
|
20895
|
+
level: "ok",
|
|
20896
|
+
detail: `${p} (${fmtBytes(stat2.size)})`
|
|
20897
|
+
};
|
|
20898
|
+
} catch {
|
|
20899
|
+
}
|
|
20900
|
+
}
|
|
20901
|
+
}
|
|
20902
|
+
return {
|
|
20903
|
+
label: "tokenizer ",
|
|
20904
|
+
level: "warn",
|
|
20905
|
+
detail: "data/deepseek-tokenizer.json.gz not found \u2014 token counts will fall back to char heuristics"
|
|
20906
|
+
};
|
|
20907
|
+
}
|
|
20908
|
+
async function checkSessions() {
|
|
20909
|
+
try {
|
|
20910
|
+
const list = listSessions();
|
|
20911
|
+
if (list.length === 0) {
|
|
20912
|
+
return {
|
|
20913
|
+
label: "sessions ",
|
|
20914
|
+
level: "ok",
|
|
20915
|
+
detail: "0 saved"
|
|
20916
|
+
};
|
|
20917
|
+
}
|
|
20918
|
+
const totalBytes = list.reduce((s, e) => s + e.size, 0);
|
|
20919
|
+
const oldest = list[list.length - 1];
|
|
20920
|
+
const ageDays = Math.floor((Date.now() - oldest.mtime.getTime()) / (24 * 60 * 60 * 1e3));
|
|
20921
|
+
const stale = list.filter(
|
|
20922
|
+
(e) => Date.now() - e.mtime.getTime() >= 90 * 24 * 60 * 60 * 1e3
|
|
20923
|
+
).length;
|
|
20924
|
+
const detail = `${list.length} saved \xB7 ${fmtBytes(totalBytes)} \xB7 oldest ${ageDays}d`;
|
|
20925
|
+
if (stale > 0) {
|
|
20926
|
+
return {
|
|
20927
|
+
label: "sessions ",
|
|
20928
|
+
level: "warn",
|
|
20929
|
+
detail: `${detail} \xB7 ${stale} idle \u226590d (run /prune-sessions)`
|
|
20930
|
+
};
|
|
20931
|
+
}
|
|
20932
|
+
return { label: "sessions ", level: "ok", detail };
|
|
20933
|
+
} catch (err) {
|
|
20934
|
+
return {
|
|
20935
|
+
label: "sessions ",
|
|
20936
|
+
level: "warn",
|
|
20937
|
+
detail: `cannot list \u2014 ${err.message}`
|
|
20938
|
+
};
|
|
20939
|
+
}
|
|
20940
|
+
}
|
|
20941
|
+
async function checkHooks(projectRoot) {
|
|
20942
|
+
try {
|
|
20943
|
+
const all = loadHooks({ projectRoot });
|
|
20944
|
+
const global = all.filter((h) => h.scope === "global").length;
|
|
20945
|
+
const project = all.filter((h) => h.scope === "project").length;
|
|
20946
|
+
return {
|
|
20947
|
+
label: "hooks ",
|
|
20948
|
+
level: "ok",
|
|
20949
|
+
detail: `${global} global, ${project} project`
|
|
20950
|
+
};
|
|
20951
|
+
} catch (err) {
|
|
20952
|
+
return {
|
|
20953
|
+
label: "hooks ",
|
|
20954
|
+
level: "warn",
|
|
20955
|
+
detail: `couldn't parse settings.json \u2014 ${err.message}`
|
|
20956
|
+
};
|
|
20957
|
+
}
|
|
20958
|
+
}
|
|
20959
|
+
async function checkOllama(projectRoot) {
|
|
20960
|
+
let exists = false;
|
|
20961
|
+
try {
|
|
20962
|
+
exists = await indexExists(projectRoot);
|
|
20963
|
+
} catch {
|
|
20964
|
+
}
|
|
20965
|
+
if (!exists) {
|
|
20966
|
+
return {
|
|
20967
|
+
label: "ollama ",
|
|
20968
|
+
level: "ok",
|
|
20969
|
+
detail: "not in use (no semantic index built; `reasonix index` to enable)"
|
|
20970
|
+
};
|
|
20971
|
+
}
|
|
20972
|
+
try {
|
|
20973
|
+
const status2 = await checkOllamaStatus(process.env.REASONIX_EMBED_MODEL ?? "nomic-embed-text");
|
|
20974
|
+
if (!status2.binaryFound) {
|
|
20975
|
+
return {
|
|
20976
|
+
label: "ollama ",
|
|
20977
|
+
level: "warn",
|
|
20978
|
+
detail: "binary not on PATH \u2014 semantic_search will fail; install from https://ollama.com"
|
|
20979
|
+
};
|
|
20980
|
+
}
|
|
20981
|
+
if (!status2.daemonRunning) {
|
|
20982
|
+
return {
|
|
20983
|
+
label: "ollama ",
|
|
20984
|
+
level: "warn",
|
|
20985
|
+
detail: "daemon not running \u2014 `ollama serve` (or just call /semantic in TUI to auto-start)"
|
|
20986
|
+
};
|
|
20987
|
+
}
|
|
20988
|
+
if (!status2.modelPulled) {
|
|
20989
|
+
return {
|
|
20990
|
+
label: "ollama ",
|
|
20991
|
+
level: "warn",
|
|
20992
|
+
detail: `model ${status2.modelName} not pulled \u2014 \`ollama pull ${status2.modelName}\``
|
|
20993
|
+
};
|
|
20994
|
+
}
|
|
20995
|
+
return {
|
|
20996
|
+
label: "ollama ",
|
|
20997
|
+
level: "ok",
|
|
20998
|
+
detail: `daemon up \xB7 model ${status2.modelName} ready`
|
|
20999
|
+
};
|
|
21000
|
+
} catch (err) {
|
|
21001
|
+
return {
|
|
21002
|
+
label: "ollama ",
|
|
21003
|
+
level: "warn",
|
|
21004
|
+
detail: `probe failed \u2014 ${err.message}`
|
|
21005
|
+
};
|
|
21006
|
+
}
|
|
21007
|
+
}
|
|
21008
|
+
async function checkProject(projectRoot) {
|
|
21009
|
+
const markers = [".git", "REASONIX.md", "package.json", "pyproject.toml", "Cargo.toml", "go.mod"];
|
|
21010
|
+
const found = markers.filter((m) => existsSync23(join21(projectRoot, m)));
|
|
21011
|
+
if (found.length === 0) {
|
|
21012
|
+
return {
|
|
21013
|
+
label: "project ",
|
|
21014
|
+
level: "warn",
|
|
21015
|
+
detail: `${projectRoot} has none of: ${markers.slice(0, 3).join(", ")} \u2026 \u2014 \`reasonix code\` will still run, but @-mentions and project memory have nothing to anchor`
|
|
21016
|
+
};
|
|
21017
|
+
}
|
|
21018
|
+
return {
|
|
21019
|
+
label: "project ",
|
|
21020
|
+
level: "ok",
|
|
21021
|
+
detail: `${projectRoot} (${found.join(", ")})`
|
|
21022
|
+
};
|
|
21023
|
+
}
|
|
21024
|
+
async function doctorCommand() {
|
|
21025
|
+
loadDotenv();
|
|
21026
|
+
const projectRoot = resolve12(process.cwd());
|
|
21027
|
+
console.log(`${color(`reasonix ${VERSION} \xB7 doctor`, "1")} (cwd: ${projectRoot})`);
|
|
21028
|
+
console.log(` home: ${homedir10()}`);
|
|
21029
|
+
console.log("");
|
|
21030
|
+
const checks = await Promise.all([
|
|
21031
|
+
checkApiKey(),
|
|
21032
|
+
checkConfig(),
|
|
21033
|
+
checkApiReach(),
|
|
21034
|
+
checkTokenizer(),
|
|
21035
|
+
checkSessions(),
|
|
21036
|
+
checkHooks(projectRoot),
|
|
21037
|
+
checkOllama(projectRoot),
|
|
21038
|
+
checkProject(projectRoot)
|
|
21039
|
+
]);
|
|
21040
|
+
for (const c of checks) {
|
|
21041
|
+
console.log(` ${badge(c.level)} ${c.label} ${c.detail}`);
|
|
21042
|
+
}
|
|
21043
|
+
const ok = checks.filter((c) => c.level === "ok").length;
|
|
21044
|
+
const warn = checks.filter((c) => c.level === "warn").length;
|
|
21045
|
+
const fail = checks.filter((c) => c.level === "fail").length;
|
|
21046
|
+
console.log("");
|
|
21047
|
+
const summary = `${ok} ok \xB7 ${warn} warn \xB7 ${fail} fail`;
|
|
21048
|
+
if (fail > 0) {
|
|
21049
|
+
console.log(color(summary, "31"));
|
|
21050
|
+
process.exit(1);
|
|
21051
|
+
} else if (warn > 0) {
|
|
21052
|
+
console.log(color(summary, "33"));
|
|
21053
|
+
} else {
|
|
21054
|
+
console.log(color(summary, "32"));
|
|
21055
|
+
}
|
|
21056
|
+
}
|
|
21057
|
+
|
|
20753
21058
|
// src/cli/commands/index.ts
|
|
20754
|
-
import { resolve as
|
|
21059
|
+
import { resolve as resolve13 } from "path";
|
|
20755
21060
|
|
|
20756
21061
|
// src/index/semantic/preflight.ts
|
|
20757
21062
|
import { stdin as stdin2, stdout } from "process";
|
|
@@ -20825,7 +21130,7 @@ async function confirm(question, defaultYes) {
|
|
|
20825
21130
|
|
|
20826
21131
|
// src/cli/commands/index.ts
|
|
20827
21132
|
async function indexCommand(opts = {}) {
|
|
20828
|
-
const root =
|
|
21133
|
+
const root = resolve13(opts.dir ?? process.cwd());
|
|
20829
21134
|
const tty = process.stderr.isTTY === true && process.stdin.isTTY === true;
|
|
20830
21135
|
const model2 = opts.model ?? process.env.REASONIX_EMBED_MODEL ?? "nomic-embed-text";
|
|
20831
21136
|
const preflightOk = await ollamaPreflight({
|
|
@@ -21747,13 +22052,13 @@ function planUpdate(input) {
|
|
|
21747
22052
|
};
|
|
21748
22053
|
}
|
|
21749
22054
|
function defaultSpawn(argv) {
|
|
21750
|
-
return new Promise((
|
|
22055
|
+
return new Promise((resolve14, reject) => {
|
|
21751
22056
|
const child = spawn6(argv[0], argv.slice(1), {
|
|
21752
22057
|
stdio: "inherit",
|
|
21753
22058
|
shell: process.platform === "win32"
|
|
21754
22059
|
});
|
|
21755
22060
|
child.once("error", reject);
|
|
21756
|
-
child.once("exit", (code) =>
|
|
22061
|
+
child.once("exit", (code) => resolve14(code ?? 1));
|
|
21757
22062
|
});
|
|
21758
22063
|
}
|
|
21759
22064
|
async function updateCommand(opts = {}) {
|
|
@@ -22038,6 +22343,11 @@ program.command("stats [transcript]").description(
|
|
|
22038
22343
|
).action((transcript) => {
|
|
22039
22344
|
statsCommand({ transcript });
|
|
22040
22345
|
});
|
|
22346
|
+
program.command("doctor").description(
|
|
22347
|
+
"One-command health check \u2014 API key, config, /user/balance reachability, tokenizer, sessions, hooks, Ollama (if used), project markers. Exit 1 on any fail; 0 on warn / clean."
|
|
22348
|
+
).action(async () => {
|
|
22349
|
+
await doctorCommand();
|
|
22350
|
+
});
|
|
22041
22351
|
program.command("sessions [name]").description("List saved chat sessions, or inspect one by name.").option("-v, --verbose", "Include system prompts + tool-call metadata when inspecting").action((name, opts) => {
|
|
22042
22352
|
sessionsCommand({ name, verbose: !!opts.verbose });
|
|
22043
22353
|
});
|