Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 21 additions & 14 deletions .claude/hooks/post-edit.sh
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
#!/bin/bash
# Post-edit hook: auto-fix markdown files after edits
#!/usr/bin/env bash
# Post-edit hook: auto-fix files after edits
set -euo pipefail

if ! command -v jq >/dev/null 2>&1; then
exit 0
fi

INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null) || FILE_PATH=""
FILE="${TOOL_INPUT_FILE_PATH:-}"

if [[ -z "$FILE_PATH" || ! -f "$FILE_PATH" ]]; then
exit 0
if [ "$FILE" = "" ]; then
# No input file provided; nothing to do.
exit 0
fi

# Auto-fix markdown with markdownlint
if [[ "$FILE_PATH" =~ \.md$ ]]; then
npx markdownlint --fix "$FILE_PATH" 2>/dev/null || true
fi
case "$FILE" in
*.sh)
if command -v shellharden > /dev/null 2>&1; then
shellharden --replace "$FILE" 2>/dev/null || true
fi
if [ -f "$FILE" ] && head -1 "$FILE" | grep -q '^#!'; then
chmod +x "$FILE" 2>/dev/null || true
fi
;;
*.md)
if command -v markdownlint > /dev/null 2>&1; then
markdownlint --fix "$FILE" 2>/dev/null || true
fi
;;
esac
14 changes: 14 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ repos:
language: system
pass_filenames: false

# Shell scripts
- repo: local
hooks:
- id: shellcheck
name: shellcheck
entry: shellcheck --severity=warning
language: system
types: [shell]
- id: shellharden
name: shellharden
entry: shellharden --check
language: system
types: [shell]

- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.47.0
hooks:
Expand Down
6 changes: 3 additions & 3 deletions .yamllint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ extends: default

rules:
line-length:
max: 200
max: 120
level: warning
document-start: disable
truthy:
allowed-values: ['true', 'false', 'on', 'off']
check-keys: false
comments:
min-spaces-from-content: 1
indentation:
spaces: 2
indent-sequences: true
indent-sequences: consistent

ignore: |
node_modules/
Expand Down
14 changes: 12 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,17 @@ All hooks must pass before committing. Install with `pre-commit install`.
- **Secrets**: detect-secrets (with `.secrets.baseline`), gitleaks.
- **Markdown**: markdownlint with `--fix`.
- **Prose**: Vale with write-good (passive voice, weasel words) and proselint (grammar, usage).
- **Shell**: shellcheck (severity: warning), shellharden.
- **GitHub Actions**: actionlint, zizmor (security analysis).
- **Commits**: conventional-pre-commit (commit-msg stage).

## Claude Code Hooks

Hooks in `.claude/settings.json` automate deterministic actions:

- **Post-edit** (`post-edit.sh`): Auto-runs `markdownlint --fix` on `.md` files
after every Edit/Write.
- **Post-edit** (`post-edit.sh`): Runs `shellharden --replace` on `.sh` files
and `markdownlint --fix` on `.md` files after every Edit/Write (when the tools
are installed).

## Claude Code Skills

Expand All @@ -110,6 +112,14 @@ Skills in `.claude/skills/` provide reusable workflows:
- Markdownlint config: MD013 line length at 120 characters, tables exempt.
That is the ONLY customization in `.markdownlint.yaml`.

## Shell Scripts

- Must pass shellcheck (severity: warning) and shellharden.
- Quote all variables. Prefer `"$VAR"` over `"${VAR}"` — only use braces when needed
(e.g., `"${VAR}_suffix"`).
- Use arrays for word splitting.
- Scripts must have shebangs and executable permissions.

## Python Scripts

- Follow PEP 8 style guidelines.
Expand Down
Loading