Skip to content

Performance optimizations across core data and rendering layers#20

Merged
max4c merged 47 commits intomainfrom
dev
Apr 8, 2026
Merged

Performance optimizations across core data and rendering layers#20
max4c merged 47 commits intomainfrom
dev

Conversation

@max4c
Copy link
Copy Markdown
Owner

@max4c max4c commented Apr 8, 2026

Summary

  • Row deserialization ~17% faster (single-pass YAML unescape, inline array parsing)
  • Database loading ~20% faster (merged schema detection, regex-free icon parsing)
  • Block document init ~20% faster (eliminated redundant content scan via parseWithFlags)
  • Cached JSONDecoder and canonical-date fast path in DatabaseDateValue.decode()
  • Single-pass IndexManager rebuild, pagination without extra Array copies in QueryEngine
  • ArraySlice-based child block parsing in MarkdownBlockParser
  • Fix pre-existing BrowserFeatureTests compilation error (removed deleted railPinned reference)

Test plan

  • All 22 performance tests pass with 0 failures
  • Build succeeds with no new warnings
  • Benchmarked against original baselines (database_load_100: 7.3ms→5.8ms, row_deserialize_100: 4.6ms→3.8ms, block_document_init_50: 0.3ms→0.24ms)
  • /simplify review pass completed — fixed SwiftUI identity bug, heap allocation in hot path, thread safety annotation, unified childEnd patterns

🤖 Generated with Claude Code

max4c and others added 30 commits April 6, 2026 23:08
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add leading padding to sidebar so rail doesn't overlay content
- Show workspace sidebar only on document panes (not browser/terminal)
- Wire WorkspaceContextualSidebarView for the workspace rail icon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…debar

- Move rail padding to entire HStack so tabs don't overlap with rail
- Use .tint() for calendar color picker (macOS context menus strip foregroundStyle)
- Show folders as expandable tree items instead of flattening into parent

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 1: Replace sidebarOpen + contextualSidebarLeaf with activeSidebarPanel
enum. Rail icons for mail/calendar/workspace now toggle their panel in
the shared sidebar slot instead of creating panes.

Phase 2: Move NavigationRailView from ZStack overlay (zIndex 3) to first
child of the HStack. Rail width animates via frame(width:) + clipped()
instead of offset. Removes the padding(.leading, railWidth) hack.

Phase 3: Add sliver mode — when browser/terminal is in layout, rail
collapses to 4px bar. Hover the sliver to summon full rail.

Phase 4: Remove dead code — sidebarPeekOverlay, sidebarPeekEdgeHotspot,
sidebarToggleOverlay, SidebarPeekState refs, contextualSidebarLeaf,
paneUsesContextualSidebar, focusedPaneSuppressesSidebar.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the default "Bugbook" folder is mostly empty but a sibling like
"Bugbook 3" has real content (common iCloud conflict duplication), the
resolver now picks the workspace with the most .md files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Hide underscore-prefixed files (_context.md etc) from sidebar tree
- Remove folder icons — use doc.text for all items (Notion-style pages)
- Unread emails: use full Color.primary (black/white) not opacity
- Tab bar: remove ScrollView, tabs compress to fit instead of scrolling
- Browser: remove quick launch suggestion buttons from new tab page

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add windowChromeTopInset padding to tab bar so tabs clear the
title bar area in fullSizeContentView mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previous logic returned the default "Bugbook" folder early if it had
>2 .md files, but those were all database row files. Now always scans
all Bugbook* siblings and picks the one with the most user-authored
.md files (excluding databases/, Daily Notes/, _-prefixed files).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…se thread

- Sidebar: clicking a folder opens it as a page (hover chevron still expands)
- Mail: unread uses .primary/.secondary (not opacity), much more readable
- Mail: added X close button on thread detail toolbar
- Calendar: replaced checkmark with eye/eye.slash icon, only shows on hover

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…er cal sources

- Replace HSplitView with full-screen thread view. Back chevron returns
  to inbox list (like Gmail web).
- Unread text uses NSColor.labelColor (guaranteed dark in light mode),
  read text uses tertiaryLabelColor for clear contrast.
- Calendar source rows: tighter vertical spacing (3pt), smaller eye
  icon (caption size), tertiary color.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Tab bar: reduce leading padding when sidebar is open (traffic lights
  are in sidebar area, no need for 70pt gap)
- Mail: sender always labelColor (black in light mode), subject uses
  secondaryLabelColor for read. Snippet and date also more visible.
- WorkspaceResolver: localFallbackWorkspacePath now resolves symlinks
  and scans sibling workspaces, so "Bugbook 3" is picked on first
  launch without waiting for async iCloud upgrade.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- initializeWorkspace: always use defaultWorkspacePath() instead of
  restoring stale recentWorkspaces entry. Ensures Bugbook 3 is picked.
- Rail: mail/calendar icons now open the pane AND toggle the sidebar
  panel, so clicking Calendar shows the full calendar view.
- Mail: sender 14px bold (unread) / medium (read), always labelColor.
  Subject 13px semibold (unread) / regular (read), always labelColor.
  Matches Gmail's text weight hierarchy.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…space

- Mail thread takes full pane (filter tabs hidden when viewing thread)
- Auto mark-as-read when opening a thread
- Added compose button to batch toolbar
- initializeWorkspace uses blocking iCloud lookup to ensure richest
  workspace (Bugbook 3) is picked on first render

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Hide AiThreads, assets, Comparisons, covers, icons, Settings,
  WorkspaceLayouts, Daily Notes 2 from sidebar file tree
- Close mail sidebar when opening a thread so it gets full width
- Tabs compress from 190pt down to 60pt min when many are open
- Removed duplicate compose button from batch toolbar (already in sidebar)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ab + padding

- Don't auto-close sidebar when opening thread
- Thread content fills full width with maxWidth .infinity
- Added Gmail-style Compose button above mailbox list in sidebar
- Plus button gets horizontal padding for right edge spacing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New-message compose now overlays as a 450×520 floating card anchored to the bottom-right of the mail pane instead of replacing it in a split view. Reply compose (threadId != nil) still renders inline in the thread.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Tapping an event now sets selectedCalendarEvent and opens the sidebar instead of navigating to a page
- Sidebar shows title, formatted date/time, calendar source, location, notes, attendees, and a "Create Meeting Notes" button
- Added greedy column-assignment overlap layout to both CalendarDayView and CalendarWeekView so concurrent events render side-by-side

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Compose new message now shows as a floating 450x520 card at bottom-right
of the inbox, overlaying the thread list. Thread view remains full-screen.
Reply compose still shows inline in the thread.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Compose button in sidebar uses accentColor fill with white text,
  full width, centered — matches Bugbook design language
- Thread detail pane gets explicit fallbackEditorBg background so
  empty space below short emails matches the pane color

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- MailHTMLView frame: minHeight 500, maxHeight .infinity so email
  content fills available vertical space instead of cramped 220pt
- Settings sidebar: increased padding between back button and header

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace rail + shared contextual slot with unified two-zone sidebar
(fixed zone with icons/favorites, contextual zone driven by focused pane).
Sidebar collapses to zero with Cmd+Period, hover-reveals when collapsed.
Compact Safari-style browser tabs with inline URL field.
Mail forward support and bottom action buttons (Reply, Reply all, Forward).
Remove split pane from slash commands. Fix Cmd+K from terminal pane.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
max4c and others added 17 commits April 7, 2026 22:53
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Container color tokens (grout, card, pill, sidebar active, URL bar)
- Set window background to grout color
- Sidebar uses grout bg, no border (flush with window)
- Pill-style workspace tabs (radius 8, active fill, no ConnectedTabShape)
- Content area wrapped with 6px grout padding + 10px card corners
- Split panes render as independent cards with 6px gaps
- Browser chrome uses card bg, URL bar uses tinted bg, 0.5px separator
- Drop target highlight uses card radius

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds Cmd+F shortcut via NSEvent monitor, per-pane find bar with
match count, Enter/Shift+Enter navigation, and yellow highlight
on all matching text across blocks. Active match gets distinct color.

Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Blue focus indicator at top of chrome bar now only shows when
  multiple panes exist (isOnlyPane check)
