Skip to content

Split five files along their natural seams - #88

Merged
alexkroman merged 2 commits into
mainfrom
claude/split-large-files
Jul 27, 2026
Merged

Split five files along their natural seams#88
alexkroman merged 2 commits into
mainfrom
claude/split-large-files

Conversation

@alexkroman

@alexkroman alexkroman commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

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 against periphery --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 its DeveloperSection/UpdateSection rewrites and BoundTriggerKey adoption are all preserved.

Deferred-split markers (explicit intent in the code)

  • SettingRow + PickerSettingRowSettingRow.swift, out of HotkeyStepView.swift. Shared form components used by four step views and the settings window.
  • DeveloperSectionDeveloperSection.swift, out of SettingsWindowRoot.swift; that also made import BlurtEngine unused in the root file, so it's dropped.
  • BoundTriggerKey (added by Push app-shell presentation logic down into the engine #86) → BoundTriggerKey.swift, out of HotkeyStepView.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 shared pulsingOpacity + palette) → OverlayPillContent.swift, leaving OverlayView as the pill shell.
  • KeyInjector.swift — the static system side effects (activate / waitUntilFrontmost / accessibilityTrusted / postCmdV) → KeyInjector+SystemActions.swift, matching the existing +Separator split. They were the only reason the actor imported CoreGraphics and ApplicationServices, so both drop from the main file — it now imports only AppKit.

Deliberately left combined

DictationSession.swift (already split into +Commands/+Pipeline/+Observation), DictationKeyTap.swift (extracting the #if UITEST_HOOKS block would force router/dispatch to internal), AssemblyAITranscriber.swift (extracting MetricsLogger would 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.sh green — swift test, periphery --strict, and swiftlint analyze ("No unused code detected") all pass; pbxproj regenerated with no drift.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings July 27, 2026 20:05
@alexkroman
alexkroman enabled auto-merge July 27, 2026 20:05

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 into KeyInjector+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, leaving OverlayView as 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
alexkroman added this pull request to the merge queue Jul 27, 2026
@alexkroman
alexkroman removed this pull request from the merge queue due to a manual request Jul 27, 2026
@alexkroman
alexkroman added this pull request to the merge queue Jul 27, 2026
@alexkroman
alexkroman removed this pull request from the merge queue due to a manual request Jul 27, 2026
Copilot AI review requested due to automatic review settings July 27, 2026 20:45
@alexkroman
alexkroman force-pushed the claude/split-large-files branch from 9e29bad to 5b87328 Compare July 27, 2026 20:45
alexkroman-assembly and others added 2 commits July 27, 2026 16:46
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
alexkroman enabled auto-merge July 27, 2026 20:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.

@alexkroman
alexkroman force-pushed the claude/split-large-files branch from 5b87328 to 8a4919a Compare July 27, 2026 20:51
@alexkroman
alexkroman added this pull request to the merge queue Jul 27, 2026
Merged via the queue into main with commit 54d3624 Jul 27, 2026
7 checks passed
@alexkroman
alexkroman deleted the claude/split-large-files branch July 27, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants