【免费下载链接】sdk-jsJavaScript and TypeScript SDK for building Astrid capsules.项目地址https://gitcode.com/gh_mirrors/sdkjs10/sdk-js点击查看免费下载本篇技术指南以 sdk-js 仓库的阶段验证笔记 notes/phase-3-install.md 为主体完整还原 Astrid JS/TS Capsule 从 TypeScript 源码一路编译为 wasip2 组件、打包成.capsule归档、经astrid capsule install安装到内核、并在 wasmtime 中执行astrid-install生命周期钩子的端到端链路。读完后你将掌握这条链路的每一步产物与数据形态、安装路径审计中的 7 项关键发现与修复、WIT 跨仓库分歧的产生机制与规避方法以及如何设计一轮安装 生命周期钩子的内核级冒烟测试。Phase 3 的验证目标与结论Phase 32026-05-15是一次针对安装路径install path与内核生命周期钩子lifecycle-hook的冒烟测试验证对象是上一阶段用 JS/TS 构建出的 Capsule 产物能否被 Astrid 内核真正加载并运行。最终判定为PASSEDinstall lifecycle-hook 路径同时明确标注了一处未覆盖工具调用的完整往返tool dispatch round-trip需要运行中的守护进程daemon来观察 KV 状态本次沙箱会话无法干净地启动长驻 daemon因此推迟到后续人工会话验证。Status: PASSED for the install lifecycle-hook path. Tool dispatch round-trip deferred (requires running daemon to observe KV state).这一结论的核心意义在于内核无法区分 Capsule 是由 Rust 还是 JS/TS 构建的——只要产物是合法的 wasip2 组件、携带正确的.capsule归档结构安装与生命周期调度对它一视同仁。这与 packages/astrid-sdk/README.md 中Same host ABI, same WIT contract, same.capsulearchive shape的定位完全一致。端到端流水线TS 源码如何变成内核可运行的组件文档记录了一条完整且可复现的流水线每一段的输入输出都有明确的产物与体积数据src/index.ts (TS, decorators) ↓ tsc → esbuild bundle → ComponentizeJS target/test-capsule.wasm (wasip2 component, 10.93 MB) ↓ pack_capsule_archive dist/test-capsule.capsule (3.5 MB gzip, Capsule.toml wasm wit/) ↓ astrid capsule install ~/.astrid/ ├── bin/89d628...d3d.wasm (BLAKE3 content-addressed) ├── wit/2618c7...554a.wit (BLAKE3 content-addressed) └── home/default/.local/capsules/test-capsule/ ├── Capsule.toml └── meta.json (records wasm wit hashes, version, timestamps) ↓ kernel lifecycle dispatch (during install) wasmtime::Component::from_binary OK all 11 host interfaces (49 fns) wired in linker astrid-install export called → bridge dispatched → user install ran → log.info OK各阶段的工程含义tsc → esbuild bundle → ComponentizeJS这是 packages/astrid-sdk 侧构建管线的核心。tsc负责类型检查与装饰器语法编译esbuild 负责把含astrid:*外部导入的多模块源码打成单一 ESM bundle外部导入保持external最后由 ComponentizeJS 以编程 API 将其包装为 wasip2 Component。构建产物体积 10.93 MB 是这一阶段的实际结果。pack_capsule_archive → .capsule归档里包含Capsule.toml清单、wasm 二进制与wit/接口目录gzip 后 3.5 MB。示例产物对应的清单见 examples/test-capsule/Capsule.toml其中[[component]]声明id test-capsule、file test-capsule.wasm、type executable。BLAKE3 内容寻址安装时内核用 BLAKE3 哈希为 wasm 与 wit 文件生成bin/、wit/下的存储名89d628...d3d.wasm、2618c7...554a.wit因此内容相同即去重、内容变更即产生新哈希天然支持多版本共存。meta.json记录 wasm 与 wit 的哈希、版本号与时间戳是安装目录的元数据事实源。内核生命周期调度安装过程即触发astrid-installexport 调用桥接层bridge派发到用户编写的install方法最终log.info成功输出——证明 JS 组件内的装饰器代码已在内核侧真实执行。安装目录结构说明内核把组件与运行时数据分开存放bin/与wit/是全局的、内容寻址的资产库home/default/.local/capsules/test-capsule/是每个 principal 下的实例目录保存该实例的清单与元数据。这种资产共享、实例隔离的布局决定了后续 KV 状态、升级版本等操作都围绕实例目录展开。内核日志证据生命周期钩子确实运行了文档给出了两条具体的内核日志这是整个冒烟测试通过的直接证据INFO astrid_capsule::engine::wasm: Running lifecycle hook capsuletest-capsule phaseInstall previous_version(none) INFO astrid_capsule::engine::wasm: Lifecycle hook completed successfully capsuletest-capsule phaseInstall第一条说明内核 wasm 引擎astrid_capsule::engine::wasm正在为test-capsule执行Install阶段的钩子且previous_version为(none)——首次安装语义。第二条确认钩子成功完成。这两行日志证明wasmtime 组件加载 → 11 个宿主接口 49 个函数全部接入 linker →astrid-install导出被调用 → JS 桥接层派发到装饰器方法的整条链路没有断点。安装路径审计7 项发现与修复文档针对安装命令实现core/crates/astrid-cli/src/commands/capsule/install.rs:548-580做了逐条审计这是本阶段最有工程价值的部分。审计表原文如下#FindingFix1Auto-build branch only triggered onCargo.toml— JS/TS source dirs would skip building and failReplaced withis_buildable_source(dir)helper that also detectsCapsule.toml package.jsonandopenclaw.plugin.json2Hardcoded--type rustarg passed to astrid-buildRemoved; astrid-builds owndetect_project_type(extended in Phase 1) handles all cases identically to the GitHub-clone path3GitHub-clone install path (line 442) — already correct, no--typepassedNo change needed4Wasm content-addressing (content_address_wasm)Readscomponent.pathfrom manifest; language-agnostic. OK.5Kernel loader (engine/wasm/mod.rs:776) usesComponent::from_binarywasip2 Component Model native. Works for any valid component. OK.6Empty WasiCtx (only stderr inherited)Fine — our JS components import zero WASI withdisableFeaturesfully on. OK.7wasm_exports_contain_runparses both core and component-model export sectionsAlready handled. OK.逐条展开is_buildable_source帮助函数修复项。原实现以Cargo.toml是否存在作为可构建源码目录的唯一判据这会把 JS/TS 目录误判为不可构建而直接跳过自动构建导致安装失败。修复后该帮助函数同时识别Capsule.toml package.jsonJS/TS 工程与openclaw.plugin.json覆盖了所有受支持的源码形态。JS 工程侧的对应证据就在 examples/test-capsule/package.json其build脚本为astrid-js-build . --out target/test-capsule.wasmdevDependencies包含unicity-astrid/build与typescript。移除硬编码的--type rust修复项。此前 install 命令在调用 astrid-build 时强制传入--type rust移除后统一交给 astrid-build 自身的detect_project_typePhase 1 已扩展与 GitHub-clone 安装路径行为完全一致。detect_project_type通过识别package.json Capsule.toml自动选择 JS/TS 构建链。GitHub-clone 安装路径无需修改。该路径install.rs 第 442 行附近本就未传--type是正确的参照实现故无需改动。BLAKE3 内容寻址确认 OK。content_address_wasm从清单读取component.path计算哈希与语言无关对 JS 构建的 wasm 同样适用。内核加载器确认 OK。engine/wasm/mod.rs:776使用wasmtime::Component::from_binary加载——这是 wasip2 Component Model 的原生加载路径任何合法组件都能通过不区分构建语言。空 WasiCtx确认 OK。内核只继承了 stderr其余 WASI 能力为空由于 JS 组件在构建时以disableFeatures全部关闭的方式声明了零 WASI 导入空 WasiCtx 不会造成任何影响。导出段解析确认 OK。wasm_exports_contain_run同时解析 core 段与 component-model 段的导出判断组件是否声明run导出JS 组件的导出形态已包含在既有处理中。这 7 项审计的核心方法值得借鉴针对新语言产物接入既有系统的改造应逐点核对构建触发条件、构建参数、内容寻址、加载器兼容性、运行时上下文与导出解析六个维度每一条都要给出修复或确认 OK的明确结论。跨仓库 WIT 分歧ipc-publish-as 缺失本阶段发现了一个典型的跨仓库契约漂移问题core/wit/astrid-capsule.wit内核侧落后于sdk-rust/astrid-sys/wit/astrid-capsule.wit一个宿主函数ipc-publish-as来自feat/ipc-publish-as分支的特性。SDK 的 WIT 声明了它而内核没有实现它。症状是 JS 构建的组件在实例化时报错component imports instance astrid:capsule/ipc0.1.0, but a matching implementation was not found in the linker文档明确解释了机制Wasmtime 的组件 linker 按整个 interface 匹配而不是按单个函数匹配。即使只缺一个宿主函数整个ipc接口的匹配也会失败——这是接口级匹配粒度带来的全有或全无语义。处理方式是双向对齐把 JS SDK 的 WIT 与 TS 代码对齐到内核当前状态——从src/ipc.ts中移除publishAs/publishJsonAs并在两个文件中留下内联 TODO 注释标记内核侧落地后的重新启用条件。后续工作不属于本次 PR是在内核侧core/wit/astrid-capsule.wit添加ipc_publish_as并在core/crates/astrid-capsule/src/engine/wasm/host/ipc.rs实现宿主函数从而自然重新启用 JS SDK 的增补。从当前仓库源码看这一契约的演进状态值得注意packages/astrid-sdk/src/ipc.ts 第 96-104 行仍保留着完整的publishAs/publishJsonAs实现其文档注释明确要求调用方在Capsule.toml [capabilities]中声明uplink true否则宿主返回capability-denied并且指出通过该路径发布的消息订阅方看到的 principal 归属是claimed(...)而非verified(...)下游消费者必须把它当作调用者输入而非已认证上下文。同时 packages/astrid-sdk/src/wit-imports.d.ts 第 140 行仍保留publishAs的宿主声明。这意味着只要宿主侧尚未实现ipc-publish-as任何声明该导入的组件在实例化时都会触发上文的 linker 报错——这也是安装路径冒烟测试必须让 WIT 与内核严格同步的根本原因。尚未验证的链路tool dispatch 与 KV 持久化文档明确划出了本次验证的边界安装触发的是astrid-install而其余钩子路径astrid-hook-trigger触发的tool_describe、tool_execute_increment等走的是同一条 wasmtime 代码路径只是 WIT 导出名不同——但这不等于已经观察到它们正确工作。尚未验证的具体内容包括tool_describe往返是否能产出符合预期的 schema 列表。tool_execute_increment往返桥接层状态加载 → 处理器执行 → 状态持久化 → IPC 发布到tool.v1.execute.increment.result的完整闭环。KV 状态跨调用持久化install 期间确实运行了桥接层的persistInstance调用但 daemon 默认写入临时内存 KV持久化的 SQLite/sled 后端只在astrid start的 daemon 模式下才挂载。文档给出了一套清晰的人工验证步骤运行astrid start启动 daemon通过 CLI 客户端发起/tool increment {}检查内核审计日志中出现tool_describe → tool_execute_increment → result publish序列并确认第二次/tool increment {}返回{counter: 2}从而证明状态已持久化。其中第二次调用返回{counter: 2}是状态持久化的关键判据。同样的限制适用于run可运行胶囊——run调用只有在存在 daemon 能派生后台任务时才真正有意义。这与 packages/astrid-sdk/src/runtime/bridge.ts 中的实现互相印证tool_execute_name派发对mutable: true的工具在调用前从 KV 加载__state、成功后持久化persistInstance写入的正是 KV 键__state第 38 行const STATE_KEY __state与 Rust SDK 完全一致。与原始计划的偏差文档记录了与原始计划的两处偏差都属于推迟而非取消schema 一致性测试被推迟。原计划 Phase 3 包含 Rust 与 TS 两个 test-capsule 之间的 schema 一致性测试解析各自tool_describe载荷并 diff schema。既然两条构建管线现在都已产出产物这个测试很容易补充被推荐为daemon 模式验证通过后的第一个后续任务。这与 packages/astrid-sdk/README.md 中Schemas may differ in subtle ways from Rustsschemarsoutput … monitored via a conformance test的表述一致。--no-install标志未加入。原计划要求 astrid-build 支持--no-install本次未添加因为当前仍无条件执行npm installworkspace 符号链接使其透明但对 air-gapped CI 场景仍有价值值得后续补充。Phase 3 改动文件与任务清单改动文件4 处文件改动core/crates/astrid-cli/src/commands/capsule/install.rs新增is_buildable_source帮助函数移除自动构建分支中仅针对 Cargo 的假设约 20 行sdk-js/packages/astrid-sdk/wit/astrid-capsule.wit即本仓库的 packages/astrid-sdk/wit-contracts/astrid-contracts.wit 同族契约替换为内核当前版本不含ipc-publish-assdk-js/packages/astrid-sdk/src/ipc.tspackages/astrid-sdk/src/ipc.ts移除publishAs/publishJsonAs导出留下带重新启用条件的 TODO 注释sdk-js/packages/astrid-sdk/src/wit-imports.d.tspackages/astrid-sdk/src/wit-imports.d.ts注释掉ipcPublishAs环境导出任务清单#28— 审计 install 路径中的 JS/TS 空白完成#29— 修复仅针对 Rust 的假设完成#30— 用 JS.capsule实测astrid capsule installPASSED#31— 内核加载冒烟测试PARTIALinstall astrid-install 已验证tool dispatch 推迟到 daemon 模式仓库源码纵深JS 侧如何响应内核的 astrid-install为了真正理解内核调用astrid-install导出在 JS 侧发生了什么可以直接看桥接层的实现。packages/astrid-sdk/src/runtime/bridge.ts 是核心它实现了 WIT 的四个 guest 导出astrid-hook-trigger、run、astrid-install、astrid-upgrade其astridInstall()第 314-324 行的逻辑是astridInstall(): void { try { const r reg(); if (r.installMethod undefined) return; const instance new r.ctor(); invoke(instance, r.installMethod, undefined); persistInstance(instance); } catch (e) { log.error(install hook failed: ${(e as Error).message ?? String(e)}); } }要点有三若注册表里没有install方法则静默返回install 钩子是可选的有则实例化胶囊类并调用该无参方法无论是否成功都会在成功路径上调用persistInstance(instance)——这正是文档所述install 运行了 bridge 的 persistInstance 调用的代码来源也是把实例字段状态写入 KV__state的地方。装饰器侧对应 packages/astrid-sdk/src/capsule.ts 的install第 39-48 行它在类初始化阶段把installMethod记录到注册表同时要求方法必须是字符串命名的公共实例方法install只接受无参签名。upgrade则接收prevVersion: string参数对应内核日志中的previous_version。一个可直接运行的最小示例在 examples/test-capsule/src/index.tscapsule类TestCapsule中install onInstall()输出test-capsule installedupgrade onUpgrade(prevVersion)输出升级前的版本号。二者都与桥接层行为一一对应。此外该文件还展示了toolincrement带{ mutable: true }、get_counter无状态、emit_event通过ipc.publishJson发布 WIT 类型事件、interceptor(test.v1.event)与hook(before_tool_call)的完整组合——这正是文档安装 生命周期钩子冒烟测试所覆盖的装饰器面。配套的单元验证在 packages/astrid-sdk/test/parity.test.mjs它用 esbuild 打包dist/产物并用宿主 mock 注入验证桥接派发行为包括hook 事件在 scoped topic 上回复、桥接派发保持 fail-open第 385 行以及装饰器拒绝符号命名处理器第 470 行等边界。关于 WIT 契约的同步机制scripts/sync-contracts-wit.sh 说明了为什么 WIT 分歧会真实发生SDK 的 WIT 契约文件wit-contracts/astrid-contracts.wit是从内核侧contracts/interfaces/*.wit打包拼接生成的派生产物而astrid:capsule0.1.0这类胶囊宿主契约见 scratch/phase0/wit-real/astrid-capsule.wit其中明确写着宿主暴露 49 个函数、横跨 11 个领域接口所有操作均能力门控并审计则由内核单独演进。两个契约若不同步更新就会产生本阶段的ipc-publish-as型分歧。脚本提供--check模式校验打包产物是否与源头同步是预防此类漂移的工程手段。结论与后续路线Phase 3 证明了JS/TS 构建的 Capsule 产物可以端到端安装并跑通内核生命周期钩子这是内核对构建语言无感知这一设计目标的关键里程碑。同时它也暴露了两类必须持续管理的工程问题契约同步问题WIT 按整个 interface 匹配的机制意味着宿主函数的增删必须与 SDK 声明严格同步任何单点漂移都会导致整个组件无法实例化验证深度问题安装路径的验证无法覆盖 KV 持久化与 tool dispatch 往返这两者依赖 daemon 模式的真实存储后端属于必须由人工会话在astrid start后执行的验证步骤。后续路线清晰先跑通 daemon 模式下的/tool increment状态持久化验证再补上 Rust/TS 两侧tool_describe的 schema 一致性测试最后为 astrid-build 增加--no-install以支撑 air-gapped CI。相关阶段笔记可从 notes/phase-0.md、notes/phase-1.md、notes/phase-2.md 与本文主体的 notes/phase-3-install.md 串成完整的技术演进脉络。赞分享【免费下载链接】sdk-jsJavaScript and TypeScript SDK for building Astrid capsules.项目地址https://gitcode.com/gh_mirrors/sdkjs10/sdk-js点击查看免费下载相关推荐AtomCode 终端界面使用大全30 斜杠命令与快捷键完整清单AtomCode 终端界面使用大全30 斜杠命令与快捷键完整清单 AtomCode 是一款用 Rust 构建的开源终端 AI 编程助手Claude Cod人工智能AI Agent代码智能体自主智能体MCP ClientsCLIKubernetes The Hard Way 冒烟测试验证 Secret 静态加密、Deployment 与 NodePort 服务链路Kubernetes The Hard Way 冒烟测试验证 Secret 静态加密、Deployment 与 NodePort 服务链路 在 Kuberne教程云原生Mastra Tools 冒烟测试指南从 Studio 页面到 /api/tools 执行链路的完整验证Mastra Tools 冒烟测试指南从 Studio 页面到 /api/tools 执行链路的完整验证 导读 Tools工具是 Mastra 中 Age人工智能Agent 框架AI AgentRAG后端上一篇LightX2V终极指南如何快速将想法变成视频的AI魔法下一篇ResNet50.tv2_in1k实战教程3步实现图像分类与特征提取创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考