Loom balances native macOS desktop craft with strict local-first privacy. This document details the visual styling system, notification architecture and storage, menu bar status modes, and disk footprint scanning.
Loom’s popover interface is designed to feel like an integral part of macOS rather than a ported web dashboard or generic Electron utility.
+---------------------------------------------------------------------------------+
| macOS 26+ Environment: |
| - System Liquid Glass: .glassEffect() and GlassEffectContainer |
| - Native glass-styled segmented navigation, header controls, and icon badges |
| - Standard content materials for data cards (no nested glass blur) |
+---------------------------------------------------------------------------------+
| macOS 14 & 15 Fallback Environment: |
| - Semantic Materials: .ultraThinMaterial backing for popover root |
| - Native NSSegmentedControl and standard AppKit/SwiftUI borderless buttons |
| - Subtle hairline separators (.quaternary) and semantic fill colors |
+---------------------------------------------------------------------------------+
| Accessibility Overrides: |
| - Reduce Transparency: Replaces all glass/translucent materials with opaque |
| system background (NSColor.windowBackgroundColor) |
| - Increase Contrast: High-contrast borders and elevated text contrast ratios |
| - VoiceOver: Semantic accessibility labels on all controls and status capsules |
+---------------------------------------------------------------------------------+
- System-Provided Glass on macOS 26+: Header chrome, navigation segment bars, and toolbar controls adopt native Liquid Glass styling via
.glassEffect()where supported by the OS runtime. - Graceful Fallbacks on macOS 14/15: Availability guards (
@available(macOS 26.0, *)) route older supported macOS versions to.background(.ultraThinMaterial)and native secondary fills. - No Nested Glass Stacking: Content cards (such as session cards and quota progress bars) use standard opaque or thin background fills. Stacking multiple translucent glass layers or placing translucent text on translucent backgrounds is strictly prohibited to prevent visual mush and contrast degradation.
- Restrained Color & Semantic Badges:
- Needs Attention (
waiting,failed): High-visibility semantic amber (Color.orange) and red (Color.red). - Active Execution (
working,starting): Crisp system accent blue or green. - Idle & Unknown: Low-emphasis secondary/tertiary grays.
- Quota Warning Thresholds: 15% threshold uses warning amber; 5% threshold uses critical red.
- Needs Attention (
- Accessibility Integrity:
- Reduce Transparency: When the user enables Reduce Transparency in macOS System Settings, all glass and material surfaces fall back immediately to solid, opaque system window fills.
- Full Keyboard Navigation & VoiceOver: Every button, disclosure arrow, filter chip, and quick action provides descriptive
.accessibilityLabeland.accessibilityHinttraits.
Loom integrates with UNUserNotificationCenter to deliver actionable system alerts while strictly guarding user privacy.
Configured under Settings → Notifications:
| Setting Key | Default | Description |
|---|---|---|
notificationsEnabled |
true |
Master toggle. Existing opt-outs are preserved; macOS authorization is still required. |
quotaWarning15Percent |
true |
Alerts when an enabled quota-capable provider's observed remaining quota crosses below 15% (Codex and Antigravity). |
quotaWarning5Percent |
true |
Alerts when an enabled quota-capable provider's observed remaining quota crosses below 5% (Codex and Antigravity). |
quotaReplenishedAlert |
true |
Alerts when a fresh observation confirms quota recovery to ~100% in a new window. |
sessionWaitingAlert |
true |
Alerts when an agent session transitions to waiting (requiring user input/decision). |
sessionFinishedAlert |
false |
Alerts when an active agent session concludes successfully and meets the observed Working duration. |
minimumWorkingDuration |
300 seconds |
Finished alerts only: Always, 2, 5 or 10 minutes of observed Working time; waiting/failure alerts stay immediate. |
sessionFailedAlert |
true |
Alerts when an agent process exits abnormally or encounters a fatal provider error. |
- Quota Support: Codex and Antigravity expose observed quota data for threshold alerts. Claude Code does not expose quota through its upstream local interface; Loom does not synthesize Claude quota values.
- Permission Handling: Notifications default to enabled. On normal launch, Loom requests macOS authorization only if notifications are enabled and permission has not been decided. Existing opt-outs and macOS denials remain unchanged; demo launches do not request permission. Enabling notifications in Settings can also request authorization.
- System Settings Link: If permissions are denied at the OS level, Settings displays an inline warning banner with a direct link to macOS System Settings.
- Debug Test Notification: Debug builds include Send Test Notification for manual development verification. Release builds exclude the button and test-alert implementation.
Production quota threshold deduplication and window observations are persisted in UserDefaults across app restarts. Reset alerts require fresh, ordered observations crossing a known prior reset boundary and restoring at least 95% in a later window; a changed timestamp alone is insufficient. Upstream account/profile identity is not yet available for scoping this state.
To provide transparency and auditability, Loom maintains a bounded local history of queued, failed or suppressed notifications:
- Storage Location: Persisted in
UserDefaultsviaSharedAppGroup.suiteNameunderloom.notificationHistory. - Bounded Retention: Stored as a circular ring buffer capped at the last 100 events to prevent unbounded disk growth.
- Stored Data Schema:
id: Unique UUID.timestamp: ISO 8601 creation date.eventType:quota15,quota5,quotaReplenished,sessionWaiting,sessionFinished,sessionFailed.providerID:codex,claude, orantigravity.title: Notification headline.subtitle: Redacted summary text.delivered: Boolean delivery status.
- No Sensitive Content Persistence: The history store never records conversation transcripts, user prompts, shell commands, environment variables, API keys, or full error stack traces.
- Path Concealment (
hideProjectPaths): When enabled:- File system paths (e.g.
/Users/deepak/Desktop/Projects/oss/Loom) are masked in notification titles and bodies, showing only the sanitized repository name (e.g.Loom) or generic identifier. - Notification history entries sanitize all paths before writing to disk.
- File system paths (e.g.
- Deep Linking Without Exposure: Clicking a notification opens Loom, activates the relevant provider tab, and highlights the corresponding session via internal session UUIDs without passing filesystem paths through system notification payloads.
To respect limited menu bar real estate—especially on notched MacBook displays—Loom provides three status modes in Settings → General:
1. Icon Only (Default):
[ ⎇ ]
2. Active Sessions Count:
[ ⎇ 2 ]
3. Lowest Quota Percentage:
[ ⎇ 18% ]
- Icon Only: Displays the canonical monochrome woven Loom glyph. Takes minimal width (~24pt).
- Active Sessions Count: Displays the glyph alongside an integer count of currently executing agents (
workingorstarting). If zero sessions are active, displays the glyph alone. - Lowest Quota Percentage: Displays the glyph alongside the lowest verified remaining quota across all monitored providers. Never displays
0%for missing or unsupported quota data (such as Claude Code). Transitions to warning colors when crossing below 15%. - Safety Invariant: Status bar strings are strictly bounded in width and truncated safely if screen constraints require it.
The popover provides instant operational tools for active developers:
- Filter Bar: Positioned at the top of the Sessions view.
All: Unfiltered list of discovered sessions.Needs Attention: Filters strictly to sessions inwaitingorfailedstates.Working: Filters strictly to sessions inworkingorstartingstates.Recent: Filters to recently completed (finished) sessions.
- Search Field: Real-time filtering matching repository names, Git branches, host application names, or session identifiers without stalling background polling.
Each session card exposes safe, non-destructive quick actions:
- Focus Terminal / IDE: Identifies the host application PID and brings its windows forward using
NSWorkspace.shared.runningApplications. - Copy PID: Copies the primary process PID to the clipboard.
- Copy Repo Path: Copies the project path (or masked name if privacy mode is active).
- Copy Session ID: Copies the provider session token.
- Reveal in Finder: Direct Finder navigation via
NSWorkspace.shared.activateFileViewerSelecting. - Strict Read-Only Contract: Loom does not provide
kill,SIGTERM, or shell prompt execution affordances.
Configured in Settings → Storage:
- Measured Directories:
- OpenAI Codex: Measures
~/.codex/sessions,~/.codex/cache, and~/.codex/logs(respectsCODEX_HOMEoverride). - Anthropic Claude Code: Measures
~/.claude/state,~/.claude/transcripts, and~/.claude/config(respectsCLAUDE_CONFIG_DIRoverride). - Google Antigravity: Measures
~/.gemini/antigravity-cli/brain,~/.gemini/antigravity-cli/mcp, and associated state files (excludes unrelated Gemini data).
- OpenAI Codex: Measures
- Execution Safeguards:
- Scans off the main actor (
Task.detached/ background queue). - Hard Bounds: Execution is limited to a maximum of 5 seconds and 100,000 entries per provider root.
- Cooperative Cancellation: Dismissing the popover or switching tabs cancels active scans immediately.
- Read-Only: The scanner only reads file attributes (
fileSize). It never inspects file contents, follows symlinks across filesystems, deletes files, or alters directory structures. - Privacy: If
hideProjectPathsis active, storage path labels in the UI are redacted.
- Scans off the main actor (
Loom provides three desktop and Notification Center widgets via SharedAppGroup:
- Loom Quotas (Small, Medium, Large): Displays remaining quota percentages, countdowns to reset timestamps, and granular model limits. Configurable via widget intent to focus on a specific provider or show all.
- Loom Sessions (Small, Medium): Glanceable count of active sessions and prominent alerts for sessions waiting for human input.
- Loom Usage Overview (Medium, Large): Multi-provider comparison with progress bars and reset countdowns.
- Data Invariants: Widgets consume serialized snapshots from
LoomWidgetSnapshot. Snapshots are written atomically upon store refresh. Saved timestamps use the original observation date, ensuring countdowns remain accurate even if Loom is idle.