msapling 2.3.6-beta.59 → 2.3.6-beta.60

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 (2) hide show
  1. package/dist/index.js +179 -49
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -23566,7 +23566,7 @@ var init_version = __esm({
23566
23566
  description: "Show version information for CLI and core packages",
23567
23567
  category: "debug",
23568
23568
  handler: async (_args, context) => {
23569
- const cliVersion = true ? "2.3.6-beta.59" : "(dev)";
23569
+ const cliVersion = true ? "2.3.6-beta.60" : "(dev)";
23570
23570
  const coreVersion = true ? "2.3.6-beta.43" : "(dev)";
23571
23571
  const runtime = process.version;
23572
23572
  context.addMessage("system", "MSapling Version Info");
@@ -29593,7 +29593,7 @@ import { render } from "ink";
29593
29593
 
29594
29594
  // src/App.tsx
29595
29595
  init_esm_shims();
29596
- import { useState as useState5, useEffect as useEffect3, useCallback as useCallback2, useRef } from "react";
29596
+ import { useState as useState5, useEffect as useEffect4, useCallback as useCallback2, useRef as useRef2 } from "react";
29597
29597
  import { randomUUID as randomUUID10 } from "crypto";
29598
29598
  import { Box as Box7, Text as Text7, useApp, useInput as useInput4, useStdout } from "ink";
29599
29599
 
@@ -29601,10 +29601,13 @@ import { Box as Box7, Text as Text7, useApp, useInput as useInput4, useStdout }
29601
29601
  init_esm_shims();
29602
29602
  import { Box, Text } from "ink";
29603
29603
  import { jsx, jsxs } from "react/jsx-runtime";
29604
- var Header = () => /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, marginBottom: 1, children: [
29604
+ var Header = ({ compact: compact2 = false }) => compact2 ? /* @__PURE__ */ jsxs(Text, { bold: true, color: "cyan", children: [
29605
+ "\u25CF MSapling v",
29606
+ "2.3.6-beta.60"
29607
+ ] }) : /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, marginBottom: 1, children: [
29605
29608
  /* @__PURE__ */ jsxs(Text, { bold: true, color: "cyan", children: [
29606
29609
  "\u25CF MSapling CLI v",
29607
- "2.3.6-beta.59"
29610
+ "2.3.6-beta.60"
29608
29611
  ] }),
29609
29612
  /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "Platinum Tier Architecture" }) })
29610
29613
  ] });
