Files
tinycast/Scripts
Jonas List a27fd41638 Run an extension's menu bar command, and draw its item natively (#963)
* 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.
2026-09-21 01:17:49 +06:00
..
2026-08-14 20:35:26 +06:00
2026-08-09 00:38:33 +06:00