// api.ts から分割(挙動不変): Piece CRUD。 import { BASE, buildQuery } from './client'; // --- Pieces --- export interface DriftStatus { drifted: boolean; forkedFromCommit: string | null; latestCommit: string | null } export interface PieceSummary { name: string; description: string; triggers?: { keywords: string[] }; custom?: boolean; source?: 'builtin' | 'user-custom' | 'global-custom'; ownerId?: string; drift?: DriftStatus; requiredMcp?: string[] } export interface PieceDef { name: string; description: string; max_movements: number; initial_movement: string; triggers?: { keywords: string[] }; movements: any[]; requiredMcp?: string[] } /** Full response from GET /api/pieces/:name — includes the server-resolved source. */ export interface PieceFetchResult { piece: PieceDef; source: 'builtin' | 'user-custom' | 'global-custom'; ownerId?: string } export async function fetchPieces(spaceId?: string): Promise { const res = await fetch(`${BASE}/pieces${buildQuery({ spaceId })}`); const data = await res.json(); if (!res.ok) throw new Error(data?.error ?? 'Failed to fetch pieces'); return data.pieces; } export async function fetchPiece(name: string, source?: 'builtin' | 'user-custom' | 'global-custom', spaceId?: string): Promise { const url = `${BASE}/pieces/${name}${buildQuery({ source, spaceId })}`; const res = await fetch(url); const data = await res.json(); if (!res.ok) throw new Error(data?.error ?? 'Failed to fetch piece'); return { piece: data.piece, source: data.source, ownerId: data.ownerId }; } export async function updatePiece(name: string, piece: PieceDef, source?: 'builtin' | 'user-custom' | 'global-custom', spaceId?: string): Promise { const url = `${BASE}/pieces/${name}${buildQuery({ source, spaceId })}`; const res = await fetch(url, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(spaceId ? { ...piece, spaceId } : piece), }); if (!res.ok) { const d = await res.json(); throw new Error(d?.error ?? 'Failed to update piece'); } } export interface PieceCreateResult { source: 'builtin' | 'user-custom' | 'global-custom' } export async function createPiece(piece: PieceDef, spaceId?: string): Promise { const res = await fetch(`${BASE}/pieces${buildQuery({ spaceId })}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(spaceId ? { ...piece, spaceId } : piece), }); if (!res.ok) { const d = await res.json(); throw new Error(d?.error ?? 'Failed to create piece'); } const d = await res.json(); return { source: d.source ?? 'user-custom' }; } export async function deletePiece(name: string, source?: 'builtin' | 'user-custom' | 'global-custom', spaceId?: string): Promise { const url = `${BASE}/pieces/${name}${buildQuery({ source, spaceId })}`; const res = await fetch(url, { method: 'DELETE' }); if (!res.ok) { const d = await res.json(); throw new Error(d?.error ?? 'Failed to delete piece'); } }