# u6u-core 獨立開源 Repo 需求規格 v3

## 背景與定位

### 為什麼開源

u6u-core 是 AI 工作流執行引擎，開源的護城河邏輯如下：

```
開源（u6u-core）                閉源（InkStone 付費服務）
────────────────────────        ──────────────────────────────
cypher-executor（執行引擎）      KBDB 向量搜尋
WASM 零件庫（Gmail / GSheets…） KBDB graph 查詢
credentials Worker              Persona SDK / Mini-me
CLI                             MatchGPT
                                → 需要訂閱，不需要 YAML / KV
```

用戶自架版：YAML + CF KV，完全免費。
升級版：不需要 YAML，直接用自然語言查 KBDB 圖譜組 workflow，這是差異化。

### 目前 matrix repo 狀況

```
matrix/
├── cypher-executor/   ← 要搬進 u6u-core
├── u6u-core/
│   ├── builtins/
│   ├── credentials/
│   └── registry/
│       └── components/（21 個 WASM 零件）
└── ...（其他 InkStone 內部服務，不搬）
```

---

## 任務一：搬移 cypher-executor 進 u6u-core

### 目標結構

```
u6u-core/（新獨立 repo，開源）
├── README.md
├── cypher-executor/         ← 從 matrix/cypher-executor 搬入
│   ├── src/
│   ├── wrangler.toml        ← 需要清理（移除 InkStone 內部 bindings）
│   └── ...
├── credentials/             ← 從 matrix/u6u-core/credentials 搬入
├── builtins/                ← 從 matrix/u6u-core/builtins 搬入
└── registry/
    └── components/          ← 從 matrix/u6u-core/registry/components 搬入
```

### wrangler.toml 清理（重要）

現有 `cypher-executor/wrangler.toml` 有大量 InkStone 內部 Service Bindings，開源版要移除：

**移除（InkStone 專屬，不公開）：**
```toml
# 移除這些 services bindings：
KBDB          → inkstone-kbdb-api
REGISTRY      → inkstone-component-registry
CLINIC_GDRIVE → clinic-gdrive
CLINIC_EXCEL  → clinic-excel
CLINIC_ANALYSIS
CLINIC_RENDER
CLINIC_GSHEETS
AICEO         → inkstone-aiceo-bot
MINI_ME       → inkstone-mini-me
```

**保留（用戶自己部署需要的）：**
```toml
[[kv_namespaces]]
binding = "EXEC_CONTEXT"    # 執行上下文暫存

[[kv_namespaces]]
binding = "WEBHOOKS"        # workflow YAML 儲存

[[r2_buckets]]
binding = "WASM_BUCKET"     # WASM 零件二進位

[ai]
binding = "AI"              # Workers AI（auto-publish 用）
```

**新增（開源版用戶需要的）：**
```toml
[[kv_namespaces]]
binding = "CREDENTIALS_KV"  # credential 加密存儲
```

### 清理後的 component-loader

現有 component-loader 可能有 InkStone 內部查詢邏輯（KBDB HTTP fetch），
開源版改為：**直接從 WASM_BUCKET R2 讀取 `.wasm` 檔案**，不依賴任何外部服務。

---

## 任務二：零件完成度審查與補充

### 完成度標準

每個零件的 `component.contract.yaml` 必須包含：

```yaml
# 已有（現狀）
canonical_id: "gmail"
input_schema: ...
output_schema: ...
gherkin_tests: ...

# 需要補充
credentials_required:        # 需要 token 的零件才需要此欄位
  - key: gmail_token         # 對應 credentials.yaml 的 key 名稱慣例
    type: google_oauth       # token 類型
    description: "Google OAuth access token（gmail.send scope）"
    inject_as: access_token  # 執行時自動注入到 input 的哪個欄位

config_example: |            # scaffold 指令產出的範本，帶說明註解
  send_email:                # 節點名稱（可自訂）
    to: ""                   # 收件人 Email（必填）
    subject: ""              # 主旨（必填）
    body: ""                 # 內文（必填）
    # access_token 由 credentials.yaml 的 gmail_token 自動注入
```

