Added
-
Rust SDK behavioral parity with JavaScript-native APIs. Added semantic lifecycle hooks through
@hook, thehooksmodule, andHookEvent;astrid:http@1.1.0request controls and metadata;astrid:process@1.1.0read-only child file injection; and schema-versioned KV reads/migrations. The canonical surface is idiomatic JavaScript:http.fetch()returns a genuine WHATWGResponse, the Rust-style fluent form is explicitly namedRequestBuilder,process.spawn()returns aChildProcesswhilespawnSync()captures output, KV results narrow on a camelCasekind, and hook events exposepayload/canReply. -
SDK parity regression tests. Host-mocked Node tests verify exact WIT record encoding, response metadata, process injection placement, versioned KV migration, and fail-open scoped hook replies.
-
capabilities.enumerate— list the calling capsule's own held capability names. Mirrors the Rust SDK'scapabilities::enumerate. The list dual ofcapabilities.check: returns the capability categories declared in this capsule's[capabilities]manifest block (host_process,net_connect,fs_read, …) — the names, not the scoped arguments within them (allowlists,host:port, paths). Argument-free (the kernel already knows the caller) and infallible — an empty array is the valid "no capabilities" answer — so a reusable capsule can ground its behaviour in what it can actually do instead of hard-coding it, avoiding code-vs-manifest drift. Backed by astrid-runtime/wit#13'sastrid:sys/host.enumerate-capabilities; contracts submodule bumped accordingly (theastrid:contractsevents bundle is unchanged). -
processpersistent-process tier —spawnPersistent,PersistentProcess, andprocess.{attach, listProcesses, statusMany}. Mirrors the Rust SDK and the hostastrid:process@1.1.0persistent tier: a background child that outlives the pooled, stateless instance that started it (unlikeBackgroundProcessHandle, whose kernel resource is reaped on instance reset).spawnPersistent(cmd, args, options)takes the persistent knobs (label,keepStdinOpen,overflow,logRingBytes,maxLifetimeMs,idleTimeoutMs,exitRetentionMs,limits) and returns aPersistentProcesskeyed by an opaque id.PersistentProcessexposesstatus/readLogs(drain) /readSince(non-draining cursor → byte-faithfulLogChunkResult; start withlogCursorStart()) /writeStdin/closeStdin/signal/wait(bounded) /stop(SIGTERM→grace→SIGKILL, frees the slot) /release. Persistproc.id(e.g. in KV) andprocess.attach(id)from a later invocation to reattach —attachis a thin id-wrapper, so it works without the host's deferredattachresource fn; the first id-keyed call validates ownership.process.listProcesses/statusManyenumerate the capsule+principal's persistent processes. New types:PersistentProcessInfo,SpawnPersistentOptions,LogChunkResult,ResourceLimits,ProcessPhase,LogStream,LogCursor,OverflowPolicy;ProcessSignalgains"stop"/"cont". The host'swatch/unwatchlifecycle-event channel and resource-limit enforcement are not yet wired (poll viastatus+ boundedwait). The persistent surface originated in astrid-runtime/wit#12 and now lives in the additive@1.1.0package alongside file injection.
Changed
- npm scope migration. The packages now publish as
@astrid-runtime/sdkand@astrid-runtime/build. The former@unicity-astrid/*packages remain at 0.1.0 only and will be deprecated on npm after the new packages are published. - JavaScript standard-library makeover. HTTP ABI conversion is no longer exposed on request objects; WHATWG request input, body consumption, abort, cloning, headers, and URL behavior are preserved.
env.get()now distinguishes a missing key withundefined;fsgained Node-compatible recursive options, aliases, file-handle method names, overloads, and realDirentpredicates;time.sleep()supplies the promise-shaped timer path. Resource constructors are private and public declarations define language-native types instead of importing generatedastrid:*host-binding modules. Deprecated aliases retain straightforward source migration where their semantics are not misleading. - Intentional API breaks before stabilization.
process.spawn()now has Node background semantics (usespawnSync()for the previous captured behavior), process signals use Node names such asSIGTERM,fs.open()uses familiarr/r+/w/aflags,UplinkIdis an opaque string rather than a Rust-style wrapper object, and versioned KV discriminants changed fromstatus: "needs-migration" | "not-found"tokind: "needsMigration" | "notFound". The misleading HTTPRequest/Responsebuilder aliases were removed in favor ofRequestBuilder/BufferedResponse;installGlobalFetch()replaces the old polyfill-named installer. - The build world now imports
astrid:http/host@1.1.0andastrid:process/host@1.1.0, and stages each WIT package version in a separate dependency directory so frozen 1.0 and 1.1 contracts can coexist. - Canonical IPC contract types were regenerated from the same WIT revision used by current Rust SDK main, including the additive session-management records.
Security
- Upgraded the build toolchain to patched
componentize-jsandesbuildlines, pinned the compatible audit-clean JCO release, and added a required dependency-audit CI job. This removes the vulnerableweval → decompressarchive-extraction chain and the affected esbuild development-server version from both the workspace and downstream@astrid-runtime/buildinstallations.
With many thanks from the following Astrinauts 🚀
- Joshua J. Bouw