Customizing Commands
Use this as the command-specific entrypoint for local mod slash commands. For broader mod work, recipes live in ../creating-mods/references/commands.md, ../creating-mods/references/architecture.md, ../creating-mods/references/ui.md, and ../creating-mods/references/plan-mode.md.
Mod files live in:
~/.letta/mods/
Use a focused file name, e.g. ~/.letta/mods/review.ts or ~/.letta/mods/commands.ts.
First decide whether a command is right
| User wants |
Build |
/foo sends a prompt or shows local output |
Mod command |
/foo starts a reusable agent workflow |
Skill + thin mod command |
| Agent/model should autonomously call the capability |
Mod tool, not a command |
| Command shows transient progress/results |
Mod command + panel |
| Command needs model output while the main agent is busy |
runWhenBusy: true command + forked ctx.conversation |
If the command is a reusable workflow like /goal, put the workflow instructions in a skill and keep the mod command as a small launcher/prompt.
Workflow
- Inspect
~/.letta/mods/ for related command files.
- Preserve unrelated mod code; create a focused new file if merging is messy.
- Register with
letta.commands.register() and guard with letta.capabilities.commands.
- Return the unregister function, or a disposer that calls it plus any timer/panel cleanup.
- Tell the user the exact file path changed and to run
/reload.
Default prompt command
export default function activate(letta) {
if (!letta.capabilities.commands) return;
return letta.commands.register({
id: "review",
description: "Review current git changes",
args: "[focus]",
run(ctx) {
const focus = ctx.args.trim();
return {
type: "prompt",
content: focus
? `Review current git changes. Focus on ${focus}.`
: "Review current git changes. Focus on correctness issues.",
systemReminder: true,
};
},
});
}
Command result types
type ModCommandResult =
| { type: "prompt"; content: string; systemReminder?: boolean }
| { type: "output"; output: string; success?: boolean }
| { type: "handled" };
prompt: sends content to the agent. Use for normal slash shortcuts.
output: prints local text and does not contact the agent.
handled: command handled its own side effects/UI; common for panel commands.
Rules
- Command IDs omit the slash:
id: "review", not "/review".
- Use lowercase slugs with letters, numbers, and hyphens.
- Do not register built-in command IDs.
runWhenBusy: true commands must not return prompt while the main agent is busy; use scoped conversation helpers/panels and return handled.
showInTranscript: false commands should usually return handled, not prompt.
- Do not import Letta Code app internals.
- Do not do surprising side effects on startup; mods activate on app start and
/reload.
More recipes
- Simple output command, panel command, busy-safe conversation command:
../creating-mods/references/commands.md
- Complex command architecture, state, cleanup:
../creating-mods/references/architecture.md
- Panel/status UI patterns:
../creating-mods/references/ui.md
- Worked plan-mode command/tool composition:
../creating-mods/references/plan-mode.md
1---2name: customizing-commands3description: Creates, edits, and enables Letta Code mod-provided slash commands. Use when the user asks to add a custom /command, slash command, command shortcut, scoped conversation-backed command, or command-driven panel behavior.4---56# Customizing Commands78Use this as the command-specific entrypoint for local mod slash commands. For broader mod work, recipes live in `../creating-mods/references/commands.md`, `../creating-mods/references/architecture.md`, `../creating-mods/references/ui.md`, and `../creating-mods/references/plan-mode.md`.910Mod files live in:1112```text13~/.letta/mods/14```1516Use a focused file name, e.g. `~/.letta/mods/review.ts` or `~/.letta/mods/commands.ts`.1718## First decide whether a command is right1920| User wants | Build |21| --- | --- |22| `/foo` sends a prompt or shows local output | Mod command |23| `/foo` starts a reusable agent workflow | Skill + thin mod command |24| Agent/model should autonomously call the capability | Mod tool, not a command |25| Command shows transient progress/results | Mod command + panel |26| Command needs model output while the main agent is busy | `runWhenBusy: true` command + forked `ctx.conversation` |2728If the command is a reusable workflow like `/goal`, put the workflow instructions in a skill and keep the mod command as a small launcher/prompt.2930## Workflow31321. Inspect `~/.letta/mods/` for related command files.332. Preserve unrelated mod code; create a focused new file if merging is messy.343. Register with `letta.commands.register()` and guard with `letta.capabilities.commands`.354. Return the unregister function, or a disposer that calls it plus any timer/panel cleanup.365. Tell the user the exact file path changed and to run `/reload`.3738## Default prompt command3940```ts41export default function activate(letta) {42 if (!letta.capabilities.commands) return;4344 return letta.commands.register({45 id: "review",46 description: "Review current git changes",47 args: "[focus]",48 run(ctx) {49 const focus = ctx.args.trim();50 return {51 type: "prompt",52 content: focus53 ? `Review current git changes. Focus on ${focus}.`54 : "Review current git changes. Focus on correctness issues.",55 systemReminder: true,56 };57 },58 });59}60```6162## Command result types6364```ts65type ModCommandResult =66 | { type: "prompt"; content: string; systemReminder?: boolean }67 | { type: "output"; output: string; success?: boolean }68 | { type: "handled" };69```7071- `prompt`: sends content to the agent. Use for normal slash shortcuts.72- `output`: prints local text and does not contact the agent.73- `handled`: command handled its own side effects/UI; common for panel commands.7475## Rules7677- Command IDs omit the slash: `id: "review"`, not `"/review"`.78- Use lowercase slugs with letters, numbers, and hyphens.79- Do not register built-in command IDs.80- `runWhenBusy: true` commands must not return `prompt` while the main agent is busy; use scoped conversation helpers/panels and return `handled`.81- `showInTranscript: false` commands should usually return `handled`, not `prompt`.82- Do not import Letta Code app internals.83- Do not do surprising side effects on startup; mods activate on app start and `/reload`.8485## More recipes8687- Simple output command, panel command, busy-safe conversation command: `../creating-mods/references/commands.md`88- Complex command architecture, state, cleanup: `../creating-mods/references/architecture.md`89- Panel/status UI patterns: `../creating-mods/references/ui.md`90- Worked plan-mode command/tool composition: `../creating-mods/references/plan-mode.md`