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

@super-repo/czar

v0.2.0

Published

Czar (aka commitizar / caesar) — Conventional Commits parser, formatter, validator, AI suggest, sanity checks, walk-through commits, and Ink components

Downloads

2,543

Readme

@super-repo/czar

Czar (aka commitizar / caesar) — Conventional Commits parser, formatter, validator, AI-suggest, sanity checks, walk-through commits, and Ink components for an interactive builder. The package ships three interchangeable bin names; pick the one your fingers prefer.

Why

When you commit the same change across N stack repos at once, you want one structured message that lands identically everywhere. Free-form text invites drift. This package gives you:

  • CLI (czar) — validate, build, push, walk subcommands. Single binary; works on its own without any other @super-repo/* package.
  • Data layer (format, parse, validate) — pure, no UI, no peer deps.
  • AI suggest — generates a Conventional Commits message from your staged diff via Anthropic or OpenAI; works on the whole staged set or per-file.
  • Sanity checks — block commits that include .env* files, large files, private keys, or strings that match common secret patterns.
  • Ink components (CommitForm, CommitPreview) — drop-in for any Ink-based TUI.

Install

pnpm add @super-repo/czar
# Components require ink + react + ink-text-input as peers (already in any Ink TUI).
pnpm add ink react ink-text-input

The package ships three interchangeable bin names — pick whichever reads best:

| Bin | Style | | ------------ | -------------------------------------- | | czar | short, the canonical name | | commitizar | full mnemonic, similar to commitizen | | caesar | because the czar historically was |

czar push        # ←
commitizar push  # all three resolve to the same CLI
caesar push      # ←

CLI

| Subcommand | What it does | | -------------- | ------------------------------------------------------------------------------------------------------------- | | czar validate| Validate a Conventional Commits message from a file or stdin. Drop-in for commit-msg hooks. (Default.) | | czar build | Launch the Ink form; print the formatted message to stdout on submit. | | czar push | Build (or accept) a message → stage → run sanity checks → commit → push. Includes shortcuts and AI suggest. | | czar walk | Iterate every changed file; commit each one individually. Combine with --ai for per-file generation. |

czar validate

czar .git/COMMIT_EDITMSG          # validate the prepared message file
echo "feat: tokens" | czar         # validate from stdin
czar --strict .git/COMMIT_EDITMSG  # treat warnings (long subject etc.) as errors

Exit codes: 0 valid, 1 invalid (or warning under --strict).

czar build

git commit -F <(czar build)        # build interactively, pipe to git
czar build --body                  # include body step in the form

The form renders to stderr so stdout stays clean for piping. Exits 130 on Esc.

czar push

Single-repo workflow: banner → status block → message resolution → sanity checks → stage → commit → push.

czar push                          # full interactive flow
czar push g                        # quick chore: shortcut → "chore: quick commit"
czar push "rotate session tokens"  # description provided, prompt for type/scope
czar push -m "fix(api): 404"       # fully non-interactive
czar push --ai                     # AI-suggest from staged diff, review in form
czar push --no-push -m "..."       # commit without pushing

The first screen of the interactive flow is a shortcut chooser:

g   quick chore         chore: quick commit
w   WIP                 chore: WIP
f   formatting          style: formatting
d   docs touch-up       docs: minor updates
…
a   AI suggest          generate message from staged diff       (when key available)
s   step (walk)         commit each changed file individually
c   group commit        compose one message for every staged change

Custom shortcuts are configurable via czar.config.ts (see Config).

czar walk

Walk through each changed file in turn — pick a per-file message, optionally letting the AI suggest one and previewing before commit. Useful for breaking up a big WIP working tree into clean per-file commits.

czar walk                          # interactive: type each message
czar walk --ai                     # AI suggests per file, you confirm/edit/skip
czar walk --ai --auto              # AI-only, no prompts (cleanup runs)
czar walk --no-push                # commit per-file but skip push at end

Per-file flow (AI mode):

[3/12] packages/cli/src/main.ts (modified)
  + new lines in green
  - removed in red
  ∴ ai  refactor(cli): extract argument parser
  [y] commit  [e] edit  [s] skip  [q] quit
  ›

q aborts mid-walk; commits already made are kept. After the loop, czar pushes unless --no-push.

You can also reach walk from the czar push first screen by pressing s.

Flags (push / walk)

| Flag | Where | Purpose | | ------------------- | ------------ | --------------------------------------------------------------------- | | -m, --message | push | Provide a complete conventional message; skips the form. | | --ai | push, walk | Generate via AI; requires ANTHROPIC_API_KEY or OPENAI_API_KEY. | | --auto | walk | Accept every AI suggestion without prompting (only with --ai). | | --body | push, build | Include a body step in the interactive form. | | --strict | all | Treat validation warnings as errors. | | --no-stage | push | Skip git add -A before committing. | | --no-push | push, walk | Commit only, do not push. | | --no-sanity | push | Skip pre-commit sanity checks. | | -c, --config | all | Path to czar.config.{ts,js,mjs,json}. |

Config

Optional czar.config.ts at the project root:

import { defineConfig } from '@super-repo/czar'

export default defineConfig({
  body: false,                      // include the body step by default
  strict: false,                    // treat warnings as errors

  // Quick-commit shortcuts shown on the first screen of `czar push`.
  shortcuts: [
    { key: 'g', label: 'quick chore', message: 'chore: quick commit' },
    { key: 'w', label: 'WIP',         message: 'chore: WIP' },
    { key: 'f', label: 'formatting',  message: 'style: formatting' },
  ],

  // Pre-commit safeguards.
  sanity: {
    enabled: true,
    maxFileSizeWarn: 1 * 1024 * 1024,
    maxFileSizeError: 5 * 1024 * 1024,
    blockEnvFiles: true,
    envFileAllowlist: ['.env.example', '.env.template', '.env.sample'],
    detectSecrets: true,
    blockPrivateKeys: true,
    skipPaths: ['pnpm-lock.yaml', 'package-lock.json', 'yarn.lock'],
  },

  // AI suggest defaults — see "Environment" below.
  ai: {
    enabled: true,
    provider: 'anthropic',
    model: 'claude-haiku-4-5-20251001',
    apiKeyEnv: 'ANTHROPIC_API_KEY',
    logLines: 20,
    maxDiffBytes: 16 * 1024,
  },
})

Override the lookup with -c <path>. Plain .json configs are also supported.

Config discovery

Czar resolves its config in this order:

  1. -c <path> if passed on the command line.
  2. czar.config.{ts,mjs,js,cjs,json} in the current working directory.
  3. The closest package.json walking up from cwd — read its czar field.

The package.json fallback accepts three shapes (matching super and rune):

// (a) Single config file
{ "czar": { "config": "./czar.config.ts" } }

// (b) Array of config files — loaded in order, merged left-to-right
{ "czar": { "config": ["./shared/base.config.ts", "./local/overrides.ts"] } }

// (c) Inline config (with optional `extends`, resolved relative to package.json)
{
  "czar": {
    "extends": "./shared/base.czar.ts",
    "shortcuts": [{ "key": "u", "label": "ui touch-up", "message": "style: ui" }]
  }
}

This makes a single package.json a one-stop config surface for super, czar, and rune blocks side by side.

Extending configs

Any czar config (file or package.json inline) can declare an extends field. Relative paths resolve against the config file's directory (or the package.json's directory for inline blocks). Pass a single path or an array; later overlays earlier.

import { defineConfig } from '@super-repo/czar'

export default defineConfig({
  extends: './shared/base.czar.ts',
  shortcuts: [
    { key: 'u', label: 'ui touch-up', message: 'style: ui touch-up' },
  ],
})

Merge semantics: shortcuts merge by key (overlay wins per-key, novel keys appended); sanity and ai shallow-merged; scalars (body, strict) last-defined wins. Circular extends chains throw CzarConfigError.

Sanity checks

Run after git add -A, before commit. Errors block; bypass with --no-sanity.

| Check | Trigger | Severity | | -------------- | --------------------------------------------------------------------------------------------- | -------- | | env-file | A staged file matches .env* and isn't on the allowlist. | error | | env-plaintext| In an env file: a KEY=VALUE line where the key looks secret-y (TOKEN/SECRET/PASSWORD/…) and the value is ≥ 12 chars and not an obvious placeholder. | error | | private-key | Filename matches id_rsa, *.pem, *.key, *.ppk, *.p12, etc. | error | | large-file | Staged file exceeds maxFileSizeError / maxFileSizeWarn. | error / warning | | secret | File content matches one of: AWS access/secret key, Anthropic / OpenAI / GitHub / Slack / Google / Stripe key, JWT, PEM block. | error in env files, warning otherwise |

skipPaths excludes lockfiles by default. Binary extensions (images, archives, executables) are not scanned for secret patterns.

Environment

czar push and czar walk automatically load .env and .env.local from cwd at startup, without overriding values already set in the shell. So ANTHROPIC_API_KEY (or OPENAI_API_KEY) defined in your project's .env is enough — no manual source needed.

When the key is detected, the status block shows:

ai mode   true · anthropic claude-haiku-4-5-20251001

Pass --ai to make AI generate the message by default; without the flag, AI is offered as the a shortcut on the first screen.

Use from package.json (commit-msg hook)

{
  "scripts": { "validate-commit": "czar" },
  "simple-git-hooks": { "commit-msg": "czar $1" },
  "devDependencies": {
    "@super-repo/czar": "^0.0.6",
    "simple-git-hooks": "^2.11.0"
  }
}

Husky:

# .husky/commit-msg
npx czar "$1"

Lefthook:

commit-msg:
  commands:
    czar:
      run: npx czar {1}

Data layer

import {
  formatCommitMessage,
  parseCommitMessage,
  validateCommitMessage,
} from '@super-repo/czar'

formatCommitMessage({ type: 'feat', scope: 'auth', description: 'rotate tokens', breaking: true })
// → "feat(auth)!: rotate tokens"

parseCommitMessage('fix(api): handle 404')
// → { message: { type: 'fix', scope: 'api', description: 'handle 404' }, errors: [] }

validateCommitMessage({ type: 'feat', description: 'a long description'.repeat(20) })
// → { valid: false, issues: [{ severity: 'error', field: 'description', ... }] }

Components

<CommitForm />

Multi-step builder: shortcuts → type → scope → description → breaking → review.

import { render } from 'ink'
import { CommitForm } from '@super-repo/czar'

render(
  <CommitForm
    aiAvailable
    walkAvailable
    onAiRequest={() => /* unmount + run AI suggest */}
    onWalkRequest={() => /* unmount + run walk */}
    onSubmit={(msg) => console.log(formatCommitMessage(msg))}
    onCancel={() => process.exit(0)}
  />
)

