ltcai 8.5.0 → 8.7.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 (50) hide show
  1. package/README.md +35 -33
  2. package/desktop/electron/main.cjs +13 -1
  3. package/desktop/electron/preload.cjs +5 -0
  4. package/docs/CHANGELOG.md +46 -0
  5. package/docs/COMMUNITY_AND_PLUGINS.md +5 -3
  6. package/docs/DEVELOPMENT.md +11 -9
  7. package/docs/LEGACY_COMPATIBILITY.md +3 -3
  8. package/docs/ONBOARDING.md +4 -4
  9. package/docs/TRUST_MODEL.md +1 -1
  10. package/docs/WHY_LATTICE.md +2 -2
  11. package/docs/kg-schema.md +1 -1
  12. package/lattice_brain/__init__.py +1 -1
  13. package/lattice_brain/runtime/multi_agent.py +1 -1
  14. package/latticeai/__init__.py +1 -1
  15. package/latticeai/app_factory.py +2 -2
  16. package/latticeai/core/config.py +14 -2
  17. package/latticeai/core/marketplace.py +1 -1
  18. package/latticeai/core/workspace_os.py +1 -1
  19. package/latticeai/models/router.py +3 -2
  20. package/latticeai/runtime/router_registration.py +11 -5
  21. package/latticeai/services/architecture_readiness.py +2 -2
  22. package/latticeai/services/model_runtime.py +52 -28
  23. package/latticeai/services/product_readiness.py +11 -11
  24. package/package.json +3 -2
  25. package/scripts/bump_version.py +2 -0
  26. package/scripts/check_python.py +25 -12
  27. package/src-tauri/Cargo.lock +1 -1
  28. package/src-tauri/Cargo.toml +1 -1
  29. package/src-tauri/capabilities/default.json +3 -0
  30. package/src-tauri/src/main.rs +32 -1
  31. package/src-tauri/tauri.conf.json +1 -1
  32. package/static/app/asset-manifest.json +11 -11
  33. package/static/app/assets/{Act-D5mo4tE4.js → Act-_U7mhXir.js} +1 -1
  34. package/static/app/assets/{Brain-BVWyQw8A.js → Brain-BxyTHZ21.js} +2 -2
  35. package/static/app/assets/Capture-DyDKWNh9.js +1 -0
  36. package/static/app/assets/Library-DJ8KioFM.js +1 -0
  37. package/static/app/assets/System-C0FIb3OO.js +1 -0
  38. package/static/app/assets/index-Bh7IIlyY.js +16 -0
  39. package/static/app/assets/index-_M5aCv21.css +2 -0
  40. package/static/app/assets/primitives-BywkNS3f.js +1 -0
  41. package/static/app/assets/{textarea-e7qaj6Hm.js → textarea-CQ61Rycp.js} +1 -1
  42. package/static/app/index.html +2 -2
  43. package/static/app/theme-boot.js +2 -2
  44. package/static/sw.js +1 -1
  45. package/static/app/assets/Capture-C1R6GT0t.js +0 -1
  46. package/static/app/assets/Library-C2wIxpTs.js +0 -1
  47. package/static/app/assets/System-DE5GRyQR.js +0 -1
  48. package/static/app/assets/index-CoiuIFFP.js +0 -16
  49. package/static/app/assets/index-ty1iGgZu.css +0 -2
  50. package/static/app/assets/primitives-BdsUNXa6.js +0 -1
@@ -16,6 +16,7 @@ import shutil
16
16
  import time
17
17
  import urllib.error
18
18
  import urllib.request
19
+ import warnings
19
20
  from pathlib import Path
20
21
  from typing import AsyncIterator, Dict, List, Optional
21
22
 
@@ -100,6 +101,21 @@ class ModelRuntimeState:
100
101
  self.get_user_api_key = _missing_user_api_key
101
102
 
102
103
  def sync_to_module_globals(self):
104
+ """Sync to bare module globals for legacy external importers.
105
+
106
+ This is a compatibility surface only. Internal code should use STATE.
107
+ Emits DeprecationWarning (future removal in major after 8.x).
108
+ """
109
+ warnings.warn(
110
+ "sync_to_module_globals is a legacy compatibility shim and will be removed "
111
+ "after 8.x. Use latticeai.services.model_runtime.STATE or injected context instead.",
112
+ DeprecationWarning,
113
+ stacklevel=2,
114
+ )
115
+ self._sync_globals()
116
+
117
+ def _sync_globals(self) -> None:
118
+ """Internal no-warning sync used at init."""
103
119
  global router, APP_MODE, DEFAULT_HOST, DEFAULT_PORT, DATA_DIR, BASE_DIR
104
120
  global ENABLE_TELEGRAM, ENABLE_GRAPH, AUTOLOAD_MODELS, MODEL_IDLE_UNLOAD_SECONDS
105
121
  global ALLOW_LOCAL_MODELS, REQUIRE_AUTH, INVITE_GATE_ENABLED, ALLOW_PLAINTEXT_API_KEYS
@@ -128,7 +144,7 @@ class ModelRuntimeState:
128
144
  get_user_api_key = self.get_user_api_key
129
145
 
130
146
  STATE = ModelRuntimeState()
131
- STATE.sync_to_module_globals()
147
+ STATE._sync_globals() # initial no-warning; public API warns on explicit legacy syncs
132
148
 
133
149
  # Configured by server_app.configure_model_runtime during app assembly.
134
150
 
@@ -141,7 +157,9 @@ def _env_bool(key: str, default: bool = False) -> bool:
141
157
 
142
158
 
143
159
  def _download_allowed(allow_download: bool = False) -> bool:
144
- return bool(allow_download) or _env_bool("LATTICEAI_ALLOW_MODEL_DOWNLOADS", default=False) or bool(AUTOLOAD_MODELS)
160
+ # Prefer STATE (the source of truth) over bare module global for internal logic.
161
+ autoload = getattr(STATE, "AUTOLOAD_MODELS", AUTOLOAD_MODELS)
162
+ return bool(allow_download) or _env_bool("LATTICEAI_ALLOW_MODEL_DOWNLOADS", default=False) or bool(autoload)
145
163
 
146
164
 
147
165
  def _download_block(provider: str, model_name: str) -> None:
@@ -204,7 +222,7 @@ def configure_model_runtime(**deps) -> None:
204
222
  elif key == "get_user_api_key":
205
223
  STATE.get_user_api_key = value
206
224
 
207
- STATE.sync_to_module_globals()
225
+ STATE._sync_globals() # wiring path uses internal (no spurious deprecation in normal startup)
208
226
 
209
227
 
210
228
  # Catalog data + version-dedup helpers live in ``model_catalog``; re-exported
@@ -727,7 +745,8 @@ def engine_installed(engine: str) -> bool:
727
745
  return False
728
746
 
729
747
  def engine_status() -> List[Dict]:
730
- cloud_models = router.detected_cloud_models()
748
+ r = getattr(STATE, "router", None) or router
749
+ cloud_models = r.detected_cloud_models() if r else []
731
750
  cloud_by_provider = {}
732
751
  for model in cloud_models:
733
752
  cloud_by_provider.setdefault(model["provider"], []).append(model)
@@ -887,37 +906,41 @@ def engine_status() -> List[Dict]:
887
906
  return engines
888
907
 
889
908
  def runtime_features() -> Dict:
