← Home

@brna/cli

brna CLI — agent-friendly snapshot and action surface for React Native apps

5
Versions
License
No
Install Scripts
Verified
Provenance

Supply chain provenance

Status for the latest visible version.

SLSA provenance attestation npm registry signatures gitHead linked

Maintainers

leolin310148

Accepted risks

Findings the reviewer chose to accept rather than block on.

SourceRuleReasonAccepted byWhen
source-diff source-size-tripled AI (source-diff): Size increase from adding bun-built bundle; expected for CLI packages. ai
semgrep semgrep:silent-process-exec-var AI (semgrep): Same daemon spawn as silent-process-exec; not malicious. ai
semgrep semgrep:env-bulk-read AI (semgrep): Config env-replacement helper in CLI; not exfiltration. ai
source-diff net-exec-file:dist/brna.js AI (source-diff): Bun-bundled CLI entry point; network+exec from bundled dependencies is expected. ai
semgrep semgrep:silent-process-exec AI (semgrep): Daemon self-respawn pattern using process.execPath; standard CLI daemon lifecycle. ai
semgrep semgrep:shady-links-raw-ip AI (semgrep): All instances reference 127.0.0.1 in integration test setup — localhost loopback, not exfiltration. ai
typosquat typosquat.levenshtein:joi AI (typosquat): No brand similarity between @brna/cli and joi; weak Levenshtein match only. ai
semgrep semgrep:env-spread AI (semgrep): Fires exclusively in test files spreading process.env for test harness setup — not a runtime secret leak. ai

Versions (showing 5 of 5)

Version Deps Published
0.1.14 3 / 0
0.1.13 3 / 0
0.1.12 3 / 0
0.1.0 3 / 0
0.0.2 3 / 0

v0.1.14

1 finding
INFO Has SLSA provenance attestation provenance