- Removed outer card bg/clip from content wrapper so each PaneContentView
  renders as its own independent rounded card with grout gaps between them
- Settings and Graph views get card treatment individually
- Chrome bar bg uses Container.cardBg

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove 0.5px separator at bottom of chrome bar (caused visual seam)
- Split divider now matches Container.groutGap (6px) instead of 8px
- Divider is transparent (grout shows through) instead of visible line
- Reverted HStack/VStack spacing to 0 since divider provides the gap

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fallbackEditorBg dark mode now matches Container.cardBg (#232323)
so chrome bar and content have identical backgrounds. PaneContentView
gets explicit Container.cardBg background behind the clip shape.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Grout/sidebar: #232323 (lighter), Card/panes: #161616 (darker).
Active pill and editor bg updated to match new card color.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Row deserialization ~17% faster (single-pass YAML unescape, inline array
parsing), database loading ~20% faster (merged schema detection, manual
icon parse replacing regex), block document init ~20% faster (eliminated
redundant content scan via parseWithFlags). Additional wins: cached
JSONDecoder and canonical-date fast path in DatabaseDateValue.decode(),
single-pass IndexManager rebuild, pagination without extra Array copies in
QueryEngine, ArraySlice-based child block parsing in MarkdownBlockParser.

Fix pre-existing BrowserFeatureTests compilation error (removed reference
to deleted railPinned property).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@max4c max4c merged commit f5db4ed into main Apr 8, 2026
1 check failed
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8d60aee42d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if offset > 0 {
sorted = Array(sorted.dropFirst(offset))
}
let startIdx = min(offset, totalCount)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Clamp negative offsets before slicing query results

Query.offset is a plain Int? with no validation, so callers can pass a negative value; with the new pagination path, startIdx becomes negative via min(offset, totalCount) and then Array(sorted[startIdx..<endIdx]) can trap at runtime. Before this commit, negative offsets were effectively ignored (dropFirst only ran when offset > 0), so this introduces a crash path for malformed or user-provided query input.

Useful? React with 👍 / 👎.

// Handles iCloud conflict duplication ("Bugbook 2", "Bugbook 3", etc.)
if let siblings = try? fm.contentsOfDirectory(atPath: documentsURL.path) {
let candidates = siblings
.filter { $0.hasPrefix(defaultFolderName) }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict workspace sibling matching to conflict suffixes

Filtering candidates with hasPrefix(defaultFolderName) will also match unrelated folders like Bugbook Backup/Bugbook-old, so the resolver can silently pick an archive folder just because it has more .md files. That risks opening the wrong workspace in normal setups where users keep backups beside the primary folder; the match should be limited to the canonical folder and explicit conflict variants (for example Bugbook, Bugbook 2, Bugbook 3).

Useful? React with 👍 / 👎.

Comment on lines 362 to +366
if colLine.trimmingCharacters(in: .whitespaces) == "<!-- /columns -->" {
// Parse final column
if currentColumnStart < i {
var columnBlocks = parseLines(lines[currentColumnStart..<i])
for j in columnBlocks.indices {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve last column when <!-- /columns --> is missing

The final column is now flushed only inside the <!-- /columns --> branch, so if a columns block is unterminated (common while editing or in partially-synced files), the loop exits at EOF and drops all trailing column content. The previous implementation parsed the remaining buffered lines after the loop, so this change regresses parser resilience and can make valid content disappear in the editor until the closing marker is restored.

Useful? React with 👍 / 👎.

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