Skip to content

Latest commit

 

History

History
61 lines (48 loc) · 4.46 KB

CLAUDE.md

File metadata and controls

61 lines (48 loc) · 4.46 KB

FrameLoop

A native macOS app in SwiftUI. It runs on this Mac only, with a local SwiftData database and no server.

Layout

  • Sources/FrameLoop/ the app. App.swift has the window, menus, and the database location.
  • Sources/FrameLoopKit/ rules and data logic with no SwiftUI. Tests in Tests/FrameLoopKitTests/.
  • Package.swift a Swift package. There is no Xcode project.
  • build.sh builds, signs, and installs /Applications/FrameLoop.app.
  • Icon/AppIcon.icon the app icon, an Icon Composer file (JSON plus SVG layers). build.sh compiles it with tools/make_icon.sh; tools/icon_review.sh renders every look into one PNG.
  • docs/ the brief, the screen index, and the user stories, when they exist.

Build and check

  • Build and install: ./build.sh. Add --open to restart the app with the new build. The build shows warnings; fix them.
  • Unit tests: swift test --scratch-path ~/Library/Developer/FrameLoop/test-build.
  • Self-test (the app's real functions on a /tmp store): tools/selftest.sh. Exit 0 when every check passes. Add a check for every story with logic in SelfTest.swift.
  • After every UI change, take snapshots with sample data and look at them: tools/snap.sh. It writes /tmp/FrameLoop-shots/<page>-light.png and -dark.png for every sidebar page, and settings-<tab>-light.png and -dark.png for every Settings tab, then quits. APP_SNAPSHOT_PAGES=all,settings tools/snap.sh limits the pages. For a panel, sheet, or popover, add a capture to Snapshot.swift like the Settings loop.
  • Snapshots, seed data, and the self-test refuse to run without APP_STORE in /tmp.
  • Never test against the real database in ~/Library/Application Support/FrameLoop/.
  • Then check the grid: tools/grid-lint.sh and swift tools/check-layout.swift /tmp/FrameLoop-shots/*-layout.json. Both print PASS.
  • A change is done when the build has no errors, the grid checks pass, and you looked at the light and dark snapshots.

Gotchas

  • Run the app through open (tools/selftest.sh and tools/snap.sh do). A binary started straight from a shell can come up with no window.
  • Builds need Xcode's toolchain: the command-line tools' SwiftPM is broken on this Mac. Run export DEVELOPER_DIR="/Volumes/OWC Express 1M2 001/Xcode.app/Contents/Developer" first.
  • Snapshots of the main window are degraded (blank sidebar, glass, and video) until the app that runs them has Screen Recording permission.
  • Icon build needs sudo xcodebuild -runFirstLaunch once; until then build.sh skips the icon.
  • The bundle identifier remains com.robschoen.frameloop2 to preserve existing preferences after the rename.
  • Stories live in docs/STORIES.md; the old Electron app is in ~/Dropbox/CC/FrameLoop for behavior reference.

Design rules

  • Use Apple's controls and system styles. Only the accent color is custom: UI/Theme.swift (ThemeStore.defaultID). People change it, and light or dark mode, in Settings > Appearance.
  • Views use .tint, Palette.accent, Palette.accentText (accent-colored text), and Palette.onAccent (text on an accent fill). Never hard-code colors, radii, or durations in views.
  • Compare accents: add APP_ACCENT=<id> to the snapshot command.
  • Spacing comes from Space in UI/Grid.swift, on a 4 pt grid. Mark custom pages and cards with .gridArea and .gridProbe.
  • Windows open calm: .noInitialFocus() on every window and sheet (no focus ring or selected text on open), .fitsContent() on sheets and Settings tabs (no scroll bar with nothing to scroll). System scroll bars. Both in UI/WindowBehavior.swift.
  • Settings: one tab per topic in SettingsView.swift, one grouped Form per tab. Add a case to SettingsTab for a new tab.
  • Window chrome (title bar, toolbar, sidebar, menus, sheets) stays system. Buttons use system styles, like .borderedProminent.
  • Colors: .primary, .secondary, .tint, and system colors. Never fixed grays or white for text.
  • Every action has a menu bar item and a keyboard shortcut.
  • Label for icon and text pairs. SF Symbols for icons.
  • ContentUnavailableView for empty states.
  • Liquid Glass belongs to floating controls only, never to content.

Skills

The bama plugin has a skill for each step: mac-design (design rules), design-system (accent and tokens), layout-grid, ux-design, swift-swiftui, os-integrations, performance, build-and-verify, test-mac-app, app-icon, user-stories, and improve-loop. Use them.

Git

  • Commit after each working change, with a message that says what the user can now do.