Conversation
The post-clone hook was installing lefthook directly via Homebrew, but mise.toml already manages lefthook. Instead, install mise itself (via Homebrew on macOS, via install script on Linux) and let `mise install` provision all tools including lefthook. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split the 1,132-line git.rs into a git/ module with focused submodules: - mod.rs: GitCommand struct, constructor, gitoxide discovery - config.rs: config_get, config_set, config_unset, config_get_global - refs.rs: show_ref_exists, for_each_ref, symbolic_ref, rev_parse, rev_list, merge_base, cherry - remote.rs: fetch, push, pull, ls_remote, remote_list, remote_get_url - worktree.rs: worktree_add/remove/list/move, find_worktree_for_branch, resolve_worktree_path - branch.rs: branch_delete, branch_list_verbose, checkout - stash.rs: has_uncommitted_changes, stash_push/pop/apply/drop - clone.rs: clone_bare, init_bare, setup_fetch_refspec - oxide.rs: moved from git_oxide.rs (gitoxide backend implementations) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split the monolithic hook_progress.rs (1,075 lines) into focused submodules: - formatting.rs: color constants, duration formatting, header/summary box drawing - interactive.rs: HookProgressRenderer (indicatif-based rich terminal output) - plain.rs: PlainHookRenderer (CI/pipe-friendly plain text output) - mod.rs: shared types (JobOutcome, JobResultEntry), HookRenderer enum, standalone functions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce src/core/ module with traits that allow core business logic to report progress and trigger hooks without depending on Output or HookExecutor: - ProgressSink trait with NullSink (no-op) implementation - OutputSink adapter bridging ProgressSink to the Output trait - HookRunner trait with NoopHookRunner implementation - HookOutcome simplified result type for core operations These abstractions will be used in Phase 3 when extracting command business logic into core::worktree modules. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move carry command's business logic into core::worktree::carry module: - CarryParams/CarryResult structs define the operation interface - execute() function uses ProgressSink instead of direct println! - Command layer becomes thin orchestrator: parse args, call core, render This is the template for extracting all remaining commands. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move init command's business logic into core::worktree::init module: - InitParams/InitResult structs define the operation interface - execute() function uses ProgressSink instead of direct Output calls - Command layer orchestrates: parse args, call core, render, run exec, cd_path - All existing tests continue to pass via run_with_output Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces CommandBridge adapter that implements both ProgressSink and HookRunner, allowing core operations to trigger hooks without depending on concrete hook or output implementations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hooks remain in the command layer due to clone-specific trust semantics (--trust-hooks, --no-hooks, check_hooks_notice). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move eject logic (worktree parsing, target resolution, dirty checks, file staging, index initialization) into src/core/worktree/flow_eject.rs. Command file becomes a thin orchestrator using CommandBridge for per-worktree pre/post-remove hook execution. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move prune logic (gone branch detection, worktree removal with dirty checks, deferred branch handling, CD target resolution, empty parent cleanup) into src/core/worktree/prune.rs. Command file becomes a thin orchestrator using CommandBridge for per-worktree removal hooks. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move all branch-delete business logic (argument resolution, validation, merge checking, deletion execution, hook invocation) from commands/branch_delete.rs into core/worktree/branch_delete.rs. The command file becomes a thin orchestrator that parses args, creates a CommandBridge, calls core::execute(), and renders the structured result. Public types: BranchDeleteParams, BranchDeleteResult, DeletionResult, ValidationError. The core uses ProgressSink for progress messages and HookRunner for pre/post-remove hooks with RemovalReason::Manual. All 11 unit tests moved to the core module alongside the types they test. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move settings, remote, config, and multi_remote modules from src/ into src/core/ where they belong as business logic. Use re-exports in lib.rs to maintain backward-compatible import paths. Refactor multi_remote/migration.rs to use ProgressSink instead of Output trait, completing the core/UI separation for that module. Modules moved: - settings.rs → core/settings.rs - remote.rs → core/remote.rs - config.rs → core/config.rs - multi_remote/ → core/multi_remote/ Skipped hints.rs and update_check.rs (UI-layer dependencies). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move all repository query functions, URL parsing, and dependency checking from src/lib.rs into src/core/repo.rs. Move WorktreeConfig to src/core/worktree/mod.rs. Re-export everything from lib.rs for backward compatibility. lib.rs is now a thin layer containing only: VERSION/CD_FILE_ENV constants, get_clap_args() (CLI-specific), module declarations, and re-exports. Removed unused functions (ensure_directory_exists, cleanup_on_error, change_to_original_dir) that duplicated src/utils.rs functionality. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rait Add `output: &mut dyn Output` parameter to cmd_dump, cmd_validate, cmd_install, and cmd_migrate. Wire up CliOutput in hooks/mod.rs run() and pass it to all subcommand handlers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add `output: &mut dyn Output` parameter to cmd_run, cmd_status, and all trust subcommands. Interactive prompts remain as print! + stdin. Pager output path preserved as-is with output.raw() for non-pager path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create CliOutput in cmd_status and cmd_set_default instead of using raw println. Use detail(), list_item(), and result() for structured output. cmd_enable and cmd_disable already used the Output trait. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ilent Replace `verbose: bool` parameter on enable_style() with `output: &mut dyn Output`. Remove create_symlink_silent() - callers that want silent behavior pass a quiet CliOutput instead. All internal functions (create_symlink, remove_symlink, cmd_status, cmd_list, cmd_enable, cmd_disable, cmd_only) now accept output parameter. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create CliOutput in run() and use output methods for all messages. Pass quiet CliOutput to enable_style() so shortcut creation is silent during setup (setup prints its own summary). Interactive prompt stays as print! + stdin. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Doctor retains its own quiet/verbose filtering logic - Output is just the print sink with quiet=false. All println!/print! calls in print_results, print_summary, preview_fixes, and apply_fixes now go through output.info() and output.warning(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/core/modules with the Output trait abstractionprintln!/eprintln!to the Output trait, completing the UI/logic separationPhase breakdown (25 commits):
src/core/worktree/src/core/Design decisions
print!+ stdin) stay outside the Output traitshortcuts::enable_style()API changed fromverbose: booltooutput: &mut dyn OutputTest plan
mise run fmt- formatting cleanmise run clippy- zero warningsmise run test:unit- all 364 tests passprintln!/eprintln!remain in src/commands/🤖 Generated with Claude Code