Skip to content
claudewheel.launch
Edit
On this page

Launch logic for resolving selections into a Claude Code invocation.

#claudewheel.launch

#claudewheel.launch

Map TUI selections to binary path, env vars, flags, and exec.

#fetch_gh_token

python
def fetch_gh_token(account: str) -> str | None

Fetch GH token live via gh CLI. Returns None on failure.

#resolve_launch_config

python
def resolve_launch_config(selections: dict[str, str | None], options_def: dict[str, Any], default_flags: list[str], locator: BinaryLocator, profiles: ProfileStore, extra_flags: list[str] | None=None, metadata: dict[str, dict[str, dict[str, Any]]] | None=None, client: str='claude', clients_config: dict[str, Any] | None=None, passthrough: list[str] | None=None, *, lifecycle_dir: Path) -> tuple[str, list[str], dict[str, str]]

Build (cwd, argv, env) for os.execvpe from TUI selections.

Maps segment values to their concrete effects. The env and cwd (the target-agnostic pieces) are assembled here; the argv is delegated to the selected client adapter in :mod:claudewheel.clients:

  • profile -> CLAUDE_CONFIG_DIR + OAuth token env vars via profiles (shared)
  • github -> GH_TOKEN env var, fetched live via gh CLI (shared)
  • directory -> os.chdir target (shared)
  • model -> resolved model id (shared), then formatted per client
  • version / mcp / permissions / session flags -> client-specific argv

The client names an entry in :data:claudewheel.clients.CLIENT_ADAPTERS ("claude" preserves the historical behavior exactly; "miniclaude" targets the miniclaude REPL). clients_config is the clients section of config.json (used by the miniclaude adapter to locate its binary). passthrough is the tail of extra_flags that came from args after --; the claude adapter appends it verbatim, the miniclaude adapter rejects it.

The selected profile is resolved through the injected profiles ProfileStore -- the single source of profile identity. A named profile that no longer exists raises :class:ValueError (the hard-error contract that replaced the old silent ~/.claude fallback); a corrupt token entry raises :class:TokenStoreError.

The "default" profile -- selected explicitly OR reached via the no-profile fallback -- is the VANILLA path: ~/.claude is Claude Code's own config dir, managed by Claude Code and strictly read-only to cw. The built env therefore carries NEITHER CLAUDE_CONFIG_DIR (any ambient one inherited from os.environ is explicitly removed) NOR CLAUDE_CODE_OAUTH_TOKEN (no token injection, even if a token entry exists under ~/.claude).

When metadata is provided (TUI path), use it for model lookups. When None (skip-TUI path), fall back to reading from options_def.

The env also carries the LAUNCH FACTS: CLAUDEWHEEL_LIFECYCLE_DIR (lifecycle_dir, where the session lifecycle store is) plus one CLAUDEWHEEL_LAUNCH_* variable per selection claudewheel actually made. The SessionStart/SessionEnd hook scripts read them, because a session cannot otherwise tell which profile, version, model or permissions mode it was launched with. A selection claudewheel did not make sets no variable -- and clears an inherited one, so a launcher run from inside a launched session never passes its parent's facts off as the child's.

#do_launch

python
def do_launch(cwd: str, argv: list[str], env: dict[str, str]) -> Any

Change to directory and exec Claude Code. Does not return.

Under --dry-run there is nothing to replace this process with: the exec is recorded and the carrier standing in for it is returned, so the dispatch can finish and the would-do log can render.

More tools from this site

  • claudestream Drive Claude Code from Python: run it as a subprocess and read its output as typed events, with async and sync sessions, sandbox policies, and tools you define in Python
  • dirstat Fast, single-binary directory statistics CLI: every file under a tree grouped by format, with counts, sizes, and lines of code, as a colored terminal table or as JSON
  • fastware A batteries-included ASGI framework: msgspec JSON, a managed Granian server, dependency injection, SSE, WebSockets, auth, and a test client
  • go-toml-edit Zero-dep TOML editing library for Go with comment preservation
  • howmuchleft The fastest Claude Code statusline: context window, 5-hour, and weekly limit usage as three customizable gradient bars, rendering in about 6 ms
  • orxtra
  • pgdesign
  • predraw Declarative rendering pipeline: describe a scene in JSON and get SVG, PNG and WebP out, with light and dark style tokens, reusable components and text converted to path outlines
  • reposummary Turn a git repository's history into a Markdown journal: pick a time window or revision range and get a readable digest of what changed, optionally narrated by an LLM
  • rlsbl Release orchestration and project scaffolding CLI that bumps versions, validates a structured JSONL changelog, tags only the commit CI verified, and publishes to npm, PyPI, Go and more
  • safegit git wrapper CLI that gives each commit its own temporary index and retries ref updates on conflict, so concurrent agents share one repository
  • saferm Command-line replacement for rm that archives every deletion with a mandatory reason and the context it ran in, so deleted files can be listed, inspected and restored
  • selfdoc Static Site Generator that builds a project's documentation site directly from its source code, so the docs can never drift from the code they describe, with SEO/AEO, first-class blog, search, and cross-project linking built in
  • strictcli
  • stricttest An always-on test-isolation floor: a pytest plugin and a Go env-hygiene module that make a test suite structurally unable to reach real credentials, the real HOME, the network, or the development repository.
  • wesktop A Python framework that turns an ASGI web app into a desktop application, serving it from a local Granian server and displaying it in a native OS window via pywebview
Search