@kehto/runtime 0.8.0 → 0.11.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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Browser-agnostic protocol engine for the napplet protocol.
4
4
 
5
5
  > **Alpha status:** Kehto is an early runtime implementation for a draft NIP-5D
6
- > protocol. NUB contracts and runtime APIs are not final; treat this package as
6
+ > protocol. NAP contracts and runtime APIs are not final; treat this package as
7
7
  > current implementation guidance, not as a stable protocol guarantee.
8
8
 
9
9
  ## Install
@@ -14,7 +14,7 @@ pnpm add @kehto/runtime
14
14
 
15
15
  ## Overview
16
16
 
17
- `@kehto/runtime` is Kehto's NIP-5D protocol engine. It owns every incoming napplet message, gates it through the ACL enforcement layer, routes it to the correct NUB handler, and emits the corresponding reply envelope.
17
+ `@kehto/runtime` is Kehto's NIP-5D protocol engine. It owns every incoming napplet message, gates it through the ACL enforcement layer, routes it to the correct NAP handler, and emits the corresponding reply envelope.
18
18
 
19
19
  The runtime is built around the current draft dispatch contract from `@napplet/core` — `createDispatch()` + `registerNub()` — so routing is declarative, not a hand-rolled switch. It covers the NIP-5D domains currently supported by Kehto:
20
20
 
package/dist/index.d.ts CHANGED
@@ -2,9 +2,140 @@ import { NappletMessage, NostrEvent, EventTemplate, NostrFilter } from '@napplet
2
2
  export { NappletMessage } from '@napplet/core';
3
3
  import { Capability } from '@kehto/acl/capabilities';
4
4
  export { ALL_CAPABILITIES, Capability } from '@kehto/acl/capabilities';
5
+ import { Decision, Action, Observation, EvaluateResult, NappletPolicy, RateLimit, ContentMatcher, FirewallConfig } from '@kehto/firewall';
5
6
  import { NubMessage } from '@kehto/acl';
6
7
  export { NubMessage, resolveCapabilitiesNub } from '@kehto/acl';
7
8
 