Published via CI/CD with Sigstore attestation (predicate: https://slsa.dev/provenance/v1). This is the strongest supply chain integrity signal.

v0.1.13

1 finding
INFO Has SLSA provenance attestation provenance

Published via CI/CD with Sigstore attestation (predicate: https://slsa.dev/provenance/v1). This is the strongest supply chain integrity signal.

v0.1.12

1 finding
INFO Has SLSA provenance attestation provenance

Published via CI/CD with Sigstore attestation (predicate: https://slsa.dev/provenance/v1). This is the strongest supply chain integrity signal.

v0.1.0

5 findings
HIGH Publisher changed: leolin310148 → GitHub Actions (on 2026-05-04) provenance

This version was published by a different npm account than previous versions on 2026-05-04. This could indicate a legitimate maintainer transition or an account compromise.

HIGH New file with network + code execution: dist/brna.js source-diff

Newly added file contains both network calls and dynamic code execution. This is a hallmark of dropper/loader malware.

HIGH silent-process-exec: src/daemon.ts:270 semgrep

Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/leolin310148/brna/blob/60707f601f423feb1278423fec981b1e9c702ba1/src/daemon.ts#L270 268 | if (await pingDaemon(identity.socketPath)) return; 269 | await rm(identity.socketPath, { force: true }); > 270 | const child = spawn(process.execPath, process.argv.slice(1), { 271 | cwd: process.cwd(), 272 | detached: true,

HIGH silent-process-exec-var: src/daemon.ts:270 semgrep

Silent detached process — runs invisibly in the background (reverse shells, miners) Source: https://github.com/leolin310148/brna/blob/60707f601f423feb1278423fec981b1e9c702ba1/src/daemon.ts#L270 268 | if (await pingDaemon(identity.socketPath)) return; 269 | await rm(identity.socketPath, { force: true }); > 270 | const child = spawn(process.execPath, process.argv.slice(1), { 271 | cwd: process.cwd(), 272 | detached: true,

INFO Has SLSA provenance attestation provenance

Published via CI/CD with Sigstore attestation (predicate: https://slsa.dev/provenance/v1). This is the strongest supply chain integrity signal.

v0.0.2

12 findings
HIGH env-spread: __tests__/act-integration.test.ts:115 semgrep

Spreading entire process.env into an object — may capture all secrets 113 | ["bun", "run", CLI_PATH, "act", ...args, "--metro", baseUrl, "--timeout", "5000"], 114 | { > 115 | env: { ...process.env, NO_COLOR: "1" }, 116 | stdout: "pipe", 117 | stderr: "pipe",

HIGH env-spread: __tests__/act-integration.test.ts:130 semgrep

Spreading entire process.env into an object — may capture all secrets 128 | async function runRaw(args: string[]): Promise<ProcResult> { 129 | const proc = Bun.spawn(["bun", "run", CLI_PATH, ...args], { > 130 | env: { ...process.env, NO_COLOR: "1" }, 131 | stdout: "pipe", 132 | stderr: "pipe",

HIGH env-spread: __tests__/act-usage.test.ts:9 semgrep

Spreading entire process.env into an object — may capture all secrets 7 | function run(args: string[]) { 8 | return spawnSync("bun", ["run", CLI_PATH, ...args], { > 9 | env: { ...process.env, NO_COLOR: "1" }, 10 | encoding: "utf8", 11 | timeout: 5000,

HIGH env-spread: __tests__/config-trace.test.ts:43 semgrep

Spreading entire process.env into an object — may capture all secrets 41 | const result = spawnSync("bun", ["run", CLI_PATH, "config", "init"], { 42 | cwd, > 43 | env: { ...process.env, NO_COLOR: "1" }, 44 | encoding: "utf8", 45 | timeout: 5000,

HIGH env-spread: __tests__/config-trace.test.ts:93 semgrep

Spreading entire process.env into an object — may capture all secrets 91 | const start = spawnSync("bun", ["run", CLI_PATH, "trace", "start"], { 92 | cwd, > 93 | env: { ...process.env, NO_COLOR: "1" }, 94 | encoding: "utf8", 95 | timeout: 5000,

HIGH env-spread: __tests__/config-trace.test.ts:100 semgrep

Spreading entire process.env into an object — may capture all secrets 98 | const stop = spawnSync("bun", ["run", CLI_PATH, "trace", "stop"], { 99 | cwd, > 100 | env: { ...process.env, NO_COLOR: "1" }, 101 | encoding: "utf8", 102 | timeout: 5000,

HIGH env-spread: __tests__/config-trace.test.ts:229 semgrep

Spreading entire process.env into an object — may capture all secrets 227 | const proc = Bun.spawn(["bun", "run", CLI_PATH, ...args], { 228 | cwd, > 229 | env: { ...process.env, NO_COLOR: "1" }, 230 | stdout: "pipe", 231 | stderr: "pipe",

HIGH env-spread: __tests__/snapshot.test.ts:73 semgrep

Spreading entire process.env into an object — may capture all secrets 71 | test("--format xml exits 4 with the expected stderr", () => { 72 | const result = spawnSync("bun", ["run", CLI_PATH, "snapshot", "--format", "xml"], { > 73 | env: { ...process.env, NO_COLOR: "1" }, 74 | encoding: "utf8", 75 | timeout: 5000,

HIGH env-spread: __tests__/snapshot.test.ts:84 semgrep

Spreading entire process.env into an object — may capture all secrets 82 | test('--format "" exits 4', () => { 83 | const result = spawnSync("bun", ["run", CLI_PATH, "snapshot", "--format", ""], { > 84 | env: { ...process.env, NO_COLOR: "1" }, 85 | encoding: "utf8", 86 | timeout: 5000,

HIGH env-spread: __tests__/snapshot.test.ts:94 semgrep

Spreading entire process.env into an object — may capture all secrets 92 | test("--format markdown alias is rejected", () => { 93 | const result = spawnSync("bun", ["run", CLI_PATH, "snapshot", "--format", "markdown"], { > 94 | env: { ...process.env, NO_COLOR: "1" }, 95 | encoding: "utf8", 96 | timeout: 5000,

HIGH env-spread: __tests__/snapshot.test.ts:103 semgrep

Spreading entire process.env into an object — may capture all secrets 101 | test("--format JSON (case-different) is rejected", () => { 102 | const result = spawnSync("bun", ["run", CLI_PATH, "snapshot", "--format", "JSON"], { > 103 | env: { ...process.env, NO_COLOR: "1" }, 104 | encoding: "utf8", 105 | timeout: 5000,

LOW No provenance attestation provenance

Package was published without Sigstore provenance. Only ~12% of npm packages have provenance, so this is common but not ideal.