registry  /  @lmctl-ai/lmctl  /  0.1.101

@lmctl-ai/lmctl@0.1.101

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

AI Security Review

scanned 2h 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` workflow/provider/MCP commands, including an accepted remote workflow.
Impact
A trusted or deliberately bypassed remote workflow can run commands; explicit MCP operations can alter supported agent configuration files.
Mechanism
User-invoked shell workflow execution and AI-agent MCP configuration management.
Rationale
Source inspection confirms powerful user-invoked agent orchestration and configuration mutation, but no lifecycle execution, stealth persistence, credential exfiltration, or concrete malicious chain. Flag as suspicious for informed firewall warning rather than block.
Evidence
package.jsonbin/lmctldist/cli/index.jsREADME.md
Network endpoints1
lmctl.com/templates/

Decision evidence

public snapshot
AI called this Suspicious at 88.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
  • `dist/cli/index.js` executes workflow `ShellStep` commands and provider CLIs after user CLI invocation.
  • `dist/cli/index.js` writes/removes package MCP entries in Claude, Codex, Copilot, Gemini, Qwen, Antigravity, and OpenCode config paths.
  • `dist/cli/index.js` fetches user-supplied HTTPS workflows and `lmctl://` catalog artifacts.
  • Remote workflow execution is documented as requiring a trust prompt, with an explicit `--no-prompt` option.
Evidence against
  • `package.json` has no `preinstall`, `install`, `postinstall`, or `prepare` lifecycle hook.
  • `bin/lmctl` only imports `runCli` and executes it with explicit command-line arguments.
  • Remote catalog artifacts are HTTPS-only, redirect-rejected, shape-validated, and support SHA-256 integrity pins.
  • No source evidence of automatic credential harvesting or covert exfiltration was found.
  • No concrete install-time mutation of foreign AI-agent configuration is present.
Behavioral surface
Source
ChildProcessEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 1 file(s), 847 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 Nm(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=es(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 Nm(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=es(f.join(` ... L16: `)}catch{}}function SI(){if(!Eo){let e=bI().slice(0,13).replace("T","-");Eo=To($l(),`debug-${e}.log`)}yI(wI(Eo),{recursive:!0})}function Ce(...t){Oe({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 Pk=Object.defineProperty;var E=(t,e)=>()=>(t&&(e=t(t=0)),e);var ne=(t,e)=>{for(var r in e)Pk(t,r,{get:e[r],enumerable:!0})};import{existsSync as Zr,readdirSync as Fk,readFileSy... L2: `)}function Nl(){return Dt(xr(),Jk)}function Sm(){return Dt(xr(),Xk)}function Kk(){try{return Zr(Nl())}catch{return!1}}function vm(t=process.stderr){Kk()&&t.write(`note: legacy ~/.... L3: `)}var Bk,Em,Hk,qk,Tm,Jk,Xk,Rr,Ke=E(()=>{"use strict";Bk=".lmctl",Em="state.db",Hk="workspaces",qk="active-workspace",Tm="default",Jk="profiles",Xk="active-profile";Rr={default:Tm}... L4: `).map(e=>Qn(e)).join(` L5: `)}function Nm(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=es(f.join(` ... L16: `)}catch{}}function SI(){if(!Eo){let e=bI().slice(0,13).replace("T","-");Eo=To($l(),`debug-${e}.log`)}yI(wI(Eo),{recursive:!0})}function Ce(...t){Oe({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 Pk=Object.defineProperty;var E=(t,e)=>()=>(t&&(e=t(t=0)),e);var ne=(t,e)=>{for(var r in e)Pk(t,r,{get:e[r],enumerable:!0})};import{existsSync as Zr,readdirSync as Fk,readFileSy... L2: `)}function Nl(){return Dt(xr(),Jk)}function Sm(){return Dt(xr(),Xk)}function Kk(){try{return Zr(Nl())}catch{return!1}}function vm(t=process.stderr){Kk()&&t.write(`note: legacy ~/.... ... L4: `).map(e=>Qn(e)).join(` L5: `)}function Nm(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=es(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:es(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 SI(){if(!Eo){let e=bI().slice(0,13).replace("T","-");Eo=To($l(),`debug-${e}.log`)}yI(wI(Eo),{recursive:!0})}function Ce(...t){Oe({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