{"id":48764587,"url":"https://github.com/justi/claude-code-project-boundary","last_synced_at":"2026-04-13T07:47:07.020Z","repository":{"id":343340376,"uuid":"1177297103","full_name":"justi/claude-code-project-boundary","owner":"justi","description":"Claude Code plugin: scope-aware protection — allows destructive ops (rm, mv, chmod) within project, blocks them outside. Built for dangerouslySkipPermissions mode.","archived":false,"fork":false,"pushed_at":"2026-04-09T23:10:49.000Z","size":31,"stargazers_count":37,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-09T23:10:54.624Z","etag":null,"topics":["claude-code","claude-code-plugin","cli-safety","dangerously-skip-permissions","destructive-commands","developer-tools","project-boundary","safety"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/justi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-09T22:27:47.000Z","updated_at":"2026-04-09T22:31:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/justi/claude-code-project-boundary","commit_stats":null,"previous_names":["justi/claude-code-project-boundary"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/justi/claude-code-project-boundary","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justi%2Fclaude-code-project-boundary","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justi%2Fclaude-code-project-boundary/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justi%2Fclaude-code-project-boundary/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justi%2Fclaude-code-project-boundary/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/justi","download_url":"https://codeload.github.com/justi/claude-code-project-boundary/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justi%2Fclaude-code-project-boundary/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31744404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T06:26:45.479Z","status":"ssl_error","status_checked_at":"2026-04-13T06:26:44.645Z","response_time":93,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude-code","claude-code-plugin","cli-safety","dangerously-skip-permissions","destructive-commands","developer-tools","project-boundary","safety"],"created_at":"2026-04-13T07:47:06.465Z","updated_at":"2026-04-13T07:47:06.998Z","avatar_url":"https://github.com/justi.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Project Boundary — Claude Code Plugin\n\nAllows destructive operations **within your project** but blocks them **outside** the project directory. Built for `--dangerously-skip-permissions` mode where Claude doesn't ask — this plugin is your safety net.\n\n## How it differs from existing plugins\n\n- **[claude-code-safety-net](https://github.com/kenryu42/claude-code-safety-net)** — blocks `rm` everywhere; Project Boundary allows it inside the project so refactoring works normally.\n- **[destructive-command-guard](https://github.com/Dicklesworthstone/destructive_command_guard)** — only distinguishes `/tmp` vs everything else; Project Boundary uses `$CLAUDE_PROJECT_DIR` as the actual boundary.\n- **[claude-code-damage-control](https://github.com/disler/claude-code-damage-control)** — requires manually listing protected paths; Project Boundary automatically protects everything outside the project.\n\n## What it does\n\n### Boundary-checked (allowed inside project, blocked outside)\n\n| Operation | Inside project | Outside project |\n|-----------|---------------|-----------------|\n| `rm`, `rm -rf` | Allowed | **Blocked** |\n| `mv` (source and destination) | Allowed | **Blocked** |\n| `cp` (source and destination) | Allowed | **Blocked** |\n| `ln` (source and target) | Allowed | **Blocked** |\n| `chmod` / `chown` | Allowed | **Blocked** |\n| `\u003e` / `\u003e\u003e` redirect | Allowed | **Blocked** |\n| `tee` / `tee -a` | Allowed | **Blocked** |\n| `curl -o` / `curl --output` | Allowed | **Blocked** |\n| `wget -O` / `wget --output-document` | Allowed | **Blocked** |\n| `find -delete` / `find -exec rm` | Allowed | **Blocked** |\n| `dd of=` | Allowed | **Blocked** |\n| `install` (source and destination) | Allowed | **Blocked** |\n| `rsync` (source and destination) | Allowed | **Blocked** |\n| `tar -C` / `--directory=` | Allowed | **Blocked** |\n| `unzip -d` / `cpio -D` | Allowed | **Blocked** |\n| **Edit** tool (file edits) | Allowed | **Blocked** |\n| **MultiEdit** tool (multi-file edits) | Allowed | **Blocked** |\n| **Write** tool (file creation) | Allowed | **Blocked** |\n\n### Always blocked (unsafe to inspect)\n\n| Command | Reason |\n|---------|--------|\n| `bash -c \"...\"` / `sh -c \"...\"` | Nested shell — cannot inspect inner command |\n| `eval '...'` | Cannot safely parse evaluated code |\n| Piping to `sh` / `bash` | Inner commands invisible to guard |\n| `xargs rm/mv/cp/...` | Arguments cannot be validated |\n| `$(...)` / backticks (outside single quotes) | Command substitution target is uninspectable. Single-quoted forms like `'$(cmd)'` and arithmetic expansion `$((2+2))` are allowed. |\n\n### Additional protections\n\n- **Chained commands** — splits on `;`, `\u0026\u0026`, `||`, `|` and checks each sub-command independently\n- **`cwd` awareness** — uses `cwd` from the hook event, so commands run outside the project (without an explicit `cd`) are also guarded\n- **`cd` tracking** — `cd /tmp \u0026\u0026 rm -rf something` is blocked because `cd` left the project; `cd $PROJECT \u0026\u0026 rm file` is allowed even if the event `cwd` was outside\n- **Destructive subcommands outside project** — when running outside the project (via event `cwd` or `cd`), these are blocked: `git clean -f`, `git checkout .`, `git restore .`, `git reset --hard`, `git push --force`, `git stash drop/clear`, `git branch -D`, `git reflog expire`, `rails db:drop/reset`, `rake db:drop/reset`. Safe commands like `git status`, `git log`, `rails routes` remain allowed.\n- **`sudo` prefix** — stripped before checking, so `sudo rm /etc/passwd` is still blocked\n- **`find` options** — handles `-L`, `-H`, `-P` before the search path\n- **Path traversal** — `..` segments are resolved before boundary check\n- **`~` and `$HOME` expansion** — `rm ~/file` and `rm $HOME/file` are correctly detected as outside-project\n- **Symlink resolution** — handles macOS `/var` → `/private/var`, dereferences symlink chains in Edit/Write/MultiEdit (fail-closed after 20 hops)\n\n### Known limitations\n\n- Paths with spaces work when properly quoted (single or double quotes). Unquoted paths with spaces are not supported.\n- Heredoc body contents are not inspected (only the first line of the command, where redirects are handled normally)\n- Brace expansion (`{a,b,c}`) is not enumerated — literal match only\n- `~user/` (home of another user) is not expanded; only `~/` (current user) is handled\n\n## Install\n\nDirect:\n```\nclaude --plugin-dir /path/to/claude-code-project-boundary\n```\n\nFrom marketplace:\n```\n/plugin marketplace add davepoon/buildwithclaude\n/plugin install project-boundary@buildwithclaude\n```\n\n## How it works\n\nPure-bash PreToolUse hooks for Bash, Edit, MultiEdit, and Write tools. The Bash hook splits chained commands and resolves target paths (handling symlinks, `..`, `~`, `$HOME`); the Edit, MultiEdit, and Write hooks perform file path boundary checks against `$CLAUDE_PROJECT_DIR`. Dependencies: bash + jq.\n\n## Testing\n\n```\nbash tests/test_guard.sh\n```\n\nFull test suite covering all guard scenarios. CI runs on Ubuntu and macOS.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjusti%2Fclaude-code-project-boundary","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjusti%2Fclaude-code-project-boundary","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjusti%2Fclaude-code-project-boundary/lists"}