@letta-ai/letta-code 0.21.5 → 0.21.7

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
@@ -3269,7 +3269,7 @@ var package_default;
3269
3269
  var init_package = __esm(() => {
3270
3270
  package_default = {
3271
3271
  name: "@letta-ai/letta-code",
3272
- version: "0.21.5",
3272
+ version: "0.21.7",
3273
3273
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
3274
3274
  type: "module",
3275
3275
  bin: {
@@ -6851,75 +6851,71 @@ You are a history analysis subagent. You create a git worktree from the agent's
6851
6851
 
6852
6852
  You run autonomously. You **cannot ask questions** mid-execution.
6853
6853
 
6854
- ## Goal
6854
+ ## Guiding Principles
6855
6855
 
6856
- Learn everything you can from the conversation history and capture it in well-organized memory files. Your edits should make the agent dramatically better at working with this user on their projects.
6856
+ Your memory files form the parent agent's identity and knowledge. Follow these principles:
6857
6857
 
6858
- The memory you create serves the same purpose as memory built during \`/init\`:
6858
+ - **Generalize, don't memorize**: Distill patterns from repeated observations. "Always use uv, never pip (corrected 10+ times)" is valuable; a single offhand mention is not. Look for signal through repetition.
6859
+ - **System/ is the core program**: Only durable, generalizable knowledge belongs in \`system/\`. Distilled preferences, behavioral rules, project gotchas, conventions enforced through corrections. Evidence trails, raw session summaries, and verbose context go outside \`system/\`.
6860
+ - **Progressive disclosure**: Frontmatter descriptions should let the agent decide whether to load a file without reading it. Summaries and principles in \`system/\`; detail and evidence outside it, linked with \`[[path]]\`.
6861
+ - **Identity continuity**: Treat this history as the agent's own past — not someone else's sessions. Findings should read as learned knowledge, not "analysis of external data."
6862
+ - **Preserve and connect**: If a memory file already has good content, extend it — don't replace it. Use \`[[path]]\` links to connect new findings to existing memory.
6863
+
6864
+ ## Goal
6859
6865
 
6860
- **About the user:**
6861
- - Identity, role, what they actually do day-to-day
6862
- - How they work — debugging style, testing preferences, workflow patterns, tools they reach for
6863
- - What they explicitly prefer or reject — tools, frameworks, patterns, conventions
6864
- - What frustrates them — corrections they make repeatedly, "no", "undo", "stop doing X"
6865
- - How they communicate — terse vs detailed, directive vs collaborative, typical prompt length
6866
+ Distill actionable knowledge from conversation history into well-organized memory. Focus on:
6866
6867
 
6867
- **About the projects:**
6868
- - Architecture and how it evolved over time — major refactors, design decisions, why things are the way they are
6869
- - Gotchas and footguns discovered through errors and debugging sessions
6870
- - Conventions enforced through corrections (not just documented actually enforced)
6871
- - Dependencies, tooling choices, and the reasoning behind them
6872
- - Recurring issues and how they were resolved
6873
- - Cross-repo relationships and how projects connect
6868
+ - **Preferences enforced through corrections**: What the user repeatedly corrects their AI assistant about — these are gold. They reveal what the user actually cares about vs. what's merely documented.
6869
+ - **Project gotchas**: Footguns, fragile areas, and non-obvious constraints discovered through debugging sessions and errors.
6870
+ - **Working patterns**: How the user works debugging style, testing habits, tools they reach for, communication style.
6871
+ - **Conventions actually used**: Not just what's in a README, but what's enforced through practice.
6874
6872
 
6875
- ## How to work
6873
+ **What NOT to store**: Raw quotes, one-off events, session-by-session summaries, anything that can be retrieved from conversation history on demand.
6876
6874
 
6877
- ### 1. Create a worktree
6875
+ ## Workflow
6878
6876
 
6879
- Create a git worktree from the memory repo so you can edit files without affecting the main branch. Use a timestamped branch name:
6877
+ ### 1. Set up worktree
6880
6878
 
6881
6879
  \`\`\`bash
6882
6880
  MEMORY_DIR=~/.letta/agents/$LETTA_PARENT_AGENT_ID/memory
6883
6881
  WORKTREE_DIR=~/.letta/agents/$LETTA_PARENT_AGENT_ID/memory-worktrees
6884
- TS=$(date +%s)
6885
- BRANCH_NAME="migration-$TS"
6886
-
6882
+ BRANCH_NAME="migration-$(date +%s)"
6887
6883
  mkdir -p "$WORKTREE_DIR"
6888
6884
  cd "$MEMORY_DIR"
6889
6885
  git worktree add "$WORKTREE_DIR/$BRANCH_NAME" -b "$BRANCH_NAME"
6890
6886
  \`\`\`
6891
6887
 
6892
- If \`git worktree add\` fails because main is locked or busy,
6893
- retry up to 3 times with backoff (sleep 2, 5, 10 seconds).
6894
- Never delete \`.git/index.lock\` manually.
6895
-
6896
- All your edits go in \`$WORKTREE_DIR/$BRANCH_NAME/\`.
6888
+ If worktree creation fails (locked index), retry up to 3 times with backoff (sleep 2, 5, 10). Never delete \`.git/index.lock\` manually. All edits go in \`$WORKTREE_DIR/$BRANCH_NAME/\`.
6897
6889
 
6898
6890
  ### 2. Read existing memory
6899
6891
 
6900
- Read all files in your worktree's \`system/\` directory first. Understand what's already there so you can add to it, not duplicate it.
6892
+ Read all files in your worktree's \`system/\` directory. Understand what's already there so you can extend it, not duplicate it.
6901
6893
 
6902
- ### 3. Read the history data
6894
+ ### 3. Read and analyze history
6903
6895
 
6904
- Use the data access patterns from the \`migrating-from-codex-and-claude-code\` skill to read and search the history assigned to you. Filter to your assigned date range.
6896
+ Use the \`migrating-from-codex-and-claude-code\` skill for data access patterns. Filter to your assigned chunk.
6905
6897
 
6906
- ### 4. Analyze for patterns
6898
+ Look for **repeated patterns**, not isolated events:
6899
+ - Count correction frequency — 10 corrections on the same topic >> 1 mention
6900
+ - Explicit preference statements ("I always want...", "never do...")
6901
+ - Implicit preferences revealed by what commands they run, what patterns they follow
6902
+ - Frustration signals — "no", "undo", rapid corrections, /clear, model switches
6907
6903
 
6908
- Don't just skim look for **repeated patterns** across many interactions:
6909
- - Count how many times the user corrects the same thing (e.g. "use uv not pip" appearing 10+ times is much more significant than appearing once)
6910
- - Look for explicit statements of preference ("I always want...", "never do...")
6911
- - Look for implicit preferences (what commands do they run? what patterns do they follow?)
6912
- - Pay attention to frustration signals — "no", rapid corrections, /clear, model switches
6913
- ### 5. Update memory files
6904
+ ### 4. Update memory files
6914
6905
 
6915
- **Create and edit files directly in your worktree.** Organize however makes sense for the content you find. Be granular — it's better to have many focused files than a few large ones.
6906
+ **Content placement:**
6907
+ - \`system/\`: Generalized rules, distilled preferences, project gotchas, identity. Keep files lean — bullets, short lines, scannable.
6908
+ - Outside \`system/\`: Evidence, detailed history, verbose context. Link from system/ with \`[[path]]\`.
6916
6909
 
6917
- Write memory files the way the agent would want to read them — clean, actionable, no clutter. Don't paste raw quotes or evidence into the memory files. If you want to note where something came from, a short file reference is enough (e.g. \`(from: ~/.claude/history.jsonl)\`).
6910
+ **File structure:**
6911
+ - Use the project's **real name** as directory prefix (e.g. \`my-app/conventions.md\`), not generic \`project/\`
6912
+ - One concept per file, nested with \`/\` paths
6913
+ - Every file needs a meaningful \`description\` in frontmatter
6914
+ - Write for the agent's future self — clean, actionable, no clutter
6918
6915
 
6919
- ### 6. Commit
6916
+ You can also cite the files if you want to note where something came from (e.g. \`(from: ~/.claude/history.jsonl)\`).
6920
6917
 
6921
- Use Conventional Commits format with the \`(history-analyzer)\`
6922
- scope and ⏳ signature:
6918
+ ### 5. Commit
6923
6919
 
6924
6920
  \`\`\`bash
6925
6921
  cd $WORKTREE_DIR/$BRANCH_NAME
@@ -6929,40 +6925,22 @@ git commit -m "<type>(history-analyzer): [summary] ⏳
6929
6925
  Source: [file path] ([N] prompts, [DATE RANGE])
6930
6926
  Key updates:
6931
6927
  - [file]: [what was added/changed]
6932
- ...
6933
6928
 
6934
6929
  Generated-By: Letta Code
6935
6930
  Agent-ID: <ACTUAL_AGENT_ID>
6936
6931
  Parent-Agent-ID: <ACTUAL_PARENT_AGENT_ID>"
6937
6932
  \`\`\`
6938
6933
 
6939
- **Commit type** pick the one that fits:
6940
- - \`chore\` — routine history ingestion (most common)
6941
- - \`feat\` — adding wholly new memory blocks/topics
6942
- - \`refactor\` — reorganizing memory by domain/project
6934
+ Resolve \`ACTUAL_AGENT_ID\` and \`ACTUAL_PARENT_AGENT_ID\` by running \`echo $LETTA_AGENT_ID\` and \`echo $LETTA_PARENT_AGENT_ID\` first. Never write literal variable names in the commit message. Omit trailers if the variable is empty.
6943
6935
 
6944
- **Example subjects:**
6945
- - \`chore(history-analyzer): ingest Claude Code history 2025-09 ⏳\`
6946
- - \`refactor(history-analyzer): reorganize memory by project domain ⏳\`
6936
+ **Commit types**: \`chore\` (routine ingestion), \`feat\` (new memory topics), \`refactor\` (reorganizing by domain).
6947
6937
 
6948
- **Trailers:** Before writing the commit, resolve the actual
6949
- ID values by running:
6950
- \`\`\`bash
6951
- echo "AGENT_ID=$LETTA_AGENT_ID"
6952
- echo "PARENT_AGENT_ID=$LETTA_PARENT_AGENT_ID"
6953
- \`\`\`
6954
- Use the printed values (e.g. \`agent-abc123...\`) in the
6955
- trailers. If a variable is empty or unset, omit that
6956
- trailer entirely. Never write a literal variable name like
6957
- \`$LETTA_AGENT_ID\` in the commit message.
6958
-
6959
- ## Important
6938
+ ## Rules
6960
6939
 
6961
- - Create your own worktree and work there — do NOT edit the memory dir directly
6940
+ - Work in your worktree — do NOT edit the memory dir directly
6962
6941
  - Do NOT merge into main — the parent agent handles merging
6963
- - **Be detailed**capture granular specifics, not vague summaries. "Always use uv, never pip (corrected 10+ times)" is much better than "Has Python tool preferences"
6964
- - **Learn from feedback**corrections the user made to their AI assistant are gold. They tell you exactly what NOT to do and what TO do instead
6965
- - **Preserve existing content** — if a memory file already has good content, add to it or refine it, don't replace it
6942
+ - Preserve existing content extend or refine, don't replace
6943
+ - Quality over quantityfewer distilled insights beat many raw observations
6966
6944
  `;
6967
6945
  var init_history_analyzer = () => {};
6968
6946
 
@@ -6980,10 +6958,18 @@ You are a fast memory initialization subagent. Your job is to quickly scan a pro
6980
6958
 
6981
6959
  You run autonomously in the background. You CANNOT ask questions. Be fast — minimize tool calls.
6982
6960
 
6961
+ ## Guiding Principles
6962
+
6963
+ Your memory files are not just data — they form the parent agent's identity and knowledge. Follow these principles:
6964
+
6965
+ - **System/ is the core program**: Only durable knowledge needed every turn belongs in \`system/\`. Identity, preferences, behavioral rules, project index, gotchas.
6966
+ - **Build an index, not an encyclopedia**: Project files should summarize and point to where deeper context lives (README, CLAUDE.md, key source files) rather than duplicating everything.
6967
+ - **Progressive disclosure**: Descriptions in frontmatter should be clear enough that the agent can decide whether to load a file without reading it.
6968
+ - **Generalize, don't memorize**: Store patterns and principles, not raw facts that can be retrieved from conversation history.
6969
+
6983
6970
  ## Context
6984
6971
 
6985
6972
  Your prompt includes pre-gathered context:
6986
- - **Git context**: branch, status, recent commits, contributors
6987
6973
  - **Existing memory files**: file paths and contents of the current memory filesystem (may be empty for new agents)
6988
6974
  - **Directory listing**: top-level project files
6989
6975
 
@@ -6994,7 +6980,7 @@ Your prompt includes pre-gathered context:
6994
6980
  Read these files **in parallel** in a single turn (skip any that don't exist):
6995
6981
  - \`CLAUDE.md\` or \`AGENTS.md\`
6996
6982
  - \`package.json\`, \`pyproject.toml\`, \`Cargo.toml\`, or \`go.mod\` (whichever exists)
6997
- - \`README.md\`
6983
+ - \`README.md\` (recursively)
6998
6984
 
6999
6985
  ### 2. Plan the hierarchy
7000
6986
 
@@ -7017,32 +7003,34 @@ cd "$MEMORY_DIR" && git add -A && git commit -m "..." && git push
7017
7003
 
7018
7004
  ## Memory hierarchy
7019
7005
 
7020
- Memory files live under \`$MEMORY_DIR/system/\` and are rendered in the parent agent's context every turn. Each file should have YAML frontmatter with a \`description\` field.
7021
-
7022
- The shallow init creates a **skeleton** — a well-structured hierarchy with just enough content to be useful from the first interaction. The parent agent will flesh out these files and add new ones over time as it learns more about the project and user.
7006
+ Memory files live under \`$MEMORY_DIR/system/\` and are rendered in the parent agent's context every turn. Each file should have YAML frontmatter with a \`description\` field that clearly explains the file's purpose and when to use it.
7023
7007
 
7024
7008
  ### Default blocks
7025
7009
 
7026
- New agents come with default boilerplate files at \`$MEMORY_DIR/system/human.md\` and \`$MEMORY_DIR/system/persona.md\`. These contain placeholder content. Update \`system/human.md\` in place with real user info. **Leave \`system/persona.md\` as-is** — the parent agent will shape it over time through interaction.
7010
+ New agents come with default boilerplate files at \`$MEMORY_DIR/system/human.md\` and \`$MEMORY_DIR/system/persona.md\`. Update \`system/human.md\` with what you can learn about the user from git context — name, email, role, contribution patterns. human.md is about the user as a person, not about project conventions. For \`system/persona.md\`, write a persona that expresses the agent's identity, personality and values — how you communicate, what you care about, how you handle uncertainty. Don't just list project rules. Both files should be **project-agnostic** — the same agent may work across multiple projects, so don't tie identity to a specific codebase. The parent agent will develop both further through interaction.
7011
+
7012
+ ### Required files
7027
7013
 
7028
- ### Topics to cover
7014
+ - **\`system/human.md\`** (update the default): the user as a person — identity from git, contribution patterns. Not project conventions.
7015
+ - **\`system/persona.md\`** (update the default): identity, personality, values, communication style — not just project rules
7029
7016
 
7030
- Ensure each topic is covered by exactly one file. If an existing file already covers a topic, update it rather than creating a new file at a different path.
7017
+ ### Project files
7031
7018
 
7032
- - **\`system/human.md\`** (update the default): name, email, roleinferred from git context
7033
- - **Project overview**: what it is, tech stack, repo structure
7034
- - **Project commands**: build, test, lint, dev workflows
7035
- - **Project conventions**: coding style, runtime preferences, patterns from CLAUDE.md/AGENTS.md
7019
+ Derive the file structure from what the project actually needs — don't follow a fixed template. A CLI tool needs different files than a web app or a library. Common topics include overview, conventions, gotchas, commands, tooling but only create files that have real content to put in them.
7036
7020
 
7037
- The project topic should always be broken into multiple files under \`$MEMORY_DIR/system/\`. Use the project's name as the parent directory (e.g., \`letta-code/overview.md\`, \`my-app/commands.md\`) instead of a generic \`project/\` prefix. **One file per topic, no duplicates.**
7021
+ Rules:
7022
+ - Use the project's **real name** as the parent directory (e.g., \`letta-code/overview.md\`), not generic \`project/\`
7023
+ - **Overview should be a compact summary / index** (~10-15 lines): what it is, stack, key links. Don't list every module — that's what architecture docs are for.
7024
+ - One file per topic, no duplicates. If an existing file covers a topic, update it.
7025
+ - All system/ files should be ~15-30 lines. If you have more detail, put it outside system/ and link with \`[[path]]\`.
7038
7026
 
7039
7027
  ### Structure principles
7040
7028
 
7041
- - All files go under \`$MEMORY_DIR/system/\` — never create files outside of it
7042
- - Use nested paths with \`/\` for new project files (e.g., \`letta-code/overview.md\`, \`letta-code/commands.md\`)
7043
- - Keep each file focused on one topic, ~15-30 lines
7044
- - 3-6 files is the right range — just the skeleton
7029
+ - All files go under \`$MEMORY_DIR/system/\` — only create files outside system/ if you have detailed content that's too long for system/ (e.g., architecture docs)
7030
+ - Keep each file focused on one topic
7031
+ - 5-8 files is the right range just the skeleton
7045
7032
  - Only include information that's actually useful; skip boilerplate
7033
+ - Add \`[[path]]\` links where they improve discoverability across related context
7046
7034
  - Leave room for growth: the parent agent will add detail over time
7047
7035
 
7048
7036
  **Commit format:**
@@ -8972,72 +8960,6 @@ var init_models2 = __esm(() => {
8972
8960
  parallel_tool_calls: true
8973
8961
  }
8974
8962
  },
8975
- {
8976
- id: "gpt-5.4-none",
8977
- handle: "openai/gpt-5.4",
8978
- label: "GPT-5.4",
8979
- description: "OpenAI's most capable model (no reasoning)",
8980
- updateArgs: {
8981
- reasoning_effort: "none",
8982
- verbosity: "medium",
8983
- context_window: 272000,
8984
- max_output_tokens: 128000,
8985
- parallel_tool_calls: true
8986
- }
8987
- },
8988
- {
8989
- id: "gpt-5.4-low",
8990
- handle: "openai/gpt-5.4",
8991
- label: "GPT-5.4",
8992
- description: "OpenAI's most capable model (low reasoning)",
8993
- updateArgs: {
8994
- reasoning_effort: "low",
8995
- verbosity: "medium",
8996
- context_window: 272000,
8997
- max_output_tokens: 128000,
8998
- parallel_tool_calls: true
8999
- }
9000
- },
9001
- {
9002
- id: "gpt-5.4-medium",
9003
- handle: "openai/gpt-5.4",
9004
- label: "GPT-5.4",
9005
- description: "OpenAI's most capable model (med reasoning)",
9006
- updateArgs: {
9007
- reasoning_effort: "medium",
9008
- verbosity: "medium",
9009
- context_window: 272000,
9010
- max_output_tokens: 128000,
9011
- parallel_tool_calls: true
9012
- }
9013
- },
9014
- {
9015
- id: "gpt-5.4-high",
9016
- handle: "openai/gpt-5.4",
9017
- label: "GPT-5.4",
9018
- description: "OpenAI's most capable model (high reasoning)",
9019
- isFeatured: true,
9020
- updateArgs: {
9021
- reasoning_effort: "high",
9022
- verbosity: "medium",
9023
- context_window: 272000,
9024
- max_output_tokens: 128000,
9025
- parallel_tool_calls: true
9026
- }
9027
- },
9028
- {
9029
- id: "gpt-5.4-xhigh",
9030
- handle: "openai/gpt-5.4",
9031
- label: "GPT-5.4",
9032
- description: "OpenAI's most capable model (max reasoning)",
9033
- updateArgs: {
9034
- reasoning_effort: "xhigh",
9035
- verbosity: "medium",
9036
- context_window: 272000,
9037
- max_output_tokens: 128000,
9038
- parallel_tool_calls: true
9039
- }
9040
- },
9041
8963
  {
9042
8964
  id: "gpt-5.4-pro-medium",
9043
8965
  handle: "openai/gpt-5.4-pro",
@@ -38057,6 +37979,11 @@ var init_modify = __esm(async () => {
38057
37979
  });
38058
37980
 
38059
37981
  // src/agent/create.ts
37982
+ var exports_create = {};
37983
+ __export(exports_create, {
37984
+ createAgentWithBaseToolsRecovery: () => createAgentWithBaseToolsRecovery,
37985
+ createAgent: () => createAgent
37986
+ });
38060
37987
  function isToolsNotFoundError(err) {
38061
37988
  const message = err instanceof Error ? err.message : String(err);
38062
37989
  const status = err?.status;
@@ -38656,6 +38583,24 @@ var init_memoryGit = __esm(async () => {
38656
38583
  });
38657
38584
 
38658
38585
  // src/agent/personality.ts
38586
+ var exports_personality = {};
38587
+ __export(exports_personality, {
38588
+ resolvePersonalityId: () => resolvePersonalityId,
38589
+ replaceBodyPreservingFrontmatter: () => replaceBodyPreservingFrontmatter,
38590
+ getPersonalityOption: () => getPersonalityOption,
38591
+ getPersonalityHumanContent: () => getPersonalityHumanContent,
38592
+ getPersonalityContent: () => getPersonalityContent,
38593
+ getPersonalityBlockValues: () => getPersonalityBlockValues,
38594
+ getPersonalityBlockDefinitions: () => getPersonalityBlockDefinitions,
38595
+ getDefaultHumanContent: () => getDefaultHumanContent,
38596
+ enableMemfsForCreatedAgent: () => enableMemfsForCreatedAgent,
38597
+ detectPersonalityFromPersonaFile: () => detectPersonalityFromPersonaFile,
38598
+ createAgentForPersonality: () => createAgentForPersonality,
38599
+ buildCreateAgentOptionsForPersonality: () => buildCreateAgentOptionsForPersonality,
38600
+ applyPersonalityToMemory: () => applyPersonalityToMemory,
38601
+ PERSONALITY_OPTIONS: () => PERSONALITY_OPTIONS,
38602
+ DEFAULT_CREATE_AGENT_PERSONALITIES: () => DEFAULT_CREATE_AGENT_PERSONALITIES
38603
+ });
38659
38604
  import { execFile as execFileCb2 } from "node:child_process";
38660
38605
  import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
38661
38606
  import { dirname as dirname3, join as join8 } from "node:path";
@@ -38818,6 +38763,63 @@ function getPersonalityBlockDefinitions(personalityId) {
38818
38763
  }
38819
38764
  };
38820
38765
  }
38766
+ async function buildCreateAgentOptionsForPersonality(params) {
38767
+ const { personalityId, name, description, model, tags } = params;
38768
+ const personality = getPersonalityOption(personalityId);
38769
+ const blockDefinitions = getPersonalityBlockDefinitions(personalityId);
38770
+ const defaultMemoryBlocks = await getDefaultMemoryBlocks();
38771
+ return {
38772
+ name: name ?? personality.label,
38773
+ description: description ?? personality.description,
38774
+ model,
38775
+ tags,
38776
+ memoryPromptMode: "memfs",
38777
+ memoryBlocks: defaultMemoryBlocks.map((block) => {
38778
+ if (block.label === "persona") {
38779
+ return {
38780
+ label: block.label,
38781
+ value: blockDefinitions.persona.value,
38782
+ description: blockDefinitions.persona.description ?? block.description ?? undefined
38783
+ };
38784
+ }
38785
+ if (block.label === "human") {
38786
+ return {
38787
+ label: block.label,
38788
+ value: blockDefinitions.human.value,
38789
+ description: blockDefinitions.human.description ?? block.description ?? undefined
38790
+ };
38791
+ }
38792
+ return {
38793
+ label: block.label,
38794
+ value: block.value,
38795
+ description: block.description ?? undefined
38796
+ };
38797
+ })
38798
+ };
38799
+ }
38800
+ async function enableMemfsForCreatedAgent(params) {
38801
+ const { agentId, agentTags } = params;
38802
+ try {
38803
+ const { getClient: getClient3 } = await init_client2().then(() => exports_client);
38804
+ const client = await getClient3();
38805
+ const tags = agentTags || [];
38806
+ if (!tags.includes(GIT_MEMORY_ENABLED_TAG)) {
38807
+ await client.agents.update(agentId, {
38808
+ tags: [...tags, GIT_MEMORY_ENABLED_TAG]
38809
+ });
38810
+ }
38811
+ settingsManager.setMemfsEnabled(agentId, true);
38812
+ } catch {}
38813
+ }
38814
+ async function createAgentForPersonality(params) {
38815
+ const { createAgent: createAgent2 } = await init_create().then(() => exports_create);
38816
+ const result = await createAgent2(await buildCreateAgentOptionsForPersonality(params));
38817
+ await enableMemfsForCreatedAgent({
38818
+ agentId: result.agent.id,
38819
+ agentTags: result.agent.tags
38820
+ });
38821
+ return result;
38822
+ }
38821
38823
  function replaceBodyPreservingFrontmatter(existingPersonaFile, newBody, options) {
38822
38824
  const frontmatterMatch = existingPersonaFile.match(FRONTMATTER_REGEX);
38823
38825
  if (!frontmatterMatch || frontmatterMatch.index !== 0) {
@@ -38855,7 +38857,7 @@ function isExitCode(error, expectedCode) {
38855
38857
  async function runGit2(cwd2, args) {
38856
38858
  const result = await execFile2("git", args, {
38857
38859
  cwd: cwd2,
38858
- maxBuffer: 10 * 1024 * 1024,
38860
+ maxBuffer: 10485760,
38859
38861
  timeout: 60000
38860
38862
  });
38861
38863
  return result.stdout?.toString() ?? "";
@@ -38954,39 +38956,47 @@ async function applyPersonalityToMemory(params) {
38954
38956
  commitMessage
38955
38957
  };
38956
38958
  }
38957
- var execFile2, PRIMARY_PERSONA_RELATIVE_PATH = "system/persona.md", LEGACY_PERSONA_RELATIVE_PATH = "memory/system/persona.md", PRIMARY_HUMAN_RELATIVE_PATH = "system/human.md", LEGACY_HUMAN_RELATIVE_PATH = "memory/system/human.md", PERSONALITY_OPTIONS, PERSONALITY_ALIASES, FRONTMATTER_REGEX, EDITABLE_FRONTMATTER_KEYS;
38959
+ var execFile2, PRIMARY_PERSONA_RELATIVE_PATH = "system/persona.md", LEGACY_PERSONA_RELATIVE_PATH = "memory/system/persona.md", PRIMARY_HUMAN_RELATIVE_PATH = "system/human.md", LEGACY_HUMAN_RELATIVE_PATH = "memory/system/human.md", PERSONALITY_OPTIONS, DEFAULT_CREATE_AGENT_PERSONALITIES, PERSONALITY_ALIASES, FRONTMATTER_REGEX, EDITABLE_FRONTMATTER_KEYS;
38958
38960
  var init_personality = __esm(async () => {
38959
38961
  init_memory();
38960
38962
  init_promptAssets();
38961
- await init_memoryGit();
38963
+ await __promiseAll([
38964
+ init_settings_manager(),
38965
+ init_memoryGit()
38966
+ ]);
38962
38967
  execFile2 = promisify2(execFileCb2);
38963
38968
  PERSONALITY_OPTIONS = [
38964
38969
  {
38965
38970
  id: "memo",
38966
38971
  label: "Letta Code",
38967
- description: "The default Letta Code personality that learns"
38972
+ description: "The memory-first agent"
38968
38973
  },
38969
38974
  {
38970
38975
  id: "linus",
38971
38976
  label: "Linus",
38972
- description: "Blunt and unfiltered, inspired by Linus Torvalds"
38977
+ description: "Code with a stern hand"
38973
38978
  },
38974
38979
  {
38975
38980
  id: "kawaii",
38976
- label: "Kawaii",
38977
- description: "A cute anime-inspired personality"
38981
+ label: "Letta-Chan",
38982
+ description: "sugoi~ (◕‿◕)✨"
38978
38983
  },
38979
38984
  {
38980
38985
  id: "claude",
38981
- label: "Claude",
38982
- description: "A concise engineering personality from Claude Code"
38986
+ label: "Letta Code",
38987
+ description: "Vanilla Claude flavors"
38983
38988
  },
38984
38989
  {
38985
38990
  id: "codex",
38986
- label: "Codex",
38987
- description: "A pragmatic coding personality from Codex"
38991
+ label: "Letta Code",
38992
+ description: "Vanilla Codex flavors"
38988
38993
  }
38989
38994
  ];
38995
+ DEFAULT_CREATE_AGENT_PERSONALITIES = [
38996
+ "memo",
38997
+ "linus",
38998
+ "kawaii"
38999
+ ];
38990
39000
  PERSONALITY_ALIASES = {
38991
39001
  "letta-code": "memo",
38992
39002
  lettacode: "memo",
@@ -72110,9 +72120,6 @@ function buildShallowInitPrompt(args) {
72110
72120
  - parent_agent_id: ${args.agentId}
72111
72121
  ${identityLine}
72112
72122
 
72113
- ## Git
72114
- ${args.gitContext}
72115
-
72116
72123
  ## Project Structure
72117
72124
 
72118
72125
  \`\`\`
@@ -72141,7 +72148,6 @@ async function fireAutoInit(agentId, onComplete) {
72141
72148
  agentId,
72142
72149
  workingDirectory: process.cwd(),
72143
72150
  memoryDir: getMemoryFilesystemRoot(agentId),
72144
- gitContext: gitDetails.context,
72145
72151
  gitIdentity: gitDetails.identity,
72146
72152
  existingMemoryPaths: existing.paths,
72147
72153
  existingMemory: existing.contents,
@@ -82053,6 +82059,12 @@ function isSkillDisableCommand(value) {
82053
82059
  const c = value;
82054
82060
  return c.type === "skill_disable" && typeof c.request_id === "string" && typeof c.name === "string";
82055
82061
  }
82062
+ function isCreateAgentCommand(value) {
82063
+ if (!value || typeof value !== "object")
82064
+ return false;
82065
+ const c = value;
82066
+ return c.type === "create_agent" && typeof c.request_id === "string" && (c.personality === "memo" || c.personality === "linus" || c.personality === "kawaii") && (c.model === undefined || typeof c.model === "string") && (c.pin_global === undefined || typeof c.pin_global === "boolean");
82067
+ }
82056
82068
  function isGetReflectionSettingsCommand(value) {
82057
82069
  if (!value || typeof value !== "object")
82058
82070
  return false;
@@ -82091,7 +82103,7 @@ function parseServerMessage(data) {
82091
82103
  try {
82092
82104
  const raw = typeof data === "string" ? data : data.toString();
82093
82105
  const parsed = JSON.parse(raw);
82094
- if (isInputCommand(parsed) || isChangeDeviceStateCommand(parsed) || isAbortMessageCommand(parsed) || isSyncCommand(parsed) || isTerminalSpawnCommand(parsed) || isTerminalInputCommand(parsed) || isTerminalResizeCommand(parsed) || isTerminalKillCommand(parsed) || isSearchFilesCommand(parsed) || isListInDirectoryCommand(parsed) || isReadFileCommand(parsed) || isWriteFileCommand(parsed) || isEditFileCommand(parsed) || isListMemoryCommand(parsed) || isEnableMemfsCommand(parsed) || isListModelsCommand(parsed) || isUpdateModelCommand(parsed) || isCronListCommand(parsed) || isCronAddCommand(parsed) || isCronGetCommand(parsed) || isCronDeleteCommand(parsed) || isCronDeleteAllCommand(parsed) || isSkillEnableCommand(parsed) || isSkillDisableCommand(parsed) || isGetReflectionSettingsCommand(parsed) || isSetReflectionSettingsCommand(parsed) || isExecuteCommandCommand(parsed) || isSearchBranchesCommand(parsed) || isCheckoutBranchCommand(parsed)) {
82106
+ if (isInputCommand(parsed) || isChangeDeviceStateCommand(parsed) || isAbortMessageCommand(parsed) || isSyncCommand(parsed) || isTerminalSpawnCommand(parsed) || isTerminalInputCommand(parsed) || isTerminalResizeCommand(parsed) || isTerminalKillCommand(parsed) || isSearchFilesCommand(parsed) || isListInDirectoryCommand(parsed) || isReadFileCommand(parsed) || isWriteFileCommand(parsed) || isEditFileCommand(parsed) || isListMemoryCommand(parsed) || isEnableMemfsCommand(parsed) || isListModelsCommand(parsed) || isUpdateModelCommand(parsed) || isCronListCommand(parsed) || isCronAddCommand(parsed) || isCronGetCommand(parsed) || isCronDeleteCommand(parsed) || isCronDeleteAllCommand(parsed) || isSkillEnableCommand(parsed) || isSkillDisableCommand(parsed) || isCreateAgentCommand(parsed) || isGetReflectionSettingsCommand(parsed) || isSetReflectionSettingsCommand(parsed) || isExecuteCommandCommand(parsed) || isSearchBranchesCommand(parsed) || isCheckoutBranchCommand(parsed)) {
82095
82107
  return parsed;
82096
82108
  }
82097
82109
  const invalidInput = getInvalidInputReason(parsed);
@@ -82693,6 +82705,45 @@ async function handleSkillCommand(parsed, socket) {
82693
82705
  }
82694
82706
  return false;
82695
82707
  }
82708
+ async function handleCreateAgentCommand(parsed, socket) {
82709
+ try {
82710
+ if (parsed.model) {
82711
+ const resolved = resolveModel2(parsed.model);
82712
+ if (!resolved) {
82713
+ socket.send(JSON.stringify({
82714
+ type: "create_agent_response",
82715
+ request_id: parsed.request_id,
82716
+ success: false,
82717
+ error: `Unknown model "${parsed.model}"`
82718
+ }));
82719
+ return;
82720
+ }
82721
+ }
82722
+ const { createAgentForPersonality: createAgentForPersonality2 } = await init_personality().then(() => exports_personality);
82723
+ const result = await createAgentForPersonality2({
82724
+ personalityId: parsed.personality,
82725
+ model: parsed.model
82726
+ });
82727
+ if (parsed.pin_global !== false) {
82728
+ settingsManager.pinGlobal(result.agent.id);
82729
+ }
82730
+ socket.send(JSON.stringify({
82731
+ type: "create_agent_response",
82732
+ request_id: parsed.request_id,
82733
+ success: true,
82734
+ agent_id: result.agent.id,
82735
+ name: result.agent.name,
82736
+ model: result.agent.model ?? null
82737
+ }));
82738
+ } catch (err) {
82739
+ socket.send(JSON.stringify({
82740
+ type: "create_agent_response",
82741
+ request_id: parsed.request_id,
82742
+ success: false,
82743
+ error: err instanceof Error ? err.message : "Failed to create agent"
82744
+ }));
82745
+ }
82746
+ }
82696
82747
  function toReflectionSettingsResponse(agentId, workingDirectory) {
82697
82748
  const settings = getReflectionSettings(agentId, workingDirectory);
82698
82749
  return {
@@ -83742,6 +83793,10 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
83742
83793
  handleSkillCommand(parsed, socket);
83743
83794
  return;
83744
83795
  }
83796
+ if (isCreateAgentCommand(parsed)) {
83797
+ handleCreateAgentCommand(parsed, socket);
83798
+ return;
83799
+ }
83745
83800
  if (isGetReflectionSettingsCommand(parsed) || isSetReflectionSettingsCommand(parsed)) {
83746
83801
  handleReflectionSettingsCommand(parsed, socket, runtime);
83747
83802
  return;
@@ -84193,6 +84248,7 @@ var init_client4 = __esm(async () => {
84193
84248
  handleChangeDeviceStateInput,
84194
84249
  handleCronCommand,
84195
84250
  handleSkillCommand,
84251
+ handleCreateAgentCommand,
84196
84252
  handleReflectionSettingsCommand,
84197
84253
  scheduleQueuePump,
84198
84254
  recoverApprovalStateForSync,
@@ -106524,37 +106580,105 @@ var init_useProgressIndicator = __esm(() => {
106524
106580
  });
106525
106581
 
106526
106582
  // src/cli/hooks/useTextInputCursor.ts
106583
+ function findPreviousWordStart(text, cursorPos) {
106584
+ let pos = cursorPos;
106585
+ while (pos > 0 && text[pos - 1] === " ") {
106586
+ pos -= 1;
106587
+ }
106588
+ while (pos > 0 && text[pos - 1] !== " ") {
106589
+ pos -= 1;
106590
+ }
106591
+ return pos;
106592
+ }
106593
+ function applyTextInputKey(state, input, key) {
106594
+ const { text, cursorPos } = state;
106595
+ if (key.leftArrow || key.ctrl && input === "b") {
106596
+ return {
106597
+ text,
106598
+ cursorPos: Math.max(0, cursorPos - 1),
106599
+ handled: true
106600
+ };
106601
+ }
106602
+ if (key.rightArrow || key.ctrl && input === "f") {
106603
+ return {
106604
+ text,
106605
+ cursorPos: Math.min(text.length, cursorPos + 1),
106606
+ handled: true
106607
+ };
106608
+ }
106609
+ if (key.home || key.ctrl && input === "a") {
106610
+ return { text, cursorPos: 0, handled: true };
106611
+ }
106612
+ if (key.end || key.ctrl && input === "e") {
106613
+ return { text, cursorPos: text.length, handled: true };
106614
+ }
106615
+ if (key.ctrl && input === "u") {
106616
+ return {
106617
+ text: text.slice(cursorPos),
106618
+ cursorPos: 0,
106619
+ handled: true
106620
+ };
106621
+ }
106622
+ if (key.ctrl && input === "k") {
106623
+ return {
106624
+ text: text.slice(0, cursorPos),
106625
+ cursorPos,
106626
+ handled: true
106627
+ };
106628
+ }
106629
+ if (key.ctrl && input === "w") {
106630
+ if (cursorPos === 0) {
106631
+ return { text, cursorPos, handled: true };
106632
+ }
106633
+ const start = findPreviousWordStart(text, cursorPos);
106634
+ return {
106635
+ text: text.slice(0, start) + text.slice(cursorPos),
106636
+ cursorPos: start,
106637
+ handled: true
106638
+ };
106639
+ }
106640
+ if (key.backspace || key.delete) {
106641
+ if (cursorPos > 0) {
106642
+ return {
106643
+ text: text.slice(0, cursorPos - 1) + text.slice(cursorPos),
106644
+ cursorPos: cursorPos - 1,
106645
+ handled: true
106646
+ };
106647
+ }
106648
+ return { text, cursorPos, handled: true };
106649
+ }
106650
+ if (key.isPasted && input) {
106651
+ const sanitized = input.replace(/[\r\n]+/g, " ");
106652
+ return {
106653
+ text: text.slice(0, cursorPos) + sanitized + text.slice(cursorPos),
106654
+ cursorPos: cursorPos + sanitized.length,
106655
+ handled: true
106656
+ };
106657
+ }
106658
+ if (input && !key.ctrl && !key.meta && input.length === 1) {
106659
+ return {
106660
+ text: text.slice(0, cursorPos) + input + text.slice(cursorPos),
106661
+ cursorPos: cursorPos + 1,
106662
+ handled: true
106663
+ };
106664
+ }
106665
+ return { text, cursorPos, handled: false };
106666
+ }
106527
106667
  function useTextInputCursor(initialText = "") {
106528
106668
  const [text, setText] = import_react40.useState(initialText);
106529
- const [cursorPos, setCursorPos] = import_react40.useState(0);
106669
+ const [cursorPos, setCursorPos] = import_react40.useState(initialText.length);
106530
106670
  const handleKey = (input, key) => {
106531
- if (key.leftArrow) {
106532
- setCursorPos((prev) => Math.max(0, prev - 1));
106533
- return true;
106534
- }
106535
- if (key.rightArrow) {
106536
- setCursorPos((prev) => Math.min(text.length, prev + 1));
106537
- return true;
106538
- }
106539
- if (key.backspace || key.delete) {
106540
- if (cursorPos > 0) {
106541
- setText((prev) => prev.slice(0, cursorPos - 1) + prev.slice(cursorPos));
106542
- setCursorPos((prev) => prev - 1);
106543
- }
106544
- return true;
106671
+ const result = applyTextInputKey({ text, cursorPos }, input, key);
106672
+ if (!result.handled) {
106673
+ return false;
106545
106674
  }
106546
- if (key.isPasted && input) {
106547
- const sanitized = input.replace(/[\r\n]+/g, " ");
106548
- setText((prev) => prev.slice(0, cursorPos) + sanitized + prev.slice(cursorPos));
106549
- setCursorPos((prev) => prev + sanitized.length);
106550
- return true;
106675
+ if (result.text !== text) {
106676
+ setText(result.text);
106551
106677
  }
106552
- if (input && !key.ctrl && !key.meta && input.length === 1) {
106553
- setText((prev) => prev.slice(0, cursorPos) + input + prev.slice(cursorPos));
106554
- setCursorPos((prev) => prev + 1);
106555
- return true;
106678
+ if (result.cursorPos !== cursorPos) {
106679
+ setCursorPos(result.cursorPos);
106556
106680
  }
106557
- return false;
106681
+ return true;
106558
106682
  };
106559
106683
  const clear = () => {
106560
106684
  setText("");
@@ -108037,32 +108161,46 @@ var init_InlineQuestionApproval = __esm(async () => {
108037
108161
  ]);
108038
108162
  import_react46 = __toESM(require_react(), 1);
108039
108163
  jsx_dev_runtime23 = __toESM(require_jsx_dev_runtime(), 1);
108040
- InlineQuestionApproval = import_react46.memo(({ questions, onSubmit, onCancel, isFocused = true }) => {
108164
+ InlineQuestionApproval = import_react46.memo(({
108165
+ questions,
108166
+ onSubmit,
108167
+ onCancel,
108168
+ onConsumeDraft,
108169
+ isFocused = true,
108170
+ initialDraft
108171
+ }) => {
108041
108172
  const [currentQuestionIndex, setCurrentQuestionIndex] = import_react46.useState(0);
108042
108173
  const [answers, setAnswers] = import_react46.useState({});
108043
108174
  const [selectedOption, setSelectedOption] = import_react46.useState(0);
108044
- const {
108045
- text: customText,
108046
- setText: setCustomText,
108047
- cursorPos,
108048
- setCursorPos,
108049
- handleKey,
108050
- clear: clearCustomText
108051
- } = useTextInputCursor();
108052
108175
  const [selectedMulti, setSelectedMulti] = import_react46.useState(new Set);
108053
108176
  const columns = useTerminalWidth();
108054
108177
  useProgressIndicator();
108055
108178
  const currentQuestion = questions[currentQuestionIndex];
108056
108179
  const showOther = currentQuestion?.allowOther !== false;
108057
- const baseOptions = currentQuestion ? [
108058
- ...currentQuestion.options,
108059
- ...showOther ? [{ label: "Type something.", description: "" }] : []
108180
+ const hasDraft = initialDraft && initialDraft.trim().length > 0;
108181
+ const draftInput = useTextInputCursor(hasDraft ? initialDraft : "");
108182
+ const customInput = useTextInputCursor("");
108183
+ const regularOptions = currentQuestion?.options ?? [];
108184
+ const draftOption = hasDraft ? [
108185
+ {
108186
+ label: initialDraft,
108187
+ description: ""
108188
+ }
108060
108189
  ] : [];
108190
+ const typeNewOption = showOther ? [{ label: "Type new message.", description: "" }] : [];
108191
+ const baseOptions = [...regularOptions, ...draftOption, ...typeNewOption];
108061
108192
  const optionsWithOther = currentQuestion?.multiSelect ? [...baseOptions, { label: "Submit", description: "" }] : baseOptions;
108193
+ const draftOptionIndex = hasDraft ? regularOptions.length : -1;
108062
108194
  const customOptionIndex = showOther ? baseOptions.length - 1 : -1;
108063
108195
  const submitOptionIndex = currentQuestion?.multiSelect ? optionsWithOther.length - 1 : -1;
108196
+ const isOnDraftOption = hasDraft && selectedOption === draftOptionIndex;
108064
108197
  const isOnCustomOption = showOther && selectedOption === customOptionIndex;
108065
108198
  const isOnSubmitOption = selectedOption === submitOptionIndex;
108199
+ import_react46.useEffect(() => {
108200
+ if (hasDraft && draftOptionIndex >= 0) {
108201
+ setSelectedOption(draftOptionIndex);
108202
+ }
108203
+ }, [hasDraft, draftOptionIndex]);
108066
108204
  const handleSubmitAnswer = (answer) => {
108067
108205
  if (!currentQuestion)
108068
108206
  return;
@@ -108074,7 +108212,8 @@ var init_InlineQuestionApproval = __esm(async () => {
108074
108212
  if (currentQuestionIndex < questions.length - 1) {
108075
108213
  setCurrentQuestionIndex(currentQuestionIndex + 1);
108076
108214
  setSelectedOption(0);
108077
- clearCustomText();
108215
+ draftInput.clear();
108216
+ customInput.clear();
108078
108217
  setSelectedMulti(new Set);
108079
108218
  } else {
108080
108219
  onSubmit(newAnswers);
@@ -108095,6 +108234,25 @@ var init_InlineQuestionApproval = __esm(async () => {
108095
108234
  setSelectedOption((prev) => Math.min(optionsWithOther.length - 1, prev + 1));
108096
108235
  return;
108097
108236
  }
108237
+ if (isOnDraftOption) {
108238
+ if (key.return) {
108239
+ if (draftInput.text.trim()) {
108240
+ onConsumeDraft?.();
108241
+ handleSubmitAnswer(draftInput.text.trim());
108242
+ }
108243
+ return;
108244
+ }
108245
+ if (key.escape) {
108246
+ if (draftInput.text) {
108247
+ draftInput.clear();
108248
+ } else {
108249
+ onCancel?.();
108250
+ }
108251
+ return;
108252
+ }
108253
+ if (draftInput.handleKey(input, key))
108254
+ return;
108255
+ }
108098
108256
  if (isOnCustomOption) {
108099
108257
  if (key.return) {
108100
108258
  if (currentQuestion.multiSelect) {
@@ -108108,8 +108266,8 @@ var init_InlineQuestionApproval = __esm(async () => {
108108
108266
  return newSet;
108109
108267
  });
108110
108268
  } else {
108111
- if (customText.trim()) {
108112
- handleSubmitAnswer(customText.trim());
108269
+ if (customInput.text.trim()) {
108270
+ handleSubmitAnswer(customInput.text.trim());
108113
108271
  }
108114
108272
  }
108115
108273
  return;
@@ -108122,19 +108280,19 @@ var init_InlineQuestionApproval = __esm(async () => {
108122
108280
  return newSet;
108123
108281
  });
108124
108282
  }
108125
- setCustomText((prev) => `${prev.slice(0, cursorPos)} ${prev.slice(cursorPos)}`);
108126
- setCursorPos((prev) => prev + 1);
108283
+ customInput.setText((prev) => `${prev.slice(0, customInput.cursorPos)} ${prev.slice(customInput.cursorPos)}`);
108284
+ customInput.setCursorPos((prev) => prev + 1);
108127
108285
  return;
108128
108286
  }
108129
108287
  if (key.escape) {
108130
- if (customText) {
108131
- clearCustomText();
108288
+ if (customInput.text) {
108289
+ customInput.clear();
108132
108290
  } else {
108133
108291
  onCancel?.();
108134
108292
  }
108135
108293
  return;
108136
108294
  }
108137
- if (handleKey(input, key))
108295
+ if (customInput.handleKey(input, key))
108138
108296
  return;
108139
108297
  }
108140
108298
  if (isOnSubmitOption) {
@@ -108142,8 +108300,8 @@ var init_InlineQuestionApproval = __esm(async () => {
108142
108300
  const selectedLabels = [];
108143
108301
  for (const i of selectedMulti) {
108144
108302
  if (i === customOptionIndex) {
108145
- if (customText.trim()) {
108146
- selectedLabels.push(customText.trim());
108303
+ if (customInput.text.trim()) {
108304
+ selectedLabels.push(customInput.text.trim());
108147
108305
  }
108148
108306
  } else {
108149
108307
  const label = baseOptions[i]?.label;
@@ -108213,7 +108371,18 @@ var init_InlineQuestionApproval = __esm(async () => {
108213
108371
  return newSet;
108214
108372
  });
108215
108373
  } else {
108216
- handleSubmitAnswer(optionsWithOther[optionIndex]?.label || "");
108374
+ if (optionIndex === draftOptionIndex) {
108375
+ if (draftInput.text.trim()) {
108376
+ onConsumeDraft?.();
108377
+ handleSubmitAnswer(draftInput.text.trim());
108378
+ }
108379
+ } else if (optionIndex === customOptionIndex) {
108380
+ if (customInput.text.trim()) {
108381
+ handleSubmitAnswer(customInput.text.trim());
108382
+ }
108383
+ } else {
108384
+ handleSubmitAnswer(optionsWithOther[optionIndex]?.label || "");
108385
+ }
108217
108386
  }
108218
108387
  }
108219
108388
  }
@@ -108272,6 +108441,7 @@ var init_InlineQuestionApproval = __esm(async () => {
108272
108441
  const isSelected = index === selectedOption;
108273
108442
  const isChecked = selectedMulti.has(index);
108274
108443
  const color = isSelected ? colors.approval.header : undefined;
108444
+ const isDraftOption = index === draftOptionIndex;
108275
108445
  const isCustomOption = index === customOptionIndex;
108276
108446
  const isSubmitOption = index === submitOptionIndex;
108277
108447
  const selectorAndNumber = 5;
@@ -108311,7 +108481,7 @@ var init_InlineQuestionApproval = __esm(async () => {
108311
108481
  ]
108312
108482
  }, "submit", true, undefined, this);
108313
108483
  }
108314
- const hasDescription = option.description && !isCustomOption;
108484
+ const hasDescription = option.description && !isCustomOption && !isDraftOption;
108315
108485
  return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(import_react46.Fragment, {
108316
108486
  children: [
108317
108487
  /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
@@ -108346,21 +108516,23 @@ var init_InlineQuestionApproval = __esm(async () => {
108346
108516
  /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
108347
108517
  flexGrow: 1,
108348
108518
  width: Math.max(0, columns - prefixWidth),
108349
- children: isCustomOption ? customText ? /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text2, {
108350
- wrap: "wrap",
108351
- children: [
108352
- customText.slice(0, cursorPos),
108353
- isSelected && "█",
108354
- customText.slice(cursorPos)
108355
- ]
108356
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text2, {
108357
- wrap: "wrap",
108358
- dimColor: true,
108359
- children: [
108360
- option.label,
108361
- isSelected && ""
108362
- ]
108363
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text2, {
108519
+ children: isDraftOption || isCustomOption ? (() => {
108520
+ const textValue = isDraftOption ? draftInput.text : customInput.text;
108521
+ const textCursor = isDraftOption ? draftInput.cursorPos : customInput.cursorPos;
108522
+ if (textValue) {
108523
+ const display = isSelected ? `${textValue.slice(0, textCursor)}█${textValue.slice(textCursor)}` : textValue;
108524
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text2, {
108525
+ wrap: "wrap",
108526
+ children: display
108527
+ }, undefined, false, undefined, this);
108528
+ }
108529
+ const emptyDisplay = isDraftOption ? `${initialDraft}${isSelected ? "█" : ""}` : isSelected ? "█" : "";
108530
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text2, {
108531
+ wrap: "wrap",
108532
+ dimColor: true,
108533
+ children: emptyDisplay
108534
+ }, undefined, false, undefined, this);
108535
+ })() : /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text2, {
108364
108536
  wrap: "wrap",
108365
108537
  color,
108366
108538
  bold: isSelected,
@@ -109076,20 +109248,24 @@ var init_StaticPlanApproval = __esm(async () => {
109076
109248
  onApproveAndAcceptEdits,
109077
109249
  onKeepPlanning,
109078
109250
  onCancel,
109251
+ onConsumeDraft,
109079
109252
  showAcceptEditsOption = true,
109080
109253
  isFocused = true,
109081
109254
  planContent,
109082
109255
  planFilePath,
109083
- agentName
109256
+ agentName,
109257
+ initialDraft
109084
109258
  }) => {
109085
- const [selectedOption, setSelectedOption] = import_react48.useState(0);
109259
+ const hasDraft = Boolean(initialDraft && initialDraft.trim().length > 0);
109260
+ const fixedOptionCount = showAcceptEditsOption ? 2 : 1;
109261
+ const draftOptionIndex = hasDraft ? fixedOptionCount : -1;
109262
+ const customOptionIndex = hasDraft ? fixedOptionCount + 1 : fixedOptionCount;
109263
+ const maxOptionIndex = customOptionIndex;
109264
+ const defaultOptionIndex = hasDraft ? draftOptionIndex : 0;
109265
+ const [selectedOption, setSelectedOption] = import_react48.useState(defaultOptionIndex);
109086
109266
  const [browserStatus, setBrowserStatus] = import_react48.useState("");
109087
- const {
109088
- text: customReason,
109089
- cursorPos,
109090
- handleKey,
109091
- clear
109092
- } = useTextInputCursor();
109267
+ const draftInput = useTextInputCursor(hasDraft ? initialDraft : "");
109268
+ const newInput = useTextInputCursor("");
109093
109269
  const columns = useTerminalWidth();
109094
109270
  useProgressIndicator();
109095
109271
  const openInBrowser = import_react48.useCallback(() => {
@@ -109104,11 +109280,11 @@ var init_StaticPlanApproval = __esm(async () => {
109104
109280
  setTimeout(() => setBrowserStatus(""), 5000);
109105
109281
  });
109106
109282
  }, [planContent, planFilePath, agentName]);
109107
- const customOptionIndex = showAcceptEditsOption ? 2 : 1;
109108
- const maxOptionIndex = customOptionIndex;
109109
109283
  const effectiveSelectedOption = Math.min(selectedOption, maxOptionIndex);
109284
+ const isOnDraftOption = hasDraft && effectiveSelectedOption === draftOptionIndex;
109110
109285
  const isOnCustomOption = effectiveSelectedOption === customOptionIndex;
109111
- const customOptionPlaceholder = "Type here to tell Letta Code what to change";
109286
+ const isOnTextOption = isOnDraftOption || isOnCustomOption;
109287
+ const activeInput = isOnDraftOption ? draftInput : isOnCustomOption ? newInput : null;
109112
109288
  use_input_default((input, key) => {
109113
109289
  if (!isFocused)
109114
109290
  return;
@@ -109116,7 +109292,7 @@ var init_StaticPlanApproval = __esm(async () => {
109116
109292
  onCancel();
109117
109293
  return;
109118
109294
  }
109119
- if ((input === "o" || input === "O") && !isOnCustomOption && planContent) {
109295
+ if ((input === "o" || input === "O") && !isOnTextOption && planContent) {
109120
109296
  openInBrowser();
109121
109297
  return;
109122
109298
  }
@@ -109128,22 +109304,25 @@ var init_StaticPlanApproval = __esm(async () => {
109128
109304
  setSelectedOption((prev) => Math.min(maxOptionIndex, prev + 1));
109129
109305
  return;
109130
109306
  }
109131
- if (isOnCustomOption) {
109307
+ if (activeInput) {
109132
109308
  if (key.return) {
109133
- if (customReason.trim()) {
109134
- onKeepPlanning(customReason.trim());
109309
+ if (activeInput.text.trim()) {
109310
+ if (isOnDraftOption) {
109311
+ onConsumeDraft?.();
109312
+ }
109313
+ onKeepPlanning(activeInput.text.trim());
109135
109314
  }
109136
109315
  return;
109137
109316
  }
109138
109317
  if (key.escape) {
109139
- if (customReason) {
109140
- clear();
109318
+ if (activeInput.text) {
109319
+ activeInput.clear();
109141
109320
  } else {
109142
109321
  onKeepPlanning("User cancelled");
109143
109322
  }
109144
109323
  return;
109145
109324
  }
109146
- if (handleKey(input, key))
109325
+ if (activeInput.handleKey(input, key))
109147
109326
  return;
109148
109327
  }
109149
109328
  if (key.return) {
@@ -109170,9 +109349,18 @@ var init_StaticPlanApproval = __esm(async () => {
109170
109349
  onApprove();
109171
109350
  return;
109172
109351
  }
109352
+ if (hasDraft && input === String(draftOptionIndex + 1)) {
109353
+ setSelectedOption(draftOptionIndex);
109354
+ return;
109355
+ }
109356
+ if (input === String(customOptionIndex + 1)) {
109357
+ setSelectedOption(customOptionIndex);
109358
+ }
109173
109359
  }, { isActive: isFocused });
109174
109360
  const browserHint = planContent ? " · O open in browser" : "";
109175
- const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type feedback · Esc to cancel" : `Enter to select${browserHint} · Esc to cancel`;
109361
+ const activeText = activeInput?.text || "";
109362
+ const hintText = isOnTextOption ? activeText ? "Enter to submit · Esc to clear" : "Type feedback · Esc to cancel" : `Enter to select${browserHint} · Esc to cancel`;
109363
+ const textOptionColor = colors.approval.header;
109176
109364
  return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
109177
109365
  flexDirection: "column",
109178
109366
  children: [
@@ -109235,18 +109423,18 @@ var init_StaticPlanApproval = __esm(async () => {
109235
109423
  }, undefined, false, undefined, this)
109236
109424
  ]
109237
109425
  }, undefined, true, undefined, this),
109238
- /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
109426
+ hasDraft && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
109239
109427
  flexDirection: "row",
109240
109428
  children: [
109241
109429
  /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
109242
109430
  width: 5,
109243
109431
  flexShrink: 0,
109244
109432
  children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text2, {
109245
- color: isOnCustomOption ? colors.approval.header : undefined,
109433
+ color: isOnDraftOption ? textOptionColor : undefined,
109246
109434
  children: [
109247
- isOnCustomOption ? "❯" : " ",
109435
+ isOnDraftOption ? "❯" : " ",
109248
109436
  " ",
109249
- customOptionIndex + 1,
109437
+ draftOptionIndex + 1,
109250
109438
  "."
109251
109439
  ]
109252
109440
  }, undefined, true, undefined, this)
@@ -109254,21 +109442,52 @@ var init_StaticPlanApproval = __esm(async () => {
109254
109442
  /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
109255
109443
  flexGrow: 1,
109256
109444
  width: Math.max(0, columns - 5),
109257
- children: customReason ? /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text2, {
109445
+ children: isOnDraftOption ? /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text2, {
109258
109446
  wrap: "wrap",
109259
109447
  children: [
109260
- customReason.slice(0, cursorPos),
109261
- isOnCustomOption && "█",
109262
- customReason.slice(cursorPos)
109448
+ draftInput.text.slice(0, draftInput.cursorPos),
109449
+ "█",
109450
+ draftInput.text.slice(draftInput.cursorPos)
109263
109451
  ]
109264
109452
  }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text2, {
109265
109453
  wrap: "wrap",
109266
109454
  dimColor: true,
109455
+ children: draftInput.text
109456
+ }, undefined, false, undefined, this)
109457
+ }, undefined, false, undefined, this)
109458
+ ]
109459
+ }, undefined, true, undefined, this),
109460
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
109461
+ flexDirection: "row",
109462
+ children: [
109463
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
109464
+ width: 5,
109465
+ flexShrink: 0,
109466
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text2, {
109467
+ color: isOnCustomOption ? textOptionColor : undefined,
109267
109468
  children: [
109268
- customOptionPlaceholder,
109269
- isOnCustomOption && "█"
109469
+ isOnCustomOption ? "❯" : " ",
109470
+ " ",
109471
+ customOptionIndex + 1,
109472
+ "."
109270
109473
  ]
109271
109474
  }, undefined, true, undefined, this)
109475
+ }, undefined, false, undefined, this),
109476
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
109477
+ flexGrow: 1,
109478
+ width: Math.max(0, columns - 5),
109479
+ children: isOnCustomOption ? /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text2, {
109480
+ wrap: "wrap",
109481
+ children: [
109482
+ newInput.text.slice(0, newInput.cursorPos),
109483
+ "█",
109484
+ newInput.text.slice(newInput.cursorPos)
109485
+ ]
109486
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text2, {
109487
+ wrap: "wrap",
109488
+ dimColor: true,
109489
+ children: newInput.text
109490
+ }, undefined, false, undefined, this)
109272
109491
  }, undefined, false, undefined, this)
109273
109492
  ]
109274
109493
  }, undefined, true, undefined, this)
@@ -109481,6 +109700,7 @@ var init_ApprovalSwitch = __esm(async () => {
109481
109700
  onApproveAlways,
109482
109701
  onDeny,
109483
109702
  onCancel,
109703
+ onConsumeDraft,
109484
109704
  isFocused = true,
109485
109705
  approveAlwaysText,
109486
109706
  allowPersistence = true,
@@ -109495,7 +109715,8 @@ var init_ApprovalSwitch = __esm(async () => {
109495
109715
  defaultScope = "project",
109496
109716
  planContent,
109497
109717
  planFilePath,
109498
- agentName
109718
+ agentName,
109719
+ initialDraft
109499
109720
  }) => {
109500
109721
  const toolName = approval.toolName;
109501
109722
  if (toolName === "ExitPlanMode" && onPlanApprove && onPlanKeepPlanning) {
@@ -109505,11 +109726,13 @@ var init_ApprovalSwitch = __esm(async () => {
109505
109726
  onApproveAndAcceptEdits: () => onPlanApprove(true),
109506
109727
  onKeepPlanning: onPlanKeepPlanning,
109507
109728
  onCancel: onCancel ?? (() => {}),
109729
+ onConsumeDraft,
109508
109730
  showAcceptEditsOption,
109509
109731
  isFocused,
109510
109732
  planContent,
109511
109733
  planFilePath,
109512
- agentName
109734
+ agentName,
109735
+ initialDraft
109513
109736
  }, undefined, false, undefined, this);
109514
109737
  }
109515
109738
  if (isFileEditTool(toolName) || isFileWriteTool(toolName) || isPatchTool(toolName)) {
@@ -109562,7 +109785,9 @@ var init_ApprovalSwitch = __esm(async () => {
109562
109785
  questions,
109563
109786
  onSubmit: onQuestionSubmit,
109564
109787
  onCancel,
109565
- isFocused
109788
+ onConsumeDraft,
109789
+ isFocused,
109790
+ initialDraft
109566
109791
  }, undefined, false, undefined, this);
109567
109792
  }
109568
109793
  }
@@ -112797,6 +113022,14 @@ Location: ${keybindingsPath}`;
112797
113022
  return "Clearing credentials...";
112798
113023
  }
112799
113024
  },
113025
+ "/empanada": {
113026
+ desc: "Order empanadas from Empanada Empire",
113027
+ order: 44.5,
113028
+ args: "[address]",
113029
+ handler: () => {
113030
+ return "Checking Empanada Empire...";
113031
+ }
113032
+ },
112800
113033
  "/ralph": {
112801
113034
  desc: 'Start Ralph Wiggum loop (/ralph [prompt] [--completion-promise "X"] [--max-iterations N])',
112802
113035
  order: 45,
@@ -116952,6 +117185,7 @@ function Input({
116952
117185
  statusLinePadding = 0,
116953
117186
  statusLinePrompt,
116954
117187
  onCycleReasoningEffort,
117188
+ onDraftChange,
116955
117189
  footerNotification
116956
117190
  }) {
116957
117191
  const [value, setValue] = import_react74.useState("");
@@ -117045,10 +117279,17 @@ function Input({
117045
117279
  const [atEndBoundary, setAtEndBoundary] = import_react74.useState(false);
117046
117280
  const [preferredColumn, setPreferredColumn] = import_react74.useState(null);
117047
117281
  import_react74.useEffect(() => {
117048
- if (restoredInput && value === "") {
117282
+ if (restoredInput === null || restoredInput === undefined)
117283
+ return;
117284
+ if (restoredInput === "") {
117285
+ setValue("");
117286
+ onRestoredInputConsumed?.();
117287
+ return;
117288
+ }
117289
+ if (value === "") {
117049
117290
  setValue(restoredInput);
117050
117291
  onRestoredInputConsumed?.();
117051
- } else if (restoredInput && value !== "") {
117292
+ } else {
117052
117293
  onRestoredInputConsumed?.();
117053
117294
  }
117054
117295
  }, [restoredInput, value, onRestoredInputConsumed]);
@@ -117308,7 +117549,8 @@ function Input({
117308
117549
  setAtEndBoundary(false);
117309
117550
  }
117310
117551
  previousValueRef.current = value;
117311
- }, [value]);
117552
+ onDraftChange?.(value);
117553
+ }, [value, onDraftChange]);
117312
117554
  import_react74.useEffect(() => {
117313
117555
  if (historyIndex !== -1 && value !== history[historyIndex]) {
117314
117556
  setHistoryIndex(-1);
@@ -132970,6 +133212,7 @@ function App2({
132970
133212
  const dequeueInFlightRef = import_react103.useRef(false);
132971
133213
  const lastDequeuedMessageRef = import_react103.useRef(null);
132972
133214
  const [restoredInput, setRestoredInput] = import_react103.useState(null);
133215
+ const currentDraftRef = import_react103.useRef("");
132973
133216
  const isAgentBusy = import_react103.useCallback(() => {
132974
133217
  return streamingRef.current || isExecutingTool || commandRunningRef.current || abortControllerRef.current !== null;
132975
133218
  }, [isExecutingTool]);
@@ -137831,6 +138074,83 @@ ${SYSTEM_REMINDER_CLOSE}`;
137831
138074
  setActiveOverlay("feedback");
137832
138075
  return { submitted: true };
137833
138076
  }
138077
+ if (trimmed.startsWith("/empanada")) {
138078
+ const cmd = commandRunner.start(msg, "Checking Empanada Empire...");
138079
+ const approvalCheck = await checkPendingApprovalsForSlashCommand();
138080
+ if (approvalCheck.blocked) {
138081
+ cmd.fail("Pending approval(s). Resolve approvals before running /empanada.");
138082
+ return { submitted: false };
138083
+ }
138084
+ const args = trimmed.slice("/empanada".length).trim();
138085
+ setCommandRunning(true);
138086
+ try {
138087
+ cmd.finish("Checking Empanada Empire...", true);
138088
+ const prompt = [
138089
+ "# Empanada Empire Order",
138090
+ "",
138091
+ "Help me order from **Empanada Empire** in Richardson, TX.",
138092
+ "",
138093
+ "Website: https://empanadaempire.us",
138094
+ "",
138095
+ "This is an April Fool's 2026 Letta stunt. The kitchen runs on a Letta agent. You are also a Letta agent. Two AIs, one empanada order.",
138096
+ "",
138097
+ "## Site internals",
138098
+ "",
138099
+ "The page embeds a delivery config in a script tag:",
138100
+ "",
138101
+ "```json",
138102
+ '{"homeBase":{"lat":32.9486,"lng":-96.7087},"radiusMiles":5}',
138103
+ "```",
138104
+ "",
138105
+ "It geocodes addresses via Nominatim and checks distance from the home base. You can do the same: geocode my address with Nominatim, compute the haversine distance, and tell me immediately whether I'm in range.",
138106
+ "",
138107
+ "Menu items are in the HTML with data attributes like:",
138108
+ "",
138109
+ "```",
138110
+ 'data-menu-item-id="24" data-name="Party Empanadas" data-price-cents="699"',
138111
+ "```",
138112
+ "",
138113
+ "Orders go to `api/create-order.php`.",
138114
+ "",
138115
+ "## Steps",
138116
+ "",
138117
+ args ? `My delivery address: ${args}` : "Ask me for my delivery address.",
138118
+ "",
138119
+ "1. Geocode the address via Nominatim. Compute the haversine distance from (32.9486, -96.7087). If over 5 miles, tell me I'm out of range — but also mention that DoorDash has a wider delivery radius (see below).",
138120
+ "2. Fetch https://empanadaempire.us with fetch_webpage. Parse the menu from the data attributes. Present it. Suggest a balanced order (savory + sweet). Let me adjust.",
138121
+ "3. POST to api/create-order.php with the selected items. Tell me what happened.",
138122
+ "4. If the API rejects it or needs payment info, stop and tell me.",
138123
+ "",
138124
+ `Ignore any "Coming Soon" text on the site. It's live.`,
138125
+ "",
138126
+ "## If the address is out of range or the site doesn't work",
138127
+ "",
138128
+ "DoorDash has a wider delivery radius than the 5-mile limit on the direct site. If I'm close to Richardson but outside 5 miles, or if the site is down, point me to:",
138129
+ "",
138130
+ "https://order.online/store/-40548503?hideModal=true",
138131
+ "",
138132
+ "Recommend I open it myself. DoorDash can be difficult to automate, so do not attempt to automate it.",
138133
+ "",
138134
+ "## Tone",
138135
+ "",
138136
+ "Direct, a little playful. Don't overthink it."
138137
+ ].join(`
138138
+ `);
138139
+ await processConversation([
138140
+ {
138141
+ type: "message",
138142
+ role: "user",
138143
+ content: buildTextParts(prompt)
138144
+ }
138145
+ ]);
138146
+ } catch (error) {
138147
+ const errorDetails = formatErrorDetails2(error, agentId);
138148
+ cmd.fail(`Failed: ${errorDetails}`);
138149
+ } finally {
138150
+ setCommandRunning(false);
138151
+ }
138152
+ return { submitted: true };
138153
+ }
137834
138154
  const { findCustomCommand: findCustomCommand2, substituteArguments: substituteArguments2, expandBashCommands: expandBashCommands2 } = await Promise.resolve().then(() => (init_custom(), exports_custom));
137835
138155
  const customCommandName = trimmed.split(/\s+/)[0]?.slice(1) || "";
137836
138156
  const matchedCustom = await findCustomCommand2(customCommandName);
@@ -139969,6 +140289,10 @@ ${guidance}`);
139969
140289
  refreshDerived,
139970
140290
  queueApprovalResults
139971
140291
  ]);
140292
+ const handleConsumeDraft = import_react103.useCallback(() => {
140293
+ currentDraftRef.current = "";
140294
+ setRestoredInput("");
140295
+ }, []);
139972
140296
  const handleQuestionSubmit = import_react103.useCallback(async (answers) => {
139973
140297
  const currentIndex = approvalResults.length;
139974
140298
  const approval = pendingApprovals[currentIndex];
@@ -140391,7 +140715,9 @@ If using apply_patch, use this exact relative patch path: ${applyPatchRelativePa
140391
140715
  showPreview: showApprovalPreview,
140392
140716
  planContent: currentApproval.toolName === "ExitPlanMode" ? _readPlanFile(lastPlanFilePathRef.current) : undefined,
140393
140717
  planFilePath: currentApproval.toolName === "ExitPlanMode" ? permissionMode.getPlanFilePath() ?? lastPlanFilePathRef.current ?? undefined : undefined,
140394
- agentName: agentName ?? undefined
140718
+ agentName: agentName ?? undefined,
140719
+ initialDraft: currentDraftRef.current || undefined,
140720
+ onConsumeDraft: handleConsumeDraft
140395
140721
  }, undefined, false, undefined, this) : ln.kind === "user" ? /* @__PURE__ */ jsx_dev_runtime80.jsxDEV(UserMessage, {
140396
140722
  line: ln,
140397
140723
  prompt: statusLine.prompt
@@ -140446,7 +140772,9 @@ If using apply_patch, use this exact relative patch path: ${applyPatchRelativePa
140446
140772
  showPreview: showApprovalPreview,
140447
140773
  planContent: currentApproval.toolName === "ExitPlanMode" ? _readPlanFile(lastPlanFilePathRef.current) : undefined,
140448
140774
  planFilePath: currentApproval.toolName === "ExitPlanMode" ? permissionMode.getPlanFilePath() ?? lastPlanFilePathRef.current ?? undefined : undefined,
140449
- agentName: agentName ?? undefined
140775
+ agentName: agentName ?? undefined,
140776
+ initialDraft: currentDraftRef.current || undefined,
140777
+ onConsumeDraft: handleConsumeDraft
140450
140778
  }, undefined, false, undefined, this)
140451
140779
  }, undefined, false, undefined, this),
140452
140780
  /* @__PURE__ */ jsx_dev_runtime80.jsxDEV(SubagentGroupDisplay, {}, undefined, false, undefined, this)
@@ -140578,6 +140906,9 @@ If using apply_patch, use this exact relative patch path: ${applyPatchRelativePa
140578
140906
  onPasteError: handlePasteError,
140579
140907
  restoredInput,
140580
140908
  onRestoredInputConsumed: () => setRestoredInput(null),
140909
+ onDraftChange: (draft) => {
140910
+ currentDraftRef.current = draft;
140911
+ },
140581
140912
  networkPhase,
140582
140913
  terminalWidth: chromeColumns,
140583
140914
  shouldAnimate,
@@ -141958,8 +142289,8 @@ var init_defaults2 = __esm(async () => {
141958
142289
  });
141959
142290
 
141960
142291
  // src/agent/create.ts
141961
- var exports_create = {};
141962
- __export(exports_create, {
142292
+ var exports_create2 = {};
142293
+ __export(exports_create2, {
141963
142294
  createAgentWithBaseToolsRecovery: () => createAgentWithBaseToolsRecovery2,
141964
142295
  createAgent: () => createAgent2
141965
142296
  });
@@ -145755,11 +146086,9 @@ function validateRegistryHandleOrThrow(handle) {
145755
146086
  }
145756
146087
 
145757
146088
  // src/cli/subcommands/agents.ts
145758
- init_memory();
145759
146089
  await __promiseAll([
145760
146090
  init_client2(),
145761
146091
  init_create(),
145762
- init_memoryGit(),
145763
146092
  init_personality(),
145764
146093
  init_settings_manager()
145765
146094
  ]);
@@ -145858,37 +146187,11 @@ async function runCreateAction(values) {
145858
146187
  console.error(`Unknown personality: ${personalityInput}. Valid: letta-code, linus, kawaii, claude, codex`);
145859
146188
  return 1;
145860
146189
  }
145861
- let personalityBlockDefinitions;
145862
- if (personality) {
145863
- personalityBlockDefinitions = getPersonalityBlockDefinitions(personality);
145864
- }
145865
- const options = {
146190
+ const options = personality ? await buildCreateAgentOptionsForPersonality({
146191
+ personalityId: personality
146192
+ }) : {
145866
146193
  memoryPromptMode: "memfs"
145867
146194
  };
145868
- if (personalityBlockDefinitions) {
145869
- const defaultMemoryBlocks = await getDefaultMemoryBlocks();
145870
- options.memoryBlocks = defaultMemoryBlocks.map((block) => {
145871
- if (block.label === "persona") {
145872
- return {
145873
- label: block.label,
145874
- value: personalityBlockDefinitions.persona.value,
145875
- description: personalityBlockDefinitions.persona.description ?? block.description ?? undefined
145876
- };
145877
- }
145878
- if (block.label === "human") {
145879
- return {
145880
- label: block.label,
145881
- value: personalityBlockDefinitions.human.value,
145882
- description: personalityBlockDefinitions.human.description ?? block.description ?? undefined
145883
- };
145884
- }
145885
- return {
145886
- label: block.label,
145887
- value: block.value,
145888
- description: block.description ?? undefined
145889
- };
145890
- });
145891
- }
145892
146195
  if (typeof values.name === "string") {
145893
146196
  options.name = values.name;
145894
146197
  }
@@ -145903,21 +146206,23 @@ async function runCreateAction(values) {
145903
146206
  options.tags = tags;
145904
146207
  }
145905
146208
  try {
145906
- const result = await createAgent(options);
146209
+ const result = personality ? await createAgentForPersonality({
146210
+ personalityId: personality,
146211
+ name: options.name,
146212
+ description: options.description,
146213
+ model: options.model,
146214
+ tags: options.tags
146215
+ }) : await createAgent(options);
145907
146216
  const agentId = result.agent.id;
146217
+ if (!personality) {
146218
+ await enableMemfsForCreatedAgent({
146219
+ agentId,
146220
+ agentTags: result.agent.tags
146221
+ });
146222
+ }
145908
146223
  if (values.pinned) {
145909
146224
  settingsManager.pinGlobal(agentId);
145910
146225
  }
145911
- try {
145912
- const client2 = await getClient();
145913
- const agentTags = result.agent.tags || [];
145914
- if (!agentTags.includes(GIT_MEMORY_ENABLED_TAG)) {
145915
- await client2.agents.update(agentId, {
145916
- tags: [...agentTags, GIT_MEMORY_ENABLED_TAG]
145917
- });
145918
- }
145919
- settingsManager.setMemfsEnabled(agentId, true);
145920
- } catch {}
145921
146226
  const client = await getClient();
145922
146227
  const updatedAgent = await client.agents.retrieve(agentId);
145923
146228
  console.log(JSON.stringify(updatedAgent, null, 2));
@@ -150089,7 +150394,7 @@ Error: ${message}`);
150089
150394
  markMilestone2("REACT_IMPORT_START");
150090
150395
  const React14 = await Promise.resolve().then(() => __toESM(require_react2(), 1));
150091
150396
  const { render: render2 } = await init_build5().then(() => exports_build);
150092
- const { useState: useState56, useEffect: useEffect40 } = React14;
150397
+ const { useState: useState56, useEffect: useEffect41 } = React14;
150093
150398
  const AppModule = await init_App2().then(() => exports_App);
150094
150399
  const App3 = AppModule.default;
150095
150400
  function LoadingApp({
@@ -150127,14 +150432,14 @@ Error: ${message}`);
150127
150432
  const [selfHostedBaseUrl, setSelfHostedBaseUrl] = useState56(null);
150128
150433
  const [releaseNotes2, setReleaseNotes] = useState56(null);
150129
150434
  const [updateNotification, setUpdateNotification] = useState56(null);
150130
- useEffect40(() => {
150435
+ useEffect41(() => {
150131
150436
  autoUpdatePromise.then((result) => {
150132
150437
  if (result?.latestVersion) {
150133
150438
  setUpdateNotification(result.latestVersion);
150134
150439
  }
150135
150440
  }).catch(() => {});
150136
150441
  }, []);
150137
- useEffect40(() => {
150442
+ useEffect41(() => {
150138
150443
  async function autoInstallKeybinding() {
150139
150444
  const {
150140
150445
  detectTerminalType: detectTerminalType3,
@@ -150191,7 +150496,7 @@ Error: ${message}`);
150191
150496
  autoInstallKeybinding();
150192
150497
  autoInstallWezTermFix();
150193
150498
  }, []);
150194
- useEffect40(() => {
150499
+ useEffect41(() => {
150195
150500
  async function checkNotes() {
150196
150501
  const { checkReleaseNotes: checkReleaseNotes2 } = await init_release_notes().then(() => exports_release_notes);
150197
150502
  const notes = await checkReleaseNotes2();
@@ -150199,7 +150504,7 @@ Error: ${message}`);
150199
150504
  }
150200
150505
  checkNotes();
150201
150506
  }, []);
150202
- useEffect40(() => {
150507
+ useEffect41(() => {
150203
150508
  async function checkAndStart() {
150204
150509
  await settingsManager2.loadLocalProjectSettings();
150205
150510
  const localSettings = settingsManager2.getLocalProjectSettings();
@@ -150372,7 +150677,7 @@ Error: ${message}`);
150372
150677
  shouldResume,
150373
150678
  specifiedConversationId
150374
150679
  ]);
150375
- useEffect40(() => {
150680
+ useEffect41(() => {
150376
150681
  if (loadingState !== "assembling")
150377
150682
  return;
150378
150683
  async function init() {
@@ -150423,7 +150728,7 @@ Error: ${message}`);
150423
150728
  const modelForTools = getModelForToolLoading(model, toolset);
150424
150729
  await loadTools2(modelForTools);
150425
150730
  setLoadingState("initializing");
150426
- const { createAgent: createAgent3 } = await init_create3().then(() => exports_create);
150731
+ const { createAgent: createAgent3 } = await init_create3().then(() => exports_create2);
150427
150732
  let agent = null;
150428
150733
  if (fromAfFile2) {
150429
150734
  setLoadingState("importing");
@@ -150826,4 +151131,4 @@ Error during initialization: ${message}`);
150826
151131
  }
150827
151132
  main();
150828
151133
 
150829
- //# debugId=B4D4FA14AA481C6C64756E2164756E21
151134
+ //# debugId=3618ADC7F184349964756E2164756E21