Skip to content

🐛 fix(cli): tail events watch from current cursor#1356

Draft
roninjin10 wants to merge 11 commits into
mainfrom
fix/microsandbox-followups-20260719
Draft

🐛 fix(cli): tail events watch from current cursor#1356
roninjin10 wants to merge 11 commits into
mainfrom
fix/microsandbox-followups-20260719

Conversation

@roninjin10

@roninjin10 roninjin10 commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Important

This draft is stacked on the task-specified local-main base e9bf4c5668. Origin main is currently ten commits behind that base, so GitHub temporarily displays those base commits/files in this PR. Once e9bf4c5668 lands on origin main, this comparison narrows automatically to commit 583b6a01f4 and the three CLI files below. The branch was not rebased because the task explicitly required that base, and no extra base branch was pushed.

Summary

  • make smithers events --watch snapshot the durable current event cursor and tail only newly appended events by default
  • preserve --since history windows
  • add --replay-history for explicit full matching-history replay before tailing
  • cover default tailing, explicit replay, and help output

Closes #1355

Tests

  • bun test --timeout=120000 --max-concurrency=1 apps/cli/tests/watch-mode-read-commands.test.js
  • bun test --timeout=120000 --max-concurrency=1 apps/cli/tests/cli-help.test.js
  • pnpm typecheck

Full package gate

pnpm -C apps/cli test reached 1766 passes / 11 skips but remains red on four pre-existing base failures outside this diff: three docs-public-surface-coverage.test.js synchronization assertions and one semantic-tools-unit.test.js fork fixture assertion. Both failing files were rerun in isolation and remain red.

roninjin10 and others added 11 commits July 19, 2026 11:14
Dependency-free Markdown renderer covering the subset chat models emit
(headings, ordered/unordered lists, fenced/inline code, bold, italics,
links). Renders through React children (never innerHTML) so it is XSS-safe
by construction, with scheme-filtered hrefs, and is memoized on the source
string. Exported from smithers-orchestrator/ui.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extract the OutputCard/SummaryPanel shape hand-rolled across .smithers/ui/*
into a shared NodeOutputCard: binds a node via runId/nodeId through
useGatewayNodeOutput, wraps it in card chrome with a pending/produced/failed
status glyph, and renders its body from a render prop given the unwrapped row.
Factor the gateway getNodeOutput envelope unwrap into unwrapNodeOutput (the one
place gateway-ui peels { status, row }), reused by formatOutput and the new
card, and fold in the key={remountKey + ":" + nodeId} remount convention.
Export the new component/helpers, document it in the package README, cover
pending/produced/failed/error/live paths in hookComponents.test.tsx, and
register it in the ui-architecture baseline.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extract the syntax-highlighted diff surface into packages/ui/src/adapters/
behind the @smithers-orchestrator/ui/adapters/pierre-diff-view subpath, keeping
the heavy @pierre/diffs widget out of the base ui barrel. Props-driven (mode +
layout) with pure diffsThemeForMode/diffStyleForLayout/patchToCodeViewItems
seams; re-exported from the smithers facade.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signals join the render context: WorkflowDriver loads _smithers_signals
rows each frame (out-of-band deliveries must be visible next frame) and
SmithersCtx.signalRows(signalName, { correlationId? }) returns parsed
payloads with their shared-clock seq, sorted durably. Groundwork for the
smithers-orchestrator/xstate fold (eventReceived source).

Also fixes the tsup generic-alias emit trap at its source: the local
OutputRowsReader typedef in SmithersCtx.js now carries @template Schema,
so regenerated index.d.ts keeps the generic alias.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
WorkflowDriverOptions.signalReader lets the engine hand the driver an
adapter-backed _smithers_signals reader; the driver's own db handle is the
raw drizzle instance, which has no listSignals. Without this wiring
ctx.signalRows silently rendered [] in engine-hosted runs while parked
WaitForEvent bridges still resolved — signals reached waiters but never the
machine fold.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d package

XState v5 machines as derived control state: useSmithersMachine recomputes
the MachineSnapshot each frame as a pure fold (initialTransition +
transition, actions discarded) over durable output and signal rows, ordered
by (provenance seq, declaration index, mapped subindex). Event sources
taskOutput / approvalDecided / eventReceived / timedOut are pure functions
of ctx; eventReceived folds _smithers_signals directly on the shared clock.
An in-process prefix cache validates folded history by content hash (an
in-place payload replacement at the same seq invalidates), and a mount-time
lint (per machine identity, no escape hatch) rejects invoke/spawn/after/
raise/enqueueActions/sendTo/emit/stop/cancel/custom actions, each naming
the Smithers-native alternative. Runtime spawn-in-assign is rejected by a
children check per fold step.

Re-exported as the smithers-orchestrator/xstate subpath (daytona/telegram
precedent). xstate is a ^5.19.0 peer + 5.32.5 dev pin; both lockfiles
refreshed with the manifests in this commit. Tests: fold conformance,
lint, content-validated prefix cache, real-engine durability e2e
(crash/resume identity, rewind, fork divergence, real signal delivery),
10k-event hierarchical benchmark, and consumer-compile tests over the
emitted .d.ts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
docs/integrations/xstate.mdx (derived-fold model, event sources,
constraints table, listener/re-entry/final-state semantics, time-travel
behavior, benchmark-backed practical limits), docs.json nav, and
INTEGRATIONS_PAGES registration; llms bundles regenerated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Port Multi's TerminalSession into packages/ui as a store-free `<Terminal>`
xterm.js render surface behind the adapters/ heavy-dep layer. Data source is
lifted onto props (lines snapshot, stream write seam, onData out); the xterm
base stylesheet is vendored as a string and injected through the ui style seam.
Exposed via @smithers-orchestrator/ui/adapters/terminal and the published
smithers-orchestrator/ui/adapters/terminal facade. Refreshes both lockfiles for
@xterm/xterm + @xterm/addon-fit and unions the ui-architecture baseline.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 events --watch replays full history by default

1 participant