lihaiplan
v0.1.2
Published
Publish static HTML plan drafts from agents and get a shareable URL.
Readme
lihaiplan
Publish a self-contained HTML file to a permanent public URL.
An agent writes a plan as one HTML file, uploads it, and gets a stable link.
People open that link in a browser; the next agent curls the same link and gets
byte-identical HTML. Every upload is kept as a numbered version, and a numbered
link keeps serving that exact version forever.
npx lihaiplan auth login # paste a key minted in the browser
npx lihaiplan upload ./plan.html # create, or update if this path was uploaded beforeWhere it uploads to
By default, https://plan.jenlihai.website — a hosted deployment. Signing in
requires a Google account.
Point it somewhere else per-invocation with --api-url, or for good:
export LIHAIPLAN_API_URL=https://plan.example.comAnything the server rejects, this CLI tries to reject first, so an obvious policy break costs no upload. It asks the server for its current policy on each run rather than assuming one, so a deployment that allows more (or less) than the default is not second-guessed.
Commands
lihaiplan auth login # interactive; works over SSH
lihaiplan auth set <api-key> # non-interactive
lihaiplan auth logout
lihaiplan whoami # which account the stored key belongs to
lihaiplan upload <file> # --draft <id>, --new, --description <text>
lihaiplan list
lihaiplan show <draft-id> # version history
lihaiplan disable <draft-id> # stop serving it; --undo to reverse
lihaiplan delete <draft-id> # --yes to skip the promptEvery command takes --api-url <url>; upload, list and show also take
--json.
upload with no flags updates whatever draft this file path last created, so
re-running it in a project does the expected thing. --new forces a separate
draft, --draft <id> targets one explicitly — that is the flag a CI job wants,
so its next run adds a version instead of quietly starting a new plan.
After the server accepts an upload, the CLI records that file-to-draft mapping
under ~/.lihaiplan/. If that local write is unavailable (for example, a
sandboxed agent has no home-directory write permission), publication still
succeeds and the CLI prints the draft ID plus a warning. Use the printed
--draft <id> command on the next upload; do not retry as a new upload.
What a draft may contain
One self-contained HTML file. The size limit, and whether inline scripts, external scripts and external stylesheets are allowed, are set per deployment — an import map is inline by definition, so it follows the inline-script setting, and what it names is checked like any other script source. Ask a deployment what it currently enforces:
curl -fsSL https://plan.jenlihai.website/api/configWhat an upload sends
The HTML, and provenance read from the surrounding directory: the git remote's org, name and host, the branch, the commit sha and subject line, whether the tree was dirty, and — under CI — the provider, the run URL and the actor's username. The dashboard shows these so two uploads can be told apart.
Worth knowing before pointing this at a work repository: the remote's host is your internal git server's hostname if you have one, and a commit subject is free text that often names a ticket, a customer, or something unreleased. The file's absolute path is not sent — only its basename.
Where the key goes
A stored key is bound to the server it was created for and is never sent
anywhere else. Targeting a different server with --api-url or
LIHAIPLAN_API_URL asks you to log in there rather than forwarding the key you
already have, because one environment variable in a shell profile or a CI job
should not be able to hand your credential — and, on upload, your document and
the metadata above — to a host you did not choose.
LIHAIPLAN_API_KEY is exempt: supplying the key and the URL together is you
stating both, which is what CI does.
State
~/.lihaiplan/ holds credentials.json, config.json and drafts.json, mode
0600. Supply a key without touching disk with LIHAIPLAN_API_KEY — which is
what CI should do.
Prefer that or auth login over auth set <api-key>: an argument on the command
line lands in your shell history and is visible to ps while it runs.
Licence
UNLICENSED. Published so npx lihaiplan resolves; all rights reserved.
