nexus/ui/src/api/skillGroups.ts
Mikkel Georgsen 6b205b9f21 [nexus] feat(19-03): update API client to use agentId instead of agentSkillsDir
- Add AgentSkillEntry type with skillId, source, installedAt fields
- install() now sends agentId in body not agentSkillsDir
- uninstall() new function that sends agentId as query param
- rollback() now sends agentId in body not agentSkillsDir
- skillGroups.assignGroup/removeGroup no longer accept agentSkillsDir param
- listAgentSkills now returns AgentSkillEntry[] not string[]
- Fix AgentDetail.tsx callers and entry rendering for new AgentSkillEntry type
- Fix SkillDetail.tsx callers to use agentId param
2026-04-04 03:55:42 +00:00

91 lines
2.6 KiB
TypeScript

import { api, ApiError } from "./client";
import type { AgentSkillEntry } from "./skillRegistry";
export type SkillGroupRow = {
id: string;
name: string;
description: string | null;
isBuiltin: number;
createdAt: number;
updatedAt: number;
};
export type GroupMemberRow = {
groupId: string;
skillId: string;
addedAt: number;
};
export type AssignResult = {
installed: string[];
skipped: string[];
pendingPlugin: string[];
};
export type GroupExport = {
version: "1";
group: {
id: string;
name: string;
description: string | null;
members: string[];
parents: string[];
};
};
export const skillGroupsApi = {
listGroups: () => api.get<SkillGroupRow[]>("/skill-registry/groups"),
getGroup: (groupId: string) =>
api.get<SkillGroupRow>(`/skill-registry/groups/${groupId}`),
createGroup: (input: { name: string; description?: string }) =>
api.post<SkillGroupRow>("/skill-registry/groups", input),
updateGroup: (groupId: string, patch: { name?: string; description?: string }) =>
api.patch<SkillGroupRow>(`/skill-registry/groups/${groupId}`, patch),
deleteGroup: (groupId: string) =>
api.delete<void>(`/skill-registry/groups/${groupId}`),
listMembers: (groupId: string) =>
api.get<GroupMemberRow[]>(`/skill-registry/groups/${groupId}/members`),
addMember: (groupId: string, skillId: string) =>
api.post<{ ok: boolean }>(`/skill-registry/groups/${groupId}/members`, { skillId }),
removeMember: (groupId: string, skillId: string) =>
api.delete<void>(`/skill-registry/groups/${groupId}/members/${skillId}`),
exportGroup: (groupId: string) =>
api.get<GroupExport>(`/skill-registry/groups/${groupId}/export`),
importGroup: (data: GroupExport) =>
api.post<SkillGroupRow>("/skill-registry/groups/import", data),
listAgentGroups: (agentId: string) =>
api.get<SkillGroupRow[]>(`/skill-registry/agents/${agentId}/groups`),
assignGroup: (agentId: string, groupId: string) =>
api.post<AssignResult>(`/skill-registry/agents/${agentId}/groups`, {
groupId,
}),
removeGroup: async (agentId: string, groupId: string): Promise<void> => {
const res = await fetch(`/api/skill-registry/agents/${agentId}/groups/${groupId}`, {
method: "DELETE",
credentials: "include",
});
if (!res.ok && res.status !== 204) {
const errorBody = await res.json().catch(() => null);
throw new ApiError(
(errorBody as { error?: string } | null)?.error ?? `Request failed: ${res.status}`,
res.status,
errorBody,
);
}
},
listAgentSkills: (agentId: string) =>
api.get<AgentSkillEntry[]>(`/skill-registry/agents/${agentId}/skills`),
};