{"id":47640593,"url":"https://github.com/jskswamy/aide","last_synced_at":"2026-06-04T04:00:40.029Z","repository":{"id":346062281,"uuid":"1188097881","full_name":"jskswamy/aide","owner":"jskswamy","description":"Stop babysitting your agent. One command, any agent — sandboxed, reproducible, zero decision fatigue","archived":false,"fork":false,"pushed_at":"2026-05-26T02:41:33.000Z","size":2203,"stargazers_count":8,"open_issues_count":1,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-26T04:28:58.887Z","etag":null,"topics":["claude","cli","codex","coding-agent","context-manager","golang","sandbox","secrets-management","sops"],"latest_commit_sha":null,"homepage":"https://github.com/jskswamy/aide","language":"Go","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/jskswamy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-21T16:05:15.000Z","updated_at":"2026-05-26T02:41:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jskswamy/aide","commit_stats":null,"previous_names":["jskswamy/aide"],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/jskswamy/aide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jskswamy%2Faide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jskswamy%2Faide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jskswamy%2Faide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jskswamy%2Faide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jskswamy","download_url":"https://codeload.github.com/jskswamy/aide/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jskswamy%2Faide/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33888302,"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-04T02:00:06.755Z","response_time":64,"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":["claude","cli","codex","coding-agent","context-manager","golang","sandbox","secrets-management","sops"],"created_at":"2026-04-02T00:51:43.617Z","updated_at":"2026-06-04T04:00:40.023Z","avatar_url":"https://github.com/jskswamy.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# aide\n\n[![CI](https://github.com/jskswamy/aide/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/jskswamy/aide/actions/workflows/ci.yml)\n[![Security](https://github.com/jskswamy/aide/actions/workflows/security.yml/badge.svg?branch=main)](https://github.com/jskswamy/aide/actions/workflows/security.yml)\n[![Release](https://img.shields.io/github/v/release/jskswamy/aide)](https://github.com/jskswamy/aide/releases/latest)\n\nStop babysitting your agent.\n\nOne command. Any agent. Sandboxed, reproducible, zero decision fatigue.\n\n---\n\nYou planned the work. You know what needs to happen. But instead of letting your agent execute, you're stuck evaluating every file read, every shell command, every network call. That's not autonomy — that's babysitting with extra steps.\n\naide fixes three things:\n\n### Sandbox — stop choosing between scary and exhausting\n\nWithout aide, you either skip all permissions and hope for the best:\n\n```bash\nclaude --dangerously-skip-permissions  # what could go wrong?\n```\n\nOr you click \"allow\" on every. single. action. File read? Allow. Shell command? Allow. Network call? Allow. Two hundred times a session.\n\nWith aide, the agent runs inside OS-native guardrails — no config, no prompts:\n\n```bash\naide    # agent launches sandboxed automatically\n```\n\n```\n🔧 aide · work (claude)\n   📁 github.com/acme/api\n   🛡 sandbox: network outbound, code-only\n```\n\nCode-only mode. Your agent can read your code, run tests, hit the network — but it physically cannot touch your SSH keys, cloud credentials, or browser data. 10 guards active by default, zero configuration.\n\n**Ready to deploy?** Tell aide what you're doing:\n\n```bash\naide --with docker          # build and push images\naide --with docker k8s      # deploy to your cluster\naide --with docker k8s gcp  # debug cloud infra too\n```\n\n```\n🔧 aide · work (claude)\n   📁 github.com/acme/api\n   🛡 sandbox: network outbound\n      ✓ docker     ~/.docker/config.json\n      ✓ k8s        ~/.kube/config (KUBECONFIG)\n      ✓ gcp        ~/.config/gcloud\n\n      ⚠ credentials exposed: GOOGLE_APPLICATION_CREDENTIALS\n```\n\nEach capability unlocks exactly what the agent needs — nothing more. Docker gets registry creds. Kubernetes gets kubeconfig. GCP gets gcloud auth. Everything else stays locked.\n\n**Protect what matters:**\n\n```bash\naide cap never-allow ~/.kube/prod-config\naide cap never-allow --env PRODUCTION_DB_PASSWORD\n```\n\nNow no capability — not even `k8s` — can ever read your production kubeconfig. The agent sees your dev and staging clusters but production is a hard wall:\n\n```\n🔧 aide · work (claude)\n   🛡 sandbox: network outbound\n      ✓ k8s        ~/.kube/dev-config, ~/.kube/staging-config\n      ✗ denied     ~/.kube/prod-config (never-allow)\n```\n\n**Make it permanent for a project:**\n\n```yaml\n# .aide.yaml in your repo root\ncapabilities: [docker, k8s, gcp]\n```\n\nNo flags needed next time — `aide` picks up the capabilities from your config.\n\nThe first time aide encounters a `.aide.yaml`, it shows the contents and asks you to trust it:\n\n```bash\naide trust    # approve the project config\naide deny     # block it permanently\n```\n\n**Create your own:**\n\n```bash\naide cap create k8s-dev --extends k8s --deny ~/.kube/prod-config\naide --with k8s-dev docker    # dev clusters only, production blocked\n```\n\n19 built-in capabilities: `aws`, `gcp`, `azure`, `docker`, `k8s`, `helm`, `terraform`, `vault`, `ssh`, `npm`, `go`, `rust`, `python`, `ruby`, `java`, `github`, `gpg`, and more. Or define your own.\n\n### Unified UX — one command, any agent\n\nWithout aide, every agent is its own world:\n\n```bash\nclaude                                          # Anthropic API key\nCLAUDE_CODE_USE_BEDROCK=1 AWS_PROFILE=work claude  # or Bedrock?\ncodex --provider anthropic                      # different CLI entirely\naider --model claude-3.5-sonnet                 # yet another interface\n```\n\nDifferent CLIs. Different config formats. Different env vars. Switch agents, rewire everything.\n\nWith aide, you configure once and forget:\n\n```bash\ncd ~/work/project \u0026\u0026 aide    # Claude with work Bedrock credentials\ncd ~/oss/repo \u0026\u0026 aide        # Aider with personal Anthropic key\ncd ~/scratch \u0026\u0026 aide         # auto-detects agent on PATH, zero config\n```\n\nSame command everywhere. aide resolves the right agent, credentials, and sandbox from your project directory.\n\n### Reproducibility — secrets that don't leak\n\nWithout aide:\n\n```bash\n# The classic footgun\necho 'ANTHROPIC_API_KEY=sk-ant-...' \u003e\u003e .env\ngit add -A \u0026\u0026 git commit -m \"update config\"  # oops\n```\n\nAPI keys in `.env` files. Wrapper scripts with hardcoded tokens. A new machine means an hour of setup.\n\nWith aide, secrets are encrypted at rest and never exist as plaintext on disk:\n\n```bash\naide secrets create personal --age-key age1abc...   # encrypted with your key\n```\n\nConfig and encrypted secrets live in git. Clone your config on a new machine and you're done. No shared secrets, no plaintext on disk.\n\n## Quick Start\n\n```bash\n# Install latest release (macOS)\ncurl -sSfL https://raw.githubusercontent.com/jskswamy/aide/main/install.sh | sh\n\n# Install to a specific directory\ncurl -sSfL https://raw.githubusercontent.com/jskswamy/aide/main/install.sh | sudo INSTALL_DIR=/usr/local/bin sh\n\n# Install a specific version\ncurl -sSfL https://raw.githubusercontent.com/jskswamy/aide/main/install.sh | VERSION=v0.1.0 sh\n\n# Install from source\ngo install github.com/jskswamy/aide/cmd/aide@latest\n\n# Or build locally\ngit clone https://github.com/jskswamy/aide.git\ncd aide \u0026\u0026 make build   # Binary at ./bin/aide\n```\n\nFour commands to know:\n\n```bash\naide                        # Resolve context and launch the agent (sandboxed)\naide setup                  # Interactive first-time configuration\naide --with k8s docker      # Enable capabilities for this session\naide cap list               # See all available capabilities\n```\n\nNo config file required. If one agent exists on PATH with its API key in the environment, `aide` launches it sandboxed — zero setup.\n\n### Passing args to your agent\n\nEverything after `--` is forwarded directly to the agent:\n\n```bash\n# Add an MCP server through aide's sandbox\naide -- mcp add --transport http 1mcp \"http://127.0.0.1:3050/mcp\" --scope user\n\n# Run a one-shot prompt\naide -- -p \"fix the failing tests and commit\"\n\n# Start with a specific model\naide -- --model sonnet\n\n# Resume the last conversation\naide -- --resume\n\n# Combine with aide flags\naide --with docker -- -p \"build and push the image\"\n```\n\nThis works with any agent — aide resolves context and sandbox, then execs the agent with your args appended.\n\n## How It Works\n\n1. Run `aide` in any project directory.\n2. aide matches the git remote URL and directory path against your config.\n3. It resolves the context: agent, credentials, capabilities, and sandbox policy.\n4. Secrets decrypt in-process via the sops Go library. Nothing hits disk.\n5. Capabilities translate to sandbox rules — each `--with` flag unlocks specific tool access while keeping everything else locked.\n6. aide applies the sandbox via macOS Seatbelt and execs the agent inside it. Linux sandbox support (Landlock) is planned.\n\nNo config file? aide detects your agent on PATH and launches it directly.\n\n## Capabilities\n\nCapabilities are task-oriented permission bundles. Instead of configuring low-level sandbox rules, you declare what you're doing:\n\n| Capability | What it unlocks |\n|------------|----------------|\n| `aws` | AWS CLI credentials (`~/.aws/`) |\n| `gcp` | Google Cloud credentials (`~/.config/gcloud/`) |\n| `azure` | Azure CLI credentials (`~/.azure/`) |\n| `docker` | Docker registry credentials (`~/.docker/`) |\n| `k8s` | Kubernetes cluster access (`~/.kube/`) |\n| `helm` | Helm charts and releases |\n| `terraform` | Terraform state and providers |\n| `vault` | HashiCorp Vault access |\n| `ssh` | SSH keys and agent |\n| `npm` | npm/yarn registry credentials |\n| `go` | Go toolchain (`~/go/`) |\n| `rust` | Rust toolchain (`~/.cargo/`, `~/.rustup/`) |\n| `python` | Python toolchain (`~/.pyenv/`) |\n| `ruby` | Ruby toolchain (`~/.rbenv/`) |\n| `java` | Java/JVM toolchain (`~/.sdkman/`, `~/.gradle/`, `~/.m2/`) |\n| `github` | GitHub CLI credentials (`~/.config/gh/`) |\n| `gpg` | GPG keys and signing (`~/.gnupg/`) |\n\n**Session-scoped** (this launch only):\n\n```bash\naide --with k8s docker\n```\n\n**Context-scoped** (always for this project):\n\n```yaml\n# ~/.config/aide/config.yaml\ncontexts:\n  work:\n    agent: claude\n    capabilities: [docker, k8s, gcp]\n    secret: work\n    env:\n      ANTHROPIC_API_KEY: \"{{ .secrets.anthropic_api_key }}\"\n```\n\n**Need something not in the list?** Create your own in one command:\n\n```bash\n# Grant access to your Bazel cache\naide cap create bazel --writable ~/.cache/bazel --env-allow BAZEL_HOME\n\n# Extend a built-in with project-specific restrictions\naide cap create k8s-dev --extends k8s --deny ~/.kube/prod-config\n\n# Bundle capabilities for a workflow\naide cap create my-deploy --combines docker,k8s,aws\n```\n\nCustom capabilities work the same as built-ins. Use them with `--with`, persist them in `.aide.yaml`, or share them across projects via your global config:\n\n```yaml\n# ~/.config/aide/config.yaml\ncapabilities:\n  bazel:\n    writable: [\"~/.cache/bazel\"]\n    env_allow: [BAZEL_HOME]\n\n# .aide.yaml in a repo (shared with the team)\ncapabilities: [docker, k8s, bazel]\n```\n\n```bash\naide cap show bazel           # inspect what it grants\naide cap check bazel docker   # preview composition before launching\n```\n\n**Global protection:**\n\n```bash\naide cap never-allow ~/.kube/prod-config      # no capability can ever read this\naide cap never-allow --env VAULT_ROOT_TOKEN   # this env var is always stripped\n```\n\n## Configuration\n\nAll config lives under `~/.config/aide/` (or `$XDG_CONFIG_HOME/aide/`).\n\n**Minimal config:**\n\n```yaml\nagent: claude\nsecret: personal\nenv:\n  ANTHROPIC_API_KEY: \"{{ .secrets.anthropic_api_key }}\"\n```\n\n**Multi-context config:**\n\n```yaml\ncontexts:\n  work:\n    match:\n      - remote: \"github.com/work-org/*\"\n      - path: \"~/work/*\"\n    agent: claude\n    capabilities: [docker, k8s, aws]\n    secret: work\n    env:\n      CLAUDE_CODE_USE_BEDROCK: \"1\"\n      AWS_PROFILE: \"{{ .secrets.aws_profile }}\"\n\n  personal:\n    match:\n      - remote: \"github.com/myuser/*\"\n    agent: codex\n    secret: personal\n    env:\n      OPENAI_API_KEY: \"{{ .secrets.openai_api_key }}\"\n\n  oss:\n    match:\n      - remote: \"github.com/*\"\n    agent: aider\n    secret: personal\n    env:\n      ANTHROPIC_API_KEY: \"{{ .secrets.anthropic_api_key }}\"\n\ndefault_context: personal\n```\n\nContexts match git remote URL patterns and directory path globs. The most specific match wins. `default_context` is the fallback. See [docs/configuration.md](docs/configuration.md) for the full reference.\n\n## Secrets\n\nSecrets are sops-encrypted YAML files using age keys. aide handles the full lifecycle without requiring the `sops` CLI at runtime.\n\n```bash\naide secrets create personal --age-key age1abc...   # Create (opens $EDITOR)\naide secrets edit personal                           # Decrypt, edit, re-encrypt\n```\n\nSecrets decrypt in-process at launch and never exist as plaintext on disk. See [docs/secrets.md](docs/secrets.md).\n\n## Provisioning — stop reinstalling your plugins on every machine\n\nIf you've ever set up a new laptop and spent an hour running\n`claude plugin install \u003cfoo\u003e` ten times in a row, only to realise\ntwo weeks later that you forgot the `commit-tools` plugin on your\nwork machine and that's why every commit message looks different\nfrom your personal machine — this section is for you.\n\nThe same problem shows up across teammates. Onboarding a new\nengineer to the project means writing a setup README that lists\n\"please install these plugins, then add this MCP server\" and hoping\nthey read past step 3. Six months later, half the team is on a\ndifferent plugin set than the other half and nobody knows when it\ndiverged.\n\nDeclare it once in `config.yaml` and reconcile with one command:\n\n```yaml\nplugins:\n  jskswamy/claude-plugins: [commit-tools, craft, refactor]\n\ncontexts:\n  work:\n    agent: claude\n    profile: work          # → CLAUDE_CONFIG_DIR=~/.claude-work\n```\n\n```bash\naide sync --plan           # preview the diff\naide sync                  # apply (plugins land in ~/.claude-work/)\naide plugin list           # declared / installed / managed view\naide adopt                 # bring hand-installed items under management\n```\n\nThe state file at `~/.local/state/aide/managed.json` is per-context,\nso syncing your `work` context never disturbs your `personal` plugin\nset. `aide which` shows a drift banner whenever your config drifts\nahead of what's installed, so the gap doesn't go unnoticed.\n\n### The other half: profiles\n\nThe reason you can declare different plugin sets for different\nprojects is that each agent context can carry a `profile:` name.\nWithout it, every claude invocation reads from one shared\n`~/.claude/` directory — your work plugins and your personal plugins\nfight for the same slot, your client A's session history shows up\nwhen you're working on client B's repo, and your \"experimental\"\nMCP servers leak into the project where you're supposed to be on\nyour best behaviour.\n\n`profile: work` tells aide's claude driver to set\n`CLAUDE_CONFIG_DIR=~/.claude-work` everywhere: at launch, during\n`aide sync`, during `aide adopt`, during plugin/MCP list. The\nagent reads from and writes to that directory and that directory\nonly. Your personal claude state in `~/.claude/` stays untouched.\nSwitch context and it's a different dir entirely.\n\nThe same idea works for gemini (`GEMINI_HOME`), codex\n(`CODEX_HOME`), copilot (`COPILOT_HOME`) — different env-var name,\nsame shape from your point of view. You write `profile: \u003cname\u003e`,\naide handles the per-agent env quirks.\n\nSee [docs/provisioning.md](docs/provisioning.md) for the full\nreference.\n\n## Reproducibility\n\n**Personal setup** tracked in git:\n\n```bash\ncd ~/.config/aide\ngit init \u0026\u0026 git add -A \u0026\u0026 git commit -m \"aide config\"\n```\n\nEncrypted secrets are safe to commit. Only holders of the age private key can decrypt.\n\n**Docker / CI:**\n\n```dockerfile\n# Requires the agent binary (e.g. claude) to be installed and on PATH.\nCOPY aide-config/ /root/.config/aide/\nENV SOPS_AGE_KEY=AGE-SECRET-KEY-1...\nRUN aide --agent claude -- -p \"run tests\"\n```\n\n## Diagnosing a failed run\n\nWhen the agent exits with a cryptic message (or with no message at all), re-run aide with `--diagnose`:\n\n```bash\naide --diagnose\n```\n\naide will:\n\n1. Run the agent normally with stdin/stdout passthrough.\n2. Capture the agent's stderr (last 200 lines / 64 KB by default).\n3. On exit, print a short summary and write a full markdown report to `~/.cache/aide/diagnose/\u003ctimestamp\u003e-\u003cid\u003e.md` (or `$XDG_CACHE_HOME/aide/diagnose/...` if set).\n\nThe report is **redacted** — no secret values, no hostnames — and is suitable to paste into a GitHub issue.\n\nFor sandbox-related failures on macOS, add `--diagnose-trace` to additionally capture sandbox-deny events from `log show`:\n\n```bash\naide --diagnose-trace\n```\n\n### Tweaking the stderr buffer\n\nTwo env vars override the defaults for one run:\n\n```bash\nAIDE_DIAGNOSE_STDERR_LINES=2000 AIDE_DIAGNOSE_STDERR_BYTES=524288 aide --diagnose\n```\n\nWhichever limit is reached first wins.\n\n### Note\n\n`--diagnose` switches the exec strategy from `syscall.Exec` (process replacement) to fork+exec so aide can stay alive to gather post-mortem data. Default runs are unaffected. `--diagnose-trace` is macOS-only in v1.\n\n## Supported Agents\n\nAider, Amp, Claude, Codex, Copilot, Cursor, Gemini, Goose. Any binary on PATH works as an agent target.\n\n## Development\n\n```bash\nnix develop                 # Full dev environment with all tools\nmake build                  # Build to ./bin/aide\nmake test                   # Run tests\nmake lint                   # Run golangci-lint\n```\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Capabilities](docs/capabilities.md)\n- [Contexts](docs/contexts.md)\n- [Environment Variables](docs/environment.md)\n- [Secrets](docs/secrets.md)\n- [Sandbox](docs/sandbox.md)\n- [Provisioning](docs/provisioning.md)\n- [Configuration Reference](docs/configuration.md)\n- [CLI Reference](docs/cli-reference.md)\n- [Deployment](docs/deployment.md)\n\n## Planned\n\n### Linux support\n\nLandlock + seccomp-bpf sandbox for Linux hosts (with bubblewrap fallback for older kernels). Currently aide sandboxes via macOS Seatbelt — Linux users run without OS-level isolation. Landlock handles filesystem access control, seccomp-bpf restricts system calls, and together they bring the same deny-default, guard-based architecture to Linux with equivalent coverage.\n\n### Network filtering\n\nAllow or deny network access by domain, port, and MIME type. Today the sandbox controls network at the transport level (outbound yes/no, port filtering). Planned: domain-level rules so an agent can reach `github.com` but not arbitrary hosts, and MIME-type filtering to block binary downloads while allowing API calls.\n\n### Command deny list\n\nBlock dangerous commands by name — `rm`, `sudo`, `chmod`, `kill`, etc. Instead of requiring users to know the binary path, aide resolves each command name through `$PATH` at sandbox build time and denies `process-exec` on the resolved binaries. One line in config:\n\n```yaml\nsandbox:\n  deny_commands: [rm, sudo, chmod, kill, reboot]\n```\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjskswamy%2Faide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjskswamy%2Faide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjskswamy%2Faide/lists"}