Skills/npm/forge

forge@0.17.0

VERIFIED· install only

Publisher claims: "Multi-model coding with a reviewer that reads the code: plan, build in parallel worktrees, review every real diff, merge only what passes." Observed in sandbox: no network, touches nothing outside the project, writes no memory.

Registry npm (MCP server)Publisher giamme · publishing for 24 daysInstalls 2,712Last detonated 2d ago
$claude mcp add forge -- npx -y @giamme/forge
WatchReport an issue

Coverage

Nothing executable in the bundle ran; the trace covers the install step only.
Tested
every file read, file written and host contacted by what ran
Not tested
use of the skill by an agent

Is [email protected] safe to install?

KillerSkills ran it in the KillerSkills honeypot sandbox (1 scenario; nothing executable in the bundle ran; the trace covers the install step only) on 2026-11-12 and scored it 84/100 (Verified). In what ran, nothing we could detect went wrong: no undeclared network egress, no credential reads, no persistent instruction writes. What it does with a real credential was not observed; the static findings and the publisher carry the rest of the score. Summary: no network, touches nothing outside the project, writes no memory.

Behavior trace

Honeypot run · 0 s · 1 scenarios · 0 deviations
t+CategoryObserved action
0.0sprocessno install scripts in bundle
0.0sprocessscript backend runs setup only
0.0sprocessscript backend runs setup only
0.0sprocessno install scripts to re-run

Static findings

