From 3d4f4dfd3cf9ebfdd177f8a0e45ed7c5d808a764 Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 17 Nov 2025 16:17:36 -0800 Subject: [PATCH] feat: Make --new safe by default, add --fresh-blocks for isolation (#91) Co-authored-by: Letta --- README.md | 26 ++++++++++++++++++++++++++ src/index.ts | 33 ++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 42e3b8f..17dc4d8 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,32 @@ letta --agent --unlink # Remove Letta Code tools When you attach tools with `/link` or `--link`, they are added to the agent with approval rules enabled (human-in-the-loop). This means the agent can use these tools, but you'll be prompted to approve each tool call. Use permission modes to control approval behavior (see Permissions section below). +#### Available Tools + +Letta Code provides the following tools for filesystem and shell operations: + +**File Operations:** +- **Read** - Read files from the filesystem, supports offset/limit for large files +- **Write** - Write or overwrite files, creates directories automatically +- **Edit** - Perform exact string replacements in files (single edit) +- **MultiEdit** - Perform multiple find-and-replace operations in a single file efficiently +- **LS** - List files and directories, supports ignore patterns + +**Search & Discovery:** +- **Glob** - Fast file pattern matching with glob patterns (`**/*.js`, `src/**/*.ts`) +- **Grep** - Powerful search using ripgrep, supports regex and various output modes + +**Shell Operations:** +- **Bash** - Execute shell commands in a persistent session with timeout support +- **BashOutput** - Retrieve output from background bash shells +- **KillBash** - Terminate running background bash shells + +**Task Management:** +- **TodoWrite** - Create and manage structured task lists for tracking progress +- **ExitPlanMode** - Signal completion of planning phase and readiness to implement + +All tools support approval rules and permission modes for safe execution. See the Permissions section for details on controlling tool access. + ### Headless Mode ```bash letta -p "Run bun lint and correct errors" # Auto-resumes project agent diff --git a/src/index.ts b/src/index.ts index c3717a9..91a0cbf 100755 --- a/src/index.ts +++ b/src/index.ts @@ -15,7 +15,8 @@ Letta Code is a general purpose CLI for interacting with Letta agents USAGE # interactive TUI letta Auto-resume project agent (from .letta/settings.local.json) - letta --new Force create a new agent + letta --new Create a new agent (reuses global persona/human blocks) + letta --fresh-blocks Create a new agent with all new memory blocks letta --continue Resume global last agent (deprecated, use project-based) letta --agent Open a specific agent by ID @@ -25,7 +26,8 @@ USAGE OPTIONS -h, --help Show this help and exit -v, --version Print version and exit - --new Force create new agent (skip auto-resume) + --new Create new agent (reuses global blocks like persona/human) + --fresh-blocks Force create all new memory blocks (isolate from other agents) -c, --continue Resume previous session (uses global lastAgent, deprecated) -a, --agent Use a specific agent ID -m, --model Model ID or handle (e.g., "opus" or "anthropic/claude-opus-4-1-20250805") @@ -37,15 +39,23 @@ OPTIONS BEHAVIOR By default, letta auto-resumes the last agent used in the current directory - (stored in .letta/settings.local.json). Use --new to force a new agent. + (stored in .letta/settings.local.json). + + Memory blocks (persona, human, project, skills) are shared between agents: + - Global blocks (persona, human) are shared across all agents + - Local blocks (project, skills) are shared within the current directory + + Use --new to create a new agent that reuses your global persona/human blocks. + Use --fresh-blocks to create a completely isolated agent with new blocks. If no credentials are configured, you'll be prompted to authenticate via Letta Cloud OAuth on first run. EXAMPLES # when installed as an executable - letta # Auto-resume project agent or create new - letta --new # Force new agent + letta # Auto-resume project agent or create new + letta --new # New agent, keeps your persona/human blocks + letta --fresh-blocks # New agent, all blocks fresh (full isolation) letta --agent agent_123 # inside the interactive session @@ -83,6 +93,7 @@ async function main() { version: { type: "boolean", short: "v" }, continue: { type: "boolean", short: "c" }, new: { type: "boolean" }, + "fresh-blocks": { type: "boolean" }, agent: { type: "string", short: "a" }, model: { type: "string", short: "m" }, prompt: { type: "boolean", short: "p" }, @@ -136,6 +147,7 @@ async function main() { const shouldContinue = (values.continue as boolean | undefined) ?? false; const forceNew = (values.new as boolean | undefined) ?? false; + const freshBlocks = (values["fresh-blocks"] as boolean | undefined) ?? false; const specifiedAgentId = (values.agent as string | undefined) ?? null; const specifiedModel = (values.model as string | undefined) ?? undefined; const skillsDirectory = (values.skills as string | undefined) ?? undefined; @@ -277,12 +289,14 @@ async function main() { function LoadingApp({ continueSession, forceNew, + freshBlocks, agentIdArg, model, skillsDirectory, }: { continueSession: boolean; forceNew: boolean; + freshBlocks: boolean; agentIdArg: string | null; model?: string; skillsDirectory?: string; @@ -357,14 +371,14 @@ async function main() { // Priority 2: Check if --new flag was passed (skip all resume logic) if (!agent && forceNew) { - // Create new agent with new memory blocks + // Create new agent (reuses global blocks unless --fresh-blocks passed) const updateArgs = getModelUpdateArgs(model); agent = await createAgent( undefined, model, undefined, updateArgs, - forceNew, + freshBlocks, // Only create new blocks if --fresh-blocks passed skillsDirectory, settings.parallelToolCalls, sleeptimeFlag ?? settings.enableSleeptime, @@ -410,7 +424,7 @@ async function main() { model, undefined, updateArgs, - false, + false, // Don't force new blocks when auto-creating (reuse shared blocks) skillsDirectory, settings.parallelToolCalls, sleeptimeFlag ?? settings.enableSleeptime, @@ -451,7 +465,7 @@ async function main() { } init(); - }, [continueSession, forceNew, agentIdArg, model]); + }, [continueSession, forceNew, freshBlocks, agentIdArg, model]); if (!agentId) { return React.createElement(App, { @@ -481,6 +495,7 @@ async function main() { React.createElement(LoadingApp, { continueSession: shouldContinue, forceNew: forceNew, + freshBlocks: freshBlocks, agentIdArg: specifiedAgentId, model: specifiedModel, skillsDirectory: skillsDirectory,