9
+ /**
10
+ * Runtime persistence + cache data types.
11
+ *
12
+ * Host-implemented persistence adapters (ACL, firewall, manifest, shell-secret,
13
+ * GUID, napplet state) plus the cached-entry shapes they store. Extracted from
14
+ * types.ts to keep that file under the size budget; re-exported from types.ts so
15
+ * the public @kehto/runtime API is unchanged.
16
+ */
17
+
18
+ /**
19
+ * ACL persistence — runtime calls these to save/load ACL state.
20
+ * Implementor decides storage backend (localStorage, file, DB, etc.).
21
+ */
22
+ interface AclPersistence {
23
+ persist(data: string): void;
24
+ load(): string | null;
25
+ }
26
+ /**
27
+ * Firewall persistence — runtime calls these to save/load firewall config.
28
+ * Implementor decides storage backend (localStorage, file, DB, etc.).
29
+ * Only the firewall config is persisted; ephemeral counters are never stored.
30
+ *
31
+ * @param persist - Store serialized config data; called after each policy mutation.
32
+ * @param load - Retrieve previously stored config, or null on first boot.
33
+ */
34
+ interface FirewallPersistence {
35
+ persist(data: string): void;
36
+ load(): string | null;
37
+ }
38
+ /**
39
+ * Event emitted on every firewall evaluation that results in an audit-level
40
+ * decision (flag, block, or prompt).
41
+ *
42
+ * @param windowId - The napplet window that sent the message.
43
+ * @param napplet - The napplet dTag (version-agnostic identity key).
44
+ * @param opClass - Operation class string (e.g. 'relay:write', 'outbox:publish').
45
+ * @param decision - Primary disposition: 'pass', 'reject', or 'prompt'.
46
+ * @param action - The matched rule's exceed-action: 'flag', 'block', or 'ignore'.
47
+ * @param ruleId - Identifier of the rule that made the decision.
48
+ * @param reason - Human-readable reason string for logging/audit.
49
+ * @param message - The triggering NappletMessage, if available.
50
+ */
51
+ interface FirewallEvent {
52
+ /** The napplet window that sent the message. */
53
+ windowId: string;
54
+ /** The napplet dTag (version-agnostic identity key). */
55
+ napplet: string;
56
+ /** Operation class string (e.g. 'relay:write', 'outbox:publish', 'intent:invoke'). */
57
+ opClass: string;
58
+ /** Primary disposition for the caller. */
59
+ decision: Decision;
60
+ /** The matched rule's exceed-action. */
61
+ action: Action;
62
+ /** Identifier of the rule that made the decision (e.g. 'rate:default', 'burst', 'policy:deny'). */
63
+ ruleId: string;
64
+ /** Human-readable reason string for logging and audit. */
65
+ reason: string;
66
+ /** The triggering message, if available. */
67
+ message?: NappletMessage;
68
+ }
69
+ /**
70
+ * Manifest persistence — runtime calls these to save/load manifest cache.
71
+ * Implementor decides storage backend.
72
+ */
73
+ interface ManifestPersistence {
74
+ persist(data: string): void;
75
+ load(): string | null;
76
+ }
77
+ /**
78
+ * Shell secret persistence — runtime calls these to save/load the per-shell secret
79
+ * used for deterministic keypair derivation. The secret is a 32-byte random value
80
+ * generated once on first use.
81
+ */
82
+ interface ShellSecretPersistence {
83
+ /** Get the stored shell secret, or null if not yet generated. */
84
+ get(): Uint8Array | null;
85
+ /** Store the shell secret. */
86
+ set(secret: Uint8Array): void;
87
+ }
88
+ /**
89
+ * GUID persistence — runtime calls these to save/load per-iframe instance GUIDs.
90
+ * GUIDs survive page reloads: same iframe slot gets the same GUID.
91
+ * Implementor decides storage backend and keying strategy
92
+ * (e.g., localStorage keyed by iframe src or slot index).
93
+ */
94
+ interface GuidPersistence {
95
+ /** Get a stored GUID for a window identifier, or null if none exists. */
96
+ get(windowId: string): string | null;
97
+ /** Store a GUID for a window identifier. */
98
+ set(windowId: string, guid: string): void;
99
+ /** Remove a stored GUID. */
100
+ remove(windowId: string): void;
101
+ }
102
+ /**
103
+ * State storage — runtime calls these for napplet-scoped key-value storage.
104
+ * All keys are pre-scoped by the runtime (dTag:hash:userKey).
105
+ */
106
+ interface StatePersistence {
107
+ get(scopedKey: string): string | null;
108
+ set(scopedKey: string, value: string): boolean;
109
+ remove(scopedKey: string): void;
110
+ clear(prefix: string): void;
111
+ keys(prefix: string): string[];
112
+ calculateBytes(prefix: string, excludeKey?: string): number;
113
+ }
114
+ /**
115
+ * A cached manifest entry for a verified napplet build.
116
+ * Optionally stores the napplet's declared service requirements from its manifest.
117
+ */
118
+ interface ManifestCacheEntry {
119
+ pubkey: string;
120
+ dTag: string;
121
+ aggregateHash: string;
122
+ verifiedAt: number;
123
+ /** Service names declared in the napplet's manifest requires tags. */
124
+ requires?: string[];
125
+ }
126
+ /**
127
+ * Cached verification result for an aggregate hash.
128
+ * Keyed by manifest event ID — immutable Nostr events mean same ID = same content.
129
+ */
130
+ interface VerificationCacheEntry {
131
+ /** The computed aggregate hash. */
132
+ aggregateHash: string;
133
+ /** Whether the computed hash matched the declared hash. */
134
+ valid: boolean;
135
+ /** Timestamp when verification was performed. */
136
+ verifiedAt: number;
137
+ }
138
+
8
139
  /**
9
140
  * types.ts — Runtime adapter interfaces and supporting types.
10
141
  *
@@ -15,7 +146,7 @@ export { NubMessage, resolveCapabilitiesNub } from '@kehto/acl';
15
146
  /**
16
147
  * A napplet class identifier. `null` is the permissive default (no class).
17
148
  * provisional — mirrors packages/shell/src/types/internal-class.ts::NappletClass;
18
- * converges on @napplet/nub/class@^0.3.0 publish. Runtime MUST NOT import
149
+ * converges on @napplet/nap/class@^0.3.0 publish. Runtime MUST NOT import
19
150
  * from shell (module-boundary), so this duplicate lives here.
20
151
  */
