feat: pinned workspaces — main and long-lived branches as sidebar items#220
Open
iabdousd wants to merge 3 commits into
Open
feat: pinned workspaces — main and long-lived branches as sidebar items#220iabdousd wants to merge 3 commits into
iabdousd wants to merge 3 commits into
Conversation
d4bd2c2 to
2f8cd3d
Compare
…ms (#61) - DB migration v20 adds is_pinned column; backfills one main pinned task per project - Backend: pin_branch attaches worktree to existing branch; unpin_task; list_local_branches - Guards: archive/merge/PR/delete reject pinned tasks with operation in error message - Auto-creates main pinned task on add_project (worktree_path=repo_path) - Frontend: Sidebar splits into pinned section + divider + regular tasks; +Pin branch button - PinBranchDialog: filter, worktree path preview, count indicator, hides already-pinned - TaskPanel: Pin/Main badge in header; archive/PR actions hidden for pinned - buildTaskMenuItems pure helper for context menu (Archive vs Unpin vs neither) - Tests: 346 frontend, 456 Rust; clippy clean; tsc clean
- add_project: use db::next_port_offset for the seeded main task instead of hard-coding 0, matching the v24 migration's MAX(port_offset)+1 logic - Sidebar: surface unpin failures via addToast instead of silently swallowing the rejection (e.g. cannot-unpin-main backend error) - Document that the main pinned task's `branch` column is purely a display label - worktree_path == repo_path is the source of truth for HEAD - Rust tests: build_main_pinned_task field invariants, pin_branch with empty project_id, idempotent re-pin without remove, unpin guards (main, missing, not-pinned, branch-pin success), v24 migration leaves legacy tasks is_pinned=0 and avoids port-offset collisions - Frontend tests: filter-no-match disables button, reopen resets state, no-op submit when nothing selected, loading label during pin, missing project hides path preview, separator placement around Archive/Unpin, selectors react to live store mutation, archived main excluded, case sensitivity on projectId, trailing-slash equality
- delete_project: comment that cascade is the only path that may remove pinned tasks (IPC handler rejects pinned via reject_if_pinned) - pin_branch: roll back the worktree on DB write failure so the user is not wedged with a worktree on disk and no row to match it - Sidebar: partition tasks once per reactive update (O(T) instead of O(P*T)) by walking `tasks` once and bucketing by projectId/isPinned/ archived; drops two unused selector imports - PinBranchDialog: clarify that the worktree path preview is pre-canonicalize and may differ from the stored task.worktreePath when the repo path is a symlink - task.rs: rename pin_branch_idempotent_after_unpin_then_repin to pin_branch_rejects_repin_when_worktree_already_exists (the test asserts failure, not idempotence) - CHANGELOG: rephrase pinned-workspaces bullet to start with a verb - GitActions.test.tsx: revert unrelated PrInfo body removal
56b4926 to
e669b4e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
mainpinned row that runs sessions directly in the repo root (no worktree created). Branch label tracksproject.base_branch.+ Pin branchbutton in the project header opens a dialog to attach a worktree for any existing local branch (trunk,develop, etc.) as a persistent sidebar item.Implementation
ALTER TABLE tasks ADD COLUMN is_pinned; backfills onemainpinned task per existing project.add_projectseeds a main pinned task automatically on new project creation.pin_branch/unpin_task/list_local_branchesIPC commands (and typed wrappers inipc.ts).archive_task,merge_branch,create_pull_request,delete_taskreject pinned tasks with the operation name in the error.buildTaskMenuItemspure helper drives context-menu branching (Archive vs Unpin vs neither for main) — fully unit-tested without rendering the full Sidebar.PinBranchDialog: filter input (visible when >6 branches), worktree path preview, count indicator, hides already-pinned branches, error states.pinnedTasksForProject/unpinnedActiveTasksForProject/isMainPinnedselectors instore/tasks.ts.Test plan
mainpinned row, no divider (no regular tasks yet)main→ session runs withpwdreturning repo rootmainper project automatically+ Pin branch→ pick an existing branch → pinned row appears with worktree under.verun/worktrees/<branch>mainand a pinned branch — each runs in its own directorymain→ Unpin is absent; Archive is absentmake checkpasses (556 frontend tests, 623 Rust lib tests, clippy clean, tsc clean)Closes #61