lavish-axi 0.1.18 → 0.1.20
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 +42 -1
- package/dist/chrome-client.js +6 -0
- package/dist/cli.mjs +23 -8
- package/package.json +4 -2
- package/skills/lavish-axi/SKILL.md +54 -0
package/README.md
CHANGED
|
@@ -51,6 +51,10 @@ Just tell your agent:
|
|
|
51
51
|
Use `npx lavish-axi` to write a product or technical plan for what we discussed.
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
+
That works with zero setup - Lavish is an AXI, so any capable agent can run the CLI directly.
|
|
55
|
+
|
|
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
|
+
|
|
54
58
|
## Install
|
|
55
59
|
|
|
56
60
|
**npm**
|
|
@@ -69,6 +73,42 @@ pnpm run build
|
|
|
69
73
|
pnpm link
|
|
70
74
|
```
|
|
71
75
|
|
|
76
|
+
## Teach Your Agent About Lavish (recommended)
|
|
77
|
+
|
|
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.
|
|
81
|
+
|
|
82
|
+
### Option A: Session hook (recommended)
|
|
83
|
+
|
|
84
|
+
Run this once to opt in:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
lavish-axi setup hooks
|
|
88
|
+
```
|
|
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
|
+
|
|
93
|
+
**Restart your agent session after running this** so the new hook takes effect.
|
|
94
|
+
|
|
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):
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
npx skills add kunchenguid/lavish-axi --skill lavish-axi
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
This drops a `lavish-axi` 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
|
+
It does not surface your live open sessions - run `lavish-axi setup hooks` if you want that ambient context too.
|
|
107
|
+
|
|
108
|
+
### No setup at all
|
|
109
|
+
|
|
110
|
+
Lavish also works fully as a plain CLI - just tell your agent to `npx lavish-axi <file.html>` as shown in the Quick Start.
|
|
111
|
+
|
|
72
112
|
## How It Works
|
|
73
113
|
|
|
74
114
|
```
|
|
@@ -98,7 +138,7 @@ pnpm link
|
|
|
98
138
|
- **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.
|
|
99
139
|
- **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.
|
|
100
140
|
- **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">`.
|
|
101
|
-
- **Feedback controls** -
|
|
141
|
+
- **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. Mark only custom (non-native) clickable elements with `data-lavish-action` so Lavish does not annotate them.
|
|
102
142
|
- **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.
|
|
103
143
|
- **Precise targets** - Text annotations include selected text plus range anchors, so agents are not limited to whole-element selectors.
|
|
104
144
|
- **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.
|
|
@@ -136,6 +176,7 @@ Known playbook IDs: `diagram`, `table`, `comparison`, `plan`, `diff`, `input`, `
|
|
|
136
176
|
```sh
|
|
137
177
|
pnpm run check # Run all verification commands
|
|
138
178
|
pnpm run build # Bundle the publishable CLI, chrome, and design assets
|
|
179
|
+
pnpm run build:skill # Regenerate the installable lavish-axi skill
|
|
139
180
|
pnpm test # Run node:test tests
|
|
140
181
|
pnpm run lint # Run ESLint
|
|
141
182
|
pnpm run format:check # Check Prettier formatting
|
package/dist/chrome-client.js
CHANGED
|
@@ -260,6 +260,12 @@ annotationButton.onclick = () => {
|
|
|
260
260
|
};
|
|
261
261
|
|
|
262
262
|
sendButton.onclick = sendQueued;
|
|
263
|
+
chatInput.addEventListener("keydown", (event) => {
|
|
264
|
+
if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
|
|
265
|
+
event.preventDefault();
|
|
266
|
+
sendQueued();
|
|
267
|
+
}
|
|
268
|
+
});
|
|
263
269
|
copyPathButton.onclick = copyFilePath;
|
|
264
270
|
endButton.onclick = endSession;
|
|
265
271
|
frame.addEventListener("load", () => {
|
package/dist/cli.mjs
CHANGED
|
@@ -642,7 +642,9 @@ var PLAYBOOKS = [
|
|
|
642
642
|
"Show queued or selected state clearly so the user trusts what will be sent back."
|
|
643
643
|
],
|
|
644
644
|
design_rules: [
|
|
645
|
-
"
|
|
645
|
+
"Native form controls - radios, checkboxes, text inputs, selects, textareas, buttons, options, labels, and contenteditable regions - are interactive automatically: clicks toggle, focus, and type instead of annotating, so they do not need data-lavish-action. Build choice and option UIs from these whenever you can.",
|
|
646
|
+
"To turn a native control into agent feedback, wire its own change, click, or submit handler to window.lavish.queuePrompt() (for example a radio group's onchange, or a submit button that reads the selected values) - no marker required.",
|
|
647
|
+
"Put data-lavish-action only on custom (non-native) elements that should act like a feedback control - typically a styled div or span you made clickable - so Lavish does not annotate it and shows a pointer cursor instead.",
|
|
646
648
|
"Call window.lavish.queuePrompt(prompt, options) from the control's click, change, or submit handler to queue a precise request for the agent.",
|
|
647
649
|
"Pass options such as tag, text, selector, target, or data when they help the agent understand exactly what the user chose.",
|
|
648
650
|
"Call window.lavish.sendQueuedPrompts() when the control should immediately send the queued feedback instead of waiting for the user to press Send to Agent.",
|
|
@@ -656,7 +658,8 @@ var PLAYBOOKS = [
|
|
|
656
658
|
],
|
|
657
659
|
lavish_notes: [
|
|
658
660
|
"Lavish is strongest when the artifact becomes a focused review surface and not just a static page.",
|
|
659
|
-
`A
|
|
661
|
+
`A native choice looks like \`<label><input type="radio" name="plan" onchange="window.lavish.queuePrompt('Use the Pro plan', { tag: 'choice', text: 'Pro' })"> Pro</label>\` - it just works, no marker needed.`,
|
|
662
|
+
`A custom (non-native) control needs the marker: \`<div role="button" tabindex="0" data-lavish-action onclick="window.lavish.queuePrompt('Choose option A', { tag: 'choice', text: 'Option A' })">Choose option A</div>\`.`,
|
|
660
663
|
"Use window.lavish.queuePrompt for user intent, not internal analytics or UI-only state changes.",
|
|
661
664
|
"End input paths with an obvious way for the user to send feedback back to the agent."
|
|
662
665
|
]
|
|
@@ -779,7 +782,7 @@ function createArtifactSdk() {
|
|
|
779
782
|
const text = selection.toString().trim().replace(/\s+/g, " ");
|
|
780
783
|
if (range.collapsed || !text) return null;
|
|
781
784
|
const ancestor = closestElement(range.commonAncestorContainer);
|
|
782
|
-
if (isLavishUi(ancestor) || isLavishAction(ancestor)) return null;
|
|
785
|
+
if (isLavishUi(ancestor) || isLavishAction(ancestor) || isInteractiveControl(ancestor)) return null;
|
|
783
786
|
const commonAncestorSelector = selector(ancestor);
|
|
784
787
|
const target = {
|
|
785
788
|
type: "text-range",
|
|
@@ -805,6 +808,9 @@ function createArtifactSdk() {
|
|
|
805
808
|
function isLavishAction(el) {
|
|
806
809
|
return !!(el && el.closest && el.closest("[data-lavish-action]"));
|
|
807
810
|
}
|
|
811
|
+
function isInteractiveControl(el) {
|
|
812
|
+
return !!(el && el.closest && el.closest("button,input,select,textarea,option,optgroup,label,[contenteditable]:not([contenteditable='false'])"));
|
|
813
|
+
}
|
|
808
814
|
function highlightElement(el) {
|
|
809
815
|
if (!el) return;
|
|
810
816
|
el.style.outline = "var(--lavish-annotate-outline,2px solid #f4c95d)";
|
|
@@ -837,7 +843,7 @@ function createArtifactSdk() {
|
|
|
837
843
|
if (annotationMode && !style) {
|
|
838
844
|
style = document.createElement("style");
|
|
839
845
|
style.id = "lavish-cursor-style";
|
|
840
|
-
style.textContent = ":root{--lavish-accent:#f4c95d;--lavish-annotate-outline:2px solid var(--lavish-accent);--lavish-annotate-offset:2px}*{cursor:default!important}[data-lavish-action],[data-lavish-action] *{cursor:pointer!important}";
|
|
846
|
+
style.textContent = ":root{--lavish-accent:#f4c95d;--lavish-annotate-outline:2px solid var(--lavish-accent);--lavish-annotate-offset:2px}*{cursor:default!important}[data-lavish-action],[data-lavish-action] *{cursor:pointer!important}input,textarea,[contenteditable]:not([contenteditable='false']){cursor:text!important}button,select,label,option,input[type='button'],input[type='submit'],input[type='reset'],input[type='checkbox'],input[type='radio'],input[type='file'],input[type='color'],input[type='range'],input[type='image']{cursor:pointer!important}";
|
|
841
847
|
document.head.appendChild(style);
|
|
842
848
|
}
|
|
843
849
|
if (!annotationMode && style) style.remove();
|
|
@@ -936,6 +942,12 @@ function createArtifactSdk() {
|
|
|
936
942
|
if (prompt) queuePrompt(prompt, c);
|
|
937
943
|
closeCard();
|
|
938
944
|
};
|
|
945
|
+
textarea.addEventListener("keydown", (event) => {
|
|
946
|
+
if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
|
|
947
|
+
event.preventDefault();
|
|
948
|
+
sendButton.click();
|
|
949
|
+
}
|
|
950
|
+
});
|
|
939
951
|
setTimeout(() => textarea.focus(), 0);
|
|
940
952
|
}
|
|
941
953
|
window.lavish = {
|
|
@@ -971,7 +983,8 @@ function createArtifactSdk() {
|
|
|
971
983
|
document.addEventListener(
|
|
972
984
|
"mouseover",
|
|
973
985
|
(event) => {
|
|
974
|
-
if (!annotationMode || isLavishUi(event.target) || isLavishAction(event.target))
|
|
986
|
+
if (!annotationMode || isLavishUi(event.target) || isLavishAction(event.target) || isInteractiveControl(event.target))
|
|
987
|
+
return;
|
|
975
988
|
if (event.target === selected) return;
|
|
976
989
|
if (hovered && hovered !== selected) clearHighlight(hovered);
|
|
977
990
|
hovered = event.target;
|
|
@@ -992,7 +1005,8 @@ function createArtifactSdk() {
|
|
|
992
1005
|
document.addEventListener(
|
|
993
1006
|
"mouseup",
|
|
994
1007
|
(event) => {
|
|
995
|
-
if (!annotationMode || isLavishUi(event.target) || isLavishAction(event.target))
|
|
1008
|
+
if (!annotationMode || isLavishUi(event.target) || isLavishAction(event.target) || isInteractiveControl(event.target))
|
|
1009
|
+
return;
|
|
996
1010
|
const c = textSelectionContext(document.getSelection());
|
|
997
1011
|
if (!c) return;
|
|
998
1012
|
ignoreNextClick = true;
|
|
@@ -1003,7 +1017,8 @@ function createArtifactSdk() {
|
|
|
1003
1017
|
document.addEventListener(
|
|
1004
1018
|
"click",
|
|
1005
1019
|
(event) => {
|
|
1006
|
-
if (!annotationMode || isLavishUi(event.target) || isLavishAction(event.target))
|
|
1020
|
+
if (!annotationMode || isLavishUi(event.target) || isLavishAction(event.target) || isInteractiveControl(event.target))
|
|
1021
|
+
return;
|
|
1007
1022
|
event.preventDefault();
|
|
1008
1023
|
event.stopPropagation();
|
|
1009
1024
|
if (ignoreNextClick) {
|
|
@@ -1890,7 +1905,7 @@ function normalizePagePath(path5) {
|
|
|
1890
1905
|
// src/cli.js
|
|
1891
1906
|
var COMMANDS = /* @__PURE__ */ new Set(["open", "poll", "end", "stop", "server", "playbook", "design", "setup"]);
|
|
1892
1907
|
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`.";
|
|
1893
|
-
var VERSION = "0.1.
|
|
1908
|
+
var VERSION = "0.1.20";
|
|
1894
1909
|
async function run(argv) {
|
|
1895
1910
|
await ensureStateDir();
|
|
1896
1911
|
const normalizedArgv = normalizeArgv(argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lavish-axi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
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",
|
|
@@ -9,13 +9,15 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
|
+
"skills/lavish-axi",
|
|
12
13
|
"lavish-editor-marketing/renders/lavish-editor-marketing.gif",
|
|
13
14
|
"LICENSE",
|
|
14
15
|
"README.md"
|
|
15
16
|
],
|
|
16
17
|
"scripts": {
|
|
17
18
|
"build": "node scripts/build.js",
|
|
18
|
-
"
|
|
19
|
+
"build:skill": "node scripts/build-skill.js",
|
|
20
|
+
"check": "npm run build && npm run lint && npm run format:check && npm run typecheck && npm test && node scripts/build-skill.js --check",
|
|
19
21
|
"start": "node dist/cli.mjs",
|
|
20
22
|
"lint": "eslint bin src test scripts",
|
|
21
23
|
"format": "prettier --write .",
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lavish-axi
|
|
3
|
+
description: Turn complex or visual agent responses into rich, reviewable HTML artifacts the user can annotate and send feedback on, using the lavish-axi CLI. Use when about to give a plan, comparison, diagram, table, code diff, report, or anything easier to grasp visually than as prose.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Lavish Editor
|
|
7
|
+
|
|
8
|
+
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 `npx -y lavish-axi <html-file>` so the user can visually review it, annotate elements or selected text, queue prompts, and send feedback back through `npx -y lavish-axi poll`.
|
|
9
|
+
|
|
10
|
+
You do not need lavish-axi installed globally - invoke it with `npx -y lavish-axi <html-file>`.
|
|
11
|
+
If lavish-axi output shows a follow-up command starting with `lavish-axi`, run it as `npx -y lavish-axi ...` instead.
|
|
12
|
+
|
|
13
|
+
## When to use
|
|
14
|
+
|
|
15
|
+
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
|
|
16
|
+
|
|
17
|
+
## Workflow
|
|
18
|
+
|
|
19
|
+
1. Create the HTML artifact (default location `.lavish/<name>.html` in the working directory).
|
|
20
|
+
2. Run `npx -y lavish-axi <html-file>` to open or resume a review session in the browser.
|
|
21
|
+
3. Run `npx -y lavish-axi poll <html-file>` to long-poll for the user's annotations and queued prompts.
|
|
22
|
+
4. Apply the feedback, then poll again with `--agent-reply "<message>"` to reply in the browser and keep the loop going.
|
|
23
|
+
5. Run `npx -y lavish-axi end <html-file>` when the review is finished.
|
|
24
|
+
|
|
25
|
+
## Visual guidance
|
|
26
|
+
|
|
27
|
+
- Use visual hierarchy to make the most important decisions, risks, tradeoffs, and next actions obvious at a glance
|
|
28
|
+
- Use visual structure such as sections, cards, tables, diagrams, annotated snippets, and side-by-side comparisons instead of long prose
|
|
29
|
+
- Choose typography, spacing, color, and layout deliberately so the artifact has a clear point of view
|
|
30
|
+
- Prevent horizontal overflow: design narrow layouts intentionally, use minmax(0, 1fr) and min-width: 0 for grid/flex children, and deliberately wrap or truncate long labels/status text
|
|
31
|
+
|
|
32
|
+
## Playbooks
|
|
33
|
+
|
|
34
|
+
Run `npx -y lavish-axi playbook <id>` for focused, detailed guidance on any of these:
|
|
35
|
+
|
|
36
|
+
- `diagram` - Map relationships, flows, state, and architecture
|
|
37
|
+
- `table` - Turn dense records into scan-friendly review surfaces
|
|
38
|
+
- `comparison` - Show options, tradeoffs, and current vs target behavior
|
|
39
|
+
- `plan` - Explain a product or technical plan before implementation
|
|
40
|
+
- `diff` - Present code or PR changes with evidence and findings
|
|
41
|
+
- `input` - Must be used when the agent needs to collect user input on decisions, choices, preferences, triage, scope, or other structured feedback from within the artifact
|
|
42
|
+
- `slides` - Create a deliberate presentation when slides are requested
|
|
43
|
+
|
|
44
|
+
## Commands & rules
|
|
45
|
+
|
|
46
|
+
- Run `npx -y lavish-axi <html-file>` to open or resume a Lavish Editor session
|
|
47
|
+
- Unless the user specifies another location, create HTML artifacts in the current working directory under `.lavish/`
|
|
48
|
+
- 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
|
|
49
|
+
- Run `npx -y lavish-axi poll <html-file>` to wait for user feedback
|
|
50
|
+
- Run `npx -y lavish-axi end <html-file>` to end a session
|
|
51
|
+
- 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)
|
|
52
|
+
- Run `npx -y lavish-axi playbook <playbook_id>` for focused artifact guidance
|
|
53
|
+
- 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.
|
|
54
|
+
- 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
|