45 lines
1.7 KiB
TypeScript
45 lines
1.7 KiB
TypeScript
// api.ts から分割(挙動不変): ツールカタログ。
|
|
import { BASE } from './client';
|
|
|
|
// --- Tools ---
|
|
/**
|
|
* Runtime tool catalog entry. Mirrors `ToolCatalogEntry` exported by
|
|
* `src/bridge/tools-api.ts` (server side). See design doc step 4:
|
|
* docs/superpowers/specs/2026-05-21-settings-ui-and-config-restructure-design.md
|
|
*/
|
|
export interface ToolCatalogEntry {
|
|
name: string;
|
|
source: 'builtin' | 'meta' | 'mcp';
|
|
/**
|
|
* Coarse grouping for UI. For builtin/meta tools this is a module name
|
|
* (e.g. 'core', 'web'). For MCP tools the server uses `mcp:<serverId>`.
|
|
*/
|
|
category: string;
|
|
/** MCP server id (only set when source === 'mcp'). */
|
|
serverId?: string;
|
|
/** Whether the tool can be invoked right now. */
|
|
available: boolean;
|
|
/** Human-readable explanation when `available` is false. */
|
|
reason?: string;
|
|
/**
|
|
* - 'global' → meta tools auto-injected by the agent loop (always available)
|
|
* - 'piece' → builtin tool gated by the workspace tool policy (Settings → Tools)
|
|
* - 'user' → per-user resource (MCP / SSH)
|
|
*/
|
|
scope: 'global' | 'piece' | 'user';
|
|
}
|
|
|
|
export async function fetchTools(): Promise<ToolCatalogEntry[]> {
|
|
const res = await fetch(`${BASE}/tools`);
|
|
if (!res.ok) throw new Error('Failed to fetch tools');
|
|
const data = (await res.json()) as { tools?: unknown };
|
|
if (!Array.isArray(data.tools)) return [];
|
|
// Server may still occasionally serve the legacy flat-string shape (e.g.
|
|
// during a transient mismatch / proxy / cache). Filter to only well-formed
|
|
// catalog entries so the UI never crashes; legacy strings are dropped.
|
|
return data.tools.filter(
|
|
(t): t is ToolCatalogEntry =>
|
|
typeof t === 'object' && t !== null && typeof (t as { name?: unknown }).name === 'string',
|
|
);
|
|
}
|