@glassly/engine 0.3.7-beta.893 → 0.3.7-beta.896

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.
@@ -1,9 +1,9 @@
1
1
  export const ENGINE_RELEASE_METADATA = Object.freeze({
2
2
  "schemaVersion": 1,
3
3
  "familyBaseVersion": "0.3.7",
4
- "releaseIdentity": "0.3.7-beta.893",
5
- "releaseSetId": "glassly-0.3.7-beta.893",
6
- "sourceCommit": "496e2647219771dbe46bd637e26a1c01bfa0e4be",
4
+ "releaseIdentity": "0.3.7-beta.896",
5
+ "releaseSetId": "glassly-0.3.7-beta.896",
6
+ "sourceCommit": "251fd15bfc9bfedd0d7ad78b78bf2843767d80d6",
7
7
  "otaManifestUrl": null,
8
8
  "otaManifestSha256": null
9
9
  });
@@ -1 +1 @@
1
- {"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,uBAAuB,GAAoC,MAAM,CAAC,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,gBAAgB;IACnC,cAAc,EAAE,wBAAwB;IACxC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,IAAI;IACtB,mBAAmB,EAAE,IAAI;CAC1B,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface EngineReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"0.3.7\",\n \"releaseIdentity\": \"0.3.7-beta.893\",\n \"releaseSetId\": \"glassly-0.3.7-beta.893\",\n \"sourceCommit\": \"496e2647219771dbe46bd637e26a1c01bfa0e4be\",\n \"otaManifestUrl\": null,\n \"otaManifestSha256\": null\n})\n"]}
1
+ {"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,uBAAuB,GAAoC,MAAM,CAAC,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,gBAAgB;IACnC,cAAc,EAAE,wBAAwB;IACxC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,IAAI;IACtB,mBAAmB,EAAE,IAAI;CAC1B,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface EngineReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"0.3.7\",\n \"releaseIdentity\": \"0.3.7-beta.896\",\n \"releaseSetId\": \"glassly-0.3.7-beta.896\",\n \"sourceCommit\": \"251fd15bfc9bfedd0d7ad78b78bf2843767d80d6\",\n \"otaManifestUrl\": null,\n \"otaManifestSha256\": null\n})\n"]}
@@ -178,7 +178,8 @@ declare class AppRegistry {
178
178
  uninstall(packageName: string, version?: string): AsyncResult<void, Error>;
179
179
  getPackageNames(): string[];
180
180
  getInstalledVersions(packageName: string): string[];
181
- getActiveVersion(packageName: string): Promise<string>;
181
+ /** Undefined when no bundle is on disk (offline built-ins, HTTP-direct dev apps). */
182
+ getActiveVersion(packageName: string): Promise<string | undefined>;
182
183
  setActiveVersion(packageName: string, version: string): Result<void, Error>;
183
184
  getMetadata(packageName: string, version: string): InstalledInfo;
184
185
  getInstalledInfo(): InstalledLma[];
@@ -1 +1 @@
1
- {"version":3,"file":"AppRegistry.d.ts","sourceRoot":"","sources":["../../src/services/AppRegistry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AppRegistry.d.ts","sourceRoot":"","sources":["../../src/services/AppRegistry.ts"],"names":[],"mappings":"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"}
@@ -593,6 +593,7 @@ class AppRegistry {
593
593
  return [];
594
594
  }
595
595
  }
596
+ /** Undefined when no bundle is on disk (offline built-ins, HTTP-direct dev apps). */
596
597
  async getActiveVersion(packageName) {
597
598
  let versions = this.getInstalledVersions(packageName);
598
599
  // Treat MMKV as a hint, not authority. A stored version may have been
@@ -612,8 +613,11 @@ class AppRegistry {
612
613
  }
613
614
  versions = versions.filter((v) => semver.valid(v));
614
615
  versions.sort((a, b) => semver.rcompare(a, b));
615
- this.setActiveVersion(packageName, versions[0]);
616
- return versions[0];
616
+ const latest = versions[0];
617
+ // Never persist undefined: MMKV.set throws on it.
618
+ if (latest)
619
+ this.setActiveVersion(packageName, latest);
620
+ return latest;
617
621
  }
618
622
  setActiveVersion(packageName, version) {
619
623
  return storage.save(`${packageName}_active_version`, version);
@@ -673,6 +677,9 @@ class AppRegistry {
673
677
  const out = [];
674
678
  for (const lmaInfo of installedInfo) {
675
679
  const versionString = await this.getActiveVersion(lmaInfo.packageName);
680
+ // A package dir with no usable bundle (e.g. only a half-written version) has nothing to run.
681
+ if (!versionString)
682
+ continue;
676
683
  const versionInfo = lmaInfo.versions[versionString];
677
684
  const manifest = this.getMiniappManifest(lmaInfo.packageName, versionString);
678
685
  const permissions = normalizeManifestPermissions(manifest?.permissions);
@@ -1 +1 @@
1
- {"version":3,"file":"AppRegistry.js","sourceRoot":"","sources":["../../src/services/AppRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * AppRegistry — on-disk install/uninstall registry for local miniapps.\n *\n * Owns the `Documents/lmas/<packageName>/<version>/` filesystem layout, the\n * download/unzip pipeline, and the active-version pointer in MMKV. It does\n * NOT touch the apps store directly — instead it notifies subscribers when\n * the install set changes, so the host (mobile manager, OEM app) can refresh\n * its own state.\n *\n * Public surface:\n * - installFromUrl(url, opts?) install/replace a miniapp from a URL\n * - installFromLocalZip(path, opts?) install/replace from a local zip\n * - uninstall(packageName, version?) remove one or all versions\n * - getInstalledMiniapps() ClientApp[] derived from disk\n * - getActiveVersion(packageName) active version string for a package\n * - getBundleDir / getMiniappManifest filesystem helpers used by hosts\n * - subscribe(fn) register a refresh listener\n */\n\nimport {Directory, Paths, File} from \"expo-file-system\"\nimport {unzip} from \"react-native-zip-archive\"\nimport semver from \"semver\"\nimport {AsyncResult, Result, result as Res} from \"typesafe-ts\"\n\nimport type {AppletPermission, AppPermissionType, AppletType, ClientApp, DeclaredWidget} from \"../types/applet\"\nimport {HardwareRequirement, HardwareRequirementLevel, HardwareType} from \"../types\"\nimport {configuredDevHost} from \"../utils/configuredDevHost\"\nimport {storage} from \"../utils/storage/storage\"\nimport {printDirectory} from \"../utils/storage/zip\"\nimport {checkManifestVersions} from \"./manifestVersionGate\"\nimport {normalizeManifestActions, normalizeManifestWidgets} from \"./manifestActions\"\nimport {normalizeManifestTags, normalizeManifestText} from \"./manifestFields\"\nimport {miniappRunningRegistry} from \"./MiniappRunningRegistry\"\n\nexport {normalizeManifestActions, normalizeManifestWidgets} from \"./manifestActions\"\n\nconst ALLOWED_PERMISSION_TYPES: ReadonlySet<AppPermissionType> = new Set<AppPermissionType>([\n \"MICROPHONE\",\n \"CAMERA\",\n \"CALENDAR\",\n \"LOCATION\",\n \"BACKGROUND_LOCATION\",\n \"READ_NOTIFICATIONS\",\n \"DISPLAY_MIRROR\",\n \"POST_NOTIFICATIONS\",\n \"API_KEYS\",\n])\n\n/**\n * Normalize the `permissions` field from a miniapp.json manifest.\n *\n * New miniapps ship `[{type, required?, description?}]` objects. A few older\n * installed bundles may have `[\"MICROPHONE\", ...]` plain strings. Accept both.\n */\nexport function normalizeManifestPermissions(\n raw: Array<string | {type: string; required?: boolean; description?: string}> | undefined,\n): AppletPermission[] {\n if (!Array.isArray(raw)) return []\n const out: AppletPermission[] = []\n for (const p of raw) {\n if (typeof p === \"string\") {\n if (ALLOWED_PERMISSION_TYPES.has(p as AppPermissionType)) {\n out.push({type: p as AppPermissionType, required: true})\n }\n } else if (p && typeof p === \"object\" && typeof p.type === \"string\") {\n if (ALLOWED_PERMISSION_TYPES.has(p.type as AppPermissionType)) {\n out.push({\n type: p.type as AppPermissionType,\n ...(typeof p.required === \"boolean\" ? {required: p.required} : {}),\n ...(typeof p.description === \"string\" ? {description: p.description} : {}),\n })\n }\n }\n }\n return out\n}\n\nfunction normalizeManifestType(raw: unknown): AppletType {\n return raw === \"background\" || raw === \"dashboard\" || raw === \"standard\" ? raw : \"standard\"\n}\n\n/**\n * Convert declared hardwareRequirements from a miniapp.json manifest into\n * runtime `HardwareRequirement[]`, always appending `{EXIST, REQUIRED}` so\n * launchers show \"Glasses Required\" when no glasses are connected.\n *\n * Malformed entries are dropped with a single warning per package so the\n * rest of the manifest still works.\n */\nexport function buildHardwareRequirements(\n raw: Array<{type: string; level: string; description?: string}> | undefined,\n packageName: string,\n): HardwareRequirement[] {\n const out: HardwareRequirement[] = []\n const validTypes = new Set(Object.values(HardwareType) as string[])\n const validLevels = new Set(Object.values(HardwareRequirementLevel) as string[])\n\n if (!Array.isArray(raw)) {\n if (raw !== undefined) {\n console.warn(`APP_REGISTRY: ${packageName} has invalid hardwareRequirements (not an array); treating as []`)\n }\n } else {\n let warned = false\n for (const r of raw) {\n if (\n !r ||\n typeof r !== \"object\" ||\n typeof r.type !== \"string\" ||\n typeof r.level !== \"string\" ||\n !validTypes.has(r.type) ||\n !validLevels.has(r.level)\n ) {\n if (!warned) {\n console.warn(\n `APP_REGISTRY: ${packageName} has malformed hardwareRequirements entry; skipping invalid entries`,\n r,\n )\n warned = true\n }\n continue\n }\n out.push({\n type: r.type as HardwareType,\n level: r.level as HardwareRequirementLevel,\n ...(typeof r.description === \"string\" ? {description: r.description} : {}),\n })\n }\n }\n\n // Always require glasses to be connected for any local miniapp.\n out.push({type: HardwareType.EXIST, level: HardwareRequirementLevel.REQUIRED})\n return out\n}\n\ninterface InstalledInfo {\n name: string\n logoUrl: string\n}\n\ninterface InstalledLma {\n packageName: string\n versions: Record<string, InstalledInfo>\n}\n\nexport interface MiniappReleaseIdentity {\n source: \"direct_download\" | \"bundled_asset\" | \"preinstalled_registry\" | \"dev_snapshot\" | \"store\"\n releaseId?: string\n bundleSha256?: string\n channel?: string\n}\n\nfunction releaseIdentityKey(packageName: string, version: string): string {\n return `miniapp_release_identity:${packageName}:${version}`\n}\n\n/**\n * Download a miniapp zip from `url` into the cache and return its local path.\n *\n * `File.downloadFileAsync` is HTTP(S)-only, so this path is for remote bundles\n * (dev server, store). Bundled-asset installs already have a local zip and\n * should call {@link unpackMiniApp} directly.\n */\nasync function downloadMiniAppZip(url: string): Promise<string> {\n const downloadDir = new Directory(Paths.cache, \"lma_downloads\")\n try {\n if (!downloadDir.exists) {\n downloadDir.create()\n }\n } catch (error) {\n console.error(\"ZIP: Error creating download directory\", error)\n throw \"CREATE_DOWNLOAD_DIR_FAILED\"\n }\n\n // Pre-delete any cached file with the same name. Both `glassly dev`\n // and `glassly release` serve their zip at /bundle.zip, so URLs\n // collide on the cache filename. Without this delete, a stale dev-snapshot\n // (containing the project source tree) gets unzipped instead of the\n // release build → white screen because index.html points at TSX files.\n const targetFileName = url.split(\"/\").pop() ?? \"bundle.zip\"\n const existingFile = new File(downloadDir, targetFileName)\n if (existingFile.exists) {\n try {\n existingFile.delete()\n } catch (e) {\n console.warn(\"ZIP: failed to delete stale cached download:\", e)\n }\n }\n\n try {\n const output = await File.downloadFileAsync(url, downloadDir)\n return output.uri\n } catch (error) {\n console.error(\"ZIP: Error downloading zip file\", error)\n throw \"DOWNLOAD_FAILED\"\n }\n}\n\n/**\n * Unpack a local miniapp zip and install it under\n * `lmas/<packageName>/<version>/`.\n *\n * Zip layout: flat — files at root, `miniapp.json` at the top level. We're\n * strict on shape so we fail loudly on malformed bundles.\n *\n * @param zipPath file:// URI of the zip on local disk.\n * @param versionOverride override the manifest's version field. Used by the\n * dev miniapp caching path which stamps `dev-<ms>`\n * so multiple snapshots can coexist alongside\n * semver-installed versions.\n */\nasync function unpackMiniApp(\n zipPath: string,\n versionOverride?: string,\n): Promise<{packageName: string; version: string}> {\n const unzipDir = new Directory(Paths.cache, \"lma_unzip\")\n try {\n if (unzipDir.exists) unzipDir.delete()\n unzipDir.create()\n } catch (error) {\n console.error(\"ZIP: Error creating or deleting the unzip directory\", error)\n throw \"CREATE_CACHE_DIR_FAILED\"\n }\n\n try {\n console.log(\"ZIP: unzipping\", zipPath)\n await unzip(zipPath, unzipDir.uri)\n } catch (error) {\n console.error(\"Error unzipping zip file\", error)\n throw \"UNZIP_FAILED\"\n }\n\n // Strict zip shape: miniapp.json at unzip root. No tolerance for an\n // enclosing folder or app.json fallback — we own the dev-server emit\n // format, so any deviation indicates a corrupt bundle.\n const appDir = unzipDir\n let packageName: string\n let manifestVersion: string\n try {\n const miniappJsonFile = new File(appDir, \"miniapp.json\")\n if (!miniappJsonFile.exists) throw new Error(\"miniapp.json missing at zip root\")\n const manifest = JSON.parse(miniappJsonFile.textSync())\n if (!manifest.packageName) throw new Error(\"miniapp.json missing packageName\")\n if (!manifest.version) throw new Error(\"miniapp.json missing version\")\n packageName = manifest.packageName\n manifestVersion = manifest.version\n } catch (error) {\n console.error(\"Error reading miniapp.json from zip:\", error)\n throw \"READ_MANIFEST_FAILED\"\n }\n const version = versionOverride ?? manifestVersion\n console.log(`ZIP: installing ${packageName} as version ${version}`)\n\n const basePackageDir = new Directory(Paths.document, \"lmas\", packageName)\n try {\n if (!basePackageDir.exists) {\n basePackageDir.create({intermediates: true})\n }\n } catch (error) {\n console.error(\"Error creating the base package directory\", error)\n throw \"CREATE_PACKAGE_DIR_FAILED\"\n }\n\n const versionDir = new Directory(basePackageDir, version)\n try {\n if (!versionDir.exists) {\n versionDir.create()\n } else {\n versionDir.delete()\n versionDir.create()\n }\n } catch (error) {\n console.error(\"Error creating the version directory\", error)\n throw \"CREATE_VERSION_DIR_FAILED\"\n }\n\n try {\n const contents = appDir.list()\n for (const item of contents) {\n await item.move(versionDir)\n }\n } catch (error) {\n console.error(\"Error moving the contents of the folder to the destination directory\", error)\n throw \"INSTALL_CONTENTS_FAILED\"\n }\n\n console.log(\"ZIP: local mini app installed at\", versionDir.uri)\n printDirectory(versionDir, 2)\n return {packageName, version}\n}\n\n/**\n * Download a miniapp zip from `url`, unpack it, and install it under\n * `lmas/<packageName>/<version>/`. Thin composition of\n * {@link downloadMiniAppZip} + {@link unpackMiniApp} for remote bundles.\n *\n * @param versionOverride override the manifest's version field. Used by the\n * dev miniapp caching path which stamps `dev-<ms>`\n * so multiple snapshots can coexist alongside\n * semver-installed versions.\n */\nasync function downloadAndInstallMiniApp(\n url: string,\n versionOverride?: string,\n): Promise<{packageName: string; version: string}> {\n const downloadedZipPath = await downloadMiniAppZip(url)\n console.log(\"ZIP: done downloading, starting unzip\")\n return unpackMiniApp(downloadedZipPath, versionOverride)\n}\n\ntype Listener = () => void\n\nclass AppRegistry {\n private cachedApps: ClientApp[] = []\n // Offline apps live in a separate layer so they survive the disk-rebuild\n // path in getInstalledMiniapps (which reassigns cachedApps).\n private offlineApps: ClientApp[] = []\n private offlineRunning = new Set<string>()\n /** Package names whose start() requires the on-device STT model (host-declared). */\n private sttModelRequired = new Set<string>()\n private refreshNeeded: boolean = true\n private listeners = new Set<Listener>()\n\n private static instance: AppRegistry | null = null\n\n private constructor() {}\n\n public static getInstance(): AppRegistry {\n if (!AppRegistry.instance) {\n AppRegistry.instance = new AppRegistry()\n }\n return AppRegistry.instance\n }\n\n /** Subscribe to install/uninstall events. Listener fires after refreshNeeded flips. */\n public subscribe(fn: Listener): () => void {\n this.listeners.add(fn)\n return () => {\n this.listeners.delete(fn)\n }\n }\n\n private notify(): void {\n for (const fn of this.listeners) {\n try {\n fn()\n } catch (e) {\n console.warn(\"AppRegistry: listener threw\", e)\n }\n }\n }\n\n /**\n * On-disk path for a given miniapp bundle version.\n */\n public getBundleDir(packageName: string, version: string): string {\n const bundleDir = new Directory(Paths.document, \"lmas\", packageName, version)\n return bundleDir.uri\n }\n\n /**\n * Resolve the two-layer entry paths for an installed miniapp version.\n * Returns absolute file:// URIs for `background` and (when present) `ui`.\n *\n * Legacy single-layer bundles (no `entry` object in manifest) fall back\n * to `index.html` discovery so the WebView host keeps working unchanged.\n * Two-layer bundles ship `entry.background` and optional `entry.ui`\n * paths relative to the bundle root.\n *\n * Returns null if neither shape resolves to existing files on disk.\n */\n public getMiniappEntryPaths(\n packageName: string,\n version: string,\n ): {background: string | null; ui: string | null} | null {\n const manifest = this.getMiniappManifest(packageName, version) as {\n entry?: {background?: string; ui?: string}\n } | null\n const bundleDir = this.getBundleDir(packageName, version)\n const resolve = (rel: string): string | null => {\n const trimmed = rel.replace(/^\\.?\\/+/, \"\")\n const file = new File(bundleDir, trimmed)\n return file.exists ? file.uri : null\n }\n if (manifest?.entry) {\n console.log(\"manifest.entry\", manifest.entry)\n const bg = manifest.entry.background ? resolve(manifest.entry.background) : null\n console.log(\"bg\", bg)\n const ui = manifest.entry.ui ? resolve(manifest.entry.ui) : null\n console.log(\"ui\", ui)\n if (bg || ui) {\n return {background: bg, ui: ui}\n }\n }\n // Legacy single-bundle fallback — `index.html` at the bundle root.\n const legacy = new File(new Directory(bundleDir.replace(/^file:\\/\\//, \"\")), \"index.html\")\n return {\n background: null,\n ui: legacy.exists ? legacy.uri : null,\n }\n }\n\n /**\n * Verify a manifest declares an SDK / host version range compatible\n * with the current host. Delegates to the pure\n * {@link checkManifestVersions} helper — same shape, no React Native\n * imports, unit-testable. Manifests missing either field pass\n * through unchanged (legacy single-layer path).\n */\n public checkManifestVersions(\n manifest: {sdkVersion?: string; minHostVersion?: string} | null,\n options: {hostVersion: string; supportedSdkRange: string},\n ): {ok: true} | {ok: false; reason: string} {\n return checkManifestVersions(manifest, options)\n }\n\n /**\n * Read and parse the miniapp manifest (miniapp.json with app.json fallback)\n * from a given bundle directory.\n */\n public getMiniappManifest(packageName: string, version: string): any {\n const bundleDir = new Directory(Paths.document, \"lmas\", packageName, version)\n try {\n const miniappJsonFile = new File(bundleDir, \"miniapp.json\")\n if (miniappJsonFile.exists) {\n return JSON.parse(miniappJsonFile.textSync())\n }\n } catch (e) {\n console.warn(\"AppRegistry: Error reading miniapp.json, trying app.json fallback\", e)\n }\n try {\n const appJsonFile = new File(bundleDir, \"app.json\")\n if (appJsonFile.exists) {\n return JSON.parse(appJsonFile.textSync())\n }\n } catch (e) {\n console.warn(\"AppRegistry: Error reading app.json fallback\", e)\n }\n return null\n }\n\n /**\n * Download and install a miniapp bundle from a URL. The URL must serve a\n * zip whose root contains `miniapp.json` plus the bundle entry files.\n *\n * @param opts.versionOverride if set, install under this version instead\n * of `manifest.version`. The dev caching path uses `dev-<ms>` so multiple\n * snapshots can coexist alongside semver-installed versions.\n */\n public installFromUrl(\n url: string,\n opts?: {versionOverride?: string; releaseIdentity?: MiniappReleaseIdentity},\n ): AsyncResult<void, Error> {\n return Res.try_async(async () => {\n const {packageName, version} = await downloadAndInstallMiniApp(url, opts?.versionOverride)\n console.log(\"APP_REGISTRY: Downloaded and installed mini app\")\n this.finalizeInstall(\n packageName,\n version,\n opts?.releaseIdentity ?? {source: version.startsWith(\"dev-\") ? \"dev_snapshot\" : \"direct_download\"},\n )\n })\n }\n\n /**\n * Install a miniapp from a zip already on local disk (e.g. a bundled asset\n * copied into cache). Skips the HTTP download path that `installFromUrl`\n * uses — `File.downloadFileAsync` is HTTP(S)-only and rejects file:// URIs.\n *\n * @param zipPath file:// URI of the local zip.\n */\n public installFromLocalZip(\n zipPath: string,\n opts?: {versionOverride?: string; releaseIdentity?: MiniappReleaseIdentity},\n ): AsyncResult<{packageName: string; version: string}, Error> {\n return Res.try_async(async () => {\n const {packageName, version} = await unpackMiniApp(zipPath, opts?.versionOverride)\n console.log(\"APP_REGISTRY: Installed mini app from local zip\")\n this.finalizeInstall(packageName, version, opts?.releaseIdentity ?? {source: \"bundled_asset\"})\n return {packageName, version}\n })\n }\n\n /**\n * Post-install bookkeeping shared by every install path: clear stale dev\n * artifacts on release installs, point the active-version at the just-\n * installed bundle, and notify subscribers to refresh.\n */\n private finalizeInstall(packageName: string, version: string, releaseIdentity: MiniappReleaseIdentity): void {\n // If this is a release install (semver, not dev-*) of a package that\n // currently has dev-* snapshots, clear the dev state so the swap to\n // \"released\" is clean. Otherwise the dev version would keep winning\n // getActiveVersion's dev-precedence rule and the just-installed\n // release wouldn't run.\n const isDevInstall = version.startsWith(\"dev-\")\n if (!isDevInstall) {\n this.clearDevArtifacts(packageName)\n }\n\n this.setActiveVersion(packageName, version)\n storage.save(releaseIdentityKey(packageName, version), releaseIdentity)\n this.refreshNeeded = true\n this.notify()\n }\n\n public getReleaseIdentity(packageName: string, version: string): MiniappReleaseIdentity | null {\n const result = storage.load<MiniappReleaseIdentity>(releaseIdentityKey(packageName, version))\n return result.is_ok() ? result.value : null\n }\n\n public installFromJsonUrl(baseUrl: string): AsyncResult<{packageName: string; version: string; name: string}, Error> {\n return Res.try_async(async () => {\n const trimmed = baseUrl.replace(/\\/$/, \"\")\n\n const manifestRes = await fetch(`${trimmed}/miniapp.json`)\n if (!manifestRes.ok) {\n throw new Error(`Failed to fetch miniapp.json: ${manifestRes.status}`)\n }\n const manifest = (await manifestRes.json()) as Record<string, unknown>\n const packageName = manifest.packageName as string | undefined\n const version = manifest.version as string | undefined\n const name = (manifest.name as string | undefined) ?? packageName ?? \"Mini app\"\n if (!packageName) throw new Error(\"miniapp.json missing packageName\")\n if (!version) throw new Error(\"miniapp.json missing version\")\n\n const installRes = await appRegistry.installFromUrl(`${trimmed}/bundle.zip`)\n if (installRes.is_error()) throw installRes.error\n\n return {packageName, version, name}\n })\n }\n\n /**\n * Drop every dev-* version directory for a package plus ALL dev MMKV keys\n * (URL/port/reachability + the home-tile metadata record). Called on a\n * release install (dev → released transition) and on uninstall, so a dev\n * package leaves nothing behind that `projectDevApps` could re-surface.\n *\n * Dev registrations live under a namespaced id (deriveDevPackageId), so a\n * release install of the MANIFEST package no longer matches them here — the\n * dev tile survives the restart-time auto-installers by construction, and\n * this cleanup fires for the dev tile only via uninstall(itsNamespacedId).\n * (Matching legacy un-namespaced records is still cleaned up, on purpose.)\n */\n private clearDevArtifacts(packageName: string): void {\n try {\n const pkgDir = new Directory(Paths.document, \"lmas\", packageName)\n if (pkgDir.exists) {\n for (const item of pkgDir.list()) {\n if (item instanceof Directory && item.name.startsWith(\"dev-\")) {\n try {\n storage.remove(releaseIdentityKey(packageName, item.name))\n item.delete()\n } catch (e) {\n console.warn(`APP_REGISTRY: failed to delete ${item.name}:`, e)\n }\n }\n }\n }\n } catch (e) {\n console.warn(`APP_REGISTRY: clearDevArtifacts dir scan failed for ${packageName}:`, e)\n }\n storage.remove(`${packageName}_dev_url`)\n storage.remove(`${packageName}_dev_port`)\n storage.remove(`${packageName}_dev_mdns`)\n storage.remove(`${packageName}_dev_last_reachable`)\n // HTTP-direct dev miniapps are indexed by their real package name. A\n // release install/uninstall of that same package should remove only its\n // dev tile; unrelated dev miniapps must remain available.\n if (readDevAppRecord(packageName)) unregisterDevApp(packageName)\n }\n\n /**\n * Garbage-collect older `dev-*` version directories for this package,\n * keeping the latest `keep` (by lexicographic sort, which matches\n * timestamp ordering since dev-<ms> is zero-padded).\n *\n * Only touches `dev-*` versions; semver-installed versions are left alone.\n */\n public gcDevVersions(packageName: string, keep: number): void {\n try {\n const pkgDir = new Directory(Paths.document, \"lmas\", packageName)\n if (!pkgDir.exists) return\n const dirs = pkgDir\n .list()\n .filter((d): d is Directory => d instanceof Directory && d.name.startsWith(\"dev-\"))\n .sort((a, b) => (a.name < b.name ? 1 : -1))\n for (let i = keep; i < dirs.length; i++) {\n try {\n dirs[i].delete()\n } catch (e) {\n console.warn(`APP_REGISTRY: failed to delete ${dirs[i].name}:`, e)\n }\n }\n if (dirs.length > keep) this.refreshNeeded = true\n } catch (e) {\n console.warn(`APP_REGISTRY: gcDevVersions error for ${packageName}:`, e)\n }\n }\n\n public uninstall(packageName: string, version?: string): AsyncResult<void, Error> {\n return Res.try_async(async () => {\n if (version) {\n const lmaDir = new Directory(Paths.document, \"lmas\", packageName, version)\n // Guard exists: a dev miniapp loads over HTTP and has no on-disk dir,\n // so an unconditional delete() would throw and abort the cleanup below.\n if (lmaDir.exists) lmaDir.delete()\n storage.remove(releaseIdentityKey(packageName, version))\n console.log(\"APP_REGISTRY: Uninstalled mini app version\", version)\n const packageDir = new Directory(Paths.document, \"lmas\", packageName)\n if (packageDir.exists && packageDir.list().length === 0) {\n packageDir.delete()\n }\n } else {\n for (const installedVersion of this.getInstalledVersions(packageName)) {\n storage.remove(releaseIdentityKey(packageName, installedVersion))\n }\n const packageDir = new Directory(Paths.document, \"lmas\", packageName)\n if (packageDir.exists) {\n packageDir.delete()\n }\n console.log(\"APP_REGISTRY: Uninstalled all versions of mini app\", packageName)\n }\n // Always clear dev artifacts: for HTTP-direct dev miniapps the tile is\n // backed by storage records (_dev_meta + dev_apps_index), not the disk\n // dir, so without this the projected tile reappears on the next refresh.\n this.clearDevArtifacts(packageName)\n this.refreshNeeded = true\n this.notify()\n })\n }\n\n public getPackageNames(): string[] {\n try {\n const lmasDir = new Directory(Paths.document, \"lmas\")\n if (!lmasDir.exists) return []\n let lmas = lmasDir.list()\n lmas = lmas.filter((lma): lma is Directory => lma instanceof Directory && lma.list().length > 0)\n return lmas.map((lma) => lma.name)\n } catch (error) {\n console.error(\"APP_REGISTRY: Error getting locally installed package names\", error)\n return []\n }\n }\n\n public getInstalledVersions(packageName: string): string[] {\n try {\n const lmaDir = new Directory(Paths.document, \"lmas\", packageName)\n // Not installed yet is an expected state (e.g. preinstall sync probing\n // versions before first install) — return [] without the error noise.\n if (!lmaDir.exists) {\n return []\n }\n const lma = lmaDir.list()\n return lma.map((lma) => lma.name)\n } catch (error) {\n console.error(\"APP_REGISTRY: Error getting local applet versions\", error)\n return []\n }\n }\n\n public async getActiveVersion(packageName: string): Promise<string> {\n let versions = this.getInstalledVersions(packageName)\n // Treat MMKV as a hint, not authority. A stored version may have been\n // GC'd off disk without this pointer being updated.\n let res = storage.load<string>(`${packageName}_active_version`)\n if (res.is_ok() && versions.includes(res.value)) {\n return res.value\n }\n // Dev versions take precedence over semver-installed versions.\n const devVersions = versions\n .filter((v) => v.startsWith(\"dev-\"))\n .sort()\n .reverse()\n if (devVersions.length > 0) {\n this.setActiveVersion(packageName, devVersions[0])\n return devVersions[0]\n }\n versions = versions.filter((v) => semver.valid(v))\n versions.sort((a, b) => semver.rcompare(a, b))\n this.setActiveVersion(packageName, versions[0])\n return versions[0]\n }\n\n public setActiveVersion(packageName: string, version: string): Result<void, Error> {\n return storage.save(`${packageName}_active_version`, version)\n }\n\n public getMetadata(packageName: string, version: string): InstalledInfo {\n try {\n const lmaDir = new Directory(Paths.document, \"lmas\", packageName, version)\n const miniappJsonFile = new File(lmaDir, \"miniapp.json\")\n const manifest = JSON.parse(miniappJsonFile.textSync())\n const logoUrl = new File(lmaDir, \"icon.png\").uri\n return {name: manifest.name, logoUrl: logoUrl}\n } catch (error) {\n console.error(\"APP_REGISTRY: Error getting local miniapp metadata\", error)\n return {name: \"error\", logoUrl: \"\"}\n }\n }\n\n public getInstalledInfo(): InstalledLma[] {\n const packageNames = this.getPackageNames()\n const out: InstalledLma[] = []\n for (const packageName of packageNames) {\n const versionStrings = this.getInstalledVersions(packageName)\n const installedVersion: InstalledLma = {packageName, versions: {}}\n for (const versionString of versionStrings) {\n installedVersion.versions[versionString] = this.getMetadata(packageName, versionString)\n }\n out.push(installedVersion)\n }\n return out\n }\n\n /**\n * Merge disk-derived apps with the projected dev + offline layers,\n * de-duping by packageName. Dev registrations use namespaced ids\n * (deriveDevPackageId), so a dev tile and a real install of the same\n * manifest package coexist as separate tiles; the dedupe below only bites\n * legacy un-namespaced dev records. Native offline apps keep top priority.\n */\n private mergeProjectedApps(diskApps: ClientApp[]): ClientApp[] {\n const offline = this.projectOfflineApps()\n const offlinePackages = new Set(offline.map((app) => app.packageName))\n const dev = this.projectDevApps().filter((app) => !offlinePackages.has(app.packageName))\n const devPackages = new Set(dev.map((app) => app.packageName))\n const installed = diskApps.filter(\n (app) => !offlinePackages.has(app.packageName) && !devPackages.has(app.packageName),\n )\n return [...installed, ...dev, ...offline]\n }\n\n public async getInstalledMiniapps(): Promise<ClientApp[]> {\n if (!this.refreshNeeded && this.cachedApps.length > 0) {\n // Cache hit: re-project running from the registry. The cached array\n // IS the disk-derived truth; running comes from the mount registry.\n return this.mergeProjectedApps(\n this.cachedApps.map((a) => ({\n ...a,\n running: miniappRunningRegistry.has(a.packageName),\n })),\n )\n }\n\n try {\n const installedInfo = this.getInstalledInfo()\n const out: ClientApp[] = []\n for (const lmaInfo of installedInfo) {\n const versionString = await this.getActiveVersion(lmaInfo.packageName)\n const versionInfo = lmaInfo.versions[versionString]\n\n const manifest = this.getMiniappManifest(lmaInfo.packageName, versionString) as {\n permissions?: Array<string | {type: string; required?: boolean; description?: string}>\n hardwareRequirements?: Array<{type: string; level: string; description?: string}>\n type?: string\n alwaysOn?: unknown\n description?: unknown\n tagline?: unknown\n tags?: unknown\n actions?: Array<{\n id?: unknown\n description?: unknown\n parameters?: unknown\n outputSchema?: unknown\n visibility?: unknown\n }>\n widgets?: unknown\n } | null\n\n const permissions = normalizeManifestPermissions(manifest?.permissions)\n const hardwareRequirements = buildHardwareRequirements(manifest?.hardwareRequirements, lmaInfo.packageName)\n const appType = normalizeManifestType(manifest?.type)\n const description = normalizeManifestText(manifest?.description)\n const tagline = normalizeManifestText(manifest?.tagline)\n const tags = normalizeManifestTags(manifest?.tags)\n\n // Declared actions (for session.miniapps.list + invoke gating).\n const actions = normalizeManifestActions(manifest?.actions)\n const widgets = withWidgetExpandChoices(lmaInfo.packageName, normalizeManifestWidgets(manifest?.widgets))\n\n // Dev miniapps live in the same lmas/ tree as installed ones, but\n // their version directory name starts with \"dev-\".\n const isMiniappDev = versionString.startsWith(\"dev-\")\n let devUrl: string | undefined\n if (isMiniappDev) {\n const devUrlRes = storage.load<string>(`${lmaInfo.packageName}_dev_url`)\n if (devUrlRes.is_ok()) devUrl = devUrlRes.value\n }\n\n out.push({\n packageName: lmaInfo.packageName,\n version: versionString,\n running: miniappRunningRegistry.has(lmaInfo.packageName),\n local: true,\n healthy: true,\n loading: false,\n offline: false,\n hidden: false,\n offlineRoute: \"\",\n name: versionInfo.name,\n webviewUrl: \"\",\n logoUrl: versionInfo.logoUrl,\n type: appType,\n alwaysOn: getAlwaysOnOverride(lmaInfo.packageName) ?? manifest?.alwaysOn === true,\n permissions,\n hardwareRequirements,\n ...(description ? {description} : {}),\n ...(tagline ? {tagline} : {}),\n ...(tags.length > 0 ? {tags} : {}),\n // Always project actions (even []) so the invoke gate can enforce\n // declared-action membership unconditionally — an app with no declared\n // actions must reject every invoke, not bypass the check.\n actions,\n ...(widgets.length > 0 ? {widgets} : {}),\n ...(isMiniappDev ? {isMiniappDev: true} : {}),\n ...(devUrl ? {devUrl} : {}),\n })\n }\n\n this.cachedApps = out\n this.refreshNeeded = false\n return this.mergeProjectedApps(this.cachedApps)\n } catch (error) {\n console.error(\"APP_REGISTRY: Error getting local applets\", error)\n return this.mergeProjectedApps(\n this.cachedApps.map((a) => ({\n ...a,\n running: miniappRunningRegistry.has(a.packageName),\n })),\n )\n }\n }\n\n /** Force the next getInstalledMiniapps() to re-derive from disk + records. */\n public markRefreshNeeded(): void {\n this.refreshNeeded = true\n this.notify()\n }\n\n /**\n * Project persisted dev-app metadata records into ClientApp tiles. Dev\n * miniapps aren't installed to disk (they load over HTTP), so they don't\n * appear in the `lmas/` scan — this surfaces them on the home screen so\n * they're re-launchable without re-scanning the QR.\n */\n private projectDevApps(): ClientApp[] {\n return getDevAppRecords().map((rec) => {\n const permissions = normalizeManifestPermissions(rec.permissions)\n const hardwareRequirements = buildHardwareRequirements(rec.hardwareRequirements, rec.packageName)\n return {\n packageName: rec.packageName,\n version: undefined,\n running: miniappRunningRegistry.has(rec.packageName),\n local: true,\n healthy: true,\n loading: false,\n offline: false,\n hidden: false,\n offlineRoute: \"\",\n name: rec.name,\n webviewUrl: \"\",\n logoUrl: rec.iconUrl,\n type: normalizeManifestType(rec.type),\n permissions,\n hardwareRequirements,\n actions: normalizeManifestActions(rec.actions),\n ...(normalizeManifestWidgets(rec.widgets).length > 0\n ? {widgets: withWidgetExpandChoices(rec.packageName, normalizeManifestWidgets(rec.widgets))}\n : {}),\n isMiniappDev: true,\n devUrl: rec.devUrl,\n devPort: rec.devPort,\n }\n })\n }\n\n private projectOfflineApps(): ClientApp[] {\n // Offline apps don't go through miniappRunningRegistry (that's for\n // MiniappHost-mounted webviews). Their running flag lives in\n // `offlineRunning` for this process only — read it back here so refreshes\n // don't blow away the active flag, while a relaunch starts them stopped.\n return this.offlineApps.map((a) => {\n const running = this.offlineRunning.has(a.packageName)\n const screenshot = getLocalAppScreenshot(a.packageName)\n\n return {...a, running, screenshot}\n })\n }\n\n // Register an offline (locally-routed) app. Survives disk rebuilds.\n public installOfflineApp(app: ClientApp, opts?: {requiresLocalSttModel?: boolean}): void {\n if (opts?.requiresLocalSttModel) {\n this.sttModelRequired.add(app.packageName)\n }\n this.offlineApps.push({\n ...app,\n onStart: () => {\n this.offlineRunning.add(app.packageName)\n app.onStart?.()\n },\n onStop: () => {\n this.offlineRunning.delete(app.packageName)\n app.onStop?.()\n },\n })\n this.refreshNeeded = true\n this.notify()\n }\n\n /**\n * Update whether a registered offline app is projected into launcher UIs.\n *\n * Offline apps are registered once at host startup, so settings-backed\n * visibility changes need to update the projection without reinstalling or\n * duplicating the app. No-op when the app is missing or already matches.\n */\n public setOfflineAppHidden(packageName: string, hidden: boolean): void {\n const app = this.offlineApps.find((candidate) => candidate.packageName === packageName)\n if (!app || app.hidden === hidden) return\n\n app.hidden = hidden\n this.refreshNeeded = true\n this.notify()\n }\n\n /**\n * Registered as needing the on-device STT model before it can start (the\n * host declares this per offline app; the apps store gates start() on it).\n */\n public requiresLocalSttModel(packageName: string): boolean {\n return this.sttModelRequired.has(packageName)\n }\n\n public getMiniappHtml(packageName: string, version: string): Result<string, Error> {\n return Res.try(() => {\n const lmaDir = new Directory(Paths.document, \"lmas\", packageName, version)\n const htmlFile = new File(lmaDir, \"index.html\")\n return htmlFile.textSync()\n })\n }\n}\n\n/** The wearer's Always On choice for a miniapp, beside the `_hidden` flag; null when they never chose. */\nexport function getAlwaysOnOverride(packageName: string): boolean | null {\n const res = storage.load<boolean>(`${packageName}_always_on`)\n return res.is_ok() ? res.value : null\n}\n\nexport function saveAlwaysOnOverride(packageName: string, status: boolean): void {\n storage.save(`${packageName}_always_on`, status)\n}\n\n/** Applies the wearer's tap-to-expand choice to each expandable widget; expansion is on until they turn it off. */\nexport function withWidgetExpandChoices(packageName: string, widgets: DeclaredWidget[]): DeclaredWidget[] {\n return widgets.map((widget) => {\n if (!widget.expandable) return widget\n const res = storage.load<boolean>(`${packageName}_widget_expand_${widget.id}`)\n return {...widget, expandOnTap: res.is_ok() ? res.value !== false : true}\n })\n}\n\nexport function saveWidgetExpandChoice(packageName: string, widgetId: string, expandOnTap: boolean): void {\n storage.save(`${packageName}_widget_expand_${widgetId}`, expandOnTap)\n}\n\nexport function getLocalAppScreenshot(packageName: string): string | undefined {\n const key = `${packageName}_screenshot`\n const res = storage.load<string>(key)\n if (res.is_error()) return undefined\n\n const uri = res.value\n if (uri.startsWith(\"file://\")) {\n try {\n if (!new File(uri).exists) {\n storage.remove(key)\n return undefined\n }\n } catch {\n storage.remove(key)\n return undefined\n }\n }\n\n return uri\n}\n\n/**\n * Persisted metadata for a dev miniapp's home tile.\n *\n * Dev miniapps load directly off the dev server over HTTP and are NOT\n * installed into `lmas/`, so the disk scan in `getInstalledMiniapps` can't\n * see them. We persist a tiny record at scan / dev-URL-entry time so the\n * tile survives across app launches and is re-launchable without re-scanning.\n * `permissions` / `hardwareRequirements` are snapshotted from the manifest so\n * the home-screen permission gate has data without a disk bundle.\n */\nexport interface DevAppRecord {\n packageName: string\n name: string\n iconUrl: string\n devUrl: string\n devPort?: number\n /**\n * Bonjour / mDNS hostname from the QR (`ComputerName.local`). Used as a\n * failover host when the raw LAN IP in `devUrl` goes stale after a Wi-Fi\n * change — phones that resolve `.local` can relaunch without re-scanning.\n */\n mdnsHost?: string\n type?: AppletType\n permissions?: Array<string | {type: string; required?: boolean; description?: string}>\n hardwareRequirements?: Array<{type: string; level: string; description?: string}>\n /** Manifest-declared actions — so dev-sideloaded miniapps can be invoked too. */\n actions?: Array<{\n id?: unknown\n description?: unknown\n parameters?: unknown\n outputSchema?: unknown\n visibility?: unknown\n }>\n /** Manifest-declared dashboard widgets. */\n widgets?: unknown\n /** Legacy single-slot migration field. New records use the real packageName directly. */\n sourcePackageName?: string\n /**\n * Short-lived Core-verifiable proof emitted by `glassly dev`. This lets the\n * dev runtime request auto-auth for the manifest package without letting\n * arbitrary dev URLs claim any package name.\n */\n devAttestation?: string\n}\n\nconst DEV_APPS_INDEX_KEY = \"dev_apps_index\"\nconst DEV_APP_ICONS_DIR = \"dev-miniapp-icons\"\n\nfunction isPrivateLanHost(hostname: string): boolean {\n return (\n hostname === \"localhost\" ||\n hostname.startsWith(\"192.168.\") ||\n hostname.startsWith(\"10.\") ||\n /^172\\.(1[6-9]|2\\d|3[0-1])\\./.test(hostname)\n )\n}\n\nfunction rewriteStaleDevUrl(value: string): string {\n if (!__DEV__) return value\n const host = configuredDevHost()\n if (!host) return value\n\n try {\n const url = new URL(value)\n if (url.hostname === host || !isPrivateLanHost(url.hostname)) return value\n url.hostname = host\n return url.toString().replace(/\\/$/, \"\")\n } catch {\n return value\n }\n}\n\nfunction normalizeDevAppRecord(record: DevAppRecord): DevAppRecord {\n const devUrl = rewriteStaleDevUrl(record.devUrl)\n const iconUrl = rewriteStaleDevUrl(record.iconUrl)\n return devUrl === record.devUrl && iconUrl === record.iconUrl ? record : {...record, devUrl, iconUrl}\n}\n\n/** Legacy package used by builds that supported only one dev miniapp. */\nexport const DEV_APP_PACKAGE_NAME = \"com.dev\"\nexport const DEV_APP_NAME = \"Dev\"\n\n/**\n * Copy a dev-server icon into Documents so the tile remains branded after the\n * laptop/server disappears. A failed download is non-fatal: the remote URL is\n * retained and can still render while the server is reachable.\n */\nasync function cacheDevAppIcon(packageName: string, iconUrl: string): Promise<string> {\n if (!/^https?:\\/\\//.test(iconUrl)) return iconUrl\n\n try {\n const dir = new Directory(Paths.document, DEV_APP_ICONS_DIR)\n if (!dir.exists) dir.create({intermediates: true})\n\n const safePackageName = packageName.replace(/[^a-zA-Z0-9._-]/g, \"_\")\n let extension = \".png\"\n try {\n const match = new URL(iconUrl).pathname.match(/\\.(png|jpe?g|webp|gif|svg)$/i)\n if (match) extension = `.${match[1].toLowerCase()}`\n } catch {\n // Keep the decoder-friendly .png fallback; image loaders sniff content.\n }\n\n // Image loaders cache file:// URIs too. Replacing bytes at the same path\n // leaves the old decoded icon visible after rescanning the development QR.\n const revision = `${Date.now()}-${Math.random().toString(36).slice(2)}`\n const target = new File(dir, `${safePackageName}.${revision}${extension}`)\n const downloaded = await File.downloadFileAsync(iconUrl, target, {idempotent: true})\n\n // Only remove older extensions AFTER the replacement is safely on disk;\n // a broken icon URL must not destroy the last known-good cached logo.\n for (const item of dir.list()) {\n if (item instanceof File && item.uri !== downloaded.uri && item.name.startsWith(`${safePackageName}.`)) {\n try {\n item.delete()\n } catch {\n // Best effort; the current icon has already been persisted.\n }\n }\n }\n return downloaded.uri\n } catch (error) {\n console.warn(`APP_REGISTRY: failed to cache dev icon for ${packageName}:`, error)\n return readDevAppRecord(packageName)?.iconUrl ?? iconUrl\n }\n}\n\nfunction removeDevRecordKeys(packageName: string): void {\n const existing = readDevAppRecord(packageName)\n if (existing?.iconUrl.startsWith(\"file://\")) {\n try {\n const icon = new File(existing.iconUrl)\n if (icon.exists) icon.delete()\n } catch (error) {\n console.warn(`APP_REGISTRY: failed to delete dev icon for ${packageName}:`, error)\n }\n }\n storage.remove(`${packageName}_dev_meta`)\n storage.remove(`${packageName}_dev_url`)\n storage.remove(`${packageName}_dev_port`)\n storage.remove(`${packageName}_dev_mdns`)\n storage.remove(`${packageName}_dev_last_reachable`)\n}\n\nfunction readDevAppRecord(packageName: string): DevAppRecord | null {\n const res = storage.load<string>(`${packageName}_dev_meta`)\n if (!res.is_ok()) return null\n try {\n return JSON.parse(res.value) as DevAppRecord\n } catch {\n return null\n }\n}\n\n/** Move the historical `com.dev` record onto its real manifest package key. */\nfunction migrateLegacyDevSlot(): void {\n const legacy = readDevAppRecord(DEV_APP_PACKAGE_NAME)\n const targetPackage = legacy?.sourcePackageName?.trim()\n if (!legacy || !targetPackage || targetPackage === DEV_APP_PACKAGE_NAME) return\n\n const existingTarget = readDevAppRecord(targetPackage)\n const migrated: DevAppRecord = existingTarget ?? {\n ...legacy,\n packageName: targetPackage,\n sourcePackageName: targetPackage,\n }\n if (!existingTarget) storage.save(`${targetPackage}_dev_meta`, JSON.stringify(migrated))\n\n const legacyUrl = storage.load<string>(`${DEV_APP_PACKAGE_NAME}_dev_url`)\n const targetUrl = storage.load<string>(`${targetPackage}_dev_url`)\n if (!targetUrl.is_ok()) {\n storage.save(`${targetPackage}_dev_url`, legacyUrl.is_ok() ? legacyUrl.value : migrated.devUrl)\n }\n const legacyPort = storage.load<number>(`${DEV_APP_PACKAGE_NAME}_dev_port`)\n const targetPort = storage.load<number>(`${targetPackage}_dev_port`)\n if (!targetPort.is_ok()) {\n const port = migrated.devPort ?? (legacyPort.is_ok() ? legacyPort.value : undefined)\n if (typeof port === \"number\" && Number.isFinite(port)) storage.save(`${targetPackage}_dev_port`, port)\n }\n const legacyMdns = storage.load<string>(`${DEV_APP_PACKAGE_NAME}_dev_mdns`)\n const targetMdns = storage.load<string>(`${targetPackage}_dev_mdns`)\n if (!targetMdns.is_ok() && legacyMdns.is_ok() && legacyMdns.value.trim()) {\n storage.save(`${targetPackage}_dev_mdns`, legacyMdns.value.trim())\n }\n\n storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_meta`)\n storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_url`)\n storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_port`)\n storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_mdns`)\n storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_last_reachable`)\n\n const index = Array.from(new Set(getDevAppIndex().map((pkg) => (pkg === DEV_APP_PACKAGE_NAME ? targetPackage : pkg))))\n storage.save(DEV_APPS_INDEX_KEY, JSON.stringify(index))\n}\n\nfunction readStoredMdnsHost(packageName: string): string | undefined {\n const res = storage.load<string>(`${packageName}_dev_mdns`)\n if (!res.is_ok()) return undefined\n return res.value.trim() || undefined\n}\n\n/**\n * Namespace a dev registration's package id so it can never collide with a\n * real install of the same manifest package. Without this, the restart-time\n * auto-installers (bundled assets in MantleManager, the preinstalled\n * registry sync) treat their release install of the manifest package as a\n * dev→released transition and wipe the dev registration via\n * clearDevArtifacts — scanning a QR for a fork of a bundled miniapp lost the\n * dev tile on every app restart. Idempotent: an already-namespaced id passes\n * through unchanged, so re-deriving at call sites is safe.\n */\nexport function deriveDevPackageId(packageName: string): string {\n const pkg = packageName.trim()\n return pkg.endsWith(\".dev\") ? pkg : `${pkg}.dev`\n}\n\n/**\n * Register or update one dev miniapp. Records are keyed by the NAMESPACED id\n * (deriveDevPackageId), not the manifest package, so a dev tile coexists\n * with a real install of the same app and survives the auto-installers;\n * `sourcePackageName` keeps the manifest package for attestation/source\n * lookups. Different packages coexist; rescanning the same package updates\n * its record in place. Returns the stored record — its `packageName` is the\n * derived id callers must use for stop/foreground/navigation.\n */\nexport async function registerDevApp(record: DevAppRecord): Promise<DevAppRecord> {\n migrateLegacyDevSlot()\n const rawPackageName = record.packageName.trim()\n if (!rawPackageName) throw new Error(\"Dev miniapp manifest is missing packageName\")\n const packageName = deriveDevPackageId(rawPackageName)\n const sourcePackageName = rawPackageName.endsWith(\".dev\") ? rawPackageName.slice(0, -\".dev\".length) : rawPackageName\n\n const iconUrl = await cacheDevAppIcon(packageName, record.iconUrl)\n // Relaunch paths (developer-URL screen, loadDevMiniapp) omit mdnsHost, so an\n // omitted field keeps whatever the QR scan stored instead of wiping the\n // `.local` failover host.\n const mdnsHost = record.mdnsHost !== undefined ? record.mdnsHost.trim() || undefined : readStoredMdnsHost(packageName)\n const devRecord: DevAppRecord = {\n ...record,\n packageName,\n sourcePackageName,\n name: record.name || DEV_APP_NAME,\n iconUrl,\n mdnsHost,\n }\n storage.save(`${packageName}_dev_meta`, JSON.stringify(devRecord))\n storage.save(`${packageName}_dev_url`, record.devUrl)\n if (typeof record.devPort === \"number\" && Number.isFinite(record.devPort)) {\n storage.save(`${packageName}_dev_port`, record.devPort)\n } else {\n storage.remove(`${packageName}_dev_port`)\n }\n if (mdnsHost) {\n storage.save(`${packageName}_dev_mdns`, mdnsHost)\n } else {\n storage.remove(`${packageName}_dev_mdns`)\n }\n const idx = getDevAppIndex()\n if (!idx.includes(packageName)) {\n idx.push(packageName)\n storage.save(DEV_APPS_INDEX_KEY, JSON.stringify(idx))\n }\n appRegistry.markRefreshNeeded()\n return devRecord\n}\n\n/** Drop one dev miniapp's metadata, routing keys, and cached icon. */\nexport function unregisterDevApp(packageName = DEV_APP_PACKAGE_NAME): void {\n removeDevRecordKeys(packageName)\n const idx = getDevAppIndex().filter((p) => p !== packageName)\n storage.save(DEV_APPS_INDEX_KEY, JSON.stringify(idx))\n appRegistry.markRefreshNeeded()\n}\n\nfunction getDevAppIndex(): string[] {\n const res = storage.load<string>(DEV_APPS_INDEX_KEY)\n if (!res.is_ok()) return []\n try {\n const parsed = JSON.parse(res.value)\n return Array.isArray(parsed) ? (parsed as string[]) : []\n } catch {\n return []\n }\n}\n\n/** Resolve the manifest package for a dev runtime (including the legacy slot). */\nexport function getDevAppSourcePackage(packageName = DEV_APP_PACKAGE_NAME): string | null {\n migrateLegacyDevSlot()\n const rec = readDevAppRecord(packageName)\n return rec?.sourcePackageName ?? rec?.packageName ?? null\n}\n\nexport function getDevAppAttestation(packageName = DEV_APP_PACKAGE_NAME): string | null {\n migrateLegacyDevSlot()\n return readDevAppRecord(packageName)?.devAttestation ?? null\n}\n\nexport function getDevAppRecords(): DevAppRecord[] {\n migrateLegacyDevSlot()\n const out: DevAppRecord[] = []\n for (const pkg of getDevAppIndex()) {\n const res = storage.load<string>(`${pkg}_dev_meta`)\n if (!res.is_ok()) continue\n try {\n const record = JSON.parse(res.value) as DevAppRecord\n const normalized = normalizeDevAppRecord(record)\n if (normalized !== record) {\n storage.save(`${pkg}_dev_meta`, JSON.stringify(normalized))\n storage.save(`${pkg}_dev_url`, normalized.devUrl)\n }\n out.push(normalized)\n } catch {\n /* corrupt record — skip */\n }\n }\n return out\n}\n\nconst appRegistry = AppRegistry.getInstance()\nexport default appRegistry\n"]}
1
+ {"version":3,"file":"AppRegistry.js","sourceRoot":"","sources":["../../src/services/AppRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * AppRegistry — on-disk install/uninstall registry for local miniapps.\n *\n * Owns the `Documents/lmas/<packageName>/<version>/` filesystem layout, the\n * download/unzip pipeline, and the active-version pointer in MMKV. It does\n * NOT touch the apps store directly — instead it notifies subscribers when\n * the install set changes, so the host (mobile manager, OEM app) can refresh\n * its own state.\n *\n * Public surface:\n * - installFromUrl(url, opts?) install/replace a miniapp from a URL\n * - installFromLocalZip(path, opts?) install/replace from a local zip\n * - uninstall(packageName, version?) remove one or all versions\n * - getInstalledMiniapps() ClientApp[] derived from disk\n * - getActiveVersion(packageName) active version string for a package\n * - getBundleDir / getMiniappManifest filesystem helpers used by hosts\n * - subscribe(fn) register a refresh listener\n */\n\nimport {Directory, Paths, File} from \"expo-file-system\"\nimport {unzip} from \"react-native-zip-archive\"\nimport semver from \"semver\"\nimport {AsyncResult, Result, result as Res} from \"typesafe-ts\"\n\nimport type {AppletPermission, AppPermissionType, AppletType, ClientApp, DeclaredWidget} from \"../types/applet\"\nimport {HardwareRequirement, HardwareRequirementLevel, HardwareType} from \"../types\"\nimport {configuredDevHost} from \"../utils/configuredDevHost\"\nimport {storage} from \"../utils/storage/storage\"\nimport {printDirectory} from \"../utils/storage/zip\"\nimport {checkManifestVersions} from \"./manifestVersionGate\"\nimport {normalizeManifestActions, normalizeManifestWidgets} from \"./manifestActions\"\nimport {normalizeManifestTags, normalizeManifestText} from \"./manifestFields\"\nimport {miniappRunningRegistry} from \"./MiniappRunningRegistry\"\n\nexport {normalizeManifestActions, normalizeManifestWidgets} from \"./manifestActions\"\n\nconst ALLOWED_PERMISSION_TYPES: ReadonlySet<AppPermissionType> = new Set<AppPermissionType>([\n \"MICROPHONE\",\n \"CAMERA\",\n \"CALENDAR\",\n \"LOCATION\",\n \"BACKGROUND_LOCATION\",\n \"READ_NOTIFICATIONS\",\n \"DISPLAY_MIRROR\",\n \"POST_NOTIFICATIONS\",\n \"API_KEYS\",\n])\n\n/**\n * Normalize the `permissions` field from a miniapp.json manifest.\n *\n * New miniapps ship `[{type, required?, description?}]` objects. A few older\n * installed bundles may have `[\"MICROPHONE\", ...]` plain strings. Accept both.\n */\nexport function normalizeManifestPermissions(\n raw: Array<string | {type: string; required?: boolean; description?: string}> | undefined,\n): AppletPermission[] {\n if (!Array.isArray(raw)) return []\n const out: AppletPermission[] = []\n for (const p of raw) {\n if (typeof p === \"string\") {\n if (ALLOWED_PERMISSION_TYPES.has(p as AppPermissionType)) {\n out.push({type: p as AppPermissionType, required: true})\n }\n } else if (p && typeof p === \"object\" && typeof p.type === \"string\") {\n if (ALLOWED_PERMISSION_TYPES.has(p.type as AppPermissionType)) {\n out.push({\n type: p.type as AppPermissionType,\n ...(typeof p.required === \"boolean\" ? {required: p.required} : {}),\n ...(typeof p.description === \"string\" ? {description: p.description} : {}),\n })\n }\n }\n }\n return out\n}\n\nfunction normalizeManifestType(raw: unknown): AppletType {\n return raw === \"background\" || raw === \"dashboard\" || raw === \"standard\" ? raw : \"standard\"\n}\n\n/**\n * Convert declared hardwareRequirements from a miniapp.json manifest into\n * runtime `HardwareRequirement[]`, always appending `{EXIST, REQUIRED}` so\n * launchers show \"Glasses Required\" when no glasses are connected.\n *\n * Malformed entries are dropped with a single warning per package so the\n * rest of the manifest still works.\n */\nexport function buildHardwareRequirements(\n raw: Array<{type: string; level: string; description?: string}> | undefined,\n packageName: string,\n): HardwareRequirement[] {\n const out: HardwareRequirement[] = []\n const validTypes = new Set(Object.values(HardwareType) as string[])\n const validLevels = new Set(Object.values(HardwareRequirementLevel) as string[])\n\n if (!Array.isArray(raw)) {\n if (raw !== undefined) {\n console.warn(`APP_REGISTRY: ${packageName} has invalid hardwareRequirements (not an array); treating as []`)\n }\n } else {\n let warned = false\n for (const r of raw) {\n if (\n !r ||\n typeof r !== \"object\" ||\n typeof r.type !== \"string\" ||\n typeof r.level !== \"string\" ||\n !validTypes.has(r.type) ||\n !validLevels.has(r.level)\n ) {\n if (!warned) {\n console.warn(\n `APP_REGISTRY: ${packageName} has malformed hardwareRequirements entry; skipping invalid entries`,\n r,\n )\n warned = true\n }\n continue\n }\n out.push({\n type: r.type as HardwareType,\n level: r.level as HardwareRequirementLevel,\n ...(typeof r.description === \"string\" ? {description: r.description} : {}),\n })\n }\n }\n\n // Always require glasses to be connected for any local miniapp.\n out.push({type: HardwareType.EXIST, level: HardwareRequirementLevel.REQUIRED})\n return out\n}\n\ninterface InstalledInfo {\n name: string\n logoUrl: string\n}\n\ninterface InstalledLma {\n packageName: string\n versions: Record<string, InstalledInfo>\n}\n\nexport interface MiniappReleaseIdentity {\n source: \"direct_download\" | \"bundled_asset\" | \"preinstalled_registry\" | \"dev_snapshot\" | \"store\"\n releaseId?: string\n bundleSha256?: string\n channel?: string\n}\n\nfunction releaseIdentityKey(packageName: string, version: string): string {\n return `miniapp_release_identity:${packageName}:${version}`\n}\n\n/**\n * Download a miniapp zip from `url` into the cache and return its local path.\n *\n * `File.downloadFileAsync` is HTTP(S)-only, so this path is for remote bundles\n * (dev server, store). Bundled-asset installs already have a local zip and\n * should call {@link unpackMiniApp} directly.\n */\nasync function downloadMiniAppZip(url: string): Promise<string> {\n const downloadDir = new Directory(Paths.cache, \"lma_downloads\")\n try {\n if (!downloadDir.exists) {\n downloadDir.create()\n }\n } catch (error) {\n console.error(\"ZIP: Error creating download directory\", error)\n throw \"CREATE_DOWNLOAD_DIR_FAILED\"\n }\n\n // Pre-delete any cached file with the same name. Both `glassly dev`\n // and `glassly release` serve their zip at /bundle.zip, so URLs\n // collide on the cache filename. Without this delete, a stale dev-snapshot\n // (containing the project source tree) gets unzipped instead of the\n // release build → white screen because index.html points at TSX files.\n const targetFileName = url.split(\"/\").pop() ?? \"bundle.zip\"\n const existingFile = new File(downloadDir, targetFileName)\n if (existingFile.exists) {\n try {\n existingFile.delete()\n } catch (e) {\n console.warn(\"ZIP: failed to delete stale cached download:\", e)\n }\n }\n\n try {\n const output = await File.downloadFileAsync(url, downloadDir)\n return output.uri\n } catch (error) {\n console.error(\"ZIP: Error downloading zip file\", error)\n throw \"DOWNLOAD_FAILED\"\n }\n}\n\n/**\n * Unpack a local miniapp zip and install it under\n * `lmas/<packageName>/<version>/`.\n *\n * Zip layout: flat — files at root, `miniapp.json` at the top level. We're\n * strict on shape so we fail loudly on malformed bundles.\n *\n * @param zipPath file:// URI of the zip on local disk.\n * @param versionOverride override the manifest's version field. Used by the\n * dev miniapp caching path which stamps `dev-<ms>`\n * so multiple snapshots can coexist alongside\n * semver-installed versions.\n */\nasync function unpackMiniApp(\n zipPath: string,\n versionOverride?: string,\n): Promise<{packageName: string; version: string}> {\n const unzipDir = new Directory(Paths.cache, \"lma_unzip\")\n try {\n if (unzipDir.exists) unzipDir.delete()\n unzipDir.create()\n } catch (error) {\n console.error(\"ZIP: Error creating or deleting the unzip directory\", error)\n throw \"CREATE_CACHE_DIR_FAILED\"\n }\n\n try {\n console.log(\"ZIP: unzipping\", zipPath)\n await unzip(zipPath, unzipDir.uri)\n } catch (error) {\n console.error(\"Error unzipping zip file\", error)\n throw \"UNZIP_FAILED\"\n }\n\n // Strict zip shape: miniapp.json at unzip root. No tolerance for an\n // enclosing folder or app.json fallback — we own the dev-server emit\n // format, so any deviation indicates a corrupt bundle.\n const appDir = unzipDir\n let packageName: string\n let manifestVersion: string\n try {\n const miniappJsonFile = new File(appDir, \"miniapp.json\")\n if (!miniappJsonFile.exists) throw new Error(\"miniapp.json missing at zip root\")\n const manifest = JSON.parse(miniappJsonFile.textSync())\n if (!manifest.packageName) throw new Error(\"miniapp.json missing packageName\")\n if (!manifest.version) throw new Error(\"miniapp.json missing version\")\n packageName = manifest.packageName\n manifestVersion = manifest.version\n } catch (error) {\n console.error(\"Error reading miniapp.json from zip:\", error)\n throw \"READ_MANIFEST_FAILED\"\n }\n const version = versionOverride ?? manifestVersion\n console.log(`ZIP: installing ${packageName} as version ${version}`)\n\n const basePackageDir = new Directory(Paths.document, \"lmas\", packageName)\n try {\n if (!basePackageDir.exists) {\n basePackageDir.create({intermediates: true})\n }\n } catch (error) {\n console.error(\"Error creating the base package directory\", error)\n throw \"CREATE_PACKAGE_DIR_FAILED\"\n }\n\n const versionDir = new Directory(basePackageDir, version)\n try {\n if (!versionDir.exists) {\n versionDir.create()\n } else {\n versionDir.delete()\n versionDir.create()\n }\n } catch (error) {\n console.error(\"Error creating the version directory\", error)\n throw \"CREATE_VERSION_DIR_FAILED\"\n }\n\n try {\n const contents = appDir.list()\n for (const item of contents) {\n await item.move(versionDir)\n }\n } catch (error) {\n console.error(\"Error moving the contents of the folder to the destination directory\", error)\n throw \"INSTALL_CONTENTS_FAILED\"\n }\n\n console.log(\"ZIP: local mini app installed at\", versionDir.uri)\n printDirectory(versionDir, 2)\n return {packageName, version}\n}\n\n/**\n * Download a miniapp zip from `url`, unpack it, and install it under\n * `lmas/<packageName>/<version>/`. Thin composition of\n * {@link downloadMiniAppZip} + {@link unpackMiniApp} for remote bundles.\n *\n * @param versionOverride override the manifest's version field. Used by the\n * dev miniapp caching path which stamps `dev-<ms>`\n * so multiple snapshots can coexist alongside\n * semver-installed versions.\n */\nasync function downloadAndInstallMiniApp(\n url: string,\n versionOverride?: string,\n): Promise<{packageName: string; version: string}> {\n const downloadedZipPath = await downloadMiniAppZip(url)\n console.log(\"ZIP: done downloading, starting unzip\")\n return unpackMiniApp(downloadedZipPath, versionOverride)\n}\n\ntype Listener = () => void\n\nclass AppRegistry {\n private cachedApps: ClientApp[] = []\n // Offline apps live in a separate layer so they survive the disk-rebuild\n // path in getInstalledMiniapps (which reassigns cachedApps).\n private offlineApps: ClientApp[] = []\n private offlineRunning = new Set<string>()\n /** Package names whose start() requires the on-device STT model (host-declared). */\n private sttModelRequired = new Set<string>()\n private refreshNeeded: boolean = true\n private listeners = new Set<Listener>()\n\n private static instance: AppRegistry | null = null\n\n private constructor() {}\n\n public static getInstance(): AppRegistry {\n if (!AppRegistry.instance) {\n AppRegistry.instance = new AppRegistry()\n }\n return AppRegistry.instance\n }\n\n /** Subscribe to install/uninstall events. Listener fires after refreshNeeded flips. */\n public subscribe(fn: Listener): () => void {\n this.listeners.add(fn)\n return () => {\n this.listeners.delete(fn)\n }\n }\n\n private notify(): void {\n for (const fn of this.listeners) {\n try {\n fn()\n } catch (e) {\n console.warn(\"AppRegistry: listener threw\", e)\n }\n }\n }\n\n /**\n * On-disk path for a given miniapp bundle version.\n */\n public getBundleDir(packageName: string, version: string): string {\n const bundleDir = new Directory(Paths.document, \"lmas\", packageName, version)\n return bundleDir.uri\n }\n\n /**\n * Resolve the two-layer entry paths for an installed miniapp version.\n * Returns absolute file:// URIs for `background` and (when present) `ui`.\n *\n * Legacy single-layer bundles (no `entry` object in manifest) fall back\n * to `index.html` discovery so the WebView host keeps working unchanged.\n * Two-layer bundles ship `entry.background` and optional `entry.ui`\n * paths relative to the bundle root.\n *\n * Returns null if neither shape resolves to existing files on disk.\n */\n public getMiniappEntryPaths(\n packageName: string,\n version: string,\n ): {background: string | null; ui: string | null} | null {\n const manifest = this.getMiniappManifest(packageName, version) as {\n entry?: {background?: string; ui?: string}\n } | null\n const bundleDir = this.getBundleDir(packageName, version)\n const resolve = (rel: string): string | null => {\n const trimmed = rel.replace(/^\\.?\\/+/, \"\")\n const file = new File(bundleDir, trimmed)\n return file.exists ? file.uri : null\n }\n if (manifest?.entry) {\n console.log(\"manifest.entry\", manifest.entry)\n const bg = manifest.entry.background ? resolve(manifest.entry.background) : null\n console.log(\"bg\", bg)\n const ui = manifest.entry.ui ? resolve(manifest.entry.ui) : null\n console.log(\"ui\", ui)\n if (bg || ui) {\n return {background: bg, ui: ui}\n }\n }\n // Legacy single-bundle fallback — `index.html` at the bundle root.\n const legacy = new File(new Directory(bundleDir.replace(/^file:\\/\\//, \"\")), \"index.html\")\n return {\n background: null,\n ui: legacy.exists ? legacy.uri : null,\n }\n }\n\n /**\n * Verify a manifest declares an SDK / host version range compatible\n * with the current host. Delegates to the pure\n * {@link checkManifestVersions} helper — same shape, no React Native\n * imports, unit-testable. Manifests missing either field pass\n * through unchanged (legacy single-layer path).\n */\n public checkManifestVersions(\n manifest: {sdkVersion?: string; minHostVersion?: string} | null,\n options: {hostVersion: string; supportedSdkRange: string},\n ): {ok: true} | {ok: false; reason: string} {\n return checkManifestVersions(manifest, options)\n }\n\n /**\n * Read and parse the miniapp manifest (miniapp.json with app.json fallback)\n * from a given bundle directory.\n */\n public getMiniappManifest(packageName: string, version: string): any {\n const bundleDir = new Directory(Paths.document, \"lmas\", packageName, version)\n try {\n const miniappJsonFile = new File(bundleDir, \"miniapp.json\")\n if (miniappJsonFile.exists) {\n return JSON.parse(miniappJsonFile.textSync())\n }\n } catch (e) {\n console.warn(\"AppRegistry: Error reading miniapp.json, trying app.json fallback\", e)\n }\n try {\n const appJsonFile = new File(bundleDir, \"app.json\")\n if (appJsonFile.exists) {\n return JSON.parse(appJsonFile.textSync())\n }\n } catch (e) {\n console.warn(\"AppRegistry: Error reading app.json fallback\", e)\n }\n return null\n }\n\n /**\n * Download and install a miniapp bundle from a URL. The URL must serve a\n * zip whose root contains `miniapp.json` plus the bundle entry files.\n *\n * @param opts.versionOverride if set, install under this version instead\n * of `manifest.version`. The dev caching path uses `dev-<ms>` so multiple\n * snapshots can coexist alongside semver-installed versions.\n */\n public installFromUrl(\n url: string,\n opts?: {versionOverride?: string; releaseIdentity?: MiniappReleaseIdentity},\n ): AsyncResult<void, Error> {\n return Res.try_async(async () => {\n const {packageName, version} = await downloadAndInstallMiniApp(url, opts?.versionOverride)\n console.log(\"APP_REGISTRY: Downloaded and installed mini app\")\n this.finalizeInstall(\n packageName,\n version,\n opts?.releaseIdentity ?? {source: version.startsWith(\"dev-\") ? \"dev_snapshot\" : \"direct_download\"},\n )\n })\n }\n\n /**\n * Install a miniapp from a zip already on local disk (e.g. a bundled asset\n * copied into cache). Skips the HTTP download path that `installFromUrl`\n * uses — `File.downloadFileAsync` is HTTP(S)-only and rejects file:// URIs.\n *\n * @param zipPath file:// URI of the local zip.\n */\n public installFromLocalZip(\n zipPath: string,\n opts?: {versionOverride?: string; releaseIdentity?: MiniappReleaseIdentity},\n ): AsyncResult<{packageName: string; version: string}, Error> {\n return Res.try_async(async () => {\n const {packageName, version} = await unpackMiniApp(zipPath, opts?.versionOverride)\n console.log(\"APP_REGISTRY: Installed mini app from local zip\")\n this.finalizeInstall(packageName, version, opts?.releaseIdentity ?? {source: \"bundled_asset\"})\n return {packageName, version}\n })\n }\n\n /**\n * Post-install bookkeeping shared by every install path: clear stale dev\n * artifacts on release installs, point the active-version at the just-\n * installed bundle, and notify subscribers to refresh.\n */\n private finalizeInstall(packageName: string, version: string, releaseIdentity: MiniappReleaseIdentity): void {\n // If this is a release install (semver, not dev-*) of a package that\n // currently has dev-* snapshots, clear the dev state so the swap to\n // \"released\" is clean. Otherwise the dev version would keep winning\n // getActiveVersion's dev-precedence rule and the just-installed\n // release wouldn't run.\n const isDevInstall = version.startsWith(\"dev-\")\n if (!isDevInstall) {\n this.clearDevArtifacts(packageName)\n }\n\n this.setActiveVersion(packageName, version)\n storage.save(releaseIdentityKey(packageName, version), releaseIdentity)\n this.refreshNeeded = true\n this.notify()\n }\n\n public getReleaseIdentity(packageName: string, version: string): MiniappReleaseIdentity | null {\n const result = storage.load<MiniappReleaseIdentity>(releaseIdentityKey(packageName, version))\n return result.is_ok() ? result.value : null\n }\n\n public installFromJsonUrl(baseUrl: string): AsyncResult<{packageName: string; version: string; name: string}, Error> {\n return Res.try_async(async () => {\n const trimmed = baseUrl.replace(/\\/$/, \"\")\n\n const manifestRes = await fetch(`${trimmed}/miniapp.json`)\n if (!manifestRes.ok) {\n throw new Error(`Failed to fetch miniapp.json: ${manifestRes.status}`)\n }\n const manifest = (await manifestRes.json()) as Record<string, unknown>\n const packageName = manifest.packageName as string | undefined\n const version = manifest.version as string | undefined\n const name = (manifest.name as string | undefined) ?? packageName ?? \"Mini app\"\n if (!packageName) throw new Error(\"miniapp.json missing packageName\")\n if (!version) throw new Error(\"miniapp.json missing version\")\n\n const installRes = await appRegistry.installFromUrl(`${trimmed}/bundle.zip`)\n if (installRes.is_error()) throw installRes.error\n\n return {packageName, version, name}\n })\n }\n\n /**\n * Drop every dev-* version directory for a package plus ALL dev MMKV keys\n * (URL/port/reachability + the home-tile metadata record). Called on a\n * release install (dev → released transition) and on uninstall, so a dev\n * package leaves nothing behind that `projectDevApps` could re-surface.\n *\n * Dev registrations live under a namespaced id (deriveDevPackageId), so a\n * release install of the MANIFEST package no longer matches them here — the\n * dev tile survives the restart-time auto-installers by construction, and\n * this cleanup fires for the dev tile only via uninstall(itsNamespacedId).\n * (Matching legacy un-namespaced records is still cleaned up, on purpose.)\n */\n private clearDevArtifacts(packageName: string): void {\n try {\n const pkgDir = new Directory(Paths.document, \"lmas\", packageName)\n if (pkgDir.exists) {\n for (const item of pkgDir.list()) {\n if (item instanceof Directory && item.name.startsWith(\"dev-\")) {\n try {\n storage.remove(releaseIdentityKey(packageName, item.name))\n item.delete()\n } catch (e) {\n console.warn(`APP_REGISTRY: failed to delete ${item.name}:`, e)\n }\n }\n }\n }\n } catch (e) {\n console.warn(`APP_REGISTRY: clearDevArtifacts dir scan failed for ${packageName}:`, e)\n }\n storage.remove(`${packageName}_dev_url`)\n storage.remove(`${packageName}_dev_port`)\n storage.remove(`${packageName}_dev_mdns`)\n storage.remove(`${packageName}_dev_last_reachable`)\n // HTTP-direct dev miniapps are indexed by their real package name. A\n // release install/uninstall of that same package should remove only its\n // dev tile; unrelated dev miniapps must remain available.\n if (readDevAppRecord(packageName)) unregisterDevApp(packageName)\n }\n\n /**\n * Garbage-collect older `dev-*` version directories for this package,\n * keeping the latest `keep` (by lexicographic sort, which matches\n * timestamp ordering since dev-<ms> is zero-padded).\n *\n * Only touches `dev-*` versions; semver-installed versions are left alone.\n */\n public gcDevVersions(packageName: string, keep: number): void {\n try {\n const pkgDir = new Directory(Paths.document, \"lmas\", packageName)\n if (!pkgDir.exists) return\n const dirs = pkgDir\n .list()\n .filter((d): d is Directory => d instanceof Directory && d.name.startsWith(\"dev-\"))\n .sort((a, b) => (a.name < b.name ? 1 : -1))\n for (let i = keep; i < dirs.length; i++) {\n try {\n dirs[i].delete()\n } catch (e) {\n console.warn(`APP_REGISTRY: failed to delete ${dirs[i].name}:`, e)\n }\n }\n if (dirs.length > keep) this.refreshNeeded = true\n } catch (e) {\n console.warn(`APP_REGISTRY: gcDevVersions error for ${packageName}:`, e)\n }\n }\n\n public uninstall(packageName: string, version?: string): AsyncResult<void, Error> {\n return Res.try_async(async () => {\n if (version) {\n const lmaDir = new Directory(Paths.document, \"lmas\", packageName, version)\n // Guard exists: a dev miniapp loads over HTTP and has no on-disk dir,\n // so an unconditional delete() would throw and abort the cleanup below.\n if (lmaDir.exists) lmaDir.delete()\n storage.remove(releaseIdentityKey(packageName, version))\n console.log(\"APP_REGISTRY: Uninstalled mini app version\", version)\n const packageDir = new Directory(Paths.document, \"lmas\", packageName)\n if (packageDir.exists && packageDir.list().length === 0) {\n packageDir.delete()\n }\n } else {\n for (const installedVersion of this.getInstalledVersions(packageName)) {\n storage.remove(releaseIdentityKey(packageName, installedVersion))\n }\n const packageDir = new Directory(Paths.document, \"lmas\", packageName)\n if (packageDir.exists) {\n packageDir.delete()\n }\n console.log(\"APP_REGISTRY: Uninstalled all versions of mini app\", packageName)\n }\n // Always clear dev artifacts: for HTTP-direct dev miniapps the tile is\n // backed by storage records (_dev_meta + dev_apps_index), not the disk\n // dir, so without this the projected tile reappears on the next refresh.\n this.clearDevArtifacts(packageName)\n this.refreshNeeded = true\n this.notify()\n })\n }\n\n public getPackageNames(): string[] {\n try {\n const lmasDir = new Directory(Paths.document, \"lmas\")\n if (!lmasDir.exists) return []\n let lmas = lmasDir.list()\n lmas = lmas.filter((lma): lma is Directory => lma instanceof Directory && lma.list().length > 0)\n return lmas.map((lma) => lma.name)\n } catch (error) {\n console.error(\"APP_REGISTRY: Error getting locally installed package names\", error)\n return []\n }\n }\n\n public getInstalledVersions(packageName: string): string[] {\n try {\n const lmaDir = new Directory(Paths.document, \"lmas\", packageName)\n // Not installed yet is an expected state (e.g. preinstall sync probing\n // versions before first install) — return [] without the error noise.\n if (!lmaDir.exists) {\n return []\n }\n const lma = lmaDir.list()\n return lma.map((lma) => lma.name)\n } catch (error) {\n console.error(\"APP_REGISTRY: Error getting local applet versions\", error)\n return []\n }\n }\n\n /** Undefined when no bundle is on disk (offline built-ins, HTTP-direct dev apps). */\n public async getActiveVersion(packageName: string): Promise<string | undefined> {\n let versions = this.getInstalledVersions(packageName)\n // Treat MMKV as a hint, not authority. A stored version may have been\n // GC'd off disk without this pointer being updated.\n let res = storage.load<string>(`${packageName}_active_version`)\n if (res.is_ok() && versions.includes(res.value)) {\n return res.value\n }\n // Dev versions take precedence over semver-installed versions.\n const devVersions = versions\n .filter((v) => v.startsWith(\"dev-\"))\n .sort()\n .reverse()\n if (devVersions.length > 0) {\n this.setActiveVersion(packageName, devVersions[0])\n return devVersions[0]\n }\n versions = versions.filter((v) => semver.valid(v))\n versions.sort((a, b) => semver.rcompare(a, b))\n const latest = versions[0] as string | undefined\n // Never persist undefined: MMKV.set throws on it.\n if (latest) this.setActiveVersion(packageName, latest)\n return latest\n }\n\n public setActiveVersion(packageName: string, version: string): Result<void, Error> {\n return storage.save(`${packageName}_active_version`, version)\n }\n\n public getMetadata(packageName: string, version: string): InstalledInfo {\n try {\n const lmaDir = new Directory(Paths.document, \"lmas\", packageName, version)\n const miniappJsonFile = new File(lmaDir, \"miniapp.json\")\n const manifest = JSON.parse(miniappJsonFile.textSync())\n const logoUrl = new File(lmaDir, \"icon.png\").uri\n return {name: manifest.name, logoUrl: logoUrl}\n } catch (error) {\n console.error(\"APP_REGISTRY: Error getting local miniapp metadata\", error)\n return {name: \"error\", logoUrl: \"\"}\n }\n }\n\n public getInstalledInfo(): InstalledLma[] {\n const packageNames = this.getPackageNames()\n const out: InstalledLma[] = []\n for (const packageName of packageNames) {\n const versionStrings = this.getInstalledVersions(packageName)\n const installedVersion: InstalledLma = {packageName, versions: {}}\n for (const versionString of versionStrings) {\n installedVersion.versions[versionString] = this.getMetadata(packageName, versionString)\n }\n out.push(installedVersion)\n }\n return out\n }\n\n /**\n * Merge disk-derived apps with the projected dev + offline layers,\n * de-duping by packageName. Dev registrations use namespaced ids\n * (deriveDevPackageId), so a dev tile and a real install of the same\n * manifest package coexist as separate tiles; the dedupe below only bites\n * legacy un-namespaced dev records. Native offline apps keep top priority.\n */\n private mergeProjectedApps(diskApps: ClientApp[]): ClientApp[] {\n const offline = this.projectOfflineApps()\n const offlinePackages = new Set(offline.map((app) => app.packageName))\n const dev = this.projectDevApps().filter((app) => !offlinePackages.has(app.packageName))\n const devPackages = new Set(dev.map((app) => app.packageName))\n const installed = diskApps.filter(\n (app) => !offlinePackages.has(app.packageName) && !devPackages.has(app.packageName),\n )\n return [...installed, ...dev, ...offline]\n }\n\n public async getInstalledMiniapps(): Promise<ClientApp[]> {\n if (!this.refreshNeeded && this.cachedApps.length > 0) {\n // Cache hit: re-project running from the registry. The cached array\n // IS the disk-derived truth; running comes from the mount registry.\n return this.mergeProjectedApps(\n this.cachedApps.map((a) => ({\n ...a,\n running: miniappRunningRegistry.has(a.packageName),\n })),\n )\n }\n\n try {\n const installedInfo = this.getInstalledInfo()\n const out: ClientApp[] = []\n for (const lmaInfo of installedInfo) {\n const versionString = await this.getActiveVersion(lmaInfo.packageName)\n // A package dir with no usable bundle (e.g. only a half-written version) has nothing to run.\n if (!versionString) continue\n const versionInfo = lmaInfo.versions[versionString]\n\n const manifest = this.getMiniappManifest(lmaInfo.packageName, versionString) as {\n permissions?: Array<string | {type: string; required?: boolean; description?: string}>\n hardwareRequirements?: Array<{type: string; level: string; description?: string}>\n type?: string\n alwaysOn?: unknown\n description?: unknown\n tagline?: unknown\n tags?: unknown\n actions?: Array<{\n id?: unknown\n description?: unknown\n parameters?: unknown\n outputSchema?: unknown\n visibility?: unknown\n }>\n widgets?: unknown\n } | null\n\n const permissions = normalizeManifestPermissions(manifest?.permissions)\n const hardwareRequirements = buildHardwareRequirements(manifest?.hardwareRequirements, lmaInfo.packageName)\n const appType = normalizeManifestType(manifest?.type)\n const description = normalizeManifestText(manifest?.description)\n const tagline = normalizeManifestText(manifest?.tagline)\n const tags = normalizeManifestTags(manifest?.tags)\n\n // Declared actions (for session.miniapps.list + invoke gating).\n const actions = normalizeManifestActions(manifest?.actions)\n const widgets = withWidgetExpandChoices(lmaInfo.packageName, normalizeManifestWidgets(manifest?.widgets))\n\n // Dev miniapps live in the same lmas/ tree as installed ones, but\n // their version directory name starts with \"dev-\".\n const isMiniappDev = versionString.startsWith(\"dev-\")\n let devUrl: string | undefined\n if (isMiniappDev) {\n const devUrlRes = storage.load<string>(`${lmaInfo.packageName}_dev_url`)\n if (devUrlRes.is_ok()) devUrl = devUrlRes.value\n }\n\n out.push({\n packageName: lmaInfo.packageName,\n version: versionString,\n running: miniappRunningRegistry.has(lmaInfo.packageName),\n local: true,\n healthy: true,\n loading: false,\n offline: false,\n hidden: false,\n offlineRoute: \"\",\n name: versionInfo.name,\n webviewUrl: \"\",\n logoUrl: versionInfo.logoUrl,\n type: appType,\n alwaysOn: getAlwaysOnOverride(lmaInfo.packageName) ?? manifest?.alwaysOn === true,\n permissions,\n hardwareRequirements,\n ...(description ? {description} : {}),\n ...(tagline ? {tagline} : {}),\n ...(tags.length > 0 ? {tags} : {}),\n // Always project actions (even []) so the invoke gate can enforce\n // declared-action membership unconditionally — an app with no declared\n // actions must reject every invoke, not bypass the check.\n actions,\n ...(widgets.length > 0 ? {widgets} : {}),\n ...(isMiniappDev ? {isMiniappDev: true} : {}),\n ...(devUrl ? {devUrl} : {}),\n })\n }\n\n this.cachedApps = out\n this.refreshNeeded = false\n return this.mergeProjectedApps(this.cachedApps)\n } catch (error) {\n console.error(\"APP_REGISTRY: Error getting local applets\", error)\n return this.mergeProjectedApps(\n this.cachedApps.map((a) => ({\n ...a,\n running: miniappRunningRegistry.has(a.packageName),\n })),\n )\n }\n }\n\n /** Force the next getInstalledMiniapps() to re-derive from disk + records. */\n public markRefreshNeeded(): void {\n this.refreshNeeded = true\n this.notify()\n }\n\n /**\n * Project persisted dev-app metadata records into ClientApp tiles. Dev\n * miniapps aren't installed to disk (they load over HTTP), so they don't\n * appear in the `lmas/` scan — this surfaces them on the home screen so\n * they're re-launchable without re-scanning the QR.\n */\n private projectDevApps(): ClientApp[] {\n return getDevAppRecords().map((rec) => {\n const permissions = normalizeManifestPermissions(rec.permissions)\n const hardwareRequirements = buildHardwareRequirements(rec.hardwareRequirements, rec.packageName)\n return {\n packageName: rec.packageName,\n version: undefined,\n running: miniappRunningRegistry.has(rec.packageName),\n local: true,\n healthy: true,\n loading: false,\n offline: false,\n hidden: false,\n offlineRoute: \"\",\n name: rec.name,\n webviewUrl: \"\",\n logoUrl: rec.iconUrl,\n type: normalizeManifestType(rec.type),\n permissions,\n hardwareRequirements,\n actions: normalizeManifestActions(rec.actions),\n ...(normalizeManifestWidgets(rec.widgets).length > 0\n ? {widgets: withWidgetExpandChoices(rec.packageName, normalizeManifestWidgets(rec.widgets))}\n : {}),\n isMiniappDev: true,\n devUrl: rec.devUrl,\n devPort: rec.devPort,\n }\n })\n }\n\n private projectOfflineApps(): ClientApp[] {\n // Offline apps don't go through miniappRunningRegistry (that's for\n // MiniappHost-mounted webviews). Their running flag lives in\n // `offlineRunning` for this process only — read it back here so refreshes\n // don't blow away the active flag, while a relaunch starts them stopped.\n return this.offlineApps.map((a) => {\n const running = this.offlineRunning.has(a.packageName)\n const screenshot = getLocalAppScreenshot(a.packageName)\n\n return {...a, running, screenshot}\n })\n }\n\n // Register an offline (locally-routed) app. Survives disk rebuilds.\n public installOfflineApp(app: ClientApp, opts?: {requiresLocalSttModel?: boolean}): void {\n if (opts?.requiresLocalSttModel) {\n this.sttModelRequired.add(app.packageName)\n }\n this.offlineApps.push({\n ...app,\n onStart: () => {\n this.offlineRunning.add(app.packageName)\n app.onStart?.()\n },\n onStop: () => {\n this.offlineRunning.delete(app.packageName)\n app.onStop?.()\n },\n })\n this.refreshNeeded = true\n this.notify()\n }\n\n /**\n * Update whether a registered offline app is projected into launcher UIs.\n *\n * Offline apps are registered once at host startup, so settings-backed\n * visibility changes need to update the projection without reinstalling or\n * duplicating the app. No-op when the app is missing or already matches.\n */\n public setOfflineAppHidden(packageName: string, hidden: boolean): void {\n const app = this.offlineApps.find((candidate) => candidate.packageName === packageName)\n if (!app || app.hidden === hidden) return\n\n app.hidden = hidden\n this.refreshNeeded = true\n this.notify()\n }\n\n /**\n * Registered as needing the on-device STT model before it can start (the\n * host declares this per offline app; the apps store gates start() on it).\n */\n public requiresLocalSttModel(packageName: string): boolean {\n return this.sttModelRequired.has(packageName)\n }\n\n public getMiniappHtml(packageName: string, version: string): Result<string, Error> {\n return Res.try(() => {\n const lmaDir = new Directory(Paths.document, \"lmas\", packageName, version)\n const htmlFile = new File(lmaDir, \"index.html\")\n return htmlFile.textSync()\n })\n }\n}\n\n/** The wearer's Always On choice for a miniapp, beside the `_hidden` flag; null when they never chose. */\nexport function getAlwaysOnOverride(packageName: string): boolean | null {\n const res = storage.load<boolean>(`${packageName}_always_on`)\n return res.is_ok() ? res.value : null\n}\n\nexport function saveAlwaysOnOverride(packageName: string, status: boolean): void {\n storage.save(`${packageName}_always_on`, status)\n}\n\n/** Applies the wearer's tap-to-expand choice to each expandable widget; expansion is on until they turn it off. */\nexport function withWidgetExpandChoices(packageName: string, widgets: DeclaredWidget[]): DeclaredWidget[] {\n return widgets.map((widget) => {\n if (!widget.expandable) return widget\n const res = storage.load<boolean>(`${packageName}_widget_expand_${widget.id}`)\n return {...widget, expandOnTap: res.is_ok() ? res.value !== false : true}\n })\n}\n\nexport function saveWidgetExpandChoice(packageName: string, widgetId: string, expandOnTap: boolean): void {\n storage.save(`${packageName}_widget_expand_${widgetId}`, expandOnTap)\n}\n\nexport function getLocalAppScreenshot(packageName: string): string | undefined {\n const key = `${packageName}_screenshot`\n const res = storage.load<string>(key)\n if (res.is_error()) return undefined\n\n const uri = res.value\n if (uri.startsWith(\"file://\")) {\n try {\n if (!new File(uri).exists) {\n storage.remove(key)\n return undefined\n }\n } catch {\n storage.remove(key)\n return undefined\n }\n }\n\n return uri\n}\n\n/**\n * Persisted metadata for a dev miniapp's home tile.\n *\n * Dev miniapps load directly off the dev server over HTTP and are NOT\n * installed into `lmas/`, so the disk scan in `getInstalledMiniapps` can't\n * see them. We persist a tiny record at scan / dev-URL-entry time so the\n * tile survives across app launches and is re-launchable without re-scanning.\n * `permissions` / `hardwareRequirements` are snapshotted from the manifest so\n * the home-screen permission gate has data without a disk bundle.\n */\nexport interface DevAppRecord {\n packageName: string\n name: string\n iconUrl: string\n devUrl: string\n devPort?: number\n /**\n * Bonjour / mDNS hostname from the QR (`ComputerName.local`). Used as a\n * failover host when the raw LAN IP in `devUrl` goes stale after a Wi-Fi\n * change — phones that resolve `.local` can relaunch without re-scanning.\n */\n mdnsHost?: string\n type?: AppletType\n permissions?: Array<string | {type: string; required?: boolean; description?: string}>\n hardwareRequirements?: Array<{type: string; level: string; description?: string}>\n /** Manifest-declared actions — so dev-sideloaded miniapps can be invoked too. */\n actions?: Array<{\n id?: unknown\n description?: unknown\n parameters?: unknown\n outputSchema?: unknown\n visibility?: unknown\n }>\n /** Manifest-declared dashboard widgets. */\n widgets?: unknown\n /** Legacy single-slot migration field. New records use the real packageName directly. */\n sourcePackageName?: string\n /**\n * Short-lived Core-verifiable proof emitted by `glassly dev`. This lets the\n * dev runtime request auto-auth for the manifest package without letting\n * arbitrary dev URLs claim any package name.\n */\n devAttestation?: string\n}\n\nconst DEV_APPS_INDEX_KEY = \"dev_apps_index\"\nconst DEV_APP_ICONS_DIR = \"dev-miniapp-icons\"\n\nfunction isPrivateLanHost(hostname: string): boolean {\n return (\n hostname === \"localhost\" ||\n hostname.startsWith(\"192.168.\") ||\n hostname.startsWith(\"10.\") ||\n /^172\\.(1[6-9]|2\\d|3[0-1])\\./.test(hostname)\n )\n}\n\nfunction rewriteStaleDevUrl(value: string): string {\n if (!__DEV__) return value\n const host = configuredDevHost()\n if (!host) return value\n\n try {\n const url = new URL(value)\n if (url.hostname === host || !isPrivateLanHost(url.hostname)) return value\n url.hostname = host\n return url.toString().replace(/\\/$/, \"\")\n } catch {\n return value\n }\n}\n\nfunction normalizeDevAppRecord(record: DevAppRecord): DevAppRecord {\n const devUrl = rewriteStaleDevUrl(record.devUrl)\n const iconUrl = rewriteStaleDevUrl(record.iconUrl)\n return devUrl === record.devUrl && iconUrl === record.iconUrl ? record : {...record, devUrl, iconUrl}\n}\n\n/** Legacy package used by builds that supported only one dev miniapp. */\nexport const DEV_APP_PACKAGE_NAME = \"com.dev\"\nexport const DEV_APP_NAME = \"Dev\"\n\n/**\n * Copy a dev-server icon into Documents so the tile remains branded after the\n * laptop/server disappears. A failed download is non-fatal: the remote URL is\n * retained and can still render while the server is reachable.\n */\nasync function cacheDevAppIcon(packageName: string, iconUrl: string): Promise<string> {\n if (!/^https?:\\/\\//.test(iconUrl)) return iconUrl\n\n try {\n const dir = new Directory(Paths.document, DEV_APP_ICONS_DIR)\n if (!dir.exists) dir.create({intermediates: true})\n\n const safePackageName = packageName.replace(/[^a-zA-Z0-9._-]/g, \"_\")\n let extension = \".png\"\n try {\n const match = new URL(iconUrl).pathname.match(/\\.(png|jpe?g|webp|gif|svg)$/i)\n if (match) extension = `.${match[1].toLowerCase()}`\n } catch {\n // Keep the decoder-friendly .png fallback; image loaders sniff content.\n }\n\n // Image loaders cache file:// URIs too. Replacing bytes at the same path\n // leaves the old decoded icon visible after rescanning the development QR.\n const revision = `${Date.now()}-${Math.random().toString(36).slice(2)}`\n const target = new File(dir, `${safePackageName}.${revision}${extension}`)\n const downloaded = await File.downloadFileAsync(iconUrl, target, {idempotent: true})\n\n // Only remove older extensions AFTER the replacement is safely on disk;\n // a broken icon URL must not destroy the last known-good cached logo.\n for (const item of dir.list()) {\n if (item instanceof File && item.uri !== downloaded.uri && item.name.startsWith(`${safePackageName}.`)) {\n try {\n item.delete()\n } catch {\n // Best effort; the current icon has already been persisted.\n }\n }\n }\n return downloaded.uri\n } catch (error) {\n console.warn(`APP_REGISTRY: failed to cache dev icon for ${packageName}:`, error)\n return readDevAppRecord(packageName)?.iconUrl ?? iconUrl\n }\n}\n\nfunction removeDevRecordKeys(packageName: string): void {\n const existing = readDevAppRecord(packageName)\n if (existing?.iconUrl.startsWith(\"file://\")) {\n try {\n const icon = new File(existing.iconUrl)\n if (icon.exists) icon.delete()\n } catch (error) {\n console.warn(`APP_REGISTRY: failed to delete dev icon for ${packageName}:`, error)\n }\n }\n storage.remove(`${packageName}_dev_meta`)\n storage.remove(`${packageName}_dev_url`)\n storage.remove(`${packageName}_dev_port`)\n storage.remove(`${packageName}_dev_mdns`)\n storage.remove(`${packageName}_dev_last_reachable`)\n}\n\nfunction readDevAppRecord(packageName: string): DevAppRecord | null {\n const res = storage.load<string>(`${packageName}_dev_meta`)\n if (!res.is_ok()) return null\n try {\n return JSON.parse(res.value) as DevAppRecord\n } catch {\n return null\n }\n}\n\n/** Move the historical `com.dev` record onto its real manifest package key. */\nfunction migrateLegacyDevSlot(): void {\n const legacy = readDevAppRecord(DEV_APP_PACKAGE_NAME)\n const targetPackage = legacy?.sourcePackageName?.trim()\n if (!legacy || !targetPackage || targetPackage === DEV_APP_PACKAGE_NAME) return\n\n const existingTarget = readDevAppRecord(targetPackage)\n const migrated: DevAppRecord = existingTarget ?? {\n ...legacy,\n packageName: targetPackage,\n sourcePackageName: targetPackage,\n }\n if (!existingTarget) storage.save(`${targetPackage}_dev_meta`, JSON.stringify(migrated))\n\n const legacyUrl = storage.load<string>(`${DEV_APP_PACKAGE_NAME}_dev_url`)\n const targetUrl = storage.load<string>(`${targetPackage}_dev_url`)\n if (!targetUrl.is_ok()) {\n storage.save(`${targetPackage}_dev_url`, legacyUrl.is_ok() ? legacyUrl.value : migrated.devUrl)\n }\n const legacyPort = storage.load<number>(`${DEV_APP_PACKAGE_NAME}_dev_port`)\n const targetPort = storage.load<number>(`${targetPackage}_dev_port`)\n if (!targetPort.is_ok()) {\n const port = migrated.devPort ?? (legacyPort.is_ok() ? legacyPort.value : undefined)\n if (typeof port === \"number\" && Number.isFinite(port)) storage.save(`${targetPackage}_dev_port`, port)\n }\n const legacyMdns = storage.load<string>(`${DEV_APP_PACKAGE_NAME}_dev_mdns`)\n const targetMdns = storage.load<string>(`${targetPackage}_dev_mdns`)\n if (!targetMdns.is_ok() && legacyMdns.is_ok() && legacyMdns.value.trim()) {\n storage.save(`${targetPackage}_dev_mdns`, legacyMdns.value.trim())\n }\n\n storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_meta`)\n storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_url`)\n storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_port`)\n storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_mdns`)\n storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_last_reachable`)\n\n const index = Array.from(new Set(getDevAppIndex().map((pkg) => (pkg === DEV_APP_PACKAGE_NAME ? targetPackage : pkg))))\n storage.save(DEV_APPS_INDEX_KEY, JSON.stringify(index))\n}\n\nfunction readStoredMdnsHost(packageName: string): string | undefined {\n const res = storage.load<string>(`${packageName}_dev_mdns`)\n if (!res.is_ok()) return undefined\n return res.value.trim() || undefined\n}\n\n/**\n * Namespace a dev registration's package id so it can never collide with a\n * real install of the same manifest package. Without this, the restart-time\n * auto-installers (bundled assets in MantleManager, the preinstalled\n * registry sync) treat their release install of the manifest package as a\n * dev→released transition and wipe the dev registration via\n * clearDevArtifacts — scanning a QR for a fork of a bundled miniapp lost the\n * dev tile on every app restart. Idempotent: an already-namespaced id passes\n * through unchanged, so re-deriving at call sites is safe.\n */\nexport function deriveDevPackageId(packageName: string): string {\n const pkg = packageName.trim()\n return pkg.endsWith(\".dev\") ? pkg : `${pkg}.dev`\n}\n\n/**\n * Register or update one dev miniapp. Records are keyed by the NAMESPACED id\n * (deriveDevPackageId), not the manifest package, so a dev tile coexists\n * with a real install of the same app and survives the auto-installers;\n * `sourcePackageName` keeps the manifest package for attestation/source\n * lookups. Different packages coexist; rescanning the same package updates\n * its record in place. Returns the stored record — its `packageName` is the\n * derived id callers must use for stop/foreground/navigation.\n */\nexport async function registerDevApp(record: DevAppRecord): Promise<DevAppRecord> {\n migrateLegacyDevSlot()\n const rawPackageName = record.packageName.trim()\n if (!rawPackageName) throw new Error(\"Dev miniapp manifest is missing packageName\")\n const packageName = deriveDevPackageId(rawPackageName)\n const sourcePackageName = rawPackageName.endsWith(\".dev\") ? rawPackageName.slice(0, -\".dev\".length) : rawPackageName\n\n const iconUrl = await cacheDevAppIcon(packageName, record.iconUrl)\n // Relaunch paths (developer-URL screen, loadDevMiniapp) omit mdnsHost, so an\n // omitted field keeps whatever the QR scan stored instead of wiping the\n // `.local` failover host.\n const mdnsHost = record.mdnsHost !== undefined ? record.mdnsHost.trim() || undefined : readStoredMdnsHost(packageName)\n const devRecord: DevAppRecord = {\n ...record,\n packageName,\n sourcePackageName,\n name: record.name || DEV_APP_NAME,\n iconUrl,\n mdnsHost,\n }\n storage.save(`${packageName}_dev_meta`, JSON.stringify(devRecord))\n storage.save(`${packageName}_dev_url`, record.devUrl)\n if (typeof record.devPort === \"number\" && Number.isFinite(record.devPort)) {\n storage.save(`${packageName}_dev_port`, record.devPort)\n } else {\n storage.remove(`${packageName}_dev_port`)\n }\n if (mdnsHost) {\n storage.save(`${packageName}_dev_mdns`, mdnsHost)\n } else {\n storage.remove(`${packageName}_dev_mdns`)\n }\n const idx = getDevAppIndex()\n if (!idx.includes(packageName)) {\n idx.push(packageName)\n storage.save(DEV_APPS_INDEX_KEY, JSON.stringify(idx))\n }\n appRegistry.markRefreshNeeded()\n return devRecord\n}\n\n/** Drop one dev miniapp's metadata, routing keys, and cached icon. */\nexport function unregisterDevApp(packageName = DEV_APP_PACKAGE_NAME): void {\n removeDevRecordKeys(packageName)\n const idx = getDevAppIndex().filter((p) => p !== packageName)\n storage.save(DEV_APPS_INDEX_KEY, JSON.stringify(idx))\n appRegistry.markRefreshNeeded()\n}\n\nfunction getDevAppIndex(): string[] {\n const res = storage.load<string>(DEV_APPS_INDEX_KEY)\n if (!res.is_ok()) return []\n try {\n const parsed = JSON.parse(res.value)\n return Array.isArray(parsed) ? (parsed as string[]) : []\n } catch {\n return []\n }\n}\n\n/** Resolve the manifest package for a dev runtime (including the legacy slot). */\nexport function getDevAppSourcePackage(packageName = DEV_APP_PACKAGE_NAME): string | null {\n migrateLegacyDevSlot()\n const rec = readDevAppRecord(packageName)\n return rec?.sourcePackageName ?? rec?.packageName ?? null\n}\n\nexport function getDevAppAttestation(packageName = DEV_APP_PACKAGE_NAME): string | null {\n migrateLegacyDevSlot()\n return readDevAppRecord(packageName)?.devAttestation ?? null\n}\n\nexport function getDevAppRecords(): DevAppRecord[] {\n migrateLegacyDevSlot()\n const out: DevAppRecord[] = []\n for (const pkg of getDevAppIndex()) {\n const res = storage.load<string>(`${pkg}_dev_meta`)\n if (!res.is_ok()) continue\n try {\n const record = JSON.parse(res.value) as DevAppRecord\n const normalized = normalizeDevAppRecord(record)\n if (normalized !== record) {\n storage.save(`${pkg}_dev_meta`, JSON.stringify(normalized))\n storage.save(`${pkg}_dev_url`, normalized.devUrl)\n }\n out.push(normalized)\n } catch {\n /* corrupt record — skip */\n }\n }\n return out\n}\n\nconst appRegistry = AppRegistry.getInstance()\nexport default appRegistry\n"]}
@@ -12,6 +12,11 @@ export interface MiniappSafeArea {
12
12
  left: number;
13
13
  right: number;
14
14
  }
15
+ /**
16
+ * The host's capsule menu in the WebView's own coordinate space. `corner`
17
+ * floats over the page's top-right; `rail` sits in the iPhone Duo's status
18
+ * rail, inside the side safe-area inset and clear of the page content.
19
+ */
15
20
  export interface CapsuleMenuRect {
16
21
  top: number;
17
22
  right: number;
@@ -19,14 +24,8 @@ export interface CapsuleMenuRect {
19
24
  left: number;
20
25
  width: number;
21
26
  height: number;
27
+ placement: "corner" | "rail";
22
28
  }
23
- /**
24
- * @param topInsetOffset extra top offset to add when the WebView container does
25
- * NOT already pad by the safe-area inset (i.e. WebView fills edge-to-edge under
26
- * the status bar). Pass `insets.top` in that case, or 0 when the container
27
- * already applies top padding.
28
- */
29
- export declare function getCapsuleMenuRect(topInsetOffset?: number): CapsuleMenuRect;
30
29
  export type MiniappColorScheme = "light" | "dark";
31
30
  export interface BuildMiniappGlobalsOptions {
32
31
  packageName?: string;
@@ -34,21 +33,18 @@ export interface BuildMiniappGlobalsOptions {
34
33
  miniappLocal?: boolean;
35
34
  miniappDeveloperMode?: boolean;
36
35
  safeAreaInsets: MiniappSafeArea;
37
- /**
38
- * True when the WebView container renders edge-to-edge (no top padding for
39
- * the status bar). In that case the capsule menu rect needs to shift down by
40
- * the top inset so its coords match where it's actually drawn on screen.
41
- */
42
- webviewFillsStatusBar?: boolean;
36
+ /** Where the host draws its capsule menu over this WebView. */
37
+ capsuleMenu: CapsuleMenuRect;
43
38
  /** Current host color scheme. Miniapps may follow this to match the phone. */
44
39
  colorScheme?: MiniappColorScheme;
45
40
  }
46
41
  /**
47
- * JS to inject into a running miniapp when the host's safe area changes (an
48
- * iPhone Duo folding moves its status rail): updates window.Glassly and the
49
- * CSS variables, then fires `glassly:safe-area-change`.
42
+ * JS to inject into a running miniapp when the host's safe area or capsule
43
+ * menu moves (an iPhone Duo folding, or its rail's reserved regions growing):
44
+ * updates window.Glassly and the CSS variables, then fires
45
+ * `glassly:safe-area-change`.
50
46
  */
51
- export declare function buildSafeAreaUpdateScript(insets: MiniappSafeArea): string;
47
+ export declare function buildSafeAreaUpdateScript(insets: MiniappSafeArea, capsuleMenu: CapsuleMenuRect): string;
52
48
  /**
53
49
  * Returns the JS string to inject into a miniapp WebView before its content
54
50
  * loads. Sets window.Glassly with the standard fields miniapps read:
@@ -1 +1 @@
1
- {"version":3,"file":"miniappGlobals.d.ts","sourceRoot":"","sources":["../../src/utils/miniappGlobals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAaD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,SAAI,GAAG,eAAe,CAWtE;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,MAAM,CAAA;AAEjD,MAAM,WAAW,0BAA0B;IACzC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,cAAc,EAAE,eAAe,CAAA;IAC/B;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,kBAAkB,CAAA;CACjC;AAWD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAazE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,0BAA0B,GAAG,MAAM,CAwKlF"}
1
+ {"version":3,"file":"miniappGlobals.d.ts","sourceRoot":"","sources":["../../src/utils/miniappGlobals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,QAAQ,GAAG,MAAM,CAAA;CAC7B;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,MAAM,CAAA;AAEjD,MAAM,WAAW,0BAA0B;IACzC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,cAAc,EAAE,eAAe,CAAA;IAC/B,+DAA+D;IAC/D,WAAW,EAAE,eAAe,CAAA;IAC5B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,kBAAkB,CAAA;CACjC;AAwBD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,GAAG,MAAM,CAcvG;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,0BAA0B,GAAG,MAAM,CAqJlF"}
@@ -6,55 +6,42 @@
6
6
  * this util is the one place that builds the globals so every WebView gets the
7
7
  * same API surface.
8
8
  */
9
- import { Dimensions, Platform } from "react-native";
10
- /**
11
- * The capsule menu bounding rect in the WebView's own coordinate space.
12
- *
13
- * Keep in sync with CapsuleMenu.tsx:
14
- * - CapsuleButton height ≈ h-7.5 (30px), width ≈ 73px
15
- * - Positioned at right-2 (8px), top = theme.spacing.s2 (8px) below insets.top
16
- */
17
- const CAPSULE_MENU_HEIGHT = 30;
18
- const CAPSULE_MENU_WIDTH = 73;
19
- const CAPSULE_MENU_PADDING = 8;
20
- /**
21
- * @param topInsetOffset extra top offset to add when the WebView container does
22
- * NOT already pad by the safe-area inset (i.e. WebView fills edge-to-edge under
23
- * the status bar). Pass `insets.top` in that case, or 0 when the container
24
- * already applies top padding.
25
- */
26
- export function getCapsuleMenuRect(topInsetOffset = 0) {
27
- const screenWidth = Dimensions.get("window").width;
28
- const top = topInsetOffset + CAPSULE_MENU_PADDING;
29
- return {
30
- top,
31
- right: CAPSULE_MENU_PADDING,
32
- bottom: top + CAPSULE_MENU_HEIGHT,
33
- left: screenWidth - CAPSULE_MENU_PADDING - CAPSULE_MENU_WIDTH,
34
- width: CAPSULE_MENU_WIDTH,
35
- height: CAPSULE_MENU_HEIGHT,
36
- };
37
- }
38
- function safeAreaCssVars(insets) {
9
+ import { Platform } from "react-native";
10
+ // CSS custom properties that mirror the safe-area and capsule menu data, so
11
+ // miniapp CSS (or Tailwind arbitrary values) can read them without touching
12
+ // JS: e.g. `style="margin-top: var(--glassly-capsule-top)"`.
13
+ function layoutCssVars(insets, capsule) {
39
14
  return {
40
15
  "--glassly-safe-top": `${insets.top}px`,
41
16
  "--glassly-safe-bottom": `${insets.bottom}px`,
42
17
  "--glassly-safe-left": `${insets.left}px`,
43
18
  "--glassly-safe-right": `${insets.right}px`,
19
+ "--glassly-capsule-top": `${capsule.top}px`,
20
+ "--glassly-capsule-bottom": `${capsule.bottom}px`,
21
+ "--glassly-capsule-left": `${capsule.left}px`,
22
+ "--glassly-capsule-right": `${capsule.right}px`,
23
+ "--glassly-capsule-width": `${capsule.width}px`,
24
+ "--glassly-capsule-height": `${capsule.height}px`,
25
+ "--glassly-capsule-center-y": `${capsule.top + capsule.height / 2}px`,
26
+ // Right-side gutter to reserve so content doesn't slide under the
27
+ // capsule: its width + 16px breathing room, none when it sits in the rail.
28
+ "--glassly-capsule-gutter": `${capsule.placement === "rail" ? 0 : capsule.width + 16}px`,
44
29
  };
45
30
  }
46
31
  /**
47
- * JS to inject into a running miniapp when the host's safe area changes (an
48
- * iPhone Duo folding moves its status rail): updates window.Glassly and the
49
- * CSS variables, then fires `glassly:safe-area-change`.
32
+ * JS to inject into a running miniapp when the host's safe area or capsule
33
+ * menu moves (an iPhone Duo folding, or its rail's reserved regions growing):
34
+ * updates window.Glassly and the CSS variables, then fires
35
+ * `glassly:safe-area-change`.
50
36
  */
51
- export function buildSafeAreaUpdateScript(insets) {
52
- const sets = Object.entries(safeAreaCssVars(insets))
37
+ export function buildSafeAreaUpdateScript(insets, capsuleMenu) {
38
+ const sets = Object.entries(layoutCssVars(insets, capsuleMenu))
53
39
  .map(([k, v]) => `document.documentElement.style.setProperty(${JSON.stringify(k)}, ${JSON.stringify(v)});`)
54
40
  .join("\n ");
55
41
  return `
56
42
  window.Glassly = window.Glassly || {};
57
43
  window.Glassly.safeAreaInsets = ${JSON.stringify(insets)};
44
+ window.Glassly.capsuleMenu = ${JSON.stringify(capsuleMenu)};
58
45
  try {
59
46
  ${sets}
60
47
  } catch (e) { /* ignore */ }
@@ -75,12 +62,11 @@ export function buildSafeAreaUpdateScript(insets) {
75
62
  * assign to it before the native bridge wires in.
76
63
  */
77
64
  export function buildMiniappGlobalsScript(opts) {
78
- const capsuleTopOffset = opts.webviewFillsStatusBar ? opts.safeAreaInsets.top : 0;
79
65
  const globals = {
80
66
  platform: Platform.OS,
81
67
  capabilities: opts.capabilities ?? ["share", "open_url", "copy_clipboard", "download"],
82
68
  safeAreaInsets: opts.safeAreaInsets,
83
- capsuleMenu: getCapsuleMenuRect(capsuleTopOffset),
69
+ capsuleMenu: opts.capsuleMenu,
84
70
  };
85
71
  if (opts.packageName)
86
72
  globals.packageName = opts.packageName;
@@ -90,25 +76,7 @@ export function buildMiniappGlobalsScript(opts) {
90
76
  globals.miniappDeveloperMode = true;
91
77
  if (opts.colorScheme)
92
78
  globals.colorScheme = opts.colorScheme;
93
- // CSS custom properties that mirror the capsule menu / safe-area data.
94
- // Miniapp CSS (or Tailwind arbitrary values) can read these without
95
- // touching JS: e.g. `style="margin-top: var(--glassly-capsule-top)"`.
96
- const capsule = globals.capsuleMenu;
97
- const insets = opts.safeAreaInsets;
98
- const capsuleCenter = capsule.top + capsule.height / 2;
99
- const cssVars = {
100
- ...safeAreaCssVars(insets),
101
- "--glassly-capsule-top": `${capsule.top}px`,
102
- "--glassly-capsule-bottom": `${capsule.bottom}px`,
103
- "--glassly-capsule-left": `${capsule.left}px`,
104
- "--glassly-capsule-right": `${capsule.right}px`,
105
- "--glassly-capsule-width": `${capsule.width}px`,
106
- "--glassly-capsule-height": `${capsule.height}px`,
107
- "--glassly-capsule-center-y": `${capsuleCenter}px`,
108
- // Right-side gutter to reserve so content doesn't slide under the
109
- // capsule: capsule width + 16px breathing room.
110
- "--glassly-capsule-gutter": `${capsule.width + 16}px`,
111
- };
79
+ const cssVars = layoutCssVars(opts.safeAreaInsets, opts.capsuleMenu);
112
80
  const cssVarsBlock = Object.entries(cssVars)
113
81
  .map(([k, v]) => `${k}: ${v};`)
114
82
  .join(" ");
@@ -1 +1 @@
1
- {"version":3,"file":"miniappGlobals.js","sourceRoot":"","sources":["../../src/utils/miniappGlobals.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * miniappGlobals — shared builder for the window.Glassly globals injected\n * into every miniapp WebView.\n *\n * Miniapps run on-device, and LocalMiniappView is the single injection path;\n * this util is the one place that builds the globals so every WebView gets the\n * same API surface.\n */\n\nimport {Dimensions, Platform} from \"react-native\"\n\nexport interface MiniappSafeArea {\n top: number\n bottom: number\n left: number\n right: number\n}\n\nexport interface CapsuleMenuRect {\n top: number\n right: number\n bottom: number\n left: number\n width: number\n height: number\n}\n\n/**\n * The capsule menu bounding rect in the WebView's own coordinate space.\n *\n * Keep in sync with CapsuleMenu.tsx:\n * - CapsuleButton height ≈ h-7.5 (30px), width ≈ 73px\n * - Positioned at right-2 (8px), top = theme.spacing.s2 (8px) below insets.top\n */\nconst CAPSULE_MENU_HEIGHT = 30\nconst CAPSULE_MENU_WIDTH = 73\nconst CAPSULE_MENU_PADDING = 8\n\n/**\n * @param topInsetOffset extra top offset to add when the WebView container does\n * NOT already pad by the safe-area inset (i.e. WebView fills edge-to-edge under\n * the status bar). Pass `insets.top` in that case, or 0 when the container\n * already applies top padding.\n */\nexport function getCapsuleMenuRect(topInsetOffset = 0): CapsuleMenuRect {\n const screenWidth = Dimensions.get(\"window\").width\n const top = topInsetOffset + CAPSULE_MENU_PADDING\n return {\n top,\n right: CAPSULE_MENU_PADDING,\n bottom: top + CAPSULE_MENU_HEIGHT,\n left: screenWidth - CAPSULE_MENU_PADDING - CAPSULE_MENU_WIDTH,\n width: CAPSULE_MENU_WIDTH,\n height: CAPSULE_MENU_HEIGHT,\n }\n}\n\nexport type MiniappColorScheme = \"light\" | \"dark\"\n\nexport interface BuildMiniappGlobalsOptions {\n packageName?: string\n capabilities?: string[]\n miniappLocal?: boolean\n miniappDeveloperMode?: boolean\n safeAreaInsets: MiniappSafeArea\n /**\n * True when the WebView container renders edge-to-edge (no top padding for\n * the status bar). In that case the capsule menu rect needs to shift down by\n * the top inset so its coords match where it's actually drawn on screen.\n */\n webviewFillsStatusBar?: boolean\n /** Current host color scheme. Miniapps may follow this to match the phone. */\n colorScheme?: MiniappColorScheme\n}\n\nfunction safeAreaCssVars(insets: MiniappSafeArea): Record<string, string> {\n return {\n \"--glassly-safe-top\": `${insets.top}px`,\n \"--glassly-safe-bottom\": `${insets.bottom}px`,\n \"--glassly-safe-left\": `${insets.left}px`,\n \"--glassly-safe-right\": `${insets.right}px`,\n }\n}\n\n/**\n * JS to inject into a running miniapp when the host's safe area changes (an\n * iPhone Duo folding moves its status rail): updates window.Glassly and the\n * CSS variables, then fires `glassly:safe-area-change`.\n */\nexport function buildSafeAreaUpdateScript(insets: MiniappSafeArea): string {\n const sets = Object.entries(safeAreaCssVars(insets))\n .map(([k, v]) => `document.documentElement.style.setProperty(${JSON.stringify(k)}, ${JSON.stringify(v)});`)\n .join(\"\\n \")\n return `\n window.Glassly = window.Glassly || {};\n window.Glassly.safeAreaInsets = ${JSON.stringify(insets)};\n try {\n ${sets}\n } catch (e) { /* ignore */ }\n window.dispatchEvent(new Event(\"glassly:safe-area-change\"));\n true;\n `\n}\n\n/**\n * Returns the JS string to inject into a miniapp WebView before its content\n * loads. Sets window.Glassly with the standard fields miniapps read:\n *\n * window.Glassly = {\n * platform, packageName?, capabilities, safeAreaInsets, capsuleMenu,\n * miniappLocal?, miniappDeveloperMode?\n * }\n *\n * Also defines a stub window.receiveNativeMessage so the miniapp can safely\n * assign to it before the native bridge wires in.\n */\nexport function buildMiniappGlobalsScript(opts: BuildMiniappGlobalsOptions): string {\n const capsuleTopOffset = opts.webviewFillsStatusBar ? opts.safeAreaInsets.top : 0\n const globals: Record<string, unknown> = {\n platform: Platform.OS,\n capabilities: opts.capabilities ?? [\"share\", \"open_url\", \"copy_clipboard\", \"download\"],\n safeAreaInsets: opts.safeAreaInsets,\n capsuleMenu: getCapsuleMenuRect(capsuleTopOffset),\n }\n if (opts.packageName) globals.packageName = opts.packageName\n if (opts.miniappLocal) globals.miniappLocal = true\n if (opts.miniappDeveloperMode) globals.miniappDeveloperMode = true\n if (opts.colorScheme) globals.colorScheme = opts.colorScheme\n\n // CSS custom properties that mirror the capsule menu / safe-area data.\n // Miniapp CSS (or Tailwind arbitrary values) can read these without\n // touching JS: e.g. `style=\"margin-top: var(--glassly-capsule-top)\"`.\n const capsule = globals.capsuleMenu as CapsuleMenuRect\n const insets = opts.safeAreaInsets\n const capsuleCenter = capsule.top + capsule.height / 2\n const cssVars: Record<string, string> = {\n ...safeAreaCssVars(insets),\n \"--glassly-capsule-top\": `${capsule.top}px`,\n \"--glassly-capsule-bottom\": `${capsule.bottom}px`,\n \"--glassly-capsule-left\": `${capsule.left}px`,\n \"--glassly-capsule-right\": `${capsule.right}px`,\n \"--glassly-capsule-width\": `${capsule.width}px`,\n \"--glassly-capsule-height\": `${capsule.height}px`,\n \"--glassly-capsule-center-y\": `${capsuleCenter}px`,\n // Right-side gutter to reserve so content doesn't slide under the\n // capsule: capsule width + 16px breathing room.\n \"--glassly-capsule-gutter\": `${capsule.width + 16}px`,\n }\n const cssVarsBlock = Object.entries(cssVars)\n .map(([k, v]) => `${k}: ${v};`)\n .join(\" \")\n\n // Console-tap shim: wrap console.log/warn/error/info/debug so each call\n // also forwards a `dev_log` envelope back to the phone via\n // ReactNativeWebView.postMessage. Dev mode forwards to the laptop's\n // `glassly dev` terminal; non-dev mode falls back to the React\n // Native log stream (Metro / Xcode console / adb logcat) so installed-\n // miniapp errors are still inspectable when there's no laptop sidecar.\n //\n // Also tap window.onerror and window.onunhandledrejection so synchronous\n // throws and unhandled promise rejections surface even when the bundle\n // never gets a chance to call console.error itself.\n const consoleTapBlock = `\n (function() {\n try {\n var levels = [\"log\", \"warn\", \"error\", \"info\", \"debug\"];\n var seen = new WeakSet();\n function safeSerialize(arg) {\n if (arg instanceof Error) return {__error: true, message: arg.message, stack: arg.stack};\n if (arg === null || typeof arg !== \"object\") return arg;\n try {\n return JSON.parse(JSON.stringify(arg, function(k, v) {\n if (v !== null && typeof v === \"object\") {\n if (seen.has(v)) return \"[Circular]\";\n seen.add(v);\n }\n return v;\n }));\n } catch (e) {\n try { return String(arg); } catch (_) { return \"[unserializable]\"; }\n }\n }\n levels.forEach(function(level) {\n var original = console[level];\n if (typeof original !== \"function\") return;\n console[level] = function() {\n try { original.apply(console, arguments); } catch (_) {}\n try {\n var args = Array.prototype.slice.call(arguments).map(safeSerialize);\n if (window.ReactNativeWebView && typeof window.ReactNativeWebView.postMessage === \"function\") {\n window.ReactNativeWebView.postMessage(JSON.stringify({\n payload: {\n type: \"dev_log\",\n level: level,\n args: args,\n packageName: (window.Glassly && window.Glassly.packageName) || null,\n timestamp: Date.now()\n }\n }));\n }\n } catch (_) { /* swallow */ }\n };\n });\n } catch (_) { /* ignore */ }\n\n // Surface synchronous errors and unhandled promise rejections via the\n // same dev_log channel — many bundle-startup crashes never get to call\n // console.error themselves.\n try {\n window.addEventListener(\"error\", function(e) {\n try {\n if (window.ReactNativeWebView && typeof window.ReactNativeWebView.postMessage === \"function\") {\n window.ReactNativeWebView.postMessage(JSON.stringify({\n payload: {\n type: \"dev_log\",\n level: \"error\",\n args: [\"[window.error] \" + (e.message || \"unknown\"), {filename: e.filename, lineno: e.lineno, colno: e.colno, stack: e.error && e.error.stack}],\n packageName: (window.Glassly && window.Glassly.packageName) || null,\n timestamp: Date.now()\n }\n }));\n }\n } catch (_) {}\n });\n window.addEventListener(\"unhandledrejection\", function(e) {\n try {\n if (window.ReactNativeWebView && typeof window.ReactNativeWebView.postMessage === \"function\") {\n var reason = e.reason;\n var serialized = reason instanceof Error\n ? {__error: true, message: reason.message, stack: reason.stack}\n : (typeof reason === \"object\" ? JSON.stringify(reason) : String(reason));\n window.ReactNativeWebView.postMessage(JSON.stringify({\n payload: {\n type: \"dev_log\",\n level: \"error\",\n args: [\"[unhandledrejection]\", serialized],\n packageName: (window.Glassly && window.Glassly.packageName) || null,\n timestamp: Date.now()\n }\n }));\n }\n } catch (_) {}\n });\n } catch (_) {}\n })();\n `\n\n // Lock zoom so miniapps feel like apps, not pages: force a non-scalable\n // viewport meta (overriding whatever the miniapp shipped) and disable\n // double-tap-zoom via CSS. Re-applies on DOMContentLoaded in case the\n // miniapp re-writes <head> during boot.\n return `\n window.Glassly = ${JSON.stringify(globals)};\n window.receiveNativeMessage = window.receiveNativeMessage || function() {};\n (function() {\n try {\n var styleEl = document.createElement(\"style\");\n styleEl.setAttribute(\"data-glassly-injected\", \"1\");\n styleEl.textContent =\n \":root { ${cssVarsBlock} }\" +\n \"html, body { touch-action: manipulation; -ms-content-zooming: none; }\";\n (document.head || document.documentElement).appendChild(styleEl);\n } catch (e) { /* ignore */ }\n\n function lockViewport() {\n try {\n var content = \"width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover\";\n var existing = document.querySelector('meta[name=\"viewport\"]');\n if (existing) {\n existing.setAttribute(\"content\", content);\n } else {\n var meta = document.createElement(\"meta\");\n meta.setAttribute(\"name\", \"viewport\");\n meta.setAttribute(\"content\", content);\n (document.head || document.documentElement).appendChild(meta);\n }\n } catch (e) { /* ignore */ }\n }\n lockViewport();\n document.addEventListener(\"DOMContentLoaded\", lockViewport);\n })();\n ${consoleTapBlock}\n true;\n `\n}\n"]}
1
+ {"version":3,"file":"miniappGlobals.js","sourceRoot":"","sources":["../../src/utils/miniappGlobals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAA;AAsCrC,4EAA4E;AAC5E,4EAA4E;AAC5E,6DAA6D;AAC7D,SAAS,aAAa,CAAC,MAAuB,EAAE,OAAwB;IACtE,OAAO;QACL,oBAAoB,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI;QACvC,uBAAuB,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI;QAC7C,qBAAqB,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI;QACzC,sBAAsB,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI;QAC3C,uBAAuB,EAAE,GAAG,OAAO,CAAC,GAAG,IAAI;QAC3C,0BAA0B,EAAE,GAAG,OAAO,CAAC,MAAM,IAAI;QACjD,wBAAwB,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI;QAC7C,yBAAyB,EAAE,GAAG,OAAO,CAAC,KAAK,IAAI;QAC/C,yBAAyB,EAAE,GAAG,OAAO,CAAC,KAAK,IAAI;QAC/C,0BAA0B,EAAE,GAAG,OAAO,CAAC,MAAM,IAAI;QACjD,4BAA4B,EAAE,GAAG,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI;QACrE,kEAAkE;QAClE,2EAA2E;QAC3E,0BAA0B,EAAE,GAAG,OAAO,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,GAAG,EAAE,IAAI;KACzF,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAuB,EAAE,WAA4B;IAC7F,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;SAC5D,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,8CAA8C,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;SAC1G,IAAI,CAAC,UAAU,CAAC,CAAA;IACnB,OAAO;;sCAE6B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;mCACzB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;;QAEtD,IAAI;;;;GAIT,CAAA;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAgC;IACxE,MAAM,OAAO,GAA4B;QACvC,QAAQ,EAAE,QAAQ,CAAC,EAAE;QACrB,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,CAAC;QACtF,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAA;IACD,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;IAC5D,IAAI,IAAI,CAAC,YAAY;QAAE,OAAO,CAAC,YAAY,GAAG,IAAI,CAAA;IAClD,IAAI,IAAI,CAAC,oBAAoB;QAAE,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAA;IAClE,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;IAE5D,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IACpE,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SACzC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;SAC9B,IAAI,CAAC,GAAG,CAAC,CAAA;IAEZ,wEAAwE;IACxE,2DAA2D;IAC3D,oEAAoE;IACpE,+DAA+D;IAC/D,uEAAuE;IACvE,uEAAuE;IACvE,EAAE;IACF,yEAAyE;IACzE,uEAAuE;IACvE,oDAAoD;IACpD,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFvB,CAAA;IAED,wEAAwE;IACxE,sEAAsE;IACtE,sEAAsE;IACtE,wCAAwC;IACxC,OAAO;uBACc,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;;;qBAOzB,YAAY;;;;;;;;;;;;;;;;;;;;;;MAsB3B,eAAe;;GAElB,CAAA;AACH,CAAC","sourcesContent":["/**\n * miniappGlobals — shared builder for the window.Glassly globals injected\n * into every miniapp WebView.\n *\n * Miniapps run on-device, and LocalMiniappView is the single injection path;\n * this util is the one place that builds the globals so every WebView gets the\n * same API surface.\n */\n\nimport {Platform} from \"react-native\"\n\nexport interface MiniappSafeArea {\n top: number\n bottom: number\n left: number\n right: number\n}\n\n/**\n * The host's capsule menu in the WebView's own coordinate space. `corner`\n * floats over the page's top-right; `rail` sits in the iPhone Duo's status\n * rail, inside the side safe-area inset and clear of the page content.\n */\nexport interface CapsuleMenuRect {\n top: number\n right: number\n bottom: number\n left: number\n width: number\n height: number\n placement: \"corner\" | \"rail\"\n}\n\nexport type MiniappColorScheme = \"light\" | \"dark\"\n\nexport interface BuildMiniappGlobalsOptions {\n packageName?: string\n capabilities?: string[]\n miniappLocal?: boolean\n miniappDeveloperMode?: boolean\n safeAreaInsets: MiniappSafeArea\n /** Where the host draws its capsule menu over this WebView. */\n capsuleMenu: CapsuleMenuRect\n /** Current host color scheme. Miniapps may follow this to match the phone. */\n colorScheme?: MiniappColorScheme\n}\n\n// CSS custom properties that mirror the safe-area and capsule menu data, so\n// miniapp CSS (or Tailwind arbitrary values) can read them without touching\n// JS: e.g. `style=\"margin-top: var(--glassly-capsule-top)\"`.\nfunction layoutCssVars(insets: MiniappSafeArea, capsule: CapsuleMenuRect): Record<string, string> {\n return {\n \"--glassly-safe-top\": `${insets.top}px`,\n \"--glassly-safe-bottom\": `${insets.bottom}px`,\n \"--glassly-safe-left\": `${insets.left}px`,\n \"--glassly-safe-right\": `${insets.right}px`,\n \"--glassly-capsule-top\": `${capsule.top}px`,\n \"--glassly-capsule-bottom\": `${capsule.bottom}px`,\n \"--glassly-capsule-left\": `${capsule.left}px`,\n \"--glassly-capsule-right\": `${capsule.right}px`,\n \"--glassly-capsule-width\": `${capsule.width}px`,\n \"--glassly-capsule-height\": `${capsule.height}px`,\n \"--glassly-capsule-center-y\": `${capsule.top + capsule.height / 2}px`,\n // Right-side gutter to reserve so content doesn't slide under the\n // capsule: its width + 16px breathing room, none when it sits in the rail.\n \"--glassly-capsule-gutter\": `${capsule.placement === \"rail\" ? 0 : capsule.width + 16}px`,\n }\n}\n\n/**\n * JS to inject into a running miniapp when the host's safe area or capsule\n * menu moves (an iPhone Duo folding, or its rail's reserved regions growing):\n * updates window.Glassly and the CSS variables, then fires\n * `glassly:safe-area-change`.\n */\nexport function buildSafeAreaUpdateScript(insets: MiniappSafeArea, capsuleMenu: CapsuleMenuRect): string {\n const sets = Object.entries(layoutCssVars(insets, capsuleMenu))\n .map(([k, v]) => `document.documentElement.style.setProperty(${JSON.stringify(k)}, ${JSON.stringify(v)});`)\n .join(\"\\n \")\n return `\n window.Glassly = window.Glassly || {};\n window.Glassly.safeAreaInsets = ${JSON.stringify(insets)};\n window.Glassly.capsuleMenu = ${JSON.stringify(capsuleMenu)};\n try {\n ${sets}\n } catch (e) { /* ignore */ }\n window.dispatchEvent(new Event(\"glassly:safe-area-change\"));\n true;\n `\n}\n\n/**\n * Returns the JS string to inject into a miniapp WebView before its content\n * loads. Sets window.Glassly with the standard fields miniapps read:\n *\n * window.Glassly = {\n * platform, packageName?, capabilities, safeAreaInsets, capsuleMenu,\n * miniappLocal?, miniappDeveloperMode?\n * }\n *\n * Also defines a stub window.receiveNativeMessage so the miniapp can safely\n * assign to it before the native bridge wires in.\n */\nexport function buildMiniappGlobalsScript(opts: BuildMiniappGlobalsOptions): string {\n const globals: Record<string, unknown> = {\n platform: Platform.OS,\n capabilities: opts.capabilities ?? [\"share\", \"open_url\", \"copy_clipboard\", \"download\"],\n safeAreaInsets: opts.safeAreaInsets,\n capsuleMenu: opts.capsuleMenu,\n }\n if (opts.packageName) globals.packageName = opts.packageName\n if (opts.miniappLocal) globals.miniappLocal = true\n if (opts.miniappDeveloperMode) globals.miniappDeveloperMode = true\n if (opts.colorScheme) globals.colorScheme = opts.colorScheme\n\n const cssVars = layoutCssVars(opts.safeAreaInsets, opts.capsuleMenu)\n const cssVarsBlock = Object.entries(cssVars)\n .map(([k, v]) => `${k}: ${v};`)\n .join(\" \")\n\n // Console-tap shim: wrap console.log/warn/error/info/debug so each call\n // also forwards a `dev_log` envelope back to the phone via\n // ReactNativeWebView.postMessage. Dev mode forwards to the laptop's\n // `glassly dev` terminal; non-dev mode falls back to the React\n // Native log stream (Metro / Xcode console / adb logcat) so installed-\n // miniapp errors are still inspectable when there's no laptop sidecar.\n //\n // Also tap window.onerror and window.onunhandledrejection so synchronous\n // throws and unhandled promise rejections surface even when the bundle\n // never gets a chance to call console.error itself.\n const consoleTapBlock = `\n (function() {\n try {\n var levels = [\"log\", \"warn\", \"error\", \"info\", \"debug\"];\n var seen = new WeakSet();\n function safeSerialize(arg) {\n if (arg instanceof Error) return {__error: true, message: arg.message, stack: arg.stack};\n if (arg === null || typeof arg !== \"object\") return arg;\n try {\n return JSON.parse(JSON.stringify(arg, function(k, v) {\n if (v !== null && typeof v === \"object\") {\n if (seen.has(v)) return \"[Circular]\";\n seen.add(v);\n }\n return v;\n }));\n } catch (e) {\n try { return String(arg); } catch (_) { return \"[unserializable]\"; }\n }\n }\n levels.forEach(function(level) {\n var original = console[level];\n if (typeof original !== \"function\") return;\n console[level] = function() {\n try { original.apply(console, arguments); } catch (_) {}\n try {\n var args = Array.prototype.slice.call(arguments).map(safeSerialize);\n if (window.ReactNativeWebView && typeof window.ReactNativeWebView.postMessage === \"function\") {\n window.ReactNativeWebView.postMessage(JSON.stringify({\n payload: {\n type: \"dev_log\",\n level: level,\n args: args,\n packageName: (window.Glassly && window.Glassly.packageName) || null,\n timestamp: Date.now()\n }\n }));\n }\n } catch (_) { /* swallow */ }\n };\n });\n } catch (_) { /* ignore */ }\n\n // Surface synchronous errors and unhandled promise rejections via the\n // same dev_log channel — many bundle-startup crashes never get to call\n // console.error themselves.\n try {\n window.addEventListener(\"error\", function(e) {\n try {\n if (window.ReactNativeWebView && typeof window.ReactNativeWebView.postMessage === \"function\") {\n window.ReactNativeWebView.postMessage(JSON.stringify({\n payload: {\n type: \"dev_log\",\n level: \"error\",\n args: [\"[window.error] \" + (e.message || \"unknown\"), {filename: e.filename, lineno: e.lineno, colno: e.colno, stack: e.error && e.error.stack}],\n packageName: (window.Glassly && window.Glassly.packageName) || null,\n timestamp: Date.now()\n }\n }));\n }\n } catch (_) {}\n });\n window.addEventListener(\"unhandledrejection\", function(e) {\n try {\n if (window.ReactNativeWebView && typeof window.ReactNativeWebView.postMessage === \"function\") {\n var reason = e.reason;\n var serialized = reason instanceof Error\n ? {__error: true, message: reason.message, stack: reason.stack}\n : (typeof reason === \"object\" ? JSON.stringify(reason) : String(reason));\n window.ReactNativeWebView.postMessage(JSON.stringify({\n payload: {\n type: \"dev_log\",\n level: \"error\",\n args: [\"[unhandledrejection]\", serialized],\n packageName: (window.Glassly && window.Glassly.packageName) || null,\n timestamp: Date.now()\n }\n }));\n }\n } catch (_) {}\n });\n } catch (_) {}\n })();\n `\n\n // Lock zoom so miniapps feel like apps, not pages: force a non-scalable\n // viewport meta (overriding whatever the miniapp shipped) and disable\n // double-tap-zoom via CSS. Re-applies on DOMContentLoaded in case the\n // miniapp re-writes <head> during boot.\n return `\n window.Glassly = ${JSON.stringify(globals)};\n window.receiveNativeMessage = window.receiveNativeMessage || function() {};\n (function() {\n try {\n var styleEl = document.createElement(\"style\");\n styleEl.setAttribute(\"data-glassly-injected\", \"1\");\n styleEl.textContent =\n \":root { ${cssVarsBlock} }\" +\n \"html, body { touch-action: manipulation; -ms-content-zooming: none; }\";\n (document.head || document.documentElement).appendChild(styleEl);\n } catch (e) { /* ignore */ }\n\n function lockViewport() {\n try {\n var content = \"width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover\";\n var existing = document.querySelector('meta[name=\"viewport\"]');\n if (existing) {\n existing.setAttribute(\"content\", content);\n } else {\n var meta = document.createElement(\"meta\");\n meta.setAttribute(\"name\", \"viewport\");\n meta.setAttribute(\"content\", content);\n (document.head || document.documentElement).appendChild(meta);\n }\n } catch (e) { /* ignore */ }\n }\n lockViewport();\n document.addEventListener(\"DOMContentLoaded\", lockViewport);\n })();\n ${consoleTapBlock}\n true;\n `\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glassly/engine",
3
- "version": "0.3.7-beta.893",
3
+ "version": "0.3.7-beta.896",
4
4
  "description": "Glassly Engine — miniapp registry, WebView bridge, and miniapp store",
5
5
  "main": "build/index.js",
6
6
  "react-native": "src/index.ts",
@@ -97,17 +97,17 @@
97
97
  "registry": "https://registry.npmjs.org/"
98
98
  },
99
99
  "dependencies": {
100
- "@glassly/bluetooth-sdk": "0.3.7-beta.893",
101
- "@glassly/cloud-client": "0.3.7-beta.893",
102
- "@glassly/cloud-protocol": "0.3.7-beta.893",
103
- "@glassly/crust": "0.3.7-beta.893",
104
- "@glassly/miniapp": "0.3.7-beta.893",
100
+ "@glassly/bluetooth-sdk": "0.3.7-beta.896",
101
+ "@glassly/cloud-client": "0.3.7-beta.896",
102
+ "@glassly/cloud-protocol": "0.3.7-beta.896",
103
+ "@glassly/crust": "0.3.7-beta.896",
104
+ "@glassly/miniapp": "0.3.7-beta.896",
105
105
  "buffer": "^6.0.3",
106
106
  "events": "^3.3.0",
107
107
  "react-native-marked": "8.3.2",
108
108
  "semver": "^7.7.4",
109
109
  "typesafe-ts": "^1.7.1",
110
- "@glassly/llm-providers": "0.3.7-beta.893",
110
+ "@glassly/llm-providers": "0.3.7-beta.896",
111
111
  "@huggingface/jinja": "^0.5.9",
112
112
  "jsonrepair": "^3.12.0"
113
113
  },
@@ -12,9 +12,9 @@ export interface EngineReleaseMetadata {
12
12
  export const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({
13
13
  "schemaVersion": 1,
14
14
  "familyBaseVersion": "0.3.7",
15
- "releaseIdentity": "0.3.7-beta.893",
16
- "releaseSetId": "glassly-0.3.7-beta.893",
17
- "sourceCommit": "496e2647219771dbe46bd637e26a1c01bfa0e4be",
15
+ "releaseIdentity": "0.3.7-beta.896",
16
+ "releaseSetId": "glassly-0.3.7-beta.896",
17
+ "sourceCommit": "251fd15bfc9bfedd0d7ad78b78bf2843767d80d6",
18
18
  "otaManifestUrl": null,
19
19
  "otaManifestSha256": null
20
20
  })
@@ -658,7 +658,8 @@ class AppRegistry {
658
658
  }
659
659
  }
660
660
 
661
- public async getActiveVersion(packageName: string): Promise<string> {
661
+ /** Undefined when no bundle is on disk (offline built-ins, HTTP-direct dev apps). */
662
+ public async getActiveVersion(packageName: string): Promise<string | undefined> {
662
663
  let versions = this.getInstalledVersions(packageName)
663
664
  // Treat MMKV as a hint, not authority. A stored version may have been
664
665
  // GC'd off disk without this pointer being updated.
@@ -677,8 +678,10 @@ class AppRegistry {
677
678
  }
678
679
  versions = versions.filter((v) => semver.valid(v))
679
680
  versions.sort((a, b) => semver.rcompare(a, b))
680
- this.setActiveVersion(packageName, versions[0])
681
- return versions[0]
681
+ const latest = versions[0] as string | undefined
682
+ // Never persist undefined: MMKV.set throws on it.
683
+ if (latest) this.setActiveVersion(packageName, latest)
684
+ return latest
682
685
  }
683
686
 
684
687
  public setActiveVersion(packageName: string, version: string): Result<void, Error> {
@@ -747,6 +750,8 @@ class AppRegistry {
747
750
  const out: ClientApp[] = []
748
751
  for (const lmaInfo of installedInfo) {
749
752
  const versionString = await this.getActiveVersion(lmaInfo.packageName)
753
+ // A package dir with no usable bundle (e.g. only a half-written version) has nothing to run.
754
+ if (!versionString) continue
750
755
  const versionInfo = lmaInfo.versions[versionString]
751
756
 
752
757
  const manifest = this.getMiniappManifest(lmaInfo.packageName, versionString) as {
@@ -7,7 +7,7 @@
7
7
  * same API surface.
8
8
  */
9
9
 
10
- import {Dimensions, Platform} from "react-native"
10
+ import {Platform} from "react-native"
11
11
 
12
12
  export interface MiniappSafeArea {
13
13
  top: number
@@ -16,6 +16,11 @@ export interface MiniappSafeArea {
16
16
  right: number
17
17
  }
18
18
 
19
+ /**
20
+ * The host's capsule menu in the WebView's own coordinate space. `corner`
21
+ * floats over the page's top-right; `rail` sits in the iPhone Duo's status
22
+ * rail, inside the side safe-area inset and clear of the page content.
23
+ */
19
24
  export interface CapsuleMenuRect {
20
25
  top: number
21
26
  right: number
@@ -23,36 +28,7 @@ export interface CapsuleMenuRect {
23
28
  left: number
24
29
  width: number
25
30
  height: number
26
- }
27
-
28
- /**
29
- * The capsule menu bounding rect in the WebView's own coordinate space.
30
- *
31
- * Keep in sync with CapsuleMenu.tsx:
32
- * - CapsuleButton height ≈ h-7.5 (30px), width ≈ 73px
33
- * - Positioned at right-2 (8px), top = theme.spacing.s2 (8px) below insets.top
34
- */
35
- const CAPSULE_MENU_HEIGHT = 30
36
- const CAPSULE_MENU_WIDTH = 73
37
- const CAPSULE_MENU_PADDING = 8
38
-
39
- /**
40
- * @param topInsetOffset extra top offset to add when the WebView container does
41
- * NOT already pad by the safe-area inset (i.e. WebView fills edge-to-edge under
42
- * the status bar). Pass `insets.top` in that case, or 0 when the container
43
- * already applies top padding.
44
- */
45
- export function getCapsuleMenuRect(topInsetOffset = 0): CapsuleMenuRect {
46
- const screenWidth = Dimensions.get("window").width
47
- const top = topInsetOffset + CAPSULE_MENU_PADDING
48
- return {
49
- top,
50
- right: CAPSULE_MENU_PADDING,
51
- bottom: top + CAPSULE_MENU_HEIGHT,
52
- left: screenWidth - CAPSULE_MENU_PADDING - CAPSULE_MENU_WIDTH,
53
- width: CAPSULE_MENU_WIDTH,
54
- height: CAPSULE_MENU_HEIGHT,
55
- }
31
+ placement: "corner" | "rail"
56
32
  }
57
33
 
58
34
  export type MiniappColorScheme = "light" | "dark"
@@ -63,37 +39,48 @@ export interface BuildMiniappGlobalsOptions {
63
39
  miniappLocal?: boolean
64
40
  miniappDeveloperMode?: boolean
65
41
  safeAreaInsets: MiniappSafeArea
66
- /**
67
- * True when the WebView container renders edge-to-edge (no top padding for
68
- * the status bar). In that case the capsule menu rect needs to shift down by
69
- * the top inset so its coords match where it's actually drawn on screen.
70
- */
71
- webviewFillsStatusBar?: boolean
42
+ /** Where the host draws its capsule menu over this WebView. */
43
+ capsuleMenu: CapsuleMenuRect
72
44
  /** Current host color scheme. Miniapps may follow this to match the phone. */
73
45
  colorScheme?: MiniappColorScheme
74
46
  }
75
47
 
76
- function safeAreaCssVars(insets: MiniappSafeArea): Record<string, string> {
48
+ // CSS custom properties that mirror the safe-area and capsule menu data, so
49
+ // miniapp CSS (or Tailwind arbitrary values) can read them without touching
50
+ // JS: e.g. `style="margin-top: var(--glassly-capsule-top)"`.
51
+ function layoutCssVars(insets: MiniappSafeArea, capsule: CapsuleMenuRect): Record<string, string> {
77
52
  return {
78
53
  "--glassly-safe-top": `${insets.top}px`,
79
54
  "--glassly-safe-bottom": `${insets.bottom}px`,
80
55
  "--glassly-safe-left": `${insets.left}px`,
81
56
  "--glassly-safe-right": `${insets.right}px`,
57
+ "--glassly-capsule-top": `${capsule.top}px`,
58
+ "--glassly-capsule-bottom": `${capsule.bottom}px`,
59
+ "--glassly-capsule-left": `${capsule.left}px`,
60
+ "--glassly-capsule-right": `${capsule.right}px`,
61
+ "--glassly-capsule-width": `${capsule.width}px`,
62
+ "--glassly-capsule-height": `${capsule.height}px`,
63
+ "--glassly-capsule-center-y": `${capsule.top + capsule.height / 2}px`,
64
+ // Right-side gutter to reserve so content doesn't slide under the
65
+ // capsule: its width + 16px breathing room, none when it sits in the rail.
66
+ "--glassly-capsule-gutter": `${capsule.placement === "rail" ? 0 : capsule.width + 16}px`,
82
67
  }
83
68
  }
84
69
 
85
70
  /**
86
- * JS to inject into a running miniapp when the host's safe area changes (an
87
- * iPhone Duo folding moves its status rail): updates window.Glassly and the
88
- * CSS variables, then fires `glassly:safe-area-change`.
71
+ * JS to inject into a running miniapp when the host's safe area or capsule
72
+ * menu moves (an iPhone Duo folding, or its rail's reserved regions growing):
73
+ * updates window.Glassly and the CSS variables, then fires
74
+ * `glassly:safe-area-change`.
89
75
  */
90
- export function buildSafeAreaUpdateScript(insets: MiniappSafeArea): string {
91
- const sets = Object.entries(safeAreaCssVars(insets))
76
+ export function buildSafeAreaUpdateScript(insets: MiniappSafeArea, capsuleMenu: CapsuleMenuRect): string {
77
+ const sets = Object.entries(layoutCssVars(insets, capsuleMenu))
92
78
  .map(([k, v]) => `document.documentElement.style.setProperty(${JSON.stringify(k)}, ${JSON.stringify(v)});`)
93
79
  .join("\n ")
94
80
  return `
95
81
  window.Glassly = window.Glassly || {};
96
82
  window.Glassly.safeAreaInsets = ${JSON.stringify(insets)};
83
+ window.Glassly.capsuleMenu = ${JSON.stringify(capsuleMenu)};
97
84
  try {
98
85
  ${sets}
99
86
  } catch (e) { /* ignore */ }
@@ -115,37 +102,18 @@ export function buildSafeAreaUpdateScript(insets: MiniappSafeArea): string {
115
102
  * assign to it before the native bridge wires in.
116
103
  */
117
104
  export function buildMiniappGlobalsScript(opts: BuildMiniappGlobalsOptions): string {
118
- const capsuleTopOffset = opts.webviewFillsStatusBar ? opts.safeAreaInsets.top : 0
119
105
  const globals: Record<string, unknown> = {
120
106
  platform: Platform.OS,
121
107
  capabilities: opts.capabilities ?? ["share", "open_url", "copy_clipboard", "download"],
122
108
  safeAreaInsets: opts.safeAreaInsets,
123
- capsuleMenu: getCapsuleMenuRect(capsuleTopOffset),
109
+ capsuleMenu: opts.capsuleMenu,
124
110
  }
125
111
  if (opts.packageName) globals.packageName = opts.packageName
126
112
  if (opts.miniappLocal) globals.miniappLocal = true
127
113
  if (opts.miniappDeveloperMode) globals.miniappDeveloperMode = true
128
114
  if (opts.colorScheme) globals.colorScheme = opts.colorScheme
129
115
 
130
- // CSS custom properties that mirror the capsule menu / safe-area data.
131
- // Miniapp CSS (or Tailwind arbitrary values) can read these without
132
- // touching JS: e.g. `style="margin-top: var(--glassly-capsule-top)"`.
133
- const capsule = globals.capsuleMenu as CapsuleMenuRect
134
- const insets = opts.safeAreaInsets
135
- const capsuleCenter = capsule.top + capsule.height / 2
136
- const cssVars: Record<string, string> = {
137
- ...safeAreaCssVars(insets),
138
- "--glassly-capsule-top": `${capsule.top}px`,
139
- "--glassly-capsule-bottom": `${capsule.bottom}px`,
140
- "--glassly-capsule-left": `${capsule.left}px`,
141
- "--glassly-capsule-right": `${capsule.right}px`,
142
- "--glassly-capsule-width": `${capsule.width}px`,
143
- "--glassly-capsule-height": `${capsule.height}px`,
144
- "--glassly-capsule-center-y": `${capsuleCenter}px`,
145
- // Right-side gutter to reserve so content doesn't slide under the
146
- // capsule: capsule width + 16px breathing room.
147
- "--glassly-capsule-gutter": `${capsule.width + 16}px`,
148
- }
116
+ const cssVars = layoutCssVars(opts.safeAreaInsets, opts.capsuleMenu)
149
117
  const cssVarsBlock = Object.entries(cssVars)
150
118
  .map(([k, v]) => `${k}: ${v};`)
151
119
  .join(" ")