@gmickel/gno 0.28.1 → 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.
Files changed (52) hide show
  1. package/README.md +10 -2
  2. package/package.json +7 -7
  3. package/src/app/constants.ts +4 -2
  4. package/src/cli/commands/mcp/install.ts +4 -4
  5. package/src/cli/commands/mcp/status.ts +7 -7
  6. package/src/cli/commands/skill/install.ts +5 -5
  7. package/src/cli/program.ts +2 -2
  8. package/src/collection/add.ts +10 -0
  9. package/src/collection/types.ts +1 -0
  10. package/src/config/types.ts +12 -2
  11. package/src/core/depth-policy.ts +1 -1
  12. package/src/core/file-ops.ts +38 -0
  13. package/src/llm/registry.ts +20 -4
  14. package/src/serve/AGENTS.md +16 -16
  15. package/src/serve/CLAUDE.md +16 -16
  16. package/src/serve/config-sync.ts +32 -1
  17. package/src/serve/connectors.ts +243 -0
  18. package/src/serve/context.ts +9 -0
  19. package/src/serve/doc-events.ts +31 -1
  20. package/src/serve/embed-scheduler.ts +12 -0
  21. package/src/serve/import-preview.ts +173 -0
  22. package/src/serve/public/app.tsx +101 -7
  23. package/src/serve/public/components/AIModelSelector.tsx +383 -145
  24. package/src/serve/public/components/AddCollectionDialog.tsx +123 -7
  25. package/src/serve/public/components/BootstrapStatus.tsx +133 -0
  26. package/src/serve/public/components/CaptureModal.tsx +5 -2
  27. package/src/serve/public/components/CollectionsEmptyState.tsx +63 -0
  28. package/src/serve/public/components/FirstRunWizard.tsx +622 -0
  29. package/src/serve/public/components/HealthCenter.tsx +128 -0
  30. package/src/serve/public/components/IndexingProgress.tsx +21 -2
  31. package/src/serve/public/components/QuickSwitcher.tsx +62 -36
  32. package/src/serve/public/components/TagInput.tsx +5 -1
  33. package/src/serve/public/components/WikiLinkAutocomplete.tsx +15 -6
  34. package/src/serve/public/components/WorkspaceTabs.tsx +60 -0
  35. package/src/serve/public/hooks/use-doc-events.ts +48 -4
  36. package/src/serve/public/lib/local-history.ts +40 -7
  37. package/src/serve/public/lib/navigation-state.ts +156 -0
  38. package/src/serve/public/lib/workspace-tabs.ts +235 -0
  39. package/src/serve/public/pages/Ask.tsx +11 -1
  40. package/src/serve/public/pages/Browse.tsx +73 -0
  41. package/src/serve/public/pages/Collections.tsx +29 -13
  42. package/src/serve/public/pages/Connectors.tsx +178 -0
  43. package/src/serve/public/pages/Dashboard.tsx +493 -67
  44. package/src/serve/public/pages/DocView.tsx +192 -34
  45. package/src/serve/public/pages/DocumentEditor.tsx +127 -5
  46. package/src/serve/public/pages/Search.tsx +12 -1
  47. package/src/serve/routes/api.ts +532 -62
  48. package/src/serve/server.ts +79 -2
  49. package/src/serve/status-model.ts +149 -0
  50. package/src/serve/status.ts +706 -0
  51. package/src/serve/watch-service.ts +73 -8
  52. package/src/types/electrobun-shell.d.ts +43 -0
