claudewheel v0.24.2 /Changelog
Edit
On this page

#Changelog

#0.24.2

Remove the claude-fable-5[1m] model option, which could never differ from plain Fable 5

Context

Fable 5 runs at 1M context unconditionally. The client's model registry marks it native_1m and, unlike Opus, withholds the supports_1m_suffix flag, so a [1m] suffix on it was stripped before the request was sent -- verified end to end: selecting claude-fable-5[1m] reported model claude-fable-5 with a 1,000,000 token window, identical to the plain id.

The option therefore offered a choice that did not exist, and when an unrelated usage-credits dialog appeared it read as though 1M context were the thing being refused. It was not; direct API probes at 396k input tokens returned 200 with and without the 1M beta header.

Removing it from the defaults does not reach an options.json that already lists it, so a migration cleans values, pinned, and metadata. The entry stays in HISTORICAL_DEFAULTS, which records what ever shipped rather than what currently does -- migration 3 reads it to tell a former default apart from a user-added value.

#Fixes

  • **Removed the claude-fable-5[1m] model option.** Fable 5 runs at 1M context unconditionally, so the suffix was discarded by Claude Code and the option could never differ from plain claude-fable-5 — while making an entitlement wall look like the reason. Existing options.json files are cleaned automatically.

#0.24.1

Unblock Fable 5 on token-authed profiles by injecting the declared plan tier

Context

Claude Code reads a subscription tier from CLAUDE_CODE_SUBSCRIPTION_TYPE and only from there when auth arrives as a setup token. Its own fallback is the OAuth profile endpoint, which answers 403 for setup tokens because they are not granted the user:profile scope. The tier therefore resolves to null, and tier-dependent checks fail closed: Fable 5 is walled behind a usage-credits dialog whose only offered action is to ask an administrator, on personal accounts that have no administrator.

Every claudewheel-launched profile authenticates this way, so this affected all of them. The tier is now declared per profile in tokens.json and injected at launch, which also removes the shell-exported workaround it replaces -- that lived in one shell and was absent from every other terminal.

Declared values are validated against the sets the client actually compares against, because a value it does not recognize is inert and produces a failure identical to declaring nothing at all.

#Fixes

  • Corrected publish documentation. The contributor docs claimed CI publishes to both npm and PyPI via OIDC Trusted Publishing with no tokens; in fact only PyPI is OIDC and npm requires the NPM_TOKEN secret.
  • Valid theme file example. The theme file structure example in the theming docs used { ... } placeholders and was not valid JSON; it is now a copyable skeleton with a real key per section.
  • Fable 5 works on token-authed profiles. Profiles can declare subscriptionType and rateLimitTier in their tokens.json entry; claudewheel injects them into the launch environment. Without them Claude Code resolves the plan tier to null under setup-token auth and walls Fable 5 behind a usage-credits dialog offering no way forward.

#0.24.0

The effects regime -- a real --dry-run and confirmation only where it is earned -- plus the vanilla default profile, approved project hooks, title-based resume, Opus 5, launch-time guardrail healing, scratchpad cleanup, and a full documentation site.

Context

This release has two halves.

The first is a launch-preflight stage that heals guardrail settings against the canonical model on every launch (so upgrades can no longer leave stale safety settings on disk), and the user-facing features built on top of it. ~/.claude is now a first-class launchable "default" profile whenever it exists — fixing invisibility on setups where credentials live outside the config dir (e.g. macOS Keychain) — and launches byte-for-byte vanilla, writing nothing into it. Project-contributed hooks now require one-time approval. cw -r accepts session titles (as printed by Claude Code's resume hint, including forks). Opus 5 is selectable with a guard that blocks launches on too-old binaries. Interactive launches offer confirmed cleanup of stale /tmp scratchpad dirs, and token entries whose profile is gone are surfaced and repairable.

The second is claudewheel's adoption of strictcli's effects regime. Every subprocess launch, filesystem mutation and network call now routes through a single chokepoint, so --dry-run genuinely previews instead of writing, and every command is classified read-only or mutating. Confirmation stopped being inferred from a command being mutating and became a declaration: three commands ask (profile delete, reconcile-permissions, patch-profiles), everything else runs straight through, and --approve-consequential replaces --yes as the non-interactive consent flag.

Documentation grew from a symbol skeleton into a real site: a getting-started tutorial and guides for profiles, theming, configuration, and health checks and preflight.

Breaking: patch-profiles and reconcile-permissions prune to exactly the canonical model (the old additive, extras-preserving behavior is gone); the per-command --dry-run flags on stats, mv, import and patch-profiles and reconcile-permissions' --apply are replaced by the framework's single --dry-run flag.

#Breaking

  • **patch-profiles and reconcile-permissions now prune to exact canonical.** The old additive, extras-preserving behavior is gone; user-added hook or disallowed-tool extras are removed on sync.
  • strictcli effects regime. Every command is now classified read_only or mutating: read-only commands (health, versions, show, profile show, profile check-tokens, permission list) run unchanged, while mutating commands confirm before they write and accept the framework's --dry-run. The per-command --dry-run flags on stats, mv, import and patch-profiles, and reconcile-permissions' --apply, are replaced by that single framework flag.
  • **No more Proceed? [y/N] in front of routine work.** Confirmation is no longer inferred from a command being mutating -- it is declared. c launch, deploy-hooks, install, mv, import and the bare claudewheel that starts every session run straight through and prompt for nothing. The commands that do declare it confirm first and refuse on a non-interactive stdin unless you pass --approve-consequential (the skip flag, replacing --yes).

#Features

  • Launch-time guardrail healing. Every launch now reconciles profile and shared guardrail settings (hooks, disallowed tools, deny/ask rules) to the canonical model, so upgrades can no longer leave stale safety settings on disk.
  • Wizard token hardening. Pasted tokens are entered masked (never echoed), checked for the sk-ant- format before any network call, and recorded with an honest "expiry unknown" marker instead of a fabricated one-year expiry.
  • Resume by session title. cw -r now accepts a session title (as printed by Claude Code's resume hint, e.g. after /fork) in addition to a UUID, resolving it across project directories with a disambiguation list on collisions.
  • Opus 5 support. claude-opus-5 is available in the model picker, and launches are blocked with an actionable message when the selected model requires a newer Claude Code binary than the one in use (needs >= 2.1.219).
  • Approved hooks. cw now detects hooks contributed by a target project's .claude/settings.json/settings.local.json, shows them for one-key approval on first sighting or any change, and refuses non-interactive launches with unapproved hooks — project hooks are never silently trusted again.
  • Scratchpad cleanup at launch. Interactive launches now offer confirmed deletion of /tmp scratchpad directories untouched for 14+ days (with sizes and ages); declining snoozes the prompt for 7 days. Nothing is ever deleted without confirmation.
  • Vanilla default profile. ~/.claude now appears as a launchable "default" profile whenever it exists (no longer requiring a credentials file — fixes invisibility on macOS-Keychain setups), launches byte-for-byte vanilla (no config-dir override, no token injection, zero writes), shows as "managed by Claude Code", and offers a one-time opt-in to inject cw guardrail hooks.
  • Stale token surfacing. Token entries whose profile no longer exists are now reported by health, shown as a persistent TUI notice with a review-and-remove page (press T), and repairable via profile fix-auth.
  • **--dry-run now previews instead of writing.** Every subprocess launch, filesystem mutation and network call routes through one effects chokepoint, so c --dry-run reconcile-permissions, --dry-run deploy-hooks, --dry-run install and the profile create/delete/rename commands record what they would do and leave ~/.claudewheel/ untouched.
  • CLAUDE.md now states which commands confirm and which do not. A new "Confirmation and preview" section documents the three consequential commands, the --approve-consequential skip flag, the framework-owned flag quartet, and what --dry-run guarantees.
  • A real documentation site. claudewheel now ships a getting-started tutorial plus guides for profiles, theming, configuration, and health checks and preflight, and every module reference page carries written prose instead of a bare symbol skeleton.

#Fixes

  • Fixed: two Claude Code versions installing at once could corrupt each other. c install 2.1.220 and c install 2.1.221 both staged their download into a file named 2.1.downloading, so one could rename the other's half-written bytes into place under a checksum that was never verified against them. Each install now stages into its own <version>.downloading.
  • **c --dry-run install no longer claims it installed anything.** It now says what it would download and where it would land, above the framework's would-do log.
  • **reconcile-permissions and patch-profiles confirm before writing.** Both rewrite every managed profile plus shared-settings.json to exactly canonical, pruning hand-added permission rules, hook entries and disallowedTools with nothing backed up. They now declare themselves consequential, so the CLI confirms first and refuses with pass --approve-consequential to confirm when there is no terminal. --dry-run still previews ungated.
  • **--dry-run no longer claims work it did not do.** Ten commands -- profile delete, profile rename, profile create, deploy-hooks, uninstall, reset-options, migrate, permission add, permission remove and profile fix-auth -- printed past-tense success text above the would-do log during a preview. They now narrate in the conditional ("Would delete profile 'x'."). migrate additionally ignored --dry-run in its own reporting entirely.
  • The push guardrail no longer points at a command that does not exist. Its escalation advice named rlsbl push, which rlsbl removed; it now names rlsbl release run only.

#0.23.3

mv now migrates nested project sessions and rewrites githubRepoPaths

Context

mv previously matched only the exact moved path: session data for projects nested inside a moved directory was silently left stale (requiring manual per-child --post-hoc runs), and githubRepoPaths values were never rewritten for any move. mv is now prefix-aware over real decoded paths, verifies every descendant's destination before touching anything, and hard-errors on ambiguous encoded names.

#Fixes

  • **mv now migrates nested projects.** Moving a directory that contains other Claude Code project dirs migrates every descendant's session data (encoded project dirs, .claude.json project keys, JSONL cwd references) and rewrites githubRepoPaths entries pointing into the moved tree. Undecodable or ambiguous encoded dirs and missing descendant destinations abort the move before anything is touched.

#0.23.2

Fixes crashes on malformed install manifests; hardens the toolchain behind the scenes.

Context

The user-facing fix closes every escape point where a malformed server manifest (missing checksum, wrong-shaped platforms or entries, null values) could crash the installer instead of reporting a clean error. Internally, this release completes a large hardening effort: the entire test suite was converted to autospec'd mocks (0 bare patch sites, enforced by a new AST-based preflight gate), mypy strict now covers tests as well as the package, ruff lint and formatting were adopted repo-wide, and all release gates are defined as canonical wrapper scripts so gate scope can never silently drift.

#Breaking

  • Breaking: strictcli v0.29.0 migration. The _bind wrapper now accepts ctx as first parameter, threading it through to strictcli's new handler contract.

#Fixes

  • Fixed crash on malformed install manifests. Installing a Claude Code version whose server manifest is missing or malforms expected fields (checksum, platforms, entry shapes) no longer crashes with a traceback; the CLI reports a clean error and the TUI shows the install-failed page.

#0.23.1

Fixes a TUI crash when installing a Claude Code version from the launcher.

Context

The TUI install flow called install_version without the BinaryLocator argument it gained when the CLI path was updated, crashing the launcher with a TypeError instead of downloading. The fix passes the app's existing locator, and failed downloads now surface the intended "Install failed" page. To catch this bug class statically, the codebase also adopted mypy in strict mode (282 errors fixed, zero suppressions) wired as a hard release preflight gate.

#Features

  • Client selection step. The interactive launcher now prompts for the launch client (claude or miniclaude) with the configured default_client pre-selected; pass --client to skip the step. Unavailable clients are marked (not installed), and for non-Claude clients the version step is skipped.

#Fixes

  • Launching with --client miniclaude no longer fails when a Claude version was remembered from a previous launch or set as a config default; the version is a Claude-only input and is now ignored for non-Claude clients.
  • Fix. Launching with --client miniclaude no longer fails when MCP strict mode was remembered from a previous launch; MCP selection is now treated as a claude-only input and ignored for non-Claude clients, alongside version and default flags.
  • Fixed TUI crash when installing a Claude Code version. Selecting a version to install from the launcher no longer crashes; failed downloads now show an "Install failed" page.

#0.23.0

Launch-target client adapters: the new --client flag can launch alternative clients (miniclaude) with mapped profile/model/permission selections.

Context

Maintenance items riding along with this release: strictcli dependency bumped to >=0.27.0, and the docs were migrated to schema auto-discovery.

#Features

  • Launch target selection. New --client flag on claudewheel launch can start the miniclaude REPL client (--client miniclaude) instead of the official claude binary; the default claude preserves existing behavior.

#0.22.1

Fixes from the post-refactor hardening pass: clone-from-default profile creation, honest health reporting, self-cleaning failed profile creation, and an exact hooks-wired check.

Context

A test-sandbox escape during the 0.22.0 Workspace refactor exposed several latent weaknesses found while remediating: the hooks-wired health check accepted hook commands by name substring (passing even when hooks pointed at a nonexistent directory), the inode check claimed cleanups it could not persist on read-only workspaces, a failed profile creation left debris that blocked retries, and the wizard's clone-from-default option produced an empty-base profile. All four are fixed with regression tests, alongside a permanent test-suite guard asserting the real workspace's config surface is immutable under every write path.

#Fixes

  • Cloning from the default profile now works. The profile wizard's clone-from-default option previously produced an empty-base profile (and falsely reported its settings source); it now clones the real ~/.claude settings.
  • Health no longer claims inode cleanup it could not persist. On read-only workspaces the inode check now reports that stale entries were found but not persisted, instead of 'cleaned'.
  • A failed profile creation cleans up after itself. If profile creation fails partway, the partially-created profile directory is removed so a retry works, instead of failing with already-exists.
  • hooks-wired now verifies the actual hook command path. The health check previously matched hook scripts by name substring and passed even when hooks pointed at a nonexistent directory; it now requires the exact canonical command.

#0.22.0

Read-only profile resolution (safe on read-only mounts and headless servers) and the Workspace refactor; corrupt token stores now fail loudly.

#Breaking

  • Corrupt tokens.json is now a hard error. resolve_profile raises instead of silently returning an env without a token; profiles resolve purely from the on-disk layout (persisted options.json metadata is no longer consulted).
  • Unknown or stale profile names fail launches loudly. Launching with a profile that no longer exists raises a clear error instead of silently falling back to ~/.claude; profile locations are derived from the profile directory, never from persisted metadata.

#Features

  • CLAUDEWHEEL_CONFIG_DIR. New env var overriding the workspace root (default ~/.claudewheel) for programmatic and containerized consumers.
  • Health detects relocated workspace roots. A new health check flags profile hook commands pointing at a different scripts directory than the current workspace; patch-profiles fixes them.

#Fixes

  • resolve_profile no longer writes. Profile resolution performs zero filesystem writes and no terminal queries — safe on read-only mounts and headless servers.
  • migrate now supports the default profile. Session data can be migrated to and from the ~/.claude default profile; previously it errored as if the profile did not exist.
  • options.json no longer stores profile locations. A one-time migration removes the legacy profile metadata block; profile locations are always derived from the profile directory.

#0.21.0

Paste token option in wizard auth flow

#Features

  • New feature. Wizard now offers a 'Paste token directly' option for users with pre-existing API tokens.

#0.20.1

Guardrail correctness fixes, a repaired --dump-schema/--version, and new guardrail documentation.

Context

Hardens the command-guardrail system and fixes release-adjacent CLI bugs. Guardrail: colon-refspec remote-branch deletion (git push origin :branch) is now hard-denied for everyone (previously only ask-gated for the main agent); a cross-separator false-positive that could wrongly block chained pushes is fixed; and the kill/pkill advice no longer fires on commands like 'npm run kill'. The rule patterns are now built through anchoring helpers so a weak anchor is structurally impossible, and each hook-backed rule carries a settings-coverage annotation. CLI: claudewheel --dump-schema and --version both worked incorrectly (the former failed outright; the latter reported a stale version) and are fixed. Docs: a new Guardrails page explains the tiers and subagent handling, with a per-rule table generated from the model so it can't drift; claudewheel health gains a deployed-hook drift check.

#Features

  • New Guardrails documentation page covering the four enforcement tiers, subagent-vs-main-agent handling, and the command-string caveat, with an always-in-sync per-rule reference table generated from the guardrail model.
  • **claudewheel health now detects deployed-hook drift** — it warns when the hook scripts installed for a profile differ from the current model.

#Fixes

  • Guardrail fixes. Remote-branch deletion via the colon-refspec form (git push origin :branch) is now hard-denied for everyone, matching --delete; a cross-separator false-positive that could wrongly block chained pushes is fixed; and kill/pkill advice no longer fires spuriously on commands like npm run kill.
  • **Fixed claudewheel --dump-schema**, which previously failed because the CLI injected an implicit launch subcommand before the flag was parsed.
  • **Fixed claudewheel --version** reporting a stale version in editable/source checkouts; it now reads the project's actual version from package.json.

#0.20.0

Subagent-aware command guardrails, a reconcile-permissions command, and a canonical-drift health check.

Context

This release overhauls the command-guardrail system that claudewheel deploys to Claude Code profiles into a single canonical protocol driven by one model (claudewheel/guardrail.py). Guardrail hooks now distinguish subagents from the main agent via the PreToolUse agent_id field: escalate-tier commands (git push, git reset, rebase, saferm purge, gh workflow run, forced switch) are hard-denied for subagents with instructions to escalate to the parent agent, while the main agent falls through to a confirmation prompt. git checkout is steered to git switch, and kill/pkill trigger advice to build graceful stop scripts. The new reconcile-permissions command sweeps every profile and the shared defaults to the canonical rule set, and the new canonical-drift health check reports any divergence.

#Features

  • New patch-profiles command syncs existing profiles and shared settings to canonical hook/disallowedTools defaults
  • **New reconcile-permissions command.** Reconciles each profile's permission rules and the shared defaults to the canonical guardrail set: adds missing rules, removes obsolete ones, and strips dead allow entries. Requires an explicit --dry-run or --apply.
  • Guardrail hooks now distinguish subagents from the main agent. Escalate-tier commands (git push, git reset, rebase, saferm purge, gh workflow run, forced switch) are hard-denied for subagents with instructions to escalate to the parent agent, while the main agent falls through to a confirmation prompt. git checkout is steered to git switch, and kill/pkill now trigger advice to build graceful stop scripts.
  • **New canonical-drift health check.** claudewheel health now reports when a profile's permission rules or hook wiring diverge from the canonical guardrail set.
  • Added Claude Opus 4.8 model variants to the model selection defaults.

#Fixes

  • Health check /tmp/claude now measures real tmpfs usage (excludes symlink targets, uses block size); threshold lowered to 1 GB
  • Fixed the rm hard-block hook emitting invalid JSON (rm commands were never blocked) and hardened it to catch sudo/env/xargs/find -exec rm

#0.19.1

Profile rename command, inline auth-shadow fix on inspect page, faster detection, and a state-save race fix.

#Features

  • Terminal background detection timeout reduced from 1s to 500ms, halving worst-case startup latency on unsupported terminals.
  • Profile inspect page now offers to fix auth shadow inline when detected (press f).
  • New profile rename <old> <new> command with automatic recovery if interrupted mid-rename.

#Fixes

  • Fixed a race where concurrent sessions could lose the remembered browser choice on state save.

#0.19.0

CLI profile command group, auth shadow fix, hook guard, rate-limit tier, live theme switching, and online token validation.

Context

Breaking: profile commands are now grouped under claudewheel profile (create/delete/show/fix-auth/check-tokens). Old flat names print a redirect and exit.

New features: auth-shadow detection and fix (profile fix-auth strips session credentials shadowing long-lived tokens), a PreToolUse hook blocking unsafe git/rm patterns in AI sessions, rate-limit tier capture from session-login credentials for downstream tools, a themed install-confirmation dialog, online token validation (profile check-tokens), and Mode 2031 live theme switching for terminals that support it.

Fixes: CSI decoder handles private-mode sequences without byte leakage, and SIGTERM/SIGHUP are cleanly saved/restored during forms and PTY sessions.

#Breaking

  • Breaking. Profile commands renamed to a group: new-profile -> profile create, delete-profile -> profile delete, show-profile -> profile show. Old names print a redirect and exit.

#Features

  • New profile fix-auth command strips session credentials that shadow a long-lived token, and a health check detects the condition.
  • New hook-block-unsafe-commands hook blocks raw git add, git stash, git restore, git checkout --, and rm in AI agent sessions, directing to safegit/saferm.
  • Rate-limit tier is captured from session-login credentials and exposed to downstream tools (e.g., howmuchleft) via a .credentials.json stub at launch.
  • Version install uses a themed confirmation dialog and result page instead of a bare text prompt.
  • New profile check-tokens command validates stored tokens against the Anthropic API and reports per-profile status.
  • Live theme switching: terminals supporting Mode 2031 (kitty, Ghostty, foot, VTE 0.82+) automatically switch claudewheel's theme when the OS dark/light mode changes mid-session.

#Fixes

  • Fixed CSI decoder to handle private-mode sequences (ESC[?...) without leaking bytes into the input stream.
  • SIGTERM and SIGHUP are now handled cleanly during forms and PTY sessions, preventing terminal corruption on kill.

#0.18.2

Profiles now launch without a login screen, and the theme adapts to light/dark terminals automatically.

#Features

  • Terminal background color is now auto-detected at startup (via OSC 11). Light-terminal users automatically get the light theme without manual configuration.

#Fixes

  • Profiles created via the wizard now work immediately without Claude Code showing a login screen. Previously, CC's onboarding gate blocked token-injected profiles.
  • Form text is now fully theme-driven — readonly fields and radio selections no longer use hardcoded colors that were invisible on light backgrounds.

#0.18.1

Hint bar now automatically reflects available keybindings and wraps on narrow terminals.

#Features

  • Keyboard shortcuts are now shown automatically in the hint bar based on current context — new bindings no longer require manual hint-string updates.
  • Hint bar wraps to a second line on narrow terminals instead of truncating.

#0.18.0

Themed form system, zero-paste token capture with API validation, profile inspect and delete in the TUI, and six new internal modules.

Context

The profile creation and auth flows are rebuilt on a themed widget layer (new forms theme section, focus-bg idiom matching the segment bar) running in one continuous fullscreen session. Token capture uses a PTY proxy to scrape setup-token's output automatically -- no more copy-paste. Every token is validated against the Anthropic API before saving (hard 401 rejection; the warn-and-save path is gone). Profiles can be inspected (i key / show-profile CLI) and deleted (Ctrl-D/Delete key / delete-profile CLI) from the TUI, with a data-destruction hard-block for profiles whose shared dirs are real directories.

Infrastructure: fsutil.py consolidates all atomic JSON writes (the permission-loss bug class is structurally eliminated), tokens.py consolidates token I/O, the CSI decoder handles Delete/PgUp/PgDn/Insert/parametric Shift-Tab without leaking bytes, and Terminal.cooked() replaces hand-rolled raw-mode transitions.

Breaking: delete-profile now requires --force-delete-data (in addition to --force-delete) to remove profiles with real shared directories.

#Features

  • Continuous fullscreen create-profile flow. The profile wizard, auth method/browser forms, and a new creation summary page now run as one uninterrupted fullscreen session (no more bouncing between the TUI and scrollback), themed via the new forms theme section. The claude auth login / setup-token subprocess and token paste open in a temporary cooked window and return to the session. The CLI new-profile path gets the same flow.
  • Zero-paste token auth with hard validation. The long-lived token flow now captures claude setup-token output directly -- no manual paste needed -- and validates every token against the API before saving. Tokens the API rejects (401) are never saved (one manual re-paste is offered); when the API is unreachable, saving unvalidated requires an explicit choice and is reported as "unverified". The pre-launch auth prompt now launches only on an explicit skip.
  • Profile inspect. Press i on the profile segment to open a fullscreen inspection page for the focused profile, or run c show-profile <name> from the CLI. The report covers registration, credentials, token expiry, shared-dir symlink health (with a danger flag for real data at shared names), settings/permission summary, active session count, and disk usage.
  • TUI profile delete. Press Ctrl-D or Delete on the profile segment to delete the focused profile after an informed confirmation (Cancel default-focused). Profiles holding real data at shared-dir names are hard-blocked with a pointer to the new delete-profile --force-delete-data CLI flag -- the TUI offers no override.

#Fixes

  • Fix: tokens.json no longer loses its 0600 permissions when a token is updated or a profile is deleted (previously triggered health-check warnings after any token update). options.json, state.json, and inodes.json likewise keep their existing permissions across updates, and a corrupt tokens.json now produces a clear error instead of a crash.
  • Fixed silent data loss on profile delete. delete-profile used to rmtree shared-dir names (e.g. projects/) even when they were real directories holding conversation data instead of symlinks. Deletion now refuses with the at-risk dir names; the built-in default profile is refused outright; profiles on disk but missing from options.json can now be deleted; a stale last_config profile reference is purged from state.json.
  • Fixed a bug where Delete, PgUp, PgDn, and Insert keys leaked stray bytes into the search buffer. Also added support for parametric Shift-Tab (ESC[1;2Z).
  • Fixed a bug where updating tokens.json lost its restrictive file permissions (0600 reverted to 0644 on every write).

#0.17.0

Auth flow UX overhaul: wizard-style prompts, browser choice with copy-URL option, remembered browser, and return-to-TUI after auth.

Context

The v0.16.x auth flow worked but was rough: a bare numbered input() prompt, forced browser auto-open with no control over which browser, whitespace-fragile token pasting, and being dropped straight into Claude Code after authenticating. This release rebuilds the flow on a reusable raw-mode selection form (new ui.py module), adds browser detection across native/flatpak/snap installs with a copy-URL fallback (via the BROWSER env var, which Claude Code honors directly), remembers the browser choice in state.json, and returns to the segment bar after auth so the user confirms the launch themselves.

#Features

  • The auth setup prompt is now an arrow-key selection form matching the wizard's style. Esc safely cancels instead of skipping auth.
  • Auth setup now lets you choose which browser to open (auto-detected from native, flatpak, and snap installs) or copy the login URL instead of opening any browser.
  • After authenticating a profile from the launch intercept, you return to the segment bar (with a status flash) instead of being dropped straight into Claude Code. Only the explicit "Launch without auth" option launches directly.
  • Your browser choice for auth is remembered and pre-focused on the next auth flow.

#Fixes

  • Long-lived token paste now strips all whitespace and linebreaks automatically, so tokens copied from the terminal with wrapping artifacts work correctly.

#0.16.1

Launching an unauthenticated profile now prompts for auth setup before starting Claude Code.

#Features

  • Launching an unauthenticated profile now prompts for auth setup (session login, long-lived token, or skip) before starting Claude Code.

#0.16.0

Profile wizard overhaul: new profiles appear instantly, inline auth setup, and visual indicators for unauthenticated profiles.

Context

Previously, profiles created via the wizard were invisible in the segment bar because discovery required .credentials.json or a tokens.json entry, neither of which the wizard created. This release fixes the root cause (broadened discovery to accept settings.json, added pinned to collection order) and adds a post-wizard auth flow so users can authenticate immediately instead of manually running CLI commands. Unauthenticated profiles now appear dimmed in the UI.

Also includes a breaking rename of --force to --force-delete/--force-overwrite and a fix for machine-local path dependencies in uv.lock.

#Breaking

  • Breaking. Renamed --force to --force-delete (delete-profile) and --force-overwrite (deploy-hooks). Boolean flags now require explicit --flag/--no-flag where no default is set.

#Features

  • Profile discovery now accepts profiles with only settings.json, so newly created profiles appear immediately without requiring auth setup first.
  • Unauthenticated profiles are visually dimmed in the segment bar, indicating they need auth setup.
  • Profile wizard now offers inline auth setup (session login, long-lived token, or skip) immediately after profile creation.

#Fixes

  • Dependency installation no longer requires a machine-local checkout: uv.lock previously carried a local path for strictcli, breaking installs and CI outside the author's machine. It now resolves from PyPI (strictcli 0.24.0).
  • Newly created profiles now appear in the segment bar immediately after the wizard completes, without requiring a restart.

#0.15.1

Thread safety fix for background discovery and wizard UX overhaul

Context

The background discovery thread shared a mutable state dict with the main thread, creating a race condition on npm_versions_cache writes. Fixed by passing a deep copy and copying results back on the main thread after completion.

The profile creation wizard was overhauled: 6 checkbox fields are now hidden behind a collapsible Advanced toggle (defaulting to sensible values), Enter from the Name field submits immediately, errors persist until the user takes a meaningful action, context-sensitive keyboard hints appear at the bottom, Shift-Tab navigates backward, and the text input has visible brackets. The Cancel button was removed (ESC suffices).

#Features

  • Wizard UX overhaul. Collapsible Advanced toggle hides 6 checkboxes by default, Enter from Name field submits, persistent error display, context-sensitive keyboard hints, Shift-Tab backward navigation, improved visual clarity (bracketed text input, bold radio selections).

#Fixes

  • Fix. Background discovery thread no longer shares mutable state dict with the main thread; uses a deep copy to prevent race conditions on npm version cache writes.

#0.15.0

Option provenance architecture: SegmentState separates discovered, pinned, and default options with staleness policies, value-based selection, deferred discovery apply, and a provenance overlay

Context

A pre-registry build (0.1.0) accidentally shipped with the maintainer's personal data hardcoded in DEFAULT_OPTIONS (GitHub handles, profile names). This seeded into users' ~/.claudewheel/options.json on first run. Even after the fix (making defaults empty + adding discovery), stale data persisted because gh_auth appended (never replaced) and claude_config_scan fell back to stale values when discovery returned empty.

This release introduces SegmentState -- a new data model that cleanly separates discovered (runtime), pinned (user-added), and default (shipped) option collections. Discovery always replaces the discovered collection; pinned values are never touched by discovery. A staleness policy (IMMEDIATE for credentials, VERIFY for filesystem objects) controls what happens when previously-discovered values disappear. The entire discovery system was refactored from a monolithic match/case dispatch into a typed registry of individual functions returning DiscoveryResult dataclasses.

Selection tracking switched from index-based (fragile when options change) to value-based. The "+" creation sentinel moved from a real option to a virtual UI element via display_options. Slow discovery results are now deferred for the focused segment and applied on defocus, preventing option list disruption during interaction. A provenance overlay (toggle with ?) shows where each option came from.

#Features

  • Staleness policy. Discovery registry entries now carry verify callbacks; set_discovered uses them to retain values that still exist on disk when a re-scan omits them.
  • Directory discovery. Recent dirs are now validated (must exist on disk) and stale entries are pruned from state. Static values no longer mixed into discovery results.
  • Virtual '+' button. The '+' creation sentinel is now a virtual UI element, no longer stored in segment state collections. Freeform values are promoted from ephemeral to pinned on launch.
  • Deferred discovery apply. Slow discovery results for the focused segment are now buffered and applied on defocus, preventing option list disruption while the user is interacting. A pending indicator (*) appears in the segment label when results are waiting.
  • Provenance overlay. Press ? to toggle a source overlay on fan-out options: * discovered, ^ pinned, . default, ~ ephemeral. The status bar shows a legend while active.
  • Docs. Added installation instructions (pipx/uv) and deprecation notice for the old Node/npm package.

#0.14.0

Add import command for importing session data from external Claude Code directories

Context

The new claudewheel import command enables importing Claude Code session data from external directories (e.g., Windows backups onto a Linux machine). It handles cross-OS path rewriting (Windows backslashes to Unix forward slashes), collision detection for sessions that already exist in the store, optional session re-identification (reid), and a dry-run mode for previewing what would be imported.

#Features

  • New command. claudewheel import imports Claude Code session data from external directories (e.g., Windows backups) into the shared store, with cross-OS path rewriting, collision detection, reid support, and dry-run mode.

#0.13.1

Instant TUI startup via async discovery, KeyboardInterrupt fix, SEO improvements

#Features

  • Improvement. TUI launches instantly. Slow discovery calls (GitHub auth, npm versions) now run in a background thread instead of blocking startup.

#Fixes

  • Fix. Ctrl-C during npm version fetch no longer produces a traceback.

#0.13.0

Proactive directory rename detection via inode tracking

#Features

  • New feature. Proactive directory rename detection via inode tracking. On every launch, claudewheel records the project directory's inode. The health check detects when a recorded path was renamed and suggests claudewheel mv --post-hoc to fix it.

#0.12.0

Fable 5 model support, model auto-sync, full orphan scan for --cont

#Features

  • New feature. Model list now auto-syncs from defaults on startup. New models added to claudewheel are automatically available without resetting options.
  • New feature. Added Fable 5 (claude-fable-5 and claude-fable-5[1m]) to the default model list.
  • Improvement. --cont now scans all orphaned session directories, not just same-parent. Cross-parent directory renames are now detected.

#0.11.0

mv now renames directories by default, --post-hoc for session-only migration

#Breaking

  • Breaking. mv now renames the directory on disk by default, then migrates sessions. Use --post-hoc for session-only migration (the old behavior).

#0.10.1

CI workflow improvements: idempotent publish steps for npm and PyPI

Context

Scaffold update added skip-if-already-published checks to both npm and PyPI publish workflows, making CI re-runs safe. Also added separate CI check workflows.

#Fixes

  • Fix. CI publish workflows are now idempotent -- re-running a partially failed publish no longer fails on already-published packages.

#0.10.0

New permission command group for managing profile permission rules

#Features

  • New command group. permission add, permission remove, and permission list subcommands for managing profile permission rules from the CLI.

#0.9.1

--cont interception, mv merge fix, cleaner dry-run UX

#Features

  • New feature. --cont now detects directory renames the same way --resume does, scanning for orphaned sessions in sibling directories.
  • Improvement. Resume/cont interception shows the claudewheel mv command when the old path still exists, and uses a concise human-readable dry-run summary instead of per-file log spam.

#Fixes

  • Bug fix. mv now merges sessions into an existing target directory instead of silently skipping the move.

#0.9.0

Rename redir to mv, add resume interception for directory renames, fix path encoding bug

Context

The redir command is renamed to mv for better discoverability. When --resume can't find a session under the current directory, claudewheel now searches the shared store, detects that the project directory was renamed, and offers to move all sessions to the new path. The path encoding function is also fixed to replace dots (not just slashes) with hyphens, matching Claude Code's internal encoding -- this fixes mv operations on dotfile paths.

#Breaking

  • Breaking. Renamed redir command to mv.

#Features

  • New feature. Resume interception: when --resume can't find a session under the current directory, claudewheel searches the shared store, detects directory renames, and offers to move sessions to the new path.

#Fixes

  • Bug fix. Path encoding now replaces both / and . with -, matching Claude Code's internal encoding. Previously, dotfile paths (e.g. ~/.claude-common) would encode incorrectly.

#0.8.0

Rename gc command to stats

Context

The gc command only reports shared-store statistics now (sentinel cleanup and origins compaction were removed in v0.7.0). Renamed to reflect its actual purpose.

#Breaking

  • Renamed. gc command renamed to stats to reflect its actual purpose (reporting shared-store statistics).

#0.7.0

Remove profile attribution system, add --picker flag, unify shared settings

Context

The profile attribution system (hook-stamp-origin, xattr stamping, sentinels, origins log) had unfixable race conditions and 30% of session files could never be attributed. Removed entirely rather than patching. Also adds --picker for argless session resume and unifies shared settings with drift detection.

#Breaking

  • Breaking. Removed the profile attribution system (hook-stamp-origin, xattr stamping, sentinel files, origins log). The system had unfixable race conditions and 30% of files could never be attributed.

#Features

  • New flag. --picker opens the Claude session resume picker without requiring a session ID argument.
  • Unified shared settings. Replaced per-profile profile-defaults.json with a single shared-settings.json and drift detection.
  • deploy-hooks --force. Added --force flag to overwrite existing hook scripts.

#Fixes

  • Health check. Removed xattr-coverage and hook-integrity checks; streamlined hooks-wired to only verify hook-timestamp.

#0.6.1

Consolidate shared data and eliminate ~/.claude-shared/ and ~/.claude-common/

Context

Shared session data (projects, session-env, file-history, tasks, todos, paste-cache) moved from ~/.claude-shared/ to ~/.claudewheel/shared/. Skills, utility scripts, and profile origins moved from ~/.claude-common/ into ~/.claudewheel/. COMMON_DIR constant eliminated. Sentinel files moved to dedicated ~/.claudewheel/shared/sentinels/ subdirectory. Dead code (_strip_xattrs, _clean_origins_file) removed. Origins file dual-location bug fixed.

#Breaking

  • Shared data consolidated. Session data, skills, and scripts moved from ~/.claude-shared/ and ~/.claude-common/ into ~/.claudewheel/. Both old directories eliminated.

#Fixes

  • Fix. Profile origins log now correctly read from ~/.claudewheel/ instead of stale ~/.claude-common/ path.

#0.6.0

Profile centralization, hook management, worktree isolation, docs website

Context

Profiles moved from ~/.claude-/ to ~/.claudewheel/profiles// (breaking). New deploy-hooks command auto-creates hook scripts from built-in templates. Settings drift detection compares profiles against canonical shared-settings.json. PreToolUse hook blocks Agent tool worktree isolation to prevent multi-session conflicts. Cron tools (CronCreate, CronDelete, CronList, ScheduleWakeup) unblocked. Documentation website at claudewheel.smmh.dev with auto-generated API/CLI reference and branding.

#Breaking

  • Profile directories moved. Profiles now live at ~/.claudewheel/profiles// instead of ~/.claude-/. A startup warning appears if old-style directories are detected.

#Features

  • New command. deploy-hooks auto-creates hook scripts at ~/.claudewheel/scripts/ from built-in templates.
  • Settings drift detection. Health check compares profiles against a canonical shared-settings.json and reports differences.
  • Worktree isolation guard. PreToolUse hook blocks the Agent tool from using worktree isolation, preventing multi-session conflicts.
  • Cron tools enabled. CronCreate, CronDelete, CronList, and ScheduleWakeup removed from disallowed tools.
  • Documentation website. Live docs site at claudewheel.smmh.dev with auto-generated API reference, CLI reference, and branding.

#0.5.0

Strictcli compatibility fix and config-directory rename to ~/.claudewheel/.

Context

The config directory has been renamed from ~/.claudelauncher/ to ~/.claudewheel/ to match the project name (the rename of the project itself happened a while ago, but the config-dir path was never updated). Existing users must mv ~/.claudelauncher ~/.claudewheel before upgrading or claudewheel will scaffold a fresh empty config directory on next launch.

Strictcli v0.16.0 added a guardrail requiring unique=True or unique=False on every repeatable=True flag. claudewheel's -s/--set flag did not pass it and crashed at startup with ValueError: Flag "set": repeatable requires explicit unique. This release adds unique=False and, more importantly, surfaces the underlying intent the guardrail is meant to enforce: _handle_launch now rejects any duplicate segment override regardless of source. Previously, passing the same key twice (e.g. --profile work -s profile=personal, or -s profile=work -s profile=personal) silently dropped the earlier value. The new diagnostic names the conflicting key, both values, and both sources.

#Breaking

  • Config directory renamed from ~/.claudelauncher/ to ~/.claudewheel/. Run mv ~/.claudelauncher ~/.claudewheel before upgrading or claudewheel will scaffold a fresh empty dir on next launch.

#Fixes

  • Fix startup crash from strictcli guardrail; -s now errors on duplicate segment keys (including conflicts between an individual segment flag and -s) instead of silently dropping the earlier value.

#0.4.5

#Fixes

  • Fix. resolve_profile() now runs option discovery before reading metadata, fixing programmatic profile resolution from external callers.

#0.4.4

  • No user-facing changes.

#0.4.3

#Fixes

  • Fix. Profiles set up before claudewheel (without .credentials.json) were invisible to health checks and the TUI profile picker. They are now discovered via tokens.json.
  • Fix. Compatibility with strictcli 0.5.0 (MutexGroup is now always required; session flags moved to a Tag with manual mutual-exclusion check).

#0.4.2

  • No user-facing changes.

#0.4.1

#Fixes

  • CI fix. Resolved dependency resolution failure by removing local path override for strictcli.

#0.4.0

#Breaking

  • Python 3.11 required. Bumped minimum Python version from 3.10 to 3.11 for strictcli compatibility.

#Features

  • New API. resolve_profile(name) returns environment variables (CLAUDE_CONFIG_DIR, CLAUDE_CODE_OAUTH_TOKEN) for a given profile, enabling programmatic consumers like claudestream.
  • CLI rewrite. Migrated from argparse to strictcli with typed subcommands, mutex groups, and structured flags.

#Fixes

  • Print mode hygiene. Print mode (-p) now skips health checks and state writes, preventing TUI default pollution and stderr noise for programmatic callers.
Search