> ## Documentation Index
> Fetch the complete documentation index at: https://smithers.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# 0.34.0

> Smithers 0.34.0 adds live workflow supervision: steer a running agent, hijack its session, and watch the whole graph from a terminal cockpit. Plus one file-change contract across every CLI harness with live diffs in the run UI, per-run token usage, durable agent checkpoints, the Nanocodex backend, fallbackAgents subscription-pool failover, and a UI theme registry.

**Smithers 0.34.0 puts you in the cockpit of a running workflow.** Mirror a
run into a [herdr](https://herdr.sh) terminal workspace and supervise it from
the same terminal as your coding agent: a pane per agent node, a cockpit
outline of the whole graph, and a dual-control dock that lets you steer a
running agent with one keystroke or hijack its session and drive it yourself.
Smithers keeps owning execution, isolation, and durability; herdr only renders
and relays, and everything degrades to a silent no-op when no herdr server is
running.

**0.34.0 also makes agent edits legible.** Every CLI harness reported file
edits differently, so the run UI could only show a flat "Edited src/foo.ts"
note. Agents now normalize a file-mutating tool call into one
`AgentFileChange` shape, the node chat stream renders each confirmed change as
an expandable diff, and the Diff tab works while the run is still executing
instead of only after it finishes.

The rest of the release is volume: 254 commits since 0.33.0, 97 of them fixes
for the places daily production use exposed cracks, notably resuming and
retrying runs, agent fallback chains, steer delivery, Gateway workflow-UI
discovery, and a run status that stops overstating how healthy a run is.
(0.33.1 was tagged but never published to npm; everything it contained ships
here.)

Disk use is now bounded and inspectable end to end. Active detached logs cap
themselves at 100 MiB with a preserved tail and truncation notice, while the
new `bunx smthrs gc` reports filesystem capacity and reclaims terminal-run
logs (including workflow-adjacent legacy logs), sandbox roots, and worktrees
behind age and ownership guards. Legacy
hidden campaign worktrees and known temp scratch shapes are surfaced but need
an explicit `--include-unmanaged`; live process directories and unpublished
worktree changes remain protected.

## Upgrading

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
bunx smthrs update        # upgrade the CLI
bunx smthrs upgrade       # agent-assisted: applies what your project needs
bunx smthrs packs update  # refresh installed workflow packs
```

Behavior changes are collected in the [upgrade notes](#upgrade-notes).

## Live workflow supervision: steer, hijack, and a terminal cockpit

A long-running workflow used to be observable but not steerable: you could
watch the logs, or kill the run. 0.34.0 adds a supervision layer with three
levels of control.

**Steer.** `bunx smthrs steer RUN_ID "focus on the failing test first"` queues
a durable instruction that lands as a user turn at the target node's next
agent step; the run never stops. `--node` picks a specific node (the default
is the run's current agent node), bare `bunx smthrs steer` auto-picks the
single active run, and delivery is tracked through `SteerQueued` and
`SteerConsumed` events with expiry at terminal states. Steers survive
restarts because they live in the store (`_smithers_steers`), not in process
memory.

**Take over.** `bunx smthrs steer --takeover` parks the run resumably and
hands you the agent's live session to drive yourself. It is run-wide, so it
warns and asks before aborting in-flight sibling agents.

**Cockpit.** `bunx smthrs supervisor` (alias `top`) opens a live outline of
phases and agents: j/k to select, Enter to open a node detail tab (in herdr
when available), an approve/deny surface for a waiting gate, and `[` `]` to
switch runs. It sources through the workspace Gateway by default and silently
falls back to direct `smithers.db` reads when none is reachable.

With a [herdr](https://herdr.sh) terminal server running, `bunx smthrs herdr
attach` mirrors the run into a terminal workspace: a workspace per run, a
cockpit tab, and a tab or pane per agent node with attention promotion and
terminal outcome markers. `bunx smthrs herdr status|attach|open|clean` manage
the mirror. The client speaks herdr wire protocol 19 (herdr 0.8.0); a protocol
mismatch fails closed before any mutating call, and the optional mirror paths
degrade to silent no-ops, so a missing or older herdr never affects the run
itself.

Reasoning effort is now first class along the way: it is derived at spawn,
persisted per attempt (`_smithers_attempts.effort`), and rendered on both the
direct-db and gateway display paths.

## Agent file edits are one contract, and the UI renders them as diffs

A CLI agent subclass may now implement `parseFileChanges`, which normalizes a
`file_change` action into `AgentFileChange` records. The same normalization
runs live inside `createOutputInterpreter`, which attaches the result to the
streamed action as `detail.fileChanges`.

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
type AgentFileChange = {
  path: string;
  kind: "created" | "modified" | "deleted" | "renamed";
  oldPath?: string;                     // set when kind is "renamed"
  unifiedDiff?: string;                 // full patch, when the harness allows one
  source: "reported" | "reconstructed"; // vendor-supplied, or built from tool input
};
```

Claude Code and Kimi carry before and after text, so their edits reconstruct a
real unified diff. Codex, OpenCode, Cursor, and Amp report paths and kinds
only. Each engine declares what it can do in
`AgentCapabilityRegistry.fileChanges` (`supportsFileChanges` and
`supportsUnifiedDiff`); the per-engine table is in the
[agents reference](/reference/agents#file-change-parsing).

In the node chat stream that means:

* A change with a diff is an expandable row that opens the hunks inline.
* A paths-only change renders as a plain row labelled `diff unavailable`
  rather than a focusable button that does nothing when you click it.
* A started edit stays hidden until the tool result confirms it, so a denied
  or failed edit no longer looks applied.
* Claude's `Write` reconstructs a full-creation diff only once the result
  confirms the file was new. Over an existing file it stays paths-only
  instead of fabricating an empty old side, and `NotebookEdit` reconstructs
  inserts only.
* Kimi's `WriteFile` keeps its file-change kind through tool-result
  completion, so the pending change finalizes instead of collapsing into a
  generic tool row.

Recorded CLI transcripts for Claude Code, Codex, and OpenCode are checked in
as fixtures and replayed through the real adapters in tests, from raw wire
lines all the way to finalized chat items, so a vendor stream-shape change
breaks a test instead of a UI.

## Diffs while the run is still executing

`getRunDiff` and `getNodeDiff` refused until a run reached a terminal status,
so the Diff tab stayed empty for exactly as long as you cared about it. While
a run is live, both now diff the run base against the current working copy of
every checkout an attempt recorded, read-only, never cached, under the same
50MB oversized cap that produces `DiffTooLarge`. The bundle is flagged
`live: true` and surfaces as a `(live)` marker in the summary. The terminal
base-to-terminal diff stays the authoritative final snapshot.

The oneshot Diff tab and the TUI tree-mode diff tab refresh off run events
with a trailing debounce, because agent edits arrive in bursts, and take one
final refetch on the terminal transition. A refresh no longer flickers the
existing diff out for a spinner.

## One account's rate limit no longer stalls a run

The new `fallbackAgents()` turns the account registry into a ready-made
failover chain: one agent rung per registered Claude Code or Codex
subscription, shuffled per call so load spreads across seats, with your normal
agent appended as the last rung. On a machine with no registered seats it
returns just that agent, so single-account setups behave exactly as before.

```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { fallbackAgents } from "smthrs";

// One rung per registered Claude/Codex seat, stable order for this run,
// a stock Claude Code agent as the final rung.
const agent = fallbackAgents({ seed: ctx.runId });
```

Seed the shuffle with `ctx.runId` and a run keeps the same chain across every
render and retry, which keeps the engine's per-rung quota skipping precise,
while different runs still start from different seats. `providers: "all"`
extends the pool to Kimi, Antigravity, and raw API-key accounts, and
`models`/`agentOptions` apply per-provider overrides without ever letting a
rung be repointed at another subscription.

Oneshot builds the same shape from the same registry, in registration order
rather than shuffled: `bunx smthrs agents add` regenerates `.smithers/agents.ts`
so every usable registered account is its own chain rung inside its engine's
pool, and the run walks those rungs before it moves on to the next engine.
Adding a second registration for a subscription you already registered is
called out at add time now, because a duplicate seat adds no capacity, only
confusion; the check compares within one provider, so a Claude seat and a
Codex seat that happen to share a sign-in email stay separate rungs with
separate rate limits.

## Register every subscription you own, browser login included

`bunx smthrs agents add --tmux` handles the providers that only offer a
browser login. It launches the provider CLI in a detached tmux session with
the account's config dir set (Claude Code via `claude auth login --claudeai`,
skipping REPL onboarding), prints the attach command so you can complete the
login in the browser, polls until the credentials land, and registers the
seat. Re-running after a timeout detects already-finished credentials and just
registers. The interactive `agents add` wizard offers the same flow whenever
tmux is available.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
bunx smthrs agents add            # wizard; offers the tmux flow when available
bunx smthrs agents add --tmux     # detached tmux browser login, then register
```

`agents add` also records who was signed in, and `agents list` shows that
account identity next to each label, so two labels backed by the same
subscription (and therefore the same rate limit) are visible at a glance
instead of looking like extra capacity. Registered agent ids are stable now:
`registeredAgentId`/`registeredAgentLabel` live in `@smthrs/accounts` as the
canonical home, and the CLI and runtime helpers stamp identical account-backed
ids.

## Subscription headroom across every registered seat

The new private `apps/quota-dashboard` workspace app is a compact Electrobun
desktop view over the real `bunx smthrs usage --format json` output. It charts the
weekly and session headroom for every registered Claude Code and Codex seat,
sorts the pool by available capacity, and puts expired or broken sessions first
so the account to re-authenticate is obvious.

`agents list --format json` now includes each seat's non-secret `signedInAs`
identity, which lets the dashboard pair a quota window with the subscription
behind a local label. The compiled `.app` bundle stays ignored; only the source,
configuration, and both refreshed lockfiles are committed.

## ForkFanOut: end-of-run chores on a fork of the finished session

`<ForkFanOut>` fans independent chores out over forks of one task's final
agent session. Every entry waits for the source task, starts from a copy of
its conversation snapshot in a fresh session (the source is never mutated),
and runs its own prompt. It is built for the end of a run: linters, named
commits, memory writes, and logging that need full context of the work just
done without depending on each other.

```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
<ForkFanOut
  fork="implement"
  agent={chores}
  tasks={[
    { id: "lint", prompt: "Run the linters and fix what they flag." },
    { id: "memory", prompt: "Record what this run learned to memory." },
  ]}
/>
```

Entries accept per-task `agent`/`output`/`label` overrides over the
component-level defaults, an allowlisted set of `Task` props passes through,
and duplicate ids or a missing `agent`/`output`/`fork` fail at render time
instead of mid-run. Details are in the
[ForkFanOut reference](/components/fork-fan-out).

## Resume and retry work again

`retry-task` ran the engine in the foreground with no detach, so a closed
pipe (SIGPIPE) killed the run and orphaned its agent children. The invocation
is now detached ([#1481](https://github.com/smithersai/smithers/issues/1481)).

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
bunx smthrs retry-task RUN_ID TASK_ID   # survives the launching terminal closing
bunx smthrs up --resume RUN_ID          # no workflow path needed anymore
```

* An approved detached run with a null `workflowHash` can resume again
  ([#1489](https://github.com/smithersai/smithers/issues/1489)).
* `up --resume RUN_ID` no longer demands a workflow path, matching its help
  text: the run's stored workflow is relaunched
  ([#1475](https://github.com/smithersai/smithers/issues/1475)).

## Fallback chains recover instead of failing the run

A session-loss error from a provider (including Kimi's "session is broken"
banner) defeated the agent fallback chain: it silently skipped its Codex
leads instead of retrying or falling through. A mixed-reason chain failure
hard-failed the run instead of parking it.

* Session-loss errors are now classified, so the chain retries or falls
  through to the next seat
  ([#1480](https://github.com/smithersai/smithers/issues/1480)).
* A mixed agent-chain failure parks the run as `waiting-quota` with preflight
  context attached, resuming when capacity returns
  ([#1482](https://github.com/smithersai/smithers/issues/1482)).
* Codex preflight accepts valid ChatGPT auth even when `auth.json` also
  contains an `OPENAI_API_KEY`
  ([#1447](https://github.com/smithersai/smithers/issues/1447)).
* Both behaviors are pinned by new quota-chain-failover and
  session-loss-chain-failover e2e suites.

## The Gateway finds your UI, and stays responsive while it does

`bunx smthrs ui` could fail three ways. The Gateway never registered workflows
launched by explicit path outside `.smithers`
([#1474](https://github.com/smithersai/smithers/issues/1474)). Registration
rendered every workflow synchronously, pegging the event loop so `/health`
went unreachable for minutes (`GATEWAY_UNREACHABLE`). And a custom-path
`<UI path="/custom">` could 404 until background discovery reached it.

All three are fixed: explicit-path workflows register, `<UI>`/`<TUI>`
discovery is queued and drains one render per macrotask so `/health` answers
throughout, and an unmatched UI request drains pending discovery once before
resolving the mount.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
bunx smthrs up ./anywhere/my-workflow.tsx -d
bunx smthrs ui RUN_ID    # now finds the <UI> declaration
```

<Frame caption="The Monitor overview starts at All clear, a release-canary run is launched live, its running status pill appears in the sidebar, and the run detail shows the Healthy banner while the execution tree ticks through preflight, build, tests, and report to end on Completed with 4/4 tasks done.">
  <img src="https://mintcdn.com/smithers/iU_GYsGHIj1wyQTE/images/0.33.1/monitor-live.gif?s=44eca3470fc35c175e19aff82eba1521" alt="The Smithers Monitor following a live release-canary run from launch to completed" width="1200" height="750" data-path="images/0.33.1/monitor-live.gif" />
</Frame>

<Frame caption="Touring the finished run: the Completed banner, per-node durations, the node inspector with transcript and output, the Timeline, Debug, Frames, and XML views with a frame scrubber, and the Notable, All, and Activity event tabs.">
  <img src="https://mintcdn.com/smithers/iU_GYsGHIj1wyQTE/images/0.33.1/monitor-tour.gif?s=193bf0cd9fa7f9c8b394352ca4126067" alt="Inspecting a completed run in the Monitor across its inspector, timeline, and XML views" width="1100" height="688" data-path="images/0.33.1/monitor-tour.gif" />
</Frame>

## A finished run tells the truth, and no agent outlives its engine

Three ways a run could look healthier than it was ([#1464](https://github.com/smithersai/smithers/issues/1464)).

A `<Loop>` or `<ReviewLoop>` that exits through the default
`onMaxReached: "return-last"` with its `until` predicate still false never
converged, yet the run reported `done`. The scheduler now records the loop as
exhausted (persisted on `_smithers_ralph.exhausted`, migration 0035), the
finished `RunResult` and the `RunFinished` event carry `exhaustedLoops`, and
the CLI stops calling it success:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
bunx smthrs status RUN_ID   # verdict: degraded, naming the loop that never converged
bunx smthrs why RUN_ID      # names the loop and its unmet until condition
```

A killed engine could still read `running-healthy`. When the full liveness
probe failed, `status`, `ps`, and `inspect` fell back to a path that ignored
the heartbeat entirely. The fallback now classifies from the run row alone
using `heartbeat_at_ms` and `runtime_owner_id`, and a continued run whose
segment never finished is treated as running so its stale heartbeat downgrades
the verdict instead of resolving to succeeded.

Agent subprocesses no longer survive their engine
([#1332](https://github.com/smithersai/smithers/issues/1332)). Agent CLIs spawn
detached as their own process-group leaders, the engine registers every agent
pid in `_smithers_agent_processes` (migration 0036), and any CLI invocation
sweeps that registry and group-kills entries whose engine is verifiably gone,
taking subagents, MCP servers, and tool children with it. `cancel` and `down`
sweep the runs they fence. Set `SMITHERS_NO_ORPHAN_REAPER=1` to opt out of the
boot sweep.

## ctx.outputs stops returning a plausible empty array

The callable form `ctx.outputs(outputs.probe)` silently returned `[]` because
it indexed the snapshot with the raw argument. It now resolves through the
same table-ref resolution as every other accessor, and an argument that
resolves to no declared output table throws
([#1486](https://github.com/smithersai/smithers/issues/1486)).

```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
const rows = ctx.outputs(outputs.probe); // real rows; an unresolvable ref now throws
```

* Regression tests pin the callable form to the same rows as the string name.

## upgrade-dependents: open rename PRs downstream

The 0.33.0 rename left dependent repos importing a package that will never
see another release. The new `upgrade-dependents` pack workflow discovers
open-source dependents (awesome-smithers, GitHub code search, and any
`extraRepos` you pass), then runs one lane per repo: an agent clones,
upgrades to `smthrs`, and must prove `git grep` returns zero hits before an
independent reviewer re-checks the diff and a draft PR is opened.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
bunx smthrs up upgrade-dependents
```

## Per-run token usage in one query

"How many tokens did this run spend" used to mean replaying the event log and
parsing `TokenUsageReported` payloads out of JSON. The engine now persists a
usage row per attempt (`_smithers_run_usage`, keyed by run, node, iteration,
and attempt) alongside each usage event it already emits, on both success and
failure paths. `bunx smthrs usage --run RUN_ID` prints the total, and
`SmithersDb.getRunTokenUsage(runId)` is a single SUM. Rows are upserts keyed
by attempt identity, so a provider that re-reports a cumulative running total
replaces its row instead of inflating the total, while genuine retries stay
separate attempts.

## Durable agent checkpoints

Agents can now declare `checkpointCapabilities` and persist a final
`AgentCheckpoint` per attempt. `<Task id={B} fork={A}>` starts `B` from a copy
of `A`'s final checkpoint when the target declares an exact codec, version,
and `"fork"` match, and falls back to the source attempt's recorded forkable
conversation messages otherwise. Forking never mutates the source: multiple
tasks can fork the same source, and a forked task can itself be forked.

## Nanocodex: a pinned-source sandboxed agent backend

`NanocodexAgent` connects Smithers to the external
[`smithers-nanocodex`](https://github.com/N0xMare/smithers-nanocodex) bridge:
a pinned stock Nanocodex agent run as a short-lived, checkpoint-aware worker
inside a Bubblewrap sandbox. The v0.0.1 integration is deliberately fixed
(one fresh `serve` worker and one stock Nanocodex turn per `generate()` call,
no daemon or worker pool) and fails closed when the sandbox requirements are
not met. Linux x64 only; see the
[Nanocodex integration page](/integrations/nanocodex) for the requirements.

## A theme registry for the UI kit

`@smthrs/ui-styleguide` now ships a generated theme registry with eight
palettes: Catppuccin, Fucory, GitHub, Gruvbox, Night Owl (new in this
release), One, Rosé Pine, and Solarized. A generator script keeps every
palette's light and dark variants, contrast ratios, and CSS custom properties
in sync, so run UIs built on `smthrs/ui` pick up a coherent theme with one
setting.

## stereOS in the browser, and three new sites

* [custom-sandbox.smithers.sh](https://custom-sandbox.smithers.sh), published at
  the time as `stereos.smithers.sh`, ran the stereOS demo entirely in your
  browser inside a WebContainer, so the sandbox-provider demo needed no local
  checkout.
* [patterns.smithers.sh](https://patterns.smithers.sh) is a field guide to
  orchestration patterns.
* [research.smithers.sh](https://research.smithers.sh) hosts the
  persuasion-gap paper.
* [status.smithers.sh](https://status.smithers.sh) gained Smithers Code and
  Smithers Cloud API components, each verified live before listing, and a
  missing feed now answers a real 404 instead of an HTML page labelled as
  status.

## Other improvements

* The bug-triage-train workflow ships in the pack with a live UI: file a
  batch of bug reports through triage, reproduction, and fix lanes.
* `CodexAgent` emits `--sandbox workspace-write` now that codex-cli 0.147
  removed `--full-auto`, so full-auto-configured workflows keep launching on
  current codex installs.
* Queued steers expire inside the terminal cancel transaction, and steer
  enqueue is fenced against terminal runs, so an instruction can no longer
  land on a run that is already ending.
* Detached built-in runs resume correctly after approval decisions.
* A Codex agent configured through the array form keeps its reasoning effort
  instead of silently dropping it.
* `bunx smthrs tail --format jsonl` emits raw event JSON per line and nothing
  else, so scripted consumers stop parsing banner noise.
* `bunx smthrs bug --run RUN_ID` attaches the run's lifecycle events instead
  of a \~25 second window of TaskHeartbeat noise, and generates a correct
  report title ([#1484](https://github.com/smithersai/smithers/issues/1484)).
* Panel moderators inside a Ralph loop no longer deadlock over Ralph's
  iteration-suffixed dependency names
  ([#1487](https://github.com/smithersai/smithers/issues/1487)).
* `bunx smthrs hijack` re-emits the agent's launch flags. `--resume` restores
  conversation state only, so a hijacked session lost the model, permission
  mode, and config dir the workflow agent ran with. Those are recorded on the
  hand-off now and replayed onto the CLI invocation.
* `reconstructUnifiedDiff` bounds its LCS grid by bytes instead of cells. The
  old `n * m` cell guard allocated one typed array per old line, so a lopsided
  payload passed the check and still allocated about a gigabyte; one flat
  `Uint32Array` makes the cell bound a real byte bound.
* The live node diff path enforces the payload cap it previously bypassed, so
  an oversized working-copy diff raises `DiffTooLarge` instead of serializing
  uncapped.
* The gateway UI keys its live diff refresh on the last event's seq rather
  than the event ring's length, which stops changing once the 200-event ring
  fills and froze the live diff on long runs.
* The review workflow UI renders reviewer feedback, synthesis, and issue
  descriptions as formatted Markdown through the shared Markdown primitive
  instead of one raw paragraph, and a mid-run rejection no longer shows a
  final `Blocked` badge next to `RUNNING`: verdicts only go final once the run
  is terminal.
* `EmptyState` and `SectionHeader` accept element titles again. Both extended
  `ComponentProps<"div">`, whose intrinsic `title?: string` intersected with
  their own `title?: ReactNode` slot and collapsed it to `string & ReactNode`.
* `scheduler` and `devtools` re-emitted their stale committed declarations from
  `tsup --dts-only`, which made `check:dts` false-green on type changes. Both
  configs now clean the emitted `index.d.ts` first.
* Hermes and OpenClaw are listed in the README harness table and the npm
  package description alongside the other CLI harnesses.
* The detached launch admission wait is configurable, and a live engine child
  is no longer killed at the deadline. `bunx smthrs up -d` waited a fixed 30
  seconds for the engine child to prove it persisted the run row, which a
  heavily loaded machine can miss on module parse alone; the launcher then
  terminated the healthy child and reported an empty log. A child that is
  still alive at the deadline now gets a grace window of four times the
  timeout, with a progress note on stderr, and the final failure names the
  live pid instead of "(empty)". Set `SMITHERS_DETACHED_ADMISSION_TIMEOUT_MS`
  to raise or lower the base window. The default is still 30 seconds, and a
  value below 1000ms falls back to it.
* The Trellis benchmark lab pin now carries the validated v2 authoring ladder:
  kit-only scripts, static validation, fuel accounting, evidence-bound
  settlement, mission CLI, and hardened batched ARC evaluation planning. It is
  internal benchmarking infrastructure, not part of any published package.
* Test scratch directories now go through a tracked cleanup helper, preventing
  abandoned SQLite, PGlite, sandbox, and workflow workspaces from accumulating
  under `$TMPDIR` after suites finish or throw.
* The TUI node inspector's empty Logs tab again renders the parenthesized
  `(no log events for this node)` placeholder, with a headless regression test
  that runs even when the optional zmux PTY suite is unavailable.
* Claude Code OAuth credentials stored in the macOS Keychain are found
  everywhere they matter. `bunx smthrs usage` and the agent availability probe
  now read the per-config-dir Keychain item for isolated accounts
  (`Claude Code-credentials-<hash of the config dir>`), with no fallback to
  the default install's item, so a validly logged-in account stops reporting
  `NO_USABLE_AGENTS` when the `claude auth status` probe times out, and one
  account's token is never attributed to another.
* `<Task fork>` authored inside a Subflow or Sandbox child workflow keeps its
  fork edge; the dom extraction variant used for child workflows dropped the
  prop and the fork was silently lost.
* Asking oneshot for a codex agent while the codex-paused marker is set now
  names the pause itself, its until/reason, and how to clear it
  (`SMITHERS_CODEX_PAUSED=0` or delete the marker) instead of the generic
  "not enough availability signals" that pointed at healthy auth.
* effect and the `@effect/*` packages are aligned at 4.0.0-beta.105. Keeping
  the family on one beta prevents npm from satisfying caret peer ranges with
  multiple effect runtimes in an end-user install.
* The `smthrs` umbrella is guarded against type-vs-runtime export drift: a
  new test imports every documented agent export and asserts it exists at
  runtime, the exact shape of the bug where `fallbackAgents` typechecked but
  threw "Export named 'fallbackAgents' not found" on import. The facade's
  committed `index.d.ts` was regenerated against the release base.
* The gateway PTY resize test polls for the new terminal geometry instead of
  reading it once after a fixed half-second sleep, so a loaded CI runner no
  longer reds the `packages/server` shard over a resize frame that merely
  arrived late.

## Upgrade notes

* No breaking changes at runtime. All 0.33.0 rename guidance still applies.
* If a package manifest overrides Effect prereleases, update the whole
  `effect` and `@effect/*` family to beta.105 together.
* `AgentCapabilityRegistry` gains a `fileChanges: { supportsFileChanges,
  supportsUnifiedDiff }` field. Registries are normalized with both flags
  `false` when absent, so existing agents keep working; a custom agent typed
  against the exported TypeScript type needs the field added.
* `getRunDiff` and `getNodeDiff` return a diff for a non-terminal run now
  instead of refusing. Bundles computed from a live working copy carry
  `live: true`; treat the terminal bundle as the authoritative snapshot.
* A mixed agent-chain failure now parks the run as `waiting-quota` instead of
  failing it. Check `bunx smthrs ps` for parked runs before concluding a run
  died.
* `bunx smthrs up --resume RUN_ID` without a workflow path is now valid; the
  stored workflow is relaunched.
* This release adds several store migrations: the `_smithers_attempts.effort`
  column, the `_smithers_steers` table, `_smithers_ralph.exhausted`, the
  `_smithers_agent_processes` table, agent checkpoints, the
  `_smithers_run_usage` table, and the Herdr supervision tables. They apply on
  first open, so no manual step is needed, but an older CLI pointed at a
  migrated database will not read the new columns.
* The herdr client pins wire protocol 19 (herdr 0.8.0). Explicit `bunx smthrs
  herdr` commands against another protocol fail closed with
  `HERDR_PROTOCOL_MISMATCH` before any mutating call; the optional mirror
  paths log and continue. herdr remains fully optional.
* `CodexAgent` maps full-auto to `--sandbox workspace-write` instead of the
  removed `--full-auto` flag. codex-cli releases that predate `--sandbox`
  need an upgrade before Codex tasks will launch.
* 0.33.1 was tagged but never published to npm. If you tracked its changelog,
  every entry ships in 0.34.0; there is no npm artifact to migrate through.
* `bunx smthrs status` can now return the verdict `degraded` for a finished
  run whose loop never satisfied its `until` condition. The run row `status`
  stays `finished` and `RunState` stays `succeeded`, so scripts that key off
  the run status are unaffected; scripts that assert `verdict === "done"`
  should accept `degraded` or treat it as the non-convergence signal it is.
* Every CLI invocation now sweeps `_smithers_agent_processes` and group-kills
  agent processes whose engine is gone. Set `SMITHERS_NO_ORPHAN_REAPER=1` if
  you deliberately keep agent processes alive past their engine.

## The full changelog

254 commits since 0.33.0, plus this changelog update, touching 901 files:
127,655 insertions, 6,718 deletions. Much of that insertion count is
regenerated `llms-*.txt` docs bundles; excluding those, the lockfiles, and
declaration bundles it is 839 files, 91,632 insertions, 3,524 deletions. The
complete commit-level list is in
[CHANGELOG.md](https://github.com/smithersai/smithers/blob/main/CHANGELOG.md).

Hit a bug? `bunx smthrs bug` files a report in seconds, and `--run RUN_ID`
attaches the run's events for you.
