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

@magic-spells/constellation

v0.7.0

Published

Files-first architecture planning for AI-assisted development. Your project plan as markdown cards in the repo — typed, connected, queryable, and diffable with git.

Readme

Constellation

Your project's architecture plan as markdown files in the repo: typed cards, connected into a graph, validated by lint, diffed by git, readable by humans on GitHub and by AI agents with nothing more than file access.

constellation/
  plan.md                      ← the living project plan (PLAN-PROJECT)
  api/API-TICKETS.md           ← one file per card; the filename IS the handle
  datatype/DATATYPE-TICKET.md
  db/DB-TICKETS.md
  flow/FLOW-CREATE-TICKET.md
  ...

Each card is frontmatter (structure) + markdown (narrative). Connections come from frontmatter: a plain connections: list of handles, plus handle-shaped values in other frontmatter fields. A [[HANDLE]] link in prose or a handle used as a Mermaid node ID is a hyperlink — clickable, linted, but never a graph edge. The indexer derives the graph; nothing derived is ever stored.

Why files? Plans drift from code when they live somewhere else. Here a plan change is a commit: it rides the same branch and PR as the code it describes, merges per-card, and "what changed in the plan" is git diff -- constellation/.

Install

npm install -g @magic-spells/constellation   # the `constellation` binary
# or run without installing:
npx @magic-spells/constellation lint

Requires Node ≥ 22.

Usage

constellation init          # scaffold constellation/ with a starter plan.md
constellation lint          # validate handles, references, folders, schemas
constellation rename A-X A-Y  # rename a card + rewrite every reference to it
constellation mcp           # run the MCP server (stdio) for AI agents
constellation serve         # open the local viewer (editable; --readonly to disable)
constellation repos         # list sibling repos declared in connected_repos
constellation add skills    # install the authoring skill into ~/.claude, ~/.codex, ~/.cursor, ~/.agents
constellation version       # print the CLI version (`v` also works)
constellation upgrade       # npm install -g @magic-spells/constellation@latest

Lint errors (broken graph: bad handles, dangling structured references, duplicates) exit non-zero for CI; warnings (wrong folder, schema violations, unknown fields, dangling prose links) don't block.

Repo layout

| Path | What | |---|---| | constellation/ | Constellation's own plan — the format spec, MCP design, and architecture as connected cards (formerly docs/); also a flagship real-world plan | | schemas/ | JSON Schemas: card.json (reserved keys) + one per type | | skill/ | AI authoring skill: SKILL.md + per-type references with golden examples | | src/core/ | Parser, reference extraction, indexer, schema validation, lint | | src/cli/ | The constellation binary (init, lint, rename, mcp, serve, repos, add skills, version, upgrade) | | src/mcp/ | MCP server: hydrated retrieval, validated writes, git tools | | viewer/ | The Puzzle single-page viewer — themes, card pages, neighborhood diagrams | | examples/constellation/ | Golden sample plan — one card of every type, lints clean, doubles as the test fixture |

Development

npm install
npm test                 # vitest
npm run lint:examples    # lint the golden plan
npm run build            # tsc → dist/

MCP

constellation mcp exposes the plan to AI agents over stdio:

  • Self-serving: orient opens a session with the whole plan at a glance in one small call; describe_type hands back a card type's schema and authoring guidance, so an agent can write correct cards with no skill installed.
  • Hydrated retrieval: get_card, search, and traverse can return connected cards with their complete frontmatter and body in one call. list_cards and traverse filter by status — ["planned", "building", "none"] is the backlog view (everything not yet built).
  • Validated writes: create_card / create_cards, update_card, append_note / edit_section (byte-cheap memory writes), set_verified, rename_card (rewrites every reference plan-wide), delete_card, add_connection(s), remove_connection — every write lints and returns issues. Body-only updates never reformat frontmatter.
  • Queryable memory: search matches appended note text; list_notes lists notes across cards by kind (every gotcha / decision in one call).
  • Git-powered change tracking: diff_plan (per-card changes since the sync marker), plan_log, set_sync_point, stale_report / check_sync (bound-code drift since a card was verified), check_integrity.
  • Connected repos (multi-repo): a plan can declare sibling repos (add_connected_repo / list_connected_repos / remove_connected_repo); every tool takes an optional repo selector to read or write a sibling's plan — or a package's plan in a monorepo (see Monorepos). Omit it and single-repo behavior is unchanged.
  • Visual viewer: start_viewer / stop_viewer open and close the local web viewer from inside an agent session, returning a clickable URL.

Add to Claude Code

Run from your repo root, so the server starts there and finds the plan:

# Run straight from npm — no install needed:
claude mcp add constellation -- npx -y @magic-spells/constellation mcp

