lavish-axi 0.1.89 → 0.1.90

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 CHANGED
@@ -216,7 +216,8 @@ pnpm link
216
216
  - **Agent presence** - The browser shows when no agent is listening, keeps queued feedback for the next successful `lavish-axi poll` send even across reloads, and keeps human feedback actions available while the agent is working because the server queues them for the next poll. An agent reply concludes delivered work and returns presence to waiting (see the CLI Reference for reply and poll commands). A supervisor-owned process listener is shown as an external listener rather than an idle captain turn.
217
217
  - **Delivery receipts** - Every note you have sent carries three emoji under it that light up in turn: 👀 **Seen** when a `lavish-axi poll` takes the note, 🛠️ **Working** when the artifact file changes after that, and ✅ **Done** when the agent replies. A step that has not happened yet is the same emoji greyed out. All three come from what the server observes; the agent does nothing extra. Until 👀 lights, the row says why: no agent is listening, or the agent is busy and the note is delivered on its next poll. A note answered without touching the artifact goes Seen to Done with Working still grey. A reply marks every note the agent has seen as Done, not notes still waiting for a poll. Each emoji names its step and time on hover and to screen readers. Notes sent before receipts existed show no receipt row.
218
218
  In a Herdr-managed pane, set `LAVISH_AXI_HERDR_CHIME=1` to show a Herdr request notification and play its chime once an indefinite poll enters the waiting state. Immediate queued feedback and timed debug polls do not trigger a notification. The integration is off unless both `LAVISH_AXI_HERDR_CHIME` and Herdr's `HERDR_ENV` session marker equal `1`; leaving either unset or using any other value opts out. Notification delivery runs without blocking feedback: if Herdr is unavailable, rejects the notification, stalls, or fails, the poll continues unchanged.
219
- Closing the last review tab while a poll is active starts a 10-second reconnect grace period. A reload or quick reconnect keeps an active poll waiting; if every review stays disconnected, the poll returns `browser_disconnected` without ending the resumable session, and the agent asks whether to reopen or end it instead of acting uninvited.
219
+ Closing the last review tab while a poll is active starts a reconnect grace period, 10 seconds by default. A reload or quick reconnect keeps an active poll waiting; if every review stays disconnected, the poll returns `browser_disconnected` without ending the resumable session, and the agent asks whether to reopen or end it instead of acting uninvited.
220
+ A phone that locks its screen or backgrounds the tab drops the connection too, so set `LAVISH_AXI_DISCONNECT_GRACE_MS` on the server to a longer millisecond budget, or to `0` or `off` so a disconnect never ends the poll (it then waits for feedback, an end, or its own timeout). Empty or invalid values keep the 10-second default.
220
221
  The no-timeout poll always writes an immediate stderr banner so it is visibly not hung; it adds the periodic stderr wait ticks only in an interactive terminal, so when stderr is piped (as under agent harnesses) the captured output carries no tick noise. Stdout always stays reserved for the final response; if the poll is interrupted or times out before feedback arrives, re-run it because feedback remains queued until delivery. Poll delivery consumes the response, so read the complete response before truncating or filtering it.
221
222
  Codex-specific guidance keeps that poll attached to the active turn instead of hiding it in a background task, because completed background tasks may not resume the agent.
222
223
  - **Session end etiquette** - Lavish tracks who ended a session: a human clicking **End session** (or **Send & End**) in the browser is a user-initiated end, while `lavish-axi end <html-file>` is agent-initiated.
@@ -313,6 +314,19 @@ For flows, architecture, state, or sequence diagrams, open the diagram playbook
313
314
  | `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. |
314
315
  | `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. |
315
316
 
