@orbit-work/oem-sdk 0.1.2 → 0.1.4

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.
@@ -26,7 +26,7 @@ var ROOT_KEYS = /* @__PURE__ */ new Set([
26
26
  "contributes"
27
27
  ]);
28
28
  var IDENTITY_KEYS = /* @__PURE__ */ new Set(["productName", "appId", "versionChannel", "protocolScheme", "userDataNamespace"]);
29
- var ASSET_KEYS = /* @__PURE__ */ new Set(["appIcon", "tray", "logo"]);
29
+ var ASSET_KEYS = /* @__PURE__ */ new Set(["appIcon", "tray", "logo", "loginKV"]);
30
30
  var MODE_KEYS = /* @__PURE__ */ new Set(["light", "dark"]);
31
31
  var CONTRIBUTES_KEYS = /* @__PURE__ */ new Set(["slots"]);
32
32
  var NETWORK_KEYS = /* @__PURE__ */ new Set(["allowedOrigins"]);
@@ -167,10 +167,12 @@ function parseAssets(value) {
167
167
  if (!isRecord(value)) throw new Error("assets must be an object");
168
168
  assertKnownKeys(value, ASSET_KEYS, "assets");
169
169
  const tray = value.tray === void 0 ? void 0 : relativePath(value.tray, "assets.tray");
170
+ const loginKV = value.loginKV === void 0 ? void 0 : relativePath(value.loginKV, "assets.loginKV");
170
171
  return {
171
172
  appIcon: relativePath(value.appIcon, "assets.appIcon"),
172
173
  ...tray ? { tray } : {},
173
- logo: relativePath(value.logo, "assets.logo")
174
+ logo: relativePath(value.logo, "assets.logo"),
175
+ ...loginKV ? { loginKV } : {}
174
176
  };
175
177
  }
176
178
  function parseBrandCopy(value, path) {
@@ -509,7 +511,7 @@ async function assertAsset(packageRoot, relative, kind) {
509
511
  if (!info.isFile()) throw new Error(`assets.${kind} must point to a file`);
510
512
  if (info.size > ASSET_BUDGET) throw new Error(`assets.${kind} exceeds 5 MiB`);
511
513
  const extension = extname(file).toLowerCase();
512
- const allowed = kind === "logo" ? /* @__PURE__ */ new Set([".svg", ".png", ".webp"]) : /* @__PURE__ */ new Set([".png"]);
514
+ const allowed = kind === "loginKV" ? /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]) : kind === "logo" ? /* @__PURE__ */ new Set([".svg", ".png", ".webp"]) : /* @__PURE__ */ new Set([".png"]);
513
515
  if (!allowed.has(extension)) throw new Error(`assets.${kind} has unsupported extension: ${extension}`);
