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

repoos

v1.5.0

Published

Reference CLI for RepoOS — validate a repository-local AI knowledge layer and generate vendor instruction files from it.

Readme

repoos — reference CLI

Installs a RepoOS layer into a repository, validates it, generates vendor instruction files from it, and turns agent observations into changes you can review.

Zero dependencies. Node ≥ 16. No lockfile, no transitive packages, no supply-chain surface.

npx [email protected] init .        # add the layer — never overwrites anything
npx [email protected] validate .    # is the layer well-formed?
npx [email protected] generate .    # project it into CLAUDE.md, .cursorrules, …
npx [email protected] propose .     # what have agents suggested?

The template ships inside this package, so init works from npx with no checkout, no clone, and no network beyond fetching the package itself.

Pin the version. generate --check compares byte for byte, so an unpinned CLI is a laptop and a CI runner disagreeing over nothing.

npm i -g repoos if you'd rather have repoos on the path. You can also copy cli/ into a project and run node cli/bin/repoos.js …, or fetch it from a git tag — the reference bootstrap covers offline and registry-free setups.

engines.node says >=16, and 16 is the oldest version the code is written for — plain CommonJS, no syntax newer than that. CI proves 18, 20, and 22. The floor is believed good rather than demonstrated, and "believed" is the honest word.

New here? The CLI is one part of a standard. Start at the project README — this file documents the tool, not the thing it operates on.


repoos init [path]

Copies the RepoOS template into a repository. Default target is the current directory. Full contract: ../tooling/INIT.md.

--dry-run              print the plan and change nothing
--suggest              print what to add to an existing AGENTS.md; writes nothing
--merge-existing-ai    proceed when .ai/ exists but is not RepoOS

It never overwrites a file that already exists. Not AGENTS.md, not .ai/, not .gitattributes, not a vendor file, not with a flag — there is no --force. init runs against repositories that already exist and already work, and the first thing an adoption tool can do to disqualify itself is destroy the thing it was adopted to improve.

$ repoos init . --dry-run
RepoOS initialization plan
  target    /home/you/payments-api
  template  /home/you/payments-api/node_modules/repoos/template

Would create:
  + .ai/repoos.yaml  ← project.name: payments-api (from git remote)
  + .ai/workflows/build.md
  …

Skipped (left exactly as they are):
  · AGENTS.md  already exists — RepoOS never rewrites a hand-written entry
                point. Run `repoos init --suggest` to see what to add.

Needs your attention:
  ! CLAUDE.md already exists. `repoos generate` will replace its contents…

No files were changed. Re-run without --dry-run to apply.

What it deliberately does not do: create vendor files (generate refuses to create ones nobody opted into, and routing around that here would be worse), delete x-repoos-template: true (which would turn your next validate into a wall of placeholder errors), touch source or CI, run git, or reach the network. Project discovery reads .git/config as a file, so init works offline.

If .ai/ exists and is not a RepoOS layer, init stops and says so rather than moving in alongside it. If .ai/repoos.yaml exists, RepoOS is already installed and init is a reported no-op — there is no re-initialize, because it could only work by overwriting.

repoos validate [path]

Checks a layer against ../tooling/RULES.md.

--format human|json    output format (default: human)
--profile <name>       override the declared conformance profile

Exit codes: 0 no errors · 1 errors found · 2 could not run.

Warnings never affect the exit code. Only errors do. A validator that fails builds over documentation metadata gets removed from CI, and a removed validator means the layer rots silently — which is worse than never having had one.

repoos generate [path]

Projects .ai/ into the vendor files agents actually read — CLAUDE.md, .cursorrules, .github/copilot-instructions.md, .windsurfrules.

--check          compare only; exit 1 if a derived file is stale (CI mode)
--targets a,b    which files to emit (default: those already present)

This is the tool that makes RepoOS do anything. No AI vendor is obliged to read .ai/; the generated file is what reaches the agent. A layer that validates cleanly and is never generated changes no behavior.

It will not create vendor files you haven't opted into. Create an empty CLAUDE.md and re-run, or configure targets in your manifest:

x-repoos-generate:
  targets:
    - file: CLAUDE.md
      include: [entrypoint, policy, lessons, conventions, workflows]
    - file: .cursorrules
      include: [entrypoint, conventions, workflows, lessons]
      max_bytes: 8000

