New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@beloved-lenora/opencode-shell-guard

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install
Package version was removed
This package version has been unpublished, mostly likely due to security reasons
Malware was recently detected in this package.

Affected versions:

0.0.0-stage0.0.1-security1.0.01.0.21.0.3
+1 more

@beloved-lenora/opencode-shell-guard

A pre-execution guard that blocks destructive shell commands before they run, with the reason and a safer alternative.

unpublished
npmnpm
Version
1.0.2
Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
 
Created
Source

opencode-shell-guard

A pre-execution guard that blocks destructive shell commands before they run, with the reason and a safer alternative.

The agent keeps working normally. Only commands that would destroy work, lose history, or run unreviewed remote code get stopped. Everything else passes through untouched.

Installation

OpenCode v2 loads the published package from the plugins array in opencode.json:

{
  "plugins": ["@beloved-lenora/opencode-shell-guard@latest"],
}

Then restart the service (opencode service restart) so the plugin loads.

How it works

Every shell command is checked before execution:

  • The command is parsed quote-aware, including chained segments (&&, ||, ;, |) and command substitutions ($(...), backticks).
  • Common wrappers (sudo, env, bash -c, sh -c) are unwrapped so the real command is what gets judged.
  • If a destructive pattern matches, the command is replaced with a short explanation naming the rule, why it fired, and what to do instead.
  • Quoted text is treated as data. echo 'rm -rf /' and grepped examples never trigger a block.

Unparseable commands are allowed through. The guard fails open rather than breaking your workflow.

What it blocks

Git history and worktree

BlocksWhyDo instead
reset --hard, --mergeDestroys uncommitted changes permanentlyStash first, then reset
checkout -- <path>, checkout -fOverwrites working-tree files permanentlyStash or diff first
clean -fRemoves untracked files permanentlyPreview with clean -n
push -f, --deleteRewrites or deletes remote historyUse --force-with-lease
branch -DDeletes a branch without a merge checkUse lowercase -d
tag -dDeletes a tag permanentlyDelete tags by hand
stash drop, stash clearPermanently deletes stashed changesApply the stash first
restore without --stagedDiscards working-tree changesPreview with diff, or use --staged
switch -f, --discard-changesDiscards uncommitted changesStash or commit first

Abbreviated flags match because git itself accepts unique prefixes. Dry runs (clean -n, --dry-run) and safe variants (--force-with-lease, lowercase -d) always pass.

Filesystem deletion

BlocksWhyDo instead
rm -rf /, ~, ., *, bare /tmpDestroys the machine, home, or working treeDelete a named subdirectory, list first
rm -rf with $VAR or backtick targetsTarget cannot be verified before runningUse literal paths
rm -rf escaping with .. or absolute pathsDeletes outside the working treeStay inside the current directory
--no-preserve-rootExplicitly disables the root-deletion guardNever pass it
find -delete, find -exec rm -rfDeletes whatever the search happens to matchPreview matches first
... | xargs rm -rfDeletes whatever the pipe feeds itUse an explicit file list

Everyday cleanup stays allowed: rm -rf node_modules, rm -rf /tmp/my-dir, and rm -rf $TMPDIR/my-dir all pass.

Disks and devices

BlocksWhy
dd of=/dev/...Overwrites disks or partitions
mkfs ...Formats a disk, destroying all data on it
shred ...Destroys file contents beyond recovery
:(){ :|:& };:Fork bomb hangs the machine

Formatting and device writes are never agent tasks. Do them by hand.

Remote code and piped shells

BlocksWhyDo instead
curl ... | sh, wget ... | bashRuns unreviewed remote codeDownload first, read it, then run it
... | xargs sh -cExecutes piped input as codeAvoid piping dynamic input into a shell

Script one-liners

Code passed to interpreters (python -c, node -e, ruby -e, perl -e) gets the same checks as the equivalent shell command. Hiding rm -rf or git reset --hard inside a one-liner does not bypass the guard.

Examples

Blocked, with explanation:

$ rm -rf /
BLOCKED by shell-guard rm.recursive-catastrophic
Recursive rm targeting /, ~, or the working tree itself is always blocked.
Safer: Delete a named subdirectory instead, and preview with ls first.

Allowed, runs normally:

$ rm -rf node_modules
$ git push --force-with-lease
$ git clean -n
$ echo 'rm -rf /'

Philosophy

  • Default allow. Only known-destructive patterns block. Unknown commands run.
  • Fail open. If a command cannot be parsed, it runs.
  • Explain, don't just deny. Every block names the rule, the reason, and the safer command.
  • Stricter than git. Bare globs, --delete pushes, and forced checkouts block even though some setups tolerate them. Typing the safe variant takes seconds; recovering history takes longer.

FAQs

Package last updated on 15 Oct 2026

Related posts