{"_id":"@brianbondy/guardrails","_rev":"5-f1f9c6b726b32fa1b580135393eaf821","name":"@brianbondy/guardrails","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.13":{"name":"@brianbondy/guardrails","version":"0.1.13","license":"MPL-2.0","_id":"@brianbondy/guardrails@0.1.13","maintainers":[{"name":"brianbondy","email":"bbondy@gmail.com"}],"homepage":"https://github.com/bbondy/guardrails#readme","bugs":{"url":"https://github.com/bbondy/guardrails/issues"},"bin":{"guardrails":"npm/bin/guardrails.js"},"dist":{"shasum":"c844ba987115db8e0c1784bd43932976e20fca2f","tarball":"https://registry.npmjs.org/@brianbondy/guardrails/-/guardrails-0.1.13.tgz","fileCount":4,"integrity":"sha512-UXqVEr/xX3GjcPoc3Q/92KhmmqLIXhA+V9VFOYLA9I8z5iP0WLMY8ij2z255/ZxK1dFmtPNL1kzmm/H4xL3X7g==","signatures":[{"sig":"MEUCIQDek0IctYhU1uSR/D3dFg5wWJnUcW41+8ro1w2/6ztNuQIgDivXJ+fb1h3Wzs8bGkQKHarwfj/XJY9O5J2JMevj8UE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14860},"engines":{"node":">=18"},"private":false,"scripts":{"postinstall":"node npm/scripts/postinstall.js"},"_npmUser":{"name":"brianbondy","email":"bbondy@gmail.com"},"repository":{"url":"git+https://github.com/bbondy/guardrails.git","type":"git"},"_npmVersion":"10.5.0","description":"Native CLI wrapper that blocks prompt-injection output from other CLIs","directories":{},"_nodeVersion":"21.7.3","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/guardrails_0.1.13_1772938017631_0.9430357288943891","host":"s3://npm-registry-packages-npm-production"}},"0.1.14":{"name":"@brianbondy/guardrails","version":"0.1.14","license":"MPL-2.0","_id":"@brianbondy/guardrails@0.1.14","maintainers":[{"name":"brianbondy","email":"bbondy@gmail.com"}],"homepage":"https://github.com/bbondy/guardrails#readme","bugs":{"url":"https://github.com/bbondy/guardrails/issues"},"bin":{"guardrails":"npm/bin/guardrails.js"},"dist":{"shasum":"035c3a36453eb54cf336205035c34c4358e9b418","tarball":"https://registry.npmjs.org/@brianbondy/guardrails/-/guardrails-0.1.14.tgz","fileCount":4,"integrity":"sha512-BUZKiTm+1EdLXd1Ic3lVTNdpwOqIhYzVN4uF1Tx0KTgd86d1nMSvqi7cjjAHGVYnt/49TlOKeLtpvjZqtJchLQ==","signatures":[{"sig":"MEUCIQDR2vpah6wLX74F1XdN2STsWvrI+dDWg0kiW3HZ5M+mOAIgAo9vP3H92/WwWEutwGoztK0QoSGVOkO4yU/euebX3ag=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16231},"engines":{"node":">=18"},"private":false,"scripts":{"postinstall":"node npm/scripts/postinstall.js"},"_npmUser":{"name":"brianbondy","email":"bbondy@gmail.com"},"repository":{"url":"git+https://github.com/bbondy/guardrails.git","type":"git"},"_npmVersion":"10.5.0","description":"Native CLI wrapper that blocks prompt-injection output from other CLIs","directories":{},"_nodeVersion":"21.7.3","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/guardrails_0.1.14_1772938999363_0.4609779863005279","host":"s3://npm-registry-packages-npm-production"}},"0.1.16":{"name":"@brianbondy/guardrails","version":"0.1.16","license":"MPL-2.0","_id":"@brianbondy/guardrails@0.1.16","maintainers":[{"name":"brianbondy","email":"bbondy@gmail.com"}],"homepage":"https://github.com/bbondy/guardrails#readme","bugs":{"url":"https://github.com/bbondy/guardrails/issues"},"bin":{"guardrails":"npm/bin/guardrails.js"},"dist":{"shasum":"42757c16cfde752e94a3a5e293a542d66727c88c","tarball":"https://registry.npmjs.org/@brianbondy/guardrails/-/guardrails-0.1.16.tgz","fileCount":4,"integrity":"sha512-M6KFk8IHMmAmp46I2aWl4XRDzOsifwFrfUpXM6r9CkigbDIvSAXFAoOUFhV5naWK2Bb/SRBkWTQ0RNJz8hbszQ==","signatures":[{"sig":"MEQCIH+426PHcIZmHgqRnjzF6O5RPn0cImpCigvYSmq6bi21AiBTb5LZSLi0CPepPAxNkOy0skGConO5xUt5/v+JGOLpUA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16145},"engines":{"node":">=18"},"private":false,"scripts":{"postinstall":"node npm/scripts/postinstall.js"},"_npmUser":{"name":"brianbondy","email":"bbondy@gmail.com"},"repository":{"url":"git+https://github.com/bbondy/guardrails.git","type":"git"},"_npmVersion":"10.5.0","description":"Native CLI wrapper that blocks prompt-injection output from other CLIs","directories":{},"_nodeVersion":"21.7.3","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/guardrails_0.1.16_1772940879004_0.9596015596720102","host":"s3://npm-registry-packages-npm-production"}},"0.1.18":{"name":"@brianbondy/guardrails","version":"0.1.18","license":"MPL-2.0","_id":"@brianbondy/guardrails@0.1.18","maintainers":[{"name":"brianbondy","email":"bbondy@gmail.com"}],"homepage":"https://github.com/bbondy/guardrails#readme","bugs":{"url":"https://github.com/bbondy/guardrails/issues"},"bin":{"guardrails":"npm/bin/guardrails.js"},"dist":{"shasum":"d2cc09813f090750ba9b2da404b1b61cac11c95b","tarball":"https://registry.npmjs.org/@brianbondy/guardrails/-/guardrails-0.1.18.tgz","fileCount":4,"integrity":"sha512-6ZmR9dBBq4CEgrfMbuO3iVOD1JlQgs5rrsXlAmU9lPhPb9oNLndLpUB3m8sjFRjQMccm3d/QjKunofa8uu1u0g==","signatures":[{"sig":"MEQCIDAo7jeasF05KdCgZOl8wxrEBK6Or6lwAOtOebTSCSVuAiBFzK/eBvO2Ljr04RK9nRvIAuDk6FFrYCTukiXNMbaHtQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":12488},"engines":{"node":">=18"},"private":false,"scripts":{"postinstall":"node npm/scripts/postinstall.js"},"_npmUser":{"name":"brianbondy","email":"bbondy@gmail.com"},"repository":{"url":"git+https://github.com/bbondy/guardrails.git","type":"git"},"_npmVersion":"10.5.0","description":"Native CLI wrapper that blocks prompt-injection output from other CLIs","directories":{},"_nodeVersion":"21.7.3","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/guardrails_0.1.18_1772945727563_0.2203994759754948","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@brianbondy/guardrails","version":"0.2.0","description":"Native CLI wrapper that blocks prompt-injection output from other CLIs","license":"MPL-2.0","repository":{"type":"git","url":"git+https://github.com/bbondy/guardrails.git"},"bugs":{"url":"https://github.com/bbondy/guardrails/issues"},"homepage":"https://github.com/bbondy/guardrails#readme","bin":{"guardrails":"npm/bin/guardrails.js"},"scripts":{"postinstall":"node npm/scripts/postinstall.js"},"engines":{"node":">=18"},"private":false,"_id":"@brianbondy/guardrails@0.2.0","_nodeVersion":"21.7.3","_npmVersion":"10.5.0","dist":{"integrity":"sha512-wjxvkZtjEkGZCP2YL2FmCT53enKzWdxLWsTyL6+5qbOJ9gs+3vIKiLyAoS2AiuOq6izTPVM9BfMlirxpuOfG6A==","shasum":"300b492a866247a760f7a2598f7ff4c7087519be","tarball":"https://registry.npmjs.org/@brianbondy/guardrails/-/guardrails-0.2.0.tgz","fileCount":4,"unpackedSize":13875,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDv0uqSbZyfpOaspkA6MC309Hrzf/MtmSxmLBu6q5NCBAiANbC3WctpMVa/Ar4vJgcZ6LSBCNjAc5QT36HhK+U8+Bg=="}]},"_npmUser":{"name":"brianbondy","email":"bbondy@gmail.com"},"directories":{},"maintainers":[{"name":"brianbondy","email":"bbondy@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/guardrails_0.2.0_1773366134700_0.5602680366400679"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-08T02:46:57.522Z","modified":"2026-03-13T01:42:14.957Z","0.1.13":"2026-03-08T02:46:57.787Z","0.1.14":"2026-03-08T03:03:19.526Z","0.1.16":"2026-03-08T03:34:39.150Z","0.1.18":"2026-03-08T04:55:27.714Z","0.2.0":"2026-03-13T01:42:14.837Z"},"bugs":{"url":"https://github.com/bbondy/guardrails/issues"},"license":"MPL-2.0","homepage":"https://github.com/bbondy/guardrails#readme","repository":{"type":"git","url":"git+https://github.com/bbondy/guardrails.git"},"description":"Native CLI wrapper that blocks prompt-injection output from other CLIs","maintainers":[{"name":"brianbondy","email":"bbondy@gmail.com"}],"readme":"# guardrails\n\n[![CI](https://github.com/bbondy/guardrails/actions/workflows/ci.yml/badge.svg)](https://github.com/bbondy/guardrails/actions/workflows/ci.yml)\n\n<img src=\"assets/icons/png/guardrails-256.png\" alt=\"guardrails logo\" width=\"180\" />\n\nA native Rust CLI that wraps another CLI, buffers `stdout` and `stderr`, and either blocks unsafe output (`check` mode) or minimally filters unsafe content (`filter` mode).\n\nDeveloper and release workflows are documented in [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md).\n\nDetailed implementation guide: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)\n\n## Install\n\nVia npmjs:\n\n```bash\nnpm install -g @brianbondy/guardrails\n```\n\nVia install script:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/bbondy/guardrails/main/install.sh | sh\n```\n\nOptional install directory:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/bbondy/guardrails/main/install.sh | INSTALL_DIR=\"$HOME/.local/bin\" sh\n```\n\n## CLI help\n\n```bash\nguardrails --help\n```\n\n```text\nUsage: guardrails [OPTIONS] --checker <CHECKER> [COMMAND]...\n\nArguments:\n  [COMMAND]...  Wrapped command and arguments. Example: -- gh issue list\n\nOptions:\n      --checker <CHECKER>\n          Tool to use for prompt-injection checks [possible values: codex, claude, gemini, agent]\n      --checker-cmd <CHECKER_CMD>\n          Checker executable path. Defaults to checker-specific command names\n      --checker-arg <CHECKER_ARG>\n          Extra args passed to the checker executable (repeatable). If provided, prompt is sent via stdin\n      --checker-context <CHECKER_CONTEXT>\n          Extra trusted context passed to the checker prompt payload (repeatable)\n      --checker-permission <CHECKER_PERMISSION>\n          Permission hints passed to the checker prompt payload (repeatable)\n      --command-name <COMMAND_NAME>\n          Logical command name when scanning stdin (no wrapped command provided) [default: stdin]\n      --exit-code <EXIT_CODE>\n          Exit code to return in stdin pass-through mode when verdict is safe [default: 0]\n      --checker-timeout-ms <CHECKER_TIMEOUT_MS>\n          Timeout (milliseconds) for checker tool execution\n      --max-output-bytes <MAX_OUTPUT_BYTES>\n          Maximum bytes per stream (stdout/stderr) sent to checker\n      --pty\n          Run wrapped command under a pseudo-terminal in buffered mode to preserve TTY-style formatting\n  -h, --help\n          Print help\n  -V, --version\n          Print version\n```\n\n## How it works (`check` mode)\n\n1. `guardrails` executes a wrapped command.\n2. Wrapped-command stdin is forwarded to the wrapped process.\n3. It captures full command output (buffered, not streamed). By default it captures `stdout` and `stderr` separately; with `--pty` it captures a merged PTY stream for terminal-style formatting.\n4. It invokes the selected checker tool (`codex`, `claude`, `gemini`, or `agent`) in non-interactive mode from inside `guardrails`.\n5. If verdict is `unsafe`, it exits with code `42` and does not forward wrapped output.\n6. If verdict is `safe`, it re-emits the same bytes to `stdout`/`stderr` and exits with the wrapped command's status.\n7. If no wrapped command is provided, it reads fully buffered stdin, checks it, and on `safe` re-emits stdin to `stdout`.\n\n`--pty` is available for wrapped commands in buffered mode when you need TTY-style formatting (for example `ls` columns/colors).\n\n## How it works (`filter` subcommand)\n\n1. `guardrails filter` executes a wrapped command (or reads piped stdin).\n2. For wrapped commands, stdin is forwarded to the wrapped process while output remains buffered for filtering.\n3. It invokes the checker and asks for sanitized output.\n4. It forwards checker-provided filtered output.\n5. If checker filtering fails (timeout/error/invalid response), it exits `43` and does not emit wrapped output.\n6. It exits `42` when prompt injection/instruction redirection is detected.\n7. Otherwise, it returns the wrapped command exit status (or `--exit-code` in stdin mode), even if trusted context caused benign output rewrites.\n\n## Commands\n\n```bash\n# Wrap another CLI command\nguardrails --checker codex -- gh issue list\n\n# Wrap a GH command with guaranteed output from this repo\nguardrails --checker codex -- gh release list --repo bbondy/guardrails --limit 5\n\n# Same release command with JSON output\nguardrails --checker codex -- gh release list --repo bbondy/guardrails --limit 5 --json tagName,name,isLatest,publishedAt\n\n# Use Gemini as checker\nguardrails --checker gemini -- gh issue list\n\n# Use Cursor Agent as checker\nguardrails --checker agent -- gh issue list\n\n# Note: default Agent checker invocation is non-interactive:\n# agent -f -p \"<prompt>\"\n\n# Add a checker timeout (milliseconds)\nguardrails --checker codex --checker-timeout-ms 10000 -- gh issue list\n\n# Cap bytes sent to checker per stream (stdout/stderr)\nguardrails --checker codex --max-output-bytes 262144 -- gh issue list\n\n# Preserve TTY formatting while still buffering + checking output\nguardrails --checker codex --pty -- ls\n\n# Check arbitrary buffered text from stdin and pass it through if safe\ncat output.txt | guardrails --checker claude\n\n# Filter a wrapped command instead of blocking\nguardrails filter --checker codex -- gh issue list\n\n# Filter piped stdin and pass through unchanged output with --exit-code when no filtering is needed\ncat output.txt | guardrails filter --checker claude --exit-code 0\n\n# Override executable path and pass provider-specific arguments\nguardrails --checker codex --checker-cmd /usr/local/bin/codex --checker-arg exec --checker-arg --json --checker-arg - -- ls -la\n\n# Add extra checker context and permissions hints to payload\nguardrails filter --checker codex \\\n  --checker-context \"repo contains internal-only docs\" \\\n  --checker-permission \"workspace-write\" \\\n  -- gh issue list\n```\n\n## Live GH API safety demo\n\nThis repo includes a defensive canary file with instruction-like text so you can verify blocking behavior end-to-end with the GitHub API.\n\n```bash\n# Run the built-in demo helper (tests all installed checkers; expects guardrails + gh)\n./examples/run-gh-api-canary-demo.sh\n\n# Optional: run demo for only one checker\nCHECKER=gemini ./examples/run-gh-api-canary-demo.sh\n\n# Or run directly\nguardrails --checker codex -- \\\n  gh api repos/bbondy/guardrails/contents/examples/gh-api-safety-canary.txt \\\n  -H \"Accept: application/vnd.github.raw\"\necho $?\n```\n\nExpected result: guardrails prints a blocked prompt-injection message and exits `42`.\n\nSafe comparison example:\n\n```bash\nguardrails --checker codex -- \\\n  gh api repos/bbondy/guardrails/contents/examples/gh-api-safe.txt \\\n  -H \"Accept: application/vnd.github.raw\"\necho $?\n```\n\nExpected result: safe text is printed and exit code is `0`.\n\n## Exit codes\n\n- `42`: blocked due to detected prompt injection/instruction redirection\n- `43`: checker tool failure\n- `126`: wrapped command found but not executable/permission denied\n- `127`: wrapped command not found\n- otherwise: wrapped command exit code (or `--exit-code` in stdin mode)\n\nNotes:\n- `43` applies to both `check` and `filter` modes when checker execution/parsing fails.\n- In `filter` mode, guardrails returns `42` only when prompt injection/instruction redirection is detected.\n- `--pty` requires a wrapped command.\n- In `--pty` mode, wrapped `stdout`/`stderr` are captured as one merged stream.\n\nChecker protocol details are documented in [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).\n","readmeFilename":"README.md"}