registry  /  @lmctl-ai/lmctl  /  0.1.62

@lmctl-ai/lmctl@0.1.62

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

AI Security Review

scanned 8d ago · by lpm-firewall-ai

No confirmed malicious attack surface was established. The risky primitives are aligned with an AI-agent control-plane CLI and activate through explicit user commands rather than install/import hooks.

Static reason
One or more suspicious static signals were detected.
Trigger
User runs lmctl subcommands such as serve, api, workflow, terminal, code, diagnose, or device.
Impact
Can run configured provider tools, read/write lmctl state and diagnostics, and contact configured/package service endpoints when users invoke those features.
Mechanism
User-invoked CLI orchestration, local SQLite state, optional HTTPS/API/AWS mailbox access, and provider CLI spawning.
Rationale
Static inspection found high-power CLI features, but they are documented, user-invoked, and consistent with the package's AI-agent orchestration purpose. There are no lifecycle hooks, hidden install/import execution, unredacted diagnostic upload, or concrete exfiltration/destructive behavior.
Evidence
package.jsonbin/lmctldist/cli/index.jsREADME.mdworkflows/triage-v2.compound.jsondist/config/ai_test_templates/example-test.md.template~/.lmctl/state.db~/.lmctl/.update-check.json~/.lmctl/recent-intents.log~/.lmctl/cli-tokens.json/tmp/lmctl-diag-<ticket>.tar.gz
Network endpoints5
lmctl.comregistry.npmjs.org/@lmctl-ai/lmctl/latestlmctl.anthropic.com127.0.0.1:8787mailbox.local

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 imports child_process spawn/spawnSync/execFileSync for provider CLIs, gh, which, uname/du.
  • dist/cli/index.js supports HTTPS workflow loading and API calls with LMCTL_API_TOKEN.
  • dist/cli/index.js contains a Codex session launcher with sandbox/approval parameters as part of user-invoked agent orchestration.
Evidence against
  • package.json has no install/preinstall/postinstall lifecycle scripts.
  • bin/lmctl only imports dist/cli/index.js and calls runCli on explicit CLI execution.
  • dist/cli/index.js redacts token/secret/key/password values in diagnostics before bundling.
  • Remote workflow loading is CLI-invoked, HTTPS-only, refuses redirects, and remote run path documents a trust prompt.
  • Network endpoints are package-aligned: lmctl.com docs/workflows, npm update check, local API, AWS mailbox support.
  • No evidence of import-time credential harvesting, persistence, destructive actions, or hidden exfiltration.
Behavioral surface
Source
ChildProcessEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 1 file(s), 799 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=>Mn(e)).join(` L5: `)}function Xf(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=Dn(f.join(`
High
Child Process

Package source references child process execution.

dist/cli/index.jsView on unpkg · L4
4`).map(e=>Mn(e)).join(` L5: `)}function Xf(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=Dn(f.join(` ... L16: `)}catch{}}function Yk(){if(!Zs){let e=Vk().slice(0,13).replace("T","-");Zs=Qs(sl(),`debug-${e}.log`)}Jk(Xk(Zs),{recursive:!0})}function Je(...t){jt({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 dk=Object.defineProperty;var b=(t,e)=>()=>(t&&(e=t(t=0)),e);var le=(t,e)=>{for(var r in e)dk(t,r,{get:e[r],enumerable:!0})};import{existsSync as qr,readdirSync as fk,readFileSy... L2: `)}function el(){return $t(gr(),wk)}function Bf(){return $t(gr(),yk)}function bk(){try{return qr(el())}catch{return!1}}function qf(t=process.stderr){bk()&&t.write(`note: legacy ~/.... L3: `)}var hk,Ff,_k,gk,Uf,wk,yk,yr,Ye=b(()=>{"use strict";hk=".lmctl",Ff="state.db",_k="workspaces",gk="active-workspace",Uf="default",wk="profiles",yk="active-profile";yr={default:Uf}... L4: `).map(e=>Mn(e)).join(` L5: `)}function Xf(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=Dn(f.join(` ... L16: `)}catch{}}function Yk(){if(!Zs){let e=Vk().slice(0,13).replace("T","-");Zs=Qs(sl(),`debug-${e}.log`)}Jk(Xk(Zs),{recursive:!0})}function Je(...t){jt({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 dk=Object.defineProperty;var b=(t,e)=>()=>(t&&(e=t(t=0)),e);var le=(t,e)=>{for(var r in e)dk(t,r,{get:e[r],enumerable:!0})};import{existsSync as qr,readdirSync as fk,readFileSy... L2: `)}function el(){return $t(gr(),wk)}function Bf(){return $t(gr(),yk)}function bk(){try{return qr(el())}catch{return!1}}function qf(t=process.stderr){bk()&&t.write(`note: legacy ~/.... ... L4: `).map(e=>Mn(e)).join(` L5: `)}function Xf(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=Dn(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:Dn(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 Yk(){if(!Zs){let e=Vk().slice(0,13).replace("T","-");Zs=Qs(sl(),`debug-${e}.log`)}Jk(Xk(Zs),{recursive:!0})}function Je(...t){jt({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