{"id":51133494,"url":"https://github.com/hyper0x/cmdguard","last_synced_at":"2026-06-25T15:01:25.043Z","repository":{"id":362856300,"uuid":"1261040699","full_name":"hyper0x/cmdguard","owner":"hyper0x","description":"A safety net for dangerous shell commands — intercept rm, mv, chmod with configurable protection levels, automatic backup, and undo.","archived":false,"fork":false,"pushed_at":"2026-06-19T07:19:17.000Z","size":220,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-19T08:29:12.789Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hyper0x.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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-06-06T06:54:00.000Z","updated_at":"2026-06-19T07:19:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hyper0x/cmdguard","commit_stats":null,"previous_names":["hyper0x/cmdguard"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/hyper0x/cmdguard","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyper0x%2Fcmdguard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyper0x%2Fcmdguard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyper0x%2Fcmdguard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyper0x%2Fcmdguard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyper0x","download_url":"https://codeload.github.com/hyper0x/cmdguard/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyper0x%2Fcmdguard/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34780126,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2026-06-25T15:01:24.198Z","updated_at":"2026-06-25T15:01:25.023Z","avatar_url":"https://github.com/hyper0x.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# cmdguard\n\n**Command protection tool** — guards `rm`, `mv`, `chmod` with confirmation, automatic backup, and undo.\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/hyper0x/cmdguard)](https://goreportcard.com/report/github.com/hyper0x/cmdguard)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n[简体中文](README.zh.md)\n\n\u003c/div\u003e\n\n---\n\n## Overview\n\ncmdguard wraps dangerous commands (`rm`, `mv`, `chmod`) to prevent accidental data loss.\n\n- 🚫 **Four protection levels** — reject, confirm_double, confirm, warn\n- 💾 **Automatic backup** — files are copied to a vault before destructive ops\n- ↩️ **Undo** — restore deleted or overwritten files via `cmdguard undo`\n- 📋 **Audit log** — every operation is recorded permanently; searchable \u0026 filterable\n- 🤖 **Agent-aware** — explicit handling for AI agents and automation (see below)\n- ⚙️ **TOML config** — glob path patterns, per-command overrides\n\n---\n\n## Design\n\n### Protecting humans\n\nAdd aliases to `~/.zshrc` or `~/.bashrc`:\n\n```bash\nalias rm='cmdguard rm'\nalias mv='cmdguard mv'\nalias chmod='cmdguard chmod'\n```\n\n### Protecting AI agents\n\nPut cmdguard's wrapper directory at the front of `PATH` so the agent's\n`rm`/`mv`/`chmod` lookups hit cmdguard's wrappers:\n\n```bash\nexport PATH=\"$(cmdguard config --bin-dir):$PATH\"\nexport CMDGUARD_NONINTERACTIVE=1   # skip the 5s/10s confirm wait\n```\n\n`cmdguard config --bin-dir` prints the wrapper directory as a bare\npath (default `~/.cmdguard/bin`, or wherever your install puts it),\nso the export above stays correct even if you customise the layout.\n\nBoth methods can coexist.\n\n### What cmdguard does NOT do\n\ncmdguard cannot intercept calls that bypass `PATH` lookup, e.g. `/bin/rm /etc/passwd`.\nThe model is \"protect + audit + recoverable\", not \"absolute lockdown\".\n\n---\n\n## AI agent usage\n\nWhen an AI agent invokes a guarded command and the target is a protected\npath, cmdguard refuses to hang on an interactive prompt. The agent must:\n\n1. **Set the env var** to declare itself non-interactive:\n   ```bash\n   export CMDGUARD_NONINTERACTIVE=1\n   ```\n   This skips the 5s/10s wait at confirm prompts. It does **NOT** grant\n   permission — the operation is still rejected.\n\n2. **If the operation is genuinely safe**, retry with a `--bypass` identifier:\n   ```bash\n   rm /path/to/file --bypass=\u003chost\u003e/\u003cplatform\u003e/\u003cagent\u003e/\u003ctask\u003e\n   ```\n   The identifier must have exactly 4 segments:\n\n   | segment  | meaning                       | example                |\n   |----------|-------------------------------|------------------------|\n   | host     | machine hostname / alias      | `mac-studio`           |\n   | platform | agent platform                | `qwenpaw`, `cursor`    |\n   | agent    | agent id                      | `ai_research`          |\n   | task     | brief task slug               | `cleanup-tmp-dirs`     |\n\n   Allowed characters: `[a-zA-Z0-9._-]`. Empty segments, angle brackets,\n   and template placeholder words (`host`, `agent`, `task`, `xxx`, `foo`,\n   `todo`, ...) are rejected.\n\nEvery bypass is recorded in the audit log with the full identifier, so\nthe audit trail attributes every protected-path operation back to a\nspecific agent / task.\n\nSee [docs/commands.md](docs/commands.md#--bypass) for full details.\n\n---\n\n## Quick start\n\n### Install\n\n```bash\n# Option 1 — pre-built binary (recommended)\n# Download from the Releases page for your platform.\n\n# Option 2 — build from source\ngit clone https://github.com/hyper0x/cmdguard.git\ncd cmdguard\nmake install   # installs to $GOBIN with version info baked in\n```\n\n### Initialize\n\n```bash\ncmdguard init\n```\n\nCreates `~/.cmdguard/{config.toml, bin/, log/, vault/}` and prints the\nintegration guide. Idempotent — re-running is safe. Use `--force` to\noverwrite (old files are zipped to `~/.cmdguard/backup/`).\n\n---\n\n## Commands at a glance\n\n| Command | Description |\n|:----|:----|\n| `rm/mv/chmod \u003cargs...\u003e` | Run a command through cmdguard |\n| `init [--force] [--dry-run]` | Initialize the environment |\n| `list [options]` | List audit log entries |\n| `undo [options]` | Restore an operation from vault |\n| `vault list [--json]` | List all vault backups |\n| `vault clean [--dry-run]` | Purge expired vault backups |\n| `config [--default \\| --raw \\| --bin-dir]` | Print configuration views |\n| `path` | Show the cmdguard directory layout |\n| `help` / `version` | Self-explanatory |\n\nFull reference: [docs/commands.md](docs/commands.md)\n\n---\n\n## Configuration\n\nLocation: `~/.cmdguard/config.toml` (overridable via `CMDGUARD_CONFIG_DIR`).\n\n```toml\n[protect]\nreject         = [\"/etc/**\", \"/private/**\", \"~/.ssh/**\"]\nconfirm_double = [\"~/.config/**\"]\nconfirm        = [\"~/Documents/**\", \"~/Desktop/**\"]\nwarn           = [\"~/Downloads/**\"]\n\n[vault]\nretention_days = 7\nauto_purge     = true\n\n[guard]\nconfirm_timeout        = 5    # seconds; 'confirm' prompt\nconfirm_double_timeout = 10   # seconds per step; 'confirm_double' prompt\n```\n\n\u003e **The config file is read-only from cmdguard's perspective.** cmdguard\n\u003e never modifies it at runtime; only `cmdguard init --force` may overwrite\n\u003e it (with a backup zip).\n\nFull reference: [docs/configuration.md](docs/configuration.md)\n\n---\n\n## Vault \u0026 undo\n\n- Backup directory: `~/.cmdguard/vault/\u003ctimestamp\u003e_\u003cid\u003e/`\n- Retention: 30 days by default, configurable\n- Restore: `cmdguard undo [--id \u003cid\u003e] [--interactive] [--dry-run]`\n- Logs: permanent, JSON, one file per day\n\nDetails: [docs/vault.md](docs/vault.md)\n\n---\n\n## Build from source\n\n```bash\ngit clone https://github.com/hyper0x/cmdguard.git\ncd cmdguard\nmake build    # build into ./dist with version from git tag\nmake install  # install to $GOBIN\n```\n\n---\n\n## FAQ\n\n**Can cmdguard be bypassed?**\nYes. `/bin/rm /etc/passwd` skips the PATH lookup entirely. cmdguard is\nprotection + audit + recovery, not an absolute lockdown.\n\n**What's the difference between `confirm` and `confirm_double`?**\n`confirm` requires a single `y`. `confirm_double` requires `y` first and\nthen typing the full word `yes` — designed to defeat fatigue errors on\nhigh-risk paths.\n\n**What if my config file gets overwritten?**\n`cmdguard init` never overwrites without `--force`. With `--force`, the\nold file is preserved at `~/.cmdguard/backup/init-\u003ctimestamp\u003e.zip`.\n\n**Where do agents put `CMDGUARD_NONINTERACTIVE`?**\nIn the agent's shell init or wherever the agent's environment is set up.\nOnce exported, every cmdguard call in that environment skips the wait\nand goes straight to the bypass-or-reject path.\n\n**How do I uninstall?**\n```bash\n# Remove the alias / PATH line from your shell rc, then:\ntrash ~/.cmdguard         # or rm -rf if you don't have trash\nrm $(which cmdguard)\n```\n\n---\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyper0x%2Fcmdguard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyper0x%2Fcmdguard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyper0x%2Fcmdguard/lists"}