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

mono-pilot

v0.2.14

Published

Cursor-compatible coding agent powered by pi-mono

Readme

MonoPilot

Cursor-compatible coding agent profile powered by pi.

MonoPilot is a lightweight, highly customizable Cursor-compatible coding agent built on top of the pi framework. It is designed for developers who want full control over how their coding agent behaves, prefer not to pay a middleman, and want to explore the limits of a lean agent architecture.

Why MonoPilot

  • Transparent prompt/runtime envelope with inspection tooling.
  • Cursor-styled tool layer replaces default pi tools so launch-time capability and behavior are defined by MonoPilot.
  • Extensible tool layer with MCP support for custom tools and resources.

Quickstart

# Run directly without global install
npx mono-pilot

# Or install globally
npm install -g mono-pilot
mono-pilot

Usage

# Interactive
mono-pilot

# Interactive game profile (murder mystery, role-play)
mono-pilot --mono-mode game

# One-shot prompt
mono-pilot -p "Refactor this module"

# One-shot game prompt
mono-pilot --mono-mode game -p "你现在是侦探,先做自我介绍"

# Game mode with explicit channel override
mono-pilot --mono-mode game --game-channel game:office-004

# Game mode with identity auto-load from workspace
# expects .mono-game/profile.json and optional .mono-game/identity.md
mono-pilot --mono-mode game

# Optional: limit tools per role
# profile.json example: { "displayName": "侦探", "tools": ["BusSend", "MailBox", "ReadFile"] }

# Continue previous session
mono-pilot --continue

By default, mono-pilot launches pi with:

  • --no-extensions
  • --extension <mono-pilot extension>
  • --tools ls (only when you do not pass --tools or --no-tools)

If you pass --tools, MonoPilot removes built-in edit, write, read, grep, glob, and bash so the extension-provided Cursor-styled tools are used instead. If the list becomes empty, it falls back to ls. The write path is provided by the ApplyPatch tool from the extension.

What ships now

  • src/cli.ts – launcher that wraps pi
  • src/extensions/mono-pilot.ts – extension entrypoint (tool wiring)
  • src/extensions/mono-game.ts – game-oriented extension entrypoint (story + bus tools)
  • src/extensions/system-prompt.ts – provider-agnostic prompt stack
  • src/extensions/user-message.ts – user message envelope assembly
  • src/brief/ – persistent agent memory ("brief" system), inspired by letta-ai/letta-code's memory architecture, renamed from "memory" to "brief" to distinguish condensed knowledge from conversation history
  • src/memory/ – memory search indexing + retrieval (builtin, SQLite + FTS)
  • src/mcp/ – config loading, JSON-RPC transport, server resolution
  • src/rules/ – rule file discovery (shared by envelope and session hints)
  • src/tools/ – tool implementations and descriptions (see src/tools/README.md)

Cursor-styled tools

MonoPilot exposes a Cursor-style tool set to highlight capability at launch:

These replace pi defaults such as edit, write, read, grep, glob, and bash.

Default-to-MonoPilot mapping:

  • edit / writeApplyPatch
  • readReadFile
  • greprg
  • globGlob
  • bashShell

The full Cursor-styled tool list exposed by the extension:

  • Shell – execute shell commands in the workspace
  • Glob – find paths by glob pattern
  • rg – search file content with ripgrep
  • AstGrep – search code structure with ast-grep (run/scan, read-only)
  • ReadFile – read file content with pagination
  • Delete – delete files or directories
  • SemanticSearch – semantic search by intent
  • memory_search – search indexed memory snippets
  • memory_get – read a snippet from memory files
  • WebSearch – search the web with snippets
  • WebFetch – fetch and render web content
  • GenerateImage – generate images via Gemini API or OpenRouter
  • AskQuestion – collect structured multiple-choice answers
  • Subagent – launch delegated subprocesses
  • ListMcpResources – list MCP resources from config
  • FetchMcpResource – fetch a specific MCP resource
  • ListMcpTools – discover MCP tools and schemas
  • CallMcpTool – invoke MCP tools by name
  • SwitchMode – switch interaction mode (option + m, cycles Plan → Ask → Agent)
  • ExitPlanMode – exit Plan mode and switch back to Agent mode
  • ApplyPatch – apply single-file patches (supports diff-style @@ line hints)
  • CodexApplyPatch – apply codex-style multi-file patches with Add/Delete/Update/Move operations
  • MailBox – read queued bus messages (game mailbox)

