@kehto/shell 0.16.7 → 0.18.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.
package/dist/index.d.ts CHANGED
@@ -4,6 +4,38 @@ import { NappletMessage, NostrEvent, NostrFilter } from '@napplet/core';
4
4
  export { NappletMessage, NostrEvent, NostrFilter, TOPICS, TopicKey, TopicValue } from '@napplet/core';
5
5
  import { Theme } from '@napplet/nap/theme/types';
6
6
 
7
+ /** NIP-5D identity metadata associated with a registered iframe window. */
8
+ interface OriginIdentity {
9
+ readonly dTag: string;
10
+ readonly aggregateHash: string;
11
+ }
12
+ /**
13
+ * Bidirectional registry mapping Window references to windowId strings.
14
+ * Optionally stores NIP-5D identity metadata (dTag and aggregateHash) per window.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { originRegistry } from '@kehto/shell';
19
+ *
20
+ * originRegistry.register(iframe.contentWindow, 'napp-1');
21
+ * const id = originRegistry.getWindowId(iframe.contentWindow); // 'napp-1'
22
+ * ```
23
+ */
24
+ interface OriginRegistry {
25
+ register(win: Window, windowId: string, identity?: OriginIdentity): void;
26
+ unregister(windowId: string): void;
27
+ getWindowId(win: Window): string | undefined;
28
+ getIframeWindow(windowId: string): Window | null;
29
+ getAllWindowIds(): string[];
30
+ getIdentity(win: Window): OriginIdentity | undefined;
31
+ setEnvironment(win: Window, environment: ShellEnvironment): void;
32
+ getEnvironment(win: Window): ShellEnvironment | undefined;
33
+ getRegistrationId(win: Window): number | undefined;
34
+ clear(): void;
35
+ }
36
+ /** Shell-wide iframe window registry singleton. */
37
+ declare const originRegistry: OriginRegistry;
38
+
7
39
  /**
8
40
  * ACL entry controlling what a napplet pubkey is permitted to do.
9
41
  * @example
@@ -42,8 +74,13 @@ interface RelayPoolHooks {
42
74
  openScopedRelay(windowId: string, relayUrl: string, subId: string, filters: NostrFilter[], sourceWindow: Window): void;
43
75
  /** Close a scoped relay connection. */
44
76
  closeScopedRelay(windowId: string): void;
45
- /** Publish to a scoped relay. Returns false if no active scoped relay. */
46
- publishToScopedRelay(windowId: string, event: NostrEvent): boolean;
77
+ /**
78
+ * Publish to a scoped relay.
79
+ *
80
+ * Async hosts settle the returned promise after transport acceptance.
81
+ * Returns false if no active scoped relay or publication fails.
82
+ */
83
+ publishToScopedRelay(windowId: string, event: NostrEvent): boolean | Promise<boolean>;
47
84
  /** Select relay URLs for a given set of filters. */
48
85
  selectRelayTier(filters: NostrFilter[]): string[];
49
86
  }
@@ -54,7 +91,7 @@ interface RelayPoolLike {
54
91
  unsubscribe(): void;
55
92
  };
56
93
  };
