bleam 0.0.8 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/cli.cjs +269 -22
  2. package/dist/cli.d.cts +32 -2
  3. package/dist/cli.d.ts +32 -2
  4. package/dist/cli.js +270 -23
  5. package/dist/platform.d.cts +2 -0
  6. package/dist/platform.d.ts +2 -0
  7. package/dist/{ui-1WepaMS4.d.cts → ui-Bg11tvlc.d.ts} +1 -1
  8. package/dist/{ui-Ce-pnUUA.d.ts → ui-Dd7SXdbg.d.cts} +7 -7
  9. package/dist/ui.d.cts +1 -1
  10. package/dist/ui.d.ts +1 -1
  11. package/dist/window.d.cts +1 -1
  12. package/dist/window.d.ts +1 -1
  13. package/package.json +5 -1
  14. package/templates/image-generation/app/index.tsx +1 -1
  15. package/templates/native/.gitattributes +1 -0
  16. package/templates/native/App.tsx +26 -0
  17. package/templates/native/app.json +12 -0
  18. package/templates/native/index.ts +8 -0
  19. package/templates/native/ios/.xcode.env +11 -0
  20. package/templates/native/ios/Bleam/AI/Flux2/Configuration/Flux2Config.swift +288 -0
  21. package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryConfig.swift +233 -0
  22. package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryOptimizationConfig.swift +157 -0
  23. package/templates/native/ios/Bleam/AI/Flux2/Configuration/ModelRegistry.swift +425 -0
  24. package/templates/native/ios/Bleam/AI/Flux2/Configuration/QuantizationConfig.swift +138 -0
  25. package/templates/native/ios/Bleam/AI/Flux2/Configuration/TransformerRepoProfile.swift +59 -0
  26. package/templates/native/ios/Bleam/AI/Flux2/Configuration/VAEConfig.swift +134 -0
  27. package/templates/native/ios/Bleam/AI/Flux2/Flux2Core.swift +55 -0
  28. package/templates/native/ios/Bleam/AI/Flux2/Loading/WeightLoader.swift +1192 -0
  29. package/templates/native/ios/Bleam/AI/Flux2/Pipeline/FluxImageRunner.swift +1282 -0
  30. package/templates/native/ios/Bleam/AI/Flux2/Pipeline/LatentUtils.swift +191 -0
  31. package/templates/native/ios/Bleam/AI/Flux2/Scheduler/FlowMatchEulerScheduler.swift +279 -0
  32. package/templates/native/ios/Bleam/AI/Flux2/Text/KleinTextEncoder.swift +380 -0
  33. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Attention.swift +379 -0
  34. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Embeddings.swift +159 -0
  35. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FeedForward.swift +154 -0
  36. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FusedKernels.swift +198 -0
  37. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2KVCache.swift +36 -0
  38. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Modulation.swift +193 -0
  39. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2ParallelAttention.swift +389 -0
  40. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2RoPE.swift +304 -0
  41. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2SingleBlock.swift +290 -0
  42. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Transformer.swift +530 -0
  43. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2TransformerBlock.swift +362 -0
  44. package/templates/native/ios/Bleam/AI/Flux2/Utils/Flux2Debug.swift +101 -0
  45. package/templates/native/ios/Bleam/AI/Flux2/Utils/MLXCheckpoint.swift +118 -0
  46. package/templates/native/ios/Bleam/AI/Flux2/Utils/MemoryManager.swift +201 -0
  47. package/templates/native/ios/Bleam/AI/Flux2/VAE/AutoencoderKL.swift +476 -0
  48. package/templates/native/ios/Bleam/AI/Flux2/VAE/ResnetBlock.swift +316 -0
  49. package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEDecoder.swift +120 -0
  50. package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEEncoder.swift +136 -0
  51. package/templates/native/ios/Bleam/AppDelegate.swift +482 -0
  52. package/templates/native/ios/Bleam/Appearance.swift +62 -0
  53. package/templates/native/ios/Bleam/Bridging-Header.h +3 -0
  54. package/templates/native/ios/Bleam/Images.xcassets/AppIcon.appiconset/Contents.json +13 -0
  55. package/templates/native/ios/Bleam/Images.xcassets/Contents.json +6 -0
  56. package/templates/native/ios/Bleam/Info.plist +76 -0
  57. package/templates/native/ios/Bleam/PrivacyInfo.xcprivacy +48 -0
  58. package/templates/native/ios/Bleam/SceneDelegate.swift +58 -0
  59. package/templates/native/ios/Bleam/SplashScreen.storyboard +47 -0
  60. package/templates/native/ios/Bleam/Supporting/Expo.plist +6 -0
  61. package/templates/native/ios/Bleam/bleam.entitlements +10 -0
  62. package/templates/native/ios/Bleam.xcodeproj/project.pbxproj +1147 -0
  63. package/templates/native/ios/Bleam.xcodeproj/xcshareddata/xcschemes/Bleam.xcscheme +88 -0
  64. package/templates/native/ios/GenerationService/GenerationService.entitlements +10 -0
  65. package/templates/native/ios/GenerationService/ImageGenerationRunner.swift +591 -0
  66. package/templates/native/ios/GenerationService/Info.plist +31 -0
  67. package/templates/native/ios/GenerationService/main.swift +165 -0
  68. package/templates/native/ios/PlatformHelper/main.swift +726 -0
  69. package/templates/native/ios/Podfile +198 -0
  70. package/templates/native/ios/Podfile.lock +2284 -0
  71. package/templates/native/ios/Podfile.properties.json +5 -0
  72. package/templates/native/ios/Shared/Generation/GenerationServiceProtocol.swift +12 -0
  73. package/templates/native/ios/Shared/Generation/GenerationWorkerProtocol.swift +124 -0
  74. package/templates/native/metro.config.js +6 -0
  75. package/templates/native/modules/bleam-runtime/BleamRuntime.podspec +14 -0
  76. package/templates/native/modules/bleam-runtime/expo-module.config.json +8 -0
  77. package/templates/native/modules/bleam-runtime/ios/AIModule.swift +1258 -0
  78. package/templates/native/modules/bleam-runtime/ios/GenerationContracts.swift +135 -0
  79. package/templates/native/modules/bleam-runtime/ios/PlatformModule.swift +329 -0
  80. package/templates/native/modules/bleam-runtime/package.json +5 -0
  81. package/templates/native/package.json +39 -0
  82. package/templates/native/scripts/build/mlx-frameworks.ts +421 -0
  83. package/templates/native/scripts/start/index.ts +474 -0
  84. package/templates/native/scripts/start/known-failures.ts +20 -0
  85. package/templates/native/scripts/start/loader.ts +76 -0
  86. package/templates/native/scripts/start/native-state.ts +242 -0
  87. package/templates/native/scripts/start/package.json +4 -0
  88. package/templates/native/scripts/start/swift-packages.ts +414 -0
  89. package/templates/native/scripts/start/xcode-formatter.ts +106 -0
  90. package/templates/native/tsconfig.json +14 -0
  91. package/templates/native/yarn.lock +3749 -0
  92. package/templates/updates/README.md +272 -0
  93. package/templates/updates/src/index.ts +385 -0
  94. package/templates/updates/src/schema.ts +385 -0
  95. package/templates/updates/tsconfig.json +12 -0
  96. package/templates/updates/wrangler.jsonc +19 -0
