Skip to main content

Contributing

Setup

Requires pnpm 10 — the repo pins pnpm@10.34.4 via the packageManager field, so corepack enable gets you the right version automatically. The repository is a pnpm workspace (root package + docs-site); one pnpm install at the root installs both.

git clone https://github.com/cdot65/prisma-airs-codex-hooks.git
cd prisma-airs-codex-hooks
pnpm install

Development Workflow

Source Changes

Edit TypeScript in src/. After changes:

pnpm build # compile to dist/ + bundle dist/hooks/*.mjs
pnpm test # run all tests
pnpm typecheck # type check

pnpm build runs tsc and then esbuild, producing self-contained minified bundles in dist/hooks/*.mjs — these are the artifacts the installer copies into .codex/hooks/.

Development Mode Hooks

For rapid iteration, point .codex/hooks.json at TypeScript source (no rebuild needed). Use absolute paths for both node and the tsx CLI — Codex runs hook commands with a system PATH, so nvm/asdf-managed node (and npx) are not resolvable and fail with exit 127:

{
"type": "command",
"command": "\"/absolute/path/to/node\" \"/path/to/repo/node_modules/tsx/dist/cli.mjs\" \"/path/to/repo/src/hooks/user-prompt-submit.ts\"",
"timeout": 30
}

Find your node binary with command -v node. This adds ~1.5s per invocation. Switch back to the bundles for production:

pnpm build
pnpm install-hooks --global
Re-trust after changes

Codex records hook trust against the definition's hash. After editing hooks.json (including switching between dev and production commands), open Codex and run /hooks to re-trust the changed definitions.

Running Tests

pnpm test # all tests once
pnpm test:watch # watch mode

Tests include:

  • Unit tests: config, scanner, code-extractor, circuit-breaker, DLP masking, logger, log rotation, tool-name parser, codex adapter, hooks-config
  • Integration tests: end-to-end hook execution via npx tsx, compiled node dist/, and standalone bundle runs with piped JSON

Pre-Commit Gate

Husky runs on every commit:

  1. lint-staged on staged files — prettier --write, secretlint (secrets scan), and eslint --fix for TypeScript/MJS
  2. pnpm typecheck across the repo

The same checks run in CI's lint job (pnpm lint, pnpm format:check, pnpm secrets). Run them manually anytime:

pnpm lint # eslint
pnpm format # prettier --write
pnpm format:check # prettier --check
pnpm secrets # secretlint

Adding a Test

Tests live in test/ and use vitest. Each module has a corresponding test file:

src/scanner.ts → test/scanner.test.ts
src/config.ts → test/config.test.ts

Working on the Docs

The Docusaurus site is the docs-site workspace package:

pnpm docs:serve # local dev server
pnpm --filter docs-site build # production build (same as pnpm docs:build)

Project Structure

src/ TypeScript source
hooks/ Hook entry points (stdin → scan → stdout)
adapters/ Codex stdout payload builders
dist/ Compiled JS + bundled .mjs hooks (git-ignored)
scripts/ CLI utilities (install, validate, stats, bundling)
test/ Vitest test suites
docs-site/ Docusaurus documentation

Pull Request Guidelines

  • Branch from main
  • Ensure pnpm test, pnpm typecheck, and pnpm lint pass (the pre-commit hook enforces lint/format/secrets/typecheck)
  • Include tests for new functionality
  • Run pnpm build to verify compilation and bundling

Publishing

Releases publish to npm automatically: creating a GitHub release triggers the publish workflow, which runs pnpm publish --provenance using npm OIDC trusted publishing (no tokens stored in the repo).