A Letta Code mod that turns the local Plannotator CLI into four agent-callable review tools.
The mod keeps the boundary simple: Letta starts Plannotator only after ordinary tool approval, Plannotator opens its local browser UI, and the submitted decision or feedback returns to the active Letta conversation.
| Tool | Purpose |
|---|---|
plannotator_annotate |
Annotate a file, folder, HTML document, plain-text document, or HTTP(S) URL. Supports Plannotator approval gates. |
plannotator_review |
Review local VCS changes or a GitHub pull request / GitLab merge request URL. Local Git reviews can select a compare base and opening diff mode. |
plannotator_annotate_last |
Annotate the latest rendered assistant response from the active Letta conversation. |
plannotator_setup_goal |
Run the interview or facts stage for an existing Plannotator goal-setup JSON bundle. |
The third tool is Letta-specific. It reads the current conversation through the mod API and sends only rendered assistant text to plannotator annotate-last --stdin; it does not ask Plannotator to inspect Claude Code or Codex session logs.
- Letta Code with mod tools. This version is maintained with Letta Code 0.32.13.
- Plannotator 0.27.15 or a later version compatible with its documented command and JSON contracts.
- Plannotator installed on every computer where the tools will run.
Verify Plannotator first:
plannotator --version
plannotator --helpOn Windows PowerShell:
plannotator --version
plannotator --helpAgent-scoped mods live in the agent's git-backed memory and follow that agent between computers. This is the recommended installation for Johnny5.
$MEMORY_DIR/mods/plannotator.ts is the agent's installed local copy of this
mod. The repository remains the development source; installation copies its
single production file into MemFS. The copy must be committed inside MemFS
before it can sync to another computer.
From this repository:
mkdir -p "$MEMORY_DIR/mods"
cp src/plannotator.ts "$MEMORY_DIR/mods/plannotator.ts"
git -C "$MEMORY_DIR" add mods/plannotator.ts
git -C "$MEMORY_DIR" commit -m 'feat: add Plannotator mod'Confirm Letta sees the agent mod:
letta mods list --agent "$AGENT_ID"From this repository:
New-Item -ItemType Directory -Force "$env:MEMORY_DIR\mods" | Out-Null
Copy-Item ".\src\plannotator.ts" "$env:MEMORY_DIR\mods\plannotator.ts" -Force
git -C $env:MEMORY_DIR add mods/plannotator.ts
git -C $env:MEMORY_DIR commit -m "feat: add Plannotator mod"Confirm Letta sees the agent mod:
letta mods list --agent $env:AGENT_IDIf you ask a Letta agent to perform the installation, it should use the correct agent authorship when committing the MemFS change.
Use this when the mod should be available to every local Letta agent but should not travel with one agent.
mkdir -p ~/.letta/mods
cp src/plannotator.ts ~/.letta/mods/plannotator.tsNew-Item -ItemType Directory -Force "$HOME\.letta\mods" | Out-Null
Copy-Item ".\src\plannotator.ts" "$HOME\.letta\mods\plannotator.ts" -ForceComputer-scoped files do not need a MemFS git commit, but they must be installed separately on every computer.
After installing or updating the mod, run this inside Letta Code:
/reload
The four tools become available on the next model turn. If a mod prevents normal startup, launch Letta without mods:
letta --no-modsor:
LETTA_DISABLE_MODS=1 lettaBy default the mod runs plannotator through the Letta process's PATH with shell: false.
For Desktop sessions, services, or machines whose GUI environment does not inherit your terminal PATH, set PLANNOTATOR_BIN to the absolute executable path before starting Letta. An absolute override also avoids selecting an unintended executable from an untrusted PATH directory.
macOS example:
PLANNOTATOR_BIN="$HOME/.local/bin/plannotator" lettaWindows PowerShell example:
$env:PLANNOTATOR_BIN = "C:\absolute\path\to\plannotator.exe"
lettaPLANNOTATOR_BIN is computer-specific and should not be stored in the agent-scoped mod file. Relative overrides are rejected.
Natural-language requests are enough:
Open README.md in Plannotator and act on my annotations.
Review the current diff with Plannotator.
Review this stacked branch in Plannotator against feature/part-1 using the merge-base view.
Open https://github.com/example/repo/pull/42 in Plannotator.
Put your last response in Plannotator so I can mark it up.
Gate SPEC.md in Plannotator before implementing it.
Open goals/catalog-search/interview.json in Plannotator's goal-setup interview.
All four tools require ordinary Letta tool approval and are intentionally marked non-parallel-safe. They should be called only when the user explicitly requests Plannotator.
The annotation, review, and latest-response tools can optionally publish the browser session over the operator's Tailscale tailnet. Code review can explicitly select Git or GitButler; the latter requires a compatible local but executable. Local Git review also supports Plannotator's session-only base and diff_type controls; either one forces Git instead of VCS auto-detection. Review outcomes are returned as structured approved, annotated, or dismissed decisions rather than classified from message text.
This mod and the upstream Plannotator skills have separate jobs:
- Skills define workflows such as visual explainers, compound analysis, and goal-package construction.
- This mod provides typed Letta tools for the browser/process boundary.
The mod does not copy, rewrite, or intercept installed skills. Plannotator's upstream skills currently launch the CLI through Bash, so a Letta agent that should use this mod needs agent-scoped copies adapted to call the typed tools.
Plannotator provides four core skills: the general plannotator CLI reference
plus plannotator-annotate, plannotator-review, and plannotator-last.
Use the Agent Skills CLI for the current core set and the three extras; an
ordinary update of previously installed skills does not necessarily add a new
skill:
npx skills add backnotprop/plannotator/apps/skills/core --global
npx skills add backnotprop/plannotator/apps/skills/extra --globalIn the interactive host selector, install the extras into the shared Agent
Skills location (~/.agents/skills; selecting Codex provides that copy). See
Install and Manage Plannotator Skills
for specific-skill and update commands.
After the core and extra skills exist under ~/.agents/skills, give the Letta
agent that owns the mod this prompt:
Install all seven Plannotator skills from ~/.agents/skills/plannotator* into your
agent-scoped $MEMORY_DIR/skills directory, preserving every bundled resource.
Adapt only the MemFS copies so they use the installed Plannotator mod tools
instead of Bash or direct `plannotator` CLI commands:
- plannotator-annotate -> plannotator_annotate
- plannotator-review -> plannotator_review
- plannotator-last -> plannotator_annotate_last
- plannotator-setup-goal -> plannotator_setup_goal and plannotator_annotate
- plannotator-visual-explainer -> plannotator_annotate
- plannotator-compound -> plannotator_annotate for report delivery
For the general plannotator reference skill, prefer these typed tools for their
supported review, annotation, latest-message, and goal-setup surfaces. Retain
direct CLI guidance only for unsupported surfaces such as archive, sessions,
and Guided Review export/share, or for a CLI-only option the user explicitly
requests.
Do not silently fall back to Bash if a mod tool is unavailable; tell me to
reload or repair the mod. Update any bundled skill tests that assert the old CLI
instructions, validate all seven skills, commit the MemFS changes with your agent
authorship, and tell me to run /reload.
This intentionally creates small agent-local adaptations. Updating the upstream skills later may overwrite or conflict with them, so reapply and revalidate the tool mapping after an upstream skill update.
Plannotator runs on the computer executing the Letta tool, and its browser opens there.
- Local Letta CLI or Desktop session: browser opens on that local computer.
- Remote/BYOM session: browser opens on the selected execution computer.
- Cloud sandbox or unattended channel listener: the browser may open somewhere you cannot use it. Do not invoke these tools there unless remote Plannotator access has been deliberately configured.
An agent-scoped mod follows Johnny5 between the Mac and Windows machines, but the Plannotator executable and PLANNOTATOR_BIN/PATH configuration remain local to each machine.
- User values are passed as process arguments with
shell: false; they are never interpolated into a shell command. - Tailscale publishing occurs only when the approved tool call explicitly sets
tailscale: true. - Annotation targets beginning with
-are rejected to prevent CLI option injection. Use./-filenameor an absolute path for a legitimate filename beginning with a hyphen. - Each captured stdout/stderr stream is limited to 1 MiB.
- Annotate-last input is limited to 1 MiB of UTF-8.
- Completed-process stderr included in an error is bounded.
- Cancellation closes stdin, requests process termination, and escalates after a short grace period.
- The mod does not install automatic stop hooks, intercept plans, edit reviewed files, or execute work merely because a plan was approved.
Path and URL access is intentionally broad after tool approval because Plannotator itself supports absolute files, folders, and URLs. Review the tool arguments before approving a call.
Normal direct-child execution is designed for macOS, Linux, and Windows. The automated process-lifecycle suite currently runs on macOS; native Windows cancellation and descendant-process behavior should be smoke-tested on the Windows machine before relying on cancellation as a process-tree cleanup boundary. A browser tab opened before cancellation may remain open even after the Plannotator CLI exits.
The Letta process cannot find the CLI. Verify plannotator --version in the same environment that launches Letta, or set an absolute PLANNOTATOR_BIN.
The installed Plannotator returned an incompatible decision record. Check plannotator --version and update the CLI. The verified contract is Plannotator 0.27.15.
Closing the browser without submitting feedback is a valid dismissed decision. No feedback is invented.
The tool ran on a different execution computer. Reconnect Letta to the computer whose browser you want to use, then invoke the tool again.
Set PLANNOTATOR_BIN to the absolute executable path in the environment that launches the Desktop listener or Letta process.
Inspect:
~/.letta/mods/diagnostics/latest.json
Then start with letta --no-mods if a clean baseline is needed.
Install development dependencies:
bun installRun the complete verification gate:
bun run checkThat command runs:
- The Bun test suite.
- TypeScript typechecking.
- A Node-targeted single-file build.
- A Node-compatible ESM activation and cleanup validation.
Useful individual commands:
bun run test
bun run typecheck
bun run build
bun run validate:modRepository structure:
SPEC.md Product and behavior contract
PLAN.md Ordered TDD implementation plan
src/plannotator.ts Single-file production mod
tests/ Public-interface and real-process tests
scripts/validate-mod.mjs Node-compatible built-mod validation
The generated dist/ directory is ignored. Install src/plannotator.ts, not a development artifact.