heremyapp/docs llms.txt
View as Markdown

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):
    • New page: there is no landing page yet. Create one with the design guide.
    • 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.
  • Installer readiness, if the project ships an app: the Developer ID identities and the notarization profile (Installers). 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)

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.

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:

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.

3. Create the space

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

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).

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 (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). 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):
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 for the product type. Keep an existing page's design.
  • Content and often-missed items: follow the landing page checklist: 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).
  • 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

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.

8. Verify

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)
  • 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, API reference.