@liminal-hq/plugin-desktop-integration 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +83 -12
  2. package/api-iife.js +94 -0
  3. package/dist-js/bindings/ActionButton.d.ts +14 -0
  4. package/dist-js/bindings/ActionButton.d.ts.map +1 -0
  5. package/dist-js/bindings/Feature.d.ts +5 -0
  6. package/dist-js/bindings/Feature.d.ts.map +1 -0
  7. package/dist-js/bindings/FeatureStatus.d.ts +18 -0
  8. package/dist-js/bindings/FeatureStatus.d.ts.map +1 -0
  9. package/dist-js/bindings/FileManagerCall.d.ts +14 -0
  10. package/dist-js/bindings/FileManagerCall.d.ts.map +1 -0
  11. package/dist-js/bindings/FileManagerMethod.d.ts +5 -0
  12. package/dist-js/bindings/FileManagerMethod.d.ts.map +1 -0
  13. package/dist-js/bindings/FileManagerOwnership.d.ts +14 -0
  14. package/dist-js/bindings/FileManagerOwnership.d.ts.map +1 -0
  15. package/dist-js/bindings/FileManagerTarget.d.ts +14 -0
  16. package/dist-js/bindings/FileManagerTarget.d.ts.map +1 -0
  17. package/dist-js/bindings/GlobalShortcutPressed.d.ts +7 -0
  18. package/dist-js/bindings/GlobalShortcutPressed.d.ts.map +1 -0
  19. package/dist-js/bindings/GlobalShortcutRequest.d.ts +14 -0
  20. package/dist-js/bindings/GlobalShortcutRequest.d.ts.map +1 -0
  21. package/dist-js/bindings/LauncherProgress.d.ts +12 -0
  22. package/dist-js/bindings/LauncherProgress.d.ts.map +1 -0
  23. package/dist-js/bindings/LauncherRequest.d.ts +23 -0
  24. package/dist-js/bindings/LauncherRequest.d.ts.map +1 -0
  25. package/dist-js/bindings/NotificationAction.d.ts +15 -0
  26. package/dist-js/bindings/NotificationAction.d.ts.map +1 -0
  27. package/dist-js/bindings/NotifyRequest.d.ts +37 -0
  28. package/dist-js/bindings/NotifyRequest.d.ts.map +1 -0
  29. package/dist-js/bindings/PluginStatus.d.ts +21 -0
  30. package/dist-js/bindings/PluginStatus.d.ts.map +1 -0
  31. package/dist-js/bindings/ServiceError.d.ts +9 -0
  32. package/dist-js/bindings/ServiceError.d.ts.map +1 -0
  33. package/dist-js/bindings/ServiceErrorKind.d.ts +5 -0
  34. package/dist-js/bindings/ServiceErrorKind.d.ts.map +1 -0
  35. package/dist-js/bindings/ShortcutChangedPayload.d.ts +11 -0
  36. package/dist-js/bindings/ShortcutChangedPayload.d.ts.map +1 -0
  37. package/dist-js/bindings/SleepInhibitHandle.d.ts +7 -0
  38. package/dist-js/bindings/SleepInhibitHandle.d.ts.map +1 -0
  39. package/dist-js/bindings/SleepInhibitRequest.d.ts +15 -0
  40. package/dist-js/bindings/SleepInhibitRequest.d.ts.map +1 -0
  41. package/dist-js/bindings/SleepKind.d.ts +5 -0
  42. package/dist-js/bindings/SleepKind.d.ts.map +1 -0
  43. package/dist-js/bindings/UnavailableReason.d.ts +5 -0
  44. package/dist-js/bindings/UnavailableReason.d.ts.map +1 -0
  45. package/dist-js/bindings/Urgency.d.ts +5 -0
  46. package/dist-js/bindings/Urgency.d.ts.map +1 -0
  47. package/dist-js/index.cjs +94 -0
  48. package/dist-js/index.cjs.map +1 -1
  49. package/dist-js/index.d.ts +98 -1
  50. package/dist-js/index.d.ts.map +1 -1
  51. package/dist-js/index.js +88 -1
  52. package/dist-js/index.js.map +1 -1
  53. package/dist-js/index.test.d.ts +2 -0
  54. package/dist-js/index.test.d.ts.map +1 -0
  55. package/package.json +1 -1
package/README.md CHANGED
@@ -64,6 +64,12 @@ confirmation dialog. Call `set_shortcut_window(&window)` once your first window
64
64
  shown to kick off the deferred binding, and listen for the `shortcut-binding-result`
65
65
  event to know when it resolves.
66
66
 
67
+ The compositor's own settings UI can also rebind the shortcut independently of the app
68
+ (e.g. GNOME Settings → Apps → <App> → Global Shortcuts) — listen for the
69
+ `shortcut-changed` event (Wayland-only) to keep your own UI in sync.
70
+ `DesktopIntegrationExt::last_shortcut_trigger_description` covers the race where the
71
+ rebind happens before your listener attaches.
72
+
67
73
  ### JavaScript
68
74
 
69
75
  JS-only apps (no custom Rust command of their own) can register shortcuts directly —
@@ -90,18 +96,65 @@ Rust consumers should prefer calling `DesktopIntegrationExt::register_shortcut`
90
96
  from `setup()` — it delivers activation via a real closure instead of an event
91
97
  round-trip. The `register_shortcut` command exists specifically for JS-only consumers.
92
98
 