21
152
  type NappletClass = string | null;
@@ -151,59 +282,7 @@ interface HotkeyAdapter {
151
282
  metaKey: boolean;
152
283
  }): void;
153
284
  }
154
- /**
155
- * ACL persistence — runtime calls these to save/load ACL state.
156
- * Implementor decides storage backend (localStorage, file, DB, etc.).
157
- */
158
- interface AclPersistence {
159
- persist(data: string): void;
160
- load(): string | null;
161
- }
162
- /**
163
- * Manifest persistence — runtime calls these to save/load manifest cache.
164
- * Implementor decides storage backend.
165
- */
166
- interface ManifestPersistence {
167
- persist(data: string): void;
168
- load(): string | null;
169
- }
170
- /**
171
- * Shell secret persistence — runtime calls these to save/load the per-shell secret
172
- * used for deterministic keypair derivation. The secret is a 32-byte random value
173
- * generated once on first use.
174
- */
175
- interface ShellSecretPersistence {
176
- /** Get the stored shell secret, or null if not yet generated. */
177
- get(): Uint8Array | null;
178
- /** Store the shell secret. */
179
- set(secret: Uint8Array): void;
180
- }
181
- /**
182
- * GUID persistence — runtime calls these to save/load per-iframe instance GUIDs.
183
- * GUIDs survive page reloads: same iframe slot gets the same GUID.
184
- * Implementor decides storage backend and keying strategy
185
- * (e.g., localStorage keyed by iframe src or slot index).
186
- */
187
- interface GuidPersistence {
188
- /** Get a stored GUID for a window identifier, or null if none exists. */
189
- get(windowId: string): string | null;
190
- /** Store a GUID for a window identifier. */
191
- set(windowId: string, guid: string): void;
192
- /** Remove a stored GUID. */
193
- remove(windowId: string): void;
194
- }
195
- /**
196
- * State storage — runtime calls these for napplet-scoped key-value storage.
197
- * All keys are pre-scoped by the runtime (dTag:hash:userKey).
198
- */
199
- interface StatePersistence {
200
- get(scopedKey: string): string | null;
201
- set(scopedKey: string, value: string): boolean;
202
- remove(scopedKey: string): void;
203
- clear(prefix: string): void;
204
- keys(prefix: string): string[];
205
- calculateBytes(prefix: string, excludeKey?: string): number;
206
- }
285
+
207
286
  /** Crypto adapter — event verification. */
208
287
  interface CryptoAdapter {
209
288
  /** Verify a nostr event's Schnorr signature. */
@@ -260,8 +339,8 @@ interface DmAdapter {
260
339
  }>;
261
340
  }
262
341
  /**
263
- * A pending consent request — either for a destructive signing kind
264
- * or for undeclared service usage.
342
+ * A pending consent request — for a destructive signing kind, undeclared
343
+ * service usage, or a firewall policy prompt.
265
344
  *
266
345
  * When type is 'destructive-signing' (or omitted for backwards compat):
267
346
  * Raised when a signer request arrives for kinds 0, 3, 5, 10002.
@@ -270,6 +349,15 @@ interface DmAdapter {
270
349
  * Raised when a napplet uses a service it did not declare in its manifest.
271
350
  * The serviceName field identifies which service was used without declaration.
272
351
  *
352
+ * When type is 'firewall-policy':
353
+ * Raised when the firewall evaluation returns a 'prompt' decision (ask policy).
354
+ * No Nostr event is associated — `event` is omitted. The `napplet` field
355
+ * carries the dTag the user's allow/deny choice will be remembered against.
356
+ * The triggering message is rejected now; if the user allows, subsequent
357
+ * messages from this napplet will pass without re-prompting (choice persisted
358
+ * as a per-napplet policy via setPolicy). Phase 82 changeset note: `event`
359
+ * was relaxed from required to optional to accommodate this variant (A3).
360
+ *
273
361
  * @example
274
362
  * ```ts
275
363
  * // Destructive signing consent (existing behavior)
@@ -279,24 +367,41 @@ interface DmAdapter {
279
367
  * resolve: (allowed) => { ... },
280
368
  * };
281
369
  *
282
- * // Undeclared service consent (new)
370
+ * // Undeclared service consent
283
371
  * const serviceConsent: ConsentRequest = {
284
372
  * type: 'undeclared-service',
285
373
  * windowId: 'win-1', pubkey: 'abc...', event: serviceEvent,
286
374
  * serviceName: 'audio',
287
375
  * resolve: (allowed) => { ... },
288
376
  * };
377
+ *
378
+ * // Firewall policy prompt (no Nostr event)
379
+ * const firewallConsent: ConsentRequest = {
380
+ * type: 'firewall-policy',
381
+ * windowId: 'win-1', pubkey: 'abc...', napplet: 'chat',
382
+ * resolve: (allowed) => { ... },
383
+ * };
289
384
  * ```
290
385
  */
