nexrall-code 0.5.74 → 0.5.75
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 +181 -39
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -64732,23 +64732,50 @@ function footerText(info) {
|
|
|
64732
64732
|
}
|
|
64733
64733
|
var IntlWithSegmenter = Intl;
|
|
64734
64734
|
var graphemeSegmenter = typeof IntlWithSegmenter.Segmenter === "function" ? new IntlWithSegmenter.Segmenter(void 0, { granularity: "grapheme" }) : null;
|
|
64735
|
-
function
|
|
64736
|
-
if (!text)
|
|
64737
|
-
return "";
|
|
64735
|
+
function graphemeBoundaries(text) {
|
|
64738
64736
|
if (graphemeSegmenter) {
|
|
64739
|
-
|
|
64740
|
-
for (const { index } of graphemeSegmenter.segment(text))
|
|
64741
|
-
|
|
64742
|
-
|
|
64743
|
-
|
|
64744
|
-
|
|
64745
|
-
|
|
64746
|
-
|
|
64747
|
-
const
|
|
64748
|
-
|
|
64749
|
-
|
|
64750
|
-
|
|
64751
|
-
|
|
64737
|
+
const bounds2 = [0];
|
|
64738
|
+
for (const { index } of graphemeSegmenter.segment(text)) {
|
|
64739
|
+
if (index > 0)
|
|
64740
|
+
bounds2.push(index);
|
|
64741
|
+
}
|
|
64742
|
+
bounds2.push(text.length);
|
|
64743
|
+
return bounds2;
|
|
64744
|
+
}
|
|
64745
|
+
const bounds = [0];
|
|
64746
|
+
let i2 = 0;
|
|
64747
|
+
while (i2 < text.length) {
|
|
64748
|
+
let next = i2 + 1;
|
|
64749
|
+
const code = text.charCodeAt(i2);
|
|
64750
|
+
if (code >= 55296 && code <= 56319 && next < text.length) {
|
|
64751
|
+
const low = text.charCodeAt(next);
|
|
64752
|
+
if (low >= 56320 && low <= 57343)
|
|
64753
|
+
next++;
|
|
64754
|
+
}
|
|
64755
|
+
while (next < text.length && /[\u0300-\u036F\u1AB0-\u1AFF\u20D0-\u20F0]/.test(text[next]))
|
|
64756
|
+
next++;
|
|
64757
|
+
bounds.push(next);
|
|
64758
|
+
i2 = next;
|
|
64759
|
+
}
|
|
64760
|
+
return bounds;
|
|
64761
|
+
}
|
|
64762
|
+
function prevGraphemeBoundary(text, pos) {
|
|
64763
|
+
const bounds = graphemeBoundaries(text);
|
|
64764
|
+
let prev = 0;
|
|
64765
|
+
for (const b of bounds) {
|
|
64766
|
+
if (b >= pos)
|
|
64767
|
+
break;
|
|
64768
|
+
prev = b;
|
|
64769
|
+
}
|
|
64770
|
+
return prev;
|
|
64771
|
+
}
|
|
64772
|
+
function nextGraphemeBoundary(text, pos) {
|
|
64773
|
+
const bounds = graphemeBoundaries(text);
|
|
64774
|
+
for (const b of bounds) {
|
|
64775
|
+
if (b > pos)
|
|
64776
|
+
return b;
|
|
64777
|
+
}
|
|
64778
|
+
return text.length;
|
|
64752
64779
|
}
|
|
64753
64780
|
var handle = null;
|
|
64754
64781
|
var inkInstance = null;
|
|
@@ -64758,8 +64785,9 @@ var App2 = ({ onReady }) => {
|
|
|
64758
64785
|
const [items, setItems] = (0, import_react35.useState)([]);
|
|
64759
64786
|
const [footer, setFooterState] = (0, import_react35.useState)({ mode: "auto", autoApprove: false });
|
|
64760
64787
|
const { columns } = use_window_size_default();
|
|
64761
|
-
const [
|
|
64788
|
+
const [busy, setBusyState] = (0, import_react35.useState)(false);
|
|
64762
64789
|
const [line, setLineState] = (0, import_react35.useState)("");
|
|
64790
|
+
const [cursorPos, setCursorPosState] = (0, import_react35.useState)(0);
|
|
64763
64791
|
const [prompt2, setPrompt] = (0, import_react35.useState)(DEFAULT_PROMPT);
|
|
64764
64792
|
const { exit } = use_app_default();
|
|
64765
64793
|
const lineRef = (0, import_react35.useRef)("");
|
|
@@ -64768,18 +64796,30 @@ var App2 = ({ onReady }) => {
|
|
|
64768
64796
|
lineRef.current = value;
|
|
64769
64797
|
setLineState(value);
|
|
64770
64798
|
}, []);
|
|
64799
|
+
const cursorRef = (0, import_react35.useRef)(0);
|
|
64800
|
+
const setCursorPos = (0, import_react35.useCallback)((next) => {
|
|
64801
|
+
const value = typeof next === "function" ? next(cursorRef.current) : next;
|
|
64802
|
+
cursorRef.current = value;
|
|
64803
|
+
setCursorPosState(value);
|
|
64804
|
+
}, []);
|
|
64771
64805
|
const askResolverRef = (0, import_react35.useRef)(null);
|
|
64772
64806
|
const onLineRef = (0, import_react35.useRef)(null);
|
|
64807
|
+
const onQueuedLineRef = (0, import_react35.useRef)(null);
|
|
64808
|
+
const busyRef = (0, import_react35.useRef)(false);
|
|
64773
64809
|
const [live, setLiveState] = (0, import_react35.useState)("");
|
|
64774
64810
|
const print = (0, import_react35.useCallback)((text) => {
|
|
64775
64811
|
setItems((prev) => [...prev, { id: idCounter++, content: text }]);
|
|
64776
64812
|
}, []);
|
|
64777
64813
|
const setFooter = (0, import_react35.useCallback)((info) => setFooterState(info), []);
|
|
64778
64814
|
const setLive = (0, import_react35.useCallback)((text) => setLiveState(text), []);
|
|
64779
|
-
const
|
|
64815
|
+
const setBusy = (0, import_react35.useCallback)((value) => {
|
|
64816
|
+
busyRef.current = value;
|
|
64817
|
+
setBusyState(value);
|
|
64818
|
+
}, []);
|
|
64780
64819
|
const askLine = (0, import_react35.useCallback)((promptText) => {
|
|
64781
64820
|
setPrompt(promptText || DEFAULT_PROMPT);
|
|
64782
64821
|
setLine("");
|
|
64822
|
+
setCursorPos(0);
|
|
64783
64823
|
return new Promise((resolve3) => {
|
|
64784
64824
|
askResolverRef.current = (answer) => {
|
|
64785
64825
|
setPrompt(DEFAULT_PROMPT);
|
|
@@ -64790,18 +64830,58 @@ var App2 = ({ onReady }) => {
|
|
|
64790
64830
|
const onLine = (0, import_react35.useCallback)((cb) => {
|
|
64791
64831
|
onLineRef.current = cb;
|
|
64792
64832
|
}, []);
|
|
64833
|
+
const onQueuedLine = (0, import_react35.useCallback)((cb) => {
|
|
64834
|
+
onQueuedLineRef.current = cb;
|
|
64835
|
+
}, []);
|
|
64836
|
+
const onInterruptRef = (0, import_react35.useRef)(null);
|
|
64837
|
+
const onInterrupt = (0, import_react35.useCallback)((cb) => {
|
|
64838
|
+
onInterruptRef.current = cb;
|
|
64839
|
+
}, []);
|
|
64793
64840
|
use_input_default((char, key) => {
|
|
64794
|
-
if (!inputEnabled)
|
|
64795
|
-
return;
|
|
64796
64841
|
if (key.ctrl && char === "c") {
|
|
64842
|
+
const askResolve = askResolverRef.current;
|
|
64843
|
+
if (askResolve) {
|
|
64844
|
+
askResolverRef.current = null;
|
|
64845
|
+
setLine("");
|
|
64846
|
+
setCursorPos(0);
|
|
64847
|
+
askResolve("n");
|
|
64848
|
+
return;
|
|
64849
|
+
}
|
|
64850
|
+
if (busyRef.current && onInterruptRef.current) {
|
|
64851
|
+
onInterruptRef.current();
|
|
64852
|
+
return;
|
|
64853
|
+
}
|
|
64797
64854
|
exit();
|
|
64798
64855
|
return;
|
|
64799
64856
|
}
|
|
64800
64857
|
if (key.backspace || key.delete) {
|
|
64801
|
-
|
|
64858
|
+
if (key.delete) {
|
|
64859
|
+
setLine((s2) => {
|
|
64860
|
+
const pos = cursorRef.current;
|
|
64861
|
+
const end = nextGraphemeBoundary(s2, pos);
|
|
64862
|
+
return s2.slice(0, pos) + s2.slice(end);
|
|
64863
|
+
});
|
|
64864
|
+
return;
|
|
64865
|
+
}
|
|
64866
|
+
setLine((s2) => {
|
|
64867
|
+
const pos = cursorRef.current;
|
|
64868
|
+
if (pos === 0)
|
|
64869
|
+
return s2;
|
|
64870
|
+
const start = prevGraphemeBoundary(s2, pos);
|
|
64871
|
+
setCursorPos(start);
|
|
64872
|
+
return s2.slice(0, start) + s2.slice(pos);
|
|
64873
|
+
});
|
|
64874
|
+
return;
|
|
64875
|
+
}
|
|
64876
|
+
if (key.leftArrow) {
|
|
64877
|
+
setCursorPos((pos) => prevGraphemeBoundary(lineRef.current, pos));
|
|
64878
|
+
return;
|
|
64879
|
+
}
|
|
64880
|
+
if (key.rightArrow) {
|
|
64881
|
+
setCursorPos((pos) => nextGraphemeBoundary(lineRef.current, pos));
|
|
64802
64882
|
return;
|
|
64803
64883
|
}
|
|
64804
|
-
if (key.upArrow || key.downArrow || key.
|
|
64884
|
+
if (key.upArrow || key.downArrow || key.tab) {
|
|
64805
64885
|
return;
|
|
64806
64886
|
}
|
|
64807
64887
|
const newlineIdx = char.search(/[\r\n]/);
|
|
@@ -64809,24 +64889,42 @@ var App2 = ({ onReady }) => {
|
|
|
64809
64889
|
if (hasNewline) {
|
|
64810
64890
|
const before = newlineIdx === -1 ? char : char.slice(0, newlineIdx);
|
|
64811
64891
|
const after = newlineIdx === -1 ? "" : char.slice(newlineIdx + 1).replace(/^[\r\n]/, "");
|
|
64812
|
-
const
|
|
64892
|
+
const pos = cursorRef.current;
|
|
64893
|
+
const submitted = lineRef.current.slice(0, pos) + before + lineRef.current.slice(pos);
|
|
64813
64894
|
setLine(after);
|
|
64895
|
+
setCursorPos(0);
|
|
64814
64896
|
print(prompt2 + submitted);
|
|
64815
64897
|
const askResolve = askResolverRef.current;
|
|
64816
64898
|
if (askResolve) {
|
|
64817
64899
|
askResolverRef.current = null;
|
|
64818
64900
|
askResolve(submitted);
|
|
64901
|
+
} else if (busyRef.current) {
|
|
64902
|
+
onQueuedLineRef.current?.(submitted);
|
|
64819
64903
|
} else {
|
|
64820
64904
|
onLineRef.current?.(submitted);
|
|
64821
64905
|
}
|
|
64822
64906
|
return;
|
|
64823
64907
|
}
|
|
64824
|
-
setLine((s2) =>
|
|
64908
|
+
setLine((s2) => {
|
|
64909
|
+
const pos = cursorRef.current;
|
|
64910
|
+
setCursorPos(pos + char.length);
|
|
64911
|
+
return s2.slice(0, pos) + char + s2.slice(pos);
|
|
64912
|
+
});
|
|
64825
64913
|
});
|
|
64826
64914
|
import_react35.default.useEffect(() => {
|
|
64827
|
-
onReady({
|
|
64915
|
+
onReady({
|
|
64916
|
+
print,
|
|
64917
|
+
setFooter,
|
|
64918
|
+
setLive,
|
|
64919
|
+
askLine,
|
|
64920
|
+
onLine,
|
|
64921
|
+
onQueuedLine,
|
|
64922
|
+
onInterrupt,
|
|
64923
|
+
setBusy,
|
|
64924
|
+
close: () => exit()
|
|
64925
|
+
});
|
|
64828
64926
|
}, []);
|
|
64829
|
-
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))),
|
|
64927
|
+
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, line.slice(0, cursorPos)), /* @__PURE__ */ import_react35.default.createElement(Text, { inverse: true }, line.slice(cursorPos, cursorPos + 1) || " "), /* @__PURE__ */ import_react35.default.createElement(Text, null, line.slice(cursorPos + 1))), /* @__PURE__ */ import_react35.default.createElement(Text, { dimColor: true }, footerText(footer), busy ? " \xB7 agent working\u2026" : ""));
|
|
64830
64928
|
};
|
|
64831
64929
|
function startInkTerminal() {
|
|
64832
64930
|
if (handle)
|
|
@@ -64867,26 +64965,31 @@ var InkReadlineAdapter = class extends EventEmitter3 {
|
|
|
64867
64965
|
line = "";
|
|
64868
64966
|
cursor = 0;
|
|
64869
64967
|
ink;
|
|
64870
|
-
|
|
64968
|
+
busy = false;
|
|
64969
|
+
pendingInput = [];
|
|
64871
64970
|
constructor(ink) {
|
|
64872
64971
|
super();
|
|
64873
64972
|
this.ink = ink;
|
|
64874
64973
|
this.ink.onLine((text) => {
|
|
64875
|
-
if (this.paused)
|
|
64876
|
-
return;
|
|
64877
64974
|
this.emit("line", text);
|
|
64878
64975
|
});
|
|
64976
|
+
this.ink.onQueuedLine((text) => {
|
|
64977
|
+
this.pendingInput.push(text);
|
|
64978
|
+
});
|
|
64979
|
+
this.ink.onInterrupt(() => {
|
|
64980
|
+
this.emit("interrupt");
|
|
64981
|
+
});
|
|
64879
64982
|
}
|
|
64880
64983
|
prompt(_preserveCursor) {
|
|
64881
64984
|
}
|
|
64882
64985
|
pause() {
|
|
64883
|
-
this.
|
|
64884
|
-
this.ink.
|
|
64986
|
+
this.busy = true;
|
|
64987
|
+
this.ink.setBusy(true);
|
|
64885
64988
|
return this;
|
|
64886
64989
|
}
|
|
64887
64990
|
resume() {
|
|
64888
|
-
this.
|
|
64889
|
-
this.ink.
|
|
64991
|
+
this.busy = false;
|
|
64992
|
+
this.ink.setBusy(false);
|
|
64890
64993
|
return this;
|
|
64891
64994
|
}
|
|
64892
64995
|
close() {
|
|
@@ -64896,6 +64999,21 @@ var InkReadlineAdapter = class extends EventEmitter3 {
|
|
|
64896
64999
|
question(query, cb) {
|
|
64897
65000
|
this.ink.askLine(query).then(cb);
|
|
64898
65001
|
}
|
|
65002
|
+
/**
|
|
65003
|
+
* Drains and returns every follow-up message the user typed and sent while
|
|
65004
|
+
* `pause()` was active (i.e. during a running agent turn). Intended to be
|
|
65005
|
+
* passed straight through as `AgentLoopOptions.takePendingInput` — see
|
|
65006
|
+
* loop.ts, and the VS Code panel's `_pendingInjections.splice(0)` for the
|
|
65007
|
+
* pattern this mirrors. Returns `[]` when nothing is queued, and empties
|
|
65008
|
+
* the queue on every call so the same follow-up is never folded in twice.
|
|
65009
|
+
*/
|
|
65010
|
+
takePendingInput() {
|
|
65011
|
+
return this.pendingInput.splice(0);
|
|
65012
|
+
}
|
|
65013
|
+
/** True while a `pause()`/`resume()` pair is in effect (an agent turn is running). */
|
|
65014
|
+
isBusy() {
|
|
65015
|
+
return this.busy;
|
|
65016
|
+
}
|
|
64899
65017
|
};
|
|
64900
65018
|
|
|
64901
65019
|
// src/commands/chat.ts
|
|
@@ -65211,7 +65329,7 @@ function formatAgentsList(workDir) {
|
|
|
65211
65329
|
}
|
|
65212
65330
|
return lines.join("\n");
|
|
65213
65331
|
}
|
|
65214
|
-
async function runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrallMd, mode, effort, checkpointManager, onProgress) {
|
|
65332
|
+
async function runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrallMd, mode, effort, checkpointManager, onProgress, takePendingInput) {
|
|
65215
65333
|
let lastUsage;
|
|
65216
65334
|
const spinner = new Spinner();
|
|
65217
65335
|
const mdRender = new MarkdownStreamRenderer();
|
|
@@ -65252,6 +65370,14 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrall
|
|
|
65252
65370
|
// prompt, and sub-agents inherit the lock.
|
|
65253
65371
|
planMode: mode === "plan",
|
|
65254
65372
|
effort,
|
|
65373
|
+
// Claude-Code-style follow-ups: text the user typed and sent WHILE this
|
|
65374
|
+
// turn was already running. inkTerminal.tsx echoes each one into the
|
|
65375
|
+
// transcript itself the moment it's submitted (chronological, matching
|
|
65376
|
+
// the VS Code panel's queueMessage) — so onInjectedInput is intentionally
|
|
65377
|
+
// a no-op here rather than printing it again.
|
|
65378
|
+
takePendingInput,
|
|
65379
|
+
onInjectedInput: () => {
|
|
65380
|
+
},
|
|
65255
65381
|
// The backend streams a cumulative output-token count (routes/code.js's
|
|
65256
65382
|
// sendProgress, throttled to ≤5/s) covering thinking, visible text AND
|
|
65257
65383
|
// tool-argument JSON. This used to be stored in a variable and rendered only
|
|
@@ -65752,12 +65878,22 @@ ${text}` : "");
|
|
|
65752
65878
|
}
|
|
65753
65879
|
});
|
|
65754
65880
|
const rl = interactive ? new InkReadlineAdapter(getInkTerminal()) : readline3.createInterface({ input: process.stdin, output: process.stdout, terminal: true });
|
|
65881
|
+
if (rl instanceof InkReadlineAdapter) {
|
|
65882
|
+
rl.on("interrupt", () => {
|
|
65883
|
+
if (agentRunning) {
|
|
65884
|
+
console.log("\n" + source_default.yellow(" Interrupted."));
|
|
65885
|
+
abortSignal.aborted = true;
|
|
65886
|
+
agentRunning = false;
|
|
65887
|
+
}
|
|
65888
|
+
});
|
|
65889
|
+
}
|
|
65755
65890
|
setReadlineInterface(rl);
|
|
65756
65891
|
const updateFooter = () => {
|
|
65757
65892
|
if (interactive)
|
|
65758
65893
|
getInkTerminal().setFooter({ mode: agentMode, autoApprove: isYoloMode() });
|
|
65759
65894
|
};
|
|
65760
65895
|
updateFooter();
|
|
65896
|
+
const takePendingInput = rl instanceof InkReadlineAdapter ? () => rl.takePendingInput() : void 0;
|
|
65761
65897
|
let inputBuffer = "";
|
|
65762
65898
|
rl.on("line", async (rawLine) => {
|
|
65763
65899
|
if (rawLine.endsWith("\\")) {
|
|
@@ -65911,7 +66047,10 @@ ${convText}`;
|
|
|
65911
66047
|
env3,
|
|
65912
66048
|
nexrallMd,
|
|
65913
66049
|
agentMode,
|
|
65914
|
-
effortLevel
|
|
66050
|
+
effortLevel,
|
|
66051
|
+
void 0,
|
|
66052
|
+
void 0,
|
|
66053
|
+
takePendingInput
|
|
65915
66054
|
);
|
|
65916
66055
|
agentRunning = false;
|
|
65917
66056
|
const summaryText = [...r2.messages].reverse().find((m2) => m2.role === "assistant")?.content[0]?.text ?? "";
|
|
@@ -65970,7 +66109,10 @@ ${dirList}`;
|
|
|
65970
66109
|
env3,
|
|
65971
66110
|
nexrallMd,
|
|
65972
66111
|
"auto",
|
|
65973
|
-
effortLevel
|
|
66112
|
+
effortLevel,
|
|
66113
|
+
void 0,
|
|
66114
|
+
void 0,
|
|
66115
|
+
takePendingInput
|
|
65974
66116
|
);
|
|
65975
66117
|
agentRunning = false;
|
|
65976
66118
|
const content = [...r2.messages].reverse().find((m2) => m2.role === "assistant")?.content[0]?.text ?? "";
|
|
@@ -66189,7 +66331,7 @@ ${text}
|
|
|
66189
66331
|
abortSignal.aborted = false;
|
|
66190
66332
|
agentRunning = true;
|
|
66191
66333
|
try {
|
|
66192
|
-
const result = await runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrallMd, agentMode, effortLevel, checkpoints, saveProgress);
|
|
66334
|
+
const result = await runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrallMd, agentMode, effortLevel, checkpoints, saveProgress, takePendingInput);
|
|
66193
66335
|
messages = result.messages;
|
|
66194
66336
|
updateTitle();
|
|
66195
66337
|
saveSession(sessionId, sessionTitle, workDir, messages);
|
|
@@ -66309,7 +66451,7 @@ ${text}
|
|
|
66309
66451
|
abortSignal.aborted = false;
|
|
66310
66452
|
agentRunning = true;
|
|
66311
66453
|
try {
|
|
66312
|
-
const result = await runTurn(messages, turnModel, workDir, abortSignal, env3, nexrallMd, turnMode, effortLevel, checkpoints, saveProgress);
|
|
66454
|
+
const result = await runTurn(messages, turnModel, workDir, abortSignal, env3, nexrallMd, turnMode, effortLevel, checkpoints, saveProgress, takePendingInput);
|
|
66313
66455
|
messages = result.messages;
|
|
66314
66456
|
updateTitle();
|
|
66315
66457
|
saveSession(sessionId, sessionTitle, workDir, messages);
|
|
@@ -66333,7 +66475,7 @@ ${text}
|
|
|
66333
66475
|
abortSignal.aborted = false;
|
|
66334
66476
|
agentRunning = true;
|
|
66335
66477
|
try {
|
|
66336
|
-
const result = await runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrallMd, agentMode, effortLevel, checkpoints, saveProgress);
|
|
66478
|
+
const result = await runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrallMd, agentMode, effortLevel, checkpoints, saveProgress, takePendingInput);
|
|
66337
66479
|
messages = result.messages;
|
|
66338
66480
|
updateTitle();
|
|
66339
66481
|
saveSession(sessionId, sessionTitle, workDir, messages);
|