Skip to content

Releases: DuJunxi1993/DSH-Shell

DSH Shell for Windows v0.2.0

Choose a tag to compare

@DuJunxi1993 DuJunxi1993 released this 24 Oct 11:18

DSH Shell for Windows — v0.2.0

The first release that is actually usable end to end: a start that fails now tells
you why, a crashed dsh is brought back, and the window behaves like a window while
it is loading.

A failed start shows the evidence, and can be retried

When the port is taken, the window used to set two lines of text and stop — so a
deliberate refusal to end somebody else's process looked exactly like a hang. It
now shows which PID holds the port, its command line, and the verdict on
whether it is ours, with Retry and Close leftovers and retry.

Scoped to our own port: listing every node.exe on the machine would be mostly
irrelevant processes with alarming names, and the one that matters would be buried.

The orphan reclaim works — and now runs before every respawn

dsh.cmd is an npm shim, so the node.exe holding the port is a child of a
cmd.exe
that stays alive as long as the dsh does. "Does it have a living
parent" was therefore true for every real orphan, and the reclaim never fired.
It now walks the whole ancestor chain and asks whose ancestor is alive: our own
shim is ours to step over, anything else alive means somebody is using it, and the
first dead parent is the break.

Under that sat a second defect: Windows reports command-line separators
doubled, so the harness marker never matched and every real dsh was refused as
"not the dsh this shell is configured to".

The reclaim now also runs before every spawn, not just at start-up: waiting
cannot free a process nobody is supervising, so a respawn that skipped it met the
same leftover and failed the same way.

The restart ladder survives a crash loop and a failed respawn

  • A failed respawn consumes a budget unit and continues into the next
    back-off, instead of ending the ladder — one EADDRINUSE from a still-draining
    socket was enough to produce an error page.
  • The budget resets on uptime (60s), not on the URL line, so a dsh that
    announces its endpoint and dies immediately is not forgiven forever.
  • Spending the budget shows the failure page, with the reason and the attempt
    count, instead of leaving the window on a dead page.

The window can be dragged while dsh loads

On the dsh page the contract paints the caption's drag strip. The shell's own boot
page is not dsh and had none, so the window could be resized but not moved until
dsh arrived. The shell now paints that band itself, on the boot page only.

Zoom is the webview's, and the readout follows a hotkey

The caption menu lists the whole 50%–200% ladder in 10% steps, with the current
rung ticked and a reset to 100%. Ctrl+−/=/0 work and are Chromium's own.
A chosen zoom survives a restart.

The status line's percentage is kept on the page rather than echoing the config:
the shell pushes a known zoom before the script runs, so the page measures the
display scale from that one point and derives every later zoom from it. A Ctrl+=
moves the readout instead of leaving it stale.

The icon is dsh's own whale, on a measured plate

The mark comes from dsh's FISH_LOGO_PATH on its FISH_LOGO_VIEWBOX — the
same geometry the macOS shell draws — rather than from dsh's favicon, which is a
different path that sat about two percent off. scripts/extract-dsh-whale.py
refreshes it from an installed dsh and commits both the geometry and the rasterised
mask, so the build needs no dsh.

The plate's colour is sampled from the supplied background, and its corner was
measured against the supplied reference: candidates rendered at the reference's
own 30px size and compared row by row give a 20% circular radius that reproduces the
reference exactly, where 12% and 22% do not.

Also

  • The menu button's bars no longer change thickness with the zoom (fractional CSS
    heights antialias differently at every scale); they are stroked SVG now.
  • The menu panel scrolls on a short window and brings the ticked rung into view.
  • auto_restart_on_crash is a real field: bounded to three attempts with
    back-off, budget reset after a minute of uptime.

Verification

122 hermetic tests against stub-dsh, cargo clippy --all-targets -- -D warnings
clean, cargo build --release clean. The reclaim was verified end to end against a
real orphan holding port 3080; the restart ladder against a new
crash-after-ready stub (three attempts at 2s/4s/8s, then the failure page, port
free and no leftover); and the boot-page drag by synthesising a drag and watching
the window's rectangle change.