291
386
  interface ConsentRequest {
292
387
  /** Consent type discriminator. Defaults to 'destructive-signing' if omitted. */
293
- type?: 'destructive-signing' | 'undeclared-service';
388
+ type?: 'destructive-signing' | 'undeclared-service' | 'firewall-policy';
294
389
  windowId: string;
295
390
  pubkey: string;
296
- event: NostrEvent;
391
+ /**
392
+ * The Nostr event associated with this consent request.
393
+ * Optional for 'firewall-policy' consent — a firewall prompt has no real Nostr event.
394
+ * Present for 'destructive-signing' and 'undeclared-service' requests.
395
+ */
396
+ event?: NostrEvent;
297
397
  resolve: (allowed: boolean) => void;
298
398
  /** Service name for undeclared-service consent. Only present when type is 'undeclared-service'. */
299
399
  serviceName?: string;
400
+ /**
401
+ * The napplet dTag the firewall policy choice is remembered against.
402
+ * Only present when type is 'firewall-policy'.
403
+ */
404
+ napplet?: string;
300
405
  }
301
406
  /** Consent handler callback type. */
302
407
  type ConsentHandler = (request: ConsentRequest) => void;
@@ -418,30 +523,6 @@ interface PendingUpdate {
418
523
  }
419
524
  /** Callback invoked when a pending update is set or cleared. */
420
525
  type PendingUpdateNotifier = (windowId: string) => void;
421
- /**
422
- * A cached manifest entry for a verified napplet build.
423
- * Optionally stores the napplet's declared service requirements from its manifest.
424
- */
425
- interface ManifestCacheEntry {
426
- pubkey: string;
427
- dTag: string;
428
- aggregateHash: string;
429
- verifiedAt: number;
430
- /** Service names declared in the napplet's manifest requires tags. */
431
- requires?: string[];
432
- }
433
- /**
434
- * Cached verification result for an aggregate hash.
435
- * Keyed by manifest event ID — immutable Nostr events mean same ID = same content.
436
- */
437
- interface VerificationCacheEntry {
438
- /** The computed aggregate hash. */
439
- aggregateHash: string;
440
- /** Whether the computed hash matched the declared hash. */
441
- valid: boolean;
442
- /** Timestamp when verification was performed. */
443
- verifiedAt: number;
444
- }
445
526
  /** External ACL entry — used in shell commands (shell:acl-get etc.). */
