lavish-axi 0.1.66 → 0.1.67

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
@@ -205,6 +205,7 @@ pnpm link
205
205
  In the annotation card, Enter queues the annotation, Shift+Enter inserts a newline, and Ctrl+Enter (Cmd+Enter on macOS) queues it and sends all queued prompts immediately. Escape closes the card, same as Cancel, but only while it is empty (no text, no attachment); with unsent text or an attachment present, Escape does nothing rather than risk discarding it.
206
206
  Cmd+I or Ctrl+I toggles between annotate and explore mode from either the browser chrome or the artifact iframe, including while focus is in a textarea or control.
207
207
  - **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. The agent's reply (`--agent-reply`) concludes delivered work and returns presence to waiting.
208
+ 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.
208
209
  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.
209
210
  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.
210
211
  - **Session end etiquette** - Lavish tracks who ended a session: a human clicking **End session** (or **Send & end session**) in the browser is a user-initiated end, while `lavish-axi end <html-file>` is agent-initiated.
@@ -253,7 +254,7 @@ pnpm link
253
254
  | `lavish-axi` | Show current sessions and usage guidance. |
254
255
  | `lavish-axi update` | Check for or apply the latest npm release through the AXI SDK self-updater. |
255
256
  | `lavish-axi <html-file>` | Open or resume a Lavish Editor session, with the open-time layout gate enabled by default. Unresolved layout issues from earlier in the session are preserved. Refuses to reopen a session the user explicitly ended from the browser unless `--reopen` is passed. |
256
- | `lavish-axi poll <html-file>` | Long-poll until the user sends feedback or ends the session; detected layout issues wait in the user's Layout issues inbox and arrive only when queued. Leave no-timeout polls running, or re-run them if interrupted. Codex guidance keeps polls attached to the active turn. On `status: ended`, stop polling and do not reopen uninvited. |
257
+ | `lavish-axi poll <html-file>` | Long-poll until the user sends feedback, ends the session, or leaves every review disconnected past the reconnect grace period; detected layout issues arrive only when queued. On `browser_disconnected`, ask before reopening or ending the still-resumable session. On `ended`, stop polling and do not reopen uninvited. |
257
258
  | `lavish-axi end <html-file>` | End a session as the agent; unlike a user-initiated end from the browser, this still allows a plain reopen later. |
258
259
  | `lavish-axi export <html-file>` | Write a portable copy of the artifact: one HTML file with its local assets inlined, so it opens with no server and no sibling files. Remote CDN/font references are left as links. |
