@letta-ai/letta-code 0.26.4 → 0.26.5

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.
package/letta.js CHANGED
@@ -4997,7 +4997,7 @@ var package_default;
4997
4997
  var init_package = __esm(() => {
4998
4998
  package_default = {
4999
4999
  name: "@letta-ai/letta-code",
5000
- version: "0.26.4",
5000
+ version: "0.26.5",
5001
5001
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5002
5002
  type: "module",
5003
5003
  packageManager: "bun@1.3.0",
@@ -139855,6 +139855,15 @@ function unregisterPiProvidersForOwner(ownerId) {
139855
139855
  if (changed)
139856
139856
  notifyRegistryListeners();
139857
139857
  }
139858
+ function clearRegisteredPiProviders() {
139859
+ if (registeredProviders.size === 0)
139860
+ return;
139861
+ for (const providerName of registeredProviders.keys()) {
139862
+ unregisterPiOAuthProvider(providerName);
139863
+ }
139864
+ registeredProviders.clear();
139865
+ notifyRegistryListeners();
139866
+ }
139858
139867
  function getRegisteredPiProvider(providerName) {
139859
139868
  const provider = registeredProviders.get(providerName);
139860
139869
  if (!provider)
@@ -162292,6 +162301,24 @@ async function emitExtensionEvent(emitter, name, event2) {
162292
162301
  return emitter.emitEvent(name, event2);
162293
162302
  }
162294
162303
 
162304
+ // src/extensions/disable.ts
162305
+ function isTruthyEnvFlag(value) {
162306
+ if (!value)
162307
+ return false;
162308
+ const normalized = value.trim().toLowerCase();
162309
+ return ["1", "true", "yes", "on"].includes(normalized);
162310
+ }
162311
+ function areExtensionsDisabled(env3 = process.env) {
162312
+ return isTruthyEnvFlag(env3[LETTA_DISABLE_EXTENSIONS_ENV]);
162313
+ }
162314
+ function shouldDisableExtensions(options3) {
162315
+ return Boolean(options3?.cliFlag || areExtensionsDisabled(options3?.env ?? process.env));
162316
+ }
162317
+ function disableExtensionsForProcess() {
162318
+ process.env[LETTA_DISABLE_EXTENSIONS_ENV] = "1";
162319
+ }
162320
+ var LETTA_DISABLE_EXTENSIONS_ENV = "LETTA_DISABLE_EXTENSIONS";
162321
+
162295
162322
  // src/extensions/tool-registry.ts
162296
162323
  function getMutableExtensionToolsRegistry() {
162297
162324
  const global2 = globalThis;
@@ -162301,6 +162328,8 @@ function getMutableExtensionToolsRegistry() {
162301
162328
  return global2[EXTENSION_TOOLS_KEY];
162302
162329
  }
162303
162330
  function getAvailableExtensionToolsRegistry() {
162331
+ if (areExtensionsDisabled())
162332
+ return new Map;
162304
162333
  return new Map(Array.from(getMutableExtensionToolsRegistry().entries()).filter(([, tool2]) => {
162305
162334
  if (tool2.activationSignal.aborted)
162306
162335
  return false;
@@ -162312,6 +162341,8 @@ function getAvailableExtensionToolsRegistry() {
162312
162341
  }));
162313
162342
  }
162314
162343
  function registerExtensionTool(tool2) {
162344
+ if (areExtensionsDisabled())
162345
+ return;
162315
162346
  getMutableExtensionToolsRegistry().set(tool2.name, tool2);
162316
162347
  }
162317
162348
  function unregisterExtensionTool(name, owner) {
@@ -162329,13 +162360,22 @@ function unregisterExtensionToolsForOwner(owner) {
162329
162360
  }
162330
162361
  }
162331
162362
  }
162363
+ function clearExtensionTools() {
162364
+ getMutableExtensionToolsRegistry().clear();
162365
+ }
162332
162366
  function getExtensionToolDefinition(name, registry2 = getMutableExtensionToolsRegistry()) {
162367
+ if (areExtensionsDisabled())
162368
+ return;
162333
162369
  return registry2.get(name);
162334
162370
  }
162335
162371
  function extensionToolRequiresApproval(name, registry2 = getMutableExtensionToolsRegistry()) {
162372
+ if (areExtensionsDisabled())
162373
+ return;
162336
162374
  return registry2.get(name)?.requiresApproval;
162337
162375
  }
162338
162376
  function isExtensionToolParallelSafe(name, registry2 = getMutableExtensionToolsRegistry()) {
162377
+ if (areExtensionsDisabled())
162378
+ return false;
162339
162379
  return registry2.get(name)?.parallelSafe === true;
162340
162380
  }
162341
162381
  async function runExtensionTool(tool2, context2) {
@@ -165285,7 +165325,7 @@ At most one step can be in_progress at a time.
165285
165325
  var init_UpdatePlan = () => {};
165286
165326
 
165287
165327
  // src/tools/descriptions/ViewImage.md
165288
- var ViewImage_default = `View a local image from the filesystem (only use if given a full filepath by the user, and the image isn't already attached to the thread context within <image ...> tags).
165328
+ var ViewImage_default = `View a local image file from the filesystem when visual inspection is needed. Use this for images already available on disk.
165289
165329
  `;
165290
165330
  var init_ViewImage = () => {};
165291
165331
 
@@ -169800,7 +169840,7 @@ function emitQueueUpdateIfOpen(runtime, scope) {
169800
169840
  emitQueueUpdate(transport, runtime, scope);
169801
169841
  }
169802
169842
  }
169803
- function emitStateSync(socket, runtime, scope) {
169843
+ function emitStateSync(socket, runtime, scope, options3) {
169804
169844
  const deviceStatus = buildDeviceStatus(runtime, scope);
169805
169845
  const deviceStatusJson = JSON.stringify(deviceStatus);
169806
169846
  const cacheKey = `${scope.agent_id ?? ""}:${scope.conversation_id ?? ""}`;
@@ -169810,7 +169850,7 @@ function emitStateSync(socket, runtime, scope) {
169810
169850
  lastSyncDeviceStatusByTransport.set(socket, scopeCache);
169811
169851
  }
169812
169852
  const prev = scopeCache.get(cacheKey);
169813
- if (deviceStatusJson !== prev) {
169853
+ if (options3?.forceDeviceStatus || deviceStatusJson !== prev) {
169814
169854
  scopeCache.set(cacheKey, deviceStatusJson);
169815
169855
  const message = {
169816
169856
  type: "update_device_status",
@@ -170299,7 +170339,7 @@ function isSyncCommand(value) {
170299
170339
  return false;
170300
170340
  }
170301
170341
  const candidate = value;
170302
- return candidate.type === "sync" && isRuntimeScope(candidate.runtime) && (candidate.recover_approvals === undefined || typeof candidate.recover_approvals === "boolean");
170342
+ return candidate.type === "sync" && isRuntimeScope(candidate.runtime) && (candidate.recover_approvals === undefined || typeof candidate.recover_approvals === "boolean") && (candidate.force_device_status === undefined || typeof candidate.force_device_status === "boolean");
170303
170343
  }
170304
170344
  function isTerminalSpawnCommand(value) {
170305
170345
  if (!value || typeof value !== "object")
@@ -188928,6 +188968,110 @@ Results include:
188928
188968
  `;
188929
188969
  var init_recall_subagent = () => {};
188930
188970
 
188971
+ // src/agent/prompts/recall_subagent_local.md
188972
+ var recall_subagent_local_default = `Your task is to recall past experience based on a query. Use the local CLI commands and search strategies below to search conversation history. Try to finish quickly with just 1-2 tool calls if possible (but use more if needed).
188973
+
188974
+ ## Output Format
188975
+
188976
+ 1. **Direct answer** - What the user asked about
188977
+ 2. **Key findings** - Relevant quotes or summaries from past conversations
188978
+ 3. **When discussed** - Timestamps of relevant discussions
188979
+ 4. **Outcome/Decision** - What was decided or concluded (if applicable)
188980
+
188981
+ ## Searching Messages
188982
+
188983
+ Use the CLI to search through past conversations.
188984
+
188985
+ ### CLI Usage
188986
+
188987
+ \`\`\`bash
188988
+ letta messages search --query <text> [options]
188989
+ \`\`\`
188990
+
188991
+ ### Options
188992
+
188993
+ | Option | Description |
188994
+ |--------|-------------|
188995
+ | \`--query <text>\` | Search query (required) |
188996
+ | \`--start-date <date>\` | Filter messages after this date (ISO format) |
188997
+ | \`--end-date <date>\` | Filter messages before this date (ISO format) |
188998
+ | \`--limit <n>\` | Max results (default: 10) |
188999
+ | \`--all-agents\` | Search all agents, not just current agent |
189000
+ | \`--agent <id>\` | Explicit agent ID (overrides LETTA_AGENT_ID) |
189001
+
189002
+ Local search is transcript-backed full-text search. Prefer distinctive keywords, exact strings, quoted phrases, and date bounds when possible.
189003
+
189004
+ ### Expanding Context: messages list
189005
+
189006
+ Use this to expand around a found message by ID cursor:
189007
+
189008
+ \`\`\`bash
189009
+ letta messages list [options]
189010
+ \`\`\`
189011
+
189012
+ | Option | Description |
189013
+ |--------|-------------|
189014
+ | \`--after <message-id>\` | Get messages after this ID (cursor) |
189015
+ | \`--before <message-id>\` | Get messages before this ID (cursor) |
189016
+ | \`--order <asc\\|desc>\` | Sort order (default: desc = newest first) |
189017
+ | \`--limit <n>\` | Max results (default: 20) |
189018
+
189019
+ ### Search Strategies
189020
+
189021
+ **Strategy 1: Needle + Expand (Recommended)**
189022
+
189023
+ 1. Search with keywords to find relevant messages:
189024
+ \`\`\`bash
189025
+ letta messages search --query "topic keywords" --limit 5
189026
+ \`\`\`
189027
+
189028
+ 2. Note the \`message_id\` of the most relevant result
189029
+
189030
+ 3. Expand before to get leading context:
189031
+ \`\`\`bash
189032
+ letta messages list --before "message-xyz" --limit 10
189033
+ \`\`\`
189034
+
189035
+ 4. Expand after for following context:
189036
+ \`\`\`bash
189037
+ letta messages list --after "message-xyz" --order asc --limit 10
189038
+ \`\`\`
189039
+
189040
+ **Strategy 2: Date-Bounded Search**
189041
+
189042
+ When you know approximately when something was discussed:
189043
+
189044
+ \`\`\`bash
189045
+ letta messages search --query "topic" --start-date "2025-12-31T00:00:00Z" --end-date "2025-12-31T23:59:59Z"
189046
+ \`\`\`
189047
+
189048
+ **Strategy 3: Broaden Terms**
189049
+
189050
+ When exact keywords miss, try alternate terms, abbreviations, filenames, issue IDs, branch names, or user quotes.
189051
+
189052
+ ### Accessing the Underlying Files
189053
+
189054
+ Prefer \`letta messages search\` first. If local full-text search misses or you need custom inspection, local backend transcripts are JSONL files on disk. The storage root is \`$LETTA_LOCAL_BACKEND_DIR\`, or \`~/.letta/lc-local-backend\` by default. Conversation directories live under \`conversations/\` and contain \`conversation.json\`, \`manifest.json\`, and \`messages.jsonl\`.
189055
+
189056
+ Use read-only Bash tools such as \`find\`, \`grep\`, \`rg\` if installed, or small scripts for custom searches, for example:
189057
+
189058
+ \`\`\`bash
189059
+ ROOT="\${LETTA_LOCAL_BACKEND_DIR:-$HOME/.letta/lc-local-backend}"
189060
+ find "$ROOT/conversations" -name messages.jsonl -print
189061
+ grep -R -n --include='messages.jsonl' "needle" "$ROOT/conversations"
189062
+ \`\`\`
189063
+
189064
+ ### Search Output
189065
+
189066
+ Results include:
189067
+ - \`message_id\` - Use for cursor-based expansion
189068
+ - \`message_type\` - \`user_message\`, \`assistant_message\`, \`reasoning_message\`
189069
+ - \`content\` or \`reasoning\` - The message text
189070
+ - \`created_at\` - Timestamp (ISO format)
189071
+ - \`agent_id\` - Which agent the message belongs to
189072
+ `;
189073
+ var init_recall_subagent_local = () => {};
189074
+
188931
189075
  // src/agent/subagents/context-budget.ts
188932
189076
  function estimateStartupContextTokens(text) {
188933
189077
  return Math.ceil(text.length / STARTUP_CONTEXT_ESTIMATED_CHARS_PER_TOKEN);
@@ -189616,8 +189760,12 @@ ${SYSTEM_REMINDER_CLOSE}
189616
189760
 
189617
189761
  `;
189618
189762
  }
189619
- function buildForkSystemReminder(subagentType) {
189763
+ function recallPromptForBackend(backendMode) {
189764
+ return backendMode === "local" ? recall_subagent_local_default : recall_subagent_default;
189765
+ }
189766
+ function buildForkSystemReminder(subagentType, backendMode) {
189620
189767
  if (subagentType === "recall") {
189768
+ const recallPrompt = recallPromptForBackend(backendMode);
189621
189769
  return `${SYSTEM_REMINDER_OPEN}
189622
189770
  You have been forked from the primary conversational thread to run as an independent subagent. The fork only exists so you can see the parent agent's conversation trajectory in-context as reference — you are NOT the primary agent and do not share its tools.
189623
189771
 
@@ -189628,7 +189776,7 @@ Your toolset is limited to Bash, Read, and TaskOutput. You cannot edit files, ru
189628
189776
  You CANNOT ask questions mid-execution — all instructions are provided upfront.
189629
189777
  Your final message will be returned to the caller.
189630
189778
 
189631
- ${recall_subagent_default}
189779
+ ${recallPrompt}
189632
189780
  ${SYSTEM_REMINDER_CLOSE}
189633
189781
 
189634
189782
  `;
@@ -189682,7 +189830,7 @@ async function spawnSubagent(type3, prompt, userModel, subagentId, signal, exist
189682
189830
  try {
189683
189831
  const cachedParent = parentAgent ?? await getBackend().retrieveAgent(resolvedParentAgentId);
189684
189832
  if (forkedContext) {
189685
- const systemReminder = buildForkSystemReminder(type3);
189833
+ const systemReminder = buildForkSystemReminder(type3, backendMode);
189686
189834
  finalPrompt = systemReminder + prompt;
189687
189835
  } else {
189688
189836
  const systemReminder = buildDeploySystemReminder(cachedParent.name ?? "", resolvedParentAgentId);
@@ -189699,6 +189847,7 @@ var init_manager3 = __esm(() => {
189699
189847
  init_context();
189700
189848
  init_model();
189701
189849
  init_recall_subagent();
189850
+ init_recall_subagent_local();
189702
189851
  init_subagent_state();
189703
189852
  init_backend2();
189704
189853
  init_metadata();
@@ -195644,9 +195793,9 @@ async function loadTools(modelIdentifier, options3) {
195644
195793
  function isOpenAIModel(modelIdentifier) {
195645
195794
  const info = getModelInfo(modelIdentifier);
195646
195795
  if (info?.handle && typeof info.handle === "string") {
195647
- return info.handle.startsWith("openai/") || info.handle.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`) || info.handle.startsWith("chatgpt_oauth/");
195796
+ return info.handle.startsWith("openai/") || info.handle.startsWith("openai-codex/") || info.handle.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`) || info.handle.startsWith("chatgpt_oauth/");
195648
195797
  }
195649
- return modelIdentifier.startsWith("openai/") || modelIdentifier.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`) || modelIdentifier.startsWith("chatgpt_oauth/");
195798
+ return modelIdentifier.startsWith("openai/") || modelIdentifier.startsWith("openai-codex/") || modelIdentifier.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`) || modelIdentifier.startsWith("chatgpt_oauth/");
195650
195799
  }
195651
195800
  function isGeminiModel(modelIdentifier) {
195652
195801
  const info = getModelInfo(modelIdentifier);
@@ -198909,7 +199058,8 @@ function createLocalConversationRecord(conversationId, agentId, _sequence, body
198909
199058
  in_context_message_ids: [],
198910
199059
  ...typeof bodyRecord.model === "string" || bodyRecord.model === null ? { model: bodyRecord.model } : {},
198911
199060
  ...modelSettings !== undefined ? { model_settings: modelSettings } : {},
198912
- ...typeof bodyRecord.context_window_limit === "number" ? { context_window_limit: bodyRecord.context_window_limit } : {}
199061
+ ...typeof bodyRecord.context_window_limit === "number" ? { context_window_limit: bodyRecord.context_window_limit } : {},
199062
+ ...typeof bodyRecord.hidden === "boolean" ? { hidden: bodyRecord.hidden } : {}
198913
199063
  };
198914
199064
  }
198915
199065
  function updateLocalConversationRecord(current, body, updatedAt) {
@@ -198939,6 +199089,9 @@ function updateLocalConversationRecord(current, body, updatedAt) {
198939
199089
  if (typeof bodyRecord.context_window_limit === "number") {
198940
199090
  next.context_window_limit = bodyRecord.context_window_limit;
198941
199091
  }
199092
+ if (typeof bodyRecord.hidden === "boolean") {
199093
+ next.hidden = bodyRecord.hidden;
199094
+ }
198942
199095
  if (typeof bodyRecord.summary === "string" || bodyRecord.summary === null) {
198943
199096
  next.summary = bodyRecord.summary;
198944
199097
  }
@@ -199585,7 +199738,7 @@ class LocalStore {
199585
199738
  const agentId = optionalString(bodyRecord.agent_id);
199586
199739
  const after = optionalString(bodyRecord.after);
199587
199740
  const limit3 = typeof bodyRecord.limit === "number" ? bodyRecord.limit : 20;
199588
- let conversations = [...this.conversations.values()].filter((conversation) => conversation.id !== "default" && (!agentId || conversation.agent_id === agentId));
199741
+ let conversations = [...this.conversations.values()].filter((conversation) => conversation.id !== "default" && (bodyRecord.include_hidden === true || !conversation.hidden) && (!agentId || conversation.agent_id === agentId));
199589
199742
  conversations.sort((a, b) => {
199590
199743
  const aDate = a.last_message_at ?? a.updated_at ?? a.created_at ?? "";
199591
199744
  const bDate = b.last_message_at ?? b.updated_at ?? b.created_at ?? "";
@@ -199647,7 +199800,8 @@ class LocalStore {
199647
199800
  const forked = createLocalConversationRecord(`${this.conversationIdPrefix}${this.conversationSeq}`, targetAgentId, this.conversationSeq, {
199648
199801
  summary: source2.summary ?? null,
199649
199802
  ...source2.model !== undefined ? { model: source2.model } : {},
199650
- ...source2.model_settings !== undefined ? { model_settings: source2.model_settings } : {}
199803
+ ...source2.model_settings !== undefined ? { model_settings: source2.model_settings } : {},
199804
+ ...typeof options3.hidden === "boolean" ? { hidden: options3.hidden } : {}
199651
199805
  });
199652
199806
  const sourceMessages = this.localMessagesForConversation(source2.id, source2.agent_id);
199653
199807
  const forkedMessages = sourceMessages.map((message) => this.cloneLocalMessageForConversation(message, forked.id, targetAgentId));
@@ -204779,6 +204933,9 @@ var init_local_backend = __esm(() => {
204779
204933
  this.complete = options3.complete;
204780
204934
  this.memfsEnabledOverride = options3.memfsEnabled;
204781
204935
  }
204936
+ getLocalStorageDir() {
204937
+ return this.storageDir;
204938
+ }
204782
204939
  async listModels() {
204783
204940
  return listLocalModels(this.storageDir);
204784
204941
  }
@@ -252413,7 +252570,7 @@ async function getResumeDataFromBackend2(agent2, conversationId, options3 = {})
252413
252570
  messageHistory: prepareMessageHistory2(messages)
252414
252571
  };
252415
252572
  } else {
252416
- inContextMessageIds = agentWithInContext.in_context_message_ids;
252573
+ inContextMessageIds = agentWithInContext.in_context_message_ids ?? agent2.message_ids;
252417
252574
  const lastInContextId = inContextMessageIds?.at(-1);
252418
252575
  let defaultConversationMessages = [];
252419
252576
  if (includeMessageHistory && isBackfillEnabled2() || !lastInContextId) {
@@ -258804,7 +258961,7 @@ function parsePatchToAdvancedDiff(patchLines, filePath) {
258804
258961
  hunks
258805
258962
  };
258806
258963
  }
258807
- var ADV_DIFF_CONTEXT_LINES = 1, ADV_DIFF_IGNORE_WHITESPACE = true;
258964
+ var ADV_DIFF_CONTEXT_LINES = 1, ADV_DIFF_IGNORE_WHITESPACE = false;
258808
258965
  var init_diff4 = __esm(() => {
258809
258966
  init_libesm();
258810
258967
  });
@@ -263106,7 +263263,8 @@ function createListenerMessageHandler(params) {
263106
263263
  return;
263107
263264
  }
263108
263265
  await replaySyncStateForRuntime(runtime, socket, parsed.runtime, {
263109
- recoverApprovals: parsed.recover_approvals !== false
263266
+ recoverApprovals: parsed.recover_approvals !== false,
263267
+ forceDeviceStatus: parsed.force_device_status === true
263110
263268
  });
263111
263269
  return;
263112
263270
  }
@@ -263468,7 +263626,9 @@ async function replaySyncStateForRuntime(listenerRuntime, socket, scope, opts) {
263468
263626
  }
263469
263627
  }
263470
263628
  }
263471
- emitStateSync(socket, listenerRuntime, scope);
263629
+ emitStateSync(socket, listenerRuntime, scope, {
263630
+ forceDeviceStatus: opts?.forceDeviceStatus
263631
+ });
263472
263632
  (opts?.scheduleWarmupsAfterSync ?? scheduleListenerWarmupsAfterSync)(listenerRuntime, scope);
263473
263633
  }
263474
263634
  async function recoverPendingChannelControlRequests(listener, opts) {
@@ -264608,20 +264768,80 @@ var init_listen_client = __esm(async () => {
264608
264768
  await init_client6();
264609
264769
  });
264610
264770
 
264611
- // src/backend/message-search.ts
264612
- function pageItems3(page) {
264613
- if (Array.isArray(page))
264614
- return page;
264615
- if (page && typeof page === "object") {
264616
- const maybePage = page;
264617
- if (typeof maybePage.getPaginatedItems === "function") {
264618
- return maybePage.getPaginatedItems();
264619
- }
264620
- if (Array.isArray(maybePage.items)) {
264621
- return maybePage.items;
264622
- }
264771
+ // src/backend/local/transcript-search.ts
264772
+ import { existsSync as existsSync40, readdirSync as readdirSync16, readFileSync as readFileSync30, statSync as statSync15 } from "node:fs";
264773
+ import { join as join41 } from "node:path";
264774
+ function readJsonFile2(path33) {
264775
+ if (!existsSync40(path33))
264776
+ return;
264777
+ try {
264778
+ return JSON.parse(readFileSync30(path33, "utf8"));
264779
+ } catch {
264780
+ return;
264623
264781
  }
264624
- return [];
264782
+ }
264783
+ function readJsonlFile2(path33) {
264784
+ if (!existsSync40(path33))
264785
+ return [];
264786
+ try {
264787
+ return readFileSync30(path33, "utf8").split(`
264788
+ `).filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
264789
+ } catch {
264790
+ return [];
264791
+ }
264792
+ }
264793
+ function conversationSearchRecord(value) {
264794
+ if (!isRecord(value))
264795
+ return;
264796
+ if (typeof value.id !== "string" || typeof value.agent_id !== "string") {
264797
+ return;
264798
+ }
264799
+ return {
264800
+ id: value.id,
264801
+ agent_id: value.agent_id,
264802
+ ...typeof value.hidden === "boolean" ? { hidden: value.hidden } : {}
264803
+ };
264804
+ }
264805
+ function isLocalMessage(value) {
264806
+ return isRecord(value) && typeof value.id === "string" && (value.role === "user" || value.role === "assistant" || value.role === "toolResult");
264807
+ }
264808
+ function transcriptFormat(manifest2, rows) {
264809
+ if (manifest2?.message_format === LOCAL_TRANSCRIPT_MESSAGE_FORMAT || manifest2?.message_format === LOCAL_TRANSCRIPT_LEGACY_MESSAGE_FORMAT) {
264810
+ return manifest2.message_format;
264811
+ }
264812
+ const firstDataRow = rows.find((row) => Boolean(isRecord(row) && row.type !== "session"));
264813
+ if (isRecord(firstDataRow) && "message" in firstDataRow) {
264814
+ return LOCAL_TRANSCRIPT_MESSAGE_FORMAT;
264815
+ }
264816
+ if (rows.some(isLocalMessage)) {
264817
+ return LOCAL_TRANSCRIPT_LEGACY_MESSAGE_FORMAT;
264818
+ }
264819
+ return;
264820
+ }
264821
+ function transcriptMessageRows(rows, format5) {
264822
+ if (format5 === LOCAL_TRANSCRIPT_LEGACY_MESSAGE_FORMAT) {
264823
+ return rows.map((row, sourceIndex) => ({ row, sourceIndex })).filter((item) => isLocalMessage(item.row)).map(({ row, sourceIndex }) => ({
264824
+ timestamp: row.metadata?.created_at,
264825
+ message: row,
264826
+ sourceIndex
264827
+ }));
264828
+ }
264829
+ const messageRows = [];
264830
+ rows.forEach((row, sourceIndex) => {
264831
+ if (!isRecord(row))
264832
+ return;
264833
+ if (row.type !== "message" && row.type !== "compaction")
264834
+ return;
264835
+ const message = row.message;
264836
+ if (!isLocalMessage(message))
264837
+ return;
264838
+ messageRows.push({
264839
+ timestamp: typeof row.timestamp === "string" ? row.timestamp : undefined,
264840
+ message,
264841
+ sourceIndex
264842
+ });
264843
+ });
264844
+ return messageRows;
264625
264845
  }
264626
264846
  function textFromContent2(content) {
264627
264847
  if (typeof content === "string")
@@ -264648,105 +264868,216 @@ function stringifySearchValue(value) {
264648
264868
  }
264649
264869
  }
264650
264870
  function searchableText(message) {
264651
- const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : message.tool_call ? [message.tool_call] : [];
264871
+ const localMessage = message;
264872
+ const toolCalls = Array.isArray(localMessage.tool_calls) ? localMessage.tool_calls : localMessage.tool_call ? [localMessage.tool_call] : [];
264652
264873
  return [
264653
- message.message_type,
264654
- textFromContent2(message.content),
264655
- message.reasoning,
264656
- message.summary,
264874
+ localMessage.message_type,
264875
+ textFromContent2(localMessage.content),
264876
+ localMessage.reasoning,
264877
+ localMessage.summary,
264657
264878
  ...toolCalls.flatMap((call2) => [call2.name, call2.arguments]),
264658
- stringifySearchValue(message.tool_return),
264659
- stringifySearchValue(message.func_response)
264879
+ stringifySearchValue(localMessage.tool_return),
264880
+ stringifySearchValue(localMessage.func_response)
264660
264881
  ].filter((part) => typeof part === "string" && part.length > 0).join(`
264661
264882
  `);
264662
264883
  }
264663
- function matchesQuery(message, query2) {
264664
- const terms = query2.toLowerCase().split(/\s+/).map((term) => term.trim()).filter(Boolean);
264665
- if (terms.length === 0)
264666
- return false;
264667
- const haystack = searchableText(message).toLowerCase();
264668
- return terms.every((term) => haystack.includes(term));
264884
+ function normalizeText(value) {
264885
+ return value.toLowerCase().replace(/\s+/g, " ").trim();
264669
264886
  }
264670
- function withinDateRange(message, startDate, endDate) {
264887
+ function parseQuery(query2) {
264888
+ const terms = [];
264889
+ const phrases = [];
264890
+ let buffer = "";
264891
+ let inQuote = false;
264892
+ let sawUnclosedQuote = false;
264893
+ const flush = () => {
264894
+ const value = buffer.trim();
264895
+ buffer = "";
264896
+ if (!value)
264897
+ return;
264898
+ if (inQuote)
264899
+ phrases.push(value);
264900
+ else
264901
+ terms.push(value);
264902
+ };
264903
+ for (const char of query2.trim()) {
264904
+ if (char === '"') {
264905
+ if (inQuote) {
264906
+ flush();
264907
+ inQuote = false;
264908
+ } else {
264909
+ flush();
264910
+ inQuote = true;
264911
+ }
264912
+ continue;
264913
+ }
264914
+ if (!inQuote && /\s/.test(char)) {
264915
+ flush();
264916
+ continue;
264917
+ }
264918
+ buffer += char;
264919
+ }
264920
+ if (inQuote)
264921
+ sawUnclosedQuote = true;
264922
+ flush();
264923
+ if (sawUnclosedQuote) {
264924
+ return {
264925
+ terms: query2.trim().split(/\s+/).map((term) => term.trim()).filter(Boolean),
264926
+ phrases: []
264927
+ };
264928
+ }
264929
+ return { terms, phrases };
264930
+ }
264931
+ function matchScore(text2, query2) {
264932
+ const haystack = normalizeText(text2);
264933
+ if (!haystack)
264934
+ return null;
264935
+ let score = 0;
264936
+ for (const rawPhrase of query2.phrases) {
264937
+ const phrase = normalizeText(rawPhrase);
264938
+ if (!phrase)
264939
+ continue;
264940
+ const index = haystack.indexOf(phrase);
264941
+ if (index < 0)
264942
+ return null;
264943
+ score += index * 0.1;
264944
+ }
264945
+ for (const rawTerm of query2.terms) {
264946
+ const term = normalizeText(rawTerm);
264947
+ if (!term)
264948
+ continue;
264949
+ const index = haystack.indexOf(term);
264950
+ if (index < 0)
264951
+ return null;
264952
+ score += index + Math.max(0, 50 - term.length);
264953
+ }
264954
+ return score;
264955
+ }
264956
+ function dateInRange(createdAt, startDate, endDate) {
264671
264957
  if (!startDate && !endDate)
264672
264958
  return true;
264673
- if (!message.date)
264959
+ if (!createdAt)
264960
+ return true;
264961
+ const messageTime = Date.parse(createdAt);
264962
+ if (!Number.isFinite(messageTime))
264674
264963
  return true;
264675
- const time3 = new Date(message.date).getTime();
264676
- if (Number.isNaN(time3))
264964
+ const startTime = startDate ? Date.parse(startDate) : Number.NEGATIVE_INFINITY;
264965
+ const endTime = endDate ? Date.parse(endDate) : Number.POSITIVE_INFINITY;
264966
+ if (startDate && !Number.isFinite(startTime))
264677
264967
  return true;
264678
- const startTime = startDate ? new Date(startDate).getTime() : 0;
264679
- const endTime = endDate ? new Date(endDate).getTime() : Number.POSITIVE_INFINITY;
264680
- return time3 >= startTime && time3 <= endTime;
264968
+ if (endDate && !Number.isFinite(endTime))
264969
+ return true;
264970
+ return messageTime >= startTime && messageTime <= endTime;
264681
264971
  }
264682
264972
  function toSearchResult(message) {
264683
- const createdAt = message.date ?? new Date(0).toISOString();
264973
+ const localMessage = message;
264974
+ const createdAt = localMessage.date ?? new Date(0).toISOString();
264684
264975
  return {
264685
- ...message,
264686
- message_id: message.id ?? `${message.agent_id ?? "local"}:${createdAt}`,
264976
+ ...localMessage,
264977
+ message_id: localMessage.id ?? `${localMessage.agent_id ?? "local"}:${createdAt}`,
264687
264978
  created_at: createdAt,
264688
- agent_id: message.agent_id ?? null,
264689
- conversation_id: message.conversation_id ?? null
264979
+ agent_id: localMessage.agent_id ?? null,
264980
+ conversation_id: localMessage.conversation_id ?? null
264690
264981
  };
264691
264982
  }
264692
- async function localConversationMessages(backend4, conversationId, agentId) {
264983
+ function projectedTranscriptMessages(input) {
264984
+ const fallbackDate = input.row.timestamp ?? input.row.message.metadata?.created_at ?? new Date(0).toISOString();
264985
+ const projected = projectLocalMessageToStoredMessages(input.row.message, input.agentId, input.conversationId, fallbackDate);
264986
+ return withProjectedMessageDates(projected, input.row.sourceIndex);
264987
+ }
264988
+ function collectConversationMessages(input) {
264989
+ const { conversation, conversationDir } = input;
264990
+ if (input.agentId && conversation.agent_id !== input.agentId)
264991
+ return [];
264992
+ if (input.conversationId && conversation.id !== input.conversationId)
264993
+ return [];
264994
+ const messagesPath = join41(conversationDir, "messages.jsonl");
264995
+ const rows = readJsonlFile2(messagesPath);
264996
+ if (rows.length === 0)
264997
+ return [];
264998
+ const manifest2 = readJsonFile2(join41(conversationDir, "manifest.json"));
264999
+ const format5 = transcriptFormat(manifest2, rows);
265000
+ if (!format5)
265001
+ return [];
265002
+ return transcriptMessageRows(rows, format5).flatMap((row) => projectedTranscriptMessages({
265003
+ row,
265004
+ agentId: conversation.agent_id,
265005
+ conversationId: conversation.id
265006
+ })).map((message) => ({
265007
+ message,
265008
+ text: searchableText(message),
265009
+ score: Number.POSITIVE_INFINITY
265010
+ })).map((record5) => {
265011
+ const score = matchScore(record5.text, input.query);
265012
+ return score === null ? null : { ...record5, score };
265013
+ }).filter((record5) => record5 !== null).filter((record5) => {
265014
+ const message = record5.message;
265015
+ return dateInRange(message.date, input.startDate, input.endDate);
265016
+ });
265017
+ }
265018
+ function conversationDirectories(storageDir) {
265019
+ const conversationsDir = join41(storageDir, "conversations");
265020
+ if (!existsSync40(conversationsDir))
265021
+ return [];
264693
265022
  try {
264694
- const page = await backend4.listConversationMessages(conversationId, {
264695
- limit: LOCAL_SEARCH_SCAN_LIMIT,
264696
- order: "desc",
264697
- ...agentId ? { agent_id: agentId } : {}
264698
- });
264699
- return pageItems3(page);
265023
+ return readdirSync16(conversationsDir).map((entry) => join41(conversationsDir, entry)).filter((entryPath) => statSync15(entryPath).isDirectory());
264700
265024
  } catch {
264701
265025
  return [];
264702
265026
  }
264703
265027
  }
264704
- async function localAgentMessages(backend4, agentId) {
264705
- const messages = [
264706
- ...await localConversationMessages(backend4, "default", agentId)
264707
- ];
264708
- try {
264709
- const conversationsPage = await backend4.listConversations({
264710
- agent_id: agentId,
264711
- limit: LOCAL_SEARCH_SCAN_LIMIT
264712
- });
264713
- const conversations = pageItems3(conversationsPage);
264714
- for (const conversation of conversations) {
264715
- if (!conversation.id || conversation.id === "default")
264716
- continue;
264717
- messages.push(...await localConversationMessages(backend4, conversation.id, agentId));
264718
- }
264719
- } catch {}
264720
- return messages;
264721
- }
264722
- async function localSearchMessages(backend4, body3) {
264723
- const query2 = typeof body3.query === "string" ? body3.query.trim() : "";
264724
- if (!query2)
265028
+ function searchLocalTranscriptMessages(storageDir, body3) {
265029
+ const queryText = typeof body3.query === "string" ? body3.query.trim() : "";
265030
+ if (!queryText)
265031
+ return [];
265032
+ const parsedQuery = parseQuery(queryText);
265033
+ if (parsedQuery.terms.length === 0 && parsedQuery.phrases.length === 0) {
265034
+ return [];
265035
+ }
265036
+ const limit3 = typeof body3.limit === "number" ? Math.max(0, body3.limit) : 100;
265037
+ if (limit3 === 0)
264725
265038
  return [];
264726
- const limit3 = typeof body3.limit === "number" ? body3.limit : 100;
264727
265039
  const agentId = typeof body3.agent_id === "string" ? body3.agent_id : undefined;
264728
265040
  const conversationId = typeof body3.conversation_id === "string" ? body3.conversation_id : undefined;
265041
+ if (conversationId === "default" && !agentId)
265042
+ return [];
264729
265043
  const startDate = typeof body3.start_date === "string" ? body3.start_date : undefined;
264730
265044
  const endDate = typeof body3.end_date === "string" ? body3.end_date : undefined;
264731
- let messages = [];
264732
- if (conversationId) {
264733
- messages = await localConversationMessages(backend4, conversationId, agentId);
264734
- } else if (agentId) {
264735
- messages = await localAgentMessages(backend4, agentId);
264736
- } else {
264737
- const agentsPage = await backend4.listAgents({
264738
- limit: LOCAL_SEARCH_SCAN_LIMIT
265045
+ const includeHidden = body3.include_hidden === true;
265046
+ const records = conversationDirectories(storageDir).flatMap((conversationDir) => {
265047
+ const conversation = conversationSearchRecord(readJsonFile2(join41(conversationDir, "conversation.json")));
265048
+ if (!conversation)
265049
+ return [];
265050
+ if (conversation.hidden && !includeHidden)
265051
+ return [];
265052
+ return collectConversationMessages({
265053
+ conversationDir,
265054
+ conversation,
265055
+ query: parsedQuery,
265056
+ agentId,
265057
+ conversationId,
265058
+ startDate,
265059
+ endDate
264739
265060
  });
264740
- const agents = pageItems3(agentsPage);
264741
- for (const agent2 of agents) {
264742
- messages.push(...await localAgentMessages(backend4, agent2.id));
264743
- }
264744
- }
264745
- return messages.filter((message) => matchesQuery(message, query2)).filter((message) => withinDateRange(message, startDate, endDate)).sort((a2, b3) => (b3.date ?? "").localeCompare(a2.date ?? "")).slice(0, limit3).map(toSearchResult);
265061
+ });
265062
+ return records.sort((a2, b3) => {
265063
+ if (a2.score !== b3.score)
265064
+ return a2.score - b3.score;
265065
+ const aDate = a2.message.date ?? "";
265066
+ const bDate = b3.message.date ?? "";
265067
+ return bDate.localeCompare(aDate);
265068
+ }).slice(0, limit3).map((record5) => toSearchResult(record5.message));
265069
+ }
265070
+ var init_transcript_search = __esm(() => {
265071
+ init_local_store();
265072
+ });
265073
+
265074
+ // src/backend/message-search.ts
265075
+ function localStorageDirForBackend(backend4) {
265076
+ return backend4.getLocalStorageDir?.() ?? getLocalBackendStorageDir();
264746
265077
  }
264747
265078
  async function searchMessagesForBackend(body3, backend4 = getBackend()) {
264748
265079
  if (backend4.capabilities.localModelCatalog) {
264749
- return await localSearchMessages(backend4, body3);
265080
+ return searchLocalTranscriptMessages(localStorageDirForBackend(backend4), body3);
264750
265081
  }
264751
265082
  return searchMessages({
264752
265083
  ...body3,
@@ -264763,10 +265094,11 @@ async function warmMessageSearchCacheForBackend(body3, backend4 = getBackend())
264763
265094
  }
264764
265095
  return warmSearchCache(body3);
264765
265096
  }
264766
- var LOCAL_SEARCH_SCAN_LIMIT = 1000;
264767
265097
  var init_message_search = __esm(() => {
264768
265098
  init_search();
264769
265099
  init_backend();
265100
+ init_paths();
265101
+ init_transcript_search();
264770
265102
  });
264771
265103
 
264772
265104
  // src/auth/ConstellationLoginView.tsx
@@ -265297,9 +265629,9 @@ var init_paste_registry = __esm(() => {
265297
265629
 
265298
265630
  // src/cli/helpers/clipboard.ts
265299
265631
  import { execFileSync as execFileSync4 } from "node:child_process";
265300
- import { existsSync as existsSync40, readFileSync as readFileSync30, statSync as statSync15, unlinkSync as unlinkSync8 } from "node:fs";
265632
+ import { existsSync as existsSync41, readFileSync as readFileSync31, statSync as statSync16, unlinkSync as unlinkSync8 } from "node:fs";
265301
265633
  import { tmpdir as tmpdir5 } from "node:os";
265302
- import { basename as basename18, extname as extname8, isAbsolute as isAbsolute17, join as join41, resolve as resolve30 } from "node:path";
265634
+ import { basename as basename18, extname as extname8, isAbsolute as isAbsolute17, join as join42, resolve as resolve30 } from "node:path";
265303
265635
  function countLines(text2) {
265304
265636
  return (text2.match(/\r\n|\r|\n/g) || []).length + 1;
265305
265637
  }
@@ -265354,16 +265686,16 @@ function translatePasteForImages(paste) {
265354
265686
  if (IMAGE_EXTS.has(ext3)) {
265355
265687
  let buf = null;
265356
265688
  try {
265357
- const stat11 = statSync15(filePath);
265689
+ const stat11 = statSync16(filePath);
265358
265690
  if (stat11.isFile())
265359
- buf = readFileSync30(filePath);
265691
+ buf = readFileSync31(filePath);
265360
265692
  } catch {}
265361
265693
  let clipboardMediaType = null;
265362
265694
  if (!buf && process.platform === "darwin" && /TemporaryItems\/.*screencaptureui/i.test(filePath)) {
265363
265695
  const clipResult = getClipboardImageToTempFile();
265364
265696
  if (clipResult) {
265365
265697
  try {
265366
- buf = readFileSync30(clipResult.tempPath);
265698
+ buf = readFileSync31(clipResult.tempPath);
265367
265699
  clipboardMediaType = UTI_TO_MEDIA_TYPE[clipResult.uti] || null;
265368
265700
  try {
265369
265701
  unlinkSync8(clipResult.tempPath);
@@ -265389,7 +265721,7 @@ function translatePasteForImages(paste) {
265389
265721
  function getClipboardImageToTempFile() {
265390
265722
  if (process.platform !== "darwin")
265391
265723
  return null;
265392
- const tempPath = join41(tmpdir5(), `letta-clipboard-${Date.now()}.bin`);
265724
+ const tempPath = join42(tmpdir5(), `letta-clipboard-${Date.now()}.bin`);
265393
265725
  try {
265394
265726
  const jxa = `
265395
265727
  ObjC.import('AppKit');
@@ -265412,11 +265744,11 @@ function getClipboardImageToTempFile() {
265412
265744
  encoding: "utf8",
265413
265745
  stdio: ["ignore", "pipe", "ignore"]
265414
265746
  }).trim();
265415
- if (!uti || !existsSync40(tempPath))
265747
+ if (!uti || !existsSync41(tempPath))
265416
265748
  return null;
265417
265749
  return { tempPath, uti };
265418
265750
  } catch {
265419
- if (existsSync40(tempPath)) {
265751
+ if (existsSync41(tempPath)) {
265420
265752
  try {
265421
265753
  unlinkSync8(tempPath);
265422
265754
  } catch {}
@@ -265432,7 +265764,7 @@ async function tryImportClipboardImageMac() {
265432
265764
  return null;
265433
265765
  const { tempPath, uti } = clipboardResult;
265434
265766
  try {
265435
- const buffer = readFileSync30(tempPath);
265767
+ const buffer = readFileSync31(tempPath);
265436
265768
  try {
265437
265769
  unlinkSync8(tempPath);
265438
265770
  } catch {}
@@ -265449,7 +265781,7 @@ async function tryImportClipboardImageMac() {
265449
265781
  height: resized.height
265450
265782
  };
265451
265783
  } catch (err) {
265452
- if (existsSync40(tempPath)) {
265784
+ if (existsSync41(tempPath)) {
265453
265785
  try {
265454
265786
  unlinkSync8(tempPath);
265455
265787
  } catch {}
@@ -267181,14 +267513,14 @@ __export(exports_debug2, {
267181
267513
  });
267182
267514
  import {
267183
267515
  appendFileSync as appendFileSync7,
267184
- existsSync as existsSync42,
267516
+ existsSync as existsSync43,
267185
267517
  mkdirSync as mkdirSync30,
267186
- readdirSync as readdirSync16,
267187
- readFileSync as readFileSync32,
267518
+ readdirSync as readdirSync17,
267519
+ readFileSync as readFileSync33,
267188
267520
  unlinkSync as unlinkSync9
267189
267521
  } from "node:fs";
267190
267522
  import { homedir as homedir25 } from "node:os";
267191
- import { join as join44 } from "node:path";
267523
+ import { join as join45 } from "node:path";
267192
267524
  import { format as format5 } from "node:util";
267193
267525
  function isDebugEnabled2() {
267194
267526
  const lettaDebug = process.env.LETTA_DEBUG;
@@ -267219,8 +267551,8 @@ class DebugLogFile2 {
267219
267551
  const telem = process.env.LETTA_CODE_TELEM;
267220
267552
  if (telem === "0" || telem === "false")
267221
267553
  return;
267222
- this.agentDir = join44(DEBUG_LOG_DIR2, agentId);
267223
- this.logPath = join44(this.agentDir, `${sessionId}.log`);
267554
+ this.agentDir = join45(DEBUG_LOG_DIR2, agentId);
267555
+ this.logPath = join45(this.agentDir, `${sessionId}.log`);
267224
267556
  this.dirCreated = false;
267225
267557
  this.pruneOldSessions();
267226
267558
  }
@@ -267236,9 +267568,9 @@ class DebugLogFile2 {
267236
267568
  if (!this.logPath)
267237
267569
  return;
267238
267570
  try {
267239
- if (!existsSync42(this.logPath))
267571
+ if (!existsSync43(this.logPath))
267240
267572
  return;
267241
- const content = readFileSync32(this.logPath, "utf8");
267573
+ const content = readFileSync33(this.logPath, "utf8");
267242
267574
  const lines = content.trimEnd().split(`
267243
267575
  `);
267244
267576
  return lines.slice(-maxLines).join(`
@@ -267251,7 +267583,7 @@ class DebugLogFile2 {
267251
267583
  if (this.dirCreated || !this.agentDir)
267252
267584
  return;
267253
267585
  try {
267254
- if (!existsSync42(this.agentDir)) {
267586
+ if (!existsSync43(this.agentDir)) {
267255
267587
  mkdirSync30(this.agentDir, { recursive: true });
267256
267588
  }
267257
267589
  this.dirCreated = true;
@@ -267261,14 +267593,14 @@ class DebugLogFile2 {
267261
267593
  if (!this.agentDir)
267262
267594
  return;
267263
267595
  try {
267264
- if (!existsSync42(this.agentDir))
267596
+ if (!existsSync43(this.agentDir))
267265
267597
  return;
267266
- const files = readdirSync16(this.agentDir).filter((f4) => f4.endsWith(".log")).sort();
267598
+ const files = readdirSync17(this.agentDir).filter((f4) => f4.endsWith(".log")).sort();
267267
267599
  if (files.length >= MAX_SESSION_FILES3) {
267268
267600
  const toDelete = files.slice(0, files.length - MAX_SESSION_FILES3 + 1);
267269
267601
  for (const file3 of toDelete) {
267270
267602
  try {
267271
- unlinkSync9(join44(this.agentDir, file3));
267603
+ unlinkSync9(join45(this.agentDir, file3));
267272
267604
  } catch {}
267273
267605
  }
267274
267606
  }
@@ -267293,7 +267625,7 @@ function debugWarn2(prefix, message, ...args) {
267293
267625
  }
267294
267626
  var DEBUG_LOG_DIR2, MAX_SESSION_FILES3 = 5, DEFAULT_TAIL_LINES2 = 50, debugLogFile2;
267295
267627
  var init_debug2 = __esm(() => {
267296
- DEBUG_LOG_DIR2 = join44(homedir25(), ".letta", "logs", "debug");
267628
+ DEBUG_LOG_DIR2 = join45(homedir25(), ".letta", "logs", "debug");
267297
267629
  debugLogFile2 = new DebugLogFile2;
267298
267630
  });
267299
267631
 
@@ -267325,16 +267657,16 @@ __export(exports_skills3, {
267325
267657
  SKILLS_DIR: () => SKILLS_DIR2,
267326
267658
  GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR2
267327
267659
  });
267328
- import { existsSync as existsSync43 } from "node:fs";
267660
+ import { existsSync as existsSync44 } from "node:fs";
267329
267661
  import { readdir as readdir10, readFile as readFile13, realpath as realpath5, stat as stat11 } from "node:fs/promises";
267330
- import { dirname as dirname22, join as join45 } from "node:path";
267662
+ import { dirname as dirname22, join as join46 } from "node:path";
267331
267663
  import { fileURLToPath as fileURLToPath9 } from "node:url";
267332
267664
  function getBundledSkillsPath2() {
267333
267665
  const thisDir = dirname22(fileURLToPath9(import.meta.url));
267334
267666
  if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
267335
- return join45(thisDir, "../skills/builtin");
267667
+ return join46(thisDir, "../skills/builtin");
267336
267668
  }
267337
- return join45(thisDir, "skills");
267669
+ return join46(thisDir, "skills");
267338
267670
  }
267339
267671
  function compareSkills2(a2, b3) {
267340
267672
  return a2.id.localeCompare(b3.id) || a2.source.localeCompare(b3.source) || a2.path.localeCompare(b3.path);
@@ -267375,7 +267707,7 @@ function isUserInvocableSkill2(skill2) {
267375
267707
  return skill2.userInvocable !== false;
267376
267708
  }
267377
267709
  function getAgentSkillsDir2(agentId) {
267378
- return join45(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "memory/skills");
267710
+ return join46(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "memory/skills");
267379
267711
  }
267380
267712
  async function getBundledSkills2() {
267381
267713
  const bundledPath = getBundledSkillsPath2();
@@ -267384,7 +267716,7 @@ async function getBundledSkills2() {
267384
267716
  }
267385
267717
  async function discoverSkillsFromDir2(skillsPath, source2) {
267386
267718
  const errors7 = [];
267387
- if (!existsSync43(skillsPath)) {
267719
+ if (!existsSync44(skillsPath)) {
267388
267720
  return { skills: [], errors: [] };
267389
267721
  }
267390
267722
  const skills = [];
@@ -267398,7 +267730,7 @@ async function discoverSkillsFromDir2(skillsPath, source2) {
267398
267730
  }
267399
267731
  return { skills, errors: errors7 };
267400
267732
  }
267401
- async function discoverSkills2(projectSkillsPath = join45(process.cwd(), SKILLS_DIR2), agentId, options3) {
267733
+ async function discoverSkills2(projectSkillsPath = join46(process.cwd(), SKILLS_DIR2), agentId, options3) {
267402
267734
  const allErrors = [];
267403
267735
  const skillsById = new Map;
267404
267736
  const sourceSet = new Set(options3?.sources ?? ALL_SKILL_SOURCES);
@@ -267453,7 +267785,7 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors7, source2,
267453
267785
  try {
267454
267786
  const entries = await readdir10(currentPath, { withFileTypes: true });
267455
267787
  for (const entry of entries) {
267456
- const fullPath = join45(currentPath, entry.name);
267788
+ const fullPath = join46(currentPath, entry.name);
267457
267789
  try {
267458
267790
  let isDirectory = entry.isDirectory();
267459
267791
  let isFile = entry.isFile();
@@ -267543,7 +267875,7 @@ ${lines.join(`
267543
267875
  var SKILLS_DIR2 = ".skills", GLOBAL_SKILLS_DIR2;
267544
267876
  var init_skills4 = __esm(() => {
267545
267877
  init_skill_sources();
267546
- GLOBAL_SKILLS_DIR2 = join45(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
267878
+ GLOBAL_SKILLS_DIR2 = join46(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
267547
267879
  });
267548
267880
 
267549
267881
  // src/utils/fs.ts
@@ -267551,13 +267883,13 @@ var exports_fs = {};
267551
267883
  __export(exports_fs, {
267552
267884
  writeJsonFile: () => writeJsonFile,
267553
267885
  writeFile: () => writeFile14,
267554
- readJsonFile: () => readJsonFile2,
267886
+ readJsonFile: () => readJsonFile3,
267555
267887
  readFile: () => readFile14,
267556
267888
  mkdir: () => mkdir12,
267557
267889
  exists: () => exists2
267558
267890
  });
267559
267891
  import {
267560
- existsSync as existsSync44,
267892
+ existsSync as existsSync45,
267561
267893
  readFileSync as fsReadFileSync2,
267562
267894
  writeFileSync as fsWriteFileSync2,
267563
267895
  mkdirSync as mkdirSync31
@@ -267568,18 +267900,18 @@ async function readFile14(path33) {
267568
267900
  }
267569
267901
  async function writeFile14(path33, content) {
267570
267902
  const dir = dirname23(path33);
267571
- if (!existsSync44(dir)) {
267903
+ if (!existsSync45(dir)) {
267572
267904
  mkdirSync31(dir, { recursive: true });
267573
267905
  }
267574
267906
  fsWriteFileSync2(path33, content, { encoding: "utf-8", flush: true });
267575
267907
  }
267576
267908
  function exists2(path33) {
267577
- return existsSync44(path33);
267909
+ return existsSync45(path33);
267578
267910
  }
267579
267911
  async function mkdir12(path33, options3) {
267580
267912
  mkdirSync31(path33, options3);
267581
267913
  }
267582
- async function readJsonFile2(path33) {
267914
+ async function readJsonFile3(path33) {
267583
267915
  const text2 = await readFile14(path33);
267584
267916
  return JSON.parse(text2);
267585
267917
  }
@@ -267783,7 +268115,7 @@ __export(exports_auto_update2, {
267783
268115
  import { execFile as execFile16 } from "node:child_process";
267784
268116
  import { realpathSync as realpathSync4 } from "node:fs";
267785
268117
  import { readdir as readdir11, rm as rm5 } from "node:fs/promises";
267786
- import { join as join46 } from "node:path";
268118
+ import { join as join47 } from "node:path";
267787
268119
  import { promisify as promisify14 } from "node:util";
267788
268120
  function debugLog4(...args) {
267789
268121
  if (DEBUG2) {
@@ -267948,12 +268280,12 @@ async function getNpmGlobalPath2() {
267948
268280
  }
267949
268281
  }
267950
268282
  async function cleanupOrphanedDirs2(globalPath) {
267951
- const lettaAiDir = join46(globalPath, "lib/node_modules/@letta-ai");
268283
+ const lettaAiDir = join47(globalPath, "lib/node_modules/@letta-ai");
267952
268284
  try {
267953
268285
  const entries = await readdir11(lettaAiDir);
267954
268286
  for (const entry of entries) {
267955
268287
  if (entry.startsWith(".letta-code-")) {
267956
- const orphanPath = join46(lettaAiDir, entry);
268288
+ const orphanPath = join47(lettaAiDir, entry);
267957
268289
  debugLog4("Cleaning orphaned temp directory:", orphanPath);
267958
268290
  await rm5(orphanPath, { recursive: true, force: true });
267959
268291
  }
@@ -268491,17 +268823,17 @@ var exports_bootstrap_tools = {};
268491
268823
  __export(exports_bootstrap_tools, {
268492
268824
  bootstrapBaseToolsIfNeeded: () => bootstrapBaseToolsIfNeeded
268493
268825
  });
268494
- import { existsSync as existsSync46, mkdirSync as mkdirSync33, writeFileSync as writeFileSync25 } from "node:fs";
268826
+ import { existsSync as existsSync47, mkdirSync as mkdirSync33, writeFileSync as writeFileSync25 } from "node:fs";
268495
268827
  import { homedir as homedir27 } from "node:os";
268496
- import { join as join48 } from "node:path";
268828
+ import { join as join49 } from "node:path";
268497
268829
  async function bootstrapBaseToolsIfNeeded() {
268498
- if (existsSync46(MARKER_PATH))
268830
+ if (existsSync47(MARKER_PATH))
268499
268831
  return;
268500
268832
  debugLog("bootstrap", "No marker found, bootstrapping base tools...");
268501
268833
  try {
268502
268834
  const success2 = await addBaseToolsToServer();
268503
268835
  if (success2) {
268504
- mkdirSync33(join48(homedir27(), ".letta"), { recursive: true });
268836
+ mkdirSync33(join49(homedir27(), ".letta"), { recursive: true });
268505
268837
  writeFileSync25(MARKER_PATH, new Date().toISOString(), "utf-8");
268506
268838
  }
268507
268839
  } catch (err) {
@@ -268512,7 +268844,7 @@ var MARKER_PATH;
268512
268844
  var init_bootstrap_tools = __esm(() => {
268513
268845
  init_debug();
268514
268846
  init_create6();
268515
- MARKER_PATH = join48(homedir27(), ".letta", ".bootstrapped");
268847
+ MARKER_PATH = join49(homedir27(), ".letta", ".bootstrapped");
268516
268848
  });
268517
268849
 
268518
268850
  // src/tools/filter.ts
@@ -268915,6 +269247,61 @@ function validateRegistryHandleOrThrow2(handle2) {
268915
269247
  }
268916
269248
  }
268917
269249
 
269250
+ // src/extensions/capabilities.ts
269251
+ function cloneExtensionCapabilities(capabilities) {
269252
+ return {
269253
+ tools: capabilities.tools,
269254
+ commands: capabilities.commands,
269255
+ events: {
269256
+ lifecycle: capabilities.events.lifecycle,
269257
+ tools: capabilities.events.tools,
269258
+ turns: capabilities.events.turns
269259
+ },
269260
+ providers: capabilities.providers,
269261
+ ui: {
269262
+ panels: capabilities.ui.panels,
269263
+ statusValues: capabilities.ui.statusValues,
269264
+ customStatuslineRenderer: capabilities.ui.customStatuslineRenderer
269265
+ }
269266
+ };
269267
+ }
269268
+ function resolveExtensionCapabilities(capabilities) {
269269
+ return cloneExtensionCapabilities(capabilities ?? DEFAULT_EXTENSION_CAPABILITIES);
269270
+ }
269271
+ var DEFAULT_EXTENSION_CAPABILITIES, DISABLED_EXTENSION_CAPABILITIES;
269272
+ var init_capabilities = __esm(() => {
269273
+ DEFAULT_EXTENSION_CAPABILITIES = {
269274
+ tools: true,
269275
+ commands: true,
269276
+ events: {
269277
+ lifecycle: true,
269278
+ tools: true,
269279
+ turns: true
269280
+ },
269281
+ providers: true,
269282
+ ui: {
269283
+ panels: true,
269284
+ statusValues: true,
269285
+ customStatuslineRenderer: true
269286
+ }
269287
+ };
269288
+ DISABLED_EXTENSION_CAPABILITIES = {
269289
+ tools: false,
269290
+ commands: false,
269291
+ events: {
269292
+ lifecycle: false,
269293
+ tools: false,
269294
+ turns: false
269295
+ },
269296
+ providers: false,
269297
+ ui: {
269298
+ panels: false,
269299
+ statusValues: false,
269300
+ customStatuslineRenderer: false
269301
+ }
269302
+ };
269303
+ });
269304
+
268918
269305
  // node_modules/typescript/lib/typescript.js
268919
269306
  var require_typescript = __commonJS((exports, module3) => {
268920
269307
  var __dirname = "/home/runner/work/letta-code/letta-code/node_modules/typescript/lib", __filename = "/home/runner/work/letta-code/letta-code/node_modules/typescript/lib/typescript.js";
@@ -277027,7 +277414,7 @@ ${lanes.join(`
277027
277414
  return process.memoryUsage().heapUsed;
277028
277415
  },
277029
277416
  getFileSize(path35) {
277030
- const stat12 = statSync18(path35);
277417
+ const stat12 = statSync19(path35);
277031
277418
  if (stat12 == null ? undefined : stat12.isFile()) {
277032
277419
  return stat12.size;
277033
277420
  }
@@ -277070,7 +277457,7 @@ ${lanes.join(`
277070
277457
  }
277071
277458
  };
277072
277459
  return nodeSystem;
277073
- function statSync18(path35) {
277460
+ function statSync19(path35) {
277074
277461
  try {
277075
277462
  return _fs.statSync(path35, statSyncOptions);
277076
277463
  } catch {
@@ -277122,7 +277509,7 @@ ${lanes.join(`
277122
277509
  activeSession.post("Profiler.stop", (err, { profile }) => {
277123
277510
  var _a8;
277124
277511
  if (!err) {
277125
- if ((_a8 = statSync18(profilePath)) == null ? undefined : _a8.isDirectory()) {
277512
+ if ((_a8 = statSync19(profilePath)) == null ? undefined : _a8.isDirectory()) {
277126
277513
  profilePath = _path.join(profilePath, `${(/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-")}+P${process.pid}.cpuprofile`);
277127
277514
  }
277128
277515
  try {
@@ -277231,7 +277618,7 @@ ${lanes.join(`
277231
277618
  let stat12;
277232
277619
  if (typeof dirent === "string" || dirent.isSymbolicLink()) {
277233
277620
  const name = combinePaths(path35, entry);
277234
- stat12 = statSync18(name);
277621
+ stat12 = statSync19(name);
277235
277622
  if (!stat12) {
277236
277623
  continue;
277237
277624
  }
@@ -277255,7 +277642,7 @@ ${lanes.join(`
277255
277642
  return matchFiles(path35, extensions, excludes, includes, useCaseSensitiveFileNames2, process.cwd(), depth, getAccessibleFileSystemEntries, realpath6);
277256
277643
  }
277257
277644
  function fileSystemEntryExists(path35, entryKind) {
277258
- const stat12 = statSync18(path35);
277645
+ const stat12 = statSync19(path35);
277259
277646
  if (!stat12) {
277260
277647
  return false;
277261
277648
  }
@@ -277289,7 +277676,7 @@ ${lanes.join(`
277289
277676
  }
277290
277677
  function getModifiedTime3(path35) {
277291
277678
  var _a8;
277292
- return (_a8 = statSync18(path35)) == null ? undefined : _a8.mtime;
277679
+ return (_a8 = statSync19(path35)) == null ? undefined : _a8.mtime;
277293
277680
  }
277294
277681
  function setModifiedTime(path35, time3) {
277295
277682
  try {
@@ -437636,46 +438023,6 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
437636
438023
  } });
437637
438024
  });
437638
438025
 
437639
- // src/extensions/capabilities.ts
437640
- function cloneExtensionCapabilities(capabilities) {
437641
- return {
437642
- tools: capabilities.tools,
437643
- commands: capabilities.commands,
437644
- events: {
437645
- lifecycle: capabilities.events.lifecycle,
437646
- tools: capabilities.events.tools,
437647
- turns: capabilities.events.turns
437648
- },
437649
- providers: capabilities.providers,
437650
- ui: {
437651
- panels: capabilities.ui.panels,
437652
- statusValues: capabilities.ui.statusValues,
437653
- customStatuslineRenderer: capabilities.ui.customStatuslineRenderer
437654
- }
437655
- };
437656
- }
437657
- function resolveExtensionCapabilities(capabilities) {
437658
- return cloneExtensionCapabilities(capabilities ?? DEFAULT_EXTENSION_CAPABILITIES);
437659
- }
437660
- var DEFAULT_EXTENSION_CAPABILITIES;
437661
- var init_capabilities = __esm(() => {
437662
- DEFAULT_EXTENSION_CAPABILITIES = {
437663
- tools: true,
437664
- commands: true,
437665
- events: {
437666
- lifecycle: true,
437667
- tools: true,
437668
- turns: true
437669
- },
437670
- providers: true,
437671
- ui: {
437672
- panels: true,
437673
- statusValues: true,
437674
- customStatuslineRenderer: true
437675
- }
437676
- };
437677
- });
437678
-
437679
438026
  // src/extensions/conversation-handle.ts
437680
438027
  function createExtensionConversationHandle(options3) {
437681
438028
  const conversationId = options3.conversationId ?? "default";
@@ -437716,11 +438063,11 @@ function createExtensionConversationHandle(options3) {
437716
438063
  // src/extensions/extension-host.ts
437717
438064
  import { createHash as createHash5 } from "node:crypto";
437718
438065
  import {
437719
- existsSync as existsSync47,
438066
+ existsSync as existsSync48,
437720
438067
  mkdirSync as mkdirSync34,
437721
- readdirSync as readdirSync18,
437722
- readFileSync as readFileSync33,
437723
- statSync as statSync18,
438068
+ readdirSync as readdirSync19,
438069
+ readFileSync as readFileSync34,
438070
+ statSync as statSync19,
437724
438071
  symlinkSync,
437725
438072
  unlinkSync as unlinkSync11,
437726
438073
  writeFileSync as writeFileSync26
@@ -437730,9 +438077,9 @@ import { homedir as homedir28 } from "node:os";
437730
438077
  import path35 from "node:path";
437731
438078
  import { pathToFileURL as pathToFileURL3 } from "node:url";
437732
438079
  function listExtensionFiles(directory) {
437733
- if (!existsSync47(directory))
438080
+ if (!existsSync48(directory))
437734
438081
  return [];
437735
- return readdirSync18(directory, { withFileTypes: true }).filter((entry) => {
438082
+ return readdirSync19(directory, { withFileTypes: true }).filter((entry) => {
437736
438083
  if (!entry.isFile())
437737
438084
  return false;
437738
438085
  if (entry.name.startsWith("."))
@@ -437882,7 +438229,7 @@ function getRuntimePackageDirectory(packageName) {
437882
438229
  function ensureRuntimeDependencySymlink(cacheDirectory, packageName) {
437883
438230
  const nodeModulesDirectory = path35.join(cacheDirectory, "node_modules");
437884
438231
  const linkPath = path35.join(nodeModulesDirectory, packageName);
437885
- if (existsSync47(linkPath))
438232
+ if (existsSync48(linkPath))
437886
438233
  return;
437887
438234
  mkdirSync34(nodeModulesDirectory, { recursive: true });
437888
438235
  symlinkSync(getRuntimePackageDirectory(packageName), linkPath, process.platform === "win32" ? "junction" : "dir");
@@ -437926,17 +438273,17 @@ function prepareExtensionForImport(extensionPath, source2) {
437926
438273
  }
437927
438274
  function createImportableExtensionPath(extensionPath, cacheDirectory) {
437928
438275
  ensureExtensionCache(cacheDirectory);
437929
- const source2 = readFileSync33(extensionPath, "utf8");
438276
+ const source2 = readFileSync34(extensionPath, "utf8");
437930
438277
  const hash4 = createHash5("sha256").update(source2).digest("hex").slice(0, 16);
437931
438278
  const extension = path35.extname(extensionPath);
437932
438279
  const importableSource = prepareExtensionForImport(extensionPath, source2);
437933
438280
  const baseName = path35.basename(extensionPath, extension).replace(/[^a-zA-Z0-9_-]/g, "-");
437934
438281
  const importPath = path35.join(cacheDirectory, `.letta-extension-${baseName}-${hash4}.mjs`);
437935
- if (!existsSync47(importPath)) {
438282
+ if (!existsSync48(importPath)) {
437936
438283
  writeFileSync26(importPath, importableSource, "utf8");
437937
438284
  }
437938
438285
  try {
437939
- for (const entry of readdirSync18(cacheDirectory)) {
438286
+ for (const entry of readdirSync19(cacheDirectory)) {
437940
438287
  if (entry.startsWith(`.letta-extension-${baseName}-`) && entry !== path35.basename(importPath)) {
437941
438288
  unlinkSync11(path35.join(cacheDirectory, entry));
437942
438289
  }
@@ -438405,7 +438752,7 @@ async function loadLocalExtensions(options3) {
438405
438752
  registry2.ownerAbortControllers[owner.id] = abortController;
438406
438753
  registry2.owners[owner.id] = owner;
438407
438754
  try {
438408
- const mtimeMs = statSync18(extensionPath).mtimeMs;
438755
+ const mtimeMs = statSync19(extensionPath).mtimeMs;
438409
438756
  failurePhase = TYPESCRIPT_EXTENSION_FILE_EXTENSIONS.has(path35.extname(extensionPath)) ? "transpile" : "import";
438410
438757
  const importPath = createImportableExtensionPath(extensionPath, cacheDirectory);
438411
438758
  failurePhase = "import";
@@ -438670,6 +439017,96 @@ var init_extension_host = __esm(() => {
438670
439017
  });
438671
439018
 
438672
439019
  // src/extensions/extension-runtime.ts
439020
+ function createDisabledExtensionRegistry() {
439021
+ return {
439022
+ capabilities: cloneExtensionCapabilities(DISABLED_EXTENSION_CAPABILITIES),
439023
+ commands: {},
439024
+ diagnostics: [],
439025
+ disposers: [],
439026
+ errors: [],
439027
+ events: {},
439028
+ generation: 0,
439029
+ loadedPaths: [],
439030
+ ownerAbortControllers: {},
439031
+ owners: {},
439032
+ sources: [],
439033
+ tools: {},
439034
+ ui: {
439035
+ panels: {},
439036
+ statuslineRenderer: null,
439037
+ statusOwners: {},
439038
+ statusValues: {}
439039
+ }
439040
+ };
439041
+ }
439042
+ function createDisabledExtensionHost(registry2) {
439043
+ return {
439044
+ dispose() {},
439045
+ emitEvent(name) {
439046
+ return Promise.resolve(emptyEventEmissionResult(name));
439047
+ },
439048
+ getSnapshot() {
439049
+ return registry2;
439050
+ },
439051
+ reload() {
439052
+ return Promise.resolve();
439053
+ },
439054
+ subscribe() {
439055
+ return () => {
439056
+ return;
439057
+ };
439058
+ }
439059
+ };
439060
+ }
439061
+ function createDisabledExtensionRuntime(options3) {
439062
+ clearExtensionTools();
439063
+ clearRegisteredPiProviders();
439064
+ let context3 = options3.initialContext;
439065
+ const registry2 = createDisabledExtensionRegistry();
439066
+ const host = createDisabledExtensionHost(registry2);
439067
+ const snapshot = {
439068
+ hadStatuslineRenderer: false,
439069
+ hasExtensionSources: false,
439070
+ isLoading: false,
439071
+ registry: registry2
439072
+ };
439073
+ const eventEmitter = {
439074
+ emitEvent(name) {
439075
+ return Promise.resolve(emptyEventEmissionResult(name));
439076
+ },
439077
+ getSnapshot() {
439078
+ return snapshot;
439079
+ }
439080
+ };
439081
+ return {
439082
+ dispose() {},
439083
+ emitEvent(name) {
439084
+ return Promise.resolve(emptyEventEmissionResult(name));
439085
+ },
439086
+ eventEmitter,
439087
+ getBackendApi() {
439088
+ return;
439089
+ },
439090
+ getContext() {
439091
+ return context3;
439092
+ },
439093
+ getSnapshot() {
439094
+ return snapshot;
439095
+ },
439096
+ host,
439097
+ reload() {
439098
+ return Promise.resolve();
439099
+ },
439100
+ subscribe() {
439101
+ return () => {
439102
+ return;
439103
+ };
439104
+ },
439105
+ updateContext(nextContext) {
439106
+ context3 = nextContext;
439107
+ }
439108
+ };
439109
+ }
438673
439110
  function hasExtensionSources(options3) {
438674
439111
  return resolveLocalExtensionSources(options3).some((source2) => source2.files.length > 0);
438675
439112
  }
@@ -438694,6 +439131,12 @@ function createLazyRuntimeBackendApi(getBackendApi) {
438694
439131
  };
438695
439132
  }
438696
439133
  function createExtensionRuntime(options3) {
439134
+ if (options3.disabled) {
439135
+ disableExtensionsForProcess();
439136
+ }
439137
+ if (options3.disabled || areExtensionsDisabled()) {
439138
+ return createDisabledExtensionRuntime(options3);
439139
+ }
438697
439140
  const {
438698
439141
  getBackendApi: resolveBackendApi,
438699
439142
  initialContext,
@@ -438793,7 +439236,10 @@ function createExtensionRuntime(options3) {
438793
439236
  };
438794
439237
  }
438795
439238
  var init_extension_runtime = __esm(() => {
439239
+ init_pi_provider_extension_registry();
439240
+ init_capabilities();
438796
439241
  init_extension_host();
439242
+ init_tool_registry();
438797
439243
  init_debug();
438798
439244
  });
438799
439245
 
@@ -438885,6 +439331,7 @@ function createHeadlessExtensionRuntime(options3) {
438885
439331
  return createExtensionRuntime({
438886
439332
  ...options3.cacheDirectory ? { cacheDirectory: options3.cacheDirectory } : {},
438887
439333
  capabilities: HEADLESS_EXTENSION_CAPABILITIES,
439334
+ disabled: options3.disabled,
438888
439335
  getBackendApi: () => createHeadlessExtensionBackendApi(options3.backend),
438889
439336
  getClient,
438890
439337
  ...options3.globalExtensionsDirectory ? { globalExtensionsDirectory: options3.globalExtensionsDirectory } : {},
@@ -439122,7 +439569,7 @@ function parseRegistryHandle(handle2) {
439122
439569
  }
439123
439570
  async function importAgentFromRegistry(options3) {
439124
439571
  const { tmpdir: tmpdir7 } = await import("node:os");
439125
- const { join: join49 } = await import("node:path");
439572
+ const { join: join50 } = await import("node:path");
439126
439573
  const { writeFile: writeFile16, unlink: unlink4 } = await import("node:fs/promises");
439127
439574
  const { author, name } = parseRegistryHandle(options3.handle);
439128
439575
  const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
@@ -439134,7 +439581,7 @@ async function importAgentFromRegistry(options3) {
439134
439581
  throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
439135
439582
  }
439136
439583
  const afContent = await response.text();
439137
- const tempPath = join49(tmpdir7(), `letta-import-${author}-${name}-${Date.now()}.af`);
439584
+ const tempPath = join50(tmpdir7(), `letta-import-${author}-${name}-${Date.now()}.af`);
439138
439585
  await writeFile16(tempPath, afContent, "utf-8");
439139
439586
  try {
439140
439587
  const result = await importAgentFromFile({
@@ -439477,6 +439924,12 @@ async function writeFinalHeadlessStdout(text2) {
439477
439924
  async function handleHeadlessCommand(parsedArgs, model, skillsDirectoryOverride, skillSourcesOverride, systemInfoReminderEnabledOverride, startupOptions = {}) {
439478
439925
  const { values: values2, positionals } = parsedArgs;
439479
439926
  telemetry.setSurface(getTerminalTelemetrySurface(true));
439927
+ const extensionsDisabled = shouldDisableExtensions({
439928
+ cliFlag: values2["no-extensions"]
439929
+ });
439930
+ if (extensionsDisabled) {
439931
+ disableExtensionsForProcess();
439932
+ }
439480
439933
  if (values2.tools !== undefined) {
439481
439934
  const { toolFilter: toolFilter3 } = await Promise.resolve().then(() => (init_filter(), exports_filter));
439482
439935
  toolFilter3.setEnabledTools(values2.tools);
@@ -440156,7 +440609,8 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
440156
440609
  conversationId,
440157
440610
  permissionMode: headlessPermissionMode,
440158
440611
  reflectionSettings: effectiveReflectionSettings,
440159
- sessionStats
440612
+ sessionStats,
440613
+ disabled: extensionsDisabled
440160
440614
  });
440161
440615
  await headlessExtensionRuntime.reload();
440162
440616
  try {
@@ -442980,13 +443434,13 @@ __export(exports_terminal_keybinding_installer, {
442980
443434
  });
442981
443435
  import {
442982
443436
  copyFileSync as copyFileSync2,
442983
- existsSync as existsSync49,
443437
+ existsSync as existsSync50,
442984
443438
  mkdirSync as mkdirSync36,
442985
- readFileSync as readFileSync35,
443439
+ readFileSync as readFileSync36,
442986
443440
  writeFileSync as writeFileSync28
442987
443441
  } from "node:fs";
442988
443442
  import { homedir as homedir30, platform as platform6 } from "node:os";
442989
- import { dirname as dirname25, join as join50 } from "node:path";
443443
+ import { dirname as dirname25, join as join51 } from "node:path";
442990
443444
  function detectTerminalType() {
442991
443445
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
442992
443446
  return "cursor";
@@ -443018,16 +443472,16 @@ function getKeybindingsPath(terminal) {
443018
443472
  }[terminal];
443019
443473
  const os7 = platform6();
443020
443474
  if (os7 === "darwin") {
443021
- return join50(homedir30(), "Library", "Application Support", appName, "User", "keybindings.json");
443475
+ return join51(homedir30(), "Library", "Application Support", appName, "User", "keybindings.json");
443022
443476
  }
443023
443477
  if (os7 === "win32") {
443024
443478
  const appData = process.env.APPDATA;
443025
443479
  if (!appData)
443026
443480
  return null;
443027
- return join50(appData, appName, "User", "keybindings.json");
443481
+ return join51(appData, appName, "User", "keybindings.json");
443028
443482
  }
443029
443483
  if (os7 === "linux") {
443030
- return join50(homedir30(), ".config", appName, "User", "keybindings.json");
443484
+ return join51(homedir30(), ".config", appName, "User", "keybindings.json");
443031
443485
  }
443032
443486
  return null;
443033
443487
  }
@@ -443049,10 +443503,10 @@ function parseKeybindings(content) {
443049
443503
  }
443050
443504
  }
443051
443505
  function keybindingExists(keybindingsPath) {
443052
- if (!existsSync49(keybindingsPath))
443506
+ if (!existsSync50(keybindingsPath))
443053
443507
  return false;
443054
443508
  try {
443055
- const content = readFileSync35(keybindingsPath, { encoding: "utf-8" });
443509
+ const content = readFileSync36(keybindingsPath, { encoding: "utf-8" });
443056
443510
  const keybindings = parseKeybindings(content);
443057
443511
  if (!keybindings)
443058
443512
  return false;
@@ -443062,7 +443516,7 @@ function keybindingExists(keybindingsPath) {
443062
443516
  }
443063
443517
  }
443064
443518
  function createBackup(keybindingsPath) {
443065
- if (!existsSync49(keybindingsPath))
443519
+ if (!existsSync50(keybindingsPath))
443066
443520
  return null;
443067
443521
  const backupPath = `${keybindingsPath}.letta-backup`;
443068
443522
  try {
@@ -443078,14 +443532,14 @@ function installKeybinding(keybindingsPath) {
443078
443532
  return { success: true, alreadyExists: true };
443079
443533
  }
443080
443534
  const parentDir = dirname25(keybindingsPath);
443081
- if (!existsSync49(parentDir)) {
443535
+ if (!existsSync50(parentDir)) {
443082
443536
  mkdirSync36(parentDir, { recursive: true });
443083
443537
  }
443084
443538
  let keybindings = [];
443085
443539
  let backupPath = null;
443086
- if (existsSync49(keybindingsPath)) {
443540
+ if (existsSync50(keybindingsPath)) {
443087
443541
  backupPath = createBackup(keybindingsPath);
443088
- const content = readFileSync35(keybindingsPath, { encoding: "utf-8" });
443542
+ const content = readFileSync36(keybindingsPath, { encoding: "utf-8" });
443089
443543
  const parsed = parseKeybindings(content);
443090
443544
  if (parsed === null) {
443091
443545
  return {
@@ -443113,10 +443567,10 @@ function installKeybinding(keybindingsPath) {
443113
443567
  }
443114
443568
  function removeKeybinding(keybindingsPath) {
443115
443569
  try {
443116
- if (!existsSync49(keybindingsPath)) {
443570
+ if (!existsSync50(keybindingsPath)) {
443117
443571
  return { success: true };
443118
443572
  }
443119
- const content = readFileSync35(keybindingsPath, { encoding: "utf-8" });
443573
+ const content = readFileSync36(keybindingsPath, { encoding: "utf-8" });
443120
443574
  const keybindings = parseKeybindings(content);
443121
443575
  if (!keybindings) {
443122
443576
  return {
@@ -443180,14 +443634,14 @@ function getWezTermConfigPath() {
443180
443634
  }
443181
443635
  const xdgConfig = process.env.XDG_CONFIG_HOME;
443182
443636
  if (xdgConfig) {
443183
- const xdgPath = join50(xdgConfig, "wezterm", "wezterm.lua");
443184
- if (existsSync49(xdgPath))
443637
+ const xdgPath = join51(xdgConfig, "wezterm", "wezterm.lua");
443638
+ if (existsSync50(xdgPath))
443185
443639
  return xdgPath;
443186
443640
  }
443187
- const configPath = join50(homedir30(), ".config", "wezterm", "wezterm.lua");
443188
- if (existsSync49(configPath))
443641
+ const configPath = join51(homedir30(), ".config", "wezterm", "wezterm.lua");
443642
+ if (existsSync50(configPath))
443189
443643
  return configPath;
443190
- return join50(homedir30(), ".wezterm.lua");
443644
+ return join51(homedir30(), ".wezterm.lua");
443191
443645
  }
443192
443646
  function stripLuaCommentsFromLine(line, blockCommentEnd) {
443193
443647
  let code2 = "";
@@ -443290,10 +443744,10 @@ ${WEZTERM_DELETE_FIX}
443290
443744
  `;
443291
443745
  }
443292
443746
  function wezTermDeleteFixExists(configPath) {
443293
- if (!existsSync49(configPath))
443747
+ if (!existsSync50(configPath))
443294
443748
  return false;
443295
443749
  try {
443296
- const content = readFileSync35(configPath, { encoding: "utf-8" });
443750
+ const content = readFileSync36(configPath, { encoding: "utf-8" });
443297
443751
  return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
443298
443752
  } catch {
443299
443753
  return false;
@@ -443307,14 +443761,14 @@ function installWezTermDeleteFix() {
443307
443761
  }
443308
443762
  let content = "";
443309
443763
  let backupPath = null;
443310
- if (existsSync49(configPath)) {
443764
+ if (existsSync50(configPath)) {
443311
443765
  backupPath = `${configPath}.letta-backup`;
443312
443766
  copyFileSync2(configPath, backupPath);
443313
- content = readFileSync35(configPath, { encoding: "utf-8" });
443767
+ content = readFileSync36(configPath, { encoding: "utf-8" });
443314
443768
  }
443315
443769
  content = injectWezTermDeleteFix(content);
443316
443770
  const parentDir = dirname25(configPath);
443317
- if (!existsSync49(parentDir)) {
443771
+ if (!existsSync50(parentDir)) {
443318
443772
  mkdirSync36(parentDir, { recursive: true });
443319
443773
  }
443320
443774
  writeFileSync28(configPath, content, { encoding: "utf-8" });
@@ -443366,9 +443820,9 @@ __export(exports_settings2, {
443366
443820
  getSetting: () => getSetting
443367
443821
  });
443368
443822
  import { homedir as homedir31 } from "node:os";
443369
- import { join as join51 } from "node:path";
443823
+ import { join as join52 } from "node:path";
443370
443824
  function getSettingsPath() {
443371
- return join51(homedir31(), ".letta", "settings.json");
443825
+ return join52(homedir31(), ".letta", "settings.json");
443372
443826
  }
443373
443827
  async function loadSettings() {
443374
443828
  const settingsPath = getSettingsPath();
@@ -443405,7 +443859,7 @@ async function getSetting(key2) {
443405
443859
  return settings3[key2];
443406
443860
  }
443407
443861
  function getProjectSettingsPath() {
443408
- return join51(process.cwd(), ".letta", "settings.local.json");
443862
+ return join52(process.cwd(), ".letta", "settings.local.json");
443409
443863
  }
443410
443864
  async function loadProjectSettings() {
443411
443865
  const settingsPath = getProjectSettingsPath();
@@ -443423,7 +443877,7 @@ async function loadProjectSettings() {
443423
443877
  }
443424
443878
  async function saveProjectSettings(settings3) {
443425
443879
  const settingsPath = getProjectSettingsPath();
443426
- const dirPath = join51(process.cwd(), ".letta");
443880
+ const dirPath = join52(process.cwd(), ".letta");
443427
443881
  try {
443428
443882
  if (!exists(dirPath)) {
443429
443883
  await mkdir(dirPath, { recursive: true });
@@ -444126,8 +444580,9 @@ function createExtensionBackendApi(backend4) {
444126
444580
  }
444127
444581
  };
444128
444582
  }
444129
- function useLocalExtensionRuntime(initialContext) {
444583
+ function useLocalExtensionRuntime(initialContext, options3 = {}) {
444130
444584
  const runtime = import_react40.useMemo(() => createExtensionRuntime2({
444585
+ disabled: options3.disabled,
444131
444586
  getBackendApi: () => createExtensionBackendApi(getBackend()),
444132
444587
  getClient,
444133
444588
  initialContext
@@ -445736,35 +446191,89 @@ function padLeft(n, width) {
445736
446191
  const s3 = String(n);
445737
446192
  return s3.length >= width ? s3 : " ".repeat(width - s3.length) + s3;
445738
446193
  }
446194
+ function expandTabsForDiffDisplay(text2) {
446195
+ return text2.replaceAll("\t", " ".repeat(TAB_WIDTH2));
446196
+ }
446197
+ function exceedsAdvancedDiffHighlightLimits(hunks) {
446198
+ let totalBytes = 0;
446199
+ let totalLines = 0;
446200
+ for (const hunk of hunks) {
446201
+ for (const line of hunk.lines) {
446202
+ const raw2 = line.raw || "";
446203
+ if (raw2.charAt(0) === "\\")
446204
+ continue;
446205
+ totalBytes += Buffer.byteLength(raw2.slice(1), "utf8");
446206
+ totalLines += 1;
446207
+ if (totalBytes > HIGHLIGHT_MAX_BYTES || totalLines > HIGHLIGHT_MAX_LINES) {
446208
+ return true;
446209
+ }
446210
+ }
446211
+ }
446212
+ return false;
446213
+ }
446214
+ function takePrefixByDisplayWidth(text2, maxWidth) {
446215
+ if (maxWidth <= 0) {
446216
+ return { prefix: "", rest: text2, width: 0 };
446217
+ }
446218
+ let prefix = "";
446219
+ let width = 0;
446220
+ for (const char of text2) {
446221
+ const charWidth = stringWidth(char);
446222
+ if (width + charWidth > maxWidth) {
446223
+ break;
446224
+ }
446225
+ prefix += char;
446226
+ width += charWidth;
446227
+ }
446228
+ return { prefix, rest: text2.slice(prefix.length), width };
446229
+ }
446230
+ function takeFirstCharacter(text2) {
446231
+ const prefix = Array.from(text2)[0] ?? "";
446232
+ return {
446233
+ prefix,
446234
+ rest: text2.slice(prefix.length),
446235
+ width: stringWidth(prefix)
446236
+ };
446237
+ }
445739
446238
  function buildPaddedRows2(chunks, cols, contIndent) {
445740
446239
  if (cols <= 0)
445741
446240
  return [chunks];
445742
446241
  const rows = [];
445743
446242
  let row = [];
445744
- let len = 0;
446243
+ let width = 0;
445745
446244
  for (const chunk of chunks) {
445746
446245
  let rem = chunk.text;
445747
446246
  while (rem.length > 0) {
445748
- const space = cols - len;
445749
- if (rem.length <= space) {
446247
+ if (width >= cols) {
446248
+ rows.push(row);
446249
+ row = [{ text: " ".repeat(contIndent) }];
446250
+ width = contIndent;
446251
+ }
446252
+ const space = Math.max(1, cols - width);
446253
+ if (stringWidth(rem) <= space) {
445750
446254
  row.push({ text: rem, color: chunk.color, dimColor: chunk.dimColor });
445751
- len += rem.length;
446255
+ width += stringWidth(rem);
445752
446256
  rem = "";
445753
446257
  } else {
446258
+ let next = takePrefixByDisplayWidth(rem, space);
446259
+ if (!next.prefix) {
446260
+ next = takeFirstCharacter(rem);
446261
+ }
445754
446262
  row.push({
445755
- text: rem.slice(0, space),
446263
+ text: next.prefix,
445756
446264
  color: chunk.color,
445757
446265
  dimColor: chunk.dimColor
445758
446266
  });
446267
+ width += next.width;
446268
+ rem = next.rest;
445759
446269
  rows.push(row);
445760
446270
  row = [{ text: " ".repeat(contIndent) }];
445761
- len = contIndent;
445762
- rem = rem.slice(space);
446271
+ width = contIndent;
445763
446272
  }
445764
446273
  }
445765
446274
  }
445766
- if (len < cols)
445767
- row.push({ text: " ".repeat(cols - len) });
446275
+ if (width < cols)
446276
+ row.push({ text: " ".repeat(cols - width) });
445768
446277
  if (row.length > 0)
445769
446278
  rows.push(row);
445770
446279
  return rows;
@@ -445790,10 +446299,13 @@ function Line({
445790
446299
  chunks.push({ text: " " });
445791
446300
  if (syntaxSpans && syntaxSpans.length > 0) {
445792
446301
  for (const span2 of syntaxSpans) {
445793
- chunks.push({ text: span2.text, color: span2.color });
446302
+ chunks.push({
446303
+ text: expandTabsForDiffDisplay(span2.text),
446304
+ color: span2.color
446305
+ });
445794
446306
  }
445795
446307
  } else {
445796
- chunks.push({ text: text2 });
446308
+ chunks.push({ text: expandTabsForDiffDisplay(text2) });
445797
446309
  }
445798
446310
  const contIndent = indent.length + gutterStr.length + 1 + 1;
445799
446311
  const rows = buildPaddedRows2(chunks, columns, contIndent);
@@ -445809,6 +446321,67 @@ function Line({
445809
446321
  }, ri, false, undefined, this))
445810
446322
  }, undefined, false, undefined, this);
445811
446323
  }
446324
+ function buildAdvancedDiffRows(hunks, hunkSyntaxLines = []) {
446325
+ const rows = [];
446326
+ for (let hIdx = 0;hIdx < hunks.length; hIdx++) {
446327
+ const h3 = hunks[hIdx];
446328
+ if (!h3) {
446329
+ continue;
446330
+ }
446331
+ const syntaxForHunk = hunkSyntaxLines[hIdx] ?? [];
446332
+ let oldNo = h3.oldStart;
446333
+ let newNo = h3.newStart;
446334
+ let displayLineIdx = 0;
446335
+ for (let i4 = 0;i4 < h3.lines.length; i4++) {
446336
+ const line = h3.lines[i4];
446337
+ if (!line)
446338
+ continue;
446339
+ const raw2 = line.raw || "";
446340
+ const ch = raw2.charAt(0);
446341
+ const body3 = raw2.slice(1);
446342
+ if (ch === "\\")
446343
+ continue;
446344
+ const spans = syntaxForHunk[displayLineIdx];
446345
+ displayLineIdx++;
446346
+ if (ch === " ") {
446347
+ rows.push({
446348
+ kind: "context",
446349
+ displayNo: newNo,
446350
+ text: body3,
446351
+ syntaxSpans: spans
446352
+ });
446353
+ oldNo++;
446354
+ newNo++;
446355
+ } else if (ch === "-") {
446356
+ rows.push({
446357
+ kind: "remove",
446358
+ displayNo: oldNo,
446359
+ text: body3,
446360
+ syntaxSpans: spans
446361
+ });
446362
+ oldNo++;
446363
+ } else if (ch === "+") {
446364
+ rows.push({
446365
+ kind: "add",
446366
+ displayNo: newNo,
446367
+ text: body3,
446368
+ syntaxSpans: spans
446369
+ });
446370
+ newNo++;
446371
+ } else {
446372
+ rows.push({
446373
+ kind: "context",
446374
+ displayNo: newNo,
446375
+ text: raw2,
446376
+ syntaxSpans: spans
446377
+ });
446378
+ oldNo++;
446379
+ newNo++;
446380
+ }
446381
+ }
446382
+ }
446383
+ return rows;
446384
+ }
445812
446385
  function AdvancedDiffRenderer(props) {
445813
446386
  const columns = useTerminalWidth();
445814
446387
  const result = import_react46.useMemo(() => {
@@ -445895,6 +446468,7 @@ function AdvancedDiffRenderer(props) {
445895
446468
  const filePath = props.filePath;
445896
446469
  const relative13 = formatRelativePath(filePath);
445897
446470
  const lang41 = languageFromPath(filePath);
446471
+ const shouldHighlight = lang41 && !exceedsAdvancedDiffHighlightLimits(hunks);
445898
446472
  const hunkSyntaxLines = [];
445899
446473
  for (const h3 of hunks) {
445900
446474
  const textLines = [];
@@ -445908,68 +446482,11 @@ function AdvancedDiffRenderer(props) {
445908
446482
  }
445909
446483
  const block = textLines.join(`
445910
446484
  `);
445911
- const highlighted = lang41 ? highlightCode(block, lang41) : undefined;
445912
- hunkSyntaxLines.push(textLines.map((_3, i4) => highlighted?.[i4]));
445913
- }
445914
- const rows = [];
445915
- for (let hIdx = 0;hIdx < hunks.length; hIdx++) {
445916
- const h3 = hunks[hIdx];
445917
- if (!h3) {
445918
- continue;
445919
- }
445920
- const syntaxForHunk = hunkSyntaxLines[hIdx] ?? [];
445921
- let oldNo = h3.oldStart;
445922
- let newNo = h3.newStart;
445923
- let lastRemovalNo = null;
445924
- let displayLineIdx = 0;
445925
- for (let i4 = 0;i4 < h3.lines.length; i4++) {
445926
- const line = h3.lines[i4];
445927
- if (!line)
445928
- continue;
445929
- const raw2 = line.raw || "";
445930
- const ch = raw2.charAt(0);
445931
- const body3 = raw2.slice(1);
445932
- if (ch === "\\")
445933
- continue;
445934
- const spans = syntaxForHunk[displayLineIdx];
445935
- displayLineIdx++;
445936
- if (ch === " ") {
445937
- rows.push({
445938
- kind: "context",
445939
- displayNo: oldNo,
445940
- text: body3,
445941
- syntaxSpans: spans
445942
- });
445943
- oldNo++;
445944
- newNo++;
445945
- lastRemovalNo = null;
445946
- } else if (ch === "-") {
445947
- rows.push({
445948
- kind: "remove",
445949
- displayNo: oldNo,
445950
- text: body3,
445951
- syntaxSpans: spans
445952
- });
445953
- lastRemovalNo = oldNo;
445954
- oldNo++;
445955
- } else if (ch === "+") {
445956
- const displayNo = lastRemovalNo !== null ? lastRemovalNo : newNo;
445957
- rows.push({ kind: "add", displayNo, text: body3, syntaxSpans: spans });
445958
- newNo++;
445959
- lastRemovalNo = null;
445960
- } else {
445961
- rows.push({
445962
- kind: "context",
445963
- displayNo: oldNo,
445964
- text: raw2,
445965
- syntaxSpans: spans
445966
- });
445967
- oldNo++;
445968
- newNo++;
445969
- lastRemovalNo = null;
445970
- }
445971
- }
446485
+ const highlighted = shouldHighlight ? highlightCode(block, lang41) : undefined;
446486
+ const syntaxLines = highlighted?.length === textLines.length ? highlighted : undefined;
446487
+ hunkSyntaxLines.push(textLines.map((_3, i4) => syntaxLines?.[i4]));
445972
446488
  }
446489
+ const rows = buildAdvancedDiffRows(hunks, hunkSyntaxLines);
445973
446490
  const maxDisplayNo = rows.reduce((m4, r5) => Math.max(m4, r5.displayNo), 1);
445974
446491
  const gutterWidth = String(maxDisplayNo).length;
445975
446492
  const header = props.kind === "write" ? `Wrote changes to ${relative13}` : `Updated ${relative13}`;
@@ -446100,8 +446617,9 @@ function AdvancedDiffRenderer(props) {
446100
446617
  ]
446101
446618
  }, undefined, true, undefined, this);
446102
446619
  }
446103
- var import_react46, jsx_dev_runtime22;
446620
+ var import_react46, jsx_dev_runtime22, TAB_WIDTH2 = 4, HIGHLIGHT_MAX_BYTES, HIGHLIGHT_MAX_LINES = 1e4;
446104
446621
  var init_AdvancedDiffRenderer = __esm(async () => {
446622
+ init_string_width();
446105
446623
  init_diff4();
446106
446624
  init_glyphs();
446107
446625
  init_use_terminal_width();
@@ -446114,6 +446632,7 @@ var init_AdvancedDiffRenderer = __esm(async () => {
446114
446632
  ]);
446115
446633
  import_react46 = __toESM(require_react(), 1);
446116
446634
  jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
446635
+ HIGHLIGHT_MAX_BYTES = 512 * 1024;
446117
446636
  });
446118
446637
 
446119
446638
  // src/cli/components/InlineFileEditApproval.tsx
@@ -446148,9 +446667,9 @@ function getHeaderText(fileEdit) {
446148
446667
  const relPath = relative13(cwd2, fileEdit.filePath);
446149
446668
  const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
446150
446669
  if (t2 === "write" || t2 === "write_file" || t2 === "writefile" || t2 === "write_file_gemini" || t2 === "writefilegemini") {
446151
- const { existsSync: existsSync50 } = __require("node:fs");
446670
+ const { existsSync: existsSync51 } = __require("node:fs");
446152
446671
  try {
446153
- if (existsSync50(fileEdit.filePath)) {
446672
+ if (existsSync51(fileEdit.filePath)) {
446154
446673
  return `Overwrite ${displayPath}?`;
446155
446674
  }
446156
446675
  } catch {}
@@ -450270,9 +450789,9 @@ __export(exports_custom, {
450270
450789
  GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
450271
450790
  COMMANDS_DIR: () => COMMANDS_DIR
450272
450791
  });
450273
- import { existsSync as existsSync50 } from "node:fs";
450792
+ import { existsSync as existsSync51 } from "node:fs";
450274
450793
  import { readdir as readdir12, readFile as readFile16 } from "node:fs/promises";
450275
- import { basename as basename20, dirname as dirname26, join as join52 } from "node:path";
450794
+ import { basename as basename20, dirname as dirname26, join as join53 } from "node:path";
450276
450795
  async function getCustomCommands() {
450277
450796
  if (cachedCommands !== null) {
450278
450797
  return cachedCommands;
@@ -450283,7 +450802,7 @@ async function getCustomCommands() {
450283
450802
  function refreshCustomCommands() {
450284
450803
  cachedCommands = null;
450285
450804
  }
450286
- async function discoverCustomCommands(projectPath = join52(process.cwd(), COMMANDS_DIR)) {
450805
+ async function discoverCustomCommands(projectPath = join53(process.cwd(), COMMANDS_DIR)) {
450287
450806
  const commandsById = new Map;
450288
450807
  const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
450289
450808
  for (const cmd of userCommands) {
@@ -450304,7 +450823,7 @@ async function discoverCustomCommands(projectPath = join52(process.cwd(), COMMAN
450304
450823
  return result;
450305
450824
  }
450306
450825
  async function discoverFromDirectory(dirPath, source2) {
450307
- if (!existsSync50(dirPath)) {
450826
+ if (!existsSync51(dirPath)) {
450308
450827
  return [];
450309
450828
  }
450310
450829
  const commands2 = [];
@@ -450315,7 +450834,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source2) {
450315
450834
  try {
450316
450835
  const entries = await readdir12(currentPath, { withFileTypes: true });
450317
450836
  for (const entry of entries) {
450318
- const fullPath = join52(currentPath, entry.name);
450837
+ const fullPath = join53(currentPath, entry.name);
450319
450838
  if (entry.isDirectory()) {
450320
450839
  await findCommandFiles(fullPath, rootPath, commands2, source2);
450321
450840
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -450400,7 +450919,7 @@ async function findCustomCommand(commandName) {
450400
450919
  }
450401
450920
  var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
450402
450921
  var init_custom = __esm(() => {
450403
- GLOBAL_COMMANDS_DIR = join52(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
450922
+ GLOBAL_COMMANDS_DIR = join53(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
450404
450923
  });
450405
450924
 
450406
450925
  // src/cli/components/HelpDialog.tsx
@@ -453453,22 +453972,22 @@ var init_AgentInfoBar = __esm(async () => {
453453
453972
  });
453454
453973
 
453455
453974
  // src/cli/helpers/file-search.ts
453456
- import { readdirSync as readdirSync19, statSync as statSync19 } from "node:fs";
453457
- import { join as join53, relative as relative13, resolve as resolve36 } from "node:path";
453975
+ import { readdirSync as readdirSync20, statSync as statSync20 } from "node:fs";
453976
+ import { join as join54, relative as relative13, resolve as resolve36 } from "node:path";
453458
453977
  function searchDirectoryRecursive(dir, pattern4, maxResults = 200, results = [], depth = 0, maxDepth = 10, lowerPattern = pattern4.toLowerCase()) {
453459
453978
  if (results.length >= maxResults || depth >= maxDepth) {
453460
453979
  return results;
453461
453980
  }
453462
453981
  try {
453463
- const entries = readdirSync19(dir);
453982
+ const entries = readdirSync20(dir);
453464
453983
  for (const entry of entries) {
453465
453984
  try {
453466
- const fullPath = join53(dir, entry);
453985
+ const fullPath = join54(dir, entry);
453467
453986
  const relativePath = relative13(getIndexRoot(), fullPath);
453468
453987
  if (shouldHardExcludeEntry(entry, getIndexRoot())) {
453469
453988
  continue;
453470
453989
  }
453471
- const stats = statSync19(fullPath);
453990
+ const stats = statSync20(fullPath);
453472
453991
  const matches2 = pattern4.length === 0 || relativePath.toLowerCase().includes(lowerPattern);
453473
453992
  if (matches2) {
453474
453993
  results.push({
@@ -453499,7 +454018,7 @@ async function searchFiles(query2, deep = false) {
453499
454018
  try {
453500
454019
  const resolvedDir = resolve36(getIndexRoot(), dirPart);
453501
454020
  try {
453502
- statSync19(resolvedDir);
454021
+ statSync20(resolvedDir);
453503
454022
  searchDir = resolvedDir;
453504
454023
  searchPattern = pattern4;
453505
454024
  } catch {}
@@ -453533,7 +454052,7 @@ async function searchFiles(query2, deep = false) {
453533
454052
  } else {
453534
454053
  let entries = [];
453535
454054
  try {
453536
- entries = readdirSync19(searchDir);
454055
+ entries = readdirSync20(searchDir);
453537
454056
  } catch {
453538
454057
  return [];
453539
454058
  }
@@ -453541,8 +454060,8 @@ async function searchFiles(query2, deep = false) {
453541
454060
  const matchingEntries = entries.filter((entry) => !shouldHardExcludeEntry(entry, getIndexRoot()) && (searchPattern.length === 0 || entry.toLowerCase().includes(lowerPattern)));
453542
454061
  for (const entry of matchingEntries.slice(0, 50)) {
453543
454062
  try {
453544
- const fullPath = join53(searchDir, entry);
453545
- const stats = statSync19(fullPath);
454063
+ const fullPath = join54(searchDir, entry);
454064
+ const stats = statSync20(fullPath);
453546
454065
  const relativePath = relative13(getIndexRoot(), fullPath);
453547
454066
  results.push({
453548
454067
  path: relativePath,
@@ -454300,6 +454819,7 @@ function renderDreamingStatus(agent2) {
454300
454819
  const elapsedS = Math.round((Date.now() - agent2.startTime) / 1000);
454301
454820
  const typeLabel = typeLabelForBackgroundAgent(agent2);
454302
454821
  const chatUrl = chatUrlForBackgroundAgent(agent2);
454822
+ const isTmux = Boolean(process.env.TMUX);
454303
454823
  return /* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
454304
454824
  children: [
454305
454825
  /* @__PURE__ */ jsx_dev_runtime57.jsxDEV(BlinkingSpinner, {
@@ -454308,7 +454828,21 @@ function renderDreamingStatus(agent2) {
454308
454828
  marginRight: 0,
454309
454829
  pulseIntervalMs: 400
454310
454830
  }, undefined, false, undefined, this),
454311
- chatUrl ? /* @__PURE__ */ jsx_dev_runtime57.jsxDEV(dist_default5, {
454831
+ chatUrl && isTmux ? /* @__PURE__ */ jsx_dev_runtime57.jsxDEV(jsx_dev_runtime57.Fragment, {
454832
+ children: [
454833
+ /* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
454834
+ color: colors.bgSubagent.label,
454835
+ children: typeLabel
454836
+ }, undefined, false, undefined, this),
454837
+ /* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
454838
+ dimColor: true,
454839
+ children: [
454840
+ ": ",
454841
+ chatUrl
454842
+ ]
454843
+ }, undefined, true, undefined, this)
454844
+ ]
454845
+ }, undefined, true, undefined, this) : chatUrl ? /* @__PURE__ */ jsx_dev_runtime57.jsxDEV(dist_default5, {
454312
454846
  url: chatUrl,
454313
454847
  fallback: false,
454314
454848
  children: /* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
@@ -456541,15 +457075,15 @@ var init_agents7 = __esm(() => {
456541
457075
  // src/cli/commands/install-github-app.ts
456542
457076
  import { execFileSync as execFileSync5 } from "node:child_process";
456543
457077
  import {
456544
- existsSync as existsSync51,
457078
+ existsSync as existsSync52,
456545
457079
  mkdirSync as mkdirSync37,
456546
457080
  mkdtempSync as mkdtempSync2,
456547
- readFileSync as readFileSync36,
457081
+ readFileSync as readFileSync37,
456548
457082
  rmSync as rmSync8,
456549
457083
  writeFileSync as writeFileSync29
456550
457084
  } from "node:fs";
456551
457085
  import { tmpdir as tmpdir7 } from "node:os";
456552
- import { dirname as dirname27, join as join54 } from "node:path";
457086
+ import { dirname as dirname27, join as join55 } from "node:path";
456553
457087
  function runCommand(command, args, cwd2, input) {
456554
457088
  try {
456555
457089
  return execFileSync5(command, args, {
@@ -456770,8 +457304,8 @@ async function createLettaAgent(apiKey, name) {
456770
457304
  return createMinimalAgent(apiKey, name);
456771
457305
  }
456772
457306
  function cloneRepoToTemp(repo) {
456773
- const tempDir = mkdtempSync2(join54(tmpdir7(), "letta-install-github-app-"));
456774
- const repoDir = join54(tempDir, "repo");
457307
+ const tempDir = mkdtempSync2(join55(tmpdir7(), "letta-install-github-app-"));
457308
+ const repoDir = join55(tempDir, "repo");
456775
457309
  runCommand("gh", ["repo", "clone", repo, repoDir, "--", "--depth=1"]);
456776
457310
  return { tempDir, repoDir };
456777
457311
  }
@@ -456782,14 +457316,14 @@ function runGit4(args, cwd2) {
456782
457316
  return runCommand("git", args, cwd2);
456783
457317
  }
456784
457318
  function writeWorkflow(repoDir, workflowPath, content) {
456785
- const absolutePath = join54(repoDir, workflowPath);
456786
- if (!existsSync51(dirname27(absolutePath))) {
457319
+ const absolutePath = join55(repoDir, workflowPath);
457320
+ if (!existsSync52(dirname27(absolutePath))) {
456787
457321
  mkdirSync37(dirname27(absolutePath), { recursive: true });
456788
457322
  }
456789
457323
  const next = `${content.trimEnd()}
456790
457324
  `;
456791
- if (existsSync51(absolutePath)) {
456792
- const previous = readFileSync36(absolutePath, "utf8");
457325
+ if (existsSync52(absolutePath)) {
457326
+ const previous = readFileSync37(absolutePath, "utf8");
456793
457327
  if (previous === next) {
456794
457328
  return false;
456795
457329
  }
@@ -461193,9 +461727,9 @@ __export(exports_generate_memory_viewer, {
461193
461727
  generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
461194
461728
  });
461195
461729
  import { execFile as execFileCb4 } from "node:child_process";
461196
- import { chmodSync as chmodSync4, existsSync as existsSync52, mkdirSync as mkdirSync38, writeFileSync as writeFileSync30 } from "node:fs";
461730
+ import { chmodSync as chmodSync4, existsSync as existsSync53, mkdirSync as mkdirSync38, writeFileSync as writeFileSync30 } from "node:fs";
461197
461731
  import { homedir as homedir33 } from "node:os";
461198
- import { join as join55 } from "node:path";
461732
+ import { join as join56 } from "node:path";
461199
461733
  import { promisify as promisify15 } from "node:util";
461200
461734
  function messagesFromOverview(overview) {
461201
461735
  return overview.messages?.map((message) => ({
@@ -461504,7 +462038,7 @@ ${m4.body}` : m4.subject;
461504
462038
  async function generateAndOpenMemoryViewer(agentId, options3) {
461505
462039
  const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
461506
462040
  const repoDir = memoryRoot;
461507
- if (!existsSync52(join55(repoDir, ".git"))) {
462041
+ if (!existsSync53(join56(repoDir, ".git"))) {
461508
462042
  throw new Error("Memory viewer requires memfs. Run /memfs enable first.");
461509
462043
  }
461510
462044
  const data = await collectMemoryData(agentId, repoDir, memoryRoot, options3?.conversationId);
@@ -461514,13 +462048,13 @@ async function generateAndOpenMemoryViewer(agentId, options3) {
461514
462048
  data.context = applyContextUsageSnapshot(data.context, options3?.contextUsage);
461515
462049
  const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
461516
462050
  const html5 = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
461517
- if (!existsSync52(VIEWERS_DIR)) {
462051
+ if (!existsSync53(VIEWERS_DIR)) {
461518
462052
  mkdirSync38(VIEWERS_DIR, { recursive: true, mode: 448 });
461519
462053
  }
461520
462054
  try {
461521
462055
  chmodSync4(VIEWERS_DIR, 448);
461522
462056
  } catch {}
461523
- const filePath = join55(VIEWERS_DIR, `memory-${encodeURIComponent(agentId)}.html`);
462057
+ const filePath = join56(VIEWERS_DIR, `memory-${encodeURIComponent(agentId)}.html`);
461524
462058
  writeFileSync30(filePath, html5);
461525
462059
  chmodSync4(filePath, 384);
461526
462060
  const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
@@ -461545,13 +462079,13 @@ var init_generate_memory_viewer = __esm(() => {
461545
462079
  init_local_memory_context();
461546
462080
  init_memory_viewer_template();
461547
462081
  execFile17 = promisify15(execFileCb4);
461548
- VIEWERS_DIR = join55(homedir33(), ".letta", "viewers");
462082
+ VIEWERS_DIR = join56(homedir33(), ".letta", "viewers");
461549
462083
  REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
461550
462084
  });
461551
462085
 
461552
462086
  // src/cli/components/MemfsTreeViewer.tsx
461553
- import { existsSync as existsSync53 } from "node:fs";
461554
- import { join as join56 } from "node:path";
462087
+ import { existsSync as existsSync54 } from "node:fs";
462088
+ import { join as join57 } from "node:path";
461555
462089
  function renderTreePrefix(node) {
461556
462090
  let prefix = "";
461557
462091
  for (let i4 = 0;i4 < node.depth; i4++) {
@@ -461579,8 +462113,8 @@ function MemfsTreeViewer({
461579
462113
  const [status, setStatus] = import_react90.useState(null);
461580
462114
  const statusTimerRef = import_react90.useRef(null);
461581
462115
  const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
461582
- const memoryExists = existsSync53(memoryRoot);
461583
- const hasGitRepo = import_react90.useMemo(() => existsSync53(join56(memoryRoot, ".git")), [memoryRoot]);
462116
+ const memoryExists = existsSync54(memoryRoot);
462117
+ const hasGitRepo = import_react90.useMemo(() => existsSync54(join57(memoryRoot, ".git")), [memoryRoot]);
461584
462118
  function showStatus(msg, durationMs) {
461585
462119
  if (statusTimerRef.current)
461586
462120
  clearTimeout(statusTimerRef.current);
@@ -462388,7 +462922,7 @@ function isSearchRangeAvailable(range3, options3) {
462388
462922
  function buildSearchTargetPlan(mode, range3, options3) {
462389
462923
  const availableRanges = SEARCH_RANGES.filter((candidateRange) => isSearchRangeAvailable(candidateRange, options3));
462390
462924
  const prefetch = [
462391
- ...SEARCH_MODES.filter((candidateMode) => candidateMode !== mode).map((candidateMode) => ({ mode: candidateMode, range: range3 })),
462925
+ ...options3.textOnlyModes ? [] : SEARCH_MODES.filter((candidateMode) => candidateMode !== mode).map((candidateMode) => ({ mode: candidateMode, range: range3 })),
462392
462926
  ...availableRanges.filter((candidateRange) => candidateRange !== range3).map((candidateRange) => ({ mode, range: candidateRange }))
462393
462927
  ];
462394
462928
  return {
@@ -462396,6 +462930,22 @@ function buildSearchTargetPlan(mode, range3, options3) {
462396
462930
  prefetch
462397
462931
  };
462398
462932
  }
462933
+ function buildMessageSearchRequestBody(query2, mode, range3, options3) {
462934
+ const body3 = {
462935
+ query: query2.trim(),
462936
+ search_mode: mode,
462937
+ limit: options3.limit ?? SEARCH_LIMIT
462938
+ };
462939
+ if (range3 === "agent" && options3.agentId) {
462940
+ body3.agent_id = options3.agentId;
462941
+ } else if (range3 === "conv" && options3.conversationId) {
462942
+ body3.conversation_id = options3.conversationId;
462943
+ if (options3.agentId) {
462944
+ body3.agent_id = options3.agentId;
462945
+ }
462946
+ }
462947
+ return body3;
462948
+ }
462399
462949
  function formatLocalTime(dateStr) {
462400
462950
  if (!dateStr)
462401
462951
  return "";
@@ -462414,6 +462964,17 @@ function formatLocalTime(dateStr) {
462414
462964
  function escapeRegExp4(text2) {
462415
462965
  return text2.replace(/[.*+?^${}()|[\]\\]/g, (match4) => `\\${match4}`);
462416
462966
  }
462967
+ function stringifyMessageValue(value) {
462968
+ if (typeof value === "string")
462969
+ return value;
462970
+ if (value === null || value === undefined)
462971
+ return "";
462972
+ try {
462973
+ return JSON.stringify(value);
462974
+ } catch {
462975
+ return String(value);
462976
+ }
462977
+ }
462417
462978
  function getMessageText(msg) {
462418
462979
  if ("content" in msg) {
462419
462980
  const content = msg.content;
@@ -462438,8 +462999,8 @@ function getMessageText(msg) {
462438
462999
  }
462439
463000
  if ("tool_return" in msg) {
462440
463001
  const toolName = "name" in msg ? msg.name : "tool";
462441
- const returnValue = msg.tool_return;
462442
- const preview2 = returnValue?.slice(0, 100) || "";
463002
+ const returnValue = stringifyMessageValue(msg.tool_return);
463003
+ const preview2 = returnValue.slice(0, 100);
462443
463004
  return `${toolName}: ${preview2}`;
462444
463005
  }
462445
463006
  return `[${msg.message_type || "unknown"}]`;
@@ -462489,6 +463050,7 @@ function MessageSearch({
462489
463050
  const [error54, setError] = import_react92.useState(null);
462490
463051
  const [selectedIndex, setSelectedIndex] = import_react92.useState(0);
462491
463052
  const [expandedMessage, setExpandedMessage] = import_react92.useState(null);
463053
+ const textOnlyModes = getBackend().capabilities.localModelCatalog;
462492
463054
  const searchRequestIdRef = import_react92.useRef(0);
462493
463055
  const resultsCache = import_react92.useRef(new Map);
462494
463056
  const pendingResultsCache = import_react92.useRef(new Map);
@@ -462496,20 +463058,16 @@ function MessageSearch({
462496
463058
  warmMessageSearchCache().catch(() => {});
462497
463059
  }, []);
462498
463060
  const getCacheKey = import_react92.useCallback((query2, mode, range3) => {
463061
+ const modeKey = textOnlyModes ? "text" : mode;
462499
463062
  const rangeKey = range3 === "agent" ? agentId || "no-agent" : range3 === "conv" ? conversationId || "no-conv" : "all";
462500
- return `${query2.trim()}-${mode}-${rangeKey}`;
462501
- }, [agentId, conversationId]);
463063
+ return `${query2.trim()}-${modeKey}-${rangeKey}`;
463064
+ }, [agentId, conversationId, textOnlyModes]);
462502
463065
  const fetchSearchResults = import_react92.useCallback(async (query2, mode, range3) => {
462503
- const body3 = {
462504
- query: query2.trim(),
462505
- search_mode: mode,
463066
+ const body3 = buildMessageSearchRequestBody(query2, mode, range3, {
463067
+ agentId,
463068
+ conversationId,
462506
463069
  limit: SEARCH_LIMIT
462507
- };
462508
- if (range3 === "agent" && agentId) {
462509
- body3.agent_id = agentId;
462510
- } else if (range3 === "conv" && conversationId) {
462511
- body3.conversation_id = conversationId;
462512
- }
463070
+ });
462513
463071
  return searchMessagesForBackend(body3);
462514
463072
  }, [agentId, conversationId]);
462515
463073
  const fetchAndCacheSearchResults = import_react92.useCallback(async (query2, mode, range3) => {
@@ -462539,7 +463097,8 @@ function MessageSearch({
462539
463097
  const prefetchSearchResults = import_react92.useCallback((query2, mode, range3) => {
462540
463098
  const { prefetch } = buildSearchTargetPlan(mode, range3, {
462541
463099
  agentId,
462542
- conversationId
463100
+ conversationId,
463101
+ textOnlyModes
462543
463102
  });
462544
463103
  if (prefetch.length === 0) {
462545
463104
  return;
@@ -462549,7 +463108,7 @@ function MessageSearch({
462549
463108
  await Promise.all(prefetch.map(({ mode: prefetchMode, range: prefetchRange }) => fetchAndCacheSearchResults(query2, prefetchMode, prefetchRange).catch(() => [])));
462550
463109
  } catch {}
462551
463110
  })();
462552
- }, [agentId, conversationId, fetchAndCacheSearchResults]);
463111
+ }, [agentId, conversationId, fetchAndCacheSearchResults, textOnlyModes]);
462553
463112
  const executeSearch = import_react92.useCallback(async (query2, mode, range3) => {
462554
463113
  if (!query2.trim())
462555
463114
  return;
@@ -462983,6 +463542,7 @@ function MessageSearch({
462983
463542
  }
462984
463543
  var import_react92, jsx_dev_runtime67, SOLID_LINE17 = "─", VISIBLE_ITEMS = 5, SEARCH_LIMIT = 100, SEARCH_MODES, SEARCH_RANGES;
462985
463544
  var init_MessageSearch = __esm(async () => {
463545
+ init_backend2();
462986
463546
  init_message_search();
462987
463547
  init_truncate_text();
462988
463548
  init_use_terminal_width();
@@ -463842,10 +464402,10 @@ var init_PersonalitySelector = __esm(async () => {
463842
464402
  // src/utils/aws-credentials.ts
463843
464403
  import { readFile as readFile17 } from "node:fs/promises";
463844
464404
  import { homedir as homedir34 } from "node:os";
463845
- import { join as join57 } from "node:path";
464405
+ import { join as join58 } from "node:path";
463846
464406
  async function parseAwsCredentials() {
463847
- const credentialsPath = join57(homedir34(), ".aws", "credentials");
463848
- const configPath = join57(homedir34(), ".aws", "config");
464407
+ const credentialsPath = join58(homedir34(), ".aws", "credentials");
464408
+ const configPath = join58(homedir34(), ".aws", "config");
463849
464409
  const profiles = new Map;
463850
464410
  try {
463851
464411
  const content = await readFile17(credentialsPath, "utf-8");
@@ -465105,8 +465665,8 @@ function SkillsDialog({ onClose, agentId }) {
465105
465665
  try {
465106
465666
  const { discoverSkills: discoverSkills3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
465107
465667
  const { getSkillsDirectory: getSkillsDirectory2, getSkillSources: getSkillSources2 } = await Promise.resolve().then(() => (init_context(), exports_context));
465108
- const { join: join58 } = await import("node:path");
465109
- const skillsDir = getSkillsDirectory2() || join58(process.cwd(), SKILLS_DIR3);
465668
+ const { join: join59 } = await import("node:path");
465669
+ const skillsDir = getSkillsDirectory2() || join59(process.cwd(), SKILLS_DIR3);
465110
465670
  const result = await discoverSkills3(skillsDir, agentId, {
465111
465671
  sources: getSkillSources2()
465112
465672
  });
@@ -469036,9 +469596,9 @@ function getFileEditHeader(toolName, toolArgs) {
469036
469596
  const relPath = relative14(cwd2, filePath);
469037
469597
  const displayPath2 = relPath.startsWith("..") ? filePath : relPath;
469038
469598
  if (t2 === "write" || t2 === "write_file" || t2 === "writefile" || t2 === "write_file_gemini" || t2 === "writefilegemini") {
469039
- const { existsSync: existsSync54 } = __require("node:fs");
469599
+ const { existsSync: existsSync55 } = __require("node:fs");
469040
469600
  try {
469041
- if (existsSync54(filePath)) {
469601
+ if (existsSync55(filePath)) {
469042
469602
  return `Overwrite ${displayPath2}?`;
469043
469603
  }
469044
469604
  } catch {}
@@ -484461,9 +485021,9 @@ __export(exports_generate_diff_viewer, {
484461
485021
  generateAndOpenDiffViewer: () => generateAndOpenDiffViewer
484462
485022
  });
484463
485023
  import { execFile as execFileCb5 } from "node:child_process";
484464
- import { chmodSync as chmodSync5, existsSync as existsSync54, mkdirSync as mkdirSync39, writeFileSync as writeFileSync31 } from "node:fs";
485024
+ import { chmodSync as chmodSync5, existsSync as existsSync55, mkdirSync as mkdirSync39, writeFileSync as writeFileSync31 } from "node:fs";
484465
485025
  import { homedir as homedir35 } from "node:os";
484466
- import { isAbsolute as isAbsolute19, join as join58, resolve as resolve37 } from "node:path";
485026
+ import { isAbsolute as isAbsolute19, join as join59, resolve as resolve37 } from "node:path";
484467
485027
  import { promisify as promisify16 } from "node:util";
484468
485028
  async function runGit5(cwd2, args) {
484469
485029
  try {
@@ -484682,13 +485242,13 @@ async function generateAndOpenDiffViewer(targetPath) {
484682
485242
  };
484683
485243
  const jsonPayload = JSON.stringify(payload).replace(/</g, "\\u003c");
484684
485244
  const html5 = diff_viewer_template_default.replace("<!--LETTA_DIFF_DATA_PLACEHOLDER-->", () => jsonPayload);
484685
- if (!existsSync54(VIEWERS_DIR2)) {
485245
+ if (!existsSync55(VIEWERS_DIR2)) {
484686
485246
  mkdirSync39(VIEWERS_DIR2, { recursive: true, mode: 448 });
484687
485247
  }
484688
485248
  try {
484689
485249
  chmodSync5(VIEWERS_DIR2, 448);
484690
485250
  } catch {}
484691
- const filePath = join58(VIEWERS_DIR2, `diff-${encodeURIComponent(worktreePath)}.html`);
485251
+ const filePath = join59(VIEWERS_DIR2, `diff-${encodeURIComponent(worktreePath)}.html`);
484692
485252
  writeFileSync31(filePath, html5);
484693
485253
  chmodSync5(filePath, 384);
484694
485254
  const skipOpen = shouldSkipOpen();
@@ -484759,7 +485319,7 @@ var init_generate_diff_viewer = __esm(() => {
484759
485319
  init_ssr();
484760
485320
  init_diff_viewer_template();
484761
485321
  execFile18 = promisify16(execFileCb5);
484762
- VIEWERS_DIR2 = join58(homedir35(), ".letta", "viewers");
485322
+ VIEWERS_DIR2 = join59(homedir35(), ".letta", "viewers");
484763
485323
  GIT_MAX_BUFFER = 50 * 1024 * 1024;
484764
485324
  });
484765
485325
 
@@ -486710,16 +487270,16 @@ __export(exports_shell_aliases, {
486710
487270
  expandAliases: () => expandAliases,
486711
487271
  clearAliasCache: () => clearAliasCache
486712
487272
  });
486713
- import { existsSync as existsSync55, readFileSync as readFileSync37 } from "node:fs";
487273
+ import { existsSync as existsSync56, readFileSync as readFileSync38 } from "node:fs";
486714
487274
  import { homedir as homedir36 } from "node:os";
486715
- import { join as join59 } from "node:path";
487275
+ import { join as join60 } from "node:path";
486716
487276
  function parseAliasesFromFile(filePath) {
486717
487277
  const aliases = new Map;
486718
- if (!existsSync55(filePath)) {
487278
+ if (!existsSync56(filePath)) {
486719
487279
  return aliases;
486720
487280
  }
486721
487281
  try {
486722
- const content = readFileSync37(filePath, "utf-8");
487282
+ const content = readFileSync38(filePath, "utf-8");
486723
487283
  const lines = content.split(`
486724
487284
  `);
486725
487285
  let inFunction = false;
@@ -486784,7 +487344,7 @@ function loadAliases(forceReload = false) {
486784
487344
  const home = homedir36();
486785
487345
  const allAliases = new Map;
486786
487346
  for (const file3 of ALIAS_FILES) {
486787
- const filePath = join59(home, file3);
487347
+ const filePath = join60(home, file3);
486788
487348
  const fileAliases = parseAliasesFromFile(filePath);
486789
487349
  for (const [name, value] of fileAliases) {
486790
487350
  allAliases.set(name, value);
@@ -492918,9 +493478,9 @@ var init_conversation_switch_alert = __esm(() => {
492918
493478
 
492919
493479
  // src/cli/app/use-submit-handler.ts
492920
493480
  import { randomUUID as randomUUID28 } from "node:crypto";
492921
- import { existsSync as existsSync56, readFileSync as readFileSync38, renameSync as renameSync3, writeFileSync as writeFileSync32 } from "node:fs";
493481
+ import { existsSync as existsSync57, readFileSync as readFileSync39, renameSync as renameSync3, writeFileSync as writeFileSync32 } from "node:fs";
492922
493482
  import { tmpdir as tmpdir8 } from "node:os";
492923
- import { join as join60 } from "node:path";
493483
+ import { join as join61 } from "node:path";
492924
493484
  async function hasCustomCommand(commandName) {
492925
493485
  const { findCustomCommand: findCustomCommand2 } = await Promise.resolve().then(() => (init_custom(), exports_custom));
492926
493486
  return Boolean(await findCustomCommand2(commandName));
@@ -493273,12 +493833,12 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
493273
493833
  try {
493274
493834
  const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
493275
493835
  const personaCandidates = [
493276
- join60(memoryRoot, "system", "persona.md"),
493277
- join60(memoryRoot, "memory", "system", "persona.md")
493836
+ join61(memoryRoot, "system", "persona.md"),
493837
+ join61(memoryRoot, "memory", "system", "persona.md")
493278
493838
  ];
493279
- const personaPath = personaCandidates.find((candidate) => existsSync56(candidate));
493839
+ const personaPath = personaCandidates.find((candidate) => existsSync57(candidate));
493280
493840
  if (personaPath) {
493281
- const personaContent = readFileSync38(personaPath, "utf-8");
493841
+ const personaContent = readFileSync39(personaPath, "utf-8");
493282
493842
  setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
493283
493843
  } else {
493284
493844
  setCurrentPersonalityId(null);
@@ -494230,11 +494790,11 @@ Path: ${memoryDir}`, true);
494230
494790
  setCommandRunning(true);
494231
494791
  try {
494232
494792
  const memoryDir = getScopedMemoryFilesystemRoot(agentId);
494233
- if (!existsSync56(memoryDir)) {
494793
+ if (!existsSync57(memoryDir)) {
494234
494794
  updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
494235
494795
  return { submitted: true };
494236
494796
  }
494237
- const backupDir = join60(tmpdir8(), `letta-memfs-reset-${agentId}-${Date.now()}`);
494797
+ const backupDir = join61(tmpdir8(), `letta-memfs-reset-${agentId}-${Date.now()}`);
494238
494798
  renameSync3(memoryDir, backupDir);
494239
494799
  if (getBackend().capabilities.localMemfs) {
494240
494800
  const { initializeLocalMemoryRepo: initializeLocalMemoryRepo2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
@@ -494278,8 +494838,8 @@ Run \`/memfs sync\` to repopulate from API.`, true, msg);
494278
494838
  await removeGitMemoryTag2(agentId);
494279
494839
  let backupInfo = "";
494280
494840
  const memoryDir = getScopedMemoryFilesystemRoot(agentId);
494281
- if (existsSync56(memoryDir)) {
494282
- const backupDir = join60(tmpdir8(), `letta-memfs-disable-${agentId}-${Date.now()}`);
494841
+ if (existsSync57(memoryDir)) {
494842
+ const backupDir = join61(tmpdir8(), `letta-memfs-disable-${agentId}-${Date.now()}`);
494283
494843
  renameSync3(memoryDir, backupDir);
494284
494844
  backupInfo = `
494285
494845
  Local files backed up to ${backupDir}`;
@@ -495197,6 +495757,7 @@ function App2({
495197
495757
  releaseNotes = null,
495198
495758
  updateNotification = null,
495199
495759
  systemInfoReminderEnabled = true,
495760
+ extensionsDisabled = false,
495200
495761
  onReload
495201
495762
  }) {
495202
495763
  import_react122.useEffect(() => {
@@ -496408,7 +496969,9 @@ function App2({
496408
496969
  isLocalBackend,
496409
496970
  statusLinePayload
496410
496971
  ]);
496411
- const extensionRuntime = useLocalExtensionRuntime(extensionContext);
496972
+ const extensionRuntime = useLocalExtensionRuntime(extensionContext, {
496973
+ disabled: extensionsDisabled
496974
+ });
496412
496975
  import_react122.useEffect(() => {
496413
496976
  extensionRuntimeRef.current = extensionRuntime;
496414
496977
  }, [extensionRuntime]);
@@ -497148,9 +497711,9 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
497148
497711
  (async () => {
497149
497712
  try {
497150
497713
  const { watch: watch3 } = await import("node:fs");
497151
- const { existsSync: existsSync57 } = await import("node:fs");
497714
+ const { existsSync: existsSync58 } = await import("node:fs");
497152
497715
  const memRoot = getScopedMemoryFilesystemRoot(agentId);
497153
- if (!existsSync57(memRoot))
497716
+ if (!existsSync58(memRoot))
497154
497717
  return;
497155
497718
  watcher = watch3(memRoot, { recursive: true }, () => {});
497156
497719
  memfsWatcherRef.current = watcher;
@@ -498308,13 +498871,13 @@ __export(exports_terminal_keybinding_installer2, {
498308
498871
  });
498309
498872
  import {
498310
498873
  copyFileSync as copyFileSync3,
498311
- existsSync as existsSync57,
498874
+ existsSync as existsSync58,
498312
498875
  mkdirSync as mkdirSync40,
498313
- readFileSync as readFileSync39,
498876
+ readFileSync as readFileSync40,
498314
498877
  writeFileSync as writeFileSync33
498315
498878
  } from "node:fs";
498316
498879
  import { homedir as homedir38, platform as platform7 } from "node:os";
498317
- import { dirname as dirname28, join as join61 } from "node:path";
498880
+ import { dirname as dirname28, join as join62 } from "node:path";
498318
498881
  function detectTerminalType2() {
498319
498882
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
498320
498883
  return "cursor";
@@ -498346,16 +498909,16 @@ function getKeybindingsPath2(terminal) {
498346
498909
  }[terminal];
498347
498910
  const os8 = platform7();
498348
498911
  if (os8 === "darwin") {
498349
- return join61(homedir38(), "Library", "Application Support", appName, "User", "keybindings.json");
498912
+ return join62(homedir38(), "Library", "Application Support", appName, "User", "keybindings.json");
498350
498913
  }
498351
498914
  if (os8 === "win32") {
498352
498915
  const appData = process.env.APPDATA;
498353
498916
  if (!appData)
498354
498917
  return null;
498355
- return join61(appData, appName, "User", "keybindings.json");
498918
+ return join62(appData, appName, "User", "keybindings.json");
498356
498919
  }
498357
498920
  if (os8 === "linux") {
498358
- return join61(homedir38(), ".config", appName, "User", "keybindings.json");
498921
+ return join62(homedir38(), ".config", appName, "User", "keybindings.json");
498359
498922
  }
498360
498923
  return null;
498361
498924
  }
@@ -498377,10 +498940,10 @@ function parseKeybindings2(content) {
498377
498940
  }
498378
498941
  }
498379
498942
  function keybindingExists2(keybindingsPath) {
498380
- if (!existsSync57(keybindingsPath))
498943
+ if (!existsSync58(keybindingsPath))
498381
498944
  return false;
498382
498945
  try {
498383
- const content = readFileSync39(keybindingsPath, { encoding: "utf-8" });
498946
+ const content = readFileSync40(keybindingsPath, { encoding: "utf-8" });
498384
498947
  const keybindings = parseKeybindings2(content);
498385
498948
  if (!keybindings)
498386
498949
  return false;
@@ -498390,7 +498953,7 @@ function keybindingExists2(keybindingsPath) {
498390
498953
  }
498391
498954
  }
498392
498955
  function createBackup2(keybindingsPath) {
498393
- if (!existsSync57(keybindingsPath))
498956
+ if (!existsSync58(keybindingsPath))
498394
498957
  return null;
498395
498958
  const backupPath = `${keybindingsPath}.letta-backup`;
498396
498959
  try {
@@ -498406,14 +498969,14 @@ function installKeybinding2(keybindingsPath) {
498406
498969
  return { success: true, alreadyExists: true };
498407
498970
  }
498408
498971
  const parentDir = dirname28(keybindingsPath);
498409
- if (!existsSync57(parentDir)) {
498972
+ if (!existsSync58(parentDir)) {
498410
498973
  mkdirSync40(parentDir, { recursive: true });
498411
498974
  }
498412
498975
  let keybindings = [];
498413
498976
  let backupPath = null;
498414
- if (existsSync57(keybindingsPath)) {
498977
+ if (existsSync58(keybindingsPath)) {
498415
498978
  backupPath = createBackup2(keybindingsPath);
498416
- const content = readFileSync39(keybindingsPath, { encoding: "utf-8" });
498979
+ const content = readFileSync40(keybindingsPath, { encoding: "utf-8" });
498417
498980
  const parsed = parseKeybindings2(content);
498418
498981
  if (parsed === null) {
498419
498982
  return {
@@ -498441,10 +499004,10 @@ function installKeybinding2(keybindingsPath) {
498441
499004
  }
498442
499005
  function removeKeybinding2(keybindingsPath) {
498443
499006
  try {
498444
- if (!existsSync57(keybindingsPath)) {
499007
+ if (!existsSync58(keybindingsPath)) {
498445
499008
  return { success: true };
498446
499009
  }
498447
- const content = readFileSync39(keybindingsPath, { encoding: "utf-8" });
499010
+ const content = readFileSync40(keybindingsPath, { encoding: "utf-8" });
498448
499011
  const keybindings = parseKeybindings2(content);
498449
499012
  if (!keybindings) {
498450
499013
  return {
@@ -498508,14 +499071,14 @@ function getWezTermConfigPath2() {
498508
499071
  }
498509
499072
  const xdgConfig = process.env.XDG_CONFIG_HOME;
498510
499073
  if (xdgConfig) {
498511
- const xdgPath = join61(xdgConfig, "wezterm", "wezterm.lua");
498512
- if (existsSync57(xdgPath))
499074
+ const xdgPath = join62(xdgConfig, "wezterm", "wezterm.lua");
499075
+ if (existsSync58(xdgPath))
498513
499076
  return xdgPath;
498514
499077
  }
498515
- const configPath = join61(homedir38(), ".config", "wezterm", "wezterm.lua");
498516
- if (existsSync57(configPath))
499078
+ const configPath = join62(homedir38(), ".config", "wezterm", "wezterm.lua");
499079
+ if (existsSync58(configPath))
498517
499080
  return configPath;
498518
- return join61(homedir38(), ".wezterm.lua");
499081
+ return join62(homedir38(), ".wezterm.lua");
498519
499082
  }
498520
499083
  function stripLuaCommentsFromLine2(line, blockCommentEnd) {
498521
499084
  let code2 = "";
@@ -498618,10 +499181,10 @@ ${WEZTERM_DELETE_FIX2}
498618
499181
  `;
498619
499182
  }
498620
499183
  function wezTermDeleteFixExists2(configPath) {
498621
- if (!existsSync57(configPath))
499184
+ if (!existsSync58(configPath))
498622
499185
  return false;
498623
499186
  try {
498624
- const content = readFileSync39(configPath, { encoding: "utf-8" });
499187
+ const content = readFileSync40(configPath, { encoding: "utf-8" });
498625
499188
  return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
498626
499189
  } catch {
498627
499190
  return false;
@@ -498635,14 +499198,14 @@ function installWezTermDeleteFix2() {
498635
499198
  }
498636
499199
  let content = "";
498637
499200
  let backupPath = null;
498638
- if (existsSync57(configPath)) {
499201
+ if (existsSync58(configPath)) {
498639
499202
  backupPath = `${configPath}.letta-backup`;
498640
499203
  copyFileSync3(configPath, backupPath);
498641
- content = readFileSync39(configPath, { encoding: "utf-8" });
499204
+ content = readFileSync40(configPath, { encoding: "utf-8" });
498642
499205
  }
498643
499206
  content = injectWezTermDeleteFix2(content);
498644
499207
  const parentDir = dirname28(configPath);
498645
- if (!existsSync57(parentDir)) {
499208
+ if (!existsSync58(parentDir)) {
498646
499209
  mkdirSync40(parentDir, { recursive: true });
498647
499210
  }
498648
499211
  writeFileSync33(configPath, content, { encoding: "utf-8" });
@@ -498694,9 +499257,9 @@ __export(exports_settings3, {
498694
499257
  getSetting: () => getSetting2
498695
499258
  });
498696
499259
  import { homedir as homedir39 } from "node:os";
498697
- import { join as join62 } from "node:path";
499260
+ import { join as join63 } from "node:path";
498698
499261
  function getSettingsPath2() {
498699
- return join62(homedir39(), ".letta", "settings.json");
499262
+ return join63(homedir39(), ".letta", "settings.json");
498700
499263
  }
498701
499264
  async function loadSettings2() {
498702
499265
  const settingsPath = getSettingsPath2();
@@ -498733,7 +499296,7 @@ async function getSetting2(key2) {
498733
499296
  return settings3[key2];
498734
499297
  }
498735
499298
  function getProjectSettingsPath2() {
498736
- return join62(process.cwd(), ".letta", "settings.local.json");
499299
+ return join63(process.cwd(), ".letta", "settings.local.json");
498737
499300
  }
498738
499301
  async function loadProjectSettings2() {
498739
499302
  const settingsPath = getProjectSettingsPath2();
@@ -498751,7 +499314,7 @@ async function loadProjectSettings2() {
498751
499314
  }
498752
499315
  async function saveProjectSettings2(settings3) {
498753
499316
  const settingsPath = getProjectSettingsPath2();
498754
- const dirPath = join62(process.cwd(), ".letta");
499317
+ const dirPath = join63(process.cwd(), ".letta");
498755
499318
  try {
498756
499319
  if (!exists(dirPath)) {
498757
499320
  await mkdir(dirPath, { recursive: true });
@@ -499365,7 +499928,7 @@ function parseRegistryHandle2(handle2) {
499365
499928
  }
499366
499929
  async function importAgentFromRegistry2(options3) {
499367
499930
  const { tmpdir: tmpdir9 } = await import("node:os");
499368
- const { join: join63 } = await import("node:path");
499931
+ const { join: join64 } = await import("node:path");
499369
499932
  const { writeFile: writeFile17, unlink: unlink4 } = await import("node:fs/promises");
499370
499933
  const { author, name } = parseRegistryHandle2(options3.handle);
499371
499934
  const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/refs/heads/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}/${name}.af`;
@@ -499377,7 +499940,7 @@ async function importAgentFromRegistry2(options3) {
499377
499940
  throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
499378
499941
  }
499379
499942
  const afContent = await response.text();
499380
- const tempPath = join63(tmpdir9(), `letta-import-${author}-${name}-${Date.now()}.af`);
499943
+ const tempPath = join64(tmpdir9(), `letta-import-${author}-${name}-${Date.now()}.af`);
499381
499944
  await writeFile17(tempPath, afContent, "utf-8");
499382
499945
  try {
499383
499946
  const result = await importAgentFromFile2({
@@ -499426,14 +499989,14 @@ __export(exports_memory_filesystem2, {
499426
499989
  MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
499427
499990
  MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
499428
499991
  });
499429
- import { existsSync as existsSync58, mkdirSync as mkdirSync41 } from "node:fs";
499992
+ import { existsSync as existsSync59, mkdirSync as mkdirSync41 } from "node:fs";
499430
499993
  import { homedir as homedir40 } from "node:os";
499431
- import { join as join63, resolve as resolve40 } from "node:path";
499994
+ import { join as join64, resolve as resolve40 } from "node:path";
499432
499995
  function getMemoryFilesystemRoot2(agentId, homeDir = homedir40()) {
499433
- return join63(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
499996
+ return join64(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
499434
499997
  }
499435
499998
  function getMemorySystemDir2(agentId, homeDir = homedir40()) {
499436
- return join63(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
499999
+ return join64(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
499437
500000
  }
499438
500001
  function getScopedMemoryFilesystemRoot2(agentId, options3 = {}) {
499439
500002
  const env6 = options3.env ?? process.env;
@@ -499469,10 +500032,10 @@ function resolveScopedMemoryDir2(options3 = {}) {
499469
500032
  function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir40()) {
499470
500033
  const root2 = getMemoryFilesystemRoot2(agentId, homeDir);
499471
500034
  const systemDir = getMemorySystemDir2(agentId, homeDir);
499472
- if (!existsSync58(root2)) {
500035
+ if (!existsSync59(root2)) {
499473
500036
  mkdirSync41(root2, { recursive: true });
499474
500037
  }
499475
- if (!existsSync58(systemDir)) {
500038
+ if (!existsSync59(systemDir)) {
499476
500039
  mkdirSync41(systemDir, { recursive: true });
499477
500040
  }
499478
500041
  }
@@ -501131,7 +501694,7 @@ async function getResumeDataFromBackend(agent2, conversationId, options3 = {}) {
501131
501694
  messageHistory: prepareMessageHistory(messages)
501132
501695
  };
501133
501696
  } else {
501134
- inContextMessageIds = agentWithInContext.in_context_message_ids;
501697
+ inContextMessageIds = agentWithInContext.in_context_message_ids ?? agent2.message_ids;
501135
501698
  const lastInContextId = inContextMessageIds?.at(-1);
501136
501699
  let defaultConversationMessages = [];
501137
501700
  if (includeMessageHistory && isBackfillEnabled() || !lastInContextId) {
@@ -502020,6 +502583,14 @@ var CLI_FLAG_CATALOG = {
502020
502583
  description: "Disable first-turn environment reminder (device/git/cwd context)"
502021
502584
  }
502022
502585
  },
502586
+ "no-extensions": {
502587
+ parser: { type: "boolean" },
502588
+ mode: "both",
502589
+ help: {
502590
+ description: "Disable local extensions for this session",
502591
+ continuationLines: ["Recovery alias: LETTA_DISABLE_EXTENSIONS=1 letta"]
502592
+ }
502593
+ },
502023
502594
  "reflection-trigger": {
502024
502595
  parser: { type: "string" },
502025
502596
  mode: "both",
@@ -504449,6 +505020,14 @@ var CLI_FLAG_CATALOG2 = {
504449
505020
  description: "Disable first-turn environment reminder (device/git/cwd context)"
504450
505021
  }
504451
505022
  },
505023
+ "no-extensions": {
505024
+ parser: { type: "boolean" },
505025
+ mode: "both",
505026
+ help: {
505027
+ description: "Disable local extensions for this session",
505028
+ continuationLines: ["Recovery alias: LETTA_DISABLE_EXTENSIONS=1 letta"]
505029
+ }
505030
+ },
504452
505031
  "reflection-trigger": {
504453
505032
  parser: { type: "string" },
504454
505033
  mode: "both",
@@ -507034,10 +507613,14 @@ Search options:
507034
507613
  --all-agents Search all agents, not just current agent
507035
507614
  --agent <id> Explicit agent ID (overrides LETTA_AGENT_ID)
507036
507615
  --agent-id <id> Alias for --agent
507616
+ --conversation <id> Conversation ID to search; "default" requires an agent
507617
+ --conversation-id <id> Alias for --conversation
507037
507618
 
507038
507619
  List options:
507039
507620
  --agent <id> Agent ID (overrides LETTA_AGENT_ID)
507040
507621
  --agent-id <id> Alias for --agent
507622
+ --conversation <id> Conversation ID to list (default: default)
507623
+ --conversation-id <id> Alias for --conversation
507041
507624
  --after <message-id> Cursor: get messages after this ID
507042
507625
  --before <message-id> Cursor: get messages before this ID
507043
507626
  --order <asc|desc> Sort order (default: desc = newest first)
@@ -507084,7 +507667,7 @@ function parseOrder(value) {
507084
507667
  function getAgentId5(agentFromArgs, agentIdFromArgs) {
507085
507668
  return agentFromArgs || agentIdFromArgs || process.env.LETTA_AGENT_ID || "";
507086
507669
  }
507087
- function pageItems4(page) {
507670
+ function pageItems3(page) {
507088
507671
  if (Array.isArray(page))
507089
507672
  return page;
507090
507673
  if (page && typeof page === "object") {
@@ -507125,7 +507708,7 @@ function parseMessagesArgs(argv) {
507125
507708
  allowPositionals: true
507126
507709
  });
507127
507710
  }
507128
- async function runMessagesSubcommand(argv) {
507711
+ async function runMessagesSubcommand(argv, deps = {}) {
507129
507712
  let parsed;
507130
507713
  try {
507131
507714
  parsed = parseMessagesArgs(argv);
@@ -507141,8 +507724,9 @@ async function runMessagesSubcommand(argv) {
507141
507724
  return 0;
507142
507725
  }
507143
507726
  try {
507144
- await settingsManager.initialize();
507145
- const backend4 = getBackend();
507727
+ await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
507728
+ const backend4 = (deps.getBackend ?? getBackend)();
507729
+ const searchMessages2 = deps.searchMessagesForBackend ?? searchMessagesForBackend;
507146
507730
  const renderText = (value) => {
507147
507731
  if (typeof value === "string")
507148
507732
  return value;
@@ -507232,7 +507816,7 @@ async function runMessagesSubcommand(argv) {
507232
507816
  ...conversationId === "default" && agentIdForDefault ? { agent_id: agentIdForDefault } : {},
507233
507817
  ...cursorBefore ? { before: cursorBefore } : {}
507234
507818
  });
507235
- const items3 = pageItems4(page);
507819
+ const items3 = pageItems3(page);
507236
507820
  if (items3.length === 0) {
507237
507821
  break;
507238
507822
  }
@@ -507259,42 +507843,61 @@ async function runMessagesSubcommand(argv) {
507259
507843
  return 1;
507260
507844
  }
507261
507845
  const allAgents = parsed.values["all-agents"] ?? false;
507846
+ const explicitAgentId = parsed.values.agent || parsed.values["agent-id"] || "";
507262
507847
  const agentId = getAgentId5(parsed.values.agent, parsed.values["agent-id"]);
507263
- if (!allAgents && !agentId) {
507264
- console.error("Missing agent id. Set LETTA_AGENT_ID or pass --agent/--agent-id.");
507848
+ const conversationId = parsed.values.conversation || parsed.values["conversation-id"];
507849
+ if (conversationId === "default") {
507850
+ if (!agentId) {
507851
+ console.error('Conversation "default" requires an agent id. Set LETTA_AGENT_ID or pass --agent/--agent-id.');
507852
+ return 1;
507853
+ }
507854
+ if (allAgents) {
507855
+ console.error('Conversation "default" requires a single agent id; do not combine --all-agents with --conversation default.');
507856
+ return 1;
507857
+ }
507858
+ }
507859
+ if (!allAgents && !agentId && !conversationId) {
507860
+ console.error("Missing search scope. Set LETTA_AGENT_ID, pass --agent/--agent-id, pass --conversation, or use --all-agents.");
507265
507861
  return 1;
507266
507862
  }
507267
- const result = await searchMessagesForBackend({
507863
+ const scopedAgentId = conversationId === "default" ? agentId : conversationId ? explicitAgentId || undefined : allAgents ? undefined : agentId || undefined;
507864
+ const searchBody = {
507268
507865
  query: query2,
507269
- agent_id: allAgents ? undefined : agentId,
507270
507866
  search_mode: parseMode(parsed.values.mode) ?? "hybrid",
507271
507867
  start_date: parsed.values["start-date"],
507272
507868
  end_date: parsed.values["end-date"],
507273
- limit: parseLimit2(parsed.values.limit, 10)
507274
- });
507869
+ limit: parseLimit2(parsed.values.limit, 10),
507870
+ ...scopedAgentId ? { agent_id: scopedAgentId } : {},
507871
+ ...typeof conversationId === "string" ? { conversation_id: conversationId } : {}
507872
+ };
507873
+ const result = await searchMessages2(searchBody);
507275
507874
  console.log(JSON.stringify(result, null, 2));
507276
507875
  return 0;
507277
507876
  }
507278
507877
  if (action3 === "list") {
507279
507878
  const agentId = getAgentId5(parsed.values.agent, parsed.values["agent-id"]);
507280
- if (!agentId) {
507281
- console.error("Missing agent id. Set LETTA_AGENT_ID or pass --agent/--agent-id.");
507282
- return 1;
507283
- }
507284
507879
  const orderRaw = parsed.values.order;
507285
507880
  const order = parseOrder(orderRaw);
507286
507881
  if (orderRaw !== undefined && !order) {
507287
507882
  console.error(`Invalid --order "${orderRaw}". Use "asc" or "desc".`);
507288
507883
  return 1;
507289
507884
  }
507290
- const response = await backend4.listAgentMessages(agentId, {
507291
- conversation_id: "default",
507885
+ const conversationId = parsed.values.conversation || parsed.values["conversation-id"] || "default";
507886
+ if (conversationId === "default" && !agentId) {
507887
+ console.error('Conversation "default" requires an agent id. Set LETTA_AGENT_ID or pass --agent/--agent-id.');
507888
+ return 1;
507889
+ }
507890
+ const listBody = {
507292
507891
  limit: parseLimit2(parsed.values.limit, 20),
507293
507892
  after: parsed.values.after,
507294
507893
  before: parsed.values.before,
507295
507894
  order
507296
- });
507297
- const messages = pageItems4(response);
507895
+ };
507896
+ const response = conversationId === "default" ? await backend4.listAgentMessages(agentId, {
507897
+ conversation_id: "default",
507898
+ ...listBody
507899
+ }) : await backend4.listConversationMessages(conversationId, listBody);
507900
+ const messages = pageItems3(response);
507298
507901
  const startDate = parsed.values["start-date"];
507299
507902
  const endDate = parsed.values["end-date"];
507300
507903
  let filtered = messages;
@@ -507422,16 +508025,16 @@ async function runSetupSubcommand(argv) {
507422
508025
  // src/cli/subcommands/skills.ts
507423
508026
  import {
507424
508027
  cpSync as cpSync2,
507425
- existsSync as existsSync41,
508028
+ existsSync as existsSync42,
507426
508029
  mkdtempSync,
507427
- readFileSync as readFileSync31,
508030
+ readFileSync as readFileSync32,
507428
508031
  rmSync as rmSync7,
507429
- statSync as statSync16,
508032
+ statSync as statSync17,
507430
508033
  writeFileSync as writeFileSync23
507431
508034
  } from "node:fs";
507432
508035
  import { mkdir as mkdir11, readdir as readdir9 } from "node:fs/promises";
507433
508036
  import { tmpdir as tmpdir6 } from "node:os";
507434
- import { basename as basename19, dirname as dirname21, join as join42, normalize as normalize7, resolve as resolve31, sep as sep7 } from "node:path";
508037
+ import { basename as basename19, dirname as dirname21, join as join43, normalize as normalize7, resolve as resolve31, sep as sep7 } from "node:path";
507435
508038
  import { parseArgs as parseArgs10 } from "node:util";
507436
508039
  var HERMES_REPO_URL = "https://github.com/NousResearch/hermes-agent.git";
507437
508040
  var HERMES_OPTIONAL_SKILLS_DIR = "optional-skills";
@@ -507688,14 +508291,14 @@ async function resolveBranchAndSubdir(location) {
507688
508291
  }
507689
508292
  async function cloneSkillSource(location) {
507690
508293
  const resolvedLocation = await resolveBranchAndSubdir(location);
507691
- const tmpDir = mkdtempSync(join42(tmpdir6(), "letta-skill-install-"));
508294
+ const tmpDir = mkdtempSync(join43(tmpdir6(), "letta-skill-install-"));
507692
508295
  const args = ["clone", "--depth", "1"];
507693
508296
  if (resolvedLocation.branch) {
507694
508297
  args.push("--branch", resolvedLocation.branch);
507695
508298
  }
507696
508299
  args.push(resolvedLocation.repoUrl, tmpDir);
507697
508300
  await execFile15("git", args, { timeout: 120000 });
507698
- const sourceDir = resolvedLocation.subdir ? join42(tmpDir, resolvedLocation.subdir) : tmpDir;
508301
+ const sourceDir = resolvedLocation.subdir ? join43(tmpDir, resolvedLocation.subdir) : tmpDir;
507699
508302
  return { tmpDir, sourceDir };
507700
508303
  }
507701
508304
  async function fetchJson2(url2) {
@@ -507732,9 +508335,9 @@ function assertSafeZipMember(name) {
507732
508335
  }
507733
508336
  async function downloadClawHubSkillSource(location) {
507734
508337
  const version2 = await resolveClawHubVersion(location);
507735
- const tmpDir = mkdtempSync(join42(tmpdir6(), "letta-clawhub-skill-"));
507736
- const zipPath = join42(tmpDir, "skill.zip");
507737
- const sourceDir = join42(tmpDir, "skill");
508338
+ const tmpDir = mkdtempSync(join43(tmpdir6(), "letta-clawhub-skill-"));
508339
+ const zipPath = join43(tmpDir, "skill.zip");
508340
+ const sourceDir = join43(tmpDir, "skill");
507738
508341
  await mkdir11(sourceDir, { recursive: true });
507739
508342
  const url2 = new URL(`${CLAWHUB_API_BASE_URL}/download`);
507740
508343
  url2.searchParams.set("slug", location.slug);
@@ -507773,7 +508376,7 @@ function sanitizeSkillName(name) {
507773
508376
  return trimmed;
507774
508377
  }
507775
508378
  function getSkillName(sourceDir) {
507776
- const skillMd = readFileSync31(join42(sourceDir, "SKILL.md"), "utf8");
508379
+ const skillMd = readFileSync32(join43(sourceDir, "SKILL.md"), "utf8");
507777
508380
  const { frontmatter } = parseFrontmatter(skillMd);
507778
508381
  const frontmatterName = frontmatter.name;
507779
508382
  const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename19(sourceDir);
@@ -507782,18 +508385,18 @@ function getSkillName(sourceDir) {
507782
508385
  async function installSkillDirectory(params) {
507783
508386
  const sourceDir = resolve31(params.sourceDir);
507784
508387
  const memoryDir = resolve31(params.memoryDir);
507785
- const skillMdPath = join42(sourceDir, "SKILL.md");
507786
- if (!existsSync41(skillMdPath)) {
508388
+ const skillMdPath = join43(sourceDir, "SKILL.md");
508389
+ if (!existsSync42(skillMdPath)) {
507787
508390
  throw new Error("No SKILL.md found in the skill directory.");
507788
508391
  }
507789
- if (!statSync16(sourceDir).isDirectory()) {
508392
+ if (!statSync17(sourceDir).isDirectory()) {
507790
508393
  throw new Error(`Skill source is not a directory: ${sourceDir}`);
507791
508394
  }
507792
508395
  const name = getSkillName(sourceDir);
507793
- const skillsDir = join42(memoryDir, "skills");
507794
- const targetPath = join42(skillsDir, name);
508396
+ const skillsDir = join43(memoryDir, "skills");
508397
+ const targetPath = join43(skillsDir, name);
507795
508398
  assertInside(skillsDir, targetPath);
507796
- if (existsSync41(targetPath)) {
508399
+ if (existsSync42(targetPath)) {
507797
508400
  if (!params.force) {
507798
508401
  throw new Error(`Skill "${name}" already exists at ${targetPath}. Re-run with --force to replace it.`);
507799
508402
  }
@@ -507808,22 +508411,22 @@ async function installSkillDirectory(params) {
507808
508411
  }
507809
508412
  async function listSkillDirectories(params) {
507810
508413
  const memoryDir = resolve31(params.memoryDir);
507811
- const skillsDir = join42(memoryDir, "skills");
507812
- if (!existsSync41(skillsDir))
508414
+ const skillsDir = join43(memoryDir, "skills");
508415
+ if (!existsSync42(skillsDir))
507813
508416
  return [];
507814
508417
  const entries = await readdir9(skillsDir, { withFileTypes: true });
507815
508418
  const skills = [];
507816
508419
  for (const entry of entries) {
507817
508420
  if (!entry.isDirectory())
507818
508421
  continue;
507819
- const skillDir = join42(skillsDir, entry.name);
507820
- const skillMdPath = join42(skillDir, "SKILL.md");
507821
- if (!existsSync41(skillMdPath))
508422
+ const skillDir = join43(skillsDir, entry.name);
508423
+ const skillMdPath = join43(skillDir, "SKILL.md");
508424
+ if (!existsSync42(skillMdPath))
507822
508425
  continue;
507823
508426
  let name = entry.name;
507824
508427
  let description;
507825
508428
  try {
507826
- const skillMd = readFileSync31(skillMdPath, "utf8");
508429
+ const skillMd = readFileSync32(skillMdPath, "utf8");
507827
508430
  const { frontmatter } = parseFrontmatter(skillMd);
507828
508431
  if (typeof frontmatter.name === "string" && frontmatter.name.trim()) {
507829
508432
  name = frontmatter.name.trim();
@@ -507838,14 +508441,14 @@ async function listSkillDirectories(params) {
507838
508441
  }
507839
508442
  async function deleteSkillDirectory(params) {
507840
508443
  const memoryDir = resolve31(params.memoryDir);
507841
- const skillsDir = join42(memoryDir, "skills");
508444
+ const skillsDir = join43(memoryDir, "skills");
507842
508445
  const name = sanitizeSkillName(params.name);
507843
- const targetPath = join42(skillsDir, name);
508446
+ const targetPath = join43(skillsDir, name);
507844
508447
  assertInside(skillsDir, targetPath);
507845
- if (!existsSync41(targetPath)) {
508448
+ if (!existsSync42(targetPath)) {
507846
508449
  throw new Error(`Skill "${name}" is not installed at ${targetPath}.`);
507847
508450
  }
507848
- if (!statSync16(targetPath).isDirectory()) {
508451
+ if (!statSync17(targetPath).isDirectory()) {
507849
508452
  throw new Error(`Skill path is not a directory: ${targetPath}`);
507850
508453
  }
507851
508454
  rmSync7(targetPath, { recursive: true, force: true });
@@ -507864,7 +508467,7 @@ async function installSkill(specifier, agentId, force) {
507864
508467
  tmpDir = downloaded.tmpDir;
507865
508468
  const sourceDir = resolve31(downloaded.sourceDir);
507866
508469
  assertInside(tmpDir, sourceDir);
507867
- if (!existsSync41(sourceDir)) {
508470
+ if (!existsSync42(sourceDir)) {
507868
508471
  const missingPath = gitSource?.subdir || clawHubSource?.slug || ".";
507869
508472
  throw new Error(`Skill path not found: ${missingPath}`);
507870
508473
  }
@@ -508129,6 +508732,24 @@ async function runSubcommand(argv) {
508129
508732
  }
508130
508733
  }
508131
508734
 
508735
+ // src/extensions/disable.ts
508736
+ var LETTA_DISABLE_EXTENSIONS_ENV2 = "LETTA_DISABLE_EXTENSIONS";
508737
+ function isTruthyEnvFlag2(value) {
508738
+ if (!value)
508739
+ return false;
508740
+ const normalized = value.trim().toLowerCase();
508741
+ return ["1", "true", "yes", "on"].includes(normalized);
508742
+ }
508743
+ function areExtensionsDisabled2(env5 = process.env) {
508744
+ return isTruthyEnvFlag2(env5[LETTA_DISABLE_EXTENSIONS_ENV2]);
508745
+ }
508746
+ function shouldDisableExtensions2(options3) {
508747
+ return Boolean(options3?.cliFlag || areExtensionsDisabled2(options3?.env ?? process.env));
508748
+ }
508749
+ function disableExtensionsForProcess2() {
508750
+ process.env[LETTA_DISABLE_EXTENSIONS_ENV2] = "1";
508751
+ }
508752
+
508132
508753
  // src/permissions/mode.ts
508133
508754
  init_cross_agent_guard();
508134
508755
  init_memory_denial_reason();
@@ -508355,7 +508976,7 @@ init_fs();
508355
508976
  init_secrets();
508356
508977
  import { randomUUID as randomUUID19 } from "node:crypto";
508357
508978
  import { homedir as homedir24 } from "node:os";
508358
- import { join as join43, resolve as resolve32 } from "node:path";
508979
+ import { join as join44, resolve as resolve32 } from "node:path";
508359
508980
  var DEFAULT_SETTINGS3 = {
508360
508981
  lastAgent: null,
508361
508982
  tokenStreaming: false,
@@ -508800,7 +509421,7 @@ class SettingsManager2 {
508800
509421
  return;
508801
509422
  const settingsPath = this.getSettingsPath();
508802
509423
  const home = process.env.HOME || homedir24();
508803
- const dirPath = join43(home, ".letta");
509424
+ const dirPath = join44(home, ".letta");
508804
509425
  try {
508805
509426
  if (!exists(dirPath)) {
508806
509427
  await mkdir(dirPath, { recursive: true });
@@ -508839,7 +509460,7 @@ class SettingsManager2 {
508839
509460
  if (!settings3)
508840
509461
  return;
508841
509462
  const settingsPath = this.getProjectSettingsPath(workingDirectory);
508842
- const dirPath = join43(workingDirectory, ".letta");
509463
+ const dirPath = join44(workingDirectory, ".letta");
508843
509464
  try {
508844
509465
  let existingSettings = {};
508845
509466
  if (exists(settingsPath)) {
@@ -508861,16 +509482,16 @@ class SettingsManager2 {
508861
509482
  }
508862
509483
  getSettingsPath() {
508863
509484
  const home = process.env.HOME || homedir24();
508864
- return join43(home, ".letta", "settings.json");
509485
+ return join44(home, ".letta", "settings.json");
508865
509486
  }
508866
509487
  getProjectSettingsPath(workingDirectory) {
508867
- return join43(workingDirectory, ".letta", "settings.json");
509488
+ return join44(workingDirectory, ".letta", "settings.json");
508868
509489
  }
508869
509490
  isProjectSettingsPathCollidingWithGlobal(workingDirectory) {
508870
509491
  return resolve32(this.getProjectSettingsPath(workingDirectory)) === resolve32(this.getSettingsPath());
508871
509492
  }
508872
509493
  getLocalProjectSettingsPath(workingDirectory) {
508873
- return join43(workingDirectory, ".letta", "settings.local.json");
509494
+ return join44(workingDirectory, ".letta", "settings.local.json");
508874
509495
  }
508875
509496
  async loadLocalProjectSettings(workingDirectory = process.cwd()) {
508876
509497
  const cached2 = this.localProjectSettings.get(workingDirectory);
@@ -508931,7 +509552,7 @@ class SettingsManager2 {
508931
509552
  if (!settings3)
508932
509553
  return;
508933
509554
  const settingsPath = this.getLocalProjectSettingsPath(workingDirectory);
508934
- const dirPath = join43(workingDirectory, ".letta");
509555
+ const dirPath = join44(workingDirectory, ".letta");
508935
509556
  try {
508936
509557
  if (!exists(dirPath)) {
508937
509558
  await mkdir(dirPath, { recursive: true });
@@ -509460,7 +510081,7 @@ class SettingsManager2 {
509460
510081
  this.upsertAgentSettings(agentId, { systemPromptPreset: "" });
509461
510082
  }
509462
510083
  hasLocalLettaDir(workingDirectory = process.cwd()) {
509463
- const dirPath = join43(workingDirectory, ".letta");
510084
+ const dirPath = join44(workingDirectory, ".letta");
509464
510085
  return exists(dirPath);
509465
510086
  }
509466
510087
  storeOAuthState(state, codeVerifier, redirectUri, provider) {
@@ -509937,9 +510558,9 @@ async function loadTools2(modelIdentifier, options3) {
509937
510558
  function isOpenAIModel2(modelIdentifier) {
509938
510559
  const info = getModelInfo(modelIdentifier);
509939
510560
  if (info?.handle && typeof info.handle === "string") {
509940
- return info.handle.startsWith("openai/") || info.handle.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`) || info.handle.startsWith("chatgpt_oauth/");
510561
+ return info.handle.startsWith("openai/") || info.handle.startsWith("openai-codex/") || info.handle.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`) || info.handle.startsWith("chatgpt_oauth/");
509941
510562
  }
509942
- return modelIdentifier.startsWith("openai/") || modelIdentifier.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`) || modelIdentifier.startsWith("chatgpt_oauth/");
510563
+ return modelIdentifier.startsWith("openai/") || modelIdentifier.startsWith("openai-codex/") || modelIdentifier.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`) || modelIdentifier.startsWith("chatgpt_oauth/");
509943
510564
  }
509944
510565
  function injectSubagentsIntoTaskDescription2(baseDescription, subagents) {
509945
510566
  if (subagents.length === 0) {
@@ -510170,12 +510791,12 @@ EXAMPLES
510170
510791
  console.log(usage);
510171
510792
  }
510172
510793
  async function printInfo() {
510173
- const { join: join64 } = await import("path");
510794
+ const { join: join65 } = await import("path");
510174
510795
  const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
510175
510796
  const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills4(), exports_skills3));
510176
510797
  const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
510177
510798
  const cwd2 = process.cwd();
510178
- const skillsDir = join64(cwd2, SKILLS_DIR3);
510799
+ const skillsDir = join65(cwd2, SKILLS_DIR3);
510179
510800
  const skillsExist = exists3(skillsDir);
510180
510801
  await settingsManager2.loadLocalProjectSettings(cwd2);
510181
510802
  const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
@@ -510556,6 +511177,12 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
510556
511177
  const noBundledSkillsFlag = values2["no-bundled-skills"];
510557
511178
  const skillSourcesRaw = values2["skill-sources"];
510558
511179
  const noSystemInfoReminderFlag = values2["no-system-info-reminder"];
511180
+ const extensionsDisabled = shouldDisableExtensions2({
511181
+ cliFlag: values2["no-extensions"]
511182
+ });
511183
+ if (extensionsDisabled) {
511184
+ disableExtensionsForProcess2();
511185
+ }
510559
511186
  const resolvedSkillSources = (() => {
510560
511187
  try {
510561
511188
  return resolveSkillSourcesSelection2({
@@ -510750,9 +511377,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
510750
511377
  }
510751
511378
  } else {
510752
511379
  const { resolve: resolve41 } = await import("path");
510753
- const { existsSync: existsSync59 } = await import("fs");
511380
+ const { existsSync: existsSync60 } = await import("fs");
510754
511381
  const resolvedPath = resolve41(fromAfFile);
510755
- if (!existsSync59(resolvedPath)) {
511382
+ if (!existsSync60(resolvedPath)) {
510756
511383
  console.error(`Error: AgentFile not found: ${resolvedPath}`);
510757
511384
  process.exit(1);
510758
511385
  }
@@ -511731,7 +512358,8 @@ Error during initialization: ${message}`);
511731
512358
  startupHasCloudCredentials,
511732
512359
  startupHasAvailableLocalModels,
511733
512360
  releaseNotes: releaseNotes2,
511734
- systemInfoReminderEnabled: !noSystemInfoReminderFlag
512361
+ systemInfoReminderEnabled: !noSystemInfoReminderFlag,
512362
+ extensionsDisabled
511735
512363
  });
511736
512364
  }
511737
512365
  return React15.createElement(App3, {
@@ -511754,6 +512382,7 @@ Error during initialization: ${message}`);
511754
512382
  releaseNotes: releaseNotes2,
511755
512383
  updateNotification,
511756
512384
  systemInfoReminderEnabled: !noSystemInfoReminderFlag,
512385
+ extensionsDisabled,
511757
512386
  onReload: handleReload
511758
512387
  });
511759
512388
  }
@@ -511776,4 +512405,4 @@ Error during initialization: ${message}`);
511776
512405
  }
511777
512406
  main2();
511778
512407
 
511779
- //# debugId=2668B262D16800F764756E2164756E21
512408
+ //# debugId=FB2D67983121CCDA64756E2164756E21