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

@gonk/extension-spec-codex

v0.4.0

Published

Codex materializer for @gonk/extension-spec — turns an ExtensionSpec into a Codex plugin tree (plugin.json, skills, hooks, .mcp.json).

Readme

@gonk/extension-spec-codex

Codex materializer for @gonk/extension-spec. It translates an ExtensionSpec into a Codex plugin tree on disk: .codex-plugin/plugin.json, optional .mcp.json, skills/*/SKILL.md, optional hooks/hooks.json, and .gonk-materialize.json.

How Codex loads a gonk plugin

Codex discovers installed plugins from versioned plugin cache trees under ~/.codex/plugins/cache/**/.codex-plugin/plugin.json. materializeCodexPlugin writes the same contract into any plugin root you choose. Re-running is idempotent, and obsolete files from a prior run are swept according to the .gonk-materialize.json sidecar.

import { materializeCodexPlugin } from "@gonk/extension-spec-codex";

const manifest = materializeCodexPlugin({
  spec,
  outDir: "~/.codex/plugins/cache/gonk/codex-memory/0.0.0",
  packageName: "@gonk/codex-memory",
  version: "1.2.3",
  mcpServerEntry: {
    command: "node",
    args: ["./dist/mcp-server.js"],
    cwd: ".",
  },
});

What gets written

| Path | Purpose | |---|---| | .codex-plugin/plugin.json | Plugin manifest and interface metadata | | .mcp.json | MCP server entry, when mcpServerEntry is set | | skills/<name>/SKILL.md | Codex skill guidance derived from the spec command or explicit skills | | hooks/hooks.json | Cache-safe lifecycle dispatch for recognized spec.hooks entries | | hooks/gonk-codex-hook.mjs | Plugin-local dispatcher referenced through PLUGIN_ROOT | | .gonk-materialize.json | Sidecar tracking the write set for sweep on next run |

MCP server convention

Existing gonk Codex packages use ESM MCP servers launched by Node: node ./dist/mcp-server.js with cwd: ".". Server keys default to gonk-<spec.id> so Codex server identity stays distinct from Claude's bare capability keys.

Hook convention and cache epochs

When spec.hooks contains recognized portable events, the materializer writes hooks/hooks.json, emits a plugin-local dispatcher, and points the plugin manifest at the hook file. Consumers that use hook dispatch must first bundle their spec as dist/hook-spec.cjs, exporting the ExtensionSpec (or a zero-argument factory) as the default export. Materialization fails rather than activating hooks when that artifact is absent. Codex supplies the plugin root through PLUGIN_ROOT, and generated commands resolve the dispatcher only through that anchored path.

The default mapping is deliberately narrow:

| Portable event | Codex event | Context contract | |---|---|---| | session_start | SessionStart (startup\|resume\|clear\|compact) | May emit a deterministic instruction floor, capped at 16,384 characters | | before_provider_request | UserPromptSubmit | Side effects only; runtime output is always {} | | turn_complete | Stop | Side effects only; runtime output is always {} |

Codex reports post-compaction reinjection as SessionStart with source: "compact"; PostCompact itself does not support additional developer context. The runtime therefore grants injectContext() only when both the portable event is session_start and the host payload proves a real SessionStart boundary with a valid source. Every non-boundary event receives a side-effect-only context and is hard-clamped to empty JSON, even where Codex itself supports dynamic additionalContext. That keeps the cached prompt prefix byte-stable inside an epoch. Query-dependent memory, knowledge, persona, and self-model context remains pull-based through tools and skills.

Spec-owned stdout is suppressed for every event, covering module evaluation, factory resolution, and handler execution: console.log, console.info, console.debug, and direct process.stdout.write calls cannot corrupt Codex's JSON hook protocol. Stderr remains available for diagnostics.

Plugin hooks retain Codex's normal hash-based trust review; installation or enablement alone does not trust a generated command hook.