259
260
  | `lavish-axi share <html-file>` | Publish the artifact (local assets inlined) to [ht-ml.app](https://ht-ml.app), a third-party host not part of Lavish, and print a visitable URL plus a secret update key; shares are public by default, `--private` locks one behind a generated password, and the same command republishes or unpublishes an existing page with `--site`/`--update-key`. |
package/dist/cli.mjs CHANGED
@@ -8813,6 +8813,7 @@ var WHITEBOARD_CHANNEL_TOKEN_TTL_MS = 5 * 6e4;
8813
8813
  var NETWORK_RECONCILE_CACHE_MS = 1e3;
8814
8814
  var TAILSCALE_BIND_RETRY_DELAYS_MS = [100, 250, 500];
8815
8815
  var WEBSOCKET_CLOSE_GRACE_MS = 250;
8816
+ var BROWSER_DISCONNECT_GRACE_MS = 1e4;
8816
8817
  var ARTIFACT_CONTENT_SECURITY_POLICY = "sandbox allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads";
8817
8818
  var ATTACHMENT_SWEEP_INTERVAL_MS = 60 * 6e4;
8818
8819
  var SHUTDOWN_REASONS = /* @__PURE__ */ new Set(["upgrade", "local-build", "stop"]);
@@ -8910,6 +8911,7 @@ async function serve({
8910
8911
  debug = false,
8911
8912
  log = null,
8912
8913
  pollHeartbeatMs = 15e3,
8914
+ browserDisconnectGraceMs = BROWSER_DISCONNECT_GRACE_MS,
8913
8915
  idleTimeoutMs = resolveIdleTimeoutMs(),
8914
8916
  host = bindHost(env),
8915
8917
  hosts,
@@ -8942,6 +8944,7 @@ async function serve({
8942
8944
  const activePolls = /* @__PURE__ */ new Map();
8943
8945
  const deliveredFeedback = /* @__PURE__ */ new Set();
8944
8946
  const liveEventClients = /* @__PURE__ */ new Map();
8947
+ const browserDisconnectTimers = /* @__PURE__ */ new Map();
8945
8948
  const whiteboardChannelSecret = crypto6.randomBytes(32);
8946
8949
  const outstandingRepairBatches = /* @__PURE__ */ new Set();
8947
8950
  const diagnosticViewportClasses = resolveDiagnosticViewportClasses();
@@ -8954,6 +8957,7 @@ async function serve({
8954
8957
  let serverReady = false;
8955
8958
  let networkReconcileCheckedAt = 0;
8956
8959
  let cachedNetworkStale = false;
8960
+ let shuttingDown = false;
8957
8961
  let networkReconcilePromise = null;
8958
8962
  function broadcastLiveEvent(type, key, data = {}) {
8959
8963
  for (const [client, clientKey] of liveEventClients) {
@@ -8965,7 +8969,30 @@ async function serve({
8965
8969
  events.on("agent-presence", (key, state) => broadcastLiveEvent("agent-presence", key, { state }));
8966
8970
  events.on("layout-warnings", (key, warnings) => broadcastLiveEvent("layout-warnings", key, { warnings }));
8967
8971
  events.on("ended", (key, endedBy) => broadcastLiveEvent("ended", key, { ended_by: endedBy || null }));
8972
+ function hasLiveEventClient(key) {
8973
+ for (const clientKey of liveEventClients.values()) {
8974
+ if (clientKey === key) return true;
8975
+ }
8976
+ return false;
8977
+ }
8978
+ function clearBrowserDisconnectTimer(key) {
8979
+ const timer = browserDisconnectTimers.get(key);
8980
+ if (!timer) return;
8981
+ clearTimeout(timer);
8982
+ browserDisconnectTimers.delete(key);
8983
+ }
8984
+ function scheduleBrowserDisconnect(key) {
8985
+ clearBrowserDisconnectTimer(key);
8986
+ if (shuttingDown || hasLiveEventClient(key) || !activePolls.has(key)) return;
8987
+ const timer = setTimeout(() => {
8988
+ browserDisconnectTimers.delete(key);
8989
+ if (!hasLiveEventClient(key) && activePolls.has(key)) events.emit("browser-disconnected", key);
8990
+ }, browserDisconnectGraceMs);
8991
+ timer.unref?.();
8992
+ browserDisconnectTimers.set(key, timer);
8993
+ }
8968
8994
  function attachLiveEventClient(client, key, onClose) {
8995
+ clearBrowserDisconnectTimer(key);
8969
8996
  liveEventClients.set(client, key);
8970
8997
  refreshIdleTimer();
8971
8998
  let cleanedUp = false;
@@ -8973,6 +9000,7 @@ async function serve({
8973
9000
  if (cleanedUp) return;
8974
9001
  cleanedUp = true;
8975
9002
  liveEventClients.delete(client);
9003
+ scheduleBrowserDisconnect(key);
8976
9004
  refreshIdleTimer();
8977
9005
  };
8978
9006
  onClose(cleanup);
@@ -9252,25 +9280,28 @@ async function serve({
9252
9280
  if (heartbeat) clearInterval(heartbeat);
9253
9281
  events.off("feedback", onFeedback);
9254
9282
  events.off("ended", onFeedback);
9283
+ events.off("browser-disconnected", onBrowserDisconnected);
9255
9284
  setPollActive(key, activePolls, deliveredFeedback, events, false);
9285
+ if (!activePolls.has(key)) clearBrowserDisconnectTimer(key);
9256
9286
  refreshIdleTimer();
9257
9287
  cleanupPoll = null;
9258
9288
  detachRequestClose();
9259
9289
  };
9260
- const respond = async () => {
9290
+ const respond = async (forcedResult = null) => {
9261
9291
  if (responding || res.writableEnded) return;
9262
9292
  responding = true;
9263
9293
  try {
9264
9294
  const result = await store.takeFeedback(key);
9295
+ const responseResult = forcedResult && result.status === "waiting" ? forcedResult : result;
9265
9296
  if (requestClosed || req.destroyed || res.writableEnded) {
9266
- await restoreClosedFeedback(key, result);
9297
+ await restoreClosedFeedback(key, responseResult);
9267
9298
  return;
9268
9299
  }
9269
- finishFeedbackDelivery(key, result);
9300
+ finishFeedbackDelivery(key, responseResult);
9270
9301
  if (streamHeartbeat) {
9271
- res.end(JSON.stringify(result));
9302
+ res.end(JSON.stringify(responseResult));
9272
9303
  } else {
9273
- res.json(result);
9304
+ res.json(responseResult);
9274
9305
  }
9275
9306
  } finally {
9276
9307
  cleanup();
@@ -9282,8 +9313,13 @@ async function serve({
9282
9313
  }
9283
9314
  respond().catch(handleRespondError);
9284
9315
  };
9316
+ const onBrowserDisconnected = (changedKey) => {
9317
+ if (changedKey !== key || res.writableEnded) return;
9318
+ respond({ status: "browser_disconnected" }).catch(handleRespondError);
9319
+ };
9285
9320
  events.on("feedback", onFeedback);
9286
9321
  events.on("ended", onFeedback);
9322
+ events.on("browser-disconnected", onBrowserDisconnected);
9287
9323
  cleanupPoll = cleanup;
9288
9324
  if (requestClosed || req.destroyed || res.writableEnded) {
9289
9325
  cleanup();
@@ -10045,7 +10081,6 @@ ${body}`
10045
10081
  }
10046
10082
  publicPort = httpServers[0].address().port;
10047
10083
  serverReady = true;
10048
- let shuttingDown = false;
10049
10084
  function shutdown(reloadKey = "", reason = "") {
10050
10085
  if (shuttingDown) return;
10051
10086
  shuttingDown = true;
@@ -10070,6 +10105,8 @@ ${body}`
10070
10105
  }
10071
10106
  }
10072
10107
  liveEventClients.clear();
10108
+ for (const timer of browserDisconnectTimers.values()) clearTimeout(timer);
10109
+ browserDisconnectTimers.clear();
10073
10110
  for (const w of watchers.values()) {
10074
10111
  w.close().catch(() => {
10075
10112
  });
@@ -10912,11 +10949,12 @@ var POLL_WAKE_PATH_RULES = Object.freeze([
10912
10949
  "Never use `nohup`, shell `&`, `disown`, redirected fire-and-forget processes, or a detached terminal without an explicit verified callback merely to keep polling alive.",
10913
10950
  "If the harness has no completion-aware background facility, use the foreground poll or first wire a verified wake callback into the surrounding supervisor.",
10914
10951
  "Do not tell the user the artifact is being monitored until that wake path is live.",
10915
- "If the poll gets killed or times out before feedback arrives, re-run it - feedback remains queued until delivery. Poll delivery consumes the response, so read it completely."
10952
+ "If the poll gets killed or times out before feedback arrives, re-run it - feedback remains queued until delivery. Poll delivery consumes the response, so read it completely.",
10953
+ "If it returns browser_disconnected, the review window stayed disconnected past its reconnect grace period but the session remains resumable; ask the user whether to reopen or end it, and do neither uninvited."
10916
10954
  ]);
10917
10955
  var POLL_SEND_AND_END_RULE = "`Send & End` ends the session. Its final feedback is still delivered once. After that response, polling stops, and the agent must not reopen the session uninvited.";
10918
10956
  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.";
10919
- var VERSION = "0.1.66";
10957
+ var VERSION = "0.1.67";
10920
10958
  function detectInvokingAgent(env = process.env) {
10921
10959
  return ["CODEX_SANDBOX", "CODEX_THREAD_ID"].some((key) => Object.hasOwn(env, key)) ? "codex" : "generic";
10922
10960
  }
@@ -11032,7 +11070,7 @@ function createHomeOutput({ bin, sessions, includeSessions = true, agent = "gene
11032
11070
  "Run `lavish-axi <html-file>` to open or resume a Lavish Editor session. If the user explicitly ended the session from the browser, this refuses to reopen it and explains why instead of reopening uninvited - pass `--reopen` only when the user asks for further review or something important needs their visual attention",
11033
11071
  "Unless the user specifies another location, create HTML artifacts in the current working directory under `.lavish/`",
11034
11072
  "Lavish serves the html file through a local express.js server. If your html needs to reference other filesystem assets such as images, CSS, fonts, and local scripts, copy them into the same directory as the HTML file, then reference them with relative paths from that directory. Never prepend `/` to those asset paths - root paths won't work",
11035
- `Run \`lavish-axi poll <html-file>\` to wait for user feedback. It long-polls and stays silent until the user sends feedback or ends the session, so leave it running - never kill it. Detected layout issues never return this poll: the browser files them in the user's Layout issues inbox in the Lavish top bar, and they arrive as an ordinary tag "layout-warnings" prompt only when the user selects them and queues the fixes. Never edit the artifact to chase a layout issue the user has not queued. The only exception is a fatal artifact_failures response, which means the review surface itself could not be used. ${pollExecutionGuidance({ agent })} ${POLL_SEND_AND_END_RULE}`,
11073
+ `Run \`lavish-axi poll <html-file>\` to wait for user feedback. It long-polls and stays silent until the user sends feedback, ends the session, or leaves every review window disconnected past the reconnect grace period, so leave it running - never kill it. Detected layout issues never return this poll: the browser files them in the user's Layout issues inbox in the Lavish top bar, and they arrive as an ordinary tag "layout-warnings" prompt only when the user selects them and queues the fixes. Never edit the artifact to chase a layout issue the user has not queued. The only exception is a fatal artifact_failures response, which means the review surface itself could not be used. ${pollExecutionGuidance({ agent })} ${POLL_SEND_AND_END_RULE}`,
11036
11074
  'Mermaid is the whiteboard opt-in, not the diagram default: only when the user asks for an editable whiteboard, author that diagram as Mermaid in a `.mermaid` container. Rendered Mermaid diagrams there become embedded, editable Excalidraw whiteboards in the browser (click a diagram to unlock editing; a Fullscreen action opens it over the whole viewport) - flowchart, sequence, class, ER, and state diagrams convert to editable shapes; other types embed as an image to draw on. Scenes autosave locally; an unmodified autosave silently re-converts when a reload changes the Mermaid source. If the reviewer edited the scene, they choose to re-convert and discard saved edits or keep editing the saved scene. Standalone and exported copies still render plain Mermaid. Queue feedback adds a prompt to the Conversation panel; when the user sends it, poll returns a tag "whiteboard" prompt carrying a bounded edit summary plus local scenePath (.excalidraw JSON) and previewPath (PNG) files - read the summary first, open the files only when needed, then apply the edits by updating the Mermaid source in the artifact (never try to write the scene back)',
11037
11075
  "Run `lavish-axi end <html-file>` to end a session as the agent - ending it this way still allows a plain reopen later. When the user ends it from the browser instead, a later `lavish-axi <html-file>` refuses to reopen it without `--reopen`",
11038
11076
  "Run `lavish-axi export <html-file> [--out <path>]` to write a portable copy of the artifact - one HTML file with its LOCAL assets inlined - so it opens with no Lavish server and no sibling files. Remote CDN/font references are left as links, so it needs network to render those. Users can also export from the browser chrome's overflow menu",
@@ -11073,7 +11111,7 @@ function createOpenOutput({
11073
11111
  session: { file, url, status },
11074
11112
  ...networkWarning ? { network_warning: networkWarning } : {},
11075
11113
  ...selfPaintWarning ? { self_paint_warning: selfPaintWarning } : {},
11076
- next_step: `${selfPaintPrefix}Do not respond to the user just yet. Now you must run \`lavish-axi poll ${file}\`. This command long-polls until the user sends feedback or ends the session, and it stays silent the whole time - that is normal, never kill it. Layout issues the browser detects do not return this poll; they wait in the user's Layout issues inbox until the user queues them, then arrive as an ordinary tag "layout-warnings" prompt. Do not pass --timeout-ms during normal agent use. ${pollExecutionGuidance({ agent })} After applying feedback, run \`lavish-axi poll ${file} --agent-reply "<message for the user>"\` without --timeout-ms to show your response in Lavish Editor and wait for more feedback. If the user ends the session, stop polling and do not reopen it by re-running \`lavish-axi ${file}\` unless the user asks for further review or something genuinely important needs their visual attention - deliver routine updates directly in this conversation instead. When reopening is warranted, run \`lavish-axi ${file} --reopen\`.`
11114
+ next_step: `${selfPaintPrefix}Do not respond to the user just yet. Now you must run \`lavish-axi poll ${file}\`. This command long-polls until the user sends feedback, ends the session, or leaves every review window disconnected past the reconnect grace period, and it stays silent the whole time - that is normal, never kill it. Layout issues the browser detects do not return this poll; they wait in the user's Layout issues inbox until the user queues them, then arrive as an ordinary tag "layout-warnings" prompt. Do not pass --timeout-ms during normal agent use. ${pollExecutionGuidance({ agent })} After applying feedback, run \`lavish-axi poll ${file} --agent-reply "<message for the user>"\` without --timeout-ms to show your response in Lavish Editor and wait for more feedback. If the user ends the session, stop polling and do not reopen it by re-running \`lavish-axi ${file}\` unless the user asks for further review or something genuinely important needs their visual attention - deliver routine updates directly in this conversation instead. When reopening is warranted, run \`lavish-axi ${file} --reopen\`.`
11077
11115
  };
11078
11116
  }
11079
11117
  function createUserEndedOpenOutput({ file, url, networkWarning = void 0 }) {
@@ -11174,11 +11212,11 @@ ${pollInterruptedText(absolute)}
11174
11212
  }
11175
11213
  }
11176
11214
  function pollWaitBannerText(file) {
11177
- return `[lavish-axi] Long-polling for user feedback on ${file}. This stays silent until the user sends feedback or ends the session - leave it running. Detected layout issues do NOT return this poll: they wait in the user's Layout issues inbox until the user queues them as ordinary feedback. If it gets killed or times out before feedback arrives, re-run \`lavish-axi poll ${file}\` - feedback remains queued until delivery. Poll delivery consumes the response, so read it completely.`;
11215
+ return `[lavish-axi] Long-polling for user feedback on ${file}. This stays silent until the user sends feedback, ends the session, or leaves every review window disconnected past the reconnect grace period - leave it running. Detected layout issues do NOT return this poll: they wait in the user's Layout issues inbox until the user queues them as ordinary feedback. If it gets killed or times out before feedback arrives, re-run \`lavish-axi poll ${file}\` - feedback remains queued until delivery. Poll delivery consumes the response, so read it completely.`;
11178
11216
  }
11179
11217
  function pollWaitTickText(elapsedMs) {
11180
11218
  const minutes = Math.round(elapsedMs / 6e4);
11181
- return `[lavish-axi] Still waiting for user feedback (${minutes}m). Leave this running until the user sends feedback or ends the session.`;
11219
+ return `[lavish-axi] Still waiting for user feedback (${minutes}m). Leave this running until the user sends feedback, ends the session, or leaves every review window disconnected.`;
11182
11220
  }
11183
11221
  function pollInterruptedText(file) {
11184
11222
  return `[lavish-axi] Poll interrupted before user feedback arrived. The user may still be reviewing - re-run \`lavish-axi poll ${file}\` to keep waiting; feedback remains queued until delivery. Poll delivery consumes the response, so read it completely.`;
@@ -11232,6 +11270,12 @@ function createPollOutput({ file, response, agent = "generic" }) {
11232
11270
  next_step: createEndedNextStep(file, response.ended_by)
11233
11271
  };
11234
11272
  }
11273
+ if (response.status === "browser_disconnected") {
11274
+ return {
11275
+ session: { file, status: "browser_disconnected" },
11276
+ next_step: "The Lavish review window was closed or disconnected. The session remains open and resumable; ask the user whether they want to reopen it or end the session. Do not reopen or end it without their direction."
11277
+ };
11278
+ }
11235
11279
  return {
11236
11280
  session: { file, status: response.status || "waiting" },
11237
11281
  next_step: `No user feedback arrived before the optional timeout. Run \`lavish-axi poll ${file}\` without --timeout-ms to wait indefinitely - feedback remains queued until delivery, so re-running the poll is safe while waiting. Poll delivery consumes the response, so read it completely.`
@@ -11251,7 +11295,7 @@ function createFeedbackNextStep(file, artifactFailures, sessionEnded, endedBy, p
11251
11295
  return `${failureNote}${layoutNote}${whiteboardNote}${attachmentNote}This was the last feedback before the Lavish Editor session ended. Stop polling ${file}. Deliver any remaining updates directly in this conversation, or run \`lavish-axi ${file}\` to open a fresh session if the user needs further visual review.`;
11252
11296
  }
11253
11297
  const prefix = count > 0 ? artifactFailuresPrefix(file, artifactFailures) : `Apply the requested changes to ${file}. `;
11254
- return `${prefix}${layoutNote}${whiteboardNote}${attachmentNote}Do not respond to the user just yet. Now you must run \`lavish-axi poll ${file} --agent-reply "<message for the user>"\` without --timeout-ms unless the user ended the session. The poll waits silently until the user sends more feedback or ends the session - never kill it. ${pollExecutionGuidance({ agent })}`;
11298
+ return `${prefix}${layoutNote}${whiteboardNote}${attachmentNote}Do not respond to the user just yet. Now you must run \`lavish-axi poll ${file} --agent-reply "<message for the user>"\` without --timeout-ms unless the user ended the session. The poll waits silently until the user sends more feedback, ends the session, or leaves every review window disconnected past the reconnect grace period - never kill it. ${pollExecutionGuidance({ agent })}`;
11255
11299
  }
11256
11300
  function artifactFailuresPrefix(file, artifactFailures) {
11257
11301
  const count = artifactFailures.length;
@@ -12316,7 +12360,7 @@ Usage:
12316
12360
 
12317
12361
  ${DESIGN_SYSTEM_HINT}
12318
12362
 
12319
- Note: poll long-polls indefinitely by default until the user sends feedback or ends the session, staying silent while it waits - never kill it. Layout issues the browser detects are passive: they collect in the user's Layout issues inbox in the Lavish top bar and reach the agent only when the user selects them and queues the fixes, as an ordinary tag "layout-warnings" prompt. Do not pass --timeout-ms during normal agent use; it is for tests and debugging only. ${pollExecutionGuidance({ agent })} ${POLL_SEND_AND_END_RULE}
12363
+ Note: poll long-polls until the user sends feedback, ends the session, or leaves every review window disconnected past the reconnect grace period, staying silent while it waits - never kill it. Layout issues the browser detects are passive: they collect in the user's Layout issues inbox in the Lavish top bar and reach the agent only when the user selects them and queues the fixes, as an ordinary tag "layout-warnings" prompt. Do not pass --timeout-ms during normal agent use; it is for tests and debugging only. ${pollExecutionGuidance({ agent })} ${POLL_SEND_AND_END_RULE}
12320
12364
 
12321
12365
  `;
12322
12366
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavish-axi",
3
- "version": "0.1.66",
3
+ "version": "0.1.67",
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.66",
4
+ "version": "0.1.67",
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",