npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jecruz/merc-coding-agent

v0.1.4

Published

Coding agent CLI with read, bash, edit, write tools and session management

Readme

New issues and PRs from new contributors are auto-closed by default. Maintainers review auto-closed issues daily. See CONTRIBUTING.md.


Pi is a minimal terminal coding harness. Adapt pi to your workflows, not the other way around, without having to fork and modify pi internals. Extend it with TypeScript Extensions, Skills, Prompt Templates, and Themes. Put your extensions, skills, prompt templates, and themes in Pi Packages and share them with others via npm or git.

Pi ships with powerful defaults but skips features like sub agents and plan mode. Instead, you can ask pi to build what you want or install a third party pi package that matches your workflow.

Pi runs in four modes: interactive, print or JSON, RPC for process integration, and an SDK for embedding in your own apps. See openclaw/openclaw for a real-world SDK integration.

Share your OSS coding agent sessions

If you use pi for open source work, please share your coding agent sessions.

Public OSS session data helps improve models, prompts, tools, and evaluations using real development workflows.

For the full explanation, see this post on X.

To publish sessions, use badlogic/pi-share-hf. Read its README.md for setup instructions. All you need is a Hugging Face account, the Hugging Face CLI, and pi-share-hf.

You can also watch this video, where I show how I publish my pi-mono sessions.

I regularly publish my own pi-mono work sessions here:

Table of Contents


Quick Start

npm install -g @jecruz/merc-coding-agent

Authenticate with an API key:

export ANTHROPIC_API_KEY=sk-ant-...
pi

Or use your existing subscription:

pi
/login anthropic  # Or just /login to browse providers first

Then just talk to pi. By default, pi gives the model four tools: read, write, edit, and bash. The model uses these to fulfill your requests. Add capabilities via skills, prompt templates, extensions, or pi packages.

Platform notes: Windows | Termux (Android) | tmux | Terminal setup | Shell aliases


Providers & Models

For each built-in provider, pi maintains a list of tool-capable models, updated with every release. Authenticate via subscription (/login) or API key, then select any model from that provider via /model (or Ctrl+L). You can also pass a provider directly, for example /login anthropic.

Subscriptions:

  • Anthropic Claude Pro/Max
  • OpenAI ChatGPT Plus/Pro (Codex)
  • GitHub Copilot

API keys:

  • Anthropic
  • OpenAI
  • Azure OpenAI
  • DeepSeek
  • Google Gemini
  • Google Vertex
  • Amazon Bedrock
  • Mistral
  • Groq
  • Cerebras
  • Cloudflare AI Gateway
  • Cloudflare Workers AI
  • xAI
  • OpenRouter
  • Vercel AI Gateway
  • ZAI Coding Plan (Global)
  • OpenCode Zen
  • OpenCode Go
  • Hugging Face
  • Fireworks
  • Together AI
  • Ant Ling
  • Kimi For Coding
  • MiniMax
  • Xiaomi MiMo
  • Xiaomi MiMo Token Plan (China)
  • Xiaomi MiMo Token Plan (Amsterdam)
  • Xiaomi MiMo Token Plan (Singapore)

See docs/providers.md for detailed setup instructions.

Custom providers & models: Add providers via ~/.pi/agent/models.json if they speak a supported API (OpenAI, Anthropic, Google). For custom APIs or OAuth, use extensions. See docs/models.md and docs/custom-provider.md.


Interactive Mode

The interface from top to bottom:

  • Startup header - Shows shortcuts (/hotkeys for all), loaded AGENTS.md files, prompt templates, skills, and extensions
  • Messages - Your messages, assistant responses, tool calls and results, notifications, errors, and extension UI
  • Editor - Where you type; border color indicates thinking level
  • Footer - Working directory, session name, total token/cache usage, cost, context usage, and current model with a colored [LOCAL] or [REMOTE] scope marker

The editor can be temporarily replaced by other UI, like built-in /settings or custom UI from extensions (e.g., a Q&A tool that lets the user answer model questions in a structured format). Extensions can also replace the editor, add widgets above/below it, a status line, custom footer, or overlays.

Editor

| Feature | How | |---------|-----| | File reference | Type @ to fuzzy-search project files | | Path completion | Tab to complete paths | | Multi-line | Shift+Enter (or Ctrl+Enter on Windows Terminal) | | Clipboard | Ctrl+V to paste an image or text (Alt+V on Windows), or drag images onto terminal | | Bash commands | !command runs and sends output to LLM, !!command runs without sending |

Standard editing keybindings for delete word, undo, etc. See docs/keybindings.md.

Commands

Type / in the editor to trigger commands. Extensions can register custom commands, skills are available as /skill:name, and prompt templates expand via /templatename.

