registry  /  @lmctl-ai/lmctl  /  0.1.80

@lmctl-ai/lmctl@0.1.80

A provider-agnostic control plane for teams of AI coding agents — across providers, with independent review and durable memory.

AI Security Review

scanned 6d ago · by lpm-firewall-ai

No confirmed malicious attack surface was found. The package is a user-invoked CLI that manages lmctl state, workflows, diagnostics, and AI-agent provider sessions.

Static reason
One or more suspicious static signals were detected.
Trigger
User runs the lmctl CLI or a loaded workflow.
Impact
No unconsented install-time execution, exfiltration, persistence, or destructive behavior confirmed by source inspection.
Mechanism
provider orchestration CLI with explicit network/workflow features
Rationale
The suspicious primitives are package-aligned and user-invoked for an AI-agent control-plane CLI, with no lifecycle hooks or import-time foreign AI-agent control-surface mutation. Source inspection did not show concrete credential exfiltration, remote payload execution, stealth persistence, or destructive install behavior.
Evidence
package.jsonbin/lmctldist/cli/index.jsREADME.mdworkflows/qa-suite.compound.jsonworkflows/pr-fix.compound.json
Network endpoints5
registry.npmjs.org/@lmctl-ai/lmctl/latestlmctl.com/templates/lmctl.comcognito-idp.${t.region}.amazonaws.com/lmctl.anthropic.com

Decision evidence

public snapshot
AI called this Clean at 86.0% confidence as Benign with medium false-positive risk.
Evidence for block
  • dist/cli/index.js can spawn provider CLIs and shells for user-run workflows/agents.
  • dist/cli/index.js fetches HTTPS workflows/templates and calls API endpoints when invoked.
  • dist/cli/index.js has diagnose support that can collect local status, env key presence, logs, and DB/sessiondir disk usage, with redaction logic.
Evidence against
  • package.json defines bin only and no preinstall/install/postinstall lifecycle hooks.
  • bin/lmctl only imports dist/cli/index.js and calls runCli with user CLI args.
  • Network use is aligned with lmctl CLI features: update check, workflow/template fetch, API/device auth, and local server routes.
  • Remote workflow loading requires explicit lmctl workflow/run commands and enforces HTTPS for remote workflow URLs.
  • Diagnostic upload paths are stubbed or user-selected; secrets are redacted unless user passes --no-sanitize.
  • AI-agent config/session actions are explicit CLI workflow/serve/seed commands, not install-time mutation.
Behavioral surface
Source
ChildProcessEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 1 file(s), 810 KB of source, external domains: 127.0.0.1, antigravity.google, api.deepseek.com, api.github.com, api.githubcopilot.com, cli.github.com, docs.anthropic.com, docs.claude.com, docs.github.com, github.com, lmctl.ai, lmctl.anthropic.com, lmctl.com, mailbox.local, nodejs.org, opencode.ai, openrouter.ai, registry.npmjs.org, unpkg.com

Source & flagged code

