registry  /  publishport-opencli  /  1.8.5-pp.11

publishport-opencli@1.8.5-pp.11

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 established. Risky primitives are aligned with an extensible browser/website CLI and are install- or user-command scoped.

Static reason
One or more suspicious static signals were detected.
Trigger
global npm install, uninstall, or explicit opencli runtime commands
Impact
Package can modify OpenCLI user config and run user-installed adapters/plugins, but inspected behavior is disclosed and package-aligned.
Mechanism
shell completion install, adapter/plugin discovery, local daemon control, site-specific API calls
Rationale
Static inspection found lifecycle hooks and powerful runtime features, but their data flow is package-aligned: completions/config setup, local daemon shutdown, update metadata checks, and user-invoked site adapters. I did not find install-time credential collection, unrelated exfiltration, persistence beyond documented config/completions, or prompt/reviewer manipulation.
Evidence
package.jsonscripts/postinstall.jsscripts/fetch-adapters.jsdist/src/main.jsdist/src/discovery.jsdist/src/launcher.jsdist/src/update-check.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/
Network endpoints4
127.0.0.1:19825/shutdownregistry.npmjs.org/@jackwener/opencli/latestapi.github.com/repos/jackwener/OpenCLI/releases?per_page=20flomoapp.com/api/v1/memo/updated/

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/preuninstall lifecycle hooks.
  • scripts/postinstall.js writes shell completions and ~/.opencli/spotify.env on global install.
  • scripts/fetch-adapters.js can remove stale ~/.opencli/clis overrides on global/explicit install.
  • dist/src/discovery.js imports user adapters/plugins from ~/.opencli at runtime.
Evidence against
  • postinstall is global-install gated, skips CI, and does not edit shell rc files.
  • scripts/fetch-adapters.js has no network calls and only manages OpenCLI adapter state.
  • dist/src/launcher.js only probes/launches local Electron CDP endpoints with user-invoked commands.
  • dist/src/update-check.js only fetches package/release metadata and caches ~/.opencli/update-check.json.
  • clis/flomo/memos.js sends a user browser session token only to flomoapp.com for the requested Flomo command.
  • No credential harvesting or exfiltration to unrelated hosts found in inspected sources.
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