registry  /  @snag-run/cli  /  0.2.5

@snag-run/cli@0.2.5

snag CLI — generate and view Snag Maps (Happy Path → Failure Map) from a PRD or spec.

AI Security Review

scanned 2h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No install-time or import-time malicious behavior was found. The notable risk is explicit user-command installation of a first-party agent skill into Claude/Codex skill directories, plus user-invoked map generation and snapshot push behavior.

Static reason
No blocking static signals were detected.; previous stored version diff introduced dangerous source
Trigger
Explicit CLI commands: `snag skills install`, `snag map`, `snag push`, or `snag view`
Impact
Can add a bundled snag-map skill to user agent skill directories and can push committed map JSON to the configured Snag backend when the user supplies SNAG_API_KEY.
Mechanism
first-party CLI with user-invoked filesystem writes, local viewer, git queries, and authenticated snapshot upload
Rationale
Source inspection shows package-aligned CLI behavior with guarded, user-invoked network and filesystem effects. Because it can explicitly install a first-party agent skill into broad agent skill directories, warn rather than block.
Evidence
package.jsondist/bin.jsdist/index.jsdist/commands/skills.jsdist/skills/snag-map/SKILL.mddist/commands/push.jsdist/commands/map.jsdist/commands/view.jsdist/path-guard.js.snag/maps~/.agents/skills/snag-map/SKILL.md~/.claude/skills/snag-map~/.codex/skills/snag-map
Network endpoints1
snag.run

Decision evidence

public snapshot
AI called this Suspicious at 88.0% confidence as Benign with medium false-positive risk.
Evidence for warning
  • dist/commands/skills.js installs bundled dist/skills/snag-map/SKILL.md into ~/.agents/skills and symlinks ~/.claude/skills and ~/.codex/skills
  • dist/commands/push.js sends SNAG_API_KEY as Bearer auth on explicit `snag push`
  • dist/commands/map.js uses child_process execFile only for git check-ignore
  • dist/commands/push.js uses child_process execFile only for git ls-tree/show
Evidence against
  • package.json has no preinstall/install/postinstall lifecycle scripts
  • dist/bin.js only dispatches explicit CLI argv to runCli
  • dist/commands/skills.js runs only via explicit `snag skills install` and avoids clobbering non-symlink user content
  • dist/commands/push.js defaults to https://snag.run and blocks remote plaintext HTTP unless explicitly overridden
  • dist/commands/map.js writes generated maps under .snag/maps with cwd confinement and symlink guard
  • dist/commands/view.js serves local read-only GET routes on 127.0.0.1 and confines map reads to .snag/maps
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 10 file(s), 112 KB of source, external domains: 127.0.0.1, snag.run

Source & flagged code

2 flagged · loading source
dist/commands/map.jsView file
matchType = previous_version_dangerous_delta matchedPackage = @snag-run/cli@0.2.4 matchedIdentity = npm:QHNuYWctcnVuL2NsaQ:0.2.4 similarity = 0.778 summary = stored previous version shares package body but lacks this dangerous source file
High
Previous Version Dangerous Delta

This package version adds a dangerous source file absent from the previous stored version; route for source-aware review.

dist/commands/map.jsView on unpkg
1import { createHash } from "node:crypto"; L2: import { execFile } from "node:child_process"; L3: import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises"; ... L39: // `generate` and `checkIgnored` so the command's behavior (path mirroring, dir L40: // creation, atomic write, ignore warning, exit codes, error messages) is L41: // unit-tested without a network/LLM key or shelling out to git. ... L52: return injected; L53: const resolved = resolveLogLevels({}, { SNAG_LOG: process.env.SNAG_LOG }); L54: const levels = "error" in resolved ... L118: return mapAndPersist(file, { L119: cwd: deps.cwd ?? process.cwd(), L120: engineOpts: deps.engineOpts ?? {},
Low
Weak Crypto

Package source references weak cryptographic algorithms.

dist/commands/map.jsView on unpkg · L1

Findings

1 High2 Medium5 Low
HighPrevious Version Dangerous Deltadist/commands/map.js
MediumNetwork
MediumEnvironment Vars
LowScripts Present
LowWeak Cryptodist/commands/map.js
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings