docs: add SDD specs + user requirements + tests

- .agents/specs/: spec-driven-dev docs for arcrun MVP, auth-recipe,
  credential-primitives-wasm (active refactor), landing-page,
  sdk-and-website, u6u-core-mvp, u6u-platform-evolution.
- .agents/steerings/tech.md: detailed tech stack rationale.
- docs/user_requirements/: long-form requirements incl. credential
  primitives, pages spec, py strategy analysis.
- tests/: end-to-end harness scaffolding.

These are the durable context backing CLAUDE.md's SDD protocol.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 17:48:24 +08:00
parent cadcaef3b0
commit 13b01328c1
36 changed files with 7499 additions and 0 deletions
@@ -0,0 +1,281 @@
# Design Document: arcrun SDK Libraries + Website
## Overview
本設計涵蓋 arcrun 的三個新增交付物:
1. Python SDK lib`pip install arcrun`
2. JS/TS SDK lib`npm install arcrun``@arcrun/sdk`
3. arcrun.dev 網站完善(零件列表、recipe 列表、登入管理)
**設計原則:修改不重建。** SDK 是 `cypher.arcrun.dev` HTTP API 的 thin wrapper。不在 client 端重新實作任何 server 端已有的邏輯(workflow 執行、credential 注入、auth recipe 解析)。唯一在 client 做的是 AES-GCM 加密(因為 server 的 POST /credentials 期望收到加密後的 payload)。
---
## Architecture
### 系統關係圖
```
使用者程式碼
├── CLIacr → cypher.arcrun.devHTTP API
├── Python SDKarcrun → cypher.arcrun.devHTTP API
└── JS SDKarcrun / @arcrun/sdk → cypher.arcrun.devHTTP API
arcrun.dev 網站(Next.js / Cloudflare Pages
├── /login → /auth/google/start, /auth/github/startcypher.arcrun.dev
├── /dashboard → /me, /me/api-key/rotatecypher.arcrun.dev
├── /integrations → /auth-recipescypher.arcrun.dev
└── /components → /recipes + 靜態零件清單(embedded
cypher.arcrun.devCloudflare Worker — cypher-executor,不改)
├── POST /credentials ← 接收 { name, encrypted, iv }
├── GET /credentials ← 列出 credential 名稱
├── DELETE /credentials/:name ← 刪除 credential
├── GET /auth-recipes ← 列出 20 個 auth recipe
├── GET /auth-recipes/:service ← 單一 recipe 詳情
├── POST /webhooks/named ← 部署 workflow
├── POST /webhooks/named/:name/trigger ← 觸發 workflow
├── GET /webhooks/named ← 列出 workflow
├── POST /register ← 註冊取得 API Key
├── GET /me ← 當前用戶資訊
└── /auth/* ← OAuth 流程
```
---
## Python SDK`arcrun/python-sdk/`
### 目錄結構
```
arcrun/python-sdk/
├── pyproject.toml ← hatchling build, name="arcrun", deps=[httpx>=0.27, cryptography>=42]
├── README.md
└── arcrun/
├── __init__.py ← from .client import Arcrun
├── client.py ← Arcrun class(主入口)
├── crypto.py ← AES-GCM 加密(client 端,用 cryptography 套件)
├── creds.py ← CredentialsClientpush/list/delete
├── auth.py ← AuthClientsetup/bind/get_token/list_services
└── workflows.py ← WorkflowClientrun/push/list/delete
```
### API 設計
```python
from arcrun import Arcrun
# 建構 — api_key 從參數 > 環境變數 > ~/.arcrun/config.yaml 自動取得
client = Arcrun()
# 或明確指定
client = Arcrun(api_key="ak_xxx", encryption_key="hexstring")
# Auth:設定並綁定服務
client.auth.setup("openai", api_key="sk-xxx") # 加密 + 上傳
openai_client = client.auth.bind("openai") # 取回 pre-auth client
response = openai_client.get("/models") # httpx.Client
token = client.auth.get_token("openai") # raw token string
services = client.auth.list_services() # [{ service, display_name, ... }]
# Credentials:低階操作
client.creds.push("my_token", "value123")
names = client.creds.list()
client.creds.delete("my_token")
# Workflows
result = client.workflows.run("my-flow", {"email": "user@example.com"})
url = client.workflows.push("my-flow", graph_dict)
workflows = client.workflows.list()
```
### Credential 加密流程
```
setup("openai", api_key="sk-xxx")
1. GET /auth-recipes/openai → recipe(含 required_secrets, inject
2. 對應 required_secrets[0].key = "openai_api_key"
3. crypto.py 用 encryption_key AES-GCM 加密 "sk-xxx"
4. POST /credentials → { name: "openai_api_key", encrypted, iv }
5. 本地 _cred_cache["openai_api_key"] = "sk-xxx"(供 bind() 用)
bind("openai")
1. GET /auth-recipes/openai → recipe.inject.header = { Authorization: "Bearer {{secret.openai_api_key}}" }
2. 用 _cred_cache["openai_api_key"] 替換 template → "Bearer sk-xxx"
3. 回傳 AuthenticatedClient(base_url="https://api.openai.com/v1", headers={"Authorization": "Bearer sk-xxx"})
```
**注意**`bind()` 依賴 `setup()` 在同一 session 建立的 `_cred_cache`。跨 session 使用時(credential 已上傳但 cache 不存在),`bind()` 無法解析 template — 此時 `get_token()` 也無法返回值。**這是已知限制,封測期間先接受。** 長期解法是 server 提供 `/credentials/:name/secret` 解密端點(u6u-core/credentials 已有)。
### 關鍵差異:crypto.py 的定位
`crypto.py` 只做 **加密**encrypt),不做解密。
功能等同 `u6u-core/credentials/src/actions/crypto.ts``encrypt()` 函數。
解密只在 server 端發生(cypher-executor 的 `credential-injector.ts``u6u-core/credentials/getCredentialSecret.ts`)。
---
## JS/TS SDK`arcrun/js-sdk/`
### 目錄結構
```
arcrun/js-sdk/
├── package.json ← name TBDarcrun vs @arcrun/sdk),tsup build
├── tsconfig.json ← ES2020, NodeNext
└── src/
├── index.ts ← export class Arcrun
├── crypto.ts ← Web Crypto API AES-GCM encryptclient 端)
├── creds.ts ← CredentialsClientpush/list/delete
├── auth.ts ← AuthClientsetup/bind/getToken/listServices
└── workflows.ts ← WorkflowClientrun/push/list/delete
```
### API 與 Python SDK 對等
```typescript
import { Arcrun } from 'arcrun' // or '@arcrun/sdk'
const client = new Arcrun() // reads ARCRUN_API_KEY from env
await client.auth.setup('openai', { api_key: 'sk-xxx' })
const oai = await client.auth.bind('openai')
const models = await (await oai.get('/models')).json()
const token = await client.auth.getToken('openai')
const services = await client.auth.listServices()
await client.creds.push('my_token', 'value')
const names = await client.creds.list()
const result = await client.workflows.run('my-flow', { email: 'user@example.com' })
```
### Build 產物
```
dist/
├── index.js ← ESM
├── index.cjs ← CJS
├── index.d.ts ← TypeScript 型別
└── index.d.cts
```
### Crypto 實作
使用 Web Crypto API`crypto.subtle`),相容 Node 18+ / browsers / CF Workers / Deno
```typescript
async function encrypt(plaintext: string, hexKey: string): Promise<{ encrypted: string; iv: string }> {
const key = await crypto.subtle.importKey('raw', hexToBytes(hexKey), { name: 'AES-GCM' }, false, ['encrypt']);
const iv = crypto.getRandomValues(new Uint8Array(12));
const ciphertext = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, new TextEncoder().encode(plaintext));
return { encrypted: toBase64(ciphertext), iv: toBase64(iv.buffer) };
}
```
---
## arcrun.dev 網站
### 現有狀態(`arcrun/landing/`
已完成:
- [x] `/` — Hero + Code DemoPython/JS/HTTP tabs
- [x] `/login` — Google + GitHub OAuth 按鈕(前端 OK,需設 OAuth secrets
- [x] `/dashboard` — API Key 查看/Copy/Rotate/Revoke(依賴 `/me` API
- [x] `/integrations` — 20 個 recipe 靜態卡片
- [x] `/api-docs` — Swagger UI CDN 嵌入
- [x] `middleware.ts` — 保護 `/dashboard`(未登入 → `/login`
- [x] Cloudflare Pages 部署
待完成:
- [ ] OAuth secrets 設定(`GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` / `GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET`
- [ ] `/components` 頁面(零件列表 — 21 個 WASM 零件的 input/output/config_example
- [ ] 首頁 code demo 更新為三種使用方式(CLI / Python / JS
- [ ] 登入流程真實驗證
### 新增頁面:`/components`
```
/components
├── 零件卡片(21 個)
│ ├── canonical_id
│ ├── display_name
│ ├── description
│ ├── input_schemarequired / optional 欄位)
│ ├── output_schema
│ ├── credentials_requiredif any
│ └── config_exampleYAML code block
└── 分類篩選(邏輯 / API / 控制流)
```
資料來源:靜態嵌入(從 `registry/components/*/component.contract.yaml` 在 build 時讀取),不依賴 runtime API。
### OAuth 設定(待 richblack 操作)
需要在 Cloudflare Worker 設定以下 secrets
```bash
wrangler secret put GOOGLE_CLIENT_ID --name arcrun-cypher-executor
wrangler secret put GOOGLE_CLIENT_SECRET --name arcrun-cypher-executor
wrangler secret put GITHUB_CLIENT_ID --name arcrun-cypher-executor
wrangler secret put GITHUB_CLIENT_SECRET --name arcrun-cypher-executor
wrangler secret put SESSION_SIGNING_SECRET --name arcrun-cypher-executor
```
---
## server 端需要的修改
### cypher-executor 修改(最小化)
目前 `POST /credentials` 端點(`routes/credentials.ts`)接收 `{ name, encrypted, iv }` 後直接存 KV。
SDK 需要的改動:
1. **`GET /auth-recipes` 回應格式**:目前 list 端點回 `{ recipes: [...] }` 但 recipe 的 `service` 欄位是 key — SDK 已在 list_services() 正確處理 ✅
2. **`GET /auth-recipes/:service` 回應格式**:目前回 `{ success: true, recipe: {...} }` — SDK 需讀 `body.recipe` 而非 body 本身 ✅
3. **`POST /credentials` 不需改動** — SDK 自己做 AES-GCM 加密後送 `{ name, encrypted, iv }`
4. **未來**:新增 `GET /credentials/:name/secret` 端點(解密返回 plaintext),讓跨 session 的 `bind()` 能工作。但此端點在 `u6u-core/credentials/src/actions/getCredentialSecret.ts` 已有實作 — 需要在 cypher-executor 整合或 Service Binding 到 u6u-credentials Worker。**封測後再做。**
---
## 不做的事(明確排除)
- ❌ 不在 SDK 裡做 workflow 解析或 YAML 處理 — 那是 CLI 的職責
- ❌ 不在 SDK 裡做 server-side 解密 — 解密只在 server 端
- ❌ 不建新的 credentials Worker — 用現有的
- ❌ 不建新的 KV namespace — 用現有的 CREDENTIALS_KV
- ❌ 不改 cypher-executor 的 credential-injector.ts — 那已經完成且測試通過
---
## 實作順序
```
Phase 1Python SDK 重建 + 測試
1.1 重建 arcrun/python-sdk/(按本 SDD 的結構)
1.2 修正上次的 bugrecipe 回應 wrapper、inject key "header" vs "headers"、secret key mapping
1.3 對 cypher.arcrun.dev live 測試全部 API
1.4 本地安裝測試(pip install -e .
Phase 2JS SDK 重建 + 測試
2.1 重建 arcrun/js-sdk/(按本 SDD 的結構)
2.2 同步修正 Python SDK 發現的所有 recipe 格式問題
2.3 buildtsup+ 本地測試
Phase 3arcrun.dev 網站補完
3.1 新增 /components 頁面
3.2 更新首頁 code demo(三種使用方式)
3.3 OAuth secrets 設定(需 richblack 操作 GCP / GitHub
3.4 登入流程驗證
Phase 4GitHub README + 發布
4.1 更新 arcrun/README.md — 三種 Quick Start
4.2 pip publisharcrun
4.3 npm publishTBD 套件名)
4.4 最終驗證:從零開始 pip install / npm install / 打 API
```
@@ -0,0 +1,131 @@
# Requirements: arcrun SDK Libraries + Website
## Introduction
arcrun 目前有三個使用介面:
1. **CLI**`acr` 指令)— 已完成,用 YAML 定義 workflow 並推送執行
2. **Python / JS SDK lib**(本次新增)— `pip install arcrun` / `npm install arcrun`,讓開發者在寫程式時直接用 arcrun 功能
3. **arcrun.dev 網站**(本次完成)— 登入取得 API Key、管理 Key、瀏覽零件 / recipe 列表
**核心原則**SDK lib 是 `cypher.arcrun.dev` HTTP API 的 thin wrapper。所有業務邏輯(加解密、credential 注入、workflow 執行)都在 server 端完成。Client 端不重做 server 已有的邏輯。
**現有基礎設施**(不重建,直接使用):
- `cypher.arcrun.dev`cypher-executor Workerworkflow 執行、credential 管理、auth recipe、webhook
- `u6u-core/credentials`credential WorkerAES-GCM 加解密)— arcrun/credentials 是其 cherry-pick
- `arcrun/cli`CLI 工具(已發布 npm `arcrun@1.1.0`
- `arcrun/landing`Next.js 前端(已部署 Cloudflare Pages,有 hero/login/dashboard/integrations 骨架)
---
## Glossary
- **SDK lib**Python / JS 套件,wrapping `cypher.arcrun.dev` HTTP API,安裝後可在程式碼中直接使用
- **auth.setup()**:上傳一個服務的 credential(如 Notion token、OpenAI API Key)到 arcrun
- **auth.bind()**:取回已設定服務的 pre-authenticated HTTP client
- **auth.get_token()**:取回某服務的 raw tokenescape hatch,給官方 SDK 用)
- **workflows.run()**:觸發已部署的 workflow
- **workflows.push()**:上傳 workflow 定義
- **Recipe**:描述「如何對某服務認證」的 YAML 設定,存在 RECIPES KV
---
## Requirements
### Requirement 1Python SDK`pip install arcrun`
**User Story:** As a Python 開發者, I want `pip install arcrun` 後在程式碼中使用 arcrun, so that 不用離開寫程式環境就能串接 20+ 服務。
#### Acceptance Criteria
1. THE Python SDK SHALL 以 `arcrun` 套件名發布到 PyPI,支援 Python 3.10+。
2. THE SDK SHALL 提供以下 API
- `Arcrun(api_key=, base_url=)` — 建構 clientapi_key 支援從環境變數 `ARCRUN_API_KEY``~/.arcrun/config.yaml` 自動讀取
- `client.health()` — 健康檢查
- `client.auth.list_services()` — 列出可用 auth recipe 服務
- `client.auth.setup(service, **kwargs)` — 上傳 credential
- `client.auth.bind(service)` — 取得 pre-authenticated HTTP client
- `client.auth.get_token(service)` — 取得 raw token
- `client.creds.push(name, value)` — 上傳加密 credential
- `client.creds.list()` — 列出 credential 名稱
- `client.creds.delete(name)` — 刪除 credential
- `client.workflows.run(name, input)` — 觸發 workflow
- `client.workflows.push(name, graph)` — 上傳 workflow
- `client.workflows.list()` — 列出已部署 workflow
3. THE SDK 的 credential 加密 SHALL 在 client 端完成(使用 `cryptography` 套件 AES-GCM),然後以 `POST /credentials` 上傳加密後的 `{ name, encrypted, iv }` 到 server。
4. THE `auth.bind()` SHALL 從 server 取得 auth recipe 的 inject template,在 client 端用 cache 的 plaintext 值填入,回傳 pre-configured `httpx.Client`
5. THE SDK SHALL 使用 `httpx` 做 HTTP clientasync 版使用 `httpx.AsyncClient`)。
6. THE SDK 位置 SHALL 為 `arcrun/python-sdk/`build 系統用 `hatchling``pyproject.toml`)。
---
### Requirement 2JavaScript/TypeScript SDK`npm install arcrun`
**User Story:** As a JS/TS 開發者, I want `npm install arcrun` 後在程式碼中使用 arcrun, so that 可以嵌入現有 Node.js / Deno / Cloudflare Workers 專案。
#### Acceptance Criteria
1. THE JS SDK SHALL 以 `arcrun` 套件名發布到 npm,提供 ESM + CJS 雙格式 + TypeScript 型別定義。
2. THE SDK SHALL 提供與 Python SDK 對等的 APIcamelCase 版):
- `new Arcrun({ apiKey?, baseUrl? })` — 讀 `process.env.ARCRUN_API_KEY`
- `client.health()` — 回傳 `Promise<unknown>`
- `client.auth.listServices()` / `setup()` / `bind()` / `getToken()`
- `client.creds.push()` / `list()` / `delete()`
- `client.workflows.run()` / `push()` / `list()` / `delete()`
3. THE SDK 的 credential 加密 SHALL 使用 Web Crypto API`crypto.subtle` AES-GCM),相容 Node 18+、browsers、Cloudflare Workers、Deno。
4. THE `auth.bind()` SHALL 回傳一個有 `get/post/put/delete/patch` 方法的 `AuthenticatedClient`base URL + auth headers 已配置。
5. THE SDK SHALL 使用原生 `fetch()` API,不依賴外部 HTTP client 套件。
6. THE SDK 位置 SHALL 為 `arcrun/js-sdk/`build 用 `tsup`ESM + CJS + DTS),`tsconfig.json` target ES2020 + NodeNext module。
7. THE JS SDK 套件名與 CLI 套件名衝突(都叫 `arcrun`),SHALL 使用 `@arcrun/sdk` 或由 richblack 決定套件名。
---
### Requirement 3arcrun.dev 網站完成
**User Story:** As a 潛在用戶, I want 在 arcrun.dev 上登入取得 API Key、瀏覽零件和 recipe 列表, so that 我可以評估 arcrun 是否符合需求並立即開始使用。
#### Acceptance Criteria
1. THE 網站 SHALL 在 `arcrun.dev` 提供以下頁面:
- `/` — 首頁 Hero + 三種使用方式(CLI / Python / JS
- `/login` — Google + GitHub OAuth 登入
- `/dashboard` — 登入後顯示 API Key(查看/Copy/Rotate/Revoke
- `/integrations` — 列出 20 個 auth recipe 服務,可按分類篩選
- `/components` — 列出所有零件(21 個 WASM 零件),顯示 input/output schema、config_example
- `/api-docs` — Swagger UI,可直接試打 API
2. THE 登入 SHALL 使用 Google + GitHub OAuth,流程走 `cypher.arcrun.dev``/auth/*` 端點。
3. THE 登入後 SHALL 自動對該 email 呼叫 `/register` 取得 API Key(若已有則取回現有 key)。
4. THE `/dashboard` SHALL 允許 Rotate(生成新 key)、Revoke(標記失效)、Copy to clipboard。
5. THE 網站 SHALL 部署在 Cloudflare Pages(現有 `arcrun/landing`),使用 Next.js App Router。
6. THE 首頁 code demo 區 SHALL 包含三個 tabPython、JavaScript、HTTP/curl,展示三種使用方式。
---
### Requirement 4GitHub README 更新
**User Story:** As a GitHub 訪客, I want README 清楚說明三種使用方式, so that 我能選擇最適合的方式開始用 arcrun。
#### Acceptance Criteria
1. THE `arcrun/README.md` SHALL 包含三種 Quick Start
- **CLI**`npm i -g arcrun && acr init && acr push workflow.yaml && acr run`
- **Python**`pip install arcrun && from arcrun import Arcrun && ...`
- **JavaScript**`npm install arcrun && import { Arcrun } from 'arcrun' && ...`
2. THE README SHALL 包含完整零件列表(21 個)和 auth recipe 列表(20 個服務)。
3. THE README SHALL 連結到 `arcrun.dev`(取得 API Key)和 Swagger UIAPI 文件)。
---
### Requirement 5SDK 發布
**User Story:** As a SDK 使用者, I want 公開安裝並直接使用, so that 不需要從原始碼 build。
#### Acceptance Criteria
1. THE Python SDK SHALL 發布到 PyPI`pip install arcrun` 可安裝。
2. THE JS SDK SHALL 發布到 npm`npm install arcrun`(或 `@arcrun/sdk`)可安裝。
3. THE 發布前 SHALL 完成以下測試(對 `cypher.arcrun.dev` live API):
- `health()`
- `auth.list_services()`
- `auth.setup()` + `auth.bind()` ✅(至少一個 static_key 服務如 openai
- `creds.push()` + `creds.list()`
- `workflows.list()`
@@ -0,0 +1,120 @@
# 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 1Python 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)、listGET /credentials)、delete
- [ ] 1.5 `arcrun/auth.py`AuthClient — setupfetch recipe → match secrets → encrypt → push)、bindfetch recipe → resolve headers from cache → return AuthenticatedClient)、get_token、list_services
- [ ] 1.6 `arcrun/workflows.py`WorkflowClient — runPOST /webhooks/named/{name}/trigger)、pushPOST /webhooks/named)、listGET /webhooks/named)、delete
- [ ] 1.7 `arcrun/client.py`Arcrun class — 讀 api_key / encryption_key 從 param > env > config.yaml
- [ ] 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`
- [ ] 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")`
---
## Phase 2JS/TS SDK
- [ ] 4. 建立 `arcrun/js-sdk/` 目錄
- [ ] 4.1 `package.json`name TBDarcrun vs @arcrun/sdk),deps=devDeps onlytsup, 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
- [ ] 5. 同步修正(與 Python SDK 同樣的 recipe 格式問題)
- [ ] 5.1 `_fetchRecipe()``body.recipe`
- [ ] 5.2 inject key: `header` not `headers`
- [ ] 5.3 setup() secret key alias matching
- [ ] 5.4 listServices() 用 `service` 欄位
- [ ] 6. Build + 測試
- [ ] 6.1 `tsup` build → dist/index.js + dist/index.cjs + dist/index.d.ts
- [ ] 6.2 Node.js 腳本對 live API 測試(同 Python 測試項目)
---
## Phase 3arcrun.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 類 / 控制流類
- [ ] 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 後驗證登入流程
- [ ] 10. 部署
- [ ] 10.1 Cloudflare Pages build + deploy
- [ ] 10.2 驗證所有頁面可存取
---
## Phase 4README + 發布
- [ ] 11. 更新 `arcrun/README.md`
- [ ] 11.1 三種 Quick StartCLI / 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
---
## Notes
- JS SDK 套件名需 richblack 決定(`arcrun` 已被 CLI 佔用 → 可能用 `@arcrun/sdk`
- OAuth secrets 設定需 richblack 手動操作(GCP Console + GitHub Settings
- `bind()` 跨 session 限制是已知的,封測期間先接受
- credential 加密用的 `encryption_key` 目前由 `/register` 回傳,`acr init` 自動存入 config