Files
iven 1cf3f585d3 refactor(store): split gatewayStore into specialized domain stores
Major restructuring:
- Split monolithic gatewayStore into 5 focused stores:
  - connectionStore: WebSocket connection and gateway lifecycle
  - configStore: quickConfig, workspaceInfo, MCP services
  - agentStore: clones, usage stats, agent management
  - handStore: hands, approvals, triggers, hand runs
  - workflowStore: workflows, workflow runs, execution

- Update all components to use new stores with selector pattern
- Remove
2026-03-20 22:14:13 +08:00

145 lines
3.2 KiB
TypeScript

/**
* Viking Local Adapter - Tauri Sidecar Integration
*
* Provides local memory operations through the OpenViking CLI sidecar.
* This eliminates the need for a Python server dependency.
*/
import { invoke } from '@tauri-apps/api/core';
// === Types ===
export interface LocalVikingStatus {
available: boolean;
version?: string;
dataDir?: string;
error?: string;
}
export interface LocalVikingResource {
uri: string;
name: string;
type: string;
size?: number;
modifiedAt?: string;
}
export interface LocalVikingFindResult {
uri: string;
score: number;
content: string;
level: string;
overview?: string;
}
export interface LocalVikingGrepResult {
uri: string;
line: number;
content: string;
matchStart: number;
matchEnd: number;
}
export interface LocalVikingAddResult {
uri: string;
status: string;
}
// === Local Viking Client ===
export class VikingLocalClient {
private available: boolean | null = null;
async isAvailable(): Promise<boolean> {
if (this.available !== null) {
return this.available;
}
try {
const status = await this.status();
this.available = status.available;
return status.available;
} catch {
this.available = false;
return false;
}
}
async status(): Promise<LocalVikingStatus> {
return await invoke<LocalVikingStatus>('viking_status');
}
async addResource(
uri: string,
content: string
): Promise<LocalVikingAddResult> {
// For small content, use inline; for large content. use file-based
if (content.length < 10000) {
return await invoke<LocalVikingAddResult>('viking_add_inline', { uri, content });
} else {
return await invoke<LocalVikingAddResult>('viking_add', { uri, content });
}
}
async find(
query: string,
options?: {
scope?: string;
limit?: number;
}
): Promise<LocalVikingFindResult[]> {
return await invoke<LocalVikingFindResult[]>('viking_find', {
query,
scope: options?.scope,
limit: options?.limit,
});
}
async grep(
pattern: string,
options?: {
uri?: string;
caseSensitive?: boolean;
limit?: number;
}
): Promise<LocalVikingGrepResult[]> {
return await invoke<LocalVikingGrepResult[]>('viking_grep', {
pattern,
uri: options?.uri,
caseSensitive: options?.caseSensitive,
limit: options?.limit,
});
}
async ls(path: string): Promise<LocalVikingResource[]> {
return await invoke<LocalVikingResource[]>('viking_ls', { path });
}
async readContent(uri: string, level?: string): Promise<string> {
return await invoke<string>('viking_read', { uri, level });
}
async removeResource(uri: string): Promise<void> {
await invoke('viking_remove', { uri });
}
async tree(path: string, depth?: number): Promise<unknown> {
return await invoke('viking_tree', { path, depth });
}
}
// === Singleton ===
let _localClient: VikingLocalClient | null;
export function getVikingLocalClient(): VikingLocalClient {
if (!_localClient) {
_localClient = new VikingLocalClient();
}
return _localClient;
}
export function resetVikingLocalClient(): void {
_localClient = null;
}