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

11 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, G done; the rest stays shared by path — see Target split stages
Asset resource initializers instead of asset symbol extensions ✅ committed, alex/asset-resource-symbols (needs a PR)
Drop storyboards ✅ last one (NavigationBar) is alex/drop-navigationbar-storyboard (PR open); Feedback #6866, PasswordManager #6950 merged
Browser code as a SwiftPM package 🔄 builds and runs from Xcode and VSCode — alex/spm-browser-package, see Browser package
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. PRs in order: #7029 (A+B) → C (move-vpn-pixel-event) / G (move-helper-only-files) → alex/asset-resource-symbols → alex/drop-navigationbar-storyboard → alex/spm-browser-package.
  2. Browser package PR follow-ups — see Browser package: localization export (loc_export.sh), CI checks for the VSCode setup, dropping the duplicated app-target package product dependencies.
  3. Helper-target split, later: D, E1, E2+H, F aren't needed for the package (helpers keep compiling the shared files by path); do them when there's a reason (F with the KeyedStoring migration).
  4. VSCode tasks with cached helper targets (extensions/login items built by Xcode only when their inputs change) — the host app already contains them; revisit if host rebuilds are too slow. See projects/vscode-migration/findings#Extensions in VSCode tasks.

Browser package

Worktree spm-browser-package, branch alex/spm-browser-package (on top of alex/move-helper-only-files + alex/asset-resource-symbols + alex/drop-navigationbar-storyboard; package work uncommitted).

  • macOS/DuckDuckGo/Package.swift: target DuckDuckGo_Privacy_Browser (same module name as the former app target: storyboards, archived class names, @testable import) with path: "." — files stay in place. Products DuckDuckGoBrowser (static, linked into the app targets) and DuckDuckGoBrowserDynamic (for swift build).
  • Resources stay in the app targets (Bundle.main: strings, JSON, scripts, app icons); asset catalogs (for generated ImageResource/ColorResource) and the 8 Core Data models (codegen entity classes) are processed by the package — models now load from Bundle.module.
  • App targets: only DuckDuckGoApp/main.swift (AppMain.main()), module DuckDuckGoApp; package reference + DuckDuckGoBrowser product added, existing product dependencies kept.
  • SPM_FORCE_DEBUG in Package.swift (same as AppKitExtensions/SyncUI): the CI configuration maps to release for packages.
  • REVIEW compilation condition can't reach the package → Browser Tools Panel debug menu item is gated at runtime (isDebugBuild || isReviewBuild).
  • VSCode/Cursor: open macOS/DuckDuckGo; .vscode/ has tasks (host app → swift build --build-system swiftbuild → sign), launch.json, make-host-app.sh, sign-dylib.sh, launcher/launcher.c.
  • Verified (Xcode 27.2, offline): all product schemes Debug, macOS Browser Review, unit + integration tests build-for-testing Debug and CI (with SPM_FORCE_DEBUG=1), Xcode-signed Debug app and the VSCode host run without crashes, swift build of the dylib.
  • Open: loc_export.sh / string catalog extraction now that sources are in a package; CI doesn't build the VSCode path; Package.resolved in macOS/DuckDuckGo (copied from the project) — keep in sync or generate.

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 DuckDuckGoVPN/, new HelperTargetsShared/ (allowed for helper targets in InputFilesChecker) git mv + pbxproj group paths only done ✅ alex/move-helper-only-files
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
move-helper-only-files alex/move-helper-only-files Stage G (committed): helper-only sources → DuckDuckGoVPN/, HelperTargetsShared/
asset-resource-symbols alex/asset-resource-symbols Asset resource initializers (committed)
spm-browser-package alex/spm-browser-package Browser code as a SwiftPM package + VSCode setup (WIP, uncommitted)
drop-sb-navigationbar alex/drop-navigationbar-storyboard Last storyboard (PR open, merged into spm-browser-package)
drop-sb-feedback alex/drop-feedback-storyboard Merged (#6866); follow-up commits after the squash?
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).