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

@brambodev/projection

v0.5.0

Published

Projects Registry entries into executors' native configuration, and owns the ledger that can take them back.

Readme

@brambodev/projection

Projects Registry entries into executors' native configuration files, in each executor's OWN vocabulary at the location that executor actually reads (port defined in @brambodev/contracts).

  • runProjection — engine: reads the ownership ledger, then runs each target SEQUENTIALLY with per-target failure containment (a failing target never affects siblings, and failures surface as typed results — the call does not throw). The native file lands before the ledger records it, so a crash between the two under-claims rather than over-claims. Single-writer assumption: concurrent runProjection calls over the same projected file are unsupported in v1; a file modified externally between read and write fails that target instead of landing stale content.

  • runRemediation — the way OUT of a state projection reports and refuses to resolve. Four verbs, one subject per call, and the SAME call describes and performs (mode: 'inspect' | 'apply', the engine's own switch), so a preview cannot disagree with the act:

    • adopt — brambo takes ownership of what is at its own location, exactly as it is now. It writes only the ledger, and that is not the same as being harmless: owning a location is what lets a LATER runProjection replace it, and on a materialisation root REMOVE it. The description names every path that becomes deletable and says which of the two will happen, before the claim is written. A tree that is only partly there is claimed as the subset that exists, so the ordinary run writes the rest back; an entry that has left the registry is claimed from the ledger's own record, and the next run then removes the tree. There is no verb that renders one entry outside the merge.
    • release — brambo stops claiming a location. The file is not opened.
    • repair — brambo rewrites its OWN ledger to hold exactly the records it can read; the only write that does not merge, and the only exit from a ledger carrying records it cannot use.
    • discard — brambo removes its OWN prior output from a vendor file (correction-01 C6): a reserved $.brambo key whose members are all brambo's own vocabulary (version, tools, mcpServers, skills, hooks), or a # BEGIN brambo-managed block whose sub-keys under [tools]/[skills] make a Codex config.toml fail to load under --strict-config. A brambo key holding anything else is somebody's own configuration: not reported, not removed. A marker inside a multi-line TOML string is the user's bytes and is invisible to the scan.

    Containment is the materialisation rule unchanged: every path is resolved and proven inside the location brambo owns, a link at any depth disqualifies it, and a path another surviving claim holds is refused. discard checks the REAL path, so a junctioned ~/.claude cannot land the write outside the scope its refusal promises. adopt builds its claim from the TARGET's plan of what brambo would write — never from a directory listing — so a file a user put beside brambo's is never swept into a record that could later authorise deleting it, and both ledger verbs write ONE entry through updateEntry rather than replacing a scope from a read they took earlier. A remediation brambo will not perform is returned as a coded BRAMBO_PROJECTION_REMEDIATION_REFUSED, not thrown, because under inspection the refusal is part of the description.

    runRemediation defaults to mode: 'inspect' — the opposite of runProjection, and the same default brambo remediate uses, so the describe-before-act guarantee is true of the SDK surface and of the command.

  • ProjectionLedger — brambo's durable record of what it wrote (target, file, native location, content hash), in ~/.brambo/projection-ledger.json. Brambo never marks a vendor's file to prove ownership: a marker has nowhere to live in some formats and is an unknown field in others. Writes MERGE one target's claims into the on-disk document; an unreadable ledger is reported and left alone, never overwritten.

  • createClaudeMcpTarget — mcpServers in ~/.claude.json (or .mcp.json for project scope), {type:'stdio', command, args}.

  • createOpenCodeConfigTarget — mcp.<id> in opencode.json, {type:'local', command: argv}.

  • createCodexConfigTarget — [mcp_servers.<id>] in config.toml, command and args only, so --strict-config has nothing to reject.

Ledger records, native-entry and drift vocabulary live in @brambodev/contracts (src/projection.ts). Drift is a ledger-versus-disk comparison — edited, removed-by-user, foreign-collision — and is always reported, never resolved by writing.

  • createClaudeSkillsTarget / createCodexSkillsTarget / createOpenCodeSkillsTarget — materialisation targets: they own a ROOT and copy each registry skill's entryPath to <root>/<id>/SKILL.md. Brambo copies; it never authors skill content.

Where skills land, and what each executor really reads

Verified by EXECUTION against each installed binary under an injected home (test/skills-discovery.live.test.ts), not by reading a document.

| Executor | Brambo writes | How it was verified | | --- | --- | --- | | claude-code | ~/.claude/skills/<id>/SKILL.md | the request claude sends lists it in its own available-skills block | | codex | ~/.codex/skills/<id>/SKILL.md | codex debug prompt-input names the file by absolute path | | opencode | ~/.config/opencode/skills/<id>/SKILL.md | opencode debug skill reports that exact location |

OpenCode reads four roots, and brambo does not write into the one that wins. Measured: ~/.config/opencode/skills, ~/.config/opencode/skill, ~/.opencode/skills and ~/.opencode/skill are all scanned, and with the same skill id present in two of them ~/.opencode/skills silently takes precedence while brambo init and brambo doctor still report brambo's own write as done. Brambo writes one root per executor and claims nothing about precedence between them. OpenCode additionally scans ~/.claude/skills and ~/.agents/skills, so a skill brambo materialises for Claude Code is visible to opencode too.

Brambo's registry id is not necessarily the name the executor shows. Claude Code takes the skill's name from the DIRECTORY, while codex and opencode take it from the source's frontmatter name:. A registry entry whose id differs from its source's frontmatter therefore appears under two different names, and brambo's ledger, init and doctor all name the registry id.

Entries no target can express are still reported rather than approximated (skippedEntryIds, plus the target's own reason in skipped): a skill is not expressible by a CONFIG target, and an mcp-server with no command has nothing to render. A RETIRED type never reaches a target at all — groupByKind has no bucket for one — so it is neither projected nor reported here; brambo doctor reports it against the registry document instead. Skills at PROJECT scope are reported the same way — materialising into a project is a decision no story has taken, so brambo invents no location.