[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"tool-kenryu42--claude-code-safety-net":3,"similar-kenryu42--claude-code-safety-net":172},{"id":4,"github_repo":5,"name":6,"description_en":7,"description_zh":8,"ai_summary_zh":9,"readme_en":10,"readme_zh":11,"quickstart_zh":12,"use_case_zh":13,"hero_image_url":14,"owner_login":15,"owner_name":16,"owner_avatar_url":17,"owner_bio":18,"owner_company":18,"owner_location":19,"owner_email":20,"owner_twitter":15,"owner_website":18,"owner_url":21,"languages":22,"stars":35,"forks":36,"last_commit_at":37,"license":38,"difficulty_score":39,"env_os":40,"env_gpu":41,"env_ram":41,"env_deps":42,"category_tags":50,"github_topics":52,"view_count":39,"oss_zip_url":18,"oss_zip_packed_at":18,"status":59,"created_at":60,"updated_at":61,"faqs":62,"releases":91},3101,"kenryu42\u002Fclaude-code-safety-net","claude-code-safety-net","A coding agent hook that acts as a safety net, catching destructive git and filesystem commands before they execute.","claude-code-safety-net 是一款专为 AI 编程助手设计的“安全网”插件，旨在防止自动化代理在执行代码时误删文件或破坏版本控制。它通过拦截并分析即将运行的命令，在 destructive（破坏性）的 Git 操作或文件系统指令实际执行前将其阻断，从而避免类似 `rm -rf` 或强制重置代码库等灾难性后果。\n\n这一工具解决了单纯依靠提示词或软性规则无法有效约束 AI 行为的痛点。以往开发者需在配置文件中反复叮嘱 AI“不要删除文件”，但 AI 仍可能因理解偏差造成数据丢失。claude-code-safety-net 将防护机制从“口头约定”升级为“硬性技术约束”，无需复杂配置即可开箱即用。\n\n它特别适合频繁使用 Claude Code、GitHub Copilot CLI 等终端编程助手的软件开发者和工程师，尤其是那些希望在不牺牲效率的前提下提升项目安全性的团队。\n\n其技术亮点在于采用语义化命令分析而非简单的通配符匹配，能更精准地识别潜在风险；支持多种运行模式（如严格模式、偏执模式），并可检测壳包装器和解释器单行命令等高级绕过手段。此外，它还具备审计日志和敏感信息","claude-code-safety-net 是一款专为 AI 编程助手设计的“安全网”插件，旨在防止自动化代理在执行代码时误删文件或破坏版本控制。它通过拦截并分析即将运行的命令，在 destructive（破坏性）的 Git 操作或文件系统指令实际执行前将其阻断，从而避免类似 `rm -rf` 或强制重置代码库等灾难性后果。\n\n这一工具解决了单纯依靠提示词或软性规则无法有效约束 AI 行为的痛点。以往开发者需在配置文件中反复叮嘱 AI“不要删除文件”，但 AI 仍可能因理解偏差造成数据丢失。claude-code-safety-net 将防护机制从“口头约定”升级为“硬性技术约束”，无需复杂配置即可开箱即用。\n\n它特别适合频繁使用 Claude Code、GitHub Copilot CLI 等终端编程助手的软件开发者和工程师，尤其是那些希望在不牺牲效率的前提下提升项目安全性的团队。\n\n其技术亮点在于采用语义化命令分析而非简单的通配符匹配，能更精准地识别潜在风险；支持多种运行模式（如严格模式、偏执模式），并可检测壳包装器和解释器单行命令等高级绕过手段。此外，它还具备审计日志和敏感信息脱帽功能，为开发环境提供多层防护。对于重视代码资产安全的技术人员而言，这是一个轻量却至关重要的守护工具。","# Claude Code Safety Net\n\n[![CI](https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net\u002Factions\u002Fworkflows\u002Fci.yml)\n[![codecov](https:\u002F\u002Fcodecov.io\u002Fgithub\u002Fkenryu42\u002Fclaude-code-safety-net\u002Fbranch\u002Fmain\u002Fgraph\u002Fbadge.svg?token=C9QTION6ZF)](https:\u002F\u002Fcodecov.io\u002Fgithub\u002Fkenryu42\u002Fclaude-code-safety-net)\n[![Version](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fv\u002Ftag\u002Fkenryu42\u002Fclaude-code-safety-net?label=version&color=blue)](https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net)\n[![Claude Code](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FClaude%20Code-D27656)](#claude-code-installation)\n[![OpenCode](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FOpenCode-black)](#opencode-installation)\n[![Gemini CLI](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FGemini%20CLI-678AE3)](#gemini-cli-installation)\n[![Copilot CLI](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FCopilot%20CLI-4EA5C9)](#github-copilot-cli-installation)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-red.svg)](https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT)\n\n\u003Cdiv align=\"center\">\n\n[![CC Safety Net](.\u002F.github\u002Fassets\u002Fcc-safety-net.png)](.\u002F.github\u002Fassets\u002Fcc-safety-net.png)\n\n\u003C\u002Fdiv>\n\nA Claude Code plugin that acts as a safety net, catching destructive git and filesystem commands before they execute.\n\n## Contents\n\n- [Why This Exists](#why-this-exists)\n- [Why Use This Instead of Permission Deny Rules?](#why-use-this-instead-of-permission-deny-rules)\n- [What About Sandboxing?](#what-about-sandboxing)\n- [Prerequisites](#prerequisites)\n- [Quick Start](#quick-start)\n  - [Claude Code Installation](#claude-code-installation)\n  - [OpenCode Installation](#opencode-installation)\n  - [Gemini CLI Installation](#gemini-cli-installation)\n  - [GitHub Copilot CLI Installation](#github-copilot-cli-installation)\n- [Status Line Integration](#status-line-integration)\n  - [Setup via Slash Command](#setup-via-slash-command)\n  - [Manual Setup](#manual-setup)\n  - [Emoji Mode Indicators](#emoji-mode-indicators)\n- [Diagnostics](#diagnostics)\n- [Explain (Debug Analysis)](#explain-debug-analysis)\n- [Commands Blocked](#commands-blocked)\n- [Commands Allowed](#commands-allowed)\n- [What Happens When Blocked](#what-happens-when-blocked)\n- [Testing the Hook](#testing-the-hook)\n- [Development](#development)\n- [Custom Rules (Experimental)](#custom-rules-experimental)\n  - [Config File Location](#config-file-location)\n  - [Rule Schema](#rule-schema)\n  - [Matching Behavior](#matching-behavior)\n  - [Examples](#examples)\n  - [Error Handling](#error-handling)\n- [Advanced Features](#advanced-features)\n  - [Strict Mode](#strict-mode)\n  - [Paranoid Mode](#paranoid-mode)\n  - [Shell Wrapper Detection](#shell-wrapper-detection)\n  - [Interpreter One-Liner Detection](#interpreter-one-liner-detection)\n  - [Secret Redaction](#secret-redaction)\n  - [Audit Logging](#audit-logging)\n- [License](#license)\n\n## Why This Exists\n\nWe learned the [hard way](https:\u002F\u002Fwww.reddit.com\u002Fr\u002FClaudeAI\u002Fcomments\u002F1pgxckk\u002Fclaude_cli_deleted_my_entire_home_directory_wiped\u002F) that instructions aren't enough to keep AI agents in check.\nAfter Claude Code silently wiped out hours of progress with a single `rm -rf ~\u002F` or `git checkout --`, it became evident that **soft** rules in an `CLAUDE.md` or `AGENTS.md` file cannot replace **hard** technical constraints.\nThe current approach is to use a dedicated hook to programmatically prevent agents from running destructive commands.\n\n## Why Use This Instead of Permission Deny Rules?\n\nClaude Code's `.claude\u002Fsettings.json` supports [deny rules](https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fiam#tool-specific-permission-rules) with wildcard matching (e.g., `Bash(git reset --hard:*)`). Here's how this plugin differs:\n\n### At a Glance\n\n| | Permission Deny Rules | Safety Net |\n|---|---|---|\n| **Setup** | Manual configuration required | Works out of the box |\n| **Parsing** | Wildcard pattern matching | Semantic command analysis |\n| **Execution order** | Runs second | Runs first (PreToolUse hook) |\n| **Shell wrappers** | Not handled automatically (must match wrapper forms) | Recursively analyzed (5 levels) |\n| **Interpreter one-liners** | Not handled automatically (must match interpreter forms) | Detected and blocked |\n\n### Permission Rules Have Known Bypass Vectors\n\nEven with wildcard matching, Bash permission patterns are intentionally limited and can be bypassed in many ways:\n\n| Bypass Method | Example |\n|---------------|---------|\n| Options before value | `curl -X GET http:\u002F\u002Fevil.com` bypasses `Bash(curl http:\u002F\u002Fevil.com:*)` |\n| Shell variables | `URL=http:\u002F\u002Fevil.com && curl $URL` bypasses URL pattern |\n| Flag reordering | `rm -r -f \u002F` bypasses `Bash(rm -rf:*)` |\n| Extra whitespace | `rm  -rf \u002F` (double space) bypasses pattern |\n| Shell wrappers | `sh -c \"rm -rf \u002F\"` bypasses `Bash(rm:*)` entirely |\n\n### Safety Net Handles What Patterns Can't\n\n| Scenario | Permission Rules | Safety Net |\n|----------|------------------|------------|\n| `git checkout -b feature` (safe) | Blocked by `Bash(git checkout:*)` | Allowed |\n| `git checkout -- file` (dangerous) | Blocked by `Bash(git checkout:*)` | Blocked |\n| `rm -rf \u002Ftmp\u002Fcache` (safe) | Blocked by `Bash(rm -rf:*)` | Allowed |\n| `rm -r -f \u002F` (dangerous) | Allowed (flag order) | Blocked |\n| `bash -c 'git reset --hard'` | Allowed (wrapper) | Blocked |\n| `python -c 'os.system(\"rm -rf \u002F\")'` | Allowed (interpreter) | Blocked |\n\n### Defense in Depth\n\nPreToolUse hooks run [**before**](https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fiam#additional-permission-control-with-hooks) the permission system. This means Safety Net inspects every command first, regardless of your permission configuration. Even if you misconfigure deny rules, Safety Net provides a fallback layer of protection.\n\n**Use both together**: Permission deny rules for quick, user-configurable blocks; Safety Net for robust, bypass-resistant protection that works out of the box.\n\n## What About Sandboxing?\n\nClaude Code offers [native sandboxing](https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fsandboxing) that provides OS-level filesystem and network isolation. Here's how it compares to Safety Net:\n\n### Different Layers of Protection\n\n| | Sandboxing | Safety Net |\n|---|---|---|\n| **Enforcement** | OS-level (Seatbelt\u002Fbubblewrap) | Application-level (PreToolUse hook) |\n| **Approach** | Containment — restricts filesystem + network access | Command analysis — blocks destructive operations |\n| **Filesystem** | Writes restricted (default: cwd); reads are broad by default | Only destructive operations blocked |\n| **Network** | Domain-based proxy filtering | None |\n| **Git awareness** | None | Explicit rules for destructive git operations |\n| **Bypass resistance** | High — OS enforces boundaries | Lower — analyzes command strings only |\n\n### Why Sandboxing Isn't Enough\n\nSandboxing restricts filesystem + network access, but it doesn't understand whether an operation is destructive within those boundaries. These commands are not blocked by the sandbox boundary:\n\n> [!NOTE]\n> Whether they're auto-run or require confirmation depends on your sandbox mode (auto-allow vs regular permissions), and network access still depends on your allowed-domain policy. Claude Code can also retry a command outside the sandbox via `dangerouslyDisableSandbox` (with user permission); this can be disabled with `allowUnsandboxedCommands: false`.\n\n| Command | Sandboxing | Safety Net |\n|---------|------------|------------|\n| `git reset --hard` | Allowed (within cwd) | **Blocked** |\n| `git checkout -- .` | Allowed (within cwd) | **Blocked** |\n| `git stash clear` | Allowed (within cwd) | **Blocked** |\n| `git push --force` | Allowed (if remote domain is allowed) | **Blocked** |\n| `rm -rf .` | Allowed (within cwd) | **Blocked** |\n\nSandboxing sees `git reset --hard` as a safe operation—it only modifies files within the current directory. But you just lost all uncommitted work.\n\n### When to Use Sandboxing Instead\n\nSandboxing is the better choice when your primary concern is:\n\n- **Prompt injection attacks** — Reduces exfiltration risk by restricting outbound domains (depends on your allowed-domain policy)\n- **Malicious dependencies** — Limits filesystem writes and network access by default (subject to your sandbox configuration)\n- **Untrusted code execution** — OS-level containment is stronger than pattern matching\n- **Network control** — Safety Net has no network protection\n\n### Recommended: Use Both\n\nThey protect against different threats:\n\n- **Sandboxing** contains blast radius — even if something goes wrong, damage is limited to cwd and approved network domains\n- **Safety Net** prevents footguns — catches git-specific mistakes that are technically \"safe\" from the sandbox's perspective\n\nRunning both together provides defense-in-depth. Sandboxing handles unknown threats; Safety Net handles known destructive patterns that sandboxing permits.\n\n## Prerequisites\n\n- **Node.js**: Version 18 or higher is required to run this plugin\n\n## Quick Start\n\n### Claude Code Installation\n\n```bash\n\u002Fplugin marketplace add kenryu42\u002Fcc-marketplace\n\u002Fplugin install safety-net@cc-marketplace\n\u002Freload-plugins\n```\n\n### Claude Code Auto-Update\n\n1. Run `\u002Fplugin` → Select `Marketplaces` → Choose `cc-marketplace` → Enable auto-update\n\n---\n\n### OpenCode Installation\n\n**Option A: Let an LLM do it**\n\nPaste this into any LLM agent (Claude Code, OpenCode, Cursor, etc.):\n\n```\nInstall the cc-safety-net plugin in `~\u002F.config\u002Fopencode\u002Fopencode.json` (or `.jsonc`) according to the schema at: https:\u002F\u002Fopencode.ai\u002Fconfig.json\n```\n\n**Option B: Manual setup**\n\n1. **Add the plugin to your config** `~\u002F.config\u002Fopencode\u002Fopencode.json` (or `.jsonc`):\n\n  ```json\n  {\n    \"plugin\": [\"cc-safety-net\"]\n  }\n  ```\n\n---\n\n### Gemini CLI Installation\n\n```bash\ngemini extensions install https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fgemini-safety-net\n```\n\n---\n\n### GitHub Copilot CLI Installation\n\n```bash\n\u002Fplugin install kenryu42\u002Fcopilot-safety-net\n```\n\n> [!NOTE]\n> After installing the plugin, you need to restart your Copilot CLI for it to take effect.\n\n---\n\n## Status Line Integration\n\nSafety Net can display its status in Claude Code's status line, showing whether protection is active and which modes are enabled.\n\n### Setup via Slash Command\n\nThe easiest way to configure the status line is using the built-in slash command:\n\n```\n\u002Fset-statusline\n```\n\nThis interactive command will:\n1. Ask whether you prefer `bunx` or `npx`\n2. Check for existing status line configuration\n3. Offer to replace or pipe with existing commands\n4. Write the configuration to `~\u002F.claude\u002Fsettings.json`\n\n### Manual Setup\n\nAdd the following to your `~\u002F.claude\u002Fsettings.json`:\n\n**Using Bun (recommended):**\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"bunx cc-safety-net --statusline\"\n  }\n}\n```\n\n**Using Claude X:**\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"BUN_BE_BUN=1 claude x cc-safety-net --statusline\"\n  }\n}\n```\n> [!NOTE]\n> The `claude x` command is only compatible with the native version of Claude Code. If you installed via npm, please use `npx` or `bunx` instead.\n\n\n\n**Using NPM:**\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"npx -y cc-safety-net --statusline\"\n  }\n}\n```\n\n**Piping with existing status line:**\n\nIf you already have a status line command, you can pipe Safety Net at the end:\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"your-existing-command | bunx cc-safety-net --statusline\"\n  }\n}\n```\n\nChanges take effect immediately — no restart needed.\n\n### Emoji Mode Indicators\n\nThe status line displays different emojis based on the current configuration:\n\n| Status | Display | Meaning |\n|--------|---------|---------|\n| Plugin disabled | `🛡️ Safety Net ❌` | Safety Net plugin is not enabled |\n| Default mode | `🛡️ Safety Net ✅` | Protection active with default settings |\n| Strict mode | `🛡️ Safety Net 🔒` | `SAFETY_NET_STRICT=1` — fail-closed on unparseable commands |\n| Paranoid mode | `🛡️ Safety Net 👁️` | `SAFETY_NET_PARANOID=1` — all paranoid checks enabled |\n| Paranoid RM only | `🛡️ Safety Net 🗑️` | `SAFETY_NET_PARANOID_RM=1` — blocks `rm -rf` even within cwd |\n| Paranoid interpreters only | `🛡️ Safety Net 🐚` | `SAFETY_NET_PARANOID_INTERPRETERS=1` — blocks interpreter one-liners |\n| Strict + Paranoid | `🛡️ Safety Net 🔒👁️` | Both strict and paranoid modes enabled |\n\nMultiple mode emojis are combined when multiple environment variables are set.\n\n## Diagnostics\n\nRun the diagnostic command to verify your installation and troubleshoot issues:\n\n```bash\nnpx cc-safety-net doctor\n# or with bun\nbunx cc-safety-net doctor\n```\n\nThe doctor command checks:\n\n| Check | Description |\n|-------|-------------|\n| Hook Integration | Verifies the plugin is properly configured for each supported platform |\n| Self-Test | Runs sample commands to confirm blocking works correctly |\n| Configuration | Validates custom rules in user and project configs |\n| Environment | Shows status of mode flags (SAFETY_NET_STRICT, SAFETY_NET_PARANOID, etc.) |\n| Recent Activity | Summarizes blocked commands from the last 7 days |\n| System Info | Displays versions of all relevant tools |\n| Update Check | Checks if a newer version is available |\n\n### Options\n\n| Flag | Description |\n|------|-------------|\n| `--json` | Output in JSON format (useful for sharing in bug reports) |\n| `--skip-update-check` | Skip the npm version check |\n\n## Explain (Debug Analysis)\n\nTrace how Safety Net analyzes a command step-by-step. Useful for debugging why a command is blocked or allowed, or when developing custom rules.\n\n```bash\nnpx cc-safety-net explain \"git reset --hard\"\n# or with bun\nbunx cc-safety-net explain \"git reset --hard\"\n```\n\n### Options\n\n| Flag | Description |\n|------|-------------|\n| `--json` | Output analysis as JSON |\n| `--cwd \u003Cpath>` | Use custom working directory for analysis |\n\n### Examples\n\n```bash\nnpx cc-safety-net explain \"rm -rf \u002F\"\nnpx cc-safety-net explain --json \"git checkout -- file.txt\"\nnpx cc-safety-net explain --cwd \u002Ftmp \"git status\"\n```\n\n## Commands Blocked\n\n| Command Pattern | Why It's Dangerous |\n|-----------------|-------------------|\n| git checkout -- files | Discards uncommitted changes permanently |\n| git checkout \\\u003Cref\\> -- \\\u003Cpath\\> | Overwrites working tree with ref version |\n| git checkout \\\u003Cref\\> \\\u003Cpath\\> | May overwrite working tree when Git disambiguates ref vs pathspec |\n| git restore files | Discards uncommitted changes |\n| git restore --worktree | Explicitly discards working tree changes |\n| git reset --hard | Destroys all uncommitted changes |\n| git reset --merge | Can lose uncommitted changes |\n| git clean -f | Removes untracked files permanently |\n| git push --force \u002F -f | Destroys remote history |\n| git branch -D | Force-deletes branch without merge check |\n| git stash drop | Permanently deletes stashed changes |\n| git stash clear | Deletes ALL stashed changes |\n| git worktree remove --force | Force-deletes worktree without checking for changes |\n| rm -rf (paths outside cwd) | Recursive file deletion outside the current directory |\n| rm -rf \u002F or ~ or $HOME | Root\u002Fhome deletion is extremely dangerous |\n| find ... -delete | Permanently removes files matching criteria |\n| xargs rm -rf | Dynamic input makes targets unpredictable |\n| xargs \\\u003Cshell\\> -c | Can execute arbitrary commands |\n| parallel rm -rf | Dynamic input makes targets unpredictable |\n| parallel \\\u003Cshell\\> -c | Can execute arbitrary commands |\n\n## Commands Allowed\n\n| Command Pattern | Why It's Safe |\n|-----------------|--------------|\n| git checkout -b branch | Creates new branch |\n| git checkout --orphan | Creates orphan branch |\n| git restore --staged | Only unstages, doesn't discard |\n| git restore --help\u002F--version | Help\u002Fversion output |\n| git branch -d | Safe delete with merge check |\n| git clean -n \u002F --dry-run | Preview only |\n| git push --force-with-lease | Safe force push |\n| rm -rf \u002Ftmp\u002F... | Temp directories are ephemeral |\n| rm -rf \u002Fvar\u002Ftmp\u002F... | System temp directory |\n| rm -rf $TMPDIR\u002F... | User's temp directory |\n| rm -rf .\u002F... (within cwd) | Limited to current working directory |\n\n## What Happens When Blocked\n\nWhen a destructive command is detected, the plugin blocks the tool execution and provides a reason.\n\nExample output:\n```text\nBLOCKED by Safety Net\n\nReason: git checkout -- discards uncommitted changes permanently. Use 'git stash' first.\n\nCommand: git checkout -- src\u002Fmain.py\n\nIf this operation is truly needed, ask the user for explicit permission and have them run the command manually.\n```\n\n## Testing the Hook\n\nYou can manually test the hook by attempting to run blocked commands in Claude Code:\n\n```bash\n# This should be blocked\ngit checkout -- README.md\n\n# This should be allowed\ngit checkout -b test-branch\n```\n\n## Development\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to this project.\n\n## Custom Rules (Experimental)\n\nBeyond the built-in protections, you can define your own blocking rules to enforce team conventions or project-specific safety policies.\n\n> [!TIP]\n> Use `\u002Fset-custom-rules` to create custom rules interactively with natural language.\n>\n> **GitHub Copilot CLI users**: Since Copilot CLI doesn't support custom slash commands, prompt your agent with:\n> ```text\n> run npx cc-safety-net --custom-rules-doc and help me set up custom rules\n> ```\n\n### Quick Example\n\nCreate `.safety-net.json` in your project root:\n\n```json\n{\n  \"version\": 1,\n  \"rules\": [\n    {\n      \"name\": \"block-git-add-all\",\n      \"command\": \"git\",\n      \"subcommand\": \"add\",\n      \"block_args\": [\"-A\", \"--all\", \".\"],\n      \"reason\": \"Use 'git add \u003Cspecific-files>' instead of blanket add.\"\n    }\n  ]\n}\n```\n\nNow `git add -A`, `git add --all`, and `git add .` will be blocked with your custom message.\n\n### Config File Location\n\nConfig files are loaded from two scopes and merged:\n\n1. **User scope**: `~\u002F.cc-safety-net\u002Fconfig.json` (always loaded if exists)\n2. **Project scope**: `.safety-net.json` in the current working directory (loaded if exists)\n\n**Merging behavior**:\n- Rules from both scopes are combined\n- If the same rule name exists in both scopes, **project scope wins**\n- Rule name comparison is case-insensitive (`MyRule` and `myrule` are considered duplicates)\n\nThis allows you to define personal defaults in user scope while letting projects override specific rules.\n\nIf no config file is found in either location, only built-in rules apply.\n\n### Config Schema\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `version` | integer | Yes | Schema version (must be `1`) |\n| `rules` | array | No | List of custom blocking rules (defaults to empty) |\n\n### Rule Schema\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `name` | string | Yes | Unique identifier (letters, numbers, hyphens, underscores; max 64 chars) |\n| `command` | string | Yes | Base command to match (e.g., `git`, `npm`, `docker`) |\n| `subcommand` | string | No | Subcommand to match (e.g., `add`, `install`). If omitted, matches any. |\n| `block_args` | array | Yes | Arguments that trigger the block (at least one required) |\n| `reason` | string | Yes | Message shown when blocked (max 256 chars) |\n\n### Matching Behavior\n\n- **Commands** are normalized to basename (`\u002Fusr\u002Fbin\u002Fgit` → `git`)\n- **Subcommand** is the first non-option argument after the command\n- **Arguments** are matched literally (no regex, no glob), with short option expansion\n- A command is blocked if **any** argument in `block_args` is present\n- **Short options** are expanded: `-Ap` matches `-A` (bundled flags are unbundled)\n- **Long options** use exact match: `--all-files` does NOT match `--all`\n- Custom rules only add restrictions—they cannot bypass built-in protections\n\n#### Known Limitations\n\n- **Short option expansion**: `-Cfoo` is treated as `-C -f -o -o`, not `-C foo`. Blocking `-f` may false-positive on attached option values.\n\n### Examples\n\n#### Block global npm installs\n\n```json\n{\n  \"version\": 1,\n  \"rules\": [\n    {\n      \"name\": \"block-npm-global\",\n      \"command\": \"npm\",\n      \"subcommand\": \"install\",\n      \"block_args\": [\"-g\", \"--global\"],\n      \"reason\": \"Global npm installs can cause version conflicts. Use npx or local install.\"\n    }\n  ]\n}\n```\n\n#### Block dangerous docker commands\n\n```json\n{\n  \"version\": 1,\n  \"rules\": [\n    {\n      \"name\": \"block-docker-system-prune\",\n      \"command\": \"docker\",\n      \"subcommand\": \"system\",\n      \"block_args\": [\"prune\"],\n      \"reason\": \"docker system prune removes all unused data. Use targeted cleanup instead.\"\n    }\n  ]\n}\n```\n\n#### Multiple rules\n\n```json\n{\n  \"version\": 1,\n  \"rules\": [\n    {\n      \"name\": \"block-git-add-all\",\n      \"command\": \"git\",\n      \"subcommand\": \"add\",\n      \"block_args\": [\"-A\", \"--all\", \".\", \"-u\", \"--update\"],\n      \"reason\": \"Use 'git add \u003Cspecific-files>' instead of blanket add.\"\n    },\n    {\n      \"name\": \"block-npm-global\",\n      \"command\": \"npm\",\n      \"subcommand\": \"install\",\n      \"block_args\": [\"-g\", \"--global\"],\n      \"reason\": \"Use npx or local install instead of global.\"\n    }\n  ]\n}\n```\n\n### Error Handling\n\nCustom rules use **silent fallback** error handling. If your config file is invalid, the safety net silently falls back to built-in rules only:\n\n| Scenario | Behavior |\n|----------|----------|\n| Config file not found | Silent — use built-in rules only |\n| Empty config file | Silent — use built-in rules only |\n| Invalid JSON syntax | Silent — use built-in rules only |\n| Missing required field | Silent — use built-in rules only |\n| Invalid field format | Silent — use built-in rules only |\n| Duplicate rule name | Silent — use built-in rules only |\n\n\n> [!IMPORTANT]  \n> If you add or modify custom rules manually, always validate them with `npx -y cc-safety-net --verify-config` or `\u002Fverify-custom-rules` slash command in your coding agent.\n\n### Block Output Format\n\nWhen a custom rule blocks a command, the output includes the rule name:\n\n```text\nBLOCKED by Safety Net\n\nReason: [block-git-add-all] Use 'git add \u003Cspecific-files>' instead of blanket add.\n\nCommand: git add -A\n```\n\n## Advanced Features\n\n### Strict Mode\n\nBy default, unparseable commands are allowed through. Enable strict mode to fail-closed\nwhen the hook input or shell command cannot be safely analyzed (e.g., invalid JSON,\nunterminated quotes, malformed `bash -c` wrappers):\n\n```bash\nexport SAFETY_NET_STRICT=1\n```\n\n### Paranoid Mode\n\nParanoid mode enables stricter safety checks that may be disruptive to normal workflows.\nYou can enable it globally or via focused toggles:\n\n```bash\n# Enable all paranoid checks\nexport SAFETY_NET_PARANOID=1\n\n# Or enable specific paranoid checks\nexport SAFETY_NET_PARANOID_RM=1\nexport SAFETY_NET_PARANOID_INTERPRETERS=1\n```\n\nParanoid behavior:\n\n- **rm**: blocks non-temp `rm -rf` even within the current working directory.\n- **interpreters**: blocks interpreter one-liners like `python -c`, `node -e`, `ruby -e`,\n  and `perl -e` (these can hide destructive commands).\n\n### Shell Wrapper Detection\n\nThe guard recursively analyzes commands wrapped in shells:\n\n```bash\nbash -c 'git reset --hard'    # Blocked\nsh -lc 'rm -rf \u002F'             # Blocked\n```\n\n### Interpreter One-Liner Detection\n\nDetects destructive commands hidden in Python\u002FNode\u002FRuby\u002FPerl one-liners:\n\n```bash\npython -c 'import os; os.system(\"rm -rf \u002F\")'  # Blocked\n```\n\n### Secret Redaction\n\nBlock messages automatically redact sensitive data (tokens, passwords, API keys) to prevent leaking secrets in logs.\n\n### Audit Logging\n\nAll blocked commands are logged to `~\u002F.cc-safety-net\u002Flogs\u002F\u003Csession_id>.jsonl` for audit purposes:\n\n```json\n{\"ts\": \"2025-01-15T10:30:00Z\", \"command\": \"git reset --hard\", \"segment\": \"git reset --hard\", \"reason\": \"...\", \"cwd\": \"\u002Fpath\u002Fto\u002Fproject\"}\n```\n\nSensitive data in log entries is automatically redacted.\n\n## License\n\nMIT\n","# 克劳德代码安全网\n\n[![CI](https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net\u002Factions\u002Fworkflows\u002Fci.yml)\n[![codecov](https:\u002F\u002Fcodecov.io\u002Fgithub\u002Fkenryu42\u002Fclaude-code-safety-net\u002Fbranch\u002Fmain\u002Fgraph\u002Fbadge.svg?token=C9QTION6ZF)](https:\u002F\u002Fcodecov.io\u002Fgithub\u002Fkenryu42\u002Fclaude-code-safety-net)\n[![Version](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fv\u002Ftag\u002Fkenryu42\u002Fclaude-code-safety-net?label=version&color=blue)](https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net)\n[![Claude Code](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FClaude%20Code-D27656)](#claude-code-installation)\n[![OpenCode](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FOpenCode-black)](#opencode-installation)\n[![Gemini CLI](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FGemini%20CLI-678AE3)](#gemini-cli-installation)\n[![Copilot CLI](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FCopilot%20CLI-4EA5C9)](#github-copilot-cli-installation)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-red.svg)](https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT)\n\n\u003Cdiv align=\"center\">\n\n[![CC 安全网](.\u002F.github\u002Fassets\u002Fcc-safety-net.png)](.\u002F.github\u002Fassets\u002Fcc-safety-net.png)\n\n\u003C\u002Fdiv>\n\n一个克劳德代码插件，充当安全网，在破坏性 Git 和文件系统命令执行前将其拦截。\n\n## 目录\n\n- [为何存在此项目](#why-this-exists)\n- [为何不使用权限拒绝规则？](#why-use-this-instead-of-permission-deny-rules)\n- [沙箱又如何？](#what-about-sandboxing)\n- [先决条件](#prerequisites)\n- [快速入门](#quick-start)\n  - [克劳德代码安装](#claude-code-installation)\n  - [OpenCode 安装](#opencode-installation)\n  - [Gemini CLI 安装](#gemini-cli-installation)\n  - [GitHub Copilot CLI 安装](#github-copilot-cli-installation)\n- [状态栏集成](#status-line-integration)\n  - [通过斜杠命令设置](#setup-via-slash-command)\n  - [手动设置](#manual-setup)\n  - [表情符号模式指示器](#emoji-mode-indicators)\n- [诊断](#diagnostics)\n- [解释（调试分析）](#explain-debug-analysis)\n- [被阻止的命令](#commands-blocked)\n- [允许的命令](#commands-allowed)\n- [被阻止时会发生什么](#what-happens-when-blocked)\n- [测试钩子](#testing-the-hook)\n- [开发](#development)\n- [自定义规则（实验性）](#custom-rules-experimental)\n  - [配置文件位置](#config-file-location)\n  - [规则模式](#rule-schema)\n  - [匹配行为](#matching-behavior)\n  - [示例](#examples)\n  - [错误处理](#error-handling)\n- [高级功能](#advanced-features)\n  - [严格模式](#strict-mode)\n  - [偏执模式](#paranoid-mode)\n  - [Shell 包装检测](#shell-wrapper-detection)\n  - [解释器单行命令检测](#interpreter-one-liner-detection)\n  - [敏感信息脱敏](#secret-redaction)\n  - [审计日志记录](#audit-logging)\n- [许可证](#license)\n\n## 为何存在此项目\n\n我们以惨痛的教训认识到，仅靠指令并不能有效约束 AI 代理的行为。[Reddit 上的一则帖子](https:\u002F\u002Fwww.reddit.com\u002Fr\u002FClaudeAI\u002Fcomments\u002F1pgxckk\u002Fclaude_cli_deleted_my_entire_home_directory_wiped\u002F)生动地展示了这一点：克劳德代码在悄无声息间执行了 `rm -rf ~\u002F` 或 `git checkout --` 等命令，瞬间清空了数小时的工作成果。这清楚地表明，仅仅依靠 `CLAUDE.md` 或 `AGENTS.md` 文件中的软性规则，无法替代硬性的技术限制措施。因此，当前的做法是利用专门的钩子程序来自动阻止代理运行破坏性命令。\n\n## 为何不使用权限拒绝规则？\n\n克劳德代码的 `.claude\u002Fsettings.json` 支持带有通配符匹配的拒绝规则（例如 `Bash(git reset --hard:*)`）。而本插件与之相比有以下区别：\n\n### 一目了然\n\n| | 权限拒绝规则 | 安全网 |\n|---|---|---|\n| **设置** | 需手动配置 | 开箱即用 |\n| **解析** | 通配符模式匹配 | 语义化命令分析 |\n| **执行顺序** | 第二步执行 | 第一步执行（PreToolUse 钩子） |\n| **Shell 包装** | 不能自动处理（需匹配包装形式） | 递归分析（最多 5 层） |\n| **解释器单行命令** | 不能自动处理（需匹配解释器形式） | 能够检测并阻止 |\n\n### 权限规则存在已知绕过途径\n\n即便使用通配符匹配，Bash 的权限模式也存在诸多局限性，容易被多种方式绕过：\n\n| 绕过方法 | 示例 |\n|---------------|---------|\n| 选项置于值之前 | `curl -X GET http:\u002F\u002Fevil.com` 可绕过 `Bash(curl http:\u002F\u002Fevil.com:*)` |\n| Shell 变量 | `URL=http:\u002F\u002Fevil.com && curl $URL` 可绕过 URL 模式 |\n| 标志位重新排序 | `rm -r -f \u002F` 可绕过 `Bash(rm -rf:*)` |\n| 多余空格 | `rm  -rf \u002F`（双空格）可绕过模式 |\n| Shell 包装 | `sh -c \"rm -rf \u002F\"` 可完全绕过 `Bash(rm:*)` |\n\n### 安全网能处理模式无法应对的情况\n\n| 场景 | 权限规则 | 安全网 |\n|----------|------------------|------------|\n| `git checkout -b feature`（安全） | 被 `Bash(git checkout:*)` 阻止 | 允许 |\n| `git checkout -- file`（危险） | 被 `Bash(git checkout:*)` 阻止 | 阻止 |\n| `rm -rf \u002Ftmp\u002Fcache`（安全） | 被 `Bash(rm -rf:*)` 阻止 | 允许 |\n| `rm -r -f \u002F`（危险） | 因标志位顺序获准执行 | 阻止 |\n| `bash -c 'git reset --hard'` | 因使用包装获准执行 | 阻止 |\n| `python -c 'os.system(\"rm -rf \u002F\")'` | 因使用解释器获准执行 | 阻止 |\n\n### 多层防御\n\nPreToolUse 钩子会在权限系统[之前](https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fiam#additional-permission-control-with-hooks)执行。这意味着安全网会优先检查每一条命令，无论你的权限配置如何。即使你误配置了拒绝规则，安全网仍能提供最后一道保护屏障。\n\n**建议两者结合使用**：权限拒绝规则适合快速、用户可配置的拦截；而安全网则提供更强大、难以绕过的保护机制，且开箱即用。\n\n## 沙箱又如何？\n\n克劳德代码提供了原生的[沙箱功能](https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fsandboxing)，可在操作系统层面实现文件系统和网络隔离。以下是它与安全网的对比：\n\n### 不同层次的保护\n\n| | 沙箱 | 安全网 |\n|---|---|---|\n| **执行方式** | 操作系统级别（Seatbelt\u002Fbubblewrap） | 应用程序级别（PreToolUse 钩子） |\n| **方法** | 封闭式——限制文件系统和网络访问 | 命令分析——阻止破坏性操作 |\n| **文件系统** | 默认限制写入（仅当前目录）；读取权限较宽 | 仅阻止破坏性操作 |\n| **网络** | 域名级代理过滤 | 无 |\n| **Git 意识** | 无 | 针对破坏性 Git 操作有明确规则 |\n| **抗绕过能力** | 高——由操作系统强制边界 | 较低——仅分析命令字符串 |\n\n### 为什么沙箱还不够\n\n沙箱会限制文件系统和网络访问，但它并不了解在这些限制范围内哪些操作是具有破坏性的。以下命令不会被沙箱边界阻止：\n\n> [!NOTE]\n> 这些命令是自动执行还是需要确认，取决于你的沙箱模式（自动允许 vs. 普通权限），而网络访问仍然取决于你允许的域名策略。Claude Code 还可以通过 `dangerouslyDisableSandbox` 在沙箱外重试命令（需用户授权）；这可以通过设置 `allowUnsandboxedCommands: false` 来禁用。\n\n| 命令 | 沙箱限制 | 安全网 |\n|---------|------------|------------|\n| `git reset --hard` | 允许（在当前工作目录内） | **阻止** |\n| `git checkout -- .` | 允许（在当前工作目录内） | **阻止** |\n| `git stash clear` | 允许（在当前工作目录内） | **阻止** |\n| `git push --force` | 允许（如果远程域名被允许） | **阻止** |\n| `rm -rf .` | 允许（在当前工作目录内） | **阻止** |\n\n沙箱会认为 `git reset --hard` 是一个安全的操作——它只修改当前目录内的文件。但这样一来，你所有未提交的工作就都丢失了。\n\n### 何时应该使用沙箱\n\n当你的主要关注点是以下情况时，使用沙箱更为合适：\n\n- **提示注入攻击** — 通过限制出站域名来降低数据泄露风险（取决于你允许的域名策略）\n- **恶意依赖** — 默认情况下限制文件系统写入和网络访问（受你的沙箱配置影响）\n- **执行不受信任的代码** — 操作系统级别的隔离比模式匹配更强大\n- **网络控制** — 安全网没有网络保护功能\n\n### 推荐：同时使用两者\n\n它们分别针对不同的威胁提供保护：\n\n- **沙箱** 可以控制破坏范围——即使出现问题，损害也仅限于当前工作目录和已批准的网络域名。\n- **安全网** 可以防止误操作——它可以捕获那些从沙箱角度看“安全”的 Git 特定错误。\n\n同时运行两者可以提供纵深防御。沙箱处理未知威胁；安全网则处理沙箱允许的已知破坏性模式。\n\n## 先决条件\n\n- **Node.js**：运行此插件需要版本 18 或更高。\n\n## 快速开始\n\n### Claude Code 的安装\n\n```bash\n\u002Fplugin marketplace add kenryu42\u002Fcc-marketplace\n\u002Fplugin install safety-net@cc-marketplace\n\u002Freload-plugins\n```\n\n### Claude Code 自动更新\n\n1. 运行 `\u002Fplugin` → 选择 `Marketplaces` → 选择 `cc-marketplace` → 启用自动更新\n\n---\n\n### OpenCode 的安装\n\n**选项 A：让 LLM 自动完成**\n\n将以下内容粘贴到任何 LLM 代理中（Claude Code、OpenCode、Cursor 等）：\n\n```\n按照 https:\u002F\u002Fopencode.ai\u002Fconfig.json 中的模式，在 `~\u002F.config\u002Fopencode\u002Fopencode.json`（或 `.jsonc`）中安装 cc-safety-net 插件。\n```\n\n**选项 B：手动设置**\n\n1. **将插件添加到你的配置文件** `~\u002F.config\u002Fopencode\u002Fopencode.json`（或 `.jsonc`）：\n\n  ```json\n  {\n    \"plugin\": [\"cc-safety-net\"]\n  }\n  ```\n\n---\n\n### Gemini CLI 的安装\n\n```bash\ngemini extensions install https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fgemini-safety-net\n```\n\n---\n\n### GitHub Copilot CLI 的安装\n\n```bash\n\u002Fplugin install kenryu42\u002Fcopilot-safety-net\n```\n\n> [!NOTE]\n> 安装插件后，你需要重启 Copilot CLI 才能使插件生效。\n\n---\n\n## 状态栏集成\n\n安全网可以在 Claude Code 的状态栏中显示其状态，表明保护是否启用以及启用了哪些模式。\n\n### 通过斜杠命令设置\n\n配置状态栏最简单的方式是使用内置的斜杠命令：\n\n```\n\u002Fset-statusline\n```\n\n这个交互式命令会：\n1. 询问你更倾向于使用 `bunx` 还是 `npx`\n2. 检查现有的状态栏配置\n3. 提供替换或与现有命令管道连接的选项\n4. 将配置写入 `~\u002F.claude\u002Fsettings.json`\n\n### 手动设置\n\n将以下内容添加到你的 `~\u002F.claude\u002Fsettings.json` 中：\n\n**使用 Bun（推荐）：**\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"bunx cc-safety-net --statusline\"\n  }\n}\n```\n\n**使用 Claude X：**\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"BUN_BE_BUN=1 claude x cc-safety-net --statusline\"\n  }\n}\n```\n\n> [!NOTE]\n> `claude x` 命令仅与原生版 Claude Code 兼容。如果你通过 npm 安装，请改用 `npx` 或 `bunx`。\n\n**使用 NPM：**\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"npx -y cc-safety-net --statusline\"\n  }\n}\n```\n\n**与现有状态栏命令管道连接：**\n\n如果你已经有状态栏命令，可以在末尾加入安全网：\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"your-existing-command | bunx cc-safety-net --statusline\"\n  }\n}\n```\n\n更改会立即生效——无需重启。\n\n### 模式指示表情符号\n\n状态栏会根据当前配置显示不同的表情符号：\n\n| 状态 | 显示 | 含义 |\n|--------|---------|---------|\n| 插件已禁用 | `🛡️ Safety Net ❌` | 安全网插件未启用 |\n| 默认模式 | `🛡️ Safety Net ✅` | 使用默认设置进行保护 |\n| 严格模式 | `🛡️ Safety Net 🔒` | `SAFETY_NET_STRICT=1` — 对无法解析的命令采取失败关闭 |\n| 偏执模式 | `🛡️ Safety Net 👁️` | `SAFETY_NET_PARANOID=1` — 启用所有偏执检查 |\n| 仅限 RM 的偏执模式 | `🛡️ Safety Net 🗑️` | `SAFETY_NET_PARANOID_RM=1` — 即使在当前工作目录内也会阻止 `rm -rf` |\n| 仅限解释器的偏执模式 | `🛡️ Safety Net 🐚` | `SAFETY_NET_PARANOID_INTERPRETERS=1` — 阻止解释器单行命令 |\n| 严格 + 偏执模式 | `🛡️ Safety Net 🔒👁️` | 同时启用严格和偏执模式 |\n\n当设置了多个环境变量时，模式表情符号会组合显示。\n\n## 诊断\n\n运行诊断命令以验证你的安装并排查问题：\n\n```bash\nnpx cc-safety-net doctor\n# 或使用 bun\nbunx cc-safety-net doctor\n```\n\n诊断命令会检查：\n\n| 检查 | 描述 |\n|-------|-------------|\n| 钩子集成 | 验证插件是否为每个支持的平台正确配置 |\n| 自我测试 | 运行示例命令以确认阻止功能正常工作 |\n| 配置 | 验证用户和项目配置中的自定义规则 |\n| 环境 | 显示模式标志的状态（SAFETY_NET_STRICT、SAFETY_NET_PARANOID 等） |\n| 最近活动 | 总结过去 7 天内被阻止的命令 |\n| 系统信息 | 显示所有相关工具的版本 |\n| 更新检查 | 检查是否有新版本可用 |\n\n### 选项\n\n| 标志 | 描述 |\n|------|-------------|\n| `--json` | 以 JSON 格式输出（便于在 bug 报告中分享） |\n| `--skip-update-check` | 跳过 npm 版本检查 |\n\n## 解释（调试分析）\n\n跟踪安全网如何逐步分析一条命令。这对于调试为什么某条命令会被阻止或允许，或者在开发自定义规则时非常有用。\n\n```bash\nnpx cc-safety-net explain \"git reset --hard\"\n# 或使用 bun\nbunx cc-safety-net explain \"git reset --hard\"\n```\n\n### 选项\n\n| 标志 | 描述 |\n|------|-------------|\n| `--json` | 将分析结果输出为 JSON |\n| `--cwd \u003Cpath>` | 使用自定义工作目录进行分析 |\n\n### 示例\n\n```bash\nnpx cc-safety-net explain \"rm -rf \u002F\"\nnpx cc-safety-net explain --json \"git checkout -- file.txt\"\nnpx cc-safety-net explain --cwd \u002Ftmp \"git status\"\n```\n\n## 被阻止的命令\n\n| 命令模式 | 危险原因 |\n|-----------------|-------------------|\n| git checkout -- files | 永久丢弃未提交的更改 |\n| git checkout \\\u003Cref\\> -- \\\u003Cpath\\> | 用引用版本覆盖工作区 |\n| git checkout \\\u003Cref\\> \\\u003Cpath\\> | 当 Git 无法区分引用和路径规范时，可能会覆盖工作区 |\n| git restore files | 丢弃未提交的更改 |\n| git restore --worktree | 显式丢弃工作区更改 |\n| git reset --hard | 销毁所有未提交的更改 |\n| git reset --merge | 可能会丢失未提交的更改 |\n| git clean -f | 永久删除未跟踪文件 |\n| git push --force \u002F -f | 破坏远程历史 |\n| git branch -D | 强制删除分支，不检查是否已合并 |\n| git stash drop | 永久删除暂存的更改 |\n| git stash clear | 删除所有暂存的更改 |\n| git worktree remove --force | 强制删除工作树，不检查是否有更改 |\n| rm -rf（当前目录外的路径） | 递归删除当前目录外的文件 |\n| rm -rf \u002F 或 ~ 或 $HOME | 根目录\u002F主目录的删除极其危险 |\n| find ... -delete | 永久删除符合条件的文件 |\n| xargs rm -rf | 动态输入使目标不可预测 |\n| xargs \\\u003Cshell\\> -c | 可以执行任意命令 |\n| parallel rm -rf | 动态输入使目标不可预测 |\n| parallel \\\u003Cshell\\> -c | 可以执行任意命令 |\n\n## 允许的命令\n\n| 命令模式 | 安全原因 |\n|-----------------|--------------|\n| git checkout -b branch | 创建新分支 |\n| git checkout --orphan | 创建孤立分支 |\n| git restore --staged | 仅取消暂存，不丢弃 |\n| git restore --help\u002F--version | 输出帮助信息或版本号 |\n| git branch -d | 安全删除，会检查是否已合并 |\n| git clean -n \u002F --dry-run | 仅预览 |\n| git push --force-with-lease | 安全强制推送 |\n| rm -rf \u002Ftmp\u002F... | 临时目录是短暂存在的 |\n| rm -rf \u002Fvar\u002Ftmp\u002F... | 系统临时目录 |\n| rm -rf $TMPDIR\u002F... | 用户临时目录 |\n| rm -rf .\u002F...（在当前目录内） | 限制在当前工作目录内 |\n\n## 被阻止时的行为\n\n当检测到破坏性命令时，插件会阻止工具执行，并给出原因。\n\n示例输出：\n```text\n被安全网阻止\n\n原因：git checkout -- 会永久丢弃未提交的更改。请先使用 'git stash'。\n\n命令：git checkout -- src\u002Fmain.py\n\n如果确实需要执行此操作，请明确征得用户同意，并由用户手动运行该命令。\n```\n\n## 测试钩子\n\n您可以通过尝试在 Claude Code 中运行被阻止的命令来手动测试钩子：\n\n```bash\n# 这应该会被阻止\ngit checkout -- README.md\n\n# 这应该会被允许\ngit checkout -b test-branch\n```\n\n## 开发\n\n有关如何参与本项目的详细信息，请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。\n\n## 自定义规则（实验性）\n\n除了内置保护之外，您还可以定义自己的阻止规则，以执行团队约定或项目特定的安全策略。\n\n> [!TIP]\n> 使用 `\u002Fset-custom-rules` 可以通过自然语言交互方式创建自定义规则。\n>\n> **GitHub Copilot CLI 用户**：由于 Copilot CLI 不支持自定义斜杠命令，请向您的代理发送以下提示：\n> ```text\n> 运行 npx cc-safety-net --custom-rules-doc 并帮我设置自定义规则\n> ```\n\n### 快速示例\n\n在项目根目录下创建 `.safety-net.json` 文件：\n\n```json\n{\n  \"version\": 1,\n  \"rules\": [\n    {\n      \"name\": \"block-git-add-all\",\n      \"command\": \"git\",\n      \"subcommand\": \"add\",\n      \"block_args\": [\"-A\", \"--all\", \".\"],\n      \"reason\": \"请使用 'git add \u003C具体文件>'，而不是一次性添加所有文件。\"\n    }\n  ]\n}\n```\n\n现在，`git add -A`、`git add --all` 和 `git add .` 都将被阻止，并显示您的自定义消息。\n\n### 配置文件位置\n\n配置文件从两个作用域加载并合并：\n\n1. **用户作用域**：`~\u002F.cc-safety-net\u002Fconfig.json`（如果存在则始终加载）\n2. **项目作用域**：当前工作目录中的 `.safety-net.json`（如果存在则加载）\n\n**合并行为**：\n- 来自两个作用域的规则会被合并\n- 如果两个作用域中存在同名规则，则 **项目作用域优先**\n- 规则名称比较不区分大小写（`MyRule` 和 `myrule` 被视为重复）\n\n这使得您可以在用户作用域中定义个人默认规则，同时允许项目覆盖特定规则。\n\n如果在任一位置都没有找到配置文件，则仅应用内置规则。\n\n### 配置模式\n\n| 字段 | 类型 | 必需 | 描述 |\n|-------|------|----------|-------------|\n| `version` | 整数 | 是 | 模式版本（必须为 `1`） |\n| `rules` | 数组 | 否 | 自定义阻止规则列表（默认为空） |\n\n### 规则模式\n\n| 字段 | 类型 | 必需 | 描述 |\n|-------|------|----------|-------------|\n| `name` | 字符串 | 是 | 唯一标识符（字母、数字、连字符、下划线；最多 64 个字符） |\n| `command` | 字符串 | 是 | 要匹配的基础命令（例如 `git`、`npm`、`docker`） |\n| `subcommand` | 字符串 | 否 | 要匹配的子命令（例如 `add`、`install`）。如果省略，则匹配任何子命令。 |\n| `block_args` | 数组 | 是 | 触发阻止的参数（至少需要一个） |\n| `reason` | 字符串 | 是 | 被阻止时显示的消息（最多 256 个字符） |\n\n### 匹配行为\n\n- **命令**会被规范化为基本名称（`\u002Fusr\u002Fbin\u002Fgit` → `git`）\n- **子命令**是命令之后的第一个非选项参数\n- **参数**会逐字匹配（不使用正则表达式或通配符），短选项会被展开\n- 如果 `block_args` 中的 **任意一个** 参数出现，命令就会被阻止\n- **短选项**会被展开：`-Ap` 会匹配 `-A`（捆绑的标志会被拆开）\n- **长选项**采用精确匹配：`--all-files` 不会匹配 `--all`\n- 自定义规则只会增加限制——它们不能绕过内置保护。\n\n#### 已知局限性\n\n- **短选项展开**：`-Cfoo` 会被视为 `-C -f -o -o`，而不是 `-C foo`。阻止 `-f` 可能会导致对附加选项值的误判。\n\n### 示例\n\n#### 阻止全局 npm 安装\n\n```json\n{\n  \"version\": 1,\n  \"rules\": [\n    {\n      \"name\": \"block-npm-global\",\n      \"command\": \"npm\",\n      \"subcommand\": \"install\",\n      \"block_args\": [\"-g\", \"--global\"],\n      \"reason\": \"全局 npm 安装可能导致版本冲突。请使用 npx 或本地安装。\"\n    }\n  ]\n}\n```\n\n#### 阻止危险的 Docker 命令\n\n```json\n{\n  \"version\": 1,\n  \"rules\": [\n    {\n      \"name\": \"block-docker-system-prune\",\n      \"command\": \"docker\",\n      \"subcommand\": \"system\",\n      \"block_args\": [\"prune\"],\n      \"reason\": \"docker system prune 会移除所有未使用的数据。建议使用更精确的清理方式。\"\n    }\n  ]\n}\n```\n\n#### 多条规则\n\n```json\n{\n  \"version\": 1,\n  \"rules\": [\n    {\n      \"name\": \"block-git-add-all\",\n      \"command\": \"git\",\n      \"subcommand\": \"add\",\n      \"block_args\": [\"-A\", \"--all\", \".\", \"-u\", \"--update\"],\n      \"reason\": \"请使用 'git add \u003C具体文件>'，而不是一次性添加所有文件。\"\n    },\n    {\n      \"name\": \"block-npm-global\",\n      \"command\": \"npm\",\n      \"subcommand\": \"install\",\n      \"block_args\": [\"-g\", \"--global\"],\n      \"reason\": \"请使用 npx 或本地安装，而非全局安装。\"\n    }\n  ]\n}\n```\n\n### 错误处理\n\n自定义规则采用**静默回退**的错误处理机制。如果您的配置文件无效，安全网将静默回退到仅使用内置规则：\n\n| 场景 | 行为 |\n|----------|----------|\n| 未找到配置文件 | 静默 — 仅使用内置规则 |\n| 空配置文件 | 静默 — 仅使用内置规则 |\n| JSON 语法无效 | 静默 — 仅使用内置规则 |\n| 缺少必填字段 | 静默 — 仅使用内置规则 |\n| 字段格式无效 | 静默 — 仅使用内置规则 |\n| 规则名称重复 | 静默 — 仅使用内置规则 |\n\n\n> [!重要]  \n> 如果您手动添加或修改自定义规则，请务必使用 `npx -y cc-safety-net --verify-config` 或编码代理中的 `\u002Fverify-custom-rules` 斜杠命令对其进行验证。\n\n### 阻断输出格式\n\n当自定义规则阻止某个命令时，输出中会包含规则名称：\n\n```text\n被安全网阻止\n\n原因：[block-git-add-all] 请使用 'git add \u003C具体文件>'，而不是一次性添加所有文件。\n\n命令：git add -A\n```\n\n## 高级功能\n\n### 严格模式\n\n默认情况下，无法解析的命令会被允许通过。启用严格模式后，当钩子输入或 shell 命令无法被安全分析时（例如，JSON 格式无效、引号未闭合、`bash -c` 包装格式错误），系统将采取失败关闭策略：\n\n```bash\nexport SAFETY_NET_STRICT=1\n```\n\n### 强硬模式\n\n强硬模式会启用更为严格的安全检查，这可能会对正常工作流程造成干扰。您可以全局启用，也可以通过特定开关进行启用：\n\n```bash\n# 启用所有强硬检查\nexport SAFETY_NET_PARANOID=1\n\n# 或者启用特定的强硬检查\nexport SAFETY_NET_PARANOID_RM=1\nexport SAFETY_NET_PARANOID_INTERPRETERS=1\n```\n\n强硬行为：\n\n- **rm**：即使在当前工作目录内，也会阻止非临时性的 `rm -rf` 命令。\n- **解释器**：会阻止类似 `python -c`、`node -e`、`ruby -e` 和 `perl -e` 这样的解释器单行命令（这些命令可能隐藏破坏性操作）。\n\n### Shell 包装检测\n\n该防护机制会递归分析被 shell 包装的命令：\n\n```bash\nbash -c 'git reset --hard'    # 被阻止\nsh -lc 'rm -rf \u002F'             # 被阻止\n```\n\n### 解释器单行命令检测\n\n能够检测隐藏在 Python\u002FNode\u002FRuby\u002FPerl 单行命令中的破坏性操作：\n\n```bash\npython -c 'import os; os.system(\"rm -rf \u002F\")'  # 被阻止\n```\n\n### 敏感信息脱敏\n\n阻断消息会自动脱敏敏感数据（如令牌、密码、API 密钥），以防止日志中泄露机密信息。\n\n### 审计日志记录\n\n所有被阻断的命令都会被记录到 `~\u002F.cc-safety-net\u002Flogs\u002F\u003Csession_id>.jsonl` 文件中，用于审计目的：\n\n```json\n{\"ts\": \"2025-01-15T10:30:00Z\", \"command\": \"git reset --hard\", \"segment\": \"git reset --hard\", \"reason\": \"...\", \"cwd\": \"\u002Fpath\u002Fto\u002Fproject\"}\n```\n\n日志条目中的敏感数据会被自动脱敏。\n\n## 许可证\n\nMIT","# Claude Code Safety Net 快速上手指南\n\n**Claude Code Safety Net** 是一个专为 Claude Code 及其他 AI 编程助手设计的安全插件。它作为一道“安全网”，在破坏性的 Git 命令或文件系统操作执行之前进行拦截，防止 AI 代理误删文件或丢失代码进度。\n\n## 环境准备\n\n在开始之前，请确保您的开发环境满足以下要求：\n\n*   **Node.js**: 版本需为 **18** 或更高。\n*   **支持的 CLI 工具**:\n    *   Claude Code (主要支持)\n    *   OpenCode\n    *   Gemini CLI\n    *   GitHub Copilot CLI\n*   **包管理器 (可选但推荐)**: 推荐使用 `bun` 以获得最佳性能，同时也支持 `npm`\u002F`npx`。\n\n> **注意**：国内用户若遇到网络连接问题，建议配置国内镜像源（如淘宝镜像）或使用代理加速 Node.js 包的下载。\n\n## 安装步骤\n\n根据您的使用场景，选择对应的安装方式：\n\n### 1. Claude Code (官方推荐)\n\n通过内置插件市场安装，支持自动更新：\n\n```bash\n\u002Fplugin marketplace add kenryu42\u002Fcc-marketplace\n\u002Fplugin install safety-net@cc-marketplace\n\u002Freload-plugins\n```\n\n**开启自动更新**：\n运行 `\u002Fplugin` -> 选择 `Marketplaces` -> 选择 `cc-marketplace` -> 启用 auto-update。\n\n### 2. OpenCode\n\n**方式 A：让 LLM 自动配置**\n在任何 LLM 代理中输入以下指令：\n```text\nInstall the cc-safety-net plugin in `~\u002F.config\u002Fopencode\u002Fopencode.json` (or `.jsonc`) according to the schema at: https:\u002F\u002Fopencode.ai\u002Fconfig.json\n```\n\n**方式 B：手动配置**\n编辑配置文件 `~\u002F.config\u002Fopencode\u002Fopencode.json` (或 `.jsonc`)，添加以下内容：\n```json\n{\n  \"plugin\": [\"cc-safety-net\"]\n}\n```\n\n### 3. Gemini CLI\n\n```bash\ngemini extensions install https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fgemini-safety-net\n```\n\n### 4. GitHub Copilot CLI\n\n```bash\n\u002Fplugin install kenryu42\u002Fcopilot-safety-net\n```\n> 安装完成后，请**重启** Copilot CLI 以使插件生效。\n\n## 基本使用\n\n安装完成后，插件默认立即生效，无需额外配置即可拦截高危命令（如 `rm -rf`、`git reset --hard` 等）。\n\n### 查看保护状态（状态栏集成）\n\n您可以在 Claude Code 的状态栏实时查看安全网的运行状态（是否激活、当前模式等）。\n\n**一键配置（推荐）：**\n在 Claude Code 中运行以下斜杠命令，按向导完成设置：\n```bash\n\u002Fset-statusline\n```\n\n**手动配置：**\n如果您希望手动编辑，请将以下配置添加到 `~\u002F.claude\u002Fsettings.json` 中。\n\n*使用 Bun (推荐):*\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"bunx cc-safety-net --statusline\"\n  }\n}\n```\n\n*使用 NPM:*\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"npx -y cc-safety-net --statusline\"\n  }\n}\n```\n\n*与现有状态栏命令共存:*\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"your-existing-command | bunx cc-safety-net --statusline\"\n  }\n}\n```\n\n### 状态指示器说明\n\n配置成功后，状态栏将显示不同的图标代表当前保护级别：\n\n| 状态 | 显示示例 | 含义 |\n| :--- | :--- | :--- |\n| **未启用** | `🛡️ Safety Net ❌` | 插件未运行 |\n| **默认模式** | `🛡️ Safety Net ✅` | 正常保护，拦截已知破坏性命令 |\n| **严格模式** | `🛡️ Safety Net 🔒` | `SAFETY_NET_STRICT=1`，无法解析的命令将被阻止 |\n| **偏执模式** | `🛡️ Safety Net 👁️` | `SAFETY_NET_PARANOID=1`，启用所有高级检查 |\n\n### 进阶模式切换（可选）\n\n您可以通过设置环境变量来改变保护策略：\n\n*   **严格模式** (遇到无法解析的命令直接阻断):\n    ```bash\n    export SAFETY_NET_STRICT=1\n    ```\n*   **偏执模式** (启用更广泛的检查，包括解释器单行命令检测等):\n    ```bash\n    export SAFETY_NET_PARANOID=1\n    ```\n\n现在，您可以放心地让 AI 助手编写代码，Safety Net 将在底层为您守护文件系统安全。","资深后端工程师小李正利用 Claude Code 辅助重构一个遗留微服务项目，试图清理冗余代码并优化 Git 提交历史。\n\n### 没有 claude-code-safety-net 时\n- AI 在理解“清理未使用文件”指令时产生幻觉，误将包含核心业务逻辑的 `src\u002Futils\u002Flegacy` 目录当作垃圾文件，准备执行 `rm -rf` 删除。\n- 当被要求“重置混乱的提交记录”时，AI 直接运行了 `git reset --hard HEAD~5`，导致过去两天精心编写的功能分支代码瞬间丢失且无法找回。\n- 仅靠 `CLAUDE.md` 中的文字警告无法形成硬性约束，AI 仍可能忽略上下文提示，在复杂推理链中触发危险命令。\n- 一旦破坏性命令执行，开发者只能依赖本地备份或远程仓库强制回滚，严重打断开发心流并造成数小时的工作损失。\n\n### 使用 claude-code-safety-net 后\n- claude-code-safety-net 作为前置钩子拦截了指令，通过语义分析识别出 `rm -rf` 针对的是非空业务目录，直接在执行前阻断并报警。\n- 面对 `git reset --hard` 请求，工具检测到该操作会丢弃未提交的更改，立即阻止执行并建议更安全的 `git stash` 替代方案。\n- 无需手动配置复杂的通配符拒绝规则，工具开箱即用，自动覆盖各类变形的 Shell 包装器和解释器单行命令。\n- 系统在状态栏实时显示拦截详情，让小李在不中断对话的情况下确认风险，既保障了代码库安全又维持了高效的协作节奏。\n\nclaude-code-safety-net 将原本依赖自觉的“软性提醒”升级为不可绕过的“硬性防线”，彻底消除了 AI 编程助手误删库或清空历史的灾难性风险。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fkenryu42_claude-code-safety-net_001cc94b.png","kenryu42","J Liew","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Fkenryu42_7a433180.png",null,"Japan","jliew@420024lab.com","https:\u002F\u002Fgithub.com\u002Fkenryu42",[23,27,31],{"name":24,"color":25,"percentage":26},"TypeScript","#3178c6",99.2,{"name":28,"color":29,"percentage":30},"JavaScript","#f1e05a",0.7,{"name":32,"color":33,"percentage":34},"Shell","#89e051",0,1223,56,"2026-04-03T14:28:34","MIT",2,"Linux, macOS, Windows","未说明",{"notes":43,"python":41,"dependencies":44},"该工具是一个 Node.js 插件，主要用于拦截破坏性的 git 和文件系统命令。它不依赖 GPU 或大量内存，核心运行环境要求是安装 Node.js 18 或更高版本。支持通过插件市场或直接配置安装在 Claude Code、OpenCode、Gemini CLI 和 GitHub Copilot CLI 中。建议使用 bunx 或 npx 运行状态行集成。",[45,46,47,48,49],"Node.js >= 18","Claude Code","OpenCode","Gemini CLI","GitHub Copilot CLI",[51],"插件",[53,54,55,56,57,58],"claude","claude-code","claude-code-plugin","security","destructive-commands","hook","ready","2026-03-27T02:49:30.150509","2026-04-06T06:45:19.294856",[63,68,73,78,83,87],{"id":64,"question_zh":65,"answer_zh":66,"source_url":67},14272,"在 Windows 上运行时提示找不到 'python3' 命令怎么办？","该问题已在 v0.4.0 版本中解决。插件现在要求使用 Node.js 18+ 而不是 Python。请更新到最新版本：\n1. 更新插件至 v0.4.0 或更高版本。\n2. 确保系统已安装 Node.js 18+。\n更新后，Windows 用户无需再配置 python3.exe 即可正常使用安全网功能。","https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net\u002Fissues\u002F2",{"id":69,"question_zh":70,"answer_zh":71,"source_url":72},14273,"PreToolUse 钩子执行非常慢（约 7 秒），如何优化速度？","该性能问题已在 v0.6.0 版本中修复。慢速原因是原本的配置使用 `npx -y` 每次都会检查 npm 注册表。\n解决方案：\n1. 将插件升级到 v0.6.0 或更高版本。\n2. 新版本已将二进制文件直接捆绑在插件中，不再依赖 npx 动态下载，执行时间从约 7 秒降低至约 350 毫秒。\n无需手动修改 hooks.json 或全局安装 npm 包。","https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net\u002Fissues\u002F16",{"id":74,"question_zh":75,"answer_zh":76,"source_url":77},14274,"如何在 GitHub Copilot CLI 中使用 safety-net 进行保护？","GitHub Copilot CLI 现已原生支持插件，无需复杂的钩子配置。\n直接使用以下命令安装插件：\n\u002Fcopilot install kenryu42\u002Fcopilot-safety-net\n此外，v0.8.0 版本还为 doctor 命令添加了 Copilot CLI 支持。如果遇到 bug，欢迎提交 Issue 或 PR。","https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net\u002Fissues\u002F24",{"id":79,"question_zh":80,"answer_zh":81,"source_url":82},14275,"在 VS Code 扩展中插件似乎没有拦截危险命令（只记录不阻止），如何解决？","这通常是由于环境缓存或扩展状态不同步导致的临时性问题。\n尝试以下步骤：\n1. 重启 VS Code 和终端。\n2. 如果问题依旧，尝试重启电脑（有用户反馈重启后自动恢复正常）。\n3. 确保插件和 Claude Code 扩展均为最新版本。\n如果问题持续存在，作为临时变通方案，可以在 `.claude\u002Fsettings.json` 中添加显式的拒绝规则：\n{\n  \"permissions\": {\n    \"Bash\": {\n      \"deny\": [\"git reset --hard\", \"git checkout --\", \"rm -rf\"]\n    }\n  }\n}","https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net\u002Fissues\u002F11",{"id":84,"question_zh":85,"answer_zh":86,"source_url":67},14276,"Windows 上 'python3' 命令指向微软商店占位符导致额外延迟，如何处理？","虽然最新版插件已移除对 Python 的依赖（改用 Node.js），但如果仍遇到类似问题，原因通常是 Windows 的 `python3.exe` 是微软商店的别名（stub），调用失败需耗时约 134ms。\n解决方法：\n1. （推荐）升级插件至 v0.4.0+，完全移除 Python 依赖。\n2. （旧版临时方案）在 Windows 设置中禁用 \"App Execution Aliases\" 里的 python3.exe，或直接删除该占位符文件。\n3. （旧版临时方案）复制真实的 python.exe 为 python3.exe：copy C:\\Python313\\python.exe C:\\Python313\\python3.exe",{"id":88,"question_zh":89,"answer_zh":90,"source_url":82},14277,"如何验证当前安装的安全网插件是否正常工作？","可以通过以下方式验证：\n1. 观察日志：当执行危险命令（如 `rm -rf`）时，检查是否有安全网的拦截日志输出。\n2. 功能测试：尝试执行一个被禁止的命令，确认其被实际阻断而不仅仅是记录。\n3. 版本检查：运行相关诊断命令（如新版中的 doctor 命令）查看集成状态。\n如果在 VS Code 中发现只记录不拦截，请尝试重启 IDE 或检查版本兼容性。",[92,97,102,107,112,117,122,127,132,137,142,147,152,157,162,167],{"id":93,"version":94,"summary_zh":95,"released_at":96},81013,"v0.8.2","### 修复\n\n- 允许对明确的临时目录目标（如 `\u002Ftmp\u002F...`、`\u002Fvar\u002Ftmp\u002F...` 和 `$TMPDIR\u002F...`）执行 `rm -rf` 操作，即使当前工作目录是 `$HOME`\n- 将主目录下的 `rm` 分类逻辑移至共享的 `rules-rm` 分析器中，以便阻止决策和 `explain` 输出遵循相同的基于目标的路径\n\n### 相关问题\n\n- 问题 [#41](https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net\u002Fissues\u002F41)：误报会阻止合法的清理操作以及 gh 命令中的字符串字面量\n\n### 相关 PR\n\n- PR [#42](https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net\u002Fpull\u002F42)：修复（rules-rm）：当当前工作目录为主目录时，允许临时目标","2026-03-25T06:04:48",{"id":98,"version":99,"summary_zh":100,"released_at":101},81014,"v0.8.1","### 新功能\n\n- 在 `doctor` 命令中，通过 `copilot plugin list` 检测 `copilot-safety-net` 插件的安装情况。\n\n### 修复\n\n- 当通过插件流程检测到 Copilot CLI 时，一致地填充 `configPath`。\n- 在基于插件的 Copilot CLI 检测中，将 `copilot-plugin` 报告为配置路径。\n\n### 相关 PR\n\n- PR [#40](https:\u002F\u002Fgithub.com\u002Fkenryu42\u002Fclaude-code-safety-net\u002Fpull\u002F40)：特性：在 `doctor` 命令中添加 Copilot CLI 插件检测。","2026-03-24T15:14:43",{"id":103,"version":104,"summary_zh":105,"released_at":106},81015,"v0.8.0","### 新特性\n\n- 为 GitHub Copilot CLI 的 `doctor` 命令添加支持，包括检测仓库钩子文件、用户钩子文件以及内联 Copilot 设置中的 Safety Net 钩子，并提供基于版本的诊断信息。\n- 禁用 `git switch --force`、`git switch --discard-changes` 以及 `git checkout --force` \u002F `-f`。\n\n### 变更\n\n- 在 `doctor` 输出中显示检测到的 Copilot CLI 版本，并更快速、更可靠地探测 Copilot 版本命令。\n- 扩展 Copilot CLI 的设置文档，涵盖钩子文件和内联配置变体、配置优先级、`disableAllHooks` 选项以及 `COPILOT_HOME` 环境变量。\n\n### 修复\n\n- 修复了 `TMPDIR` 路径遍历绕过漏洞，防止非临时路径覆盖逃逸至 `\u002Ftmp`、`\u002Fvar\u002Ftmp` 或系统临时目录之外。\n- 加强 Shell 解析机制，确保在重定向、嵌套命令替换、算术扩展、分组子 Shell、进程替换以及反引号中也能正确检测到破坏性命令。\n- 修复了 `git checkout` 在处理歧义引用\u002F路径规范时的参数解析问题，并修正了对未明确分类为值型标志的选项变体（如 `git switch -cfeature`）的误判。","2026-03-21T04:44:55",{"id":108,"version":109,"summary_zh":110,"released_at":111},81016,"v0.7.1","## 核心\n- c439be8 修复：在路径规范化中去除尾部分隔符，以便跨平台比较\n- 33012b1 修复：在 explain config 中将当前工作目录解析为绝对路径\n- 300ee42 修复：在 rm 命令分析中处理 Windows 路径分隔符\n- a4db304 修复：Windows 路径分隔符\n\n## Claude Code\n本次发布无变更\n\n## OpenCode\n本次发布无变更","2026-01-25T15:04:23",{"id":113,"version":114,"summary_zh":115,"released_at":116},81017,"v0.7.0","## 核心\n- 25c18a2 功能：添加 explain 命令和结构化的 CLI 帮助\n- 976e382 修复：为会话 ID 中缺失的时间戳添加回退机制\n- e187b3f 修复：将 outputDeny 重命名为 outputCopilotDeny\n- db01a91 功能：添加 GitHub Copilot CLI 钩子集成\n\n## Claude Code\n本次发布无变更\n\n## OpenCode\n本次发布无变更\n\n**感谢 1 位社区贡献者：**\n- @crmitchelmore：\n  - 功能：添加 GitHub Copilot CLI 钩子集成\n  - 修复：将 outputDeny 重命名为 outputCopilotDeny\n  - 修复：为会话 ID 中缺失的时间戳添加回退机制","2026-01-23T19:08:39",{"id":118,"version":119,"summary_zh":120,"released_at":121},81018,"v0.6.2","## 核心\n- 58cc257 功能：添加医生命令诊断功能\n\n## Claude Code\n- 44cb35c 修复（Windows）：显式使用 node 调用 cc-safety-net.js\n\n## OpenCode\n本次发布无变更\n\n---\n\n感谢 @jacoballen4534 在 #21 中识别并提出了 Windows 支持的修复方案。","2026-01-19T09:38:59",{"id":123,"version":124,"summary_zh":125,"released_at":126},81019,"v0.6.0","## 核心\n- 5e3b4d8 功能：添加状态栏命令\n- b2eed5e 修复：阻止递归深度过大的命令\n\n## Claude Code\n- e121857 功能：添加 \u002Fset-statusline 斜杠命令\n- 8b0bb67 修复：在钩子中使用本地二进制文件，而非 npx，以提高执行速度\n\n## OpenCode\n本次发布无变更\n\n---\n\n感谢 @lgandecki 指出 npx 的性能开销问题。","2026-01-15T17:05:48",{"id":128,"version":129,"summary_zh":130,"released_at":131},81020,"v0.5.1","## 核心\n- 6f40164 功能：为 opencode 插件添加内置命令\n\n## Claude Code\n本次发布无变更\n\n## OpenCode\n本次发布无变更","2026-01-11T17:59:54",{"id":133,"version":134,"summary_zh":135,"released_at":136},81021,"v0.5.0","## 核心\n- cfb5b25 修复：在 Gemini 钩子测试中清空 stderr\n- 5075018 功能：添加 Gemini CLI 兼容性\n\n## Claude Code\n本次发布无变更\n\n## OpenCode\n本次发布无变更","2026-01-10T18:45:46",{"id":138,"version":139,"summary_zh":140,"released_at":141},81022,"v0.4.1","## 核心\n本次发布无变更\n\n## Claude Code\n- 997bb25 修复(commands): 简化 verify-custom-rules 文档\n- 23dd9e1 修复(commands): 改进 set-custom-rules 流程及 schema 文档\n\n## OpenCode\n- b656671 功能(.opencode): 添加 OpenCode 命令定义","2026-01-08T17:35:31",{"id":143,"version":144,"summary_zh":145,"released_at":146},81023,"v0.4.0","## Core\r\n- 09aedb4 feat: add VERSION constant synchronization in bin file during publish\r\n- 415509e feat: add plugin.json version synchronization in publish script\r\n- e1ccc2d feat: add automated npm publishing script with changelog generation\r\n- aac915e fix: use GITHUB_REPOSITORY env var in changelog script\r\n- 02e0f7a feat: add schema build script\r\n- 980e8b2 feat: auto-add $schema to config files during verification\r\n- d464897 fix: improve TMPDIR override detection and implement strict mode\r\n- 9b3e56c fix: handle TMPDIR edge cases in override detection\r\n- e890307 feat: add paranoid mode support to OpenCode plugin\r\n- a6abab9 fix: use cwd from hook input instead of tool_input.workdir\r\n- 819ab9a fix: update HookInput type to match Claude Code schema\r\n- e1a0700 fix: handle undefined cwd in loadConfig\r\n- 1435c59 feat: display blocked segment in OpenCode plugin errors\r\n- 2f58977 feat: display blocked segment in deny output\r\n- 91acb1b feat: add AnalyzeResult type for structured block info\r\n- 1e298cb feat: rewrite from python to typescript\r\n\r\n## Claude Code\r\n- ac46e94 fix: remove extra quotes from hook command path\r\n","2026-01-07T11:27:47",{"id":148,"version":149,"summary_zh":150,"released_at":151},81024,"v0.3.2","## v0.3.2 (2026-01-03)\n\n### Fix\n\n- add AskUserQuestion tool to improve UX","2026-01-02T16:11:28",{"id":153,"version":154,"summary_zh":155,"released_at":156},81025,"v0.3.1","## v0.3.1 (2026-01-02)\n\n### Fix\n\n- Add cross-platform script execution compatibility","2026-01-02T13:25:55",{"id":158,"version":159,"summary_zh":160,"released_at":161},81026,"v0.3.0","## v0.3.0 (2026-01-01)\n\n### Feat\n\n- add short option expansion to custom rule matching\n- add commands for custom rules management\n- detect find -exec rm -rf as destructive pattern\n- add verify_config script for config validation\n- integrate custom rules into hook analysis\n- add custom rule matching logic\n- add config loading module for user-configurable rules\n\n### Fix\n\n- stop _short_opts parsing at non-alpha chars and -- marker\n- Block rm -rf of cwd itself even when under \u002Ftmp\u002F\n\n### Refactor\n\n- improve verify_config output formatting\n- return ValidationResult from validate_config_file","2026-01-01T12:37:11",{"id":163,"version":164,"summary_zh":165,"released_at":166},81027,"v0.2.0","## v0.2.0 (2025-12-29)\n\n### Feat\n\n- add audit logging for denied commands\n- add paranoid mode environment variable checks\n- detect dangerous commands via xargs and parallel\n- block git worktree remove --force\n- block git checkout \u003Cref> \u003Cpathspec> without --\n- block find -delete destructive command\n\n### Fix\n\n- Add cross-platform script execution compatibility\n- recognize rm -R (uppercase) as recursive and respect -- delimiter\n- preserve case sensitivity for git branch -D detection\n\n### Refactor\n\n- rename strict to paranoid for rm rule parameter","2025-12-29T06:00:36",{"id":168,"version":169,"summary_zh":170,"released_at":171},81028,"v0.1.0","## v0.1.0 (2025-12-26)\n\n### Feat\n\n- initial implementation","2025-12-25T17:56:18",[173,189,198,206,214,222],{"id":174,"name":175,"github_repo":176,"description_zh":177,"stars":178,"difficulty_score":39,"last_commit_at":179,"category_tags":180,"status":59},2268,"ML-For-Beginners","microsoft\u002FML-For-Beginners","ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程，旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周，包含 26 节精炼课程和 52 道配套测验，内容涵盖从基础概念到实际应用的完整流程，有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。\n\n无论是希望转型的开发者、需要补充算法背景的研究人员，还是对人工智能充满好奇的普通爱好者，都能从中受益。课程不仅提供了清晰的理论讲解，还强调动手实践，让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持，通过自动化机制提供了包括简体中文在内的 50 多种语言版本，极大地降低了全球不同背景用户的学习门槛。此外，项目采用开源协作模式，社区活跃且内容持续更新，确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路，ML-For-Beginners 将是理想的起点。",84991,"2026-04-05T10:45:23",[181,182,183,51,184,185,186,187,188],"图像","数据工具","视频","Agent","其他","语言模型","开发框架","音频",{"id":190,"name":191,"github_repo":192,"description_zh":193,"stars":194,"difficulty_score":195,"last_commit_at":196,"category_tags":197,"status":59},2181,"OpenHands","OpenHands\u002FOpenHands","OpenHands 是一个专注于 AI 驱动开发的开源平台，旨在让智能体（Agent）像人类开发者一样理解、编写和调试代码。它解决了传统编程中重复性劳动多、环境配置复杂以及人机协作效率低等痛点，通过自动化流程显著提升开发速度。\n\n无论是希望提升编码效率的软件工程师、探索智能体技术的研究人员，还是需要快速原型验证的技术团队，都能从中受益。OpenHands 提供了灵活多样的使用方式：既可以通过命令行（CLI）或本地图形界面在个人电脑上轻松上手，体验类似 Devin 的流畅交互；也能利用其强大的 Python SDK 自定义智能体逻辑，甚至在云端大规模部署上千个智能体并行工作。\n\n其核心技术亮点在于模块化的软件智能体 SDK，这不仅构成了平台的引擎，还支持高度可组合的开发模式。此外，OpenHands 在 SWE-bench 基准测试中取得了 77.6% 的优异成绩，证明了其解决真实世界软件工程问题的能力。平台还具备完善的企业级功能，支持与 Slack、Jira 等工具集成，并提供细粒度的权限管理，适合从个人开发者到大型企业的各类用户场景。",70612,3,"2026-04-05T11:12:22",[186,184,187,51],{"id":199,"name":200,"github_repo":201,"description_zh":202,"stars":203,"difficulty_score":39,"last_commit_at":204,"category_tags":205,"status":59},3074,"gpt4free","xtekky\u002Fgpt4free","gpt4free 是一个由社区驱动的开源项目，旨在聚合多种可访问的大型语言模型（LLM）和媒体生成接口，让用户能更灵活、便捷地使用前沿 AI 能力。它解决了直接调用各类模型时面临的接口分散、门槛高或成本昂贵等痛点，通过统一的标准将不同提供商的资源整合在一起。\n\n无论是希望快速集成 AI 功能的开发者、需要多模型对比测试的研究人员，还是想免费体验最新技术的普通用户，都能从中受益。gpt4free 提供了丰富的使用方式：既包含易于上手的 Python 和 JavaScript 客户端库，也支持部署本地图形界面（GUI），更提供了兼容 OpenAI 标准的 REST API，方便无缝替换现有应用后端。\n\n其技术亮点在于强大的多提供商支持架构，能够动态调度包括 Opus、Gemini、DeepSeek 等多种主流模型资源，并支持 Docker 一键部署及本地推理。项目秉持社区优先原则，在降低使用门槛的同时，也为贡献者提供了扩展新接口的便利框架，是探索和利用多样化 AI 资源的实用工具。",65970,"2026-04-04T01:02:03",[51,186,184],{"id":207,"name":208,"github_repo":209,"description_zh":210,"stars":211,"difficulty_score":39,"last_commit_at":212,"category_tags":213,"status":59},51,"gstack","garrytan\u002Fgstack","gstack 是 Y Combinator CEO Garry Tan 亲自开源的一套 AI 工程化配置，旨在将 Claude Code 升级为你的虚拟工程团队。面对单人开发难以兼顾产品战略、架构设计、代码审查及质量测试的挑战，gstack 提供了一套标准化解决方案，帮助开发者实现堪比二十人团队的高效产出。\n\n这套配置特别适合希望提升交付效率的创始人、技术负责人，以及初次尝试 Claude Code 的开发者。gstack 的核心亮点在于内置了 15 个具有明确职责的 AI 角色工具，涵盖 CEO、设计师、工程经理、QA 等职能。用户只需通过简单的斜杠命令（如 `\u002Freview` 进行代码审查、`\u002Fqa` 执行测试、`\u002Fplan-ceo-review` 规划功能），即可自动化处理从需求分析到部署上线的全链路任务。\n\n所有操作基于 Markdown 和斜杠命令，无需复杂配置，完全免费且遵循 MIT 协议。gstack 不仅是一套工具集，更是一种现代化的软件工厂实践，让单人开发者也能拥有严谨的工程流程。",64261,"2026-04-05T11:08:43",[184,51],{"id":215,"name":216,"github_repo":217,"description_zh":218,"stars":219,"difficulty_score":39,"last_commit_at":220,"category_tags":221,"status":59},193,"meilisearch","meilisearch\u002Fmeilisearch","Meilisearch 是一个开源的极速搜索服务，专为现代应用和网站打造，开箱即用。它能帮助开发者快速集成高质量的搜索功能，无需复杂的配置或额外的数据预处理。传统搜索方案往往需要大量调优才能实现准确结果，而 Meilisearch 内置了拼写容错、同义词识别、即时响应等实用特性，并支持 AI 驱动的混合搜索（结合关键词与语义理解），显著提升用户查找信息的体验。\n\nMeilisearch 特别适合 Web 开发者、产品团队或初创公司使用，尤其适用于需要快速上线搜索功能的场景，如电商网站、内容平台或 SaaS 应用。它提供简洁的 RESTful API 和多种语言 SDK，部署简单，资源占用低，本地开发或生产环境均可轻松运行。对于希望在不依赖大型云服务的前提下，为用户提供流畅、智能搜索体验的团队来说，Meilisearch 是一个高效且友好的选择。",56964,"2026-04-05T08:19:14",[181,184,182,187,51,185],{"id":223,"name":224,"github_repo":225,"description_zh":226,"stars":227,"difficulty_score":39,"last_commit_at":228,"category_tags":229,"status":59},4022,"awesome-claude-skills","ComposioHQ\u002Fawesome-claude-skills","awesome-claude-skills 是一个精心整理的开源资源库，旨在帮助用户挖掘和扩展 Claude AI 的潜力。它不仅仅是一份列表，更提供了实用的“技能（Skills）”模块，让 Claude 从单纯的文本生成助手，进化为能执行复杂工作流的智能代理。\n\n许多用户在使用 AI 时，常受限于其无法直接操作外部软件或处理特定格式文件的痛点。awesome-claude-skills 通过预设的工作流解决了这一问题：它不仅能教会 Claude 专业地处理 Word、PDF 等文档，进行代码开发与数据分析，还能借助 Composio 插件连接 Slack、邮箱及数百种常用应用，实现发送邮件、创建任务等自动化操作。这使得重复性任务变得标准化且可复用，极大提升了工作效率。\n\n无论是希望优化日常办公流程的普通用户、需要处理复杂文档的研究人员，还是寻求将 AI 深度集成到开发管线中的开发者，都能从中找到适合的解决方案。其独特的技术亮点在于“技能”的可定制性与强大的应用连接能力，让用户无需编写复杂代码，即可通过简单的配置让 Claude 具备跨平台执行真实任务的能力。如果你希望让 Claude",51312,"2026-04-05T19:04:23",[184,51]]