lavish-axi 0.1.40 → 0.1.42
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 +19 -17
- package/dist/chrome-client.js +1 -0
- package/dist/cli.mjs +64 -32
- package/dist/whiteboard/whiteboard.js +438 -436
- package/package.json +1 -1
- package/skills/lavish/SKILL.md +10 -4
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,9 @@ 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.
|
|
163
|
-
-
|
|
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.
|
|
164
|
+
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.
|
|
165
|
+
- **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
166
|
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
167
|
Agent-initiated ends keep reopening normally, same as before.
|
|
166
168
|
`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 +184,20 @@ pnpm link
|
|
|
182
184
|
|
|
183
185
|
## CLI Reference
|
|
184
186
|
|
|
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.
|
|
187
|
+
| Command | Description |
|
|
188
|
+
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
189
|
+
| `lavish-axi` | Show current sessions and usage guidance. |
|
|
190
|
+
| `lavish-axi update` | Check for or apply the latest npm release through the AXI SDK self-updater. |
|
|
191
|
+
| `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. |
|
|
192
|
+
| `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. |
|
|
193
|
+
| `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. |
|
|
194
|
+
| `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. |
|
|
195
|
+
| `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. |
|
|
196
|
+
| `lavish-axi stop` | Shut down the background server. |
|
|
197
|
+
| `lavish-axi playbook [id]` | List focused artifact guidance or show one playbook; agents must open each matching playbook before writing HTML. |
|
|
198
|
+
| `lavish-axi design` | Show agent-facing design guidance, including optional CDN and Mermaid snippets. |
|
|
199
|
+
| `lavish-axi setup hooks` | Install or repair optional SessionStart hooks for Claude Code, Codex, OpenCode, and GitHub Copilot CLI; restart the agent session afterward. |
|
|
200
|
+
| `lavish-axi server` | Run the local Lavish Editor server. |
|
|
199
201
|
|
|
200
202
|
Known playbook IDs: `diagram`, `table`, `comparison`, `plan`, `code`, `input`, `slides`.
|
|
201
203
|
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,29 @@ 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_WAKE_PATH_RULES = Object.freeze([
|
|
6944
|
+
"Keep the poll in the foreground by default and let it return the feedback directly to the agent.",
|
|
6945
|
+
"A background poll is allowed only through a harness-native tracked background-job facility whose completion result is guaranteed to resume or notify the same agent.",
|
|
6946
|
+
"Never use `nohup`, shell `&`, `disown`, redirected fire-and-forget processes, or a detached terminal without an explicit verified callback merely to keep polling alive.",
|
|
6947
|
+
"If the harness has no completion-aware background facility, use the foreground poll or first wire a verified wake callback into the surrounding supervisor.",
|
|
6948
|
+
"Do not tell the user the artifact is being monitored until that wake path is live.",
|
|
6949
|
+
"If the poll gets killed or times out anyway, just re-run it - queued feedback is never lost."
|
|
6950
|
+
]);
|
|
6951
|
+
var POLL_SEND_AND_END_RULE = "`Send & End` ends the session. Its final feedback is still delivered once. After that response, polling stops, and the agent must not reopen the session uninvited.";
|
|
6952
|
+
var CODEX_POLL_WAKE_PATH_GUIDANCE = "Codex detected: completed background tasks may not resume Codex automatically, so keep the poll attached to the active turn.";
|
|
6953
|
+
var VERSION = "0.1.42";
|
|
6954
|
+
function detectInvokingAgent(env = process.env) {
|
|
6955
|
+
return ["CODEX_SANDBOX", "CODEX_THREAD_ID"].some((key) => Object.hasOwn(env, key)) ? "codex" : "generic";
|
|
6956
|
+
}
|
|
6957
|
+
function pollExecutionGuidance({ agent = "generic" } = {}) {
|
|
6958
|
+
const sharedGuidance = POLL_WAKE_PATH_RULES.join(" ");
|
|
6959
|
+
const agentGuidance = agent === "codex" ? ` ${CODEX_POLL_WAKE_PATH_GUIDANCE}` : "";
|
|
6960
|
+
return `${sharedGuidance}${agentGuidance}`;
|
|
6961
|
+
}
|
|
6941
6962
|
async function run(argv) {
|
|
6942
6963
|
await ensureStateDir();
|
|
6943
6964
|
const normalizedArgv = normalizeArgv(argv);
|
|
6965
|
+
const agent = detectInvokingAgent(process.env);
|
|
6944
6966
|
const isTopLevelHelp = argv.length === 1 && argv[0] === "--help";
|
|
6945
6967
|
const command = telemetryCommandName(argv);
|
|
6946
6968
|
const telemetry = initDefaultTelemetry({
|
|
@@ -6955,11 +6977,12 @@ async function run(argv) {
|
|
|
6955
6977
|
description: DESCRIPTION,
|
|
6956
6978
|
version: VERSION,
|
|
6957
6979
|
argv: isTopLevelHelp ? [] : normalizedArgv,
|
|
6958
|
-
topLevelHelp:
|
|
6980
|
+
topLevelHelp: createTopLevelHelp({ agent }),
|
|
6959
6981
|
home: async () => createHomeOutput({
|
|
6960
6982
|
bin: process.argv[1] || "lavish-axi",
|
|
6961
6983
|
sessions: isTopLevelHelp ? [] : await visibleSessions(),
|
|
6962
|
-
includeSessions: !isTopLevelHelp
|
|
6984
|
+
includeSessions: !isTopLevelHelp,
|
|
6985
|
+
agent
|
|
6963
6986
|
}),
|
|
6964
6987
|
commands: {
|
|
6965
6988
|
open: openCommand,
|
|
@@ -6973,7 +6996,7 @@ async function run(argv) {
|
|
|
6973
6996
|
export: exportCommand,
|
|
6974
6997
|
share: shareCommand
|
|
6975
6998
|
},
|
|
6976
|
-
getCommandHelp
|
|
6999
|
+
getCommandHelp: (command2) => getCommandHelp(command2, { agent })
|
|
6977
7000
|
});
|
|
6978
7001
|
telemetry.track("command", { command, status: "success" });
|
|
6979
7002
|
} catch (error) {
|
|
@@ -7008,7 +7031,7 @@ function telemetryCommandName(argv) {
|
|
|
7008
7031
|
const normalized = normalizeArgv(argv);
|
|
7009
7032
|
return normalized[0] && !normalized[0].startsWith("-") ? normalized[0] : "home";
|
|
7010
7033
|
}
|
|
7011
|
-
function createHomeOutput({ bin, sessions, includeSessions = true }) {
|
|
7034
|
+
function createHomeOutput({ bin, sessions, includeSessions = true, agent = "generic" }) {
|
|
7012
7035
|
return {
|
|
7013
7036
|
bin: collapseHomeDirectory(bin, os2.homedir()),
|
|
7014
7037
|
description: DESCRIPTION,
|
|
@@ -7032,7 +7055,7 @@ function createHomeOutput({ bin, sessions, includeSessions = true }) {
|
|
|
7032
7055
|
"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
7056
|
"Unless the user specifies another location, create HTML artifacts in the current working directory under `.lavish/`",
|
|
7034
7057
|
"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
|
-
|
|
7058
|
+
`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 })} ${POLL_SEND_AND_END_RULE}`,
|
|
7036
7059
|
'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
7060
|
"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
7061
|
"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 +7083,10 @@ function createPlaybookOutput(args) {
|
|
|
7060
7083
|
}
|
|
7061
7084
|
return { playbook };
|
|
7062
7085
|
}
|
|
7063
|
-
function createOpenOutput({ file, url, status }) {
|
|
7086
|
+
function createOpenOutput({ file, url, status, agent = "generic" }) {
|
|
7064
7087
|
return {
|
|
7065
7088
|
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.
|
|
7089
|
+
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({ 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
7090
|
};
|
|
7068
7091
|
}
|
|
7069
7092
|
function createUserEndedOpenOutput({ file, url }) {
|
|
@@ -7094,7 +7117,12 @@ async function openCommand(args) {
|
|
|
7094
7117
|
response.status = "ready";
|
|
7095
7118
|
}
|
|
7096
7119
|
}
|
|
7097
|
-
return createOpenOutput({
|
|
7120
|
+
return createOpenOutput({
|
|
7121
|
+
file: absolute,
|
|
7122
|
+
url: response.url,
|
|
7123
|
+
status: response.status || "opened",
|
|
7124
|
+
agent: detectInvokingAgent(process.env)
|
|
7125
|
+
});
|
|
7098
7126
|
}
|
|
7099
7127
|
function shouldOpenBrowser(args, env) {
|
|
7100
7128
|
return !args.includes("--no-open") && env.LAVISH_AXI_NO_OPEN !== "1";
|
|
@@ -7128,7 +7156,7 @@ ${pollInterruptedText(absolute)}
|
|
|
7128
7156
|
retries: 3,
|
|
7129
7157
|
retryDelayMs: 500
|
|
7130
7158
|
});
|
|
7131
|
-
return createPollOutput({ file: absolute, response });
|
|
7159
|
+
return createPollOutput({ file: absolute, response, agent: detectInvokingAgent(process.env) });
|
|
7132
7160
|
} finally {
|
|
7133
7161
|
waitReporter?.stop();
|
|
7134
7162
|
if (!timeoutMs) {
|
|
@@ -7165,7 +7193,7 @@ function startPollWaitReporter({
|
|
|
7165
7193
|
timer.unref?.();
|
|
7166
7194
|
return { stop: () => clearInterval(timer) };
|
|
7167
7195
|
}
|
|
7168
|
-
function createPollOutput({ file, response }) {
|
|
7196
|
+
function createPollOutput({ file, response, agent = "generic" }) {
|
|
7169
7197
|
if (response.status === "missing") {
|
|
7170
7198
|
throw new AxiError("No active Lavish Editor session for this file", "NOT_FOUND", [
|
|
7171
7199
|
`Run \`lavish-axi ${file}\` first`
|
|
@@ -7184,7 +7212,7 @@ function createPollOutput({ file, response }) {
|
|
|
7184
7212
|
dom_snapshot: response.dom_snapshot || "",
|
|
7185
7213
|
prompts: response.prompts || [],
|
|
7186
7214
|
...layoutWarnings.length > 0 ? { layout_warnings: layoutWarnings } : {},
|
|
7187
|
-
next_step: createFeedbackNextStep(file, layoutWarnings, sessionEnded, endedBy, response.prompts || [])
|
|
7215
|
+
next_step: createFeedbackNextStep(file, layoutWarnings, sessionEnded, endedBy, response.prompts || [], agent)
|
|
7188
7216
|
};
|
|
7189
7217
|
}
|
|
7190
7218
|
if (response.status === "ended") {
|
|
@@ -7198,7 +7226,7 @@ function createPollOutput({ file, response }) {
|
|
|
7198
7226
|
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
7227
|
};
|
|
7200
7228
|
}
|
|
7201
|
-
function createFeedbackNextStep(file, layoutWarnings, sessionEnded, endedBy, prompts = []) {
|
|
7229
|
+
function createFeedbackNextStep(file, layoutWarnings, sessionEnded, endedBy, prompts = [], agent = "generic") {
|
|
7202
7230
|
const count = layoutWarnings.length;
|
|
7203
7231
|
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
7232
|
if (sessionEnded) {
|
|
@@ -7209,7 +7237,7 @@ function createFeedbackNextStep(file, layoutWarnings, sessionEnded, endedBy, pro
|
|
|
7209
7237
|
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
7238
|
}
|
|
7211
7239
|
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.
|
|
7240
|
+
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
7241
|
}
|
|
7214
7242
|
function layoutWarningsPrefix(file, layoutWarnings) {
|
|
7215
7243
|
const count = layoutWarnings.length;
|
|
@@ -7749,10 +7777,11 @@ function isValueFlagToken(arg, flags) {
|
|
|
7749
7777
|
function delay(ms) {
|
|
7750
7778
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
7751
7779
|
}
|
|
7752
|
-
function getCommandHelp(command) {
|
|
7753
|
-
return
|
|
7780
|
+
function getCommandHelp(command, { agent = "generic" } = {}) {
|
|
7781
|
+
return createCommandHelp({ agent })[command] || null;
|
|
7754
7782
|
}
|
|
7755
|
-
|
|
7783
|
+
function createTopLevelHelp({ agent = "generic" } = {}) {
|
|
7784
|
+
return `lavish-axi - Lavish Editor AXI
|
|
7756
7785
|
|
|
7757
7786
|
Usage:
|
|
7758
7787
|
lavish-axi
|
|
@@ -7768,35 +7797,37 @@ Usage:
|
|
|
7768
7797
|
|
|
7769
7798
|
${DESIGN_SYSTEM_HINT}
|
|
7770
7799
|
|
|
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.
|
|
7800
|
+
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 })} ${POLL_SEND_AND_END_RULE}
|
|
7772
7801
|
|
|
7773
7802
|
`;
|
|
7774
|
-
|
|
7775
|
-
|
|
7803
|
+
}
|
|
7804
|
+
function createCommandHelp({ agent = "generic" } = {}) {
|
|
7805
|
+
return {
|
|
7806
|
+
open: `Usage: lavish-axi <html-file> [--no-open] [--no-gate] [--reopen]
|
|
7776
7807
|
|
|
7777
7808
|
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
7809
|
`,
|
|
7779
|
-
|
|
7810
|
+
poll: `Usage: lavish-axi poll <html-file> [--agent-reply "..."]
|
|
7780
7811
|
|
|
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.
|
|
7812
|
+
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({ agent })} Use --agent-reply after applying prior feedback to display your response in Lavish Editor before waiting again. ${POLL_SEND_AND_END_RULE}
|
|
7782
7813
|
`,
|
|
7783
|
-
|
|
7814
|
+
end: `Usage: lavish-axi end <html-file>
|
|
7784
7815
|
|
|
7785
7816
|
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
7817
|
`,
|
|
7787
|
-
|
|
7818
|
+
export: `Usage: lavish-axi export <html-file> [--out <path>]
|
|
7788
7819
|
|
|
7789
7820
|
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
7821
|
`,
|
|
7791
|
-
|
|
7822
|
+
share: `Usage: lavish-axi share <html-file> [--password <pw>] [--token <t>]
|
|
7792
7823
|
|
|
7793
7824
|
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
7825
|
`,
|
|
7795
|
-
|
|
7826
|
+
stop: `Usage: lavish-axi stop [--port <port>]
|
|
7796
7827
|
|
|
7797
7828
|
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
7829
|
`,
|
|
7799
|
-
|
|
7830
|
+
playbook: `Usage: lavish-axi playbook [playbook_id]
|
|
7800
7831
|
|
|
7801
7832
|
List focused artifact guidance playbooks, or show one playbook by ID. Known IDs: diagram, table, comparison, plan, code, input, slides.
|
|
7802
7833
|
|
|
@@ -7807,21 +7838,22 @@ Examples:
|
|
|
7807
7838
|
lavish-axi playbook diagram
|
|
7808
7839
|
lavish-axi playbook input
|
|
7809
7840
|
`,
|
|
7810
|
-
|
|
7841
|
+
design: `Usage: lavish-axi design
|
|
7811
7842
|
|
|
7812
7843
|
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
7844
|
`,
|
|
7814
|
-
|
|
7845
|
+
setup: `Usage: lavish-axi setup hooks
|
|
7815
7846
|
|
|
7816
7847
|
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
7848
|
`,
|
|
7818
|
-
|
|
7849
|
+
server: `Usage: lavish-axi server [--port 4387] [--verbose]
|
|
7819
7850
|
|
|
7820
7851
|
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
7852
|
|
|
7822
7853
|
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
7854
|
`
|
|
7824
|
-
};
|
|
7855
|
+
};
|
|
7856
|
+
}
|
|
7825
7857
|
|
|
7826
7858
|
// bin/lavish-axi.js
|
|
7827
7859
|
await run(process.argv.slice(2));
|