nolo-cli 0.63.0 → 0.64.0-alpha.1
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/README.md +1 -0
- package/{agentDeleteCommand-NTUC5X4H.js → agentDeleteCommand-6R6EXQOR.js} +1 -1
- package/{agentEmailCommands-D74ZOQXN.js → agentEmailCommands-AKENZOKO.js} +3 -3
- package/{agentListCommands-43NKDIUT.js → agentListCommands-XJU3JJQO.js} +1 -1
- package/{agentMachineCommands-5MPEQQMR.js → agentMachineCommands-V7IJDPAY.js} +2 -2
- package/{agentRecordCommands-UUYNJGVC.js → agentRecordCommands-VIEINDIV.js} +3 -3
- package/{agentRunCommand-7MIBF4J7.js → agentRunCommand-GT5ZTYRM.js} +3 -3
- package/{agentRuntimeLocal-WWBWDTTG.js → agentRuntimeLocal-HGJ4D3JF.js} +1 -1
- package/{appDeleteCommands-VTIDMUUS.js → appDeleteCommands-VG2UVW4T.js} +1 -1
- package/{appDeployCommands-LOACOW26.js → appDeployCommands-PABMVMN2.js} +1 -1
- package/{appDeployStatusCommands-2RKASRYO.js → appDeployStatusCommands-X7WEU4TU.js} +1 -1
- package/{appGetCommands-GRO6QDM3.js → appGetCommands-NQYXHVJL.js} +1 -1
- package/{appListCommands-5BMCSU66.js → appListCommands-5NGZQ6IK.js} +1 -1
- package/{chunk-ECSQC7UV.js → chunk-3ROJR3TG.js} +22 -2
- package/{chunk-JNDDM6BU.js → chunk-BWIPK2PD.js} +22 -3
- package/{chunk-Y4AIZ4N2.js → chunk-LJ6OKZ6D.js} +201 -7
- package/{chunk-GJUFAZPF.js → chunk-OOCYHKCV.js} +1 -1
- package/{chunk-CGUUOBD2.js → chunk-URHZKKK7.js} +2 -2
- package/{dialogCommands-PPONZF6D.js → dialogCommands-HGMV4NQJ.js} +1 -1
- package/{docCreateCommands-SJSQAX4J.js → docCreateCommands-WQT5EZG2.js} +1 -1
- package/{docDeleteCommands-T4IFYPWR.js → docDeleteCommands-GUMELBKM.js} +1 -1
- package/{docReadCommands-RHD6RPV7.js → docReadCommands-T6FDDKJ3.js} +1 -1
- package/{docUpdateCommands-5OLZXCEB.js → docUpdateCommands-GBWGXG2G.js} +1 -1
- package/index.js +43 -41
- package/{machineCommands-Y6NJLJ77.js → machineCommands-SCGLQQCA.js} +3 -3
- package/{machineWsRunDispatch-LBSNCUW7.js → machineWsRunDispatch-EAH5VIEL.js} +3 -3
- package/package.json +1 -1
- package/{readlineWorkspace-F3IYM37K.js → readlineWorkspace-7FNJDYLD.js} +185 -99
- package/{spaceCommands-OAKDKTZV.js → spaceCommands-76ECKNFH.js} +1 -1
|
@@ -72,7 +72,7 @@ import {
|
|
|
72
72
|
wrapTextToLines,
|
|
73
73
|
wrapTranscriptLine,
|
|
74
74
|
wrapTranscriptLineWithLayout
|
|
75
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-BWIPK2PD.js";
|
|
76
76
|
import "./chunk-S7Z2HMCN.js";
|
|
77
77
|
import {
|
|
78
78
|
listFavoriteAgentIdsAcrossServers,
|
|
@@ -89,6 +89,7 @@ import {
|
|
|
89
89
|
import "./chunk-JYYZCK2Z.js";
|
|
90
90
|
import {
|
|
91
91
|
RUN_WAKE_CHANNEL_ENV,
|
|
92
|
+
appendTurnBillingAudit,
|
|
92
93
|
createCliLocalRuntimeAdapter,
|
|
93
94
|
dailyWelcomeTip,
|
|
94
95
|
initCliLocale,
|
|
@@ -96,7 +97,7 @@ import {
|
|
|
96
97
|
readTimestamp,
|
|
97
98
|
setCliLocale,
|
|
98
99
|
t
|
|
99
|
-
} from "./chunk-
|
|
100
|
+
} from "./chunk-LJ6OKZ6D.js";
|
|
100
101
|
import "./chunk-MXUDQZXQ.js";
|
|
101
102
|
import "./chunk-EADNWBAZ.js";
|
|
102
103
|
import {
|
|
@@ -170,8 +171,7 @@ import "./chunk-DWYSDNOH.js";
|
|
|
170
171
|
import "./chunk-N6HLMLKE.js";
|
|
171
172
|
import "./chunk-ZJ7UHBJS.js";
|
|
172
173
|
import {
|
|
173
|
-
extractReferenceKeysFromMessage
|
|
174
|
-
normalizeUsage
|
|
174
|
+
extractReferenceKeysFromMessage
|
|
175
175
|
} from "./chunk-TBHAHL33.js";
|
|
176
176
|
import "./chunk-EVBFYPDC.js";
|
|
177
177
|
import "./chunk-HQUORJTM.js";
|
|
@@ -202,7 +202,7 @@ import {
|
|
|
202
202
|
buildLocalWorkspaceToolset,
|
|
203
203
|
getProcessRegistry,
|
|
204
204
|
readCommandActionGatePayload
|
|
205
|
-
} from "./chunk-
|
|
205
|
+
} from "./chunk-3ROJR3TG.js";
|
|
206
206
|
import "./chunk-7A3RRUCQ.js";
|
|
207
207
|
import "./chunk-ZNFJWEN4.js";
|
|
208
208
|
import "./chunk-XOKOSO35.js";
|
|
@@ -2215,7 +2215,7 @@ function createHistoryOutputStream(history, onUpdate) {
|
|
|
2215
2215
|
};
|
|
2216
2216
|
return stream;
|
|
2217
2217
|
}
|
|
2218
|
-
function
|
|
2218
|
+
function computeScrollMetrics(history, output, inputLines, reservedRows = 0) {
|
|
2219
2219
|
const tty = output;
|
|
2220
2220
|
const rows = tty.rows ?? 24;
|
|
2221
2221
|
const columns = tty.columns ?? 80;
|
|
@@ -2230,6 +2230,15 @@ function applyScrollAction(history, action, output, inputLines, reservedRows = 0
|
|
|
2230
2230
|
totalLines += currentTurnSeparator(history) + countTurnLines(history.currentRole, history.currentContent, contentWidth);
|
|
2231
2231
|
}
|
|
2232
2232
|
const maxScrollTop = Math.max(0, totalLines - visibleHeight);
|
|
2233
|
+
return { visibleHeight, contentWidth, totalLines, maxScrollTop };
|
|
2234
|
+
}
|
|
2235
|
+
function applyScrollAction(history, action, output, inputLines, reservedRows = 0) {
|
|
2236
|
+
const { visibleHeight, maxScrollTop } = computeScrollMetrics(
|
|
2237
|
+
history,
|
|
2238
|
+
output,
|
|
2239
|
+
inputLines,
|
|
2240
|
+
reservedRows
|
|
2241
|
+
);
|
|
2233
2242
|
history.followBottom = false;
|
|
2234
2243
|
switch (action) {
|
|
2235
2244
|
case "page-up":
|
|
@@ -6241,7 +6250,7 @@ ${t("autoUsage")}`
|
|
|
6241
6250
|
}
|
|
6242
6251
|
return {
|
|
6243
6252
|
nextState: state,
|
|
6244
|
-
output: "
|
|
6253
|
+
output: t("compactingDialog"),
|
|
6245
6254
|
action: { type: "compact", dialogId: state.dialogId }
|
|
6246
6255
|
};
|
|
6247
6256
|
case "/agent":
|
|
@@ -6689,66 +6698,6 @@ function normalizeStatus(raw) {
|
|
|
6689
6698
|
return "failed";
|
|
6690
6699
|
}
|
|
6691
6700
|
|
|
6692
|
-
// packages/cli/client/turnBillingAudit.ts
|
|
6693
|
-
import { appendFileSync, mkdirSync as mkdirSync2 } from "node:fs";
|
|
6694
|
-
import { homedir as homedir4 } from "node:os";
|
|
6695
|
-
import { join as join3 } from "node:path";
|
|
6696
|
-
function projectUsageForAudit(usage) {
|
|
6697
|
-
if (!usage || typeof usage !== "object") return null;
|
|
6698
|
-
const normalized = normalizeUsage(usage);
|
|
6699
|
-
const projected = {
|
|
6700
|
-
input_tokens: normalized.input_tokens,
|
|
6701
|
-
output_tokens: normalized.output_tokens,
|
|
6702
|
-
cache_read_input_tokens: normalized.cache_read_input_tokens,
|
|
6703
|
-
cache_creation_input_tokens: normalized.cache_creation_input_tokens
|
|
6704
|
-
};
|
|
6705
|
-
if (typeof usage.cost === "number" && Number.isFinite(usage.cost)) {
|
|
6706
|
-
projected.cost = usage.cost;
|
|
6707
|
-
}
|
|
6708
|
-
if (typeof usage.billing_unit === "string" && usage.billing_unit.trim()) {
|
|
6709
|
-
projected.billing_unit = usage.billing_unit;
|
|
6710
|
-
}
|
|
6711
|
-
if (typeof usage.provider_call_id === "string" && usage.provider_call_id.trim()) {
|
|
6712
|
-
projected.provider_call_id = usage.provider_call_id.trim();
|
|
6713
|
-
}
|
|
6714
|
-
return projected;
|
|
6715
|
-
}
|
|
6716
|
-
function resolveTurnBillingAuditLogPath(env = process.env) {
|
|
6717
|
-
const noloHome = env.NOLO_HOME?.trim() || join3(homedir4(), ".nolo");
|
|
6718
|
-
return join3(noloHome, "logs", "turn-billing.jsonl");
|
|
6719
|
-
}
|
|
6720
|
-
function appendTurnBillingAudit(input) {
|
|
6721
|
-
try {
|
|
6722
|
-
if (process.env.NOLO_TURN_BILLING_AUDIT === "0") return;
|
|
6723
|
-
const calls = (input.usageRecords ?? []).map((record) => {
|
|
6724
|
-
const usage = projectUsageForAudit(record?.usage);
|
|
6725
|
-
if (!usage) return null;
|
|
6726
|
-
return {
|
|
6727
|
-
...record?.callId ? { callId: record.callId } : {},
|
|
6728
|
-
...record?.model ? { model: record.model } : {},
|
|
6729
|
-
...record?.provider ? { provider: record.provider } : {},
|
|
6730
|
-
...usage
|
|
6731
|
-
};
|
|
6732
|
-
}).filter((call) => call !== null);
|
|
6733
|
-
if (calls.length === 0 && (input.turnCredits === void 0 || input.turnCredits === null)) {
|
|
6734
|
-
return;
|
|
6735
|
-
}
|
|
6736
|
-
const row = {
|
|
6737
|
-
ts: Date.now(),
|
|
6738
|
-
...input.dialogId ? { dialogId: input.dialogId } : {},
|
|
6739
|
-
...input.agentKey ? { agentKey: input.agentKey } : {},
|
|
6740
|
-
...input.turnCredits !== void 0 && input.turnCredits !== null ? { turnCredits: input.turnCredits } : {},
|
|
6741
|
-
...input.aborted ? { aborted: true } : {},
|
|
6742
|
-
calls
|
|
6743
|
-
};
|
|
6744
|
-
const logPath = resolveTurnBillingAuditLogPath();
|
|
6745
|
-
mkdirSync2(join3(logPath, ".."), { recursive: true });
|
|
6746
|
-
appendFileSync(logPath, `${JSON.stringify(row)}
|
|
6747
|
-
`);
|
|
6748
|
-
} catch {
|
|
6749
|
-
}
|
|
6750
|
-
}
|
|
6751
|
-
|
|
6752
6701
|
// packages/ai/tools/askChoiceState.ts
|
|
6753
6702
|
function normalizeAskChoiceArgs(args) {
|
|
6754
6703
|
const blocking = args.blocking !== false;
|
|
@@ -8274,7 +8223,118 @@ function createTuiRender(host) {
|
|
|
8274
8223
|
renderHistoryToOutput,
|
|
8275
8224
|
renderHistoryUnderDialog,
|
|
8276
8225
|
scheduleRender,
|
|
8277
|
-
flushPendingRender
|
|
8226
|
+
flushPendingRender,
|
|
8227
|
+
// 立即绘制一帧同步帧(BSU/ESU + 光标隐藏)。流式路径走 33ms 节流的
|
|
8228
|
+
// scheduleRender;平滑滚动推进器按 16ms 自己的节奏调用这里,避免被节流
|
|
8229
|
+
// 抹平成"每 33ms 一跳"。
|
|
8230
|
+
paintImmediate: paintSyncedFrame
|
|
8231
|
+
};
|
|
8232
|
+
}
|
|
8233
|
+
|
|
8234
|
+
// packages/cli/tui/tuiScrollAnimation.ts
|
|
8235
|
+
var SCROLL_ANIMATION_TICK_MS = 16;
|
|
8236
|
+
var DEFAULT_SCROLL_MAX_LINES_PER_TICK = 6;
|
|
8237
|
+
function readPositiveInt(raw, fallback, max) {
|
|
8238
|
+
if (raw === void 0 || raw.trim() === "") return fallback;
|
|
8239
|
+
const parsed = Number.parseInt(raw, 10);
|
|
8240
|
+
if (!Number.isFinite(parsed) || parsed < 1) return fallback;
|
|
8241
|
+
return Math.min(parsed, max);
|
|
8242
|
+
}
|
|
8243
|
+
function resolveScrollTuning(env = process.env) {
|
|
8244
|
+
return {
|
|
8245
|
+
wheelLines: readPositiveInt(env.NOLO_TUI_WHEEL_LINES, WHEEL_SCROLL_LINES, 50),
|
|
8246
|
+
maxLinesPerTick: readPositiveInt(
|
|
8247
|
+
env.NOLO_TUI_SCROLL_MAX_STEP,
|
|
8248
|
+
DEFAULT_SCROLL_MAX_LINES_PER_TICK,
|
|
8249
|
+
100
|
|
8250
|
+
)
|
|
8251
|
+
};
|
|
8252
|
+
}
|
|
8253
|
+
var defaultTickTimer = {
|
|
8254
|
+
every(ms, fn) {
|
|
8255
|
+
const handle = setInterval(fn, ms);
|
|
8256
|
+
handle.unref?.();
|
|
8257
|
+
return () => clearInterval(handle);
|
|
8258
|
+
}
|
|
8259
|
+
};
|
|
8260
|
+
function createScrollAnimator(deps) {
|
|
8261
|
+
const { wheelLines, maxLinesPerTick } = resolveScrollTuning(
|
|
8262
|
+
deps.env ?? process.env
|
|
8263
|
+
);
|
|
8264
|
+
const timer = deps.tickTimer ?? defaultTickTimer;
|
|
8265
|
+
const history = deps.history;
|
|
8266
|
+
let goal = null;
|
|
8267
|
+
let intent = null;
|
|
8268
|
+
let stopTicker = null;
|
|
8269
|
+
const metrics = () => computeScrollMetrics(
|
|
8270
|
+
history,
|
|
8271
|
+
deps.output,
|
|
8272
|
+
deps.getInputLines(),
|
|
8273
|
+
deps.getReservedRows?.() ?? 0
|
|
8274
|
+
);
|
|
8275
|
+
const stop = () => {
|
|
8276
|
+
if (stopTicker) {
|
|
8277
|
+
stopTicker();
|
|
8278
|
+
stopTicker = null;
|
|
8279
|
+
}
|
|
8280
|
+
goal = null;
|
|
8281
|
+
intent = null;
|
|
8282
|
+
};
|
|
8283
|
+
const settle = (maxScrollTop) => {
|
|
8284
|
+
if (intent === "down" && history.scrollTop >= maxScrollTop) {
|
|
8285
|
+
history.followBottom = true;
|
|
8286
|
+
}
|
|
8287
|
+
stop();
|
|
8288
|
+
};
|
|
8289
|
+
const tick = () => {
|
|
8290
|
+
if (goal === null) {
|
|
8291
|
+
stop();
|
|
8292
|
+
return;
|
|
8293
|
+
}
|
|
8294
|
+
const { maxScrollTop } = metrics();
|
|
8295
|
+
if (goal > maxScrollTop) goal = maxScrollTop;
|
|
8296
|
+
const delta = goal - history.scrollTop;
|
|
8297
|
+
if (delta === 0) {
|
|
8298
|
+
settle(maxScrollTop);
|
|
8299
|
+
return;
|
|
8300
|
+
}
|
|
8301
|
+
const step = Math.sign(delta) * Math.min(Math.abs(delta), maxLinesPerTick);
|
|
8302
|
+
history.scrollTop += step;
|
|
8303
|
+
deps.onPaint();
|
|
8304
|
+
if (history.scrollTop === goal) {
|
|
8305
|
+
settle(maxScrollTop);
|
|
8306
|
+
}
|
|
8307
|
+
};
|
|
8308
|
+
const ensureTicker = () => {
|
|
8309
|
+
if (!stopTicker) {
|
|
8310
|
+
stopTicker = timer.every(SCROLL_ANIMATION_TICK_MS, tick);
|
|
8311
|
+
}
|
|
8312
|
+
};
|
|
8313
|
+
return {
|
|
8314
|
+
/**
|
|
8315
|
+
* 一条滚轮报告:折算为目标位置并保证推进器在跑。
|
|
8316
|
+
* followBottom 先退出(与 applyScrollAction 的 wheel 分支一致)。
|
|
8317
|
+
*/
|
|
8318
|
+
wheel(direction) {
|
|
8319
|
+
const isOpposing = intent !== null && intent !== direction;
|
|
8320
|
+
const base = isOpposing ? history.scrollTop : goal ?? history.scrollTop;
|
|
8321
|
+
const next = direction === "up" ? base - wheelLines : base + wheelLines;
|
|
8322
|
+
goal = Math.max(0, next);
|
|
8323
|
+
intent = direction;
|
|
8324
|
+
if (goal === history.scrollTop) {
|
|
8325
|
+
stop();
|
|
8326
|
+
return;
|
|
8327
|
+
}
|
|
8328
|
+
history.followBottom = false;
|
|
8329
|
+
ensureTicker();
|
|
8330
|
+
},
|
|
8331
|
+
/** 外部直接改了 scrollTop(键盘滚动、选区拖拽自动滚动)前调用,避免两套写入打架。 */
|
|
8332
|
+
cancel() {
|
|
8333
|
+
stop();
|
|
8334
|
+
},
|
|
8335
|
+
isAnimating() {
|
|
8336
|
+
return goal !== null;
|
|
8337
|
+
}
|
|
8278
8338
|
};
|
|
8279
8339
|
}
|
|
8280
8340
|
|
|
@@ -8282,17 +8342,8 @@ function createTuiRender(host) {
|
|
|
8282
8342
|
import { ulid } from "ulid";
|
|
8283
8343
|
var DB_PATH = "/api/v1/db";
|
|
8284
8344
|
function parseTokenUserId(token) {
|
|
8285
|
-
|
|
8286
|
-
|
|
8287
|
-
if (parts.length < 2) return null;
|
|
8288
|
-
const payloadBase64 = parts[1];
|
|
8289
|
-
const payload = JSON.parse(
|
|
8290
|
-
Buffer.from(payloadBase64, "base64").toString("utf8")
|
|
8291
|
-
);
|
|
8292
|
-
return typeof payload?.userId === "string" ? payload.userId : null;
|
|
8293
|
-
} catch {
|
|
8294
|
-
return null;
|
|
8295
|
-
}
|
|
8345
|
+
const userId = parseUserIdFromAuthToken(token);
|
|
8346
|
+
return userId || null;
|
|
8296
8347
|
}
|
|
8297
8348
|
async function readDialogRecord(fetchImpl, serverUrl, authToken, dialogKey) {
|
|
8298
8349
|
const res = await fetchImpl(`${serverUrl}${DB_PATH}/read/${dialogKey}`, {
|
|
@@ -8327,7 +8378,7 @@ async function patchDialog(fetchImpl, serverUrl, authToken, dialogKey, changes)
|
|
|
8327
8378
|
"Content-Type": "application/json",
|
|
8328
8379
|
Authorization: `Bearer ${authToken}`
|
|
8329
8380
|
},
|
|
8330
|
-
body: JSON.stringify(
|
|
8381
|
+
body: JSON.stringify(changes)
|
|
8331
8382
|
});
|
|
8332
8383
|
if (!res.ok) {
|
|
8333
8384
|
throw new Error(`Failed to patch dialog "${dialogKey}": HTTP ${res.status}`);
|
|
@@ -8433,12 +8484,13 @@ async function resolveContextWindow(fetchImpl, serverUrl, authToken, agentKey) {
|
|
|
8433
8484
|
}
|
|
8434
8485
|
async function compactDialog(options) {
|
|
8435
8486
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
8436
|
-
const userId = parseTokenUserId(options.authToken);
|
|
8487
|
+
const userId = options.userId || parseTokenUserId(options.authToken);
|
|
8437
8488
|
if (!userId) {
|
|
8438
8489
|
throw new Error(
|
|
8439
8490
|
"[nolo] compact: cannot compact \u2014 invalid or missing auth token"
|
|
8440
8491
|
);
|
|
8441
8492
|
}
|
|
8493
|
+
options.onProgress?.("reading");
|
|
8442
8494
|
const dialogKey = `dialog-${userId}-${options.dialogId}`;
|
|
8443
8495
|
const current = await readDialogRecord(
|
|
8444
8496
|
fetchImpl,
|
|
@@ -8472,6 +8524,7 @@ async function compactDialog(options) {
|
|
|
8472
8524
|
reason: "manual"
|
|
8473
8525
|
});
|
|
8474
8526
|
if (plan.shouldCompress && plan.msgsToCompress.length > 0) {
|
|
8527
|
+
options.onProgress?.("summarizing");
|
|
8475
8528
|
const previousSummary = current.summary || "";
|
|
8476
8529
|
const messagesText = formatMessagesForSummaryWithTruncation(plan.msgsToCompress);
|
|
8477
8530
|
const fileOpsText = formatFileOperationsFromMessages(
|
|
@@ -8520,6 +8573,7 @@ async function compactDialog(options) {
|
|
|
8520
8573
|
}
|
|
8521
8574
|
}
|
|
8522
8575
|
}
|
|
8576
|
+
options.onProgress?.("forking");
|
|
8523
8577
|
const next = buildForkedDialogRecord(current, userId);
|
|
8524
8578
|
await writeDialogRecord(fetchImpl, options.serverUrl, options.authToken, next);
|
|
8525
8579
|
await addDialogToSpaceIfNeeded(
|
|
@@ -9483,7 +9537,13 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
9483
9537
|
serverUrl: host.state.serverUrl,
|
|
9484
9538
|
authToken,
|
|
9485
9539
|
dialogId: result.action.dialogId,
|
|
9486
|
-
summaryLlmCaller: options.summaryLlmCaller
|
|
9540
|
+
summaryLlmCaller: options.summaryLlmCaller,
|
|
9541
|
+
onProgress: (phase) => {
|
|
9542
|
+
const phaseText = phase === "reading" ? t("compactPhaseReading") : phase === "summarizing" ? t("compactPhaseSummarizing") : phase === "forking" ? t("compactPhaseForking") : void 0;
|
|
9543
|
+
if (phaseText) {
|
|
9544
|
+
emitCommandOutput(phaseText);
|
|
9545
|
+
}
|
|
9546
|
+
}
|
|
9487
9547
|
});
|
|
9488
9548
|
const elapsedSec = ((Date.now() - compactStart) / 1e3).toFixed(1);
|
|
9489
9549
|
host.state = {
|
|
@@ -9532,13 +9592,9 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
9532
9592
|
compactResult.dialogId,
|
|
9533
9593
|
elapsed
|
|
9534
9594
|
);
|
|
9535
|
-
|
|
9536
|
-
`);
|
|
9595
|
+
emitCommandOutput(message);
|
|
9537
9596
|
} catch (error) {
|
|
9538
|
-
|
|
9539
|
-
`[nolo] Compact failed: ${toErrorMessage(error)}
|
|
9540
|
-
`
|
|
9541
|
-
);
|
|
9597
|
+
emitCommandOutput(t("compactFailed", toErrorMessage(error)));
|
|
9542
9598
|
}
|
|
9543
9599
|
}
|
|
9544
9600
|
if (result.action?.type === "self-update") {
|
|
@@ -10117,6 +10173,15 @@ async function runTuiWorkspace(options) {
|
|
|
10117
10173
|
onRecordsPolled: (records) => runCompletionWatcher.observe(records)
|
|
10118
10174
|
});
|
|
10119
10175
|
const history = createTurnHistory();
|
|
10176
|
+
let handleTranscriptScroll = (action) => {
|
|
10177
|
+
applyScrollAction(
|
|
10178
|
+
history,
|
|
10179
|
+
action,
|
|
10180
|
+
output,
|
|
10181
|
+
fixedInput.getInputLines(),
|
|
10182
|
+
dialogHost.getReservedRows()
|
|
10183
|
+
);
|
|
10184
|
+
};
|
|
10120
10185
|
const dialogHost = createDialogHost({
|
|
10121
10186
|
composer: {
|
|
10122
10187
|
pause: () => fixedInput.pause(),
|
|
@@ -10137,13 +10202,7 @@ async function runTuiWorkspace(options) {
|
|
|
10137
10202
|
fixedInput.repaint(buffer, cursorPos);
|
|
10138
10203
|
},
|
|
10139
10204
|
onTranscriptScroll: (action) => {
|
|
10140
|
-
|
|
10141
|
-
history,
|
|
10142
|
-
action,
|
|
10143
|
-
output,
|
|
10144
|
-
fixedInput.getInputLines(),
|
|
10145
|
-
dialogHost.getReservedRows()
|
|
10146
|
-
);
|
|
10205
|
+
handleTranscriptScroll(action);
|
|
10147
10206
|
},
|
|
10148
10207
|
output,
|
|
10149
10208
|
// The decoder-drain hook is only bound once the interactive raw-mode
|
|
@@ -10160,7 +10219,8 @@ async function runTuiWorkspace(options) {
|
|
|
10160
10219
|
renderHistoryToOutput,
|
|
10161
10220
|
renderHistoryUnderDialog,
|
|
10162
10221
|
scheduleRender,
|
|
10163
|
-
flushPendingRender
|
|
10222
|
+
flushPendingRender,
|
|
10223
|
+
paintImmediate
|
|
10164
10224
|
} = createTuiRender({
|
|
10165
10225
|
output,
|
|
10166
10226
|
history,
|
|
@@ -10176,6 +10236,28 @@ async function runTuiWorkspace(options) {
|
|
|
10176
10236
|
},
|
|
10177
10237
|
getReservedRows: () => dialogHost.getReservedRows()
|
|
10178
10238
|
});
|
|
10239
|
+
const scrollAnimator = createScrollAnimator({
|
|
10240
|
+
history,
|
|
10241
|
+
output,
|
|
10242
|
+
getInputLines: () => fixedInput.getInputLines(),
|
|
10243
|
+
getReservedRows: () => dialogHost.getReservedRows(),
|
|
10244
|
+
onPaint: () => paintImmediate(),
|
|
10245
|
+
env: effectiveEnv
|
|
10246
|
+
});
|
|
10247
|
+
handleTranscriptScroll = (action) => {
|
|
10248
|
+
if (action === "wheel-up" || action === "wheel-down") {
|
|
10249
|
+
scrollAnimator.wheel(action === "wheel-up" ? "up" : "down");
|
|
10250
|
+
return;
|
|
10251
|
+
}
|
|
10252
|
+
scrollAnimator.cancel();
|
|
10253
|
+
applyScrollAction(
|
|
10254
|
+
history,
|
|
10255
|
+
action,
|
|
10256
|
+
output,
|
|
10257
|
+
fixedInput.getInputLines(),
|
|
10258
|
+
dialogHost.getReservedRows()
|
|
10259
|
+
);
|
|
10260
|
+
};
|
|
10179
10261
|
const refreshGitStatus = () => {
|
|
10180
10262
|
if ((options.env?.NOLO_CLI_GIT_STATUS ?? process.env.NOLO_CLI_GIT_STATUS) === "0") return;
|
|
10181
10263
|
void detectGitStatusAsync(state.cwd).then((gitStatus) => {
|
|
@@ -10497,6 +10579,7 @@ async function runTuiWorkspace(options) {
|
|
|
10497
10579
|
if (done) return;
|
|
10498
10580
|
done = true;
|
|
10499
10581
|
sessionEnded = true;
|
|
10582
|
+
scrollAnimator.cancel();
|
|
10500
10583
|
if (resizeTimer !== null) {
|
|
10501
10584
|
clearTimeout(resizeTimer);
|
|
10502
10585
|
resizeTimer = null;
|
|
@@ -10625,6 +10708,7 @@ ${err.message}` : ""}`
|
|
|
10625
10708
|
const startAutoScroll = (direction, mouseX) => {
|
|
10626
10709
|
autoScrollDirection = direction;
|
|
10627
10710
|
lastDragMouseX = mouseX;
|
|
10711
|
+
scrollAnimator.cancel();
|
|
10628
10712
|
if (autoScrollTimer) return;
|
|
10629
10713
|
autoScrollTimer = setInterval(() => {
|
|
10630
10714
|
if (!selectionState.dragging || !selectionState.anchor || fixedInput.isPaused()) {
|
|
@@ -10835,9 +10919,9 @@ ${merged}` : merged;
|
|
|
10835
10919
|
if (mouseEvent) {
|
|
10836
10920
|
if (fixedInput.isPaused()) return;
|
|
10837
10921
|
if (mouseEvent.kind === "wheel") {
|
|
10838
|
-
|
|
10839
|
-
|
|
10840
|
-
|
|
10922
|
+
scrollAnimator.wheel(
|
|
10923
|
+
mouseEvent.wheelDirection === "down" ? "down" : "up"
|
|
10924
|
+
);
|
|
10841
10925
|
return;
|
|
10842
10926
|
}
|
|
10843
10927
|
const tty = output;
|
|
@@ -10857,6 +10941,7 @@ ${merged}` : merged;
|
|
|
10857
10941
|
const screenCol = mouseEvent.x - 1;
|
|
10858
10942
|
if (mouseEvent.kind === "press" && mouseEvent.button === "left") {
|
|
10859
10943
|
stopAutoScroll();
|
|
10944
|
+
scrollAnimator.cancel();
|
|
10860
10945
|
if (screenRow < visibleHeight && screenCol < contentWidth) {
|
|
10861
10946
|
const hit = hitTestHistory(
|
|
10862
10947
|
history,
|
|
@@ -10936,6 +11021,7 @@ ${merged}` : merged;
|
|
|
10936
11021
|
const scrollAction = parseScrollAction(sequence);
|
|
10937
11022
|
if (scrollAction) {
|
|
10938
11023
|
if (fixedInput.isPaused()) return;
|
|
11024
|
+
scrollAnimator.cancel();
|
|
10939
11025
|
applyScrollAction(history, scrollAction, output, fixedInput.getInputLines());
|
|
10940
11026
|
paintFrame(buffer);
|
|
10941
11027
|
return;
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import "./chunk-CTCW7U7N.js";
|
|
12
12
|
import "./chunk-SPAQ4PVV.js";
|
|
13
13
|
import "./chunk-KQHGZWSV.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-3ROJR3TG.js";
|
|
15
15
|
import "./chunk-7A3RRUCQ.js";
|
|
16
16
|
import "./chunk-ZNFJWEN4.js";
|
|
17
17
|
import "./chunk-XOKOSO35.js";
|