feat(skills-ui): manage plugin skill mirrors
This commit is contained in:
@ -19,6 +19,7 @@ import type {
|
||||
FileAttachment,
|
||||
NotificationDetail,
|
||||
NotificationRun,
|
||||
BeaverPlugin,
|
||||
ProviderConfigPayload,
|
||||
Session,
|
||||
SessionDetail,
|
||||
@ -833,6 +834,55 @@ export async function listSkills(): Promise<Skill[]> {
|
||||
return fetchJSON('/api/skills');
|
||||
}
|
||||
|
||||
export async function listPlugins(): Promise<BeaverPlugin[]> {
|
||||
return fetchJSON('/api/plugins');
|
||||
}
|
||||
|
||||
export async function syncPlugins(): Promise<BeaverPlugin[]> {
|
||||
return fetchJSON('/api/plugins/sync', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
}
|
||||
|
||||
export async function enablePlugin(pluginId: string): Promise<BeaverPlugin> {
|
||||
return fetchJSON(`/api/plugins/${encodeURIComponent(pluginId)}/enable`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
}
|
||||
|
||||
export async function pausePlugin(pluginId: string): Promise<BeaverPlugin> {
|
||||
return fetchJSON(`/api/plugins/${encodeURIComponent(pluginId)}/pause`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
}
|
||||
|
||||
export async function resumePlugin(pluginId: string): Promise<BeaverPlugin> {
|
||||
return fetchJSON(`/api/plugins/${encodeURIComponent(pluginId)}/resume`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
}
|
||||
|
||||
export async function disablePlugin(
|
||||
pluginId: string,
|
||||
payload: { disable_linked_skills: boolean }
|
||||
): Promise<BeaverPlugin> {
|
||||
return fetchJSON(`/api/plugins/${encodeURIComponent(pluginId)}/disable`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
export async function adoptPluginSkill(pluginId: string, skillName: string): Promise<BeaverPlugin> {
|
||||
return fetchJSON(`/api/plugins/${encodeURIComponent(pluginId)}/skills/${encodeURIComponent(skillName)}/adopt`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
}
|
||||
|
||||
export async function getSkillDetail(skillName: string): Promise<SkillDetailResponse> {
|
||||
return fetchJSON(`/api/skills/${encodeURIComponent(skillName)}/detail`);
|
||||
}
|
||||
|
||||
29
app-instance/frontend/lib/plugin-api.test.ts
Normal file
29
app-instance/frontend/lib/plugin-api.test.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
const root = resolve(__dirname, '..');
|
||||
|
||||
describe('plugin API client wiring', () => {
|
||||
it('declares plugin API types', () => {
|
||||
const types = readFileSync(resolve(root, 'types/index.ts'), 'utf8');
|
||||
|
||||
expect(types).toContain('export interface PluginSkillBinding');
|
||||
expect(types).toContain('export interface BeaverPlugin');
|
||||
});
|
||||
|
||||
it('routes plugin API helpers to backend endpoints', () => {
|
||||
const api = readFileSync(resolve(root, 'lib/api.ts'), 'utf8');
|
||||
|
||||
expect(api).toContain('listPlugins');
|
||||
expect(api).toContain('/api/plugins');
|
||||
expect(api).toContain('/api/plugins/sync');
|
||||
expect(api).toContain('/api/plugins/${encodeURIComponent(pluginId)}/enable');
|
||||
expect(api).toContain('/api/plugins/${encodeURIComponent(pluginId)}/pause');
|
||||
expect(api).toContain('/api/plugins/${encodeURIComponent(pluginId)}/resume');
|
||||
expect(api).toContain('/api/plugins/${encodeURIComponent(pluginId)}/disable');
|
||||
expect(api).toContain('/api/plugins/${encodeURIComponent(pluginId)}/skills/${encodeURIComponent(skillName)}/adopt');
|
||||
expect(api).toContain('disable_linked_skills');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user