| Command | Description | |---------|-------------| | /login [provider], /logout | OAuth authentication and provider auth setup | | /providers | Manage providers and models; use /providers status for secret-safe readiness and model counts | | /model-stats | Show measured local model fitness statistics | | /model [provider/model] | Switch models | | /scoped-models | Enable/disable models for Ctrl+P cycling | | /settings | Thinking level, theme, message delivery, transport | | /workspace | Show/hide the bounded workspace context strip | | /memory remember <text> | Confirm and store durable project memory when content indexing is enabled | | /memory list [session|project] | List bounded project-scoped semantic memories | | /memory explain <id> | Show memory provenance and details | | /memory edit <id> <text> | Confirm and update one project-scoped memory while preserving provenance | | /memory delete <id> / /memory forget <text> | Confirm and delete matching memories | | /memory clear project | Confirm and clear project-scoped memory matches | | /memory on / /memory off | Enable or disable retrieval in the nearest project manifest | | /resume | Pick from previous sessions | | /new | Start a new session | | /rename <name> / /rename --auto | Set a display name or accept a project/task-derived default | | /related list | List up to five ranked related sessions with confidence and reasons | | /related open <id> / /related dismiss <id> | Resume or dismiss a related-session suggestion | | /related groups / /related group / /related ungroup | Manage reversible session groups without modifying transcripts | | /session | Show session info (file, ID, messages, tokens, cost) | | /tree | Jump to any point in the session and continue from there | | /fork | Create a new session from a previous user message | | /clone | Duplicate the current active branch into a new session | | /compact [prompt] | Manually compact context, optional custom instructions | | /copy | Copy last assistant message to clipboard | | /retry | Retry the last user prompt on a new session-tree branch | | /continue | Continue a response that stopped at the output limit | | /memory <action> | Remember, list, explain, edit, delete, forget, clear, enable, or disable project-scoped memories; every mutation asks for confirmation | | /flow start [spec] | Start the workflow; omit spec to run the guided interview and generate SPEC.md | | /flow status, /flow show | Inspect the active workflow and its milestones | | /flow next, /flow cancel | Queue the next workflow stage or cancel the workflow | | /flow milestone add <title> | Add a milestone to the active workflow | | /flow milestone complete | Complete the current milestone and advance to the next one | | /tasks next | List actionable Merc Flow milestones in deterministic priority order | | /tasks begin [milestone-id] | Begin the only actionable milestone, or an explicitly selected milestone | | /key-probe task | Capture and classify the next raw terminal input once without changing keybindings | | /export [file] | Export session to HTML file | | /share | Upload as private GitHub gist with shareable HTML link | | /reload | Reload keybindings, extensions, skills, prompts, themes, and context files | | /hotkeys | Show all keyboard shortcuts | | /changelog | Display version history | | /quit | Quit pi |

The interactive resume picker uses a versioned metadata cache to show at most five related sessions with confidence, match reasons, branch, task, and execution state. Identity and execution state are tracked separately, legacy cache records are migrated, stale running state recovers to idle, and ranked matches explain project, repository, branch, task, or topic overlap. Strong matches score at least 0.85; possible matches score 0.65 to 0.849. Groups contain session references only and never merge, rewrite, or delete transcripts. /related exposes list, open, dismiss, and reversible group controls. New unnamed sessions show a one-time /rename reminder and support a generated project/task name through /rename --auto. Switching away from an active run requires explicit abort confirmation; idle switches checkpoint metadata without changing the session ID or transcript. A live process owner prevents another Merc process from opening the same running session, and inter-process metadata locking preserves concurrent updates. AgentSession releases ownership before settlement in interactive, print, RPC, and SDK modes using an atomic owner-token comparison.

Press Ctrl+K to open Merc's searchable command palette. It exposes model, provider, thinking, fitness, recovery, transcript, review, settings, and registered extension commands without clearing the editor input.

Project milestones

The workflow reads optional project milestones from .merc/flow-project.json:

{
  "milestones": [
    { "id": "api", "title": "Build the API", "criteria": ["API tests pass"] },
    { "id": "ui", "title": "Build the UI", "criteria": ["UI review passes"] }
  ]
}

If the file is missing or invalid, Merc uses one default implementation milestone. Workflow state is persisted in the session so older sessions remain resumable. When /flow start is used without a spec, Merc records three guided answers and writes the resulting specification to <project>/SPEC.md before implementation.

Keyboard Shortcuts

See /hotkeys for the full list. Customize via ~/.merc/agent/keybindings.json; configuring an action replaces that action's defaults rather than adding to them. See the canonical keybinding guide, including the complete F1-F12 and Shift+F-key map.

