# Core Architecture of the Worktrunk CLI: A Deep Dive into the Rust Implementation

> Explore the core architecture of the Worktrunk CLI. Learn how its Rust implementation uses branch-first worktree addressing and safe Git integration for secure worktree management.

- Repository: [Maximilian Roos/worktrunk](https://github.com/max-sixty/worktrunk)
- Tags: deep-dive
- Published: 2026-09-14

---

**The Worktrunk CLI employs a layered Rust architecture with branch-first worktree addressing, safe Git integration through environment scrubbing, and an approval-gated hook system to manage Git worktrees securely and responsively.**

The core architecture of the Worktrunk CLI is built in Rust to orchestrate Git worktrees through a strictly layered design that prioritizes safety and extensibility. This command-line tool manages complex Git operations while providing responsive user interfaces and project-specific automation hooks.

## Entry Point and Command Dispatch

The application follows a clear separation between argument parsing and command execution. In [`src/main.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/main.rs), the CLI parses arguments using Clap, initializes logging, and delegates to the command dispatcher defined in [`src/lib.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/lib.rs). The dispatcher maps sub-commands to concrete handlers while injecting a shared **Context** struct containing the repository handle, configuration, and UI state.

This architecture ensures that every command handler receives a consistent execution environment without redundant initialization code.

## Domain Logic and Worktree Operations

User-facing commands live in `src/commands/*`, with specific implementations like [`src/commands/worktree/switch.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/commands/worktree/switch.rs) handling the `wt switch` workflow. The core architectural principle here is **branch-first worktree addressing**: all worktree operations resolve by branch name first through `Repository::resolve_worktree`, treating paths merely as aliases rather than primary identifiers.

This design choice removes ambiguity and aligns closely with Git's native semantics. The worktree model itself is defined in [`src/commands/worktree/types.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/commands/worktree/types.rs), which enforces a strict one-to-one mapping between branches and worktrees while providing helpers for creation, removal, and promotion.

## Safe Git Integration

External process execution is strictly controlled through the `shell_exec::Cmd` abstraction in [`src/git/repository/mod.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/mod.rs). Every Git command runs through this wrapper, which provides three critical safety guarantees:

- **Environment sanitization**: `Cmd::scrub_git_discovery_env_vars` clears `GIT_DIR`, `GIT_WORK_TREE`, and related variables before spawning child processes
- **Structured output parsing**: Preference for machine-readable flags like `--porcelain=v2` and `--json` over human-readable text
- **Unified error handling**: Consistent tracing via `[wt-trace]` prefixes and exit-code semantics

Direct calls to `std::process::Command` are prohibited throughout the codebase, ensuring all external interactions follow the safety protocol.

## Worktree Model and Hook System

The hook system in [`src/commands/hook_plan.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/commands/hook_plan.rs) implements an **approval gate** architecture. Project-defined hooks (pre-merge, post-switch, etc.) load into a `HookPlan` structure but execute only after explicit user approval through `commands::command_approval`. This protects against arbitrary code execution when cloning repositories with embedded hook definitions.

The worktree representation in [`src/commands/worktree/types.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/commands/worktree/types.rs) maintains the branch-first invariant, ensuring that operations like promotion and removal maintain repository integrity.

## Output and Configuration Layers

Worktrunk implements **progressive output** through [`src/output/mod.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/output/mod.rs). Commands stream output line-by-line via `Cmd::stream`, rendering the first frame instantly while deferring network calls (like CI status fetches) to background tasks. The output layer supports multiple formats—human-readable, JSON, and LLM-friendly—selected at runtime.

Configuration management in [`src/config/user/mod.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/config/user/mod.rs) handles TOML parsing, deprecation migrations, and typed accessors (`require_*`, `set_*` methods). All configuration changes flow through `wt config update` to maintain version-controlled state.

## Diagnostic Tracing

Performance analysis is built into the core architecture through [`src/trace/timeline.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/trace/timeline.rs). This module records command-level timing information and writes structured trace files, enabling the `wt-perf` tooling to analyze bottlenecks without impacting normal operations.

## Practical Implementation Examples

Switching to a branch with automatic worktree creation:

```rust
use worktrunk::commands::worktree::switch::run_switch;

// Equivalent to: wt switch feature/login --create
run_switch(&ctx, "feature/login", SwitchOptions { create: true })?;

```

Executing the approval-gated hook system:

```rust
use worktrunk::commands::hook_plan::HookPlan;

let plan = HookPlan::load(&ctx)?;
plan.execute(&ctx)?; // Approval step happens internally

```

Outputting structured data for scripting integration:

```rust
use worktrunk::output::json::write_json;

// Equivalent to: wt list --format json
write_json(&ctx, &worktree_data)?;

```

## Summary

- **Layered dispatch**: [`src/main.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/main.rs) handles CLI parsing while [`src/lib.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/lib.rs) orchestrates command execution with dependency injection
- **Branch-first addressing**: The `Repository::resolve_worktree` method treats branch names as canonical identifiers, with paths as secondary aliases
- **Safe execution**: `Cmd::scrub_git_discovery_env_vars` prevents Git discovery leaks, and `shell_exec::Cmd` wraps all external processes
- **Approval gates**: The `HookPlan` system requires explicit user consent before executing project-defined automation
- **Progressive rendering**: `Cmd::stream` provides immediate UI feedback while background tasks handle latency-sensitive operations
- **Structured configuration**: [`src/config/user/mod.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/config/user/mod.rs) manages typed TOML access with migration support and version control integration

## Frequently Asked Questions

### How does Worktrunk prevent Git environment leaks between commands?

According to the Worktrunk source code, the `Cmd::scrub_git_discovery_env_vars` method clears `GIT_DIR`, `GIT_WORK_TREE`, and related environment variables before spawning any child process. This guarantees that external tools cannot accidentally operate on the wrong repository, even when Worktrunk itself is running inside a complex Git environment.

### Why does Worktrunk require user approval before running hooks?

The hook system implemented in [`src/commands/hook_plan.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/commands/hook_plan.rs) enforces an approval gate through `commands::command_approval` to prevent arbitrary code execution. This security measure ensures that freshly cloned repositories cannot execute malicious hooks immediately upon first use, protecting users from supply-chain attacks embedded in project automation scripts.

### What makes Worktrunk's output responsive on slow connections?

The architecture implements progressive output streaming via `Cmd::stream` in the output layer ([`src/output/mod.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/output/mod.rs)). The CLI renders the first frame instantly while deferring network-dependent operations (such as CI status checks) to background tasks. This approach maintains interface responsiveness regardless of connection latency.

### How does the branch-first addressing model simplify worktree management?

Rather than managing paths and branches as separate namespaces, `Repository::resolve_worktree` treats the branch name as the canonical identifier and paths as derived aliases. This design eliminates ambiguity about which worktree belongs to which branch and mirrors Git's native semantics, reducing complexity in commands like `wt switch` and `wt merge`.