Files
obsidian-vault/work/projects/vscode-migration/vscode-migration.md
T

8.8 KiB
Executable File
Raw Blame History

VSCode/Cursor Builds & Debugging (macOS)

Status: IN PROGRESS · updated 2026-10-01

Asana: Migration to fully VSCode-supported builds&debugging Repo: ~/DuckDuckGo/apple-browsers.git (bare + worktrees) Findings: projects/vscode-migration/findings

Goal

Build, run and debug the macOS app from VSCode/Cursor: make most of the app SPM-compatible, so swift build + SourceKit-LSP work, and configure .vscode (tasks, launch).

Status

Step Status
Move non-Swift code to local packages ✅ Jun 2025
Missing imports, unused files cleanup ✅ Jun 2025
Initial VSCode config ✅ Jun 2025 (stale: sweetpad worktree)
Unify WebKit private methods (Sparkle/AppStore) ✅ Feb 2026
Drop #if SPARKLE/APPSTORE ✅ Mar 2026 — DMG and App Store targets now compile the same 1398 files
Drop dead target flags (SANDBOX_TEST_TOOL, ALPHA, NETWORK_EXTENSION in shared files) ✅ #6983
Replace sandbox-test-tool with App Store UI tests (AppStoreSandboxUITests, CI leg along full DMG runs) ✅ #6980
Split app files shared with helper targets 🔄 A+B in review (#7029), C ready — see Target split stages
Drop storyboards 🔄 3 left on main: Feedback, NavigationBar, PasswordManager (drop-sb-* worktrees)
Core Data models in code ❌ Cancelled 2026-10-01 — Xcode 27 builds these in SPM
Asset catalogs for swift build ❌ Cancelled 2026-10-01 — Xcode 27 builds these in SPM
swift-build fork (Provisional Inputs) ⏸ not started; may be unnecessary
Remote debugging (VMs, old hardware) ⏸ not started
AI instructions, GitHub MCP subtasks ⏸ not started

Open items after the cancellation

  • Closed PR #6976 (AssetCatalogPlugin) and the Core Data PR; their worktrees are removed.
  • Check what Xcode 27 actually does for swift build (native) and SourceKit-LSP: asset symbols, .car, .momd, storyboards? Earlier finding on Xcode 26: only --build-system swiftbuild handles assets, native doesn't. See projects/vscode-migration/findings#Asset catalogs.
  • Re-check whether storyboards still need dropping with Xcode 27.

Plan (next steps)

  1. Extract files shared with helper targets into packages — in progress, see Target split stages. Started from 38 app files also compiled into VPN / PIR agent / NetP extensions. Dead flags are gone (#6983); unused memberships trimmed and stages A+B moved (#7029). The old draft netp-dependencies is superseded.
  2. Decide on strings & resources in the package (tech design): 1964 NSLocalizedString without bundle: (→ Bundle.main), ~60 resource files, 8 Bundle.main.url(…). bundleIdentifier/appGroup via Bundle.main can stay.
  3. App code as a library package + thin app target (AppMain, Info.plist, entitlements, embed phases for login items / extensions).
  4. VSCode tasks with cached helper targets: gate script hashes each extension's inputs (git-based, not mtime) and skips xcodebuild when unchanged; assemble step copies prebuilt extensions and signs. Only pays off once the app itself builds with swift build. See projects/vscode-migration/findings#Extensions in VSCode tasks.
  5. Convert ~57 string-name image lookups (NSImage(named:), Image("…")) to asset symbols — they break once code moves to Bundle.module.

Target split stages

Goal: no file in macOS/DuckDuckGo/ is compiled into a helper target (VPN agent, PIR agent, NetP extensions), so the app directory can become one SPM target. InputFilesChecker tracks the remaining files in temporarilyAllowedMisplacedFiles (one block per stage); a stale entry fails the build, so each stage PR must remove its block.

Stage Files Used by Home New deps / project changes Size & blockers PR
A ApplicationBuildType, BuildFlags, DuckDuckGoUserAgent app + all 6 helpers AppKitExtensions none (all targets already link it) 46 imports #7029
B DBPFeatureFlagger, DataBrokerAuthenticationManagerBuilder, DataBrokerProtectionSettings+Environment, WebViewUserAgentProvider, SafariVersionReader, WebKitVersionProvider app + PIR agent DataBrokerProtection-macOS none (Subscription comes transitively, like elsewhere in the package) 5 imports #7029
C NetworkProtectionPixelEvent (569 loc) app, VPN agent, 3 extensions NetworkProtectionMac → VPNPixels (new library product) VPNPixels += VPN, Configuration; BSK package dep; product linked to 7 targets 9 imports. Ready, uncommitted (move-vpn-pixel-event) own PR, on top of #7029
D SubscriptionPixel, SubscriptionPixelHandler, SubscriptionEnvironment+Default, WideEventFeatureFlagAdapter, SubscriptionFunnelOrigin (836 loc) app, VPN agent, PIR agent, 3 extensions new local package (no existing one is linked by all consumers) Subscription, PixelKit, Networking, PrivacyConfig, WideEvent, AppKitExtensions; product linked to ~8 targets used in ~134 files — biggest diff own PR (new package, Subscription reviewers)
E1 TipKit ×4, VPNIPCResources, VPNOperationErrorRecorder, NetworkProtectionVPNCountryLabelsModel, VPNSettings+Environment (~470 loc) app + VPN agent NetworkProtectionMac (IPC / UI, or a small TipKitSupport target) Subscription for VPNSettings+Environment moderate, no strings combine with G
G 10 helper-only sources living in DuckDuckGo/ (Bundle+VPN, NetworkProtectionOptionKeyExtension, NetworkProtectionControllerErrorStore, NetworkProtectionTunnelController, MacPacketTunnelProvider, MacTransparentProxyProvider, NetworkProtectionNotificationsPresenterFactory, VPNFailureRecoveryPixel, Bundle+NetworkProtectionExtensions, SubscriptionManager+StandardConfiguration) helpers only, never the app helper-owned folders git mv + pbxproj group paths only small, noisy pbxproj combine with E1
E2 UserText+NetworkProtection+Shared, DefaultVPNLocationFormatter app + VPN agent NetworkProtectionUI (has Localizable.xcstrings) strings → Bundle.module with translations; app and VPN agent each have their own UserText blocked on the strings/resources decision combine with H
H 4 app icons, macos-config.json, 7 VPN Lottie JSONs, 2 NetP .xcstrings app + helpers package resources or per-target copies resource bundles / Bundle.module same decision as E2 and the app-package tech design with E2
F UserDefaultsWrapper (415 loc) + UserDefaults+NetworkProtectionShared app, VPN agent, all extensions; ~51 app files don't move — deprecated in favour of KeyedStoring follows the KeyedStoring migration blocked on that migration (owner/timeline TBD) after the migration
X (optional) NETP_SYSTEM_EXTENSION in MacPacketTunnelProvider, MacTransparentProxyProvider, NetworkProtectionNotificationsPresenterFactory extensions only runtime check Bundle.main.bundleURL.pathExtension == "systemextension" removes the last FEATURE_FLAGS from xcconfigs changes keychain service / defaults selection — needs VPN team review optional, separate

Order: C → D → E1+G → strings/resources tech design → E2+H → F after KeyedStoring. X any time if the VPN team agrees.

Worktrees

Worktree Branch What
trim-target-memberships alex/trim-target-memberships Stages A+B + membership trim, PR #7029
move-vpn-pixel-event alex/move-vpn-pixel-event Stage C, uncommitted, on top of #7029
drop-sb-feedback, drop-sb-navigationbar, drop-sb-passwordmanager alex/drop-*-storyboard Remaining storyboards
coredata-spm-hacks-cleanup alex/coredata-spm-hacks-cleanup no commits ahead of main yet
netp-dependencies alex/align-netp-dependencies Old draft: move files by target (superseded by the stages above)
vscode, vscode2 alex/fix-imports-cleanup, alex/vscode2 Old: SwiftGenPlugin draft (uncommitted), root Package.swift
sweetpad alex/cursor-fix-build Old .vscode (SweetPad) config

Gone: spm-asset-symbols-plugin, coredata-code-models*, drop-sb-bookmarksbar* (BookmarksBar storyboard + xib are on main), appstore-sandbox-ui-tests (#6980), drop-dead-target-flags (#6983), split-shared-target-files.

Demo project for the (cancelled) asset approach: ~/Developer/SPMAssetSymbolsDemo (./verify.sh).