Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
20892ec
Mail UI: unread indicator + full-height thread detail
max4c Apr 7, 2026
a29a7f4
Shell: fix rail/sidebar overlap and suppress sidebar on browser/terminal
max4c Apr 7, 2026
9708f71
Calendar UI: 2-letter day headers + source color picker
max4c Apr 7, 2026
741aaca
Merge branch 'worktree-agent-a452f205' into dev
max4c Apr 7, 2026
7422b0a
Add workspace rail item to navigation
max4c Apr 7, 2026
12b4d31
Merge branch 'worktree-agent-a2b310f2' into dev
max4c Apr 7, 2026
648a144
Fix rail/content overlap, calendar colors, and show folder tree in si…
max4c Apr 7, 2026
e776c2c
Harbor Desktop: refactor rail from overlay to inline HStack layout
max4c Apr 7, 2026
a8fa43c
WorkspaceResolver: prefer richest iCloud workspace when duplicates exist
max4c Apr 7, 2026
fee402f
UI polish: hide _context files, remove folder icons, fix tabs and mail
max4c Apr 7, 2026
9b71514
Fix tab bar overlapping window traffic lights
max4c Apr 7, 2026
f4a7fd4
WorkspaceResolver: always pick richest iCloud workspace, exclude db rows
max4c Apr 7, 2026
1811d92
UI fixes: clickable folders, mail readability, calendar eye icon, clo…
max4c Apr 7, 2026
775811c
Mail: full-screen thread with back button, fix unread contrast, tight…
max4c Apr 7, 2026
b3a0e10
Tab bar: remove top gap, align tabs beside traffic lights
max4c Apr 7, 2026
92af8e7
Tab bar: add 70pt leading padding to clear traffic lights
max4c Apr 7, 2026
ce2f3b9
Fix tab padding with sidebar, mail text visibility, workspace resolver
max4c Apr 7, 2026
b0b1f73
Fix workspace init, rail opens panes + sidebar, bolder mail text
max4c Apr 7, 2026
f11ec70
Full-screen thread view, mark-as-read, compose btn, force iCloud work…
max4c Apr 7, 2026
798f814
Hide junk folders, full-width mail thread, compress tabs
max4c Apr 7, 2026
8182273
Mail: keep sidebar open, fill thread space, compose btn in sidebar, t…
max4c Apr 7, 2026
8e8b4e3
Mail: floating compose popup
max4c Apr 7, 2026
0f9c3bf
Calendar: event details in sidebar, overlapping events side-by-side
max4c Apr 7, 2026
5319b60
Mail: floating compose popup overlay on inbox list
max4c Apr 7, 2026
1014f79
Merge branch 'worktree-agent-ad2e1df9' into dev
max4c Apr 7, 2026
7627a22
Mail: accent compose button, thread background fill
max4c Apr 7, 2026
66245e9
Settings: add back-to-app arrow button above settings sidebar
max4c Apr 7, 2026
e7ba002
Mail HTML expands to fill space, settings back-to-app padding
max4c Apr 7, 2026
52ae330
Design System v2: unified sidebar, compact browser tabs, mail actions
max4c Apr 8, 2026
d8b9f0c
Mail: dim read threads with secondary label color for contrast
max4c Apr 8, 2026
8a07fb4
Calendar: use source color for event rendering in week and month views
max4c Apr 8, 2026
2bb0ae2
Browser: remove inner tabs, full-width URL bar
max4c Apr 8, 2026
df6daac
Merge branch 'worktree-agent-a805dd2b' into dev
max4c Apr 8, 2026
1f81dd2
Meetings: focus on previous meetings, compact record button
max4c Apr 8, 2026
c4f9ae5
Merge branch 'worktree-agent-a805dd2b' into dev
max4c Apr 8, 2026
8becb9a
Calendar: recurring events with RRULE + drag-to-create time blocking
max4c Apr 8, 2026
21a9ab6
Calendar: recurring events with RRULE + drag-to-create time blocking
max4c Apr 8, 2026
ce6456c
Modular container system: cards on grout surface, pill tabs
max4c Apr 8, 2026
c8432ae
Cmd+F find-in-page: search bar, highlight, match navigation
max4c Apr 8, 2026
a61fed8
Fix: blue focus line only in multi-pane, independent card per pane
max4c Apr 8, 2026
c7c7aa5
Fix: add left grout padding when sidebar is collapsed
max4c Apr 8, 2026
cf588d4
Tab pill active color matches card background
max4c Apr 8, 2026
8b2279b
Fix: remove chrome bar bottom line, match split gap to grout size
max4c Apr 8, 2026
49dcb8a
Fix: unify editor bg with card bg, add explicit card background to panes
max4c Apr 8, 2026
b95d086
Dark mode: swap grout and card colors — darker panes, lighter frame
max4c Apr 8, 2026
8d60aee
Performance optimizations across core data and rendering layers
max4c Apr 8, 2026
635f488
Merge origin/main into dev — resolve pbxproj conflict (accept main)
max4c Apr 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 12 additions & 41 deletions .go/progress.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,12 @@
# Go Run — 2026-04-03

