lavish-axi 0.1.38 → 0.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/dist/chrome.css +8 -0
- package/dist/cli.mjs +105 -7
- package/package.json +1 -1
- package/skills/lavish/SKILL.md +2 -1
package/README.md
CHANGED
|
@@ -137,7 +137,8 @@ pnpm link
|
|
|
137
137
|
Before writing HTML, choose a design system in strict priority order: follow a user-requested look first; otherwise inspect the project the artifact is about - the subject or product whose content or UI it represents, which may differ from your current working directory - and match that project's Tailwind or theme config, CSS variables or design tokens, component library, brand assets, or existing styled pages.
|
|
138
138
|
If the artifact previews, proposes, or mocks a specific app's UI, render it in that app's own design system so it faithfully shows the product, even when you are running in a different repo.
|
|
139
139
|
Only when both come up empty, run `lavish-axi design` for a copy-pasteable Tailwind CSS v4 + DaisyUI v5 CDN fallback, a content-to-playbook router, and Mermaid diagram tooling.
|
|
140
|
-
That fallback guidance recommends DaisyUI's `luxury` theme by default, warns not to `@apply` DaisyUI classes inside Tailwind browser-runtime style blocks, includes an optional layout safety CSS snippet for dense nested grid/flex layouts, and provides a pinned Mermaid CDN snippet
|
|
140
|
+
That fallback guidance recommends DaisyUI's `luxury` theme by default, warns not to `@apply` DaisyUI classes inside Tailwind browser-runtime style blocks, includes an optional layout safety CSS snippet for dense nested grid/flex layouts, and provides a pinned, theme-aware Mermaid CDN snippet for flows, architecture, state, and sequence diagrams.
|
|
141
|
+
The Mermaid snippet waits for page styles, chooses its light or dark rendering from the effective page background, and keeps diagrams in sync with page-theme and OS appearance changes.
|
|
141
142
|
- **Open-time layout gate** - The browser chrome masks each artifact until the real in-iframe layout audit reports no error-severity findings.
|
|
142
143
|
Warning-only artifacts reveal normally; error findings notify the agent through the same `layout_warnings` poll path and keep the curtain up until a clean reload.
|
|
143
144
|
The user can click **Show anyway**, and a bounded safety timeout reveals with a persistent layout-issues banner so review is never blocked indefinitely.
|
|
@@ -168,7 +169,7 @@ pnpm link
|
|
|
168
169
|
Agent-initiated ends keep reopening normally, same as before.
|
|
169
170
|
`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.
|
|
170
171
|
- **Precise targets** - Text annotations include selected text plus range anchors, so agents are not limited to whole-element selectors.
|
|
171
|
-
- **Mermaid diagrams** - Rendered Mermaid diagrams become pannable and zoomable while you explore (drag to pan, scroll to zoom) and freeze when you turn on annotation so a click lands on a single node. Clicking a node annotates the whole node and sends the agent its diagram id, node id, and rendered label instead of just a CSS selector. Lavish only enhances the live render, so the saved HTML still opens identically anywhere.
|
|
172
|
+
- **Mermaid diagrams** - The `lavish-axi design` Mermaid snippet matches diagram rendering to the effective artifact page background and re-renders when a page-theme or OS appearance change alters that appearance. Rendered Mermaid diagrams become pannable and zoomable while you explore (drag to pan, scroll to zoom) and freeze when you turn on annotation so a click lands on a single node. Clicking a node annotates the whole node and sends the agent its diagram id, node id, and rendered label instead of just a CSS selector. Lavish only enhances the live render, so the saved HTML still opens identically anywhere.
|
|
172
173
|
- **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.
|
|
173
174
|
Set `LAVISH_AXI_IDLE_TIMEOUT_MS=0` or `off` to disable idle self-shutdown.
|
|
174
175
|
- **Local-first state** - Session state stays under `~/.lavish-axi/` by default, or `LAVISH_AXI_STATE_DIR` when set.
|
|
@@ -187,13 +188,13 @@ pnpm link
|
|
|
187
188
|
| `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. |
|
|
188
189
|
| `lavish-axi stop` | Shut down the background server. |
|
|
189
190
|
| `lavish-axi playbook [id]` | List focused artifact guidance or show one playbook; agents must open each matching playbook before writing HTML. |
|
|
190
|
-
| `lavish-axi design` | Show the Tailwind + DaisyUI CDN fallback, content-to-playbook router, Mermaid diagram tooling, `luxury` default theme, DaisyUI `@apply` warning, and layout safety snippet.
|
|
191
|
+
| `lavish-axi design` | Show the Tailwind + DaisyUI CDN fallback, content-to-playbook router, theme-aware Mermaid diagram tooling, `luxury` default theme, DaisyUI `@apply` warning, and layout safety snippet. |
|
|
191
192
|
| `lavish-axi setup hooks` | Install or repair optional SessionStart hooks for Claude Code, Codex, OpenCode, and GitHub Copilot CLI; restart the agent session afterward. |
|
|
192
193
|
| `lavish-axi server` | Run the local Lavish Editor server. |
|
|
193
194
|
|
|
194
195
|
Known playbook IDs: `diagram`, `table`, `comparison`, `plan`, `code`, `input`, `slides`.
|
|
195
196
|
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.
|
|
196
|
-
For flows, architecture, state, or sequence diagrams, open the diagram playbook and use the Mermaid tooling from `lavish-axi design` unless SVG is needed for richly annotated nodes; avoid hand-built div/flexbox boxes-and-arrows.
|
|
197
|
+
For flows, architecture, state, or sequence diagrams, open the diagram playbook and use the theme-aware Mermaid tooling from `lavish-axi design` unless SVG is needed for richly annotated nodes; avoid hand-built div/flexbox boxes-and-arrows.
|
|
197
198
|
|
|
198
199
|
### Flags
|
|
199
200
|
|
package/dist/chrome.css
CHANGED
|
@@ -652,6 +652,14 @@ body.lavish {
|
|
|
652
652
|
flex-direction: column;
|
|
653
653
|
gap: 10px;
|
|
654
654
|
}
|
|
655
|
+
|
|
656
|
+
.chat:empty::before {
|
|
657
|
+
content: "Agent hasn't sent a message yet. Click an element in the artifact to annotate, or type below to start.";
|
|
658
|
+
margin-top: 2px;
|
|
659
|
+
color: var(--fg-muted);
|
|
660
|
+
font-size: 13px;
|
|
661
|
+
line-height: 1.45;
|
|
662
|
+
}
|
|
655
663
|
.bubble {
|
|
656
664
|
max-width: 85%;
|
|
657
665
|
border-radius: var(--radius-xl);
|
package/dist/cli.mjs
CHANGED
|
@@ -34,7 +34,8 @@ var PLAYBOOKS = [
|
|
|
34
34
|
design_rules: [
|
|
35
35
|
"Use page-scoped class names and avoid generic names like .node that can collide with diagram libraries.",
|
|
36
36
|
"Prefer top-down flow for multi-step diagrams unless the flow is genuinely linear and short.",
|
|
37
|
-
"Quote labels that contain punctuation or code-like names, and use explicit line breaks where the renderer supports them."
|
|
37
|
+
"Quote labels that contain punctuation or code-like names, and use explicit line breaks where the renderer supports them.",
|
|
38
|
+
"Initialize Mermaid to match the page theme and re-render when the theme changes: pick the Mermaid theme from the effective page appearance (light or dark) at render time, and use the theme-aware `lavish-axi design` Mermaid snippet rather than hardcoding a single theme, since Mermaid does not restyle an already-rendered SVG when the viewer toggles the page theme."
|
|
38
39
|
],
|
|
39
40
|
pitfalls: [
|
|
40
41
|
"Do not cram every file or function into one diagram when a layered explanation would be clearer.",
|
|
@@ -283,11 +284,108 @@ var DESIGN_CDN_SNIPPET = `<link rel="stylesheet" href="${DESIGN_CDN_URLS.daisyui
|
|
|
283
284
|
var MERMAID_CDN_SNIPPET = `<script type="module">
|
|
284
285
|
import mermaid from "${MERMAID_CDN_URL}";
|
|
285
286
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
287
|
+
// Render Mermaid in a theme that matches the artifact page, and re-render when
|
|
288
|
+
// the viewer flips the page theme - Mermaid never restyles an already-rendered
|
|
289
|
+
// SVG on its own, so a fixed theme clashes in either light or dark mode.
|
|
290
|
+
const darkQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
291
|
+
|
|
292
|
+
// Normalize any CSS color the browser produces (rgb, oklch, hsl, named, ...)
|
|
293
|
+
// to [r, g, b, a] bytes via a 1x1 canvas, so parsing never breaks on modern
|
|
294
|
+
// color syntaxes like DaisyUI's oklch() values.
|
|
295
|
+
const paint = document.createElement("canvas").getContext("2d");
|
|
296
|
+
function toRgba(color) {
|
|
297
|
+
paint.clearRect(0, 0, 1, 1);
|
|
298
|
+
paint.fillStyle = "#000";
|
|
299
|
+
paint.fillStyle = color;
|
|
300
|
+
paint.fillRect(0, 0, 1, 1);
|
|
301
|
+
return paint.getImageData(0, 0, 1, 1).data;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function compositeRgba(foreground, background) {
|
|
305
|
+
const foregroundAlpha = foreground[3] / 255;
|
|
306
|
+
const backgroundAlpha = background[3] / 255;
|
|
307
|
+
const alpha = foregroundAlpha + backgroundAlpha * (1 - foregroundAlpha);
|
|
308
|
+
if (alpha === 0) return [0, 0, 0, 0];
|
|
309
|
+
return [
|
|
310
|
+
(foreground[0] * foregroundAlpha + background[0] * backgroundAlpha * (1 - foregroundAlpha)) / alpha,
|
|
311
|
+
(foreground[1] * foregroundAlpha + background[1] * backgroundAlpha * (1 - foregroundAlpha)) / alpha,
|
|
312
|
+
(foreground[2] * foregroundAlpha + background[2] * backgroundAlpha * (1 - foregroundAlpha)) / alpha,
|
|
313
|
+
alpha * 255,
|
|
314
|
+
];
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function pageIsDark() {
|
|
318
|
+
// Trust the actually-rendered page background so this works with any theming
|
|
319
|
+
// mechanism: prefers-color-scheme, a data-theme attribute, or plain CSS.
|
|
320
|
+
const root = document.documentElement;
|
|
321
|
+
const rootBackground = toRgba(getComputedStyle(root).backgroundColor);
|
|
322
|
+
const bodyBackground = document.body ? toRgba(getComputedStyle(document.body).backgroundColor) : [0, 0, 0, 0];
|
|
323
|
+
const [r, g, b, a] = compositeRgba(bodyBackground, rootBackground);
|
|
324
|
+
if (a > 0) {
|
|
325
|
+
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255 < 0.5;
|
|
326
|
+
}
|
|
327
|
+
const colorScheme = getComputedStyle(root).colorScheme;
|
|
328
|
+
if (colorScheme.includes("dark") && !colorScheme.includes("light")) return true;
|
|
329
|
+
if (colorScheme.includes("light") && !colorScheme.includes("dark")) return false;
|
|
330
|
+
return darkQuery.matches;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const diagrams = [...document.querySelectorAll(".mermaid")].map((el) => ({ el, src: el.textContent }));
|
|
334
|
+
let applied;
|
|
335
|
+
let rendering = false;
|
|
336
|
+
let queued = false;
|
|
337
|
+
function queueRender() {
|
|
338
|
+
queued = true;
|
|
339
|
+
if (rendering) return;
|
|
340
|
+
void render();
|
|
341
|
+
}
|
|
342
|
+
async function render() {
|
|
343
|
+
rendering = true;
|
|
344
|
+
try {
|
|
345
|
+
while (queued) {
|
|
346
|
+
queued = false;
|
|
347
|
+
const theme = pageIsDark() ? "dark" : "default";
|
|
348
|
+
if (theme === applied) continue;
|
|
349
|
+
mermaid.initialize({ startOnLoad: false, theme, securityLevel: "strict" });
|
|
350
|
+
for (const { el, src } of diagrams) {
|
|
351
|
+
el.removeAttribute("data-processed");
|
|
352
|
+
el.textContent = src;
|
|
353
|
+
}
|
|
354
|
+
try {
|
|
355
|
+
await mermaid.run({ nodes: diagrams.map((d) => d.el) });
|
|
356
|
+
} catch (error) {
|
|
357
|
+
console.error("Mermaid diagram render failed:", error);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
applied = theme;
|
|
361
|
+
}
|
|
362
|
+
} finally {
|
|
363
|
+
rendering = false;
|
|
364
|
+
if (queued) queueRender();
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// First render once stylesheets are applied (no wrong-theme flash), then keep
|
|
369
|
+
// the diagrams in sync with page-theme toggles and OS light/dark changes.
|
|
370
|
+
if (document.readyState === "complete") queueRender();
|
|
371
|
+
else window.addEventListener("load", queueRender, { once: true });
|
|
372
|
+
const themeObserver = new MutationObserver(queueRender);
|
|
373
|
+
for (const el of [document.documentElement, document.body]) {
|
|
374
|
+
if (!el) continue;
|
|
375
|
+
themeObserver.observe(el, {
|
|
376
|
+
attributes: true,
|
|
377
|
+
attributeFilter: ["data-theme", "class", "style"],
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
document.addEventListener("change", queueRender, true);
|
|
381
|
+
document.addEventListener(
|
|
382
|
+
"transitionend",
|
|
383
|
+
({ propertyName }) => {
|
|
384
|
+
if (propertyName === "background-color") queueRender();
|
|
385
|
+
},
|
|
386
|
+
true,
|
|
387
|
+
);
|
|
388
|
+
darkQuery.addEventListener("change", queueRender);
|
|
291
389
|
</script>`;
|
|
292
390
|
var LAYOUT_SAFETY_CSS_SNIPPET = `<style>
|
|
293
391
|
*, *::before, *::after { box-sizing: border-box; }
|
|
@@ -6410,7 +6508,7 @@ function normalizePagePath(path6) {
|
|
|
6410
6508
|
var COMMANDS = /* @__PURE__ */ new Set(["open", "poll", "end", "stop", "server", "playbook", "design", "setup", "export", "share"]);
|
|
6411
6509
|
var RESERVED = new Set(RESERVED_COMMANDS);
|
|
6412
6510
|
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`.";
|
|
6413
|
-
var VERSION = "0.1.
|
|
6511
|
+
var VERSION = "0.1.39";
|
|
6414
6512
|
async function run(argv) {
|
|
6415
6513
|
await ensureStateDir();
|
|
6416
6514
|
const normalizedArgv = normalizeArgv(argv);
|
package/package.json
CHANGED
package/skills/lavish/SKILL.md
CHANGED
|
@@ -32,6 +32,7 @@ Use lavish-axi when the user asks for a visual artifact, HTML explainer, interac
|
|
|
32
32
|
1. Create the HTML artifact (default location `.lavish/<name>.html` in the working directory).
|
|
33
33
|
2. Run `npx -y lavish-axi <html-file>` to open or resume a review session in the browser.
|
|
34
34
|
3. Run `npx -y lavish-axi poll <html-file>` to long-poll for the user's annotations, queued prompts, and browser-reported `layout_warnings`.
|
|
35
|
+
On the first poll, prefer `--agent-reply "<one-line summary of what you built and what to review first>"` so the conversation panel opens with context.
|
|
35
36
|
The poll stays silent until the user acts or the real browser reports fresh layout warnings - leave it running, never kill it.
|
|
36
37
|
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.
|
|
37
38
|
4. If poll returns `layout_warnings`, follow the returned `next_step`: fix and re-check fresh error-severity findings, but proceed with a note instead of looping when every current warning is persistent or low-severity.
|
|
@@ -51,7 +52,7 @@ Use lavish-axi when the user asks for a visual artifact, HTML explainer, interac
|
|
|
51
52
|
|
|
52
53
|
Run `npx -y lavish-axi playbook <id>` for focused, detailed guidance on any of these.
|
|
53
54
|
One artifact often combines several playbooks (for example a plan that includes a comparison and a diagram), so MUST open each matching playbook before writing HTML.
|
|
54
|
-
For flows, architecture, state, or sequence diagrams, do not hand-build boxes-and-arrows from div/flexbox; open the diagram playbook and use Mermaid unless SVG is needed for richly annotated nodes.
|
|
55
|
+
For flows, architecture, state, or sequence diagrams, do not hand-build boxes-and-arrows from div/flexbox; open the diagram playbook and use the theme-aware Mermaid snippet from `npx -y lavish-axi design` unless SVG is needed for richly annotated nodes.
|
|
55
56
|
|
|
56
57
|
- `diagram` - Map relationships, flows, state, and architecture
|
|
57
58
|
- `table` - Turn dense records into scan-friendly review surfaces
|