registry  /  @jhizzard/termdeck  /  1.13.0

@jhizzard/termdeck@1.13.0

Browser-based terminal multiplexer with metadata overlays, panel flashback memory recall, and AI-aware session management

AI Security Review

scanned 2h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No concrete malicious attack surface is established. The package has a real agent-extension lifecycle surface because explicit setup commands install TermDeck-owned Claude hooks and MCP config, but not at npm install time.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
User runs termdeck init --mnestra, termdeck init --rumen, termdeck stack, or termdeck server commands.
Impact
Could extend Claude Code with TermDeck memory hooks and MCP credentials when the user opts in; no unconsented install-time mutation or exfiltration confirmed.
Mechanism
Explicit user-command setup of local terminal server, memory hooks, and Supabase/OpenAI integrations.
Rationale
Static inspection shows dangerous primitives are aligned with a browser terminal/memory orchestration tool and are activated by explicit user commands, with no npm lifecycle hook or confirmed covert exfiltration. Because it intentionally wires AI-agent hooks/config on user setup, treat as lifecycle risk rather than malicious.
Evidence
package.jsonpackages/cli/src/index.jspackages/cli/src/init-mnestra.jspackages/cli/src/init-rumen.jspackages/cli/src/mcp-config.jspackages/cli/src/stack.jspackages/server/src/index.jsdoctrine/index.js~/.termdeck/secrets.env~/.termdeck/config.yaml~/.claude/hooks/memory-session-end.js~/.claude/hooks/memory-pre-compact.js~/.claude/settings.json~/.claude.json~/.claude/mcp.json
Network endpoints7
127.0.0.1:3000localhost:37778api.openai.com/v1/embeddingsapi.anthropic.com/v1/messagesapi.supabase.com/v1/projects/<projectRef>/functions/<functionSlug>/body<project-ref>.supabase.co/functions/v1/rumen-tick<project-ref>.supabase.co/functions/v1/graph-inference

Decision evidence

public snapshot
AI called this Suspicious at 82.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • packages/cli/src/init-mnestra.js installs/refreshes TermDeck Claude hooks under ~/.claude/hooks and wires ~/.claude/settings.json on explicit init.
  • packages/cli/src/init-rumen.js can update ~/.claude.json Supabase MCP env token only when user supplies SUPABASE_ACCESS_TOKEN and placeholder exists.
  • packages/cli/src/index.js launches a local PTY web server and uses child_process for port reclaim, browser open, and server startup.
  • packages/server/src/index.js exposes terminal/session APIs and spawns PTYs, but has a non-loopback auth guard.
Evidence against
  • package.json has no preinstall/install/postinstall lifecycle hooks; activation is via bin or npm scripts/user commands.
  • No import-time exfiltration or payload fetch found in inspected entrypoints.
  • Secrets are read for local config, Supabase/OpenAI/Anthropic integrations, and child PTY env; management tokens are explicitly excluded from PTY merge.
  • Network endpoints are package-aligned: localhost TermDeck/Mnestra, Supabase, OpenAI, Anthropic, npm version lookup, CDN browser assets.
  • Claude hook overwrites are version/marker-gated with backups and custom-hook preservation.
  • Server defaults to 127.0.0.1 and refuses non-loopback bind without auth token.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 90 file(s), 1.67 MB of source, external domains: 127.0.0.1, api.anthropic.com, api.openai.com, api.supabase.com, deno.com, deno.land, github.com, grok.com, pkg.cloudflare.com, registry.npmjs.org, supabase.com, www.apple.com, xxxxxx.supabase.co, xyz.supabase.co, your-project.supabase.co

Source & flagged code

9 flagged · loading source
doctrine/index.jsView file
9// - vanilla JS / CommonJS / zero build / ZERO non-builtin deps. (node:fs, L10: // path, os, child_process only. better-sqlite3 is NEVER required here — L11: // the db handle is dependency-injected; doctrine opens no DB file.)
High
Child Process

Package source references child process execution.

doctrine/index.jsView on unpkg · L9
13// path. Bad inputs log one `[doctrine]` warning and degrade gracefully. L14: // - NO work at require() time. Requiring this module only defines functions, L15: // so `database.js` can require it cheaply for the DDL.
Medium
Dynamic Require

Package source references dynamic require/import behavior.

doctrine/index.jsView on unpkg · L13
packages/cli/src/init-bridge.jsView file
27// ~/.cloudflared/config.yml (tunnel id from the credentials JSON, L28: // ingress → http://127.0.0.1:8870). Existing files are backed up L29: // before any overwrite and a foreign (non-wizard) config.yml is never ... L33: // unit + timer → ~/.config/systemd/user/ on linux — then PRINTS the L34: // operator `launchctl load -w` / `systemctl enable` steps. It never L35: // runs launchctl/systemctl itself (ORCH decision 2026-06-11 20:58). ... L68: // L69: // Exit codes: 0 ok · 2 input/validation error · 3 tunnel credentials L70: // pending or ambiguous (resume with `--yes` / `--tunnel-id` after the ... L81: const os = require('os'); L82: const { execSync } = require('child_process'); L83:
Medium
Install Persistence

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

