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

@dogik/agent-ctx

v0.3.0

Published

Deterministic multi-layer build engine that compiles engine-neutral agent context (.agent/) into Claude Code and Gemini CLI artifacts.

Downloads

352

Readme

agent-ctx

A deterministic, multi-layer build engine that compiles engine-neutral agent context (.agent/) into artifacts for Claude Code and Gemini CLI.

You author one source of truth in .agent/. agent-ctx resolves the layers (personal / org / project / repo), composes them into a single model, and renders per-engine artifacts (CLAUDE.md, GEMINI.md, .mcp.json, .claude/, .gemini/).

Why

  • One source, many engines. Stop maintaining CLAUDE.md and GEMINI.md by hand. Edit .agent/ once.
  • Layered composition. Personal preferences, org standards, project context, and repo specifics compose with clear precedence.
  • Deterministic. Same source ⇒ byte-for-byte same artifact. CI can gate on --check.

Install

Distributed as a pinned npm package — never copy-pasted into a repo:

Distributed as a pinned public npm package — never copy-pasted into a repo:

npm install --save-dev @dogik/[email protected]

It's a public scoped package, so no .npmrc or auth is needed to install. The package exposes the same agent-ctx binary — only the package name is scoped.

Usage

Connect a repository (remote sources — the default)

Point a repo at its layers by git URL + ref in .agent/manifest.yaml; on build agent-ctx clones each source at that ref and composes from it. No paths, no flags — system git provides access (see Accessing private sources).

# .agent/manifest.yaml
extends:
  - personal
  - org: acme
  - project: platform        # inside the acme repo — needs no source
sources:
  personal:
    repo: https://github.com/octo-dev/agent-personal.git
    ref: main
  org:acme:
    repo: https://github.com/acme-inc/agent-config.git
    ref: v2026.06.1          # pin a tag/commit = reproducible build
targets: [claude, gemini]
agent-ctx build .            # clone sources at their ref, render artifacts, commit
agent-ctx build . --check    # CI gate: exit 1 if artifacts would change, write nothing
agent-ctx status .           # git ls-remote probe: is the committed artifact behind?
agent-ctx refresh .          # re-fetch sources, rebuild, show the diff (no commit)
agent-ctx cache clear        # drop the clone cache (an optimization, not state)

Ready-to-copy example layouts: examples/consuming-repo/ is a built workplace (its manifest + the committed artifacts), and examples/sources/ holds the repos it points at — an org repo (with a project inside it) and a personal repo.

Local override (develop a layer without pushing)

Resolve a layer from a local path instead of its source — the escape hatch while iterating. A local path wins over the matching sources entry: orgs via a registry.yaml, personal via --personal.

agent-ctx build . --registry ../agent-config/registry.yaml --personal ~/.agent
agent-ctx init . --org acme --registry ../agent-config/registry.yaml  # scaffold + register dependent

--registry, --personal, and --cache-dir also read from AGENT_REGISTRY / AGENT_PERSONAL / AGENT_CACHE so pre-commit and CI can stay terse — all three are optional.

