From claude-initial-setup
Patterns for auto-format on save, auto-lint, auto-test on file change, and CI triggers within Claude Code. Use when the user wants automated reactions to file changes, wants to set up continuous feedback loops, or asks about triggering actions automatically.
npx claudepluginhub versoxbt/claude-initial-setup --plugin claude-initial-setupThis skill uses the workspace's default tool permissions.
Automation triggers create feedback loops that run formatting, linting, testing, or CI actions in response to file changes. They reduce manual intervention and catch issues immediately.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Automation triggers create feedback loops that run formatting, linting, testing, or CI actions in response to file changes. They reduce manual intervention and catch issues immediately.
Use a PostToolUse hook to format files immediately after modification:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(js|ts|jsx|tsx|css|json)$'; then npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null; fi",
"description": "Auto-format JS/TS/CSS/JSON files with Prettier"
}
]
}
}
For Python projects, use Black or Ruff:
{
"matcher": "Edit|Write",
"command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.py$'; then ruff format \"$CLAUDE_FILE_PATH\" 2>/dev/null && ruff check --fix \"$CLAUDE_FILE_PATH\" 2>/dev/null; fi",
"description": "Auto-format and fix Python files with Ruff"
}
For Go projects:
{
"matcher": "Edit|Write",
"command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.go$'; then gofmt -w \"$CLAUDE_FILE_PATH\" && goimports -w \"$CLAUDE_FILE_PATH\" 2>/dev/null; fi",
"description": "Auto-format Go files with gofmt and goimports"
}
Run linters as PostToolUse hooks to surface issues immediately:
{
"matcher": "Edit|Write",
"command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(ts|tsx)$'; then npx eslint --no-warn-ignored \"$CLAUDE_FILE_PATH\" 2>&1 | head -30; fi",
"description": "Auto-lint TypeScript files with ESLint"
}
For TypeScript, run incremental type-checking after edits:
{
"matcher": "Edit|Write",
"command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.tsx?$'; then npx tsc --noEmit --pretty 2>&1 | tail -20; fi",
"description": "Type-check TypeScript after edit"
}
Run related tests when source files change. Keep the test scope narrow for speed:
{
"matcher": "Edit|Write",
"command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(ts|tsx)$'; then TEST_FILE=$(echo \"$CLAUDE_FILE_PATH\" | sed 's/\\.ts/.test.ts/' | sed 's/\\.tsx/.test.tsx/'); if [ -f \"$TEST_FILE\" ]; then npx vitest run \"$TEST_FILE\" --reporter=verbose 2>&1 | tail -30; fi; fi",
"description": "Run matching test file when source is edited"
}
For pytest:
{
"matcher": "Edit|Write",
"command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.py$'; then TEST_FILE=$(echo \"$CLAUDE_FILE_PATH\" | sed 's|/\\([^/]*\\)\\.py$|/test_\\1.py|'); if [ -f \"$TEST_FILE\" ]; then python -m pytest \"$TEST_FILE\" -x --tb=short 2>&1 | tail -20; fi; fi",
"description": "Run matching pytest file when Python source is edited"
}
Use Stop hooks or git push PreToolUse hooks to integrate with CI:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'git push'; then echo 'Reminder: CI will run on push. Ensure tests pass locally first.'; fi",
"description": "Remind about CI before git push"
}
]
}
}
Combine format + lint + type-check in a single hook with early exit on failure:
{
"matcher": "Edit|Write",
"command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.tsx?$'; then npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null && npx eslint --fix \"$CLAUDE_FILE_PATH\" 2>/dev/null && npx tsc --noEmit --pretty 2>&1 | tail -10; fi",
"description": "Format, lint, and type-check TypeScript files"
}
$CLAUDE_FILE_PATH only. Never run prettier --write . in a hook — it reformats the entire project on every edit.&&, a failure in formatting stops linting. Use ; instead of && if you want all steps to run regardless.head or tail to limit output and prevent flooding the agent context.| Trigger | Tool Matcher | When | Speed Target |
|---|---|---|---|
| Format | Edit|Write | PostToolUse | < 1s |
| Lint | Edit|Write | PostToolUse | < 3s |
| Type-check | Edit|Write | PostToolUse | < 5s |
| Test (single) | Edit|Write | PostToolUse | < 10s |
| CI reminder | Bash (git push) | PreToolUse | instant |
Rule of thumb: If a hook takes > 5 seconds, it should be opt-in, not automatic. Scope narrowly: Always filter by file extension and limit output.