You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CLAUDE.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,10 +15,10 @@ Always rebuild after code changes so the user can test immediately. Use `killall
15
15
16
16
## Architecture
17
17
18
-
-**AppState** (`App/AppState.swift`): Central `@MainActor @Observable` model. Owns all notification data, selection, search, auth, background refresh. ~1200 lines. All UI state derives from here.
18
+
-**AppState** (`App/AppState.swift`): Central `@MainActor @Observable` model. Owns all notification data, selection, search, auth, and background refresh. All UI state derives from here.
19
19
-**GitHubAPIClient** (`Auth/GitHubAPIClient.swift`): `actor` for thread-safe API calls with caching, pagination, conditional polling (`If-Modified-Since`/304), and rate limit awareness.
-**ThreadActionStore** (`App/ThreadActionStore.swift`): Optimistic actions (done, unsubscribe) with batched dispatch. Reconciles with server on refresh.
21
+
-**ThreadActionStore** (`App/ThreadActionStore.swift`): Optimistic actions (mark read, done, unsubscribe) with batched dispatch. Reconciles with server on refresh.
22
22
-**StatusItemController** (`Panel/StatusItemController.swift`): Menu bar icon, panel toggle, global hotkey (Carbon Events), right-click context menu, outside-click dismiss.
23
23
-**NotificationPanel** (`Panel/NotificationPanel.swift`): `NSPanel` hosting SwiftUI via `NSHostingView`. Floating, non-activating, status bar level.
24
24
-**PanelInput** (`Views/PanelInput.swift`): All keyboard routing. Vim-style (`j/k/d/x/u/o/gg/G`) plus standard shortcuts (`Cmd+Up/Down`, arrows, Page Up/Down).
@@ -31,7 +31,7 @@ Always rebuild after code changes so the user can test immediately. Use `killall
31
31
-**NetworkSession protocol** for testable networking. Production uses `URLSession.shared`, tests use `StubNetworkSession`.
32
32
-**Race condition prevention**: UUID-based `activeLoadRequestID` pattern — generate ID before async work, check it after `await`.
33
33
-**Narrow view dependencies**: Pass specific values to row views (`let notification`, `let isSelected`), not entire state objects.
34
-
-**Equatable views** for list performance (`NotificationRowView: View, Equatable`).
34
+
-**Narrow row inputs** for list performance; keep list rows independent from the full app state.
35
35
36
36
## Testing
37
37
@@ -46,7 +46,7 @@ Uses Swift Testing framework (`import Testing`, `@Test`, `#expect`). Not XCTest.
46
46
47
47
-**Entitlements**: Network client only (no sandbox). Hardened runtime for notarization.
48
48
-**Token storage**: Keychain in release, file (`~/Library/Application Support/Octodot/.debug-token`) in debug.
49
-
-**Debug logging**: `DebugTrace.log()` — compiled out in release builds (`#if DEBUG`). Writes to `/tmp/octodot-debug-trace.log`.
49
+
-**Debug logging**: `DebugTrace.log()` — compiled out in release builds (`#if DEBUG`). Writes to the current user's temporary directory.
50
50
-**Version config**: `OCTODOT_MARKETING_VERSION` in project.pbxproj. CI overrides from git tag.
51
51
-**New files**: Must be added to `project.pbxproj` manually (PBXFileReference, PBXBuildFile, PBXGroup children, PBXSourcesBuildPhase). Follow existing ID patterns (`AA00...` for refs, `BB00...` for build files).
52
52
-**Commit style**: Imperative mood, concise subject line. Body explains "why" not "what".
0 commit comments