nexrall-code 0.5.133 → 0.5.134
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/index.js +400 -60
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3382,7 +3382,7 @@ var require_dist = __commonJS({
|
|
|
3382
3382
|
return;
|
|
3383
3383
|
}
|
|
3384
3384
|
const noValue = fieldLength < 0;
|
|
3385
|
-
const
|
|
3385
|
+
const field2 = lineBuffer.slice(index, index + (noValue ? lineLength : fieldLength));
|
|
3386
3386
|
let step = 0;
|
|
3387
3387
|
if (noValue) {
|
|
3388
3388
|
step = lineLength;
|
|
@@ -3394,13 +3394,13 @@ var require_dist = __commonJS({
|
|
|
3394
3394
|
const position = index + step;
|
|
3395
3395
|
const valueLength = lineLength - step;
|
|
3396
3396
|
const value = lineBuffer.slice(position, position + valueLength).toString();
|
|
3397
|
-
if (
|
|
3397
|
+
if (field2 === "data") {
|
|
3398
3398
|
data += value ? "".concat(value, "\n") : "\n";
|
|
3399
|
-
} else if (
|
|
3399
|
+
} else if (field2 === "event") {
|
|
3400
3400
|
eventName = value;
|
|
3401
|
-
} else if (
|
|
3401
|
+
} else if (field2 === "id" && !value.includes("\0")) {
|
|
3402
3402
|
eventId = value;
|
|
3403
|
-
} else if (
|
|
3403
|
+
} else if (field2 === "retry") {
|
|
3404
3404
|
const retry = parseInt(value, 10);
|
|
3405
3405
|
if (!Number.isNaN(retry)) {
|
|
3406
3406
|
onParse({
|
|
@@ -3728,9 +3728,9 @@ var require_ponyfill_es2018 = __commonJS({
|
|
|
3728
3728
|
throw new TypeError(`Parameter ${position} is required in '${context}'.`);
|
|
3729
3729
|
}
|
|
3730
3730
|
}
|
|
3731
|
-
function assertRequiredField(x2,
|
|
3731
|
+
function assertRequiredField(x2, field2, context) {
|
|
3732
3732
|
if (x2 === void 0) {
|
|
3733
|
-
throw new TypeError(`${
|
|
3733
|
+
throw new TypeError(`${field2} is required in '${context}'.`);
|
|
3734
3734
|
}
|
|
3735
3735
|
}
|
|
3736
3736
|
function convertUnrestrictedDouble(value) {
|
|
@@ -68109,8 +68109,8 @@ var require_FieldFormatter = __commonJS({
|
|
|
68109
68109
|
}
|
|
68110
68110
|
return false;
|
|
68111
68111
|
}
|
|
68112
|
-
format(
|
|
68113
|
-
const preparedField = `${lodash_isnil_1.default(
|
|
68112
|
+
format(field2, fieldIndex, isHeader) {
|
|
68113
|
+
const preparedField = `${lodash_isnil_1.default(field2) ? "" : field2}`.replace(/\0/g, "");
|
|
68114
68114
|
const { formatterOptions } = this;
|
|
68115
68115
|
if (formatterOptions.quote !== "") {
|
|
68116
68116
|
const shouldEscape = preparedField.indexOf(formatterOptions.quote) !== -1;
|
|
@@ -68124,9 +68124,9 @@ var require_FieldFormatter = __commonJS({
|
|
|
68124
68124
|
}
|
|
68125
68125
|
return preparedField;
|
|
68126
68126
|
}
|
|
68127
|
-
quoteField(
|
|
68127
|
+
quoteField(field2) {
|
|
68128
68128
|
const { quote } = this.formatterOptions;
|
|
68129
|
-
return `${quote}${
|
|
68129
|
+
return `${quote}${field2}${quote}`;
|
|
68130
68130
|
}
|
|
68131
68131
|
};
|
|
68132
68132
|
exports2.FieldFormatter = FieldFormatter;
|
|
@@ -68292,7 +68292,7 @@ var require_RowFormatter = __commonJS({
|
|
|
68292
68292
|
return this._rowTransform(row, cb);
|
|
68293
68293
|
}
|
|
68294
68294
|
formatColumns(columns, isHeadersRow) {
|
|
68295
|
-
const formattedCols = columns.map((
|
|
68295
|
+
const formattedCols = columns.map((field2, i2) => this.fieldFormatter.format(field2, i2, isHeadersRow)).join(this.formatterOptions.delimiter);
|
|
68296
68296
|
const { rowCount } = this;
|
|
68297
68297
|
this.rowCount += 1;
|
|
68298
68298
|
if (rowCount) {
|
|
@@ -77951,8 +77951,8 @@ var require_common2 = __commonJS({
|
|
|
77951
77951
|
exports2.mark = mark;
|
|
77952
77952
|
exports2.isIgnored = isIgnored;
|
|
77953
77953
|
exports2.childrenIgnored = childrenIgnored;
|
|
77954
|
-
function ownProp(obj2,
|
|
77955
|
-
return Object.prototype.hasOwnProperty.call(obj2,
|
|
77954
|
+
function ownProp(obj2, field2) {
|
|
77955
|
+
return Object.prototype.hasOwnProperty.call(obj2, field2);
|
|
77956
77956
|
}
|
|
77957
77957
|
var fs15 = __require("fs");
|
|
77958
77958
|
var path15 = __require("path");
|
|
@@ -105961,14 +105961,14 @@ var require_destructive = __commonJS({
|
|
|
105961
105961
|
return null;
|
|
105962
105962
|
}
|
|
105963
105963
|
var MAX_DEPTH = 4;
|
|
105964
|
-
function
|
|
105964
|
+
function classify2(command, depth) {
|
|
105965
105965
|
if (depth > MAX_DEPTH)
|
|
105966
105966
|
return null;
|
|
105967
105967
|
const viaRegex = classifyRegex(command);
|
|
105968
105968
|
if (viaRegex)
|
|
105969
105969
|
return viaRegex;
|
|
105970
105970
|
for (const tokens of (0, destructiveTokens_1.tokenize)(stripHeredocs(command))) {
|
|
105971
|
-
const m2 = (0, destructiveTokens_1.classifyTokens)(tokens, (inner) =>
|
|
105971
|
+
const m2 = (0, destructiveTokens_1.classifyTokens)(tokens, (inner) => classify2(inner, depth + 1), classifyRawSql);
|
|
105972
105972
|
if (m2)
|
|
105973
105973
|
return m2;
|
|
105974
105974
|
}
|
|
@@ -105977,7 +105977,7 @@ var require_destructive = __commonJS({
|
|
|
105977
105977
|
function classifyDestructiveCommand(command) {
|
|
105978
105978
|
if (!command || typeof command !== "string")
|
|
105979
105979
|
return null;
|
|
105980
|
-
return
|
|
105980
|
+
return classify2(command, 0);
|
|
105981
105981
|
}
|
|
105982
105982
|
function isDestructiveBash3(tool, input) {
|
|
105983
105983
|
if (tool !== "bash" && tool !== "run_command" && tool !== "execute_command")
|
|
@@ -146066,6 +146066,269 @@ function paintLine(l2) {
|
|
|
146066
146066
|
}
|
|
146067
146067
|
}
|
|
146068
146068
|
|
|
146069
|
+
// src/ui/errorView.ts
|
|
146070
|
+
var TITLE_MAX = 120;
|
|
146071
|
+
var DETAIL_MAX = 300;
|
|
146072
|
+
function clip(s2, max) {
|
|
146073
|
+
const flat = s2.replace(/\s+/g, " ").trim();
|
|
146074
|
+
return flat.length <= max ? flat : flat.slice(0, max - 1) + "\u2026";
|
|
146075
|
+
}
|
|
146076
|
+
function messageOf(err) {
|
|
146077
|
+
let msg;
|
|
146078
|
+
if (typeof err === "string")
|
|
146079
|
+
msg = err;
|
|
146080
|
+
else if (err instanceof Error)
|
|
146081
|
+
msg = err.message || (err.name && err.name !== "Error" ? err.name : "");
|
|
146082
|
+
else if (err && typeof err === "object" && typeof err.message === "string")
|
|
146083
|
+
msg = err.message;
|
|
146084
|
+
else
|
|
146085
|
+
msg = String(err);
|
|
146086
|
+
const brace = msg.indexOf("{");
|
|
146087
|
+
if (brace > 0) {
|
|
146088
|
+
const tail = msg.slice(brace);
|
|
146089
|
+
try {
|
|
146090
|
+
const parsed = JSON.parse(tail);
|
|
146091
|
+
const inner = typeof parsed.error === "string" ? parsed.error : typeof parsed.message === "string" ? parsed.message : "";
|
|
146092
|
+
if (inner)
|
|
146093
|
+
return `${msg.slice(0, brace).replace(/[:,\s]+$/, "")}: ${inner}`.trim();
|
|
146094
|
+
} catch {
|
|
146095
|
+
}
|
|
146096
|
+
}
|
|
146097
|
+
return msg;
|
|
146098
|
+
}
|
|
146099
|
+
function codesOf(err) {
|
|
146100
|
+
const out = [];
|
|
146101
|
+
const push = (v) => {
|
|
146102
|
+
if (v && typeof v === "object") {
|
|
146103
|
+
const rec = v;
|
|
146104
|
+
if (typeof rec.code === "string")
|
|
146105
|
+
out.push(rec.code);
|
|
146106
|
+
if (typeof rec.errno === "string")
|
|
146107
|
+
out.push(rec.errno);
|
|
146108
|
+
if (typeof rec.name === "string")
|
|
146109
|
+
out.push(rec.name);
|
|
146110
|
+
if (rec.cause)
|
|
146111
|
+
push(rec.cause);
|
|
146112
|
+
}
|
|
146113
|
+
};
|
|
146114
|
+
push(err);
|
|
146115
|
+
return out;
|
|
146116
|
+
}
|
|
146117
|
+
function field(err, key) {
|
|
146118
|
+
if (err && typeof err === "object" && key in err) {
|
|
146119
|
+
return err[key];
|
|
146120
|
+
}
|
|
146121
|
+
return void 0;
|
|
146122
|
+
}
|
|
146123
|
+
var NETWORK_RE = /fetch failed|econnrefused|econnreset|enotfound|eai_again|etimedout|socket hang up|network error|getaddrinfo|tls|ssl|proxy|socket disconnected|terminated|other side closed/i;
|
|
146124
|
+
var NETWORK_CODES = /* @__PURE__ */ new Set(["ECONNREFUSED", "ECONNRESET", "ENOTFOUND", "EAI_AGAIN", "ETIMEDOUT", "UND_ERR_SOCKET", "UND_ERR_CONNECT_TIMEOUT", "EHOSTUNREACH", "ENETUNREACH"]);
|
|
146125
|
+
var CONTEXT_RE = /context (?:length|window)|too many tokens|maximum context|token limit|prompt is too long|exceeds the maximum|max_tokens|input length/i;
|
|
146126
|
+
var MODEL_RE = /unknown model|model[^.]{0,20}not found|invalid model|model[^.]{0,20}does not exist|model[^.]{0,20}not available|no such model|unsupported model/i;
|
|
146127
|
+
var AUTH_RE = /not authenticated|unauthorized|invalid (?:api )?(?:key|token)|authentication (?:failed|required)|sign in|login required|token (?:expired|revoked)/i;
|
|
146128
|
+
var BALANCE_RE = /insufficient (?:balance|credit|funds)|out of (?:credit|funds|balance)|balance (?:is )?too low|no credit|quota exceeded|payment required/i;
|
|
146129
|
+
var RATE_RE = /rate ?limit|too many requests|overloaded/i;
|
|
146130
|
+
function describeError(err, opts = {}) {
|
|
146131
|
+
const view = classify(err, opts);
|
|
146132
|
+
if (opts.debugLogPath && view.kind !== "abort")
|
|
146133
|
+
view.hints.push(`Full trace: ${opts.debugLogPath}`);
|
|
146134
|
+
return view;
|
|
146135
|
+
}
|
|
146136
|
+
function classify(err, opts) {
|
|
146137
|
+
const msg = messageOf(err);
|
|
146138
|
+
const status = field(err, "status");
|
|
146139
|
+
const code = field(err, "code");
|
|
146140
|
+
const names = codesOf(err);
|
|
146141
|
+
const hay = `${msg} ${names.join(" ")}`;
|
|
146142
|
+
const name = field(err, "name");
|
|
146143
|
+
if (opts.aborted || name === "AbortError" || names.includes("AbortError") || /^(Aborted|Request aborted)$/i.test(msg)) {
|
|
146144
|
+
return { kind: "abort", title: "Interrupted", hints: [] };
|
|
146145
|
+
}
|
|
146146
|
+
if (code === "team_budget_exhausted") {
|
|
146147
|
+
return {
|
|
146148
|
+
kind: "team-budget",
|
|
146149
|
+
title: "This team pool is out of budget",
|
|
146150
|
+
hints: ["Bill your own wallet instead: /team use personal", "Or ask a team admin to top the shared budget up"]
|
|
146151
|
+
};
|
|
146152
|
+
}
|
|
146153
|
+
if (status === 402 || BALANCE_RE.test(msg)) {
|
|
146154
|
+
return {
|
|
146155
|
+
kind: "balance",
|
|
146156
|
+
title: "Out of credit \u2014 the turn could not start",
|
|
146157
|
+
hints: ["Top up your wallet, then send the message again", "/balance shows what is left; /team switches who pays"]
|
|
146158
|
+
};
|
|
146159
|
+
}
|
|
146160
|
+
if (field(err, "authExpired") || status === 401 || AUTH_RE.test(msg)) {
|
|
146161
|
+
return {
|
|
146162
|
+
kind: "auth",
|
|
146163
|
+
title: "Not signed in",
|
|
146164
|
+
hints: ["Run `nexrall-code login` to sign in again", "Your session keeps its place: /resume picks it back up"]
|
|
146165
|
+
};
|
|
146166
|
+
}
|
|
146167
|
+
if (status === 429 || RATE_RE.test(msg)) {
|
|
146168
|
+
return {
|
|
146169
|
+
kind: "rate-limit",
|
|
146170
|
+
title: "Rate limited by the API",
|
|
146171
|
+
hints: ["Transient overload \u2014 already retried a few times automatically", "Send the message again, or /model to switch models"]
|
|
146172
|
+
};
|
|
146173
|
+
}
|
|
146174
|
+
if (status === 404 && MODEL_RE.test(msg)) {
|
|
146175
|
+
return { kind: "model", title: clip(msg, TITLE_MAX), hints: ["/model lists what this account can use"] };
|
|
146176
|
+
}
|
|
146177
|
+
if (MODEL_RE.test(msg)) {
|
|
146178
|
+
return { kind: "model", title: clip(msg, TITLE_MAX), hints: ["/model lists what this account can use"] };
|
|
146179
|
+
}
|
|
146180
|
+
if (CONTEXT_RE.test(msg)) {
|
|
146181
|
+
return {
|
|
146182
|
+
kind: "context",
|
|
146183
|
+
title: "Context window is full",
|
|
146184
|
+
hints: ["/compact summarizes the conversation to make room", "/clear starts a fresh session"]
|
|
146185
|
+
};
|
|
146186
|
+
}
|
|
146187
|
+
if (field(err, "name") === "ToolNotAllowedError") {
|
|
146188
|
+
return { kind: "tool", title: clip(msg, TITLE_MAX), hints: ["/permissions shows which tools are allowed, asked for, or denied"] };
|
|
146189
|
+
}
|
|
146190
|
+
if (typeof status === "number" && status >= 500 || /\bAPI error 5\d\d\b/.test(msg)) {
|
|
146191
|
+
return {
|
|
146192
|
+
kind: "server",
|
|
146193
|
+
title: `Nexrall API error (${typeof status === "number" ? status : "5xx"})`,
|
|
146194
|
+
hints: ["Usually transient \u2014 send the message again", "`nex doctor` checks login, model and connectivity"]
|
|
146195
|
+
};
|
|
146196
|
+
}
|
|
146197
|
+
if (NETWORK_RE.test(hay) || names.some((n) => NETWORK_CODES.has(n))) {
|
|
146198
|
+
return {
|
|
146199
|
+
kind: "network",
|
|
146200
|
+
title: "Cannot reach the Nexrall API",
|
|
146201
|
+
hints: ["Check your connection, VPN or proxy", "`nex doctor` shows what is reachable and with which credentials"]
|
|
146202
|
+
};
|
|
146203
|
+
}
|
|
146204
|
+
const view = {
|
|
146205
|
+
kind: "other",
|
|
146206
|
+
title: clip(msg, TITLE_MAX) || "The turn failed",
|
|
146207
|
+
hints: ["Send the message again to retry", "`nex doctor` checks your setup"]
|
|
146208
|
+
};
|
|
146209
|
+
return view;
|
|
146210
|
+
}
|
|
146211
|
+
function errorDetail(err, view) {
|
|
146212
|
+
if (view.kind !== "other")
|
|
146213
|
+
return null;
|
|
146214
|
+
const msg = messageOf(err);
|
|
146215
|
+
const title = view.title;
|
|
146216
|
+
if (!msg || msg === title || title.endsWith(msg))
|
|
146217
|
+
return null;
|
|
146218
|
+
return clip(msg, DETAIL_MAX);
|
|
146219
|
+
}
|
|
146220
|
+
|
|
146221
|
+
// src/ui/turnSummary.ts
|
|
146222
|
+
var FILE_TOOLS = /* @__PURE__ */ new Set([
|
|
146223
|
+
"write_file",
|
|
146224
|
+
"write_docx",
|
|
146225
|
+
"write_xlsx",
|
|
146226
|
+
"write_pptx",
|
|
146227
|
+
"edit_file",
|
|
146228
|
+
"multi_edit",
|
|
146229
|
+
"delete_file",
|
|
146230
|
+
"notebook_edit",
|
|
146231
|
+
"move_file",
|
|
146232
|
+
"copy_file"
|
|
146233
|
+
]);
|
|
146234
|
+
var TEST_RE = /(^|[\s;&|])(npm (?:run )?(?:test|t)\b|yarn test\b|pnpm (?:run )?test\b|bun test\b|jest\b|vitest\b|mocha\b|pytest\b|python3? -m pytest\b|go test\b|cargo test\b|rspec\b|phpunit\b|dotnet test\b|mvn (?:test|verify)\b|gradle test\b|make test\b|swift test\b)/i;
|
|
146235
|
+
function freshTurnStats(now = Date.now()) {
|
|
146236
|
+
return { startedAt: now, endedAt: now, rounds: 0, toolCalls: 0, files: [], testRuns: [], costKnown: false };
|
|
146237
|
+
}
|
|
146238
|
+
function pathsTouched(name, input) {
|
|
146239
|
+
if (!FILE_TOOLS.has(name) || !input || typeof input !== "object")
|
|
146240
|
+
return [];
|
|
146241
|
+
const rec = input;
|
|
146242
|
+
const str = (v) => typeof v === "string" && v ? [v] : [];
|
|
146243
|
+
if (name === "move_file")
|
|
146244
|
+
return [...str(rec.source), ...str(rec.dest)];
|
|
146245
|
+
if (name === "copy_file")
|
|
146246
|
+
return str(rec.destination);
|
|
146247
|
+
return str(rec.path);
|
|
146248
|
+
}
|
|
146249
|
+
function noteToolUse(stats, name, input, subAgent = false) {
|
|
146250
|
+
if (subAgent)
|
|
146251
|
+
return;
|
|
146252
|
+
stats.toolCalls++;
|
|
146253
|
+
for (const p of pathsTouched(name, input)) {
|
|
146254
|
+
if (!stats.files.includes(p))
|
|
146255
|
+
stats.files.push(p);
|
|
146256
|
+
}
|
|
146257
|
+
}
|
|
146258
|
+
function isTestCommand(command) {
|
|
146259
|
+
return TEST_RE.test(command);
|
|
146260
|
+
}
|
|
146261
|
+
function noteBashResult(stats, command, ok) {
|
|
146262
|
+
if (!isTestCommand(command))
|
|
146263
|
+
return;
|
|
146264
|
+
const label = command.replace(/\s+/g, " ").trim().slice(0, 60);
|
|
146265
|
+
const existing = stats.testRuns.find((t2) => t2.label === label);
|
|
146266
|
+
if (existing)
|
|
146267
|
+
existing.ok = ok;
|
|
146268
|
+
else
|
|
146269
|
+
stats.testRuns.push({ label, ok });
|
|
146270
|
+
}
|
|
146271
|
+
function formatDuration(ms) {
|
|
146272
|
+
const clamped = Math.max(0, ms);
|
|
146273
|
+
if (clamped < 1e3)
|
|
146274
|
+
return `${Math.round(clamped)}ms`;
|
|
146275
|
+
const s2 = clamped / 1e3;
|
|
146276
|
+
if (s2 < 60)
|
|
146277
|
+
return `${s2 < 10 ? s2.toFixed(1) : Math.round(s2)}s`;
|
|
146278
|
+
const m2 = Math.floor(s2 / 60);
|
|
146279
|
+
const rest = Math.round(s2 - m2 * 60);
|
|
146280
|
+
if (m2 < 60)
|
|
146281
|
+
return rest ? `${m2}m ${rest}s` : `${m2}m`;
|
|
146282
|
+
const h2 = Math.floor(m2 / 60);
|
|
146283
|
+
const rem = m2 - h2 * 60;
|
|
146284
|
+
return rem ? `${h2}h ${rem}m` : `${h2}h`;
|
|
146285
|
+
}
|
|
146286
|
+
function formatTokens(n) {
|
|
146287
|
+
if (n < 1e3)
|
|
146288
|
+
return String(n);
|
|
146289
|
+
if (n < 1e6)
|
|
146290
|
+
return `${(n / 1e3).toFixed(n < 1e5 ? 1 : 0)}k`;
|
|
146291
|
+
return `${(n / 1e6).toFixed(1)}M`;
|
|
146292
|
+
}
|
|
146293
|
+
function formatCost(usd) {
|
|
146294
|
+
if (usd > 0 && usd < 0.01)
|
|
146295
|
+
return `$${usd.toFixed(4)}`;
|
|
146296
|
+
return `$${usd.toFixed(2)}`;
|
|
146297
|
+
}
|
|
146298
|
+
function summaryLines2(stats, opts) {
|
|
146299
|
+
const { outcome } = opts;
|
|
146300
|
+
const elapsed = formatDuration(stats.endedAt - stats.startedAt);
|
|
146301
|
+
const parts = [];
|
|
146302
|
+
if (outcome === "failed")
|
|
146303
|
+
parts.push("stopped early");
|
|
146304
|
+
if (outcome === "interrupted")
|
|
146305
|
+
parts.push("interrupted");
|
|
146306
|
+
const n = stats.files.length;
|
|
146307
|
+
if (n)
|
|
146308
|
+
parts.push(`${n} file${n === 1 ? "" : "s"} changed`);
|
|
146309
|
+
if (stats.toolCalls)
|
|
146310
|
+
parts.push(`${stats.toolCalls} tool call${stats.toolCalls === 1 ? "" : "s"}`);
|
|
146311
|
+
if (stats.tokens) {
|
|
146312
|
+
const cached = stats.cachedTokens ?? 0;
|
|
146313
|
+
const pct = cached > 0 ? ` (cached ${Math.round(cached / stats.tokens * 100)}%)` : "";
|
|
146314
|
+
parts.push(`${formatTokens(stats.tokens)} tokens${pct}`);
|
|
146315
|
+
}
|
|
146316
|
+
if (stats.costKnown && stats.costUsd)
|
|
146317
|
+
parts.push(formatCost(stats.costUsd));
|
|
146318
|
+
parts.push(elapsed);
|
|
146319
|
+
const head = parts.join(" \xB7 ");
|
|
146320
|
+
const lines = [head];
|
|
146321
|
+
const failedTests = stats.testRuns.filter((t2) => !t2.ok);
|
|
146322
|
+
for (const t2 of failedTests)
|
|
146323
|
+
lines.push(`tests: \u2717 ${t2.label}`);
|
|
146324
|
+
if (failedTests.length === 0) {
|
|
146325
|
+
for (const t2 of stats.testRuns)
|
|
146326
|
+
lines.push(`tests: \u2713 ${t2.label}`);
|
|
146327
|
+
}
|
|
146328
|
+
const cols = opts.cols && opts.cols > 20 ? opts.cols - 4 : 0;
|
|
146329
|
+
return cols ? lines.map((l2) => l2.length > cols ? l2.slice(0, cols - 1) + "\u2026" : l2) : lines;
|
|
146330
|
+
}
|
|
146331
|
+
|
|
146069
146332
|
// src/commands/chat.ts
|
|
146070
146333
|
import * as os9 from "os";
|
|
146071
146334
|
import * as crypto4 from "crypto";
|
|
@@ -147036,23 +147299,39 @@ function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, ne
|
|
|
147036
147299
|
};
|
|
147037
147300
|
}
|
|
147038
147301
|
|
|
147302
|
+
// src/ui/previewCap.ts
|
|
147303
|
+
var MAX_PREVIEW_LINES = 24;
|
|
147304
|
+
function previewCap(total, max = MAX_PREVIEW_LINES) {
|
|
147305
|
+
const show = Math.max(0, Math.min(total, max));
|
|
147306
|
+
return { show, hidden: Math.max(0, total - show) };
|
|
147307
|
+
}
|
|
147308
|
+
function hiddenNote(hidden) {
|
|
147309
|
+
return `\u2026 ${hidden} more line${hidden === 1 ? "" : "s"} not shown`;
|
|
147310
|
+
}
|
|
147311
|
+
|
|
147039
147312
|
// src/ui/diff.ts
|
|
147040
147313
|
function showDiff(filePath2, oldContent, newContent) {
|
|
147041
147314
|
const isNew = oldContent === null;
|
|
147042
147315
|
const from = isNew ? "/dev/null" : `a/${filePath2}`;
|
|
147043
147316
|
const to = `b/${filePath2}`;
|
|
147044
|
-
|
|
147045
|
-
|
|
147046
|
-
|
|
147317
|
+
const emit = (head, body2) => {
|
|
147318
|
+
for (const line of head)
|
|
147319
|
+
console.log(line);
|
|
147320
|
+
const { show, hidden } = previewCap(body2.length);
|
|
147321
|
+
for (const line of body2.slice(0, show))
|
|
147322
|
+
console.log(line);
|
|
147323
|
+
if (hidden > 0)
|
|
147324
|
+
console.log(source_default.dim(` ${hiddenNote(hidden)}`));
|
|
147325
|
+
console.log();
|
|
147326
|
+
};
|
|
147047
147327
|
if (isNew) {
|
|
147048
147328
|
const lines = newContent.split("\n");
|
|
147049
147329
|
if (lines[lines.length - 1] === "")
|
|
147050
147330
|
lines.pop();
|
|
147051
|
-
|
|
147052
|
-
|
|
147053
|
-
|
|
147054
|
-
|
|
147055
|
-
console.log();
|
|
147331
|
+
emit(
|
|
147332
|
+
["", source_default.bold(`--- ${from}`), source_default.bold(`+++ ${to}`), source_default.cyan(`@@ -0,0 +1,${lines.length} @@`)],
|
|
147333
|
+
lines.map((line) => source_default.green(`+${line}`))
|
|
147334
|
+
);
|
|
147056
147335
|
return;
|
|
147057
147336
|
}
|
|
147058
147337
|
const patch = structuredPatch(
|
|
@@ -147069,20 +147348,21 @@ function showDiff(filePath2, oldContent, newContent) {
|
|
|
147069
147348
|
console.log();
|
|
147070
147349
|
return;
|
|
147071
147350
|
}
|
|
147351
|
+
const body = [];
|
|
147072
147352
|
for (const hunk of patch.hunks) {
|
|
147073
147353
|
const hunkHeader = `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`;
|
|
147074
|
-
|
|
147354
|
+
body.push(source_default.cyan(hunkHeader));
|
|
147075
147355
|
for (const line of hunk.lines) {
|
|
147076
147356
|
if (line.startsWith("+")) {
|
|
147077
|
-
|
|
147357
|
+
body.push(source_default.green(line));
|
|
147078
147358
|
} else if (line.startsWith("-")) {
|
|
147079
|
-
|
|
147359
|
+
body.push(source_default.red(line));
|
|
147080
147360
|
} else {
|
|
147081
|
-
|
|
147361
|
+
body.push(source_default.gray(line));
|
|
147082
147362
|
}
|
|
147083
147363
|
}
|
|
147084
147364
|
}
|
|
147085
|
-
|
|
147365
|
+
emit(["", source_default.bold(`--- ${from}`), source_default.bold(`+++ ${to}`)], body);
|
|
147086
147366
|
}
|
|
147087
147367
|
|
|
147088
147368
|
// src/permissions/risk.ts
|
|
@@ -147211,6 +147491,15 @@ function announceAgent(req) {
|
|
|
147211
147491
|
console.error();
|
|
147212
147492
|
console.error(source_default.cyan(` \u21B3 sub-agent ${req.agent.name}${req.agent.description ? ` (${req.agent.description})` : ""} asks:`));
|
|
147213
147493
|
}
|
|
147494
|
+
function printCommandBox(command) {
|
|
147495
|
+
const lines = command.split("\n");
|
|
147496
|
+
const { show, hidden } = previewCap(lines.length);
|
|
147497
|
+
for (const line of lines.slice(0, show)) {
|
|
147498
|
+
console.error(source_default.yellow(" \u2502 ") + source_default.white(line));
|
|
147499
|
+
}
|
|
147500
|
+
if (hidden > 0)
|
|
147501
|
+
console.error(source_default.yellow(" \u2502 ") + source_default.dim(hiddenNote(hidden)));
|
|
147502
|
+
}
|
|
147214
147503
|
async function requestPermission(req) {
|
|
147215
147504
|
const { tool, input } = req;
|
|
147216
147505
|
const decision = (0, import_code_core4.evaluatePermission)(_rules, tool, input, _workDir);
|
|
@@ -147227,9 +147516,7 @@ async function requestPermission(req) {
|
|
|
147227
147516
|
console.error(source_default.red.bold(" \u26A0 DESTRUCTIVE / IRREVERSIBLE COMMAND"));
|
|
147228
147517
|
console.error(source_default.red(` ${destructive.reason} [${destructive.category}]`));
|
|
147229
147518
|
console.error(source_default.yellow(" \u250C\u2500 bash \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"));
|
|
147230
|
-
|
|
147231
|
-
console.error(source_default.yellow(" \u2502 ") + source_default.white(line));
|
|
147232
|
-
}
|
|
147519
|
+
printCommandBox(command);
|
|
147233
147520
|
console.error(source_default.yellow(" \u2514\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\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
147234
147521
|
console.error(source_default.dim(" This cannot be undone. Auto-approve does not apply here."));
|
|
147235
147522
|
console.error();
|
|
@@ -147341,9 +147628,7 @@ async function askFlow(req) {
|
|
|
147341
147628
|
const command = input.command ?? input.cmd ?? "";
|
|
147342
147629
|
console.error();
|
|
147343
147630
|
console.error(source_default.yellow(" \u250C\u2500 bash \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"));
|
|
147344
|
-
|
|
147345
|
-
console.error(source_default.yellow(" \u2502 ") + source_default.white(line));
|
|
147346
|
-
}
|
|
147631
|
+
printCommandBox(command);
|
|
147347
147632
|
console.error(source_default.yellow(" \u2514\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\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
147348
147633
|
console.error();
|
|
147349
147634
|
const v = await choose({
|
|
@@ -147454,6 +147739,9 @@ function redact(text, max = 400) {
|
|
|
147454
147739
|
s2 = s2.replace(/(authorization["']?\s*[:=]\s*["']?)(bearer\s+)?[^\s"',}]+/gi, "$1[redacted]").replace(/\bbearer\s+[A-Za-z0-9._~+/=-]{8,}/gi, "Bearer [redacted]").replace(/\b(sk|pk|rk|ghp|gho|ghs|github_pat|xox[abprs]|AKIA|AIza)[-_A-Za-z0-9]{12,}/g, "[redacted]").replace(/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{5,}/g, "[redacted-jwt]").replace(/((?:api[_-]?key|token|secret|password|passwd)["']?\s*[:=]\s*["']?)[^\s"',}&]{4,}/gi, "$1[redacted]");
|
|
147455
147740
|
return s2.length > max ? s2.slice(0, max) + "\u2026" : s2;
|
|
147456
147741
|
}
|
|
147742
|
+
function debugLogPath() {
|
|
147743
|
+
return filePath;
|
|
147744
|
+
}
|
|
147457
147745
|
function enableDebug(explicitPath) {
|
|
147458
147746
|
try {
|
|
147459
147747
|
const p = explicitPath ? path3.resolve(explicitPath) : path3.join(debugDir(), `${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}-${process.pid}.log`);
|
|
@@ -154372,10 +154660,10 @@ var Output = class {
|
|
|
154372
154660
|
transformers
|
|
154373
154661
|
});
|
|
154374
154662
|
}
|
|
154375
|
-
clip(
|
|
154663
|
+
clip(clip4) {
|
|
154376
154664
|
this.operations.push({
|
|
154377
154665
|
type: "clip",
|
|
154378
|
-
clip:
|
|
154666
|
+
clip: clip4
|
|
154379
154667
|
});
|
|
154380
154668
|
}
|
|
154381
154669
|
unclip() {
|
|
@@ -154409,40 +154697,40 @@ var Output = class {
|
|
|
154409
154697
|
const { text, transformers } = operation;
|
|
154410
154698
|
let { x: x2, y } = operation;
|
|
154411
154699
|
let lines = text.split("\n");
|
|
154412
|
-
const
|
|
154413
|
-
if (
|
|
154414
|
-
const clipHorizontally = typeof
|
|
154415
|
-
const clipVertically = typeof
|
|
154700
|
+
const clip4 = clips.at(-1);
|
|
154701
|
+
if (clip4) {
|
|
154702
|
+
const clipHorizontally = typeof clip4?.x1 === "number" && typeof clip4?.x2 === "number";
|
|
154703
|
+
const clipVertically = typeof clip4?.y1 === "number" && typeof clip4?.y2 === "number";
|
|
154416
154704
|
if (clipHorizontally) {
|
|
154417
154705
|
const width = this.caches.getWidestLine(text);
|
|
154418
|
-
if (x2 + width <
|
|
154706
|
+
if (x2 + width < clip4.x1 || x2 > clip4.x2) {
|
|
154419
154707
|
continue;
|
|
154420
154708
|
}
|
|
154421
154709
|
}
|
|
154422
154710
|
if (clipVertically) {
|
|
154423
154711
|
const height = lines.length;
|
|
154424
|
-
if (y + height <
|
|
154712
|
+
if (y + height < clip4.y1 || y > clip4.y2) {
|
|
154425
154713
|
continue;
|
|
154426
154714
|
}
|
|
154427
154715
|
}
|
|
154428
154716
|
if (clipHorizontally) {
|
|
154429
154717
|
lines = lines.map((line) => {
|
|
154430
|
-
const from = x2 <
|
|
154718
|
+
const from = x2 < clip4.x1 ? clip4.x1 - x2 : 0;
|
|
154431
154719
|
const width = this.caches.getStringWidth(line);
|
|
154432
|
-
const to = x2 + width >
|
|
154720
|
+
const to = x2 + width > clip4.x2 ? clip4.x2 - x2 : width;
|
|
154433
154721
|
return sliceAnsi(line, from, to);
|
|
154434
154722
|
});
|
|
154435
|
-
if (x2 <
|
|
154436
|
-
x2 =
|
|
154723
|
+
if (x2 < clip4.x1) {
|
|
154724
|
+
x2 = clip4.x1;
|
|
154437
154725
|
}
|
|
154438
154726
|
}
|
|
154439
154727
|
if (clipVertically) {
|
|
154440
|
-
const from = y <
|
|
154728
|
+
const from = y < clip4.y1 ? clip4.y1 - y : 0;
|
|
154441
154729
|
const height = lines.length;
|
|
154442
|
-
const to = y + height >
|
|
154730
|
+
const to = y + height > clip4.y2 ? clip4.y2 - y : height;
|
|
154443
154731
|
lines = lines.slice(from, to);
|
|
154444
|
-
if (y <
|
|
154445
|
-
y =
|
|
154732
|
+
if (y < clip4.y1) {
|
|
154733
|
+
y = clip4.y1;
|
|
154446
154734
|
}
|
|
154447
154735
|
}
|
|
154448
154736
|
}
|
|
@@ -157611,7 +157899,7 @@ function ctxSegment(pct) {
|
|
|
157611
157899
|
function money2(usd) {
|
|
157612
157900
|
return usd > 0 && usd < 0.01 ? "$" + usd.toFixed(4) : "$" + usd.toFixed(2);
|
|
157613
157901
|
}
|
|
157614
|
-
function
|
|
157902
|
+
function clip2(s2, max) {
|
|
157615
157903
|
return s2.length <= max ? s2 : s2.slice(0, Math.max(1, max - 1)) + "\u2026";
|
|
157616
157904
|
}
|
|
157617
157905
|
function composeFooter(base, extras, columns, reserve = 0) {
|
|
@@ -157622,9 +157910,9 @@ function composeFooter(base, extras, columns, reserve = 0) {
|
|
|
157622
157910
|
];
|
|
157623
157911
|
const optional = [];
|
|
157624
157912
|
if (extras?.model)
|
|
157625
|
-
optional.push({ keep: 3, at: 0, segment: { text:
|
|
157913
|
+
optional.push({ keep: 3, at: 0, segment: { text: clip2(extras.model, 24), tone: "dim" } });
|
|
157626
157914
|
if (extras?.branch)
|
|
157627
|
-
optional.push({ keep: 1, at: 1, segment: { text: "\u2387 " +
|
|
157915
|
+
optional.push({ keep: 1, at: 1, segment: { text: "\u2387 " + clip2(extras.branch, 24), tone: "dim" } });
|
|
157628
157916
|
if (typeof extras?.ctxPct === "number")
|
|
157629
157917
|
optional.push({ keep: 4, at: 2, segment: ctxSegment(extras.ctxPct) });
|
|
157630
157918
|
if (typeof extras?.costUsd === "number")
|
|
@@ -159672,7 +159960,7 @@ var InkReadlineAdapter = class extends EventEmitter3 {
|
|
|
159672
159960
|
// src/ui/rewindPicker.ts
|
|
159673
159961
|
var MAX_REWIND_CHOICES = 9;
|
|
159674
159962
|
var LABEL_MAX = 52;
|
|
159675
|
-
function
|
|
159963
|
+
function clip3(text, max) {
|
|
159676
159964
|
const t2 = text.replace(/\s+/g, " ").trim();
|
|
159677
159965
|
return t2.length <= max ? t2 : t2.slice(0, max - 1) + "\u2026";
|
|
159678
159966
|
}
|
|
@@ -159683,7 +159971,7 @@ function rewindChoices(cps) {
|
|
|
159683
159971
|
const options = newest.map((c, i2) => {
|
|
159684
159972
|
const files = `${c.fileCount} file${c.fileCount === 1 ? "" : "s"}`;
|
|
159685
159973
|
const bash = c.bashCount > 0 ? ` \xB7 ${c.bashCount} shell cmd${c.bashCount === 1 ? "" : "s"} (not undone)` : "";
|
|
159686
|
-
return { key: String(i2 + 1), label: `${
|
|
159974
|
+
return { key: String(i2 + 1), label: `${clip3(c.label, LABEL_MAX)} (${files}${bash})` };
|
|
159687
159975
|
});
|
|
159688
159976
|
options.push({ key: "n", label: "Cancel" });
|
|
159689
159977
|
return { options, ids: newest.map((c) => c.id) };
|
|
@@ -160501,8 +160789,38 @@ function formatAgentsList(workDir) {
|
|
|
160501
160789
|
}
|
|
160502
160790
|
return lines.join("\n");
|
|
160503
160791
|
}
|
|
160792
|
+
var turnStats = freshTurnStats();
|
|
160793
|
+
function printTurnSummary(outcome) {
|
|
160794
|
+
if (turnStats.endedAt <= turnStats.startedAt)
|
|
160795
|
+
turnStats.endedAt = Date.now();
|
|
160796
|
+
const lines = summaryLines2(turnStats, { outcome, cols: process.stdout.columns });
|
|
160797
|
+
const glyph = outcome === "ok" ? source_default.green("\u2713") : outcome === "interrupted" ? source_default.yellow("\u25E6") : source_default.red("\u2717");
|
|
160798
|
+
console.log(" " + glyph + " " + source_default.dim(lines[0]));
|
|
160799
|
+
for (const extra of lines.slice(1))
|
|
160800
|
+
console.log(" " + source_default.dim(extra));
|
|
160801
|
+
}
|
|
160802
|
+
function errorReportLines(err, aborted) {
|
|
160803
|
+
const view = describeError(err, { aborted, debugLogPath: debugLogPath() ?? void 0 });
|
|
160804
|
+
if (view.kind === "abort")
|
|
160805
|
+
return ["", source_default.yellow(" \u25E6 Interrupted")];
|
|
160806
|
+
const lines = ["", source_default.red(" \u2717 ") + source_default.bold(view.title)];
|
|
160807
|
+
const detail = errorDetail(err, view);
|
|
160808
|
+
if (detail)
|
|
160809
|
+
lines.push(source_default.dim(" " + detail));
|
|
160810
|
+
for (const h2 of view.hints)
|
|
160811
|
+
lines.push(source_default.dim(" " + h2));
|
|
160812
|
+
return lines;
|
|
160813
|
+
}
|
|
160814
|
+
function printErrorReport(err, aborted) {
|
|
160815
|
+
for (const l2 of errorReportLines(err, aborted))
|
|
160816
|
+
console.error(l2);
|
|
160817
|
+
}
|
|
160504
160818
|
async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrallMd, mode, effort, checkpointManager, onProgress, takePendingInput, worktreeState, peerCtx) {
|
|
160505
160819
|
let lastUsage;
|
|
160820
|
+
turnStats = freshTurnStats();
|
|
160821
|
+
const turnCostStart = sessionUsage.cost;
|
|
160822
|
+
const turnTokenStart = sessionUsage.totalTokens;
|
|
160823
|
+
const turnCachedStart = sessionUsage.cacheRead;
|
|
160506
160824
|
const spinner = new Spinner();
|
|
160507
160825
|
const mdRender = new MarkdownStreamRenderer();
|
|
160508
160826
|
const toolStream = new ToolStreamPrinter(PREVIEW_LINES);
|
|
@@ -160614,7 +160932,13 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
160614
160932
|
mdRender.flush();
|
|
160615
160933
|
spinner.stop();
|
|
160616
160934
|
if (meta?.id)
|
|
160617
|
-
toolCalls.set(meta.id, {
|
|
160935
|
+
toolCalls.set(meta.id, {
|
|
160936
|
+
name,
|
|
160937
|
+
start: Date.now(),
|
|
160938
|
+
label: toolLabel(name, input),
|
|
160939
|
+
command: name === "bash" && typeof input.command === "string" ? input.command : void 0
|
|
160940
|
+
});
|
|
160941
|
+
noteToolUse(turnStats, name, input, isSubTask);
|
|
160618
160942
|
debugLog("tool_use", { tool: name, sub: !!isSubTask });
|
|
160619
160943
|
if (isSubTask) {
|
|
160620
160944
|
console.log(subPrefix(meta) + formatToolUse(name, input).trim());
|
|
@@ -160647,6 +160971,8 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
160647
160971
|
const tracked = meta?.id ? toolCalls.get(meta.id) : void 0;
|
|
160648
160972
|
if (meta?.id)
|
|
160649
160973
|
toolCalls.delete(meta.id);
|
|
160974
|
+
if (!isSubTask && tracked?.command)
|
|
160975
|
+
noteBashResult(turnStats, tracked.command, res.error === void 0);
|
|
160650
160976
|
debugLog("tool_result", { tool: tracked?.name ?? name, ms: tracked ? Date.now() - tracked.start : void 0, ok: res.error === void 0, error: res.error, sub: !!isSubTask });
|
|
160651
160977
|
if (isSubTask) {
|
|
160652
160978
|
const ms = tracked ? Date.now() - tracked.start : 0;
|
|
@@ -160690,6 +161016,7 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
160690
161016
|
debugLog("usage", { input: u.input_tokens, output: u.output_tokens, cache_read: u.cache_read_input_tokens, cache_write: u.cache_creation_input_tokens, cost, partial: !!partial, sub: !!isSubTask });
|
|
160691
161017
|
},
|
|
160692
161018
|
onApiCallDuration: (ms) => {
|
|
161019
|
+
turnStats.rounds++;
|
|
160693
161020
|
debugLog("api_call", { ms });
|
|
160694
161021
|
},
|
|
160695
161022
|
// A transient disconnect (network drop, machine sleep/wake, overloaded upstream)
|
|
@@ -160731,6 +161058,12 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
160731
161058
|
mdRender.flush();
|
|
160732
161059
|
printBalanceNotice(balance, zero);
|
|
160733
161060
|
},
|
|
161061
|
+
// The user's Esc / Ctrl+C. Wiring this into the loop is what makes "interrupt" mean
|
|
161062
|
+
// STOP rather than "stop drawing": without it the signal only silenced the event
|
|
161063
|
+
// handlers below, and the agent kept calling tools and the API (and spending money)
|
|
161064
|
+
// until it happened to finish — measured live: Esc at 12s left `sleep 30` running to
|
|
161065
|
+
// 30.0s and the turn still made its next request. Headless mode already passed it.
|
|
161066
|
+
abortSignal,
|
|
160734
161067
|
requestPermission,
|
|
160735
161068
|
checkpointManager,
|
|
160736
161069
|
onProgress,
|
|
@@ -160745,6 +161078,11 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
160745
161078
|
if (lastUsage) {
|
|
160746
161079
|
console.log(source_default.dim(" " + formatUsage(lastUsage.output_tokens)));
|
|
160747
161080
|
}
|
|
161081
|
+
turnStats.tokens = Math.max(0, sessionUsage.totalTokens - turnTokenStart);
|
|
161082
|
+
turnStats.cachedTokens = Math.max(0, sessionUsage.cacheRead - turnCachedStart);
|
|
161083
|
+
turnStats.costKnown = sessionUsage.costReported;
|
|
161084
|
+
turnStats.costUsd = Math.max(0, sessionUsage.cost - turnCostStart);
|
|
161085
|
+
printTurnSummary(abortSignal.aborted ? "interrupted" : "ok");
|
|
160748
161086
|
return { messages: result, usage: lastUsage };
|
|
160749
161087
|
}
|
|
160750
161088
|
function toolIds(isSubTask, meta) {
|
|
@@ -161243,7 +161581,8 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
161243
161581
|
};
|
|
161244
161582
|
const recoverTurn = (err, current) => {
|
|
161245
161583
|
const salvaged = (0, import_code_core8.salvageHistory)(err);
|
|
161246
|
-
|
|
161584
|
+
printErrorReport(err, abortSignal.aborted);
|
|
161585
|
+
printTurnSummary(abortSignal.aborted ? "interrupted" : "failed");
|
|
161247
161586
|
if (!salvaged)
|
|
161248
161587
|
return current;
|
|
161249
161588
|
const rounds = err.progressCount ?? 1;
|
|
@@ -161321,7 +161660,8 @@ ${text}` : "");
|
|
|
161321
161660
|
...salvaged ? { resumable: true, messagesCompleted: salvaged.length } : {}
|
|
161322
161661
|
}) + "\n");
|
|
161323
161662
|
} else {
|
|
161324
|
-
|
|
161663
|
+
for (const l2 of errorReportLines(err, abortSignal2.aborted))
|
|
161664
|
+
console.error(l2);
|
|
161325
161665
|
if (salvaged) {
|
|
161326
161666
|
console.error(source_default.dim(" Progress was saved \u2014 run `nex --resume` (or `nex -r`) to resume this session."));
|
|
161327
161667
|
}
|