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

theoria

v2.3.1

Published

Local-first research and decision runs on the AI you already have — Claude, ChatGPT, Gemini, any OpenAI-compatible endpoint or a local model: a brief in, a cited, verified report out.

Readme

Theoria

A local-first research and decision app. Give it a brief, answer at most four questions, confirm the plan and budget, and it runs on its own to a cited, verified report — a decision record or a research report — that you review in a loopback web page and export for a person (TXT, Markdown, PDF) or for an AI (a JSON bundle).

Contributing? See CONTRIBUTING.md. To report a vulnerability, see SECURITY.md.

It runs on whatever AI you already have. Out of the box that is a Claude subscription through the Claude Agent SDK; a role can be sent to a ChatGPT subscription (the codex CLI), a Google one (the gemini CLI), or any OpenAI-compatible endpoint — OpenAI, OpenRouter, or a model running locally under Ollama or llama.cpp, which costs nothing. Each of the six model roles, including the researcher, can use any provider and has its own model and effort level — see Settings. A key is read from your environment only when a role or Brave Search names its variable.

Install

Needs Node 24 or newer and, by default, a logged-in Claude Code (claude auth login). Settings can name another provider instead.

npm install -g theoria
theoria install    # add Theoria to the desktop launcher
theoria uninstall  # remove the launcher and icon

On Omarchy there is also a bar plugin — the running run's stage and spend in the top bar, a panel with the recent runs and a button that opens Theoria — in its own repository, off until you turn it on:

omarchy plugin add https://github.com/broken-branch/omarchy-theoria.git
omarchy plugin enable io.github.broken-branch.theoria

Then:

theoria doctor

prints one line per requirement — ok:, warn: or fix: with the command that fixes it — and exits 1 while anything needs fixing. It checks Node, Playwright's Chromium (the report page and the PDF export render in it; the fix line is the one-off download), whether the desktop launcher is installed, that each provider named by the settings is available and authenticated for the six effective roles, and that the data directory is writable.

Use

theoria open          # starts the loopback server and opens it in your browser
theoria open --app    # the same page as a window of its own (Omarchy's app mode when available)
theoria open --port N # a fixed port instead of a random one
theoria run --brief "Should a small team adopt pnpm workspaces?" --mode research --tier standard
theoria runs          # every run: id, status, when, the brief's first line
theoria resume <id>   # finish a run whose process died, from the last stage it saved

theoria open prints the one-time page URL it opens; the random port is visible, but the launch token never appears in a process argument or browser URL. Opening Theoria again while a run is going returns to that run instead of opening a second server; a run waiting for clarification or plan confirmation reopens on that intake flow. A brief query parameter prefills the New run brief without submitting it. THEORIA_NO_BROWSER=1 prints the URL without opening anything. theoria run is the same engine on the command line, asking its clarifying questions on stdin (--use-defaults skips them) and printing the report. The brief is text, a file path, or a single http(s):// URL, in which case the page's text (tags stripped, at most 20,000 characters) is the brief and the URL is kept on the run.

Budget tiers are quick (three sub-questions, one researcher and round, four claims, six tool calls, 300k tokens) for a narrow question, standard (eight sub-questions, 1.2M tokens) for most briefs, deep (eight sub-questions, 2.5M tokens) when the brief has several sides, and exhaustive (eight sub-questions, 5M tokens) when being wrong is expensive. Quick never asks to extend its budget: it writes up gaps as open questions. Its research reports are at most 250 words; Quick decision reports show only the recommendation and confidence, three-sentence rationale, what would change the answer, up to two risks, and open questions. The JSON bundle retains the complete record.

Runs are kept in ~/.local/share/theoria/runs.sqlite ($XDG_DATA_HOME respected; $THEORIA_HOME overrides the whole directory, settings included). A run whose server or CLI died mid-way keeps what it had saved: the GUI lists it at the top of New run with Resume and Discard, and theoria resume <id> does the same headlessly. Resume picks up from the last saved stage — research is done again from the saved scope when it had not finished — and a run interrupted before its plan was confirmed is marked failed.

Settings

Open Settings in the app header to choose an AI vendor, a model from that vendor, and effort for every role. Expand Per role settings to override one role. The screen shows sign-in fixes from theoria doctor, checks a local or remote model endpoint, and offers SearXNG or Brave search when the researcher uses an OpenAI-compatible model. Enter the name of a key environment variable, never its value. Saving replaces the settings file atomically with mode 0600; an active run keeps its current settings and the next run uses the new choice.

~/.config/theoria/settings.json (or $THEORIA_HOME/settings.json) is optional. Out of the box every role runs claude-opus-5-5 on the Claude Agent SDK. Name a role to send it elsewhere — another provider, another model, or a different effort level:

{
  "roles": {
    "critic": { "provider": "codex" },
    "researcher": { "effort": "medium" }
  }
}

For example, local Ollama can run research through a SearXNG search service, while an OpenRouter critic names its key:

{
  "search": { "provider": "searxng", "baseUrl": "http://127.0.0.1:8080" },
  "roles": {
    "researcher": {
      "provider": "openai-compatible",
      "model": "qwen3:30b",
      "baseUrl": "http://127.0.0.1:11434/v1"
    },
    "critic": {
      "provider": "openai-compatible",
      "model": "anthropic/claude-opus-4.1",
      "baseUrl": "https://openrouter.ai/api/v1",
      "apiKeyEnv": "OPENROUTER_API_KEY"
    }
  }
}

For Brave Search instead, set "search": { "provider": "brave", "apiKeyEnv": "BRAVE_API_KEY" } and export BRAVE_API_KEY. Search returns at most ten titles, URLs and snippets per query.

An OpenAI-compatible role reads a key only from the environment variable that its own apiKeyEnv names; without that setting, Theoria sends no authorization header. A role with apiKeyEnv must use HTTPS unless its endpoint is on the loopback host. An openai-compatible researcher needs a search setting and a model that supports tool calling. For Ollama, choose a tools-capable model and raise num_ctx in its Modelfile for long prompts; Ollama's /v1 API cannot set num_ctx. For llama.cpp, start the server with --jinja. The OpenAI-compatible adapter records token counts, but its dollar cost is unknown; a zero estimate does not mean a keyed endpoint is free.

Research caps: Claude and OpenAI-compatible check before each web tool, and fetch pages through Theoria's own guarded fetcher. Gemini searches only (its CLI's page fetch is turned off, because Theoria cannot guard it), checks each search with a BeforeTool hook, and its token ceiling is checked when final stats arrive. Codex counts live web_search events and stops after an overage, returning the research already written; its token ceiling is approximate because usage arrives at turn.completed.

Roles: intake, scope, lead, researcher, writer, critic. Providers: claude (default), codex (the codex CLI, logged in with codex login), gemini (the gemini CLI; run it, then enter /auth), and openai-compatible (OpenAI, OpenRouter, Ollama, llama.cpp, or another compatible /chat/completions endpoint). Efforts: low, medium, high, xhigh, max. Default models: Claude uses claude-opus-5-5, Codex uses gpt-6-luna, and Gemini uses gemini-2.5-pro.