sdk-js README

The project's README from github.com/astrid-runtime/sdk-js. As one markdown file: README.md.

sdk-js

License: MIT OR Apache-2.0 Node: >=20 TypeScript: 5.2+

The JavaScript / TypeScript SDK for building Astrid capsules.

Companion to sdk-rust. Same WIT contract, same wasip2 Component Model output, same .capsule archive format — your kernel can't tell which language built the binary. Where the Rust SDK feels like writing against std, this one uses node:fs/promises, node:child_process, WHATWG fetch, async iterators, and disposable resource handles. Same host ABI, idiom translated.

Packages

Package Role
@astrid-runtime/sdk The capsule author API. Module-by-module mirror of astrid-sdk's prelude — fs, net, process, env, time, log, plus Astrid-specific ipc, kv, http, hooks, uplink, identity, approval, runtime, elicit, capabilities, interceptors. TypeScript decorators (@capsule, @tool, @interceptor, @hook, @command, @install, @upgrade, @run) replace Rust attributes.
@astrid-runtime/build Build orchestrator. Runs tsc + esbuild + ComponentizeJS programmatic API. Emits a wasm32-wasip2 component that the Rust-side astrid-build packs into a .capsule archive.
@astrid-runtime/sdk/contracts Auto-generated TS types from astrid-contracts.wit — IPC event types (Message, ToolCall, GenerateRequest, StreamEvent, etc.) usable on both ends of cross-capsule IPC.

Quick start

mkdir my-capsule && cd my-capsule
npm init -y
npm install @astrid-runtime/sdk
npm install --save-dev @astrid-runtime/build typescript

Capsule.toml:

[package]
name = "my-capsule"
version = "0.1.0"

[[component]]
id = "my-capsule"
file = "my-capsule.wasm"
type = "executable"

[capabilities]
kv = ["*"]

[publish]
"tool.v1.execute.*" = { wit = "opaque" }

src/index.ts:

import { capsule, tool, install, log, kv } from "@astrid-runtime/sdk";

@capsule
export class MyCapsule {
  greetings = 0;

  @tool("greet", { mutable: true })
  greet({ name }: { name: string }): { message: string; count: number } {
    this.greetings++;
    log.info(`greeting ${name} (#${this.greetings})`);
    return { message: `Hello, ${name}!`, count: this.greetings };
  }

  @install
  onInstall(): void {
    log.info("my-capsule installed");
  }
}

Build:

astrid build           # or: astrid capsule install .

That's it. tsc compiles your TypeScript, esbuild bundles in the SDK, ComponentizeJS produces a wasip2 component, the Rust-side astrid-build packs it into dist/my-capsule.capsule.

Building capsules

End-to-end pipeline:

