registry  /  fleetlens  /  0.15.4

fleetlens@0.15.4

fleetlens — local-only dashboard and usage tracker for Claude Code sessions and agent fleets

AI Security Review

scanned 2d ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No confirmed malicious attack surface was established. The package is a local dashboard/usage CLI with powerful but package-aligned runtime features: self-update, daemon autostart, local agent invocation, and optional team sync.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
Explicit CLI commands such as fleetlens start, update, usage, team join, autostart, menubar, digest, or dashboard API actions
Impact
Reads local agent usage/credential state and may persist Fleetlens services or send aggregate metrics to configured endpoints
Mechanism
user-invoked local telemetry dashboard and agent workflow automation
Rationale
Static inspection shows risky primitives, but they are consistent with Fleetlens' advertised local dashboard, usage tracking, self-update, menubar, and team-sync features, with no install-time execution or hardcoded exfiltration chain. Because it performs first-party persistence/autostart and agent configuration changes under explicit commands, warning is more appropriate than blocking.
Evidence
package.jsondist/index.jsdist/daemon-worker.jsapp/apps/web/app/api/menubar/route.tsapp/apps/web/app/api/pdf/[key]/route.ts~/.cclens/*~/.claude/.credentials.json~/.config/claude/credentials.json~/.claude.json~/Library/LaunchAgents/com.fleetlens.daemon.plist~/Applications/FleetlensMenubar.app
Network endpoints6
registry.npmjs.org/fleetlens/latestapi.anthropic.com/api/oauth/usageapi.z.ai/api/monitor/usage/quota/limitlocalhost:<port><user-provided serverUrl>/api/ingest/metrics<user-provided serverUrl>/api/team/whoami

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/index.js has runtime self-update path fetching registry.npmjs.org and running npm install -g fleetlens@latest.
  • dist/index.js reads Claude OAuth credentials from keychain or ~/.claude credential files to call Anthropic usage APIs.
  • dist/index.js can install macOS LaunchAgent and menu bar app via explicit autostart/menubar commands and team join.
  • dist/index.js modifies ~/.claude.json trust for its own ~/.cclens/runtime before spawning claude under tmux for AI features.
Evidence against
  • package.json defines no preinstall/install/postinstall lifecycle hooks.
  • dist/index.js command dispatch is CLI-driven; dangerous paths are behind start/update/usage/team/autostart/menubar/digest commands, not import-time execution.
  • Network endpoints are package-aligned: npm registry update check, Anthropic/Z.ai usage APIs, localhost dashboard, and user-provided team server URL.
  • Team sync posts aggregate usage/activity rollups to a configured serverUrl with bearer token, not hardcoded exfiltration.
  • No obfuscated payload, eval/Function remote loader, credential exfiltration endpoint, destructive install hook, or foreign AI-agent control-surface mutation found.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsMinifiedUrlStrings
ManifestNo manifest risk signals triggered.
scanned 181 file(s), 2.43 MB of source, external domains: api.anthropic.com, api.z.ai, keepachangelog.com, registry.npmjs.org, team.example.com, z.ai

Source & flagged code

8 flagged · loading source
app/apps/web/app/api/menubar/route.tsView file
1import { execFile } from "node:child_process"; L2: import { promisify } from "node:util";
High
Child Process

Package source references child process execution.

app/apps/web/app/api/menubar/route.tsView on unpkg · L1
app/apps/web/app/api/pdf/[key]/route.tsView file
83L84: function digestExists(match: RegExpExecArray): boolean { L85: const monday = match[2];
High
Shell

Package source references shell execution.

app/apps/web/app/api/pdf/[key]/route.tsView on unpkg · L83
dist/index.jsView file
matchType = previous_version_dangerous_delta matchedPackage = fleetlens@0.15.2 matchedIdentity = npm:ZmxlZXRsZW5z:0.15.2 similarity = 0.833 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; route for source-aware review.

dist/index.jsView on unpkg
5002const dataDir = join3(homedir2(), ".claude", "projects"); L5003: const child = spawn(process.execPath, [serverJs], { L5004: detached: true, ... L5006: env: { L5007: ...process.env, L5008: PORT: String(port), ... L5017: writePid(PID_FILE, pid, port, "0.15.4"); L5018: await waitForHealth(`http://localhost:${port}`, 3e4); L5019: return { pid, port };
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

dist/index.jsView on unpkg · L5002
13import { readFileSync, writeFileSync, mkdirSync, unlinkSync } from "node:fs"; L14: import { execFileSync } from "node:child_process"; L15: import { dirname } from "node:path"; ... L934: "<command-name>", L935: "<local-command-stdout>", L936: "<local-command-caveat>", ... L981: try { L982: const parsed = JSON.parse(body); L983: if (parsed.type === "idle_notification") ... L1503: function walkBoundary(start2) { L1504: const home = realpathOrSelf(homedir()); L1505: return start2 === home || start2.startsWith(`${home}/`) ? home : void 0;
High
Sandbox Evasion Gated Capability

Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.

dist/index.jsView on unpkg · L13
5319try { L5320: execSync(`npm install -g ${PACKAGE_NAME}@latest --prefer-online`, { L5321: stdio: "pipe",
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/index.jsView on unpkg · L5319
13import { readFileSync, writeFileSync, mkdirSync, unlinkSync } from "node:fs"; L14: import { execFileSync } from "node:child_process"; L15: import { dirname } from "node:path"; ... L934: "<command-name>", L935: "<local-command-stdout>", L936: "<local-command-caveat>", ... L981: try { L982: const parsed = JSON.parse(body); L983: if (parsed.type === "idle_notification") ... L1503: function walkBoundary(start2) { L1504: const home = realpathOrSelf(homedir()); L1505: return start2 === home || start2.startsWith(`${home}/`) ? home : void 0;
Medium
Install Persistence

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

dist/index.jsView on unpkg · L13
dist/daemon-worker.jsView file
866Cross-file remote execution chain: dist/daemon-worker.js spawns dist/index.js; helper contains network access plus dynamic code execution. L866: "<command-name>", L867: "<local-command-stdout>", L868: "<local-command-caveat>", ... L913: try { L914: const parsed = JSON.parse(body); L915: if (parsed.type === "idle_notification") ... L1479: const owner = segs.slice(0, -1).join("/"); L1480: return { host, owner, name, url, webUrl: `https://${host}/${owner}/${name}` }; L1481: } ... L1645: toTeammateId, L1646: body: msg.body, L1647: kind: "message"
High
Cross File Remote Execution Context

Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.

dist/daemon-worker.jsView on unpkg · L866

Findings

1 Critical6 High4 Medium4 Low
CriticalPrevious Version Dangerous Deltadist/index.js
HighChild Processapp/apps/web/app/api/menubar/route.ts
HighShellapp/apps/web/app/api/pdf/[key]/route.ts
HighSame File Env Network Executiondist/index.js
HighSandbox Evasion Gated Capabilitydist/index.js
HighCross File Remote Execution Contextdist/daemon-worker.js
HighRuntime Package Installdist/index.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/index.js
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings