Skip to content

Releases: modem-dev/sideshow

v0.11.0

Choose a tag to compare

@benvinegar benvinegar released this 03 Jul 15:59
c95d64c

Minor Changes

  • 2bc9db6: Return per-surface ids, kinds, and indexes in write responses without echoing surface payload bodies, and remove the redundant top-level kinds array. Read kinds from surfaces.map((surface) => surface.kind) instead.
  • 28a3a6d: Add a host-overridable ss:aside-head slot at the top of the sidebar, above the session list (mirrors ss:aside-foot). Self-hosted rendering is unchanged; an embedder can project a sidebar header — e.g. a workspace picker and a pinned Home link — above the session list.
  • 71bf606: Add a hideBrand flag to the embed host contract. When set, the engine omits its own "sideshow" wordmark (the sidebar/header home-link brand) so a host that supplies its own branding — e.g. a workspace picker atop the sidebar and a wordmark in the footer — isn't doubled up. Self-hosted leaves it unset and shows the wordmark as before.
  • 1b7a28c: Add a homeView flag to the embed host contract. When a host owns its own session-less landing (e.g. a "home" feed), the engine no longer auto-selects a session on boot — it honors a deep-linked route session but otherwise stays session-less so nothing is highlighted behind the host's landing, and it clears the selection when the route later becomes session-less. Self-hosted leaves the flag unset and is unchanged (auto-selects the latest session on boot).
  • 5eba65a: Add a server onEvent feed tap for hosts and a liveTransport: "ws" viewer-embed option so hosted wrappers can provide hibernation-friendly WebSocket live updates while self-hosted sideshow keeps using SSE by default.
  • ffe7099: Embed host contract: onThemeChange now receives a second meta argument —
    { theme, mode } — naming the resolved theme id and light/dark scheme behind the
    tokens it already reports. Hosts that re-render surfaces out-of-band (e.g.
    server-side preview frames they can't theme from the token values alone) can pass
    those identifiers to /s/:id?theme=&mode= to reproduce the exact look; hosts that
    only paint from the token values ignore it. Additive — the tokens argument is
    unchanged and the default self-hosted host is unaffected.

Patch Changes

  • ed8b987: Validate sideshow surface add has at least one surface flag before resolving or creating a session, and resolve long-poll waits promptly when clients disconnect.
  • 7698b1f: Hydrate session post streams from the session list endpoint to avoid N+1 post detail requests on open.
  • 23dad90: Lazy-load sandboxed surface iframes to reduce initial viewer work on long sessions.
  • 46cf918: Fix markdown/code/diff/mermaid surfaces rendering on a white canvas (washed-out
    text) on a dark board. These rich-part frames are sandboxed opaque-origin
    iframes, which default to color-scheme: normal (light), so in dark mode the UA
    painted a white backdrop behind the transparent body. They now pin color-scheme
    to the resolved scheme — like html surfaces already do — so the frame's canvas
    tracks the card in both light and dark.
  • 2bc9db6: List session posts with canonical surfaces entries that include surface ids and omit elided html bodies.
  • cc6504c: Slides kit now grid-stacks its deck so it cross-fades in normal flow. Previously
    it swapped slides with display:none, which can't fade — so decks were hand-rolled
    with position:absolute slides over a min-height stage, an out-of-flow layout the
    surface-page height bridge can't measure (the overlay grows scrollHeight but not
    the box its ResizeObserver watches), leaving the frame clipped/frozen. The kit now
    stacks slides in one grid cell (in flow, sized to the tallest slide) and fades with
    opacity/visibility, so the frame follows it. DESIGN_GUIDE documents the out-of-flow
    trap and the grid-stack recipe alongside the existing position: fixed ban.
  • 2bc9db6: Expose derived 0-based surface indexes on post detail, session post list, and post history read responses.
  • 0a094ac: Let direct rich-surface renders without an explicit mode follow the browser's system color scheme.
  • 565c85f: Fix intermittent clipping in surface iframes when async content settles after the initial resize pass.

v0.10.0

Choose a tag to compare

@benvinegar benvinegar released this 29 Jun 21:04
549d793

