CJackHwang/Succinix--packages-engine5

@succinix/engine

Succinix engine as a dsh-compatible Cordis plugin: a Unix-like sandbox (real Node runtime + Lifo userland) inside a WebContainer, exposed through ctx.fs, ctx.sandbox, ctx.terminals and ctx.sessionPersistence.

包名
@succinix/engine
版本
0.7.0
许可证
MIT
最近更新
2026年8月18日

安装

此插件尚未提供可验证的 bundle,或兼容性检查未通过。请先阅读仓库说明。 阅读完整 README ↗

@succinix/engine

Succinix engine as a dsh-compatible Cordis plugin: a Unix-like sandbox that runs inside a WebContainer and shares the container's filesystem with your app. It provides a real Node runtime (node, npm, npx), a built-in Pyodide Python (python, pip), and a Lifo Unix userland for everything else.

This is the 0.7.0 single-track plugin form. It is built for @deepseek-ai/cordis@4.0.1 and exposes the dsh service keys ctx.fs, ctx.sandbox, ctx.terminals, and ctx.sessionPersistence. The old 0.4.0 standalone SDK exports and the 0.5.0 single-key succinix service are removed; see the migration guide: docs/MIGRATION.md.

Install

npm install @succinix/engine
npm install @deepseek-ai/cordis @webcontainer/api   # peer dependencies

Quick start

import { Context } from '@deepseek-ai/cordis';
import engine from '@succinix/engine';
import { WebContainer } from '@webcontainer/api';

const ctx = new Context();
const fiber = ctx.plugin(engine, {
  container: { mode: 'external' },
  defaultInstance: {
    instanceId: 'default',
    persistence: { dbName: 'my-app', storeKey: 'default' },
  },
});
await fiber;

const wc = await WebContainer.boot();
const host = ctx.get('succinix', false)!;
await host.attach(wc);
await host.ensureInstance('default', { executor: {} });

const node = await host.executor.exec('node -e "console.log(1+1)"');
const lifo = await host.executor.exec('grep -i foo file.txt');

await host.shutdown();
await fiber.dispose();

The plugin registers itself as succinix and provides four dsh services. Consumers declare inject: ['fs', 'sandbox', 'terminals', 'sessionPersistence'] or use ctx.get('fs', false).

Service surface

dsh services

KeyPurpose
ctx.fsdsh FileSystem: 12 primitives, 13 FS_* codes, sandboxMode
ctx.sandboxSynchronous confine(argv, policy); Lifo wrappers, real Node fail-closed
ctx.terminalsOwner-scoped PTY registry (spawn, startSend, read, signal, kill, list)
ctx.sessionPersistenceAppend-only event log stored as JSONL under the instance state root

Import the published types from @succinix/engine:

import {
  FsError,
  SandboxUnavailableError,
  TerminalError,
  SessionId,
  type FileSystem,
  type SandboxProvider,
  type TerminalSessionService,
  type SessionPersistence,
} from '@succinix/engine';

Host seam

succinix is the lifecycle and app-observability service. It is not a dsh service key; trusted consumers probe it with ctx.get('succinix', false).

MemberPurpose
statePlugin state, host, instances, capabilities, configRevision
containerCurrent container handle (internal / external, wc, host)
fs / sandbox / terminals / sessionPersistenceThe four dsh services
executorDefault-instance executor: exec, spawn, listProcesses, kill, ping, respawn
terminalterminal.create(output) for a UI-free terminal session
snapshot / persist / workspaceSnapshot save/restore, persistence, workspace facade
portsPage-level port view and server-ready / server-closed subscriptions
servicesDeclarative background services
capabilitiesterminal.*, fs.*, workspace.* capability registry
instanceDefault SuccinixInstance or null
boot / attachInternal boot or external container adoption
ensureInstanceCreate/reuse a per-instance stack on the shared host
dispose / shutdownSoft fiber teardown / hard host shutdown
reconfigureApply a new validated configuration

Container modes

  • Internal: const wc = await host.boot();
  • External: await host.attach(wc); when your app owns the WebContainer. The plugin still injects and spawns the host daemon.

attach() and boot() are mutually exclusive; switching modes throws ERR_MODE_MISMATCH.

Lifecycle

The page-level HostManager survives fiber reloads. dispose() is soft by default; shutdown() flushes instances, kills the host, and clears page registries. Set lifecycle.disposeMode: 'hard' if fiber dispose must also shut the host down.

Assets

The package ships assets/host.js, assets/lifo-core.js, assets/pyodide/*, and assets/sha256.json. Copy them to your static directory or import them with Vite:

import hostJsUrl from '@succinix/engine/host.js?url';
import lifoCoreUrl from '@succinix/engine/lifo-core.js?url';

Asset SHA-256 verification is on by default.

Requirements

  • Chromium only; WebContainers does not support Firefox, Safari, or mobile.
  • Cross-origin isolation is required (COOP: same-origin and COEP: credentialless).
  • Ports are virtual previews; there is no real inbound network.

Documentation