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

@hey-echodev/cli

v0.3.0

Published

EchoDev — persistent design memory for Claude-assisted codebases

Readme

EchoDev

npm license

Persistent design memory for Claude-assisted codebases. Before you edit a file, EchoDev surfaces why the module was built that way. After you commit, it records the new rationale into a structured decision graph.

Install

npm install -g @hey-echodev/cli
echodev --help

Or one-off without installing:

npx --package=@hey-echodev/cli echodev <command>

60-second tour

cd /path/to/your-project
echodev init                      # creates .echodev/ and .claude/skills/
echodev list                      # (empty — no decisions yet)

# Seed a decision:
echo '[{
  "slug": "auth-jwt-cookie",
  "problem": "Where do session tokens live on the client?",
  "decision": "HttpOnly cookie, never localStorage.",
  "affected_files": ["src/auth/**"],
  "future_reminders": {
    "who_might_repeat": "engineer adding SSO",
    "revisit_when":     "a cross-origin client needs tokens in JS"
  }
}]' | echodev add --stdin

echodev recall src/auth/login.ts  # returns the seeded decision
echodev graph --format mermaid    # renders the decision graph

Commands

echodev init [--no-claude]
echodev recall <paths...> [--modules a,b] [--keywords x,y]
                          [--top K] [--min-score N] [--quiet] [--format json|text]
echodev extract <ref>     [--kind commit|diff|pr|manual] [--llm auto|api|skill|null] [--force]
echodev add    --stdin    [--ref <label>]
echodev check  <diff-file>
echodev list              [--status active|superseded|expired] [--format json|text]
echodev graph             [--format mermaid|json]

Claude Code integration

echodev init drops two skills into .claude/skills/ and prints a hook recipe to stdout for you to paste into .claude/settings.json:

  • echodev-recallechodev recall <file> before any non-trivial edit.
  • echodev-record — captures decisions from a completed change.

EchoDev never auto-edits .claude/settings.json — Claude Code best practices recommend you own that file. Re-running echodev init is safe; it detects an existing echodev recall entry and skips the recipe.

For deeper guidance, see docs/best_practice.md — a user-facing best-practices guide where every rule cites both a Claude Code anchor and an EchoDev design anchor.

Hook recipe

Copy these entries into your .claude/settings.json (under the top-level "hooks" key):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "test -d .echodev && command -v echodev >/dev/null 2>&1 && echodev recall --from-stdin --quiet --format text || true"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "test -d .echodev && command -v echodev >/dev/null 2>&1 && git rev-parse HEAD >/dev/null 2>&1 && echodev extract HEAD --kind commit --llm auto || true"
          }
        ]
      }
    ]
  }
}
  • PreToolUse on Edit|MultiEdit → silent recall (gated on .echodev/ and command -v echodev)
  • Stop → idempotent extract HEAD (same gates + git rev-parse HEAD)

Hook contract

PreToolUse consumes Claude Code's documented hook input — a JSON object on stdin with a tool_input.file_path field. recall --from-stdin parses it; the contract surface lives inside this CLI so the recipe stays POSIX-pure (no jq dependency) and so a future Claude Code schema change needs one fix here, not in every consumer's settings.json. The command -v echodev guard keeps the hook silent on machines where the CLI isn't installed.

Tested against Claude Code as of 2026-04. If the hook stops returning recall results after a Claude Code update, the contract may have shifted — open an issue or check recall --from-stdin against the latest hooks reference.

After merging, run /hooks inside Claude Code to verify (or restart Claude Code).

Why EchoDev

Claude wastes context re-deriving what your project already decided. The naive fix ("dump the wiki") makes it worse.

Thesis: inject the fewest, most load-bearing prior decisions, at the moment the editor needs them, and stay silent otherwise.

Three commitments:

  1. Decision unit, not document. Each node has problem, decision, alternatives, constraints, failures, expiry_conditions, future_reminders{who_might_repeat, revisit_when}.
  2. Context-aware retrieval. File glob (1.0) → module (0.6) → keyword (0.3) → one graph hop. Embeddings are an optional re-ranker, never the base.
  3. Prefer silence over noise. Empty queries, weak hits, and already-extracted commits all produce zero output.