Highlights

  • Added per-surface operations across CLI, HTTP, and MCP, including stable surface ids and add/edit/remove/reorder flows.
  • Improved CLI multi-surface publishing: repeated surface flags now work and flag order is preserved.
  • Added a system/light/dark color-mode switcher in the viewer.
  • Added GET /api/surfaces/recent for recent post previews across sessions.

Fixes and polish

  • sideshow update now preserves each surface kind instead of converting updates to HTML.
  • Fixed configured base paths for uploaded asset URLs and native image/trace surfaces.
  • Improved mobile drawer behavior in embedded WebKit viewers.
  • Added page title/share metadata improvements and safer CLI handling for ids that start with - or _.

0.9.0

Choose a tag to compare

@benvinegar benvinegar released this 26 Jun 15:14
39a604e

New

  • Post / surface vocabulary — a published artifact is now a post (an ordered list of surfaces). New /api/posts, /p/:id routes and publish_post / update_post / list_posts MCP tools join the legacy ones; all old routes, tools, and keys remain as deprecated aliases.
  • Open-as-image — each surface footer gains an action to open it as a PNG (/s/:id.png), live on Workers deployments.
  • sideshow --version — prints the installed version and checks npm for updates.
  • Sidebar empty-state slotss:aside-empty is now host-overridable; shows a "Connect an agent" nudge when empty.

Fixes

  • Data dir moved to ~/.sideshow/ — fixes EACCES under sudo npm i -g and data loss on upgrade; one-time migration from the old package-relative location.
  • SQLite parent-dir guard — first-run crash when the db paths parent directory doesnt exist.
  • Submit-time validation — rejects diffs and mermaid diagrams that wont render.
  • Connection cap — held SSE / long-poll connections bounded per workspace (default 32).
  • Mobile viewer — improved layout for phone-sized screens.

Breaking (embedders)

  • identity.accountSlugidentity.workspaceSlug on the injected host contract.

v0.8.0

Choose a tag to compare

@benvinegar benvinegar released this 25 Jun 15:12
f4bfeca

Minor Changes

  • f8fb7b3: Sidebar wordmark is now a clickable home link that clears the session and returns to the board.
  • 4822f77: Embeddable engine: add host.onReady() and stop the empty-board onboarding flash before sessions load.
  • 760320f: Embeddable engine: add host.onThemeChange(tokens) so a host can mirror the resolved palette onto its own chrome.
  • 38992d7: Embeddable engine: expose layout ("stream") and readonly on the host contract.
  • 23be3a1: Link unfurls — bare /s/:id URLs serve Open Graph + Twitter Card metadata (with a 1200×630 .png card) so links render rich in Slack/X/Discord/iMessage.
  • 12bb6b4: Embeddable engine: add a ss:main host-overridable slot wrapping the main content pane.
  • bd8df08: Screenshot any surface as PNG by appending .png (supports ?mode, ?theme, ?w, ?nocache).
  • e924954: Breaking (library consumers): rename the data model — SurfacePost, *PartSurface, partssurfaces, plus matching type/Store/helper renames. SQLite boards migrate in place; route paths and MCP tool names are unchanged.
  • eb2001d: Embeddable engine: add a ss:session-actions host slot in the session header (empty by default).
  • 9da948d: Local Node server now defaults to SQLite (node:sqlite) — the same store as the Cloudflare deploy; an existing sideshow.json migrates in once. SIDESHOW_STORE=json keeps the legacy store.
  • f5e89d7: Direct links to a surface open a full-page standalone view (just that surface, no sidebar or feed).
  • 5436598: Embeddable engine: publish the theme-token contract as data via a new sideshow/theme-tokens entry.

Patch Changes

  • b60c9a2: Cap the asset-upload body while streaming so a chunked request can't OOM the server (413).
  • eb269b5: Cap every request body via a global bodyLimit, closing the same OOM vector on JSON/MCP endpoints.
  • ff217bf: The pi extension's tool schema now accepts the mermaid surface part kind.
  • c8f7c68: Input validation: clean 400 on malformed asset base64, cap comment/title sizes, fail fast on non-numeric CLI --after.
  • c04a9ac: Mermaid diagrams now fully re-theme on a light/dark flip (arrowheads and text track the active scheme).
  • 58c515f: Validate the openLink scheme host-side so a surface can't open non-http(s) URLs.
  • 6e3c1b6: Refresh two README surface-gallery examples (html data table, image SaaS ad); no runtime changes.
  • 134a926: Reserve the user comment author so surface content can't impersonate the user to the agent.
  • bd3ea88: Render rich parts (markdown/code/diff/terminal) server-side from /s/:id?part=N, fixing blank/clipped reloads under a Chrome 149 field trial.
  • 3752061: Sandbox the /s/:id document with a CSP response header so agent script can't run in the board origin on a top-level load.
  • 57829c0: Fix an auto-resize feedback loop that could pin a CPU core.
  • 7f86b13: Share-link ids are now 11-char url-safe base64 (~64 bits) instead of a 32-bit UUID segment.

