android-reverse-engineering.../CLAUDE.md

92 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What this repo is
A Claude Code **plugin marketplace** (a fork of `SimoneAvogadro/android-reverse-engineering-skill`) hosting three plugins:
- `plugins/android-reverse-engineering/`**upstream, vendored. Never modify.** Decompiles APK/XAPK/JAR/AAR with jadx, extracts HTTP APIs, recovers R8-obfuscated Kotlin names.
- `plugins/clone-app/`**this project's work.** A `/clone-app` skill that takes a Google Play URL, drives the RE plugin to reverse engineer the app, scrapes store metrics, estimates AI-assisted clone effort + infra cost, writes a viability report, and optionally hands off to the `writing-plans` skill.
- `plugins/market-research/`**this project's work.** A `/market-research` skill that autonomously scans the app/game market (free web + LLM trend synthesis), scores ≥10 non-repeating clone candidates (cloneability + market opportunity + monetization fit), and hands user-picked candidates to `clone-app`.
These two project plugins are the first stages of a planned three-stage **discover → analyze → build** pipeline (chained skill handoffs, no central orchestrator): `market-research``clone-app` → a future `hermes-build` plugin (autonomous build → test → Firebase → ads → Play internal-testing track via [hermes-agent](https://github.com/nousresearch/hermes-agent)). The umbrella design lives in `docs/superpowers/specs/2026-06-22-market-to-build-pipeline-design.md`; `hermes-build` and the `clone-app` Phase 7 "Build with hermes" branch are **not yet implemented**.
There is no compiled artifact and no application runtime. "The code" is bash + Python helper scripts plus Markdown skill/command/reference docs that Claude Code loads at session time.
## The hard constraint
`plugins/android-reverse-engineering/` is the upstream tree. Keeping it byte-identical is what makes `git pull upstream master` conflict-free. Before committing, this must print nothing:
```bash
git status --porcelain plugins/android-reverse-engineering/
```
Two remotes: `origin` = `masa2146/clone-app-skill` (this fork), `upstream` = `SimoneAvogadro/android-reverse-engineering-skill`. Sync upstream with `git pull upstream master`. The only shared file the project plugins touch is root `.claude-plugin/marketplace.json` (it now lists three plugins: the upstream RE entry stays attributed to Simone Avogadro and byte-identical; `clone-app` and `market-research` are appended) and—if ever—root `README.md`; everything else lives under each plugin's own dir.
## Commands
```bash
# Full clone-app test suite (5 suites, ~28 assertions). Run from repo root.
bash plugins/clone-app/tests/run-all.sh
# A single test
bash plugins/clone-app/tests/test-extract-package.sh
python3 plugins/clone-app/tests/test-scrape-play-store.py
# Structural smoke test: files present, scripts executable, JSON valid, all plugins in marketplace
bash plugins/clone-app/tests/smoke-structure.sh
# Full market-research suite (3 suites: structure + bash + python). Run from repo root.
bash plugins/market-research/tests/run-all.sh
# A single market-research test
python3 plugins/market-research/tests/test-fetch-charts.py
python3 plugins/market-research/tests/test-history.py
bash plugins/market-research/tests/test-skill-content.sh
# Validate the JSON manifests
python3 -c "import json; json.load(open('.claude-plugin/marketplace.json')); json.load(open('plugins/clone-app/.claude-plugin/plugin.json')); json.load(open('plugins/market-research/.claude-plugin/plugin.json'))"
```
Shell is zsh but every script uses `#!/usr/bin/env bash` — invoke with `bash <path>`, not `sh`. `shopt` etc. fail under zsh; wrap in `bash -c '...'`. Python is stdlib-only (`urllib`, `json`, `re`); no pip, no virtualenv.
**bash 4+ is required at runtime.** The upstream RE scripts (`fingerprint.sh`, `find-api-calls.sh`) use `${VAR,,}` and break with "bad substitution" on macOS's stock bash 3.2. You cannot patch them (upstream-untouched rule), so the fix is `brew install bash`; `#!/usr/bin/env bash` then resolves to the modern one. `resolve-re-scripts.sh` emits a stderr WARNING when it detects bash < 4.
**APK source is APKCombo, not APKPure.** The old `d.apkpure.com/b/APK/<pkg>` endpoint now returns an HTTP 403 Cloudflare challenge for every package. `download-apk.sh` instead GETs `apkcombo.com/app/<pkg>/download/apk` with a browser User-Agent, greps the embedded `/r2?u=<signed-url>` link out of the HTML, and downloads that (no JavaScript needed; the URL slug segment is ignored by the server so a literal `app` works for any package).
## How clone-app is wired
`plugins/clone-app/skills/clone-app/SKILL.md` is the orchestrator an 8-phase (07) prose workflow Claude executes. Phases split into two kinds:
- **Deterministic steps helper scripts** under `skills/clone-app/scripts/`, each independently testable: `extract-package.sh` (Play URL package), `download-apk.sh` (APKCombo two-step download, 3 retries, apk-vs-xapk by ZIP contents), `resolve-re-scripts.sh` (locates the sibling RE plugin's `scripts/` dir + warns if `bash` is < 4), `scrape-play-store.py` (Play page metrics JSON via embedded ld+json), `check-appstore.py` (iTunes Search iOS presence).
- **AI-judgment steps reference rubrics** under `skills/clone-app/references/` (`stack-recommendation-guide`, `effort-estimation-guide`, `infra-cost-guide`, `report-template`). These keep effort/cost/verdict output consistent; edit the rubric, not the prose, to change how estimates are produced.
clone-app never hardcodes RE script paths. It calls `resolve-re-scripts.sh`, which from `plugins/clone-app/` walks to `plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/` (honoring `$CLAUDE_PLUGIN_ROOT`, falling back to deriving its own location). Phase 2 then invokes that dir's `fingerprint.sh`, `check-deps.sh`, `decompile.sh -o "$WORK/output"`, `recover-kotlin-names.sh`, `find-api-calls.sh`.
Two runtime conventions the scripts and SKILL.md share:
- **Working dir** is `./work/{package}/` relative to the user's cwd (never inside the plugin). Decompile output must land at `$WORK/output/` via `decompile.sh -o` `decompile.sh` otherwise defaults to a relative `<basename>-decompiled` dir in cwd.
- **Effort is measured in "AI Sprints"** (one focused Claude session, ~24h review), never calendar time.
SKILL.md pauses for the user at exactly two points: Phase 4 (choose clone stack) and Phase 7 (proceed to implementation plan?). Phase 7's "yes" path invokes `superpowers:writing-plans`.
## How market-research is wired
`plugins/market-research/skills/market-research/SKILL.md` is a 6-phase (05) prose orchestrator following the same **scripts-for-deterministic / rubrics-for-judgment** split as clone-app:
- **Scripts** under `skills/market-research/scripts/`: `fetch-charts.py` (Apple App Store RSS chart feeds normalized JSON; `<feed>` `topfreeapplications`/`toppaidapplications`/`topgrossingapplications`, flags `--region`/`--limit`/`--json-file`) and `history.py` (the non-repeat memory; subcommands `filter`/`add` read a candidates JSON array on **stdin**, flag `--history`; `cand_key` = package if present, else lowercased/stripped name).
- **Rubrics** under `skills/market-research/references/`: `research-angles.md` (rotating category × region × niche seeds for run-to-run variety), `scoring-guide.md` (the 0100 weighted composite: cloneability 35 + market 35 + monetization 20 + niche 10), `report-template.md`.
Working dir is `./work/market-research/` (relative to cwd, never inside the plugin), holding `history.json` (every past suggestion the cross-run non-repeat memory) and `research-<date>.md`. Variety comes from seed rotation **plus** history exclusion. `history.py add` is deterministic it takes `--date`/`--run-id` rather than reading a clock so tests need no fixture clock. Phase 5 resolves each user-picked candidate to a Play package/URL (it may only have an iOS bundle id or a bare name) **before** invoking `clone-app`.
## Test pattern
Bash tests use `set -uo pipefail` (intentionally not `-e`) and aggregate failures into a `fail` var so every assertion runs; the script exits non-zero if any failed. Python scrapers are tested offline against `tests/fixtures/` via `--html-file` / `--json-file` flags never hitting the network. New scrape logic needs a fixture, not a live call.
## Conventions
- Plugin/skill identity is layered: `marketplace.json` top-level `name` (`clone-app-skill`) is what `/plugin install <plugin>@clone-app-skill` resolves against; each plugin's `.claude-plugin/plugin.json` carries its own `name`. The upstream plugin entry inside `marketplace.json` stays attributed to Simone Avogadro.
- Commits follow Conventional Commits scoped to the plugin: `feat(clone-app): …`, `test(market-research): …`, `chore(market-research): …`.
- `docs/superpowers/specs/` and `docs/superpowers/plans/` hold the design specs and task-by-task implementation plans the project plugins were built from read them for the rationale behind a phase or script. `.superpowers/sdd/` is git-ignored scratch (subagent-driven-development progress ledger + per-task briefs/reports); not part of the deliverable.
- Each project plugin mirrors the same layout `skills/<name>/{SKILL.md,scripts/,references/}`, `commands/<name>.md`, `tests/{run-all.sh,smoke-structure.sh,test-*}`, `tests/fixtures/`, `.claude-plugin/plugin.json`, `README.md` so a new plugin starts by copying that shape.