Repository navigation
Archive, Library, history and sidebar backups - #12
Conversation
…entries carry tab and Space name - src/main/archive/store.ts: every entry and its back/forward history in an append-only JSONL log (userData/archive/archive.jsonl), compacted when mostly dead; paged, day-grouped queries reusing the history store's matching. - src/main/archive/service.ts: mirrors state.archive (the recent window other features write to) into the store, drops private and deleted profiles' entries, moves the oldest out of state past 300 (never younger than 15 min), and drops entries whose tab came back. - ops.ts: archive entries carry tabId and spaceName; closed tabs' history is handed to the Archive (inbox.ts) instead of being lost. - archive.query / archive.delete commands (archive.testSeed under e2e). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…riginal Space (AR-02, AR-03, AR-04, SB-09, AR-05 core) - Library (AR-02, DL-09): its own view over the page area, kept above the tab views and below the command bar and Peek; opened from the new Library button in the sidebar's bottom bar (SB-09), Open Library (Cmd+Shift+L), View Archive and the macOS Archive menu; reopens to the last section; Esc, Cmd+W or another tab closes it and the page gets the keys back. Sections come from a registry (*.library-section.tsx) so other lanes add theirs without edits here. - Archive section (AR-03, AR-04): newest first under day headings, filters by source, Space and how it closed, per profile; virtualised and paged; search on each keystroke from the store's keys, narrowing the last answer as you type; Enter restores the top or highlighted match. - Restore (AR-05 core): back to the top of its Space's Today (routing rule > origin Space > current Space), with its tab id and history only when the profile matches; batch order kept; toast with Go to Space when it lands elsewhere; the command bar restores without a jump. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A folder deleted with its tabs and brought back with ⌘Z after its Space moved to another profile now gives the tabs that profile, and their old back/forward history stays behind (PR-05), as a restore from the Archive does. AR-05 is now built in full. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When an archived tab replaced a history row for the same page, it took the history row's place in the list, so two equally matching archived tabs could come out oldest first. The kept row now takes its own place, and the stable sort keeps the most recently archived tab first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A view's webContents is undefined once its window has closed, so calling isDestroyed() on it throws, and an uncaught main-process exception blocks quitting. Every use of the Library view's page now goes through pageOf(), which checks it exists first; the fade-out timer, the focus hand-backs and the tab-view scan included. The row menu no longer pops up over a window that has closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Restore sat over the end of a row, wider than the time it replaces, so it covered part of the Space name. It now shares the time's grid cell and always takes its room (hidden until hover or the keyboard highlight), so nothing moves or hides when it shows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…osed pages rank high (AR-09) - Audit: ⌘⇧T walks back through closes newest first, each tab selected with its back/forward history; ⌘Z reopens a just-closed tab in place (e2e: close A, B, C, then ⌘⇧T three times brings back C, B, A). - Undoing Close Tab now shows the tab again in the windows that were showing it; a tab closed in the background comes back unselected. - macOS File menu: Recently Closed, the last 10 closed tabs with their favicons, rebuilt as tabs close and come back. Windows and Linux have no app menu, so the Archive toolbar has a Recently Closed button with the same list (plus Reopen Closed Tab) on every platform. - Command bar: a page closed in the last 10 minutes keeps its history row's score as the archived row, instead of ranking after history. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…days by default (AR-08) AR-07: "Clear Archive…" is in the menu of the Archive's entry in the Library, Archive → Clear Archive… in the macOS app menu, and the command bar. Each opens the Library on the Archive and asks there first: the question says it can't be undone and that browsing history is kept. Cancel has the focus; Esc cancels and leaves the Library open. Clearing removes the shown profile's entries from the store and OrbitState; history is a separate store and stays. AR-08: settings.archiveKeepDays (default 30, 0 = forever; repaired on load). Entries older than that go once the Archive log is read at launch, every hour, and at once when a shorter time is chosen. The choice (30 Days, 90 Days, 1 Year, Forever) is in the Archive entry's menu and Archive → Keep Archived Tabs For on macOS, since there is no Settings view yet. The empty Archive says how long entries are kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… first "clear archive" listed Clear Today Tabs (keyword "archive") above Clear Archive…, because each word was scored on its own: Enter would have archived the Today tabs. The whole query starting an action title now scores as a full prefix match. Unit test with the real action definitions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
History is a Library section after the Archive: every visit of the current profile, newest first under day headings, from the history store's own query (`history.visits`, through `library.history`, which adds the remembered site icons). The list is virtualised and fetches pages as it scrolls; the next page starts just after the oldest visit fetched and skips those already listed, so visits that share a millisecond are neither lost nor doubled. Search matches every word in the title or the address; Enter opens the top match. A row opens its page in a new tab (⌘-click, ⌘Enter or the middle button: behind the Library). Its × or its menu (Open in New Tab, Open in Background, Copy Link, Remove from History) removes every visit to the page. View History (⌘Y on macOS, Ctrl+H elsewhere) is in Archive → View History and the command bar. The Recently Closed button takes a reopen arrow, so the clock icon is History's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ry (AR-06) Clicking an Archive row opens its page in the Peek card over the Library, which stays open underneath; the entry stays archived. ⌘W and Esc close only the Peek, and the Library takes the keys back with the row still chosen, so Enter restores it. The card's Open as Tab (⌘O) opens the page as a tab and keeps the entry, as the row menu's Open in New Tab does. ⌘-click and ⇧-click still select; double-click no longer restores (the first click previews). A closed Peek is archived like a closed tab, so closing a preview would have listed the page twice. The Archive now leaves out the entry a preview's Peek adds when it closes on the page previewed, while that entry is still archived; a reopened preview (⌘⇧T, ⌘Z) over the Library counts too, and a page the preview went on to is archived as usual. The Peek carries the entry's id (overlay.archiveEntry) and archive.restorePreview restores it and closes the Peek: the card's Restore button is for the peek lane. With no tab to preview over (an empty Space) a click opens the page in a new tab. The Peek takes the window's profile, so an entry of another profile is never previewed. Entries deleted from the row menu also leave the Library's selection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Backups of the whole sidebar (Spaces, Favorites per profile, pinned and Today tabs, folders, split views; private profiles left out), one JSON file each in userData/backups, written atomically. One is taken 30 s after launch and every 5 minutes when the sidebar changed (never for browsing alone), and before every restore. The schedule keeps up to 10 from today, then one a day for 10 days, one a week for the month before and one a month for the year before. Restoring puts the sidebar back in one store update: tabs in both keep their page and go back to their place; tabs only in the backup come back asleep with the page and history the Archive kept for them; tabs opened since go to the Archive with their history; Spaces added since go. Help → Restore Data… and the command bar's "Restore Data…" open the Library's Backups section. ⌘Z (and the restore's result) restore the backup taken just before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… asks, then restores with Undo (AR-11) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: cb052a43-6792-4c23-866a-c7219f62bf68) |
Conflicts: src/shared/rpc.ts keeps both renderer views ('library' and 'pip');
FEATURES.md regenerated. Typecheck, lint and build exit 0; unit 352/352.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ecent window in state (M1, AR-04) state.archive only keeps the newest 200-300 entries; older ones live in the Archive store, which the command bar never searched. The bar's archive source now reads the store (the profile's entries newest first, up to 5,000 as on main, cached on the store's version), and state.archive only until the Archive log has been read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…abs alone (M2, AR-11) Spaces outside the Space list (a private window's) and Spaces of a private or gone profile are kept as they are, with everything in them, and the windows that show them are neither moved nor changed. A backup's Space whose profile was deleted since no longer comes back in Default: that profile's data is gone (PR-08). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d deleted profiles' tabs (M3, AR-09) The Archive toolbar's Recently Closed menu and the macOS File menu read tabs.recentlyClosed, which lists every closed tab. They show in normal windows only, so they now drop tabs whose profile is private or gone. tabs.recentlyClosed reports each tab's profile for this (additive). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…'t be written (M4, AR-11)
The restore flow moves to restore-data.ts (no Electron), so it can be
tested. When backing up the sidebar as it is fails, the restore stops
before touching anything and says why ({ restored: false, reason:
'backup-failed' }); the Library shows "Couldn't back up the sidebar first;
nothing was changed". Removing backups the schedule no longer keeps is
best effort: it no longer fails the backup just written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Z and ⌘⇧Z work in the Library (F2, F3, AR-11, TB-18) - A restore pushes one "Restore Data" step above the steps from before it, which stay. Its undo puts back the sidebar it replaced, held in memory, so a backup the schedule prunes never breaks it, and no undo or redo writes a backup. The next ⌘Z goes further back; ⌘⇧Z restores again and records the step again. - The toast's Undo (backups.undoRestore) takes the restore back only while it is the newest change, and says so otherwise. - In the Library, ⌘Z / ⌘⇧Z (Ctrl on Windows and Linux) outside text fields run tabs.undo / tabs.redo, as from the sidebar or a page. - The tabs code no longer clears its stack on a restore; UndoStack.clear is back as on main. Left as the review allows (F3): a window moved off a removed Space stays where it went, and pages that come back are asleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 18ee437e-ac43-4b83-93df-296153e68d82) |
…rchive log and the backups (M5, AR-07, PR-08) - ArchiveStore.clear (Clear Archive, a deleted profile) rewrites the log right after it removed entries, and once more when it came during a rewrite that still held them. At load, a clear whose rewrite never happened (Orbit quit first) triggers one. - When a profile leaves the state (profiles.delete), and once shortly after launch, every backup is rewritten without that profile's Favorites, its Spaces and the tabs, folders and split views only they held, under a name with the new counts; a backup left with no Space goes. A private window's profile closing triggers nothing. - Restore Data no longer brings a deleted profile's Space back (in e4231a8, with M2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s on a new line (F11, AR-01) When the log doesn't end with a newline (read at load), or an append failed part way, the next append starts with one, so it is not glued onto the cut line and lost with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: ee59b730-d6d6-442f-b1b7-6fe65c20b7be) |
… as one unit (F1, SV-19, SV-24) - When every pane of a split goes at once (Close Split, the idle auto-archive of a Today split, a deleted folder), each pane's Archive entry records the split: its id, layout and sizes, name and focused pane (ArchivedTab.split, kept by the store). - Restoring any of those entries (row, preview, command bar) brings the split's other panes along, and restoreUnitInDraft puts them back as that split at the top of Today, in the first pane's Space. With one pane left in the Archive it comes back as a tab. - The Archive marks such rows with a split icon. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: b0bb24ad-8d90-4a98-83c2-55e7e3268915) |
…r Delete (F5, AR-07, AR-08)
- A shorter Keep time deletes the older entries at once, so it waits for
the user's yes: archive.setKeepDays({ days, confirmed? }) now answers
{ set, purges } and changes nothing while purges > 0 and not
confirmed. The menus (the Library's Archive menu, macOS Archive menu)
open the Library, which asks "Keep archived tabs for 90 days?" with
how many tabs go ("Delete 3 Tabs"). Cancel keeps them and the time; a
longer time is set at once. The app menu's check goes back to the time
in force while it asks.
- Delete from a row's menu and the selection's Delete show a toast with
Undo, which puts the entries back with their history (DeleteUndo, kept
in memory for a minute; entries whose tab is back or whose profile is
gone stay deleted).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 1fa4193b-438a-4cbc-9750-e2def23e3214) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 85a567da-38ec-40cf-be7c-fca16bf18154) |
…; the rest land in Today (F7, D33) A backup taken before the Favorites limit can hold more than MAX_FAVORITES. planRestore now keeps a profile's first 12 and puts the rest at the top of Today in the profile's first Space, as Today tabs (no pinned address); with no Space of that profile they stay out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 0a35961f-896b-48a3-8f05-e6354ab9cc1d) |
… stays off the network (F9) archive.testSeed takes `base`, a loopback origin, and seeds pages of it; the e2e seed helper always passes the fixture server's. The 10,000-entry test now restores a fixture page and waits for it to load, where it used to open https://harbor75.example.test/… (a name lookup). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: a5104b17-dc9e-4cf7-adc1-77387cfe1903) |
… so even the first open is quick (F10) A main window's Library view is made 5 s after the window first lays out, when no page is loading and nothing is over the window (rechecked every 2 s, made anyway after 5 checks). Its page builds the section it opens to, hidden, so the first open only shows it: open to shown 56-58 ms here, where a cold first open took 250-460 ms. library.testInfo reports `ready` once the view's page has loaded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 1f69f0c4-d0cf-4046-bce5-5a092e2804de) |
…entries (F10) The review measured a cold first open of 509 ms at 10k entries; with the view made while Orbit is idle it shows in 67-77 ms here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…9 lists its sections (F4, F12) - AR-10 is partial: History stays a Library section until Orbit has internal pages (D39). - DL-09: the Archive, History and Backups are Library sections; the view is made while Orbit is idle, so the first open is quick. - AR-04 (command bar searches the whole store), AR-07 (Delete has Undo, Clear leaves the disk), AR-08 (a shorter Keep time asks first), AR-09 (no private or deleted profile's tabs), AR-11 (undo step, failed safety backup, private windows, deleted profiles, unreadable files, D33), SV-19 and SV-24 (a split restores from the Archive as one unit). - A test comment no longer names FL-22, which it doesn't test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 5097f32c-d166-42b0-8808-6ddbdbb138ac) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…long (re-review R1) Undoing a Restore Data archives the tabs it brought back, as new entries. An older undo step (Close Tab, Delete Folder) then brought the tab back but removed only the entry its own close made, so the Archive still listed the open tab, and restoring that row opened its page twice. restoreClosed and the Delete Folder undo now drop every entry of a returning tab. Two unit tests run Restore Data → ⌘Z → ⌘Z after a close and after a folder delete. Both fail without the fix (an entry left in state and in the store). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 87ff3a20-b738-4469-849d-8d309727c188) |
…unit tests; first-open budget 250 ms (re-review R2) The e2e first-open test passed whether or not the idle wait worked, and its 100 ms budget failed on every run at load 30-44 (127-165 ms; 66-77 ms quiet). - New archive-library-idle.test.ts drives LibraryHost's idle checks with fake timers: the view waits while the command bar is open or a page loads, and is made at the first check after, or after the last check anyway. With the busy check taken out, two of its three tests fail (the view is made at 5 s). - The e2e budget is 250 ms x FRAME_SLACK: about 1.5 times the slowest loaded run, and half the 490 ms cold open, so it still fails without the view made ahead. FL-24 (P2) sets no number for the first open. - library.ts exports IDLE_RETRY_MS and IDLE_CHECKS for the test; no behaviour change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 49753e48-ce62-4977-8d74-54ca296415a3) |
… came from The builder's 66-77 ms has no recorded load, so it isn't called quiet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: c6dd44c1-c63b-4746-8d73-e812ddc49d24) |
…ta, comes back once with no Archive entry (fix check M1)
R1 changed three call sites to unarchive(); the split one (placedByUnit) had no
test. With only that site back to removing the close's own entry, this test
fails: each pane is open but still has an entry in state and in the store
(expected { open: true, rows: +0, ... } to match object { open: true,
archived: 0, stored: 0 }).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: d29f5b86-44fb-488c-b150-34412bf4b24f) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: bbabb192-8448-4924-a78f-d2cfa5d11101) |
docs/feature-status.json keeps this branch's TD-08 entry and archive's AR-01 to AR-11 entries; FEATURES.md is regenerated, not merged by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts, each resolved keeping both sides: - src/main/tabs/runtime.ts: load() keeps chrome's page-open handling and takes main's guard for contents destroyed mid-restore. - src/shared/rpc.ts: RendererView lists chrome's views (sidebar, tools, prompt, loading, link) and the archive's library view. - src/renderer/src/main.tsx: boot() renders chrome's views and the Library. - docs/feature-status.json: chrome's SB-11/12/14/19/20/21 notes, main's SB-09 note (the Library button is built). - FEATURES.md: regenerated with scripts/features.mjs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts, both sides kept: - src/shared/state.ts, src/shared/defaults.ts: the settings lane's hardwareAcceleration, secureDns, updateFeedUrl, updateChecks (and lastRunVersion, whatsNew) beside the archive's librarySection and archiveKeepDays. - src/shared/rpc.ts: RendererView has 'library' and 'onboarding'. - src/main/menu.ts: Help keeps Orbit Help, Report a Bug…, Release Notes and Troubleshooting ▸ Copy Build Info, and gains Restore Data… (AR-11) as a direct item, where archive.spec looks. - FEATURES.md: regenerated with scripts/features.mjs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: docs/feature-status.json (union: DL-09 from main, DL-01 from this lane); FEATURES.md regenerated with node scripts/features.mjs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Archive, the Library, browsing history and sidebar backups, built from
spec/archive.md(AR-01 to AR-11) andspec/sidebar.mdSB-09. Branched frommainatcc43e90.mainata8478c4(PRs #9, #10, #11 and #13) is merged in (33ff075).Built
PeekLayer.tsx). What it needs is ready:overlay.archiveEntryand thearchive.restorePreviewcommand.da3d778).9cf7c16).4b4f3dd).ce3092d).Decisions where the spec was open
userData/backups, written atomically.Review first
planRestoreandapplyRestoreinsrc/main/archive/snapshot.ts: removing Spaces added since the backup, and archiving tabs opened since.onSidebarRestoredhook in theTabOpsconstructor (src/main/tabs/ops.ts), which goes through a module-level listener ininbox.ts. A second ⌘Z puts the restore back again (a toggle), rather than ⌘⇧Z redoing it.src/main/archive/preview.ts: keeping a closed preview from adding a second Archive entry is heuristic.state.ts,defaults.ts,persist.ts,rpc.ts,actions.ts,global.css,main.tsx,SpaceBar.tsx,Toasts.tsx,menu.ts, the command bar'ssearch.tsandrank.ts, tabsops.ts, andundo.ts(clear()now also clears redo).Tests
tests/unit/archive-*.test.ts.tests/e2e/archive.spec.tshas 19 tests.73bdf11(229/230; its one failure, SV-17/SV-19, was the race PR Main-process exceptions no longer block quitting (D28): the check, the strip's fade timer, two test races #11 fixed), and the fix round's at6f54bec(264 passed, 2 skipped, 0 failed).FEATURES.mdis regenerated on the merge head.Review rounds
reviews/lane-archive.md): request changes, 5 must-fixes and 12 follow-ups.6f54bec,reviews/lane-archive-fix-report.md):6f54bec: 264 passed, 2 skipped, 0 failed.reviews/lane-archive.md): approve with 2 fixes. The lead made both (D18):60c4175): after undoing past a Restore Data, a tab brought back by an older undo also stayed in the Archive, so restoring that row opened the page twice. A tab that comes back now drops every Archive entry of it. Two tests inarchive-backups.test.ts(undoing a close, undoing a folder delete) fail without the fix.c8288ff,ac59a22): F10's first-open test didn't prove the idle wait, and its 100 ms budget failed at load 30–44.archive-library-idle.test.tsdrives the Library's idle checks with fake timers. Two of its three tests fail without the busy check.FRAME_SLACK, half the 490 ms cold open, so it still fails without the view made ahead.ops.ts, a split closed as one unit) had no test that failed without it; the lead added one in472862f, which fails without the fix. R1 and R2 hold, and each of 8 mutations of the idle wait fails at least one of the three idle tests.Merge gate (D42)
Run on the merge head
87dd757in the lane's worktree, on the Linux VPS. GitHub Actions is off (D42).media.spec.ts:1075(MD-12): with three media tabs playing, the floating player didn't settle within 10 s.split.spec.ts:1006(SV-17/SV-26): no view placement was recorded during a pane's close.media.spec.ts:1485(MD-07): main loggedTypeError: timer._onTimeout is not a functionas Orbit quit.app.close()callsapp.quit()through the inspector, and the inspector can run that call part-way through other main-process code.persistence.flush()clears the state file's next write), so Node then calls a cleared timer.🤖 Generated with Claude Code
Note
High Risk
Changes core data paths (archive log, backups, sidebar restore/undo) and cross-cutting behavior (splits, profiles, Peek); mistakes could lose or mis-restore tabs and sidebar state.
Overview
This PR replaces the archive stub with a full Archive / Library lane: closed tabs are mirrored from
state.archiveinto a durable JSONL store (ArchiveStore) with back/forward history, search, delete-with-undo, retention, and profile-scoped clear.Library opens as a dedicated WebContentsView over the page area (
LibraryHost), with commands for Archive, History, and sidebar backups (scheduled JSON snapshots + Restore Data with undo on the sidebar stack). Row preview uses Peek over the Library;ArchivePreviewssuppresses duplicate archive entries when a preview closes.Restore brings tabs (and split panes as one unit) back to Today with routing rules and profile-safe history. Command bar ranking now searches the full archive source and boosts very recent closes; macOS menus gain Recently Closed and Archive actions.
Feature checklist totals and notes are regenerated (
FEATURES.md,docs/feature-status.json).Reviewed by Cursor Bugbot for commit 87dd757. Bugbot is set up for automated code reviews on this repo. Configure here.