arcrun — AI workflow execution engine (clean history)

Self-hosted 開源:WASM 零件 + recipe + cypher-executor,跑在你自己的 Cloudflare。

此為重建的乾淨歷史起點(移除曾誤 commit 的 GCP SA 金鑰,舊歷史保留在
richblack/arcrun 與本地 backup 分支)。含:
- acr init --self-hosted installer(建 KV/R2 + codeload 拉預編譯 wasm + wrangler deploy + seed recipe)
- recipe push 把關(資料外流提醒 + 打通檢查)
- 19 個正當零件預編譯 wasm(claude_api/km_writer/kbdb_upsert_block 排除:違反 DECISIONS §1)
- CLI / cypher-executor / registry / 完整 SDD

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
uncle6me-web
2026-06-03 15:52:38 +08:00
commit 922a57fe34
485 changed files with 89356 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
/**
* acr list — 列出 USER_KV 中所有已上傳的 workflow
*/
import chalk from 'chalk';
import ora from 'ora';
import { loadConfig } from '../lib/config.js';
import { CfKvClient } from '../lib/cf-api.js';
export async function cmdList(): Promise<void> {
const config = loadConfig();
if (!config.cloudflare_account_id || !config.cf_api_token) {
console.error(chalk.red('缺少 Cloudflare 設定,請執行 acr init'));
process.exit(1);
}
const namespaceId = config.mode === 'standard'
? config.user_kv_namespace_id!
: config.webhooks_kv_namespace_id!;
if (!namespaceId) {
console.error(chalk.red('缺少 KV Namespace ID,請執行 acr init'));
process.exit(1);
}
const kv = new CfKvClient({
accountId: config.cloudflare_account_id,
namespaceId,
apiToken: config.cf_api_token,
});
const spinner = ora('讀取 workflow 清單').start();
try {
const keys = await kv.list('workflow:');
spinner.stop();
if (keys.length === 0) {
console.log(chalk.yellow('\n 沒有已部署的 workflow。執行 acr push <workflow.yaml> 部署第一個。\n'));
return;
}
console.log(chalk.bold(`\n 已部署 ${keys.length} 個 workflow\n`));
for (const key of keys) {
const name = key.name.replace('workflow:', '');
// 嘗試讀取 workflow 定義取得 created_at
try {
const raw = await kv.get(key.name);
if (raw) {
const def = JSON.parse(raw) as { name: string; description?: string; created_at?: string };
const date = def.created_at ? new Date(def.created_at).toLocaleString('zh-TW') : '未知';
const desc = def.description ? chalk.gray(`${def.description}`) : '';
console.log(`${chalk.cyan(name.padEnd(25))} ${date}${desc}`);
} else {
console.log(`${chalk.cyan(name)}`);
}
} catch {
console.log(`${chalk.cyan(name)}`);
}
}
console.log('');
} catch (e) {
spinner.fail(chalk.red(`KV 讀取失敗:${e instanceof Error ? e.message : e}`));
process.exit(1);
}
}