You can now work on several branches of a project at once, each in its…#414
Merged
Conversation
* feat(open-knowledge): worktree selector for isolated per-branch windows
Adds a worktree selector to the desktop app so you can work on several
branches of a project at once, each in its own window with its own editor
and server. Surfaced in two places (PRD-7231):
- The sidebar project switcher gains a Worktrees section listing local
branches and their worktrees, with the current window and main worktree
flagged. Picking a branch opens its worktree in a new window, creating one
on demand under .ok/worktrees/<branch> if it does not exist yet. A "New
worktree" item opens a dialog to start a fresh branch off the current one.
- The File menu gains "New worktree" and "Switch worktree" items that drive
the same renderer surface via menu actions.
Desktop main enumerates branches and worktrees and runs git worktree add,
auto-locating each worktree inside the project and excluding .ok/worktrees/
from the parent repo git status through .git/info/exclude so the nested
worktree never shows up as untracked. Opening a worktree reuses the existing
project-open path with a new 'worktree' entry point; because the worktree
carries the committed .ok/config.yml it resolves as a managed project and
opens with no consent dialog. There is no in-place git checkout, so the live
editor and auto-committing shadow repo are never disturbed.
list and create ride one consolidated IPC channel (ok:worktree:dispatch),
following the ok:sharing:dispatch precedent to respect the hand-rolled
channel cap. The pure branch/worktree merge and path logic live in core with
unit tests; the git IO and selector UI are covered by integration and DOM
tests.
* fix(open-knowledge): worktree IPC no-git logging + stderr classify types
CI caught two issues on the worktree selector:
- worktree-service classifyAddError reached err.stderr through optional
chaining (a biome --unsafe rewrite of the original non-null assertion),
making raw possibly-undefined and failing desktop typecheck (TS18048).
Rewritten with a stable local + Buffer.isBuffer guard so no assertion is
needed and the unsafe fix cannot reintroduce it.
- The ok:worktree:dispatch handler returned { ok: false, reason: no-git }
without a paired logIpcError call, failing the ipc-log-coverage meta-test.
Added the logIpcError call in the guard block.
* fix(open-knowledge): guard project switcher against Electron open-click fall-through
On the Electron host Chromium delivers no real pointerdown to the renderer, so
the click that opens the project-switcher dropdown can fall through onto a menu
row and immediately fire its onSelect — a project opens and the menu flickers
shut. Swallow any row selection landing within SELECT_GUARD_MS of the menu
opening (preventDefault keeps the menu open); a deliberate later click still
works. Applies to recents, the project actions, and the new worktree rows.
Gated on the Electron host so browsers keep normal behavior.
* feat(open-knowledge): enrich recents with worktree relationship + keep project as launch default
Backend for first-class nested worktrees (PRD-7231): ok:project:list-recent
now annotates each present recent with { gitCommonDir, mainRoot, isLinkedWorktree,
branch } via a memoized single git rev-parse per path, so the renderer can group
linked worktrees under their main project. Opening a worktree still records it in
recents but sets lastOpenedProject to the main repo root, so the launch default
stays the project rather than a specific branch's window.
* feat(open-knowledge): cached non-blocking worktree store for the current project
Module-level store (mirrors current-branch-store) holding the current window's
WorktreeSelectorModel, fetched once via bridge.worktree.list() and shared across
the switcher, command palette, and search via useSyncExternalStore. Repeat reads
are cache-served (instant, non-blocking); refresh() re-fetches after a create; a
failed/null fetch keeps the prior cache. PRD-7231 FR7.
* feat(open-knowledge): pure repo-grouping of recents for nested worktrees
* feat(open-knowledge): nested worktree submenu, switcher search, Cmd-K worktrees
Make worktrees first-class in the project switcher. Recents group by repo:
a project with opened worktrees exposes them in a submenu (project row +
each worktree), a project with none stays a flat row. Typing in the switcher
searches across recent projects, opened worktrees, and the current project's
un-opened branches (create-on-demand via the cached worktree store). The
Cmd-K palette gains a Worktrees group over the same cached model.
Replaces the flat WorktreeSwitcherSection with RecentProjectsMenu; the
top-level "New worktree" item stays for git projects. One git spawn total,
shared across surfaces; async arrival fills a stable region without reflow.
* feat(open-knowledge): dual-mode New Worktree dialog (create or check out a branch)
The New Worktree dialog now disambiguates the typed branch against the
project's local branches: an unknown name creates a fresh branch off the
current one, a known name checks that existing branch out as a worktree
(createBranch false, no base). Existing branches surface in a datalist so
selection is discoverable, the caption + confirm label adapt to the mode,
and the current window's cached worktree model refreshes after a create.
* docs(open-knowledge): align worktree-selector SPEC with shipped submenu/search/dialog
* fix(open-knowledge): use <Trans> not interpolated t`` in worktree submenu
The React Compiler cannot lower a tagged template with interpolations
(`t`Open ${name}``), and it only fails in the vite build's Babel pass — not
tsc or bun tests — so it slipped local checks and broke the app build (and
every downstream OK Validation job). Switch the "Open <project>" label to
the <Trans> component, which handles interpolation compiler-safely.
* style(open-knowledge): biome-format worktree recents test files
* docs(open-knowledge): drop FR7 tag from worktree-store comment (comment-discipline)
* fix(open-knowledge): coalesce mid-flight worktree-store refresh + cover create error path
Addresses PR review: refresh() (fired right after worktree.create) was dropped
if it landed while the bootstrap load was still in-flight, so a just-created
worktree could miss the current window's cache until remount. Queue one
follow-up load instead. Also add the flagged error-path test: a failed
create-on-demand toasts and opens no window.
GitOrigin-RevId: 093eba067e2497015f4800bb3b17fa3995d4e6c3
Contributor
There was a problem hiding this comment.
Automated approval from agents-private public-mirror-sync (run: https://github.com/inkeep/agents-private/actions/runs/28509679656). Source of truth is the monorepo; direct edits on inkeep/open-knowledge are overwritten on next sync.
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.
You can now work on several branches of a project at once, each in its own window. The project switcher in the sidebar footer (and the File menu) has a new Worktrees section: pick a branch to open its worktree in a new window — if it doesn't have one yet, OpenKnowledge creates it on demand — or choose "New worktree…" to start a fresh branch. Worktrees are stored inside the project under
.ok/worktrees/and kept out of git status automatically, so each window stays fully isolated (its own editor and server) without touching your working copy.