Skip to content

feat(sidebar): activity-sorted project view with pinning#133

Open
matej21 wants to merge 7 commits into
mainfrom
feat/sidebar-activity-sort
Open

feat(sidebar): activity-sorted project view with pinning#133
matej21 wants to merge 7 commits into
mainfrom
feat/sidebar-activity-sort

Conversation

@matej21

@matej21 matej21 commented Jun 1, 2026

Copy link
Copy Markdown
Member

Addresses #120 — surfacing active/attention-worthy projects in the sidebar.

Instead of auto-moving projects between ACTIVE/RECENT/ARCHIVED sections (which would fight the existing manual project_order + folders + drag-and-drop model), this adds an opt-in, per-window "sort by activity" view that leaves the manual model completely untouched. Toggle it from the PROJECTS header (focus icon, highlighted when active).

Behaviour

In Activity mode the sidebar ignores project_order and folders and shows a flat, tiered list:

  1. Pinned — kept in stable manual order (an anchor for muscle memory; never reordered by activity)
  2. Needs attention — a terminal has an unseen bell / OSC notification
  3. Running — a terminal is actively running a command
  4. Recent — everything else

Non-pinned tiers sort by most-recent activity first.

What counts as "activity"

Deliberately discrete attention events, not raw output volume (a tail -f / dev server must not pin itself to the top):

  • focus
  • a finished command (OSC 133 ;D — new one-shot edge on Terminal)
  • a bell / OSC 9/777/99 notification

last_activity_at is persisted (unix-millis) so the view is sensible right after a restart.

Anti-jumping

  • Re-sort is driven by these discrete events, not per-output ticks
  • Hover-freeze: ordering is cached and not recomputed while the pointer is over the sidebar, so rows don't shuffle out from under the cursor
  • Attention state is sticky until the pane is focused
  • The "running" tier reads cached atomics only — no per-render /proc scans

Pinning

Pin/unpin from the project context menu; a pin marker shows in the row.

Commits (each independently buildable)

  1. feat(state)pinned, last_activity_at, ProjectSortMode (serde-default, backward compatible)
  2. feat(terminal) — OSC 133 command-finished edge
  3. feat(workspace)bump_activity, sort-mode + pin toggles
  4. feat(app) — bump activity on bell / notification / command-finish in the PTY loop
  5. feat(sidebar) — the activity view, tier headers, hover-freeze, pin UI

Tests

order_by_activity has unit coverage for tier precedence, pinned anchoring, recency sorting, and tiebreaks. All touched crates' test suites pass.

Known limitations / follow-ups

  • No keybind for the toggle yet (header button + context menu cover it)
  • Keyboard cursor-nav (arrow keys) isn't wired for the activity view
  • No move animations (event-driven re-sort + hover-freeze already keep it calm)
  • Dragging a row in Activity mode still mutates the manual order invisibly

🤖 Generated with Claude Code

@matej21 matej21 force-pushed the feat/sidebar-activity-sort branch from 71c95ae to 39ca58d Compare June 5, 2026 12:28
matej21 and others added 7 commits June 11, 2026 13:19
Adds per-project `pinned` and `last_activity_at` (unix-millis) plus a
per-window `ProjectSortMode` (Manual/Activity) to back an activity-sorted
sidebar view. All fields are serde-default for backward-compatible loads.
Remaining changes are the forced literal updates at ProjectData
construction sites.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A one-shot `command_finished_pending` edge fires when the prompt sidecar
records an OSC 133 ;D mark, consumed via `take_pending_command_finished()`.
Mirrors the bell edge so the PTY loop can stamp project activity once per
finished command.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds `bump_activity` (stamps last_activity_at + persists) plus
`toggle_project_sort_mode` and `toggle_project_pinned`. Focus now bumps
activity so the activity view surfaces the project the user moved into.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drains the command-finished edge each PTY batch and stamps the owning
project's activity, and bumps activity on bell/OSC alerts independent of
notification settings. Raw terminal output is deliberately not treated as
activity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A per-window toggle (PROJECTS header) flips the sidebar between the manual
order and a tiered activity view: pinned -> needs-attention -> running ->
recent, each non-pinned tier sorted by last activity. Folders and worktree
nesting are flattened in this mode. Hover-freeze holds the ordering while
the pointer is over the list so rows don't shuffle under the cursor. The
running tier uses cached atomics (no per-render /proc reads). Pin/unpin via
the project context menu, with a pin marker in the row.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The activity-sorted view had two correctness issues:

- Keyboard cursor handlers (up/down/confirm/toggle_expand) stayed live
  in activity mode but operate on the manual project_order+folder cursor
  list, which doesn't match the tiered activity rows. Arrow keys moved an
  invisible cursor, scroll jumped to the wrong row, and Enter focused an
  unhighlighted project. Guard them to no-op in activity mode (Escape
  stays active — it only clears the cursor).
- ActivityEntry.manual_index used the projects Vec push order instead of
  the user's arranged project_order, so the pinned tier and within-tier
  tiebreaks diverged from the manual view after any drag-reorder. Derive
  it from project_order (folders expanded inline). The Vec index is kept
  only for render_project_item's drag-drop target, which is unchanged.
The soft_close test helper's ProjectData literal was missing the new
`pinned` and `last_activity_at` fields, breaking the lib-test build
(`cargo clippy --all-targets`). The file comes from main and wasn't in
the original PR diff, so the gap surfaced after rebase. Add both fields
to match every other ProjectData literal in the branch.
@matej21 matej21 force-pushed the feat/sidebar-activity-sort branch from f504c59 to 2e53059 Compare June 11, 2026 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant