ltcai 7.0.0 → 7.2.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 (67) hide show
  1. package/README.md +22 -20
  2. package/docs/CHANGELOG.md +43 -0
  3. package/frontend/src/App.tsx +80 -0
  4. package/frontend/src/api/client.ts +9 -0
  5. package/frontend/src/components/AdminAccessGate.tsx +70 -0
  6. package/frontend/src/components/BrainConversation.tsx +232 -8
  7. package/frontend/src/components/FeedbackState.tsx +45 -0
  8. package/frontend/src/components/WorkspaceProfileSwitcher.tsx +176 -0
  9. package/frontend/src/components/onboarding/AnalysisScreen.tsx +20 -12
  10. package/frontend/src/components/onboarding/InstallScreen.tsx +55 -0
  11. package/frontend/src/components/onboarding/RecommendationScreen.tsx +55 -5
  12. package/frontend/src/components/onboarding/recommendationModel.ts +59 -2
  13. package/frontend/src/features/admin/AdminConsole.tsx +41 -1
  14. package/frontend/src/features/brain/BrainConversation.tsx +232 -19
  15. package/frontend/src/features/brain/BrainGraphLayer.tsx +258 -25
  16. package/frontend/src/features/brain/BrainHome.tsx +193 -1
  17. package/frontend/src/features/brain/brainData.ts +25 -1
  18. package/frontend/src/features/brain/graphLayout.ts +12 -1
  19. package/frontend/src/features/brain/types.ts +41 -0
  20. package/frontend/src/i18n.ts +328 -0
  21. package/frontend/src/store/appStore.ts +15 -0
  22. package/frontend/src/styles.css +1175 -0
  23. package/lattice_brain/__init__.py +1 -1
  24. package/lattice_brain/runtime/agent_runtime.py +51 -0
  25. package/lattice_brain/runtime/multi_agent.py +1 -1
  26. package/latticeai/__init__.py +1 -1
  27. package/latticeai/api/agents.py +12 -0
  28. package/latticeai/api/tools.py +14 -0
  29. package/latticeai/api/workspace.py +59 -0
  30. package/latticeai/core/marketplace.py +1 -1
  31. package/latticeai/core/tool_registry.py +47 -0
  32. package/latticeai/core/workspace_os.py +1 -1
  33. package/latticeai/services/tool_dispatch.py +14 -0
  34. package/package.json +1 -1
  35. package/src-tauri/Cargo.lock +1 -1
  36. package/src-tauri/Cargo.toml +1 -1
  37. package/src-tauri/tauri.conf.json +1 -1
  38. package/static/app/asset-manifest.json +28 -28
  39. package/static/app/assets/Act-Di4tRFWY.js +2 -0
  40. package/static/app/assets/{Act-DhLaHnrT.js.map → Act-Di4tRFWY.js.map} +1 -1
  41. package/static/app/assets/Brain-BZB3Gy9w.js +322 -0
  42. package/static/app/assets/Brain-BZB3Gy9w.js.map +1 -0
  43. package/static/app/assets/{Capture-CAKouj52.js → Capture-tNyYWxnh.js} +2 -2
  44. package/static/app/assets/{Capture-CAKouj52.js.map → Capture-tNyYWxnh.js.map} +1 -1
  45. package/static/app/assets/Library-DAtDDLdg.js +2 -0
  46. package/static/app/assets/{Library-B_hW4AwR.js.map → Library-DAtDDLdg.js.map} +1 -1
  47. package/static/app/assets/System-DEu0xNUc.js +2 -0
  48. package/static/app/assets/System-DEu0xNUc.js.map +1 -0
  49. package/static/app/assets/{index-DKFpn5Kn.css → index-Bi_bpigM.css} +1 -1
  50. package/static/app/assets/index-COuGp7_5.js +17 -0
  51. package/static/app/assets/index-COuGp7_5.js.map +1 -0
  52. package/static/app/assets/primitives-CdwcE--L.js +2 -0
  53. package/static/app/assets/primitives-CdwcE--L.js.map +1 -0
  54. package/static/app/assets/textarea-CqOdBPL1.js +2 -0
  55. package/static/app/assets/{textarea-DR2Tyy_6.js.map → textarea-CqOdBPL1.js.map} +1 -1
  56. package/static/app/index.html +2 -2
  57. package/static/app/assets/Act-DhLaHnrT.js +0 -2
  58. package/static/app/assets/Brain-DS7NULyY.js +0 -322
  59. package/static/app/assets/Brain-DS7NULyY.js.map +0 -1
  60. package/static/app/assets/Library-B_hW4AwR.js +0 -2
  61. package/static/app/assets/System-9OAoXWPz.js +0 -2
  62. package/static/app/assets/System-9OAoXWPz.js.map +0 -1
  63. package/static/app/assets/index-C-7aHabu.js +0 -17
  64. package/static/app/assets/index-C-7aHabu.js.map +0 -1
  65. package/static/app/assets/primitives-DcO2H3yh.js +0 -2
  66. package/static/app/assets/primitives-DcO2H3yh.js.map +0 -1
  67. package/static/app/assets/textarea-DR2Tyy_6.js +0 -2
