# https://github.com/yordan-kanchelov/sync-worktrees Project Manual

Generated at: 2026-07-07 23:41:45 UTC

## Table of Contents

- [Overview, Modes, and Configuration](#page-overview)
- [System Architecture and Sync Engine](#page-architecture)
- [Interactive TUI and MCP Server](#page-interfaces)
- [Safety, Trash, Maintenance, and Failure Modes](#page-safety)

<a id='page-overview'></a>

## Overview, Modes, and Configuration

### Related Pages

Related topics: [System Architecture and Sync Engine](#page-architecture), [Safety, Trash, Maintenance, and Failure Modes](#page-safety)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/README.md)
- [sync-worktrees.config.example.js](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/sync-worktrees.config.example.js)
- [src/index.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/index.ts)
- [src/types/index.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/types/index.ts)
- [src/utils/config-generator.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/utils/config-generator.ts)
- [src/utils/cli.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/utils/cli.ts)
</details>

# Overview, Modes, and Configuration

## Purpose and Scope

`sync-worktrees` is a Node.js / TypeScript utility that maintains a set of local git worktrees across one or more repositories from a single configuration file. Rather than being a generic git client, it is opinionated around three jobs: cloning bare repositories, creating a worktree per branch of interest on first run, keeping those worktrees up to date on subsequent runs, and exposing a guarded subset of the same operations to AI agents over MCP (`detect_context`, `list_worktrees`, branch-aware mutations). As of v4.0.0 the CLI no longer accepts ad-hoc flag arguments — every behavioral knob is declarative and lives in the user-authored config file `Source: [README.md:1-120]()` `Source: [src/index.ts:1-60]()`.

## Config-File-Only Workflow

Starting with v4.0.0 (`497c18e`), `sync-worktrees` collapsed to a one-action CLI: load a config and run it. Flags removed include `--repoUrl` / `-u`, `--worktreeDir`, branch filter flags, `--mode`, and friends, so replay and share-ability comes from version-controlled config rather than shell history `Source: [src/utils/cli.ts:1-120]()` `Source: [README.md:120-260]()`. The shipped template `sync-worktrees.config.example.js` doubles as both the canonical schema and the starting point every user copies from. The optional companion `init` command (`src/utils/cli.ts`) is the only interactive surface left: it walks the user through generating a working, self-documenting config file.

### Configuration Surface

The config is a CommonJS module exporting either a single repository descriptor or an array of them. The example file enumerates every field that `src/types/index.ts` accepts `Source: [sync-worktrees.config.example.js:1-180]()` `Source: [src/types/index.ts:1-200]()`:

| Field | Role |
| --- | --- |
| `repoUrl` | Remote used to clone the bare mirror. |
| `worktreeDir` | Parent directory for created worktrees; absolute paths are validated. |
| `mode` | Sync strategy (see *Sync Modes* below). |
| `runOnce` | When `true`, exit after the first full pass instead of looping. |
| `branches` / `branchFilter` | Include/exclude patterns for branches to materialize. |
| `lfs` / `lfsMode` | Whether and how to fetch LFS objects. |
| `depth` | Shallow-clone depth for the bare mirror. |
| `retry`, `parallelism` | Network resilience and concurrency. |
| `debug` | Per-repo verbose logging (git transfer progress is suppressed by default since v4.1.0). |
| `updateExistingWorktrees` | Whether to fetch & fast-forward existing worktrees on each pass. |
| `filesToCopyOnBranchCreate` | Relative-only file patterns (absolute and escaping patterns rejected after v5.1.1, F1–F20 review) copied from the default branch into each new worktree `Source: [sync-worktrees.config.example.js:80-180]()`. |

The v5.1.1 patch release tightened several of these fields: orphan cleanup can no longer delete a bare repo nested inside `worktreeDir`, default branches containing `/` are detected correctly, and `filesToCopyOnBranchCreate` rejects absolute patterns outright `Source: [src/types/index.ts:60-200]()`.

## Sync Modes

A repo's `mode` selector steers the sync engine's behavior on each pass. The `init` wizard introduced in v5.1.0 is *mode-aware*: its prompts branch on the chosen mode so the generated file is internally consistent `Source: [src/utils/config-generator.ts:1-160]()`. Three operational modes are recognized:

1. **Continuous / watch mode** — the default for interactive TUI use. The process loops, polling remotes on a schedule and applying updates to existing worktrees while creating any newly-matched branch worktrees.
2. **Run-once mode (`runOnce: true`)** — performs a single full pass per configured repo and exits non-zero on failure; well-suited to CI invocations and cron jobs.
3. **Bare-mirror mode** — clones a bare repository to seed local mirrors without creating per-branch worktrees; used by the multi-repo wizard when initializing sibling repos in a monorepo.

Lifecycle concerns that cross modes — such as treating worktrees with stashed changes as unsafe (v3.6.1, `3cf502b`) and stabilizing hook execution via child-process `onComplete` (v3.6.2, `a68bebc`) — are enforced uniformly by the orchestrator in `src/index.ts` `Source: [src/index.ts:60-240]()`.

## The `init` Wizard (v5.1.0+)

Before v5.1.0, scaffolding a multi-repo workspace meant running `init` once per repository. The rework in `c3ca559` changed this so a single wizard pass can declare an arbitrary number of repositories by looping with an "Add another repository?" prompt — the dominant monorepo-sibling case can therefore be set up in one shot `Source: [src/utils/cli.ts:120-260]()` `Source: [src/utils/config-generator.ts:120-260]()`. The output of the wizard is a `*.config.js` file with inline comments documenting every field (`self-documenting generated config`), removing the need for users to cross-reference the README while editing. After `init` writes the config, the wizard's last step is a one-shot dry-run so failures surface immediately rather than during unattended loops.

## Operational Notes from the Community

Community-reported concerns worth surfacing when reading this area:

- **CI lint policy.** Issue #38 tracks pipeline failures caused by prettier drift in the repository; when contributing config examples, run the project's formatter so the generated file passes the same linter the example file does `Source: [README.md:260-360]()`.
- **MCP safety surface.** v5.0.0 (`6bf58b5`) deliberately removed all deletion capabilities from the MCP server — `remove_worktree`, `list_trash`, `restore_trash`, and per-repo trash summaries. Configuration that previously assumed the agent could garbage-collect stale worktrees must now do so out-of-band `Source: [src/types/index.ts:200-340]()`.
- **Editor spawn correctness.** v5.1.1 fixes an ENOENT from v5.0.1 by tokenizing the `EDITOR` / `VISUAL` string before `spawn`, so values like `code -w` work for the "open in editor" TUI action `Source: [src/utils/cli.ts:60-180]()`.

For per-field schema details, see [Configuration Reference](./Configuration-Reference). For how the orchestrator steps through repos, see [Sync Engine and Lifecycle](./Sync-Engine-and-Lifecycle).

---

<a id='page-architecture'></a>

## System Architecture and Sync Engine

### Related Pages

Related topics: [Overview, Modes, and Configuration](#page-overview), [Interactive TUI and MCP Server](#page-interfaces), [Safety, Trash, Maintenance, and Failure Modes](#page-safety)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/services/worktree-mode-sync-runner.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/worktree-mode-sync-runner.ts)
- [src/services/clone-sync.service.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/clone-sync.service.ts)
- [src/services/worktree-sync.service.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/worktree-sync.service.ts)
- [src/services/worktree-sync-planner.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/worktree-sync-planner.ts)
- [src/services/git.service.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/git.service.ts)
- [src/services/config-loader.service.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/config-loader.service.ts)
</details>

# System Architecture and Sync Engine

The `sync-worktrees` project is a single-purpose CLI that loads a config file and synchronizes a set of git worktrees across one or more configured repositories. As of v4.0.0 the CLI surface was deliberately collapsed: there are no per-run flags, every knob — `runOnce`, branch filters, LFS, mode, depth, retry, parallelism, debug, `updateExistingWorktrees`, etc. — is expressed in the config file. The sync engine is therefore the heart of the program and is the only subsystem that actually performs work after configuration is loaded. Source: [src/services/config-loader.service.ts:1-1]()

## High-Level Architecture

The system is layered as a pipeline: a top-level runner selects a per-repository sync strategy, the chosen service builds a plan from the live git state, and a low-level `GitService` issues the underlying `git` operations while emitting progress. Two main execution modes are supported:

- **Worktree mode** — the bare repository already exists locally; the engine reconciles its checked-out worktrees against the desired set of branches.
- **Clone mode** — the repository is fetched from a remote URL, optionally as a bare repo, and then expanded into worktrees.

Each configured repository is processed independently, and the v3.6.2 hardening pass serialized repository mutations through a shared lock so the MCP server and the sync runner cannot interleave destructive operations on the same repo. Source: [src/services/worktree-mode-sync-runner.ts:1-1](), [src/services/clone-sync.service.ts:1-1]()

```mermaid
flowchart TD
    A[config-loader.service.ts] --> B{Per Repository}
    B -->|existing bare repo| C[worktree-mode-sync-runner.ts]
    B -->|remote URL| D[clone-sync.service.ts]
    C --> E[worktree-sync.service.ts]
    D --> E
    E --> F[worktree-sync-planner.ts]
    F --> G[git.service.ts]
    G --> H[(git CLI)]
    G --> I[Logger / TUI]
```

The two mode-specific runners converge on `worktree-sync.service.ts`, which owns the create/update/remove decisions for a single repository, and delegates the actual reconcile logic to the planner. The planner compares desired branches (derived from the config's branch filters) against the worktree list returned by `GitService` and produces a list of actions — add, update, leave — that the sync service then executes. Source: [src/services/worktree-sync.service.ts:1-1](), [src/services/worktree-sync-planner.ts:1-1]()

## The Sync Engine Core

The core engine is split across three cooperating services.

### Planner: Desired vs. Actual State

`worktree-sync-planner.ts` is a pure module that turns (a) the list of branches that should exist and (b) the list of worktrees that already exist into a set of operations. It does not touch git directly; it only computes the diff. The planner is the place where config-derived concerns like branch include/exclude filters, default-branch handling, and `updateExistingWorktrees` are translated into discrete actions. Because it is pure, the same planner is reused by the worktree-mode runner, the clone-mode runner, and the MCP tool surface, which keeps behavior consistent across UIs. Source: [src/services/worktree-sync-planner.ts:1-1]()

### Sync Service: Action Execution

`worktree-sync.service.ts` consumes the planner's output and invokes `GitService` to perform the actions. It is responsible for:

- Creating new worktrees for branches that are desired but missing — honoring `filesToCopyOnBranchCreate` (whose pattern handling was fixed in v5.1.1 to keep patterns relative and reject absolute/escaping forms).
- Updating existing worktrees when `updateExistingWorktrees` is enabled.
- Running configured hooks (the v3.6.2 release stabilized hook tests by awaiting `onComplete` instead of using a fixed sleep).
- Reporting per-worktree progress that the TUI surfaces (v4.1.0 added per-repository progress and disk-usage display). Source: [src/services/worktree-sync.service.ts:1-1]()

### GitService: The I/O Boundary

`git.service.ts` is the only module that shells out to `git` (via `simple-git`). It exposes typed methods for the operations the engine needs: clone, fetch, worktree add/remove, branch listing, and revision queries. As of v3.6.0 it wires `simple-git`'s progress events into the logger so long Bitbucket clones no longer appear to hang silently while the TUI shows "Cloning from …". v5.1.1 also tightened several safety paths here — orphan cleanup can no longer delete a bare repo nested under `worktreeDir`, and default branches containing `/` are detected correctly. Source: [src/services/git.service.ts:1-1]()

## Configuration, Modes, and Execution Flow

`config-loader.service.ts` is the single source of truth at startup. It validates the config, resolves repository entries, and hands the runner a normalized structure. Because v4.0.0 made the config the only place to express behavior, the loader is effectively the public API contract: every option the engine understands must be representable in the file produced by the v5.1.0 `init` wizard. Source: [src/services/config-loader.service.ts:1-1]()

Execution flow for a single configured repository:

1. The runner reads the repo entry and picks a strategy. If `repoUrl` is set and no bare repo is present at the local path, `clone-sync.service.ts` runs first and produces the bare repo; otherwise `worktree-mode-sync-runner.ts` runs directly.
2. The selected runner instantiates `worktree-sync.service.ts` for that repo, acquires the per-repo lock, and asks the planner for a plan.
3. The sync service executes the plan through `GitService`, emitting progress events that the v4.2.0 Ink v7 TUI renders (with `useWindowSize`, alternate screen, and incremental rendering).
4. On completion the runner records the result; in `runOnce: false` mode the loop sleeps and repeats.

This separation — loader → runner → sync service → planner → `GitService` — is what lets the same engine drive the CLI, the interactive TUI, and the MCP server tools without divergence, and is what the v3.6.2 and v5.1.1 safety fixes targeted when they hardened locks, hooks, and cleanup paths. Source: [src/services/worktree-mode-sync-runner.ts:1-1](), [src/services/clone-sync.service.ts:1-1](), [src/services/worktree-sync.service.ts:1-1](), [src/services/git.service.ts:1-1]()

### Related community context

- The v4.0.0 release notes describe the breaking move to a config-file-only CLI, which is the architectural premise of the engine.
- v3.6.2 and v5.1.1 patch notes describe the locking and safety guarantees that the sync engine now provides, especially around MCP-driven mutations and orphan cleanup.
- v4.1.0 and v4.2.0 release notes describe the TUI progress integration that consumes the events the engine emits.

---

<a id='page-interfaces'></a>

## Interactive TUI and MCP Server

### Related Pages

Related topics: [System Architecture and Sync Engine](#page-architecture), [Safety, Trash, Maintenance, and Failure Modes](#page-safety)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/services/InteractiveUIService.tsx](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/InteractiveUIService.tsx)
- [src/components/App.tsx](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/components/App.tsx)
- [src/components/BranchCreationWizard.tsx](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/components/BranchCreationWizard.tsx)
- [src/components/OpenEditorWizard.tsx](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/components/OpenEditorWizard.tsx)
- [src/components/WorktreeStatusView.tsx](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/components/WorktreeStatusView.tsx)
- [src/components/StatusBar.tsx](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/components/StatusBar.tsx)
- [src/mcp/server.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/mcp/server.ts)
- [src/mcp/tools/detectContext.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/mcp/tools/detectContext.ts)
</details>

# Interactive TUI and MCP Server

## Overview

The project ships two user-facing interaction surfaces that both observe — but never directly mutate the git state of worktrees without going through the sync pipeline:

1. An **Interactive TUI** built on [Ink v7](https://github.com/vadimdemedes/ink), used when the CLI is launched in a terminal. It drives branch creation, displays per-repository sync progress, and renders a live status view.
2. An **MCP (Model Context Protocol) server** that exposes a read-mostly tool surface so AI agents can enumerate worktrees, detect workspace context, and trigger actions safely.

Both surfaces share an underlying `GitService`, the same `WorktreeManager` lifecycle, and the same per-repository operation lock used by sync, which keeps concurrent mutations serialized (see release `v3.6.2`). They are deliberately separated so that humans and agents never compete for the same UI thread.

## Interactive TUI

### Rendering and Layout

The TUI is bootstrapped by `src/services/InteractiveUIService.tsx`, which mounts the root `App` component inside Ink's `<App>` host and applies three runtime options that were introduced in release `v4.2.0`:

- `useWindowSize` so the layout re-flows live on terminal resize.
- `alternateScreen` so prior scrollback is restored when the TUI exits.
- `incrementalRendering` to reduce flicker during redraws.

`Source: [src/services/InteractiveUIService.tsx:1-80]()`

Long git clone and fetch operations previously felt like a hang because simple-git swallowed progress; release `v3.6.0` re-wired `GitService` to surface clone/fetch progress through the logger that the TUI consumes, while keeping raw transfer progress out of normal logs by default. The TUI overlays user-meaningful milestones (e.g. `Cloning from "..."`) on top of that stream.

`Source: [src/components/WorktreeStatusView.tsx:1-120]()`

### Components

The TUI is composed of a small set of focused components:

- `src/components/App.tsx` — top-level router that decides whether to show the worktree status, the branch-creation wizard, or the open-editor wizard based on the current `uiMode` state.
- `src/components/BranchCreationWizard.tsx` — Ink multi-step prompt that collects a branch name, optional copy-pattern list, and confirms creation against the config's `filesToCopyOnBranchCreate`.
- `src/components/OpenEditorWizard.tsx` — editor picker that turns the `EDITOR` / `VISUAL` environment variable into a `(command, args)` tuple before invoking `spawn`. This split is the fix from release `v5.0.1` that resolves `ENOENT` failures when the env var contains flags like `code -w`.
- `src/components/WorktreeStatusView.tsx` — per-repository status grid. It now includes repository disk usage (added in `v4.1.0`) alongside branch, ahead/behind counts, and sync state.
- `src/components/StatusBar.tsx` — footer that surfaces global state: active mode, lock holder, last sync timestamp, and any in-flight error.

The `OpenEditorWizard` is the canonical example of why the TUI shells out through a helper rather than passing the raw env var to `spawn`: the wizard explicitly tokenizes the string on whitespace, treats the first token as the binary, and passes the remainder as argv so that values like `code -w --reuse-window` work correctly.

`Source: [src/components/OpenEditorWizard.tsx:1-60]()`

### Sync Progress

Per-repository sync progress was promoted from CLI logs into the interactive UI in release `v4.1.0`. The progress stream is keyed by repository, so multi-repo workspaces render one progress strip per repo instead of an interleaved log.

`Source: [src/components/App.tsx:1-150]()`

## MCP Server

The MCP server lives under `src/mcp/` and is registered alongside the CLI as an alternative entrypoint. Its tool surface is intentionally narrowed:

| Capability | Status | Notes |
|---|---|---|
| Enumerate worktrees (`list_worktrees`) | Available | Per-repo status; trash summary removed in `v5.0.0`. |
| Detect workspace context (`detect_context`) | Available | Config-driven, multi-repo aware (since `v3.6.3`). |
| Create worktree | Available | Routed through shared repo lock. |
| Remove worktree (`remove_worktree`) | **Removed** in `v5.0.0` | Breaking change; previously shipped. |
| `list_trash` / `restore_trash` | **Removed** in `v5.0.0` | Were unreleased; not in final surface. |

`detect_context` reports configured sibling repositories (including nested worktree directories and missing bare-repo presence), can include all configured repo worktrees via `includeAllWorktrees`, and surfaces per-repo enumeration errors — all derived from the same config file the CLI uses. This is what makes the server safe to point at a monorepo-style workspace without manual setup.

`Source: [src/mcp/tools/detectContext.ts:1-120]()`

### Concurrency Safety

Release `v3.6.2` made MCP repository mutations serialize through the same per-repo operation lock used by the sync engine. Combined with the `v3.6.1` rule that treats worktrees with stashed changes as unsafe to remove, the server cannot race the TUI or a background sync and cannot accidentally destroy dirty state.

`Source: [src/mcp/server.ts:1-200]()`

## Cross-cutting Concerns

Both surfaces share three guarantees that come from elsewhere in the codebase rather than from the UI layers themselves:

- **Config is the source of truth.** Since `v4.0.0`, all knobs (mode, depth, retry, parallelism, branch filters, `updateExistingWorktrees`, etc.) live in the config file, so the TUI prompts and the MCP `detect_context` read the same values.
- **Operations are locked per repo.** MCP mutations, the TUI's branch-creation wizard, and the sync engine all funnel through one mutex per repository, which is what made the `v3.6.2` fix possible.
- **Destructive operations were deliberately excised from the agent-facing surface.** The `v5.0.0` removals are an explicit safety choice: the MCP server is read-mostly by design, while the human-facing TUI keeps the workflows that need confirmation and rich feedback.

Together, the TUI gives a human operator a rich, resizable, scrollback-preserving console, while the MCP server gives an agent a narrow, config-driven, lock-aware view of the same workspace.

---

<a id='page-safety'></a>

## Safety, Trash, Maintenance, and Failure Modes

### Related Pages

Related topics: [Overview, Modes, and Configuration](#page-overview), [System Architecture and Sync Engine](#page-architecture), [Interactive TUI and MCP Server](#page-interfaces)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/services/trash.service.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/trash.service.ts)
- [src/services/trash-reaper.service.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/trash-reaper.service.ts)
- [src/services/trash-migration.service.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/trash-migration.service.ts)
- [src/services/removal-audit.service.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/removal-audit.service.ts)
- [src/services/git-maintenance.service.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/git-maintenance.service.ts)
- [src/services/repo-operation-lock.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/repo-operation-lock.ts)
- [src/services/clone-failure-recovery.service.ts](https://github.com/yordan-kanchelov/sync-worktrees/blob/main/src/services/clone-failure-recovery.service.ts)
</details>

# Safety, Trash, Maintenance, and Failure Modes

sync-worktrees operates on bare repositories, worktrees, and user files. Because the tool routinely creates, refreshes, and removes working directories on disk, the project treats destructive behavior as a first-class concern. This page documents the subsystems that protect users from accidental data loss, manage a recoverable trash lifecycle, keep git repositories healthy, and define what the system considers an unsafe or failed operation.

## Safety Architecture

The project enforces safety through three complementary mechanisms: serialized repository access, audited removals, and explicit guards on unsafe states.

**Repository operation lock.** All write-path operations against a single repository — sync, clone, MCP mutation, and removal — flow through `repo-operation-lock.ts`. This serializes operations so that, for example, an MCP `remove_worktree` invocation cannot race with an in-flight `git fetch` or with another MCP mutation against the same repo. v3.6.2 fixed a bug where MCP repository mutations bypassed this lock; they now share it with the sync path. Source: [src/services/repo-operation-lock.ts]()

**Removal audit.** `removal-audit.service.ts` records what was deleted, by which path, and under what conditions, so that an operator can reconstruct the chain of events leading to a missing worktree. The audit pairs with the trash subsystem: when an item is moved to trash rather than removed outright, the audit and the trash entry refer to the same logical operation. Source: [src/services/removal-audit.service.ts]()

**Unsafe-state guards.** The system refuses to remove a worktree that contains stashed changes. v3.6.1 introduced this check explicitly: a worktree with `git stash` entries is treated as unsafe to remove, even when other invariants suggest it is stale. Source: [src/services/removal-audit.service.ts]()

## Trash Subsystem

The trash layer exists so that worktrees and other disposable artifacts are not deleted on the first destructive pass; they are staged for later reaping, with a migration path for older on-disk layouts.

**Lifecycle and reaping.** `trash.service.ts` owns the staging directory and the metadata needed to restore or permanently delete an entry. `trash-reaper.service.ts` runs on a schedule (and after operations that produce trash) to purge entries that have aged past retention. `trash-migration.service.ts` reconciles older trash layouts with the current one, so that upgrading the tool does not orphan previously-trashed worktrees. Sources: [src/services/trash.service.ts](), [src/services/trash-reaper.service.ts](), [src/services/trash-migration.service.ts]()

**MCP surface deliberately reduced.** v5.0.0 removed all deletion capabilities from the agent-facing MCP server. The `remove_worktree` tool was removed (a breaking change versus earlier releases), and the unreleased `list_trash` and `restore_trash` tools, along with the per-repo trash summary on `list_worktrees`, were also dropped. The trash layer remains internally for safety and recovery, but agents can no longer trigger or inspect it directly. Source: [src/services/trash.service.ts]()

**Orphan-cleanup boundary.** v5.1.1 fixed a finding (F1 in REVIEW_FINDINGS.md) where orphan cleanup could delete a bare repo that was nested inside the configured `worktreeDir`. The cleanup now distinguishes between a bare repository and a worktree directory under the same parent, and refuses to remove the bare repo even when its path looks like an orphan. Source: [src/services/trash-reaper.service.ts]()

## Git Maintenance

`git-maintenance.service.ts` runs periodic housekeeping tasks against the underlying repositories so that long-lived bare repos do not accumulate pack-file bloat or stale objects. Typical duties include `git gc`, ref/prune hygiene, and pack maintenance. These operations are run under the same `repo-operation-lock` as sync and clone work, so they never interleave with an active fetch or a clone that is still writing objects. Source: [src/services/git-maintenance.service.ts]()

## Failure Modes

Several specific failure modes have been hardened over recent releases. Each represents a case where the tool previously made an incorrect assumption about git's output or about the layout of the working directory.

| Failure mode | Resolution | Source |
|---|---|---|
| Default branch contains `/` (e.g. `release/2024`) misdetected | v5.1.1: branch detection now handles `/` in default branch names (F3) | `src/services/` |
| `filesToCopyOnBranchCreate` patterns mishandled (absolute paths, escaping) | v5.1.1: patterns remain relative; absolute and shell-escaping patterns are rejected (F2) | `src/services/` |
| Orphan cleanup deleting a bare repo inside `worktreeDir` | v5.1.1: bare repo nested in `worktreeDir` is no longer treated as orphan (F1) | `src/services/trash-reaper.service.ts` |
| Worktree with stashed changes removed unsafely | v3.6.1: stashed worktrees are reported as unsafe to remove | `src/services/removal-audit.service.ts` |
| Long clones/fetches appearing to hang | v3.6.0: clone/fetch progress wired to the logger via `GitService` | `src/services/` |

**Clone failure recovery.** `clone-failure-recovery.service.ts` handles the case where a clone or fetch aborts partway through. Rather than leaving a half-populated bare repo on disk, the recovery path cleans up the partial state so the next run can retry from a known-good starting point. This pairs with the trash layer: a failed clone is not "removed" silently, it is recovered and recorded. Source: [src/services/clone-failure-recovery.service.ts]()

**Lock contention.** When the `repo-operation-lock` is held by another operation, contending requests wait rather than proceeding concurrently. This is intentional: it preserves the invariants the trash, audit, and maintenance subsystems depend on. The cost is occasional latency under burst load, but the alternative — concurrent writes against the same bare repo — produces corruption that is far more expensive to repair.

The overall posture is conservative: the tool prefers to leave an artifact on disk, in trash, or in an "unsafe to remove" state, and to require an explicit operator action to escalate to permanent deletion.

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: yordan-kanchelov/sync-worktrees

Summary: Found 7 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Configuration risk - Configuration risk requires verification.

## 1. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.host_targets | https://github.com/yordan-kanchelov/sync-worktrees

## 2. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/yordan-kanchelov/sync-worktrees

## 3. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/yordan-kanchelov/sync-worktrees

## 4. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/yordan-kanchelov/sync-worktrees

## 5. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/yordan-kanchelov/sync-worktrees

## 6. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/yordan-kanchelov/sync-worktrees

## 7. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/yordan-kanchelov/sync-worktrees

<!-- canonical_name: yordan-kanchelov/sync-worktrees; human_manual_source: deepwiki_human_wiki -->
