nolo-cli 0.74.0-alpha.2 → 0.74.0
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/{_executeModel-YEVZAJYX.js → _executeModel-IULR47HG.js} +20 -20
- package/{agentDeleteCommand-WVO3JTH6.js → agentDeleteCommand-2S4WCDQC.js} +15 -14
- package/{agentEmailCommands-QYQ2DZUS.js → agentEmailCommands-V3ADGHX7.js} +29 -27
- package/{agentListCommands-XWLQZ2ZH.js → agentListCommands-EPK3S274.js} +17 -16
- package/{agentMachineCommands-BJZUZ2EY.js → agentMachineCommands-XMZWK7P3.js} +15 -14
- package/{agentRecordCommands-O6PYBK2A.js → agentRecordCommands-WFPWLWOF.js} +28 -26
- package/{agentRunCommand-POFC5W46.js → agentRunCommand-VUWNWC7C.js} +28 -26
- package/{agentRuntimeLocal-O6DZDTK4.js → agentRuntimeLocal-YRONTDLM.js} +15 -14
- package/{agentSlice-RRZS2UII.js → agentSlice-2P7OJFES.js} +1 -1
- package/{appDeleteCommands-426QK2XG.js → appDeleteCommands-YS7UGMP3.js} +16 -15
- package/{appDeployCommands-FIGFGXIJ.js → appDeployCommands-XIE5Z4BE.js} +16 -15
- package/{appDeployStatusCommands-D3B235FQ.js → appDeployStatusCommands-54UDVYET.js} +16 -15
- package/{appGetCommands-U6RZJII4.js → appGetCommands-6XYLBCRN.js} +16 -15
- package/{appListCommands-732PFEWM.js → appListCommands-VEGH7SF5.js} +16 -15
- package/{authCommand-EVGFLAHO.js → authCommand-JIEOFHXW.js} +84 -9
- package/{chatQueueReduxAdapter-LSBTGZW2.js → chatQueueReduxAdapter-GPYCH5Z2.js} +5 -5
- package/chromeCommands-VOIRNJBL.js +499 -0
- package/chromeOpsCommands-M7DPCX2T.js +258 -0
- package/{chunk-SJTCDYBY.js → chunk-3VPDELAP.js} +41 -30
- package/{chunk-CS36XM4N.js → chunk-4SZ37KLL.js} +21 -9
- package/{chunk-FPTQQSS6.js → chunk-73BR2IQT.js} +23 -2
- package/{chunk-PYXL2CJL.js → chunk-7FWPLK4M.js} +1 -1
- package/{chunk-DSRXPQWA.js → chunk-7QVPPOEC.js} +1 -1
- package/{chunk-KIS76A2P.js → chunk-AX7RMXSH.js} +1 -1
- package/{chunk-HSELVGAL.js → chunk-BKJO7LDP.js} +2 -2
- package/{chunk-Q6FF2MCK.js → chunk-BOYUESO7.js} +1 -1
- package/{chunk-GBPZKFYK.js → chunk-BZNGCVAW.js} +1 -1
- package/{chunk-EXMHJN7C.js → chunk-CADAR6QU.js} +1 -1
- package/{chunk-2QDDKFG5.js → chunk-CQ3WA2NE.js} +77 -0
- package/{chunk-AFIKMMGC.js → chunk-D6XYLSOS.js} +1 -1
- package/{chunk-TI4CCL34.js → chunk-DM4FBSWG.js} +3 -3
- package/{chunk-DWPNOYMB.js → chunk-DUJWWUGV.js} +1 -1
- package/{chunk-XGZM6BTX.js → chunk-EBKMQULC.js} +66 -120
- package/{chunk-ZLPA7K55.js → chunk-ETLZZQJE.js} +2 -2
- package/chunk-FMODTASJ.js +109 -0
- package/{chunk-FSFQ3A7S.js → chunk-FNGAF7C4.js} +2 -2
- package/{chunk-MYU3MJCF.js → chunk-GCJ3IS5M.js} +0 -1
- package/{chunk-XPQJXIF5.js → chunk-GHEJJGJI.js} +125 -25
- package/{chunk-DFY6PUV4.js → chunk-HTMVBPOF.js} +7 -7
- package/{chunk-VOEW2KF3.js → chunk-IDGYOD2O.js} +59 -55
- package/{chunk-2JCTE5UN.js → chunk-KEZNSFGD.js} +3 -3
- package/{chunk-I4UWPYBH.js → chunk-KRMWO2NN.js} +2 -2
- package/{chunk-PGSKWZCB.js → chunk-LHDV2QUI.js} +1 -1
- package/{chunk-UJ63UXGE.js → chunk-MXUSPS2N.js} +289 -2
- package/{chunk-3IT2PFHL.js → chunk-NB5SIWC4.js} +1 -1
- package/{chunk-HXAINXPQ.js → chunk-NFT2AOK5.js} +2 -2
- package/{chunk-QA6YKM3H.js → chunk-NRALD3CC.js} +1 -1
- package/{chunk-CJ23A7U4.js → chunk-PF6O3GR3.js} +533 -57
- package/{chunk-K7AG465Q.js → chunk-PZCTYKGU.js} +3 -1
- package/chunk-QCZX4FTW.js +242 -0
- package/{chunk-QBA5KMJI.js → chunk-RZOJRTKR.js} +29 -15
- package/{chunk-VE3O45CJ.js → chunk-T25L377S.js} +4 -4
- package/{chunk-CMH2SYHX.js → chunk-TMPLPCVX.js} +1 -1
- package/{chunk-L2Y24GRM.js → chunk-U7YP7ECK.js} +3 -3
- package/{chunk-AWPU7GXU.js → chunk-URWDSZRW.js} +2 -2
- package/{chunk-AFIWC5NH.js → chunk-WL2RKIBF.js} +1 -1
- package/{chunk-57VRXRLF.js → chunk-Y3NZYLPG.js} +1 -1
- package/{chunk-V3ZKNK5D.js → chunk-ZVN6I33J.js} +5 -5
- package/{codingSkills-E6KSDNSJ.js → codingSkills-7S6523WH.js} +2 -2
- package/{contentThunks-476Y6CFR.js → contentThunks-THSCADSK.js} +6 -6
- package/{createAgentAutomationAction-DN4SFTP5.js → createAgentAutomationAction-WGN3UQ5A.js} +6 -6
- package/{createDialogAction-2GS4JCMU.js → createDialogAction-3EN2NLH7.js} +8 -8
- package/{createPageAction-44WTUMZ5.js → createPageAction-4VK473QV.js} +6 -6
- package/{dialogCommands-7FH6Z2YK.js → dialogCommands-PS4NWYY7.js} +16 -15
- package/{dialogSlice-7HEVCJFT.js → dialogSlice-CLV7SVOZ.js} +5 -5
- package/{docCreateCommands-GN5E5ULM.js → docCreateCommands-4KANZJR6.js} +15 -14
- package/{docDeleteCommands-OQWPPQME.js → docDeleteCommands-F2S2TRUF.js} +16 -15
- package/{docReadCommands-E4QK2223.js → docReadCommands-B2WDPZQE.js} +15 -14
- package/{docStore-LJ7KNKFB.js → docStore-TDLCHWPF.js} +1 -1
- package/{docUpdateCommands-ZDJE4SI7.js → docUpdateCommands-E7TKHRIO.js} +15 -14
- package/{getPricing-HRMSOF3E.js → getPricing-QVTUQQTM.js} +2 -2
- package/{handleSendMessageAction-ETA5QZIN.js → handleSendMessageAction-AHL3ZHE4.js} +5 -5
- package/index.js +111 -47
- package/{machineCommands-SJLMLCCV.js → machineCommands-OTABVXOA.js} +27 -25
- package/{machineWsRunDispatch-74GHVCNY.js → machineWsRunDispatch-V4EVQSMZ.js} +27 -25
- package/package.json +1 -1
- package/{readlineWorkspace-XHS5C5F7.js → readlineWorkspace-IIT3FQ6I.js} +437 -115
- package/{runAgentClientLoop-2PGZSCET.js → runAgentClientLoop-7TQM7IAR.js} +18 -18
- package/{spaceCommands-GSQCO2LI.js → spaceCommands-FSYH7AL4.js} +15 -14
- package/{streamAgentChatTurn-I6FUM6RV.js → streamAgentChatTurn-6EF6TVFK.js} +22 -22
- package/{tools-KU4X5HGZ.js → tools-R3QNWWTD.js} +15 -13
- package/{tuiSummaryLlmCaller-J5BEPLW5.js → tuiSummaryLlmCaller-PWOXTCBF.js} +5 -5
- package/{updateDialogTitleAction-E3SNB75W.js → updateDialogTitleAction-F3EUOWOB.js} +6 -6
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
normalizeDialogRecord,
|
|
9
9
|
readDialogSnapshot,
|
|
10
10
|
sortDialogs
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-FNGAF7C4.js";
|
|
12
12
|
import {
|
|
13
13
|
ANSI_ESCAPE_REGEX,
|
|
14
14
|
COLLAPSED_PASTE_PLACEHOLDER_RE,
|
|
@@ -72,7 +72,7 @@ import {
|
|
|
72
72
|
wrapTextToLines,
|
|
73
73
|
wrapTranscriptLine,
|
|
74
74
|
wrapTranscriptLineWithLayout
|
|
75
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-3VPDELAP.js";
|
|
76
76
|
import "./chunk-S7Z2HMCN.js";
|
|
77
77
|
import {
|
|
78
78
|
listFavoriteAgentIdsAcrossServers,
|
|
@@ -80,12 +80,12 @@ import {
|
|
|
80
80
|
listRemoteAgents,
|
|
81
81
|
listRemoteAgentsAcrossServers,
|
|
82
82
|
normalizeListedAgent
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-U7YP7ECK.js";
|
|
84
84
|
import "./chunk-ID4G2MAR.js";
|
|
85
85
|
import {
|
|
86
86
|
listUserRecordsFromServers,
|
|
87
87
|
readLiveDbRecordAfterTombstoneMerge
|
|
88
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-WL2RKIBF.js";
|
|
89
89
|
import "./chunk-JYYZCK2Z.js";
|
|
90
90
|
import {
|
|
91
91
|
RUN_WAKE_CHANNEL_ENV,
|
|
@@ -96,8 +96,9 @@ import {
|
|
|
96
96
|
readTimestamp,
|
|
97
97
|
setCliLocale,
|
|
98
98
|
t
|
|
99
|
-
} from "./chunk-
|
|
100
|
-
import "./chunk-
|
|
99
|
+
} from "./chunk-GHEJJGJI.js";
|
|
100
|
+
import "./chunk-BZNGCVAW.js";
|
|
101
|
+
import "./chunk-QCZX4FTW.js";
|
|
101
102
|
import "./chunk-EADNWBAZ.js";
|
|
102
103
|
import {
|
|
103
104
|
backfillRunRecordParentDialog,
|
|
@@ -114,8 +115,8 @@ import {
|
|
|
114
115
|
deleteDbRecord,
|
|
115
116
|
queryUserRecords,
|
|
116
117
|
readDbRecord
|
|
117
|
-
} from "./chunk-
|
|
118
|
-
import "./chunk-
|
|
118
|
+
} from "./chunk-NRALD3CC.js";
|
|
119
|
+
import "./chunk-BOYUESO7.js";
|
|
119
120
|
import {
|
|
120
121
|
NOLO_DEFAULT_AGENT_KEY,
|
|
121
122
|
resolveCliAgentKeyInput
|
|
@@ -134,12 +135,12 @@ import "./chunk-ATNTHIZI.js";
|
|
|
134
135
|
import "./chunk-JEXVIMYZ.js";
|
|
135
136
|
import {
|
|
136
137
|
prepareTools
|
|
137
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-KRMWO2NN.js";
|
|
138
139
|
import {
|
|
139
140
|
buildResponseGuidelines
|
|
140
141
|
} from "./chunk-EOARMOVD.js";
|
|
141
142
|
import "./chunk-HS7MLR74.js";
|
|
142
|
-
import "./chunk-
|
|
143
|
+
import "./chunk-RZOJRTKR.js";
|
|
143
144
|
import "./chunk-5XTOKQLW.js";
|
|
144
145
|
import "./chunk-NF64D32W.js";
|
|
145
146
|
import "./chunk-3L2WKC3W.js";
|
|
@@ -154,7 +155,7 @@ import {
|
|
|
154
155
|
runShowsLogTail,
|
|
155
156
|
shortRunId
|
|
156
157
|
} from "./chunk-NTW5GWDM.js";
|
|
157
|
-
import "./chunk-
|
|
158
|
+
import "./chunk-73BR2IQT.js";
|
|
158
159
|
import "./chunk-KQHGZWSV.js";
|
|
159
160
|
import "./chunk-UDQWGU7F.js";
|
|
160
161
|
import "./chunk-PZM3EENV.js";
|
|
@@ -165,18 +166,18 @@ import "./chunk-FZGV4FGK.js";
|
|
|
165
166
|
import "./chunk-MEYIRKDN.js";
|
|
166
167
|
import "./chunk-63W5N6P3.js";
|
|
167
168
|
import "./chunk-VF4K2QE6.js";
|
|
168
|
-
import "./chunk-
|
|
169
|
-
import "./chunk-
|
|
170
|
-
import "./chunk-
|
|
169
|
+
import "./chunk-URWDSZRW.js";
|
|
170
|
+
import "./chunk-KEZNSFGD.js";
|
|
171
|
+
import "./chunk-EBKMQULC.js";
|
|
171
172
|
import "./chunk-ZJ7UHBJS.js";
|
|
172
173
|
import {
|
|
173
174
|
extractReferenceKeysFromMessage
|
|
174
|
-
} from "./chunk-
|
|
175
|
+
} from "./chunk-IDGYOD2O.js";
|
|
175
176
|
import "./chunk-EVBFYPDC.js";
|
|
176
177
|
import "./chunk-HQUORJTM.js";
|
|
177
178
|
import "./chunk-YYLHWIW6.js";
|
|
178
179
|
import "./chunk-AGGIDPCZ.js";
|
|
179
|
-
import "./chunk-
|
|
180
|
+
import "./chunk-DM4FBSWG.js";
|
|
180
181
|
import "./chunk-BJCWNHVU.js";
|
|
181
182
|
import "./chunk-5RGU3J7P.js";
|
|
182
183
|
import "./chunk-6YTOJY35.js";
|
|
@@ -190,43 +191,45 @@ import {
|
|
|
190
191
|
buildSkillDiscoveryContextBlock,
|
|
191
192
|
buildSkillDiscoveryContextLayer
|
|
192
193
|
} from "./chunk-E4MARS3Q.js";
|
|
193
|
-
import "./chunk-
|
|
194
|
+
import "./chunk-NB5SIWC4.js";
|
|
194
195
|
import {
|
|
195
196
|
expandEnabledPacks
|
|
196
|
-
} from "./chunk-
|
|
197
|
+
} from "./chunk-GCJ3IS5M.js";
|
|
197
198
|
import "./chunk-AETZ7AD6.js";
|
|
198
199
|
import "./chunk-KHCLMKZZ.js";
|
|
199
200
|
import {
|
|
200
201
|
buildLocalWorkspaceOpenAiTools,
|
|
201
202
|
buildLocalWorkspaceToolset,
|
|
203
|
+
formatToolOverflowMarker,
|
|
202
204
|
getProcessRegistry,
|
|
203
205
|
readCommandActionGatePayload
|
|
204
|
-
} from "./chunk-
|
|
205
|
-
import "./chunk-HXAINXPQ.js";
|
|
206
|
+
} from "./chunk-PF6O3GR3.js";
|
|
206
207
|
import "./chunk-ZNFJWEN4.js";
|
|
207
|
-
import "./chunk-
|
|
208
|
-
import "./chunk-
|
|
208
|
+
import "./chunk-NFT2AOK5.js";
|
|
209
|
+
import "./chunk-FMODTASJ.js";
|
|
210
|
+
import "./chunk-AX7RMXSH.js";
|
|
211
|
+
import "./chunk-CQ3WA2NE.js";
|
|
209
212
|
import "./chunk-N7J63Q6C.js";
|
|
210
213
|
import {
|
|
211
214
|
buildIdentityBlock,
|
|
212
215
|
buildRuntimeGuidanceBlocks,
|
|
213
216
|
resolveToolGuidedSections
|
|
214
|
-
} from "./chunk-
|
|
217
|
+
} from "./chunk-ETLZZQJE.js";
|
|
215
218
|
import "./chunk-PUOC4YRO.js";
|
|
216
|
-
import "./chunk-
|
|
217
|
-
import {
|
|
218
|
-
resolvePlatformAuthToken
|
|
219
|
-
} from "./chunk-CMH2SYHX.js";
|
|
220
|
-
import "./chunk-V3ZKNK5D.js";
|
|
219
|
+
import "./chunk-ZVN6I33J.js";
|
|
221
220
|
import {
|
|
222
221
|
isQuotaExhaustedError
|
|
223
222
|
} from "./chunk-CJCJF5XB.js";
|
|
223
|
+
import "./chunk-LHDV2QUI.js";
|
|
224
|
+
import {
|
|
225
|
+
resolvePlatformAuthToken
|
|
226
|
+
} from "./chunk-TMPLPCVX.js";
|
|
224
227
|
import "./chunk-2MBTWINN.js";
|
|
225
228
|
import {
|
|
226
229
|
DEFAULT_CONTEXT_WINDOW,
|
|
227
230
|
getModelContextWindow,
|
|
228
231
|
normalizeUsage
|
|
229
|
-
} from "./chunk-
|
|
232
|
+
} from "./chunk-7QVPPOEC.js";
|
|
230
233
|
import {
|
|
231
234
|
buildCompactionMetricsFromPlan,
|
|
232
235
|
buildCompactionUserContent,
|
|
@@ -237,12 +240,12 @@ import {
|
|
|
237
240
|
planCompression,
|
|
238
241
|
serializeMessageContent
|
|
239
242
|
} from "./chunk-E36HZARC.js";
|
|
240
|
-
import "./chunk-
|
|
243
|
+
import "./chunk-PZCTYKGU.js";
|
|
241
244
|
import {
|
|
242
245
|
estimateTokenCount
|
|
243
246
|
} from "./chunk-PSCNXBYA.js";
|
|
244
247
|
import "./chunk-BYXBJQAS.js";
|
|
245
|
-
import "./chunk-
|
|
248
|
+
import "./chunk-MXUSPS2N.js";
|
|
246
249
|
import {
|
|
247
250
|
compactWhitespace
|
|
248
251
|
} from "./chunk-DWLEOOGR.js";
|
|
@@ -346,7 +349,7 @@ import { stdin as defaultInput, stdout as defaultOutput } from "node:process";
|
|
|
346
349
|
import nacl from "tweetnacl";
|
|
347
350
|
|
|
348
351
|
// node_modules/js-base64/base64.mjs
|
|
349
|
-
var version = "3.9.
|
|
352
|
+
var version = "3.9.4";
|
|
350
353
|
var VERSION = version;
|
|
351
354
|
var _TD = typeof TextDecoder === "function" ? new TextDecoder("utf-8", { ignoreBOM: true }) : void 0;
|
|
352
355
|
var _TE = typeof TextEncoder === "function" ? new TextEncoder() : void 0;
|
|
@@ -1655,13 +1658,14 @@ function layoutTurnRows(role, content, contentWidth, colorEnabled, command) {
|
|
|
1655
1658
|
const surfaceSeq = colorEnabled ? userSurfaceBackgroundSequence() : "";
|
|
1656
1659
|
const boldOn = colorEnabled ? "\x1B[1m" : "";
|
|
1657
1660
|
const boldOff = colorEnabled ? "\x1B[22m" : "";
|
|
1661
|
+
const fgOff = colorEnabled ? "\x1B[39m" : "";
|
|
1658
1662
|
const prefixWidth = 3;
|
|
1659
1663
|
let lineSourceStart = 0;
|
|
1660
1664
|
const rows2 = [];
|
|
1661
1665
|
for (let i = 0; i < logicalLines.length; i++) {
|
|
1662
1666
|
const line = logicalLines[i];
|
|
1663
1667
|
const prefix = i === 0 ? firstPrefix : multilinePrefix;
|
|
1664
|
-
const styledLine = `${prefix}${boldOn}${line}${boldOff}`;
|
|
1668
|
+
const styledLine = `${prefix}${accentSeq}${boldOn}${line}${boldOff}${fgOff}`;
|
|
1665
1669
|
const prefixCharCount = prefix.length;
|
|
1666
1670
|
const wrappedRows = wrapTranscriptLineWithLayout(
|
|
1667
1671
|
styledLine,
|
|
@@ -1854,9 +1858,10 @@ function renderTailTurnBlock(role, content, contentWidth, colorEnabled) {
|
|
|
1854
1858
|
const hangingIndent = colorEnabled ? `${accentSeq}\x1B[1m\u2503 \x1B[0m` : "\u2503 ";
|
|
1855
1859
|
const boldOn = colorEnabled ? "\x1B[1m" : "";
|
|
1856
1860
|
const boldOff = colorEnabled ? "\x1B[22m" : "";
|
|
1861
|
+
const fgOff = colorEnabled ? "\x1B[39m" : "";
|
|
1857
1862
|
const lines = [];
|
|
1858
1863
|
for (const rawLine of content.split("\n")) {
|
|
1859
|
-
const styledLine = `${multilinePrefix}${boldOn}${rawLine}${boldOff}`;
|
|
1864
|
+
const styledLine = `${multilinePrefix}${accentSeq}${boldOn}${rawLine}${boldOff}${fgOff}`;
|
|
1860
1865
|
const rows = wrapTranscriptLine(styledLine, contentWidth, hangingIndent);
|
|
1861
1866
|
lines.push(
|
|
1862
1867
|
...surfaceSeq ? rows.map((row) => fillUserBubbleRow(row, surfaceSeq, contentWidth)) : rows
|
|
@@ -4502,6 +4507,36 @@ function detectImagePaths(line, cwd, opts = {}) {
|
|
|
4502
4507
|
}
|
|
4503
4508
|
return out;
|
|
4504
4509
|
}
|
|
4510
|
+
function detectFileReferences(line, cwd, opts = {}) {
|
|
4511
|
+
const wsl = opts.wsl ?? isWslEnvironment();
|
|
4512
|
+
const excluded = new Set(opts.exclude ?? []);
|
|
4513
|
+
const out = [];
|
|
4514
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4515
|
+
for (const token of tokenizePasteLine(line)) {
|
|
4516
|
+
if (!token.raw || excluded.has(token.raw)) continue;
|
|
4517
|
+
let candidate = token.decoded;
|
|
4518
|
+
const uriPath = fileUriToPath(candidate);
|
|
4519
|
+
if (uriPath !== null) candidate = uriPath;
|
|
4520
|
+
if (wsl) candidate = mapWindowsPathToWsl(candidate);
|
|
4521
|
+
if (candidate.startsWith("~")) candidate = resolveImageSource(candidate, cwd);
|
|
4522
|
+
const looksLikePath = /[/\\]/.test(candidate) || candidate.startsWith("~") || /^[a-zA-Z]:/.test(candidate);
|
|
4523
|
+
if (!looksLikePath) continue;
|
|
4524
|
+
const ext = extnameOf(candidate);
|
|
4525
|
+
if (!/^[a-z0-9]{1,8}$/.test(ext)) continue;
|
|
4526
|
+
if (IMAGE_EXTENSION_SET.has(ext)) continue;
|
|
4527
|
+
const resolved = resolveImageSource(candidate, cwd);
|
|
4528
|
+
if (excluded.has(resolved) || seen.has(resolved)) continue;
|
|
4529
|
+
if (!isReadableFilePath(resolved)) continue;
|
|
4530
|
+
try {
|
|
4531
|
+
if (!statSync(resolved).isFile()) continue;
|
|
4532
|
+
} catch {
|
|
4533
|
+
continue;
|
|
4534
|
+
}
|
|
4535
|
+
seen.add(resolved);
|
|
4536
|
+
out.push({ raw: token.raw, resolvedPath: resolved });
|
|
4537
|
+
}
|
|
4538
|
+
return out;
|
|
4539
|
+
}
|
|
4505
4540
|
function tokenizePasteLine(line) {
|
|
4506
4541
|
const tokens = [];
|
|
4507
4542
|
let rawBuf = "";
|
|
@@ -5004,22 +5039,69 @@ async function readClipboardImage(deps = {}) {
|
|
|
5004
5039
|
});
|
|
5005
5040
|
}
|
|
5006
5041
|
|
|
5042
|
+
// packages/cli/tui/pasteFlow.ts
|
|
5043
|
+
function isTextFallbackEligibleCode(code) {
|
|
5044
|
+
return code === "empty-clipboard" || code === "binary-missing" || code === "unsupported-platform";
|
|
5045
|
+
}
|
|
5046
|
+
function errorCodeOf(error) {
|
|
5047
|
+
if (typeof error !== "object" || error === null) return void 0;
|
|
5048
|
+
const code = error.code;
|
|
5049
|
+
return code === void 0 || code === null ? void 0 : String(code);
|
|
5050
|
+
}
|
|
5051
|
+
function messageOf(error) {
|
|
5052
|
+
return error instanceof Error ? error.message : String(error);
|
|
5053
|
+
}
|
|
5054
|
+
async function resolveClipboardPaste(deps) {
|
|
5055
|
+
try {
|
|
5056
|
+
const image = await deps.readImage();
|
|
5057
|
+
return { kind: "image", image };
|
|
5058
|
+
} catch (imageError) {
|
|
5059
|
+
const code = errorCodeOf(imageError);
|
|
5060
|
+
if (!isTextFallbackEligibleCode(code)) {
|
|
5061
|
+
return {
|
|
5062
|
+
kind: "error",
|
|
5063
|
+
code: code ?? "read-failed",
|
|
5064
|
+
message: messageOf(imageError)
|
|
5065
|
+
};
|
|
5066
|
+
}
|
|
5067
|
+
let text;
|
|
5068
|
+
try {
|
|
5069
|
+
text = await deps.readText();
|
|
5070
|
+
} catch (textError) {
|
|
5071
|
+
return {
|
|
5072
|
+
kind: "error",
|
|
5073
|
+
code: "text-read-failed",
|
|
5074
|
+
message: `${messageOf(textError)} (${messageOf(imageError)})`
|
|
5075
|
+
};
|
|
5076
|
+
}
|
|
5077
|
+
if (text.length > 0) {
|
|
5078
|
+
return { kind: "text", text };
|
|
5079
|
+
}
|
|
5080
|
+
return { kind: "empty", message: messageOf(imageError) };
|
|
5081
|
+
}
|
|
5082
|
+
}
|
|
5083
|
+
function shouldApplyPastedResult(snapshot, current) {
|
|
5084
|
+
if (current.sessionEnded) return false;
|
|
5085
|
+
return snapshot.epoch === current.epoch;
|
|
5086
|
+
}
|
|
5087
|
+
|
|
5007
5088
|
// packages/cli/tui/clipboard.ts
|
|
5008
5089
|
function osc52SetClipboard(text, output) {
|
|
5009
5090
|
const payload = Buffer.from(text, "utf8").toString("base64");
|
|
5010
5091
|
output.write(`\x1B]52;c;${payload}\x07`);
|
|
5011
5092
|
}
|
|
5012
5093
|
async function writeClipboard(text, target) {
|
|
5013
|
-
|
|
5094
|
+
if (target.transport === "system") {
|
|
5014
5095
|
await target.systemWrite(text);
|
|
5015
|
-
|
|
5096
|
+
return;
|
|
5016
5097
|
}
|
|
5017
|
-
if (target.
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
} catch {
|
|
5021
|
-
}
|
|
5098
|
+
if (target.transport === "osc52") {
|
|
5099
|
+
osc52SetClipboard(text, target.output);
|
|
5100
|
+
return;
|
|
5022
5101
|
}
|
|
5102
|
+
throw new Error(
|
|
5103
|
+
"Client clipboard is unavailable in a non-interactive remote session."
|
|
5104
|
+
);
|
|
5023
5105
|
}
|
|
5024
5106
|
|
|
5025
5107
|
// packages/cli/tui/gitStatus.ts
|
|
@@ -5633,6 +5715,7 @@ var SLASH_COMMANDS = [
|
|
|
5633
5715
|
"/resume",
|
|
5634
5716
|
"/lang",
|
|
5635
5717
|
"/copy",
|
|
5718
|
+
"/paste",
|
|
5636
5719
|
"/mouse",
|
|
5637
5720
|
"/math",
|
|
5638
5721
|
"/doc",
|
|
@@ -5989,12 +6072,18 @@ function handleTuiInput(input, state) {
|
|
|
5989
6072
|
const stripped = stripImageTokens(trimmed, readableHints);
|
|
5990
6073
|
const finalMessage = stripped.length > 0 ? stripped : trimmed;
|
|
5991
6074
|
const imagePaths = readableHints.map((hint) => hint.resolvedPath);
|
|
5992
|
-
const
|
|
5993
|
-
(hint) => hint.
|
|
5994
|
-
)
|
|
6075
|
+
const fileRefs = detectFileReferences(trimmed, state.cwd, {
|
|
6076
|
+
exclude: hints.map((hint) => hint.resolvedPath)
|
|
6077
|
+
});
|
|
6078
|
+
const previewLines = [
|
|
6079
|
+
...hints.map(
|
|
6080
|
+
(hint) => hint.unreadable ? `image path unreadable: ${hint.resolvedPath}` : `found image: ${hint.resolvedPath}`
|
|
6081
|
+
),
|
|
6082
|
+
...fileRefs.map((ref) => t("pasteFilePathHint", ref.resolvedPath))
|
|
6083
|
+
];
|
|
5995
6084
|
return {
|
|
5996
6085
|
nextState: state,
|
|
5997
|
-
output:
|
|
6086
|
+
output: previewLines.join("\n"),
|
|
5998
6087
|
action: {
|
|
5999
6088
|
type: "chat",
|
|
6000
6089
|
message: finalMessage,
|
|
@@ -6341,6 +6430,15 @@ ${t("autoUsage")}`
|
|
|
6341
6430
|
}
|
|
6342
6431
|
return { nextState: state, output: t("copyUsage") };
|
|
6343
6432
|
}
|
|
6433
|
+
case "/paste":
|
|
6434
|
+
if (argText) {
|
|
6435
|
+
return { nextState: state, output: t("pasteUsage") };
|
|
6436
|
+
}
|
|
6437
|
+
return {
|
|
6438
|
+
nextState: state,
|
|
6439
|
+
output: "",
|
|
6440
|
+
action: { type: "paste-clipboard" }
|
|
6441
|
+
};
|
|
6344
6442
|
case "/mouse": {
|
|
6345
6443
|
if (argText !== "on" && argText !== "off") {
|
|
6346
6444
|
return { nextState: state, output: t("mouseUsage") };
|
|
@@ -6653,13 +6751,45 @@ function createTurnInjectionInbox() {
|
|
|
6653
6751
|
|
|
6654
6752
|
// packages/cli/tui/processTerminalNotice.ts
|
|
6655
6753
|
function formatProcessTerminalWakeMessage(notices) {
|
|
6754
|
+
const missingCapsule = notices.some((notice) => !notice.resultCapsule);
|
|
6656
6755
|
return [
|
|
6657
6756
|
`<background_task_completion count="${notices.length}">`,
|
|
6658
|
-
...notices.
|
|
6659
|
-
|
|
6757
|
+
...notices.flatMap((notice) => [
|
|
6758
|
+
formatProcessTerminalNoticeLine(notice),
|
|
6759
|
+
...notice.resultCapsule ? formatProcessResultCapsuleLines(notice.resultCapsule) : []
|
|
6760
|
+
]),
|
|
6761
|
+
...missingCapsule ? ["\u751F\u547D\u5468\u671F\u8BE6\u60C5\u53EF\u7528 taskLogs(taskId)"] : [],
|
|
6660
6762
|
`</background_task_completion>`
|
|
6661
6763
|
].join("\n");
|
|
6662
6764
|
}
|
|
6765
|
+
function formatProcessResultCapsuleLines(capsule) {
|
|
6766
|
+
const meta = [];
|
|
6767
|
+
if (capsule.durationMs !== void 0) meta.push(`duration=${capsule.durationMs}ms`);
|
|
6768
|
+
meta.push(capsule.truncated ? "tail-only" : "full");
|
|
6769
|
+
const stream = (name, value) => [
|
|
6770
|
+
`--- ${name} ---`,
|
|
6771
|
+
...value.trim() ? value.replace(/\n+$/, "").split("\n") : ["(empty)"]
|
|
6772
|
+
];
|
|
6773
|
+
const omittedChars = capsule.spill ? Math.max(0, capsule.spill.totalChars - capsule.stdout.length - capsule.stderr.length) : 0;
|
|
6774
|
+
return [
|
|
6775
|
+
`result capsule (${meta.join(", ")}):`,
|
|
6776
|
+
...capsule.captureError ? [`capture error: ${capsule.captureError}`] : [],
|
|
6777
|
+
...stream("stdout", capsule.stdout),
|
|
6778
|
+
...stream("stderr", capsule.stderr),
|
|
6779
|
+
// Retrieval pointer reuses the tool-overflow convention: the model learns
|
|
6780
|
+
// one marker for "the tail above is not the whole story, full text lives
|
|
6781
|
+
// here", whether the truncation happened in a foreground tool result or in
|
|
6782
|
+
// a detached task capsule.
|
|
6783
|
+
...capsule.spill ? [
|
|
6784
|
+
formatToolOverflowMarker({
|
|
6785
|
+
spillRef: capsule.spill.displayPath,
|
|
6786
|
+
totalChars: capsule.spill.totalChars,
|
|
6787
|
+
totalLines: capsule.spill.totalLines,
|
|
6788
|
+
omittedChars
|
|
6789
|
+
}).trim()
|
|
6790
|
+
] : []
|
|
6791
|
+
];
|
|
6792
|
+
}
|
|
6663
6793
|
function formatProcessTerminalNoticeLine(notice) {
|
|
6664
6794
|
const informative = notice.label && notice.label.trim() !== "" && notice.label !== notice.command;
|
|
6665
6795
|
const label = informative ? ` (label: "${notice.label.replace(/(["\\])/g, "\\$1")}")` : "";
|
|
@@ -6670,7 +6800,30 @@ function buildProcessTerminalTurnMessage(notices) {
|
|
|
6670
6800
|
if (notices.length === 0) return "";
|
|
6671
6801
|
return formatProcessTerminalWakeMessage(notices);
|
|
6672
6802
|
}
|
|
6803
|
+
function buildProcessTaskCompletedTurnEvent(notice) {
|
|
6804
|
+
return {
|
|
6805
|
+
kind: "background-task-completed",
|
|
6806
|
+
taskId: notice.taskId,
|
|
6807
|
+
status: notice.status,
|
|
6808
|
+
...notice.exitCode !== void 0 ? { exitCode: notice.exitCode } : {},
|
|
6809
|
+
text: buildProcessTerminalTurnMessage([notice]),
|
|
6810
|
+
displayText: formatProcessTerminalNoticeLine(notice)
|
|
6811
|
+
};
|
|
6812
|
+
}
|
|
6813
|
+
var PENDING_NOTICE_PREFIX = "process-notice-v1:";
|
|
6814
|
+
function serializePendingProcessNotice(notice) {
|
|
6815
|
+
return notice.resultCapsule ? `${PENDING_NOTICE_PREFIX}${JSON.stringify(notice)}` : formatProcessTerminalNoticeLine(notice);
|
|
6816
|
+
}
|
|
6673
6817
|
function parsePendingProcessNoticeLine(line) {
|
|
6818
|
+
if (line.startsWith(PENDING_NOTICE_PREFIX)) {
|
|
6819
|
+
try {
|
|
6820
|
+
const parsed = JSON.parse(line.slice(PENDING_NOTICE_PREFIX.length));
|
|
6821
|
+
if (parsed && typeof parsed.taskId === "string" && parsed.resultCapsule) {
|
|
6822
|
+
return parsed;
|
|
6823
|
+
}
|
|
6824
|
+
} catch {
|
|
6825
|
+
}
|
|
6826
|
+
}
|
|
6674
6827
|
const taskMatch = line.match(
|
|
6675
6828
|
/^\[Background task ([^ \]]+?)(?:\s+\(label: "((?:[^"\\]|\\.)*)"\))? finished: status=(\w+)(?: exitCode=(-?\d+))?\]$/
|
|
6676
6829
|
);
|
|
@@ -6702,6 +6855,80 @@ function normalizeStatus(raw) {
|
|
|
6702
6855
|
return "failed";
|
|
6703
6856
|
}
|
|
6704
6857
|
|
|
6858
|
+
// packages/agent-runtime/processTerminalResume.ts
|
|
6859
|
+
var DEFAULT_MAX_CHAINED_COMPLETION_TURNS = 3;
|
|
6860
|
+
function createProcessTerminalResumeState() {
|
|
6861
|
+
const claimedTaskIds = /* @__PURE__ */ new Set();
|
|
6862
|
+
const chainDepthByDialog = /* @__PURE__ */ new Map();
|
|
6863
|
+
return {
|
|
6864
|
+
claimedTaskIds,
|
|
6865
|
+
chainDepthByDialog,
|
|
6866
|
+
noteUserTurn() {
|
|
6867
|
+
chainDepthByDialog.clear();
|
|
6868
|
+
}
|
|
6869
|
+
};
|
|
6870
|
+
}
|
|
6871
|
+
var resolveCap = (value) => {
|
|
6872
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 1) {
|
|
6873
|
+
return DEFAULT_MAX_CHAINED_COMPLETION_TURNS;
|
|
6874
|
+
}
|
|
6875
|
+
return Math.floor(value);
|
|
6876
|
+
};
|
|
6877
|
+
function decideProcessTerminalResume(input) {
|
|
6878
|
+
const taskId = input.notice.taskId;
|
|
6879
|
+
if (input.canDeliver === false) {
|
|
6880
|
+
return { kind: "notice-only", reason: "no-channel", taskId };
|
|
6881
|
+
}
|
|
6882
|
+
const dialogId = input.owner?.dialogId;
|
|
6883
|
+
if (!input.owner || !dialogId) {
|
|
6884
|
+
return { kind: "notice-only", reason: "unowned", taskId };
|
|
6885
|
+
}
|
|
6886
|
+
if (!input.notice.promoted) {
|
|
6887
|
+
return { kind: "notice-only", reason: "not-promoted", taskId };
|
|
6888
|
+
}
|
|
6889
|
+
if (input.state.claimedTaskIds.has(taskId)) {
|
|
6890
|
+
return { kind: "notice-only", reason: "duplicate", taskId };
|
|
6891
|
+
}
|
|
6892
|
+
const currentDialogId = input.currentDialogId ?? null;
|
|
6893
|
+
if (currentDialogId !== dialogId) {
|
|
6894
|
+
return { kind: "notice-only", reason: "dialog-mismatch", taskId };
|
|
6895
|
+
}
|
|
6896
|
+
if (input.turnActive) {
|
|
6897
|
+
input.state.claimedTaskIds.add(taskId);
|
|
6898
|
+
return { kind: "inject-turn", taskId, owner: input.owner, notice: input.notice };
|
|
6899
|
+
}
|
|
6900
|
+
const cap = resolveCap(input.maxChainedCompletionTurns);
|
|
6901
|
+
const depth = input.state.chainDepthByDialog.get(dialogId) ?? 0;
|
|
6902
|
+
if (depth >= cap) {
|
|
6903
|
+
return { kind: "notice-only", reason: "chain-cap", taskId };
|
|
6904
|
+
}
|
|
6905
|
+
input.state.claimedTaskIds.add(taskId);
|
|
6906
|
+
input.state.chainDepthByDialog.set(dialogId, depth + 1);
|
|
6907
|
+
return { kind: "completion-turn", taskId, owner: input.owner, notice: input.notice };
|
|
6908
|
+
}
|
|
6909
|
+
function createProcessTerminalAutoResumer(deps) {
|
|
6910
|
+
const state = createProcessTerminalResumeState();
|
|
6911
|
+
return {
|
|
6912
|
+
state,
|
|
6913
|
+
noteUserTurn: () => state.noteUserTurn(),
|
|
6914
|
+
decide: (notice) => {
|
|
6915
|
+
const promoted = notice.promoted ?? deps.isPromoted?.(notice.taskId) ?? false;
|
|
6916
|
+
const effectiveNotice = notice.promoted === promoted ? notice : { ...notice, promoted };
|
|
6917
|
+
const decision = decideProcessTerminalResume({
|
|
6918
|
+
notice: effectiveNotice,
|
|
6919
|
+
owner: deps.readOwner(notice.taskId),
|
|
6920
|
+
currentDialogId: deps.getCurrentDialogId(),
|
|
6921
|
+
turnActive: deps.isTurnActive(),
|
|
6922
|
+
state,
|
|
6923
|
+
...deps.canDeliver ? { canDeliver: deps.canDeliver() } : {},
|
|
6924
|
+
...deps.maxChainedCompletionTurns === void 0 ? {} : { maxChainedCompletionTurns: deps.maxChainedCompletionTurns }
|
|
6925
|
+
});
|
|
6926
|
+
deps.onDecision?.(decision);
|
|
6927
|
+
return decision;
|
|
6928
|
+
}
|
|
6929
|
+
};
|
|
6930
|
+
}
|
|
6931
|
+
|
|
6705
6932
|
// packages/cli/client/turnBillingAudit.ts
|
|
6706
6933
|
import { appendFileSync, mkdirSync as mkdirSync2 } from "node:fs";
|
|
6707
6934
|
import { homedir as homedir4 } from "node:os";
|
|
@@ -7504,6 +7731,8 @@ async function runAskChoiceDialog(args) {
|
|
|
7504
7731
|
// packages/chat/messages/contextualFragment.ts
|
|
7505
7732
|
var BACKGROUND_RUN_OPEN = "<background_run_completion";
|
|
7506
7733
|
var BACKGROUND_RUN_CLOSE = "</background_run_completion>";
|
|
7734
|
+
var BACKGROUND_TASK_OPEN = "<background_task_completion";
|
|
7735
|
+
var BACKGROUND_TASK_CLOSE = "</background_task_completion>";
|
|
7507
7736
|
var SERVER_LEGACY_PREFIX = "--- \u540E\u53F0 run \u7EC8\u6001\u4E8B\u4EF6 ---";
|
|
7508
7737
|
var TUI_LEGACY_PREFIX = "\u3010\u540E\u53F0 run \u7EC8\u6001\u901A\u77E5\u3011";
|
|
7509
7738
|
var TIME_BLOCK_PREFIX = "--- \u5F53\u524D\u65F6\u95F4 ---";
|
|
@@ -7518,6 +7747,13 @@ var registry = [
|
|
|
7518
7747
|
return trimmed.startsWith(BACKGROUND_RUN_OPEN) && trimmed.endsWith(BACKGROUND_RUN_CLOSE);
|
|
7519
7748
|
}
|
|
7520
7749
|
},
|
|
7750
|
+
{
|
|
7751
|
+
kind: "background_task_completion",
|
|
7752
|
+
match: (text) => {
|
|
7753
|
+
const trimmed = text.trim();
|
|
7754
|
+
return trimmed.startsWith(BACKGROUND_TASK_OPEN) && trimmed.endsWith(BACKGROUND_TASK_CLOSE);
|
|
7755
|
+
}
|
|
7756
|
+
},
|
|
7521
7757
|
{
|
|
7522
7758
|
kind: "server_legacy_wake",
|
|
7523
7759
|
match: (text) => {
|
|
@@ -8217,6 +8453,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
|
|
|
8217
8453
|
}
|
|
8218
8454
|
}
|
|
8219
8455
|
const message = req.text;
|
|
8456
|
+
if (req.event.kind === "user") ctx.noteUserTurn?.();
|
|
8220
8457
|
ctx.forcedStop = false;
|
|
8221
8458
|
ctx.turnEpoch += 1;
|
|
8222
8459
|
const myEpoch = ctx.turnEpoch;
|
|
@@ -8224,7 +8461,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
|
|
|
8224
8461
|
ctx.history.followBottom = true;
|
|
8225
8462
|
const isInternalEvent = req.event.kind !== "user";
|
|
8226
8463
|
const isContextualFragment = matchContextualFragment(message) !== null;
|
|
8227
|
-
const transcriptText = isContextualFragment && req.event.kind === "child-run-completed" ? req.event.displayText ?? req.event.text : message;
|
|
8464
|
+
const transcriptText = isContextualFragment && (req.event.kind === "child-run-completed" || req.event.kind === "background-task-completed") ? req.event.displayText ?? req.event.text : message;
|
|
8228
8465
|
startTurn(ctx.history, isInternalEvent ? "assistant" : "user");
|
|
8229
8466
|
appendToCurrentTurn(
|
|
8230
8467
|
ctx.history,
|
|
@@ -8525,6 +8762,8 @@ function createTuiRender(host) {
|
|
|
8525
8762
|
// packages/cli/tui/tuiScrollAnimation.ts
|
|
8526
8763
|
var SCROLL_ANIMATION_TICK_MS = 16;
|
|
8527
8764
|
var DEFAULT_SCROLL_MAX_LINES_PER_TICK = 6;
|
|
8765
|
+
var ADAPTIVE_STEP_CAP = 20;
|
|
8766
|
+
var EXPLICIT_STEP_CAP = 100;
|
|
8528
8767
|
function readPositiveInt(raw, fallback, max) {
|
|
8529
8768
|
if (raw === void 0 || raw.trim() === "") return fallback;
|
|
8530
8769
|
const parsed = Number.parseInt(raw, 10);
|
|
@@ -8532,15 +8771,20 @@ function readPositiveInt(raw, fallback, max) {
|
|
|
8532
8771
|
return Math.min(parsed, max);
|
|
8533
8772
|
}
|
|
8534
8773
|
function resolveScrollTuning(env = process.env) {
|
|
8774
|
+
const rawStep = env.NOLO_TUI_SCROLL_MAX_STEP;
|
|
8775
|
+
const explicit = parseExplicitStep(rawStep);
|
|
8535
8776
|
return {
|
|
8536
8777
|
wheelLines: readPositiveInt(env.NOLO_TUI_WHEEL_LINES, WHEEL_SCROLL_LINES, 50),
|
|
8537
|
-
maxLinesPerTick:
|
|
8538
|
-
|
|
8539
|
-
DEFAULT_SCROLL_MAX_LINES_PER_TICK,
|
|
8540
|
-
100
|
|
8541
|
-
)
|
|
8778
|
+
maxLinesPerTick: explicit ?? DEFAULT_SCROLL_MAX_LINES_PER_TICK,
|
|
8779
|
+
adaptiveStep: explicit === null
|
|
8542
8780
|
};
|
|
8543
8781
|
}
|
|
8782
|
+
function parseExplicitStep(raw) {
|
|
8783
|
+
if (raw === void 0 || raw.trim() === "") return null;
|
|
8784
|
+
const parsed = Number.parseInt(raw, 10);
|
|
8785
|
+
if (!Number.isFinite(parsed) || parsed < 1) return null;
|
|
8786
|
+
return Math.min(parsed, EXPLICIT_STEP_CAP);
|
|
8787
|
+
}
|
|
8544
8788
|
var defaultTickTimer = {
|
|
8545
8789
|
every(ms, fn) {
|
|
8546
8790
|
const handle = setInterval(fn, ms);
|
|
@@ -8549,9 +8793,10 @@ var defaultTickTimer = {
|
|
|
8549
8793
|
}
|
|
8550
8794
|
};
|
|
8551
8795
|
function createScrollAnimator(deps) {
|
|
8552
|
-
const { wheelLines, maxLinesPerTick } = resolveScrollTuning(
|
|
8796
|
+
const { wheelLines, maxLinesPerTick, adaptiveStep } = resolveScrollTuning(
|
|
8553
8797
|
deps.env ?? process.env
|
|
8554
8798
|
);
|
|
8799
|
+
const stepCap = adaptiveStep ? Math.max(ADAPTIVE_STEP_CAP, wheelLines) : maxLinesPerTick;
|
|
8555
8800
|
const timer = deps.tickTimer ?? defaultTickTimer;
|
|
8556
8801
|
const history = deps.history;
|
|
8557
8802
|
let goal = null;
|
|
@@ -8589,7 +8834,17 @@ function createScrollAnimator(deps) {
|
|
|
8589
8834
|
settle(maxScrollTop);
|
|
8590
8835
|
return;
|
|
8591
8836
|
}
|
|
8592
|
-
const
|
|
8837
|
+
const backlog = Math.abs(delta);
|
|
8838
|
+
const limit = adaptiveStep ? Math.min(
|
|
8839
|
+
backlog,
|
|
8840
|
+
Math.max(
|
|
8841
|
+
DEFAULT_SCROLL_MAX_LINES_PER_TICK,
|
|
8842
|
+
wheelLines,
|
|
8843
|
+
Math.ceil(backlog / 4)
|
|
8844
|
+
),
|
|
8845
|
+
stepCap
|
|
8846
|
+
) : Math.min(backlog, maxLinesPerTick);
|
|
8847
|
+
const step = Math.sign(delta) * limit;
|
|
8593
8848
|
history.scrollTop += step;
|
|
8594
8849
|
deps.onPaint();
|
|
8595
8850
|
if (history.scrollTop === goal) {
|
|
@@ -9743,6 +9998,8 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
9743
9998
|
persistExplicitAgentSwitch,
|
|
9744
9999
|
persistAgentSelection: persistAgentSelection2,
|
|
9745
10000
|
writeClipboard: writeClipboard2,
|
|
10001
|
+
readAndApplyClipboard,
|
|
10002
|
+
bumpDraftEpoch,
|
|
9746
10003
|
selfUpdater,
|
|
9747
10004
|
spawnRunner,
|
|
9748
10005
|
installAltScreenRestoreHandlers: installAltScreenRestoreHandlers2
|
|
@@ -9751,9 +10008,12 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
9751
10008
|
const previousAgentKey = host.state.agentKey;
|
|
9752
10009
|
host.state = result.nextState;
|
|
9753
10010
|
const interactive = isInteractiveInput(input);
|
|
10011
|
+
const isChatAction = result.action?.type === "chat";
|
|
9754
10012
|
if (result.action?.type !== "exit" && result.output) {
|
|
9755
|
-
|
|
9756
|
-
|
|
10013
|
+
emitCommandOutput(
|
|
10014
|
+
result.output,
|
|
10015
|
+
interactive && !isChatAction ? line.trim() : ""
|
|
10016
|
+
);
|
|
9757
10017
|
}
|
|
9758
10018
|
if (host.state.agentKey !== previousAgentKey) {
|
|
9759
10019
|
persistExplicitAgentSwitch(previousAgentKey);
|
|
@@ -9784,6 +10044,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
9784
10044
|
}
|
|
9785
10045
|
}
|
|
9786
10046
|
clearCollapsedPasteStore(pasteStore);
|
|
10047
|
+
bumpDraftEpoch();
|
|
9787
10048
|
host.state = {
|
|
9788
10049
|
...host.state,
|
|
9789
10050
|
turnTokens: void 0,
|
|
@@ -10044,6 +10305,9 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
10044
10305
|
}
|
|
10045
10306
|
}
|
|
10046
10307
|
}
|
|
10308
|
+
if (result.action?.type === "paste-clipboard") {
|
|
10309
|
+
await readAndApplyClipboard("slash");
|
|
10310
|
+
}
|
|
10047
10311
|
if (result.action?.type === "pick-dialog") {
|
|
10048
10312
|
const interactivePicker = isInteractiveInput(input);
|
|
10049
10313
|
try {
|
|
@@ -10086,6 +10350,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
10086
10350
|
};
|
|
10087
10351
|
seedDialogCreditsBase(pickResult.dialog.id, pickResult.dialog.dbKey);
|
|
10088
10352
|
clearCollapsedPasteStore(pasteStore);
|
|
10353
|
+
bumpDraftEpoch();
|
|
10089
10354
|
emitCommandOutput(
|
|
10090
10355
|
`${t("resumedDialogPrefix")}: ${pickResult.dialog.title} (${pickResult.dialog.id})`
|
|
10091
10356
|
);
|
|
@@ -10325,7 +10590,7 @@ var WELCOME_ANIM_MAX_FRAME = 8;
|
|
|
10325
10590
|
var WELCOME_ANIM_INTERVAL_MS = 70;
|
|
10326
10591
|
function isClipboardImageFallbackEligible(error) {
|
|
10327
10592
|
const code = error instanceof ClipboardImageError ? error.code : typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0;
|
|
10328
|
-
return code
|
|
10593
|
+
return isTextFallbackEligibleCode(code);
|
|
10329
10594
|
}
|
|
10330
10595
|
async function runTuiWorkspace(options) {
|
|
10331
10596
|
const startupThemeMode = resolveTuiThemeMode(
|
|
@@ -10352,7 +10617,12 @@ async function runTuiWorkspace(options) {
|
|
|
10352
10617
|
await clipboard.write(t2);
|
|
10353
10618
|
},
|
|
10354
10619
|
output,
|
|
10355
|
-
|
|
10620
|
+
// Local sessions have direct access to the user's OS clipboard and
|
|
10621
|
+
// must not enqueue a redundant OSC 52 write behind it: that late
|
|
10622
|
+
// terminal-side write can overwrite a newer browser copy. Over SSH,
|
|
10623
|
+
// OSC 52 remains the only path to the client clipboard; a pipe/non-
|
|
10624
|
+
// interactive remote session has no valid client clipboard channel.
|
|
10625
|
+
transport: isRemoteSession(runtimeEnv) ? isInteractiveInput(input) ? "osc52" : "unavailable" : "system"
|
|
10356
10626
|
});
|
|
10357
10627
|
const readClipboardText = options.clipboardReader ?? (async () => {
|
|
10358
10628
|
const { default: clipboard } = await import("./clipboardy-BX4NMYHE.js");
|
|
@@ -10439,16 +10709,17 @@ async function runTuiWorkspace(options) {
|
|
|
10439
10709
|
});
|
|
10440
10710
|
const pushPendingProcessNotice = (notice) => {
|
|
10441
10711
|
if (sessionEnded) return;
|
|
10442
|
-
const line =
|
|
10712
|
+
const line = serializePendingProcessNotice(notice);
|
|
10443
10713
|
state = {
|
|
10444
10714
|
...state,
|
|
10445
10715
|
pendingProcessNotices: [...state.pendingProcessNotices ?? [], line]
|
|
10446
10716
|
};
|
|
10447
10717
|
scheduleRender();
|
|
10448
10718
|
};
|
|
10449
|
-
|
|
10450
|
-
|
|
10451
|
-
|
|
10719
|
+
let deliverProcessTerminalNotice = pushPendingProcessNotice;
|
|
10720
|
+
const unsubscribeProcessTerminal = getProcessRegistry().onProcessTerminal((notice) => {
|
|
10721
|
+
deliverProcessTerminalNotice(notice);
|
|
10722
|
+
});
|
|
10452
10723
|
const effectiveEnv = options.env ? { ...process.env, ...options.env } : process.env;
|
|
10453
10724
|
const runRegistryPoller = createRunRegistryPoller({
|
|
10454
10725
|
getDockedRuns: () => activityIndicator.getAgentRuns(),
|
|
@@ -10648,6 +10919,10 @@ async function runTuiWorkspace(options) {
|
|
|
10648
10919
|
state = { ...state, sessionCredits: (state.sessionCredits ?? 0) + credits };
|
|
10649
10920
|
};
|
|
10650
10921
|
let composerDecoderDrain = null;
|
|
10922
|
+
let draftEpoch = 0;
|
|
10923
|
+
const bumpDraftEpoch = () => {
|
|
10924
|
+
draftEpoch += 1;
|
|
10925
|
+
};
|
|
10651
10926
|
const emitCommandOutput = (text, command = "") => {
|
|
10652
10927
|
if (!text) return;
|
|
10653
10928
|
if (!isInteractiveInput(input)) {
|
|
@@ -10660,8 +10935,56 @@ async function runTuiWorkspace(options) {
|
|
|
10660
10935
|
renderHistoryToOutput();
|
|
10661
10936
|
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
10662
10937
|
};
|
|
10938
|
+
const applyClipboardPasteResult = (outcome, source) => {
|
|
10939
|
+
const colorEnabled = resolveCliColorEnabled();
|
|
10940
|
+
if (outcome.kind === "image") {
|
|
10941
|
+
state = {
|
|
10942
|
+
...state,
|
|
10943
|
+
attachedImages: mergeAttachedImages(state.attachedImages, [outcome.image])
|
|
10944
|
+
};
|
|
10945
|
+
emitCommandOutput(summarizeAttachment(outcome.image));
|
|
10946
|
+
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
10947
|
+
return;
|
|
10948
|
+
}
|
|
10949
|
+
if (outcome.kind === "text") {
|
|
10950
|
+
const pasteResult = applyTuiInputKey(
|
|
10951
|
+
buffer,
|
|
10952
|
+
`${PASTE_TOKEN_PREFIX}${outcome.text}`,
|
|
10953
|
+
{},
|
|
10954
|
+
cursorPos,
|
|
10955
|
+
{ pasteStore, cwd: state.cwd }
|
|
10956
|
+
);
|
|
10957
|
+
buffer = pasteResult.buffer;
|
|
10958
|
+
cursorPos = pasteResult.cursorPos ?? buffer.length;
|
|
10959
|
+
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
10960
|
+
if (source === "slash") {
|
|
10961
|
+
emitCommandOutput(t("pasteTextInserted", String(outcome.text.length)));
|
|
10962
|
+
}
|
|
10963
|
+
return;
|
|
10964
|
+
}
|
|
10965
|
+
emitCommandOutput(
|
|
10966
|
+
themeText(`[nolo] ${outcome.message}`, "warning", colorEnabled)
|
|
10967
|
+
);
|
|
10968
|
+
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
10969
|
+
};
|
|
10970
|
+
const readAndApplyClipboard = async (source) => {
|
|
10971
|
+
const snapshot = { epoch: draftEpoch, sessionEnded };
|
|
10972
|
+
const outcome = await resolveClipboardPaste({
|
|
10973
|
+
readImage: () => readImage({ env: options.env ?? process.env }),
|
|
10974
|
+
readText: () => readClipboardText()
|
|
10975
|
+
});
|
|
10976
|
+
if (!shouldApplyPastedResult(snapshot, { epoch: draftEpoch, sessionEnded })) {
|
|
10977
|
+
if (!sessionEnded) {
|
|
10978
|
+
emitCommandOutput(t("pasteStaleDropped"));
|
|
10979
|
+
}
|
|
10980
|
+
return false;
|
|
10981
|
+
}
|
|
10982
|
+
applyClipboardPasteResult(outcome, source);
|
|
10983
|
+
return true;
|
|
10984
|
+
};
|
|
10663
10985
|
let chatQueueBinding = null;
|
|
10664
10986
|
let turnInjectionInbox = null;
|
|
10987
|
+
let noteUserTurnHook = null;
|
|
10665
10988
|
const turnCtx = {
|
|
10666
10989
|
get state() {
|
|
10667
10990
|
return state;
|
|
@@ -10711,6 +11034,7 @@ async function runTuiWorkspace(options) {
|
|
|
10711
11034
|
set turnInjectionInbox(v) {
|
|
10712
11035
|
turnInjectionInbox = v;
|
|
10713
11036
|
},
|
|
11037
|
+
noteUserTurn: () => noteUserTurnHook?.(),
|
|
10714
11038
|
get sessionEnded() {
|
|
10715
11039
|
return sessionEnded;
|
|
10716
11040
|
},
|
|
@@ -10782,6 +11106,8 @@ async function runTuiWorkspace(options) {
|
|
|
10782
11106
|
persistExplicitAgentSwitch,
|
|
10783
11107
|
persistAgentSelection,
|
|
10784
11108
|
writeClipboard: writeClipboard2,
|
|
11109
|
+
readAndApplyClipboard,
|
|
11110
|
+
bumpDraftEpoch,
|
|
10785
11111
|
selfUpdater,
|
|
10786
11112
|
spawnRunner,
|
|
10787
11113
|
installAltScreenRestoreHandlers
|
|
@@ -10928,6 +11254,14 @@ async function runTuiWorkspace(options) {
|
|
|
10928
11254
|
};
|
|
10929
11255
|
return { actionGateHandler, confirmDestructiveAction };
|
|
10930
11256
|
};
|
|
11257
|
+
const processTerminalResumer = createProcessTerminalAutoResumer({
|
|
11258
|
+
readOwner: (taskId) => getProcessRegistry().getByTaskId(taskId)?.owner ?? null,
|
|
11259
|
+
isPromoted: (taskId) => getProcessRegistry().getByTaskId(taskId)?.promoted ?? false,
|
|
11260
|
+
getCurrentDialogId: () => state.dialogId ?? null,
|
|
11261
|
+
isTurnActive: () => busy || fixedInput.isPaused(),
|
|
11262
|
+
canDeliver: () => !sessionEnded && !done && runWakeHandler !== null
|
|
11263
|
+
});
|
|
11264
|
+
noteUserTurnHook = () => processTerminalResumer.noteUserTurn();
|
|
10931
11265
|
const runIdleTextTurn = async (inputMsg) => {
|
|
10932
11266
|
const req = createTurnRequest(inputMsg);
|
|
10933
11267
|
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
@@ -10958,25 +11292,28 @@ ${err.message}` : ""}`
|
|
|
10958
11292
|
fixedInput.exitOutputMode(buffer, cursorPos);
|
|
10959
11293
|
};
|
|
10960
11294
|
(options.env ?? process.env)[RUN_WAKE_CHANNEL_ENV] = "1";
|
|
11295
|
+
const printInternalEventLine = (displayText) => {
|
|
11296
|
+
const noticeLine = dimCliText(displayText, resolveCliColorEnabled());
|
|
11297
|
+
if (!isInteractiveInput(input)) {
|
|
11298
|
+
output.write(`${noticeLine}
|
|
11299
|
+
`);
|
|
11300
|
+
return;
|
|
11301
|
+
}
|
|
11302
|
+
history.followBottom = true;
|
|
11303
|
+
appendStreamSafeNotice(history, noticeLine, {
|
|
11304
|
+
appendLocalTurn,
|
|
11305
|
+
startTurn
|
|
11306
|
+
});
|
|
11307
|
+
renderHistoryToOutput();
|
|
11308
|
+
};
|
|
10961
11309
|
runWakeHandler = (event) => {
|
|
10962
11310
|
if (done) return;
|
|
10963
11311
|
if (busy || fixedInput.isPaused()) {
|
|
10964
11312
|
const text = typeof event === "string" ? event : event.text;
|
|
10965
11313
|
const injected = !!turnInjectionInbox && turnInjectionInbox.push({ text, fallback: event });
|
|
10966
11314
|
if (injected) {
|
|
10967
|
-
const displayText = typeof event
|
|
10968
|
-
|
|
10969
|
-
if (!isInteractiveInput(input)) {
|
|
10970
|
-
output.write(`${noticeLine}
|
|
10971
|
-
`);
|
|
10972
|
-
} else {
|
|
10973
|
-
history.followBottom = true;
|
|
10974
|
-
appendStreamSafeNotice(history, noticeLine, {
|
|
10975
|
-
appendLocalTurn,
|
|
10976
|
-
startTurn
|
|
10977
|
-
});
|
|
10978
|
-
renderHistoryToOutput();
|
|
10979
|
-
}
|
|
11315
|
+
const displayText = typeof event === "string" ? event : event.kind === "user" ? event.text : event.displayText ?? event.text;
|
|
11316
|
+
printInternalEventLine(displayText);
|
|
10980
11317
|
} else {
|
|
10981
11318
|
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
10982
11319
|
ensureChatQueueBinding(turnCtx, actionGateHandler, confirmDestructiveAction).enqueue(event);
|
|
@@ -10993,6 +11330,18 @@ ${err.message}` : ""}`
|
|
|
10993
11330
|
);
|
|
10994
11331
|
});
|
|
10995
11332
|
};
|
|
11333
|
+
deliverProcessTerminalNotice = (notice) => {
|
|
11334
|
+
if (done || sessionEnded) return;
|
|
11335
|
+
const decision = processTerminalResumer.decide(notice);
|
|
11336
|
+
if (decision.kind === "notice-only") {
|
|
11337
|
+
pushPendingProcessNotice(notice);
|
|
11338
|
+
return;
|
|
11339
|
+
}
|
|
11340
|
+
runWakeHandler?.(buildProcessTaskCompletedTurnEvent(notice));
|
|
11341
|
+
if (fixedInput.active && !fixedInput.isPaused()) {
|
|
11342
|
+
fixedInput.repaint(buffer, cursorPos);
|
|
11343
|
+
}
|
|
11344
|
+
};
|
|
10996
11345
|
let autoScrollDirection = "up";
|
|
10997
11346
|
const autoScrollStep = () => autoScrollStepForTicks(++autoScrollTicks);
|
|
10998
11347
|
const startAutoScroll = (direction, mouseX) => {
|
|
@@ -11090,6 +11439,7 @@ ${err.message}` : ""}`
|
|
|
11090
11439
|
clearSelection();
|
|
11091
11440
|
}
|
|
11092
11441
|
if (buffer.length > 0) {
|
|
11442
|
+
bumpDraftEpoch();
|
|
11093
11443
|
buffer = "";
|
|
11094
11444
|
cursorPos = 0;
|
|
11095
11445
|
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
@@ -11107,11 +11457,16 @@ ${err.message}` : ""}`
|
|
|
11107
11457
|
};
|
|
11108
11458
|
const handleBusyLocalSlash = async (submittedText, busySlashCommand) => {
|
|
11109
11459
|
releaseCollapsedPasteReferences(submittedText, pasteStore);
|
|
11460
|
+
bumpDraftEpoch();
|
|
11110
11461
|
buffer = "";
|
|
11111
11462
|
cursorPos = 0;
|
|
11112
11463
|
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
11113
11464
|
const beforeAgentKey = state.agentKey;
|
|
11114
11465
|
const res = handleTuiInput(submittedText, state);
|
|
11466
|
+
if (res.action?.type === "paste-clipboard") {
|
|
11467
|
+
await readAndApplyClipboard("slash");
|
|
11468
|
+
return;
|
|
11469
|
+
}
|
|
11115
11470
|
if (res.action?.type === "theme-refresh") {
|
|
11116
11471
|
state = res.nextState;
|
|
11117
11472
|
const detected = await detectTerminalBackground({
|
|
@@ -11340,45 +11695,10 @@ ${merged}` : merged;
|
|
|
11340
11695
|
return;
|
|
11341
11696
|
}
|
|
11342
11697
|
const isPasteToken = sequence.startsWith(PASTE_TOKEN_PREFIX);
|
|
11343
|
-
const
|
|
11698
|
+
const isEmptyBracketedPaste = isPasteToken && sequence.slice(PASTE_TOKEN_PREFIX.length).trim() === "";
|
|
11699
|
+
const isPasteShortcut = sequence === "" || isEmptyBracketedPaste;
|
|
11344
11700
|
if (isPasteShortcut) {
|
|
11345
|
-
|
|
11346
|
-
const image = await readImage({
|
|
11347
|
-
env: options.env ?? process.env
|
|
11348
|
-
});
|
|
11349
|
-
state = {
|
|
11350
|
-
...state,
|
|
11351
|
-
attachedImages: mergeAttachedImages(state.attachedImages, [image])
|
|
11352
|
-
};
|
|
11353
|
-
emitCommandOutput(summarizeAttachment(image));
|
|
11354
|
-
} catch (error) {
|
|
11355
|
-
if (isClipboardImageFallbackEligible(error)) {
|
|
11356
|
-
let clipboardText = "";
|
|
11357
|
-
try {
|
|
11358
|
-
clipboardText = await readClipboardText();
|
|
11359
|
-
} catch {
|
|
11360
|
-
clipboardText = "";
|
|
11361
|
-
}
|
|
11362
|
-
if (clipboardText.length > 0) {
|
|
11363
|
-
const pasteResult = applyTuiInputKey(
|
|
11364
|
-
buffer,
|
|
11365
|
-
`${PASTE_TOKEN_PREFIX}${clipboardText}`,
|
|
11366
|
-
{},
|
|
11367
|
-
cursorPos,
|
|
11368
|
-
{ pasteStore, cwd: state.cwd }
|
|
11369
|
-
);
|
|
11370
|
-
buffer = pasteResult.buffer;
|
|
11371
|
-
cursorPos = pasteResult.cursorPos;
|
|
11372
|
-
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
11373
|
-
return;
|
|
11374
|
-
}
|
|
11375
|
-
}
|
|
11376
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
11377
|
-
emitCommandOutput(
|
|
11378
|
-
themeText(`[nolo] ${msg}`, "warning", resolveCliColorEnabled())
|
|
11379
|
-
);
|
|
11380
|
-
}
|
|
11381
|
-
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
11701
|
+
await readAndApplyClipboard(isEmptyBracketedPaste ? "bracketed-empty" : "key");
|
|
11382
11702
|
return;
|
|
11383
11703
|
}
|
|
11384
11704
|
if (isBackspaceSequence(sequence, {}) && buffer === "" && state.attachedImages.length > 0) {
|
|
@@ -11417,7 +11737,7 @@ ${merged}` : merged;
|
|
|
11417
11737
|
if (busyLock) {
|
|
11418
11738
|
const trimmedText = submittedText.trim();
|
|
11419
11739
|
const busySlashCommand = trimmedText.split(/\s+/)[0]?.toLowerCase();
|
|
11420
|
-
const isBusyLocalSlash = busySlashCommand === "/context" || busySlashCommand === "/ctx" || busySlashCommand === "/cd" || busySlashCommand === "/switch" || busySlashCommand === "/theme" || busySlashCommand === "/runtime" || busySlashCommand === "/tools" || busySlashCommand === "/thinking" || busySlashCommand === "/auto" || busySlashCommand === "/tasks" || busySlashCommand === "/jobs" || busySlashCommand === "/procs" || busySlashCommand === "/agents" || busySlashCommand === "/doc" || busySlashCommand === "/skill" || busySlashCommand === "/customize" || busySlashCommand === "/login" || busySlashCommand === "/profile" || busySlashCommand === "/version";
|
|
11740
|
+
const isBusyLocalSlash = busySlashCommand === "/context" || busySlashCommand === "/ctx" || busySlashCommand === "/cd" || busySlashCommand === "/switch" || busySlashCommand === "/theme" || busySlashCommand === "/runtime" || busySlashCommand === "/tools" || busySlashCommand === "/thinking" || busySlashCommand === "/auto" || busySlashCommand === "/tasks" || busySlashCommand === "/jobs" || busySlashCommand === "/procs" || busySlashCommand === "/agents" || busySlashCommand === "/doc" || busySlashCommand === "/skill" || busySlashCommand === "/customize" || busySlashCommand === "/login" || busySlashCommand === "/profile" || busySlashCommand === "/paste" || busySlashCommand === "/version";
|
|
11421
11741
|
if (isBusyLocalSlash) {
|
|
11422
11742
|
await handleBusyLocalSlash(submittedText, busySlashCommand);
|
|
11423
11743
|
return;
|
|
@@ -11446,11 +11766,13 @@ ${merged}` : merged;
|
|
|
11446
11766
|
if (drainedText !== null) {
|
|
11447
11767
|
buffer = "";
|
|
11448
11768
|
cursorPos = 0;
|
|
11769
|
+
bumpDraftEpoch();
|
|
11449
11770
|
await runIdleTextTurn(drainedText);
|
|
11450
11771
|
return;
|
|
11451
11772
|
}
|
|
11452
11773
|
}
|
|
11453
11774
|
busy = startsChatTurn;
|
|
11775
|
+
bumpDraftEpoch();
|
|
11454
11776
|
buffer = "";
|
|
11455
11777
|
cursorPos = 0;
|
|
11456
11778
|
fixedInput.enterOutputMode(submittedText);
|