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