nexrall-code 0.5.73 → 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 +231 -56
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -9873,6 +9873,7 @@ var require_client = __commonJS({
|
|
|
9873
9873
|
exports.streamChat = streamChat;
|
|
9874
9874
|
exports.cancelTurn = cancelTurn;
|
|
9875
9875
|
exports.revokeRefreshToken = revokeRefreshToken2;
|
|
9876
|
+
exports.describeAttachment = describeAttachment2;
|
|
9876
9877
|
exports.getBalance = getBalance3;
|
|
9877
9878
|
exports.exchangeVscodeCode = exchangeVscodeCode;
|
|
9878
9879
|
exports.login = login2;
|
|
@@ -10596,6 +10597,37 @@ var require_client = __commonJS({
|
|
|
10596
10597
|
} catch {
|
|
10597
10598
|
}
|
|
10598
10599
|
}
|
|
10600
|
+
async function describeAttachment2(kind, data, mediaType, name) {
|
|
10601
|
+
const fetchOnce = () => (0, node_fetch_1.default)(`${exports.API_BASE}/api/code/assets/describe`, {
|
|
10602
|
+
method: "POST",
|
|
10603
|
+
headers: { ...authHeaders(), "Content-Type": "application/json" },
|
|
10604
|
+
body: JSON.stringify({ kind, data, media_type: mediaType, name })
|
|
10605
|
+
});
|
|
10606
|
+
let response = await fetchOnce();
|
|
10607
|
+
if (response.status === 401 || response.status === 403) {
|
|
10608
|
+
const body = await response.text().catch(() => "");
|
|
10609
|
+
if (isExpiredTokenResponse(response.status, body) && await refreshAccessToken()) {
|
|
10610
|
+
response = await fetchOnce();
|
|
10611
|
+
} else {
|
|
10612
|
+
throw new Error(`API error ${response.status}: ${body}`);
|
|
10613
|
+
}
|
|
10614
|
+
}
|
|
10615
|
+
if (!response.ok) {
|
|
10616
|
+
let message = `API error ${response.status}`;
|
|
10617
|
+
try {
|
|
10618
|
+
const body = await response.json();
|
|
10619
|
+
if (body?.error)
|
|
10620
|
+
message = body.error;
|
|
10621
|
+
} catch {
|
|
10622
|
+
}
|
|
10623
|
+
throw new Error(message);
|
|
10624
|
+
}
|
|
10625
|
+
const json = await response.json();
|
|
10626
|
+
return {
|
|
10627
|
+
text: typeof json.text === "string" ? json.text : "",
|
|
10628
|
+
balance: typeof json.balance === "number" ? json.balance : 0
|
|
10629
|
+
};
|
|
10630
|
+
}
|
|
10599
10631
|
async function getBalance3() {
|
|
10600
10632
|
const fetchOnce = () => (0, node_fetch_1.default)(`${exports.API_BASE}/api/code/balance`, { method: "GET", headers: authHeaders() });
|
|
10601
10633
|
let response = await fetchOnce();
|
|
@@ -64700,23 +64732,50 @@ function footerText(info) {
|
|
|
64700
64732
|
}
|
|
64701
64733
|
var IntlWithSegmenter = Intl;
|
|
64702
64734
|
var graphemeSegmenter = typeof IntlWithSegmenter.Segmenter === "function" ? new IntlWithSegmenter.Segmenter(void 0, { granularity: "grapheme" }) : null;
|
|
64703
|
-
function
|
|
64704
|
-
if (!text)
|
|
64705
|
-
return "";
|
|
64735
|
+
function graphemeBoundaries(text) {
|
|
64706
64736
|
if (graphemeSegmenter) {
|
|
64707
|
-
|
|
64708
|
-
for (const { index } of graphemeSegmenter.segment(text))
|
|
64709
|
-
|
|
64710
|
-
|
|
64711
|
-
|
|
64712
|
-
|
|
64713
|
-
|
|
64714
|
-
|
|
64715
|
-
const
|
|
64716
|
-
|
|
64717
|
-
|
|
64718
|
-
|
|
64719
|
-
|
|
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;
|
|
64720
64779
|
}
|
|
64721
64780
|
var handle = null;
|
|
64722
64781
|
var inkInstance = null;
|
|
@@ -64726,8 +64785,9 @@ var App2 = ({ onReady }) => {
|
|
|
64726
64785
|
const [items, setItems] = (0, import_react35.useState)([]);
|
|
64727
64786
|
const [footer, setFooterState] = (0, import_react35.useState)({ mode: "auto", autoApprove: false });
|
|
64728
64787
|
const { columns } = use_window_size_default();
|
|
64729
|
-
const [
|
|
64788
|
+
const [busy, setBusyState] = (0, import_react35.useState)(false);
|
|
64730
64789
|
const [line, setLineState] = (0, import_react35.useState)("");
|
|
64790
|
+
const [cursorPos, setCursorPosState] = (0, import_react35.useState)(0);
|
|
64731
64791
|
const [prompt2, setPrompt] = (0, import_react35.useState)(DEFAULT_PROMPT);
|
|
64732
64792
|
const { exit } = use_app_default();
|
|
64733
64793
|
const lineRef = (0, import_react35.useRef)("");
|
|
@@ -64736,18 +64796,30 @@ var App2 = ({ onReady }) => {
|
|
|
64736
64796
|
lineRef.current = value;
|
|
64737
64797
|
setLineState(value);
|
|
64738
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
|
+
}, []);
|
|
64739
64805
|
const askResolverRef = (0, import_react35.useRef)(null);
|
|
64740
64806
|
const onLineRef = (0, import_react35.useRef)(null);
|
|
64807
|
+
const onQueuedLineRef = (0, import_react35.useRef)(null);
|
|
64808
|
+
const busyRef = (0, import_react35.useRef)(false);
|
|
64741
64809
|
const [live, setLiveState] = (0, import_react35.useState)("");
|
|
64742
64810
|
const print = (0, import_react35.useCallback)((text) => {
|
|
64743
64811
|
setItems((prev) => [...prev, { id: idCounter++, content: text }]);
|
|
64744
64812
|
}, []);
|
|
64745
64813
|
const setFooter = (0, import_react35.useCallback)((info) => setFooterState(info), []);
|
|
64746
64814
|
const setLive = (0, import_react35.useCallback)((text) => setLiveState(text), []);
|
|
64747
|
-
const
|
|
64815
|
+
const setBusy = (0, import_react35.useCallback)((value) => {
|
|
64816
|
+
busyRef.current = value;
|
|
64817
|
+
setBusyState(value);
|
|
64818
|
+
}, []);
|
|
64748
64819
|
const askLine = (0, import_react35.useCallback)((promptText) => {
|
|
64749
64820
|
setPrompt(promptText || DEFAULT_PROMPT);
|
|
64750
64821
|
setLine("");
|
|
64822
|
+
setCursorPos(0);
|
|
64751
64823
|
return new Promise((resolve3) => {
|
|
64752
64824
|
askResolverRef.current = (answer) => {
|
|
64753
64825
|
setPrompt(DEFAULT_PROMPT);
|
|
@@ -64758,18 +64830,58 @@ var App2 = ({ onReady }) => {
|
|
|
64758
64830
|
const onLine = (0, import_react35.useCallback)((cb) => {
|
|
64759
64831
|
onLineRef.current = cb;
|
|
64760
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
|
+
}, []);
|
|
64761
64840
|
use_input_default((char, key) => {
|
|
64762
|
-
if (!inputEnabled)
|
|
64763
|
-
return;
|
|
64764
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
|
+
}
|
|
64765
64854
|
exit();
|
|
64766
64855
|
return;
|
|
64767
64856
|
}
|
|
64768
64857
|
if (key.backspace || key.delete) {
|
|
64769
|
-
|
|
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
|
+
});
|
|
64770
64874
|
return;
|
|
64771
64875
|
}
|
|
64772
|
-
if (key.
|
|
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));
|
|
64882
|
+
return;
|
|
64883
|
+
}
|
|
64884
|
+
if (key.upArrow || key.downArrow || key.tab) {
|
|
64773
64885
|
return;
|
|
64774
64886
|
}
|
|
64775
64887
|
const newlineIdx = char.search(/[\r\n]/);
|
|
@@ -64777,24 +64889,42 @@ var App2 = ({ onReady }) => {
|
|
|
64777
64889
|
if (hasNewline) {
|
|
64778
64890
|
const before = newlineIdx === -1 ? char : char.slice(0, newlineIdx);
|
|
64779
64891
|
const after = newlineIdx === -1 ? "" : char.slice(newlineIdx + 1).replace(/^[\r\n]/, "");
|
|
64780
|
-
const
|
|
64892
|
+
const pos = cursorRef.current;
|
|
64893
|
+
const submitted = lineRef.current.slice(0, pos) + before + lineRef.current.slice(pos);
|
|
64781
64894
|
setLine(after);
|
|
64895
|
+
setCursorPos(0);
|
|
64782
64896
|
print(prompt2 + submitted);
|
|
64783
64897
|
const askResolve = askResolverRef.current;
|
|
64784
64898
|
if (askResolve) {
|
|
64785
64899
|
askResolverRef.current = null;
|
|
64786
64900
|
askResolve(submitted);
|
|
64901
|
+
} else if (busyRef.current) {
|
|
64902
|
+
onQueuedLineRef.current?.(submitted);
|
|
64787
64903
|
} else {
|
|
64788
64904
|
onLineRef.current?.(submitted);
|
|
64789
64905
|
}
|
|
64790
64906
|
return;
|
|
64791
64907
|
}
|
|
64792
|
-
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
|
+
});
|
|
64793
64913
|
});
|
|
64794
64914
|
import_react35.default.useEffect(() => {
|
|
64795
|
-
onReady({
|
|
64915
|
+
onReady({
|
|
64916
|
+
print,
|
|
64917
|
+
setFooter,
|
|
64918
|
+
setLive,
|
|
64919
|
+
askLine,
|
|
64920
|
+
onLine,
|
|
64921
|
+
onQueuedLine,
|
|
64922
|
+
onInterrupt,
|
|
64923
|
+
setBusy,
|
|
64924
|
+
close: () => exit()
|
|
64925
|
+
});
|
|
64796
64926
|
}, []);
|
|
64797
|
-
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" : ""));
|
|
64798
64928
|
};
|
|
64799
64929
|
function startInkTerminal() {
|
|
64800
64930
|
if (handle)
|
|
@@ -64835,26 +64965,31 @@ var InkReadlineAdapter = class extends EventEmitter3 {
|
|
|
64835
64965
|
line = "";
|
|
64836
64966
|
cursor = 0;
|
|
64837
64967
|
ink;
|
|
64838
|
-
|
|
64968
|
+
busy = false;
|
|
64969
|
+
pendingInput = [];
|
|
64839
64970
|
constructor(ink) {
|
|
64840
64971
|
super();
|
|
64841
64972
|
this.ink = ink;
|
|
64842
64973
|
this.ink.onLine((text) => {
|
|
64843
|
-
if (this.paused)
|
|
64844
|
-
return;
|
|
64845
64974
|
this.emit("line", text);
|
|
64846
64975
|
});
|
|
64976
|
+
this.ink.onQueuedLine((text) => {
|
|
64977
|
+
this.pendingInput.push(text);
|
|
64978
|
+
});
|
|
64979
|
+
this.ink.onInterrupt(() => {
|
|
64980
|
+
this.emit("interrupt");
|
|
64981
|
+
});
|
|
64847
64982
|
}
|
|
64848
64983
|
prompt(_preserveCursor) {
|
|
64849
64984
|
}
|
|
64850
64985
|
pause() {
|
|
64851
|
-
this.
|
|
64852
|
-
this.ink.
|
|
64986
|
+
this.busy = true;
|
|
64987
|
+
this.ink.setBusy(true);
|
|
64853
64988
|
return this;
|
|
64854
64989
|
}
|
|
64855
64990
|
resume() {
|
|
64856
|
-
this.
|
|
64857
|
-
this.ink.
|
|
64991
|
+
this.busy = false;
|
|
64992
|
+
this.ink.setBusy(false);
|
|
64858
64993
|
return this;
|
|
64859
64994
|
}
|
|
64860
64995
|
close() {
|
|
@@ -64864,6 +64999,21 @@ var InkReadlineAdapter = class extends EventEmitter3 {
|
|
|
64864
64999
|
question(query, cb) {
|
|
64865
65000
|
this.ink.askLine(query).then(cb);
|
|
64866
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
|
+
}
|
|
64867
65017
|
};
|
|
64868
65018
|
|
|
64869
65019
|
// src/commands/chat.ts
|
|
@@ -65179,7 +65329,7 @@ function formatAgentsList(workDir) {
|
|
|
65179
65329
|
}
|
|
65180
65330
|
return lines.join("\n");
|
|
65181
65331
|
}
|
|
65182
|
-
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) {
|
|
65183
65333
|
let lastUsage;
|
|
65184
65334
|
const spinner = new Spinner();
|
|
65185
65335
|
const mdRender = new MarkdownStreamRenderer();
|
|
@@ -65220,6 +65370,14 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrall
|
|
|
65220
65370
|
// prompt, and sub-agents inherit the lock.
|
|
65221
65371
|
planMode: mode === "plan",
|
|
65222
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
|
+
},
|
|
65223
65381
|
// The backend streams a cumulative output-token count (routes/code.js's
|
|
65224
65382
|
// sendProgress, throttled to ≤5/s) covering thinking, visible text AND
|
|
65225
65383
|
// tool-argument JSON. This used to be stored in a variable and rendered only
|
|
@@ -65720,12 +65878,22 @@ ${text}` : "");
|
|
|
65720
65878
|
}
|
|
65721
65879
|
});
|
|
65722
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
|
+
}
|
|
65723
65890
|
setReadlineInterface(rl);
|
|
65724
65891
|
const updateFooter = () => {
|
|
65725
65892
|
if (interactive)
|
|
65726
65893
|
getInkTerminal().setFooter({ mode: agentMode, autoApprove: isYoloMode() });
|
|
65727
65894
|
};
|
|
65728
65895
|
updateFooter();
|
|
65896
|
+
const takePendingInput = rl instanceof InkReadlineAdapter ? () => rl.takePendingInput() : void 0;
|
|
65729
65897
|
let inputBuffer = "";
|
|
65730
65898
|
rl.on("line", async (rawLine) => {
|
|
65731
65899
|
if (rawLine.endsWith("\\")) {
|
|
@@ -65879,7 +66047,10 @@ ${convText}`;
|
|
|
65879
66047
|
env3,
|
|
65880
66048
|
nexrallMd,
|
|
65881
66049
|
agentMode,
|
|
65882
|
-
effortLevel
|
|
66050
|
+
effortLevel,
|
|
66051
|
+
void 0,
|
|
66052
|
+
void 0,
|
|
66053
|
+
takePendingInput
|
|
65883
66054
|
);
|
|
65884
66055
|
agentRunning = false;
|
|
65885
66056
|
const summaryText = [...r2.messages].reverse().find((m2) => m2.role === "assistant")?.content[0]?.text ?? "";
|
|
@@ -65938,7 +66109,10 @@ ${dirList}`;
|
|
|
65938
66109
|
env3,
|
|
65939
66110
|
nexrallMd,
|
|
65940
66111
|
"auto",
|
|
65941
|
-
effortLevel
|
|
66112
|
+
effortLevel,
|
|
66113
|
+
void 0,
|
|
66114
|
+
void 0,
|
|
66115
|
+
takePendingInput
|
|
65942
66116
|
);
|
|
65943
66117
|
agentRunning = false;
|
|
65944
66118
|
const content = [...r2.messages].reverse().find((m2) => m2.role === "assistant")?.content[0]?.text ?? "";
|
|
@@ -66113,20 +66287,6 @@ ${content}
|
|
|
66113
66287
|
return;
|
|
66114
66288
|
}
|
|
66115
66289
|
const model = normaliseModelId(modelAlias);
|
|
66116
|
-
if (isPdf && NO_PDF_MODELS.has(model)) {
|
|
66117
|
-
console.log(source_default.red(
|
|
66118
|
-
` ${resolveModelLabel(modelAlias)} does not support PDF attachments. Switch models with /model (Claude models support PDFs), or extract the text yourself and use /add instead.`
|
|
66119
|
-
));
|
|
66120
|
-
rl.prompt();
|
|
66121
|
-
return;
|
|
66122
|
-
}
|
|
66123
|
-
if (!isPdf && NO_VISION_MODELS.has(model)) {
|
|
66124
|
-
console.log(source_default.red(
|
|
66125
|
-
` ${resolveModelLabel(modelAlias)} does not support image input. Switch models with /model, or attach as text with /add instead.`
|
|
66126
|
-
));
|
|
66127
|
-
rl.prompt();
|
|
66128
|
-
return;
|
|
66129
|
-
}
|
|
66130
66290
|
let buf;
|
|
66131
66291
|
try {
|
|
66132
66292
|
buf = fs8.readFileSync(filePath);
|
|
@@ -66146,9 +66306,24 @@ ${content}
|
|
|
66146
66306
|
const label = caption ? `[Attached: ${rel}]
|
|
66147
66307
|
${caption}` : `[Attached: ${rel}]`;
|
|
66148
66308
|
const content = [{ type: "text", text: label }];
|
|
66149
|
-
|
|
66150
|
-
|
|
66151
|
-
|
|
66309
|
+
const needsSidecar = isPdf ? NO_PDF_MODELS.has(model) : NO_VISION_MODELS.has(model);
|
|
66310
|
+
if (needsSidecar) {
|
|
66311
|
+
console.log(source_default.dim(` ${resolveModelLabel(modelAlias)} can't read ${isPdf ? "PDFs" : "images"} directly \u2014 describing ${rel} with Claude Sonnet 5 first\u2026`));
|
|
66312
|
+
try {
|
|
66313
|
+
const { text } = await (0, import_code_core3.describeAttachment)(isPdf ? "pdf" : "image", data, mimeType, rel);
|
|
66314
|
+
content.push({ type: "text", text: `<attachment_description>
|
|
66315
|
+
${text}
|
|
66316
|
+
</attachment_description>` });
|
|
66317
|
+
} catch (err) {
|
|
66318
|
+
console.log(source_default.red(` Could not describe ${rel}: ${err.message}`));
|
|
66319
|
+
rl.prompt();
|
|
66320
|
+
return;
|
|
66321
|
+
}
|
|
66322
|
+
} else {
|
|
66323
|
+
content.push(
|
|
66324
|
+
isPdf ? { type: "document", source: { type: "base64", media_type: "application/pdf", data } } : { type: "image", source: { type: "base64", media_type: mimeType, data } }
|
|
66325
|
+
);
|
|
66326
|
+
}
|
|
66152
66327
|
console.log(source_default.dim(` Attached ${rel} (${(buf.length / 1024).toFixed(0)}KB) \u2014 sending\u2026`));
|
|
66153
66328
|
checkpoints.beginTurn(`/image ${rel}${caption ? " " + caption : ""}`, messages.length);
|
|
66154
66329
|
messages.push({ role: "user", content });
|
|
@@ -66156,7 +66331,7 @@ ${caption}` : `[Attached: ${rel}]`;
|
|
|
66156
66331
|
abortSignal.aborted = false;
|
|
66157
66332
|
agentRunning = true;
|
|
66158
66333
|
try {
|
|
66159
|
-
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);
|
|
66160
66335
|
messages = result.messages;
|
|
66161
66336
|
updateTitle();
|
|
66162
66337
|
saveSession(sessionId, sessionTitle, workDir, messages);
|
|
@@ -66276,7 +66451,7 @@ ${caption}` : `[Attached: ${rel}]`;
|
|
|
66276
66451
|
abortSignal.aborted = false;
|
|
66277
66452
|
agentRunning = true;
|
|
66278
66453
|
try {
|
|
66279
|
-
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);
|
|
66280
66455
|
messages = result.messages;
|
|
66281
66456
|
updateTitle();
|
|
66282
66457
|
saveSession(sessionId, sessionTitle, workDir, messages);
|
|
@@ -66300,7 +66475,7 @@ ${caption}` : `[Attached: ${rel}]`;
|
|
|
66300
66475
|
abortSignal.aborted = false;
|
|
66301
66476
|
agentRunning = true;
|
|
66302
66477
|
try {
|
|
66303
|
-
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);
|
|
66304
66479
|
messages = result.messages;
|
|
66305
66480
|
updateTitle();
|
|
66306
66481
|
saveSession(sessionId, sessionTitle, workDir, messages);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexrall-code",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.75",
|
|
4
4
|
"description": "Nexrall Code — AI coding assistant for your terminal (headless agent for scripts, CI and automation)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"release": "node build.js && node scripts/upload-release.cjs"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@nexrall/code-core": "^1.4.
|
|
42
|
+
"@nexrall/code-core": "^1.4.44",
|
|
43
43
|
"chalk": "^5.3.0",
|
|
44
44
|
"commander": "^12.0.0",
|
|
45
45
|
"diff": "^5.2.0",
|