src/*.ts
   ↓  tsc (typecheck + emit dist/*.js)
   ↓  esbuild (bundle dist/ + @astrid-runtime/sdk into one ESM, mark astrid:* WIT specifiers external)
   ↓  ComponentizeJS programmatic API (StarlingMonkey + your bundle → wasip2 Component)
target/<name>.wasm
   ↓  pack_capsule_archive (Rust side)
dist/<name>.capsule (Capsule.toml + .wasm + wit/, gzipped tar)

tsc and esbuild run from @astrid-runtime/build/src/index.mjs — a small Node CLI invoked by Rust's astrid build when it detects a package.json + Capsule.toml project.

Trade-off: binary size

JS capsules cost ~11 MB raw (3.5 MB gzipped in the .capsule archive). That's the StarlingMonkey embed. Rust capsules are ~200 KB. Acceptable for daemon-mode workloads (capsules load once); if size matters more than ergonomics, write Rust.

The host ABI is identical, so a hot capsule can be ported between languages without kernel changes.

Repository layout

sdk-js/
├── packages/
│   ├── astrid-sdk/        @astrid-runtime/sdk — public API
│   ├── astrid-build/      @astrid-runtime/build — build orchestrator
│   └── ...
├── examples/
│   └── test-capsule/      Minimal end-to-end example mirroring sdk-rust/examples/test-capsule
├── notes/                 Phase-by-phase development notes (Phase 0–3)
├── package.json           npm workspace root
└── tsconfig.base.json

Development

npm install
npm --workspace @astrid-runtime/sdk run build
node packages/astrid-build/src/index.mjs examples/test-capsule

Or, from a kernel checkout with the JS dispatch wired into astrid-build:

cd core
cargo build -p astrid-build
./target/debug/astrid-build ../sdk-js/examples/test-capsule

Status

Alpha. The vertical slice (TypeScript → wasip2 component → .capsule → installed by astrid capsule install → kernel lifecycle hook execution) is proven end-to-end. Daemon-mode tool-dispatch round-trip (/tool greet { "name": "world" }) is on the same code path as install — same wasmtime instantiation, same linker contract — and ready for human-operator smoke testing.

See notes/phase-{0,1,2,3-install}.md for development history, design decisions, and known follow-ups.

License

Dual-licensed under MIT and Apache 2.0.

Copyright (c) 2025-2026 Joshua J. Bouw and Unicity Labs.

sdk-js (astrid-runtime/sdk-js)

Searching Database…

8.1K ·GitHub
这是什么?这是用于构建 'Astrid capsules' 的 JavaScript/TypeScript SDK。它会把你的 TS 代码编译成 wasm32-wasip2 组件,打包成 .capsule 归档文件,并由 Astrid 内核运行。它是 Rust SDK(sdk-rust)的 JavaScript 语言版本,面向相同的宿主 ABI。
这是一个独立应用还是一套工具?这是一套由三个 npm 包组成的工具:@astrid-runtime/sdk(带装饰器的 capsule 作者 API)、@astrid-runtime/build(tsc + esbuild + ComponentizeJS 的构建编排器),以及 @astrid-runtime/sdk/contracts(根据 WIT 合约自动生成的 IPC 类型)。
我该如何用这个 SDK 构建 capsule?添加 Capsule.toml 和 src/index.ts,然后运行构建脚本:tsc 编译你的 TypeScript,esbuild 打包进 SDK,ComponentizeJS 将其转为 wasip2 组件,最后由 Rust 端的 astrid-build 将其打包成 dist/my-capsule.capsule 归档文件。
还需要 Rust 工具链吗,还是纯 Node 就行?tsc、esbuild 和 ComponentizeJS 需要 Node.js 20 或更高版本,但最后的打包步骤仍依赖 Rust 端的 astrid-build 工具。当检测到 package.json 和 Capsule.toml 时,会自动调用它。
和使用 Rust SDK 相比,有什么不足之处?JS capsule 体积大得多:由于内置了 StarlingMonkey JS 引擎,原始大小约 11 MB(.capsule 归档中压缩后约 3.5 MB),而 Rust capsule 约为 200 KB。对于只需加载一次的守护进程模式工作负载,这样的体积可以接受,但在选择 JS 而非 Rust 之前需要了解这一点。
这个东西现在能用于生产环境了吗?还不能,它明确处于 Alpha 阶段。从 TypeScript 到 wasip2 组件、再到 .capsule 和内核生命周期钩子的安装流程,已经可以端到端运行。但守护进程模式下的工具分发才刚刚可以供人工操作员进行冒烟测试。
@astrid-runtime/sdk 包里到底有什么?它镜像了 Rust 的 prelude(fs、net、process、env、time、log),并增加了 Astrid 专属模块,如 ipc、kv、http、hooks、uplink、identity、approval、runtime、elicit、capabilities 和 interceptors。这些功能通过 @capsule、@tool、@hook、@command、@install、@upgrade 和 @run 等装饰器提供。
以后能在 Rust 和 JS SDK 之间移植 capsule 吗?可以。两个 SDK 共享相同的宿主 ABI 和链接器合约,因此 capsule 可以从 JS 迁移到 Rust(反之亦然),无需修改内核。
配套的 @astrid-runtime/build 包到底做什么?它是构建编排器:先运行 tsc 和 esbuild,然后调用 ComponentizeJS 的编程接口,生成 wasm32-wasip2 组件,并将其打包为最终的 .capsule 归档文件。
什么是 .capsule 归档?它是打包好的 wasm32-wasip2 组件格式。Astrid 内核通过 `astrid capsule install` 安装它,运行时通过 IPC 处理生命周期钩子,以及 Message、ToolCall、GenerateRequest 等工具分发请求。
Size
0.5 MB
Stars
8.1K
Age
5mo
Commits · 90 Days