Started: 11:00 PM
Focus: Bugbook iOS app — full parity with desktop

## Completed (9 tasks, all verified via build)

- [x] Rich block editor — headings, lists, tasks, code, blockquotes, images, formatting toolbar
- [x] Database table view — all field types rendered, swipe to delete, row navigation
- [x] Database kanban view — horizontal scroll columns by select property, cards with badges
- [x] Database calendar view — month grid, day detail, date property rows
- [x] View management — view tabs, sort/filter UI, column visibility, grouping, new view creation
- [x] Full property editor — relation picker, rich dates, formula/lookup/rollup, URL/email actions
- [x] Schema management — add/rename/delete properties, select options with colors
- [x] Quick capture — text, photo library, camera, quick action pills for tasks/lists
- [x] Navigation polish — 5-tab layout (Today/Notes/Databases/Agents/Settings), settings view

## Files Created
- `Sources/BugbookMobile/Views/MobileBlockEditorView.swift` — Block editor + toolbar
- `Sources/BugbookMobile/ViewModels/MobileDatabaseViewState.swift` — Shared database state
- `Sources/BugbookMobile/Views/MobileFilterSortView.swift` — Filter/sort/view options
- `Sources/BugbookMobile/Views/MobileSchemaEditorView.swift` — Schema + property editor
- `Sources/BugbookMobile/Views/MobileSettingsView.swift` — Settings view

## Files Modified
- `MobileDatabaseView.swift` — Complete rewrite with table/kanban/calendar views
- `MobileDatabaseRowView.swift` — Full property editor, relation picker, body editor
- `MobilePageEditorView.swift` — Block editor integration
- `MobileRootView.swift` — 5-tab navigation with settings
- `MobileTodayView.swift` — Quick capture with photo/camera, action pills
- `ios/project.yml` — Camera/photo library permissions
- `ios/BugbookMobile.xcodeproj/` — Regenerated

## Build Status
BugbookMobile target: PASSING (0 errors, 0 warnings)

## How to Test
1. Open `ios/BugbookMobile.xcodeproj` in Xcode
2. Select an iPhone simulator or physical device
3. Build and run
4. Verify iCloud sync by checking if workspace matches desktop app
# Go Run — 2026-04-07
Started: 10:43 PM
Time budget: 8h

