ltcai 9.8.0 → 9.9.1

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 (97) hide show
  1. package/README.md +45 -28
  2. package/bin/ltcai.js +1 -1
  3. package/desktop/electron/main.cjs +1 -1
  4. package/docs/BENCHMARKS.md +107 -0
  5. package/docs/CHANGELOG.md +82 -0
  6. package/docs/CI_AND_RELEASE_GATES.md +106 -0
  7. package/docs/COMMUNITY_AND_PLUGINS.md +1 -1
  8. package/docs/DEVELOPMENT.md +11 -8
  9. package/docs/LEGACY_COMPATIBILITY.md +48 -49
  10. package/docs/ONBOARDING.md +1 -1
  11. package/docs/OPERATIONS.md +15 -6
  12. package/docs/PERFORMANCE.md +9 -1
  13. package/docs/SECURITY_AUDIT.md +91 -0
  14. package/docs/TRUST_MODEL.md +1 -1
  15. package/docs/USABILITY_AUDIT.md +164 -0
  16. package/docs/WHY_LATTICE.md +1 -1
  17. package/docs/architecture.md +4 -2
  18. package/docs/kg-schema.md +6 -6
  19. package/docs/spec-vs-impl.md +8 -1
  20. package/lattice_brain/__init__.py +1 -1
  21. package/lattice_brain/graph/schema.py +1 -1
  22. package/lattice_brain/runtime/multi_agent.py +1 -1
  23. package/latticeai/__init__.py +1 -1
  24. package/latticeai/api/review_queue.py +7 -0
  25. package/latticeai/core/agent.py +105 -8
  26. package/latticeai/core/agent_eval.py +99 -1
  27. package/latticeai/core/legacy_compatibility.py +71 -47
  28. package/latticeai/core/marketplace.py +1 -1
  29. package/latticeai/core/tool_governor.py +92 -1
  30. package/latticeai/core/workspace_os.py +1 -1
  31. package/latticeai/services/architecture_readiness.py +1 -1
  32. package/latticeai/services/change_proposals.py +165 -23
  33. package/latticeai/services/product_readiness.py +2 -2
  34. package/latticeai/services/tool_dispatch.py +33 -0
  35. package/latticeai/tools/__init__.py +1 -1
  36. package/latticeai/tools/knowledge.py +1 -1
  37. package/package.json +9 -17
  38. package/scripts/bench_models.py +312 -0
  39. package/scripts/check_bundle_budget.mjs +103 -0
  40. package/scripts/check_current_release_docs.mjs +20 -1
  41. package/scripts/check_doc_status.mjs +149 -0
  42. package/scripts/check_legacy_debt.mjs +91 -0
  43. package/scripts/generate_sbom.py +70 -0
  44. package/scripts/prune_release_evidence.mjs +38 -0
  45. package/scripts/wheel_smoke.py +22 -6
  46. package/src-tauri/Cargo.lock +1 -1
  47. package/src-tauri/Cargo.toml +1 -1
  48. package/src-tauri/src/main.rs +12 -12
  49. package/src-tauri/tauri.conf.json +1 -13
  50. package/static/app/asset-manifest.json +27 -11
  51. package/static/app/assets/Act-CcSWTQsx.js +1 -0
  52. package/static/app/assets/{Brain-BMkgdWnI.js → Brain-CSCDZEHd.js} +2 -2
  53. package/static/app/assets/BrainHome-B5QpJ1Fx.js +2 -0
  54. package/static/app/assets/BrainSignals-CmFD8PWk.js +1 -0
  55. package/static/app/assets/Capture-BiuerOio.js +1 -0
  56. package/static/app/assets/CommandPalette-BrqpT7K2.js +1 -0
  57. package/static/app/assets/Library-BcaiPbum.js +1 -0
  58. package/static/app/assets/LivingBrain-6FvA0H5T.js +1 -0
  59. package/static/app/assets/ProductFlow-Cr8bkQPw.js +1 -0
  60. package/static/app/assets/ReviewCard-D56TMypk.js +1 -0
  61. package/static/app/assets/System-D6uJacqu.js +1 -0
  62. package/static/app/assets/bot-DgC7xgUl.js +1 -0
  63. package/static/app/assets/cpu-DDGb4XHl.js +1 -0
  64. package/static/app/assets/download-C-Ei3GFa.js +1 -0
  65. package/static/app/assets/folder-open-BbVuSO9M.js +1 -0
  66. package/static/app/assets/hard-drive-yDZR6XYz.js +1 -0
  67. package/static/app/assets/index-CFRhNBuH.css +2 -0
  68. package/static/app/assets/index-DrZSkwrE.js +10 -0
  69. package/static/app/assets/input-DPIkTs9n.js +1 -0
  70. package/static/app/assets/navigation-B1mkmyUe.js +1 -0
  71. package/static/app/assets/network-0XDI1Uf_.js +1 -0
  72. package/static/app/assets/primitives-sIQYKyf5.js +1 -0
  73. package/static/app/assets/sunrise-DXMjueec.js +1 -0
  74. package/static/app/assets/textarea-DvnwpnqS.js +1 -0
  75. package/static/app/assets/utils-BrfFHAJl.js +7 -0
  76. package/static/app/index.html +4 -2
  77. package/static/sw.js +1 -1
  78. package/auto_setup.py +0 -21
  79. package/kg_schema.py +0 -13
  80. package/knowledge_graph.py +0 -51
  81. package/knowledge_graph_api.py +0 -24
  82. package/llm_router.py +0 -20
  83. package/local_knowledge_api.py +0 -16
  84. package/ltcai_cli.py +0 -21
  85. package/mcp_registry.py +0 -20
  86. package/p_reinforce.py +0 -16
  87. package/setup_wizard.py +0 -16
  88. package/static/app/assets/Act-Dd3z8AzF.js +0 -2
  89. package/static/app/assets/Capture-D2Aw9gkv.js +0 -1
  90. package/static/app/assets/Library-Yreq-KW5.js +0 -1
  91. package/static/app/assets/System-CXNmmtEo.js +0 -1
  92. package/static/app/assets/index-7gY9t9Sd.css +0 -2
  93. package/static/app/assets/index-CndfILiF.js +0 -18
  94. package/static/app/assets/primitives-DxsIXb6G.js +0 -1
  95. package/static/app/assets/textarea-DH7ne8VI.js +0 -1
  96. package/telegram_bot.py +0 -16
  97. package/tools/__init__.py +0 -29
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env node
2
+ // Legacy debt gate (9.9.1): the root shim layer stays removed.
3
+ //
4
+ // Fails when:
5
+ // 1. a Python module other than server.py appears at the repository root;
6
+ // 2. any source tree imports a removed root shim module;
7
+ // 3. a removed shim directory (tools/) reappears at the root.
8
+ //
9
+ // Mirror of tests/unit/test_legacy_root_shims.py, but static and runnable in
10
+ // `npm run lint` without a Python environment.
11
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
12
+ import { join, relative } from "node:path";
13
+
14
+ const repo = join(import.meta.dirname, "..");
15
+
16
+ const ALLOWED_ROOT_MODULES = new Set(["server.py"]);
17
+ const REMOVED_ROOT_DIRS = ["tools"];
18
+ const REMOVED_MODULES = [
19
+ "ltcai_cli",
20
+ "auto_setup",
21
+ "setup_wizard",
22
+ "mcp_registry",
23
+ "kg_schema",
24
+ "knowledge_graph",
25
+ "knowledge_graph_api",
26
+ "local_knowledge_api",
27
+ "llm_router",
28
+ "p_reinforce",
29
+ "telegram_bot",
30
+ "tools",
31
+ ];
32
+ // Trees that must not import removed shims. static/app and node_modules are
33
+ // build output; src-tauri/target is compiler output.
34
+ const SOURCE_TREES = ["latticeai", "lattice_brain", "tests", "scripts", "bin", "desktop/electron"];
35
+
36
+ const failures = [];
37
+
38
+ for (const entry of readdirSync(repo)) {
39
+ if (entry.endsWith(".py") && !ALLOWED_ROOT_MODULES.has(entry)) {
40
+ failures.push(`root module reappeared: ${entry} — put code in latticeai/ or lattice_brain/`);
41
+ }
42
+ }
43
+ for (const dir of REMOVED_ROOT_DIRS) {
44
+ if (existsSync(join(repo, dir))) {
45
+ failures.push(`removed root package reappeared: ${dir}/ — use latticeai.${dir} instead`);
46
+ }
47
+ }
48
+
49
+ const modulePattern = REMOVED_MODULES.join("|");
50
+ const pyImport = new RegExp(`^\\s*(?:import\\s+(?:${modulePattern})\\b|from\\s+(?:${modulePattern})\\s+import\\b)`);
51
+ const jsSpawn = new RegExp(`(?:${modulePattern})\\.py\\b`);
52
+
53
+ function* walk(dir) {
54
+ for (const entry of readdirSync(dir)) {
55
+ if (entry === "__pycache__" || entry === "node_modules" || entry === ".venv") continue;
56
+ const full = join(dir, entry);
57
+ const st = statSync(full);
58
+ if (st.isDirectory()) yield* walk(full);
59
+ else yield full;
60
+ }
61
+ }
62
+
63
+ for (const tree of SOURCE_TREES) {
64
+ const base = join(repo, tree);
65
+ if (!existsSync(base)) continue;
66
+ for (const file of walk(base)) {
67
+ const rel = relative(repo, file);
68
+ if (/\.py$/.test(file)) {
69
+ const lines = readFileSync(file, "utf8").split("\n");
70
+ lines.forEach((line, i) => {
71
+ if (pyImport.test(line)) {
72
+ failures.push(`${rel}:${i + 1} imports a removed root shim: ${line.trim()}`);
73
+ }
74
+ });
75
+ } else if (/\.(mjs|cjs|js)$/.test(file) && !/\.min\.js$/.test(file)) {
76
+ const lines = readFileSync(file, "utf8").split("\n");
77
+ lines.forEach((line, i) => {
78
+ if (jsSpawn.test(line) && !line.includes("check_legacy_debt")) {
79
+ failures.push(`${rel}:${i + 1} references a removed root shim file: ${line.trim()}`);
80
+ }
81
+ });
82
+ }
83
+ }
84
+ }
85
+
86
+ if (failures.length > 0) {
87
+ console.error("legacy debt gate FAILED:");
88
+ for (const failure of failures) console.error(` - ${failure}`);
89
+ process.exit(1);
90
+ }
91
+ console.log("legacy debt gate ok: root shim layer stays removed (server.py only)");
@@ -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())
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ // Retention policy for output/release/: keep the newest N versioned evidence
3
+ // directories (default 3, override with LTCAI_RELEASE_EVIDENCE_KEEP or argv).
4
+ // Older captures are reproducible on demand via `npm run release:evidence`,
5
+ // so keeping the full history only burns disk (13 versions ≈ 90MB).
6
+ import { existsSync, readdirSync, rmSync, statSync } from "node:fs";
7
+ import { join } from "node:path";
8
+
9
+ const repo = join(import.meta.dirname, "..");
10
+ const releaseDir = join(repo, "output", "release");
11
+ const keep = Math.max(1, Number(process.argv[2] || process.env.LTCAI_RELEASE_EVIDENCE_KEEP || 3));
12
+
13
+ if (!existsSync(releaseDir)) {
14
+ console.log(`release evidence: nothing to prune (${releaseDir} missing)`);
15
+ process.exit(0);
16
+ }
17
+
18
+ const semver = (name) => {
19
+ const m = /^v(\d+)\.(\d+)\.(\d+)$/.exec(name);
20
+ return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
21
+ };
22
+
23
+ const versioned = readdirSync(releaseDir)
24
+ .filter((name) => semver(name) && statSync(join(releaseDir, name)).isDirectory())
25
+ .sort((a, b) => {
26
+ const [a1, a2, a3] = semver(a);
27
+ const [b1, b2, b3] = semver(b);
28
+ return b1 - a1 || b2 - a2 || b3 - a3;
29
+ });
30
+
31
+ const stale = versioned.slice(keep);
32
+ for (const name of stale) {
33
+ rmSync(join(releaseDir, name), { recursive: true, force: true });
34
+ console.log(`release evidence: pruned ${name}`);
35
+ }
36
+ console.log(
37
+ `release evidence: keeping ${Math.min(keep, versioned.length)} of ${versioned.length} versions (policy: newest ${keep})`,
38
+ );
@@ -32,7 +32,6 @@ REPO_ROOT = Path(__file__).resolve().parents[1]
32
32
 
33
33
  # Every importable module the wheel ships (pyproject py-modules + packages).
34
34
  WHEEL_MODULES = [
35
- "setup_wizard",
36
35
  "lattice_brain",
37
36
  "lattice_brain.graph",
38
37
  "lattice_brain.graph.store",
@@ -55,9 +54,18 @@ WHEEL_MODULES = [
55
54
  "latticeai.services.p_reinforce",
56
55
  "latticeai.tools",
57
56
  "latticeai.tools.knowledge",
57
+ "latticeai.setup.auto_setup",
58
+ "latticeai.setup.wizard",
59
+ "latticeai.services.local_knowledge",
60
+ "lattice_brain.graph.schema",
61
+ "server",
62
+ ]
63
+
64
+ # Root shims removed in 9.9.1 — the wheel must NOT ship them anymore.
65
+ REMOVED_ROOT_MODULES = [
58
66
  "ltcai_cli",
59
67
  "auto_setup",
60
- "server",
68
+ "setup_wizard",
61
69
  "mcp_registry",
62
70
  "kg_schema",
63
71
  "knowledge_graph",
@@ -67,15 +75,23 @@ WHEEL_MODULES = [
67
75
  "p_reinforce",
68
76
  "telegram_bot",
69
77
  "tools",
70
- "tools.knowledge",
71
78
  ]
72
79
 
73
80
  IMPORT_CHECK = (
74
81
  "import importlib\n"
75
82
  + "".join(f"importlib.import_module({mod!r})\n" for mod in WHEEL_MODULES)
76
- + "assert importlib.import_module('tools') is importlib.import_module('latticeai.tools')\n"
77
- + "assert importlib.import_module('tools.knowledge') is importlib.import_module('latticeai.tools.knowledge')\n"
78
- + f"print('wheel imports ok: {len(WHEEL_MODULES)} modules')\n"
83
+ + "".join(
84
+ f"""
85
+ try:
86
+ importlib.import_module({mod!r})
87
+ except ImportError:
88
+ pass
89
+ else:
90
+ raise AssertionError('removed root shim {mod} is still shipped in the wheel')
91
+ """
92
+ for mod in REMOVED_ROOT_MODULES
93
+ )
94
+ + f"print('wheel imports ok: {len(WHEEL_MODULES)} modules, {len(REMOVED_ROOT_MODULES)} shims gone')\n"
79
95
  )
80
96
 
81
97
  HEALTH_CHECK = """
@@ -1584,7 +1584,7 @@ dependencies = [
1584
1584
 
1585
1585
  [[package]]
1586
1586
  name = "lattice-ai-desktop"
1587
- version = "9.8.0"
1587
+ version = "9.9.1"
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.8.0"
3
+ version = "9.9.1"
4
4
  description = "Lattice AI Digital Brain desktop shell"
5
5
  authors = ["TaeSoo Park"]
6
6
  edition = "2021"
@@ -164,9 +164,9 @@ fn resource_dir() -> Option<PathBuf> {
164
164
  fn bundled_python_root() -> Option<PathBuf> {
165
165
  let resources = resource_dir()?;
166
166
  let up = resources.join("_up_");
167
- if up.join("ltcai_cli.py").is_file() {
167
+ if up.join("latticeai").join("cli").join("entrypoint.py").is_file() {
168
168
  Some(up)
169
- } else if resources.join("ltcai_cli.py").is_file() {
169
+ } else if resources.join("latticeai").join("cli").join("entrypoint.py").is_file() {
170
170
  Some(resources)
171
171
  } else {
172
172
  None
@@ -222,13 +222,13 @@ fn backend_launch(origin: &str) -> BackendLaunch {
222
222
  }
223
223
 
224
224
  for python in python_candidates() {
225
- if module_importable(&python, "ltcai_cli") {
225
+ if module_importable(&python, "latticeai.cli.entrypoint") {
226
226
  return BackendLaunch {
227
- command: format!("{python} -m ltcai_cli --host 127.0.0.1 --port {port}"),
227
+ command: format!("{python} -m latticeai.cli.entrypoint --host 127.0.0.1 --port {port}"),
228
228
  program: python,
229
229
  args: vec![
230
230
  "-m".into(),
231
- "ltcai_cli".into(),
231
+ "latticeai.cli.entrypoint".into(),
232
232
  "--host".into(),
233
233
  "127.0.0.1".into(),
234
234
  "--port".into(),
@@ -240,27 +240,27 @@ fn backend_launch(origin: &str) -> BackendLaunch {
240
240
  }
241
241
 
242
242
  if let Some(resources) = bundled_python_root() {
243
- let launcher = resources.join("ltcai_cli.py");
244
- if launcher.is_file() {
243
+ if resources.join("latticeai").join("cli").join("entrypoint.py").is_file() {
245
244
  if let Some(python) = python_candidates().into_iter().next() {
246
245
  return BackendLaunch {
247
- command: format!("{python} {} --host 127.0.0.1 --port {port}", launcher.display()),
246
+ command: format!("{python} -m latticeai.cli.entrypoint --host 127.0.0.1 --port {port}"),
248
247
  program: python,
249
248
  args: vec![
250
- launcher.to_string_lossy().to_string(),
249
+ "-m".into(),
250
+ "latticeai.cli.entrypoint".into(),
251
251
  "--host".into(),
252
252
  "127.0.0.1".into(),
253
253
  "--port".into(),
254
254
  port,
255
255
  ],
256
- cwd: None,
256
+ cwd: Some(resources),
257
257
  };
258
258
  }
259
259
  }
260
260
  }
261
261
 
262
262
  BackendLaunch {
263
- command: "unavailable: LTCAI executable or importable ltcai_cli module not found".to_string(),
263
+ command: "unavailable: LTCAI executable or importable latticeai.cli.entrypoint module not found".to_string(),
264
264
  program: String::new(),
265
265
  args: Vec::new(),
266
266
  cwd: None,
@@ -278,7 +278,7 @@ fn spawn_backend(origin: &str, launch: &BackendLaunch) -> Result<Option<Child>,
278
278
  return Ok(None);
279
279
  }
280
280
  if launch.program.is_empty() {
281
- return Err("Desktop backend unavailable: LTCAI executable or importable ltcai_cli module not found.".to_string());
281
+ return Err("Desktop backend unavailable: LTCAI executable or importable latticeai.cli.entrypoint module not found.".to_string());
282
282
  }
283
283
 
284
284
  let mut cmd = Command::new(&launch.program);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://schema.tauri.app/config/2",
3
3
  "productName": "Lattice AI",
4
- "version": "9.8.0",
4
+ "version": "9.9.1",
5
5
  "identifier": "ai.lattice.desktop",
6
6
  "build": {
7
7
  "beforeDevCommand": "npm run frontend:dev",
@@ -33,22 +33,10 @@
33
33
  "app"
34
34
  ],
35
35
  "resources": [
36
- "../auto_setup.py",
37
- "../kg_schema.py",
38
- "../knowledge_graph.py",
39
- "../knowledge_graph_api.py",
40
- "../llm_router.py",
41
- "../local_knowledge_api.py",
42
- "../ltcai_cli.py",
43
- "../mcp_registry.py",
44
- "../p_reinforce.py",
45
36
  "../server.py",
46
- "../setup_wizard.py",
47
- "../telegram_bot.py",
48
37
  "../requirements.txt",
49
38
  "../latticeai",
50
39
  "../lattice_brain",
51
- "../tools",
52
40
  "../static"
53
41
  ],
54
42
  "icon": [
@@ -1,19 +1,35 @@
1
1
  {
2
- "version": "9.8.0",
2
+ "version": "9.9.1",
3
3
  "generated_at": "vite",
4
4
  "entrypoints": {
5
- "app": "/static/app/assets/index-CndfILiF.js"
5
+ "app": "/static/app/assets/index-DrZSkwrE.js"
6
6
  },
7
7
  "assets": {
8
8
  "../node_modules/@tauri-apps/api/core.js": "/static/app/assets/core-CwxXejkd.js",
9
- "_primitives-DxsIXb6G.js": "/static/app/assets/primitives-DxsIXb6G.js",
10
- "_textarea-DH7ne8VI.js": "/static/app/assets/textarea-DH7ne8VI.js",
11
- "index.html": "/static/app/assets/index-CndfILiF.js",
12
- "assets/index-7gY9t9Sd.css": "/static/app/assets/index-7gY9t9Sd.css",
13
- "src/pages/Act.tsx": "/static/app/assets/Act-Dd3z8AzF.js",
14
- "src/pages/Brain.tsx": "/static/app/assets/Brain-BMkgdWnI.js",
15
- "src/pages/Capture.tsx": "/static/app/assets/Capture-D2Aw9gkv.js",
16
- "src/pages/Library.tsx": "/static/app/assets/Library-Yreq-KW5.js",
17
- "src/pages/System.tsx": "/static/app/assets/System-CXNmmtEo.js"
9
+ "_BrainSignals-CmFD8PWk.js": "/static/app/assets/BrainSignals-CmFD8PWk.js",
10
+ "_LivingBrain-6FvA0H5T.js": "/static/app/assets/LivingBrain-6FvA0H5T.js",
11
+ "_ReviewCard-D56TMypk.js": "/static/app/assets/ReviewCard-D56TMypk.js",
12
+ "_bot-DgC7xgUl.js": "/static/app/assets/bot-DgC7xgUl.js",
13
+ "_cpu-DDGb4XHl.js": "/static/app/assets/cpu-DDGb4XHl.js",
14
+ "_download-C-Ei3GFa.js": "/static/app/assets/download-C-Ei3GFa.js",
15
+ "_folder-open-BbVuSO9M.js": "/static/app/assets/folder-open-BbVuSO9M.js",
16
+ "_hard-drive-yDZR6XYz.js": "/static/app/assets/hard-drive-yDZR6XYz.js",
17
+ "_input-DPIkTs9n.js": "/static/app/assets/input-DPIkTs9n.js",
18
+ "_navigation-B1mkmyUe.js": "/static/app/assets/navigation-B1mkmyUe.js",
19
+ "_network-0XDI1Uf_.js": "/static/app/assets/network-0XDI1Uf_.js",
20
+ "_primitives-sIQYKyf5.js": "/static/app/assets/primitives-sIQYKyf5.js",
21
+ "_sunrise-DXMjueec.js": "/static/app/assets/sunrise-DXMjueec.js",
22
+ "_textarea-DvnwpnqS.js": "/static/app/assets/textarea-DvnwpnqS.js",
23
+ "_utils-BrfFHAJl.js": "/static/app/assets/utils-BrfFHAJl.js",
24
+ "index.html": "/static/app/assets/index-DrZSkwrE.js",
25
+ "assets/index-CFRhNBuH.css": "/static/app/assets/index-CFRhNBuH.css",
26
+ "src/components/ProductFlow.tsx": "/static/app/assets/ProductFlow-Cr8bkQPw.js",
27
+ "src/features/brain/BrainHome.tsx": "/static/app/assets/BrainHome-B5QpJ1Fx.js",
28
+ "src/features/command/CommandPalette.tsx": "/static/app/assets/CommandPalette-BrqpT7K2.js",
29
+ "src/pages/Act.tsx": "/static/app/assets/Act-CcSWTQsx.js",
30
+ "src/pages/Brain.tsx": "/static/app/assets/Brain-CSCDZEHd.js",
31
+ "src/pages/Capture.tsx": "/static/app/assets/Capture-BiuerOio.js",
32
+ "src/pages/Library.tsx": "/static/app/assets/Library-BcaiPbum.js",
33
+ "src/pages/System.tsx": "/static/app/assets/System-D6uJacqu.js"
18
34
  }
19
35
  }