/happy-app-audit
Audit a local macOS app's telemetry / reporting behavior using static analysis only. Reverse-engineers an .app bundle to identify embedded SDKs (AppLog/TEA, Parfait, TTNet, mars, MMKV, Sentry, Firebase, Bugly, Umeng, etc.), mapped upload endpoints, local on-disk queues, and
$ npx -y skills add iamzhihuix/happy-claude-skills --skill happy-app-audit --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/happy-app-audit
Context preview
The summary Claude sees to decide when to auto-load this skill.
Audit a local macOS app's telemetry / reporting behavior using static analysis only. Reverse-engineers an .app bundle to identify embedded SDKs (AppLog/TEA, Parfait, TTNet, mars, MMKV, Sentry, Firebase, Bugly, Umeng, etc.), mapped upload endpoints, local on-disk queues, and
SKILL.md
happy-app-audit.SKILL.mdname: happy-app-audit
description: Audit a local macOS app's telemetry / reporting behavior using static analysis only. Reverse-engineers an .app bundle to identify embedded SDKs (AppLog/TEA, Parfait, TTNet, mars, MMKV, Sentry, Firebase, Bugly, Umeng, etc.), mapped upload endpoints, local on-disk queues, and privacy-relevant fields — without packet capture, network requests, debugger attach, or DRM bypass. Use when user asks to investigate, audit, or reverse-engineer a macOS app for telemetry, reporting, data upload, privacy, or SDK fingerprinting. Targets /Applications, ~/Applications, /Library/Input Methods, /Library/PrivilegedHelperTools, and similar local install paths.
metadata:
author: iamzhihuix
version: "0.1.0"
Happy App Audit
Static-only macOS app telemetry auditor. Produces a markdown report describing what an installed `.app` bundle reports, to whom, how often (inferred), and what it leaves on disk.
When to invoke
Invoke when the user says any of: "审计 / 调查 / 看看 / 拆 / 逆向 / 上报 / 埋点 / 隐私 / 抓 SDK" combined with a `.app` path or app name. Also invoke when given paths under `/Applications`, `~/Applications`, `/Library/Input Methods`, or `/Library/PrivilegedHelperTools`.
Do **NOT** invoke for: source-code repos, web sites, mobile (iOS/Android) packages — this skill is macOS-bundle specific.
Hard rules (non-negotiable)
- **Read only.** No `curl/wget/nc/dig` against discovered endpoints. No `lldb attach`, `dtrace`, `fs_usage`, `tcpdump`, `mitmproxy`, `frida`. No Keychain reads. No DRM bypass. No memory dump.
- **Allowed commands only.** See `references/safe_commands.md`. If a step seems to need something outside the whitelist, stop and tell the user instead of improvising.
- **Privacy by default.** In every output file, scrub `device_id`, `uid`, `session_id`, `email`, IDFV, IDFA, JWT, and any 16+ hex blob to `<redacted:N>` (keep length, drop content).
- **Scope cap.** Refuse a single invocation that targets more than 5 apps. Refuse paths under `/System/`, `/usr/libexec/`, `/private/var/db/com.apple.*`. Those are OS components, not third-party telemetry targets.
Runtime
`{baseDir}` = directory of this SKILL.md.
All scripts are bun + TypeScript. Resolve runtime as: prefer `bun` in PATH, otherwise `npx -y bun`. If neither exists, abort with a one-line install hint.
# Smoke check
bun --version || npx --version || echo "Need bun (recommended) or npx"
Workflow — 6 phases, in order
Each phase has: **Goal → Inputs → Commands → Output → Stop conditions**. Do not skip ahead. Do not interleave.
Phase 0 — Scope confirm
**Goal.** Lock the target list to ≤5 valid `.app` paths.
**Inputs.** Whatever the user said — could be a path, a name, or "the input methods I have installed."
**Commands.**
- If user gave a path → verify it exists and ends with `.app`
- If user gave a name → search a fixed list:
/Applications (depth 2)
~/Applications (depth 2)
/Library/Input Methods (depth 1)
/Library/PrivilegedHelperTools (depth 1)
- Reject anything under `/System/`, `/usr/libexec/`, `/private/var/db/com.apple.*`
**Output.** A list `target_apps[]` with absolute paths.
**Stop.** If the list is empty, ask the user once. If >5, ask which to keep.
Phase 1 — Metadata snapshot
**Goal.** Per app, capture the immutable surface: bundle id, version, signing, entitlements, network policy, embedded frameworks.
**Inputs.** `target_apps[]` from Phase 0.
**Commands.** Run `scripts/snapshot_app.ts`:
bun {baseDir}/scripts/snapshot_app.ts <app-path> --out <workdir>/meta.jsonThe script collects:
- `plutil -p <app>/Contents/Info.plist`
- `codesign -dv --entitlements - <app>` (stderr)
- `find <app>/Contents/Frameworks -maxdepth 3 -name '*.dylib' -o -name '*.framework'`
- `otool -L <main-binary>`
- `file <main-binary>` for arch
- Sizes via `du -sh`
**Output.** `<workdir>/meta.json` with: `bundle_id`, `version`, `sandboxed`, `arbitrary_loads`, `ats_exceptions[]`, `entitlements_summary[]`, `frameworks[]` (each: name, path, size_bytes, archs).
**Stop.** If `bundle_id` cannot be read → abort, app is malformed.
Phase 2 — Strings preprocessing
**Goal.** Turn raw `strings` of every embedded binary into bucketed markdown that fits in context.
**Inputs.** `meta.json::frameworks[]`.
**Commands.**
bun {baseDir}/scripts/classify_strings.ts <workdir>/meta.json --out <workdir>/strings/For each binary, the script runs `strings -a -n 6` and sorts each line into one of:
- `urls` — anything matching `https?://`
- `domains` — bare hostnames
- `paths` — `/Library/...`, `~/Library/...`, container-relative paths
- `sql` — `CREATE TABLE`, `INSERT INTO`, `SELECT ... FROM`
- `events` — looks like an event name (`/^[a-z][a-z0-9_]{8,80}$/` with at least one underscore)
- `keys` — base64 / hex blobs ≥ 24 chars (kept count + first 12 chars only, never full)
- `noise` — discarded
**Output.** `<workdir>/strings/<binary-name>.{urls,domains,paths,sql,events}.md` (the `keys` bucket holds only counts + redacted previews).
**Stop.** If a binary is >200 MB → skip it and emit a warning line, do not OOM.
Phase 3 — SDK fingerprint matching
**Goal.** Identify which third-party SDKs are present and how confident.
**Inputs.** `<workdir>/strings/`, plus `references/sdk_fingerprints.md`.
**Commands.**
bun {baseDir}/scripts/match_fingerprints.ts <workdir>/strings/ \
--fingerprints {baseDir}/references/sdk_fingerprints.md \
--out <workdir>/matched.mdThe script applies each fingerprint's `tell-tale strings` regex set to the bucketed strings. A fingerprint counts as **confirmed** when its `min_hits` threshold is met (defined per fingerprint).
**Output.** `<workdir>/matched.md` with one row per SDK: name, vendor, hits, evidence file lines, status (confirmed / partial / absent).
**Stop.** If zero fingerprints confirmed AND the app embeds no third-party `.framework` → write a one-line "no telemetry detected"
Read more
name: happy-app-audit description: Audit a local macOS app's telemetry / reporting behavior using static analysis only. Reverse-engineers an .app bundle to identify embedded SDKs (AppLog/TEA, Parfait, TTNet, mars, MMKV, Sentry, Firebase, Bugly, Umeng, etc.), mapped upload endpoints, local on-disk queues, and privacy-relevant fields — without packet capture, network requests, debugger attach, or DRM bypass. Use when user asks to investigate, audit, or reverse-engineer a macOS app for telemetry, reporting, data upload, privacy, or SDK fingerprinting. Targets /Applications, ~/Applications, /Library/Input Methods, /Library/PrivilegedHelperTools, and similar local install paths. metadata: author: iamzhihuix version: "0.1.0"
Happy App Audit
Static-only macOS app telemetry auditor. Produces a markdown report describing what an installed `.app` bundle reports, to whom, how often (inferred), and what it leaves on disk.
When to invoke
Invoke when the user says any of: "审计 / 调查 / 看看 / 拆 / 逆向 / 上报 / 埋点 / 隐私 / 抓 SDK" combined with a `.app` path or app name. Also invoke when given paths under `/Applications`, `~/Applications`, `/Library/Input Methods`, or `/Library/PrivilegedHelperTools`.
Do **NOT** invoke for: source-code repos, web sites, mobile (iOS/Android) packages — this skill is macOS-bundle specific.
Hard rules (non-negotiable)
- **Read only.** No `curl/wget/nc/dig` against discovered endpoints. No `lldb attach`, `dtrace`, `fs_usage`, `tcpdump`, `mitmproxy`, `frida`. No Keychain reads. No DRM bypass. No memory dump.
- **Allowed commands only.** See `references/safe_commands.md`. If a step seems to need something outside the whitelist, stop and tell the user instead of improvising.
- **Privacy by default.** In every output file, scrub `device_id`, `uid`, `session_id`, `email`, IDFV, IDFA, JWT, and any 16+ hex blob to `<redacted:N>` (keep length, drop content).
- **Scope cap.** Refuse a single invocation that targets more than 5 apps. Refuse paths under `/System/`, `/usr/libexec/`, `/private/var/db/com.apple.*`. Those are OS components, not third-party telemetry targets.
Runtime
`{baseDir}` = directory of this SKILL.md.
All scripts are bun + TypeScript. Resolve runtime as: prefer `bun` in PATH, otherwise `npx -y bun`. If neither exists, abort with a one-line install hint.
# Smoke check bun --version || npx --version || echo "Need bun (recommended) or npx"
Workflow — 6 phases, in order
Each phase has: **Goal → Inputs → Commands → Output → Stop conditions**. Do not skip ahead. Do not interleave.
Phase 0 — Scope confirm
**Goal.** Lock the target list to ≤5 valid `.app` paths.
**Inputs.** Whatever the user said — could be a path, a name, or "the input methods I have installed."
**Commands.**
- If user gave a path → verify it exists and ends with `.app`
- If user gave a name → search a fixed list:
/Applications (depth 2) ~/Applications (depth 2) /Library/Input Methods (depth 1) /Library/PrivilegedHelperTools (depth 1)
- Reject anything under `/System/`, `/usr/libexec/`, `/private/var/db/com.apple.*`
**Output.** A list `target_apps[]` with absolute paths.
**Stop.** If the list is empty, ask the user once. If >5, ask which to keep.
Phase 1 — Metadata snapshot
**Goal.** Per app, capture the immutable surface: bundle id, version, signing, entitlements, network policy, embedded frameworks.
**Inputs.** `target_apps[]` from Phase 0.
**Commands.** Run `scripts/snapshot_app.ts`:
bun {baseDir}/scripts/snapshot_app.ts <app-path> --out <workdir>/meta.jsonThe script collects:
- `plutil -p <app>/Contents/Info.plist`
- `codesign -dv --entitlements - <app>` (stderr)
- `find <app>/Contents/Frameworks -maxdepth 3 -name '*.dylib' -o -name '*.framework'`
- `otool -L <main-binary>`
- `file <main-binary>` for arch
- Sizes via `du -sh`
**Output.** `<workdir>/meta.json` with: `bundle_id`, `version`, `sandboxed`, `arbitrary_loads`, `ats_exceptions[]`, `entitlements_summary[]`, `frameworks[]` (each: name, path, size_bytes, archs).
**Stop.** If `bundle_id` cannot be read → abort, app is malformed.
Phase 2 — Strings preprocessing
**Goal.** Turn raw `strings` of every embedded binary into bucketed markdown that fits in context.
**Inputs.** `meta.json::frameworks[]`.
**Commands.**
bun {baseDir}/scripts/classify_strings.ts <workdir>/meta.json --out <workdir>/strings/For each binary, the script runs `strings -a -n 6` and sorts each line into one of:
- `urls` — anything matching `https?://`
- `domains` — bare hostnames
- `paths` — `/Library/...`, `~/Library/...`, container-relative paths
- `sql` — `CREATE TABLE`, `INSERT INTO`, `SELECT ... FROM`
- `events` — looks like an event name (`/^[a-z][a-z0-9_]{8,80}$/` with at least one underscore)
- `keys` — base64 / hex blobs ≥ 24 chars (kept count + first 12 chars only, never full)
- `noise` — discarded
**Output.** `<workdir>/strings/<binary-name>.{urls,domains,paths,sql,events}.md` (the `keys` bucket holds only counts + redacted previews).
**Stop.** If a binary is >200 MB → skip it and emit a warning line, do not OOM.
Phase 3 — SDK fingerprint matching
**Goal.** Identify which third-party SDKs are present and how confident.
**Inputs.** `<workdir>/strings/`, plus `references/sdk_fingerprints.md`.
**Commands.**
bun {baseDir}/scripts/match_fingerprints.ts <workdir>/strings/ \
--fingerprints {baseDir}/references/sdk_fingerprints.md \
--out <workdir>/matched.mdThe script applies each fingerprint's `tell-tale strings` regex set to the bucketed strings. A fingerprint counts as **confirmed** when its `min_hits` threshold is met (defined per fingerprint).
**Output.** `<workdir>/matched.md` with one row per SDK: name, vendor, hits, evidence file lines, status (confirmed / partial / absent).
**Stop.** If zero fingerprints confirmed AND the app embeds no third-party `.framework` → write a one-line "no telemetry detected"
A collection of practical skill plugins for AI coding agents. Works with Claude Code, Codex, Factory Droid, OpenClaw, Cursor, and 40+ agents.
Repo: iamzhihuix/happy-claude-skills
Other skills on happy-claude-skills.
- /1password
使用 1Password CLI (op) 管理密码和 API credentials。保存、查询、读取 API key/token,注入环境变量到脚本。当用户提到保存密码、保存 API key、查询密码、1password、op CLI、secret 管理时使用此 skill。
Open skill - /browser
Minimal Chrome DevTools Protocol tools for browser automation and scraping. Use when you need to start Chrome, navigate pages, execute JavaScript, take screenshots, or interactively pick DOM elements. Triggers include "browse website", "scrape page", "take screenshot", "automate
Open skill - /docx-format-replicator
Extract formatting from existing Word documents and generate new documents with the same format but different content. Use this skill when users need to create multiple documents with consistent formatting, replicate document templates, or maintain corporate document standards
Open skill - /happy-audio-gen
Universal AI voice / text-to-speech skill supporting OpenAI TTS (gpt-4o-mini-tts, tts-1), ElevenLabs multilingual TTS with voice cloning, Bailian Qwen TTS (qwen-tts / qwen3-tts-vd with voice-design custom voices, long-text chunking built in), MiniMax speech-02-hd, SiliconFlow
Open skill - /happy-dreamina
ByteDance Jimeng (Dreamina) image and video generation via the official `dreamina` CLI. Use this skill whenever the user mentions 即梦, Dreamina, Jimeng, or asks to generate images or videos specifically through ByteDance's Jimeng service. Covers text2image, image2image,
Open skill - /happy-image-gen
Universal AI image generation supporting OpenAI DALL·E / gpt-image, Google Gemini Image / Imagen, Replicate (Flux / SDXL / any model), Stability AI, FAL, Ark (Seedream 4.5), Bailian (qwen-image / wanx), and SiliconFlow. Use this skill whenever the user asks to generate, create,
Open skill