@@ -29708,6 +29711,42 @@ function promptLabel(user) {
29708
29711
  init_esm_shims();
29709
29712
  import { useState, useMemo } from "react";
29710
29713
  import { Box as Box3, Text as Text3, useInput } from "ink";
29714
+
29715
+ // src/hooks/useTerminalMouseScroll.ts
29716
+ init_esm_shims();
29717
+ import { useEffect, useRef } from "react";
29718
+ var ESC = String.fromCharCode(27);
29719
+ function isMouseReport(input) {
29720
+ return input.includes(`${ESC}[<`) && /\d+;\d+;\d+[mM]/.test(input);
29721
+ }
29722
+ function parseMouseScroll(input) {
29723
+ const directions = [];
29724
+ const pattern = new RegExp(`${ESC}\\[<(64|65);\\d+;\\d+[mM]`, "g");
29725
+ for (const match of input.matchAll(pattern)) {
29726
+ directions.push(match[1] === "64" ? "up" : "down");
29727
+ }
29728
+ return directions;
29729
+ }
29730
+ function useTerminalMouseScroll(onScroll) {
29731
+ const callback = useRef(onScroll);
29732
+ callback.current = onScroll;
29733
+ useEffect(() => {
29734
+ if (!process.stdin.isTTY || !process.stdout.isTTY) return;
29735
+ const handleData = (chunk) => {
29736
+ for (const direction of parseMouseScroll(String(chunk))) {
29737
+ callback.current(direction);
29738
+ }
29739
+ };
29740
+ process.stdout.write("\x1B[?1000h\x1B[?1006h");
29741
+ process.stdin.on("data", handleData);
29742
+ return () => {
29743
+ process.stdin.off("data", handleData);
29744
+ process.stdout.write("\x1B[?1006l\x1B[?1000l");
29745
+ };
29746
+ }, []);
29747
+ }
29748
+
29749
+ // src/components/ApprovalDialog.tsx
29711
29750
  import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
29712
29751
  function parseDiffLines(diffText) {
29713
29752
  if (!diffText) return [];
@@ -29774,6 +29813,7 @@ var ApprovalDialog = ({
29774
29813
  const { hasDiff, diffText, title } = useMemo(() => extractDiffFromCommand(command, diff), [command, diff]);
29775
29814
  const diffLines = useMemo(() => parseDiffLines(diffText), [diffText]);
29776
29815
  useInput((input, key) => {
29816
+ if (isMouseReport(input)) return;
29777
29817
  if (key.escape) {
29778
29818
  onResolve("no");
29779
29819
  return;
@@ -29860,6 +29900,7 @@ var AskUserQuestion = ({ question, options, multiSelect, onResolve }) => {
29860
29900
  const [selectedIndex, setSelectedIndex] = useState2(0);
29861
29901
  const [selectedIndices, setSelectedIndices] = useState2(/* @__PURE__ */ new Set());
29862
29902
  useInput2((input, key) => {
29903
+ if (isMouseReport(input)) return;
29863
29904
  if (key.upArrow) {
29864
29905
  setSelectedIndex((prev) => prev > 0 ? prev - 1 : options.length - 1);
29865
29906
  } else if (key.downArrow) {
@@ -29969,7 +30010,7 @@ var VirtualizedMessageList = ({
29969
30010
  );
29970
30011
  const separatorWidth = termColumns > 0 ? Math.min(termColumns, 60) : 60;
29971
30012
  return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", flexGrow: 1, children: [
29972
- (hiddenCount > 0 || hiddenAfter > 0) && /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: `[\u2191 ${hiddenCount} older \xB7 \u2193 ${hiddenAfter} newer \xB7 PageUp/PageDown to scroll \xB7 Ctrl+E for latest]` }),
30013
+ (hiddenCount > 0 || hiddenAfter > 0) && /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: `[\u2191 ${hiddenCount} older \xB7 \u2193 ${hiddenAfter} newer \xB7 wheel/\u2191/\u2193 or PageUp/PageDown \xB7 Ctrl+E latest]` }),
29973
30014
  displayMessages.map((msg, i) => /* @__PURE__ */ jsxs5(
29974
30015
  Box5,
29975
30016
  {
@@ -30001,7 +30042,7 @@ init_src3();
30001
30042
 
30002
30043
  // src/ui/TextInput.tsx
30003
30044
  init_esm_shims();
30004
- import { useState as useState3, useEffect } from "react";
30045
+ import { useState as useState3, useEffect as useEffect2 } from "react";
30005
30046
  import { Box as Box6, Text as Text6, useInput as useInput3 } from "ink";
30006
30047
 
30007
30048
  // src/state/commandHandler.ts
@@ -30596,14 +30637,16 @@ var TextInput = ({
30596
30637
  onCancel,
30597
30638
  disabled,
30598
30639
  storage,
30599
- promptColor = "green"
30640
+ promptColor = "green",
30641
+ transcriptNavigationActive = false
30600
30642
  }) => {
30601
30643
  const [history, setHistory] = useState3([]);
30602
30644
  const [historyIndex, setHistoryIndex] = useState3(-1);
30603
- useEffect(() => {
30645
+ useEffect2(() => {
30604
30646
  storage.loadHistory().then((entries) => setHistory(filterSafeHistory(entries)));
30605
30647
  }, [storage]);
30606
30648
  useInput3((input, key) => {
30649
+ if (isMouseReport(input)) return;
30607
30650
  if (key.ctrl && input === "c" || key.escape) {
30608
30651
  onCancel?.();
30609
30652
  return;
@@ -30619,13 +30662,13 @@ var TextInput = ({
30619
30662
  }
30620
30663
  } else if (key.backspace || key.delete) {
30621
30664
  onChange(value.slice(0, -1));
30622
- } else if (key.upArrow) {
30665
+ } else if (key.ctrl && input === "p" || key.upArrow && !transcriptNavigationActive) {
30623
30666
  const nextIndex = historyIndex + 1;
30624
30667
  if (nextIndex < history.length) {
30625
30668
  setHistoryIndex(nextIndex);
30626
30669
  onChange(history[history.length - 1 - nextIndex]);
30627
30670
  }
30628
- } else if (key.downArrow) {
30671
+ } else if (key.ctrl && input === "n" || key.downArrow && !transcriptNavigationActive) {
30629
30672
  const nextIndex = historyIndex - 1;
30630
30673
  if (nextIndex >= 0) {
30631
30674
  setHistoryIndex(nextIndex);
@@ -30634,6 +30677,8 @@ var TextInput = ({
30634
30677
  setHistoryIndex(-1);
30635
30678
  onChange("");
30636
30679
  }
30680
+ } else if ((key.upArrow || key.downArrow) && transcriptNavigationActive) {
30681
+ return;
30637
30682
  } else if (input && !key.ctrl && !key.meta) {
30638
30683
  onChange(value + input);
30639
30684
  }
@@ -30824,7 +30869,7 @@ init_errorPresentation();
30824
30869
 
30825
30870
  // src/hooks/useTerminalResize.ts
30826
30871
  init_esm_shims();
30827
- import { useState as useState4, useEffect as useEffect2, useCallback } from "react";
30872
+ import { useState as useState4, useEffect as useEffect3, useCallback } from "react";
30828
30873
  function getCurrentDimensions() {
30829
30874
  return {
30830
30875
  columns: process.stdout.columns ?? 80,
@@ -30838,7 +30883,7 @@ function useTerminalResize() {
30838
30883
  const handleResize = useCallback(() => {
30839
30884
  setDimensions(getCurrentDimensions());
30840
30885
  }, []);
30841
- useEffect2(() => {
30886
+ useEffect3(() => {
30842
30887
  process.stdout.on("resize", handleResize);
30843
30888
  const onSigwinch = () => handleResize();
30844
30889
  process.on("SIGWINCH", onSigwinch);
@@ -30875,6 +30920,42 @@ function releaseSubmission(lock2) {
30875
30920
  lock2.current = false;
30876
30921
  }
30877
30922
 
30923
+ // src/state/terminalLayout.ts
30924
+ init_esm_shims();
30925
+ function resolveTerminalLayout(rows, columns, forceCompact = false) {
30926
+ const safeRows = Number.isFinite(rows) && rows > 0 ? rows : 24;
30927
+ const safeColumns = Number.isFinite(columns) && columns > 0 ? columns : 80;
30928
+ const density = forceCompact || safeRows <= 34 ? "minimal" : safeRows <= 48 || safeColumns < 100 ? "condensed" : "full";
30929
+ if (density === "minimal") {
30930
+ return {
30931
+ density,
30932
+ outerPadding: 0,
30933
+ showFramedHeader: false,
30934
+ showFooter: false,
30935
+ statusRows: 1,
30936
+ fixedRows: 3
30937
+ };
30938
+ }
30939
+ if (density === "condensed") {
30940
+ return {
30941
+ density,
30942
+ outerPadding: 0,
30943
+ showFramedHeader: false,
30944
+ showFooter: false,
30945
+ statusRows: 2,
30946
+ fixedRows: 5
30947
+ };
30948
+ }
30949
+ return {
30950
+ density,
30951
+ outerPadding: 1,
30952
+ showFramedHeader: true,
30953
+ showFooter: true,
30954
+ statusRows: 6,
30955
+ fixedRows: 16
30956
+ };
30957
+ }
30958
+
30878
30959
  // src/App.tsx
30879
30960
  import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
30880
30961
  var App = ({ compact: compact2 = false, continueSession: continueSession2 = false, executionMode: executionMode2 = "remote" }) => {
@@ -30905,20 +30986,20 @@ var App = ({ compact: compact2 = false, continueSession: continueSession2 = fals
30905
30986
  const [billingProfile, setBillingProfile] = useState5(executionMode2 === "local" ? "ollama" : "account-metered");
30906
30987
  const [continuityProfile, setContinuityProfile] = useState5(executionMode2 === "local" ? "standalone-private" : "connected-mirrored");
30907
30988
  const [bootstrapState, setBootstrapState] = useState5("loading");
30908
- const submissionLockRef = useRef(false);
30989
+ const submissionLockRef = useRef2(false);
30909
30990
  const { exit } = useApp();
30910
30991
  const { stdout: termStdout } = useStdout();
30911
30992
  const { columns: termResizeCols, rows: termResizeRows } = useTerminalResize();
30912
- const storage = useRef(new StorageManager()).current;
30913
- const client = useRef(new MSaplingClient()).current;
30993
+ const storage = useRef2(new StorageManager()).current;
30994
+ const client = useRef2(new MSaplingClient()).current;
30914
30995
  const remoteEnvironment = describeRemoteEnvironment(client.getApiUrl());
30915
- const modeContract = useRef(new CliModeRuntime({
30996
+ const modeContract = useRef2(new CliModeRuntime({
30916
30997
  mode: executionMode2,
30917
30998
  provider: process.env.MSAPLING_LOCAL_LLM_PROVIDER ?? "ollama"
30918
30999
  })).current;
30919
- const sessionRecovery = useRef(new CliSessionRecovery()).current;
30920
- const checkpointTurns = useRef(/* @__PURE__ */ new Map()).current;
30921
- const agentRef = useRef(null);
31000
+ const sessionRecovery = useRef2(new CliSessionRecovery()).current;
31001
+ const checkpointTurns = useRef2(/* @__PURE__ */ new Map()).current;
31002
+ const agentRef = useRef2(null);
30922
31003
  const requestApproval = useCallback2((request) => {
30923
31004
  agentRef.current?.fireLifecycleHook(
30924
31005
  "notification",
@@ -30929,7 +31010,7 @@ var App = ({ compact: compact2 = false, continueSession: continueSession2 = fals
30929
31010
  setPendingApproval({ request, resolve: resolve31 });
30930
31011
  });
30931
31012
  }, []);
30932
- const agent = useRef(new Agent(client, process.cwd(), requestApproval, { executionMode: executionMode2, modeContract })).current;
31013
+ const agent = useRef2(new Agent(client, process.cwd(), requestApproval, { executionMode: executionMode2, modeContract })).current;
30933
31014
  agentRef.current = agent;
30934
31015
  const applyStandaloneSyncState = (state) => {
30935
31016
  const localChatId = "local-cli-chat";
@@ -30950,18 +31031,18 @@ var App = ({ compact: compact2 = false, continueSession: continueSession2 = fals
30950
31031
  setContinuityProfile(profile);
30951
31032
  if (profile === "standalone-private") agent.configureStandaloneSync(null);
30952
31033
  };
30953
- const trustStore = useRef(new TrustStore()).current;
30954
- const lastActivityRef = useRef(Date.now());
30955
- const pollingIntervalRef = useRef(null);
30956
- useEffect3(() => {
31034
+ const trustStore = useRef2(new TrustStore()).current;
31035
+ const lastActivityRef = useRef2(Date.now());
31036
+ const pollingIntervalRef = useRef2(null);
31037
+ useEffect4(() => {
30957
31038
  agent.setApprovalCallback(requestApproval);
30958
31039
  }, [agent, requestApproval]);
30959
- useEffect3(() => {
31040
+ useEffect4(() => {
30960
31041
  if (bypassExpiry === null) return;
30961
31042
  const timer = setInterval(() => setPermissionNow(Date.now()), 1e3);
30962
31043
  return () => clearInterval(timer);
30963
31044
  }, [bypassExpiry]);
30964
- useEffect3(() => {
31045
+ useEffect4(() => {
30965
31046
  agent.setOnModeChange((m) => {
30966
31047
  setModeState(m);
30967
31048
  addMessage("system", `Mode changed to: ${m} (via plan-mode tool)`);
@@ -30990,7 +31071,7 @@ var App = ({ compact: compact2 = false, continueSession: continueSession2 = fals
30990
31071
  setModeState(m);
30991
31072
  agent.setMode(m, source);
30992
31073
  }, [agent]);
30993
- useEffect3(() => {
31074
+ useEffect4(() => {
30994
31075
  if (mode !== "bypassPermissions" || !isBypassExpired(bypassExpiry, permissionNow)) return;
30995
31076
  setMode("default");
30996
31077
  setBypassExpiry(null);
@@ -31006,7 +31087,7 @@ var App = ({ compact: compact2 = false, continueSession: continueSession2 = fals
31006
31087
  setContextBudgetSnap(snapshotBudget(agent.getContextBudget()));
31007
31088
  }, [agent]);
31008
31089
  const getModel = useCallback2(() => activeModel, [activeModel]);
31009
- const cliProjectRef = useRef(null);
31090
+ const cliProjectRef = useRef2(null);
31010
31091
  const setProjectId = useCallback2((id) => {
31011
31092
  if (cliProjectRef.current && id !== cliProjectRef.current) return;
31012
31093
  setActiveProjectId(id);
@@ -31092,7 +31173,7 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31092
31173
  client.setToken("");
31093
31174
  setStatus("Session expired - run /login");
31094
31175
  }, [client, storage]);
31095
- useEffect3(() => {
31176
+ useEffect4(() => {
31096
31177
  agent.setAuthFailureHandler(handle401);
31097
31178
  return () => agent.setAuthFailureHandler(null);
31098
31179
  }, [agent, handle401]);
@@ -31113,7 +31194,7 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31113
31194
  setStatus(classifyCliError(error, { executionMode: executionMode2 }).summary);
31114
31195
  }
31115
31196
  }, [client, activeChatId, setProjectId, handle401]);
31116
- useEffect3(() => {
31197
+ useEffect4(() => {
31117
31198
  (async () => {
31118
31199
  try {
31119
31200
  if (executionMode2 === "local") {
@@ -31225,14 +31306,14 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31225
31306
  }
31226
31307
  })();
31227
31308
  }, []);
31228
- useEffect3(() => {
31309
+ useEffect4(() => {
31229
31310
  return () => {
31230
31311
  void agent.flushPendingToolTelemetry();
31231
31312
  void agent.flushPendingUsageTelemetry();
31232
31313
  agent.fireLifecycleHook("session-end", { cwd: process.cwd() });
31233
31314
  };
31234
31315
  }, []);
31235
- useEffect3(() => {
31316
+ useEffect4(() => {
31236
31317
  if (!user) return;
31237
31318
  createIdleAwarePoll(pollingIntervalRef, lastActivityRef, client, setUser, setUsageError);
31238
31319
  return () => {
@@ -31331,9 +31412,9 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31331
31412
  return { journalEvents, checkpoints };
31332
31413
  }
31333
31414
  });
31334
- const relayCommandRef = useRef(handleCommand);
31415
+ const relayCommandRef = useRef2(handleCommand);
31335
31416
  relayCommandRef.current = handleCommand;
31336
- useEffect3(() => {
31417
+ useEffect4(() => {
31337
31418
  if (executionMode2 !== "remote" || process.env.MSAPLING_RELAY_ENABLED !== "1" || !activeProjectId) return;
31338
31419
  let listener = null;
31339
31420
  let cancelled = false;
@@ -31362,44 +31443,66 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31362
31443
  }, [executionMode2, storage, activeProjectId, activeChatId]);
31363
31444
  const termHeight = termResizeRows ?? termStdout?.rows ?? 24;
31364
31445
  const termColumns = termResizeCols ?? termStdout?.columns ?? 80;
31446
+ const terminalLayout = resolveTerminalLayout(termHeight, termColumns, compact2);
31447
+ const compactPresentation = terminalLayout.density !== "full";
31365
31448
  const normalizedFooterOptions = normalizeFooterOptions(footerOptions);
31366
- const footerRows = compact2 ? 0 : 4 + (normalizedFooterOptions.expanded && normalizedFooterOptions.chat ? 1 : 0) + Number(normalizedFooterOptions.location) + Number(normalizedFooterOptions.permissions) + Number(normalizedFooterOptions.tokens) + Number(normalizedFooterOptions.context) + Number(normalizedFooterOptions.costs) + Number(normalizedFooterOptions.budget);
31367
- const modeRows = mode === "plan" || mode === "bypassPermissions" ? 4 : 0;
31449
+ const footerRows = terminalLayout.showFooter ? 4 + (normalizedFooterOptions.expanded && normalizedFooterOptions.chat ? 1 : 0) + Number(normalizedFooterOptions.location) + Number(normalizedFooterOptions.permissions) + Number(normalizedFooterOptions.tokens) + Number(normalizedFooterOptions.context) + Number(normalizedFooterOptions.costs) + Number(normalizedFooterOptions.budget) : 0;
31450
+ const modeRows = mode === "plan" || mode === "bypassPermissions" ? terminalLayout.density === "full" ? 4 : 1 : 0;
31368
31451
  const activityRows = pendingApproval ? 6 : pendingAskUser ? 10 : isRunning ? 2 : 0;
31369
- const visibleLines = Math.max(termHeight - (16 + footerRows + modeRows + activityRows), 1);
31452
+ const visibleLines = Math.max(termHeight - (terminalLayout.fixedRows + footerRows + modeRows + activityRows), 1);
31370
31453
  const displayedHistory = historyView ?? history;
31371
31454
  const historyPageStep = Math.max(1, Math.floor(visibleLines / 3));
31455
+ const viewport = computeViewport(displayedHistory, visibleLines, termColumns, historyOffset);
31456
+ const canScrollOlder = viewport.hiddenCount > 0;
31457
+ const canScrollNewer = historyOffset > 0;
31458
+ const scrollTranscript = useCallback2((direction, page = false) => {
31459
+ const amount = page ? historyPageStep : 1;
31460
+ if (direction === "up") {
31461
+ setHistoryOffset((current) => Math.min(Math.max(0, displayedHistory.length - 1), current + amount));
31462
+ } else {
31463
+ setHistoryOffset((current) => Math.max(0, current - amount));
31464
+ }
31465
+ }, [displayedHistory.length, historyPageStep]);
31466
+ useTerminalMouseScroll((direction) => {
31467
+ if (!pendingApproval && !pendingAskUser) scrollTranscript(direction);
31468
+ });
31372
31469
  useInput4((input2, key) => {
31373
31470
  if (pendingApproval || pendingAskUser) return;
31374
31471
  if (key.pageUp) {
31375
- setHistoryOffset((current) => Math.min(Math.max(0, displayedHistory.length - 1), current + historyPageStep));
31472
+ scrollTranscript("up", true);
31376
31473
  } else if (key.pageDown) {
31377
- setHistoryOffset((current) => Math.max(0, current - historyPageStep));
31474
+ scrollTranscript("down", true);
31475
+ } else if (key.upArrow && input2.length === 0 && canScrollOlder) {
31476
+ scrollTranscript("up");
31477
+ } else if (key.downArrow && input2.length === 0 && canScrollNewer) {
31478
+ scrollTranscript("down");
31378
31479
  } else if (key.ctrl && input2 === "e") {
31379
31480
  setHistoryOffset(0);
31380
31481
  setHistoryView(null);
31381
31482
  }
31382
31483
  });
31383
- return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", padding: 1, children: [
31384
- /* @__PURE__ */ jsx7(Header, {}),
31385
- /* @__PURE__ */ jsx7(Box7, { marginBottom: compact2 ? 0 : 1, children: /* @__PURE__ */ jsx7(
31484
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", padding: terminalLayout.outerPadding, children: [
31485
+ /* @__PURE__ */ jsx7(Header, { compact: !terminalLayout.showFramedHeader }),
31486
+ /* @__PURE__ */ jsx7(Box7, { marginBottom: compactPresentation ? 0 : 1, children: /* @__PURE__ */ jsx7(
31386
31487
  VirtualizedMessageList,
31387
31488
  {
31388
31489
  messages: displayedHistory,
31389
31490
  visibleLines,
31390
31491
  termColumns,
31391
- compact: compact2,
31492
+ compact: compactPresentation,
31392
31493
  offsetFromEnd: historyOffset
31393
31494
  }
31394
31495
  ) }),
31395
- mode === "plan" && /* @__PURE__ */ jsxs7(Box7, { borderStyle: "single", borderColor: "blueBright", paddingX: 1, marginBottom: 1, children: [
31496
+ mode === "plan" && terminalLayout.density === "full" && /* @__PURE__ */ jsxs7(Box7, { borderStyle: "single", borderColor: "blueBright", paddingX: 1, marginBottom: 1, children: [
31396
31497
  /* @__PURE__ */ jsx7(Text7, { color: "blueBright", bold: true, children: "PLAN MODE " }),
31397
31498
  /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "(read-only \u2014 edits, run_command, sub_shell are blocked. /mode default to execute.)" })
31398
31499
  ] }),
31399
- mode === "bypassPermissions" && /* @__PURE__ */ jsxs7(Box7, { borderStyle: "single", borderColor: "redBright", paddingX: 1, marginBottom: 1, children: [
31500
+ mode === "plan" && terminalLayout.density !== "full" && /* @__PURE__ */ jsx7(Text7, { color: "blueBright", bold: true, children: "PLAN MODE \xB7 read-only" }),
31501
+ mode === "bypassPermissions" && terminalLayout.density === "full" && /* @__PURE__ */ jsxs7(Box7, { borderStyle: "single", borderColor: "redBright", paddingX: 1, marginBottom: 1, children: [
31400
31502
  /* @__PURE__ */ jsx7(Text7, { color: "redBright", bold: true, children: "BYPASS " }),
31401
31503
  /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "(approvals disabled \u2014 every tool call runs without prompting. /mode default to re-enable.)" })
31402
31504
  ] }),
31505
+ mode === "bypassPermissions" && terminalLayout.density !== "full" && /* @__PURE__ */ jsx7(Text7, { color: "redBright", bold: true, children: "BYPASS \xB7 approvals disabled" }),
31403
31506
  isRunning && !pendingApproval && !pendingAskUser && /* @__PURE__ */ jsx7(Box7, { marginBottom: 1, children: /* @__PURE__ */ jsx7(Text7, { color: "yellow", children: "Thinking..." }) }),
31404
31507
  pendingApproval && /* @__PURE__ */ jsx7(
31405
31508
  ApprovalDialog,
@@ -31447,10 +31550,11 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31447
31550
  },
31448
31551
  disabled: bootstrapState === "loading" || isRunning || pendingApproval !== null || pendingAskUser !== null,
31449
31552
  storage,
31450
- promptColor: PROMPT_COLOR_BY_MODE[mode] ?? "green"
31553
+ promptColor: PROMPT_COLOR_BY_MODE[mode] ?? "green",
31554
+ transcriptNavigationActive: input.length === 0 && (canScrollOlder || canScrollNewer)
31451
31555
  }
31452
31556
  ),
31453
- /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "row", justifyContent: "space-between", children: [
31557
+ terminalLayout.density === "full" && /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "row", justifyContent: "space-between", children: [
31454
31558
  /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
31455
31559
  /* @__PURE__ */ jsxs7(Text7, { color: executionMode2 === "local" ? "yellow" : "cyan", children: [
31456
31560
  "Execution: ",
@@ -31490,7 +31594,32 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31490
31594
  contextBudgetSnap !== null && /* @__PURE__ */ jsx7(Text7, { color: contextBudgetColor(contextBudgetSnap.usedPct), children: formatContextBudgetLabel(contextBudgetSnap) })
31491
31595
  ] })
31492
31596
  ] }),
31493
- !compact2 && /* @__PURE__ */ jsx7(
31597
+ terminalLayout.density === "condensed" && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
31598
+ /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate-end", color: executionMode2 === "local" ? "yellow" : "cyan", children: [
31599
+ executionMode2 === "local" ? "LOCAL" : remoteEnvironment.label.replace("CONNECTED ", ""),
31600
+ " \xB7 ",
31601
+ mode,
31602
+ " \xB7 ",
31603
+ billingProfile,
31604
+ " \xB7 ",
31605
+ continuityProfile
31606
+ ] }),
31607
+ /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate-end", dimColor: true, children: [
31608
+ activeModel,
31609
+ contextBudgetSnap ? ` \xB7 ${formatContextBudgetLabel(contextBudgetSnap)}` : "",
31610
+ lastCost > 0 ? ` \xB7 last $${lastCost.toFixed(4)}` : ""
31611
+ ] })
31612
+ ] }),
31613
+ terminalLayout.density === "minimal" && /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate-end", dimColor: true, children: [
31614
+ executionMode2 === "local" ? "LOCAL" : remoteEnvironment.label.replace("CONNECTED ", ""),
31615
+ " \xB7 ",
31616
+ mode,
31617
+ " \xB7 ",
31618
+ activeModel,
31619
+ lastCost > 0 ? ` \xB7 $${lastCost.toFixed(4)}` : "",
31620
+ contextBudgetSnap ? ` \xB7 ctx ${contextBudgetSnap.usedPct}%` : ""
31621
+ ] }),
31622
+ terminalLayout.showFooter && /* @__PURE__ */ jsx7(
31494
31623
  Footer,
31495
31624
  {
31496
31625
  user,
@@ -31509,7 +31638,8 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31509
31638
  projectContained: true,
31510
31639
  attachmentPaths,
31511
31640
  usageError,
31512
- attachmentCount
31641
+ attachmentCount,
31642
+ terminalWidth: termColumns
31513
31643
  }
31514
31644
  )
31515
31645
  ] });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "msapling",
3
- "version": "2.3.6-beta.59",
3
+ "version": "2.3.6-beta.60",
4
4
  "description": "Short-name distribution of the MSapling CLI.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "MSapling Team",