# Or, if installed globally (npm i -g @magic-spells/constellation):
claude mcp add constellation -- constellation mcp

# Share with everyone who clones the repo (writes .mcp.json):
claude mcp add --scope project constellation -- npx -y @magic-spells/constellation mcp

Manage it with claude mcp list, claude mcp get constellation, and claude mcp remove constellation.

To build a plan from an existing codebase (or audit one), ask the agent to bootstrap or audit — the server ships bootstrap_plan and audit_plan prompts (slash commands in Claude Code) that walk the code macro→micro: follow the data, follow the user/auth, then step back and pressure-test the plan for blind spots (missing unhappy paths, auth gaps, forgotten cross-cutting concerns) and recommend. The full method is in skill/methodology.md.

Add to Codex

Codex CLI keeps MCP servers in ~/.codex/config.toml (TOML, not JSON). Add it with the CLI:

# Run straight from npm — no install needed:
codex mcp add constellation -- npx -y @magic-spells/constellation mcp

# Or, if installed globally (npm i -g @magic-spells/constellation):
codex mcp add constellation -- constellation mcp

…or hand-edit the config (a project-scoped .codex/config.toml also works in trusted repos):

[mcp_servers.constellation]
command = "npx"
args = ["-y", "@magic-spells/constellation", "mcp"]
cwd = "/path/to/your/repo"   # so the server walks up to your plan

Launch codex from your repo root (or set cwd above) so the server starts there and finds the plan — otherwise tools return NO_PLAN_FOUND. Run /mcp inside a Codex session to confirm it's connected; manage it with codex mcp list and codex mcp remove constellation.

Other MCP clients

Hand-edit the client's config (Claude Desktop, a project .mcp.json, etc.):

{
  "mcpServers": {
    "constellation": {
      "command": "constellation",
      "args": ["mcp"],
      "cwd": "/path/to/your/repo"
    }
  }
}

Set cwd to your repo root (or any folder inside it). The server finds the plan by walking up from its working directory; without cwd it inherits the client's, which may not be your project — in which case tools return NO_PLAN_FOUND.

Monorepos

A plan doesn't have to live at the git root. In a monorepo each package keeps its own plan, and the root holds at most a thin signpost that routes to them:

packages/puzzle/constellation/plan.md         ← the framework's plan
packages/puzzle-pieces/constellation/plan.md  ← the registry's plan
constellation/plan.md                         ← signpost: connected_repos, no cards

A card's path: and code_refs are relative to its plan's code root — the folder containing that constellation/ dir, or the code_root field on the plan's frontmatter. Staleness, the version check, commit scoping and code attachment all follow the code root, so each package measures drift against its own history.

The signpost is plan.md and nothing else: its connected_repos names the package plans (puzzlepackages/puzzle), so repo=puzzle addresses that plan from any MCP tool. Never init_plan a full plan at a monorepo root — architecture cards belong to the package plans, and cards never connect across plans.

constellation serve at a monorepo root hosts every plan in the repo from one server, with a plan-switcher dropdown in the viewer; --plan <id> picks which one opens by default, and constellation serve <path> still serves exactly one. Discovery runs at startup and never crosses into a nested .git, so a brand-new plan needs a restart.

Single-repo behavior is unchanged: the code root is the repo root, there's no dropdown, and every path and URL stays what it was.

Viewer

constellation serve renders the plan as a local website, editable in place (pass --readonly to disable writes). Five colour schemes toggle in the header — observatory (dark, star-field; the default), default, warm, void and dim — each with a light / dark / follow-system switch.

The Overview page is a status board for the plan:

  • a health strip — the freshness verdict, the counts that qualify it (cards, connections, integrity, drift), and a Set sync point button that stamps the baseline every claim card is measured against
  • Releases — every RELEASE card newest-first, the one still in flight expanded with its FEATURE cards grouped Breaking / Features / Fixes / Chores (from each feature's change: field), the shipped ones collapsed and openable. A release describes itself from the features pointing at it — never a hand-written changelog
  • Activity — plan commits and code commits in one stream, tagged by kind
  • Code drift — the cards whose bound code moved since they were last verified, as a verdict rather than a list, with the fix named when nothing is tracked yet
  • Notes — the latest append_note memory across cards

Card pages show structured fields, the markdown body, connection chips in both directions, and a small constellation diagram of the card's neighborhood — its nodes tinted by card type. Mermaid blocks render in-browser, [[HANDLE]] links navigate, and the page live-reloads when plan files change on disk.

constellation serve     # http://localhost:4747 (walks upward if busy; assets ship prebuilt)
npm run build:viewer    # only when developing from source

In an agent session you don't need the CLI — ask Claude to open the viewer and it calls the start_viewer MCP tool, which returns the URL (stop_viewer closes it).