## Queue (7 tickets)
1. Mail: read/unread contrast
2. Meetings: focus history, shrink record button
3. Calendar: source color → event color
4. Calendar: recurring events + time blocking
5. Browser: remove tabs, full-width URL
6. Cmd+F in-page search
7. Modular container system
19 changes: 7 additions & 12 deletions .go/queue.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
[
{"position": 1, "row_id": "row_wtl5f9", "name": "Ship Bugbook as standalone .app binary", "files": ["macos/Bugbook.xcodeproj/project.pbxproj", "macos/project.yml", "Package.swift", "Sources/Bugbook/App/BugbookApp.swift"], "worker": "claude", "note": "Complex build system work — needs xcode project investigation, GhosttyKit resolution, signing. Claude agent better suited."},
{"position": 2, "row_id": "row_xsiof2", "name": "Gateway redesign", "files": ["Sources/Bugbook/Views/Gateway/GatewayView.swift", "Sources/Bugbook/Views/ContentView.swift"], "worker": "codex", "note": "Has full design spec in Bugbook. Progressive disclosure, greeting+date, quick nav, todays focus, recent activity."},
{"position": 3, "row_id": "row_wcsgow", "name": "Rename Meetings → Meetings", "files": ["Sources/Bugbook/Views/Meetings/MeetingsView.swift", "Sources/Bugbook/Views/Sidebar/SidebarView.swift"], "worker": "codex", "note": "Simple rename. Sidebar + view title → Meetings. Keep chat button."},
{"position": 4, "row_id": "row_k1pfpn", "name": "Meeting padding fix", "files": ["Sources/Bugbook/Views/Editor/MeetingBlockView.swift"], "worker": "codex", "note": "Reduce title-to-notes gap to 4pt max."},
{"position": 5, "row_id": "row_fnmxx9", "name": "Callout block fix", "files": ["Sources/Bugbook/Views/Editor/CalloutBlockView.swift", "Sources/Bugbook/Views/Editor/BlockCellView.swift"], "worker": "codex", "note": "Remove left border. Just rounded gray bg + icon. Match TOC styling."},
{"position": 6, "row_id": "row_u9mndd", "name": "Outline/TOC fix", "files": ["Sources/Bugbook/Views/Editor/OutlineBlockView.swift", "Sources/Bugbook/Views/Editor/BlockCellView.swift"], "worker": "codex", "note": "Grey text links not bullets/stars. Match callout container. Click scrolls to heading."},
{"position": 7, "row_id": "row_b7h2vl", "name": "Heading toggles behavior", "files": ["Sources/Bugbook/Views/Editor/BlockCellView.swift", "Sources/Bugbook/Models/BlockDocument.swift", "Sources/BugbookCLI/PageBlockHelpers.swift"], "worker": "claude", "note": "Complex: Cmd+Shift+Enter toggle, Enter exits, auto-nest smaller headings. Needs multi-file reasoning."},
{"position": 8, "row_id": "row_srmgse", "name": "TableBlockView fix", "files": ["Sources/Bugbook/Views/Editor/TableBlockView.swift"], "worker": "codex", "note": "Attempt 3. Fix grip dots duplication, alignment, flush with content area."},
{"position": 9, "row_id": "row_0lsztg", "name": "Kebab menu fix", "files": ["Sources/Bugbook/Views/Database/SelectOptionViews.swift"], "worker": "codex", "note": "Larger hit area, popover positioning beside not on top."},
{"position": 10, "row_id": "row_qm7iyh", "name": "Chat redesign", "files": ["Sources/Bugbook/Views/AI/AiSidePanelView.swift", "Sources/Bugbook/Views/AI/NotesChatView.swift", "Sources/Bugbook/Views/ContentView.swift", "Sources/Bugbook/Views/Sidebar/SidebarView.swift"], "worker": "codex", "note": "Rename Ask AI → Chat, remove X, Cmd+I opens sidebar panel."},
{"position": 11, "row_id": "row_dimm5g", "name": "Mention picker link styling", "files": ["Sources/Bugbook/Views/Editor/BlockTextView.swift", "Sources/Bugbook/Views/Editor/WikiLinkView.swift"], "worker": "codex", "note": "Style @[[Page Name]] as visible link (pill or colored text), clickable."},
{"position": 12, "row_id": "row_uqw8vz", "name": "Cmd+K search navigation fix", "files": ["Sources/Bugbook/Views/ContentView.swift", "Sources/Bugbook/Views/Components/CommandPaletteView.swift"], "worker": "claude", "note": "Attempt 3. navigateToEntryInPane works from sidebar but not command palette. Deep nav system issue."}
{"position": 1, "row_id": "row_x1g8d6", "name": "Mail: read/unread contrast", "files": ["Sources/Bugbook/Views/Mail/MailPaneView.swift"]},
{"position": 2, "row_id": "row_9d6uuv", "name": "Meetings: focus history, shrink record button", "files": ["Sources/Bugbook/Views/Meetings/MeetingsView.swift"]},
{"position": 3, "row_id": "row_zy9ouz", "name": "Calendar: source color → event color", "files": ["Sources/Bugbook/Views/Calendar/CalendarWeekView.swift", "Sources/Bugbook/Views/Calendar/CalendarMonthView.swift", "Sources/Bugbook/Views/Calendar/CalendarDayView.swift", "Sources/Bugbook/Services/CalendarService.swift"]},
{"position": 4, "row_id": "row_omf7j6", "name": "Calendar: recurring events + time blocking", "files": ["Sources/Bugbook/Views/Calendar/WorkspaceCalendarView.swift", "Sources/Bugbook/Services/CalendarService.swift", "Sources/Bugbook/Views/Calendar/CalendarWeekView.swift", "Sources/Bugbook/Views/Calendar/CalendarDayView.swift"]},
{"position": 5, "row_id": "row_9fg5sv", "name": "Browser: remove tabs, full-width URL", "files": ["Sources/Bugbook/Views/Browser/BrowserPaneView.swift"]},
{"position": 6, "row_id": "row_ncrdg3", "name": "Cmd+F in-page search", "files": ["Sources/Bugbook/Views/ContentView.swift"]},
{"position": 7, "row_id": "row_2hvac7", "name": "Modular container system", "files": ["Sources/Bugbook/Views/ContentView.swift", "Sources/Bugbook/Views/Shell/ShellNavigationViews.swift", "Sources/Bugbook/Views/Components/WorkspaceTabBar.swift", "Sources/Bugbook/Views/Browser/BrowserPaneView.swift", "Sources/Bugbook/Views/Panes/PaneTreeView.swift", "Sources/Bugbook/Views/Panes/PaneContentView.swift", "Sources/Bugbook/Extensions/DesignTokens.swift", "Sources/Bugbook/App/BugbookApp.swift"]}
]
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<key>BugbookCLITests.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>4</integer>
<integer>3</integer>
</dict>
<key>BugbookCore.xcscheme_^#shared#^_</key>
<dict>
Expand All @@ -32,12 +32,12 @@
<key>BugbookCoreTests.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
<integer>4</integer>
</dict>
<key>BugbookMCPSpike.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
<integer>1</integer>
</dict>
<key>BugbookMobile.xcscheme_^#shared#^_</key>
<dict>
Expand Down
26 changes: 25 additions & 1 deletion Sources/Bugbook/App/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,35 @@ struct MCPServerInfo: Identifiable {
var id: String { name }
}