Commands

  • build <place> — compose the layers and render artifacts. Remote sources are cloned/fetched into the cache at their pinned ref first. --check writes nothing and exits non-zero if anything would change (the CI gate).
  • status <place> — compare the org version stamped in the committed artifact against the org's current upstream state. For a remote source this is a git ls-remote probe (no clone); reports up to date / behind (exit 1) / no artifact / cannot check (no access — diagnostic, not a failure). Makes the manual update mode safe: a repo may lag, but the lag is visible on demand.
  • refresh <place> — bring source layers to their current ref (remote sources are re-fetched into the cache by the rebuild; local-override git trees are git pull --ff-only, deduped by top-level, the repo's own git untouched), rebuild, and print the diff. It does not commit — the human decides.
  • cache clear — delete the source clone cache (--cache-dir/AGENT_CACHE). The cache is an optimization, never state: clearing it only forces a re-clone.
  • init <place> — scaffold .agent/. With --org X the manifest extends that org and the repo registers itself in the org's dependents.yaml (see Federated distribution).

Source layout (.agent/)

.agent/
  manifest.yaml          # extends + precedence + targets
  *.md                   # context docs (layered into CLAUDE.md / GEMINI.md)
  skills/<name>/
    skill.yaml           # name, description, disallowed_tools?
    body.md
  subagents/*.yaml       # name, description, system_prompt, tools?
  mcp/*.yaml             # name, command?/url?, args?, env?
  hooks/*.yaml           # name, event, command   (Claude-only)

manifest.yaml

extends:
  - personal
  - org: acme
  - project: platform
sources:                                        # where each layer comes from
  personal:
    repo: https://github.com/you/agent-personal.git
    ref: main
  org:acme:
    repo: https://github.com/acme-org/agent-config.git
    ref: v2026.06.1                             # pin a tag/commit = reproducible
  # project:platform needs NO source — a project lives inside its org repo
  # (orgs/acme/projects/platform) and arrives with the org clone.
compose:
  precedence: [repo, project, org, personal]   # highest-first
targets:
  - claude
  - gemini

sources maps each non-repo layer to a remote git repo and a ref. At build time agent-ctx clones the pinned ref into a cache and composes from it — auth is delegated entirely to system git (see Accessing private sources and INVARIANT 6). Pin ref to a tag/commit for reproducibility, or use a branch (main) to track the tip; a branch is resolved to the concrete commit SHA stamped in the artifact header.

registry.yaml (local override)

sources is the default. A local path override takes precedence over it — the escape hatch for iterating on a layer without committing/pushing. Orgs are overridden via the registry; personal via --personal. When a layer has a local override, its source is ignored and no clone happens.

orgs:
  acme:   { path: ../orgs/acme }
  globex: { path: ../orgs/globex }

Composition rules

  • Context docs accumulate from every layer in base→top order (personal → org → project → repo). Order is significant.
  • Skills, subagents, MCP servers, hooks are keyed by name; the higher-precedence layer overrides a same-named entry (default: repo wins, personal is the base).

Invariants

These are non-negotiable and covered by tests:

  1. Source / artifact separation. Generated files (CLAUDE.md, GEMINI.md, AGENTS.md, …) are never read back in as source. A stale generated file sitting in a source dir is skipped.
  2. Engine holds no secrets — fail closed. Org isolation rests on access to the org's content. An unreachable org source aborts the build with a nonzero exit and writes nothing — it is never silently skipped.
  3. Determinism. No timestamps, no nondeterministic ordering. Rebuilding unchanged source is a no-op. The artifact header carries a source-hash, not a build time.
  4. Multi-stage. A directory builds iff it holds .agent/manifest.yaml. An org folder can be both a workplace and a pure source.
  5. Capability warnings. When a target engine cannot enforce a feature (Gemini has no hooks; Gemini cannot enforce skill disallowed-tools), the adapter emits a text warning rather than silently dropping it.
  6. agent-ctx never touches credentials (auth-delegation). It never stores, reads, parses, forwards, or logs tokens. Access to private sources is handled only by system git via its credential helper. agent-ctx merely spawns git clone / git fetch / git ls-remote as child processes and passes source URLs through verbatim — never https://<token>@…. This is what lets the engine be open and run safely in any container/CI: there is no secret in it to steal. Multi-org isolation rests on the same fact — the environment holds credentials only for the orgs it may reach; no access → git fails → the build fails closed (INVARIANT 2). agent-ctx makes no access decisions; git and the environment do.

Capability matrix

| Feature | Claude | Gemini | | -------------------- | ------------- | --------------------------------- | | Context docs | CLAUDE.md | GEMINI.md | | Skills | .claude/skills/<n>/SKILL.md | .gemini/commands/<n>.toml | | Skill disallow-tools | enforced | warning (not enforced) | | Subagents | .claude/agents/<n>.md | .gemini/settings.json agents | | MCP servers | .mcp.json (url) | .gemini/settings.json (httpUrl) | | Hooks | .claude/settings.json | warning (no equivalent) |

Federated distribution

When an org layer changes, dependent repos carry a stale artifact until rebuilt. Distribution is federated: org-CI only signals dependents that the org changed; each dependent's own CI does its own rebuild and commit (narrow local rights instead of broad central access). Automation is the repo's choice:

  • automatic — catch the signal, rebuild, commit;
  • semi-automatic — catch the signal, open a PR;
  • manual — no signal; a human runs status / refresh when they like.

The rebuild mechanics (agent-ctx build with access to the layers) are identical everywhere; only the trigger differs. init --org X records the repo in org X's dependents.yaml (a plain, sorted, non-secret list) so org-CI knows whom to signal. The container that executes agent tasks consumes the already committed artifact — it never runs agent-ctx or clones layers.

Accessing private sources

agent-ctx calls git clone / git fetch / git ls-remote; access is configured entirely through your environment's git credential helper — never through agent-ctx, which holds no tokens (INVARIANT 6). The binary is identical in every environment; only the environment's git setup changes.

For multi-org setups, enable per-URL credential selection so git picks the right token by full repo URL rather than only by host:

git config --global credential.useHttpPath true

Per environment (see git / GCM / gh / Coder docs for exact commands):

  • macOSosxkeychain, or Git Credential Manager (Keychain-backed).
  • Windows / WSL — Git Credential Manager (Windows Credential Manager). From WSL you can bridge to the Windows GCM (credential.helpergit-credential-manager.exe).
  • Linux server (non-interactive) — a token in env from a protected .env, org-level SSH deploy keys (don't expire), or gh auth login device-flow.
  • Coder — don't configure a helper by hand: Coder injects tokens via GIT_ASKPASS from its external-auth providers (one per access source, declared in the template with data "coder_external_auth", which also gates workspace start). Use HTTPS source URLs so Coder matches them to providers by URL.
  • GitHub CLI (gh) — optional helper via gh auth setup-git; convenient on a server (device-flow) and in a worker (one token for both clone and gh pr create). Weaker for multi-org (built around one active account) and GitHub-only — handy, but not provider-neutral.

If a clone fails, agent-ctx aborts the build (fail closed) with the source URL and a hint to check your credential helper — never with any credential material.

Distribution & guardrails

The engine is published to the public npm registry and shared as a pinned dependency — never copy-pasted into a repo.

Releasing a new version (from this repo):

# keep src/version.ts in sync with package.json, then:
npm version 0.1.1            # bumps package.json + tags v0.1.1
git push --follow-tags       # the tag triggers .github/workflows/publish.yml

Consuming repos get these drop-ins from examples/:

Development

Setup

npm install

Running the CLI locally

You do not need to build to run the CLI. npm run dev executes the TypeScript source directly through tsx, so edit src/ and run immediately.

Pass CLI args after a -- (npm forwards everything after it to the script):

npm run dev -- <command> <args>          # e.g. init / build / status / refresh

The -- is required. Without it, npm eats the flags and the command silently does nothing.

Safe scaffold into a throwaway dir (never touches your home or global config — init only writes into the <place> you name, and is idempotent):

npm run dev -- init /tmp/agt-playground
# created: /tmp/agt-playground/.agent/manifest.yaml
# created: /tmp/agt-playground/.agent/context.md

Full multi-layer build against the bundled fixtures — a real registry + personal + org + repo wired up under test/fixtures/, so you can see composition end-to-end without inventing config:

npm run dev -- build test/fixtures/work/acme/api-service \
  --registry test/fixtures/registry.yaml \
  --personal test/fixtures/personal

This writes CLAUDE.md, GEMINI.md, .claude/, .gemini/, .mcp.json into the fixture place. They land as untracked files — discard them with git clean -fd test/fixtures/work/.

--registry / --personal also read from AGENT_REGISTRY / AGENT_PERSONAL, so you can export them once and keep commands terse:

export AGENT_REGISTRY=test/fixtures/registry.yaml
export AGENT_PERSONAL=test/fixtures/personal
npm run dev -- status  test/fixtures/work/acme/api-service
npm run dev -- build   test/fixtures/work/acme/api-service --check   # CI gate

Tip: keep all manual experiments under /tmp/... or test/fixtures/. Because init/build write only into the <place> argument, pointing them at a scratch dir means you can never clobber your real working tree.

Running the compiled binary

To exercise the published entrypoint (bin/agent-ctxdist/cli.js) you must build first:

npm run build               # tsc -> dist/
node bin/agent-ctx init /tmp/agt-playground

Test & typecheck

npm test           # vitest run — isolated, uses test/fixtures, no global writes
npm run test:watch # vitest in watch mode
npm run typecheck  # tsc --noEmit

Tests import modules directly (they never shell out to the CLI), so they need no build and have no side effects on your environment.

License

MIT