claudewheel 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. claudewheel-0.3.0/.claude/settings.json +15 -0
  2. claudewheel-0.3.0/.github/workflows/ci.yml +25 -0
  3. claudewheel-0.3.0/.github/workflows/publish.yml +28 -0
  4. claudewheel-0.3.0/.gitignore +19 -0
  5. claudewheel-0.3.0/.npmignore +7 -0
  6. claudewheel-0.3.0/.rlsbl/bases/.claude/settings.json +3 -0
  7. claudewheel-0.3.0/.rlsbl/bases/.github/workflows/ci.yml +23 -0
  8. claudewheel-0.3.0/.rlsbl/bases/.github/workflows/publish.yml +30 -0
  9. claudewheel-0.3.0/.rlsbl/bases/.gitignore +15 -0
  10. claudewheel-0.3.0/.rlsbl/bases/CLAUDE.md +20 -0
  11. claudewheel-0.3.0/.rlsbl/config.json +6 -0
  12. claudewheel-0.3.0/.rlsbl/hashes.json +9 -0
  13. claudewheel-0.3.0/.rlsbl/hooks/post-release.sh +8 -0
  14. claudewheel-0.3.0/.rlsbl/hooks/pre-release.sh +27 -0
  15. claudewheel-0.3.0/.rlsbl/version +1 -0
  16. claudewheel-0.3.0/CHANGELOG.md +166 -0
  17. claudewheel-0.3.0/CLAUDE.md +45 -0
  18. claudewheel-0.3.0/LICENSE +21 -0
  19. claudewheel-0.3.0/PKG-INFO +15 -0
  20. claudewheel-0.3.0/README.md +167 -0
  21. claudewheel-0.3.0/assets/banner.png +0 -0
  22. claudewheel-0.3.0/assets/logo.png +0 -0
  23. claudewheel-0.3.0/bin/claudewheel.js +51 -0
  24. claudewheel-0.3.0/c +3 -0
  25. claudewheel-0.3.0/claudewheel/__init__.py +16 -0
  26. claudewheel-0.3.0/claudewheel/__main__.py +3 -0
  27. claudewheel-0.3.0/claudewheel/app.py +333 -0
  28. claudewheel-0.3.0/claudewheel/cli.py +404 -0
  29. claudewheel-0.3.0/claudewheel/config.py +218 -0
  30. claudewheel-0.3.0/claudewheel/constants.py +50 -0
  31. claudewheel-0.3.0/claudewheel/defaults.py +332 -0
  32. claudewheel-0.3.0/claudewheel/fuzzy.py +46 -0
  33. claudewheel-0.3.0/claudewheel/gc.py +121 -0
  34. claudewheel-0.3.0/claudewheel/health.py +408 -0
  35. claudewheel-0.3.0/claudewheel/hooks.py +57 -0
  36. claudewheel-0.3.0/claudewheel/install.py +136 -0
  37. claudewheel-0.3.0/claudewheel/launch.py +130 -0
  38. claudewheel-0.3.0/claudewheel/migrate.py +231 -0
  39. claudewheel-0.3.0/claudewheel/profile_ops.py +238 -0
  40. claudewheel-0.3.0/claudewheel/redir.py +197 -0
  41. claudewheel-0.3.0/claudewheel/renderer.py +537 -0
  42. claudewheel-0.3.0/claudewheel/segment.py +383 -0
  43. claudewheel-0.3.0/claudewheel/state.py +23 -0
  44. claudewheel-0.3.0/claudewheel/terminal.py +97 -0
  45. claudewheel-0.3.0/claudewheel/theme.py +90 -0
  46. claudewheel-0.3.0/claudewheel/wizard.py +351 -0
  47. claudewheel-0.3.0/package.json +34 -0
  48. claudewheel-0.3.0/pyproject.toml +31 -0
  49. claudewheel-0.3.0/scripts/patch-profiles +116 -0
  50. claudewheel-0.3.0/scripts/redir-history.sh +95 -0
  51. claudewheel-0.3.0/tests/__init__.py +0 -0
  52. claudewheel-0.3.0/tests/test_cli.py +411 -0
  53. claudewheel-0.3.0/tests/test_discover.py +153 -0
  54. claudewheel-0.3.0/tests/test_fuzzy.py +114 -0
  55. claudewheel-0.3.0/tests/test_gc.py +320 -0
  56. claudewheel-0.3.0/tests/test_health.py +567 -0
  57. claudewheel-0.3.0/tests/test_install.py +180 -0
  58. claudewheel-0.3.0/tests/test_launch.py +79 -0
  59. claudewheel-0.3.0/tests/test_migrate.py +449 -0
  60. claudewheel-0.3.0/tests/test_migration.py +297 -0
  61. claudewheel-0.3.0/tests/test_profile_ops.py +354 -0
  62. claudewheel-0.3.0/tests/test_redir.py +349 -0
  63. claudewheel-0.3.0/tests/test_requires.py +136 -0
  64. claudewheel-0.3.0/tests/test_segment.py +190 -0
  65. claudewheel-0.3.0/tests/test_viewport.py +446 -0
  66. claudewheel-0.3.0/tests/test_wizard.py +470 -0
  67. claudewheel-0.3.0/todo/.done/core.md +226 -0
  68. claudewheel-0.3.0/todo/.done/disallowed-tools-not-enforced.md +45 -0
  69. claudewheel-0.3.0/todo/.done/publish-on-npm.md +45 -0
  70. claudewheel-0.3.0/todo/lsp-replacement-mcp.md +60 -0
  71. claudewheel-0.3.0/todo/rename-config-dir.md +78 -0
  72. claudewheel-0.3.0/todo/session-segment.md +81 -0
