tissues is a Rust terminal app for working through GitHub issues in one repository at a time. It uses Ratatui for the interface, TachyonFX for terminal animations, Octocrab for GitHub API calls, and the GitHub CLI for authentication.
- Browse open, closed, or all issues for a single repository.
- Filter by issue state, assignee, labels, and search text.
- Sort by updated time, created time, comment count, or assignee.
- View the selected issue body and comments in a collapsible tree.
- Render issue descriptions and comments as Markdown in the detail pane.
- Create new issues, optionally starting from Markdown issue templates in
.github/ISSUE_TEMPLATE. - Edit issue title and body inline.
- Add comments to existing issues.
- Complete
@usernamementions from repository collaborators while writing comments and issue bodies. - Assign issues to yourself, a collaborator, or nobody.
- Edit labels on existing issues.
- Use mouse clicks for issue selection, modal fields, picker rows, and action buttons.
- Close issues with a required closing comment.
- Reopen issues after confirmation.
- Refresh issue data without leaving the terminal.
- Auto-refresh issue data every 5 seconds while browsing.
- Show a visible notification, terminal bell, and macOS system sound when new issues arrive.
- Notify when new comments mention your authenticated GitHub username.
- Notify when new issue descriptions or updated issue bodies mention your authenticated GitHub username.
- Animate newly arrived issues in the list with a temporary
NEWrow highlight. - Animate mentioned issues in the list with a temporary
PINGrow highlight. - Show issue author, assignees, relative age, mention badges, and stale badges in the list.
- Show a confirmation after successful writes once issue state has reloaded.
- Show compact loading indicators for routine actions with contained TachyonFX movement.
- Use a simple TachyonFX coalesce effect for loading and completion feedback.
- Use exabind-inspired frame glyphs while inheriting the user's terminal theme.
- Use your existing
ghlogin instead of storing a token in the app.
- Rust toolchain.
- GitHub CLI installed as
gh. - Authenticated GitHub CLI session:
gh auth loginThe app reads a token from:
gh auth tokenIt does not persist GitHub credentials.
Install from crates.io:
# Latest
cargo install tissues --locked
# Specific version
cargo install tissues --version "0.2.0" --lockedValidate:
tissues --version
tissues --helpOpen a specific repository:
tissues owner/tissuesGitHub remote URLs work too:
tissues git@github.com:Kade-Powell/tissues.gitOr run from source:
cargo run -- owner/tissuesOr run inside a GitHub checkout and let gh repo view infer the repository:
cargo runj/Down: move to the next issue.k/Up: move to the previous issue.Enter: collapse or expand comments in the detail tree.:: open command mode at the bottom of the screen.Tab: complete the highlighted command suggestion while in command mode.Space: toggle users while assigning, thenEntersubmits all selected assignees.n: create a new issue with separate title, Markdown body, and labels fields.x: close the selected open issue with a required comment, or reopen a closed issue after confirmation.Tab/Shift+Tab: move between new issue fields.Tab: complete an active@usernamemention while writing a comment or issue body.- Arrow keys,
Home,End,Backspace, andDelete: edit text at the cursor in command, search, comment, issue, and picker fields. Enter: move from title to body, insert body newlines, or add the current label.Ctrl+T: apply the next available issue template while creating a new issue.Ctrl+S: submit a comment, close with comment, or create the issue from any new issue field.Ctrl+EnterorCtrl+J: insert a newline while writing an issue body or comment.Esc: cancel the current input or modal.- Mouse: click issue rows, detail tree, picker rows, text fields, and action buttons.
q: quit when not editing text.
Useful commands:
:refresh: reload issues now.:all,:clear, or:clear filters: clear state, assignee, label, and search filters.:fsor:filter state: cycle state filter: open, closed, all.:faor:filter assignee: choose an assignee filter: any, me, unassigned, or a collaborator.:s <text>or:search <text>: search issue titles.:me: filter to issues assigned to you.:unassigned: filter to unassigned issues.:label <name>: filter to a label. Use:label anyto clear label filters.:sort,:sort updated,:sort created,:sort comments, or:sort assignee: change issue ordering.:assign: assign the selected issue to yourself, nobody, or collaborators.:labels: edit labels on the selected issue.:edit: edit the selected issue title and Markdown body.:comment: comment on the selected issue.:pingor:mentions: jump to the first highlighted mention.:new: create a new issue.:close: close or reopen the selected issue.:quit: quit.
While browsing, tissues automatically reloads issues every 5 seconds. If the refreshed list contains issue numbers that were not already visible, or new comments, new issue descriptions, or updated issue bodies mention your authenticated GitHub username, the footer shows the notification, the terminal bell rings, and macOS plays the system notification sound when available.
For the fastest edit/check loop, run bacon from the repo root:
baconThis watches the project and runs cargo check --all-targets after changes. Inside bacon:
t: run tests.u: run library unit tests.c: run clippy with the same warning policy used for verification.f: runcargo fmt --check.d: build docs without dependencies.s: run the non-interactive help smoke test.
Run the interactive TUI in a separate terminal:
cargo run -- owner/tissuesFor restart-on-change development of the actual TUI, install watchexec and run the helper script in a normal terminal:
cargo install watchexec-cli
./scripts/dev-tui owner/tissuesDo not run the full tissues TUI as a bacon job. Bacon is also a terminal UI, and nesting tissues inside it can leave the terminal alternate screen, mouse capture, or formatting in a bad state. Bacon's run and run-long jobs are intentionally overridden to print a reminder instead of launching tissues. The included smoke job intentionally runs only cargo run -- --help.
Run the checks used for this project:
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo testInstall the local git hooks with prek before committing:
prek install
prek install --hook-type pre-pushThe commit-message hook enforces Conventional Commits, and the pre-push hook runs the quick formatting and packaging checks. Conventional Commit messages also drive the release workflow.
Releases are driven by Conventional Commit messages on main. Breaking changes create a major release, feat: creates a minor release, and any other Conventional Commit type creates a patch release. The release workflow commits the package version, tags vX.Y.Z, creates the GitHub release, and publishes tissues to crates.io with CRATES_IO_TOKEN.
The core code is split by responsibility:
src/app.rs: UI state, filters, selection, and modes.src/cache.rs: local issue list and detail cache.src/config.rs: built-in and user-defined saved views.src/domain.rs: issue, comment, label, and user models.src/github.rs: Octocrab adapter andgh auth tokenintegration.src/repo.rs: repository parsing andgh repo viewinference.src/tui.rs: terminal event loop and live issue operations.src/ui.rs: Ratatui rendering and TachyonFX effects.
This is a v1 focused issue tracker. It intentionally does not include multi-repo inboxes, project board sync, pull request review workflows, or custom token storage.