registry  /  tmux-ide  /  2.6.1

tmux-ide@2.6.1

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

AI Security Review

scanned 11d ago · by lpm-firewall-ai

LPM blocks this version under the AI-agent control-surface policy. Global install silently modifies Claude Code control surfaces if ~/.claude exists. It installs package-supplied agent instructions and changes Claude settings during npm postinstall.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
npm global install with ~/.claude present
Impact
Claude Code behavior/configuration can be changed by package install before explicit user invocation.
Mechanism
unconsented lifecycle AI-agent control-surface mutation
Policy narrative
During postinstall, the package checks for a global npm install and an existing ~/.claude directory. If present, it creates ~/.claude/skills/tmux-ide/SKILL.md from bundled package content and rewrites ~/.claude/settings.json to enable CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS. This is a lifecycle-time mutation of an AI-agent control surface without requiring the user to run tmux-ide or an integration command.
Rationale
The package has legitimate tmux IDE functionality, but its postinstall performs unconsented Claude Code configuration and skill installation in the user's home directory. Under the firewall policy, lifecycle AI-agent control-surface mutation is a concrete blocking behavior even without network exfiltration. Product guard normalized a non-low false-positive publish_block request to warn-only suspicious.
Evidence
package.jsonscripts/postinstall.jsskill/SKILL.mdpackages/daemon/src/lib/skill-sync.tspackages/daemon/src/tui/integrations/claude.ts~/.claude/skills/tmux-ide/SKILL.md~/.claude/settings.json

Decision evidence

public snapshot
AI called this Suspicious at 91.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for policy block
  • package.json runs postinstall: node scripts/postinstall.js
  • scripts/postinstall.js writes bundled skill/SKILL.md to ~/.claude/skills/tmux-ide/SKILL.md on global install
  • scripts/postinstall.js rewrites ~/.claude/settings.json env to set CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
  • packages/daemon/src/tui/integrations/claude.ts can install Claude hooks into ~/.claude/settings.json and ~/.tmux-ide/hooks/claude-state.sh
  • skill/SKILL.md instructs agents to use tmux-ide commands and coordinate agent state
Evidence against
  • Postinstall only mutates Claude files when npm_config_global is true and ~/.claude exists
  • No credential harvesting or external exfiltration found in inspected install script
  • Network findings are package-aligned local daemon/update-check behavior, not install-time exfiltration
  • Child process use is mostly tmux/git/bun/node for declared tmux IDE functionality
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 321 file(s), 2.10 MB of source, external domains: 0.0.0.0, 127.0.0.1, bun.sh, github.com, registry.npmjs.org

Source & flagged code

8 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
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
bin/cli.jsView file
5685function candidateSpawnHelperPaths() { L5686: const requireForNodePty = createRequire(import.meta.url); L5687: let pkgJsonPath;
Medium
Dynamic Require

Package source references dynamic require/import behavior.

bin/cli.jsView on unpkg · L5685
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
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: L1: # tmux-ide — Claude Code Skill L2:
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

Findings

1 Critical4 High7 Medium5 Low
CriticalAi Agent Control Hijackscripts/postinstall.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processbin/cli.ts
HighShell
HighRuntime Package Installscripts/pack-check-run.mjs
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
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings