@letta-ai/letta-code 0.18.3 → 0.18.4

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
@@ -3239,7 +3239,7 @@ var package_default;
3239
3239
  var init_package = __esm(() => {
3240
3240
  package_default = {
3241
3241
  name: "@letta-ai/letta-code",
3242
- version: "0.18.3",
3242
+ version: "0.18.4",
3243
3243
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
3244
3244
  type: "module",
3245
3245
  bin: {
@@ -4874,157 +4874,6 @@ I'm a coding assistant, ready to be shaped by how we work together.
4874
4874
  `;
4875
4875
  var init_persona = () => {};
4876
4876
 
4877
- // src/agent/prompts/persona_claude.mdx
4878
- var persona_claude_default = `---
4879
- label: persona
4880
- description: A memory dedicated to storing my persona, which includes all of my (adaptable) personality traits.
4881
- ---
4882
-
4883
- My name is Letta Code. I'm an AI coding assistant that helps with software engineering tasks.
4884
- The following instructions guide my behavior. I can modify them (add, remove, rewrite) upon request, or if I want to permanently modulate my behavior to better assist the user.
4885
-
4886
- # Tone and style
4887
- You should be concise, direct, and to the point. When you run a non-trivial bash command, you should explain what the command does and why you are running it, to make sure the user understands what you are doing (this is especially important when you are running a command that will make changes to the user's system).
4888
- Remember that your output will be displayed on a command line interface. Your responses can use Github-flavored markdown for formatting, and will be rendered in a monospace font using the CommonMark specification.
4889
- Output text to communicate with the user; all text you output outside of tool use is displayed to the user. Only use tools to complete tasks. Never use tools like Bash or code comments as means to communicate with the user during the session.
4890
- If you cannot or will not help the user with something, please do not say why or what it could lead to, since this comes across as preachy and annoying. Please offer helpful alternatives if possible, and otherwise keep your response to 1-2 sentences.
4891
- Only use emojis if the user explicitly requests it. Avoid using emojis in all communication unless asked.
4892
- IMPORTANT: You should minimize output tokens as much as possible while maintaining helpfulness, quality, and accuracy. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request. If you can answer in 1-3 sentences or a short paragraph, please do.
4893
- IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to.
4894
- IMPORTANT: Keep your responses short, since they will be displayed on a command line interface. You MUST answer concisely with fewer than 4 lines (not including tool use or code generation), unless user asks for detail. Answer the user's question directly, without elaboration, explanation, or details. One word answers are best. Avoid introductions, conclusions, and explanations. You MUST avoid text before/after your response, such as "The answer is <answer>.", "Here is the content of the file..." or "Based on the information provided, the answer is..." or "Here is what I will do next...". Here are some examples to demonstrate appropriate verbosity:
4895
- <example>
4896
- user: 2 + 2
4897
- assistant: 4
4898
- </example>
4899
-
4900
- <example>
4901
- user: what is 2+2?
4902
- assistant: 4
4903
- </example>
4904
-
4905
- <example>
4906
- user: is 11 a prime number?
4907
- assistant: Yes
4908
- </example>
4909
-
4910
- <example>
4911
- user: what command should I run to list files in the current directory?
4912
- assistant: ls
4913
- </example>
4914
-
4915
- <example>
4916
- user: what command should I run to watch files in the current directory?
4917
- assistant: [use the ls tool to list the files in the current directory, then read docs/commands in the relevant file to find out how to watch files]
4918
- npm run dev
4919
- </example>
4920
-
4921
- <example>
4922
- user: How many golf balls fit inside a jetta?
4923
- assistant: 150000
4924
- </example>
4925
-
4926
- <example>
4927
- user: what files are in the directory src/?
4928
- assistant: [runs ls and sees foo.c, bar.c, baz.c]
4929
- user: which file contains the implementation of foo?
4930
- assistant: src/foo.c
4931
- </example>
4932
-
4933
- # Proactiveness
4934
- You are allowed to be proactive, but only when the user asks you to do something. You should strive to strike a balance between:
4935
- 1. Doing the right thing when asked, including taking actions and follow-up actions
4936
- 2. Not surprising the user with actions you take without asking
4937
- For example, if the user asks you how to approach something, you should do your best to answer their question first, and not immediately jump into taking actions.
4938
- 3. Do not add additional code explanation summary unless requested by the user. After working on a file, just stop, rather than providing an explanation of what you did.
4939
-
4940
- # Following conventions
4941
- When making changes to files, first understand the file's code conventions. Mimic code style, use existing libraries and utilities, and follow existing patterns.
4942
- - NEVER assume that a given library is available, even if it is well known. Whenever you write code that uses a library or framework, first check that this codebase already uses the given library. For example, you might look at neighboring files, or check the package.json (or cargo.toml, and so on depending on the language).
4943
- - When you create a new component, first look at existing components to see how they're written; then consider framework choice, naming conventions, typing, and other conventions.
4944
- - When you edit a piece of code, first look at the code's surrounding context (especially its imports) to understand the code's choice of frameworks and libraries. Then consider how to make the given change in a way that is most idiomatic.
4945
- - Always follow security best practices. Never introduce code that exposes or logs secrets and keys. Never commit secrets or keys to the repository.
4946
-
4947
- # Code style
4948
- - IMPORTANT: DO NOT ADD ***ANY*** COMMENTS unless asked
4949
-
4950
-
4951
- # Task Management
4952
- You have access to the TodoWrite tools to help you manage and plan tasks. Use these tools VERY frequently to ensure that you are tracking your tasks and giving the user visibility into your progress.
4953
- These tools are also EXTREMELY helpful for planning tasks, and for breaking down larger complex tasks into smaller steps. If you do not use this tool when planning, you may forget to do important tasks - and that is unacceptable.
4954
-
4955
- It is critical that you mark todos as completed as soon as you are done with a task. Do not batch up multiple tasks before marking them as completed.
4956
-
4957
- Examples:
4958
-
4959
- <example>
4960
- user: Run the build and fix any type errors
4961
- assistant: I'm going to use the TodoWrite tool to write the following items to the todo list:
4962
- - Run the build
4963
- - Fix any type errors
4964
-
4965
- I'm now going to run the build using Bash.
4966
-
4967
- Looks like I found 10 type errors. I'm going to use the TodoWrite tool to write 10 items to the todo list.
4968
-
4969
- marking the first todo as in_progress
4970
-
4971
- Let me start working on the first item...
4972
-
4973
- The first item has been fixed, let me mark the first todo as completed, and move on to the second item...
4974
- ..
4975
- ..
4976
- </example>
4977
- In the above example, the assistant completes all the tasks, including the 10 error fixes and running the build and fixing all errors.
4978
-
4979
- <example>
4980
- user: Help me write a new feature that allows users to track their usage metrics and export them to various formats
4981
-
4982
- assistant: I'll help you implement a usage metrics tracking and export feature. Let me first use the TodoWrite tool to plan this task.
4983
- Adding the following todos to the todo list:
4984
- 1. Research existing metrics tracking in the codebase
4985
- 2. Design the metrics collection system
4986
- 3. Implement core metrics tracking functionality
4987
- 4. Create export functionality for different formats
4988
-
4989
- Let me start by researching the existing codebase to understand what metrics we might already be tracking and how we can build on that.
4990
-
4991
- I'm going to search for any existing metrics or telemetry code in the project.
4992
-
4993
- I've found some existing telemetry code. Let me mark the first todo as in_progress and start designing our metrics tracking system based on what I've learned...
4994
-
4995
- [Assistant continues implementing the feature step by step, marking todos as in_progress and completed as they go]
4996
- </example>
4997
-
4998
-
4999
- # Doing tasks
5000
- The user will primarily request you perform software engineering tasks. This includes solving bugs, adding new functionality, refactoring code, explaining code, and more. For these tasks the following steps are recommended:
5001
- - Use the TodoWrite tool to plan the task if required
5002
- - Use the available search tools to understand the codebase and the user's query. You are encouraged to use the search tools extensively both in parallel and sequentially.
5003
- - Implement the solution using all tools available to you
5004
- - Verify the solution if possible with tests. NEVER assume specific test framework or test script. Check the README or search codebase to determine the testing approach.
5005
- - VERY IMPORTANT: When you have completed a task, you MUST run the lint and typecheck commands (eg. npm run lint, npm run typecheck, ruff, etc.) with Bash if they were provided to you to ensure your code is correct. If you are unable to find the correct command, ask the user for the command to run and if they supply it, proactively suggest writing it to your memory so that you will know to run it next time.
5006
- NEVER commit changes unless the user explicitly asks you to. It is VERY IMPORTANT to only commit when explicitly asked, otherwise the user will feel that you are being too proactive.
5007
-
5008
- # Tool usage policy
5009
- - When doing file search, prefer to use the Task tool in order to reduce context usage.
5010
- - When WebFetch returns a message about a redirect to a different host, you should immediately make a new WebFetch request with the redirect URL provided in the response.
5011
- - You have the capability to call multiple tools in a single response. When multiple independent pieces of information are requested, batch your tool calls together for optimal performance. When making multiple bash tool calls, you MUST send a single message with multiple tools calls to run the calls in parallel. For example, if you need to run "git status" and "git diff", send a single message with two tool calls to run the calls in parallel.
5012
-
5013
- You MUST answer concisely with fewer than 4 lines of text (not including tool use or code generation), unless user asks for detail.
5014
-
5015
- IMPORTANT: Always use the TodoWrite tool to plan and track tasks throughout the conversation.
5016
-
5017
- # Code References
5018
-
5019
- When referencing specific functions or pieces of code include the pattern \`file_path:line_number\` to allow the user to easily navigate to the source code location.
5020
-
5021
- <example>
5022
- user: Where are errors from the client handled?
5023
- assistant: Clients are marked as failed in the \`connectToServer\` function in src/services/process.ts:712.
5024
- </example>
5025
- `;
5026
- var init_persona_claude = () => {};
5027
-
5028
4877
  // src/agent/prompts/persona_kawaii.mdx
5029
4878
  var persona_kawaii_default = `---
5030
4879
  label: persona
@@ -5276,16 +5125,57 @@ Your goal is to:
5276
5125
  `;
5277
5126
  var init_skill_creator_mode = () => {};
5278
5127
 
5279
- // src/agent/prompts/source_claude.md
5280
- var source_claude_default = `<!-- Source: Claude Code (Anthropic) -->
5281
- <!-- Version: ~v2.1.50 (Feb 2026) — assembled from modular prompt files -->
5282
- <!-- Reference: https://github.com/Piebald-AI/claude-code-system-prompts -->
5283
- <!-- Note: Since v2.1.20 the prompt is composed from ~110 atomic files at runtime. -->
5284
- <!-- This is the rendered assembly for a default session (no custom output style, -->
5285
- <!-- standard tools, TodoWrite present, Explore subagent available). -->
5286
- <!-- Dynamic session context (env block, directoryStructure, gitStatus) stripped. -->
5128
+ // src/agent/prompts/sleeptime.md
5129
+ var sleeptime_default = `I am a sleep-time memory management agent. I observe the conversation between the user and their primary agent, then actively maintain memory blocks to keep them accurate, concise, and useful.
5130
+
5131
+ **Core responsibilities:**
5132
+
5133
+ 1. **Update memory blocks in real-time** - Don't wait until end of session
5134
+ - Capture important facts, decisions, and context as they occur
5135
+ - Update existing information when it changes or becomes stale
5136
+ - Remove outdated or contradictory information immediately
5137
+
5138
+ 2. **Consolidate and refine memory continuously**
5139
+ - Merge duplicate or redundant information
5140
+ - Rewrite verbose entries into concise summaries
5141
+ - Reorganize memory blocks when structure becomes unclear
5142
+
5143
+ 3. **Identify and preserve patterns**
5144
+ - Track recurring themes, preferences, and behaviors
5145
+ - Note relationships between different pieces of information
5146
+ - Surface insights from conversation history
5147
+
5148
+ 4. **Maintain memory hygiene**
5149
+ - Keep memory blocks under size limits through aggressive consolidation
5150
+ - Prioritize recent and frequently-referenced information
5151
+ - Remove low-value details that don't contribute to agent effectiveness
5152
+
5153
+ 5. **Refine my own memory management approach**
5154
+ - Update this \`memory_persona\` block as I learn what works
5155
+ - Add user-specific memory policies when I identify patterns
5156
+ - Remove or adjust guidelines that don't match observed behavior
5157
+ - Adapt my consolidation strategy based on what the primary agent references most
5158
+
5159
+ **Operating rules:**
5160
+
5161
+ - If it was discussed, capture it somewhere in memory
5162
+ - Update memory during the session, not after
5163
+ - Be aggressive with edits - better to over-manage than under-manage
5164
+ - Assume the primary agent relies entirely on memory blocks for context
5165
+ - Every session should result in measurable memory improvements
5166
+ - Regularly evaluate and improve my own memory management policies
5167
+
5168
+ **DO NOT:**
5169
+ - Wait to batch all updates at session end
5170
+ - Skip memory edits because "nothing major happened"
5171
+ - Let memory blocks grow stale or bloated
5172
+ - Assume information will be captured later
5173
+ - Continue using memory policies that don't serve the user's actual needs
5174
+ `;
5175
+ var init_sleeptime = () => {};
5287
5176
 
5288
- You are Claude Code, Anthropic's official CLI for Claude.
5177
+ // src/agent/prompts/source_claude.md
5178
+ var source_claude_default = `You are Claude Code, Anthropic's official CLI for Claude.
5289
5179
 
5290
5180
  You are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
5291
5181
 
@@ -5416,14 +5306,7 @@ assistant: Clients are marked as failed in the \`connectToServer\` function in s
5416
5306
  var init_source_claude = () => {};
5417
5307
 
5418
5308
  // src/agent/prompts/source_codex.md
5419
- var source_codex_default = `<!-- Source: OpenAI Codex CLI (gpt-5.3-codex model) -->
5420
- <!-- Version: Extracted from codex-rs/core/models.json, base_instructions for gpt-5.3-codex -->
5421
- <!-- Reference: https://github.com/openai/codex -->
5422
- <!-- Note: gpt-5.3-codex is the latest model. Its prompt differs significantly from the -->
5423
- <!-- older gpt-5.1-codex-max_prompt.md file: adds Personality section, commentary/final -->
5424
- <!-- channels, intermediary updates, and removes the Plan tool section. -->
5425
-
5426
- You are Codex, a coding agent based on GPT-5. You and the user share the same workspace and collaborate to achieve the user's goals.
5309
+ var source_codex_default = `You are Codex, a coding agent based on GPT-5. You and the user share the same workspace and collaborate to achieve the user's goals.
5427
5310
 
5428
5311
  # Personality
5429
5312
 
@@ -5541,14 +5424,7 @@ Unless the user explicitly asks for a plan, asks a question about the code, is b
5541
5424
  var init_source_codex = () => {};
5542
5425
 
5543
5426
  // src/agent/prompts/source_gemini.md
5544
- var source_gemini_default = `<!-- Source: Gemini CLI (Google) -->
5545
- <!-- Version: snippets.ts (Feb 2026, copyright 2026 Google LLC) -->
5546
- <!-- Reference: https://github.com/google-gemini/gemini-cli/blob/main/packages/core/src/prompts/snippets.ts -->
5547
- <!-- Rendered for: Interactive mode, git repo present, outside sandbox, standard tools, -->
5548
- <!-- no sub-agents, no skills, no YOLO mode, no approved plan. Tool name variables resolved. -->
5549
- <!-- Conditional sections (YOLO mode, Plan mode, sandbox, GEMINI.md) noted but not inlined. -->
5550
-
5551
- You are Gemini CLI, an interactive CLI agent specializing in software engineering tasks. Your primary goal is to help users safely and effectively.
5427
+ var source_gemini_default = `You are Gemini CLI, an interactive CLI agent specializing in software engineering tasks. Your primary goal is to help users safely and effectively.
5552
5428
 
5553
5429
  # Core Mandates
5554
5430
 
@@ -5699,13 +5575,8 @@ For example, if they mention "never git commit without asking me first", I shoul
5699
5575
  `;
5700
5576
  var init_style = () => {};
5701
5577
 
5702
- // src/agent/prompts/system_prompt_memfs.txt
5703
- var system_prompt_memfs_default = "\n# Memory\n\nYour memory is stored in a git repository at `$MEMORY_DIR` (absolute path provided by Letta Code shell tools; usually `~/.letta/agents/$AGENT_ID/memory/`). This provides full version control, sync with the server, and worktrees for parallel edits. All memory files are markdown with YAML frontmatter (`description`, `limit`, optional `metadata`). The `description` field enables progressive disclosure — like skills, you see descriptions in your prompt and load full contents on demand; `limit` caps file size to keep system memory lean.\n\n## Memory layout\n\n**System memory** (`memory/system/`): Every `.md` file here is pinned directly into your system prompt — you see it at all times. This is your most valuable real estate: reserve it for durable knowledge that helps across sessions (user identity, persona, project architecture, conventions, gotchas). Do NOT store transient items here like specific commits, current work items, or session-specific notes — those dilute the signal.\n\n**Progressive memory**: Files outside `system/` are stored but not pinned in-context. Access them with standard file tools when you need deeper reference material — good for large notes, historical records, transient work tracking, or data that doesn't need to be always-visible.\n\n**Recall** (conversation history): Your full message history is searchable even after messages leave your context window. Use the recall subagent to retrieve past discussions, decisions, and context from earlier sessions.\n\n## How files map to your prompt\n\n1. Each `.md` file in `memory/system/` is pinned to your system prompt with tags <system/context/{name}.md></system/context/{name}.md>\n2. The `memory_filesystem` block renders the current tree view of all available memory files\n3. The system prompt is only recompiled on compactions or message resets — your local edits take effect on the next recompilation\n\n## Syncing\n\nChanges you commit and push sync to the Letta server within seconds, and server-side changes sync back automatically.\n\n```bash\ncd \"$MEMORY_DIR\"\n\n# See what changed\ngit status\n\n# Commit and push your changes\ngit add .\ngit commit -m \"<type>: <what changed>\" # e.g. \"fix: update user prefs\", \"refactor: reorganize persona blocks\"\ngit push\n\n# Get latest from server\ngit pull\n```\nThe system will remind you when your memory has uncommitted changes. Sync when convenient.\n\n## History\n```bash\ngit -C \"$MEMORY_DIR\" log --oneline\n```\n";
5704
- var init_system_prompt_memfs = () => {};
5705
-
5706
- // src/agent/prompts/system_prompt_memory.txt
5707
- var system_prompt_memory_default = `
5708
- # Memory
5578
+ // src/agent/prompts/system_prompt_blocks.md
5579
+ var system_prompt_blocks_default = `# Memory
5709
5580
 
5710
5581
  You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
5711
5582
  Your memory consists of core memory (composed of memory blocks) and external memory:
@@ -5718,7 +5589,11 @@ Memory blocks are stored in a *virtual filesystem* along with the rest of your a
5718
5589
 
5719
5590
  When applying memory in responses, integrate it naturally — like a colleague who recalls shared context without narrating their thought process. Apply memory when it's relevant: the user asks for personalization, references past context, or the task benefits from stored preferences/conventions. Don't apply memory for generic questions where personal details would be irrelevant, and for simple greetings use only their name at most. Never draw attention to the memory system itself or use phrases like "I remember that...", "Based on my memory...", or "Looking at your preferences..." — just use what you know seamlessly.
5720
5591
  `;
5721
- var init_system_prompt_memory = () => {};
5592
+ var init_system_prompt_blocks = () => {};
5593
+
5594
+ // src/agent/prompts/system_prompt_memfs.md
5595
+ var system_prompt_memfs_default = "# Memory\n\nYour memory is stored in a git repository at `$MEMORY_DIR` (absolute path provided by Letta Code shell tools; usually `~/.letta/agents/$AGENT_ID/memory/`). This provides full version control, sync with the server, and worktrees for parallel edits. All memory files are markdown with YAML frontmatter (`description`, `limit`, optional `metadata`). The `description` field enables progressive disclosure — like skills, you see descriptions in your prompt and load full contents on demand; `limit` caps file size to keep system memory lean.\n\n## Memory layout\n\n**System memory** (`memory/system/`): Every `.md` file here is pinned directly into your system prompt — you see it at all times. This is your most valuable real estate: reserve it for durable knowledge that helps across sessions (user identity, persona, project architecture, conventions, gotchas). Do NOT store transient items here like specific commits, current work items, or session-specific notes — those dilute the signal.\n\n**Progressive memory**: Files outside `system/` are stored but not pinned in-context. Access them with standard file tools when you need deeper reference material — good for large notes, historical records, transient work tracking, or data that doesn't need to be always-visible.\n\n**Recall** (conversation history): Your full message history is searchable even after messages leave your context window. Use the recall subagent to retrieve past discussions, decisions, and context from earlier sessions.\n\n## How files map to your prompt\n\n1. Each `.md` file in `memory/system/` is pinned to your system prompt with tags <system/context/{name}.md></system/context/{name}.md>\n2. The `memory_filesystem` block renders the current tree view of all available memory files\n3. The system prompt is only recompiled on compactions or message resets — your local edits take effect on the next recompilation\n\n## Syncing\n\nChanges you commit and push sync to the Letta server within seconds, and server-side changes sync back automatically.\n\n```bash\ncd \"$MEMORY_DIR\"\n\n# See what changed\ngit status\n\n# Commit and push your changes\ngit add .\ngit commit -m \"<type>: <what changed>\" # e.g. \"fix: update user prefs\", \"refactor: reorganize persona blocks\"\ngit push\n\n# Get latest from server\ngit pull\n```\nThe system will remind you when your memory has uncommitted changes. Sync when convenient.\n\n## History\n```bash\ngit -C \"$MEMORY_DIR\" log --oneline\n```\n";
5596
+ var init_system_prompt_memfs = () => {};
5722
5597
 
5723
5598
  // src/utils/error.ts
5724
5599
  function getErrorMessage2(error) {
@@ -6840,10 +6715,11 @@ __export(exports_promptAssets, {
6840
6715
  resolveAndBuildSystemPrompt: () => resolveAndBuildSystemPrompt,
6841
6716
  isKnownPreset: () => isKnownPreset,
6842
6717
  buildSystemPrompt: () => buildSystemPrompt,
6843
- SYSTEM_PROMPT_MEMORY_ADDON: () => SYSTEM_PROMPT_MEMORY_ADDON,
6844
6718
  SYSTEM_PROMPT_MEMFS_ADDON: () => SYSTEM_PROMPT_MEMFS_ADDON,
6719
+ SYSTEM_PROMPT_BLOCKS_ADDON: () => SYSTEM_PROMPT_BLOCKS_ADDON,
6845
6720
  SYSTEM_PROMPTS: () => SYSTEM_PROMPTS,
6846
6721
  SYSTEM_PROMPT: () => SYSTEM_PROMPT,
6722
+ SLEEPTIME_MEMORY_PERSONA: () => SLEEPTIME_MEMORY_PERSONA,
6847
6723
  SKILL_CREATOR_PROMPT: () => SKILL_CREATOR_PROMPT,
6848
6724
  REMEMBER_PROMPT: () => REMEMBER_PROMPT,
6849
6725
  PLAN_MODE_REMINDER: () => PLAN_MODE_REMINDER,
@@ -6910,7 +6786,7 @@ function buildSystemPrompt(presetId, memoryMode) {
6910
6786
  if (!preset) {
6911
6787
  throw new Error(`Unknown preset "${presetId}" — cannot rebuild system prompt`);
6912
6788
  }
6913
- const addon = memoryMode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON : SYSTEM_PROMPT_MEMORY_ADDON;
6789
+ const addon = memoryMode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON : SYSTEM_PROMPT_BLOCKS_ADDON;
6914
6790
  return `${preset.content.trimEnd()}
6915
6791
 
6916
6792
  ${addon.trimStart()}`.trim();
@@ -6918,7 +6794,7 @@ ${addon.trimStart()}`.trim();
6918
6794
  function swapMemoryAddon(systemPrompt, mode) {
6919
6795
  let result = systemPrompt;
6920
6796
  for (const addon of [
6921
- SYSTEM_PROMPT_MEMORY_ADDON.trim(),
6797
+ SYSTEM_PROMPT_BLOCKS_ADDON.trim(),
6922
6798
  SYSTEM_PROMPT_MEMFS_ADDON.trim()
6923
6799
  ]) {
6924
6800
  result = result.replaceAll(addon, "");
@@ -6934,7 +6810,7 @@ function swapMemoryAddon(systemPrompt, mode) {
6934
6810
  result = result.replace(/\n{3,}/g, `
6935
6811
 
6936
6812
  `).trimEnd();
6937
- const target = mode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON : SYSTEM_PROMPT_MEMORY_ADDON;
6813
+ const target = mode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON : SYSTEM_PROMPT_BLOCKS_ADDON;
6938
6814
  return `${result}
6939
6815
 
6940
6816
  ${target.trimStart()}`.trim();
@@ -6981,7 +6857,7 @@ async function resolveSystemPrompt(systemPromptPreset) {
6981
6857
  }
6982
6858
  throw new Error(`Unknown system prompt "${systemPromptPreset}" — does not match any preset or subagent`);
6983
6859
  }
6984
- var SYSTEM_PROMPT, SYSTEM_PROMPT_MEMORY_ADDON, SYSTEM_PROMPT_MEMFS_ADDON, PLAN_MODE_REMINDER, SKILL_CREATOR_PROMPT, REMEMBER_PROMPT, MEMORY_CHECK_REMINDER, APPROVAL_RECOVERY_PROMPT, AUTO_INIT_REMINDER, INTERRUPT_RECOVERY_ALERT, MEMORY_PROMPTS, SYSTEM_PROMPTS;
6860
+ var SYSTEM_PROMPT, SYSTEM_PROMPT_BLOCKS_ADDON, SYSTEM_PROMPT_MEMFS_ADDON, PLAN_MODE_REMINDER, SKILL_CREATOR_PROMPT, REMEMBER_PROMPT, MEMORY_CHECK_REMINDER, APPROVAL_RECOVERY_PROMPT, AUTO_INIT_REMINDER, INTERRUPT_RECOVERY_ALERT, SLEEPTIME_MEMORY_PERSONA, MEMORY_PROMPTS, SYSTEM_PROMPTS;
6985
6861
  var init_promptAssets = __esm(() => {
6986
6862
  init_approval_recovery_alert();
6987
6863
  init_auto_init_reminder();
@@ -6991,21 +6867,21 @@ var init_promptAssets = __esm(() => {
6991
6867
  init_memory_check_reminder();
6992
6868
  init_memory_filesystem();
6993
6869
  init_persona();
6994
- init_persona_claude();
6995
6870
  init_persona_kawaii();
6996
6871
  init_persona_memo();
6997
6872
  init_plan_mode_reminder();
6998
6873
  init_project();
6999
6874
  init_remember();
7000
6875
  init_skill_creator_mode();
6876
+ init_sleeptime();
7001
6877
  init_source_claude();
7002
6878
  init_source_codex();
7003
6879
  init_source_gemini();
7004
6880
  init_style();
6881
+ init_system_prompt_blocks();
7005
6882
  init_system_prompt_memfs();
7006
- init_system_prompt_memory();
7007
6883
  SYSTEM_PROMPT = letta_default;
7008
- SYSTEM_PROMPT_MEMORY_ADDON = system_prompt_memory_default;
6884
+ SYSTEM_PROMPT_BLOCKS_ADDON = system_prompt_blocks_default;
7009
6885
  SYSTEM_PROMPT_MEMFS_ADDON = system_prompt_memfs_default;
7010
6886
  PLAN_MODE_REMINDER = plan_mode_reminder_default;
7011
6887
  SKILL_CREATOR_PROMPT = skill_creator_mode_default;
@@ -7014,9 +6890,9 @@ var init_promptAssets = __esm(() => {
7014
6890
  APPROVAL_RECOVERY_PROMPT = approval_recovery_alert_default;
7015
6891
  AUTO_INIT_REMINDER = auto_init_reminder_default;
7016
6892
  INTERRUPT_RECOVERY_ALERT = interrupt_recovery_alert_default;
6893
+ SLEEPTIME_MEMORY_PERSONA = sleeptime_default;
7017
6894
  MEMORY_PROMPTS = {
7018
6895
  "persona.mdx": persona_default,
7019
- "persona_claude.mdx": persona_claude_default,
7020
6896
  "persona_kawaii.mdx": persona_kawaii_default,
7021
6897
  "persona_memo.mdx": persona_memo_default,
7022
6898
  "human.mdx": human_default,
@@ -36112,18 +35988,20 @@ var require_picomatch = __commonJS((exports, module) => {
36112
35988
  });
36113
35989
 
36114
35990
  // src/cli/helpers/ignoredDirectories.ts
36115
- import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
35991
+ import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
36116
35992
  import { join as join5 } from "node:path";
36117
35993
  function ensureLettaIgnoreFile(cwd2 = process.cwd()) {
36118
- const filePath = join5(cwd2, ".lettaignore");
35994
+ const lettaDir = join5(cwd2, ".letta");
35995
+ const filePath = join5(lettaDir, ".lettaignore");
36119
35996
  if (existsSync6(filePath))
36120
35997
  return;
36121
35998
  try {
35999
+ mkdirSync4(lettaDir, { recursive: true });
36122
36000
  writeFileSync2(filePath, DEFAULT_LETTAIGNORE, "utf-8");
36123
36001
  } catch {}
36124
36002
  }
36125
36003
  function readLettaIgnorePatterns(cwd2 = process.cwd()) {
36126
- const filePath = join5(cwd2, ".lettaignore");
36004
+ const filePath = join5(cwd2, ".letta", ".lettaignore");
36127
36005
  if (!existsSync6(filePath))
36128
36006
  return [];
36129
36007
  try {
@@ -36140,37 +36018,79 @@ function parseLettaIgnore(content) {
36140
36018
  var DEFAULT_LETTAIGNORE = `# .lettaignore — Letta Code file index exclusions
36141
36019
  #
36142
36020
  # Files and directories matching these patterns are excluded from the @ file
36143
- # search index (cache). They won't appear in autocomplete results by default,
36144
- # but can still be found if you type their path explicitly.
36021
+ # search index and disk scan fallback. Comment out or remove a line to bring
36022
+ # it back into search results. Add new patterns to exclude more.
36145
36023
  #
36146
36024
  # Syntax: one pattern per line, supports globs (e.g. *.log, src/generated/**)
36147
36025
  # Lines starting with # are comments.
36148
36026
  #
36149
- # The following are always excluded (even from explicit search) and do not need
36150
- # to be listed here:
36151
- # node_modules dist build out coverage target bower_components
36152
- # .git .cache .next .nuxt venv .venv __pycache__ .tox
36153
-
36154
- # Lock files
36027
+ # --- Dependency directories ---
36028
+ node_modules
36029
+ bower_components
36030
+ vendor
36031
+
36032
+ # --- Build outputs ---
36033
+ dist
36034
+ build
36035
+ out
36036
+ coverage
36037
+ target
36038
+ .next
36039
+ .nuxt
36040
+
36041
+ # --- Python ---
36042
+ venv
36043
+ .venv
36044
+ __pycache__
36045
+ .tox
36046
+
36047
+ # --- Version control & tooling ---
36048
+ .git
36049
+ .cache
36050
+ .letta
36051
+
36052
+ # --- Lock files ---
36155
36053
  package-lock.json
36156
36054
  yarn.lock
36157
36055
  pnpm-lock.yaml
36158
36056
  poetry.lock
36159
36057
  Cargo.lock
36160
36058
 
36161
- # Logs
36059
+ # --- Logs ---
36162
36060
  *.log
36163
36061
 
36164
- # OS artifacts
36062
+ # --- OS artifacts ---
36165
36063
  .DS_Store
36166
36064
  Thumbs.db
36167
36065
  `;
36168
36066
  var init_ignoredDirectories = () => {};
36169
36067
 
36170
36068
  // src/cli/helpers/fileSearchConfig.ts
36069
+ function buildConfig(cwd2) {
36070
+ const patterns = readLettaIgnorePatterns(cwd2);
36071
+ const nameMatchers = [];
36072
+ const pathMatchers = [];
36073
+ for (const raw of patterns) {
36074
+ const normalized = raw.replace(/\/$/, "");
36075
+ if (normalized.includes("/")) {
36076
+ pathMatchers.push(import_picomatch.default(normalized, { dot: true }));
36077
+ } else {
36078
+ nameMatchers.push(import_picomatch.default(normalized, { dot: true, nocase: true }));
36079
+ }
36080
+ }
36081
+ return { nameMatchers, pathMatchers };
36082
+ }
36083
+ function getConfig() {
36084
+ const cwd2 = process.cwd();
36085
+ const cached = cwdConfigCache.get(cwd2);
36086
+ if (cached)
36087
+ return cached;
36088
+ const config = buildConfig(cwd2);
36089
+ cwdConfigCache.set(cwd2, config);
36090
+ return config;
36091
+ }
36171
36092
  function shouldExcludeEntry(name, relativePath) {
36172
- if (DEFAULT_EXCLUDED.has(name.toLowerCase()))
36173
- return true;
36093
+ const { nameMatchers, pathMatchers } = getConfig();
36174
36094
  if (nameMatchers.length > 0 && nameMatchers.some((m) => m(name)))
36175
36095
  return true;
36176
36096
  if (relativePath && pathMatchers.length > 0 && pathMatchers.some((m) => m(relativePath)))
@@ -36178,44 +36098,19 @@ function shouldExcludeEntry(name, relativePath) {
36178
36098
  return false;
36179
36099
  }
36180
36100
  function shouldHardExcludeEntry(name) {
36181
- return DEFAULT_EXCLUDED.has(name.toLowerCase());
36101
+ const { nameMatchers } = getConfig();
36102
+ return nameMatchers.length > 0 && nameMatchers.some((m) => m(name));
36182
36103
  }
36183
- var import_picomatch, DEFAULT_EXCLUDED, nameMatchers, pathMatchers;
36104
+ var import_picomatch, cwdConfigCache;
36184
36105
  var init_fileSearchConfig = __esm(() => {
36185
36106
  init_ignoredDirectories();
36186
36107
  import_picomatch = __toESM(require_picomatch(), 1);
36187
- DEFAULT_EXCLUDED = new Set([
36188
- "node_modules",
36189
- "bower_components",
36190
- "dist",
36191
- "build",
36192
- "out",
36193
- "coverage",
36194
- ".next",
36195
- ".nuxt",
36196
- "venv",
36197
- ".venv",
36198
- "__pycache__",
36199
- ".tox",
36200
- "target",
36201
- ".git",
36202
- ".cache"
36203
- ]);
36204
- ({ nameMatchers, pathMatchers } = (() => {
36205
- ensureLettaIgnoreFile();
36206
- const patterns = readLettaIgnorePatterns();
36207
- const nameMatchers2 = [];
36208
- const pathMatchers2 = [];
36209
- for (const raw of patterns) {
36210
- const normalized = raw.replace(/\/$/, "");
36211
- if (normalized.includes("/")) {
36212
- pathMatchers2.push(import_picomatch.default(normalized, { dot: true }));
36213
- } else {
36214
- nameMatchers2.push(import_picomatch.default(normalized, { dot: true }));
36215
- }
36216
- }
36217
- return { nameMatchers: nameMatchers2, pathMatchers: pathMatchers2 };
36218
- })());
36108
+ cwdConfigCache = new Map;
36109
+ (() => {
36110
+ const cwd2 = process.cwd();
36111
+ ensureLettaIgnoreFile(cwd2);
36112
+ cwdConfigCache.set(cwd2, buildConfig(cwd2));
36113
+ })();
36219
36114
  });
36220
36115
 
36221
36116
  // src/agent/model.ts
@@ -39670,7 +39565,7 @@ var init_build4 = __esm(async () => {
39670
39565
  import { createHash as createHash2 } from "node:crypto";
39671
39566
  import {
39672
39567
  existsSync as existsSync9,
39673
- mkdirSync as mkdirSync6,
39568
+ mkdirSync as mkdirSync7,
39674
39569
  readdirSync as readdirSync4,
39675
39570
  readFileSync as readFileSync6,
39676
39571
  statSync as statSync2,
@@ -39880,7 +39775,7 @@ async function buildDirectory2(dir, relativePath, entries, merkle, statsMap, pre
39880
39775
  return previous.merkle[relativePath] ?? hashValue2("__reused__");
39881
39776
  }
39882
39777
  statsMap[relativePath] = currentStats;
39883
- if (depth >= MAX_INDEX_DEPTH2) {
39778
+ if (depth >= MAX_INDEX_DEPTH2 || context2.newEntryCount >= MAX_CACHE_ENTRIES2) {
39884
39779
  context2.truncated = true;
39885
39780
  const truncatedHash = hashValue2("__truncated__");
39886
39781
  merkle[relativePath] = truncatedHash;
@@ -39888,6 +39783,10 @@ async function buildDirectory2(dir, relativePath, entries, merkle, statsMap, pre
39888
39783
  }
39889
39784
  const childHashes = [];
39890
39785
  for (const entry of childNames) {
39786
+ if (context2.newEntryCount >= MAX_CACHE_ENTRIES2) {
39787
+ context2.truncated = true;
39788
+ break;
39789
+ }
39891
39790
  if (context2.newEntryCount > 0 && context2.newEntryCount % 500 === 0) {
39892
39791
  await new Promise((resolve2) => setImmediate(resolve2));
39893
39792
  }
@@ -39969,7 +39868,7 @@ function getProjectStorageDir2() {
39969
39868
  function ensureProjectStorageDir2() {
39970
39869
  const storageDir = getProjectStorageDir2();
39971
39870
  if (!existsSync9(storageDir)) {
39972
- mkdirSync6(storageDir, { recursive: true });
39871
+ mkdirSync7(storageDir, { recursive: true });
39973
39872
  }
39974
39873
  return storageDir;
39975
39874
  }
@@ -43063,7 +42962,7 @@ import { execFile as execFileCb } from "node:child_process";
43063
42962
  import {
43064
42963
  chmodSync,
43065
42964
  existsSync as existsSync10,
43066
- mkdirSync as mkdirSync7,
42965
+ mkdirSync as mkdirSync8,
43067
42966
  renameSync,
43068
42967
  rmSync,
43069
42968
  writeFileSync as writeFileSync5
@@ -43130,7 +43029,7 @@ function installPreCommitHook(dir) {
43130
43029
  const hooksDir = join9(dir, ".git", "hooks");
43131
43030
  const hookPath = join9(hooksDir, "pre-commit");
43132
43031
  if (!existsSync10(hooksDir)) {
43133
- mkdirSync7(hooksDir, { recursive: true });
43032
+ mkdirSync8(hooksDir, { recursive: true });
43134
43033
  }
43135
43034
  writeFileSync5(hookPath, PRE_COMMIT_HOOK_SCRIPT, "utf-8");
43136
43035
  chmodSync(hookPath, 493);
@@ -43145,7 +43044,7 @@ async function cloneMemoryRepo(agentId) {
43145
43044
  const dir = getMemoryRepoDir(agentId);
43146
43045
  debugLog("memfs-git", `Cloning ${url} → ${dir}`);
43147
43046
  if (!existsSync10(dir)) {
43148
- mkdirSync7(dir, { recursive: true });
43047
+ mkdirSync8(dir, { recursive: true });
43149
43048
  await runGit(dir, ["clone", url, "."], token);
43150
43049
  } else if (!existsSync10(join9(dir, ".git"))) {
43151
43050
  const tmpDir = `${dir}-git-clone-tmp`;
@@ -43153,7 +43052,7 @@ async function cloneMemoryRepo(agentId) {
43153
43052
  if (existsSync10(tmpDir)) {
43154
43053
  rmSync(tmpDir, { recursive: true, force: true });
43155
43054
  }
43156
- mkdirSync7(tmpDir, { recursive: true });
43055
+ mkdirSync8(tmpDir, { recursive: true });
43157
43056
  await runGit(tmpDir, ["clone", url, "."], token);
43158
43057
  renameSync(join9(tmpDir, ".git"), join9(dir, ".git"));
43159
43058
  await runGit(dir, ["checkout", "--", "."], token);
@@ -43552,17 +43451,15 @@ async function updateConversationLLMConfig(conversationId, modelHandle, updateAr
43552
43451
  };
43553
43452
  return client.conversations.update(conversationId, payload);
43554
43453
  }
43555
- async function recompileAgentSystemPrompt(conversationId, options = {}, clientOverride) {
43454
+ async function recompileAgentSystemPrompt(conversationId, agentId, dryRun, clientOverride) {
43556
43455
  const client = clientOverride ?? await getClient2();
43456
+ if (!agentId) {
43457
+ throw new Error("recompileAgentSystemPrompt requires agentId");
43458
+ }
43557
43459
  const params = {
43558
- dry_run: options.dryRun
43460
+ dry_run: dryRun,
43461
+ agent_id: agentId
43559
43462
  };
43560
- if (conversationId === "default") {
43561
- if (!options.agentId) {
43562
- throw new Error('recompileAgentSystemPrompt requires options.agentId when conversationId is "default"');
43563
- }
43564
- params.agent_id = options.agentId;
43565
- }
43566
43463
  return client.conversations.recompile(conversationId, params);
43567
43464
  }
43568
43465
  async function updateAgentSystemPromptRaw2(agentId, systemPromptContent) {
@@ -43875,7 +43772,7 @@ __export(exports_memoryFilesystem, {
43875
43772
  MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR,
43876
43773
  MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR
43877
43774
  });
43878
- import { existsSync as existsSync11, mkdirSync as mkdirSync8 } from "node:fs";
43775
+ import { existsSync as existsSync11, mkdirSync as mkdirSync9 } from "node:fs";
43879
43776
  import { homedir as homedir10 } from "node:os";
43880
43777
  import { join as join10 } from "node:path";
43881
43778
  function getMemoryFilesystemRoot(agentId, homeDir = homedir10()) {
@@ -43888,10 +43785,10 @@ function ensureMemoryFilesystemDirs(agentId, homeDir = homedir10()) {
43888
43785
  const root = getMemoryFilesystemRoot(agentId, homeDir);
43889
43786
  const systemDir = getMemorySystemDir(agentId, homeDir);
43890
43787
  if (!existsSync11(root)) {
43891
- mkdirSync8(root, { recursive: true });
43788
+ mkdirSync9(root, { recursive: true });
43892
43789
  }
43893
43790
  if (!existsSync11(systemDir)) {
43894
- mkdirSync8(systemDir, { recursive: true });
43791
+ mkdirSync9(systemDir, { recursive: true });
43895
43792
  }
43896
43793
  }
43897
43794
  function labelFromRelativePath(relativePath) {
@@ -44038,7 +43935,7 @@ __export(exports_shellEnv, {
44038
43935
  getShellEnv: () => getShellEnv,
44039
43936
  ensureLettaShimDir: () => ensureLettaShimDir
44040
43937
  });
44041
- import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync6 } from "node:fs";
43938
+ import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync6 } from "node:fs";
44042
43939
  import { createRequire as createRequire2 } from "node:module";
44043
43940
  import { tmpdir } from "node:os";
44044
43941
  import * as path4 from "node:path";
@@ -44111,7 +44008,7 @@ function ensureLettaShimDir(invocation) {
44111
44008
  if (!invocation.command)
44112
44009
  return null;
44113
44010
  const shimDir = path4.join(tmpdir(), "letta-code-shell-shim");
44114
- mkdirSync9(shimDir, { recursive: true });
44011
+ mkdirSync10(shimDir, { recursive: true });
44115
44012
  if (process.platform === "win32") {
44116
44013
  const cmdPath = path4.join(shimDir, "letta.cmd");
44117
44014
  const quotedCommand = `"${invocation.command.replaceAll('"', '""')}"`;
@@ -69723,7 +69620,7 @@ var init_approvalClassification = __esm(async () => {
69723
69620
  // src/cli/helpers/chunkLog.ts
69724
69621
  import {
69725
69622
  existsSync as existsSync14,
69726
- mkdirSync as mkdirSync11,
69623
+ mkdirSync as mkdirSync12,
69727
69624
  readdirSync as readdirSync8,
69728
69625
  unlinkSync as unlinkSync5,
69729
69626
  writeFileSync as writeFileSync9
@@ -69824,7 +69721,7 @@ class ChunkLog {
69824
69721
  return;
69825
69722
  try {
69826
69723
  if (!existsSync14(this.agentDir)) {
69827
- mkdirSync11(this.agentDir, { recursive: true });
69724
+ mkdirSync12(this.agentDir, { recursive: true });
69828
69725
  }
69829
69726
  this.dirCreated = true;
69830
69727
  } catch (e) {
@@ -72003,8 +71900,83 @@ var init_memoryReminder = __esm(async () => {
72003
71900
  };
72004
71901
  });
72005
71902
 
71903
+ // src/cli/helpers/gitContext.ts
71904
+ import { execFileSync as execFileSync2 } from "node:child_process";
71905
+ function runGit2(args, cwd2) {
71906
+ try {
71907
+ return execFileSync2("git", args, {
71908
+ cwd: cwd2,
71909
+ encoding: "utf-8",
71910
+ stdio: ["ignore", "pipe", "ignore"]
71911
+ }).trim();
71912
+ } catch {
71913
+ return null;
71914
+ }
71915
+ }
71916
+ function truncateLines(value, maxLines) {
71917
+ const lines = value.split(`
71918
+ `);
71919
+ if (lines.length <= maxLines) {
71920
+ return value;
71921
+ }
71922
+ return lines.slice(0, maxLines).join(`
71923
+ `) + `
71924
+ ... and ${lines.length - maxLines} more changes`;
71925
+ }
71926
+ function formatGitUser(name, email) {
71927
+ if (!name && !email) {
71928
+ return null;
71929
+ }
71930
+ if (name && email) {
71931
+ return `${name} <${email}>`;
71932
+ }
71933
+ return name || email;
71934
+ }
71935
+ function gatherGitContextSnapshot(options = {}) {
71936
+ const cwd2 = options.cwd ?? process.cwd();
71937
+ const recentCommitLimit = options.recentCommitLimit ?? 3;
71938
+ if (!runGit2(["rev-parse", "--git-dir"], cwd2)) {
71939
+ return {
71940
+ isGitRepo: false,
71941
+ branch: null,
71942
+ status: null,
71943
+ recentCommits: null,
71944
+ gitUser: null
71945
+ };
71946
+ }
71947
+ const branch = runGit2(["branch", "--show-current"], cwd2);
71948
+ const fullStatus = runGit2(["status", "--short"], cwd2);
71949
+ const status = typeof fullStatus === "string" && options.statusLineLimit ? truncateLines(fullStatus, options.statusLineLimit) : fullStatus;
71950
+ const recentCommits = options.recentCommitFormat ? runGit2([
71951
+ "log",
71952
+ `--format=${options.recentCommitFormat}`,
71953
+ "-n",
71954
+ String(recentCommitLimit)
71955
+ ], cwd2) : runGit2(["log", "--oneline", "-n", String(recentCommitLimit)], cwd2);
71956
+ const userConfig = runGit2(["config", "--get-regexp", "^user\\.(name|email)$"], cwd2);
71957
+ let userName = null;
71958
+ let userEmail = null;
71959
+ if (userConfig) {
71960
+ for (const line of userConfig.split(`
71961
+ `)) {
71962
+ if (line.startsWith("user.name "))
71963
+ userName = line.slice("user.name ".length);
71964
+ else if (line.startsWith("user.email "))
71965
+ userEmail = line.slice("user.email ".length);
71966
+ }
71967
+ }
71968
+ const gitUser = formatGitUser(userName, userEmail);
71969
+ return {
71970
+ isGitRepo: true,
71971
+ branch,
71972
+ status,
71973
+ recentCommits,
71974
+ gitUser
71975
+ };
71976
+ }
71977
+ var init_gitContext = () => {};
71978
+
72006
71979
  // src/cli/helpers/sessionContext.ts
72007
- import { execSync as execSync2 } from "node:child_process";
72008
71980
  import { platform as platform3 } from "node:os";
72009
71981
  function getLocalTime() {
72010
71982
  const now = new Date;
@@ -72031,37 +72003,22 @@ function getDeviceType() {
72031
72003
  return p;
72032
72004
  }
72033
72005
  }
72034
- function safeGitExec(command, cwd2) {
72035
- try {
72036
- return execSync2(command, { cwd: cwd2, encoding: "utf-8", stdio: "pipe" }).trim();
72037
- } catch {
72038
- return null;
72039
- }
72040
- }
72041
72006
  function getGitInfo() {
72042
- const cwd2 = process.cwd();
72043
- try {
72044
- execSync2("git rev-parse --git-dir", { cwd: cwd2, stdio: "pipe" });
72045
- const branch = safeGitExec("git branch --show-current", cwd2) ?? "(unknown)";
72046
- const recentCommits = safeGitExec('git log --format="%h %s (%an)" -3', cwd2) ?? "(failed to get commits)";
72047
- const fullStatus = safeGitExec("git status --short", cwd2) ?? "(failed to get status)";
72048
- const statusLines = fullStatus.split(`
72049
- `);
72050
- let status = fullStatus;
72051
- if (statusLines.length > 20) {
72052
- status = statusLines.slice(0, 20).join(`
72053
- `) + `
72054
- ... and ${statusLines.length - 20} more files`;
72055
- }
72056
- return {
72057
- isGitRepo: true,
72058
- branch,
72059
- recentCommits,
72060
- status: status || "(clean working tree)"
72061
- };
72062
- } catch {
72007
+ const git = gatherGitContextSnapshot({
72008
+ recentCommitLimit: 3,
72009
+ recentCommitFormat: "%h %s (%an)",
72010
+ statusLineLimit: 20
72011
+ });
72012
+ if (!git.isGitRepo) {
72063
72013
  return { isGitRepo: false };
72064
72014
  }
72015
+ return {
72016
+ isGitRepo: true,
72017
+ branch: git.branch ?? "(unknown)",
72018
+ recentCommits: git.recentCommits ?? "(failed to get commits)",
72019
+ status: git.status || "(clean working tree)",
72020
+ gitUser: git.gitUser ?? "(not configured)"
72021
+ };
72065
72022
  }
72066
72023
  function buildSessionContext() {
72067
72024
  try {
@@ -72091,6 +72048,7 @@ The user has just initiated a new connection via the [Letta Code CLI client](htt
72091
72048
  `;
72092
72049
  if (gitInfo.isGitRepo) {
72093
72050
  context3 += `- **Git repository**: Yes (branch: ${gitInfo.branch})
72051
+ - **Git user**: ${gitInfo.gitUser}
72094
72052
 
72095
72053
  ### Recent Commits
72096
72054
  \`\`\`
@@ -72123,6 +72081,7 @@ ${gitInfo.status}
72123
72081
  var init_sessionContext = __esm(() => {
72124
72082
  init_constants();
72125
72083
  init_version();
72084
+ init_gitContext();
72126
72085
  });
72127
72086
 
72128
72087
  // src/reminders/catalog.ts
@@ -72998,7 +72957,7 @@ function loadPersistedCwdMap() {
72998
72957
  const cachePath = getCwdCachePath();
72999
72958
  if (!existsSync15(cachePath))
73000
72959
  return new Map;
73001
- const raw = __require("fs").readFileSync(cachePath, "utf-8");
72960
+ const raw = __require("node:fs").readFileSync(cachePath, "utf-8");
73002
72961
  const parsed = JSON.parse(raw);
73003
72962
  const map = new Map;
73004
72963
  for (const [key, value] of Object.entries(parsed)) {
@@ -73161,6 +73120,56 @@ function mergeDequeuedBatchContent(items) {
73161
73120
  normalizeUserContent: (content) => content
73162
73121
  });
73163
73122
  }
73123
+ function isBase64ImageContentPart(part) {
73124
+ if (!part || typeof part !== "object") {
73125
+ return false;
73126
+ }
73127
+ const candidate = part;
73128
+ return candidate.type === "image" && !!candidate.source && candidate.source.type === "base64" && typeof candidate.source.media_type === "string" && candidate.source.media_type.length > 0 && typeof candidate.source.data === "string" && candidate.source.data.length > 0;
73129
+ }
73130
+ async function normalizeMessageContentImages(content, resize = resizeImageIfNeeded3) {
73131
+ if (typeof content === "string") {
73132
+ return content;
73133
+ }
73134
+ let didChange = false;
73135
+ const normalizedParts = await Promise.all(content.map(async (part) => {
73136
+ if (!isBase64ImageContentPart(part)) {
73137
+ return part;
73138
+ }
73139
+ const resized = await resize(Buffer.from(part.source.data, "base64"), part.source.media_type);
73140
+ if (resized.data !== part.source.data || resized.mediaType !== part.source.media_type) {
73141
+ didChange = true;
73142
+ }
73143
+ return {
73144
+ ...part,
73145
+ source: {
73146
+ ...part.source,
73147
+ type: "base64",
73148
+ data: resized.data,
73149
+ media_type: resized.mediaType
73150
+ }
73151
+ };
73152
+ }));
73153
+ return didChange ? normalizedParts : content;
73154
+ }
73155
+ async function normalizeInboundMessages(messages, resize = resizeImageIfNeeded3) {
73156
+ let didChange = false;
73157
+ const normalizedMessages = await Promise.all(messages.map(async (message) => {
73158
+ if (!("content" in message)) {
73159
+ return message;
73160
+ }
73161
+ const normalizedContent = await normalizeMessageContentImages(message.content, resize);
73162
+ if (normalizedContent !== message.content) {
73163
+ didChange = true;
73164
+ return {
73165
+ ...message,
73166
+ content: normalizedContent
73167
+ };
73168
+ }
73169
+ return message;
73170
+ }));
73171
+ return didChange ? normalizedMessages : messages;
73172
+ }
73164
73173
  function getPrimaryQueueMessageItem(items) {
73165
73174
  for (const item of items) {
73166
73175
  if (item.kind === "message") {
@@ -73310,6 +73319,7 @@ function buildStateResponse(runtime, stateSeq, agentId, conversationId) {
73310
73319
  is_processing: runtime.isProcessing,
73311
73320
  last_stop_reason: runtime.lastStopReason,
73312
73321
  control_response_capable: true,
73322
+ tool_lifecycle_capable: true,
73313
73323
  active_run: {
73314
73324
  run_id: runtime.activeRunId,
73315
73325
  agent_id: runtime.activeAgentId,
@@ -73626,6 +73636,34 @@ function emitInterruptToolReturnMessage(socket, runtime, approvals, runId, uuidP
73626
73636
  });
73627
73637
  }
73628
73638
  }
73639
+ function emitToolExecutionStartedEvents(socket, runtime, params) {
73640
+ for (const toolCallId of params.toolCallIds) {
73641
+ emitToWS(socket, {
73642
+ type: "tool_execution_started",
73643
+ tool_call_id: toolCallId,
73644
+ ...params.runId ? { run_id: params.runId } : {},
73645
+ session_id: runtime.sessionId,
73646
+ uuid: `tool-exec-started-${toolCallId}`,
73647
+ agent_id: params.agentId,
73648
+ conversation_id: params.conversationId
73649
+ });
73650
+ }
73651
+ }
73652
+ function emitToolExecutionFinishedEvents(socket, runtime, params) {
73653
+ const toolReturns = extractInterruptToolReturns(params.approvals);
73654
+ for (const toolReturn of toolReturns) {
73655
+ emitToWS(socket, {
73656
+ type: "tool_execution_finished",
73657
+ tool_call_id: toolReturn.tool_call_id,
73658
+ status: toolReturn.status,
73659
+ ...params.runId ? { run_id: params.runId } : {},
73660
+ session_id: runtime.sessionId,
73661
+ uuid: `tool-exec-finished-${toolReturn.tool_call_id}`,
73662
+ agent_id: params.agentId,
73663
+ conversation_id: params.conversationId
73664
+ });
73665
+ }
73666
+ }
73629
73667
  function getInterruptApprovalsForEmission(runtime, params) {
73630
73668
  if (params.lastExecutionResults && params.lastExecutionResults.length > 0) {
73631
73669
  return params.lastExecutionResults;
@@ -74446,6 +74484,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
74446
74484
  if (connectionId) {
74447
74485
  onStatusChange?.("processing", connectionId);
74448
74486
  }
74487
+ const normalizedMessages = await normalizeInboundMessages(msg.messages);
74449
74488
  const messagesToSend = [];
74450
74489
  let turnToolContextId = null;
74451
74490
  let queuedInterruptedToolCallIds = [];
@@ -74454,8 +74493,8 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
74454
74493
  messagesToSend.push(consumed.approvalMessage);
74455
74494
  queuedInterruptedToolCallIds = consumed.interruptedToolCallIds;
74456
74495
  }
74457
- messagesToSend.push(...msg.messages);
74458
- const firstMessage = msg.messages[0];
74496
+ messagesToSend.push(...normalizedMessages);
74497
+ const firstMessage = normalizedMessages[0];
74459
74498
  const isApprovalMessage = firstMessage && "type" in firstMessage && firstMessage.type === "approval" && "approvals" in firstMessage;
74460
74499
  if (!isApprovalMessage) {
74461
74500
  const { parts: reminderParts } = await buildSharedReminderParts(buildListenReminderContext({
@@ -74710,6 +74749,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
74710
74749
  for (const ac of needsUserInput) {
74711
74750
  const requestId = `perm-${ac.approval.toolCallId}`;
74712
74751
  const diffs = await computeDiffPreviews(ac.approval.toolName, ac.parsedArgs, turnWorkingDirectory);
74752
+ const lifecycleRunId = runId || runtime.activeRunId || msgRunIds[msgRunIds.length - 1];
74713
74753
  const controlRequest = {
74714
74754
  type: "control_request",
74715
74755
  request_id: requestId,
@@ -74725,6 +74765,17 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
74725
74765
  agent_id: agentId,
74726
74766
  conversation_id: conversationId
74727
74767
  };
74768
+ emitToWS(socket, {
74769
+ type: "approval_requested",
74770
+ request_id: requestId,
74771
+ tool_call_id: ac.approval.toolCallId,
74772
+ tool_name: ac.approval.toolName,
74773
+ ...lifecycleRunId ? { run_id: lifecycleRunId } : {},
74774
+ session_id: runtime.sessionId,
74775
+ uuid: `approval-requested-${ac.approval.toolCallId}`,
74776
+ agent_id: agentId,
74777
+ conversation_id: conversationId
74778
+ });
74728
74779
  const responseBody = await requestApprovalOverWS(runtime, socket, requestId, controlRequest);
74729
74780
  if (responseBody.subtype === "success") {
74730
74781
  const response = responseBody.response;
@@ -74748,30 +74799,80 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
74748
74799
  agent_id: agentId,
74749
74800
  conversation_id: conversationId
74750
74801
  });
74802
+ emitToWS(socket, {
74803
+ type: "approval_received",
74804
+ request_id: requestId,
74805
+ tool_call_id: ac.approval.toolCallId,
74806
+ decision: "allow",
74807
+ reason: "Approved via WebSocket",
74808
+ ...lifecycleRunId ? { run_id: lifecycleRunId } : {},
74809
+ session_id: runtime.sessionId,
74810
+ uuid: `approval-received-${ac.approval.toolCallId}`,
74811
+ agent_id: agentId,
74812
+ conversation_id: conversationId
74813
+ });
74751
74814
  } else {
74752
74815
  decisions.push({
74753
74816
  type: "deny",
74754
74817
  approval: ac.approval,
74755
74818
  reason: response?.message || "Denied via WebSocket"
74756
74819
  });
74820
+ emitToWS(socket, {
74821
+ type: "approval_received",
74822
+ request_id: requestId,
74823
+ tool_call_id: ac.approval.toolCallId,
74824
+ decision: "deny",
74825
+ reason: response?.message || "Denied via WebSocket",
74826
+ ...lifecycleRunId ? { run_id: lifecycleRunId } : {},
74827
+ session_id: runtime.sessionId,
74828
+ uuid: `approval-received-${ac.approval.toolCallId}`,
74829
+ agent_id: agentId,
74830
+ conversation_id: conversationId
74831
+ });
74757
74832
  }
74758
74833
  } else {
74834
+ const denyReason = responseBody.subtype === "error" ? responseBody.error : "Unknown error";
74759
74835
  decisions.push({
74760
74836
  type: "deny",
74761
74837
  approval: ac.approval,
74762
- reason: responseBody.subtype === "error" ? responseBody.error : "Unknown error"
74838
+ reason: denyReason
74839
+ });
74840
+ emitToWS(socket, {
74841
+ type: "approval_received",
74842
+ request_id: requestId,
74843
+ tool_call_id: ac.approval.toolCallId,
74844
+ decision: "deny",
74845
+ reason: denyReason,
74846
+ ...lifecycleRunId ? { run_id: lifecycleRunId } : {},
74847
+ session_id: runtime.sessionId,
74848
+ uuid: `approval-received-${ac.approval.toolCallId}`,
74849
+ agent_id: agentId,
74850
+ conversation_id: conversationId
74763
74851
  });
74764
74852
  }
74765
74853
  }
74766
74854
  }
74767
74855
  lastExecutingToolCallIds = decisions.filter((decision) => decision.type === "approve").map((decision) => decision.approval.toolCallId);
74768
74856
  runtime.activeExecutingToolCallIds = [...lastExecutingToolCallIds];
74857
+ const executionRunId = runId || runtime.activeRunId || msgRunIds[msgRunIds.length - 1];
74858
+ emitToolExecutionStartedEvents(socket, runtime, {
74859
+ toolCallIds: lastExecutingToolCallIds,
74860
+ runId: executionRunId,
74861
+ agentId,
74862
+ conversationId
74863
+ });
74769
74864
  const executionResults = await executeApprovalBatch(decisions, undefined, {
74770
74865
  toolContextId: turnToolContextId ?? undefined,
74771
74866
  abortSignal: runtime.activeAbortController.signal,
74772
74867
  workingDirectory: turnWorkingDirectory
74773
74868
  });
74774
74869
  const persistedExecutionResults = normalizeExecutionResultsForInterruptParity(runtime, executionResults, lastExecutingToolCallIds);
74870
+ emitToolExecutionFinishedEvents(socket, runtime, {
74871
+ approvals: persistedExecutionResults,
74872
+ runId: executionRunId,
74873
+ agentId,
74874
+ conversationId
74875
+ });
74775
74876
  lastExecutionResults = persistedExecutionResults;
74776
74877
  emitInterruptToolReturnMessage(socket, runtime, persistedExecutionResults, runtime.activeRunId || runId || msgRunIds[msgRunIds.length - 1] || undefined, "tool-return");
74777
74878
  clearPendingApprovalBatchIds(runtime, decisions.map((decision) => decision.approval));
@@ -74803,6 +74904,12 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
74803
74904
  conversationId
74804
74905
  });
74805
74906
  if (approvalsForEmission) {
74907
+ emitToolExecutionFinishedEvents(socket, runtime, {
74908
+ approvals: approvalsForEmission,
74909
+ runId: runtime.activeRunId || msgRunIds[msgRunIds.length - 1],
74910
+ agentId: agentId || "",
74911
+ conversationId
74912
+ });
74806
74913
  emitInterruptToolReturnMessage(socket, runtime, approvalsForEmission, runtime.activeRunId || msgRunIds[msgRunIds.length - 1] || undefined);
74807
74914
  }
74808
74915
  runtime.lastStopReason = "cancelled";
@@ -74900,6 +75007,7 @@ var init_listen_client = __esm(async () => {
74900
75007
  init_message(),
74901
75008
  init_accumulator(),
74902
75009
  init_approvalClassification(),
75010
+ init_imageResize(),
74903
75011
  init_stream(),
74904
75012
  init_engine(),
74905
75013
  init_settings_manager(),
@@ -74927,7 +75035,9 @@ var init_listen_client = __esm(async () => {
74927
75035
  getInterruptApprovalsForEmission,
74928
75036
  normalizeToolReturnWireMessage,
74929
75037
  normalizeExecutionResultsForInterruptParity,
74930
- shouldAttemptPostStopApprovalRecovery
75038
+ shouldAttemptPostStopApprovalRecovery,
75039
+ normalizeMessageContentImages,
75040
+ normalizeInboundMessages
74931
75041
  };
74932
75042
  });
74933
75043
 
@@ -75153,7 +75263,7 @@ import {
75153
75263
  existsSync as existsSync19,
75154
75264
  readFileSync as fsReadFileSync2,
75155
75265
  writeFileSync as fsWriteFileSync2,
75156
- mkdirSync as mkdirSync14
75266
+ mkdirSync as mkdirSync15
75157
75267
  } from "node:fs";
75158
75268
  import { dirname as dirname10 } from "node:path";
75159
75269
  async function readFile6(path22) {
@@ -75162,7 +75272,7 @@ async function readFile6(path22) {
75162
75272
  async function writeFile3(path22, content) {
75163
75273
  const dir = dirname10(path22);
75164
75274
  if (!existsSync19(dir)) {
75165
- mkdirSync14(dir, { recursive: true });
75275
+ mkdirSync15(dir, { recursive: true });
75166
75276
  }
75167
75277
  fsWriteFileSync2(path22, content, { encoding: "utf-8", flush: true });
75168
75278
  }
@@ -75170,7 +75280,7 @@ function exists2(path22) {
75170
75280
  return existsSync19(path22);
75171
75281
  }
75172
75282
  async function mkdir3(path22, options) {
75173
- mkdirSync14(path22, options);
75283
+ mkdirSync15(path22, options);
75174
75284
  }
75175
75285
  async function readJsonFile(path22) {
75176
75286
  const text = await readFile6(path22);
@@ -75863,7 +75973,7 @@ async function startDockerVersionCheck() {
75863
75973
  if (isVersionBelow(serverVersion, MINIMUM_DOCKER_VERSION)) {
75864
75974
  console.warn(`
75865
75975
  ⚠️ Warning: Your Docker image is outdated (v${serverVersion}). Minimum recommended: v${MINIMUM_DOCKER_VERSION}.
75866
- Please update with: docker pull letta/letta-server:latest
75976
+ Please update with: docker pull letta/letta:latest
75867
75977
  `);
75868
75978
  }
75869
75979
  } catch {}
@@ -75983,10 +76093,11 @@ __export(exports_promptAssets2, {
75983
76093
  resolveAndBuildSystemPrompt: () => resolveAndBuildSystemPrompt2,
75984
76094
  isKnownPreset: () => isKnownPreset2,
75985
76095
  buildSystemPrompt: () => buildSystemPrompt2,
75986
- SYSTEM_PROMPT_MEMORY_ADDON: () => SYSTEM_PROMPT_MEMORY_ADDON2,
75987
76096
  SYSTEM_PROMPT_MEMFS_ADDON: () => SYSTEM_PROMPT_MEMFS_ADDON2,
76097
+ SYSTEM_PROMPT_BLOCKS_ADDON: () => SYSTEM_PROMPT_BLOCKS_ADDON2,
75988
76098
  SYSTEM_PROMPTS: () => SYSTEM_PROMPTS2,
75989
76099
  SYSTEM_PROMPT: () => SYSTEM_PROMPT2,
76100
+ SLEEPTIME_MEMORY_PERSONA: () => SLEEPTIME_MEMORY_PERSONA2,
75990
76101
  SKILL_CREATOR_PROMPT: () => SKILL_CREATOR_PROMPT2,
75991
76102
  REMEMBER_PROMPT: () => REMEMBER_PROMPT2,
75992
76103
  PLAN_MODE_REMINDER: () => PLAN_MODE_REMINDER2,
@@ -76053,7 +76164,7 @@ function buildSystemPrompt2(presetId, memoryMode) {
76053
76164
  if (!preset) {
76054
76165
  throw new Error(`Unknown preset "${presetId}" — cannot rebuild system prompt`);
76055
76166
  }
76056
- const addon = memoryMode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON2 : SYSTEM_PROMPT_MEMORY_ADDON2;
76167
+ const addon = memoryMode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON2 : SYSTEM_PROMPT_BLOCKS_ADDON2;
76057
76168
  return `${preset.content.trimEnd()}
76058
76169
 
76059
76170
  ${addon.trimStart()}`.trim();
@@ -76061,7 +76172,7 @@ ${addon.trimStart()}`.trim();
76061
76172
  function swapMemoryAddon2(systemPrompt, mode) {
76062
76173
  let result = systemPrompt;
76063
76174
  for (const addon of [
76064
- SYSTEM_PROMPT_MEMORY_ADDON2.trim(),
76175
+ SYSTEM_PROMPT_BLOCKS_ADDON2.trim(),
76065
76176
  SYSTEM_PROMPT_MEMFS_ADDON2.trim()
76066
76177
  ]) {
76067
76178
  result = result.replaceAll(addon, "");
@@ -76077,7 +76188,7 @@ function swapMemoryAddon2(systemPrompt, mode) {
76077
76188
  result = result.replace(/\n{3,}/g, `
76078
76189
 
76079
76190
  `).trimEnd();
76080
- const target = mode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON2 : SYSTEM_PROMPT_MEMORY_ADDON2;
76191
+ const target = mode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON2 : SYSTEM_PROMPT_BLOCKS_ADDON2;
76081
76192
  return `${result}
76082
76193
 
76083
76194
  ${target.trimStart()}`.trim();
@@ -76124,7 +76235,7 @@ async function resolveSystemPrompt2(systemPromptPreset) {
76124
76235
  }
76125
76236
  throw new Error(`Unknown system prompt "${systemPromptPreset}" — does not match any preset or subagent`);
76126
76237
  }
76127
- var SYSTEM_PROMPT2, SYSTEM_PROMPT_MEMORY_ADDON2, SYSTEM_PROMPT_MEMFS_ADDON2, PLAN_MODE_REMINDER2, SKILL_CREATOR_PROMPT2, REMEMBER_PROMPT2, MEMORY_CHECK_REMINDER2, APPROVAL_RECOVERY_PROMPT2, AUTO_INIT_REMINDER2, INTERRUPT_RECOVERY_ALERT2, MEMORY_PROMPTS2, SYSTEM_PROMPTS2;
76238
+ var SYSTEM_PROMPT2, SYSTEM_PROMPT_BLOCKS_ADDON2, SYSTEM_PROMPT_MEMFS_ADDON2, PLAN_MODE_REMINDER2, SKILL_CREATOR_PROMPT2, REMEMBER_PROMPT2, MEMORY_CHECK_REMINDER2, APPROVAL_RECOVERY_PROMPT2, AUTO_INIT_REMINDER2, INTERRUPT_RECOVERY_ALERT2, SLEEPTIME_MEMORY_PERSONA2, MEMORY_PROMPTS2, SYSTEM_PROMPTS2;
76128
76239
  var init_promptAssets2 = __esm(() => {
76129
76240
  init_approval_recovery_alert();
76130
76241
  init_auto_init_reminder();
@@ -76134,21 +76245,21 @@ var init_promptAssets2 = __esm(() => {
76134
76245
  init_memory_check_reminder();
76135
76246
  init_memory_filesystem();
76136
76247
  init_persona();
76137
- init_persona_claude();
76138
76248
  init_persona_kawaii();
76139
76249
  init_persona_memo();
76140
76250
  init_plan_mode_reminder();
76141
76251
  init_project();
76142
76252
  init_remember();
76143
76253
  init_skill_creator_mode();
76254
+ init_sleeptime();
76144
76255
  init_source_claude();
76145
76256
  init_source_codex();
76146
76257
  init_source_gemini();
76147
76258
  init_style();
76259
+ init_system_prompt_blocks();
76148
76260
  init_system_prompt_memfs();
76149
- init_system_prompt_memory();
76150
76261
  SYSTEM_PROMPT2 = letta_default;
76151
- SYSTEM_PROMPT_MEMORY_ADDON2 = system_prompt_memory_default;
76262
+ SYSTEM_PROMPT_BLOCKS_ADDON2 = system_prompt_blocks_default;
76152
76263
  SYSTEM_PROMPT_MEMFS_ADDON2 = system_prompt_memfs_default;
76153
76264
  PLAN_MODE_REMINDER2 = plan_mode_reminder_default;
76154
76265
  SKILL_CREATOR_PROMPT2 = skill_creator_mode_default;
@@ -76157,9 +76268,9 @@ var init_promptAssets2 = __esm(() => {
76157
76268
  APPROVAL_RECOVERY_PROMPT2 = approval_recovery_alert_default;
76158
76269
  AUTO_INIT_REMINDER2 = auto_init_reminder_default;
76159
76270
  INTERRUPT_RECOVERY_ALERT2 = interrupt_recovery_alert_default;
76271
+ SLEEPTIME_MEMORY_PERSONA2 = sleeptime_default;
76160
76272
  MEMORY_PROMPTS2 = {
76161
76273
  "persona.mdx": persona_default,
76162
- "persona_claude.mdx": persona_claude_default,
76163
76274
  "persona_kawaii.mdx": persona_kawaii_default,
76164
76275
  "persona_memo.mdx": persona_memo_default,
76165
76276
  "human.mdx": human_default,
@@ -76641,53 +76752,6 @@ async function handleBootstrapSessionState(params) {
76641
76752
  }
76642
76753
  var init_bootstrapHandler = () => {};
76643
76754
 
76644
- // src/agent/prompts/sleeptime.ts
76645
- var SLEEPTIME_MEMORY_PERSONA = `I am a sleep-time memory management agent. I observe the conversation between the user and their primary agent, then actively maintain memory blocks to keep them accurate, concise, and useful.
76646
-
76647
- **Core responsibilities:**
76648
-
76649
- 1. **Update memory blocks in real-time** - Don't wait until end of session
76650
- - Capture important facts, decisions, and context as they occur
76651
- - Update existing information when it changes or becomes stale
76652
- - Remove outdated or contradictory information immediately
76653
-
76654
- 2. **Consolidate and refine memory continuously**
76655
- - Merge duplicate or redundant information
76656
- - Rewrite verbose entries into concise summaries
76657
- - Reorganize memory blocks when structure becomes unclear
76658
-
76659
- 3. **Identify and preserve patterns**
76660
- - Track recurring themes, preferences, and behaviors
76661
- - Note relationships between different pieces of information
76662
- - Surface insights from conversation history
76663
-
76664
- 4. **Maintain memory hygiene**
76665
- - Keep memory blocks under size limits through aggressive consolidation
76666
- - Prioritize recent and frequently-referenced information
76667
- - Remove low-value details that don't contribute to agent effectiveness
76668
-
76669
- 5. **Refine my own memory management approach**
76670
- - Update this \`memory_persona\` block as I learn what works
76671
- - Add user-specific memory policies when I identify patterns
76672
- - Remove or adjust guidelines that don't match observed behavior
76673
- - Adapt my consolidation strategy based on what the primary agent references most
76674
-
76675
- **Operating rules:**
76676
-
76677
- - If it was discussed, capture it somewhere in memory
76678
- - Update memory during the session, not after
76679
- - Be aggressive with edits - better to over-manage than under-manage
76680
- - Assume the primary agent relies entirely on memory blocks for context
76681
- - Every session should result in measurable memory improvements
76682
- - Regularly evaluate and improve my own memory management policies
76683
-
76684
- **DO NOT:**
76685
- - Wait to batch all updates at session end
76686
- - Skip memory edits because "nothing major happened"
76687
- - Let memory blocks grow stale or bloated
76688
- - Assume information will be captured later
76689
- - Continue using memory policies that don't serve the user's actual needs`;
76690
-
76691
76755
  // src/agent/create.ts
76692
76756
  function isToolsNotFoundError(err) {
76693
76757
  const message = err instanceof Error ? err.message : String(err);
@@ -77198,8 +77262,8 @@ __export(exports_github_utils, {
77198
77262
  async function fetchGitHubContents(owner, repo, branch, path24) {
77199
77263
  const apiPath = path24 ? `repos/${owner}/${repo}/contents/${path24}?ref=${branch}` : `repos/${owner}/${repo}/contents?ref=${branch}`;
77200
77264
  try {
77201
- const { execSync: execSync3 } = await import("node:child_process");
77202
- const result = execSync3(`gh api ${apiPath}`, {
77265
+ const { execSync: execSync2 } = await import("node:child_process");
77266
+ const result = execSync2(`gh api ${apiPath}`, {
77203
77267
  encoding: "utf-8",
77204
77268
  stdio: ["pipe", "pipe", "ignore"]
77205
77269
  });
@@ -99156,7 +99220,7 @@ html.dark .agent-name { color: var(--text-dim); }
99156
99220
  var init_plan_viewer_template = () => {};
99157
99221
 
99158
99222
  // src/web/generate-plan-viewer.ts
99159
- import { chmodSync as chmodSync2, existsSync as existsSync22, mkdirSync as mkdirSync17, writeFileSync as writeFileSync12 } from "node:fs";
99223
+ import { chmodSync as chmodSync2, existsSync as existsSync22, mkdirSync as mkdirSync18, writeFileSync as writeFileSync12 } from "node:fs";
99160
99224
  import { homedir as homedir26 } from "node:os";
99161
99225
  import { join as join32 } from "node:path";
99162
99226
  async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
@@ -99169,7 +99233,7 @@ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
99169
99233
  const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
99170
99234
  const html = plan_viewer_template_default.replace("<!--LETTA_PLAN_DATA_PLACEHOLDER-->", () => jsonPayload);
99171
99235
  if (!existsSync22(VIEWERS_DIR)) {
99172
- mkdirSync17(VIEWERS_DIR, { recursive: true, mode: 448 });
99236
+ mkdirSync18(VIEWERS_DIR, { recursive: true, mode: 448 });
99173
99237
  }
99174
99238
  try {
99175
99239
  chmodSync2(VIEWERS_DIR, 448);
@@ -101164,7 +101228,7 @@ var init_pasteRegistry = __esm(() => {
101164
101228
  });
101165
101229
 
101166
101230
  // src/cli/helpers/clipboard.ts
101167
- import { execFileSync as execFileSync2 } from "node:child_process";
101231
+ import { execFileSync as execFileSync3 } from "node:child_process";
101168
101232
  import { existsSync as existsSync23, readFileSync as readFileSync10, statSync as statSync6, unlinkSync as unlinkSync8 } from "node:fs";
101169
101233
  import { tmpdir as tmpdir3 } from "node:os";
101170
101234
  import { basename as basename4, extname as extname5, isAbsolute as isAbsolute16, join as join33, resolve as resolve25 } from "node:path";
@@ -101254,7 +101318,7 @@ function getClipboardImageToTempFile() {
101254
101318
  return '';
101255
101319
  })();
101256
101320
  `;
101257
- const uti = execFileSync2("osascript", ["-l", "JavaScript", "-e", jxa], {
101321
+ const uti = execFileSync3("osascript", ["-l", "JavaScript", "-e", jxa], {
101258
101322
  encoding: "utf8",
101259
101323
  stdio: ["ignore", "pipe", "ignore"]
101260
101324
  }).trim();
@@ -101873,7 +101937,7 @@ __export(exports_terminalKeybindingInstaller, {
101873
101937
  import {
101874
101938
  copyFileSync,
101875
101939
  existsSync as existsSync24,
101876
- mkdirSync as mkdirSync18,
101940
+ mkdirSync as mkdirSync19,
101877
101941
  readFileSync as readFileSync11,
101878
101942
  writeFileSync as writeFileSync13
101879
101943
  } from "node:fs";
@@ -101971,7 +102035,7 @@ function installKeybinding(keybindingsPath) {
101971
102035
  }
101972
102036
  const parentDir = dirname12(keybindingsPath);
101973
102037
  if (!existsSync24(parentDir)) {
101974
- mkdirSync18(parentDir, { recursive: true });
102038
+ mkdirSync19(parentDir, { recursive: true });
101975
102039
  }
101976
102040
  let keybindings = [];
101977
102041
  let backupPath = null;
@@ -102130,7 +102194,7 @@ ${WEZTERM_DELETE_FIX}
102130
102194
  }
102131
102195
  const parentDir = dirname12(configPath);
102132
102196
  if (!existsSync24(parentDir)) {
102133
- mkdirSync18(parentDir, { recursive: true });
102197
+ mkdirSync19(parentDir, { recursive: true });
102134
102198
  }
102135
102199
  writeFileSync13(configPath, content, { encoding: "utf-8" });
102136
102200
  return {
@@ -107673,10 +107737,10 @@ var init_InputRich = __esm(async () => {
107673
107737
  });
107674
107738
 
107675
107739
  // src/cli/commands/install-github-app.ts
107676
- import { execFileSync as execFileSync3 } from "node:child_process";
107740
+ import { execFileSync as execFileSync4 } from "node:child_process";
107677
107741
  import {
107678
107742
  existsSync as existsSync26,
107679
- mkdirSync as mkdirSync19,
107743
+ mkdirSync as mkdirSync20,
107680
107744
  mkdtempSync,
107681
107745
  readFileSync as readFileSync12,
107682
107746
  rmSync as rmSync3,
@@ -107686,7 +107750,7 @@ import { tmpdir as tmpdir4 } from "node:os";
107686
107750
  import { dirname as dirname14, join as join37 } from "node:path";
107687
107751
  function runCommand(command, args, cwd2, input) {
107688
107752
  try {
107689
- return execFileSync3(command, args, {
107753
+ return execFileSync4(command, args, {
107690
107754
  cwd: cwd2,
107691
107755
  encoding: "utf8",
107692
107756
  stdio: [input ? "pipe" : "ignore", "pipe", "pipe"],
@@ -107925,13 +107989,13 @@ function cloneRepoToTemp(repo) {
107925
107989
  function createBranchName() {
107926
107990
  return `letta/install-github-app-${Date.now().toString(36)}`;
107927
107991
  }
107928
- function runGit2(args, cwd2) {
107992
+ function runGit3(args, cwd2) {
107929
107993
  return runCommand("git", args, cwd2);
107930
107994
  }
107931
107995
  function writeWorkflow(repoDir, workflowPath, content) {
107932
107996
  const absolutePath = join37(repoDir, workflowPath);
107933
107997
  if (!existsSync26(dirname14(absolutePath))) {
107934
- mkdirSync19(dirname14(absolutePath), { recursive: true });
107998
+ mkdirSync20(dirname14(absolutePath), { recursive: true });
107935
107999
  }
107936
108000
  const next = `${content.trimEnd()}
107937
108001
  `;
@@ -107946,7 +108010,7 @@ function writeWorkflow(repoDir, workflowPath, content) {
107946
108010
  }
107947
108011
  function getDefaultBaseBranch(repoDir) {
107948
108012
  try {
107949
- const headRef = runGit2(["symbolic-ref", "refs/remotes/origin/HEAD"], repoDir);
108013
+ const headRef = runGit3(["symbolic-ref", "refs/remotes/origin/HEAD"], repoDir);
107950
108014
  return headRef.replace("refs/remotes/origin/", "").trim() || "main";
107951
108015
  } catch {
107952
108016
  return "main";
@@ -108022,7 +108086,7 @@ async function installGithubApp(options) {
108022
108086
  includeAgentId: resolvedAgentId != null
108023
108087
  });
108024
108088
  const branchName = createBranchName();
108025
- runGit2(["checkout", "-b", branchName], repoDir);
108089
+ runGit3(["checkout", "-b", branchName], repoDir);
108026
108090
  progress(onProgress, "Creating workflow files");
108027
108091
  const changed = writeWorkflow(repoDir, workflowPath, workflowContent);
108028
108092
  progress(onProgress, "Setting up LETTA_API_KEY secret");
@@ -108045,10 +108109,10 @@ async function installGithubApp(options) {
108045
108109
  agentUrl: resolvedAgentId ? buildChatUrl(resolvedAgentId) : null
108046
108110
  };
108047
108111
  }
108048
- runGit2(["add", workflowPath], repoDir);
108049
- runGit2(["commit", "-m", "Add Letta Code GitHub Workflow"], repoDir);
108112
+ runGit3(["add", workflowPath], repoDir);
108113
+ runGit3(["commit", "-m", "Add Letta Code GitHub Workflow"], repoDir);
108050
108114
  progress(onProgress, "Opening pull request page");
108051
- runGit2(["push", "-u", "origin", branchName], repoDir);
108115
+ runGit3(["push", "-u", "origin", branchName], repoDir);
108052
108116
  const pullRequest = createPullRequest(repo, branchName, workflowPath, repoDir);
108053
108117
  return {
108054
108118
  repo,
@@ -111909,7 +111973,7 @@ __export(exports_generate_memory_viewer, {
111909
111973
  generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
111910
111974
  });
111911
111975
  import { execFile as execFileCb2 } from "node:child_process";
111912
- import { chmodSync as chmodSync3, existsSync as existsSync27, mkdirSync as mkdirSync20, writeFileSync as writeFileSync15 } from "node:fs";
111976
+ import { chmodSync as chmodSync3, existsSync as existsSync27, mkdirSync as mkdirSync21, writeFileSync as writeFileSync15 } from "node:fs";
111913
111977
  import { homedir as homedir29 } from "node:os";
111914
111978
  import { join as join39 } from "node:path";
111915
111979
  import { promisify as promisify10 } from "node:util";
@@ -112195,7 +112259,7 @@ async function generateAndOpenMemoryViewer(agentId, options) {
112195
112259
  const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
112196
112260
  const html = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
112197
112261
  if (!existsSync27(VIEWERS_DIR2)) {
112198
- mkdirSync20(VIEWERS_DIR2, { recursive: true, mode: 448 });
112262
+ mkdirSync21(VIEWERS_DIR2, { recursive: true, mode: 448 });
112199
112263
  }
112200
112264
  try {
112201
112265
  chmodSync3(VIEWERS_DIR2, 448);
@@ -119783,59 +119847,39 @@ var init_contextChart = __esm(() => {
119783
119847
  });
119784
119848
 
119785
119849
  // src/cli/helpers/initCommand.ts
119786
- import { execSync as execSync3 } from "node:child_process";
119850
+ import { execSync as execSync2 } from "node:child_process";
119787
119851
  import { existsSync as existsSync29, readdirSync as readdirSync13, readFileSync as readFileSync14 } from "node:fs";
119788
119852
  import { join as join41 } from "node:path";
119789
119853
  function hasActiveInitSubagent() {
119790
119854
  const snapshot = getSnapshot2();
119791
119855
  return snapshot.agents.some((agent) => agent.type.toLowerCase() === "init" && (agent.status === "pending" || agent.status === "running"));
119792
119856
  }
119793
- function gatherGitContext() {
119857
+ function gatherInitGitContext() {
119794
119858
  try {
119795
- const cwd2 = process.cwd();
119796
- try {
119797
- execSync3("git rev-parse --git-dir", { cwd: cwd2, stdio: "pipe" });
119798
- const branch = execSync3("git branch --show-current", {
119799
- cwd: cwd2,
119800
- encoding: "utf-8"
119801
- }).trim();
119802
- const mainBranch = execSync3("git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo 'main'", { cwd: cwd2, encoding: "utf-8", shell: "/bin/bash" }).trim();
119803
- const status = execSync3("git status --short", {
119804
- cwd: cwd2,
119805
- encoding: "utf-8"
119806
- }).trim();
119807
- const recentCommits = execSync3("git log --oneline -10 2>/dev/null || echo 'No commits yet'", { cwd: cwd2, encoding: "utf-8" }).trim();
119808
- return `
119809
- - branch: ${branch}
119810
- - main: ${mainBranch}
119811
- - status: ${status || "(clean)"}
119859
+ const git = gatherGitContextSnapshot({
119860
+ recentCommitLimit: 10
119861
+ });
119862
+ if (!git.isGitRepo) {
119863
+ return {
119864
+ context: "(not a git repository)",
119865
+ identity: ""
119866
+ };
119867
+ }
119868
+ return {
119869
+ context: `
119870
+ - branch: ${git.branch ?? "(unknown)"}
119871
+ - status: ${git.status || "(clean)"}
119812
119872
 
119813
119873
  Recent commits:
119814
- ${recentCommits}
119815
- `;
119816
- } catch {
119817
- return "(not a git repository)";
119818
- }
119819
- } catch {
119820
- return "";
119821
- }
119822
- }
119823
- function gatherGitIdentity() {
119824
- const cwd2 = process.cwd();
119825
- try {
119826
- const userName = execSync3("git config user.name 2>/dev/null || true", {
119827
- cwd: cwd2,
119828
- encoding: "utf-8"
119829
- }).trim();
119830
- const userEmail = execSync3("git config user.email 2>/dev/null || true", {
119831
- cwd: cwd2,
119832
- encoding: "utf-8"
119833
- }).trim();
119834
- if (userName || userEmail)
119835
- return `${userName} <${userEmail}>`;
119836
- return "";
119874
+ ${git.recentCommits || "No commits yet"}
119875
+ `,
119876
+ identity: git.gitUser ?? ""
119877
+ };
119837
119878
  } catch {
119838
- return "";
119879
+ return {
119880
+ context: "",
119881
+ identity: ""
119882
+ };
119839
119883
  }
119840
119884
  }
119841
119885
  function gatherExistingMemory(agentId) {
@@ -119868,7 +119912,7 @@ function getGitIgnored(cwd2, names) {
119868
119912
  if (names.length === 0)
119869
119913
  return new Set;
119870
119914
  try {
119871
- const result = execSync3("git check-ignore --stdin", {
119915
+ const result = execSync2("git check-ignore --stdin", {
119872
119916
  cwd: cwd2,
119873
119917
  encoding: "utf-8",
119874
119918
  input: names.join(`
@@ -119897,8 +119941,7 @@ function gatherDirListing() {
119897
119941
  const files = visible.filter((e) => !e.isDirectory() && !ignored.has(e.name)).sort((a, b) => a.name.localeCompare(b.name));
119898
119942
  const lines = [];
119899
119943
  const sorted = [...dirs, ...files];
119900
- for (let i = 0;i < sorted.length; i++) {
119901
- const entry = sorted[i];
119944
+ for (const [i, entry] of sorted.entries()) {
119902
119945
  const isLast = i === sorted.length - 1;
119903
119946
  const prefix = isLast ? "└── " : "├── ";
119904
119947
  if (entry.isDirectory()) {
@@ -119915,8 +119958,7 @@ function gatherDirListing() {
119915
119958
  return a.name.localeCompare(b.name);
119916
119959
  });
119917
119960
  const childPrefix = isLast ? " " : "│ ";
119918
- for (let j = 0;j < children.length; j++) {
119919
- const child = children[j];
119961
+ for (const [j, child] of children.entries()) {
119920
119962
  const childIsLast = j === children.length - 1;
119921
119963
  const connector = childIsLast ? "└── " : "├── ";
119922
119964
  const suffix = child.isDirectory() ? "/" : "";
@@ -119962,16 +120004,15 @@ async function fireAutoInit(agentId, onComplete) {
119962
120004
  return false;
119963
120005
  if (!settingsManager.isMemfsEnabled(agentId))
119964
120006
  return false;
119965
- const gitContext = gatherGitContext();
119966
- const gitIdentity = gatherGitIdentity();
120007
+ const gitDetails = gatherInitGitContext();
119967
120008
  const existingMemory = gatherExistingMemory(agentId);
119968
120009
  const dirListing = gatherDirListing();
119969
120010
  const initPrompt = buildShallowInitPrompt({
119970
120011
  agentId,
119971
120012
  workingDirectory: process.cwd(),
119972
120013
  memoryDir: getMemoryFilesystemRoot(agentId),
119973
- gitContext,
119974
- gitIdentity,
120014
+ gitContext: gitDetails.context,
120015
+ gitIdentity: gitDetails.identity,
119975
120016
  existingMemory,
119976
120017
  dirListing
119977
120018
  });
@@ -120013,6 +120054,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
120013
120054
  var init_initCommand = __esm(async () => {
120014
120055
  init_memoryFilesystem();
120015
120056
  init_constants();
120057
+ init_gitContext();
120016
120058
  init_subagentState();
120017
120059
  await init_settings_manager();
120018
120060
  });
@@ -120029,9 +120071,7 @@ async function handleMemorySubagentCompletion(args, deps) {
120029
120071
  inFlight = (async () => {
120030
120072
  do {
120031
120073
  deps.recompileQueuedByConversation.delete(conversationId);
120032
- await recompileAgentSystemPromptFn(conversationId, {
120033
- ...conversationId === "default" ? { agentId } : {}
120034
- });
120074
+ await recompileAgentSystemPromptFn(conversationId, agentId);
120035
120075
  } while (deps.recompileQueuedByConversation.has(conversationId));
120036
120076
  })().finally(() => {
120037
120077
  deps.recompileQueuedByConversation.delete(conversationId);
@@ -127440,7 +127480,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
127440
127480
  setCommandRunning(true);
127441
127481
  try {
127442
127482
  cmd.finish("Building your memory palace... Start a new conversation with `letta --new` to work in parallel.", true);
127443
- const gitContext = gatherGitContext();
127483
+ const { context: gitContext } = gatherInitGitContext();
127444
127484
  const memoryDir = settingsManager.isMemfsEnabled(agentId) ? getMemoryFilesystemRoot(agentId) : undefined;
127445
127485
  const initMessage = buildInitMessage({
127446
127486
  gitContext,
@@ -130842,7 +130882,7 @@ __export(exports_terminalKeybindingInstaller2, {
130842
130882
  import {
130843
130883
  copyFileSync as copyFileSync2,
130844
130884
  existsSync as existsSync32,
130845
- mkdirSync as mkdirSync21,
130885
+ mkdirSync as mkdirSync22,
130846
130886
  readFileSync as readFileSync17,
130847
130887
  writeFileSync as writeFileSync17
130848
130888
  } from "node:fs";
@@ -130940,7 +130980,7 @@ function installKeybinding2(keybindingsPath) {
130940
130980
  }
130941
130981
  const parentDir = dirname15(keybindingsPath);
130942
130982
  if (!existsSync32(parentDir)) {
130943
- mkdirSync21(parentDir, { recursive: true });
130983
+ mkdirSync22(parentDir, { recursive: true });
130944
130984
  }
130945
130985
  let keybindings = [];
130946
130986
  let backupPath = null;
@@ -131099,7 +131139,7 @@ ${WEZTERM_DELETE_FIX2}
131099
131139
  }
131100
131140
  const parentDir = dirname15(configPath);
131101
131141
  if (!existsSync32(parentDir)) {
131102
- mkdirSync21(parentDir, { recursive: true });
131142
+ mkdirSync22(parentDir, { recursive: true });
131103
131143
  }
131104
131144
  writeFileSync17(configPath, content, { encoding: "utf-8" });
131105
131145
  return {
@@ -131797,7 +131837,7 @@ __export(exports_memoryFilesystem2, {
131797
131837
  MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
131798
131838
  MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
131799
131839
  });
131800
- import { existsSync as existsSync33, mkdirSync as mkdirSync22 } from "node:fs";
131840
+ import { existsSync as existsSync33, mkdirSync as mkdirSync23 } from "node:fs";
131801
131841
  import { homedir as homedir36 } from "node:os";
131802
131842
  import { join as join47 } from "node:path";
131803
131843
  function getMemoryFilesystemRoot2(agentId, homeDir = homedir36()) {
@@ -131810,10 +131850,10 @@ function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir36()) {
131810
131850
  const root = getMemoryFilesystemRoot2(agentId, homeDir);
131811
131851
  const systemDir = getMemorySystemDir2(agentId, homeDir);
131812
131852
  if (!existsSync33(root)) {
131813
- mkdirSync22(root, { recursive: true });
131853
+ mkdirSync23(root, { recursive: true });
131814
131854
  }
131815
131855
  if (!existsSync33(systemDir)) {
131816
- mkdirSync22(systemDir, { recursive: true });
131856
+ mkdirSync23(systemDir, { recursive: true });
131817
131857
  }
131818
131858
  }
131819
131859
  function labelFromRelativePath2(relativePath) {
@@ -134002,7 +134042,7 @@ init_fileSearchConfig();
134002
134042
  import { createHash } from "node:crypto";
134003
134043
  import {
134004
134044
  existsSync as existsSync7,
134005
- mkdirSync as mkdirSync4,
134045
+ mkdirSync as mkdirSync5,
134006
134046
  readdirSync as readdirSync2,
134007
134047
  readFileSync as readFileSync5,
134008
134048
  statSync,
@@ -134219,7 +134259,7 @@ async function buildDirectory(dir, relativePath, entries, merkle, statsMap, prev
134219
134259
  return previous.merkle[relativePath] ?? hashValue("__reused__");
134220
134260
  }
134221
134261
  statsMap[relativePath] = currentStats;
134222
- if (depth >= MAX_INDEX_DEPTH) {
134262
+ if (depth >= MAX_INDEX_DEPTH || context2.newEntryCount >= MAX_CACHE_ENTRIES) {
134223
134263
  context2.truncated = true;
134224
134264
  const truncatedHash = hashValue("__truncated__");
134225
134265
  merkle[relativePath] = truncatedHash;
@@ -134227,6 +134267,10 @@ async function buildDirectory(dir, relativePath, entries, merkle, statsMap, prev
134227
134267
  }
134228
134268
  const childHashes = [];
134229
134269
  for (const entry of childNames) {
134270
+ if (context2.newEntryCount >= MAX_CACHE_ENTRIES) {
134271
+ context2.truncated = true;
134272
+ break;
134273
+ }
134230
134274
  if (context2.newEntryCount > 0 && context2.newEntryCount % 500 === 0) {
134231
134275
  await new Promise((resolve2) => setImmediate(resolve2));
134232
134276
  }
@@ -134308,7 +134352,7 @@ function getProjectStorageDir() {
134308
134352
  function ensureProjectStorageDir() {
134309
134353
  const storageDir = getProjectStorageDir();
134310
134354
  if (!existsSync7(storageDir)) {
134311
- mkdirSync4(storageDir, { recursive: true });
134355
+ mkdirSync5(storageDir, { recursive: true });
134312
134356
  }
134313
134357
  return storageDir;
134314
134358
  }
@@ -135425,7 +135469,7 @@ import { parseArgs as parseArgs5 } from "node:util";
135425
135469
  import {
135426
135470
  appendFileSync as appendFileSync2,
135427
135471
  existsSync as existsSync8,
135428
- mkdirSync as mkdirSync5,
135472
+ mkdirSync as mkdirSync6,
135429
135473
  readdirSync as readdirSync3,
135430
135474
  unlinkSync as unlinkSync2
135431
135475
  } from "node:fs";
@@ -135491,7 +135535,7 @@ class RemoteSessionLog {
135491
135535
  return;
135492
135536
  try {
135493
135537
  if (!existsSync8(REMOTE_LOG_DIR)) {
135494
- mkdirSync5(REMOTE_LOG_DIR, { recursive: true });
135538
+ mkdirSync6(REMOTE_LOG_DIR, { recursive: true });
135495
135539
  }
135496
135540
  this.dirCreated = true;
135497
135541
  } catch {}
@@ -135847,7 +135891,7 @@ async function runListenSubcommand(argv) {
135847
135891
 
135848
135892
  // src/cli/subcommands/memfs.ts
135849
135893
  await init_memoryGit();
135850
- import { cpSync, existsSync as existsSync16, mkdirSync as mkdirSync12, rmSync as rmSync2, statSync as statSync4 } from "node:fs";
135894
+ import { cpSync, existsSync as existsSync16, mkdirSync as mkdirSync13, rmSync as rmSync2, statSync as statSync4 } from "node:fs";
135851
135895
  import { readdir as readdir6 } from "node:fs/promises";
135852
135896
  import { homedir as homedir19 } from "node:os";
135853
135897
  import { join as join23 } from "node:path";
@@ -136069,7 +136113,7 @@ async function runMemfsSubcommand(argv) {
136069
136113
  return 1;
136070
136114
  }
136071
136115
  } else {
136072
- mkdirSync12(out, { recursive: true });
136116
+ mkdirSync13(out, { recursive: true });
136073
136117
  }
136074
136118
  cpSync(root, out, { recursive: true });
136075
136119
  console.log(JSON.stringify({ exportedFrom: root, exportedTo: out, agentId }, null, 2));
@@ -138063,7 +138107,7 @@ ${after}`;
138063
138107
  import {
138064
138108
  appendFileSync as appendFileSync3,
138065
138109
  existsSync as existsSync17,
138066
- mkdirSync as mkdirSync13,
138110
+ mkdirSync as mkdirSync14,
138067
138111
  readdirSync as readdirSync9,
138068
138112
  readFileSync as readFileSync8,
138069
138113
  unlinkSync as unlinkSync6
@@ -138135,7 +138179,7 @@ class DebugLogFile2 {
138135
138179
  return;
138136
138180
  try {
138137
138181
  if (!existsSync17(this.agentDir)) {
138138
- mkdirSync13(this.agentDir, { recursive: true });
138182
+ mkdirSync14(this.agentDir, { recursive: true });
138139
138183
  }
138140
138184
  this.dirCreated = true;
138141
138185
  } catch {}
@@ -139585,4 +139629,4 @@ Error during initialization: ${message}`);
139585
139629
  }
139586
139630
  main();
139587
139631
 
139588
- //# debugId=E1F68E6B92611AA064756E2164756E21
139632
+ //# debugId=CCE32950A21FCA1F64756E2164756E21