### 需要 credentials_required 的零件

| 零件 | 需要的 token | inject_as |
|------|-------------|-----------|
| gmail | google_oauth | access_token |
| google_sheets | google_oauth | access_token |
| telegram | telegram_bot_token | bot_token |
| line_notify | line_token | token |
| http_request | 不固定（用戶自訂） | 不適用 |

### 不需要 credentials_required 的零件

set, filter, merge, switch, wait, if_control, foreach_control,
try_catch, validate_json, string_ops, number_ops, array_ops,
date_ops, cron, ai_transform_compile, ai_transform_run

### 審查任務（給 CC）

對 21 個零件逐一檢查，**只回報，不修改**：

```
路徑：u6u-core/registry/components/

檢查四項：
1. contract.yaml 存在？
2. 有 credentials_required？（需要 token 的才需要）
3. 有 config_example？
4. main.go required 欄位與 contract input_schema required[] 一致？

回報格式：表格（✓ / ✗ / N/A）+ 每個零件缺少什麼
不修改任何檔案。
```

審查完成後，再逐一補充缺少的欄位。

---

## 任務三：workflow YAML 格式定義

### 格式設計原則

- `flow:` 用 `>>` 三元組描述資料流，人類直接看懂
- 關係詞使用有語意的詞，**不使用 PIPE**（PIPE 等於什麼都沒說）
- `config:` 用零件名稱對應參數，欄位從 contract 的 config_example 來
- credential 全部集中在 `credentials.yaml`，workflow 只寫 `{{creds.KEY}}`

### 可用關係詞

| 關係詞 | 語意 | 使用時機 |
|--------|------|---------|
| `完成後` | 前一個成功後執行 | 最常用的串接 |
| `失敗時` | 前一個失敗後執行 | 錯誤處理 |
| `對每個` | 對陣列每個元素執行 | 迭代 |
| `條件滿足時` | 條件分支 | 判斷 |
| `ON_SUCCESS` | 同「完成後」 | 英文版 |
| `ON_FAIL` | 同「失敗時」 | 英文版 |
| `FOREACH` | 同「對每個」 | 英文版 |
| `IF` | 同「條件滿足時」 | 英文版 |
| `ON_CLICK` | 前端按鈕觸發 | UI 互動 |
| `CALLS_SUBFLOW` | 呼叫子工作流 | 模組化 |

**禁止使用 PIPE** — 任何串接都應該用有語意的關係詞。

### workflow.yaml 範例

```yaml
name: newsletter_subscribe
description: 訂閱電子報，發感謝信並記錄到 GSheets

flow:
  - "input >> 完成後 >> send_thanks"
  - "input >> 完成後 >> save_to_sheet"
  - "send_thanks >> 完成後 >> output"
  - "send_thanks >> 失敗時 >> notify_error"
  - "save_to_sheet >> 完成後 >> output"

config:
  send_thanks:             # componentId: gmail（由 cypher-executor 語意搜尋對應）
    to: "{{input.email}}"
    subject: "感謝訂閱！"
    body: "歡迎加入！"
    # access_token 由 credentials.yaml 的 gmail_token 自動注入

  save_to_sheet:           # componentId: google_sheets
    action: write
    spreadsheet_id: "{{creds.sheet_id}}"
    range: "訂閱者!A:B"
    values: [["{{input.email}}", "{{input.timestamp}}"]]
    # access_token 由 credentials.yaml 的 google_oauth 自動注入

  notify_error:            # componentId: telegram
    chat_id: "{{creds.telegram_chat_id}}"
    text: "發信失敗：{{input.email}}"
    # bot_token 由 credentials.yaml 的 telegram_bot_token 自動注入
```

### credentials.yaml 範例

```yaml
# credentials.yaml — 類似 .env，加入 .gitignore，不進 git
# u6u creds push 時逐一加密上傳到 CREDENTIALS_KV

gmail_token: "ya29.a0AfB_..."
google_oauth: "ya29.a0AfB_..."
sheet_id: "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms"
telegram_bot_token: "123456:ABC-..."
telegram_chat_id: "987654321"
```