Commonly used:

| Key | Action | |-----|--------| | Ctrl+C | Clear editor | | Ctrl+C twice | Quit | | Ctrl+D / Fn+F12 | Quit when the editor is empty | | Escape | Cancel/abort | | Escape twice | Open /tree | | Ctrl+L | Open model selector | | Ctrl+K | Open searchable command palette | | F6 | Show/hide workspace context | | Ctrl+P / Shift+Ctrl+P | Cycle scoped models forward/backward | | Shift+Tab | Cycle thinking level | | Ctrl+O | Collapse/expand tool output | | Ctrl+T | Collapse/expand thinking blocks | | Ctrl+X | Copy the last assistant message |

The function-key layer groups Help, Resume, Models, Thinking, Tool output, Workspace, Session tree, Tangents, Reload, Feature Center, Command palette, and guarded Quit across F1-F12. Its sparse Shift layer provides New session, Next model, Show/hide thinking, Fork session, and Providers & Models. On macOS media-key keyboards, hold Fn for both layers, for example Fn+F3 or Fn+Shift+F3. Shift+F1/F5/F6/F8/F9/F11/F12 are intentionally unbound. See Function-Key Productivity Layer for the exact map and draft guards.

Message Queue

Submit messages while the agent is working:

  • Enter queues a steering message, delivered after the current assistant turn finishes executing its tool calls
  • Alt+Enter queues a follow-up message, delivered only after the agent finishes all work
  • Escape aborts and restores queued messages to editor
  • Alt+Up retrieves queued messages back to editor

On Windows Terminal, Alt+Enter is fullscreen by default. Remap it in docs/terminal-setup.md so pi can receive the follow-up shortcut.

Configure delivery in settings: steeringMode and followUpMode can be "one-at-a-time" (default, waits for response) or "all" (delivers all queued at once). transport selects provider transport preference ("sse", "websocket", or "auto") for providers that support multiple transports.


Sessions

Sessions are stored as JSONL files with a tree structure. Each entry has an id and parentId, enabling in-place branching without creating new files. See docs/session-format.md for file format.

Management

Sessions auto-save to ~/.pi/agent/sessions/ organized by working directory.

pi -c                  # Continue most recent session
pi -r                  # Browse and select from past sessions
pi --no-session        # Ephemeral mode (don't save)
pi --session <path|id> # Use specific session file or ID
pi --session-id <id>   # Use an exact session id, creating it if missing
pi --fork <path|id>    # Fork specific session file or ID into a new session

Use /session in interactive mode to see the current session ID before reusing it with --session <id> or --fork <id>.

Project Workflow Sessions

Merc can keep separate sessions for planning, development, review, and delivery in one project-owned registry. Initialize and inspect it with:

merc project sessions init
merc project sessions list
merc project sessions use development
merc --project-session review

The registry is .agent/sessions.yaml. It stores role-to-session IDs and bounded workflow metadata; transcripts remain ordinary JSONL files in the existing Merc session directory. Initialization creates only the registry, and role transcripts are created on first use. In interactive mode, use /sessions or /sessions switch <role>, or choose Switch project session from Ctrl-K. Switching uses the normal session ownership and abort guards and updates the registry only after the target runtime is open.

On the next startup, Merc resumes the registry's lastActiveRole by reading one metadata record and one selected transcript. It does not scan all role transcripts, call the model, or run roles concurrently. Explicit session flags such as --session, --resume, --fork, and --continue take precedence.

Branching

/tree - Navigate the session tree in-place. Select any previous point, continue from there, and switch between branches. All history preserved in a single file.

  • Search by typing, fold/unfold and jump between branches with Ctrl+←/Ctrl+→ or Alt+←/Alt+→, page with ←/→
  • Filter modes (Ctrl+O): default → no-tools → user-only → labeled-only → all
  • Press Ctrl+X to copy the selected message
  • Press Shift+L to label entries as bookmarks and Shift+T to toggle label timestamps

/fork - Create a new session file from a previous user message on the active branch. Opens a selector, copies the active path up to that point, and places the selected prompt in the editor for modification.

/clone - Duplicate the current active branch into a new session file at the current position. The new session keeps the full active-path history and opens with an empty editor.

--fork <path|id> - Fork an existing session file or partial session UUID directly from the CLI. This copies the full source session into a new session file in the current project.

Compaction

Long sessions can exhaust context windows. Compaction summarizes older messages while keeping recent ones.

Manual: /compact or /compact <custom instructions>

