msapling 2.3.6-beta.59 → 2.3.6-beta.61

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 +218 -31
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -14450,6 +14450,14 @@ var init_Settings = __esm({
14450
14450
  });
14451
14451
 
14452
14452
  // ../core/src/agent/localModelPolicy.ts
14453
+ function buildDeterministicReadPlan(prompt4, availableTools) {
14454
+ if (MUTATING_INTENT.test(prompt4) || !LIST_DIRECTORY_INTENT.test(prompt4)) return null;
14455
+ if (!new Set(availableTools).has("list_directory")) return null;
14456
+ const absolute = (prompt4.match(QUOTED_WINDOWS_PATH)?.[1] ?? prompt4.match(WINDOWS_DRIVE_ROOT)?.[1] ?? prompt4.match(WINDOWS_ABSOLUTE_TOKEN)?.[1])?.trim();
14457
+ const drive = prompt4.match(WINDOWS_DRIVE_WORDS)?.[1] ?? prompt4.match(WINDOWS_DIRECTORY_THEN_DRIVE)?.[1];
14458
+ const path3 = absolute || (drive ? `${drive.toUpperCase()}:\\` : ".");
14459
+ return { tool: "list_directory", args: { path: path3 } };
14460
+ }
14453
14461
  function buildReadToolRecovery(prompt4, response, availableTools) {
14454
14462
  if (MUTATING_INTENT.test(prompt4)) return null;
14455
14463
  const hasReadIntent = SAFE_READ_INTENT.test(prompt4) || SAFE_READ_VERB.test(prompt4);
@@ -14478,7 +14486,7 @@ function inferCapability(model) {
14478
14486
  if (sizes.some((size) => size <= 7)) return "small";
14479
14487
  return "unknown";
14480
14488
  }
14481
- var LOCAL_ACCESS_DENIAL, SAFE_READ_INTENT, SAFE_READ_VERB, PATH_LIKE_INTENT, MUTATING_INTENT, READ_RECOVERY_TOOLS, SAFE_TOOLS;
14489
+ var LOCAL_ACCESS_DENIAL, SAFE_READ_INTENT, SAFE_READ_VERB, PATH_LIKE_INTENT, MUTATING_INTENT, READ_RECOVERY_TOOLS, LIST_DIRECTORY_INTENT, QUOTED_WINDOWS_PATH, WINDOWS_DRIVE_ROOT, WINDOWS_ABSOLUTE_TOKEN, WINDOWS_DRIVE_WORDS, WINDOWS_DIRECTORY_THEN_DRIVE, SAFE_TOOLS;
14482
14490
  var init_localModelPolicy = __esm({
14483
14491
  "../core/src/agent/localModelPolicy.ts"() {
14484
14492
  "use strict";
@@ -14489,6 +14497,12 @@ var init_localModelPolicy = __esm({
14489
14497
  PATH_LIKE_INTENT = /(?:[A-Za-z]:[\\/]|\/{1,2}[A-Za-z0-9_.-]+\/|\.\.?[\\/])[A-Za-z0-9_.\\/ -]*/;
14490
14498
  MUTATING_INTENT = /\b(?:create|overwrite|write|edit|modify|change|delete|remove|move|rename|execute|run|install|uninstall|commit|push|upload)\b/i;
14491
14499
  READ_RECOVERY_TOOLS = ["read_file", "list_directory", "glob_files", "grep_search"];
14500
+ LIST_DIRECTORY_INTENT = /\b(?:list|show|display|enumerate|review|inspect|what(?:'s| is)? (?:in|inside))\b[^\n]{0,120}\b(?:files?|folders?|director(?:y|ies)|drive|workspace|project)\b/i;
14501
+ QUOTED_WINDOWS_PATH = /["']([A-Za-z]:[\\/][^"']*)["']/;
14502
+ WINDOWS_DRIVE_ROOT = /\b([A-Za-z]:[\\/])(?=\s|$|[.,;:)])/;
14503
+ WINDOWS_ABSOLUTE_TOKEN = /\b([A-Za-z]:[\\/][^\s,;]*)/;
14504
+ WINDOWS_DRIVE_WORDS = /\b([A-Za-z])\s+(?:drive|directory)\b/i;
14505
+ WINDOWS_DIRECTORY_THEN_DRIVE = /\b(?:drive|directory)\s+([A-Za-z])\b/i;
14492
14506
  SAFE_TOOLS = /* @__PURE__ */ new Set([
14493
14507
  "read_file",
14494
14508
  "list_directory",
@@ -15028,6 +15042,33 @@ var init_Agent = __esm({
15028
15042
  }
15029
15043
  return this.executor.execute(toolName, args2, this.projectRoot);
15030
15044
  }
15045
+ async executeDeterministicReadAdapter(chatId, turnId, plan) {
15046
+ const toolCallId = `client-read-${randomUUID6()}`;
15047
+ const request = {
15048
+ toolName: plan.tool,
15049
+ toolCallId,
15050
+ turnId,
15051
+ input: plan.args
15052
+ };
15053
+ await this.modeContract?.recordToolRequest(request);
15054
+ try {
15055
+ const result = await this.executeTurnTool(plan.tool, plan.args, false);
15056
+ await this.modeContract?.recordToolResult(request, result.content, !!result.isError);
15057
+ this.recordRemoteToolTelemetry(
15058
+ chatId,
15059
+ turnId,
15060
+ toolCallId,
15061
+ plan.tool,
15062
+ result.isError ? "failed" : "completed"
15063
+ );
15064
+ return result;
15065
+ } catch (error) {
15066
+ const content = SafetyGuard.redact(error instanceof Error ? error.message : String(error));
15067
+ await this.modeContract?.recordToolResult(request, content, true);
15068
+ this.recordRemoteToolTelemetry(chatId, turnId, toolCallId, plan.tool, "failed");
15069
+ throw error;
15070
+ }
15071
+ }
15031
15072
  recordRemoteToolTelemetry(chatId, turnId, toolCallId, toolName, outcome) {
15032
15073
  if (this.executionMode !== "remote") return;
15033
15074
  if (this.toolTelemetryQueue.length >= TOOL_TELEMETRY_QUEUE_MAX) {
@@ -15277,7 +15318,37 @@ var init_Agent = __esm({
15277
15318
  structuredToolResults = false;
15278
15319
  }
15279
15320
  }
15280
- const queue = [{ prompt: prompt4, allowReadRecovery: true }];
15321
+ let initialQueueItem = { prompt: prompt4, allowReadRecovery: true };
15322
+ if (!localTurn) {
15323
+ const initialToolNames = this.getTurnToolSchemas(false).map((tool) => String(tool.name));
15324
+ const deterministicPlan = buildDeterministicReadPlan(prompt4, initialToolNames);
15325
+ if (deterministicPlan) {
15326
+ const diagnostic = `[MSapling: running safe local ${deterministicPlan.tool} before the connected model.]
15327
+ `;
15328
+ await this.modeContract?.recordOutput(chatId, contractTurnId, diagnostic);
15329
+ onContent(diagnostic);
15330
+ const result = await this.executeDeterministicReadAdapter(
15331
+ chatId,
15332
+ contractTurnId,
15333
+ deterministicPlan
15334
+ );
15335
+ const evidence = boundToolResultForModel(result.content);
15336
+ initialQueueItem = {
15337
+ prompt: `A trusted MSapling client read-only adapter executed ${deterministicPlan.tool} with ${JSON.stringify(deterministicPlan.args)} for the original request below.
15338
+
15339
+ <client_tool_result error="${result.isError === true}">
15340
+ ${evidence}
15341
+ </client_tool_result>
15342
+
15343
+ Original request: ${prompt4}
15344
+
15345
+ Answer directly from the tool result. Do not claim local access is unavailable, do not emit a patch or diff, and do not invent entries.`,
15346
+ allowedToolNames: [],
15347
+ allowReadRecovery: false
15348
+ };
15349
+ }
15350
+ }
15351
+ const queue = [initialQueueItem];
15281
15352
  let rounds = 0;
15282
15353
  let toolCallSeq = 0;
15283
15354
  let streamUsage = null;
@@ -15450,16 +15521,44 @@ ${next.prompt}`
15450
15521
  const recovery = !localTurn && allowReadRecovery && !remoteReadRecoveryUsed && !assistantResponse.includes("[MSapling: local model denied available file tools;") ? buildReadToolRecovery(prompt4, assistantResponse, turnTools.map((tool) => String(tool.name))) : null;
15451
15522
  if (recovery) {
15452
15523
  remoteReadRecoveryUsed = true;
15453
- const diagnostic = `
15524
+ const deterministicPlan = buildDeterministicReadPlan(prompt4, recovery.tools);
15525
+ if (deterministicPlan) {
15526
+ const diagnostic = `
15527
+
15528
+ [MSapling: connected model did not use the required read tool; running safe local ${deterministicPlan.tool}.]
15529
+ `;
15530
+ await this.modeContract?.recordOutput(chatId, contractTurnId, diagnostic);
15531
+ onContent(diagnostic);
15532
+ const result = await this.executeDeterministicReadAdapter(
15533
+ chatId,
15534
+ contractTurnId,
15535
+ deterministicPlan
15536
+ );
15537
+ const evidence = boundToolResultForModel(result.content);
15538
+ queue.push({
15539
+ prompt: `A trusted MSapling client read-only adapter executed ${deterministicPlan.tool} with ${JSON.stringify(deterministicPlan.args)} for the original request below.
15540
+
15541
+ <client_tool_result error="${result.isError === true}">
15542
+ ${evidence}
15543
+ </client_tool_result>
15544
+
15545
+ Original request: ${prompt4}
15546
+
15547
+ Answer from the tool result. Do not claim local access is unavailable.`,
15548
+ allowedToolNames: []
15549
+ });
15550
+ } else {
15551
+ const diagnostic = `
15454
15552
 
15455
15553
  [MSapling: connected model did not use required client file tools; retrying once with ${recovery.tools.join(", ")}.]
15456
15554
  `;
15457
- await this.modeContract?.recordOutput(chatId, contractTurnId, diagnostic);
15458
- onContent(diagnostic);
15459
- queue.push({
15460
- prompt: recovery.instruction,
15461
- allowedToolNames: recovery.tools
15462
- });
15555
+ await this.modeContract?.recordOutput(chatId, contractTurnId, diagnostic);
15556
+ onContent(diagnostic);
15557
+ queue.push({
15558
+ prompt: recovery.instruction,
15559
+ allowedToolNames: recovery.tools
15560
+ });
15561
+ }
15463
15562
  }
15464
15563
  continue;
15465
15564
  }
@@ -23566,7 +23665,7 @@ var init_version = __esm({
23566
23665
  description: "Show version information for CLI and core packages",
23567
23666
  category: "debug",
23568
23667
  handler: async (_args, context) => {
23569
- const cliVersion = true ? "2.3.6-beta.59" : "(dev)";
23668
+ const cliVersion = true ? "2.3.6-beta.61" : "(dev)";
23570
23669
  const coreVersion = true ? "2.3.6-beta.43" : "(dev)";
23571
23670
  const runtime = process.version;
23572
23671
  context.addMessage("system", "MSapling Version Info");
@@ -29601,10 +29700,13 @@ import { Box as Box7, Text as Text7, useApp, useInput as useInput4, useStdout }
29601
29700
  init_esm_shims();
29602
29701
  import { Box, Text } from "ink";
29603
29702
  import { jsx, jsxs } from "react/jsx-runtime";
29604
- var Header = () => /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, marginBottom: 1, children: [
29703
+ var Header = ({ compact: compact2 = false }) => compact2 ? /* @__PURE__ */ jsxs(Text, { bold: true, color: "cyan", children: [
29704
+ "\u25CF MSapling v",
29705
+ "2.3.6-beta.61"
29706
+ ] }) : /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, marginBottom: 1, children: [
29605
29707
  /* @__PURE__ */ jsxs(Text, { bold: true, color: "cyan", children: [
29606
29708
  "\u25CF MSapling CLI v",
29607
- "2.3.6-beta.59"
29709
+ "2.3.6-beta.61"
29608
29710
  ] }),
29609
29711
  /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "Platinum Tier Architecture" }) })
29610
29712
  ] });
@@ -29969,7 +30071,7 @@ var VirtualizedMessageList = ({
29969
30071
  );
29970
30072
  const separatorWidth = termColumns > 0 ? Math.min(termColumns, 60) : 60;
29971
30073
  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]` }),
30074
+ (hiddenCount > 0 || hiddenAfter > 0) && /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: `[\u2191 ${hiddenCount} older \xB7 \u2193 ${hiddenAfter} newer \xB7 \u2191/\u2193 or PageUp/PageDown \xB7 Ctrl+E latest]` }),
29973
30075
  displayMessages.map((msg, i) => /* @__PURE__ */ jsxs5(
29974
30076
  Box5,
29975
30077
  {
@@ -30596,7 +30698,8 @@ var TextInput = ({
30596
30698
  onCancel,
30597
30699
  disabled,
30598
30700
  storage,
30599
- promptColor = "green"
30701
+ promptColor = "green",
30702
+ transcriptNavigationActive = false
30600
30703
  }) => {
30601
30704
  const [history, setHistory] = useState3([]);
30602
30705
  const [historyIndex, setHistoryIndex] = useState3(-1);
@@ -30619,13 +30722,13 @@ var TextInput = ({
30619
30722
  }
30620
30723
  } else if (key.backspace || key.delete) {
30621
30724
  onChange(value.slice(0, -1));
30622
- } else if (key.upArrow) {
30725
+ } else if (key.ctrl && input === "p" || key.upArrow && !transcriptNavigationActive) {
30623
30726
  const nextIndex = historyIndex + 1;
30624
30727
  if (nextIndex < history.length) {
30625
30728
  setHistoryIndex(nextIndex);
30626
30729
  onChange(history[history.length - 1 - nextIndex]);
30627
30730
  }
30628
- } else if (key.downArrow) {
30731
+ } else if (key.ctrl && input === "n" || key.downArrow && !transcriptNavigationActive) {
30629
30732
  const nextIndex = historyIndex - 1;
30630
30733
  if (nextIndex >= 0) {
30631
30734
  setHistoryIndex(nextIndex);
@@ -30634,6 +30737,8 @@ var TextInput = ({
30634
30737
  setHistoryIndex(-1);
30635
30738
  onChange("");
30636
30739
  }
30740
+ } else if ((key.upArrow || key.downArrow) && transcriptNavigationActive) {
30741
+ return;
30637
30742
  } else if (input && !key.ctrl && !key.meta) {
30638
30743
  onChange(value + input);
30639
30744
  }
@@ -30875,6 +30980,42 @@ function releaseSubmission(lock2) {
30875
30980
  lock2.current = false;
30876
30981
  }
30877
30982
 
30983
+ // src/state/terminalLayout.ts
30984
+ init_esm_shims();
30985
+ function resolveTerminalLayout(rows, columns, forceCompact = false) {
30986
+ const safeRows = Number.isFinite(rows) && rows > 0 ? rows : 24;
30987
+ const safeColumns = Number.isFinite(columns) && columns > 0 ? columns : 80;
30988
+ const density = forceCompact || safeRows <= 34 ? "minimal" : safeRows <= 48 || safeColumns < 100 ? "condensed" : "full";
30989
+ if (density === "minimal") {
30990
+ return {
30991
+ density,
30992
+ outerPadding: 0,
30993
+ showFramedHeader: false,
30994
+ showFooter: false,
30995
+ statusRows: 1,
30996
+ fixedRows: 3
30997
+ };
30998
+ }
30999
+ if (density === "condensed") {
31000
+ return {
31001
+ density,
31002
+ outerPadding: 0,
31003
+ showFramedHeader: false,
31004
+ showFooter: false,
31005
+ statusRows: 2,
31006
+ fixedRows: 5
31007
+ };
31008
+ }
31009
+ return {
31010
+ density,
31011
+ outerPadding: 1,
31012
+ showFramedHeader: true,
31013
+ showFooter: true,
31014
+ statusRows: 6,
31015
+ fixedRows: 16
31016
+ };
31017
+ }
31018
+
30878
31019
  // src/App.tsx
30879
31020
  import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
30880
31021
  var App = ({ compact: compact2 = false, continueSession: continueSession2 = false, executionMode: executionMode2 = "remote" }) => {
@@ -31362,44 +31503,63 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31362
31503
  }, [executionMode2, storage, activeProjectId, activeChatId]);
31363
31504
  const termHeight = termResizeRows ?? termStdout?.rows ?? 24;
31364
31505
  const termColumns = termResizeCols ?? termStdout?.columns ?? 80;
31506
+ const terminalLayout = resolveTerminalLayout(termHeight, termColumns, compact2);
31507
+ const compactPresentation = terminalLayout.density !== "full";
31365
31508
  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;
31509
+ 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;
31510
+ const modeRows = mode === "plan" || mode === "bypassPermissions" ? terminalLayout.density === "full" ? 4 : 1 : 0;
31368
31511
  const activityRows = pendingApproval ? 6 : pendingAskUser ? 10 : isRunning ? 2 : 0;
31369
- const visibleLines = Math.max(termHeight - (16 + footerRows + modeRows + activityRows), 1);
31512
+ const visibleLines = Math.max(termHeight - (terminalLayout.fixedRows + footerRows + modeRows + activityRows), 1);
31370
31513
  const displayedHistory = historyView ?? history;
31371
31514
  const historyPageStep = Math.max(1, Math.floor(visibleLines / 3));
31515
+ const viewport = computeViewport(displayedHistory, visibleLines, termColumns, historyOffset);
31516
+ const canScrollOlder = viewport.hiddenCount > 0;
31517
+ const canScrollNewer = historyOffset > 0;
31518
+ const scrollTranscript = useCallback2((direction, page = false) => {
31519
+ const amount = page ? historyPageStep : 1;
31520
+ if (direction === "up") {
31521
+ setHistoryOffset((current) => Math.min(Math.max(0, displayedHistory.length - 1), current + amount));
31522
+ } else {
31523
+ setHistoryOffset((current) => Math.max(0, current - amount));
31524
+ }
31525
+ }, [displayedHistory.length, historyPageStep]);
31372
31526
  useInput4((input2, key) => {
31373
31527
  if (pendingApproval || pendingAskUser) return;
31374
31528
  if (key.pageUp) {
31375
- setHistoryOffset((current) => Math.min(Math.max(0, displayedHistory.length - 1), current + historyPageStep));
31529
+ scrollTranscript("up", true);
31376
31530
  } else if (key.pageDown) {
31377
- setHistoryOffset((current) => Math.max(0, current - historyPageStep));
31531
+ scrollTranscript("down", true);
31532
+ } else if (key.upArrow && input2.length === 0 && canScrollOlder) {
31533
+ scrollTranscript("up");
31534
+ } else if (key.downArrow && input2.length === 0 && canScrollNewer) {
31535
+ scrollTranscript("down");
31378
31536
  } else if (key.ctrl && input2 === "e") {
31379
31537
  setHistoryOffset(0);
31380
31538
  setHistoryView(null);
31381
31539
  }
31382
31540
  });
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(
31541
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", padding: terminalLayout.outerPadding, children: [
31542
+ /* @__PURE__ */ jsx7(Header, { compact: !terminalLayout.showFramedHeader }),
31543
+ /* @__PURE__ */ jsx7(Box7, { marginBottom: compactPresentation ? 0 : 1, children: /* @__PURE__ */ jsx7(
31386
31544
  VirtualizedMessageList,
31387
31545
  {
31388
31546
  messages: displayedHistory,
31389
31547
  visibleLines,
31390
31548
  termColumns,
31391
- compact: compact2,
31549
+ compact: compactPresentation,
31392
31550
  offsetFromEnd: historyOffset
31393
31551
  }
31394
31552
  ) }),
31395
- mode === "plan" && /* @__PURE__ */ jsxs7(Box7, { borderStyle: "single", borderColor: "blueBright", paddingX: 1, marginBottom: 1, children: [
31553
+ mode === "plan" && terminalLayout.density === "full" && /* @__PURE__ */ jsxs7(Box7, { borderStyle: "single", borderColor: "blueBright", paddingX: 1, marginBottom: 1, children: [
31396
31554
  /* @__PURE__ */ jsx7(Text7, { color: "blueBright", bold: true, children: "PLAN MODE " }),
31397
31555
  /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "(read-only \u2014 edits, run_command, sub_shell are blocked. /mode default to execute.)" })
31398
31556
  ] }),
31399
- mode === "bypassPermissions" && /* @__PURE__ */ jsxs7(Box7, { borderStyle: "single", borderColor: "redBright", paddingX: 1, marginBottom: 1, children: [
31557
+ mode === "plan" && terminalLayout.density !== "full" && /* @__PURE__ */ jsx7(Text7, { color: "blueBright", bold: true, children: "PLAN MODE \xB7 read-only" }),
31558
+ mode === "bypassPermissions" && terminalLayout.density === "full" && /* @__PURE__ */ jsxs7(Box7, { borderStyle: "single", borderColor: "redBright", paddingX: 1, marginBottom: 1, children: [
31400
31559
  /* @__PURE__ */ jsx7(Text7, { color: "redBright", bold: true, children: "BYPASS " }),
31401
31560
  /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "(approvals disabled \u2014 every tool call runs without prompting. /mode default to re-enable.)" })
31402
31561
  ] }),
31562
+ mode === "bypassPermissions" && terminalLayout.density !== "full" && /* @__PURE__ */ jsx7(Text7, { color: "redBright", bold: true, children: "BYPASS \xB7 approvals disabled" }),
31403
31563
  isRunning && !pendingApproval && !pendingAskUser && /* @__PURE__ */ jsx7(Box7, { marginBottom: 1, children: /* @__PURE__ */ jsx7(Text7, { color: "yellow", children: "Thinking..." }) }),
31404
31564
  pendingApproval && /* @__PURE__ */ jsx7(
31405
31565
  ApprovalDialog,
@@ -31447,10 +31607,11 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31447
31607
  },
31448
31608
  disabled: bootstrapState === "loading" || isRunning || pendingApproval !== null || pendingAskUser !== null,
31449
31609
  storage,
31450
- promptColor: PROMPT_COLOR_BY_MODE[mode] ?? "green"
31610
+ promptColor: PROMPT_COLOR_BY_MODE[mode] ?? "green",
31611
+ transcriptNavigationActive: input.length === 0 && (canScrollOlder || canScrollNewer)
31451
31612
  }
31452
31613
  ),
31453
- /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "row", justifyContent: "space-between", children: [
31614
+ terminalLayout.density === "full" && /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "row", justifyContent: "space-between", children: [
31454
31615
  /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
31455
31616
  /* @__PURE__ */ jsxs7(Text7, { color: executionMode2 === "local" ? "yellow" : "cyan", children: [
31456
31617
  "Execution: ",
@@ -31490,7 +31651,32 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31490
31651
  contextBudgetSnap !== null && /* @__PURE__ */ jsx7(Text7, { color: contextBudgetColor(contextBudgetSnap.usedPct), children: formatContextBudgetLabel(contextBudgetSnap) })
31491
31652
  ] })
31492
31653
  ] }),
31493
- !compact2 && /* @__PURE__ */ jsx7(
31654
+ terminalLayout.density === "condensed" && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
31655
+ /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate-end", color: executionMode2 === "local" ? "yellow" : "cyan", children: [
31656
+ executionMode2 === "local" ? "LOCAL" : remoteEnvironment.label.replace("CONNECTED ", ""),
31657
+ " \xB7 ",
31658
+ mode,
31659
+ " \xB7 ",
31660
+ billingProfile,
31661
+ " \xB7 ",
31662
+ continuityProfile
31663
+ ] }),
31664
+ /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate-end", dimColor: true, children: [
31665
+ activeModel,
31666
+ contextBudgetSnap ? ` \xB7 ${formatContextBudgetLabel(contextBudgetSnap)}` : "",
31667
+ lastCost > 0 ? ` \xB7 last $${lastCost.toFixed(4)}` : ""
31668
+ ] })
31669
+ ] }),
31670
+ terminalLayout.density === "minimal" && /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate-end", dimColor: true, children: [
31671
+ executionMode2 === "local" ? "LOCAL" : remoteEnvironment.label.replace("CONNECTED ", ""),
31672
+ " \xB7 ",
31673
+ mode,
31674
+ " \xB7 ",
31675
+ activeModel,
31676
+ lastCost > 0 ? ` \xB7 $${lastCost.toFixed(4)}` : "",
31677
+ contextBudgetSnap ? ` \xB7 ctx ${contextBudgetSnap.usedPct}%` : ""
31678
+ ] }),
31679
+ terminalLayout.showFooter && /* @__PURE__ */ jsx7(
31494
31680
  Footer,
31495
31681
  {
31496
31682
  user,
@@ -31509,7 +31695,8 @@ ${renderCliError(classifyCliError(error, { executionMode: executionMode2 }))}`);
31509
31695
  projectContained: true,
31510
31696
  attachmentPaths,
31511
31697
  usageError,
31512
- attachmentCount
31698
+ attachmentCount,
31699
+ terminalWidth: termColumns
31513
31700
  }
31514
31701
  )
31515
31702
  ] });
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.61",
4
4
  "description": "Short-name distribution of the MSapling CLI.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "MSapling Team",