registry  /  @lmctl-ai/lmctl  /  0.1.64

@lmctl-ai/lmctl@0.1.64

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

AI Security Review

scanned 7d 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
Explicit lmctl commands such as seed, chat, workflow run, diagnose, or normal CLI invocation
Impact
Can run AI provider CLIs with broad tool permissions and load remote workflows after user action; risk is capability abuse, not covert malware.
Mechanism
user-invoked agent orchestration with permission-bypass provider flags and local config writes
Policy narrative
A user running lmctl can seed teams, install an lmctl MCP bridge, write local team/skill/config files, fetch remote workflows or skills over HTTPS, and launch provider CLIs with YOLO/permission-bypass flags. These are powerful and risky, but they are explicit CLI workflows aligned with the package purpose and are not delivered by npm lifecycle hooks or covert import-time execution.
Rationale
Static inspection supports a warning for dangerous AI-agent orchestration capability, but not a publish block: activation is user-invoked and package-aligned, with no install-time mutation or exfiltration found. The scanner's env/network/child_process findings map to documented diagnostics, update checks, remote workflow loading, and provider CLI control.
Evidence
package.jsonbin/lmctlREADME.mddist/cli/index.js~/.lmctl/state.db~/.lmctl/.update-check.json<teamfile>.lmctldurable-memory/skills/*.md.mcp.json.opencode/opencode.json/tmp/lmctl-diag-*.tar.gz
Network endpoints6
registry.npmjs.org/@lmctl-ai/lmctl/latestlmctl.comlmctl.anthropic.comapi.githubcopilot.comapi.deepseek.com/v1openrouter.ai/api/v1

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/cli/index.js defines provider launch/resume commands with permission bypass flags for claude/codex/gemini/copilot/qwen/agy.
  • lmctl seed writes teamfile session ids, durable-memory/skills/*.md, and may install .mcp.json for the Lead provider.
  • opencode setup writes .opencode/opencode.json with permission:"allow" and lmctl MCP config.
  • workflow/skill loading accepts https URLs; workflow run has --yes/--no-prompt trust bypass for remote workflows.
Evidence against
  • package.json has no lifecycle scripts; install/import does not auto-run package logic.
  • bin/lmctl only imports runCli and executes on explicit CLI invocation.
  • README describes a multi-agent AI coding control plane; child_process and provider CLI use are package-aligned.
  • Diagnostics redact secret-like env values and upload modes are stubbed or user-invoked.
  • No evidence of credential exfiltration, destructive persistence, shell startup/VCS hook mutation, or install-time foreign agent hijack.
Behavioral surface
Source
ChildProcessEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 1 file(s), 802 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=>Dn(e)).join(` L5: `)}function Gf(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=Pn(f.join(`
High
Child Process

Package source references child process execution.

dist/cli/index.jsView on unpkg · L4
4`).map(e=>Dn(e)).join(` L5: `)}function Gf(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=Pn(f.join(` ... L16: `)}catch{}}function zk(){if(!Qs){let e=Yk().slice(0,13).replace("T","-");Qs=eo(ol(),`debug-${e}.log`)}Xk(Gk(Qs),{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 fk=Object.defineProperty;var T=(t,e)=>()=>(t&&(e=t(t=0)),e);var le=(t,e)=>{for(var r in e)fk(t,r,{get:e[r],enumerable:!0})};import{existsSync as Hr,readdirSync as mk,readFileSy... L2: `)}function tl(){return xt(wr(),yk)}function qf(){return xt(wr(),Ek)}function Tk(){try{return Hr(tl())}catch{return!1}}function Hf(t=process.stderr){Tk()&&t.write(`note: legacy ~/.... L3: `)}var _k,Uf,gk,wk,Wf,yk,Ek,Er,Ye=T(()=>{"use strict";_k=".lmctl",Uf="state.db",gk="workspaces",wk="active-workspace",Wf="default",yk="profiles",Ek="active-profile";Er={default:Wf}... L4: `).map(e=>Dn(e)).join(` L5: `)}function Gf(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=Pn(f.join(` ... L16: `)}catch{}}function zk(){if(!Qs){let e=Yk().slice(0,13).replace("T","-");Qs=eo(ol(),`debug-${e}.log`)}Xk(Gk(Qs),{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 fk=Object.defineProperty;var T=(t,e)=>()=>(t&&(e=t(t=0)),e);var le=(t,e)=>{for(var r in e)fk(t,r,{get:e[r],enumerable:!0})};import{existsSync as Hr,readdirSync as mk,readFileSy... L2: `)}function tl(){return xt(wr(),yk)}function qf(){return xt(wr(),Ek)}function Tk(){try{return Hr(tl())}catch{return!1}}function Hf(t=process.stderr){Tk()&&t.write(`note: legacy ~/.... ... L4: `).map(e=>Dn(e)).join(` L5: `)}function Gf(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=Pn(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:Pn(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 zk(){if(!Qs){let e=Yk().slice(0,13).replace("T","-");Qs=eo(ol(),`debug-${e}.log`)}Xk(Gk(Qs),{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