forgetop #
A fast, keyboard-driven command center for your pull requests, work items, and CI pipelines — in one place.
Across GitHub, GitLab, Azure DevOps, Bitbucket, Linear, and Jira. Triage and act on everything without tab-hopping between forges, as a terminal UI and a web dashboard.
GitHub
GitLab
Azure DevOps
Bitbucket
Linear
Jira
This is the full reference. For install and a 60-second start, see the README.
Many sections below have a Terminal / Dashboard switch — pick the surface you're using and the whole page follows, so you only read the instructions that apply to you. Your choice is remembered.
forgetop --demoBuilt-in demo data, nothing written to disk. Getting started covers running it against your own accounts.
What forgetop does #
A short inventory of the whole app, before the section-by-section detail.
- The Command Center — the default landing screen: one cross-provider action inbox that triages every PR, work item, and pipeline into "what needs you", so you start on your queue instead of scrolling three separate lists.
- Terminal or browser — the same app as a keyboard-driven TUI and a local web dashboard, opened together by default. Everything below works in both.
- Three sections in one dashboard — Pull Requests, Work Items, and Pipelines, each a tab you can act on.
- Six forges — GitHub, GitLab, Azure DevOps, Bitbucket, Linear, and Jira, plus a built-in
--demo. - Cross-provider aggregation — bind several connections to a section and their items merge into one list, tagged by provider. All your PRs across GitHub and GitLab and Azure, in a single view.
- Do work, not just watch it — approve / request changes / merge / comment on PRs, change work-item states, re-run or cancel pipeline runs — all from the keyboard.
- Real code review — a full-screen PR view with Conversation, Commits, Checks, and Diff tabs; syntax-highlighted diffs grouped by directory, per-file viewed checkboxes, thread jump-navigation, a line cursor in the patch; inline line comments buffered locally then submitted as one review (Comment / Approve / Request changes); replying in-thread to someone else's comment; and an event timeline of who approved / requested changes / merged / commented.
- Pipeline drill-in — expand stages → jobs → steps with per-node durations, failure reasons, a scrollable logs pane, and open-in-browser.
- Pipeline actions — from a run's detail pane, re-run a failed run or cancel a running/queued one (GitHub, GitLab, Azure DevOps, Bitbucket).
- Pipeline approvals — see which runs are blocked on a gate (red Approval needed); acting on a gate is available in the terminal (GitHub, Azure DevOps, GitLab).
- Filter, sort, and shape — a live quick-filter, per-column sorting, work-item state visibility, and pipeline subscriptions — all remembered per view.
- Command palette (
Ctrl-P) — fuzzy-jump to any PR, work item, or pipeline across every provider from one search box, without scrolling or switching tabs. - Notification inbox (
i) — your cross-provider notification stream (reviews, mentions, CI failures, assignments) in one list, with a top-left unread indicator;Enterdrills straight into the item. GitHub, GitLab, and Linear. - Saved views — bundle a filter + sort + state into a named view and flip between them from an always-visible view bar (
[/]). - Desktop notifications — get pinged when a pipeline fails, a review is requested, or your PR is approved / gets changes requested — across every connected provider.
- Secure by default — tokens live in your OS keychain; the config file only ever holds a reference.
Core concepts #
Sections, connections, capabilities — and where your tokens actually live.
Sections and bindings #
forgetop has three sections: Pull Requests, Work Items, and Pipelines. Each is bound to one or more connections (a configured account on a forge). A section only shows data from the connections bound to it. You manage connections and bindings in the web dashboard — press C in the TUI to open it.
Providers and capabilities #
Each provider advertises capabilities — which sections it can serve. A connection only ever offers what it can actually do, so the UI never dangles a dead option:
| Provider | Pull Requests | Work Items | Pipelines |
|---|---|---|---|
| GitHub | yes | yes (Issues) | yes (Actions) |
| GitLab | yes (MRs) | yes (Issues) | yes (CI) |
| Azure DevOps | yes | yes | yes (Builds) |
| Bitbucket | yes | – | yes (Pipelines) |
| Linear | – | yes | – |
| Jira | – | yes | – |
Cross-provider aggregation #
Every section aggregates. Bind two or more connections to Pull Requests (or Work Items, or Pipelines) and their items merge into a single list with a Provider column so you can tell them apart. Filtering, sorting, and actions all work across the combined list — and each action targets the row's own provider, so approving a GitLab MR and merging a GitHub PR just work from the same screen.
Try it live: forgetop --demo seeds two demo connections so you can see the merged lists immediately.
Security #
Tokens are written to the OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service). The JSON config only stores a reference to each token — never the secret itself. For headless use you can supply a token via an environment variable instead (see Configuration).
The web dashboard is served on 127.0.0.1 only, gated by a per-session token carried in its URL. Because its API can act on your behalf (merge a PR, change a state), it never listens off-loopback and never accepts cross-origin requests; the token is never returned by the API, written to config, or logged.
Getting started #
Try it with the built-in demo, then point it at your own accounts.
Try it with no setup — everything is in memory, nothing is written:
forgetop --demoThen run it for real:
forgetopThis opens the terminal UI and the web dashboard together (the default). On first launch — before any connection has a token — the dashboard drops into a quick setup: pick a provider, paste a token, choose which sections it feeds. Tokens go to your OS keychain and are shared straight back to the terminal. Press C in the TUI (or open the dashboard's Settings) to manage connections any time, and ? shows every keybinding. See Web dashboard for the run modes.
Diagnosing setup #
If a connection isn't working, run the diagnostic — it checks the config location, keychain access, and each connection's token + connectivity, without opening the UI:
forgetop doctorIt prints a line per connection (✓ healthy, ⚠ no token, ✗ token present but auth failed), so you can see at a glance whether it's a missing token, a bad scope, or an expired credential.
Command-line options #
| Command | What it does |
|---|---|
forgetop | Launch the terminal UI (the web dashboard is served in the background — press B) |
forgetop --dashboard | Serve only the web dashboard (headless — no TUI) |
forgetop --demo (-d) | Launch with built-in demo data (no setup) |
forgetop doctor | Diagnose config, keychain access, and connection health |
forgetop --version (-V) | Print the version and exit |
forgetop --help (-h) | Show usage and exit |
Web dashboard #
The same app in a browser, built into the binary and served on loopback.
forgetop ships the same app as a local web dashboard — the Command Center, all three lists, PR review with an inline-comment diff viewer, the command palette, sort/filter, themes, and every write action (approve, merge, comment, submit a review, change a work-item state, approve a pipeline gate, retry a run, mark a notification read). It's a React app built into the binary and served by forgetop itself — no separate install, no external network.
The terminal UI and the dashboard are two frontends over one core, so they show the same data, act through the same providers, and share the same config + keychain — a connection or a setting changed in one shows up in the other.
Opening it #
- From the TUI: press
B(shown in the footer and?help on every screen). - Give feedback: use the dashboard button beside connection health, or press
Fin the TUI. Both open the public GitHub feedback issue form; forgetop does not send logs or credentials. - Headless:
forgetop --dashboardserves it and opens your browser — no TTY, so it's handy over SSH with a forwarded port.
Connections & settings #
Connection setup lives in the dashboard's Settings page: add a provider from a form tailored to it, paste a token (stored in the OS keychain), tick which sections it feeds, and Test / Edit / Delete it. First launch with nothing set up opens this automatically. Pressing C in the TUI jumps straight here.
Security #
The server binds 127.0.0.1 only and gates its API with a per-session token in the URL — see Security.
Command Center #
The landing screen: everything that needs you, from every provider, on one page.
The Command Center is the screen forgetop opens on. Instead of browsing by type, it answers one question — what needs me right now? — by pulling every PR, work item, and pipeline across every connected provider into a single, prioritised page. The Pull Requests / Work Items / Pipelines views are still there as drill-downs.
It's split into two columns:
- Needs you (left) — things ripe for action now, in urgency order:
- Needs your review — PRs where you're a requested reviewer.
- Approvals waiting — pipeline runs blocked on a gate you can approve.
- Ready to merge — your PRs that are approved, mergeable, and green.
- Needs fixing — your PRs with changes requested / failing checks / conflicts, and failed pipeline runs.
- Your work (right) — your own things:
- Assigned to you — work items assigned to you.
- Your open pull requests — the full list of your open authored PRs (a PR that's also an action item on the left still appears here; this is the complete list).
- Recently merged — your PRs merged in the last few days.
Every row is laid out on one aligned grid so PRs, pipelines (CI), and work items (WI) read as siblings: a coloured type badge, a status signal (a PR shows its review state — ✓ ok, ○ review, ✗ changes, ◌ draft; a pipeline its run status; a work item its state), a short #ref, the title, one type-specific detail (PR +/-, pipeline branch, work-item type), the provider, and the age (which reddens once it's stale). For pipelines the title is the pipeline name (e.g. CI Build) and the ref is the run/release (e.g. 10.1.100).
Getting around: the two columns scroll independently. Click a card to open it — a pull request opens its in-app review panel right here; work items and pipelines open in their provider (open them from the Work Items / Pipelines tabs for the in-app panel). When you act on an item — submit a review, approve, or merge — it drops off the Command Center straight away rather than waiting for the next poll. The sidebar Command Center badge counts only the items that actually need you.
Getting around:
↑/↓(ork/j) — move within the focused column.←/→(orh/l) — switch between the two columns.Enter— open the selected item in its full view (the same PR / work-item / pipeline view as from the section tabs, with all its actions).Esc— from an item opened here, return to the Command Center with the same row still selected.Tab,1–4— switch top-level tabs.r— refresh.
Two touches make it feel live: when you act on an item — submit a review, approve, or merge a PR — it drops off the Command Center immediately rather than lingering until the next poll; and the selected row's title scrolls horizontally when it's too long to fit, so you can always read it in full. The Command Center (N) tab badge counts the items that actually need you (the reference sections don't inflate it).
Pull Requests #
Find a pull request in the list; do the review work inside it.
The Pull Requests view is browse-and-open: the list is for finding a PR; every write action lives inside the PR panel.
On the list:
- Click a card to open the PR review panel (a slide-over from the right).
- The control bar across the top filters and sorts: Show (Open / Draft / Checks failing), Connection (one provider or all), and Sort (Recently updated / Oldest / Title). Your choice per list is remembered.
- Each card shows the review state,
#number, the+/-, checks, reviewers, and labels.
The meta bar under the title shows who opened the PR and the reviewers, each with a vote mark: ✓ approved, ✗ changes requested, · no vote yet. (These come from the provider's review data — on GitHub/GitLab the votes are read from /reviews and /approvals, not just the requested-reviewer list, so an approver actually shows a tick.)
Inside the PR panel (three tabs):
- Conversation — the description, a Timeline of events (see below), the comment threads, a box to add a comment, and ↳ Reply on each thread.
- Commits — one row per commit; click one to see its diff on the Files tab.
- Files — the changed files with a left-hand file list you click between and a syntax-coloured diff; existing review comments render inline beneath the line they're on. Hover a line and click the
+to write an inline comment, or click ↳ Reply under any existing comment to answer it in-thread. Selecting a commit on the Commits tab scopes this to that commit's diff.
Checks live on the action-bar badge (below), not a tab.
The Timeline (newest first) shows who did what: approvals, change-requests, merges, state changes and comments — assembled from each provider's timeline/activity/history API (GitHub reviews + issue events, Bitbucket activity, GitLab resource-events + approvals, Azure reviewer votes, plus comments). A provider without a timeline API just shows the comment activity.
The header has an ↗ open-in-provider link. The action bar shows a checks badge on the left — green "All checks passed" or red "N checks failed"; click it for a popover listing every check (each links to the provider) — and Approve, Request changes, Merge on the right. Choosing an action closes the panel. Press Esc or click the backdrop to close.
Reviewing code with line comments #
On the Files tab, click the + on a code line to write an inline comment. Comments are buffered as pending (shown in a blue pending box) so you can comment on several lines first, then submit them together as one review — Submit comments, Request changes, or Approve. If you try to close the panel with comments still pending, forgetop asks before discarding them.
- GitHub posts it as a single native review.
- GitLab posts positioned discussions (and approves if you chose Approve).
- Azure DevOps / Bitbucket don't expose inline patches, so line comments aren't available there — use the Conversation tab.
Replying to a comment #
Click ↳ Reply under any comment to answer it in-thread rather than starting a new top-level comment. forgetop uses each provider's real reply API:
- Azure DevOps and GitLab (discussions) nest the reply under the original comment.
- Bitbucket replies to the root comment of the thread.
- GitHub review (diff-line) threads get a native threaded reply. A GitHub PR conversation comment is flat — GitHub has no reply API for it — so a reply there posts a new conversation comment.
The Pull Requests tab is browse-and-open: the list is for finding a PR; every write action lives inside the PR view.
On the list:
Enter— open the full-screen PR view.f— filter by status: a checklist of Open / Draft / Merged / Closed; tick which to show. Defaults to Open + Draft; ticking Merged or Closed transparently widens the fetch to include completed PRs, so you can e.g. keep the Mine view but see your open and recently-merged PRs together. The list title shows the active set (Pull Requests · Open, Merged). Session-only.[/]— switch saved views; PRs default to All / Mine / Review-requested./— quick-filter by typing;S— sort by a column;o— open in browser.
Inside the PR view (four sub-tabs, switch with ←/→):
- Conversation — description, reviewers, labels, and comment threads.
- Commits — one row per commit;
Enterdrills into that commit's diff. - Checks — each named CI check with its status.
- Diff — the changed files, grouped by directory and syntax-highlighted;
Enteron a file drops into a line cursor in the patch (↑/↓move line-by-line; the title shows the real file line).
Write actions from the view: a approve, x request changes, m merge (pick a strategy), c comment, r reply to a thread, o open in browser.
Reading the diff
- Syntax highlighting — patches are highlighted for common languages (Rust, TS/JS, Python, Go, Java, JSON, YAML), using the theme's colours; other languages render plain. The
+/-add/remove colour is always kept. - Viewed checkboxes — press
von a file to mark it reviewed ([x]); the file-list title tracks your progress asN/M reviewed. Session-only. - Directory grouping — files are grouped under directory headers so a large PR is easier to scan.
- Inline comment threads — existing review comments render inline in the diff, beneath the line they're on (a left bar: accent = open, dim = resolved), so you read them in context instead of a side list.
[/]jump the cursor between them, andrreplies to the thread under the cursor in-thread. (Unanchored / PR-level comments stay on the Conversation tab, whererreplies to the thread there.)
Reviewing code with line comments
In the Diff tab's line cursor, press c on a code line to write an inline comment. Comments are buffered locally — the line gets a ▎ marker — so you can comment on several lines first. Press s to submit them all as one review, choosing the verdict: Comment, Approve, or Request changes. If you press Esc or q to leave with comments still buffered, forgetop asks whether to submit or leave without submitting first, so you don't lose them by accident.
- GitHub posts it as a single native review.
- GitLab posts positioned discussions (and approves if you chose Approve).
- Azure DevOps / Bitbucket don't expose inline patches, so the line cursor — and line comments — aren't available there.
Work Items #
The items assigned to you, with state transitions pulled from the provider.
The Work Items view shows only items assigned to you — each provider resolves the current user from your token (@me, currentUser(), isMe, …), so there's nothing to configure.
Browse-and-open; the write actions live in the item panel.
- Click a work item to open its panel: the description, a Timeline of events (status changes, assignments, comments — from the provider's history: Jira changelog, Linear issue history, Azure work-item revisions, GitHub/GitLab issue events), comment threads with a box to add a comment, and a Move ▾ control to change state.
- Move ▾ pulls its choices from the provider itself: Jira's workflow transitions, Linear's team states, Azure's work-item-type states, or open/closed for GitHub/GitLab issues.
- The header's ↗ opens the item in its provider.
- The control bar filters and sorts: Show (In progress / Blocked / Not started), Connection, and Sort.
The list is browse-and-open; the write actions live in the item view:
Enter— open the item.f(on the list) — a checklist of the states currently in view; pick which to show. Built from the loaded items, so it's always provider-accurate (In ProgressvsInprogress). Persisted.
Inside the item view (after Enter):
u— update state. The choices are pulled from the provider itself: Jira's workflow transitions, Linear's team states, Azure's work-item-type states, or open/closed for GitHub/GitLab issues. (Falls back to the states seen across the list if a provider can't report them.)c— comment (works on every work-item provider).o— open in browser.
Pipelines #
Runs, a stages → jobs → steps drill-in, logs, re-runs, and approval gates.
Each entry is a run, tagged with its pipeline (definition) name — e.g. CI Build or CD (Release) — and its own run name or release (e.g. 10.1.100, or its number when it has none).
- Click a run to open its drill-in panel: a stages → jobs → steps tree. Each node carries its status; expand a job to load its scrollable logs, and failed jobs show a short failure reason (GitLab's reason, Azure's error/warning counts).
- A failed run gets a Re-run button; a run waiting on a gate shows Approve / Reject (see below). The header's ↗ opens the run in its provider.
- Filter with the control bar's Show (Running / Failed / Succeeded / Awaiting approval), plus Connection and Sort.
The list shows a Pipeline column separate from the Run column; sort by Pipeline to group runs by their definition.
Enter— drill into a run: a collapsible stages → jobs → steps tree.T— trigger a run.
Inside the drill-in each node shows its duration, and failed jobs show a short failure reason (GitLab's reason, Azure's error/warning counts). Then:
Enter— expand / collapse the selected node.L— open a scrollable logs pane for the selected job (Esccloses).A— approve / reject a waiting gate (see below).o— open the selected job in the browser.
For a connection that discovers many pipelines, open the config screen and press s on it to subscribe to just the definitions you care about.
Approvals #
When a run is blocked on a manual gate — a GitHub environment required-reviewer, an Azure DevOps approval check, or a GitLab manual job — forgetop surfaces it, refreshed on the normal poll (and you can opt into a desktop notification when a gate first appears):
- The run shows the waiting gate inline; on providers where forgetop can act (GitHub, GitLab) it renders Approve / Reject buttons — both on the card and inside the run's panel.
- The Pipelines list shows a red Approval needed column on that run. Inside the run, a banner reads ⏸ Approval needed: {environment}; on providers where forgetop can act (GitHub, GitLab) press
Ato open a picker of Approve / Reject options per gate, then confirm.
Acting is capability-scoped:
- GitHub / GitLab — approve or reject in-app (on GitLab a reject cancels the manual job).
- Azure DevOps — view-only: the pending gate is surfaced, but Azure doesn't expose the environment check as an actionable approval over the API, so there's no
Aaction — approve it in the Azure UI. - Bitbucket — approvals aren't surfaced at all (its API can't resume a paused manual step); the run shows an explicit "not supported" note.
Filtering and sorting #
Cut a busy view down, and keep the shape you chose.
Each list has a control bar across the top with three dropdowns, remembered per list in your browser:
- Sort — order the list (Recently updated / Oldest / Title, and so on per section).
- Connection — narrow to one provider, or All connections.
- Show — a status filter tuned to the section: PRs (Open / Draft / Checks failing), Work Items (In progress / Blocked / Not started), Pipelines (Running / Failed / Succeeded / Awaiting approval).
All three compose, and all work across the aggregated (multi-provider) list.
Four complementary ways to cut a busy view down:
- Quick-filter (
/) — on any list, type to filter rows live; every whitespace-separated token must match (case-insensitive) across the row's key fields.Enterapplies,Escclears. Remembered per tab. - Sort (
S) — pick a column to sort by; re-pick to flip direction. The sorted column shows a▲/▼arrow. Persisted per view. - PR status (
fon Pull Requests) — show only chosen statuses (Open / Draft / Merged / Closed); see Pull Requests. - Work-item state visibility (
fon Work Items) — show only chosen states. - Pipeline subscriptions (
sin the config screen) — track only chosen pipeline definitions per connection.
All of these compose, and all work across the aggregated (multi-provider) list.
Command palette #
Fuzzy-jump to any loaded PR, work item, or pipeline from one box.
The command palette is a fuzzy jump across everything already loaded: every PR, work item, and pipeline, from every connected provider, in one list. Type to filter (matching the title, author, branch, identifier, or connection); each row carries a status dot in the usual green/blue/red/grey colours. It searches only what's loaded — no network round-trip — so it's instant.
Press ⌘K (Ctrl-K on Windows/Linux) from anywhere to open it; type to filter, click a result (or ↑/↓ then Enter) to open it, Esc to dismiss.
Press Ctrl-P (from the Command Center or any list) to open it; ↑/↓ (or Ctrl-n/Ctrl-p) to move, Enter to open the item's full view, Esc to dismiss.
Notification inbox #
What just happened, aggregated across every provider that reports it.
The notification inbox is your notification stream aggregated across providers: review requests, @mentions, assignments, CI failures, comments, and state changes, newest first. It answers what just happened, where the Command Center answers what needs me now. A Notifications nav item carries an unread count that stands out when something's waiting.
- Open Notifications in the sidebar. Each row shows a kind glyph in the status colours, an unread dot, the title, the repo/project, the connection, and age.
- Click a row to open it in its provider; the ✓ read button marks it read (and the Show filter can narrow to unread). Marking updates the count immediately.
Press i (from the Command Center or any list) to open the Inbox. The Notifications (N) [i] nav item sits at the far right of the tab bar — dim grey at zero, bold yellow with the count when something's waiting, accent while the Inbox is open. It's a nav item, not part of the Tab cycle.
↑/↓move ·Enteropens the item in-app (drills straight into that PR / work item) ·oopens it in the browser ·xmarks the row read ·Amarks everything read ·rrefreshes ·Escback. Opening or marking updates the count immediately.- Each row shows a kind glyph in the status colours (CI failures red, reviews/assignments accent, mentions magenta), an unread dot, the title, the repo/project, the connection, and age.
Provider support. The inbox is fed by the providers that expose a personal notification feed:
| Provider | Notification inbox |
|---|---|
| GitHub | ✅ (notifications) |
| GitLab | ✅ (todos) |
| Linear | ✅ (notifications) |
| Azure DevOps | — no personal feed |
| Bitbucket | — no personal feed |
| Jira | — no personal feed |
Azure DevOps, Bitbucket, and Jira don't offer a personal notification feed in their APIs, so connections for those providers simply don't contribute to the inbox. (This is separate from desktop notifications, which is about which events fire an OS ping.)
Saved views #
Bundle a filter, a sort, and a state set into a named view.
The dashboard doesn't have named saved views — instead, each list remembers its own control-bar state (Sort, Connection, Show) in your browser, so a list comes back shaped the way you left it. For the named-view workflow with a switchable view bar, use the terminal (toggle above).
A saved view is a named bundle of a section's shaping — its base filter, the quick-filter text, the sort, and (on Work Items) which states are hidden. Views live in a horizontal view bar above the list, gh-dash style, with the active one highlighted. The bar appears once a section has more than one view.
Every section starts with sensible defaults: Pull Requests get All, Mine, and Review; Work Items and Pipelines get a single All.
[/]— switch to the previous / next view.V— save the current filter + sort + states as a new view (you're prompted for a name), then switch to it.X— delete the current view (with a confirm; you can't delete the last one).
Switching a view re-applies the whole bundle at once, so a Mine view can pin a different sort and quick-filter than Review. Views are persisted per section, so they're waiting next time — except in --demo, where the in-memory config means saved views last only for that session.
Notifications #
Native desktop pings for the events you opt into.
forgetop raises native desktop notifications on the events you choose:
- Pipeline failed — a run transitions into a failed state.
- Pipeline approval needed — a run first starts waiting on a gate you can approve.
- Review requested — you're newly a requested reviewer on a PR.
- Your PR approved / changes requested — a reviewer votes on a PR you authored.
Press N anywhere to open a checklist and opt in/out of each event; the choice is persisted. Detection is seeded on load (no startup spam), de-duped, and re-seeded when you change settings — and enabling fires one confirmation notification so you can verify it works on your machine. Every event spans all bound providers, not just the first.
Keybindings #
Every key, grouped by the screen it belongs to.
Terminal only — the dashboard is mouse-driven, with ⌘K for the command palette.
forgetop shows a context-aware key glossary along the bottom — it only lists the keys valid for where you are. Press ? for the full panel. The complete set:
Global #
| Key | Action |
|---|---|
Tab, 1–4 | Switch tab (1 = Command Center) |
↑ / ↓, k / j | Move selection |
Ctrl-P | Command palette — fuzzy-jump to any PR, work item, or pipeline |
i | Notification inbox (review requests, mentions, CI failures, assignments) |
/ | Quick-filter the current list |
S | Sort by a column (re-pick flips direction) |
o | Open selected item in browser |
B | Open the web dashboard in your browser |
F | Open the public GitHub feedback issue form |
v | Choose which tabs are visible |
C | Open the connections page (in the web dashboard) |
r | Refresh · t cycle theme |
N | Notifications — choose which events ping you |
? | Show all keybindings (anywhere) |
Esc / q | Back / close — neither one quits · Ctrl-C quits |
Command Center #
| Key | Action |
|---|---|
↑ / ↓, k / j | Move within the focused column |
← / →, h / l | Switch between the two columns |
Enter | Open the selected item in its full view |
Esc (in the opened item) | Return to the Command Center, same row selected |
Saved views #
| Key | Action |
|---|---|
[ / ] | Previous / next saved view |
V | Save the current filter + sort + states as a view |
X | Delete the current view |
Pull Requests (list) #
| Key | Action |
|---|---|
Enter | Open the PR view |
f | Filter by status (Open / Draft / Merged / Closed) |
[ / ] | Switch saved views (defaults All / Mine / Review-requested) |
Inside the PR view #
| Key | Action |
|---|---|
← / → | Switch sub-tab |
a / x | Approve / request changes |
m | Merge (choose strategy) |
c | Comment (inline on a diff line, otherwise the PR) |
[ / ] (Diff line cursor) | Jump between existing comment threads |
r | Reply to a comment thread (under the diff cursor, or the Conversation thread) |
Enter (Commits) | Drill into that commit's diff |
Enter (Diff, on a file) | Line cursor within the patch |
s | Submit buffered line comments as one review |
Esc | Step back (line cursor → file list → close) |
Work Items #
| Key | Action |
|---|---|
Enter | Open the item |
f | Choose which states to show |
u (in the item view) | Update state (choices pulled from the provider) |
c (in the item view) | Comment |
Pipelines #
| Key | Action |
|---|---|
Enter | Drill in (stages → jobs → steps) |
Enter (in drill-in) | Expand / collapse a node |
L | View the selected job's logs |
A (in drill-in) | Approve / reject a waiting gate (GitHub, GitLab; Azure view-only) |
o | Open the selected job in the browser |
T | Trigger a run |
Connections (terminal fallback) #
Connection management lives in the web dashboard — C opens it and also shows a connections list in the terminal. That list still supports the original keys as a fallback:
| Key | Action |
|---|---|
a | Add a connection |
p / w | Bind Pull Requests / Work Items (multi-select) |
s | Pipeline subscriptions |
x | Remove connection |
Configuration #
Where config lives, how tokens are stored, and what gets logged.
Config is a small JSON file, created and managed for you:
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/forgetop/config.json |
| Linux | ~/.config/forgetop/config.json |
| Windows | %APPDATA%\forgetop\config.json |
It never contains secrets — only a reference to each token in the keychain, plus your bindings and view preferences (saved views, sorts, hidden states, notification choices).
Tokens #
You add connections and paste tokens in the dashboard's Settings page (see Web dashboard); each token is stored in your OS keychain under the service name forgetop. In headless environments (CI, containers) you can instead supply a token via an environment variable named FORGETOP_PAT_<CONNECTION_ID> (uppercased; non-alphanumeric characters become _).
Logs & diagnostics #
forgetop keeps rolling diagnostic files next to your config — forgetop.log and its numbered segments in the same directory (e.g. ~/.config/forgetop/). The retained history is limited to approximately the latest 24 hours and never more than 3 MiB; under heavy logging, the size limit wins. It records:
- Crashes — if forgetop ever panics it restores your terminal (no garbled screen), writes the panic to the log, and prints the path so you can send it on.
- Errors — a failed action (approve / merge / comment / trigger / …) and background provider / auth / network fetch failures, which otherwise only flash on screen — each timestamped, so intermittent issues are reviewable after the fact.
forgetop doctor prints the active log's path. Logging is best-effort and redacts common credential headers, token fields, credential-bearing URLs, dashboard session tokens, and known provider-token formats. Request/response bodies and configuration contents are not intentionally logged, but you should still inspect diagnostics before sharing them manually. forgetop never attaches them to the GitHub feedback form.
The running version is shown in the header (▟ forgetop v…) and via forgetop --version, so it's easy to include when reporting an issue.
Token scopes #
| Provider | What to create | Scopes |
|---|---|---|
| GitHub | Personal access token | repo (PRs, issues, checks); workflow / Actions read for pipelines |
| GitLab | Personal access token (Settings → Access Tokens) | api (merge requests, issues, pipelines) |
| Azure DevOps | Personal access token | Code Read, Work Items Read/Write, Build Read/Execute |
| Linear | Personal API key (Settings → Security and access → API) | default |
| Jira | API token (id.atlassian.com) + your account email | default (account access) |
| Bitbucket | App password (Personal settings → App passwords) + your username | Pull requests, Pipelines (read/write) |
Themes #
Four built-in themes, remembered per surface.
Four built-in themes — slate (default), dark, light, and matrix. In the terminal, cycle with t (256-colour palettes, so they render correctly on every terminal, including ones without truecolor); in the web dashboard, use the theme toggle in the sidebar footer. Each side remembers your choice (the dashboard's per browser).
How it works #
A Rust workspace: core, providers, terminal UI, server, CLI.
forgetop is a Rust Cargo workspace:
| Crate | Responsibility |
|---|---|
forgetop-core | Domain model, capability-scoped provider traits, config, secrets, services |
forgetop-providers | GitHub, GitLab, Azure DevOps, Linear, Jira, Bitbucket, and Demo implementations |
forgetop-tui | The ratatui terminal UI |
forgetop-server | The web dashboard — an axum server + an embedded React SPA, over the same services |
forgetop-cli | The forgetop binary |
A few design ideas hold it together:
- Capability-scoped traits. Providers implement
PullRequestSource,WorkItemSource, and/orPipelineSource— only what they support. The core never assumes a provider can do something it can't, which is how a Linear connection appears for Work Items but not Pull Requests. - Sections resolve to feeds. A section binds to a set of connections; the service resolves each to a live source (a "feed"). Aggregation is just iterating every feed and tagging each item with its connection — the same shape for PRs, Work Items, and Pipelines.
- Config never holds secrets. The config service persists bindings and preferences and stores only a
credential_refper connection; the actual token lives in the OS keychain via a separate secret store. - Immediate-mode UI, own input loop. The TUI owns a dedicated input reader thread feeding a
tokioloop, and redraws the whole frame each tick — so there are no framework focus fights, and every keystroke is dispatched explicitly.
cargo test # run the test suite
cargo clippy # lint
cargo run -- --demoSource: github.com/magna-nz/forgetop.