### 執行時 credential 注入流程

```
u6u run newsletter_subscribe
  ↓
cypher-executor 讀 workflow YAML
  ↓
遇到節點 send_thanks → 查 contract：credentials_required.inject_as = access_token
  ↓
去 CREDENTIALS_KV 讀 gmail_token → 解密
  ↓
注入到 WASM input：{ to, subject, body, access_token: "ya29..." }
  ↓
WASM 執行，用戶的 config 裡完全不出現 token
```

---

## 任務四：CLI 開發

### 技術選型

- **語言**：Node.js（TypeScript）
- **安裝**：`npm i -g u6u`
- **依賴**：`commander`、`js-yaml`、`chalk`、`ora`

### 指令規格

#### `u6u init`

互動式初始化，產生 `~/.u6u/config.yaml` 和本機 `credentials.yaml`。

```
$ u6u init
? Cloudflare Account ID: abc123
? KV Namespace ID (WEBHOOKS): xyz789
? KV Namespace ID (CREDENTIALS_KV): abc456
? R2 Bucket name (WASM_BUCKET): u6u-wasm
? Cypher Executor Worker URL: https://cypher-executor.xxx.workers.dev
? Credentials Worker URL: https://u6u-credentials.xxx.workers.dev
? Cloudflare API Token: ***

✓ 設定完成 → ~/.u6u/config.yaml
✓ 建立 credentials.yaml（已加入 .gitignore）
```

---

#### `u6u creds push [credentials.yaml]`

讀取 credentials.yaml，逐一加密上傳到 CREDENTIALS_KV。

```
$ u6u creds push
讀取 ./credentials.yaml...
  ✓ gmail_token          → 已加密上傳
  ✓ google_oauth         → 已加密上傳
  ✓ sheet_id             → 已上傳
  ✓ telegram_bot_token   → 已加密上傳
  ✓ telegram_chat_id     → 已上傳
共上傳 5 個 credentials
```

---

#### `u6u push <workflow.yaml>`

解析 `flow:` 三元組，轉換成 triplets 陣列，上傳到 WEBHOOKS KV。

```
$ u6u push newsletter_subscribe.yaml
✓ 已上傳 newsletter_subscribe → WEBHOOKS KV
  Webhook: https://cypher-executor.xxx.workers.dev/webhook/abc123
```

轉換邏輯（CLI 負責）：

```
flow[] 三元組
  ↓
POST /cypher/search（取得 ExecutionGraph）
  ↓
連同 config 存入 WEBHOOKS KV
```

---

#### `u6u run <workflow_name> [--input key=value...]`

觸發執行，顯示結果。

```
$ u6u run newsletter_subscribe --input email=test@example.com
⏳ 執行中...
✓ 完成（2.3s）

結果：
  send_thanks:    { success: true, data: { message_id: "xxx" } }
  save_to_sheet:  { success: true, data: { range: "訂閱者!A2" } }
```

錯誤時給出具體修復步驟：

```
✗ 執行失敗：節點 send_thanks
  原因: access_token 無效（401 Unauthorized）

  修復方式：
  1. 更新 credentials.yaml 的 gmail_token
  2. 執行 u6u creds push
  3. 重新執行 u6u run newsletter_subscribe

  取得 Google OAuth token：
  → https://developers.google.com/oauthplayground
```

---

#### `u6u validate <workflow.yaml>`

執行前完整驗證，提前發現問題。

```
$ u6u validate newsletter_subscribe.yaml
✓ YAML 格式正確
✓ flow 三元組語法正確
✓ 所有關係詞有效（無 PIPE）
✓ 所有節點名稱在 config 有對應
✓ 所有零件存在於 WASM_BUCKET
✓ credentials 對應：
    gmail_token        ✓ 已上傳
    google_oauth       ✓ 已上傳
    sheet_id           ✓ 已上傳
    telegram_bot_token ✗ 缺少

⚠ 缺少 1 個 credential：
  telegram_bot_token → 請加入 credentials.yaml 並執行 u6u creds push
```

