A vibecoded, native GTK4/libadwaita agentic development environment to manage, orchestrate and complement all your Claude Code sessions.
My wife keeps referring to Claude as Collins by mistake. So now when she asks me if I'm talking to Collins, I can say yes.
Collins is a fork of agent-session-manager by Máté Molnár (original project website) — all credit for the original app goes there. This fork is GPL-3.0 like the original.
Unofficial community tool. An independent community project, not affiliated with or endorsed by any agent vendor (including Anthropic). It never modifies your agents' own session data — all app state lives in its own config file. Fair warning: this app is entirely vibecoded — the code is written by Claude Code.
Features:
-
Sidebar lists every session found on disk (for Claude Code, under
~/.claude/projects/), grouped by project (click a project header to start a new session there; the strip left of its title — icon included, shown as a caret under the pointer — folds and unfolds the group, ←/→ on a focused header do too, and the sidebar header has a collapse-all/expand-all toggle), with a Favorites section pinned on top — star a session to move it there. Drag a project header to rearrange projects — the order and each project's expanded state persist across restarts. The search button opens a search box across the sidebar header that filters by name, project, preview, or session id, and the list updates live as sessions are created or written to. -
Sessions can be given custom names (right-click → Rename…, or rename the session's tab), and unnamed sessions get an auto-generated title: pre-existing sessions are titled locally on launch (first 10 words of the initial prompt), while sessions created during an app run have their first prompt summarized to ≤5 words by a headless
claude -prun (the model is a Preferences setting, defaulting to the newest Haiku, with a None option that turns the model runs off) — the same CLI and login the whole app is based on, no extra credentials needed. A prompt that only points at a pull request ("review PR 183") would summarize to a number nobody can read at a glance, so that PR's title is fetched withghand handed to the model as quoted context — flagged as untrusted data, with any instruction inside it to be ignored. Titles are persisted so each is generated only once; right-click → Regenerate name re-runs the model for one session — the item names the model it will run, and it works under None too, on the automatic default (a manual rename always wins). Names, favorites, and archived sessions persist in~/.config/collins/state.json— your agents' own session files are never modified. -
Clicking a session opens a tab in the main area; each tab is an embedded VTE terminal running your
$SHELLwith the agent's resume command (claude --resume <session-id>for Claude Code) typed into it, in the directory the session last worked in (worktree-aware). If the session is still running detached, Collins re-attaches to the live process (claude attach) instead of resuming a copy. When the agent exits you drop to a shell prompt; the tab closes when the shell exits. Closing a tab asks the agent to exit cleanly (Claude Code'sCtrl+CCtrl+C, which works from whatever screen the agent is on) in the background first — or, for agents that support it, the close dialog offers to background the session instead (Claude Code's/bg), leaving it running detached to re-attach to later. On the next launch the window comes back at its last size — and with Reopen the last session on (Preferences → Session behavior), with the session you had focused when you closed it. -
In-terminal search with a find bar (
Ctrl+Shift+G) over the tab's scrollback. -
Terminal panel (
Ctrl+J, or the small buttons in the window's bottom-right corner): every tab has a second plain-shell terminal — no agent auto-launched — below or beside the agent terminal. It opens in the agent's current working directory (worktree-aware), and the rotate button in the panel's tab row — orCtrl+;— moves the tab you're in bottom↔right without restarting its shell. The overlay button beside it floats that tab over the whole session tab — agent terminal, other panels and editor alike — until the restore button in its top-left puts it back where it was. Each layout's panel size is remembered per tab while the app runs, and the last-set size per layout is saved app-wide, so every panel opened from then on defaults to it. Right-clicking the terminal button opens that same directory in your desktop's own terminal instead, in a window of its own. Typingexitin it hides the panel; the last-used position (bottom/right) is remembered app-wide, and whichever panel you open next defaults to it. Closing a tab while a command is running in its panel — even a hidden one — asks for confirmation before the command is killed. Closing the whole window with busy sessions shows a single confirmation — close (every agent is asked to exit cleanly), background the sessions (/bg), or keep running (hide the window) — before the window goes away. -
Pull requests, tracked and acted on: every PR a session opens shows up as a mark on its sidebar row and chips in its tab footer — GitHub's own iconography, carrying the least settled state (draft/open/merged/closed) and the loudest thing left to do (red CI or conflicts, comments waiting on a reply, checks still running, all green). Click through to an in-app PR page beside the terminal, or right-click for the actions: mark ready for review, merge (or arm auto-merge), ask Claude for a review — and send red CI, conflicts, or unanswered comments back to the session as a prompt. Status refreshes on demand, at launch, and the moment a session's run finishes. All of it runs on the GitHub CLI (
gh). -
Git page (
F6, the footer's git button, or a click on its branch label): the session's diffs beside its terminal, drawn by Collins itself, with a native sidebar to the left. The diff: a card per file (renames, new, deleted, untracked, binary, too-large and mode changes named), one syntax-highlighted view per hunk in the editor's style scheme and font, split or stacked (automatic by width), word-level emphasis, expandable gaps, before/after pictures for images, a pinned file header, a find bar (Ctrl+F) across hunks, a files filter (/), and page-local navigation keys (][.,jkz012lwreq?) that never reach the agent's terminal. The sidebar: a commits list (the current branch's commits, then every branch of the stack under it — git's word on what stacks on what — down to the default branch's, unpushed ones marked↑; a click loads that commit or branch into the same page, the loaded row wears▸), a files list that splits into Unstaged and Staged on the working tree and follows the view, and an action row: stage all, unstage all, commit (with a body), fix up an unpushed commit. Staging in the diff itself: every file and hunk header carries its buttons — Stage file / Discard file, Stage hunk / Discard hunk, Unstage … on the index, Revert … on a commit or branch — and a line selection (drag in the text or on the line numbers,Shift+arrows) turns them into Stage lines / Discard lines / Revert lines;x/X/Dpress the same, a discard confirms first (a revert does not: its result is unstaged, a discard away), a files-list row on a commit offers Revert file on a right-click, an untracked file's discard goes to the trash, and a file that changed under the view is refused and reloaded. Notes go on the diff:copens a card under the focused hunk anchored to the cursor line (Ctrl+Entersaves,Esccancels),Eedits it,}/{walk the annotated hunks, and the cards say who wrote them — you, or the agent, whose notes and highlights the next release's tools land andafolds away.Ctrl+1/Ctrl+2/Ctrl+3jump to the unstaged, staged and whole-branch diffs; the sidebar folds below about 680 px and on the header's panel button; edits reload through file monitors, and the page reloads by itself when the index orHEADmoves (the agent stages, commits, rebases). -
Editor panel (
F8): a syntax-highlighted code editor beside the agent terminal — file tree, quick open (Ctrl+Shift+O), and an Agent files list of what the session most recently wrote, one click from the change it just made. External changes reload cleanly (the agent is rewriting these files, after all), the editor follows the session into worktrees, it shows one column at a time when the panel is narrow, and it can pop out to a window on a second monitor. -
Prompt composer: a multi-line, spell-checked text box floating over the agent terminal for prompts that outgrow one line — start typing at an empty prompt and it opens with what you typed (the CLI's
/,!,#and@keep their keys),Ctrl+.toggles it, closing puts the draft back in the agent's input box, and dropped or pasted images ride along as attachments. Floating or docked below the terminal. Drafts wait for you: a prompt you haven't sent yet belongs to its session, not to the process — close the tab, quit Collins, come back a week later, and it's back in the composer the next time you open it, where the bare CLI forgets anything typed-but-unsent the moment it exits. A new session's first prompt is written in the same box, on a new-chat screen that stays in the sidebar as a Draft row until you send it. -
In-app notifications: when a session that isn't the one on screen wants you — a
notify_usermessage, a terminal bell, or (if you ask) a finished run — a card slides in at the top-right of the window with the project's icon, the session's name and the message, and the notification sound plays (the desktop's own, one of its other sounds, one of five public-domain chimes Collins ships, or a file you pick). Click it to go there. Away from Collins the same thing is a desktop notification titled with the session. A newer Collins arrives the same way: once a day the app asks GitHub for the latest release (through yourghlogin when it has one, anonymously otherwise) and, when one is newer, says so once — a card, or a desktop notification — whose click opens the release page; Check for updates in Preferences turns the check off. -
Status icon & close-to-hide: a status icon in the top bar whose menu jumps to any open session, wearing an unread badge counting unread notifications — every finished run nobody has looked at yet, and every message and bell nobody has gone to — the same number the bell in the header bar wears, which opens a notification history of every finished run, message and bell waiting for you — and pouring the sidebar's barber pole into its glass while any session works — with the drink in the glass only while something is unread, so an empty glass means nothing running and nothing waiting. Closing the window can hide it instead — every session keeps running, and the icon, a notification, or a relaunch brings the window back. (StatusNotifierItem; GNOME needs an AppIndicator extension.)
-
Caffeine Mode: the header's coffee cup keeps the machine awake while agents work — armed at every launch by default — by timer, indefinitely, or until idle: as long as any open tab is working the machine stays up, and five minutes after the last one stops it dozes, re-arming when work resumes.
-
Easy copy & paste (on by default): plain
Ctrl+Ccopies whenever text is selected — otherwise it interrupts the agent as usual — plainCtrl+Vpastes, and right-click opens a Copy / Paste / Select All menu. NoCtrl+Shiftfinger-twisting just because it's a terminal (Ctrl+Shift+C/Ctrl+Shift+Vstill work, and the mode can be turned off in Preferences). -
Live sessions stand out: a session with a tab open gets a fill in the sidebar, whether or not you're caught up on its output (a tab with unread output is marked by the tab bar itself). A session running detached (
/bg) gets a yellow guide line and no fill — there's no tab to return to until you reopen it. While an agent is actually working in a tab, its row's guide line becomes a moving blue barber pole that stops soon after the agent does, so the sidebar says which sessions are thinking and which are waiting on you. A red guide line marks a session you stopped mid-task, and stays red whether or not a tab is open. -
A Claude usage panel at the bottom of the sidebar shows your subscription limits (session, weekly, extra usage) as progress bars with reset countdowns — read straight from the
claudeCLI's own login, refreshed every 5 minutes (paused while the window is minimized or the screen is locked). An expired login quietly repairs itself — at launch, or when a poll finds the token dead under a running app — with one throwaway headlessclaude -prun, then re-fetches; Auto-renew the Claude login in Preferences → Token use turns that off, and the panel then says to runclaudeyourself. Toggle the panel in Preferences. -
Tabs follow the sidebar's order: left to right is the session list read top to bottom, whatever order you opened them in, and they re-arrange when the list does (drag a project to a new spot and its tabs move with it). Tabs with no row in the list — chats, replays — collect at the right-hand end; the tab bar itself isn't drag-reorderable, since the sidebar is where the order is set.
-
Tabs can be renamed, given an emoji prefix, or have their session ID copied (right-click → Rename… / Set emoji… / Copy session ID); renaming a session's tab updates its name everywhere. While a session tab is focused, header buttons exit or background it and close the tab immediately — no confirmation dialog — the tab bar is hidden by default — the window title names the active tab, and the header's toggle shows the bar for anyone who wants it, and the sidebar toggles with the header button or
F9. Shift+Enter inserts a newline in the agent's prompt. -
Each tab has a slim footer showing the agent's live working directory (click to copy; worktree-aware) and the current git branch (⎇; click to open the git page, right-click to copy), plus the terminal-panel, git-page and editor buttons.
-
Right-click a session for the full action set: open, open in Ghostty (external window — Ghostty can't be embedded), fork (
--fork-session), rename, regenerate name, favorite, details (messages/models/tokens, a peek at recent messages, and MCP servers/usage), copy session id, export as Markdown, reveal transcript, archive, move the transcript to trash, or delete permanently. Right-click a project header to start a new session there (in a new window, or with the worktree setting inverted), open its folder in another app, git pull it, check out its default branch, or archive the whole project (archiving a session in a git worktree first asks whether to move the worktree to the trash once the session has stopped, with Cancel leaving the session alone and the archive's Undo bringing the worktree back; a preference makes that always or never) — projects with no visible sessions still show their header (with a+button) so a folder stays reachable. The open-in list carries each app's own icon: one row per app added under Preferences → Footer apps, plus Open in File Manager and Open in Terminal using whatever your desktop nominates for those ($TERMINAL,xdg-terminals.list, and the system'sx-terminal-emulatorare honoured, in that order). -
Tools the session itself can call: every session Collins starts is offered a small MCP server of Collins' own (
collinsin its/mcplist), so the agent can drive the window it runs in —notify_user(a notification titled with the session — a card inside the window when you're in Collins, a desktop notification when you're not; it flashes the session's tab and row, flags the row until you come back, and clicking it raises that tab),set_session_title(the session names itself in the tab and sidebar),open_in_editor(put a file on your screen at a line, in the session's editor pane),show_diff(open the session's git page on the working tree, the index, the branch or a commit, and move it to a file and a line or hunk — the page comes up without taking your keyboard),diff_context(read the page back: the diff loaded, the hunk and lines you are on, every file's hunks, the patches and notes on request),annotate_diffandhighlight_diff(note cards under hunks and attention marks on ranges of lines, right in the diff you're reading),clear_diff_marks(take them off again),show_image(a screenshot or render in the in-app lightbox — a file, or anhttp(s)URL Collins fetches for it),attach_pr(put a pull request on the session's footer and sidebar row — for one Collins can't spot on its own, like a PR opened by a subagent),start_session(spawn a sibling session in a background tab, handed a prompt and inheriting the caller's model, effort level and permission mode unless told otherwise — it never steals your focus),read_terminal(read the terminal panel's tabs, scrollback and all), andrun_in_terminal(type a command into an idle panel shell and run it where you can watch). Each asks permission on first use, like any MCP tool, and each has its own on/off switch in Preferences → Built-in MCP tools (all on by default). -
Select mode (menu → Select multiple sessions) for bulk actions: open, star, archive, or trash many sessions at once.
-
Archived sessions can delete themselves: Preferences → Delete archived sessions after takes a number and a unit (days / weeks / months / years; 0, the default, never). Once a day, sessions archived at least that long ago have their transcripts moved to the system trash — the same recoverable trash as the manual Delete archived sessions…, with running sessions skipped and an emptied project kept as a sidebar header.
-
New session (tab icon in the header) starts a fresh agent session (
claude) in the visible session's project — no dialog needed; with no session visible it asks for a folder. Every project header also has a+button to start a session right there. The tab opens onto a new-chat screen — the project's icon and name over the composer, with a New git worktree checkbox and, in the composer's Send row, a model picker and an effort picker (each opening pre-selected on the CLI's own default — the model or level~/.claude/settings.jsonresolves it to, marked in the list and named on the button; a pick here is for this session alone) — and the agent starts when you Send the first prompt, on the model and at the effort level the pickers say (with nothing written, the button reads Empty Session and starts the agent with no prompt); a just-started session shows a "New Thread" placeholder row until the agent writes its transcript. A screen with text on it (or a terminal open beside it) is kept as a draft in the sidebar if you close the tab or quit, and comes back as you left it. -
Quick switcher (
Ctrl+K) jumps to any session by type-ahead; the sidebar is resizable and its width is remembered. -
MCP servers browser (menu → MCP servers): a read-only view of every MCP server configured in
~/.claude.json, global and per-project. -
Preferences (menu → Preferences, or
Ctrl+,): terminal font, scrollback, terminal color theme (Dracula, Solarized, Gruvbox, Nord, Catppuccin, Tokyo Night, Monokai, One Dark…), color scheme, language (English, Magyar, Deutsch, Español, Français), easy copy & paste, plus Show folder paths in sidebar and Show Claude usage toggles for the sidebar, a Token use group directly under General for everything that runs Claude on your behalf — the Session title model and Icon generation model pickers (each with a None option; it is the icon picker's default, under which the Generate Icon dialog waits for a pick and a click instead of running on open), an Auto-renew the Claude login switch for the background login repair, and the Model list row, which is free — followed by a switch per session tool, a Git group for the git page — the diff's Layout (automatic / split / stacked), Line numbers, Wrap long lines and Highlight changed words, Show untracked files, Commits per page, and a Default parent branch to measure branches against when no pull request names one — and a Check for updates switch for the once-a-day look at GitHub's latest release. A fresh install sees the Token use rows and the tool switches once before anything runs, in a Before you start dialog on its first launch — the same dialog that asks whereclaudeis when a desktop launch can't find it on itsPATH. -
A sidebar status footer shows session, project, transcript-size, and open-tab counts.
-
Continue last session (New Session menu): resume the most recent session in a folder (
claude --continue). -
Permanent delete sits alongside Move to trash;
Ctrl+Shift+Etoggles a 😊 marker on the current tab.
All rebindable from the sidebar menu → Keyboard Bindings. The defaults (the full list is in the docs):
| Shortcut | Action |
|---|---|
Ctrl+Shift+T |
New session |
Ctrl+Shift+N |
New window |
Ctrl+W |
Close the last-focused panel tab, then the session tab once none are left |
Ctrl+Q |
Quit |
Ctrl+PgUp / Ctrl+PgDn |
Previous / next tab |
Ctrl+C / Ctrl+V |
Copy selection / paste (easy copy & paste, on by default) |
Ctrl+Shift+C / Ctrl+Shift+V |
Copy / paste in terminal (always available) |
Ctrl+Shift+G |
Find in terminal |
Ctrl++ / Ctrl+- / Ctrl+0 |
Zoom the terminal in / out / back to normal |
Ctrl+K |
Quick switcher (jump to any session) |
Ctrl+Shift+E |
Toggle 😊 marker on the current tab |
Ctrl+Shift+A / Ctrl+Shift+Z |
Archive the current session / undo the last archive |
Ctrl+Shift+B |
Show/hide the notification history (the header bell's sheet) |
Ctrl+J |
Show/hide the terminal panel |
Ctrl+Shift+K |
Clear the terminal panel (screen and saved history) |
Ctrl+; |
Move the current panel tab to the panel's other side (bottom ↔ right) |
Ctrl+. |
Show/hide the composer (pressed while composing, it closes and puts the draft back in the agent's box) |
Ctrl+' |
Show/hide the attachments gallery (docked as a panel tab, it comes to the front instead) |
F6 |
Show/hide the git page |
F7 |
Open the page for the session's most recently linked pull request |
F8 |
Show/hide the editor panel |
Ctrl+Shift+O |
Quick open a file in the editor |
Ctrl+S (in the editor) |
Save the current file |
Ctrl+F (in the editor) |
Find in file |
Ctrl+F (in the git page) |
Find in the diff, across hunks |
F9 |
Toggle sidebar |
Ctrl+, |
Preferences |
Python ≥ 3.10, GTK ≥ 4.10, libadwaita ≥ 1.5, VTE (GTK 4 build), GtkSourceView 5, PyGObject, and markdown-it-py with linkify-it-py (the PR page's markdown parser) — all from your distro's packages. libspelling is optional: with it the prompt composer gets spell-check, without it the composer is a plain text box. GStreamer (the core typelib plus the base plugins) is optional too: with it Collins plays the notification sound, without it the desktop's beep stands in. The .deb and the .rpm only recommend those two.
# Ubuntu / Debian
sudo apt install python3-gi gir1.2-gtk-4.0 gir1.2-adw-1 gir1.2-vte-3.91 gir1.2-gtksource-5 python3-markdown-it python3-linkify-it gir1.2-spelling-1 gir1.2-gstreamer-1.0 gir1.2-gst-plugins-base-1.0
# Fedora
sudo dnf install python3-gobject gtk4 libadwaita vte291-gtk4 gtksourceview5 python3-markdown-it-py python3-linkify-it-py libspelling gstreamer1 gstreamer1-plugins-base
# Arch
sudo pacman -S python-gobject gtk4 libadwaita vte4 gtksourceview5 python-markdown-it-py python-linkify-it-py libspelling gstreamer gst-plugins-base-libsPlus the claude CLI on your PATH — Collins is a tool for Claude specifically.
Optional: the GitHub CLI (gh), signed in. It is what every pull request mark and every pull request action above runs on; without it a PR is a number and nothing else, so a launch that finds gh missing or signed out says so — showing what it's holding back, and pointing at the install or the one command that signs you in — until you set it up or tick Don't show this again.
The git page needs git alone — Collins draws the diffs itself.
From source:
git clone https://github.com/episode6/collins.git
cd collins
python3 -m collinsOr install the desktop launcher + icon (shows up in the app grid as "Collins"):
./data/install.shPyPI — pipx or pip. Available everywhere, and the way in on a distro with no package of its own.
pipx install --system-site-packages collins # or: pip install --user collins
collins --install-desktop # optional: add it to the app grid--system-site-packages is not optional: Collins' dependencies list is deliberately empty because PyGObject, GTK, VTE and GtkSourceView come from your distro's packages (see Requirements), not from PyPI. A plain pipx install collins or a venv without that flag builds an environment that cannot see them, and the app exits on import gi the first time you run it.
collins --install-desktop is what data/install.sh is for a checkout and what the packages do system-wide: it writes the launcher, app icon and metainfo under ~/.local/share for your user only. The app offers the same thing from its sidebar menu — Install desktop icon, shown only when nothing has put Collins in your app grid yet. Nothing else needs installing — the toolbar and sidebar artwork ships inside the wheel.
Ubuntu — the episode6 PPA. The maintained channel on Ubuntu 24.04 (noble) and 26.04 (resolute), and on the derivatives that share them: Linux Mint, Pop!_OS, elementary OS, Zorin. Collins upgrades with the rest of your system from here.
sudo add-apt-repository ppa:episode6/stable
sudo apt install collinsUbuntu 22.04 (jammy) is not supported — it ships libadwaita 1.1 and GTK 4.6, and Collins uses APIs from libadwaita 1.5 and GTK 4.10.
Fedora — the episode6 COPR. The maintained channel on every current Fedora, and on RHEL 10 and its rebuilds (AlmaLinux 10, Rocky Linux 10, CentOS Stream 10). Same deal as the PPA: enable it once and Collins upgrades with the rest of your system.
sudo dnf copr enable episode6/stable
sudo dnf install collinsDebian — .deb package. A Launchpad PPA can only serve Ubuntu, so on Debian — and the Debian-family distros that don't build on Ubuntu — this is the way in (outside the Debian family, PyPI above is). Grab one from the releases page, or build it with ./scripts/build_deb.sh:
sudo apt install ./collins_*_all.debDependencies are pulled in automatically and the app appears in your app grid as "Collins". Note that a .deb installed this way does not update itself — it adds no apt source, deliberately, so nothing is subscribed to a third-party archive behind your back. Watch the releases page, or use the PPA if you are on Ubuntu.
RPM-based distros — .rpm package. Every release also attaches a binary noarch .rpm, built from the same spec the COPR publishes, for installing directly without enabling a repository:
sudo dnf install ./collins-*.noarch.rpmLike the .deb it adds no repository and does not update itself; on Fedora and RHEL 10 the COPR above is the maintained channel.
Updating. PPA: sudo apt upgrade picks it up with everything else. COPR: sudo dnf upgrade, likewise. .deb: install the new one over the old with the same sudo apt install ./collins_*_all.deb; .rpm: likewise, sudo dnf install ./collins-*.noarch.rpm. pipx: pipx upgrade collins (the --system-site-packages flag is remembered). pip: pip install --user --upgrade collins. Source: git pull. Relaunch Collins afterwards — a running instance keeps the old code, including one hidden with Keep Running; use Quit for a real restart.
Debian 13 (trixie) and newer have everything Collins needs. Debian 12 (bookworm) does not — libadwaita 1.2 against the 1.5 APIs.
Terminal copy & paste works the way you'd expect out of the box: plain Ctrl+C (when text is selected) and Ctrl+V — see easy copy & paste above. Ctrl+Shift+C / Ctrl+Shift+V always work too.
collins/
├── app.py # Adw.Application entry point + CSS
├── window.py # main window: tabs, actions, dialogs wiring
├── sidebar.py # session list: search, groups, badges, select mode
├── store.py # single source of truth: threaded scans, file monitors
├── models.py # SessionItem GObject with bindable properties
├── sessions.py # transcript discovery & parsing (pure Python)
├── providers.py # agent CLI abstraction (currently Claude Code)
├── state.py # persistent app state (names, favorites, settings)
├── terminal.py # VTE terminal tab + secondary shell panel
├── titles.py # auto-generated session titles (local + claude)
├── usage.py # Claude subscription usage fetch/parse
├── usagepanel.py # the sidebar usage panel widget
├── tokenrefresh.py # repair of an expired CLI login (auto_renew_login)
├── gitinfo.py # git branch, trunk and freshness for the footer and the git page
├── gitpage.py # the git page: the diff view under its header, the sidebar beside it, loads and freshness
├── diffview.py # the diff view: a view per hunk, split or stacked, gaps, find, selection, buttons, notes
├── gitsidebar.py # the git page's native commits and files panels and action row
├── gitmodel.py # the panels' rows and sections, as pure functions (GTK-free)
├── gitops.py # the git reads and mutations behind the panels and the diff view (GTK-free)
├── diffmodel.py # a parsed diff stream: files, hunks, gaps, split rows, word emphasis (GTK-free)
├── gitpatch.py # the staging arithmetic: partial patches and their plans (GTK-free)
├── gitloads.py # what the git page can load: modes, commits, ranges, their names and layout slot (GTK-free)
├── diffnotes.py # the notes and highlights on a diff, and their survival across reloads (GTK-free)
├── dialogs.py # rename / emoji / confirm / details / MCP dialogs
├── prefs.py # preferences dialog
├── tokensettings.py # the Token use rows: what runs Claude for you
├── welcome.py # the first-launch dialog: those rows, and where claude is
└── themes.py, i18n.py, switcher.py, panelhistory.py, copylabel.py, …
data/ # symlinked into collins/, so it ships in the wheel
├── com.episode6.Collins.desktop # launcher template
├── com.episode6.Collins.metainfo.xml # AppStream metadata
├── icons/ # app icon + the app-private action icons
└── install.sh # install launcher + icon for current user
scripts/
├── build_deb.sh # build the .deb package into dist/
├── install-debug-launcher.sh # app-grid entry: pull this checkout, run debug
├── make_demo_data.py # fake sessions for screenshots/demos
├── ship-release.py # publish a release branch as a GitHub release
├── verify_versions.py # CI check: all version copies agree
└── verify_wheel_data.py # CI check: the wheel carries icons + launcher
Releases follow the episode6 release-branch flow: cut release/v<VERSION>,
harden it, then ship from it. The whole process — versioning scheme,
version-bump PRs, hardening, hotfixes — lives in
RELEASE_CHECKLIST.md, and the release-branch-skill
and ship-release-skill agent skills in .agents/ automate most of
it.
Shipping runs ./scripts/ship-release.py from the release branch: it creates
the GitHub Release (tag v<VERSION>, notes extracted from
docs/releases.md), and the tag push runs
.github/workflows/release.yml — build the wheel/sdist, the .deb and a
binary .rpm, attach the .deb and .rpm to the release, publish to PyPI
(trusted publishing / OIDC), upload a source package per Ubuntu series to
ppa:episode6/stable, and an SRPM to the episode6/stable COPR, which
builds it for every Fedora and for RHEL 10.
Collins is a rebranded fork of agent-session-manager by Máté Molnár, which did all the heavy lifting — see the original project's website for the app Collins grew out of. Released under GPL-3.0-or-later, same as the original.
Everything Collins is built on is disclosed in THIRD_PARTY_LICENSES.md — the same document the app shows on the Legal page of its About dialog.
