nolo-cli 0.63.1 → 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.
Files changed (29) hide show
  1. package/README.md +1 -0
  2. package/{agentDeleteCommand-NTUC5X4H.js → agentDeleteCommand-6R6EXQOR.js} +1 -1
  3. package/{agentEmailCommands-D74ZOQXN.js → agentEmailCommands-AKENZOKO.js} +3 -3
  4. package/{agentListCommands-43NKDIUT.js → agentListCommands-XJU3JJQO.js} +1 -1
  5. package/{agentMachineCommands-5MPEQQMR.js → agentMachineCommands-V7IJDPAY.js} +2 -2
  6. package/{agentRecordCommands-UUYNJGVC.js → agentRecordCommands-VIEINDIV.js} +3 -3
  7. package/{agentRunCommand-7MIBF4J7.js → agentRunCommand-GT5ZTYRM.js} +3 -3
  8. package/{agentRuntimeLocal-WWBWDTTG.js → agentRuntimeLocal-HGJ4D3JF.js} +1 -1
  9. package/{appDeleteCommands-VTIDMUUS.js → appDeleteCommands-VG2UVW4T.js} +1 -1
  10. package/{appDeployCommands-LOACOW26.js → appDeployCommands-PABMVMN2.js} +1 -1
  11. package/{appDeployStatusCommands-2RKASRYO.js → appDeployStatusCommands-X7WEU4TU.js} +1 -1
  12. package/{appGetCommands-GRO6QDM3.js → appGetCommands-NQYXHVJL.js} +1 -1
  13. package/{appListCommands-5BMCSU66.js → appListCommands-5NGZQ6IK.js} +1 -1
  14. package/{chunk-ECSQC7UV.js → chunk-3ROJR3TG.js} +22 -2
  15. package/{chunk-JNDDM6BU.js → chunk-BWIPK2PD.js} +22 -3
  16. package/{chunk-Y4AIZ4N2.js → chunk-LJ6OKZ6D.js} +201 -7
  17. package/{chunk-GJUFAZPF.js → chunk-OOCYHKCV.js} +1 -1
  18. package/{chunk-CGUUOBD2.js → chunk-URHZKKK7.js} +2 -2
  19. package/{dialogCommands-PPONZF6D.js → dialogCommands-HGMV4NQJ.js} +1 -1
  20. package/{docCreateCommands-SJSQAX4J.js → docCreateCommands-WQT5EZG2.js} +1 -1
  21. package/{docDeleteCommands-T4IFYPWR.js → docDeleteCommands-GUMELBKM.js} +1 -1
  22. package/{docReadCommands-RHD6RPV7.js → docReadCommands-T6FDDKJ3.js} +1 -1
  23. package/{docUpdateCommands-5OLZXCEB.js → docUpdateCommands-GBWGXG2G.js} +1 -1
  24. package/index.js +43 -41
  25. package/{machineCommands-Y6NJLJ77.js → machineCommands-SCGLQQCA.js} +3 -3
  26. package/{machineWsRunDispatch-LBSNCUW7.js → machineWsRunDispatch-EAH5VIEL.js} +3 -3
  27. package/package.json +1 -1
  28. package/{readlineWorkspace-F3IYM37K.js → readlineWorkspace-7FNJDYLD.js} +185 -99
  29. 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-JNDDM6BU.js";
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-Y4AIZ4N2.js";
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-ECSQC7UV.js";
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 applyScrollAction(history, action, output, inputLines, reservedRows = 0) {
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: "Compacting current dialog...",
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
- try {
8286
- const parts = token.split(".");
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({ data: changes })
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
- output.write(`${message}
9536
- `);
9595
+ emitCommandOutput(message);
9537
9596
  } catch (error) {
9538
- output.write(
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
- applyScrollAction(
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
- const scrollAction2 = mouseEvent.wheelDirection === "down" ? "wheel-down" : "wheel-up";
10839
- applyScrollAction(history, scrollAction2, output, fixedInput.getInputLines());
10840
- scheduleRender();
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-ECSQC7UV.js";
14
+ import "./chunk-3ROJR3TG.js";
15
15
  import "./chunk-7A3RRUCQ.js";
16
16
  import "./chunk-ZNFJWEN4.js";
17
17
  import "./chunk-XOKOSO35.js";