57
- publish(relayUrls: string[], event: any): void;
94
+ publish(relayUrls: string[], event: any): void | Promise<void>;
58
95
  request(relayUrls: string[], filters: any): {
59
96
  subscribe(observer: {
60
97
  next: (event: unknown) => void;
@@ -205,8 +242,26 @@ interface WebrtcHooks {
205
242
  * environments while still using the production shell-ready path.
206
243
  */
207
244
  interface CapabilityHooks {
208
- /** Bare capability domains to remove from domains, naps, and protocols. */
245
+ /** Bare capability domains to remove from the delivered environment. */
209
246
  readonly disabledDomains?: readonly string[];
247
+ /**
248
+ * Narrow the live environment for one trusted creation-time identity.
249
+ *
250
+ * The shell supplies copied, frozen live domains and named services. Returned
251
+ * names are intersected with that exact availability set, so this hook cannot
252
+ * add aliases, disabled entries, or unwired capabilities.
253
+ *
254
+ * @param identity - Identity assigned by the host when the iframe was created.
255
+ * @param available - Immutable live domains and services before host policy.
256
+ * @returns The requested subset for this identity.
257
+ */
258
+ readonly resolveEnvironment?: (identity: OriginIdentity, available: Readonly<{
259
+ domains: readonly string[];
260
+ services: readonly string[];
261
+ }>) => Readonly<{
262
+ domains: readonly string[];
263
+ services: readonly string[];
264
+ }>;
210
265
  }
211
266
  /**
212
267
  * Event emitted on every ACL enforcement check.
@@ -262,71 +317,21 @@ interface UnroutedMessageInfo {
262
317
  }
263
318
  /**
264
319
  * Static capability set sent to napplet iframes through the shell.ready /
265
- * shell.init handshake. The current runtime availability primitive is injected
266
- * `window.napplet.<domain>` presence; this shape remains for older consumers
267
- * that still read shell.init capability metadata.
268
- *
269
- * Current availability is the injected `window.napplet.<domain>` namespace.
270
- * Compatibility supports() helpers should treat only NAP domains and protocols
271
- * as advertised capabilities:
320
+ * shell.init handshake. Optional runtime domain presence is injected before
321
+ * authored code, while mandatory NAP-SHELL caches this environment for local
322
+ * capability queries.
272
323
  *
273
- * - Bare names for NAP-capability lookups, resolved against the `naps`
274
- * array — e.g. `supports('relay')`, `supports('identity')`.
275
- *
276
- * The sandbox array remains for older payload readers, but Kehto emits it empty.
277
- * NIP-5D no longer blesses additional browser sandbox tokens as interoperability
278
- * requirements or napplet-visible capabilities.
279
- *
280
- * ## Compatibility NAP-SHELL shape
281
- *
282
- * Older shell consumers may read the structured
283
- * `capabilities.{ domains: string[], protocols: Record<string, string[]> }`
284
- * alongside the flat `naps` array:
285
- *
286
- * - `supports('relay')` → true iff `'relay' ∈ capabilities.domains`
287
- * - `supports('inc','NAP-01')`→ true iff `capabilities.protocols['inc']`
288
- * includes `'NAP-01'`
289
- *
290
- * `domains` and `protocols` are emitted as a superset alongside the
291
- * `naps`/`sandbox` fields for back-compat.
324
+ * NAP-SHELL needs only a truthful set of bare domain names. The shim answers
325
+ * `shell.supports(domain)` locally from this snapshot after `shell.init`.
292
326
  */
293
327
  interface ShellCapabilities {
294
- /**
295
- * Compatibility NAP-SHELL domain list.
296
- * Bare NAP domain names the shell offers — `'identity'`, `'storage'`,
297
- * `'inc'`, `'theme'`, etc. — with the same conditional entries as `naps`
298
- * (`relay`/`outbox` when a relay pool is wired, `upload`/`intent` under their
299
- * hooks). Carries NO `inc:NAP-NN` protocol strings (those live in
300
- * `protocols`).
301
- */
302
- domains: string[];
303
- /**
304
- * Compatibility NAP-SHELL per-domain numbered protocols. Maps a domain to the NAP-NN protocol IDs it
305
- * speaks — `{ inc: ['NAP-01','NAP-02','NAP-03','NAP-04','NAP-05','NAP-06'] }`
306
- * (derived from `NAP_INC_PROTOCOLS` by stripping the `inc:` prefix).
307
- *
308
- * Legacy supports helpers resolve `supports('<domain>','NAP-NN')` against this map.
309
- */
310
- protocols: Record<string, string[]>;
311
- /**
312
- * NAP-vocabulary domain entries the shell handles (PRIMARY — consumed by
313
- * `@napplet/shim >=0.9.0`). Bare domain `inc` (the NAP rename of `inc`)
314
- * plus protocol IDs `inc:NAP-01..inc:NAP-06`. Conditional entries:
315
- * `relay`, `outbox` prepended when a relay pool is wired; `upload` appended
316
- * when an upload backend is wired; `intent` appended when an intent
317
- * dispatcher is available.
318
- *
319
- * Contains NO `NAP-NN` protocol strings (those live in `protocols`).
320
- */
321
- naps: string[];
322
- /**
323
- * Empty compatibility field for older `shell.init` payload consumers.
324
- *
325
- * Current NIP-5D keeps the web sandbox baseline narrow: hosted napplet iframes
326
- * use `allow-scripts`, never `allow-same-origin`, and do not receive optional
327
- * browser sandbox relaxations as advertised capabilities.
328
- */
329
- sandbox: string[];
328
+ /** Immutable bare domain names the shell offers to this napplet. */
329
+ readonly domains: readonly string[];
330
+ }
331
+ /** Immutable NAP-SHELL environment delivered to one trusted iframe session. */
332
+ interface ShellEnvironment {
333
+ readonly capabilities: ShellCapabilities;
334
+ readonly services: readonly string[];
330
335
  }
331
336
  /**
332
337
  * All adapters that the shell requires from the host application.
@@ -532,18 +537,13 @@ interface ShellBridge {
532
537
  */
533
538
  registerConsentHandler(handler: (request: ConsentRequest) => void): void;
534
539
  /**
535
- * Publish a theme update to every registered napplet.
540
+ * Publish a theme update to each eligible napplet.
536
541
  *
537
542
  * Posts a `theme.changed` envelope (shell → napplet push) to every
538
- * window currently tracked by the runtime's sessionRegistry, using
539
- * the browser-adapter originRegistry to resolve windowId → iframe.
540
- * Napplets whose window cannot be resolved (stale sessions) are
541
- * silently skipped; this method never throws.
542
- *
543
- * ACL is enforced BY THE RECIPIENT NAPPLET — the runtime's
544
- * `themeMap` in @kehto/acl assigns `recipientCap: 'theme:read'` for
545
- * `theme.changed`, and @napplet/shim drops pushes the napplet lacks
546
- * the capability for. Hosts should not self-filter here.
543
+ * live authenticated session whose frozen environment grants `theme` and
544
+ * whose current ACL grants `theme:read`. Stale or ineligible sessions are
545
+ * skipped before origin-registry delivery; recipient code is not trusted
546
+ * to enforce host authorization.
547
547
  *
548
548
  * @param theme - The new theme payload to broadcast.
549
549
  * @example
@@ -575,6 +575,14 @@ interface ShellBridge {
575
575
  }
576
576
  declare function createShellBridge(hooks: ShellAdapter): ShellBridge;
577
577
 
578
+ /**
579
+ * The injected implementation must remain one self-contained function: the
580
+ * renderer serializes it ahead of verified artifact scripts without changing
581
+ * the signed artifact bytes. Splitting it into imported helpers would leave
582
+ * unresolved closures in the generated `srcdoc`.
583
+ *
584
+ * aislop-ignore-file complexity/file-too-large complexity/function-too-long
585
+ */
578
586
  /**
579
587
  * Options for rendering the host-owned NIP-5D `window.napplet` namespace prelude.
580
588
  *
@@ -587,7 +595,8 @@ declare function createShellBridge(hooks: ShellAdapter): ShellBridge;
587
595
  */
588
596
  interface NappletNamespacePreludeOptions {
589
597
  /**
590
- * Bare NAP domain names the shell exposes to this napplet.
598
+ * Optional bare NAP domain names the shell exposes to this napplet.
599
+ * Mandatory `shell` is injected even when omitted here.
591
600
  */
592
601
  domains: readonly string[];
593
602
  }
@@ -621,77 +630,6 @@ declare function renderNappletNamespacePrelude(options: NappletNamespacePreludeO
621
630
  */
622
631
  declare function injectNappletNamespacePrelude(html: string, options: NappletNamespacePreludeOptions): string;
623
632
 
624
- /**
625
- * Bidirectional registry mapping Window references to windowId strings.
626
- * Optionally stores NIP-5D identity metadata (dTag and aggregateHash) per window.
627
- *
628
- * @example
629
- * ```ts
630
- * import { originRegistry } from '@kehto/shell';
631
- *
632
- * originRegistry.register(iframe.contentWindow, 'napp-1');
633
- * const id = originRegistry.getWindowId(iframe.contentWindow); // 'napp-1'
634
- * ```
635
- */
636
- declare const originRegistry: {
637
- /**
638
- * Register a window reference with a windowId and optional identity metadata.
639
- *
640
- * @param win - The iframe's contentWindow reference
641
- * @param windowId - The unique identifier for this napplet window
642
- * @param identity - Optional NIP-5D identity metadata (dTag and aggregateHash)
643
- */
644
- register(win: Window, windowId: string, identity?: {
645
- dTag: string;
646
- aggregateHash: string;
647
- }): void;
648
- /**
649
- * Unregister a window by its windowId, removing the mapping.
650
- *
651
- * @param windowId - The window identifier to remove
652
- */
653
- unregister(windowId: string): void;
654
- /**
655
- * Look up the windowId for a given Window reference.
656
- *
657
- * @param win - The Window reference (typically from event.source)
658
- * @returns The windowId string, or undefined if not registered
659
- */
660
- getWindowId(win: Window): string | undefined;
661
- /**
662
- * Look up the Window reference for a given windowId.
663
- *
664
- * @param windowId - The window identifier to look up
665
- * @returns The Window reference, or null if not found
666
- */
667
- getIframeWindow(windowId: string): Window | null;
668
- /**
669
- * Get all registered windowId strings.
670
- *
671
- * @returns Array of all registered window identifiers
672
- */
673
- getAllWindowIds(): string[];
674
- /**
675
- * Get identity metadata for a registered Window.
676
- *
677
- * @param win - The Window reference to look up
678
- * @returns Identity metadata, or undefined if not registered or no identity set
679
- */
680
- getIdentity(win: Window): {
681
- dTag: string;
682
- aggregateHash: string;
683
- } | undefined;
684
- /**
685
- * Look up the monotonically increasing registration id for a Window.
686
- *
687
- * @param win - The Window reference to look up
688
- * @returns The registration id, or undefined if the Window is not registered
689
- */
690
- getRegistrationId(win: Window): number | undefined;
691
- /** Clear all registrations. */
692
- clear(): void;
693
- };
694
-
695
633
  /**
696
634
  * Manifest cache — persists verified NIP-5A aggregate hashes per napplet identity.
697
635
  */
@@ -723,44 +661,17 @@ interface ManifestCacheEntry {
723
661
  * const entry = manifestCache.get('abc...', 'chat');
724
662
  * ```
725
663
  */
726
- declare const manifestCache: {
727
- /**
728
- * Get a cached manifest entry by pubkey and dTag.
729
- *
730
- * @param pubkey - The napp's pubkey
731
- * @param dTag - The napp's dTag
732
- * @returns The cached entry, or undefined if not found
733
- */
664
+ interface ManifestCache {
734
665
  get(pubkey: string, dTag: string): ManifestCacheEntry | undefined;
735
- /**
736
- * Set (upsert) a manifest cache entry and persist to localStorage.
737
- *
738
- * @param entry - The manifest entry to cache
739
- */
740
666
  set(entry: ManifestCacheEntry): void;
741
- /**
742
- * Check if a specific hash is cached for a pubkey/dTag combination.
743
- *
744
- * @param pubkey - The napp's pubkey
745
- * @param dTag - The napp's dTag
746
- * @param hash - The aggregateHash to check
747
- * @returns True if the exact hash matches the cached entry
748
- */
749
667
  has(pubkey: string, dTag: string, hash: string): boolean;
750
- /**
751
- * Remove a cached entry for a pubkey/dTag and persist.
752
- *
753
- * @param pubkey - The napp's pubkey
754
- * @param dTag - The napp's dTag
755
- */
756
668
  remove(pubkey: string, dTag: string): void;
757
- /** Load the cache from localStorage. */
758
669
  load(): void;
759
- /** Persist the cache to localStorage. */
760
670
  persist(): void;
761
- /** Clear all cached entries and remove from localStorage. */
762
671
  clear(): void;
763
- };
672
+ }
673
+ /** Shell-wide manifest verification cache singleton. */
674
+ declare const manifestCache: ManifestCache;
764
675
 
765
676
  /**
766
677
  * ACL store — manages capability grants, revocations, and blocks for napp identities.
@@ -774,92 +685,22 @@ declare const manifestCache: {
774
685
  * const allowed = aclStore.check(pubkey, dTag, hash, 'relay:read'); // true
775
686
  * ```
776
687
  */
777
- declare const aclStore: {
778
- /**
779
- * Check if a napp identity has a specific capability.
780
- * Returns true for unknown identities (permissive default).
781
- *
782
- * @param pubkey - The napp's pubkey
783
- * @param dTag - The napp's dTag
784
- * @param aggregateHash - The napp's build hash
785
- * @param capability - The capability to check
786
- * @returns True if the capability is granted and the napp is not blocked
787
- */
688
+ interface AclStore {
788
689
  check(pubkey: string, dTag: string, aggregateHash: string, capability: Capability): boolean;
789
- /**
790
- * Grant a capability to a napp identity.
791
- *
792
- * @param pubkey - The napp's pubkey
793
- * @param dTag - The napp's dTag
794
- * @param aggregateHash - The napp's build hash
795
- * @param capability - The capability to grant
796
- */
797
690
  grant(pubkey: string, dTag: string, aggregateHash: string, capability: Capability): void;
798
- /**
799
- * Revoke a capability from a napp identity.
800
- *
801
- * @param pubkey - The napp's pubkey
802
- * @param dTag - The napp's dTag
803
- * @param aggregateHash - The napp's build hash
804
- * @param capability - The capability to revoke
805
- */
806
691
  revoke(pubkey: string, dTag: string, aggregateHash: string, capability: Capability): void;
807
- /**
808
- * Block a napp identity entirely (all capabilities denied).
809
- *
810
- * @param pubkey - The napp's pubkey
811
- * @param dTag - The napp's dTag
812
- * @param aggregateHash - The napp's build hash
813
- */
814
692
  block(pubkey: string, dTag: string, aggregateHash: string): void;
815
- /**
816
- * Unblock a napp identity.
817
- *
818
- * @param pubkey - The napp's pubkey
819
- * @param dTag - The napp's dTag
820
- * @param aggregateHash - The napp's build hash
821
- */
822
693
  unblock(pubkey: string, dTag: string, aggregateHash: string): void;
823
- /**
824
- * Check if a napp identity is blocked.
825
- *
826
- * @param pubkey - The napp's pubkey
827
- * @param dTag - The napp's dTag
828
- * @param aggregateHash - The napp's build hash
829
- * @returns True if the identity is blocked
830
- */
831
694
  isBlocked(pubkey: string, dTag: string, aggregateHash: string): boolean;
832
- /**
833
- * Get the external ACL entry for a napp identity.
834
- *
835
- * @param pubkey - The napp's pubkey
836
- * @param dTag - The napp's dTag
837
- * @param aggregateHash - The napp's build hash
838
- * @returns The ACL entry, or undefined if no explicit entry exists
839
- */
840
695
  getEntry(pubkey: string, dTag: string, aggregateHash: string): AclEntry | undefined;
841
- /**
842
- * Get all ACL entries.
843
- *
844
- * @returns Array of all ACL entries
845
- */
846
696
  getAllEntries(): AclEntry[];
847
- /** Persist the ACL store to localStorage. */
848
697
  persist(): void;
849
- /** Load the ACL store from localStorage. Migrates old 3-segment keys to 2-segment format. */
850
698
  load(): void;
851
- /**
852
- * Get the state quota for a napp identity.
853
- *
854
- * @param pubkey - The napp's pubkey
855
- * @param dTag - The napp's dTag
856
- * @param aggregateHash - The napp's build hash
857
- * @returns The quota in bytes (defaults to DEFAULT_STATE_QUOTA)
858
- */
859
699
  getStateQuota(pubkey: string, dTag: string, aggregateHash: string): number;
860
- /** Clear all ACL entries and remove from localStorage. */
861
700
  clear(): void;
862
- };
701
+ }
702
+ /** Shell ACL store singleton. */
703
+ declare const aclStore: AclStore;
863
704
 
864
705
  /**
865
706
  * audio-manager.ts — Shell-side registry of active audio sources.
@@ -895,69 +736,22 @@ interface AudioSource {
895
736
  * audioManager.mute('win-1', true);
896
737
  * ```
897
738
  */
898
- declare const audioManager: {
899
- /**
900
- * Register a new audio source for a window.
901
- *
902
- * @param windowId - The window identifier
903
- * @param nappletClass - The napplet class/type (e.g., 'music-player')
904
- * @param title - Human-readable title for the audio source
905
- */
739
+ interface AudioManager {
906
740
  register(windowId: string, nappletClass: string, title: string): void;
907
- /**
908
- * Unregister an audio source for a window.
909
- *
910
- * @param windowId - The window identifier to remove
911
- */
912
741
  unregister(windowId: string): void;
913
- /**
914
- * Update the state of an audio source (e.g., change title).
915
- *
916
- * @param windowId - The window identifier
917
- * @param update - Partial update with optional title
918
- */
919
742
  updateState(windowId: string, update: {
920
743
  title?: string;
921
744
  }): void;
922
- /**
923
- * Mute or unmute an audio source and notify the napplet via postMessage.
924
- *
925
- * @param windowId - The window identifier
926
- * @param muted - True to mute, false to unmute
927
- * @example
928
- * ```ts
929
- * audioManager.mute('win-1', true); // mute
930
- * audioManager.mute('win-1', false); // unmute
931
- * ```
932
- */
933
745
  mute(windowId: string, muted: boolean): void;
934
- /**
935
- * Check if a window has a registered audio source.
936
- *
937
- * @param windowId - The window identifier
938
- * @returns True if the window has an active audio source
939
- */
940
746
  has(windowId: string): boolean;
941
- /**
942
- * Get the audio source for a window.
943
- *
944
- * @param windowId - The window identifier
945
- * @returns The AudioSource, or undefined if not found
946
- */
947
747
  get(windowId: string): AudioSource | undefined;
948
- /**
949
- * Get a snapshot of all audio sources.
950
- *
951
- * @returns A new Map of all active audio sources
952
- */
953
748
  getSources(): Map<string, AudioSource>;
954
- /** Current version counter (incremented on every change). */
955
749
  readonly version: number;
956
- /** Number of active audio sources. */
957
750
  readonly count: number;
958
- /** Clear all audio sources and reset version counter. */
959
751
  clear(): void;
960
- };
752
+ }
753
+ /** Shell-wide audio source registry singleton. */
754
+ declare const audioManager: AudioManager;
961
755
 
962
756
  /**
963
757
  * SessionRegistry — windowId to verified napplet pubkey bidirectional mapping.
@@ -978,149 +772,23 @@ declare const audioManager: {
978
772
  * const entry = pubkey ? sessionRegistry.getEntry(pubkey) : undefined;
979
773
  * ```
980
774
  */
981
- declare const sessionRegistry: {
982
- /**
983
- * Register a napplet entry, mapping windowId to pubkey and vice versa.
984
- *
985
- * @param windowId - The window identifier
986
- * @param entry - The verified napplet session entry from AUTH handshake
987
- */
775
+ interface SessionRegistry {
988
776
  register(windowId: string, entry: SessionEntry): void;
989
- /**
990
- * Unregister a napplet by windowId, removing both mappings.
991
- *
992
- * @param windowId - The window identifier to remove
993
- */
994
777
  unregister(windowId: string): void;
995
- /**
996
- * Get the pubkey associated with a windowId.
997
- *
998
- * @param windowId - The window identifier
999
- * @returns The napplet's pubkey, or undefined if not registered
1000
- */
1001
778
  getPubkey(windowId: string): string | undefined;
1002
- /**
1003
- * Get the full entry for a napplet pubkey.
1004
- *
1005
- * @param pubkey - The napplet's pubkey
1006
- * @returns The full SessionEntry, or undefined if not found
1007
- */
1008
779
  getEntry(pubkey: string): SessionEntry | undefined;
1009
- /**
1010
- * Get the windowId for a napplet pubkey.
1011
- *
1012
- * @param pubkey - The napplet's pubkey
1013
- * @returns The windowId, or undefined if not found
1014
- */
1015
780
  getWindowId(pubkey: string): string | undefined;
1016
- /**
1017
- * Check if a windowId has a registered napplet.
1018
- *
1019
- * @param windowId - The window identifier
1020
- * @returns True if the windowId has a registered napplet
1021
- */
1022
781
  isRegistered(windowId: string): boolean;
1023
- /**
1024
- * Get all registered napplet entries.
1025
- *
1026
- * @returns Array of all SessionEntry objects
1027
- */
1028
782
  getAllEntries(): SessionEntry[];
1029
- /**
1030
- * Set a pending update for a window (napplet reconnected with different hash).
1031
- *
1032
- * @param windowId - The window identifier
1033
- * @param update - The pending update details with resolve callback
1034
- */
1035
783
  setPendingUpdate(windowId: string, update: PendingUpdate): void;
1036
- /**
1037
- * Get a pending update for a window.
1038
- *
1039
- * @param windowId - The window identifier
1040
- * @returns The pending update, or undefined if none
1041
- */
1042
784
  getPendingUpdate(windowId: string): PendingUpdate | undefined;
1043
- /**
1044
- * Clear a pending update for a window.
1045
- *
1046
- * @param windowId - The window identifier
1047
- */
1048
785
  clearPendingUpdate(windowId: string): void;
1049
- /** Clear all registrations and pending updates. */
1050
786
  clear(): void;
1051
- };
787
+ }
788
+ /** Shell-wide verified napplet session registry singleton. */
789
+ declare const sessionRegistry: SessionRegistry;
1052
790
  /** @deprecated Use sessionRegistry. Will be removed in v0.9.0. */
1053
- declare const nappKeyRegistry: {
1054
- /**
1055
- * Register a napplet entry, mapping windowId to pubkey and vice versa.
1056
- *
1057
- * @param windowId - The window identifier
1058
- * @param entry - The verified napplet session entry from AUTH handshake
1059
- */
1060
- register(windowId: string, entry: SessionEntry): void;
1061
- /**
1062
- * Unregister a napplet by windowId, removing both mappings.
1063
- *
1064
- * @param windowId - The window identifier to remove
1065
- */
1066
- unregister(windowId: string): void;
1067
- /**
1068
- * Get the pubkey associated with a windowId.
1069
- *
1070
- * @param windowId - The window identifier
1071
- * @returns The napplet's pubkey, or undefined if not registered
1072
- */
1073
- getPubkey(windowId: string): string | undefined;
1074
- /**
1075
- * Get the full entry for a napplet pubkey.
1076
- *
1077
- * @param pubkey - The napplet's pubkey
1078
- * @returns The full SessionEntry, or undefined if not found
1079
- */
1080
- getEntry(pubkey: string): SessionEntry | undefined;
1081
- /**
1082
- * Get the windowId for a napplet pubkey.
1083
- *
1084
- * @param pubkey - The napplet's pubkey
1085
- * @returns The windowId, or undefined if not found
1086
- */
1087
- getWindowId(pubkey: string): string | undefined;
1088
- /**
1089
- * Check if a windowId has a registered napplet.
1090
- *
1091
- * @param windowId - The window identifier
1092
- * @returns True if the windowId has a registered napplet
1093
- */
1094
- isRegistered(windowId: string): boolean;
1095
- /**
1096
- * Get all registered napplet entries.
1097
- *
1098
- * @returns Array of all SessionEntry objects
1099
- */
1100
- getAllEntries(): SessionEntry[];
1101
- /**
1102
- * Set a pending update for a window (napplet reconnected with different hash).
1103
- *
1104
- * @param windowId - The window identifier
1105
- * @param update - The pending update details with resolve callback
1106
- */
1107
- setPendingUpdate(windowId: string, update: PendingUpdate): void;
1108
- /**
1109
- * Get a pending update for a window.
1110
- *
1111
- * @param windowId - The window identifier
1112
- * @returns The pending update, or undefined if none
1113
- */
1114
- getPendingUpdate(windowId: string): PendingUpdate | undefined;
1115
- /**
1116
- * Clear a pending update for a window.
1117
- *
1118
- * @param windowId - The window identifier
1119
- */
1120
- clearPendingUpdate(windowId: string): void;
1121
- /** Clear all registrations and pending updates. */
1122
- clear(): void;
1123
- };
791
+ declare const nappKeyRegistry: SessionRegistry;
1124
792
 
1125
793
  /**
1126
794
  * hooks-adapter.ts — Converts ShellAdapter (browser-facing) to RuntimeAdapter (environment-agnostic).
@@ -1166,63 +834,36 @@ interface BrowserDeps {
1166
834
  declare function adaptHooks(shellHooks: ShellAdapter, deps: BrowserDeps): RuntimeAdapter;
1167
835
 
1168
836
  /**
1169
- * Build the shell's static capability set from adapter configuration.
1170
- *
1171
- * Returns the compatibility NAP-SHELL `domains`/`protocols` shape alongside
1172
- * the flat `naps` array and the `sandbox` array. Current availability is
1173
- * injected `window.napplet.<domain>` presence; this payload remains for older
1174
- * consumers that still inspect shell.init capabilities.
1175
- *
1176
- * ### naps array (NAP vocabulary)
1177
- * Bare domain `inc` + `inc:NAP-01..inc:NAP-06`.
1178
- * Conditional: `relay`+`outbox` prepended when hooks.relayPool;
1179
- * `upload` appended when hooks.upload;
1180
- * `intent` appended when hooks.intent.isAvailable();
1181
- * `link` appended when hooks.link.isAvailable();
1182
- * `common` appended when hooks.common.isAvailable().
1183
- *
1184
- * The sandbox array is retained as an always-empty compatibility field. Current
1185
- * NIP-5D defines only the `allow-scripts` baseline and does not make additional
1186
- * browser sandbox tokens a napplet capability surface.
1187
- *
1188
- * ### domains array + protocols map (compatibility NAP-SHELL)
1189
- * The structured shape older shell capability consumers read:
1190
- *
1191
- * - `domains` — bare NAP domain names (the `naps` set MINUS the `inc:NAP-NN`
1192
- * protocol strings) with the same conditional entries (relay/outbox under
1193
- * `hooks.relayPool`, upload/intent/link/common under their hooks).
1194
- * - `protocols` — `{ inc: ['NAP-01'..'NAP-06'] }`, derived from
1195
- * `NAP_INC_PROTOCOLS` by stripping the `inc:` prefix.
1196
- *
1197
- * Emitted as a superset alongside `naps`/`sandbox` for back-compat.
1198
- *
1199
- * @param hooks - The ShellAdapter provided by the host app
1200
- * @returns ShellCapabilities with domains/protocols (compatibility shape), naps
1201
- * (NAP vocab), and an empty sandbox compatibility array
837
+ * Build the shell's immutable live capability snapshot from adapter wiring.
838
+ *
839
+ * @param hooks - The ShellAdapter provided by the host app.
840
+ * @returns Domain-only ShellCapabilities for the current live wiring.
1202
841
  * @example
1203
842
  * ```ts
1204
843
  * const caps = buildShellCapabilities(hooks);
1205
- * // caps.domains => ['relay','outbox','identity','storage','inc','theme','keys','media','notify','config','resource','cvm']
1206
- * // (relay + outbox present when hooks.relayPool is provided; 'upload'/'intent'
1207
- * // appended under their hooks)
1208
- * // caps.protocols => { inc: ['NAP-01','NAP-02','NAP-03','NAP-04','NAP-05','NAP-06'] }
1209
- * // caps.naps => ['relay','outbox','identity','storage','inc','theme','keys','media','notify','config','resource','cvm',
1210
- * // 'inc:NAP-01','inc:NAP-02','inc:NAP-03','inc:NAP-04','inc:NAP-05','inc:NAP-06']
1211
- * // (relay + outbox present when hooks.relayPool is provided; 'upload'
1212
- * // appended when hooks.upload is provided; 'intent' appended when
1213
- * // hooks.intent.isAvailable() is true)
1214
- * // caps.sandbox => [] // retained for compatibility; not a NAP capability surface
844
+ * // caps.domains => ['relay', 'identity', 'storage', 'inc', 'theme', 'keys', 'media', 'notify']
1215
845
  * ```
1216
846
  */
1217
847
  declare function buildShellCapabilities(hooks: ShellAdapter): ShellCapabilities;
848
+ /**
849
+ * Resolve a trusted creation identity's immutable NAP-SHELL environment.
850
+ *
851
+ * This host-adapter API is intentionally not part of `window.napplet`: it
852
+ * bounds host policy to current runtime wiring before `shell.init` crosses into
853
+ * an untrusted iframe.
854
+ *
855
+ * @param hooks - Shell host wiring and optional per-identity grant policy.
856
+ * @param identity - The source's creation-time identity.
857
+ * @returns A fresh immutable environment whose entries are exact live subsets.
858
+ */
859
+ declare function resolveShellEnvironment(hooks: ShellAdapter, identity: OriginIdentity): ShellEnvironment;
1218
860
 
1219
861
  /**
1220
862
  * identity-proxy.ts — Shell-side per-domain proxy for identity.* envelopes.
1221
863
  *
1222
864
  * Establishes the canonical proxy shape for @kehto/shell (Plan 12-11): each
1223
865
  * per-domain proxy exposes a `dispatch` method that delegates napplet→shell
1224
- * requests to the runtime and an `emit` method that posts shell→napplet
1225
- * push envelopes through the origin registry.
866
+ * requests to the runtime.
1226
867
  *
1227
868
  * By default, `createShellBridge()` does NOT compose this proxy into its
1228
869
  * dispatch path — the runtime already owns identity.* dispatch per Plan
@@ -1231,10 +872,9 @@ declare function buildShellCapabilities(hooks: ShellAdapter): ShellCapabilities;
1231
872
  * augment identity dispatch (e.g. custom logging, sandboxed rewrites, test
1232
873
  * doubles).
1233
874
  *
1234
- * The canonical proxy shape — dispatch + emit — is mirrored verbatim by
1235
- * theme-proxy, keys-proxy, media-proxy, and notify-proxy. Storage today is
1236
- * served by `@kehto/runtime` state-handler directly; a storage-proxy using
1237
- * this shape can be added later if host apps need a composition seam.
875
+ * Identity changes are deliberately not emitted through this proxy. Hosts
876
+ * must use `ShellBridge.publishIdentityChanged()`, which enforces the live
877
+ * session, granted-domain, and current recipient-capability checks.
1238
878
  */
1239
879
 
1240
880
  /**
@@ -1267,9 +907,8 @@ interface IdentityProxyDeps {
1267
907
  /**
1268
908
  * Per-domain proxy for `identity.*` envelopes.
1269
909
  *
1270
- * The canonical proxy shape: `dispatch` routes napplet→shell requests into
1271
- * the runtime; `emit` pushes shell→napplet envelopes through the iframe's
1272
- * Window.
910
+ * `dispatch` routes napplet→shell requests into the runtime. The deprecated
911
+ * `emit` member remains only as a fail-closed compatibility trap.
1273
912
  */
1274
913
  interface IdentityProxy {
1275
914
  /**
@@ -1283,13 +922,10 @@ interface IdentityProxy {
1283
922
  */
1284
923
  dispatch(windowId: string, envelope: NappletMessage): void;
1285
924
  /**
1286
- * Push a shell-initiated identity-domain envelope into a napplet iframe.
1287
- *
1288
- * No-op when the originRegistry cannot resolve the windowId (unknown or
1289
- * unregistered napplet). Never throws.
925
+ * Direct identity delivery is prohibited.
1290
926
  *
1291
- * @param windowId - The target napplet's windowId
1292
- * @param envelope - The NIP-5D NappletMessage envelope to deliver
927
+ * @deprecated Use `ShellBridge.publishIdentityChanged()` so delivery is
928
+ * filtered by live session, granted domain, and current ACL.
1293
929
  */
1294
930
  emit(windowId: string, envelope: NappletMessage): void;
1295
931
  }
@@ -1326,12 +962,9 @@ declare function createIdentityProxy(deps: IdentityProxyDeps): IdentityProxy;
1326
962
  * API that emits `theme.changed` push envelopes to registered napplets;
1327
963
  * this proxy is the canonical seam those pieces plug into.
1328
964
  *
1329
- * Shape mirrors identity-proxy (Plan 12-11):
1330
- *
1331
- * - `dispatch(windowId, envelope)` routes napplet→shell `theme.get` into
1332
- * the runtime (where Phase 13's theme-service will answer).
1333
- * - `emit(windowId, envelope)` posts shell→napplet `theme.changed`
1334
- * envelopes through the origin registry.
965
+ * `dispatch(windowId, envelope)` routes napplet→shell `theme.get` into the
966
+ * runtime. Theme changes must use `ShellBridge.publishTheme()` so the host
967
+ * projection enforces live-session, granted-domain, and current-ACL checks.
1335
968
  *
1336
969
  * By default `createShellBridge()` does NOT compose this proxy into its
1337
970
  * dispatch path — the runtime owns theme.* dispatch. This module is an
@@ -1358,8 +991,8 @@ interface ThemeProxyDeps {
1358
991
  /**
1359
992
  * Per-domain proxy for `theme.*` envelopes.
1360
993
  *
1361
- * Shape: `dispatch` routes napplet→shell requests into the runtime; `emit`
1362
- * pushes shell→napplet envelopes through the iframe's Window.
994
+ * `dispatch` routes napplet→shell requests into the runtime. The deprecated
995
+ * `emit` member remains only as a fail-closed compatibility trap.
1363
996
  */
1364
997
  interface ThemeProxy {
1365
998
  /**
@@ -1371,14 +1004,10 @@ interface ThemeProxy {
1371
1004
  */
1372
1005
  dispatch(windowId: string, envelope: NappletMessage): void;
1373
1006
  /**
1374
- * Push a shell-initiated theme-domain envelope (e.g. `theme.changed`)
1375
- * into a napplet iframe.
1007
+ * Direct theme delivery is prohibited.
1376
1008
  *
1377
- * No-op when the originRegistry cannot resolve the windowId (unknown or
1378
- * unregistered napplet). Never throws.
1379
- *
1380
- * @param windowId - The target napplet's windowId
1381
- * @param envelope - The NIP-5D NappletMessage envelope to deliver
1009
+ * @deprecated Use `ShellBridge.publishTheme()` so delivery is filtered by
1010
+ * live session, granted domain, and current ACL.
1382
1011
  */
1383
1012
  emit(windowId: string, envelope: NappletMessage): void;
1384
1013
  }
@@ -1389,18 +1018,13 @@ interface ThemeProxy {
1389
1018
  * @returns A {@link ThemeProxy} ready to route theme.* envelopes
1390
1019
  * @example
1391
1020
  * ```ts
1392
- * import { createThemeProxy, originRegistry, createShellBridge } from '@kehto/shell';
1021
+ * import { createThemeProxy, originRegistry } from '@kehto/shell';
1393
1022
  *
1394
- * const bridge = createShellBridge(hooks);
1395
1023
  * const themeProxy = createThemeProxy({
1396
- * runtime: bridge.runtime,
1024
+ * runtime,
1397
1025
  * originRegistry,
1398
1026
  * });
1399
- *
1400
- * // Phase 13: broadcast theme.changed to every registered napplet
1401
- * for (const entry of bridge.runtime.sessionRegistry.getAllEntries()) {
1402
- * themeProxy.emit(entry.windowId, { type: 'theme.changed', theme: newTheme });
1403
- * }
1027
+ * themeProxy.dispatch(windowId, { type: 'theme.get', id: requestId });
1404
1028
  * ```
1405
1029
  */
1406
1030
  declare function createThemeProxy(deps: ThemeProxyDeps): ThemeProxy;
@@ -1408,11 +1032,11 @@ declare function createThemeProxy(deps: ThemeProxyDeps): ThemeProxy;
1408
1032
  /**
1409
1033
  * keys-proxy.ts — Shell-side per-domain proxy for keys.* envelopes.
1410
1034
  *
1411
- * Per Plan 12-05, the runtime already dispatches `keys.*` (forward,
1412
- * registerAction, unregisterAction) to the keys-service. This proxy is the
1413
- * shell-side composition point for host apps that want to observe or
1414
- * inject keys envelopes — it pairs with `keys-forwarder.ts` (Plan 12-11)
1415
- * which covers the shell→napplet `keys.forward` push path.
1035
+ * The runtime already dispatches napplet-originated `keys.*` (forward,
1036
+ * registerAction, unregisterAction) to the keys service. This proxy is the
1037
+ * shell-side composition point for host apps that want to observe requests or
1038
+ * inject shell-originated keys envelopes such as `keys.action` and
1039
+ * `keys.bindings`.
1416
1040
  *
1417
1041
  * Shape mirrors identity-proxy (Plan 12-11):
1418
1042
  *
@@ -1463,10 +1087,6 @@ interface KeysProxy {
1463
1087
  * Push a shell-initiated keys-domain envelope (e.g. `keys.action`,
1464
1088
  * `keys.bindings`) into a napplet iframe.
1465
1089
  *
1466
- * Paired with `keys-forwarder.ts`: the forwarder targets the DOM
1467
- * `keydown` → `keys.forward` path; this `emit` covers the complementary
1468
- * host-initiated pushes (binding updates, action triggers).
1469
- *
1470
1090
  * No-op when the originRegistry cannot resolve the windowId (unknown or
1471
1091
  * unregistered napplet). Never throws.
1472
1092
  *
@@ -1672,101 +1292,6 @@ interface NotifyProxy {
1672
1292
  */
1673
1293
  declare function createNotifyProxy(deps: NotifyProxyDeps): NotifyProxy;
1674
1294
 
1675
- /**
1676
- * keys-forwarder.ts — Shell-side host keydown listener that forwards events
1677
- * to registered napplets as `keys.forward` envelopes (Plan 12-11, NAP-05
1678
- * shell-side half).
1679
- *
1680
- * Per `@napplet/nap/keys`, `keys.forward` is fire-and-forget (no result
1681
- * envelope, no correlation id). Field names follow the nap convention:
1682
- * `{ ctrl, alt, shift, meta }` — NOT the DOM-style `ctrlKey`/etc.
1683
- *
1684
- * Capability gate: only forwards to napplets whose ACL grants the
1685
- * `keys:forward` capability (per Plan 12-10 `resolveCapabilitiesNap` 'keys'
1686
- * case). The caller wires the cap-lookup via the `hasKeysForwardCap` dep so
1687
- * this module stays free of any direct ACL-store dependency.
1688
- *
1689
- * Lifecycle: `createShellBridge()` attaches a forwarder on construction and
1690
- * detaches it inside `bridge.destroy()`.
1691
- */
1692
-
1693
- /**
1694
- * Minimal origin-registry contract used by the forwarder — matches the
1695
- * `@kehto/shell` singleton `originRegistry` and test doubles alike.
1696
- */
1697
- interface KeysForwarderOriginRegistry {
1698
- /** Resolve a registered napplet windowId to its iframe Window, or null. */
1699
- getIframeWindow(windowId: string): Window | null;
1700
- }
1701
- /**
1702
- * Minimal session-registry contract used by the forwarder — matches the
1703
- * `@kehto/shell` singleton `sessionRegistry` and test doubles alike.
1704
- */
1705
- interface KeysForwarderSessionRegistry {
1706
- /** Return every registered napplet session entry. */
1707
- getAllEntries(): SessionEntry[];
1708
- }
1709
- /**
1710
- * Dependencies for `createKeysForwarder`.
1711
- *
1712
- * @example
1713
- * ```ts
1714
- * const forwarder = createKeysForwarder({
1715
- * originRegistry,
1716
- * sessionRegistry,
1717
- * hasKeysForwardCap: (pubkey) =>
1718
- * aclStore.getAclEntry(pubkey)?.capabilities.includes('keys:forward') ?? false,
1719
- * });
1720
- * ```
1721
- */
1722
- interface KeysForwarderDeps {
1723
- /** Origin registry for resolving windowId → iframe Window. */
1724
- originRegistry: KeysForwarderOriginRegistry;
1725
- /** Session registry for enumerating napplets to forward to. */
1726
- sessionRegistry: KeysForwarderSessionRegistry;
1727
- /**
1728
- * Capability check: returns true when the given napplet pubkey holds the
1729
- * `keys:forward` capability. Called per keydown per registered napplet —
1730
- * keep the implementation cheap.
1731
- */
1732
- hasKeysForwardCap(pubkey: string): boolean;
1733
- /**
1734
- * Optional EventTarget to attach to. Defaults to the global `window` when
1735
- * running in a DOM environment. Passing a fresh `new EventTarget()` is
1736
- * useful for unit tests.
1737
- */
1738
- target?: EventTarget;
1739
- }
1740
- /**
1741
- * Handle returned by `createKeysForwarder`. Call `destroy()` to remove the
1742
- * keydown listener (e.g. inside `bridge.destroy()`).
1743
- */
1744
- interface KeysForwarder {
1745
- /** Detach the keydown listener and release resources. */
1746
- destroy(): void;
1747
- }
1748
- /**
1749
- * Create a host-keydown forwarder that posts `keys.forward` envelopes to
1750
- * every registered napplet granted the `keys:forward` capability.
1751
- *
1752
- * @param deps - Origin registry, session registry, cap checker, optional target
1753
- * @returns A {@link KeysForwarder} — call `destroy()` to detach
1754
- * @example
1755
- * ```ts
1756
- * // Inside createShellBridge():
1757
- * const keysForwarder = createKeysForwarder({
1758
- * originRegistry,
1759
- * sessionRegistry,
1760
- * hasKeysForwardCap: (pubkey) =>
1761
- * aclStore.getAclEntry(pubkey)?.capabilities.includes('keys:forward') ?? false,
1762
- * });
1763
- * // ...
1764
- * // Inside bridge.destroy():
1765
- * keysForwarder.destroy();
1766
- * ```
1767
- */
1768
- declare function createKeysForwarder(deps: KeysForwarderDeps): KeysForwarder;
1769
-
1770
1295
  /**
1771
1296
  * @file internal-resource.ts
1772
1297
  *
@@ -1938,4 +1463,4 @@ type ResourceInbound = ResourceInfoRequest | ResourceBytesRequest | ResourceByte
1938
1463
  */
1939
1464
  type ResourceOutbound = ResourceInfoResult | ResourceInfoError | ResourceBytesResult | ResourceBytesError | ResourceBytesManyResult | ResourceBytesManyError;
1940
1465
 
1941
- export { type AclCheckEvent, type AclEntry, type AudioSource, type AuthHooks, type BleHooks, type BrowserDeps, type CapabilityHooks, type CommonHooks, type ConfigHooks, type CryptoHooks, type DmHooks, type HotkeyHooks, type IdentityProxy, type IdentityProxyDeps, type IntentHooks, type KeysForwarder, type KeysForwarderDeps, type KeysForwarderOriginRegistry, type KeysForwarderSessionRegistry, type KeysProxy, type KeysProxyDeps, type LinkHooks, type ListsHooks, type ManifestCacheEntry, type MediaProxy, type MediaProxyDeps, type NappletNamespacePreludeOptions, type NotifyProxy, type NotifyProxyDeps, type ProxyOriginRegistry, type RelayConfigHooks, type RelayPoolHooks, type RelayPoolLike, type ResourceBytesError, type ResourceBytesManyError, type ResourceBytesManyItem, type ResourceBytesManyRequest, type ResourceBytesManyResult, type ResourceBytesRequest, type ResourceBytesResult, type ResourceCancelRequest, type ResourceErrorCode, type ResourceInbound, type ResourceInfo, type ResourceInfoError, type ResourceInfoRequest, type ResourceInfoResult, type ResourceOutbound, type ResourceRequestId, type SerialHooks, type ShellAdapter, type ShellBridge, type ShellCapabilities, type ThemeProxy, type ThemeProxyDeps, type UnroutedMessageInfo, type UploadBackendLike, type UploadHooks, type WebrtcHooks, type WindowManagerHooks, type WorkerRelayHooks, type WorkerRelayLike, adaptHooks, audioManager, buildShellCapabilities, createIdentityProxy, createKeysForwarder, createKeysProxy, createMediaProxy, createNotifyProxy, createShellBridge, createThemeProxy, injectNappletNamespacePrelude, manifestCache, nappKeyRegistry, originRegistry, renderNappletNamespacePrelude, sessionRegistry };
1466
+ export { type AclCheckEvent, type AclEntry, type AclStore, type AudioManager, type AudioSource, type AuthHooks, type BleHooks, type BrowserDeps, type CapabilityHooks, type CommonHooks, type ConfigHooks, type CryptoHooks, type DmHooks, type HotkeyHooks, type IdentityProxy, type IdentityProxyDeps, type IntentHooks, type KeysProxy, type KeysProxyDeps, type LinkHooks, type ListsHooks, type ManifestCache, type ManifestCacheEntry, type MediaProxy, type MediaProxyDeps, type NappletNamespacePreludeOptions, type NotifyProxy, type NotifyProxyDeps, type OriginIdentity, type OriginRegistry, type ProxyOriginRegistry, type RelayConfigHooks, type RelayPoolHooks, type RelayPoolLike, type ResourceBytesError, type ResourceBytesManyError, type ResourceBytesManyItem, type ResourceBytesManyRequest, type ResourceBytesManyResult, type ResourceBytesRequest, type ResourceBytesResult, type ResourceCancelRequest, type ResourceErrorCode, type ResourceInbound, type ResourceInfo, type ResourceInfoError, type ResourceInfoRequest, type ResourceInfoResult, type ResourceOutbound, type ResourceRequestId, type SerialHooks, type SessionRegistry, type ShellAdapter, type ShellBridge, type ShellCapabilities, type ShellEnvironment, type ThemeProxy, type ThemeProxyDeps, type UnroutedMessageInfo, type UploadBackendLike, type UploadHooks, type WebrtcHooks, type WindowManagerHooks, type WorkerRelayHooks, type WorkerRelayLike, adaptHooks, audioManager, buildShellCapabilities, createIdentityProxy, createKeysProxy, createMediaProxy, createNotifyProxy, createShellBridge, createThemeProxy, injectNappletNamespacePrelude, manifestCache, nappKeyRegistry, originRegistry, renderNappletNamespacePrelude, resolveShellEnvironment, sessionRegistry };