# Contributing to arcrun 感謝你考慮貢獻 arcrun!本文件說明如何新增零件(WASM component)並提交至公眾零件庫。 --- ## 開發環境 ### 必要工具 ```bash # TinyGo(編譯 Go → WASM) brew install tinygo # macOS # 或參考 https://tinygo.org/getting-started/ # wasmtime(本機測試 WASM) brew install wasmtime # macOS # 或參考 https://wasmtime.dev # Wrangler CLI(部署 Cloudflare Workers) npm i -g wrangler # arcrun CLI npm i -g arcrun ``` --- ## 新增零件步驟 ### 1. 建立目錄結構 ``` registry/components/my_component/ ├── component.contract.yaml # 零件規格宣告 ├── main.go # 零件邏輯(TinyGo) └── my_component.wasm # 編譯產出(不提交至 git,CI 自動產生) ``` ### 2. 撰寫 component.contract.yaml ```yaml canonical_id: "my_component" display_name: "我的零件" category: "data" # api / logic / data / ai version: "v1" author: "@your-github-username" wasi_target: "preview1" stability: "floating" runtime_compat: - "cf-workers" - "workerd" - "wazero" constraints: max_size_kb: 2048 max_cold_start_ms: 50 no_network_syscall: true # 功能類零件不允許網路請求 no_filesystem_syscall: true io_model: "stdin_stdout_json" input_schema: type: object required: [input] properties: input: type: string description: 輸入文字 output_schema: type: object properties: result: type: string gherkin_tests: - scenario: "基本轉換" given: '{"input":"hello"}' then_contains: '"result"' config_example: | transform: # 節點名稱(可自訂) input: "{{input.text}}" # 輸入欄位(必填) description: "我的零件功能說明。" ``` **需要 Credential 的整合類零件需額外加入:** ```yaml credentials_required: - key: my_api_token type: api_key description: "My Service API token" inject_as: api_token ``` ### 3. 撰寫 main.go WASM 零件使用 stdin/stdout JSON I/O 模型(WASI preview1): ```go package main import ( "encoding/json" "fmt" "os" ) type Input struct { Input string `json:"input"` } type Output struct { Success bool `json:"success"` Result string `json:"result,omitempty"` Error string `json:"error,omitempty"` } func main() { var input Input decoder := json.NewDecoder(os.Stdin) if err := decoder.Decode(&input); err != nil { out, _ := json.Marshal(Output{Success: false, Error: "invalid input: " + err.Error()}) fmt.Println(string(out)) return } // 你的邏輯 result := doTransform(input.Input) out, _ := json.Marshal(Output{Success: true, Result: result}) fmt.Println(string(out)) } func doTransform(s string) string { return "[transformed] " + s } ``` ### 4. 編譯 WASM ```bash cd registry/components/my_component tinygo build -o my_component.wasm -target wasi . ``` ### 5. 本機測試 ```bash # 直接測試 WASM echo '{"input":"hello world"}' | wasmtime run my_component.wasm # 預期輸出:{"success":true,"result":"[transformed] hello world"} ``` ### 6. 驗證 Gherkin 測試 確認 contract.yaml 的 `gherkin_tests` 所有場景都通過: ```bash # 每個 scenario:given 輸入 → 輸出包含 then_contains echo '' | wasmtime run my_component.wasm | grep '' ``` --- ## 提交零件至公眾 Registry ```bash # 確保已編譯 .wasm tinygo build -o my_component.wasm -target wasi . # 提交(需要 arcrun.dev API Key) acr parts publish ./registry/components/my_component/ ``` 提交後: - **功能類**零件(無網路請求):體積 + syscall + Gherkin 測試通過後,立即 `author_only`(你自己可用) - **整合類**零件(有外部 API 呼叫):體積 + syscall 掃描通過後,`author_only` - 等人工審核通過 → `public`(所有人可用,開始累積執行統計) 查詢審核進度: ```bash acr parts publish --status ``` --- ## 零件類型指引 ### 功能類(category: logic / data / ai) - 不允許網路請求(`no_network_syscall: true`) - 不允許檔案系統存取(`no_filesystem_syscall: true`) - 需通過所有 Gherkin 測試 - 冷啟動 < 50ms,體積 < 2048KB ### 整合類(category: api) - 允許網路請求(設 `no_network_syscall: false`) - 必須宣告 `credentials_required` - 需通過體積和 syscall 掃描 --- ## 程式碼風格 - 零件必須回傳包含 `success: bool` 的 JSON - 錯誤時回傳 `{"success":false,"error":"..."}`,不 panic - 所有 `required` 欄位缺少時應回傳 `success:false` 而非 crash - contract 的 `input_schema.required[]` 必須與 main.go 的驗證邏輯一致 --- ## 問題回報 開 Issue:[github.com/arcrun/arcrun/issues](https://github.com/arcrun/arcrun/issues)