lavish-axi 0.1.40 → 0.1.41

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
@@ -53,6 +53,7 @@ npx skills add kunchenguid/lavish-axi --skill lavish
53
53
 
54
54
  That is the entire setup - no npm install needed.
55
55
  The skill teaches your agent to run Lavish through `npx -y lavish-axi`, so the CLI comes along on demand.
56
+ In restricted subprocess sandboxes, CI, or agent harnesses where `npx -y` exits opaquely, the skill also documents direct installed-copy fallbacks through the local or global npm install path.
56
57
  Its frontmatter also includes Hermes Agent metadata, so Hermes-compatible harnesses can categorize and surface it as a first-class productivity skill.
57
58
  This installs the public `lavish` skill.
58
59
  The repository also contains an internal `lavish-design` brand skill for maintainers; default `npx skills add ... --list` and skills.sh discovery hide it unless `INSTALL_INTERNAL_SKILLS=1` is set.
@@ -77,7 +78,7 @@ Lavish is an AXI, so any capable agent can run the CLI directly with nothing ins
77
78
  Just tell your agent:
78
79
 
79
80
  ```
80
- Use `npx lavish-axi` to write a product or technical plan for what we discussed.
81
+ Use `npx -y lavish-axi` to write a product or technical plan for what we discussed.
81
82
  ```
82
83
 
83
84
  ### Session hook
@@ -159,8 +160,8 @@ pnpm link
159
160
  - **Keyboard shortcuts** - In the chrome composer, Enter sends queued prompts and Shift+Enter inserts a newline.
160
161
  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.
161
162
  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.
162
- - **Agent presence** - The browser shows when no agent is listening, keeps queued feedback and fresh layout warnings for the next successful `lavish-axi poll` send even across reloads, and only blocks human sends while the agent is working on delivered feedback. The no-timeout poll writes an immediate stderr banner and periodic stderr heartbeats while stdout stays reserved for the final response; if the poll is interrupted or times out, re-run it because queued feedback is never lost.
163
- - **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.
163
+ - **Agent presence** - The browser shows when no agent is listening, keeps queued feedback and fresh layout warnings for the next successful `lavish-axi poll` send even across reloads, and only blocks human sends while the agent is working on delivered feedback. The no-timeout poll writes an immediate stderr banner and periodic stderr heartbeats while stdout stays reserved for the final response; if the poll is interrupted or times out, re-run it because queued feedback is never lost. 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.
164
+ - **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.
164
165
  A plain `lavish-axi <html-file>` after a user-initiated end refuses to reopen the browser and returns guidance instead; pass `--reopen` only when the user asks for further review or something important needs their visual attention.
165
166
  Agent-initiated ends keep reopening normally, same as before.
166
167
  `lavish-axi poll`'s `ended` response and the `feedback` response for the final batch before an end both carry `next_step` guidance telling the agent to stop polling and deliver remaining updates in chat instead of reopening.
@@ -182,20 +183,20 @@ pnpm link
182
183
 
183
184
  ## CLI Reference
184
185
 