User rules

MonoPilot injects user rules into the runtime envelope on each turn (handled by src/extensions/user-message.ts).

Rules are loaded from two locations:

  • ~/.pi/rules/*.rule.txt – user-level rules (applies to all projects)
  • .pi/rules/*.rule.txt – project-level rules (workspace root)

When the same filename exists in both, the project rule wins. Each file becomes one <user_rule> block inside a <rules> envelope, sorted by filename. Empty files are ignored; the envelope is omitted if no rules are found.

MCP

  • The user message envelope issues a lightweight MCP server initialize request to collect server instructions.
  • MCP tools then progressively load and surface resources, schemas, and execution only when needed.
  • MCP configs are loaded from .pi/mcp.json (project) and ~/.pi/mcp.json (user); project entries take precedence on name conflicts.

Memory search

  • Builtin memory search reads ~/.mono-pilot/config.json (memorySearch field). If missing, defaults are used.
  • Local embeddings use node-llama-cpp; configure memorySearch.local.modelPath (and optional modelCacheDir).
  • Session flush triggers are configured via memorySearch.flush (onSessionSwitch, onSessionCompact, deltaBytes, deltaMessages).
  • Use /build-memory --mode full|dirty to rebuild or incrementally sync the current agent's memory index partition.

Cluster v2 logging

  • Enable cluster_v2 with MONO_PILOT_CLUSTER_V2=1 or MONO_PILOT_CLUSTER_VERSION=2.
  • cluster_v2 logs are persisted to ~/.mono-pilot/logs/cluster_v2.YYYY-MM-DD.log.
  • Default behavior is file-only logging (keeps TUI clean). Set MONO_PILOT_CLUSTER_V2_LOG_STDIO=1 to also mirror logs to stdout/stderr.
  • /cluster operational subcommands include status, services, reelect, stepdown, and close.

System events (TUI)

  • MonoPilot keeps an in-session system event queue for low-disruption operational signals (for example SFTP, memory warmup/build/session flush, cluster failover, Discord collector progress, and Twitter pull status/failures).
  • In interactive mode, info/warning/error system events show a bottom-right overlay toast (non-capturing), with latest-only replacement.
  • Overlay can be dismissed with Esc or clicking header [×]; a 2-minute timeout remains as a fallback.
  • Use /events to inspect recent events, /events <N> for more lines, and /events clear to reset.

Discord intelligence collector (leader-local)

When cluster_v2 is enabled, leader can run a local Discord IPC collector that subscribes to message events and persists them as JSONL for intelligence gathering.

  • No follower push
  • No Discord channel interaction
  • Local persistence only

Config in ~/.mono-pilot/config.json:

{
  "discord": {
    "enabled": true,
    "clientId": "YOUR_DISCORD_APP_ID",
    "channels": [
      {
        "id": "123456789012345678",
        "alias": "My Server / general"
      }
    ],
    "events": ["MESSAGE_CREATE", "MESSAGE_UPDATE", "MESSAGE_DELETE"],
    "scopes": ["rpc", "messages.read", "identify"],
    "outputPath": "~/.mono-pilot/discord/messages.jsonl",
    "includeRawPayload": false,
    "systemEventBatchSize": 20
  }
}

Notes:

  • Requires a locally running Discord desktop client.
  • If accessToken is omitted, collector first tries cached auth from ~/.mono-pilot/auth.json.
  • If cache is missing/invalid, collector runs RPC AUTHORIZE + OAuth token exchange, then stores tokens back to ~/.mono-pilot/auth.json.
  • For first-time OAuth token exchange, many Discord apps require clientSecret (and sometimes redirectUri) in config.
  • accessToken and cached tokens are never printed in logs.
  • channels[].alias is persisted as channelAlias in each JSONL event record.
  • Collector enriches records by resolving channelId -> channelName and guildId -> guildName via RPC (GET_CHANNEL / GET_GUILD) when available.
  • Collector writes with daily rotation: outputPath is treated as base name and actual files are <base>.YYYY-MM-DD.jsonl.
  • Collector emits system-events when a channel accumulates systemEventBatchSize MESSAGE_CREATE events, then resets the channel counter and continues.
  • Collector service is registered as discord_intel in /cluster services when active.

Twitter intelligence collector (leader-local)

When cluster_v2 is enabled, leader can run a local Twitter/X collector via bird CLI. The collector verifies browser profile/cookie access at startup, then periodically pulls the "For You" timeline and persists JSONL records locally.

Config in ~/.mono-pilot/config.json:

{
  "twitter": {
    "enabled": true,
    "outputPath": "~/.mono-pilot/twitter/home.jsonl",
    "pullIntervalMinutes": 10,
    "pullCount": 10,
    "commandTimeoutMs": 30000,
    "requestTimeoutMs": 15000,
    "chromeProfile": "Profile 4",
    "chromeProfileDir": "~/Library/Application Support/Google/Chrome",
    "cookieSource": ["chrome"],
    "cookieTimeoutMs": 5000,
    "includeRawPayload": false
  }
}

Notes:

  • Startup runs bird check; if browser profile/cookies are not readable, collector startup fails and is skipped (no in-process retry loop).
  • On successful startup, collector runs one timeline pull immediately and then every pullIntervalMinutes; it treats bird home and bird home --following as two channels and switches between them when the current channel returns 0 tweets.
  • Persisted tweets[] keeps bird top-level tweet objects as-is, including nested quote structure (not flattened).
  • Collector uses depth-1 enrichment (tweet + quotedTweet) and short-link resolution: it records shortLinkMappings[] (shortUrl -> resolvedUrl -> tweetId?) for all detected t.co links, and when a mapping resolves to a tweet id it attaches shortLinkMappings[].tweetFull (deduped by tweet id within a pull cycle, excluding self-reference where tweetId equals the host tweet id).
  • Before each pull, collector loads archived tweetId snapshots from the recent two-day window (today + yesterday) and skips re-archiving duplicates that already have tweetFull; duplicate ids with missing historical tweetFull are kept for backfill attempts.
  • Each persisted batch includes a unique snapshotId to avoid downstream overwrite collisions.
  • Persisted feed reflects the actual source timeline for the batch (for_you or following).
  • Per-cycle pull errors are reported as system-events/log warnings and skipped until next scheduled cycle (no immediate retry).
  • Collector writes with daily rotation: outputPath is treated as base name and actual files are <base>.YYYY-MM-DD.jsonl.
  • Collector service is registered as twitter_intel in /cluster services when active.

Digest draft command

Use /digest draft to generate the digest draft in TUI. Use /digest backfill to serially backfill missing archive fields in-place (tweetFull, quotedTweetFull, shortLinkMappings).

/digest draft reads the daily JSONL file (<outputBase>.YYYY-MM-DD.jsonl) and classifies tweets with TUI progress events. /digest backfill scans archive files and writes updates back to the same JSONL lines (serial mode to keep upstream pressure low).

Config in ~/.mono-pilot/config.json:

{
  "twitter": {
    "digest": {
      "classifier": {
        "provider": "openai",
        "model": "gpt-4o-mini",
        "temperature": 0,
        "maxTokens": 300,
        "concurrency": 4
      }
    }
  }
}

Command examples:

/digest draft
/digest draft --date 2026-03-09
/digest draft --file ~/.mono-pilot/twitter/home.2026-03-09.jsonl --concurrency 8 --sample 6
/digest backfill
/digest backfill --date 2026-03-09
/digest backfill --file ~/.mono-pilot/twitter/home.2026-03-09.jsonl

Notes:

  • Classification categories are fixed to 7 classes: 技术 / 产品 / 融资并购 / 开源生态 / 组织动态 / 政策监管 / 学术研究.
  • Depth-1 enriched fields (tweetFull, quotedTweetFull) are used when present.
  • Draft rendering rewrites t.co short links to shortLinkMappings[].resolvedUrl; if the resolved link points to the host tweet itself, that short link is removed from draft text.
  • Draft mode now starts in background and rejects duplicate runs while active; check progress via /events.
  • Draft artifacts are written to ~/.mono-pilot/twitter/draft.md (primary draft) and ~/.mono-pilot/twitter/draft-debug.md (classification debug details).
  • Backfill mode is serial (non-concurrent), starts in background, and reuses per-run tweetId cache to avoid repeated bird read calls.
  • /events includes backfill start/file progress/end summary plus low-frequency item-level progress updates.

Image generation config

GenerateImage can read defaults from ~/.mono-pilot/config.json:

{
  "imageGen": {
    "provider": "openrouter",
    "model": "google/gemini-3.1-flash-image-preview"
  },
  "imageGenProviders": {
    "openrouter": {
      "baseUrl": "https://openrouter.ai/api/v1",
      "apiKey": "",
      "authHeader": true,
      "models": [
        { "id": "google/gemini-3.1-flash-image-preview", "name": "Nano Banana 2" }
      ]
    }
  }
}

Use /image-model to switch the active provider/model stored in config:

/image-model
/image-model list
/image-model use openrouter google/gemini-3.1-flash-image-preview

SFTP sync on ApplyPatch

If .vscode/sftp.json exists and a profile has uploadOnSave: true, patch tools can trigger uploads after successful writes:

  • ApplyPatch: uploads the affected file.
  • CodexApplyPatch: uploads files in added[] and modified[] (deleted[] is intentionally not auto-deleted remotely).

Set interactiveAuth: true to enable OTP prompts for /sftp commands and patch-triggered sync when needed.

Manual commands:

/sftp
/sftp upload path/to/file-or-dir
/sftp download path/to/file-or-dir
/sftp target <targetName>

/sftp (without args) opens an interactive target selector (up/down to choose, enter to confirm).

[
  {
    "name": "prod",
    "protocol": "sftp",
    "host": "10.0.0.130",
    "port": 22,
    "username": "wanqian",
    "privateKeyPath": "~/.ssh/id_rsa",
    "passphrase": "...",
    "remotePath": "/home/wanqian/project",
    "uploadOnSave": true,
    "interactiveAuth": true,
    "hop": {
      "host": "36.151.163.132",
      "port": 22,
      "username": "wanqian",
      "privateKeyPath": "/Users/wanqian/.ssh/id_rsa",
      "passphrase": "...",
      "interactiveAuth": true
    }
  }
]

hop enables single-jump SFTP tunneling (local -> hop -> target). Both target and hop authentication are performed by the local client, so privateKeyPath values must point to local files.

Local development

git clone https://github.com/qianwan/mono-pilot.git
cd mono-pilot
npm install
npm run build

Source-mode development (no build needed on each change):

# Run from TypeScript sources directly
npm run dev

# Optional: auto-restart on file changes
npm run dev:watch

# Continue the latest session from source mode
npm run dev:continue

# Auto-restart + continue latest session
npm run dev:watch:continue

When running in interactive mode, option+o opens the current workspace in nvim (falls back to vim), restores an existing workspace session from .mono-pilot/nvim/session.vim, and saves the session on exit.

Prompt inspection

# Build first (ensures dist extension exists)
npm run build

# Print injected system prompt + runtime envelope (snippet)
npm run inspect:injection

# Print full prompt and envelope to stdout
npm run inspect:injection:full

# Provide a custom user query to render
node scripts/inspect-injection.mjs --query="Summarize this repo"

The report shows:

  • the final system prompt after tool injection
  • the runtime envelope built from <rules>, <mcp_instructions>, <system_reminder>, and <user_query>

License

MIT