@@ -26,7 +26,7 @@ from .storage import (
26
26
  storage_from_env,
27
27
  )
28
28
 
29
- __version__ = "7.0.0"
29
+ __version__ = "7.2.0"
30
30
 
31
31
  __all__ = [
32
32
  "AgentRuntime",
@@ -228,6 +228,57 @@ class AgentRuntime:
228
228
  "runs": runs[:25],
229
229
  }
230
230
 
231
+ def preview(
232
+ self,
233
+ goal: str,
234
+ *,
235
+ roles: Optional[List[str]] = None,
236
+ inputs: Optional[Dict[str, Any]] = None,
237
+ max_retries: int = 2,
238
+ scope: Optional[str] = None,
239
+ ) -> Dict[str, Any]:
240
+ """Return the execution contract without reserving or starting a run.
241
+
242
+ The preview is the product-facing readiness gate for agent execution:
243
+ clients can show whether a real LLM-backed run can start, which roles
244
+ will execute, how retry limits are clamped, and why the run is blocked.
245
+ """
246
+
247
+ requested_roles = list(roles or CORE_PIPELINE)
248
+ unknown_roles = [role for role in requested_roles if role not in AGENT_ROLES]
249
+ health = self.health()
250
+ goal_ready = bool(str(goal or "").strip())
251
+ retry_budget = max(0, min(int(max_retries or 0), self._max_retries_cap))
252
+ blocking_reasons: List[str] = []
253
+ if not goal_ready:
254
+ blocking_reasons.append("goal is required")
255
+ if unknown_roles:
256
+ blocking_reasons.append(f"unknown roles: {', '.join(unknown_roles)}")
257
+ if not health.get("ready"):
258
+ orchestrator = (health.get("checks") or {}).get("orchestrator") or {}
259
+ blocking_reasons.append(str(orchestrator.get("detail") or "agent runtime is unavailable"))
260
+ can_start = not blocking_reasons
261
+ return {
262
+ "ready": can_start,
263
+ "can_start": can_start,
264
+ "blocking_reasons": blocking_reasons,
265
+ "goal": str(goal or "").strip(),
266
+ "roles": requested_roles,
267
+ "unknown_roles": unknown_roles,
268
+ "inputs_keys": sorted((inputs or {}).keys()),
269
+ "max_retries": retry_budget,
270
+ "max_retries_requested": max_retries,
271
+ "scope": scope,
272
+ "execution_mode": self._execution_mode(),
273
+ "runtime": {
274
+ "version": MULTI_AGENT_VERSION,
275
+ "default_pipeline": list(CORE_PIPELINE),
276
+ "max_retries_cap": self._max_retries_cap,
277
+ "simulation_runs_allowed": self._allow_simulation_runs,
278
+ },
279
+ "health": health,
280
+ }
281
+
231
282
  # ── events / state ────────────────────────────────────────────────────
