@letta-ai/letta-code 0.23.0 → 0.23.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 (2) hide show
  1. package/letta.js +457 -248
  2. package/package.json +1 -1
package/letta.js CHANGED
@@ -3269,7 +3269,7 @@ var package_default;
3269
3269
  var init_package = __esm(() => {
3270
3270
  package_default = {
3271
3271
  name: "@letta-ai/letta-code",
3272
- version: "0.23.0",
3272
+ version: "0.23.1",
3273
3273
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
3274
3274
  type: "module",
3275
3275
  bin: {
@@ -43143,6 +43143,7 @@ __export(exports_service, {
43143
43143
  removeChannelAccountLive: () => removeChannelAccountLive,
43144
43144
  refreshChannelAccountDisplayNameLive: () => refreshChannelAccountDisplayNameLive,
43145
43145
  listPendingPairingSnapshots: () => listPendingPairingSnapshots,
43146
+ listEnabledChannelIds: () => listEnabledChannelIds,
43146
43147
  listChannelTargetSnapshots: () => listChannelTargetSnapshots,
43147
43148
  listChannelSummaries: () => listChannelSummaries,
43148
43149
  listChannelRouteSnapshots: () => listChannelRouteSnapshots,
@@ -43400,6 +43401,9 @@ function listChannelSummaries() {
43400
43401
  };
43401
43402
  });
43402
43403
  }
43404
+ function listEnabledChannelIds() {
43405
+ return getSupportedChannelIds().filter((channelId) => listChannelAccounts(channelId).some((account) => account.enabled));
43406
+ }
43403
43407
  function getChannelConfigSnapshot(channelId, accountId) {
43404
43408
  assertSupportedChannelId(channelId);
43405
43409
  const account = getSelectedChannelAccount(channelId, accountId);
@@ -55627,7 +55631,8 @@ async function executeSingleDecision(decision, onChunk, options) {
55627
55631
  toolCallId: decision.approval.toolCallId,
55628
55632
  toolContextId: options?.toolContextId,
55629
55633
  parentScope: options?.parentScope,
55630
- onOutput: options?.onStreamingOutput ? (chunk, stream) => options.onStreamingOutput?.(decision.approval.toolCallId, chunk, stream === "stderr") : undefined
55634
+ onOutput: options?.onStreamingOutput ? (chunk, stream) => options.onStreamingOutput?.(decision.approval.toolCallId, chunk, stream === "stderr") : undefined,
55635
+ onFileWrite: options?.onFileWrite
55631
55636
  });
55632
55637
  if (onChunk) {
55633
55638
  onChunk({
@@ -77520,6 +77525,8 @@ var init_analyzer = __esm(() => {
77520
77525
  });
77521
77526
 
77522
77527
  // src/tools/manager.ts
77528
+ import * as nodeFs from "node:fs/promises";
77529
+ import * as nodePath from "node:path";
77523
77530
  function maybeAppendChannelTools(toolNames) {
77524
77531
  if (getActiveChannelIds().length > 0 && !toolNames.includes("MessageChannel")) {
77525
77532
  return [...toolNames, "MessageChannel"];
@@ -77590,8 +77597,8 @@ function acquireSwitchLock() {
77590
77597
  const lock = getSwitchLock();
77591
77598
  lock.refCount++;
77592
77599
  if (lock.refCount === 1) {
77593
- lock.promise = new Promise((resolve24) => {
77594
- lock.resolve = resolve24;
77600
+ lock.promise = new Promise((resolve25) => {
77601
+ lock.resolve = resolve25;
77595
77602
  });
77596
77603
  }
77597
77604
  }
@@ -78120,6 +78127,16 @@ async function executeTool(name, args, options) {
78120
78127
  const result = await withExecutionWorkingDirectory(workingDirectory, () => tool.fn(enhancedArgs));
78121
78128
  const duration = Date.now() - startTime;
78122
78129
  refreshFileIndex();
78130
+ if (options?.onFileWrite && FILE_MUTATING_TOOLS.has(internalName)) {
78131
+ const filePath = enhancedArgs.file_path;
78132
+ if (filePath) {
78133
+ try {
78134
+ const resolvedPath = nodePath.isAbsolute(filePath) ? filePath : nodePath.resolve(process.env.USER_CWD || process.cwd(), filePath);
78135
+ const content = await nodeFs.readFile(resolvedPath, "utf-8");
78136
+ options.onFileWrite(resolvedPath, content);
78137
+ } catch {}
78138
+ }
78139
+ }
78123
78140
  const recordResult = isRecord(result) ? result : undefined;
78124
78141
  const stdoutValue = recordResult?.stdout;
78125
78142
  const stderrValue = recordResult?.stderr;
@@ -78253,7 +78270,7 @@ function clearToolsWithLock() {
78253
78270
  releaseSwitchLock();
78254
78271
  }
78255
78272
  }
78256
- var TOOL_NAMES, STREAMING_SHELL_TOOLS, TOOL_NAME_MAPPINGS, ANTHROPIC_DEFAULT_TOOLS, OPENAI_DEFAULT_TOOLS, GEMINI_DEFAULT_TOOLS, OPENAI_PASCAL_TOOLS, GEMINI_PASCAL_TOOLS, REGISTRY_KEY, SWITCH_LOCK_KEY, EXECUTION_CONTEXTS_KEY, toolRegistry, toolExecutionContextCounter = 0, EXTERNAL_TOOLS_KEY, EXTERNAL_EXECUTOR_KEY;
78273
+ var TOOL_NAMES, STREAMING_SHELL_TOOLS, FILE_MUTATING_TOOLS, TOOL_NAME_MAPPINGS, ANTHROPIC_DEFAULT_TOOLS, OPENAI_DEFAULT_TOOLS, GEMINI_DEFAULT_TOOLS, OPENAI_PASCAL_TOOLS, GEMINI_PASCAL_TOOLS, REGISTRY_KEY, SWITCH_LOCK_KEY, EXECUTION_CONTEXTS_KEY, toolRegistry, toolExecutionContextCounter = 0, EXTERNAL_TOOLS_KEY, EXTERNAL_EXECUTOR_KEY;
78257
78274
  var init_manager3 = __esm(async () => {
78258
78275
  init_model2();
78259
78276
  init_subagents();
@@ -78283,6 +78300,7 @@ var init_manager3 = __esm(async () => {
78283
78300
  "run_shell_command",
78284
78301
  "RunShellCommand"
78285
78302
  ]);
78303
+ FILE_MUTATING_TOOLS = new Set(["Edit", "Write", "MultiEdit", "replace"]);
78286
78304
  TOOL_NAME_MAPPINGS = {
78287
78305
  glob_gemini: "glob",
78288
78306
  write_todos: "write_todos",
@@ -81705,7 +81723,7 @@ import {
81705
81723
  appendFile,
81706
81724
  mkdir as mkdir7,
81707
81725
  readdir as readdir5,
81708
- readFile as readFile9,
81726
+ readFile as readFile10,
81709
81727
  writeFile as writeFile7
81710
81728
  } from "node:fs/promises";
81711
81729
  import { homedir as homedir21, tmpdir as tmpdir3 } from "node:os";
@@ -81752,7 +81770,7 @@ async function collectParentMemoryFiles(memoryDir) {
81752
81770
  continue;
81753
81771
  }
81754
81772
  try {
81755
- const content = await readFile9(entryPath, "utf-8");
81773
+ const content = await readFile10(entryPath, "utf-8");
81756
81774
  const { frontmatter } = parseFrontmatter(content);
81757
81775
  const description = typeof frontmatter.description === "string" ? frontmatter.description : undefined;
81758
81776
  files.push({
@@ -82012,7 +82030,7 @@ async function ensurePaths(paths) {
82012
82030
  }
82013
82031
  async function readState(paths) {
82014
82032
  try {
82015
- const raw = await readFile9(paths.statePath, "utf-8");
82033
+ const raw = await readFile10(paths.statePath, "utf-8");
82016
82034
  const parsed = parseJsonLine(raw);
82017
82035
  if (!parsed) {
82018
82036
  return defaultState();
@@ -82032,7 +82050,7 @@ async function writeState(paths, state) {
82032
82050
  }
82033
82051
  async function readTranscriptLines(paths) {
82034
82052
  try {
82035
- const raw = await readFile9(paths.transcriptPath, "utf-8");
82053
+ const raw = await readFile10(paths.transcriptPath, "utf-8");
82036
82054
  return raw.split(`
82037
82055
  `).map((line) => line.trim()).filter((line) => line.length > 0);
82038
82056
  } catch {
@@ -82391,11 +82409,11 @@ async function discoverFallbackRunIdWithTimeout(client, ctx) {
82391
82409
  return withTimeout(discoverFallbackRunIdForResume(client, ctx), FALLBACK_RUN_DISCOVERY_TIMEOUT_MS, `Fallback run discovery timed out after ${FALLBACK_RUN_DISCOVERY_TIMEOUT_MS}ms`);
82392
82410
  }
82393
82411
  function withTimeout(promise, timeoutMs, timeoutMessage) {
82394
- return new Promise((resolve24, reject) => {
82412
+ return new Promise((resolve25, reject) => {
82395
82413
  const timer = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
82396
82414
  promise.then((value) => {
82397
82415
  clearTimeout(timer);
82398
- resolve24(value);
82416
+ resolve25(value);
82399
82417
  }, (error) => {
82400
82418
  clearTimeout(timer);
82401
82419
  reject(error);
@@ -83535,7 +83553,7 @@ function requestApprovalOverWS(runtime, socket, requestId, controlRequest) {
83535
83553
  if (isInterrupted()) {
83536
83554
  return Promise.reject(new Error("Cancelled by user"));
83537
83555
  }
83538
- return new Promise((resolve24, reject) => {
83556
+ return new Promise((resolve25, reject) => {
83539
83557
  let settled = false;
83540
83558
  const cleanupAbortListener = () => {
83541
83559
  abortSignal?.removeEventListener("abort", handleAbort);
@@ -83546,7 +83564,7 @@ function requestApprovalOverWS(runtime, socket, requestId, controlRequest) {
83546
83564
  }
83547
83565
  settled = true;
83548
83566
  cleanupAbortListener();
83549
- resolve24(response);
83567
+ resolve25(response);
83550
83568
  };
83551
83569
  const wrappedReject = (error) => {
83552
83570
  if (settled) {
@@ -87209,7 +87227,7 @@ async function sendMessageStreamWithRetry(conversationId, messages, opts, socket
87209
87227
  conversationId
87210
87228
  });
87211
87229
  }
87212
- await new Promise((resolve24) => setTimeout(resolve24, delayMs));
87230
+ await new Promise((resolve25) => setTimeout(resolve25, delayMs));
87213
87231
  if (abortSignal?.aborted) {
87214
87232
  throw new Error("Cancelled by user");
87215
87233
  }
@@ -87264,7 +87282,7 @@ async function sendMessageStreamWithRetry(conversationId, messages, opts, socket
87264
87282
  agentId: runtime.agentId ?? undefined,
87265
87283
  conversationId
87266
87284
  });
87267
- await new Promise((resolve24) => setTimeout(resolve24, delayMs));
87285
+ await new Promise((resolve25) => setTimeout(resolve25, delayMs));
87268
87286
  if (abortSignal?.aborted) {
87269
87287
  throw new Error("Cancelled by user");
87270
87288
  }
@@ -87339,7 +87357,7 @@ async function sendApprovalContinuationWithRetry(conversationId, messages, opts,
87339
87357
  retryAfterMs
87340
87358
  });
87341
87359
  transientRetries = attempt;
87342
- await new Promise((resolve24) => setTimeout(resolve24, delayMs));
87360
+ await new Promise((resolve25) => setTimeout(resolve25, delayMs));
87343
87361
  if (abortSignal?.aborted) {
87344
87362
  throw new Error("Cancelled by user");
87345
87363
  }
@@ -87384,7 +87402,7 @@ async function sendApprovalContinuationWithRetry(conversationId, messages, opts,
87384
87402
  category: "conversation_busy",
87385
87403
  attempt: conversationBusyRetries
87386
87404
  });
87387
- await new Promise((resolve24) => setTimeout(resolve24, retryDelayMs));
87405
+ await new Promise((resolve25) => setTimeout(resolve25, retryDelayMs));
87388
87406
  if (abortSignal?.aborted) {
87389
87407
  throw new Error("Cancelled by user");
87390
87408
  }
@@ -87422,6 +87440,7 @@ var init_send = __esm(async () => {
87422
87440
  });
87423
87441
 
87424
87442
  // src/websocket/listener/turn-approval.ts
87443
+ import WebSocket2 from "ws";
87425
87444
  async function handleApprovalStop(params) {
87426
87445
  const {
87427
87446
  approvals,
@@ -87647,11 +87666,24 @@ async function handleApprovalStop(params) {
87647
87666
  if (shouldInterrupt()) {
87648
87667
  return interruptTermination();
87649
87668
  }
87669
+ const onFileWrite = (filePath, content) => {
87670
+ if (socket.readyState === WebSocket2.OPEN) {
87671
+ socket.send(JSON.stringify({
87672
+ type: "file_ops",
87673
+ path: filePath,
87674
+ cg_entries: [],
87675
+ ops: [],
87676
+ source: "agent",
87677
+ document_content: content
87678
+ }));
87679
+ }
87680
+ };
87650
87681
  const executionResults = await executeApprovalBatch(decisions, undefined, {
87651
87682
  toolContextId: turnToolContextId ?? undefined,
87652
87683
  abortSignal: abortController.signal,
87653
87684
  workingDirectory: turnWorkingDirectory,
87654
- parentScope: agentId && conversationId ? { agentId, conversationId } : undefined
87685
+ parentScope: agentId && conversationId ? { agentId, conversationId } : undefined,
87686
+ onFileWrite
87655
87687
  });
87656
87688
  const persistedExecutionResults = normalizeExecutionResultsForInterruptParity(runtime, executionResults, lastExecutingToolCallIds);
87657
87689
  validateApprovalResultIds(decisions.map((decision) => ({
@@ -88276,7 +88308,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
88276
88308
  agentId,
88277
88309
  conversationId
88278
88310
  });
88279
- await new Promise((resolve24) => setTimeout(resolve24, delayMs));
88311
+ await new Promise((resolve25) => setTimeout(resolve25, delayMs));
88280
88312
  if (turnAbortSignal.aborted) {
88281
88313
  throw new Error("Cancelled by user");
88282
88314
  }
@@ -88321,7 +88353,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
88321
88353
  agentId,
88322
88354
  conversationId
88323
88355
  });
88324
- await new Promise((resolve24) => setTimeout(resolve24, delayMs));
88356
+ await new Promise((resolve25) => setTimeout(resolve25, delayMs));
88325
88357
  if (turnAbortSignal.aborted) {
88326
88358
  throw new Error("Cancelled by user");
88327
88359
  }
@@ -88811,7 +88843,7 @@ var init_commands = __esm(async () => {
88811
88843
  });
88812
88844
 
88813
88845
  // src/websocket/listener/protocol-outbound.ts
88814
- import WebSocket2 from "ws";
88846
+ import WebSocket3 from "ws";
88815
88847
  function getCachedDeviceGitContext(cwd2) {
88816
88848
  const now = Date.now();
88817
88849
  const cached = gitContextCache.get(cwd2);
@@ -88928,7 +88960,7 @@ function buildDeviceStatus(runtime, params) {
88928
88960
  return {
88929
88961
  current_connection_id: listener.connectionId,
88930
88962
  connection_name: listener.connectionName,
88931
- is_online: listener.socket?.readyState === WebSocket2.OPEN,
88963
+ is_online: listener.socket?.readyState === WebSocket3.OPEN,
88932
88964
  is_processing: !!conversationRuntime?.isProcessing,
88933
88965
  current_permission_mode: conversationPermissionModeState.mode,
88934
88966
  current_working_directory: resolvedCwd,
@@ -88996,7 +89028,7 @@ function setLoopStatus(runtime, status, scope) {
88996
89028
  emitLoopStatusIfOpen(runtime, scope);
88997
89029
  }
88998
89030
  function emitProtocolV2Message(socket, runtime, message, scope) {
88999
- if (socket.readyState !== WebSocket2.OPEN) {
89031
+ if (socket.readyState !== WebSocket3.OPEN) {
89000
89032
  return;
89001
89033
  }
89002
89034
  const listener = getListenerRuntime(runtime);
@@ -89048,13 +89080,13 @@ function emitLoopStatusUpdate(socket, runtime, scope) {
89048
89080
  }
89049
89081
  function emitLoopStatusIfOpen(runtime, scope) {
89050
89082
  const listener = getListenerRuntime(runtime);
89051
- if (listener?.socket?.readyState === WebSocket2.OPEN) {
89083
+ if (listener?.socket?.readyState === WebSocket3.OPEN) {
89052
89084
  emitLoopStatusUpdate(listener.socket, runtime, scope);
89053
89085
  }
89054
89086
  }
89055
89087
  function emitDeviceStatusIfOpen(runtime, scope) {
89056
89088
  const listener = getListenerRuntime(runtime);
89057
- if (listener?.socket?.readyState === WebSocket2.OPEN) {
89089
+ if (listener?.socket?.readyState === WebSocket3.OPEN) {
89058
89090
  emitDeviceStatusUpdate(listener.socket, runtime, scope);
89059
89091
  }
89060
89092
  }
@@ -89113,7 +89145,7 @@ function emitDequeuedUserMessage(socket, runtime, incoming, batch) {
89113
89145
  }
89114
89146
  function emitQueueUpdateIfOpen(runtime, scope) {
89115
89147
  const listener = getListenerRuntime(runtime);
89116
- if (listener?.socket?.readyState === WebSocket2.OPEN) {
89148
+ if (listener?.socket?.readyState === WebSocket3.OPEN) {
89117
89149
  emitQueueUpdate(listener.socket, runtime, scope);
89118
89150
  }
89119
89151
  }
@@ -89169,7 +89201,7 @@ function emitSubagentStateUpdate(socket, runtime, scope) {
89169
89201
  }
89170
89202
  function emitSubagentStateIfOpen(runtime, scope) {
89171
89203
  const listener = getListenerRuntime(runtime);
89172
- if (listener?.socket?.readyState === WebSocket2.OPEN) {
89204
+ if (listener?.socket?.readyState === WebSocket3.OPEN) {
89173
89205
  emitSubagentStateUpdate(listener.socket, runtime, scope);
89174
89206
  }
89175
89207
  }
@@ -89787,7 +89819,7 @@ var init_toolset_labels = __esm(() => {
89787
89819
 
89788
89820
  // src/websocket/terminalHandler.ts
89789
89821
  import * as os4 from "node:os";
89790
- import WebSocket3 from "ws";
89822
+ import WebSocket4 from "ws";
89791
89823
  function getDefaultShell() {
89792
89824
  if (os4.platform() === "win32") {
89793
89825
  return process.env.COMSPEC || "cmd.exe";
@@ -89795,7 +89827,7 @@ function getDefaultShell() {
89795
89827
  return process.env.SHELL || "/bin/zsh";
89796
89828
  }
89797
89829
  function sendTerminalMessage(socket, message) {
89798
- if (socket.readyState === WebSocket3.OPEN) {
89830
+ if (socket.readyState === WebSocket4.OPEN) {
89799
89831
  socket.send(JSON.stringify(message));
89800
89832
  }
89801
89833
  }
@@ -90163,6 +90195,12 @@ function isEditFileCommand(value) {
90163
90195
  const c = value;
90164
90196
  return c.type === "edit_file" && typeof c.file_path === "string" && typeof c.old_string === "string" && typeof c.new_string === "string" && typeof c.request_id === "string" && (c.replace_all === undefined || typeof c.replace_all === "boolean") && (c.expected_replacements === undefined || typeof c.expected_replacements === "number" && Number.isInteger(c.expected_replacements) && c.expected_replacements > 0);
90165
90197
  }
90198
+ function isFileOpsCommand(value) {
90199
+ if (!value || typeof value !== "object")
90200
+ return false;
90201
+ const c = value;
90202
+ return c.type === "file_ops" && typeof c.path === "string" && Array.isArray(c.cg_entries) && Array.isArray(c.ops) && typeof c.source === "string";
90203
+ }
90166
90204
  function isListMemoryCommand(value) {
90167
90205
  if (!value || typeof value !== "object")
90168
90206
  return false;
@@ -90453,7 +90491,7 @@ function parseServerMessage(data) {
90453
90491
  try {
90454
90492
  const raw = typeof data === "string" ? data : data.toString();
90455
90493
  const parsed = JSON.parse(raw);
90456
- if (isInputCommand(parsed) || isChangeDeviceStateCommand(parsed) || isAbortMessageCommand(parsed) || isSyncCommand(parsed) || isTerminalSpawnCommand(parsed) || isTerminalInputCommand(parsed) || isTerminalResizeCommand(parsed) || isTerminalKillCommand(parsed) || isSearchFilesCommand(parsed) || isListInDirectoryCommand(parsed) || isReadFileCommand(parsed) || isWriteFileCommand(parsed) || isWatchFileCommand(parsed) || isUnwatchFileCommand(parsed) || isEditFileCommand(parsed) || isListMemoryCommand(parsed) || isMemoryHistoryCommand(parsed) || isMemoryFileAtRefCommand(parsed) || isEnableMemfsCommand(parsed) || isListModelsCommand(parsed) || isUpdateModelCommand(parsed) || isCronListCommand(parsed) || isCronAddCommand(parsed) || isCronGetCommand(parsed) || isCronDeleteCommand(parsed) || isCronDeleteAllCommand(parsed) || isSkillEnableCommand(parsed) || isSkillDisableCommand(parsed) || isCreateAgentCommand(parsed) || isGetReflectionSettingsCommand(parsed) || isSetReflectionSettingsCommand(parsed) || isChannelsListCommand(parsed) || isChannelAccountsListCommand(parsed) || isChannelAccountCreateCommand(parsed) || isChannelAccountUpdateCommand(parsed) || isChannelAccountBindCommand(parsed) || isChannelAccountUnbindCommand(parsed) || isChannelAccountDeleteCommand(parsed) || isChannelAccountStartCommand(parsed) || isChannelAccountStopCommand(parsed) || isChannelGetConfigCommand(parsed) || isChannelSetConfigCommand(parsed) || isChannelStartCommand(parsed) || isChannelStopCommand(parsed) || isChannelPairingsListCommand(parsed) || isChannelPairingBindCommand(parsed) || isChannelRoutesListCommand(parsed) || isChannelTargetsListCommand(parsed) || isChannelTargetBindCommand(parsed) || isChannelRouteUpdateCommand(parsed) || isChannelRouteRemoveCommand(parsed) || isExecuteCommandCommand(parsed) || isSearchBranchesCommand(parsed) || isCheckoutBranchCommand(parsed)) {
90494
+ if (isInputCommand(parsed) || isChangeDeviceStateCommand(parsed) || isAbortMessageCommand(parsed) || isSyncCommand(parsed) || isTerminalSpawnCommand(parsed) || isTerminalInputCommand(parsed) || isTerminalResizeCommand(parsed) || isTerminalKillCommand(parsed) || isSearchFilesCommand(parsed) || isListInDirectoryCommand(parsed) || isReadFileCommand(parsed) || isWriteFileCommand(parsed) || isWatchFileCommand(parsed) || isUnwatchFileCommand(parsed) || isEditFileCommand(parsed) || isFileOpsCommand(parsed) || isListMemoryCommand(parsed) || isMemoryHistoryCommand(parsed) || isMemoryFileAtRefCommand(parsed) || isEnableMemfsCommand(parsed) || isListModelsCommand(parsed) || isUpdateModelCommand(parsed) || isCronListCommand(parsed) || isCronAddCommand(parsed) || isCronGetCommand(parsed) || isCronDeleteCommand(parsed) || isCronDeleteAllCommand(parsed) || isSkillEnableCommand(parsed) || isSkillDisableCommand(parsed) || isCreateAgentCommand(parsed) || isGetReflectionSettingsCommand(parsed) || isSetReflectionSettingsCommand(parsed) || isChannelsListCommand(parsed) || isChannelAccountsListCommand(parsed) || isChannelAccountCreateCommand(parsed) || isChannelAccountUpdateCommand(parsed) || isChannelAccountBindCommand(parsed) || isChannelAccountUnbindCommand(parsed) || isChannelAccountDeleteCommand(parsed) || isChannelAccountStartCommand(parsed) || isChannelAccountStopCommand(parsed) || isChannelGetConfigCommand(parsed) || isChannelSetConfigCommand(parsed) || isChannelStartCommand(parsed) || isChannelStopCommand(parsed) || isChannelPairingsListCommand(parsed) || isChannelPairingBindCommand(parsed) || isChannelRoutesListCommand(parsed) || isChannelTargetsListCommand(parsed) || isChannelTargetBindCommand(parsed) || isChannelRouteUpdateCommand(parsed) || isChannelRouteRemoveCommand(parsed) || isExecuteCommandCommand(parsed) || isSearchBranchesCommand(parsed) || isCheckoutBranchCommand(parsed)) {
90457
90495
  return parsed;
90458
90496
  }
90459
90497
  const invalidInput = getInvalidInputReason(parsed);
@@ -90474,6 +90512,135 @@ var init_protocol_inbound = __esm(async () => {
90474
90512
  await init_approval();
90475
90513
  });
90476
90514
 
90515
+ // src/websocket/listener/worktree-watcher.ts
90516
+ import { readdir as readdir6, stat as stat5, watch } from "node:fs/promises";
90517
+ import path22 from "node:path";
90518
+ function startWorktreeWatcher(params) {
90519
+ const { runtime, agentId, conversationId } = params;
90520
+ const cwd2 = getConversationWorkingDirectory(runtime, agentId, conversationId);
90521
+ const worktreesDir = path22.join(cwd2, WORKTREES_DIR);
90522
+ const abort = new AbortController;
90523
+ const state = { abort, watchedDir: worktreesDir };
90524
+ runWatchLoop({
90525
+ worktreesDir,
90526
+ abort,
90527
+ runtime,
90528
+ agentId,
90529
+ conversationId
90530
+ }).catch((err) => {
90531
+ if (err.name === "AbortError")
90532
+ return;
90533
+ console.error("[WorktreeWatcher] watch loop error:", err);
90534
+ });
90535
+ return state;
90536
+ }
90537
+ function stopWorktreeWatcher(state) {
90538
+ state.abort.abort();
90539
+ }
90540
+ function stopAllWorktreeWatchers(runtime) {
90541
+ for (const watcher of runtime.worktreeWatcherByConversation.values()) {
90542
+ stopWorktreeWatcher(watcher);
90543
+ }
90544
+ runtime.worktreeWatcherByConversation.clear();
90545
+ }
90546
+ function restartWorktreeWatcher(params) {
90547
+ const { runtime, agentId, conversationId } = params;
90548
+ const scopeKey = getWorkingDirectoryScopeKey(agentId, conversationId);
90549
+ const existing = runtime.worktreeWatcherByConversation.get(scopeKey);
90550
+ if (existing) {
90551
+ stopWorktreeWatcher(existing);
90552
+ runtime.worktreeWatcherByConversation.delete(scopeKey);
90553
+ }
90554
+ const state = startWorktreeWatcher(params);
90555
+ if (state) {
90556
+ runtime.worktreeWatcherByConversation.set(scopeKey, state);
90557
+ }
90558
+ }
90559
+ async function runWatchLoop(params) {
90560
+ const { worktreesDir, abort, runtime, agentId, conversationId } = params;
90561
+ const dirExists = await directoryExists(worktreesDir);
90562
+ if (!dirExists) {
90563
+ const lettaDir = path22.dirname(worktreesDir);
90564
+ const lettaDirExists = await directoryExists(lettaDir);
90565
+ if (!lettaDirExists) {
90566
+ return;
90567
+ }
90568
+ await waitForDirectoryCreation(lettaDir, "worktrees", abort.signal);
90569
+ }
90570
+ const existingEntries = new Set(await safeReaddir(worktreesDir));
90571
+ let debounceTimer = null;
90572
+ const watcher = watch(worktreesDir, { signal: abort.signal });
90573
+ for await (const event of watcher) {
90574
+ if (event.eventType !== "rename" || !event.filename)
90575
+ continue;
90576
+ if (existingEntries.has(event.filename))
90577
+ continue;
90578
+ if (debounceTimer)
90579
+ clearTimeout(debounceTimer);
90580
+ const filename = event.filename;
90581
+ debounceTimer = setTimeout(() => {
90582
+ handleNewWorktree({
90583
+ worktreesDir,
90584
+ filename,
90585
+ runtime,
90586
+ agentId,
90587
+ conversationId
90588
+ });
90589
+ }, DEBOUNCE_MS);
90590
+ }
90591
+ }
90592
+ async function handleNewWorktree(params) {
90593
+ const { worktreesDir, filename, runtime, agentId, conversationId } = params;
90594
+ const newWorktreePath = path22.join(worktreesDir, filename);
90595
+ if (!await directoryExists(newWorktreePath))
90596
+ return;
90597
+ const currentCwd = getConversationWorkingDirectory(runtime, agentId, conversationId);
90598
+ if (currentCwd === newWorktreePath)
90599
+ return;
90600
+ console.log(`[WorktreeWatcher] New worktree detected: ${newWorktreePath} — switching CWD`);
90601
+ setConversationWorkingDirectory(runtime, agentId, conversationId, newWorktreePath);
90602
+ const scopeKey = getWorkingDirectoryScopeKey(agentId, conversationId);
90603
+ const reminderState = runtime.reminderStateByConversation.get(scopeKey);
90604
+ if (reminderState) {
90605
+ reminderState.hasSentSessionContext = false;
90606
+ reminderState.pendingSessionContextReason = "cwd_changed";
90607
+ }
90608
+ if (runtime.socket) {
90609
+ emitDeviceStatusUpdate(runtime.socket, runtime, {
90610
+ agent_id: agentId,
90611
+ conversation_id: conversationId
90612
+ });
90613
+ }
90614
+ }
90615
+ async function waitForDirectoryCreation(parentDir, targetName, signal) {
90616
+ const watcher = watch(parentDir, { signal });
90617
+ for await (const event of watcher) {
90618
+ if (event.eventType === "rename" && event.filename === targetName && await directoryExists(path22.join(parentDir, targetName))) {
90619
+ return;
90620
+ }
90621
+ }
90622
+ }
90623
+ async function directoryExists(dir) {
90624
+ try {
90625
+ const stats = await stat5(dir);
90626
+ return stats.isDirectory();
90627
+ } catch {
90628
+ return false;
90629
+ }
90630
+ }
90631
+ async function safeReaddir(dir) {
90632
+ try {
90633
+ return await readdir6(dir);
90634
+ } catch {
90635
+ return [];
90636
+ }
90637
+ }
90638
+ var WORKTREES_DIR = ".letta/worktrees", DEBOUNCE_MS = 500;
90639
+ var init_worktree_watcher = __esm(async () => {
90640
+ init_cwd();
90641
+ await init_protocol_outbound();
90642
+ });
90643
+
90477
90644
  // src/agent/memoryScanner.ts
90478
90645
  var exports_memoryScanner = {};
90479
90646
  __export(exports_memoryScanner, {
@@ -90555,10 +90722,10 @@ var init_memoryScanner = () => {};
90555
90722
 
90556
90723
  // src/websocket/listener/client.ts
90557
90724
  import { execFile as execFile13 } from "node:child_process";
90558
- import { realpath as realpath3, stat as stat5 } from "node:fs/promises";
90559
- import path22 from "node:path";
90725
+ import { realpath as realpath3, stat as stat6 } from "node:fs/promises";
90726
+ import path23 from "node:path";
90560
90727
  import { promisify as promisify13 } from "node:util";
90561
- import WebSocket4 from "ws";
90728
+ import WebSocket5 from "ws";
90562
90729
  async function loadChannelsService() {
90563
90730
  if (channelsServiceLoaderOverride) {
90564
90731
  return channelsServiceLoaderOverride();
@@ -90573,7 +90740,7 @@ function trackListenerError(errorType, error, context3) {
90573
90740
  });
90574
90741
  }
90575
90742
  function safeSocketSend(socket, payload, errorType, context3) {
90576
- if (socket.readyState !== WebSocket4.OPEN) {
90743
+ if (socket.readyState !== WebSocket5.OPEN) {
90577
90744
  return false;
90578
90745
  }
90579
90746
  try {
@@ -91760,8 +91927,8 @@ async function handleSkillCommand(parsed, socket) {
91760
91927
  const linkPath = join31(globalSkillsDir, linkName);
91761
91928
  mkdirSync19(globalSkillsDir, { recursive: true });
91762
91929
  if (existsSync26(linkPath)) {
91763
- const stat6 = lstatSync2(linkPath);
91764
- if (stat6.isSymbolicLink()) {
91930
+ const stat7 = lstatSync2(linkPath);
91931
+ if (stat7.isSymbolicLink()) {
91765
91932
  if (process.platform === "win32") {
91766
91933
  rmdirSync(linkPath);
91767
91934
  } else {
@@ -91810,8 +91977,8 @@ async function handleSkillCommand(parsed, socket) {
91810
91977
  }, "listener_skill_send_failed", "listener_skill_command");
91811
91978
  return true;
91812
91979
  }
91813
- const stat6 = lstatSync2(linkPath);
91814
- if (!stat6.isSymbolicLink()) {
91980
+ const stat7 = lstatSync2(linkPath);
91981
+ if (!stat7.isSymbolicLink()) {
91815
91982
  safeSocketSend(socket, {
91816
91983
  type: "skill_disable_response",
91817
91984
  request_id: parsed.request_id,
@@ -92263,9 +92430,9 @@ async function handleCwdChange(msg, socket, runtime) {
92263
92430
  if (!requestedPath) {
92264
92431
  throw new Error("Working directory cannot be empty");
92265
92432
  }
92266
- const resolvedPath = path22.isAbsolute(requestedPath) ? requestedPath : path22.resolve(currentWorkingDirectory, requestedPath);
92433
+ const resolvedPath = path23.isAbsolute(requestedPath) ? requestedPath : path23.resolve(currentWorkingDirectory, requestedPath);
92267
92434
  const normalizedPath = await realpath3(resolvedPath);
92268
- const stats = await stat5(normalizedPath);
92435
+ const stats = await stat6(normalizedPath);
92269
92436
  if (!stats.isDirectory()) {
92270
92437
  throw new Error(`Not a directory: ${normalizedPath}`);
92271
92438
  }
@@ -92280,6 +92447,11 @@ async function handleCwdChange(msg, socket, runtime) {
92280
92447
  agent_id: agentId,
92281
92448
  conversation_id: conversationId
92282
92449
  });
92450
+ restartWorktreeWatcher({
92451
+ runtime: runtime.listener,
92452
+ agentId,
92453
+ conversationId
92454
+ });
92283
92455
  } catch (error) {
92284
92456
  emitLoopErrorNotice(socket, runtime, {
92285
92457
  message: error instanceof Error ? error.message : "Working directory change failed",
@@ -92309,6 +92481,7 @@ function createRuntime() {
92309
92481
  reminderState: createSharedReminderState(),
92310
92482
  bootWorkingDirectory,
92311
92483
  workingDirectoryByConversation: loadPersistedCwdMap(),
92484
+ worktreeWatcherByConversation: new Map,
92312
92485
  permissionModeByConversation: loadPersistedPermissionModeMap(),
92313
92486
  reminderStateByConversation: new Map,
92314
92487
  contextTrackerByConversation: new Map,
@@ -92340,6 +92513,7 @@ function stopRuntime(runtime, suppressCallbacks) {
92340
92513
  runtime.contextTrackerByConversation.clear();
92341
92514
  runtime.systemPromptRecompileByConversation.clear();
92342
92515
  runtime.queuedSystemPromptRecompileByConversation.clear();
92516
+ stopAllWorktreeWatchers(runtime);
92343
92517
  if (!runtime.socket) {
92344
92518
  return;
92345
92519
  }
@@ -92348,7 +92522,7 @@ function stopRuntime(runtime, suppressCallbacks) {
92348
92522
  if (suppressCallbacks) {
92349
92523
  socket.removeAllListeners();
92350
92524
  }
92351
- if (socket.readyState === WebSocket4.OPEN || socket.readyState === WebSocket4.CONNECTING) {
92525
+ if (socket.readyState === WebSocket5.OPEN || socket.readyState === WebSocket5.CONNECTING) {
92352
92526
  socket.close();
92353
92527
  }
92354
92528
  }
@@ -92383,8 +92557,8 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92383
92557
  const delay = Math.min(INITIAL_RETRY_DELAY_MS * 2 ** (attempt - 1), MAX_RETRY_DELAY_MS);
92384
92558
  const maxAttempts = Math.ceil(Math.log2(MAX_RETRY_DURATION_MS / INITIAL_RETRY_DELAY_MS));
92385
92559
  opts.onRetrying?.(attempt, maxAttempts, delay, opts.connectionId);
92386
- await new Promise((resolve24) => {
92387
- runtime.reconnectTimeout = setTimeout(resolve24, delay);
92560
+ await new Promise((resolve25) => {
92561
+ runtime.reconnectTimeout = setTimeout(resolve25, delay);
92388
92562
  });
92389
92563
  runtime.reconnectTimeout = null;
92390
92564
  if (runtime !== getActiveRuntime() || runtime.intentionallyClosed) {
@@ -92403,7 +92577,7 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92403
92577
  const url = new URL(opts.wsUrl);
92404
92578
  url.searchParams.set("deviceId", opts.deviceId);
92405
92579
  url.searchParams.set("connectionName", opts.connectionName);
92406
- const socket = new WebSocket4(url.toString(), {
92580
+ const socket = new WebSocket5(url.toString(), {
92407
92581
  headers: {
92408
92582
  Authorization: `Bearer ${apiKey}`
92409
92583
  }
@@ -92457,7 +92631,7 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92457
92631
  });
92458
92632
  runtime._unsubscribeSubagentStreamEvents?.();
92459
92633
  runtime._unsubscribeSubagentStreamEvents = subscribeToStreamEvents((subagentId, event) => {
92460
- if (socket.readyState !== WebSocket4.OPEN)
92634
+ if (socket.readyState !== WebSocket5.OPEN)
92461
92635
  return;
92462
92636
  const subagent = getSubagents().find((entry) => entry.id === subagentId);
92463
92637
  if (subagent?.silent === true) {
@@ -92483,7 +92657,7 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92483
92657
  scheduleQueuePump(targetRuntime, socket, opts, processQueuedTurn);
92484
92658
  });
92485
92659
  runtime.heartbeatInterval = setInterval(() => {
92486
- if (socket.readyState === WebSocket4.OPEN) {
92660
+ if (socket.readyState === WebSocket5.OPEN) {
92487
92661
  safeSocketSend(socket, { type: "ping" }, "listener_ping_send_failed", "listener_heartbeat");
92488
92662
  }
92489
92663
  }, 30000);
@@ -92644,14 +92818,14 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92644
92818
  try {
92645
92819
  if (parsed.cwd) {
92646
92820
  const currentRoot = getIndexRoot();
92647
- if (!parsed.cwd.startsWith(currentRoot + path22.sep) && parsed.cwd !== currentRoot) {
92821
+ if (!parsed.cwd.startsWith(currentRoot + path23.sep) && parsed.cwd !== currentRoot) {
92648
92822
  setIndexRoot(parsed.cwd);
92649
92823
  }
92650
92824
  }
92651
92825
  await ensureFileIndex2();
92652
92826
  let searchDir = ".";
92653
92827
  if (parsed.cwd) {
92654
- const rel = path22.relative(getIndexRoot(), parsed.cwd);
92828
+ const rel = path23.relative(getIndexRoot(), parsed.cwd);
92655
92829
  if (rel && !rel.startsWith("..") && rel !== "") {
92656
92830
  searchDir = rel;
92657
92831
  }
@@ -92685,9 +92859,9 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92685
92859
  console.log(`[Listen] Received list_in_directory command: path=${parsed.path}`);
92686
92860
  runDetachedListenerTask("list_in_directory", async () => {
92687
92861
  try {
92688
- const { readdir: readdir6 } = await import("node:fs/promises");
92862
+ const { readdir: readdir7 } = await import("node:fs/promises");
92689
92863
  console.log(`[Listen] Reading directory: ${parsed.path}`);
92690
- const entries = await readdir6(parsed.path, { withFileTypes: true });
92864
+ const entries = await readdir7(parsed.path, { withFileTypes: true });
92691
92865
  console.log(`[Listen] Directory read success, ${entries.length} entries`);
92692
92866
  const IGNORED_NAMES = new Set([
92693
92867
  ".DS_Store",
@@ -92746,8 +92920,8 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92746
92920
  console.log(`[Listen] Received read_file command: path=${parsed.path}, request_id=${parsed.request_id}`);
92747
92921
  runDetachedListenerTask("read_file", async () => {
92748
92922
  try {
92749
- const { readFile: readFile10 } = await import("node:fs/promises");
92750
- const content = await readFile10(parsed.path, "utf-8");
92923
+ const { readFile: readFile11 } = await import("node:fs/promises");
92924
+ const content = await readFile11(parsed.path, "utf-8");
92751
92925
  console.log(`[Listen] read_file success: ${parsed.path} (${content.length} bytes)`);
92752
92926
  safeSocketSend(socket, {
92753
92927
  type: "read_file_response",
@@ -92777,10 +92951,10 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92777
92951
  try {
92778
92952
  const { edit: edit2 } = await Promise.resolve().then(() => (init_Edit2(), exports_Edit));
92779
92953
  const { write: write2 } = await Promise.resolve().then(() => (init_Write2(), exports_Write));
92780
- const { readFile: readFile10 } = await import("node:fs/promises");
92954
+ const { readFile: readFile11 } = await import("node:fs/promises");
92781
92955
  let currentContent = null;
92782
92956
  try {
92783
- currentContent = await readFile10(parsed.path, "utf-8");
92957
+ currentContent = await readFile11(parsed.path, "utf-8");
92784
92958
  } catch (readErr) {
92785
92959
  const e = readErr;
92786
92960
  if (e.code !== "ENOENT")
@@ -92829,11 +93003,11 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92829
93003
  return;
92830
93004
  }
92831
93005
  try {
92832
- const { watch } = await import("node:fs");
92833
- const { stat: stat6 } = await import("node:fs/promises");
93006
+ const { watch: watch2 } = await import("node:fs");
93007
+ const { stat: stat7 } = await import("node:fs/promises");
92834
93008
  if (cancelledWatches.delete(parsed.path))
92835
93009
  return;
92836
- const watcher = watch(parsed.path, { persistent: false }, (eventType) => {
93010
+ const watcher = watch2(parsed.path, { persistent: false }, (eventType) => {
92837
93011
  if (eventType !== "change" && eventType !== "rename")
92838
93012
  return;
92839
93013
  const existing2 = watchDebounceTimers.get(parsed.path);
@@ -92841,7 +93015,7 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92841
93015
  clearTimeout(existing2);
92842
93016
  watchDebounceTimers.set(parsed.path, setTimeout(() => {
92843
93017
  watchDebounceTimers.delete(parsed.path);
92844
- stat6(parsed.path).then((s) => {
93018
+ stat7(parsed.path).then((s) => {
92845
93019
  safeSocketSend(socket, {
92846
93020
  type: "file_changed",
92847
93021
  path: parsed.path,
@@ -92887,6 +93061,7 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92887
93061
  console.log(`[Listen] Received edit_file command: file_path=${parsed.file_path}, request_id=${parsed.request_id}`);
92888
93062
  runDetachedListenerTask("edit_file", async () => {
92889
93063
  try {
93064
+ const { readFile: readFile11 } = await import("node:fs/promises");
92890
93065
  const { edit: edit2 } = await Promise.resolve().then(() => (init_Edit2(), exports_Edit));
92891
93066
  console.log(`[Listen] Executing edit: old_string="${parsed.old_string.slice(0, 50)}${parsed.old_string.length > 50 ? "..." : ""}"`);
92892
93067
  const result = await edit2({
@@ -92897,6 +93072,19 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92897
93072
  expected_replacements: parsed.expected_replacements
92898
93073
  });
92899
93074
  console.log(`[Listen] edit_file success: ${result.replacements} replacement(s) at line ${result.startLine}`);
93075
+ if (result.replacements > 0) {
93076
+ try {
93077
+ const contentAfter = await readFile11(parsed.file_path, "utf-8");
93078
+ safeSocketSend(socket, {
93079
+ type: "file_ops",
93080
+ path: parsed.file_path,
93081
+ cg_entries: [],
93082
+ ops: [],
93083
+ source: "agent",
93084
+ document_content: contentAfter
93085
+ }, "listener_edit_file_ops_send_failed", "listener_edit_file");
93086
+ } catch {}
93087
+ }
92900
93088
  safeSocketSend(socket, {
92901
93089
  type: "edit_file_response",
92902
93090
  request_id: parsed.request_id,
@@ -92922,6 +93110,21 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
92922
93110
  });
92923
93111
  return;
92924
93112
  }
93113
+ if (isFileOpsCommand(parsed)) {
93114
+ if (parsed.document_content !== undefined) {
93115
+ runDetachedListenerTask("file_ops", async () => {
93116
+ try {
93117
+ const { writeFile: writeFile9 } = await import("node:fs/promises");
93118
+ const content = parsed.document_content;
93119
+ await writeFile9(parsed.path, content, "utf-8");
93120
+ console.log(`[Listen] file_ops: wrote ${content.length} bytes to ${parsed.path}`);
93121
+ } catch (err) {
93122
+ console.error(`[Listen] file_ops error: ${err instanceof Error ? err.message : "Unknown error"}`);
93123
+ }
93124
+ });
93125
+ }
93126
+ return;
93127
+ }
92925
93128
  if (isListMemoryCommand(parsed)) {
92926
93129
  runDetachedListenerTask("list_memory", async () => {
92927
93130
  try {
@@ -93606,6 +93809,12 @@ function createLegacyTestRuntime() {
93606
93809
  listener.memfsSyncedAgents = value;
93607
93810
  }
93608
93811
  },
93812
+ worktreeWatcherByConversation: {
93813
+ get: () => listener.worktreeWatcherByConversation,
93814
+ set: (value) => {
93815
+ listener.worktreeWatcherByConversation = value;
93816
+ }
93817
+ },
93609
93818
  lastEmittedStatus: {
93610
93819
  get: () => listener.lastEmittedStatus,
93611
93820
  set: (value) => {
@@ -93675,6 +93884,7 @@ var init_client4 = __esm(async () => {
93675
93884
  init_recovery(),
93676
93885
  init_send(),
93677
93886
  init_turn(),
93887
+ init_worktree_watcher(),
93678
93888
  init_approval(),
93679
93889
  init_protocol_inbound(),
93680
93890
  init_protocol_outbound()
@@ -93788,8 +93998,8 @@ function isDebugEnabled2() {
93788
93998
  return lettaDebug === "1" || lettaDebug === "true" || legacyDebug === "1" || legacyDebug === "true";
93789
93999
  }
93790
94000
  function getDebugFile2() {
93791
- const path23 = process.env.LETTA_DEBUG_FILE;
93792
- return path23 && path23.trim().length > 0 ? path23 : null;
94001
+ const path24 = process.env.LETTA_DEBUG_FILE;
94002
+ return path24 && path24.trim().length > 0 ? path24 : null;
93793
94003
  }
93794
94004
  function printDebugLine2(line, level = "log") {
93795
94005
  const debugFile = getDebugFile2();
@@ -93913,7 +94123,7 @@ __export(exports_skills2, {
93913
94123
  GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR2
93914
94124
  });
93915
94125
  import { existsSync as existsSync28 } from "node:fs";
93916
- import { readdir as readdir7, readFile as readFile10, realpath as realpath4, stat as stat6 } from "node:fs/promises";
94126
+ import { readdir as readdir8, readFile as readFile11, realpath as realpath4, stat as stat7 } from "node:fs/promises";
93917
94127
  import { dirname as dirname13, join as join35 } from "node:path";
93918
94128
  import { fileURLToPath as fileURLToPath8 } from "node:url";
93919
94129
  function getBundledSkillsPath2() {
@@ -94003,14 +94213,14 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors, source, vi
94003
94213
  return;
94004
94214
  }
94005
94215
  try {
94006
- const entries = await readdir7(currentPath, { withFileTypes: true });
94216
+ const entries = await readdir8(currentPath, { withFileTypes: true });
94007
94217
  for (const entry of entries) {
94008
94218
  const fullPath = join35(currentPath, entry.name);
94009
94219
  try {
94010
94220
  let isDirectory = entry.isDirectory();
94011
94221
  let isFile = entry.isFile();
94012
94222
  if (entry.isSymbolicLink()) {
94013
- const entryStat = await stat6(fullPath);
94223
+ const entryStat = await stat7(fullPath);
94014
94224
  isDirectory = entryStat.isDirectory();
94015
94225
  isFile = entryStat.isFile();
94016
94226
  }
@@ -94044,7 +94254,7 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors, source, vi
94044
94254
  }
94045
94255
  }
94046
94256
  async function parseSkillFile2(filePath, rootPath, source) {
94047
- const content = await readFile10(filePath, "utf-8");
94257
+ const content = await readFile11(filePath, "utf-8");
94048
94258
  const { frontmatter, body } = parseFrontmatter(content);
94049
94259
  const normalizedRoot = rootPath.endsWith("/") ? rootPath.slice(0, -1) : rootPath;
94050
94260
  const relativePath = filePath.slice(normalizedRoot.length + 1);
@@ -94103,7 +94313,7 @@ __export(exports_fs, {
94103
94313
  writeJsonFile: () => writeJsonFile,
94104
94314
  writeFile: () => writeFile10,
94105
94315
  readJsonFile: () => readJsonFile,
94106
- readFile: () => readFile11,
94316
+ readFile: () => readFile12,
94107
94317
  mkdir: () => mkdir9,
94108
94318
  exists: () => exists2
94109
94319
  });
@@ -94114,31 +94324,31 @@ import {
94114
94324
  mkdirSync as mkdirSync21
94115
94325
  } from "node:fs";
94116
94326
  import { dirname as dirname14 } from "node:path";
94117
- async function readFile11(path23) {
94118
- return fsReadFileSync2(path23, { encoding: "utf-8" });
94327
+ async function readFile12(path24) {
94328
+ return fsReadFileSync2(path24, { encoding: "utf-8" });
94119
94329
  }
94120
- async function writeFile10(path23, content) {
94121
- const dir = dirname14(path23);
94330
+ async function writeFile10(path24, content) {
94331
+ const dir = dirname14(path24);
94122
94332
  if (!existsSync29(dir)) {
94123
94333
  mkdirSync21(dir, { recursive: true });
94124
94334
  }
94125
- fsWriteFileSync2(path23, content, { encoding: "utf-8", flush: true });
94335
+ fsWriteFileSync2(path24, content, { encoding: "utf-8", flush: true });
94126
94336
  }
94127
- function exists2(path23) {
94128
- return existsSync29(path23);
94337
+ function exists2(path24) {
94338
+ return existsSync29(path24);
94129
94339
  }
94130
- async function mkdir9(path23, options) {
94131
- mkdirSync21(path23, options);
94340
+ async function mkdir9(path24, options) {
94341
+ mkdirSync21(path24, options);
94132
94342
  }
94133
- async function readJsonFile(path23) {
94134
- const text = await readFile11(path23);
94343
+ async function readJsonFile(path24) {
94344
+ const text = await readFile12(path24);
94135
94345
  return JSON.parse(text);
94136
94346
  }
94137
- async function writeJsonFile(path23, data, options) {
94347
+ async function writeJsonFile(path24, data, options) {
94138
94348
  const indent = options?.indent ?? 2;
94139
94349
  const content = `${JSON.stringify(data, null, indent)}
94140
94350
  `;
94141
- await writeFile10(path23, content);
94351
+ await writeFile10(path24, content);
94142
94352
  }
94143
94353
  var init_fs2 = () => {};
94144
94354
 
@@ -94163,7 +94373,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
94163
94373
  }
94164
94374
  const wasRaw = process.stdin.isRaw;
94165
94375
  const wasFlowing = process.stdin.readableFlowing;
94166
- return new Promise((resolve26) => {
94376
+ return new Promise((resolve27) => {
94167
94377
  let response = "";
94168
94378
  let resolved = false;
94169
94379
  const cleanup = () => {
@@ -94180,7 +94390,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
94180
94390
  };
94181
94391
  const timeout = setTimeout(() => {
94182
94392
  cleanup();
94183
- resolve26(null);
94393
+ resolve27(null);
94184
94394
  }, timeoutMs);
94185
94395
  const onData = (data) => {
94186
94396
  response += data.toString();
@@ -94190,7 +94400,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
94190
94400
  if (match3) {
94191
94401
  clearTimeout(timeout);
94192
94402
  cleanup();
94193
- resolve26({
94403
+ resolve27({
94194
94404
  r: parseHexComponent(match3[1] ?? "0"),
94195
94405
  g: parseHexComponent(match3[2] ?? "0"),
94196
94406
  b: parseHexComponent(match3[3] ?? "0")
@@ -94205,7 +94415,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
94205
94415
  } catch {
94206
94416
  clearTimeout(timeout);
94207
94417
  cleanup();
94208
- resolve26(null);
94418
+ resolve27(null);
94209
94419
  }
94210
94420
  });
94211
94421
  }
@@ -94291,7 +94501,7 @@ __export(exports_manager2, {
94291
94501
  lspManager: () => lspManager2,
94292
94502
  LSPManager: () => LSPManager2
94293
94503
  });
94294
- import * as path23 from "node:path";
94504
+ import * as path24 from "node:path";
94295
94505
 
94296
94506
  class LSPManager2 {
94297
94507
  static instance = null;
@@ -94319,7 +94529,7 @@ class LSPManager2 {
94319
94529
  async getOrStartServer(filePath) {
94320
94530
  if (!this.enabled)
94321
94531
  return null;
94322
- const ext3 = path23.extname(filePath).toLowerCase();
94532
+ const ext3 = path24.extname(filePath).toLowerCase();
94323
94533
  const serverDef = this.serverDefinitions.find((s) => s.extensions.includes(ext3));
94324
94534
  if (!serverDef) {
94325
94535
  return null;
@@ -94387,7 +94597,7 @@ class LSPManager2 {
94387
94597
  const client = await this.getOrStartServer(filePath);
94388
94598
  if (!client)
94389
94599
  return;
94390
- const absolutePath = path23.isAbsolute(filePath) ? filePath : path23.resolve(process.cwd(), filePath);
94600
+ const absolutePath = path24.isAbsolute(filePath) ? filePath : path24.resolve(process.cwd(), filePath);
94391
94601
  const uri = `file://${absolutePath}`;
94392
94602
  const existing = this.openDocuments.get(absolutePath);
94393
94603
  if (!existing) {
@@ -94415,7 +94625,7 @@ class LSPManager2 {
94415
94625
  if (!this.enabled)
94416
94626
  return [];
94417
94627
  if (filePath) {
94418
- const absolutePath = path23.isAbsolute(filePath) ? filePath : path23.resolve(process.cwd(), filePath);
94628
+ const absolutePath = path24.isAbsolute(filePath) ? filePath : path24.resolve(process.cwd(), filePath);
94419
94629
  return this.diagnostics.get(absolutePath) || [];
94420
94630
  }
94421
94631
  const all = [];
@@ -94425,7 +94635,7 @@ class LSPManager2 {
94425
94635
  return all;
94426
94636
  }
94427
94637
  getLanguageId(filePath) {
94428
- const ext3 = path23.extname(filePath).toLowerCase();
94638
+ const ext3 = path24.extname(filePath).toLowerCase();
94429
94639
  const languageMap = {
94430
94640
  ".ts": "typescript",
94431
94641
  ".tsx": "typescriptreact",
@@ -94476,7 +94686,7 @@ __export(exports_auto_update, {
94476
94686
  });
94477
94687
  import { execFile as execFile14 } from "node:child_process";
94478
94688
  import { realpathSync as realpathSync3 } from "node:fs";
94479
- import { readdir as readdir8, rm as rm3 } from "node:fs/promises";
94689
+ import { readdir as readdir9, rm as rm3 } from "node:fs/promises";
94480
94690
  import { join as join37 } from "node:path";
94481
94691
  import { promisify as promisify14 } from "node:util";
94482
94692
  function debugLog4(...args) {
@@ -94644,7 +94854,7 @@ async function getNpmGlobalPath() {
94644
94854
  async function cleanupOrphanedDirs(globalPath) {
94645
94855
  const lettaAiDir = join37(globalPath, "lib/node_modules/@letta-ai");
94646
94856
  try {
94647
- const entries = await readdir8(lettaAiDir);
94857
+ const entries = await readdir9(lettaAiDir);
94648
94858
  for (const entry of entries) {
94649
94859
  if (entry.startsWith(".letta-code-")) {
94650
94860
  const orphanPath = join37(lettaAiDir, entry);
@@ -94895,13 +95105,13 @@ __export(exports_overflow, {
94895
95105
  import { randomUUID as randomUUID10 } from "node:crypto";
94896
95106
  import * as fs15 from "node:fs";
94897
95107
  import * as os5 from "node:os";
94898
- import * as path24 from "node:path";
95108
+ import * as path25 from "node:path";
94899
95109
  function getOverflowDirectory2(workingDirectory) {
94900
95110
  const homeDir = os5.homedir();
94901
- const lettaDir = path24.join(homeDir, ".letta");
94902
- const normalizedPath = path24.normalize(workingDirectory);
95111
+ const lettaDir = path25.join(homeDir, ".letta");
95112
+ const normalizedPath = path25.normalize(workingDirectory);
94903
95113
  const sanitizedPath = normalizedPath.replace(/^[/\\]/, "").replace(/[/\\:]/g, "_").replace(/\s+/g, "_");
94904
- const overflowDir = path24.join(lettaDir, "projects", sanitizedPath, "agent-tools");
95114
+ const overflowDir = path25.join(lettaDir, "projects", sanitizedPath, "agent-tools");
94905
95115
  return overflowDir;
94906
95116
  }
94907
95117
  function ensureOverflowDirectory2(workingDirectory) {
@@ -94915,7 +95125,7 @@ function writeOverflowFile2(content, workingDirectory, toolName) {
94915
95125
  const overflowDir = ensureOverflowDirectory2(workingDirectory);
94916
95126
  const uuid = randomUUID10();
94917
95127
  const filename = toolName ? `${toolName.toLowerCase()}-${uuid}.txt` : `${uuid}.txt`;
94918
- const filePath = path24.join(overflowDir, filename);
95128
+ const filePath = path25.join(overflowDir, filename);
94919
95129
  fs15.writeFileSync(filePath, content, "utf-8");
94920
95130
  return filePath;
94921
95131
  }
@@ -94933,7 +95143,7 @@ function cleanupOldOverflowFiles(workingDirectory, maxAgeMs = 24 * 60 * 60 * 100
94933
95143
  const now = Date.now();
94934
95144
  let deletedCount = 0;
94935
95145
  for (const file of files) {
94936
- const filePath = path24.join(overflowDir, file);
95146
+ const filePath = path25.join(overflowDir, file);
94937
95147
  try {
94938
95148
  const stats = fs15.statSync(filePath);
94939
95149
  if (stats.isDirectory()) {
@@ -94960,7 +95170,7 @@ function getOverflowStats(workingDirectory) {
94960
95170
  const files = fs15.readdirSync(overflowDir);
94961
95171
  let totalSize = 0;
94962
95172
  for (const file of files) {
94963
- const filePath = path24.join(overflowDir, file);
95173
+ const filePath = path25.join(overflowDir, file);
94964
95174
  const stats = fs15.statSync(filePath);
94965
95175
  totalSize += stats.size;
94966
95176
  }
@@ -95438,10 +95648,10 @@ __export(exports_setup, {
95438
95648
  runSetup: () => runSetup
95439
95649
  });
95440
95650
  async function runSetup() {
95441
- return new Promise((resolve27) => {
95651
+ return new Promise((resolve28) => {
95442
95652
  const { waitUntilExit } = render_default(import_react32.default.createElement(SetupUI, {
95443
95653
  onComplete: () => {
95444
- resolve27();
95654
+ resolve28();
95445
95655
  }
95446
95656
  }));
95447
95657
  waitUntilExit().catch((error) => {
@@ -95936,8 +96146,8 @@ __export(exports_github_utils, {
95936
96146
  parseDirNames: () => parseDirNames,
95937
96147
  fetchGitHubContents: () => fetchGitHubContents
95938
96148
  });
95939
- async function fetchGitHubContents(owner, repo, branch, path25) {
95940
- const apiPath = path25 ? `repos/${owner}/${repo}/contents/${path25}?ref=${branch}` : `repos/${owner}/${repo}/contents?ref=${branch}`;
96149
+ async function fetchGitHubContents(owner, repo, branch, path26) {
96150
+ const apiPath = path26 ? `repos/${owner}/${repo}/contents/${path26}?ref=${branch}` : `repos/${owner}/${repo}/contents?ref=${branch}`;
95941
96151
  try {
95942
96152
  const { execSync: execSync2 } = await import("node:child_process");
95943
96153
  const result = execSync2(`gh api ${apiPath}`, {
@@ -95946,7 +96156,7 @@ async function fetchGitHubContents(owner, repo, branch, path25) {
95946
96156
  });
95947
96157
  return JSON.parse(result);
95948
96158
  } catch {}
95949
- const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path25}?ref=${branch}`;
96159
+ const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path26}?ref=${branch}`;
95950
96160
  const response = await fetch(url, {
95951
96161
  headers: {
95952
96162
  Accept: "application/vnd.github.v3+json",
@@ -95954,7 +96164,7 @@ async function fetchGitHubContents(owner, repo, branch, path25) {
95954
96164
  }
95955
96165
  });
95956
96166
  if (!response.ok) {
95957
- throw new Error(`Failed to fetch from ${owner}/${repo}/${branch}/${path25}: ${response.statusText}`);
96167
+ throw new Error(`Failed to fetch from ${owner}/${repo}/${branch}/${path26}: ${response.statusText}`);
95958
96168
  }
95959
96169
  return await response.json();
95960
96170
  }
@@ -95970,11 +96180,11 @@ __export(exports_import, {
95970
96180
  extractSkillsFromAf: () => extractSkillsFromAf
95971
96181
  });
95972
96182
  import { createReadStream } from "node:fs";
95973
- import { chmod, mkdir as mkdir10, readFile as readFile12, writeFile as writeFile11 } from "node:fs/promises";
95974
- import { dirname as dirname15, resolve as resolve27 } from "node:path";
96183
+ import { chmod, mkdir as mkdir10, readFile as readFile13, writeFile as writeFile11 } from "node:fs/promises";
96184
+ import { dirname as dirname15, resolve as resolve28 } from "node:path";
95975
96185
  async function importAgentFromFile(options) {
95976
96186
  const client = await getClient();
95977
- const resolvedPath = resolve27(options.filePath);
96187
+ const resolvedPath = resolve28(options.filePath);
95978
96188
  const file = createReadStream(resolvedPath);
95979
96189
  const importResponse = await client.agents.importFile({
95980
96190
  file,
@@ -96003,13 +96213,13 @@ async function importAgentFromFile(options) {
96003
96213
  }
96004
96214
  async function extractSkillsFromAf(afPath, destDir) {
96005
96215
  const extracted = [];
96006
- const content = await readFile12(afPath, "utf-8");
96216
+ const content = await readFile13(afPath, "utf-8");
96007
96217
  const afData = JSON.parse(content);
96008
96218
  if (!afData.skills || !Array.isArray(afData.skills)) {
96009
96219
  return [];
96010
96220
  }
96011
96221
  for (const skill2 of afData.skills) {
96012
- const skillDir = resolve27(destDir, skill2.name);
96222
+ const skillDir = resolve28(destDir, skill2.name);
96013
96223
  await mkdir10(skillDir, { recursive: true });
96014
96224
  if (skill2.files) {
96015
96225
  await writeSkillFiles(skillDir, skill2.files);
@@ -96029,7 +96239,7 @@ async function writeSkillFiles(skillDir, files) {
96029
96239
  }
96030
96240
  }
96031
96241
  async function writeSkillFile(skillDir, filePath, content) {
96032
- const fullPath = resolve27(skillDir, filePath);
96242
+ const fullPath = resolve28(skillDir, filePath);
96033
96243
  await mkdir10(dirname15(fullPath), { recursive: true });
96034
96244
  await writeFile11(fullPath, content, "utf-8");
96035
96245
  const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
@@ -96048,13 +96258,13 @@ async function fetchSkillFromUrl(skillDir, sourceUrl) {
96048
96258
  const owner = parts[0];
96049
96259
  const repo = parts[1];
96050
96260
  const branch = parts[2];
96051
- const path25 = parts.slice(3).join("/");
96261
+ const path26 = parts.slice(3).join("/");
96052
96262
  const { fetchGitHubContents: fetchGitHubContents2 } = await Promise.resolve().then(() => exports_github_utils);
96053
- const entries = await fetchGitHubContents2(owner, repo, branch, path25);
96263
+ const entries = await fetchGitHubContents2(owner, repo, branch, path26);
96054
96264
  if (!Array.isArray(entries)) {
96055
96265
  throw new Error(`Expected directory at ${sourceUrl}, got file`);
96056
96266
  }
96057
- await downloadGitHubDirectory(entries, skillDir, owner, repo, branch, path25);
96267
+ await downloadGitHubDirectory(entries, skillDir, owner, repo, branch, path26);
96058
96268
  }
96059
96269
  async function downloadGitHubDirectory(entries, destDir, owner, repo, branch, basePath) {
96060
96270
  const { fetchGitHubContents: fetchGitHubContents2 } = await Promise.resolve().then(() => exports_github_utils);
@@ -96361,12 +96571,12 @@ async function prepareHeadlessToolExecutionContext(params) {
96361
96571
  };
96362
96572
  }
96363
96573
  async function flushAndExit(code) {
96364
- const flushWritable = (stream2) => new Promise((resolve28) => {
96574
+ const flushWritable = (stream2) => new Promise((resolve29) => {
96365
96575
  if (stream2.destroyed || stream2.writableEnded) {
96366
- resolve28();
96576
+ resolve29();
96367
96577
  return;
96368
96578
  }
96369
- stream2.write("", () => resolve28());
96579
+ stream2.write("", () => resolve29());
96370
96580
  });
96371
96581
  await Promise.allSettled([
96372
96582
  flushWritable(process.stdout),
@@ -97325,7 +97535,7 @@ ${loadedContents.join(`
97325
97535
  } else {
97326
97536
  console.error(`Conversation is busy, waiting ${Math.round(retryDelayMs / 1000)}s and retrying...`);
97327
97537
  }
97328
- await new Promise((resolve28) => setTimeout(resolve28, retryDelayMs));
97538
+ await new Promise((resolve29) => setTimeout(resolve29, retryDelayMs));
97329
97539
  continue;
97330
97540
  }
97331
97541
  }
@@ -97374,7 +97584,7 @@ ${loadedContents.join(`
97374
97584
  const delaySeconds = Math.round(delayMs / 1000);
97375
97585
  console.error(`Transient API error before streaming (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
97376
97586
  }
97377
- await new Promise((resolve28) => setTimeout(resolve28, delayMs));
97587
+ await new Promise((resolve29) => setTimeout(resolve29, delayMs));
97378
97588
  conversationBusyRetries = 0;
97379
97589
  continue;
97380
97590
  }
@@ -97613,7 +97823,7 @@ ${loadedContents.join(`
97613
97823
  const delaySeconds = Math.round(delayMs / 1000);
97614
97824
  console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
97615
97825
  }
97616
- await new Promise((resolve28) => setTimeout(resolve28, delayMs));
97826
+ await new Promise((resolve29) => setTimeout(resolve29, delayMs));
97617
97827
  refreshCurrentInputOtids();
97618
97828
  continue;
97619
97829
  }
@@ -97703,7 +97913,7 @@ ${loadedContents.join(`
97703
97913
  } else {
97704
97914
  console.error(`Empty LLM response, retrying (attempt ${attempt} of ${EMPTY_RESPONSE_MAX_RETRIES2})...`);
97705
97915
  }
97706
- await new Promise((resolve28) => setTimeout(resolve28, delayMs));
97916
+ await new Promise((resolve29) => setTimeout(resolve29, delayMs));
97707
97917
  refreshCurrentInputOtids();
97708
97918
  continue;
97709
97919
  }
@@ -97731,7 +97941,7 @@ ${loadedContents.join(`
97731
97941
  const delaySeconds = Math.round(delayMs / 1000);
97732
97942
  console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
97733
97943
  }
97734
- await new Promise((resolve28) => setTimeout(resolve28, delayMs));
97944
+ await new Promise((resolve29) => setTimeout(resolve29, delayMs));
97735
97945
  refreshCurrentInputOtids();
97736
97946
  continue;
97737
97947
  }
@@ -97761,7 +97971,7 @@ ${loadedContents.join(`
97761
97971
  const delaySeconds = Math.round(delayMs / 1000);
97762
97972
  console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
97763
97973
  }
97764
- await new Promise((resolve28) => setTimeout(resolve28, delayMs));
97974
+ await new Promise((resolve29) => setTimeout(resolve29, delayMs));
97765
97975
  refreshCurrentInputOtids();
97766
97976
  continue;
97767
97977
  }
@@ -98101,9 +98311,9 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
98101
98311
  const syntheticUserLine = serializeQueuedMessageAsUserLine(queuedMessage);
98102
98312
  maybeNotifyBlocked(syntheticUserLine);
98103
98313
  if (lineResolver) {
98104
- const resolve28 = lineResolver;
98314
+ const resolve29 = lineResolver;
98105
98315
  lineResolver = null;
98106
- resolve28(syntheticUserLine);
98316
+ resolve29(syntheticUserLine);
98107
98317
  return;
98108
98318
  }
98109
98319
  lineQueue.push(syntheticUserLine);
@@ -98111,9 +98321,9 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
98111
98321
  rl.on("line", (line) => {
98112
98322
  maybeNotifyBlocked(line);
98113
98323
  if (lineResolver) {
98114
- const resolve28 = lineResolver;
98324
+ const resolve29 = lineResolver;
98115
98325
  lineResolver = null;
98116
- resolve28(line);
98326
+ resolve29(line);
98117
98327
  } else {
98118
98328
  lineQueue.push(line);
98119
98329
  }
@@ -98122,17 +98332,17 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
98122
98332
  setMessageQueueAdder(null);
98123
98333
  msgQueueRuntime.clear("shutdown");
98124
98334
  if (lineResolver) {
98125
- const resolve28 = lineResolver;
98335
+ const resolve29 = lineResolver;
98126
98336
  lineResolver = null;
98127
- resolve28(null);
98337
+ resolve29(null);
98128
98338
  }
98129
98339
  });
98130
98340
  async function getNextLine() {
98131
98341
  if (lineQueue.length > 0) {
98132
98342
  return lineQueue.shift() ?? null;
98133
98343
  }
98134
- return new Promise((resolve28) => {
98135
- lineResolver = resolve28;
98344
+ return new Promise((resolve29) => {
98345
+ lineResolver = resolve29;
98136
98346
  });
98137
98347
  }
98138
98348
  async function requestPermission(toolCallId, toolName, toolInput) {
@@ -98623,7 +98833,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
98623
98833
  uuid: `retry-bidir-${randomUUID13()}`
98624
98834
  };
98625
98835
  console.log(JSON.stringify(retryMsg));
98626
- await new Promise((resolve28) => setTimeout(resolve28, delayMs));
98836
+ await new Promise((resolve29) => setTimeout(resolve29, delayMs));
98627
98837
  continue;
98628
98838
  }
98629
98839
  throw preStreamError;
@@ -98925,10 +99135,10 @@ async function detectAndEnableKittyProtocol() {
98925
99135
  detectionComplete = true;
98926
99136
  return;
98927
99137
  }
98928
- return new Promise((resolve28) => {
99138
+ return new Promise((resolve29) => {
98929
99139
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
98930
99140
  detectionComplete = true;
98931
- resolve28();
99141
+ resolve29();
98932
99142
  return;
98933
99143
  }
98934
99144
  const originalRawMode = process.stdin.isRaw;
@@ -98961,7 +99171,7 @@ async function detectAndEnableKittyProtocol() {
98961
99171
  console.error("[kitty] protocol query unsupported; enabled anyway (best-effort)");
98962
99172
  }
98963
99173
  detectionComplete = true;
98964
- resolve28();
99174
+ resolve29();
98965
99175
  };
98966
99176
  const handleData = (data) => {
98967
99177
  if (timeoutId === undefined) {
@@ -99174,13 +99384,13 @@ var init_reconcileExistingAgentState = __esm(() => {
99174
99384
  // src/agent/sessionHistory.ts
99175
99385
  import * as fs17 from "node:fs";
99176
99386
  import * as os6 from "node:os";
99177
- import * as path25 from "node:path";
99387
+ import * as path26 from "node:path";
99178
99388
  function getHistoryDir() {
99179
99389
  const homeDir = os6.homedir();
99180
- return path25.join(homeDir, ".letta");
99390
+ return path26.join(homeDir, ".letta");
99181
99391
  }
99182
99392
  function getHistoryFilePath() {
99183
- return path25.join(getHistoryDir(), "sessions.jsonl");
99393
+ return path26.join(getHistoryDir(), "sessions.jsonl");
99184
99394
  }
99185
99395
  function recordSessionEnd(agentId, sessionId, stats, sessionInfo, cost, metadata) {
99186
99396
  const entry = {
@@ -117444,8 +117654,8 @@ function getHeader(command) {
117444
117654
  return `Run memory ${command}?`;
117445
117655
  }
117446
117656
  }
117447
- function displayPath(path26) {
117448
- return path26.replace(/\.md$/, "");
117657
+ function displayPath(path27) {
117658
+ return path27.replace(/\.md$/, "");
117449
117659
  }
117450
117660
  function truncate2(text, max) {
117451
117661
  if (text.length <= max)
@@ -117549,7 +117759,7 @@ var init_InlineMemoryApproval = __esm(async () => {
117549
117759
  const {
117550
117760
  command,
117551
117761
  reason,
117552
- path: path26,
117762
+ path: path27,
117553
117763
  oldPath,
117554
117764
  newPath,
117555
117765
  oldString,
@@ -117596,9 +117806,9 @@ var init_InlineMemoryApproval = __esm(async () => {
117596
117806
  }, undefined, false, undefined, this)
117597
117807
  ]
117598
117808
  }, undefined, true, undefined, this)
117599
- }, undefined, false, undefined, this) : path26 && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text2, {
117809
+ }, undefined, false, undefined, this) : path27 && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text2, {
117600
117810
  bold: true,
117601
- children: displayPath(path26)
117811
+ children: displayPath(path27)
117602
117812
  }, undefined, false, undefined, this),
117603
117813
  command === "str_replace" && oldString != null && newString != null && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
117604
117814
  flexDirection: "column",
@@ -121237,7 +121447,7 @@ var init_pasteRegistry = __esm(() => {
121237
121447
  import { execFileSync as execFileSync3 } from "node:child_process";
121238
121448
  import { existsSync as existsSync34, readFileSync as readFileSync20, statSync as statSync10, unlinkSync as unlinkSync10 } from "node:fs";
121239
121449
  import { tmpdir as tmpdir4 } from "node:os";
121240
- import { basename as basename9, extname as extname8, isAbsolute as isAbsolute19, join as join42, resolve as resolve28 } from "node:path";
121450
+ import { basename as basename9, extname as extname8, isAbsolute as isAbsolute20, join as join42, resolve as resolve29 } from "node:path";
121241
121451
  function countLines2(text) {
121242
121452
  return (text.match(/\r\n|\r|\n/g) || []).length + 1;
121243
121453
  }
@@ -121284,8 +121494,8 @@ function translatePasteForImages(paste) {
121284
121494
  }
121285
121495
  } catch {}
121286
121496
  }
121287
- if (!isAbsolute19(filePath))
121288
- filePath = resolve28(process.cwd(), filePath);
121497
+ if (!isAbsolute20(filePath))
121498
+ filePath = resolve29(process.cwd(), filePath);
121289
121499
  const ext3 = extname8(filePath || "").toLowerCase();
121290
121500
  if (IMAGE_EXTS.has(ext3) && existsSync34(filePath) && statSync10(filePath).isFile()) {
121291
121501
  const buf = readFileSync20(filePath);
@@ -122220,14 +122430,14 @@ function installKeybindingForCurrentTerminal() {
122220
122430
  error: "Not running in a VS Code-like terminal"
122221
122431
  };
122222
122432
  }
122223
- const path26 = getKeybindingsPath(terminal);
122224
- if (!path26) {
122433
+ const path27 = getKeybindingsPath(terminal);
122434
+ if (!path27) {
122225
122435
  return {
122226
122436
  success: false,
122227
122437
  error: `Could not determine keybindings.json path for ${terminal}`
122228
122438
  };
122229
122439
  }
122230
- return installKeybinding(path26);
122440
+ return installKeybinding(path27);
122231
122441
  }
122232
122442
  function removeKeybindingForCurrentTerminal() {
122233
122443
  const terminal = detectTerminalType();
@@ -122237,14 +122447,14 @@ function removeKeybindingForCurrentTerminal() {
122237
122447
  error: "Not running in a VS Code-like terminal"
122238
122448
  };
122239
122449
  }
122240
- const path26 = getKeybindingsPath(terminal);
122241
- if (!path26) {
122450
+ const path27 = getKeybindingsPath(terminal);
122451
+ if (!path27) {
122242
122452
  return {
122243
122453
  success: false,
122244
122454
  error: `Could not determine keybindings.json path for ${terminal}`
122245
122455
  };
122246
122456
  }
122247
- return removeKeybinding(path26);
122457
+ return removeKeybinding(path27);
122248
122458
  }
122249
122459
  function isWezTerm() {
122250
122460
  return process.env.TERM_PROGRAM === "WezTerm";
@@ -122900,7 +123110,7 @@ __export(exports_custom, {
122900
123110
  COMMANDS_DIR: () => COMMANDS_DIR
122901
123111
  });
122902
123112
  import { existsSync as existsSync36 } from "node:fs";
122903
- import { readdir as readdir9, readFile as readFile13 } from "node:fs/promises";
123113
+ import { readdir as readdir10, readFile as readFile14 } from "node:fs/promises";
122904
123114
  import { basename as basename10, dirname as dirname17, join as join44 } from "node:path";
122905
123115
  async function getCustomCommands() {
122906
123116
  if (cachedCommands !== null) {
@@ -122942,7 +123152,7 @@ async function discoverFromDirectory(dirPath, source2) {
122942
123152
  }
122943
123153
  async function findCommandFiles(currentPath, rootPath, commands2, source2) {
122944
123154
  try {
122945
- const entries = await readdir9(currentPath, { withFileTypes: true });
123155
+ const entries = await readdir10(currentPath, { withFileTypes: true });
122946
123156
  for (const entry of entries) {
122947
123157
  const fullPath = join44(currentPath, entry.name);
122948
123158
  if (entry.isDirectory()) {
@@ -122959,7 +123169,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source2) {
122959
123169
  } catch (_error) {}
122960
123170
  }
122961
123171
  async function parseCommandFile(filePath, rootPath, source2) {
122962
- const content = await readFile13(filePath, "utf-8");
123172
+ const content = await readFile14(filePath, "utf-8");
122963
123173
  const { frontmatter, body } = parseFrontmatter(content);
122964
123174
  const id = basename10(filePath, ".md");
122965
123175
  const relativePath = dirname17(filePath).slice(rootPath.length);
@@ -123311,11 +123521,11 @@ var init_HelpDialog = __esm(async () => {
123311
123521
 
123312
123522
  // src/hooks/writer.ts
123313
123523
  import { homedir as homedir34 } from "node:os";
123314
- import { resolve as resolve29 } from "node:path";
123524
+ import { resolve as resolve30 } from "node:path";
123315
123525
  function isProjectSettingsPathCollidingWithGlobal2(workingDirectory) {
123316
123526
  const home = process.env.HOME || homedir34();
123317
- const globalSettingsPath = resolve29(home, ".letta", "settings.json");
123318
- const projectSettingsPath = resolve29(workingDirectory, ".letta", "settings.json");
123527
+ const globalSettingsPath = resolve30(home, ".letta", "settings.json");
123528
+ const projectSettingsPath = resolve30(workingDirectory, ".letta", "settings.json");
123319
123529
  return globalSettingsPath === projectSettingsPath;
123320
123530
  }
123321
123531
  function loadHooksFromLocation(location, workingDirectory = process.cwd()) {
@@ -125953,7 +126163,7 @@ var init_AgentInfoBar = __esm(async () => {
125953
126163
 
125954
126164
  // src/cli/helpers/fileSearch.ts
125955
126165
  import { readdirSync as readdirSync12, statSync as statSync11 } from "node:fs";
125956
- import { join as join45, relative as relative16, resolve as resolve30 } from "node:path";
126166
+ import { join as join45, relative as relative16, resolve as resolve31 } from "node:path";
125957
126167
  function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [], depth = 0, maxDepth = 10, lowerPattern = pattern.toLowerCase()) {
125958
126168
  if (results.length >= maxResults || depth >= maxDepth) {
125959
126169
  return results;
@@ -125996,7 +126206,7 @@ async function searchFiles(query, deep = false) {
125996
126206
  const dirPart = query.slice(0, lastSlashIndex);
125997
126207
  const pattern = query.slice(lastSlashIndex + 1);
125998
126208
  try {
125999
- const resolvedDir = resolve30(getIndexRoot(), dirPart);
126209
+ const resolvedDir = resolve31(getIndexRoot(), dirPart);
126000
126210
  try {
126001
126211
  statSync11(resolvedDir);
126002
126212
  searchDir = resolvedDir;
@@ -128321,9 +128531,9 @@ function buildInstallPrBody(workflowPath) {
128321
128531
  ].join(`
128322
128532
  `);
128323
128533
  }
128324
- function checkRemoteFileExists(repo, path26) {
128534
+ function checkRemoteFileExists(repo, path27) {
128325
128535
  try {
128326
- runCommand("gh", ["api", `repos/${repo}/contents/${path26}`]);
128536
+ runCommand("gh", ["api", `repos/${repo}/contents/${path27}`]);
128327
128537
  return true;
128328
128538
  } catch {
128329
128539
  return false;
@@ -135684,7 +135894,7 @@ var init_PersonalitySelector = __esm(async () => {
135684
135894
  });
135685
135895
 
135686
135896
  // src/utils/aws-credentials.ts
135687
- import { readFile as readFile14 } from "node:fs/promises";
135897
+ import { readFile as readFile15 } from "node:fs/promises";
135688
135898
  import { homedir as homedir36 } from "node:os";
135689
135899
  import { join as join48 } from "node:path";
135690
135900
  async function parseAwsCredentials() {
@@ -135692,11 +135902,11 @@ async function parseAwsCredentials() {
135692
135902
  const configPath = join48(homedir36(), ".aws", "config");
135693
135903
  const profiles = new Map;
135694
135904
  try {
135695
- const content = await readFile14(credentialsPath, "utf-8");
135905
+ const content = await readFile15(credentialsPath, "utf-8");
135696
135906
  parseIniFile(content, profiles, false);
135697
135907
  } catch {}
135698
135908
  try {
135699
- const content = await readFile14(configPath, "utf-8");
135909
+ const content = await readFile15(configPath, "utf-8");
135700
135910
  parseIniFile(content, profiles, true);
135701
135911
  } catch {}
135702
135912
  return Array.from(profiles.values());
@@ -138303,8 +138513,8 @@ function MemoryDiffRenderer({
138303
138513
  }, undefined, false, undefined, this);
138304
138514
  }
138305
138515
  const command = args.command;
138306
- const path26 = args.path || args.old_path || "unknown";
138307
- const blockName = path26.split("/").pop() || path26;
138516
+ const path27 = args.path || args.old_path || "unknown";
138517
+ const blockName = path27.split("/").pop() || path27;
138308
138518
  switch (command) {
138309
138519
  case "str_replace": {
138310
138520
  const oldStr = args.old_string || args.old_str || "";
@@ -141176,7 +141386,7 @@ async function executeStatusLineCommand(command, payload, options) {
141176
141386
  };
141177
141387
  }
141178
141388
  function runWithLauncher(launcher, inputJson, timeout, signal, workingDirectory, startTime) {
141179
- return new Promise((resolve31, reject) => {
141389
+ return new Promise((resolve32, reject) => {
141180
141390
  const [executable, ...args] = launcher;
141181
141391
  if (!executable) {
141182
141392
  reject(new Error("Empty launcher"));
@@ -141189,7 +141399,7 @@ function runWithLauncher(launcher, inputJson, timeout, signal, workingDirectory,
141189
141399
  const safeResolve = (result) => {
141190
141400
  if (!resolved) {
141191
141401
  resolved = true;
141192
- resolve31(result);
141402
+ resolve32(result);
141193
141403
  }
141194
141404
  };
141195
141405
  let child;
@@ -142361,28 +142571,28 @@ var exports_export = {};
142361
142571
  __export(exports_export, {
142362
142572
  packageSkills: () => packageSkills
142363
142573
  });
142364
- import { readdir as readdir10, readFile as readFile15 } from "node:fs/promises";
142365
- import { relative as relative17, resolve as resolve31 } from "node:path";
142574
+ import { readdir as readdir11, readFile as readFile16 } from "node:fs/promises";
142575
+ import { relative as relative17, resolve as resolve32 } from "node:path";
142366
142576
  async function packageSkills(agentId, skillsDir) {
142367
142577
  const skills = [];
142368
142578
  const skillNames = new Set;
142369
142579
  const dirsToCheck = skillsDir ? [skillsDir] : [
142370
142580
  agentId && getAgentSkillsDir(agentId),
142371
- resolve31(process.cwd(), ".skills"),
142372
- resolve31(process.env.HOME || "~", ".letta", "skills")
142581
+ resolve32(process.cwd(), ".skills"),
142582
+ resolve32(process.env.HOME || "~", ".letta", "skills")
142373
142583
  ].filter((dir) => Boolean(dir));
142374
142584
  for (const baseDir of dirsToCheck) {
142375
142585
  try {
142376
- const entries = await readdir10(baseDir, { withFileTypes: true });
142586
+ const entries = await readdir11(baseDir, { withFileTypes: true });
142377
142587
  for (const entry of entries) {
142378
142588
  if (!entry.isDirectory())
142379
142589
  continue;
142380
142590
  if (skillNames.has(entry.name))
142381
142591
  continue;
142382
- const skillDir = resolve31(baseDir, entry.name);
142383
- const skillMdPath = resolve31(skillDir, "SKILL.md");
142592
+ const skillDir = resolve32(baseDir, entry.name);
142593
+ const skillMdPath = resolve32(skillDir, "SKILL.md");
142384
142594
  try {
142385
- await readFile15(skillMdPath, "utf-8");
142595
+ await readFile16(skillMdPath, "utf-8");
142386
142596
  } catch {
142387
142597
  console.warn(`Skipping invalid skill ${entry.name}: missing SKILL.md`);
142388
142598
  continue;
@@ -142408,13 +142618,13 @@ async function packageSkills(agentId, skillsDir) {
142408
142618
  async function readSkillFiles(skillDir) {
142409
142619
  const files = {};
142410
142620
  async function walk(dir) {
142411
- const entries = await readdir10(dir, { withFileTypes: true });
142621
+ const entries = await readdir11(dir, { withFileTypes: true });
142412
142622
  for (const entry of entries) {
142413
- const fullPath = resolve31(dir, entry.name);
142623
+ const fullPath = resolve32(dir, entry.name);
142414
142624
  if (entry.isDirectory()) {
142415
142625
  await walk(fullPath);
142416
142626
  } else {
142417
- const content = await readFile15(fullPath, "utf-8");
142627
+ const content = await readFile16(fullPath, "utf-8");
142418
142628
  const relativePath = relative17(skillDir, fullPath).replace(/\\/g, "/");
142419
142629
  files[relativePath] = content;
142420
142630
  }
@@ -142434,8 +142644,8 @@ async function findSkillSourceUrl(skillName) {
142434
142644
  }
142435
142645
  return null;
142436
142646
  }
142437
- async function fetchGitHubDirs(path26) {
142438
- const [owner, repo, branch, ...pathParts] = path26.split("/");
142647
+ async function fetchGitHubDirs(path27) {
142648
+ const [owner, repo, branch, ...pathParts] = path27.split("/");
142439
142649
  if (!owner || !repo || !branch)
142440
142650
  return new Set;
142441
142651
  try {
@@ -144592,12 +144802,12 @@ Memory may be stale. Try running: git -C ~/.letta/agents/${agentId}/memory pull`
144592
144802
  let watcher = null;
144593
144803
  (async () => {
144594
144804
  try {
144595
- const { watch } = await import("node:fs");
144805
+ const { watch: watch2 } = await import("node:fs");
144596
144806
  const { existsSync: existsSync43 } = await import("node:fs");
144597
144807
  const memRoot = getMemoryFilesystemRoot(agentId);
144598
144808
  if (!existsSync43(memRoot))
144599
144809
  return;
144600
- watcher = watch(memRoot, { recursive: true }, () => {});
144810
+ watcher = watch2(memRoot, { recursive: true }, () => {});
144601
144811
  memfsWatcherRef.current = watcher;
144602
144812
  debugLog("memfs", `Watching memory directory: ${memRoot}`);
144603
144813
  watcher.on("error", (err) => {
@@ -144924,7 +145134,7 @@ ${newState.originalPrompt}`,
144924
145134
  cancelled = true;
144925
145135
  break;
144926
145136
  }
144927
- await new Promise((resolve32) => setTimeout(resolve32, 100));
145137
+ await new Promise((resolve33) => setTimeout(resolve33, 100));
144928
145138
  }
144929
145139
  buffersRef.current.byId.delete(statusId);
144930
145140
  buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
@@ -144988,7 +145198,7 @@ ${newState.originalPrompt}`,
144988
145198
  cancelled = true;
144989
145199
  break;
144990
145200
  }
144991
- await new Promise((resolve32) => setTimeout(resolve32, 100));
145201
+ await new Promise((resolve33) => setTimeout(resolve33, 100));
144992
145202
  }
144993
145203
  if (retryStatusId) {
144994
145204
  buffersRef.current.byId.delete(retryStatusId);
@@ -145746,7 +145956,7 @@ ${feedback}
145746
145956
  });
145747
145957
  buffersRef.current.order.push(statusId);
145748
145958
  refreshDerived();
145749
- await new Promise((resolve32) => setTimeout(resolve32, delayMs));
145959
+ await new Promise((resolve33) => setTimeout(resolve33, delayMs));
145750
145960
  buffersRef.current.byId.delete(statusId);
145751
145961
  buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
145752
145962
  refreshDerived();
@@ -145806,7 +146016,7 @@ ${feedback}
145806
146016
  cancelled = true;
145807
146017
  break;
145808
146018
  }
145809
- await new Promise((resolve32) => setTimeout(resolve32, 100));
146019
+ await new Promise((resolve33) => setTimeout(resolve33, 100));
145810
146020
  }
145811
146021
  if (retryStatusId) {
145812
146022
  buffersRef.current.byId.delete(retryStatusId);
@@ -152514,14 +152724,14 @@ function installKeybindingForCurrentTerminal2() {
152514
152724
  error: "Not running in a VS Code-like terminal"
152515
152725
  };
152516
152726
  }
152517
- const path26 = getKeybindingsPath2(terminal);
152518
- if (!path26) {
152727
+ const path27 = getKeybindingsPath2(terminal);
152728
+ if (!path27) {
152519
152729
  return {
152520
152730
  success: false,
152521
152731
  error: `Could not determine keybindings.json path for ${terminal}`
152522
152732
  };
152523
152733
  }
152524
- return installKeybinding2(path26);
152734
+ return installKeybinding2(path27);
152525
152735
  }
152526
152736
  function removeKeybindingForCurrentTerminal2() {
152527
152737
  const terminal = detectTerminalType2();
@@ -152531,14 +152741,14 @@ function removeKeybindingForCurrentTerminal2() {
152531
152741
  error: "Not running in a VS Code-like terminal"
152532
152742
  };
152533
152743
  }
152534
- const path26 = getKeybindingsPath2(terminal);
152535
- if (!path26) {
152744
+ const path27 = getKeybindingsPath2(terminal);
152745
+ if (!path27) {
152536
152746
  return {
152537
152747
  success: false,
152538
152748
  error: `Could not determine keybindings.json path for ${terminal}`
152539
152749
  };
152540
152750
  }
152541
- return removeKeybinding2(path26);
152751
+ return removeKeybinding2(path27);
152542
152752
  }
152543
152753
  function isWezTerm2() {
152544
152754
  return process.env.TERM_PROGRAM === "WezTerm";
@@ -153174,11 +153384,11 @@ __export(exports_import2, {
153174
153384
  extractSkillsFromAf: () => extractSkillsFromAf2
153175
153385
  });
153176
153386
  import { createReadStream as createReadStream2 } from "node:fs";
153177
- import { chmod as chmod2, mkdir as mkdir11, readFile as readFile16, writeFile as writeFile12 } from "node:fs/promises";
153178
- import { dirname as dirname20, resolve as resolve32 } from "node:path";
153387
+ import { chmod as chmod2, mkdir as mkdir11, readFile as readFile17, writeFile as writeFile12 } from "node:fs/promises";
153388
+ import { dirname as dirname20, resolve as resolve33 } from "node:path";
153179
153389
  async function importAgentFromFile2(options) {
153180
153390
  const client = await getClient();
153181
- const resolvedPath = resolve32(options.filePath);
153391
+ const resolvedPath = resolve33(options.filePath);
153182
153392
  const file = createReadStream2(resolvedPath);
153183
153393
  const importResponse = await client.agents.importFile({
153184
153394
  file,
@@ -153207,13 +153417,13 @@ async function importAgentFromFile2(options) {
153207
153417
  }
153208
153418
  async function extractSkillsFromAf2(afPath, destDir) {
153209
153419
  const extracted = [];
153210
- const content = await readFile16(afPath, "utf-8");
153420
+ const content = await readFile17(afPath, "utf-8");
153211
153421
  const afData = JSON.parse(content);
153212
153422
  if (!afData.skills || !Array.isArray(afData.skills)) {
153213
153423
  return [];
153214
153424
  }
153215
153425
  for (const skill2 of afData.skills) {
153216
- const skillDir = resolve32(destDir, skill2.name);
153426
+ const skillDir = resolve33(destDir, skill2.name);
153217
153427
  await mkdir11(skillDir, { recursive: true });
153218
153428
  if (skill2.files) {
153219
153429
  await writeSkillFiles2(skillDir, skill2.files);
@@ -153233,7 +153443,7 @@ async function writeSkillFiles2(skillDir, files) {
153233
153443
  }
153234
153444
  }
153235
153445
  async function writeSkillFile2(skillDir, filePath, content) {
153236
- const fullPath = resolve32(skillDir, filePath);
153446
+ const fullPath = resolve33(skillDir, filePath);
153237
153447
  await mkdir11(dirname20(fullPath), { recursive: true });
153238
153448
  await writeFile12(fullPath, content, "utf-8");
153239
153449
  const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
@@ -153252,13 +153462,13 @@ async function fetchSkillFromUrl2(skillDir, sourceUrl) {
153252
153462
  const owner = parts[0];
153253
153463
  const repo = parts[1];
153254
153464
  const branch = parts[2];
153255
- const path26 = parts.slice(3).join("/");
153465
+ const path27 = parts.slice(3).join("/");
153256
153466
  const { fetchGitHubContents: fetchGitHubContents2 } = await Promise.resolve().then(() => exports_github_utils);
153257
- const entries = await fetchGitHubContents2(owner, repo, branch, path26);
153467
+ const entries = await fetchGitHubContents2(owner, repo, branch, path27);
153258
153468
  if (!Array.isArray(entries)) {
153259
153469
  throw new Error(`Expected directory at ${sourceUrl}, got file`);
153260
153470
  }
153261
- await downloadGitHubDirectory2(entries, skillDir, owner, repo, branch, path26);
153471
+ await downloadGitHubDirectory2(entries, skillDir, owner, repo, branch, path27);
153262
153472
  }
153263
153473
  async function downloadGitHubDirectory2(entries, destDir, owner, repo, branch, basePath) {
153264
153474
  const { fetchGitHubContents: fetchGitHubContents2 } = await Promise.resolve().then(() => exports_github_utils);
@@ -158271,23 +158481,21 @@ async function runListenSubcommand(argv) {
158271
158481
  process.exit(code);
158272
158482
  };
158273
158483
  await settingsManager.loadLocalProjectSettings();
158274
- if (values.channels) {
158275
- const channelNames = values.channels.split(",").map((s) => s.trim()).filter(Boolean);
158276
- if (channelNames.length > 0) {
158277
- if (values["install-channel-runtimes"]) {
158278
- const { ensureChannelRuntimeInstalled: ensureChannelRuntimeInstalled2 } = await Promise.resolve().then(() => (init_runtimeDeps(), exports_runtimeDeps));
158279
- const { isSupportedChannelId: isSupportedChannelId2 } = await Promise.resolve().then(() => (init_pluginRegistry(), exports_pluginRegistry));
158280
- for (const channelName of channelNames) {
158281
- if (!isSupportedChannelId2(channelName)) {
158282
- console.error(`Unknown channel "${channelName}" passed to --channels.`);
158283
- return 1;
158284
- }
158285
- await ensureChannelRuntimeInstalled2(channelName);
158484
+ const channelNames = values.channels ? values.channels.split(",").map((s) => s.trim()).filter(Boolean) : process.env.LETTA_RESTORE_ENABLED_CHANNELS === "1" ? (await Promise.resolve().then(() => (init_service(), exports_service))).listEnabledChannelIds() : [];
158485
+ if (channelNames.length > 0) {
158486
+ if (values.channels && values["install-channel-runtimes"]) {
158487
+ const { ensureChannelRuntimeInstalled: ensureChannelRuntimeInstalled2 } = await Promise.resolve().then(() => (init_runtimeDeps(), exports_runtimeDeps));
158488
+ const { isSupportedChannelId: isSupportedChannelId2 } = await Promise.resolve().then(() => (init_pluginRegistry(), exports_pluginRegistry));
158489
+ for (const channelName of channelNames) {
158490
+ if (!isSupportedChannelId2(channelName)) {
158491
+ console.error(`Unknown channel "${channelName}" passed to --channels.`);
158492
+ return 1;
158286
158493
  }
158494
+ await ensureChannelRuntimeInstalled2(channelName);
158287
158495
  }
158288
- const { initializeChannels: initializeChannels2 } = await Promise.resolve().then(() => (init_registry(), exports_registry));
158289
- await initializeChannels2(channelNames);
158290
158496
  }
158497
+ const { initializeChannels: initializeChannels2 } = await Promise.resolve().then(() => (init_registry(), exports_registry));
158498
+ await initializeChannels2(channelNames);
158291
158499
  }
158292
158500
  let connectionName;
158293
158501
  if (values["env-name"]) {
@@ -158301,11 +158509,11 @@ async function runListenSubcommand(argv) {
158301
158509
  connectionName = hostname3();
158302
158510
  settingsManager.setListenerEnvName(connectionName);
158303
158511
  } else {
158304
- connectionName = await new Promise((resolve24) => {
158512
+ connectionName = await new Promise((resolve25) => {
158305
158513
  const { unmount } = render_default(/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(PromptEnvName, {
158306
158514
  onSubmit: (name) => {
158307
158515
  unmount();
158308
- resolve24(name);
158516
+ resolve25(name);
158309
158517
  }
158310
158518
  }, undefined, false, undefined, this));
158311
158519
  });
@@ -158508,7 +158716,7 @@ async function runListenSubcommand(argv) {
158508
158716
  // src/cli/subcommands/memfs.ts
158509
158717
  init_memoryGit();
158510
158718
  import { cpSync, existsSync as existsSync26, mkdirSync as mkdirSync19, rmSync as rmSync3, statSync as statSync8 } from "node:fs";
158511
- import { readdir as readdir6 } from "node:fs/promises";
158719
+ import { readdir as readdir7 } from "node:fs/promises";
158512
158720
  import { homedir as homedir24 } from "node:os";
158513
158721
  import { join as join31 } from "node:path";
158514
158722
  import { parseArgs as parseArgs8 } from "node:util";
@@ -158575,22 +158783,22 @@ async function listBackups(agentId) {
158575
158783
  if (!existsSync26(agentRoot)) {
158576
158784
  return [];
158577
158785
  }
158578
- const entries = await readdir6(agentRoot, { withFileTypes: true });
158786
+ const entries = await readdir7(agentRoot, { withFileTypes: true });
158579
158787
  const backups = [];
158580
158788
  for (const entry of entries) {
158581
158789
  if (!entry.isDirectory())
158582
158790
  continue;
158583
158791
  if (!entry.name.startsWith("memory-backup-"))
158584
158792
  continue;
158585
- const path23 = join31(agentRoot, entry.name);
158793
+ const path24 = join31(agentRoot, entry.name);
158586
158794
  let createdAt = null;
158587
158795
  try {
158588
- const stat6 = statSync8(path23);
158589
- createdAt = stat6.mtime.toISOString();
158796
+ const stat7 = statSync8(path24);
158797
+ createdAt = stat7.mtime.toISOString();
158590
158798
  } catch {
158591
158799
  createdAt = null;
158592
158800
  }
158593
- backups.push({ name: entry.name, path: path23, createdAt });
158801
+ backups.push({ name: entry.name, path: path24, createdAt });
158594
158802
  }
158595
158803
  backups.sort((a, b) => a.name.localeCompare(b.name));
158596
158804
  return backups;
@@ -158694,8 +158902,8 @@ async function runMemfsSubcommand(argv) {
158694
158902
  console.error(`Backup not found: ${backupPath}`);
158695
158903
  return 1;
158696
158904
  }
158697
- const stat6 = statSync8(backupPath);
158698
- if (!stat6.isDirectory()) {
158905
+ const stat7 = statSync8(backupPath);
158906
+ if (!stat7.isDirectory()) {
158699
158907
  console.error(`Backup path is not a directory: ${backupPath}`);
158700
158908
  return 1;
158701
158909
  }
@@ -158717,9 +158925,9 @@ async function runMemfsSubcommand(argv) {
158717
158925
  return 1;
158718
158926
  }
158719
158927
  if (existsSync26(out)) {
158720
- const stat6 = statSync8(out);
158721
- if (stat6.isDirectory()) {
158722
- const contents = await readdir6(out);
158928
+ const stat7 = statSync8(out);
158929
+ if (stat7.isDirectory()) {
158930
+ const contents = await readdir7(out);
158723
158931
  if (contents.length > 0) {
158724
158932
  console.error(`Export directory not empty: ${out}`);
158725
158933
  return 1;
@@ -158748,7 +158956,7 @@ async function runMemfsSubcommand(argv) {
158748
158956
  init_client2();
158749
158957
  init_settings_manager();
158750
158958
  import { writeFile as writeFile9 } from "node:fs/promises";
158751
- import { resolve as resolve24 } from "node:path";
158959
+ import { resolve as resolve25 } from "node:path";
158752
158960
  import { parseArgs as parseArgs9 } from "node:util";
158753
158961
  function printUsage6() {
158754
158962
  console.log(`
@@ -159053,7 +159261,7 @@ async function runMessagesSubcommand(argv) {
159053
159261
 
159054
159262
  `).trim();
159055
159263
  if (outputPathRaw && typeof outputPathRaw === "string") {
159056
- const outputPath = resolve24(process.cwd(), outputPathRaw);
159264
+ const outputPath = resolve25(process.cwd(), outputPathRaw);
159057
159265
  await writeFile9(outputPath, `${transcript}
159058
159266
  `, "utf-8");
159059
159267
  console.log(JSON.stringify({
@@ -159115,13 +159323,13 @@ init_memoryScope();
159115
159323
  init_readOnlyShell();
159116
159324
  init_shell_command_normalization();
159117
159325
  import { homedir as homedir25 } from "node:os";
159118
- import { isAbsolute as isAbsolute17, join as join32, relative as relative13 } from "node:path";
159326
+ import { isAbsolute as isAbsolute18, join as join32, relative as relative13 } from "node:path";
159119
159327
  var MODE_KEY2 = Symbol.for("@letta/permissionMode");
159120
159328
  var PLAN_FILE_KEY2 = Symbol.for("@letta/planFilePath");
159121
159329
  var MODE_BEFORE_PLAN_KEY2 = Symbol.for("@letta/permissionModeBeforePlan");
159122
159330
  function everyResolvedTargetIsWithinRoots2(candidatePaths, roots, workingDirectory) {
159123
- return candidatePaths.length > 0 && candidatePaths.every((path23) => {
159124
- const resolvedPath = resolveScopedTargetPath(path23, workingDirectory);
159331
+ return candidatePaths.length > 0 && candidatePaths.every((path24) => {
159332
+ const resolvedPath = resolveScopedTargetPath(path24, workingDirectory);
159125
159333
  return resolvedPath ? isPathWithinRoots(resolvedPath, roots) : false;
159126
159334
  });
159127
159335
  }
@@ -159155,11 +159363,11 @@ function setGlobalModeBeforePlan2(value) {
159155
159363
  function resolvePlanTargetPath2(targetPath, workingDirectory) {
159156
159364
  return resolveScopedTargetPath(targetPath, workingDirectory);
159157
159365
  }
159158
- function isPathInPlansDir2(path23, plansDir) {
159159
- if (!path23.endsWith(".md"))
159366
+ function isPathInPlansDir2(path24, plansDir) {
159367
+ if (!path24.endsWith(".md"))
159160
159368
  return false;
159161
- const rel = relative13(plansDir, path23);
159162
- return rel !== "" && !rel.startsWith("..") && !isAbsolute17(rel);
159369
+ const rel = relative13(plansDir, path24);
159370
+ return rel !== "" && !rel.startsWith("..") && !isAbsolute18(rel);
159163
159371
  }
159164
159372
  function extractApplyPatchPaths2(input) {
159165
159373
  const paths = [];
@@ -159260,8 +159468,8 @@ class PermissionModeManager2 {
159260
159468
  getMode() {
159261
159469
  return this.currentMode;
159262
159470
  }
159263
- setPlanFilePath(path23) {
159264
- setGlobalPlanFilePath2(path23);
159471
+ setPlanFilePath(path24) {
159472
+ setGlobalPlanFilePath2(path24);
159265
159473
  }
159266
159474
  getPlanFilePath() {
159267
159475
  return getGlobalPlanFilePath2();
@@ -159356,8 +159564,8 @@ class PermissionModeManager2 {
159356
159564
  } else if (typeof targetPath === "string") {
159357
159565
  candidatePaths = [targetPath];
159358
159566
  }
159359
- if (candidatePaths.length > 0 && candidatePaths.every((path23) => {
159360
- const resolvedPath = resolvePlanTargetPath2(path23, workingDirectory);
159567
+ if (candidatePaths.length > 0 && candidatePaths.every((path24) => {
159568
+ const resolvedPath = resolvePlanTargetPath2(path24, workingDirectory);
159361
159569
  return resolvedPath ? isPathInPlansDir2(resolvedPath, plansDir) : false;
159362
159570
  })) {
159363
159571
  return "allow";
@@ -159516,7 +159724,7 @@ init_fs();
159516
159724
  init_secrets();
159517
159725
  import { randomUUID as randomUUID9 } from "node:crypto";
159518
159726
  import { homedir as homedir26 } from "node:os";
159519
- import { join as join33, resolve as resolve25 } from "node:path";
159727
+ import { join as join33, resolve as resolve26 } from "node:path";
159520
159728
  var DEFAULT_SETTINGS3 = {
159521
159729
  lastAgent: null,
159522
159730
  tokenStreaming: false,
@@ -159970,7 +160178,7 @@ class SettingsManager2 {
159970
160178
  return join33(workingDirectory, ".letta", "settings.json");
159971
160179
  }
159972
160180
  isProjectSettingsPathCollidingWithGlobal(workingDirectory) {
159973
- return resolve25(this.getProjectSettingsPath(workingDirectory)) === resolve25(this.getSettingsPath());
160181
+ return resolve26(this.getProjectSettingsPath(workingDirectory)) === resolve26(this.getSettingsPath());
159974
160182
  }
159975
160183
  getLocalProjectSettingsPath(workingDirectory) {
159976
160184
  return join33(workingDirectory, ".letta", "settings.local.json");
@@ -160915,6 +161123,7 @@ var STREAMING_SHELL_TOOLS2 = new Set([
160915
161123
  "run_shell_command",
160916
161124
  "RunShellCommand"
160917
161125
  ]);
161126
+ var FILE_MUTATING_TOOLS2 = new Set(["Edit", "Write", "MultiEdit", "replace"]);
160918
161127
  var ANTHROPIC_DEFAULT_TOOLS2 = [
160919
161128
  "AskUserQuestion",
160920
161129
  "Bash",
@@ -160985,8 +161194,8 @@ function acquireSwitchLock2() {
160985
161194
  const lock = getSwitchLock2();
160986
161195
  lock.refCount++;
160987
161196
  if (lock.refCount === 1) {
160988
- lock.promise = new Promise((resolve26) => {
160989
- lock.resolve = resolve26;
161197
+ lock.promise = new Promise((resolve27) => {
161198
+ lock.resolve = resolve27;
160990
161199
  });
160991
161200
  }
160992
161201
  }
@@ -161475,7 +161684,7 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
161475
161684
  printHelp();
161476
161685
  const helpDelayMs = Number.parseInt(process.env.LETTA_TEST_HELP_EXIT_DELAY_MS ?? "", 10);
161477
161686
  if (Number.isFinite(helpDelayMs) && helpDelayMs > 0) {
161478
- await new Promise((resolve33) => setTimeout(resolve33, helpDelayMs));
161687
+ await new Promise((resolve34) => setTimeout(resolve34, helpDelayMs));
161479
161688
  }
161480
161689
  process.exit(0);
161481
161690
  }
@@ -161697,9 +161906,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
161697
161906
  process.exit(1);
161698
161907
  }
161699
161908
  } else {
161700
- const { resolve: resolve33 } = await import("path");
161909
+ const { resolve: resolve34 } = await import("path");
161701
161910
  const { existsSync: existsSync45 } = await import("fs");
161702
- const resolvedPath = resolve33(fromAfFile);
161911
+ const resolvedPath = resolve34(fromAfFile);
161703
161912
  if (!existsSync45(resolvedPath)) {
161704
161913
  console.error(`Error: AgentFile not found: ${resolvedPath}`);
161705
161914
  process.exit(1);
@@ -162579,4 +162788,4 @@ Error during initialization: ${message}`);
162579
162788
  }
162580
162789
  main();
162581
162790
 
162582
- //# debugId=F6C28381AA0FA8FC64756E2164756E21
162791
+ //# debugId=6821E41BE6A3D26164756E2164756E21