Contenido del repositorio de origen con títulos, ejemplos, código, tablas, enlaces e imágenes preservados.
here.now
Skill version: 1.28.0
here.now lets agents publish websites and files to live URLs in seconds.
The core primitive is a Site: publish a file or folder and get a live URL at {slug}.here.now or a custom domain. Every Site has access control: public link (default), password, or restricted invite-only access.
here.now also includes workspaces — shared team accounts where Sites belong to the team and serve at {label}.{workspace}.here.now (see "Publish to a workspace" below).
To install or update (recommended): npx skills add heredotnow/skill --skill here-now -g
For repo-pinned/project-local installs, run the same command without -g.
Current docs
Before answering questions about here.now capabilities, features, or workflows, read the current docs:
→ https://here.now/docs
Read the docs:
- at the first here.now-related interaction in a conversation
- any time the user asks how to do something
- any time the user asks what is possible, supported, or recommended
- before telling the user a feature is unsupported
Topics that require current docs (do not rely on local skill text alone):
- Site access control (passwords and restricted access)
- workspaces (team accounts, membership, label URLs)
- Drives and Drive sharing
- custom domains
- Site Data
- public profiles
- proxy routes and service variables
- limits and quotas
- SPA routing
- owner Site search
- Site analytics
- Site version history, previews, and rollback
- error handling and remediation
- feature availability
If docs and live API behavior disagree, trust the live API behavior.
Command-line fetches of https://here.now/docs (curl, WebFetch, etc.) receive a markdown summary, not the full HTML docs: it lists every stable public endpoint with a one-line description, but section anchors in this skill (like /docs#access-control) resolve only in the HTML version, and worked examples live there too. For complete request/response schemas and parameters, fetch https://here.now/openapi.json. Do not conclude an operation is unsupported from the markdown summary alone — check the OpenAPI spec first.
If the docs fetch fails or times out, continue with the local skill and live API/script output. Prefer live API behavior for active operations.
Requirements
- Required binaries:
curl,file,jq - Required network access:
https://here.now(API) andhttps://*.r2.cloudflarestorage.com(file uploads PUT directly to storage; the exact host is in each upload URL). In a sandbox or behind a proxy with an egress allowlist, allow BOTH hosts. With onlyhere.nowallowed, the create call succeeds, every upload fails, and finalize reports missing files. - Optional environment variable:
$HERENOW_API_KEY - Optional Drive token variable:
$HERENOW_DRIVE_TOKEN - Optional credentials file:
~/.herenow/credentials - Bundled helpers:
./scripts/publish.shfor publishing sites./scripts/drive.shfor private Drive storage
If the helper scripts aren't installed
Some environments receive this document without the bundled scripts/ directory (for example, hosted platform integrations that provide only $HERENOW_API_KEY). In that case, either install the full bundle first:
npx skills add heredotnow/skill --skill here-now -gor call the API directly — every script workflow in this document is a wrapper over the public API. Publishing is a three-step flow: POST /api/v1/publish with a files array ([{path, size}]) returns presigned upload targets, PUT each file's bytes to its returned URL, then POST the returned finalizeUrl. The site is not live until finalize succeeds. Full walkthrough with request/response examples: https://here.now/docs#create (then #upload and #finalize), machine-readable schemas: https://here.now/openapi.json.
Create a site
./scripts/publish.sh {file-or-dir}Outputs the live URL (e.g. https://bright-canvas-a7k2.here.now/).
Under the hood this is a three-step flow: create/update -> upload files -> finalize. A site is not live until finalize succeeds.
Without an API key this creates an anonymous site that expires in 24 hours. With a saved API key, the site is permanent.
File structure: For HTML sites, place index.html at the root of the directory you publish, not inside a subdirectory. The directory's contents become the site root. For example, publish my-site/ where my-site/index.html exists — don't publish a parent folder that contains my-site/.
You can also publish raw files without any HTML. Single files get a rich auto-viewer (images, PDF, video, audio). Multiple files get an auto-generated directory listing with folder navigation and an image gallery.
Update an existing site
./scripts/publish.sh {file-or-dir} --slug {slug}The script auto-loads the claimToken from .herenow/state.json when updating anonymous sites. Pass --claim-token {token} to override.
Authenticated updates require a saved API key.
Stale-base protection. The live Site may have changed since your local files were published — the owner can edit it from other tools (another agent, the here.now Studio, a teammate). The script records the live versionId in .herenow/state.json after each publish and sends it as baseVersionId on the next update of the same slug from the same directory; if the live Site moved past it, the update is rejected with code: "version_conflict" naming the live version and what created it. When that happens, relay the message to the user and offer to (a) read the live files with GET /api/v1/publish/{slug}/files (lists them with a url each) and GET /api/v1/publish/{slug}/files/{path} (the bytes; owner API key, works for password-protected and restricted Sites without the visitor password), reconcile them into the local files, and republish, or (b) re-run with --overwrite to replace the live version anyway. Before editing local files for an authenticated Site you haven't touched recently, check for drift first: GET /api/v1/publish/{slug} returns currentVersionId plus currentVersionSource and currentVersionCreatedAt (what changed it and when, e.g. studio) — if the id differs from your state file's versionId, read the live files before editing. The published version is the shared truth; never fetch the public URL to read an owned Site (it is gated for protected Sites) and never ask the user for a visitor password to read their own Site. Anonymous Sites can't call these endpoints; they rely on the saved state and server enforcement. Omitting baseVersionId (or using --overwrite) is an unchecked full replacement — today's default for raw API callers.
Every publish records an immutable version. If the user asks to see earlier versions of a Site, undo a publish, or roll back: list history with GET /api/v1/publish/{slug}/versions and restore instantly with POST /api/v1/publish/{slug}/versions/{versionId}/restore (restoring keeps the current access mode, password, and domains). Version access requires a paid plan and is included for workspace Sites; free accounts' history is recorded and unlocks on upgrade. A byte-identical republish returns unchanged: true from finalize instead of creating a new version. See https://here.now/docs#versions.
Signed-in users also have public profiles. Agents can help users show or hide Sites on their profile and manage profile settings through the API documented at https://here.now/docs#profile.
Publish to a workspace
Workspaces are shared team accounts: Sites published into one belong to the team, not the publishing member, and get a memorable URL at {label}.{workspace}.here.now.
./scripts/publish.sh {file-or-dir} --workspace {subdomain}Requires a saved API key and membership in the workspace. List the user's workspaces (and valid subdomains) with GET /api/v1/accounts. Workspace Sites default to member-only access; the script reports the team URL as publish_result.account_url.
For everything else — creating workspaces, invites and auto-join, workspace domains and variables, label renames — read the current docs:
→ https://here.now/docs#workspaces
Site access control
A Site uses one access mode at a time:
- anyone_with_link (default): anyone with the URL can view.
- password: visitors must enter a shared password.
- restricted: invite-only; only verified email addresses or email domains the owner allows can view.
Workspace-owned Sites default to account_members (visitors sign in and must be workspace members) and also support public, public with a password, and restricted. On a workspace Site, restricted means workspace members plus a per-Site guest allowlist: members always have access, and allowlisted emails/domains are outside guests who can view only that Site — they never become workspace members, though the Site appears in the guest's own dashboard as a shared Site. Workspace restricted requires at least one guest email or domain — an empty allowlist is rejected with a 400 (use account_members for members-only). See https://here.now/docs#workspace-access.
Manage access with GET/PATCH /api/v1/publish/{slug}/access (passwords via the metadata endpoint). Restricted access requires a claimed Site. The PATCH replaces the full allowlists — read, merge, then write. Before working with access control, read the current docs:
→ https://here.now/docs#access-control
Use a Drive
Use a Drive when the user wants private cloud storage for agent files: documents, context, memory, plans, assets, media, research, code, and anything else that should persist without being published as a website.
Every signed-in account has a default Drive named My Drive.
./scripts/drive.sh default
./scripts/drive.sh ls My Drive
./scripts/drive.sh put My Drive notes/today.md --from ./notes/today.md
./scripts/drive.sh cat My Drive notes/today.md
./scripts/drive.sh share My Drive --perms write --prefix notes/ --ttl 7dUse scoped Drive tokens for agent-to-agent handoff. If you receive a herenow_drive share block, use its token as Authorization: Bearer <token> against api_base, respect pathPrefix when present, and preserve ETags on writes. A pathPrefix of null means full-Drive access. If the skill is available, prefer ./scripts/drive.sh; otherwise call the listed API operations directly.
Client attribution
Pass --client with the name of the agent product or harness you are running in — cursor, claude-code, codex, grok-bot, openclaw, gemini, etc:
./scripts/publish.sh {file-or-dir} --client claude-codeThis sends X-HereNow-Client: claude-code/publish-sh on publish API calls. If omitted, the script sends a fallback value.
Use the platform's name, not the name you were given inside it. If you are a bot named "research-bot" running inside Grok Bot, the correct value is grok-bot — not research-bot. Bot names, personas, sub-agents, projects, and thread names don't identify the platform. To record your instance name too, append it after a slash:
./scripts/publish.sh {file-or-dir} --client grok-bot/research-botOnly a standalone agent running in no harness should use its own product name.
API key storage
The publish script reads the API key from these sources (first match wins):
--api-key {key}flag (CI/scripting only — avoid in interactive use)$HERENOW_API_KEYenvironment variable~/.herenow/credentialsfile (recommended for agents)
To store a key, write it to the credentials file:
mkdir -p ~/.herenow && echo "{API_KEY}" > ~/.herenow/credentials && chmod 600 ~/.herenow/credentialsIMPORTANT: After receiving an API key, save it immediately — run the command above yourself. Do not ask the user to run it manually. Avoid passing the key via CLI flags (e.g. --api-key) in interactive sessions; the credentials file is the preferred storage method.
Never commit credentials or local state files (~/.herenow/credentials, .herenow/state.json) to source control.
Getting an API key
To upgrade from anonymous (24h) to permanent sites:
- Ask the user for their email address.
- Request a one-time sign-in code:
curl -sS https://here.now/api/auth/agent/request-code \
-H "content-type: application/json" \
-d '{"email": "user@example.com"}'- Tell the user: "Check your inbox for a sign-in code from here.now and paste it here."
- Verify the code and get the API key:
curl -sS https://here.now/api/auth/agent/verify-code \
-H "content-type: application/json" \
-d '{"email":"user@example.com","code":"ABCD-2345"}'- Save the returned
apiKeyyourself (do not ask the user to do this):
mkdir -p ~/.herenow && echo "{API_KEY}" > ~/.herenow/credentials && chmod 600 ~/.herenow/credentialsState file
After every site create/update, the script writes to .herenow/state.json in the working directory:
{
"publishes": {
"bright-canvas-a7k2": {
"siteUrl": "https://bright-canvas-a7k2.here.now/",
"claimToken": "4fQ9tK2mXb7cW1pZ",
"claimUrl": "https://here.now/c/4fQ9tK2mXb7cW1pZ",
"expiresAt": "2026-02-18T01:00:00.000Z"
}
}
}Before creating or updating sites, you may check this file to find prior slugs. Treat .herenow/state.json as internal cache only. Never present this local file path as a URL, and never use it as source of truth for auth mode, expiry, or claim URL.
What to tell the user
For published sites:
- Always share the
siteUrlfrom the current script run. - Put the site URL on its own line with nothing else on that line — no punctuation, dashes, or status text after it (chat clients autolink everything up to whitespace, gluing your words into the URL). Status details like "permanent, saved to your account" go on the following line.
- Read and follow
publish_result.*lines from script stderr to determine auth mode. - When
publish_result.account_urlis non-empty (workspace publishes), share it as the primary team URL alongsidesiteUrl. - When
publish_result.auth_mode=authenticated: tell the user the site is permanent and saved to their account. No claim URL is needed. - When
publish_result.auth_mode=anonymous: tell the user the site expires in 24 hours. Share the claim URL (ifpublish_result.claim_urlis non-empty and starts withhttps://) so they can keep it permanently. Copy it byte-for-byte as a clickable link — never shorten, redact, summarize, or replace any part of it with...; a modified claim link will not work. Warn that claim tokens are only returned once and cannot be recovered. - Never tell the user to inspect
.herenow/state.jsonfor claim URLs or auth status.
For Drives:
- Do not describe Drive files as public URLs.
- Tell the user Drive contents are private unless shared with a scoped token.
- When sharing access with another agent, prefer a scoped token with a narrow
pathPrefixand short TTL.
publish.sh options
| Flag | Description |
|---|---|
--slug {slug} | Update an existing site instead of creating |
--workspace {subdomain} | Publish into a workspace (team account) you belong to |
--claim-token {token} | Override claim token for anonymous updates |
--overwrite | Skip the stale-base check and replace the live version |
--title {text} | Viewer title (non-HTML sites) |
--description {text} | Viewer description |
--ttl {seconds} | Set expiry (authenticated only) |
--client {name} | Agent harness for attribution — the platform you run in (e.g. cursor, grok-bot), not your bot/persona name; optionally append it: grok-bot/research-bot |
--base-url {url} | API base URL (default: https://here.now) |
--allow-nonherenow-base-url | Allow sending auth to non-default --base-url |
--api-key {key} | API key override (prefer credentials file) |
--spa | Enable SPA routing (serve index.html for unknown paths) |
Beyond publish.sh
For Drive operations, use ./scripts/drive.sh or the Drive API. For broader account and Site management — Site Data, search, analytics, profiles, delete, metadata, access control, domains, variables, proxy routes, duplication, and more — see the current docs:
→ https://here.now/docs
Full docs: https://here.now/docs
