AI Security Review
scanned 5h ago · by lpm-firewall-aiThe CLI provides an agent-callable OS scheduling feature that survives process exit. No install-time mutation or concrete exfiltration chain was found.
Static reason
No blocking static signals were detected.
Trigger
Run the `agentx` CLI and invoke its ScheduleTask tool with an OS-routed trigger.
Impact
A permitted or model-initiated runtime tool call can create persistent headless agent execution.
Mechanism
Creates per-job shell scripts and registers launchd, cron, or at jobs.
Rationale
The package is not concretely malicious, but its runtime agent tools can establish persistent headless execution and execute configured local hooks. Flag as a warning for dangerous capability rather than blocking publication.
Evidence
package.jsondist/cli.jsdist/index.jsdist/tools.shell.js$HOME/.agent/sched/<id>.sh$HOME/.agent/sched/<id>.json$HOME/Library/LaunchAgents/cc.livx.agentx.sched-<id>.plistuser crontab
Decision evidence
public snapshotAI called this Suspicious at 90.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
- `dist/cli.js` exposes ScheduleTask to the running agent.
- ScheduleTask can persist jobs via launchd, crontab, or at.
- `dist/cli.js` writes executable job scripts under `$HOME/.agent/sched`.
- Configured hooks execute shell commands from local `.agent` config.
Evidence against
- `package.json` has no preinstall/install/postinstall hook.
- `prepare` only sets this repository's Git hooks path.
- No source shows secret harvesting or unprompted network exfiltration.
- `.claude` settings are read for compatibility; no foreign-agent config write found.
- Network calls implement explicit web search, OAuth, and update checks.
Behavioral surface
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShellWebSocket
HighEntropyStringsObfuscatedUrlStrings
WildcardDependency
Source & flagged code
3 flagged · loading sourcedist/index.jsView file
4251if (!/^[A-Za-z_]\w{0,39}$/.test(spec.name)) throw new Error(`invalid tool name '${spec.name}'`);
L4252: const fn = new Function("args", "ctx", `"use strict"; return (async (args, ctx) => { ${spec.code} })(args, ctx);`);
L4253: return {
Low
Eval
Package source references a known benign dynamic code generation pattern.
dist/index.jsView on unpkg · L4251dist/cli.jsView file
507try {
L508: _dnsLookup = (await import("dns/promises")).lookup;
L509: } catch {
Medium
Dynamic Require
Package source references dynamic require/import behavior.
dist/cli.jsView on unpkg · L50722CONFIG_FILE_RE = /(^|\/)\.(agent|claude)\/(settings(\.[\w-]+)?\.json|config\.(json|js|mjs|cjs|ts))$/i;
L23: SECRET_PAIR = /((?:^|[\s,{[])(?:export\s+)?["']?[\w.\-]*(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|PRIVATE_KEY|ACCESS_?KEY|AUTH(?:_?TOKEN)?|BEARER)[\w.\-]*["']?\s*[:=]\s*)(["']...
L24: SECRET_TOKEN = /\b(sk-ant-[\w-]{12,}|sk-[A-Za-z0-9]{20,}|ghp_[A-Za-z0-9]{20,}|gho_[A-Za-z0-9]{20,}|github_pat_[\w]{20,}|xox[baprs]-[\w-]{10,}|AKIA[0-9A-Z]{12,}|AIza[\w-]{20,}|eyJ[\...
...
L522: if (!reader) {
L523: const t = await res.text();
L524: return t.length > maxBytes ? t.slice(0, maxBytes) : t;
...
L591: if (blocked) return `Error: refusing to fetch a private/internal address (${blocked}) \u2014 set allowPrivateHosts to override`;
L592: res = await doFetch(current, { signal: ctl.signal, redirect: "manual", headers: { "user-agent": "agentx (+https://github.com/Livshitz/agentx)" } });
L593: if (res.status >= 300 && res.status < 400 && res.headers.get("location")) {
...
L652: headers: { authorization: `Bearer ${opts.key}`, "content-type": "application/json" },
L653: body: JSON.stringify({ query: q2, limit: opts.maxResults })
L654: });
Medium
Install Persistence
Source writes installer persistence such as shell profile or service configuration.
dist/cli.jsView on unpkg · L22Findings
6 Medium7 Low
MediumDynamic Requiredist/cli.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/cli.js
MediumStructural Risk Force Deep Review
MediumWildcard Dependency
LowNon Install Lifecycle Scripts
LowScripts Present
LowEvaldist/index.js
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowUrl Strings