lavish-axi 0.1.27 → 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
 
@@ -143,6 +144,7 @@ pnpm link
143
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.
144
145
  Set `LAVISH_AXI_IDLE_TIMEOUT_MS=0` or `off` to disable idle self-shutdown.
145
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).
146
148
 
147
149
  ## CLI Reference
148
150
 
package/dist/cli.mjs CHANGED
@@ -474,6 +474,25 @@ import { mkdir } from "node:fs/promises";
474
474
  import os from "node:os";
475
475
  import path from "node:path";
476
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
+ }
477
496
  function stateDir() {
478
497
  return process.env.LAVISH_AXI_STATE_DIR || path.join(os.homedir(), ".lavish-axi");
479
498
  }
@@ -1229,7 +1248,9 @@ async function serve({
1229
1248
  debug = false,
1230
1249
  log = null,
1231
1250
  pollHeartbeatMs = 15e3,
1232
- idleTimeoutMs = resolveIdleTimeoutMs()
1251
+ idleTimeoutMs = resolveIdleTimeoutMs(),
1252
+ host = bindHost(),
1253
+ linkHost: linkHostName = linkHost()
1233
1254
  }) {
1234
1255
  const app = express();
1235
1256
  const store = new SessionStore(stateFile2);
@@ -1259,7 +1280,7 @@ async function serve({
1259
1280
  try {
1260
1281
  const file = await canonicalFile(req.body.file);
1261
1282
  const key = sessionKey(file);
1262
- const url = `http://${LOOPBACK_HOST}:${publicPort}/session/${key}`;
1283
+ const url = `http://${hostForUrl(linkHostName)}:${publicPort}/session/${key}`;
1263
1284
  const existing = await store.findByKey(key);
1264
1285
  const session = await store.upsertSession(file, url);
1265
1286
  if (existing?.status === "ended") {
@@ -1532,8 +1553,11 @@ data: ${JSON.stringify({ state: computePresence(req.params.key, activePolls, del
1532
1553
  app.use((error, req, res, _next) => {
1533
1554
  res.status(500).json({ error: error instanceof Error ? error.message : String(error) });
1534
1555
  });
1535
- const httpServer = await new Promise((resolve) => {
1536
- const s = app.listen(port, LOOPBACK_HOST, () => resolve(s));
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);
1537
1561
  });
1538
1562
  publicPort = httpServer.address().port;
1539
1563
  let shuttingDown = false;
@@ -1947,7 +1971,7 @@ function normalizePagePath(path5) {
1947
1971
  // src/cli.js
1948
1972
  var COMMANDS = /* @__PURE__ */ new Set(["open", "poll", "end", "stop", "server", "playbook", "design", "setup"]);
1949
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`.";
1950
- var VERSION = "0.1.27";
1974
+ var VERSION = "0.1.28";
1951
1975
  async function run(argv) {
1952
1976
  await ensureStateDir();
1953
1977
  const normalizedArgv = normalizeArgv(argv);
@@ -2195,11 +2219,11 @@ async function endCommand(args) {
2195
2219
  }
2196
2220
  async function stopCommand(args) {
2197
2221
  const port = Number(flagValue(args, "--port") || defaultPort());
2198
- const baseUrl = `http://${LOOPBACK_HOST}:${port}`;
2222
+ const baseUrl = `http://${hostForUrl(clientHost())}:${port}`;
2199
2223
  return shutdownServerOnPort(port, { baseUrl, currentVersion: VERSION });
2200
2224
  }
2201
2225
  async function shutdownServerOnPort(port, {
2202
- baseUrl = `http://${LOOPBACK_HOST}:${port}`,
2226
+ baseUrl = `http://${hostForUrl(clientHost())}:${port}`,
2203
2227
  currentVersion = VERSION,
2204
2228
  fetchHealth: healthFetcher = fetchHealth,
2205
2229
  requestShutdown: shutdownRequester = requestShutdown,
@@ -2279,7 +2303,7 @@ function isHtmlPath(file) {
2279
2303
  }
2280
2304
  async function ensureServer({ forceRestart = false } = {}) {
2281
2305
  const port = defaultPort();
2282
- const baseUrl = `http://${LOOPBACK_HOST}:${port}`;
2306
+ const baseUrl = `http://${hostForUrl(clientHost())}:${port}`;
2283
2307
  const existing = await fetchHealth(baseUrl);
2284
2308
  if (existing && !shouldRestartServer(VERSION, existing, forceRestart)) {
2285
2309
  return baseUrl;
@@ -2543,6 +2567,8 @@ Install or repair agent SessionStart hooks for lavish-axi ambient context in Cla
2543
2567
  server: `Usage: lavish-axi server [--port 4387] [--verbose]
2544
2568
 
2545
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.
2546
2572
  `
2547
2573
  };
2548
2574
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavish-axi",
3
- "version": "0.1.27",
3
+ "version": "0.1.28",
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",
@@ -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