Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cad0p/pi-steering-hooks/llms.txt

Use this file to discover all available pages before exploring further.

pi-steering-commit-format gates git commit -m commands against commit-message format checkers. It ships as a sibling of pi-steering — opt-in functionality that doesn’t belong in the core engine — and mirrors the pi-steering-flags precedent for external plugin packaging. The package parses commit message strings; it does not walk bash ASTs and carries no unbash / unbash-walker dependency.

Bundled formats

  • "conventional" — Conventional Commits 1.0.0, restricted to the Angular preset’s 11-token type allowlist: feat, fix, docs, style, refactor, perf, test, chore, ci, build, revert. Headers like feat: add login, fix(scope): resolve crash, and refactor!: drop deprecated API all pass. Types outside the Angular set (release:, merge:, etc.) are rejected even if they are otherwise 1.0.0-conformant.
  • "jira" — at least one bracketed JIRA-style ticket reference in the message body ([ABC-123], [PROJ-1234], etc.).
Both formats can be required individually or combined (AND semantics) in a single rule.

Install

pnpm add pi-steering-commit-format

Quickstart

// .pi/steering/index.ts
import { defineConfig } from "pi-steering";
import commitFormatPlugin from "pi-steering-commit-format";

export default defineConfig({
  plugins: [commitFormatPlugin],
  rules: [
    {
      name: "require-conventional-commit",
      tool: "bash",
      field: "command",
      pattern: /^git\s+commit\b/,
      when: { commitFormat: { require: ["conventional"] } },
      reason:
        "Commit messages must follow Conventional Commits 1.0.0 with the Angular preset's type allowlist (feat: ..., fix(scope): ..., etc.).",
    },
    {
      name: "require-jira-and-conventional",
      tool: "bash",
      field: "command",
      pattern: /^git\s+commit\b/,
      when: { commitFormat: { require: ["conventional", "jira"] } },
      reason:
        "Commit messages must follow Conventional Commits 1.0.0 with the Angular preset's type allowlist AND include a bracketed JIRA reference (e.g. [ABC-123]).",
    },
  ],
});

when.commitFormat

The rule fires (commit is blocked) when the commit message fails any of the required format checks.
commitFormat: {
  require: readonly FormatName[];   // AND across all listed formats
}
The predicate inspects ctx.input.command, extracts the -m <msg> value via the internal extractCommitMessage helper, and runs every checker in require. All listed checkers must pass — if any fails the rule fires. Empty require: [] is a no-op (nothing required, nothing fires).
Commands without a -m flag — bare git commit, which opens an editor — are NOT validated by this predicate. The editor flow requires a separate hook outside pi-steering’s current scope.

Custom formats with commitFormatFactory

Use commitFormatFactory to build a predicate that AND-gates the built-in checkers with your own format checker. Pass an object whose keys are format names and whose values are (msg: string) => boolean checker functions.
import {
  BUILTIN_FORMATS,
  commitFormatFactory,
} from "pi-steering-commit-format";
import type { Plugin, PredicateShape } from "pi-steering";

const myCommitFormat = commitFormatFactory({
  ...BUILTIN_FORMATS,
  custom: (msg) => /^\[CUSTOM\]/.test(msg),
});

// Register the predicate name on PiSteeringPredicates so consumers
// get the same compile-time autocomplete + JSDoc on hover the default
// `commitFormat` predicate provides. Without this `declare global`
// block, an unregistered predicate name is rejected at the type
// level inside a rule's `when:` slot.
declare global {
  interface PiSteeringPredicates {
    /** `when.myCommitFormat` — conventional + jira + custom. */
    myCommitFormat: PredicateShape<
      Parameters<typeof myCommitFormat>[0]
    >;
  }
}

export const myPlugin = {
  name: "my-org",
  predicates: { myCommitFormat },
} as const satisfies Plugin;
The factory’s require argument is type-narrowed to keyof F, so TypeScript flags typos at the rule’s when: slot. Calling with an unknown format name via a JS bypass or as any fails closed — the predicate fires. BUILTIN_FORMATS is the registry of available checkers. It is not a default-required set — callers always pick which formats to AND together via require:. Spreading BUILTIN_FORMATS into the factory makes those format names available alongside your custom checker; omitting it produces a predicate that only knows your custom formats.

Build docs developers (and LLMs) love