Skip to content

Releases: vritser/dsh-emacs

dsh-emacs 0.7.0

Choose a tag to compare

@vritser vritser released this 23 Oct 08:21

Compatible with dsh 0.2.1-rc.2, the latest upstream release as of 2026-10-18 (npm next; npm latest still points to 0.2.0-rc.2). The minimum supported Emacs version is now 28.1.

Breaking changes

  • Emacs 28.1 is now the minimum; 27.1 support is removed. CI runs the gate on 28.1 and a current stable release.
  • Removed Lisp helpers (no aliases): dsh-emacs-modeline-set-cwd, dsh-emacs-modeline-set-branch, dsh-emacs-modeline-teardown, dsh-emacs-usage-p. Mode-line cwd and branch use the chat's default-directory and cached Git detection.
  • Removed inactive transcript options: dsh-emacs-group-consecutive-tools, dsh-emacs-assistant-divider.

Opening sessions

  • Complete rounds on open: a fresh chat buffer completes the latest round, paging back for a long round without moving the draft cursor or delaying the live stream. C-c C-o cancels a pending load and then loads earlier rounds (three by default).
  • Cheaper tool-heavy history: live and replayed tool cards format their terminal, read, diff and generic result bodies only when expanded, and repeated expansion reuses the formatted body. Expanded cards still update as results arrive.

Transcript

  • Web-style task and activity disclosures: settled thinking and tool cards fold into independent summaries between visible replies; a successful turn without mid-turn input folds its whole process under a muted Completed in … row. RET toggles each disclosure; set dsh-emacs-fold-work-details to nil and reopen to flatten the transcript.
  • Stopped and interleaved turns match Web: Failed/Stopped rows no longer hide the process, mid-turn input keeps the turn open, and automatic compaction folds with its activity without contributing a tool count.
  • No duplicate replies while opening: reentrant WebSocket reads queue behind the active snapshot consumer, so thinking, tools and final answers no longer render twice around the reply footer.
  • No flash of expanded work: snapshots and older pages redraw only after reply footers and task folds are reconciled; completed work first appears collapsed.
  • Copy and navigation details: copy-line/region drops the hidden prompt and transcript properties, C-a reaches the first authored character, and the blank line below a question survives the first streamed chunk.

