頂層 D22 決策(leo 2026-07-03 拍板):推什麼由開發環境歸屬決定, Gitea private=除機敏值/build 產物/.github 外全 push。 解 T1.5 卡點:雲端工人 clone 拿得到 credential-store-migration.md,可就地改寫 SDD。 機敏掃描兩輪通過(新增 189 檔約 2.1MB,node_modules/dist/wasm 照舊排除)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
13 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
Phase 6:壓測四橫向問題修正(2026-06-06,richblack 點名)
來源:
/Users/youlinhsieh/Documents/tech_projects/test_arcrun/docs/壓測報告.md。 四個結構性問題(非個別 bug):薄殼原則未成鐵律、CLI/MCP 不同步打不同帳號、deploy 未全推、表達不清。
- 6.1 薄殼鐵律成文 + hook 強制:新增
.claude/rules/07-thin-shell.md(能力長在 API,介面只暴露);02-forbidden.md第五類 +CLAUDE.md鐵律 8 + 索引;pre-write-guard.sh規則 7.x (擋 cli/src + arcrun-mcp/src 的 seedApiRecipes/seedAuthRecipes、upsert 拼裝、deployFullyOk gate)。 - 6.2 seed 下沉成 API 行為(薄殼正例 + 修 §4.1 seed bug):
- 新增
cypher-executor/src/routes/init-seed.ts:POST /init/seed一次灌 API recipe + auth recipe(冪等、直寫 KV、誠實計數),mount 進 index.ts - 種子資料移到 server:
cypher-executor/src/lib/api-recipe-seeds.ts(唯一真相),刪 CLI 重複cli/src/lib/api-recipe-seeds.ts,seed-api-recipes.ts改 import server 端 - CLI
init.ts:seedApiRecipes迴圈 →callSeedEndpoint薄殼一次呼叫;移除 deployFullyOk gate(registry 失敗不再連坐害 seed 被跳過,§4.1 根因);auth recipe 現在一併 seed(§4.1.2 修) - CLI
update.ts:重部署後也呼叫/init/seed(修 §4.1.3「update 不 seed 卻提示說會 seed」矛盾)+ 改為重解析「全部」KV id(修「只注入 2 個」風險)
- 新增
- 6.3 hook seed 例外通用化:
*-seeds.ts整類豁免 endpoint/template 檢查(richblack 原則:不為單一零件改全域規則),未來新種子檔自動適用,永不再動 hook。 - 6.4 registry SUBMISSIONS_KV(修 §2.6/#11「20/21」):加進
REQUIRED_KV_NAMESPACES→ init/update 會建 + 注入 → registry 部署回 21/21 → 連帶 seed 不再被連坐(§4.1.1)。 - 6.5 Deploy 一致性(Gherkin + 把 npm publish 補進現行機制):誠實前提——GH Actions 2026-05-16 停用、公開 repo
.github/已移除,現行 deploy 走scripts/local-deploy.sh。故:tests/release.feature(每個 publish target 場景,描述「該到位什麼」)scripts/check-release.sh(一眼看版本/部署狀態,已驗證抓出 CLI 1.2.0≠npm 1.1.0 漂移)scripts/local-deploy.sh第 6 段新增 CLI npm publish(cli/ 變動且 version bump → npm publish;同版跳過、未登入誠實標)。這是真正讓「推送=全部到位」的修法,根因是舊腳本只 wrangler deploy worker 從不 publish CLI。.github/workflows/publish-cli.yml為預備檔(gitignored、不跑),日後重啟 GH Actions 可啟用。
- 6.6 表達不清 → README 同步現況:移除 R2 殘留文案(權限表去掉 R2、init 輸出去掉 WASM_BUCKET、「無需綁卡」)、補
--account-id/--api-token/env 非互動、補多帳號.arcrun.yaml+acr config --where。 - 6.7 客觀驗證:cypher-executor + cli 兩端
tsc --noEmitexit 0;hook 7.x + *-seeds 例外 + 非 seed 仍擋 全部回歸測試通過。 - 6.8 MCP 帳號架構(richblack 2026-06-06 拍板「單一 remote MCP + .env 切 MCP URL」,推翻初版三方案):
- SDD
mcp-account-source.md重寫為實作版。不加 stdio(self-hosted 用戶也有 CF,MCP 一律 remote Worker;差別只在連哪台)。 - 共用 config 解析:
config.ts加mcp_url三層(envARCRUN_MCP_URL> 專案.arcrun.yaml> 全域)+getMcpUrl()+DEFAULT_MCP_URL。「切換帳號」能力收斂到 config 解析(薄殼正解),不再綁 CLI。 - MCP 搬進
arcrun/mcp/(從 sibling repo verbatim 搬;wrangler name→arcrun-mcp+workers_dev=true;形態不變仍 remote Worker)。deploy 掃描已掃到、tsc 綠。 - 新增
acr mcp-setup:依getMcpUrl()寫專案.mcp.json(remote http MCP)。init 順帶呼叫。接案進客戶資料夾跑一次 → Claude Code 連客戶 MCP。實測 3 情境(fallback/專案覆蓋/env)+ merge 保留既有 server 全通過。 acr --version改從 package.json 動態讀(不再 hardcode,根治版本漂移)。
- SDD
- 6.10 CLI 版本自動化(richblack:deploy 時自動昇版 + 留記錄,避免忘了改):
local-deploy.shdeploy CLI 時若版本未 bump → 自動npm version patch+ prependcli/CHANGELOG.md(含 commit subject)。已 bump 到 1.3.0 + 建 CHANGELOG.md。 - 6.9 驗收:richblack 跑
scripts/local-deploy.sh(worker + MCP + CLI npm 一起);壓測者重跑acr init→ recipe/auth-recipe 不再空 +.mcp.json自動產 → 表單→Google Sheets 端到端。 - 6.11 待 richblack 確認:MCP 搬進主庫後對外正式網址(現役
studio.finally.click/mcp,DEFAULT_MCP_URL暫用此);sibling repomatrix/arcrun-mcp去留(建議標歷史、新開發在 arcrun/mcp/)。
Notes
- JS SDK 套件名需 richblack 決定(
arcrun已被 CLI 佔用 → 可能用@arcrun/sdk) - OAuth secrets 設定需 richblack 手動操作(GCP Console + GitHub Settings)
bind()跨 session 限制是已知的,封測期間先接受- credential 加密用的
encryption_key目前由/register回傳,acr init自動存入 config