# Start here: instructions for AI agents

You are an AI coding agent, and the user has pointed you at heremyapp (`https://heremyapp.com`) and asked you to publish, deploy or
launch their project there. This page is the whole job, in order. Follow it from top to bottom and open the linked pages
only when a step needs more detail. You need only `curl`, `tar` and `shasum`.

heremyapp hosts the project's **landing page** (static files: HTML, CSS, JS, images, fonts, video) and its **installer
downloads** (.pkg, .dmg, .zip) at a permanent public URL such as `https://heremyapp.com/ACCOUNT/SPACE`. You build the page, and you
take care of the privacy policy, terms, link previews and version numbers so the user does not have to. heremyapp does
not run server code or databases, and it does not sign, notarize or review installers.

## 1. Work out what to publish

Look at the project before asking anything:

- **What it is**: name, what it does, who it is for (README, `Info.plist`, `package.json`, store listings, the code).
- **What already exists**: a site folder (`site/`, `web/`, `landing/`, `docs/`, `public/`, a build output such as
  `dist/`), an app icon, screenshots, an installer build, a contact email.
- **Which situation** this is, because it sets how much you change
  ([Landing page checklist](https://heremyapp.com/docs/landing.md)):
  - **New page**: there is no landing page yet. Create one with the [design guide](https://heremyapp.com/docs/design.md).
  - **Existing page**: publish it as it is, adding only the missing basics (privacy policy, terms, title, description,
    language, link previews, icons, 404 page).
  - **Release**: the site is already on heremyapp. Update the release information and redeploy.
- **Product type** (Mac app, mobile app, web service, developer tool, game, ...) for the [design guide](https://heremyapp.com/docs/design.md).
- **Installer readiness**, if the project ships an app: the Developer ID identities and the notarization profile
  ([Installers](https://heremyapp.com/docs/installers.md#before-uploading-macos)). Check this now, so a missing credential goes into your single
  question in step 4 instead of interrupting the user later.

If the product needs a server (a web app with a backend), heremyapp can host its landing page and link to the app,
but not the app itself; tell the user.

## 2. Sign in (only when there is no token)

```bash
export HEREMYAPP_TOKEN="${HEREMYAPP_TOKEN:-$(cat ~/.config/heremyapp/token 2>/dev/null)}"
API=https://api.heremyapp.com/v1
AUTH="Authorization: Bearer $HEREMYAPP_TOKEN"
curl -sS --fail-with-body "$API/me" -H "$AUTH"      # account.username is ACCOUNT in every URL
```

If there is no token or `/me` returns `401`, start the device login. The user signs in with GitHub in their browser
(the first time this creates their account) and approves; you never sign up, accept terms or pay for them.

```bash
R=$(curl -sS --fail-with-body -X POST "$API/auth/device" -H "content-type: application/json" \
  -d '{"client_name":"AI agent publishing MY-PROJECT"}')
DEVICE_CODE=$(printf '%s' "$R" | sed -n 's/.*"device_code":"\([^"]*\)".*/\1/p')
printf '%s' "$R" | grep -oE '"(verification_uri_complete|user_code|signups)":"[^"]*"'
```

Send the user the `verification_uri_complete` link and the `user_code`, in their language, for example: "Open this
link, sign in with GitHub, check that the code is ABCD-EFGH and click Approve." If `signups` is `invite_only`, add that
only existing accounts can approve for now. Then poll and save the token without printing it:

```bash
mkdir -p ~/.config/heremyapp && chmod 700 ~/.config/heremyapp
for i in $(seq 1 36); do
  sleep 5
  T=$(curl -sS -X POST "$API/auth/token" -H "content-type: application/json" -d "{\"device_code\":\"$DEVICE_CODE\"}")
  case "$T" in
    *'"token":"hma_'*) printf '%s' "$T" | sed -n 's/.*"token":"\(hma_[^"]*\)".*/\1/p' > ~/.config/heremyapp/token
                       chmod 600 ~/.config/heremyapp/token; echo approved; break ;;
    *authorization_pending*|*slow_down*) ;;
    *) echo "$T"; break ;;
  esac
done
export HEREMYAPP_TOKEN="$(cat ~/.config/heremyapp/token 2>/dev/null)"; AUTH="Authorization: Bearer $HEREMYAPP_TOKEN"
```

The code is valid for 15 minutes; run the loop again if the user needs more time. Details:
[Authentication](https://heremyapp.com/docs/authentication.md).

## 3. Create the space

The slug is part of the permanent URL; use the product name in lowercase with hyphens.

```bash
curl -sS -X POST "$API/spaces" -H "$AUTH" -H "content-type: application/json" \
  -d '{"slug":"my-app","name":"My App"}' -w '\nHTTP %{http_code}\n'
```

`201` creates it. `409 space_exists` means the account already has it; that is fine when it is this project. `402
plan_limit` means the plan's site limit was reached: tell the user and give them `details.upgrade_url`. Save the
response's `public_url` (share this) and `site_url` (use it for absolute URLs inside the page).

## 4. Ask the user once, only for what you cannot find

Collect everything you can from the project first. Then send **one** message, in the user's language, with only the
questions that are still open. Skip any question whose answer you already have.

| Ask | Only when |
|---|---|
| Contact details for the page and the privacy policy (email, business name, phone, address, country), or "skip" | The space's `contact_status` is `unknown` (`GET $API/spaces/SPACE/contact`; a new space always is). If another of the account's spaces has details (`GET $API/spaces`, then its `/contact`), offer to reuse them. |
| More languages than English and the user's own | You are creating a new page |
| A color or mood | New page, and the product has no icon, colors or existing design to take them from |
| Screenshots | New page, and the project has none you can use |
| Signing or notarization setup | Step 1 found no Developer ID identity or no working notarization profile. Never ask for passwords in the chat; ask the user to store the credentials in the keychain themselves and tell you the profile name ([Installers](https://heremyapp.com/docs/installers.md)). |

Never ask about version numbers, slugs, file formats or wording; decide those yourself. Ask again later only if
something fails that you could not check in advance (for example notarization is rejected). If the user does not answer or
cannot be asked (for example in CI), go on with the defaults: English plus the user's language, colors from the icon,
and contact details left `unknown` (do not save `skipped` for them).

A message for a new page could read: "I'll publish MyApp on heremyapp. Two quick questions: (1) Which contact details
should the page and privacy policy show: email, business name, phone, address? You can skip this. (2) The page will be
in English and Korean; any other languages?"

## 5. Publish the installer (if the project ships one)

1. `GET $API/spaces/SPACE/versions` shows the published versions. For the first release, use the project's version
   (completed to three numbers, `1.0` → `1.0.0`); later, pick the next version and build by the
   [versioning policy](https://heremyapp.com/docs/releases.md) (major: incompatible changes, minor: features, patch: fixes; build always goes
   up). Write them into the project, then build and sign.
2. Package it as `.dmg`, `.pkg` or `.zip`, notarize, staple and check it with `spctl`
   ([Installers](https://heremyapp.com/docs/installers.md#before-uploading-macos)). If the check fails, stop and ask the user.
3. Register and upload it, and use the returned `latest_url` as the download link
   ([Installers](https://heremyapp.com/docs/installers.md)):

```bash
FILE=./build/MyApp.pkg; NAME=$(basename "$FILE")
SIZE=$(stat -f%z "$FILE" 2>/dev/null || stat -c%s "$FILE"); SHA=$(shasum -a 256 "$FILE" | cut -d' ' -f1)
curl -sS --fail-with-body -X POST "$API/spaces/my-app/artifacts" -H "$AUTH" -H "content-type: application/json" \
  -d "{\"filename\":\"$NAME\",\"version\":\"1.2.0\",\"build\":\"46\",\"notes\":\"What changed\",\"size\":$SIZE,\"sha256\":\"$SHA\"}"
curl -sS --fail-with-body -T "$FILE" -H "$AUTH" "$API/artifacts/ARTIFACT_ID/content"   # upload.mode "single"
```

## 6. Build the page

- **Design**: follow the [design guide](https://heremyapp.com/docs/design.md) for the product type. Keep an existing page's design.
- **Content and often-missed items**: follow the [landing page checklist](https://heremyapp.com/docs/landing.md): title, description, `lang`,
  link previews with an absolute `og:image` on `site_url`, favicon and apple-touch-icon, structured data, `llms.txt`,
  `404.html`, contact details.
- **Privacy policy and terms**: create `privacy.html` and `terms.html` from the templates, written from what the app
  really does, and link them from the footer of every page ([Privacy policy and terms](https://heremyapp.com/docs/legal.md)).
- **Languages**: English and the user's language by default, with `/ko/`-style folders and `hreflang`.
- **Downloads**: link buttons to the absolute `latest_url`, with version, size and requirements next to them.
- Keep the page in the project (an existing site folder, or a new `site/` folder), not in a temporary copy, so the next
  release can update it.

## 7. Deploy, then fix what the advice says

```bash
curl -sS --fail-with-body "$API/spaces/my-app/versions" -H "$AUTH"     # next site version and build
# The first deploy is always 1.0.0. Later deploys: bump=major|minor|patch by what changed (see Releases).
COPYFILE_DISABLE=1 tar -czf - -C site . | curl -sS --fail-with-body -X POST "$API/spaces/my-app/deployments" \
  --url-query "notes=First public page" \
  -H "$AUTH" -H "content-type: application/gzip" --data-binary @-
# curl older than 7.87 has no --url-query: use ".../deployments?notes=First%20public%20page"
```

The response's `advice` lists anything people often miss (privacy policy, terms, link previews, language, favicon).
Fix what applies and deploy again with `bump=patch` until the list is empty or only has items that do not apply.
Details: [Static sites](https://heremyapp.com/docs/sites.md).

## 8. Verify

```bash
curl -sIL https://heremyapp.com/ACCOUNT/my-app | grep -iE "^HTTP|^x-heremyapp-(version|build)"   # 302, then 200 and the new version
curl -fsSL -o /tmp/check.pkg https://heremyapp.com/dl/ACCOUNT/my-app/latest/MyApp.pkg && shasum -a 256 /tmp/check.pkg   # = $SHA
```

If you can open a browser, look at the page at a phone width and in dark mode.

## 9. Report to the user

Reply in the user's language with:

- The public URL `https://heremyapp.com/ACCOUNT/SPACE` (never the site origin) and the download link
- What you published: pages, languages, privacy policy and terms, the version and build numbers
- What you assumed, and that the privacy policy and terms come from templates and are not legal advice
- Anything left for them: open `advice` items, dead links or placeholder text you did not fix, plan limits
  ([Plans and billing](https://heremyapp.com/docs/billing.md))
- For app stores: the privacy policy URL is `https://heremyapp.com/ACCOUNT/SPACE/privacy`

## Rules

- Never print, log or commit the token, or put it in site files.
- Never sign up, accept terms, choose a plan or pay for the user; on `402`, tell them and give them the upgrade link.
- Ask once per task, and only what you cannot find yourself; ask again only when something fails that you could not
  check in advance. Decide versions yourself.
- Do not upload an installer that fails signature checks unless the user explicitly says so.
- When a request fails, read `error.message` and `error.docs`. More: [For AI agents](https://heremyapp.com/docs/agents.md),
  [API reference](https://heremyapp.com/docs/api.md).