SDK, RPC, and extensions can also attach typed obligations for exact text that must survive compaction. Unlike advisory custom instructions, obligations are validated after the first summary, repaired once if needed, and finally appended through a deterministic fallback before the new summary is committed. Requests are limited to 32 obligations, 8 KiB per item, and 32 KiB total UTF-8 text.

await session.compact({
  customInstructions: "Keep the summary concise.",
  obligations: [{ id: "verification", text: "npm run check", source: "workflow" }],
});

Automatic: Enabled by default. Triggers on context overflow (recovers and retries) or when approaching the limit (proactive). Configure via /settings or settings.json.

Compaction is lossy. The full history remains in the JSONL file; use /tree to revisit. Customize compaction behavior via extensions. See docs/compaction.md for internals.

Use merc bench compaction --model <exact-id> --trials 15 --mode paired to compare the legacy instruction-only path with typed obligations. Merc runs an exact-model/tool-protocol canary first and writes content-free stage evidence to the model-fitness ledger.


Settings

Use /settings to modify common options, including editor padding and transcript output padding, or edit JSON files directly:

| Location | Scope | |----------|-------| | ~/.pi/agent/settings.json | Global (all projects) | | .pi/settings.json | Project (overrides global) |

See docs/settings.md for all options.

Bash executable policy

Merc denies direct use of rm, curl, wget, bash, sh, zsh, python, and node unless their case-sensitive basename appears in the global bash.allowedExecutables list in ~/.merc/agent/settings.json. Project settings cannot override this boundary. Run /reload after editing the list.

Allowlisting does not permit shell composition: chaining, pipelines, grouping, redirection, substitutions, and shell -c execution remain blocked. The policy is not an OS sandbox; an allowed interpreter retains its normal capabilities. See Bash executable allowlist for the exact JSON shape and limitations.

Telemetry and update checks

  • Update check: Merc reads the published @jecruz/merc-coding-agent npm metadata endpoint. Override it with MERC_UPDATE_URL for a private or self-hosted release service. Disable it with MERC_SKIP_VERSION_CHECK=1.
  • Merc does not send an install/update telemetry ping during startup.
  • enableInstallTelemetry and MERC_TELEMETRY control optional provider attribution headers, not update checks or release reporting.

Use --offline or MERC_OFFLINE=1 to disable startup network operations, including update checks and package update checks.


Context Files

Merc loads AGENTS.md (or CLAUDE.md) at startup from:

  • ~/.pi/agent/AGENTS.md (global)
  • Parent directories (walking up from cwd)
  • Current directory

Use for project instructions, conventions, common commands. All matching files are concatenated.

Disable context file loading with --no-context-files (or -nc).

Project Configuration

Projects can use a structured .agent/manifest.yaml and a compact .agent/constitution.md to reduce context duplication and make workflow policy inspectable. Initialize them from detected project files with:

merc project init --auto
merc policy doctor
merc policy explain [path]
merc policy apply --mode confirm
merc context migrate --auto
merc context migrate --auto --apply --confirm --strict
merc context migrate --rollback --confirm

project init --auto does not overwrite existing files unless --force is provided. It starts policy in observe mode, records detected command evidence, and preserves an existing AGENTS.md as explicitly referenced context. policy doctor reports effective manifest sources, context budget usage, and omitted files. The constitution is the durable project principle layer; the manifest contains machine-readable policy and commands. Use merc context migrate --auto to preview Markdown classifications and projected token savings. Applying requires both --apply and --confirm; the generated context index and atomic backup support inspection and rollback without rewriting the source Markdown.

Orchestrated Workgroups

Merc keeps ordinary prompts single-model. Opt into the bounded workgroup design explicitly:

merc orchestrate plan "Implement the requested feature"
merc orchestrate start "Implement the requested feature"
merc orchestrate inspect
merc orchestrate inspect <run-id>
merc orchestrate pause <run-id>
merc orchestrate resume <run-id>
merc orchestrate cancel <run-id>
merc orchestrate retry <run-id> <task-id>
merc orchestrate recover
merc orchestrate review <run-id>
merc orchestrate apply <run-id> --confirm
merc orchestrate rollback <run-id> --confirm

plan is read-only: it shows the dependency graph, worker roles, configured model candidates, budgets, and expected side effects without starting workers or writing a run. inspect reads persisted run summaries under ~/.merc/agent/orchestration/runs/ when a future execution creates them. start creates a durable running record and marks only root tasks ready; it does not launch workers implicitly. pause, resume, and cancel change only the durable lifecycle state and preserve evidence. recover converts orphaned running records to paused records after a process restart. The first release validates task IDs, dependencies, cycles, budgets, lifecycle states, and artifact roots before persistence; records are written with mode 0600 using temporary-file replacement. No worker can merge, push, publish, or mutate the parent worktree automatically.

