Repository navigation
Releases: DuJunxi1993/DSH-Shell
Release list
DSH Shell for Windows v0.2.0
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 — oneEADDRINUSEfrom 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_crashis 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
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 firstEADDRINUSE. - 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 (anexitGenerationseparates 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:
- it listens on this app's configured port;
- its parent is
1(nothing supervises it); - 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 realppid == 1stub 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
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 oftarget\releasestill 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
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+F4or 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
First deliverable. A native macOS shell for the DeepSeek Harness (dsh) web UI that:
- forks
dsh webas a child process and captures the URL line from stdout, - renders the dsh SPA inside a
WKWebViewwith a transparent titlebar and floating status badge, - cleanly tears the child down with
kill+waitpidon quit (no orphan dsh processes), - survives dsh crashes via one-shot exponential back-off restart,
- rebuilds the child PATH so
#!/usr/bin/env noderesolves 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 errorsswift test— 10/10 passingxcodebuild -scheme DSHShell— succeeds; producesDSHShell.appwith embeddedDSHShellCore.framework
Install / Build
brew install xcodegen
./scripts/generate-xcodeproj.sh
open DSHShell.xcodeproj # then ⌘RRequires 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.