| Prop | Type | Default | Purpose | | ---------------- | --------------------------------- | ------- | ------------------------------------------------------ | | initial | Partial<CommitMessage> | {} | Pre-fill any field. With type + description set, jumps straight to review. | | showBodyStep | boolean | false | Add a single-line body step before review. | | shortcuts | ShortcutConfig[] | builtin | Custom quick-commit shortcuts (key/label/message). | | aiAvailable | boolean | false | Render the a AI shortcut on the first screen. | | walkAvailable | boolean | false | Render the s walk shortcut on the first screen. | | onAiRequest | () => void | — | Called when the user picks a. | | onWalkRequest | () => void | — | Called when the user picks s. | | onSubmit | (message: CommitMessage) => void| — | Called with the assembled message on confirm. | | onCancel | () => void | — | Called when the user presses Esc. |

<CommitPreview />

Renders a CommitMessage with live validation issues underneath.

<CommitPreview message={{ type: 'feat', description: 'add login' }} />

Validation rules

| Rule | Severity | | ----------------------------------------------------------------------------------------------------- | -------- | | Type must be one of: feat/fix/docs/style/refactor/perf/test/chore/build/ci/revert. | error | | Description required and non-empty. | error | | Description ≤ 100 characters. | error | | Description ≤ 72 characters (recommended). | warning | | Description should not end with a period. | warning | | Description should not have leading/trailing whitespace. | warning | | Scope, when provided, must be non-empty and free of ( ) ! : and whitespace. | error |

Format reference

<type>[(<scope>)][!]: <description>

[<body>]

[<footer-key>: <footer-value>]
[<footer-key>: <footer-value>]
  • The ! after type/scope marks a breaking change. Equivalent to a BREAKING CHANGE: … footer.
  • Body and footers are separated by blank lines.
  • Footer keys match [A-Za-z0-9-]+ (or the literal BREAKING CHANGE / BREAKING-CHANGE).

See conventionalcommits.org for the full spec.