nexrall-code 0.5.135 → 0.5.136
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 +160 -27
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -159144,19 +159144,26 @@ function decideChoiceKey(spec, sel, char, key, now, openedAt) {
|
|
|
159144
159144
|
const idx = spec.options.findIndex((o) => o.key.toLowerCase() === char.toLowerCase());
|
|
159145
159145
|
return idx >= 0 ? { kind: "pick", idx } : { kind: "none" };
|
|
159146
159146
|
}
|
|
159147
|
-
function choiceView(spec, sel) {
|
|
159147
|
+
function choiceView(spec, sel, maxRows) {
|
|
159148
159148
|
const n = spec.options.length;
|
|
159149
|
+
const size = maxRows && maxRows > 0 ? Math.min(maxRows, n) : n;
|
|
159150
|
+
const start = windowStart(Math.min(Math.max(sel, 0), Math.max(n - 1, 0)), n, size);
|
|
159151
|
+
const rows = spec.options.slice(start, start + size).map((o, k) => {
|
|
159152
|
+
const i2 = start + k;
|
|
159153
|
+
return { selected: i2 === sel, text: `${i2 === sel ? "\u203A" : " "} ${i2 + 1}. ${o.label}` };
|
|
159154
|
+
});
|
|
159155
|
+
const range = size < n ? `rows ${start + 1}-${start + size} of ${n} \xB7 ` : "";
|
|
159149
159156
|
return {
|
|
159150
159157
|
title: spec.title,
|
|
159151
159158
|
detail: spec.detail,
|
|
159152
159159
|
risk: spec.risk,
|
|
159153
|
-
rows
|
|
159154
|
-
|
|
159155
|
-
text: `${i2 === sel ? "\u203A" : " "} ${i2 + 1}. ${o.label}`
|
|
159156
|
-
})),
|
|
159157
|
-
hint: ` \u2191\u2193 select \xB7 1-${Math.min(n, 9)} pick \xB7 Enter confirm \xB7 Esc = no`
|
|
159160
|
+
rows,
|
|
159161
|
+
hint: ` \u2191\u2193 select \xB7 ${range}1-${Math.min(n, 9)} pick \xB7 Enter confirm \xB7 Esc = no`
|
|
159158
159162
|
};
|
|
159159
159163
|
}
|
|
159164
|
+
function choiceRowBudget(terminalRows, max = 12) {
|
|
159165
|
+
return Math.max(3, Math.min(max, terminalRows - 12));
|
|
159166
|
+
}
|
|
159160
159167
|
function denyIndex(spec) {
|
|
159161
159168
|
return spec.options.findIndex((o) => o.key.toLowerCase() === "n");
|
|
159162
159169
|
}
|
|
@@ -159359,6 +159366,14 @@ var App2 = ({ onReady }) => {
|
|
|
159359
159366
|
const onRewind = (0, import_react35.useCallback)((cb) => {
|
|
159360
159367
|
onRewindRef.current = cb;
|
|
159361
159368
|
}, []);
|
|
159369
|
+
const onModelRef = (0, import_react35.useRef)(null);
|
|
159370
|
+
const onModel = (0, import_react35.useCallback)((cb) => {
|
|
159371
|
+
onModelRef.current = cb;
|
|
159372
|
+
}, []);
|
|
159373
|
+
const onEffortRef = (0, import_react35.useRef)(null);
|
|
159374
|
+
const onEffort = (0, import_react35.useCallback)((cb) => {
|
|
159375
|
+
onEffortRef.current = cb;
|
|
159376
|
+
}, []);
|
|
159362
159377
|
const onHelpRef = (0, import_react35.useRef)(null);
|
|
159363
159378
|
const onHelp = (0, import_react35.useCallback)((cb) => {
|
|
159364
159379
|
onHelpRef.current = cb;
|
|
@@ -159759,6 +159774,17 @@ var App2 = ({ onReady }) => {
|
|
|
159759
159774
|
});
|
|
159760
159775
|
return;
|
|
159761
159776
|
}
|
|
159777
|
+
if (key.meta && (char === "m" || char === "M" || char === "t" || char === "T")) {
|
|
159778
|
+
if (askResolverRef.current)
|
|
159779
|
+
return;
|
|
159780
|
+
const which = char.toLowerCase() === "m" ? "model" : "effort";
|
|
159781
|
+
if (busyRef.current) {
|
|
159782
|
+
setHintText(`The ${which} can be changed when this turn finishes`);
|
|
159783
|
+
return;
|
|
159784
|
+
}
|
|
159785
|
+
(which === "model" ? onModelRef.current : onEffortRef.current)?.();
|
|
159786
|
+
return;
|
|
159787
|
+
}
|
|
159762
159788
|
if (key.ctrl && char === "l") {
|
|
159763
159789
|
forceFullRedrawRef?.();
|
|
159764
159790
|
return;
|
|
@@ -159974,7 +160000,9 @@ var App2 = ({ onReady }) => {
|
|
|
159974
160000
|
onExpand,
|
|
159975
160001
|
onBackground,
|
|
159976
160002
|
onJump,
|
|
159977
|
-
onEscape
|
|
160003
|
+
onEscape,
|
|
160004
|
+
onModel,
|
|
160005
|
+
onEffort
|
|
159978
160006
|
});
|
|
159979
160007
|
}, []);
|
|
159980
160008
|
const slices = renderInputSlices(line, cursorPos);
|
|
@@ -160042,7 +160070,7 @@ var App2 = ({ onReady }) => {
|
|
|
160042
160070
|
menuReserveRef.current,
|
|
160043
160071
|
slashMenu ? slashMenu.rows.length + 1 : mentionMenu ? mentionMenu.rows.length + 1 : 0
|
|
160044
160072
|
);
|
|
160045
|
-
const choiceVm = choiceRef.current ? choiceView(choiceRef.current.spec, choiceRef.current.sel) : null;
|
|
160073
|
+
const choiceVm = choiceRef.current ? choiceView(choiceRef.current.spec, choiceRef.current.sel, choiceRowBudget(process.stdout.rows ?? 24)) : null;
|
|
160046
160074
|
const riskColor = choiceVm?.risk === "high" ? "red" : choiceVm?.risk === "medium" ? "yellow" : "green";
|
|
160047
160075
|
return /* @__PURE__ */ import_react35.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react35.default.createElement(Static, { items, key: staticKey }, (item) => /* @__PURE__ */ import_react35.default.createElement(Text, { key: item.id }, item.content)), live ? /* @__PURE__ */ import_react35.default.createElement(Text, null, live) : null, choiceVm ? /* @__PURE__ */ import_react35.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react35.default.createElement(Text, { bold: true, wrap: "truncate-end" }, choiceVm.title), choiceVm.detail ? /* @__PURE__ */ import_react35.default.createElement(Text, { wrap: "truncate-end", color: choiceVm.risk ? riskColor : void 0, dimColor: !choiceVm.risk }, choiceVm.risk ? `${choiceVm.risk.toUpperCase()} RISK \xB7 ` : "", choiceVm.detail) : null, choiceVm.rows.map((r2) => /* @__PURE__ */ import_react35.default.createElement(Text, { key: r2.text, wrap: "truncate-end", inverse: r2.selected }, r2.text)), /* @__PURE__ */ import_react35.default.createElement(Text, { dimColor: true, wrap: "truncate-end" }, choiceVm.hint)) : null, searchVm ? /* @__PURE__ */ import_react35.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react35.default.createElement(Text, { color: searchVm.failed ? "red" : "cyan", wrap: "truncate-end" }, " " + searchVm.label), /* @__PURE__ */ import_react35.default.createElement(Text, { dimColor: true, wrap: "truncate-end" }, SEARCH_HINT)) : null, menuReserveRef.current > 0 ? /* @__PURE__ */ import_react35.default.createElement(Box_default, { flexDirection: "column", justifyContent: "flex-end", minHeight: menuReserveRef.current }, mentionMenu ? /* @__PURE__ */ import_react35.default.createElement(Box_default, { flexDirection: "column" }, mentionMenu.rows.map((r2) => /* @__PURE__ */ import_react35.default.createElement(Text, { key: r2.key, wrap: "truncate-end", inverse: r2.selected }, r2.text)), /* @__PURE__ */ import_react35.default.createElement(Text, { dimColor: true, wrap: "truncate-end" }, mentionMenu.hint)) : null, slashMenu ? /* @__PURE__ */ import_react35.default.createElement(Box_default, { flexDirection: "column" }, slashMenu.rows.map((r2) => /* @__PURE__ */ import_react35.default.createElement(Text, { key: r2.key, wrap: "truncate-end", inverse: r2.selected }, r2.text)), /* @__PURE__ */ import_react35.default.createElement(Text, { dimColor: true, wrap: "truncate-end" }, slashMenu.hint)) : null) : null, /* @__PURE__ */ import_react35.default.createElement(
|
|
160048
160076
|
Box_default,
|
|
@@ -160262,6 +160290,52 @@ function rewindChoices(cps) {
|
|
|
160262
160290
|
return { options, ids: newest.map((c) => c.id) };
|
|
160263
160291
|
}
|
|
160264
160292
|
|
|
160293
|
+
// src/ui/pickList.ts
|
|
160294
|
+
var PICK_LABEL_MAX = 34;
|
|
160295
|
+
var PICK_NOTE_MAX = 30;
|
|
160296
|
+
var CURRENT_MARK = "current";
|
|
160297
|
+
function buildPickList(o) {
|
|
160298
|
+
if (!o.items.length)
|
|
160299
|
+
return null;
|
|
160300
|
+
const labelMax = o.labelMax ?? PICK_LABEL_MAX;
|
|
160301
|
+
const values = [];
|
|
160302
|
+
const options = o.items.map((it, i2) => {
|
|
160303
|
+
values.push(it.value);
|
|
160304
|
+
const parts = [clip4(it.label, labelMax)];
|
|
160305
|
+
if (it.note)
|
|
160306
|
+
parts.push(clip4(it.note, PICK_NOTE_MAX));
|
|
160307
|
+
if (o.current !== void 0 && it.value === o.current)
|
|
160308
|
+
parts.push(CURRENT_MARK);
|
|
160309
|
+
return { key: String(i2 + 1), label: parts.join(" ") };
|
|
160310
|
+
});
|
|
160311
|
+
options.push({ key: "n", label: o.cancelLabel ?? "Cancel" });
|
|
160312
|
+
const currentIndex = o.current ? values.indexOf(o.current) : -1;
|
|
160313
|
+
return {
|
|
160314
|
+
spec: {
|
|
160315
|
+
title: o.title,
|
|
160316
|
+
detail: o.detail,
|
|
160317
|
+
risk: o.risk ?? "low",
|
|
160318
|
+
options,
|
|
160319
|
+
defaultIndex: currentIndex >= 0 ? currentIndex : 0
|
|
160320
|
+
},
|
|
160321
|
+
values,
|
|
160322
|
+
currentIndex
|
|
160323
|
+
};
|
|
160324
|
+
}
|
|
160325
|
+
function pickOutcome(list, index) {
|
|
160326
|
+
const value = list.values[index];
|
|
160327
|
+
return value === void 0 ? { kind: "cancel" } : { kind: "pick", value };
|
|
160328
|
+
}
|
|
160329
|
+
function currentNotOfferedLine(label) {
|
|
160330
|
+
return `Current: ${label} \u2014 not in the list below, so no row is marked.`;
|
|
160331
|
+
}
|
|
160332
|
+
|
|
160333
|
+
// src/modelSwitch.ts
|
|
160334
|
+
function planModelSwitch(next, effort, clamp) {
|
|
160335
|
+
const clamped = clamp(effort, next);
|
|
160336
|
+
return { model: next, effort: clamped, effortChanged: clamped !== effort };
|
|
160337
|
+
}
|
|
160338
|
+
|
|
160265
160339
|
// src/ui/backgroundShells.ts
|
|
160266
160340
|
var MAX_KEPT = 64e3;
|
|
160267
160341
|
var BackgroundShells = class {
|
|
@@ -160491,10 +160565,6 @@ var MODEL_COST_MULTIPLIER = {
|
|
|
160491
160565
|
// 130_glm_5_3_pricing.sql's own caveat if Z.ai ships a GLM-5.3-specific rate.
|
|
160492
160566
|
"glm-5.3": 0.6
|
|
160493
160567
|
};
|
|
160494
|
-
function modelWithCostHint(id) {
|
|
160495
|
-
const mult = (0, import_code_core9.liveCostMultiplierFor)(id, MODEL_COST_MULTIPLIER[id]);
|
|
160496
|
-
return mult === void 0 ? id : `${id} (${mult}x)`;
|
|
160497
|
-
}
|
|
160498
160568
|
var NO_VISION_MODELS = /* @__PURE__ */ new Set(["qwen3.7-max", "glm-5.3"]);
|
|
160499
160569
|
var NO_PDF_MODELS = /* @__PURE__ */ new Set([
|
|
160500
160570
|
"gpt-5.6-sol",
|
|
@@ -161539,9 +161609,9 @@ function printHelp() {
|
|
|
161539
161609
|
["/worktree [list]", "Show this session's worktree isolation status, or list every worktree (start one with `nex --worktree [name]`)"],
|
|
161540
161610
|
["/peers [send <name> <msg>|broadcast <msg>]", "List other discoverable Nexrall Code sessions, message one directly, or broadcast to all"],
|
|
161541
161611
|
["/help", "Show this help"],
|
|
161542
|
-
["/model [name]", "
|
|
161612
|
+
["/model [name]", "Pick a model from a list (or name one: /model claude-opus-5-5)"],
|
|
161543
161613
|
["/mode [ask|edit|plan|auto]", "Set agent mode"],
|
|
161544
|
-
["/effort [level]", "
|
|
161614
|
+
["/effort [level]", "Pick a thinking effort level (the scale is the current model's own \u2014 /effort opens a list)"],
|
|
161545
161615
|
["/yolo", "Auto-approve all permissions"],
|
|
161546
161616
|
["/balance", "Show what is paying (personal wallet or team) and what is left"],
|
|
161547
161617
|
["/team [use <id|personal>]", "List your teams, or switch what usage is billed to"],
|
|
@@ -161590,6 +161660,7 @@ function printHelp() {
|
|
|
161590
161660
|
["Ctrl+W / Alt+\u232B", "Delete the previous word"],
|
|
161591
161661
|
["Ctrl+U / Ctrl+K", "Delete to the start / end of the line (Ctrl+Y pastes it back)"],
|
|
161592
161662
|
["Shift+Tab", "Cycle the mode: ask \u2192 edit \u2192 auto \u2192 plan (when no turn is running)"],
|
|
161663
|
+
["Alt+M / Alt+T", "Pick the model / the thinking effort without typing a command"],
|
|
161593
161664
|
["Ctrl+R", "Search your prompt history: type to filter, Ctrl+R older, Enter use it, Esc cancel"],
|
|
161594
161665
|
["Ctrl+G", "Edit the draft in $VISUAL / $EDITOR"],
|
|
161595
161666
|
["Esc Esc", "At an empty prompt: pick a checkpoint to rewind to (same as /rewind)"],
|
|
@@ -162037,10 +162108,81 @@ ${text}` : "");
|
|
|
162037
162108
|
}
|
|
162038
162109
|
}
|
|
162039
162110
|
};
|
|
162111
|
+
const applyModel = (id) => {
|
|
162112
|
+
const plan = planModelSwitch(id, effortLevel, clampEffortForModel);
|
|
162113
|
+
modelAlias = plan.model;
|
|
162114
|
+
effortLevel = plan.effort;
|
|
162115
|
+
updateFooter();
|
|
162116
|
+
console.log(source_default.green(` Model \u2192 ${source_default.bold(resolveModelLabel(modelAlias))}`));
|
|
162117
|
+
if (plan.effortChanged)
|
|
162118
|
+
console.log(source_default.dim(` Effort reset \u2192 ${effortLevel} (previous level not available on this model)`));
|
|
162119
|
+
};
|
|
162120
|
+
const applyEffort = (level) => {
|
|
162121
|
+
effortLevel = level;
|
|
162122
|
+
console.log(source_default.green(` Effort \u2192 ${source_default.bold(level)}`));
|
|
162123
|
+
};
|
|
162124
|
+
const modelPickerNote = (id) => {
|
|
162125
|
+
const parts = [];
|
|
162126
|
+
const mult = (0, import_code_core9.liveCostMultiplierFor)(id, MODEL_COST_MULTIPLIER[id]);
|
|
162127
|
+
if (mult !== void 0 && mult !== 1)
|
|
162128
|
+
parts.push(`${mult}x`);
|
|
162129
|
+
if (needsVisionSidecar(id))
|
|
162130
|
+
parts.push("images via Sonnet");
|
|
162131
|
+
if (needsPdfSidecar(id))
|
|
162132
|
+
parts.push("no PDFs");
|
|
162133
|
+
return parts.length ? parts.join(" \xB7 ") : void 0;
|
|
162134
|
+
};
|
|
162135
|
+
const openModelPicker = async () => {
|
|
162136
|
+
if (!(rl instanceof InkReadlineAdapter))
|
|
162137
|
+
return;
|
|
162138
|
+
const list = buildPickList({
|
|
162139
|
+
title: "Switch model",
|
|
162140
|
+
detail: "Takes effect on the next turn \u2014 the conversation and your files are untouched",
|
|
162141
|
+
items: selectableModelIds().map((id) => ({ value: id, label: resolveModelLabel(id), note: modelPickerNote(id) })),
|
|
162142
|
+
current: modelAlias
|
|
162143
|
+
});
|
|
162144
|
+
if (!list) {
|
|
162145
|
+
console.log(source_default.red(" No model list available (offline and no cached catalogue)."));
|
|
162146
|
+
return;
|
|
162147
|
+
}
|
|
162148
|
+
if (list.currentIndex < 0)
|
|
162149
|
+
console.log(source_default.dim(" " + currentNotOfferedLine(resolveModelLabel(modelAlias))));
|
|
162150
|
+
const out = pickOutcome(list, await rl.askChoice(list.spec));
|
|
162151
|
+
if (out.kind === "cancel")
|
|
162152
|
+
return;
|
|
162153
|
+
applyModel(out.value);
|
|
162154
|
+
};
|
|
162155
|
+
const openEffortPicker = async () => {
|
|
162156
|
+
if (!(rl instanceof InkReadlineAdapter))
|
|
162157
|
+
return;
|
|
162158
|
+
const config = effortConfigFor(modelAlias);
|
|
162159
|
+
if (config.levels.length < 2) {
|
|
162160
|
+
console.log(source_default.dim(` ${resolveModelLabel(modelAlias)} has one thinking setting (${config.levels[0] ?? "\u2014"} \xB7 ${config.names[0] ?? "not configurable"}); there is nothing to pick.`));
|
|
162161
|
+
return;
|
|
162162
|
+
}
|
|
162163
|
+
const list = buildPickList({
|
|
162164
|
+
title: `Thinking effort \u2014 ${resolveModelLabel(modelAlias)}`,
|
|
162165
|
+
detail: "Higher levels think longer before answering; the scale belongs to this model",
|
|
162166
|
+
items: config.levels.map((v, i2) => ({ value: v, label: v, note: config.names[i2] })),
|
|
162167
|
+
current: effortLevel
|
|
162168
|
+
});
|
|
162169
|
+
if (!list)
|
|
162170
|
+
return;
|
|
162171
|
+
const out = pickOutcome(list, await rl.askChoice(list.spec));
|
|
162172
|
+
if (out.kind === "cancel")
|
|
162173
|
+
return;
|
|
162174
|
+
applyEffort(out.value);
|
|
162175
|
+
};
|
|
162040
162176
|
if (interactive) {
|
|
162041
162177
|
getInkTerminal().onHelp(() => {
|
|
162042
162178
|
printHelp();
|
|
162043
162179
|
});
|
|
162180
|
+
getInkTerminal().onModel(() => {
|
|
162181
|
+
void openModelPicker();
|
|
162182
|
+
});
|
|
162183
|
+
getInkTerminal().onEffort(() => {
|
|
162184
|
+
void openEffortPicker();
|
|
162185
|
+
});
|
|
162044
162186
|
getInkTerminal().onJump((delta) => {
|
|
162045
162187
|
jumpTranscript(messages, delta);
|
|
162046
162188
|
updateFooter();
|
|
@@ -162477,17 +162619,9 @@ ${dirList}`;
|
|
|
162477
162619
|
const requested = arg.trim();
|
|
162478
162620
|
const models = selectableModelIds();
|
|
162479
162621
|
if (!requested) {
|
|
162480
|
-
|
|
162481
|
-
console.log(source_default.dim(` Options: ${models.map(modelWithCostHint).join(" \xB7 ")}`));
|
|
162622
|
+
await openModelPicker();
|
|
162482
162623
|
} else if (models.includes(normaliseModelId(requested))) {
|
|
162483
|
-
|
|
162484
|
-
const clamped = clampEffortForModel(effortLevel, modelAlias);
|
|
162485
|
-
const effortChanged = clamped !== effortLevel;
|
|
162486
|
-
effortLevel = clamped;
|
|
162487
|
-
console.log(source_default.green(` Model \u2192 ${source_default.bold(resolveModelLabel(modelAlias))}`));
|
|
162488
|
-
if (effortChanged) {
|
|
162489
|
-
console.log(source_default.dim(` Effort reset \u2192 ${effortLevel} (previous level not available on this model)`));
|
|
162490
|
-
}
|
|
162624
|
+
applyModel(normaliseModelId(requested));
|
|
162491
162625
|
} else {
|
|
162492
162626
|
console.log(source_default.red(` Unknown: ${requested}. Options: ${models.join(", ")}`));
|
|
162493
162627
|
}
|
|
@@ -162521,10 +162655,9 @@ ${dirList}`;
|
|
|
162521
162655
|
const config = effortConfigFor(modelAlias);
|
|
162522
162656
|
const optionsLine = config.levels.map((v, i2) => `${v} (${config.names[i2]})`).join(" \xB7 ");
|
|
162523
162657
|
if (!effortArg) {
|
|
162524
|
-
|
|
162658
|
+
await openEffortPicker();
|
|
162525
162659
|
} else if (config.levels.includes(effortArg)) {
|
|
162526
|
-
|
|
162527
|
-
console.log(source_default.green(` Effort \u2192 ${source_default.bold(effortArg)}`));
|
|
162660
|
+
applyEffort(effortArg);
|
|
162528
162661
|
} else {
|
|
162529
162662
|
console.log(source_default.red(` Unknown: ${effortArg}. Options: ${optionsLine}`));
|
|
162530
162663
|
}
|