99
+ To detect an external rebind (Wayland-only), listen for `shortcut-changed` directly via
100
+ `@tauri-apps/api/event`, and use `checkShortcutTriggerDescription` as a race guard for
101
+ UI that mounts after a missed event:
102
+
103
+ ```typescript
104
+ import { listen } from '@tauri-apps/api/event';
105
+ import {
106
+ desktopIntegration,
107
+ type ShortcutChangedPayload,
108
+ } from '@liminal-hq/plugin-desktop-integration';
109
+
110
+ await listen<ShortcutChangedPayload>('shortcut-changed', ({ payload }) => {
111
+ console.log(`rebound externally to: ${payload.triggerDescription}`);
112
+ });
113
+
114
+ const lastKnownTrigger = await desktopIntegration.checkShortcutTriggerDescription();
115
+ ```
116
+
117
+ ### Services
118
+
119
+ Besides window activation and shortcuts, the plugin offers desktop services that are not behind a portal. Use [`@liminal-hq/plugin-xdg-portal`](../xdg-portal) first where the portal exists, and these where it does not (or on Windows). Every service rejects with a `ServiceError`, `{ kind, message }`, where `kind` is one of `unsupported-platform`, `unavailable`, `needs-app-id`, `invalid-argument`, `not-found`, `conflict`, `timeout` or `failed`. D-Bus work runs off the main thread and every call is bounded by a 5 second timeout.
120
+
121
+ `getStatus()` reports, per feature (`notify`, `notificationActions`, `inhibitSleep`, `launcherProgress`, `fileManager`, `globalShortcuts`), whether it works here and, if not, a typed `reason` (`platform-unsupported`, `no-session-bus`, `no-notification-server`, `no-logind`, `needs-app-id`, `no-display-server`, `actions-unsupported`) with the `detail` behind it. Hide options whose feature is unavailable.
122
+
123
+ - **Notifications:** `notify({ id, title, body, defaultAction, urgency })` shows a notification and replaces the one with the same `id`; `withdrawNotification(id)` closes it; `onNotificationAction` reports a click on it as `{ id, action }`. On Linux it calls `org.freedesktop.Notifications` and sets the `desktop-entry` hint from `desktopId` (default: the bundle identifier). Add up to three buttons with `actions: [{ id, label }]` (ids are 1 to 256 bytes, unique, not `default` and different from `defaultAction`; labels are 1 to 100 characters; further buttons are dropped with a log line): they go to the `actions` array of `Notify` after the `default` key that `defaultAction` adds, and a press arrives through `onNotificationAction` as `{ id, action }` with the button's id. Signals for notifications this plugin did not send are ignored. The `notificationActions` feature is available when the server lists the `actions` capability; some servers show only the default click, and `detail` says so. On Windows it shows a WinRT toast, which needs an AppUserModelID: set one with `setAppUserModelId(id)` (or `SetCurrentProcessExplicitAppUserModelID` yourself) and until then `notify` rejects with `needs-app-id`.
124
+ - **Sleep inhibit:** `inhibitSleep({ reason, kinds })` returns a `handle` for `releaseSleepInhibit`. On Linux it takes a blocking `sleep` (and, with the `idle` kind, `idle`) inhibitor from systemd-logind and holds its file descriptor; on Windows it holds a `PowerCreateRequest` for `PowerRequestSystemRequired`. Inhibitors end when released or when the app exits.
125
+ - **Launcher progress:** `setLauncherProgress({ progress, count, desktopId, windowLabel })` shows `{ state: 'value', value }` (0 to 1), `{ state: 'indeterminate' }` or `{ state: 'cleared' }`. On Linux it emits the `com.canonical.Unity.LauncherEntry` `Update` signal (`progress`, `progress-visible`, `count`, `count-visible`) for `application://<desktopId>.desktop`; docks have no indeterminate state, so it shows an empty bar, and the signal is a broadcast that succeeds whether or not a dock listens. On Windows it sets `ITaskbarList3` progress on the button of `windowLabel` (default: the focused window, else the first label starting with `main`, else the first label in alphabetical order).
126
+ - **File manager (Linux):** `ownFileManager()` takes `org.freedesktop.FileManager1` and serves `ShowFolders`, `ShowItems` and `ShowItemProperties`; each call arrives through `onFileManagerCall` as `{ method, targets, startupId }`, where each target has the URI and, for `file:` URIs on this machine, the decoded local `path`. A call with no usable URI is refused. Another process can take the name over (the app allows replacement); `onFileManagerOwnership` then reports `owned: false` (only for the ownership that lost the name, so giving the name back and taking it again is not undone by a late loss). `ownFileManager` rejects with `conflict` when another process holds the name and will not give it up, and `disownFileManager()` gives it back. Ship a D-Bus activation file for the name if the app should be started by other applications' calls.
127
+ - **Windows global shortcuts:** `registerGlobalShortcut({ id, accelerator })` registers `RegisterHotKey` on a message-only window thread (an accelerator such as `Ctrl+Alt+K` with at least one modifier) and `onShortcutPressed` reports `{ id }`; `unregisterGlobalShortcut(id)` removes it. Registering an id again replaces its accelerator (the same accelerator included); a combination another application holds rejects with `conflict`, and the earlier binding of that id then stays. A call that rejects with `timeout` did not take effect and can be retried. On Linux use `registerShortcut`.
128
+
129
+ ```typescript
130
+ import { desktopIntegration, isFeatureAvailable } from '@liminal-hq/plugin-desktop-integration';
131
+
132
+ const status = await desktopIntegration.getStatus();
133
+ if (isFeatureAvailable(status, 'launcherProgress')) {
134
+ await desktopIntegration.setLauncherProgress({
135
+ progress: { state: 'value', value: 0.4 },
136
+ count: 2,
137
+ desktopId: null,
138
+ windowLabel: null,
139
+ });
140
+ }
141
+ ```
142
+
143
+ From Rust, `app.desktop_services()` (the `DesktopServicesExt` trait) offers the same calls as async methods: `status`, `notify`, `withdraw_notification`, `inhibit_sleep`, `release_sleep_inhibit`, `set_launcher_progress`, `own_file_manager`, `disown_file_manager`, `register_global_shortcut`, `unregister_global_shortcut` and `set_app_user_model_id`. Events are emitted to every window, and Rust code can `listen` to them too.
144
+
93
145
  ### Generated types
94
146
 
