@codyswann/lisa 4.18.0 → 4.19.0

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.
Files changed (63) hide show
  1. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  2. package/dist/core/lisa-owned-hash-ledger.js +14 -0
  3. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  4. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  5. package/dist/core/upstream-evidence-manifest.js +15 -5
  6. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  7. package/expo/copy-overwrite/scripts/bdd/baseline.mjs +10 -2
  8. package/expo/copy-overwrite/scripts/bdd/render.mjs +3 -2
  9. package/expo/copy-overwrite/scripts/bdd-matrix.mjs +3 -3
  10. package/package.json +7 -2
  11. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  12. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  13. package/plugins/lisa-agy/plugin.json +1 -1
  14. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  15. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  16. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  17. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  19. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  23. package/plugins/lisa-expo-agy/plugin.json +1 -1
  24. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  28. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  29. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  33. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  34. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  38. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  39. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  43. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  44. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  48. package/plugins/lisa-rails-agy/plugin.json +1 -1
  49. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  53. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  54. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  58. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  59. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  61. package/scripts/check-ui-demo-data.mjs +102 -0
  62. package/ui/README.md +32 -0
  63. package/ui/index.html +901 -115
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Evaluate the Lisa UI catalog in a code-generation-disabled VM and invoke the
5
+ * catalog's own renderer-aware audit. Keeping the audit in `ui/index.html`
6
+ * means the browser and repository guard cannot drift into different ideas of
7
+ * which values are renderable.
8
+ * @module scripts/check-ui-demo-data
9
+ */
10
+ import { readFileSync } from "node:fs";
11
+ import path from "node:path";
12
+ import vm from "node:vm";
13
+
14
+ import { invokedAsScript } from "./lib/invoked-as-script.mjs";
15
+
16
+ const START_MARKER = "/* LISA_UI_CATALOG_START */";
17
+ const END_MARKER = "/* LISA_UI_CATALOG_END */";
18
+ const DEFAULT_UI_FILE = path.resolve("ui/index.html");
19
+ const VM_TIMEOUT_MS = 2_000;
20
+
21
+ /**
22
+ * Extract exactly one bounded catalog program from the HTML document.
23
+ * @param {string} html - Complete UI HTML
24
+ * @returns {string} Catalog JavaScript including the shared audit seam
25
+ */
26
+ export function extractUiCatalogProgram(html) {
27
+ const start = html.indexOf(START_MARKER);
28
+ const end = html.indexOf(END_MARKER);
29
+ if (start === -1 || end === -1 || end <= start) {
30
+ throw new Error(
31
+ `UI catalog markers are missing or out of order (${START_MARKER}, ${END_MARKER})`
32
+ );
33
+ }
34
+ if (
35
+ html.indexOf(START_MARKER, start + START_MARKER.length) !== -1 ||
36
+ html.indexOf(END_MARKER, end + END_MARKER.length) !== -1
37
+ ) {
38
+ throw new Error("UI catalog markers must each occur exactly once");
39
+ }
40
+ return html.slice(start + START_MARKER.length, end);
41
+ }
42
+
43
+ /**
44
+ * Audit an HTML catalog and optionally exercise the live preparation path.
45
+ * @param {string} html - Complete UI HTML
46
+ * @param {{liveConfigPresent?: boolean, liveConfig?: unknown, filename?: string}} [options]
47
+ * @returns {{audit: {inspected: number, sections: number, violations: string[]}, preparation: object|null, catalog: object}}
48
+ */
49
+ export function inspectUiDemoData(html, options = {}) {
50
+ const context = vm.createContext(
51
+ {
52
+ __liveConfigPresent: options.liveConfigPresent === true,
53
+ __liveConfig: options.liveConfig,
54
+ },
55
+ {
56
+ codeGeneration: { strings: false, wasm: false },
57
+ name: "lisa-ui-demo-data-audit",
58
+ }
59
+ );
60
+ const program = `${extractUiCatalogProgram(html)}
61
+ const __auditResult = auditUiCatalog(DATA);
62
+ const __preparationResult = globalThis.__liveConfigPresent
63
+ ? prepareUiCatalogForLive(DATA, globalThis.__liveConfig)
64
+ : null;
65
+ globalThis.__inspectionResult = {
66
+ audit: __auditResult,
67
+ preparation: __preparationResult,
68
+ catalog: DATA
69
+ };
70
+ `;
71
+ // The bounded catalog source is intentionally executed in a context with
72
+ // string/wasm code generation disabled and a hard timeout. This is the
73
+ // guard's shared-seam contract, not application input.
74
+ // eslint-disable-next-line sonarjs/code-eval -- Evaluate only the extracted catalog inside the locked VM above.
75
+ vm.runInContext(program, context, {
76
+ displayErrors: true,
77
+ filename: options.filename || "ui/index.html#catalog",
78
+ timeout: VM_TIMEOUT_MS,
79
+ });
80
+ return context.__inspectionResult;
81
+ }
82
+
83
+ /** Run the repository guard against a supplied file or the real UI. */
84
+ function main() {
85
+ const file = path.resolve(process.argv[2] || DEFAULT_UI_FILE);
86
+ try {
87
+ const inspection = inspectUiDemoData(readFileSync(file, "utf8"), {
88
+ filename: file,
89
+ });
90
+ process.stdout.write(
91
+ `[ui-demo-data] PASS: inspected ${inspection.audit.inspected} rendered values across ${inspection.audit.sections} sections\n`
92
+ );
93
+ } catch (error) {
94
+ const message = error instanceof Error ? error.message : String(error);
95
+ process.stderr.write(`[ui-demo-data] FAIL: ${message}\n`);
96
+ process.exitCode = 1;
97
+ }
98
+ }
99
+
100
+ if (invokedAsScript(import.meta.url)) {
101
+ main();
102
+ }
package/ui/README.md CHANGED
@@ -30,6 +30,38 @@ live config it falls back to Lisa's shipped defaults:
30
30
  open ui/index.html