232
283
  def list_runs(self, *, scope: Optional[str] = None) -> Dict[str, Any]:
233
284
  return self._store.list_agents(workspace_id=scope)
@@ -19,7 +19,7 @@ from datetime import datetime
19
19
  from typing import Any, Callable, Dict, List, Optional
20
20
 
21
21
 
22
- MULTI_AGENT_VERSION = "7.0.0"
22
+ MULTI_AGENT_VERSION = "7.2.0"
23
23
 
24
24
  AGENT_ROLES = ("researcher", "planner", "executor", "reviewer", "release")
25
25
  CORE_PIPELINE = ("planner", "executor", "reviewer")
@@ -1,3 +1,3 @@
1
1
  """Lattice AI - modular server package."""
2
2
 
3
- __version__ = "7.0.0"
3
+ __version__ = "7.2.0"
@@ -192,4 +192,16 @@ def create_agents_router(
192
192
  # A pre_run hook gated this run (e.g. a policy/permission hook).
193
193
  raise HTTPException(status_code=403, detail=str(exc)) from exc
194
194
 
195
+ @router.post("/agents/api/run/preview")
196
+ async def agent_run_preview(req: AgentRunRequest, request: Request):
197
+ require_user(request)
198
+ scope = gate_read(request)
199
+ return runtime.preview(
200
+ req.goal,
201
+ scope=scope,
202
+ roles=req.roles or None,
203
+ inputs=req.inputs,
204
+ max_retries=req.max_retries,
205
+ )
206
+
195
207
  return router
@@ -25,6 +25,8 @@ from latticeai.services.tool_dispatch import (
25
25
  check_tool_role as _check_tool_role,
26
26
  get_tool_permission,
27
27
  list_tool_permissions,
28
+ tool_registry_diagnostics,
29
+ tool_registry_manifest,
28
30
  )
29
31
  from latticeai.services.router_context import ToolRouterContext
30
32
  from latticeai.services.p_reinforce import BRAIN_DIR
@@ -602,6 +604,18 @@ def create_tools_router(
602
604
  """
603
605
  require_user(request)
604
606
  return {"status": "ok", "permissions": list_tool_permissions()}
607
+
608
+ @api_router.get("/tools/registry")
609
+ async def tools_registry(request: Request):
610
+ """Full ToolRegistry contract: handlers, governance, catalog, diagnostics."""
611
+ require_user(request)
612
+ return tool_registry_manifest()
613
+
614
+ @api_router.get("/tools/registry/diagnostics")
615
+ async def tools_registry_diagnostics(request: Request):
616
+ """Small drift check for CI/admin runtime readiness views."""
617
+ require_user(request)
618
+ return {"status": "ok", "diagnostics": tool_registry_diagnostics()}
605
619
 
606
620
 
607
621
  # ── MCP / skills / plugins router (latticeai.api.mcp, v1.3.0) ────────────────
@@ -99,6 +99,25 @@ class WorkspaceVSCodeRequest(BaseModel):
99
99
  content: str = ""
100
100
  selection: str = ""
101
101
  prompt: str = ""
102
+ extension_version: str = ""
103
+ workspace_folder: str = ""
104
+
105
+
106
+ class WorkspaceVSCodeStatusRequest(BaseModel):
107
+ status: str = "connected"
108
+ index_status: str = "unknown"
109
+ workspace_folder: str = ""
110
+ extension_version: str = ""
111
+ active_file: str = ""
112
+ detail: str = ""
113
+
114
+
115
+ _VSCODE_STATUS: Dict[str, object] = {
116
+ "connected": False,
117
+ "status": "offline",
118
+ "index_status": "unknown",
119
+ "last_seen_ms": 0,
120
+ }
102
121
 
103
122
 
104
123
  class WorkspaceCreateRequest(BaseModel):
@@ -630,9 +649,49 @@ def create_workspace_router(context: AppContext) -> APIRouter:
630
649
 
631
650
  # ── VS Code workflow bridge ───────────────────────────────────────────
632
651
 
652
+ @router.get("/workspace/vscode/status")
653
+ async def workspace_vscode_status(request: Request):
654
+ require_user(request)
655
+ last_seen = int(_VSCODE_STATUS.get("last_seen_ms") or 0)
656
+ now_ms = int(datetime.utcnow().timestamp() * 1000)
657
+ connected = last_seen > 0 and (now_ms - last_seen) < 60000
658
+ return {
659
+ **_VSCODE_STATUS,
660
+ "connected": connected,
661
+ "status": _VSCODE_STATUS.get("status") if connected else "offline",
662
+ }
663
+
664
+ @router.post("/workspace/vscode/status")
665
+ async def workspace_vscode_status_update(req: WorkspaceVSCodeStatusRequest, request: Request):
666
+ current_user = require_user(request)
667
+ now_ms = int(datetime.utcnow().timestamp() * 1000)
668
+ _VSCODE_STATUS.update({
669
+ "connected": True,
670
+ "status": req.status or "connected",
671
+ "index_status": req.index_status or "unknown",
672
+ "workspace_folder": req.workspace_folder,
673
+ "extension_version": req.extension_version,
674
+ "active_file": req.active_file,
675
+ "detail": req.detail,
676
+ "last_seen_ms": now_ms,
677
+ "user_email": current_user,
678
+ })
679
+ return {"status": "ok", **_VSCODE_STATUS}
680
+
633
681
  @router.post("/workspace/vscode/send")
634
682
  async def workspace_vscode_send(req: WorkspaceVSCodeRequest, request: Request):
635
683
  current_user = require_user(request)
684
+ now_ms = int(datetime.utcnow().timestamp() * 1000)
685
+ _VSCODE_STATUS.update({
686
+ "connected": True,
687
+ "status": "synced",
688
+ "index_status": "synced",
689
+ "workspace_folder": req.workspace_folder,
690
+ "extension_version": req.extension_version,
691
+ "active_file": req.file_path or "",
692
+ "last_seen_ms": now_ms,
693
+ "user_email": current_user,
694
+ })
636
695
  content = req.selection or req.content or req.prompt
637
696
  workflow = WORKSPACE_OS.create_workflow(
638
697
  name=f"VS Code: {req.action}",
@@ -11,7 +11,7 @@ from copy import deepcopy
11
11
  from typing import Any, Dict, List, Optional
12
12
 
13
13
 
14
- MARKETPLACE_VERSION = "7.0.0"
14
+ MARKETPLACE_VERSION = "7.2.0"
15
15
  TEMPLATE_KINDS = ("plugin", "workflow", "agent")
16
16
 
17
17
 
@@ -130,6 +130,7 @@ TOOL_GOVERNANCE: Dict[str, ToolPolicy] = {
130
130
  "todo_read": _r(),
131
131
  "local_list": _r(sandbox="home"),
132
132
  "local_read": _r(sandbox="home"),
133
+ "read_document": _r(sandbox="home"),
133
134
  "git_status": _rs(),
134
135
  "git_diff": _rs(),
135
136
  "git_log": _rs(),
@@ -189,6 +190,7 @@ MCP_TOOL_DESCRIPTIONS: Dict[str, str] = {
189
190
  "clear_history": "Clear chat history to reduce context and speed up responses.",
190
191
  "inspect_html": "Inspect local HTML structure and assets.",
191
192
  "preview_url": "Return a server URL for a workspace file.",
193
+ "create_web_project": "Create a web project scaffold inside the workspace.",
192
194
  "create_docx": "Create a Word DOCX document in the agent workspace.",
193
195
  "create_xlsx": "Create an XLSX spreadsheet in the agent workspace.",
194
196
  "create_pptx": "Create a PPTX presentation deck in the agent workspace.",
@@ -251,6 +253,51 @@ class ToolRegistry:
251
253
  def registered_tools(self) -> frozenset[str]:
252
254
  return frozenset(self.handlers)
253
255
 
256
+ def diagnostics(self) -> Dict[str, Any]:
257
+ """Return registry drift checks without executing any tool.
258
+
259
+ This is intentionally derived from the live registry instance, not from
260
+ duplicated constants, so admin/runtime surfaces can prove whether the
261
+ dispatch, governance, and catalog projections are still aligned.
262
+ """
263
+
264
+ registered = set(self.registered_tools())
265
+ governed = set(self.governance)
266
+ described = set(self.descriptions)
267
+ return {
268
+ "ready": not (governed - registered or registered - governed or registered - described),
269
+ "registered_tools": len(registered),
270
+ "governed_tools": len(governed),
271
+ "described_tools": len(described),
272
+ "governance_without_handler": sorted(governed - registered),
273
+ "handler_without_governance": sorted(registered - governed),
274
+ "handler_without_description": sorted(registered - described),
275
+ "description_without_handler": sorted(described - registered),
276
+ }
277
+
278
+ def manifest(self) -> Dict[str, Any]:
279
+ """Serializable tool registry contract for runtime/admin inspection."""
280
+
281
+ tools = []
282
+ for name in sorted(self.registered_tools() | set(self.governance) | set(self.descriptions)):
283
+ policy = self.policy_for(name, {})
284
+ tools.append({
285
+ "name": name,
286
+ "registered": name in self.handlers,
287
+ "governed": name in self.governance,
288
+ "described": name in self.descriptions,
289
+ "description": self.descriptions.get(name, ""),
290
+ "policy": dict(policy),
291
+ "permission": dict(self.permission(name, {})),
292
+ })
293
+ diagnostics = self.diagnostics()
294
+ return {
295
+ "status": "ok" if diagnostics["ready"] else "degraded",
296
+ "catalog_brief": self.catalog_brief.strip(),
297
+ "diagnostics": diagnostics,
298
+ "tools": tools,
299
+ }
300
+
254
301
  def execute(self, action: str, args: Dict[str, Any], *, error_cls: type[Exception]) -> Dict[str, Any]:
255
302
  handler = self.handlers.get(action)
256
303
  if handler is None:
@@ -19,7 +19,7 @@ from pathlib import Path
19
19
  from typing import Any, Callable, Dict, Iterable, List, Optional
20
20
 
21
21
 
22
- WORKSPACE_OS_VERSION = "7.0.0"
22
+ WORKSPACE_OS_VERSION = "7.2.0"
23
23
 
24
24
  # Workspace types separate single-user Personal workspaces from shared
25
25
  # Organization workspaces. Both keep the same local-first JSON store; the type
@@ -90,6 +90,12 @@ class ToolDispatchService:
90
90
  def permissions(self) -> list[ToolPermission]:
91
91
  return self.registry.permissions()
92
92
 
93
+ def diagnostics(self) -> Dict[str, Any]:
94
+ return self.registry.diagnostics()
95
+
96
+ def manifest(self) -> Dict[str, Any]:
97
+ return self.registry.manifest()
98
+
93
99
  def check_role(self, tool_name: str, current_user: str) -> None:
94
100
  if tool_name not in self.registry.admin_only_tools:
95
101
  return
@@ -131,6 +137,14 @@ def list_tool_permissions() -> list:
131
137
  return DEFAULT_TOOL_DISPATCH_SERVICE.permissions()
132
138
 
133
139
 
140
+ def tool_registry_diagnostics() -> Dict[str, Any]:
141
+ return DEFAULT_TOOL_DISPATCH_SERVICE.diagnostics()
142
+
143
+
144
+ def tool_registry_manifest() -> Dict[str, Any]:
145
+ return DEFAULT_TOOL_DISPATCH_SERVICE.manifest()
146
+
147
+
134
148
  def check_tool_role(tool_name: str, current_user: str) -> None:
135
149
  DEFAULT_TOOL_DISPATCH_SERVICE.check_role(tool_name, current_user)
136
150
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ltcai",
3
- "version": "7.0.0",
3
+ "version": "7.2.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": {
@@ -1654,7 +1654,7 @@ dependencies = [
1654
1654
 
1655
1655
  [[package]]
1656
1656
  name = "lattice-ai-desktop"
1657
- version = "7.0.0"
1657
+ version = "7.2.0"
1658
1658
  dependencies = [
1659
1659
  "plist",
1660
1660
  "serde",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "lattice-ai-desktop"
3
- version = "7.0.0"
3
+ version = "7.2.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": "7.0.0",
4
+ "version": "7.2.0",
5
5
  "identifier": "ai.lattice.desktop",
6
6
  "build": {
7
7
  "beforeDevCommand": "npm run frontend:dev",
@@ -1,20 +1,20 @@
1
1
  {
2
- "version": "7.0.0",
2
+ "version": "7.2.0",
3
3
  "generated_at": "vite",
4
4
  "entrypoints": {
5
5
  "app": "/static/app/index.html"
6
6
  },
7
7
  "assets": {
8
8
  "../node_modules/@tauri-apps/api/core.js": "/static/app/assets/core-CwxXejkd.js",
9
- "_primitives-DcO2H3yh.js": "/static/app/assets/primitives-DcO2H3yh.js",
10
- "_textarea-DR2Tyy_6.js": "/static/app/assets/textarea-DR2Tyy_6.js",
11
- "index.html": "/static/app/assets/index-C-7aHabu.js",
12
- "assets/index-DKFpn5Kn.css": "/static/app/assets/index-DKFpn5Kn.css",
13
- "src/pages/Act.tsx": "/static/app/assets/Act-DhLaHnrT.js",
14
- "src/pages/Brain.tsx": "/static/app/assets/Brain-DS7NULyY.js",
15
- "src/pages/Capture.tsx": "/static/app/assets/Capture-CAKouj52.js",
16
- "src/pages/Library.tsx": "/static/app/assets/Library-B_hW4AwR.js",
17
- "src/pages/System.tsx": "/static/app/assets/System-9OAoXWPz.js"
9
+ "_primitives-CdwcE--L.js": "/static/app/assets/primitives-CdwcE--L.js",
10
+ "_textarea-CqOdBPL1.js": "/static/app/assets/textarea-CqOdBPL1.js",
11
+ "index.html": "/static/app/assets/index-COuGp7_5.js",
12
+ "assets/index-Bi_bpigM.css": "/static/app/assets/index-Bi_bpigM.css",
13
+ "src/pages/Act.tsx": "/static/app/assets/Act-Di4tRFWY.js",
14
+ "src/pages/Brain.tsx": "/static/app/assets/Brain-BZB3Gy9w.js",
15
+ "src/pages/Capture.tsx": "/static/app/assets/Capture-tNyYWxnh.js",
16
+ "src/pages/Library.tsx": "/static/app/assets/Library-DAtDDLdg.js",
17
+ "src/pages/System.tsx": "/static/app/assets/System-DEu0xNUc.js"
18
18
  },
19
19
  "vite": {
20
20
  "../node_modules/@tauri-apps/api/core.js": {
@@ -23,22 +23,22 @@
23
23
  "src": "../node_modules/@tauri-apps/api/core.js",
24
24
  "isDynamicEntry": true
25
25
  },
26
- "_primitives-DcO2H3yh.js": {
27
- "file": "assets/primitives-DcO2H3yh.js",
26
+ "_primitives-CdwcE--L.js": {
27
+ "file": "assets/primitives-CdwcE--L.js",
28
28
  "name": "primitives",
29
29
  "imports": [
30
30
  "index.html"
31
31
  ]
32
32
  },
33
- "_textarea-DR2Tyy_6.js": {
34
- "file": "assets/textarea-DR2Tyy_6.js",
33
+ "_textarea-CqOdBPL1.js": {
34
+ "file": "assets/textarea-CqOdBPL1.js",
35
35
  "name": "textarea",
36
36
  "imports": [
37
37
  "index.html"
38
38
  ]
39
39
  },
40
40
  "index.html": {
41
- "file": "assets/index-C-7aHabu.js",
41
+ "file": "assets/index-COuGp7_5.js",
42
42
  "name": "index",
43
43
  "src": "index.html",
44
44
  "isEntry": true,
@@ -51,59 +51,59 @@
51
51
  "src/pages/System.tsx"
52
52
  ],
53
53
  "css": [
54
- "assets/index-DKFpn5Kn.css"
54
+ "assets/index-Bi_bpigM.css"
55
55
  ]
56
56
  },
57
57
  "src/pages/Act.tsx": {
58
- "file": "assets/Act-DhLaHnrT.js",
58
+ "file": "assets/Act-Di4tRFWY.js",
59
59
  "name": "Act",
60
60
  "src": "src/pages/Act.tsx",
61
61
  "isDynamicEntry": true,
62
62
  "imports": [
63
63
  "index.html",
64
- "_primitives-DcO2H3yh.js",
65
- "_textarea-DR2Tyy_6.js"
64
+ "_primitives-CdwcE--L.js",
65
+ "_textarea-CqOdBPL1.js"
66
66
  ]
67
67
  },
68
68
  "src/pages/Brain.tsx": {
69
- "file": "assets/Brain-DS7NULyY.js",
69
+ "file": "assets/Brain-BZB3Gy9w.js",
70
70
  "name": "Brain",
71
71
  "src": "src/pages/Brain.tsx",
72
72
  "isDynamicEntry": true,
73
73
  "imports": [
74
74
  "index.html",
75
- "_primitives-DcO2H3yh.js",
76
- "_textarea-DR2Tyy_6.js"
75
+ "_primitives-CdwcE--L.js",
76
+ "_textarea-CqOdBPL1.js"
77
77
  ]
78
78
  },
79
79
  "src/pages/Capture.tsx": {
80
- "file": "assets/Capture-CAKouj52.js",
80
+ "file": "assets/Capture-tNyYWxnh.js",
81
81
  "name": "Capture",
82
82
  "src": "src/pages/Capture.tsx",
83
83
  "isDynamicEntry": true,
84
84
  "imports": [
85
85
  "index.html",
86
- "_primitives-DcO2H3yh.js"
86
+ "_primitives-CdwcE--L.js"
87
87
  ]
88
88
  },
89
89
  "src/pages/Library.tsx": {
90
- "file": "assets/Library-B_hW4AwR.js",
90
+ "file": "assets/Library-DAtDDLdg.js",
91
91
  "name": "Library",
92
92
  "src": "src/pages/Library.tsx",
93
93
  "isDynamicEntry": true,
94
94
  "imports": [
95
95
  "index.html",
96
- "_primitives-DcO2H3yh.js"
96
+ "_primitives-CdwcE--L.js"
97
97
  ]
98
98
  },
99
99
  "src/pages/System.tsx": {
100
- "file": "assets/System-9OAoXWPz.js",
100
+ "file": "assets/System-DEu0xNUc.js",
101
101
  "name": "System",
102
102
  "src": "src/pages/System.tsx",
103
103
  "isDynamicEntry": true,
104
104
  "imports": [
105
105
  "index.html",
106
- "_primitives-DcO2H3yh.js"
106
+ "_primitives-CdwcE--L.js"
107
107
  ]
108
108
  }
109
109
  }