fb2d0b0c2d
讓任何 CC 用自己的 CF 帳號一鍵 self-host arcrun(戰法轉 self-hosted 開源)。
Task 1 — acr init --self-hosted installer(用戶只給 CF Account ID + token,其餘自動):
- cli/src/lib/cf-api.ts: CfAccountClient(驗 token / 建 KV 冪等 / 建 R2 / 查 workers.dev subdomain)
- cli/src/lib/deploy.ts: 從 GitHub codeload tarball 拉部署物 → 注入用戶 KV id → wrangler deploy
(tier1 component-builds 先、tier2 cypher-executor/registry 後;部分失敗誠實回報不假綠)
- cli/src/lib/api-recipe-seeds.ts: 10 個現役 API recipe 種子(KBDB 採 Supabase 模式)
- cli/src/commands/init.ts: initSelfHosted() 改寫成 installer 流程
- cli/src/commands/update.ts: acr update(拉新 ref 重部署)
- cypher-executor/scripts/seed-api-recipes.ts: prod 補灌腳本
Task 2 — recipe 入庫把關(封鎖自製零件後,CC 唯一能擴充的是 recipe):
- cli/src/commands/recipe.ts: 新增 probeRecipeEndpoint 打通檢查(提醒級不硬擋,
含模板誠實說明待 run 才知,401/403 標多半缺 credential 非 bug)
- 資料外流提醒沿用既有 obtainExposureConsent(非 TTY 拒絕)
部署物產製:commit 預編譯 wasm 進 repo(推翻 rule 05「wasm 不 commit」):
- .gitignore: 放行 .component-builds/**/component.wasm(registry 中間產物仍排除)
- 只 commit 19 個正當零件 wasm;claude_api / km_writer / kbdb_upsert_block 排除
(非薄殼、是把工作流硬塞進零件,違反 DECISIONS §1,待降級)
- rule 05 同步記錄此慣例變更 + 膨脹 trade-off
SDD: sdk-and-website/self-hosted-init.md(installer 定案)、
component-gatekeeping/recipe-push-gatekeeping.md(recipe 把關)
README 重寫成單一 self-hosted 路徑。CLI typecheck exit 0。
未完(待 richblack):push 此 commit 到 GitHub 後 codeload 才拿得到 wasm;
用第二 CF 帳號端對端驗收 acr init --self-hosted。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7.9 KiB
7.9 KiB
Implementation Plan: arcrun SDK Libraries + Website
Overview
按 Design 的四個 Phase 實作。原則:修改不重建,SDK 是 HTTP API thin wrapper,加密只在 client 做 encrypt(不做 decrypt)。
前置依賴:必須先完成 credential-primitives-wasm/tasks.md 的 Phase 0-3(核心合併 + WASM primitives),確認核心穩定後才開始建三個介面。
Phase 0(前置):核心合併 + WASM 改寫
詳見
.agents/specs/arcrun/credential-primitives-wasm/tasks.md摘要:
- 合併 u6u-core → arcrun(搬 builtins、刪重複 credentials)
- credential-injector TS → auth_static_key / auth_service_account WASM
- 刪除 component-loader 內建 API recipes TS
- 驗證 20 個 auth recipe 正常運作
Phase 1:Python SDK
-
1. 建立
arcrun/python-sdk/目錄- 1.1
pyproject.toml:name=arcrun, deps=[httpx>=0.27, cryptography>=42], build-system=hatchling - 1.2
arcrun/__init__.py:from .client import Arcrun - 1.3
arcrun/crypto.py:AES-GCM encrypt only(使用cryptography套件) - 1.4
arcrun/creds.py:CredentialsClient — push(加密 + POST /credentials)、list(GET /credentials)、delete - 1.5
arcrun/auth.py:AuthClient — setup(fetch recipe → match secrets → encrypt → push)、bind(fetch recipe → resolve headers from cache → return AuthenticatedClient)、get_token、list_services - 1.6
arcrun/workflows.py:WorkflowClient — run(POST /webhooks/named/{name}/trigger)、push(POST /webhooks/named)、list(GET /webhooks/named)、delete - 1.7
arcrun/client.py:Arcrun class — 讀 api_key / encryption_key 從 param > env > config.yaml
- 1.1
-
2. 修正上次已知的 bug
- 2.1
_fetch_recipe()回應是{ success: true, recipe: {...} },需讀.recipe欄位 - 2.2
inject下的 key 是header(singular),不是headers - 2.3
required_secrets[].key是 prefixed(如openai_api_key),setup() 的 kwargs alias 要能對應 - 2.4
list_services()回應的 recipe 用service欄位(不是service_id)
- 2.1
-
3. 測試(對 cypher.arcrun.dev live API)
- 3.1
health()→{"ok": true} - 3.2
auth.list_services()→ 20 個服務 - 3.3
auth.setup("openai", api_key="sk-test-dummy")→ 成功 - 3.4
auth.bind("openai")→ AuthenticatedClient with Authorization header - 3.5
auth.get_token("openai")→ "sk-test-dummy" - 3.6
creds.push("test_token", "value123")→ 成功 - 3.7
creds.list()→ 含 "test_token"(注意 KV eventual consistency) - 3.8
workflows.list()→ [] - 3.9 cleanup:
creds.delete("test_token")
- 3.1
Phase 2:JS/TS SDK
-
4. 建立
arcrun/js-sdk/目錄- 4.1
package.json:name TBD(arcrun vs @arcrun/sdk),deps=devDeps only(tsup, typescript, @types/node) - 4.2
tsconfig.json:ES2020, NodeNext - 4.3
src/crypto.ts:Web Crypto API AES-GCM encrypt only - 4.4
src/creds.ts:CredentialsClient — push/list/delete via fetch - 4.5
src/auth.ts:AuthClient — setup/bind/getToken/listServices - 4.6
src/workflows.ts:WorkflowClient — run/push/list/delete - 4.7
src/index.ts:export class Arcrun + re-exports
- 4.1
-
5. 同步修正(與 Python SDK 同樣的 recipe 格式問題)
- 5.1
_fetchRecipe()讀body.recipe - 5.2 inject key:
headernotheaders - 5.3 setup() secret key alias matching
- 5.4 listServices() 用
service欄位
- 5.1
-
6. Build + 測試
- 6.1
tsupbuild → dist/index.js + dist/index.cjs + dist/index.d.ts - 6.2 Node.js 腳本對 live API 測試(同 Python 測試項目)
- 6.1
Phase 3:arcrun.dev 網站
-
7. 新增
/components頁面- 7.1 從
registry/components/*/component.contract.yaml讀取 21 個零件資料 - 7.2 卡片顯示:canonical_id, display_name, description, input required/optional, credentials_required, config_example
- 7.3 分類篩選:邏輯類 / API 類 / 控制流類
- 7.1 從
-
8. 更新首頁
- 8.1 Code demo tabs 改為 CLI / Python / JS 三個
- 8.2 CLI tab 展示
acr init → acr push → acr run - 8.3 Python tab 展示
pip install arcrun → Arcrun() → auth.setup → auth.bind - 8.4 JS tab 展示
npm install arcrun → new Arcrun() → auth.setup → auth.bind
-
9. OAuth 流程補完
- 9.1 確認 cypher-executor 的
/auth/google/start、/auth/github/start、/auth/callback路由正確 - 9.2 提供 richblack OAuth secrets 設定指令清單
- 9.3 richblack 設定 secrets 後驗證登入流程
- 9.1 確認 cypher-executor 的
-
10. 部署
- 10.1 Cloudflare Pages build + deploy
- 10.2 驗證所有頁面可存取
Phase 4:README + 發布
-
11. 更新
arcrun/README.md- 11.1 三種 Quick Start(CLI / Python / JS)
- 11.2 零件列表(21 個)
- 11.3 Auth Recipe 列表(20 個服務)
- 11.4 連結到 arcrun.dev 和 Swagger UI
-
12. 發布
- 12.1 Python SDK:
pip install build && python -m build && twine upload dist/* - 12.2 JS SDK:
npm run build && npm publish - 12.3 驗證:從零開始
pip install arcrun/npm install arcrun+ hello world
- 12.1 Python SDK:
Phase 5:acr init --self-hosted installer(2026-06-02 新增)
定稿 design:
self-hosted-init.md。CLI = installer:建 KV/R2 + 拉預編譯 wasm + wrangler deploy + seed。 用戶只做:申請 CF 帳號 → 裝 wrangler → 裝 acr → acr init --self-hosted。其餘自動。 背景:戰法轉 self-hosted 開源(docs/HANDOFF-self-host-harness.md)。
- 13.1 API recipe 種子 — 位置修正:種子資料放
cli/src/lib/api-recipe-seeds.ts(installer 用,避開 cypher §2.2 hook),seed 腳本cypher-executor/scripts/seed-api-recipes.ts(import 種子,給 prod 補灌)。10 個現役 recipe(kbdb_/gmail_send/google_sheets_/telegram_send/line_notify_send)。KBDB Supabase 模式進 seed(finally.click 是 KBDB 端 follow-up,已註於 api-recipe-seeds.ts) - 13.2
cli/src/lib/cf-api.ts新增CfAccountClient:verifyAccess / listKvNamespaces / ensureKvNamespace(冪等)/ ensureR2Bucket(冪等)/ getWorkersSubdomain - 13.3
cli/src/commands/init.tsinitSelfHosted()改寫:驗 token → 建 7 KV + R2 → 查 subdomain → downloadAndDeploy → 寫 config → seed(部署完成時)→ 印 secret 提示。誠實:部署未自動化時明說,不假綠 - 13.4
cli/src/lib/deploy.ts:REQUIRED_KV/R2/SECRET 常數 + wranglerAvailable() + downloadAndDeploy 已補實(codeload tarball 下載 + 解壓 + discoverWorkerDirs 分 tier + injectWranglerConfig 注入 KV id/subdomain + runWranglerDeploy;部分失敗誠實收集回報,不假綠) - 13.5
cli/src/commands/update.ts+ index.ts 註冊acr update(self-hosted 重部署,同走 downloadAndDeploy) - 13.6 部署物產製:改用 commit wasm 進 repo + codeload(取代 release artifact,richblack 2026-06-02,§6)
.gitignore否定規則放行.component-builds/**/component.wasm(registry 中間產物仍排除)→ 已驗 git check-ignore- rule 05 同步改(記錄推翻「wasm 不 commit」+ trade-off)
- commit 22 個
.component-builds/*/component.wasm進 repo
- 13.7 驗收:全新 CF 帳號跑 acr init --self-hosted 全自動;acr push workflow → trigger 2xx + trace(待 richblack 用第二帳號實測 + push 含 wasm 的 commit 到 GitHub 後 codeload 才拿得到)
- 13.8 typecheck:cli
tsc --noEmitexit 0
Notes
- JS SDK 套件名需 richblack 決定(
arcrun已被 CLI 佔用 → 可能用@arcrun/sdk) - OAuth secrets 設定需 richblack 手動操作(GCP Console + GitHub Settings)
bind()跨 session 限制是已知的,封測期間先接受- credential 加密用的
encryption_key目前由/register回傳,acr init自動存入 config