Markdown and links

  • Links keep their colour when the label is inline code, bold, italic or struck through.
  • Emphasis and inline code no longer rewrite link/image targets, including incomplete streamed ones; linked images open the enclosing link.
  • Local paths decode URI escapes once, support workspace-relative targets and one-based line/column positions; invalid targets no longer launch a browser, and unsafe schemes are rejected.
  • File links with line ranges (file.el#L10-L20, file.el:10-20) open in Emacs at the first line.
  • Bracketed local image destinations such as ![alt](<path with spaces>) render; images inside inline or fenced code stay literal.
  • Multi-backtick inline code is literal, and partial streamed bare image paths wait for their boundary.

Appearance and mode line

  • Image attachments use a web-style thumbnail gallery in wrapping rows: RET or mouse-1 opens the original, and dsh-emacs-render-image-thumbnail-lines sets the height.
  • Clearer conversation grouping: a three-pixel teal rail instead of a full-width highlight, with Copy, Fork and tokens together on the left in configured order.
  • Next Message above the Goal Row, and a visible gap between the collapsed goal notice's icon and label.
  • Running-subagent icon and count pulse together with Motion Line; native mode lines show plain DSH; header separator colours follow the adjacent label.
  • Idle session indicators inherit shadow, and every chat window keeps its own draft cursor while output follows.

Sessions, state and robustness

  • Switching to an already-open session reuses its live buffer without clearing transcript, draft, cursor position or event stream; C-c C-r remains the explicit resync.
  • The model indicator stays in sync with live selections, including switches made in another client.
  • Running status survives C-c C-r, and a completed turn is not revived by a stale session-list flag.
  • RPC and WebSocket bodies keep required booleans, nulls, arrays and empty objects regardless of user json.el encoding settings.
  • Workspace regrouping no longer trips the Emacs transposition crash or corrupts multibyte row text.
  • Desktop notifications fall back without D-Bus, and a question or approval whose prompt cannot open is declined instead of leaving the host waiting.
  • Chat startup no longer prints internal integration flags; Emacs 28 keeps goal objectives in the help buffer and leaves unchanged cards untouched.

Upgrade

  • Emacs 28.1+ is required.
  • Remove calls to dsh-emacs-modeline-set-cwd, dsh-emacs-modeline-set-branch, dsh-emacs-modeline-teardown and dsh-emacs-usage-p, and settings for dsh-emacs-group-consecutive-tools / dsh-emacs-assistant-divider.
  • Change dsh-emacs-default-preset from "code" to "ptc".
  • Restart Emacs after updating.

Validation

  • scripts/verify.sh: passed — syntax checks, byte compilation (free-variable warnings fail), 1,235 unit tests with and without Motion Line, clean load, whitespace and junk scans.
  • Real-server RPC and event-stream suite against dsh 0.2.1-rc.2: 31 passed, 0 failed (2026-10-23).
  • Optional model-driven subagent and running-status scenarios were not enabled in this release run.

Full changelog · Getting started · Compare with 0.6.1

dsh-emacs 0.6.1

Choose a tag to compare

@vritser vritser released this 18 Oct 01:38

Compatible with dsh 0.2.1-rc.2, the latest upstream release as of 2026-10-18. This version is published under npm next; npm latest still points to 0.2.0-rc.2. Emacs 27.1+ remains supported.

Compatibility fixes

  • Use server-assigned session IDs when activating drafts, preserving draft text and retry state.
  • Surface migration-required projection reads as errors instead of accepting them as session state.
  • Keep external subagents visible while preventing unsupported local navigation and interruption.
  • Update the RPC reference for the dsh 0.2.1 protocol. Existing browser-cookie authentication remains supported; /connect migration is not required.

Transcript feedback

  • Show retries once in the transcript, removing the duplicate mode-line Retry/Retrying label.
  • Distinguish scheduled/started retries, failed replies, cancellation, and recovery retries confirmed by a later response in the same step.
  • Give retry and error events a consistent compact layout and status dot: orange for retries, red for failures, grey for cancellation or unknown outcomes. Model error codes appear as muted metadata, with explanations visible below.
  • Preserve expandable partial output and folding when outcomes arrive, including through older-history pages. Release outcome caches when the corresponding transcript content is trimmed.

Upgrade

Restart Emacs after updating to load the changed protocol structs and remove old mode-line definitions.

Validation

  • scripts/verify.sh: passed, including syntax checks, byte compilation, unit tests with and without Motion Line, and clean load.
  • Real-server RPC and event-stream suite against dsh 0.2.1-rc.2: 28 passed, 0 failed.
  • Retry classification regressions cover live events, history replay, older-page insertion, step boundaries, and cache pruning.
  • Optional model-driven running-status, subagent, plan-review, and timed-question scenarios were not enabled in this release run.

Full changelog · Getting started · Compare with 0.6.0

dsh-emacs 0.6.0

Choose a tag to compare

@vritser vritser released this 17 Oct 11:23

An expanded Emacs client for the dsh 0.2.0 protocol, with subagent conversations, plan review, staged attachments, and smoother history and completion. Emacs 27.1 remains the minimum; Motion Line is optional.

Upgrade notes

  • Attachments are staged before sending. C-c C-a adds one file; repeat to add more, then send everything with C-c C-c. Drag-and-drop also stages files. Lisp callers use (dsh-emacs-attach-file file); the caption argument has been removed.
  • Queue and job counts have left the mode line. Use the Composer preview and C-c C-q for pending input, and tool rows or C-c C-j for jobs. Remove customizations of the deleted dsh-emacs-modeline-queue-face, dsh-emacs-jobs-modeline-face, and dsh-emacs-jobs-map.
  • Composer rows use the buffer background. Remove references to dsh-emacs-input-box-face, dsh-emacs-color-input-bg, and dsh-emacs-color-input-bg-dark.
  • Restart Emacs after upgrading to replace removed definitions and changed protocol structs. The protocol reference records the audited dsh 0.2.0-rc.2 baseline; this release does not promise full compatibility with older servers.

Highlights

  • Browse subagent conversations from the session tree or minibuffer, send follow-ups to continuable children, and return to the parent through xref.
  • Enter plan mode with /plan, review submitted plans in a document buffer, and approve execution or request changes. Timed questions support late answers, and approval reasons can follow your locale.
  • Attach arbitrary files, paste clipboard images, and review the staged set before sending.
  • Load complete earlier rounds with C-c C-o, return to the draft with C-c >, fork from an assistant reply, and use configurable reply actions and usage statistics.
  • Start typing while a session is created. Discover @ references asynchronously, with live Corfu refresh and session-list visibility filtering.
  • Follow goal activity and automatic compaction in the transcript and Composer. Optional Motion Line integration adds an animated whale and elapsed clock.
  • Add providers and select reasoning effort from Emacs; reload local source with M-x dsh-emacs-reload while preserving chats and drafts.
  • Rendering, session-list updates, and JSON decoding receive performance improvements. The README now focuses on setup and everyday use, with detailed guides linked separately.

Full changelog · Getting started · Compare with 0.5.0

Validation

  • scripts/verify.sh: passed, including the unit suite with Motion Line.
  • GUI display regression suite: 2 passed.
  • Real-server transport smoke suite: 28 passed. Optional model-driven subagent, running-status, plan-review, and timed-question scenarios were not enabled in this release run.

dsh-emacs 0.5.0

Choose a tag to compare

@vritser vritser released this 24 Sep 05:36

Emacs client for DeepSeek Harness
(dsh): streaming replies, tool cards, thinking blocks, slash commands, and
session/workspace management — Emacs 27.1+, no third-party dependencies.

Requires a dsh server on the 0.1.6 wire protocol (0.1.6-alpha.1 or
newer
). See docs/rpc.md for the protocol reference.

Highlights

  • Paste a clipboard image into the next message — C-c C-v stages a
    screenshot or copied picture in a Composer row above the input; C-c C-c
    sends text and image together. C-c C-d discards the staged images, s-v
    does the same whenever the clipboard holds an image (and stays a text yank
    otherwise), and M-x yank-media works on Emacs 29+.
  • Opening the session list lands on the session you are in — cursor and
    hl-line move to the current session's row (unfolding its group and clearing
    a hiding filter if needed) instead of parking on the first row.
  • Undo/redo scoped to the input area — C-/, C-_ and C-x u undo input
    editing, C-g C-/ redoes it; the rendered transcript is never undone.
  • Ask rows record the decision — an ask_user_question call collapses to
    Ask question · waiting / 2/2 answered and expands into the questionnaire
    with the chosen options checked, instead of dumping raw JSON.
  • Restore an archived session without leaving Emacs — M-x dsh-emacs-unarchive-session, or u in *dsh-sessions*, the inverse the d
    archive action never had.
  • Failed tool rows explain themselves — a settled tool/result shows
    dsh 0.1.6's user-facing error.reason (✗ failed — …) rather than a bare
    failure.
  • See and switch the session's permission preset — a shield-icon mode-line
    segment shows the current sandbox/approval preset, and M-x dsh-emacs-set-permission offers the host's preset catalog.

Changed

  • Opening the session list no longer re-fetches or reconnects. The list
    stays live from the event stream, so M-x dsh-emacs / C-c C-l reuses the
    cached rows; g still refreshes on demand.
  • TAB completes ordinary words and local file paths in the chat input.
    Words already in the draft or transcript complete nearest-first; a token with
    a separator (docs/rp, ./src/, ~/…, an absolute path) completes through
    the stock file-name completer against the session workspace.
  • Generic tool cards line up and say what happened. Variant-less tools
    expand into one aligned IN / OUT block under Tool Call · <tool name>,
    and a clean success no longer prints a bogus ✓ exit 0.
  • Ask option descriptions read as one face, with the bare description
    instead of a bracketed suffix, matching the transcript's ask card.

Fixed

Streaming and rendering

  • Streamed blocks stay separate through finalization and retry, and a finished
    reply no longer gains a duplicate Think row.
  • Reconnect restores the complete in-progress reply once; live replies recover
    from restarted counters and missing frames instead of leaving truncated text.
  • Thinking no longer rewrites the transcript while it streams, and a streamed
    code block no longer rearranges what is already on screen.
  • Streamed replies and live Think output are read-only from the first chunk;
    typing no longer stalls a block transition.
  • Markdown after a code fence renders in the same chunk; interleaved answers
    keep their order when finalized.
  • File diffs distinguish unchanged context from edits: only added/removed lines
    get red/green prefixes and count toward the footer totals.

Session list

  • A refresh no longer scrolls the list or drops a second window back to the
    top; opening the list still moves to the current session.
  • Re-opening the list no longer resets folded groups, the workspace filter, or
    the live-stream binding.

Sending and queueing

  • Sent messages show up the moment the input clears; a rejected prompt removes
    the optimistic echo and restores the draft.
  • An idle C-c C-c is no longer queued as if the session were running, and no
    longer flashes the blue Next Message row (first send in a new session
    included).
  • M-p no longer recalls the host's own injected messages
    (<system-reminder> prose, runtime-context snapshots, notices).
  • Undo immediately after sending restores the draft.

Server and input

  • A slow first server start waits the configured grace period instead of
    reading as a failure, and says whether the process it started exited.
  • Wire booleans (isDefault, authorable, hasDocument, attachments,
    session running) are normalized where they cross into the protocol structs,
    so a new session no longer pre-selects the wrong agent preset.
  • M-<backspace> / M-DEL clears punctuation at the input start (~/, ../).

Full detail: CHANGELOG.md

dsh-emacs 0.4.1

Choose a tag to compare

@vritser vritser released this 17 Sep 01:56
v0.4.1

dsh-emacs 0.4.1

dsh-emacs 0.4.0

Choose a tag to compare

@vritser vritser released this 16 Sep 04:30
v0.4.0

dsh-emacs 0.4.0

dsh-emacs 0.3.0

Choose a tag to compare

@vritser vritser released this 10 Sep 07:03

dsh-emacs 0.3.0 — Emacs client for DeepSeek Harness (dsh), 46 commits
since v0.2.0.

This release migrates the client to the dsh 0.1.2 wire protocol — which
also introduces browser-session authentication, so it needs a server of
0.1.2-rc.1 or newer — and lands goals (Goal Row with pause/resume/edit/clear
actions), a Next Message row in the Composer, web-style @ references, local
!command shell execution, a bash terminal card, collapsible workspace groups
in the session list, and a deep pass of streaming-performance work.

Breaking changes

  • dsh 0.1.2 wire protocol migration: the realtime surfaces move from the
    per-session mux plus host stream to a single /api/remote.mux WebSocket
    multiplexing logical streams — a chat opens a session/follow stream whose
    snapshot seeds the transcript, and the session list keeps a core connection
    (session/control + workspace/follow + $events). RPC endpoints use the
    two-segment slash form (session/list, session/create, …) with bodies
    wrapped as payload = {args: …}; questions and approvals arrive as $events
    waterfall frames and are answered through $events/result. Workspace state
    now comes from workspace/follow instead of a workspace.list RPC, and
    dsh-emacs-history-refetch-max-rounds is gone (reconnects reseed from a
    fresh snapshot). Saved customizations of the removed option are dropped on
    upgrade.
  • Slash-command and @ auto-pop go through your own completion
    front-end
    : dsh-emacs no longer runs its own content-driven trigger to force
    a popup for stock *Completions* / vertico / ivy (and no longer
    buffer-locally force-enables corfu-auto). It is a completion backend
    now — it registers completion-at-point-functions and contributes / to a
    front-end's auto trigger only when that front-end's own auto mode is already
    on (corfu, company via company-capf). Stock *Completions* / vertico /
    icomplete stay TAB-only. dsh-emacs-slash-auto-complete (default t)
    controls whether the / trigger is contributed at all.
  • Fragment extension API: dsh-emacs-ui-find-block and
    dsh-emacs-ui-delete-fragment now take separate namespace-id / block-id
    arguments (joined ids and keyword deletion arguments are rejected), and
    dsh-emacs-ui-update-fragment takes a complete snapshot — nil clears a field
    and it returns (START . END). The append update argument, the unused
    group and hide-label-on-collapse constructor arguments, the
    :color-key argument (renamed :status; it never applied colors — :face
    does) and several unused helper functions and faces are removed. No
    compatibility shims are retained.

Added

  • Realtime live chat and session list: an open chat keeps a
    session/follow stream on the shared mux socket, so replies stream in live
    and a drop reseeds from a fresh snapshot instead of needing a manual refresh;
    the session list keeps a core connection, so workspace, session and archive
    changes from any client — including dsh web — repaint it in place, with live
    queue/context projections.
  • Goal Row and goal actions: while a session has an active goal, a
    read-only row pinned above the input shows a dartboard icon with the
    objective and phase (never sent to the model, hidden for a completed goal),
    and C-c C-g is a goal prefix — p pause, r resume, e edit (pre-filled
    in the minibuffer), d clear, a toggle the inline SVG action icons,
    ? full objective and blocked reason. Actions are CAS calls on the live goal
    ref, guarded against double-fire, and update optimistically.
  • !command local shell commands: a line starting with ! and without
    attachments runs the full input locally with Emacs's shell-file-name
    in the session's workspace — it works offline and while the model is busy,
    becomes an expanded, collapsible transcript row with its exit status, and is
    never sent to the model or saved in server history. C-c C-! stops the
    tracked process. New options: dsh-emacs-shell-require-confirm,
    -max-output, -null-stdin, -timeout
    (see docs/shell-commands.md).
  • @ file/session references: typing @ opens a combined completion menu
    — files and directories from the session workspace first, then sessions —
    with flexible (flex-style) matching across the whole path, @"path with spaces" quoting and host-side snapshots mirroring dsh web. Completed
    mentions become atomic chips in the composer (backspace removes the whole
    mention, RET opens a session or file), and mentions echoed in the transcript
    render as clickable links instead of raw text —
    @[label](dsh-session:…) shows as just @label. See
    docs/reference.md.
  • Next Message row in the Composer: pending input gets its own read-only
    row between the goal and the ❯ prompt, with a width-adaptive preview and a
    full-text tooltip; steering items take priority over queued messages.
  • Bash tool rows expand into a terminal card: a bash/pwsh call opens into
    dsh web's BashRow shape — a code-block-style background band, a single $
    prompt line, a divider, raw output, and a state-colored footer only on
    failure or interrupt (a clean exit ends bare). Other tool variants keep the
    IN/OUT ioCard.
  • Workspace folding in the session list: workspace and Ungrouped headers
    show an expanded/collapsed indicator and fold with TAB or RET; fold state
    survives refreshes. dsh-emacs-workspaces-collapsed-by-default,
    dsh-emacs-collapse-workspaces and dsh-emacs-expand-workspaces control it.
  • Browser-session authentication for dsh 0.1.2-rc.1+: dsh-emacs performs
    the launch-token → dsh-auth-* cookie exchange itself, reading the token
    from the managed server's output, from dsh-emacs-server-auth-token, or from
    a ?token= in dsh-emacs-base-url (stripped before requests are built, so
    pasting the URL dsh prints just works), and sends the cookie on RPC posts, the
    mux WebSocket handshakes and the dsh web URL. A 401 now reports an
    actionable hint, and pointing at an external server prompts once for the
    token instead of opening a Basic username/password prompt — the token is
    remembered.

Changed

  • Much less CPU while replies stream: socket reads coalesce over 50 ms, the
    first chunk still appears immediately, Markdown scan state persists across
    refreshes, mode-line segments rebuild only when their inputs change, and
    transcript edits and history reads skip redundant redisplay work.
    Following respects real line heights and multiline drafts. A streamed table
    now renders in one pass when it ends instead of row by row (unfinished code
    fences keep showing raw source as before).
  • Faster @ detection in long drafts and faster table wrapping: reference
    completion inspects the buffer and copies only the active token, and each
    cell character's display width is measured once and reused.
  • The model picker names the current provider: C-c C-m prompts
    Select model (current <provider>/<model>):, so ids shared by several
    providers are unambiguous.
  • Session-list keys are clearer: archiving a session is d (was D) and
    deleting a workspace is D (was u), matching the other workspace keys
    (W/R/M); the / text search and dsh-emacs-session-search were
    removed as duplicates of the workspace filter and the session switchers.

Fixed

  • Connecting to any real server works: client WebSocket frames are forced
    to true unibyte UTF-8 before masking, so a multibyte payload no longer dies
    on connect, and the browser-session cookie is actually minted — the exchange
    now reads the first response's headers directly instead of following dsh's
    303 redirect into a 401, which was surfacing as an unusable Basic
    username/password prompt. A stale cookie self-heals instead of 401-looping,
    session/list sends the wire _request parameter again, and sending
    non-ASCII (Chinese) messages works again.
  • The session list is grouped by workspace again (the workspace/follow
    stream is applied correctly), and g no longer opens a second live
    workspace/follow connection.
  • Questions and approvals answered in another client are dismissed here
    instead of staying pending.
  • C-u C-c C-c consistently steers, and a busy submit no longer falls back
    to an optimistic send.
  • The mode-line preset segment works again: the wire migration moved
    agentPreset into a session projection, but the client kept reading the old
    top-level row field, so a real server row produced no preset.
  • Composer editing: C-k on an @ chip removes the whole chip while
    C-k elsewhere keeps standard kill-line semantics, a forward delete at the
    input's end no longer drops the cursor below the input, and goal editing
    preserves the source text.
  • Tables: header styling stays above the reply base face, widths follow the
    destination font and are no longer capped at the window edge, and width
    probes preserve draft and undo history — deferred tables now finish on
    Emacs 27–30.
  • Tool card IN/OUT labels keep their bold weight (dsh-emacs-tool-io-face
    declares it separately from its inheritance).
  • …plus many more fragment, streaming and rendering fixes — see the full
    changelog below.

