Build a native macOS version of GIF Cleanup Studio in SwiftUI. Prefer native SwiftUI/AppKit over Electron for this target unless the user explicitly asks for a fast Electron package.
Source files to study:
- outputs/gif-cleanup-studio/src/App.tsx for the three-pane workflow
- outputs/gif-cleanup-studio/src/sprite.ts for parsing, alignment, color snapping, resizing, and starter frame generation
- outputs/gif-cleanup-studio/src/gif.ts for GIF export behavior
- outputs/gif-cleanup-studio/src/midi.ts for MIDI Fighter mapping
- outputs/gif-cleanup-studio/src/classicHeroSprites.ts for the CC0 starter cycle
Target:
- macOS 14+ SwiftUI app with a real desktop layout: left MIDI Fighter bank rail, center pixel editor/timeline, right prompt/analyzer drawer.
- Import by drag/drop and NSOpenPanel.
- Parse sprite sheets into up to 64 frames with selectable columns, rows/auto rows, background tolerance, color snap tolerance, bottom/center/cell alignment, frame size presets 24/48/64/124/128.
- Pixel editor with pencil, eraser, eyedropper, color picker, zoom slider, grid toggle, checkerboard transparency, and stable square pixels.
- CoreMIDI support for MIDI Fighter hardware plus manual keyboard/mouse fallback.
- Export GIF at 8/16/24/30/60 FPS and show a preview after export.
- Include the ChatGPT prompt drawer and suspicion report from the Windows app.
Implementation requirements:
- Model PixelFrame as width, height, RGBA [UInt8], sourceIndex, id, name.
- Implement SpriteSheetParser with the same behavior as sprite.ts: background sampling, grid cell copy, non-background bbox, bottom/center/cell alignment, cluster-based color normalization, empty-frame warnings, drift warnings.
- Use NSBitmapImageRep or CGImage pixel access for imports, CoreGraphics/ImageIO for GIF export, and CoreMIDI for hardware.
- Use NSOpenPanel plus SwiftUI dropDestination for imports. Add sandbox file access only if the project enables App Sandbox.
- Keep UI dense and tool-like. No marketing landing screen inside the app.
- Preserve MIDI orientation options: bottom-left, top-left, top-right, bottom-right.
Suggested file layout:
- GIFCleanupStudioMacApp.swift
- Models/PixelFrame.swift
- Models/SpriteParseReport.swift
- Models/MidiBinding.swift
- Sprite/SpriteSheetParser.swift
- Sprite/FrameRenderer.swift
- Sprite/ClassicHeroStarter.swift
- Export/GifExporter.swift
- MIDI/MidiFighterController.swift
- Views/MainWindowView.swift
- Views/MidiBankRail.swift
- Views/PixelEditorView.swift
- Views/TimelineView.swift
- Views/PromptDrawerView.swift
- Views/ImportAnalyzerView.swift
- Tests/SpriteSheetParserTests.swift
- Tests/MidiMappingTests.swift
- Tests/GifExporterTests.swift
Checks before calling it done:
- xcodebuild -scheme GIFCleanupStudioMac -destination 'platform=macOS' build
- xcodebuild -scheme GIFCleanupStudioMac -destination 'platform=macOS' test
- Unit test that a 4x4 sheet produces 16 frames.
- Unit test that bottom alignment keeps baselines consistent.
- Unit test that color snap reduces near-duplicate palette colors.
- Unit test that all four MIDI orientation modes map frame 1, 16, 17, and 64 correctly.
- Manual hardware note: verify the MIDI Fighter on a real Mac through CoreMIDI and confirm pad presses select the expected frames.