registry  /  @truealter/cli  /  0.8.30

@truealter/cli@0.8.30

~Alter identity CLI - login once, authenticated everywhere.

AI Security Review

scanned 11d ago · by lpm-firewall-ai

No confirmed malicious attack surface by source inspection. Sensitive primitives are tied to explicit CLI/plugin features: login, self-update, Claude hook installation, local wrappers, and Obsidian pairing.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
User runs alter commands such as login, update, hooks install, cc, alignment, or enables the bundled Obsidian plugin.
Impact
No evidence of unconsented install-time execution, credential harvesting, hidden exfiltration, persistence, or destructive behavior.
Mechanism
Feature-aligned credential storage, network API calls, subprocess wrappers, and optional AI-agent hook installation.
Rationale
Static source inspection found high-risk primitives, but they are user-invoked and package-aligned, with no lifecycle execution or hidden exfiltration path. The scanner's AI-agent hook and network findings are real capabilities but not malicious in this package context.
Evidence
package.jsondist/index.jsdist/commands/hooks.jsdist/cc-wrapper/pty-adapter.jsdist/commands/alignment.jsdist/lib/self-update.jsdist/auth.jsdist/embedded-plugins/alter-obsidian-plugin/main.jsdist/assets/hooksdist/doctor/checks/runtime.jsdist/lib/cosmetics/inscribe.jsdist/assets/hooks/destructive-bash-gate.shdist/assets/hooks/environment-intent-gate.shdist/assets/hooks/cc-broadcast.sh
Network endpoints7
registry.npmjs.org/@truealter/cliapi.truealter.comtruealter.comreleases.truealter.commcp.truealter.com/api/v1/mcp127.0.0.1localhost:11434

Decision evidence

public snapshot
AI called this Clean at 88.0% confidence as Benign with low false-positive risk.
Evidence for block
  • dist/commands/hooks.js can write curated Claude Code hooks into .claude/settings.json and .claude/hooks when user runs alter hooks install.
  • dist/lib/self-update.js may run npm install -g @truealter/cli after registry/version checks and release verification/prompting.
  • dist/embedded-plugins/alter-obsidian-plugin/main.js sends consent/ingest requests with X-ALTER-API-Key to api.truealter.com after Obsidian pairing actions.
Evidence against
  • package.json has no install/postinstall/prepare hook; only prepublishOnly is publisher-side.
  • dist/index.js only dispatches CLI commands; no import-time execution beyond credential-residue cleanup and update/preflight checks at CLI runtime.
  • dist/cc-wrapper/pty-adapter.js spawns the requested cc command/PTY for the explicit alter cc wrapper path.
  • dist/commands/alignment.js requires ALTER_MCP_CMD to be an absolute user-configured server command and rejects shell metacharacter parsing.
  • dist/commands/hooks.js install/uninstall is explicit, documented, marker-based, and includes uninstall handling; not lifecycle-triggered.
  • Network endpoints observed are TrueAlter, npm registry, release verification, localhost callback/Ollama, or user-configured MCP endpoints aligned with CLI features.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsObfuscatedUrlStrings
ManifestNo manifest risk signals triggered.
scanned 161 file(s), 1.25 MB of source, external domains: 127.0.0.1, api.github.com, api.truealter.com, aur.archlinux.org, github.com, mcp.truealter.com, objects.githubusercontent.com, obsidian.md, registry.npmjs.org, releases.truealter.com, starship.rs, token.actions.githubusercontent.com, truealter.com

Source & flagged code

8 flagged · loading source
dist/cc-wrapper/pty-adapter.jsView file
1import * as childProcess from "node:child_process"; L2: export async function spawnCcUnderPty(opts) {
High
Child Process

Package source references child process execution.

dist/cc-wrapper/pty-adapter.jsView on unpkg · L1
4const moduleId = "node-pty"; L5: const pty = (await import(moduleId)); L6: const proc = pty.spawn(opts.file, opts.args, {
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/cc-wrapper/pty-adapter.jsView on unpkg · L4
dist/commands/hooks.jsView file
173: `D="${hooksDir}"; [ -x "$D/_verify.sh" ] && bash "$D/_verify.sh" >/dev/null && [ -x ${scriptPath} ] && bash ${scriptPath}${argSuffix}; exit 0`; L174: return `bash -c '${body} ${marker}'`; L175: }
High
Shell

Package source references shell execution.

dist/commands/hooks.jsView on unpkg · L173
dist/lib/cosmetics/inscribe.jsView file
61if (surface.id === "pfetch") { L62: return inscribePfetch(surface, ctx); L63: } ... L178: function expandHome(p) { L179: return p.replace(/^\$HOME/, os.homedir()); L180: } L181: function ccStatuslineWardrobePath() { L182: const base = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config"); L183: return path.join(base, "alter", "statusline-wardrobe.json"); ... L187: return "fish"; L188: if (targetPath.endsWith(".bashrc") || targetPath.endsWith(".bash_profile")) L189: return "bash";
Medium
Install Persistence

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

dist/lib/cosmetics/inscribe.jsView on unpkg · L61
dist/doctor/checks/runtime.jsView file
1import * as fs from "node:fs"; L2: import * as net from "node:net"; L3: import * as os from "node:os"; L4: import * as path from "node:path"; L5: import { execFile as _execFile } from "node:child_process"; L6: import { promisify } from "node:util"; ... L11: } L12: const runtimeDir = process.env.XDG_RUNTIME_DIR; L13: if (runtimeDir) {
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/doctor/checks/runtime.jsView on unpkg · L1
dist/commands/alignment.jsView file
1import { spawn } from "child_process"; L2: import * as path from "path"; ... L13: function resolveServerCmd() { L14: const envCmd = process.env.ALTER_MCP_CMD; L15: if (envCmd) { ... L24: "(no shell metacharacters)."); L25: process.exitCode = 1; L26: return null; ... L39: "Set ALTER_MCP_CMD=<absolute-path-to-the-server-binary> to enable. " + L40: "See https://truealter.com/docs/cli#alignment"); L41: process.exitCode = 1; ... L49: const wait = await withKeyListenerCancel(async (signal) => {
High
Sandbox Evasion Gated Capability

Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.

dist/commands/alignment.jsView on unpkg · L1
dist/assets/statusline/statusline.shView file
path = [redacted].sh kind = build_helper sizeBytes = 39343 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

dist/assets/statusline/statusline.shView on unpkg
dist/embedded-plugins/alter-obsidian-plugin/main.jsView file
matchType = previous_version_dangerous_delta matchedPackage = @truealter/cli@0.8.29 matchedIdentity = npm:QHRydWVhbHRlci9jbGk:0.8.29 similarity = 0.950 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.

dist/embedded-plugins/alter-obsidian-plugin/main.jsView on unpkg

Findings

1 Critical4 High6 Medium6 Low
CriticalPrevious Version Dangerous Deltadist/embedded-plugins/alter-obsidian-plugin/main.js
HighChild Processdist/cc-wrapper/pty-adapter.js
HighShelldist/commands/hooks.js
HighSame File Env Network Executiondist/doctor/checks/runtime.js
HighSandbox Evasion Gated Capabilitydist/commands/alignment.js
MediumDynamic Requiredist/cc-wrapper/pty-adapter.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/lib/cosmetics/inscribe.js
MediumShips Build Helperdist/assets/statusline/statusline.sh
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowUrl Strings