ltcai 7.9.0 → 8.1.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 (107) hide show
  1. package/README.md +35 -49
  2. package/docs/CHANGELOG.md +35 -0
  3. package/docs/V3_FRONTEND.md +11 -5
  4. package/lattice_brain/__init__.py +1 -1
  5. package/lattice_brain/embeddings.py +9 -1
  6. package/lattice_brain/graph/projection.py +19 -5
  7. package/lattice_brain/graph/provenance.py +26 -4
  8. package/lattice_brain/graph/write_master.py +30 -3
  9. package/lattice_brain/runtime/multi_agent.py +1 -1
  10. package/latticeai/__init__.py +1 -1
  11. package/latticeai/app_factory.py +13 -134
  12. package/latticeai/core/local_embeddings.py +8 -0
  13. package/latticeai/core/marketplace.py +1 -1
  14. package/latticeai/core/mcp_registry.py +140 -1
  15. package/latticeai/core/tool_registry.py +7 -0
  16. package/latticeai/core/workspace_os.py +1 -1
  17. package/latticeai/services/architecture_readiness.py +50 -6
  18. package/latticeai/services/model_runtime.py +36 -2
  19. package/latticeai/services/product_readiness.py +19 -17
  20. package/package.json +2 -2
  21. package/scripts/build_frontend_assets.mjs +11 -2
  22. package/src-tauri/Cargo.lock +1 -1
  23. package/src-tauri/Cargo.toml +1 -1
  24. package/src-tauri/tauri.conf.json +1 -1
  25. package/static/app/asset-manifest.json +11 -102
  26. package/static/app/assets/Act-BOO66G-c.js +1 -0
  27. package/static/app/assets/Brain-C6lEYiD7.js +321 -0
  28. package/static/app/assets/{Capture-B9Tlhzqr.js → Capture-TATXBRDw.js} +1 -2
  29. package/static/app/assets/Library-DK4FIp8a.js +1 -0
  30. package/static/app/assets/System-Bgs6Ql7x.js +1 -0
  31. package/static/app/assets/core-CwxXejkd.js +1 -2
  32. package/static/app/assets/index-Bvv79nre.js +16 -0
  33. package/static/app/assets/index-Dslqglia.css +2 -0
  34. package/static/app/assets/primitives-B70WOra0.js +1 -0
  35. package/static/app/assets/{textarea-BZk6ybp5.js → textarea-Czrd9gwM.js} +1 -2
  36. package/static/app/index.html +3 -10
  37. package/static/app/theme-boot.js +8 -0
  38. package/static/sw.js +1 -1
  39. package/frontend/index.html +0 -24
  40. package/frontend/openapi.json +0 -15425
  41. package/frontend/src/App.tsx +0 -243
  42. package/frontend/src/api/client.ts +0 -580
  43. package/frontend/src/api/openapi.ts +0 -17892
  44. package/frontend/src/components/AdminAccessGate.tsx +0 -70
  45. package/frontend/src/components/FeedbackState.tsx +0 -45
  46. package/frontend/src/components/LanguageSwitcher.tsx +0 -23
  47. package/frontend/src/components/LivingBrain.tsx +0 -220
  48. package/frontend/src/components/ProductFlow.tsx +0 -171
  49. package/frontend/src/components/WorkspaceProfileSwitcher.tsx +0 -176
  50. package/frontend/src/components/onboarding/AnalysisScreen.tsx +0 -135
  51. package/frontend/src/components/onboarding/DownloadConsentPanel.tsx +0 -29
  52. package/frontend/src/components/onboarding/InstallScreen.tsx +0 -263
  53. package/frontend/src/components/onboarding/LanguageChooser.tsx +0 -23
  54. package/frontend/src/components/onboarding/LoginScreen.tsx +0 -131
  55. package/frontend/src/components/onboarding/ProductFlowScreens.tsx +0 -13
  56. package/frontend/src/components/onboarding/RecommendationScreen.tsx +0 -116
  57. package/frontend/src/components/onboarding/recommendationModel.ts +0 -189
  58. package/frontend/src/components/primitives.tsx +0 -392
  59. package/frontend/src/components/ui/badge.tsx +0 -27
  60. package/frontend/src/components/ui/button.tsx +0 -37
  61. package/frontend/src/components/ui/card.tsx +0 -22
  62. package/frontend/src/components/ui/input.tsx +0 -16
  63. package/frontend/src/components/ui/textarea.tsx +0 -16
  64. package/frontend/src/features/admin/AdminConsole.tsx +0 -334
  65. package/frontend/src/features/brain/BrainCarePanel.tsx +0 -254
  66. package/frontend/src/features/brain/BrainComposer.tsx +0 -85
  67. package/frontend/src/features/brain/BrainConversation.tsx +0 -688
  68. package/frontend/src/features/brain/BrainGraphLayer.tsx +0 -365
  69. package/frontend/src/features/brain/BrainHome.tsx +0 -624
  70. package/frontend/src/features/brain/BrainMemoryLayer.tsx +0 -45
  71. package/frontend/src/features/brain/BrainOverviewPanel.tsx +0 -149
  72. package/frontend/src/features/brain/BrainRelationshipLayer.tsx +0 -43
  73. package/frontend/src/features/brain/DepthEmergence.tsx +0 -53
  74. package/frontend/src/features/brain/brainData.ts +0 -246
  75. package/frontend/src/features/brain/graphLayout.ts +0 -37
  76. package/frontend/src/features/brain/types.ts +0 -150
  77. package/frontend/src/features/review/ReviewCard.tsx +0 -100
  78. package/frontend/src/features/review/ReviewInbox.tsx +0 -127
  79. package/frontend/src/features/review/reviewHelpers.ts +0 -69
  80. package/frontend/src/i18n.ts +0 -1303
  81. package/frontend/src/lib/utils.ts +0 -33
  82. package/frontend/src/main.tsx +0 -23
  83. package/frontend/src/pages/Act.tsx +0 -458
  84. package/frontend/src/pages/Ask.tsx +0 -14
  85. package/frontend/src/pages/Brain.tsx +0 -914
  86. package/frontend/src/pages/Capture.tsx +0 -258
  87. package/frontend/src/pages/Library.tsx +0 -486
  88. package/frontend/src/pages/System.tsx +0 -621
  89. package/frontend/src/routes.ts +0 -92
  90. package/frontend/src/store/appStore.ts +0 -94
  91. package/frontend/src/styles.css +0 -6579
  92. package/static/app/assets/Act-DOvf59ru.js +0 -2
  93. package/static/app/assets/Act-DOvf59ru.js.map +0 -1
  94. package/static/app/assets/Brain-C7_0mEiI.js +0 -322
  95. package/static/app/assets/Brain-C7_0mEiI.js.map +0 -1
  96. package/static/app/assets/Capture-B9Tlhzqr.js.map +0 -1
  97. package/static/app/assets/Library-BJPEEm5O.js +0 -2
  98. package/static/app/assets/Library-BJPEEm5O.js.map +0 -1
  99. package/static/app/assets/System-D6t9jo9V.js +0 -2
  100. package/static/app/assets/System-D6t9jo9V.js.map +0 -1
  101. package/static/app/assets/core-CwxXejkd.js.map +0 -1
  102. package/static/app/assets/index-C7g26IF6.css +0 -2
  103. package/static/app/assets/index-DbcEYJQ2.js +0 -17
  104. package/static/app/assets/index-DbcEYJQ2.js.map +0 -1
  105. package/static/app/assets/primitives-CD38lt4n.js +0 -2
  106. package/static/app/assets/primitives-CD38lt4n.js.map +0 -1
  107. package/static/app/assets/textarea-BZk6ybp5.js.map +0 -1