MEDIUM
Python subprocess execution detectedscripts/forge-control.py:597 · Python subprocess execution detectedsubprocess.run(cmd, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=10)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-dispatch.sh:430 · Process kill command — agent can terminate processesif [ -n "${hpid:-}" ] && kill -0 "$hpid" 2>/dev/null; thenFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandscripts/forge-dispatch.sh:432 · Process kill command — agent can terminate processespkill -TERM -P "$hpid" 2>/dev/null; kill -TERM "$hpid" 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandscripts/forge-dispatch.sh:434 · Process kill command — agent can terminate processessleep 1; kill -s KILL -- "-$hpid" 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-compare.py:293 · Python subprocess execution detectedplanned = subprocess.run(['bash', str(SKILL / 'scripts' / 'forge-parallel.sh'), 'plan', str(new['plan']),Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-config.py:530 · Python subprocess execution detectedrun = subprocess.run([sys.executable, script, 'gate', gate, value],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-compare.py:322 · Python subprocess execution detectedrc = subprocess.run(command.split(), stdin=subprocess.DEVNULL).returncodeFix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
HIGH
Authorization escalation languageSKILL.md:55 · Authorization escalation languagetop-level `--planner` as `--fractal-planner`; otherwise each task's initial root modelFix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.
AST01
MEDIUM
Python subprocess execution detectedscripts/forge-fail-first.py:55 · Python subprocess execution detectedreturn subprocess.run(['git', '-C', str(repo), *args], input=data, capture_output=True,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-dispatch.sh:431 · Process kill command — agent can terminate processes[ "${GUARD_ON:-0}" != 1 ] || kill -s TERM -- "-$hpid" 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-control.py:680 · Python subprocess execution detecteddone = subprocess.run(base + ['--spec', spec, '--role', role], capture_output=True, text=True,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-compare.py:55 · Python subprocess execution detectedout = subprocess.run(['git', '-C', str(repo), *args], capture_output=True, text=True, stdin=subprocess.DEVNULL)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-dispatch.sh:429 · Process kill command — agent can terminate processes[ -z "${tpid:-}" ] || kill -TERM "$tpid" 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-config.py:84 · Python subprocess execution detectedout = subprocess.run(['git', '-C', path, 'rev-parse', '--show-toplevel'],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-metrics.sh:49 · Process kill command — agent can terminate processes( sleep $(( limit + 10 )); kill -KILL "$pid" 2>/dev/null ) >/dev/null 2>&1 &Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-issues.py:174 · Python subprocess execution detectedres = subprocess.run(cmd, cwd=cwd, input=stdin, capture_output=True, text=True, env=env, timeout=120)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-schedule.py:439 · Python subprocess execution detectedstopping.append((name, role, subprocess.Popen(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-jev-options.sh:68 · Process kill command — agent can terminate processesFORGE_JEV=off is a hard kill switch and wins over every other setting, and a repo'sFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-pr.py:195 · Python subprocess execution detectedlocal = subprocess.run(['git', '-C', str(repo), 'rev-parse', '--verify', '--quiet', 'refs/heads/' + head],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-parallel.sh:1965 · Process kill command — agent can terminate processeskill -TERM -- "-$group" 2>/dev/null || { termed=0; kill -TERM "$group" 2>/dev/null; }Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandscripts/forge-metrics.sh:35 · Process kill command — agent can terminate processes# default 20, plus a kill 10 s later), never changes the caller's exit code, logs its errors to theFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandscripts/forge-parallel.sh:1516 · Process kill command — agent can terminate processeskill -USR1 "$shadow_pid" 2>/dev/null || trueFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-sweep.py:140 · Python subprocess execution detectedresult = subprocess.run(['git', '-C', str(cwd), *args], capture_output=True)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-jev-options.sh:422 · Process kill command — agent can terminate processes# on after every level (run flags, the kill switch and the privacy floor included) andFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandscripts/forge-jev-options.sh:24 · Process kill command — agent can terminate processes# first time: FORGE_JEV=off is a hard kill switch that wins over everything, and untilFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandscripts/forge-lib-attribute.sh:314 · Process kill command — agent can terminate processes[ "$ATTR_STOP" = 1 ] && kill -TERM "$ATTR_CHILD" 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-runs.py:43 · Python subprocess execution detectedout = subprocess.run(['git', '-C', str(start), 'rev-parse', '--show-toplevel'], capture_output=True,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-verify-failed.py:40 · Python subprocess execution detectedout = subprocess.run(['git', '-C', checkout, 'ls-files', '-z'], capture_output=True, check=True).stdoutFix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-lib-attribute.sh:339 · Process kill command — agent can terminate processestrap 'ATTR_STOP=1; [ -n "$ATTR_CHILD" ] && kill -TERM "$ATTR_CHILD" 2>/dev/null' TERM INTFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-shadow.py:265 · Python subprocess execution detectedSTATE['child'] = subprocess.Popen(argv, stdin=subprocess.DEVNULL, stdout=log, stderr=subprocess.STDOUT,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-ripwire.py:26 · Python subprocess execution detectedprocess = subprocess.Popen(command, cwd=cwd, stdin=subprocess.DEVNULL,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-guard.py:394 · Python subprocess execution detectedout = subprocess.run([ps, '-p', str(pid), '-o', field + '='], stdout=subprocess.PIPE,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-ripwire.py:52 · Process kill command — agent can terminate processes# Also kill descendants that closed their pipes before the parent exited.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandscripts/forge-lib-attribute.sh:116 · Process kill command — agent can terminate processes[ "$ATTR_STOP" = 1 ] && kill -TERM "$ATTR_CHILD" 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-guard.py:114 · Python subprocess execution detectedout = subprocess.run([ps, '-axo', 'pid=,pgid=,stat=,command='],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-submodules.py:70 · Python subprocess execution detectedreturn subprocess.run(git_cmd(*args), capture_output=True, env=git_env(), timeout=timeout)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-metrics.sh:52 · Process kill command — agent can terminate processespkill -P "$watcher" 2>/dev/null; kill "$watcher" 2>/dev/null; wait "$watcher" 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-runtime.py:59 · Python subprocess execution detectedresult = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
File type combined with upload actionscripts/forge-parallel.sh:528 · File type combined with upload action — agent may exfiltrate local data files# `on` marks the ones no task covers pending in plan-gates.json; the send-back file belowFix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why.
AST07
MEDIUM
Python subprocess execution detectedscripts/forge-runs-rm.py:408 · Python subprocess execution detecteddone = subprocess.run(['git', '--no-optional-locks', '-C', repo, *args], capture_output=True, text=True,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-shadow.py:328 · Python subprocess execution detectedresult = subprocess.run(['/bin/bash', str(DISPATCH), 'doctor', '--spec', spec, '--role', 'qa', *flags],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-issues.py:1099 · Process kill command — agent can terminate processesflags, the kill switch, the privacy floor and a missing key all count. A gate that cannot answer behaves asFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandscripts/forge-parallel.sh:1971 · Process kill command — agent can terminate processeswhile kill -0 -- "-$group" 2>/dev/null || { [ "$termed" = 0 ] && kill -0 "$group" 2>/dev/null; }; doFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandscripts/forge-shadow.py:231 · Process kill command — agent can terminate processes# and SIGUSR1's default action would kill a launcher that is still preparing.Fix: Rename the tool with a prefix unique to your server.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-schedule.py:729 · Python subprocess execution detectedresult = subprocess.run([sys.executable, ROUTE, 'attempt-cap', '--plan', str(plan), '--task', name],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-lib-attribute.sh:95 · Process kill command — agent can terminate processes[ "$ATTR_STOP" = 1 ] && kill -TERM "$ATTR_CHILD" 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-pr.py:213 · Python subprocess execution detectedreturn 1 if subprocess.run(argv, cwd=repo, stdin=subprocess.DEVNULL).returncode else 0Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-verify.py:206 · Python subprocess execution detectedproc = subprocess.Popen(argv, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-fail-first.py:95 · Python subprocess execution detecteddone = subprocess.run(command, shell=True, cwd=str(cwd), capture_output=True, text=True,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-schedule.py:742 · Python subprocess execution detectedresult = subprocess.run(['/bin/bash', script, '_prepare_retry', str(plan), name, '--resume'])Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-ui.py:218 · Python subprocess execution detectedproc = subprocess.Popen(command, cwd=str(state), stdin=subprocess.DEVNULL, stdout=out, stderr=out,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-route.py:551 · Python subprocess execution detecteddone = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Process kill commandscripts/forge-lib-attribute.sh:447 · Process kill command — agent can terminate processestrap 'stopped=1; [ -n "$job" ] && kill -TERM "$job" 2>/dev/null' TERM INTFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-shadow.py:128 · Python subprocess execution detectedout = subprocess.run(['/bin/bash', str(DISPATCH), 'qa', spec, '--run-dir', tmp, '--prompt-file',Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-ui.py:265 · Python subprocess execution detectedproc = subprocess.Popen(command, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-submodules.py:252 · Python subprocess execution detectedproc = subprocess.Popen(git_cmd('--git-dir=' + gitdir, 'archive', '--format=tar', sha),Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-guard.py:198 · Python subprocess execution detectedout = subprocess.run([ps, '-axo', 'pid=,ppid=,stat=,lstart=,command='], stdout=subprocess.PIPE,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-pr.py:198 · Python subprocess execution detectedupstream = subprocess.run(['git', '-C', str(repo), 'for-each-ref', '--format=%(upstream)', 'refs/heads/' + head],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-shadow.py:186 · Python subprocess execution detectedreturn subprocess.run(['/bin/bash', '-c', 'source "$1"; shift; "$@"', '_', str(ARTIFACT), function, *args],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-schedule.py:654 · Python subprocess execution detectedresult = subprocess.run(['/bin/bash', script, '_merge', str(plan), name])Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-schedule.py:705 · Python subprocess execution detectedresult = subprocess.run(['/bin/bash', script, '_prepare_retry', str(plan), name])Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-watch.py:148 · Python subprocess execution detectedsubprocess.run(build(title, clean(describe(event))), stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
LOW
Unpinned dependencyscripts/forge-update.sh:31 · Unpinned dependencyecho 'forge: installed with npm; update with: npm install -g @giamme/forge@latest && forge install' >&2; return 2 ;;Fix: Pin the exact version (`[email protected]`, `==1.2.3`) so every install gets the bytes that were reviewed.
AST06
MEDIUM
Python subprocess execution detectedscripts/forge-version.py:52 · Python subprocess execution detectedout = subprocess.run(['git', '-C', str(source), *args], capture_output=True, text=True,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
File permission modification commandscripts/forge_jev/verify.py:169 · File permission modification command — agent changes file ownership/permissions# A runner script that was never chmod +x is still the project's realFix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge_jev/verify.py:368 · Python subprocess execution detectedlisted = subprocess.run(['git', '-C', str(repo), 'ls-files', '-z'],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-verify.py:436 · Python subprocess execution detectedproc = subprocess.Popen(['/bin/bash', '-c', lane['command']], cwd=self.checkout,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge_jev/gates.py:147 · Python subprocess execution detectedout = subprocess.run(['git', '-C', str(repo), 'ls-files', '-z'],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
File type combined with upload actionscripts/forge-verify.py:353 · File type combined with upload action — agent may exfiltrate local data files"""Rewrite lanes.json. State changes force it; output only marks it due."""Fix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why.
AST07
MEDIUM
Python subprocess execution detectedscripts/forge_jev/gates.py:163 · Python subprocess execution detectedout = subprocess.run(['git', '-C', str(repo), '-c', 'core.quotePath=false', 'log',Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge_jev/cli.py:960 · Python subprocess execution detectedout = subprocess.run(['git', '-C', str(Path(anchor).parent), 'rev-parse', '--show-toplevel'],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-watch.py:178 · Python subprocess execution detectedreturn subprocess.run(['git', '-C', str(repo), 'ls-files', '--error-unmatch', '--', str(path)], stdin=subprocess.DEVNULL,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Python subprocess execution detectedscripts/forge-watch.py:166 · Python subprocess execution detecteddone = subprocess.run(argv_or_cmd, shell=shell, cwd=cwd, env=hook_env(event), stdin=subprocess.DEVNULL,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05

Cost to the agent

Instructions loaded
≈4,399 tok
1 file · 80 in bundle

Tokens estimated at four characters each. Skills load their instruction text when triggered; the figure is what that costs.

Known vulnerabilities

No advisories in OSV for @giamme/forge@0.17.0 as of 2d ago. This is the package itself, not its dependencies.