commits
Add textAlreadyMatchesCommand guard — Tab only enters PARAM_MODE when
text fully matches command name. Partial match completes the name first.
New window opens about:blank in canvas page host with navbar focused
on URL bar. Inherits space mode from the focused window if active.
- Enable command cache version validation (isCacheValid was defined but never called)
- Restore missing scope/modes/hasCanExecute fields from cache
- Add ctx.value (raw input) as fallback in buildExecutionContext
- Add two more extraction fallbacks in extractSearchQuery + diagnostic logging
Extract openPopupInPageHost() shared function for popup creation.
Register setWindowOpenHandler on non-canvas web pages (modals, overlays,
slides) so JS-opened links always open in proper page host canvas windows
with navbar, widgets, and space mode inheritance.
- Union types: pre-resolved refs, cached sub-forms, instant variant switching
- External refs: full lexicon fetch for nested resolution
- Blob upload: drag-and-drop, preview, maxSize validation in generic forms
- Nested objects: collapsible sections, required-first sorting
- Client-side validation: field constraints, inline errors on blur
- Arrays: card-like UI for complex items with numbering
Use did-stop-loading as authoritative loading-done signal in addition
to did-finish-load. Handles JS redirects where error -3 fires for the
original URL while the redirect target is still loading.
Ensure OAuth callback handler properly closes the callback window
and prevents the localhost URL from landing in a page host.
Relax URL filter to save peek://ext/ and peek://app/ windows to the
closed stack. Store role in ClosedWindowEntry so windows reopen with
correct role. Exclude background.html and extension-host.html.
Canvas bounds adjustment only for web URLs.
Track latestNavigationUrl in did-start-navigation. In did-fail-load
error -3 handler, skip stopLoading() if the aborted URL differs from
the latest navigation — it's a redirect abort, not a real failure.
- Skip findWindowByUrl dedup when trackingSource is 'reopen'
- Add suppressClosedWindowPush flag to prevent duplicate stack entries
during quit (before-quit push + close event push were doubling up)
- Detect app.bsky.feed.post NSID and show specialized post composer
- Rich text facet detection: mentions, links, hashtags with UTF-8 byte offsets
- 300-grapheme counter with Intl.Segmenter (color warns near/over limit)
- Live post preview with highlighted facets
- Image embed: up to 4 images, alt text, aspect ratio, blob upload
- Language selector, auto-filled createdAt
- Session-bound blob uploader wired through template system
- Add webview crash handler with reload overlay (render-process-gone)
- Wrap show()/hide() setWindowPadding in try/finally for opacity safety
- Add myWindowId retry on failure (prevents all hotkeys breaking)
- Add global unhandledrejection handler
- Wrap all 8 did-navigate handlers in try/catch
- Isolate loading lifecycle notify callbacks
- Guard async setTimeout bodies with try/catch
- Revert adblocker toggle on error
Cancel active drag/hold/resize state before async toggleMaximize(),
guard all drag/resize handlers against isMaximized to prevent stale
bounds overwrites during the await suspension.
- Add params declarations to all websearch commands (manifest + dynamic)
- Forward params from manifest in lazy command registration
- Add extractSearchQuery helper for robust query extraction across entry modes
Subscribe to sync:pull-completed, item:created/deleted, tag:item-added/removed
so list views update when data changes (e.g., after sync).
- Closed window stack persisted to feature_settings DB on each push/pop
- Loaded from DB on startup via loadClosedWindowStack()
- On quit, all open content windows pushed onto stack before saving
- Stack increased from 20 to 50 entries
- If session restore fails, user can mash undo-close to recover everything
- 8 new persistence tests
Use setOverlayFocusTarget to store selected window ID before closing
the overlay, then focus it after hidden windows are restored.
- Restore page maximize feature lost in prior overwrites: toggle, edge-to-edge
webview, floating navbar, panel clamping, drag-out restore, dblclick, IPC handler
- Favicon: add preload API wrapper, Google favicon fallback in card-helpers,
entity enrichment persists favicons
- Space colors: vivid color assignment on load, shared resolve function in config.js
- Tests: 49 favicon unit tests, 22 maximize layout tests, 9 Playwright tests unskipped
- Complete group→space rename across backend, frontend, tests (~40 files)
- Complete extension_settings→feature_settings rename (~30 files, SQL migration)
- Strip all mode context calls from groups (pure data browser now)
- Fix 16 audit issues: IPC mismatches, mode values, metadata fields, widget CSS
- Add spaces feature files: background, config, border, home UI, manifest
- Add 41 new tests: space-mode, session migration, groups isolation
- Add 7 Claude Code skills: ship, fix, test, release, explore, review, ios-build
- Fix shichijuni theme missing font variables
- Fix ClosedWindowEntry type: groupMode→spaceMode
- Register spaces in CONSOLIDATED_EXTENSION_IDS
- Inject webauthn.js via executeJavaScript() on dom-ready for http/https
webviews, enabling navigator.credentials override in the main world
- Only injects when Proton Pass is loaded (isChromeExtensionLoaded check)
- Falls back to native WebAuthn if orchestrator not connected (5s timeout)
- Update compatibility doc: all 4 API blockers resolved, extension enabled
save_url was missing offline content fetch — tags were stored but
fetch_and_store_offline_content was never called. Also added offline
content fetching for items arriving via sync pull, and on-demand
fetch fallback in the UI when content is missing.
- Rewrite screen border to track focused window's mode, not all windows.
Border shows only when the focused window is a group member.
- Modal windows (cmd palette) are transparent to border state — opening
cmd while in a group keeps the border visible, preventing flicker.
- Remove groups URL auto-detection from detectModeFromUrl() — groups
home manages its own mode explicitly via setMode() calls.
- Add shutdown flag to prevent border recreation during quit.
- Add group-screen-border-spec.md with full visibility rules.
- Update tests: 19 focus-based border tests including modal exemption.
- Destroy group screen border overlay on app quit (was preventing
Electron from exiting since the hidden BrowserWindow stayed alive)
- Fix j/k/g/G keys being swallowed in tags input and notes panel —
pagestream nav handler now checks for focused input elements
- Add cleanupGroupScreenBorder() called in before-quit handler
- Add 70 unit tests for pagestream key navigation guards
- Fix README typo
- Remove lastFocusedVisibleWindowId fallback from auto-tagging and window-open
group mode inheritance. Group mode now only propagates through explicit
groupMode option or direct opener lineage, preventing leakage to items from
external apps, peeks, slides, and cmd palette.
- Add full-screen transparent overlay border when group mode is active: 4px solid
border with rounded corners and group name label. Vivid color resolution falls
back to iOS theme palette when group color is too desaturated. Debounced hide
(600ms) prevents flicker during navigation transitions.
- findWindowByUrl now only matches content/child-content windows, skipping
peeks, slides, modals, and other non-page-host window types.
- Add 32 unit tests for color resolution, leakage prevention, lineage scoping,
and border visibility logic.
- Fix card action button contrast in dark mode: use --base04 across all extensions
- Fix search checkbox toggle: refresh tags from datastore before re-render
- Add Delete/Backspace shortcut to delete items in search view
- Position remove-from-group button left of delete in group detail view
- Fix window centering on display switch: use cursor display instead of primary
- Fix download navigation: page stays loaded when clicking download links
- Migrate search list view to standard peek-card components
- Add download handling tests
- Fix extension ID mismatch: config.js IDs now match manifest IDs
- Fix ext:ready ordering: all background.html files call init() before publishing ext:ready
- Remove BroadcastChannel from websearch (origin mismatch), use IPC pubsub
- Add URL-based window dedup: opening same http/https URL focuses existing window
- Add link hover tooltip: status bar shows URL on webview link hover
- Remove debug TRACE logging from pubsub.ts, ipc.ts, preload.js, commands.js
- Add Playwright tests for websearch commands and window URL handling
- Add dev-both.sh: launches iOS simulator + Android emulator with HMR simultaneously
- iOS uses custom build pipeline (port 5188), Android uses tauri android dev
- Fix iOS device build: use cargo rustc --crate-type staticlib to avoid cdylib linker errors
- DRY up App.tsx: extract icon consts and reusable CardFooter/TodoCheckbox/TodayToggleButton/DeleteButton components
- Fix image items using hardcoded todo/done tags instead of configurable state
- Replace setImmediate fire-and-hope with hasSubscriber verification in handleLazyExtensionReady
- Add message buffering to lazy command stubs and event interceptors (latest wins, exactly-once replay)
- Add 10s safety timeout to loadLazyExtension to prevent callback accumulation
- Add hasSubscriber() with excludePrefix to pubsub for stub-aware verification
- Convert lex from declarative to lazy extension with noun system (lex/new lex/list lex)
- Remove 176+ dynamic lex command registrations, replace with single noun query/create
- Make tags page widget update reactively on tag:item-added/removed events
- Add pubsub and lazy-loading unit tests (24 tests)
- Add Playwright test for dynamic tags widget updates
The custom macOS menu was missing a Window submenu, so Cmd+W did nothing.
Added Window menu with Close Window item routing through closeOrHideWindow()
to preserve keepLive/modal hide behavior and child window cleanup.
Remove keyboard shortcuts from: tags, timers, tag-actions, feeds, scripts.
Normalize remaining shortcuts from Option+X to CommandOrControl+X.
Use Cmd+Shift for windows switcher and lists to avoid OS conflicts.
- Add will-download handler on profile session to save to ~/Downloads
and close the originating window (no page to display for downloads)
- Fix did-fail-load error -3 to clear loading state on download aborts
- Add 30s loading timeout safety net for permanently frozen windows
- Move did-attach-webview listener before loadURL so guest keyboard
shortcuts (Cmd+L navbar, Cmd+R reload, Cmd+[/] nav) are registered
before the webview attaches
ADDRESS_RE was too loose (case-insensitive, zero-length words, no mandatory
whitespace) causing strings like '16 yarn test' to match as street addresses.
- Remove /i flag from ADDRESS_RE (street suffixes must be capitalized)
- Require 2+ char words with mandatory whitespace between them
- Add optional city, state, zip tail matching
- Extract name/label context preceding addresses (business names, venues)
- Add migration to hard-delete regex-extracted false-positive place entities
- Add 20 new unit tests for address detection and label extraction
- Union types: pre-resolved refs, cached sub-forms, instant variant switching
- External refs: full lexicon fetch for nested resolution
- Blob upload: drag-and-drop, preview, maxSize validation in generic forms
- Nested objects: collapsible sections, required-first sorting
- Client-side validation: field constraints, inline errors on blur
- Arrays: card-like UI for complex items with numbering
- Detect app.bsky.feed.post NSID and show specialized post composer
- Rich text facet detection: mentions, links, hashtags with UTF-8 byte offsets
- 300-grapheme counter with Intl.Segmenter (color warns near/over limit)
- Live post preview with highlighted facets
- Image embed: up to 4 images, alt text, aspect ratio, blob upload
- Language selector, auto-filled createdAt
- Session-bound blob uploader wired through template system
- Add webview crash handler with reload overlay (render-process-gone)
- Wrap show()/hide() setWindowPadding in try/finally for opacity safety
- Add myWindowId retry on failure (prevents all hotkeys breaking)
- Add global unhandledrejection handler
- Wrap all 8 did-navigate handlers in try/catch
- Isolate loading lifecycle notify callbacks
- Guard async setTimeout bodies with try/catch
- Revert adblocker toggle on error
- Closed window stack persisted to feature_settings DB on each push/pop
- Loaded from DB on startup via loadClosedWindowStack()
- On quit, all open content windows pushed onto stack before saving
- Stack increased from 20 to 50 entries
- If session restore fails, user can mash undo-close to recover everything
- 8 new persistence tests
- Restore page maximize feature lost in prior overwrites: toggle, edge-to-edge
webview, floating navbar, panel clamping, drag-out restore, dblclick, IPC handler
- Favicon: add preload API wrapper, Google favicon fallback in card-helpers,
entity enrichment persists favicons
- Space colors: vivid color assignment on load, shared resolve function in config.js
- Tests: 49 favicon unit tests, 22 maximize layout tests, 9 Playwright tests unskipped
- Complete group→space rename across backend, frontend, tests (~40 files)
- Complete extension_settings→feature_settings rename (~30 files, SQL migration)
- Strip all mode context calls from groups (pure data browser now)
- Fix 16 audit issues: IPC mismatches, mode values, metadata fields, widget CSS
- Add spaces feature files: background, config, border, home UI, manifest
- Add 41 new tests: space-mode, session migration, groups isolation
- Add 7 Claude Code skills: ship, fix, test, release, explore, review, ios-build
- Fix shichijuni theme missing font variables
- Fix ClosedWindowEntry type: groupMode→spaceMode
- Register spaces in CONSOLIDATED_EXTENSION_IDS
- Inject webauthn.js via executeJavaScript() on dom-ready for http/https
webviews, enabling navigator.credentials override in the main world
- Only injects when Proton Pass is loaded (isChromeExtensionLoaded check)
- Falls back to native WebAuthn if orchestrator not connected (5s timeout)
- Update compatibility doc: all 4 API blockers resolved, extension enabled
- Rewrite screen border to track focused window's mode, not all windows.
Border shows only when the focused window is a group member.
- Modal windows (cmd palette) are transparent to border state — opening
cmd while in a group keeps the border visible, preventing flicker.
- Remove groups URL auto-detection from detectModeFromUrl() — groups
home manages its own mode explicitly via setMode() calls.
- Add shutdown flag to prevent border recreation during quit.
- Add group-screen-border-spec.md with full visibility rules.
- Update tests: 19 focus-based border tests including modal exemption.
- Destroy group screen border overlay on app quit (was preventing
Electron from exiting since the hidden BrowserWindow stayed alive)
- Fix j/k/g/G keys being swallowed in tags input and notes panel —
pagestream nav handler now checks for focused input elements
- Add cleanupGroupScreenBorder() called in before-quit handler
- Add 70 unit tests for pagestream key navigation guards
- Fix README typo
- Remove lastFocusedVisibleWindowId fallback from auto-tagging and window-open
group mode inheritance. Group mode now only propagates through explicit
groupMode option or direct opener lineage, preventing leakage to items from
external apps, peeks, slides, and cmd palette.
- Add full-screen transparent overlay border when group mode is active: 4px solid
border with rounded corners and group name label. Vivid color resolution falls
back to iOS theme palette when group color is too desaturated. Debounced hide
(600ms) prevents flicker during navigation transitions.
- findWindowByUrl now only matches content/child-content windows, skipping
peeks, slides, modals, and other non-page-host window types.
- Add 32 unit tests for color resolution, leakage prevention, lineage scoping,
and border visibility logic.
- Fix extension ID mismatch: config.js IDs now match manifest IDs
- Fix ext:ready ordering: all background.html files call init() before publishing ext:ready
- Remove BroadcastChannel from websearch (origin mismatch), use IPC pubsub
- Add URL-based window dedup: opening same http/https URL focuses existing window
- Add link hover tooltip: status bar shows URL on webview link hover
- Remove debug TRACE logging from pubsub.ts, ipc.ts, preload.js, commands.js
- Add Playwright tests for websearch commands and window URL handling
- Add dev-both.sh: launches iOS simulator + Android emulator with HMR simultaneously
- iOS uses custom build pipeline (port 5188), Android uses tauri android dev
- Fix iOS device build: use cargo rustc --crate-type staticlib to avoid cdylib linker errors
- DRY up App.tsx: extract icon consts and reusable CardFooter/TodoCheckbox/TodayToggleButton/DeleteButton components
- Fix image items using hardcoded todo/done tags instead of configurable state
- Replace setImmediate fire-and-hope with hasSubscriber verification in handleLazyExtensionReady
- Add message buffering to lazy command stubs and event interceptors (latest wins, exactly-once replay)
- Add 10s safety timeout to loadLazyExtension to prevent callback accumulation
- Add hasSubscriber() with excludePrefix to pubsub for stub-aware verification
- Convert lex from declarative to lazy extension with noun system (lex/new lex/list lex)
- Remove 176+ dynamic lex command registrations, replace with single noun query/create
- Make tags page widget update reactively on tag:item-added/removed events
- Add pubsub and lazy-loading unit tests (24 tests)
- Add Playwright test for dynamic tags widget updates
- Add will-download handler on profile session to save to ~/Downloads
and close the originating window (no page to display for downloads)
- Fix did-fail-load error -3 to clear loading state on download aborts
- Add 30s loading timeout safety net for permanently frozen windows
- Move did-attach-webview listener before loadURL so guest keyboard
shortcuts (Cmd+L navbar, Cmd+R reload, Cmd+[/] nav) are registered
before the webview attaches
ADDRESS_RE was too loose (case-insensitive, zero-length words, no mandatory
whitespace) causing strings like '16 yarn test' to match as street addresses.
- Remove /i flag from ADDRESS_RE (street suffixes must be capitalized)
- Require 2+ char words with mandatory whitespace between them
- Add optional city, state, zip tail matching
- Extract name/label context preceding addresses (business names, venues)
- Add migration to hard-delete regex-extracted false-positive place entities
- Add 20 new unit tests for address detection and label extraction