registry  /  oh-my-hi  /  0.14.0

oh-my-hi@0.14.0

Oh, so that's what your coding agents have been doing! — Claude Code & Codex harness insights dashboard

AI Security Review

scanned 3d ago · by lpm-firewall-ai

No confirmed malicious attack surface. The package is a local Claude/Codex usage dashboard that reads local agent config/transcripts and writes dashboard output; optional auto-refresh modifies Claude settings only when the user invokes --enable-auto.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
npm install runs postinstall dependency repair; CLI/runtime actions generate or serve dashboard; --enable-auto opt-in writes hook
Impact
Local analytics/output files and optional auto-refresh hook; no credential harvesting or remote exfiltration found
Mechanism
local dashboard generation, localhost server, optional user-invoked Claude Stop hook
Rationale
Source inspection shows package-aligned local analytics behavior, with lifecycle code limited to native dependency repair and no install-time mutation of foreign AI-agent control surfaces. The optional Claude hook and update/install actions are user-invoked CLI features, so the scanner's dangerous primitives are explainable and not malicious.
Evidence
package.jsonscripts/postinstall.mjsbin/oh-my-hi.mjsscripts/generate-dashboard.mjsscripts/serve.mjsscripts/parsers/mcp-servers.mjsskills/omh/SKILL.mdnode_modules/better-sqlite3/build/Release/better_sqlite3.nodenode_modules/esbuildoutput/output/cache/.pricing-cache.jsonoutput/cache/.update-checkoutput/cache/.serve.jsonoutput/data.jsonoutput/index.html$CLAUDE_CONFIG_DIR/settings.json
Network endpoints4
platform.claude.com/docs/en/docs/about-claude/pricingapi.github.com/repos/netil/oh-my-hi/tagsregistry.npmjs.org/oh-my-hi/latest127.0.0.1:8282

Decision evidence

public snapshot
AI called this Clean at 90.0% confidence as Benign with low false-positive risk.
Evidence for block
  • package.json defines postinstall
  • scripts/postinstall.mjs runs npm rebuild/install for native deps
  • scripts/generate-dashboard.mjs can write Claude settings hook only with --enable-auto
Evidence against
  • postinstall only patches/rebuilds better-sqlite3 and esbuild inside package root
  • bin/oh-my-hi.mjs is a thin launcher to scripts/generate-dashboard.mjs
  • network calls are update/pricing checks to GitHub, npm registry, and Claude docs
  • serve.mjs binds local dashboard to 127.0.0.1 and guards static path traversal
  • parsers/mcp-servers.mjs comments and code mask env values, no exfiltration found
  • agent hook mutation is explicitly user-invoked, reversible with --disable-auto, not install-time
Behavioral surface
Source
ChildProcessEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 38 file(s), 725 KB of source, external domains: 127.0.0.1, api.github.com, code.claude.com, developers.openai.com, docs.anthropic.com, github.com, platform.claude.com, registry.npmjs.org, www.anthropic.com, www.w3.org

Source & flagged code

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

Package defines install-time lifecycle scripts.

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

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

package.jsonView on unpkg
bin/oh-my-hi.mjsView file
11// independent of how this launcher was invoked. L12: import { spawn } from 'child_process'; L13: import { fileURLToPath } from 'url';
High
Child Process

Package source references child process execution.

bin/oh-my-hi.mjsView on unpkg · L11
scripts/serve.mjsView file
413if (process.platform === 'darwin') execSync(`open "${launchUrl}"`); L414: else if (process.platform === 'win32') execSync(`start "" "${launchUrl}"`, { shell: true }); L415: else execSync(`xdg-open "${launchUrl}"`);
High
Shell

Package source references shell execution.

scripts/serve.mjsView on unpkg · L413
12L13: import http from 'http'; L14: import fs from 'fs'; L15: import path from 'path'; L16: import { execSync, spawnSync } from 'child_process'; L17: import { fileURLToPath } from 'url'; ... L25: // OMH_OUTPUT_DIR override matches generate-dashboard.mjs (also used by tests). L26: const OUTPUT_DIR = process.env.OMH_OUTPUT_DIR || path.join(ROOT, 'output'); L27: const LEGACY_DB_PATH = path.join(OUTPUT_DIR, 'oh-my-hi.sqlite');
High
Same File Env Network Execution

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

scripts/serve.mjsView on unpkg · L12
scripts/generate-dashboard.mjsView file
matchType = previous_version_dangerous_delta matchedPackage = oh-my-hi@0.13.0 matchedIdentity = npm:b2gtbXktaGk:0.13.0 similarity = 0.765 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.

scripts/generate-dashboard.mjsView on unpkg
23import fs from 'fs'; L24: import { execSync, spawnSync, spawn } from 'child_process'; L25: ... L57: const __filename = fileURLToPath(import.meta.url); L58: const __dirname = path.dirname(__filename); L59: const ROOT = path.resolve(__dirname, '..'); L60: const TEMPLATES = path.join(ROOT, 'templates'); L61: const OUTPUT = process.env.OMH_OUTPUT_DIR || path.join(ROOT, 'output'); L62: ... L64: // Dev build: script is running from the source git checkout (the folder L65: // with .git and package.json name === "oh-my-hi"). Always L66: // rebuilds HTML from templates (skips mtime short-circuit),
High
Sandbox Evasion Gated Capability

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

scripts/generate-dashboard.mjsView on unpkg · L23
23Cross-file remote execution chain: scripts/generate-dashboard.mjs spawns templates/app.js; helper contains network access plus dynamic code execution. L23: import fs from 'fs'; L24: import { execSync, spawnSync, spawn } from 'child_process'; L25: ... L57: const __filename = fileURLToPath(import.meta.url); L58: const __dirname = path.dirname(__filename); L59: const ROOT = path.resolve(__dirname, '..'); L60: const TEMPLATES = path.join(ROOT, 'templates'); L61: const OUTPUT = process.env.OMH_OUTPUT_DIR || path.join(ROOT, 'output'); L62: ... L64: // Dev build: script is running from the source git checkout (the folder L65: // with .git and package.json name === "oh-my-hi"). Always L66: // rebuilds HTML from templates (skips mtime short-circuit),
High
Cross File Remote Execution Context

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

scripts/generate-dashboard.mjsView on unpkg · L23
30console.log('oh-my-hi: installing dependencies...'); L31: execSync('npm install --omit=dev', { cwd: __boot_root, stdio: 'inherit' }); L32: }
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

scripts/generate-dashboard.mjsView on unpkg · L30

Findings

1 Critical7 High4 Medium4 Low
CriticalPrevious Version Dangerous Deltascripts/generate-dashboard.mjs
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processbin/oh-my-hi.mjs
HighShellscripts/serve.mjs
HighSame File Env Network Executionscripts/serve.mjs
HighSandbox Evasion Gated Capabilityscripts/generate-dashboard.mjs
HighCross File Remote Execution Contextscripts/generate-dashboard.mjs
HighRuntime Package Installscripts/generate-dashboard.mjs
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings