---
name: publik-publish
description: List the app in this repo on publik (publikhq.com) from its GitHub repository and latest release. Use when asked to "list my app on publik" or "publish to publik". Publish nothing before the human says yes to the step 3 checklist.
---

# List this app on publik

Read this file raw (curl), not through a summarising fetch; the shell blocks must run exactly as written.

This needs an interactive session: the human approves in the browser mid-run. In a non-interactive run (`claude -p`, `codex exec`), at each wait print what the human needs (checklist, or URL and code), stop, and tell them to re-run once they have answered.

publik lists apps from their GitHub repository: it reads the repo and the latest release, derives the listing, and publishes it once a scan passes. Follow these steps in order. Use only the endpoints named here; do not guess others.

**Rules.** Never read `.env*` files or print a secret (`pbt_`). Publish nothing the human has not seen and approved.

## 1. Find the repository
Run `git remote get-url origin` and turn it into `owner/repo`. A GitHub release with the built app attached makes the best listing. If there is no release yet, tell the human and ask whether to continue (a public repository can install from source).

**Private repository** (listed closed source: the code is never shown, so it needs a release with a download for each platform). Do step 4 first. Then have the human open `https://publikhq.com/api/github/app/connect?repo=<owner>/<repo>&next=/submit` where they are signed in and finish GitHub's screens. In step 2, add `-H @"$D/pbt.hdr"` to the curl. A `404` there means it is not connected yet.

## 2. Derive the listing (no sign-in needed)
```sh
umask 077; D=$(mktemp -d "${TMPDIR:-/tmp}/publik.XXXXXX"); echo "work dir: $D"
curl -s -X POST https://publikhq.com/api/submit/derive -H 'content-type: application/json' -d '{"repo":"<owner>/<repo>"}' > "$D/derived"
```
Start every later block with `D=<work dir>`. The answer is `{manifest, confidence, notes}` (or `{error}`). Save the `manifest` object alone to `$D/manifest.json`.

## 3. Show the human a checklist and wait for a yes
Show, from the manifest: `name` (18 characters max), `summary` (80 max, no URLs), `category`, `alternativeTo`, `license`, `platforms`, each of `artifacts` (file name and platform), `run` (install / run / build commands), and `publikApi` (`enabled`, `products`). Add every line of `notes` and any field whose `confidence` source is `inferred` or `default`, so the human knows what was guessed. Ask:
- are these right? (apply every correction to `$D/manifest.json`)
- should the app use publik API (AI for its users with no key; the builder earns a share)? If yes, set `publikApi.enabled` to `true` and `publikApi.products` to what it needs from `ai.chat`, `ai.embeddings`, `ai.transcribe`, `ai.speech`, `ai.image`, `search`

**Print the checklist, then stop and wait for a yes.** Do not run step 4 or 5 before the human answers; publishing makes a public listing.

## 4. Sign in through the device flow
```sh
B=https://publikhq.com/api/v1; D=<work dir>; umask 077
curl -s -X POST $B/device/code -H 'content-type: application/json' -d '{"client_name":"<your agent> in <folder>"}' > "$D/device"
tr , '\n' < "$D/device" | sed -n 's/.*"verification_uri_complete":"\([^"]*\)".*/Open \1/p; s/.*"user_code":"\([^"]*\)".*/Code: \1/p'
```
Tell the human: open that URL, check the code matches, click Approve (signing in with GitHub if asked). Then poll (run with a timeout of at least 10 minutes):
```sh
B=https://publikhq.com/api/v1; D=<work dir>; umask 077
{ printf '{"device_code":"'; sed -n 's/.*"device_code":"\([^"]*\)".*/\1/p' "$D/device" | tr -d '\n'; printf '"}'; } > "$D/poll.json"; I=5
while sleep $I; do
  R=$(curl -s -X POST $B/device/token -H 'content-type: application/json' --data-binary @"$D/poll.json")
  case "$R" in
    *access_token*) { printf 'Authorization: Bearer '; echo "$R" | sed -n 's/.*"access_token":"\([^"]*\)".*/\1/p'; } > "$D/pbt.hdr"; echo approved; break;;
    *authorization_pending*|*temporarily_unavailable*) ;;
    *slow_down*) I=$((I+5));;
    *) echo "$R" | sed -n 's/.*"error":"\([^"]*\)".*/stopped: \1/p'; break;;
  esac
done
```
`expired_token`: start step 4 again. `access_denied`: stop and ask the human. The approval lasts one hour.

## 5. Publish
The bearer rides in the header file, never on the command line:
```sh
D=<work dir>; umask 077
{ printf '{"confirm":true,"manifest":'; cat "$D/manifest.json"; printf '}'; } > "$D/body"
curl -s -X POST https://publikhq.com/api/submit -H 'content-type: application/json' -H @"$D/pbt.hdr" --data-binary @"$D/body"; echo
```
When you are done (published, or the human stops), run `rm -rf <work dir>`.
- `200 {slug, url, status}`: print `url`. `status: "live"` means it is public now; `"held_for_review"` means the scan wants a human look first, and it goes live once reviewed. If the answer has `publikApi.prompt`, offer to run it next: it adds publik API to the app (https://publikhq.com/skills/api.md). If it has `publikApi.reason: "claim_first"`, the listing is attributed to the repo's author: publik API can be switched on once they claim it.
- `400 invalid_manifest` / `invalid_fields`: fix the fields it names in `$D/manifest.json`, show the human the change, and re-run step 5.
- `401`: the approval expired; repeat step 4.
- `409 repo_already_listed`: it is already listed under the returned `slug`; tell the human and stop (a new GitHub release updates it).
- `429`: the weekly submission limit; tell the human when to retry.

## After publishing
publik picks up a new GitHub release within a day (or at once from the dashboard's "Check GitHub for a new release now"), scans it, and it replaces the current version after a quick review. Nothing needs resubmitting.
