> ## 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.35.0

> Smithers 0.35.0 makes a run recoverable and a store multi-tenant: bounded terminal task repair, transactional subtree cancellation down to process trees, first-class (owner, app) run ownership, workflows callable as agent tools, declarative GitHub listeners, a Grok provider, an embeddable Node engine, and a bounded control-plane database.

**Smithers 0.35.0 is about what happens when things go wrong.** Retry was the
only recovery primitive, so a terminal failure meant hand-authoring a repair
workflow. A task can now declare `repair`: on terminal failure it receives the
terminal error, the attempt history, and the worktree context, with a bounded
budget and a `TASK_REPAIR_FAILED` terminal state. It is deliberately neither a
fallback (which would substitute a different result) nor an escalation (which
would move the failure elsewhere), because a recovery primitive that hides the
failure is worse than none.

**Cancellation now reaches all the way down.** `cancelRun` cascades the whole
descendant subtree as one transition: a cycle- and depth-guarded descendant
CTE, single-winner CAS so concurrent cancellers cannot half-apply, and a
transactional continue-as-new fence. Detached owners and agent process trees
are terminated through the driver's existing `killProcessTree`, so no work
outlives the subtree that owned it, and the response reports every run the
cascade reached with its depth and action.

**The store is multi-tenant.** Runs carry a persisted, indexed `(owner, app)`
pair. Enforcement is real isolation at the Gateway boundary, and a foreign run
id answers `RunNotFound` rather than a permission error, so ownership cannot be
probed by id. Child, continue-as-new, and fork runs inherit; legacy rows stay
unowned and keep shared behavior.

The rest is volume: 127 commits since 0.34.0, 68 of them fixes. (0.33.0 and
0.34.0 were tagged but never published to npm; everything they contained ships
here.)

## 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). This
release has more of them than usual, and two will turn a previously silent
condition into a hard error.

## Workflows are callable agent tools

Pass a workflow to an agent as a tool. The schema is derived from the
workflow's Zod `inputSchema`, and a schema-less workflow gets a strict empty
object rather than a permissive one, so an agent cannot invent arguments.

Calls are not a side channel: they run as real child runs through the existing
`executeChildWorkflow` machinery, carrying `parentRunId` lineage and a
`startedBy` harness of `smithers-workflow-tool`, so a tool-invoked run is as
visible and attributable as any other. A child that parks on an approval,
event, or timer returns `WORKFLOW_TOOL_SUSPENDED` instead of blocking, depth is
bounded by a durable counter, and per-attempt serialization preserves the
parent's concurrency slot.

## Declarative external-event listeners

A registry file declares which GitHub issue and pull-request events start which
workflows, and Smithers registers, reconciles, and deregisters the real
webhooks to match. A pure planner produces an inspectable plan before anything
is mutated, `smithers listeners` drives it from the CLI, and the Gateway grows a
`github-source` webhook branch.

Ownership state is written `0600` via atomic rename and holds only a sha256
digest of the secret. No secret or token reaches plans, state, errors, or logs.

## Grok (xAI) is a supported provider

`GrokAgent` runs through `BaseCliAgent` like the other CLI providers, with
accounts (`bunx smthrs agents add`), quota-aware ordering in `fallbackAgents()` so
a rate-limited account sinks rather than blocking, and dead-session
classification so a stale Grok session cannot burn a retry budget.

xAI exposes no live usage endpoint. `bunx smthrs usage` says exactly that rather
than inventing an estimate.

## The engine embeds in plain Node

`packages/smithers/src/external` exposes a reusable engine instance usable
without bun: PGlite by default (or real Postgres via `connectionString`,
`connection`, `SMITHERS_POSTGRES_URL`, or `DATABASE_URL`), a host-supplied
logger, one instance running many runs, and `error.cause` preserved across the
tagged-error boundary. Capabilities that genuinely do not exist off-bun fail
with named errors rather than degrading silently: Node SQLite raises
`DB_REQUIRES_BUN_SQLITE`, and PTY stays a Gateway/UI capability.

## The control-plane database is bounded

A 100 GB `smithers.db` was possible because nothing ever reclaimed anything.
`smithers gc` now compacts duplicate snapshot rows (behavior-preserving,
resumable, batched) and can delete history for terminal runs older than a
window, protecting lineage and live runs. `--dry-run` reports what each would
reclaim.

Retention is **opt-in** behind `--db-retention-days` or
`SMITHERS_DB_RETENTION_DAYS`, because an upgrade must never silently delete run
history. Compaction and retention free pages for reuse inside the file; they do
not shrink it on disk, and Smithers never VACUUMs a live database.

## The monitor is a product surface

The monitor now composes from the shared UI design system end to end: runs
overview and rail with intentional density, an execution tree with legible
node kinds, iteration and attempt/retry metadata, failure counts on collapsed
ancestors and auto-expansion of paths needing attention, complete keyboard
navigation with APG tree semantics, and loading, empty, error, and offline
states that do not look broken. Verified across both themes and mobile,
tablet, and desktop widths.

## Fixes worth calling out

* **A failed run launch could lose a delivery permanently.** The integration
  delivery hook ran *after* completion, and claim release only rewinds pending
  rows, so a failure marked the delivery complete and every provider
  redelivery was deduped away. The workflow start vanished with no error.
* **Stale resume pointers poisoned every retry.** Resume ids persisted on
  failed and cancelled attempts, so the next attempt resumed a conversation
  that no longer existed and died immediately, burning a retry without doing
  work. Pointers from unsuccessful attempts are now ignored at resolution
  (which repairs existing rows) and cleared at terminal transition.
* **CI shard 3 wedged on SQLite.** `createSmithers` had no reachable `close()`,
  so callers could never release a handle and one test process peaked at 189
  open databases. A tracked-fixture teardown brings that to 53.
* **Trusted-proxy auth honoured an app header outside its allow-list.** A proxy
  that never stripped `x-app-id` could be used to claim a different app's half
  of the tenant key.
* **Isolated clones were not byte-faithful.** `createIsolatedClone` inherited
  the host's `core.autocrlf`, so on Windows a patch or bundle produced from a
  capsule reported every text file as wholly changed.
* **A degraded run looked identical to a clean one.** A run whose children
  failed under `continueOnFail` now reports a distinct
  `succeeded-with-failures` state while keeping the `finished` lifecycle status,
  so terminal polling is unchanged.

## Upgrade notes

* **CLI agent constructors reject unknown options.** A mistyped adapter option
  used to be ignored silently, forever. It is now a `TypeError`. This will
  surface real typos in existing code as hard failures.
* **`@modelcontextprotocol/sdk` is an optional peer you install explicitly.**
  It was a hard dependency in every install. The MCP toolset lazy-loads it and
  fails with an install hint if absent.
* **Lifecycle children share the parent's concurrency budget.** A parent capped
  at N previously bounded only its own tasks, so a subtree could run
  arbitrarily wide. Workflows relying on that will now run subtrees more
  slowly. Runs linked only by `parentRunId` stay detached and independent.
* **`SMITHERS_HOME` inheritance is split.** Ordinary workflows inherit it;
  `inherit: false` and `clone.run` scrub it unless supplied explicitly.
* **`Task.repair` and `continueOnFail` are mutually exclusive**, rejected at
  graph-extraction time rather than resolved by precedence at runtime.
* **A fresh `bunx smthrs init` no longer ships the docs-driven-development
  workflow and starter spec.** They are opt-in; the docs describe how to add
  them.
* **The Gateway requires a trusted-proxy peer boundary** before honouring
  identity headers.
* **Migration 0044** adds the run ownership columns and index.
