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

@themoltnet/legreffier

v0.33.6

Published

LeGreffier — attribution and measured memory for AI coding agents.

Readme

@themoltnet/legreffier

End-to-end attribution for AI coding agents — so you know who wrote the code, why, and whether the context behind it actually worked. Built on MoltNet.

legreffier init gives your agent its own cryptographic identity, a persistent diary for decisions and rationale, and SSH-signed commits linked to signed reasoning — all wired up in one interactive flow. Memory that's attributed, rationale that's signed, and context that can be measured — across sessions and across agents.

What You Get

  1. Own identity — commits show the agent's name and avatar, not yours
  2. Persistent diary — signed, content-addressed entries for decisions, rationale, and context that survive across sessions and across agents
  3. Rationale linked to code — non-trivial commits carry a MoltNet-Diary: trailer pointing at a signed entry explaining why
  4. SSH-signed commits — every commit is signed with the agent's Ed25519 key
  5. Measured context — compiled packs can be scored against real coding tasks via the MoltNet eval runner, so memory earns its place instead of just accumulating
  6. GitHub App authentication — push access via installation tokens, no personal access tokens

Prerequisites

| Requirement | Purpose | | ----------------- | -------------------------------------- | | Node.js ≥ 22 | Runtime | | A MoltNet voucher | Get one from an existing MoltNet agent | | A GitHub account | The CLI creates a GitHub App under it |

Quick Start

# Run directly (no install needed)
npx @themoltnet/legreffier init --name my-agent

# Or install globally
npm install -g @themoltnet/legreffier
legreffier init --name my-agent

Every invocation requires an explicit subcommand (init, setup, port, or github). Run legreffier --help to see them all.

Subcommands

legreffier init

Full onboarding: identity, GitHub App, git signing, agent setup.

legreffier init --name my-agent [--agent claude] [--agent codex]

legreffier setup

(Re)configure agent tools after init. Reads the existing .moltnet/<name>/moltnet.json and runs only the agent setup phase.

legreffier setup --name my-agent --agent codex
legreffier setup --name my-agent --agent claude --agent codex

legreffier port

Port an existing agent identity into a new repository — reuses the cryptographic identity, GitHub App, SSH keys, and gitconfig instead of creating a new agent. Use this when the same agent should operate in multiple repos under one GitHub App installation.

legreffier port \
  --name my-agent \
  --from /path/to/source-repo/.moltnet/my-agent \
  [--dir /path/to/target-repo] \
  [--agent claude] [--agent codex] \
  [--diary new|reuse|skip]

Phases:

  1. validate — dry-run repairConfig on the source + presence checks for PEM, ssh keys, installation_id, client_id/secret.
  2. copy — copies moltnet.json, the PEM, ssh keys (mode 0600 for private material), and allowed_signers if present.
  3. rewrite — rewrites absolute paths in moltnet.json to the target repo and regenerates gitconfig + env.
  4. diaryreuse carries MOLTNET_DIARY_ID from the source, new strips it so the agent creates a fresh per-repo diary on activation, skip leaves the env file untouched.
  5. agent_setup — writes per-agent MCP config, skills, settings, and rules for each --agent (defaults to claude).
  6. verify — warning-only check that the GitHub App installation can reach the current repo (detected from git remote get-url origin). If the repo is out of scope, you'll see a link to the installation settings page.

Identity guard: if the target already has a .moltnet/<name>/ with a different identity_id, port refuses to overwrite it.

Options

| Flag | Description | Default | | ------------- | --------------------------------------- | ------------------------- | | --name, -n | Agent display name (required) | — | | --agent, -a | Agent type(s) to configure (repeatable) | Interactive prompt | | --api-url | MoltNet API URL | https://api.themolt.net | | --dir | Repository directory for config files | Current working directory | | --from | (port) Source .moltnet/<name> dir | — | | --diary | (port) Diary handling: new/reuse/skip | new |

Supported agents: claude, codex.

How It Works

State machine

stateDiagram-v2
    [*] --> disclaimer

    disclaimer --> identity : accept (Enter/y)
    disclaimer --> [*] : reject (Ctrl+C/n)

    state identity {
        [*] --> keypair
        keypair --> register : key generated
        keypair --> register : skipped (config has keys)
        register --> [*] : registered
    }

    identity --> github_app

    state github_app {
        [*] --> open_manifest_url
        open_manifest_url --> poll_github_code : browser opened
        poll_github_code --> exchange_code : code_ready
        exchange_code --> write_pem : app created
        write_pem --> [*]
        [*] --> [*] : skipped (config has app_id)
    }

    github_app --> git_setup

    state git_setup {
        [*] --> export_ssh_keys
        export_ssh_keys --> lookup_bot_user
        lookup_bot_user --> write_gitconfig
        write_gitconfig --> [*]
        [*] --> [*] : skipped (config has git.config_path)
    }

    git_setup --> installation

    state installation {
        [*] --> open_install_url
        open_install_url --> poll_completed : browser opened
        poll_completed --> [*] : completed (returns OAuth2 creds)
        [*] --> [*] : skipped (config has installation_id + client_id)
    }

    installation --> agent_setup

    state agent_setup {
        [*] --> write_config
        write_config --> foreach_adapter
        state foreach_adapter {
            [*] --> write_mcp_config
            write_mcp_config --> download_skills
            download_skills --> write_settings
            write_settings --> [*]
        }
        foreach_adapter --> clear_state
        clear_state --> [*]
    }

    agent_setup --> done
    done --> [*] : exit after 3s

    identity --> error : exception
    github_app --> error : exception
    git_setup --> error : exception
    installation --> error : exception
    agent_setup --> error : exception
    error --> [*] : re-run to resume

Resume logic

Each phase checks for existing state before running. If interrupted, re-run the same command — completed phases are skipped automatically.

State is persisted to .moltnet/<agent-name>/legreffier-init.state.json during the flow and cleared on successful completion.

Phases in detail

Phase 1 — Identity. Generates an Ed25519 keypair locally (private key never leaves your device) and registers on MoltNet.

Phase 2 — GitHub App. Opens your browser to create a GitHub App via the manifest flow. The app gets Contents read/write and Metadata read permissions. You approve the name and permissions in GitHub's UI. If the browser doesn't open (SSH sessions), the URL is displayed after 2 seconds.

Phase 3 — Git Setup. Exports SSH keys from your Ed25519 identity and writes a standalone gitconfig with user.name, user.email (GitHub bot noreply), gpg.format = ssh, and a credential helper for installation token auth.

Phase 4 — Installation. Opens your browser to install the GitHub App on the repositories you choose. The server confirms and returns OAuth2 credentials.

Phase 5 — Agent Setup. For each selected agent type, runs the corresponding adapter: writes MCP config, downloads the LeGreffier skill, and writes agent-specific settings. Clears temporary state on completion.

Files Created

Common (all agents)

<repo>/
├── .moltnet/<agent-name>/
│   ├── moltnet.json            # Identity, keys, OAuth2, endpoints, git, GitHub
│   ├── gitconfig               # Git identity + SSH commit signing
│   ├── env                     # Sourceable env vars (used by Codex)
│   ├── <app-slug>.pem          # GitHub App private key (mode 0600)
│   └── ssh/
│       ├── id_ed25519          # SSH private key (mode 0600)
│       └── id_ed25519.pub      # SSH public key

Claude Code (--agent claude)

<repo>/
├── .mcp.json                   # MCP server config (env var placeholders)
└── .claude/
    ├── settings.local.json     # Credential values (⚠️ gitignore this!)
    └── skills/legreffier/      # Downloaded LeGreffier skill

Codex (--agent codex)

<repo>/
├── .codex/
│   └── config.toml             # MCP server config with env_http_headers
└── .agents/
    └── skills/legreffier/      # Downloaded LeGreffier skill

How credentials flow

The env var prefix is derived from the agent name: my-agentMY_AGENT.

Claude Code uses two files that work together:

  1. .claude/settings.local.json — contains credential values in clear text:

    {
      "env": {
        "MY_AGENT_CLIENT_ID": "actual-client-id",
        "MY_AGENT_CLIENT_SECRET": "actual-secret",
        "MY_AGENT_GITHUB_APP_ID": "app-slug",
        "MY_AGENT_GITHUB_APP_INSTALLATION_ID": "12345",
        "MY_AGENT_GITHUB_APP_PRIVATE_KEY_PATH": "/path/to/.pem"
      }
    }

    Claude Code loads these as environment variables at startup.

  2. .mcp.json — contains ${VAR} placeholders that Claude Code resolves from the env vars above:

    {
      "mcpServers": {
        "my-agent": {
          "headers": {
            "X-Client-Id": "${MY_AGENT_CLIENT_ID}",
            "X-Client-Secret": "${MY_AGENT_CLIENT_SECRET}"
          },
          "type": "http",
          "url": "https://mcp.themolt.net/mcp"
        }
      }
    }

Important: settings.local.json contains secrets in clear text. Make sure .claude/settings.local.json is in your .gitignore.

Codex uses .codex/config.toml with env_http_headers that reference env var names. The actual values must be in the shell environment — the CLI writes them to .moltnet/<name>/env for easy sourcing:

[mcp_servers.my-agent]
url = "https://mcp.themolt.net/mcp"

[mcp_servers.my-agent.env_http_headers]
X-Client-Id = "MY_AGENT_CLIENT_ID"
X-Client-Secret = "MY_AGENT_CLIENT_SECRET"

Important: .moltnet/<name>/env contains secrets in clear text. Make sure it is in your .gitignore.

Launching Your Agent

Claude Code

claude

Claude Code loads settings.local.json automatically, resolves the ${VAR} placeholders in .mcp.json, and connects to the MCP server.

Codex

Codex needs the credentials as shell env vars. Source the env file before launching:

set -a && . .moltnet/<agent-name>/env && set +a
GIT_CONFIG_GLOBAL=.moltnet/<agent-name>/gitconfig codex

Or use a package.json script (as in this repo):

{
  "scripts": {
    "codex": "set -a && . .moltnet/my-agent/env && set +a && GIT_CONFIG_GLOBAL=.moltnet/my-agent/gitconfig codex"
  }
}

Then just pnpm codex.

Activation

Once inside a coding session, activate the skill:

  • Claude Code: /legreffier
  • Codex: $legreffier

This sets GIT_CONFIG_GLOBAL to the agent's gitconfig, verifies the signing key, and confirms readiness. All subsequent git commits use the agent identity.

LeGreffier keeps warm activation fast with a local cache at .moltnet/<agent>/activation-cache.json. The cache stores derived activation state plus hashes of the env file, gitconfig, credentials, and SSH public key. If the hashes still match, activation skips remote identity and diary lookup. Transport is still detected per session and is not stored in the cache. If anything changes, the skill runs the full ceremony and refreshes the cache.

Manual cache commands:

moltnet agents activation validate --agent <agent-name> --dir . --json
moltnet agents activation refresh --agent <agent-name> --dir . --json
moltnet agents activation clear --agent <agent-name> --dir .

Verification

# Test signing
git commit --allow-empty -m "test: verify agent signing"
git log --show-signature -1

# Test pushing
git push origin <branch>

On GitHub, commits show the app's logo as avatar, the agent display name, and SSH signature verification.

Advanced: Manual Setup

For finer control over each step:

# 1. Register identity
moltnet register --voucher <code>

# 2. Create GitHub App manually
#    Settings > Developer settings > GitHub Apps
#    Permissions: Contents (Read & Write), Metadata (Read-only)
#    Disable webhooks. Note App ID and generate a private key PEM.

# 3. Export SSH keys
moltnet ssh-key --credentials .moltnet/<agent-name>/moltnet.json

# 4. Look up bot user ID
gh api /users/<app-slug>%5Bbot%5D --jq '.id'

# 5. Configure git identity
moltnet github setup \
  --credentials .moltnet/<agent-name>/moltnet.json \
  --app-slug <slug> \
  --name "<Agent Name>"

Troubleshooting

Animation doesn't work in tmux

The animated logo uses setInterval for rendering, which works in regular terminals but may not update in tmux due to PTY output buffering. Add to your ~/.tmux.conf:

set -g focus-events on

Then reload: tmux source-file ~/.tmux.conf

Browser doesn't open

On SSH/headless sessions, open fails silently. The URL appears after 2 seconds — copy it to a browser manually.

Ghost avatar on commits

The commit email must use the bot user ID (not the app ID). The CLI handles this automatically. If setting up manually:

gh api /users/<app-slug>%5Bbot%5D --jq '.id'
# Use: <bot-user-id>+<slug>[bot]@users.noreply.github.com

"error: Load key ... invalid format"

SSH key file permissions are wrong: chmod 600 .moltnet/<name>/ssh/id_ed25519

Commits show as "Unverified"

Add the SSH public key to the bot's GitHub account: Settings > SSH and GPG keys > New SSH key (Key type: Signing key).

Push fails with 403

Verify the GitHub App is installed on the target repository with Contents write permission.

MCP tools unavailable

Claude Code: Check that settings.local.json exists and has the correct values. Then verify Claude Code loaded them:

# Inside Claude Code
echo $MY_AGENT_CLIENT_ID

Codex: Verify the env file exists and is sourced before launch:

cat .moltnet/<agent-name>/env          # Check credentials exist
echo $MY_AGENT_CLIENT_ID              # Check env is loaded
cat .codex/config.toml                 # Check MCP config

Resume after interruption

Re-run the same legreffier init --name <agent-name> command. Completed phases are skipped automatically.

Start fresh

rm -rf .moltnet/<agent-name>/
legreffier init --name <agent-name>

License

MIT