@@ -0,0 +1,178 @@
1
+ import {
2
+ BotIcon,
3
+ CheckCircle2Icon,
4
+ CpuIcon,
5
+ Loader2Icon,
6
+ PlugZapIcon,
7
+ } from "lucide-react";
8
+ import { useCallback, useEffect, useState } from "react";
9
+
10
+ import { Button } from "../components/ui/button";
11
+ import {
12
+ Card,
13
+ CardContent,
14
+ CardDescription,
15
+ CardHeader,
16
+ CardTitle,
17
+ } from "../components/ui/card";
18
+ import { apiFetch } from "../hooks/use-api";
19
+
20
+ interface PageProps {
21
+ navigate: (to: string | number) => void;
22
+ }
23
+
24
+ interface ConnectorStatus {
25
+ id: string;
26
+ appName: string;
27
+ installKind: "skill" | "mcp";
28
+ target: string;
29
+ scope: "user" | "project";
30
+ installed: boolean;
31
+ path: string;
32
+ summary: string;
33
+ nextAction: string;
34
+ mode: {
35
+ label: string;
36
+ detail: string;
37
+ };
38
+ error?: string;
39
+ }
40
+
41
+ interface ConnectorsResponse {
42
+ connectors: ConnectorStatus[];
43
+ }
44
+
45
+ export default function Connectors({ navigate }: PageProps) {
46
+ const [connectors, setConnectors] = useState<ConnectorStatus[]>([]);
47
+ const [error, setError] = useState<string | null>(null);
48
+ const [installingId, setInstallingId] = useState<string | null>(null);
49
+
50
+ const loadConnectors = useCallback(async () => {
51
+ const { data, error: err } =
52
+ await apiFetch<ConnectorsResponse>("/api/connectors");
53
+ if (err) {
54
+ setError(err);
55
+ return;
56
+ }
57
+
58
+ setConnectors(data?.connectors ?? []);
59
+ setError(null);
60
+ }, []);
61
+
62
+ useEffect(() => {
63
+ void loadConnectors();
64
+ }, [loadConnectors]);
65
+
66
+ const handleInstall = async (connectorId: string) => {
67
+ const connector = connectors.find((entry) => entry.id === connectorId);
68
+ setInstallingId(connectorId);
69
+ const { error: err } = await apiFetch("/api/connectors/install", {
70
+ method: "POST",
71
+ body: JSON.stringify({
72
+ connectorId,
73
+ reinstall: connector?.installed ?? false,
74
+ }),
75
+ });
76
+ setInstallingId(null);
77
+
78
+ if (err) {
79
+ setError(err);
80
+ return;
81
+ }
82
+
83
+ await loadConnectors();
84
+ };
85
+
86
+ return (
87
+ <div className="min-h-screen">
88
+ <main className="mx-auto max-w-6xl p-8">
89
+ <div className="mb-10 flex flex-wrap items-start justify-between gap-4">
90
+ <div className="max-w-3xl space-y-3">
91
+ <div className="flex items-center gap-2 text-primary">
92
+ <PlugZapIcon className="size-4" />
93
+ <span className="font-medium text-sm tracking-wide uppercase">
94
+ Agent Connectors
95
+ </span>
96
+ </div>
97
+ <h1 className="font-semibold text-3xl tracking-tight">
98
+ Install GNO into your coding agents without editing config files
99
+ </h1>
100
+ <p className="text-muted-foreground">
101
+ These actions reuse the existing CLI installers. Read/search
102
+ access is the default path. Write-capable MCP stays an advanced
103
+ opt-in instead of something the app quietly enables for you.
104
+ </p>
105
+ </div>
106
+ <Button onClick={() => navigate("/")} variant="outline">
107
+ Back to Dashboard
108
+ </Button>
109
+ </div>
110
+
111
+ {error && (
112
+ <Card className="mb-6 border-destructive bg-destructive/10">
113
+ <CardContent className="py-4 text-destructive">{error}</CardContent>
114
+ </Card>
115
+ )}
116
+
117
+ <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
118
+ {connectors.map((connector) => (
119
+ <Card className="border-border/60 bg-card/70" key={connector.id}>
120
+ <CardHeader className="space-y-3 pb-3">
121
+ <div className="flex items-center justify-between gap-3">
122
+ <div className="flex items-center gap-2">
123
+ <BotIcon className="size-4 text-primary" />
124
+ <CardTitle className="text-base">
125
+ {connector.appName}
126
+ </CardTitle>
127
+ </div>
128
+ {connector.installed ? (
129
+ <CheckCircle2Icon className="size-4 text-green-500" />
130
+ ) : (
131
+ <CpuIcon className="size-4 text-muted-foreground" />
132
+ )}
133
+ </div>
134
+ <CardDescription>{connector.summary}</CardDescription>
135
+ </CardHeader>
136
+ <CardContent className="space-y-4 text-sm">
137
+ <div className="rounded-lg border border-border/50 bg-background/70 p-3">
138
+ <div className="mb-1 font-medium">{connector.mode.label}</div>
139
+ <p className="text-muted-foreground">
140
+ {connector.mode.detail}
141
+ </p>
142
+ </div>
143
+ <div className="space-y-1">
144
+ <div>
145
+ <span className="font-medium">Install type:</span>{" "}
146
+ {connector.installKind.toUpperCase()}
147
+ </div>
148
+ <div>
149
+ <span className="font-medium">Scope:</span>{" "}
150
+ {connector.scope}
151
+ </div>
152
+ <div className="font-mono text-muted-foreground text-xs">
153
+ {connector.path}
154
+ </div>
155
+ </div>
156
+ {connector.error && (
157
+ <p className="text-destructive text-sm">{connector.error}</p>
158
+ )}
159
+ <p className="text-muted-foreground">{connector.nextAction}</p>
160
+ <Button
161
+ className="w-full"
162
+ onClick={() => void handleInstall(connector.id)}
163
+ size="sm"
164
+ variant={connector.installed ? "outline" : "default"}
165
+ >
166
+ {installingId === connector.id ? (
167
+ <Loader2Icon className="mr-2 size-4 animate-spin" />
168
+ ) : null}
169
+ {connector.installed ? "Reinstall" : "Install"}
170
+ </Button>
171
+ </CardContent>
172
+ </Card>
173
+ ))}
174
+ </div>
175
+ </main>
176
+ </div>
177
+ );
178
+ }