experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs(tasks): mark v1-removal + v2/v1 cmd:execute result task as DONE

+2 -2
+2 -2
docs/tasks.md
··· 28 28 ## Tile architecture cleanup (post-conversion) 29 29 30 30 - [ ] **Merge websearch's separate background tile into the home window.** Manifest has two tile entries: `background.html` (lazy:true) for settings/engine state, `home.html` for the UI. They communicate via pubsub round-trips (`websearch:engine-request` → `websearch:engines-list`) across `peek://ext/websearch/background.html` vs `peek://websearch/home.html`. Cross-window pubsub within one feature is fragile (see 2026-04-20 session — broadcaster echo-prevention bug + cluster 3 regression risk). The round-trip also blocks 3 websearch tests from passing. With the single-file tiles model shipping (`resident: true`), websearch can collapse to one tile whose home window owns both UI and engine state directly. No IPC needed. Applies also to any feature tile with a bg + window pair that pubsubs between itself — audit other candidates. 31 - - [ ] **Remove v1 entirely.** Single source of truth: every renderer runs through `tile-preload.cts` against `tile:*` IPC. No more consolidated extension host iframes, no more legacy IPC channels, no more dual paths in tile-preload. See [v1-removal-plan.md](v1-removal-plan.md). This is the root fix for the v2→v1 routing flakies (kagi/tag/widget-update tests, ~10 tests blocked) — the boundary disappears, the bugs disappear with it. Phased: (1) cmd/hud/page core scripts → tile-preload, (2) test fixture → tile-preload, (3) delete v1 plumbing, (4) manifest cleanup. ~5–6 days. 31 + - [x] **Remove v1 entirely.** DONE 2026-04-24 — 36 commits stacked off main. ipc.ts has zero legacy `ipcMain.handle` calls; every renderer routes through `tile-preload.cts` against strict capability-gated `tile:*` IPC. Delivered: Phases 3.7b/d/e/f/g/h IPC migrations, Phase 4 manifest schema cutover (drop `type`/`windowHints`, bump to v3), declarative-command machinery deleted, lazy-extension parallel mechanism deleted, vestigial `tile:extensions:*` surface merged into `tile:features:*`, `extensionPaths` → `tilePaths`, `ext:*` startup topics → `feature:*`, `extensions` SQLite table dropped, internal "extension" vocabulary purged from non-Chrome-MV3 paths. Validation: Playwright 223/0, unit tests 2277/0. Deferred follow-ups tracked separately below (Tauri rename, bootstrap IPC migration). 32 32 - [x] **Single-file tiles as default model.** Shipped 2026-04-17: `resident: true` marker + flat window fields on TileEntry, `api.window.showSelf/hideSelf` (token-scoped, no capability), hello-world/widget-demo/mcp-server converted. Plan: `docs/tiles-single-file.md`. 33 33 - [x] **Theme live-reload in open tiles.** RESOLVED 2026-04-23. Root: every tile `@import url('peek://theme/variables.css')` resolved once at CSS load and cached in the CSSOM. Additionally, the three theme-change broadcasts (`theme:changed`, `theme:themeChanged`, `theme:windowChanged`) used different channel names than `api.theme.onChange` listened on (`tile:theme:changed`), so the existing hook was dead code — no subscriber would have fired anyway. Fix: (a) consolidated all three broadcasts to the single `tile:theme:changed` channel with a `{kind, ...}` discriminated payload so every existing `api.theme.onChange` call automatically works; (b) added a preload-level listener (not per-tile) that, on each `tile:theme:changed`, injects a cache-busted `<link rel="stylesheet" href="peek://theme/variables.css?v=TS">` and removes the previous override after the new one loads. Every tile now gets live theme updates for free — no per-feature wiring. 34 34 ··· 40 40 - [ ] **Migrate bootstrap IPC channels to tile:lifecycle:* namespace.** `session-restore-pending` and `frontend-ready` in `backend/electron/entry.ts` are bare `ipcMain.handle()` registrations from before the tile system initializes. They're only reachable from trustedBuiltin renderers via `api.invoke()`, so the security gap is theoretical, but they're the last bare main-process IPC handlers outside `tile-ipc-gate.ts`. Decision skipped 2026-04-24: leaving them bare for now since they exist *before* any tile loads — the indirection through tile-ipc-gate would require either bootstrapping the gate earlier or having two IPC modes (bootstrap vs. post-init). Worth revisiting if tile-ipc-gate ever gains a "no token required for these specific channels" mode, or if entry.ts gets folded into a tile lifecycle. 41 41 - [ ] **Page host window jumps to wrong position after switching primary monitor.** Repro: connect external monitor, set it primary; open page host (cmd+L); disconnect/swap so the laptop becomes primary; cmd+L again — the whole window shifts to a different (off-screen / wrong-display) position. Likely cause: `computeWindowBounds`/canvas positioning caches screen bounds at first compute or reads stale `screen.getPrimaryDisplay()`/`getDisplayNearestPoint` results across display topology changes. Fix path: subscribe to Electron's `screen` `display-added`/`display-removed`/`display-metrics-changed` events and recompute the page-host window's normal+maximized bounds against current displays before show; clamp restored positions to a visible display. Surfaced 2026-04-24. 42 42 - [x] **post.nl → postnl.nl redirect shows blank page.** Fixed 2026-04-17 commit `5dfa3e7a` — `did-redirect-navigation` listener in `app/page/page.js` updates `latestNavigationUrl` so the did-fail-load(-3) handler doesn't abort the redirect target mid-load. 43 - - [ ] **v2 tile `cmd:execute:<name>:result` doesn't reach v1 extension-host subscribers.** (Will be obsolete after v1 removal — see [v1-removal-plan.md](v1-removal-plan.md). Documented here in case a quick patch is desired before that lands.) Tests in `smoke.spec.ts` (Command Execution describe — tag/untag/tagset/widget-update tests, ~7 of them) publish `cmd:execute:tag` from bgWindow with `expectResult:true, resultTopic:'cmd:execute:tag:result'`, then subscribe to that result topic. The tags v2 tile receives the publish, runs `executeTag()`, and tile-preload sends `tile:pubsub:publish` with the result topic — BUT the bgWindow subscriber never fires. Confirmed: 2026-04-17 added `cmd:execute:*` to tags' pubsub allowlist (in `b3a80b27`) and `waitForCommand` in beforeAll (in `daa4221a`); both necessary but tests still time out at 10s. Per Opus agent triage: bgWindow is `peek://app/background.html`, NOT in `extensionHostWindow`/`extensionWindows`/`getAllTileWindows()` — `extensionBroadcaster` skips it. bgWindow subscribes via legacy `IPC_CHANNELS.SUBSCRIBE` (`ipc.ts:4466`); the in-proc callback should fire on `publish()` but doesn't. That's the next concrete investigation. 43 + - [x] **v2 tile `cmd:execute:<name>:result` doesn't reach v1 extension-host subscribers.** OBSOLETED 2026-04-24 by v1 removal. `extensionHostWindow`, `extensionWindows`, the v1 branch of `extensionBroadcaster`, and `IPC_CHANNELS.SUBSCRIBE`/`PUBLISH` are all gone. The test fixture is now a tile (`peek://test/index.html`) using `tile-preload.cts` with a trustedBuiltin grant, so it sits in the same capability-gated pubsub fabric as every other tile. Result-topic propagation now works through the standard `tile:pubsub:publish` path with no v2↔v1 seam to cross. 44 44 - [ ] **Proton Pass extension doesn't autofill.** Still broken — doesn't show up in form fields, no autofill suggestions. Likely a content-script injection or messaging API gap in the webview/canvas setup. Reproduce: install Proton Pass extension, navigate to any login page, observe no inline autofill UI. (2026-04-17: agent triaged, 5 hypotheses in agent-ae11e03d worktree — extension gitignored so couldn't repro.) 45 45 - [x] **Download save failing.** Fixed 2026-04-17 commit `ab66d9e0` — cause (a): `setSavePath()` with existing path silently fails. Added `resolveUniqueDownloadPath()` in `session-partition.ts` that appends `-1`, `-2`, etc. before the extension. 46 46 - [x] **`target=_blank` download popup window not cleaned up.** RESOLVED 2026-04-23. Root: the `will-download` handler was registered on `profileSession` (the BrowserWindow's session) but not on the webview guest's partition session. Webview partitions are set async in `app/page/page.js:645` to `persist:<profileId>`; even when that's the same profile string, `session.fromPartition` returns its own Session instance that doesn't share event listeners with the BrowserWindow's `profileSession`. The three explicit `registerDownloadHandler` sites (session init + popup did-attach-webview + canvas did-attach-webview) still had gaps in popup-spawned-from-popup edge cases and test harness paths. Fix: blanket-register via `app.on('web-contents-created', wc => registerDownloadHandler(wc.session))` in `backend/electron/entry.ts`. Every webContents (top-level, webview guest, popup, extension) gets its session covered. `registerDownloadHandler` is already idempotent via WeakSet so the existing explicit sites remain harmless belt-and-suspenders. Test: `yarn test:grep "target=_blank download cleans up"` passes 1/1 in 5.7s; full suite 229/0.