feat: community and custom plugin registries

This commit is contained in:
LukeGus committed 2026-10-11 13:29:05 -05:00
1 parent 1aa1bde5f7
commit 6a7afa94a0
31 files changed
+2903 -134

No files matched your search

+73 -1
View File
@@ -291,8 +291,14 @@ export interface RegistryPluginVersion {
size: number;
}
export type RegistryTier = "official" | "community" | "custom";
export interface RegistryPluginEntry {
id: string;
/** Which registry this entry comes from. */
registryId?: string;
registryName?: string;
tier?: RegistryTier;
name: string;
description: string;
author: string;
@@ -320,6 +326,16 @@ export interface RegistryPluginEntry {
installCountSource: string | null;
}
export interface RegistryListingSource {
id: string;
name: string;
tier: RegistryTier;
url: string;
lastCheckedAt: string | null;
error: string | null;
plugins: number;
}
export interface RegistryListing {
registry: {
id: string;
@@ -327,6 +343,7 @@ export interface RegistryListing {
lastCheckedAt: string | null;
error: string | null;
};
registries?: RegistryListingSource[];
managedByServer: boolean;
plugins: RegistryPluginEntry[];
}
@@ -375,7 +392,7 @@ export async function getPluginRegistry(
/** `capabilities` is exactly what the consent prompt showed. */
export async function installPlugin(
pluginId: string,
options: { version?: string; capabilities: string[] },
options: { version?: string; capabilities: string[]; registryId?: string },
): Promise<{ id: string; version: string; state: string }> {
try {
const response = await rbacApi.post(
@@ -407,6 +424,61 @@ export async function updatePlugin(
}
}
export interface CustomRegistryInfo {
id: string;
name: string;
url: string;
keyId: string;
enabled: boolean;
addedAt: string;
}
export interface RegistriesState {
managedByServer: boolean;
official: { id: string; url: string };
community: { id: string; url: string; enabled: boolean };
custom: CustomRegistryInfo[];
}
export interface RegistryPreview {
id: string;
name: string;
url: string;
keyId: string;
plugins: number;
}
export async function getRegistries(): Promise<RegistriesState> {
const response = await rbacApi.get("/plugins/registries");
return response.data;
}
export async function previewRegistry(url: string): Promise<RegistryPreview> {
const response = await rbacApi.post("/plugins/registries/preview", { url });
return response.data;
}
export async function addRegistry(
url: string,
keyId: string,
): Promise<CustomRegistryInfo> {
const response = await rbacApi.post("/plugins/registries", { url, keyId });
return response.data;
}
export async function setRegistryEnabled(
id: string,
enabled: boolean,
): Promise<void> {
await rbacApi.patch(`/plugins/registries/${encodeURIComponent(id)}`, {
enabled,
});
}
export async function removeRegistry(id: string): Promise<void> {
await rbacApi.delete(`/plugins/registries/${encodeURIComponent(id)}`);
}
export async function updateAllPlugins(): Promise<UpdateAllResult> {
try {
const response = await rbacApi.post("/plugins/update-all");