185
- | Command | Description |
186
- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
187
- | `lavish-axi` | Show current sessions and usage guidance. |
188
- | `lavish-axi update` | Check for or apply the latest npm release through the AXI SDK self-updater. |
189
- | `lavish-axi <html-file>` | Open or resume a Lavish Editor session, with the open-time layout gate enabled by default. Refuses to reopen a session the user explicitly ended from the browser unless `--reopen` is passed. |
190
- | `lavish-axi poll <html-file>` | Long-poll until the user sends feedback, ends the session, or the browser reports fresh `layout_warnings`; leave no-timeout polls running, or re-run them if interrupted. On `status: ended`, stop polling and do not reopen uninvited. |
191
- | `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. |
192
- | `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. |
193
- | `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, and `--password` makes viewers enter the password before viewing. |
194
- | `lavish-axi stop` | Shut down the background server. |
195
- | `lavish-axi playbook [id]` | List focused artifact guidance or show one playbook; agents must open each matching playbook before writing HTML. |
196
- | `lavish-axi design` | Show agent-facing design guidance, including optional CDN and Mermaid snippets. |
197
- | `lavish-axi setup hooks` | Install or repair optional SessionStart hooks for Claude Code, Codex, OpenCode, and GitHub Copilot CLI; restart the agent session afterward. |
198
- | `lavish-axi server` | Run the local Lavish Editor server. |
186
+ | Command | Description |
187
+ | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
188
+ | `lavish-axi` | Show current sessions and usage guidance. |
189
+ | `lavish-axi update` | Check for or apply the latest npm release through the AXI SDK self-updater. |
190
+ | `lavish-axi <html-file>` | Open or resume a Lavish Editor session, with the open-time layout gate enabled by default. Refuses to reopen a session the user explicitly ended from the browser unless `--reopen` is passed. |
191
+ | `lavish-axi poll <html-file>` | Long-poll until the user sends feedback, ends the session, or the browser reports fresh `layout_warnings`; 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. |
192
+ | `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. |
193
+ | `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. |
194
+ | `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, and `--password` makes viewers enter the password before viewing. |
195
+ | `lavish-axi stop` | Shut down the background server. |
196
+ | `lavish-axi playbook [id]` | List focused artifact guidance or show one playbook; agents must open each matching playbook before writing HTML. |
197
+ | `lavish-axi design` | Show agent-facing design guidance, including optional CDN and Mermaid snippets. |
198
+ | `lavish-axi setup hooks` | Install or repair optional SessionStart hooks for Claude Code, Codex, OpenCode, and GitHub Copilot CLI; restart the agent session afterward. |
199
+ | `lavish-axi server` | Run the local Lavish Editor server. |
199
200
 
200
201
  Known playbook IDs: `diagram`, `table`, `comparison`, `plan`, `code`, `input`, `slides`.
201
202
  One artifact often combines several playbooks, such as a plan that includes a comparison and a diagram, so agents must match against each `use_when` trigger and open every matching playbook before writing HTML.
@@ -938,6 +938,7 @@ async function persistWhiteboardScene(index, message) {
938
938
  headers: { "content-type": "application/json" },
939
939
  body: JSON.stringify({
940
940
  source_hash: String(message.sourceHash || ""),
941
+ text_metrics_version: Number(message.textMetricsVersion) || 0,
941
942
  scene: message.scene || null,
942
943
  baseline: message.baseline || null,
943
944
  }),
package/dist/cli.mjs CHANGED
@@ -5476,10 +5476,11 @@ function whiteboardFeedbackPaths(stateDir2, key, index) {
5476
5476
  previewPath: path3.join(dir, `${Number(index)}.png`)
5477
5477
  };
5478
5478
  }
