lavish-axi 0.1.77 → 0.1.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/chrome-client.js +3 -3
- package/dist/cli.mjs +655 -175
- package/package.json +1 -1
- package/plugin.json +1 -1
package/README.md
CHANGED
|
@@ -200,6 +200,7 @@ pnpm link
|
|
|
200
200
|
If the element an unsent annotation was attached to is gone from the artifact for good, Lavish cannot reopen that card, so it writes your text into the conversation panel under **Unsent annotation** - selectable, never written over anything you have typed, and kept there across reloads; no note is ever dropped to make room for a newer one, and a note the browser refuses to store says so where it is shown.
|
|
201
201
|
- **Feedback controls** - Native controls (radios, checkboxes, inputs, selects, buttons, labels, disclosure summaries, contenteditable) are interactive automatically, so they do not need `data-lavish-action`.
|
|
202
202
|
For reversible choices, let option clicks update local state, then queue exactly one final answer from a per-question submit or Queue answer button with `window.lavish.queuePrompt()`.
|
|
203
|
+
If someone may open a decision artifact as a standalone HTML file, `lavish-axi playbook input` provides an optional Copy all answers control they can use to paste their form answers back into chat.
|
|
203
204
|
Mark only custom (non-native) clickable elements with `data-lavish-action` so Lavish does not annotate them, and use `data-lavish-question` or `queueKey` when pre-send updates for the same question should replace each other.
|
|
204
205
|
Everything you send is part of the conversation: a note on an element, a text selection, a table cell, a diagram node, a whiteboard, a layout-issue batch, or a composer message each becomes a bubble on your side of the Conversation panel, with an anchor line naming what it was attached to (the element tag, text selection, table cell, diagram node, whiteboard, or layout issues), a quoted excerpt, and, when available, the selector on hover. A note you have queued but not sent sits at the end of the conversation as a dashed bubble labelled **Queued** with a remove control; while its batch is in flight it reads **Sending**, and once the server accepts it, it settles in place as a sent bubble in every tab of the session. The panel keeps the newest stored transcript up to 5 MiB; older bubbles drop from view, but an accepted note still settles and is not sent twice. Agent replies render a small Markdown subset - paragraphs, line breaks, headings as bold lead lines, bullet and numbered lists, fenced and inline code, bold, italic, and http(s) links - while tables, images, and raw HTML stay as the text the agent wrote; your own messages keep their line breaks and are never parsed.
|
|
205
206
|
On wider screens, the conversation and the queued notes share one scrollable Conversation panel above a sticky composer, so long feedback queues do not push the text box or send controls off screen.
|
|
@@ -228,7 +229,7 @@ pnpm link
|
|
|
228
229
|
Images are stored under the state dir and the queued prompt carries a server-generated absolute `path` and content-hash `id` (plus mime and dimensions) - never the raw bytes - so `lavish-axi poll` hands the agent a local file path to open.
|
|
229
230
|
Limits are `LAVISH_AXI_MAX_ATTACHMENT_BYTES` (default 10 MiB per image), `LAVISH_AXI_MAX_ATTACHMENTS_PER_PROMPT` (default 4), and `LAVISH_AXI_MAX_PROMPT_ATTACHMENT_BYTES` (default 25 MiB per prompt); if any image is missing or any prompt breaches a count or byte cap, the entire send batch is rejected, the queue is preserved, and the reason is surfaced in the composer rather than silently dropping images.
|
|
230
231
|
As a browser-side abuse guard, each chrome page allows 30 upload attempts per rolling minute, 4 uploads in flight at once, and 256 MiB of attempted image bytes over its lifetime; rejected uploads stay visible for retry or removal.
|
|
231
|
-
|
|
232
|
+
Unreferenced attachments expire after `LAVISH_AXI_ATTACHMENT_TTL_MS` (default 7 days; `0`/`off` disables); `LAVISH_AXI_MAX_ATTACHMENT_DISK_MB` (default 512 MiB; `0`/`off` disables) caps total attachment disk and may evict older unreferenced images sooner.
|
|
232
233
|
The cap is enforced when an image is uploaded, not just periodically: the upload first reclaims unreferenced files (oldest first, and never one added within the last hour), and if it still would not fit, that upload is refused with a storage-full error on its chip instead of discarding an image the user is about to send.
|
|
233
234
|
- **Mermaid diagrams** - Whiteboards are an opt-in: agents author a diagram as Mermaid only when you ask for an editable whiteboard, and hand-authored inline SVG illustrations are the default figure medium otherwise.
|
|
234
235
|
In the Lavish browser, every rendered Mermaid diagram in a `.mermaid` container becomes an embedded editable Excalidraw whiteboard.
|
|
@@ -249,7 +250,8 @@ pnpm link
|
|
|
249
250
|
- **Local-first state** - Session state stays under `~/.lavish-axi/` by default, or `LAVISH_AXI_STATE_DIR` when set.
|
|
250
251
|
- **Diagnostic viewports** - `LAVISH_AXI_DIAGNOSTIC_VIEWPORTS` sets which viewport classes the layout-issue inbox tracks (`mobile`, `compact`, `desktop`; comma-separated, default all). Warnings whose class leaves the set are marked obsolete with an explicit reason instead of silently reading as fixed.
|
|
251
252
|
- **Server port** - Set `LAVISH_AXI_PORT` to choose the server port; it defaults to `4387`.
|
|
252
|
-
- **Network binding** - With Tailscale running, the review server automatically listens only on loopback (`127.0.0.1`) and this machine's Tailscale IPv4 address - never on `0.0.0.0` or every interface. The generated session link uses the machine's MagicDNS name, so it is the phone-ready URL to open from another device on the same tailnet. When Tailscale is absent or down, Lavish silently falls back to loopback-only and prints no phone URL. If Tailscale is running but MagicDNS is unavailable
|
|
253
|
+
- **Network binding** - With Tailscale running, the review server automatically listens only on loopback (`127.0.0.1`) and this machine's Tailscale IPv4 address - never on `0.0.0.0` or every interface. The generated session link uses the machine's MagicDNS name, so it is the phone-ready URL to open from another device on the same tailnet. When Tailscale is absent or down, Lavish silently falls back to loopback-only and prints no phone URL. If Tailscale is running but MagicDNS is unavailable, Lavish visibly warns that phone access is unavailable and remains loopback-only. Binding beyond loopback exposes an unauthenticated server that can read and serve arbitrary local files to devices that can reach it, so the tailnet should be trusted. Any explicit `LAVISH_AXI_HOST` overrides automatic Tailscale binding; wildcard values are restricted to loopback, while a non-wildcard value selects that concrete bind address, and the server listens on loopback as well so every local CLI finds it whatever its own `LAVISH_AXI_HOST` says. An address that cannot be bound - the tailnet address while another process holds it, while Tailscale restarts, or an explicit hostname that temporarily does not resolve - is reported as `network_warning` in `lavish-axi <file>` output and logged to `server.log`; session links point at loopback meanwhile unless `LAVISH_AXI_LINK_HOST` overrides them, and the server keeps retrying that address in the background and immediately on the next CLI invocation. Once it binds, the warning clears and new session links use it again, with no restart. If no listener can bind, startup fails rather than claiming a reachable server. `LAVISH_AXI_LINK_HOST` controls the link host when automatic Tailscale binding is disabled.
|
|
254
|
+
- **One server per port** - Agents on one machine can run with different `LAVISH_AXI_HOST` settings, or none, and still share one server: before starting one, the CLI looks for a running server on its configured host, loopback, and every other local address. A running server that was never asked to listen on the address a CLI's `LAVISH_AXI_HOST` names is replaced once by a server that listens on that address plus every address the old one served, keeping all sessions. Upgrade and network-change restarts keep every address the old server served in the same way, except an address that is no longer on this machine. Switching to an address the running server already serves, including loopback, reuses it, so run `lavish-axi stop` first to drop an address. Another server of the same installation (the same state directory) found on the same port at a different address is shut down through its own shutdown endpoint, after the kept server is made to serve that address too, so review links already handed out there keep working. A server belonging to another state directory that reports its installation identity is never used, replaced, or stopped: when it holds loopback or the configured address, the CLI fails with an error naming its state directory, so pick another `LAVISH_AXI_PORT`. Older servers that cannot report an identity are treated as belonging to this installation only at those control addresses, for upgrade compatibility.
|
|
253
255
|
- **Allowed hosts** - To defend against DNS rebinding, the server rejects (`403`) any request whose `Host` header is missing or not one it answers to: loopback names plus the concrete Tailscale IPv4 address and MagicDNS name when the Tailscale listener is successfully bound. If you configure a reverse proxy or another intentional hostname, list it in `LAVISH_AXI_ALLOWED_HOSTS` (whitespace-separated). Behind a reverse proxy, the forwarded `X-Forwarded-Host` is validated against the same list, so add the public hostname there and have the proxy send it together with `X-Forwarded-Proto`. Set `LAVISH_AXI_ALLOWED_HOSTS` to `*` to disable the check entirely, only when the server sits behind your own authentication or proxy. Mutating routes also reject a present foreign `Origin` or `Referer` (`403`); header-less CLI control requests remain allowed where supported.
|
|
254
256
|
- **Browser opening** - Set `LAVISH_AXI_NO_OPEN=1`, equivalent to `--no-open`, to create or resume a session without launching a browser window.
|
|
255
257
|
|
|
@@ -297,6 +299,7 @@ For flows, architecture, state, or sequence diagrams, open the diagram playbook
|
|
|
297
299
|
| `lavish-axi poll` | `--timeout-ms <ms>` | Test/debug escape hatch only; agents should normally omit it and leave the long poll running. |
|
|
298
300
|
| `lavish-axi stop` | `--port <port>` | Shut down a server running on a non-default port. |
|
|
299
301
|
| `lavish-axi server` | `--verbose` | Log session and watcher events to stderr; can also be enabled with `LAVISH_AXI_DEBUG=1`. Detached server output is appended with UTC timestamps to `~/.lavish-axi/server.log` (or `LAVISH_AXI_STATE_DIR/server.log`) for startup, shutdown-cause, and crash diagnostics. |
|
|
302
|
+
| `lavish-axi server` | `--also-listen <host>` | Also listen on this concrete address (repeatable). The CLI passes it when it replaces a running server, so the replacement keeps every address the old one served; see One server per port. |
|
|
300
303
|
|
|
301
304
|
## Development
|
|
302
305
|
|
package/dist/chrome-client.js
CHANGED
|
@@ -3129,9 +3129,9 @@ async function replaceArtifactFrame({ recoveryRetry = false } = {}) {
|
|
|
3129
3129
|
return false;
|
|
3130
3130
|
};
|
|
3131
3131
|
// Keep whatever is on screen, then try again later. A begin-load can fail for reasons that
|
|
3132
|
-
// clear on their own - the shared server is mid-restart, or
|
|
3133
|
-
// restart and this chrome's one re-handshake landed in the same
|
|
3134
|
-
// is what leaves the review permanently unloaded.
|
|
3132
|
+
// clear on their own - the shared server is mid-restart, or a handoff no begin-load had yet
|
|
3133
|
+
// persisted was lost with that restart and this chrome's one re-handshake landed in the same
|
|
3134
|
+
// outage window. Giving up here is what leaves the review permanently unloaded.
|
|
3135
3135
|
const recoverLater = () => {
|
|
3136
3136
|
preservePreviousLoad();
|
|
3137
3137
|
if (requestSequence !== artifactLoadRequestSequence || ended) return false;
|