/** * acr update — 拉新 GitHub release,重新部署零件/引擎到用戶自己的 Cloudflare。 * * 與 acr init --self-hosted 走同一條「下載 release → 注入 KV id → wrangler deploy」的路, * 差別只在:init 是首次(建 KV/R2 + 寫 config),update 是沿用既有 config 重部署變動的 Worker。 * * 對應 SDD:.agents/specs/arcrun/sdk-and-website/self-hosted-init.md §3「acr update」 * * 誠實限制(mindset §7 / SDD §6):部署依賴 GitHub release(含預編譯 wasm), * release 產製管道補上前,誠實回報未實作,不假裝更新成功。 */ import chalk from 'chalk'; import { loadConfig } from '../lib/config.js'; import { wranglerAvailable, downloadAndDeploy, type DeployContext, } from '../lib/deploy.js'; export async function cmdUpdate(): Promise { const config = loadConfig(); if (config.mode !== 'self-hosted') { console.log(chalk.yellow('\n acr update 只用於 self-hosted 模式(部署在你自己的 Cloudflare)。')); console.log(chalk.gray(' 目前模式:' + config.mode + '。如要 self-host,先跑 acr init --self-hosted。\n')); process.exit(1); } if (!config.cloudflare_account_id || !config.cf_api_token) { console.log(chalk.yellow('\n config 缺 cloudflare_account_id / cf_api_token,無法部署。')); console.log(chalk.gray(' 請重新跑 acr init --self-hosted。\n')); process.exit(1); } if (!wranglerAvailable()) { console.log(chalk.yellow('\n ✗ 找不到 wrangler(Cloudflare CLI)。請先 npm i -g wrangler。\n')); process.exit(1); } console.log(chalk.bold('\n acr update — 拉新 release 並重新部署\n')); const ctx: DeployContext = { accountId: config.cloudflare_account_id, apiToken: config.cf_api_token, workerSubdomain: extractSubdomain(config.cypher_executor_url), kvNamespaceIds: { WEBHOOKS: config.webhooks_kv_namespace_id ?? '', CREDENTIALS_KV: config.credentials_kv_namespace_id ?? '', }, }; const result = await downloadAndDeploy(ctx); if (result.implemented) { console.log(chalk.green('\n ✓ 更新完成\n')); } else { console.log(chalk.yellow(' ⚠ 更新尚未自動化:')); console.log(chalk.gray(' ' + result.message.split('\n').join('\n ')) + '\n'); } } /** 從 cypher_executor_url(https://arcrun-cypher-executor..workers.dev)抽 subdomain。*/ function extractSubdomain(url?: string): string { if (!url) return ''; const m = url.match(/arcrun-cypher-executor\.([^.]+)\.workers\.dev/); return m?.[1] ?? ''; }