95
- `ShortcutBindingResult` and `ShortcutActivatedPayload` (the payloads of the
96
- `shortcut-binding-result` and `shortcut-activated` events) are generated from their Rust
97
- definitions via [`ts-rs`](https://github.com/Aleph-Alpha/ts-rs) into
98
- `guest-js/bindings/` and re-exported from the package root, so the JS/Rust shapes can't
99
- drift:
147
+ `ShortcutBindingResult`, `ShortcutActivatedPayload`, and `ShortcutChangedPayload` (the
148
+ payloads of the `shortcut-binding-result`, `shortcut-activated`, and `shortcut-changed`
149
+ events) are generated from their Rust definitions via
150
+ [`ts-rs`](https://github.com/Aleph-Alpha/ts-rs) into `guest-js/bindings/` and re-exported
151
+ from the package root, so the JS/Rust shapes can't drift:
100
152
 
101
153
  ```typescript
102
154
  import type {
103
155
  ShortcutActivatedPayload,
104
156
  ShortcutBindingResult,
157
+ ShortcutChangedPayload,
105
158
  } from '@liminal-hq/plugin-desktop-integration';
106
159
  ```
107
160
 
@@ -116,16 +169,34 @@ This plugin requires these permissions:
116
169
  - `allow-register-shortcut`: Grants access to `register_shortcut`
117
170
  - `allow-check-shortcut-binding-complete`: Grants access to `check_shortcut_binding_complete`
118
171
  - `allow-check-shortcut-binding-error`: Grants access to `check_shortcut_binding_error`
172
+ - `allow-check-shortcut-trigger-description`: Grants access to `check_shortcut_trigger_description`
173
+ - `allow-get-status`: Grants access to `get_status`
174
+ - `allow-notify`: Grants access to `notify`
175
+ - `allow-withdraw-notification`: Grants access to `withdraw_notification`
176
+ - `allow-set-app-user-model-id`: Grants access to `set_app_user_model_id`
177
+ - `allow-inhibit-sleep`: Grants access to `inhibit_sleep`
178
+ - `allow-release-sleep-inhibit`: Grants access to `release_sleep_inhibit`
179
+ - `allow-set-launcher-progress`: Grants access to `set_launcher_progress`
180
+ - `allow-own-file-manager`: Grants access to `own_file_manager`
181
+ - `allow-disown-file-manager`: Grants access to `disown_file_manager`
182
+ - `allow-register-global-shortcut`: Grants access to `register_global_shortcut`
183
+ - `allow-unregister-global-shortcut`: Grants access to `unregister_global_shortcut`
184
+
185
+ The `default` set grants the four shortcut commands and the read-only `get_status`; grant the rest explicitly.
119
186
 
120
187
  ## Platform Support
121
188
 
122
- | Platform | Support Level | Notes |
123
- | -------- | ------------- | ------------------------------------------------------------- |
124
- | Windows | None | X11/Wayland activation helpers only |
125
- | Linux | Full | X11 activation via `gdkx11`, Wayland shortcuts via the portal |
126
- | macOS | None | X11/Wayland activation helpers only |
127
- | Android | None | X11/Wayland activation helpers only |
128
- | iOS | None | X11/Wayland activation helpers only |
189
+ | Platform | Support Level | Notes |
190
+ | -------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
191
+ | Windows | Partial | Toasts (with an AppUserModelID), sleep inhibit, taskbar progress and `RegisterHotKey` shortcuts; type-checked for `x86_64-pc-windows-msvc`, not yet run on Windows |
192
+ | Linux | Full | X11 activation via `gdkx11`, Wayland shortcuts via the portal, notifications, logind sleep inhibit, launcher progress and `FileManager1` over zbus |
193
+ | macOS | None | Every service reports `platform-unsupported` |
194
+ | Android | None | Every service reports `platform-unsupported` |
195
+ | iOS | None | Every service reports `platform-unsupported` |
196
+
197
+ ## Testing
198
+
199
+ `cargo test -p tauri-plugin-desktop-integration` runs the headless tests (message and payload construction, id and handle bookkeeping, `FileManager1` URI parsing, accelerator parsing, status mapping). The `#[ignore]`d `live_*` tests touch the real session and are run by hand on a Linux desktop: `live_status` (read-only), `live_inhibit` (holds a logind inhibitor for 8 seconds; `systemd-inhibit --list` shows it), `live_launcher_entry` (emits three `Update` signals that `dbus-monitor "interface=com.canonical.Unity.LauncherEntry"` shows), `live_file_manager` and `live_file_manager_name_lost_and_taken` (briefly own `org.freedesktop.FileManager1`; run with `--test-threads=1`) and `live_notify` (shows one real notification).
129
200
 
130
201
  ## Licence
131
202
 
package/api-iife.js CHANGED
@@ -6,6 +6,32 @@ var __TAURI_PLUGIN_DESKTOP_INTEGRATION__ = (function (exports, core, event) {
6
6
  //
7
7
  // (c) Copyright 2026 Liminal HQ, Scott Morris
8
8
  // SPDX-License-Identifier: Apache-2.0 OR MIT
9
+ /**
10
+ * Event emitted when the user clicks a notification shown through `notify` or presses one of its
11
+ * action buttons; the payload is `{ id, action }`.
12
+ */
13
+ const NOTIFICATION_ACTION_EVENT = 'desktop-integration://notification-action';
14
+ /** Event emitted for each `org.freedesktop.FileManager1` call another application makes. */
15
+ const FILE_MANAGER_CALL_EVENT = 'desktop-integration://file-manager';
16
+ /** Event emitted when the app gains or loses the `org.freedesktop.FileManager1` name. */
17
+ const FILE_MANAGER_OWNERSHIP_EVENT = 'desktop-integration://file-manager-ownership';
18
+ /** Event emitted when a Windows global shortcut is pressed. */
19
+ const SHORTCUT_PRESSED_EVENT = 'desktop-integration://shortcut-pressed';
20
+ /** Whether a rejection from one of the service commands is a {@link ServiceError}. */
21
+ function isServiceError(error) {
22
+ return (typeof error === 'object' &&
23
+ error !== null &&
24
+ typeof error.kind === 'string' &&
25
+ typeof error.message === 'string');
26
+ }
27
+ /** The status of one feature, or `undefined` when the plugin did not report it. */
28
+ function featureStatus(status, feature) {
29
+ return status.features.find((entry) => entry.feature === feature);
30
+ }
31
+ /** Whether a feature is available; the way to decide whether to show the option that needs it. */
32
+ function isFeatureAvailable(status, feature) {
33
+ return featureStatus(status, feature)?.available === true;
34
+ }
9
35
  const PREFIX = 'plugin:desktop-integration|';
10
36
  function cmd(name, args) {
11
37
  return core.invoke(`${PREFIX}${name}`, args);
@@ -19,7 +45,60 @@ var __TAURI_PLUGIN_DESKTOP_INTEGRATION__ = (function (exports, core, event) {
19
45
  activationCallback?.();
20
46
  });
21
47
  }
48
+ function on(event$1, callback) {
49
+ return event.listen(event$1, (e) => callback(e.payload));
50
+ }
22
51
  const desktopIntegration = {
52
+ /** Which services work on this system, with a reason for each that does not. */
53
+ getStatus: () => cmd('get_status'),
54
+ /**
55
+ * Shows a desktop notification outside the portal, or replaces the one with the same `id`.
56
+ * Windows needs an AppUserModelID (see {@link desktopIntegration.setAppUserModelId}); without
57
+ * one this rejects with kind `needs-app-id`.
58
+ */
59
+ notify: (request) => cmd('notify', { request }),
60
+ /** Takes a notification shown through `notify` off screen. */
61
+ withdrawNotification: (id) => cmd('withdraw_notification', { id }),
62
+ /** Sets the AppUserModelID of the process, which Windows toasts need. Windows only. */
63
+ setAppUserModelId: (id) => cmd('set_app_user_model_id', { id }),
64
+ /**
65
+ * Keeps the machine from sleeping (or idling, on Linux) until
66
+ * {@link desktopIntegration.releaseSleepInhibit} is called with the returned handle or the app
67
+ * exits.
68
+ */
69
+ inhibitSleep: (request) => cmd('inhibit_sleep', { request }),
70
+ /** Ends an inhibitor taken with {@link desktopIntegration.inhibitSleep}. */
71
+ releaseSleepInhibit: (handle) => cmd('release_sleep_inhibit', { handle }),
72
+ /**
73
+ * Shows one combined progress value (0 to 1), an indeterminate state or nothing on the app's
74
+ * dock or taskbar entry, with an optional badge count (Linux).
75
+ */
76
+ setLauncherProgress: (request) => cmd('set_launcher_progress', { request }),
77
+ /**
78
+ * Takes the `org.freedesktop.FileManager1` name so other applications' "Show in folder" reaches
79
+ * this app as {@link FILE_MANAGER_CALL_EVENT} events. Linux only.
80
+ */
81
+ ownFileManager: () => cmd('own_file_manager'),
82
+ /** Gives the `org.freedesktop.FileManager1` name back. */
83
+ disownFileManager: () => cmd('disown_file_manager'),
84
+ /**
85
+ * Registers a global shortcut with `RegisterHotKey`; {@link desktopIntegration.onShortcutPressed}
86
+ * reports presses. Registering an id again replaces its accelerator, the same one included; if
87
+ * the new accelerator is refused, the earlier binding stays. A call that rejects with
88
+ * `timeout` did not take effect. Windows only; Linux uses
89
+ * {@link desktopIntegration.registerShortcut}.
90
+ */
91
+ registerGlobalShortcut: (request) => cmd('register_global_shortcut', { request }),
92
+ /** Removes a shortcut registered with {@link desktopIntegration.registerGlobalShortcut}. */
93
+ unregisterGlobalShortcut: (id) => cmd('unregister_global_shortcut', { id }),
94
+ /** Subscribes to notification clicks and button presses; resolves to a function that unsubscribes. */
95
+ onNotificationAction: (callback) => on(NOTIFICATION_ACTION_EVENT, callback),
96
+ /** Subscribes to `FileManager1` calls from other applications. */
97
+ onFileManagerCall: (callback) => on(FILE_MANAGER_CALL_EVENT, callback),
98
+ /** Subscribes to the app losing the `FileManager1` name to another file manager. */
99
+ onFileManagerOwnership: (callback) => on(FILE_MANAGER_OWNERSHIP_EVENT, callback),
100
+ /** Subscribes to presses of Windows global shortcuts. */
101
+ onShortcutPressed: (callback) => on(SHORTCUT_PRESSED_EVENT, callback),
23
102
  /**
24
103
  * Registers a global shortcut. On X11 it's bound immediately; on Wayland,
25
104
  * binding is deferred until the compositor confirms it — see
@@ -49,9 +128,24 @@ var __TAURI_PLUGIN_DESKTOP_INTEGRATION__ = (function (exports, core, event) {
49
128
  * shortcut-binding-result listener — complements checkShortcutBindingComplete.
50
129
  */
51
130
  checkShortcutBindingError: () => cmd('check_shortcut_binding_error'),
131
+ /**
132
+ * Returns the trigger description (e.g. "Super+E") from the most recent
133
+ * shortcut-changed event, or null if the shortcut hasn't been externally
134
+ * rebound yet this session. Use this to hydrate UI that mounts after a missed
135
+ * event — listen for the `shortcut-changed` event directly via
136
+ * `@tauri-apps/api/event`'s `listen()` for live updates.
137
+ */
138
+ checkShortcutTriggerDescription: () => cmd('check_shortcut_trigger_description'),
52
139
  };
53
140
 
141
+ exports.FILE_MANAGER_CALL_EVENT = FILE_MANAGER_CALL_EVENT;
142
+ exports.FILE_MANAGER_OWNERSHIP_EVENT = FILE_MANAGER_OWNERSHIP_EVENT;
143
+ exports.NOTIFICATION_ACTION_EVENT = NOTIFICATION_ACTION_EVENT;
144
+ exports.SHORTCUT_PRESSED_EVENT = SHORTCUT_PRESSED_EVENT;
54
145
  exports.desktopIntegration = desktopIntegration;
146
+ exports.featureStatus = featureStatus;
147
+ exports.isFeatureAvailable = isFeatureAvailable;
148
+ exports.isServiceError = isServiceError;
55
149
 
56
150
  return exports;
57
151
 
@@ -0,0 +1,14 @@
1
+ /**
2
+ * One action button on a notification.
3
+ */
4
+ export type ActionButton = {
5
+ /**
6
+ * Reported as the event's `action` when the button is pressed.
7
+ */
8
+ id: string;
9
+ /**
10
+ * The text on the button.
11
+ */
12
+ label: string;
13
+ };
14
+ //# sourceMappingURL=ActionButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionButton.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/ActionButton.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IAC3B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * A feature the plugin can offer, as reported by `get_status`.
3
+ */
4
+ export type Feature = "notify" | "notificationActions" | "inhibitSleep" | "launcherProgress" | "fileManager" | "globalShortcuts";
5
+ //# sourceMappingURL=Feature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Feature.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/Feature.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,qBAAqB,GAAG,cAAc,GAAG,kBAAkB,GAAG,aAAa,GAAG,iBAAiB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Feature } from "./Feature";
2
+ import type { UnavailableReason } from "./UnavailableReason";
3
+ /**
4
+ * Whether one feature works on this system.
5
+ */
6
+ export type FeatureStatus = {
7
+ feature: Feature;
8
+ available: boolean;
9
+ /**
10
+ * Why the feature is unavailable; absent when it works.
11
+ */
12
+ reason: UnavailableReason | null;
13
+ /**
14
+ * The error text behind the reason, for logs and the Services panel.
15
+ */
16
+ detail: string | null;
17
+ };
18
+ //# sourceMappingURL=FeatureStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureStatus.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/FeatureStatus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IACnE;;OAEG;IACH,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { FileManagerMethod } from "./FileManagerMethod";
2
+ import type { FileManagerTarget } from "./FileManagerTarget";
3
+ /**
4
+ * Payload of the `desktop-integration://file-manager` event.
5
+ */
6
+ export type FileManagerCall = {
7
+ method: FileManagerMethod;
8
+ targets: Array<FileManagerTarget>;
9
+ /**
10
+ * The caller's startup id, for focus-stealing prevention; often empty.
11
+ */
12
+ startupId: string;
13
+ };
14
+ //# sourceMappingURL=FileManagerCall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileManagerCall.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/FileManagerCall.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC7F;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * The `org.freedesktop.FileManager1` method another application called.
3
+ */
4
+ export type FileManagerMethod = "show-folders" | "show-items" | "show-item-properties";
5
+ //# sourceMappingURL=FileManagerMethod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileManagerMethod.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/FileManagerMethod.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,YAAY,GAAG,sBAAsB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Whether this process owns `org.freedesktop.FileManager1`.
3
+ *
4
+ * This is the return value of `own_file_manager` and `disown_file_manager` and the payload of the
5
+ * `desktop-integration://file-manager-ownership` event, which also reports a name taken away.
6
+ */
7
+ export type FileManagerOwnership = {
8
+ owned: boolean;
9
+ /**
10
+ * Why the name is not owned, when it was lost or could not be taken.
11
+ */
12
+ reason: string | null;
13
+ };
14
+ //# sourceMappingURL=FileManagerOwnership.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileManagerOwnership.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/FileManagerOwnership.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IACpD;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * One URI from a `FileManager1` call.
3
+ */
4
+ export type FileManagerTarget = {
5
+ /**
6
+ * The URI as the caller sent it.
7
+ */
8
+ uri: string;
9
+ /**
10
+ * The local path, percent-decoded, when the URI is a `file:` URI for this machine.
11
+ */
12
+ path: string | null;
13
+ };
14
+ //# sourceMappingURL=FileManagerTarget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileManagerTarget.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/FileManagerTarget.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAChC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAAE,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Payload of the `desktop-integration://shortcut-pressed` event.
3
+ */
4
+ export type GlobalShortcutPressed = {
5
+ id: string;
6
+ };
7
+ //# sourceMappingURL=GlobalShortcutPressed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlobalShortcutPressed.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/GlobalShortcutPressed.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;CAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * A global shortcut to register on Windows.
3
+ */
4
+ export type GlobalShortcutRequest = {
5
+ /**
6
+ * The caller's id for the shortcut, reported by the `pressed` event.
7
+ */
8
+ id: string;
9
+ /**
10
+ * A Tauri-style accelerator such as `Ctrl+Alt+K`.
11
+ */
12
+ accelerator: string;
13
+ };
14
+ //# sourceMappingURL=GlobalShortcutRequest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlobalShortcutRequest.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/GlobalShortcutRequest.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IACpC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CAAE,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * What the launcher or taskbar icon shows.
3
+ */
4
+ export type LauncherProgress = {
5
+ "state": "value";
6
+ value: number;
7
+ } | {
8
+ "state": "indeterminate";
9
+ } | {
10
+ "state": "cleared";
11
+ };
12
+ //# sourceMappingURL=LauncherProgress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LauncherProgress.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/LauncherProgress.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;CAAE,GAAG;IAAE,OAAO,EAAE,eAAe,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,SAAS,CAAA;CAAE,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { LauncherProgress } from "./LauncherProgress";
2
+ /**
3
+ * Progress and count for the app's dock or taskbar entry.
4
+ */
5
+ export type LauncherRequest = {
6
+ progress: LauncherProgress;
7
+ /**
8
+ * A badge count, such as the number of running jobs; zero hides it. Absent leaves it alone.
9
+ * Linux only.
10
+ */
11
+ count: number | null;
12
+ /**
13
+ * The `.desktop` file id the dock matches the signal to; defaults to the bundle identifier.
14
+ * Linux only.
15
+ */
16
+ desktopId: string | null;
17
+ /**
18
+ * The window whose taskbar button shows the progress. Windows only; defaults to the focused
19
+ * window, else the first window whose label starts with `main`, else the first label in alphabetical order.
20
+ */
21
+ windowLabel: string | null;
22
+ };
23
+ //# sourceMappingURL=LauncherRequest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LauncherRequest.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/LauncherRequest.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,QAAQ,EAAE,gBAAgB,CAAC;IAC3D;;;OAGG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;OAGG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;OAGG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAAE,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Payload of the `desktop-integration://notification-action` event.
3
+ */
4
+ export type NotificationAction = {
5
+ /**
6
+ * The id of the notification the user acted on.
7
+ */
8
+ id: string;
9
+ /**
10
+ * The request's `defaultAction` for a click on the notification, or the `id` of the button
11
+ * that was pressed.
12
+ */
13
+ action: string;
14
+ };
15
+ //# sourceMappingURL=NotificationAction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationAction.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/NotificationAction.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IACjC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAAE,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { ActionButton } from "./ActionButton";
2
+ import type { Urgency } from "./Urgency";
3
+ /**
4
+ * A desktop notification to show or replace.
5
+ */
6
+ export type NotifyRequest = {
7
+ /**
8
+ * The caller's id. Sending the same id again replaces the shown notification.
9
+ */
10
+ id: string;
11
+ title: string;
12
+ body: string | null;
13
+ /**
14
+ * The action id reported through the `notification-action` event when the user clicks the
15
+ * notification itself.
16
+ */
17
+ defaultAction: string | null;
18
+ urgency: Urgency | null;
19
+ /**
20
+ * The application name the shell shows; defaults to the package name.
21
+ */
22
+ appName: string | null;
23
+ /**
24
+ * The `.desktop` file id of the app, so the shell can group and style the notification;
25
+ * defaults to the bundle identifier.
26
+ */
27
+ desktopId: string | null;
28
+ /**
29
+ * Buttons to show on the notification, in order. At most 3 are shown; extras are dropped.
30
+ * A press is reported through the `notification-action` event with the button's `id`
31
+ * (`default` is reserved for the click on the notification, and an id must differ from
32
+ * `defaultAction` so the two can be told apart). Servers that do not draw
33
+ * buttons (see the `notificationActions` feature) show only the default click.
34
+ */
35
+ actions?: Array<ActionButton>;
36
+ };
37
+ //# sourceMappingURL=NotifyRequest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotifyRequest.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/NotifyRequest.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC5B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C;;;OAGG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACtD;;OAEG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;OAGG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;CAAE,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { FeatureStatus } from "./FeatureStatus";
2
+ import type { UnavailableReason } from "./UnavailableReason";
3
+ /**
4
+ * What the plugin can do on the running system.
5
+ */
6
+ export type PluginStatus = {
7
+ /**
8
+ * True when at least one feature is available.
9
+ */
10
+ available: boolean;
11
+ /**
12
+ * Why nothing is available; absent otherwise.
13
+ */
14
+ reason: UnavailableReason | null;
15
+ features: Array<FeatureStatus>;
16
+ /**
17
+ * Whether this process currently owns `org.freedesktop.FileManager1`.
18
+ */
19
+ fileManagerOwned: boolean;
20
+ };
21
+ //# sourceMappingURL=PluginStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginStatus.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/PluginStatus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IAC3B;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IACjE;;OAEG;IACH,gBAAgB,EAAE,OAAO,CAAC;CAAE,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ServiceErrorKind } from "./ServiceErrorKind";
2
+ /**
3
+ * The error of every service command: a `kind` to branch on and a `message` for logs.
4
+ */
5
+ export type ServiceError = {
6
+ kind: ServiceErrorKind;
7
+ message: string;
8
+ };
9
+ //# sourceMappingURL=ServiceError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServiceError.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/ServiceError.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;CAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Why a service command failed, as a value a caller can branch on.
3
+ */
4
+ export type ServiceErrorKind = "unsupported-platform" | "unavailable" | "needs-app-id" | "invalid-argument" | "not-found" | "conflict" | "timeout" | "failed";
5
+ //# sourceMappingURL=ServiceErrorKind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServiceErrorKind.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/ServiceErrorKind.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,sBAAsB,GAAG,aAAa,GAAG,cAAc,GAAG,kBAAkB,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Payload emitted on the `shortcut-changed` event, fired when the user rebinds the
3
+ * shortcut through the compositor's own settings UI (e.g. GNOME Settings → Apps →
4
+ * <App> → Global Shortcuts) rather than through this app. Wayland-only — X11 direct
5
+ * grabs have no equivalent out-of-band rebind path, so this never fires there.
6
+ */
7
+ export type ShortcutChangedPayload = {
8
+ sessionId: string;
9
+ triggerDescription: string;
10
+ };
11
+ //# sourceMappingURL=ShortcutChangedPayload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShortcutChangedPayload.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/ShortcutChangedPayload.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAC;CAAE,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The handle of a live sleep inhibitor, to give back to `release_sleep_inhibit`.
3
+ */
4
+ export type SleepInhibitHandle = {
5
+ handle: number;
6
+ };
7
+ //# sourceMappingURL=SleepInhibitHandle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SleepInhibitHandle.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/SleepInhibitHandle.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;CAAE,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { SleepKind } from "./SleepKind";
2
+ /**
3
+ * A request to keep the machine awake.
4
+ */
5
+ export type SleepInhibitRequest = {
6
+ /**
7
+ * What the user is told the app is doing, such as "Copying 3 files".
8
+ */
9
+ reason: string;
10
+ /**
11
+ * What to inhibit; empty means sleep only.
12
+ */
13
+ kinds: Array<SleepKind>;
14
+ };
15
+ //# sourceMappingURL=SleepInhibitRequest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SleepInhibitRequest.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/SleepInhibitRequest.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAClC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * What to keep the machine from doing.
3
+ */
4
+ export type SleepKind = "sleep" | "idle";
5
+ //# sourceMappingURL=SleepKind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SleepKind.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/SleepKind.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Why a feature is not available.
3
+ */
4
+ export type UnavailableReason = "platform-unsupported" | "no-session-bus" | "no-notification-server" | "no-logind" | "needs-app-id" | "no-display-server" | "actions-unsupported";
5
+ //# sourceMappingURL=UnavailableReason.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UnavailableReason.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/UnavailableReason.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,GAAG,gBAAgB,GAAG,wBAAwB,GAAG,WAAW,GAAG,cAAc,GAAG,mBAAmB,GAAG,qBAAqB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * How urgent a notification is.
3
+ */
4
+ export type Urgency = "low" | "normal" | "critical";
5
+ //# sourceMappingURL=Urgency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Urgency.d.ts","sourceRoot":"","sources":["../../guest-js/bindings/Urgency.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,UAAU,CAAC"}
package/dist-js/index.cjs CHANGED
@@ -7,6 +7,32 @@ var event = require('@tauri-apps/api/event');
7
7
  //
8
8
  // (c) Copyright 2026 Liminal HQ, Scott Morris
9
9
  // SPDX-License-Identifier: Apache-2.0 OR MIT
10
+ /**
11
+ * Event emitted when the user clicks a notification shown through `notify` or presses one of its
12
+ * action buttons; the payload is `{ id, action }`.
13
+ */
14
+ const NOTIFICATION_ACTION_EVENT = 'desktop-integration://notification-action';
15
+ /** Event emitted for each `org.freedesktop.FileManager1` call another application makes. */
16
+ const FILE_MANAGER_CALL_EVENT = 'desktop-integration://file-manager';
17
+ /** Event emitted when the app gains or loses the `org.freedesktop.FileManager1` name. */
18
+ const FILE_MANAGER_OWNERSHIP_EVENT = 'desktop-integration://file-manager-ownership';
19
+ /** Event emitted when a Windows global shortcut is pressed. */
20
+ const SHORTCUT_PRESSED_EVENT = 'desktop-integration://shortcut-pressed';
21
+ /** Whether a rejection from one of the service commands is a {@link ServiceError}. */
22
+ function isServiceError(error) {
23
+ return (typeof error === 'object' &&
24
+ error !== null &&
25
+ typeof error.kind === 'string' &&
26
+ typeof error.message === 'string');
27
+ }
28
+ /** The status of one feature, or `undefined` when the plugin did not report it. */
29
+ function featureStatus(status, feature) {
30
+ return status.features.find((entry) => entry.feature === feature);
31
+ }
32
+ /** Whether a feature is available; the way to decide whether to show the option that needs it. */
33
+ function isFeatureAvailable(status, feature) {
34
+ return featureStatus(status, feature)?.available === true;
35
+ }
10
36
  const PREFIX = 'plugin:desktop-integration|';
11
37
  function cmd(name, args) {
12
38
  return core.invoke(`${PREFIX}${name}`, args);
@@ -20,7 +46,60 @@ function ensureActivationListener() {
20
46
  activationCallback?.();
21
47
  });
22
48
  }
49
+ function on(event$1, callback) {
50
+ return event.listen(event$1, (e) => callback(e.payload));
51
+ }
23
52
  const desktopIntegration = {
53
+ /** Which services work on this system, with a reason for each that does not. */
54
+ getStatus: () => cmd('get_status'),
55
+ /**
56
+ * Shows a desktop notification outside the portal, or replaces the one with the same `id`.
57
+ * Windows needs an AppUserModelID (see {@link desktopIntegration.setAppUserModelId}); without
58
+ * one this rejects with kind `needs-app-id`.
59
+ */
60
+ notify: (request) => cmd('notify', { request }),
61
+ /** Takes a notification shown through `notify` off screen. */
62
+ withdrawNotification: (id) => cmd('withdraw_notification', { id }),
63
+ /** Sets the AppUserModelID of the process, which Windows toasts need. Windows only. */
64
+ setAppUserModelId: (id) => cmd('set_app_user_model_id', { id }),
65
+ /**
66
+ * Keeps the machine from sleeping (or idling, on Linux) until
67
+ * {@link desktopIntegration.releaseSleepInhibit} is called with the returned handle or the app
68
+ * exits.
69
+ */
70
+ inhibitSleep: (request) => cmd('inhibit_sleep', { request }),
71
+ /** Ends an inhibitor taken with {@link desktopIntegration.inhibitSleep}. */
72
+ releaseSleepInhibit: (handle) => cmd('release_sleep_inhibit', { handle }),
73
+ /**
74
+ * Shows one combined progress value (0 to 1), an indeterminate state or nothing on the app's
75
+ * dock or taskbar entry, with an optional badge count (Linux).
76
+ */
77
+ setLauncherProgress: (request) => cmd('set_launcher_progress', { request }),
78
+ /**
79
+ * Takes the `org.freedesktop.FileManager1` name so other applications' "Show in folder" reaches
80
+ * this app as {@link FILE_MANAGER_CALL_EVENT} events. Linux only.
81
+ */
82
+ ownFileManager: () => cmd('own_file_manager'),
83
+ /** Gives the `org.freedesktop.FileManager1` name back. */
84
+ disownFileManager: () => cmd('disown_file_manager'),
85
+ /**
86
+ * Registers a global shortcut with `RegisterHotKey`; {@link desktopIntegration.onShortcutPressed}
87
+ * reports presses. Registering an id again replaces its accelerator, the same one included; if
88
+ * the new accelerator is refused, the earlier binding stays. A call that rejects with
89
+ * `timeout` did not take effect. Windows only; Linux uses
90
+ * {@link desktopIntegration.registerShortcut}.
91
+ */
92
+ registerGlobalShortcut: (request) => cmd('register_global_shortcut', { request }),
93
+ /** Removes a shortcut registered with {@link desktopIntegration.registerGlobalShortcut}. */
94
+ unregisterGlobalShortcut: (id) => cmd('unregister_global_shortcut', { id }),
95
+ /** Subscribes to notification clicks and button presses; resolves to a function that unsubscribes. */
96
+ onNotificationAction: (callback) => on(NOTIFICATION_ACTION_EVENT, callback),
97
+ /** Subscribes to `FileManager1` calls from other applications. */
98
+ onFileManagerCall: (callback) => on(FILE_MANAGER_CALL_EVENT, callback),
99
+ /** Subscribes to the app losing the `FileManager1` name to another file manager. */
100
+ onFileManagerOwnership: (callback) => on(FILE_MANAGER_OWNERSHIP_EVENT, callback),
101
+ /** Subscribes to presses of Windows global shortcuts. */
102
+ onShortcutPressed: (callback) => on(SHORTCUT_PRESSED_EVENT, callback),
24
103
  /**
25
104
  * Registers a global shortcut. On X11 it's bound immediately; on Wayland,
26
105
  * binding is deferred until the compositor confirms it — see
@@ -50,7 +129,22 @@ const desktopIntegration = {
50
129
  * shortcut-binding-result listener — complements checkShortcutBindingComplete.
51
130
  */
52
131
  checkShortcutBindingError: () => cmd('check_shortcut_binding_error'),
132
+ /**
133
+ * Returns the trigger description (e.g. "Super+E") from the most recent
134
+ * shortcut-changed event, or null if the shortcut hasn't been externally
135
+ * rebound yet this session. Use this to hydrate UI that mounts after a missed
136
+ * event — listen for the `shortcut-changed` event directly via
137
+ * `@tauri-apps/api/event`'s `listen()` for live updates.
138
+ */
139
+ checkShortcutTriggerDescription: () => cmd('check_shortcut_trigger_description'),
53
140
  };
54
141
 
142
+ exports.FILE_MANAGER_CALL_EVENT = FILE_MANAGER_CALL_EVENT;
143
+ exports.FILE_MANAGER_OWNERSHIP_EVENT = FILE_MANAGER_OWNERSHIP_EVENT;
144
+ exports.NOTIFICATION_ACTION_EVENT = NOTIFICATION_ACTION_EVENT;
145
+ exports.SHORTCUT_PRESSED_EVENT = SHORTCUT_PRESSED_EVENT;
55
146
  exports.desktopIntegration = desktopIntegration;
147
+ exports.featureStatus = featureStatus;
148
+ exports.isFeatureAvailable = isFeatureAvailable;
149
+ exports.isServiceError = isServiceError;
56
150
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../guest-js/index.ts"],"sourcesContent":[null],"names":["invoke","listen"],"mappings":";;;;;AAAA;AACA;AACA;AACA;AASA,MAAM,MAAM,GAAG,6BAA6B;AAE5C,SAAS,GAAG,CAAI,IAAY,EAAE,IAA8B,EAAA;IAC3D,OAAOA,WAAM,CAAI,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAE,EAAE,IAAI,CAAC;AAC3C;AAEA,IAAI,kBAAkB,GAAwB,IAAI;AAClD,IAAI,mBAAmB,GAA4B,IAAI;AAEvD,SAAS,wBAAwB,GAAA;AAChC,IAAA,IAAI,mBAAmB;QAAE;AACzB,IAAA,mBAAmB,GAAGC,YAAM,CAA2B,oBAAoB,EAAE,MAAK;QACjF,kBAAkB,IAAI;AACvB,IAAA,CAAC,CAAC;AACH;AAEO,MAAM,kBAAkB,GAAG;AACjC;;;;;;;;;;;AAWG;IACH,gBAAgB,EAAE,CACjB,SAAiB,EACjB,kBAA0B,EAC1B,QAAgB,EAChB,WAAuB,KACL;QAClB,kBAAkB,GAAG,WAAW;AAChC,QAAA,wBAAwB,EAAE;AAC1B,QAAA,OAAO,GAAG,CAAC,mBAAmB,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,QAAQ,EAAE,CAAC;IAC7E,CAAC;AAED;;;;AAIG;AACH,IAAA,4BAA4B,EAAE,MAAM,GAAG,CAAU,iCAAiC,CAAC;AAEnF;;;;AAIG;AACH,IAAA,yBAAyB,EAAE,MAAM,GAAG,CAAgB,8BAA8B,CAAC;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../guest-js/index.ts"],"sourcesContent":[null],"names":["invoke","listen","event"],"mappings":"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"}
@@ -1,7 +1,96 @@
1
+ import type { ActionButton } from './bindings/ActionButton';
2
+ import type { Feature } from './bindings/Feature';
3
+ import type { FeatureStatus } from './bindings/FeatureStatus';
4
+ import type { FileManagerCall } from './bindings/FileManagerCall';
5
+ import type { FileManagerMethod } from './bindings/FileManagerMethod';
6
+ import type { FileManagerOwnership } from './bindings/FileManagerOwnership';
7
+ import type { FileManagerTarget } from './bindings/FileManagerTarget';
8
+ import type { GlobalShortcutPressed } from './bindings/GlobalShortcutPressed';
9
+ import type { GlobalShortcutRequest } from './bindings/GlobalShortcutRequest';
10
+ import type { LauncherProgress } from './bindings/LauncherProgress';
11
+ import type { LauncherRequest } from './bindings/LauncherRequest';
12
+ import type { NotificationAction } from './bindings/NotificationAction';
13
+ import type { NotifyRequest } from './bindings/NotifyRequest';
14
+ import type { PluginStatus } from './bindings/PluginStatus';
15
+ import type { ServiceError } from './bindings/ServiceError';
16
+ import type { ServiceErrorKind } from './bindings/ServiceErrorKind';
1
17
  import type { ShortcutActivatedPayload } from './bindings/ShortcutActivatedPayload';
2
18
  import type { ShortcutBindingResult } from './bindings/ShortcutBindingResult';
3
- export type { ShortcutActivatedPayload, ShortcutBindingResult };
19
+ import type { ShortcutChangedPayload } from './bindings/ShortcutChangedPayload';
20
+ import type { SleepInhibitHandle } from './bindings/SleepInhibitHandle';
21
+ import type { SleepInhibitRequest } from './bindings/SleepInhibitRequest';
22
+ import type { SleepKind } from './bindings/SleepKind';
23
+ import type { UnavailableReason } from './bindings/UnavailableReason';
24
+ import type { Urgency } from './bindings/Urgency';
25
+ export type { ActionButton, Feature, FeatureStatus, FileManagerCall, FileManagerMethod, FileManagerOwnership, FileManagerTarget, GlobalShortcutPressed, GlobalShortcutRequest, LauncherProgress, LauncherRequest, NotificationAction, NotifyRequest, PluginStatus, ServiceError, ServiceErrorKind, ShortcutActivatedPayload, ShortcutBindingResult, ShortcutChangedPayload, SleepInhibitHandle, SleepInhibitRequest, SleepKind, UnavailableReason, Urgency, };
26
+ /**
27
+ * Event emitted when the user clicks a notification shown through `notify` or presses one of its
28
+ * action buttons; the payload is `{ id, action }`.
29
+ */
30
+ export declare const NOTIFICATION_ACTION_EVENT = "desktop-integration://notification-action";
31
+ /** Event emitted for each `org.freedesktop.FileManager1` call another application makes. */
32
+ export declare const FILE_MANAGER_CALL_EVENT = "desktop-integration://file-manager";
33
+ /** Event emitted when the app gains or loses the `org.freedesktop.FileManager1` name. */
34
+ export declare const FILE_MANAGER_OWNERSHIP_EVENT = "desktop-integration://file-manager-ownership";
35
+ /** Event emitted when a Windows global shortcut is pressed. */
36
+ export declare const SHORTCUT_PRESSED_EVENT = "desktop-integration://shortcut-pressed";
37
+ /** Whether a rejection from one of the service commands is a {@link ServiceError}. */
38
+ export declare function isServiceError(error: unknown): error is ServiceError;
39
+ /** The status of one feature, or `undefined` when the plugin did not report it. */
40
+ export declare function featureStatus(status: PluginStatus, feature: Feature): FeatureStatus | undefined;
41
+ /** Whether a feature is available; the way to decide whether to show the option that needs it. */
42
+ export declare function isFeatureAvailable(status: PluginStatus, feature: Feature): boolean;
4
43
  export declare const desktopIntegration: {
44
+ /** Which services work on this system, with a reason for each that does not. */
45
+ getStatus: () => Promise<PluginStatus>;
46
+ /**
47
+ * Shows a desktop notification outside the portal, or replaces the one with the same `id`.
48
+ * Windows needs an AppUserModelID (see {@link desktopIntegration.setAppUserModelId}); without
49
+ * one this rejects with kind `needs-app-id`.
50
+ */
51
+ notify: (request: NotifyRequest) => Promise<void>;
52
+ /** Takes a notification shown through `notify` off screen. */
53
+ withdrawNotification: (id: string) => Promise<void>;
54
+ /** Sets the AppUserModelID of the process, which Windows toasts need. Windows only. */
55
+ setAppUserModelId: (id: string) => Promise<void>;
56
+ /**
57
+ * Keeps the machine from sleeping (or idling, on Linux) until
58
+ * {@link desktopIntegration.releaseSleepInhibit} is called with the returned handle or the app
59
+ * exits.
60
+ */
61
+ inhibitSleep: (request: SleepInhibitRequest) => Promise<SleepInhibitHandle>;
62
+ /** Ends an inhibitor taken with {@link desktopIntegration.inhibitSleep}. */
63
+ releaseSleepInhibit: (handle: number) => Promise<void>;
64
+ /**
65
+ * Shows one combined progress value (0 to 1), an indeterminate state or nothing on the app's
66
+ * dock or taskbar entry, with an optional badge count (Linux).
67
+ */
68
+ setLauncherProgress: (request: LauncherRequest) => Promise<void>;
69
+ /**
70
+ * Takes the `org.freedesktop.FileManager1` name so other applications' "Show in folder" reaches
71
+ * this app as {@link FILE_MANAGER_CALL_EVENT} events. Linux only.
72
+ */
73
+ ownFileManager: () => Promise<FileManagerOwnership>;
74
+ /** Gives the `org.freedesktop.FileManager1` name back. */
75
+ disownFileManager: () => Promise<FileManagerOwnership>;
76
+ /**
77
+ * Registers a global shortcut with `RegisterHotKey`; {@link desktopIntegration.onShortcutPressed}
78
+ * reports presses. Registering an id again replaces its accelerator, the same one included; if
79
+ * the new accelerator is refused, the earlier binding stays. A call that rejects with
80
+ * `timeout` did not take effect. Windows only; Linux uses
81
+ * {@link desktopIntegration.registerShortcut}.
82
+ */
83
+ registerGlobalShortcut: (request: GlobalShortcutRequest) => Promise<void>;
84
+ /** Removes a shortcut registered with {@link desktopIntegration.registerGlobalShortcut}. */
85
+ unregisterGlobalShortcut: (id: string) => Promise<void>;
86
+ /** Subscribes to notification clicks and button presses; resolves to a function that unsubscribes. */
87
+ onNotificationAction: (callback: (_action: NotificationAction) => void) => Promise<() => void>;
88
+ /** Subscribes to `FileManager1` calls from other applications. */
89
+ onFileManagerCall: (callback: (_call: FileManagerCall) => void) => Promise<() => void>;
90
+ /** Subscribes to the app losing the `FileManager1` name to another file manager. */
91
+ onFileManagerOwnership: (callback: (_ownership: FileManagerOwnership) => void) => Promise<() => void>;
92
+ /** Subscribes to presses of Windows global shortcuts. */
93
+ onShortcutPressed: (callback: (_pressed: GlobalShortcutPressed) => void) => Promise<() => void>;
5
94
  /**
6
95
  * Registers a global shortcut. On X11 it's bound immediately; on Wayland,
7
96
  * binding is deferred until the compositor confirms it — see
@@ -27,5 +116,13 @@ export declare const desktopIntegration: {
27
116
  * shortcut-binding-result listener — complements checkShortcutBindingComplete.
28
117
  */
29
118
  checkShortcutBindingError: () => Promise<string | null>;
119
+ /**
120
+ * Returns the trigger description (e.g. "Super+E") from the most recent
121
+ * shortcut-changed event, or null if the shortcut hasn't been externally
122
+ * rebound yet this session. Use this to hydrate UI that mounts after a missed
123
+ * event — listen for the `shortcut-changed` event directly via
124
+ * `@tauri-apps/api/event`'s `listen()` for live updates.
125
+ */
126
+ checkShortcutTriggerDescription: () => Promise<string | null>;
30
127
  };
31
128
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../guest-js/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AACpF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAE9E,YAAY,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,CAAC;AAkBhE,eAAO,MAAM,kBAAkB;IAC9B;;;;;;;;;;;OAWG;kCAES,MAAM,sBACG,MAAM,YAChB,MAAM,eACH,MAAM,IAAI,KACrB,OAAO,CAAC,IAAI,CAAC;IAMhB;;;;OAIG;;IAGH;;;;OAIG;;CAEH,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../guest-js/index.ts"],"names":[],"mappings":"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"}
package/dist-js/index.js CHANGED
@@ -5,6 +5,32 @@ import { listen } from '@tauri-apps/api/event';
5
5
  //
6
6
  // (c) Copyright 2026 Liminal HQ, Scott Morris
7
7
  // SPDX-License-Identifier: Apache-2.0 OR MIT
8
+ /**
9
+ * Event emitted when the user clicks a notification shown through `notify` or presses one of its
10
+ * action buttons; the payload is `{ id, action }`.
11
+ */
12
+ const NOTIFICATION_ACTION_EVENT = 'desktop-integration://notification-action';
13
+ /** Event emitted for each `org.freedesktop.FileManager1` call another application makes. */
14
+ const FILE_MANAGER_CALL_EVENT = 'desktop-integration://file-manager';
15
+ /** Event emitted when the app gains or loses the `org.freedesktop.FileManager1` name. */
16
+ const FILE_MANAGER_OWNERSHIP_EVENT = 'desktop-integration://file-manager-ownership';
17
+ /** Event emitted when a Windows global shortcut is pressed. */
18
+ const SHORTCUT_PRESSED_EVENT = 'desktop-integration://shortcut-pressed';
19
+ /** Whether a rejection from one of the service commands is a {@link ServiceError}. */
20
+ function isServiceError(error) {
21
+ return (typeof error === 'object' &&
22
+ error !== null &&
23
+ typeof error.kind === 'string' &&
24
+ typeof error.message === 'string');
25
+ }
26
+ /** The status of one feature, or `undefined` when the plugin did not report it. */
27
+ function featureStatus(status, feature) {
28
+ return status.features.find((entry) => entry.feature === feature);
29
+ }
30
+ /** Whether a feature is available; the way to decide whether to show the option that needs it. */
31
+ function isFeatureAvailable(status, feature) {
32
+ return featureStatus(status, feature)?.available === true;
33
+ }
8
34
  const PREFIX = 'plugin:desktop-integration|';
9
35
  function cmd(name, args) {
10
36
  return invoke(`${PREFIX}${name}`, args);
@@ -18,7 +44,60 @@ function ensureActivationListener() {
18
44
  activationCallback?.();
19
45
  });
20
46
  }
47
+ function on(event, callback) {
48
+ return listen(event, (e) => callback(e.payload));
49
+ }
21
50
  const desktopIntegration = {
51
+ /** Which services work on this system, with a reason for each that does not. */
52
+ getStatus: () => cmd('get_status'),
53
+ /**
54
+ * Shows a desktop notification outside the portal, or replaces the one with the same `id`.
55
+ * Windows needs an AppUserModelID (see {@link desktopIntegration.setAppUserModelId}); without
56
+ * one this rejects with kind `needs-app-id`.
57
+ */
58
+ notify: (request) => cmd('notify', { request }),
59
+ /** Takes a notification shown through `notify` off screen. */
60
+ withdrawNotification: (id) => cmd('withdraw_notification', { id }),
61
+ /** Sets the AppUserModelID of the process, which Windows toasts need. Windows only. */
62
+ setAppUserModelId: (id) => cmd('set_app_user_model_id', { id }),
63
+ /**
64
+ * Keeps the machine from sleeping (or idling, on Linux) until
65
+ * {@link desktopIntegration.releaseSleepInhibit} is called with the returned handle or the app
66
+ * exits.
67
+ */
68
+ inhibitSleep: (request) => cmd('inhibit_sleep', { request }),
69
+ /** Ends an inhibitor taken with {@link desktopIntegration.inhibitSleep}. */
70
+ releaseSleepInhibit: (handle) => cmd('release_sleep_inhibit', { handle }),
71
+ /**
72
+ * Shows one combined progress value (0 to 1), an indeterminate state or nothing on the app's
73
+ * dock or taskbar entry, with an optional badge count (Linux).
74
+ */
75
+ setLauncherProgress: (request) => cmd('set_launcher_progress', { request }),
76
+ /**
77
+ * Takes the `org.freedesktop.FileManager1` name so other applications' "Show in folder" reaches
78
+ * this app as {@link FILE_MANAGER_CALL_EVENT} events. Linux only.
79
+ */
80
+ ownFileManager: () => cmd('own_file_manager'),
81
+ /** Gives the `org.freedesktop.FileManager1` name back. */
82
+ disownFileManager: () => cmd('disown_file_manager'),
83
+ /**
84
+ * Registers a global shortcut with `RegisterHotKey`; {@link desktopIntegration.onShortcutPressed}
85
+ * reports presses. Registering an id again replaces its accelerator, the same one included; if
86
+ * the new accelerator is refused, the earlier binding stays. A call that rejects with
87
+ * `timeout` did not take effect. Windows only; Linux uses
88
+ * {@link desktopIntegration.registerShortcut}.
89
+ */
90
+ registerGlobalShortcut: (request) => cmd('register_global_shortcut', { request }),
91
+ /** Removes a shortcut registered with {@link desktopIntegration.registerGlobalShortcut}. */
92
+ unregisterGlobalShortcut: (id) => cmd('unregister_global_shortcut', { id }),
93
+ /** Subscribes to notification clicks and button presses; resolves to a function that unsubscribes. */
94
+ onNotificationAction: (callback) => on(NOTIFICATION_ACTION_EVENT, callback),
95
+ /** Subscribes to `FileManager1` calls from other applications. */
96
+ onFileManagerCall: (callback) => on(FILE_MANAGER_CALL_EVENT, callback),
97
+ /** Subscribes to the app losing the `FileManager1` name to another file manager. */
98
+ onFileManagerOwnership: (callback) => on(FILE_MANAGER_OWNERSHIP_EVENT, callback),
99
+ /** Subscribes to presses of Windows global shortcuts. */
100
+ onShortcutPressed: (callback) => on(SHORTCUT_PRESSED_EVENT, callback),
22
101
  /**
23
102
  * Registers a global shortcut. On X11 it's bound immediately; on Wayland,
24
103
  * binding is deferred until the compositor confirms it — see
@@ -48,7 +127,15 @@ const desktopIntegration = {
48
127
  * shortcut-binding-result listener — complements checkShortcutBindingComplete.
49
128
  */
50
129
  checkShortcutBindingError: () => cmd('check_shortcut_binding_error'),
130
+ /**
131
+ * Returns the trigger description (e.g. "Super+E") from the most recent
132
+ * shortcut-changed event, or null if the shortcut hasn't been externally
133
+ * rebound yet this session. Use this to hydrate UI that mounts after a missed
134
+ * event — listen for the `shortcut-changed` event directly via
135
+ * `@tauri-apps/api/event`'s `listen()` for live updates.
136
+ */
137
+ checkShortcutTriggerDescription: () => cmd('check_shortcut_trigger_description'),
51
138
  };
52
139
 
53
- export { desktopIntegration };
140
+ export { FILE_MANAGER_CALL_EVENT, FILE_MANAGER_OWNERSHIP_EVENT, NOTIFICATION_ACTION_EVENT, SHORTCUT_PRESSED_EVENT, desktopIntegration, featureStatus, isFeatureAvailable, isServiceError };
54
141
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../guest-js/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAAA;AACA;AACA;AACA;AASA,MAAM,MAAM,GAAG,6BAA6B;AAE5C,SAAS,GAAG,CAAI,IAAY,EAAE,IAA8B,EAAA;IAC3D,OAAO,MAAM,CAAI,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAE,EAAE,IAAI,CAAC;AAC3C;AAEA,IAAI,kBAAkB,GAAwB,IAAI;AAClD,IAAI,mBAAmB,GAA4B,IAAI;AAEvD,SAAS,wBAAwB,GAAA;AAChC,IAAA,IAAI,mBAAmB;QAAE;AACzB,IAAA,mBAAmB,GAAG,MAAM,CAA2B,oBAAoB,EAAE,MAAK;QACjF,kBAAkB,IAAI;AACvB,IAAA,CAAC,CAAC;AACH;AAEO,MAAM,kBAAkB,GAAG;AACjC;;;;;;;;;;;AAWG;IACH,gBAAgB,EAAE,CACjB,SAAiB,EACjB,kBAA0B,EAC1B,QAAgB,EAChB,WAAuB,KACL;QAClB,kBAAkB,GAAG,WAAW;AAChC,QAAA,wBAAwB,EAAE;AAC1B,QAAA,OAAO,GAAG,CAAC,mBAAmB,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,QAAQ,EAAE,CAAC;IAC7E,CAAC;AAED;;;;AAIG;AACH,IAAA,4BAA4B,EAAE,MAAM,GAAG,CAAU,iCAAiC,CAAC;AAEnF;;;;AAIG;AACH,IAAA,yBAAyB,EAAE,MAAM,GAAG,CAAgB,8BAA8B,CAAC;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../guest-js/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../guest-js/index.test.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liminal-hq/plugin-desktop-integration",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "license": "Apache-2.0 OR MIT",
5
5
  "authors": [
6
6
  "Liminal HQ Contributors"