import fs from 'fs'; import path from 'path'; import { OUTPUT_DIR, loadJSON } from './shared'; import type { ToolDefinition } from './types'; export const listOutputs: ToolDefinition = { name: 'list_outputs', description: '列出 output 目录下所有项目及其 manifest 状态,方便查看历史生成记录和进行中的任务。', input_schema: { type: 'object', properties: {}, required: [], }, execute: async () => { if (!fs.existsSync(OUTPUT_DIR)) return 'output 目录不存在'; const entries = fs.readdirSync(OUTPUT_DIR, { withFileTypes: true }) .filter((d) => d.isDirectory()) .map((d) => { const manifestPath = path.join(OUTPUT_DIR, d.name, 'manifest.json'); if (!fs.existsSync(manifestPath)) return { name: d.name, status: 'no manifest' }; try { const manifest = loadJSON(manifestPath) as { account?: string; imageModel?: string; videoModel?: string; mode?: string; pipeline?: { phases?: Record }; items?: Array<{ status?: string }>; }; const phases = manifest.pipeline?.phases || {}; const itemCount = manifest.items?.length || 0; const doneCount = manifest.items?.filter((i) => i.status === 'done').length || 0; return { name: d.name, account: manifest.account || '?', mode: manifest.mode || '?', items: `${doneCount}/${itemCount} done`, phases: Object.entries(phases).map(([k, v]) => `${k}:${v}`).join(', ') || 'pending', }; } catch { return { name: d.name, status: 'manifest parse error' }; } }); return JSON.stringify(entries, null, 2); }, };