5479
- async function saveWhiteboard(stateDir2, key, index, { sourceHash, scene, baseline = null }) {
5479
+ async function saveWhiteboard(stateDir2, key, index, { sourceHash, textMetricsVersion = 0, scene, baseline = null }) {
5480
5480
  assertValidRef(key, index);
5481
5481
  const record = {
5482
5482
  source_hash: String(sourceHash || ""),
5483
+ text_metrics_version: Math.max(0, Math.floor(Number(textMetricsVersion) || 0)),
5483
5484
  updated_at: (/* @__PURE__ */ new Date()).toISOString(),
5484
5485
  scene: sanitizeWhiteboardScene(scene),
5485
5486
  baseline: baseline ?? null
@@ -5499,6 +5500,7 @@ async function loadWhiteboard(stateDir2, key, index) {
5499
5500
  if (!parsed || typeof parsed !== "object") return null;
5500
5501
  return {
5501
5502
  source_hash: String(parsed.source_hash || ""),
5503
+ text_metrics_version: Math.max(0, Math.floor(Number(parsed.text_metrics_version) || 0)),
5502
5504
  updated_at: String(parsed.updated_at || ""),
5503
5505
  scene: parsed.scene ?? null,
5504
5506
  baseline: parsed.baseline ?? null
@@ -6330,6 +6332,7 @@ data: ${JSON.stringify({ state: computePresence(req.params.key, activePolls, del
6330
6332
  const body = req.body || {};
6331
6333
  await saveWhiteboard(whiteboardStateRoot, req.params.key, Number(req.params.index), {
6332
6334
  sourceHash: String(body.source_hash || body.sourceHash || ""),
6335
+ textMetricsVersion: Number(body.text_metrics_version || body.textMetricsVersion) || 0,
6333
6336
  scene: body.scene ?? null,
6334
6337
  baseline: body.baseline ?? null
6335
6338
  });
@@ -6937,10 +6940,26 @@ function normalizePagePath(path7) {
6937
6940
  var COMMANDS = /* @__PURE__ */ new Set(["open", "poll", "end", "stop", "server", "playbook", "design", "setup", "export", "share"]);
6938
6941
  var RESERVED = new Set(RESERVED_COMMANDS);
6939
6942
  var DESCRIPTION = "Lavish Editor helps agents turn rich HTML artifacts into collaborative human review surfaces. Whenever you are about to give user a complex response that will be easier to understand via a rich / interactive page, consider using Lavish Editor. First generate an interactive HTML artifact according to user request, then run `lavish-axi <html-file>` so the user can visually review it, annotate elements or selected text, queue prompts, and send feedback back through `lavish-axi poll`.";
6940
- var VERSION = "0.1.40";
6943
+ var POLL_BACKGROUND_TASK_GUIDANCE = "If your agent harness limits how long a foreground command may run, run the poll as a background task";
6944
+ var CODEX_POLL_BACKGROUND_TASK_GUIDANCE = "Codex detected: do not hide the poll in a background task. Completed background tasks may not resume Codex automatically, so keep the poll attached to the active turn.";
6945
+ var VERSION = "0.1.41";
6946
+ function detectInvokingAgent(env = process.env) {
6947
+ return ["CODEX_SANDBOX", "CODEX_THREAD_ID"].some((key) => Object.hasOwn(env, key)) ? "codex" : "generic";
6948
+ }
6949
+ function pollExecutionGuidance({ waitForBackground = false, agent = "generic" } = {}) {
6950
+ if (agent === "codex") {
6951
+ return `${CODEX_POLL_BACKGROUND_TASK_GUIDANCE} If it gets killed or times out anyway, just re-run it - queued feedback is never lost.`;
6952
+ }
6953
+ if (agent === "static") {
6954
+ return "If it gets killed or times out anyway, just re-run it - queued feedback is never lost.";
6955
+ }
6956
+ const backgroundGuidance = `${POLL_BACKGROUND_TASK_GUIDANCE}${waitForBackground ? " and wait for it to finish" : ""}; if it gets killed or times out anyway, just re-run it - queued feedback is never lost.`;
6957
+ return backgroundGuidance;
6958
+ }
6941
6959
  async function run(argv) {
6942
6960
  await ensureStateDir();
6943
6961
  const normalizedArgv = normalizeArgv(argv);
6962
+ const agent = detectInvokingAgent(process.env);
6944
6963
  const isTopLevelHelp = argv.length === 1 && argv[0] === "--help";
6945
6964
  const command = telemetryCommandName(argv);
6946
6965
  const telemetry = initDefaultTelemetry({
@@ -6955,11 +6974,12 @@ async function run(argv) {
6955
6974
  description: DESCRIPTION,
6956
6975
  version: VERSION,
6957
6976
  argv: isTopLevelHelp ? [] : normalizedArgv,
6958
- topLevelHelp: TOP_LEVEL_HELP,
6977
+ topLevelHelp: createTopLevelHelp({ agent }),
6959
6978
  home: async () => createHomeOutput({
6960
6979
  bin: process.argv[1] || "lavish-axi",
6961
6980
  sessions: isTopLevelHelp ? [] : await visibleSessions(),
6962
- includeSessions: !isTopLevelHelp
6981
+ includeSessions: !isTopLevelHelp,
6982
+ agent
6963
6983
  }),
6964
6984
  commands: {
6965
6985
  open: openCommand,
@@ -6973,7 +6993,7 @@ async function run(argv) {
6973
6993
  export: exportCommand,
6974
6994
  share: shareCommand
6975
6995
  },
6976
- getCommandHelp
6996
+ getCommandHelp: (command2) => getCommandHelp(command2, { agent })
6977
6997
  });
6978
6998
  telemetry.track("command", { command, status: "success" });
6979
6999
  } catch (error) {
@@ -7008,7 +7028,7 @@ function telemetryCommandName(argv) {
7008
7028
  const normalized = normalizeArgv(argv);
7009
7029
  return normalized[0] && !normalized[0].startsWith("-") ? normalized[0] : "home";
7010
7030
  }
7011
- function createHomeOutput({ bin, sessions, includeSessions = true }) {
7031
+ function createHomeOutput({ bin, sessions, includeSessions = true, agent = "generic" }) {
7012
7032
  return {
7013
7033
  bin: collapseHomeDirectory(bin, os2.homedir()),
7014
7034
  description: DESCRIPTION,
@@ -7032,7 +7052,7 @@ function createHomeOutput({ bin, sessions, includeSessions = true }) {
7032
7052
  "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",
7033
7053
  "Unless the user specifies another location, create HTML artifacts in the current working directory under `.lavish/`",
7034
7054
  "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",
7035
- "Run `lavish-axi poll <html-file>` to wait for user feedback or browser-reported layout_warnings. It long-polls and stays silent until the user sends feedback, ends the session, or the real browser reports fresh layout_warnings, so leave it running - never kill it. Fix and re-check fresh error-severity layout_warnings before involving the human; if the poll says every current warning is persistent or low-severity, proceed with a note instead of looping. If your harness limits how long a foreground command may run, run the poll as a background task; if it gets killed or times out anyway, just re-run it - queued feedback is never lost. When it reports the session ended, stop polling and do not reopen it uninvited - deliver remaining updates in this conversation instead",
7055
+ `Run \`lavish-axi poll <html-file>\` to wait for user feedback or browser-reported layout_warnings. It long-polls and stays silent until the user sends feedback, ends the session, or the real browser reports fresh layout_warnings, so leave it running - never kill it. Fix and re-check fresh error-severity layout_warnings before involving the human; if the poll says every current warning is persistent or low-severity, proceed with a note instead of looping. ${pollExecutionGuidance({ agent })} When it reports the session ended, stop polling and do not reopen it uninvited - deliver remaining updates in this conversation instead`,
7036
7056
  'Rendered Mermaid diagrams in `.mermaid` containers 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; when a reload detects a changed Mermaid source, the reviewer explicitly chooses 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)',
7037
7057
  "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`",
7038
7058
  "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",
@@ -7060,10 +7080,10 @@ function createPlaybookOutput(args) {
7060
7080
  }
7061
7081
  return { playbook };
7062
7082
  }
7063
- function createOpenOutput({ file, url, status }) {
7083
+ function createOpenOutput({ file, url, status, agent = "generic" }) {
7064
7084
  return {
7065
7085
  session: { file, url, status },
7066
- next_step: `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 the real browser reports layout_warnings from the in-iframe layout audit, and it stays silent the whole time - that is normal, never kill it. If layout_warnings arrive, follow the poll response's next_step: fix and re-check fresh error-severity overflow or clipped-text findings before involving the human, but persistent or low-severity warnings may be surfaced with a note when the cause is not obvious. Do not pass --timeout-ms during normal agent use. If your harness limits how long a foreground command may run, run the poll as a background task and wait for it to finish; if the poll still gets killed or times out, just re-run it - queued feedback is never lost. 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\`.`
7086
+ next_step: `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 the real browser reports layout_warnings from the in-iframe layout audit, and it stays silent the whole time - that is normal, never kill it. If layout_warnings arrive, follow the poll response's next_step: fix and re-check fresh error-severity overflow or clipped-text findings before involving the human, but persistent or low-severity warnings may be surfaced with a note when the cause is not obvious. Do not pass --timeout-ms during normal agent use. ${pollExecutionGuidance({ waitForBackground: true, 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\`.`
7067
7087
  };
7068
7088
  }
7069
7089
  function createUserEndedOpenOutput({ file, url }) {
@@ -7094,7 +7114,12 @@ async function openCommand(args) {
7094
7114
  response.status = "ready";
7095
7115
  }
7096
7116
  }
7097
- return createOpenOutput({ file: absolute, url: response.url, status: response.status || "opened" });
7117
+ return createOpenOutput({
7118
+ file: absolute,
7119
+ url: response.url,
7120
+ status: response.status || "opened",
7121
+ agent: detectInvokingAgent(process.env)
7122
+ });
7098
7123
  }
7099
7124
  function shouldOpenBrowser(args, env) {
7100
7125
  return !args.includes("--no-open") && env.LAVISH_AXI_NO_OPEN !== "1";
@@ -7128,7 +7153,7 @@ ${pollInterruptedText(absolute)}
7128
7153
  retries: 3,
7129
7154
  retryDelayMs: 500
7130
7155
  });
7131
- return createPollOutput({ file: absolute, response });
7156
+ return createPollOutput({ file: absolute, response, agent: detectInvokingAgent(process.env) });
7132
7157
  } finally {
7133
7158
  waitReporter?.stop();
7134
7159
  if (!timeoutMs) {
@@ -7165,7 +7190,7 @@ function startPollWaitReporter({
7165
7190
  timer.unref?.();
7166
7191
  return { stop: () => clearInterval(timer) };
7167
7192
  }
7168
- function createPollOutput({ file, response }) {
7193
+ function createPollOutput({ file, response, agent = "generic" }) {
7169
7194
  if (response.status === "missing") {
7170
7195
  throw new AxiError("No active Lavish Editor session for this file", "NOT_FOUND", [
7171
7196
  `Run \`lavish-axi ${file}\` first`
@@ -7184,7 +7209,7 @@ function createPollOutput({ file, response }) {
7184
7209
  dom_snapshot: response.dom_snapshot || "",
7185
7210
  prompts: response.prompts || [],
7186
7211
  ...layoutWarnings.length > 0 ? { layout_warnings: layoutWarnings } : {},
7187
- next_step: createFeedbackNextStep(file, layoutWarnings, sessionEnded, endedBy, response.prompts || [])
7212
+ next_step: createFeedbackNextStep(file, layoutWarnings, sessionEnded, endedBy, response.prompts || [], agent)
7188
7213
  };
7189
7214
  }
7190
7215
  if (response.status === "ended") {
@@ -7198,7 +7223,7 @@ function createPollOutput({ file, response }) {
7198
7223
  next_step: `No user feedback arrived before the optional timeout. Run \`lavish-axi poll ${file}\` without --timeout-ms to wait indefinitely - queued feedback is never lost, so re-running the poll is always safe.`
7199
7224
  };
7200
7225
  }
7201
- function createFeedbackNextStep(file, layoutWarnings, sessionEnded, endedBy, prompts = []) {
7226
+ function createFeedbackNextStep(file, layoutWarnings, sessionEnded, endedBy, prompts = [], agent = "generic") {
7202
7227
  const count = layoutWarnings.length;
7203
7228
  const whiteboardNote = prompts.some((prompt) => prompt && prompt.tag === "whiteboard") ? `This feedback includes whiteboard edits (tag "whiteboard"): read the edit summary in the prompt text first, and only when it is not enough, open the target's scenePath (.excalidraw scene JSON) or previewPath (PNG) local files for detail. The artifact's Mermaid source stays authoritative - apply the edits by updating the Mermaid text in ${file} (Lavish live-reloads it); never try to write the .excalidraw scene back. ` : "";
7204
7229
  if (sessionEnded) {
@@ -7209,7 +7234,7 @@ function createFeedbackNextStep(file, layoutWarnings, sessionEnded, endedBy, pro
7209
7234
  return `${layoutNote}${whiteboardNote}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.`;
7210
7235
  }
7211
7236
  const layoutPrefix = count > 0 ? layoutWarningsPrefix(file, layoutWarnings) : `Apply the requested changes to ${file}. `;
7212
- return `${layoutPrefix}${whiteboardNote}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 reports fresh layout_warnings - never kill it. If your harness limits how long a foreground command may run, run the poll as a background task; if it still gets killed or times out, just re-run it - queued feedback is never lost.`;
7237
+ return `${layoutPrefix}${whiteboardNote}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 reports fresh layout_warnings - never kill it. ${pollExecutionGuidance({ agent })}`;
7213
7238
  }
7214
7239
  function layoutWarningsPrefix(file, layoutWarnings) {
7215
7240
  const count = layoutWarnings.length;
@@ -7749,10 +7774,11 @@ function isValueFlagToken(arg, flags) {
7749
7774
  function delay(ms) {
7750
7775
  return new Promise((resolve) => setTimeout(resolve, ms));
7751
7776
  }
7752
- function getCommandHelp(command) {
7753
- return COMMAND_HELP[command] || null;
7777
+ function getCommandHelp(command, { agent = "generic" } = {}) {
7778
+ return createCommandHelp({ agent })[command] || null;
7754
7779
  }
7755
- var TOP_LEVEL_HELP = `lavish-axi - Lavish Editor AXI
7780
+ function createTopLevelHelp({ agent = "generic" } = {}) {
7781
+ return `lavish-axi - Lavish Editor AXI
7756
7782
 
7757
7783
  Usage:
7758
7784
  lavish-axi
@@ -7768,35 +7794,37 @@ Usage:
7768
7794
 
7769
7795
  ${DESIGN_SYSTEM_HINT}
7770
7796
 
7771
- Note: poll long-polls indefinitely by default until the user sends feedback, ends the session, or the browser reports fresh layout_warnings, staying silent while it waits - never kill it. Fix and re-check fresh error-severity layout_warnings before involving the human; persistent or low-severity findings may be surfaced with a note when the cause is not obvious. Do not pass --timeout-ms during normal agent use; it is for tests and debugging only. If your harness limits how long a foreground command may run, run the poll as a background task; if it gets killed or times out anyway, just re-run it - queued feedback is never lost. When the user ends a session from the browser, stop polling and do not reopen it uninvited - pass --reopen to <html-file> only when the user asks for further review or something important needs their visual attention.
7797
+ Note: poll long-polls indefinitely by default until the user sends feedback, ends the session, or the browser reports fresh layout_warnings, staying silent while it waits - never kill it. Fix and re-check fresh error-severity layout_warnings before involving the human; persistent or low-severity findings may be surfaced with a note when the cause is not obvious. Do not pass --timeout-ms during normal agent use; it is for tests and debugging only. ${pollExecutionGuidance({ agent })} When the user ends a session from the browser, stop polling and do not reopen it uninvited - pass --reopen to <html-file> only when the user asks for further review or something important needs their visual attention.
7772
7798
 
7773
7799
  `;
7774
- var COMMAND_HELP = {
7775
- open: `Usage: lavish-axi <html-file> [--no-open] [--no-gate] [--reopen]
7800
+ }
7801
+ function createCommandHelp({ agent = "generic" } = {}) {
7802
+ return {
7803
+ open: `Usage: lavish-axi <html-file> [--no-open] [--no-gate] [--reopen]
7776
7804
 
7777
7805
  Open or resume a Lavish Editor review session for an HTML artifact. Use --no-open when you need to ensure the server/session exists without opening another browser window. Use --no-gate to skip the open-time layout curtain for this browser open. If the user explicitly ended the session from the browser, this refuses to reopen it and returns guidance instead - pass --reopen to force it open when the user asks for further review or something important needs their visual attention. Sessions ended by the agent (\`lavish-axi end\`) reopen normally without the flag.
7778
7806
  `,
7779
- poll: `Usage: lavish-axi poll <html-file> [--agent-reply "..."]
7807
+ poll: `Usage: lavish-axi poll <html-file> [--agent-reply "..."]
7780
7808
 
7781
- This command long-polls indefinitely for queued user prompts and browser-reported layout_warnings, then returns them to the agent. It stays silent while it waits - that is normal, never kill it. Fix and re-check fresh error-severity layout_warnings before involving the human; persistent or low-severity findings may be surfaced with a note when the cause is not obvious. Do not pass --timeout-ms during normal agent use; it is for tests and debugging only. If your harness limits how long a foreground command may run, run the poll as a background task and wait for it to finish; if it still gets killed or times out, just re-run it - queued feedback is never lost. Use --agent-reply after applying prior feedback to display your response in Lavish Editor before waiting again. When status is ended, stop polling and do not reopen the session uninvited - deliver remaining updates directly in this conversation instead.
7809
+ This command long-polls indefinitely for queued user prompts and browser-reported layout_warnings, then returns them to the agent. It stays silent while it waits - that is normal, never kill it. Fix and re-check fresh error-severity layout_warnings before involving the human; persistent or low-severity findings may be surfaced with a note when the cause is not obvious. Do not pass --timeout-ms during normal agent use; it is for tests and debugging only. ${pollExecutionGuidance({ waitForBackground: true, agent })} Use --agent-reply after applying prior feedback to display your response in Lavish Editor before waiting again. When status is ended, stop polling and do not reopen the session uninvited - deliver remaining updates directly in this conversation instead.
7782
7810
  `,
7783
- end: `Usage: lavish-axi end <html-file>
7811
+ end: `Usage: lavish-axi end <html-file>
7784
7812
 
7785
7813
  End a Lavish Editor session as the agent. A session ended this way still reopens normally on the next \`lavish-axi <html-file>\`, unlike a user ending it from the browser, which requires --reopen.
7786
7814
  `,
7787
- export: `Usage: lavish-axi export <html-file> [--out <path>]
7815
+ export: `Usage: lavish-axi export <html-file> [--out <path>]
7788
7816
 
7789
7817
  Write a portable copy of an artifact: one HTML file with its LOCAL assets inlined (relative-path stylesheets, scripts, images, and fonts become inline <style>/<script> blocks and data URIs). Remote CDN/font references (https URLs) are left as links for the browser to load, so the file needs network to render those. Lavish makes no outbound requests - it only reads local files, confined to the artifact's directory. Defaults to writing <name>.export.html next to the source; pass --out to choose a path. The Lavish annotation SDK is never included in an export.
7790
7818
  `,
7791
- share: `Usage: lavish-axi share <html-file> [--password <pw>] [--token <t>]
7819
+ share: `Usage: lavish-axi share <html-file> [--password <pw>] [--token <t>]
7792
7820
 
7793
7821
  Publish the artifact on ht-ml.app (https://ht-ml.app), a third-party hosting service not part of Lavish, and print a visitable URL. Shares are PUBLIC by default: anyone with the link can open the page, and it may be indexed or scraped. Pass --password to publish a PRIVATE password-protected page; viewers must supply the password to view. Builds the same local-inlined HTML as 'export' (local assets inlined; remote CDN/font URLs left as links and are not blocked by CSP on ht-ml.app, but still load over the viewer's network), then POSTs it to ht-ml.app's /v1 API. Creating a site needs no account or API key. The response includes the url plus a secret update_key (shown once) for updating or deleting the page later. Set LAVISH_AXI_HTML_APP_TOKEN (or pass --token) to attach an optional bearer token; it is never required. The annotation SDK is never included.
7794
7822
  `,
7795
- stop: `Usage: lavish-axi stop [--port <port>]
7823
+ stop: `Usage: lavish-axi stop [--port <port>]
7796
7824
 
7797
7825
  Shut down the background Lavish Editor server. The server also stops itself when no browser or poll has been connected for a while (LAVISH_AXI_IDLE_TIMEOUT_MS, default 30m) and immediately when the last session ends with nothing connected.
7798
7826
  `,
7799
- playbook: `Usage: lavish-axi playbook [playbook_id]
7827
+ playbook: `Usage: lavish-axi playbook [playbook_id]
7800
7828
 
7801
7829
  List focused artifact guidance playbooks, or show one playbook by ID. Known IDs: diagram, table, comparison, plan, code, input, slides.
7802
7830
 
@@ -7807,21 +7835,22 @@ Examples:
7807
7835
  lavish-axi playbook diagram
7808
7836
  lavish-axi playbook input
7809
7837
  `,
7810
- design: `Usage: lavish-axi design
7838
+ design: `Usage: lavish-axi design
7811
7839
 
7812
7840
  Show a copy-pasteable CDN snippet for Tailwind CSS browser runtime v4 + DaisyUI v5 + themes, Mermaid diagram tooling, a content-to-playbook router, an optional layout safety CSS snippet, plus technical reference for DaisyUI components. ${PLAYBOOK_ROUTER_HELP} Lavish artifacts stay portable HTML. This CDN snippet is the design fallback, not the default: inspect the subject project before falling back, and paste the layout safety CSS only when useful for dense nested grid/flex layouts, badges, wide fonts, or local media. ${DESIGN_PRIORITY_RULE}
7813
7841
  `,
7814
- setup: `Usage: lavish-axi setup hooks
7842
+ setup: `Usage: lavish-axi setup hooks
7815
7843
 
7816
7844
  Install or repair agent SessionStart hooks for lavish-axi ambient context in Claude Code, Codex, OpenCode, and GitHub Copilot CLI. Restart your agent session afterward to receive the context.
7817
7845
  `,
7818
- server: `Usage: lavish-axi server [--port 4387] [--verbose]
7846
+ server: `Usage: lavish-axi server [--port 4387] [--verbose]
7819
7847
 
7820
7848
  Run the local Lavish Editor server. Pass --verbose (or set LAVISH_AXI_DEBUG=1) to log session and watcher events to stderr. Detached server output is appended to ~/.lavish-axi/server.log, or LAVISH_AXI_STATE_DIR/server.log when set, for startup and crash diagnostics.
7821
7849
 
7822
7850
  LAVISH_AXI_HOST sets the bind address (default 127.0.0.1; a wildcard 0.0.0.0 or :: binds every interface). Binding beyond loopback exposes an unauthenticated server that can read and serve arbitrary local files to anything that can reach it, so only do so on a trusted network. LAVISH_AXI_LINK_HOST sets the hostname written into generated session links (default: the bind address, or loopback when bound to a wildcard). LAVISH_AXI_NO_OPEN=1 (or --no-open) suppresses the local browser launch.
7823
7851
  `
7824
- };
7852
+ };
7853
+ }
7825
7854
 
7826
7855
  // bin/lavish-axi.js
7827
7856
  await run(process.argv.slice(2));