v0.7.0

Choose a tag to compare

@benvinegar benvinegar released this 22 Jun 18:57

Minor Changes

  • ee75c8d: Embeddable viewer engine — mountViewer(el, host) (new sideshow/viewer-embed export) lets a host app embed the viewer. Self-hosted is unchanged.

  • a4033cf: Embedders can override the empty-board and sidebar-footer regions via named <slot>s. Self-hosted markup is unchanged.

  • 91db9a3: Support deployments mounted below an origin root.

  • 3f45e76: New json and code part kinds for surfaces.

    • json — a JSON value rendered natively as a collapsible tree (objects/arrays expand on click, type-colored primitives). Like image/trace it's data, not markup, so no sandbox is needed.
    • code — source highlighted with shiki in a sandboxed iframe, with line numbers, an optional filename header, and a copy button. lineStart shows original line numbers for excerpts. CLI: sideshow code app.ts --title "app.ts" --line-start 80.

    Also extracts the shared shiki highlighter into viewer/src/highlight.ts.

  • ddbfab2: SIDESHOW_PUBLIC_READ env var for read-only board access — session for unlisted-link sharing, full to expose the whole board.

Patch Changes

  • 5e3f292: Fix invisible markdown/mermaid/diff/terminal surfaces caused by a Chrome field trial that breaks layout measurement in srcdoc iframes. The viewer now retries the srcdoc parse after 2s if still stuck at minimum height.
  • c2e4443: Honor lineStart in code-part gutter numbers — shiki's <pre> markup wasn't matched by the counter-reset injection, so excerpts now number from their original line.
  • 3c56cc1: Deep links to /session/:id/s/:surfaceId now scroll to the target surface card.
  • 84e7057: Reject oversize asset uploads before buffering the body into memory, so a multi-GB upload can't exhaust the heap before the 413 fires.
  • 6962019: Fix cursor lag in waitForComments. lastSeq/agentSeq now derive from the unfiltered comment list, so an agent reply no longer makes every author=user poll re-read it and waste a round-trip.
  • a18f210: Pin surface iframes to the chrome's color scheme so light/dark no longer diverges across the frame boundary (html parts via a mode query param, markdown/code/comment frames via renderSandboxedPart). With no mode passed, the OS media query is kept, preserving self-hosted parity.
  • f0c6cd4: Fix a lost-update race in SqlStore.updateSurface. Concurrent PUT /api/surfaces/:id calls could lose one caller's parts; now uses compare-and-set with retry.
  • db463ce: Improve intro readme.

v0.6.0

Choose a tag to compare

@benvinegar benvinegar released this 19 Jun 20:12
71e6405

Sideshow 0.6 focuses on richer surfaces, safer rendering, and better agent setup.

Highlights

  • Timeline traces. Sessions can show the prompts, reasoning, and commands behind a surface. Claude Code users can install the Stop hook with sideshow install-hook, or run sideshow trace-sync manually.
  • Themes. The board now has seven light/dark theme presets — GitHub, Gruvbox, One, Solarized, Catppuccin, Rosé Pine, and Everforest — applied across viewer chrome, html tokens, markdown/diff highlighting, mermaid, and terminal parts.
  • Mermaid parts. Agents can publish Mermaid diagrams directly with sideshow mermaid, --mermaid, MCP, or HTTP.
  • HTML kits. Opt-in issues and slides kits give agents ready-made, theme-aware building blocks for issue trees, status boards, and decks. Discover them with sideshow kits or GET /api/kits.
  • Deep links. Viewer URLs now track the current session and surface (/session/:id, /session/:id/s/:surfaceId), including back/forward navigation.
  • Pi extension. Installing the package in Pi adds native sideshow_* tools for publishing, updating, uploading assets, waiting for feedback, replying, listing surfaces, and fetching the guide.