Full changelog: https://github.com/vritser/dsh-emacs/blob/v0.3.0/CHANGELOG.md

dsh-emacs 0.2.0

Choose a tag to compare

@vritser vritser released this 04 Sep 02:26

dsh-emacs 0.2.0 — Emacs client for DeepSeek Harness (dsh), 51 commits since v0.1.0.

This release renames the status bar to a mode-line, drops the HTTP polling
fallback, and lands queueing/steering of input while a turn runs, session
switching, project-aware session creation, interactive approval prompts,
notifications, inline image attachments and more.

Breaking changes

  • Status bar "footer" renamed to "mode-line": customize group
    dsh-emacs-footer → dsh-emacs-modeline, with options, commands and faces
    renamed accordingly (-enabled / -format-spec / -branch-refresh-interval
    → dsh-emacs-modeline-*). No compatibility aliases are retained — saved
    customizations must be renamed to keep working.
  • Manual context-window options removed (dsh-emacs-footer-context-window
    / -alist): the ctx% segment is driven exclusively by the server's
    session/projection context window.
  • HTTP polling fallback removed (dsh-emacs-poll-*): the WebSocket event
    stream is the only automatic reply channel; recovery happens via stream
    reconnect or manual refresh (C-c C-r).

Added

  • Queue and steer while a turn runs: C-c C-c no longer only interrupts —
    per dsh-emacs-busy-enter-behavior (queue / steer / stop) input is queued as
    the next turn or wakes the running agent; C-c C-q manages the queue
    (dsh-emacs-list-queue: e edit, s steer, d delete, RET send now,
    x clear all), C-c C-b interrupts, a [Q2 S1] mode-line indicator and a
    next-input preview at the prompt mirror the server's session/queue frames.
  • Session switching: dsh-emacs-switch-workspace-session (C-c C-s)
    within the current workspace, dsh-emacs-switch-session (C-u C-c C-s)
    across all workspaces; candidates match exactly what dsh web shows.
  • Project-aware session creation: new sessions inherit the current buffer's
    directory, auto-detect the project root (project.el / VC root / .git walk)
    and land in that project's workspace, created idempotently on first use.
  • Interactive approval prompts: approval/requested frames answered in the
    minibuffer via /api/respond, serialized with ask questions.
  • Notifications: run-finished and interaction (question/approval)
    notifications when the chat buffer is not visible
    (dsh-emacs-enable-notifications).
  • Filter-free question chooser: 1–9 (0 = 10th) pick an option
    immediately, t switches to free text; per-question skip key (s).
  • Per-session input history: dsh-emacs-input-history-cross-session
    chooses M-p/M-n scope; history seeded from the transcript, never lost on
    toggle.
  • Inline image attachments rendered in the chat transcript.
  • Remote dsh servers first-class: non-loopback / HTTPS URLs probed and used
    directly (5s cap), userinfo/basic auth on probe, WebSocket and RPC, no local
    CLI spawn.
  • Mode-line: opt-in provider segment, segment tooltips and hover
    highlight.
  • Contributor tooling: scripts/verify.sh aggregates every
    machine-checkable verification step into one exit-code gate.

Changed

  • scripts/verify.sh now gates byte-compilation (Error fails the gate,
    warnings stay allowed).
  • scripts/check-lisp.el became diagnostics-only (ordered root-cause report
    instead of an auto-fixer).

Fixed

  • Stream reconnect no longer doubles the transcript (replayed mux frames gated
    by seq anchor; reconnection itself no longer fails on a reused events buffer).
  • A fast second submit can no longer double-send; failed sends restore the
    draft.
  • Mode-line spinner reliably stops at turn/end even when a very fast run
    finishes before the prompt callback fires.
  • M-p/M-n recall works on first entry of a session.
  • Collapsed blocks no longer crash with void-variable old-body when new
    chunks stream in.
  • C-g on a question abandons the whole group like dsh web (protocol
    cancelled receipt); replayed questions are never asked twice.
  • ctx% reflects the server and survives failed runs, zero-sample re-submits
    and incomplete session rows.
  • C-c C-r renders history into the issuing chat buffer; prompt images reach
    the model as content parts; cursor stays on the input line and never rests on
    the prompt icon; sending with an empty queue no longer flashes queued:
    feedback.

Full changelog: https://github.com/vritser/dsh-emacs/blob/v0.2.0/CHANGELOG.md