If you are an agent
This page is written so you can follow it. Four rules:
- Publish only when the owner has asked you to publish. Writing an HTML file is not permission to put it online.
- Give the owner the exact
urlfrom the command's output. Never build or guess a URL. - Never send, paste or print this machine's private key. The owner needs only the public key.
- Add a viewer password only when the owner asks for one.
The same instructions, packaged: /SKILL.md is an Agent Skill, /llms.txt is the plain-text summary, and /v1/help describes the API as JSON.
Set up a machine
Download the client and make a key
Needs Node 24 or newer.
mkdir -p ~/.local/share/heyadhi-share && cd ~/.local/share/heyadhi-share curl -fsSLO https://share.heyadhi.com/share.mjs node share.mjs keygenkeygenwrites the private key to~/.config/heyadhi-share/ed25519.pemand prints the public key, a line likeed25519:AbC…=.Give the owner the public key
Send only the
ed25519:line. The private key never leaves this machine.Wait for the owner to register it
Until then every publish fails with
this public key is not registered
. Once registered, the key alone authorizes publishing, until the owner revokes it.
Publish a page
node share.mjs publish page.html
It prints JSON:
{
"site_id": "k3v…",
"url": "https://k3v….share.heyadhi.com/",
"status": "created",
"assets_uploaded": ["style.css", "img/logo.png"],
"assets_missing": []
}
The page is live at url straight away. Each page is its own browser origin, so scripts, storage, cookies and same-origin requests work as they would on any site. A publish that hits a network error retries safely and never creates a duplicate page.
Assets
Stylesheets, scripts, images and fonts that the HTML references by relative path upload automatically when they sit beside the HTML file. Anything listed in assets_missing was referenced but not found: add the file and upload it, or fix the reference.
node share.mjs inspect <site_id>
node share.mjs asset <site_id> ./fonts/Inter.woff2 --path fonts/Inter.woff2
inspect lists every referenced asset as present or missing. --path is where the file lives on the page and defaults to the file name. Paths must be relative: no .., no leading /.
Update and delete
node share.mjs update <site_id> page.html
node share.mjs delete <site_id>
update replaces the HTML at the same URL. delete unpublishes the page for good, and its site_id is never reused.
Viewer password
Pages are public by default. A password makes the page ask visitors for it before showing the HTML or any asset.
| Flag | What it does |
|---|---|
--generate-password | Makes a strong password and prints it once as viewer_password. It is not shown again. |
--password | Asks for a password on the terminal without echoing it. |
--remove-password | On update only: makes the page public again. |
An update with no password flag keeps the current password. Never put a password on the command line or in a URL.
Limits
- HTML file
- 10 MB
- Each asset
- 50 MB
API
The client wraps this HTTP API. Every write carries a one-use token: the machine asks for a challenge, signs it with its Ed25519 key, and trades the signature for the token. Creating a page also needs an Idempotency-Key header.
| Route | What it does |
|---|---|
POST /v1/sites | Create a page from {"html_content", "password"?}. |
GET /v1/sites/{id} | Status, HTML digest, and each referenced asset as present or missing. |
PUT /v1/sites/{id} | Replace the HTML; set, rotate or remove the password. |
POST /v1/sites/{id}/assets?relative_path=… | Upload one asset. |
DELETE /v1/sites/{id} | Unpublish. The id is never reused. |
GET /v1/help | Routes, limits, authentication and errors, as JSON. |
Errors
Errors come back as JSON with a message field that says what to do next.
| Code | Meaning |
|---|---|
401 | The machine key is missing, unregistered or revoked. |
403 | Unsafe asset path. |
404 | No such page, or a protected page and the request is not from a registered machine. |
409 | A conflicting update landed first. Inspect the page and retry. |
410 | This Idempotency-Key belongs to a deleted page. Create with a new key. |
413 | Over a size limit. |
422 | Invalid input. |
429 | Too many requests. Wait a minute and retry. |
503 | Storage is briefly unavailable. Retry. |