@@ -0,0 +1,15 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "matcher": "",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "rlsbl prs"
10
+ }
11
+ ]
12
+ }
13
+ ]
14
+ }
15
+ }
@@ -0,0 +1,25 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ branches: [main]
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ python-version: ["3.10", "3.13", "3.14"]
13
+ steps:
14
+ - uses: actions/checkout@v6
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: ${{ matrix.python-version }}
18
+ - uses: astral-sh/setup-uv@v7
19
+ - run: uv pip install --system -e . pytest
20
+ - run: python3 -m pytest tests/ -v
21
+ - uses: actions/setup-node@v6
22
+ with:
23
+ node-version: 22
24
+ - run: node -e "require('./package.json')"
25
+ - run: node bin/claudewheel.js --help || true
@@ -0,0 +1,28 @@
1
+ name: Publish
2
+ on:
3
+ release:
4
+ types: [published]
5
+ permissions:
6
+ contents: read
7
+ id-token: write
8
+
9
+ jobs:
10
+ npm:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v6
14
+ - uses: actions/setup-node@v6
15
+ with:
16
+ node-version: 22
17
+ registry-url: https://registry.npmjs.org
18
+ - run: npm publish --provenance --access public
19
+ env:
20
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
21
+
22
+ pypi:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v6
26
+ - uses: astral-sh/setup-uv@v7
27
+ - run: uv build
28
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,19 @@
1
+ __pycache__/
2
+ *.pyc
3
+
4
+ # Added by share-it-on
5
+ node_modules/
6
+ *.log
7
+ .DS_Store
8
+ coverage/
9
+ dist/
10
+ *.egg-info/
11
+ .rlsbl/lock
12
+ .credentials.json
13
+ .*-cache.json
14
+ .env
15
+ .env.local
16
+
17
+ # Added by rlsbl
18
+ .rlsbl-notes-*.tmp
19
+ *.local-only
@@ -0,0 +1,7 @@
1
+ __pycache__/
2
+ **/__pycache__/
3
+ *.pyc
4
+ **/*.pyc
5
+ tests/
6
+ todo/
7
+ scripts/
@@ -0,0 +1,3 @@
1
+ {
2
+ "hooks": {}
3
+ }
@@ -0,0 +1,23 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ # engines.node: >= 18
15
+ node-version: [20, 22, 24]
16
+ steps:
17
+ - uses: actions/checkout@v6
18
+ - uses: actions/setup-node@v6
19
+ with:
20
+ node-version: ${{ matrix.node-version }}
21
+ - run: npm ci
22
+ - run: npm test --if-present
23
+ - run: npm audit --audit-level=moderate || true
@@ -0,0 +1,30 @@
1
+ name: Publish
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+ id-token: write
10
+
11
+ jobs:
12
+ npm:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v6
16
+ - uses: actions/setup-node@v6
17
+ with:
18
+ node-version: 24
19
+ registry-url: https://registry.npmjs.org
20
+ - run: npm publish --provenance --access public
21
+ env:
22
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
23
+
24
+ pypi:
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v6
28
+ - uses: astral-sh/setup-uv@v7
29
+ - run: uv build
30
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,15 @@
1
+ node_modules/
2
+ __pycache__/
3
+ *.pyc
4
+ *.log
5
+ .DS_Store
6
+ coverage/
7
+ dist/
8
+ *.egg-info/
9
+ .rlsbl-notes-*.tmp
10
+ .rlsbl/lock
11
+ .credentials.json
12
+ .*-cache.json
13
+ .env
14
+ .env.local
15
+ *.local-only
@@ -0,0 +1,20 @@
1
+ # claudewheel
2
+
3
+ ## Release workflow
4
+
5
+ This project uses [rlsbl](https://github.com/smm-h/rlsbl) for release orchestration.
6
+
7
+ - Update CHANGELOG.md with a `## X.Y.Z` entry describing changes
8
+ - Run `rlsbl release [patch|minor|major]` to bump version and create a GitHub Release
9
+ - CI handles publishing automatically via the publish workflow
10
+ - Never publish manually — always use `rlsbl release`
11
+ - Requires NPM_TOKEN secret on GitHub (Settings > Secrets > Actions)
12
+ - Use `rlsbl release --dry-run` to preview a release without making changes
13
+
14
+ ## Conventions
15
+
16
+ - No tokens or secrets in command-line arguments (use env vars or config files)
17
+ - All file writes to shared state should be atomic (write to tmp, then rename)
18
+ - External calls (APIs, CLI tools) must have timeouts and graceful fallbacks
19
+ - Use `npm link` (npm) or `uv pip install -e .` (Python) for local development
20
+ - CI runs smoke tests on every push; manual testing for UI/UX changes
@@ -0,0 +1,6 @@
1
+ {
2
+ "targets": [
3
+ "npm",
4
+ "pypi"
5
+ ]
6
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ ".github/workflows/ci.yml": "c8ea07acf2aa7a96c71f6e70f625807138549fd2b96cb5f15bd7d60785b4b86d",
3
+ ".github/workflows/publish.yml": "1216ed5948dec0ec26a2e1aea32c7eda914e76fca6aec3676e564630d49deb2a",
4
+ "scripts/check-prs.sh": "a438f046ac169256b859873e6f12b66bf629e12fa4bc1f766ed8484af983383c",
5
+ "scripts/pre-push-hook.sh": "68c436c3d16b88b289be8eb8af0d621d94a0249dd8287b2adca3b0bb85c9fa58",
6
+ ".rlsbl/hooks/pre-release.sh": "1b13062dda97df66792df382312263d704a6cc706d2dd3da921f4c470488276d",
7
+ ".rlsbl/hooks/post-release.sh": "b455f8511e0b2655509ecf5dcb0ab7da5bb7c961f47910ff8e00cab5bd51f833",
8
+ ".gitignore": "773ea3da02e79c42be002ec89b8b29cb7ad4001bf440b7fa78789210a8bbd7ef"
9
+ }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ # Post-release hook. Runs after a successful release (non-fatal).
3
+ # Environment: RLSBL_VERSION is set to the released version.
4
+ # Customize this for your project (e.g., local install, deploy, notify).
5
+
6
+ set -euo pipefail
7
+
8
+ echo "Post-release: v$RLSBL_VERSION"
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env bash
2
+ # Pre-release validation hook.
3
+ # Runs before rlsbl creates a release. Exit non-zero to abort.
4
+ # Detects project type and runs appropriate checks automatically.
5
+
6
+ set -euo pipefail
7
+
8
+ echo "Running pre-release checks..."
9
+
10
+ if [ -f go.mod ]; then
11
+ echo "Detected Go project"
12
+ go vet ./...
13
+ go build ./...
14
+ go test ./... -race -short -count=1
15
+ elif [ -f package.json ]; then
16
+ echo "Detected npm project"
17
+ npm test
18
+ elif [ -f pyproject.toml ]; then
19
+ echo "Detected Python project"
20
+ if command -v uv &>/dev/null; then
21
+ uv run pytest
22
+ elif command -v pytest &>/dev/null; then
23
+ pytest
24
+ fi
25
+ fi
26
+
27
+ echo "Pre-release checks passed."
@@ -0,0 +1 @@
1
+ 0.17.0
@@ -0,0 +1,166 @@
1
+ # claudewheel Changelog
2
+
3
+ ## 0.3.0
4
+ - Publish to PyPI: `pip install claudewheel` or `uv pip install claudewheel` now works alongside the existing npm distribution
5
+ - Lower minimum Python version from 3.14 to 3.10 (the JS wrapper now reads requires-python from pyproject.toml instead of hardcoding)
6
+
7
+ ## 0.2.1
8
+ - Fix: disallowedTools were never enforced -- the wizard wrote to a top-level `disallowedTools` key in settings.json that Claude Code silently ignores
9
+ - Enforcement now uses `--disallowedTools` CLI flag in launch.py, which strips tools from the model's context entirely
10
+ - Persist tool list under `settings.claudewheel.disallowedTools` (namespaced, not a Claude Code key)
11
+ - Health check detects missing tools in claudewheel namespace and flags stale top-level key
12
+ - patch-profiles migrates existing profiles: moves tools to new namespace, deletes inert key
13
+
14
+ ## 0.2.0
15
+ - Enforce disallowedTools across all profiles: 19 Claude Code tools disabled via settings.json (plan mode, worktree, task tracking, cron, notebook, push notifications, remote triggers, LSP, skill auto-invoke)
16
+ - Disable auto permission mode across all profiles (permissions.disableAutoMode)
17
+ - Remove "auto" from permissions segment options
18
+ - Wizard applies disallowedTools and disableAutoMode to new profiles automatically
19
+ - Health check flags profiles missing disallowedTools or disableAutoMode
20
+ - Add scripts/patch-profiles to retrofit existing profiles
21
+
22
+ ## 0.1.13
23
+ - Schema-versioned config migrations: existing users' github segment automatically fixed to optional
24
+ - Minimap character configurable via `overflow.minimap_char` theme key
25
+ - Config migration runs on startup, adds missing keys and applies one-time value fixes
26
+
27
+ ## 0.1.12
28
+ - Fix minimap: use small square (▪) instead of full block so focused segment's background highlight is visible
29
+
30
+ ## 0.1.11
31
+ - Viewport scrolling for narrow terminals: bar scrolls horizontally with focused segment centered
32
+ - Edge arrows (`<2`, `3>`) show off-screen segment count at viewport edges
33
+ - Minimap: colored block indicators in top-right corner showing all segments at a glance
34
+ - Configurable minimap visibility (`"minimap": "auto"` or `"always"` in config.json)
35
+ - Overflow theme colors: `arrow_fg`, `minimap_fg`, `minimap_focused_bg` in the `overflow` theme section
36
+ - Clip partially visible segments at viewport edges instead of rendering past margins
37
+ - Clip fan-out options at screen edges when scrolling
38
+ - Minimum width guard for degenerate terminals (< 9 columns)
39
+ - Config migration: missing default keys are merged into existing config/segments/theme files on startup
40
+ - Wide terminals see no visual change (viewport only activates when the bar overflows)
41
+
42
+ ## 0.1.10
43
+ - Fix backspace in freeform segments trapping arrow keys (emptying the buffer now exits edit mode; LEFT/RIGHT work mid-edit)
44
+ - Make GitHub segment optional (launching without a GH profile is legitimate)
45
+
46
+ ## 0.1.9
47
+ - Add `--version` flag (prints app version)
48
+ - Add `-s`/`--set KEY=VALUE` flag for setting any segment value (e.g. `-s version=2.1.119`)
49
+ - `-s` is required for the `version` segment (its `--version` flag collides with the app version flag)
50
+ - `-s` takes precedence over individual `--<segment>` flags; validates segment name and format
51
+
52
+ ## 0.1.8
53
+ - Add `print_mode` toggle to segment definitions; segments declare whether they participate in `-p` mode
54
+ - Exclude `github`, `mcp`, `permissions` segments from print mode by default (github is slow, mcp unreliable non-interactively, permissions can hang on interactive-only modes)
55
+ - Fix health check blocking `input()` in print mode; warnings now go to stderr without blocking
56
+ - Warn to stderr when print mode uses fallback defaults for missing required segments
57
+
58
+ ## 0.1.7
59
+ - Add `-p`/`--print` flag for non-interactive print mode
60
+ - Add `--` passthrough for raw Claude Code flags (e.g. `--output-format`, `--allowedTools`)
61
+ - Add `scripts/redir-history.sh` for rewriting paths in history.jsonl files
62
+
63
+ ## 0.1.6
64
+ - Default directory segment to current working directory
65
+ - Raise `/tmp/claude` health check threshold from 500 MB to 2 GB
66
+
67
+ ## 0.1.5
68
+ - Add `--redir OLD NEW` subcommand for redirecting session data after a project directory rename
69
+ - Fix `--redir` to find `.claude.json` project keys under `data["projects"]` (not top-level)
70
+ - Fix `--redir --dry-run` to report accurate JSONL file/line counts
71
+ - Rename Python package from `claude_launcher` to `claudewheel`
72
+ - Simplify README quick start, add `--redir` to CLI docs
73
+
74
+ ## 0.1.4
75
+ - Rename all internal references from ClaudeLauncher to claudewheel (CLI output, User-Agent)
76
+ - Add branding assets (logo, banner) and banner to README
77
+
78
+ ## 0.1.3
79
+ - Fix freeform backspace bug: can now delete to empty string without resetting
80
+
81
+ ## 0.1.2
82
+ - Exclude `__pycache__` bytecode from npm tarball (package size: 75kB -> 26kB)
83
+
84
+ ## 0.1.1
85
+ - Remove hardcoded personal data from defaults (profile names, GitHub usernames)
86
+ - Add runtime discovery for profile segment (`claude_config_scan` — scans `~/.claude-*` directories)
87
+ - Add runtime discovery for github segment (`gh_auth` — parses `gh auth status`)
88
+ - Expand directory scan parents to common project directories
89
+
90
+ ## 0.1.0
91
+ - Initial npm release as `claudewheel`
92
+ - Node.js bin wrapper with Python 3.14+ version check
93
+
94
+ ## Architecture
95
+
96
+ - 16-module Python package (no external deps, stdlib only -- targets Python 3.14)
97
+ - Bash shim `c` as entry point, sets `PYTHONPATH` and runs `python3 -m claude_launcher`
98
+ - Tests via stdlib `unittest` (61+ tests, run in <10 ms)
99
+
100
+ ## TUI
101
+
102
+ - Single-line segment bar at vertical-centre-left of the terminal
103
+ - Vertical fan-out shows other options above/below the selected value
104
+ - Per-segment focus background; per-option foreground colours from theme
105
+ - Fuzzy search with character-position highlighting (matched chars in `search_match_fg`)
106
+ - Search buffer turns red (`search_no_match_fg`) when zero matches
107
+ - "+" sentinel option for creatable segments (profile, github, model) lets users add new values inline
108
+ - Freeform editing on directory segment: backspace/typing on a selected value enters edit mode
109
+ - Cycle math includes -1 (blank) as a ring position; symmetric blank reachability for both `wrap=True` and `wrap=False`
110
+
111
+ ## Discovery
112
+
113
+ - `npm_and_local` for versions: fetches `npm view @anthropic-ai/claude-code versions --json` (cached 1 h in `state.json`), merges with locally installed binaries
114
+ - `directory_scan`: lists subdirectories of configured parent dirs (`~/Projects`, `~/Work`)
115
+ - `state_field`: merges state-tracked recent values
116
+ - `directory_listing`: simple file listing (legacy, used by older configs)
117
+
118
+ ## Cross-segment dependencies
119
+
120
+ - Options can declare `requires` constraints on other segments' values (e.g. `auto` permission previously required version >=2.1.110, since dropped)
121
+ - `evaluate_requires(bar)` recomputes per-segment `unavailable` sets on every keypress
122
+ - Renderer dims unavailable options with `unavailable_fg`
123
+
124
+ ## Install mechanism
125
+
126
+ - Direct binary download from Anthropic's GCS bucket (the same mechanism Claude Code's own updater uses): `storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases/{ver}/{platform}/claude`
127
+ - Fetches `manifest.json` first for SHA-256 checksum
128
+ - Streams ~234 MB binary with progress reporting
129
+ - Atomic write via `.downloading` -> rename
130
+ - Replaces the original npm-based approach which failed on user-prefix installs
131
+
132
+ ## CLI
133
+
134
+ - Dynamic `--<segment_key>` flags generated from segment definitions
135
+ - TUI shown by default (pre-filled from `last_config` + arg overrides)
136
+ - TUI skipped only when args alone cover every required segment
137
+ - Passthrough flags `-c` / `--continue` and `-r` / `--resume [SESSION_ID]` for Claude Code's session restore
138
+ - One-shot flags: `--versions`, `--config`, `--health`, `--install VERSION`, `--uninstall VERSION`, `--reset-options`, `--show`
139
+
140
+ ## Health checks
141
+
142
+ - tmpfs quota (warns >80%)
143
+ - `/tmp/claude-$UID/` size (warns >500 MB)
144
+ - Ghost files check removed -- was misidentifying memfd regions as leaks
145
+
146
+ ## State persistence
147
+
148
+ - `last_config` (segment selections from last launch)
149
+ - `recent_dirs` (cap 20, dedup, recent-first)
150
+ - `launch_count`
151
+ - `npm_versions_cache` (1 h TTL)
152
+ - Atomic writes via tmp-file rename
153
+
154
+ ## Hooks
155
+
156
+ - `~/.claudelauncher/hooks/pre-launch*` scripts run before `exec`
157
+ - Receive segment selections as `CL_*` env vars
158
+ - Nonzero exit aborts launch
159
+
160
+ ## Notable upstream issue
161
+
162
+ - Filed and closed [#54026](https://github.com/anthropics/claude-code/issues/54026) as duplicate of [#53180](https://github.com/anthropics/claude-code/issues/53180): Claude Code 2.1.120 `--resume` crashes due to `RW4` hook returning fewer keys than the destructure call expects. Workaround: use 2.1.116 or 2.1.119 until upstream ships a fix.
163
+
164
+ ## Open future work
165
+
166
+ - Session-picker-as-segment (filed in `todo/session-segment.md`)
@@ -0,0 +1,45 @@
1
+ # claudewheel
2
+
3
+ A TUI launcher for Claude Code: pick a profile, model, directory, MCP mode, and permissions from a horizontal segment bar, then launch.
4
+
5
+ ## Release workflow
6
+
7
+ This project uses [rlsbl](https://github.com/smm-h/rlsbl) for release orchestration.
8
+
9
+ - Update CHANGELOG.md with a `## X.Y.Z` entry describing changes
10
+ - Run `rlsbl release [patch|minor|major]` to bump version and create a GitHub Release
11
+ - CI handles `npm publish` automatically via OIDC Trusted Publishing (no tokens needed)
12
+ - First publish must be done locally: `npm login && npm publish --access public`
13
+ - After first publish, configure Trusted Publishing on npmjs.com (package settings)
14
+ - Never run `npm publish` manually after Trusted Publishing is configured
15
+ - Use `rlsbl release --dry-run` to preview a release without making changes
16
+
17
+ ## Architecture
18
+
19
+ - `claudewheel/renderer.py` -- TUI rendering: segment bar, fan-out options, viewport scrolling, minimap, edge arrows
20
+ - `claudewheel/app.py` -- TUI event loop, keyboard handling, SIGWINCH resize
21
+ - `claudewheel/segment.py` -- Segment/SegmentBar dataclasses, option discovery
22
+ - `claudewheel/config.py` -- ConfigManager: loads/saves JSON configs, key migration, schema-versioned value migrations
23
+ - `claudewheel/defaults.py` -- All DEFAULT_* dicts (config, segments, options, state, themes)
24
+ - `claudewheel/theme.py` -- ThemeColors dataclass, hex-to-ANSI parsing
25
+ - `claudewheel/terminal.py` -- Raw terminal I/O, key reading, alt screen
26
+ - `claudewheel/constants.py` -- Paths, ANSI escape sequences
27
+ - `claudewheel/launch.py` -- Builds the exec command from selections
28
+ - `claudewheel/cli.py` -- CLI argument parsing, one-shot commands
29
+
30
+ ## Config system
31
+
32
+ - Config files live in `~/.claudelauncher/` (config.json, segments.json, options.json, state.json, themes/)
33
+ - On startup, `_migrate()` adds missing keys from DEFAULT_* without overwriting user values
34
+ - `_run_versioned_migrations()` applies one-time value fixes keyed by `_schema_version` in config.json
35
+ - New migrations go in the `_MIGRATIONS` list in config.py with an incremented version number
36
+
37
+ ## Viewport scrolling
38
+
39
+ When the segment bar overflows the terminal width, the renderer activates a scrolling viewport:
40
+ - `_compute_bar_layout()` pre-computes logical column positions for all segments
41
+ - `_compute_viewport()` centers the focused segment with ARROW_MARGIN (4 chars) reserved on each side
42
+ - Segments outside the viewport are skipped; partially visible ones are clipped at the margins
43
+ - Edge arrows show off-screen segment counts; minimap shows colored squares in the top-right
44
+ - Config key `"minimap"` controls visibility: `"auto"` (only when scrolling) or `"always"`
45
+ - Theme section `"overflow"` controls arrow/minimap colors and the minimap character
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 smm-h
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.4
2
+ Name: claudewheel
3
+ Version: 0.3.0
4
+ Summary: TUI launcher for Claude Code
5
+ Project-URL: Homepage, https://github.com/smm-h/claudewheel
6
+ Project-URL: Repository, https://github.com/smm-h/claudewheel
7
+ Author-email: smm-h <smmh72@gmail.com>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: claude,claude-code,config,launcher,rlsbl,tui
11
+ Classifier: Environment :: Console
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Software Development :: User Interfaces
15
+ Requires-Python: >=3.10