registry  /  plugin-updater  /  1.5.0

plugin-updater@1.5.0

Plugin lifecycle manager for OpenCode and Claude Code launchers

AI Security Review

scanned 7d ago · by lpm-firewall-ai

No confirmed malicious attack surface was established. The package has high-privilege plugin-manager behavior, but inspected behavior matches its documented OpenCode/Claude plugin updater role.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
User invokes plugin-updater CLI or app imports the plugin entry during configured plugin startup.
Impact
Can update/build/deploy configured plugins and write app plugin/command config; no source evidence of covert exfiltration or attacker-controlled endpoint.
Mechanism
Documented plugin lifecycle manager using git/npm, config writes, command deployment, and optional plugin daemon startup
Rationale
Static inspection shows dangerous primitives, but they are exposed as the documented plugin lifecycle manager and act on configured plugin entries or explicit CLI actions. I found no covert endpoint, credential/file harvesting, install-time execution, or unconsented AI-agent control mutation sufficient to classify this as malicious.
Evidence
package.jsondist/index.jsdist/cli.jsdist/npm.jsdist/git.jsdist/deploy.jsdist/daemon.jsdist/syncbridge.jsdist/commands.jslib/core.jsREADME.mddist/config.jsdist/env.js
Network endpoints4
127.0.0.1:<daemon.port>/healthgithub.com/intisy-ai/plugin-updater.gitgithub.com/intisy-ai/<plugin>opencode.ai/config.json

Decision evidence

public snapshot
AI called this Clean at 78.0% confidence as Benign with high false-positive risk.
Evidence for block
  • dist/index.js auto-activates on import unless PLUGIN_UPDATER_LIBRARY_MODE/ACTIVATION is set.
  • dist/cli.js init writes OpenCode plugin entries or Claude SessionStart hook with npx -y plugin-updater@latest.
  • dist/git.js and dist/npm.js run git/npm commands for configured plugins; arguments are not shell-escaped.
  • dist/deploy.js can import deployed plugin files and start plugin-declared daemons.
Evidence against
  • package.json has only prepublishOnly; no install/postinstall lifecycle execution.
  • README.md describes plugin lifecycle management, auto-run hooks, git/npm updates, and command deployment as package purpose.
  • Network activity is package-aligned: git/npm commands for configured plugin names/URLs and localhost daemon health checks.
  • No credential harvesting, secret scanning, external exfiltration endpoint, persistence outside documented app hooks, or destructive behavior beyond managed plugin dirs found.
  • dist/cli.js control-surface writes are user-invoked init/add/remove actions; import-time earlyLaunch operates from app plugin configuration.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 14 file(s), 67.6 KB of source, external domains: 127.0.0.1, opencode.ai

Source & flagged code

4 flagged · loading source
dist/npm.jsView file
3import os from "os"; L4: import { execSync } from "child_process"; L5: import { isOpencodeHookInvocation } from "./env.js";
High
Child Process

Package source references child process execution.

dist/npm.jsView on unpkg · L3
82} L83: execSync(`npm install -g ${name}`, { stdio: "pipe", timeout: getNpmTimeoutMs() }); L84: writeLog(`Installed npm plugin: ${name}`);
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/npm.jsView on unpkg · L82
dist/syncbridge.jsView file
29try { L30: const bridge = (await import(pathToFileURL(libPath).href)); L31: if (typeof bridge.syncPlugins !== "function") {
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/syncbridge.jsView on unpkg · L29
dist/daemon.jsView file
matchType = previous_version_dangerous_delta matchedPackage = plugin-updater@1.4.3 matchedIdentity = npm:cGx1Z2luLXVwZGF0ZXI:1.4.3 similarity = 0.615 summary = stored previous version shares package body but lacks this dangerous source file
Critical
Previous Version Dangerous Delta

This package version adds a dangerous source file absent from the previous stored version.

dist/daemon.jsView on unpkg

Findings

1 Critical3 High4 Medium5 Low
CriticalPrevious Version Dangerous Deltadist/daemon.js
HighChild Processdist/npm.js
HighShell
HighRuntime Package Installdist/npm.js
MediumDynamic Requiredist/syncbridge.js
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings