The sidebar is a tree of three levels: spaces, the projects in a space, and one row per branch or worktree of a project. Select a branch row to make it the place everything else works in: the tab strip, the editor, the terminals and the right panel all follow it.
pnpm test rank in this workspace?How it maps to disk
Tori keeps your work in one base folder, picked at first run. Every space is a folder inside it, and every project is a folder inside a space:
~/Projects the base folder work a space api a project web personal blogNothing is registered anywhere else. Create a folder inside a space from Finder and it appears as a project; create a folder in the base folder and it appears as a space. Folders whose names start with a dot are ignored.
A git repository sitting at the top of the base folder is not read as a
space. It shows in the banner below until you sort it into a space or attach
it to Home. A top-level folder under git that holds repositories of its own is
still a space, and so is one that only has a manifest such as package.json.
The base folder can be changed or forgotten in Settings > Advanced; nothing on disk moves when you do.
Projects outside a space
When the base folder holds projects Tori can’t place, a banner above the space strip reads 2 projects aren’t in a space. Click it to open it: Sort them into spaces, or attach one to Home to use it where it is., a Sort into spaces button, and each project with Attach to Home, which opens the Attach folder dialog on it.
It counts projects at the top of the base folder, and git repositories one
level inside a space’s folder that is not a project itself, such as
work/clients/api.
Sort into spaces opens Sort projects into spaces, the same grouping view as first run, over your current base folder. See The grouping view. Click Apply to run it. With nothing to sort it says Every project here is already in a space. Sort projects… in Settings > Advanced opens the same dialog.
A top-level folder you hide there stops showing as a space and stays on disk. Moving a project into a hidden folder from the grouping view shows it again.
If Tori stops partway through a move, the sidebar says A move didn’t finish: 1 of 3 folders left with Resume, which finishes the moves still left. Nothing else can move until it has.
The parts of the sidebar
- The heading: the active space’s name. The … beside it is the space’s menu. In Home it reads Home, and its menu offers a new chat, Topic or attached folder.
- The filter: the search button at the right of the heading, or
Cmd+Shift+E, opens a field that filters the tree by chat, Topic and project name.Escapecloses it and clears it. - The tree of the active space, in three groups: Chats and Topics when the space has any, then Projects with their branches.
- The space strip at the bottom: the Home tile, then a tile per
space, then the dock button at the far right, which shows or hides the
dock (
Cmd+Ctrl+J) and counts the dock’s tabs while it is hidden.
Right-click the empty part of the tree, or the heading, for the space menu.
Long groups
Each group in a space’s tree, Chats, Topics and Projects, shows six. The rest fold into a row at the bottom of the group, such as 3 more chats, 2 more Topics or 4 more projects, which carries a status bubble for what it hides. Click it to show them all, and Show less to fold them again; Tori remembers.
Folding never hides what you are using. A Topic or project you have open, the one you have selected, and one with an agent working, waiting on you or a pull request needing you stay in the list past the six, in their own place.
While the filter has text, every match shows and nothing folds.
Chats in a space
A space has chats of its own, which work exactly like
Home’s chats and list under its Chats
heading. Cmd+N, the + on the Chats heading and New chat in the
space menu all start one in the space on screen. Send to a new chat in a
space’s chat starts the new one in the same space.
A space’s chats live in their own folder under ~/.config/tori/chats/, named
after the space. When a space’s folder is renamed outside Tori, its chats
show in Home instead. Opening them still works, but resuming or forking one
started before the rename cannot find its history, since the agent finds a
conversation by the folder it ran in.
Spaces
A space groups the projects of one client, company or side of your life. Only one space is shown at a time; switch with its tile.
The space strip
Each space is a tile with its icon or initials, tinted in the space’s colour. The lit tile, the space you are in, grows into a pill that says its name; as the sidebar narrows the name shortens and then shows only the glyph.
Every tile you are not looking at carries one status bubble for everything in that space, so a space in the background still tells you when something in it needs you or is working.
Drag a tile left or right to reorder the spaces. The Home tile comes first, set apart by a thin line, and does not move.
Space tiles, in Settings > Sidebar, puts the tiles in a strip along the
Bottom of the sidebar (the default) or in a rail down its Left edge.
The rail fits any number of spaces, has its own New space button, and stays
visible when you hide the sidebar with Cmd+B; then the selected space’s tile
rolls up everything in it.
A space remembers where you were: switch back to it and the project and branch you left on are selected again.
Create a space
- Open the space menu (the … by the heading, or right-click a tile) and choose New space. With the tiles in a rail, the + under them does the same.
- Type a Name. It becomes a folder in your base folder, so keep it short.
- Under Appearance, pick a Colour and an Icon, or keep the defaults: the colour is worked out from the name, and the icon is the space’s initials. The dice button rerolls both.
- Click Create space.
The colour tints the space’s tile and the window behind the space while you are in it. Icons come from a searchable set; No icon - use initials goes back to letters.
Edit a space
Edit space in the space menu opens the same dialog. The name cannot change there, because the folder on disk carries it; rename the folder in Finder to rename the space. Colour and icon can change.
Delete a space
The confirmation shows what is at stake before you decide: how many agents are running in the space, its size on disk, how many projects have unpushed commits, and every folder inside it, with uncommitted and unpushed marked and those sorted first. Type the space’s name, in any case, to enable the button. Running agents and terminals in it are stopped first.
When the space has Topics, the confirmation also lists them:
- Topics deleted with it: the space’s own Topics, each with how many members it has. They are deleted before the folder. If Tori cannot delete one, it stops there and the folder stays.
- Home Topics that lose members: each Topic of no space with a member in this space, such as Loses web, api, and left empty when it has no other member. The lost members’ chips are struck through. Those members stay in the Topic and read Repository unavailable, with Locate to point them at a copy elsewhere. A Topic left empty is not deleted.
When the space has chats, the confirmation lists them under Chats deleted with it. Their sessions are stopped and deleted, and their folders go with the space.
Projects
A project is a folder inside a space. What Tori does with it depends on what is inside, and the project menu’s heading says which kind it is:
| Kind | What it is | Rows under it |
|---|---|---|
| Folder | A plain folder, no git | None: the project row itself is where its sessions run |
| Repo | An ordinary git repository, one branch checked out at a time | One row per local branch |
| Bare | A bare repository in .bare with each branch checked out as its own folder beside it |
One row per worktree |
The Bare layout is what lets several agents work on several branches of one repository at the same time without touching each other’s files. See Worktrees and branches.
Click a project row to open or close it. A Folder project has nothing to open, so clicking it selects it.
Add a project
- Open the space menu and choose New in “work” (with your space’s name).
- Pick what to create:
- Folder: a plain folder, no git. Type a Name.
- Clone: clones a git repository into a new folder. Type the
Repository URL; the Folder name fills in from the URL unless you
change it. Worktree layout is on by default: the clone goes into a
.barerepository with its default branch checked out as its own folder, and you add more branches later as their own folders. Clear the box for a plain clone. - Move here: moves a folder you already have into the space. See Move a project into a space.
- Press
Enteror confirm.
A clone runs in the dock, so you can watch it
and answer a password or passphrase prompt. The dock closes itself when the
clone finishes, or stays open with the exit code when it fails. A URL starting
with - is refused, so it can never be read as a git option.
To add a project that already exists on disk, use Move here, or Move folder here… in the space menu (Moves a folder from anywhere on this disk into work.), which opens the same dialog on that mode. Or leave it where it is and attach it to Home.
The project menu
Right-click a project row, or hover it and click its actions button:
| Item | On | What it does |
|---|---|---|
| New session | Folder | Opens Claude in a terminal tab in the folder |
| Initialize git | Folder | Turns the folder into a repository. Choose Normal repo or Bare + worktree, an Initial branch (blank for your git default) and an optional Remote URL, added as origin |
| Add branch | Repo | Checks out or creates a branch. See Worktrees and branches |
| Add worktree | Bare | Adds a branch as its own folder |
| Fan out | Repo, Bare | Several attempts at one task. See Fan out |
| Convert to worktree layout | Repo | Turns the clone into a Bare project in place, see below |
| Prune worktrees | Bare | Clears git’s records of worktree folders deleted outside Tori, and says how many it pruned |
| Set origin, Change origin | Repo, Bare | Points origin at a remote. Accepts https://, git@ and ssh:// URLs. Existing branches keep their names |
| Move to space… | Any | Moves the project’s folder into another space, see Move a project into a space. Shown once there is another space to move to |
| Project settings | Any | Opens the project’s settings dialog: icon, setup, run and teardown commands and shared files, allowed agents, verification commands, trust, origin and account, the repo’s workspace settings and the autopilot contract |
| Remove project, Remove folder | Any | Deletes it, see below. The row’s second line says so: Deletes the folder from disk |
Convert a clone to the worktree layout
Convert to worktree layout in a Repo project’s menu turns an ordinary
clone into a Bare project without cloning again. .git becomes .bare,
and the checkout moves into a folder named after the branch’s last segment:
repo/main for a clone on main, repo/x for one on feat/x. The project
keeps its place in the space.
The dialog lists everything that moves before anything runs:
| Row | What it is |
|---|---|
| Checkout | Where the checkout lands |
| Repo | .git becomes .bare |
| Topic | A Topic worktree in the repo, moving out to its own folder beside the checkout. Its Topic follows it |
| Moves | Another worktree inside the checkout, moving with it |
| Repaired | A worktree of this repo outside the project folder. It stays where it is and is pointed at .bare |
Nothing in git is lost: staged and unstaged changes, untracked and ignored
files, stashes, local branches, remotes and the branch’s reflog all stay, so
git status, git stash list and git branch read the same afterwards.
Your open tabs, breakpoints, expanded folders, pane layout, closed-tab history and search history follow the files into the new folder, and the new branch row is selected. Earlier agent sessions stay recorded at the old path, so they drop out of the branch’s history.
If a Topic reads this repo and the branch you convert is not the default branch, the dialog says so: the new layout has no default-branch folder until you add one with Add worktree.
Convert stays disabled, with the reason shown, when:
- a rebase, merge, cherry-pick, revert or bisect is in progress,
- the repository has submodules, a sparse checkout, per-worktree config or
core.worktreeset, HEADis detached, or the branch has no commits yet,- a Topic worktree in the repo has the same name as the branch’s folder,
- a terminal or agent tab is running in the project, or
- a file in the project has unsaved changes, including unsaved work kept from your last quit.
Move a project into a space
Two ways in, one dialog:
- Move here in a space’s New in dialog, for a folder anywhere on the same disk. Choose… opens the folder picker; Change… picks another.
- Move to space… in a project’s menu, in Home or in a space. The dialog, Move “api” to a space, has a Space list of the other spaces.
The dialog shows the same card as Attach folder: a plain folder, a git clone with its branch, remote and worktrees, or a bare repository with its worktrees. Name in the space is filled in from the folder’s name. Under it, always: Anything outside Tori that points at the old path stops working, and agent history stays under the old path. Click Move.
For an ordinary clone, Convert to worktree layout is ticked by default. It
turns the clone into a Bare project once it has moved, with two worktrees:
the branch you had checked out, and the repository’s default branch when that
is a different one. The default branch is the one origin points HEAD at,
else main or master if origin has it. Ticked, the dialog says Tori
trusts the folder, then makes it a .bare repo with the default branch and the
checked-out branch as worktrees. Clear the box to move the clone as it is. A
bare repository and a plain folder just move.
Ticking Convert to worktree layout is what lets Tori trust the folder, since converting runs git in it. Tori checks the clone against the same rules as Convert to worktree layout before anything moves. If one stops it, the box clears and greys out, the dialog says It can’t be converted, so it moves as it is. with the reason, and the trust is taken back. Click Move again to move it unconverted. Without the box, moving never trusts a folder that was not trusted already.
After the move, Tori may say:
- No default branch found, so only the current branch has a worktree.
- A folder named main is in the way, so main has no worktree yet.
- Moved, but the conversion didn’t run:, with the reason. The folder is in the space as an ordinary clone; convert it from its menu.
What moves with the folder: its worktrees, inside and outside it, which Tori relinks without running git; your open tabs and editor state; and Tori’s own records of it, such as its settings, trust, issues, origin and Topic membership. A project moved out of Home is no longer attached. What does not: earlier agent sessions stay recorded under the old path, and nothing is left at the old path to point at the new one.
Move stays disabled, with the reason shown, when:
- a terminal or agent tab is running in the folder: 1 terminal or agent tab is running in this folder. Close it first.
- a file in it has unsaved changes,
- the space already has a folder with that name, in any letter case: work already has a folder named api.
- the name is empty, holds a
/or starts with a dot, - the folder is on another disk: This folder is on a different disk. Attach it to Home instead.
- it holds the space, the base folder or your home folder: A folder can’t move into itself.
- it holds Tori’s own files: This folder holds Tori’s own files.
- it is a space: This is a space folder. Move its projects instead.
- it is a worktree of another repository: This is a worktree of another repository. Move that repository instead.
- it is halfway through a conversion: This project is halfway through a layout conversion. Finish or undo it first.
Change a project’s icon
Open Project settings from the project menu. Icon under General picks Automatic, Upload or Pick an icon. See General.
Remove a project
The confirmation shows the folder’s path, And everything in it, including .git for a project, tagged Deleted, then its size, running agents, and anything uncommitted or unpushed, and asks you to type the project’s name, in any case. Agents and terminals running in it are stopped first.
A bare project whose setup never finished, with a .bare and no worktree,
shows as an empty container. Its menu has Add worktree and Remove empty
container, which deletes the .bare and its folder.
Marks on a project row
At the right end of a project row:
- A status bubble, while the project is closed, rolling up every session under it.
- An orange pull request mark when pull requests in the project’s repo are waiting on your review and have no worktree here yet, with the count from 2 up. Click it for the list, each with its number, title and author; pick one to make its worktree and select it. A project can make these by itself: see Automations.
- A broken link mark when a worktree is missing a shared file. Click it to open the project’s settings on Worktrees.
- A plug when the repository’s host has no signed-in account: click it to add one in Settings > Hosts.
- A person when more than one of your host accounts could serve this repository: click it to pick which one it uses.
- A shield when your account cannot see the repository because its organisation has not approved Tori. Click it for Settings > Hosts.
See Hosts and accounts for those three.
Branch rows
Each row under a project is one branch of a Repo or one worktree of a Bare project. Up to six show; the rest fold into a N more row that opens them. A stack or a group counts as one of the six. The branch you have selected always stays visible.
The rows are in your own order: drag one to move it. You can also gather branches into named groups and sort them into lanes by pull request state, see Arranging the sidebar.
What a row shows
From left to right:
-
The glyph: a branch for a repo’s branch, a folder with a branch off it for a worktree. The branch you are standing on (the checkout) is drawn filled and brighter. While a session in it is working, the glyph traces itself.
-
The name.
-
A play button while the pointer is on the row, when the project has a run command. It turns into a stop square while the command runs. Off the row it stays out of sight, and a running server shows by its port.
-
A port, such as
:3000, for each dev server listening from the worktree. It is amber while the browser extension is connected and grey when it is not. -
An issue chip, such as #214, when the branch was started from an issue. Click it to open the issue.
-
Sync marks, small glyphs with counts. Hover for the full story:
Mark Means Red conflict mark The base branch has moved on and some files would conflict when you catch up Amber files mark with a count A session in another worktree is changing these files too. See Conflict radar Up arrow with a count Commits to push. Amber when you are also behind (diverged) Up arrow, muted Commits to publish: the branch has never been pushed Up arrow, no count The branch has no upstream yet, or its remote branch was deleted Down arrow with a count Commits to pull Dot Uncommitted changes The tooltip also says when the last commit was made, and lists conflicting files. While a session in the branch is working or waiting on you, the marks step aside for its status, except the amber files mark, which stays. A branch with an open pull request has no red conflict mark: its second line shows the conflict instead (see the second line).
-
A Topic tag when the worktree belongs to a Topic and Show Topic worktrees in Spaces is on. Click it to open the Topic.
-
A status bubble for the sessions in it.
The second line
A branch with a pull request, or with changes against its base, grows a second line. Branch line, in Settings > Sidebar or the sidebar’s View options menu, sets how much it shows: Off, PR only or Full (the default), and in Full which facts, see The branch line. In Full:
- The pull request’s number and state (draft, open, merged or closed), its
place in a stack as a stack glyph and
2/3when it is one layer of a stack, an eye when a chat is watching it, and its checks as passed out of the checks that ran. Skipped checks never ran, so they count on neither side; a grey count with a slashed circle beside the score says how many there were. - The size of the change against the base:
+120/-14and the number of files. - When it was opened (or merged or closed), and how many comments it has.
The pull request’s number is coloured for where its review stands. The colour names are Tori Dark’s:
| Number | Means |
|---|---|
| Blue | Your pull request is open, with no review yet |
| White | Reviewed with comments, nothing blocking |
| Red | Changes requested |
| Orange | You asked a reviewer who requested changes to look again, or someone else’s pull request asks for your review |
| Green | Approved |
| Purple | Merged |
| Grey | A draft, closed, someone else’s pull request you have reviewed, or one that never asked you |
These are the states PR lanes sort by. When the base has moved on and some files would conflict, a red conflict glyph with the number of files follows the number.
On the repository’s default branch, such as main or master, a pull request
is a release to another long-lived branch, so the line reads -> stage #8020
under an arrowed pull request glyph. It stays grey once approved, and is
coloured like any other number until then. Once merged or closed it shows, grey, for a
day, then the line goes away, and the row never takes the teal wash a finished
branch gets.
Hover the line for the title, the author, its place in a stack (Layer 2 of 3 in a stack, targets main), the review and checks in words, the size, and the files that would conflict with the base. A branch whose pull request merged with nothing new since rests on a faint teal wash; one whose pull request was closed unmerged is dimmed.
Stacked pull requests
GitHub can stack pull requests: each one targets the branch of the one below
it, and the bottom one targets the trunk, usually main. You make and change
stacks on GitHub or with the gh stack command. Tori only reads them, and only
on github.com, not on GitHub Enterprise Server or GitLab.
When two or more layers of one stack are branches in the project, they gather under a Stack row:
- The badge says how many pull requests the stack has and where it lands, as
3 PRs -> main. The count is every layer on GitHub, including merged ones and ones you do not have locally, so a gap in the2/3marks below is a layer that is not here. - The layers are listed top first, the way GitHub’s stack map reads, and the trunk sits faintly at the foot. The trunk row is only a label, not a branch you can select.
- The Stack row takes the place its top layer had, so nothing else in the list moves.
- It starts open. Click it to collapse it; Tori remembers. Collapsed, it carries one status bubble for the sessions in all its layers. Following a link or a notification to a layer opens it again.
- A layer whose pull request merged and that you still have keeps its place in the group, styled like any other merged branch.
A single local layer stays an ordinary row; its 2/3 mark says it has
neighbours. A fan out attempt stays in its fan out group even when its branch
is also a layer.
Select a branch
Click a row to select it. For a Repo, selecting a branch that is not checked out asks Switch api to “feature”? first, because a repository has one working tree and checking out changes every file in it, under every terminal open there. A Bare project’s worktrees are separate folders, so selecting one never checks anything out.
The branch menu
Right-click a row:
| Item | On | What it does |
|---|---|---|
| New session | Any | Opens Claude in a terminal tab here |
| Graph | Any | Opens the commit graph for this branch |
| Reset to upstream | A branch whose upstream was force-pushed over it | Resets the branch to the upstream, instead of pushing or pulling |
| Watch with this session | A branch with an open pull request | Lets a chat in this folder watch the pull request |
| Remove worktree | A worktree | See Remove a worktree or branch |
| Checkout | A repo’s branch | Checks it out |
| Remove branch | A repo’s branch that is not checked out | Deletes it, see the same section |
A worktree that belongs to a fan out group has a shorter menu: New session and Promote this attempt.
Drag a project or branch row onto a terminal or the composer to insert its path.
Status bubbles
Sessions report one of three states, and the sidebar rolls them up:
- Needs you (rose): waiting on a permission prompt, a question, a spending limit or a failing check.
- Working (violet): a turn is running.
- Done (teal): finished and idle.
A branch row shows its sessions, a closed project shows everything under it, and a space tile shows everything in the space. Needs you always wins: one waiting session makes the whole rollup say so, with the count.
An orange pull request in the bubble, Pull request needs attention, means it is your move on a branch’s pull request. A branch row leaves it out of its own bubble, since the colour of its pull request number already says why; a closed project and a space tile still show it:
- Your own pull request: a check failed, or a reviewer requested changes.
- Someone else’s: it is asking for your review. It clears once you review it, and comes back when the author asks you again. Their failing checks never light it.
Topics
A Topic is a branch shared across several repositories. One that holds projects from more than one space is listed in Home. See Topics.
A Topic can also belong to a space, holding only that space’s projects. New Topic in the space menu, Groups worktrees from work’s projects, makes one. The space’s Topics are listed at the top of its tree, under a Topics heading with a + for another; the projects follow under Projects. See Topics in a space.
Find a project
Press Cmd+Shift+E or click the search button to filter the tree. To find a
session rather than a project, use Session history in the tab strip (see
Starting a chat),
or the omnibox (see
Search, the omnibox and shortcuts).