Skip to content

Projects, worktrees, and directories

Give each branch or pull request its own checkout and terminal session. You and your agents can work on separate tasks without switching branches in the same folder. Projects and worktrees are optional.

Ghosthub delegates repository and worktree identity to kwt. Packaged builds use their revision-pinned bundled kwt locally and a matching managed helper on remote macOS or Linux hosts.

Register a project

Start with an existing Git checkout on the target host.

  1. Expand the local Mac or a remote macOS or Linux host.
  2. Select the + beside Projects.
  3. Enter the checkout's absolute path on that host.
  4. Confirm the registration.

Ghosthub registers that one path through kwt and refreshes inventory. It does not scan the machine or edit kwt configuration itself.

Repositories arranged as a .bare/ directory with sibling worktrees are also supported. Enter the containing directory or any worktree's path. New worktrees stay beside the existing ones; the .bare/ directory is not a worktree row.

Ghosthub automatically maintains the managed kwt helper on configured remote macOS and Linux hosts. Before a project or worktree operation, Ghosthub repairs the helper if needed; if repair fails, that operation shows the error without affecting ordinary terminal sessions. Project registration is not yet available for native Windows hosts.

If the SSH destination changes while the Add Project sheet is open, close the sheet and start again so the confirmation applies to the current host.

Find a moved project

When a project folder moves or is renamed, Ghosthub asks kwt to look for its new location among repositories it already knows about. One unambiguous match updates the project automatically. Ghosthub attempts this once while that registration remains unavailable; normal refreshes still notice when the original folder returns.

An unresolved project shows a folder question-mark button beside its name. Other projects and terminal sessions remain usable. Select that button, or Control-click the project and choose Locate Folder…. On this Mac, use Choose Folder… or enter the new absolute path. For a remote host, enter the path on that host. Select the main checkout of the same repository, then select Use Folder.

Locate Folder sheet for a moved project

Recovery preserves the registration until it can verify the new location. Automatic matching requires a repository identity; multiple matching clones need an explicit choice. If the project has no stable repository identity, remove its old registration and add its new location. Remove Project… is also available when you no longer want the project listed.

Remove a project

Hover over a project row and select its × control, or Control-click the row and choose Remove Project…. Then confirm the project and host. Ghosthub asks kwt to unregister that project and refreshes inventory. You can remove the registration even if its checkout folder has already been deleted. This does not delete the repository, any worktree directory, or any tmux session. If an imported pull-request worktree still has a live session on its protected tmux server, kill that session before removing the project. Ordinary sessions that remain live are still available under the host's Tmux Sessions group.

Ghosthub showing the Remove Project action and its non-destructive confirmation

If the project or host connection changes while confirmation is open, Ghosthub stops and asks you to start the removal again. Project removal is available on the local Mac and configured remote macOS or Linux hosts, but not native Windows hosts.

Register a plain directory

A hub, notes tree, or other directory that is not a Git checkout can still use the same kwt layouts and Ghosthub terminal flow. Register it on the target host:

kwt workspace add /absolute/path/to/directory

Refresh Ghosthub. The directory appears as one flat row in Projects, after the repository rows. It has no expandable worktree children because one registered directory owns one workspace session.

Select the row to let kwt create or repair its configured layout and attach the ordinary tmux client. Removing the registration with kwt workspace remove does not end a live session; after refresh, that session remains available under Tmux Sessions.

Open a project checkout

Select the project's primary checkout or any linked worktree in the sidebar. Kwt supplies the exact canonical tmux session name. Ghosthub creates or repairs that session when necessary and then attaches an ordinary tmux client. The native window tab and titlebar show the project and worktree names instead of that internal session name. New worktree sessions use kwt's short, hash-suffixed naming format. To list them from a shell, use the kwt-server command. To put the whole project in one new window, right-click the project and choose Open All Worktrees as Tabs. Ghosthub opens the visible worktrees in sidebar order, creating or repairing each Kwt session as needed. If one scene cannot be created, the group stops there instead of opening the remaining worktrees as unrelated windows.

The worktree row shows a compact window count. While Ghosthub is connected, the count refreshes with the existing background activity check: within about five seconds for a working session and twenty seconds for a quiet session. This also covers protected sockets. Detached ordinary sessions use the count from current discovery. A running or agent glyph remains the fallback when no trustworthy count is available, and cached sessions do not remain marked live while the host is unreachable.

Ghosthub showing a compact tmux window count on a worktree row

By default, a live kwt-managed session appears only on its worktree row instead of being duplicated under Tmux Sessions. Open Settings → Worktrees and turn off Hide kwt-managed sessions from Tmux Sessions if you want both entries visible.

Flag worktrees

Open the … menu beside a worktree and choose Flag Worktree. Its name turns amber and its leading icon becomes a filled flag. Use Unflag Worktree to restore the original icon and text color. Control-clicking the row offers the same actions.

Flagged primary and linked worktrees beside an unflagged checkout

Flags are manual reminders saved on this Mac. They appear across open windows and survive relaunches, even if a terminal session stops or a host goes offline. You can flag several worktrees, including the primary checkout. Flagging does not open a session, change row order, or follow terminal activity.

Flagging becomes available once inventory supplies a verified worktree identity. A newly created checkout at an old path starts unflagged.

Inspect changed files

Select the disclosure chevron beside a worktree. The panel expands beneath that worktree without selecting it or attaching its tmux session. More than one worktree can remain expanded.

Ghosthub showing staged, modified, and untracked files beneath a worktree

Each file shows separate staged and working-tree states when both apply, and a renamed file includes its original path. An empty panel says No changed files. Large results show the first 200 files; select Show more to reveal the next page. Expanded panels refresh about five seconds after each successful read. Temporary failures retry less frequently when they continue, while a permanent failure waits for Refresh. Use Refresh for an immediate read or the disclosure chevron to hide the panel. If a later read fails, Ghosthub keeps the last successful rows visible and marks them stale.

If Kwt reports that the worktree registration changed, automatic retries stop. Select the panel's Refresh button to refresh workspace inventory. The panel resumes inspection when inventory supplies the current worktree identity.

The panel shows file status only. Use your editor or Git tools to read diffs, stage changes, or commit them.

Create a worktree from a branch

  1. Select the project.
  2. Press Shift+Cmd+N or choose the new-worktree action.
  3. Select Branch.
  4. Search local and remote branches that are not already checked out, or type a new branch name.
  5. Confirm the worktree.

Selecting a remote source creates a local tracking branch when needed. The picker distinguishes same-named sources. Input that does not match an existing branch creates a new branch.

New worktree sheet with branch choices

Import a GitHub pull request

Pull-request import requires the GitHub CLI and Git 2.42.0 or newer on the macOS or Linux host that contains the project. For native Windows hosts, it requires Git for Windows 2.53.0.windows.3 or newer. Install these tools on the project host, even when Ghosthub runs on another Mac.

On that host:

gh auth login

For an HTTPS Git remote, Git authentication must also work there. GitHub CLI can configure itself as the credential helper:

gh auth setup-git

Then select the project, press Shift+Cmd+N, choose Pull Request, and search for an open pull request. Ghosthub asks kwt to import it and selects the resulting worktree session.

Remove a worktree

Open the … menu beside a non-primary worktree, or Control-click its row. Choose Remove Worktree…. After you confirm the exact worktree and host, Ghosthub:

  1. ends that worktree's verified live tmux session when necessary; and
  2. asks kwt to remove the checkout.

The Git branch is kept. If the checkout is already absent, Ghosthub skips the redundant filesystem removal but still reconciles the exact live session covered by the confirmation. If the worktree or session changes while the confirmation is open, Ghosthub stops and presents the current removal details for fresh confirmation instead of continuing automatically.

If a worktree has uncommitted changes, review the warning before confirming forced removal. This discards those changes. If there are too many changed files to list, Ghosthub says the inspection is incomplete and still requires that explicit confirmation.

After removal, the owning project remains selected. Ghosthub does not select another worktree or open its tmux session on your behalf.

Rearrange worktrees

Drag worktrees within a project to set their display order. The insertion line shows the destination. This changes Ghosthub's navigation only; it does not rename or reorder anything in Git, kwt, or tmux.

Rust source builds

The unreleased Rust app can also register projects on connected macOS and Linux SSH hosts. Select + beside that host's Projects, enter the repository's absolute path on the remote machine, and select Add Project. Ghosthub installs or repairs its bundled remote helper automatically. If this fails, the Projects section shows the error and a Retry action. Ordinary terminal sessions remain available. Select Retry after resolving the error to reconnect and refresh projects.

