registry  /  @lmctl-ai/lmctl  /  0.1.118

@lmctl-ai/lmctl@0.1.118

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

AI Security Review

scanned 3h ago · by lpm-firewall-ai

Review flagged AI-agent configuration or capability changes. This remains warn-only unless evidence shows foreign-agent hijack through preinstall/install/postinstall, hidden persistence, exfiltration, remote code execution, or other concrete malicious behavior.

Static reason
One or more suspicious static signals were detected.
Trigger
User runs lmctl commands, including team seed or remote workflow/MCP/skill loading.
Impact
May alter first-party lmctl bridge entries in AI-agent user configuration and execute user-selected provider CLIs; no credential exfiltration or stealth persistence was confirmed.
Mechanism
Explicit CLI orchestration with guarded agent-config cleanup and HTTPS artifact retrieval.
Rationale
No lifecycle hook, unsolicited execution, credential harvesting, or exfiltration chain was found. Warn because explicit runtime team seeding can mutate broad AI-agent configuration surfaces, although cleanup is shape-gated and package-aligned.
Evidence
package.jsonbin/lmctldist/cli/index.jsCHANGELOG.md~/.claude.json~/.codex/config.toml~/.gemini/settings.json~/.copilot/mcp-config.json~/.config/opencode/opencode.json
Network endpoints1
registry.npmjs.org/@lmctl-ai/lmctl/latest

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
  • `dist/cli/index.js` removes recognized lmctl MCP entries from user agent configs during team seed.
  • Cleanup targets `~/.claude.json`, `~/.codex/config.toml`, Gemini, Copilot, Qwen, and OpenCode config paths.
  • CLI can fetch remote HTTPS workflow/MCP/skill artifacts and invoke provider CLIs.
Evidence against
  • `package.json` has no preinstall, install, postinstall, or prepare lifecycle scripts.
  • `bin/lmctl` invokes `runCli` only after the user executes `lmctl`.
  • MCP cleanup is shape-gated to lmctl/lmctl0 command signatures, avoiding unrelated servers.
  • Fetch helper requires HTTPS, uses a timeout, and refuses redirects.
  • No eval, VM, native binary loading, credential exfiltration, or covert install-time execution found.
Behavioral surface
Source
ChildProcessEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 1 file(s), 827 KB of source, external domains: 127.0.0.1, antigravity.google, api.github.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, registry.npmjs.org, unpkg.com

Source & flagged code

4 flagged · loading source
dist/cli/index.jsView file
4`).map(e=>qn(e)).join(` L5: `)}function vm(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=Jn(f.join(`
High
Child Process

Package source references child process execution.

dist/cli/index.jsView on unpkg · L4
4`).map(e=>qn(e)).join(` L5: `)}function vm(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=Jn(f.join(` ... L16: `)}catch{}}function fI(){if(!uo){let e=dI().slice(0,13).replace("T","-");uo=fo(wl(),`debug-${e}.log`)}aI(lI(uo),{recursive:!0})}function Oe(...t){Xe({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 Nv=Object.defineProperty;var T=(t,e)=>()=>(t&&(e=t(t=0)),e);var ae=(t,e)=>{for(var r in e)Nv(t,r,{get:e[r],enumerable:!0})};import{existsSync as qr,readdirSync as xv,readFileSy... L2: `)}function hl(){return Lt(Tr(),Ov)}function Tm(){return Lt(Tr(),Cv)}function Dv(){try{return qr(hl())}catch{return!1}}function bm(t=process.stderr){Dv()&&t.write(`note: legacy ~/.... L3: `)}var $v,ym,jv,Lv,wm,Ov,Cv,Sr,ze=T(()=>{"use strict";$v=".lmctl",ym="state.db",jv="workspaces",Lv="active-workspace",wm="default",Ov="profiles",Cv="active-profile";Sr={default:wm}... L4: `).map(e=>qn(e)).join(` L5: `)}function vm(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=Jn(f.join(` ... L16: `)}catch{}}function fI(){if(!uo){let e=dI().slice(0,13).replace("T","-");uo=fo(wl(),`debug-${e}.log`)}aI(lI(uo),{recursive:!0})}function Oe(...t){Xe({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 Nv=Object.defineProperty;var T=(t,e)=>()=>(t&&(e=t(t=0)),e);var ae=(t,e)=>{for(var r in e)Nv(t,r,{get:e[r],enumerable:!0})};import{existsSync as qr,readdirSync as xv,readFileSy... L2: `)}function hl(){return Lt(Tr(),Ov)}function Tm(){return Lt(Tr(),Cv)}function Dv(){try{return qr(hl())}catch{return!1}}function bm(t=process.stderr){Dv()&&t.write(`note: legacy ~/.... ... L4: `).map(e=>qn(e)).join(` L5: `)}function vm(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=Jn(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:Jn(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 fI(){if(!uo){let e=dI().slice(0,13).replace("T","-");uo=fo(wl(),`debug-${e}.log`)}aI(lI(uo),{recursive:!0})}function Oe(...t){Xe({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