include accepts entrypoint, policy, lessons, conventions, workflows, and knowledge. Unrecognized names are ignored rather than rejected.

lessons is in every target's default, and emits an index — one line per unit in .ai/memory/lessons/, with title, tags, summary, and a link — never the bodies. An approved lesson has to reach whichever assistant a contributor actually uses, or the value of a promotion depends on the reviewer's choice of tool. Bodies would grow the always-loaded set without bound, so the generated text tells the agent to open the linked file when the subject is relevant.

Nothing else under .ai/memory/ is ever derived. inbox/ is low-trust by construction and archived/ is what stopped being true; both share type: memory with lessons, so selection is by path. Full contract: ../tooling/GENERATOR.md.

In CI

npx [email protected] validate . && npx [email protected] generate . --check

--check is the one blocking check this standard endorses: the failure is unambiguous, the fix is always the same single command, and it's never a matter of judgement.

Output is deterministic — the generated date is omitted under --check so comparison is stable.


repoos propose [path]

Lists what agents have proposed in .ai/memory/inbox/, and promotes one onto a branch you can review. Full contract: ../tooling/PROPOSE.md.

$ repoos propose .
● The repoos CI job only works while its upstream repo is public
  from  .ai/memory/inbox/repoos-ci-job-needs-a-public-upstream.md
  to    .ai/memory/lessons/repoos-ci-job-needs-a-public-upstream.md
  conf  high
  by    agent:claude-opus-5/session-2026-08-03

1 proposal, 1 applicable
Apply one: repoos propose --apply=<name>
Reject one: delete the inbox file. Git keeps the history.

An agent marks an inbox entry as a proposal by adding x-repoos-proposes::

x-repoos-proposes:
  action: promote
  target: .ai/memory/lessons/some-lesson.md
  reason: >
    Why this is worth keeping. Ends up in the commit message.

The bare proposes: spelling shipped in 1.3.0 and 1.3.1 and is still read, so nothing written against those releases breaks. RO-608 warns; it never errors. The namespaced spelling wins if both appear.

--apply writes the durable unit, deletes the inbox entry, and commits both to a new branch. --dry-run prints the result without touching git. Neither pushes — that stays with you:

npx [email protected] propose . --apply=some-lesson
git push -u origin repoos/promote-some-lesson
gh pr create --fill

What it will not do. Promotion targets are limited to .ai/knowledge/ and .ai/memory/lessons/, must not already exist, and cannot escape .ai/ — so a proposal can never reach source code, CI, the agent policy, the manifest, or decisions/. Escape is blocked as a string and as a path: traversal in either separator, absolute and UNC paths, embedded NULs, a case-shifted prefix, and a destination that resolves outside .ai/ through a symlink are all refused. It also cannot amend an existing unit; corrections are a human edit. The reasoning for each refusal is in PROPOSE.md, the machine-readable table is conformance/proposals.json, and there is deliberately no flag that relaxes any of it.

If it fails partway, it rolls back. The inbox entry is restored byte for byte, the partial target is removed, and you are returned to the branch you started on. The durable unit can be rebuilt from the observation; the observation cannot be rebuilt from anything.

Rejecting is the normal outcome. Delete the file. §17.3 rule 8 is explicit that most inbox content should be deleted rather than promoted, and a promotion rate near 100% means nobody is really curating.


repoos release check [path]

Proves that every place in a repository stating a version agrees with the one place that declares it. Aimed at this project's own release process rather than at adopters, but the mechanism is general. Full contract: ../tooling/RELEASE-CHECK.md.

(no options)           check internal consistency; read-only, safe any time
--version=<x.y.z>      also check readiness to publish that specific release
$ repoos release check .
error    versioning-now-cli  VERSIONING.md disagrees about the release version
         in        VERSIONING.md
         found     1.4.0
         expected  1.4.1
         fix       Update the 'Now' column in the version table at the top of VERSIONING.md.

That is a real finding from this repository, not an illustration: release 1.4.1 moved every other declaration and left that table saying 1.4.0. Nothing failed, because nothing was comparing them.

The set of locations it checks is data, in release.json, not code. It is not a grep for the current version — changelog history, migration guides, and version examples inside the specification are explicitly out of scope, because a checker that demanded history be rewritten would be switched off within a week. A declaration that can no longer be located is an error rather than a skip, so restructuring a document cannot silently disable the check that reads it.

