A backend-portable planner for WebAssembly Component deployment on edge devices, in MoonBit
weft:织造时横向穿过的纬线。清单里的 wires 就是纬线——本项目把它们织成一份计划。
| 使用方式 | 入口与状态 |
|---|---|
| 源码构建 | 下方快速开始,固定工具链安装见 构建说明 |
| Windows/Linux 预构建规划 CLI | Actions 成功运行内的 weft-cli 制品;下载解包与校验见 构建说明,正式 Release 待 M6 |
| Mooncakes 库 | 已发布 soehi/weft@0.3.0,依赖固定为0.3.0;独立注册表消费者已复验 |
| 本地库消费者 | examples/consumer,通过本地workspace引入,不能替代注册表安装验证 |
| 浏览器本地演示 | demo,用户组件留在本机内存 |
| Linux 可选执行 | 执行说明,独立实验命令;通用 weft run 仍未支持 |
git clone https://github.com/soehi/weft.git
cd weft
python scripts/install-toolchain.py --destination _build/toolchains/pinnedexport MOON_HOME="$PWD/_build/toolchains/pinned"
export PATH="$MOON_HOME/bin:$PATH"
moon update
moon check src/api src/cli --target js
python3 scripts/check-release-inputs.py$env:MOON_HOME = Join-Path (Get-Location) '_build/toolchains/pinned'
$env:PATH = (Join-Path $env:MOON_HOME 'bin') + ';' + $env:PATH
moon update
moon check src/api src/cli --target js
python scripts/check-release-inputs.pymoon run src/cli --target js -- plan examples/chain.json --out plan.json
# 类型错误,应失败并指出source.read/sink.in的签名不匹配
moon run src/cli --target js -- plan examples/type-mismatch.json
# 浏览器:打开 http://127.0.0.1:8000,选择成功链或类型错误示例
node scripts/build-demo.mjs
python scripts/serve-demo.py| 项目 | 它做什么 | weft 不做什么 |
|---|---|---|
| wasm-compose (Rust) | 构建时静态合成,产物是一个 .wasm | 不生成合成产物 |
| wasmCloud (CNCF) | 分布式集群编排,依赖 NATS/lattice/k8s | 不做网络、不做分布式 |
| moonrockz/wac + wasm-devkit | WAC/WIT 语言工具链 | 不重写语言工具,消费它 |
| wasmoon | 组件运行时 | 不做执行引擎,执行层依赖它 |
| moonkoog | LLM Agent 编排 | 完全不碰 LLM/Agent |
| golemcloud/golem_sdk | 云端 durable agent 平台 | 不做云端平台 |
# 生成示例组件(从 WAT 汇编成真实组件二进制)
moon run src/tools/make_fixtures --target native -- examples
# 生成计划
moon run src/cli --target native -- plan examples/chain.json
# 同样的命令,换后端,输出逐字节相同
moon run src/cli --target js -- plan examples/chain.json{
"version": "0.1.0",
"components": [
{ "name": "reader", "path": "reader.wasm" },
{ "name": "filter", "path": "filter.wasm" },
{ "name": "sink", "path": "sink.wasm" }
],
"wires": [
{ "from": "reader.read", "to": "filter.in" },
{ "from": "filter.out", "to": "sink.in" }
],
"resources": { "max_memory_pages": 256, "quota": 1000000 }
}{"plan_version":"0.2.0",
"instances":[
{"name":"reader","path":"reader.wasm","order":0,"incoming":[]},
{"name":"filter","path":"filter.wasm","order":1,"incoming":[1]},
{"name":"sink","path":"sink.wasm","order":2,"incoming":[0]}],
"wires":[
{"from":"filter.out","to":"sink.in","from_signature":"(i32) -> (i32)","to_signature":"(i32) -> (i32)"},
{"from":"reader.read","to":"filter.in","from_signature":"(i32) -> (i32)","to_signature":"(i32) -> (i32)"}],
"resources":{"max_memory_pages":256,"quota":1000000},
"plan_hash":"1a3640bcc99318d5"}| 命令 | 作用 | 后端 |
|---|---|---|
| weft plan <manifest> [--out <file>] | 校验清单与组件二进制,输出确定性计划 JSON | native / wasm-gc / js |
| weft emit-wac <manifest> [--out <file>] | 把清单渲染成 WAC,交给外部工具链 | 全部 |
| weft convert <file.wac> --dep <ns:name>[@version]=<path>... [--out <file>] | WAC 组合 → 本工具的清单格式 | 全部 |
| weft run <manifest> | 预留命令,明确报未支持并退出 1 | 全部 |
$ weft plan cycle.json
error: plan: dependency cycle: filter -> reader -> filter # 退出码 1
$ weft plan bad.json
error: plan: `sink` has no port `missing` # 退出码 1
$ weft plan missing.wasm.json
error: cannot read component `reader` from /path/to/reader.wasm: No such file or directoryweft/
├── src/
│ ├── manifest/ 声明式清单:解析 + 校验(纯逻辑,三后端)
│ ├── ir/ 组件二进制 → 干净的接口/类型表(唯一解码点)
│ ├── plan/ ★ 规划器:图构建、环检测、拓扑排序、canonical 签名检查、JSON + hash
│ ├── wac_adapter/ WAC ↔ 清单 双向转换
│ ├── exec_plan/ 计划 → 执行轨迹(纯逻辑,三后端可测)
│ ├── cli/ CLI(三后端可编译)
│ ├── runtime_native/ ★ native-only 实验执行命令(Linux 验证)
│ ├── runtime_probe/ Linux 两组件真实连线执行探针
│ └── tools/ 开发者工具(生成示例组件)
├── examples/
├── docs/
└── .github/workflows/ci.ymlmoon test src/manifest src/ir src/plan src/wac_adapter src/exec_plan src/cli --target native
moon test src/manifest src/ir src/plan src/wac_adapter src/exec_plan src/cli --target wasm-gc
moon test src/manifest src/ir src/plan src/wac_adapter src/exec_plan src/cli --target js| 包 | 测试数 | 覆盖 |
|---|---|---|
| manifest | 25 | 合法/非法 JSON、缺字段、重复组件、端口路径、负数/小数配额、版本 |
| ir | 7 | 函数/接口导入导出、富类型、canonical 展开、排序、解码失败命名 |
| plan | 64 | 线性链、菱形、宽扇出、成环(自环/多节点)、未知组件/端口、签名不匹配、接口路径、资源、hash 敏感性、21 节点扇入、黄金字节、语义结构匹配、相同 ABI 反例、未支持类型、重复绑定与 import 覆盖 |
| wac_adapter | 18 | WAC→清单、Access→wire、缺依赖、往返、名称消毒 |
| exec_plan | 5 | 两阶段顺序、轨迹确定性、终点调用、空计划 |
| api | 7 | 内存输入、稳定诊断、缺字节、解码、类型/绑定与环 |
| cli | 5 | 严格参数解析、版本与路径保留 |
bash scripts/check-backends.sh
# Windows PowerShell(需要 moon、node):
pwsh -NoProfile -File scripts/check-backends.ps1
# 故意失败的隔离夹具:验证两个入口均失败并保留原始诊断(另需 Bash、pwsh)
node scripts/test-gate.mjs本项目只能宣称"编排策略",不能宣称"隔离保证"。"This project is primarily developed with AI assistance and has not been thoroughly audited. Do not use in production or security-sensitive environments."
moon run src/runtime_native --target native -- run examples/execution/chain.json --component consumer --export run --arg u32:41Install
Download zipA backend-portable planner for WebAssembly Component deployment on edge devices, in MoonBit