# install.md — installation guide for AI agents

> You are an agent. **Do not just say "I'll install it" — run the commands below.**
> This file: `https://fuzhang.net/iosapp/install.md`
> Package: `https://fuzhang.net/iosapp/appstore-ipa-download-skill.zip`

## What this is

A local web app: type an app name → see its App Store listing plus **every historical version** → click a version to download that exact IPA.

- Search and metadata use the public iTunes API (no login, milliseconds).
- Version lists and IPA downloads go through the `ipatool` 2.7 binary (Apple now requires SAP-signed requests; raw requests only return 204/301/500).
- The user logs in with their Apple ID inside the web page. The password never passes through chat and is never stored in plaintext (only an encrypted keychain token).

## Prerequisites

```bash
python --version || python3 --version      # must be 3.8 or newer
curl --version | head -1
```

- Network access to `fuzhang.net`, `github.com` (about 20 MB for ipatool), `itunes.apple.com`, and Apple's CDN.
- At least 2 GB of free disk space (a single IPA can exceed 1 GB).
- Windows, macOS, or Linux.

## One-step install

```bash
mkdir -p /tmp/appstore-dl && cd /tmp/appstore-dl
curl -fL -o skill.zip https://fuzhang.net/iosapp/appstore-ipa-download-skill.zip
python -c "import zipfile;zipfile.ZipFile('skill.zip').extractall('.')"
cd appstore-ipa-download-pack
python install.py
```

The python one-liner is used instead of `unzip` because git-bash on Windows usually has no `unzip`.

`install.py` does all of it: locate the Hermes skills directory → copy the skill in → download the ipatool engine → start the server in the background → open the system browser → print the URL, download directory, and login status.

Install without launching: `SKIP_LAUNCH=1 python install.py`
If skills-directory detection fails: `HERMES_SKILLS_DIR="SKILLS_ROOT" python install.py`

## Verify after installing (never claim success without this)

```bash
curl -s http://127.0.0.1:PORT/api/status
curl -s "http://127.0.0.1:PORT/api/search?q=wechat&country=us"
```

- `/api/status` must return `"engine":"ipatool"` and a `downloads_dir` value.
- `/api/search` must return a non-empty `results` array.
- When nobody is logged in, `/api/versions` returns HTTP 401 with a login hint. That is **normal**, not a failure.

The port is not fixed. Read the `URL:` line printed by `install.py`, or the file `port.txt` inside the working directory.

## Tell the user these three things

1. The web address (the browser should already be open).
2. Ask them to log in themselves via "Sign in with Apple ID" in the top-right of the page — **never ask for the password in chat**. If they use two-factor authentication, the page shows a separate 6-digit code prompt.
3. Where IPAs are saved (the `downloads_dir` from `/api/status`). The page has a live progress bar, the save path, and an "Open folder" button in the bottom-right dock.

## Pitfalls (all hit in real testing)

- **The first launch downloads ipatool 2.7 (about 20 MB). Slow is normal** — do not assume it hung.
- **Do not call ipatool concurrently yourself**: multiple processes fight over `~/.ipatool/cookies.lock` and panic with `cannot acquire lock: cookies.lock already locked`. This app isolates read-only queries with a private `XDG_STATE_HOME` and serializes state-changing operations.
- **Version numbers must be resolved one by one**: the API only returns version IDs; showing "8.0.80" requires a separate Apple request per ID. Apps with hundreds of versions are slow, so the page auto-resolves only the newest 60 and offers a "resolve all" link for the rest.
- **Free apps need a license first** (`purchase`). The page retries that automatically; no manual click needed.
- **Progress percentage is only exact for the latest version**: Apple does not report sizes for old versions, so those show downloaded bytes plus an indeterminate animation instead of a fake percentage.
- IPAs in the download directory can be deleted one by one (red "Delete" button; the server only deletes files inside the download directory).

## Manual install (use this if `install.py` fails)

1. Locate the skills root:
   - Windows: `%LOCALAPPDATA%\hermes\skills`
   - macOS: `~/Library/Application Support/hermes/skills`
   - Linux: `~/.local/share/hermes/skills`
   - With multiple profiles: `SKILLS_ROOT/profiles/PROFILE_NAME/skills`
2. Copy the whole `appstore-ipa-download/` directory to `SKILLS_ROOT/software-development/appstore-ipa-download/`.
3. Start it:
   ```bash
   cd "SKILLS_ROOT/software-development/appstore-ipa-download/scripts"
   python launch.py
   ```
4. Give the user the `URL:` line that `launch.py` prints, verbatim.

## Uninstall

Delete `SKILLS_ROOT/software-development/appstore-ipa-download`, then delete the working directory
`%LOCALAPPDATA%\appstore-dl` (it holds downloaded IPAs, login state, and the engine binary).
