@stacksjs/desktop 0.2.21 → 0.2.25

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 (56) hide show
  1. package/dist/_bridge.d.ts +105 -0
  2. package/dist/app-info.d.ts +22 -0
  3. package/dist/apple-script.d.ts +8 -0
  4. package/dist/audio.d.ts +17 -0
  5. package/dist/battery.d.ts +15 -0
  6. package/dist/biometric.d.ts +14 -0
  7. package/dist/bluetooth.d.ts +52 -0
  8. package/dist/bonjour.d.ts +13 -0
  9. package/dist/capabilities.d.ts +31 -0
  10. package/dist/clipboard.d.ts +11 -0
  11. package/dist/continuity-camera.d.ts +10 -0
  12. package/dist/coreml.d.ts +6 -0
  13. package/dist/crash-reporter.d.ts +46 -0
  14. package/dist/deep-link.d.ts +10 -0
  15. package/dist/drag-out.d.ts +18 -0
  16. package/dist/file-associations.d.ts +5 -0
  17. package/dist/fs.d.ts +62 -0
  18. package/dist/global-shortcuts.d.ts +19 -0
  19. package/dist/handoff.d.ts +24 -0
  20. package/dist/hotkeys.d.ts +10 -8
  21. package/dist/iap.d.ts +79 -0
  22. package/dist/index.d.ts +322 -0
  23. package/dist/index.js +2505 -20
  24. package/dist/index.js.map +55 -7
  25. package/dist/keychain.d.ts +7 -0
  26. package/dist/live-activities.d.ts +11 -0
  27. package/dist/local-server.d.ts +23 -0
  28. package/dist/location.d.ts +29 -0
  29. package/dist/log.d.ts +7 -0
  30. package/dist/menu.d.ts +29 -0
  31. package/dist/midi.d.ts +17 -0
  32. package/dist/native-autolaunch.d.ts +6 -0
  33. package/dist/network.d.ts +33 -0
  34. package/dist/notifications.d.ts +56 -0
  35. package/dist/pdf.d.ts +5 -0
  36. package/dist/permissions.d.ts +21 -0
  37. package/dist/printing.d.ts +9 -0
  38. package/dist/screen-capture.d.ts +11 -0
  39. package/dist/screen.d.ts +18 -0
  40. package/dist/serial.d.ts +15 -0
  41. package/dist/service-menu.d.ts +10 -0
  42. package/dist/shell.d.ts +28 -0
  43. package/dist/speech-recognition.d.ts +12 -0
  44. package/dist/speech.d.ts +21 -0
  45. package/dist/spotlight.d.ts +12 -0
  46. package/dist/system.d.ts +16 -0
  47. package/dist/tags.d.ts +6 -0
  48. package/dist/test-utils.d.ts +17 -0
  49. package/dist/test-utils.js +108 -0
  50. package/dist/test-utils.js.map +10 -0
  51. package/dist/theme.d.ts +10 -0
  52. package/dist/touchbar.d.ts +29 -0
  53. package/dist/updater.d.ts +37 -0
  54. package/dist/vision.d.ts +17 -0
  55. package/dist/window-events.d.ts +20 -0
  56. package/package.json +5 -1
