- Created skills/ directory - Moved 272 skills to skills/ subfolder - Kept agents/ at root level - Kept installation scripts and docs at root level Repository structure: - skills/ - All 272 skills from skills.sh - agents/ - Agent definitions - *.sh, *.ps1 - Installation scripts - README.md, etc. - Documentation Co-Authored-By: Claude <noreply@anthropic.com>
4.5 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
A Claude Code and OpenCode plugin that blocks destructive git and filesystem commands before execution. It works as a PreToolUse hook that intercepts Bash commands and denies dangerous operations like git reset --hard, rm -rf, and git checkout -- <files>.
Commands
- Setup:
bun install - All checks:
bun run check(runs lint, typecheck, knip, ast-grep scan, tests) - Single test:
bun test tests/file.test.ts - Lint:
bun run lint(uses Biome) - Type check:
bun run typecheck - Dead code:
bun run knip - AST scan:
bun run sg:scan - Build:
bun run build
Architecture
The hook receives JSON input on stdin containing tool_name and tool_input. For Bash tools, it analyzes the command and outputs JSON with permissionDecision: "deny" to block dangerous operations.
Entry points:
src/bin/cc-safety-net.ts— Claude Code CLI (reads stdin JSON)src/index.ts— OpenCode plugin export
Core analysis flow:
cc-safety-net.ts:main()parses JSON input, extracts commandanalyze.ts:analyzeCommand()splits command on shell operators (;,&&,|, etc.)analyzeSegment()tokenizes each segment, strips wrappers (sudo, env), identifies the command- Dispatches to
rules-git.ts:analyzeGit()orrules-rm.ts:analyzeRm()based on command - Checks custom rules via
rules-custom.ts:checkCustomRules()if configured
Key modules (src/core/):
shell.ts: Shell parsing (splitShellCommands,shlexSplit,stripWrappers,shortOpts)rules-git.ts: Git subcommand analysis (checkout, restore, reset, clean, push, branch, stash)rules-rm.ts: rm analysis (allows rm -rf within cwd except when cwd is $HOME; temp paths always allowed; strict mode blocks non-temp)config.ts: Config loading, validation, merging (user~/.cc-safety-net/config.json+ project.safety-net.json)rules-custom.ts: Custom rule matching (checkCustomRules())audit.ts: Audit logging for blocked commandsverify-config.ts: Config validator
Test utilities (tests/helpers.ts):
assertBlocked(),assertAllowed()helpers for testing command analysis
Advanced detection:
- Recursively analyzes shell wrappers (
bash -c '...') up to 5 levels deep - Detects destructive commands in interpreter one-liners (
python -c,node -e,ruby -e,perl -e) - Handles
xargsandparallelwith template expansion and dynamic input detection - Detects
find -deleteandfind -exec rmpatterns - Redacts secrets (tokens, passwords, API keys) in block messages and audit logs
- Audit logging: blocked commands logged to
~/.cc-safety-net/logs/<session_id>.jsonl
Code Style (TypeScript)
- Use Bun instead of Node.js for running, testing, and building
- Biome for linting and formatting
- All functions require type annotations
- Use
type | nullsyntax (notundefinedwhere possible) - Use kebab-case for file names (
rules-git.ts, notrulesGit.ts)
Commit Conventions
When committing changes to files in commands/, hooks/, or .opencode/, use only fix or feat commit types. These directories contain user-facing skill definitions and hook configurations that represent features or fixes to the plugin's capabilities.
Environment Variables
SAFETY_NET_STRICT=1: Strict mode (fail-closed on unparseable hook input/commands)SAFETY_NET_PARANOID=1: Paranoid mode (enables all paranoid checks)SAFETY_NET_PARANOID_RM=1: Paranoid rm (blocks non-temprm -rfeven within cwd)SAFETY_NET_PARANOID_INTERPRETERS=1: Paranoid interpreters (blocks interpreter one-liners)
Custom Rules
Users can define additional blocking rules in two scopes (merged, project overrides user):
- User scope:
~/.cc-safety-net/config.json(applies to all projects) - Project scope:
.safety-net.json(in project root)
Rules are additive only—cannot bypass built-in protections. Invalid config silently falls back to built-in rules only.
Testing
Use AGENT=1 bun test to run tests.
Bun Best Practices
- Use
bun <file>instead ofnode <file>orts-node <file> - Use
bun testinstead ofjestorvitest - Use
bun buildinstead ofwebpackoresbuild - Use
bun installinstead ofnpm install - Use
bun run <script>instead ofnpm run <script> - Bun automatically loads .env, so don't use dotenv
For more information, read the Bun API docs in node_modules/bun-types/docs/**.mdx.