registry  /  @lmctl-ai/lmctl  /  0.1.63

@lmctl-ai/lmctl@0.1.63

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. Risky primitives are present, but they are exposed through explicit CLI workflow, terminal, provider-check, and diagnostic commands aligned with the package purpose.

Static reason
One or more suspicious static signals were detected.
Trigger
User runs the lmctl CLI and invokes workflow, terminal, provider, or diagnostic commands.
Impact
Could execute configured provider/terminal workflows when intentionally invoked; no unconsented install/import-time behavior or covert exfiltration found.
Mechanism
User-invoked AI-agent control CLI with local state, subprocess, and optional remote workflow loading
Rationale
Static inspection found a declared CLI with subprocess, environment, local database/session, and optional HTTPS workflow functionality, but these are user-invoked and consistent with the package description. No lifecycle execution, covert credential/file harvesting, persistence, destructive behavior, or unconsented AI-agent control-surface mutation was identified.
Evidence
package.jsonbin/lmctldist/cli/index.js
Network endpoints3
lmctl.comdocs.claude.com/en/docs/claude-codegithub.com/openai/codex

Decision evidence

public snapshot
AI called this Clean at 82.0% confidence as Benign with medium false-positive risk.
Evidence for block
  • package.json exposes a user-invoked CLI bin at bin/lmctl.
  • dist/cli/index.js contains child_process usage for terminal/provider workflows and diagnostics.
  • dist/cli/index.js can load workflow JSON from https URLs and mentions remote workflow run after a trust prompt.
  • dist/cli/index.js reads LMCTL_* environment variables and local lmctl state/session paths for configuration/diagnostics.
Evidence against
  • No package.json lifecycle scripts, so no install-time hook was found.
  • bin/lmctl only execs ../dist/cli/index.js as the declared CLI entrypoint.
  • Remote workflow loading is tied to explicit workflow commands, not import/install-time execution.
  • Environment collection shown is limited to LMCTL-related config/status values, with unset values redacted/represented.
  • Shell/child_process calls are package-aligned for a CLI that checks providers, runs terminal workflows, and reports diagnostics.
  • No evidence of credential harvesting, persistence, destructive actions, or covert exfiltration in inspected entrypoints.
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