Files
Arcrun/registry/scripts/register-component.sh
T
Leo 497f92a268 feat(arcrun): recipe system + resumable workflow + component registry canon
Three new platform capabilities + one component (kbdb_get) to enable
real AI workflow execution through cypher binding YAML.

## Recipe System (容器 + Recipe 模式)
SDD: .agents/specs/recipe-system/

- prompt_recipe schema (Zod): fragments + inputs + assembly + output
- recipe-expander.ts: expand recipe ref → real prompt by fetching KBDB blocks
  + pulling context fields with transforms (pluck_content / extract_field / etc)
- 7 transform whitelist: json_array / to_string / join / markdown_list /
  extract_field / first / pluck_content
- graph-executor hooks: detect node.data.recipe → expand → inject into ctx
- output JSON parser (with markdown fence stripping for Claude-wrapped JSON)
- Stored in RECIPES KV under prompt_recipe:{name}

## Resumable Workflow (webhook callback resume)
SDD: .agents/specs/resumable-workflow/

- WorkflowPaused class + paused-runs.ts (persist/load/consume in EXEC_CONTEXT KV, 24h TTL)
- graph-executor: detect {pending:true, task_id} → persist state → throw WorkflowPaused
- cypher-handlers: catch → return {success:true, paused:true, task_id, run_id}
- POST /workflows/resume route: consume KV state → resumeFromPaused()
- Auto-inject callback_url for claude_api nodes (PUBLIC_BASE_URL or default cypher.arcrun.dev)
- claude_api/main.go: forward callback_url to Mira daemon, default timeout 25s→120s
- Idempotent (consume = load+delete)

## Component Registry Canon
SDD: .agents/specs/component-registry-canon/

- Add POST /components/index-only endpoint (metadata-only, no wasm/sandbox)
- Backfill script (mjs): scan registry/components/*/contract.yaml → submit to KV
- register-component.sh: SSOT for local + CI hook (deploy.yml change in next commit)
- Drop R2 dead storage from submitComponent + types + wrangler
- Schema relaxed: category enum + auth/ai/platform; cold_start 50→500ms; size 2→8MB

## kbdb_get component
- registry/components/kbdb_get/: TinyGo WASM, two modes (block_id / page_name list)
- .component-builds/kbdb_get/: WASI shim worker (kbdb-get.arcrun.dev)

End-to-end validation: AI uses MCP execute_workflow with recipe ref →
cypher-executor expands prompt from KBDB schema/skill blocks + drafts →
claude_api calls Mira daemon → daemon callback fires resume route →
workflow continues. Verified with real 2KB+ Karpathy LLM Wiki draft.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 15:52:19 +08:00

61 lines
1.7 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# 單一 component 註冊到 registry index
# SDD: matrix/arcrun/.agents/specs/component-registry-canon/design.md Phase 2
#
# 用法:
# bash scripts/register-component.sh <component_name>
# REGISTRY_URL=https://registry.arcrun.dev bash scripts/register-component.sh kbdb_ingest
#
# CI deploy 流程內也使用同樣邏輯(見 .github/workflows/deploy.yml 的 Register step
# 此 script 是「本地 / hook 一致性」的 SSOTCI 改邏輯時 script 跟著改
set -uo pipefail
REGISTRY_URL="${REGISTRY_URL:-https://registry.arcrun.dev}"
COMPONENT_NAME="${1:-}"
if [[ -z "$COMPONENT_NAME" ]]; then
echo "Usage: $0 <component_name>" >&2
exit 1
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
COMPONENT_DIR="$SCRIPT_DIR/../components/$COMPONENT_NAME"
CONTRACT="$COMPONENT_DIR/component.contract.yaml"
if [[ ! -f "$CONTRACT" ]]; then
echo "::warning::no component.contract.yaml at $COMPONENT_DIR" >&2
exit 0
fi
python3 -c "import yaml" 2>/dev/null || {
echo "需要 python3 + pyyaml" >&2
exit 1
}
contract_json=$(python3 -c "
import yaml, json
with open('$CONTRACT') as f:
c = yaml.safe_load(f)
print(json.dumps({'contract': c}))
") || {
echo "::warning::無法解析 $CONTRACT" >&2
exit 0
}
echo "Registering $COMPONENT_NAME to $REGISTRY_URL ..."
http_code=$(curl -s -o /tmp/reg-response.json -w "%{http_code}" \
-X POST "$REGISTRY_URL/components/index-only" \
-H "Content-Type: application/json" \
-d "$contract_json")
if [[ "$http_code" =~ ^(200|201)$ ]]; then
echo "✓ $COMPONENT_NAME registered (HTTP $http_code)"
cat /tmp/reg-response.json
echo
else
echo "::warning::Registry 註冊失敗 HTTP $http_code" >&2
cat /tmp/reg-response.json || true
exit 1
fi