---
name: wiki-api
description: >-
  How to drive the Adom Wiki (wiki.adom.inc) programmatically: the `adom-wiki pkg` CLI,
  the REST API (/api/v1/...), authentication, and the publish workflow that
  writes BOTH storage layers (git repo + package registry). Read this before any
  create-page, push-files, or publish call. Trigger words: wiki api, `adom-wiki pkg`,
  adom-wiki pkg publish, adom-wiki pkg install, POST pages, push files to wiki, wiki rest
  api, publish to the wiki, create wiki page, commit to wiki repo, wiki bearer
  token, adom-wiki auth, two storage layers, wiki tarball.
---

Parent skill: **adom-wiki-skillpack**

# Driving the Adom Wiki: `adom-wiki pkg` + the REST API

Canonical host: **https://wiki.adom.inc**. Read **wiki-anatomy** first if you
don't yet know why the wiki has two independent storage layers, this skill is
the how. Read **wiki-publish-safely** for the pitfalls.

## Auth

```bash
bash <(curl -fsSL https://wiki.adom.inc/static/bootstrap.sh)   # if `adom-wiki pkg` missing
export PATH="$HOME/.local/bin:$PATH"
adom-wiki auth "$(cat /var/run/adom/api-key)"
adom-wiki whoami
# For curl: -H "Authorization: Bearer $(cat /var/run/adom/api-key)"
```

## `adom-wiki pkg` CLI (the bits you use most)

| Command | Purpose |
|---|---|
| `adom-wiki pkg install <slug>[@ver]` | Install a package (+ its dependencies) |
| `adom-wiki pkg info <slug>` / `view` | Manifest / full metadata + versions |
| `adom-wiki pkg search <query>` | Search the registry |
| `adom-wiki pkg list` / `outdated` / `update` | Manage installed packages |
| `adom-wiki pkg version <patch\|minor\|major>` | Bump version in package.json |
| `adom-wiki pkg publish [--org adom] [-y]` | Build + upload the tarball to the registry |
| `adom-wiki release upload <slug>@<ver> <file> --platform <os>` | Attach a downloadable binary |

Namespace: `adom-wiki pkg publish` goes to your personal namespace (`john/<slug>`).
Add `--org adom -y` to publish a canonical org package (`adom/<slug>`).

## The publish workflow: both layers, in this order

The git repo and the package registry are written separately (see wiki-anatomy).
Write both, and order matters because of the hero-clobber gotcha (see step 4).

**Step 1, `package.json` first.** Set `slug`, `version`, `type`, `description`,
`dependencies`, `files[]` (list every shipped file), and `scripts.install/uninstall`.

**Step 2, create the page (first publish only).** Inits the git repo.

```bash
WIKI="https://wiki.adom.inc"
curl -s -X POST "$WIKI/api/v1/pages" \
  -H "Authorization: Bearer $(cat /var/run/adom/api-key)" \
  -H "Content-Type: application/json" \
  -d '{"type":"skill","slug":"my-tool","title":"my-tool","brief":"One line","version":"0.1.0"}'
```

**Step 3, `adom-wiki pkg publish`.** Builds the tarball and uploads it to the registry.
(Do this before the final file push, see step 4.)

```bash
cd /path/to/my-tool && adom-wiki pkg publish
```

**Step 4, push ALL source files to the git repo, with a complete `page.json` LAST.**
This is the equivalent of `git push`. **Critical:** `adom-wiki pkg publish` overwrote
the repo's `page.json` with the package manifest, which has no `hero`, so you
re-push a *complete* `page.json` (including `hero:{type,path}`, title, brief,
tags) as the final step to re-index and re-link the hero. See **wiki-hero**.

```python
import requests, base64, os
BINARY_EXTS = {'.png','.jpg','.jpeg','.webp','.gif','.ico','.woff','.woff2',
               '.tgz','.gz','.zip','.bin','.exe','.glb','.step','.stl','.wasm','.so','.dll'}
files, skip = [], {'.git','target','node_modules'}
for root, dirs, fnames in os.walk(project_dir):
    dirs[:] = [d for d in dirs if d not in skip]
    for f in fnames:
        full = os.path.join(root, f); rel = os.path.relpath(full, project_dir)
        if os.path.getsize(full) > 10_000_000: continue
        if os.path.splitext(f)[1].lower() in BINARY_EXTS:
            files.append({"path": rel, "content": base64.b64encode(open(full,'rb').read()).decode(), "encoding": "base64"})
        else:
            files.append({"path": rel, "content": open(full).read()})  # TEXT = plain, never base64
for i in range(0, len(files), 50):  # batch by 50 (payload limit)
    requests.post(f"{WIKI}/api/v1/pages/{slug}/files",
        headers={"Authorization": f"Bearer {token}", "User-Agent": "`adom-wiki pkg`/2.1.0"},  # UA dodges Cloudflare WAF
        json={"files": files[i:i+50], "message": "Publish source"})
```

**Step 5, verify in pup** (non-negotiable; see **wiki-publish-safely**).

## Encoding rule (memorize)

Text files (`.md`, `.rs`, `.toml`, `.js`, `.json`, `.sh`) → plain `{"content": "..."}`.
Binary files (images, fonts, archives) → `{"content": "<base64>", "encoding": "base64"}`.
Base64-encode a text file and the README renders as gibberish.

## REST API quick reference

- Pages: `POST /pages`, `GET/PUT/DELETE /pages/:slug`, `GET /pages` (`?type=&limit=&offset=`)
- Files (git): `GET/POST /pages/:slug/files`, `GET /pages/:slug/files/:path`, `GET /pages/:slug/log`
- Packages: `POST /packages/:slug/publish`, `GET /packages/:slug/manifest|versions`, `POST /packages/resolve`, `PUT .../deprecate`
- Social: `POST/DELETE /pages/:slug/star`, `GET /pages/:slug/stars`, discussions under `/pages/:slug/discussions`
- PRs: `GET/POST /pages/:slug/prs`, `POST /prs/:id/merge|close`
- Breadcrumbs: `GET /pages/:slug/breadcrumbs` (see **wiki-breadcrumbs**)
- Search/discover: `GET /search?q=`, `GET /discover?triggers=<csv>`

Two gotchas worth pinning here: **Cloudflare WAF blocks Python urllib without a
`User-Agent`** (use ``adom-wiki pkg`/2.1.0`; curl is fine), and **FTS search chokes on
hyphens** (`chip-fetcher` → "no such column: fetcher"). Full pitfall list →
**wiki-publish-safely**.

## Which manifest a publish reads (PAGE_JSON_IGNORED)

`adom-wiki pkg publish` reads **`package.json` ONLY**. Discovery fields placed in `page.json`
(`discovery_triggers`, `discovery_pitch`, `sample_prompts`, `description`) do NOTHING at publish
time; the linter says so: `PAGE_JSON_IGNORED ... Only the package.json manifest counts.`
`page.json` is read on **page-repo pushes**, not package publishes. Keep the discovery fields in
`package.json`; keep them mirrored in `page.json` only if the page layer also uses them.

And for page files themselves: `adom-wiki repo push` is the canonical write path (see wiki-anatomy,
"Two storage layers") - a 200 from the raw files POST does not mean the Files tab updated.