/// What the sidebar's contextual zone should display, derived from the selected pane type.
enum SidebarContextType: Equatable {
case mail
case calendar
case workspace // editor pages — shows file tree
case none // terminal, browser — contextual zone collapses

static func from(_ content: PaneContent) -> SidebarContextType {
switch content {
case .terminal: return .none
case .document(let file):
if file.isMail { return .mail }
if file.isCalendar { return .calendar }
if file.isBrowser { return .none }
return .workspace
}
}
}

@MainActor
@Observable class AppState {
var openTabs: [OpenFile] = []
var activeTabIndex: Int = 0
var sidebarOpen: Bool = false

// Unified sidebar state
var sidebarVisible: Bool = true
var sidebarWidth: CGFloat = 200
/// Contextual zone type — follows the focused pane, always.
var sidebarContextType: SidebarContextType = .workspace
var workspacePath: String?
var fileTree: [FileEntry] = []
var sidebarReferences: [FileEntry] = []
Expand Down
26 changes: 23 additions & 3 deletions Sources/Bugbook/App/BugbookApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ struct BugbookApp: App {
}

CommandGroup(after: .toolbar) {
Button("Toggle Rail") {
Button("Toggle Sidebar") {
NotificationCenter.default.post(name: .toggleSidebar, object: nil)
}
.keyboardShortcut("\\", modifiers: .command)
.keyboardShortcut(".", modifiers: .command)

Divider()

Expand All @@ -84,7 +84,7 @@ struct BugbookApp: App {
.keyboardShortcut("]", modifiers: .command)

Button("Find in Page") {
NotificationCenter.default.post(name: .findInPane, object: nil)
NotificationCenter.default.post(name: .findInPage, object: nil)
}
.keyboardShortcut("f")

Expand Down Expand Up @@ -404,6 +404,24 @@ class AppDelegate: NSObject, NSApplicationDelegate {
NotificationCenter.default.post(name: .focusPaneByIndex, object: index)
return nil
}

// Cmd+K — intercept before native NSView responders (e.g. Ghostty terminal)
// so the command palette always opens regardless of which view has focus.
NSEvent.addLocalMonitorForEvents(matching: .keyDown) { event in
let flags = event.modifierFlags.intersection(.deviceIndependentFlagsMask)
guard flags == .command, event.charactersIgnoringModifiers == "k" else { return event }
NotificationCenter.default.post(name: .quickOpen, object: nil)
return nil
}

// Cmd+F should route through the app-level notification layer even when
// an editor NSTextView or terminal responder currently has focus.
NSEvent.addLocalMonitorForEvents(matching: .keyDown) { event in
let flags = event.modifierFlags.intersection(.deviceIndependentFlagsMask)
guard flags == .command, event.charactersIgnoringModifiers == "f" else { return event }
NotificationCenter.default.post(name: .findInPage, object: nil)
return nil
}
}

@objc private func windowDidBecomeKey(_ notification: Notification) {
Expand All @@ -419,6 +437,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
window.title = "Bugbook"
window.styleMask.insert(.fullSizeContentView)
window.isMovableByWindowBackground = true
window.backgroundColor = NSColor(Container.groutBg)
}
}

Expand Down Expand Up @@ -461,6 +480,7 @@ extension Notification.Name {
static let movePageToDir = Notification.Name("movePageToDir")
static let addToSidebar = Notification.Name("addToSidebar")

static let findInPage = Notification.Name("findInPage")
static let findInPane = Notification.Name("findInPane")

// Pane/Workspace system
Expand Down
4 changes: 2 additions & 2 deletions Sources/Bugbook/Extensions/Color+Theme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ extension Color {
// Chrome — sidebar, tab bar, breadcrumbs
static let fallbackSidebarBg = Color(light: Color(hex: "f8f8f7"), dark: Color(hex: "202020"))
static let fallbackTabBarBg = Color(light: Color(hex: "f8f8f7"), dark: Color(hex: "202020"))
// Canvas — editor, active tab
static let fallbackEditorBg = Color(light: .white, dark: Color(hex: "191919"))
// Canvas — editor, active tab (matches Container.cardBg)
static let fallbackEditorBg = Color(light: .white, dark: Color(hex: "161616"))

// Semantic surfaces
static let fallbackCardBg = Color(light: .white, dark: Color(hex: "202020"))
Expand Down
31 changes: 31 additions & 0 deletions Sources/Bugbook/Extensions/DesignTokens.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,37 @@ enum Typography {
static let title: CGFloat = 28
}

// MARK: - Container System (Grout + Card)

enum Container {
/// Window/grout background — the surface cards float on
static let groutBg = Color(light: Color(hex: "e2e0db"), dark: Color(hex: "232323"))

/// Content card background
static let cardBg = Color(light: .white, dark: Color(hex: "161616"))

/// Sidebar active item highlight
static let sidebarActiveBg = Color(light: Color(hex: "d6d4cf"), dark: Color(hex: "2a2a2a"))

/// Workspace pill tab — active fill (matches card bg so it feels connected)
static let pillActiveBg = Color(light: .white, dark: Color(hex: "161616"))

/// Workspace pill tab — inactive text
static let pillInactiveText = Color(light: Color(hex: "888888"), dark: Color(hex: "555555"))

/// Browser URL bar background (inside card)
static let urlBarBg = Color(light: Color(hex: "f5f3ef"), dark: Color(hex: "2e2e2e"))

/// Gap between cards and around content area
static let groutGap: CGFloat = 6

/// Card corner radius
static let cardRadius: CGFloat = 10

/// Pill tab corner radius
static let pillRadius: CGFloat = 8
}

// MARK: - Corner Radii

enum Radius {
Expand Down
Loading
Loading