lavish-axi 0.1.26 → 0.1.28
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
|
+
Its frontmatter also includes Hermes Agent metadata, so Hermes-compatible harnesses can categorize and surface it as a first-class productivity skill.
|
|
56
57
|
|
|
57
58
|
Then, in agents that expose skills as slash commands (Claude Code, for example), invoke it directly:
|
|
58
59
|
|
|
@@ -127,7 +128,10 @@ pnpm link
|
|
|
127
128
|
```
|
|
128
129
|
|
|
129
130
|
- **File-path identity** - Sessions are keyed by the canonical HTML file path, so agents do not need opaque IDs.
|
|
130
|
-
- **Portable artifacts** - The artifact runs in an iframe while Lavish injects a small SDK for annotations, snapshots, and feedback controls.
|
|
131
|
+
- **Portable artifacts** - The artifact runs in an iframe while Lavish injects a small SDK for annotations, snapshots, and feedback controls.
|
|
132
|
+
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.
|
|
133
|
+
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.
|
|
134
|
+
That fallback guidance recommends DaisyUI's `luxury` theme by default and warns not to `@apply` DaisyUI classes inside Tailwind browser-runtime style blocks.
|
|
131
135
|
- **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.
|
|
132
136
|
- **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">`.
|
|
133
137
|
- **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.
|
|
@@ -140,6 +144,7 @@ pnpm link
|
|
|
140
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.
|
|
141
145
|
Set `LAVISH_AXI_IDLE_TIMEOUT_MS=0` or `off` to disable idle self-shutdown.
|
|
142
146
|
- **Local-first state** - Session state stays under `.lavish-axi/` in the workspace.
|
|
147
|
+
- **Network binding** - The server binds to loopback (`127.0.0.1`) by default. Set `LAVISH_AXI_HOST` to bind elsewhere; 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. Set `LAVISH_AXI_LINK_HOST` to control the hostname written into generated session links (defaults to the bind address, or loopback when bound to a wildcard).
|
|
143
148
|
|
|
144
149
|
## CLI Reference
|
|
145
150
|
|
|
@@ -151,7 +156,7 @@ pnpm link
|
|
|
151
156
|
| `lavish-axi end <html-file>` | End a session. |
|
|
152
157
|
| `lavish-axi stop` | Shut down the background server. |
|
|
153
158
|
| `lavish-axi playbook [id]` | List focused artifact guidance or show one playbook. |
|
|
154
|
-
| `lavish-axi design` | Show the Tailwind + DaisyUI CDN fallback
|
|
159
|
+
| `lavish-axi design` | Show the Tailwind + DaisyUI CDN fallback, including the `luxury` default theme and DaisyUI `@apply` warning. |
|
|
155
160
|
| `lavish-axi setup hooks` | Install or repair optional SessionStart hooks for Claude Code, Codex, and OpenCode; restart the agent session afterward. |
|
|
156
161
|
| `lavish-axi server` | Run the local Lavish Editor server. |
|
|
157
162
|
|
package/dist/cli.mjs
CHANGED
|
@@ -70,11 +70,12 @@ function createDesignOutput() {
|
|
|
70
70
|
other_design_systems: "If the user asks for a different design system (Bootstrap, custom CSS, plain HTML, etc.), use that instead - Lavish does not require DaisyUI."
|
|
71
71
|
},
|
|
72
72
|
theme_usage: [
|
|
73
|
-
'
|
|
73
|
+
'Default to `<html data-theme="luxury">` - it matches the Lavish look. Pick a different theme from the list below only when the user asked for one or the content clearly calls for it.',
|
|
74
74
|
'Set a nested section theme with `<section data-theme="night">`.',
|
|
75
75
|
"Prefer semantic colors such as `bg-base-100`, `bg-base-200`, `text-base-content`, `bg-primary`, `text-primary-content`, `alert-warning`, and `btn-primary` so themes remain readable.",
|
|
76
76
|
"Avoid hardcoded Tailwind color names for text and surfaces unless the user asked for exact colors.",
|
|
77
|
-
"Use Tailwind responsive prefixes such as `sm:`, `md:`, `lg:`, and `xl:` for layout changes."
|
|
77
|
+
"Use Tailwind responsive prefixes such as `sm:`, `md:`, `lg:`, and `xl:` for layout changes.",
|
|
78
|
+
'Never `@apply` DaisyUI classes (such as `text-base-content/40`, `bg-base-200`, or `btn`) inside `<style type="text/tailwindcss">` - the Tailwind browser runtime does not know them, and one unknown utility aborts the entire compile, leaving the page with no Tailwind styles at all. Put DaisyUI classes directly on elements, or write plain CSS with theme variables such as `var(--color-base-200)`.'
|
|
78
79
|
],
|
|
79
80
|
themes: DAISYUI_THEMES,
|
|
80
81
|
components: {
|
|
@@ -473,6 +474,25 @@ import { mkdir } from "node:fs/promises";
|
|
|
473
474
|
import os from "node:os";
|
|
474
475
|
import path from "node:path";
|
|
475
476
|
var LOOPBACK_HOST = "127.0.0.1";
|
|
477
|
+
var IPV6_LOOPBACK_HOST = "::1";
|
|
478
|
+
var WILDCARD_BIND_LOOPBACK = /* @__PURE__ */ new Map([
|
|
479
|
+
["0.0.0.0", LOOPBACK_HOST],
|
|
480
|
+
["::", IPV6_LOOPBACK_HOST]
|
|
481
|
+
]);
|
|
482
|
+
function bindHost(env = process.env) {
|
|
483
|
+
return env.LAVISH_AXI_HOST?.trim() || LOOPBACK_HOST;
|
|
484
|
+
}
|
|
485
|
+
function clientHost(env = process.env) {
|
|
486
|
+
const host = bindHost(env);
|
|
487
|
+
return WILDCARD_BIND_LOOPBACK.get(host) ?? host;
|
|
488
|
+
}
|
|
489
|
+
function linkHost(env = process.env) {
|
|
490
|
+
return env.LAVISH_AXI_LINK_HOST?.trim() || clientHost(env);
|
|
491
|
+
}
|
|
492
|
+
function hostForUrl(host) {
|
|
493
|
+
if (host.includes(":") && !host.startsWith("[")) return `[${host}]`;
|
|
494
|
+
return host;
|
|
495
|
+
}
|
|
476
496
|
function stateDir() {
|
|
477
497
|
return process.env.LAVISH_AXI_STATE_DIR || path.join(os.homedir(), ".lavish-axi");
|
|
478
498
|
}
|
|
@@ -1228,7 +1248,9 @@ async function serve({
|
|
|
1228
1248
|
debug = false,
|
|
1229
1249
|
log = null,
|
|
1230
1250
|
pollHeartbeatMs = 15e3,
|
|
1231
|
-
idleTimeoutMs = resolveIdleTimeoutMs()
|
|
1251
|
+
idleTimeoutMs = resolveIdleTimeoutMs(),
|
|
1252
|
+
host = bindHost(),
|
|
1253
|
+
linkHost: linkHostName = linkHost()
|
|
1232
1254
|
}) {
|
|
1233
1255
|
const app = express();
|
|
1234
1256
|
const store = new SessionStore(stateFile2);
|
|
@@ -1258,7 +1280,7 @@ async function serve({
|
|
|
1258
1280
|
try {
|
|
1259
1281
|
const file = await canonicalFile(req.body.file);
|
|
1260
1282
|
const key = sessionKey(file);
|
|
1261
|
-
const url = `http://${
|
|
1283
|
+
const url = `http://${hostForUrl(linkHostName)}:${publicPort}/session/${key}`;
|
|
1262
1284
|
const existing = await store.findByKey(key);
|
|
1263
1285
|
const session = await store.upsertSession(file, url);
|
|
1264
1286
|
if (existing?.status === "ended") {
|
|
@@ -1531,8 +1553,11 @@ data: ${JSON.stringify({ state: computePresence(req.params.key, activePolls, del
|
|
|
1531
1553
|
app.use((error, req, res, _next) => {
|
|
1532
1554
|
res.status(500).json({ error: error instanceof Error ? error.message : String(error) });
|
|
1533
1555
|
});
|
|
1534
|
-
const httpServer = await new Promise((resolve) => {
|
|
1535
|
-
const s = app.listen(port,
|
|
1556
|
+
const httpServer = await new Promise((resolve, reject) => {
|
|
1557
|
+
const s = app.listen(port, host, () => {
|
|
1558
|
+
if (s.address()) resolve(s);
|
|
1559
|
+
});
|
|
1560
|
+
s.once("error", reject);
|
|
1536
1561
|
});
|
|
1537
1562
|
publicPort = httpServer.address().port;
|
|
1538
1563
|
let shuttingDown = false;
|
|
@@ -1946,7 +1971,7 @@ function normalizePagePath(path5) {
|
|
|
1946
1971
|
// src/cli.js
|
|
1947
1972
|
var COMMANDS = /* @__PURE__ */ new Set(["open", "poll", "end", "stop", "server", "playbook", "design", "setup"]);
|
|
1948
1973
|
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`.";
|
|
1949
|
-
var VERSION = "0.1.
|
|
1974
|
+
var VERSION = "0.1.28";
|
|
1950
1975
|
async function run(argv) {
|
|
1951
1976
|
await ensureStateDir();
|
|
1952
1977
|
const normalizedArgv = normalizeArgv(argv);
|
|
@@ -2194,11 +2219,11 @@ async function endCommand(args) {
|
|
|
2194
2219
|
}
|
|
2195
2220
|
async function stopCommand(args) {
|
|
2196
2221
|
const port = Number(flagValue(args, "--port") || defaultPort());
|
|
2197
|
-
const baseUrl = `http://${
|
|
2222
|
+
const baseUrl = `http://${hostForUrl(clientHost())}:${port}`;
|
|
2198
2223
|
return shutdownServerOnPort(port, { baseUrl, currentVersion: VERSION });
|
|
2199
2224
|
}
|
|
2200
2225
|
async function shutdownServerOnPort(port, {
|
|
2201
|
-
baseUrl = `http://${
|
|
2226
|
+
baseUrl = `http://${hostForUrl(clientHost())}:${port}`,
|
|
2202
2227
|
currentVersion = VERSION,
|
|
2203
2228
|
fetchHealth: healthFetcher = fetchHealth,
|
|
2204
2229
|
requestShutdown: shutdownRequester = requestShutdown,
|
|
@@ -2278,7 +2303,7 @@ function isHtmlPath(file) {
|
|
|
2278
2303
|
}
|
|
2279
2304
|
async function ensureServer({ forceRestart = false } = {}) {
|
|
2280
2305
|
const port = defaultPort();
|
|
2281
|
-
const baseUrl = `http://${
|
|
2306
|
+
const baseUrl = `http://${hostForUrl(clientHost())}:${port}`;
|
|
2282
2307
|
const existing = await fetchHealth(baseUrl);
|
|
2283
2308
|
if (existing && !shouldRestartServer(VERSION, existing, forceRestart)) {
|
|
2284
2309
|
return baseUrl;
|
|
@@ -2542,6 +2567,8 @@ Install or repair agent SessionStart hooks for lavish-axi ambient context in Cla
|
|
|
2542
2567
|
server: `Usage: lavish-axi server [--port 4387] [--verbose]
|
|
2543
2568
|
|
|
2544
2569
|
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.
|
|
2570
|
+
|
|
2571
|
+
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.
|
|
2545
2572
|
`
|
|
2546
2573
|
};
|
|
2547
2574
|
|
|
Binary file
|
package/package.json
CHANGED
package/skills/lavish/SKILL.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
name: lavish
|
|
3
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
4
|
argument-hint: <what the artifact should show>
|
|
5
|
+
author: Kun Chen (kunchenguid)
|
|
6
|
+
metadata:
|
|
7
|
+
hermes:
|
|
8
|
+
tags: [html, review, artifacts, visualization]
|
|
9
|
+
category: productivity
|
|
5
10
|
---
|
|
6
11
|
|
|
7
12
|
# Lavish Editor
|