Skip to content

feat: native macOS Phase 2 — SwiftPM Spike setup - #153

Merged
tukuyomil032 merged 10 commits into
mainfrom
feat/native-macos-phase2-spike-setup
Jul 8, 2026
Merged

feat: native macOS Phase 2 — SwiftPM Spike setup#153
tukuyomil032 merged 10 commits into
mainfrom
feat/native-macos-phase2-spike-setup

Conversation

@tukuyomil032

Copy link
Copy Markdown
Owner

Summary

Implements spec/phase-tasks.md Phase 2 (tasks 2-1 through 2-9): the SwiftPM scaffold for the independent native macOS reimplementation (apps/native-macos/), plus lint/format tooling and CI.

  • apps/native-macos/Package.swift: 3-target layout (App executable, Core library, CoreTests), no .xcodeproj per spec/native-macos-requirements.md's brew-browser-style decision. swift-tools-version:6.2, platforms: [.macOS(.v26)].
  • Placeholder RootView + #Preview in Core, confirming the library-target split lets previews work without ENABLE_DEBUG_DYLIB.
  • Minimal CoreTests baseline using Swift Testing (@Test/#expect), matching the framework Phase 3's security.rs migration will use.
  • SwiftFormat via SPM command plugin (upstream has no build-tool plugin) and SwiftLint via SPM build-tool plugin (strict: true), both verified to build/lint/format cleanly.
  • lefthook.yml: new lint-format-swift job (mirrors fmt-rust/lint-format-ts), no-ops when swift isn't on PATH locally.
  • .github/workflows/native.yml: lint job (ubuntu-latest, swift-actions/setup-swift@v2 @ 6.2) + build-and-test job (macos-26, matches the platform's actual macOS 26 requirement rather than macos-latest).
  • apps/native-macos/README.md + a CLAUDE.md pointer documenting the build/lint commands.

Naming note

Deviated from spec/phase-tasks.md's literal MCVectorNative/MCVectorNativeKit naming — per user feedback mid-implementation, dropped the redundant MCVector prefix (the repo is already mc-vector). Targets are App / Core / CoreTests, package name Native.

Verified deviations from the task table

  • SwiftFormat (task 2-4) is invoked as a command plugin, not a build-tool plugin — nicklockwood/SwiftFormat doesn't ship one upstream.
  • -skipPackagePluginValidation (task 2-8's open question) does not exist as a flag on Swift 6.2.4 — omitted.
  • native.yml's build/test job runs on macos-26 rather than macos-latest, since macos-latest doesn't move to macos-26 until later and this project specifically targets macOS 26 Tahoe.

Test plan

  • swift build clean locally (Xcode 26.3 / Swift 6.2.4)
  • swift test — 1/1 passing
  • swift package swiftformat --lint — 0 files require formatting
  • swift package swiftlint --strict (via build-tool plugin during swift build) — clean
  • lefthook run pre-commit --command lint-format-swift --force --all-files — verified end-to-end, caught and fixed a real trailing-comma violation
  • CI (native.yml lint + build-and-test jobs)

tukuyomil032 and others added 9 commits July 8, 2026 22:17
Set up the 3-target SwiftPM layout (executable App + library Core +
testTarget CoreTests) per spec/native-macos-requirements.md's
no-.xcodeproj decision: the executable stays a thin @main entry point
while Core holds the actual logic/views, which is what lets #Preview
work without ENABLE_DEBUG_DYLIB (only settable via .xcodeproj).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Confirms library-target separation lets #Preview render without
ENABLE_DEBUG_DYLIB (Package.swift-only setup, no .xcodeproj).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Confirms swift test discovers and runs the CoreTests target via
Swift Testing (@Test/#expect), matching the framework Phase 3's
security.rs migration (spec/phase-tasks.md 3-11) will use.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
nicklockwood/SwiftFormat only ships a command plugin (no build-tool
plugin exists upstream), so this is invoked explicitly via
`swift package --allow-writing-to-package-directory swiftformat`
rather than running automatically on every build. Verified both lint
(--lint) and write modes locally against the current source tree;
fixed the one real violation swiftformat found in CoreTests.swift.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Attach SwiftLintBuildToolPlugin to App/Core/CoreTests so `swift build`
and `swift test` enforce .swiftlint.yml (strict: true) automatically,
in contrast to SwiftFormat's manual command-plugin invocation.

Also disables SwiftFormat's swiftTestingTestCaseNames rule: it rewrites
`@Test("description") func name()` into a backtick-quoted function
name, which then fails SwiftLint's identifier_name
(validates_start_with_lowercase) check. Keeping the descriptive-string
+ camelCase form avoids the two tools fighting each other.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors the existing fmt-rust/lint-format-ts pre-commit jobs: runs
swiftformat + swiftlint --fix over apps/native-macos on commit, and
no-ops with a message (rather than failing) when swift isn't on PATH
locally, since CI is the enforcement backstop either way.

Verified end-to-end via `lefthook run pre-commit --command
lint-format-swift --force --all-files`, which also caught and fixed a
real trailing-comma violation in Package.swift.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ubuntu-latest job running swiftformat --lint and swiftlint --strict
via the SPM plugins added in the previous two commits, gated on
paths: ['apps/native-macos/**'] so it doesn't fire for unrelated
changes. Uses swift-actions/setup-swift@v2 pinned to 6.2 to match
Package.swift's swift-tools-version.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Runs swift build + swift test on the macos-26 runner image (Xcode
26.x, matching this repo's local dev environment and the
platforms: [.macOS(.v26)] requirement).

Verified -skipPackagePluginValidation, which spec/phase-tasks.md
flagged as possibly needed: it is not a recognized flag on Swift
6.2.4 (absent from swift build/test/package --help), and swift
build/test already run cleanly without a TTY locally with the
SwiftLint/SwiftFormat plugins attached, so it's omitted.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
New apps/native-macos/README.md documents swift build/test, the
SwiftFormat/SwiftLint plugin invocations, and the lefthook/CI
enforcement split. Root CLAUDE.md gets a one-line pointer to it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 8, 2026 13:35
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@tukuyomil032, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 21 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eaa2df17-8584-4a69-a250-d0e0879b2553

📥 Commits

Reviewing files that changed from the base of the PR and between 358a600 and b8cf930.

📒 Files selected for processing (13)
  • .github/workflows/native.yml
  • .gitignore
  • CLAUDE.md
  • apps/native-macos/.swiftformat
  • apps/native-macos/.swiftlint.yml
  • apps/native-macos/Package.resolved
  • apps/native-macos/Package.swift
  • apps/native-macos/README.md
  • apps/native-macos/Sources/App/Main.swift
  • apps/native-macos/Sources/Core/Core.swift
  • apps/native-macos/Sources/Core/RootView.swift
  • apps/native-macos/Tests/CoreTests/CoreTests.swift
  • lefthook.yml
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/native-macos-phase2-spike-setup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds the Phase 2 SwiftPM “spike” scaffold for the independent native macOS reimplementation under apps/native-macos/, along with local hooks and CI to enforce Swift formatting/linting and run basic build/test.

Changes:

  • Introduces a new SwiftPM package (Native) with App (executable), Core (library), and CoreTests (Swift Testing) targets plus minimal placeholder implementation.
  • Adds SwiftFormat + SwiftLint configuration and wiring (SwiftLint build-tool plugin + SwiftFormat command plugin), plus a lefthook pre-commit job for Swift files.
  • Adds a dedicated GitHub Actions workflow (native.yml) to lint, build, and test the native macOS package.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
lefthook.yml Adds a lint-format-swift pre-commit command for Swift formatting/linting.
CLAUDE.md Documents where the SwiftPM native macOS package lives and points to its README for commands.
apps/native-macos/Package.swift Defines the SwiftPM package, targets, dependencies, and SwiftLint plugin usage.
apps/native-macos/Package.resolved Pins SwiftPM dependency resolution for the new native macOS package.
apps/native-macos/.swiftlint.yml Adds SwiftLint configuration (strict mode, opt-in rules, exclusions).
apps/native-macos/.swiftformat Adds SwiftFormat configuration and disables the Swift Testing test case name rule.
apps/native-macos/README.md Documents build/test/lint/format commands and the no-.xcodeproj approach.
apps/native-macos/Sources/App/Main.swift Adds the executable entry point for the App target.
apps/native-macos/Sources/Core/Core.swift Adds a minimal Core API surface (Core.version).
apps/native-macos/Sources/Core/RootView.swift Adds a placeholder SwiftUI RootView and #Preview.
apps/native-macos/Tests/CoreTests/CoreTests.swift Adds a baseline Swift Testing test for Core.version.
.gitignore Ignores SwiftPM build artifacts and generated Xcode project files under apps/native-macos/.
.github/workflows/native.yml Adds CI workflow for native macOS linting and build/test.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/native.yml Outdated
Comment thread lefthook.yml
Comment on lines +18 to +21
if ! command -v swift >/dev/null 2>&1; then
echo "swift not found locally, skipping Swift format/lint (still enforced in CI)"
exit 0
fi
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@tukuyomil032
tukuyomil032 merged commit 33f292b into main Jul 8, 2026
12 checks passed
@tukuyomil032
tukuyomil032 deleted the feat/native-macos-phase2-spike-setup branch July 8, 2026 13:45
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.

2 participants