registry  /  tmux-ide  /  2.8.0

tmux-ide@2.8.0

Turn any project into a tmux-powered terminal IDE with a simple ide.yml

AI Security Review

scanned 7h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. Global installation can set up package-owned Claude Code skill content and enable Claude agent teams only when `~/.claude` already exists. Explicit integration commands may add reversible Claude/OpenCode hooks or plugins. No confirmed malicious attack chain was found.

Static reason
High-risk behavior combination matched malicious policy.; previous stored version diff introduced dangerous source
Trigger
`npm install -g tmux-ide` with an existing `~/.claude`; explicit `tmux-ide integration install ...` and update commands
Impact
Changes local AI-agent configuration but no exfiltration, remote payload execution, or destructive behavior is established.
Mechanism
Guarded agent integration setup and explicit tmux tooling downloads
Rationale
Source inspection confirms guarded install-time Claude configuration mutation, so it is not clean. The mutation is package-aligned and limited, with no concrete malicious chain; warn rather than block.
Evidence
package.jsonscripts/postinstall.jsskill/SKILL.mdpackages/daemon/src/lib/skill-sync.tspackages/daemon/src/tui/integrations/claude.tspackages/daemon/src/tui/integrations/opencode.tspackages/daemon/src/lib/update-check.tspackages/daemon/src/lib/manifest-pack.tspackages/daemon/src/lib/tui-binary.tsbin/cli.ts~/.claude/skills/tmux-ide/SKILL.md~/.claude/settings.json~/.tmux-ide/hooks/claude-state.sh~/.config/opencode/plugin/tmux-ide.js
Network endpoints2
registry.npmjs.org/tmux-ide/latestgithub.com/${RELEASE_REPO}/releases/download/v${version}/agent-manifests.json

Decision evidence

public snapshot
AI called this Suspicious at 88.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
  • `scripts/postinstall.js` modifies `~/.claude` during global installs when that directory exists.
  • Postinstall copies package `skill/SKILL.md` into `~/.claude/skills/tmux-ide` and sets `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` in `~/.claude/settings.json`.
Evidence against
  • Postinstall is gated by `npm_config_global === "true"` and performs no network or child-process activity.
  • The lifecycle mutation is limited to package-owned skill content and one Claude feature flag; it does not register hooks or MCP servers.
  • `integration install claude` and `integration install opencode` are explicit user commands with marker-based reversible config writes.
  • `bin/cli.ts` uses child processes for tmux orchestration; runtime downloads target npm/GitHub endpoints and are update features.
  • No credential harvesting, secret exfiltration, eval/vm execution, destructive deletion, or stealth persistence was found.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 384 file(s), 3.09 MB of source, external domains: 0.0.0.0, 127.0.0.1, bun.sh, github.com, registry.npmjs.org

Source & flagged code

13 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall.js
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node scripts/postinstall.js
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
bin/cli.tsView file
matchType = previous_version_dangerous_delta matchedPackage = tmux-ide@2.6.1 matchedIdentity = npm:dG11eC1pZGU:2.6.1 similarity = 0.675 summary = stored previous version shares package body but lacks this dangerous source file
Critical
Previous Version Dangerous Delta

This package version adds a dangerous source file absent from the previous stored version; route for source-aware review.

bin/cli.tsView on unpkg
6import { resolve, dirname, join } from "node:path"; L7: import { execFileSync } from "node:child_process"; L8: import { existsSync } from "node:fs";
High
Child Process

Package source references child process execution.

bin/cli.tsView on unpkg · L6
6Cross-file remote execution chain: bin/cli.ts spawns bin/cli.js; helper contains network access plus dynamic code execution. L6: import { resolve, dirname, join } from "node:path"; L7: import { execFileSync } from "node:child_process"; L8: import { existsSync } from "node:fs"; ... L10: L11: const __dirname = dirname(fileURLToPath(import.meta.url)); L12: // The node-runnable CLI path that spawned TUI surfaces shell back to (the app's ... L161: if (values.version) { L162: const pkg = await import("../package.json"); L163: console.log(`tmux-ide v${pkg.version}`); ... L177: L178: const noColor = "NO_COLOR" in process.env; L179: const bold = (s: string) => (noColor ? s : `\x1b[1m${s}\x1b[22m`);
High
Cross File Remote Execution Context

Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.

