@lingxia/types 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/automation/index.d.ts +26 -1
  2. package/dist/automation/index.d.ts.map +1 -1
  3. package/dist/error.d.ts +32 -3
  4. package/dist/error.d.ts.map +1 -1
  5. package/dist/error.js +33 -3
  6. package/dist/error.js.map +1 -1
  7. package/dist/esm/automation/index.js +12 -0
  8. package/dist/esm/automation/index.js.map +1 -0
  9. package/dist/esm/error.js +148 -0
  10. package/dist/esm/error.js.map +1 -0
  11. package/dist/esm/generated/error.js +44 -0
  12. package/dist/esm/generated/error.js.map +1 -0
  13. package/dist/esm/generated/i18n.js +167 -0
  14. package/dist/esm/generated/i18n.js.map +1 -0
  15. package/dist/esm/generated/logic.js +4 -0
  16. package/dist/esm/generated/logic.js.map +1 -0
  17. package/dist/esm/index.js +11 -0
  18. package/dist/esm/index.js.map +1 -0
  19. package/dist/esm/package.json +4 -0
  20. package/dist/esm/process.js +9 -0
  21. package/dist/esm/process.js.map +1 -0
  22. package/dist/{testing/public-api.mjs → esm/testing/public-api.js} +79 -19
  23. package/dist/esm/testing/public-api.js.map +1 -0
  24. package/dist/generated/error.d.ts +5 -1
  25. package/dist/generated/error.d.ts.map +1 -1
  26. package/dist/generated/error.js +1 -0
  27. package/dist/generated/error.js.map +1 -1
  28. package/dist/generated/i18n.d.ts +1 -1
  29. package/dist/generated/i18n.d.ts.map +1 -1
  30. package/dist/generated/i18n.js +4 -0
  31. package/dist/generated/i18n.js.map +1 -1
  32. package/dist/generated/logic-web.d.ts +124 -0
  33. package/dist/generated/logic.d.ts +338 -136
  34. package/dist/generated/logic.d.ts.map +1 -1
  35. package/dist/index.d.ts +20 -10
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +5 -6
  38. package/dist/index.js.map +1 -1
  39. package/dist/process.d.ts +2 -2
  40. package/dist/process.js +2 -2
  41. package/dist/testing/public-api.d.ts +66 -15
  42. package/dist/testing/public-api.d.ts.map +1 -1
  43. package/dist/testing/public-api.js +78 -19
  44. package/dist/testing/public-api.js.map +1 -1
  45. package/package.json +9 -93
  46. package/src/automation/index.ts +28 -1
  47. package/src/error.ts +43 -3
  48. package/src/generated/error.ts +2 -1
  49. package/src/generated/i18n.ts +4 -0
  50. package/src/generated/logic-web.d.ts +124 -0
  51. package/src/generated/logic.ts +367 -144
  52. package/src/index.ts +32 -11
  53. package/src/process.ts +2 -2
  54. package/src/testing/public-api.ts +90 -19
@@ -8,8 +8,46 @@ export interface PageConfig<TData extends Record<string, unknown> = Record<strin
8
8
  onHide?: () => void | Promise<void>;
9
9
  onUnload?: () => void | Promise<void>;
10
10
  onPullDownRefresh?: () => void | Promise<void>;
11
- [key: string]: unknown;
12
11
  }
12
+ /** Lifecycle hook names a `Page({...})` config may declare. */
13
+ export type PageLifecycleName = Exclude<keyof PageConfig, 'data'>;
14
+ /** Lifecycle hook names an `App({...})` config may declare. */
15
+ export type AppLifecycleName = Exclude<keyof AppConfig, 'globalData'>;
16
+ /**
17
+ * What a key that differs from a lifecycle hook only in case resolves to, so
18
+ * the compiler names the mistake instead of silently accepting a new method.
19
+ */
20
+ export type MisspelledLifecycle<K extends string> = {
21
+ 'LingXia type error': `'${K}' differs only in case from a lifecycle hook`;
22
+ };
23
+ /**
24
+ * Applied to the custom half of a `Page`/`App` config. `onload` and `onShow`
25
+ * are one keystroke apart from real hooks and the runtime would simply never
26
+ * call the misspelling, so the closest case-insensitive match is rejected.
27
+ * Genuinely different names stay ordinary methods.
28
+ */
29
+ export type NoLifecycleTypos<TCustom, TNames extends string> = {
30
+ [K in keyof TCustom]: K extends TNames ? TCustom[K] : Lowercase<K & string> extends Lowercase<TNames> ? MisspelledLifecycle<K & string> : TCustom[K];
31
+ };
32
+ /**
33
+ * A `setData` key that addresses inside `data` — `'a.b'` or `'rows[0].name'`.
34
+ * Values behind a path stay `unknown`: the runtime resolves the path, so the
35
+ * type cannot.
36
+ */
37
+ export type PageDataPath = `${string}.${string}` | `${string}[${number}]${string}`;
38
+ /**
39
+ * A field initialized to `null` or `[]` states nothing about what will fill it
40
+ * later, so it stays open. Annotate it (`null as Profile | null`) to have the
41
+ * fill checked.
42
+ */
43
+ export type LazyInitField<T> = [T] extends [null | undefined] ? unknown : [T] extends [never[]] ? unknown[] : T;
44
+ /**
45
+ * Top-level keys are checked against `data`; only path-shaped keys stay open.
46
+ * A misspelled or wrongly typed top-level key is a compile error.
47
+ */
48
+ export type SetDataPatch<TData> = {
49
+ [K in keyof TData]?: LazyInitField<TData[K]>;
50
+ } & Partial<Record<PageDataPath, unknown>>;
13
51
  export interface PageInstance<TData extends Record<string, unknown> = Record<string, unknown>> {
14
52
  data: TData;
15
53
  route: string;
@@ -22,7 +60,7 @@ export interface PageInstance<TData extends Record<string, unknown> = Record<str
22
60
  * Available when this page was opened by `lx.navigateTo(...)`.
23
61
  */
24
62
  opener?: PageMessagePort;
25
- setData(data: Partial<TData> | Record<string, unknown>, callback?: () => void): void;
63
+ setData(data: SetDataPatch<TData>, callback?: () => void): void;
26
64
  }
27
65
  /**
28
66
  * Injected by the runtime into methods listed in `stream_handlers` page metadata.
@@ -62,8 +100,8 @@ export interface ChannelHandle<TSend = unknown, TReceive = unknown> {
62
100
  *
63
101
  * - `app`: app-owned temporary output, or durable `lx://userdata` output when
64
102
  * `filePath` is set
65
- * - `downloads`: user-visible system Downloads output, requiring
66
- * `security.privileges: ["downloads"]` in `lxapp.json`
103
+ * - `downloads`: user-visible system Downloads output, requiring a host
104
+ * privilege grant and a native Downloads grant
67
105
  *
68
106
  * Default: `app`.
69
107
  */
@@ -95,18 +133,46 @@ export interface DownloadTask<TDownloadResult extends DownloadResult = DownloadR
95
133
  wait(): Promise<TDownloadResult>;
96
134
  }
97
135
  declare global {
136
+ /**
137
+ * The lxapp's configured page names, one key per page.
138
+ *
139
+ * Empty here on purpose. `lingxia dev` / `lingxia build` generates the
140
+ * project's own names into this interface; until then `ConfiguredPageName`
141
+ * stays `string` and every navigation call compiles exactly as before.
142
+ */
143
+ interface LxAppPages {
144
+ }
98
145
  interface HostAppApi {
99
146
  /**
100
- * The build environment from `app.json::envVersion`. It is fixed at boot
101
- * and defaults to `release` for older artifacts.
147
+ * The host deployment environment from `app.json::env` (`dev` | `prod`).
148
+ * It is fixed at boot and defaults to `prod` for older artifacts.
149
+ * Not the lxapp publish channel (`release` | `preview` | `draft`).
102
150
  */
103
- readonly envVersion: HostAppEnvVersion;
151
+ readonly env: HostAppEnv;
104
152
  /**
105
153
  * Launch-at-startup control. Absent where the host cannot register a
106
154
  * startup item; its presence and `lx.supports({ capability: 'autostart' })` always
107
155
  * agree, so `lx.app.autostart?.…` and the query are interchangeable.
108
156
  */
109
157
  autostart?: AutostartApi;
158
+ /** The language this lxapp renders in. Every lxapp follows it. */
159
+ readonly displayLanguage: DisplayLanguageApi;
160
+ /** The light/dark scheme this lxapp renders in. */
161
+ readonly appearance: AppearanceApi;
162
+ /**
163
+ * Product-wide settings, and their single writer. Present only in the
164
+ * Control app the host sealed at build time; its presence and
165
+ * `lx.supports({ capability: 'control' })` always agree, so
166
+ * `lx.app.control?.…` and the query are interchangeable.
167
+ */
168
+ readonly control?: ControlApi;
169
+ /**
170
+ * Product-wide cache reporting and clearing for a settings screen.
171
+ * Present only in the Control app; its presence and
172
+ * `lx.supports({ capability: 'control' })` always agree, so
173
+ * `lx.app.cache?.…` and the query are interchangeable.
174
+ */
175
+ cache?: AppCacheApi;
110
176
  }
111
177
  /** Runtime environment constants backed by abstract `lx://` paths. */
112
178
  interface LxEnv {
@@ -156,6 +222,7 @@ type StorageEntry<S extends object> = {
156
222
  export type TypedStorage<S extends object> = {
157
223
  get<K extends StorageKey<S>>(key: K): Promise<S[K] | undefined>;
158
224
  set(...entry: StorageEntry<S>): Promise<void>;
225
+ has(key: StorageKey<S>): Promise<boolean>;
159
226
  delete(key: StorageKey<S>): Promise<void>;
160
227
  clear(): Promise<void>;
161
228
  list(prefix?: string): Promise<string[]>;
@@ -172,13 +239,36 @@ export type ActionSheetResult = {
172
239
  } | CanceledResult;
173
240
  /** Every surface handle, narrowable by `kind`. */
174
241
  export type AnySurface = PageSurface | DeclaredSurface | AppSurface | TabSurface | BuiltinSurface;
242
+ /**
243
+ * The product-wide cache a settings screen reports and clears.
244
+ * App-scoped, not lxapp-scoped: the figure covers every lxapp the host
245
+ * has run. Injected only into the Control app, same gate as
246
+ * `lx.app.control` — guests do not have the member.
247
+ */
248
+ export type AppCacheApi = {
249
+ /** Estimated reclaimable managed bytes; excludes live session storage and WebView cache. */
250
+ size(): Promise<number>;
251
+ /**
252
+ * Clear reclaimable host caches. Control app only. Live session usercache and
253
+ * temp are preserved, including the caller's. Does not restart any lxapp.
254
+ * Userdata, KV, Downloads, cookies, valid installs and host components survive.
255
+ * Per-category failures are reported; setup/worker failures reject the call.
256
+ */
257
+ clear(): Promise<{
258
+ /** Estimated file bytes successfully removed; excludes WebView cache. */
259
+ freedBytes: number;
260
+ /** Protected usercache/session paths skipped, not a count of apps. */
261
+ skippedActivePaths: number;
262
+ webview: 'cleared' | 'unsupported' | 'failed';
263
+ failures: string[];
264
+ }>;
265
+ };
175
266
  export type AppConfig = {
176
267
  globalData?: Record<string, unknown>;
177
268
  onLaunch?: (options?: AppLaunchOptions) => void | Promise<void>;
178
269
  onShow?: (args?: AppLifecycleEventArgs) => void | Promise<void>;
179
270
  onHide?: (args?: AppLifecycleEventArgs) => void | Promise<void>;
180
271
  onUserCaptureScreen?: () => void | Promise<void>;
181
- [key: string]: unknown;
182
272
  };
183
273
  /** Runtime-managed app download path, usually under `lx://userdata`. */
184
274
  export type AppDownloadFilePath = string & {
@@ -224,15 +314,32 @@ export type AppInstance = AppConfig & {
224
314
  export type AppLaunchOptions = {
225
315
  path?: string;
226
316
  query?: Record<string, string>;
227
- scene?: number;
317
+ /** `8003` = AppLink (cold: onLaunch; warm: onShow). */
318
+ scene?: AppLaunchScene;
319
+ /**
320
+ * Inbound link exactly as the OS delivered it, fragment included. Present
321
+ * only with `scene: 8003`. Untrusted: route from an allowlist of paths.
322
+ */
323
+ url?: string;
228
324
  referrerInfo?: {
229
325
  appId?: string;
230
326
  extraData?: Record<string, unknown>;
231
327
  };
232
328
  };
329
+ /**
330
+ * Launch scene. `8003` is AppLink (cold: `onLaunch`; warm: `onShow`).
331
+ * Other numeric scenes stay valid; completion offers `8003`.
332
+ */
333
+ export type AppLaunchScene = 8003 | (number & {});
233
334
  export type AppLifecycleEventArgs = {
234
335
  source: 'host' | 'lxapp';
235
336
  reason: 'foreground' | 'background' | 'screenshot' | 'open' | 'close' | 'switch_back' | 'switch_away';
337
+ path?: string;
338
+ query?: Record<string, string>;
339
+ /** `8003` = AppLink. */
340
+ scene?: AppLaunchScene;
341
+ /** Inbound link, present only with `scene: 8003`. */
342
+ url?: string;
236
343
  };
237
344
  export type AppScreenshotOptions = {
238
345
  /**
@@ -254,7 +361,25 @@ export type AppSurface = SurfaceBase & SurfaceShowable & {
254
361
  readonly kind: 'app';
255
362
  readonly realized: 'main' | 'aside';
256
363
  };
257
- export type AppearanceApi = globalThis.AppearanceApi;
364
+ /** `lx.app.appearance` — the scheme this lxapp renders in. */
365
+ export type AppearanceApi = {
366
+ /**
367
+ * The scheme this lxapp is rendering in. An lxapp that pinned one in its
368
+ * `lxapp.json` reports that; every other lxapp reports the product's.
369
+ */
370
+ get(): ResolvedAppearance;
371
+ /**
372
+ * Follow it, starting with the current value. Returns an unsubscribe.
373
+ *
374
+ * The first callback runs synchronously, before `watch` returns, so the
375
+ * unsubscribe is not yet bound inside it.
376
+ */
377
+ watch(callback: (resolved: ResolvedAppearance) => void): () => void;
378
+ };
379
+ /**
380
+ * What the product's light/dark scheme is set to. `'auto'` follows
381
+ * the system.
382
+ */
258
383
  export type AppearancePreference = 'auto' | 'light' | 'dark';
259
384
  /**
260
385
  * Launch-at-startup control for the host app.
@@ -272,8 +397,8 @@ export type AppearancePreference = 'auto' | 'light' | 'dark';
272
397
  * is called, so the decision stays with the user (typically a settings-page
273
398
  * toggle, default off).
274
399
  * Host-app-level capability: like `checkUpdate` and `screenshot`, the methods
275
- * are available only to the home lxapp; other lxapps receive a permission
276
- * error.
400
+ * are available only to the native-assigned Control app; other lxapps receive
401
+ * a permission error.
277
402
  */
278
403
  export type AutostartApi = {
279
404
  /**
@@ -294,11 +419,11 @@ export type AutostartApi = {
294
419
  export type BinaryFileData = ArrayBuffer | ArrayBufferView;
295
420
  /**
296
421
  * Built-in browser product page. Opening one requires
297
- * `capabilities.browser` and is restricted to the home lxapp.
422
+ * `capabilities.browser` and is restricted to the native-assigned Control app.
298
423
  */
299
- export type BuiltinShellPage = 'settings' | 'downloads';
424
+ export type BuiltinShellPage = 'downloads';
300
425
  /**
301
- * A host builtin page such as settings or downloads. The shell owns
426
+ * A host builtin page such as downloads. The shell owns
302
427
  * its lifetime and its visibility, so this handle reports identity:
303
428
  * there is no `show` / `hide`, and the inherited `close()` rejects
304
429
  * with `unsupported_placement`.
@@ -452,10 +577,68 @@ export type CompressVideoTask = PromiseLike<CompressVideoResult> & AsyncIterable
452
577
  cancel(): void;
453
578
  wait(): Promise<CompressVideoResult>;
454
579
  };
580
+ /**
581
+ * Configured page name from `lxapp.json` / `lingxia.yaml`. JavaScript
582
+ * navigation accepts only this name; full routes such as
583
+ * `/pages/home/index` are internal runtime details. Discover names
584
+ * with `lxdev lxapp pages`.
585
+ * Narrows to the project's own names once `lingxia dev` or
586
+ * `lingxia build` has generated them; plain `string` before that, so
587
+ * a project that never ran a build still compiles.
588
+ */
589
+ export type ConfiguredPageName = keyof LxAppPages extends never ? string : keyof LxAppPages;
455
590
  export type ConnectWifiOptions = {
456
591
  SSID: string;
457
592
  password?: string;
458
593
  };
594
+ /**
595
+ * `lx.app.control` — product-wide settings, and their single writer.
596
+ * Present only in the Control app. Bind it once rather than repeating
597
+ * `lx.app.control!`:
598
+ * ```js
599
+ * const control = lx.app.control;
600
+ * if (!control) return; // not the Control app
601
+ * await control.appearance.setPreference('dark');
602
+ * ```
603
+ */
604
+ export type ControlApi = {
605
+ readonly displayLanguage: ControlDisplayLanguageApi;
606
+ readonly appearance: ControlAppearanceApi;
607
+ };
608
+ /** `lx.app.control.appearance` — the product's own light/dark setting. */
609
+ export type ControlAppearanceApi = {
610
+ /** What the user chose for the whole product. */
611
+ getPreference(): AppearancePreference;
612
+ /**
613
+ * Pin the product to `'light'` or `'dark'`, or follow the system with
614
+ * `'auto'`. An lxapp that pinned a scheme in its manifest keeps it.
615
+ */
616
+ setPreference(preference: AppearancePreference): Promise<void>;
617
+ /**
618
+ * Follow the choice, not what it resolves to: a system flip under `'auto'`
619
+ * moves `lx.app.appearance.watch` and leaves this quiet. Starts with the
620
+ * current value; that first callback runs synchronously, before
621
+ * `watchPreference` returns.
622
+ */
623
+ watchPreference(callback: (preference: AppearancePreference) => void): () => void;
624
+ };
625
+ /**
626
+ * `lx.app.control.displayLanguage` — the preference behind that
627
+ * language, for the one surface that edits it.
628
+ */
629
+ export type ControlDisplayLanguageApi = {
630
+ /** What the user chose: `'auto'`, or a canonical BCP-47 tag. */
631
+ getPreference(): DisplayLanguagePreference;
632
+ /** Persist the product's language. Rejects a tag that is not valid BCP-47. */
633
+ setPreference(preference: DisplayLanguagePreference): Promise<void>;
634
+ /**
635
+ * Follow the choice, not what it resolves to: a system locale change under
636
+ * `'auto'` moves the language without moving the preference. Starts with
637
+ * the current value and returns an unsubscribe; that first callback runs
638
+ * synchronously, before `watchPreference` returns.
639
+ */
640
+ watchPreference(callback: (preference: DisplayLanguagePreference) => void): () => void;
641
+ };
459
642
  /** A surface declared by the host in `lingxia.yaml`. */
460
643
  export type DeclaredSurface = SurfaceBase & SurfaceShowable & {
461
644
  readonly kind: 'declared';
@@ -465,6 +648,33 @@ export type DeviceOrientation = "portrait" | "landscape";
465
648
  export type DeviceOrientationChangeEvent = {
466
649
  value: DeviceOrientation;
467
650
  };
651
+ /** `lx.app.displayLanguage` — the language this lxapp renders in. */
652
+ export type DisplayLanguageApi = {
653
+ /**
654
+ * The language in effect right now, as a canonical BCP-47 tag. Map it to
655
+ * the catalogs this lxapp actually ships and fall back where it has none;
656
+ * that narrowing is yours, and is not a language setting of its own.
657
+ */
658
+ get(): string;
659
+ /**
660
+ * Follow the language, starting with the current value. Returns an
661
+ * unsubscribe.
662
+ *
663
+ * Logic needs this because the strings it hands to native chrome —
664
+ * navigation bar titles, tab bar labels, modal and action-sheet text — are
665
+ * the app's own, and nothing re-renders them on its behalf.
666
+ *
667
+ * The first callback runs synchronously, before `watch` returns, so the
668
+ * unsubscribe is not yet bound inside it.
669
+ */
670
+ watch(callback: (language: string) => void): () => void;
671
+ };
672
+ /**
673
+ * What the product's language is set to: `'auto'` follows the system,
674
+ * or any canonical BCP-47 tag. `string & {}` keeps `'auto'` in
675
+ * autocomplete while still accepting a tag.
676
+ */
677
+ export type DisplayLanguagePreference = 'auto' | (string & {});
468
678
  export type DownloadDestination = 'app' | 'downloads';
469
679
  export type DownloadOptionsBase = {
470
680
  /** HTTP(S) source URL. */
@@ -496,6 +706,12 @@ export type DownloadsDownloadResult = {
496
706
  mimeType?: string;
497
707
  size: number;
498
708
  };
709
+ /**
710
+ * Configured page name belonging to *another* lxapp. This app's own
711
+ * page union cannot check it, so it stays a plain string and the
712
+ * target runtime rejects a name it does not have.
713
+ */
714
+ export type ExternalPageName = string;
499
715
  export type ExtractVideoThumbnailOptions = {
500
716
  /**
501
717
  * Source video path or `lx://` URI.
@@ -592,15 +808,17 @@ export type GetVideoInfoOptions = {
592
808
  };
593
809
  export type HostAppApi = globalThis.HostAppApi;
594
810
  /**
595
- * Build-time environment version of the host app.
596
- * Surfaced via {@link HostAppApi.envVersion}. Mirrors the
597
- * `crates/lingxia-update::ReleaseType` enum and the `envVersion` field in the
598
- * generated `app.json`. Pre-envVersion app artifacts are treated as `'release'`.
599
- * Note: this is *separate* from `LxAppEnvVersion` in the navigator module,
600
- * which encodes lxapp release channels for cross-app navigation URLs —
601
- * same three names, different axis.
811
+ * Build-time deployment environment of the host app (`dev` | `prod`).
812
+ * Surfaced via {@link HostAppApi.env}. Taken from the `env` field in
813
+ * the generated `app.json`. Missing `env` is treated as `'prod'`.
814
+ * This is the host build axis: which server, package-id suffix, publish
815
+ * token, and self-update endpoint the host uses. It is **not** the
816
+ * lxapp publish channel (`LxAppEnvVersion` / `LxAppReleaseType`:
817
+ * `'release' | 'preview' | 'draft'`). Default channel is derived
818
+ * from env (`dev` → `draft`, `prod` → `release`) and can be
819
+ * overridden when opening an lxapp.
602
820
  */
603
- export type HostAppEnvVersion = 'developer' | 'preview' | 'release';
821
+ export type HostAppEnv = 'dev' | 'prod';
604
822
  export type HostAppUpdateApplyStage = 'download' | 'install';
605
823
  export type HostAppUpdateCheckResult = {
606
824
  hasUpdate: false;
@@ -654,6 +872,11 @@ export type HostAppUpdateTask = PromiseLike<HostAppUpdateResult> & AsyncIterable
654
872
  finally(onfinally?: (() => void) | null): Promise<HostAppUpdateResult>;
655
873
  wait(): Promise<HostAppUpdateResult>;
656
874
  };
875
+ /**
876
+ * Canonical platform-family label shared by `lx.app.getBaseInfo().os`
877
+ * and `lx.getDeviceInfo().osName`. `"unknown"` is a non-product build.
878
+ */
879
+ export type HostOs = 'iOS' | 'macOS' | 'Android' | 'Windows' | 'Harmony' | 'unknown';
657
880
  export type InstalledTerminalFont = {
658
881
  family: string;
659
882
  monospace: boolean;
@@ -676,11 +899,11 @@ export type KeyEvent = {
676
899
  repeat?: boolean;
677
900
  };
678
901
  export type KeyEventCallback = (event: KeyEvent) => void;
679
- export type LxAppEnvVersion = 'release' | 'preview' | 'developer';
902
+ export type LxAppEnvVersion = 'release' | 'preview' | 'draft';
680
903
  /** LxApp metadata APIs. */
681
- export type LxAppReleaseType = 'release' | 'preview' | 'developer';
904
+ export type LxAppReleaseType = 'release' | 'preview' | 'draft';
682
905
  /** Boolean capability names accepted by `lx.supports`. */
683
- export type LxCapabilityFlag = 'terminal' | 'autostart' | 'notifications' | 'browser' | 'proxy' | 'selfUpdate' | 'process' | 'appUse' | 'computerUse' | 'browserUse' | 'mediaCapture';
906
+ export type LxCapabilityFlag = 'control' | 'terminal' | 'autostart' | 'notifications' | 'browser' | 'proxy' | 'selfUpdate' | 'process' | 'appUse' | 'computerUse' | 'browserUse' | 'mediaCapture';
684
907
  /**
685
908
  * One capability question per call. The catalog is closed, so
686
909
  * completion enumerates it and a typo is a type error. `capability`
@@ -753,9 +976,13 @@ export type NavigateToAppOptions = {
753
976
  * open the target app's initial page. Full routes such as
754
977
  * `/pages/home/index` are not supported.
755
978
  */
756
- page?: string;
979
+ page?: ExternalPageName;
757
980
  query?: PageQuery;
758
- envVersion?: LxAppEnvVersion;
981
+ /**
982
+ * Lxapp publish channel. Defaults from the host env
983
+ * (`dev` → `draft`, `prod` → `release`).
984
+ */
985
+ channel?: LxAppEnvVersion;
759
986
  targetVersion?: string;
760
987
  };
761
988
  export type NavigateToOptions = PageTargetOptions;
@@ -830,7 +1057,7 @@ export type OpenPageShared = {
830
1057
  */
831
1058
  size?: OverlaySurfaceSize;
832
1059
  interaction?: SurfaceInteraction;
833
- query?: Record<string, unknown>;
1060
+ query?: PageQuery;
834
1061
  /** Caller-owned identity, for `lx.surface.get(key)` later. */
835
1062
  key?: string;
836
1063
  };
@@ -879,7 +1106,7 @@ export type PageSurface = SurfaceBase & SurfaceShowable & SurfaceMessaging & {
879
1106
  */
880
1107
  export type PageTargetOptions = {
881
1108
  /** Configured page name from `lingxia.yaml` / `lxapp.json`. */
882
- page: string;
1109
+ page: ConfiguredPageName;
883
1110
  query?: PageQuery;
884
1111
  };
885
1112
  export type PreviewMediaAdvance = 'manual' | 'next' | 'loop';
@@ -1007,7 +1234,11 @@ export type PreviewMediaSingleOptions = PreviewMediaSource & {
1007
1234
  export type PreviewMediaSource = {
1008
1235
  /**
1009
1236
  * Media source path.
1010
- * Recommended: `lx://` path (for example `lx://usercache/...`) or a sandbox-local path
1237
+ *
1238
+ * Accepts an `https://` (or `http://`) URL for a remote image or video —
1239
+ * the host loads it directly, so no prior `lx.downloadFile` is required,
1240
+ * and its domain must be permitted by the app's network policy — an
1241
+ * `lx://` path (for example `lx://usercache/...`), or a sandbox-local path
1011
1242
  * that can be resolved by runtime access rules.
1012
1243
  */
1013
1244
  path: string;
@@ -1130,8 +1361,8 @@ export type ShareTitleOptions = {
1130
1361
  title?: string;
1131
1362
  };
1132
1363
  /**
1133
- * App-owned host-shell chrome. Mutations are available only to the home
1134
- * lxapp's Logic context; other lxapps receive a permission error.
1364
+ * App-owned host-shell chrome. Mutations are available only to the
1365
+ * Control app's Logic context; other lxapps receive a permission error.
1135
1366
  */
1136
1367
  export type ShellApi = {
1137
1368
  /**
@@ -1142,7 +1373,7 @@ export type ShellApi = {
1142
1373
  sidebarActions: ShellSidebarActionsApi;
1143
1374
  /** Compose another lxapp into a shell slot. */
1144
1375
  openApp(appId: string, options: ShellOpenAppOptions): Promise<AppSurface>;
1145
- /** Open a host builtin page such as settings or downloads. */
1376
+ /** Open a host builtin page such as downloads. */
1146
1377
  openBuiltin(page: BuiltinShellPage): Promise<BuiltinSurface>;
1147
1378
  /**
1148
1379
  * Open a declared surface with shell privileges — the same declaration
@@ -1162,16 +1393,19 @@ export type ShellOpenAppOptions = {
1162
1393
  * Configured page name from the target lxapp's `lxapp.json`. Omit it to
1163
1394
  * open that app's initial page. Full page routes are not supported.
1164
1395
  */
1165
- page?: string;
1396
+ page?: ExternalPageName;
1166
1397
  query?: PageQuery;
1167
- /** Defaults to 'release'. */
1168
- envVersion?: LxAppEnvVersion;
1398
+ /**
1399
+ * Lxapp publish channel. Defaults from the host env
1400
+ * (`dev` → `draft`, `prod` → `release`).
1401
+ */
1402
+ channel?: LxAppEnvVersion;
1169
1403
  targetVersion?: string;
1170
1404
  /** Stable identity for `lx.surface.get(key)`. */
1171
1405
  key?: string;
1172
1406
  };
1173
1407
  /**
1174
- * The declared-surface options only the home lxapp may use.
1408
+ * The declared-surface options only the native-assigned Control app may use.
1175
1409
  * Creating an extra instance and overriding a placement both mutate
1176
1410
  * shared shell composition, so they live here and not on
1177
1411
  * `lx.surface.openDeclared` — which consumes a declaration exactly as
@@ -1214,8 +1448,13 @@ export type ShellSidebarAction = {
1214
1448
  * `public/settings.svg`, or an `lx://temp`, `lx://usercache`, or
1215
1449
  * `lx://userdata` path returned by LingXia file APIs. Native absolute paths,
1216
1450
  * parent traversal, `file:` URLs, and network URLs are rejected; download a
1217
- * remote icon before registration. For portable rendering, prefer a square,
1218
- * transparent, monochrome SVG or PNG designed for a 16-point visual.
1451
+ * remote icon before registration.
1452
+ *
1453
+ * SVG is a template glyph tinted by the host. Raster PNG/JPEG/WebP retains
1454
+ * its colour and is center-cropped to the square icon slot, which is suitable
1455
+ * for a brand logo; provide square artwork when the crop matters. A path in
1456
+ * `lx://temp` is temporary, so download and register it again after the next
1457
+ * Logic launch rather than persisting it.
1219
1458
  */
1220
1459
  icon: string;
1221
1460
  /**
@@ -1261,7 +1500,7 @@ export type ShellSidebarActionUpdate = {
1261
1500
  disabled?: boolean;
1262
1501
  };
1263
1502
  /**
1264
- * Role and edge overrides the home lxapp may apply to a live declared
1503
+ * Role and edge overrides the native-assigned Control app may apply to a live declared
1265
1504
  * surface. A stable root rejects non-main roles.
1266
1505
  */
1267
1506
  export type ShellSurfacePatch = {
@@ -1305,6 +1544,12 @@ export type Storage = {
1305
1544
  */
1306
1545
  get<T = unknown>(key: string): Promise<T | undefined>;
1307
1546
  set(key: string, value: unknown): Promise<void>;
1547
+ /**
1548
+ * Resolves whether an exact key exists, without reading its value. Prefer
1549
+ * it over comparing `get` against `undefined`: presence is a key lookup,
1550
+ * while `get` also reads and deserializes the stored value.
1551
+ */
1552
+ has(key: string): Promise<boolean>;
1308
1553
  delete(key: string): Promise<void>;
1309
1554
  clear(): Promise<void>;
1310
1555
  /** Resolves every key, optionally filtered by prefix. */
@@ -1329,7 +1574,7 @@ export type StreamSourceOptions = {
1329
1574
  */
1330
1575
  export type SurfaceApi = {
1331
1576
  /** Open one of this lxapp's own pages as a float or a window. */
1332
- openPage(page: string, options?: OpenPageOptions): Promise<PageSurface>;
1577
+ openPage(page: ConfiguredPageName, options?: OpenPageOptions): Promise<PageSurface>;
1333
1578
  /** Open external content in the in-app browser. */
1334
1579
  openUrl(url: string, options?: OpenUrlOptions): Promise<TabSurface>;
1335
1580
  /**
@@ -1435,7 +1680,7 @@ export type SurfaceError = Error & {
1435
1680
  * `SurfaceError`, so no caller has to match on message text.
1436
1681
  */
1437
1682
  export type SurfaceErrorCode = /** The placement cannot be realized by this host build. */ 'unsupported_placement'
1438
- /** A privileged operation was called by an lxapp other than the home lxapp. */
1683
+ /** A privileged operation was called by an lxapp other than the native-assigned Control app. */
1439
1684
  | 'denied'
1440
1685
  /** No such declared surface, lxapp, or builtin page. */
1441
1686
  | 'not_declared'
@@ -1519,6 +1764,15 @@ export type TabBarApi = globalThis.TabBarApi;
1519
1764
  export type TabBarItemPatch = {
1520
1765
  index: number;
1521
1766
  text?: string | null;
1767
+ /**
1768
+ * Package-relative path, or an `lx://temp` / `lx://usercache` /
1769
+ * `lx://userdata` path from a LingXia file API. Network URLs are rejected —
1770
+ * download first (`lx.downloadFile`) and pass the returned path.
1771
+ *
1772
+ * SVG (and SF Symbols) are template-tinted with `foregroundColor` /
1773
+ * `selectedForegroundColor`. Raster files (PNG/JPEG/WebP) keep their own
1774
+ * colour so a brand mark is not flattened into a solid square.
1775
+ */
1522
1776
  iconPath?: string | null;
1523
1777
  badge?: string | null;
1524
1778
  redDot?: boolean;
@@ -1641,8 +1895,7 @@ export type TerminalSettingsSnapshot = {
1641
1895
  /** Resolved configuration after all valid layers. */
1642
1896
  value: TerminalSettingsValue;
1643
1897
  effective: {
1644
- /** Host appearance before applying terminal.theme.mode. */
1645
- systemAppearance: 'light' | 'dark';
1898
+ /** The scheme the product is in, and therefore the terminal too. */
1646
1899
  appearance: 'light' | 'dark';
1647
1900
  colorScheme: string | null;
1648
1901
  font: {
@@ -1661,9 +1914,11 @@ export type TerminalSettingsWarning = {
1661
1914
  code: 'invalidUserFile' | 'missingColorScheme';
1662
1915
  message: string;
1663
1916
  };
1664
- export type TerminalThemeMode = 'system' | 'light' | 'dark';
1917
+ /**
1918
+ * A light scheme and a dark one. Which is in use follows the
1919
+ * product's light/dark setting; the terminal has no switch of its own.
1920
+ */
1665
1921
  export type TerminalThemeSettings = {
1666
- mode: TerminalThemeMode;
1667
1922
  light: string;
1668
1923
  dark: string;
1669
1924
  };
@@ -1692,7 +1947,7 @@ export type UpdateFailedInfo = UpdateReadyInfo & {
1692
1947
  };
1693
1948
  /**
1694
1949
  * Callback-based updates for this lxapp's bundle. Available to every
1695
- * lxapp. To update the native host app, the home lxapp uses the
1950
+ * lxapp. To update the native host app, the Control app uses the
1696
1951
  * task-based `lx.app.checkUpdate()` API instead.
1697
1952
  */
1698
1953
  export type UpdateManager = {
@@ -1705,7 +1960,7 @@ export type UpdateManager = {
1705
1960
  export type UpdateReadyInfo = {
1706
1961
  version?: string;
1707
1962
  isForceUpdate?: boolean;
1708
- channel?: "release" | "preview" | "developer" | string;
1963
+ channel?: "release" | "preview" | "draft" | string;
1709
1964
  };
1710
1965
  export type UploadIteratorResult = {
1711
1966
  done: boolean;
@@ -1926,38 +2181,27 @@ export type WindowsTerminalInlineImageStatus = {
1926
2181
  bytes: number;
1927
2182
  };
1928
2183
  };
1929
- /** Host app base information. */
2184
+ /**
2185
+ * Host app identity. Everything here is fixed for the life of the process;
2186
+ * the language the app renders in is not, and lives on
2187
+ * `lx.app.displayLanguage`.
2188
+ */
1930
2189
  export interface AppBaseInfo {
1931
- /**
1932
- * Raw system locale, unaffected by a saved in-app language override.
1933
- * For the language the UI should actually render in, use
1934
- * `display_language` instead.
1935
- */
1936
- locale: string;
1937
- /**
1938
- * Effective display language: a saved user override when set, else
1939
- * `locale`. This is what native chrome and `lx.*` i18n strings follow.
1940
- */
1941
- displayLanguage: string;
1942
2190
  /**
1943
2191
  * Platform family: `"iOS"` / `"macOS"` / `"Android"` / `"Windows"` /
1944
2192
  * `"Harmony"`. Matches the View-side `usePlatform().os` value.
1945
2193
  */
1946
- os: string;
2194
+ os: HostOs;
1947
2195
  productName: string;
1948
2196
  version: string;
1949
2197
  SDKVersion: string;
1950
2198
  }
1951
- export interface AppearanceState {
1952
- preference: AppearancePreference;
1953
- resolved: ResolvedAppearance;
1954
- }
1955
2199
  /** Device info APIs. */
1956
2200
  export interface DeviceInfo {
1957
2201
  brand: string;
1958
2202
  model: string;
1959
2203
  marketName: string;
1960
- osName: string;
2204
+ osName: HostOs;
1961
2205
  osVersion: string;
1962
2206
  }
1963
2207
  export interface FileStats {
@@ -1996,7 +2240,7 @@ export interface LxAppInfo {
1996
2240
  appId: string;
1997
2241
  appName: string;
1998
2242
  version: string;
1999
- releaseType: LxAppReleaseType;
2243
+ channel: LxAppReleaseType;
2000
2244
  }
2001
2245
  export interface ScreenInfo {
2002
2246
  width: number;
@@ -2029,37 +2273,6 @@ export declare class DirEntry {
2029
2273
  readonly isDirectory: boolean;
2030
2274
  readonly isSymlink: boolean;
2031
2275
  }
2032
- export declare class JSMessagePort {
2033
- constructor();
2034
- static postMessage(payload: any): void;
2035
- static onMessage(handler: (...args: any[]) => any): (...args: any[]) => any;
2036
- }
2037
- export declare class JSSurface {
2038
- constructor();
2039
- close(): Promise<void>;
2040
- postMessage(payload: any): void;
2041
- onMessage(handler: (...args: any[]) => any): (...args: any[]) => any;
2042
- static onClose(handler: (...args: any[]) => any): (...args: any[]) => any;
2043
- }
2044
- export declare class JSUpdateManager {
2045
- constructor();
2046
- /** Apply update by restarting the app */
2047
- applyUpdate(): void;
2048
- /** Subscribes to a ready update and returns the unsubscribe fn. */
2049
- onUpdateReady(cb: (...args: any[]) => any): (...args: any[]) => any;
2050
- /** Subscribes to a failed update and returns the unsubscribe fn. */
2051
- onUpdateFailed(cb: (...args: any[]) => any): (...args: any[]) => any;
2052
- }
2053
- export declare class JSVideoContext {
2054
- constructor();
2055
- play(): void;
2056
- pause(): void;
2057
- stop(): void;
2058
- seek(position: number): void;
2059
- requestFullScreen(): void;
2060
- exitFullScreen(): void;
2061
- setStreamSource(options: StreamSourceOptions): void;
2062
- }
2063
2276
  export declare class LxFile {
2064
2277
  private constructor();
2065
2278
  /** The path supplied to `lx.fs.file`. */
@@ -2084,14 +2297,6 @@ export declare class LxFile {
2084
2297
  /** Read metadata for this managed path. */
2085
2298
  stat(): Promise<FileStats>;
2086
2299
  }
2087
- declare global {
2088
- interface AppearanceApi {
2089
- /** Read the appearance preference and the light/dark value it resolves to. */
2090
- get(): AppearanceState;
2091
- /** Set the appearance preference to `auto`, `light`, or `dark`. */
2092
- set(preference: AppearancePreference): Promise<void>;
2093
- }
2094
- }
2095
2300
  declare global {
2096
2301
  interface FileSystemApi {
2097
2302
  /**
@@ -2126,33 +2331,27 @@ declare global {
2126
2331
  * is what the user sees of the whole app — host-drawn navigation chrome,
2127
2332
  * native overlays, and every composited WebView, not just this lxapp's web
2128
2333
  * content. Because that view can include other lxapps' UI, the API is
2129
- * restricted to the home lxapp, like the other host-level APIs on `lx.app`.
2334
+ * restricted to the Control app, like the other host-level APIs on `lx.app`.
2130
2335
  */
2131
2336
  screenshot(options?: AppScreenshotOptions): Promise<AppScreenshotResult>;
2132
2337
  /**
2133
2338
  * Check whether the host app has an update.
2134
- * This host-level capability is restricted to the home lxapp. Calling it opts
2339
+ * This host-level capability is restricted to the Control app. Calling it opts
2135
2340
  * the process into custom update handling. Incompatible updates are hidden as
2136
2341
  * `hasUpdate: false`; platforms that cannot apply a package may still return
2137
2342
  * metadata and reject when `update.apply()` is invoked.
2138
2343
  */
2139
2344
  checkUpdate(): Promise<HostAppUpdateCheckResult>;
2140
- readonly envVersion: HostAppEnvVersion;
2345
+ readonly env: HostAppEnv;
2141
2346
  /**
2142
- * Read the host app's identity: locale, display language, OS, product name,
2143
- * product version, and SDK runtime version.
2347
+ * Read the host app's identity: OS, product name, product version, and SDK
2348
+ * runtime version.
2144
2349
  */
2145
2350
  getBaseInfo(): AppBaseInfo;
2146
- /**
2147
- * Follow the host's effective display language.
2148
- * `getBaseInfo().displayLanguage` answers what it is now; this answers when it
2149
- * changes. Logic needs both because the strings it hands to native chrome —
2150
- * navigation bar titles, tab bar labels, modal and action-sheet text — are the
2151
- * app's own, and nothing re-renders them on its behalf.
2152
- */
2153
- onDisplayLanguageChange(callback: (language: string) => void): () => void;
2154
2351
  /**
2155
2352
  * Exit the host app immediately without a confirmation dialog.
2353
+ * Control app only: quitting the product is not an lxapp's decision. Other
2354
+ * lxapps get a permission error.
2156
2355
  * If the user should confirm first, call `lx.showModal(...)` and invoke this
2157
2356
  * only after confirmation.
2158
2357
  */
@@ -2160,8 +2359,9 @@ declare global {
2160
2359
  /**
2161
2360
  * Set the app-icon badge, for example an unread count.
2162
2361
  * This targets the dock on macOS, taskbar on Windows, and home/launcher icon
2163
- * on mobile. Null or an empty string clears it. Unsupported platforms treat
2164
- * the call as a no-op.
2362
+ * on mobile — the product's own icon, not the calling lxapp's, so it is
2363
+ * Control app only and other lxapps get a permission error. Null or an empty
2364
+ * string clears it. Unsupported platforms treat the call as a no-op.
2165
2365
  */
2166
2366
  setBadge(value: string | number | null): void;
2167
2367
  }
@@ -2257,7 +2457,7 @@ declare global {
2257
2457
  onKeyUp(callback: KeyEventCallback): () => void;
2258
2458
  /** Get location function */
2259
2459
  getLocation(options?: GetLocationOptions): Promise<LocationInfo>;
2260
- /** Identify the running lxapp: its id, display name, version, and release type. */
2460
+ /** Identify the running lxapp: its id, display name, version, and channel. */
2261
2461
  getLxAppInfo(): LxAppInfo;
2262
2462
  /** Read an image's dimensions, type, and orientation without decoding it into a view. */
2263
2463
  getImageInfo(options: GetImageInfoOptions): Promise<ImageInfo>;
@@ -2352,7 +2552,6 @@ declare global {
2352
2552
  * an invalid selection.
2353
2553
  */
2354
2554
  showActionSheet(options: ShowActionSheetOptions): Promise<ActionSheetResult>;
2355
- readonly appearance: AppearanceApi;
2356
2555
  /**
2357
2556
  * Shows a confirmation modal.
2358
2557
  * Resolves `{ canceled: false }` when the user confirms and `{ canceled: true }`
@@ -2371,6 +2570,8 @@ declare global {
2371
2570
  * lx.startPullDownRefresh()
2372
2571
  * Programmatically start the pull-to-refresh animation.
2373
2572
  * This will show the refresh indicator and trigger the onPullDownRefresh lifecycle method.
2573
+ * Throws `E_INVALID_STATE` (`data.bizCode === 4004`) unless the current page
2574
+ * config sets `enablePullDownRefresh: true`.
2374
2575
  */
2375
2576
  startPullDownRefresh(): void;
2376
2577
  /**
@@ -2417,7 +2618,7 @@ declare global {
2417
2618
  readonly tray: TrayApi;
2418
2619
  /**
2419
2620
  * Return the callback-based update manager for this lxapp's bundle. This is
2420
- * available to every lxapp and is distinct from the home-only
2621
+ * available to every lxapp and is distinct from the Control-app-only
2421
2622
  * `lx.app.checkUpdate()`, which updates the native host app.
2422
2623
  */
2423
2624
  getUpdateManager(): UpdateManager;
@@ -2439,27 +2640,28 @@ declare global {
2439
2640
  interface ShellApi {
2440
2641
  /**
2441
2642
  * `lx.shell.openApp(appId, options)` — compose another lxapp into a shell
2442
- * slot. Home-lxapp only; the namespace is the privilege.
2643
+ * slot. Control-app only; the namespace is the privilege.
2443
2644
  */
2444
2645
  openApp(appId: string, options: ShellOpenAppOptions): Promise<AppSurface>;
2445
- /** `lx.shell.openBuiltin(page)` — a host builtin page. Home-lxapp only. */
2646
+ /** `lx.shell.openBuiltin(page)` — a host builtin page. Control-app only. */
2446
2647
  openBuiltin(page: BuiltinShellPage): Promise<BuiltinSurface>;
2447
2648
  /**
2448
2649
  * `lx.shell.openDeclared(id, options?)` — the declared surface, plus the
2449
- * keyed multi-instance form and placement overrides. Home-lxapp only.
2650
+ * keyed multi-instance form and placement overrides. Control-app only.
2450
2651
  */
2451
2652
  openDeclared(id: string, options?: ShellOpenDeclaredOptions): Promise<DeclaredSurface>;
2452
2653
  /** `lx.shell.reconfigure(id, patch)` — re-place a live declared surface. */
2453
2654
  reconfigure(id: string, patch: ShellSurfacePatch): Promise<void>;
2655
+ readonly sidebarActions: ShellSidebarActionsApi;
2454
2656
  }
2455
2657
  }
2456
2658
  declare global {
2457
2659
  interface ShellSidebarActionsApi {
2458
2660
  /**
2459
2661
  * Atomically replaces the complete desktop sidebar action declaration. Only the
2460
- * home lxapp may call this API. Ids must be non-empty and unique across both
2662
+ * Control app may call this API. Ids must be non-empty and unique across both
2461
2663
  * placements; header accepts at most two entries. Icons must be bundled relative
2462
- * paths or runtime-managed `lx://` paths accessible to the home lxapp.
2664
+ * paths or runtime-managed `lx://` paths accessible to the Control app.
2463
2665
  * Every entry is bound to its generation-scoped callback. The shell invokes that
2464
2666
  * callback but never infers navigation or selected state. Validation or host
2465
2667
  * projection failure leaves the previous generation active. `replace([])` clears
@@ -2469,21 +2671,21 @@ declare global {
2469
2671
  replace(items: ShellSidebarAction[]): void;
2470
2672
  /**
2471
2673
  * Atomically updates the icon, label, and/or disabled state of one stable id.
2472
- * Only the home lxapp may call this API. The patch must be non-empty; unknown
2674
+ * Only the Control app may call this API. The patch must be non-empty; unknown
2473
2675
  * fields are rejected. The callback and placement stay unchanged. Throws
2474
2676
  * `E_NOT_FOUND` when `id` is not in the current declaration.
2475
2677
  */
2476
2678
  update(id: string, patch: ShellSidebarActionUpdate): void;
2477
2679
  /**
2478
2680
  * Atomically removes one stable id and its generation-scoped callback. Only the
2479
- * home lxapp may call this API. Throws `E_NOT_FOUND` when `id` is not in the
2681
+ * Control app may call this API. Throws `E_NOT_FOUND` when `id` is not in the
2480
2682
  * current declaration.
2481
2683
  */
2482
2684
  remove(id: string): void;
2483
2685
  /**
2484
- * Atomically clears every runtime sidebar action and callback. Only the home
2485
- * lxapp may call this API. Equivalent to `replace([])` and safe when already
2486
- * empty; the home lxapp must still redeclare actions after the next Logic launch.
2686
+ * Atomically clears every runtime sidebar action and callback. Only the
2687
+ * Control app may call this API. Equivalent to `replace([])` and safe when already
2688
+ * empty; the Control app must still redeclare actions after the next Logic launch.
2487
2689
  */
2488
2690
  clear(): void;
2489
2691
  }
@@ -2495,7 +2697,7 @@ declare global {
2495
2697
  * float or a window. A page can never be an aside: asides carry external
2496
2698
  * content only, which is why that member does not exist on this signature.
2497
2699
  */
2498
- openPage(page: string, options?: OpenPageOptions): Promise<PageSurface>;
2700
+ openPage(page: ConfiguredPageName, options?: OpenPageOptions): Promise<PageSurface>;
2499
2701
  /**
2500
2702
  * `lx.surface.openUrl(url, options?)` — external content in the in-app
2501
2703
  * browser, as a tab or docked as an aside.