package/dist/cli.cjs CHANGED
@@ -24,6 +24,7 @@ let yoctocolors = require("yoctocolors");
24
24
  yoctocolors = require_chunk.__toESM(yoctocolors);
25
25
 
26
26
  //#region src/cli.ts
27
+ const localUpdateServiceUrl = "http://127.0.0.1:8787";
27
28
  const require$1 = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
28
29
  const packageRoot = node_path.default.dirname((0, node_url.fileURLToPath)(new URL("../package.json", require("url").pathToFileURL(__filename).href)));
29
30
  const packageJson = require$1("../package.json");
@@ -96,7 +97,7 @@ Commands:
96
97
  Build and install a standalone macOS app
97
98
  publish ota [dir] [--service-url <url>]
98
99
  Publish an OTA update to the local update service
99
- publish platform [dir] [--service-url <url>]
100
+ publish platform [dir] [--service-url <url>] [--redeploy]
100
101
  Build and publish a platform update locally
101
102
  doctor [dir] Check the local Bleam environment
102
103
  typecheck [dir] Typecheck project files
@@ -108,7 +109,7 @@ function parsePublishOtaOptions(argv) {
108
109
  const root = invocationRoot();
109
110
  let projectRoot = root;
110
111
  let hasProjectRootArg = false;
111
- let serviceUrl = process.env.BLEAM_UPDATE_SERVICE_URL ?? "http://127.0.0.1:8787";
112
+ let serviceUrl = process.env.BLEAM_UPDATE_SERVICE_URL ?? localUpdateServiceUrl;
112
113
  for (let index = 0; index < argv.length; index += 1) {
113
114
  const arg = argv[index];
114
115
  if (arg === "--service-url") {
@@ -132,6 +133,13 @@ function parsePublishOtaOptions(argv) {
132
133
  serviceUrl: url.origin
133
134
  };
134
135
  }
136
+ function parsePublishPlatformOptions(argv) {
137
+ const redeploy = argv.includes("--redeploy");
138
+ return {
139
+ ...parsePublishOtaOptions(argv.filter((argument) => argument !== "--redeploy")),
140
+ redeploy
141
+ };
142
+ }
135
143
  function invocationRoot() {
136
144
  const pwd = process.env.PWD;
137
145
  return pwd && node_path.default.isAbsolute(pwd) ? pwd : process.cwd();
@@ -479,7 +487,8 @@ function readProjectConfig(options) {
479
487
  teamId: config.teamId,
480
488
  appearance: config.appearance ?? normalizeAppearance(void 0),
481
489
  runtimeVersion,
482
- sdkVersion: runtimeVersion
490
+ sdkVersion: runtimeVersion,
491
+ iconPath: (0, node_fs.existsSync)(node_path.default.join(options.projectRoot, "icon.png")) ? node_path.default.join(options.projectRoot, "icon.png") : void 0
483
492
  };
484
493
  }
485
494
  function slugFromName(name) {
@@ -635,8 +644,21 @@ function writeProjectRuntimeConfig(projectRoot, config, origin) {
635
644
  }, null, 2)}\n`);
636
645
  return projectConfigPath;
637
646
  }
638
- function nativeRuntimeTemplateRoot() {
639
- return node_path.default.resolve(packageRoot, "..", "..", "app", "bleam");
647
+ function nativeRuntimeTemplateRoot(root = packageRoot) {
648
+ const bundledTemplate = node_path.default.join(root, "templates", "native");
649
+ return (0, node_fs.existsSync)(bundledTemplate) ? bundledTemplate : node_path.default.resolve(root, "..", "..", "app", "bleam");
650
+ }
651
+ function localUpdateServiceRoot(root = packageRoot) {
652
+ const bundledService = node_path.default.join(root, "templates", "updates");
653
+ return (0, node_fs.existsSync)(bundledService) ? bundledService : node_path.default.resolve(root, "..", "..", "services", "updates");
654
+ }
655
+ function localUpdateServicePaths(home = node_os.default.homedir()) {
656
+ const root = node_path.default.join(home, "Library", "Caches", "bleam", "updates");
657
+ return {
658
+ root,
659
+ state: node_path.default.join(root, "state"),
660
+ log: node_path.default.join(root, "worker.log")
661
+ };
640
662
  }
641
663
  function safeArtifactName(name) {
642
664
  return name.trim().replace(/[/:\\]/g, "-").replace(/\s+/g, " ") || "App";
@@ -672,11 +694,13 @@ function replaceOrInsertPlistStringArray(plist, key, values) {
672
694
  return `${plist.slice(0, closingDictionary)}\t<key>${key}</key>\n\t<array>\n${plistStringArray(values)}\n\t</array>\n${plist.slice(closingDictionary)}`;
673
695
  }
674
696
  function writeGeneratedAppJson(nativeRoot, config) {
697
+ const icon = config.iconPath ? "./icon.png" : void 0;
675
698
  (0, node_fs.writeFileSync)(node_path.default.join(nativeRoot, "app.json"), `${JSON.stringify({ expo: {
676
699
  name: config.name,
677
700
  slug: slugFromName(config.name),
678
701
  version: config.version ?? "1.0.0",
679
702
  platforms: ["ios"],
703
+ icon,
680
704
  ios: {
681
705
  appleTeamId: config.teamId,
682
706
  buildNumber: config.buildNumber,
@@ -684,24 +708,65 @@ function writeGeneratedAppJson(nativeRoot, config) {
684
708
  }
685
709
  } }, null, 2)}\n`);
686
710
  }
711
+ function prepareNativeIcon(nativeRoot, iconPath) {
712
+ const generatedIcon = node_path.default.join(nativeRoot, "icon.png");
713
+ const appIconRoot = node_path.default.join(nativeRoot, "ios", "Bleam", "Images.xcassets", "AppIcon.appiconset");
714
+ (0, node_fs.rmSync)(generatedIcon, { force: true });
715
+ (0, node_fs.rmSync)(node_path.default.join(appIconRoot, "AppIcon.png"), { force: true });
716
+ if (!iconPath) return;
717
+ (0, node_fs.cpSync)(iconPath, generatedIcon);
718
+ (0, node_fs.cpSync)(iconPath, node_path.default.join(appIconRoot, "AppIcon.png"));
719
+ (0, node_fs.writeFileSync)(node_path.default.join(appIconRoot, "Contents.json"), `${JSON.stringify({
720
+ images: [{
721
+ filename: "AppIcon.png",
722
+ idiom: "universal",
723
+ platform: "ios",
724
+ size: "1024x1024"
725
+ }],
726
+ info: {
727
+ version: 1,
728
+ author: "bleam"
729
+ }
730
+ }, null, 2)}\n`);
731
+ }
732
+ function platformInputFingerprint(config) {
733
+ const iconSha256 = config.iconPath ? sha256(config.iconPath) : null;
734
+ return (0, node_crypto.createHash)("sha256").update(JSON.stringify({
735
+ schemaVersion: 1,
736
+ bleamPlatformVersion: config.runtimeVersion,
737
+ name: config.name,
738
+ appVersion: config.version ?? "1.0.0",
739
+ buildNumber: config.buildNumber,
740
+ bundleIdentifier: config.bundleIdentifier,
741
+ teamIdentifier: config.teamId,
742
+ appGroups: config.appGroups,
743
+ appearance: config.appearance,
744
+ iconSha256,
745
+ updateServiceUrl: process.env.BLEAM_UPDATE_SERVICE_URL ?? localUpdateServiceUrl,
746
+ target: {
747
+ os: "macos",
748
+ architecture: "arm64",
749
+ minimumMacOSVersion: "14.0"
750
+ }
751
+ })).digest("hex");
752
+ }
687
753
  function patchNativeProject(nativeRoot, config) {
688
754
  const projectPath = node_path.default.join(nativeRoot, "ios", "Bleam.xcodeproj", "project.pbxproj");
689
755
  const infoPlistPath = node_path.default.join(nativeRoot, "ios", "Bleam", "Info.plist");
690
756
  const generationInfoPlistPath = node_path.default.join(nativeRoot, "ios", "GenerationService", "Info.plist");
691
- const platformInfoPlistPath = node_path.default.join(nativeRoot, "ios", "PlatformHelper", "Info.plist");
692
757
  const appEntitlementsPath = node_path.default.join(nativeRoot, "ios", "Bleam", "bleam.entitlements");
693
758
  const generationEntitlementsPath = node_path.default.join(nativeRoot, "ios", "GenerationService", "GenerationService.entitlements");
694
759
  const productName = xcodeSettingValue(config.name);
695
760
  const bundleIdentifier = xcodeSettingValue(config.bundleIdentifier ?? "");
696
761
  const generationBundleIdentifier = xcodeSettingValue(`${config.bundleIdentifier}.GenerationService`);
697
- const platformBundleIdentifier = xcodeSettingValue(`${config.bundleIdentifier}.PlatformHelper`);
698
762
  const teamId = xcodeSettingValue(config.teamId ?? "");
699
763
  const version = xcodeSettingValue(config.version ?? "1.0.0");
700
764
  const buildNumber = xcodeSettingValue(config.buildNumber);
701
765
  const primaryAppGroup = config.appGroups[0];
766
+ const fingerprint = platformInputFingerprint(config);
702
767
  let project = (0, node_fs.readFileSync)(projectPath, "utf8");
703
768
  project = project.replace(/PRODUCT_BUNDLE_IDENTIFIER = ([^;]+);/g, (_, current) => {
704
- return `PRODUCT_BUNDLE_IDENTIFIER = ${current.endsWith(".GenerationService") ? generationBundleIdentifier : current.endsWith(".PlatformHelper") ? platformBundleIdentifier : bundleIdentifier};`;
769
+ return `PRODUCT_BUNDLE_IDENTIFIER = ${current.endsWith(".GenerationService") ? generationBundleIdentifier : bundleIdentifier};`;
705
770
  }).replace(/DEVELOPMENT_TEAM = [^;]+;/g, () => {
706
771
  return `DEVELOPMENT_TEAM = ${teamId};`;
707
772
  }).replace(/MARKETING_VERSION = [^;]+;/g, () => {
@@ -716,9 +781,10 @@ function patchNativeProject(nativeRoot, config) {
716
781
  infoPlist = replacePlistString(infoPlist, "CFBundleDisplayName", config.name);
717
782
  infoPlist = replacePlistString(infoPlist, "CFBundleShortVersionString", config.version ?? "1.0.0");
718
783
  infoPlist = replaceOrInsertPlistString(infoPlist, "BleamRuntimeVersion", config.runtimeVersion);
784
+ infoPlist = replaceOrInsertPlistString(infoPlist, "BleamPlatformFingerprint", fingerprint);
719
785
  infoPlist = replaceOrInsertPlistString(infoPlist, "BleamTeamIdentifier", config.teamId ?? "");
720
- const updateServiceUrl = process.env.BLEAM_UPDATE_SERVICE_URL;
721
- if (updateServiceUrl) infoPlist = replaceOrInsertPlistString(infoPlist, "BleamUpdateServiceURL", updateServiceUrl);
786
+ const updateServiceUrl = process.env.BLEAM_UPDATE_SERVICE_URL ?? localUpdateServiceUrl;
787
+ infoPlist = replaceOrInsertPlistString(infoPlist, "BleamUpdateServiceURL", updateServiceUrl);
722
788
  infoPlist = replacePlistString(infoPlist, "CFBundleVersion", config.buildNumber);
723
789
  if (primaryAppGroup) infoPlist = replaceOrInsertPlistString(infoPlist, "AppGroupIdentifier", primaryAppGroup);
724
790
  (0, node_fs.writeFileSync)(infoPlistPath, infoPlist);
@@ -726,7 +792,6 @@ function patchNativeProject(nativeRoot, config) {
726
792
  let generationInfoPlist = (0, node_fs.readFileSync)(generationInfoPlistPath, "utf8");
727
793
  generationInfoPlist = replaceOrInsertPlistString(generationInfoPlist, "AppGroupIdentifier", primaryAppGroup);
728
794
  (0, node_fs.writeFileSync)(generationInfoPlistPath, generationInfoPlist);
729
- (0, node_fs.writeFileSync)(platformInfoPlistPath, replaceOrInsertPlistString((0, node_fs.readFileSync)(platformInfoPlistPath, "utf8"), "BleamPlatformVersion", config.runtimeVersion));
730
795
  for (const entitlementsPath of [appEntitlementsPath, generationEntitlementsPath]) (0, node_fs.writeFileSync)(entitlementsPath, replaceOrInsertPlistStringArray((0, node_fs.readFileSync)(entitlementsPath, "utf8"), "com.apple.security.application-groups", config.appGroups));
731
796
  }
732
797
  }
@@ -742,8 +807,10 @@ function createBuildNativeWorkspace(options, config) {
742
807
  recursive: true,
743
808
  verbatimSymlinks: true,
744
809
  filter(source) {
745
- return !node_path.default.relative(templateRoot, source).split(node_path.default.sep).some((part) => {
746
- return part === "build" || part === "dist" || part === "node_modules" || part === ".expo" || part === "Pods" || part === ".xcode.env.local" || part === ".DS_Store" || part.endsWith(".xcworkspace");
810
+ const parts = node_path.default.relative(templateRoot, source).split(node_path.default.sep);
811
+ return !parts.some((part, index) => {
812
+ const frameworkBuildScript = part === "build" && index === 1 && parts[0] === "scripts";
813
+ return part === "build" && !frameworkBuildScript || part === "dist" || part === "node_modules" || part === ".expo" || part === "Pods" || part === ".xcode.env.local" || part === ".DS_Store" || part.endsWith(".xcworkspace");
747
814
  });
748
815
  }
749
816
  });
@@ -757,6 +824,7 @@ function createBuildNativeWorkspace(options, config) {
757
824
  (0, node_fs.writeFileSync)(node_path.default.join(nativeRoot, "index.ts"), `import { registerApp } from 'bleam/app'\nimport App from ${JSON.stringify(node_path.default.join(options.projectRoot, "app"))}\n\nregisterApp(App)\n`);
758
825
  (0, node_fs.writeFileSync)(node_path.default.join(nativeRoot, "metro.config.js"), `const { getDefaultConfig } = require(${JSON.stringify(node_path.default.join(packageRoot, "metro-config.cjs"))})\n\nmodule.exports = getDefaultConfig(__dirname)\n`);
759
826
  (0, node_fs.writeFileSync)(node_path.default.join(nativeRoot, "ios", ".xcode.env"), `export NODE_BINARY=$(command -v node)\nexport BLEAM_PROJECT_ROOT=${singleQuotedString(options.projectRoot)}\nexport BLEAM_DEV_PLATFORM=macos\n`);
827
+ prepareNativeIcon(nativeRoot, config.iconPath);
760
828
  patchNativeProject(nativeRoot, config);
761
829
  return nativeRoot;
762
830
  }
@@ -781,14 +849,27 @@ function runInheritedCommand(command, args, cwd) {
781
849
  }
782
850
  function installPods(nativeRoot) {
783
851
  const iosRoot = node_path.default.join(nativeRoot, "ios");
784
- const expectedStamp = podInstallInputStamp(iosRoot);
785
- if (hasCurrentPodInstall(iosRoot, expectedStamp)) {
852
+ if (hasCurrentPodInstall(iosRoot, podInstallInputStamp(iosRoot))) {
786
853
  console.log("Using cached native dependencies");
787
854
  return;
788
855
  }
789
856
  console.log("Installing native dependencies...");
790
857
  runInheritedCommand("pod", ["install"], iosRoot);
791
- (0, node_fs.writeFileSync)(podInstallStampPath(iosRoot), `${expectedStamp}\n`);
858
+ (0, node_fs.writeFileSync)(podInstallStampPath(iosRoot), `${podInstallInputStamp(iosRoot)}\n`);
859
+ }
860
+ function ensureNativeFrameworks(nativeRoot) {
861
+ const frameworksRoot = node_path.default.join(nativeRoot, "ios", "Vendor", "MLXSwift", "0.31.6-macos");
862
+ if ([
863
+ "Cmlx",
864
+ "MLX",
865
+ "MLXNN",
866
+ "MLXOptimizers"
867
+ ].every((name) => (0, node_fs.existsSync)(node_path.default.join(frameworksRoot, `${name}.framework`)))) {
868
+ console.log("Using cached native MLX frameworks");
869
+ return;
870
+ }
871
+ console.log("Preparing native MLX frameworks...");
872
+ runInheritedCommand(node_path.default.join(resolvedDependencyRoot(), ".bin", "tsx"), [node_path.default.join(nativeRoot, "scripts", "build", "mlx-frameworks.ts")], nativeRoot);
792
873
  }
793
874
  function podInstallInputStamp(iosRoot) {
794
875
  const inputHash = (0, node_crypto.createHash)("sha256");
@@ -807,7 +888,9 @@ function podInstallStampPath(iosRoot) {
807
888
  }
808
889
  function hasCurrentPodInstall(iosRoot, expectedStamp) {
809
890
  const stampPath = podInstallStampPath(iosRoot);
810
- return (0, node_fs.existsSync)(node_path.default.join(iosRoot, "Bleam.xcworkspace")) && (0, node_fs.existsSync)(node_path.default.join(iosRoot, "Pods", "Manifest.lock")) && (0, node_fs.existsSync)(stampPath) && (0, node_fs.readFileSync)(stampPath, "utf8").trim() === expectedStamp;
891
+ const lockPath = node_path.default.join(iosRoot, "Podfile.lock");
892
+ const manifestPath = node_path.default.join(iosRoot, "Pods", "Manifest.lock");
893
+ return (0, node_fs.existsSync)(node_path.default.join(iosRoot, "Bleam.xcworkspace")) && (0, node_fs.existsSync)(lockPath) && (0, node_fs.existsSync)(manifestPath) && (0, node_fs.readFileSync)(lockPath, "utf8") === (0, node_fs.readFileSync)(manifestPath, "utf8") && (0, node_fs.existsSync)(stampPath) && (0, node_fs.readFileSync)(stampPath, "utf8").trim() === expectedStamp;
811
894
  }
812
895
  function nativeArchiveArgs(options) {
813
896
  return [
@@ -866,6 +949,7 @@ async function buildNativeArchives(options) {
866
949
  const config = readProjectConfig(options);
867
950
  preflightBuild(options, config);
868
951
  const nativeRoot = createBuildNativeWorkspace(options, config);
952
+ ensureNativeFrameworks(nativeRoot);
869
953
  installPods(nativeRoot);
870
954
  const archivePath = archiveNativeApp({
871
955
  nativeRoot,
@@ -981,10 +1065,76 @@ async function publishOta(options) {
981
1065
  console.log(`Published OTA update ${releaseId}`);
982
1066
  console.log(`${options.serviceUrl}/v1/apps/${encodeURIComponent(config.bundleIdentifier)}/ota/${runtimeVersion}`);
983
1067
  }
1068
+ function compareVersions(left, right) {
1069
+ const parse = (value) => {
1070
+ const match = /^(\d+)\.(\d+)\.(\d+)(?:-([^+]+))?(?:\+.*)?$/.exec(value);
1071
+ if (!match) throw new Error(`Invalid Bleam platform version: ${value}`);
1072
+ return {
1073
+ core: match.slice(1, 4).map(Number),
1074
+ prerelease: match[4]?.split(".")
1075
+ };
1076
+ };
1077
+ const a = parse(left);
1078
+ const b = parse(right);
1079
+ for (let index = 0; index < a.core.length; index += 1) if (a.core[index] !== b.core[index]) return (a.core[index] ?? 0) < (b.core[index] ?? 0) ? -1 : 1;
1080
+ if (!a.prerelease && !b.prerelease) return 0;
1081
+ if (!a.prerelease) return 1;
1082
+ if (!b.prerelease) return -1;
1083
+ const length = Math.max(a.prerelease.length, b.prerelease.length);
1084
+ for (let index = 0; index < length; index += 1) {
1085
+ const aPart = a.prerelease[index];
1086
+ const bPart = b.prerelease[index];
1087
+ if (aPart === void 0) return -1;
1088
+ if (bPart === void 0) return 1;
1089
+ if (aPart === bPart) continue;
1090
+ const aNumber = /^\d+$/.test(aPart) ? Number(aPart) : void 0;
1091
+ const bNumber = /^\d+$/.test(bPart) ? Number(bPart) : void 0;
1092
+ if (aNumber !== void 0 && bNumber !== void 0) return aNumber < bNumber ? -1 : 1;
1093
+ if (aNumber !== void 0) return -1;
1094
+ if (bNumber !== void 0) return 1;
1095
+ return aPart < bPart ? -1 : 1;
1096
+ }
1097
+ return 0;
1098
+ }
1099
+ function platformPublicationReason(active, target, redeploy) {
1100
+ if (active && compareVersions(target.bleamPlatformVersion, active.bleamPlatformVersion) < 0) throw new Error(`Cannot publish older Bleam platform ${target.bleamPlatformVersion} over ${active.bleamPlatformVersion}. Rollback requires a separate release operation.`);
1101
+ const unchanged = active?.platformFingerprint === target.platformFingerprint;
1102
+ if (unchanged && !redeploy) throw new Error("Platform inputs are unchanged. Developer code and ordinary assets must be published with bleam publish ota. Use --redeploy only to intentionally republish identical platform inputs.");
1103
+ if (!unchanged && redeploy) throw new Error("--redeploy requires an existing release with the same platform fingerprint; publish normally because platform inputs changed.");
1104
+ if (unchanged) return "redeploy";
1105
+ if (!active) return "first-release";
1106
+ if (!active.platformFingerprint) return "legacy-migration";
1107
+ if (active.bleamPlatformVersion !== target.bleamPlatformVersion) return "runtime-upgrade";
1108
+ return "signed-input-change";
1109
+ }
1110
+ async function activePlatformRelease(serviceUrl, config) {
1111
+ const response = await fetch(`${serviceUrl}/v1/apps/${encodeURIComponent(config.bundleIdentifier ?? "")}/platform/macos-arm64`, { cache: "no-store" });
1112
+ if (response.status === 404) return void 0;
1113
+ if (!response.ok) throw new Error(`Could not resolve the active platform release: ${response.status} ${await response.text()}`);
1114
+ const release = await response.json();
1115
+ if (release.kind !== "platform" || release.bundleIdentifier !== config.bundleIdentifier || release.teamIdentifier !== config.teamId || typeof release.bleamPlatformVersion !== "string" || release.platformFingerprint !== void 0 && (typeof release.platformFingerprint !== "string" || !/^[a-f0-9]{64}$/.test(release.platformFingerprint))) throw new Error("The active platform release is invalid for this app");
1116
+ return {
1117
+ bleamPlatformVersion: release.bleamPlatformVersion,
1118
+ platformFingerprint: release.platformFingerprint
1119
+ };
1120
+ }
984
1121
  async function publishPlatform(options) {
985
1122
  const config = readProjectConfig(options);
986
1123
  if (!config.bundleIdentifier) throw missingBuildFieldError("bundleIdentifier");
987
1124
  if (!config.teamId) throw missingBuildFieldError("teamId");
1125
+ const fingerprint = platformInputFingerprint(config);
1126
+ const active = await activePlatformRelease(options.serviceUrl, config);
1127
+ console.log(`Bleam platform: ${active?.bleamPlatformVersion ?? "none"} -> ${config.runtimeVersion}`);
1128
+ console.log(`Platform fingerprint: ${active?.platformFingerprint ?? "none"} -> ${fingerprint}`);
1129
+ const reason = platformPublicationReason(active, {
1130
+ bleamPlatformVersion: config.runtimeVersion,
1131
+ platformFingerprint: fingerprint
1132
+ }, options.redeploy);
1133
+ if (reason === "redeploy") console.log("Redeploying unchanged platform inputs by explicit request");
1134
+ else if (reason === "first-release") console.log("Publishing the first platform release for this app");
1135
+ else if (reason === "legacy-migration") console.log("Migrating the active legacy release to platform fingerprints");
1136
+ else if (reason === "runtime-upgrade") console.log("Publishing a Bleam platform runtime upgrade");
1137
+ else console.log("Publishing changed signed app metadata or resources");
988
1138
  const archivePath = await buildNativeArchives({
989
1139
  projectRoot: options.projectRoot,
990
1140
  output: node_path.default.join(options.projectRoot, "dist"),
@@ -1013,7 +1163,7 @@ async function publishPlatform(options) {
1013
1163
  const sizeBytes = (0, node_fs.readFileSync)(artifactPath).byteLength;
1014
1164
  const digest = sha256(artifactPath);
1015
1165
  const releaseId = `platform_${Date.now().toString(36)}_${digest.slice(0, 12)}`;
1016
- const release = platformRelease(config, releaseId, sizeBytes, digest);
1166
+ const release = platformRelease(config, releaseId, sizeBytes, digest, options.redeploy);
1017
1167
  const response = await fetch(`${options.serviceUrl}/v1/local/releases/platform`, {
1018
1168
  method: "POST",
1019
1169
  headers: { "content-type": "application/json" },
@@ -1026,7 +1176,7 @@ async function publishPlatform(options) {
1026
1176
  console.log(`Published platform update ${releaseId}`);
1027
1177
  console.log(`${options.serviceUrl}/v1/apps/${encodeURIComponent(config.bundleIdentifier)}/platform/macos-arm64`);
1028
1178
  }
1029
- function platformRelease(config, releaseId, sizeBytes, digest) {
1179
+ function platformRelease(config, releaseId, sizeBytes, digest, redeploy = false) {
1030
1180
  if (!config.bundleIdentifier) throw missingBuildFieldError("bundleIdentifier");
1031
1181
  if (!config.teamId) throw missingBuildFieldError("teamId");
1032
1182
  return {
@@ -1038,7 +1188,9 @@ function platformRelease(config, releaseId, sizeBytes, digest) {
1038
1188
  releaseId,
1039
1189
  appVersion: config.version ?? "1.0.0",
1040
1190
  buildNumber: config.buildNumber,
1041
- bleamPlatformVersion: runtimeVersion,
1191
+ bleamPlatformVersion: config.runtimeVersion,
1192
+ platformFingerprint: platformInputFingerprint(config),
1193
+ redeploy,
1042
1194
  target: {
1043
1195
  os: "macos",
1044
1196
  architecture: "arm64",
@@ -1387,6 +1539,92 @@ async function launchRuntimeClient(appPath, projectConfigPath, manifest) {
1387
1539
  quitRuntimeClient();
1388
1540
  openRuntimeClient(appPath, projectConfigPath, manifest);
1389
1541
  }
1542
+ async function updateServiceHealthy(serviceUrl) {
1543
+ try {
1544
+ const response = await fetch(`${serviceUrl}/v1/health`, {
1545
+ cache: "no-store",
1546
+ signal: AbortSignal.timeout(1e3)
1547
+ });
1548
+ if (!response.ok) return false;
1549
+ return (await response.json()).healthy === true;
1550
+ } catch {
1551
+ return false;
1552
+ }
1553
+ }
1554
+ function updateServiceLogTail(logPath) {
1555
+ if (!(0, node_fs.existsSync)(logPath)) return "";
1556
+ return (0, node_fs.readFileSync)(logPath, "utf8").slice(-4e3).trim();
1557
+ }
1558
+ async function waitForUpdateService(child, serviceUrl, logPath, timeoutMs = 3e4) {
1559
+ const startedAt = Date.now();
1560
+ let startupError;
1561
+ child.once("error", (error) => {
1562
+ startupError = error;
1563
+ });
1564
+ while (Date.now() - startedAt < timeoutMs) {
1565
+ if (startupError || child.exitCode !== null) break;
1566
+ if (await updateServiceHealthy(serviceUrl)) return;
1567
+ await new Promise((resolve) => setTimeout(resolve, 250));
1568
+ }
1569
+ const log = updateServiceLogTail(logPath);
1570
+ const detail = log ? `\n\n${log}` : "";
1571
+ throw new Error(`Local update Worker failed to start.\nLog: ${logPath}${detail}`, startupError ? { cause: startupError } : void 0);
1572
+ }
1573
+ async function startLocalUpdateService() {
1574
+ const configuredUrl = process.env.BLEAM_UPDATE_SERVICE_URL ?? localUpdateServiceUrl;
1575
+ const serviceUrl = new URL(configuredUrl).origin;
1576
+ if (await updateServiceHealthy(serviceUrl)) {
1577
+ console.log(`Using local update Worker at ${serviceUrl}`);
1578
+ return {
1579
+ child: void 0,
1580
+ serviceUrl
1581
+ };
1582
+ }
1583
+ if (serviceUrl !== localUpdateServiceUrl) throw new Error(`BLEAM_UPDATE_SERVICE_URL is not healthy: ${serviceUrl}/v1/health`);
1584
+ const serviceRoot = localUpdateServiceRoot();
1585
+ const configPath = node_path.default.join(serviceRoot, "wrangler.jsonc");
1586
+ if (!(0, node_fs.existsSync)(configPath)) throw new Error(`Missing local update Worker: ${serviceRoot}`);
1587
+ const wrangler = node_path.default.join(resolvedDependencyRoot(), ".bin", "wrangler");
1588
+ if (!(0, node_fs.existsSync)(wrangler)) throw new Error("Missing Wrangler dependency for the local update Worker");
1589
+ const paths = localUpdateServicePaths();
1590
+ (0, node_fs.mkdirSync)(paths.state, { recursive: true });
1591
+ const log = (0, node_fs.openSync)(paths.log, "a");
1592
+ const child = (0, node_child_process.spawn)(wrangler, [
1593
+ "dev",
1594
+ "--config",
1595
+ configPath,
1596
+ "--local",
1597
+ "--persist-to",
1598
+ paths.state,
1599
+ "--ip",
1600
+ "127.0.0.1",
1601
+ "--port",
1602
+ "8787"
1603
+ ], {
1604
+ cwd: serviceRoot,
1605
+ stdio: [
1606
+ "ignore",
1607
+ log,
1608
+ log
1609
+ ],
1610
+ env: {
1611
+ ...process.env,
1612
+ NO_COLOR: "1"
1613
+ }
1614
+ });
1615
+ (0, node_fs.closeSync)(log);
1616
+ try {
1617
+ await waitForUpdateService(child, serviceUrl, paths.log);
1618
+ } catch (error) {
1619
+ child.kill("SIGTERM");
1620
+ throw error;
1621
+ }
1622
+ console.log(`Local update Worker running at ${serviceUrl}`);
1623
+ return {
1624
+ child,
1625
+ serviceUrl
1626
+ };
1627
+ }
1390
1628
  function focusRuntimeClient() {
1391
1629
  return (0, node_child_process.spawnSync)("osascript", ["-e", "tell application id \"dev.bleam.app\" to activate"], { stdio: "ignore" }).status === 0;
1392
1630
  }
@@ -1721,6 +1959,7 @@ async function startDevServer(options) {
1721
1959
  const workspaceRoot = createDevWorkspace(options.projectRoot, config);
1722
1960
  const origin = `http://localhost:${options.port}`;
1723
1961
  const projectConfigPath = writeProjectRuntimeConfig(options.projectRoot, config, origin);
1962
+ const updateService = await startLocalUpdateService();
1724
1963
  const child = (0, node_child_process.spawn)(process.execPath, [
1725
1964
  (0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href),
1726
1965
  "internal:metro",
@@ -1741,6 +1980,7 @@ async function startDevServer(options) {
1741
1980
  BLEAM_DEV_PLATFORM: "macos",
1742
1981
  BLEAM_DEV_RUNTIME_VERSION: config.runtimeVersion,
1743
1982
  BLEAM_DEV_SDK_VERSION: config.sdkVersion,
1983
+ BLEAM_UPDATE_SERVICE_URL: updateService.serviceUrl,
1744
1984
  NODE_PATH: [
1745
1985
  node_path.default.join(options.projectRoot, "node_modules"),
1746
1986
  resolvedDependencyRoot(),
@@ -1760,6 +2000,7 @@ async function startDevServer(options) {
1760
2000
  didCleanupDevSession = true;
1761
2001
  cleanupInteractiveControls();
1762
2002
  if (didLaunchRuntimeClient) quitRuntimeClient();
2003
+ if (updateService.child?.exitCode === null) updateService.child.kill("SIGTERM");
1763
2004
  };
1764
2005
  const stop = (signal) => {
1765
2006
  if (stopping) return;
@@ -1842,10 +2083,10 @@ async function main(argv = process.argv.slice(2)) {
1842
2083
  return;
1843
2084
  }
1844
2085
  if (kind === "platform") {
1845
- await publishPlatform(parsePublishOtaOptions(publishArgs));
2086
+ await publishPlatform(parsePublishPlatformOptions(publishArgs));
1846
2087
  return;
1847
2088
  }
1848
- throw new Error("Usage: bleam publish <ota|platform> [dir] [--service-url <url>]");
2089
+ throw new Error("Usage: bleam publish <ota|platform> [dir] [--service-url <url>] [--redeploy]");
1849
2090
  }
1850
2091
  if (command === "doctor") {
1851
2092
  runDoctor(parseDoctorOptions(args));
@@ -1883,10 +2124,16 @@ const __test = {
1883
2124
  hasCurrentPodInstall,
1884
2125
  installedAppPath,
1885
2126
  installArchivedApp,
2127
+ localUpdateServicePaths,
2128
+ localUpdateServiceRoot,
2129
+ nativeRuntimeTemplateRoot,
1886
2130
  nativeArchiveArgs,
1887
2131
  parseBuildOptions,
1888
2132
  parseNewOptions,
1889
2133
  parsePublishOtaOptions,
2134
+ parsePublishPlatformOptions,
2135
+ platformInputFingerprint,
2136
+ platformPublicationReason,
1890
2137
  platformRelease,
1891
2138
  podInstallInputStamp,
1892
2139
  replaceOrInsertPlistString
package/dist/cli.d.cts CHANGED
@@ -13,6 +13,9 @@ interface PublishOtaOptions {
13
13
  projectRoot: string;
14
14
  serviceUrl: string;
15
15
  }
16
+ interface PublishPlatformOptions extends PublishOtaOptions {
17
+ redeploy: boolean;
18
+ }
16
19
  interface ProjectConfig {
17
20
  name: string;
18
21
  version?: string;
@@ -23,11 +26,13 @@ interface ProjectConfig {
23
26
  appearance: BleamAppearance;
24
27
  runtimeVersion: string;
25
28
  sdkVersion: string;
29
+ iconPath?: string;
26
30
  }
27
31
  declare function parsePublishOtaOptions(argv: string[]): PublishOtaOptions;
32
+ declare function parsePublishPlatformOptions(argv: string[]): PublishPlatformOptions;
28
33
  declare function parseNewOptions(argv: string[]): {
29
34
  projectRoot: string;
30
- template: "basic" | "state" | "foundation-models" | "image-generation";
35
+ template: "state" | "basic" | "foundation-models" | "image-generation";
31
36
  };
32
37
  declare const projectTemplates: readonly ["basic", "state", "foundation-models", "image-generation"];
33
38
  type ProjectTemplate = (typeof projectTemplates)[number];
@@ -36,7 +41,15 @@ declare function createProject(options: {
36
41
  projectRoot: string;
37
42
  template?: ProjectTemplate;
38
43
  }): void;
44
+ declare function nativeRuntimeTemplateRoot(root?: string): string;
45
+ declare function localUpdateServiceRoot(root?: string): string;
46
+ declare function localUpdateServicePaths(home?: string): {
47
+ root: string;
48
+ state: string;
49
+ log: string;
50
+ };
39
51
  declare function replaceOrInsertPlistString(plist: string, key: string, value: string): string;
52
+ declare function platformInputFingerprint(config: ProjectConfig): string;
40
53
  declare function createBuildNativeWorkspace(options: BuildOptions, config: ProjectConfig): string;
41
54
  declare function podInstallInputStamp(iosRoot: string): string;
42
55
  declare function hasCurrentPodInstall(iosRoot: string, expectedStamp: string): boolean;
@@ -47,7 +60,16 @@ declare function nativeArchiveArgs(options: {
47
60
  }): string[];
48
61
  declare function installArchivedApp(archivePath: string, applications?: string): string;
49
62
  declare function installedAppPath(appName: string): string;
50
- declare function platformRelease(config: ProjectConfig, releaseId: string, sizeBytes: number, digest: string): {
63
+ interface ActivePlatformRelease {
64
+ bleamPlatformVersion: string;
65
+ platformFingerprint?: string;
66
+ }
67
+ type PlatformPublicationReason = 'first-release' | 'legacy-migration' | 'runtime-upgrade' | 'signed-input-change' | 'redeploy';
68
+ declare function platformPublicationReason(active: ActivePlatformRelease | undefined, target: {
69
+ bleamPlatformVersion: string;
70
+ platformFingerprint: string;
71
+ }, redeploy: boolean): PlatformPublicationReason;
72
+ declare function platformRelease(config: ProjectConfig, releaseId: string, sizeBytes: number, digest: string, redeploy?: boolean): {
51
73
  schemaVersion: number;
52
74
  kind: string;
53
75
  bundleIdentifier: string;
@@ -57,6 +79,8 @@ declare function platformRelease(config: ProjectConfig, releaseId: string, sizeB
57
79
  appVersion: string;
58
80
  buildNumber: string;
59
81
  bleamPlatformVersion: string;
82
+ platformFingerprint: string;
83
+ redeploy: boolean;
60
84
  target: {
61
85
  os: string;
62
86
  architecture: string;
@@ -77,10 +101,16 @@ declare const __test: {
77
101
  hasCurrentPodInstall: typeof hasCurrentPodInstall;
78
102
  installedAppPath: typeof installedAppPath;
79
103
  installArchivedApp: typeof installArchivedApp;
104
+ localUpdateServicePaths: typeof localUpdateServicePaths;
105
+ localUpdateServiceRoot: typeof localUpdateServiceRoot;
106
+ nativeRuntimeTemplateRoot: typeof nativeRuntimeTemplateRoot;
80
107
  nativeArchiveArgs: typeof nativeArchiveArgs;
81
108
  parseBuildOptions: typeof parseBuildOptions;
82
109
  parseNewOptions: typeof parseNewOptions;
83
110
  parsePublishOtaOptions: typeof parsePublishOtaOptions;
111
+ parsePublishPlatformOptions: typeof parsePublishPlatformOptions;
112
+ platformInputFingerprint: typeof platformInputFingerprint;
113
+ platformPublicationReason: typeof platformPublicationReason;
84
114
  platformRelease: typeof platformRelease;
85
115
  podInstallInputStamp: typeof podInstallInputStamp;
86
116
  replaceOrInsertPlistString: typeof replaceOrInsertPlistString;
package/dist/cli.d.ts CHANGED
@@ -13,6 +13,9 @@ interface PublishOtaOptions {
13
13
  projectRoot: string;
14
14
  serviceUrl: string;
15
15
  }
16
+ interface PublishPlatformOptions extends PublishOtaOptions {
17
+ redeploy: boolean;
18
+ }
16
19
  interface ProjectConfig {
17
20
  name: string;
18
21
  version?: string;
@@ -23,11 +26,13 @@ interface ProjectConfig {
23
26
  appearance: BleamAppearance;
24
27
  runtimeVersion: string;
25
28
  sdkVersion: string;
29
+ iconPath?: string;
26
30
  }
27
31
  declare function parsePublishOtaOptions(argv: string[]): PublishOtaOptions;
32
+ declare function parsePublishPlatformOptions(argv: string[]): PublishPlatformOptions;
28
33
  declare function parseNewOptions(argv: string[]): {
29
34
  projectRoot: string;
30
- template: "basic" | "state" | "foundation-models" | "image-generation";
35
+ template: "state" | "basic" | "foundation-models" | "image-generation";
31
36
  };
32
37
  declare const projectTemplates: readonly ["basic", "state", "foundation-models", "image-generation"];
33
38
  type ProjectTemplate = (typeof projectTemplates)[number];
@@ -36,7 +41,15 @@ declare function createProject(options: {
36
41
  projectRoot: string;
37
42
  template?: ProjectTemplate;
38
43
  }): void;
44
+ declare function nativeRuntimeTemplateRoot(root?: string): string;
45
+ declare function localUpdateServiceRoot(root?: string): string;
46
+ declare function localUpdateServicePaths(home?: string): {
47
+ root: string;
48
+ state: string;
49
+ log: string;
50
+ };
39
51
  declare function replaceOrInsertPlistString(plist: string, key: string, value: string): string;
52
+ declare function platformInputFingerprint(config: ProjectConfig): string;
40
53
  declare function createBuildNativeWorkspace(options: BuildOptions, config: ProjectConfig): string;
41
54
  declare function podInstallInputStamp(iosRoot: string): string;
42
55
  declare function hasCurrentPodInstall(iosRoot: string, expectedStamp: string): boolean;
@@ -47,7 +60,16 @@ declare function nativeArchiveArgs(options: {
47
60
  }): string[];
48
61
  declare function installArchivedApp(archivePath: string, applications?: string): string;
49
62
  declare function installedAppPath(appName: string): string;
50
- declare function platformRelease(config: ProjectConfig, releaseId: string, sizeBytes: number, digest: string): {
63
+ interface ActivePlatformRelease {
64
+ bleamPlatformVersion: string;
65
+ platformFingerprint?: string;
66
+ }
67
+ type PlatformPublicationReason = 'first-release' | 'legacy-migration' | 'runtime-upgrade' | 'signed-input-change' | 'redeploy';
68
+ declare function platformPublicationReason(active: ActivePlatformRelease | undefined, target: {
69
+ bleamPlatformVersion: string;
70
+ platformFingerprint: string;
71
+ }, redeploy: boolean): PlatformPublicationReason;
72
+ declare function platformRelease(config: ProjectConfig, releaseId: string, sizeBytes: number, digest: string, redeploy?: boolean): {
51
73
  schemaVersion: number;
52
74
  kind: string;
53
75
  bundleIdentifier: string;
@@ -57,6 +79,8 @@ declare function platformRelease(config: ProjectConfig, releaseId: string, sizeB
57
79
  appVersion: string;
58
80
  buildNumber: string;
59
81
  bleamPlatformVersion: string;
82
+ platformFingerprint: string;
83
+ redeploy: boolean;
60
84
  target: {
61
85
  os: string;
62
86
  architecture: string;
@@ -77,10 +101,16 @@ declare const __test: {
77
101
  hasCurrentPodInstall: typeof hasCurrentPodInstall;
78
102
  installedAppPath: typeof installedAppPath;
79
103
  installArchivedApp: typeof installArchivedApp;
104
+ localUpdateServicePaths: typeof localUpdateServicePaths;
105
+ localUpdateServiceRoot: typeof localUpdateServiceRoot;
106
+ nativeRuntimeTemplateRoot: typeof nativeRuntimeTemplateRoot;
80
107
  nativeArchiveArgs: typeof nativeArchiveArgs;
81
108
  parseBuildOptions: typeof parseBuildOptions;
82
109
  parseNewOptions: typeof parseNewOptions;
83
110
  parsePublishOtaOptions: typeof parsePublishOtaOptions;
111
+ parsePublishPlatformOptions: typeof parsePublishPlatformOptions;
112
+ platformInputFingerprint: typeof platformInputFingerprint;
113
+ platformPublicationReason: typeof platformPublicationReason;
84
114
  platformRelease: typeof platformRelease;
85
115
  podInstallInputStamp: typeof podInstallInputStamp;
86
116
  replaceOrInsertPlistString: typeof replaceOrInsertPlistString;