Mysten Incubation
Internals

Lifecycle

How the current runtime boots and stops a stack.

defineDevstack(...) is synchronous. It builds a static stack handle and performs composition-time checks. The runtime path starts when a surface consumes that handle.

Runtime surfaces:

  • devstack up starts a supervisor and stays attached.
  • devstack apply publishes apply.requested to the live supervisor when this stack is already attached; otherwise it starts the same supervisor path in one-shot mode.
  • runStack(stack, opts) embeds the supervisor in another TypeScript program.
import { Effect } from 'effect';
import { account, defineDevstack, runStack, sui } from '@mysten-incubation/devstack';

const stack = defineDevstack({ members: [sui(), account('alice')], stackName: 'embedded' });
const handle = runStack(stack, {
	runtimeRoot: '.devstack',
	identity: { app: 'demo', stack: 'embedded' },
});

await Effect.runPromise(handle.start);
await Effect.runPromise(handle.stop);
await Effect.runPromise(handle.awaitShutdown);

Boot order is derived from dependsOn edges. Members that need Sui depend on the shared sui resource, so the stack includes one concrete sui(...) provider. wallet({ accounts: 'all' }) is expanded after the full member list is known, so it depends on every account member in the final stack.

The supervisor claims roster.json while attached, publishes typed events, maintains a live projection, writes the manifest, emits generated files, and serves commands from the attached TUI and filesystem command channel. Shutdown is attached to the running process: quit the TUI or interrupt devstack up, then scope finalizers run and the roster claim is released.