Unlike validate, errors here are meant to block a build: a version contradiction is unambiguous and mechanically fixable, the same bar generate --check clears. It never tags, pushes, or publishes, and there is no subcommand that does.

The = is required. Bare --version prints this tool's version, and a form that consumed the next token would make release check --version 1.4.2 print 1.4.1 and exit 0.


The YAML subset — read this before trusting it

The parser is hand-written and covers only what RepoOS files use. It is verified against all 60 YAML documents and frontmatter blocks in this repository.

Supported: block mappings and sequences · nested structures · inline flow ({ a: 1 }, [a, b]) · single and double quoted scalars · block scalars (>, |, >-, |-) · comments, including # inside quoted strings · booleans, integers, floats, null/~ · sequences of mappings.

Explicitly rejected — these throw with a line number rather than being misparsed: anchors and aliases (&/*) · type tags (!!) · complex keys (?) · tab indentation · multi-document streams.

The design rule is never guess. A parser that silently returns the wrong object turns a real violation into a false pass, and a validator that incorrectly reports "clean" is worse than no validator. If your YAML is outside the subset you get a clear error, not a wrong answer.

If you need full YAML, reimplement against ../tooling/VALIDATOR.md with a real parser and check yourself against ../conformance/.


Rules not implemented

This CLI implements every rule needed for conformance plus the tractable warnings. It deliberately skips the rest and says so — --format json returns them in a not_implemented array.

| Rule | Why not | |---|---| | RO-105, RO-204 | JSON Schema validation. Out of scope for zero-dep; use ../schemas/ with a JSON Schema library. The hand-coded RO-1xx/RO-2xx field checks cover the same ground. | | RO-305, RO-306, RO-503, RO-504 | Heuristics. A validator cannot determine what an arbitrary command does, and a noisy check gets ignored. | | RO-601 | Staleness. Needs --changed-files plus VCS history. | | RO-603 | Memory/knowledge contradiction. Needs semantic comparison. | | RO-606 | Derived-file drift — use generate --check instead. |

A validator that silently omits half its registry looks complete and isn't.


Tests

npm run selfcheck       # every canonical check, in the order CI runs them
npm test                # alias for check:test — the fast in-memory suites
npm run check:package   # npm pack → install → init, from the real tarball

selfcheck runs seven check:* scripts — check:test, check:repoos, check:template, check:json, check:generated, check:release, check:package — and .github/workflows/ci.yml runs the same seven as named steps. Each is defined once, in package.json, so there is no list to keep in sync; test/checks.js asserts it.

| Suite | Asserts | Source of truth | |---|---|---| | test/checks.js | That selfcheck and CI run the same checks in the same order, 14 assertions | package.json + ../.github/workflows/ci.yml | | test/conformance.js | Exit codes and error-severity rule IDs, 12 fixtures | ../conformance/expected.json | | test/propose.js | The promotion containment table, 83 checks | ../conformance/proposals.json | | test/generate.js | What may and may not reach a derived file, 75 checks | ../conformance/proposals.json | | test/init.js | That init creates what is missing and never overwrites what is not, 119 checks | ../tooling/INIT.md | | test/release.js | That version disagreements are caught and history is not, 87 checks | ../release.json | | test/package.js | That the published tarball can run init offline, 56 checks | package.json files |

None of them touch the network, the clock, or git, so there are no flaky cases. The first four render everything in memory; init and release write to a temp directory and remove it. test/package.js additionally shells out to npm, which is why it is check:package rather than part of check:test — it is also the only test that can tell "works in this checkout" from "works when published", since every other one resolves the template as ../template.

test/checks.js runs first, and is the odd one out: its subject is the build rather than the code. It reads package.json and ../.github/workflows/ci.yml and fails if the canonical checks, selfcheck, and CI have stopped agreeing — which they had, in both directions, before it existed.

The tables are not written in the test files. They are read from ../conformance/, so the assertions this implementation is held to are the ones an independent implementation can read without opening any of this source. A containment rule that exists only inside the reference CLI is not part of the standard, however carefully it is enforced.

Building your own implementation? Check it against the same files. If an assertion looks wrong, that's worth reporting — ambiguity in the contract is what produces tools that disagree.


MIT. This is a reference implementation, not the standard. The standard is ../SPECIFICATION.md, and it is language-agnostic by design.