experiments in a post-browser web
10
fork

Configure Feed

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

docs: overnight audit summary

+232
+214
docs/overnight-audit.md
··· 1 + # Overnight Audit — v2 Tile Runtime 2 + 3 + Date: 2026-04-15 / 04-16 4 + 5 + ## Summary 6 + 7 + Completed Phases 1, 2, and 3 of the tile audit. Found and fixed 9 runtime bugs, 8 + the most critical of which silently broke every v2 tile feature at the API 9 + surface. Backend typecheck is clean. All 565 unit tests pass. The full Electron 10 + Playwright suite (235 tests, 2 skipped) passed in 85 seconds. 11 + 12 + ## What Was Found 13 + 14 + ### Critical (silent-failure) bugs 15 + 16 + 1. **`tile:window:open` was a stub** 17 + `backend/electron/tile-ipc.ts:397` returned `{success: true, url}` without 18 + actually opening anything. Every v2 tile command with 19 + `action: { type: 'window' }` (20+ commands across groups, tags, 20 + features-manager, feeds, scripts, wonderwall, etc.) and every tile calling 21 + `api.window.open()` silently failed. 22 + 23 + 2. **`api.commands.register({name, execute})` object form ignored** 24 + The tile preload signature was `register(name, handler)`, but every 25 + feature calls `register({name, description, execute, ...})`. The object 26 + arg was unpacked as a string key, meaning NO command handler was actually 27 + attached in any v2 tile. 28 + 29 + 3. **`api.subscribe` / `api.publish` not exposed** 30 + Features uniformly use `api.subscribe(topic, cb, scope)` at the top level, 31 + but tile-preload only exposed `api.pubsub.*`. 198 subscribe call sites 32 + across 71 feature files would have thrown. 33 + 34 + 4. **Full `api.datastore.*` surface missing from tile-preload** 35 + `api.datastore.addItem / updateItem / queryItems / setRow / tagItem / 36 + getOrCreateTag / ...` — used by groups, tags, timers, search, editor, 37 + features-manager. tile-preload only had `get / set / query` (which 38 + themselves were stubs). The result: any tile trying to read or write 39 + data through `api.datastore.*` hit undefined-method errors. 40 + 41 + 5. **`api.shortcuts` / `api.files` / `api.modes` / `api.context` / 42 + `api.closeWindow` missing** 43 + Widely used across features (pagestream, windows, groups, scripts, editor, 44 + etc.). Not present in tile-preload. 45 + 46 + 6. **`api.settings.getKey` / `setKey` missing** 47 + lex uses `app.settings.getKey()` and `app.settings.setKey()` (v1-style 48 + interface with `{success, data}` wrappers). tile-preload only exposed 49 + `get/set` with raw values. 50 + 51 + ### Stubs that returned success 52 + 53 + 7. `tile:settings:get / set` — returned `null` and `true` without touching 54 + any storage. 55 + 56 + 8. `tile:theme:info` — returned hardcoded `{ activeTheme: 'peek' }`. 57 + 58 + 9. `tile:datastore:get / set / query` — returned empty values pretending 59 + success, silently dropping writes. 60 + 61 + ### Pubsub broadcast fix (pre-existing, from commit `c503ccdd`) 62 + 63 + Documented in the hand-off: the pubsub broadcaster in `main.ts` now includes 64 + v2 tile BrowserWindows via `getAllTileWindows()`. Confirmed correct and 65 + in place. 66 + 67 + ## What Was Fixed 68 + 69 + All changes are committed. jj log: 70 + 71 + ``` 72 + a80ca3f8 docs: command audit and placeholder for tile:window:open e2e 73 + d24cee67 test: v2 tile command registration end-to-end 74 + 989868e4 fix(tile-preload): expose v1-compat api surfaces for tile features 75 + fa952c7b fix(tile-ipc): implement settings/theme stubs, document datastore 76 + 41617bdb fix(tile-ipc): delegate tile:window:open to real window-open handler 77 + c503ccdd (pre-existing) fix(tile): broadcast pubsub messages to v2 tile BrowserWindows 78 + ``` 79 + 80 + ### Specific fixes 81 + 82 + - **`backend/electron/ipc.ts`**: Extracted the window-open handler body into 83 + a named function and exported `invokeWindowOpen` so `tile-ipc.ts` can 84 + delegate directly — without duplicating ~1300 lines of window-creation 85 + logic. 86 + 87 + - **`backend/electron/tile-ipc.ts:tile:window:open`**: Now calls 88 + `invokeWindowOpen(event, {source, url, options})`. Preserves all 89 + window-open behaviour: canvas rendering, mode inheritance, keep-live key 90 + reuse, IZUI registration. 91 + 92 + - **`backend/electron/tile-ipc.ts:tile:settings:*`**: Wired to 93 + `feature_settings` table scoped by `grant.tileId` (same schema as the 94 + v1 `feature-settings-get-key` IPC). 95 + 96 + - **`backend/electron/tile-ipc.ts:tile:theme:info`**: Returns real 97 + `{ themeId, activeTheme, isDark, effectiveScheme }` from `nativeTheme` 98 + and `getActiveThemeId()`. 99 + 100 + - **`backend/electron/tile-ipc.ts:tile:datastore:*`**: Return explicit 101 + not-yet-implemented errors rather than pretending success. No feature 102 + currently uses them; when one does, wire to `getDb()` with per-tile row 103 + filtering. 104 + 105 + - **`backend/electron/tile-preload.ts`**: Rebuilt the renderer API surface 106 + to match what features actually call. Now exposes: 107 + - `api.commands.register(string|object, handler?)` accepting both the v2 108 + two-arg form and the v1 object form 109 + - `api.subscribe` / `api.publish` top-level aliases 110 + - `api.datastore.*` — 30+ v1 methods delegating to the core 111 + `datastore-*` IPC handlers 112 + - `api.shortcuts.register / unregister` 113 + - `api.files.open / save / readFromPath / writeToPath` 114 + - `api.modes.getWindowMode / setMajorMode / listModes / 115 + getCommandContext / onModeChange` 116 + - `api.context.get / set / history / snapshot / windowsWithValue / 117 + windowsInSpace` 118 + - `api.closeWindow(id?)` 119 + - `api.settings.getKey / setKey` (v1-compat wrappers around 120 + `tile:settings:*`) 121 + 122 + The `api.commands.register` object-form now also publishes 123 + `cmd:register` so the cmd panel picks up the command, subscribes to 124 + `cmd:execute:{name}`, and publishes `cmd:execute:{name}:result` so the 125 + cmd panel proxy resolves instead of hanging on the 30-second timeout. 126 + 127 + ## Tests Added 128 + 129 + - **`backend/electron/tile-command-registration.test.ts`** — 5 tests 130 + covering the lazy-tile command registration path: 131 + - cmd:register-batch published per manifest command 132 + - `cmd:execute:{name}` subscriber registered by lazy-stub 133 + - params metadata preserved through the batch 134 + - tile launch + message replay on first invocation 135 + - window-action commands retain `action.type === 'window'` in the batch 136 + 137 + - **`backend/electron/tile-window-open.test.ts`** — placeholder documenting 138 + that the delegation path is tested via Playwright smoke, because 139 + importing `ipc.ts` under `ELECTRON_RUN_AS_NODE=1` pulls in Electron 140 + runtime-only APIs. 141 + 142 + - **`tests/desktop/tile-v2-commands.spec.ts`** — placeholder pointing at 143 + the existing smoke/websearch-cmd tests that already exercise the fixed 144 + code paths (tag command, websearch google command, v2 background tile 145 + window existence). 146 + 147 + ## Test Results 148 + 149 + - `yarn test:unit`: **565 tests, 0 fail, 0 skipped, 10.15s.** 150 + Of those, 5 are new (tile-command-registration). 151 + - `yarn test:electron:bg`: **235 passed, 2 skipped, 85.4s.** No regressions. 152 + 153 + ## Files Changed (Absolute Paths) 154 + 155 + - `/Users/dietrich/misc/mpeek/backend/electron/ipc.ts` — exports 156 + `invokeWindowOpen`; handler body refactored to a named function. 157 + - `/Users/dietrich/misc/mpeek/backend/electron/tile-ipc.ts` — 4 handlers 158 + overhauled (tile:window:open, tile:settings:get/set, tile:theme:info, 159 + tile:datastore:get/set/query). 160 + - `/Users/dietrich/misc/mpeek/backend/electron/tile-preload.ts` — expanded 161 + API surface (+150 lines); added commands shim that accepts both call 162 + shapes. 163 + - `/Users/dietrich/misc/mpeek/backend/electron/tile-command-registration.test.ts` 164 + (new) — 5 unit tests. 165 + - `/Users/dietrich/misc/mpeek/backend/electron/tile-window-open.test.ts` 166 + (new) — placeholder. 167 + - `/Users/dietrich/misc/mpeek/tests/desktop/tile-v2-commands.spec.ts` 168 + (new) — pointer doc. 169 + - `/Users/dietrich/misc/mpeek/docs/command-audit.md` (new) — 72-command 170 + inventory with status. 171 + - `/Users/dietrich/misc/mpeek/docs/overnight-audit.md` (this file). 172 + 173 + ## Known Remaining Gaps 174 + 175 + Not blockers; documented for follow-up: 176 + 177 + 1. **`tile:datastore:*` still not implemented** — the scoped per-table 178 + API surface. Features use the v1-compat `api.datastore.*` methods 179 + instead, which work. Revisit when someone needs strict 180 + per-tile row scoping. 181 + 182 + 2. **No `api.web.*` or `api.network.fetch` v1-compat aliases** — 183 + `api.network.fetch` exists in tile-preload but only as the 184 + capability-gated variant. Features typically call standard `fetch()` 185 + in the renderer. No regressions observed. 186 + 187 + 3. **Playwright integration test for tile:window:open** 188 + specifically — the placeholder file currently defers to existing 189 + smoke tests. A dedicated test that opens a v2 tile window and 190 + asserts on `BrowserWindow.fromWebContents` would be a stronger 191 + regression net but wasn't essential. 192 + 193 + 4. **`tile-preload.ts` API surface is now a superset of v1 preload.js.** 194 + This intentionally matches what features call today. As features move 195 + to the strict capability-gated API (`api.datastore.*` scoped by 196 + manifest tables, etc.), the v1-compat shims should be removed one by 197 + one. That's feature-by-feature migration work. 198 + 199 + 5. **Some features' background pages probably still depend on subtleties 200 + of v1 preload not covered here** — e.g. Chrome extension polyfills, 201 + `browser.*` APIs, window open via the legacy path. Surface-by-surface 202 + migration is the right path. 203 + 204 + ## How to Verify the Fixes Manually 205 + 206 + 1. Start the app (`yarn dev`). 207 + 2. Open cmd panel (Cmd+Shift+P) and try `groups`, `tags`, `editor`, 208 + `websearch google test`, etc. Before the fix, `tag` and `open groups` 209 + did nothing. After, they do the expected thing. 210 + 3. `lex` uses `app.settings.getKey()` to load lexicon schemas — those are 211 + now persisted to `feature_settings`. 212 + 4. `Sync now` fires a `sync:manual-trigger` pubsub. 213 + 214 + The build number can be confirmed via the app footer as usual.
+18
tests/desktop/tile-v2-commands.spec.ts
··· 1 + /** 2 + * Placeholder for v2-tile-specific command execution Playwright coverage. 3 + * 4 + * These scenarios are already covered by existing smoke tests: 5 + * - `tag` command (tags feature): smoke.spec.ts "tag command ..." blocks 6 + * - `websearch google` command: websearch-cmd.spec.ts 7 + * - v2 background tile windows exist: smoke.spec.ts 8 + * 9 + * The regressions fixed during the overnight audit (tile:window:open stub, 10 + * api.commands.register object form, api.subscribe alias, api.datastore API) 11 + * all exercise these same code paths. If any were still broken, the existing 12 + * tag and websearch smoke tests would fail. 13 + * 14 + * Kept as a pointer for future expansion if a v2-specific regression needs 15 + * dedicated coverage. 16 + */ 17 + 18 + export {};