Worker starts reserve worker, token, cost, and latency capacity before launch. Usage is persisted as prompt-free counters, and retry returns failed tasks to ready only while maxRetries permits it. Pause and cancel abort active child processes through a bounded signal while preserving completed evidence.

Research execution is bounded and read-only. start selects at most three configured candidates through ModelRegistry.getRoutingCandidates, which reuses provider readiness and the local model-fitness ledger; the exact three-model fallback list is used only when no configured candidate is available. Workers use the selected candidates in order, fall back only when the worker reports model unavailability, require authoritative model: and provider: startup metadata, and preserve only redacted, capped evidence under the Merc orchestration state directory.

Every worker attempt also receives an isolated Merc session descriptor under ~/.merc/agent/orchestration/runs/sessions/<run-id>/<task-id>/. The mode-0600 JSONL session records the worker identity and parent-session link, and its ID and path are passed through MERC_ORCHESTRATION_WORKER_SESSION_ID and MERC_ORCHESTRATION_WORKER_SESSION_PATH; worker transcripts are not merged into the parent session. Implementation workers use a separate Merc-owned detached Git worktree and never receive the parent checkout as their current directory. Their changed files and worker evidence remain available for the review/apply phase; no implementation worker merges or pushes automatically.

Research, implementation, and tester workers receive explicit project policy metadata, protected paths, required checks, and discovered extension paths. Implementer changes are checked against protected paths before review. Tester workers run non-shell commands only and persist redacted test evidence; reviewer workers persist the review gate as a worker record. Metadata-only lifecycle telemetry is stored mode 0600 without prompts, diffs, or tool content.

The review gate reports changed-file overlap, failed task/test gates, policy violations, and incomplete worker evidence. Apply requires a clean parent checkout, a ready review, and the explicit --confirm flag. A mode-0600 rollback patch is written before changes are applied; rollback --confirm reverses that patch without deleting the run record. The interactive TUI shows at most one bounded [Workgroup] line above the editor when a running or paused run is present. It is informational and does not start, stop, or apply workers.

Project Taste Preferences

Merc resolves reviewed project preferences through the configured Noesis MCP server and falls back to .merc/taste.md when the service is unavailable. Each user turn, including queued steer and follow-up messages, receives at most five rules in a 2,000-character block with a 500 ms resolution deadline. Queued evidence is recorded only when its message reaches a provider call. Inspect and manage the local projection with:

merc taste list
merc taste explain <rule-id>
merc taste export
merc taste export <path> --confirm
merc taste import <path> --confirm
merc taste sync --dry-run

Import and path-based export require explicit confirmation. Sync is currently dry-run-only. Merc records prompt-free outcome evidence under ~/.merc/agent/preferences/evidence.jsonl; it never stores prompt, file, rule text, system-prompt, or tool content in that ledger.

Merc keeps session discovery metadata separate from transcript JSONL files. The versioned local metadata index stores only bounded project/session fields, supports atomic updates, and quarantines corrupt indexes so unavailable metadata never blocks startup. Conversation content is not indexed by this layer.

Semantic Memory is a separate, opt-in service boundary. Configure it in the project manifest only when desired:

memory:
  enabled: true
  contentIndexing: false
  endpoint: http://localhost:8096

The adapter uses project-scoped tags, limits retrieval to five memories and 2,000 characters, waits at most 500 ms, and fails open when the service is unavailable. Resume initiates retrieval for the selected session; results from a session that was switched away are discarded, and results that arrive during streaming are queued for the next turn. Content writes remain disabled unless contentIndexing is explicitly enabled and the caller confirms the mutation. Use /memory remember <text> for explicit creation; explain, edit, and delete resolve only records tagged to the current project.

System Prompt

Replace the default system prompt with .pi/SYSTEM.md (project) or ~/.pi/agent/SYSTEM.md (global). Append without replacing via APPEND_SYSTEM.md.


Customization

Prompt Templates

Reusable prompts as Markdown files. Type /name to expand.

<!-- ~/.pi/agent/prompts/review.md -->
Review this code for bugs, security issues, and performance problems.
Focus on: {{focus}}

Place in ~/.pi/agent/prompts/, .pi/prompts/, or a pi package to share with others. See docs/prompt-templates.md.

Skills

On-demand capability packages following the Agent Skills standard. Invoke via /skill:name or let the agent load them automatically.

<!-- ~/.pi/agent/skills/my-skill/SKILL.md -->
# My Skill
Use this skill when the user asks about X.

## Steps
1. Do this
2. Then that

Place in ~/.pi/agent/skills/, ~/.agents/skills/, .pi/skills/, or .agents/skills/ (from cwd up through parent directories) or a pi package to share with others. See docs/skills.md.