Install

  • DSH.Shell_0.2.0_x64-setup.exe — NSIS, per-user, no admin needed (recommended)
  • DSH.Shell_0.2.0_x64_en-US.msi — MSI for managed installs

Requires the WebView2 Runtime (preinstalled on Windows 11) and dsh on PATH.

dsh-swiftUI v0.2.0 — a bounded ladder, and our own orphans reclaimed

Choose a tag to compare

@DuJunxi1993 DuJunxi1993 released this 23 Oct 09:24

The native macOS shell for dsh. This release is about the two ways a real dsh
crash used to end on an error screen when it should have recovered.

Auto-restart that can finish

  • A failed respawn now consumes a budget unit and continues the back-off
    ladder instead of ending it at the first EADDRINUSE.
  • The budget resets only after 60s of healthy uptime, not when the URL line
    arrives — a dsh that announces its endpoint and immediately dies is a crash
    loop, and is now treated as one.
  • A crash between the URL line and start() returning no longer races the
    ladder (an exitGeneration separates them), and a start that dies early fails
    fast instead of sitting out the spawn timeout.
  • Before respawning, the shell waits (bounded, 10s) for the dead child's port to
    come free.

Leftover dsh processes are reclaimed, not retried into

The remaining failure was a genuine orphan: a dsh web from an earlier app run
with ppid == 1, holding the port, which no amount of waiting or retrying could
dislodge. The shell now closes leftovers it can prove are its own before
spawning — the same rule Windows applies at startup
(orphan::reclaim_orphan). All three facts are required:

  1. it listens on this app's configured port;
  2. its parent is 1 (nothing supervises it);
  3. its command line runs this app's configured dshBinaryPath.

A dsh web you started in a terminal keeps that terminal as its parent, so it
is never touched. Anything that fails a fact is refused with the evidence, not
killed. Reclaims are logged and shown in the console, and the manual "Close
leftover and Retry" remains as the fallback.

Failures that explain themselves

The error screen now carries dsh's own last words, the exec detail, and the
current port holder, so a failure says EADDRINUSE with the PID rather than
"exited with status 1".

Preferences

"Open Preferences…" on the failure page and in the menu is a real SettingsLink
again; the flag it used to set raised a window that no longer existed.

Verification

  • swift test — 190 tests, 1 skipped, 0 failures. New coverage: three-attempt
    exhaustion, budget restoration after 60s, bounded port wait, reclaim-only-
    orphans, and an end-to-end test where a real ppid == 1 stub orphan on the
    port is reclaimed and the shell starts.
  • scripts/build-app.sh — release build with both JS bridges injected; smoke
    test launches, quits, confirms the child is reaped and the port released.

Requirements

A working dsh install and the dsh front-end dist built (pnpm run build in the
dsh repo). Build from source with macos/scripts/build-app.sh; the app is
ad-hoc signed, so a copy from another machine needs the one-time xattr step
described in macos/README.md.

DSH Shell for Windows v0.1.1

Choose a tag to compare

@DuJunxi1993 DuJunxi1993 released this 11 Oct 07:19

DSH Shell for Windows — v0.1.1

Two fixes to the chrome, both visible only after living with the app for a while.

The window buttons now follow the page theme

dsh ships a dark theme, and on it the minimize / maximize / close buttons were
effectively invisible. The glyphs are currentColor, which resolves to the title
bar's color: var(--dsw-alias-label-primary, #16181d) — and that fallback is
near-black. On a light page it is exactly right; on a dark one, where dsh does
not always define the alias, the buttons fell back to dark-on-dark.

The chrome now measures the surface the bar sits on and picks a foreground
with contrast against it, instead of guessing at dsh's theme tokens (which differ
per build and are not guaranteed to exist on <html> at all). It reacts to a
theme switch on its own.

Clicking one of the shell's toasts brings the window back

When the shell raises a toast — dsh failed to start, or dsh exited while you were
away — clicking it did nothing. The notification plugin shows the toast and drops
its handle, so the Windows activation handler died with it and the click was
swallowed.

The shell's own toasts now keep the handle and act on the click: the window is
restored and focused.

Installers

