Files
Artemis-Eapil/apps/showcase_ui/src/app/services/plugin.service.ts
T

43 lines
2.9 KiB
TypeScript

import { Injectable, inject } from '@angular/core';
import { tap } from 'rxjs';
import { HttpClient } from '@angular/common/http';
export interface PluginManifest {
id: string; name: string; version: string; description: string;
artemis_version: string; platforms: string[]; source: string;
config: Record<string, { label: string; description: string; secret: boolean; required: boolean; default: string }>;
workspace?: unknown; server?: unknown; skill?: string;
resources: string[];
targets: ('android' | 'computer' | 'mixed')[];
}
export interface PluginProfile {
name: string; label: string; is_default?: boolean; values: Record<string, string>;
secrets?: Record<string, string>; configured_secrets?: string[];
allowed_tools: string[] | null;
argument_constraints: Record<string, Record<string, string[]>>;
resources: string[]; authorized: boolean;
}
export interface InstalledPlugin { manifest: PluginManifest; enabled: boolean; source: string; profiles: PluginProfile[] }
export interface MarketPlugin { manifest: PluginManifest; verification: string; release_stage?: 'stable' | 'preview' }
export interface InstallProgress { id: string; status: 'queued' | 'running' | 'completed' | 'failed'; stage: string; progress: number }
@Injectable({ providedIn: 'root' })
export class PluginService {
private http = inject(HttpClient);
list() { return this.http.get<{ plugins: InstalledPlugin[]; blocked_resources?: Record<string, string> }>('/api/plugins'); }
confirmStopped(resource: string) { return this.http.post('/api/plugins/resources/confirm-stopped', { resource, confirmed_stopped: true }); }
catalog() { return this.http.get<{ plugins: MarketPlugin[] }>('/api/plugins/catalog'); }
install(payload: { plugin_id?: string; version?: string; local_path?: string }) {
return this.http.post<{ job_id: string }>('/api/plugins/install', payload);
}
progress(id: string) { return this.http.get<InstallProgress>(`/api/plugins/install/${encodeURIComponent(id)}`).pipe(tap(() => window.dispatchEvent(new Event('artemis-plugin-change')))); }
save(id: string, profile: PluginProfile) {
const { configured_secrets, ...payload } = profile;
return this.http.put<InstalledPlugin>(`/api/plugins/${encodeURIComponent(id)}/profiles`, payload);
}
enable(id: string, enabled: boolean) { return this.http.put<InstalledPlugin>(`/api/plugins/${encodeURIComponent(id)}/enabled`, { enabled }).pipe(tap(() => window.dispatchEvent(new Event('artemis-plugin-change')))); }
diagnose(id: string, profile: string) { return this.http.post<{ ok: boolean; message: string }>(`/api/plugins/${encodeURIComponent(id)}/diagnose`, { profile }); }
uninstall(id: string) { return this.http.delete(`/api/plugins/${encodeURIComponent(id)}`).pipe(tap(() => window.dispatchEvent(new Event('artemis-plugin-change')))); }
custom(manifest: unknown, skill_content: string) { return this.http.post('/api/plugins/custom', { manifest, skill_content }); }
}