Changelog¶
1.0.0 (2026-07-28)¶
Highlights¶
Clauster 1.0 is the first stable release — a self-hosted dashboard for spawning and managing Claude Code remote-control bridges on your own host. Highlights since 0.12.9:
- Claude Code config management, in the browser. A full dashboard editor and gated write API for a project's entire Claude Code config surface — CLAUDE.md, settings/env, permission rules, hooks, MCP servers, subagents, skills, and plugins/marketplaces — across User / Project / Local scopes, each behind a type-the-name confirm with secret masking. The release's largest new capability.
- Multiple sessions per project, with reliable resume. Run several interactive sessions per project (each in its own git worktree) alongside a standard bridge, fork any past conversation into a new session, give sessions custom names, and rely on a hardened self-heal path so a restarted bridge never comes back idle with no session.
- The dashboard reports what is actually running. Bridges are tracked per instance rather than per project, so every session gets its own card instead of one silently displacing the rest; Resume survives a restart instead of vanishing from stopped cards; and when the one-Server-Mode-bridge-per-project cap would decline a resume, the card says so before you click, rather than reporting a success that never happened.
- Windows & cross-OS parity. Interactive (true-resume PTY) sessions now run on Windows over ConPTY, the hosted channel speaks Windows named pipes, and state writes are hardened — bringing Windows to parity with POSIX across the 3-OS test matrix.
- Drive it headless: CLI, MCP, and a versioned API. Operate Clauster entirely from the
terminal with no server running (
clauster projects/status/sessions/logs/open,start/stop), inspect sessions from any MCP client, and integrate against a versioned/api/v1with named, revocable bearer tokens. The stdio MCP surface is read-only by default — it is local-privileged and unauthenticated, so the tools that spawn, stop and resume sessions are opt-in behindmcp.allow_writes. - Re-authenticate from the dashboard. A browser login flow (
claude auth login/setup-token) plus a header pill that surfaces a logged-out runtime account before a bridge silently hangs — no more SSHing in to fix auth. - Security & supply-chain hardening. Dropped
unsafe-evalfrom the CSP, auto-provisioned self-signed TLS, a correct reverse-proxyroot_pathguard, and an MCP-approval preflight that stops silent hangs. - Smaller, signed distribution. A slimmer Alpine/musl Docker image with pinned packages,
first-class
uninstallscripts, and an optional-extras lifecycle where the standalone binary bundles pip and side-installspty/notifyon demand. - Committed to SQLite. Storage is now SQLite-only (the unsupported Postgres
database_urlis gone), with an automaticclauster.dbsnapshot before every migration.
Read Breaking Changes below before upgrading, and UPGRADING.md for the step-by-step. The three most likely to need action from you:
- Cross-site requests are now blocked even with no password set. If you reach the
dashboard at anything other than a loopback address at its configured port — a LAN bind,
a tunnel or reverse proxy, an SSH forward onto a different port — that address must be in
auth.allowed_originsor your buttons and live views stop working. It fails visibly, not silently. A default loopback deployment needs no change. - The Docker base moved to Alpine. Derived images must use
apkrather thanapt, andsu-execreplacesgosu. clauster mcpchanged twice. Its write tools now default off (above), and a bridge'sidis its unique instance id rather than the project name — if you consumelist_sessions, readprojectfor the name.
Breaking Changes¶
- The Docker image now uses an Alpine (musl) base with explicitly pinned, Renovate-tracked apk packages instead of Debian slim with an unpinned
apt upgrade; it is smaller and drops the Go-basedgosu(nowsu-exec). Derived images must useapkrather thanapt. (#944) - The
clauster mcpwrite tools (spawn_session/stop_session/resume_session) are now gated behind a newmcp.allow_writesconfig key that defaults off, so the local-privileged, unauthenticated stdio MCP surface is read-only by default and its--help/banner no longer understate its capability (#1010); setmcp.allow_writes: trueto restore the #950 write tools. (#1066) - The cross-site
Originallowlist is now enforced even whenauth.enabledis false (the shipped default), closing a CSRF / WebSocket-hijack hole: previously the HTTPguardmiddleware returned before the Origin check and all four WebSocket routes short-circuited theirs, so a page the operator merely visited could drive unsafe requests against the loopback dashboard (trust a directory, resume a bridge, clone a repo, restart) and read-stream live session output. With auth off the gate rejects only a present, non-allowlistedOrigin— an absent one (a CLI/script client, never a browser) still passes. A loopback bind auto-allows127.0.0.1/localhost/[::1]at its configured port, so the default deployment needs no change; an auth-off deployment the browser reaches at any other address — a non-loopback bind, a tunnel or reverse proxy, or an SSH port-forward onto a different local port — must now list that origin inauth.allowed_origins, the same setting an authenticated deployment in those positions already needs. It fails closed and visibly, never silently (see UPGRADING.md). (#1070) - Live sessions are now attributed to the bridge that actually owns them, so a Server Mode bridge no longer lists a project's independent Interactive Sessions as its own; the MCP
list_sessionstool no longer repeats a session once per bridge, and a bridge'sidis now its unique instance id (breaking: it was the project name — see UPGRADING.md). (#1082) - Commit to SQLite for storage and remove the unsupported
database_url(Postgres) config key; a leftoverdatabase_urlin your config is now ignored rather than rejected. (#801)
Features¶
- The Advanced config panel now edits list and map fields too (#978):
clone.allowed_schemesandclone.allowed_private_cidrsget a rows editor (add/remove entries), andwebhooks.eventsgets a checkbox per known lifecycle event (each shown at its correct default, saving only the events you change). These join the existing Advanced scalars behind the sameconfig_writecapability + step-up re-auth. Secret URL lists (webhooks.urls,notifications.urls) and auth trust lists stay file/CLI-only — their masked values can't round-trip a browser edit safely — and every write is still fail-closed, re-validated (bad CIDR / unknown event rejected), and audited by key-name only. (#982) - New Advanced config surface (#978): the operational-but-sensitive
clone.*andwebhooks.*scalars are now editable in-app behind theconfig_writecapability and a step-up re-auth —POST /api/reauthre-proves the operator password for a short unlock window, andGET/PUT /api/config/advancedgate on that fresh proof. Lockout/exposure/RCE keys (bind, auth switches,ui.enabled, TLS, binaries,config_write.*,login_shepherd.*) stay file/CLI-only, and every Advanced write is fail-closed (backup + atomic replace) and audited by key-name only. (#979) - The config editor now has an Advanced settings panel (#978): when config-write is enabled, the
clone.*andwebhooks.*scalars are editable from the dashboard behind a step-up re-auth — re-enter your password to unlock a short window, edit, and save through the same "restart to apply" flow. A wrong password shows an inline error and keeps the panel locked; the unlock window expiring mid-edit re-prompts rather than silently failing. Network bind, authentication, and TLS stay file/CLI-managed. (#980) - Launching a bridge over the API now reports whether it was newly created or an existing one was reused, and each project's metrics add up across all of its bridges. (#797)
- Add two optional per-launch controls for standard (server-mode) bridges: a custom session name shown in claude.ai/code in place of the project name, and a sandbox toggle (OS-level filesystem/network isolation). Both default to no change and persist across resume. (#811)
- New headless read commands —
clauster projects,status,sessions,logs, andopen— drive clauster from the terminal with no server running (add--jsonfor scriptable output), sharing one engine with the web UI. (#927) - New headless write commands —
clauster start <project>andclauster stop <instance>— spawn and stop bridges from the terminal with no server running, sharing the web UI's engine, mode policy, and validation (--mode,--trust,--json). (#928) - Completes the config-change audit trail's subprocess-visibility slice (#958 Part 6): MCP and plugin writes now record the redacted
claude mcp/claude pluginargv the CLI actually ran, and the before/after file fingerprints (path + SHA-256 + size, never contents) now cover the reset-project-choices, approvals, plugin, and marketplace handlers too — not just MCP-server writes. Soconfig_audit.loganswers both "where did this change land?" and "what ran?" for every CLI-driven config mutation. (#977) - The config-change audit trail now records, for each MCP-server write, which config files the change actually touched — by path, SHA-256, and byte size (never the file contents). Because
claude mcpdoes Claude Code's own bookkeeping across several files, this makes the subprocess's side effects visible inconfig_audit.logand answers "where did this change land?" without exposing any secret values. (#976) - Every config-write is now recorded to a single
config_audit.logaudit trail — one JSON line per change across every surface (CLAUDE.md, settings, permissions, hooks, MCP, approvals, subagents, skills, plugins, marketplaces), capturing the surface, scope, target file, action, actor, and the top-level key names touched (never the values). Generalises the previous CLAUDE.md-only edit audit so a config change can be traced to where it landed. (#969) - Add a Config management panel to the dashboard (when config-write is enabled) for editing your project's CLAUDE.md and settings.json across User/Project/Local scopes, with a type-the-name confirm and secret masking. (#828)
- Add an MCP tab to the Config management panel to add, edit, and remove MCP servers at project, local, or user scope, and to approve or reject each committed project server. (#831)
- Add Permissions and Hooks tabs to the Config management panel for editing a scope's tool-permission rules and lifecycle hooks, behind the same type-the-name confirm. (#829)
- Add a Plugins tab to the Config management panel to enable, disable, install, uninstall, and update plugins, and to add, remove, and update marketplaces — each gated by the type-the-name confirm, with an extra retype-the-id confirm on install. (#833)
- Add a Skills tab to the Config management panel to list, create, edit, and delete your project or user skills (their SKILL.md), behind the same type-the-name confirm. (#832)
- Add a Subagents tab to the Config management panel to list, create, edit, and delete your project or user subagents (built-in and plugin agents are shown read-only). (#830)
- Add a CLAUDE.md config-write surface (user/project/local scope, edit/blank, gitignore-on-create for the local file) — content is never redacted, unlike other config-write surfaces, since it's prose, not secrets. (#818)
- Add a
localscope to the config-write API (MCP servers, permission rules, hooks) for project-only settings, gitignoring any newly created local config file automatically. (#813) - MCP servers can now be added/removed/edited through Claude Code's own
claude mcpCLI (secrets travel via env, never the command line), plus project approval enable/disable and a reset-approvals action — all behind the existing config-write gate. (#822) - Add a plugins + marketplaces config-write API (enable/disable/install/uninstall/update, marketplace add/remove/list/update) driven through
claude plugin, gated behind the existing off-by-default capability plus a strong per-plugin confirm on install. (#827) - Add a config-write API for
env/model/miscsettings.jsonkeys at user/project/local scope, plus a scope-merge provenance view showing each key's effective value and source layer. (#823) - Add a skills config-write surface (user/project scope; list/view/add/delete +
skillOverridesenable/disable at all three scopes) — plugin skills stay read-only, uploaded scripts need an extra confirm and are never executed, and skill content is redacted on read. (#825) - Add a subagents config-write surface (list/view/add/edit/delete at user/project scope) — Claude Code's own built-in and plugin-provided agents are shown but refused as read-only. (#824)
- Harden the dashboard's Content-Security-Policy by removing
unsafe-evalfrom script-src. (#788) - Run several interactive sessions per project from the dashboard, each with its own controls and isolated git worktree, plus a warning when two would share the same working copy. (#800)
clauster deps install claustrumnow side-installs the Direct Session daemon — the standaloneclaustrumbinary the hosted live-view channel needs. It downloads the pinned, SHA-256-verified release for your OS/arch (Linux/macOS/Windows × x86_64/arm64) fromschubydoo/claustruminto<state_dir>/deps/bin, and Clauster's daemon launcher uses it automatically (an explicitclaustrum.binaryor aclaustrumonPATHstill wins). Fail-closed like the other managed binaries — a checksum mismatch refuses — and surfaced inclauster deps list/doctor(the doctor line only appears whenclaustrum.enabled). The pin auto-bumps via Renovate. (#984)- New
clauster deps list/install/uninstall <extra>side-installs the optionalpty/notifyextras into<state_dir>/depsfor the standalone binary (which adds that directory to its import path at startup), behind an explicit unsigned-wheel confirmation. (#933) - First-run setup wizard (#978): running
clausterwith noclauster.ymlnow serves a small, loopback-only setup page instead of exiting with an error. Enter your projects folder, bind address, and a dashboard password, and it writes a config with authentication enabled, then restarts onto it. The wizard binds127.0.0.1:7621by default (override withCLAUSTER_SETUP_PORT) and gates the submit to a loopback origin, so only a local operator can complete setup. (#981) - The standalone binary now bundles
pip, soclauster deps install <extra>runs on it directly (no separate Python needed);clauster deps install shawlprovides the pinned, checksum-verified Shawl service wrapper thatinstall-service windowsnow uses instead of nssm; and the uninstaller enumerates the side-installed extras/Shawl and can preserve them with--keep-deps. (#936) - The config panel's Hooks surface gains a friendly rows editor — add/remove one command hook per row (event, matcher, command, timeout) instead of hand-editing the nested JSON; rows sharing an event + matcher are saved as one group, and raw JSON stays as the escape hatch for shapes the rows can't show. Commands are stored verbatim and never run by Clauster. (#973)
clauster stop/logs/open, the MCP tools and the API now accept a unique instance-id prefix, refusing an ambiguous one instead of guessing. (#1113)- Add an opt-in, auth-gated dashboard panel that drives a
claude auth login/claude setup-tokenflow so an operator can re-authenticate the runtimeclaudeaccount from the browser instead of SSHing in. (#846) - The dashboard login panel now points operators at the non-interactive runtime-account auth options (
ANTHROPIC_API_KEY,CLAUDE_CODE_OAUTH_TOKEN,apiKeyHelper) so they can be set from the config editor without SSH, with docs on which to use when. (#925) - The
clauster mcpserver gains write tools — an MCP client can now spawn, stop, and resume bridge sessions (not just observe them). Trust is never auto-granted:spawn_sessionrequires an explicittrust: truefor an untrusted directory. (#950) - The
claude.node_from_nvmsetting now defaults to on: bridges resolve nvm'sdefaultnode and put itsnode/npx/npmplus nvm-global CLIs (e.g.agent-browser) on the bridgePATHin every spawn context (not justbash -c).clauster doctorwarns when an nvm toolchain won't reach spawned bridges; set the option false to opt out. (#859) - Add an opt-in
claude.node_from_nvmsetting that puts your nvm-managed Node on the bridge's PATH, fixing npx/node MCP servers that failed to start under systemd. (#803) - The config panel's Permissions surface gains a friendly rows editor — add/remove
allow,deny, andaskrules and pick a default mode from a list, instead of hand-editing raw JSON (raw stays as the escape hatch for shapes the rows can't show).askrules are now accepted by the permissions write surface. (#972) - Automatically back up
clauster.dbbefore running a database migration, keeping the last 5 snapshots understate_dir/backups/. (#804) - Interactive Session launches gain a Conversation picker (More options): fork any of the project's past conversations into the new session — the original stays untouched. (#948)
- Add a versioned
/api/v1public API with named, revocable bearer tokens (clauster api-token issue/list/rotate/revoke) and an optional OpenAPI docs page (api.openapi_enabled, off by default). (#805) - Allow one standard bridge and several interactive sessions to run side by side within a single project. (#789)
- The Settings config surface now offers a friendly key/value row editor for the
envmap (add / edit / remove), with the raw-JSON view kept as an escape hatch for other keys. (#879) - The config panel's subagent editor now treats the Name box as the single source of the agent's name — it's written into the frontmatter
name:automatically on save (the backend requires the two to match), so you no longer type it twice. New agents start from a small frontmatter template that omitsname:. (#974) - Add
tls.provision = self-signedto auto-generate and renew a self-signed HTTPS certificate at startup, stored understate_dir/tls/. (#790) - Add
ui.enabled(defaulttrue) to optionally run Clauster as a JSON-API-only deployment with no browser dashboard. (#810) - Add an
uninstall.sh/uninstall.ps1counterpart to the install scripts: it auto-detects the install method (standalone binary or uv/pipx/pip/scoop), removes the binary/package, the service unit, and the state directory + config, with--dry-run,--keep-config/--keep-data, a confirmation prompt, and fail-closed path safety. (#881)
Fixes¶
- The dashboard now wraps its content in a single
<main>landmark and carries a page<h1>, so assistive tech can navigate its regions and every content node sits inside a landmark (resolves the dashboard's remaining moderate axe landmark/heading findings). (#963) - The config editor's section jump-nav now includes an Advanced chip whenever the password-gated Advanced panel is available, so the panel is discoverable without scrolling to the bottom. (#1052)
- The frozen binary now completes its first-run database migration under a non-UTF-8 locale (#1015):
alembic.iniwas ASCII-cleaned soconfigparserno longer crashes on an em-dash when the binary starts with noLANG/LC_ALLagainst a fresh database. (#1055) clauster api-token issue/rotate/revokenow accept the token label either as a positional argument or with--label— previously the three verbs disagreed (issuerequired--labelwhilerotate/revoketook a positional), soapi-token revoke --label Xerrored. (#962)config_audit.logis now size-rotated (#1011): at ~5 MB the current file becomesconfig_audit.log.1, older files shift up, and anything past 5 rotated files is dropped — so the config-write audit trail is bounded at ~30 MB instead of growing unbounded on a long-lived instance. Rotation is best-effort (a rotation error is logged and never blocks the already-best-effort audit append), so a committed config write is never held up by it. (#1062)- Docs: co-locate auth safety caveats with the options they qualify — proxy identity is admission not access control (networking + security),
auth.enabled/allow_unauthenticated_networkreference rows now carry their fail-closed context, and the public-API unauthenticated note states its loopback-only premise. (#992) - A Background session that is not registered on claude.ai now requires a first prompt — launched blank it would idle at "send a prompt to start" forever with no way to receive one; the launch popover marks the field required and the dispatch API rejects it with a 422. (#1053)
- The claustrum preflight (
doctor, the session-start panel, anddeps list) now resolves the binary the same way the daemon spawns it (#1013): a configuredclaustrum.binary— the documented workaround for systemd's minimal PATH — counts as present instead of a permanent false "unavailable" warning, anddeps listagrees withdoctorinstead of reporting the same binary two different ways. (#1057) clauster doctornow reports the detected claustrum daemon version and warns — advisorily, never as a failure — when it can't be confirmed at or above the release clauster pins (#1013): an unstamped/dev build or an older release is surfaced rather than silently assumed compatible, and a manageddeps/bininstall shadowed by a differentPATH/configured binary now raises abinary:claustrum:shadowwarning so you know which copy actually runs. Completes the claustrum-preflight follow-up (Bug 3–5). (#1060)- On Windows the claustrum daemon is now launched with
-listen-pipe, so it opens the named-pipe listener the Windows client dials (via therpc.pipefile beside the socket); POSIX keeps using the AF_UNIX socket unchanged. (#900) - Teach the claustrum client to reach the daemon over a Windows named pipe (discovered via the
rpc.pipefile beside the socket) on Windows, where asyncio cannot consume the AF_UNIX socket; POSIX keeps using the AF_UNIX socket unchanged. (#893) - On Windows the claustrum daemon is now spawned with
-token-fileinstead of-token-fd 0(a numeric fd is not a usable token handle for the Go daemon there), so clauster can start and drive a hosted-channel daemon over the named pipe. (#902) - The Clone button now stays disabled until you enter a Git URL, so an empty clone no longer shows a raw error. (#762)
- A restart no longer hides stopped sessions: every persisted instance is now rebuilt on its own row, instead of collapsing to one card per project. (#1118)
- The config editor now tells a feature switch what it needs (#1016 Part 2): a switch whose optional dependency is missing — Direct Sessions (the
claustrumbinary), notifications (apprise), the live-terminal view (pyte) — shows a "Requires … — runclauster deps install …" note and can't be turned on, so you learn what a feature needs at the moment you'd enable it instead of finding it silently dormant. Availability is resolved exactly the way the runtime resolves it (honoring a configuredclaustrum.binary), so a dependency that IS present never greys out its switch. (#1064) - Config-panel feedback now scrolls into view when it appears: arming a delete focuses its type-to-confirm input, and an Advanced save brings its success/error banner into the visible scrollport instead of leaving it hidden above the fold. (#1050)
- Fix the config editor's section tabs stretching into full-width bars when they wrap onto multiple rows. (#758)
- Fix the config editor's section jumps so the heading you click lands below the sticky nav instead of hiding under it. (#759)
- Config panel fixes: clearing a JSON surface (Settings/Permissions/Hooks) and saving now treats a blank box as the empty default instead of rejecting it as invalid JSON, the typed scope confirm-token no longer lingers when you switch surface tabs, and the last inline
styleattributes were converted to classes so the panel no longer trips thestyle-srcCSP. (#960) - The config panel's "Show merged (effective) view" toggle now carries a disclosure caret and
aria-expanded— matching the panel's other expand/collapse toggles — instead of rendering as easy-to-miss plain text. (#975) - Internal: simplify effective-settings scope-merge computation to remove an unreachable branch (no behavior change). (#826)
- The config-management MCP, permissions, and hooks surfaces now return 404 (not 422) for an unknown scope while config-write is disabled, so a disabled surface can't be fingerprinted. (#835)
- The hooks config-write API now rejects plugin-owned hook commands — manage those via the plugin, not this surface. (#817)
- The config panel no longer rejects valid Skills and Subagents that carry forward-compatible frontmatter keys (e.g.
effort,license,metadata), and no longer masks a benignauthorfield as a secret. (#959) - Broaden the automated test suite and tighten coverage checks to guard against regressions. (#808)
- Cross-OS robustness: reject Windows reserved device names (
CON,NUL, …) as project names, honestly report a Windows background-agent stop (a hard kill, not a false clean stop), don't mislabel a transient clone-finalize failure as "already exists", preflight the AF_UNIX socket-path length for macOS, and warn whennssmis absent for the Windows service install. (#917) - Headless CLI/MCP writers now serialize spawn/stop against the running server on a per-project cross-process lock, and state saves merge onto the store's current contents — a bridge can no longer be double-launched and a forgotten record no longer resurrects (#949). (#951)
- Config and CLAUDE.md writes now share one cross-process lock held on a file in the state dir, so the editor and config-write paths mutually exclude across processes without leaving a
CLAUDE.md.lockartifact in project directories. (#921) - Fix unreadable text selection in the dark theme: selected text in the config editors (and elsewhere) now renders as white on a solid Signal-Blue field (WCAG-AA 5:1) instead of Tabler's near-invisible default tint. (#970)
- Fix the dashboard hiding running Server Mode sessions when a project has more than one bridge. (#1144)
- Close short-lived database engines' SQLite connections deterministically instead of leaving them for the garbage collector, which emitted spurious
unclosed databasewarnings on Python 3.13+. (#890) - Internal cleanup: share one SHA-256 hash helper across the config modules (no behavior change). (#753)
- The dashboard now shows a header pill when the runtime
claudeaccount is logged out, and/healthzreports its auth state (claude_login_ok/claude_login_method, covering OAuth, API-key, and helper logins) — so a stale login surfaces before a bridge silently hangs at "Starting". (#844) - Completing the first-run setup wizard on a non-loopback bind now records the origin you reached it at in
auth.allowed_origins, so the login that follows succeeds. The wizard wrote no origins at all, andbuild_allowed_originsauto-allows loopback only when the bind host is itself loopback — so on the0.0.0.0bind the Docker image forces, setup completed onto an empty allowlist and the very next request, the login POST, was refused with403 origin check failedwith no way back into the dashboard short of hand-editing the generatedclauster.yml. The origin is recorded only for a bind that auto-allows nothing, only from a submit that already cleared the wizard's own gate (the setup token, or the loopback Origin check), and only when it parses as anhttp(s)origin; a loopback install's generated config is unchanged. The bundledcompose.yamland the installation guide now setCLAUSTER_AUTH_ALLOWED_ORIGINStoo, which covers the same failure on the environment-configured path that never runs the wizard. (#1077) - The first-run setup wizard now works in Docker (#1017): it writes
clauster.ymlto the persistent/configvolume (CLAUSTER_CONFIG) instead of the container's ephemeral layer, and — withCLAUSTER_SETUP_HOST=0.0.0.0(baked into the image) — binds a reachable interface gated by a one-time token printed to the container log, so a published port can complete first-run setup without hand-writing config or an SSH tunnel. (#1067) - docs: new
reference/cli.mdcatalogues every subcommand, ending the CLI scatter across installation/operations/README (#1007) - Docs: new operator-facing "How it works" page with a runtime-topology diagram, and a glossary defining the vocabulary (bridge, keeper, Server Mode / Interactive Session / Direct Session, spawn modes) the docs previously used before defining. (#1004)
- docs: DB-snapshot rollback must delete stale
-wal/-shmsidecars, not keep them (the snapshot is a self-containedVACUUM INTOcopy) (#1009) - Docs: the in-app config editor gets its own guide page, the first-run setup wizard now leads the quickstart config step, and the login shepherd is discoverable from the docs home and quickstart. (#1002)
- docs: installation decision table — pick an install method by platform/updates instead of reading all ten sections (#1008)
- Docs accuracy: warn that the on-disk bridge log is not redacted by default (SUPPORT + operations), and replace the stale README claim that
claustrumis not distributable with theclauster deps install claustruminstruction. (#990) - docs: split configuration.md into a how-to guide (
guides/configuration.md) and the generated key reference (reference/config.md), with a redirect from the old URL (#1006) - Docs: platform support is now a scannable capability × OS matrix on its own reference page, and the site ships an
llms.txtmap that states the bind/auth safety invariant for assistants. (#1005) - Docs site: new symptom-first Troubleshooting page, journey-grouped navigation (Start here / Concepts / Guides / Reference / Operations / Project), and the root UPGRADING / CHANGELOG / CONTRIBUTING / SUPPORT / SECURITY files now appear on the published site. (#994)
- Update the README and docs feature lists to describe the full dashboard Claude Code config editor (CLAUDE.md, settings/env, permissions, hooks, MCP, subagents, skills, plugins) instead of just the CLAUDE.md editor it started as. (#883)
- List-valued config keys can now be set from the environment, and dict-valued keys no longer advertise a variable that crashes startup. Eight
list[str]keys — includingauth.allowed_origins, which an auth-on deployment behind a proxy, tunnel, or non-loopback bind needs — were mapped to aCLAUSTER_*variable whose raw string was assigned straight into the field, so setting the documented variable failed config validation withInput should be a valid listand the process never started; env-only deployments (Docker/Compose in particular) had no way to set them short of hand-editingclauster.yml. Values now split on commas or newlines — the newline form so a*_FILEsecret file can be written one entry per line, which previously collapsed into a single unusable entry — with surrounding whitespace trimmed and blank entries dropped. Note that an empty value now means an empty list rather than falling through to the YAML value, soCLAUSTER_AUTH_ALLOWED_ORIGINS: ""in a Compose file clears a configured allowlist (it fails closed, refusing origins rather than allowing them). An entry containing a literal comma — an Apprise URL innotifications.urlswith comma-separated query targets, say — still has to be set in the YAML file. The threedictkeys (projects,claude.env,webhooks.events) genuinely cannot be addressed by one variable and are now omitted from the env map entirely rather than being discoverable-but-fatal, matching what the configuration guide already documented. (#1075) clauster.yml.exampleagain shows theconfig_writeandlogin_shepherdsections (withallow_user_scope/allow_setup_token) as commented-out defaults with a one-line explanation and a pointer to the config reference (#1012). The #983 declutter had dropped them, so a new operator starting from the example couldn't discover the config-management panel or the login shepherd — the surfaces the 1.0 test-plan pre-flight tells testers to enable. (#1061)- An external terminal/SSH
claudesession sharing a running bridge's directory now stays labeled external instead of being folded in as one of the bridge's managed sessions. (#874) clauster doctornow reports each optional extra (pty/notify) as OK or WARN with an install hint, and the dashboard's live-terminal control renders greyed with that hint when the tap is enabled but thepyteextra is missing instead of silently vanishing. (#919)- Forgetting a stopped Interactive Session now also clears its saved pointer, so the next launch registers a fresh session instead of silently reattaching one that was archived or deleted out from under it (#671). (#868)
- Document that in forward-auth (header-only) mode,
trusted_ipsmust list only your proxy's own IP — a broader range lets anyone reachable there bypass authentication. (#754) - Config-editor validation failures now surface a per-field, plain-language message (e.g. "clone.allowed_private_cidrs: '…' does not appear to be an IPv4 or IPv6 network") instead of the raw pydantic dump with internal model names and error URLs. (#1054)
- Internal frontend cleanup: dedupe shared helpers, drop dead code, and add reusable template macros (no behavior change). (#784)
clauster doctorand the dashboard preflight panel no longer nag about the optionalapprisedependency when notifications aren't actually going to send (#1016): theextra:appriserow now appears only whennotifications.enabledis set and at least onenotifications.urlsentry is configured — matching when runtime actually imports apprise. (pyte/pywinptystay ungated: pyte also reassembles the bridge connect-URL and pywinpty is the Windows Interactive-Session backend, so they matter beyond the opt-in live-terminal view. Binary deps like claustrum were already gated on their feature switch.) (#1063)- The per-launch sandbox toggle is disabled for this release (#1037). Evidence from the pre-RC dogfood showed
--sandboxreached the remote-control bridge but was never passed to the server-mode session worker that runs Bash, so the security-labeled control silently did nothing — a "fail closed visibly" violation. The launch popover no longer offers it, thesandboxAPI/CLI/MCP parameter is accepted-but-inert (coerced todefault), and any persistedon/offon a stopped card resumes safely asdefault. It returns behind dependency preflight + platform gating in #1046. (#1059) - A Direct Session's
instance_idnow persists across a clauster restart (both the JSON and DB hosted-state backends), so a client-cached id keeps resolving instead of 404ing against a freshly re-minted one. (#843) - The Direct Session (hosted) lifecycle API endpoints — stop, resume, forget, and message — now accept a session's
instance_idin addition to itsclaustrum_process_id, so an API client can address a session by whichever id it already holds. (#840) - Stop hosted sessions from spawning duplicate processes when resumed twice at once, reject an unknown
permission_modewith a clear 422, and finish pending notifications cleanly on shutdown. (#757) - Fix the Windows owner-only ACL so a stuck
icaclsno longer fails the state write — it now logs a warning and proceeds on the inherited permissions, restoring the best-effort contract. (#920) - Fix the CLI and MCP server reporting stale, incomplete bridge state, and bridges started from the CLI rendering as EXTERNAL/unmanaged in the dashboard: instance liveness is now persisted and read per instance rather than resolved per project, so every bridge on a project is visible to every process and can be stopped by its own id. (#1109)
- A long or hostile line in a project's config file can no longer stall the dashboard's secret-redaction pass. (#1123)
- Password managers no longer autofill a saved username into the launch popover's First prompt and Session name, which could otherwise become a bridge display name. (#1122)
- The launch popover now closes as soon as you hit Trust & start, instead of lingering through the whole spawn. (#761)
- Cap the live transcript at the most recent 1000 turns, with a "showing last N" indicator, so long sessions stay responsive. (#787)
- An abandoned dashboard sign-in no longer wedges every later attempt: the login panel rehydrates its in-progress flow after a page reload (so Cancel is reachable), and a flow left idle for 15 minutes is reclaimed by the next sign-in. (#1081)
- The dashboard's long-lived
setup-tokenlogin now runs on Windows over a ConPTY (pip install 'clauster[pty]'), with the operator-pasted code redacted from returned output since a ConPTY echoes input back. (#912) - The dashboard
claude setup-tokenlogin now waits for the authorize URL to be stable across two polls before showing it, so a URL caught mid-render (split across the pty reader's chunks) is never surfaced truncated. (#856) clauster logsnow withholds a half-flushed line until it completes, so redaction can never miss a secret split across two reads. (#1111)- The MCP Server-approvals panel now reflects approvals that live in the settings files (top-level
enabledMcpjsonServers/disabledMcpjsonServers, whereclaude mcp add-json --scope local|userrelocates them), so a server approved that way no longer shows as un-approved. A settings-owned approval is shown read-only (markedsettings), since it can only be changed on the settings surface or viaclaude mcp— the panel no longer offers an approve/reject/unset that would silently revert on reload. (#961) - The unapproved-MCP-server launch preflight now also treats a server decided (enabled or disabled) in a project's
.claude/settings.json/settings.local.jsonor the user~/.claude/settings.jsonas decided — matching which sources claude actually honors — so it no longer falsely warns about a server that shows no enable gate. (#857) - Launching an Interactive Session in a project with unapproved committed
.mcp.jsonservers now soft-blocks with an error-styled confirm (it would otherwise hang at claude's MCP approval prompt and never connect): a "Resolve in Server approvals" button, a "Launch anyway" override, and block-by-default. Resolving the servers refreshes the check so the next launch proceeds. (#858) - The per-project readiness check now warns when a committed
.mcp.jsonhas servers pending approval, since an interactive (pty) launch hangs invisibly at claude's MCP-approval prompt otherwise — resolve them in Server approvals first. (#845) - The MCP
list_sessionsread tool no longer writes the shared state store or fires crash webhooks and notifications. (#1110) - Modals no longer close when a text-selection drag that started inside the dialog releases over the backdrop — only a click that both starts and ends on the backdrop dismisses (Escape and the close button are unchanged). (#1049)
- Password managers no longer offer to fill non-credential dashboard fields (#1036). Every non-password
input/textarea— config-editor rows, launch popovers, the clone URL, the first-run setup wizard — now carries the per-vendor opt-out attributes (data-1p-ignore/data-lpignore/data-bwignore/data-form-type="other") alongsideautocomplete="off", which Chromium Autofill and the manager extensions ignore on its own (crbug 468153). Applied in the templates (a{{ NO_AUTOFILL }}global) so Alpinex-forrow clones and the Alpine-free setup page inherit it. The login and setup password fields deliberately omit it, so your manager still fills/saves credentials. (#1065) - The launch popover's First prompt and custom session name fields no longer get autofilled by a password manager — they were the only opt-out inputs without an explicit
type, which is enough for a manager to skip the opt-out entirely. (#1095) - Dismissing the first-run orientation card now collapses it to a light "No projects yet" hint instead of a near-identical block. (#802)
- A stopped card that shadows a live unmanaged Server Mode bridge is pruned again — the check now finds the bridge above a working session, whose own pid is the SDK worker rather than the bridge. (#1119)
- Fix Stopped session cards vanishing when an unrelated
claudehappened to be running in the same project folder, and stale phantom cards never being cleaned up while another session on that project was live: the dashboard's phantom-prune now decides per instance rather than per project, and only treats an external session as a bridge when its command line actually is one (including the--rcform, which it previously failed to recognise). (#1109) - An Interactive Session whose preserved session was archived or deleted while stopped now surfaces as an error on restart — instead of a misleading "running" bridge that sits idle with no session — and its stale pointer is cleared so the next launch starts fresh (#671). This is the backstop for when the pre-launch check can't confirm the session (e.g. credentials unavailable). (#870)
- Fix the launch popover's consent gates squeezing their explanation text to about two words per line: Tabler's
.alertis a flex row, so the trust, bypass-permissions and MCP-approval gates laid their explanation and controls out side by side until an explicitdisplay: blockrestored stacking. (#1098) - Fix the black strips that appeared around the live terminal after resizing or zooming. (#791)
- Publish the repo's contributor conventions:
AGENTS.md(machine-facing) +CLAUDE.mdare now committed, and CONTRIBUTING gains the branching/review workflow (linear history, squash-merge, Greptile review). (#991) - The PyPI page now renders its README links correctly (they were repo-relative, so every one 404'd there) and the package is classified
Development Status :: 5 - Production/Stable. (#1085) - Remove the outdated "v0.3 — multi-user" line from the README; clauster is single-operator by design. (#786)
- Stop the environment reaper archiving a live bridge owned by another clauster instance or OS user: it filtered an account-wide environment list against an instance-scoped live set, so any bridge outside this instance's
projects_rootread as a leftover and could be archived mid-session — such an environment is now unattributable and skipped. (#1102) - The in-app restart (
POST /api/restart) and the first-run setup wizard's post-completion restart now work on the frozen binary (#1014):_reexecno longer passes the binary path twice in argv (a PyInstaller one-file build hassys.executable == sys.argv[0]), which previously aborted withunrecognized argumentsand left the server dead — masked only where a service manager restarts on exit. (#1056) - Internal cleanup: dedupe config-write helpers and tighten type annotations (no behavior change). (#783)
- Say up front when a stopped Server Mode card can't be resumed because its project already has a live bridge. (#1151)
- Resuming a stopped bridge now revives the same session instead of creating a duplicate entry. (#799)
- The auth and web-UI guards now strip the configured
root_pathbefore matching routes, so path classification stays correct behind a reverse proxy that does not strip the mount prefix (defense-in-depth; the supported prefix-stripping proxy is unaffected). (#880) - A blank
auth.password_hashcan no longer be logged in with.verify_passwordreturned success for any falsy stored hash, so an empty-string hash (reachable viapassword_hash: ""or a present-but-emptyCLAUSTER_AUTH_PASSWORD_HASH) made the source-visible dummy password a working credential for both/loginand the/api/reauthstep-up. Success now requires a real configured hash, and a blank or whitespace-onlypassword_hashnormalizes tonullat config load — mirroringapi_token_hash— so the value is refused at both layers. The constant-time dummy verify still runs, so no timing oracle is opened. (#1070) - An MCP server credential carried in a URL query string (
?api_key=…), a URL fragment, or a stdioargselement is no longer serialized intoclaude mcp add-json's argv, where any local user could read it fromps//proc/<pid>/cmdline. The keep-secrets-off-argv guard (entry_needs_direct_write) only recognizedenv/headersvalues andscheme://user@hostURLs, which key-name redaction cannot see past; it now fails closed on a URL with a query, userinfo, or fragment component, on a non-emptyargslist, and on an unparseable URL, routing those entries to the direct (non-spawning) writer that produces identical on-disk state. A credential embedded in the URL path remains uncovered — every hosted-MCP URL has a path, so that needs a field-allowlist redesign. (#1070) clauster restore --config-outnow writes the restoredclauster.ymlatomically at mode0600instead of copying it at a umask-derived0644. The config carries the argon2auth.password_hash(andapi_token_hash), so the old behaviour published it to every local user for offline cracking — and with--forceit actively relaxed an existing0600file. The write now goes through amkstemptemp (created owner-only) and an atomic replace, so the hash is never briefly world-readable, a failed restore leaves no permissive file behind, and a symlink sitting at--config-outis replaced rather than written through to an unrelated file. The destination's parent directory is deliberately left alone, since--config-outis often a shared location. (#1070)- The
.baksibling that a local-scope settings write leaves beside.claude/settings.local.jsonis now gitignored too. Only the exact target path was ignored, so the backup — a plaintext copy of the previousenvmap, this surface's one secret-bearing shape — sat un-ignored next to it and could be swept into a commit bygit add -Aand pushed.ensure_gitignoredgained an opt-inignore_backup_siblingflag, set by all four writers of that file (settings, hooks, skill overrides, permissions), and those writers now run it before the write rather than after — so a failure between the two steps can no longer leave the secret-bearing backup trackable. (#1070) claude setup-token's authorize URL is now recovered from its OSC 8 hyperlink, so the dashboard login shepherd can read it under a Windows ConPTY where the terminal emits the URL as a hyperlink rather than plain text. (#909)- Internal cleanup from a slop-cleanup sweep: share the Anthropic HTTPS transport + client base between the environments and code-sessions clients, collapse the duplicate
~/.claude.jsonatomic-writer onto the shared core, and tighten a few return/param types. No behavior change. (#873) - Launching an Interactive Session now pre-checks the preserved session and, if it was archived or deleted, clears the stale pointer so the launch starts fresh instead of reattaching a dead session and coming back idle (#671). Best-effort — it never blocks a launch, and leaves the pointer untouched on any uncertainty. (#869)
- The startup warning for an ignored
database_urlno longer cites an incorrect version. (#835) - On startup, clauster now garbage-collects its own stale bridge pointers — only those that are both non-live and older than a 14-day retention window — so long-dead pointers stop accumulating (#671). A live bridge's pointer, or a recently-stopped session's (still resumable), is never touched, and any error is logged, never fatal to startup. (#871)
- Restore Resume on a stopped Server Mode session after a restart, and stop a declined resume reporting success. (#1147)
- Fix the live transcript on a running session so turns no longer duplicate or lag, and the oldest/newest sort toggle now applies to the live feed with a matching label. (#751)
- Add a read-only Transcript button to the live desktop/bridge session row (hidden for worktree interactive sessions, whose transcript lives under a different working directory). (#918)
- The Transcripts selector (and the resume/fork picker that shares its endpoint) now opens near-instantly on unchanged transcripts (#1035): each file's
turn_countplus the picker's label/timestamp fields are cached on a(mtime, size)stamp instead of re-parsing every.jsonlon every open — which stalled ~20 s on a project with a large transcript. Any append/change re-derives, so the listing stays correct. (#1058) - Trim
clauster.yml.examplefrom a dense inline-manual (247 lines, ~71% comments) to a concise quick-start template: one terse hint per key, verbose prose moved to the docs, all keys and defaults preserved. (#882) - Widen the launch popover so the trust-on-start text reads comfortably instead of wrapping to a word or two per line. (#760)
- The README's feature catalogue is now a short summary that links to the docs site rather than restating it, and SUPPORT.md documents the release cadence (event-driven; security fixes immediate, regressions within days). (#1083)
- The dashboard now offers Interactive Session on Windows when the ConPTY keeper (the
ptyextra) is installed, instead of always hiding it — the mode-picker gate was stale after Windows ConPTY support landed. (#916) - Harden Windows state/config file writes: a best-effort owner-only ACL on the state dir, an in-process write lock serializing clauster's own concurrent writers, a retry over transient file-sharing violations, and LF (not CRLF) output. (#915)
- Interactive Session (true-resume PTY) now runs on Windows: the keeper drives the bridge over a ConPTY pseudo-console via pywinpty (
pip install 'clauster[pty]'), falling back to Server Mode when the extra is absent. (#903) - Cancelling or finishing a Windows login no longer stalls for five seconds and leaks a reader thread when the CLI leaves a child process behind. (#1126)
- On Windows, stopping a poisoned bridge, a timed-out clone, or a stuck claustrum launcher now kills the whole process tree instead of leaving its children running. (#1127)
- Conversations from sessions spawned in a git worktree now appear in the pty launch popover's Conversation picker (which branches a new session off a past conversation, leaving the original untouched), resolve when selected, and count toward the project's token rollup. A worktree session runs with the worktree as its cwd, so Claude files its transcript in a sibling
~/.claude/projects/<sanitized-cwd>/directory; every reader keyed on the project root alone, so those conversations were invisible to the picker (a project whose only main-dir transcript was live showed just "New conversation") and their tokens were missing from usage. The project's own directory and its worktree siblings are now searched together. Because sanitizing a path collapses/,.,-and_all to-, a directory name cannot be mapped back to a path unambiguously — a sibling project named<project>--claude-worktrees-xproduces a name carrying this project's worktree prefix — so every candidate that is a real sibling project's directory is excluded, and an unreadable projects root skips the worktree scan entirely rather than admitting an ambiguous one. The session resolver accepts the same directory set (its per-directory parent-identity check and stem validation are unchanged, so a crafted session id still cannot escape), and the liveness join counts worktree sessions too, keeping the listing and the live set in lockstep — otherwise a running worktree session would have shown as dormant and been offered in a picker meant for finished conversations, branching from one still being written. (#1076)
0.12.9 (2026-06-29)¶
Features¶
- Confirm before cancelling an in-progress clone, and reattach a second browser tab to its live progress instead of showing nothing. (#708)
- Make the
log_formatsetting editable from the in-app config editor. (#705) - Add an opt-in, off-by-default surface for editing Claude Code hooks (project + user scope) from the config editor. (#740)
- Add an opt-in, off-by-default surface for editing MCP server config (project + user scope) — no dashboard UI yet. (#732)
- Add an opt-in, off-by-default surface for editing permission rules — no dashboard UI yet. (#738)
- Internal: lay the groundwork (off-by-default gate, type-the-name confirm, automatic secret redaction) that the new hooks/MCP/permissions editors build on. (#706)
- Add
clauster mcp, a read-only MCP server exposing session status to any MCP client. (#710) - Add an opt-in
CLAUSTER_PYTE_PATHenvironment variable so standalone-binary users can enable the live terminal view by installingpyteseparately. (#702) - Live-tail a running session's transcript in the read-only viewer as the agent works. (#709)
Fixes¶
- Harden the dashboard's Content-Security-Policy further by removing
unsafe-inlinefromstyle-src. (#635) - Fix pty bridges intermittently showing "No web link — use Logs" instead of the actual connect link. (#721)
- Unify the launch and permission mode labels into a single source, so the picker, inline UI, and config editor never disagree. (#729)
- Simplify the launch flow into a single-screen popover: advanced options tuck under "More options," and Desktop stays the default launch mode. (#731)
- Fix a failed trust-on-start leaving the launch popover hidden instead of showing the error. (#739)
- Add a dismissible first-run orientation card explaining what Clauster is and how to start. (#728)
- Fix a freshly-spawned bridge's session briefly appearing as an unmanaged "phantom" row while the bridge is still starting. (#714)
- Internal: harden the atomic file-writer against a rare file-descriptor leak on write failure. (#718)
- Hide a deprecated config field once it's removed from disk, and stop
config reconcilefrom re-offering an already-set replacement. (#703) - Fix the progress-bar fill and non-name sort layout breaking under the stricter
style-srcCSP. (#742) - Fix the live terminal failing to render under the stricter
style-srcCSP. (#743) - Correct the docs: the live terminal IS available on the standalone binary via
CLAUSTER_PYTE_PATH; the install guide now also listsclauster hash-metrics-tokenandclauster config reconcile. (#717) - Fix a rare mis-render in the hosted live-event stream past 1000 lines. (#720)
- Fix a 500 error when stopping a hosted session that a concurrent forget/resume already removed. (#715)
- Fix
clauster keepersmislabeling live, dashboard-managed keepers as orphans, risking--killreaping them. (#719) - Point the live terminal's "unavailable" message on the standalone binary at the real fix (
pip/uvinstall with[pty]) instead of a dead end. (#700) - Internal: speed up the dashboard's project-sort endpoint by batching its per-project queries. (#716)
- Replace ad hoc emoji in the dashboard with consistent Tabler icons. (#704)
0.12.8 (2026-06-28)¶
Features¶
- Add a Cancel button to the in-progress clone flow, with a confirmation toast when a clone is cancelled. (#684)
- Add an optional
tlsconfig block so Clauster can terminate HTTPS directly using an existing certificate and key, validated fail-closed at load and at startup, with a non-fatal warning if the private key file is readable by others. (#695)
Fixes¶
- Fix several inaccuracies in the public docs and add an automated check to prevent them recurring. (#683)
- Fix Interactive Session (PTY) launches failing under the standalone binary. (#697)
- Rename session-type terminology across the UI and docs to match Anthropic's Remote Control vocabulary (Server Mode / Interactive Session / Background Agent / Direct Session). (#681)
0.12.7 (2026-06-27)¶
Features¶
- Add an in-app "Restart Clauster" action to the config editor so a saved config change can be applied without dropping to a shell, exposed via an auth-gated
POST /api/restart. (#637) - Add a browser-notifications channel with per-channel and per-event toggles for ready, stop, permission-needed, session-ended, and reconnect-failed events. (#636)
- Add
clauster config reconcile, an interactive CLI command that removes deprecated config keys and writes their replacements. (#650) - Add a server-side cancel for an in-progress clone so the UI abort actually stops the git transfer. (#633)
- Badge a transcript as live in the read-only viewer when its session id maps to a currently-running bridge, agent, or hosted session. (#653)
- Scale the read-only live terminal to fit the panel width on narrow viewports (e.g. phones). (#654)
Fixes¶
- Add a copy-paste Claude Code install +
claude loginstep to the Quickstart guide, and make the doctor version-FAIL message suggestclaude update. (#649) - Fix the project-sort cap: changing sort no longer flashes the full list, and returning to A–Z restores the 6-row cap and "Show all N" toggle. (#655)
- Correct the Claude Code install docs (native installer, not the deprecated npm package) and the clone dialog's helper text, which now names the
clone.allow_private_hostsconfig key and clarifies that cloning only fetches files. (#658) - Project sort: selecting a non-name sort (Last used / Cost) no longer uncaps the list past the 6-row limit. (#661)
- Lower the default
claude.agents_json_poll_interval_secondsfrom 300 to 30, so session liveness and crash detection refresh within ~30 seconds instead of up to 5 minutes. (#662) - Fix the in-app Restart: the page reloads once the server is back (no more stuck "Restarting…"), and the confirmation now correctly says running sessions survive the restart instead of warning they end. (#666)
- Browser notifications now prompt for permission the moment you enable the channel instead of only after a reload, and a failed bridge resume only raises the "reconnect failed" notification when the bridge genuinely could not restart. (#668)
- The config editor now flags when browser notifications can't be delivered (non-HTTPS connection, unsupported browser, or blocked permission) and disables the toggle instead of silently offering a setting that won't work. (#675)
clauster config reconcile --dry-runis now non-interactive: it prints the plan and writes nothing without prompting. (#667)
0.12.6 (2026-06-27)¶
Fixes¶
- Fix the in-app config editor's dropdowns (Launch mode, Usage badge mode, and every other selector) showing the first option instead of the actual saved value, which also left Save greyed out after re-picking the real value. (#644)
- Fix the config editor showing stale pre-save values after a save until a restart —
GET /api/confignow reads current values from disk instead of the in-memory startup config, so a successful save no longer looks reverted (the change still only takes effect on restart). (#645) - Fix the dashboard's per-bridge live-session count never appearing for a
spawn_mode: worktreebridge, whose sessions run in per-project git worktrees and were previously misclassified as external/untracked. (#646)
0.12.5 (2026-06-27)¶
Features¶
- Add an opt-in trusted-header reverse-proxy mode (
auth.reverse_proxy.require_hmac: false) so SSO proxies that don't sign a per-request HMAC (Authelia, authentik, Caddy, Traefik, oauth2-proxy) can authenticate viatrusted_ips+user_headeralone, and makereverse_proxy.enabledwithouttrusted_ipsfail fast at startup instead of silently authenticating no one. (#617) - Add a read-only in-dashboard transcript viewer: a per-project "View transcript" button opens a modal listing each session's history (newest-first) with paginated, redacted turns. (#611)
- Add the read-only live PTY terminal view: when
claude.pty_screen_enabledis on, each pty bridge gets a "Live terminal" button that streams a redacted, auth-gated view of the session over/ws/pty-screen, and the flag is now toggleable from the in-app config editor. (#640) - List every live session under a standard
claude remote-controlbridge: an Active-session card now expands to enumerate each working session with a short-UUID label, uptime, and a per-session deep link into the Claude web app. (#618) - Add an in-app help page: a
?icon in the navbar opens a panel covering launch modes, permission modes, the dashboard zones, and session types, with a link to the README. (#619) - When a non-git project's default spawn mode is
worktree, the "Run Claude here" popover now falls back tosame-dirand shows a note rather than letting the server reject the spawn, keeping the picker and trust-on-start confirm reachable. (#615) - Add a sort-direction toggle (newest-first / oldest-first) and a search box to the transcript viewer; search only matches against already-redacted content, so it can never reveal a masked secret. (#616)
- Add an
instance_defaults.verboseconfig toggle (default off, editable from the config editor) for detailed connection/session logs on standard bridges; pty bridges are intentionally never passed--verbose. (#642)
Fixes¶
- Rename the "Fire-and-forget" /
detachedsession type to "Background" consistently across the launch picker, filter chip, and card badge. (#567) - Show the live-session list from the first live session on a standard bridge (not only at two or more), giving each session its own
claude.ai/codedeep link; the toggle label is now singular/plural-aware. (#622) - Fix two dashboard error-UX papercuts: the default-session Stop button now asks for confirmation like every other destructive action, and error toasts persist until dismissed instead of auto-vanishing after 4.5 seconds. (#627)
- Fix the config editor's "restart Clauster to apply" help link, which pointed at a broken README anchor; it now targets the Operations runbook's restart section. (#624)
clauster.yml.examplenow usesprojects_root: ~/code(matching every prose doc) instead of/srv/projects, which contradicted the docs and hard-failed validation if copied as-is on a box without that directory. (#625)- Correct the
webhooks.block_private_targetsconfig-field description, which incorrectly claimed DNS hostnames are not resolved (the SSRF guard does resolve them); documentation only, no behavior change. (#598) - a11y: the clone-progress bar now announces its progress to screen readers/assistive tech via proper ARIA value attributes. (#607)
- The "Recap prior transcript on restart" config toggle is now always editable instead of greyed out when the default launch mode isn't
standard; an informational note explains it applies to standard bridges only. (#600) - Update the README's "First bridge in 60 seconds" walkthrough to match the current UI (button labels and the actual relaunch steps). (#605)
Security¶
- Redact a failed clone's
error_detail(git stderr) on the progress WebSocket, matching the redaction already applied on the clone-done webhook path. (#606)
Build System & Dependencies¶
- Internal: vendor xterm.js 6.0.0 as the foundation for the upcoming live pty terminal view (no user-facing behavior yet). (#631)
- Internal: add a pyte-backed module for the upcoming live pty terminal view, with
pyteas an optionalptyextra kept out of the default install (no user-facing behavior yet). (#634) - Internal: add the keeper-side live-screen capture (gated on
claude.pty_screen_enabled, needs the optionalpyteextra) that renders the bridge's terminal into a redacted, cells-only sidecar, as groundwork for the live-terminal view; no WebSocket or UI yet. (#638) - Internal: add the
/ws/pty-screenWebSocket endpoint that streams the keeper's redacted, cells-only terminal frames to the browser, as groundwork for the live-terminal view; no UI yet. (#639)
0.12.4 (2026-06-25)¶
Fixes¶
- Fix the live bridge-log tail going dead after a service restart and bridge reattach, showing "Live tail disconnected" for a bridge that was actually still alive; reattached bridges now re-bind their log tail correctly, and the Reconnect button now always retries instead of becoming a no-op after auto-reconnect gives up. (#595)
- Fix
clauster install-servicegenerating an invalid service unit command for standalone-binary and console-script installs; the unit now invokes the entry point directly on systemd, launchd, and Windows/nssm. (#588) - Fix
clauster install-serviceso the generated systemd/launchd units bake in a usablePATH(~/.local/binplus standard system dirs) instead of a minimal default, so spawned bridges can resolve user-local tools likeuv/ruff/pytest; a unit comment now points operators atclaude.path_append/claude.envfor shell-managed toolchains (nvm/pyenv/cargo/go). (#593) - Fix the hosted live-view rendering each assistant reply twice; a successful turn now collapses to a "turn complete" marker, with full text still shown on error (e.g. "Not logged in · Please run /login"). (#596)
- Fix clauster-spawned hosted (claustrum) sessions being misclassified as external/unmanaged, which also left a stale Active card next to the Stopped one after Stop. (#594)
0.12.3 (2026-06-24)¶
Features¶
- Make the Claustrum (hosted live-view) config block editable in the config editor: the
claustrum.enabledtoggle plus its operational fields (socket_path,spawn_timeout_seconds,keep_children,request_timeout_seconds) can now be changed in-app instead of by hand-editingclauster.yml, withclaustrum.binaryintentionally left non-editable. (#563)
Fixes¶
- Replace Unicode emoji with consistent Tabler icons for the tool and permission-decision badges in the hosted transcript view. (#558)
- Make the project name truncate at a viewport-relative width instead of a fixed cap so long names adapt to the screen, and validate that the Active-list "Open in Claude" link is an
http(s)URL before using it. (#546) - De-jargon the opt-in Maintenance panel: "Reap ghost environments" becomes "Clean up leftover environments," with plainer copy and a "Permanently delete — this can't be undone" label on the destructive action. (#554)
- Config editor fixes:
usage.modeis now authoritative over the deprecatedusage.show_costalias, the transcript-recap toggle greys out under the pty launch mode where it has no effect, the bridge-log retention settings (logs.retention_max_age_days/_max_files/_max_total_mb) are now editable in-app, and a blankusage.currency_symbolfalls back to the default instead of showing an empty badge. (#564) - Security hardening: validate the reverse-proxy
trusted_ipsallowlist as IP/CIDR at load instead of silently never matching, and make the opt-in webhook SSRF guard (webhooks.block_private_targets) resolve DNS hostnames so a hostname pointing at an internal IP is blocked too. (#565) - Config editor: the Default permission mode dropdown now shows the same friendly labels as the "Run Claude here" launch menu instead of bare enum tokens, the recap size limit greys out when transcript recap is off, and the "Where new sessions run" and "Enable metrics line" descriptions were rewritten to say what they actually do. (#544)
- Internal: fix a hosted-session stream-subscriber leak that could accumulate over failed spawns/reattaches and natural agent exits (no user-facing behavior change). (#552)
- Fix the live-tail "reconnecting…" and "disconnected" banners appearing even while the log was actively streaming. (#538)
- Dashboard polish: replace raw enum tokens with friendly labels across the Run button, hosted-session rows, Active-zone filter chips, and config editor dropdowns, and fix two accessibility gaps where form inputs weren't properly associated with their labels. (#547)
- Projects zone: the "Show all / Show fewer" toggle and 6-row cap now apply to every sort order (not just A–Z), and a project with a live session is never hidden by the cap. (#545)
- Fix the PTY keeper crashing on hosts with many concurrent bridges or open file descriptors (previously hit a hard 1024-descriptor ceiling). (#557)
- Security: fix the
sk-…token redaction pattern to also match underscores, so an Anthropicsk-ant-…key could previously leak into the bridge debug log or live-tail stream unredacted. (#551) - Fix a race where stopping a bridge immediately after launch could leave it running but untracked by Clauster. (#553)
- Dashboard: unify the two pre-launch warning vocabularies so both the header and per-project pills read as "readiness checks" instead of mixing in "preflight" jargon. (#560)
- Rename the confusing
claude.resume_modeconfig key toclaude.launch_mode; the old key and itsCLAUSTER_CLAUDE_RESUME_MODEenv var still work as deprecated aliases (with a warning), andlaunch_modewins if both are set. (#561)
0.12.2 (2026-06-23)¶
Features¶
- Add an optional sort control (Name / Last used / Cost) to the Projects zone — it stays in the default A–Z order until you pick a different sort, which then reveals every project ordered by recency or cost. (#528)
- Track bridge/session lifecycle events (spawned, ready, ended, crashed) with cost/token snapshots, powering new per-project "last used" and total-cost rollups. (#514)
- Add three new webhook events —
bg-settled,permission-needed, andclone-done— each off by default; opt in per-key underwebhooks.events. (#518) - Add an opt-in SSRF guard for webhooks — set
webhooks.block_private_targets: trueto block webhook URLs that resolve to loopback, link-local, private, or other non-routable addresses (including the cloud-metadata IP) — off by default, so existing private-network receivers keep working. (#529) - Add the new Clauster brand — a theme-adaptive logo lockup in the dashboard navbar, login and 404 pages, plus a refreshed favicon and the full logo kit in
assets/logo/. (#494) - Extend the bridge subprocess
PATH/env fromclauster.ymlviaclaude.path_appendandclaude.env(both standard and pty modes), so aclaudesession can resolve user-local tools a minimal servicePATHomits. (#504)
Fixes¶
- Align hosted-session status badge colors with the bridge map:
startingis azure,stoppingis orange, andcrashedis amber (recoverable via Resume) instead of red. (#505) - Fix a transient "could not persist bridge state" warning that could appear under concurrent bridge-state writes. (#501)
- Fix a malformed
keeper_pid/bridge_pidvalue (e.g.true/false) resolving to PID 1 instead of being treated as absent. (#500) - Document the three
logs.retention_*knobs inclauster.yml.example. (#502) - Fix Forget failing to clear a dead background agent when
claude rmsoft-fails — clauster now drops the orphaned record itself once the worker is confirmed dead. (#506) - Fix the live-tail "reconnecting" and "disconnected" banners overlapping, and stop the disconnect banner from claiming the bridge may have stopped while it's still running. (#507)
- Document the config-file search order (
$CLAUSTER_CONFIG→./clauster.yml→$CLAUSTER_HOME/clauster.yml) inclauster --help. (#522) - Fix a pty bridge surviving a clauster restart being orphaned as a stopped card or leaking an uncontrolled keeper process — it's now reattached as a running instance. (#535)
Security¶
- Gate inline scripts with a per-request CSP nonce and drop
unsafe-inlinefromscript-src. (#532) - Store the
/metricsscrape token as a SHA-256 hash at rest (observability.metrics_token_hash), matching the API token; mint one with the newclauster hash-metrics-tokencommand. (#503)
Build System & Dependencies¶
- Internal: add a
changeset-autodraftworkflow that auto-drafts a changeset fragment on trusted PRs touchingsrc/. (#530)
0.12.1 (2026-06-20)¶
Fixes¶
- Harden two inputs surfaced by new fuzz tests: a malformed
Originheader port no longer trips a 500 in the CSRF/CORS check, and a non-dict~/.claude.jsonno longer crashes project discovery. (#492) - Fix toast notifications rendering ~50% transparent instead of fully opaque, so they stay readable over busy page content. (#484)
0.12.0 (2026-06-19)¶
Features¶
- Add a Resume action for ended background agents. (#336)
- Add an API-token (Bearer) auth primitive. (#360)
- Harden login lockout for the reverse-proxy case. (#358)
- Add
clauster keepersto stop an orphaned pty keeper that isn't attached to any card. (#301) - Support
CLAUSTER_*_FILEsecret indirection for config values. (#368) - Wire up the session-name-prefix and capacity bridge config knobs. (#294)
- Internal: lay the persistence foundation (SQLAlchemy 2.0 + Alembic) that later session-history features build on. (#362)
- Add a per-project preflight readiness pill. (#335)
- Add an in-app config editor with safe, allowlisted writes. (#299)
- Adopt a standard external session into a managed bridge. (#330)
- Add a richer display for external sessions. (#300)
- Gate the hosted launch mode on
CLAUSTRUM_ENABLED. (#375) - Add Homebrew/Nix installer support for macOS x86_64 and Linux arm64. (#289)
- Add JSON logging, enabled via the
log_formatconfig key. (#361) - Add retention and rotation for bridge debug logs. (#348)
- Enrich the
/metricsendpoint and add a scrape token. (#352) - Add HTTP security-headers middleware. (#439)
- Show whether a session is cloud-visible (bridge) or local-only (hosted) in the UI. (#343)
- Add outbound lifecycle webhooks — the first extension point for integrating with other tools. (#371)
Fixes¶
- Announce live updates to screen readers, honor reduced-motion preferences, and fix a dead-end in the Active filter. (#384)
- Fix toast accessibility labeling, the hosted status dot, and a double-submit race on Resume. (#447)
- Fix unbounded memory growth from stale login-throttle entries. (#436)
- Fix
clauster keepersmisclassifying or killing the wrong process by checking the keeper's command line, not just its PID. (#470) - Internal: pin the atheris fuzzing dependency per Python interpreter so the 3.11 CI leg keeps a working wheel. (#464)
- Fix hosted live-view frames being dropped by sizing the subscriber queue to hold a full replay snapshot. (#437)
- Internal: correct the repo-config settings baseline (homepage URL, has_projects flag). (#325)
- Internal: add a drift check that verifies admin-only merge flags in the repo config. (#328)
- Fix bridge-state persistence not handling a disk-write failure gracefully. (#435)
- Fix config backup files being written with default umask permissions instead of matching the source file's mode. (#469)
- Apply a batch of low-severity security hardening fixes. (#452)
- Fix login/logout form submissions losing their Origin header by setting
Referrer-Policy: same-origin. (#465) - Fix the bridge-log live tail stranding instead of auto-reconnecting after a drop. (#419)
- Cap hosted live-view reconnect attempts to match the bridge-log tail's behavior. (#444)
- Clarify the permission-mode labels, the missing connect-URL case, and which config changes require a restart. (#457)
- Fix the Recent zone being hidden by the live-session filter. (#451)
- Fix a detached session's action button always reading "Stop" regardless of whether it's actually live. (#332)
- Fix the Recent group being labeled "resumable" even when it isn't. (#334)
- Fix action buttons getting stuck in a busy state after a failed request, blocking further clicks. (#401)
- Fix the hosted live-view dropping frames and failing to repaint through a reverse proxy. (#315)
- Show a crashed bridge's error detail directly on its card. (#321)
Performance¶
- Cache project discovery and batch the first-paint preflight checks for a faster initial load. (#440)
- Serve per-bridge metrics from a server-side cache. (#354)
- Sample bridge metrics concurrently instead of serially. (#407)
- Batch the live-metrics poll through a single
/api/metricsrequest. (#438) - Cache the usage/transcript rollup so it's not recomputed on every request. (#455)
- Gzip responses and set immutable caching for versioned static assets. (#353)
0.11.0 (2026-06-15)¶
Features¶
- Add one-line installers for Scoop, Homebrew, and Nix, with automatic version bumping on release. (#287)
0.10.0 (2026-06-15)¶
Features¶
- Make
install-service --writeinstall the systemd unit directly, and givedoctoran actionable fix for it. (#267) - Add a Forget action to clear a stopped session from the Recent/resumable list. (#268)
Fixes¶
- Fix the SessionStart recap hook failing under the frozen one-file binary. (#279)
- Clarify the launch Mode label and restrict the Spawn selector to the standard bridge. (#265)
- Fix unclickable Stop/Kill/Resume buttons on detached and hosted sessions, and correct the claude.ai framing in the UI. (#266)
Performance¶
- Internal: shrink the hosted stop-grace period so the test suite isn't 30 seconds slower. (#275)
0.9.0 (2026-06-14)¶
Features¶
- Add cloud-deregistering stop for background agent sessions. (#218)
- Add the ability to dispatch a
claude --bgbackground session. (#215) - Add a read-only background-agents panel. (#214)
- Wire dispatch and stop buttons into the background-agents panel. (#220)
- Make the usage badge configurable with currency conversion and a tokens-only mode. (#192)
- Add
--resumerespawn for a lost hosted session. (#236) - Internal: add the claustrum daemon connect-or-spawn lifecycle that hosted sessions run on. (#229)
- Internal: add the claustrum NDJSON JSON-RPC client and a fake-daemon test fixture — foundation for hosted sessions. (#224)
- Internal: add the hosted-channel session engine. (#230)
- Add a live-view UI for hosted sessions. (#233)
- Detect and recover orphaned hosted sessions after a daemon restart. (#237)
- Add an approve/deny permissions UI for hosted sessions. (#234)
- Persist hosted sessions so they reattach automatically across a clauster restart. (#235)
- Internal: wire the hosted channel into the app. (#231)
- Redact the session URL in the on-disk bridge log. (#200)
- Add crash notifications via Apprise (optional extra). (#197)
- Add a per-project preflight endpoint (
GET /api/projects/{name}/preflight). (#193) - Default the systemd unit to
KillMode=processso pty bridges survive asystemctl restart. (#206) - Redesign the dashboard into two zones and migrate icons to Tabler Icons. (#248)
Fixes¶
- Fix a stop being reported as clean when no live worker was actually found. (#255)
- Fix ghost WebSocket tasks stalling shutdown by ending send-only handlers on client disconnect. (#243)
- Enforce the bypass-permissions ceiling on hosted and background-agent channels too. (#249)
- Show a friendly HTML 404 page for browser navigation, and unify project-not-found wording. (#247)
- Ensure
session.secretcreation is durably written to disk. (#261) - Internal: always run CodeQL so docs-only PRs aren't blocked by the code-scanning branch rule. (#196)
- Fix a batch of correctness and robustness issues found in a clean-room audit. (#252)
- Bump the Docker base image to clear stale OpenSSL CVEs. (#216)
- Fix the live metrics line rendering twice in the rows layout. (#190)
- Fix an oversized claustrum frame killing the hosted-session reader instead of being handled gracefully. (#256)
- Fix a permission-allow race with updated tool input, and a stop exit-latch race, in hosted sessions. (#242)
- Resolve parked permission requests on exit, and fix hosted live-view double-wiring. (#254)
- Fix the claustrum daemon inheriting a stray daemonize sentinel from its spawn environment. (#241)
- Surface a session's terminal state in the hosted live-view, and stop it endlessly reconnecting to a dead session. (#245)
- Fix incorrect working-directory attribution for some agent-view session kinds/states. (#213)
- Fix a truncated first line in the live-tail WebSocket, and write the bridge log at
0600permissions when redaction is off. (#259) - Scrub Clauster secrets from every spawned child process's environment. (#253)
- Harden state-file writes with restrictive permissions (
0700dir,0600temp file) and fsync durability. (#258) - Fix stale state lingering in the New-project dialog across close, mode-switch, and edit. (#246)
- Label the launch controls clearly, and guard the launch button against double-submit. (#260)
- Render the Active status rail and fix keyboard focus order. (#250)
- Restore the Tabler and Alpine.js attribution in the dashboard footer. (#198)
- Align status presentation across views, add an untrusted-project indicator, and gate the bypass-permissions confirmation. (#251)
- Fix the usage rollup failing on malformed token values instead of tolerating them. (#257)
0.8.0 (2026-06-07)¶
Features¶
- Add a gated Prometheus
/metricsendpoint. (#178) - Add a read-only
/api/widgetsummary endpoint. (#179) - Add a cards/rows layout toggle for the dashboard. (#173)
- Show an honest currency label on the cost badge — the symbol alone is used only for USD. (#167)
- Show live per-bridge resource metrics: CPU, memory, and disk. (#172)
Fixes¶
- Internal: stop the
@claudeCI review from cancelling itself. (#183) - Correct and clarify the permission-mode tooltip. (#165)
0.7.0 (2026-06-06)¶
Features¶
- Add an actionable call-to-action to the empty-state screen. (#159)
- Add tooltips across the dashboard card. (#158)
Fixes¶
- Internal: address four low-severity review findings. (#155)
- Fix a live, clauster-launched pty bridge being misclassified as external. (#153)
0.6.0 (2026-06-05)¶
Features¶
- Redesign the project card with clearer hierarchy and one primary action. (#143)
- Prompt to trust a directory at launch (trust-on-start). (#144)
Fixes¶
- Suppress a false "port in use" warning in the dashboard. (#142)
0.5.0 (2026-06-05)¶
Features¶
- Add
GET /api/doctor, surfacing system readiness as JSON. (#127) - Retitle the process as
clauster[<name>](a newinstance_namesetting) so it's identifiable inps/pgrep. (#130) - Recover the "Open session" deep link on a
--continueresume. (#135) - Distinguish "Interrupted" from "Stopped" on the dashboard card. (#136)
- Add a system-readiness (preflight) panel to the dashboard. (#129)
Fixes¶
- Fix a
--continueresume reading "Failed to start" while the bridge was actually running. (#134) - Fix a phantom STOPPED instance shadowing a live external bridge. (#133)
0.4.0 (2026-06-04)¶
Features¶
- Recover reboot-orphaned bridges as resumable stopped cards. (#110)
- Add a per-launch picker to choose standard or pty resume mode. (#103)
- Rename "Restart" to "Resume" and add a warned "Start new session" action. (#101)
- Add a
usage.show_costtoggle to hide the cost badge. (#121)
Fixes¶
- Fix file reads and writes to always use UTF-8 encoding instead of the platform default. (#122)
- Fix a bridge's resume mode to stay fixed at launch instead of following live config changes. (#100)
- Fix a rare race where PID reuse could cause a dead bridge to be reported as alive. (#104)
- Harden the transcript-recap boundary against prompt injection. (#105)
- Fix a race that could lose concurrent writes to
~/.claude.json. (#108)
Performance¶
- Internal: speed up the test suite from 48s to 14s (parallelize with xdist, cap the ready-timeout test at 15s). (#111)
Build System & Dependencies¶
- Sign release artifacts (sdist/wheel) with Sigstore and attach them to each GitHub Release. (#114)
- Internal: adopt CodeRabbit as the automatic PR reviewer, with
@claudeas an on-demand backup. (#120) - Internal: move the Trivy image scan to main-push and cron instead of running on every PR. (#112)
- Internal: tune Codecov configuration to best practice. (#115)
- Internal: skip the coverage upload on release-please PRs. (#109)
- Internal: add an end-to-end test for the clone pipeline. (#106)
- Internal: add Windows pty-mode guard test coverage. (#107)
0.3.0 (2026-06-03)¶
Features¶
- Add a Docker Compose quickstart. (#97)
clauster doctornow checks that theclaudeCLI is logged in. (#84)
Fixes¶
- Fix a race that let concurrent spawns of the same project collide. (#91)
- Fix persisted metadata for untracked projects being wiped. (#92)
- Show the Restart action for stopped pty bridges so true-resume is reachable. (#99)
0.2.2 (2026-06-03)¶
Fixes¶
- Refuse to start on a non-loopback bind unless auth is actually enforced. (#88)
Security¶
- This is a security release. Binding to a non-loopback address (e.g.
0.0.0.0or a LAN IP) could serve the dashboard unauthenticated — even with a password configured — becauseauth.enableddefaulted tofalseand was not required for a network bind. Clauster now refuses to start on a non-loopback bind unless auth is actually enforced. All prior releases (≤0.2.1), including the Docker image, are affected. Upgrade, and setauth.enabled: trueon any networked deployment. See GHSA-h4g2-xfmw-q2c9.
0.2.1 (2026-06-03)¶
Fixes¶
- Fix README images not rendering on PyPI by using absolute GitHub URLs. (#79)
0.2.0 (2026-06-03)¶
Features¶
- Add the authentication foundation: password login, WebSocket auth, reverse-proxy trust, and
state.jsonpersistence. (b9f40eb) - Add a CLAUDE.md viewer/editor. (4bb7a6e)
- Add async project cloning with live progress over WebSocket. (#52)
- Add cost/token tracking from session transcripts. (842e6dc)
- Ship a multi-arch GHCR Docker image with an integrated Trivy vulnerability scan. (#14)
clauster doctornow warns when a source checkout is behind upstream. (#34)- Add an opt-in ghost-environment reaper UI to the dashboard. (15d50e5)
- Add a ghost-environment reaper, dry-run by default. (5a5fadd)
- Internal: add a docstring-coverage lint gate (pydocstyle) and backfill missing docstrings. (#42)
- Add packaging/ops CLIs (
doctor,backup,restore,migrate,install-service) and a PyInstaller build. (b13f5e9) - Add a per-project cost badge to the dashboard. (7d67f94)
- Add project create and clone. (599c57b)
- Add project discovery and the initial dashboard. (54591cc)
- Add real logout revocation via a server-held session epoch. (d0c37a5)
- Recap the prior conversation into a restarted bridge (opt-in). (#39)
- Resume stopped bridges and surface bridge startup errors. (#36)
- Add PTY true-resume mode (backend). (#58)
- Auto-enable remote control so bridges skip the y/n prompt. (#29)
- Add graceful stop on Windows via
CTRL_BREAK. (#13) - Add bridge spawn/stop, cross-checked against
claude agents --json. (71a5965) - Add spawn-mode and permission-mode pickers, gated to prevent risky combinations. (02c1da8)
- Show a connection-lost banner and inline action errors instead of failing silently. (#56)
- Insert new project cards reactively instead of reloading the page. (#55)
- Show a live clone progress bar with visible errors. (#53)
- Rebuild the dashboard and login page on Tabler, with dark/light theme support. (#40)
- Add a true-resume badge and recover the keeper on pty rediscovery. (#76)
- Add Iconoir icons to dashboard actions and the theme toggle. (#57)
- Show the session URL and a QR code for sessions. (d1323c4)
- Stream a redacted bridge-log tail over WebSocket. (5151fea)
Fixes¶
- Fix four UI bugs found in live testing. (ce99b3e)
- Internal: address multi-agent review findings (type/config hardening + tests; no behavior change). (39c6a43)
- Fix the session-epoch bump so it can't regress below the in-memory value. (#25)
- Fix two deferred review items: a backup error and an insecure-cookie warning. (fd8bcd6)
- Fix restore to be atomic, correct IPv6 origin handling, and bound pagination. (#30)
- Mask bare UUIDs (organization ID, bridge ID) in the WebSocket log stream. (#51)
- Internal: fix Renovate matching for vendored
versions.txt(glob instead of path-anchored regex). (#48) - Internal: stop Renovate from ignoring
src/clauster/static/vendorvia its default ignore paths. (#49) - Resolve executable paths and harden bridge spawn/stop. (#17)
- Fix a slow-but-alive bridge being marked ERROR instead of STARTING. (#27)
- Require environment registration before reporting a bridge RUNNING. (#28)
- Tolerate an unparseable process-start pointer during bridge rediscovery. (#23)
- Trust-gate CLAUDE.md and harden CSRF, throttling, secrets, and backups. (#18)
- Relabel "Resume" to "Restart" since it doesn't restore the conversation. (#38)
- Tolerate invalid UTF-8 bytes when parsing transcripts. (#22)
Build System & Dependencies¶
- Internal: sync
uv.lockwithpyproject.toml(drop the logfire dependency tree, add ruff and pyright). (48abfcd)