Agent and viewer polish

  • Added /agent-howto and sideshow agent-howto; the bundled skill/setup block is now a small bootstrap that asks the running server for current Sideshow guidance.
  • Changed the default local server from http://localhost:4242 to http://localhost:8228.
  • Sidebar sessions now show agent logos, a surface count, and cleaner metadata.
  • The card comment footer is flatter and quieter.
  • Comments now always attach to a surface; sideshow comment requires --surface.
  • The agent design guide is shorter and frames kits/theme tokens as optional scaffolding, not a required house style.

Safety and reliability

  • Markdown, Mermaid, diff, terminal parts, and comment text now render inside opaque-origin sandboxed iframes, matching html parts and reducing the impact of sanitizer regressions.
  • The viewer only accepts host-affecting postMessage events from frames it embedded.
  • Added focused unit and e2e coverage for sandbox isolation, themes, kits, trace ingest, and cross-channel feedback delivery.

v0.5.0

Choose a tag to compare

@benvinegar benvinegar released this 17 Jun 12:09

Added

  • Surfaces: a published card is now an ordered list of parts, not a single HTML
    blob. New part kinds render natively in the viewer alongside sandboxed html:
    diff (a syntax-highlighted code review from a patch), markdown (prose with
    highlighted fenced code), terminal (monospace output with ANSI colors), plus
    image and trace. Publish any of them across all three tiers — MCP
    (publish_surface/update_surface), POST /api/surfaces, and the CLI.
  • Uploads: push images, traces, and files across all three tiers (POST /api/assets, the upload_asset MCP tool, sideshow upload/image/trace).
    Assets are content-addressed by SHA-256, identical uploads dedupe, and an
    asset lives as long as any surface references it. Capped at 5 MB each.
  • A Claude Code plugin (plugin/, via a repo-hosted marketplace) bundles the
    MCP server, the skill, and a background monitor — browser comments arrive in
    the agent as notifications without pasting or re-arming a watcher. Install with
    /plugin marketplace add modem-dev/sideshow then
    /plugin install sideshow@sideshow.
  • sideshow watch streams user comments to stdout, re-arming the long-poll
    forever (exactly-once across watch, wait, and piggyback).
  • A "connect Claude Code" link in the viewer opens an integrations panel with
    the plugin install commands and caveats.
  • A copy button on each comment puts an agent-ready paste block (surface title +
    id + comment) on the clipboard.
  • The npm package exposes a stable sideshow/server entrypoint so integrations
    can reuse createApp/JsonFileStore without importing private internals.

Changed

  • Snippets are now "surfaces" throughout the API (/api/surfaces, surface-*
    SSE events, comments keyed by surfaceId). The old snippet endpoints and
    publish_snippet/update_snippet tools remain as back-compat aliases; stored
    boards migrate in place on load.
  • The session sidebar groups sessions by recency (Today / Yesterday / Earlier),
    and sessions with no surfaces yet are dimmed and sunk to the bottom.
  • The viewer is framed around leaving comments rather than messaging an agent —
    composers read "Leave a comment…", with no delivery receipts or "listening"
    indicators.
  • A surface card's open and delete actions are now minimal Lucide icons.
  • sideshow-term auto-starts a local server when needed (bare sideshow-term
    opens the watcher, default port 4243), supports mouse input, and gains
    clear / clear --all.

Fixed

  • sideshow-term hardens STML parsing/rendering for untrusted markup (tested
    entity decoding, bounded size/depth, neutralized control characters, render
    failures degrade to an in-view error).
  • Local JSON storage shares a single cold-load promise across concurrent first
    requests, fixing a race that could overwrite persisted board data.
  • The viewer shows a neutral "refresh sideshow to update the viewer" hint for an
    unrecognized part kind instead of a broken-diff error.
  • Malformed POST/PUT /api/surfaces part payloads are rejected before they
    reach storage.
  • sideshow-term can be packaged and installed standalone (declared server
    dependencies, reuses the sideshow server core, runs built JavaScript).

v0.4.0

Choose a tag to compare

@benvinegar benvinegar released this 15 Jun 14:53

