# plani.sh
> Share HTML plans and static demos as live URLs. Built for agents and the humans they work for.
## What this is
plani turns any HTML file or static build into a shareable URL in seconds.
Use it to hand your human a link instead of pasting long output into chat.
## Install
npm i -g plani (or: npx plani)
## Core commands
plani share plan.html # random URL like https://a8xk2m1p.plani.sh
plani share plan.html --name q3-roadmap # stable URL: https://q3-roadmap.plani.sh (login required, free)
plani share ./dist # share a folder of static files (needs index.html)
plani share plan.html --folder clients/acme/q3 # file it in your human's dashboard (Pro)
plani list # list active shares
plani delete # delete a share
plani login # GitHub OAuth; opens a browser for the human
plani versions # version history; every named re-share snapshots the old one
plani ds import --name acme # import a design system (JSON tokens or CSS with --p-* custom props)
plani ds list # list your design systems
plani share plan.html --ds acme # theme the share with a design system (re-resolved live on every view)
plani templates # list preset templates (punchlist, business-plan, project-plan, roadmap, design-concept, dashboard, planning-board)
plani new punchlist/crew --out plan.html # scaffold a preset; --ds bakes your design system, --dice rolls a style seed
plani new --prompt "..." [--ds x|--dice] # print a template-builder brief for the agent to generate a new template against
plani template save file.html --name x # save generated HTML as a reusable account template (scaffold via: plani new mine/x)
plani mcp # run as an MCP stdio server (tools: share/list/versions/delete/ds)
## Behavior notes for agents
- Re-sharing the same --name replaces content at the same URL. "The plan" stays one link as it evolves.
- Names: 3-40 chars, lowercase a-z 0-9 and hyphens. Folders: up to 5 segments, same charset, joined by /.
- Output prints the URL to stdout; exit code 0 on success. Errors are JSON on the API, human-readable on the CLI.
- Anonymous: 1 share/day, 6h expiry, 10MB, public auto URL. Logged in (free): 25/day, 72h, 50MB, public auto URLs, 1 pin.
- Pro ($8/mo): named URLs (--name), private by default (share/publish when ready), 200/day, 7-day links, 100MB, passwords, folders + dashboard, 25 pins.
- Naming (--name) and privacy are Pro-only. Non-Pro shares get a public auto-generated URL immediately.
- Pro shares are private by default (owner-only). Publish with: plani publish (or plani share --public to publish on upload). Make private again with: plani unpublish .
- Shares carry a small plani badge by default; Pro owners can pass --no-badge or set an account default at https://plani.sh/settings.
- Feedback loop: anyone viewing a share can POST a reply to it (free, no login); the owner reads replies back (Pro). Configure a webhook at https://plani.sh/settings to get pinged on every new reply.
- Design systems: named token sets (login required, up to 20). Tokens are the --p-* CSS custom properties
(bg, surface, surface-2, text, muted, border, accent, accent-contrast, ok, warn, danger,
font-display, font-body, font-mono, radius, radius-lg, shadow). A share with --ds gets the
tokens injected at serve time, so editing the design system re-themes every live share using it.
Curated ready-made styles: GET https://plani.sh/api/styles
- Templates: presets at GET https://plani.sh/api/templates (list) and /api/templates//
(returns {html}). All presets consume the --p-* contract and carry data-plani-item reply anchors.
Gallery for humans: https://plani.sh/templates
Custom templates (login): GET/PUT/DELETE https://plani.sh/api/templates/mine[/] with {"html":"...","name":"..."}
- Set PLANI_API_URL to target a self-hosted instance. Source: https://github.com/mitchellfox/plani
## HTTP API (if you cannot run the CLI)
POST https://plani.sh/api/upload {"files":{"index.html":""},"name":"...","folder":"...","ttl":24,"feedbackWidget":true}
feedbackWidget injects a viewer reply widget into the served page (persists across republishes; mark elements with data-plani-item="" + optional data-plani-item-label to make them reply targets)
Authorization: Bearer
GET https://plani.sh/api/deployments # list your shares
GET https://plani.sh/api/deployments?feedback=1 # + feedbackCount/feedbackLatest/feedbackUnread per share (Pro)
DELETE https://plani.sh/api/deployments/
POST https://plani.sh/api/feedback/ {"text":"...","item":"optional anchor","author":"optional"} # public, rate-limited
GET https://plani.sh/api/feedback/ # replies for your share (Pro), Authorization: Bearer ; marks read unless ?peek=1
GET/PUT/DELETE https://plani.sh/api/design-systems/ # {"tokens":{"bg":"#0b141b",...},"fonts":[{"href":"https://..."}]}
POST https://plani.sh/api/deployments//ds {"ds":"acme"} # re-theme an existing share ("" clears)