446
527
  interface AclEntryExternal {
447
528
  pubkey: string;
@@ -610,6 +691,30 @@ interface RuntimeAdapter {
610
691
  onHashMismatch?: (dTag: string, claimed: string, computed: string) => void;
611
692
  /** Called on every ACL enforcement check (audit). */
612
693
  onAclCheck?: (event: AclCheckEvent) => void;
694
+ /**
695
+ * Firewall config persistence (save/load firewall config).
696
+ * When absent, firewall config is in-memory only and resets on reload.
697
+ * Only the config is persisted; ephemeral counters are never stored.
698
+ */
699
+ firewallPersistence?: FirewallPersistence;
700
+ /**
701
+ * Called on every firewall evaluation that results in an audit-level decision
702
+ * (flag, block, or prompt). When absent, firewall decisions are not audited.
703
+ */
704
+ onFirewallEvent?: (event: FirewallEvent) => void;
705
+ /**
706
+ * Returns the current focus state for a napplet window.
707
+ * When absent, defaults to `{ focused: true }` — a host without a window
708
+ * manager treats everything as focused, so focus never tightens rate budgets.
709
+ * Focus alone never hard-blocks; it only scales token refill rates.
710
+ *
711
+ * @param windowId - The napplet window to query focus state for.
712
+ * @returns Current focus state and optional milliseconds since last focus gain.
713
+ */
714
+ getFocusContext?: (windowId: string) => {
715
+ focused: boolean;
716
+ msSinceFocusGain?: number;
717
+ };
613
718
  /** Called when a pending napp update is set or cleared. */
614
719
  onPendingUpdate?: PendingUpdateNotifier;
615
720
  /**
@@ -876,6 +981,102 @@ interface AclStateContainer {
876
981
  */
877
982
  declare function createAclState(persistence: AclPersistence, defaultPolicy?: 'permissive' | 'restrictive'): AclStateContainer;
878
983
 
984
+ /**
985
+ * firewall-state.ts — Firewall state container with persistence hooks.
986
+ *
987
+ * Wraps @kehto/firewall's pure functions with persistence via
988
+ * FirewallPersistence. No localStorage or DOM references.
989
+ *
990
+ * Two independent `let`-bound cells:
991
+ * - `config` — immutable FirewallConfig; persisted on each mutation.
992
+ * - `counters` — ephemeral FirewallState (token-buckets + burst counters);
993
+ * in-memory only, reset on reload (RUNTIME-03).
994
+ *
995
+ * CRITICAL: `evaluate` reassigns `counters = result.newState` on every call.
996
+ * Without this, token buckets never advance and flood events never escalate
997
+ * from 'flag' to 'block'.
998
+ */
999
+
1000
+ /**
1001
+ * Stateful firewall container — wraps @kehto/firewall's pure functions
1002
+ * with persistence and a convenient imperative API.
1003
+ *
1004
+ * Mirrors AclStateContainer from acl-state.ts in structure and naming.
1005
+ *
1006
+ * @example
1007
+ * ```ts
1008
+ * const firewall = createFirewallState(persistence);
1009
+ * firewall.load();
1010
+ * const result = firewall.evaluate({ napplet: 'chat', opClass: 'relay:write', focused: true, now: Date.now() });
1011
+ * ```
1012
+ */
1013
+ interface FirewallStateContainer {
1014
+ /**
1015
+ * Evaluate an observation against the current firewall config and counters.
1016
+ * CRITICAL: advances the in-memory counter state on each call.
1017
+ *
1018
+ * @param observation - Normalized observation extracted from the napplet message envelope.
1019
+ * @returns The full EvaluateResult (decision, action, ruleId, reason, newState).
1020
+ */
1021
+ evaluate(observation: Observation): EvaluateResult;
1022
+ /**
1023
+ * Set a per-napplet policy override (allow / deny / ask).
1024
+ *
1025
+ * @param napplet - The napplet dTag (version-agnostic identity key).
1026
+ * @param policy - Hard policy override for this napplet.
1027
+ */
1028
+ setPolicy(napplet: string, policy: NappletPolicy): void;
1029
+ /**
1030
+ * Set a per-(napplet, opClass) token-bucket rate limit.
1031
+ *
1032
+ * @param napplet - The napplet dTag.
1033
+ * @param opClass - The operation class string.
1034
+ * @param limit - The rate limit to apply.
1035
+ */
1036
+ setRateLimit(napplet: string, opClass: string, limit: RateLimit): void;
1037
+ /**
1038
+ * Set a global rate limit applied to all op-classes that have no specific entry.
1039
+ *
1040
+ * @param napplet - The napplet dTag.
1041
+ * @param limit - The global fallback rate limit.
1042
+ */
1043
+ setGlobalRate(napplet: string, limit: RateLimit): void;
1044
+ /**
1045
+ * Add a content matcher to the firewall config.
1046
+ *
1047
+ * @param matcher - The content matcher to append.
1048
+ */
1049
+ addMatcher(matcher: ContentMatcher): void;
1050
+ /** Return the current firewall config. */
1051
+ getConfig(): FirewallConfig;
1052
+ /** Persist the current firewall config via the persistence hook. Best-effort. */
1053
+ persist(): void;
1054
+ /** Load previously persisted firewall config. Counters are NOT restored. */
1055
+ load(): void;
1056
+ /** Reset config to defaultConfig() and counters to createState(), then persist empty. */
1057
+ clear(): void;
1058
+ }
1059
+ /**
1060
+ * Create a firewall state container backed by @kehto/firewall and optionally
1061
+ * persisted via the given persistence hooks.
1062
+ *
1063
+ * When `persistence` is absent (or undefined), firewall config is in-memory
1064
+ * only and resets on container recreation. This is safe for hosts that do not
1065
+ * need durable per-napplet policies.
1066
+ *
1067
+ * @param persistence - Optional storage backend for firewall config.
1068
+ * @returns A FirewallStateContainer instance.
1069
+ *
1070
+ * @example
1071
+ * ```ts
1072
+ * const firewall = createFirewallState(persistence);
1073
+ * firewall.load();
1074
+ * firewall.setPolicy('chat', 'allow');
1075
+ * firewall.persist();
1076
+ * ```
1077
+ */
1078
+ declare function createFirewallState(persistence?: FirewallPersistence): FirewallStateContainer;
1079
+
879
1080
  /**
880
1081
  * manifest-cache.ts — Manifest cache with persistence hooks.
881
1082
  *
@@ -1127,6 +1328,8 @@ interface Runtime {
1127
1328
  readonly sessionRegistry: SessionRegistry;
1128
1329
  /** Access the ACL state container. */
1129
1330
  readonly aclState: AclStateContainer;
1331
+ /** Access the firewall state container (for tests to pre-set policy/rules). */
1332
+ readonly firewallState: FirewallStateContainer;
1130
1333
  /** Access the manifest cache. */
1131
1334
  readonly manifestCache: ManifestCache;
1132
1335
  }
@@ -1149,25 +1352,25 @@ declare function createRuntime(hooks: RuntimeAdapter): Runtime;
1149
1352
  * state-handler.ts — Storage NUB request handler using persistence hooks.
1150
1353
  *
1151
1354
  * Handles napplet storage operations (get, set, remove, keys) via the
1152
- * canonical `@napplet/nub/storage` NIP-5D envelope surface. Delegates
1355
+ * canonical `@napplet/nap/storage` NIP-5D envelope surface. Delegates
1153
1356
  * storage to StatePersistence. No localStorage, no legacy NIP-01 dispatch.
1154
1357
  */
1155
1358
 
1156
1359
  /**
1157
1360
  * Handle a NIP-5D NUB storage message from a napplet.
1158
- * Routes to the canonical four `@napplet/nub/storage` actions:
1361
+ * Routes to the canonical four `@napplet/nap/storage` actions:
1159
1362
  * - `storage.get` → `storage.get.result` `{ value: string | null }`
1160
1363
  * - `storage.set` → `storage.set.result` `{ ok: boolean }` (canonical only checks `error`)
1161
1364
  * - `storage.remove` → `storage.remove.result` `{ ok: boolean }`
1162
1365
  * - `storage.keys` → `storage.keys.result` `{ keys: string[] }`
1163
1366
  *
1164
- * `storage.clear` is NOT in the canonical `@napplet/nub/storage` union (it was a
1367
+ * `storage.clear` is NOT in the canonical `@napplet/nap/storage` union (it was a
1165
1368
  * kehto unilateral extension); attempts produce a `storage.clear.result` envelope
1166
1369
  * with an `error` field set. Internal lifecycle cleanup still uses the
1167
1370
  * `cleanupNappState()` helper below — it is not napplet-reachable.
1168
1371
  *
1169
1372
  * **Deviation note (Phase 15 to decide):** Set/remove results emit both `ok`
1170
- * (legacy compat) and an `error` field on failure. Canonical `@napplet/nub/storage`
1373
+ * (legacy compat) and an `error` field on failure. Canonical `@napplet/nap/storage`
1171
1374
  * only specifies the optional `error`; napplets check `!result.error` for success.
1172
1375
  * Emitting `ok` preserves backward compatibility with existing in-tree callers.
1173
1376
  * Phase 15 (v1.2 release prep) decides whether to drop `ok` pre-release.
@@ -1247,4 +1450,4 @@ declare function routeServiceMessage(windowId: string, message: NappletMessage,
1247
1450
  */
1248
1451
  declare function notifyServiceWindowDestroyed(windowId: string, services: ServiceRegistry): void;
1249
1452
 
1250
- export { type AclCheckEvent, type AclChecker, type AclEntryExternal, type AclPersistence, type AclStateContainer, type AuthAdapter, type CacheAdapter, type CompatibilityReport, type ConfigAdapter, type ConsentHandler, type ConsentRequest, type CryptoAdapter, type DmAdapter, type EnforceConfig, type EnforceResult, type EventBuffer, type GuidPersistence, type HashVerifierAdapter, type HotkeyAdapter, type IdentityResolver, type ManifestCache, type ManifestCacheEntry, type ManifestPersistence, type NappKeyEntry, type NappKeyRegistry, type NappletClass, type NubEnforceConfig, type PendingUpdate, type PendingUpdateNotifier, RING_BUFFER_SIZE, type RelayConfigAdapter, type RelayPoolAdapter, type RelaySubscriptionHandle, type ReplayDetector, type Runtime, type RuntimeAdapter, type RuntimeConfigOverrides, type SendToNapplet, type ServiceDescriptor, type ServiceHandler, type ServiceInfo, type ServiceRegistry, type SessionEntry, type SessionRegistry, type ShellSecretPersistence, type Signer, type StatePersistence, type SubscriptionEntry, type VerificationCacheEntry, type WindowManagerAdapter, cleanupNappState, createAclState, createEnforceGate, createEventBuffer, createManifestCache, createNappKeyRegistry, createNubEnforceGate, createReplayDetector, createRuntime, createSessionRegistry, formatDenialReason, handleStorageNub, matchesAnyFilter, matchesFilter, notifyServiceWindowDestroyed, routeServiceMessage };
1453
+ export { type AclCheckEvent, type AclChecker, type AclEntryExternal, type AclPersistence, type AclStateContainer, type AuthAdapter, type CacheAdapter, type CompatibilityReport, type ConfigAdapter, type ConsentHandler, type ConsentRequest, type CryptoAdapter, type DmAdapter, type EnforceConfig, type EnforceResult, type EventBuffer, type FirewallEvent, type FirewallPersistence, type FirewallStateContainer, type GuidPersistence, type HashVerifierAdapter, type HotkeyAdapter, type IdentityResolver, type ManifestCache, type ManifestCacheEntry, type ManifestPersistence, type NappKeyEntry, type NappKeyRegistry, type NappletClass, type NubEnforceConfig, type PendingUpdate, type PendingUpdateNotifier, RING_BUFFER_SIZE, type RelayConfigAdapter, type RelayPoolAdapter, type RelaySubscriptionHandle, type ReplayDetector, type Runtime, type RuntimeAdapter, type RuntimeConfigOverrides, type SendToNapplet, type ServiceDescriptor, type ServiceHandler, type ServiceInfo, type ServiceRegistry, type SessionEntry, type SessionRegistry, type ShellSecretPersistence, type Signer, type StatePersistence, type SubscriptionEntry, type VerificationCacheEntry, type WindowManagerAdapter, cleanupNappState, createAclState, createEnforceGate, createEventBuffer, createFirewallState, createManifestCache, createNappKeyRegistry, createNubEnforceGate, createReplayDetector, createRuntime, createSessionRegistry, formatDenialReason, handleStorageNub, matchesAnyFilter, matchesFilter, notifyServiceWindowDestroyed, routeServiceMessage };