43 lines
2.9 KiB
TypeScript
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 }); }
|
|
}
|