skill
cc-outline
Split-pane viewer for Claude Code in Windows Terminal and tmux: the session as rendered Markdown with subagents, live git diffs, plan-mode plans and a session browser
Set up
Skills are installed by placing their folder where your agent loads skills.
The download comes from github.com/hopp1395/cc-outline itself, not from our server, so what you get is exactly what its author published.
Install instructions come from the README
README
synced Oct 21, 2026cc-outline: a viewer for Claude Code in a split pane
cc-outline (command cco) is a terminal viewer for Claude Code that runs in a split pane next to it, in Windows Terminal or tmux. It has seven views:
- Chat renders the answers of the current session as proper Markdown: headings, lists, tables and code blocks with syntax highlighting. It follows the session live.
- Changes lists the files changed in the git repository, and in the repositories in the folders below, and shows their diffs with syntax highlighting.
- Plan shows the plans Claude presented in plan mode, with their status and what changed between versions.
- Sessions gives an overview of your sessions across all projects: when, where, how long, which plans and which changed files. From there a session continues in a new terminal tab, in another Claude account, is exported (Markdown, JSON and a backup to import elsewhere), or goes to the trash. With several accounts it lists their sessions too, each marked in its account's colour.
- Monitor charts how fast Claude answered over the day: output tokens per second, the wait for the first block and the number of responses, compared with the usual values at that time, plus errors such as usage limits.
- Accounts (
0, or a click on the "cco" at the left of the top bar) lists the Claude accounts on this machine (config folders~/.claude*) with their details: organization, plan, colour, whether the cco plugin runs there, the Claude Codes running with them and their sessions of this project.Enteron an account offers to continue the current session there, to start a new session there, or to open its config folder. It also sets up a new account (config folder, start script, cco plugin) and moves one you no longer need to a trash. See Sessions and accounts. - Settings lists all options in one place: whether the viewer opens by itself when Claude Code starts, and the display options of the other views.
Besides the pane, the Remote Control Viewer (cco rc-viewer or /cco:rc-viewer) is a window of its own that watches every session at once: of every project and account on this machine, and the Remote Control sessions on other machines. It shows which ones wait for you, lets you answer them and sends them prompts. See Every session in one window.
Why
Working with Claude Code in the terminal has seven blind spots. cc-outline fills them without leaving the terminal and without interrupting Claude.
1. Answers are hard to read and quickly gone
The problem. Claude answers in Markdown, but the terminal shows much of it as plain text. Tables lose their shape, and headings and emphasis blend into the text. A plan with several steps looks like a wall of text. Long answers scroll past while Claude keeps working. To read an earlier answer again you scroll back through tool calls and output, and the prompt that answer belongs to is somewhere above it.
How cc-outline solves it. The Chat view renders each answer as Markdown, with real tables, headings, lists and highlighted code. The session is organised by prompt: every prompt is one entry in a list. Select one and you see exactly its answer, with the prompt pinned above it and tool noise hidden. The view follows the running session live and stays at the bottom like Claude Code. You can scroll up at any time without losing your place, and each turn remembers where you left it. Important answers can be marked with Space and found again after a restart.
2. You don't see what Claude changed
The problem. Claude edits files as it goes. The terminal only shows short summaries such as "Updated with 10 additions and 1 removal". To review the actual change you open an editor or run git diff in another window, and then find your way back to the conversation. Claude often touches several files, so reviewing them costs time and focus. Changes also get accepted without a real look.
How cc-outline solves it. The Changes view lists every changed file of the repository: modified, added, deleted and untracked. It shows each diff with line numbers and syntax highlighting, right next to the conversation that caused it. It refreshes every two seconds while Claude works, so you watch the changes appear. You can jump between hunks or open the whole file as it is now. The branch shows at a glance how many commits are waiting to be pushed or pulled.
3. Plans get lost once work starts
The problem. In plan mode Claude writes a plan and asks for approval. Once you approve it, Claude starts working and the plan scrolls away under tool calls and output. To check what was agreed, or whether a step was skipped, you have to scroll back and find it. If you reject a plan with feedback, Claude writes a new version, and nothing shows what changed compared with the one you rejected. Which versions were approved or rejected, and why, is hard to reconstruct later.
How cc-outline solves it. The Plan view lists every plan of the session with its time, title and status: approved, rejected or waiting for your decision. The selected plan stays readable next to the session while Claude carries it out, with the prompt it answers pinned above it, and for a rejected plan your feedback. Enter shows what changed compared with the previous version as a diff, so you only review the changes. Plans appear as soon as Claude writes them, before they are presented and before you decide, and can be marked like answers and files.
4. Past sessions are hard to find, resume and clean up
The problem. Every session is kept, in every project, but only as JSONL files with random names. /resume offers them by title and time. What a session was about, which plans it had and which files it changed only shows once you resume it, and that takes you out of the session you are in. Nothing deletes old or failed sessions, so the list only grows.
How cc-outline solves it. The Sessions view lists the sessions of this project or, with its filter (a), of all projects with their project, name and time. For the selected session it shows when and where it ran and for how long, on which branch, its plans with their status, the subagents it started, the files it changed and its prompts, all without resuming it. Enter continues it in a new terminal tab in the right folder, and c copies the claude --resume command instead. Sessions you no longer need go to a trash with d, where they can be restored until you delete them for good.
5. Several Claude accounts don't know of each other
The problem. Many people run Claude Code with more than one account: a work and a private one, or a team plan next to a personal one, each in its own config folder (CLAUDE_CONFIG_DIR). Claude Code shows nothing of the others. Which account a terminal runs is easy to mix up, and /resume lists only that account's sessions. Setting up another account means writing a start script by hand, and a name like cp or sc quietly runs a PowerShell command instead. Nothing removes an account you no longer use.
How cc-outline solves it. Every account gets a colour and, if you like, an avatar ((^_^), 🦊, ☕💻 or your own): the "cco" at the left of the top bar shows them, and the terminal title ends with the avatar. The Accounts view (0) lists all accounts on the machine with their organization, plan, plugin, running Claude Codes and sessions. The Sessions view's filter (a) lists the sessions of the accounts you check in one list, each with a bar in its account's colour. Any session continues in another account in a new window, the viewer moving along. How to add an account sets one up with Enter and refuses names a shell would run something else for, and d moves an account to a trash, after asking twice, from where it can be restored.
6. A usage limit stops the work
The problem. With more than one account, say a team plan and a personal Max plan, one of them sooner or later reaches its usage limit in the middle of a session. Claude Code stops, and it only goes on after the reset, hours later. The other account still has capacity but does not know the session: it lives in the first account's config folder, and /resume lists only the account's own sessions. In the other account the whole context is missing: the plan, what was discussed and decided, which files are already changed. You start over or explain everything to Claude again.
How cc-outline solves it. Enter on the session in the Sessions view, then Continue it in …; /cco:account <email> does the same from Claude Code, and so does the Accounts view. The session stays as it is, running or not, and so does its viewer. Where the other account lacks the cco plugin, it is installed first. cco then copies the conversation into the other account, with its predecessors from before a /compact, its subagents, file history, pasted images and cco's own marks and positions; the original stays as it is. The copy starts in a new window under the other account, which opens a viewer of its own there (as the auto open setting says): its colour and email show the new account. Claude has the whole history and goes on where the limit stopped it. In the Sessions view the original is marked ⇢ and the copy ⇠, so you can tell where the work went. Once the first account is free again, the session comes back the same way.
7. Sessions on several machines are hard to keep an eye on
The problem. With Claude working in several sessions at once, in a few terminals here and on another machine, you keep checking each one: is it done, does it wait for an answer, did it stop at a permission? Every Claude Code shows only its own session. The ones on another machine are out of sight, unless you open each in the Claude app or on claude.ai, one at a time, with no overview of what waits for you. A question that waits unseen holds up the work for as long as it waits.
How cc-outline solves it. The Remote Control Viewer (cco rc-viewer) is one window for all of them: every session of this machine, of every project and account, and the Remote Control sessions of your other machines, grouped by what they need (Waiting, Working, Idle, Ended). A session that waits for you blinks, and so does one that has just finished; n jumps to the next of them. Beside the list it shows the selected session's turns and chat, live. Its question or permission shows in the prompt line's place: for a session on another machine, or one of this machine connected with Remote Control (⇄), you answer it right there, otherwise Enter brings its terminal to the front. The prompt line below sends any of them a prompt, and Enter offers what fits: interrupt it, continue an ended one, make a session steerable with /remote-control.
In daily work
- Review while Claude works. Keep the approved plan in the Plan view and check the resulting diff in the Changes view, both next to the running session.
- No context switch. No editor, no second terminal, no
git diff. One key (1–6) switches views,alt+←returns to Claude Code. - Better answers stay useful. Tables, code and step-by-step plans are readable, and you can copy an answer's Markdown with
cfor a ticket, a PR description or documentation. - Long sessions stay navigable. Prompts are listed with their time, prompts sent while Claude was busy are marked, and marked turns survive restarts,
--continueand/resume. - Pick up older work. Find yesterday's session in the Sessions view by its plans and changed files, and continue it in a terminal window of its own.
- Switch accounts without losing the thread. When one account reaches its usage limit, continue the session in another one from the Sessions or the Accounts view; the copy keeps the conversation, and the viewer follows it there.
- Everything stays where you left it. Every list keeps its selected entry and each entry's scroll position, also across restarts.
- Nothing to manage. The plugin opens the pane with
/cco:chat,/cco:git,/cco:plan,/cco:session,/cco:settingsor/cco:monitor, follows the active session, closes it with the session and opens it again on every start (with auto open set toremember: only if it was open). - Set up once, in one place. The Settings view (
6or/cco:settings) lists every option with its default: whether the viewer opens by itself, whether quitting asks first, whether long entries scroll and positions are remembered, and the display options of the other views. A change applies at once in all views and all projects.
Sessions and accounts
cc-outline manages your sessions and your Claude accounts from the pane next to Claude Code:
- Every session, every account. The Sessions view (
4) lists the sessions of this project, of the others or of all, of the accounts you check, with or without the background sessions (claude -p, the SDK, the daemon; marked◌):aopens the filter. A bar in the account's colour marks each row once other accounts are shown, and the header names the account, its organization and folder. See the Sessions view. - Continue anywhere.
Enteron a session continues it here (/resumetyped into Claude Code), in a new window (a viewer without a Claude Code can move along), or in another account: a copy of the conversation goes on there, with the cco plugin installed first where it lacks it, and the original keeps running if it runs./cco:account workdoes the same from Claude Code. - Accounts at a glance. The Accounts view (
0, or a click on the "cco" at the left of the top bar) lists the accounts found (~/.claude*), the active one first, with organization, plan, colour, the cco plugin, the Claude Codes running with each and its sessions of this project.Enterstarts a new session in an account or opens its folder. See the Accounts view. - Add an account. How to add an account explains the setup and does it with
Enter: config folder, start scripts next toclaude(cw.cmdandcw), cco plugin, and a window to sign in with/login. Names that a shell would run something else for are refused (PowerShell aliases such ascporsc, built-ins of cmd and Bash, programs on the PATH). - Clean up. Sessions go to a trash with
d(Tshows it,urestores). Accounts too:don an account, or the menu's Danger zone, moves its folder and start scripts to the accounts trash after asking twice (the second time with the folder's name typed in). The default~/.claude, the active account and accounts in use are refused.
Every session in one window
The Remote Control Viewer (cco rc-viewer, /cco:rc-viewer, or the row ⊞ Remote Control Viewer above the Sessions list) is a window of its own, one per machine, for keeping an eye on everything Claude does:
- One list for every session. The sessions of every project and account on this machine and, with Sessions: remote API, the Remote Control sessions of your other machines (
◈), grouped by what they need: Waiting, Working, Idle, Ended. Each row tells how long it has been so. - See what waits for you. A waiting session's
⚠blinks, here and in the Sessions view; one that has just finished blinks its●until you have looked at it.ngoes to the next of them, the one waiting longest first. - Answer from here. What it waits for shows in the prompt line's place, the question with its options or the tool with its command. A session on another machine, or one of this machine connected with Remote Control (
⇄, Sessions: steer remote on), is answered right there; any other is answered in its terminal, whichEnterbrings to the front. - Send prompts.
Spaceor a click gives the prompt line the keys; it writes to the selected session, into its Claude Code or through claude.ai, and keeps a draft per session. - Act on it.
Enteroffers what fits the session: bring its terminal to the front, interrupt Claude, continue an ended one in a new window, make an idle one steerable (/remote-controltyped in), open a session viewer, copy the resume command.
See Remote Control Viewer for the details.
Small screens
On a small screen, or in a narrow pane next to Claude Code, list and preview side by side leave both too narrow. The setting compact (Settings › General) switches the layout:
- stacked. The list is above the preview, both as wide as the pane. The list takes compact split of the height (10% to 50%, default 20%) and has compact columns columns (1 to 4, default 2), filled one after the other like a newspaper;
<and>change the columns. - single. One column: the list, and
Enter(a detail) or|shows the preview over the whole pane,Escor|goes back. - Both leave out the help line (
istill lists the keys), the status and the version, shorten the tabs to their number and keep the preview's header to one line.
Installation
Requirements:
- Node.js 22 or later
- Claude Code
- Windows Terminal or tmux, to open the viewer in a split pane
1. Install the CLI:
npm install -g cc-outline
cco --version
2. Install the Claude Code plugin. It provides the hooks and the /cco:open, /cco:chat, /cco:git, /cco:plan, /cco:session, /cco:settings, /cco:monitor, /cco:releases, /cco:update, /cco:restart, /cco:account and /cco:doctor commands. The npm package is its own plugin marketplace:
claude plugin marketplace add "$(npm root -g)/cc-outline"
claude plugin install cco@cc-outline
3. Restart Claude Code, then run /cco:chat, /cco:git, /cco:plan, /cco:session, /cco:settings or /cco:monitor. The viewer then opens on every start; set auto open to remember or never in the Settings view to change that.
Updating. When a new version is out, the top bar shows it (v0.7.0 → 0.8.0, in narrow panes ↑ 0.8.0) and the Releases entries in the Settings view (/cco:releases) show its release notes; Enter on update to v0.8.0 (or /cco:update, which checks right away and asks) runs the three commands below, then the viewer opens again with the new version (see Settings view). By hand: update the CLI and the plugin, then restart Claude Code. New commands such as /cco:settings only appear after the plugin update:
npm install -g cc-outline
claude plugin marketplace update cc-outline
claude plugin update cco@cc-outline
When something does not work (the viewer does not open on start, /cco:… takes seconds, a pane opens as a window), run cco doctor, see Usage.
To uninstall, run claude plugin uninstall cco@cc-outline, claude plugin marketplace remove cc-outline and npm rm -g cc-outline, then delete ~/.claude/cco/.
From source
npm install
npm run build
npm link # makes `cco` available globally
claude plugin marketplace add <path-to-this-repo>
claude plugin install cco@cc-outline
To load the plugin for a single session without installing it, run claude --plugin-dir ./plugin instead.
Usage
-
/cco:chat,/cco:git,/cco:plan,/cco:session,/cco:settingsor/cco:monitorin Claude Code opens the viewer in a split pane (Windows Terminal or tmux), starting in that view. If a viewer is already running for the project, the command switches it to that view instead of opening a second pane./cco:openopens it in the view the session was shown in last (with the setting view per session, else the chat) and leaves a running viewer as it is./cco:releasesopens the Settings view on the release notes and the update, if one is out./cco:updatechecks for a new version right away, also with the setting update off, and asks in the Settings view whether to install it./cco:restartcloses the viewer and opens it again in the same place and view with the version installed now; if none runs, it opens one./cco:accountsopens the Accounts view./cco:accountcontinues the session in another Claude account (see Continue it in another account… in the Sessions view);/cco:account workor/cco:account jan@work.comnames the account by its config folder or email. -
Where it opens: docked right of Claude Code (default), docked left, or in a window of its own, as the placement setting says.
pin the viewer moves it:1right,2left,3window. The viewer closes and reopens there, keeping its selection and scroll positions, and the session remembers the place for the next time it opens (on start,/resumein a new Claude Code,/cco:…). A window takes the keyboard focus from Claude Code, also when it opens on start, since Windows Terminal cannot hand the focus back to another window. In tmux, window is a tmux window. A/cco:…command typed while Claude is working only runs when the turn ends; by then you may be in another tab, and Windows Terminal can only split the tab that is active then, so in that case the viewer opens in a window of its own (tmux still splits Claude Code's pane), andpdocks it. A viewer that already runs stays where it is when you change the setting or/resumeanother session. -
cco(orcco watch) in a project directory starts the viewer by hand, in any terminal:--cwd <dir>: the project whose session is shown--session <id>: show this session instead (see Session viewer in the Sessions view): its chat, live, with a prompt line while it runs, and settings of its own--view chat|git|plan|sessions|settings|monitor|accounts: view to start with (default: the session's last view, see view per session, elsechat)
A viewer started this way follows the project's latest session. To tie it to one Claude Code instead, select a session running in it in the Sessions view and press
Enter(↵ attach), see Sessions. -
cco openopens the viewer next to the current pane like the/cco:…commands, with--viewand--placement right|left|window(default: the session's placement, else the setting). -
cco import <zip>imports the session backups of an archive that the Sessions view exported into the current folder, see Sessions. -
cco doctorchecks what cco needs and prints a report, one line per check (✓fine,!worth a look,✗error), with what to do below each problem:- Installation: npm install or checkout, the path the plugin starts cco by (
~/.claude/cco/cli.json), whether the plugincco@cc-outlineis installed and enabled, and whether its version matches the CLI. - State files in
~/.claude/cco/of all projects: those of Claude Code processes, viewers and viewers of one session (viewers/, beforeobservers/andremote-<id>.viewer.json) that have ended, unfinished writes (*.tmp), debug logs, files that are no valid JSON, records of sessions that ended over a day ago, the restore state of projects without transcripts, and trash folders without a readable manifest. Marks, positions and views are never touched. - Settings: values of the wrong type or unknown, unknown keys and old formats in
settings.jsonand insettings.session-viewer.json(the viewers of one session's). - Environment: Node version, Claude Code's folder (
CLAUDE_CONFIG_DIR), and the terminal (Windows Terminal, also withoutWT_SESSION, or tmux). - Hooks: while a Claude Code runs in the project (
--cwd, default: the current folder), whether the plugin's hooks recorded its last prompt.
It exits with 1 if an error is found.
--fixrepairs without asking what it can: deletes or renames (.corrupt) the state files above, records the CLI's path, rewritessettings.jsonwith the values that apply, and for an npm install updates an older plugin (claude plugin marketplace update,claude plugin update; restart Claude Code afterwards). Then it checks again./cco:doctorshows the report in Claude Code, and doctor in the Settings view's Reset group checks and repairs, each after asking. - Installation: npm install or checkout, the path the plugin starts cco by (
All views share one layout:
- Top bar: the view tabs, a status summary and, on the right if there is room, the version of cc-outline. Options that are on are not repeated there; the help line highlights them.
- Body: a list on the left and a preview on the right. When the preview is longer than the pane, its first or last row becomes a blue badge that says how many lines are hidden above (
↑ 5 more lines (ctrl+Home)) or below (↓ 15 more lines (ctrl+End)), with the key that jumps there; a click on the badge jumps as well. In a narrow preview the key is left out. A scroll bar on its right edge shows which part is in view: the thumb touches the top or bottom of the track only when the preview is at its very top or end. A click on the bar jumps there. The status in the top bar names the position:top,end, the lines in view in between (121–160/300), orallwhen everything fits. - Help line: the keys of the current view at the bottom.
The viewer sets the terminal title to the session title, the one set with /rename or else the one Claude Code gave the session; until the session has one, the project folder. So its tab, and a window of its own in the taskbar, show which session it follows instead of just cco. Like Claude Code, the title starts with a status mark: ◐ and ◑ in turn while Claude works on the last turn, ✳ when it waits for you. A viewer of one session (--session, --remote; a remote one's title starts with ◈) shows the status mark only while its session runs in a Claude Code. A Windows Terminal profile with suppressApplicationTitle keeps cco.
Press 1 to 6 to switch between the views, or Tab and Shift+Tab (or → and ←) for the next and previous one (hidden views are skipped; past the last comes the first again). All of them keep running in the background, so the chat keeps following the session while you look at the changes.
Lists. All lists work the same way:
↑/↓select the previous or next entry,Home/Endthe first or last one. The preview next to the list scrolls by page withPgUp/PgDnand by line withCtrl+↑/Ctrl+↓;Ctrl+Home/Ctrl+Endgo to its top and bottom.←/→switch to the previous or next view.- Chat and Plan show the oldest entry at the top;
sturns the list around and remembers it (the order settings). Sessions (with its trash) and Monitor always show the newest at the top. The keys follow what you see:↑/↓go up and down,Home/gto the top,End/Gto the bottom; in the chat, whichever of them reaches the newest turn resumes follow mode. - If the text of the selected entry (prompt, file path, plan or session name) is too long for the list, it scrolls: at most 250 characters, then it starts over from the beginning. The other entries are cut with
…. The Settings view switches this off. - If the list is longer than the pane, its first or last row shows how many entries are hidden above (
▲ 12 more Home) or below (▼ 5 more End), together with the key that jumps there. - Chat, Plan and Sessions (with its trash) show only the time of an entry; a dimmed line with the date (
── Mon 28 Sep 2026 ──) starts each day, above its entries in either order. A list whose entries are all from today has none. The date separators setting turns the lines off. The lines cannot be selected (a click on one selects the day's first entry), and when the day's line has scrolled away, the▲row names the day (▲ 12 more · Mon 28 Sep Home). In a session's preview, plans, agents and prompts get these lines if the session spans several days. The Monitor's list of days gets a line per year (── 2025 ──) once it reaches into another year. - Mouse: a click on a tab in the top bar switches to its view, a click in a list selects an entry, a double click does what
Enterdoes (in every view; a confirmation still asks first), the wheel moves to the previous or next one.↓ more ↓loads with a single click. In the preview the wheel scrolls, and a click on a web address (https://…, also one wrapped over two lines) opens it in the browser when you let go. Dragging in the preview selects text in the preview only, not the list beside it, and copies it when you let go (copied 4 lines); dragging past the top or bottom scrolls on. The header above it (the prompt in the chat, the path in Changes) selects the same way, on its own and without the❯in front. A selection that starts right of the line numbers (Changes) leaves them out. A click or the right mouse button drops it. To select across the whole pane as the terminal does, holdShiftwhile dragging. The mouse setting turns this off. Spacemarks the selected entry as a favourite (★at the start of its row) or removes the mark.Shift+↑andShift+↓jump to the previous and next marked entry, and the top bar counts them (★ 2).- With the pinned favorites setting (off by default), every list but the trash shows its marked entries once more at the top, under
── ★ Pinned ──, in the list's order, and below a plain line (or the first date separator) the whole list, where they keep their place; both rows show the★.↑/↓,Home/Endand the wheel follow the rows on screen, through both copies;Shift+↑/↓steps through the pinned rows (from the list below, up to the last one). Following (Chat, Plan) and a restored selection go to the entry's place in the list. Marking or unmarking an entry in the list keeps the selection there; unmarking a pinned row selects the next pinned one (after the last, the one above), and the only one stays selected in its place in the list. A filter applies to the group too, and Sessions and the Monitor pin only what their range has read. The pinned sessions setting (on by default) also puts the active session (●) and those running in another Claude Code (▶) into the Sessions view's group, marked or not and also with pinned favorites off; a session that ends leaves it, and a selected copy hands the selection on as unmarking does. Ctrl+Ffilters the list. A dialog opens; the list shrinks while you type and the dialog counts the matches (12 of 340).Enterkeeps the filter,Escdrops it;↑/↓and the wheel select in the filtered list meanwhile. While a filter is on, the list's top row shows it (⌕ plan*view · 12 of 340 · ^F clear) and the top bar counts12/340;Ctrl+Fagain drops it, and the nextCtrl+Foffers it again (selected: type to replace it,→to add to it). Case does not matter, every word must occur (in any order),*stands for any text and?or_for one character. The dialog's[x] in the list(^L) and[x] in the details(^D) choose where it looks; the choice is kept as the filter in setting (default: the list only). The list is what a row shows: the prompt (Chat), the path (Changes), the plan's title (Plan), the title and project (Sessions), the date written several ways and the weekday (Monitor), value, group and name (Settings). The details are what the preview adds: attached files and subagents (Chat), the former path and the status (Changes), the plan text, status and feedback (Plan), folder, branch, id, prompts, changed files, plans and agents (Sessions), the models of the day (Monitor), the description (Settings). Each view keeps its filter while the viewer runs; the trash has none. Following (Chat, Plan) goes to the newest entry that matches, andShift+↑/↓jump only between marked entries that are shown.- Marks are saved per project in
~/.claude/cco/<project-slug>.favorites.json: turns by prompt, files by path, plans by their id, sessions by their id, Monitor days by their date. The settings are global, and so are their marks, in~/.claude/cco/favorites.json. - Every list remembers its selected entry, and the preview remembers its scroll position for each entry: switch to another entry and back, and you are where you left it. Detail views keep their own position (the whole file of a changed file, the changes to a plan's previous version). Both survive closing and reopening the viewer; they are saved per project in
~/.claude/cco/<project-slug>.positions.json. A list that was following the newest entry (Chat, Plan) follows it again. With remember positions off in the Settings view, they are kept only while the viewer runs.
Chat view
The Chat view shows the session turn by turn. A turn is one prompt plus everything Claude answered to it.
List (left). One entry per prompt, with its time.
- Slash commands appear as
/name args, with the command's name in orange in the list and above the answer, shell commands run with!as! command, with their output as the answer. Claude Code writes a!command to the transcript only when it has ended, so it shows up then. - Side questions asked with
/btwdo not show up: Claude Code keeps them in memory only and writes neither the question nor the answer to the transcript. - Pasted images keep Claude Code's placeholders in the prompt,
[Image #3], in cyan and with a dimmed(o); a click on one opens it. Images without one (older transcripts, a prompt of images only, listed as[Image]or[3 images]) get theirs added at the end. - Browser calls (Claude in Chrome, and the Browser pane of the Claude desktop app) show one line per browser action, verb first:
↗ navigate example.com/…,⊙ click (451, 265),⌨ type "…",▣ screenshot · 1568×744,⌕ browser find "…" → 2 elements,⇄ browser network; a browser batch lists its actions below it. A dimmed line names the page whenever it changes (on CloudWatch | eu-central-1). At full, scripts, search results and console messages follow. Screenshots are numbered through the turn,[▣ 3]after the action that took them (a scroll or click can bring one too): a dimmed(o)after the mark names the key. A click on the mark opens it in the system's image viewer;olists the turn's images, the prompt's pasted ones first, then the screenshots with their action and page, to open one (Enter keeps the list open, Esc orocloses it). The image is the copy the desktop app saved next to the transcript, otherwise the image data from the transcript, written to a temporary folder. - Subagents. Where Claude starts a subagent, the answer shows it as a block:
◆ Explore · Map the order flow · sonnet · background, below it its status (⠿ running, spinning, then✓ completed · 1 min 13 s · 12 tool uses · 41k tokens, or✗ failed). In the list,◆2marks a turn that started two subagents, and the spinner stays while background agents of that turn still run.ashows what the turn's subagent did instead of the answer: its task and its answers, with tool calls and thinking astandhsay, read live from its own transcript in~/.claude/projects/<project-slug>/<session-id>/subagents/. With several agents,agoes on to the next one andAback to the previous one, past the last or first back to the answer;Escgoes back at once.↑/↓switch turns as always, which closes the agent's page. When a background agent hands its report back, the report gets a turn of its own (↩ Agent "…" reported back, magenta): the report comes first with a magenta bar, then Claude's reaction to it.ashows it as the agent's result too. The Settings view hides the blocks (Chat: agents). - Workflows. Where Claude starts a dynamic workflow (the Workflow tool: a script that runs agents in the background), the answer shows it in a magenta frame like a question or browser actions,
◇ Workflow · ticket-rating · backgroundon its top line, inside it its description, its status (⠿ running · phase 1/2 Rate · 3 of 8 agents done, spinning, then✓ completed · 18 min 24 s · 8 agents · 356 tool uses · 862k tokens) and its agents by phase, each with its status. The agents are read from the run's folder next to the transcript (<session-id>/subagents/workflows/<run-id>/) every second while the workflow runs, so they show as they start and return. They are the turn's subagents:◆8in the list,+ ◆8 862kin the stats, anda/Ashow each one's page, where the request the workflow relays and the task its script computed are shown without the harness's preamble, and the agent's structured result as a JSON block at the end. A resumed run shows↻ resume <run-id>. The notification at the end is an entry of its own like any task's;Entershows how its agents went (8 agents · 1 failed) and its result, JSON as an indented code block; Claude Code cuts a long result and keeps the whole one in a file, whichoopens. Like agents, the blocks follow Chat: agents. - When a background agent or command stops, Claude Code reports it to Claude. That report becomes an entry of its own, marked
↩(green when it completed, red when it failed), with Claude's reaction as its answer.Entershows what the task returned. - Images and PDFs other tools return (
Readof a.pngor a.pdf, MCP tools) are marked like screenshots: images go on in the same numbering,[▣ 4], PDFs have their own,[▤ 1]. With tool calls off they still show, as a line of their own (▣ diagram.png [▣ 4] (o)). A click on the mark opens the copy in the transcript, what Claude saw. - What came with a prompt and what the turn's tools returned is named in a line below the prompt:
📎 2 pasted images · @src/Order.cs · 12 lines selected in Foo.cs · 1 tool image · 3 screenshots · 1 PDF (o)(files and folders mentioned with@, lines selected in the IDE or a diff). The list shows the number of images and PDFs before the prompt,▣4.Enterlists them below the full prompt, with where each pasted image is stored.olists them all to open one in the app the system uses for it (Enter keeps the list open, Esc orocloses it): a pasted image from the copy Claude Code keeps in~/.claude/uploads, or, when that is gone, from the transcript, written to a temporary folder; a file or folder mentioned with@where it is now; a tool's image or PDF from the transcript. On a subagent's page,oand the marks are that page's. Files Claude Code attaches again after/compactare not the user's and are left out. /compactshows the summary Claude Code compacted the conversation into as its answer, under a heading with the tokens before and after and how long it took. An automatic compaction gets an entry of its own,⟳ Conversation compacted automatically, with Claude's work after it.- When you come back after a while, Claude Code writes a recap of the session. The chat shows it below the answer it follows, set apart with a yellow bar and
※ Recap. /compactcan move the session to a new transcript, for example when it sends the session to the background. The viewer then reads on in that transcript, so the chat keeps the turns so far and shows what follows. Where it went on, the list has an entry of its own,⤷ Session continues in …: its details name both sessions, the compaction (tokens before and after, how long it took), whether the session was sent to the background, and the command to resume it; Claude's answers after the switch belong to it. Opened on the new transcript later, for example after/resume, it reads the earlier one first. The Sessions view shows both as one session, resumed under the newer id.- Prompts you sent while Claude was still working are marked with
↳. Claude Code stores these separately; cc-outline shows them as turns of their own. - The turn Claude is working on has a spinning
⠋in front of it, and its answer ends withClaude is working…until Claude finishes. With tool calls off, that line counts the turn's calls so far (Claude is working… · 12 tool calls), so you can see it getting on. A turn you stopped withEscin Claude Code is marked with a red⊘, and its answer ends with⊘ Interrupted by user(or… during a tool call). - Turns keep their marks across restarts and when you continue a session with
--continueor/resume, which starts a new session id but keeps the turns.
Prompt (top right). The selected prompt stays pinned above the answer while you scroll.
- It shows at most five lines (blank lines left out) and never more than half the pane height.
- If it is cut, its last line ends in
…and the separator reads↵ full prompt. PressEnterto read the whole prompt, thenEnterorEscto return to the answer. - Below it, marked with
$like the prompt with❯, what the turn took:2 min 14 s · ↓ 3.2k · ctx 84k · opus-5.5 · 12 tools · + ◆2 58k. That is how long it ran (counting up while Claude works), the tokens Claude wrote (thinking included), how full the context was at its end, the models, the tool calls and the subagents it started with their tokens. A second line counts the files it created and changed and their lines:files +2 ~5 · lines +184 −37. Files deleted with a shell command are not counted, nor what subagents wrote. Turns without an answer from Claude (!commands,/rename) have no such line. Parts that do not fit the pane width are left out from the end. Entershows it in full below the whole prompt, under its own$ Detailsheading: when the turn ran (14:02 – 14:09 · 6 min 41 s), the tokens per model, the context, the tool calls per tool (Edit 6 · Read 9), each subagent with its type, description and status, and each file it created (+) or changed (~) with its lines. While Claude works, the duration counts up and the rest grows with the transcript.
Answer. The answer is rendered as Markdown and wrapped to the pane width. List items keep their indentation when they wrap.
-
Browser. With tools
off, what Claude did in the browser still shows, in a cyan frame (╭─ Claude in Chrome · 6 actions · 2 screenshots,Browserfor the desktop app's pane): one line per action as above, the page in between, and below an action what it found, dimmed and at most five lines: the elements a search matched, a script's value of several lines, console messages. Claude's text between the actions starts a new frame; tool calls hidden withoffdo not.cleaves the frames out. -
Questions. When Claude asks you something (a multiple-choice question in Claude Code), the answer shows it in a yellow frame (
╭─ Claude asks). Each question starts with a yellow badge (its number and header, e.g.1/4 Focus), then its options: the one you chose marked●in green, the others dimmed○. Below, your answer in green as┃ You: …((own answer)when you typed it, and your note if you added one). A dimmed line separates the questions. The frame is only for toolsoff(t), so questions show even then; withcompactandfulla question is a tool call like the others:⚙ AskUserQuestionwith the question and your answer, infulleach question with its answer below. -
Tool calls.
tsteps through three levels:- off (default): no tool calls.
- compact: one line each, with its result:
⚙ Read src/open.ts · lines 85–145 of 300,⚙ Edit src/open.ts · +12 −3,⚙ Bash Run the tests · ✓ · 14 lines,⚙ Grep TODO in src · 3 files,▤ Plan presented → approved.✗marks a tool that failed,⊘ deniedone you rejected. - full: also the command, the last 10 lines of its output, the files found and the pages a web search returned.
Claude Code writes a tool call to the transcript only once it has finished, so a call shows up together with its result: a question appears when you have answered it.
-
Tool calls (
t) and thinking blocks (h) are hidden by default. -
With
w, wrapping is switched off: paragraphs and code lines stay whole, andCtrl+←/→scrolls sideways. -
ccopies the turn's Markdown (without tools and thinking) to the clipboard.
Follow mode is on by default.
- The newest turn is selected, and the view sticks to the bottom while the answer grows, like in Claude Code.
- Scrolling up or selecting an older turn leaves follow mode. The badge
↓ 15 more lines (ctrl+End)at the bottom of the preview then shows how much is left below;Ctrl+Endor a click on it goes there. Scrolling back down to the end,↓to the newest turn,Ctrl+EndorGresumes following.ftoggles follow mode directly. - Each turn remembers where you left it scrolled. An older turn that is not scrolled to its end also shows the badge; there
Ctrl+Endjumps to the end of that answer.
Status. The top bar shows:
- the session id
- the number of turns
- the scroll position (
top,end, the lines in view such as121–160/300, orall) - the number of marked turns (
★ 2) - with wrapping off, how far the answer is scrolled sideways (
→ 16 cols)
Which options are on (f follow, t tools, h think, w wrap) shows in the help line at the bottom, where they are highlighted.
The viewer switches sessions automatically after /clear or /resume.
Changes view
The Changes view shows what Claude has changed in the working tree, compared with HEAD.
Repositories. The view shows the repository the project folder is in and every repository up to 3 folder levels below its top level (or below the folder, when it is in none): repositories inside it, submodules and worktrees, also in folders the repository ignores. Hidden folders, node_modules, bin and obj are not searched. Each repository gets a separator with its path and branch (── tools/bar · main ──; the project's own repository first, by its folder name, then the others by path), also when it is the only one. The separator can be selected: its preview names the folder, then in one line a git operation in progress (REBASE 3/7, MERGE, CHERRY-PICK, REVERT, BISECT, AM), the branch with ↑/↓, its upstream and when it was last fetched (fetched 3 h ago; yellow after a day, never fetched only with an upstream). Below it: the remote (the upstream's, else origin, else the first; +1 for each other) and what kind of repository it is (submodule, worktree of its main folder, shallow), the tag git describe --tags names and the stashes (yellow), the identity commits are made with (no user.email in yellow when none is set), the changes in one line (3 files · +40 -12, or No changes) and the last 100 commits (Last 100 of 1 234 commits:, with older commits: git log below when there are more). What is missing is left out. All of it is read again with every refresh, the remote, kind and identity every 30 seconds; Enter opens the folder. An operation in progress also shows in the separator, which turns yellow (── proj · main · REBASE 3/7 ──). A nested repository or submodule no longer shows as an entry of the repository around it; its files show under its own separator. The first 10 repositories are read; with more, the last entry ↓ more ↓ reads the others (Enter or a click) until the viewer restarts, every 10 seconds. The Changes: sub-repositories setting turns the search off: then only the project's repository shows, under its separator.
List (left). One entry per changed file, with its status and line counts, its path relative to its repository. A marked file keeps its mark by path, also after it was committed and changed again; in the Pinned group it shows its repository's path in front. The statuses:
Mmodified,Aadded,Ddeleted,Rrenamed,Ccopied,Uconflict?untracked, counted as all-added lines
File header (top right). It stays in place while you scroll, like the prompt in the Chat view. It shows:
- the full path, from the project's repository (with the repository's path in front for one below), wrapped at
/ - the status, the line counts and the current mode (
difforwhole file) - for renames, the old path
Diff. Each hunk starts with its @@ header.
- Every line shows its old and new line number, a
+/-sign and a colored background for added and removed lines. ]and[jump to the next and previous hunk.- Repositories without any commit are diffed against the empty tree.
- Binary files are only named.
Whole file. Ctrl+Enter switches to the complete file as it is now, with line numbers and highlighting but without change markers. There, ] and [ jump between the changed blocks. Ctrl+Enter or Esc returns to the diff. Deleted files have no content after the change, so the view says so.
Opening. Enter or a double click on a file in the list opens it as it is now in the app the system uses for its type (via explorer.exe, open or xdg-open). Deleted files cannot be opened. In tmux, Ctrl+Enter only arrives with extended-keys on.
Wrapping. Long lines wrap by default. After w, lines stay whole and Ctrl+←/→ scrolls sideways in steps of 8 columns. The line numbers and hunk headers stay in place.
Status. The top bar shows the branch of the selected entry's repository, the number of repositories (when there are several), the files and line counts over all of them, and the scroll position. If the branch has an upstream, ↑ is followed by the number of outgoing commits (not yet pushed) and ↓ by the number of incoming ones (not yet pulled), e.g. main ↑2 ↓1. Non-zero counts are highlighted. cc-outline never fetches, so the incoming count is as of your last git fetch or git pull.
Refresh. While the view is visible, it re-reads git every 2 seconds and searches for repositories every 30 seconds; F5 does both at once, so a repository created or cloned since (git init, git clone) shows. The selected file stays selected as long as it is still changed.
Syntax highlighting exists so far for C# (.cs, .csx). Add more languages through the LANGUAGES map in src/render/diff.ts.
Plan view
In plan mode (Shift+Tab in Claude Code), Claude first writes a plan and asks for approval. When you ask for changes, it writes a new version. The Plan view keeps every plan of the session.
List (left). One entry per plan, with its time, its title (the first heading) and its status:
✓approved✗rejected●waiting for your decision✎being written: Claude is still in plan mode and has not presented it yet
Plan (right). The selected plan rendered as Markdown. Above it, pinned while you scroll:
- the title
- the version, status and time (
v2 · approved · 11:15) - the prompt the plan answers
- your feedback, if you rejected it with a comment
Changes between versions. If there is an earlier version, the separator below the header reads ↵ changes to v1. Enter then shows what changed compared with that version, as a diff with line numbers. Enter or Esc returns to the plan.
Following. The newest plan stays selected while Claude presents new ones; selecting an older plan stops that, and End resumes it.
While Claude writes. A plan shows up as soon as Claude writes it, not only once it is presented. Claude Code records the presented plan in the transcript only after you decided; but when plan mode starts it names the plan file (in ~/.claude/plans/), and Claude writes the plan there first. The Plan view shows that file as ✎ and updates it while Claude revises it. Once the plan is presented and you decide, it becomes a regular entry (✓/✗); after a rejection, the next revision shows up as ✎ again, and Enter shows what it changes. c copies the plan's Markdown.
Wrapping. Long lines wrap by default. After w, lines stay whole and Ctrl+←/→ scrolls sideways; in the changes between versions the line numbers stay in place.
Status. The top bar shows:
- the number of plans, and how many are approved, rejected and waiting
- the scroll position
- the number of marked plans (
★ 2) - with wrapping off, how far the plan is scrolled sideways (
→ 16 cols)
The help line highlights w wrap while wrapping is on and End follow while the newest plan is followed.
Sessions view
The Sessions view is an overview of your Claude Code sessions: of this project by default. a opens the filter, a dialog of check boxes remembered in settings.json (Sessions: folders, accounts, background): the folders (this one, the others, or both), the accounts found on the machine (shown with two or more; checking all of them also takes an account signed in later) whether the background sessions show and, with the remote API, the remote ones. ↑/↓ pick a row, Space switches it, Enter applies, Esc cancels; the last box of a group stays checked. Below the rows the dialog names every mark of the list in short; the Sessions rows of the Settings view explain them in full. The help line shows a filter highlighted while it differs from this folder, this account and all sessions. The active session always shows. It only reads them: the other views keep showing the active session.
List (left). One entry per session, the one last written to first, with the time its transcript was last written (under a line per day; for a session continued under a new id, its latest transcript). Any write counts: a prompt, Claude working, a report of a background task, a rename, an import or a move. Each row shows, with all projects, the project's folder name and then the session's name: the name given with /rename (bright), otherwise its first prompt (dim and in quotes, „like this“). Background sessions, those started with claude -p or the Agent SDK and those the Claude Code daemon runs, have a dim ◌ before their project and name, and the header says how they ran (◌ background: claude -p / SDK, or daemon with the claude attach command while it runs). The active session is marked with a green ●, sessions running in another Claude Code with ▶, and a session whose folder is gone with a gray ∅ (with all projects, its folder name is struck through; the preview says folder gone, and the filter finds it by that). Whether a folder exists is looked up once while the view runs, again after F5. While Claude works in one of them, its mark blinks; while it waits for you (a permission, a question), the mark is yellow. The preview's header says working or waiting for input. Both come from the status Claude Code writes to ~/.claude/sessions/ (version 2.1.283 on), read every second. A blue ◎ marks a session open in a session viewer (◎2 for two), see Session viewer below. A magenta ◇ marks a session in which Claude started a dynamic workflow (◇2 for two). Sessions that only ran slash commands such as /resume or ! commands and changed nothing are left out.
Other accounts. With the last two scopes, the list also holds the sessions of the other Claude accounts signed in on this machine (the ~/.claude* folders, see the Accounts view), sorted in with this account's. Every row then starts with a bar ▌ in its account's colour (the colour chosen in that folder's settings, else the one from the email; gray where it is off), this account's too. The preview's header names the account (email, organisation, folder) and whether the cco plugin is installed there; whether the session runs in a Claude Code there shows like for this account's. Enter on another account's session offers to continue it there, in a new window under that account's folder (cco claude --config-dir … -- --resume), to switch to its tab while it runs there, or to copy the command (CLAUDE_CONFIG_DIR=… claude --resume …, a folder in the home folder written as %USERPROFILE%\… or $HOME/…; also c). Such sessions can be marked, but not deleted, renamed, exported or moved; the trash holds this account's only. The filter also finds a session by its account's email. A session continued in another account shows in both, each with its ⇢/⇠.
Range. The list holds the sessions written to in the last 7 days (the Sessions: range setting: today, 7, 30 or 90 days, or unlimited; days count from midnight, today included). The active session and sessions running elsewhere are listed even if that was earlier. When there is no session at all, the list's top entry is ⤓ import sessions…, which opens the import (Enter or a double click). The last entry, ↓ more ↓ (centred, blue like the previews' "more lines"), reads the whole history with Enter or a click (↓ loading… 42/97 ↓ meanwhile) and then goes; that holds until the viewer restarts, also if the setting changes. Transcripts last written before the range are not read at all, so a short range is quicker. A filter never hides it.
Details (right). Pinned at the top:
- the name
- the date, start and end time, duration and git branch
- the number of prompts, plans, subagents, workflows and changed files
- the folder the session ran in, where the resume command has to be run
- the command that continues the session:
claude --resume <session-id>.ccopies it to the clipboard. In a running Claude Code,/resume <session-id>does the same.
Below it:
- Plans with their status (
✓approved,✗rejected,●waiting), time and title - Attachments (only if there are any): images pasted into the prompts (
⎘, with the prompt), files and folders mentioned with@(@, once per path,(3×)for three prompts), images (▣) and PDFs (▤) tools returned, with their time. A click on one opens it,olists them all; the list counts the images and PDFs in the row (▣3). For a session in the trash they are read from there. - Workflows (only if the session started any, after the plans): each dynamic workflow with its status, start time, name, number of agents, duration and description
- Agents (only if the session started any): the subagents with their status (
✓completed,✗failed,⠿running), start time, type, task and duration - Changed files: every file Claude edited or wrote. Files of the project come first, relative to it; files elsewhere (such as plan files) are dimmed.
- Prompts with their time. Reports of background tasks (
↩in the chat) are not counted as prompts.
Remote sessions (experimental). With the setting Sessions: remote API on, the list also shows the Remote Control sessions of this account that claude.ai knows (a Claude Code started with claude remote-control or /remote-control, as the Claude app lists them), marked with a cyan ◈ before their title. Use it to see from another machine what runs elsewhere. cco reads them through an interface of claude.ai that Anthropic does not document and may change at any time (hence experimental and off by default), with the login Claude Code keeps in .credentials.json: it only reads that file, never writes or renews it, so once the login has expired the top bar says so and Claude Code has to be started or /login run. It needs a Pro, Max, Team or Enterprise login; behind a company proxy that replaces certificates, start cco with NODE_OPTIONS=--use-system-ca. The preview shows what claude.ai reports (◈ remote · working · connected) and, once the session is selected, its prompts, plans and changed files read from its events; Enter offers its address (https://claude.ai/code/…), c copies it. Like the app, the list leaves out the sessions claude.ai has archived (a Remote Control session is archived once its Claude Code has exited). A session of this machine that is connected to claude.ai shows ⇄ instead of appearing twice: its transcript records the id claude.ai lists it under. remote in the filter (a) lists them with the others or not at all. Enter on a remote session also offers Open it in a session viewer: like a session of this machine (see Session viewer below), a session viewer (cco watch --remote <id>) follows the whole session live in its chat (no other views but its own settings), as the app shows it, refreshed every second; any number of them, ◎ in the list, Bring its session viewer to the front. With the setting Sessions: steer remote (also experimental, off by default), cco steers them like the app: the Enter dialog in Sessions starts with what fits what the session does (Send a prompt while it is idle, Interrupt Claude while Claude works), and the prompt line below the chat of every viewer of the session sends (without the setting it says steer remote is off; switching the setting takes effect at once): the chat has the keys at first, Tab or i hand them to the prompt line, which grows with its text up to six rows (Ctrl+J starts a new line, Enter sends, also while Claude works, which takes it in when it can); Esc stops Claude while it works, else hands the keys back to the chat; PgUp/PgDn and the wheel scroll the chat meanwhile. Several viewers, the app and the terminal can steer the same session at once. The prompt window of Sessions takes several lines too and keeps an unsent text until it is opened again. A session whose Claude waits for you, for a permission or a question, gets a yellow ⚠ (and joins the Pinned group); its ◈ blinks while Claude works there. Its Enter dialog starts with Allow or deny (with the command it wants to run) or Answer Claude's question, and in its own viewer it takes the place of the prompt line, as in Claude Code: the command with Allow, Deny and Deny, saying why… (↑↓ and Enter, or 1–3), or the question. A permission is allowed once, denied, or denied with a reason Claude reads, as in the app (which offers no always allow either); a question shows its options like the filter dialogs ((•) one, [x] several, Other… with a text field) and is sent once every question has an answer. When the app or the terminal answers first, cco's window closes with already answered in another app, and what was typed in it is copied.
Refresh. Sessions are read when the view is first shown and re-read every 3 seconds while it is visible. The first read fills the list as it goes (reading 42/97 in the top bar); with many projects it takes a few seconds. After that only files that changed are read again, and of those only the part that was appended. Only what the overview shows is kept in memory, not the answers.
Enter: attach, resume, detach. Enter (or a double click) on a session always opens the same dialog: the actions that make sense for it, the usual one selected (↑/↓ and Enter, or its number; Esc cancels), the others greyed out with the reason they cannot be chosen now. The help line names the action selected (↵ switch, ↵ attach, ↵ resume in this Claude Code, ↵ new Claude Code, ↵ new Claude Code + attach, ↵ move to this project, ↵ session viewer, ↵ copy). A viewer attached to a Claude Code is one opened by a /cco:… command or on start, or attached later; one started by hand (cco watch) is detached and follows the project's latest session. Only one viewer runs per Claude Code: cco watch --claude-pid refuses to start a second.
| The session | Viewer attached | Viewer detached |
|---|---|---|
| the viewer's own | Stay attached · Detach this viewer | (as any other) |
| runs in another Claude Code | Switch to its Claude Code tab · Attach this viewer there | Attach this viewer · Switch to its Claude Code tab |
| runs nowhere | Continue it in this Claude Code · Continue it in a new Claude Code window | Continue it in a new Claude Code window and attach · Continue it in a new Claude Code window |
Every dialog about a session starts with the same head: its title; time span, prompts and files; with two or more accounts its account (▌ email, the bar in the account's colour, · this account for the viewer's own); its folder (or folder gone: …); where it stands (runs nowhere, runs in a Claude Code, this viewer's session). The confirmations (trash, delete for good, move to this project), the rename and export dialogs and the dialogs of continuing in another account start with it too; those about several sessions (export of the marked ones, emptying the trash) with a line that counts them. Where a dialog has more options than the pane has rows, only the selected one shows its detail line. With a second Claude account signed in on this machine, every dialog offers Continue it in … (with several, Continue it in another account…; see below). Another account's session (with the Sessions scope of every account) gets the same list: what works only on this account's folder (continuing it here or with the viewer, another account, moving, renaming, exporting, importing, attaching) is greyed out as only for sessions of this account; Switch to its Claude Code tab, Continue it in a new Claude Code window (under that account's folder) and Copy the command remain. Every dialog ends with Rename it, Export it (Export 3 marked sessions while sessions are marked), Import sessions… and Copy the command (claude --resume <session-id>, for a background session of the Claude Code daemon claude attach <id>), which is selected when nothing else can be done: without Windows Terminal or tmux there is no tab to switch to and no window to open. A session whose folder is gone cannot be continued; for one that runs nowhere, Move it to this project comes first and is selected (↵ move to this project).
- Detach this viewer: it stays open, now detached, and follows the project's latest session;
/cco:…in its former Claude Code opens a new viewer. Stay attached is selected, soEntertwice changes nothing. - Switch to its Claude Code tab brings the tab the session runs in to the front: in tmux its pane, in Windows Terminal the tab titled with the session's name (it takes a second or two; with two tabs of the same name, nothing is switched). A background session without a tab says to use
claude attach <id>. - Attach this viewer (there): the viewer stays where it is, switches to that session's project and shows its chat, follows it like a viewer opened with
/cco:chat(also after/clearand/resume), and closes when that Claude Code ends; its/cco:…commands then use this viewer. An attached viewer leaves its former Claude Code without one. Not on offer when that Claude Code has a viewer of its own. - Continue it in this Claude Code: in the Claude Code the viewer belongs to, with
/resume <session-id>. The command is typed in for you, after clearing whatever was typed there: in tmux into its pane, on Windows into its console (which tab or pane has the focus does not matter). Where that does not work, it is copied instead and the focus moves to Claude Code's pane next to the viewer, soCtrl+VandEntercontinue it. Selected when that Claude Code has no prompt yet (a/clearat the start does not count), and not on offer while Claude works or waits for an answer, or for a session of another project folder (/resumeonly finds the sessions of the folder Claude Code was started in). The viewer then follows the session as after a/resumetyped by hand. - Continue it in a new Claude Code window: a new Windows Terminal window (or a new tmux window), in the folder it ran in, with
claude --resume <session-id>. The shell stays open when Claude Code exits. The viewer stays as it is; the new Claude Code opens a viewer of its own if the auto open setting says so. - Continue it in a new Claude Code window and attach: only for a viewer that follows no Claude Code (one attached to a Claude Code leaves it be: the new one opens a viewer of its own). The same, then a progress dialog waits for its Claude Code (
Waiting for Claude Code…,4 of 30 s,Escstops waiting); that Claude Code opens no viewer of its own, and once it runs, the viewer moves next to it as the placement setting says and shows its chat. If it does not show up within 30 seconds, the viewer stays as it was, and the started Claude Code keeps running. - Move it to this project: only for a session whose folder is gone. After a confirmation, it moves into the project folder the viewer runs in: its transcripts and their folder (subagents, tool results) go to that project in
~/.claude/projects, with every path of the gone folder in them rewritten to this one, as an import does; the session id stays, soclaude --resume <session-id>continues it here. Its file history and session environment are kept by id and stay. cco's marks, scroll positions and view of it go along and are removed from the gone project's files. - Continue it in … / Continue it in another account…: only while another Claude account is signed in here, in a config folder of its own (
~/.claude-work, used withCLAUDE_CONFIG_DIR). With several, a list asks which;/cco:accountasks for the viewer's session. A copy of the session goes into that account's folder and continues there in a new window, under that account; its Claude Code opens a viewer of its own there, as the auto open setting of that account says. The original stays in this account, as it is: a running session keeps running, and the viewer stays where it is. Copied are the transcripts with their folders, file history, session environment and the pasted images, with paths into this config folder rewritten to that one; cco's marks, scroll positions and view go along. If that account has the session already (continued there before), the copy gets new ids. Before anything is copied, the cco plugin is installed in that account if it lacks it (claude plugin marketplace add,claude plugin install, run under its folder), and cco's CLI path and, if it has none, these settings (without the account colour) are given to it. If the installation fails, the dialog shows why (ccopies the commands);Escthen asks whether to go on without the plugin (no hooks there: the viewer does not follow/clear,/resumeor the session's end) or to stop. Both sides note it: the list marks the original⇢and the copy⇠, and the header names the other account. Without Windows Terminal or tmux, the dialog gives the command to run (ccopies it). - Open it in a session viewer (Open another session viewer while one is open, Bring its session viewer to the front): see Session viewer below.
- Open its folder: the folder it ran in, in Explorer, Finder or the file manager (also for another account's session; greyed out once that folder is gone).
- Rename it: asks for a new title, the current one filled in, and gives it to the session as
/renamedoes: Claude Code's/resumeand its tab title show it as well. An empty title is refused. Only for a session that runs nowhere: a running Claude Code writes its own title again, so there it is greyed out, and/renamein that Claude Code renames it. For a session continued in a new session id, the title goes to the latest part, the oneclaude --resumecontinues.
Session viewer. For every session, running or not, also another account's and the viewer's own. A session viewer is a window of its own (Windows Terminal or tmux) that shows the session's chat, as the Chat view does, and settings of its own, and nothing else: no other views, no p or r; the top bar shows the tabs 1 Chat and 6 Settings (←/→ and a click switch too), then the session's title. Below the chat is a prompt line, as in Claude Code (a remote session's with steer remote, see above): Tab or i in the chat give it the keys, Ctrl+J starts a new line, Enter sends, Esc stops Claude while it works, else gives the keys back. A session of this machine gets its prompts typed into the Claude Code that runs it (on Windows into its console, under tmux into its pane), after whatever is typed there already, a line break as \ and Enter; the focus stays in the viewer. While it cannot, the line says why and keeps no keys: not running (Enter in Sessions continues it), background session (claude attach <id>), no tmux (macOS and Linux outside tmux), or Claude waits for you in its terminal while a permission or a question waits there, which only Claude Code shows. Its Settings view has only what fits such a window: how the chat looks (tool calls, thinking, agents, wrap, order, list width), the compact layout, the mouse, marquee, date separators, pinned favorites, filter in, confirm quit and remember positions. They are kept apart from the project's viewer in ~/.claude/cco/settings.session-viewer.json, shared by all such windows: the first one to start takes the project's viewer's values, and from then on a change on either side (also t, w, <, > in the chat) stays there. Its Reset group sets them to the default or takes the project's viewer's values once more; their marks ★ are their own. Everything else (accounts, remote, update) follows the project's viewer's settings. While the session runs in a Claude Code, it follows it live, with Claude's work as in the Chat view (Claude is working…, the ◐/◑ in the window's title); once it ends, the window stays open for reading. Reading works as in the Chat view: the full prompt, subagents, images, the filter, copying, tools and thinking, marks; marks and positions are the project's (each session keeps its own selected turn, so such a viewer does not move the one of the project's viewer). Every Open another session viewer opens one more, and the list marks the session ◎ (◎2 and up for several), the preview header says ◎ 2 session viewers open; Bring its session viewer to the front then raises the one opened last. A session continued under a new id (after /compact in the background) is followed into it. Without Windows Terminal or tmux it copies the command (cco watch --session <id> --cwd <folder>), and it is selected where nothing else can be done. q closes it.
Deleting. Claude Code has no command to delete a session; cc-outline moves it to a trash of its own first.
d(orDel) moves the selected session to the trash, after a confirmation. It then disappears from the list and from/resume.uright afterwards undoes it.- Moved are the transcript, the session's folder next to it (subagents, title), its file history for
/rewindand its session environment. The shared prompt history (history.jsonl) and plan files in~/.claude/plans/stay. - The active session and sessions running in another Claude Code (per
~/.claude/sessions/) can't be deleted. Tshows the trash, of the folders the filter checks and with its background choice (athere leaves the accounts out: the trash is this account's), most recently deleted first, with the details as before. There,urestores the selected session,xdeletes it for good andXempties the trash, each after a confirmation.TorEscreturns to the list.- In the confirmation,
Entermeans yes andEscmeans no. While it is open, no other key does anything. - The trash lives in
~/.claude/cco/trash/<project-slug>/, per project of the session. A session stays there until it is deleted for good; restoring is refused if the session exists again in the meantime.
Exporting. Export it in the Enter dialog exports the selected session, or, while sessions are marked (★), Export 3 marked sessions those, into one zip archive in your Downloads folder: cco-session-export.zip, or cco-session-export (2).zip and so on when that name is taken. A form asks first, filled with your last choice (the first time with the chat's tool and thinking settings): Tool calls off/compact/full, Thinking, Subagents none/reports/whole conversations and Turn stats. ↑/↓ pick a field, ←/→ (or Space) change it, Enter exports, Esc cancels. A running session is exported as it stands now. While the archive is written, a dialog shows the progress, then the archive's path; Esc closes it. Each session gets four folders in it, named <YYYY-MM-DD-HHMM>-<first 8 characters of the id>-<format> with the time it was last written (as in the list):
markdown:session.mdto read: a head (session id, project, branch, time,claude --resume), then per turn the prompt, its stats, Claude's answer with the tool calls at the chosen level, recaps, compaction summaries, the subagents with their reports, the workflows with their agents and results, and at the end the plans and changed files. Pasted images, browser screenshots and the images and PDFs of other tools are inattachments/, the images shown in the document, the PDFs linked. With whole conversations, each subagent's conversation (a workflow's agents' too) is a file of its own inagents/, linked where it ran.llm:session.mdas context for a language model:## Userand## Claudein turn, with tool calls at mostcompact, and without stats, recaps and screenshots.json:session.json, for scripts: the session, its turns with their blocks as far as the fields let them in (compactdrops the tools' input and details), stats, plans and agents, and the sameattachments/andagents/.backup: the session's files as Claude Code keeps them, belowclaude/(relative to~/.claude): the transcript and those it continued from, its folder (subagents, tool results), its file history and session environment, and the pasted images in~/.claude/uploadsit names; plus cco's marks, scroll positions, view and placement of it (cco.json) and amanifest.json(with the folder the session ran in and the~/.claudeit came from). The form's fields do not apply to it.
Importing. Import sessions… in the Enter dialog (or ⤓ import sessions… in an empty list) imports the backups of such an archive, e.g. on another machine; it proposes the newest cco-session-export*.zip in the Downloads folder, and you can type or paste another path. cco import <zip> does the same from the command line. Each session goes into the project folder the viewer runs in (cco import: the current folder), whatever folder it ran in, with cco's marks and positions added to what the project has:
- Every path of the folder it ran in is rewritten to this one, in the transcripts, their subagents and tool results: as written (
C:\Workspace\shop, also escaped in JSON), with slashes (C:/Workspace/shop) and as Git Bash writes it (/c/Workspace/shop), each into the same spelling of the new folder; only whole path parts (shop2stays), on Windows whatever the case. Paths into the~/.claudeit came from (saved screenshots, pasted images) are rewritten to this one's, with the new project folder. File history and session environment stay as they were. - A session that is in this folder already is skipped. One whose id is taken in another folder (imported on the same machine, or a copy of a session that is still there) gets new ids, for every part of a continued session, in the file names and wherever the transcripts name them; the dialog shows the new id (
new id 1a2b3c4d), and an archive imported again finds that copy and skips it. - Its files are written now, so it comes first in the list, also with a short range.
The dialog lists what was imported and skipped. Afterwards claude --resume <id> continues an imported session. CCO_EXPORT_DIR sets another folder than Downloads for both.
Remote Control Viewer
The Sessions view opens it: its list always starts with the row ⊞ Remote Control Viewer (with · ⚠2 waiting while sessions of any account wait for you); a click on it, or ↑ from the top of the list and Enter, opens the Remote Control Viewer in a window of its own (Windows Terminal or tmux; without them it copies cco rc-viewer), or brings the one that runs to the front; k does the same from anywhere in the list. Enter on a session offers Watch it in the Remote Control Viewer last, which selects it there (for the sessions the Remote Control Viewer lists: running, or active today). /cco:rc-viewer does the same for the session of the Claude Code it is typed in. cco rc-viewer opens it in the terminal it is run in. It is one window that watches every session of this machine, of every project and every account, and (with the setting Sessions: remote API) the Remote Control sessions on claude.ai. It runs once per machine; a second start says so and exits.
It has three columns. Left, the sessions that run now or were written today, grouped by what they need, under a line each: Waiting (a yellow ⚠ that blinks on and off: Claude waits for a permission or an answer, the one waiting longest on top), Working (a green ● that goes bright and dim), Idle (●: Claude waits for the next prompt; one the Remote Control Viewer saw finish blinks on and off until you select it while the Remote Control Viewer has the focus, at most 10 minutes, or 3 seconds when it was selected already) and Ended (a dim ∅: no Claude Code runs it any more). A remote session has a cyan ◈ instead of the ●. A cyan ⇄ after it marks the sessions whose questions and permissions are answered here, through claude.ai: the remote ones and those of this machine connected to claude.ai; it is dim while Sessions: steer remote is off. Each row shows the session's name (/rename, else its first prompt) and project, and at its end how long it has been in its state (3m); with other accounts, it starts with the account's colour. Middle, the turns of the selected session, as in the Chat view. Right, the chat of the selected turn, live while Claude works.
← and → move the keys between the columns; the help line names the column that has them (←→ sessions). In the sessions ↑/↓ select, Enter asks what to do with the selected one (see below); in the turns ↑/↓ select as in the Chat view; in the chat ↑/↓ scroll it. n selects the next session waiting for you, then those that just finished (the one finished first first). <, > and | change the width of the list of the column with the keys (the sessions, else the turns), stored in the settings Remote Control Viewer: sessions width and turns width. A click puts the keys in the column under it. 1 and 2 (or Tab) switch between the Remote Control Viewer and its own settings, kept in ~/.claude/cco/settings.rc-viewer.json like a session viewer's (the first start takes the project's viewer's values). The window's title counts the sessions waiting (⚠2 cco rc-viewer).
Enter on a session opens a dialog with what fits its state, the usual choice selected:
- Bring its terminal to the front: the Windows Terminal tab or tmux pane its Claude Code runs in (not for a background session, which has none:
claude attach <id>). Selected while Claude waits there for an answer or works, so a slip ofEnterstops nothing. - Write a prompt: the keys go to the prompt line below the chat (selected for an idle session).
- Interrupt Claude: while it works, like
Escin its terminal. - Make it steerable (Remote Control): an idle session of this machine not yet connected to claude.ai, with Sessions: remote API and steer remote on:
/remote-controlis typed into its Claude Code (the first time, Claude Code asks once there), and once claude.ai lists it, it gets the⇄and its questions are answered here. Claude Code's own setting Enable Remote Control for all sessions (/config) does this for every new session. - Answer Claude's question / Allow or deny …: a remote session that waits; the question or permission takes the prompt line's place (selected).
- Continue it in a new Claude Code window: an ended session (selected).
- Open it in a session viewer, Copy the command (a remote session's address).
The prompt line below the three columns writes to the selected session, as in a session viewer: typed into the Claude Code that runs one of this machine (tmux, or Windows), sent through claude.ai to a remote one while Sessions: steer remote is on. Space from any column or a click on it gives it the keys (in the chat column Tab and i too; turns are not marked with Space in the Remote Control Viewer); Enter sends, Ctrl+J starts a new line, Esc stops Claude while it works and otherwise gives the keys back to the chat. You stay in the Remote Control Viewer and see the answer in its chat. Each session keeps its own draft, so a text is never sent to another session than the one it was written for. While it cannot take a prompt (it ended, Claude waits in its terminal, a background session) the line says why.
What a session of this machine does comes from the status Claude Code writes to ~/.claude/sessions/ (version 2.1.283 on; before it, a running session counts as idle). Claude Code writes the permission or question it waits for to the transcript only once it is answered, so the plugin's hooks record it as it is asked (PreToolUse of AskUserQuestion, PermissionRequest; they only record and decide nothing). The Remote Control Viewer and the session viewer show it in the prompt line's place, the questions with their options or the tool with its command, read-only: it is answered in the session's terminal, which Enter brings to the front (the dialog names it there too). The hooks need the plugin updated and Claude Code restarted. A remote session's request is answered in the Remote Control Viewer. A session of this machine connected to claude.ai with Remote Control (/remote-control, ⇄ in Sessions) is the exception, with Sessions: remote API on: claude.ai has what it waits for, so its question or permission takes the prompt line's place and is answered there (Answer Claude's question / Allow or deny … is selected on Enter, Bring its terminal to the front next), and with Sessions: steer remote on, its prompts and interrupts go through claude.ai too (otherwise they are typed into its terminal as before). Its chat still comes from its transcript.
Monitor view
The Monitor view (5, or /cco:monitor) shows how Claude Code answered over a day, from the transcripts of all projects, subagents and the agents of workflows included.
List (left). Every day with responses in the last 7 days (the Monitor: range setting, like in Sessions), newest first, with how many; today leads. The last entry, ↓ more ↓, reads the whole history with Enter or a click. The usual values come from the days read, so a short range has fewer of them. ✗ marks a day with errors. Like every list, Space marks a day (★), for example one with a slump to come back to, and Shift+↑/↓ jump between marked days.
Chart (right). One bar per stretch of the day, as fine as the pane allows (5 to 60 minutes), with a y axis and the hours below:
vswitches the value: overall (see below; the chart starts with it), speed (output tokens per second of a response, median per stretch), wait (seconds until its first block was finished; an upper bound of the time to the first token) and responses (how many started).- Overall is an index of speed and wait together against the usual values at that time: 100 is usual, higher is better. It is the geometric mean of speed / usual speed and usual wait / wait, so twice as fast counts as much as half the wait. The day's index weighs each stretch by its timed responses.
- A dimmed
─marks the usual value at that time of day: the median of the 30 days before (for overall: 100). Bars more than 15 % worse than usual are red, more than 15 % better ones green, the rest cyan; a legend below the chart says so. ✗on the time axis marks an error Claude Code wrote into the transcript, such as a usage limit.mswitches the model: all models (the start), then each model seen, the one used last first, since models differ in speed.
Table. Enter switches between the chart and a table of the day's raw data, and back (Esc closes it too): one row per response with its time, model, wait, how long it took, output tokens, speed and overall index against the usual values of its stretch, and the errors in between. Responses too short to time are dimmed. The header shows the day's overall index.
Below the chart: the day's overall index, median speed and wait against the usual values, the number of responses, the slowest and the fastest hour, and the errors with their time. Today's chart follows new answers every few seconds while the view is shown.
Limits. It measures only your own sessions, so it shows how fast Claude answered you, not the load of the service as a whole. Speed depends on the model, the effort and how much Claude thinks. Transient API errors (overloaded, rate limits, retries) appear only briefly in Claude Code and are not written to transcripts, so they are missing here.
Accounts view
The Accounts view (0, a click on the "cco" at the left of the top bar, or /cco:accounts) has no tab of its own: the "cco", in the account's colour, is its tab and shows inverted while the view is open. The list holds the active account (the one of the Claude Code the viewer follows, ●) first, then the other accounts found (○, each in its colour) by email, by folder or the one used last first (accounts order, s goes round; last use is the latest prompt in its history.jsonl), then how accounts are found and how to add an account; without any account, a note says to sign in with /login. The details of an account show its email, name, organization, billing, seat and rate limit tier, the .claude.json they come from and its colour (chosen in that folder's settings, or from the email); whether the cco plugin is installed and enabled in its config folder and where its marketplace comes from; the Claude Codes running with it now (project, working / waiting / idle, every 3 seconds); and the sessions of this project in its folder (how many, when the last was written and its title, and how many went on in another account ⇢ or came from one ⇠). The rest is read again every 30 seconds and with F5.
Enter (or a double click) on an account opens a menu (↵ actions…, What to do in ?, its head the account and the head of the viewer's session), the same in the Account group of the Settings view:
- Continue it in …: the viewer's session goes on in that account, as the same option in the Sessions view does (asking first; the session and the viewer stay as they are). Greyed out on the active account and without a session to continue (a viewer that follows no Claude Code, or one of
--session), with the reason. - Start a new session there: a new Claude Code under that account, in this project's folder, in a new window (
claude --session-id <new id>throughcco claude --config-dir), which opens a viewer of its own there; this viewer stays. - Open its config folder in the file manager.
Both ways of starting install the cco plugin there first if it lacks it (if that fails, Esc asks whether to go on without it). Without Windows Terminal or tmux, a dialog gives the command to run (c copies it). Space marks an account ★ (for all projects), Ctrl+F filters, and the list keeps its selection and scroll positions; its width is the setting accounts list width. The account entries and settings stay in the Settings view as well.
Adding an account. How to add an account (here and in Settings › Account) explains it: Claude Code keeps login, sessions, settings and plugins in one config folder (~/.claude, or the one CLAUDE_CONFIG_DIR names), so a second account is a second folder ~/.claude-<name> with a start script that sets the variable; how to write that script by hand for cmd and PowerShell (cw.cmd), Git Bash and Linux/macOS (cw), and how to add cco there. Enter on it does it: a dialog asks for the command (e.g. cw) and the folder (.claude-cw, following the command until edited), checks the command's name, then creates the folder, writes the start scripts next to claude on the PATH (on Windows cw.cmd and a Bash script cw; elsewhere cw, executable), installs the cco plugin there and gives it cco's settings, and runs the script in a new window, where you sign in with /login; the account then shows up (within 30 seconds, or with F5). A name a shell would run something else for is refused with the reason: PowerShell aliases win over files on the PATH (cp runs Copy-Item, not cp.cmd; also sc, r, h, where, …; PowerShell is asked for its aliases, your profile's included), as do the built-ins of cmd (copy, dir, start, …) and Bash (test, type, …) and a program of the same name on the PATH; so are an existing script and a folder that is signed in already. An existing folder without an account is used after a second Enter. Without Windows Terminal or tmux, the dialog says to run the command yourself (c copies it). With accounts view off, 0, the click on the "cco" and Tab no longer reach the view (the "cco" stays, in its colour); /cco:accounts still opens it.
Deleting an account. d on an account (here and in Settings › Account), or Move this account to the trash… at the end of its Enter menu, below a red Danger zone line, moves it to the trash: its config folder and the start scripts that set CLAUDE_CONFIG_DIR to it (in the folder next to claude and in ~/.local/bin). It asks twice: first with what moves (email, folder, sessions, size, scripts), then for the folder's name typed in (.claude-cw). The default ~/.claude and the active account can't be deleted, nor an account a Claude Code or a cco viewer runs with; on Windows a folder a process holds a file in can't be moved either, and then nothing has moved. u right after brings it back. T shows the accounts trash (~/.claude/cco/trash/accounts/, the same for the viewers of every account; /cco:accounts and T while the view is off): u restores an account (refused while its folder or a script exists again), x deletes it for good and X empties the trash, both after the same two questions (for X, type delete). Its mark goes with it then; the ⇢/⇠ notes of sessions continued from or to it stay.
Settings view
The Settings view (6, or /cco:settings) lists every option under a line with its group (── Chat ──), with its value at the right end of the row; a name too long for the list is cut, never the value. The preview shows what it does, all possible values (the current one marked ●, the default named) and the key that switches it in its own view. Values that differ from the default are yellow, and the top bar counts them.
| Setting | Values | Default | Also |
|---|---|---|---|
| Start: auto open | remember / always / never | always | – |
| Start: placement | right / left / window | right | p in any view |
| General: confirm quit | on / off | on | – |
| General: compact (layout for small screens) | off / single / stacked | off | – |
| General: compact columns (stacked list) | 1 / 2 / 3 / 4 | 2 | < > with compact stacked |
| General: compact split (stacked list height) | 10% / 20% / 30% / 40% / 50% | 20% | – |
| General: marquee (long list entries scroll) | on / off | on | – |
| General: date separators (a line per day in lists) | on / off | on | – |
| General: pinned favorites (marked entries at the top) | on / off | off | – |
| General: remember positions (across restarts) | on / off | on | – |
| General: view per session | on / off | on | – |
| General: mouse | on / off | on | – |
| General: update | on / off / auto | auto | – |
| Account: colour in the top bar | auto / off / one of 16 colours | auto | – |
| Account: avatar | cco / one of 24 / your own (up to 6 columns) | cco | – |
| Account: avatar in the title | on / off | on | – |
| Account: accounts view | on / off | on | – |
| Account: accounts list width | hidden / narrow / normal / wide / wider / full | normal | < > | in Accounts |
| Account: accounts order | email / folder / recent | s in Accounts | |
| Chat: tab | on / off | on | – |
| Chat: list width | hidden / narrow / normal / wide / wider / full | normal | < > | in Chat |
| Chat: tool calls | off / compact / full | off | t in Chat |
| Chat: thinking | on / off | off | h in Chat |
| Chat: agents | on / off | on | – |
| Chat: wrap | on / off | on | w in Chat |
| Chat: order | oldest first / newest first | oldest first | s in Chat |
| Changes: tab | on / off | on | – |
| Changes: list width | hidden / narrow / normal / wide / wider / full | normal | < > | in Changes |
| Changes: wrap | on / off | on | w in Changes |
| Changes: sub-repositories | on / off | on | – |
| Plan: tab | on / off | on | – |
| Plan: list width | hidden / narrow / normal / wide / wider / full | normal | < > | in Plan |
| Plan: wrap | on / off | on | w in Plan |
| Plan: order | oldest first / newest first | oldest first | s in Plan |
| Sessions: tab | on / off | on | – |
| Sessions: list width | hidden / narrow / normal / wide / wider / full | normal | < > | in Sessions |
| Sessions: folders | this / other / all | this | a in Sessions |
| Sessions: accounts | current / all / those checked | current | a in Sessions |
| Sessions: background | show / hide | show | a in Sessions |
| Sessions: remote (with remote API) | show / hide | show | a in Sessions |
| Sessions: remote API (experimental) | on / off | off | – |
| Sessions: pinned sessions (active and running ones at the top) | on / off | on | – |
| Sessions: range | today / 7 days / 30 days / 90 days / unlimited | 7 days | – |
| Monitor: tab | on / off | on | – |
| Monitor: list width | hidden / narrow / normal / wide / wider / full | normal | < > | in Monitor |
| Monitor: range | today / 7 days / 30 days / 90 days / unlimited | 7 days | – |
| Settings: list width | hidden / narrow / normal / wide / wider / full | normal | < > | in Settings |
What they do:
- auto open decides whether the viewer opens by itself when Claude Code starts: only if it was open when Claude Code last exited in the project (
remember), on every start in every project (always), or never (never). See Opening on start. - placement is where the viewer opens for sessions that have no place of their own: docked right or left of Claude Code, or in a window.
pin the viewer moves it and remembers the place for the session (see Usage). - confirm quit makes
qask before the viewer closes, andrand restart the viewer in the Reset group ask before it restarts. - compact
singleis for a small screen or a narrow pane: one column that shows the list, andEnter(a detail) or|(in every view) shows the preview over the whole pane,Escor|goes back. The help line, the status and the version are left out (ilists the keys), the tabs are shortened to their number and the preview's header takes one line.<and>do nothing then; the list widths you chose apply again withoff.stackedshows the list above the preview, both as wide as the pane, with a rule between them; the list takes compact split of the height (10% to 50%) and has compact columns columns, filled one after the other like a newspaper, which<and>change (up to four). Everything else ofsingleapplies too, except that nothing opens over the pane and|does nothing. - marquee lets the selected list entry scroll when it is too long; off, it is cut with
…like the others. - date separators puts a line with the date above each day's entries in Chat, Plan, Sessions and the trash, and one per year in the Monitor; off, Sessions and the trash show the date in each row again.
- pinned favorites moves the marked entries of every list (Chat, Changes, Plan, Sessions, Monitor, Settings) once more to the top, under
── ★ Pinned ──, in the list's order, above the whole list; see Lists. - pinned sessions puts the active and running sessions into that group in the Sessions view too, also while pinned favorites is off.
- remember positions keeps the selected entries and scroll positions across restarts of the viewer; off, they are kept only while it runs.
- mouse lets the viewer take the mouse: a click on a web address in the preview opens it in the browser, a click in a list selects the entry, a double click does what
Enterdoes, and the wheel scrolls the preview or, over the list, moves to the previous or next entry. While it is on, the terminal leaves clicks and drags to the viewer: a drag in the preview selects and copies its text, andShift+drag selects the terminal's way (Windows Terminal). Off, the terminal keeps the mouse and opens addresses withCtrl+click. - view per session brings each session back in the view it was shown in last (Chat, Changes, Plan, Sessions or Settings): when Claude Code starts or resumes it, when you start
ccowithout--view, and when the viewer follows it after/resume. A/cco:…command still opens the view it names. Off, the viewer starts in the chat, or on start in the view shown last in the project. Kept per project in~/.claude/cco/<project-slug>.views.json. - tab (the first entry of each view's group) hides a view you do not use: a hidden view has no tab, and its number key does nothing; the other views keep their numbers. A
/cco:…command or--viewthat names it still opens it, with its tab shown while it is open. On start, a remembered view that is hidden is replaced by the first shown one. Settings cannot be hidden, and at least one other view stays shown. - list width (in each view's group, Settings' own included) sets how wide the list is next to the preview:
narrow20 % of the pane (16–30 columns),normal30 % (20–40),wide40 % (24–60),wider50 % (30–80). The preview keeps at least 20 columns. At the ends,hiddenfolds the list away and the preview takes the whole pane,fullspreads the list over the whole pane without a preview.<and>in a view step one width at a time,|goes to an end and back (see Folding the list); every change is stored here, the ends too, so a view starts as you left it. The preview says the new width for a moment. - update asks npm for the latest version and GitHub for the release notes when the viewer starts (see Releases below).
autodoes the same and, as soon as that check finds a newer version, opens update to v… in Settings and asks whether to install it. Off, the viewer makes no network requests;F5in Settings still checks once. - Account (after General) is for people who run Claude Code with several accounts, e.g.
claude-workandclaude-persothat setCLAUDE_CONFIG_DIR. cco looks for accounts in~/.claude*: a folder counts when its.claude.jsonnames a signed-in account. The "cco" at the left of the top bar gets the account's colour as its background (colour in the top bar:auto,offor one of the console's 16 colours, which look as in the terminal's colour scheme), whatever the number of accounts. avatar puts up to six columns of letters, symbols or emojis there instead of the "cco":Enteropens a list of 24 (eight ASCII ones like(^_^)and=^.^=, eight emojis like 🦊 and 🚀, eight combinations like ☕💻 and 🐙🌊🐚), each with what it shows, and a field for your own (Win+.opens the emoji panel on Windows,Ctrl+Cmd+Spaceon macOS). The avatar also stands in the account's entries, before its sessions in the Sessions view (with the other accounts listed) and at the end of the terminal title (avatar in the title:✳ orders · 🦊). Like the colour it is stored in the folder's own settings and read from there by the other accounts' viewers.autotakes the colour from the email (red, green, yellow, magenta, cyan or a bright one of them, never blue like the focus bar); a fixed colour is for the account of the viewer's own config folder and is stored in that folder's settings, where the viewers of the other accounts read it too, so each account shows in its own colour everywhere. The group has one entry per account found (● email (folder);●marks the active one, the account of the Claude Code the viewer follows) with its email, name, organization, plan and folder in the preview, then its three settings, those of the Accounts view (accounts view, accounts list width, accounts order), and last how the accounts were found and how to add one.don an account moves it to the trash (see Deleting an account in the Accounts view),ubrings it back. - The other Chat, Changes, Plan, Sessions and Monitor settings are the same as the keys in those views; switching them there changes them here, and the other way round.
Keys:
↑/↓select a setting,Enterswitches to the next value. A change applies right away in all views.Spacemarks a setting or a reset entry★like in every list,Shift+↑/↓jump between them.rsets the selected setting back to its default,Rresets all of them and removes the marks of the settings, after a confirmation.- Releases, the last group, below Reset, lists every release of cco with its notes, newest first; the installed one is marked
installed, newer onesnew./cco:releasesopens the viewer here, and a click on the top bar's update does too. The viewer asks npm and GitHub once when it starts (setting update),F5asks again, and the answer is kept in~/.claude/cco/releases.jsonfor offline use.- When a newer version is out, the first entry is update to v…: its details show the notes of every newer release.
Enterasks, then runsnpm install -g cc-outline@latest,claude plugin marketplace update cc-outlineandclaude plugin update cco@cc-outline, showing each step and its output. When all succeed, the viewer opens again in the same place and view with the new version, and says once that Claude Code needs a restart for the plugin. A dialog then shows the notes of every version since the one you ran before, skipped versions included (↑↓/PgUp/PgDnscroll,EnterorEsccloses); it also comes after an update by hand, once per new version. If a step fails, the update stops there and shows its output;ccopies the commands still to run. - Another viewer that is still on the old version offers restart with v… instead, which only reopens it.
- A cco run from a checkout (
npm link) or through npx is not updated: the entry only says that a new version is out.
- When a newer version is out, the first entry is update to v…: its details show the notes of every newer release.
- Reset, below the settings (above Releases), has five entries;
Entershows what would change and asks first:- restart the viewer closes the viewer and opens it again in the same place and view, with the version of cco installed now (after
npm install -gby hand, or a rebuild of a linked checkout).rdoes the same in every view but Settings. It asks first, unless confirm quit is off; a dialog then saysRestarting…for a second./cco:restartdoes the same from Claude Code, without asking. If the viewer cannot reopen itself, the dialog says so; close it withqand open it again. The plugin's hooks and commands change only when Claude Code restarts. - doctor: check and repair runs
cco doctor(see Usage):Enteror a double click asks, then checks one area after the other (Checking Installation…,Checking State files…, the areas done with their mark) and shows the report; nothing is checked before. If it found something to repair,Enterlists the repairs and asks, then runs them one by one with their output, and checks again.F5checks again once it has checked; without anything to repair,Enterdoes. - Ctrl+G: cco's prompt editor sets
VISUALin theenvof Claude Code'ssettings.jsontocco edit(the file before is kept assettings.json.cco-backup), or takes it out again and puts back what was there; see Prompt editor. Claude Code reads it when it starts. - all settings to default, the same as
R, which also removes the marks★of the settings. - saved data of this project deletes what cco remembers for the project: the marks
★of every list, the selected entries and scroll positions, the view and placement of each session, and whether the viewer was open at the last exit. The settings stay, and transcripts, sessions and git are not touched. The views reload empty.
- restart the viewer closes the viewer and opens it again in the same place and view, with the version of cco installed now (after
- Settings are global, for all projects, in
~/.claude/cco/settings.json; a viewer of one session keeps some of its own insettings.session-viewer.jsonnext to it. auto open takes effect at the next start of Claude Code, remember positions at the next start of the viewer.
Prompt editor
Claude Code's prompt line is small for a long prompt, and on Windows an image from the clipboard often does not get in (Windows Terminal takes Ctrl+V for itself; images from the Snipping Tool, a browser or a file copied in Explorer fail now and then). e in the viewer opens cco's prompt editor over the whole pane:
- Write as in Notepad:
Enterstarts a new line,↑/↓,PgUp/PgDn,Home/End(Ctrlfor the whole text),Ctrl+←/→by word. Alt+Vtakes the clipboard's image: a screenshot (Snipping Tool), an image copied in the browser, or image files copied in Explorer. A paste that brings no text (Ctrl+Vwith only an image in the clipboard) does the same. Each image is saved in~/.claude/cco/imagesand shows as[Image #1]in the text;Backspaceright after it takes the whole placeholder.Tabgoes to the image list (number, pixels, size, where it came from, time;Enteropens one,dremoves it with its placeholder) and to the button.Ctrl+Enter,Ctrl+Sor the button[ Hand over to Claude ]hand the prompt over: each placeholder becomes the image's path in quotes, which Claude reads, and the text is typed into Claude Code's prompt line (Windows: its console, tmux: its pane; line breaks asCtrl+J). Nothing is sent:Enterin Claude Code does that. Where the viewer types into no Claude Code (a viewer of one session, no Windows Terminal or tmux), the text is copied instead. In tmux,Ctrl+Enteronly arrives withextended-keyson;Ctrl+Salways does.Esccloses it and keeps the draft, per session in~/.claude/cco/drafts, also across restarts; the nextebrings it back. A prompt handed over clears it. Images and drafts are deleted 30 days after they were last written.
With Ctrl+G: cco's prompt editor set up in Settings (Reset), Ctrl+G in Claude Code opens the same editor: in the viewer next to it (docked in Windows Terminal, or in tmux), which takes the focus and gives it back, else in Claude Code's own pane. What is in Claude Code's prompt line then comes along (its image paths become placeholders again), and the prompt goes back into the prompt line. cco doctor says what Ctrl+G opens.
Keys
The help line lists the keys of the current view. Options that are on (f follow, t tools, w wrap) and open detail views (↵ prompt, ↵ file, ↵ changes) are highlighted. If the pane is too narrow for all keys, the least important ones are left out, and i more points to the info dialog, which lists every key. i and q are always shown, and so are options that are on. The keys of the Settings view are listed in its section.
| Key | Chat | Changes | Plan | Sessions |
|---|---|---|---|---|
0 – 6 | switch view (0: Accounts) | switch view | switch view | switch view |
Tab / Shift+Tab, → / ← | next / previous view | next / previous view | next / previous view | next / previous view |
↑ / ↓ | previous / next turn | previous / next file | previous / next plan | previous / next session |
Home / End, g / G | first / last turn (End and G resume follow mode) | first / last file | first / last plan (End and G resume following) | first / last session |
Space | mark the turn ★ | mark the file ★ | mark the plan ★ | mark the session ★ |
Shift+↑ / Shift+↓ | previous / next marked turn | previous / next marked file | previous / next marked plan | previous / next marked session |
Ctrl+F | filter the turns; again: drop the filter | filter the files | filter the plans | filter the sessions (not the trash) |
PgUp / PgDn | scroll by page | scroll by page | scroll by page | scroll by page |
Ctrl+↑ / Ctrl+↓ | scroll by line | scroll by line | scroll by line | scroll by line |
Ctrl+Home | top of the answer | top of the diff | top of the plan | top of the details |
Ctrl+End | bottom of the answer; on the newest turn also resume follow mode | bottom of the diff | bottom of the plan | bottom of the details |
Enter (also: double click) | full prompt ↔ answer | open the file in the app the system uses for it | plan ↔ changes to the previous version | what to do with the session: switch to its tab, attach the viewer, resume it here or in a new window, detach, move it here, rename, export, import, open its folder (a dialog) |
Esc | close the full prompt | close the whole file | close the changes | leave the trash |
f | toggle follow mode | – | – | – |
t / h | tool calls off / compact / full; thinking | – | – | – |
o | list the turn's attachments (pasted images, @ files, tool images and PDFs) to open one | – | – | list the session's attachments to open one |
Ctrl+Enter | – | whole file ↔ diff | – | – |
a / A | next / previous subagent of the turn, past the last / first back to the answer (Esc back) | – | – | – |
c | copy the turn's Markdown | – | copy the plan | copy the resume command |
d / Del | – | – | – | move the session to the trash |
u | – | – | – | undo the last move; in the trash: restore |
T | – | – | – | show / leave the trash |
a | – | – | – | the filter: folders, accounts, background and remote sessions (a dialog) |
x / X | – | – | – | in the trash: delete for good / empty the trash |
] / [ | – | next / previous hunk (changed block in whole-file mode) | – | – |
w | toggle wrapping | toggle wrapping | toggle wrapping | – |
s | newest / oldest first | – | newest / oldest first | – |
Ctrl+← / Ctrl+→ | scroll sideways (wrapping off) | scroll sideways (wrapping off) | scroll sideways (wrapping off) | – |
F5 / Ctrl+R | reload the view (see below) | reload the view | reload the view | reload the view |
< / > | list narrower / wider (setting list width), past the ends folded away / over the pane | list narrower / wider | list narrower / wider | list narrower / wider |
| | list folded away or over the pane, and back (see below) | list folded away or over the pane | list folded away or over the pane | list folded away or over the pane |
p | move the viewer: right, left or own window | move the viewer | move the viewer | move the viewer |
e | write a prompt in the prompt editor | write a prompt | write a prompt | write a prompt |
r | restart the viewer, with the version installed now (not in Settings, where it resets the selected setting) | restart the viewer | restart the viewer | restart the viewer |
i | info dialog | info dialog | info dialog | info dialog |
q | quit | quit | quit | quit |
Folding the list. | folds the shown view's list away, so the preview takes the whole pane, and on the next press brings it back at its width; the press after that spreads the list over the whole pane, without a preview, and the next brings it back again, and so on. < and > reach the same two ends one step past narrow and wider, and step back out of them. Selection and scroll positions stay. The ends are stored as the list width hidden and full, so a view starts folded or spread as you left it; after such a restart the width before is not known, and | goes from hidden to narrow and from full to wider. Which end | takes next is not stored: after a restart it first folds the list away. With the list over the pane, Enter (and a in Chat) shows the detail it opens over the whole pane, the full prompt, the whole file, the plan's changes or the Monitor's table, and Esc goes back to the list; in Sessions and Settings, Enter does what it always does.
Reloading. F5 (or Ctrl+R, for terminals that keep F5 to themselves) reads the shown view's data again from scratch and redraws the screen, in every view: the Chat and Plan views the transcript (both, since they share it), the subagent shown and the plan file; Changes git; Sessions and Monitor all transcripts; Settings settings.json, with changes made by other viewers. Marks are read again too. The selection, scroll positions and open details stay; a list filter is dropped. The top bar says reloading… until the data is there, then reloaded. While a dialog is open, F5 does nothing.
Quitting with q, and restarting from the Settings view, asks first, unless confirm quit is off in the Settings view. Esc never quits: it closes what is open (a detail, the trash, a dialog) and otherwise does nothing. In this and every other confirmation, Enter means yes and Esc means no. When the session ends, the viewer still closes without asking.
What you start and then wait for (the update, the doctor's check and repairs, export, import, attaching to a Claude Code started for it, the restart) shows in the same progress dialog: its title names the run, a spinner line says what runs now (Updating – marketplace (2/3)…), and a mark replaces the spinner at the end, ✓ in green or ✗ in red. Only waiting for a Claude Code to attach to can be cancelled (Esc). A dialog that ends with a result only it shows (export, import) or with a failure stays until Esc; c copies the commands left to run, where there are some.
t, h, w and a are saved globally for all projects in ~/.claude/cco/settings.json, like everything in the Settings view. Each view keeps its own w setting.
Info dialog
i opens a dialog centred over the view. It shows:
- the version, the author and the license
- the project directory, the session id and its transcript file
- the git repository root
- the terminal and the key that switches panes
- the settings file
- the keys of the current view
←, → or Tab switch to its second page, Legend: what the marks of the current view's list mean (★ marked, ↳ queued, ✓ approved, M modified, …), two to a line. The dialog always opens on the keys.
The dialog is modal: the view underneath takes no keys until you close it with i or Esc.
Focus
The viewer shows whether it or Claude Code has the keyboard focus:
| Focused | Not focused | |
|---|---|---|
| Top bar | blue background, or the session's colour | dimmed; a session colour stays, darker |
| Selected list entry | inverted | gray background |
| Help line | starts with alt+← (back to Claude Code), then the keys | only alt+→ focus cco |
A session with a colour set with /color in Claude Code (red, orange, yellow, green, cyan, blue, purple, pink) colours the top bar with a dark shade of it, so you can tell sessions apart at a glance; without one the bar stays as it is.
alt+←/→ is Windows Terminal's default for moving between panes; under tmux the help line shows ctrl+b ←/→. The focus comes from the terminal's focus events (ESC[?1004h). tmux needs set -g focus-events on. Some terminals send no focus events (Windows Terminal 1.12, for example); there the viewer counts a key or click in it as focus, and a prompt you send in Claude Code as focus back in Claude Code. Switching with alt+←/→ alone shows only after that.
How it works
-
Reading sessions. Claude Code stores every session as JSONL in
~/.claude/projects/<project-slug>/<session-id>.jsonl. cc-outline reads this file incrementally and groups it into turns. -
Tracking the session. The plugin hooks (
SessionStart,UserPromptSubmit,SessionEnd) runcco hook, which records the session of each Claude Code process in~/.claude/cco/<project-slug>.claude-<pid>.json. A viewer opened with/cco:…belongs to the Claude Code it was opened from and follows only that one, also through/clearand/resume. Other sessions in the same project, for example one started from the Sessions view, don't affect it. -
Closing with the session. When its session ends or its Claude Code process is gone, the viewer closes itself. After
/clearit continues with the new session instead. -
Opening on start. The auto open setting decides what happens when Claude Code starts, also with
--resumeand--continue:remember: if the viewer was open when Claude Code last exited in this project, it reopens in the view it last showed. If it was closed, it stays closed.always(default): the viewer opens on every start, in every project, even in one it never ran in; in the chat, or in the view it showed last in the project.never: it only opens through a/cco:…command.
It opens in the view the session was shown in last (view per session), for a new session in the view shown last in the project. The focus stays in Claude Code, and no second viewer is opened for a Claude Code that already has one. Each Claude Code gets its own, also a session started from the Sessions view in its new window.
-
Without hooks, the viewer uses the project's most recently modified transcript that contains messages.
-
Drawing. The viewer writes only the lines that changed, each in place and all in one write, so the pane does not flicker when the machine is busy. Should a terminal show garbled lines, start the viewer with
CCO_FRAME_BUFFER=0to let it redraw the whole screen every time instead.
Development
npm run dev # tsup --watch
npm test # vitest
npm run typecheck
npm run demo # re-record docs/demo.gif, chat.svg, changes.svg, plan.svg, sessions.svg and monitor.svg
npm run demo:compact # re-record docs/compact.gif (the compact view in a narrow pane)
npm run demo:rc-viewer # re-record docs/rc-viewer.gif (the Remote Control Viewer)
The demo runs the viewer headlessly on a made-up project with a few older sessions, also of a second project, and a month of responses for the Monitor (demo/fixture.mjs), plays a key script and writes the screens as SVG stills and an animated GIF (rendered with headless Chrome; set CHROME if it is not found). The Claude Code pane in it is a simplified stand-in (demo/claude-mock.mjs). demo/social-preview.html turns docs/chat.svg into the 1280×640 image GitHub shows when the repository is shared (docs/social-preview.png).
cco runs the built dist/cli.js. After a rebuild, close a running viewer with q and reopen it. Changes to the plugin (hooks, commands) take effect only after Claude Code restarts.
Releases are published to npm by GitHub Actions when a GitHub release is published, with npm provenance, so each version on npm links to the commit and workflow run it was built from.
License
MIT © 2026 Jan Hoppe
cc-outline is an independent community tool. It is not affiliated with or endorsed by Anthropic. Claude and Claude Code are trademarks of Anthropic.