@letta-ai/letta-code 0.19.1 → 0.19.2

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/letta.js +300 -60
  2. package/package.json +1 -1
package/letta.js CHANGED
@@ -3240,7 +3240,7 @@ var package_default;
3240
3240
  var init_package = __esm(() => {
3241
3241
  package_default = {
3242
3242
  name: "@letta-ai/letta-code",
3243
- version: "0.19.1",
3243
+ version: "0.19.2",
3244
3244
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
3245
3245
  type: "module",
3246
3246
  bin: {
@@ -6365,7 +6365,7 @@ name: recall
6365
6365
  description: Search conversation history to recall past discussions, decisions, and context
6366
6366
  tools: Bash, Read, TaskOutput
6367
6367
  skills: searching-messages
6368
- model: haiku
6368
+ model: auto-fast
6369
6369
  memoryBlocks: none
6370
6370
  mode: stateless
6371
6371
  ---
@@ -6965,6 +6965,7 @@ var init_models2 = __esm(() => {
6965
6965
  models: [
6966
6966
  {
6967
6967
  id: "auto",
6968
+ isDefault: true,
6968
6969
  handle: "letta/auto",
6969
6970
  label: "Auto",
6970
6971
  description: "Automatically select the best model",
@@ -6984,7 +6985,6 @@ var init_models2 = __esm(() => {
6984
6985
  handle: "anthropic/claude-sonnet-4-6",
6985
6986
  label: "Sonnet 4.6",
6986
6987
  description: "Anthropic's new Sonnet model (high reasoning)",
6987
- isDefault: true,
6988
6988
  isFeatured: true,
6989
6989
  updateArgs: {
6990
6990
  context_window: 200000,
@@ -42660,6 +42660,9 @@ class PermissionModeManager {
42660
42660
  const _effectivePlanFilePath = planFilePathOverride !== undefined ? planFilePathOverride : this.getPlanFilePath();
42661
42661
  switch (effectiveMode) {
42662
42662
  case "bypassPermissions":
42663
+ if (toolName === "ExitPlanMode" || toolName === "exit_plan_mode") {
42664
+ return null;
42665
+ }
42663
42666
  return "allow";
42664
42667
  case "acceptEdits":
42665
42668
  if ([
@@ -68131,7 +68134,125 @@ var init_manager3 = __esm(async () => {
68131
68134
  });
68132
68135
 
68133
68136
  // src/websocket/terminalHandler.ts
68137
+ import * as os4 from "node:os";
68134
68138
  import WebSocket from "ws";
68139
+ function getDefaultShell() {
68140
+ if (os4.platform() === "win32") {
68141
+ return process.env.COMSPEC || "cmd.exe";
68142
+ }
68143
+ return process.env.SHELL || "/bin/zsh";
68144
+ }
68145
+ function sendTerminalMessage(socket, message) {
68146
+ if (socket.readyState === WebSocket.OPEN) {
68147
+ socket.send(JSON.stringify(message));
68148
+ }
68149
+ }
68150
+ function handleTerminalSpawn(msg, socket, cwd2) {
68151
+ const { terminal_id, cols, rows } = msg;
68152
+ killTerminal(terminal_id);
68153
+ const shell2 = getDefaultShell();
68154
+ console.log(`[Terminal] Spawning PTY: shell=${shell2}, cwd=${cwd2}, cols=${cols}, rows=${rows}`);
68155
+ try {
68156
+ const proc2 = Bun.spawn([shell2], {
68157
+ cwd: cwd2,
68158
+ env: {
68159
+ ...process.env,
68160
+ TERM: "xterm-256color",
68161
+ COLORTERM: "truecolor"
68162
+ },
68163
+ terminal: {
68164
+ cols: cols || 80,
68165
+ rows: rows || 24,
68166
+ data: (() => {
68167
+ let buffer = "";
68168
+ let flushTimer = null;
68169
+ return (_terminal, data) => {
68170
+ buffer += new TextDecoder().decode(data);
68171
+ if (!flushTimer) {
68172
+ flushTimer = setTimeout(() => {
68173
+ if (buffer.length > 0) {
68174
+ sendTerminalMessage(socket, {
68175
+ type: "terminal_output",
68176
+ terminal_id,
68177
+ data: buffer
68178
+ });
68179
+ buffer = "";
68180
+ }
68181
+ flushTimer = null;
68182
+ }, 16);
68183
+ }
68184
+ };
68185
+ })()
68186
+ }
68187
+ });
68188
+ const terminal = proc2.terminal;
68189
+ console.log(`[Terminal] proc.pid=${proc2.pid}, terminal=${typeof terminal}, keys=${Object.keys(proc2).join(",")}`);
68190
+ if (!terminal) {
68191
+ console.error("[Terminal] terminal object is undefined on proc — Bun.Terminal API may not be available");
68192
+ sendTerminalMessage(socket, {
68193
+ type: "terminal_exited",
68194
+ terminal_id,
68195
+ exitCode: 1
68196
+ });
68197
+ return;
68198
+ }
68199
+ const session = {
68200
+ process: proc2,
68201
+ terminal,
68202
+ terminalId: terminal_id,
68203
+ spawnedAt: Date.now()
68204
+ };
68205
+ terminals.set(terminal_id, session);
68206
+ console.log(`[Terminal] Session stored for terminal_id=${terminal_id}, map size=${terminals.size}`);
68207
+ const myPid = proc2.pid;
68208
+ proc2.exited.then((exitCode) => {
68209
+ const current = terminals.get(terminal_id);
68210
+ if (current && current.process.pid === myPid) {
68211
+ console.log(`[Terminal] PTY process exited: terminal_id=${terminal_id}, pid=${myPid}, exitCode=${exitCode}`);
68212
+ terminals.delete(terminal_id);
68213
+ sendTerminalMessage(socket, {
68214
+ type: "terminal_exited",
68215
+ terminal_id,
68216
+ exitCode: exitCode ?? 0
68217
+ });
68218
+ } else {
68219
+ console.log(`[Terminal] Stale PTY exit ignored: terminal_id=${terminal_id}, pid=${myPid} (current pid=${current?.process.pid})`);
68220
+ }
68221
+ });
68222
+ sendTerminalMessage(socket, {
68223
+ type: "terminal_spawned",
68224
+ terminal_id,
68225
+ pid: proc2.pid
68226
+ });
68227
+ } catch (error) {
68228
+ console.error("[Terminal] Failed to spawn PTY:", error);
68229
+ sendTerminalMessage(socket, {
68230
+ type: "terminal_exited",
68231
+ terminal_id,
68232
+ exitCode: 1
68233
+ });
68234
+ }
68235
+ }
68236
+ function handleTerminalInput(msg) {
68237
+ const session = terminals.get(msg.terminal_id);
68238
+ if (session) {
68239
+ session.terminal.write(msg.data);
68240
+ }
68241
+ }
68242
+ function handleTerminalResize(msg) {
68243
+ const session = terminals.get(msg.terminal_id);
68244
+ if (session) {
68245
+ session.terminal.resize(msg.cols, msg.rows);
68246
+ }
68247
+ }
68248
+ function handleTerminalKill(msg) {
68249
+ const session = terminals.get(msg.terminal_id);
68250
+ if (session && Date.now() - session.spawnedAt < 2000) {
68251
+ console.log(`[Terminal] Ignoring kill for recently spawned session (age=${Date.now() - session.spawnedAt}ms)`);
68252
+ return;
68253
+ }
68254
+ killTerminal(msg.terminal_id);
68255
+ }
68135
68256
  function killTerminal(terminalId) {
68136
68257
  const session = terminals.get(terminalId);
68137
68258
  if (session) {
@@ -69568,11 +69689,35 @@ function isSyncCommand(value) {
69568
69689
  const candidate = value;
69569
69690
  return candidate.type === "sync" && isRuntimeScope(candidate.runtime);
69570
69691
  }
69692
+ function isTerminalSpawnCommand(value) {
69693
+ if (!value || typeof value !== "object")
69694
+ return false;
69695
+ const c = value;
69696
+ return c.type === "terminal_spawn" && typeof c.terminal_id === "string" && typeof c.cols === "number" && typeof c.rows === "number";
69697
+ }
69698
+ function isTerminalInputCommand(value) {
69699
+ if (!value || typeof value !== "object")
69700
+ return false;
69701
+ const c = value;
69702
+ return c.type === "terminal_input" && typeof c.terminal_id === "string" && typeof c.data === "string";
69703
+ }
69704
+ function isTerminalResizeCommand(value) {
69705
+ if (!value || typeof value !== "object")
69706
+ return false;
69707
+ const c = value;
69708
+ return c.type === "terminal_resize" && typeof c.terminal_id === "string" && typeof c.cols === "number" && typeof c.rows === "number";
69709
+ }
69710
+ function isTerminalKillCommand(value) {
69711
+ if (!value || typeof value !== "object")
69712
+ return false;
69713
+ const c = value;
69714
+ return c.type === "terminal_kill" && typeof c.terminal_id === "string";
69715
+ }
69571
69716
  function parseServerMessage(data) {
69572
69717
  try {
69573
69718
  const raw = typeof data === "string" ? data : data.toString();
69574
69719
  const parsed = JSON.parse(raw);
69575
- if (isInputCommand(parsed) || isChangeDeviceStateCommand(parsed) || isAbortMessageCommand(parsed) || isSyncCommand(parsed)) {
69720
+ if (isInputCommand(parsed) || isChangeDeviceStateCommand(parsed) || isAbortMessageCommand(parsed) || isSyncCommand(parsed) || isTerminalSpawnCommand(parsed) || isTerminalInputCommand(parsed) || isTerminalResizeCommand(parsed) || isTerminalKillCommand(parsed)) {
69576
69721
  return parsed;
69577
69722
  }
69578
69723
  const invalidInput = getInvalidInputReason(parsed);
@@ -75362,7 +75507,7 @@ function gatherGitContextSnapshot(options = {}) {
75362
75507
  var init_gitContext = () => {};
75363
75508
 
75364
75509
  // src/cli/helpers/sessionContext.ts
75365
- import { platform as platform3 } from "node:os";
75510
+ import { platform as platform4 } from "node:os";
75366
75511
  function getLocalTime() {
75367
75512
  const now = new Date;
75368
75513
  return now.toLocaleString(undefined, {
@@ -75376,7 +75521,7 @@ function getLocalTime() {
75376
75521
  });
75377
75522
  }
75378
75523
  function getDeviceType() {
75379
- const p = platform3();
75524
+ const p = platform4();
75380
75525
  switch (p) {
75381
75526
  case "darwin":
75382
75527
  return "macOS";
@@ -75449,7 +75594,7 @@ ${gitInfo.status}
75449
75594
  context3 += `- **Git repository**: No
75450
75595
  `;
75451
75596
  }
75452
- if (platform3() === "win32") {
75597
+ if (platform4() === "win32") {
75453
75598
  context3 += `
75454
75599
  ## Windows Shell Notes
75455
75600
  - The Bash tool uses PowerShell or cmd.exe on Windows
@@ -77092,6 +77237,22 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
77092
77237
  scheduleQueuePump(scopedRuntime, socket, opts, processQueuedTurn);
77093
77238
  return;
77094
77239
  }
77240
+ if (parsed.type === "terminal_spawn") {
77241
+ handleTerminalSpawn(parsed, socket, runtime.bootWorkingDirectory);
77242
+ return;
77243
+ }
77244
+ if (parsed.type === "terminal_input") {
77245
+ handleTerminalInput(parsed);
77246
+ return;
77247
+ }
77248
+ if (parsed.type === "terminal_resize") {
77249
+ handleTerminalResize(parsed);
77250
+ return;
77251
+ }
77252
+ if (parsed.type === "terminal_kill") {
77253
+ handleTerminalKill(parsed);
77254
+ return;
77255
+ }
77095
77256
  });
77096
77257
  socket.on("close", (code, reason) => {
77097
77258
  if (runtime !== getActiveRuntime()) {
@@ -78353,10 +78514,10 @@ __export(exports_overflow, {
78353
78514
  });
78354
78515
  import { randomUUID as randomUUID4 } from "node:crypto";
78355
78516
  import * as fs15 from "node:fs";
78356
- import * as os4 from "node:os";
78517
+ import * as os5 from "node:os";
78357
78518
  import * as path24 from "node:path";
78358
78519
  function getOverflowDirectory2(workingDirectory) {
78359
- const homeDir = os4.homedir();
78520
+ const homeDir = os5.homedir();
78360
78521
  const lettaDir = path24.join(homeDir, ".letta");
78361
78522
  const normalizedPath = path24.normalize(workingDirectory);
78362
78523
  const sanitizedPath = normalizedPath.replace(/^[/\\]/, "").replace(/[/\\:]/g, "_").replace(/\s+/g, "_");
@@ -82609,10 +82770,10 @@ var init_reconcileExistingAgentState = __esm(() => {
82609
82770
 
82610
82771
  // src/agent/sessionHistory.ts
82611
82772
  import * as fs17 from "node:fs";
82612
- import * as os5 from "node:os";
82773
+ import * as os6 from "node:os";
82613
82774
  import * as path25 from "node:path";
82614
82775
  function getHistoryDir() {
82615
- const homeDir = os5.homedir();
82776
+ const homeDir = os6.homedir();
82616
82777
  return path25.join(homeDir, ".letta-code");
82617
82778
  }
82618
82779
  function getHistoryFilePath() {
@@ -98252,6 +98413,26 @@ var init_lowlight = __esm(() => {
98252
98413
  });
98253
98414
 
98254
98415
  // src/cli/components/SyntaxHighlightedCommand.tsx
98416
+ function clipStyledSpans(spans, maxColumns) {
98417
+ if (maxColumns <= 0) {
98418
+ return { spans: [], clipped: spans.length > 0 };
98419
+ }
98420
+ let remaining = maxColumns;
98421
+ const clipped = [];
98422
+ for (const span of spans) {
98423
+ if (remaining <= 0) {
98424
+ return { spans: clipped, clipped: true };
98425
+ }
98426
+ if (span.text.length <= remaining) {
98427
+ clipped.push(span);
98428
+ remaining -= span.text.length;
98429
+ continue;
98430
+ }
98431
+ clipped.push({ text: span.text.slice(0, remaining), color: span.color });
98432
+ return { spans: clipped, clipped: true };
98433
+ }
98434
+ return { spans: clipped, clipped: false };
98435
+ }
98255
98436
  function languageFromPath(filePath) {
98256
98437
  const basename4 = filePath.split("/").pop() ?? filePath;
98257
98438
  const lower = basename4.toLowerCase();
@@ -98479,34 +98660,70 @@ var init_SyntaxHighlightedCommand = __esm(async () => {
98479
98660
  };
98480
98661
  HEREDOC_RE = /<<-?\s*['"]?(\w+)['"]?\s*$/;
98481
98662
  REDIRECT_FILE_RE = />>?\s+(\S+)/;
98482
- SyntaxHighlightedCommand = import_react34.memo(({ command, showPrompt = true, prefix, suffix }) => {
98663
+ SyntaxHighlightedCommand = import_react34.memo(({
98664
+ command,
98665
+ showPrompt = true,
98666
+ prefix,
98667
+ suffix,
98668
+ maxLines,
98669
+ maxColumns,
98670
+ showTruncationHint = false
98671
+ }) => {
98483
98672
  const palette = colors.shellSyntax;
98484
- const lines = highlightCommand(command, palette);
98673
+ const highlightedLines = highlightCommand(command, palette);
98674
+ const hasLineCap = typeof maxLines === "number" && maxLines >= 0;
98675
+ const visibleLines = hasLineCap ? highlightedLines.slice(0, maxLines) : highlightedLines;
98676
+ const hiddenLineCount = Math.max(0, highlightedLines.length - visibleLines.length);
98677
+ const renderedLines = [];
98678
+ let anyColumnClipping = false;
98679
+ for (let i = 0;i < visibleLines.length; i++) {
98680
+ const spans = visibleLines[i] ?? [];
98681
+ if (typeof maxColumns === "number") {
98682
+ const prefixLen = i === 0 && prefix ? prefix.length : 0;
98683
+ const suffixLen = i === visibleLines.length - 1 && suffix ? suffix.length : 0;
98684
+ const textBudget = Math.max(0, maxColumns - prefixLen - suffixLen);
98685
+ const clipped = clipStyledSpans(spans, textBudget);
98686
+ renderedLines.push(clipped.spans);
98687
+ anyColumnClipping = anyColumnClipping || clipped.clipped;
98688
+ } else {
98689
+ renderedLines.push(spans);
98690
+ }
98691
+ }
98485
98692
  return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
98486
98693
  flexDirection: "column",
98487
- children: lines.map((spans, lineIdx) => {
98488
- const lineKey = spans.map((s) => s.text).join("");
98489
- return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
98490
- children: [
98491
- showPrompt ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
98492
- color: palette.prompt,
98493
- children: lineIdx === 0 ? FIRST_LINE_PREFIX : " "
98494
- }, undefined, false, undefined, this) : null,
98495
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
98496
- color: palette.text,
98497
- children: [
98498
- lineIdx === 0 && prefix ? prefix : null,
98499
- spans.map((span, si) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
98500
- color: span.color,
98501
- children: span.text
98502
- }, `${si}:${span.color}`, false, undefined, this)),
98503
- lineIdx === lines.length - 1 && suffix ? suffix : null
98504
- ]
98505
- }, undefined, true, undefined, this)
98506
- ]
98507
- }, `${lineIdx}:${lineKey}`, true, undefined, this);
98508
- })
98509
- }, undefined, false, undefined, this);
98694
+ children: [
98695
+ renderedLines.map((spans, lineIdx) => {
98696
+ const lineKey = spans.map((s) => s.text).join("");
98697
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
98698
+ children: [
98699
+ showPrompt ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
98700
+ color: palette.prompt,
98701
+ children: lineIdx === 0 ? FIRST_LINE_PREFIX : " "
98702
+ }, undefined, false, undefined, this) : null,
98703
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
98704
+ color: palette.text,
98705
+ children: [
98706
+ lineIdx === 0 && prefix ? prefix : null,
98707
+ spans.map((span, si) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
98708
+ color: span.color,
98709
+ children: span.text
98710
+ }, `${si}:${span.color}`, false, undefined, this)),
98711
+ lineIdx === renderedLines.length - 1 && suffix ? suffix : null
98712
+ ]
98713
+ }, undefined, true, undefined, this)
98714
+ ]
98715
+ }, `${lineIdx}:${lineKey}`, true, undefined, this);
98716
+ }),
98717
+ showTruncationHint && hiddenLineCount > 0 && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
98718
+ dimColor: true,
98719
+ children: `… +${hiddenLineCount} more lines`
98720
+ }, undefined, false, undefined, this),
98721
+ showTruncationHint && hiddenLineCount === 0 && anyColumnClipping && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text2, {
98722
+ dimColor: true,
98723
+ children: "… output clipped"
98724
+ }, undefined, false, undefined, this)
98725
+ ]
98726
+ }, undefined, true, undefined, this);
98510
98727
  });
98511
98728
  SyntaxHighlightedCommand.displayName = "SyntaxHighlightedCommand";
98512
98729
  });
@@ -99263,7 +99480,7 @@ var init_AdvancedDiffRenderer = __esm(async () => {
99263
99480
  });
99264
99481
 
99265
99482
  // src/cli/components/previews/BashPreview.tsx
99266
- var import_react36, jsx_dev_runtime15, SOLID_LINE3 = "─", BashPreview;
99483
+ var import_react36, jsx_dev_runtime15, SOLID_LINE3 = "─", BASH_PREVIEW_MAX_LINES = 3, BashPreview;
99267
99484
  var init_BashPreview = __esm(async () => {
99268
99485
  init_useTerminalWidth();
99269
99486
  init_colors();
@@ -99296,7 +99513,10 @@ var init_BashPreview = __esm(async () => {
99296
99513
  flexDirection: "column",
99297
99514
  children: [
99298
99515
  /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(SyntaxHighlightedCommand, {
99299
- command
99516
+ command,
99517
+ maxLines: BASH_PREVIEW_MAX_LINES,
99518
+ maxColumns: Math.max(10, columns - 2),
99519
+ showTruncationHint: true
99300
99520
  }, undefined, false, undefined, this),
99301
99521
  description && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text2, {
99302
99522
  dimColor: true,
@@ -99698,7 +99918,7 @@ var init_useTextInputCursor = __esm(() => {
99698
99918
  });
99699
99919
 
99700
99920
  // src/cli/components/InlineBashApproval.tsx
99701
- var import_react41, jsx_dev_runtime18, SOLID_LINE6 = "─", InlineBashApproval;
99921
+ var import_react41, jsx_dev_runtime18, SOLID_LINE6 = "─", BASH_PREVIEW_MAX_LINES2 = 3, InlineBashApproval;
99702
99922
  var init_InlineBashApproval = __esm(async () => {
99703
99923
  init_useProgressIndicator();
99704
99924
  init_useTerminalWidth();
@@ -99810,7 +100030,10 @@ var init_InlineBashApproval = __esm(async () => {
99810
100030
  flexDirection: "column",
99811
100031
  children: [
99812
100032
  /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(SyntaxHighlightedCommand, {
99813
- command: bashInfo.command
100033
+ command: bashInfo.command,
100034
+ maxLines: BASH_PREVIEW_MAX_LINES2,
100035
+ maxColumns: Math.max(10, columns - 2),
100036
+ showTruncationHint: true
99814
100037
  }, undefined, false, undefined, this),
99815
100038
  bashInfo.description && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
99816
100039
  marginTop: 1,
@@ -99822,7 +100045,7 @@ var init_InlineBashApproval = __esm(async () => {
99822
100045
  ]
99823
100046
  }, undefined, true, undefined, this)
99824
100047
  ]
99825
- }, undefined, true, undefined, this), [bashInfo.command, bashInfo.description, solidLine]);
100048
+ }, undefined, true, undefined, this), [bashInfo.command, bashInfo.description, solidLine, columns]);
99826
100049
  const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type reason · Esc to cancel" : "Enter to select · Esc to cancel";
99827
100050
  const optionsMarginTop = showPreview ? 1 : 0;
99828
100051
  return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
@@ -102435,6 +102658,7 @@ var init_CollapsedOutputDisplay = __esm(async () => {
102435
102658
  // src/cli/components/StreamingOutputDisplay.tsx
102436
102659
  var import_react53, jsx_dev_runtime30, StreamingOutputDisplay;
102437
102660
  var init_StreamingOutputDisplay = __esm(async () => {
102661
+ init_useTerminalWidth();
102438
102662
  await __promiseAll([
102439
102663
  init_build2(),
102440
102664
  init_Text2()
@@ -102442,6 +102666,7 @@ var init_StreamingOutputDisplay = __esm(async () => {
102442
102666
  import_react53 = __toESM(require_react(), 1);
102443
102667
  jsx_dev_runtime30 = __toESM(require_jsx_dev_runtime(), 1);
102444
102668
  StreamingOutputDisplay = import_react53.memo(({ streaming, showInterruptHint }) => {
102669
+ const columns = useTerminalWidth();
102445
102670
  const [, forceUpdate] = import_react53.useState(0);
102446
102671
  import_react53.useEffect(() => {
102447
102672
  const interval = setInterval(() => forceUpdate((n) => n + 1), 1000);
@@ -102450,6 +102675,16 @@ var init_StreamingOutputDisplay = __esm(async () => {
102450
102675
  const elapsed = Math.floor((Date.now() - streaming.startTime) / 1000);
102451
102676
  const { tailLines, totalLineCount } = streaming;
102452
102677
  const hiddenCount = Math.max(0, totalLineCount - tailLines.length);
102678
+ const contentWidth = Math.max(10, columns - 5);
102679
+ const clipToWidth = (text) => {
102680
+ if (text.length <= contentWidth) {
102681
+ return text;
102682
+ }
102683
+ if (contentWidth <= 1) {
102684
+ return "…";
102685
+ }
102686
+ return `${text.slice(0, contentWidth - 1)}…`;
102687
+ };
102453
102688
  const firstLine = tailLines[0];
102454
102689
  const interruptHint = showInterruptHint ? " (esc to interrupt)" : "";
102455
102690
  if (!firstLine) {
@@ -102472,7 +102707,7 @@ var init_StreamingOutputDisplay = __esm(async () => {
102472
102707
  /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text2, {
102473
102708
  dimColor: !firstLine.isStderr,
102474
102709
  color: firstLine.isStderr ? "red" : undefined,
102475
- children: firstLine.text
102710
+ children: clipToWidth(firstLine.text)
102476
102711
  }, undefined, false, undefined, this)
102477
102712
  ]
102478
102713
  }, undefined, true, undefined, this),
@@ -102481,7 +102716,7 @@ var init_StreamingOutputDisplay = __esm(async () => {
102481
102716
  color: line.isStderr ? "red" : undefined,
102482
102717
  children: [
102483
102718
  " ",
102484
- line.text
102719
+ clipToWidth(line.text)
102485
102720
  ]
102486
102721
  }, i, true, undefined, this)),
102487
102722
  hiddenCount > 0 && /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text2, {
@@ -104460,7 +104695,7 @@ import {
104460
104695
  readFileSync as readFileSync12,
104461
104696
  writeFileSync as writeFileSync13
104462
104697
  } from "node:fs";
104463
- import { homedir as homedir28, platform as platform4 } from "node:os";
104698
+ import { homedir as homedir28, platform as platform5 } from "node:os";
104464
104699
  import { dirname as dirname13, join as join34 } from "node:path";
104465
104700
  function detectTerminalType() {
104466
104701
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
@@ -104491,17 +104726,17 @@ function getKeybindingsPath(terminal) {
104491
104726
  cursor: "Cursor",
104492
104727
  windsurf: "Windsurf"
104493
104728
  }[terminal];
104494
- const os6 = platform4();
104495
- if (os6 === "darwin") {
104729
+ const os7 = platform5();
104730
+ if (os7 === "darwin") {
104496
104731
  return join34(homedir28(), "Library", "Application Support", appName, "User", "keybindings.json");
104497
104732
  }
104498
- if (os6 === "win32") {
104733
+ if (os7 === "win32") {
104499
104734
  const appData = process.env.APPDATA;
104500
104735
  if (!appData)
104501
104736
  return null;
104502
104737
  return join34(appData, appName, "User", "keybindings.json");
104503
104738
  }
104504
- if (os6 === "linux") {
104739
+ if (os7 === "linux") {
104505
104740
  return join34(homedir28(), ".config", appName, "User", "keybindings.json");
104506
104741
  }
104507
104742
  return null;
@@ -107569,7 +107804,7 @@ var require_jsx_runtime = __commonJS((exports, module) => {
107569
107804
 
107570
107805
  // node_modules/supports-color/index.js
107571
107806
  import process19 from "node:process";
107572
- import os6 from "node:os";
107807
+ import os7 from "node:os";
107573
107808
  import tty2 from "node:tty";
107574
107809
  function hasFlag2(flag, argv = globalThis.Deno ? globalThis.Deno.args : process19.argv) {
107575
107810
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
@@ -107635,7 +107870,7 @@ function _supportsColor2(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
107635
107870
  return min;
107636
107871
  }
107637
107872
  if (process19.platform === "win32") {
107638
- const osRelease = os6.release().split(".");
107873
+ const osRelease = os7.release().split(".");
107639
107874
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
107640
107875
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
107641
107876
  }
@@ -121055,7 +121290,7 @@ function colorizeArgs(argsStr) {
121055
121290
  children: parts
121056
121291
  }, undefined, false, undefined, this);
121057
121292
  }
121058
- var import_react94, jsx_dev_runtime74, ToolCallMessage;
121293
+ var import_react94, jsx_dev_runtime74, LIVE_SHELL_ARGS_MAX_LINES = 2, ToolCallMessage;
121059
121294
  var init_ToolCallMessageRich = __esm(async () => {
121060
121295
  init_constants();
121061
121296
  init_subagentState();
@@ -121824,7 +122059,9 @@ var init_ToolCallMessageRich = __esm(async () => {
121824
122059
  command: shellCommand,
121825
122060
  showPrompt: false,
121826
122061
  prefix: "(",
121827
- suffix: ")"
122062
+ suffix: ")",
122063
+ maxLines: LIVE_SHELL_ARGS_MAX_LINES,
122064
+ maxColumns: Math.max(10, rightWidth - displayName.length)
121828
122065
  }, undefined, false, undefined, this)
121829
122066
  }, undefined, false, undefined, this) : args ? /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Box_default, {
121830
122067
  flexGrow: 1,
@@ -126130,7 +126367,7 @@ function App2({
126130
126367
  description = typeof args.description === "string" ? args.description : typeof args.justification === "string" ? args.justification : "";
126131
126368
  }
126132
126369
  let lines2 = 3;
126133
- lines2 += countWrappedLines(command, wrapWidth);
126370
+ lines2 += Math.min(countWrappedLines(command, wrapWidth), SHELL_PREVIEW_MAX_LINES);
126134
126371
  if (description) {
126135
126372
  lines2 += countWrappedLines(description, wrapWidth);
126136
126373
  }
@@ -133561,7 +133798,7 @@ Open /mcp to attach or detach tools for this server.`, true);
133561
133798
  ]
133562
133799
  }, resumeKey, true, undefined, this);
133563
133800
  }
133564
- var import_react101, jsx_dev_runtime78, CLEAR_SCREEN_AND_HOME = "\x1B[2J\x1B[H", MIN_RESIZE_DELTA = 2, RESIZE_SETTLE_MS = 250, MIN_CLEAR_INTERVAL_MS = 750, STABLE_WIDTH_SETTLE_MS = 180, TOOL_CALL_COMMIT_DEFER_MS = 50, ANIMATION_RESUME_HYSTERESIS_ROWS = 2, EAGER_CANCEL = true, LLM_API_ERROR_MAX_RETRIES3 = 3, EMPTY_RESPONSE_MAX_RETRIES3 = 2, CONVERSATION_BUSY_MAX_RETRIES2 = 3, INTERRUPT_MESSAGE = "Interrupted – tell the agent what to do differently. Something went wrong? Use /feedback to report issues.", ERROR_FEEDBACK_HINT = "Something went wrong? Use /feedback to report issues.", OPUS_BEDROCK_FALLBACK_HINT = "Downstream provider issues? Use /model to switch to Bedrock Opus 4.5", PROVIDER_FALLBACK_HINT = "Downstream provider issues? Use /model to switch to another provider", INTERACTIVE_SLASH_COMMANDS, NON_STATE_COMMANDS, APPROVAL_OPTIONS_HEIGHT = 8, APPROVAL_PREVIEW_BUFFER = 4, MIN_WRAP_WIDTH = 10, TEXT_WRAP_GUTTER = 6, DIFF_WRAP_GUTTER = 12, AUTO_REFLECTION_DESCRIPTION = "Reflect on recent conversations";
133801
+ var import_react101, jsx_dev_runtime78, CLEAR_SCREEN_AND_HOME = "\x1B[2J\x1B[H", MIN_RESIZE_DELTA = 2, RESIZE_SETTLE_MS = 250, MIN_CLEAR_INTERVAL_MS = 750, STABLE_WIDTH_SETTLE_MS = 180, TOOL_CALL_COMMIT_DEFER_MS = 50, ANIMATION_RESUME_HYSTERESIS_ROWS = 2, EAGER_CANCEL = true, LLM_API_ERROR_MAX_RETRIES3 = 3, EMPTY_RESPONSE_MAX_RETRIES3 = 2, CONVERSATION_BUSY_MAX_RETRIES2 = 3, INTERRUPT_MESSAGE = "Interrupted – tell the agent what to do differently. Something went wrong? Use /feedback to report issues.", ERROR_FEEDBACK_HINT = "Something went wrong? Use /feedback to report issues.", OPUS_BEDROCK_FALLBACK_HINT = "Downstream provider issues? Use /model to switch to Bedrock Opus 4.5", PROVIDER_FALLBACK_HINT = "Downstream provider issues? Use /model to switch to another provider", INTERACTIVE_SLASH_COMMANDS, NON_STATE_COMMANDS, APPROVAL_OPTIONS_HEIGHT = 8, APPROVAL_PREVIEW_BUFFER = 4, MIN_WRAP_WIDTH = 10, TEXT_WRAP_GUTTER = 6, DIFF_WRAP_GUTTER = 12, SHELL_PREVIEW_MAX_LINES = 3, AUTO_REFLECTION_DESCRIPTION = "Reflect on recent conversations";
133565
133802
  var init_App2 = __esm(async () => {
133566
133803
  init_error();
133567
133804
  init_check_approval();
@@ -133736,7 +133973,7 @@ import {
133736
133973
  readFileSync as readFileSync18,
133737
133974
  writeFileSync as writeFileSync17
133738
133975
  } from "node:fs";
133739
- import { homedir as homedir35, platform as platform5 } from "node:os";
133976
+ import { homedir as homedir35, platform as platform6 } from "node:os";
133740
133977
  import { dirname as dirname16, join as join45 } from "node:path";
133741
133978
  function detectTerminalType2() {
133742
133979
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
@@ -133767,17 +134004,17 @@ function getKeybindingsPath2(terminal) {
133767
134004
  cursor: "Cursor",
133768
134005
  windsurf: "Windsurf"
133769
134006
  }[terminal];
133770
- const os7 = platform5();
133771
- if (os7 === "darwin") {
134007
+ const os8 = platform6();
134008
+ if (os8 === "darwin") {
133772
134009
  return join45(homedir35(), "Library", "Application Support", appName, "User", "keybindings.json");
133773
134010
  }
133774
- if (os7 === "win32") {
134011
+ if (os8 === "win32") {
133775
134012
  const appData = process.env.APPDATA;
133776
134013
  if (!appData)
133777
134014
  return null;
133778
134015
  return join45(appData, appName, "User", "keybindings.json");
133779
134016
  }
133780
- if (os7 === "linux") {
134017
+ if (os8 === "linux") {
133781
134018
  return join45(homedir35(), ".config", appName, "User", "keybindings.json");
133782
134019
  }
133783
134020
  return null;
@@ -139402,6 +139639,9 @@ class PermissionModeManager2 {
139402
139639
  const _effectivePlanFilePath = planFilePathOverride !== undefined ? planFilePathOverride : this.getPlanFilePath();
139403
139640
  switch (effectiveMode) {
139404
139641
  case "bypassPermissions":
139642
+ if (toolName === "ExitPlanMode" || toolName === "exit_plan_mode") {
139643
+ return null;
139644
+ }
139405
139645
  return "allow";
139406
139646
  case "acceptEdits":
139407
139647
  if ([
@@ -142605,4 +142845,4 @@ Error during initialization: ${message}`);
142605
142845
  }
142606
142846
  main();
142607
142847
 
142608
- //# debugId=271668920D12255A64756E2164756E21
142848
+ //# debugId=795EEAC4C0962C6964756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.19.1",
3
+ "version": "0.19.2",
4
4
  "description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5
5
  "type": "module",
6
6
  "bin": {