Add a project on the Studio SSH host in the native Rust application

Remote project diagnostic and Retry action beside an active terminal

Select × beside a project and confirm Remove to unregister it. The repository, worktrees, and running sessions remain intact. Cancel leaves the registration unchanged.

Confirm removing the remote project registration while its terminal stays open

Select an ordinary remote worktree to open its terminal, even when its session is stopped. Ghosthub asks KWT to open the exact registered worktree and checks the resulting client before showing it. Registered directories also open when their sessions are stopped. The Rust app supports direct sessions on the default tmux server and KWT's standard kwt server. Switching rows keeps already-opened tmux clients available for reuse. A same-name session on the other server remains separate.

A remote worktree attached through the standard KWT server

To import a pull request, select + beside the remote project, then Pull Request. Search the open PRs and choose one, or enter its number or URL. Select Import to create its checkout and open the terminal. GitHub access uses gh auth login or KWT_GITHUB_TOKEN on the remote host. If listing fails, the error stays in this dialog; existing projects remain available.

Import a pull request into a remote Rust project

Already imported pull-request worktrees also open from the remote project tree. KWT opens its protected terminal without running the checkout's configured layout. Switching away and back reuses the terminal, even if the checkout is removed or its project is unregistered. The open terminal remains available in the session list. Detaching leaves the session running; opening a new client still requires the registered project and checkout.

An imported pull-request worktree opened on the Studio SSH host

To stop an open protected PR terminal, choose Kill from its row's ⋯ menu, then confirm Kill Session. You can also kill a retained terminal after switching away, including from its fallback session row if the project was unregistered. Ghosthub closes matching terminals in every window and leaves the checkout intact. Cancel leaves the session running. If the session was replaced or the SSH connection changed, choose Kill again and review the new confirmation.

Confirm killing a protected PR session over SSH

To create a remote worktree, select + beside its project. Enter a new branch name or search and select an existing branch. If several remotes have the same branch name, choose the source you want. Select Create to create the checkout and open its terminal. Cancel closes the dialog without creating a worktree.

Create a remote worktree from a branch in the native Rust application

Ghosthub checks the project registration and SSH connection before creation. If the result cannot be confirmed, refresh the host before trying again; the worktree may already exist. Newer navigation takes precedence over automatically opening a completed worktree.

To register a directory, run kwt workspace add /absolute/path on the remote host. Refresh that host in Ghosthub and select the row under Directory Workspaces. Ghosthub opens the registered directory and reuses its terminal when you switch away and return.

A registered remote directory opened from its idle row

Open an ordinary running worktree or directory row's ⋯ menu, select Kill, and confirm Kill Session to stop its session. Its files and registration remain intact.

Confirm killing a remote worktree session in the native Rust application

Idle worktrees also open with tmux's destroy-unattached option enabled. KWT keeps the new session alive during setup, then restores the session's captured policy when its first client attaches.

To remove a remote worktree, open its ⋯ menu and choose Remove Worktree. Review the worktree and host, then select Remove Worktree to end its confirmed session and delete the checkout. The Git branch is kept. Cancel leaves both the checkout and session intact.

Confirm removal of a remote worktree in the native Rust application

Imported PR worktrees offer the same action, whether or not their terminal is open. Ghosthub checks their protected socket and captures the session identity for confirmation.

Confirm removing an imported PR worktree over SSH

For a worktree with uncommitted changes, Ghosthub shows a warning and an explicit Force Remove Worktree button. This permanently discards its staged, unstaged, and untracked changes. Cancel to keep the work, or commit or stash it before ordinary removal. The Git branch is kept after either action.

Confirm force removal of a dirty remote worktree

Local Linux and WSL worktrees use the same confirmation. Open the worktree's ⋯ menu and choose Remove Worktree. A dirty checkout requires Force Remove Worktree; Cancel leaves its checkout and session intact.

Confirm force removal of a dirty local worktree

If the pre-removal check finds new changes after a clean confirmation, Ghosthub keeps the checkout and session and offers Review Again. If its session, checkout, project registration, local host runtime, or SSH connection changes, refresh the host and review the removal again. KWT also refuses removal while the workspace session name remains on either shared tmux server. Failed change inspection blocks removal.

Registering directories through the remote Rust UI is still in development. Arbitrary named SSH sockets are not supported.