pi-dcg
Guard Pi shell commands with Destructive Command Guard.
Package details
Install pi-dcg from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-dcg- Package
pi-dcg- Version
0.1.0- Published
- Jul 17, 2026
- Downloads
- 125/mo · 44/wk
- Author
- mocito
- License
- MIT
- Types
- extension
- Size
- 43.4 KB
- Dependencies
- 0 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-dcg
Guard Pi shell commands with Destructive Command Guard (dcg) before they execute.
pi-dcg is a Pi extension bridge. It does not bundle dcg, replace dcg policy, or provide a sandbox.
Requirements
- Node.js 20.6 or newer
- Pi 0.80 or newer
- A separately installed
dcgexecutable; dcg 0.6.8 or newer is recommended
Install dcg using its upstream installation instructions, review its release-verification guidance, and confirm that the binary is visible in the same environment as Pi:
dcg --version
Separate license: dcg is external software with its own nonstandard license, including an OpenAI/Anthropic rider. It is not included in this package. Review the dcg license before installing or using it.
Install
pi install npm:pi-dcg
For project-local installation:
pi install -l npm:pi-dcg
For a one-off checkout test:
pi -e /path/to/pi-mono/packages/pi-dcg
What it guards
By default, the extension checks both Pi shell events available to extensions:
- agent calls to Pi's built-in
bashtool; - user
!commandand!!commandinvocations.
Pi's separate RPC control-channel {"type":"bash"} command does not emit either event in current Pi releases and cannot be intercepted by pi-dcg; see Limitations.
For every non-empty command, the extension starts dcg directly without a shell, sends a Claude-compatible PreToolUse payload on stdin, and waits for dcg's decision before Pi executes the command.
Pi allows tool_call handlers to rewrite tool arguments in sequence. pi-dcg checks mutations made by earlier handlers, then seals both the approved command value and its input reference. If a later handler attempts to replace either one, Pi blocks the tool call rather than executing a command dcg did not check.
| dcg response | Pi behavior |
|---|---|
Empty stdout / explicit allow |
Execute the command |
permissionDecision: "deny" |
Block and show bounded rule/remediation details |
permissionDecision: "ask" |
Ask for confirmation when UI is available; otherwise block |
| Bridge failure | Allow by default, visibly marking dcg unavailable; configurable to block |
Hard denials are never converted into one-click approvals. When dcg provides an allow-once code, pi-dcg shows the exact dcg allow-once ... command only in a user-facing UI notification. It is deliberately excluded from the model-visible blocked tool result so an agent cannot redeem the exception itself.
Run /dcg to probe the binary and show the active bridge configuration.
Why this uses hook mode
The short upstream Pi recipe calls dcg --robot test. pi-dcg deliberately uses dcg's normal hook protocol instead because the current hook path provides the behavior expected from an agent integration:
- Pi-specific agent profiles and their pack/allowlist changes;
- hook policy and confidence handling;
- scoped allow-once checks and pending exception records;
- history/audit integration;
- structured rule, severity, explanation, and remediation fields.
The bridge sets PI_CODING_AGENT=true so dcg resolves [agents.pi] policy. It also sets DCG_NO_SELF_HEAL=1 only for the child process: dcg's default hook self-healing targets Claude settings and should not rewrite those files merely because Pi asked for a decision.
Configuration
pi-dcg uses environment variables for bridge behavior. dcg's own DCG_* variables and TOML files continue to control policy.
| Variable | Default | Purpose |
|---|---|---|
PI_DCG_BIN |
DCG_BIN, then dcg |
Executable name or path. Leading ~/ is expanded. |
PI_DCG_TIMEOUT_MS |
5000 |
Whole child-process timeout, from 100 to 60000 ms. |
PI_DCG_ON_ERROR |
allow |
allow (fail open) or block when the bridge cannot obtain a valid decision. |
PI_DCG_GUARD_USER_BASH |
1 |
Set to 0, false, no, or off to skip user !/!! commands. |
Examples:
PI_DCG_BIN="$HOME/.local/bin/dcg" pi
PI_DCG_ON_ERROR=block pi
PI_DCG_GUARD_USER_BASH=0 pi
PI_DCG_ON_ERROR=block covers bridge failures such as a missing executable, timeout, malformed output, or oversized output. It cannot turn dcg's own intentional fail-open analysis decisions into failures. Configure dcg itself for stricter heredoc and hook behavior.
Pi-specific dcg policy
Current dcg releases recognize the pi agent profile:
# ~/.config/dcg/config.toml or .dcg.toml
[agents.pi]
trust_level = "medium"
extra_packs = ["database", "containers"]
Use real pack or category IDs reported by dcg packs.
Process and data handling
- The command is sent only to the local dcg child process over stdin.
- The extension never invokes a shell to start dcg.
- dcg runs with Pi's current working directory, preserving project policy and allow-once scope.
- Captured stdout and stderr share a 512 KiB limit.
- dcg's human stderr output is captured rather than copied into Pi logs or model context.
- Denial text sent back to Pi is bounded to prevent context flooding.
On startup, this package also sends the monorepo-standard best-effort install/update telemetry ping to mocito.dev, once per package version. It is disabled in CI and respects Pi offline and telemetry settings. It contains the package name/version and platform/runtime/architecture only—never commands, paths, dcg output, or policy.
Limitations
This extension intercepts Pi events, not operating-system process execution. It cannot see:
- custom tools that execute commands under another tool name;
- Pi's RPC control-channel
{"type":"bash"}command, which does not emit auser_bashevent; pi.exec()or child processes started internally by another extension;- destructive behavior performed directly through non-shell tools;
- the contents of an opaque script invoked only as
./script.shunless dcg can infer or inspect the payload; - commands that dcg itself intentionally allows after a parse, size, or deadline fallback.
user_bash handlers are first-result-wins in Pi. An earlier extension that fully handles ! commands can prevent later handlers, including pi-dcg, from seeing them.
Use a container, VM, sandbox, restricted credentials, backups, and review controls when a hard security boundary is required.
Development
npm install
npm run -w packages/pi-dcg check
npm run -w packages/pi-dcg test
npm run -w packages/pi-dcg pack:dry-run
See CONTRIBUTING.md and SECURITY.md.
License
pi-dcg is MIT licensed. dcg is separate external software and is not covered by this package's MIT license. See THIRD-PARTY-NOTICES.