---

#### `u6u parts`

列出可用零件。

```
$ u6u parts
可用零件（21）：

  [整合]
  • gmail           Gmail 發信
                    需要: to, subject, body
                    credential: gmail_token（google_oauth）
  • google_sheets   讀寫 Google 試算表
                    需要: spreadsheet_id, range, action
                    credential: google_oauth
  • telegram        Telegram Bot 發訊息
                    需要: chat_id, text
                    credential: telegram_bot_token
  • line_notify     LINE Notify
                    需要: message
                    credential: line_token
  • http_request    任意 HTTP 請求
                    需要: url

  [控制]
  • if_control      條件分支
  • foreach_control 迭代執行
  • try_catch       錯誤處理
  • switch          多路路由
  • wait            等待 N 毫秒

  [資料]
  • set / filter / merge / string_ops / number_ops / array_ops / date_ops

  [AI]
  • ai_transform_compile   自然語言 → JS 轉換函式
  • ai_transform_run       執行已編譯的轉換
```

---

#### `u6u parts scaffold <component>`

從 contract 的 config_example 產出可直接貼入 workflow 的 config 範本。

```
$ u6u parts scaffold gmail

貼入 workflow.yaml 的 config 區塊：

  send_email:                    # 節點名稱（可自訂）
    to: ""                       # 收件人 Email（必填）
    subject: ""                  # 主旨（必填）
    body: ""                     # 內文（必填）
    # access_token 由 credentials.yaml 的 gmail_token 自動注入

貼入 credentials.yaml：

  gmail_token: ""                # Google OAuth token
                                 # 取得方式：https://developers.google.com/oauthplayground
```

---

#### `u6u list`

列出 WEBHOOKS KV 中所有 workflow。

```
$ u6u list
  • newsletter_subscribe   (更新: 2026-04-16)
  • daily_summary          (更新: 2026-04-15)
```

---

#### `u6u logs <workflow_name>`

查看最近執行記錄。

```
$ u6u logs newsletter_subscribe
  2026-04-16 14:30  ✓ 成功   2.1s
  2026-04-16 09:00  ✗ 失敗   send_thanks: 401 Unauthorized
  2026-04-15 09:00  ✓ 成功   1.8s
```

---

## 開發順序

### Phase 1：搬移與清理（先做）

```
1. 建立新的獨立 repo：u6u-core
2. 從 matrix 搬入：
   - cypher-executor/
   - u6u-core/credentials/
   - u6u-core/builtins/
   - u6u-core/registry/
3. 清理 cypher-executor/wrangler.toml（移除 InkStone 內部 bindings）
4. 確認 component-loader 只依賴 WASM_BUCKET，不依賴 KBDB / REGISTRY
5. 本機部署測試
```

### Phase 2：零件完成度（搬移後）

```
6. 審查 21 個零件的 contract.yaml
7. 補充 credentials_required（gmail, google_sheets, telegram, line_notify）
8. 補充 config_example（全部 21 個）
9. 驗證 main.go required 欄位與 contract 一致
```

### Phase 3：CLI（完成度補充後）

```
10. u6u init
11. u6u creds push
12. u6u push
13. u6u run（含 credential 自動注入）
14. u6u parts / u6u parts scaffold
15. u6u validate
16. u6u list / u6u logs
```

### Phase 4：開源發布

```
17. 撰寫 README.md（快速開始、零件列表、workflow 語法說明）
18. 撰寫 CONTRIBUTING.md（如何新增零件）
19. 發布到 GitHub
20. npm publish（u6u CLI）
```

---

## 不在此次範圍

- KBDB 整合（未來付費服務）
- 向量搜尋 / graph 查詢
- 前端管理介面
- Webhook trigger 設定（用戶自行設定 CF Cron）
- 新增 WASM 零件（現有 21 個先做完整，之後再擴充）
