# Core

> Runtime-agnostic engine for Taskbox: runTask, workspace, event bus, errors.

Source: https://taskbox.n.yatsyk.com/docs/core

# @taskbox/core

The runtime-agnostic engine. `runTask` validates a `TaskSpec`, mints a
disposable workspace under `os.tmpdir()/taskbox-runs/<taskId>`, hands control
to a `RuntimeAdapter` (e.g. [`@taskbox/podman`](/docs/podman)), and parses the
adapter's `result.json` back into a typed `TaskResult`. All lifecycle events
flow through an `EventBus` that simultaneously appends to `events.jsonl` and
fans out to subscribers.

* **Stability:** beta
* **Platforms:** node

## Install

```bash
npm i @taskbox/core @taskbox/schemas
```

You also need a runtime adapter — for now that's [`@taskbox/podman`](/docs/podman).

## Run a task

```ts
import { runTask } from "@taskbox/core";
import { podman } from "@taskbox/podman";

const result = await runTask(
  {
    tool: "media.downloadSubtitles",
    input: { url: "https://youtu.be/jNQXAC9IVRw", languages: ["en"] },
    network: { mode: "direct" },
  },
  podman({ pullPolicy: "if-missing" }),
  { onEvent: (e) => console.log(e.type) },
);

if (!result.ok) throw new Error(result.error?.code);
```

## Subscribe to events without driving a task

```ts
import { createWorkspace, EventBus } from "@taskbox/core";

const ws = createWorkspace();
const bus = new EventBus(ws.eventsJsonlPath);

bus.on((e) => console.log(e.type, e.ts));

for await (const ev of bus) {
  if (ev.type === "task.completed" || ev.type === "task.failed") break;
}
```

See [API](./api.mdx) for the full export list.