Extensions

TypeScript modules that extend Merc with custom tools, commands, keyboard shortcuts, event handlers, and UI components.

export default function (pi: ExtensionAPI) {
  pi.registerTool({ name: "deploy", ... });
  pi.registerCommand("stats", { ... });
  pi.on("tool_call", async (event, ctx) => { ... });
}

The default export can also be async. pi waits for async extension factories before startup continues, which is useful for one-time initialization such as fetching remote model lists before calling pi.registerProvider().

What's possible:

  • Custom tools (or replace built-in tools entirely)
  • Sub-agents and plan mode
  • Custom compaction and summarization
  • Permission gates and path protection
  • Custom editors and UI components
  • Status lines, headers, footers
  • Git checkpointing and auto-commit
  • SSH and sandbox execution
  • MCP server integration
  • Make pi look like Claude Code
  • Games while waiting (yes, Doom runs)
  • ...anything you can dream up

Place in ~/.merc/agent/extensions/, .merc/extensions/, or a Merc package to share with others. The repository also includes a source-controlled local bundle in ../../extensions/, installed by bash ../../install/sync-extensions.sh. See docs/extensions.md and examples/extensions/.

Themes

Built-in: merc-forge, dark, light. Merc defaults to merc-forge; themes hot-reload when you modify the active custom theme file.

Place custom themes in ~/.merc/agent/themes/ or .merc/themes/. Select one with /settings or --theme <path>. See docs/themes.md.

Pi Packages

Bundle and share extensions, skills, prompts, and themes via npm or git. Find packages on npmjs.com or Discord.

Security: Pi packages run with full system access. Extensions execute arbitrary code, and skills can instruct the model to perform any action including running executables. Review source code before installing third-party packages.

pi install npm:@foo/pi-tools
pi install npm:@foo/[email protected]      # pinned version
pi install git:github.com/user/repo
pi install git:github.com/user/repo@v1  # tag or commit
pi install git:[email protected]:user/repo
pi install git:[email protected]:user/repo@v1  # tag or commit
pi install https://github.com/user/repo
pi install https://github.com/user/repo@v1      # tag or commit
pi install ssh://[email protected]/user/repo
pi install ssh://[email protected]/user/repo@v1    # tag or commit
pi remove npm:@foo/pi-tools
pi uninstall npm:@foo/pi-tools          # alias for remove
pi list
pi update                               # update pi and packages (skips pinned packages)
pi update --extensions                  # update packages only
pi update --self                        # update pi only
pi update --self --force                # reinstall pi even if current
pi update npm:@foo/pi-tools             # update one package
pi config                               # enable/disable extensions, skills, prompts, themes

Packages install to ~/.pi/agent/git/ (git) or global npm. Use -l for project-local installs (.pi/git/, .pi/npm/). Git @ref values are pinned tags or commits; pinned packages are skipped by pi update, so use pi install git:host/user/repo@new-ref to move an existing package to a new ref. Git packages install dependencies with npm install --omit=dev by default, so runtime deps must be listed under dependencies; when npmCommand is configured, git packages use plain install for compatibility with wrappers. If you use a Node version manager and want package installs to reuse a stable npm context, set npmCommand in settings.json, for example ["mise", "exec", "node@20", "--", "npm"].

Create a package by adding a pi key to package.json:

{
  "name": "my-pi-package",
  "keywords": ["pi-package"],
  "pi": {
    "extensions": ["./extensions"],
    "skills": ["./skills"],
    "prompts": ["./prompts"],
    "themes": ["./themes"]
  }
}

Without a pi manifest, pi auto-discovers from conventional directories (extensions/, skills/, prompts/, themes/).

See docs/packages.md.


Programmatic Usage

SDK

import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@jecruz/merc-coding-agent";

const authStorage = AuthStorage.create();
const modelRegistry = ModelRegistry.create(authStorage);
const { session } = await createAgentSession({
  sessionManager: SessionManager.inMemory(),
  authStorage,
  modelRegistry,
});

await session.prompt("What files are in the current directory?");

For advanced multi-session runtime replacement, use createAgentSessionRuntime() and AgentSessionRuntime.

See docs/sdk.md and examples/sdk/.

RPC Mode

For non-Node.js integrations, use RPC mode over stdin/stdout:

pi --mode rpc

RPC mode uses strict LF-delimited JSONL framing. Clients must split records on \n only. Do not use generic line readers like Node readline, which also split on Unicode separators inside JSON payloads.

See docs/rpc.md for the protocol.


Philosophy

