@gmickel/gno 0.28.2 → 0.29.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.
- package/README.md +10 -2
- package/package.json +1 -1
- package/src/app/constants.ts +4 -2
- package/src/cli/commands/mcp/install.ts +4 -4
- package/src/cli/commands/mcp/status.ts +7 -7
- package/src/cli/commands/skill/install.ts +5 -5
- package/src/cli/program.ts +2 -2
- package/src/collection/add.ts +10 -0
- package/src/collection/types.ts +1 -0
- package/src/config/types.ts +12 -2
- package/src/core/depth-policy.ts +1 -1
- package/src/core/file-ops.ts +38 -0
- package/src/llm/registry.ts +20 -4
- package/src/serve/AGENTS.md +16 -16
- package/src/serve/CLAUDE.md +16 -16
- package/src/serve/config-sync.ts +32 -1
- package/src/serve/connectors.ts +243 -0
- package/src/serve/context.ts +9 -0
- package/src/serve/doc-events.ts +31 -1
- package/src/serve/embed-scheduler.ts +12 -0
- package/src/serve/import-preview.ts +173 -0
- package/src/serve/public/app.tsx +101 -7
- package/src/serve/public/components/AIModelSelector.tsx +383 -145
- package/src/serve/public/components/AddCollectionDialog.tsx +123 -7
- package/src/serve/public/components/BootstrapStatus.tsx +133 -0
- package/src/serve/public/components/CaptureModal.tsx +5 -2
- package/src/serve/public/components/CollectionsEmptyState.tsx +63 -0
- package/src/serve/public/components/FirstRunWizard.tsx +622 -0
- package/src/serve/public/components/HealthCenter.tsx +128 -0
- package/src/serve/public/components/IndexingProgress.tsx +21 -2
- package/src/serve/public/components/QuickSwitcher.tsx +62 -36
- package/src/serve/public/components/TagInput.tsx +5 -1
- package/src/serve/public/components/WikiLinkAutocomplete.tsx +15 -6
- package/src/serve/public/components/WorkspaceTabs.tsx +60 -0
- package/src/serve/public/hooks/use-doc-events.ts +48 -4
- package/src/serve/public/lib/local-history.ts +40 -7
- package/src/serve/public/lib/navigation-state.ts +156 -0
- package/src/serve/public/lib/workspace-tabs.ts +235 -0
- package/src/serve/public/pages/Ask.tsx +11 -1
- package/src/serve/public/pages/Browse.tsx +73 -0
- package/src/serve/public/pages/Collections.tsx +29 -13
- package/src/serve/public/pages/Connectors.tsx +178 -0
- package/src/serve/public/pages/Dashboard.tsx +493 -67
- package/src/serve/public/pages/DocView.tsx +192 -34
- package/src/serve/public/pages/DocumentEditor.tsx +127 -5
- package/src/serve/public/pages/Search.tsx +12 -1
- package/src/serve/routes/api.ts +532 -62
- package/src/serve/server.ts +79 -2
- package/src/serve/status-model.ts +149 -0
- package/src/serve/status.ts +706 -0
- package/src/serve/watch-service.ts +73 -8
- package/src/types/electrobun-shell.d.ts +43 -0
package/src/serve/public/app.tsx
CHANGED
|
@@ -2,14 +2,26 @@ import { useCallback, useEffect, useMemo, useState } from "react";
|
|
|
2
2
|
import { createRoot } from "react-dom/client";
|
|
3
3
|
|
|
4
4
|
import { HelpButton } from "./components/HelpButton";
|
|
5
|
-
import { QuickSwitcher
|
|
5
|
+
import { QuickSwitcher } from "./components/QuickSwitcher";
|
|
6
6
|
import { ShortcutHelpModal } from "./components/ShortcutHelpModal";
|
|
7
|
+
import { WorkspaceTabs } from "./components/WorkspaceTabs";
|
|
7
8
|
import { CaptureModalProvider, useCaptureModal } from "./hooks/useCaptureModal";
|
|
8
9
|
import { useKeyboardShortcuts } from "./hooks/useKeyboardShortcuts";
|
|
9
10
|
import { parseDocumentDeepLink } from "./lib/deep-links";
|
|
11
|
+
import { saveRecentDocument } from "./lib/navigation-state";
|
|
12
|
+
import {
|
|
13
|
+
activateWorkspaceTab,
|
|
14
|
+
closeWorkspaceTab,
|
|
15
|
+
createWorkspaceTab,
|
|
16
|
+
loadWorkspaceState,
|
|
17
|
+
saveWorkspaceState,
|
|
18
|
+
updateActiveTabLocation,
|
|
19
|
+
type WorkspaceState,
|
|
20
|
+
} from "./lib/workspace-tabs";
|
|
10
21
|
import Ask from "./pages/Ask";
|
|
11
22
|
import Browse from "./pages/Browse";
|
|
12
23
|
import Collections from "./pages/Collections";
|
|
24
|
+
import Connectors from "./pages/Connectors";
|
|
13
25
|
import Dashboard from "./pages/Dashboard";
|
|
14
26
|
import DocumentEditor from "./pages/DocumentEditor";
|
|
15
27
|
import DocView from "./pages/DocView";
|
|
@@ -24,7 +36,8 @@ type Route =
|
|
|
24
36
|
| "/ask"
|
|
25
37
|
| "/edit"
|
|
26
38
|
| "/collections"
|
|
27
|
-
| "/graph"
|
|
39
|
+
| "/graph"
|
|
40
|
+
| "/connectors";
|
|
28
41
|
type Navigate = (to: string | number) => void;
|
|
29
42
|
|
|
30
43
|
const routes: Record<Route, React.ComponentType<{ navigate: Navigate }>> = {
|
|
@@ -34,6 +47,7 @@ const routes: Record<Route, React.ComponentType<{ navigate: Navigate }>> = {
|
|
|
34
47
|
"/doc": DocView,
|
|
35
48
|
"/edit": DocumentEditor,
|
|
36
49
|
"/collections": Collections,
|
|
50
|
+
"/connectors": Connectors,
|
|
37
51
|
"/ask": Ask,
|
|
38
52
|
"/graph": GraphView,
|
|
39
53
|
};
|
|
@@ -43,13 +57,21 @@ interface AppContentProps {
|
|
|
43
57
|
navigate: Navigate;
|
|
44
58
|
shortcutHelpOpen: boolean;
|
|
45
59
|
setShortcutHelpOpen: (open: boolean) => void;
|
|
60
|
+
workspace: WorkspaceState;
|
|
61
|
+
onActivateTab: (tabId: string) => void;
|
|
62
|
+
onCloseTab: (tabId: string) => void;
|
|
63
|
+
onNewTab: () => void;
|
|
46
64
|
}
|
|
47
65
|
|
|
48
66
|
function AppContent({
|
|
49
67
|
location,
|
|
50
68
|
navigate,
|
|
69
|
+
onActivateTab,
|
|
70
|
+
onCloseTab,
|
|
71
|
+
onNewTab,
|
|
51
72
|
shortcutHelpOpen,
|
|
52
73
|
setShortcutHelpOpen,
|
|
74
|
+
workspace,
|
|
53
75
|
}: AppContentProps) {
|
|
54
76
|
const { openCapture } = useCaptureModal();
|
|
55
77
|
const [quickSwitcherOpen, setQuickSwitcherOpen] = useState(false);
|
|
@@ -112,6 +134,13 @@ function AppContent({
|
|
|
112
134
|
return (
|
|
113
135
|
<>
|
|
114
136
|
<div className="flex min-h-screen flex-col">
|
|
137
|
+
<WorkspaceTabs
|
|
138
|
+
activeTabId={workspace.activeTabId}
|
|
139
|
+
onActivate={onActivateTab}
|
|
140
|
+
onClose={onCloseTab}
|
|
141
|
+
onNewTab={onNewTab}
|
|
142
|
+
tabs={workspace.tabs}
|
|
143
|
+
/>
|
|
115
144
|
<div className="flex-1">
|
|
116
145
|
<Page key={location} navigate={navigate} />
|
|
117
146
|
</div>
|
|
@@ -179,25 +208,86 @@ function AppContent({
|
|
|
179
208
|
}
|
|
180
209
|
|
|
181
210
|
function App() {
|
|
182
|
-
const
|
|
183
|
-
|
|
211
|
+
const initialLocation = window.location.pathname + window.location.search;
|
|
212
|
+
const [workspace, setWorkspace] = useState<WorkspaceState>(() =>
|
|
213
|
+
loadWorkspaceState(initialLocation)
|
|
184
214
|
);
|
|
185
215
|
const [shortcutHelpOpen, setShortcutHelpOpen] = useState(false);
|
|
216
|
+
const activeTab =
|
|
217
|
+
workspace.tabs.find((tab) => tab.id === workspace.activeTabId) ??
|
|
218
|
+
workspace.tabs[0];
|
|
219
|
+
const location = activeTab?.location ?? "/";
|
|
186
220
|
|
|
187
221
|
useEffect(() => {
|
|
188
|
-
const
|
|
189
|
-
|
|
222
|
+
const currentLocation = window.location.pathname + window.location.search;
|
|
223
|
+
if (location !== currentLocation) {
|
|
224
|
+
window.history.replaceState({}, "", location);
|
|
225
|
+
}
|
|
226
|
+
}, [location]);
|
|
227
|
+
|
|
228
|
+
useEffect(() => {
|
|
229
|
+
const handlePopState = () => {
|
|
230
|
+
setWorkspace((current) =>
|
|
231
|
+
updateActiveTabLocation(
|
|
232
|
+
current,
|
|
233
|
+
window.location.pathname + window.location.search
|
|
234
|
+
)
|
|
235
|
+
);
|
|
236
|
+
};
|
|
190
237
|
window.addEventListener("popstate", handlePopState);
|
|
191
238
|
return () => window.removeEventListener("popstate", handlePopState);
|
|
192
239
|
}, []);
|
|
193
240
|
|
|
241
|
+
useEffect(() => {
|
|
242
|
+
saveWorkspaceState(workspace);
|
|
243
|
+
}, [workspace]);
|
|
244
|
+
|
|
194
245
|
const navigate = useCallback((to: string | number) => {
|
|
195
246
|
if (typeof to === "number") {
|
|
196
247
|
window.history.go(to);
|
|
197
248
|
return;
|
|
198
249
|
}
|
|
199
250
|
window.history.pushState({}, "", to);
|
|
200
|
-
|
|
251
|
+
setWorkspace((current) => updateActiveTabLocation(current, to));
|
|
252
|
+
}, []);
|
|
253
|
+
|
|
254
|
+
const activateTab = useCallback((tabId: string) => {
|
|
255
|
+
setWorkspace((current) => {
|
|
256
|
+
const next = activateWorkspaceTab(current, tabId);
|
|
257
|
+
const tab =
|
|
258
|
+
next.tabs.find((entry) => entry.id === next.activeTabId) ??
|
|
259
|
+
next.tabs[0];
|
|
260
|
+
if (tab) {
|
|
261
|
+
window.history.pushState({}, "", tab.location);
|
|
262
|
+
}
|
|
263
|
+
return next;
|
|
264
|
+
});
|
|
265
|
+
}, []);
|
|
266
|
+
|
|
267
|
+
const closeTab = useCallback((tabId: string) => {
|
|
268
|
+
setWorkspace((current) => {
|
|
269
|
+
const next = closeWorkspaceTab(current, tabId);
|
|
270
|
+
const tab =
|
|
271
|
+
next.tabs.find((entry) => entry.id === next.activeTabId) ??
|
|
272
|
+
next.tabs[0];
|
|
273
|
+
if (tab) {
|
|
274
|
+
window.history.replaceState({}, "", tab.location);
|
|
275
|
+
}
|
|
276
|
+
return next;
|
|
277
|
+
});
|
|
278
|
+
}, []);
|
|
279
|
+
|
|
280
|
+
const openNewTab = useCallback(() => {
|
|
281
|
+
setWorkspace((current) => {
|
|
282
|
+
const next = createWorkspaceTab(current, "/search");
|
|
283
|
+
const tab =
|
|
284
|
+
next.tabs.find((entry) => entry.id === next.activeTabId) ??
|
|
285
|
+
next.tabs[0];
|
|
286
|
+
if (tab) {
|
|
287
|
+
window.history.pushState({}, "", tab.location);
|
|
288
|
+
}
|
|
289
|
+
return next;
|
|
290
|
+
});
|
|
201
291
|
}, []);
|
|
202
292
|
|
|
203
293
|
return (
|
|
@@ -205,8 +295,12 @@ function App() {
|
|
|
205
295
|
<AppContent
|
|
206
296
|
location={location}
|
|
207
297
|
navigate={navigate}
|
|
298
|
+
onActivateTab={activateTab}
|
|
299
|
+
onCloseTab={closeTab}
|
|
300
|
+
onNewTab={openNewTab}
|
|
208
301
|
setShortcutHelpOpen={setShortcutHelpOpen}
|
|
209
302
|
shortcutHelpOpen={shortcutHelpOpen}
|
|
303
|
+
workspace={workspace}
|
|
210
304
|
/>
|
|
211
305
|
</CaptureModalProvider>
|
|
212
306
|
);
|