open-agents-ai 0.103.83 → 0.103.85
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 +169 -52
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4713,6 +4713,24 @@ Process error: ${err.message}`;
|
|
|
4713
4713
|
entry.finishedAt = Date.now();
|
|
4714
4714
|
return true;
|
|
4715
4715
|
}
|
|
4716
|
+
/** Kill ALL running tasks immediately (for /stop and /quit authority) */
|
|
4717
|
+
stopAll() {
|
|
4718
|
+
let killed = 0;
|
|
4719
|
+
for (const [, entry] of this.tasks) {
|
|
4720
|
+
if (entry.status !== "running")
|
|
4721
|
+
continue;
|
|
4722
|
+
if (entry.child) {
|
|
4723
|
+
try {
|
|
4724
|
+
entry.child.kill("SIGKILL");
|
|
4725
|
+
} catch {
|
|
4726
|
+
}
|
|
4727
|
+
}
|
|
4728
|
+
entry.status = "stopped";
|
|
4729
|
+
entry.finishedAt = Date.now();
|
|
4730
|
+
killed++;
|
|
4731
|
+
}
|
|
4732
|
+
return killed;
|
|
4733
|
+
}
|
|
4716
4734
|
list() {
|
|
4717
4735
|
return Array.from(this.tasks.values()).map(toInfo);
|
|
4718
4736
|
}
|
|
@@ -12442,8 +12460,8 @@ async function handleCmd(cmd) {
|
|
|
12442
12460
|
// succeeds in <1s. Racing them eliminates the wait.
|
|
12443
12461
|
dlog('remote_infer: invoking ' + riCapName + ' on peer ' + riTargetPeer.slice(0, 20) + ' (libp2p' + (_natsConn ? ' + NATS parallel' : '') + ')');
|
|
12444
12462
|
try {
|
|
12445
|
-
var RI_TIMEOUT =
|
|
12446
|
-
var riInvokeP = nexus.invokeCapability(riTargetPeer, riCapName, riData, { stream: false, maxDurationMs:
|
|
12463
|
+
var RI_TIMEOUT = 60000; // 60s outer timeout \u2014 fail fast for interactive use
|
|
12464
|
+
var riInvokeP = nexus.invokeCapability(riTargetPeer, riCapName, riData, { stream: false, maxDurationMs: 45000 });
|
|
12447
12465
|
var riTimeoutP = new Promise(function(_, reject) { setTimeout(function() { reject(new Error('remote_infer timed out after ' + (RI_TIMEOUT / 1000) + 's')); }, RI_TIMEOUT); });
|
|
12448
12466
|
|
|
12449
12467
|
// Build race candidates \u2014 libp2p + timeout always present
|
|
@@ -12454,7 +12472,7 @@ async function handleCmd(cmd) {
|
|
|
12454
12472
|
var _riNatsRaceP = (async function() {
|
|
12455
12473
|
var _rSubject = 'nexus.invoke.' + riTargetPeer;
|
|
12456
12474
|
var _rPayload = JSON.stringify({ capability: riCapName, input: riData, from: nexus.peerId || '' });
|
|
12457
|
-
var _rResp = await _natsConn.request(_rSubject, _natsCodec.encode(_rPayload), { timeout:
|
|
12475
|
+
var _rResp = await _natsConn.request(_rSubject, _natsCodec.encode(_rPayload), { timeout: 45000 });
|
|
12458
12476
|
var _rResult = JSON.parse(_natsCodec.decode(_rResp.data));
|
|
12459
12477
|
if (_rResult && _rResult.error) throw new Error('NATS: ' + _rResult.error);
|
|
12460
12478
|
dlog('remote_infer: NATS won the race');
|
|
@@ -12493,8 +12511,8 @@ async function handleCmd(cmd) {
|
|
|
12493
12511
|
var rPid = riCandidates[ri];
|
|
12494
12512
|
dlog('remote_infer: trying peer ' + rPid.slice(0, 20) + '...');
|
|
12495
12513
|
try {
|
|
12496
|
-
var PEER_INVOKE_TIMEOUT =
|
|
12497
|
-
var specInvoke = nexus.invokeCapability(rPid, riCapName, riData, { stream: false, maxDurationMs:
|
|
12514
|
+
var PEER_INVOKE_TIMEOUT = 30000; // 30s per peer in discovery \u2014 fail fast, try next
|
|
12515
|
+
var specInvoke = nexus.invokeCapability(rPid, riCapName, riData, { stream: false, maxDurationMs: 25000 });
|
|
12498
12516
|
var specTimeout = new Promise(function(_, reject) {
|
|
12499
12517
|
setTimeout(function() { reject(new Error('peer invoke timeout')); }, PEER_INVOKE_TIMEOUT);
|
|
12500
12518
|
});
|
|
@@ -12523,7 +12541,7 @@ async function handleCmd(cmd) {
|
|
|
12523
12541
|
try {
|
|
12524
12542
|
var _dpSubject = 'nexus.invoke.' + _dpPid;
|
|
12525
12543
|
var _dpPayload = JSON.stringify({ capability: riCapName, input: riData, from: nexus.peerId || '' });
|
|
12526
|
-
var _dpResp = await _natsConn.request(_dpSubject, _natsCodec.encode(_dpPayload), { timeout:
|
|
12544
|
+
var _dpResp = await _natsConn.request(_dpSubject, _natsCodec.encode(_dpPayload), { timeout: 30000 });
|
|
12527
12545
|
var _dpResult = JSON.parse(_natsCodec.decode(_dpResp.data));
|
|
12528
12546
|
if (_dpResult && !_dpResult.error) {
|
|
12529
12547
|
riResult = _dpResult;
|
|
@@ -18848,6 +18866,13 @@ ${this.options.dynamicContext}`,
|
|
|
18848
18866
|
injectUserMessage(content) {
|
|
18849
18867
|
this.pendingUserMessages.push(content);
|
|
18850
18868
|
}
|
|
18869
|
+
/** Retract the last pending user message (Esc cancel).
|
|
18870
|
+
* Returns the retracted text, or null if queue is empty or already consumed. */
|
|
18871
|
+
retractLastPendingMessage() {
|
|
18872
|
+
if (this.pendingUserMessages.length === 0)
|
|
18873
|
+
return null;
|
|
18874
|
+
return this.pendingUserMessages.pop();
|
|
18875
|
+
}
|
|
18851
18876
|
/** Abort the current task run — cancels in-flight requests and kills child processes */
|
|
18852
18877
|
abort() {
|
|
18853
18878
|
this.aborted = true;
|
|
@@ -19126,6 +19151,10 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
|
|
|
19126
19151
|
try {
|
|
19127
19152
|
response = this.options.streamEnabled && this.hasStreamingSupport() ? await this.streamingRequest(chatRequest, turn) : await this.backend.chatCompletion(chatRequest);
|
|
19128
19153
|
} catch (reqErr) {
|
|
19154
|
+
if (reqErr instanceof Error && reqErr.fatal) {
|
|
19155
|
+
this.emit({ type: "error", content: `Backend error: ${reqErr.message}`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
19156
|
+
break;
|
|
19157
|
+
}
|
|
19129
19158
|
const recovered = await this.retryOnTransient(reqErr, chatRequest, turn);
|
|
19130
19159
|
if (!recovered) {
|
|
19131
19160
|
const errMsg = reqErr instanceof Error ? reqErr.message : String(reqErr);
|
|
@@ -20886,6 +20915,8 @@ ${transcript}`
|
|
|
20886
20915
|
// -------------------------------------------------------------------------
|
|
20887
20916
|
/** Detect whether an error is transient (worth retrying) */
|
|
20888
20917
|
isTransientError(err) {
|
|
20918
|
+
if (err instanceof Error && err.fatal)
|
|
20919
|
+
return false;
|
|
20889
20920
|
const msg = err instanceof Error ? err.message : String(err);
|
|
20890
20921
|
if (/Backend HTTP (502|503|504)/i.test(msg))
|
|
20891
20922
|
return true;
|
|
@@ -20895,6 +20926,10 @@ ${transcript}`
|
|
|
20895
20926
|
return true;
|
|
20896
20927
|
if (/model is loading|server busy|overloaded/i.test(msg))
|
|
20897
20928
|
return true;
|
|
20929
|
+
if (/multiaddrs failed|all multiaddrs failed|dial to peer failed|stream was reset|Cannot reach peer/i.test(msg))
|
|
20930
|
+
return true;
|
|
20931
|
+
if (/NATS.*timeout|relay.*timeout|invoke.*timeout/i.test(msg))
|
|
20932
|
+
return true;
|
|
20898
20933
|
return false;
|
|
20899
20934
|
}
|
|
20900
20935
|
/**
|
|
@@ -21222,6 +21257,15 @@ var init_nexusBackend = __esm({
|
|
|
21222
21257
|
this.authKey = authKey || "";
|
|
21223
21258
|
this.thinking = thinking ?? true;
|
|
21224
21259
|
}
|
|
21260
|
+
/** Reset the consecutive failure counter (called on endpoint switch / reconnect) */
|
|
21261
|
+
resetFailures() {
|
|
21262
|
+
this.consecutiveFailures = 0;
|
|
21263
|
+
}
|
|
21264
|
+
/** Update target peer (allows switching peers without recreating the backend) */
|
|
21265
|
+
setTargetPeer(peerId) {
|
|
21266
|
+
this.targetPeer = peerId;
|
|
21267
|
+
this.consecutiveFailures = 0;
|
|
21268
|
+
}
|
|
21225
21269
|
async chatCompletion(request) {
|
|
21226
21270
|
if (this.consecutiveFailures >= _NexusAgenticBackend.MAX_CONSECUTIVE_FAILURES) {
|
|
21227
21271
|
const err = new Error(`Remote peer unreachable after ${this.consecutiveFailures} attempts. Use /endpoint to switch to a local model or reconnect.`);
|
|
@@ -21258,7 +21302,10 @@ var init_nexusBackend = __esm({
|
|
|
21258
21302
|
}
|
|
21259
21303
|
if (parsed.success === false) {
|
|
21260
21304
|
this.consecutiveFailures++;
|
|
21261
|
-
|
|
21305
|
+
const output = String(parsed.output || rawResult);
|
|
21306
|
+
const isDialErr = /multiaddrs failed|Cannot reach peer|dial to peer|timeout|ECONNREFUSED/i.test(output);
|
|
21307
|
+
const hint = isDialErr ? ` (${this.consecutiveFailures}/${_NexusAgenticBackend.MAX_CONSECUTIVE_FAILURES} failures \u2014 will stop after ${_NexusAgenticBackend.MAX_CONSECUTIVE_FAILURES})` : "";
|
|
21308
|
+
throw new Error(`Remote inference failed: ${output}${hint}`);
|
|
21262
21309
|
}
|
|
21263
21310
|
this.consecutiveFailures = 0;
|
|
21264
21311
|
const invokeResult = parsed.result;
|
|
@@ -45592,8 +45639,11 @@ var init_status_bar = __esm({
|
|
|
45592
45639
|
active = false;
|
|
45593
45640
|
scrollRegionTop = 1;
|
|
45594
45641
|
stdinHooked = false;
|
|
45595
|
-
/** Track previous terminal
|
|
45642
|
+
/** Track previous terminal dimensions to clear ghost separators on resize */
|
|
45596
45643
|
_prevTermRows = 0;
|
|
45644
|
+
_prevTermCols = 0;
|
|
45645
|
+
/** Debounce timer for resize events — prevents separator stacking during drag */
|
|
45646
|
+
_resizeTimer = null;
|
|
45597
45647
|
/**
|
|
45598
45648
|
* Depth-counted content write guard. Incremented by beginContentWrite(),
|
|
45599
45649
|
* decremented by endContentWrite(). Footer is only redrawn and cursor
|
|
@@ -46040,6 +46090,7 @@ var init_status_bar = __esm({
|
|
|
46040
46090
|
this.scrollRegionTop = scrollRegionTop ?? 1;
|
|
46041
46091
|
this.active = true;
|
|
46042
46092
|
this._prevTermRows = process.stdout.rows ?? 24;
|
|
46093
|
+
this._prevTermCols = process.stdout.columns ?? 80;
|
|
46043
46094
|
this.applyScrollRegion();
|
|
46044
46095
|
this.renderFooterAndPositionInput();
|
|
46045
46096
|
this.hookStdin();
|
|
@@ -46077,24 +46128,42 @@ var init_status_bar = __esm({
|
|
|
46077
46128
|
get reservedRows() {
|
|
46078
46129
|
return this._currentFooterHeight;
|
|
46079
46130
|
}
|
|
46080
|
-
/** Handle terminal resize —
|
|
46131
|
+
/** Handle terminal resize — debounced to prevent separator stacking during drag */
|
|
46081
46132
|
handleResize() {
|
|
46082
46133
|
if (!this.active)
|
|
46083
46134
|
return;
|
|
46135
|
+
if (this._resizeTimer)
|
|
46136
|
+
clearTimeout(this._resizeTimer);
|
|
46137
|
+
this._resizeTimer = setTimeout(() => {
|
|
46138
|
+
this._resizeTimer = null;
|
|
46139
|
+
this._handleResizeImmediate();
|
|
46140
|
+
}, 50);
|
|
46141
|
+
}
|
|
46142
|
+
/** Actual resize handler — called after debounce settles */
|
|
46143
|
+
_handleResizeImmediate() {
|
|
46144
|
+
if (!this.active)
|
|
46145
|
+
return;
|
|
46146
|
+
const prevRows = this._prevTermRows;
|
|
46147
|
+
const prevCols = this._prevTermCols;
|
|
46084
46148
|
this.updateFooterHeight();
|
|
46085
46149
|
const rows = process.stdout.rows ?? 24;
|
|
46086
|
-
const
|
|
46150
|
+
const cols = process.stdout.columns ?? 80;
|
|
46087
46151
|
this._prevTermRows = rows;
|
|
46152
|
+
this._prevTermCols = cols;
|
|
46088
46153
|
const pos = this.rowPositions(rows);
|
|
46089
46154
|
const w = getTermWidth();
|
|
46090
46155
|
const sep = c2.dim("\u2500".repeat(w));
|
|
46091
|
-
let
|
|
46092
|
-
if (prevRows > 0 && rows
|
|
46093
|
-
|
|
46156
|
+
let clearBuf = "";
|
|
46157
|
+
if (prevRows > 0 && (rows !== prevRows || cols !== prevCols)) {
|
|
46158
|
+
const wrapFactor = cols > 0 ? Math.ceil(prevCols / cols) : 1;
|
|
46159
|
+
const extraWrappedRows = Math.max(0, (wrapFactor - 1) * 3);
|
|
46160
|
+
const safetyMargin = extraWrappedRows + 2;
|
|
46161
|
+
const clearFrom = Math.max(1, pos.bufferRow - safetyMargin);
|
|
46162
|
+
clearBuf = "\x1B[1;" + rows + `r\x1B[${clearFrom};1H\x1B[J`;
|
|
46094
46163
|
}
|
|
46095
46164
|
if (this.writeDepth > 0) {
|
|
46096
46165
|
const inputWrap = this.wrapInput(w);
|
|
46097
|
-
let buf =
|
|
46166
|
+
let buf = clearBuf + `\x1B[${this.scrollRegionTop};${pos.scrollEnd}r\x1B[?25l\x1B[?7l\x1B[${pos.bufferRow};1H\x1B[2K${this.buildBufferContent(w)}\x1B[${pos.topSepRow};1H\x1B[2K${sep}`;
|
|
46098
46167
|
for (let i = 0; i < inputWrap.lines.length; i++) {
|
|
46099
46168
|
const row = pos.inputStartRow + i;
|
|
46100
46169
|
const prefix = i === 0 ? this.promptText : " ".repeat(this.promptWidth);
|
|
@@ -46103,8 +46172,8 @@ var init_status_bar = __esm({
|
|
|
46103
46172
|
buf += `\x1B[${pos.bottomSepRow};1H\x1B[2K${sep}\x1B[${pos.metricsRow};1H\x1B[2K${this.buildMetricsLine()}\x1B[?7h\x1B[${pos.scrollEnd};1H`;
|
|
46104
46173
|
process.stdout.write(buf);
|
|
46105
46174
|
} else {
|
|
46106
|
-
if (
|
|
46107
|
-
process.stdout.write(
|
|
46175
|
+
if (clearBuf)
|
|
46176
|
+
process.stdout.write(clearBuf);
|
|
46108
46177
|
this.applyScrollRegion();
|
|
46109
46178
|
this.renderFooterAndPositionInput();
|
|
46110
46179
|
}
|
|
@@ -47956,8 +48025,9 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
47956
48025
|
let currentTaskType;
|
|
47957
48026
|
let sessionFilesTouched = [];
|
|
47958
48027
|
let sessionToolCallCount = 0;
|
|
48028
|
+
let lastSteeringInput = "";
|
|
48029
|
+
let lastSteeringRetracted = false;
|
|
47959
48030
|
let restoredSessionContext = null;
|
|
47960
|
-
let pendingSessionRestore = false;
|
|
47961
48031
|
let sessionSudoPassword = null;
|
|
47962
48032
|
let sudoPromptPending = false;
|
|
47963
48033
|
const idlePrompt = `${c2.bold(c2.white("\u276F "))}`;
|
|
@@ -49217,7 +49287,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
49217
49287
|
if (!activeTask)
|
|
49218
49288
|
return false;
|
|
49219
49289
|
activeTask.runner.abort();
|
|
49220
|
-
|
|
49290
|
+
const bgKilled = taskManager.stopAll();
|
|
49291
|
+
writeContent(() => renderInfo(`Task aborted.${bgKilled > 0 ? ` ${bgKilled} background task(s) killed.` : ""}`));
|
|
49221
49292
|
return true;
|
|
49222
49293
|
},
|
|
49223
49294
|
pauseTask() {
|
|
@@ -49309,28 +49380,40 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
49309
49380
|
const lastTime = lastEntry.savedAt ? new Date(lastEntry.savedAt) : null;
|
|
49310
49381
|
const timeAgo = lastTime ? formatTimeAgo(lastTime) : "unknown";
|
|
49311
49382
|
const lastTask = lastEntry.task?.slice(0, 80) || "unknown";
|
|
49312
|
-
setTimeout(() => {
|
|
49383
|
+
setTimeout(async () => {
|
|
49313
49384
|
writeContent(() => {
|
|
49314
49385
|
renderInfo(`Previous session found (${savedCtx.entries.length} entries, last active ${timeAgo})`);
|
|
49315
49386
|
renderInfo(`Last task: ${lastTask}${lastEntry.task && lastEntry.task.length > 80 ? "..." : ""}`);
|
|
49316
|
-
renderInfo(`Restore previous context? (y/n) [auto-restores in 15s]`);
|
|
49317
49387
|
});
|
|
49318
|
-
|
|
49319
|
-
|
|
49320
|
-
setTimeout(() => {
|
|
49321
|
-
if (pendingSessionRestore) {
|
|
49322
|
-
pendingSessionRestore = false;
|
|
49323
|
-
const prompt = buildContextRestorePrompt(repoRoot);
|
|
49324
|
-
if (prompt) {
|
|
49325
|
-
restoredSessionContext = prompt;
|
|
49326
|
-
const info = loadSessionContext(repoRoot);
|
|
49327
|
-
writeContent(() => renderInfo(`Context auto-restored from ${info?.entries.length ?? 0} session(s).`));
|
|
49328
|
-
} else {
|
|
49329
|
-
writeContent(() => renderInfo("No context to restore. Starting fresh."));
|
|
49330
|
-
}
|
|
49331
|
-
showPrompt();
|
|
49332
|
-
}
|
|
49388
|
+
let autoRestoreTimer = setTimeout(() => {
|
|
49389
|
+
autoRestoreTimer = null;
|
|
49333
49390
|
}, 15e3);
|
|
49391
|
+
const result = await tuiSelect({
|
|
49392
|
+
items: [
|
|
49393
|
+
{ key: "restore", label: "Restore previous context" },
|
|
49394
|
+
{ key: "fresh", label: "Start fresh" }
|
|
49395
|
+
],
|
|
49396
|
+
activeKey: "restore",
|
|
49397
|
+
title: "Restore previous session context?",
|
|
49398
|
+
rl
|
|
49399
|
+
});
|
|
49400
|
+
if (autoRestoreTimer)
|
|
49401
|
+
clearTimeout(autoRestoreTimer);
|
|
49402
|
+
if (result.confirmed && result.key === "restore" || !result.confirmed && !autoRestoreTimer) {
|
|
49403
|
+
const prompt = buildContextRestorePrompt(repoRoot);
|
|
49404
|
+
if (prompt) {
|
|
49405
|
+
restoredSessionContext = prompt;
|
|
49406
|
+
const info = loadSessionContext(repoRoot);
|
|
49407
|
+
writeContent(() => renderInfo(`Context restored from ${info?.entries.length ?? 0} session(s).`));
|
|
49408
|
+
} else {
|
|
49409
|
+
writeContent(() => renderInfo("No context to restore. Starting fresh."));
|
|
49410
|
+
}
|
|
49411
|
+
} else if (result.confirmed && result.key === "fresh") {
|
|
49412
|
+
writeContent(() => renderInfo("Starting fresh."));
|
|
49413
|
+
} else {
|
|
49414
|
+
writeContent(() => renderInfo("Starting fresh."));
|
|
49415
|
+
}
|
|
49416
|
+
showPrompt();
|
|
49334
49417
|
}, 150);
|
|
49335
49418
|
}
|
|
49336
49419
|
}
|
|
@@ -49453,22 +49536,6 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
|
|
|
49453
49536
|
rl.on("line", (line) => {
|
|
49454
49537
|
persistHistoryLine(line);
|
|
49455
49538
|
const input = line.trim();
|
|
49456
|
-
if (pendingSessionRestore) {
|
|
49457
|
-
pendingSessionRestore = false;
|
|
49458
|
-
const answer = input.toLowerCase();
|
|
49459
|
-
if (answer === "y" || answer === "yes") {
|
|
49460
|
-
const prompt = buildContextRestorePrompt(repoRoot);
|
|
49461
|
-
if (prompt) {
|
|
49462
|
-
restoredSessionContext = prompt;
|
|
49463
|
-
const info = loadSessionContext(repoRoot);
|
|
49464
|
-
writeContent(() => renderInfo(`Context restored from ${info?.entries.length ?? 0} session(s). Will be injected into your next task.`));
|
|
49465
|
-
}
|
|
49466
|
-
} else {
|
|
49467
|
-
writeContent(() => renderInfo("Starting fresh."));
|
|
49468
|
-
}
|
|
49469
|
-
showPrompt();
|
|
49470
|
-
return;
|
|
49471
|
-
}
|
|
49472
49539
|
if (!input) {
|
|
49473
49540
|
if (pasteBuffer.length > 0) {
|
|
49474
49541
|
flushPasteBuffer();
|
|
@@ -49523,6 +49590,7 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
|
|
|
49523
49590
|
if (activeTask) {
|
|
49524
49591
|
activeTask.runner.abort();
|
|
49525
49592
|
}
|
|
49593
|
+
taskManager.stopAll();
|
|
49526
49594
|
if (blessEngine?.isActive)
|
|
49527
49595
|
blessEngine.stop();
|
|
49528
49596
|
if (telegramBridge?.isActive)
|
|
@@ -49592,6 +49660,10 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
49592
49660
|
const isImage = isImagePath(cleanPath) && existsSync40(resolve28(repoRoot, cleanPath));
|
|
49593
49661
|
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync40(resolve28(repoRoot, cleanPath));
|
|
49594
49662
|
if (activeTask) {
|
|
49663
|
+
if (activeTask.runner.isPaused) {
|
|
49664
|
+
activeTask.runner.resume();
|
|
49665
|
+
statusBar.setProcessing(true);
|
|
49666
|
+
}
|
|
49595
49667
|
if (isImage) {
|
|
49596
49668
|
try {
|
|
49597
49669
|
const imgPath = resolve28(repoRoot, cleanPath);
|
|
@@ -49619,8 +49691,16 @@ ${result.text}`;
|
|
|
49619
49691
|
writeContent(() => renderUserInterrupt(`[Media: ${cleanPath}]`));
|
|
49620
49692
|
}
|
|
49621
49693
|
} else {
|
|
49694
|
+
const isReplacement = lastSteeringRetracted;
|
|
49695
|
+
lastSteeringInput = input;
|
|
49696
|
+
lastSteeringRetracted = false;
|
|
49622
49697
|
const lineCount = input.split("\n").length;
|
|
49623
|
-
if (
|
|
49698
|
+
if (isReplacement) {
|
|
49699
|
+
const displayText2 = lineCount > 1 ? `[pasted ${lineCount} lines]` : input;
|
|
49700
|
+
writeContent(() => process.stdout.write(`
|
|
49701
|
+
${c2.green("\u21BB")} ${c2.bold("Context replaced:")} ${displayText2}
|
|
49702
|
+
`));
|
|
49703
|
+
} else if (lineCount > 1) {
|
|
49624
49704
|
writeContent(() => renderUserInterrupt(`[pasted ${lineCount} lines]`));
|
|
49625
49705
|
} else {
|
|
49626
49706
|
writeContent(() => renderUserInterrupt(input));
|
|
@@ -49991,6 +50071,7 @@ ${c2.dim("(paste cancelled)")}
|
|
|
49991
50071
|
}
|
|
49992
50072
|
if (activeTask) {
|
|
49993
50073
|
activeTask.runner.abort();
|
|
50074
|
+
taskManager.stopAll();
|
|
49994
50075
|
writeContent(() => renderTaskAborted());
|
|
49995
50076
|
} else {
|
|
49996
50077
|
writeContent(() => process.stdout.write(`
|
|
@@ -49999,6 +50080,42 @@ ${c2.dim("(Use /quit to exit)")}
|
|
|
49999
50080
|
}
|
|
50000
50081
|
showPrompt();
|
|
50001
50082
|
});
|
|
50083
|
+
if (process.stdin.isTTY) {
|
|
50084
|
+
readline2.emitKeypressEvents(process.stdin, rl);
|
|
50085
|
+
process.stdin.on("keypress", (_str, key) => {
|
|
50086
|
+
if (!key)
|
|
50087
|
+
return;
|
|
50088
|
+
if (key.name === "escape" && activeTask) {
|
|
50089
|
+
if (!activeTask.runner.isPaused) {
|
|
50090
|
+
activeTask.runner.pause();
|
|
50091
|
+
statusBar.setProcessing(false);
|
|
50092
|
+
}
|
|
50093
|
+
const retracted = activeTask.runner.retractLastPendingMessage();
|
|
50094
|
+
if (retracted) {
|
|
50095
|
+
lastSteeringInput = retracted;
|
|
50096
|
+
lastSteeringRetracted = true;
|
|
50097
|
+
writeContent(() => process.stdout.write(` ${c2.yellow("\u23F8")} ${c2.dim("\x1B[9m" + retracted.slice(0, 120) + "\x1B[29m")} ${c2.dim("\u2190 retracted, edit below and press Enter")}
|
|
50098
|
+
`));
|
|
50099
|
+
rl.line = retracted;
|
|
50100
|
+
rl.cursor = retracted.length;
|
|
50101
|
+
if (statusBar.isActive)
|
|
50102
|
+
statusBar.renderFooterPreserveCursor?.();
|
|
50103
|
+
} else if (lastSteeringInput) {
|
|
50104
|
+
lastSteeringRetracted = true;
|
|
50105
|
+
writeContent(() => process.stdout.write(` ${c2.yellow("\u23F8")} ${c2.dim("\x1B[9m" + lastSteeringInput.slice(0, 120) + "\x1B[29m")} ${c2.dim("\u2190 already sent, re-type below to override")}
|
|
50106
|
+
`));
|
|
50107
|
+
rl.line = lastSteeringInput;
|
|
50108
|
+
rl.cursor = lastSteeringInput.length;
|
|
50109
|
+
if (statusBar.isActive)
|
|
50110
|
+
statusBar.renderFooterPreserveCursor?.();
|
|
50111
|
+
} else {
|
|
50112
|
+
writeContent(() => process.stdout.write(` ${c2.yellow("\u23F8")} ${c2.dim("Paused. /resume to continue, /stop to kill.")}
|
|
50113
|
+
`));
|
|
50114
|
+
}
|
|
50115
|
+
showPrompt();
|
|
50116
|
+
}
|
|
50117
|
+
});
|
|
50118
|
+
}
|
|
50002
50119
|
}
|
|
50003
50120
|
async function runWithTUI(task, config, repoPath) {
|
|
50004
50121
|
const repoRoot = resolve28(repoPath ?? cwd());
|
package/package.json
CHANGED