nexrall-code 0.5.77 → 0.5.78
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 +110 -25
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -55817,7 +55817,18 @@ function prepareSessionScreen() {
|
|
|
55817
55817
|
return;
|
|
55818
55818
|
process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
55819
55819
|
}
|
|
55820
|
-
|
|
55820
|
+
function bottomChromeRows(opts = {
|
|
55821
|
+
footerText: ""
|
|
55822
|
+
}) {
|
|
55823
|
+
const columns = opts.columns ?? process.stdout.columns ?? 80;
|
|
55824
|
+
const separatorRows = 1;
|
|
55825
|
+
const inputRows = rowsOccupied(
|
|
55826
|
+
" ".repeat(opts.promptWidth ?? 2) + (opts.inputText ?? ""),
|
|
55827
|
+
columns
|
|
55828
|
+
);
|
|
55829
|
+
const footerRows = rowsOccupied(opts.footerText, columns);
|
|
55830
|
+
return separatorRows + inputRows + footerRows;
|
|
55831
|
+
}
|
|
55821
55832
|
function rowsOccupied(text, columns = process.stdout.columns || 80) {
|
|
55822
55833
|
let rows = 0;
|
|
55823
55834
|
for (const line of text.split("\n")) {
|
|
@@ -55826,11 +55837,12 @@ function rowsOccupied(text, columns = process.stdout.columns || 80) {
|
|
|
55826
55837
|
}
|
|
55827
55838
|
return rows;
|
|
55828
55839
|
}
|
|
55829
|
-
function padToBottom(rowsAlreadyPrinted) {
|
|
55840
|
+
function padToBottom(rowsAlreadyPrinted, footerText2 = "") {
|
|
55830
55841
|
const rows = process.stdout.rows;
|
|
55831
55842
|
if (!process.stdout.isTTY || !rows)
|
|
55832
55843
|
return;
|
|
55833
|
-
const
|
|
55844
|
+
const chromeRows = bottomChromeRows({ footerText: footerText2, columns: process.stdout.columns ?? 80 });
|
|
55845
|
+
const filler = rows - rowsAlreadyPrinted - chromeRows - 2;
|
|
55834
55846
|
const MIN_WORTHWHILE_FILLER = 3;
|
|
55835
55847
|
if (filler < MIN_WORTHWHILE_FILLER)
|
|
55836
55848
|
return;
|
|
@@ -55841,19 +55853,26 @@ function startRowCount() {
|
|
|
55841
55853
|
if (rowCounter)
|
|
55842
55854
|
return;
|
|
55843
55855
|
const columns = process.stdout.columns || 80;
|
|
55844
|
-
const
|
|
55845
|
-
const
|
|
55856
|
+
const originalLog = console.log;
|
|
55857
|
+
const originalError = console.error;
|
|
55858
|
+
const state = { rows: 0, originalLog, originalError };
|
|
55846
55859
|
rowCounter = state;
|
|
55860
|
+
const measure = (args) => args.length === 0 ? 1 : rowsOccupied(args.map(String).join(" "), columns);
|
|
55847
55861
|
console.log = (...args) => {
|
|
55848
|
-
state.rows +=
|
|
55849
|
-
|
|
55862
|
+
state.rows += measure(args);
|
|
55863
|
+
originalLog(...args);
|
|
55864
|
+
};
|
|
55865
|
+
console.error = (...args) => {
|
|
55866
|
+
state.rows += measure(args);
|
|
55867
|
+
originalError(...args);
|
|
55850
55868
|
};
|
|
55851
55869
|
}
|
|
55852
55870
|
function stopRowCount() {
|
|
55853
55871
|
if (!rowCounter)
|
|
55854
55872
|
return 0;
|
|
55855
|
-
const { rows,
|
|
55856
|
-
console.log =
|
|
55873
|
+
const { rows, originalLog, originalError } = rowCounter;
|
|
55874
|
+
console.log = originalLog;
|
|
55875
|
+
console.error = originalError;
|
|
55857
55876
|
rowCounter = null;
|
|
55858
55877
|
return rows;
|
|
55859
55878
|
}
|
|
@@ -64873,6 +64892,26 @@ function nextGraphemeBoundary(text, pos) {
|
|
|
64873
64892
|
}
|
|
64874
64893
|
return text.length;
|
|
64875
64894
|
}
|
|
64895
|
+
function renderInputSlices(line, cursorPos) {
|
|
64896
|
+
const end = nextGraphemeBoundary(line, cursorPos);
|
|
64897
|
+
return {
|
|
64898
|
+
before: line.slice(0, cursorPos),
|
|
64899
|
+
atCursor: line.slice(cursorPos, end) || " ",
|
|
64900
|
+
after: line.slice(end)
|
|
64901
|
+
};
|
|
64902
|
+
}
|
|
64903
|
+
var CTRL_C_QUIT_WINDOW_MS = 3e3;
|
|
64904
|
+
var CTRL_C_HINT = "Press Ctrl+C again to exit";
|
|
64905
|
+
function decideCtrlC(state) {
|
|
64906
|
+
if (state.hasPendingQuestion)
|
|
64907
|
+
return "answer-prompt";
|
|
64908
|
+
if (state.busy)
|
|
64909
|
+
return "interrupt-turn";
|
|
64910
|
+
if (state.quitArmedAt !== null && state.now - state.quitArmedAt <= CTRL_C_QUIT_WINDOW_MS) {
|
|
64911
|
+
return "quit";
|
|
64912
|
+
}
|
|
64913
|
+
return "arm-quit";
|
|
64914
|
+
}
|
|
64876
64915
|
var handle = null;
|
|
64877
64916
|
var inkInstance = null;
|
|
64878
64917
|
var idCounter = 0;
|
|
@@ -64902,6 +64941,12 @@ var App2 = ({ onReady }) => {
|
|
|
64902
64941
|
const onLineRef = (0, import_react35.useRef)(null);
|
|
64903
64942
|
const onQueuedLineRef = (0, import_react35.useRef)(null);
|
|
64904
64943
|
const busyRef = (0, import_react35.useRef)(false);
|
|
64944
|
+
const [quitArmed, setQuitArmedState] = (0, import_react35.useState)(null);
|
|
64945
|
+
const quitArmedAtRef = (0, import_react35.useRef)(null);
|
|
64946
|
+
const setQuitArmed = (0, import_react35.useCallback)((at) => {
|
|
64947
|
+
quitArmedAtRef.current = at;
|
|
64948
|
+
setQuitArmedState(at);
|
|
64949
|
+
}, []);
|
|
64905
64950
|
const [live, setLiveState] = (0, import_react35.useState)("");
|
|
64906
64951
|
const print = (0, import_react35.useCallback)((text) => {
|
|
64907
64952
|
setItems((prev) => [...prev, { id: idCounter++, content: text }]);
|
|
@@ -64933,23 +64978,49 @@ var App2 = ({ onReady }) => {
|
|
|
64933
64978
|
const onInterrupt = (0, import_react35.useCallback)((cb) => {
|
|
64934
64979
|
onInterruptRef.current = cb;
|
|
64935
64980
|
}, []);
|
|
64981
|
+
const onExitRef = (0, import_react35.useRef)(null);
|
|
64982
|
+
const onExit = (0, import_react35.useCallback)((cb) => {
|
|
64983
|
+
onExitRef.current = cb;
|
|
64984
|
+
}, []);
|
|
64985
|
+
const exitedRef = (0, import_react35.useRef)(false);
|
|
64986
|
+
const requestExit = (0, import_react35.useCallback)((notify) => {
|
|
64987
|
+
if (exitedRef.current)
|
|
64988
|
+
return;
|
|
64989
|
+
exitedRef.current = true;
|
|
64990
|
+
if (notify)
|
|
64991
|
+
onExitRef.current?.();
|
|
64992
|
+
exit();
|
|
64993
|
+
}, []);
|
|
64936
64994
|
use_input_default((char, key) => {
|
|
64937
64995
|
if (key.ctrl && char === "c") {
|
|
64938
|
-
const
|
|
64939
|
-
|
|
64996
|
+
const action = decideCtrlC({
|
|
64997
|
+
hasPendingQuestion: askResolverRef.current !== null,
|
|
64998
|
+
busy: busyRef.current && onInterruptRef.current !== null,
|
|
64999
|
+
quitArmedAt: quitArmedAtRef.current,
|
|
65000
|
+
now: Date.now()
|
|
65001
|
+
});
|
|
65002
|
+
if (action === "answer-prompt") {
|
|
65003
|
+
const askResolve = askResolverRef.current;
|
|
64940
65004
|
askResolverRef.current = null;
|
|
64941
65005
|
setLine("");
|
|
64942
65006
|
setCursorPos(0);
|
|
64943
65007
|
askResolve("n");
|
|
64944
65008
|
return;
|
|
64945
65009
|
}
|
|
64946
|
-
if (
|
|
64947
|
-
|
|
65010
|
+
if (action === "interrupt-turn") {
|
|
65011
|
+
setQuitArmed(null);
|
|
65012
|
+
onInterruptRef.current?.();
|
|
64948
65013
|
return;
|
|
64949
65014
|
}
|
|
64950
|
-
|
|
65015
|
+
if (action === "arm-quit") {
|
|
65016
|
+
setQuitArmed(Date.now());
|
|
65017
|
+
return;
|
|
65018
|
+
}
|
|
65019
|
+
requestExit(true);
|
|
64951
65020
|
return;
|
|
64952
65021
|
}
|
|
65022
|
+
if (quitArmedAtRef.current !== null)
|
|
65023
|
+
setQuitArmed(null);
|
|
64953
65024
|
if (key.backspace || key.delete) {
|
|
64954
65025
|
if (key.delete) {
|
|
64955
65026
|
setLine((s2) => {
|
|
@@ -65022,11 +65093,13 @@ var App2 = ({ onReady }) => {
|
|
|
65022
65093
|
onLine,
|
|
65023
65094
|
onQueuedLine,
|
|
65024
65095
|
onInterrupt,
|
|
65096
|
+
onExit,
|
|
65025
65097
|
setBusy,
|
|
65026
|
-
close: () =>
|
|
65098
|
+
close: () => requestExit(false)
|
|
65027
65099
|
});
|
|
65028
65100
|
}, []);
|
|
65029
|
-
|
|
65101
|
+
const slices = renderInputSlices(line, cursorPos);
|
|
65102
|
+
return /* @__PURE__ */ import_react35.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react35.default.createElement(Static, { items }, (item) => /* @__PURE__ */ import_react35.default.createElement(Text, { key: item.id }, item.content)), live ? /* @__PURE__ */ import_react35.default.createElement(Text, null, live) : null, /* @__PURE__ */ import_react35.default.createElement(Text, { dimColor: true }, "\u2500".repeat(Math.max(1, columns - 1))), /* @__PURE__ */ import_react35.default.createElement(Box_default, null, /* @__PURE__ */ import_react35.default.createElement(Text, null, prompt2), /* @__PURE__ */ import_react35.default.createElement(Text, null, slices.before), /* @__PURE__ */ import_react35.default.createElement(Text, { inverse: true }, slices.atCursor), /* @__PURE__ */ import_react35.default.createElement(Text, null, slices.after)), quitArmed !== null ? /* @__PURE__ */ import_react35.default.createElement(Text, { color: "yellow" }, CTRL_C_HINT) : /* @__PURE__ */ import_react35.default.createElement(Text, { dimColor: true }, footerText(footer), busy ? " \xB7 agent working\u2026" : ""));
|
|
65030
65103
|
};
|
|
65031
65104
|
function startInkTerminal() {
|
|
65032
65105
|
if (handle)
|
|
@@ -65110,6 +65183,9 @@ var InkReadlineAdapter = class extends EventEmitter3 {
|
|
|
65110
65183
|
this.ink.onInterrupt(() => {
|
|
65111
65184
|
this.emit("interrupt");
|
|
65112
65185
|
});
|
|
65186
|
+
this.ink.onExit(() => {
|
|
65187
|
+
this.emit("close");
|
|
65188
|
+
});
|
|
65113
65189
|
}
|
|
65114
65190
|
prompt(_preserveCursor) {
|
|
65115
65191
|
}
|
|
@@ -65868,15 +65944,20 @@ Set ${TRUST_ENV_VAR}=1 to confirm non-interactively, or run \`nex\` interactivel
|
|
|
65868
65944
|
let skills = (0, import_code_core3.loadSkills)(workDir);
|
|
65869
65945
|
if (skills.length && !headless)
|
|
65870
65946
|
console.log(source_default.dim(` ${skills.length} skill(s) loaded`));
|
|
65871
|
-
|
|
65872
|
-
|
|
65873
|
-
|
|
65874
|
-
|
|
65875
|
-
|
|
65876
|
-
|
|
65947
|
+
const mcpStarted = (async () => {
|
|
65948
|
+
try {
|
|
65949
|
+
await initMcp(workDir);
|
|
65950
|
+
const connected = _mcpManager?.serverNames.length ?? 0;
|
|
65951
|
+
const total = _mcpConfig ? Object.keys(_mcpConfig.mcpServers).length : 0;
|
|
65952
|
+
if (total && !headless) {
|
|
65953
|
+
console.log(source_default.dim(` ${connected}/${total} MCP server(s) connected`) + source_default.dim(" (/mcp for details)"));
|
|
65954
|
+
}
|
|
65955
|
+
} catch {
|
|
65877
65956
|
}
|
|
65878
|
-
}
|
|
65879
|
-
|
|
65957
|
+
})();
|
|
65958
|
+
const mcpReady = () => mcpStarted;
|
|
65959
|
+
if (!interactive)
|
|
65960
|
+
await mcpStarted;
|
|
65880
65961
|
if (headless && !options.prompt && !options.stdinText) {
|
|
65881
65962
|
process.stdout.write(JSON.stringify({ type: "error", error: "--output-format json/stream-json requires a one-shot prompt (or piped stdin)." }) + "\n");
|
|
65882
65963
|
process.exit(1);
|
|
@@ -65999,7 +66080,7 @@ ${text}` : "");
|
|
|
65999
66080
|
console.log();
|
|
66000
66081
|
if (interactive) {
|
|
66001
66082
|
await flushInkFrame();
|
|
66002
|
-
padToBottom(stopRowCount());
|
|
66083
|
+
padToBottom(stopRowCount(), footerText({ mode: agentMode, autoApprove: isYoloMode() }));
|
|
66003
66084
|
}
|
|
66004
66085
|
let agentRunning = false;
|
|
66005
66086
|
const abortSignal = { aborted: false };
|
|
@@ -66469,6 +66550,7 @@ ${text}
|
|
|
66469
66550
|
rl.pause();
|
|
66470
66551
|
abortSignal.aborted = false;
|
|
66471
66552
|
agentRunning = true;
|
|
66553
|
+
await mcpReady();
|
|
66472
66554
|
try {
|
|
66473
66555
|
const result = await runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrallMd, agentMode, effortLevel, checkpoints, saveProgress, takePendingInput);
|
|
66474
66556
|
messages = result.messages;
|
|
@@ -66510,6 +66592,7 @@ ${text}
|
|
|
66510
66592
|
return;
|
|
66511
66593
|
}
|
|
66512
66594
|
case "/mcp": {
|
|
66595
|
+
await mcpReady();
|
|
66513
66596
|
console.log();
|
|
66514
66597
|
console.log(source_default.bold(" MCP servers:"));
|
|
66515
66598
|
console.log(formatMcpStatus());
|
|
@@ -66589,6 +66672,7 @@ ${text}
|
|
|
66589
66672
|
rl.pause();
|
|
66590
66673
|
abortSignal.aborted = false;
|
|
66591
66674
|
agentRunning = true;
|
|
66675
|
+
await mcpReady();
|
|
66592
66676
|
try {
|
|
66593
66677
|
const result = await runTurn(messages, turnModel, workDir, abortSignal, env3, nexrallMd, turnMode, effortLevel, checkpoints, saveProgress, takePendingInput);
|
|
66594
66678
|
messages = result.messages;
|
|
@@ -66613,6 +66697,7 @@ ${text}
|
|
|
66613
66697
|
rl.pause();
|
|
66614
66698
|
abortSignal.aborted = false;
|
|
66615
66699
|
agentRunning = true;
|
|
66700
|
+
await mcpReady();
|
|
66616
66701
|
try {
|
|
66617
66702
|
const result = await runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrallMd, agentMode, effortLevel, checkpoints, saveProgress, takePendingInput);
|
|
66618
66703
|
messages = result.messages;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexrall-code",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.78",
|
|
4
4
|
"description": "Nexrall Code — AI coding assistant for your terminal (headless agent for scripts, CI and automation)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"release": "node build.js && node scripts/upload-release.cjs"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@nexrall/code-core": "^1.4.
|
|
44
|
+
"@nexrall/code-core": "^1.4.46",
|
|
45
45
|
"chalk": "^5.3.0",
|
|
46
46
|
"commander": "^12.0.0",
|
|
47
47
|
"diff": "^5.2.0",
|