909
+ # Read from STATE object (central) for implementation; bare globals kept only
910
+ # for external legacy consumers who import names directly from this module.
911
+ s = STATE
912
+ r = getattr(s, "router", None) or router
890
913
  return {
891
- "mode": APP_MODE,
892
- "public": IS_PUBLIC_MODE,
893
- "host": DEFAULT_HOST,
894
- "port": DEFAULT_PORT,
895
- "data_dir": str(DATA_DIR),
896
- "telegram_enabled": ENABLE_TELEGRAM,
897
- "graph_enabled": ENABLE_GRAPH,
898
- "autoload_models": AUTOLOAD_MODELS,
899
- "model_idle_unload_seconds": MODEL_IDLE_UNLOAD_SECONDS,
900
- "model_memory_policy": router.model_memory_policy(),
901
- "allow_local_models": ALLOW_LOCAL_MODELS,
914
+ "mode": s.APP_MODE,
915
+ "public": s.IS_PUBLIC_MODE,
916
+ "host": s.DEFAULT_HOST,
917
+ "port": s.DEFAULT_PORT,
918
+ "data_dir": str(s.DATA_DIR),
919
+ "telegram_enabled": s.ENABLE_TELEGRAM,
920
+ "graph_enabled": s.ENABLE_GRAPH,
921
+ "autoload_models": s.AUTOLOAD_MODELS,
922
+ "model_idle_unload_seconds": s.MODEL_IDLE_UNLOAD_SECONDS,
923
+ "model_memory_policy": r.model_memory_policy() if r else None,
924
+ "allow_local_models": s.ALLOW_LOCAL_MODELS,
902
925
  "security": {
903
- "host": DEFAULT_HOST,
904
- "require_auth": REQUIRE_AUTH,
905
- "invite_gate_enabled": INVITE_GATE_ENABLED,
906
- "keyring_available": keyring is not None,
907
- "plaintext_api_keys_allowed": ALLOW_PLAINTEXT_API_KEYS,
908
- "cors_allow_network": CORS_ALLOW_NETWORK,
926
+ "host": s.DEFAULT_HOST,
927
+ "require_auth": s.REQUIRE_AUTH,
928
+ "invite_gate_enabled": s.INVITE_GATE_ENABLED,
929
+ "keyring_available": s.keyring is not None,
930
+ "plaintext_api_keys_allowed": s.ALLOW_PLAINTEXT_API_KEYS,
931
+ "cors_allow_network": s.CORS_ALLOW_NETWORK,
909
932
  },
910
- "default_model": PUBLIC_MODEL if IS_PUBLIC_MODE else LOCAL_MODEL,
933
+ "default_model": s.PUBLIC_MODEL if s.IS_PUBLIC_MODE else s.LOCAL_MODEL,
911
934
  "local_only_features": {
912
- "mlx": ALLOW_LOCAL_MODELS and not IS_PUBLIC_MODE,
913
- "telegram_bridge": ENABLE_TELEGRAM,
914
- "desktop_chrome_bridge": not IS_PUBLIC_MODE,
915
- "computer_use_bridge": not IS_PUBLIC_MODE,
935
+ "mlx": s.ALLOW_LOCAL_MODELS and not s.IS_PUBLIC_MODE,
936
+ "telegram_bridge": s.ENABLE_TELEGRAM,
937
+ "desktop_chrome_bridge": not s.IS_PUBLIC_MODE,
938
+ "computer_use_bridge": not s.IS_PUBLIC_MODE,
916
939
  },
917
940
  "public_features": {
918
941
  "web_ui": True,
919
942
  "openai_compatible_models": True,
920
- "persistent_data_dir": str(DATA_DIR),
943
+ "persistent_data_dir": str(s.DATA_DIR),
921
944
  },
922
945
  }
923
946
 
@@ -1099,7 +1122,8 @@ async def _probe_cloud_model(model_ref: str) -> Dict[str, object]:
1099
1122
 
1100
1123
  async def verify_cloud_models(force: bool = False, provider_filter: Optional[str] = None) -> Dict[str, Dict]:
1101
1124
  now = time.time()
1102
- cloud_items = [item for item in router.detected_cloud_models() if item.get("tag") == "cloud"]
1125
+ r = getattr(STATE, "router", None) or router
1126
+ cloud_items = [item for item in (r.detected_cloud_models() if r else []) if item.get("tag") == "cloud"]
1103
1127
  if provider_filter:
1104
1128
  cloud_items = [item for item in cloud_items if item.get("provider") == provider_filter]
1105
1129
 
@@ -18,7 +18,7 @@ from typing import Any, Dict, List
18
18
 
19
19
  from latticeai.services.architecture_readiness import architecture_readiness
20
20
 
21
- PRODUCT_VERSION_TARGET = "8.5.0"
21
+ PRODUCT_VERSION_TARGET = "8.7.0"
22
22
 
23
23
 
24
24
  @dataclass(frozen=True)
