{"_id":"@dreki-gg/pi-command-sandbox","_rev":"5-946e022cd4532e4e8a179846053ad60a","name":"@dreki-gg/pi-command-sandbox","dist-tags":{"latest":"0.4.3"},"versions":{"0.3.2":{"name":"@dreki-gg/pi-command-sandbox","version":"0.3.2","author":{"name":"Juan Albarran","email":"jalbarrandev@gmail.com"},"license":"MIT","_id":"@dreki-gg/pi-command-sandbox@0.3.2","maintainers":[{"name":"jalbarrang","email":"jalbarrandev@gmail.com"}],"homepage":"https://github.com/dreki-gg/pi-extensions#readme","bugs":{"url":"https://github.com/dreki-gg/pi-extensions/issues"},"dist":{"shasum":"8842829db19075ca63d522b24ea18f5ed16b5706","tarball":"https://registry.npmjs.org/@dreki-gg/pi-command-sandbox/-/pi-command-sandbox-0.3.2.tgz","fileCount":4,"integrity":"sha512-iHseNGE/khZ4MKO8UzpdDEUA6wmV4TxXwEMFD2lngo05LYQzCxPnznwNj+akq1cpfabIlRWJ/QFRs32tNMkJ+w==","signatures":[{"sig":"MEYCIQCvwtHD2AEXA0Ifsts1wesaVZDj0ucLUDKHwFsKK5+4vQIhAMGHBt6uZIquXHNnfAMlv+t7ujEI3CgCq52fE9/DuUXc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19141},"main":"./dist/index.mjs","type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"}},"gitHead":"c48ed25bbb6c9b5441dd1fa2184e5b59313f02f0","scripts":{"lint":"oxlint src","test":"bun test","build":"tsdown","format":"oxfmt --write src","typecheck":"tsc --noEmit","format:check":"oxfmt --check src"},"_npmUser":{"name":"jalbarrang","email":"jalbarrandev@gmail.com"},"repository":{"url":"git+https://github.com/dreki-gg/pi-extensions.git","type":"git","directory":"packages/command-sandbox"},"_npmVersion":"11.12.1","description":"Shared command sandboxing utilities for pi extensions — validates shell commands against safe/destructive pattern lists using proper shell parsing","directories":{},"_nodeVersion":"24.12.0","dependencies":{"shell-quote":"^1.8.3"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.43.0","oxlint":"^1.58.0","tsdown":"^0.22.0","bun-types":"latest","typescript":"^6.0.0","@types/node":"24","@types/shell-quote":"^1.7.5"},"_npmOperationalInternal":{"tmp":"tmp/pi-command-sandbox_0.3.2_1780120035392_0.15828884757986983","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@dreki-gg/pi-command-sandbox","version":"0.4.0","author":{"name":"Juan Albarran","email":"jalbarrandev@gmail.com"},"license":"MIT","_id":"@dreki-gg/pi-command-sandbox@0.4.0","maintainers":[{"name":"jalbarrang","email":"jalbarrandev@gmail.com"}],"homepage":"https://github.com/jalbarrang/pi-command-sandbox#readme","bugs":{"url":"https://github.com/jalbarrang/pi-command-sandbox/issues"},"dist":{"shasum":"b76c5e918c6262f6b04438637ceb6bc295f6a57a","tarball":"https://registry.npmjs.org/@dreki-gg/pi-command-sandbox/-/pi-command-sandbox-0.4.0.tgz","fileCount":3,"integrity":"sha512-21tKFjakg1669EzXb4vmnp8tRQXH/F7lmyWQtQ3+4poVZYRZhKjy/aYZ09rHReR0xO0ClEF8i3IG9plyTuh1FQ==","signatures":[{"sig":"MEUCIQCeWJum7blo9QnO9SHY6uARRWksA/2MVxrqxPDajrQztgIgM2SP3ymFoR1V4BlVgltShrcQveu/DO+ynATF08o5BgE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dreki-gg%2fpi-command-sandbox@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4631},"main":"./dist/index.mjs","type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"}},"gitHead":"1416586138a1911d42c7f5efe0a6274c8d927b02","scripts":{"lint":"oxlint src","test":"bun test","build":"tsdown","format":"oxfmt --write src","typecheck":"tsc --noEmit","format:check":"oxfmt --check src"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:9a4aa901-8d95-4fce-9eff-40ee0e8f5376"}},"repository":{"url":"git+https://github.com/jalbarrang/pi-command-sandbox.git","type":"git"},"_npmVersion":"11.16.0","description":"Shared command sandboxing utilities for pi extensions — validates shell commands against safe/destructive pattern lists using proper shell parsing","directories":{},"_nodeVersion":"24.18.0","dependencies":{"shell-quote":"^1.8.3"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.43.0","oxlint":"^1.58.0","tsdown":"^0.22.0","bun-types":"latest","typescript":"^6.0.0","@types/node":"24","@types/shell-quote":"^1.7.5"},"_npmOperationalInternal":{"tmp":"tmp/pi-command-sandbox_0.4.0_1783788721544_0.00850114193639051","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@dreki-gg/pi-command-sandbox","version":"0.4.1","keywords":["pi","shell","sandbox","command-validation","safe-commands","shell-quote"],"author":{"name":"Juan Albarran","email":"jalbarrandev@gmail.com"},"license":"MIT","_id":"@dreki-gg/pi-command-sandbox@0.4.1","maintainers":[{"name":"jalbarrang","email":"jalbarrandev@gmail.com"}],"homepage":"https://github.com/jalbarrang/pi-command-sandbox#readme","bugs":{"url":"https://github.com/jalbarrang/pi-command-sandbox/issues"},"dist":{"shasum":"7f51d789ec50e5b9ac958a51f0fa49fcf3d6d3d7","tarball":"https://registry.npmjs.org/@dreki-gg/pi-command-sandbox/-/pi-command-sandbox-0.4.1.tgz","fileCount":3,"integrity":"sha512-GJOTLVPsoUzHabdGRRsPEWHwCrYGLRho2usyOLfUdoFp9Pz64yL96uwnubGA7hzeSWrqGys2aq1fbkAX926Y3g==","signatures":[{"sig":"MEYCIQDsY+zQred2FsZA2qV/YDxO9QC2dUOAIWzenhSN30azqAIhAI9aCeD8oRQl8Np3Vq+lVW4u3QoCAURFvTe5YvS3HWIP","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dreki-gg%2fpi-command-sandbox@0.4.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4861},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"}},"gitHead":"05b4d571de04af0e5119a84027e98bd0b6cffd6b","scripts":{"lint":"oxlint src","test":"bun test","build":"tsdown","format":"oxfmt --write src","typecheck":"tsc --noEmit","format:check":"oxfmt --check src"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:9a4aa901-8d95-4fce-9eff-40ee0e8f5376"}},"repository":{"url":"git+https://github.com/jalbarrang/pi-command-sandbox.git","type":"git"},"_npmVersion":"11.16.0","description":"Shared command sandboxing utilities for pi extensions — validates shell commands against safe/destructive pattern lists using proper shell parsing","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","dependencies":{"shell-quote":"^1.8.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.43.0","oxlint":"^1.58.0","tsdown":"^0.22.0","bun-types":"latest","typescript":"^6.0.0","@types/node":"24","@types/shell-quote":"^1.7.5"},"_npmOperationalInternal":{"tmp":"tmp/pi-command-sandbox_0.4.1_1783797940777_0.03294066519289096","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"@dreki-gg/pi-command-sandbox","version":"0.4.2","keywords":["pi","shell","sandbox","command-validation","safe-commands","shell-quote"],"author":{"name":"Juan Albarran","email":"jalbarrandev@gmail.com"},"license":"MIT","_id":"@dreki-gg/pi-command-sandbox@0.4.2","maintainers":[{"name":"jalbarrang","email":"jalbarrandev@gmail.com"}],"homepage":"https://github.com/jalbarrang/pi-command-sandbox#readme","bugs":{"url":"https://github.com/jalbarrang/pi-command-sandbox/issues"},"dist":{"shasum":"bab67552c2d20f074d5abff8d9f66080cfbc06b9","tarball":"https://registry.npmjs.org/@dreki-gg/pi-command-sandbox/-/pi-command-sandbox-0.4.2.tgz","fileCount":5,"integrity":"sha512-N3C9Ue68A3HIEKP+LJ4faeBtVhfAzN0jV/uh/ylqT1NElN7p/nDlQZf6/DzaliWSpNc8Cebx7FudnhP33C+0Ug==","signatures":[{"sig":"MEUCIQDWgDwpXyWVlf1HQIpkPC+P8AKUBSqi0nn6pcQzRM8MvgIgG6d9hJ5l+/rCXJfrcduJIAQ8PlpyzYSP6NKYd4hSGQo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dreki-gg%2fpi-command-sandbox@0.4.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":23883},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"}},"gitHead":"de3401e2d84c8eeb1622219e6e6c946138956b3d","scripts":{"lint":"oxlint src","test":"bun test","build":"tsdown","format":"oxfmt --write src","typecheck":"tsc --noEmit","format:check":"oxfmt --check src","prepublishOnly":"bun run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:9a4aa901-8d95-4fce-9eff-40ee0e8f5376"}},"repository":{"url":"git+https://github.com/jalbarrang/pi-command-sandbox.git","type":"git"},"_npmVersion":"11.16.0","description":"Shared command sandboxing utilities for pi extensions — validates shell commands against safe/destructive pattern lists using proper shell parsing","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","dependencies":{"shell-quote":"^1.8.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.43.0","oxlint":"^1.58.0","tsdown":"^0.22.0","bun-types":"latest","typescript":"^6.0.0","@types/node":"24","@types/shell-quote":"^1.7.5"},"_npmOperationalInternal":{"tmp":"tmp/pi-command-sandbox_0.4.2_1783799315317_0.612407968477604","host":"s3://npm-registry-packages-npm-production"}},"0.4.3":{"name":"@dreki-gg/pi-command-sandbox","version":"0.4.3","description":"Shared command sandboxing utilities for pi extensions — validates shell commands against safe/destructive pattern lists using proper shell parsing","author":{"name":"Juan Albarran","email":"jalbarrandev@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/jalbarrang/pi-command-sandbox.git"},"type":"module","main":"./dist/index.mjs","types":"./dist/index.d.mts","exports":{".":{"import":"./dist/index.mjs","types":"./dist/index.d.mts"}},"scripts":{"build":"tsdown","test":"bun test","typecheck":"tsc --noEmit","lint":"oxlint src","format":"oxfmt --write src","format:check":"oxfmt --check src","prepublishOnly":"bun run build"},"dependencies":{"shell-quote":"^1.8.3"},"devDependencies":{"@types/node":"24","@types/shell-quote":"^1.7.5","bun-types":"latest","oxfmt":"^0.43.0","oxlint":"^1.58.0","tsdown":"^0.22.0","typescript":"^6.0.0"},"publishConfig":{"access":"public"},"keywords":["pi","shell","sandbox","command-validation","safe-commands","shell-quote"],"sideEffects":false,"gitHead":"4a274f2696ce1b9acbd4dadabd1368eb5a1df385","_id":"@dreki-gg/pi-command-sandbox@0.4.3","bugs":{"url":"https://github.com/jalbarrang/pi-command-sandbox/issues"},"homepage":"https://github.com/jalbarrang/pi-command-sandbox#readme","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-4UX0FP8jcYHRmHXdxczb3tKfHHxvj0VXssOhSXRXLXwFv281RlTY/rPYPm3lWmHvXqAsiryy2qvA2aDYinAGiQ==","shasum":"08946b87445c8362eec451a7f80ad40cac989fe5","tarball":"https://registry.npmjs.org/@dreki-gg/pi-command-sandbox/-/pi-command-sandbox-0.4.3.tgz","fileCount":5,"unpackedSize":25185,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dreki-gg%2fpi-command-sandbox@0.4.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAy/Qlv7/JtOytfB0YMNruDVlLxm2aHSZtu5WRyc0LmQAiEA/jJ000oUbFOFCynm6xTZgPmIW+zN5te6vtrb5/GMIMY="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:9a4aa901-8d95-4fce-9eff-40ee0e8f5376"}},"directories":{},"maintainers":[{"name":"jalbarrang","email":"jalbarrandev@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-command-sandbox_0.4.3_1785087355356_0.6881872653102312"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-30T05:47:15.210Z","modified":"2026-07-26T17:35:55.975Z","0.3.2":"2026-05-30T05:47:15.554Z","0.4.0":"2026-07-11T16:52:01.671Z","0.4.1":"2026-07-11T19:25:40.917Z","0.4.2":"2026-07-11T19:48:35.449Z","0.4.3":"2026-07-26T17:35:55.512Z"},"bugs":{"url":"https://github.com/jalbarrang/pi-command-sandbox/issues"},"author":{"name":"Juan Albarran","email":"jalbarrandev@gmail.com"},"license":"MIT","homepage":"https://github.com/jalbarrang/pi-command-sandbox#readme","keywords":["pi","shell","sandbox","command-validation","safe-commands","shell-quote"],"repository":{"type":"git","url":"git+https://github.com/jalbarrang/pi-command-sandbox.git"},"description":"Shared command sandboxing utilities for pi extensions — validates shell commands against safe/destructive pattern lists using proper shell parsing","maintainers":[{"name":"jalbarrang","email":"jalbarrandev@gmail.com"}],"readme":"# @dreki-gg/pi-command-sandbox\n\nShared command sandboxing utilities for pi extensions. Validates shell commands against safe/destructive pattern lists using proper shell parsing via [shell-quote](https://github.com/ljharb/shell-quote).\n\n## Why\n\nPi extensions like `plan-mode` and `ask-mode` restrict bash commands to read-only operations. Previously, each extension had its own regex-based parser that only split on pipes (`|`), causing false positives when agents used concatenated commands (`&&`, `||`, `;`) — even when every individual command was safe.\n\nThis package solves that by using `shell-quote` to properly tokenize shell commands, then validating each segment independently.\n\n## Usage\n\n```ts\nimport { isSafeCommand } from '@dreki-gg/pi-command-sandbox';\n\n// Simple commands\nisSafeCommand('ls -la');           // true\nisSafeCommand('rm -rf /');         // false\n\n// Concatenated commands — the fix\nisSafeCommand('cd src && ls -la'); // true  ← was blocked before\nisSafeCommand('ls && rm -rf /');   // false ← still blocked\n\n// Pipes work too\nisSafeCommand('find . -name \"*.ts\" | grep -v node_modules'); // true\n\n// Quoted operators are handled correctly\nisSafeCommand('echo \"hello && world\"'); // true (not split)\n\n// Command substitution is blocked by default\nisSafeCommand('echo $(rm -rf /)'); // false\n```\n\n### Custom options\n\n```ts\nimport { isSafeCommand } from '@dreki-gg/pi-command-sandbox';\n\nisSafeCommand('mkdir -p .plans/my-plan', {\n  // Allow specific commands via predicate\n  allowCommand: (cmd) => /^\\s*mkdir\\s+(-p\\s+)?\\.plans\\//.test(cmd),\n});\n\nisSafeCommand('bun test', {\n  // Extend the safe patterns list\n  extraSafe: [/^\\s*bun\\s+(test|run)/i],\n});\n\nisSafeCommand('curl -X POST https://example.com', {\n  // Extend the destructive patterns list\n  extraDestructive: [/\\bcurl\\s+.*-X\\s+(POST|PUT|DELETE)/i],\n});\n```\n\n### Lower-level API\n\n```ts\nimport { parseCommandSegments, hasCommandSubstitution } from '@dreki-gg/pi-command-sandbox';\n\nparseCommandSegments('cd foo && ls -la');\n// → [{ command: 'cd foo', hasRedirect: false },\n//    { command: 'ls -la', hasRedirect: false }]\n\nhasCommandSubstitution('echo $(whoami)'); // true\n```\n\n## Patterns\n\nThe package exports two pattern lists:\n\n- **`DESTRUCTIVE_PATTERNS`** — commands that modify the filesystem, install packages, manage processes, etc.\n- **`SAFE_PATTERNS`** — read-only commands (ls, cat, grep, git status, etc.)\n\nBoth can be extended via `extraSafe` and `extraDestructive` options. Built-in destructive command names inside `grep` and `rg` search arguments are treated as data, while caller-supplied `extraDestructive` patterns still apply. Shell operators the parser does not explicitly model are denied rather than treated as arguments.\n","readmeFilename":"README.md"}