bin/cli.tsView on unpkg · L6
packages/daemon/src/tui/chrome/notify.tsView file
551L552: /** PURE — single-quote a string for safe interpolation into a `/bin/sh -c` command. */ L553: function shellSingleQuote(value: string): string {
High
Shell

Package source references shell execution.

packages/daemon/src/tui/chrome/notify.tsView on unpkg · L551
bin/cli.jsView file
7316if (!pane) return {}; // not inside tmux \u2014 inert L7317: const { execFile } = await import("node:child_process"); L7318: let last = "";
Medium
Dynamic Require

Package source references dynamic require/import behavior.

bin/cli.jsView on unpkg · L7316
113code; L114: exitCode; L115: constructor(message, code, options = {}) { ... L133: // packages/tmux-bridge/src/runner.ts L134: import { execFileSync, spawn } from "node:child_process"; L135: function _setExecutor(fn) { ... L184: if (typeof stderr === "string" && stderr.length > 0) return stderr; L185: if (Buffer.isBuffer(stderr) && stderr.length > 0) return stderr.toString("utf-8"); L186: return error?.message ?? ""; ... L192: init_errors(); L193: DEBUG = process.env.TMUX_IDE_DEBUG === "1"; L194: SESSION_NOT_FOUND_PATTERNS = ["can't find session", "can't find window", "unknown target"];
Medium
Install Persistence

Source writes installer persistence such as shell profile or service configuration.

bin/cli.jsView on unpkg · L113
113code; L114: exitCode; L115: constructor(message, code, options = {}) { ... L133: // packages/tmux-bridge/src/runner.ts L134: import { execFileSync, spawn } from "node:child_process"; L135: function _setExecutor(fn) { ... L184: if (typeof stderr === "string" && stderr.length > 0) return stderr; L185: if (Buffer.isBuffer(stderr) && stderr.length > 0) return stderr.toString("utf-8"); L186: return error?.message ?? ""; ... L192: init_errors(); L193: DEBUG = process.env.TMUX_IDE_DEBUG === "1"; L194: SESSION_NOT_FOUND_PATTERNS = ["can't find session", "can't find window", "unknown target"];
Low
Weak Crypto

Package source references weak cryptographic algorithms.

bin/cli.jsView on unpkg · L113
scripts/postinstall.jsView file
1Install-time AI-agent control hijack evidence: L1: import { existsSync, mkdirSync, readFileSync, writeFileSync, symlinkSync } from "node:fs"; L2: import { resolve, dirname, relative } from "node:path"; ... L20: if (!existsSync(target) || existsSync(link)) continue; L21: mkdirSync(scopeDir, { recursive: true }); L22: // "junction" keeps Windows working without admin; ignored elsewhere. ... L28: L29: const claudeDir = resolve(homedir(), ".claude"); L30: if (!shouldInstallClaudeIntegration() || !existsSync(claudeDir)) { ... L33: L34: // Sync the bundled Claude Code skill into ~/.claude/skills/tmux-ide, rewriting L35: // its version marker to the installed package version. This is the JS twin of ... L43: const skillDir = resolve(claudeDir, "skills", "tmux-ide"); Payload evidence from skill/SKILL.md: L163: ```js L164: const net = require("node:net"); L165: const os = require("node:os"); L166: const sock = net.connect(`${os.homedir()}/.tmux-ide/control.sock`); L167: let buf = ""; ... L172: for (const line of lines.filter(Boolean)) { L173: const frame = JSON.parse(line); L174: if (frame.event === "agent-status") console.log(frame.data); // react here ... L176: }); L177: sock.write('{"v…
Critical
Ai Agent Control Hijack

Install-time source drops package-supplied AI-agent/MCP control files or instructions.

scripts/postinstall.jsView on unpkg · L1
scripts/pack-check-run.mjsView file
54L55: child = spawn("npx", ["tmux-ide", "--headless"], { L56: cwd: projectDir,
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

scripts/pack-check-run.mjsView on unpkg · L54
scripts/check-src-additions.shView file
path = scripts/check-src-additions.sh kind = build_helper sizeBytes = 2435 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

scripts/check-src-additions.shView on unpkg
packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Resources/AppIcon.icnsView file
path = [redacted].app/Contents/Resources/AppIcon.icns kind = high_entropy_blob sizeBytes = 1018507 magicHex = [redacted]
High
Ships High Entropy Blob

Package ships high-entropy non-source blobs.

packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Resources/AppIcon.icnsView on unpkg

Findings

2 Critical6 High7 Medium6 Low
CriticalAi Agent Control Hijackscripts/postinstall.js
CriticalPrevious Version Dangerous Deltabin/cli.ts
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processbin/cli.ts
HighShellpackages/daemon/src/tui/chrome/notify.ts
HighCross File Remote Execution Contextbin/cli.ts
HighRuntime Package Installscripts/pack-check-run.mjs
HighShips High Entropy Blobpackages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Resources/AppIcon.icns
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requirebin/cli.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencebin/cli.js
MediumShips Build Helperscripts/check-src-additions.sh
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowWeak Cryptobin/cli.js
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings