ltcai 9.7.0 → 9.9.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 (85) hide show
  1. package/README.md +114 -320
  2. package/docs/BENCHMARKS.md +107 -0
  3. package/docs/CHANGELOG.md +72 -0
  4. package/docs/CI_AND_RELEASE_GATES.md +106 -0
  5. package/docs/COMMUNITY_AND_PLUGINS.md +1 -1
  6. package/docs/DEVELOPMENT.md +11 -8
  7. package/docs/ONBOARDING.md +1 -1
  8. package/docs/OPERATIONS.md +15 -6
  9. package/docs/PERFORMANCE.md +9 -1
  10. package/docs/SECURITY_AUDIT.md +91 -0
  11. package/docs/TRUST_MODEL.md +1 -1
  12. package/docs/USABILITY_AUDIT.md +164 -0
  13. package/docs/WHY_LATTICE.md +1 -1
  14. package/docs/architecture.md +4 -2
  15. package/docs/kg-schema.md +1 -1
  16. package/docs/spec-vs-impl.md +8 -1
  17. package/lattice_brain/__init__.py +1 -1
  18. package/lattice_brain/graph/retrieval.py +93 -4
  19. package/lattice_brain/graph/retrieval_vector.py +43 -0
  20. package/lattice_brain/ingestion.py +399 -14
  21. package/lattice_brain/runtime/multi_agent.py +1 -1
  22. package/latticeai/__init__.py +1 -1
  23. package/latticeai/api/brain_intelligence.py +12 -0
  24. package/latticeai/api/chat.py +17 -0
  25. package/latticeai/api/chat_helpers.py +48 -0
  26. package/latticeai/api/chat_stream.py +9 -1
  27. package/latticeai/api/local_files.py +120 -2
  28. package/latticeai/api/review_queue.py +7 -0
  29. package/latticeai/core/agent.py +105 -8
  30. package/latticeai/core/agent_eval.py +222 -1
  31. package/latticeai/core/legacy_compatibility.py +1 -1
  32. package/latticeai/core/marketplace.py +1 -1
  33. package/latticeai/core/tool_governor.py +92 -1
  34. package/latticeai/core/workspace_os.py +1 -1
  35. package/latticeai/services/architecture_readiness.py +1 -1
  36. package/latticeai/services/automation_intelligence.py +151 -14
  37. package/latticeai/services/brain_intelligence.py +72 -0
  38. package/latticeai/services/change_proposals.py +165 -23
  39. package/latticeai/services/product_readiness.py +1 -1
  40. package/latticeai/services/tool_dispatch.py +33 -0
  41. package/package.json +5 -3
  42. package/scripts/bench_models.py +312 -0
  43. package/scripts/check_bundle_budget.mjs +103 -0
  44. package/scripts/check_current_release_docs.mjs +1 -1
  45. package/scripts/check_doc_status.mjs +149 -0
  46. package/scripts/generate_sbom.py +70 -0
  47. package/src-tauri/Cargo.lock +1 -1
  48. package/src-tauri/Cargo.toml +1 -1
  49. package/src-tauri/tauri.conf.json +1 -1
  50. package/static/app/asset-manifest.json +27 -11
  51. package/static/app/assets/Act-CfOPUKPs.js +2 -0
  52. package/static/app/assets/Brain-Cgkh0Hpn.js +321 -0
  53. package/static/app/assets/BrainHome-D8e3wQiW.js +3 -0
  54. package/static/app/assets/BrainSignals-BjRBA18L.js +1 -0
  55. package/static/app/assets/Capture-CQQYQ1Ga.js +1 -0
  56. package/static/app/assets/CommandPalette-pss56Mg4.js +1 -0
  57. package/static/app/assets/Library-CoI3xYJk.js +1 -0
  58. package/static/app/assets/LivingBrain-CaU_hCxQ.js +1 -0
  59. package/static/app/assets/ProductFlow-Db-1O71-.js +1 -0
  60. package/static/app/assets/System-Dfocn0zN.js +1 -0
  61. package/static/app/assets/bot-Bp2x1i6F.js +1 -0
  62. package/static/app/assets/circle-check-CyGal42W.js +1 -0
  63. package/static/app/assets/cpu-DQFk82hG.js +1 -0
  64. package/static/app/assets/download-C70gKQVi.js +1 -0
  65. package/static/app/assets/folder-open-DNGytsVw.js +1 -0
  66. package/static/app/assets/hard-drive-CYo_bEl4.js +1 -0
  67. package/static/app/assets/i18n-BBMJshCW.js +7 -0
  68. package/static/app/assets/index-BjaXCeOZ.js +10 -0
  69. package/static/app/assets/{index-85wQvEie.css → index-BqRcLZR3.css} +1 -1
  70. package/static/app/assets/input-ChWD-Fsh.js +1 -0
  71. package/static/app/assets/navigation-D9D9_FPC.js +1 -0
  72. package/static/app/assets/network-DzLDGmtV.js +1 -0
  73. package/static/app/assets/primitives-CmaSAyGG.js +1 -0
  74. package/static/app/assets/sparkles-DXiaM1NS.js +1 -0
  75. package/static/app/assets/textarea-CV43-o79.js +1 -0
  76. package/static/app/index.html +4 -2
  77. package/static/sw.js +1 -1
  78. package/static/app/assets/Act-B6c39ays.js +0 -2
  79. package/static/app/assets/Brain-D7Qg4k6M.js +0 -321
  80. package/static/app/assets/Capture-VF_di68r.js +0 -1
  81. package/static/app/assets/Library-D_Gis2PA.js +0 -1
  82. package/static/app/assets/System-C5s5H2ov.js +0 -1
  83. package/static/app/assets/index-DJC_2oub.js +0 -18
  84. package/static/app/assets/primitives-DL4Nip8C.js +0 -1
  85. package/static/app/assets/textarea-woZfCXHy.js +0 -1
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+ // Guards the initial JavaScript payload of the /app SPA so heavy features stay
3
+ // behind lazy boundaries. It measures the entry chunk plus its transitive
4
+ // STATIC import closure (what a browser must download before first paint),
5
+ // gzips each file, and fails if the total exceeds the budget.
6
+ //
7
+ // The dynamic import() chunks (pages, onboarding, conversation home, command
8
+ // palette) are intentionally excluded — they are fetched on demand.
9
+ //
10
+ // The check builds into an isolated temp dir so it reads Vite's rich manifest
11
+ // (with `isEntry`/`imports`) without clobbering the production `static/app`
12
+ // manifest, which `build_frontend_assets.mjs` rewrites into a flat runtime map.
13
+ import { existsSync, readFileSync, rmSync } from "node:fs";
14
+ import { gzipSync } from "node:zlib";
15
+ import { join } from "node:path";
16
+ import { spawnSync } from "node:child_process";
17
+
18
+ const repo = join(import.meta.dirname, "..");
19
+ const outDir = join(repo, "node_modules", ".cache", "bundle-budget");
20
+ const manifestPath = join(outDir, "asset-manifest.json");
21
+
22
+ // Budget for the initial static JS closure, in gzipped bytes. Set below the
23
+ // pre-split baseline (632.9 kB raw / ~180 kB gzip single chunk) to lock in the
24
+ // code-splitting win and catch regressions that pull heavy code back onto the
25
+ // first-paint path. Raise it only with a deliberate, reviewed reason.
26
+ const INITIAL_JS_GZIP_BUDGET = 153_600; // 150 KiB
27
+
28
+ function build() {
29
+ rmSync(outDir, { recursive: true, force: true });
30
+ const result = spawnSync(
31
+ "npx",
32
+ ["vite", "build", "--outDir", outDir, "--emptyOutDir"],
33
+ { cwd: repo, encoding: "utf8", stdio: ["ignore", "ignore", "inherit"] },
34
+ );
35
+ if (result.status !== 0) {
36
+ console.error("bundle budget: vite build failed");
37
+ process.exit(1);
38
+ }
39
+ if (!existsSync(manifestPath)) {
40
+ console.error("bundle budget: manifest missing after build");
41
+ process.exit(1);
42
+ }
43
+ }
44
+
45
+ function measure() {
46
+ const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
47
+ const entryKey = Object.keys(manifest).find((key) => manifest[key].isEntry);
48
+ if (!entryKey) {
49
+ console.error("bundle budget: no entry chunk in manifest");
50
+ process.exit(1);
51
+ }
52
+
53
+ const seen = new Set();
54
+ const walk = (key) => {
55
+ if (seen.has(key) || !manifest[key]) return;
56
+ seen.add(key);
57
+ for (const imp of manifest[key].imports || []) walk(imp);
58
+ };
59
+ walk(entryKey);
60
+
61
+ const rows = [];
62
+ let rawTotal = 0;
63
+ let gzipTotal = 0;
64
+ for (const key of seen) {
65
+ const chunk = manifest[key];
66
+ if (!chunk?.file || !chunk.file.endsWith(".js")) continue;
67
+ const buffer = readFileSync(join(outDir, chunk.file));
68
+ const gzip = gzipSync(buffer).length;
69
+ rawTotal += buffer.length;
70
+ gzipTotal += gzip;
71
+ rows.push({ file: chunk.file, raw: buffer.length, gzip });
72
+ }
73
+ rows.sort((a, b) => b.gzip - a.gzip);
74
+
75
+ const lazyChunks = Object.values(manifest)
76
+ .filter((chunk) => chunk?.file?.endsWith(".js") && !seen.has(chunk.name ?? ""))
77
+ .filter((chunk) => !rows.some((row) => row.file === chunk.file));
78
+
79
+ return { rows, rawTotal, gzipTotal, lazyCount: lazyChunks.length };
80
+ }
81
+
82
+ const kib = (bytes) => `${(bytes / 1024).toFixed(1)} KiB`;
83
+
84
+ build();
85
+ const { rows, rawTotal, gzipTotal, lazyCount } = measure();
86
+ rmSync(outDir, { recursive: true, force: true });
87
+
88
+ console.log("Initial static JS (entry + static imports):");
89
+ for (const row of rows) {
90
+ console.log(` ${row.file.padEnd(40)} raw ${kib(row.raw).padStart(11)} gzip ${kib(row.gzip).padStart(11)}`);
91
+ }
92
+ console.log(` ${"TOTAL".padEnd(40)} raw ${kib(rawTotal).padStart(11)} gzip ${kib(gzipTotal).padStart(11)}`);
93
+ console.log(`Budget (initial JS gzip): ${kib(INITIAL_JS_GZIP_BUDGET)}`);
94
+ console.log(`Lazy JS chunks kept off first paint: ${lazyCount}`);
95
+
96
+ if (gzipTotal > INITIAL_JS_GZIP_BUDGET) {
97
+ console.error(
98
+ `\nbundle budget: FAIL — initial JS ${kib(gzipTotal)} gzip exceeds budget ${kib(INITIAL_JS_GZIP_BUDGET)}.\n`
99
+ + "Move heavy modules behind React.lazy/dynamic import() or justify a budget bump.",
100
+ );
101
+ process.exit(1);
102
+ }
103
+ console.log(`\nbundle budget: PASS — initial JS ${kib(gzipTotal)} gzip within ${kib(INITIAL_JS_GZIP_BUDGET)}.`);
@@ -6,7 +6,7 @@ const root = process.cwd();
6
6
  const pkg = JSON.parse(readFileSync(path.join(root, "package.json"), "utf8"));
7
7
  const version = pkg.version;
8
8
  const releaseDir = `output/release/v${version}`;
9
- const releaseTheme = "Proactive Hybrid Brain";
9
+ const releaseTheme = "Fail-Closed Trust";
10
10
  const title = `${version} — ${releaseTheme}`;
11
11
  const escapedVersion = version.replaceAll(".", "\\.");
12
12
 
@@ -0,0 +1,149 @@
1
+ // Repo-wide documentation status + link gate.
2
+ //
3
+ // Companion to scripts/check_current_release_docs.mjs (which pins the fixed set
4
+ // of current-release files). This script widens coverage to every Markdown doc:
5
+ //
6
+ // 1. Every relative Markdown link under the root canonical docs and docs/**
7
+ // must resolve to a file inside the repo.
8
+ // 2. Docs are classified by an explicit status badge:
9
+ // > **Status: canonical** (or `> Status: canonical`)
10
+ // > **Status: reference**
11
+ // > **Status: historical**
12
+ // Canonical docs are asserted to track the current package version and
13
+ // carry no stale "Current release" marker. Reference/historical (and
14
+ // unbadged) docs are allowed to preserve their point-in-time versions, so
15
+ // snapshots do not have to be rewritten every release.
16
+ //
17
+ // It intentionally does not force a badge onto every doc; unbadged docs are
18
+ // link-checked only. Add a `> **Status: ...**` badge when a doc should be held
19
+ // to (or exempted from) the current-version assertion.
20
+
21
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
22
+ import path from "node:path";
23
+ import process from "node:process";
24
+
25
+ const root = process.cwd();
26
+ const pkg = JSON.parse(readFileSync(path.join(root, "package.json"), "utf8"));
27
+ const version = pkg.version;
28
+ const escapedVersion = version.replaceAll(".", "\\.");
29
+
30
+ const rootCanonicalDocs = [
31
+ "README.md",
32
+ "ARCHITECTURE.md",
33
+ "FEATURE_STATUS.md",
34
+ "SECURITY.md",
35
+ "PRIVACY.md",
36
+ "AGENTS.md",
37
+ ];
38
+
39
+ const errors = [];
40
+
41
+ function walkMarkdown(dir) {
42
+ const out = [];
43
+ if (!existsSync(dir)) return out;
44
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
45
+ const full = path.join(dir, entry.name);
46
+ if (entry.isDirectory()) {
47
+ out.push(...walkMarkdown(full));
48
+ } else if (entry.isFile() && entry.name.endsWith(".md")) {
49
+ out.push(full);
50
+ }
51
+ }
52
+ return out;
53
+ }
54
+
55
+ function collectDocs() {
56
+ const files = new Set();
57
+ for (const rel of rootCanonicalDocs) {
58
+ const full = path.join(root, rel);
59
+ if (existsSync(full)) files.add(full);
60
+ }
61
+ for (const full of walkMarkdown(path.join(root, "docs"))) {
62
+ files.add(full);
63
+ }
64
+ return [...files].sort();
65
+ }
66
+
67
+ function isExternal(target) {
68
+ return /^(https?:|mailto:|tel:)/i.test(target);
69
+ }
70
+
71
+ function relativeLinks(markdown) {
72
+ const out = [];
73
+ const linkPattern = /!?\[[^\]]*\]\(([^)]+)\)/g;
74
+ let match;
75
+ while ((match = linkPattern.exec(markdown))) {
76
+ out.push(match[1].trim());
77
+ }
78
+ return out;
79
+ }
80
+
81
+ function checkLinks(file, markdown) {
82
+ for (const raw of relativeLinks(markdown)) {
83
+ const hash = raw.indexOf("#");
84
+ let target = (hash >= 0 ? raw.slice(0, hash) : raw).trim();
85
+ target = target.replace(/^<|>$/g, "").trim();
86
+ if (!target || isExternal(target)) continue;
87
+ const resolved = path.resolve(path.dirname(file), decodeURIComponent(target));
88
+ const rel = path.relative(root, file);
89
+ if (!resolved.startsWith(root)) {
90
+ errors.push(`${rel}: link points outside repo: ${raw}`);
91
+ continue;
92
+ }
93
+ if (!existsSync(resolved)) {
94
+ errors.push(`${rel}: missing link target: ${raw}`);
95
+ }
96
+ }
97
+ }
98
+
99
+ function statusOf(markdown) {
100
+ const match = markdown.match(
101
+ />\s*\*{0,2}Status:\*{0,2}\s*(canonical|reference|historical)\b/i,
102
+ );
103
+ return match ? match[1].toLowerCase() : null;
104
+ }
105
+
106
+ function checkCanonicalVersion(file, markdown) {
107
+ const rel = path.relative(root, file);
108
+ const stale = markdown.match(
109
+ new RegExp(`Current release:\\s+\\*\\*(?!${escapedVersion}\\b)[^*]+\\*\\*`, "i"),
110
+ );
111
+ if (stale) {
112
+ errors.push(`${rel}: canonical doc has stale current-release marker ${JSON.stringify(stale[0])}`);
113
+ }
114
+ if (!markdown.includes(version)) {
115
+ errors.push(`${rel}: canonical doc does not reference current version ${version}`);
116
+ }
117
+ }
118
+
119
+ const docs = collectDocs();
120
+ let canonical = 0;
121
+ let reference = 0;
122
+ let historical = 0;
123
+
124
+ for (const file of docs) {
125
+ const markdown = readFileSync(file, "utf8");
126
+ checkLinks(file, markdown);
127
+ const status = statusOf(markdown);
128
+ if (status === "canonical") {
129
+ canonical += 1;
130
+ checkCanonicalVersion(file, markdown);
131
+ } else if (status === "reference") {
132
+ reference += 1;
133
+ } else if (status === "historical") {
134
+ historical += 1;
135
+ }
136
+ }
137
+
138
+ if (errors.length) {
139
+ console.error("Documentation status/link check failed:");
140
+ for (const error of errors) {
141
+ console.error(`- ${error}`);
142
+ }
143
+ process.exit(1);
144
+ }
145
+
146
+ console.log(
147
+ `Documentation status/link check passed: ${docs.length} docs scanned ` +
148
+ `(${canonical} canonical @ ${version}, ${reference} reference, ${historical} historical).`,
149
+ );
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env python3
2
+ """Generate CycloneDX SBOMs for the Python and npm dependency trees.
3
+
4
+ Thin, dependency-light wrapper so the same artifacts can be produced locally
5
+ and in CI (.github/workflows/dependency-audit.yml). Python SBOM uses pip-audit
6
+ (``pip install pip-audit``); npm SBOM uses ``npm sbom`` (npm >= 9).
7
+
8
+ Usage:
9
+ .venv/bin/python scripts/generate_sbom.py --out-dir dist/sbom
10
+ Each generator is best-effort: a missing tool is reported, not fatal, so one
11
+ ecosystem's absence never blocks the other.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import argparse
17
+ import subprocess
18
+ import sys
19
+ from pathlib import Path
20
+
21
+
22
+ def _run(cmd: list[str], *, stdout_path: Path | None = None) -> tuple[bool, str]:
23
+ try:
24
+ proc = subprocess.run(cmd, capture_output=True, text=True, check=False)
25
+ except FileNotFoundError as exc:
26
+ return False, f"tool not found: {exc}"
27
+ if proc.returncode != 0:
28
+ return False, (proc.stderr or proc.stdout or "").strip()[:400]
29
+ if stdout_path is not None:
30
+ stdout_path.write_text(proc.stdout, encoding="utf-8")
31
+ return True, ""
32
+
33
+
34
+ def main(argv: list[str] | None = None) -> int:
35
+ parser = argparse.ArgumentParser(description="Generate CycloneDX SBOMs")
36
+ parser.add_argument("--out-dir", default="dist/sbom", help="output directory")
37
+ parser.add_argument("--requirements", default="requirements.txt")
38
+ args = parser.parse_args(argv)
39
+
40
+ root = Path(__file__).resolve().parent.parent
41
+ out = Path(args.out_dir)
42
+ out.mkdir(parents=True, exist_ok=True)
43
+
44
+ results: list[tuple[str, bool, str]] = []
45
+
46
+ py_sbom = out / "sbom-python.json"
47
+ ok, err = _run(
48
+ [
49
+ sys.executable, "-m", "pip_audit",
50
+ "-r", str(root / args.requirements),
51
+ "-f", "cyclonedx-json",
52
+ "-o", str(py_sbom),
53
+ ]
54
+ )
55
+ results.append(("python (pip-audit)", ok, err or str(py_sbom)))
56
+
57
+ npm_sbom = out / "sbom-npm.json"
58
+ ok, err = _run(["npm", "sbom", "--sbom-format", "cyclonedx"], stdout_path=npm_sbom)
59
+ results.append(("npm (npm sbom)", ok, err or str(npm_sbom)))
60
+
61
+ print("SBOM generation:")
62
+ any_ok = False
63
+ for name, ok, detail in results:
64
+ print(f" [{'OK' if ok else 'SKIP'}] {name}: {detail}")
65
+ any_ok = any_ok or ok
66
+ return 0 if any_ok else 1
67
+
68
+
69
+ if __name__ == "__main__":
70
+ raise SystemExit(main())
@@ -1584,7 +1584,7 @@ dependencies = [
1584
1584
 
1585
1585
  [[package]]
1586
1586
  name = "lattice-ai-desktop"
1587
- version = "9.7.0"
1587
+ version = "9.9.0"
1588
1588
  dependencies = [
1589
1589
  "plist",
1590
1590
  "serde",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "lattice-ai-desktop"
3
- version = "9.7.0"
3
+ version = "9.9.0"
4
4
  description = "Lattice AI Digital Brain desktop shell"
5
5
  authors = ["TaeSoo Park"]
6
6
  edition = "2021"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://schema.tauri.app/config/2",
3
3
  "productName": "Lattice AI",
4
- "version": "9.7.0",
4
+ "version": "9.9.0",
5
5
  "identifier": "ai.lattice.desktop",
6
6
  "build": {
7
7
  "beforeDevCommand": "npm run frontend:dev",
@@ -1,19 +1,35 @@
1
1
  {
2
- "version": "9.7.0",
2
+ "version": "9.9.0",
3
3
  "generated_at": "vite",
4
4
  "entrypoints": {
5
- "app": "/static/app/assets/index-DJC_2oub.js"
5
+ "app": "/static/app/assets/index-BjaXCeOZ.js"
6
6
  },
7
7
  "assets": {
8
8
  "../node_modules/@tauri-apps/api/core.js": "/static/app/assets/core-CwxXejkd.js",
9
- "_primitives-DL4Nip8C.js": "/static/app/assets/primitives-DL4Nip8C.js",
10
- "_textarea-woZfCXHy.js": "/static/app/assets/textarea-woZfCXHy.js",
11
- "index.html": "/static/app/assets/index-DJC_2oub.js",
12
- "assets/index-85wQvEie.css": "/static/app/assets/index-85wQvEie.css",
13
- "src/pages/Act.tsx": "/static/app/assets/Act-B6c39ays.js",
14
- "src/pages/Brain.tsx": "/static/app/assets/Brain-D7Qg4k6M.js",
15
- "src/pages/Capture.tsx": "/static/app/assets/Capture-VF_di68r.js",
16
- "src/pages/Library.tsx": "/static/app/assets/Library-D_Gis2PA.js",
17
- "src/pages/System.tsx": "/static/app/assets/System-C5s5H2ov.js"
9
+ "_BrainSignals-BjRBA18L.js": "/static/app/assets/BrainSignals-BjRBA18L.js",
10
+ "_LivingBrain-CaU_hCxQ.js": "/static/app/assets/LivingBrain-CaU_hCxQ.js",
11
+ "_bot-Bp2x1i6F.js": "/static/app/assets/bot-Bp2x1i6F.js",
12
+ "_circle-check-CyGal42W.js": "/static/app/assets/circle-check-CyGal42W.js",
13
+ "_cpu-DQFk82hG.js": "/static/app/assets/cpu-DQFk82hG.js",
14
+ "_download-C70gKQVi.js": "/static/app/assets/download-C70gKQVi.js",
15
+ "_folder-open-DNGytsVw.js": "/static/app/assets/folder-open-DNGytsVw.js",
16
+ "_hard-drive-CYo_bEl4.js": "/static/app/assets/hard-drive-CYo_bEl4.js",
17
+ "_i18n-BBMJshCW.js": "/static/app/assets/i18n-BBMJshCW.js",
18
+ "_input-ChWD-Fsh.js": "/static/app/assets/input-ChWD-Fsh.js",
19
+ "_navigation-D9D9_FPC.js": "/static/app/assets/navigation-D9D9_FPC.js",
20
+ "_network-DzLDGmtV.js": "/static/app/assets/network-DzLDGmtV.js",
21
+ "_primitives-CmaSAyGG.js": "/static/app/assets/primitives-CmaSAyGG.js",
22
+ "_sparkles-DXiaM1NS.js": "/static/app/assets/sparkles-DXiaM1NS.js",
23
+ "_textarea-CV43-o79.js": "/static/app/assets/textarea-CV43-o79.js",
24
+ "index.html": "/static/app/assets/index-BjaXCeOZ.js",
25
+ "assets/index-BqRcLZR3.css": "/static/app/assets/index-BqRcLZR3.css",
26
+ "src/components/ProductFlow.tsx": "/static/app/assets/ProductFlow-Db-1O71-.js",
27
+ "src/features/brain/BrainHome.tsx": "/static/app/assets/BrainHome-D8e3wQiW.js",
28
+ "src/features/command/CommandPalette.tsx": "/static/app/assets/CommandPalette-pss56Mg4.js",
29
+ "src/pages/Act.tsx": "/static/app/assets/Act-CfOPUKPs.js",
30
+ "src/pages/Brain.tsx": "/static/app/assets/Brain-Cgkh0Hpn.js",
31
+ "src/pages/Capture.tsx": "/static/app/assets/Capture-CQQYQ1Ga.js",
32
+ "src/pages/Library.tsx": "/static/app/assets/Library-CoI3xYJk.js",
33
+ "src/pages/System.tsx": "/static/app/assets/System-Dfocn0zN.js"
18
34
  }
19
35
  }