Commit Graph

9 Commits

Author SHA1 Message Date
Brooklyn Nicholson c57f8ad4e1 feat(desktop): PluginOs gains native save/open file pickers
Plugins had no sanctioned way to ask for a file path — the OS door
carried notify, openExternal, revealPath and writeClipboard, so anything
needing a dialog had to reach around the SDK for window.hermesDesktop.

pickSavePath and pickOpenPath wrap the existing selectSavePath /
selectPaths IPC with the door's usual contract: resolve null when the
bridge is missing or the user cancels, never throw at the plugin.
2026-08-28 22:38:01 -05:00
hermes-seaeye[bot] 72f9e01497 fmt(js): npm run fix on merge (#89492)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-18 21:38:17 +00:00
seref 73ddf6665c feat(desktop): rich plugin OS notifications with deeplink activation
Extends ctx.os.notify (the curated plugin OS door from #78685) with icon,
action buttons, and a serializable `activate` target. Body/action clicks
focus the window and navigate to the plugin's screen; activation paths
share one resolver (hermes-open-target.ts) with hermes:// OS deep links,
so `hermes://index-network/intent/1`, `/index-network/intent/1`, and
{ path, params } all land on the same hash-router route. Approval
notifications keep their existing session-scoped channel.

Salvaged from PR #84192 by @serefyarar (net diff of the PR branch applied
onto current main; branch carried merge commits so a single authored
commit preserves attribution).
2026-08-18 14:26:28 -07:00
Brooklyn Nicholson 44790bc9c8 feat(desktop): plugin descriptions + open the agent plugins folder
HermesPlugin/PluginRecord gain a description one-liner (kanban gets
one) shown in the inventory instead of the raw file path, and the
agent plugins section can open the backend's plugins dir — path from
config.get profile so it's profile-aware, local backends only since
openDir mkdir-creates.
2026-08-08 17:34:20 -05:00
Brooklyn Nicholson e8ccb4a2ea feat(desktop): ctx.os — the curated OS door for plugins
Fold ctx.notifyNative into a ctx.os namespace so every way a plugin
reaches outside the app window lives behind one attributed door instead
of accreting one top-level ctx method per capability:

- ctx.os.notify — the native-notification door from the previous commit,
  unchanged semantics (plugin kind pref, away-gating, per-plugin throttle).
- ctx.os.openExternal / ctx.os.revealPath / ctx.os.writeClipboard — the
  existing window.hermesDesktop bridge capabilities, now sanctioned and
  result-shaped: each resolves false (never throws) when the bridge or
  member is missing, so a plugin branches on the result instead of
  sniffing the preload surface or crashing on an older shell.

No new Electron surface: everything routes through bridge members the
app already ships; the notification path keeps every existing gate.
2026-08-04 11:33:25 -06:00
seref 5d24594ab3 feat(desktop): expose native OS notifications to plugins via ctx.notifyNative
Desktop plugins can toast in-app (host.notify) but have no sanctioned way to
reach the OS notification pipeline the app's own approval/turn alerts use, so
a plugin surfacing a genuinely notable background event (e.g. a discovery
plugin finding a match) stays invisible once the user steps away from Hermes.

Add a curated per-plugin door instead of exporting the raw dispatcher:

- ctx.notifyNative({ title, body?, silent? }) on PluginContext — attributed
  to the plugin id, routed through dispatchNativeNotification so every
  existing gate applies (master + per-kind prefs, post-connect baseline,
  away-from-app gating, throttle).
- New 'plugin' native-notification kind with its own Settings ▸ Notifications
  toggle (default on), so users silence plugins without losing app alerts.
- New optional `tag` discriminator on the notify payload keys the renderer
  throttle and main-process cross-window dedupe per plugin, so two plugins
  can't collapse each other's session-less notifications.

Consumer: the Index Network desktop plugin wants background opportunity
alerts; anything in ~/.hermes/desktop-plugins gets the same door.
2026-08-04 11:28:20 -06:00
Brooklyn Nicholson 77f1e84a34 feat(desktop): plugin ctx.onDispose + self-disposing kanban bindApi
The plugin context only tracked contribution/socket disposers, so a plugin's
other side effects (store subscriptions) leaked across disable/re-enable. Add
ctx.onDispose(fn) — an arbitrary cleanup collected alongside the rest and run
on deactivate. bindApi now returns a disposer (unsubscribes its persisted-atom
listeners, closes the socket, drops the rest handle) and the kanban plugin
registers it via ctx.onDispose, so a toggle leaves nothing behind and never
duplicates listeners. Also DRYs the atom-persistence into one `persist` helper.
2026-07-30 07:18:08 -05:00
Brooklyn Nicholson bba18c6008 feat(desktop): expose ctx.i18n on the plugin SDK
Wire the scoped translator into the plugin context alongside storage/rest/
socket, and export usePluginI18n + the bundle types from @hermes/plugin-sdk.
The runtime shim re-exports the barrel automatically, so disk/third-party
plugins get the same door as bundled ones.
2026-07-19 00:05:08 -04:00
Brooklyn Nicholson aefb36299a feat(desktop): contribution registry — namespaced areas, keybinds, palette 2026-07-13 17:57:53 -04:00