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

promptpilot

v0.2.2

Published

A code-first prompt optimizer, session memory layer, and downstream model router for Claude CLI and agentic LLM workflows.

Readme

promptpilot

A local prompt optimizer and model router for Claude CLI and agentic LLM workflows.

Before your prompt reaches a remote model, PromptPilot rewrites it locally using a small Ollama model — cutting noise, compressing context, and routing to the right downstream model. No prompt rewrite costs you remote tokens.


Install

npm install -g promptpilot

Requires Ollama running locally and Node.js >= 20.10.0.

Pull at least one small local model:

ollama pull qwen2.5:3b

What it does

  • Rewrites your prompt locally before sending it anywhere
  • Keeps session memory across turns so context carries forward
  • Compresses old context when it gets too long
  • Routes to the best model from a list you provide
  • Outputs plain text for shell pipelines or JSON for tooling

Quick start

# Optimize a prompt and print the result
promptpilot optimize "explain binary search simply" --plain

# Pipe directly into Claude
promptpilot optimize "continue my study guide" --session dsa --save-context --plain | claude

# Read from a file
cat notes.txt | promptpilot optimize --task summarization --plain | claude

Session memory

Pass --session <name> to persist context across calls. PromptPilot stores sessions as JSON under ~/.promptpilot/sessions by default.

# Save context after each turn
promptpilot optimize "start a refactor plan" --session repo-refactor --save-context --plain

# Pick up where you left off
promptpilot optimize "continue the refactor" --session repo-refactor --save-context --plain | claude

# Clear a session when you're done
promptpilot optimize --session repo-refactor --clear-session

Custom compressor model

PromptPilot ships a Modelfile that builds promptpilot-compressor — a stripped-down Ollama model tuned to output only the rewritten prompt with no extra commentary.

ollama pull qwen2.5:3b
ollama create promptpilot-compressor -f ./Modelfile

Use it:

promptpilot optimize "help me refactor this auth middleware" \
  --model promptpilot-compressor \
  --preset code \
  --plain

Downstream model routing

Tell PromptPilot which models you're allowed to use and it picks the best one for the job.

promptpilot optimize "rewrite this for a coding refactor" \
  --task code \
  --preset code \
  --target anthropic:claude-sonnet \
  --target openai:gpt-4.1-mini \
  --target openai:gpt-5-codex \
  --target-hint coding \
  --target-hint refactor \
  --json --debug

Library usage

Basic optimization

import { createOptimizer } from "promptpilot";

const optimizer = createOptimizer({
  provider: "ollama",
  host: "http://localhost:11434",
  contextStore: "local"
});

const result = await optimizer.optimize({
  prompt: "help me debug this failing CI job",
  task: "code",
  preset: "code",
  sessionId: "ci-fix",
  saveContext: true
});

console.log(result.finalPrompt);
console.log(result.model);

Routing across multiple models

const result = await optimizer.optimize({
  prompt: "rewrite this prompt for a coding refactor task",
  task: "code",
  preset: "code",
  availableTargets: [
    {
      provider: "anthropic",
      model: "claude-sonnet",
      label: "anthropic:claude-sonnet",
      capabilities: ["coding", "writing"],
      costRank: 2
    },
    {
      provider: "openai",
      model: "gpt-4.1-mini",
      label: "openai:gpt-4.1-mini",
      capabilities: ["writing", "chat"],
      costRank: 1
    },
    {
      provider: "openai",
      model: "gpt-5-codex",
      label: "openai:gpt-5-codex",
      capabilities: ["coding", "agentic", "tool_use", "debugging"],
      costRank: 3
    }
  ],
  routingPriority: "cheapest_adequate",
  targetHints: ["coding", "agentic", "refactor"],
  workloadBias: "code_first",
  debug: true
});

console.log(result.selectedTarget);
console.log(result.rankedTargets);
console.log(result.routingReason);

Non-coding tasks work too

const result = await optimizer.optimize({
  prompt: "write a short internship follow-up email",
  task: "email",
  preset: "email",
  availableTargets: [
    {
      provider: "anthropic",
      model: "claude-sonnet",
      label: "anthropic:claude-sonnet",
      capabilities: ["coding", "writing"],
      costRank: 2
    },
    {
      provider: "openai",
      model: "gpt-4.1-mini",
      label: "openai:gpt-4.1-mini",
      capabilities: ["writing", "email", "chat"],
      costRank: 1
    }
  ]
});

console.log(result.selectedTarget);

Node child_process pipeline

import { spawn } from "node:child_process";

const promptpilot = spawn("promptpilot", [
  "optimize",
  "continue working on this repo refactor",
  "--session", "repo-refactor",
  "--save-context",
  "--plain"
]);

const claude = spawn("claude", [], { stdio: ["pipe", "inherit", "inherit"] });
promptpilot.stdout.pipe(claude.stdin);

CLI flags

| Flag | What it does | |---|---| | --session <id> | Name the session for persistent memory | | --save-context | Write this turn back into the session | | --clear-session | Wipe a session and start fresh | | --no-context | Ignore session history for this call | | --model <name> | Use a specific local Ollama model | | --preset <preset> | Prompt style: code, email, essay, support, summarization, chat | | --mode <mode> | Rewrite mode: clarity, concise, detailed, structured, persuasive, compress, claude_cli | | --task <task> | Task hint passed to the optimizer | | --tone <tone> | Tone hint passed to the optimizer | | --target <provider:model> | Add a downstream model to the routing pool (repeatable) | | --target-hint <value> | Capability hint for routing (repeatable) | | --routing-priority <value> | cheapest_adequate, best_quality, or fastest_adequate | | --routing-top-k <n> | How many ranked targets to return | | --workload-bias <value> | code_first to bias routing toward coding models | | --no-routing | Skip downstream routing entirely | | --plain | Output the final prompt as plain text | | --json | Output full result as JSON | | --debug | Include routing and optimization details in output | | --host <url> | Ollama host (default: http://localhost:11434) | | --store <local\|sqlite> | Session storage backend | | --storage-dir <path> | Custom path for session files | | --sqlite-path <path> | Path to SQLite database file | | --max-total-tokens <n> | Token budget for the full composed prompt | | --max-context-tokens <n> | Token budget for retrieved session context | | --max-input-tokens <n> | Token budget for the incoming prompt | | --timeout <ms> | Ollama request timeout in milliseconds | | --bypass-optimization | Skip Ollama and pass the prompt through as-is | | --pin-constraint <text> | Add a pinned constraint (repeatable) | | --tag <value> | Tag this session entry (repeatable) | | --output-format <text> | Output format hint | | --max-length <n> | Max length hint for the rewritten prompt | | --target-model <name> | Alternate flag for downstream model name |

If no prompt text is given, promptpilot optimize reads from stdin.


How local model selection works

PromptPilot prefers small Ollama models (≤ 4B params). If only one suitable model is installed, it uses it directly. If multiple are installed, a local Qwen router picks the best one for the task. Explicit --model always overrides this.

Default preference order:

  1. qwen2.5:3b
  2. phi3:mini
  3. llama3.2:3b

If Ollama is unavailable or times out, PromptPilot falls back to deterministic prompt shaping (whitespace cleanup, mode-specific wrappers) instead of failing outright.


Exports

import {
  createOptimizer,
  optimizePrompt,
  PromptOptimizer,
  OllamaClient,
  FileSessionStore,
  SQLiteSessionStore
} from "promptpilot";

Key fields on the result object:

| Field | Description | |---|---| | optimizedPrompt | The rewritten prompt from the local model | | finalPrompt | The composed prompt including context | | selectedTarget | The downstream model chosen by the router | | rankedTargets | All targets ranked by the router | | routingReason | Why the top target was selected | | routingWarnings | Any issues the router flagged | | provider | Which provider ran the optimization (ollama or heuristic) | | model | Which local model was used | | estimatedTokensBefore | Token estimate before optimization | | estimatedTokensAfter | Token estimate after optimization |


License

MIT