@@ -1,243 +0,0 @@
1
- import * as React from "react";
2
- import { type BrainState } from "@/components/LivingBrain";
3
- import { ProductFlow, readProductFlowComplete } from "@/components/ProductFlow";
4
- import { useAppStore } from "@/store/appStore";
5
- import { parseHash, productShellRoutes } from "@/routes";
6
- import { BrainHome } from "@/features/brain/BrainHome";
7
- import { AdminConsole } from "@/features/admin/AdminConsole";
8
- import { WorkspaceProfileSwitcher } from "@/components/WorkspaceProfileSwitcher";
9
- import { AdminAccessGate } from "@/components/AdminAccessGate";
10
- import { t, type Language } from "@/i18n";
11
- import { latticeApi } from "@/api/client";
12
- import { useQuery } from "@tanstack/react-query";
13
- import { FeedbackState } from "@/components/FeedbackState";
14
-
15
- const ActPage = React.lazy(() => import("@/pages/Act").then((module) => ({ default: module.ActPage })));
16
- const BrainPage = React.lazy(() => import("@/pages/Brain").then((module) => ({ default: module.BrainPage })));
17
- const CapturePage = React.lazy(() => import("@/pages/Capture").then((module) => ({ default: module.CapturePage })));
18
- const LibraryPage = React.lazy(() => import("@/pages/Library").then((module) => ({ default: module.LibraryPage })));
19
- const SystemPage = React.lazy(() => import("@/pages/System").then((module) => ({ default: module.SystemPage })));
20
-
21
- export default function App() {
22
- const theme = useAppStore((state) => state.theme);
23
- const language = useAppStore((state) => state.language);
24
- const [flowComplete, setFlowComplete] = React.useState(readProductFlowComplete);
25
- const rawRoute = useHashRoute();
26
- const parsed = React.useMemo(() => parseHash(), [rawRoute]);
27
- const { state: brainState, intensity, setBrain } = useBrainState();
28
-
29
- React.useEffect(() => {
30
- document.documentElement.dataset.theme = theme;
31
- document.documentElement.lang = language === "ko" ? "ko" : "en";
32
- }, [theme, language]);
33
-
34
- React.useEffect(() => {
35
- const onKey = (event: KeyboardEvent) => {
36
- if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
37
- event.preventDefault();
38
- document.querySelector<HTMLTextAreaElement>(".brain-composer textarea")?.focus();
39
- }
40
- };
41
- window.addEventListener("keydown", onKey);
42
- return () => window.removeEventListener("keydown", onKey);
43
- }, []);
44
-
45
- if (!flowComplete) {
46
- return <ProductFlow onComplete={() => setFlowComplete(true)} />;
47
- }
48
-
49
- return (
50
- <div className="brain-space">
51
- <div className="brain-field" />
52
- {rawRoute.startsWith("/admin") ? (
53
- <AdminConsole onBack={() => navigateHash("/brain")} />
54
- ) : parsed.primary === "act" ? (
55
- <BrainShell active={parsed.primary}>
56
- <React.Suspense fallback={<PageLoader />}>
57
- <ActPage initialTab={parsed.tab} />
58
- </React.Suspense>
59
- </BrainShell>
60
- ) : parsed.primary === "capture" ? (
61
- <BrainShell active={parsed.primary}>
62
- <React.Suspense fallback={<PageLoader />}>
63
- <CapturePage initialTab={parsed.tab} />
64
- </React.Suspense>
65
- </BrainShell>
66
- ) : parsed.primary === "library" ? (
67
- <BrainShell active={parsed.primary}>
68
- <React.Suspense fallback={<PageLoader />}>
69
- <LibraryPage initialTab={parsed.tab} />
70
- </React.Suspense>
71
- </BrainShell>
72
- ) : parsed.primary === "system" ? (
73
- <BrainShell active={parsed.primary}>
74
- <React.Suspense fallback={<PageLoader />}>
75
- <SystemPage initialTab={parsed.tab} />
76
- </React.Suspense>
77
- </BrainShell>
78
- ) : parsed.primary === "memory" ? (
79
- <BrainShell active="memory">
80
- <React.Suspense fallback={<PageLoader />}>
81
- <BrainPage initialTab="memory" />
82
- </React.Suspense>
83
- </BrainShell>
84
- ) : parsed.primary === "brain" && parsed.tab && parsed.tab !== "conversation" ? (
85
- <BrainShell active="brain">
86
- <React.Suspense fallback={<PageLoader />}>
87
- <BrainPage initialTab={parsed.tab} />
88
- </React.Suspense>
89
- </BrainShell>
90
- ) : (
91
- <BrainShell active="brain">
92
- <BrainHome brainState={brainState} intensity={intensity} onBrainChange={setBrain} />
93
- </BrainShell>
94
- )}
95
- </div>
96
- );
97
- }
98
-
99
- function BrainShell({
100
- active,
101
- children,
102
- }: {
103
- active: string;
104
- children: React.ReactNode;
105
- }) {
106
- const language = useAppStore((state) => state.language);
107
- return (
108
- <main className="brain-shell-page" aria-label="Lattice workspace">
109
- <nav className="brain-shell-nav" aria-label="Brain workspace navigation">
110
- {productShellRoutes.map((item) => (
111
- <button
112
- key={item.id}
113
- type="button"
114
- className={item.id === active ? "is-active" : ""}
115
- aria-current={item.id === active ? "page" : undefined}
116
- onClick={() => navigateHash(`/${item.path}`)}
117
- >
118
- {t(language, item.labelKey)}
119
- </button>
120
- ))}
121
- <div className="brain-shell-switchers" aria-label={t(language, "shell.workspace.label")}>
122
- <VsCodeSyncStatus language={language} />
123
- <WorkspaceProfileSwitcher language={language} />
124
- <AdminAccessGate language={language} />
125
- </div>
126
- </nav>
127
- <section className="brain-shell-content">
128
- <ExternalConsentStatus language={language} />
129
- {children}
130
- </section>
131
- </main>
132
- );
133
- }
134
-
135
- function ExternalConsentStatus({ language }: { language: Language }) {
136
- const externalConsent = useAppStore((state) => state.externalConsent);
137
- const setExternalConsent = useAppStore((state) => state.setExternalConsent);
138
-
139
- return (
140
- <section className="external-consent-status" aria-label={t(language, "feedback.consent.aria")}>
141
- <FeedbackState
142
- tone={externalConsent ? "empty" : "error"}
143
- language={language}
144
- title={externalConsent ? t(language, "feedback.consent.activeTitle") : t(language, "feedback.consent.revokedTitle")}
145
- body={externalConsent ? t(language, "feedback.consent.activeBody") : t(language, "feedback.consent.revokedBody")}
146
- actionLabel={externalConsent ? t(language, "feedback.consent.revoke") : t(language, "feedback.consent.reenable")}
147
- onAction={() => setExternalConsent(!externalConsent)}
148
- />
149
- </section>
150
- );
151
- }
152
-
153
- function VsCodeSyncStatus({ language }: { language: Language }) {
154
- const bridge = useQuery({
155
- queryKey: ["workspaceVscodeStatus"],
156
- queryFn: latticeApi.workspaceVscodeStatus,
157
- refetchInterval: 15000,
158
- });
159
- const index = useQuery({
160
- queryKey: ["index"],
161
- queryFn: latticeApi.indexStatus,
162
- refetchInterval: 15000,
163
- });
164
- const data = bridge.data?.data as Record<string, unknown> | undefined;
165
- const lastSeen = Number(data?.last_seen_ms || 0);
166
- const connected = Boolean(data?.connected) || (lastSeen > 0 && Date.now() - lastSeen < 60000);
167
- const indexData = index.data?.data as Record<string, unknown> | undefined;
168
- const indexStatus = String(indexData?.status || indexData?.state || "");
169
- const indexing = /index|build|running|pending/i.test(indexStatus);
170
- const state = bridge.isLoading
171
- ? "checking"
172
- : !connected
173
- ? "offline"
174
- : indexing
175
- ? "indexing"
176
- : "synced";
177
- const labelKey = `shell.sync.${state}`;
178
- const detail = connected
179
- ? t(language, "shell.sync.detail")
180
- : t(language, "shell.sync.detailOffline");
181
-
182
- return (
183
- <button
184
- type="button"
185
- className={`vscode-sync-status is-${state}`}
186
- aria-label={`${t(language, "shell.sync.label")}: ${t(language, labelKey)}`}
187
- title={`${t(language, "shell.sync.label")}: ${t(language, labelKey)}\n${detail}`}
188
- onClick={() => {
189
- window.location.hash = "/settings";
190
- }}
191
- >
192
- <span className="vscode-sync-dot" aria-hidden="true" />
193
- <span className="vscode-sync-copy">
194
- <strong>{t(language, "shell.sync.label")}</strong>
195
- <small>{t(language, labelKey)}</small>
196
- </span>
197
- </button>
198
- );
199
- }
200
-
201
- function PageLoader() {
202
- return (
203
- <div className="brain-shell-loader" role="status">
204
- Loading Brain workspace...
205
- </div>
206
- );
207
- }
208
-
209
- function useHashRoute() {
210
- const read = React.useCallback(() => {
211
- const hash = window.location.hash.replace(/^#/, "");
212
- return hash.startsWith("/") ? hash : "/brain";
213
- }, []);
214
- const [route, setRoute] = React.useState(read);
215
-
216
- React.useEffect(() => {
217
- const onHashChange = () => setRoute(read());
218
- window.addEventListener("hashchange", onHashChange);
219
- return () => window.removeEventListener("hashchange", onHashChange);
220
- }, [read]);
221
-
222
- return route;
223
- }
224
-
225
- function navigateHash(route: string) {
226
- window.location.hash = route;
227
- }
228
-
229
- function useBrainState() {
230
- const [state, setState] = React.useState<BrainState>("idle");
231
- const [intensity, setIntensity] = React.useState(0.58);
232
-
233
- const setBrain = React.useCallback((next: BrainState, nextIntensity?: number) => {
234
- setState(next);
235
- if (nextIntensity !== undefined) setIntensity(clamp(nextIntensity, 0.38, 1));
236
- }, []);
237
-
238
- return { state, intensity, setBrain };
239
- }
240
-
241
- function clamp(value: number, min: number, max: number) {
242
- return Math.max(min, Math.min(max, value));
243
- }