lunelet

For people & their agents

A small addition.
An easy habit.

Lunelet supplies the window. Your website holds the books.
Install once; after that, just tell your agent what changed.

Install with your website agent.

The easiest route is the setup prompt. It links to a complete, plain-text guide your agent can fetch without a browser or sign-in.

For a direct integration, publish a reading.json file on your own site, then add:

<script type="module" src="https://lunelet.com/v1/reading-shelf.js"></script>
<reading-shelf collapsible variant="compact" theme="neutral" design="loom"
  src="/reading.json"></reading-shelf>

The starter is deliberately empty. Add only the reader’s own books. Do not connect a new installation to the demonstration feed.

Three things for your agent to do

  1. Find the site’s public asset directory and create its reading.json with the reader’s current books and any history they supplied.
  2. Load the module once in the browser and place the shelf where requested. In server-rendered frameworks, register it client-side; don’t evaluate the module on the server.
  3. Leave a LUNELET.md in the project recording the feed path, placement and publishing steps. Publish normally, then check the live JSON and embed.

No account, write key, package installation or database is needed for this file-based setup. Custom scripts must be permitted by the website’s host.

Update books by asking.

“I finished this book. I’m starting that one.” Your website agent can edit the JSON directly, or use the free update tool below. The tool checks the data and keeps unrelated books in place.

Download the agent update tool ↗ · Node 22 or later, no packages.

node tools/lunelet.mjs list --file public/reading.json

node tools/lunelet.mjs next --file public/reading.json \
  --id CURRENT_BOOK_ID \
  --title "Middlemarch" --author "George Eliot" \
  --date YYYY-MM-DD

node tools/lunelet.mjs validate --file public/reading.json

Replace example values and dates with real ones. “Next” finishes the selected book and starts the new one in one local change. Use “start” to add another current book, “finish” to complete one, or “update” to change a note or progress.

The tool updates the file; it does not publish your site. Your agent still uses your normal publishing workflow and verifies the public feed before saying it is live. It refuses concurrent tool edits, invalid data and mismatched revisions.

Full update instructions and commands ↗

Ten styles. The same little window.

Try each style on the live shelf. Your choice follows you into the setup prompt and embed code. The Loom is the default; to switch an existing embed, change only its design attribute.

nocturne · Nocturne
Midnight blue, gold rules and a fine double frame.
orangery · Orangery
Apricot paper, deep botanical green and an arched frame.
papillon · Papillon
Soft lilac, plum lettering and delicate inset rules.
grand-tour · Grand Tour
Peach paper, oxblood type and crisp editorial lines.
tidepool · Tidepool
Sea-glass green, deep teal and gently rounded edges.
print-room · Print Room
Warm paper, mustard bands and bold letterpress type.
loom · The Loom
Parchment, navy lettering and a rust-and-navy woven edge.
correspondent · The Correspondent
Pale blue stationery, an italic signature and an airmail edge.
signal · Signal
Powder blue, vermilion accents and precise ruled details.
paper-theatre · Paper Theatre
Cream pages, cranberry edging and a powder-blue frame.

Each style keeps the compact, icon-only opener and “Currently reading” inside. The small book logo and “powered by lunelet” sit in the top-right corner—there is no large LUNELET heading. Large illustrations, personal headings and current-book counts are omitted. Your books, feed URL, open state and history stay unchanged when switching. All styles support the same font and text-size settings:

reading-shelf {
  --reading-font: Georgia, "Times New Roman", serif;
  --reading-title-font: Georgia, "Times New Roman", serif;
  --reading-font-size: 1rem;
}

Use the host site’s font and body-text size instead when matching its design. Keep both font properties the same. Existing colour overrides take priority over a preset: remove old --reading-* colour values when changing styles if you want the preset’s full palette. Keep font overrides. Colour and type stay inside the shelf, so they won’t restyle the website.

design
One of the ten exact IDs above; for example design="nocturne". No package or separate theme file is needed.
collapsible
Start with just the animated book icon.
open
Start expanded instead; visitors can still close it.
theme="neutral"
The legacy parchment palette; still works without a design attribute.
variant="compact"
A window up to 27rem wide, with 44 × 66px covers.
heading
An optional screen-reader label, not a visible heading.
.refresh()
Re-fetch the current feed; it also refreshes automatically.
The darker Ink palette
reading-shelf {
  --reading-background: #353741;
  --reading-control: #3d3f49;
  --reading-line: #ba856d;
  --reading-border: #a99577;
  --reading-ink: #f4f1e7;
  --reading-muted: #d0cdc3;
  --reading-accent: #eccb7c;
}

Keep keyboard focus, accessible names and reduced-motion support intact. For a strict Content Security Policy, follow the agent guide’s security notes; don’t switch the policy off.

Let Lunelet know you’re using it.

After installing, your agent can ask whether you’d like to register your website. This shares your website address, chosen style and registration dates with Lunelet’s creator—not your books or visitor data.

It’s optional. If you agree, the agent publishes a small public opt-in file on your site and confirms it with Lunelet. This also works if you host the component yourself. Declining changes nothing about your shelf, and you can ask your agent to withdraw later.

No visitor tracking is added. The registry counts participating websites, not people, page views or every installation. A confirmation date is not online presence.

Consent, registration and withdrawal instructions ↗ · Registration API contract ↗

Already have a hosted shelf?

The embed can read any public endpoint returning the shelf JSON format. A compatible write API lets an agent update books without rebuilding the site.

Lunelet does not currently provision hosted accounts or give out book-write keys. These instructions are for an API you own. Optional website registration is separate and cannot change books. Never send somebody else’s books or credentials to Lily’s API.

# LUNELET_WRITE_KEY is supplied by your authorised secret store.
# Never paste it into the embed, a URL, a public file or a prompt.
node tools/lunelet.mjs finish \
  --api https://your-site.example/api/reading \
  --id BOOK_ID --date YYYY-MM-DD

The tool reads the latest revision, sends the smallest requested action with a private bearer key and If-Match, and confirms the saved response. If the shelf changed meanwhile, it stops; it never retries an overwrite.

OpenAPI contract ↗ · Agent API instructions ↗

Everything an agent needs.

Public, directly fetchable files. No browser automation or account required.

Keep book lists and public notes separate from credentials. The release manifest includes SHA-256 checksums for the component and update tool.