Pi is aggressively extensible so it doesn't have to dictate your workflow. Features that other tools bake in can be built with extensions, skills, or installed from third-party pi packages. This keeps the core minimal while letting you shape pi to fit how you work.

No MCP. Build CLI tools with READMEs (see Skills), or build an extension that adds MCP support. Why?

Subagents are provided by the bundled Merc extension. Worktree-isolated subagents use the first active terminal adapter (tmux, WezTerm, iTerm2, or Zellij) and fall back to a child process when no adapter is active.

No permission popups. Run in a container, or build your own confirmation flow with extensions inline with your environment and security requirements.

No plan mode. Write plans to files, or build it with extensions, or install a package.

No built-in to-dos. They confuse models. Use a TODO.md file, or build your own with extensions.

No background bash. Use tmux. Full observability, direct interaction.

Read the blog post for the full rationale.


CLI Reference

pi [options] [@files...] [messages...]

Package Commands

pi install <source> [-l]     # Install package, -l for project-local
pi remove <source> [-l]      # Remove package
pi uninstall <source> [-l]   # Alias for remove
pi update [source|self|pi]   # Update pi and packages (skips pinned packages)
pi update --extensions       # Update packages only
pi update --self             # Update pi only
pi update --self --force     # Reinstall pi even if current
pi update --extension <src>  # Update one package
pi list                      # List installed packages
pi config                    # Enable/disable package resources

Modes

| Flag | Description | |------|-------------| | (default) | Interactive mode | | -p, --print | Print response and exit | | --mode json | Output all events as JSON lines (see docs/json.md) | | --mode rpc | RPC mode for process integration (see docs/rpc.md) | | --export <in> [out] | Export session to HTML |

In print mode, pi also reads piped stdin and merges it into the initial prompt:

cat README.md | pi -p "Summarize this text"

Model Options

| Option | Description | |--------|-------------| | --provider <name> | Provider (anthropic, openai, google, etc.) | | --model <pattern> | Model pattern or ID (supports provider/id and optional :<thinking>) | | --api-key <key> | API key (overrides env vars) | | --thinking <level> | off, minimal, low, medium, high, xhigh, max | | --models <patterns> | Comma-separated patterns for Ctrl+P cycling | | --list-models [search] | List available models |

Session Options