514
516
  if (kind === "appIcon" || kind === "tray") {
515
517
  const bytes = await readFile(file);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/manifest.ts","../src/audit-brand.ts","../src/cli.ts"],"names":["text","manifestFile"],"mappings":"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","file":"audit-brand.js","sourcesContent":["import {\n BRAND_ACTION_TOKENS,\n type BrandTheme,\n type BrandThemeToken,\n type LocalizedBranding,\n type TenantBranding,\n UNIFIED_NEUTRAL_TOKENS,\n ds2ContrastRatio,\n} from \"@orbit-work/ui/appearance\"\nimport { type SlotKind, WORKBENCH_KEYED_SLOT_KEYS, WORKBENCH_SLOT_DECLARATIONS } from \"@orbit-work/ui/slot/core\"\n\nexport type BrandSlotName = keyof typeof WORKBENCH_SLOT_DECLARATIONS\n\nexport const BRAND_MANIFEST_SCHEMA = \"@orbit-work/oem-sdk/manifest@1\" as const\n\nexport type BrandIdentity = {\n productName: string\n appId: string\n versionChannel: string\n protocolScheme: string\n /**\n * Optional override for the per-installation user data directory namespace.\n * Managed builds default to the identity appId; workspace packages derive\n * storage from appId and omit this field.\n */\n userDataNamespace?: string\n}\n\n/** Upload-time brand manifest: every field optional, filled fields fully validated. */\nexport type PartialBrandIdentity = { [Key in keyof BrandIdentity]?: BrandIdentity[Key] }\n\nexport type PartialBrandAssets = { [Key in keyof BrandAssets]?: BrandAssets[Key] }\n\nexport type PartialLocalizedBranding = Record<string, Partial<TenantBranding>>\n\nexport type PartialBrandManifest = {\n $schema?: typeof BRAND_MANIFEST_SCHEMA\n id?: string\n /** Installer package description (electron-builder `description`). */\n description?: string\n /** Assistant display name in chat copy; defaults to the branding productName. */\n assistantName?: string\n /** Product homepage packaged into installer metadata. */\n homepage?: string\n /** OS permission prompts overridden by the OEM. */\n permissions?: BrandPermissions\n entry?: string\n identity?: PartialBrandIdentity\n tokens?: BrandManifest[\"tokens\"]\n assets?: PartialBrandAssets\n branding?: PartialLocalizedBranding\n locales?: BrandLocaleSources\n network?: BrandNetworkAccess\n contributes?: { slots: SlotContribution[] }\n}\n\nexport type PartialBrandManifestValidationResult =\n | { ok: true; manifest: PartialBrandManifest }\n | { ok: false; error: string }\n\nexport type BrandAssets = {\n appIcon: string\n tray?: string\n logo: string\n}\n\nexport type BrandLocaleSources = Record<string, string>\n\nexport type BrandNetworkAccess = {\n /** Exact production HTTPS origins added to the packaged renderer connect-src. */\n allowedOrigins: string[]\n}\n\nexport type BrandPermissions = {\n /** macOS microphone prompt (Info.plist NSMicrophoneUsageDescription), written in the OEM's own language. */\n microphoneUsage: string\n}\n\ntype SlotNameOfKind<Kind extends SlotKind> = {\n [Name in BrandSlotName]: (typeof WORKBENCH_SLOT_DECLARATIONS)[Name][\"kind\"] extends Kind ? Name : never\n}[BrandSlotName]\n\ntype SlotContributionBase<Name extends BrandSlotName> = {\n name: Name\n}\n\ntype SingleSlotContribution = {\n [Name in SlotNameOfKind<\"single\">]: SlotContributionBase<Name>\n}[SlotNameOfKind<\"single\">]\n\ntype ListSlotContribution = {\n [Name in SlotNameOfKind<\"list\">]: SlotContributionBase<Name> & { id: string; order: number }\n}[SlotNameOfKind<\"list\">]\n\ntype KeyedSlotName = Extract<keyof typeof WORKBENCH_KEYED_SLOT_KEYS, BrandSlotName>\ntype KeyedSlotContribution = {\n [Name in KeyedSlotName]: SlotContributionBase<Name> & {\n key: (typeof WORKBENCH_KEYED_SLOT_KEYS)[Name][number]\n }\n}[KeyedSlotName]\n\nexport type SlotContribution = SingleSlotContribution | ListSlotContribution | KeyedSlotContribution\n\nexport type BrandManifest = {\n $schema: typeof BRAND_MANIFEST_SCHEMA\n id: string\n /** Installer package description (electron-builder `description`). */\n description?: string\n /** Assistant display name in chat copy; defaults to the branding productName. */\n assistantName?: string\n /** Product homepage packaged into installer metadata. */\n homepage?: string\n /** OS permission prompts overridden by the OEM. */\n permissions?: BrandPermissions\n entry?: string\n identity: BrandIdentity\n tokens?: Partial<Record<\"light\" | \"dark\", Partial<Record<BrandThemeToken, string>>>>\n assets: BrandAssets\n branding: LocalizedBranding\n /** Package-relative dictionaries owned by this OEM namespace. en-US is the required fallback. */\n locales?: BrandLocaleSources\n network?: BrandNetworkAccess\n contributes?: {\n slots: SlotContribution[]\n }\n}\n\nexport type BrandManifestParseOptions = {\n /**\n * Platform builds accept manifests resolved from the managed OEM pipeline:\n * every shape/format/safety check stays in force, only the workspace\n * namespacing bindings are relaxed (productName/versionChannel/protocolScheme\n * must equal id, appId must end with .oem.<id>, reserved feed channels).\n */\n platform?: boolean\n}\n\nexport type BrandManifestValidationResult = { ok: true; manifest: BrandManifest } | { ok: false; error: string }\n\nconst ROOT_KEYS = new Set([\n \"$schema\",\n \"id\",\n \"description\",\n \"assistantName\",\n \"homepage\",\n \"permissions\",\n \"entry\",\n \"identity\",\n \"tokens\",\n \"assets\",\n \"branding\",\n \"locales\",\n \"network\",\n \"contributes\",\n])\nconst IDENTITY_KEYS = new Set([\"productName\", \"appId\", \"versionChannel\", \"protocolScheme\", \"userDataNamespace\"])\nconst ASSET_KEYS = new Set([\"appIcon\", \"tray\", \"logo\"])\nconst MODE_KEYS = new Set([\"light\", \"dark\"])\nconst CONTRIBUTES_KEYS = new Set([\"slots\"])\nconst NETWORK_KEYS = new Set([\"allowedOrigins\"])\nconst PERMISSIONS_KEYS = new Set([\"microphoneUsage\"])\nconst BRANDING_KEYS = new Set([\"productName\", \"companyName\", \"claim\", \"claimNote\", \"slogan\"])\nconst SLOT_COMMON_KEYS = new Set([\"name\"])\nconst BRAND_TOKEN_NAMES = new Set<string>([...UNIFIED_NEUTRAL_TOKENS, ...BRAND_ACTION_TOKENS])\nconst SLOT_DECLARATIONS = WORKBENCH_SLOT_DECLARATIONS as Readonly<Record<string, { kind: SlotKind }>>\nconst HEX = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i\nconst KEBAB_ID = /^[a-z0-9]+(?:-[a-z0-9]+)*$/\nconst APP_ID = /^[a-zA-Z][a-zA-Z0-9]*(?:\\.[a-zA-Z0-9][a-zA-Z0-9-]*){2,}$/\nconst PROTOCOL_SCHEME = /^[a-z][a-z0-9+.-]*$/\nconst SOURCE_ENTRY = /^\\.\\/src\\/.+\\.(?:[cm]?js|[jt]sx?)$/\nconst WINDOWS_DEVICE_NAME = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\\..*)?$/i\nconst OFFICIAL_APP_ID = \"ai.orbit.desktop\"\nconst OFFICIAL_PRODUCT_NAMES = new Set([\"orbitwork\"])\nconst RESERVED_VERSION_CHANNELS = new Set([\n \"stable\",\n \"preview\",\n \"uat\",\n \"latest\",\n \"desktop\",\n \"macos\",\n \"windows\",\n \"linux\",\n])\nconst RESERVED_PROTOCOL_SCHEMES = new Set([\n \"about\",\n \"blob\",\n \"chrome\",\n \"chrome-extension\",\n \"data\",\n \"devtools\",\n \"electron\",\n \"file\",\n \"ftp\",\n \"geo\",\n \"http\",\n \"https\",\n \"javascript\",\n \"mailto\",\n \"orbit\",\n \"sms\",\n \"tel\",\n \"urn\",\n \"ws\",\n \"wss\",\n])\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n}\n\nfunction hasUnsafeProductNameCharacter(value: string): boolean {\n return [...value].some((character) => {\n const code = character.charCodeAt(0)\n return code <= 31 || code === 127 || '<>:\"/\\\\|?*'.includes(character)\n })\n}\n\nfunction productNameNamespace(value: string): string {\n return value\n .normalize(\"NFKD\")\n .replace(/\\p{M}+/gu, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n}\n\nfunction assertKnownKeys(value: Record<string, unknown>, allowed: Set<string>, path: string): void {\n const unknown = Object.keys(value).find((key) => !allowed.has(key))\n if (unknown) throw new Error(`${path} contains unsupported field: ${unknown}`)\n}\n\nfunction text(value: unknown, path: string, limit = 100): string {\n if (typeof value !== \"string\" || !value.trim()) throw new Error(`${path} must be a non-empty string`)\n const result = value.trim()\n if (result.length > limit) throw new Error(`${path} exceeds ${limit} characters`)\n return result\n}\n\nfunction canonicalLocale(value: string, path: string): string {\n try {\n const locale = Intl.getCanonicalLocales(value)[0]\n if (!locale || locale !== value) throw new Error()\n return locale\n } catch {\n throw new Error(`${path} must be a canonical BCP 47 locale`)\n }\n}\n\nfunction relativePath(value: unknown, path: string): string {\n const result = text(value, path, 240)\n if (!result.startsWith(\"./\") || result.includes(\"\\\\\") || result.split(\"/\").includes(\"..\")) {\n throw new Error(`${path} must be a package-relative ./ path without traversal`)\n }\n return result\n}\n\nfunction parseIdentity(value: unknown, id: string, platform: boolean): BrandIdentity {\n if (!isRecord(value)) throw new Error(\"identity must be an object\")\n assertKnownKeys(value, IDENTITY_KEYS, \"identity\")\n const productName = text(value.productName, \"identity.productName\", 64)\n const appId = text(value.appId, \"identity.appId\", 160)\n const versionChannel = text(value.versionChannel, \"identity.versionChannel\", 64)\n const protocolScheme = text(value.protocolScheme, \"identity.protocolScheme\", 64)\n if (value.userDataNamespace !== undefined && !KEBAB_ID.test(text(value.userDataNamespace, \"identity.userDataNamespace\", 64))) {\n throw new Error(\"identity.userDataNamespace must be lowercase kebab-case\")\n }\n if (!APP_ID.test(appId)) throw new Error(\"identity.appId must be a reverse-DNS identifier\")\n if (!KEBAB_ID.test(versionChannel)) throw new Error(\"identity.versionChannel must be kebab-case\")\n // Managed platform builds assign the update channel from the frozen build\n // input; reserved feed names and the == id binding only police workspace\n // packages, where collisions would merge OEM feeds.\n if (!platform && RESERVED_VERSION_CHANNELS.has(versionChannel)) {\n throw new Error(`identity.versionChannel is reserved: ${versionChannel}`)\n }\n if (!PROTOCOL_SCHEME.test(protocolScheme)) {\n throw new Error(\"identity.protocolScheme must be a lowercase URI scheme beginning with a letter\")\n }\n if (RESERVED_PROTOCOL_SCHEMES.has(protocolScheme)) {\n throw new Error(`identity.protocolScheme is reserved: ${protocolScheme}`)\n }\n if (\n hasUnsafeProductNameCharacter(productName) ||\n /[. ]$/.test(productName) ||\n productName === \".\" ||\n productName === \"..\" ||\n WINDOWS_DEVICE_NAME.test(productName)\n ) {\n throw new Error(\"identity.productName must be safe for macOS, Windows, Linux, and release artifact paths\")\n }\n if (OFFICIAL_PRODUCT_NAMES.has(productName.toLowerCase())) {\n throw new Error(`identity.productName is reserved for the official application: ${productName}`)\n }\n if (appId === OFFICIAL_APP_ID) {\n throw new Error(`identity.appId is reserved for the official application: ${appId}`)\n }\n if (!platform && productNameNamespace(productName) !== id) {\n throw new Error(\"identity.productName must normalize to manifest id so installation names cannot collide\")\n }\n if (!platform && versionChannel !== id) {\n throw new Error(\"identity.versionChannel must equal manifest id to keep OEM update feeds namespaced\")\n }\n if (!platform && protocolScheme !== id) {\n throw new Error(\"identity.protocolScheme must equal manifest id to keep OEM deep links namespaced\")\n }\n if (!platform && !appId.endsWith(`.oem.${id}`)) {\n throw new Error(\"identity.appId must end with .oem.<manifest id> to isolate installation and user data\")\n }\n return {\n productName,\n appId,\n versionChannel,\n protocolScheme,\n ...(value.userDataNamespace !== undefined ? { userDataNamespace: text(value.userDataNamespace, \"identity.userDataNamespace\", 64) } : {}),\n }\n}\n\nfunction parseAssets(value: unknown): BrandAssets {\n if (!isRecord(value)) throw new Error(\"assets must be an object\")\n assertKnownKeys(value, ASSET_KEYS, \"assets\")\n const tray = value.tray === undefined ? undefined : relativePath(value.tray, \"assets.tray\")\n return {\n appIcon: relativePath(value.appIcon, \"assets.appIcon\"),\n ...(tray ? { tray } : {}),\n logo: relativePath(value.logo, \"assets.logo\"),\n }\n}\n\nfunction parsePartialAssets(value: unknown): PartialBrandAssets {\n if (!isRecord(value)) throw new Error(\"assets must be an object\")\n assertKnownKeys(value, ASSET_KEYS, \"assets\")\n return {\n ...(value.appIcon !== undefined ? { appIcon: relativePath(value.appIcon, \"assets.appIcon\") } : {}),\n ...(value.logo !== undefined ? { logo: relativePath(value.logo, \"assets.logo\") } : {}),\n ...(value.tray !== undefined ? { tray: relativePath(value.tray, \"assets.tray\") } : {}),\n }\n}\n\nfunction parseBrandCopy(value: unknown, path: string): TenantBranding {\n if (!isRecord(value)) throw new Error(`${path} must be an object`)\n assertKnownKeys(value, BRANDING_KEYS, path)\n const result: TenantBranding = {\n productName: text(value.productName, `${path}.productName`, 64),\n companyName: text(value.companyName, `${path}.companyName`, 80),\n }\n for (const [key, limit] of [\n [\"claim\", 40],\n [\"claimNote\", 48],\n [\"slogan\", 68],\n ] as const) {\n if (value[key] !== undefined) result[key] = text(value[key], `${path}.${key}`, limit)\n }\n return result\n}\n\nfunction parseBranding(value: unknown): LocalizedBranding {\n if (!isRecord(value)) throw new Error(\"branding must be a locale map\")\n const result: LocalizedBranding = {}\n for (const [rawLocale, copy] of Object.entries(value)) {\n const locale = canonicalLocale(rawLocale, `branding.${rawLocale}`)\n result[locale] = parseBrandCopy(copy, `branding.${locale}`)\n }\n if (!result[\"en-US\"]) throw new Error(\"branding.en-US is required\")\n return result\n}\n\nfunction parseLocales(value: unknown): BrandLocaleSources | undefined {\n if (value === undefined) return undefined\n if (!isRecord(value)) throw new Error(\"locales must be a locale map\")\n const result: BrandLocaleSources = {}\n for (const [rawLocale, source] of Object.entries(value)) {\n const locale = canonicalLocale(rawLocale, `locales.${rawLocale}`)\n result[locale] = relativePath(source, `locales.${locale}`)\n }\n if (!result[\"en-US\"]) throw new Error(\"locales.en-US is required when locales are declared\")\n return result\n}\n\nfunction isDevelopmentHostname(hostname: string): boolean {\n const lower = hostname.toLowerCase()\n if (lower === \"localhost\" || lower.endsWith(\".localhost\") || lower.endsWith(\".local\")) return true\n if ([\"::1\", \"[::1]\"].includes(lower) || /^(?:fc|fd|fe8|fe9|fea|feb)/.test(lower.replace(/[\\[\\]]/g, \"\"))) {\n return true\n }\n const ipv4 = lower\n .match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/)\n ?.slice(1)\n .map(Number)\n if (ipv4) {\n const [a, b] = ipv4\n if (\n a === 0 ||\n a === 10 ||\n a === 127 ||\n (a === 169 && b === 254) ||\n (a === 172 && b! >= 16 && b! <= 31) ||\n (a === 192 && b === 168)\n ) {\n return true\n }\n }\n return lower\n .split(/[.-]/)\n .some((label) => [\"dev\", \"development\", \"test\", \"testing\", \"stage\", \"staging\", \"uat\"].includes(label))\n}\n\nfunction parseNetwork(value: unknown): BrandNetworkAccess | undefined {\n if (value === undefined) return undefined\n if (!isRecord(value)) throw new Error(\"network must be an object\")\n assertKnownKeys(value, NETWORK_KEYS, \"network\")\n if (!Array.isArray(value.allowedOrigins) || value.allowedOrigins.length === 0) {\n throw new Error(\"network.allowedOrigins must be a non-empty array\")\n }\n const allowedOrigins = value.allowedOrigins.map((raw, index) => {\n const path = `network.allowedOrigins[${index}]`\n const origin = text(raw, path, 240)\n let parsed: URL\n try {\n parsed = new URL(origin)\n } catch {\n throw new Error(`${path} must be an exact HTTPS origin`)\n }\n if (\n parsed.protocol !== \"https:\" ||\n parsed.username ||\n parsed.password ||\n parsed.pathname !== \"/\" ||\n parsed.search ||\n parsed.hash ||\n parsed.origin !== origin\n ) {\n throw new Error(`${path} must be a canonical exact HTTPS origin without credentials, path, query, or fragment`)\n }\n if (isDevelopmentHostname(parsed.hostname)) {\n throw new Error(`${path} must be a production origin, not localhost, private network, dev, test, staging, or UAT`)\n }\n return origin\n })\n if (new Set(allowedOrigins).size !== allowedOrigins.length) {\n throw new Error(\"network.allowedOrigins must not contain duplicates\")\n }\n return { allowedOrigins }\n}\n\nfunction parseHomepage(value: unknown): string {\n const homepage = text(value, \"homepage\", 200)\n let parsed: URL\n try {\n parsed = new URL(homepage)\n } catch {\n throw new Error(\"homepage must be an https URL\")\n }\n if (parsed.protocol !== \"https:\" || !parsed.hostname) {\n throw new Error(\"homepage must be an https URL\")\n }\n return homepage\n}\n\nfunction parsePermissions(value: unknown): BrandPermissions {\n if (!isRecord(value)) throw new Error(\"permissions must be an object\")\n assertKnownKeys(value, PERMISSIONS_KEYS, \"permissions\")\n return { microphoneUsage: text(value.microphoneUsage, \"permissions.microphoneUsage\", 120) }\n}\n\nfunction parseModeTokens(value: unknown, path: string): Partial<Record<BrandThemeToken, string>> { if (!isRecord(value)) throw new Error(`${path} must be an object`)\n const result: Partial<Record<BrandThemeToken, string>> = {}\n for (const [name, raw] of Object.entries(value)) {\n if (!BRAND_TOKEN_NAMES.has(name)) throw new Error(`${path} contains forbidden token: ${name}`)\n if (typeof raw !== \"string\" || !HEX.test(raw)) throw new Error(`${path}.${name} must be a hex color`)\n result[name as BrandThemeToken] = raw.toLowerCase()\n }\n\n const touchedNeutral = UNIFIED_NEUTRAL_TOKENS.some((name) => result[name] !== undefined)\n if (touchedNeutral) {\n const missing = UNIFIED_NEUTRAL_TOKENS.filter((name) => result[name] === undefined)\n if (missing.length) throw new Error(`${path} neutral group is incomplete: ${missing.join(\", \")}`)\n for (const textToken of [\"--ow-text\", \"--ow-text-2\"] as const) {\n for (const surfaceToken of [\"--ow-bg\", \"--ow-surface\", \"--ow-surface-2\"] as const) {\n const ratio = ds2ContrastRatio(result[textToken] as string, result[surfaceToken] as string)\n if (ratio < 4.5) {\n throw new Error(\n `${path} contrast ${textToken} on ${surfaceToken} is ${ratio.toFixed(2)}:1; expected >= 4.5:1`,\n )\n }\n }\n }\n }\n\n const touchedAction = BRAND_ACTION_TOKENS.some((name) => result[name] !== undefined)\n if (touchedAction) {\n const missing = BRAND_ACTION_TOKENS.filter((name) => result[name] === undefined)\n if (missing.length) throw new Error(`${path} action pole group is incomplete: ${missing.join(\", \")}`)\n for (const background of [\"--ow-btn-primary-bg\", \"--ow-btn-primary-hover\", \"--ow-btn-primary-press\"] as const) {\n const ratio = ds2ContrastRatio(result[background] as string, result[\"--ow-btn-primary-fg\"] as string)\n if (ratio < 4.5) {\n throw new Error(\n `${path} contrast --ow-btn-primary-fg on ${background} is ${ratio.toFixed(2)}:1; expected >= 4.5:1`,\n )\n }\n }\n }\n return result\n}\n\nfunction parseTokens(value: unknown): BrandManifest[\"tokens\"] {\n if (value === undefined) return undefined\n if (!isRecord(value)) throw new Error(\"tokens must be an object\")\n assertKnownKeys(value, MODE_KEYS, \"tokens\")\n const light = value.light === undefined ? undefined : parseModeTokens(value.light, \"tokens.light\")\n const dark = value.dark === undefined ? undefined : parseModeTokens(value.dark, \"tokens.dark\")\n if (!light && !dark) throw new Error(\"tokens must define light or dark\")\n return { ...(light ? { light } : {}), ...(dark ? { dark } : {}) }\n}\n\nfunction slotAllowedKeys(kind: SlotKind): Set<string> {\n return new Set([\n ...SLOT_COMMON_KEYS,\n ...(kind === \"list\" ? [\"id\", \"order\"] : []),\n ...(kind === \"keyed\" ? [\"key\"] : []),\n ])\n}\n\nfunction parseSlotContribution(value: unknown, index: number): SlotContribution {\n const path = `contributes.slots[${index}]`\n if (!isRecord(value)) throw new Error(`${path} must be an object`)\n const name = text(value.name, `${path}.name`, 120)\n const declaration = SLOT_DECLARATIONS[name]\n if (!declaration) throw new Error(`${path}.name is not in the host slot whitelist: ${name}`)\n assertKnownKeys(value, slotAllowedKeys(declaration.kind), path)\n const common = { name: name as BrandSlotName }\n if (declaration.kind === \"list\") {\n const id = text(value.id, `${path}.id`, 100)\n if (typeof value.order !== \"number\" || !Number.isFinite(value.order)) {\n throw new Error(`${path}.order must be a finite number`)\n }\n return { ...common, id, order: value.order } as SlotContribution\n }\n if (declaration.kind === \"keyed\") {\n const key = text(value.key, `${path}.key`, 100)\n const allowed = WORKBENCH_KEYED_SLOT_KEYS[name as KeyedSlotName] as readonly string[] | undefined\n if (!allowed?.includes(key)) throw new Error(`${path}.key is not reachable by the host: ${key}`)\n return { ...common, key } as SlotContribution\n }\n return common as SlotContribution\n}\n\nfunction contributionCell(value: SlotContribution): string {\n if (\"id\" in value) return value.id\n if (\"key\" in value) return value.key\n return \"single\"\n}\n\nfunction parseContributes(value: unknown): BrandManifest[\"contributes\"] {\n if (value === undefined) return undefined\n if (!isRecord(value)) throw new Error(\"contributes must be an object\")\n assertKnownKeys(value, CONTRIBUTES_KEYS, \"contributes\")\n if (!Array.isArray(value.slots)) throw new Error(\"contributes.slots must be an array\")\n const slots = value.slots.map(parseSlotContribution)\n const seen = new Set<string>()\n for (const slot of slots) {\n const identity = `${slot.name}\\0${contributionCell(slot)}`\n if (seen.has(identity)) throw new Error(`duplicate slot contribution: ${slot.name} / ${contributionCell(slot)}`)\n seen.add(identity)\n }\n return { slots }\n}\n\nexport function parseBrandManifest(input: unknown, options?: BrandManifestParseOptions): BrandManifestValidationResult {\n try {\n const platform = options?.platform === true\n if (!isRecord(input)) throw new Error(\"brand manifest must be a JSON object\")\n assertKnownKeys(input, ROOT_KEYS, \"manifest\")\n if (input.$schema !== BRAND_MANIFEST_SCHEMA) throw new Error(`$schema must equal ${BRAND_MANIFEST_SCHEMA}`)\n const id = text(input.id, \"id\", 64)\n if (!KEBAB_ID.test(id)) throw new Error(\"id must be lowercase kebab-case\")\n const entry = input.entry === undefined ? undefined : relativePath(input.entry, \"entry\")\n if (entry && !SOURCE_ENTRY.test(entry)) {\n throw new Error(\"entry must point to reviewed source under ./src using .js, .mjs, .jsx, .ts, or .tsx\")\n }\n const contributes = parseContributes(input.contributes)\n if ((contributes?.slots.length ?? 0) > 0 && !entry)\n throw new Error(\"entry is required when contributes.slots is not empty\")\n const tokens = parseTokens(input.tokens)\n const locales = parseLocales(input.locales)\n const network = parseNetwork(input.network)\n const identity = parseIdentity(input.identity, id, platform)\n if (!platform && productNameNamespace(identity.productName) !== id) {\n throw new Error(\"identity.productName must normalize to manifest id so installation names cannot collide\")\n }\n if (!platform && identity.versionChannel !== id) {\n throw new Error(\"identity.versionChannel must equal manifest id to keep OEM update feeds namespaced\")\n }\n if (!platform && identity.protocolScheme !== id) {\n throw new Error(\"identity.protocolScheme must equal manifest id to keep OEM deep links namespaced\")\n }\n if (!platform && !identity.appId.endsWith(`.oem.${id}`)) {\n throw new Error(\"identity.appId must end with .oem.<manifest id> to isolate installation and user data\")\n }\n return {\n ok: true,\n manifest: {\n $schema: BRAND_MANIFEST_SCHEMA,\n id,\n ...(input.description !== undefined ? { description: text(input.description, \"description\", 200) } : {}),\n ...(input.assistantName !== undefined ? { assistantName: text(input.assistantName, \"assistantName\", 48) } : {}),\n ...(input.homepage !== undefined ? { homepage: parseHomepage(input.homepage) } : {}),\n ...(input.permissions !== undefined ? { permissions: parsePermissions(input.permissions) } : {}),\n ...(entry ? { entry } : {}),\n identity,\n ...(tokens ? { tokens } : {}),\n assets: parseAssets(input.assets),\n branding: parseBranding(input.branding),\n ...(locales ? { locales } : {}),\n ...(network ? { network } : {}),\n ...(contributes ? { contributes } : {}),\n },\n }\n } catch (cause) {\n return { ok: false, error: cause instanceof Error ? cause.message : String(cause) }\n }\n}\n\nfunction parsePartialIdentity(value: unknown): PartialBrandIdentity {\n if (!isRecord(value)) throw new Error(\"identity must be an object\")\n assertKnownKeys(value, IDENTITY_KEYS, \"identity\")\n // Filled fields are validated exactly like the strict parser (formats,\n // reserved values), but the id-binding rules are skipped: partial manifests\n // are merged with source defaults before consumption, and the resolved\n // product is re-validated where those bindings apply.\n if (value.userDataNamespace !== undefined && !KEBAB_ID.test(text(value.userDataNamespace, \"identity.userDataNamespace\", 64))) {\n throw new Error(\"identity.userDataNamespace must be lowercase kebab-case\")\n }\n if (value.appId !== undefined) {\n const appId = text(value.appId, \"identity.appId\", 160)\n if (!APP_ID.test(appId)) throw new Error(\"identity.appId must be a reverse-DNS identifier\")\n if (appId === OFFICIAL_APP_ID) {\n throw new Error(`identity.appId is reserved for the official application: ${appId}`)\n }\n }\n if (value.versionChannel !== undefined) {\n const versionChannel = text(value.versionChannel, \"identity.versionChannel\", 64)\n if (!KEBAB_ID.test(versionChannel)) throw new Error(\"identity.versionChannel must be kebab-case\")\n }\n if (value.protocolScheme !== undefined) {\n const protocolScheme = text(value.protocolScheme, \"identity.protocolScheme\", 64)\n if (!PROTOCOL_SCHEME.test(protocolScheme)) {\n throw new Error(\"identity.protocolScheme must be a lowercase URI scheme beginning with a letter\")\n }\n if (RESERVED_PROTOCOL_SCHEMES.has(protocolScheme)) {\n throw new Error(`identity.protocolScheme is reserved: ${protocolScheme}`)\n }\n }\n if (value.productName !== undefined) {\n const productName = text(value.productName, \"identity.productName\", 64)\n if (\n hasUnsafeProductNameCharacter(productName) ||\n /[. ]$/.test(productName) ||\n productName === \".\" ||\n productName === \"..\" ||\n WINDOWS_DEVICE_NAME.test(productName)\n ) {\n throw new Error(\"identity.productName must be safe for macOS, Windows, Linux, and release artifact paths\")\n }\n if (OFFICIAL_PRODUCT_NAMES.has(productName.toLowerCase())) {\n throw new Error(`identity.productName is reserved for the official application: ${productName}`)\n }\n }\n return {\n ...(value.productName !== undefined ? { productName: text(value.productName, \"identity.productName\", 64) } : {}),\n ...(value.appId !== undefined ? { appId: text(value.appId, \"identity.appId\", 160) } : {}),\n ...(value.versionChannel !== undefined ? { versionChannel: text(value.versionChannel, \"identity.versionChannel\", 64) } : {}),\n ...(value.protocolScheme !== undefined ? { protocolScheme: text(value.protocolScheme, \"identity.protocolScheme\", 64) } : {}),\n ...(value.userDataNamespace !== undefined\n ? { userDataNamespace: text(value.userDataNamespace, \"identity.userDataNamespace\", 64) }\n : {}),\n }\n}\n\nfunction parsePartialBranding(value: unknown): PartialLocalizedBranding {\n if (!isRecord(value)) throw new Error(\"branding must be a locale map\")\n const result: PartialLocalizedBranding = {}\n for (const [rawLocale, copy] of Object.entries(value)) {\n const locale = canonicalLocale(rawLocale, `branding.${rawLocale}`)\n if (!isRecord(copy)) throw new Error(`branding.${locale} must be an object`)\n assertKnownKeys(copy, BRANDING_KEYS, `branding.${locale}`)\n const partial: Partial<TenantBranding> = {}\n for (const [key, limit] of [\n [\"productName\", 64],\n [\"companyName\", 80],\n [\"claim\", 40],\n [\"claimNote\", 48],\n [\"slogan\", 68],\n ] as const) {\n if (copy[key] !== undefined) partial[key] = text(copy[key], `branding.${locale}.${key}`, limit)\n }\n result[locale] = partial\n }\n return result\n}\n\n/**\n * Validates an upload-time (partial) brand manifest: omitted fields inherit\n * source defaults at merge time; every filled field is fully validated. The\n * resolved product must still pass `parseBrandManifest` where it is consumed.\n */\nexport function parsePartialBrandManifest(input: unknown): PartialBrandManifestValidationResult {\n try {\n if (!isRecord(input)) throw new Error(\"brand manifest must be a JSON object\")\n assertKnownKeys(input, ROOT_KEYS, \"manifest\")\n if (input.$schema !== undefined && input.$schema !== BRAND_MANIFEST_SCHEMA) {\n throw new Error(`$schema must equal ${BRAND_MANIFEST_SCHEMA}`)\n }\n const entry = input.entry === undefined ? undefined : relativePath(input.entry, \"entry\")\n if (entry && !SOURCE_ENTRY.test(entry)) {\n throw new Error(\"entry must point to reviewed source under ./src using .js, .mjs, .jsx, .ts, or .tsx\")\n }\n const contributes = parseContributes(input.contributes)\n if ((contributes?.slots.length ?? 0) > 0 && !entry)\n throw new Error(\"entry is required when contributes.slots is not empty\")\n if (input.id !== undefined) {\n const id = text(input.id, \"id\", 64)\n if (!KEBAB_ID.test(id)) throw new Error(\"id must be lowercase kebab-case\")\n }\n return {\n ok: true,\n manifest: {\n ...(input.id !== undefined ? { id: text(input.id, \"id\", 64) } : {}),\n ...(input.description !== undefined ? { description: text(input.description, \"description\", 200) } : {}),\n ...(input.assistantName !== undefined ? { assistantName: text(input.assistantName, \"assistantName\", 48) } : {}),\n ...(input.homepage !== undefined ? { homepage: parseHomepage(input.homepage) } : {}),\n ...(input.permissions !== undefined ? { permissions: parsePermissions(input.permissions) } : {}),\n ...(entry ? { entry } : {}),\n ...(input.identity !== undefined ? { identity: parsePartialIdentity(input.identity) } : {}),\n ...(input.tokens !== undefined ? { tokens: parseTokens(input.tokens) } : {}),\n ...(input.assets !== undefined ? { assets: parsePartialAssets(input.assets) } : {}),\n ...(input.branding !== undefined ? { branding: parsePartialBranding(input.branding) } : {}),\n ...(input.locales !== undefined ? { locales: parseLocales(input.locales) } : {}),\n ...(input.network !== undefined ? { network: parseNetwork(input.network) } : {}),\n ...(contributes ? { contributes } : {}),\n },\n }\n } catch (cause) {\n return { ok: false, error: cause instanceof Error ? cause.message : String(cause) }\n }\n}\n\nexport function manifestToBrandTheme(manifest: BrandManifest): BrandTheme {\n return {\n id: manifest.id,\n logo: manifest.assets.logo,\n modes: manifest.tokens ?? {},\n branding: manifest.branding,\n }\n}\n","import { readFile, realpath, stat } from \"node:fs/promises\"\nimport { dirname, extname, resolve, sep } from \"node:path\"\nimport { gzipSync } from \"node:zlib\"\nimport { init, parse } from \"es-module-lexer\"\nimport { type Loader, transform } from \"esbuild\"\nimport { type LocaleDictionary, validateDictionary } from \"./locale.ts\"\nimport { type BrandManifest, parseBrandManifest } from \"./manifest.ts\"\n\nconst ENTRY_GZIP_BUDGET = 256 * 1024\nconst ASSET_BUDGET = 5 * 1024 * 1024\nconst LOCALE_BUDGET = 256 * 1024\nconst IMPORT_ALLOWLIST = new Set([\n \"@orbit-work/oem-sdk\",\n \"@orbit-work/oem-sdk/runtime\",\n \"@orbit-work/ui\",\n \"react\",\n \"react-dom\",\n \"react/jsx-runtime\",\n \"react/jsx-dev-runtime\",\n])\nconst CREDENTIAL_ASSIGNMENT = /\\b(?:api[_-]?key|client[_-]?secret|access[_-]?token|password)\\b\\s*[:=]\\s*([^\\n;]+)/gi\nconst STATIC_STRING = /\"([^\"\\n]*(?:\\\\.[^\"\\n]*)*)\"|'([^'\\n]*(?:\\\\.[^'\\n]*)*)'|`([^`\\n]*(?:\\\\.[^`\\n]*)*)`/g\nconst CODE_EXTENSIONS = new Set([\".js\", \".mjs\", \".cjs\", \".jsx\", \".ts\", \".tsx\"])\nconst ASSET_EXTENSIONS = new Set([\".png\", \".svg\", \".webp\", \".jpg\", \".jpeg\", \".gif\", \".woff\", \".woff2\"])\nconst DATA_EXTENSIONS = new Set([\".json\"])\nconst CSS_IMPORT = /@import\\s+(?:url\\(\\s*)?[\"']([^\"']+)[\"']\\s*\\)?/g\nconst CSS_URL = /url\\(\\s*[\"']?([^\"')]+)[\"']?\\s*\\)/g\nconst STATIC_HTTP_URL = /https?:\\/\\/[^\\s\"'`<>)]+/g\n\nexport type BrandAuditResult = {\n manifest: BrandManifest\n entryGzipBytes: number\n checkedAssets: string[]\n checkedModules: string[]\n checkedLocales: string[]\n}\n\nexport const OEM_ENTRY_IMPORTS = Object.freeze([...IMPORT_ALLOWLIST].sort())\n\nfunction containsLikelyHardCodedCredential(source: string): boolean {\n CREDENTIAL_ASSIGNMENT.lastIndex = 0\n for (const assignment of source.matchAll(CREDENTIAL_ASSIGNMENT)) {\n const rightHandSide = assignment[1] ?? \"\"\n const literalValue = [...rightHandSide.matchAll(STATIC_STRING)]\n .map((match) => match[1] ?? match[2] ?? match[3] ?? \"\")\n .join(\"\")\n if (literalValue.length >= 8) return true\n }\n return false\n}\n\nfunction parseLocaleDictionary(source: string, label: string): LocaleDictionary {\n let value: unknown\n try {\n value = JSON.parse(source)\n } catch {\n throw new Error(`${label} must contain valid JSON`)\n }\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(`${label} must contain a JSON object`)\n }\n const dictionary = value as Record<string, unknown>\n if (Object.keys(dictionary).length === 0) throw new Error(`${label} must not be empty`)\n const invalidKey = Object.keys(dictionary).find((key) => !/^[A-Za-z][A-Za-z0-9]*(?:[._-][A-Za-z0-9]+)*$/.test(key))\n if (invalidKey) throw new Error(`${label} contains an invalid translation key: ${invalidKey}`)\n const invalidValue = Object.entries(dictionary).find(([, text]) => typeof text !== \"string\")\n if (invalidValue) throw new Error(`${label}.${invalidValue[0]} must be a string`)\n return dictionary as LocaleDictionary\n}\n\nasync function auditLocaleDictionaries(\n packageRoot: string,\n locales: NonNullable<BrandManifest[\"locales\"]>,\n): Promise<string[]> {\n const dictionaries = new Map<string, LocaleDictionary>()\n for (const [locale, relative] of Object.entries(locales)) {\n const file = await resolvePackageFile(packageRoot, relative, `locales.${locale}`)\n const info = await stat(file)\n if (!info.isFile()) throw new Error(`locales.${locale} must point to a file`)\n if (info.size > LOCALE_BUDGET) throw new Error(`locales.${locale} exceeds 256 KiB`)\n dictionaries.set(locale, parseLocaleDictionary(await readFile(file, \"utf8\"), `locales.${locale}`))\n }\n const baseline = dictionaries.get(\"en-US\") as LocaleDictionary\n for (const [locale, dictionary] of dictionaries) {\n const result = validateDictionary(baseline, dictionary)\n if (!result.ok) {\n throw new Error(\n `locales.${locale} must match en-US keys (missing: ${result.missing.join(\", \") || \"none\"}; unknown: ${result.unknown.join(\", \") || \"none\"}; invalid: ${result.invalid.join(\", \") || \"none\"})`,\n )\n }\n }\n return Object.keys(locales)\n}\n\nasync function resolvePackageFile(packageRoot: string, relative: string, label: string): Promise<string> {\n const candidate = resolve(packageRoot, relative)\n if (candidate !== packageRoot && !candidate.startsWith(`${packageRoot}${sep}`)) {\n throw new Error(`${label} escapes the brand package`)\n }\n const actual = await realpath(candidate)\n if (actual !== packageRoot && !actual.startsWith(`${packageRoot}${sep}`)) {\n throw new Error(`${label} resolves outside the brand package`)\n }\n return actual\n}\n\nasync function assertAsset(\n packageRoot: string,\n relative: string,\n kind: keyof BrandManifest[\"assets\"],\n): Promise<string> {\n const file = await resolvePackageFile(packageRoot, relative, `assets.${kind}`)\n const info = await stat(file)\n if (!info.isFile()) throw new Error(`assets.${kind} must point to a file`)\n if (info.size > ASSET_BUDGET) throw new Error(`assets.${kind} exceeds 5 MiB`)\n const extension = extname(file).toLowerCase()\n const allowed = kind === \"logo\" ? new Set([\".svg\", \".png\", \".webp\"]) : new Set([\".png\"])\n if (!allowed.has(extension)) throw new Error(`assets.${kind} has unsupported extension: ${extension}`)\n if (kind === \"appIcon\" || kind === \"tray\") {\n const bytes = await readFile(file)\n if (bytes.length < 24 || bytes.toString(\"hex\", 0, 8) !== \"89504e470d0a1a0a\") {\n throw new Error(`assets.${kind} must be a valid PNG`)\n }\n const width = bytes.readUInt32BE(16)\n const height = bytes.readUInt32BE(20)\n if (kind === \"appIcon\") {\n if (width !== height || width < 512) throw new Error(\"assets.appIcon must be square and at least 512x512\")\n } else if (width !== 32 || height !== 32) {\n // One tray asset serves every platform: 32px covers the macOS menu bar\n // @2x template and scales down for the Windows/Linux system trays.\n throw new Error(\"assets.tray must be a 32x32 PNG (single asset used on macOS, Windows, and Linux)\")\n }\n }\n return file\n}\n\ntype ModuleKind = \"code\" | \"css\" | \"asset\" | \"data\"\n\nfunction moduleKind(file: string, specifier: string): ModuleKind {\n const extension = extname(file).toLowerCase()\n if (CODE_EXTENSIONS.has(extension)) return \"code\"\n if (extension === \".css\") {\n if (!file.endsWith(\".module.css\")) {\n throw new Error(`entry styles must use CSS Modules (*.module.css): ${specifier}`)\n }\n return \"css\"\n }\n if (ASSET_EXTENSIONS.has(extension)) return \"asset\"\n if (DATA_EXTENSIONS.has(extension)) return \"data\"\n throw new Error(`entry imports an unsupported module type: ${specifier}`)\n}\n\nasync function resolveRelativeModule(\n packageRoot: string,\n importer: string,\n specifier: string,\n): Promise<{ file: string; kind: ModuleKind }> {\n if (specifier.includes(\"?\") || specifier.includes(\"#\")) {\n throw new Error(`entry relative import must not contain a query or fragment: ${specifier}`)\n }\n const base = resolve(dirname(importer), specifier)\n const candidates = extname(base)\n ? [base]\n : [base, ...[\".js\", \".mjs\", \".cjs\", \".jsx\", \".ts\", \".tsx\"].map((extension) => `${base}${extension}`)]\n for (const candidate of candidates) {\n try {\n const actual = await realpath(candidate)\n if (actual !== packageRoot && !actual.startsWith(`${packageRoot}${sep}`)) {\n throw new Error(`entry import resolves outside the brand package: ${specifier}`)\n }\n const info = await stat(actual)\n if (!info.isFile()) throw new Error(`entry import must resolve to a file: ${specifier}`)\n if (info.size > ASSET_BUDGET) throw new Error(`entry import exceeds 5 MiB: ${specifier}`)\n return { file: actual, kind: moduleKind(actual, specifier) }\n } catch (error) {\n if (error instanceof Error && !error.message.includes(\"ENOENT\")) throw error\n }\n }\n throw new Error(`entry relative import cannot be resolved: ${specifier}`)\n}\n\nfunction assertScopedCss(source: string, file: string): void {\n const withoutComments = source.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\")\n if (/:global\\b/.test(withoutComments)) throw new Error(`CSS Module uses forbidden :global selector: ${file}`)\n if (/(?:^|[,{]\\s*)(?:html|body|:root|\\*)\\b/m.test(withoutComments)) {\n throw new Error(`CSS Module contains a global root selector: ${file}`)\n }\n if (/(?:^|[\\s:(,])(?:#(?:[0-9a-f]{3,8})|rgba?\\(|hsla?\\()/i.test(withoutComments)) {\n throw new Error(`CSS Module colors must use DS2 --ow-* tokens: ${file}`)\n }\n}\n\nfunction cssRelativeSpecifiers(source: string, file: string): string[] {\n const specifiers = new Set<string>()\n for (const pattern of [CSS_IMPORT, CSS_URL]) {\n pattern.lastIndex = 0\n for (const match of source.matchAll(pattern)) {\n const specifier = match[1]?.trim()\n if (!specifier) continue\n if (/^(?:data:|https?:|\\/\\/|\\/)/i.test(specifier)) {\n throw new Error(`CSS Module contains a non-package-relative URL: ${file}: ${specifier}`)\n }\n specifiers.add(specifier)\n }\n }\n return [...specifiers]\n}\n\nfunction esbuildLoader(file: string): Loader {\n switch (extname(file).toLowerCase()) {\n case \".ts\":\n return \"ts\"\n case \".tsx\":\n return \"tsx\"\n case \".jsx\":\n return \"jsx\"\n default:\n return \"js\"\n }\n}\n\nfunction assertDeclaredNetworkOrigins(source: string, file: string, allowedOrigins: ReadonlySet<string>): void {\n STATIC_HTTP_URL.lastIndex = 0\n for (const match of source.matchAll(STATIC_HTTP_URL)) {\n let origin: string\n try {\n origin = new URL(match[0]).origin\n } catch {\n continue\n }\n if (!allowedOrigins.has(origin)) {\n throw new Error(`entry module references undeclared network origin ${origin}: ${file}`)\n }\n }\n}\n\nasync function auditEntryModuleGraph(\n packageRoot: string,\n entryFile: string,\n allowedOrigins: ReadonlySet<string>,\n): Promise<{ gzipBytes: number; files: string[] }> {\n await init\n const pending: Array<{ file: string; kind: ModuleKind }> = [{ file: entryFile, kind: \"code\" }]\n const visited = new Set<string>()\n const sources: Buffer[] = []\n\n while (pending.length) {\n const { file, kind } = pending.pop() as { file: string; kind: ModuleKind }\n if (visited.has(file)) continue\n visited.add(file)\n const bytes = await readFile(file)\n sources.push(Buffer.from(`// ${file.slice(packageRoot.length)}\\n`), bytes)\n if (kind === \"asset\" || kind === \"data\") continue\n\n const source = bytes.toString(\"utf8\")\n if (kind === \"css\") {\n assertScopedCss(source, file)\n for (const specifier of cssRelativeSpecifiers(source, file)) {\n pending.push(await resolveRelativeModule(packageRoot, file, specifier))\n }\n continue\n }\n if (containsLikelyHardCodedCredential(source)) {\n throw new Error(`entry module contains a likely hard-coded credential: ${file}`)\n }\n assertDeclaredNetworkOrigins(source, file, allowedOrigins)\n if (/\\brequire\\s*\\(/.test(source))\n throw new Error(`entry module uses require(), which is not browser-safe: ${file}`)\n\n let imports: ReturnType<typeof parse>[0]\n try {\n const transformed = await transform(source, {\n loader: esbuildLoader(file),\n format: \"esm\",\n jsx: \"automatic\",\n sourcemap: false,\n sourcefile: file,\n })\n ;[imports] = parse(transformed.code)\n } catch (error) {\n throw new Error(\n `entry module cannot be parsed: ${file}: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n for (const imported of imports) {\n const specifier = imported.n\n if (!specifier) throw new Error(`entry module uses a non-literal dynamic import: ${file}`)\n if (imported.d >= 0) throw new Error(`entry module uses dynamic import(), which is not supported: ${file}`)\n if (specifier.startsWith(\"node:\")) throw new Error(`entry imports Node.js module: ${specifier}`)\n if (specifier.startsWith(\".\")) {\n pending.push(await resolveRelativeModule(packageRoot, file, specifier))\n continue\n }\n if (!IMPORT_ALLOWLIST.has(specifier)) throw new Error(`entry imports non-public dependency: ${specifier}`)\n }\n }\n\n return { gzipBytes: gzipSync(Buffer.concat(sources)).byteLength, files: [...visited] }\n}\n\nexport async function auditBrandPackage(\n manifestFile: string,\n options: { developmentAllowedOrigins?: readonly string[]; platform?: boolean } = {},\n): Promise<BrandAuditResult> {\n const absoluteManifest = await realpath(resolve(manifestFile))\n const packageRoot = await realpath(resolve(absoluteManifest, \"..\"))\n const raw = JSON.parse(await readFile(absoluteManifest, \"utf8\")) as unknown\n // Managed pipeline builds audit a merge-resolved manifest whose identity\n // was assigned from the frozen build input; workspace packages keep the\n // strict namespacing bindings.\n const parsed = parseBrandManifest(raw, { platform: options.platform === true })\n if (!parsed.ok) throw new Error(`manifest contract failed: ${parsed.error}`)\n const manifest = parsed.manifest\n\n const checkedAssets: string[] = []\n for (const [kind, relative] of Object.entries(manifest.assets) as Array<[keyof BrandManifest[\"assets\"], string]>) {\n await assertAsset(packageRoot, relative, kind)\n checkedAssets.push(relative)\n }\n\n let entryGzipBytes = 0\n let checkedModules: string[] = []\n const checkedLocales = manifest.locales ? await auditLocaleDictionaries(packageRoot, manifest.locales) : []\n if (manifest.entry) {\n const entryFile = await resolvePackageFile(packageRoot, manifest.entry, \"entry\")\n const graph = await auditEntryModuleGraph(\n packageRoot,\n entryFile,\n new Set([...(manifest.network?.allowedOrigins ?? []), ...(options.developmentAllowedOrigins ?? [])]),\n )\n entryGzipBytes = graph.gzipBytes\n checkedModules = graph.files.map((file) => `.${file.slice(packageRoot.length)}`)\n if (entryGzipBytes > ENTRY_GZIP_BUDGET) {\n throw new Error(`entry gzip size ${entryGzipBytes} exceeds ${ENTRY_GZIP_BUDGET} byte budget`)\n }\n }\n\n return { manifest, entryGzipBytes, checkedAssets, checkedModules, checkedLocales }\n}\n","#!/usr/bin/env node\n\nimport { auditBrandPackage } from \"./audit-brand.ts\"\n\nconst manifestFile = process.argv[2]\nif (manifestFile === \"--help\" || manifestFile === \"-h\") {\n console.log(\"Usage: orbit-audit-brand <path/to/orbit-brand.json>\")\n} else if (!manifestFile) {\n console.error(\"Usage: orbit-audit-brand <path/to/orbit-brand.json>\")\n process.exitCode = 2\n} else {\n try {\n const report = await auditBrandPackage(manifestFile)\n console.log(\n `✓ ${report.manifest.id}: ${report.checkedAssets.length} assets, ${report.checkedLocales.length} locale packs, ${report.checkedModules.length} entry modules, ${report.entryGzipBytes} module-graph gzip bytes`,\n )\n } catch (cause) {\n console.error(`✗ brand audit failed: ${cause instanceof Error ? cause.message : String(cause)}`)\n process.exitCode = 1\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/manifest.ts","../src/audit-brand.ts","../src/cli.ts"],"names":["text","manifestFile"],"mappings":"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","file":"audit-brand.js","sourcesContent":["import {\n BRAND_ACTION_TOKENS,\n type BrandTheme,\n type BrandThemeToken,\n type LocalizedBranding,\n type TenantBranding,\n UNIFIED_NEUTRAL_TOKENS,\n ds2ContrastRatio,\n} from \"@orbit-work/ui/appearance\"\nimport { type SlotKind, WORKBENCH_KEYED_SLOT_KEYS, WORKBENCH_SLOT_DECLARATIONS } from \"@orbit-work/ui/slot/core\"\n\nexport type BrandSlotName = keyof typeof WORKBENCH_SLOT_DECLARATIONS\n\nexport const BRAND_MANIFEST_SCHEMA = \"@orbit-work/oem-sdk/manifest@1\" as const\n\nexport type BrandIdentity = {\n productName: string\n appId: string\n versionChannel: string\n protocolScheme: string\n /**\n * Optional override for the per-installation user data directory namespace.\n * Managed builds default to the identity appId; workspace packages derive\n * storage from appId and omit this field.\n */\n userDataNamespace?: string\n}\n\n/** Upload-time brand manifest: every field optional, filled fields fully validated. */\nexport type PartialBrandIdentity = { [Key in keyof BrandIdentity]?: BrandIdentity[Key] }\n\nexport type PartialBrandAssets = { [Key in keyof BrandAssets]?: BrandAssets[Key] }\n\nexport type PartialLocalizedBranding = Record<string, Partial<TenantBranding>>\n\nexport type PartialBrandManifest = {\n $schema?: typeof BRAND_MANIFEST_SCHEMA\n id?: string\n /** Installer package description (electron-builder `description`). */\n description?: string\n /** Assistant display name in chat copy; defaults to the branding productName. */\n assistantName?: string\n /** Product homepage packaged into installer metadata. */\n homepage?: string\n /** OS permission prompts overridden by the OEM. */\n permissions?: BrandPermissions\n entry?: string\n identity?: PartialBrandIdentity\n tokens?: BrandManifest[\"tokens\"]\n assets?: PartialBrandAssets\n branding?: PartialLocalizedBranding\n locales?: BrandLocaleSources\n network?: BrandNetworkAccess\n contributes?: { slots: SlotContribution[] }\n}\n\nexport type PartialBrandManifestValidationResult =\n | { ok: true; manifest: PartialBrandManifest }\n | { ok: false; error: string }\n\nexport type BrandAssets = {\n appIcon: string\n tray?: string\n logo: string\n /** Optional login key-visual photo (KV board background on the desktop login page). */\n loginKV?: string\n}\n\nexport type BrandLocaleSources = Record<string, string>\n\nexport type BrandNetworkAccess = {\n /** Exact production HTTPS origins added to the packaged renderer connect-src. */\n allowedOrigins: string[]\n}\n\nexport type BrandPermissions = {\n /** macOS microphone prompt (Info.plist NSMicrophoneUsageDescription), written in the OEM's own language. */\n microphoneUsage: string\n}\n\ntype SlotNameOfKind<Kind extends SlotKind> = {\n [Name in BrandSlotName]: (typeof WORKBENCH_SLOT_DECLARATIONS)[Name][\"kind\"] extends Kind ? Name : never\n}[BrandSlotName]\n\ntype SlotContributionBase<Name extends BrandSlotName> = {\n name: Name\n}\n\ntype SingleSlotContribution = {\n [Name in SlotNameOfKind<\"single\">]: SlotContributionBase<Name>\n}[SlotNameOfKind<\"single\">]\n\ntype ListSlotContribution = {\n [Name in SlotNameOfKind<\"list\">]: SlotContributionBase<Name> & { id: string; order: number }\n}[SlotNameOfKind<\"list\">]\n\ntype KeyedSlotName = Extract<keyof typeof WORKBENCH_KEYED_SLOT_KEYS, BrandSlotName>\ntype KeyedSlotContribution = {\n [Name in KeyedSlotName]: SlotContributionBase<Name> & {\n key: (typeof WORKBENCH_KEYED_SLOT_KEYS)[Name][number]\n }\n}[KeyedSlotName]\n\nexport type SlotContribution = SingleSlotContribution | ListSlotContribution | KeyedSlotContribution\n\nexport type BrandManifest = {\n $schema: typeof BRAND_MANIFEST_SCHEMA\n id: string\n /** Installer package description (electron-builder `description`). */\n description?: string\n /** Assistant display name in chat copy; defaults to the branding productName. */\n assistantName?: string\n /** Product homepage packaged into installer metadata. */\n homepage?: string\n /** OS permission prompts overridden by the OEM. */\n permissions?: BrandPermissions\n entry?: string\n identity: BrandIdentity\n tokens?: Partial<Record<\"light\" | \"dark\", Partial<Record<BrandThemeToken, string>>>>\n assets: BrandAssets\n branding: LocalizedBranding\n /** Package-relative dictionaries owned by this OEM namespace. en-US is the required fallback. */\n locales?: BrandLocaleSources\n network?: BrandNetworkAccess\n contributes?: {\n slots: SlotContribution[]\n }\n}\n\nexport type BrandManifestParseOptions = {\n /**\n * Platform builds accept manifests resolved from the managed OEM pipeline:\n * every shape/format/safety check stays in force, only the workspace\n * namespacing bindings are relaxed (productName/versionChannel/protocolScheme\n * must equal id, appId must end with .oem.<id>, reserved feed channels).\n */\n platform?: boolean\n}\n\nexport type BrandManifestValidationResult = { ok: true; manifest: BrandManifest } | { ok: false; error: string }\n\nconst ROOT_KEYS = new Set([\n \"$schema\",\n \"id\",\n \"description\",\n \"assistantName\",\n \"homepage\",\n \"permissions\",\n \"entry\",\n \"identity\",\n \"tokens\",\n \"assets\",\n \"branding\",\n \"locales\",\n \"network\",\n \"contributes\",\n])\nconst IDENTITY_KEYS = new Set([\"productName\", \"appId\", \"versionChannel\", \"protocolScheme\", \"userDataNamespace\"])\nconst ASSET_KEYS = new Set([\"appIcon\", \"tray\", \"logo\", \"loginKV\"])\nconst MODE_KEYS = new Set([\"light\", \"dark\"])\nconst CONTRIBUTES_KEYS = new Set([\"slots\"])\nconst NETWORK_KEYS = new Set([\"allowedOrigins\"])\nconst PERMISSIONS_KEYS = new Set([\"microphoneUsage\"])\nconst BRANDING_KEYS = new Set([\"productName\", \"companyName\", \"claim\", \"claimNote\", \"slogan\"])\nconst SLOT_COMMON_KEYS = new Set([\"name\"])\nconst BRAND_TOKEN_NAMES = new Set<string>([...UNIFIED_NEUTRAL_TOKENS, ...BRAND_ACTION_TOKENS])\nconst SLOT_DECLARATIONS = WORKBENCH_SLOT_DECLARATIONS as Readonly<Record<string, { kind: SlotKind }>>\nconst HEX = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i\nconst KEBAB_ID = /^[a-z0-9]+(?:-[a-z0-9]+)*$/\nconst APP_ID = /^[a-zA-Z][a-zA-Z0-9]*(?:\\.[a-zA-Z0-9][a-zA-Z0-9-]*){2,}$/\nconst PROTOCOL_SCHEME = /^[a-z][a-z0-9+.-]*$/\nconst SOURCE_ENTRY = /^\\.\\/src\\/.+\\.(?:[cm]?js|[jt]sx?)$/\nconst WINDOWS_DEVICE_NAME = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\\..*)?$/i\nconst OFFICIAL_APP_ID = \"ai.orbit.desktop\"\nconst OFFICIAL_PRODUCT_NAMES = new Set([\"orbitwork\"])\nconst RESERVED_VERSION_CHANNELS = new Set([\n \"stable\",\n \"preview\",\n \"uat\",\n \"latest\",\n \"desktop\",\n \"macos\",\n \"windows\",\n \"linux\",\n])\nconst RESERVED_PROTOCOL_SCHEMES = new Set([\n \"about\",\n \"blob\",\n \"chrome\",\n \"chrome-extension\",\n \"data\",\n \"devtools\",\n \"electron\",\n \"file\",\n \"ftp\",\n \"geo\",\n \"http\",\n \"https\",\n \"javascript\",\n \"mailto\",\n \"orbit\",\n \"sms\",\n \"tel\",\n \"urn\",\n \"ws\",\n \"wss\",\n])\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n}\n\nfunction hasUnsafeProductNameCharacter(value: string): boolean {\n return [...value].some((character) => {\n const code = character.charCodeAt(0)\n return code <= 31 || code === 127 || '<>:\"/\\\\|?*'.includes(character)\n })\n}\n\nfunction productNameNamespace(value: string): string {\n return value\n .normalize(\"NFKD\")\n .replace(/\\p{M}+/gu, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n}\n\nfunction assertKnownKeys(value: Record<string, unknown>, allowed: Set<string>, path: string): void {\n const unknown = Object.keys(value).find((key) => !allowed.has(key))\n if (unknown) throw new Error(`${path} contains unsupported field: ${unknown}`)\n}\n\nfunction text(value: unknown, path: string, limit = 100): string {\n if (typeof value !== \"string\" || !value.trim()) throw new Error(`${path} must be a non-empty string`)\n const result = value.trim()\n if (result.length > limit) throw new Error(`${path} exceeds ${limit} characters`)\n return result\n}\n\nfunction canonicalLocale(value: string, path: string): string {\n try {\n const locale = Intl.getCanonicalLocales(value)[0]\n if (!locale || locale !== value) throw new Error()\n return locale\n } catch {\n throw new Error(`${path} must be a canonical BCP 47 locale`)\n }\n}\n\nfunction relativePath(value: unknown, path: string): string {\n const result = text(value, path, 240)\n if (!result.startsWith(\"./\") || result.includes(\"\\\\\") || result.split(\"/\").includes(\"..\")) {\n throw new Error(`${path} must be a package-relative ./ path without traversal`)\n }\n return result\n}\n\nfunction parseIdentity(value: unknown, id: string, platform: boolean): BrandIdentity {\n if (!isRecord(value)) throw new Error(\"identity must be an object\")\n assertKnownKeys(value, IDENTITY_KEYS, \"identity\")\n const productName = text(value.productName, \"identity.productName\", 64)\n const appId = text(value.appId, \"identity.appId\", 160)\n const versionChannel = text(value.versionChannel, \"identity.versionChannel\", 64)\n const protocolScheme = text(value.protocolScheme, \"identity.protocolScheme\", 64)\n if (value.userDataNamespace !== undefined && !KEBAB_ID.test(text(value.userDataNamespace, \"identity.userDataNamespace\", 64))) {\n throw new Error(\"identity.userDataNamespace must be lowercase kebab-case\")\n }\n if (!APP_ID.test(appId)) throw new Error(\"identity.appId must be a reverse-DNS identifier\")\n if (!KEBAB_ID.test(versionChannel)) throw new Error(\"identity.versionChannel must be kebab-case\")\n // Managed platform builds assign the update channel from the frozen build\n // input; reserved feed names and the == id binding only police workspace\n // packages, where collisions would merge OEM feeds.\n if (!platform && RESERVED_VERSION_CHANNELS.has(versionChannel)) {\n throw new Error(`identity.versionChannel is reserved: ${versionChannel}`)\n }\n if (!PROTOCOL_SCHEME.test(protocolScheme)) {\n throw new Error(\"identity.protocolScheme must be a lowercase URI scheme beginning with a letter\")\n }\n if (RESERVED_PROTOCOL_SCHEMES.has(protocolScheme)) {\n throw new Error(`identity.protocolScheme is reserved: ${protocolScheme}`)\n }\n if (\n hasUnsafeProductNameCharacter(productName) ||\n /[. ]$/.test(productName) ||\n productName === \".\" ||\n productName === \"..\" ||\n WINDOWS_DEVICE_NAME.test(productName)\n ) {\n throw new Error(\"identity.productName must be safe for macOS, Windows, Linux, and release artifact paths\")\n }\n if (OFFICIAL_PRODUCT_NAMES.has(productName.toLowerCase())) {\n throw new Error(`identity.productName is reserved for the official application: ${productName}`)\n }\n if (appId === OFFICIAL_APP_ID) {\n throw new Error(`identity.appId is reserved for the official application: ${appId}`)\n }\n if (!platform && productNameNamespace(productName) !== id) {\n throw new Error(\"identity.productName must normalize to manifest id so installation names cannot collide\")\n }\n if (!platform && versionChannel !== id) {\n throw new Error(\"identity.versionChannel must equal manifest id to keep OEM update feeds namespaced\")\n }\n if (!platform && protocolScheme !== id) {\n throw new Error(\"identity.protocolScheme must equal manifest id to keep OEM deep links namespaced\")\n }\n if (!platform && !appId.endsWith(`.oem.${id}`)) {\n throw new Error(\"identity.appId must end with .oem.<manifest id> to isolate installation and user data\")\n }\n return {\n productName,\n appId,\n versionChannel,\n protocolScheme,\n ...(value.userDataNamespace !== undefined ? { userDataNamespace: text(value.userDataNamespace, \"identity.userDataNamespace\", 64) } : {}),\n }\n}\n\nfunction parseAssets(value: unknown): BrandAssets {\n if (!isRecord(value)) throw new Error(\"assets must be an object\")\n assertKnownKeys(value, ASSET_KEYS, \"assets\")\n const tray = value.tray === undefined ? undefined : relativePath(value.tray, \"assets.tray\")\n const loginKV =\n value.loginKV === undefined ? undefined : relativePath(value.loginKV, \"assets.loginKV\")\n return {\n appIcon: relativePath(value.appIcon, \"assets.appIcon\"),\n ...(tray ? { tray } : {}),\n logo: relativePath(value.logo, \"assets.logo\"),\n ...(loginKV ? { loginKV } : {}),\n }\n}\n\nfunction parsePartialAssets(value: unknown): PartialBrandAssets {\n if (!isRecord(value)) throw new Error(\"assets must be an object\")\n assertKnownKeys(value, ASSET_KEYS, \"assets\")\n return {\n ...(value.appIcon !== undefined ? { appIcon: relativePath(value.appIcon, \"assets.appIcon\") } : {}),\n ...(value.logo !== undefined ? { logo: relativePath(value.logo, \"assets.logo\") } : {}),\n ...(value.tray !== undefined ? { tray: relativePath(value.tray, \"assets.tray\") } : {}),\n ...(value.loginKV !== undefined\n ? { loginKV: relativePath(value.loginKV, \"assets.loginKV\") }\n : {}),\n }\n}\n\nfunction parseBrandCopy(value: unknown, path: string): TenantBranding {\n if (!isRecord(value)) throw new Error(`${path} must be an object`)\n assertKnownKeys(value, BRANDING_KEYS, path)\n const result: TenantBranding = {\n productName: text(value.productName, `${path}.productName`, 64),\n companyName: text(value.companyName, `${path}.companyName`, 80),\n }\n for (const [key, limit] of [\n [\"claim\", 40],\n [\"claimNote\", 48],\n [\"slogan\", 68],\n ] as const) {\n if (value[key] !== undefined) result[key] = text(value[key], `${path}.${key}`, limit)\n }\n return result\n}\n\nfunction parseBranding(value: unknown): LocalizedBranding {\n if (!isRecord(value)) throw new Error(\"branding must be a locale map\")\n const result: LocalizedBranding = {}\n for (const [rawLocale, copy] of Object.entries(value)) {\n const locale = canonicalLocale(rawLocale, `branding.${rawLocale}`)\n result[locale] = parseBrandCopy(copy, `branding.${locale}`)\n }\n if (!result[\"en-US\"]) throw new Error(\"branding.en-US is required\")\n return result\n}\n\nfunction parseLocales(value: unknown): BrandLocaleSources | undefined {\n if (value === undefined) return undefined\n if (!isRecord(value)) throw new Error(\"locales must be a locale map\")\n const result: BrandLocaleSources = {}\n for (const [rawLocale, source] of Object.entries(value)) {\n const locale = canonicalLocale(rawLocale, `locales.${rawLocale}`)\n result[locale] = relativePath(source, `locales.${locale}`)\n }\n if (!result[\"en-US\"]) throw new Error(\"locales.en-US is required when locales are declared\")\n return result\n}\n\nfunction isDevelopmentHostname(hostname: string): boolean {\n const lower = hostname.toLowerCase()\n if (lower === \"localhost\" || lower.endsWith(\".localhost\") || lower.endsWith(\".local\")) return true\n if ([\"::1\", \"[::1]\"].includes(lower) || /^(?:fc|fd|fe8|fe9|fea|feb)/.test(lower.replace(/[\\[\\]]/g, \"\"))) {\n return true\n }\n const ipv4 = lower\n .match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/)\n ?.slice(1)\n .map(Number)\n if (ipv4) {\n const [a, b] = ipv4\n if (\n a === 0 ||\n a === 10 ||\n a === 127 ||\n (a === 169 && b === 254) ||\n (a === 172 && b! >= 16 && b! <= 31) ||\n (a === 192 && b === 168)\n ) {\n return true\n }\n }\n return lower\n .split(/[.-]/)\n .some((label) => [\"dev\", \"development\", \"test\", \"testing\", \"stage\", \"staging\", \"uat\"].includes(label))\n}\n\nfunction parseNetwork(value: unknown): BrandNetworkAccess | undefined {\n if (value === undefined) return undefined\n if (!isRecord(value)) throw new Error(\"network must be an object\")\n assertKnownKeys(value, NETWORK_KEYS, \"network\")\n if (!Array.isArray(value.allowedOrigins) || value.allowedOrigins.length === 0) {\n throw new Error(\"network.allowedOrigins must be a non-empty array\")\n }\n const allowedOrigins = value.allowedOrigins.map((raw, index) => {\n const path = `network.allowedOrigins[${index}]`\n const origin = text(raw, path, 240)\n let parsed: URL\n try {\n parsed = new URL(origin)\n } catch {\n throw new Error(`${path} must be an exact HTTPS origin`)\n }\n if (\n parsed.protocol !== \"https:\" ||\n parsed.username ||\n parsed.password ||\n parsed.pathname !== \"/\" ||\n parsed.search ||\n parsed.hash ||\n parsed.origin !== origin\n ) {\n throw new Error(`${path} must be a canonical exact HTTPS origin without credentials, path, query, or fragment`)\n }\n if (isDevelopmentHostname(parsed.hostname)) {\n throw new Error(`${path} must be a production origin, not localhost, private network, dev, test, staging, or UAT`)\n }\n return origin\n })\n if (new Set(allowedOrigins).size !== allowedOrigins.length) {\n throw new Error(\"network.allowedOrigins must not contain duplicates\")\n }\n return { allowedOrigins }\n}\n\nfunction parseHomepage(value: unknown): string {\n const homepage = text(value, \"homepage\", 200)\n let parsed: URL\n try {\n parsed = new URL(homepage)\n } catch {\n throw new Error(\"homepage must be an https URL\")\n }\n if (parsed.protocol !== \"https:\" || !parsed.hostname) {\n throw new Error(\"homepage must be an https URL\")\n }\n return homepage\n}\n\nfunction parsePermissions(value: unknown): BrandPermissions {\n if (!isRecord(value)) throw new Error(\"permissions must be an object\")\n assertKnownKeys(value, PERMISSIONS_KEYS, \"permissions\")\n return { microphoneUsage: text(value.microphoneUsage, \"permissions.microphoneUsage\", 120) }\n}\n\nfunction parseModeTokens(value: unknown, path: string): Partial<Record<BrandThemeToken, string>> { if (!isRecord(value)) throw new Error(`${path} must be an object`)\n const result: Partial<Record<BrandThemeToken, string>> = {}\n for (const [name, raw] of Object.entries(value)) {\n if (!BRAND_TOKEN_NAMES.has(name)) throw new Error(`${path} contains forbidden token: ${name}`)\n if (typeof raw !== \"string\" || !HEX.test(raw)) throw new Error(`${path}.${name} must be a hex color`)\n result[name as BrandThemeToken] = raw.toLowerCase()\n }\n\n const touchedNeutral = UNIFIED_NEUTRAL_TOKENS.some((name) => result[name] !== undefined)\n if (touchedNeutral) {\n const missing = UNIFIED_NEUTRAL_TOKENS.filter((name) => result[name] === undefined)\n if (missing.length) throw new Error(`${path} neutral group is incomplete: ${missing.join(\", \")}`)\n for (const textToken of [\"--ow-text\", \"--ow-text-2\"] as const) {\n for (const surfaceToken of [\"--ow-bg\", \"--ow-surface\", \"--ow-surface-2\"] as const) {\n const ratio = ds2ContrastRatio(result[textToken] as string, result[surfaceToken] as string)\n if (ratio < 4.5) {\n throw new Error(\n `${path} contrast ${textToken} on ${surfaceToken} is ${ratio.toFixed(2)}:1; expected >= 4.5:1`,\n )\n }\n }\n }\n }\n\n const touchedAction = BRAND_ACTION_TOKENS.some((name) => result[name] !== undefined)\n if (touchedAction) {\n const missing = BRAND_ACTION_TOKENS.filter((name) => result[name] === undefined)\n if (missing.length) throw new Error(`${path} action pole group is incomplete: ${missing.join(\", \")}`)\n for (const background of [\"--ow-btn-primary-bg\", \"--ow-btn-primary-hover\", \"--ow-btn-primary-press\"] as const) {\n const ratio = ds2ContrastRatio(result[background] as string, result[\"--ow-btn-primary-fg\"] as string)\n if (ratio < 4.5) {\n throw new Error(\n `${path} contrast --ow-btn-primary-fg on ${background} is ${ratio.toFixed(2)}:1; expected >= 4.5:1`,\n )\n }\n }\n }\n return result\n}\n\nfunction parseTokens(value: unknown): BrandManifest[\"tokens\"] {\n if (value === undefined) return undefined\n if (!isRecord(value)) throw new Error(\"tokens must be an object\")\n assertKnownKeys(value, MODE_KEYS, \"tokens\")\n const light = value.light === undefined ? undefined : parseModeTokens(value.light, \"tokens.light\")\n const dark = value.dark === undefined ? undefined : parseModeTokens(value.dark, \"tokens.dark\")\n if (!light && !dark) throw new Error(\"tokens must define light or dark\")\n return { ...(light ? { light } : {}), ...(dark ? { dark } : {}) }\n}\n\nfunction slotAllowedKeys(kind: SlotKind): Set<string> {\n return new Set([\n ...SLOT_COMMON_KEYS,\n ...(kind === \"list\" ? [\"id\", \"order\"] : []),\n ...(kind === \"keyed\" ? [\"key\"] : []),\n ])\n}\n\nfunction parseSlotContribution(value: unknown, index: number): SlotContribution {\n const path = `contributes.slots[${index}]`\n if (!isRecord(value)) throw new Error(`${path} must be an object`)\n const name = text(value.name, `${path}.name`, 120)\n const declaration = SLOT_DECLARATIONS[name]\n if (!declaration) throw new Error(`${path}.name is not in the host slot whitelist: ${name}`)\n assertKnownKeys(value, slotAllowedKeys(declaration.kind), path)\n const common = { name: name as BrandSlotName }\n if (declaration.kind === \"list\") {\n const id = text(value.id, `${path}.id`, 100)\n if (typeof value.order !== \"number\" || !Number.isFinite(value.order)) {\n throw new Error(`${path}.order must be a finite number`)\n }\n return { ...common, id, order: value.order } as SlotContribution\n }\n if (declaration.kind === \"keyed\") {\n const key = text(value.key, `${path}.key`, 100)\n const allowed = WORKBENCH_KEYED_SLOT_KEYS[name as KeyedSlotName] as readonly string[] | undefined\n if (!allowed?.includes(key)) throw new Error(`${path}.key is not reachable by the host: ${key}`)\n return { ...common, key } as SlotContribution\n }\n return common as SlotContribution\n}\n\nfunction contributionCell(value: SlotContribution): string {\n if (\"id\" in value) return value.id\n if (\"key\" in value) return value.key\n return \"single\"\n}\n\nfunction parseContributes(value: unknown): BrandManifest[\"contributes\"] {\n if (value === undefined) return undefined\n if (!isRecord(value)) throw new Error(\"contributes must be an object\")\n assertKnownKeys(value, CONTRIBUTES_KEYS, \"contributes\")\n if (!Array.isArray(value.slots)) throw new Error(\"contributes.slots must be an array\")\n const slots = value.slots.map(parseSlotContribution)\n const seen = new Set<string>()\n for (const slot of slots) {\n const identity = `${slot.name}\\0${contributionCell(slot)}`\n if (seen.has(identity)) throw new Error(`duplicate slot contribution: ${slot.name} / ${contributionCell(slot)}`)\n seen.add(identity)\n }\n return { slots }\n}\n\nexport function parseBrandManifest(input: unknown, options?: BrandManifestParseOptions): BrandManifestValidationResult {\n try {\n const platform = options?.platform === true\n if (!isRecord(input)) throw new Error(\"brand manifest must be a JSON object\")\n assertKnownKeys(input, ROOT_KEYS, \"manifest\")\n if (input.$schema !== BRAND_MANIFEST_SCHEMA) throw new Error(`$schema must equal ${BRAND_MANIFEST_SCHEMA}`)\n const id = text(input.id, \"id\", 64)\n if (!KEBAB_ID.test(id)) throw new Error(\"id must be lowercase kebab-case\")\n const entry = input.entry === undefined ? undefined : relativePath(input.entry, \"entry\")\n if (entry && !SOURCE_ENTRY.test(entry)) {\n throw new Error(\"entry must point to reviewed source under ./src using .js, .mjs, .jsx, .ts, or .tsx\")\n }\n const contributes = parseContributes(input.contributes)\n if ((contributes?.slots.length ?? 0) > 0 && !entry)\n throw new Error(\"entry is required when contributes.slots is not empty\")\n const tokens = parseTokens(input.tokens)\n const locales = parseLocales(input.locales)\n const network = parseNetwork(input.network)\n const identity = parseIdentity(input.identity, id, platform)\n if (!platform && productNameNamespace(identity.productName) !== id) {\n throw new Error(\"identity.productName must normalize to manifest id so installation names cannot collide\")\n }\n if (!platform && identity.versionChannel !== id) {\n throw new Error(\"identity.versionChannel must equal manifest id to keep OEM update feeds namespaced\")\n }\n if (!platform && identity.protocolScheme !== id) {\n throw new Error(\"identity.protocolScheme must equal manifest id to keep OEM deep links namespaced\")\n }\n if (!platform && !identity.appId.endsWith(`.oem.${id}`)) {\n throw new Error(\"identity.appId must end with .oem.<manifest id> to isolate installation and user data\")\n }\n return {\n ok: true,\n manifest: {\n $schema: BRAND_MANIFEST_SCHEMA,\n id,\n ...(input.description !== undefined ? { description: text(input.description, \"description\", 200) } : {}),\n ...(input.assistantName !== undefined ? { assistantName: text(input.assistantName, \"assistantName\", 48) } : {}),\n ...(input.homepage !== undefined ? { homepage: parseHomepage(input.homepage) } : {}),\n ...(input.permissions !== undefined ? { permissions: parsePermissions(input.permissions) } : {}),\n ...(entry ? { entry } : {}),\n identity,\n ...(tokens ? { tokens } : {}),\n assets: parseAssets(input.assets),\n branding: parseBranding(input.branding),\n ...(locales ? { locales } : {}),\n ...(network ? { network } : {}),\n ...(contributes ? { contributes } : {}),\n },\n }\n } catch (cause) {\n return { ok: false, error: cause instanceof Error ? cause.message : String(cause) }\n }\n}\n\nfunction parsePartialIdentity(value: unknown): PartialBrandIdentity {\n if (!isRecord(value)) throw new Error(\"identity must be an object\")\n assertKnownKeys(value, IDENTITY_KEYS, \"identity\")\n // Filled fields are validated exactly like the strict parser (formats,\n // reserved values), but the id-binding rules are skipped: partial manifests\n // are merged with source defaults before consumption, and the resolved\n // product is re-validated where those bindings apply.\n if (value.userDataNamespace !== undefined && !KEBAB_ID.test(text(value.userDataNamespace, \"identity.userDataNamespace\", 64))) {\n throw new Error(\"identity.userDataNamespace must be lowercase kebab-case\")\n }\n if (value.appId !== undefined) {\n const appId = text(value.appId, \"identity.appId\", 160)\n if (!APP_ID.test(appId)) throw new Error(\"identity.appId must be a reverse-DNS identifier\")\n if (appId === OFFICIAL_APP_ID) {\n throw new Error(`identity.appId is reserved for the official application: ${appId}`)\n }\n }\n if (value.versionChannel !== undefined) {\n const versionChannel = text(value.versionChannel, \"identity.versionChannel\", 64)\n if (!KEBAB_ID.test(versionChannel)) throw new Error(\"identity.versionChannel must be kebab-case\")\n }\n if (value.protocolScheme !== undefined) {\n const protocolScheme = text(value.protocolScheme, \"identity.protocolScheme\", 64)\n if (!PROTOCOL_SCHEME.test(protocolScheme)) {\n throw new Error(\"identity.protocolScheme must be a lowercase URI scheme beginning with a letter\")\n }\n if (RESERVED_PROTOCOL_SCHEMES.has(protocolScheme)) {\n throw new Error(`identity.protocolScheme is reserved: ${protocolScheme}`)\n }\n }\n if (value.productName !== undefined) {\n const productName = text(value.productName, \"identity.productName\", 64)\n if (\n hasUnsafeProductNameCharacter(productName) ||\n /[. ]$/.test(productName) ||\n productName === \".\" ||\n productName === \"..\" ||\n WINDOWS_DEVICE_NAME.test(productName)\n ) {\n throw new Error(\"identity.productName must be safe for macOS, Windows, Linux, and release artifact paths\")\n }\n if (OFFICIAL_PRODUCT_NAMES.has(productName.toLowerCase())) {\n throw new Error(`identity.productName is reserved for the official application: ${productName}`)\n }\n }\n return {\n ...(value.productName !== undefined ? { productName: text(value.productName, \"identity.productName\", 64) } : {}),\n ...(value.appId !== undefined ? { appId: text(value.appId, \"identity.appId\", 160) } : {}),\n ...(value.versionChannel !== undefined ? { versionChannel: text(value.versionChannel, \"identity.versionChannel\", 64) } : {}),\n ...(value.protocolScheme !== undefined ? { protocolScheme: text(value.protocolScheme, \"identity.protocolScheme\", 64) } : {}),\n ...(value.userDataNamespace !== undefined\n ? { userDataNamespace: text(value.userDataNamespace, \"identity.userDataNamespace\", 64) }\n : {}),\n }\n}\n\nfunction parsePartialBranding(value: unknown): PartialLocalizedBranding {\n if (!isRecord(value)) throw new Error(\"branding must be a locale map\")\n const result: PartialLocalizedBranding = {}\n for (const [rawLocale, copy] of Object.entries(value)) {\n const locale = canonicalLocale(rawLocale, `branding.${rawLocale}`)\n if (!isRecord(copy)) throw new Error(`branding.${locale} must be an object`)\n assertKnownKeys(copy, BRANDING_KEYS, `branding.${locale}`)\n const partial: Partial<TenantBranding> = {}\n for (const [key, limit] of [\n [\"productName\", 64],\n [\"companyName\", 80],\n [\"claim\", 40],\n [\"claimNote\", 48],\n [\"slogan\", 68],\n ] as const) {\n if (copy[key] !== undefined) partial[key] = text(copy[key], `branding.${locale}.${key}`, limit)\n }\n result[locale] = partial\n }\n return result\n}\n\n/**\n * Validates an upload-time (partial) brand manifest: omitted fields inherit\n * source defaults at merge time; every filled field is fully validated. The\n * resolved product must still pass `parseBrandManifest` where it is consumed.\n */\nexport function parsePartialBrandManifest(input: unknown): PartialBrandManifestValidationResult {\n try {\n if (!isRecord(input)) throw new Error(\"brand manifest must be a JSON object\")\n assertKnownKeys(input, ROOT_KEYS, \"manifest\")\n if (input.$schema !== undefined && input.$schema !== BRAND_MANIFEST_SCHEMA) {\n throw new Error(`$schema must equal ${BRAND_MANIFEST_SCHEMA}`)\n }\n const entry = input.entry === undefined ? undefined : relativePath(input.entry, \"entry\")\n if (entry && !SOURCE_ENTRY.test(entry)) {\n throw new Error(\"entry must point to reviewed source under ./src using .js, .mjs, .jsx, .ts, or .tsx\")\n }\n const contributes = parseContributes(input.contributes)\n if ((contributes?.slots.length ?? 0) > 0 && !entry)\n throw new Error(\"entry is required when contributes.slots is not empty\")\n if (input.id !== undefined) {\n const id = text(input.id, \"id\", 64)\n if (!KEBAB_ID.test(id)) throw new Error(\"id must be lowercase kebab-case\")\n }\n return {\n ok: true,\n manifest: {\n ...(input.id !== undefined ? { id: text(input.id, \"id\", 64) } : {}),\n ...(input.description !== undefined ? { description: text(input.description, \"description\", 200) } : {}),\n ...(input.assistantName !== undefined ? { assistantName: text(input.assistantName, \"assistantName\", 48) } : {}),\n ...(input.homepage !== undefined ? { homepage: parseHomepage(input.homepage) } : {}),\n ...(input.permissions !== undefined ? { permissions: parsePermissions(input.permissions) } : {}),\n ...(entry ? { entry } : {}),\n ...(input.identity !== undefined ? { identity: parsePartialIdentity(input.identity) } : {}),\n ...(input.tokens !== undefined ? { tokens: parseTokens(input.tokens) } : {}),\n ...(input.assets !== undefined ? { assets: parsePartialAssets(input.assets) } : {}),\n ...(input.branding !== undefined ? { branding: parsePartialBranding(input.branding) } : {}),\n ...(input.locales !== undefined ? { locales: parseLocales(input.locales) } : {}),\n ...(input.network !== undefined ? { network: parseNetwork(input.network) } : {}),\n ...(contributes ? { contributes } : {}),\n },\n }\n } catch (cause) {\n return { ok: false, error: cause instanceof Error ? cause.message : String(cause) }\n }\n}\n\nexport function manifestToBrandTheme(manifest: BrandManifest): BrandTheme {\n return {\n id: manifest.id,\n logo: manifest.assets.logo,\n ...(manifest.assets.loginKV ? { loginKV: manifest.assets.loginKV } : {}),\n modes: manifest.tokens ?? {},\n branding: manifest.branding,\n }\n}\n","import { readFile, realpath, stat } from \"node:fs/promises\"\nimport { dirname, extname, resolve, sep } from \"node:path\"\nimport { gzipSync } from \"node:zlib\"\nimport { init, parse } from \"es-module-lexer\"\nimport { type Loader, transform } from \"esbuild\"\nimport { type LocaleDictionary, validateDictionary } from \"./locale.ts\"\nimport { type BrandManifest, parseBrandManifest } from \"./manifest.ts\"\n\nconst ENTRY_GZIP_BUDGET = 256 * 1024\nconst ASSET_BUDGET = 5 * 1024 * 1024\nconst LOCALE_BUDGET = 256 * 1024\nconst IMPORT_ALLOWLIST = new Set([\n \"@orbit-work/oem-sdk\",\n \"@orbit-work/oem-sdk/runtime\",\n \"@orbit-work/ui\",\n \"react\",\n \"react-dom\",\n \"react/jsx-runtime\",\n \"react/jsx-dev-runtime\",\n])\nconst CREDENTIAL_ASSIGNMENT = /\\b(?:api[_-]?key|client[_-]?secret|access[_-]?token|password)\\b\\s*[:=]\\s*([^\\n;]+)/gi\nconst STATIC_STRING = /\"([^\"\\n]*(?:\\\\.[^\"\\n]*)*)\"|'([^'\\n]*(?:\\\\.[^'\\n]*)*)'|`([^`\\n]*(?:\\\\.[^`\\n]*)*)`/g\nconst CODE_EXTENSIONS = new Set([\".js\", \".mjs\", \".cjs\", \".jsx\", \".ts\", \".tsx\"])\nconst ASSET_EXTENSIONS = new Set([\".png\", \".svg\", \".webp\", \".jpg\", \".jpeg\", \".gif\", \".woff\", \".woff2\"])\nconst DATA_EXTENSIONS = new Set([\".json\"])\nconst CSS_IMPORT = /@import\\s+(?:url\\(\\s*)?[\"']([^\"']+)[\"']\\s*\\)?/g\nconst CSS_URL = /url\\(\\s*[\"']?([^\"')]+)[\"']?\\s*\\)/g\nconst STATIC_HTTP_URL = /https?:\\/\\/[^\\s\"'`<>)]+/g\n\nexport type BrandAuditResult = {\n manifest: BrandManifest\n entryGzipBytes: number\n checkedAssets: string[]\n checkedModules: string[]\n checkedLocales: string[]\n}\n\nexport const OEM_ENTRY_IMPORTS = Object.freeze([...IMPORT_ALLOWLIST].sort())\n\nfunction containsLikelyHardCodedCredential(source: string): boolean {\n CREDENTIAL_ASSIGNMENT.lastIndex = 0\n for (const assignment of source.matchAll(CREDENTIAL_ASSIGNMENT)) {\n const rightHandSide = assignment[1] ?? \"\"\n const literalValue = [...rightHandSide.matchAll(STATIC_STRING)]\n .map((match) => match[1] ?? match[2] ?? match[3] ?? \"\")\n .join(\"\")\n if (literalValue.length >= 8) return true\n }\n return false\n}\n\nfunction parseLocaleDictionary(source: string, label: string): LocaleDictionary {\n let value: unknown\n try {\n value = JSON.parse(source)\n } catch {\n throw new Error(`${label} must contain valid JSON`)\n }\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(`${label} must contain a JSON object`)\n }\n const dictionary = value as Record<string, unknown>\n if (Object.keys(dictionary).length === 0) throw new Error(`${label} must not be empty`)\n const invalidKey = Object.keys(dictionary).find((key) => !/^[A-Za-z][A-Za-z0-9]*(?:[._-][A-Za-z0-9]+)*$/.test(key))\n if (invalidKey) throw new Error(`${label} contains an invalid translation key: ${invalidKey}`)\n const invalidValue = Object.entries(dictionary).find(([, text]) => typeof text !== \"string\")\n if (invalidValue) throw new Error(`${label}.${invalidValue[0]} must be a string`)\n return dictionary as LocaleDictionary\n}\n\nasync function auditLocaleDictionaries(\n packageRoot: string,\n locales: NonNullable<BrandManifest[\"locales\"]>,\n): Promise<string[]> {\n const dictionaries = new Map<string, LocaleDictionary>()\n for (const [locale, relative] of Object.entries(locales)) {\n const file = await resolvePackageFile(packageRoot, relative, `locales.${locale}`)\n const info = await stat(file)\n if (!info.isFile()) throw new Error(`locales.${locale} must point to a file`)\n if (info.size > LOCALE_BUDGET) throw new Error(`locales.${locale} exceeds 256 KiB`)\n dictionaries.set(locale, parseLocaleDictionary(await readFile(file, \"utf8\"), `locales.${locale}`))\n }\n const baseline = dictionaries.get(\"en-US\") as LocaleDictionary\n for (const [locale, dictionary] of dictionaries) {\n const result = validateDictionary(baseline, dictionary)\n if (!result.ok) {\n throw new Error(\n `locales.${locale} must match en-US keys (missing: ${result.missing.join(\", \") || \"none\"}; unknown: ${result.unknown.join(\", \") || \"none\"}; invalid: ${result.invalid.join(\", \") || \"none\"})`,\n )\n }\n }\n return Object.keys(locales)\n}\n\nasync function resolvePackageFile(packageRoot: string, relative: string, label: string): Promise<string> {\n const candidate = resolve(packageRoot, relative)\n if (candidate !== packageRoot && !candidate.startsWith(`${packageRoot}${sep}`)) {\n throw new Error(`${label} escapes the brand package`)\n }\n const actual = await realpath(candidate)\n if (actual !== packageRoot && !actual.startsWith(`${packageRoot}${sep}`)) {\n throw new Error(`${label} resolves outside the brand package`)\n }\n return actual\n}\n\nasync function assertAsset(\n packageRoot: string,\n relative: string,\n kind: keyof BrandManifest[\"assets\"],\n): Promise<string> {\n const file = await resolvePackageFile(packageRoot, relative, `assets.${kind}`)\n const info = await stat(file)\n if (!info.isFile()) throw new Error(`assets.${kind} must point to a file`)\n if (info.size > ASSET_BUDGET) throw new Error(`assets.${kind} exceeds 5 MiB`)\n const extension = extname(file).toLowerCase()\n // The login key visual carries photography, so it accepts JPEG in addition\n // to the web-image set; logo stays SVG/PNG/WebP and appIcon/tray PNG-only.\n const allowed =\n kind === \"loginKV\"\n ? new Set([\".png\", \".jpg\", \".jpeg\", \".webp\"])\n : kind === \"logo\"\n ? new Set([\".svg\", \".png\", \".webp\"])\n : new Set([\".png\"])\n if (!allowed.has(extension)) throw new Error(`assets.${kind} has unsupported extension: ${extension}`)\n if (kind === \"appIcon\" || kind === \"tray\") {\n const bytes = await readFile(file)\n if (bytes.length < 24 || bytes.toString(\"hex\", 0, 8) !== \"89504e470d0a1a0a\") {\n throw new Error(`assets.${kind} must be a valid PNG`)\n }\n const width = bytes.readUInt32BE(16)\n const height = bytes.readUInt32BE(20)\n if (kind === \"appIcon\") {\n if (width !== height || width < 512) throw new Error(\"assets.appIcon must be square and at least 512x512\")\n } else if (width !== 32 || height !== 32) {\n // One tray asset serves every platform: 32px covers the macOS menu bar\n // @2x template and scales down for the Windows/Linux system trays.\n throw new Error(\"assets.tray must be a 32x32 PNG (single asset used on macOS, Windows, and Linux)\")\n }\n }\n return file\n}\n\ntype ModuleKind = \"code\" | \"css\" | \"asset\" | \"data\"\n\nfunction moduleKind(file: string, specifier: string): ModuleKind {\n const extension = extname(file).toLowerCase()\n if (CODE_EXTENSIONS.has(extension)) return \"code\"\n if (extension === \".css\") {\n if (!file.endsWith(\".module.css\")) {\n throw new Error(`entry styles must use CSS Modules (*.module.css): ${specifier}`)\n }\n return \"css\"\n }\n if (ASSET_EXTENSIONS.has(extension)) return \"asset\"\n if (DATA_EXTENSIONS.has(extension)) return \"data\"\n throw new Error(`entry imports an unsupported module type: ${specifier}`)\n}\n\nasync function resolveRelativeModule(\n packageRoot: string,\n importer: string,\n specifier: string,\n): Promise<{ file: string; kind: ModuleKind }> {\n if (specifier.includes(\"?\") || specifier.includes(\"#\")) {\n throw new Error(`entry relative import must not contain a query or fragment: ${specifier}`)\n }\n const base = resolve(dirname(importer), specifier)\n const candidates = extname(base)\n ? [base]\n : [base, ...[\".js\", \".mjs\", \".cjs\", \".jsx\", \".ts\", \".tsx\"].map((extension) => `${base}${extension}`)]\n for (const candidate of candidates) {\n try {\n const actual = await realpath(candidate)\n if (actual !== packageRoot && !actual.startsWith(`${packageRoot}${sep}`)) {\n throw new Error(`entry import resolves outside the brand package: ${specifier}`)\n }\n const info = await stat(actual)\n if (!info.isFile()) throw new Error(`entry import must resolve to a file: ${specifier}`)\n if (info.size > ASSET_BUDGET) throw new Error(`entry import exceeds 5 MiB: ${specifier}`)\n return { file: actual, kind: moduleKind(actual, specifier) }\n } catch (error) {\n if (error instanceof Error && !error.message.includes(\"ENOENT\")) throw error\n }\n }\n throw new Error(`entry relative import cannot be resolved: ${specifier}`)\n}\n\nfunction assertScopedCss(source: string, file: string): void {\n const withoutComments = source.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\")\n if (/:global\\b/.test(withoutComments)) throw new Error(`CSS Module uses forbidden :global selector: ${file}`)\n if (/(?:^|[,{]\\s*)(?:html|body|:root|\\*)\\b/m.test(withoutComments)) {\n throw new Error(`CSS Module contains a global root selector: ${file}`)\n }\n if (/(?:^|[\\s:(,])(?:#(?:[0-9a-f]{3,8})|rgba?\\(|hsla?\\()/i.test(withoutComments)) {\n throw new Error(`CSS Module colors must use DS2 --ow-* tokens: ${file}`)\n }\n}\n\nfunction cssRelativeSpecifiers(source: string, file: string): string[] {\n const specifiers = new Set<string>()\n for (const pattern of [CSS_IMPORT, CSS_URL]) {\n pattern.lastIndex = 0\n for (const match of source.matchAll(pattern)) {\n const specifier = match[1]?.trim()\n if (!specifier) continue\n if (/^(?:data:|https?:|\\/\\/|\\/)/i.test(specifier)) {\n throw new Error(`CSS Module contains a non-package-relative URL: ${file}: ${specifier}`)\n }\n specifiers.add(specifier)\n }\n }\n return [...specifiers]\n}\n\nfunction esbuildLoader(file: string): Loader {\n switch (extname(file).toLowerCase()) {\n case \".ts\":\n return \"ts\"\n case \".tsx\":\n return \"tsx\"\n case \".jsx\":\n return \"jsx\"\n default:\n return \"js\"\n }\n}\n\nfunction assertDeclaredNetworkOrigins(source: string, file: string, allowedOrigins: ReadonlySet<string>): void {\n STATIC_HTTP_URL.lastIndex = 0\n for (const match of source.matchAll(STATIC_HTTP_URL)) {\n let origin: string\n try {\n origin = new URL(match[0]).origin\n } catch {\n continue\n }\n if (!allowedOrigins.has(origin)) {\n throw new Error(`entry module references undeclared network origin ${origin}: ${file}`)\n }\n }\n}\n\nasync function auditEntryModuleGraph(\n packageRoot: string,\n entryFile: string,\n allowedOrigins: ReadonlySet<string>,\n): Promise<{ gzipBytes: number; files: string[] }> {\n await init\n const pending: Array<{ file: string; kind: ModuleKind }> = [{ file: entryFile, kind: \"code\" }]\n const visited = new Set<string>()\n const sources: Buffer[] = []\n\n while (pending.length) {\n const { file, kind } = pending.pop() as { file: string; kind: ModuleKind }\n if (visited.has(file)) continue\n visited.add(file)\n const bytes = await readFile(file)\n sources.push(Buffer.from(`// ${file.slice(packageRoot.length)}\\n`), bytes)\n if (kind === \"asset\" || kind === \"data\") continue\n\n const source = bytes.toString(\"utf8\")\n if (kind === \"css\") {\n assertScopedCss(source, file)\n for (const specifier of cssRelativeSpecifiers(source, file)) {\n pending.push(await resolveRelativeModule(packageRoot, file, specifier))\n }\n continue\n }\n if (containsLikelyHardCodedCredential(source)) {\n throw new Error(`entry module contains a likely hard-coded credential: ${file}`)\n }\n assertDeclaredNetworkOrigins(source, file, allowedOrigins)\n if (/\\brequire\\s*\\(/.test(source))\n throw new Error(`entry module uses require(), which is not browser-safe: ${file}`)\n\n let imports: ReturnType<typeof parse>[0]\n try {\n const transformed = await transform(source, {\n loader: esbuildLoader(file),\n format: \"esm\",\n jsx: \"automatic\",\n sourcemap: false,\n sourcefile: file,\n })\n ;[imports] = parse(transformed.code)\n } catch (error) {\n throw new Error(\n `entry module cannot be parsed: ${file}: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n for (const imported of imports) {\n const specifier = imported.n\n if (!specifier) throw new Error(`entry module uses a non-literal dynamic import: ${file}`)\n if (imported.d >= 0) throw new Error(`entry module uses dynamic import(), which is not supported: ${file}`)\n if (specifier.startsWith(\"node:\")) throw new Error(`entry imports Node.js module: ${specifier}`)\n if (specifier.startsWith(\".\")) {\n pending.push(await resolveRelativeModule(packageRoot, file, specifier))\n continue\n }\n if (!IMPORT_ALLOWLIST.has(specifier)) throw new Error(`entry imports non-public dependency: ${specifier}`)\n }\n }\n\n return { gzipBytes: gzipSync(Buffer.concat(sources)).byteLength, files: [...visited] }\n}\n\nexport async function auditBrandPackage(\n manifestFile: string,\n options: { developmentAllowedOrigins?: readonly string[]; platform?: boolean } = {},\n): Promise<BrandAuditResult> {\n const absoluteManifest = await realpath(resolve(manifestFile))\n const packageRoot = await realpath(resolve(absoluteManifest, \"..\"))\n const raw = JSON.parse(await readFile(absoluteManifest, \"utf8\")) as unknown\n // Managed pipeline builds audit a merge-resolved manifest whose identity\n // was assigned from the frozen build input; workspace packages keep the\n // strict namespacing bindings.\n const parsed = parseBrandManifest(raw, { platform: options.platform === true })\n if (!parsed.ok) throw new Error(`manifest contract failed: ${parsed.error}`)\n const manifest = parsed.manifest\n\n const checkedAssets: string[] = []\n for (const [kind, relative] of Object.entries(manifest.assets) as Array<[keyof BrandManifest[\"assets\"], string]>) {\n await assertAsset(packageRoot, relative, kind)\n checkedAssets.push(relative)\n }\n\n let entryGzipBytes = 0\n let checkedModules: string[] = []\n const checkedLocales = manifest.locales ? await auditLocaleDictionaries(packageRoot, manifest.locales) : []\n if (manifest.entry) {\n const entryFile = await resolvePackageFile(packageRoot, manifest.entry, \"entry\")\n const graph = await auditEntryModuleGraph(\n packageRoot,\n entryFile,\n new Set([...(manifest.network?.allowedOrigins ?? []), ...(options.developmentAllowedOrigins ?? [])]),\n )\n entryGzipBytes = graph.gzipBytes\n checkedModules = graph.files.map((file) => `.${file.slice(packageRoot.length)}`)\n if (entryGzipBytes > ENTRY_GZIP_BUDGET) {\n throw new Error(`entry gzip size ${entryGzipBytes} exceeds ${ENTRY_GZIP_BUDGET} byte budget`)\n }\n }\n\n return { manifest, entryGzipBytes, checkedAssets, checkedModules, checkedLocales }\n}\n","#!/usr/bin/env node\n\nimport { auditBrandPackage } from \"./audit-brand.ts\"\n\nconst manifestFile = process.argv[2]\nif (manifestFile === \"--help\" || manifestFile === \"-h\") {\n console.log(\"Usage: orbit-audit-brand <path/to/orbit-brand.json>\")\n} else if (!manifestFile) {\n console.error(\"Usage: orbit-audit-brand <path/to/orbit-brand.json>\")\n process.exitCode = 2\n} else {\n try {\n const report = await auditBrandPackage(manifestFile)\n console.log(\n `✓ ${report.manifest.id}: ${report.checkedAssets.length} assets, ${report.checkedLocales.length} locale packs, ${report.checkedModules.length} entry modules, ${report.entryGzipBytes} module-graph gzip bytes`,\n )\n } catch (cause) {\n console.error(`✗ brand audit failed: ${cause instanceof Error ? cause.message : String(cause)}`)\n process.exitCode = 1\n }\n}\n"]}