packages/cli/src/init-bridge.jsView on unpkg · L27
packages/cli/src/stack.jsView file
13const path = require('path'); L14: const http = require('http'); L15: const net = require('net'); L16: const { spawn, spawnSync } = require('child_process'); L17: ... L26: const SECRETS_FILE = path.join(CONFIG_DIR, 'secrets.env'); L27: const DEFAULT_MNESTRA_PORT = parseInt(process.env.MNESTRA_PORT || '37778', 10); L28: const MNESTRA_LOG = path.join(os.tmpdir(), 'termdeck-mnestra.log');
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

packages/cli/src/stack.jsView on unpkg · L13
packages/cli/src/init-rumen.jsView file
136function which(bin) { L137: const r = spawnSync('which', [bin], { encoding: 'utf-8' }); L138: if (r.status !== 0) return null; L139: return (r.stdout || '').trim() || null; L140: } ... L146: fail('not found on PATH'); L147: process.stderr.write( L148: '\nInstall it first:\n' + L149: ' macOS: brew install supabase/tap/supabase\n' + L150: ' other: https://supabase.com/docs/guides/local-development/cli/getting-started\n' L151: );
High
Command Output Exfiltration

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

packages/cli/src/init-rumen.jsView on unpkg · L136
packages/cli/src/index.jsView file
matchType = previous_version_dangerous_delta matchedPackage = @jhizzard/termdeck@1.12.0 matchedIdentity = npm:QGpoaXp6YXJkL3Rlcm1kZWNr:1.12.0 similarity = 0.954 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.

packages/cli/src/index.jsView on unpkg
17Cross-file remote execution chain: packages/cli/src/index.js spawns packages/cli/src/init-rumen.js; helper contains network access plus dynamic code execution. L17: const os = require('os'); L18: const { exec, execSync, spawn } = require('child_process'); L19: ... L29: // L30: // Fix: when launched in non-TTY mode (nohup detaches stdin/stdout/stderr) L31: // AND secrets.env exists with at least one key not already in process.env, L32: // spawn a detached child node with the merged env and exit the parent. The ... L63: if (argvSet.has('--service') || argvSet.has('--non-interactive')) return false; L64: const secretsPath = path.join(os.homedir(), '.termdeck', 'secrets.env'); L65: if (!fs.existsSync(secretsPath)) return false; ... L149: try { L150: const probe = execSync(`curl -sf -m 1.5 -o /dev/null -w "%{http_code}" http://127.0.0.1:${port}/api/sessions 2>/dev/null`, { encoding: 'utf8' });
High
Cross File Remote Execution Context

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

packages/cli/src/index.jsView on unpkg · L17
packages/server/src/index.jsView file
1Detached bundled service listener: packages/server/src/index.js launches a Node helper and exposes a broad-bound HTTP listener. L1: // TermDeck Server - main entry point L2: // Express REST API + WebSocket hub + PTY management L3: ... L10: const fs = require('fs'); L11: const dns = require('dns'); L12: const { spawn: spawnChild } = require('child_process'); L13: const { createCachedLookup, createFailureLogger } = require('./rumen-pool-resilience'); ... L30: console.error('[db] Fix:'); L31: process.stderr.write(' cd "$(npm root -g)/@jhizzard/termdeck" && npm rebuild better-sqlite3\n'); L32: console.error('[db] Then restart TermDeck. Aborting.'); ... L62: } L63: if (!pg || !process.env.DATABASE_URL) return null;
High
Spawned Bundled Service Listener

Source launches a detached bundled service that exposes a broad-bound HTTP listener.

packages/server/src/index.jsView on unpkg · L1
packages/cli/assets/supervise/termdeck-supervise.shView file
path = [redacted]-supervise.sh kind = build_helper sizeBytes = 7190 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

packages/cli/assets/supervise/termdeck-supervise.shView on unpkg

Findings

1 Critical6 High6 Medium4 Low
CriticalPrevious Version Dangerous Deltapackages/cli/src/index.js
HighChild Processdoctrine/index.js
HighShell
HighSame File Env Network Executionpackages/cli/src/stack.js
HighCommand Output Exfiltrationpackages/cli/src/init-rumen.js
HighCross File Remote Execution Contextpackages/cli/src/index.js
HighSpawned Bundled Service Listenerpackages/server/src/index.js
MediumDynamic Requiredoctrine/index.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencepackages/cli/src/init-bridge.js
MediumShips Build Helperpackages/cli/assets/supervise/termdeck-supervise.sh
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings