mirror of
https://github.com/abue-ammar/tinycast.git
synced 2026-10-02 00:04:44 +08:00
* Prepare extension runtime for menu bar commands * Host Raycast menu bar commands with transient runtimes * Stabilize extension menu layout and lifecycle * Restore menu dismissal and release runtime temporaries * Preserve pending menu actions and explicit launches * Render menu actions before loading icons * Promote menu interactions and retry returning icons * Keep cached menu actions responsive during reload * Prepare extension menus before opening from bottom edge * Match native status menu spacing on every display * Release extension HTTP sessions and reuse private transport * Record extension HTTP retention investigation and validation * Keep background refreshes out of the foreground runtime Rebasing onto main brought in scheduled no-view refresh, which shares the one JSContext with the palette. Four ways that went wrong: - A refresh that finished before its waiter registered recorded a timeout, so a fast command backed its own schedule off as though it had failed. - Boot and bundle reads suspend. A foreground launch in that gap aborted the refresh, but the refresh then started inside the context that replaced it. - Disabling extensions left a running "Refresh Now" alive, and a queued one could still start afterwards. - A scheduled command could not launch a sibling without naming its extension, since ownership resolved only from the foreground session. ExtensionBackgroundSession now owns one run: the outcome is buffered rather than signalled, and the first writer wins, so neither an early finish nor a late callback can be lost or overwritten. A preempted run is cancelled rather than recorded, leaving its schedule where it found it, and every suspension point rechecks session identity before touching the runtime. Also drops the duplicate ExtensionLaunchType the merge left in ExtensionBootConfig. All 64 harnesses pass; Debug builds with no new warnings. Verified against the real OpenCodex Usage and Port Manager menu commands. * Let AppKit own the extension status menu Clicking a second extension menu bar item while one was open only closed the first: the button drove a manual popUp, whose modal tracking loop swallowed the click instead of handing it to the other item. Two native menus hand off, and ours did not. Attach the menu to the status item and let AppKit position and track it, which restores that handoff along with Escape, outside clicks and click-to-close. The manual anchor maths and its two spacing constants go with it, since AppKit places the menu itself. The menu is attached once at init rather than per snapshot, so the first click opens it before any render has arrived. * Key menu icons by value instead of scanning for them A menu rebuilds every row on each React commit, and each row searched two arrays for its icon and a third for the failures. Small menus make that cheap, but it is linear work on a path that runs several times a second while a menu is open. RenderValue and RenderNode gain Hashable, so the cache becomes a dictionary and the failure list a Set. Same behaviour, no per-row scans. Also restores the guard that a menu bar extra with no rows detaches its menu, which the switch to AppKit tracking had dropped: without it an extension rendering nothing would open an empty menu. * Cut every menu bar comment back to one line * Drop the menu memory investigation log and table the shortcut keys The benchmark file recorded how one HTTP retention bug was found, which the feature doc already states as a rule. No other investigation is kept this way, so it goes rather than starting a convention. The named-key switch becomes the table it always was. * Reuse the existing refresh, metadata and icon paths for menu bar commands The branch was written against an older main and grew its own copies of machinery main already ships. Menu-bar activation and the saved button now live on the command's own ExtensionCommandMetadata record, so ExtensionMenuBarStore and extension-menu-bars.json go away and the writes coalesce on the metadata store's debounce instead of hitting the disk on every React commit. Menu-bar refresh cadence comes from ExtensionRefreshPolicy.nextDue, which adds the failure backoff and the per-command phase the hand-rolled scan never had. ExtensionBackgroundSession and its rewrite of the manager's background internals are gone: main's continuation path does the same work, so the scheduler is main's again. Manifest intervals parse once through ExtensionRefreshPolicy.parse, which takes a floor and now rejects an amount that overflows to infinity. Menu-bar icons load through ExtensionImage.load rather than restating its four bitmap cases, which also fixes fileIcon to draw fitted like every other icon here. Settings reads the manager directly, mirroring the background-refresh row, so the coordinator no longer threads through four views. * Reach the menu bar toggle through the extension coordinator A feature action belongs on its coordinator, with AppCore only locating it. The Show in menu bar toggle read and wrote ExtensionManager directly, past the coordinator the enable switch two hundred lines above already goes through.