| Option | Description | |--------|-------------| | -c, --continue | Continue most recent session | | -r, --resume | Browse and select session | | --session <path\|id> | Use specific session file or partial UUID | | --fork <path\|id> | Fork specific session file or partial UUID into a new session | | --project-session <role> | Resume planning, development, review, or delivery | | --session-dir <dir> | Custom session storage directory | | --no-session | Ephemeral mode (don't save) |

Tool Options

| Option | Description | |--------|-------------| | --tools <list>, -t <list> | Allowlist specific tool names across built-in, extension, and custom tools | | --no-builtin-tools, -nbt | Disable built-in tools by default but keep extension/custom tools enabled | | --no-tools, -nt | Disable all tools by default |

Available built-in tools: read, bash, edit, write, grep, find, ls

Resource Options

| Option | Description | |--------|-------------| | -e, --extension <source> | Load extension from path, npm, or git (repeatable) | | --no-extensions | Disable extension discovery | | --skill <path> | Load skill (repeatable) | | --no-skills | Disable skill discovery | | --prompt-template <path> | Load prompt template (repeatable) | | --no-prompt-templates | Disable prompt template discovery | | --theme <path> | Load theme (repeatable) | | --no-themes | Disable theme discovery | | --no-context-files, -nc | Disable AGENTS.md and CLAUDE.md context file discovery |

Combine --no-* with explicit flags to load exactly what you need, ignoring settings.json (e.g., --no-extensions -e ./my-ext.ts).

Other Options

| Option | Description | |--------|-------------| | --system-prompt <text> | Replace default prompt (context files and skills still appended) | | --append-system-prompt <text> | Append to system prompt | | --verbose | Force verbose startup | | -h, --help | Show help | | -v, --version | Show version |

File Arguments

Prefix files with @ to include in the message:

pi @prompt.md "Answer this"
pi -p @screenshot.png "What's in this image?"
pi @code.ts @test.ts "Review these files"

Examples

# Interactive with initial prompt
pi "List all .ts files in src/"

# Non-interactive
pi -p "Summarize this codebase"

# Non-interactive with piped stdin
cat README.md | pi -p "Summarize this text"

# Different model
pi --provider openai --model gpt-4o "Help me refactor"

# Model with provider prefix (no --provider needed)
pi --model openai/gpt-4o "Help me refactor"

# Model with thinking level shorthand
pi --model sonnet:high "Solve this complex problem"

# Limit model cycling
pi --models "claude-*,gpt-4o"

# Read-only mode
pi --tools read,grep,find,ls -p "Review the code"

# High thinking level
pi --thinking high "Solve this complex problem"

Environment Variables

| Variable | Description | |----------|-------------| | PI_CODING_AGENT_DIR | Override config directory (default: ~/.pi/agent) | | PI_CODING_AGENT_SESSION_DIR | Override session storage directory (overridden by --session-dir) | | PI_PACKAGE_DIR | Override package directory (useful for Nix/Guix where store paths tokenize poorly) | | PI_OFFLINE | Disable startup network operations, including update checks, package update checks, and install/update telemetry | | PI_SKIP_VERSION_CHECK | Skip the Pi version update check at startup. This prevents the pi.dev latest-version request | | MERC_TELEMETRY | Enable or disable optional provider attribution headers. Use 1/true/yes or 0/false/no. This does not control update checks | | PI_CACHE_RETENTION | Set to long for extended prompt cache (Anthropic: 1h, OpenAI: 24h) | | VISUAL, EDITOR | External editor for Ctrl+G |


Contributing & Development

See CONTRIBUTING.md for guidelines and docs/development.md for setup, forking, and debugging.


Routing contract

Merc supports manual, auto, local_only, cloud_only, hybrid, review_pair, and opt-in fan_out modes, with balanced, local_first, quality_first, cost_saver, privacy_strict, and review_heavy profiles. Routing defaults to manual. An explicit model, scoped model set, or resumed session model bypasses startup CAISS routing, as does manual mode; these paths do not open a startup Noesis connection. Eligible automatic startup receives a bounded 2.5-second cold-transport budget, while normal per-turn preference resolution retains its 500 ms budget. Local provider constraints, local_only, cloud_only, and privacy_strict remain authoritative. Startup preference failures are non-fatal and leave the configured route unchanged.

Automatic startup routing accepts only strict applies_to.routing_hints objects with schema_version: 1 and the allowlisted fields prefer_models, ban_models, require_locality, max_cost_tier, prefer_strengths, and require_reviewer. Soft rules can advise prefer_models and prefer_strengths; only hard rules can ban models, require local or remote execution, cap cost, or require a reviewer. Cost is classified from the greater of the model's input/output price per million tokens: free is 0, low is at most 5, medium is at most 20, and high is above 20. A remote model reporting zero input and output cost is treated as unknown and excluded below high. The case-insensitive proven-local provider allowlist is exactly local, ollama, lmstudio, and llama.cpp; llmdynamix is not automatically local.

For example, a hard reviewed rule can constrain an automatic route and request review:

{
  "applies_to": {
    "routing_hints": {
      "schema_version": 1,
      "require_locality": "local",
      "max_cost_tier": "free",
      "prefer_models": ["ollama/qwen3-coder"],
      "prefer_strengths": ["bugfix"],
      "require_reviewer": true
    }
  },
  "strength": "hard"
}

require_reviewer promotes automatic startup routing to review_pair. After a completed primary response, the shared session lifecycle runs a distinct no-tool reviewer in interactive, text, JSON, and RPC modes. Reviewer failure never invalidates the primary. Reviewer context contains only the bounded visible user request, tool names with success/error status, and visible primary answer; it excludes thinking, raw tool output, and file contents, and the review is not appended to the transcript. local_only and cloud_only also constrain reviewer selection.

Use merc --route local-first --route-info or interactive /route to inspect routing. Material preference effects use fixed labels (ban-model, require-locality, max-cost-tier, preferred-model, strength-tool-fidelity, strength-reasoning, strength-local-provider, strength-context-window, and require-reviewer) with sanitized rule IDs. Use merc --route-stats or /route stats for aggregate outcomes, then record prompt-free feedback with /route feedback accepted, /route feedback edited, /route feedback tests-passed, /route feedback retry, /route feedback model-switch, or /route feedback correction.

Export portable trajectory evidence with merc route evidence export [path] [--confirm]. Without a path, Merc prints metadata-only JSONL and does not mutate the ledger or filesystem. A path requires --confirm and receives a private mode-0600 atomic write. Export includes only applied effects from transport-resolved rules, with stable idempotency keys. It excludes prompts, tool output, files, tokens, latency, costs, rejected candidates, finish reasons, and score breakdowns, and it is never uploaded automatically.

Structured startup routing hints come only from the preference transport. Merc does not reconstruct them from .merc/taste.md; that file remains the bounded prompt-preference fallback. Use /compare <prompt> for a bounded no-tool comparison, /review-pair <prompt> for an explicit independent review, and merc --route-eval for the offline faux-provider routing quality gate.

License

MIT

See Also