lavish-axi 0.1.23 → 0.1.25

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
@@ -40,76 +40,67 @@ Lavish Editor opens agent-generated HTML files in a local browser, lets you pinp
40
40
  Lavish Editor is an [AXI](https://axi.md), which means -
41
41
 
42
42
  - It's just a CLI any capable agent can run without setup.
43
- - No skills required. Agents learn to use AXIs by using them.
44
43
  - It's optimized for agent ergonomics. TOON output, long polling, and contextual disclosure making it highly token efficient.
44
+ - The skill and hooks below only handle discovery; agents learn to use the AXI by using it.
45
45
 
46
46
  ## Quick Start
47
47
 
48
- Just tell your agent:
48
+ Install the Lavish skill in the [Agent Skills](https://agentskills.io) format with [`npx skills`](https://github.com/vercel-labs/skills):
49
49
 
50
50
  ```sh
51
- Use `npx lavish-axi` to write a product or technical plan for what we discussed.
51
+ npx skills add kunchenguid/lavish-axi --skill lavish
52
52
  ```
53
53
 
54
- That works with zero setup - Lavish is an AXI, so any capable agent can run the CLI directly.
54
+ That is the entire setup - no npm install needed.
55
+ The skill teaches your agent to run Lavish through `npx -y lavish-axi`, so the CLI comes along on demand.
55
56
 
56
- To make your agent reach for Lavish on its own (without you naming it every time), install the agent hooks as instructed below.
57
+ Then, in agents that expose skills as slash commands (Claude Code, for example), invoke it directly:
57
58
 
58
- ## Install
59
+ ```
60
+ /lavish let's discuss our plan here
61
+ ```
59
62
 
60
- **npm**
63
+ Or just ask for anything that is easier to grasp visually - a plan, comparison, diagram, table, diff, or report - and the agent loads the skill on its own when it recognizes the task.
61
64
 
62
- ```sh
63
- npm install -g lavish-axi
64
- ```
65
+ By default the skill lands in the current project's skills directory (`.claude/skills/`, for example); add `-g` to install it for all projects (`~/.claude/skills/`).
65
66
 
66
- **From source**
67
+ ## Other Ways to Use Lavish
67
68
 
68
- ```sh
69
- git clone https://github.com/kunchenguid/lavish-axi.git
70
- cd lavish-axi
71
- pnpm install --frozen-lockfile
72
- pnpm run build
73
- pnpm link
74
- ```
69
+ The skill is the recommended path, but it is not the only one.
70
+
71
+ ### Zero setup
75
72
 
76
- ## Teach Your Agent About Lavish (recommended)
73
+ Lavish is an AXI, so any capable agent can run the CLI directly with nothing installed at all.
74
+ Just tell your agent:
77
75
 
78
- Lavish does not wire itself into your agent automatically, so in a fresh session your agent would not know to use it.
79
- There are two ways to fix that - **you only need one.**
80
- We recommend the hook.
76
+ ```
77
+ Use `npx lavish-axi` to write a product or technical plan for what we discussed.
78
+ ```
81
79
 
82
- ### Option A: Session hook (recommended)
80
+ ### Session hook
83
81
 
84
- Run this once to opt in:
82
+ Want Lavish's ambient context - including your live open sessions - fed into every agent session instead of loading on demand?
83
+ Install the CLI globally and opt into the hook:
85
84
 
86
85
  ```sh
86
+ npm install -g lavish-axi
87
87
  lavish-axi setup hooks
88
88
  ```
89
89
 
90
- This installs a `SessionStart` hook for **Claude Code**, **Codex**, and **OpenCode** that feeds Lavish's ambient context (open sessions, visualization playbooks, and usage guidance) into your agent at the start of each session.
91
- With the hook installed, your agent learns to turn complex responses into rich, reviewable HTML artifacts proactively - no need to mention `lavish-axi` by name.
92
-
90
+ This installs a `SessionStart` hook for **Claude Code**, **Codex**, and **OpenCode** that surfaces open sessions, visualization playbooks, and usage guidance at the start of each session.
91
+ Unlike the skill, the hook also shows your live open sessions, so a fresh agent session can resume an in-flight review.
93
92
  **Restart your agent session after running this** so the new hook takes effect.
94
93
 
95
- ### Option B: Install as a skill
96
-
97
- Prefer the [Agent Skills](https://agentskills.io) format, or use an agent that supports it?
98
- Install Lavish as a skill with [`npx skills`](https://github.com/vercel-labs/skills):
94
+ ### From source
99
95
 
100
96
  ```sh
101
- npx skills add kunchenguid/lavish-axi --skill lavish
97
+ git clone https://github.com/kunchenguid/lavish-axi.git
98
+ cd lavish-axi
99
+ pnpm install --frozen-lockfile
100
+ pnpm run build
101
+ pnpm link
102
102
  ```
103
103
 
104
- This drops a `lavish` skill into your agent's skills directory (`.claude/skills/` for example; add `-g` for `~/.claude/skills/`).
105
- The skill carries the same guidance the hook delivers, but it loads on demand when the agent recognizes a task that calls for a visual artifact, rather than every session.
106
- In agents that expose skills as slash commands (Claude Code, for example), you can also invoke it explicitly with `/lavish <what the artifact should show>`.
107
- It does not surface your live open sessions - run `lavish-axi setup hooks` if you want that ambient context too.
108
-
109
- ### No setup at all
110
-
111
- Lavish also works fully as a plain CLI - just tell your agent to `npx lavish-axi <file.html>` as shown in the Quick Start.
112
-
113
104
  ## How It Works
114
105
 
115
106
  ```
@@ -136,13 +127,15 @@ Lavish also works fully as a plain CLI - just tell your agent to `npx lavish-axi
136
127
  ```
137
128
 
138
129
  - **File-path identity** - Sessions are keyed by the canonical HTML file path, so agents do not need opaque IDs.
139
- - **Portable artifacts** - The artifact runs in an iframe while Lavish injects a small SDK for annotations, snapshots, and feedback controls. Lavish does not inject any design system, so the saved HTML file renders identically whether you open it through `lavish-axi` or directly in a browser. Choose a design system in priority order: follow a user-requested look first, match the current project's design system or conventions next, and otherwise run `lavish-axi design` for a copy-pasteable Tailwind CSS v4 + DaisyUI v5 CDN fallback.
130
+ - **Portable artifacts** - The artifact runs in an iframe while Lavish injects a small SDK for annotations, snapshots, and feedback controls. Lavish does not inject any design system, so the saved HTML file renders identically whether you open it through `lavish-axi` or directly in a browser. Before writing HTML, choose a design system in strict priority order: follow a user-requested look first; otherwise inspect the current project for a Tailwind or theme config, CSS variables or design tokens, a component library, brand assets, or existing styled pages and match what you find; only when both come up empty, run `lavish-axi design` for a copy-pasteable Tailwind CSS v4 + DaisyUI v5 CDN fallback.
140
131
  - **Local assets** - Copy local images, CSS, fonts, and scripts next to the HTML artifact and reference them with relative paths from that directory; root-prefixed paths such as `/assets/logo.png` will not resolve through Lavish's artifact route.
141
132
  - **Live reload** - Lavish watches the HTML artifact file by default and preserves the artifact iframe scroll position across reloads. To also reload on sibling asset changes, add `data-lavish-live-reload-root` to the root element or `<meta name="lavish-live-reload" content="root">`.
142
133
  - **Feedback controls** - Native form controls (radios, checkboxes, inputs, selects, buttons, labels, contenteditable) are interactive automatically, so they do not need `data-lavish-action`; wire their handlers to `window.lavish.queuePrompt()` or `window.lavish.sendQueuedPrompts()` to send feedback.
143
134
  Mark only custom (non-native) clickable elements with `data-lavish-action` so Lavish does not annotate them.
144
135
  The browser chrome keeps editing actions in the overflow menu (copy path, reload artifact, copy DOM snapshot, end session) and can submit queued prompts with **Send & end session**, which delivers the prompts before ending the session.
145
- - **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 only blocks sending while the agent is working on delivered feedback.
136
+ - **Keyboard shortcuts** - In the chrome composer, Enter sends queued prompts and Shift+Enter inserts a newline.
137
+ 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.
138
+ - **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 only blocks sending 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.
146
139
  - **Precise targets** - Text annotations include selected text plus range anchors, so agents are not limited to whole-element selectors.
147
140
  - **Server cleanup** - The detached server stops after the last session ends when nothing is connected, or after `LAVISH_AXI_IDLE_TIMEOUT_MS` (default 30 minutes) with no browser or poll connections.
148
141
  Set `LAVISH_AXI_IDLE_TIMEOUT_MS=0` or `off` to disable idle self-shutdown.
@@ -150,19 +143,20 @@ Lavish also works fully as a plain CLI - just tell your agent to `npx lavish-axi
150
143
 
151
144
  ## CLI Reference
152
145
 
153
- | Command | Description |
154
- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
155
- | `lavish-axi` | Show current sessions and usage guidance. |
156
- | `lavish-axi <html-file>` | Open or resume a Lavish Editor session. |
157
- | `lavish-axi poll <html-file>` | Long-poll until the user sends feedback or ends the session. |
158
- | `lavish-axi end <html-file>` | End a session. |
159
- | `lavish-axi stop` | Shut down the background server. |
160
- | `lavish-axi playbook [id]` | List focused artifact guidance or show one playbook. |
161
- | `lavish-axi design` | Show CDN snippet + DaisyUI component reference (opt-in). |
162
- | `lavish-axi setup hooks` | Install or repair optional SessionStart hooks for Claude Code, Codex, and OpenCode; restart the agent session afterward. |
163
- | `lavish-axi server` | Run the local Lavish Editor server. |
146
+ | Command | Description |
147
+ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
148
+ | `lavish-axi` | Show current sessions and usage guidance. |
149
+ | `lavish-axi <html-file>` | Open or resume a Lavish Editor session. |
150
+ | `lavish-axi poll <html-file>` | Long-poll until the user sends feedback or ends the session; leave no-timeout polls running, or re-run them if interrupted. |
151
+ | `lavish-axi end <html-file>` | End a session. |
152
+ | `lavish-axi stop` | Shut down the background server. |
153
+ | `lavish-axi playbook [id]` | List focused artifact guidance or show one playbook. |
154
+ | `lavish-axi design` | Show the Tailwind + DaisyUI CDN fallback after user and project design sources come up empty. |
155
+ | `lavish-axi setup hooks` | Install or repair optional SessionStart hooks for Claude Code, Codex, and OpenCode; restart the agent session afterward. |
156
+ | `lavish-axi server` | Run the local Lavish Editor server. |
164
157
 
165
158
  Known playbook IDs: `diagram`, `table`, `comparison`, `plan`, `diff`, `input`, `slides`.
159
+ One artifact often combines several playbooks, such as a plan that includes a comparison and a diagram, so read every playbook relevant to the artifact for the best quality.
166
160
 
167
161
  ### Flags
168
162
 
@@ -170,7 +164,7 @@ Known playbook IDs: `diagram`, `table`, `comparison`, `plan`, `diff`, `input`, `
170
164
  | ------------------------ | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
171
165
  | `lavish-axi <html-file>` | `--no-open` | Ensure the server/session exists without opening another browser window. |
172
166
  | `lavish-axi poll` | `--agent-reply "..."` | Show the agent's reply in the existing browser chat before polling again. |
173
- | `lavish-axi poll` | `--timeout-ms <ms>` | Test/debug escape hatch only; agents should normally omit it. |
167
+ | `lavish-axi poll` | `--timeout-ms <ms>` | Test/debug escape hatch only; agents should normally omit it and leave the long poll running. |
174
168
  | `lavish-axi stop` | `--port <port>` | Shut down a server running on a non-default port. |
175
169
  | `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 to `~/.lavish-axi/server.log` (or `LAVISH_AXI_STATE_DIR/server.log`) for startup and crash diagnostics. |
176
170
 
package/dist/cli.mjs CHANGED
@@ -20,7 +20,7 @@ var DESIGN_CDN_URLS = {
20
20
  var DESIGN_CDN_SNIPPET = `<link rel="stylesheet" href="${DESIGN_CDN_URLS.daisyui}">
21
21
  <link rel="stylesheet" href="${DESIGN_CDN_URLS.daisyuiThemes}">
22
22
  <script src="${DESIGN_CDN_URLS.tailwind}"></script>`;
23
- var DESIGN_SYSTEM_HINT = "Lavish does not auto-inject any design system - artifacts stay portable so they render identically when opened directly without lavish-axi running. Choose a design system in this priority order: (1) if the user asked for a specific look or named design system, follow that; (2) otherwise, if the current project already has a design system or style conventions, match those so the artifact fits in; (3) otherwise, prefer the Lavish-recommended Tailwind CSS browser runtime v4 + DaisyUI v5, available via CDN - run `lavish-axi design` for a copy-pasteable CDN snippet plus component reference. Prefer that CDN snippet over hand-writing styles unless explicitly instructed otherwise by the user.";
23
+ var DESIGN_SYSTEM_HINT = "Lavish does not auto-inject any design system - artifacts stay portable so they render identically when opened directly without lavish-axi running. Before writing any HTML, decide the design direction in this strict priority order, and only move to the next step when the current one truly yields nothing: (1) if the user asked for a specific look or named design system, use that; (2) otherwise you must first inspect the current project for design conventions - look for a Tailwind or theme config, shared CSS variables or design tokens, a component library, brand assets, or existing styled pages - and match what you find so the artifact fits in; (3) only when both steps come up empty, use the Lavish-recommended Tailwind CSS browser runtime v4 + DaisyUI v5, available via CDN - run `lavish-axi design` for a copy-pasteable CDN snippet plus component reference, and prefer that CDN snippet over hand-writing styles unless explicitly instructed otherwise by the user. When you deliver the artifact, state which of the three design sources you used and why.";
24
24
  var DAISYUI_THEMES = [
25
25
  "light",
26
26
  "dark",
@@ -61,7 +61,7 @@ var DAISYUI_THEMES = [
61
61
  function createDesignOutput() {
62
62
  return {
63
63
  design: {
64
- summary: "Lavish does not auto-inject any design system. Artifacts stay portable HTML. Choose a design system in this priority order: (1) if the user asked for a specific look or named design system, follow that; (2) otherwise, if the current project already ships a design system or style conventions, match those; (3) otherwise, prefer the Lavish-recommended Tailwind CSS browser runtime v4 + DaisyUI v5 + themes - paste the CDN snippet below into your `<head>`. Prefer this CDN snippet over hand-writing styles unless explicitly instructed otherwise by the user.",
64
+ summary: "Use this Lavish CDN fallback only if (1) the user gave no design direction and (2) you already inspected the current project and found no design system or style conventions to match. If you have not checked the project yet, check first. Lavish does not auto-inject any design system; artifacts stay portable HTML. The strict priority order is: (1) a look or named design system the user asked for; (2) the current project's design system or style conventions - look for a Tailwind or theme config, shared CSS variables or design tokens, a component library, brand assets, or existing styled pages; (3) this Tailwind CSS browser runtime v4 + DaisyUI v5 + themes snippet - paste the CDN snippet below into your `<head>` and prefer the CDN snippet over hand-writing styles unless explicitly instructed otherwise by the user.",
65
65
  cdn_snippet: DESIGN_CDN_SNIPPET,
66
66
  cdn_urls: DESIGN_CDN_URLS,
67
67
  versions: { tailwind: TAILWIND_BROWSER_VERSION, daisyui: DAISYUI_VERSION },
@@ -889,7 +889,7 @@ function createArtifactSdk() {
889
889
  document.documentElement.appendChild(host);
890
890
  shadow = host.attachShadow({ mode: "open" });
891
891
  const style = document.createElement("style");
892
- style.textContent = `:host{all:initial;position:fixed;z-index:2147483647;left:0;top:0;color-scheme:dark;--ink-900:#0f1115;--ink-800:#11141a;--ink-700:#171a21;--ink-600:#1c212b;--steel-700:#2a2f3a;--steel-600:#303745;--steel-500:#3c4557;--steel-400:#8c96aa;--steel-300:#aeb6c6;--steel-200:#b9c0cf;--steel-100:#d8deea;--cream-50:#fffbf3;--cream-100:#f7f3ea;--cream-200:#e8e1cf;--brass-500:#f4c95d;--brass-400:#ffd877;--brass-ink:#17130a;--bg:var(--ink-900);--bg-panel:var(--ink-800);--bg-elevated:var(--ink-600);--fg:var(--cream-100);--fg-faint:var(--steel-300);--border:var(--steel-600);--accent:#f4c95d;--accent-hover:#ffd877;--font-sans:Geist,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;--font-mono:"Geist Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;--radius-md:10px;--radius-xl:14px;--shadow-floating:0 20px 70px rgba(0,0,0,.35);font-family:var(--font-sans)}*{box-sizing:border-box}:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.lavish-text-highlight{position:fixed;pointer-events:none;background:rgba(244,201,93,.28);border-radius:2px;box-shadow:0 0 0 1px rgba(244,201,93,.45)}.lavish-annotation-card{position:fixed;width:min(320px,calc(100vw - 24px));padding:12px;border-radius:var(--radius-xl);background:var(--bg-panel);color:var(--fg);border:1px solid var(--accent);box-shadow:var(--shadow-floating);font:14px/1.4 var(--font-sans)}.lavish-heading{font-weight:700;margin-bottom:6px}.lavish-annotation-card textarea{width:100%;min-height:86px;resize:vertical;border-radius:var(--radius-md);border:1px solid var(--border);background:var(--bg);color:var(--fg);padding:9px;font:inherit;font-family:var(--font-sans)}.lavish-annotation-card textarea::placeholder{color:var(--fg-faint)}.lavish-annotation-card .lavish-row{display:flex;gap:8px;justify-content:flex-end;margin-top:8px}.lavish-annotation-card button{border:0;border-radius:var(--radius-md);padding:8px 10px;font-family:var(--font-sans);font-size:13px;font-weight:700;cursor:pointer}.lavish-annotation-card button:active{opacity:.85}.lavish-annotation-card .lavish-send{background:var(--accent);color:var(--brass-ink)}.lavish-annotation-card .lavish-send:hover{background:var(--accent-hover)}.lavish-annotation-card .lavish-cancel{background:var(--steel-700);color:var(--fg)}`;
892
+ style.textContent = `:host{all:initial;position:fixed;z-index:2147483647;left:0;top:0;color-scheme:dark;--ink-900:#0f1115;--ink-800:#11141a;--ink-700:#171a21;--ink-600:#1c212b;--steel-700:#2a2f3a;--steel-600:#303745;--steel-500:#3c4557;--steel-400:#8c96aa;--steel-300:#aeb6c6;--steel-200:#b9c0cf;--steel-100:#d8deea;--cream-50:#fffbf3;--cream-100:#f7f3ea;--cream-200:#e8e1cf;--brass-500:#f4c95d;--brass-400:#ffd877;--brass-ink:#17130a;--bg:var(--ink-900);--bg-panel:var(--ink-800);--bg-elevated:var(--ink-600);--fg:var(--cream-100);--fg-faint:var(--steel-300);--border:var(--steel-600);--accent:#f4c95d;--accent-hover:#ffd877;--font-sans:Geist,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;--font-mono:"Geist Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;--radius-md:10px;--radius-xl:14px;--shadow-floating:0 20px 70px rgba(0,0,0,.35);font-family:var(--font-sans)}*{box-sizing:border-box}:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.lavish-text-highlight{position:fixed;pointer-events:none;background:rgba(244,201,93,.28);border-radius:2px;box-shadow:0 0 0 1px rgba(244,201,93,.45)}.lavish-annotation-card{position:fixed;width:min(320px,calc(100vw - 24px));padding:12px;border-radius:var(--radius-xl);background:var(--bg-panel);color:var(--fg);border:1px solid var(--accent);box-shadow:var(--shadow-floating);font:14px/1.4 var(--font-sans)}.lavish-heading{font-weight:700;margin-bottom:6px}.lavish-annotation-card textarea{width:100%;min-height:86px;resize:vertical;border-radius:var(--radius-md);border:1px solid var(--border);background:var(--bg);color:var(--fg);padding:9px;font:inherit;font-family:var(--font-sans)}.lavish-annotation-card textarea::placeholder{color:var(--fg-faint)}.lavish-annotation-card .lavish-hint{margin-top:6px;font-size:11px;color:var(--fg-faint)}.lavish-annotation-card .lavish-row{display:flex;gap:8px;justify-content:flex-end;margin-top:8px}.lavish-annotation-card button{border:0;border-radius:var(--radius-md);padding:8px 10px;font-family:var(--font-sans);font-size:13px;font-weight:700;cursor:pointer}.lavish-annotation-card button:active{opacity:.85}.lavish-annotation-card .lavish-send{background:var(--accent);color:var(--brass-ink)}.lavish-annotation-card .lavish-send:hover{background:var(--accent-hover)}.lavish-annotation-card .lavish-cancel{background:var(--steel-700);color:var(--fg)}`;
893
893
  shadow.appendChild(style);
894
894
  return shadow;
895
895
  }
@@ -918,7 +918,7 @@ function createArtifactSdk() {
918
918
  card.className = "lavish-annotation-card";
919
919
  const heading = c.tag === "text" ? "Annotate text" : "Annotate &lt;" + c.tag + "&gt;";
920
920
  const placeholder = c.tag === "text" ? "Tell the agent what to change about this text..." : "Tell the agent what to change about this element...";
921
- card.innerHTML = '<div class="lavish-heading">' + heading + '</div><textarea placeholder="' + placeholder + '"></textarea><div class="lavish-row"><button class="lavish-cancel" type="button">Cancel</button><button class="lavish-send" type="button">Queue</button></div>';
921
+ card.innerHTML = '<div class="lavish-heading">' + heading + '</div><textarea placeholder="' + placeholder + '"></textarea><div class="lavish-hint">Enter to queue &middot; ' + (/Mac|iP(hone|ad|od)/.test(navigator.platform) ? "\u2318" : "Ctrl") + '+Enter to send now</div><div class="lavish-row"><button class="lavish-cancel" type="button">Cancel</button><button class="lavish-send" type="button">Queue</button></div>';
922
922
  root.appendChild(card);
923
923
  const left = Math.min(Math.max(12, rect.left), window.innerWidth - card.offsetWidth - 12);
924
924
  const top = Math.min(Math.max(12, rect.bottom + 8), window.innerHeight - card.offsetHeight - 12);
@@ -946,7 +946,9 @@ function createArtifactSdk() {
946
946
  textarea.addEventListener("keydown", (event) => {
947
947
  if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
948
948
  event.preventDefault();
949
+ const sendNow = (event.ctrlKey || event.metaKey) && !!textarea.value.trim();
949
950
  sendButton.click();
951
+ if (sendNow) sendQueuedPrompts();
950
952
  }
951
953
  });
952
954
  setTimeout(() => textarea.focus(), 0);
@@ -1944,7 +1946,7 @@ function normalizePagePath(path5) {
1944
1946
  // src/cli.js
1945
1947
  var COMMANDS = /* @__PURE__ */ new Set(["open", "poll", "end", "stop", "server", "playbook", "design", "setup"]);
1946
1948
  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`.";
1947
- var VERSION = "0.1.23";
1949
+ var VERSION = "0.1.25";
1948
1950
  async function run(argv) {
1949
1951
  await ensureStateDir();
1950
1952
  const normalizedArgv = normalizeArgv(argv);
@@ -2036,10 +2038,10 @@ function createHomeOutput({ bin, sessions, includeSessions = true }) {
2036
2038
  "Run `lavish-axi <html-file>` to open or resume a Lavish Editor session",
2037
2039
  "Unless the user specifies another location, create HTML artifacts in the current working directory under `.lavish/`",
2038
2040
  "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",
2039
- "Run `lavish-axi poll <html-file>` to wait for user feedback",
2041
+ "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. 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",
2040
2042
  "Run `lavish-axi end <html-file>` to end a session",
2041
2043
  "Run `lavish-axi stop` to shut down the background server (it also self-stops when idle or after the last session ends with nothing connected)",
2042
- "Run `lavish-axi playbook <playbook_id>` for focused artifact guidance",
2044
+ "Run `lavish-axi playbook <playbook_id>` for focused artifact guidance. One artifact often combines several playbooks (for example a plan that includes a comparison and a diagram), so read every playbook relevant to the artifact, not just one, for the best quality",
2043
2045
  DESIGN_SYSTEM_HINT,
2044
2046
  "Use lavish-axi when the user asks for a visual artifact, HTML explainer, interactive prototype, review surface, product or technical plan, comparison, report, or browser-based feedback loop"
2045
2047
  ]
@@ -2050,7 +2052,10 @@ function createPlaybookOutput(args) {
2050
2052
  if (!id) {
2051
2053
  return {
2052
2054
  playbooks: listPlaybooks(),
2053
- help: ["Run `lavish-axi playbook <playbook_id>` for focused artifact guidance"]
2055
+ help: [
2056
+ "Run `lavish-axi playbook <playbook_id>` for focused artifact guidance",
2057
+ "One artifact often combines several playbooks (for example a plan that includes a comparison and a diagram), so read every playbook relevant to the artifact, not just one, for the best quality"
2058
+ ]
2054
2059
  };
2055
2060
  }
2056
2061
  const playbook = findPlaybook(id);
@@ -2064,7 +2069,7 @@ function createPlaybookOutput(args) {
2064
2069
  function createOpenOutput({ file, url, status }) {
2065
2070
  return {
2066
2071
  session: { file, url, status },
2067
- 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 or ends the session. Do not pass --timeout-ms during normal agent use. Do not set a short shell timeout; either run it without a timeout or set the shell timeout above 10 minutes. 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.`
2072
+ 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 or ends the session, and it stays silent the whole time - that is normal, never kill it. 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.`
2068
2073
  };
2069
2074
  }
2070
2075
  async function openCommand(args) {
@@ -2102,11 +2107,58 @@ async function pollCommand(args) {
2102
2107
  }
2103
2108
  const timeoutMs = flagValue(args, "--timeout-ms");
2104
2109
  const timeoutQuery = timeoutMs ? `&timeoutMs=${encodeURIComponent(timeoutMs)}` : "";
2105
- const response = await fetchJson(`${baseUrl}/api/poll?file=${encodeURIComponent(absolute)}${timeoutQuery}`, {
2106
- retries: 3,
2107
- retryDelayMs: 500
2108
- });
2109
- return createPollOutput({ file: absolute, response });
2110
+ const waitReporter = timeoutMs ? null : startPollWaitReporter({ file: absolute });
2111
+ const onPollSignal = (signal) => {
2112
+ process.stderr.write(`
2113
+ ${pollInterruptedText(absolute)}
2114
+ `);
2115
+ process.exit(signal === "SIGINT" ? 130 : 143);
2116
+ };
2117
+ if (!timeoutMs) {
2118
+ process.on("SIGINT", onPollSignal);
2119
+ process.on("SIGTERM", onPollSignal);
2120
+ }
2121
+ try {
2122
+ const response = await fetchJson(`${baseUrl}/api/poll?file=${encodeURIComponent(absolute)}${timeoutQuery}`, {
2123
+ retries: 3,
2124
+ retryDelayMs: 500
2125
+ });
2126
+ return createPollOutput({ file: absolute, response });
2127
+ } finally {
2128
+ waitReporter?.stop();
2129
+ if (!timeoutMs) {
2130
+ process.off("SIGINT", onPollSignal);
2131
+ process.off("SIGTERM", onPollSignal);
2132
+ }
2133
+ }
2134
+ }
2135
+ function pollWaitBannerText(file) {
2136
+ 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. If it gets killed or times out, re-run \`lavish-axi poll ${file}\` - queued feedback is never lost.`;
2137
+ }
2138
+ function pollWaitTickText(elapsedMs) {
2139
+ const minutes = Math.round(elapsedMs / 6e4);
2140
+ return `[lavish-axi] Still waiting for user feedback (${minutes}m). Leave this running until the user acts.`;
2141
+ }
2142
+ function pollInterruptedText(file) {
2143
+ return `[lavish-axi] Poll interrupted before user feedback arrived. The user may still be reviewing - re-run \`lavish-axi poll ${file}\` to keep waiting; queued feedback is never lost.`;
2144
+ }
2145
+ function startPollWaitReporter({
2146
+ file,
2147
+ write = (line) => {
2148
+ process.stderr.write(line);
2149
+ },
2150
+ intervalMs = 6e4
2151
+ }) {
2152
+ write(`${pollWaitBannerText(file)}
2153
+ `);
2154
+ let elapsedMs = 0;
2155
+ const timer = setInterval(() => {
2156
+ elapsedMs += intervalMs;
2157
+ write(`${pollWaitTickText(elapsedMs)}
2158
+ `);
2159
+ }, intervalMs);
2160
+ timer.unref?.();
2161
+ return { stop: () => clearInterval(timer) };
2110
2162
  }
2111
2163
  function createPollOutput({ file, response }) {
2112
2164
  if (response.status === "missing") {
@@ -2119,7 +2171,7 @@ function createPollOutput({ file, response }) {
2119
2171
  session: { file, status: "feedback" },
2120
2172
  dom_snapshot: response.dom_snapshot || "",
2121
2173
  prompts: response.prompts || [],
2122
- next_step: `Apply the requested changes to ${file}. 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 command waits until the user sends more feedback or ends the session; do not set a short shell timeout, or set the shell timeout above 10 minutes.`
2174
+ next_step: `Apply the requested changes to ${file}. 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. 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.`
2123
2175
  };
2124
2176
  }
2125
2177
  if (response.status === "ended") {
@@ -2127,7 +2179,7 @@ function createPollOutput({ file, response }) {
2127
2179
  }
2128
2180
  return {
2129
2181
  session: { file, status: response.status || "waiting" },
2130
- next_step: `No user feedback arrived before the optional timeout. Run \`lavish-axi poll ${file}\` without --timeout-ms to wait indefinitely.`
2182
+ 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.`
2131
2183
  };
2132
2184
  }
2133
2185
  async function endCommand(args) {
@@ -2448,7 +2500,7 @@ Usage:
2448
2500
 
2449
2501
  ${DESIGN_SYSTEM_HINT}
2450
2502
 
2451
- Note: poll long-polls indefinitely by default until the user sends feedback or ends the session. Do not pass --timeout-ms during normal agent use; it is for tests and debugging only. do not set a short shell timeout; either run it without a timeout or use a very high threshold above 10 minutes.
2503
+ Note: poll long-polls indefinitely by default until the user sends feedback or ends the session, staying silent while it waits - never kill it. 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.
2452
2504
 
2453
2505
  `;
2454
2506
  var COMMAND_HELP = {
@@ -2458,7 +2510,7 @@ Open or resume a Lavish Editor review session for an HTML artifact. Use --no-ope
2458
2510
  `,
2459
2511
  poll: `Usage: lavish-axi poll <html-file> [--agent-reply "..."]
2460
2512
 
2461
- This command long-polls indefinitely for queued user prompts, then returns them to the agent. Do not pass --timeout-ms during normal agent use; it is for tests and debugging only. do not set a short shell timeout; either run it without a timeout or use a very high threshold above 10 minutes so the user has time to review and send feedback. Use --agent-reply after applying prior feedback to display your response in Lavish Editor before waiting again.
2513
+ This command long-polls indefinitely for queued user prompts, then returns them to the agent. It stays silent while it waits - that is normal, never kill it. 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.
2462
2514
  `,
2463
2515
  end: `Usage: lavish-axi end <html-file>
2464
2516
 
@@ -2472,6 +2524,8 @@ Shut down the background Lavish Editor server. The server also stops itself when
2472
2524
 
2473
2525
  List focused artifact guidance playbooks, or show one playbook by ID. Known IDs: diagram, table, comparison, plan, diff, input, slides.
2474
2526
 
2527
+ One artifact often combines several playbooks (for example a plan that includes a comparison and a diagram), so read every playbook relevant to the artifact, not just one, for the best quality.
2528
+
2475
2529
  Examples:
2476
2530
  lavish-axi playbook
2477
2531
  lavish-axi playbook diagram
@@ -2479,7 +2533,7 @@ Examples:
2479
2533
  `,
2480
2534
  design: `Usage: lavish-axi design
2481
2535
 
2482
- Show a copy-pasteable CDN snippet for Tailwind CSS browser runtime v4 + DaisyUI v5 + themes, plus technical reference for DaisyUI components. Lavish artifacts stay portable HTML. Choose a design system in this priority order: (1) if the user asked for a specific look or named design system, follow that; (2) otherwise, if the current project already has a design system or style conventions, match those; (3) otherwise, prefer the Lavish-recommended Tailwind + DaisyUI CDN snippet over hand-writing styles unless explicitly instructed otherwise by the user.
2536
+ Show a copy-pasteable CDN snippet for Tailwind CSS browser runtime v4 + DaisyUI v5 + themes, plus technical reference for DaisyUI components. Lavish artifacts stay portable HTML. This CDN snippet is the design fallback, not the default: inspect the project before falling back. The strict priority order is: (1) if the user asked for a specific look or named design system, follow that; (2) otherwise, if the current project already has a design system or style conventions, match those; (3) only when both come up empty, prefer the Lavish-recommended Tailwind + DaisyUI CDN snippet over hand-writing styles unless explicitly instructed otherwise by the user.
2483
2537
  `,
2484
2538
  setup: `Usage: lavish-axi setup hooks
2485
2539
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavish-axi",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
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",
@@ -27,6 +27,8 @@ Use lavish-axi when the user asks for a visual artifact, HTML explainer, interac
27
27
  1. Create the HTML artifact (default location `.lavish/<name>.html` in the working directory).
28
28
  2. Run `npx -y lavish-axi <html-file>` to open or resume a review session in the browser.
29
29
  3. Run `npx -y lavish-axi poll <html-file>` to long-poll for the user's annotations and queued prompts.
30
+ The poll stays silent until the user acts - leave it running, never kill it.
31
+ 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.
30
32
  4. Apply the feedback, then poll again with `--agent-reply "<message>"` to reply in the browser and keep the loop going.
31
33
  5. Run `npx -y lavish-axi end <html-file>` when the review is finished.
32
34
 
@@ -39,7 +41,8 @@ Use lavish-axi when the user asks for a visual artifact, HTML explainer, interac
39
41
 
40
42
  ## Playbooks
41
43
 
42
- Run `npx -y lavish-axi playbook <id>` for focused, detailed guidance on any of these:
44
+ Run `npx -y lavish-axi playbook <id>` for focused, detailed guidance on any of these.
45
+ One artifact often combines several playbooks (for example a plan that includes a comparison and a diagram), so read every playbook relevant to your artifact, not just one, for the best quality:
43
46
 
44
47
  - `diagram` - Map relationships, flows, state, and architecture
45
48
  - `table` - Turn dense records into scan-friendly review surfaces
@@ -54,9 +57,9 @@ Run `npx -y lavish-axi playbook <id>` for focused, detailed guidance on any of t
54
57
  - Run `npx -y lavish-axi <html-file>` to open or resume a Lavish Editor session
55
58
  - Unless the user specifies another location, create HTML artifacts in the current working directory under `.lavish/`
56
59
  - 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
57
- - Run `npx -y lavish-axi poll <html-file>` to wait for user feedback
60
+ - Run `npx -y 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. 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
58
61
  - Run `npx -y lavish-axi end <html-file>` to end a session
59
62
  - Run `npx -y lavish-axi stop` to shut down the background server (it also self-stops when idle or after the last session ends with nothing connected)
60
- - Run `npx -y lavish-axi playbook <playbook_id>` for focused artifact guidance
61
- - Lavish does not auto-inject any design system - artifacts stay portable so they render identically when opened directly without lavish-axi running. Choose a design system in this priority order: (1) if the user asked for a specific look or named design system, follow that; (2) otherwise, if the current project already has a design system or style conventions, match those so the artifact fits in; (3) otherwise, prefer the Lavish-recommended Tailwind CSS browser runtime v4 + DaisyUI v5, available via CDN - run `npx -y lavish-axi design` for a copy-pasteable CDN snippet plus component reference. Prefer that CDN snippet over hand-writing styles unless explicitly instructed otherwise by the user.
63
+ - Run `npx -y lavish-axi playbook <playbook_id>` for focused artifact guidance. One artifact often combines several playbooks (for example a plan that includes a comparison and a diagram), so read every playbook relevant to the artifact, not just one, for the best quality
64
+ - Lavish does not auto-inject any design system - artifacts stay portable so they render identically when opened directly without lavish-axi running. Before writing any HTML, decide the design direction in this strict priority order, and only move to the next step when the current one truly yields nothing: (1) if the user asked for a specific look or named design system, use that; (2) otherwise you must first inspect the current project for design conventions - look for a Tailwind or theme config, shared CSS variables or design tokens, a component library, brand assets, or existing styled pages - and match what you find so the artifact fits in; (3) only when both steps come up empty, use the Lavish-recommended Tailwind CSS browser runtime v4 + DaisyUI v5, available via CDN - run `npx -y lavish-axi design` for a copy-pasteable CDN snippet plus component reference, and prefer that CDN snippet over hand-writing styles unless explicitly instructed otherwise by the user. When you deliver the artifact, state which of the three design sources you used and why.
62
65
  - Use lavish-axi when the user asks for a visual artifact, HTML explainer, interactive prototype, review surface, product or technical plan, comparison, report, or browser-based feedback loop