4 flagged · loading source
dist/cli/index.jsView file
4`).map(e=>Pn(e)).join(` L5: `)}function Qf(t,e){let r=t.toUpperCase();return r.includes("TOKEN")||r.includes("SECRET")||r.includes("KEY")||r.includes("PASSWORD")||r.includes("PASSWD")||r.includes("CREDENTIAL"... L6: `),f=d.slice(Math.max(0,d.length-n));c=f.length,a=Fn(f.join(`
High
Child Process

Package source references child process execution.

dist/cli/index.jsView on unpkg · L4
4`).map(e=>Pn(e)).join(` L5: `)}function Qf(t,e){let r=t.toUpperCase();return r.includes("TOKEN")||r.includes("SECRET")||r.includes("KEY")||r.includes("PASSWORD")||r.includes("PASSWD")||r.includes("CREDENTIAL"... L6: `),f=d.slice(Math.max(0,d.length-n));c=f.length,a=Fn(f.join(` ... L16: `)}catch{}}function dv(){if(!eo){let e=uv().slice(0,13).replace("T","-");eo=to(ul(),`debug-${e}.log`)}iv(av(eo),{recursive:!0})}function Je(...t){At({event:"legacy",msg:t.join(" ")... L17: `)){let r=e.trim();if(!r||r.startsWith("#"))continue;if(r.startsWith("["))break;let n=/^debug\s*=\s*(.+)$/.exec(r);if(n){let s=n[1].trim().toLowerCase().replace(/^["']|["']$/g,"");... L18: CREATE TABLE IF NOT EXISTS session_size (
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/cli/index.jsView on unpkg · L4
1var Ik=Object.defineProperty;var b=(t,e)=>()=>(t&&(e=t(t=0)),e);var ae=(t,e)=>{for(var r in e)Ik(t,r,{get:e[r],enumerable:!0})};import{existsSync as Hr,readdirSync as Nk,readFileSy... L2: `)}function il(){return xt(yr(),Ok)}function Vf(){return xt(yr(),Lk)}function Mk(){try{return Hr(il())}catch{return!1}}function Yf(t=process.stderr){Mk()&&t.write(`note: legacy ~/.... L3: `)}var jk,Xf,Ak,Rk,Gf,Ok,Lk,br,Ye=b(()=>{"use strict";jk=".lmctl",Xf="state.db",Ak="workspaces",Rk="active-workspace",Gf="default",Ok="profiles",Lk="active-profile";br={default:Gf}... L4: `).map(e=>Pn(e)).join(` L5: `)}function Qf(t,e){let r=t.toUpperCase();return r.includes("TOKEN")||r.includes("SECRET")||r.includes("KEY")||r.includes("PASSWORD")||r.includes("PASSWD")||r.includes("CREDENTIAL"... L6: `),f=d.slice(Math.max(0,d.length-n));c=f.length,a=Fn(f.join(` ... L16: `)}catch{}}function dv(){if(!eo){let e=uv().slice(0,13).replace("T","-");eo=to(ul(),`debug-${e}.log`)}iv(av(eo),{recursive:!0})}function Je(...t){At({event:"legacy",msg:t.join(" ")... L17: `)){let r=e.trim();if(!r||r.startsWith("#"))continue;if(r.startsWith("["))break;let n=/^debug\s*=\s*(.+)$/.exec(r);if(n){let s=n[1].trim().toLowerCase().rep
High
Command Output Exfiltration

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

dist/cli/index.jsView on unpkg · L1
1var Ik=Object.defineProperty;var b=(t,e)=>()=>(t&&(e=t(t=0)),e);var ae=(t,e)=>{for(var r in e)Ik(t,r,{get:e[r],enumerable:!0})};import{existsSync as Hr,readdirSync as Nk,readFileSy... L2: `)}function il(){return xt(yr(),Ok)}function Vf(){return xt(yr(),Lk)}function Mk(){try{return Hr(il())}catch{return!1}}function Yf(t=process.stderr){Mk()&&t.write(`note: legacy ~/.... ... L4: `).map(e=>Pn(e)).join(` L5: `)}function Qf(t,e){let r=t.toUpperCase();return r.includes("TOKEN")||r.includes("SECRET")||r.includes("KEY")||r.includes("PASSWORD")||r.includes("PASSWD")||r.includes("CREDENTIAL"... L6: `),f=d.slice(Math.max(0,d.length-n));c=f.length,a=Fn(f.join(` ... L14: `).filter(i=>i.length>0),o=s.slice(Math.max(0,s.length-r));return{source_path:e,tail_lines:o.length,tail:Fn(o.join(` L15: `)),note:null}}catch(n){return n.code==="ENOENT"?{source_path:e,tail_lines:0,tail:"",note:"no intent log present (status never run on this host)"}:{source_path:e,tail_lines:0,tail:... L16: `)}catch{}}function dv(){if(!eo){let e=uv().slice(0,13).replace("T","-");eo=to(ul(),`debug-${e}.log`)}iv(av(eo),{recursive:!0})}function Je(...t){At({event:"legacy",msg:t.join(" ")... L17: `)){let r=e.trim();if(!r||r.s
Low
Weak Crypto

Package source references weak cryptographic algorithms.

dist/cli/index.jsView on unpkg · L1

Findings

4 High2 Medium5 Low
HighChild Processdist/cli/index.js
HighShell
HighSame File Env Network Executiondist/cli/index.js
HighCommand Output Exfiltrationdist/cli/index.js
MediumNetwork
MediumEnvironment Vars
LowWeak Cryptodist/cli/index.js
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License