From a262076648b2c8375f193c336ccfc1e768d70694 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Thu, 1 Oct 2026 12:28:44 +0600 Subject: [PATCH] [2026-10-01] eagle: work/_index.md work/projects/vscode-migration/findings.md work/projects/vscode-migration/vscode-migration.md --- work/_index.md | 2 +- work/projects/vscode-migration/findings.md | 39 +++++++++++++ .../vscode-migration/vscode-migration.md | 58 +++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 work/projects/vscode-migration/findings.md create mode 100644 work/projects/vscode-migration/vscode-migration.md diff --git a/work/_index.md b/work/_index.md index 5e948ec9..f1150f9d 100755 --- a/work/_index.md +++ b/work/_index.md @@ -1,3 +1,3 @@ # Work -[[projects/ios-duck-ai-toggle]] | [[projects/ios-demo-tracker]] +[[projects/ios-duck-ai-toggle]] | [[projects/ios-demo-tracker]] | [[projects/vscode-migration/vscode-migration]] diff --git a/work/projects/vscode-migration/findings.md b/work/projects/vscode-migration/findings.md new file mode 100644 index 00000000..9843d722 --- /dev/null +++ b/work/projects/vscode-migration/findings.md @@ -0,0 +1,39 @@ +# VSCode Migration — Technical Findings + +Back to [[projects/vscode-migration/vscode-migration]]. Verified on Xcode 26.6 / Swift 6.3.3, Sep 2026. + +## App target readiness + +- DMG and App Store targets compile identical sources (1398 files); `FEATURE_FLAGS` is empty for the app — only `DEBUG` remains (SPM handles it). +- No ObjC/C in `macOS/DuckDuckGo/`, empty bridging header. +- Unit Tests compile only 2 app files directly; the rest is `@testable import` → can switch to the library. +- 46 app files are shared with helper targets (VPN 36, DBP agent 18, NetP extensions 14 each): `UserText.swift`, `UserDefaultsWrapper`, `ConfigurationManager`, `Subscription*`, `TipKit*`, `VPN*`, `DuckDuckGoUserAgent`, … +- Remaining Xcode-only resources: storyboards `PasswordManager`, `BookmarksBar`, `NavigationBar`, `Feedback` + `BookmarksBarCollectionViewItem.xib`; 8 `.xcdatamodeld` in the app, 3 in BSK. + +## Asset catalogs + +- Xcode generates asset symbols with `actool --bundle-identifier … --generate-swift-asset-symbols X.swift`. In that mode actool writes no `Assets.car`, so compiling is a second invocation (same as Xcode's `GenerateAssetSymbols` + `CompileAssetCatalog`). +- For **package** targets Xcode and `swiftbuild` generate `ImageResource`/`ColorResource` symbols but **not** `NSImage.foo` / `NSColor.foo` extensions. The app target uses extensions (e.g. `NSImage.menuVertical16`) → those call sites must change when moving into a package. +- Native `swift build` (also what SourceKit-LSP uses) neither compiles catalogs nor generates symbols. +- Native SwiftPM resource bundles are flat and lack Info.plist; CoreUI ignores `Assets.car` without `CFBundleIdentifier`. +- In Xcode's plugin sandbox actool fails for iOS ("No available simulator runtimes"); macOS works. So a plugin can't replace Xcode's processing on iOS. +- Plugin environment is identical for native and `swiftbuild` → can't tell them apart; Xcode is detectable by the `/BuildToolPluginIntermediates/` work dir. +- Asset usage in the app catalog: ~415 via symbols, ~57 via string names, 20 only from storyboards, ~300 apparently unreferenced (heuristic). + +## Extensions in VSCode tasks + +- `tasks.json` `dependsOn` has no up-to-date check → needs a gate script (input hash via `git ls-files -s` + diff, stamp file). +- `xcodebuild` always visits explicit target dependencies (planning, Provisional Inputs) even when nothing changed; no flag to skip. Gating extensions only pays off once the app is built with `swift build` and assembled by a script. +- Assemble: copy pre-signed extensions, sign the outer app last without `--deep`; same Team ID; embed provisioning profiles for NetworkExtension entitlements; system extension activates only from `/Applications`. +- Embedded: Login Items `DuckDuckGo VPN.app`, `DuckDuckGo Personal Information Removal.app`; PlugIns `NetworkProtectionAppExtension.appex`, `VPNProxyExtension.appex`. + +## Toolchain + +- `~/.swiftly/bin/swift` (6.2) is first in PATH; it can't compile packages importing WebKit against the macOS 26 SDK. Use `xcrun swift`, and set `swift.path` in VSCode to Xcode's toolchain. +- Native builds rewrite stale `Package.resolved` files (e.g. `SharedPackages/Onboarding`) — don't commit those. + +## Pre-existing issues found + +- `UIComponentsTests`: macOS 15 API without `@available` (package min 12.3). +- `PerformanceTestTests`: reference removed types (`CoreWebVitalsAssessment`, `averageResourceSize`). +- `DataBrokerProtectionCore`: empty `DBP.xcassets` inside `.copy("BundleResources")` — dead, never compiled. diff --git a/work/projects/vscode-migration/vscode-migration.md b/work/projects/vscode-migration/vscode-migration.md new file mode 100644 index 00000000..f8d09a3f --- /dev/null +++ b/work/projects/vscode-migration/vscode-migration.md @@ -0,0 +1,58 @@ +# VSCode/Cursor Builds & Debugging (macOS) + +Status: **IN PROGRESS** · updated 2026-10-01 + +**Asana:** [Migration to fully VSCode-supported builds&debugging](https://app.asana.com/1/137249556945/project/1203301625297703/task/1209808486380252) +**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 storyboards | 🔄 4 storyboards + 1 xib left (`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 + +- [ ] PR [#6976](https://github.com/duckduckgo/apple-browsers/pull/6976) (AssetCatalogPlugin, reviewer ayoy): close, or keep until Xcode 27 is the minimum? Branch `alex/spm-asset-symbols-plugin`. +- [ ] Core Data branch `alex/coredata-code-models` (draft `PR.md`, Tech Design subtask): close. +- [ ] 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 a package.** 46 app files are also compiled into VPN / DBP agent / NetP extensions, with `#if NETWORK_EXTENSION` / `NETP_SYSTEM_EXTENSION` / `SANDBOX_TEST_TOOL`. They block moving the app code into a package. Old draft: worktree `netp-dependencies` (`alex/align-netp-dependencies`, Oct 2025, far behind main) — redo on fresh main rather than merge. +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`. + +## Worktrees + +| Worktree | Branch | What | +|---|---|---| +| `spm-asset-symbols-plugin` | `alex/spm-asset-symbols-plugin` | AssetCatalogPlugin, PR #6976 | +| `coredata-code-models` | `alex/coredata-code-models` | Code-defined Core Data models (cancelled) | +| `coredata-code-models-bookmarks` | `alex/coredata-code-models-bookmarks` | Bookmarks models (not started, cancelled) | +| `drop-sb-*` (5) | `alex/drop-*-storyboard`, `…-xib` | Remaining storyboards | +| `netp-dependencies` | `alex/align-netp-dependencies` | Old draft: move files by target | +| `vscode`, `vscode2` | `alex/fix-imports-cleanup`, `alex/vscode2` | Old: SwiftGenPlugin draft (uncommitted), root `Package.swift` | +| `sweetpad` | `alex/cursor-fix-build` | Old `.vscode` (SweetPad) config | + +Demo project proving the asset approach: `~/Developer/SPMAssetSymbolsDemo` (`./verify.sh`).