Split five files along their natural seams - #88
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Refactors the Blurt app + engine codebase by splitting several large Swift files into smaller, seam-aligned files (UI components, overlay pill content, settings sections, and KeyInjector system glue) to improve separation of concerns and reduce unnecessary imports in core files.
Changes:
- Extracted
KeyInjector’s system-side effects intoKeyInjector+SystemActions.swift, reducing imports in the actor file. - Split shared SwiftUI components/sections (
SettingRow,DeveloperSection, recent dictations UI) into dedicated files. - Moved overlay pill leaf content (palette, status line text, waveform + animation helpers) into
OverlayPillContent.swift, leavingOverlayViewas the shell.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| Sources/BlurtEngine/Injection/KeyInjector+SystemActions.swift | New engine-side file holding KeyInjector’s AppKit/CoreGraphics/ApplicationServices side effects. |
| Sources/BlurtEngine/Injection/KeyInjector.swift | Removes system-action helpers and drops now-unneeded imports. |
| App/Blurt/Blurt/Wizard/Steps/HotkeyStepView.swift | Removes shared settings-row UI types that don’t belong to the hotkey step. |
| App/Blurt/Blurt/Wizard/SettingsWindowRoot.swift | Removes embedded DeveloperSection and drops unused BlurtEngine import. |
| App/Blurt/Blurt/Wizard/SettingRow.swift | New shared settings/setup form row components (SettingRow, PickerSettingRow). |
| App/Blurt/Blurt/Wizard/RecentDictationsSection.swift | New file containing “Recent dictations” list UI and copy affordances (moved out of ReadyView). |
| App/Blurt/Blurt/Wizard/ReadyView.swift | Removes embedded recent-dictations UI and its now-unneeded import. |
| App/Blurt/Blurt/Wizard/DeveloperSection.swift | New file for the Settings Developer section UI. |
| App/Blurt/Blurt/Overlay/OverlayView.swift | Removes embedded overlay leaf views/helpers so the file is focused on the pill shell. |
| App/Blurt/Blurt/Overlay/OverlayPillContent.swift | New file containing overlay palette, status line text, waveform bars, and animation helpers. |
| App/Blurt/Blurt.xcodeproj/project.pbxproj | Registers the newly split app-target Swift files in the generated Xcode project. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Semantic separator (adapts to light/dark + Increase Contrast), | ||
| // full-bleed across the grouped container — the rows carry no | ||
| // leading icon to inset past, so an edge-to-edge rule reads cleaner. | ||
| Divider() |
alexkroman
force-pushed
the
claude/split-large-files
branch
from
July 27, 2026 20:45
9e29bad to
5b87328
Compare
Two view types carried a comment explaining they were "Housed here rather than in its own file so the committed XcodeGen project doesn't need regenerating; move it to its own file next time xcodegen generate runs anyway" — a workaround for an environment that couldn't run xcodegen or verify the result against periphery. Do the move now: - SettingRow + PickerSettingRow (shared form components used by four step views and the settings window) → Wizard/SettingRow.swift, out of HotkeyStepView.swift where they had nothing to do with the hotkey. - DeveloperSection → Wizard/DeveloperSection.swift, out of SettingsWindowRoot.swift. Dropping DeveloperSection also made BlurtEngine unused in SettingsWindowRoot.swift (it only served that section's DeveloperModeStore / DictationLog), so remove the now-dead import. Regenerated the pbxproj so the new files are in the build; check.sh (incl. periphery --strict) green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Each of these bundled a self-contained cluster that stood on its own, and pulling it out also dropped an import the remaining file no longer needed (the kind of unused-import cleanup swiftlint analyze enforces but the web environment couldn't run, so the clusters were left combined): - ReadyView.swift (354→127): the whole "Recent dictations" list — RecentDictationsSection + RecentDictationRow + the two copy-button types — moves to RecentDictationsSection.swift. Its `import Accessibility` (only AccessibilityNotification.Announcement in the row's copy path) goes with it, leaving ReadyView with just its logo + keycap chrome. - OverlayView.swift (340→152): the pill's leaf content views — StatusLineText, TranscribingLabel, RecordingTag, the waveform bars, and the shared pulsingOpacity animation + palette — move to OverlayPillContent.swift, leaving OverlayView as the pill shell (fill, shadow, state → content switch). - KeyInjector.swift (314→265): the static system side effects behind its injectable seams (activate / waitUntilFrontmost / accessibilityTrusted / postCmdV) move to KeyInjector+SystemActions.swift, matching the existing +Separator split. They were the only reason the actor imported CoreGraphics and ApplicationServices, so both imports drop from the main file — it now imports only AppKit. Regenerated the pbxproj for the two new app-target files; check.sh green (swift test, periphery --strict, swiftlint analyze all clean). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
alexkroman
enabled auto-merge
July 27, 2026 20:46
alexkroman
force-pushed
the
claude/split-large-files
branch
from
July 27, 2026 20:51
5b87328 to
8a4919a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Splits files that combined multiple self-contained concerns into one file — the kind of split the web environment left undone because it couldn't run
xcodegen generate(to register new app-target files) or verify the result againstperiphery --strict/swiftlint analyze. Several were annotated in-code with "Housed here rather than in its own file … move it out next time xcodegen generate runs anyway."Rebased onto current
main(past #85/#86/#87). #86 also added a fresh deferred-split marker (BoundTriggerKey), which this PR now clears too, and itsDeveloperSection/UpdateSectionrewrites andBoundTriggerKeyadoption are all preserved.Deferred-split markers (explicit intent in the code)
SettingRow+PickerSettingRow→SettingRow.swift, out ofHotkeyStepView.swift. Shared form components used by four step views and the settings window.DeveloperSection→DeveloperSection.swift, out ofSettingsWindowRoot.swift; that also madeimport BlurtEngineunused in the root file, so it's dropped.BoundTriggerKey(added by Push app-shell presentation logic down into the engine #86) →BoundTriggerKey.swift, out ofHotkeyStepView.swift.Natural seams in the largest files
ReadyView.swift— the whole "Recent dictations" list (RecentDictationsSection+RecentDictationRow+ the two copy-button types) →RecentDictationsSection.swift.import Accessibility(only the row's copy path used it) moves with it.OverlayView.swift— the pill's leaf content views (StatusLineText,TranscribingLabel,RecordingTag, the waveform bars, and the sharedpulsingOpacity+ palette) →OverlayPillContent.swift, leavingOverlayViewas the pill shell.KeyInjector.swift— the static system side effects (activate/waitUntilFrontmost/accessibilityTrusted/postCmdV) →KeyInjector+SystemActions.swift, matching the existing+Separatorsplit. They were the only reason the actor importedCoreGraphicsandApplicationServices, so both drop from the main file — it now imports onlyAppKit.Deliberately left combined
DictationSession.swift(already split into+Commands/+Pipeline/+Observation),DictationKeyTap.swift(extracting the#if UITEST_HOOKSblock would forcerouter/dispatchtointernal),AssemblyAITranscriber.swift(extractingMetricsLoggerwould need a module-global logger),APIKeyStepView.swift(its sheet is a deliberately co-designed private companion), and the large test files (cohesive single suites).Verification
scripts/check.shgreen —swift test,periphery --strict, andswiftlint analyze("No unused code detected") all pass; pbxproj regenerated with no drift.🤖 Generated with Claude Code