@@ -0,0 +1,105 @@
1
+ /** True when `window.craft.<ns>` exists. Cheap; do not memoize. */
2
+ export declare function hasBridge(ns: string): boolean;
3
+ /**
4
+ * Get the bridge namespace, or throw a clear error if it isn't there.
5
+ * Use this in the rare case where a sensible web fallback doesn't exist
6
+ * (e.g. system-level battery info). For everything else, prefer
7
+ * `hasBridge` + manual fallback so the call works in browsers too.
8
+ */
9
+ export declare function requireBridge<T = Record<string, any>>(ns: string): T;
10
+ /**
11
+ * Subscribe to a `craft:*` window event with auto-detached cleanup.
12
+ *
13
+ * Two overloads:
14
+ * - **Known event** (string literal in `CraftEventMap`): `detail` is
15
+ * typed to the matching payload, no generic argument needed.
16
+ * - **Custom event** (any other name): pass an explicit `T` to type
17
+ * the payload yourself, or default to `unknown`.
18
+ */
19
+ export declare function onCraftEvent<K extends keyof CraftEventMap>(name: K, cb: (detail: CraftEventMap[K]) => void): () => void;
20
+ export declare function onCraftEvent<T = unknown>(name: string, cb: (detail: T) => void): () => void;
21
+ /**
22
+ * Central index of every `craft:*` event the SDK currently knows about,
23
+ * mapped to its payload shape. Apps that subscribe via `onCraftEvent`
24
+ * with a literal name get fully-typed `detail` automatically — no
25
+ * `<unknown>` casts. Internal modules also use the map to keep their
26
+ * own `onXxx` callbacks honest.
27
+ *
28
+ * When adding a new event name on the native side, add a row here so
29
+ * the public TS surface stays in sync.
30
+ */
31
+ export declare interface CraftEventMap {
32
+ 'craft:powerSleep': void
33
+ 'craft:powerWake': void
34
+ 'craft:networkChange': { type: import('./network').ConnectionType, online: boolean }
35
+ 'craft:screen:change': void
36
+ 'craft:theme': import('./theme').ThemeInfo
37
+ 'craft:bluetooth:deviceFound': import('./bluetooth').BluetoothDevice
38
+ 'craft:bluetooth:deviceConnected': import('./bluetooth').BluetoothDevice
39
+ 'craft:bluetooth:deviceDisconnected': import('./bluetooth').BluetoothDevice
40
+ 'craft:bluetooth:characteristicValue': import('./bluetooth').BluetoothCharacteristicValueEvent
41
+ 'craft:bonjour:found': import('./bonjour').BonjourService
42
+ 'craft:bonjour:lost': import('./bonjour').BonjourService
43
+ 'craft:deepLink': import('./deep-link').DeepLinkEvent
44
+ 'craft:fs:change': import('./fs').FSChangeEvent
45
+ 'craft:shortcut': import('./global-shortcuts').ShortcutFireEvent
46
+ 'craft:handoff:incoming': import('./handoff').HandoffIncomingEvent
47
+ 'craft:iap:purchased': import('./iap').IAPTransactionEvent
48
+ 'craft:iap:failed': import('./iap').IAPFailureEvent
49
+ 'craft:iap:restored': import('./iap').IAPTransactionEvent
50
+ 'craft:iap:productsLoaded': { products?: import('./iap').IAPProduct[] }
51
+ 'craft:iap:refunded': import('./iap').IAPRefundEvent
52
+ 'craft:iap:subscriptionStatusChanged': import('./iap').IAPSubscriptionStatusEvent
53
+ 'craft:localServer:request': import('./local-server').LocalServerRequestEvent
54
+ 'craft:location:update': import('./location').LocationCoordinate
55
+ 'craft:location:error': { message: string }
56
+ 'craft:location:authChanged': { status: import('./location').LocationAuthStatus }
57
+ 'craft:menu:action': import('./menu').MenuActionEvent
58
+ 'craft:midi:message': import('./midi').MIDIMessageEvent
59
+ 'craft:notification:actionClicked': import('./notifications').NotificationActionEvent
60
+ 'craft:notification:reply': import('./notifications').NotificationReplyEvent
61
+ 'craft:serial:data': import('./serial').SerialDataEvent
62
+ 'craft:serviceMenu:invoked': import('./service-menu').ServiceMenuInvokedEvent
63
+ 'craft:shell:stdout': import('./shell').ShellOutputEvent
64
+ 'craft:shell:stderr': import('./shell').ShellOutputEvent
65
+ 'craft:shell:exit': import('./shell').ShellExitEvent
66
+ 'craft:speechRecognition:partial': { transcript: string }
67
+ 'craft:speechRecognition:final': { transcript: string }
68
+ 'craft:touchbar:action': import('./touchbar').TouchBarActionEvent
69
+ 'craft:updateAvailable': import('./updater').UpdateInfo
70
+ 'craft:updateDownloaded': import('./updater').UpdateInfo
71
+ 'craft:window:focus': void
72
+ 'craft:window:blur': void
73
+ 'craft:window:resize': import('./window-events').WindowSize
74
+ 'craft:window:move': import('./window-events').WindowPosition
75
+ 'craft:window:close': void
76
+ 'craft:window:minimize': void
77
+ 'craft:window:restore': void
78
+ 'craft:tray:menu': { id?: string }
79
+ }
80
+ /**
81
+ * Shared internals for craft bridge wrappers.
82
+ *
83
+ * Every public module in this package follows the same shape:
84
+ * 1. Detect whether `window.craft.<namespace>` is available.
85
+ * 2. Forward to it when running inside a Craft native window.
86
+ * 3. Fall back gracefully (or refuse with a clear error) elsewhere.
87
+ *
88
+ * Centralising these helpers keeps the per-module wrappers small and
89
+ * means a future bridge-detection change (e.g. version negotiation)
90
+ * lives in exactly one place.
91
+ *
92
+ * Internal — not re-exported from index.ts. Apps that want to call the
93
+ * bridge directly should use the namespaced public modules.
94
+ */
95
+ // Augment the global window type so callers can import from this module
96
+ // without each one redeclaring `(window as any).craft`. Kept as a loose
97
+ // shape because the bridge is built from the Zig side and we don't want
98
+ // the TS layer to drift out of sync if a single field renames.
99
+ declare global {
100
+ interface Window {
101
+ craft?: Record<string, any>
102
+ __craftPendingDeepLink?: string
103
+ __craftCurrentTheme?: { appearance: 'light' | 'dark' }
104
+ }
105
+ }
@@ -0,0 +1,22 @@
1
+ export declare const app: AppAPI;
2
+ export declare interface AppInfo {
3
+ name: string
4
+ version: string
5
+ bundleId?: string
6
+ bundlePath?: string
7
+ executablePath?: string
8
+ }
9
+ export declare interface AppNotifyOptions {
10
+ title: string
11
+ body?: string
12
+ sound?: string
13
+ }
14
+ export declare interface AppAPI {
15
+ hideDockIcon: () => Promise<void>
16
+ showDockIcon: () => Promise<void>
17
+ quit: () => Promise<void>
18
+ getInfo: () => Promise<AppInfo>
19
+ notify: (options: AppNotifyOptions) => Promise<void>
20
+ setBadge: (count: number) => Promise<void>
21
+ bounce: (type?: 'critical' | 'informational') => Promise<void>
22
+ }
@@ -0,0 +1,8 @@
1
+ export declare const appleScript: AppleScriptAPI;
2
+ export declare interface AppleScriptResult {
3
+ ok: boolean
4
+ result?: string
5
+ }
6
+ export declare interface AppleScriptAPI {
7
+ execute: (source: string) => Promise<AppleScriptResult>
8
+ }
@@ -0,0 +1,17 @@
1
+ export declare const audio: AudioAPI;
2
+ export declare interface AudioPlayOptions {
3
+ volume?: number
4
+ loops?: boolean
5
+ }
6
+ export declare interface AudioRecordOptions {
7
+ maxDurationSec?: number
8
+ }
9
+ export declare interface AudioAPI {
10
+ play: (path: string, options?: AudioPlayOptions) => Promise<boolean>
11
+ playSystemSound: (name: string) => Promise<boolean>
12
+ stop: () => Promise<void>
13
+ isPlaying: () => Promise<boolean>
14
+ startRecording: (path: string, options?: AudioRecordOptions) => Promise<boolean>
15
+ stopRecording: () => Promise<void>
16
+ isRecording: () => Promise<boolean>
17
+ }
@@ -0,0 +1,15 @@
1
+ export declare const battery: BatteryAPI;
2
+ export declare interface BatteryAPI {
3
+ isCharging: () => Promise<boolean>
4
+ isPluggedIn: () => Promise<boolean>
5
+ isLowPowerMode: () => Promise<boolean>
6
+ level: () => Promise<number | null>
7
+ timeRemaining: () => Promise<number | null>
8
+ thermalState: () => Promise<ThermalState>
9
+ uptimeSeconds: () => Promise<number>
10
+ preventSleep: (reason?: string) => Promise<void>
11
+ allowSleep: () => Promise<void>
12
+ onSleep: (cb: () => void) => () => void
13
+ onWake: (cb: () => void) => () => void
14
+ }
15
+ export type ThermalState = 'nominal' | 'fair' | 'serious' | 'critical' | 'unknown';
@@ -0,0 +1,14 @@
1
+ export declare const biometric: BiometricAPI;
2
+ export declare interface BiometricEvaluateOptions {
3
+ allowPasscodeFallback?: boolean
4
+ }
5
+ export declare interface BiometricEvaluateResult {
6
+ success: boolean
7
+ errorCode?: number
8
+ }
9
+ export declare interface BiometricAPI {
10
+ isAvailable: () => Promise<boolean>
11
+ getBiometryType: () => Promise<BiometryType>
12
+ evaluate: (reason: string, options?: BiometricEvaluateOptions) => Promise<BiometricEvaluateResult>
13
+ }
14
+ export type BiometryType = 'none' | 'touchID' | 'faceID' | 'opticID';
@@ -0,0 +1,52 @@
1
+ export declare const bluetooth: BluetoothAPI;
2
+ export declare interface BluetoothDevice {
3
+ id: string
4
+ name: string
5
+ connected: boolean
6
+ rssi?: number
7
+ manufacturer?: string
8
+ }
9
+ export declare interface BluetoothService {
10
+ uuid: string
11
+ primary?: boolean
12
+ }
13
+ export declare interface BluetoothCharacteristic {
14
+ uuid: string
15
+ serviceUuid: string
16
+ properties?: Array<'read' | 'write' | 'writeWithoutResponse' | 'notify' | 'indicate' | 'broadcast' | 'authenticatedSignedWrites' | 'extendedProperties'>
17
+ }
18
+ export declare interface BluetoothCharacteristicValueEvent {
19
+ deviceId: string
20
+ serviceUuid: string
21
+ characteristicUuid: string
22
+ valueHex: string
23
+ }
24
+ export declare interface BluetoothAPI {
25
+ isEnabled: () => Promise<boolean>
26
+ powerState: () => Promise<BluetoothPowerState>
27
+ connectedDevices: () => Promise<BluetoothDevice[]>
28
+ pairedDevices: () => Promise<BluetoothDevice[]>
29
+ startDiscovery: () => Promise<void>
30
+ stopDiscovery: () => Promise<void>
31
+ isDiscovering: () => Promise<boolean>
32
+ connect: (id: string) => Promise<void>
33
+ disconnect: (id: string) => Promise<void>
34
+ openPreferences: () => Promise<void>
35
+ discoverServices: (deviceId: string) => Promise<BluetoothService[]>
36
+ discoverCharacteristics: (deviceId: string, serviceUuid: string) => Promise<BluetoothCharacteristic[]>
37
+ readCharacteristic: (deviceId: string, serviceUuid: string, characteristicUuid: string) => Promise<{ ok: boolean, valueHex?: string, reason?: string }>
38
+ writeCharacteristic: (
39
+ deviceId: string,
40
+ serviceUuid: string,
41
+ characteristicUuid: string,
42
+ valueHex: string,
43
+ mode?: BluetoothWriteMode,
44
+ ) => Promise<{ ok: boolean, reason?: string }>
45
+ setCharacteristicNotify: (deviceId: string, serviceUuid: string, characteristicUuid: string, on: boolean) => Promise<{ ok: boolean, reason?: string }>
46
+ onDeviceFound: (cb: (device: BluetoothDevice) => void) => () => void
47
+ onDeviceConnected: (cb: (device: BluetoothDevice) => void) => () => void
48
+ onDeviceDisconnected: (cb: (device: BluetoothDevice) => void) => () => void
49
+ onCharacteristicValue: (cb: (event: BluetoothCharacteristicValueEvent) => void) => () => void
50
+ }
51
+ export type BluetoothPowerState = 'unknown' | 'resetting' | 'unsupported' | 'unauthorized' | 'poweredOff' | 'poweredOn';
52
+ export type BluetoothWriteMode = 'with-response' | 'without-response';
@@ -0,0 +1,13 @@
1
+ export declare const bonjour: BonjourAPI;
2
+ export declare interface BonjourService {
3
+ name: string
4
+ host?: string
5
+ port?: number
6
+ type: string
7
+ }
8
+ export declare interface BonjourAPI {
9
+ browse: (serviceType: string) => Promise<{ started: boolean, reason?: string }>
10
+ stop: () => Promise<void>
11
+ onFound: (cb: (service: BonjourService) => void) => () => void
12
+ onLost: (cb: (service: BonjourService) => void) => () => void
13
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Snapshot of every known bridge's availability on the current host.
3
+ * Re-call after the bridge IIFE loads (e.g. `DOMContentLoaded`) — the
4
+ * `available` field is computed against `window.craft` at call time.
5
+ */
6
+ export declare function getCapabilities(): BridgeCapability[];
7
+ /**
8
+ * Lookup a single capability by name. Returns `undefined` for bridges
9
+ * the SDK doesn't know about.
10
+ */
11
+ export declare function getCapability(name: string): BridgeCapability | undefined;
12
+ /**
13
+ * Convenience predicate — `true` when a bridge is *both* known to the
14
+ * SDK and currently reachable.
15
+ */
16
+ export declare function isAvailable(name: string): boolean;
17
+ export declare interface BridgeCapability {
18
+ name: string
19
+ support: BridgePlatformSupport
20
+ available: boolean
21
+ }
22
+ /**
23
+ * The set of bridges the SDK knows about, plus the platforms each is
24
+ * implemented on. Used to power the `capabilities` map and to drive
25
+ * docs / tooling.
26
+ *
27
+ * `'all'` means the bridge has a working web/non-bridge fallback too;
28
+ * `'macos'` means it requires a Craft macOS host; `'native'` means it
29
+ * needs *some* Craft host (mac/linux/windows) but has no web fallback.
30
+ */
31
+ export type BridgePlatformSupport = 'all' | 'native' | 'macos';
@@ -0,0 +1,11 @@
1
+ export declare const clipboard: Clipboard;
2
+ export declare interface Clipboard {
3
+ writeText: (text: string) => Promise<void>
4
+ readText: () => Promise<string>
5
+ writeHTML: (html: string) => Promise<void>
6
+ readHTML: () => Promise<string>
7
+ clear: () => Promise<void>
8
+ hasText: () => Promise<boolean>
9
+ hasHTML: () => Promise<boolean>
10
+ hasImage: () => Promise<boolean>
11
+ }
@@ -0,0 +1,10 @@
1
+ export declare const continuityCamera: ContinuityCameraAPI;
2
+ export declare interface ContinuityCameraDevice {
3
+ id: string
4
+ name: string
5
+ manufacturer: string
6
+ isContinuity: boolean
7
+ }
8
+ export declare interface ContinuityCameraAPI {
9
+ listCameras: () => Promise<ContinuityCameraDevice[]>
10
+ }
@@ -0,0 +1,6 @@
1
+ export declare const coreml: CoreMLAPI;
2
+ export declare interface CoreMLAPI {
3
+ loadModel: (id: string, path: string) => Promise<boolean>
4
+ unloadModel: (id: string) => Promise<void>
5
+ predict: (id: string, input: Record<string, unknown>) => Promise<unknown>
6
+ }
@@ -0,0 +1,46 @@
1
+ /** Default redactor — replaces emails, IPv4s, and home paths with placeholders. */
2
+ export declare function redactPII(entry: StoredCrashEntry): StoredCrashEntry;
3
+ /** Sign `body` with HMAC-SHA256 + `secret`. Returns lowercase hex. */
4
+ export declare function signPayload(secret: string, body: string): Promise<string>;
5
+ export declare const crashReporter: CrashReporterAPI;
6
+ export declare interface CrashReport {
7
+ severity?: CrashSeverity
8
+ message: string
9
+ source?: 'js' | 'native'
10
+ stack?: string
11
+ }
12
+ export declare interface StoredCrashEntry {
13
+ timestamp: number
14
+ severity: string
15
+ message: string
16
+ source: string
17
+ stack: string
18
+ userId?: string
19
+ appVersion?: string
20
+ }
21
+ export declare interface CrashForwarderOptions {
22
+ endpoint: string
23
+ intervalMs?: number
24
+ signingSecret?: string
25
+ redact?: boolean | ((entry: StoredCrashEntry) => StoredCrashEntry)
26
+ headers?: Record<string, string>
27
+ maxRetries?: number
28
+ persistKey?: string | null
29
+ }
30
+ export declare interface CrashForwarderHandle {
31
+ flushNow: () => Promise<void>
32
+ stop: () => void
33
+ pending: () => StoredCrashEntry[]
34
+ }
35
+ export declare interface CrashReporterAPI {
36
+ report: (entry: CrashReport | Error) => Promise<void>
37
+ flush: () => Promise<StoredCrashEntry[]>
38
+ clear: () => Promise<void>
39
+ setEnabled: (on: boolean) => Promise<void>
40
+ isEnabled: () => Promise<boolean>
41
+ setUser: (id: string) => Promise<void>
42
+ setAppVersion: (version: string) => Promise<void>
43
+ attachGlobalHandlers: () => () => void
44
+ forwardTo: (options: CrashForwarderOptions) => CrashForwarderHandle
45
+ }
46
+ export type CrashSeverity = 'fatal' | 'error' | 'warning';
@@ -0,0 +1,10 @@
1
+ export declare const deepLinks: DeepLinks;
2
+ export declare interface DeepLinkEvent {
3
+ url: string
4
+ }
5
+ export declare interface DeepLinks {
6
+ onUrl: (cb: (e: DeepLinkEvent) => void) => () => void
7
+ getInitialUrl: () => string | null
8
+ consumeInitialUrl: () => string | null
9
+ isAvailable: () => boolean
10
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Start a native drag with the given file path(s). Returns a promise
3
+ * that resolves when the drag has *started* (not when it ends — there's
4
+ * no reliable native callback for that without per-source delegate
5
+ * scaffolding, and the OS handles the success path on the destination
6
+ * side anyway).
7
+ *
8
+ * Outside a Craft window this rejects with a descriptive error so
9
+ * callers can offer a fallback (e.g. trigger a download).
10
+ */
11
+ export declare function dragOut(paths: string | string[], options?: DragOutOptions): Promise<void>;
12
+ /** True when native drag-out is available. */
13
+ export declare function isDragOutAvailable(): boolean;
14
+ export declare interface DragOutOptions {
15
+ event?: MouseEvent
16
+ x?: number
17
+ y?: number
18
+ }
@@ -0,0 +1,5 @@
1
+ export declare const fileAssociations: FileAssociationsAPI;
2
+ export declare interface FileAssociationsAPI {
3
+ getDefault: (uti: string) => Promise<string | null>
4
+ setDefault: (uti: string, bundleId: string) => Promise<boolean>
5
+ }
package/dist/fs.d.ts ADDED
@@ -0,0 +1,62 @@
1
+ // Each method is `async` so that the synchronous `requireBridge` throw
2
+ // surfaces as a rejected promise — matching the rest of the surface and
3
+ // keeping call sites uniformly awaitable.
4
+ export declare const fs: FS;
5
+ export declare interface FileStat {
6
+ isFile: boolean
7
+ isDirectory: boolean
8
+ isSymlink: boolean
9
+ size: number
10
+ modifiedAt: number
11
+ }
12
+ export declare interface FSChangeEvent {
13
+ id: string
14
+ path: string
15
+ kind?: 'created' | 'modified' | 'deleted' | 'renamed' | 'unknown'
16
+ }
17
+ export declare interface WatchOptions {
18
+ recursive?: boolean
19
+ coalesceMs?: number
20
+ kinds?: Array<NonNullable<FSChangeEvent['kind']>>
21
+ }
22
+ export declare interface WatchHandle {
23
+ stop: () => Promise<void>
24
+ id: string
25
+ }
26
+ export declare interface DirEntry {
27
+ name: string
28
+ path: string
29
+ isDirectory: boolean
30
+ }
31
+ export declare interface MkdirOptions {
32
+ recursive?: boolean
33
+ }
34
+ export declare interface RmdirOptions {
35
+ recursive?: boolean
36
+ }
37
+ export declare interface FS {
38
+ readFile: (path: string) => Promise<string>
39
+ readBuffer: (path: string) => Promise<Uint8Array>
40
+ writeFile: (path: string, data: string) => Promise<void>
41
+ writeBuffer: (path: string, data: Uint8Array) => Promise<void>
42
+ appendFile: (path: string, data: string) => Promise<void>
43
+ deleteFile: (path: string) => Promise<void>
44
+ exists: (path: string) => Promise<boolean>
45
+ stat: (path: string) => Promise<FileStat>
46
+ readDir: (path: string) => Promise<DirEntry[]>
47
+ mkdir: (path: string, opts?: MkdirOptions) => Promise<void>
48
+ rmdir: (path: string, opts?: RmdirOptions) => Promise<void>
49
+ copy: (from: string, to: string) => Promise<void>
50
+ move: (from: string, to: string) => Promise<void>
51
+ watch: (path: string, id?: string) => Promise<void>
52
+ unwatch: (id: string) => Promise<void>
53
+ onChange: (cb: (event: FSChangeEvent) => void) => () => void
54
+ watchTree: (
55
+ path: string,
56
+ options: WatchOptions,
57
+ cb: (events: FSChangeEvent[]) => void,
58
+ ) => Promise<WatchHandle>
59
+ homeDir: () => Promise<string>
60
+ tempDir: () => Promise<string>
61
+ appDataDir: () => Promise<string>
62
+ }
@@ -0,0 +1,19 @@
1
+ export declare const globalShortcuts: GlobalShortcuts;
2
+ export declare interface GlobalShortcutOptions {
3
+ repeats?: boolean
4
+ }
5
+ export declare interface ShortcutFireEvent {
6
+ id: string
7
+ accelerator: string
8
+ timestamp: number
9
+ }
10
+ export declare interface GlobalShortcuts {
11
+ register: (id: string, accelerator: string, opts?: GlobalShortcutOptions) => Promise<void>
12
+ unregister: (id: string) => Promise<void>
13
+ unregisterAll: () => Promise<void>
14
+ enable: (id: string) => Promise<void>
15
+ disable: (id: string) => Promise<void>
16
+ isRegistered: (id: string) => Promise<boolean>
17
+ list: () => Promise<Array<{ id: string, accelerator: string, enabled: boolean }>>
18
+ on: (cb: (e: ShortcutFireEvent) => void) => () => void
19
+ }
@@ -0,0 +1,24 @@
1
+ export declare const handoff: HandoffAPI;
2
+ export declare interface HandoffActivityOptions {
3
+ title?: string
4
+ webpageURL?: string
5
+ userInfo?: Record<string, unknown>
6
+ }
7
+ export declare interface HandoffSnapshot {
8
+ type: string
9
+ title: string
10
+ webpageURL: string
11
+ }
12
+ export declare interface HandoffIncomingEvent {
13
+ type: string
14
+ title?: string
15
+ webpageURL?: string
16
+ userInfo?: Record<string, unknown>
17
+ }
18
+ export declare interface HandoffAPI {
19
+ startActivity: (type: string, options?: HandoffActivityOptions) => Promise<boolean>
20
+ updateActivity: (options: HandoffActivityOptions) => Promise<boolean>
21
+ stopActivity: () => Promise<void>
22
+ getCurrentActivity: () => Promise<HandoffSnapshot | null>
23
+ onIncoming: (cb: (event: HandoffIncomingEvent) => void) => () => void
24
+ }
package/dist/hotkeys.d.ts CHANGED
@@ -37,25 +37,27 @@ export declare function unregisterAllHotkeys(): void;
37
37
  */
38
38
  export declare function getRegisteredHotkeys(): HotkeyRegistration[];
39
39
  /**
40
- * Global Hotkey API
40
+ * Hotkey API (in-window, document-level)
41
41
  *
42
- * Register global keyboard shortcuts that work even when the app is not focused.
43
- * Communicates with Craft's native side to register system-wide hotkeys.
44
- * Falls back to document-level listeners in web/non-native mode.
42
+ * Register keyboard shortcuts via document-level listeners. These fire
43
+ * **only while a Craft window has focus** a thin wrapper around
44
+ * `keydown`. Use this for app-internal shortcuts like
45
+ * "Cmd+K opens the command palette."
46
+ *
47
+ * **For system-wide shortcuts** that fire even when the app isn't
48
+ * focused (e.g. global "Cmd+Shift+V to bring up your clipboard
49
+ * manager"), use `globalShortcuts` from `./global-shortcuts` — that
50
+ * talks to the native `RegisterEventHotKey` / `RegisterHotKey` APIs.
45
51
  *
46
52
  * @example
47
53
  * ```typescript
48
54
  * import { registerHotkey, unregisterAllHotkeys } from '@stacksjs/desktop'
49
55
  *
50
- * // Register a global shortcut
51
56
  * const reg = registerHotkey('Cmd+Shift+C', () => {
52
57
  * console.log('Hotkey triggered!')
53
58
  * })
54
59
  *
55
- * // Unregister a specific shortcut
56
60
  * reg.unregister()
57
- *
58
- * // Unregister all shortcuts
59
61
  * unregisterAllHotkeys()
60
62
  * ```
61
63
  */
package/dist/iap.d.ts ADDED
@@ -0,0 +1,79 @@
1
+ export declare const iap: IAPAPI;
2
+ export declare interface IAPSubscriptionInfo {
3
+ numberOfUnits: number
4
+ unit: IAPSubscriptionPeriod
5
+ introductoryOffer?: IAPIntroductoryOffer
6
+ familyShareable?: boolean
7
+ groupIdentifier?: string
8
+ }
9
+ export declare interface IAPIntroductoryOffer {
10
+ paymentMode: 'free-trial' | 'pay-as-you-go' | 'pay-up-front'
11
+ localizedPrice: string
12
+ numberOfUnits: number
13
+ unit: IAPSubscriptionPeriod
14
+ numberOfPeriods?: number
15
+ }
16
+ export declare interface IAPProduct {
17
+ id: string
18
+ title: string
19
+ description?: string
20
+ price: string
21
+ currency?: string
22
+ localizedPrice?: string
23
+ type?: IAPProductType
24
+ subscription?: IAPSubscriptionInfo
25
+ }
26
+ export declare interface IAPPurchaseResult {
27
+ queued: boolean
28
+ productId?: string
29
+ reason?: string
30
+ }
31
+ export declare interface IAPTransactionEvent {
32
+ productId: string
33
+ transactionId: string
34
+ date?: string
35
+ originalTransactionId?: string
36
+ familyShared?: boolean
37
+ restored?: boolean
38
+ autoRenewing?: boolean
39
+ expiresAt?: string
40
+ inIntroPeriod?: boolean
41
+ }
42
+ export declare interface IAPFailureEvent {
43
+ productId: string
44
+ code?: number
45
+ message?: string
46
+ }
47
+ export declare interface IAPRefundEvent {
48
+ productId: string
49
+ transactionId: string
50
+ refundedAt?: string
51
+ reason?: string
52
+ }
53
+ export declare interface IAPSubscriptionStatusEvent {
54
+ productId: string
55
+ status: 'active' | 'expired' | 'in-grace-period' | 'in-billing-retry' | 'revoked'
56
+ changedAt?: string
57
+ expiresAt?: string
58
+ }
59
+ export declare interface IAPAPI {
60
+ isAvailable: () => Promise<boolean>
61
+ getProducts: (ids: string[] | string) => Promise<IAPProduct[]>
62
+ purchase: (productId: string) => Promise<IAPPurchaseResult>
63
+ restorePurchases: () => Promise<{ ok: boolean }>
64
+ finishTransaction: (transactionId: string) => Promise<void>
65
+ getReceiptData: () => Promise<string | null>
66
+ onPurchased: (cb: (e: IAPTransactionEvent) => void) => () => void
67
+ onFailed: (cb: (e: IAPFailureEvent) => void) => () => void
68
+ onRestored: (cb: (e: IAPTransactionEvent) => void) => () => void
69
+ onProductsLoaded: (cb: (products: IAPProduct[]) => void) => () => void
70
+ onRefunded: (cb: (e: IAPRefundEvent) => void) => () => void
71
+ onSubscriptionStatusChanged: (cb: (e: IAPSubscriptionStatusEvent) => void) => () => void
72
+ getActiveSubscriptions: () => Promise<IAPSubscriptionStatusEvent[]>
73
+ isEligibleForIntroOffer: (productId: string) => Promise<boolean>
74
+ }
75
+ export type IAPProductType = | 'consumable'
76
+ | 'non-consumable'
77
+ | 'auto-subscription'
78
+ | 'non-auto-subscription';
79
+ export type IAPSubscriptionPeriod = 'day' | 'week' | 'month' | 'year';