registry  /  @lmctl-ai/lmctl  /  0.1.111

@lmctl-ai/lmctl@0.1.111

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

No confirmed malicious attack surface. The package is an explicit CLI that launches configured AI-provider tools, loads user-selected HTTPS workflows, and maintains `~/.lmctl` state. No install-time execution, covert exfiltration, or unconsented foreign AI-agent control-surface mutation was found.

Static reason
One or more suspicious static signals were detected.
Trigger
User runs `lmctl` commands such as workflow, device, diagnose, or workspace operations.
Impact
Capabilities can execute configured provider CLIs or send user-supplied device prompts, but no automatic malicious chain is established.
Mechanism
User-invoked CLI orchestration, local state management, and optional remote workflow retrieval.
Rationale
Scanner signals correspond to documented, explicit CLI features: subprocess provider orchestration, HTTPS workflow retrieval, local state, and user-directed device messaging. Source inspection found no lifecycle hook, import-time behavior, stealth persistence, or completed unsolicited exfiltration.
Evidence
package.jsonbin/lmctldist/cli/index.js~/.lmctl/
Network endpoints4
registry.npmjs.org/@lmctl-ai/lmctl/latestapi.github.com/repos/${owner}/${repo}/issuescognito-idp.${region}.amazonaws.com/lmctl.anthropic.com

Decision evidence

public snapshot
AI called this Clean at 90.0% confidence as Benign with low false-positive risk.
Evidence for block
    Evidence against
    • `package.json` has no lifecycle scripts.
    • `bin/lmctl` invokes `runCli` only after explicit CLI execution.
    • HTTPS workflow loading is user-invoked and rejects redirects.
    • Remote workflow execution documents a trust prompt; `--yes`/`--no-prompt` are explicit overrides.
    • Diagnostic `--upload` and `--internal-s3` paths are stubs with no actual upload.
    • Workspace deletion requires `--confirm`; active/default deletion additionally requires `--force`.
    Behavioral surface
    Source
    ChildProcessEnvironmentVarsEvalFilesystemNetworkShell
    Supply chain
    HighEntropyStringsUrlStrings
    Manifest
    NoLicense
    scanned 1 file(s), 854 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=>Vn(e)).join(` L5: `)}function Dm(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=Yn(f.join(`
    High
    Child Process

    Package source references child process execution.

    dist/cli/index.jsView on unpkg · L4
    4`).map(e=>Vn(e)).join(` L5: `)}function Dm(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=Yn(f.join(` ... L16: `)}catch{}}function LI(){if(!Eo){let e=RI().slice(0,13).replace("T","-");Eo=To(Ll(),`debug-${e}.log`)}II(NI(Eo),{recursive:!0})}function je(...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 Xk=Object.defineProperty;var T=(t,e)=>()=>(t&&(e=t(t=0)),e);var se=(t,e)=>{for(var r in e)Xk(t,r,{get:e[r],enumerable:!0})};import{existsSync as Vr,readdirSync as Gk,readFileSy... L2: `)}function Nl(){return Mt(vr(),Qk)}function Om(){return Mt(vr(),eI)}function rI(){try{return Vr(Nl())}catch{return!1}}function jm(t=process.stderr){rI()&&t.write(`note: legacy ~/.... L3: `)}var Yk,Rm,zk,Zk,Lm,Qk,eI,Ir,Ve=T(()=>{"use strict";Yk=".lmctl",Rm="state.db",zk="workspaces",Zk="active-workspace",Lm="default",Qk="profiles",eI="active-profile";Ir={default:Lm}... L4: `).map(e=>Vn(e)).join(` L5: `)}function Dm(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=Yn(f.join(` ... L16: `)}catch{}}function LI(){if(!Eo){let e=RI().slice(0,13).replace("T","-");Eo=To(Ll(),`debug-${e}.log`)}II(NI(Eo),{recursive:!0})}function je(...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 Xk=Object.defineProperty;var T=(t,e)=>()=>(t&&(e=t(t=0)),e);var se=(t,e)=>{for(var r in e)Xk(t,r,{get:e[r],enumerable:!0})};import{existsSync as Vr,readdirSync as Gk,readFileSy... L2: `)}function Nl(){return Mt(vr(),Qk)}function Om(){return Mt(vr(),eI)}function rI(){try{return Vr(Nl())}catch{return!1}}function jm(t=process.stderr){rI()&&t.write(`note: legacy ~/.... ... L4: `).map(e=>Vn(e)).join(` L5: `)}function Dm(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=Yn(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:Yn(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 LI(){if(!Eo){let e=RI().slice(0,13).replace("T","-");Eo=To(Ll(),`debug-${e}.log`)}II(NI(Eo),{recursive:!0})}function je(...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 Medium6 Low
    HighChild Processdist/cli/index.js
    HighShell
    HighSame File Env Network Executiondist/cli/index.js
    HighCommand Output Exfiltrationdist/cli/index.js
    MediumNetwork
    MediumEnvironment Vars
    LowEval
    LowWeak Cryptodist/cli/index.js
    LowFilesystem
    LowHigh Entropy Strings
    LowUrl Strings
    LowNo License