/** * acr list — 列出已部署的 workflow * * thin-shell-alignment P1(issue #11):原本直連 CF KV 讀 `workflow:` 前綴(CfKvClient), * 有兩個漂移:① 前綴對不上(部署寫 `{apiKey}:wf:` → 永遠列不到新部署)② 薄殼直碰底層儲存 * (self-hosted 用戶需 CF API token 才能 list)。改走 cypher `GET /webhooks/named`(KV 源,與 * MCP arcrun_list_workflows 同源),薄殼不再直連 KV、key 前綴 bug 自然消失。 */ import chalk from 'chalk'; import ora from 'ora'; import { loadConfig, getCypherExecutorUrl } from '../lib/config.js'; export async function cmdList(): Promise { const config = loadConfig(); const executorUrl = getCypherExecutorUrl(config); const headers: Record = { 'Content-Type': 'application/json' }; if (config.api_key) headers['X-Arcrun-API-Key'] = config.api_key; const spinner = ora('讀取 workflow 清單').start(); try { const res = await fetch(`${executorUrl}/webhooks/named`, { method: 'GET', headers }); if (!res.ok) { spinner.fail(chalk.red(`讀取失敗(HTTP ${res.status}):${(await res.text()).slice(0, 200)}`)); process.exit(1); } const data = await res.json() as { workflows: Array<{ name: string; description?: string; created_at?: string }>; }; spinner.stop(); const workflows = data.workflows ?? []; if (workflows.length === 0) { console.log(chalk.yellow('\n 沒有已部署的 workflow。執行 acr push 部署第一個。\n')); return; } console.log(chalk.bold(`\n 已部署 ${workflows.length} 個 workflow\n`)); for (const wf of workflows) { const date = wf.created_at ? new Date(wf.created_at).toLocaleString('zh-TW') : '未知'; const desc = wf.description ? chalk.gray(` — ${wf.description}`) : ''; console.log(` • ${chalk.cyan(wf.name.padEnd(25))} ${date}${desc}`); } console.log(''); } catch (e) { spinner.fail(chalk.red(`讀取失敗:${e instanceof Error ? e.message : e}`)); process.exit(1); } }