@tamer4lynx/cli 0.0.2 → 0.0.3

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 (2) hide show
  1. package/dist/index.js +203 -234
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7,12 +7,12 @@ process.on("warning", (w) => {
7
7
  });
8
8
 
9
9
  // index.ts
10
- import fs25 from "fs";
10
+ import fs24 from "fs";
11
11
  import path25 from "path";
12
12
  import { program } from "commander";
13
13
 
14
14
  // package.json
15
- var version = "0.0.2";
15
+ var version = "0.0.3";
16
16
 
17
17
  // src/android/create.ts
18
18
  import fs3 from "fs";
@@ -213,6 +213,7 @@ function findRepoRoot(start2) {
213
213
  }
214
214
  function findDevAppPackage(projectRoot) {
215
215
  const candidates = [
216
+ path2.join(projectRoot, "node_modules", "@tamer4lynx", "tamer-dev-app"),
216
217
  path2.join(projectRoot, "node_modules", "tamer-dev-app"),
217
218
  path2.join(projectRoot, "packages", "tamer-dev-app"),
218
219
  path2.join(path2.dirname(projectRoot), "tamer-dev-app")
@@ -226,6 +227,7 @@ function findDevAppPackage(projectRoot) {
226
227
  }
227
228
  function findDevClientPackage(projectRoot) {
228
229
  const candidates = [
230
+ path2.join(projectRoot, "node_modules", "@tamer4lynx", "tamer-dev-client"),
229
231
  path2.join(projectRoot, "node_modules", "tamer-dev-client"),
230
232
  path2.join(projectRoot, "packages", "tamer-dev-client"),
231
233
  path2.join(path2.dirname(projectRoot), "tamer-dev-client")
@@ -321,17 +323,25 @@ function resolveIconPaths(projectRoot, config) {
321
323
  }
322
324
  return Object.keys(out).length ? out : null;
323
325
  }
324
- function resolveDevAppPaths(repoRoot) {
325
- const devAppDir = path2.join(repoRoot, "packages", "tamer-dev-app");
326
+ function resolveDevAppPaths(searchRoot) {
327
+ const devAppDir = findDevAppPackage(searchRoot) ?? findDevAppPackage(findRepoRoot(searchRoot));
328
+ if (!devAppDir) {
329
+ throw new Error("tamer-dev-app not found. Add @tamer4lynx/tamer-dev-app to dependencies, or run from the tamer4lynx monorepo.");
330
+ }
326
331
  const configPath = path2.join(devAppDir, "tamer.config.json");
327
332
  if (!fs2.existsSync(configPath)) {
328
- throw new Error("packages/tamer-dev-app/tamer.config.json not found.");
333
+ throw new Error(`tamer.config.json not found in ${devAppDir}`);
329
334
  }
330
335
  const config = JSON.parse(fs2.readFileSync(configPath, "utf8"));
331
336
  const packageName = config.android?.packageName ?? "com.nanofuxion.tamerdevapp";
332
337
  const androidDirRel = config.paths?.androidDir ?? "android";
333
338
  const androidDir = path2.join(devAppDir, androidDirRel);
334
- const devClientDir = findDevClientPackage(repoRoot) ?? path2.join(repoRoot, "packages", "tamer-dev-client");
339
+ const inDevAppScoped = path2.join(devAppDir, "node_modules", "@tamer4lynx", "tamer-dev-client");
340
+ const inDevAppFlat = path2.join(devAppDir, "node_modules", "tamer-dev-client");
341
+ const devClientDir = findDevClientPackage(searchRoot) ?? findDevClientPackage(findRepoRoot(searchRoot)) ?? (fs2.existsSync(path2.join(inDevAppScoped, "package.json")) ? inDevAppScoped : null) ?? (fs2.existsSync(path2.join(inDevAppFlat, "package.json")) ? inDevAppFlat : null);
342
+ if (!devClientDir || !fs2.existsSync(devClientDir)) {
343
+ throw new Error("tamer-dev-client not found. Add @tamer4lynx/tamer-dev-client (or tamer-dev-app pulls it in).");
344
+ }
335
345
  const lynxBundlePath = path2.join(devClientDir, DEFAULT_BUNDLE_ROOT, "dev-client.lynx.bundle");
336
346
  return {
337
347
  projectRoot: devAppDir,
@@ -919,30 +929,13 @@ function readAndSubstituteTemplate(templatePath, vars) {
919
929
  raw
920
930
  );
921
931
  }
922
- function findRepoRoot2(start2) {
923
- let dir = path3.resolve(start2);
924
- const root = path3.parse(dir).root;
925
- while (dir !== root) {
926
- const pkgPath = path3.join(dir, "package.json");
927
- if (fs3.existsSync(pkgPath)) {
928
- try {
929
- const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf8"));
930
- if (pkg.workspaces) return dir;
931
- } catch {
932
- }
933
- }
934
- dir = path3.dirname(dir);
935
- }
936
- return start2;
937
- }
938
932
  var create = async (opts = {}) => {
939
933
  const target = opts.target ?? "host";
940
934
  const origCwd = process.cwd();
941
935
  if (target === "dev-app") {
942
- const repoRoot = findRepoRoot2(origCwd);
943
- const devAppDir = path3.join(repoRoot, "packages", "tamer-dev-app");
944
- if (!fs3.existsSync(path3.join(devAppDir, "tamer.config.json"))) {
945
- console.error("\u274C packages/tamer-dev-app/tamer.config.json not found.");
936
+ const devAppDir = findDevAppPackage(origCwd) ?? findDevAppPackage(findRepoRoot(origCwd));
937
+ if (!devAppDir || !fs3.existsSync(path3.join(devAppDir, "tamer.config.json"))) {
938
+ console.error("\u274C tamer-dev-app not found. Add @tamer4lynx/tamer-dev-app to dependencies.");
946
939
  process.exit(1);
947
940
  }
948
941
  process.chdir(devAppDir);
@@ -2093,22 +2086,6 @@ $1$2`);
2093
2086
  var syncDevClient_default = syncDevClient;
2094
2087
 
2095
2088
  // src/android/bundle.ts
2096
- function findRepoRoot3(start2) {
2097
- let dir = path9.resolve(start2);
2098
- const root = path9.parse(dir).root;
2099
- while (dir !== root) {
2100
- const pkgPath = path9.join(dir, "package.json");
2101
- if (fs9.existsSync(pkgPath)) {
2102
- try {
2103
- const pkg = JSON.parse(fs9.readFileSync(pkgPath, "utf8"));
2104
- if (pkg.workspaces) return dir;
2105
- } catch {
2106
- }
2107
- }
2108
- dir = path9.dirname(dir);
2109
- }
2110
- return start2;
2111
- }
2112
2089
  async function bundleAndDeploy(opts = {}) {
2113
2090
  const target = opts.target ?? "host";
2114
2091
  const release = opts.release === true;
@@ -2116,8 +2093,7 @@ async function bundleAndDeploy(opts = {}) {
2116
2093
  let resolved;
2117
2094
  try {
2118
2095
  if (target === "dev-app") {
2119
- const repoRoot = findRepoRoot3(origCwd);
2120
- resolved = resolveDevAppPaths(repoRoot);
2096
+ resolved = resolveDevAppPaths(origCwd);
2121
2097
  const devAppDir = resolved.projectRoot;
2122
2098
  const androidDir = resolved.androidDir;
2123
2099
  if (!fs9.existsSync(androidDir)) {
@@ -2189,28 +2165,22 @@ async function bundleAndDeploy(opts = {}) {
2189
2165
  var bundle_default = bundleAndDeploy;
2190
2166
 
2191
2167
  // src/android/build.ts
2192
- import fs10 from "fs";
2193
2168
  import path10 from "path";
2194
2169
  import { execSync as execSync3 } from "child_process";
2195
- function findRepoRoot4(start2) {
2196
- let dir = path10.resolve(start2);
2197
- const root = path10.parse(dir).root;
2198
- while (dir !== root) {
2199
- const pkgPath = path10.join(dir, "package.json");
2200
- if (fs10.existsSync(pkgPath)) {
2201
- try {
2202
- const pkg = JSON.parse(fs10.readFileSync(pkgPath, "utf8"));
2203
- if (pkg.workspaces) return dir;
2204
- } catch {
2205
- }
2206
- }
2207
- dir = path10.dirname(dir);
2208
- }
2209
- return start2;
2210
- }
2211
2170
  async function buildApk(opts = {}) {
2212
2171
  const target = opts.target ?? "host";
2213
- const resolved = target === "dev-app" ? resolveDevAppPaths(findRepoRoot4(process.cwd())) : resolveHostPaths();
2172
+ let resolved;
2173
+ try {
2174
+ resolved = target === "dev-app" ? resolveDevAppPaths(process.cwd()) : resolveHostPaths();
2175
+ } catch (error) {
2176
+ const msg = error instanceof Error ? error.message : String(error);
2177
+ if (target === "dev-app") {
2178
+ console.error(`\u274C ${msg}`);
2179
+ console.error(" Add @tamer4lynx/tamer-dev-app to dependencies, or use -t host to build your app.");
2180
+ process.exit(1);
2181
+ }
2182
+ throw error;
2183
+ }
2214
2184
  await bundle_default({ target, release: opts.release });
2215
2185
  const androidDir = resolved.androidDir;
2216
2186
  const gradlew = path10.join(androidDir, process.platform === "win32" ? "gradlew.bat" : "gradlew");
@@ -2238,12 +2208,12 @@ async function buildApk(opts = {}) {
2238
2208
  var build_default = buildApk;
2239
2209
 
2240
2210
  // src/ios/create.ts
2241
- import fs12 from "fs";
2211
+ import fs11 from "fs";
2242
2212
  import path12 from "path";
2243
2213
 
2244
2214
  // src/ios/getPod.ts
2245
2215
  import { execSync as execSync4 } from "child_process";
2246
- import fs11 from "fs";
2216
+ import fs10 from "fs";
2247
2217
  import path11 from "path";
2248
2218
  function isCocoaPodsInstalled() {
2249
2219
  try {
@@ -2267,7 +2237,7 @@ async function setupCocoaPods(rootDir) {
2267
2237
  try {
2268
2238
  console.log("\u{1F4E6} CocoaPods is installed. Proceeding with dependency installation...");
2269
2239
  const podfilePath = path11.join(rootDir, "Podfile");
2270
- if (!fs11.existsSync(podfilePath)) {
2240
+ if (!fs10.existsSync(podfilePath)) {
2271
2241
  throw new Error(`Podfile not found at ${podfilePath}`);
2272
2242
  }
2273
2243
  console.log(`\u{1F680} Executing pod install in: ${rootDir}`);
@@ -2285,7 +2255,7 @@ async function setupCocoaPods(rootDir) {
2285
2255
  // src/ios/create.ts
2286
2256
  import { randomBytes } from "crypto";
2287
2257
  function readAndSubstituteTemplate3(templatePath, vars) {
2288
- const raw = fs12.readFileSync(templatePath, "utf-8");
2258
+ const raw = fs11.readFileSync(templatePath, "utf-8");
2289
2259
  return Object.entries(vars).reduce(
2290
2260
  (s, [k, v]) => s.replace(new RegExp(`\\{\\{${k}\\}\\}`, "g"), v),
2291
2261
  raw
@@ -2313,12 +2283,12 @@ var create2 = () => {
2313
2283
  const xcodeprojDir = path12.join(rootDir, `${appName}.xcodeproj`);
2314
2284
  const bridgingHeader = `${appName}-Bridging-Header.h`;
2315
2285
  function writeFile3(filePath, content) {
2316
- fs12.mkdirSync(path12.dirname(filePath), { recursive: true });
2317
- fs12.writeFileSync(filePath, content.trimStart(), "utf8");
2286
+ fs11.mkdirSync(path12.dirname(filePath), { recursive: true });
2287
+ fs11.writeFileSync(filePath, content.trimStart(), "utf8");
2318
2288
  }
2319
- if (fs12.existsSync(rootDir)) {
2289
+ if (fs11.existsSync(rootDir)) {
2320
2290
  console.log(`\u{1F9F9} Removing existing directory: ${rootDir}`);
2321
- fs12.rmSync(rootDir, { recursive: true, force: true });
2291
+ fs11.rmSync(rootDir, { recursive: true, force: true });
2322
2292
  }
2323
2293
  console.log(`\u{1F680} Creating a new Tamer4Lynx project in: ${rootDir}`);
2324
2294
  const ids = {
@@ -2417,7 +2387,7 @@ end
2417
2387
  const templateDir = path12.join(hostPkg, "ios", "templates");
2418
2388
  for (const f of ["AppDelegate.swift", "SceneDelegate.swift", "ViewController.swift", "LynxProvider.swift", "LynxInitProcessor.swift"]) {
2419
2389
  const srcPath = path12.join(templateDir, f);
2420
- if (fs12.existsSync(srcPath)) {
2390
+ if (fs11.existsSync(srcPath)) {
2421
2391
  writeFile3(path12.join(projectDir, f), readAndSubstituteTemplate3(srcPath, templateVars));
2422
2392
  }
2423
2393
  }
@@ -2648,23 +2618,23 @@ final class LynxInitProcessor {
2648
2618
  </plist>
2649
2619
  `);
2650
2620
  const appIconDir = path12.join(projectDir, "Assets.xcassets", "AppIcon.appiconset");
2651
- fs12.mkdirSync(appIconDir, { recursive: true });
2621
+ fs11.mkdirSync(appIconDir, { recursive: true });
2652
2622
  const iconPaths = resolveIconPaths(process.cwd(), config);
2653
2623
  if (iconPaths?.ios) {
2654
- const entries = fs12.readdirSync(iconPaths.ios, { withFileTypes: true });
2624
+ const entries = fs11.readdirSync(iconPaths.ios, { withFileTypes: true });
2655
2625
  for (const e of entries) {
2656
2626
  const dest = path12.join(appIconDir, e.name);
2657
2627
  if (e.isDirectory()) {
2658
- fs12.cpSync(path12.join(iconPaths.ios, e.name), dest, { recursive: true });
2628
+ fs11.cpSync(path12.join(iconPaths.ios, e.name), dest, { recursive: true });
2659
2629
  } else {
2660
- fs12.copyFileSync(path12.join(iconPaths.ios, e.name), dest);
2630
+ fs11.copyFileSync(path12.join(iconPaths.ios, e.name), dest);
2661
2631
  }
2662
2632
  }
2663
2633
  console.log("\u2705 Copied iOS icon from tamer.config.json icon.ios");
2664
2634
  } else if (iconPaths?.source) {
2665
2635
  const ext = path12.extname(iconPaths.source) || ".png";
2666
2636
  const icon1024 = `Icon-1024${ext}`;
2667
- fs12.copyFileSync(iconPaths.source, path12.join(appIconDir, icon1024));
2637
+ fs11.copyFileSync(iconPaths.source, path12.join(appIconDir, icon1024));
2668
2638
  writeFile3(path12.join(appIconDir, "Contents.json"), JSON.stringify({
2669
2639
  images: [{ filename: icon1024, idiom: "universal", platform: "ios", size: "1024x1024" }],
2670
2640
  info: { author: "xcode", version: 1 }
@@ -2678,7 +2648,7 @@ final class LynxInitProcessor {
2678
2648
  }
2679
2649
  `);
2680
2650
  }
2681
- fs12.mkdirSync(xcodeprojDir, { recursive: true });
2651
+ fs11.mkdirSync(xcodeprojDir, { recursive: true });
2682
2652
  writeFile3(path12.join(xcodeprojDir, "project.pbxproj"), `
2683
2653
  // !$*UTF8*$!
2684
2654
  {
@@ -2965,7 +2935,7 @@ final class LynxInitProcessor {
2965
2935
  var create_default2 = create2;
2966
2936
 
2967
2937
  // src/ios/autolink.ts
2968
- import fs13 from "fs";
2938
+ import fs12 from "fs";
2969
2939
  import path13 from "path";
2970
2940
  import { execSync as execSync5 } from "child_process";
2971
2941
  var autolink2 = () => {
@@ -2979,11 +2949,11 @@ var autolink2 = () => {
2979
2949
  const projectRoot = resolved.projectRoot;
2980
2950
  const iosProjectPath = resolved.iosDir;
2981
2951
  function updateGeneratedSection(filePath, newContent, startMarker, endMarker) {
2982
- if (!fs13.existsSync(filePath)) {
2952
+ if (!fs12.existsSync(filePath)) {
2983
2953
  console.warn(`\u26A0\uFE0F File not found, skipping update: ${filePath}`);
2984
2954
  return;
2985
2955
  }
2986
- let fileContent = fs13.readFileSync(filePath, "utf8");
2956
+ let fileContent = fs12.readFileSync(filePath, "utf8");
2987
2957
  const escapedStartMarker = startMarker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2988
2958
  const escapedEndMarker = endMarker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2989
2959
  const regex = new RegExp(`${escapedStartMarker}[\\s\\S]*?${escapedEndMarker}`, "g");
@@ -3008,15 +2978,15 @@ ${replacementBlock}
3008
2978
  ${replacementBlock}
3009
2979
  `;
3010
2980
  }
3011
- fs13.writeFileSync(filePath, fileContent, "utf8");
2981
+ fs12.writeFileSync(filePath, fileContent, "utf8");
3012
2982
  console.log(`\u2705 Updated autolinked section in ${path13.basename(filePath)}`);
3013
2983
  }
3014
2984
  function resolvePodName(pkg) {
3015
2985
  const podspecDir = pkg.config.ios?.podspecPath || ".";
3016
2986
  const fullPodspecDir = path13.join(pkg.packagePath, podspecDir);
3017
- if (fs13.existsSync(fullPodspecDir)) {
2987
+ if (fs12.existsSync(fullPodspecDir)) {
3018
2988
  try {
3019
- const files = fs13.readdirSync(fullPodspecDir);
2989
+ const files = fs12.readdirSync(fullPodspecDir);
3020
2990
  const podspecFile = files.find((f) => f.endsWith(".podspec"));
3021
2991
  if (podspecFile) return podspecFile.replace(".podspec", "");
3022
2992
  } catch {
@@ -3050,7 +3020,7 @@ ${replacementBlock}
3050
3020
  candidatePaths.push(path13.join(iosProjectPath, appNameFromConfig, "LynxInitProcessor.swift"));
3051
3021
  }
3052
3022
  candidatePaths.push(path13.join(iosProjectPath, "LynxInitProcessor.swift"));
3053
- const found = candidatePaths.find((p) => fs13.existsSync(p));
3023
+ const found = candidatePaths.find((p) => fs12.existsSync(p));
3054
3024
  const lynxInitPath = found ?? candidatePaths[0];
3055
3025
  const iosPackages = packages.filter((p) => getIosModuleClassNames(p.config.ios).length > 0 || Object.keys(getIosElements(p.config.ios)).length > 0);
3056
3026
  function updateImportsSection(filePath, pkgs) {
@@ -3065,7 +3035,7 @@ ${replacementBlock}
3065
3035
  const podName = resolvePodName(pkg);
3066
3036
  return `import ${podName}`;
3067
3037
  }).join("\n");
3068
- const fileContent = fs13.readFileSync(filePath, "utf8");
3038
+ const fileContent = fs12.readFileSync(filePath, "utf8");
3069
3039
  if (fileContent.indexOf(startMarker) !== -1) {
3070
3040
  updateGeneratedSection(filePath, imports, startMarker, endMarker);
3071
3041
  return;
@@ -3102,7 +3072,7 @@ ${after}`;
3102
3072
  ${fileContent}`;
3103
3073
  }
3104
3074
  }
3105
- fs13.writeFileSync(filePath, newContent, "utf8");
3075
+ fs12.writeFileSync(filePath, newContent, "utf8");
3106
3076
  console.log(`\u2705 Updated imports in ${path13.basename(filePath)}`);
3107
3077
  }
3108
3078
  updateImportsSection(lynxInitPath, iosPackages);
@@ -3133,10 +3103,10 @@ ${fileContent}`;
3133
3103
  candidates.push(path13.join(iosProjectPath, appNameFromConfig, "Info.plist"));
3134
3104
  }
3135
3105
  candidates.push(path13.join(iosProjectPath, "Info.plist"));
3136
- return candidates.find((p) => fs13.existsSync(p)) ?? null;
3106
+ return candidates.find((p) => fs12.existsSync(p)) ?? null;
3137
3107
  }
3138
3108
  function readPlistXml(plistPath) {
3139
- return fs13.readFileSync(plistPath, "utf8");
3109
+ return fs12.readFileSync(plistPath, "utf8");
3140
3110
  }
3141
3111
  function syncInfoPlistPermissions(packages) {
3142
3112
  const plistPath = findInfoPlist();
@@ -3167,7 +3137,7 @@ ${fileContent}`;
3167
3137
  added++;
3168
3138
  }
3169
3139
  if (added > 0) {
3170
- fs13.writeFileSync(plistPath, plist, "utf8");
3140
+ fs12.writeFileSync(plistPath, plist, "utf8");
3171
3141
  console.log(`\u2705 Synced ${added} Info.plist permission description(s)`);
3172
3142
  }
3173
3143
  }
@@ -3214,12 +3184,12 @@ ${schemesXml}
3214
3184
  $1`
3215
3185
  );
3216
3186
  }
3217
- fs13.writeFileSync(plistPath, plist, "utf8");
3187
+ fs12.writeFileSync(plistPath, plist, "utf8");
3218
3188
  console.log(`\u2705 Synced ${urlSchemes.length} iOS URL scheme(s) into Info.plist`);
3219
3189
  }
3220
3190
  function runPodInstall(forcePath) {
3221
3191
  const podfilePath = forcePath ?? path13.join(iosProjectPath, "Podfile");
3222
- if (!fs13.existsSync(podfilePath)) {
3192
+ if (!fs12.existsSync(podfilePath)) {
3223
3193
  console.log("\u2139\uFE0F No Podfile found in ios directory; skipping `pod install`.");
3224
3194
  return;
3225
3195
  }
@@ -3248,7 +3218,7 @@ $1`
3248
3218
  const appNameFromConfig = resolved.config.ios?.appName;
3249
3219
  if (appNameFromConfig) {
3250
3220
  const appPodfile = path13.join(iosProjectPath, appNameFromConfig, "Podfile");
3251
- if (fs13.existsSync(appPodfile)) {
3221
+ if (fs12.existsSync(appPodfile)) {
3252
3222
  runPodInstall(appPodfile);
3253
3223
  console.log("\u2728 Autolinking complete for iOS.");
3254
3224
  return;
@@ -3262,12 +3232,12 @@ $1`
3262
3232
  var autolink_default2 = autolink2;
3263
3233
 
3264
3234
  // src/ios/bundle.ts
3265
- import fs15 from "fs";
3235
+ import fs14 from "fs";
3266
3236
  import path15 from "path";
3267
3237
  import { execSync as execSync6 } from "child_process";
3268
3238
 
3269
3239
  // src/ios/syncHost.ts
3270
- import fs14 from "fs";
3240
+ import fs13 from "fs";
3271
3241
  import path14 from "path";
3272
3242
  import crypto from "crypto";
3273
3243
  function deterministicUUID(seed) {
@@ -3316,7 +3286,7 @@ function getLaunchScreenStoryboard() {
3316
3286
  `;
3317
3287
  }
3318
3288
  function addLaunchScreenToXcodeProject(pbxprojPath, appName) {
3319
- let content = fs14.readFileSync(pbxprojPath, "utf8");
3289
+ let content = fs13.readFileSync(pbxprojPath, "utf8");
3320
3290
  if (content.includes("LaunchScreen.storyboard")) return;
3321
3291
  const baseFileRefUUID = deterministicUUID(`launchScreenBase:${appName}`);
3322
3292
  const variantGroupUUID = deterministicUUID(`launchScreenGroup:${appName}`);
@@ -3353,11 +3323,11 @@ function addLaunchScreenToXcodeProject(pbxprojPath, appName) {
3353
3323
  );
3354
3324
  content = content.replace(groupPattern, `$1
3355
3325
  ${variantGroupUUID} /* LaunchScreen.storyboard */,`);
3356
- fs14.writeFileSync(pbxprojPath, content, "utf8");
3326
+ fs13.writeFileSync(pbxprojPath, content, "utf8");
3357
3327
  console.log("\u2705 Registered LaunchScreen.storyboard in Xcode project");
3358
3328
  }
3359
3329
  function addSwiftSourceToXcodeProject(pbxprojPath, appName, filename) {
3360
- let content = fs14.readFileSync(pbxprojPath, "utf8");
3330
+ let content = fs13.readFileSync(pbxprojPath, "utf8");
3361
3331
  const escaped = filename.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3362
3332
  if (new RegExp(`path = ${escaped};`).test(content)) return;
3363
3333
  const fileRefUUID = deterministicUUID(`fileRef:${appName}:${filename}`);
@@ -3382,11 +3352,11 @@ function addSwiftSourceToXcodeProject(pbxprojPath, appName, filename) {
3382
3352
  );
3383
3353
  content = content.replace(groupPattern, `$1
3384
3354
  ${fileRefUUID} /* ${filename} */,`);
3385
- fs14.writeFileSync(pbxprojPath, content, "utf8");
3355
+ fs13.writeFileSync(pbxprojPath, content, "utf8");
3386
3356
  console.log(`\u2705 Registered ${filename} in Xcode project sources`);
3387
3357
  }
3388
3358
  function addResourceToXcodeProject(pbxprojPath, appName, filename) {
3389
- let content = fs14.readFileSync(pbxprojPath, "utf8");
3359
+ let content = fs13.readFileSync(pbxprojPath, "utf8");
3390
3360
  const escaped = filename.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3391
3361
  if (new RegExp(`path = ${escaped};`).test(content)) return;
3392
3362
  const fileRefUUID = deterministicUUID(`fileRef:${appName}:${filename}`);
@@ -3411,12 +3381,12 @@ function addResourceToXcodeProject(pbxprojPath, appName, filename) {
3411
3381
  );
3412
3382
  content = content.replace(groupPattern, `$1
3413
3383
  ${fileRefUUID} /* ${filename} */,`);
3414
- fs14.writeFileSync(pbxprojPath, content, "utf8");
3384
+ fs13.writeFileSync(pbxprojPath, content, "utf8");
3415
3385
  console.log(`\u2705 Registered ${filename} in Xcode project resources`);
3416
3386
  }
3417
3387
  function writeFile(filePath, content) {
3418
- fs14.mkdirSync(path14.dirname(filePath), { recursive: true });
3419
- fs14.writeFileSync(filePath, content, "utf8");
3388
+ fs13.mkdirSync(path14.dirname(filePath), { recursive: true });
3389
+ fs13.writeFileSync(filePath, content, "utf8");
3420
3390
  }
3421
3391
  function getAppDelegateSwift() {
3422
3392
  return `import UIKit
@@ -3626,8 +3596,8 @@ class ViewController: UIViewController {
3626
3596
  `;
3627
3597
  }
3628
3598
  function patchInfoPlist(infoPlistPath) {
3629
- if (!fs14.existsSync(infoPlistPath)) return;
3630
- let content = fs14.readFileSync(infoPlistPath, "utf8");
3599
+ if (!fs13.existsSync(infoPlistPath)) return;
3600
+ let content = fs13.readFileSync(infoPlistPath, "utf8");
3631
3601
  content = content.replace(/\s*<key>UIMainStoryboardFile<\/key>\s*<string>[^<]*<\/string>/g, "");
3632
3602
  if (!content.includes("UILaunchStoryboardName")) {
3633
3603
  content = content.replace("</dict>\n</plist>", ` <key>UILaunchStoryboardName</key>
@@ -3659,7 +3629,7 @@ function patchInfoPlist(infoPlistPath) {
3659
3629
  </plist>`);
3660
3630
  console.log("\u2705 Added UIApplicationSceneManifest to Info.plist");
3661
3631
  }
3662
- fs14.writeFileSync(infoPlistPath, content, "utf8");
3632
+ fs13.writeFileSync(infoPlistPath, content, "utf8");
3663
3633
  }
3664
3634
  function getSimpleLynxProviderSwift() {
3665
3635
  return `import Foundation
@@ -3685,8 +3655,8 @@ class LynxProvider: NSObject, LynxTemplateProvider {
3685
3655
  function readTemplateOrFallback(devClientPkg, templateName, fallback, vars = {}) {
3686
3656
  if (devClientPkg) {
3687
3657
  const tplPath = path14.join(devClientPkg, "ios", "templates", templateName);
3688
- if (fs14.existsSync(tplPath)) {
3689
- let content = fs14.readFileSync(tplPath, "utf8");
3658
+ if (fs13.existsSync(tplPath)) {
3659
+ let content = fs13.readFileSync(tplPath, "utf8");
3690
3660
  for (const [k, v] of Object.entries(vars)) {
3691
3661
  content = content.replace(new RegExp(`\\{\\{${k}\\}\\}`, "g"), v);
3692
3662
  }
@@ -3706,7 +3676,7 @@ function syncHostIos(opts) {
3706
3676
  }
3707
3677
  const projectDir = path14.join(resolved.iosDir, appName);
3708
3678
  const infoPlistPath = path14.join(projectDir, "Info.plist");
3709
- if (!fs14.existsSync(projectDir)) {
3679
+ if (!fs13.existsSync(projectDir)) {
3710
3680
  throw new Error(`iOS project not found at ${projectDir}. Run \`tamer ios create\` first.`);
3711
3681
  }
3712
3682
  const pbxprojPath = path14.join(resolved.iosDir, `${appName}.xcodeproj`, "project.pbxproj");
@@ -3715,8 +3685,8 @@ function syncHostIos(opts) {
3715
3685
  patchInfoPlist(infoPlistPath);
3716
3686
  writeFile(path14.join(projectDir, "AppDelegate.swift"), getAppDelegateSwift());
3717
3687
  writeFile(path14.join(projectDir, "SceneDelegate.swift"), getSceneDelegateSwift());
3718
- if (!fs14.existsSync(launchScreenPath)) {
3719
- fs14.mkdirSync(baseLprojDir, { recursive: true });
3688
+ if (!fs13.existsSync(launchScreenPath)) {
3689
+ fs13.mkdirSync(baseLprojDir, { recursive: true });
3720
3690
  writeFile(launchScreenPath, getLaunchScreenStoryboard());
3721
3691
  addLaunchScreenToXcodeProject(pbxprojPath, appName);
3722
3692
  }
@@ -3792,11 +3762,11 @@ function bundleAndDeploy2(opts = {}) {
3792
3762
  process.exit(1);
3793
3763
  }
3794
3764
  try {
3795
- if (!fs15.existsSync(sourceBundlePath)) {
3765
+ if (!fs14.existsSync(sourceBundlePath)) {
3796
3766
  console.error(`\u274C Build output not found at: ${sourceBundlePath}`);
3797
3767
  process.exit(1);
3798
3768
  }
3799
- if (!fs15.existsSync(destinationDir)) {
3769
+ if (!fs14.existsSync(destinationDir)) {
3800
3770
  console.error(`Destination directory not found at: ${destinationDir}`);
3801
3771
  process.exit(1);
3802
3772
  }
@@ -3805,10 +3775,10 @@ function bundleAndDeploy2(opts = {}) {
3805
3775
  copyDistAssets(distDir, destinationDir, resolved.lynxBundleFile);
3806
3776
  console.log(`\u2728 Successfully copied bundle to: ${destinationBundlePath}`);
3807
3777
  const pbxprojPath = path15.join(resolved.iosDir, `${appName}.xcodeproj`, "project.pbxproj");
3808
- if (fs15.existsSync(pbxprojPath)) {
3778
+ if (fs14.existsSync(pbxprojPath)) {
3809
3779
  const skip = /* @__PURE__ */ new Set([".rspeedy", "stats.json"]);
3810
- for (const entry of fs15.readdirSync(distDir)) {
3811
- if (skip.has(entry) || fs15.statSync(path15.join(distDir, entry)).isDirectory()) continue;
3780
+ for (const entry of fs14.readdirSync(distDir)) {
3781
+ if (skip.has(entry) || fs14.statSync(path15.join(distDir, entry)).isDirectory()) continue;
3812
3782
  addResourceToXcodeProject(pbxprojPath, appName, entry);
3813
3783
  }
3814
3784
  }
@@ -3824,18 +3794,18 @@ function bundleAndDeploy2(opts = {}) {
3824
3794
  console.warn("\u26A0\uFE0F dev-client build failed; skipping dev-client bundle");
3825
3795
  }
3826
3796
  const builtBundle = path15.join(devClientPkg, "dist", "dev-client.lynx.bundle");
3827
- if (fs15.existsSync(builtBundle)) {
3828
- fs15.copyFileSync(builtBundle, devClientBundle);
3797
+ if (fs14.existsSync(builtBundle)) {
3798
+ fs14.copyFileSync(builtBundle, devClientBundle);
3829
3799
  console.log("\u2728 Copied dev-client.lynx.bundle to iOS project");
3830
3800
  const pbxprojPath2 = path15.join(resolved.iosDir, `${appName}.xcodeproj`, "project.pbxproj");
3831
- if (fs15.existsSync(pbxprojPath2)) {
3801
+ if (fs14.existsSync(pbxprojPath2)) {
3832
3802
  addResourceToXcodeProject(pbxprojPath2, appName, "dev-client.lynx.bundle");
3833
3803
  }
3834
3804
  }
3835
3805
  }
3836
3806
  } else {
3837
- if (!fs15.existsSync(devClientBundle)) {
3838
- fs15.writeFileSync(devClientBundle, "");
3807
+ if (!fs14.existsSync(devClientBundle)) {
3808
+ fs14.writeFileSync(devClientBundle, "");
3839
3809
  }
3840
3810
  console.log("\u2139\uFE0F Skipped dev-client bundle (release build)");
3841
3811
  }
@@ -3849,17 +3819,17 @@ function bundleAndDeploy2(opts = {}) {
3849
3819
  var bundle_default2 = bundleAndDeploy2;
3850
3820
 
3851
3821
  // src/ios/build.ts
3852
- import fs17 from "fs";
3822
+ import fs16 from "fs";
3853
3823
  import path17 from "path";
3854
3824
  import { execSync as execSync8 } from "child_process";
3855
3825
 
3856
3826
  // src/ios/syncDevClient.ts
3857
- import fs16 from "fs";
3827
+ import fs15 from "fs";
3858
3828
  import path16 from "path";
3859
3829
  import { execSync as execSync7 } from "child_process";
3860
3830
  import { randomBytes as randomBytes2 } from "crypto";
3861
3831
  function readAndSubstituteTemplate4(templatePath, vars) {
3862
- const raw = fs16.readFileSync(templatePath, "utf-8");
3832
+ const raw = fs15.readFileSync(templatePath, "utf-8");
3863
3833
  return Object.entries(vars).reduce(
3864
3834
  (s, [k, v]) => s.replace(new RegExp(`\\{\\{${k}\\}\\}`, "g"), v),
3865
3835
  raw
@@ -3872,8 +3842,8 @@ function generateId() {
3872
3842
  return randomBytes2(12).toString("hex").toUpperCase();
3873
3843
  }
3874
3844
  function writeFile2(filePath, content) {
3875
- fs16.mkdirSync(path16.dirname(filePath), { recursive: true });
3876
- fs16.writeFileSync(filePath, content, "utf8");
3845
+ fs15.mkdirSync(path16.dirname(filePath), { recursive: true });
3846
+ fs15.writeFileSync(filePath, content, "utf8");
3877
3847
  }
3878
3848
  function getAppDelegateSwift2() {
3879
3849
  return `import UIKit
@@ -4886,8 +4856,8 @@ function generatePbxproj(ids) {
4886
4856
  async function createDevAppProject(iosDir, repoRoot) {
4887
4857
  const projectDir = path16.join(iosDir, APP_NAME);
4888
4858
  const xcodeprojDir = path16.join(iosDir, `${APP_NAME}.xcodeproj`);
4889
- if (fs16.existsSync(iosDir)) {
4890
- fs16.rmSync(iosDir, { recursive: true, force: true });
4859
+ if (fs15.existsSync(iosDir)) {
4860
+ fs15.rmSync(iosDir, { recursive: true, force: true });
4891
4861
  }
4892
4862
  console.log(`\u{1F680} Creating TamerDevApp iOS project at: ${iosDir}`);
4893
4863
  const ids = {};
@@ -4953,7 +4923,7 @@ async function createDevAppProject(iosDir, repoRoot) {
4953
4923
  ];
4954
4924
  for (const f of templateFiles) {
4955
4925
  const src = templateDir ? path16.join(templateDir, f) : null;
4956
- if (src && fs16.existsSync(src)) {
4926
+ if (src && fs15.existsSync(src)) {
4957
4927
  writeFile2(path16.join(projectDir, f), readAndSubstituteTemplate4(src, templateVars));
4958
4928
  } else {
4959
4929
  const fallback = (() => {
@@ -4990,7 +4960,7 @@ async function createDevAppProject(iosDir, repoRoot) {
4990
4960
  JSON.stringify({ info: { author: "xcode", version: 1 } }, null, 2)
4991
4961
  );
4992
4962
  writeFile2(path16.join(projectDir, "dev-client.lynx.bundle"), "");
4993
- fs16.mkdirSync(xcodeprojDir, { recursive: true });
4963
+ fs15.mkdirSync(xcodeprojDir, { recursive: true });
4994
4964
  writeFile2(path16.join(xcodeprojDir, "project.pbxproj"), generatePbxproj(ids));
4995
4965
  console.log(`\u2705 TamerDevApp iOS project created at ${iosDir}`);
4996
4966
  await setupCocoaPods(iosDir);
@@ -4999,8 +4969,8 @@ async function syncDevClientIos() {
4999
4969
  let resolved;
5000
4970
  let repoRoot;
5001
4971
  try {
5002
- repoRoot = findRepoRoot(process.cwd());
5003
- resolved = resolveDevAppPaths(repoRoot);
4972
+ resolved = resolveDevAppPaths(process.cwd());
4973
+ repoRoot = resolved.projectRoot;
5004
4974
  } catch (e) {
5005
4975
  console.error(`\u274C ${e.message}`);
5006
4976
  process.exit(1);
@@ -5008,10 +4978,10 @@ async function syncDevClientIos() {
5008
4978
  const iosDir = resolved.iosDir;
5009
4979
  const workspacePath = path16.join(iosDir, `${APP_NAME}.xcworkspace`);
5010
4980
  const projectDir = path16.join(iosDir, APP_NAME);
5011
- const hasCommittedSource = fs16.existsSync(path16.join(projectDir, "AppDelegate.swift"));
4981
+ const hasCommittedSource = fs15.existsSync(path16.join(projectDir, "AppDelegate.swift"));
5012
4982
  if (!hasCommittedSource) {
5013
4983
  await createDevAppProject(iosDir, repoRoot);
5014
- } else if (!fs16.existsSync(workspacePath)) {
4984
+ } else if (!fs15.existsSync(workspacePath)) {
5015
4985
  await setupCocoaPods(iosDir);
5016
4986
  console.log(`\u2139\uFE0F iOS dev-app project exists; ran pod install`);
5017
4987
  } else {
@@ -5029,8 +4999,8 @@ async function syncDevClientIos() {
5029
4999
  execSync7("npm run build", { stdio: "inherit", cwd: devClientDir });
5030
5000
  const bundleSrc = resolved.lynxBundlePath;
5031
5001
  const bundleDst = path16.join(iosDir, APP_NAME, "dev-client.lynx.bundle");
5032
- if (fs16.existsSync(bundleSrc)) {
5033
- fs16.copyFileSync(bundleSrc, bundleDst);
5002
+ if (fs15.existsSync(bundleSrc)) {
5003
+ fs15.copyFileSync(bundleSrc, bundleDst);
5034
5004
  console.log(`\u2728 Copied dev-client.lynx.bundle to iOS project`);
5035
5005
  } else {
5036
5006
  console.warn(`\u26A0\uFE0F Bundle not found at ${bundleSrc}`);
@@ -5072,7 +5042,7 @@ async function buildIpa(opts = {}) {
5072
5042
  const scheme = appName;
5073
5043
  const workspacePath = path17.join(iosDir, `${appName}.xcworkspace`);
5074
5044
  const projectPath = path17.join(iosDir, `${appName}.xcodeproj`);
5075
- const xcproject = fs17.existsSync(workspacePath) ? workspacePath : projectPath;
5045
+ const xcproject = fs16.existsSync(workspacePath) ? workspacePath : projectPath;
5076
5046
  const flag = xcproject.endsWith(".xcworkspace") ? "-workspace" : "-project";
5077
5047
  const derivedDataPath = path17.join(iosDir, "build");
5078
5048
  const sdk = opts.install ? "iphonesimulator" : "iphoneos";
@@ -5091,7 +5061,7 @@ async function buildIpa(opts = {}) {
5091
5061
  `${configuration}-iphonesimulator`,
5092
5062
  `${appName}.app`
5093
5063
  );
5094
- if (!fs17.existsSync(appGlob)) {
5064
+ if (!fs16.existsSync(appGlob)) {
5095
5065
  console.error(`\u274C Built app not found at: ${appGlob}`);
5096
5066
  process.exit(1);
5097
5067
  }
@@ -5112,14 +5082,13 @@ async function buildIpa(opts = {}) {
5112
5082
  }
5113
5083
  }
5114
5084
  async function buildIosDevApp(install, release) {
5115
- const repoRoot = findRepoRoot(process.cwd());
5116
- const resolved = resolveDevAppPaths(repoRoot);
5085
+ const resolved = resolveDevAppPaths(process.cwd());
5117
5086
  const iosDir = resolved.iosDir;
5118
5087
  const configuration = release ? "Release" : "Debug";
5119
5088
  await syncDevClient_default2();
5120
5089
  const workspacePath = path17.join(iosDir, `${DEV_APP_NAME}.xcworkspace`);
5121
5090
  const projectPath = path17.join(iosDir, `${DEV_APP_NAME}.xcodeproj`);
5122
- const xcproject = fs17.existsSync(workspacePath) ? workspacePath : projectPath;
5091
+ const xcproject = fs16.existsSync(workspacePath) ? workspacePath : projectPath;
5123
5092
  const flag = xcproject.endsWith(".xcworkspace") ? "workspace" : "project";
5124
5093
  console.log(`
5125
5094
  \u{1F528} Building TamerDevApp for simulator (${configuration})...`);
@@ -5144,7 +5113,7 @@ async function buildIosDevApp(install, release) {
5144
5113
  var build_default2 = buildIpa;
5145
5114
 
5146
5115
  // src/common/init.ts
5147
- import fs18 from "fs";
5116
+ import fs17 from "fs";
5148
5117
  import path18 from "path";
5149
5118
  import readline from "readline";
5150
5119
  var rl = readline.createInterface({
@@ -5197,7 +5166,7 @@ async function init() {
5197
5166
  };
5198
5167
  if (lynxProject) config.lynxProject = lynxProject;
5199
5168
  const configPath = path18.join(process.cwd(), "tamer.config.json");
5200
- fs18.writeFileSync(configPath, JSON.stringify(config, null, 2));
5169
+ fs17.writeFileSync(configPath, JSON.stringify(config, null, 2));
5201
5170
  console.log(`
5202
5171
  \u2705 Generated tamer.config.json at ${configPath}`);
5203
5172
  rl.close();
@@ -5205,7 +5174,7 @@ async function init() {
5205
5174
  var init_default = init;
5206
5175
 
5207
5176
  // src/common/create.ts
5208
- import fs19 from "fs";
5177
+ import fs18 from "fs";
5209
5178
  import path19 from "path";
5210
5179
  import readline2 from "readline";
5211
5180
  var rl2 = readline2.createInterface({ input: process.stdin, output: process.stdout, terminal: false });
@@ -5237,12 +5206,12 @@ async function create3() {
5237
5206
  const fullModuleClassName = `${packageName}.${simpleModuleName}`;
5238
5207
  const cwd = process.cwd();
5239
5208
  const root = path19.join(cwd, extName);
5240
- if (fs19.existsSync(root)) {
5209
+ if (fs18.existsSync(root)) {
5241
5210
  console.error(`\u274C Directory ${extName} already exists.`);
5242
5211
  rl2.close();
5243
5212
  process.exit(1);
5244
5213
  }
5245
- fs19.mkdirSync(root, { recursive: true });
5214
+ fs18.mkdirSync(root, { recursive: true });
5246
5215
  const lynxExt = {
5247
5216
  platforms: {
5248
5217
  android: {
@@ -5257,7 +5226,7 @@ async function create3() {
5257
5226
  web: {}
5258
5227
  }
5259
5228
  };
5260
- fs19.writeFileSync(path19.join(root, "lynx.ext.json"), JSON.stringify(lynxExt, null, 2));
5229
+ fs18.writeFileSync(path19.join(root, "lynx.ext.json"), JSON.stringify(lynxExt, null, 2));
5261
5230
  const pkg = {
5262
5231
  name: extName,
5263
5232
  version: "0.0.1",
@@ -5270,17 +5239,17 @@ async function create3() {
5270
5239
  engines: { node: ">=18" }
5271
5240
  };
5272
5241
  if (includeModule) pkg.types = "src/index.d.ts";
5273
- fs19.writeFileSync(path19.join(root, "package.json"), JSON.stringify(pkg, null, 2));
5242
+ fs18.writeFileSync(path19.join(root, "package.json"), JSON.stringify(pkg, null, 2));
5274
5243
  const pkgPath = packageName.replace(/\./g, "/");
5275
5244
  if (includeModule) {
5276
- fs19.mkdirSync(path19.join(root, "src"), { recursive: true });
5277
- fs19.writeFileSync(path19.join(root, "src", "index.d.ts"), `/** @lynxmodule */
5245
+ fs18.mkdirSync(path19.join(root, "src"), { recursive: true });
5246
+ fs18.writeFileSync(path19.join(root, "src", "index.d.ts"), `/** @lynxmodule */
5278
5247
  export declare class ${simpleModuleName} {
5279
5248
  // Add your module methods here
5280
5249
  }
5281
5250
  `);
5282
- fs19.mkdirSync(path19.join(root, "android", "src", "main", "kotlin", pkgPath), { recursive: true });
5283
- fs19.writeFileSync(path19.join(root, "android", "build.gradle.kts"), `plugins {
5251
+ fs18.mkdirSync(path19.join(root, "android", "src", "main", "kotlin", pkgPath), { recursive: true });
5252
+ fs18.writeFileSync(path19.join(root, "android", "build.gradle.kts"), `plugins {
5284
5253
  id("com.android.library")
5285
5254
  id("org.jetbrains.kotlin.android")
5286
5255
  }
@@ -5301,7 +5270,7 @@ dependencies {
5301
5270
  implementation(libs.lynx.jssdk)
5302
5271
  }
5303
5272
  `);
5304
- fs19.writeFileSync(path19.join(root, "android", "src", "main", "AndroidManifest.xml"), `<?xml version="1.0" encoding="utf-8"?>
5273
+ fs18.writeFileSync(path19.join(root, "android", "src", "main", "AndroidManifest.xml"), `<?xml version="1.0" encoding="utf-8"?>
5305
5274
  <manifest />
5306
5275
  `);
5307
5276
  const ktContent = `package ${packageName}
@@ -5318,8 +5287,8 @@ class ${simpleModuleName}(context: Context) : LynxModule(context) {
5318
5287
  }
5319
5288
  }
5320
5289
  `;
5321
- fs19.writeFileSync(path19.join(root, "android", "src", "main", "kotlin", pkgPath, `${simpleModuleName}.kt`), ktContent);
5322
- fs19.mkdirSync(path19.join(root, "ios", extName, extName, "Classes"), { recursive: true });
5290
+ fs18.writeFileSync(path19.join(root, "android", "src", "main", "kotlin", pkgPath, `${simpleModuleName}.kt`), ktContent);
5291
+ fs18.mkdirSync(path19.join(root, "ios", extName, extName, "Classes"), { recursive: true });
5323
5292
  const podspec = `Pod::Spec.new do |s|
5324
5293
  s.name = '${extName}'
5325
5294
  s.version = '0.0.1'
@@ -5333,7 +5302,7 @@ class ${simpleModuleName}(context: Context) : LynxModule(context) {
5333
5302
  s.dependency 'Lynx'
5334
5303
  end
5335
5304
  `;
5336
- fs19.writeFileSync(path19.join(root, "ios", extName, `${extName}.podspec`), podspec);
5305
+ fs18.writeFileSync(path19.join(root, "ios", extName, `${extName}.podspec`), podspec);
5337
5306
  const swiftContent = `import Foundation
5338
5307
 
5339
5308
  @objc public class ${simpleModuleName}: NSObject {
@@ -5342,16 +5311,16 @@ end
5342
5311
  }
5343
5312
  }
5344
5313
  `;
5345
- fs19.writeFileSync(path19.join(root, "ios", extName, extName, "Classes", `${simpleModuleName}.swift`), swiftContent);
5314
+ fs18.writeFileSync(path19.join(root, "ios", extName, extName, "Classes", `${simpleModuleName}.swift`), swiftContent);
5346
5315
  }
5347
- fs19.writeFileSync(path19.join(root, "index.js"), `'use strict';
5316
+ fs18.writeFileSync(path19.join(root, "index.js"), `'use strict';
5348
5317
  module.exports = {};
5349
5318
  `);
5350
- fs19.writeFileSync(path19.join(root, "tsconfig.json"), JSON.stringify({
5319
+ fs18.writeFileSync(path19.join(root, "tsconfig.json"), JSON.stringify({
5351
5320
  compilerOptions: { target: "ES2020", module: "ESNext", moduleResolution: "bundler", strict: true },
5352
5321
  include: ["src"]
5353
5322
  }, null, 2));
5354
- fs19.writeFileSync(path19.join(root, "README.md"), `# ${extName}
5323
+ fs18.writeFileSync(path19.join(root, "README.md"), `# ${extName}
5355
5324
 
5356
5325
  Lynx extension for ${extName}.
5357
5326
 
@@ -5376,7 +5345,7 @@ This package uses \`lynx.ext.json\` (RFC-compliant) for autolinking.
5376
5345
  var create_default3 = create3;
5377
5346
 
5378
5347
  // src/common/codegen.ts
5379
- import fs20 from "fs";
5348
+ import fs19 from "fs";
5380
5349
  import path20 from "path";
5381
5350
  function codegen() {
5382
5351
  const cwd = process.cwd();
@@ -5387,7 +5356,7 @@ function codegen() {
5387
5356
  }
5388
5357
  const srcDir = path20.join(cwd, "src");
5389
5358
  const generatedDir = path20.join(cwd, "generated");
5390
- fs20.mkdirSync(generatedDir, { recursive: true });
5359
+ fs19.mkdirSync(generatedDir, { recursive: true });
5391
5360
  const dtsFiles = findDtsFiles(srcDir);
5392
5361
  const modules = extractLynxModules(dtsFiles);
5393
5362
  if (modules.length === 0) {
@@ -5398,25 +5367,25 @@ function codegen() {
5398
5367
  const tsContent = `export type { ${mod} } from '../src/index.js';
5399
5368
  `;
5400
5369
  const outPath = path20.join(generatedDir, `${mod}.ts`);
5401
- fs20.writeFileSync(outPath, tsContent);
5370
+ fs19.writeFileSync(outPath, tsContent);
5402
5371
  console.log(`\u2705 Generated ${outPath}`);
5403
5372
  }
5404
5373
  if (config.android) {
5405
5374
  const androidGenerated = path20.join(cwd, "android", "src", "main", "kotlin", config.android.moduleClassName.replace(/\./g, "/").replace(/[^/]+$/, ""), "generated");
5406
- fs20.mkdirSync(androidGenerated, { recursive: true });
5375
+ fs19.mkdirSync(androidGenerated, { recursive: true });
5407
5376
  console.log(`\u2139\uFE0F Android generated dir: ${androidGenerated} (spec generation coming soon)`);
5408
5377
  }
5409
5378
  if (config.ios) {
5410
5379
  const iosGenerated = path20.join(cwd, "ios", "generated");
5411
- fs20.mkdirSync(iosGenerated, { recursive: true });
5380
+ fs19.mkdirSync(iosGenerated, { recursive: true });
5412
5381
  console.log(`\u2139\uFE0F iOS generated dir: ${iosGenerated} (spec generation coming soon)`);
5413
5382
  }
5414
5383
  console.log("\u2728 Codegen complete.");
5415
5384
  }
5416
5385
  function findDtsFiles(dir) {
5417
5386
  const result = [];
5418
- if (!fs20.existsSync(dir)) return result;
5419
- const entries = fs20.readdirSync(dir, { withFileTypes: true });
5387
+ if (!fs19.existsSync(dir)) return result;
5388
+ const entries = fs19.readdirSync(dir, { withFileTypes: true });
5420
5389
  for (const e of entries) {
5421
5390
  const full = path20.join(dir, e.name);
5422
5391
  if (e.isDirectory()) result.push(...findDtsFiles(full));
@@ -5428,7 +5397,7 @@ function extractLynxModules(files) {
5428
5397
  const modules = [];
5429
5398
  const seen = /* @__PURE__ */ new Set();
5430
5399
  for (const file of files) {
5431
- const content = fs20.readFileSync(file, "utf8");
5400
+ const content = fs19.readFileSync(file, "utf8");
5432
5401
  const regex = /\/\*\*\s*@lynxmodule\s*\*\/\s*export\s+declare\s+class\s+(\w+)/g;
5433
5402
  let m;
5434
5403
  while ((m = regex.exec(content)) !== null) {
@@ -5444,7 +5413,7 @@ var codegen_default = codegen;
5444
5413
 
5445
5414
  // src/common/devServer.ts
5446
5415
  import { spawn } from "child_process";
5447
- import fs21 from "fs";
5416
+ import fs20 from "fs";
5448
5417
  import http from "http";
5449
5418
  import os3 from "os";
5450
5419
  import path21 from "path";
@@ -5470,8 +5439,8 @@ async function startDevServer(opts) {
5470
5439
  let buildProcess = null;
5471
5440
  function detectPackageManager2(cwd) {
5472
5441
  const dir = path21.resolve(cwd);
5473
- if (fs21.existsSync(path21.join(dir, "pnpm-lock.yaml"))) return { cmd: "pnpm", args: ["run", "build"] };
5474
- if (fs21.existsSync(path21.join(dir, "bun.lockb")) || fs21.existsSync(path21.join(dir, "bun.lock"))) return { cmd: "bun", args: ["run", "build"] };
5442
+ if (fs20.existsSync(path21.join(dir, "pnpm-lock.yaml"))) return { cmd: "pnpm", args: ["run", "build"] };
5443
+ if (fs20.existsSync(path21.join(dir, "bun.lockb")) || fs20.existsSync(path21.join(dir, "bun.lock"))) return { cmd: "bun", args: ["run", "build"] };
5475
5444
  return { cmd: "npm", args: ["run", "build"] };
5476
5445
  }
5477
5446
  function runBuild() {
@@ -5497,14 +5466,14 @@ async function startDevServer(opts) {
5497
5466
  const basePath = `/${projectName}`;
5498
5467
  const iconPaths = resolveIconPaths(projectRoot, config);
5499
5468
  let iconFilePath = null;
5500
- if (iconPaths?.source && fs21.statSync(iconPaths.source).isFile()) {
5469
+ if (iconPaths?.source && fs20.statSync(iconPaths.source).isFile()) {
5501
5470
  iconFilePath = iconPaths.source;
5502
5471
  } else if (iconPaths?.android) {
5503
5472
  const androidIcon = path21.join(iconPaths.android, "mipmap-xxxhdpi", "ic_launcher.png");
5504
- if (fs21.existsSync(androidIcon)) iconFilePath = androidIcon;
5473
+ if (fs20.existsSync(androidIcon)) iconFilePath = androidIcon;
5505
5474
  } else if (iconPaths?.ios) {
5506
5475
  const iosIcon = path21.join(iconPaths.ios, "Icon-1024.png");
5507
- if (fs21.existsSync(iosIcon)) iconFilePath = iosIcon;
5476
+ if (fs20.existsSync(iosIcon)) iconFilePath = iosIcon;
5508
5477
  }
5509
5478
  const iconExt = iconFilePath ? path21.extname(iconFilePath) || ".png" : "";
5510
5479
  const iconMime = {
@@ -5545,7 +5514,7 @@ async function startDevServer(opts) {
5545
5514
  return;
5546
5515
  }
5547
5516
  if (iconFilePath && (reqPath === `${basePath}/icon` || reqPath === `${basePath}/icon${iconExt}`)) {
5548
- fs21.readFile(iconFilePath, (err, data) => {
5517
+ fs20.readFile(iconFilePath, (err, data) => {
5549
5518
  if (err) {
5550
5519
  res.writeHead(404);
5551
5520
  res.end();
@@ -5570,7 +5539,7 @@ async function startDevServer(opts) {
5570
5539
  res.end();
5571
5540
  return;
5572
5541
  }
5573
- fs21.readFile(filePath, (err, data) => {
5542
+ fs20.readFile(filePath, (err, data) => {
5574
5543
  if (err) {
5575
5544
  res.writeHead(404);
5576
5545
  res.end("Not found");
@@ -5627,7 +5596,7 @@ async function startDevServer(opts) {
5627
5596
  path21.join(lynxProjectDir, "src"),
5628
5597
  path21.join(lynxProjectDir, "lynx.config.ts"),
5629
5598
  path21.join(lynxProjectDir, "lynx.config.js")
5630
- ].filter((p) => fs21.existsSync(p));
5599
+ ].filter((p) => fs20.existsSync(p));
5631
5600
  if (watchPaths.length > 0) {
5632
5601
  const watcher = chokidar.watch(watchPaths, { ignoreInitial: true });
5633
5602
  watcher.on("change", async () => {
@@ -5706,10 +5675,10 @@ async function start(opts) {
5706
5675
  var start_default = start;
5707
5676
 
5708
5677
  // src/common/injectHost.ts
5709
- import fs22 from "fs";
5678
+ import fs21 from "fs";
5710
5679
  import path22 from "path";
5711
5680
  function readAndSubstitute(templatePath, vars) {
5712
- const raw = fs22.readFileSync(templatePath, "utf-8");
5681
+ const raw = fs21.readFileSync(templatePath, "utf-8");
5713
5682
  return Object.entries(vars).reduce(
5714
5683
  (s, [k, v]) => s.replace(new RegExp(`\\{\\{${k}\\}\\}`, "g"), v),
5715
5684
  raw
@@ -5734,7 +5703,7 @@ async function injectHostAndroid(opts) {
5734
5703
  const packagePath = packageName.replace(/\./g, "/");
5735
5704
  const javaDir = path22.join(rootDir, "app", "src", "main", "java", packagePath);
5736
5705
  const kotlinDir = path22.join(rootDir, "app", "src", "main", "kotlin", packagePath);
5737
- if (!fs22.existsSync(javaDir) || !fs22.existsSync(kotlinDir)) {
5706
+ if (!fs21.existsSync(javaDir) || !fs21.existsSync(kotlinDir)) {
5738
5707
  console.error("\u274C Android project not found. Run `t4l android create` first or ensure android/ exists.");
5739
5708
  process.exit(1);
5740
5709
  }
@@ -5747,14 +5716,14 @@ async function injectHostAndroid(opts) {
5747
5716
  ];
5748
5717
  for (const { src, dst } of files) {
5749
5718
  const srcPath = path22.join(templateDir, src);
5750
- if (!fs22.existsSync(srcPath)) continue;
5751
- if (fs22.existsSync(dst) && !opts?.force) {
5719
+ if (!fs21.existsSync(srcPath)) continue;
5720
+ if (fs21.existsSync(dst) && !opts?.force) {
5752
5721
  console.log(`\u23ED\uFE0F Skipping ${path22.basename(dst)} (use --force to overwrite)`);
5753
5722
  continue;
5754
5723
  }
5755
5724
  const content = readAndSubstitute(srcPath, vars);
5756
- fs22.mkdirSync(path22.dirname(dst), { recursive: true });
5757
- fs22.writeFileSync(dst, content);
5725
+ fs21.mkdirSync(path22.dirname(dst), { recursive: true });
5726
+ fs21.writeFileSync(dst, content);
5758
5727
  console.log(`\u2705 Injected ${path22.basename(dst)}`);
5759
5728
  }
5760
5729
  }
@@ -5775,7 +5744,7 @@ async function injectHostIos(opts) {
5775
5744
  const iosDir = config.paths?.iosDir ?? "ios";
5776
5745
  const rootDir = path22.join(projectRoot, iosDir);
5777
5746
  const projectDir = path22.join(rootDir, appName);
5778
- if (!fs22.existsSync(projectDir)) {
5747
+ if (!fs21.existsSync(projectDir)) {
5779
5748
  console.error("\u274C iOS project not found. Run `t4l ios create` first or ensure ios/ exists.");
5780
5749
  process.exit(1);
5781
5750
  }
@@ -5791,19 +5760,19 @@ async function injectHostIos(opts) {
5791
5760
  for (const f of files) {
5792
5761
  const srcPath = path22.join(templateDir, f);
5793
5762
  const dstPath = path22.join(projectDir, f);
5794
- if (!fs22.existsSync(srcPath)) continue;
5795
- if (fs22.existsSync(dstPath) && !opts?.force) {
5763
+ if (!fs21.existsSync(srcPath)) continue;
5764
+ if (fs21.existsSync(dstPath) && !opts?.force) {
5796
5765
  console.log(`\u23ED\uFE0F Skipping ${f} (use --force to overwrite)`);
5797
5766
  continue;
5798
5767
  }
5799
5768
  const content = readAndSubstitute(srcPath, vars);
5800
- fs22.writeFileSync(dstPath, content);
5769
+ fs21.writeFileSync(dstPath, content);
5801
5770
  console.log(`\u2705 Injected ${f}`);
5802
5771
  }
5803
5772
  }
5804
5773
 
5805
5774
  // src/common/buildEmbeddable.ts
5806
- import fs23 from "fs";
5775
+ import fs22 from "fs";
5807
5776
  import path23 from "path";
5808
5777
  import { execSync as execSync9 } from "child_process";
5809
5778
  var EMBEDDABLE_DIR = "embeddable";
@@ -5884,9 +5853,9 @@ function generateAndroidLibrary(outDir, androidDir, projectRoot, lynxBundlePath,
5884
5853
  const assetsDir = path23.join(libSrcMain, "assets");
5885
5854
  const kotlinDir = path23.join(libSrcMain, "kotlin", LIB_PACKAGE.replace(/\./g, "/"));
5886
5855
  const generatedDir = path23.join(kotlinDir, "generated");
5887
- fs23.mkdirSync(path23.join(androidDir, "gradle"), { recursive: true });
5888
- fs23.mkdirSync(generatedDir, { recursive: true });
5889
- fs23.mkdirSync(assetsDir, { recursive: true });
5856
+ fs22.mkdirSync(path23.join(androidDir, "gradle"), { recursive: true });
5857
+ fs22.mkdirSync(generatedDir, { recursive: true });
5858
+ fs22.mkdirSync(assetsDir, { recursive: true });
5890
5859
  const androidModules = modules.filter((m) => m.config.android);
5891
5860
  const abiList = abiFilters.map((a) => `"${a}"`).join(", ");
5892
5861
  const settingsContent = `pluginManagement {
@@ -5953,9 +5922,9 @@ dependencies {
5953
5922
  ${libDeps}
5954
5923
  }
5955
5924
  `;
5956
- fs23.writeFileSync(path23.join(androidDir, "gradle", "libs.versions.toml"), LIBS_VERSIONS_TOML);
5957
- fs23.writeFileSync(path23.join(androidDir, "settings.gradle.kts"), settingsContent);
5958
- fs23.writeFileSync(
5925
+ fs22.writeFileSync(path23.join(androidDir, "gradle", "libs.versions.toml"), LIBS_VERSIONS_TOML);
5926
+ fs22.writeFileSync(path23.join(androidDir, "settings.gradle.kts"), settingsContent);
5927
+ fs22.writeFileSync(
5959
5928
  path23.join(androidDir, "build.gradle.kts"),
5960
5929
  `plugins {
5961
5930
  alias(libs.plugins.android.library) apply false
@@ -5964,25 +5933,25 @@ ${libDeps}
5964
5933
  }
5965
5934
  `
5966
5935
  );
5967
- fs23.writeFileSync(
5936
+ fs22.writeFileSync(
5968
5937
  path23.join(androidDir, "gradle.properties"),
5969
5938
  `org.gradle.jvmargs=-Xmx2048m
5970
5939
  android.useAndroidX=true
5971
5940
  kotlin.code.style=official
5972
5941
  `
5973
5942
  );
5974
- fs23.writeFileSync(path23.join(libDir, "build.gradle.kts"), libBuildContent);
5975
- fs23.writeFileSync(
5943
+ fs22.writeFileSync(path23.join(libDir, "build.gradle.kts"), libBuildContent);
5944
+ fs22.writeFileSync(
5976
5945
  path23.join(libSrcMain, "AndroidManifest.xml"),
5977
5946
  '<?xml version="1.0" encoding="utf-8"?>\n<manifest />'
5978
5947
  );
5979
- fs23.copyFileSync(lynxBundlePath, path23.join(assetsDir, lynxBundleFile));
5980
- fs23.writeFileSync(path23.join(kotlinDir, "LynxEmbeddable.kt"), LYNX_EMBEDDABLE_KT);
5981
- fs23.writeFileSync(
5948
+ fs22.copyFileSync(lynxBundlePath, path23.join(assetsDir, lynxBundleFile));
5949
+ fs22.writeFileSync(path23.join(kotlinDir, "LynxEmbeddable.kt"), LYNX_EMBEDDABLE_KT);
5950
+ fs22.writeFileSync(
5982
5951
  path23.join(generatedDir, "GeneratedLynxExtensions.kt"),
5983
5952
  generateLynxExtensionsKotlin(modules, LIB_PACKAGE)
5984
5953
  );
5985
- fs23.writeFileSync(
5954
+ fs22.writeFileSync(
5986
5955
  path23.join(generatedDir, "GeneratedActivityLifecycle.kt"),
5987
5956
  generateActivityLifecycleKotlin(modules, LIB_PACKAGE)
5988
5957
  );
@@ -5992,20 +5961,20 @@ async function buildEmbeddable(opts = {}) {
5992
5961
  const { lynxProjectDir, lynxBundlePath, lynxBundleFile, projectRoot, config } = resolved;
5993
5962
  console.log("\u{1F4E6} Building Lynx project (release)...");
5994
5963
  execSync9("npm run build", { stdio: "inherit", cwd: lynxProjectDir });
5995
- if (!fs23.existsSync(lynxBundlePath)) {
5964
+ if (!fs22.existsSync(lynxBundlePath)) {
5996
5965
  console.error(`\u274C Bundle not found at ${lynxBundlePath}`);
5997
5966
  process.exit(1);
5998
5967
  }
5999
5968
  const outDir = path23.join(projectRoot, EMBEDDABLE_DIR);
6000
- fs23.mkdirSync(outDir, { recursive: true });
5969
+ fs22.mkdirSync(outDir, { recursive: true });
6001
5970
  const distDir = path23.dirname(lynxBundlePath);
6002
5971
  copyDistAssets(distDir, outDir, lynxBundleFile);
6003
5972
  const modules = discoverModules(projectRoot);
6004
5973
  const androidModules = modules.filter((m) => m.config.android);
6005
5974
  const abiFilters = resolveAbiFilters(config);
6006
5975
  const androidDir = path23.join(outDir, "android");
6007
- if (fs23.existsSync(androidDir)) fs23.rmSync(androidDir, { recursive: true });
6008
- fs23.mkdirSync(androidDir, { recursive: true });
5976
+ if (fs22.existsSync(androidDir)) fs22.rmSync(androidDir, { recursive: true });
5977
+ fs22.mkdirSync(androidDir, { recursive: true });
6009
5978
  generateAndroidLibrary(
6010
5979
  outDir,
6011
5980
  androidDir,
@@ -6023,15 +5992,15 @@ async function buildEmbeddable(opts = {}) {
6023
5992
  ].filter(Boolean);
6024
5993
  let hasWrapper = false;
6025
5994
  for (const d of existingGradleDirs) {
6026
- if (fs23.existsSync(path23.join(d, "gradlew"))) {
5995
+ if (fs22.existsSync(path23.join(d, "gradlew"))) {
6027
5996
  for (const name of ["gradlew", "gradlew.bat", "gradle"]) {
6028
5997
  const src = path23.join(d, name);
6029
- if (fs23.existsSync(src)) {
5998
+ if (fs22.existsSync(src)) {
6030
5999
  const dest = path23.join(androidDir, name);
6031
- if (fs23.statSync(src).isDirectory()) {
6032
- fs23.cpSync(src, dest, { recursive: true });
6000
+ if (fs22.statSync(src).isDirectory()) {
6001
+ fs22.cpSync(src, dest, { recursive: true });
6033
6002
  } else {
6034
- fs23.copyFileSync(src, dest);
6003
+ fs22.copyFileSync(src, dest);
6035
6004
  }
6036
6005
  }
6037
6006
  }
@@ -6052,8 +6021,8 @@ async function buildEmbeddable(opts = {}) {
6052
6021
  }
6053
6022
  const aarSrc = path23.join(androidDir, "lib", "build", "outputs", "aar", "lib-release.aar");
6054
6023
  const aarDest = path23.join(outDir, "tamer-embeddable.aar");
6055
- if (fs23.existsSync(aarSrc)) {
6056
- fs23.copyFileSync(aarSrc, aarDest);
6024
+ if (fs22.existsSync(aarSrc)) {
6025
+ fs22.copyFileSync(aarSrc, aarDest);
6057
6026
  console.log(` - tamer-embeddable.aar`);
6058
6027
  }
6059
6028
  const snippetAndroid = `// Add to your app's build.gradle:
@@ -6064,7 +6033,7 @@ async function buildEmbeddable(opts = {}) {
6064
6033
  // LynxEmbeddable.init(applicationContext)
6065
6034
  // val lynxView = LynxEmbeddable.buildLynxView(containerViewGroup)
6066
6035
  `;
6067
- fs23.writeFileSync(path23.join(outDir, "snippet-android.kt"), snippetAndroid);
6036
+ fs22.writeFileSync(path23.join(outDir, "snippet-android.kt"), snippetAndroid);
6068
6037
  generateIosPod(outDir, projectRoot, lynxBundlePath, lynxBundleFile, modules);
6069
6038
  const readme = `# Embeddable Lynx Bundle
6070
6039
 
@@ -6095,7 +6064,7 @@ Add the \`Podfile.snippet\` entries to your Podfile (inside your app target), th
6095
6064
 
6096
6065
  - [Embedding LynxView](https://lynxjs.org/guide/embed-lynx-to-native)
6097
6066
  `;
6098
- fs23.writeFileSync(path23.join(outDir, "README.md"), readme);
6067
+ fs22.writeFileSync(path23.join(outDir, "README.md"), readme);
6099
6068
  console.log(`
6100
6069
  \u2705 Embeddable output at ${outDir}/`);
6101
6070
  console.log(" - main.lynx.bundle");
@@ -6110,14 +6079,14 @@ function generateIosPod(outDir, projectRoot, lynxBundlePath, lynxBundleFile, mod
6110
6079
  const iosDir = path23.join(outDir, "ios");
6111
6080
  const podDir = path23.join(iosDir, "TamerEmbeddable");
6112
6081
  const resourcesDir = path23.join(podDir, "Resources");
6113
- fs23.mkdirSync(resourcesDir, { recursive: true });
6114
- fs23.copyFileSync(lynxBundlePath, path23.join(resourcesDir, lynxBundleFile));
6082
+ fs22.mkdirSync(resourcesDir, { recursive: true });
6083
+ fs22.copyFileSync(lynxBundlePath, path23.join(resourcesDir, lynxBundleFile));
6115
6084
  const iosModules = modules.filter((m) => m.config.ios);
6116
6085
  const podDeps = iosModules.map((p) => {
6117
6086
  const podspecPath = p.config.ios?.podspecPath || ".";
6118
6087
  const podspecDir = path23.join(p.packagePath, podspecPath);
6119
- if (!fs23.existsSync(podspecDir)) return null;
6120
- const files = fs23.readdirSync(podspecDir);
6088
+ if (!fs22.existsSync(podspecDir)) return null;
6089
+ const files = fs22.readdirSync(podspecDir);
6121
6090
  const podspecFile = files.find((f) => f.endsWith(".podspec"));
6122
6091
  const podName = podspecFile ? podspecFile.replace(".podspec", "") : p.name.split("/").pop().replace(/-/g, "");
6123
6092
  const absPath = path23.resolve(podspecDir);
@@ -6161,8 +6130,8 @@ end
6161
6130
  const swiftImports = iosModules.map((p) => {
6162
6131
  const podspecPath = p.config.ios?.podspecPath || ".";
6163
6132
  const podspecDir = path23.join(p.packagePath, podspecPath);
6164
- if (!fs23.existsSync(podspecDir)) return null;
6165
- const files = fs23.readdirSync(podspecDir);
6133
+ if (!fs22.existsSync(podspecDir)) return null;
6134
+ const files = fs22.readdirSync(podspecDir);
6166
6135
  const podspecFile = files.find((f) => f.endsWith(".podspec"));
6167
6136
  return podspecFile ? podspecFile.replace(".podspec", "") : null;
6168
6137
  }).filter(Boolean);
@@ -6181,16 +6150,16 @@ ${regBlock}
6181
6150
  }
6182
6151
  }
6183
6152
  `;
6184
- fs23.writeFileSync(path23.join(iosDir, "TamerEmbeddable.podspec"), podspecContent);
6185
- fs23.writeFileSync(path23.join(podDir, "LynxEmbeddable.swift"), lynxEmbeddableSwift);
6153
+ fs22.writeFileSync(path23.join(iosDir, "TamerEmbeddable.podspec"), podspecContent);
6154
+ fs22.writeFileSync(path23.join(podDir, "LynxEmbeddable.swift"), lynxEmbeddableSwift);
6186
6155
  const absIosDir = path23.resolve(iosDir);
6187
6156
  const podfileSnippet = `# Paste into your app target in Podfile:
6188
6157
 
6189
6158
  pod 'TamerEmbeddable', :path => '${absIosDir}'
6190
6159
  ${podDeps.map((d) => `pod '${d.podName}', :path => '${d.absPath}'`).join("\n")}
6191
6160
  `;
6192
- fs23.writeFileSync(path23.join(iosDir, "Podfile.snippet"), podfileSnippet);
6193
- fs23.writeFileSync(
6161
+ fs22.writeFileSync(path23.join(iosDir, "Podfile.snippet"), podfileSnippet);
6162
+ fs22.writeFileSync(
6194
6163
  path23.join(outDir, "snippet-ios.swift"),
6195
6164
  `// Add LynxEmbeddable.initEnvironment() in your AppDelegate/SceneDelegate before presenting LynxView.
6196
6165
  // Then create LynxView with your bundle URL (main.lynx.bundle is in the pod resources).
@@ -6199,7 +6168,7 @@ ${podDeps.map((d) => `pod '${d.podName}', :path => '${d.absPath}'`).join("\n")}
6199
6168
  }
6200
6169
 
6201
6170
  // src/common/add.ts
6202
- import fs24 from "fs";
6171
+ import fs23 from "fs";
6203
6172
  import path24 from "path";
6204
6173
  import { execSync as execSync10 } from "child_process";
6205
6174
  var CORE_PACKAGES = [
@@ -6214,8 +6183,8 @@ var CORE_PACKAGES = [
6214
6183
  ];
6215
6184
  function detectPackageManager(cwd) {
6216
6185
  const dir = path24.resolve(cwd);
6217
- if (fs24.existsSync(path24.join(dir, "pnpm-lock.yaml"))) return "pnpm";
6218
- if (fs24.existsSync(path24.join(dir, "bun.lockb"))) return "bun";
6186
+ if (fs23.existsSync(path24.join(dir, "pnpm-lock.yaml"))) return "pnpm";
6187
+ if (fs23.existsSync(path24.join(dir, "bun.lockb"))) return "bun";
6219
6188
  return "npm";
6220
6189
  }
6221
6190
  function runInstall(cwd, packages, pm) {
@@ -6267,12 +6236,12 @@ android.command("create").option("-t, --target <target>", "Create target: host (
6267
6236
  android.command("link").description("Link native modules to the Android project").action(() => {
6268
6237
  autolink_default();
6269
6238
  });
6270
- android.command("bundle").option("-t, --target <target>", "Bundle target: host (default) or dev-app", "host").option("-d, --debug", "Build debug (development) bundle").option("-r, --release", "Build release (production) bundle").description("Build Lynx bundle and copy to Android assets (runs autolink first)").action(async (opts) => {
6239
+ android.command("bundle").option("-t, --target <target>", "Bundle target: dev-app (default) or host", "dev-app").option("-d, --debug", "Build debug (development) bundle").option("-r, --release", "Build release (production) bundle").description("Build Lynx bundle and copy to Android assets (runs autolink first)").action(async (opts) => {
6271
6240
  validateDebugRelease(opts.debug, opts.release);
6272
6241
  const release = opts.release === true;
6273
6242
  await bundle_default({ target: opts.target, release });
6274
6243
  });
6275
- var androidBuildCmd = android.command("build").option("-i, --install", "Install APK to connected device and launch app after building").option("-t, --target <target>", "Build target: host (default) or dev-app", "host").option("-e, --embeddable", "Build for embedding in existing app (host only). Use with --release for production-ready embeddable.").option("-d, --debug", "Build debug (development) APK").option("-r, --release", "Build release (production) APK").description("Build APK (autolink + bundle + gradle)").action(async () => {
6244
+ var androidBuildCmd = android.command("build").option("-i, --install", "Install APK to connected device and launch app after building").option("-t, --target <target>", "Build target: dev-app (default) or host", "dev-app").option("-e, --embeddable", "Build for embedding in existing app (host only). Use with --release for production-ready embeddable.").option("-d, --debug", "Build debug (development) APK").option("-r, --release", "Build release (production) APK").description("Build APK (autolink + bundle + gradle)").action(async () => {
6276
6245
  const opts = androidBuildCmd.opts();
6277
6246
  validateDebugRelease(opts.debug, opts.release);
6278
6247
  const release = opts.release === true;
@@ -6298,12 +6267,12 @@ ios.command("inject").option("-f, --force", "Overwrite existing files").descript
6298
6267
  ios.command("link").description("Link native modules to the iOS project").action(() => {
6299
6268
  autolink_default2();
6300
6269
  });
6301
- ios.command("bundle").option("-t, --target <target>", "Bundle target: host (default) or dev-app", "host").option("-d, --debug", "Build debug (development) bundle").option("-r, --release", "Build release (production) bundle").description("Build Lynx bundle and copy to iOS project (runs autolink first)").action((opts) => {
6270
+ ios.command("bundle").option("-t, --target <target>", "Bundle target: dev-app (default) or host", "dev-app").option("-d, --debug", "Build debug (development) bundle").option("-r, --release", "Build release (production) bundle").description("Build Lynx bundle and copy to iOS project (runs autolink first)").action((opts) => {
6302
6271
  validateDebugRelease(opts.debug, opts.release);
6303
6272
  const release = opts.release === true;
6304
6273
  bundle_default2({ target: opts.target, release });
6305
6274
  });
6306
- var iosBuildCmd = ios.command("build").option("-t, --target <target>", "Build target: host (default) or dev-app", "host").option("-e, --embeddable", "Output bundle + code snippets to embeddable/ for adding LynxView to an existing app. Use with --release.").option("-i, --install", "Install and launch on booted simulator after building").option("-d, --debug", "Build debug (development) configuration").option("-r, --release", "Build release (production) configuration").description("Build iOS app (autolink + bundle + xcodebuild)").action(async () => {
6275
+ var iosBuildCmd = ios.command("build").option("-t, --target <target>", "Build target: dev-app (default) or host", "dev-app").option("-e, --embeddable", "Output bundle + code snippets to embeddable/ for adding LynxView to an existing app. Use with --release.").option("-i, --install", "Install and launch on booted simulator after building").option("-d, --debug", "Build debug (development) configuration").option("-r, --release", "Build release (production) configuration").description("Build iOS app (autolink + bundle + xcodebuild)").action(async () => {
6307
6276
  const opts = iosBuildCmd.opts();
6308
6277
  validateDebugRelease(opts.debug, opts.release);
6309
6278
  const release = opts.release === true;
@@ -6375,8 +6344,8 @@ program.command("codegen").description("Generate code from @lynxmodule declarati
6375
6344
  program.command("autolink-toggle").alias("autolink").description("Toggle autolink on/off in tamer.config.json (controls postinstall linking)").action(async () => {
6376
6345
  const configPath = path25.join(process.cwd(), "tamer.config.json");
6377
6346
  let config = {};
6378
- if (fs25.existsSync(configPath)) {
6379
- config = JSON.parse(fs25.readFileSync(configPath, "utf8"));
6347
+ if (fs24.existsSync(configPath)) {
6348
+ config = JSON.parse(fs24.readFileSync(configPath, "utf8"));
6380
6349
  }
6381
6350
  if (config.autolink) {
6382
6351
  delete config.autolink;
@@ -6385,7 +6354,7 @@ program.command("autolink-toggle").alias("autolink").description("Toggle autolin
6385
6354
  config.autolink = true;
6386
6355
  console.log("Autolink enabled in tamer.config.json");
6387
6356
  }
6388
- fs25.writeFileSync(configPath, JSON.stringify(config, null, 2));
6357
+ fs24.writeFileSync(configPath, JSON.stringify(config, null, 2));
6389
6358
  console.log(`Updated ${configPath}`);
6390
6359
  });
6391
6360
  if (process.argv.length <= 2 || process.argv.length === 3 && process.argv[2] === "init") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamer4lynx/cli",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "description": "A CLI tool for managing LynxJS native modules.",