Install Claude Code hooks for automatic formatting, linting, and context monitoring. Use when setting up a project, after "install hooks", "set up hooks", "add auto-formatting", or when starting a new project that uses Biome.
Installs and manages automated code formatting, linting, and safety hooks for Claude Code projects.
/plugin marketplace add howells/arc/plugin install arc@howellsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
<tool_restrictions>
EnterPlanMode — BANNED. Do NOT call this tool. This skill has its own structured process. Execute the steps below directly.ExitPlanMode — BANNED. You are never in plan mode.
</tool_restrictions>If the user passed --remove:
.claude/settings.jsongrep -q '"@biomejs/biome"' package.json 2>/dev/null
If Biome is in package.json: Continue to Step 2.
If Biome is NOT found:
Biome not found in package.json.
Arc hooks require Biome for auto-formatting and linting.
1. Install Biome and continue
2. Skip formatting hooks, install context monitor only
3. Cancel
If user picks 1:
# Detect package manager from lockfile
if [ -f pnpm-lock.yaml ]; then
pnpm add -D @biomejs/biome
elif [ -f yarn.lock ]; then
yarn add -D @biomejs/biome
else
npm install -D @biomejs/biome
fi
Then check for biome.json / biome.jsonc. If missing:
npx @biomejs/biome init
If user picks 2: Set SKIP_BIOME=true, continue to Step 3.
./node_modules/.bin/biome --version
If this fails, the binary isn't available. Tell the user and offer to reinstall.
Also check for biome config:
ls biome.json biome.jsonc 2>/dev/null
If no config exists, note this — biome will use defaults, which is fine.
Build the hooks object to merge into .claude/settings.json.
Biome format hook (PostToolUse, Edit|Write):
{
"matcher": "Edit|Write|NotebookEdit",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path // .tool_input.filePath // empty' | { read file_path; case \"$file_path\" in *.js|*.ts|*.jsx|*.tsx|*.json|*.jsonc|*.css|*.graphql) ./node_modules/.bin/biome format --write \"$file_path\" 2>/dev/null || true ;; esac; }"
}
]
}
Biome lint hook (Stop):
{
"hooks": [
{
"type": "command",
"command": "git diff --name-only --diff-filter=d HEAD 2>/dev/null | grep -E '\\.(js|ts|jsx|tsx|json|jsonc|css|graphql)$' | xargs -r ./node_modules/.bin/biome check --fix --unsafe 2>/dev/null || true"
}
]
}
TypeScript check hook (Stop):
Only include this if the project has TypeScript (tsconfig.json exists).
{
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | tail -20 || true"
}
]
}
Git guard hook (PreToolUse, Bash):
This hook blocks destructive git operations before they execute. Always install — not dependent on Biome.
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.command' | grep -qE 'git\\s+(reset\\s+--hard|push\\s+(-f|--force)|clean\\s+-f|checkout\\s+\\.)' && echo '{\"decision\":\"block\",\"reason\":\"Destructive git operation blocked by Arc hooks. Ask the user first.\"}' || true"
}
]
}
Context monitor hook (PostToolUse, all tools):
Determine the path to the Arc plugin's hooks directory. Use ${CLAUDE_PLUGIN_ROOT}/hooks/ — this resolves to wherever Arc is installed.
Read ${CLAUDE_PLUGIN_ROOT}/hooks/arc-context-monitor.js to confirm it exists.
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "node ${ARC_HOOKS_PATH}/arc-context-monitor.js"
}
]
}
Where ${ARC_HOOKS_PATH} is the resolved absolute path to the Arc plugin's hooks/ directory.
Statusline hook:
{
"type": "command",
"command": "node ${ARC_HOOKS_PATH}/arc-statusline.js"
}
If SKIP_BIOME is true: Only include the git guard, context monitor, and statusline hooks. The tsc hook is independent of Biome — include it if tsconfig.json exists.
cat .claude/settings.json 2>/dev/null
If file doesn't exist:
mkdir -p .claude
Start with an empty object {}.
If file exists: Parse the JSON. Preserve ALL existing fields (permissions, enabledMcpjsonServers, enableAllProjectMcpServers, enabledPlugins, etc.).
This is the critical step. NEVER clobber existing hooks — merge with them.
Read the existing hooks object (may be undefined).
For PreToolUse:
hooks.PreToolUse array (or empty array)git.*reset.*--hard)For PostToolUse:
hooks.PostToolUse array (or empty array)biome format)arc-context-monitor)For Stop:
hooks.Stop array (or empty array)biome check)tsc --noEmit)tsconfig.json in the project, skip the tsc hookFor Statusline:
hooks.Statusline array (or empty array)arc-statusline)Write the merged settings back: Use the Write tool to write the complete JSON (pretty-printed with 2-space indent).
CRITICAL: Preserve all non-hook fields exactly as they were. Do not add, remove, or modify anything outside the hooks key.
Read back .claude/settings.json and confirm the hooks are present.
Count installed hooks:
Arc hooks installed in .claude/settings.json
PreToolUse (Bash) → blocks destructive git ops (force push, reset --hard)
PostToolUse (Edit|Write) → biome format --write on edited file
PostToolUse (all tools) → context monitor (warns at 35%/25% remaining)
Stop → biome check --fix --unsafe on all changed files
Stop → tsc --noEmit (if tsconfig.json exists)
Statusline → context bar showing usage
Hooks run automatically — zero token cost, zero agent effort.
To remove: /arc:hooks --remove
If SKIP_BIOME was true:
Arc hooks installed in .claude/settings.json
PreToolUse (Bash) → blocks destructive git ops (force push, reset --hard)
PostToolUse (all tools) → context monitor (warns at 35%/25% remaining)
Statusline → context bar showing usage
Biome hooks skipped (not installed). Run /arc:hooks again after adding Biome.
To remove: /arc:hooks --remove
</process>
<notes>
- The biome format hook uses `jq` to extract the file path from the tool input. This is standard on macOS (via Homebrew) and most Linux distros. If jq is missing, the hook silently fails (|| true).
- The Stop hook uses `xargs -r` which is a no-op if there are no files. On macOS, `xargs` without `-r` still works (just runs biome with no args, which exits cleanly).
- The context monitor hooks reference files inside the Arc plugin. If the user uninstalls Arc, these hooks will silently fail (node script not found → exit 1, but hooks don't block).
- `--unsafe` in the Stop hook enables Biome's unsafe fixes (like removing unused imports). This is intentional — at conversation end, we want maximum cleanup.
- The PostToolUse format hook handles both `file_path` (Edit tool) and `filePath` (NotebookEdit) via jq fallback.
- The tsc hook uses `tail -20` to avoid flooding the stop output — just enough to see if there are errors and what they are.
- The git guard uses PreToolUse with `decision: block` to stop destructive commands before execution. This is especially important for users running with `--dangerously-skip-permissions` or liberal auto-approve settings.
- The git guard blocks: `git reset --hard`, `git push --force` / `git push -f`, `git clean -f`, `git checkout .`. These are the operations that destroy uncommitted work with no undo.
</notes>Activates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.
Search, retrieve, and install Agent Skills from the prompts.chat registry using MCP tools. Use when the user asks to find skills, browse skill catalogs, install a skill for Claude, or extend Claude's capabilities with reusable AI agent components.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.