31
31
  ```
32
32
 
33
+ ## Demo-data boundary
34
+
35
+ The standalone and CLI-served paths deliberately have different data
36
+ contracts. Opening `ui/index.html` directly leaves
37
+ `window.LISA_LIVE_CONFIG` absent and renders the fictional demo catalog. The
38
+ CLI defines that property before the page boots, so the console enters live
39
+ mode even when the injected value is `false`, `0`, an empty string, or `null`.
40
+ Live mode scrubs every `demoOnly` block and row before the first render, keeps
41
+ present falsey configuration values, turns missing configuration keys into
42
+ `unknown`, and initializes probe/API values as pending or unknown. An empty
43
+ live section and a filter with no matches both render a generic empty/unknown
44
+ state; neither falls back to a demo value on a later render.
45
+
46
+ Every renderer-bearing catalog value must declare exactly one provenance:
47
+
48
+ - `key` for a value hydrated from `LISA_LIVE_CONFIG`;
49
+ - `liveSource` for a probe, API, or injected live snapshot;
50
+ - `demoOnly: true` for intentional direct-file sample data; or
51
+ - `staticCopy` with a narrow reason for fixed Lisa documentation or semantics.
52
+
53
+ The browser and repository guard invoke the same renderer-aware catalog audit.
54
+ It discovers the current sections and values rather than relying on a hardcoded
55
+ count, fails on unclassified or multiply classified values, and fails if it
56
+ inspects nothing. Run it after adding or changing console data:
57
+
58
+ ```bash
59
+ bun run check:ui-demo-data
60
+ ```
61
+
62
+ `acme/acme-app` is not a forbidden string: a live project can legitimately use
63
+ that name. The boundary is provenance, not a sentinel grep.
64
+
33
65
  ## Config write contract (`POST /api/config`)
34
66
 
35
67
  The same-origin endpoint classifies the complete request before reading either