registry  /  publishport-opencli  /  1.8.5-pp.12

publishport-opencli@1.8.5-pp.12

Make any website or Electron App your CLI. AI-powered.

AI Security Review

scanned 2d ago · by lpm-firewall-ai

No confirmed malicious attack surface was found. The risky primitives are tied to an OpenCLI browser/adapter tool: global-install completion setup, local OpenCLI state cleanup, user/plugin discovery, and user-invoked site API calls.

Static reason
One or more suspicious static signals were detected.
Trigger
global npm install, uninstall, or explicit opencli command execution
Impact
No evidence of credential harvesting, covert exfiltration, persistence, or destructive behavior outside OpenCLI-managed files.
Mechanism
benign CLI adapter discovery, local state maintenance, and site-specific network requests
Rationale
Static inspection shows lifecycle hooks and dynamic execution are package-aligned for a CLI framework and are scoped to global-install setup, OpenCLI-managed user state, or explicit commands. I did not find install/import-time credential collection, unauthorized remote exfiltration, AI-agent control mutation, or covert persistence.
Evidence
package.jsonscripts/postinstall.jsscripts/fetch-adapters.jsdist/src/main.jsdist/src/discovery.jsdist/src/external.jsdist/src/launcher.jsdist/src/browser/article-extract.jsclis/flomo/memos.js~/.zsh/completions/_opencli~/.bash_completion.d/opencli~/.config/fish/completions/opencli.fish~/.opencli/spotify.env~/.opencli/adapter-manifest.json~/.opencli/clis~/.opencli/node_modules/@jackwener/opencli
Network endpoints6
127.0.0.1:19825/shutdown127.0.0.1:<cdp-port>/jsonflomoapp.com/api/v1/memo/updated/v.flomoapp.com/developer.spotify.com/dashboardgithub.com/jackwener/opencli/releases

Decision evidence

public snapshot
AI called this Clean at 86.0% confidence as Benign with medium false-positive risk.
Evidence for block
  • package.json has postinstall and preuninstall lifecycle hooks.
  • scripts/fetch-adapters.js can remove stale files under ~/.opencli/clis and legacy shim files.
  • dist/src/discovery.js dynamically imports package/user CLI/plugin modules from clis and ~/.opencli.
  • dist/src/launcher.js uses pgrep/pkill/spawn for user-invoked Electron app launch/restart.
Evidence against
  • scripts/postinstall.js only runs on global install and writes shell completions plus a Spotify template; no rc-file mutation or exfiltration.
  • scripts/fetch-adapters.js states no network calls and only hashes bundled clis to clean stale OpenCLI overrides.
  • preuninstall fetches only http://127.0.0.1:19825/shutdown with an OpenCLI header.
  • dist/src/external.js parses install commands, rejects shell operators, and executes configured/user-registered external CLIs only when invoked.
  • clis/flomo/memos.js sends a browser-derived Flomo token only to flomoapp.com for the requested memos command.
  • article-extract.js uses Function to load bundled @mozilla/readability source into page extraction code, aligned with feature behavior.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetwork
Supply chain
HighEntropyStringsMinifiedObfuscatedTelemetryUrlStrings
Manifest
NoLicense
scanned 1,549 file(s), 4.73 MB of source, external domains: 127.0.0.1, 36kr.com, a.example, account.dianping.com, accounts.douban.com, accounts.google.com, accounts.pixiv.net, accounts.spotify.com, admin.xiaoe-tech.com, api.bilibili.com, api.chess.com, api.coingecko.com, api.dictionaryapi.dev, api.fda.gov, api.github.com, api.juejin.cn, api.llama.fi, api.m.jd.com, api.manus.im, api.npmjs.org, api.nuget.org, api.openalex.org, api.osv.dev, api.ruguoapp.com, api.semanticscholar.org, api.slock.ai, api.spotify.com, api.stackexchange.com, api.tvmaze.com, api.xiaoyuzhoufm.com, api.zhihu.com, api.zsxq.com, api2.mubu.com, api2.openreview.net, apiv1.oschina.net, app.cj.sina.com.cn, app.slock.ai, appxxxx.h5.xet.citv.cn, archive.org, arxiv.org, assets.grok.com, auth.1point3acres.com, auth.band.us, auth.openai.com, azuresearch-usnc.nuget.org, baijiahao.baidu.com, bbs.hupu.com, bid.powerchina.cn, bizapi.csdn.net, blog.51cto.com

Source & flagged code

