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:
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* seed-api-recipes.ts
|
||||
*
|
||||
* 將現役 API recipe 種子上傳至目標 cypher-executor(prod 或 self-host)。
|
||||
* 種子資料的單一來源在 CLI 端(cli/src/lib/api-recipe-seeds.ts),此腳本 import 它,
|
||||
* 避免兩份種子定義漂移。
|
||||
*
|
||||
* 執行:
|
||||
* npx tsx scripts/seed-api-recipes.ts
|
||||
*
|
||||
* 環境變數:
|
||||
* ARCRUN_API_URL - 目標 cypher-executor,預設 https://cypher.arcrun.dev
|
||||
* ARCRUN_API_KEY - X-Arcrun-API-Key(POST /recipes 需要)
|
||||
*
|
||||
* 注意:API recipe 帶 endpoint(資料去向)→ POST /recipes 會要 exposure_consent
|
||||
* (data-exfil-warning)。seed 是平台預建、非用戶 push,腳本帶種子層級的 consent。
|
||||
*
|
||||
* 對應 SDD:.agents/specs/arcrun/sdk-and-website/self-hosted-init.md §5
|
||||
*/
|
||||
|
||||
import { API_RECIPE_SEEDS } from '../../cli/src/lib/api-recipe-seeds.js';
|
||||
|
||||
const BASE_URL = process.env.ARCRUN_API_URL ?? 'https://cypher.arcrun.dev';
|
||||
const API_KEY = process.env.ARCRUN_API_KEY ?? '';
|
||||
|
||||
async function main() {
|
||||
console.log(`\n Seeding ${API_RECIPE_SEEDS.length} API recipes → ${BASE_URL}\n`);
|
||||
|
||||
let ok = 0;
|
||||
let fail = 0;
|
||||
|
||||
for (const recipe of API_RECIPE_SEEDS) {
|
||||
process.stdout.write(` ${recipe.canonical_id.padEnd(24)} `);
|
||||
|
||||
try {
|
||||
const res = await fetch(`${BASE_URL}/recipes`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...(API_KEY ? { 'X-Arcrun-API-Key': API_KEY } : {}),
|
||||
},
|
||||
body: JSON.stringify({
|
||||
canonical_id: recipe.canonical_id,
|
||||
display_name: recipe.display_name,
|
||||
description: recipe.description,
|
||||
endpoint: recipe.endpoint,
|
||||
method: recipe.method,
|
||||
auth_service: recipe.auth_service,
|
||||
// 種子層級的暴露同意:平台預建 recipe,非用戶互動 push。
|
||||
// 格式須符合 cypher-executor ExposureConsent(confirmed_by_human + understood + confirmed_at)。
|
||||
// 誠實標明來源是 seed,軌跡可審(mindset §7:機制價值是歸責+可審,非防偽)。
|
||||
exposure_consent: {
|
||||
confirmed_by_human: true,
|
||||
understood: `platform seed recipe (api-recipe-seeds.ts): ${recipe.canonical_id} → ${recipe.endpoint}`,
|
||||
confirmed_at: new Date().toISOString(),
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
console.log('✓');
|
||||
ok++;
|
||||
} else {
|
||||
const err = await res.text().catch(() => '');
|
||||
console.log(`✗ HTTP ${res.status}: ${err.slice(0, 120)}`);
|
||||
fail++;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`✗ ${e instanceof Error ? e.message : String(e)}`);
|
||||
fail++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n 完成:${ok} 成功,${fail} 失敗\n`);
|
||||
if (fail > 0) process.exit(1);
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* seed-auth-recipes.ts
|
||||
*
|
||||
* 將 auth-recipe-seeds.ts 中定義的 20 個 auth recipe 上傳至 cypher.arcrun.dev。
|
||||
*
|
||||
* 執行:
|
||||
* npx tsx scripts/seed-auth-recipes.ts
|
||||
*
|
||||
* 環境變數:
|
||||
* ARCRUN_API_URL - 預設 https://cypher.arcrun.dev
|
||||
*/
|
||||
|
||||
import { AUTH_RECIPE_SEEDS } from '../src/lib/auth-recipe-seeds.js';
|
||||
|
||||
const BASE_URL = process.env.ARCRUN_API_URL ?? 'https://cypher.arcrun.dev';
|
||||
|
||||
async function main() {
|
||||
console.log(`\n Seeding ${AUTH_RECIPE_SEEDS.length} auth recipes → ${BASE_URL}\n`);
|
||||
|
||||
let ok = 0;
|
||||
let fail = 0;
|
||||
|
||||
for (const recipe of AUTH_RECIPE_SEEDS) {
|
||||
process.stdout.write(` ${recipe.service.padEnd(24)} `);
|
||||
|
||||
try {
|
||||
const res = await fetch(`${BASE_URL}/auth-recipes`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(recipe),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
console.log(`✓`);
|
||||
ok++;
|
||||
} else {
|
||||
const err = await res.text().catch(() => '');
|
||||
console.log(`✗ HTTP ${res.status}: ${err.slice(0, 100)}`);
|
||||
fail++;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`✗ ${e instanceof Error ? e.message : String(e)}`);
|
||||
fail++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n 完成:${ok} 成功,${fail} 失敗\n`);
|
||||
if (fail > 0) process.exit(1);
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user