registry  /  plani  /  0.6.0

plani@0.6.0

Share beautiful HTML plans and demo links from agents and humans

AI Security Review

scanned 1h ago · by lpm-firewall-ai

No confirmed malicious attack surface. The CLI reads user-selected static-site files and uploads them only when the user invokes share/link commands; its MCP mode exposes the same explicit sharing operations.

Static reason
One or more suspicious static signals were detected.
Trigger
User runs the plani CLI or explicitly starts `plani mcp` and calls a declared tool.
Impact
Selected files may be uploaded to the Plani service by the requested command; no unconsented collection or execution chain was found.
Mechanism
User-directed static-file upload, authenticated share management, and optional local project build.
Rationale
Static signals map to normal CLI functionality: explicit uploads, OAuth login, project builds, and MCP tools. There is no install-time execution or concrete exfiltration, persistence, remote payload, or AI-agent control-surface abuse.
Evidence
package.jsondist/index.js~/.plani/auth.jsonnext.config.tsnext.config.mjsnext.config.jsapp
Network endpoints3
plani.sh${t}.plani.shlocalhost

Decision evidence

public snapshot
AI called this Clean at 94.0% confidence as Benign with low false-positive risk.
Evidence for block
    Evidence against
    • package.json has only prepublishOnly; no install-time lifecycle hook.
    • dist/index.js is a user-invoked CLI entrypoint, not import-time payload logic.
    • Network requests target the configured Plani API for explicit upload, login, and share-management commands.
    • Child-process use runs the detected project's build command only for `plani link`, with `--no-build` available.
    • Local credential storage is limited to ~/.plani/auth.json and logout deletes that file.
    • No eval, dynamic module loading, native/binary loading, hidden persistence, or foreign AI-agent config writes found.
    Behavioral surface
    Source
    ChildProcessEnvironmentVarsNetwork
    Supply chain
    HighEntropyStrings
    Manifest
    CopyleftLicense
    scanned 1 file(s), 26.0 KB of source

    Source & flagged code

    3 flagged · loading source
    dist/index.jsView file
    1#!/usr/bin/env node L2: import{resolve as C,basename as gt}from"path";import{existsSync as we,statSync as mt}from"fs";import{randomBytes as ht}from"crypto";import{createInterface as yt}from"readline";impo... L3: `:` Open this URL in your browser:
    High
    Child Process

    Package source references child process execution.

    dist/index.jsView on unpkg · L1
    1#!/usr/bin/env node L2: import{resolve as C,basename as gt}from"path";import{existsSync as we,statSync as mt}from"fs";import{randomBytes as ht}from"crypto";import{createInterface as yt}from"readline";impo... L3: `:` Open this URL in your browser:
    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/index.jsView on unpkg · L1
    1#!/usr/bin/env node L2: import{resolve as C,basename as gt}from"path";import{existsSync as we,statSync as mt}from"fs";import{randomBytes as ht}from"crypto";import{createInterface as yt}from"readline";impo... L3: `:` Open this URL in your browser: ... L5: ${a} L6: `)}),setTimeout(()=>{r||(i.close(),e(new Error("Login timed out \u2014 no response within 2 minutes.")))},12e4)})}function ie(){try{return z(j)?(ze(j),!0):!1}catch{return!1}}async ... L7: `),e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",async n=>{e+=n;let r;for(;(r=e.indexOf(`
    High
    Command Output Exfiltration

    Source combines command execution, command-output handling, and outbound requests; review data flow before blocking.

    dist/index.jsView on unpkg · L1

    Findings

    3 High2 Medium4 Low
    HighChild Processdist/index.js
    HighSame File Env Network Executiondist/index.js
    HighCommand Output Exfiltrationdist/index.js
    MediumNetwork
    MediumEnvironment Vars
    LowNon Install Lifecycle Scripts
    LowScripts Present
    LowHigh Entropy Strings
    LowCopyleft License