@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.
- package/README.md +10 -2
- package/package.json +7 -7
- 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
|
@@ -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
|
+
}
|