@@ -76,10 +76,10 @@ PRODUCT_GATES: List[ProductGate] = [
76
76
  evidence=[
77
77
  "package.json::release:artifacts",
78
78
  "package.json::release:validate",
79
- "README.md::dist/ltcai-8.5.0-py3-none-any.whl",
80
- "README.md::dist/ltcai-8.5.0.tar.gz",
81
- "README.md::dist/ltcai-8.5.0.vsix",
82
- "README.md::ltcai-8.5.0.tgz",
79
+ "README.md::dist/ltcai-8.7.0-py3-none-any.whl",
80
+ "README.md::dist/ltcai-8.7.0.tar.gz",
81
+ "README.md::dist/ltcai-8.7.0.vsix",
82
+ "README.md::ltcai-8.7.0.tgz",
83
83
  "scripts/validate_release_artifacts.py",
84
84
  "scripts/release_smoke.py",
85
85
  "Dockerfile",
@@ -95,12 +95,12 @@ PRODUCT_GATES: List[ProductGate] = [
95
95
  title="Release story is documented and honest",
96
96
  evidence=[
97
97
  "README.md",
98
- "README.md::The current release is **8.5.0",
99
- "SECURITY.md::8.5.x (latest)",
100
- "vscode-extension/README.md::**8.5.0",
101
- "docs/CHANGELOG.md::## [8.5.0]",
98
+ "README.md::The current release is **8.7.0",
99
+ "SECURITY.md::8.7.x (latest)",
100
+ "vscode-extension/README.md::**8.7.0",
101
+ "docs/CHANGELOG.md::## [8.7.0]",
102
102
  "FEATURE_STATUS.md",
103
- "RELEASE_NOTES_v8.4.0.md",
103
+ "RELEASE_NOTES_v8.7.0.md",
104
104
  "latticeai/core/agent.py::SingleAgentRuntime",
105
105
  "latticeai/core/agent.py::AgentRuntime = SingleAgentRuntime",
106
106
  "lattice_brain/runtime/contracts.py::runtime-boundary/v1",
@@ -115,7 +115,7 @@ PRODUCT_GATES: List[ProductGate] = [
115
115
  id="ecosystem-path",
116
116
  title="Community and plugin growth path is explicit",
117
117
  evidence=[
118
- "docs/COMMUNITY_AND_PLUGINS.md::8.5.0",
118
+ "docs/COMMUNITY_AND_PLUGINS.md::8.7.0",
119
119
  "docs/PLUGIN_SDK.md",
120
120
  "plugins/README.md",
121
121
  "plugins/hello-world/plugin.json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ltcai",
3
- "version": "8.5.0",
3
+ "version": "8.7.0",
4
4
  "description": "Lattice AI — local-first Digital Brain that keeps your knowledge durable across any AI model.",
5
5
  "homepage": "https://github.com/TaeSooPark-PTS/LatticeAI#readme",
6
6
  "repository": {
@@ -23,7 +23,8 @@
23
23
  "build:assets": "vite build && node scripts/build_frontend_assets.mjs",
24
24
  "build:python": "node scripts/run_python.mjs -m build",
25
25
  "check:python": "node scripts/run_python.mjs scripts/check_python.py",
26
- "lint": "node --check tests/visual/mock_server.cjs && node --check tests/visual/v3.spec.js && npm run lint:frontend && node scripts/check_i18n_literals.mjs",
26
+ "lint": "npm run lint:python && node --check tests/visual/mock_server.cjs && node --check tests/visual/v3.spec.js && npm run lint:frontend && node scripts/check_i18n_literals.mjs",
27
+ "lint:python": "node scripts/run_python.mjs -m ruff check .",
27
28
  "lint:frontend": "node scripts/lint_frontend.mjs",
28
29
  "docs:check-links": "node scripts/check_markdown_links.mjs",
29
30
  "typecheck": "npm run typecheck:frontend && cd vscode-extension && npm run build",
@@ -27,6 +27,8 @@ TARGETS = [
27
27
  ("latticeai/core/workspace_os.py", "regex", r'(WORKSPACE_OS_VERSION = ")([^"]+)(")'),
28
28
  ("latticeai/core/marketplace.py", "regex", r'(MARKETPLACE_VERSION = ")([^"]+)(")'),
29
29
  ("lattice_brain/runtime/multi_agent.py", "regex", r'(MULTI_AGENT_VERSION = ")([^"]+)(")'),
30
+ ("latticeai/services/architecture_readiness.py", "regex", r'(ARCHITECTURE_VERSION_TARGET = ")([^"]+)(")'),
31
+ ("latticeai/services/product_readiness.py", "regex", r'(PRODUCT_VERSION_TARGET = ")([^"]+)(")'),
30
32
  ("pyproject.toml", "regex", r'(^version = ")([^"]+)(")'),
31
33
  ("package.json", "json", "version"),
32
34
  ("package-lock.json", "package-lock", None),
@@ -1,23 +1,26 @@
1
1
  #!/usr/bin/env python3
2
- """Discover-and-compile every first-party Python module.
2
+ """Discover-and-syntax-check every first-party Python module.
3
3
 
4
4
  Replaces the hand-maintained ``py_compile`` enumeration in CI and
5
5
  ``package.json``: walks the repository, skips vendored / virtualenv / build /
6
- cache / generated directories, and byte-compiles everything that remains. New
6
+ cache / generated directories, and checks everything that remains. New
7
7
  modules are picked up automatically — there is nothing to update when a file is
8
8
  added, so the syntax gate can never silently fall behind the codebase.
9
9
 
10
+ Unlike ``py_compile``, this script does not write ``.pyc`` files or create
11
+ ``__pycache__`` directories. Validation should not dirty a developer's working
12
+ tree or leave generated files for later lint passes to trip over.
13
+
10
14
  Usage::
11
15
 
12
- python scripts/check_python.py # compile all discovered modules
13
- python scripts/check_python.py --list # just print what would be compiled
16
+ python scripts/check_python.py # syntax-check all discovered modules
17
+ python scripts/check_python.py --list # just print what would be checked
14
18
 
15
- Exit code is non-zero if any module fails to compile.
19
+ Exit code is non-zero if any module fails to parse.
16
20
  """
17
21
 
18
22
  from __future__ import annotations
19
23
 
20
- import py_compile
21
24
  import sys
22
25
  from pathlib import Path
23
26
 
@@ -44,6 +47,7 @@ EXCLUDE_DIRS = {
44
47
  "playwright-report",
45
48
  "test-results",
46
49
  "ltcai.egg-info",
50
+ "output",
47
51
  ".ltcai",
48
52
  ".ltcai-brain",
49
53
  ".ltcai-test",
@@ -60,6 +64,16 @@ def iter_modules():
60
64
  yield path
61
65
 
62
66
 
67
+ def check_syntax(path: Path) -> str | None:
68
+ """Return a human-readable failure string, or ``None`` when syntax is valid."""
69
+
70
+ try:
71
+ compile(path.read_bytes(), str(path), "exec", dont_inherit=True)
72
+ except (OSError, SyntaxError, ValueError) as exc:
73
+ return f"{path.relative_to(ROOT)}: {exc}"
74
+ return None
75
+
76
+
63
77
  def main(argv: list[str]) -> int:
64
78
  modules = sorted(iter_modules())
65
79
  if "--list" in argv:
@@ -69,17 +83,16 @@ def main(argv: list[str]) -> int:
69
83
 
70
84
  failures: list[str] = []
71
85
  for path in modules:
72
- try:
73
- py_compile.compile(str(path), doraise=True)
74
- except py_compile.PyCompileError as exc:
75
- failures.append(str(exc))
86
+ failure = check_syntax(path)
87
+ if failure:
88
+ failures.append(failure)
76
89
 
77
90
  if failures:
78
91
  print("\n".join(failures))
79
- print(f"check:python FAILED — {len(failures)} of {len(modules)} module(s) did not compile")
92
+ print(f"check:python FAILED — {len(failures)} of {len(modules)} module(s) did not parse")
80
93
  return 1
81
94
 
82
- print(f"check:python OK — compiled {len(modules)} modules")
95
+ print(f"check:python OK — syntax-checked {len(modules)} modules")
83
96
  return 0
84
97
 
85
98
 
@@ -1584,7 +1584,7 @@ dependencies = [
1584
1584
 
1585
1585
  [[package]]
1586
1586
  name = "lattice-ai-desktop"
1587
- version = "8.4.0"
1587
+ version = "8.7.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 = "8.5.0"
3
+ version = "8.7.0"
4
4
  description = "Lattice AI Digital Brain desktop shell"
5
5
  authors = ["TaeSoo Park"]
6
6
  edition = "2021"
@@ -3,5 +3,8 @@
3
3
  "identifier": "default",
4
4
  "description": "Default Lattice AI desktop capability set.",
5
5
  "windows": ["main"],
6
+ "remote": {
7
+ "urls": ["http://127.0.0.1:*", "http://localhost:*"]
8
+ },
6
9
  "permissions": ["core:default"]
7
10
  }
@@ -66,6 +66,36 @@ fn shutdown_backend(state: State<'_, BackendState>) -> BackendStatus {
66
66
  status_from_state(&state)
67
67
  }
68
68
 
69
+ #[tauri::command]
70
+ fn select_folder() -> Option<String> {
71
+ native_select_folder()
72
+ }
73
+
74
+ #[cfg(target_os = "macos")]
75
+ fn native_select_folder() -> Option<String> {
76
+ let output = Command::new("osascript")
77
+ .args([
78
+ "-e",
79
+ r#"POSIX path of (choose folder with prompt "Choose a folder for Lattice AI")"#,
80
+ ])
81
+ .output()
82
+ .ok()?;
83
+ if !output.status.success() {
84
+ return None;
85
+ }
86
+ let path = String::from_utf8_lossy(&output.stdout).trim().to_string();
87
+ if path.is_empty() {
88
+ None
89
+ } else {
90
+ Some(path)
91
+ }
92
+ }
93
+
94
+ #[cfg(not(target_os = "macos"))]
95
+ fn native_select_folder() -> Option<String> {
96
+ None
97
+ }
98
+
69
99
  fn split_command(command: &str) -> Vec<String> {
70
100
  command.split_whitespace().map(|part| part.to_string()).collect()
71
101
  }
@@ -379,7 +409,8 @@ fn main() {
379
409
  backend_origin,
380
410
  backend_status,
381
411
  restart_backend,
382
- shutdown_backend
412
+ shutdown_backend,
413
+ select_folder
383
414
  ])
384
415
  .setup(|app| {
385
416
  if let Some(window) = app.get_webview_window("main") {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://schema.tauri.app/config/2",
3
3
  "productName": "Lattice AI",
4
- "version": "8.5.0",
4
+ "version": "8.7.0",
5
5
  "identifier": "ai.lattice.desktop",
6
6
  "build": {
7
7
  "beforeDevCommand": "npm run frontend:dev",
@@ -1,19 +1,19 @@
1
1
  {
2
- "version": "8.5.0",
2
+ "version": "8.7.0",
3
3
  "generated_at": "vite",
4
4
  "entrypoints": {
5
- "app": "/static/app/assets/index-CoiuIFFP.js"
5
+ "app": "/static/app/assets/index-Bh7IIlyY.js"
6
6
  },
7
7
  "assets": {
8
8
  "../node_modules/@tauri-apps/api/core.js": "/static/app/assets/core-CwxXejkd.js",
9
- "_primitives-BdsUNXa6.js": "/static/app/assets/primitives-BdsUNXa6.js",
10
- "_textarea-e7qaj6Hm.js": "/static/app/assets/textarea-e7qaj6Hm.js",
11
- "index.html": "/static/app/assets/index-CoiuIFFP.js",
12
- "assets/index-ty1iGgZu.css": "/static/app/assets/index-ty1iGgZu.css",
13
- "src/pages/Act.tsx": "/static/app/assets/Act-D5mo4tE4.js",
14
- "src/pages/Brain.tsx": "/static/app/assets/Brain-BVWyQw8A.js",
15
- "src/pages/Capture.tsx": "/static/app/assets/Capture-C1R6GT0t.js",
16
- "src/pages/Library.tsx": "/static/app/assets/Library-C2wIxpTs.js",
17
- "src/pages/System.tsx": "/static/app/assets/System-DE5GRyQR.js"
9
+ "_primitives-BywkNS3f.js": "/static/app/assets/primitives-BywkNS3f.js",
10
+ "_textarea-CQ61Rycp.js": "/static/app/assets/textarea-CQ61Rycp.js",
11
+ "index.html": "/static/app/assets/index-Bh7IIlyY.js",
12
+ "assets/index-_M5aCv21.css": "/static/app/assets/index-_M5aCv21.css",
13
+ "src/pages/Act.tsx": "/static/app/assets/Act-_U7mhXir.js",
14
+ "src/pages/Brain.tsx": "/static/app/assets/Brain-BxyTHZ21.js",
15
+ "src/pages/Capture.tsx": "/static/app/assets/Capture-DyDKWNh9.js",
16
+ "src/pages/Library.tsx": "/static/app/assets/Library-DJ8KioFM.js",
17
+ "src/pages/System.tsx": "/static/app/assets/System-C0FIb3OO.js"
18
18
  }
19
19
  }