9 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall.js || true; node scripts/fetch-adapters.js || true
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node scripts/postinstall.js || true; node scripts/fetch-adapters.js || true
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
dist/src/external.jsView file
1import*as Q from"node:fs";import*as Y from"node:path";import*as V from"node:os";import{fileURLToPath as M}from"node:url";import{spawnSync as U,execFileSync as L}from"node:child_pro...
High
Child Process

Package source references child process execution.

dist/src/external.jsView on unpkg · L1
dist/src/browser/article-extract.jsView file
1import*as j from"node:fs";import{createRequire as O}from"node:module";const v=O(import.meta.url);let Y=null;function U(){if(Y)return Y;const Q=v.resolve("@mozilla/readability/Reada... L2: `)}export async function extractArticle(Q,V={}){const Z=buildExtractArticleJs(V),W=await Q.evaluate(Z);if(W==null||typeof W!=="object")return null;const z=W;if(typeof z.html!=="str...
Low
Eval

Package source references a known benign dynamic code generation pattern.

dist/src/browser/article-extract.jsView on unpkg · L1
dist/src/discovery.jsView file
1import*as H from"node:fs";import*as G from"node:os";import*as Y from"node:path";import{fileURLToPath as F,pathToFileURL as v}from"node:url";import{Strategy as A,registerCommand as ... L2: `;try{if(await H.promises.readFile(x,"utf-8")!==B)await H.promises.writeFile(x,B,"utf-8")}catch{await H.promises.writeFile(x,B,"utf-8")}const V=L,q=Y.join(z,"node_modules","@jackwe...
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/src/discovery.jsView on unpkg · L1
clis/flomo/memos.jsView file
1import{cli as y,Strategy as A}from"@jackwener/opencli/registry";import{ArgumentError as m,AuthRequiredError as l,CommandExecutionError as s,EmptyResultError as b}from"@jackwener/op... L2: (() => { ... L5: if (!raw) return null; L6: const me = JSON.parse(raw); L7: const token = me?.access_token || me?.data?.access_token || ''; ... L12: })() L13: `}function P(t){return/auth|unauth|login|token|permission|forbidden|unauthorized|登录|登陆|鉴权|权限/i.test(String(t||""))}function $(t){if(!Array.isArray(t))return"";return t.map((e)=>{if...
Low
Weak Crypto

Package source references weak cryptographic algorithms.

clis/flomo/memos.jsView on unpkg · L1
scripts/postinstall.jsView file
7* standard completion directory. For zsh and bash, the script prints manual L8: * instructions instead of modifying rc files (~/.zshrc, ~/.bashrc) — this L9: * avoids breaking multi-line shell commands and other fragile rc structures. ... L60: function detectShell() { L61: const shell = process.env.SHELL || ''; L62: if (shell.includes('zsh')) return 'zsh'; ... L77: // Skip in CI environments L78: if (process.env.CI || process.env.CONTINUOUS_INTEGRATION) { L79: return; ... L93: L94: const home = homedir(); L95:
Medium
Install Persistence

Source writes installer persistence such as shell profile or service configuration.

scripts/postinstall.jsView on unpkg · L7
dist/src/launcher.jsView file
1import{execFileSync as B,spawn as w}from"node:child_process";import{request as D}from"node:http";import*as K from"node:path";import{getElectronApp as U}from"./electron-apps.js";imp... L2: ${j(W,J)} L3: `+` • Set OPENCLI_CDP_ENDPOINT=http://127.0.0.1:${J} L4: `+` • Or just re-run the command once ${W} is listening on port ${J}.`);if(detectProcess(X)){G.debug(`[launcher] ${W} is running but CDP not available`);if(!await q(`${W} is runni... L5: `);await killProcess(X)}const H=discoverAppPath(W);if(!H)throw new $(`Could not find ${W} on this machine.`,`Install ${W} or register a custom path in ~/.opencli/apps.yaml`);const ...
High
Command Output Exfiltration

Source combines command execution, command-output handling, and outbound requests; review data flow before blocking.

dist/src/launcher.jsView on unpkg · L1
scripts/check-doc-coverage.shView file
path = scripts/check-doc-coverage.sh kind = build_helper sizeBytes = 2256 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

scripts/check-doc-coverage.shView on unpkg

Findings

3 High7 Medium10 Low
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processdist/src/external.js
HighCommand Output Exfiltrationdist/src/launcher.js
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requiredist/src/discovery.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencescripts/postinstall.js
MediumShips Build Helperscripts/check-doc-coverage.sh
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowEvaldist/src/browser/article-extract.js
LowWeak Cryptoclis/flomo/memos.js
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowTelemetry
LowUrl Strings
LowNo License