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"
  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 ↗

Make it feel at home.

The default integration is compact, warm grey and entirely serif. It starts closed; the golden page turns only while there are current books. Book titles, authors and controls share one size.

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. Colour and type stay inside the shelf, so they won’t restyle the website.

collapsible
Start with the little Reading now pill.
open
Start expanded instead; visitors can still close it.
theme="neutral"
The warm-grey palette.
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: #676873;
  --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.

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 write keys. These instructions are for an API you own. 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.