docs(registry): seed 10 examples + 5 skills (LI SDD M3.1 + M3.3)
對應 .agents/specs/llm-interface/ Milestone 3.1 + 3.3。
registry/examples/ — 10 個可直接 push 的 workflow 範本:
starter: webhook-to-http
common: cron-watcher, llm-classify, rag-search-answer, daily-digest
external: email-summary (gmail+claude+telegram), pdf-to-blocks,
github-issue-bot
advanced: parallel-fanout (trigger_workflow fan-out),
error-retry (try_catch+wait pattern)
每個含:workflow.yaml(可直接 push)+ description.md(解決什麼問題 /
改成你自己的 / 學到什麼)+ tags.json(搜尋用)
registry/skills/ — 5 個 AI playbook(markdown):
build_watcher_workflow — cron + filter + trigger 模式
debug_paused_workflow — claude_api callback paused 怎麼追
migrate_http_to_trigger_workflow — 從 self-fetch 換 trigger_workflow
rag_with_arcrun — KBDB + claude_api 組裝 RAG
add_new_wasm_component — TinyGo 寫 + 部署全流程
兩者差異:
examples = 可直接拿來改的 YAML
skills = 面對 X 問題該怎麼想 + 該用哪個 example
兩者後續:CI 自動同步進 KBDB(type=workflow-example / type=agent-skill),
MCP arcrun_search_examples / arcrun_list_skills 走 KBDB semantic search。
(CI sync 是 M3.4 工作)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
# Skill: Add New WASM Component
|
||||
|
||||
## 何時用這個 skill
|
||||
|
||||
`arcrun_list_components()` 沒有你需要的零件。要寫一個新的 TinyGo / AssemblyScript WASM。
|
||||
|
||||
**重要**:寫零件 = **改 arcrun 平台本身**,不是改 user workflow。
|
||||
這 skill 預設你有 arcrun repo write access。沒有 → 告訴用戶「需要 X 零件,請聯絡平台維護者」,停手。
|
||||
|
||||
## 7 步流程
|
||||
|
||||
### 1. 確認真的需要新零件
|
||||
|
||||
先想:能不能用 `http_request` 加組合搞定?
|
||||
- 多數第三方 API → `http_request` 已夠(搭配 `auth_recipe` 處理 auth)
|
||||
- 簡單轉換 → 用 logic primitives(`set` / `filter` / `array_ops`)
|
||||
- 複雜流程編排 → cypher binding 多步而非單一大零件
|
||||
|
||||
真的需要新零件的場景:
|
||||
- 跟 cypher-executor host functions 互動(KV、加解密、簽 JWT)
|
||||
- 邏輯太複雜不適合多節點分解
|
||||
- 為效能(一次 worker call 取代 10 次 fetch)
|
||||
|
||||
### 2. 讀規範
|
||||
|
||||
- `matrix/arcrun/.claude/rules/03-component-architecture.md` — 部署慣例
|
||||
- `matrix/arcrun/.claude/rules/01-tech-stack.md` — TinyGo 限制
|
||||
- 既有相似零件範例:`matrix/arcrun/registry/components/{name}/main.go`
|
||||
|
||||
### 3. 開新目錄
|
||||
|
||||
```
|
||||
matrix/arcrun/registry/components/{your_component}/
|
||||
├── main.go TinyGo source
|
||||
├── component.contract.yaml input/output schema + 描述
|
||||
└── (build 後產出 .wasm)
|
||||
```
|
||||
|
||||
合約格式(contract.yaml):
|
||||
```yaml
|
||||
canonical_id: your_component
|
||||
display_name: 中文顯示名
|
||||
category: data | auth | api | logic
|
||||
version: 0.1.0
|
||||
description: |
|
||||
做什麼用、限制、注意事項。AI 看這份決定要不要用你的零件
|
||||
input_schema:
|
||||
type: object
|
||||
required: [foo, bar]
|
||||
properties:
|
||||
foo: { type: string, description: "..." }
|
||||
bar: { type: number, description: "..." }
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
result: { type: string }
|
||||
success: { type: boolean }
|
||||
gherkin_tests:
|
||||
- given: "input foo=hello"
|
||||
when: "component runs"
|
||||
then: "result contains hello"
|
||||
```
|
||||
|
||||
### 4. 寫 main.go
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Input struct {
|
||||
Foo string `json:"foo"`
|
||||
Bar int `json:"bar"`
|
||||
}
|
||||
|
||||
type Output struct {
|
||||
Result string `json:"result"`
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
bytes, _ := io.ReadAll(os.Stdin)
|
||||
var in Input
|
||||
json.Unmarshal(bytes, &in)
|
||||
|
||||
// 你的邏輯
|
||||
result := in.Foo + ":" + string(rune(in.Bar))
|
||||
|
||||
out := Output{Result: result, Success: true}
|
||||
json.NewEncoder(os.Stdout).Encode(out)
|
||||
}
|
||||
```
|
||||
|
||||
限制:
|
||||
- 只 import:`os`、`io`、`encoding/json`、`encoding/base64`、`strings`、`time` 等 stdlib
|
||||
- **禁用**:`net/http`(用 host function `u6u.http_request`)、`crypto/rsa`(用 host function)
|
||||
- 全部 logic 在 main(),stdin/stdout JSON I/O
|
||||
|
||||
### 5. 本地 build + 測
|
||||
|
||||
```bash
|
||||
cd registry/components/your_component
|
||||
tinygo build -target=wasi -o your_component.wasm main.go
|
||||
echo '{"foo":"hello","bar":42}' | wasmtime your_component.wasm
|
||||
```
|
||||
|
||||
### 6. 部署成獨立 Worker
|
||||
|
||||
```
|
||||
.component-builds/your_component/
|
||||
├── wrangler.toml name = "arcrun-your-component"
|
||||
├── package.json
|
||||
├── component.wasm 從上面 build 複製過來
|
||||
└── src/index.ts 固定 WASI shim(複製 component-worker-template)
|
||||
```
|
||||
|
||||
`wrangler.toml`:
|
||||
```toml
|
||||
name = "arcrun-your-component"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2025-02-19"
|
||||
workers_dev = true # 必須 true,cypher-executor 走 workers.dev 對內 URL
|
||||
[[routes]]
|
||||
pattern = "your-component.arcrun.dev/*"
|
||||
zone_name = "arcrun.dev"
|
||||
```
|
||||
|
||||
push → CI 自動部署。
|
||||
|
||||
### 7. 註冊到 cypher-executor 白名單
|
||||
|
||||
⚠️ **目前的架構債**(M2 計畫修):每加零件要手動加 `cypher-executor/src/lib/component-loader.ts`:
|
||||
|
||||
```ts
|
||||
const WASM_HTTP_RUNNER_IDS: ReadonlySet<string> = new Set([
|
||||
// ... 既有
|
||||
'your_component', // ← 加這行
|
||||
]);
|
||||
```
|
||||
|
||||
不加 → workflow 用你的零件會噴「找不到零件」。
|
||||
|
||||
未來會改成 registry KV 動態查(`cypher-executor-dynamic-component-discovery` SDD 待開)。
|
||||
|
||||
## 驗證上線
|
||||
|
||||
```
|
||||
arcrun_list_components() → 應該看到 your_component
|
||||
arcrun_get_component_contract(canonical_id='your_component') → 看 schema
|
||||
```
|
||||
|
||||
寫個 test workflow 用你的零件,跑通就完成。
|
||||
Reference in New Issue
Block a user