317
+ ## Telemetry
318
+
319
+ The npm release sends anonymous usage telemetry to an [Umami](https://umami.is) server at `https://a.kunchenguid.com`. The host and website ID are baked into the published bundle at build time, so telemetry is on by default for `npx -y lavish-axi`.
320
+
321
+ Each `lavish-axi` run sends two requests, except `lavish-axi --version` (also `-v` and `-V`), which sends none: a page view when the command starts, and a `command` event when it finishes. Both carry:
322
+
323
+ - the command name (for example `open`, `poll`, or `home` when you run it with no command), but not its arguments, file paths, artifact content, or prompts
324
+ - the Lavish version, `process.platform`, and `process.arch`
325
+
326
+ The `command` event also carries a `status` field: `success`, or `error` only when the CLI itself throws. A command that fails and sets a nonzero exit code is handled by the CLI framework, so it still reports `success`. No user identifier is sent. Requests time out after 1 second, and failures are ignored, so telemetry never changes what a command does.
327
+
328
+ Set `LAVISH_AXI_TELEMETRY=0` (or `false` or `off`) to turn it off. A build from source sends nothing unless `LAVISH_AXI_UMAMI_WEBSITE_ID` is set, and `LAVISH_AXI_UMAMI_HOST` overrides the host.
329
+
316
330
  ## Development
317
331
 
318
332
  ```sh
package/dist/cli.mjs CHANGED
@@ -10161,7 +10161,7 @@ var BIND_RECOVERY_DELAYS_MS = [1e3, 2e3, 5e3, 1e4, 3e4];
10161
10161
  var LOOPBACK_OWNER_PROBE_TIMEOUT_MS = 500;
10162
10162
  var WEBSOCKET_CLOSE_GRACE_MS = 250;
10163
10163
  var LIVE_EVENT_HEARTBEAT_MS = 3e4;
10164
- var BROWSER_DISCONNECT_GRACE_MS = 1e4;
10164
+ var DEFAULT_BROWSER_DISCONNECT_GRACE_MS = 1e4;
10165
10165
  var ARTIFACT_CONTENT_SECURITY_POLICY = "sandbox allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads";
10166
10166
  var ATTACHMENT_SWEEP_INTERVAL_MS = 60 * 6e4;
10167
10167
  var SHUTDOWN_REASONS = /* @__PURE__ */ new Set(["upgrade", "local-build", "stop"]);
@@ -10250,7 +10250,15 @@ function resolveIdleTimeoutMs(env = process.env) {
10250
10250
  if (raw === "0" || raw.toLowerCase() === "off") return null;
10251
10251
  const value = Number(raw);
10252
10252
  if (!Number.isFinite(value) || value <= 0) return DEFAULT_IDLE_TIMEOUT_MS;
10253
- return value;
10253
+ return Math.min(value, 2147483647);
10254
+ }
10255
+ function resolveBrowserDisconnectGraceMs(env = process.env) {
10256
+ const raw = env.LAVISH_AXI_DISCONNECT_GRACE_MS?.trim();
10257
+ if (raw === void 0 || raw === "") return DEFAULT_BROWSER_DISCONNECT_GRACE_MS;
10258
+ if (raw === "0" || raw.toLowerCase() === "off") return null;
10259
+ const value = Number(raw);
10260
+ if (!Number.isFinite(value) || value <= 0) return DEFAULT_BROWSER_DISCONNECT_GRACE_MS;
10261
+ return Math.min(value, 2147483647);
10254
10262
  }
10255
10263
  async function serve({
10256
10264
  env = process.env,
@@ -10261,7 +10269,7 @@ async function serve({
10261
10269
  log = null,
10262
10270
  pollHeartbeatMs = 15e3,
10263
10271
  liveEventHeartbeatMs = LIVE_EVENT_HEARTBEAT_MS,
10264
- browserDisconnectGraceMs = BROWSER_DISCONNECT_GRACE_MS,
10272
+ browserDisconnectGraceMs = resolveBrowserDisconnectGraceMs(env),
10265
10273
  idleTimeoutMs = resolveIdleTimeoutMs(),
10266
10274
  host = bindHost(env),
10267
10275
  hosts,
@@ -10353,6 +10361,7 @@ async function serve({
10353
10361
  }
10354
10362
  function scheduleBrowserDisconnect(key) {
10355
10363
  clearBrowserDisconnectTimer(key);
10364
+ if (browserDisconnectGraceMs === null) return;
10356
10365
  if (shuttingDown || hasLiveEventClient(key) || !activePolls.has(key)) return;
10357
10366
  const timer = setTimeout(() => {
10358
10367
  browserDisconnectTimers.delete(key);
@@ -12778,7 +12787,7 @@ var AGENT_REPLY_INPUT_LIMIT_BYTES = AGENT_REPLY_JSON_LIMIT_BYTES - AGENT_REPLY_J
12778
12787
  var AGENT_REPLY_LIMIT_LABEL = "2 MB JSON request limit";
12779
12788
  var POLL_STATE_HEADER = "lavish-poll-state";
12780
12789
  var CODEX_POLL_WAKE_PATH_GUIDANCE = "Codex detected: completed background tasks may not resume Codex automatically, so keep the poll attached to the active turn.";
12781
- var VERSION = "0.1.89";
12790
+ var VERSION = "0.1.90";
12782
12791
  function detectInvokingAgent(env = process.env) {
12783
12792
  return ["CODEX_SANDBOX", "CODEX_THREAD_ID"].some((key) => Object.hasOwn(env, key)) ? "codex" : "generic";
12784
12793
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavish-axi",
3
- "version": "0.1.89",
3
+ "version": "0.1.90",
4
4
  "packageManager": "pnpm@11.1.1",
5
5
  "description": "HTML is the new markdown. Lavish is the new editor for your HTML artifacts.",
6
6
  "type": "module",
package/plugin.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
3
  "name": "lavish-axi",
4
- "version": "0.1.89",
4
+ "version": "0.1.90",
5
5
  "description": "HTML is the new markdown. Lavish is the new editor for your HTML artifacts.",
6
6
  "author": {
7
7
  "name": "Kun Chen",