Skip to main content

Git Hooks

mekara uses pre-commit so expensive checks run automatically before each commit. Install them once per clone:

pre-commit install

Each hook runs only when its files change:

HookTriggerPurpose
Ruff FormatAny change to Python sources under src/Keeps formatting consistent before code reaches reviewers.
Ruff LintSame trigger as Ruff FormatEnforces lint cleanliness so warnings never reach main.
Pyright Type CheckSame trigger as Ruff FormatRuns strict static type checks so regressions are caught before runtime.
Forbid type workaroundsSame trigger as Ruff FormatBlocks type: ignore suppressions and if TYPE_CHECKING: blocks so typing issues get fixed properly.
Prettier FormatAny change to formattable files in docs/Keeps documentation formatting consistent (JavaScript, TypeScript, JSON, Markdown, YAML, CSS, HTML).
ESLint LintAny change to JavaScript/TypeScript files in docs/Enforces linting standards for documentation code.
TypeScript Type CheckAny change to TypeScript files in docs/Runs type checking on documentation TypeScript code (skips library checks for speed).
Build DocumentationAny change inside docs/Builds the Docusaurus site to catch broken links, broken anchors, or other regressions early.
Sync Bundled StandardsAny change to docs/docs/standards/*.mdSyncs standards from docs to src/mekara/bundled/standards/, stripping Docusaurus frontmatter and imports.
Check Bundled ScriptsAny change to .mekara/scripts/nl/, docs/wiki/, or src/mekara/bundled/scripts/Syncs between .mekara/scripts/nl/ and docs/wiki/. Validates bundled NL/compiled pairs. Alerts on potential sync needs.
Wiki sidebar labelAny change to docs/wiki/**/*.md filesValidates that all non-index wiki files have a sidebar_label field in their frontmatter.
  • Each Python hook runs through poetry run ..., so make sure poetry install --with dev has completed before committing.
  • Each docs hook runs through pnpm in the docs/ directory, so make sure pnpm install has completed before committing.
  • Hooks stop the commit if a command fails. Fix the issue locally, re-stage files, and the hook will re-run automatically on the next git commit.

Check Bundled Scripts

The "Check Bundled Scripts" hook manages script syncing and validation:

Script Syncing

Syncs between three locations:

  • docs/wiki/ — Generic scripts for any mekara project (Prettier-formatted, with frontmatter). Only scripts that apply to all projects belong here — do not add project-specific scripts (e.g., mekara-internal development scripts).
  • src/mekara/bundled/scripts/nl/ — Bundled generic scripts (including test scripts)
  • .mekara/scripts/nl/ — This repo's scripts, which may include project-specific scripts that don't exist in wiki/bundled, as well as customized overrides of generic scripts

In general, the hook will sync changes from any one of the three sources to the other two sources, unless the sources are already verbatim copies of each other apart from the edge cases noted below. If there are conflicting staged changes, the hook will exit with an error asking for manual adjustments.

The only exception to the above are the scripts in .mekara/scripts/nl/ that are intentionally more specific than the generic bundled/wiki version (e.g., project/release.md has mekara-specific PyPI steps). These are also the individual scripts that are mentioned in Bundled Script Generalization. If a script is mentioned in that file, that script is treated as customized and is excluded from bidirectional sync between the bundled and project-specific scripts. However, a sync between wiki and bundled versions remain.

Normally this script acts only on changed files, but the --all option als exists to sync all scripts regardless of what's staged, allowing drift to be fixed.

Important edge cases:

  1. Frontmatter blank line handling: Wiki files require a blank line after frontmatter (Prettier requirement). When syncing from wiki to .mekara/scripts/nl/, the sync script strips this blank line so .mekara files don't have a leading blank line. When syncing from .mekara to wiki, it adds the blank line back.

  2. Prettier formatting: The .mekara/scripts/nl/ and src/mekara/bundled/scripts/nl/ files contain Prettier-formatted Markdown (blank lines before lists, consistent emphasis markers, etc.). This formatting is inherited from docs/wiki/ during sync. Do not "simplify" these files by removing blank lines—they must match the wiki formatting to avoid sync conflicts.

  3. Atomic sync: When syncing in one direction, the hook stages all three locations (wiki, mekara, and bundled) in a single pass. This prevents needing multiple commit attempts to propagate changes through all three locations.

  4. Category exclusions: Some categories are excluded from sync to specific destinations. mekara/ (mekara development tools) is excluded from both wiki and bundled. test/ (test fixtures) is excluded from wiki but stays in bundled so users can verify their mekara installation works. Top-level scripts (no category subdirectory, e.g., waterfall.md, change.md) are excluded from wiki but synced to bundled. These exclusions are hardcoded in sync_nl.py.

Bundled Script Validation

Bundled scripts in src/mekara/bundled/scripts/ are edited independently (no automatic sync). The hook:

  1. Validates generalized NL/compiled pairs — if a bundled NL script listed in bundled-script-generalization.md changes and a corresponding bundled compiled file exists, that compiled file must also change in the same commit

  2. Validates non-generalized compiled equality — if both .mekara/scripts/compiled/ and src/mekara/bundled/scripts/compiled/ contain a script that is not listed in bundled-script-generalization.md, those two compiled files must be exactly identical

  3. Alerts on potential sync needs — warns when .mekara/scripts/nl/ or bundled scripts change without corresponding changes in the other location, prompting you to check if synced updates are needed

    When the hook requires a generated or compiled file update, the agent should be informed that the file update should reflect the real source change. The agent should not add filler comments or docstrings just to force a diff.

Generalized scripts are excluded from sync

Scripts listed in docs/docs/code-base/mekara/bundled-script-generalization.md (e.g., project:release.md) have intentional divergence between .mekara/scripts/nl/ (project-specific) and wiki/bundled (generic). The sync script reads that doc at runtime and excludes those scripts in both directions.

Writing custom hook scripts

When writing shell scripts for pre-commit hooks, be careful with error handling. A common pitfall is using patterns that silently pass when the underlying tool isn't available:

# BROKEN: silently passes if grep isn't found
matches=$(grep "pattern" "$file" || true)

# BROKEN: also silently passes - conditionals suppress set -e
if matches=$(grep "pattern" "$file"); then
echo "found"
fi

Both patterns fail silently because:

  1. || true swallows all errors, including "command not found"
  2. set -e doesn't apply inside conditionals, so a missing command returns empty output and the script continues

The fix is to verify the tool exists upfront and explicitly check exit codes:

# Verify tool exists before using it
command -v grep >/dev/null 2>&1 || { echo "Error: grep not found" >&2; exit 1; }

# Explicitly capture and check exit codes
# grep returns: 0 = found, 1 = not found, >1 = error
matches=""
grep_exit=0
matches=$(grep "pattern" "$file") || grep_exit=$?
if [ "$grep_exit" -gt 1 ]; then
echo "Error: grep failed" >&2
exit 1
elif [ "$grep_exit" -eq 0 ]; then
echo "Found: $matches"
fi