Added

  • Cmd+Option+Up/Down switches between sessions in the viewer without reaching
    for the sidebar — Down moves to the next session in the list, Up the
    previous, wrapping at the ends.
  • The viewer notices new releases: a dismissable banner in the sidebar names
    the latest version with a copyable upgrade command (npm install locally,
    redeploy for workers), and the release notes render as a card at the top of
    the stream. Dismissing either hides both until the next release. The check
    lives server-side at /api/version (npm registry + GitHub release notes),
    is cached for six hours, and fails silently — offline costs nothing but the
    absence of the notice.
  • The CLI now runs on Windows: session detection walks the process tree with a
    single PowerShell call instead of ps, and sideshow serve --open launches
    the browser via cmd /c start. macOS and Linux are unchanged.

v0.3.0

Choose a tag to compare

@benvinegar benvinegar released this 12 Jun 19:10

Added

  • A session thread at the bottom of each session in the viewer: a composer
    for messaging the agent without picking a snippet.
  • Feedback now reaches agents without polling: publish/update/reply responses
    carry a userFeedback array with any comments the user left since the
    agent's last call (delivered once; a consumed wait also counts as seen).
  • The design guide, setup block, and Claude Code skill teach the background
    watch pattern: arm sideshow wait as a background process after publishing
    and react when it exits, instead of blocking or polling.
  • Agents can name their session at creation: sessionTitle on the publish
    body and both MCP publish_snippet tools, --session-title on
    sideshow publish. Applied only when the publish creates the session —
    it never overwrites a title, including renames made in the viewer.
  • A snippet kit baked into every snippet doc, so agents publish compact
    markup instead of hand-written inline CSS: bare button/input/select/
    textarea pre-styled to match the viewer, SVG utility classes (t/ts/
    th text presets, box, arr, leader, node, c-* color ramps with
    dark-mode-aware text), and a shared #arrow marker injected into every
    doc. The design guide documents it as a compact reference table.

Changed

  • New snippets no longer steal the scroll position: the viewer only follows
    them when already at the bottom of the stream, and shows a "new snippet ↓"
    pill otherwise.
  • Activity the user isn't looking at — another session, or any session while
    the tab is hidden — badges the tab title with an unread count.
  • The Claude Code skill now documents the repo-local CLI fallback and a
    checkpoint-drain feedback pattern for harnesses that cannot surface
    background watcher output.

Fixed

  • Feedback was re-delivered when channels were mixed: a fresh sideshow wait
    process (or restarted stdio MCP server) started from seq 0 and replayed
    comments the agent had already received via piggyback or another channel.
    author=user session reads with no explicit after now resume from the
    server-side agent cursor, and the CLI and stdio MCP keep no cursor of their
    own — delivery is exactly-once across CLI, MCP, and piggyback. Pass
    --after <seq> (CLI) or afterSeq (MCP at /mcp) to deliberately re-read.
  • A comment that failed to send was silently lost (input cleared, no error).
    The viewer now echoes comments immediately (pending until confirmed) and on
    failure restores the text to the input with an error toast.
  • After an SSE reconnect the viewer refetches the selected session, so
    snippets and comments that arrived during the gap can no longer be
    silently missing from a live-looking board.
  • The viewer layout no longer breaks at phone widths: below 700px the
    sidebar collapses into a drawer behind a slim top bar (hamburger toggle,
    unread dot), the stream takes the full width, and hover-only actions
    (card open/delete, session delete) stay visible on narrow or touch
    screens.
  • Comments not attached to a snippet (e.g. sideshow comment without
    --snippet) were stored and delivered to agents but never shown in the
    viewer; they now render in the session thread.
  • The viewer is now usable by keyboard and assistive tech: session rows are
    focusable and activate with Enter/Space (focus survives live re-renders),
    hover-only actions (session delete, card open/delete) are reachable and
    shown on focus, the editable session title is labeled and Escape cancels
    an edit, snippet iframes carry the snippet title, and toasts are announced
    via a polite live region.

v0.2.0

Choose a tag to compare

@benvinegar benvinegar released this 11 Jun 16:06

Added

  • sideshow demo seeds two example sessions (a sequence diagram with a
    comment thread, an interactive explainer, a metrics card) so the viewer can
    be explored without an agent.