Defaults that enforce #3

| Guard | Default | Why | |---|---|---| | recall --min-score | 0.5 | Drops lone-keyword hits (0.3). File/module/multi-keyword survive. | | recall --top | 5 | Hard cap. Never injects more than ~5 decisions (~20 lines). | | Empty query → empty output | always | No paths/modules/keywords → no dump. | | recall --quiet | used by hooks | Zero hits print nothing — no breadcrumb on every edit. | | Graph expansion | 1 hop, re-gated by min-score | Neighbours score × 0.5. | | extract idempotency | on | .last-extracted marker — safe to bind to Stop. | | Hook repo gate | test -d .echodev | No cross-project leakage. | | Hook matcher | Edit\|MultiEdit | Write excluded — new files have no prior decisions. |

Cost scales with decision count, not project size.

Decision schema

Each decision is one JSON file under .echodev/decisions/<id>.json:

{
  "schema_version":   "1.0",
  "id":               "d-YYYY-MM-DD-<slug>",
  "status":           "active | superseded | expired",
  "problem":          "...", "decision": "...",
  "alternatives":     ["..."], "constraints": ["..."], "failures": ["..."],
  "expiry_conditions":["falsifiable signals this no longer applies"],
  "affected_files":   ["globs"], "affected_modules": ["logical"],
  "relations": {
    "inherits": [...], "conflicts_with": [...], "fills_gap_of": [...],
    "shared_premise": [...], "superseded_by": null
  },
  "future_reminders": { "who_might_repeat": "...", "revisit_when": "..." },
  "source": { "type": "commit|pr|issue|manual", "ref": "..." }
}

Full schema: schema/decision.schema.json — language-agnostic, any tool can read/write.

Schema versioning

Every decision file carries schema_version. The current version is "1.0".

  • Writers stamp it. echodev add and echodev extract set schema_version: "1.0" on every decision they produce.
  • Readers fail-closed. Any decision missing schema_version, or carrying a value the running CLI doesn't know, is rejected with an error pointing to echodev migrate. This prevents silent corruption when the schema evolves.
  • echodev migrate walks a forward chain. packages/cli/src/commands/migrate.ts declares a MIGRATIONS registry — currently one step (undefined → "1.0", backfilling pre-versioned legacy files). The walker applies whatever steps lead from the file's current version to the target.
  • Adding v2 is one append. When a future schema change ships, add a {from: "1.0", to: "1.1", apply: ...} entry to the chain. echodev migrate picks it up; existing files migrate forward in a single pass; no other code changes.
  • No downgrade. A file carrying a version newer than the running CLI knows about has no chain step → migrate refuses with a clear error rather than corrupting it. Upgrade the CLI instead.

What to commit

  • Commit: .echodev/decisions/, .echodev/.gitignore
  • Ignore (auto-managed, per-clone): .echodev/index/, .echodev/bridge/ — these are rebuilt from decisions/ on demand and include a local idempotency marker; they should never be shared.

LLM modes

--llm auto|api|skill|null:

  • auto (default) — Claude API if ANTHROPIC_API_KEY is set, else Skill Bridge
  • api — force Claude API
  • skill — force Skill Bridge (no API key; skill fills the prompt from Claude Code)
  • null — never call an LLM (CI smoke tests)

Contributing / forking

Clone the repo, run the bundled sample:

git clone https://github.com/jieyao-MilestoneHub/EchoDev
cd EchoDev
npm install
npm run build
node packages/cli/dist/index.js --repo examples/sample-repo list

The core logic is free functions behind typed ports (DecisionReader, DecisionWriter, Extractor, Retriever, LLMClient). Adapters live in packages/{storage-fs,extractors,retriever,llm}. The composition root is packages/cli/src/composition.ts — add a new LLM client or storage backend by writing a new adapter and wiring it there.

MIT © jieyao-MilestoneHub