File
DSH Shell_0.1.1_x64-setup.exe NSIS installer — start from here
DSH Shell_0.1.1_x64_en-US.msi MSI package

Per-user install, no admin rights needed. Unsigned, so SmartScreen warns on first
run ("More info" → "Run anyway").

Launch it from the Start Menu shortcut after installing. The click-to-focus
behaviour needs the app's AUMID, which only an installed app registers. Running
the binary out of target\release still works, but its toasts show without an
activation path — that is deliberate, not a regression: claiming an unregistered
AUMID makes a toast fail to appear at all.

Known limitation

A dsh plugin's notifications — anything calling new Notification(...), such
as dsh-notification — still cannot be made clickable. The plugin owns that
toast end to end, the packaged-app activation APIs are absent from every available
windows crate, and the toast carries no launch argument to fall back on.

Upgrade

Install over the existing 0.1.0; your settings.json and dsh sessions are
untouched.

Full details: windows/CHANGELOG.md

DSH Shell for Windows v0.1.0

Choose a tag to compare

@DuJunxi1993 DuJunxi1993 released this 03 Oct 16:28

DSH Shell for Windows — v0.1.0

The first release of the Windows implementation: a native Tauri 2 / WebView2
window around the DeepSeek Harness
(dsh) web UI, owning the dsh process behind it.

This is one of two independent implementations in this repository. The macOS
SwiftUI shell lives under macos/ and has its own releases.

Installers

File
DSH Shell_0.1.0_x64_en-US.msi MSI package
DSH Shell_0.1.0_x64-setup.exe NSIS installer

Per-user install; no admin rights needed. The builds are unsigned, so
Windows SmartScreen will warn on first run ("More info" → "Run anyway").

What you get

  • Frameless window with an injected title bar. The chrome is DOM inside
    dsh's own page, and the content column is inset so nothing is occluded.
  • Zoom 50–100% in 10% steps, persisted across restarts, Ctrl + / - / 0.
  • Tray icon. Left click shows or hides. The ✕ hides to the tray and leaves
    dsh running; Alt+F4 or the tray's quit really exits and terminates dsh.
  • Single instance. A second launch raises the running window instead of
    racing dsh for its port.
  • External links open in your default browser; the window can only ever
    navigate to the boot page and the dsh origin.
  • Notifications on dsh startup failure and on dsh exiting unexpectedly, and
    support for dsh plugins that raise system notifications (dsh-notification
    verified).

Requirements

Windows 10+ with the WebView2 Runtime (preinstalled on Windows 11), and a
working dsh (npm install -g @deepseek-ai/dsh).

Full details, changes and fixes: windows/CHANGELOG.md.

dsh-swiftUI v0.1.0 — main panel

Choose a tag to compare

@DuJunxi1993 DuJunxi1993 released this 14 Aug 11:49

First deliverable. A native macOS shell for the DeepSeek Harness (dsh) web UI that:

  • forks dsh web as a child process and captures the URL line from stdout,
  • renders the dsh SPA inside a WKWebView with a transparent titlebar and floating status badge,
  • cleanly tears the child down with kill+waitpid on quit (no orphan dsh processes),
  • survives dsh crashes via one-shot exponential back-off restart,
  • rebuilds the child PATH so #!/usr/bin/env node resolves when launched from Finder,
  • exposes real exec-failure detail in the error UI (no more opaque errno -1).

Scope

This is the main panel milestone. The Git panel, file tree, and in-process terminal are planned but intentionally deferred — see docs/ROADMAP.md.

Verification

  • macOS 27, Xcode-beta (Swift 6.4 toolchain)
  • swift build — clean, 0 warnings, 0 errors
  • swift test — 10/10 passing
  • xcodebuild -scheme DSHShell — succeeds; produces DSHShell.app with embedded DSHShellCore.framework

Install / Build

brew install xcodegen
./scripts/generate-xcodeproj.sh
open DSHShell.xcodeproj   # then ⌘R

Requires a working dsh install (npm i -g @deepseek-ai/dsh) and the dsh front-end dist built (pnpm run build in the dsh repo).

See README.md for the full lifecycle diagram, settings reference, and log show one-liner for diagnostics.