package/dist/audit.js CHANGED
@@ -26,7 +26,7 @@ var ROOT_KEYS = /* @__PURE__ */ new Set([
26
26
  "contributes"
27
27
  ]);
28
28
  var IDENTITY_KEYS = /* @__PURE__ */ new Set(["productName", "appId", "versionChannel", "protocolScheme", "userDataNamespace"]);
29
- var ASSET_KEYS = /* @__PURE__ */ new Set(["appIcon", "tray", "logo"]);
29
+ var ASSET_KEYS = /* @__PURE__ */ new Set(["appIcon", "tray", "logo", "loginKV"]);
30
30
  var MODE_KEYS = /* @__PURE__ */ new Set(["light", "dark"]);
31
31
  var CONTRIBUTES_KEYS = /* @__PURE__ */ new Set(["slots"]);
32
32
  var NETWORK_KEYS = /* @__PURE__ */ new Set(["allowedOrigins"]);
@@ -167,10 +167,12 @@ function parseAssets(value) {
167
167
  if (!isRecord(value)) throw new Error("assets must be an object");
168
168
  assertKnownKeys(value, ASSET_KEYS, "assets");
169
169
  const tray = value.tray === void 0 ? void 0 : relativePath(value.tray, "assets.tray");
170
+ const loginKV = value.loginKV === void 0 ? void 0 : relativePath(value.loginKV, "assets.loginKV");
170
171
  return {
171
172
  appIcon: relativePath(value.appIcon, "assets.appIcon"),
172
173
  ...tray ? { tray } : {},
173
- logo: relativePath(value.logo, "assets.logo")
174
+ logo: relativePath(value.logo, "assets.logo"),
175
+ ...loginKV ? { loginKV } : {}
174
176
  };
175
177
  }
176
178
  function parseBrandCopy(value, path) {
@@ -509,7 +511,7 @@ async function assertAsset(packageRoot, relative, kind) {
509
511
  if (!info.isFile()) throw new Error(`assets.${kind} must point to a file`);
510
512
  if (info.size > ASSET_BUDGET) throw new Error(`assets.${kind} exceeds 5 MiB`);
511
513
  const extension = extname(file).toLowerCase();
512
- const allowed = kind === "logo" ? /* @__PURE__ */ new Set([".svg", ".png", ".webp"]) : /* @__PURE__ */ new Set([".png"]);
514
+ const allowed = kind === "loginKV" ? /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]) : kind === "logo" ? /* @__PURE__ */ new Set([".svg", ".png", ".webp"]) : /* @__PURE__ */ new Set([".png"]);
513
515
  if (!allowed.has(extension)) throw new Error(`assets.${kind} has unsupported extension: ${extension}`);
514
516
  if (kind === "appIcon" || kind === "tray") {
515
517
  const bytes = await readFile(file);