@lark-apaas/fullstack-cli 1.1.45-alpha.2 → 1.1.45-alpha.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.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/index.ts
2
- import fs27 from "fs";
3
- import path23 from "path";
2
+ import fs29 from "fs";
3
+ import path25 from "path";
4
4
  import { fileURLToPath as fileURLToPath5 } from "url";
5
5
  import { config as dotenvConfig } from "dotenv";
6
6
 
@@ -2365,21 +2365,43 @@ var genDbSchemaCommand = {
2365
2365
  };
2366
2366
 
2367
2367
  // src/commands/sync/run.handler.ts
2368
- import path5 from "path";
2369
- import fs7 from "fs";
2368
+ import path6 from "path";
2369
+ import fs8 from "fs";
2370
2370
  import { fileURLToPath as fileURLToPath3 } from "url";
2371
2371
 
2372
2372
  // src/config/sync.ts
2373
2373
  var syncConfig = {
2374
2374
  // 派生规则
2375
2375
  sync: [
2376
- // 1. 派生 scripts 目录(总是覆盖)
2376
+ // 1. 派生 scripts 目录(总是覆盖;递归同步,包含 scripts/hooks/run-precommit.js)
2377
2377
  {
2378
2378
  from: "templates/scripts",
2379
2379
  to: "scripts",
2380
2380
  type: "directory",
2381
2381
  overwrite: true
2382
2382
  },
2383
+ // 1a. 同步 .husky 目录(hook 入口,可执行 sh 脚本)
2384
+ {
2385
+ from: "templates/.husky",
2386
+ to: ".husky",
2387
+ type: "directory",
2388
+ overwrite: true
2389
+ },
2390
+ // 1b. scripts.prepare:npm install 后自动激活 git hooks(不依赖 husky 库)
2391
+ // 直接写 core.hooksPath,并保底给 pre-commit 加执行位;非 git 仓库下静默退出
2392
+ {
2393
+ type: "add-script",
2394
+ name: "prepare",
2395
+ command: "chmod +x .husky/pre-commit 2>/dev/null; git config core.hooksPath .husky 2>/dev/null || true",
2396
+ overwrite: false
2397
+ },
2398
+ // 1c. scripts.precommit = pre-commit 真正的执行体(npm run lint + read-logs ×5)
2399
+ {
2400
+ type: "add-script",
2401
+ name: "precommit",
2402
+ command: "node scripts/hooks/run-precommit.js",
2403
+ overwrite: false
2404
+ },
2383
2405
  // 2. 智能合并 nest-cli.json 配置(保留用户自定义的 assets、plugins 等)
2384
2406
  {
2385
2407
  from: "templates/nest-cli.json",
@@ -2602,18 +2624,42 @@ function cleanupPackageJson(cwd = process.cwd()) {
2602
2624
  }
2603
2625
  }
2604
2626
 
2627
+ // src/commands/sync/install-husky.ts
2628
+ import fs7 from "fs";
2629
+ import path5 from "path";
2630
+ import { spawnSync as spawnSync2 } from "child_process";
2631
+ function activateGitHooks(userProjectRoot) {
2632
+ if (!fs7.existsSync(path5.join(userProjectRoot, ".git"))) {
2633
+ return { action: "skipped-no-git" };
2634
+ }
2635
+ const hookFile = path5.join(userProjectRoot, ".husky", "pre-commit");
2636
+ if (!fs7.existsSync(hookFile)) {
2637
+ return { action: "skipped-no-hook-file" };
2638
+ }
2639
+ fs7.chmodSync(hookFile, 493);
2640
+ const res = spawnSync2("git", ["config", "core.hooksPath", ".husky"], {
2641
+ cwd: userProjectRoot,
2642
+ stdio: ["ignore", "inherit", "inherit"]
2643
+ });
2644
+ if (res.status !== 0) {
2645
+ throw new Error(`git config core.hooksPath exited with ${String(res.status)}`);
2646
+ }
2647
+ console.log("[fullstack-cli] \u2713 git hooks activated (core.hooksPath -> .husky)");
2648
+ return { action: "activated" };
2649
+ }
2650
+
2605
2651
  // src/commands/sync/run.handler.ts
2606
2652
  async function run2(options) {
2607
2653
  const userProjectRoot = process.env.INIT_CWD || process.cwd();
2608
2654
  const __filename = fileURLToPath3(import.meta.url);
2609
- const __dirname2 = path5.dirname(__filename);
2610
- const pluginRoot = path5.resolve(__dirname2, "..");
2655
+ const __dirname2 = path6.dirname(__filename);
2656
+ const pluginRoot = path6.resolve(__dirname2, "..");
2611
2657
  if (userProjectRoot === pluginRoot) {
2612
2658
  console.log("[fullstack-cli] Skip syncing (installing plugin itself)");
2613
2659
  process.exit(0);
2614
2660
  }
2615
- const userPackageJson = path5.join(userProjectRoot, "package.json");
2616
- if (!fs7.existsSync(userPackageJson)) {
2661
+ const userPackageJson = path6.join(userProjectRoot, "package.json");
2662
+ if (!fs8.existsSync(userPackageJson)) {
2617
2663
  console.log("[fullstack-cli] Skip syncing (not a valid npm project)");
2618
2664
  process.exit(0);
2619
2665
  }
@@ -2633,6 +2679,12 @@ async function run2(options) {
2633
2679
  if (config.permissions) {
2634
2680
  setPermissions(config.permissions, userProjectRoot);
2635
2681
  }
2682
+ try {
2683
+ activateGitHooks(userProjectRoot);
2684
+ } catch (error) {
2685
+ const message = error instanceof Error ? error.message : String(error);
2686
+ console.warn(`[fullstack-cli] \u26A0 Failed to activate git hooks: ${message}`);
2687
+ }
2636
2688
  console.log("[fullstack-cli] Sync completed successfully \u2705");
2637
2689
  } catch (error) {
2638
2690
  const message = error instanceof Error ? error.message : String(error);
@@ -2644,28 +2696,51 @@ function patchUserPackageJson(userProjectRoot) {
2644
2696
  try {
2645
2697
  const pkg2 = readPackageJson(userProjectRoot);
2646
2698
  const lintPatchResult = patchLintScriptForFilesSupport(pkg2);
2699
+ const huskyMigrated = migrateLegacyHuskySetup(pkg2);
2700
+ let needsWrite = false;
2701
+ let logMessage = "";
2647
2702
  if (lintPatchResult === "patched") {
2648
- writePackageJson(pkg2, userProjectRoot);
2649
- console.log("[fullstack-cli] \u2713 Patched scripts.lint to support --files");
2650
- return;
2651
- }
2652
- if (lintPatchResult === "already-patched") {
2703
+ needsWrite = true;
2704
+ logMessage = "[fullstack-cli] \u2713 Patched scripts.lint to support --files";
2705
+ } else if (lintPatchResult === "already-patched") {
2653
2706
  console.log("[fullstack-cli] \u25CB scripts.lint already supports --files");
2654
- return;
2655
- }
2656
- if (lintPatchResult === "skipped-custom") {
2707
+ } else if (lintPatchResult === "skipped-custom") {
2657
2708
  console.warn(
2658
2709
  "[fullstack-cli] \u26A0 Skipped patching scripts.lint because it has been customized"
2659
2710
  );
2660
2711
  }
2712
+ if (huskyMigrated) {
2713
+ needsWrite = true;
2714
+ }
2715
+ if (needsWrite) {
2716
+ writePackageJson(pkg2, userProjectRoot);
2717
+ if (logMessage) console.log(logMessage);
2718
+ }
2661
2719
  } catch (error) {
2662
2720
  const message = error instanceof Error ? error.message : String(error);
2663
2721
  console.warn(`[fullstack-cli] \u26A0 Could not patch package.json: ${message}`);
2664
2722
  }
2665
2723
  }
2724
+ function migrateLegacyHuskySetup(pkg2) {
2725
+ let changed = false;
2726
+ const newPrepare = "chmod +x .husky/pre-commit 2>/dev/null; git config core.hooksPath .husky 2>/dev/null || true";
2727
+ const scripts = pkg2.scripts;
2728
+ if (scripts && scripts.prepare === "husky") {
2729
+ scripts.prepare = newPrepare;
2730
+ console.log("[fullstack-cli] \u2713 Migrated scripts.prepare from husky to native git config");
2731
+ changed = true;
2732
+ }
2733
+ const devDeps = pkg2.devDependencies;
2734
+ if (devDeps && devDeps.husky) {
2735
+ delete devDeps.husky;
2736
+ console.log("[fullstack-cli] \u2713 Removed legacy husky devDependency");
2737
+ changed = true;
2738
+ }
2739
+ return changed;
2740
+ }
2666
2741
  async function syncRule(rule, pluginRoot, userProjectRoot) {
2667
2742
  if (rule.type === "delete-file" || rule.type === "delete-directory") {
2668
- const destPath2 = path5.join(userProjectRoot, rule.to);
2743
+ const destPath2 = path6.join(userProjectRoot, rule.to);
2669
2744
  if (rule.type === "delete-file") {
2670
2745
  deleteFile(destPath2);
2671
2746
  } else {
@@ -2674,32 +2749,32 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
2674
2749
  return;
2675
2750
  }
2676
2751
  if (rule.type === "remove-line") {
2677
- const destPath2 = path5.join(userProjectRoot, rule.to);
2752
+ const destPath2 = path6.join(userProjectRoot, rule.to);
2678
2753
  removeLineFromFile(destPath2, rule.pattern);
2679
2754
  return;
2680
2755
  }
2681
2756
  if (rule.type === "add-script") {
2682
- const packageJsonPath = path5.join(userProjectRoot, "package.json");
2757
+ const packageJsonPath = path6.join(userProjectRoot, "package.json");
2683
2758
  addScript(packageJsonPath, rule.name, rule.command, rule.overwrite ?? false);
2684
2759
  return;
2685
2760
  }
2686
2761
  if (rule.type === "add-line") {
2687
- const destPath2 = path5.join(userProjectRoot, rule.to);
2762
+ const destPath2 = path6.join(userProjectRoot, rule.to);
2688
2763
  addLineToFile(destPath2, rule.line);
2689
2764
  return;
2690
2765
  }
2691
2766
  if (rule.type === "merge-json") {
2692
- const srcPath2 = path5.join(pluginRoot, rule.from);
2693
- const destPath2 = path5.join(userProjectRoot, rule.to);
2767
+ const srcPath2 = path6.join(pluginRoot, rule.from);
2768
+ const destPath2 = path6.join(userProjectRoot, rule.to);
2694
2769
  mergeJsonFile(srcPath2, destPath2, rule.arrayMerge);
2695
2770
  return;
2696
2771
  }
2697
2772
  if (!("from" in rule)) {
2698
2773
  return;
2699
2774
  }
2700
- const srcPath = path5.join(pluginRoot, rule.from);
2701
- const destPath = path5.join(userProjectRoot, rule.to);
2702
- if (!fs7.existsSync(srcPath)) {
2775
+ const srcPath = path6.join(pluginRoot, rule.from);
2776
+ const destPath = path6.join(userProjectRoot, rule.to);
2777
+ if (!fs8.existsSync(srcPath)) {
2703
2778
  console.warn(`[fullstack-cli] Source not found: ${rule.from}`);
2704
2779
  return;
2705
2780
  }
@@ -2716,68 +2791,68 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
2716
2791
  }
2717
2792
  }
2718
2793
  function syncFile(src, dest, overwrite = true, onlyIfExists = false) {
2719
- if (onlyIfExists && !fs7.existsSync(dest)) {
2720
- console.log(`[fullstack-cli] \u25CB ${path5.basename(dest)} (skipped, target not exists)`);
2794
+ if (onlyIfExists && !fs8.existsSync(dest)) {
2795
+ console.log(`[fullstack-cli] \u25CB ${path6.basename(dest)} (skipped, target not exists)`);
2721
2796
  return;
2722
2797
  }
2723
- const destDir = path5.dirname(dest);
2724
- if (!fs7.existsSync(destDir)) {
2725
- fs7.mkdirSync(destDir, { recursive: true });
2798
+ const destDir = path6.dirname(dest);
2799
+ if (!fs8.existsSync(destDir)) {
2800
+ fs8.mkdirSync(destDir, { recursive: true });
2726
2801
  }
2727
- if (fs7.existsSync(dest) && !overwrite) {
2728
- console.log(`[fullstack-cli] \u25CB ${path5.basename(dest)} (skipped, already exists)`);
2802
+ if (fs8.existsSync(dest) && !overwrite) {
2803
+ console.log(`[fullstack-cli] \u25CB ${path6.basename(dest)} (skipped, already exists)`);
2729
2804
  return;
2730
2805
  }
2731
- fs7.copyFileSync(src, dest);
2732
- console.log(`[fullstack-cli] \u2713 ${path5.basename(dest)}`);
2806
+ fs8.copyFileSync(src, dest);
2807
+ console.log(`[fullstack-cli] \u2713 ${path6.basename(dest)}`);
2733
2808
  }
2734
2809
  function syncDirectory(src, dest, overwrite = true) {
2735
- if (!fs7.existsSync(dest)) {
2736
- fs7.mkdirSync(dest, { recursive: true });
2810
+ if (!fs8.existsSync(dest)) {
2811
+ fs8.mkdirSync(dest, { recursive: true });
2737
2812
  }
2738
- const files = fs7.readdirSync(src);
2813
+ const files = fs8.readdirSync(src);
2739
2814
  let count = 0;
2740
2815
  files.forEach((file) => {
2741
- const srcFile = path5.join(src, file);
2742
- const destFile = path5.join(dest, file);
2743
- const stats = fs7.statSync(srcFile);
2816
+ const srcFile = path6.join(src, file);
2817
+ const destFile = path6.join(dest, file);
2818
+ const stats = fs8.statSync(srcFile);
2744
2819
  if (stats.isDirectory()) {
2745
2820
  syncDirectory(srcFile, destFile, overwrite);
2746
2821
  } else {
2747
- if (overwrite || !fs7.existsSync(destFile)) {
2748
- fs7.copyFileSync(srcFile, destFile);
2749
- console.log(`[fullstack-cli] \u2713 ${path5.relative(dest, destFile)}`);
2822
+ if (overwrite || !fs8.existsSync(destFile)) {
2823
+ fs8.copyFileSync(srcFile, destFile);
2824
+ console.log(`[fullstack-cli] \u2713 ${path6.relative(dest, destFile)}`);
2750
2825
  count++;
2751
2826
  }
2752
2827
  }
2753
2828
  });
2754
2829
  if (count > 0) {
2755
- console.log(`[fullstack-cli] Synced ${count} files to ${path5.basename(dest)}/`);
2830
+ console.log(`[fullstack-cli] Synced ${count} files to ${path6.basename(dest)}/`);
2756
2831
  }
2757
2832
  }
2758
2833
  function appendToFile(src, dest) {
2759
- const content = fs7.readFileSync(src, "utf-8");
2834
+ const content = fs8.readFileSync(src, "utf-8");
2760
2835
  let existingContent = "";
2761
- if (fs7.existsSync(dest)) {
2762
- existingContent = fs7.readFileSync(dest, "utf-8");
2836
+ if (fs8.existsSync(dest)) {
2837
+ existingContent = fs8.readFileSync(dest, "utf-8");
2763
2838
  }
2764
2839
  if (existingContent.includes(content.trim())) {
2765
- console.log(`[fullstack-cli] \u25CB ${path5.basename(dest)} (already contains content)`);
2840
+ console.log(`[fullstack-cli] \u25CB ${path6.basename(dest)} (already contains content)`);
2766
2841
  return;
2767
2842
  }
2768
- fs7.appendFileSync(dest, content);
2769
- console.log(`[fullstack-cli] \u2713 ${path5.basename(dest)} (appended)`);
2843
+ fs8.appendFileSync(dest, content);
2844
+ console.log(`[fullstack-cli] \u2713 ${path6.basename(dest)} (appended)`);
2770
2845
  }
2771
2846
  function setPermissions(permissions, projectRoot) {
2772
2847
  for (const [pattern, mode] of Object.entries(permissions)) {
2773
2848
  if (pattern === "**/*.sh") {
2774
- const scriptsDir = path5.join(projectRoot, "scripts");
2775
- if (fs7.existsSync(scriptsDir)) {
2776
- const files = fs7.readdirSync(scriptsDir);
2849
+ const scriptsDir = path6.join(projectRoot, "scripts");
2850
+ if (fs8.existsSync(scriptsDir)) {
2851
+ const files = fs8.readdirSync(scriptsDir);
2777
2852
  files.forEach((file) => {
2778
2853
  if (file.endsWith(".sh")) {
2779
- const filePath = path5.join(scriptsDir, file);
2780
- fs7.chmodSync(filePath, mode);
2854
+ const filePath = path6.join(scriptsDir, file);
2855
+ fs8.chmodSync(filePath, mode);
2781
2856
  }
2782
2857
  });
2783
2858
  }
@@ -2785,27 +2860,27 @@ function setPermissions(permissions, projectRoot) {
2785
2860
  }
2786
2861
  }
2787
2862
  function deleteFile(filePath) {
2788
- if (fs7.existsSync(filePath)) {
2789
- fs7.unlinkSync(filePath);
2790
- console.log(`[fullstack-cli] \u2713 ${path5.basename(filePath)} (deleted)`);
2863
+ if (fs8.existsSync(filePath)) {
2864
+ fs8.unlinkSync(filePath);
2865
+ console.log(`[fullstack-cli] \u2713 ${path6.basename(filePath)} (deleted)`);
2791
2866
  } else {
2792
- console.log(`[fullstack-cli] \u25CB ${path5.basename(filePath)} (not found)`);
2867
+ console.log(`[fullstack-cli] \u25CB ${path6.basename(filePath)} (not found)`);
2793
2868
  }
2794
2869
  }
2795
2870
  function deleteDirectory(dirPath) {
2796
- if (fs7.existsSync(dirPath)) {
2797
- fs7.rmSync(dirPath, { recursive: true });
2798
- console.log(`[fullstack-cli] \u2713 ${path5.basename(dirPath)} (deleted)`);
2871
+ if (fs8.existsSync(dirPath)) {
2872
+ fs8.rmSync(dirPath, { recursive: true });
2873
+ console.log(`[fullstack-cli] \u2713 ${path6.basename(dirPath)} (deleted)`);
2799
2874
  } else {
2800
- console.log(`[fullstack-cli] \u25CB ${path5.basename(dirPath)} (not found)`);
2875
+ console.log(`[fullstack-cli] \u25CB ${path6.basename(dirPath)} (not found)`);
2801
2876
  }
2802
2877
  }
2803
2878
  function addScript(packageJsonPath, name, command, overwrite) {
2804
- if (!fs7.existsSync(packageJsonPath)) {
2879
+ if (!fs8.existsSync(packageJsonPath)) {
2805
2880
  console.log(`[fullstack-cli] \u25CB package.json (not found)`);
2806
2881
  return;
2807
2882
  }
2808
- const content = fs7.readFileSync(packageJsonPath, "utf-8");
2883
+ const content = fs8.readFileSync(packageJsonPath, "utf-8");
2809
2884
  const pkg2 = JSON.parse(content);
2810
2885
  if (!pkg2.scripts) {
2811
2886
  pkg2.scripts = {};
@@ -2817,42 +2892,42 @@ function addScript(packageJsonPath, name, command, overwrite) {
2817
2892
  }
2818
2893
  }
2819
2894
  pkg2.scripts[name] = command;
2820
- fs7.writeFileSync(packageJsonPath, JSON.stringify(pkg2, null, 2) + "\n");
2895
+ fs8.writeFileSync(packageJsonPath, JSON.stringify(pkg2, null, 2) + "\n");
2821
2896
  console.log(`[fullstack-cli] \u2713 scripts.${name}`);
2822
2897
  }
2823
2898
  function addLineToFile(filePath, line) {
2824
- const fileName = path5.basename(filePath);
2825
- if (!fs7.existsSync(filePath)) {
2899
+ const fileName = path6.basename(filePath);
2900
+ if (!fs8.existsSync(filePath)) {
2826
2901
  console.log(`[fullstack-cli] \u25CB ${fileName} (not found, skipped)`);
2827
2902
  return;
2828
2903
  }
2829
- const content = fs7.readFileSync(filePath, "utf-8");
2904
+ const content = fs8.readFileSync(filePath, "utf-8");
2830
2905
  const lines = content.split("\n").map((l) => l.trim());
2831
2906
  if (lines.includes(line)) {
2832
2907
  console.log(`[fullstack-cli] \u25CB ${fileName} (line already exists: ${line})`);
2833
2908
  return;
2834
2909
  }
2835
2910
  const appendContent = (content.endsWith("\n") ? "" : "\n") + line + "\n";
2836
- fs7.appendFileSync(filePath, appendContent);
2911
+ fs8.appendFileSync(filePath, appendContent);
2837
2912
  console.log(`[fullstack-cli] \u2713 ${fileName} (added: ${line})`);
2838
2913
  }
2839
2914
  function mergeJsonFile(src, dest, arrayMerge) {
2840
- const fileName = path5.basename(dest);
2841
- if (!fs7.existsSync(src)) {
2915
+ const fileName = path6.basename(dest);
2916
+ if (!fs8.existsSync(src)) {
2842
2917
  console.warn(`[fullstack-cli] Source not found: ${src}`);
2843
2918
  return;
2844
2919
  }
2845
- const templateContent = JSON.parse(fs7.readFileSync(src, "utf-8"));
2846
- if (!fs7.existsSync(dest)) {
2847
- const destDir = path5.dirname(dest);
2848
- if (!fs7.existsSync(destDir)) {
2849
- fs7.mkdirSync(destDir, { recursive: true });
2920
+ const templateContent = JSON.parse(fs8.readFileSync(src, "utf-8"));
2921
+ if (!fs8.existsSync(dest)) {
2922
+ const destDir = path6.dirname(dest);
2923
+ if (!fs8.existsSync(destDir)) {
2924
+ fs8.mkdirSync(destDir, { recursive: true });
2850
2925
  }
2851
- fs7.writeFileSync(dest, JSON.stringify(templateContent, null, 2) + "\n");
2926
+ fs8.writeFileSync(dest, JSON.stringify(templateContent, null, 2) + "\n");
2852
2927
  console.log(`[fullstack-cli] \u2713 ${fileName} (created)`);
2853
2928
  return;
2854
2929
  }
2855
- const userContent = JSON.parse(fs7.readFileSync(dest, "utf-8"));
2930
+ const userContent = JSON.parse(fs8.readFileSync(dest, "utf-8"));
2856
2931
  const merged = deepMergeJson(userContent, templateContent, arrayMerge ?? {});
2857
2932
  const userStr = JSON.stringify(userContent, null, 2);
2858
2933
  const mergedStr = JSON.stringify(merged, null, 2);
@@ -2860,7 +2935,7 @@ function mergeJsonFile(src, dest, arrayMerge) {
2860
2935
  console.log(`[fullstack-cli] \u25CB ${fileName} (already up to date)`);
2861
2936
  return;
2862
2937
  }
2863
- fs7.writeFileSync(dest, mergedStr + "\n");
2938
+ fs8.writeFileSync(dest, mergedStr + "\n");
2864
2939
  console.log(`[fullstack-cli] \u2713 ${fileName} (merged)`);
2865
2940
  }
2866
2941
 
@@ -2920,16 +2995,16 @@ async function reportCreateInstanceEvent(pluginKey, version) {
2920
2995
  }
2921
2996
 
2922
2997
  // src/utils/git.ts
2923
- import { execSync, spawnSync as spawnSync2 } from "child_process";
2924
- import fs8 from "fs";
2925
- import path6 from "path";
2998
+ import { execSync, spawnSync as spawnSync3 } from "child_process";
2999
+ import fs9 from "fs";
3000
+ import path7 from "path";
2926
3001
  function isGitRepository(cwd = process.cwd()) {
2927
3002
  try {
2928
- const gitDir = path6.join(cwd, ".git");
2929
- if (fs8.existsSync(gitDir)) {
3003
+ const gitDir = path7.join(cwd, ".git");
3004
+ if (fs9.existsSync(gitDir)) {
2930
3005
  return true;
2931
3006
  }
2932
- const result = spawnSync2("git", ["rev-parse", "--git-dir"], {
3007
+ const result = spawnSync3("git", ["rev-parse", "--git-dir"], {
2933
3008
  cwd,
2934
3009
  stdio: "pipe",
2935
3010
  encoding: "utf-8"
@@ -2955,11 +3030,11 @@ function getChangedFiles(cwd = process.cwd()) {
2955
3030
  function gitAddUpgradeFiles(cwd = process.cwd(), filesToStage) {
2956
3031
  const filteredFiles = [];
2957
3032
  for (const filePath of filesToStage) {
2958
- if (fs8.existsSync(path6.join(cwd, filePath))) {
3033
+ if (fs9.existsSync(path7.join(cwd, filePath))) {
2959
3034
  filteredFiles.push(filePath);
2960
3035
  continue;
2961
3036
  }
2962
- const tracked = spawnSync2("git", ["ls-files", "--error-unmatch", "--", filePath], {
3037
+ const tracked = spawnSync3("git", ["ls-files", "--error-unmatch", "--", filePath], {
2963
3038
  cwd,
2964
3039
  stdio: "pipe",
2965
3040
  encoding: "utf-8"
@@ -2971,7 +3046,7 @@ function gitAddUpgradeFiles(cwd = process.cwd(), filesToStage) {
2971
3046
  if (filteredFiles.length === 0) {
2972
3047
  return;
2973
3048
  }
2974
- const result = spawnSync2("git", ["add", "--", ...filteredFiles], {
3049
+ const result = spawnSync3("git", ["add", "--", ...filteredFiles], {
2975
3050
  cwd,
2976
3051
  stdio: "pipe",
2977
3052
  encoding: "utf-8"
@@ -2982,7 +3057,7 @@ function gitAddUpgradeFiles(cwd = process.cwd(), filesToStage) {
2982
3057
  }
2983
3058
  }
2984
3059
  function hasStagedChanges(cwd = process.cwd()) {
2985
- const result = spawnSync2("git", ["diff", "--cached", "--quiet"], {
3060
+ const result = spawnSync3("git", ["diff", "--cached", "--quiet"], {
2986
3061
  cwd,
2987
3062
  stdio: "pipe",
2988
3063
  encoding: "utf-8"
@@ -2997,7 +3072,7 @@ function hasStagedChanges(cwd = process.cwd()) {
2997
3072
  throw new Error(`Failed to check staged changes: ${errorMsg}`);
2998
3073
  }
2999
3074
  function gitCommit(message, cwd = process.cwd()) {
3000
- const result = spawnSync2("git", ["commit", "-m", message], {
3075
+ const result = spawnSync3("git", ["commit", "-m", message], {
3001
3076
  cwd,
3002
3077
  stdio: "pipe",
3003
3078
  encoding: "utf-8"
@@ -3040,15 +3115,15 @@ Auto-committed by fullstack-cli`;
3040
3115
  }
3041
3116
 
3042
3117
  // src/commands/upgrade/shared/utils.ts
3043
- import path7 from "path";
3044
- import fs9 from "fs";
3118
+ import path8 from "path";
3119
+ import fs10 from "fs";
3045
3120
  import { fileURLToPath as fileURLToPath4 } from "url";
3046
3121
  function getCliVersion() {
3047
3122
  try {
3048
3123
  const __filename = fileURLToPath4(import.meta.url);
3049
- const __dirname2 = path7.dirname(__filename);
3050
- const pkgPath = path7.resolve(__dirname2, "../../../package.json");
3051
- const pkgContent = fs9.readFileSync(pkgPath, "utf-8");
3124
+ const __dirname2 = path8.dirname(__filename);
3125
+ const pkgPath = path8.resolve(__dirname2, "../../../package.json");
3126
+ const pkgContent = fs10.readFileSync(pkgPath, "utf-8");
3052
3127
  const pkg2 = JSON.parse(pkgContent);
3053
3128
  return pkg2.version || "unknown";
3054
3129
  } catch {
@@ -3106,31 +3181,47 @@ async function run3(options = {}) {
3106
3181
  }
3107
3182
 
3108
3183
  // src/commands/upgrade/deps/run.handler.ts
3109
- import { spawnSync as spawnSync3 } from "child_process";
3110
- import fs10 from "fs";
3111
- import path8 from "path";
3184
+ import { spawnSync as spawnSync4 } from "child_process";
3185
+ import fs11 from "fs";
3186
+ import path9 from "path";
3112
3187
 
3113
3188
  // src/utils/grayscale/config.ts
3114
3189
  function getGrayscaleConfig(configJson) {
3115
3190
  if (!configJson) {
3116
3191
  return null;
3117
3192
  }
3193
+ let parsed;
3118
3194
  try {
3119
- const parsed = JSON.parse(configJson);
3120
- const config = parsed.config;
3121
- if (!config || !config.enabled) {
3195
+ parsed = JSON.parse(configJson);
3196
+ } catch {
3197
+ console.warn("[grayscale] Failed to parse grayscale config");
3198
+ return null;
3199
+ }
3200
+ if (parsed && parsed.target_versions && typeof parsed.target_versions === "object") {
3201
+ const entries = Object.entries(parsed.target_versions).filter(
3202
+ ([, v]) => typeof v === "string" && v.length > 0
3203
+ );
3204
+ if (entries.length === 0) {
3205
+ console.log("[grayscale] target_versions present but empty, skip");
3122
3206
  return null;
3123
3207
  }
3124
3208
  return {
3125
- config,
3126
- tenantId: parsed.tenant_id != null ? String(parsed.tenant_id) : void 0,
3127
- appId: parsed.app_id || void 0,
3128
- xTtEnv: parsed.x_tt_env || void 0
3209
+ kind: "resolved",
3210
+ targetVersions: new Map(entries),
3211
+ matchedChannel: typeof parsed.matched_channel === "string" ? parsed.matched_channel : void 0
3129
3212
  };
3130
- } catch {
3131
- console.warn("[grayscale] Failed to parse grayscale config");
3213
+ }
3214
+ const config = parsed?.config;
3215
+ if (!config || !config.enabled) {
3132
3216
  return null;
3133
3217
  }
3218
+ return {
3219
+ kind: "legacy",
3220
+ config,
3221
+ tenantId: parsed.tenant_id != null ? String(parsed.tenant_id) : void 0,
3222
+ appId: parsed.app_id || void 0,
3223
+ xTtEnv: parsed.x_tt_env || void 0
3224
+ };
3134
3225
  }
3135
3226
 
3136
3227
  // src/utils/grayscale/identity.ts
@@ -3218,6 +3309,19 @@ function resolveGrayscaleVersions(_cwd, configJson) {
3218
3309
  console.log("[grayscale] Config not available, skipping grayscale");
3219
3310
  return null;
3220
3311
  }
3312
+ if (result.kind === "resolved") {
3313
+ console.log(
3314
+ `[grayscale] Using server-resolved versions (matched channel: ${result.matchedChannel || "(stable)"})`
3315
+ );
3316
+ console.log(`[grayscale] Resolved ${result.targetVersions.size} package version(s):`);
3317
+ for (const [pkg2, ver] of result.targetVersions) {
3318
+ console.log(`[grayscale] ${pkg2} -> ${ver}`);
3319
+ }
3320
+ return result.targetVersions;
3321
+ }
3322
+ console.warn(
3323
+ "[grayscale] Received legacy payload (full TCC config). This path is deprecated; sandbox_console should be upgraded to server-side resolution."
3324
+ );
3221
3325
  const { config, tenantId: payloadTenantId, appId: payloadAppId, xTtEnv: payloadXTtEnv } = result;
3222
3326
  const envIdentity = readProjectIdentity();
3223
3327
  const identity = {
@@ -3298,7 +3402,7 @@ function upgradePackages(packages, version, cwd) {
3298
3402
  packages.forEach((pkg2) => {
3299
3403
  const target = `${pkg2}@${version}`;
3300
3404
  console.log(`[fullstack-cli] Installing ${target}...`);
3301
- const result = spawnSync3("npm", ["install", target], {
3405
+ const result = spawnSync4("npm", ["install", target], {
3302
3406
  cwd,
3303
3407
  stdio: "inherit"
3304
3408
  });
@@ -3310,7 +3414,7 @@ function upgradePackages(packages, version, cwd) {
3310
3414
  console.log("[fullstack-cli] Upgrading to latest compatible versions...");
3311
3415
  packages.forEach((pkg2) => {
3312
3416
  console.log(`[fullstack-cli] Updating ${pkg2}...`);
3313
- const result = spawnSync3("npm", ["update", pkg2], {
3417
+ const result = spawnSync4("npm", ["update", pkg2], {
3314
3418
  cwd,
3315
3419
  stdio: "inherit"
3316
3420
  });
@@ -3327,8 +3431,8 @@ function installGrayscaleVersions(packages, grayscaleVersions, cwd, dryRun, mode
3327
3431
  if (version) {
3328
3432
  let current = "";
3329
3433
  try {
3330
- const installedPkgPath = path8.join(cwd, "node_modules", pkg2, "package.json");
3331
- const installedPkg = JSON.parse(fs10.readFileSync(installedPkgPath, "utf-8"));
3434
+ const installedPkgPath = path9.join(cwd, "node_modules", pkg2, "package.json");
3435
+ const installedPkg = JSON.parse(fs11.readFileSync(installedPkgPath, "utf-8"));
3332
3436
  current = installedPkg.version || "";
3333
3437
  } catch (err) {
3334
3438
  const code = err?.code;
@@ -3371,7 +3475,7 @@ function installGrayscaleVersions(packages, grayscaleVersions, cwd, dryRun, mode
3371
3475
  }
3372
3476
  const targets = upgradePlan.map(({ pkg: pkg2, version }) => `${pkg2}@${version}`);
3373
3477
  console.log(`[fullstack-cli] Installing ${targets.join(" ")}...`);
3374
- const result = spawnSync3("npm", ["install", ...targets], {
3478
+ const result = spawnSync4("npm", ["install", ...targets], {
3375
3479
  cwd,
3376
3480
  stdio: "inherit"
3377
3481
  });
@@ -3444,6 +3548,111 @@ var depsCommand = {
3444
3548
  }
3445
3549
  };
3446
3550
 
3551
+ // src/commands/upgrade/global-deps/run.handler.ts
3552
+ import { spawnSync as spawnSync5 } from "child_process";
3553
+ import fs12 from "fs";
3554
+ import path10 from "path";
3555
+ var MANAGED_GLOBAL_CLIS = [
3556
+ "@lark-apaas/fullstack-cli",
3557
+ "@lark-apaas/miaoda-cli"
3558
+ ];
3559
+ function readGlobalInstalledVersion(pkg2) {
3560
+ const candidates = [];
3561
+ if (process.env.npm_config_prefix) candidates.push(process.env.npm_config_prefix);
3562
+ if (process.env.NPM_CONFIG_PREFIX) candidates.push(process.env.NPM_CONFIG_PREFIX);
3563
+ candidates.push("/usr");
3564
+ candidates.push("/usr/local");
3565
+ if (process.env.HOME) candidates.push(path10.join(process.env.HOME, ".npm-global"));
3566
+ const seen = /* @__PURE__ */ new Set();
3567
+ for (const prefix of candidates) {
3568
+ if (seen.has(prefix)) continue;
3569
+ seen.add(prefix);
3570
+ try {
3571
+ const pkgPath = path10.join(prefix, "lib", "node_modules", pkg2, "package.json");
3572
+ if (fs12.existsSync(pkgPath)) {
3573
+ const meta = JSON.parse(fs12.readFileSync(pkgPath, "utf-8"));
3574
+ if (meta && typeof meta.version === "string") return meta.version;
3575
+ }
3576
+ } catch (err) {
3577
+ console.warn(
3578
+ `[fullstack-cli] readGlobalInstalledVersion(${pkg2}) failed at prefix=${prefix}: ${err instanceof Error ? err.message : String(err)}`
3579
+ );
3580
+ }
3581
+ }
3582
+ return "";
3583
+ }
3584
+ function buildGlobalUpgradePlan(managed, resolvedVersions, readVersion) {
3585
+ const plan = [];
3586
+ for (const pkg2 of managed) {
3587
+ const target = resolvedVersions.get(pkg2);
3588
+ if (!target) {
3589
+ console.log(`[fullstack-cli] ${pkg2}: no target version in grayscale config, skip`);
3590
+ continue;
3591
+ }
3592
+ const current = readVersion(pkg2);
3593
+ if (current && current === target) {
3594
+ console.log(`[fullstack-cli] ${pkg2}@${target} (already installed, skip)`);
3595
+ continue;
3596
+ }
3597
+ plan.push({ pkg: pkg2, current, target });
3598
+ }
3599
+ return plan;
3600
+ }
3601
+ async function run5(options = {}) {
3602
+ console.log("[fullstack-cli] Starting global CLI upgrade...");
3603
+ if (!options.grayscaleConfig) {
3604
+ console.log("[fullstack-cli] No grayscale config, skip global upgrade");
3605
+ return;
3606
+ }
3607
+ const grayscaleVersions = resolveGrayscaleVersions("/", options.grayscaleConfig);
3608
+ if (!grayscaleVersions) {
3609
+ console.log("[fullstack-cli] Grayscale config not available, skip global upgrade");
3610
+ return;
3611
+ }
3612
+ const plan = buildGlobalUpgradePlan(MANAGED_GLOBAL_CLIS, grayscaleVersions, readGlobalInstalledVersion);
3613
+ if (plan.length === 0) {
3614
+ console.log("[fullstack-cli] No global CLI upgrade needed");
3615
+ return;
3616
+ }
3617
+ console.log(`[fullstack-cli] Global upgrade plan (${plan.length} package(s)):`);
3618
+ plan.forEach(({ pkg: pkg2, current, target }) => {
3619
+ console.log(` - ${pkg2} ${current || "(not installed)"} -> ${target}`);
3620
+ });
3621
+ if (options.dryRun) {
3622
+ console.log("[fullstack-cli] Dry run mode, skipping actual installation");
3623
+ return;
3624
+ }
3625
+ const targets = plan.map(({ pkg: pkg2, target }) => `${pkg2}@${target}`);
3626
+ const npmArgs = ["install", "-g", ...targets];
3627
+ if (options.registry) {
3628
+ npmArgs.push("--registry", options.registry);
3629
+ }
3630
+ console.log(`[fullstack-cli] Running: npm ${npmArgs.join(" ")}`);
3631
+ const result = spawnSync5("npm", npmArgs, { stdio: "inherit" });
3632
+ if (result.error || result.status !== 0) {
3633
+ console.warn(
3634
+ `[fullstack-cli] npm install -g failed: ${result.error?.message ?? `exit ${result.status}`}`
3635
+ );
3636
+ process.exit(1);
3637
+ }
3638
+ console.log("[fullstack-cli] \u2713 Global CLI upgrade completed");
3639
+ }
3640
+
3641
+ // src/commands/upgrade/global-deps/index.ts
3642
+ var globalDepsCommand = {
3643
+ name: "global-deps",
3644
+ description: "Upgrade global @lark-apaas CLIs (fullstack-cli, miaoda-cli) per grayscale config",
3645
+ register(parentCommand) {
3646
+ parentCommand.command(this.name).description(this.description).option("--grayscale-config <json>", "Grayscale config JSON (injected by sandbox_console)").option("--dry-run", "Show upgrade plan without executing").option(
3647
+ "--registry <url>",
3648
+ "npm registry URL (default: https://registry.npmmirror.com/)",
3649
+ "https://registry.npmmirror.com/"
3650
+ ).action(async (options) => {
3651
+ await run5(options);
3652
+ });
3653
+ }
3654
+ };
3655
+
3447
3656
  // src/commands/upgrade/index.ts
3448
3657
  var upgradeCommand = {
3449
3658
  name: "upgrade",
@@ -3453,13 +3662,14 @@ var upgradeCommand = {
3453
3662
  await run3(options);
3454
3663
  });
3455
3664
  depsCommand.register(upgradeCmd);
3665
+ globalDepsCommand.register(upgradeCmd);
3456
3666
  }
3457
3667
  };
3458
3668
 
3459
3669
  // src/commands/action-plugin/utils.ts
3460
- import fs11 from "fs";
3461
- import path9 from "path";
3462
- import { spawnSync as spawnSync4, execSync as execSync2 } from "child_process";
3670
+ import fs13 from "fs";
3671
+ import path11 from "path";
3672
+ import { spawnSync as spawnSync6, execSync as execSync2 } from "child_process";
3463
3673
  function parsePluginName(input) {
3464
3674
  const match = input.match(/^(@[^/]+\/[^@]+)(?:@(.+))?$/);
3465
3675
  if (!match) {
@@ -3476,18 +3686,18 @@ function getProjectRoot() {
3476
3686
  return process.cwd();
3477
3687
  }
3478
3688
  function getPackageJsonPath() {
3479
- return path9.join(getProjectRoot(), "package.json");
3689
+ return path11.join(getProjectRoot(), "package.json");
3480
3690
  }
3481
3691
  function getPluginPath(pluginName) {
3482
- return path9.join(getProjectRoot(), "node_modules", pluginName);
3692
+ return path11.join(getProjectRoot(), "node_modules", pluginName);
3483
3693
  }
3484
3694
  function readPackageJson2() {
3485
3695
  const pkgPath = getPackageJsonPath();
3486
- if (!fs11.existsSync(pkgPath)) {
3696
+ if (!fs13.existsSync(pkgPath)) {
3487
3697
  throw new Error("package.json not found in current directory");
3488
3698
  }
3489
3699
  try {
3490
- const content = fs11.readFileSync(pkgPath, "utf-8");
3700
+ const content = fs13.readFileSync(pkgPath, "utf-8");
3491
3701
  return JSON.parse(content);
3492
3702
  } catch {
3493
3703
  throw new Error("Failed to parse package.json");
@@ -3495,7 +3705,7 @@ function readPackageJson2() {
3495
3705
  }
3496
3706
  function writePackageJson2(pkg2) {
3497
3707
  const pkgPath = getPackageJsonPath();
3498
- fs11.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
3708
+ fs13.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
3499
3709
  }
3500
3710
  function readActionPlugins() {
3501
3711
  const pkg2 = readPackageJson2();
@@ -3516,7 +3726,7 @@ function getInstalledPluginVersion(pluginName) {
3516
3726
  }
3517
3727
  function npmInstall(tgzPath) {
3518
3728
  console.log(`[action-plugin] Running npm install ${tgzPath}...`);
3519
- const result = spawnSync4("npm", ["install", tgzPath, "--no-save", "--no-package-lock", "--ignore-scripts"], {
3729
+ const result = spawnSync6("npm", ["install", tgzPath, "--no-save", "--no-package-lock", "--ignore-scripts"], {
3520
3730
  cwd: getProjectRoot(),
3521
3731
  stdio: "inherit"
3522
3732
  });
@@ -3528,12 +3738,12 @@ function npmInstall(tgzPath) {
3528
3738
  }
3529
3739
  }
3530
3740
  function getPackageVersion(pluginName) {
3531
- const pkgJsonPath = path9.join(getPluginPath(pluginName), "package.json");
3532
- if (!fs11.existsSync(pkgJsonPath)) {
3741
+ const pkgJsonPath = path11.join(getPluginPath(pluginName), "package.json");
3742
+ if (!fs13.existsSync(pkgJsonPath)) {
3533
3743
  return null;
3534
3744
  }
3535
3745
  try {
3536
- const content = fs11.readFileSync(pkgJsonPath, "utf-8");
3746
+ const content = fs13.readFileSync(pkgJsonPath, "utf-8");
3537
3747
  const pkg2 = JSON.parse(content);
3538
3748
  return pkg2.version || null;
3539
3749
  } catch {
@@ -3541,49 +3751,49 @@ function getPackageVersion(pluginName) {
3541
3751
  }
3542
3752
  }
3543
3753
  function readPluginPackageJson(pluginPath) {
3544
- const pkgJsonPath = path9.join(pluginPath, "package.json");
3545
- if (!fs11.existsSync(pkgJsonPath)) {
3754
+ const pkgJsonPath = path11.join(pluginPath, "package.json");
3755
+ if (!fs13.existsSync(pkgJsonPath)) {
3546
3756
  return null;
3547
3757
  }
3548
3758
  try {
3549
- const content = fs11.readFileSync(pkgJsonPath, "utf-8");
3759
+ const content = fs13.readFileSync(pkgJsonPath, "utf-8");
3550
3760
  return JSON.parse(content);
3551
3761
  } catch {
3552
3762
  return null;
3553
3763
  }
3554
3764
  }
3555
3765
  function extractTgzToNodeModules(tgzPath, pluginName) {
3556
- const nodeModulesPath = path9.join(getProjectRoot(), "node_modules");
3557
- const targetDir = path9.join(nodeModulesPath, pluginName);
3558
- const scopeDir = path9.dirname(targetDir);
3559
- if (!fs11.existsSync(scopeDir)) {
3560
- fs11.mkdirSync(scopeDir, { recursive: true });
3766
+ const nodeModulesPath = path11.join(getProjectRoot(), "node_modules");
3767
+ const targetDir = path11.join(nodeModulesPath, pluginName);
3768
+ const scopeDir = path11.dirname(targetDir);
3769
+ if (!fs13.existsSync(scopeDir)) {
3770
+ fs13.mkdirSync(scopeDir, { recursive: true });
3561
3771
  }
3562
- if (fs11.existsSync(targetDir)) {
3563
- fs11.rmSync(targetDir, { recursive: true });
3772
+ if (fs13.existsSync(targetDir)) {
3773
+ fs13.rmSync(targetDir, { recursive: true });
3564
3774
  }
3565
- const tempDir = path9.join(nodeModulesPath, ".cache", "fullstack-cli", "extract-temp");
3566
- if (fs11.existsSync(tempDir)) {
3567
- fs11.rmSync(tempDir, { recursive: true });
3775
+ const tempDir = path11.join(nodeModulesPath, ".cache", "fullstack-cli", "extract-temp");
3776
+ if (fs13.existsSync(tempDir)) {
3777
+ fs13.rmSync(tempDir, { recursive: true });
3568
3778
  }
3569
- fs11.mkdirSync(tempDir, { recursive: true });
3779
+ fs13.mkdirSync(tempDir, { recursive: true });
3570
3780
  try {
3571
3781
  execSync2(`tar -xzf "${tgzPath}" -C "${tempDir}"`, { stdio: "pipe" });
3572
- const extractedDir = path9.join(tempDir, "package");
3573
- if (fs11.existsSync(extractedDir)) {
3574
- fs11.renameSync(extractedDir, targetDir);
3782
+ const extractedDir = path11.join(tempDir, "package");
3783
+ if (fs13.existsSync(extractedDir)) {
3784
+ fs13.renameSync(extractedDir, targetDir);
3575
3785
  } else {
3576
- const files = fs11.readdirSync(tempDir);
3786
+ const files = fs13.readdirSync(tempDir);
3577
3787
  if (files.length === 1) {
3578
- fs11.renameSync(path9.join(tempDir, files[0]), targetDir);
3788
+ fs13.renameSync(path11.join(tempDir, files[0]), targetDir);
3579
3789
  } else {
3580
3790
  throw new Error("Unexpected tgz structure");
3581
3791
  }
3582
3792
  }
3583
3793
  return targetDir;
3584
3794
  } finally {
3585
- if (fs11.existsSync(tempDir)) {
3586
- fs11.rmSync(tempDir, { recursive: true });
3795
+ if (fs13.existsSync(tempDir)) {
3796
+ fs13.rmSync(tempDir, { recursive: true });
3587
3797
  }
3588
3798
  }
3589
3799
  }
@@ -3592,10 +3802,10 @@ function checkMissingPeerDeps(peerDeps) {
3592
3802
  return [];
3593
3803
  }
3594
3804
  const missing = [];
3595
- const nodeModulesPath = path9.join(getProjectRoot(), "node_modules");
3805
+ const nodeModulesPath = path11.join(getProjectRoot(), "node_modules");
3596
3806
  for (const [depName, _version] of Object.entries(peerDeps)) {
3597
- const depPath = path9.join(nodeModulesPath, depName);
3598
- if (!fs11.existsSync(depPath)) {
3807
+ const depPath = path11.join(nodeModulesPath, depName);
3808
+ if (!fs13.existsSync(depPath)) {
3599
3809
  missing.push(depName);
3600
3810
  }
3601
3811
  }
@@ -3606,7 +3816,7 @@ function installMissingDeps(deps) {
3606
3816
  return;
3607
3817
  }
3608
3818
  console.log(`[action-plugin] Installing missing dependencies: ${deps.join(", ")}`);
3609
- const result = spawnSync4("npm", ["install", ...deps, "--no-save", "--no-package-lock"], {
3819
+ const result = spawnSync6("npm", ["install", ...deps, "--no-save", "--no-package-lock"], {
3610
3820
  cwd: getProjectRoot(),
3611
3821
  stdio: "inherit"
3612
3822
  });
@@ -3619,16 +3829,16 @@ function installMissingDeps(deps) {
3619
3829
  }
3620
3830
  function removePluginDirectory(pluginName) {
3621
3831
  const pluginPath = getPluginPath(pluginName);
3622
- if (fs11.existsSync(pluginPath)) {
3623
- fs11.rmSync(pluginPath, { recursive: true });
3832
+ if (fs13.existsSync(pluginPath)) {
3833
+ fs13.rmSync(pluginPath, { recursive: true });
3624
3834
  console.log(`[action-plugin] Removed ${pluginName}`);
3625
3835
  }
3626
3836
  }
3627
3837
 
3628
3838
  // src/commands/action-plugin/api-client.ts
3629
3839
  import { HttpClient as HttpClient2 } from "@lark-apaas/http-client";
3630
- import fs12 from "fs";
3631
- import path10 from "path";
3840
+ import fs14 from "fs";
3841
+ import path12 from "path";
3632
3842
  var PLUGIN_CACHE_DIR = "node_modules/.cache/fullstack-cli/plugins";
3633
3843
  async function getPluginVersions(keys, latestOnly = true) {
3634
3844
  const client = getHttpClient();
@@ -3692,19 +3902,19 @@ async function downloadFromPublic(downloadURL) {
3692
3902
  return Buffer.from(arrayBuffer);
3693
3903
  }
3694
3904
  function getPluginCacheDir() {
3695
- return path10.join(process.cwd(), PLUGIN_CACHE_DIR);
3905
+ return path12.join(process.cwd(), PLUGIN_CACHE_DIR);
3696
3906
  }
3697
3907
  function ensureCacheDir() {
3698
3908
  const cacheDir = getPluginCacheDir();
3699
- if (!fs12.existsSync(cacheDir)) {
3700
- fs12.mkdirSync(cacheDir, { recursive: true });
3909
+ if (!fs14.existsSync(cacheDir)) {
3910
+ fs14.mkdirSync(cacheDir, { recursive: true });
3701
3911
  }
3702
3912
  }
3703
3913
  function getTempFilePath(pluginKey, version) {
3704
3914
  ensureCacheDir();
3705
3915
  const safeKey = pluginKey.replace(/[/@]/g, "_");
3706
3916
  const filename = `${safeKey}@${version}.tgz`;
3707
- return path10.join(getPluginCacheDir(), filename);
3917
+ return path12.join(getPluginCacheDir(), filename);
3708
3918
  }
3709
3919
  var MAX_RETRIES = 2;
3710
3920
  async function withRetry(operation, description, maxRetries = MAX_RETRIES) {
@@ -3741,7 +3951,7 @@ async function downloadPlugin(pluginKey, requestedVersion) {
3741
3951
  );
3742
3952
  }
3743
3953
  const tgzPath = getTempFilePath(pluginKey, pluginInfo.version);
3744
- fs12.writeFileSync(tgzPath, tgzBuffer);
3954
+ fs14.writeFileSync(tgzPath, tgzBuffer);
3745
3955
  console.log(`[action-plugin] Downloaded to ${tgzPath} (${(tgzBuffer.length / 1024).toFixed(2)} KB)`);
3746
3956
  return {
3747
3957
  tgzPath,
@@ -3755,18 +3965,18 @@ function getCachePath(pluginKey, version) {
3755
3965
  ensureCacheDir();
3756
3966
  const safeKey = pluginKey.replace(/[/@]/g, "_");
3757
3967
  const filename = `${safeKey}@${version}.tgz`;
3758
- return path10.join(getPluginCacheDir(), filename);
3968
+ return path12.join(getPluginCacheDir(), filename);
3759
3969
  }
3760
3970
  function hasCachedPlugin(pluginKey, version) {
3761
3971
  const cachePath = getCachePath(pluginKey, version);
3762
- return fs12.existsSync(cachePath);
3972
+ return fs14.existsSync(cachePath);
3763
3973
  }
3764
3974
  function listCachedPlugins() {
3765
3975
  const cacheDir = getPluginCacheDir();
3766
- if (!fs12.existsSync(cacheDir)) {
3976
+ if (!fs14.existsSync(cacheDir)) {
3767
3977
  return [];
3768
3978
  }
3769
- const files = fs12.readdirSync(cacheDir);
3979
+ const files = fs14.readdirSync(cacheDir);
3770
3980
  const result = [];
3771
3981
  for (const file of files) {
3772
3982
  if (!file.endsWith(".tgz")) continue;
@@ -3774,8 +3984,8 @@ function listCachedPlugins() {
3774
3984
  if (!match) continue;
3775
3985
  const [, rawName, version] = match;
3776
3986
  const name = rawName.replace(/^_/, "@").replace(/_/, "/");
3777
- const filePath = path10.join(cacheDir, file);
3778
- const stat = fs12.statSync(filePath);
3987
+ const filePath = path12.join(cacheDir, file);
3988
+ const stat = fs14.statSync(filePath);
3779
3989
  result.push({
3780
3990
  name,
3781
3991
  version,
@@ -3788,14 +3998,14 @@ function listCachedPlugins() {
3788
3998
  }
3789
3999
  function cleanAllCache() {
3790
4000
  const cacheDir = getPluginCacheDir();
3791
- if (!fs12.existsSync(cacheDir)) {
4001
+ if (!fs14.existsSync(cacheDir)) {
3792
4002
  return 0;
3793
4003
  }
3794
- const files = fs12.readdirSync(cacheDir);
4004
+ const files = fs14.readdirSync(cacheDir);
3795
4005
  let count = 0;
3796
4006
  for (const file of files) {
3797
4007
  if (file.endsWith(".tgz")) {
3798
- fs12.unlinkSync(path10.join(cacheDir, file));
4008
+ fs14.unlinkSync(path12.join(cacheDir, file));
3799
4009
  count++;
3800
4010
  }
3801
4011
  }
@@ -3803,21 +4013,21 @@ function cleanAllCache() {
3803
4013
  }
3804
4014
  function cleanPluginCache(pluginKey, version) {
3805
4015
  const cacheDir = getPluginCacheDir();
3806
- if (!fs12.existsSync(cacheDir)) {
4016
+ if (!fs14.existsSync(cacheDir)) {
3807
4017
  return 0;
3808
4018
  }
3809
4019
  const safeKey = pluginKey.replace(/[/@]/g, "_");
3810
- const files = fs12.readdirSync(cacheDir);
4020
+ const files = fs14.readdirSync(cacheDir);
3811
4021
  let count = 0;
3812
4022
  for (const file of files) {
3813
4023
  if (version) {
3814
4024
  if (file === `${safeKey}@${version}.tgz`) {
3815
- fs12.unlinkSync(path10.join(cacheDir, file));
4025
+ fs14.unlinkSync(path12.join(cacheDir, file));
3816
4026
  count++;
3817
4027
  }
3818
4028
  } else {
3819
4029
  if (file.startsWith(`${safeKey}@`) && file.endsWith(".tgz")) {
3820
- fs12.unlinkSync(path10.join(cacheDir, file));
4030
+ fs14.unlinkSync(path12.join(cacheDir, file));
3821
4031
  count++;
3822
4032
  }
3823
4033
  }
@@ -4244,40 +4454,40 @@ var actionPluginCommandGroup = {
4244
4454
  };
4245
4455
 
4246
4456
  // src/commands/capability/utils.ts
4247
- import fs13 from "fs";
4457
+ import fs15 from "fs";
4248
4458
  import { createRequire as createRequire2 } from "module";
4249
- import path11 from "path";
4459
+ import path13 from "path";
4250
4460
  var CAPABILITIES_DIR = "server/capabilities";
4251
4461
  function getProjectRoot2() {
4252
4462
  return process.cwd();
4253
4463
  }
4254
4464
  function getCapabilitiesDir() {
4255
- return path11.join(getProjectRoot2(), CAPABILITIES_DIR);
4465
+ return path13.join(getProjectRoot2(), CAPABILITIES_DIR);
4256
4466
  }
4257
4467
  function getCapabilityPath(id) {
4258
- return path11.join(getCapabilitiesDir(), `${id}.json`);
4468
+ return path13.join(getCapabilitiesDir(), `${id}.json`);
4259
4469
  }
4260
4470
  function getPluginManifestPath(pluginKey) {
4261
- return path11.join(getProjectRoot2(), "node_modules", pluginKey, "manifest.json");
4471
+ return path13.join(getProjectRoot2(), "node_modules", pluginKey, "manifest.json");
4262
4472
  }
4263
4473
  function capabilitiesDirExists() {
4264
- return fs13.existsSync(getCapabilitiesDir());
4474
+ return fs15.existsSync(getCapabilitiesDir());
4265
4475
  }
4266
4476
  function listCapabilityIds() {
4267
4477
  const dir = getCapabilitiesDir();
4268
- if (!fs13.existsSync(dir)) {
4478
+ if (!fs15.existsSync(dir)) {
4269
4479
  return [];
4270
4480
  }
4271
- const files = fs13.readdirSync(dir);
4481
+ const files = fs15.readdirSync(dir);
4272
4482
  return files.filter((f) => f.endsWith(".json") && f !== "capabilities.json").map((f) => f.replace(/\.json$/, ""));
4273
4483
  }
4274
4484
  function readCapability(id) {
4275
4485
  const filePath = getCapabilityPath(id);
4276
- if (!fs13.existsSync(filePath)) {
4486
+ if (!fs15.existsSync(filePath)) {
4277
4487
  throw new Error(`Capability not found: ${id}`);
4278
4488
  }
4279
4489
  try {
4280
- const content = fs13.readFileSync(filePath, "utf-8");
4490
+ const content = fs15.readFileSync(filePath, "utf-8");
4281
4491
  return JSON.parse(content);
4282
4492
  } catch (error) {
4283
4493
  if (error instanceof SyntaxError) {
@@ -4304,11 +4514,11 @@ function readAllCapabilities() {
4304
4514
  }
4305
4515
  function readPluginManifest(pluginKey) {
4306
4516
  const manifestPath = getPluginManifestPath(pluginKey);
4307
- if (!fs13.existsSync(manifestPath)) {
4517
+ if (!fs15.existsSync(manifestPath)) {
4308
4518
  throw new Error(`Plugin not installed: ${pluginKey} (manifest.json not found)`);
4309
4519
  }
4310
4520
  try {
4311
- const content = fs13.readFileSync(manifestPath, "utf-8");
4521
+ const content = fs15.readFileSync(manifestPath, "utf-8");
4312
4522
  return JSON.parse(content);
4313
4523
  } catch (error) {
4314
4524
  if (error instanceof SyntaxError) {
@@ -4325,7 +4535,7 @@ function hasValidParamsSchema(paramsSchema) {
4325
4535
  }
4326
4536
  async function loadPlugin(pluginKey) {
4327
4537
  try {
4328
- const userRequire = createRequire2(path11.join(getProjectRoot2(), "package.json"));
4538
+ const userRequire = createRequire2(path13.join(getProjectRoot2(), "package.json"));
4329
4539
  const resolvedPath = userRequire.resolve(pluginKey);
4330
4540
  const pluginModule = await import(resolvedPath);
4331
4541
  const pluginPackage = pluginModule.default ?? pluginModule;
@@ -4488,8 +4698,8 @@ var capabilityCommandGroup = {
4488
4698
  import { execFile } from "child_process";
4489
4699
 
4490
4700
  // src/commands/component/registry-preparer.ts
4491
- import fs14 from "fs";
4492
- import path12 from "path";
4701
+ import fs16 from "fs";
4702
+ import path14 from "path";
4493
4703
  import os from "os";
4494
4704
 
4495
4705
  // src/commands/component/service.ts
@@ -4545,7 +4755,7 @@ async function sendInstallEvent(key) {
4545
4755
  }
4546
4756
 
4547
4757
  // src/commands/component/registry-preparer.ts
4548
- var REGISTRY_TEMP_DIR = path12.join(os.tmpdir(), "miaoda-registry");
4758
+ var REGISTRY_TEMP_DIR = path14.join(os.tmpdir(), "miaoda-registry");
4549
4759
  function parseComponentKey(key) {
4550
4760
  const match = key.match(/^@([^/]+)\/(.+)$/);
4551
4761
  if (!match) {
@@ -4557,11 +4767,11 @@ function parseComponentKey(key) {
4557
4767
  }
4558
4768
  function getLocalRegistryPath(key) {
4559
4769
  const { scope, name } = parseComponentKey(key);
4560
- return path12.join(REGISTRY_TEMP_DIR, scope, `${name}.json`);
4770
+ return path14.join(REGISTRY_TEMP_DIR, scope, `${name}.json`);
4561
4771
  }
4562
4772
  function ensureDir(dirPath) {
4563
- if (!fs14.existsSync(dirPath)) {
4564
- fs14.mkdirSync(dirPath, { recursive: true });
4773
+ if (!fs16.existsSync(dirPath)) {
4774
+ fs16.mkdirSync(dirPath, { recursive: true });
4565
4775
  }
4566
4776
  }
4567
4777
  async function prepareRecursive(key, visited) {
@@ -4594,8 +4804,8 @@ async function prepareRecursive(key, visited) {
4594
4804
  registryDependencies: deps.map((dep) => getLocalRegistryPath(dep))
4595
4805
  };
4596
4806
  const localPath = getLocalRegistryPath(key);
4597
- ensureDir(path12.dirname(localPath));
4598
- fs14.writeFileSync(localPath, JSON.stringify(rewrittenItem, null, 2), "utf-8");
4807
+ ensureDir(path14.dirname(localPath));
4808
+ fs16.writeFileSync(localPath, JSON.stringify(rewrittenItem, null, 2), "utf-8");
4599
4809
  debug("\u4FDD\u5B58\u5230: %s", localPath);
4600
4810
  }
4601
4811
  async function prepareComponentRegistryItems(id) {
@@ -4605,18 +4815,18 @@ async function prepareComponentRegistryItems(id) {
4605
4815
  }
4606
4816
  function cleanupTempDir() {
4607
4817
  try {
4608
- if (fs14.existsSync(REGISTRY_TEMP_DIR)) {
4609
- fs14.rmSync(REGISTRY_TEMP_DIR, { recursive: true, force: true });
4818
+ if (fs16.existsSync(REGISTRY_TEMP_DIR)) {
4819
+ fs16.rmSync(REGISTRY_TEMP_DIR, { recursive: true, force: true });
4610
4820
  }
4611
4821
  } catch {
4612
4822
  }
4613
4823
  }
4614
4824
  function getDownloadedRegistryItem(itemId) {
4615
4825
  const localPath = getLocalRegistryPath(itemId);
4616
- if (!fs14.existsSync(localPath)) {
4826
+ if (!fs16.existsSync(localPath)) {
4617
4827
  return null;
4618
4828
  }
4619
- const content = fs14.readFileSync(localPath, "utf-8");
4829
+ const content = fs16.readFileSync(localPath, "utf-8");
4620
4830
  return JSON.parse(content);
4621
4831
  }
4622
4832
 
@@ -4784,58 +4994,58 @@ var componentCommandGroup = {
4784
4994
  };
4785
4995
 
4786
4996
  // src/commands/migration/version-manager.ts
4787
- import fs15 from "fs";
4788
- import path13 from "path";
4997
+ import fs17 from "fs";
4998
+ import path15 from "path";
4789
4999
  var PACKAGE_JSON = "package.json";
4790
5000
  var VERSION_FIELD = "migrationVersion";
4791
5001
  function getPackageJsonPath2() {
4792
- return path13.join(process.cwd(), PACKAGE_JSON);
5002
+ return path15.join(process.cwd(), PACKAGE_JSON);
4793
5003
  }
4794
5004
  function getCurrentVersion() {
4795
5005
  const pkgPath = getPackageJsonPath2();
4796
- if (!fs15.existsSync(pkgPath)) {
5006
+ if (!fs17.existsSync(pkgPath)) {
4797
5007
  throw new Error("package.json not found");
4798
5008
  }
4799
- const pkg2 = JSON.parse(fs15.readFileSync(pkgPath, "utf-8"));
5009
+ const pkg2 = JSON.parse(fs17.readFileSync(pkgPath, "utf-8"));
4800
5010
  return pkg2[VERSION_FIELD] ?? 0;
4801
5011
  }
4802
5012
  function setCurrentVersion(version) {
4803
5013
  const pkgPath = getPackageJsonPath2();
4804
- const pkg2 = JSON.parse(fs15.readFileSync(pkgPath, "utf-8"));
5014
+ const pkg2 = JSON.parse(fs17.readFileSync(pkgPath, "utf-8"));
4805
5015
  pkg2[VERSION_FIELD] = version;
4806
- fs15.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
5016
+ fs17.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
4807
5017
  }
4808
5018
 
4809
5019
  // src/commands/migration/versions/v001_capability/json-migrator/detector.ts
4810
- import fs17 from "fs";
4811
- import path15 from "path";
5020
+ import fs19 from "fs";
5021
+ import path17 from "path";
4812
5022
 
4813
5023
  // src/commands/migration/versions/v001_capability/utils.ts
4814
- import fs16 from "fs";
4815
- import path14 from "path";
5024
+ import fs18 from "fs";
5025
+ import path16 from "path";
4816
5026
  var CAPABILITIES_DIR2 = "server/capabilities";
4817
5027
  function getProjectRoot3() {
4818
5028
  return process.cwd();
4819
5029
  }
4820
5030
  function getCapabilitiesDir2() {
4821
- return path14.join(getProjectRoot3(), CAPABILITIES_DIR2);
5031
+ return path16.join(getProjectRoot3(), CAPABILITIES_DIR2);
4822
5032
  }
4823
5033
  function getPluginManifestPath2(pluginKey) {
4824
- return path14.join(getProjectRoot3(), "node_modules", pluginKey, "manifest.json");
5034
+ return path16.join(getProjectRoot3(), "node_modules", pluginKey, "manifest.json");
4825
5035
  }
4826
5036
 
4827
5037
  // src/commands/migration/versions/v001_capability/json-migrator/detector.ts
4828
5038
  function detectJsonMigration() {
4829
5039
  const capabilitiesDir = getCapabilitiesDir2();
4830
- const oldFilePath = path15.join(capabilitiesDir, "capabilities.json");
4831
- if (!fs17.existsSync(oldFilePath)) {
5040
+ const oldFilePath = path17.join(capabilitiesDir, "capabilities.json");
5041
+ if (!fs19.existsSync(oldFilePath)) {
4832
5042
  return {
4833
5043
  needsMigration: false,
4834
5044
  reason: "capabilities.json not found"
4835
5045
  };
4836
5046
  }
4837
5047
  try {
4838
- const content = fs17.readFileSync(oldFilePath, "utf-8");
5048
+ const content = fs19.readFileSync(oldFilePath, "utf-8");
4839
5049
  const parsed = JSON.parse(content);
4840
5050
  if (!Array.isArray(parsed)) {
4841
5051
  return {
@@ -4886,8 +5096,8 @@ async function check(options) {
4886
5096
  }
4887
5097
 
4888
5098
  // src/commands/migration/versions/v001_capability/json-migrator/index.ts
4889
- import fs18 from "fs";
4890
- import path16 from "path";
5099
+ import fs20 from "fs";
5100
+ import path18 from "path";
4891
5101
 
4892
5102
  // src/commands/migration/versions/v001_capability/mapping.ts
4893
5103
  var DEFAULT_PLUGIN_VERSION = "1.0.0";
@@ -5117,18 +5327,18 @@ function transformCapabilities(oldCapabilities) {
5117
5327
  // src/commands/migration/versions/v001_capability/json-migrator/index.ts
5118
5328
  function loadExistingCapabilities() {
5119
5329
  const capabilitiesDir = getCapabilitiesDir2();
5120
- if (!fs18.existsSync(capabilitiesDir)) {
5330
+ if (!fs20.existsSync(capabilitiesDir)) {
5121
5331
  return [];
5122
5332
  }
5123
- const files = fs18.readdirSync(capabilitiesDir);
5333
+ const files = fs20.readdirSync(capabilitiesDir);
5124
5334
  const capabilities = [];
5125
5335
  for (const file of files) {
5126
5336
  if (file === "capabilities.json" || !file.endsWith(".json")) {
5127
5337
  continue;
5128
5338
  }
5129
5339
  try {
5130
- const filePath = path16.join(capabilitiesDir, file);
5131
- const content = fs18.readFileSync(filePath, "utf-8");
5340
+ const filePath = path18.join(capabilitiesDir, file);
5341
+ const content = fs20.readFileSync(filePath, "utf-8");
5132
5342
  const capability = JSON.parse(content);
5133
5343
  if (capability.id && capability.pluginKey) {
5134
5344
  capabilities.push(capability);
@@ -5186,9 +5396,9 @@ async function migrateJsonFiles(options) {
5186
5396
  }
5187
5397
  const capabilitiesDir = getCapabilitiesDir2();
5188
5398
  for (const cap of newCapabilities) {
5189
- const filePath = path16.join(capabilitiesDir, `${cap.id}.json`);
5399
+ const filePath = path18.join(capabilitiesDir, `${cap.id}.json`);
5190
5400
  const content = JSON.stringify(cap, null, 2);
5191
- fs18.writeFileSync(filePath, content, "utf-8");
5401
+ fs20.writeFileSync(filePath, content, "utf-8");
5192
5402
  console.log(` \u2713 Created: ${cap.id}.json`);
5193
5403
  }
5194
5404
  return {
@@ -5200,11 +5410,11 @@ async function migrateJsonFiles(options) {
5200
5410
  }
5201
5411
 
5202
5412
  // src/commands/migration/versions/v001_capability/plugin-installer/detector.ts
5203
- import fs19 from "fs";
5413
+ import fs21 from "fs";
5204
5414
  function isPluginInstalled2(pluginKey) {
5205
5415
  const actionPlugins = readActionPlugins();
5206
5416
  const manifestPath = getPluginManifestPath2(pluginKey);
5207
- return fs19.existsSync(manifestPath) && !!actionPlugins[pluginKey];
5417
+ return fs21.existsSync(manifestPath) && !!actionPlugins[pluginKey];
5208
5418
  }
5209
5419
  function detectPluginsToInstall(capabilities) {
5210
5420
  const pluginKeys = /* @__PURE__ */ new Set();
@@ -5280,12 +5490,12 @@ async function installPlugins(capabilities, options) {
5280
5490
  }
5281
5491
 
5282
5492
  // src/commands/migration/versions/v001_capability/code-migrator/index.ts
5283
- import path18 from "path";
5493
+ import path20 from "path";
5284
5494
  import { Project as Project3 } from "ts-morph";
5285
5495
 
5286
5496
  // src/commands/migration/versions/v001_capability/code-migrator/scanner.ts
5287
- import fs20 from "fs";
5288
- import path17 from "path";
5497
+ import fs22 from "fs";
5498
+ import path19 from "path";
5289
5499
  var EXCLUDED_DIRS = [
5290
5500
  "node_modules",
5291
5501
  "dist",
@@ -5300,9 +5510,9 @@ var EXCLUDED_PATTERNS = [
5300
5510
  /\.d\.ts$/
5301
5511
  ];
5302
5512
  function scanDirectory(dir, files = []) {
5303
- const entries = fs20.readdirSync(dir, { withFileTypes: true });
5513
+ const entries = fs22.readdirSync(dir, { withFileTypes: true });
5304
5514
  for (const entry of entries) {
5305
- const fullPath = path17.join(dir, entry.name);
5515
+ const fullPath = path19.join(dir, entry.name);
5306
5516
  if (entry.isDirectory()) {
5307
5517
  if (EXCLUDED_DIRS.includes(entry.name)) {
5308
5518
  continue;
@@ -5318,14 +5528,14 @@ function scanDirectory(dir, files = []) {
5318
5528
  return files;
5319
5529
  }
5320
5530
  function scanServerFiles() {
5321
- const serverDir = path17.join(getProjectRoot3(), "server");
5322
- if (!fs20.existsSync(serverDir)) {
5531
+ const serverDir = path19.join(getProjectRoot3(), "server");
5532
+ if (!fs22.existsSync(serverDir)) {
5323
5533
  return [];
5324
5534
  }
5325
5535
  return scanDirectory(serverDir);
5326
5536
  }
5327
5537
  function hasCapabilityImport(filePath) {
5328
- const content = fs20.readFileSync(filePath, "utf-8");
5538
+ const content = fs22.readFileSync(filePath, "utf-8");
5329
5539
  return /import\s+.*from\s+['"][^'"]*capabilities[^'"]*['"]/.test(content);
5330
5540
  }
5331
5541
  function scanFilesToMigrate() {
@@ -5702,7 +5912,7 @@ function analyzeFile(project, filePath, actionNameMap) {
5702
5912
  const callSites = analyzeCallSites(sourceFile, imports);
5703
5913
  const classInfo = analyzeClass(sourceFile);
5704
5914
  const { canMigrate, reason } = canAutoMigrate(classInfo);
5705
- const relativePath = path18.relative(getProjectRoot3(), filePath);
5915
+ const relativePath = path20.relative(getProjectRoot3(), filePath);
5706
5916
  return {
5707
5917
  filePath: relativePath,
5708
5918
  imports,
@@ -5713,7 +5923,7 @@ function analyzeFile(project, filePath, actionNameMap) {
5713
5923
  };
5714
5924
  }
5715
5925
  function migrateFile(project, analysis, dryRun) {
5716
- const absolutePath = path18.join(getProjectRoot3(), analysis.filePath);
5926
+ const absolutePath = path20.join(getProjectRoot3(), analysis.filePath);
5717
5927
  if (!analysis.canAutoMigrate) {
5718
5928
  return {
5719
5929
  filePath: analysis.filePath,
@@ -5816,17 +6026,17 @@ function getSuggestion(analysis) {
5816
6026
  }
5817
6027
 
5818
6028
  // src/commands/migration/versions/v001_capability/cleanup.ts
5819
- import fs21 from "fs";
5820
- import path19 from "path";
6029
+ import fs23 from "fs";
6030
+ import path21 from "path";
5821
6031
  function cleanupOldFiles(capabilities, dryRun) {
5822
6032
  const deletedFiles = [];
5823
6033
  const errors = [];
5824
6034
  const capabilitiesDir = getCapabilitiesDir2();
5825
- const oldJsonPath = path19.join(capabilitiesDir, "capabilities.json");
5826
- if (fs21.existsSync(oldJsonPath)) {
6035
+ const oldJsonPath = path21.join(capabilitiesDir, "capabilities.json");
6036
+ if (fs23.existsSync(oldJsonPath)) {
5827
6037
  try {
5828
6038
  if (!dryRun) {
5829
- fs21.unlinkSync(oldJsonPath);
6039
+ fs23.unlinkSync(oldJsonPath);
5830
6040
  }
5831
6041
  deletedFiles.push("capabilities.json");
5832
6042
  } catch (error) {
@@ -5834,11 +6044,11 @@ function cleanupOldFiles(capabilities, dryRun) {
5834
6044
  }
5835
6045
  }
5836
6046
  for (const cap of capabilities) {
5837
- const tsFilePath = path19.join(capabilitiesDir, `${cap.id}.ts`);
5838
- if (fs21.existsSync(tsFilePath)) {
6047
+ const tsFilePath = path21.join(capabilitiesDir, `${cap.id}.ts`);
6048
+ if (fs23.existsSync(tsFilePath)) {
5839
6049
  try {
5840
6050
  if (!dryRun) {
5841
- fs21.unlinkSync(tsFilePath);
6051
+ fs23.unlinkSync(tsFilePath);
5842
6052
  }
5843
6053
  deletedFiles.push(`${cap.id}.ts`);
5844
6054
  } catch (error) {
@@ -5854,8 +6064,8 @@ function cleanupOldFiles(capabilities, dryRun) {
5854
6064
  }
5855
6065
 
5856
6066
  // src/commands/migration/versions/v001_capability/report-generator.ts
5857
- import fs22 from "fs";
5858
- import path20 from "path";
6067
+ import fs24 from "fs";
6068
+ import path22 from "path";
5859
6069
  var REPORT_FILE = "capability-migration-report.md";
5860
6070
  function printSummary(result) {
5861
6071
  const { jsonMigration, pluginInstallation, codeMigration, cleanup } = result;
@@ -6018,15 +6228,15 @@ async function generateReport(result) {
6018
6228
  }
6019
6229
  lines.push("");
6020
6230
  const logDir = process.env.LOG_DIR || "logs";
6021
- if (!fs22.existsSync(logDir)) {
6231
+ if (!fs24.existsSync(logDir)) {
6022
6232
  return;
6023
6233
  }
6024
- const reportDir = path20.join(logDir, "migration");
6025
- if (!fs22.existsSync(reportDir)) {
6026
- fs22.mkdirSync(reportDir, { recursive: true });
6234
+ const reportDir = path22.join(logDir, "migration");
6235
+ if (!fs24.existsSync(reportDir)) {
6236
+ fs24.mkdirSync(reportDir, { recursive: true });
6027
6237
  }
6028
- const reportPath = path20.join(reportDir, REPORT_FILE);
6029
- fs22.writeFileSync(reportPath, lines.join("\n"), "utf-8");
6238
+ const reportPath = path22.join(reportDir, REPORT_FILE);
6239
+ fs24.writeFileSync(reportPath, lines.join("\n"), "utf-8");
6030
6240
  console.log(`\u{1F4C4} Report generated: ${reportPath}`);
6031
6241
  }
6032
6242
 
@@ -6203,7 +6413,7 @@ function buildResult(jsonMigration, pluginInstallation, codeMigration, cleanup)
6203
6413
  }
6204
6414
 
6205
6415
  // src/commands/migration/versions/v001_capability/run.ts
6206
- async function run5(options) {
6416
+ async function run6(options) {
6207
6417
  try {
6208
6418
  const migrationOptions = {
6209
6419
  dryRun: options.dryRun ?? false
@@ -6268,7 +6478,7 @@ var v001CapabilityMigration = {
6268
6478
  name: "capability",
6269
6479
  description: "Migrate capability configurations from old format (capabilities.json array) to new format (individual JSON files)",
6270
6480
  check,
6271
- run: run5
6481
+ run: run6
6272
6482
  };
6273
6483
 
6274
6484
  // src/commands/migration/versions/index.ts
@@ -6558,10 +6768,10 @@ var migrationCommand = {
6558
6768
  };
6559
6769
 
6560
6770
  // src/commands/read-logs/index.ts
6561
- import path21 from "path";
6771
+ import path23 from "path";
6562
6772
 
6563
6773
  // src/commands/read-logs/std-utils.ts
6564
- import fs23 from "fs";
6774
+ import fs25 from "fs";
6565
6775
  function formatStdPrefixTime(localTime) {
6566
6776
  const match = localTime.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/);
6567
6777
  if (!match) return localTime;
@@ -6591,11 +6801,11 @@ function stripPrefixFromStdLine(line) {
6591
6801
  return `[${time}] ${content}`;
6592
6802
  }
6593
6803
  function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarker) {
6594
- const stat = fs23.statSync(filePath);
6804
+ const stat = fs25.statSync(filePath);
6595
6805
  if (stat.size === 0) {
6596
6806
  return { lines: [], markerFound: false, totalLinesCount: 0 };
6597
6807
  }
6598
- const fd = fs23.openSync(filePath, "r");
6808
+ const fd = fs25.openSync(filePath, "r");
6599
6809
  const chunkSize = 64 * 1024;
6600
6810
  let position = stat.size;
6601
6811
  let remainder = "";
@@ -6609,7 +6819,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
6609
6819
  const length = Math.min(chunkSize, position);
6610
6820
  position -= length;
6611
6821
  const buffer = Buffer.alloc(length);
6612
- fs23.readSync(fd, buffer, 0, length, position);
6822
+ fs25.readSync(fd, buffer, 0, length, position);
6613
6823
  let chunk = buffer.toString("utf8");
6614
6824
  if (remainder) {
6615
6825
  chunk += remainder;
@@ -6651,7 +6861,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
6651
6861
  }
6652
6862
  }
6653
6863
  } finally {
6654
- fs23.closeSync(fd);
6864
+ fs25.closeSync(fd);
6655
6865
  }
6656
6866
  return { lines: collected.reverse(), markerFound, totalLinesCount };
6657
6867
  }
@@ -6672,21 +6882,21 @@ function readServerStdSegment(filePath, maxLines, offset) {
6672
6882
  }
6673
6883
 
6674
6884
  // src/commands/read-logs/tail.ts
6675
- import fs24 from "fs";
6885
+ import fs26 from "fs";
6676
6886
  function fileExists(filePath) {
6677
6887
  try {
6678
- fs24.accessSync(filePath, fs24.constants.F_OK | fs24.constants.R_OK);
6888
+ fs26.accessSync(filePath, fs26.constants.F_OK | fs26.constants.R_OK);
6679
6889
  return true;
6680
6890
  } catch {
6681
6891
  return false;
6682
6892
  }
6683
6893
  }
6684
6894
  function readFileTailLines(filePath, maxLines) {
6685
- const stat = fs24.statSync(filePath);
6895
+ const stat = fs26.statSync(filePath);
6686
6896
  if (stat.size === 0) {
6687
6897
  return [];
6688
6898
  }
6689
- const fd = fs24.openSync(filePath, "r");
6899
+ const fd = fs26.openSync(filePath, "r");
6690
6900
  const chunkSize = 64 * 1024;
6691
6901
  const chunks = [];
6692
6902
  let position = stat.size;
@@ -6696,13 +6906,13 @@ function readFileTailLines(filePath, maxLines) {
6696
6906
  const length = Math.min(chunkSize, position);
6697
6907
  position -= length;
6698
6908
  const buffer = Buffer.alloc(length);
6699
- fs24.readSync(fd, buffer, 0, length, position);
6909
+ fs26.readSync(fd, buffer, 0, length, position);
6700
6910
  chunks.unshift(buffer.toString("utf8"));
6701
6911
  const chunkLines = buffer.toString("utf8").split("\n").length - 1;
6702
6912
  collectedLines += chunkLines;
6703
6913
  }
6704
6914
  } finally {
6705
- fs24.closeSync(fd);
6915
+ fs26.closeSync(fd);
6706
6916
  }
6707
6917
  const content = chunks.join("");
6708
6918
  const allLines = content.split("\n");
@@ -6718,11 +6928,11 @@ function readFileTailLines(filePath, maxLines) {
6718
6928
  return allLines.slice(allLines.length - maxLines);
6719
6929
  }
6720
6930
  function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
6721
- const stat = fs24.statSync(filePath);
6931
+ const stat = fs26.statSync(filePath);
6722
6932
  if (stat.size === 0) {
6723
6933
  return { lines: [], totalLinesCount: 0 };
6724
6934
  }
6725
- const fd = fs24.openSync(filePath, "r");
6935
+ const fd = fs26.openSync(filePath, "r");
6726
6936
  const chunkSize = 64 * 1024;
6727
6937
  let position = stat.size;
6728
6938
  let remainder = "";
@@ -6734,7 +6944,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
6734
6944
  const length = Math.min(chunkSize, position);
6735
6945
  position -= length;
6736
6946
  const buffer = Buffer.alloc(length);
6737
- fs24.readSync(fd, buffer, 0, length, position);
6947
+ fs26.readSync(fd, buffer, 0, length, position);
6738
6948
  let chunk = buffer.toString("utf8");
6739
6949
  if (remainder) {
6740
6950
  chunk += remainder;
@@ -6765,7 +6975,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
6765
6975
  }
6766
6976
  }
6767
6977
  } finally {
6768
- fs24.closeSync(fd);
6978
+ fs26.closeSync(fd);
6769
6979
  }
6770
6980
  return { lines: collected.reverse(), totalLinesCount };
6771
6981
  }
@@ -6907,7 +7117,7 @@ function readDevStdSegment(filePath, maxLines, offset) {
6907
7117
  }
6908
7118
 
6909
7119
  // src/commands/read-logs/json-lines.ts
6910
- import fs25 from "fs";
7120
+ import fs27 from "fs";
6911
7121
  function normalizePid(value) {
6912
7122
  if (typeof value === "number") {
6913
7123
  return String(value);
@@ -6958,11 +7168,11 @@ function buildWantedLevelSet(levels) {
6958
7168
  return set.size > 0 ? set : null;
6959
7169
  }
6960
7170
  function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
6961
- const stat = fs25.statSync(filePath);
7171
+ const stat = fs27.statSync(filePath);
6962
7172
  if (stat.size === 0) {
6963
7173
  return { lines: [], totalLinesCount: 0 };
6964
7174
  }
6965
- const fd = fs25.openSync(filePath, "r");
7175
+ const fd = fs27.openSync(filePath, "r");
6966
7176
  const chunkSize = 64 * 1024;
6967
7177
  let position = stat.size;
6968
7178
  let remainder = "";
@@ -6977,7 +7187,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
6977
7187
  const length = Math.min(chunkSize, position);
6978
7188
  position -= length;
6979
7189
  const buffer = Buffer.alloc(length);
6980
- fs25.readSync(fd, buffer, 0, length, position);
7190
+ fs27.readSync(fd, buffer, 0, length, position);
6981
7191
  let chunk = buffer.toString("utf8");
6982
7192
  if (remainder) {
6983
7193
  chunk += remainder;
@@ -7039,7 +7249,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
7039
7249
  }
7040
7250
  }
7041
7251
  } finally {
7042
- fs25.closeSync(fd);
7252
+ fs27.closeSync(fd);
7043
7253
  }
7044
7254
  return { lines: collected.reverse(), totalLinesCount };
7045
7255
  }
@@ -7082,11 +7292,11 @@ function extractTraceId(obj) {
7082
7292
  function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
7083
7293
  const wanted = traceId.trim();
7084
7294
  if (!wanted) return { lines: [], totalLinesCount: 0 };
7085
- const stat = fs25.statSync(filePath);
7295
+ const stat = fs27.statSync(filePath);
7086
7296
  if (stat.size === 0) {
7087
7297
  return { lines: [], totalLinesCount: 0 };
7088
7298
  }
7089
- const fd = fs25.openSync(filePath, "r");
7299
+ const fd = fs27.openSync(filePath, "r");
7090
7300
  const chunkSize = 64 * 1024;
7091
7301
  let position = stat.size;
7092
7302
  let remainder = "";
@@ -7099,7 +7309,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
7099
7309
  const length = Math.min(chunkSize, position);
7100
7310
  position -= length;
7101
7311
  const buffer = Buffer.alloc(length);
7102
- fs25.readSync(fd, buffer, 0, length, position);
7312
+ fs27.readSync(fd, buffer, 0, length, position);
7103
7313
  let chunk = buffer.toString("utf8");
7104
7314
  if (remainder) {
7105
7315
  chunk += remainder;
@@ -7152,7 +7362,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
7152
7362
  }
7153
7363
  }
7154
7364
  } finally {
7155
- fs25.closeSync(fd);
7365
+ fs27.closeSync(fd);
7156
7366
  }
7157
7367
  return { lines: collected.reverse(), totalLinesCount };
7158
7368
  }
@@ -7161,11 +7371,11 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
7161
7371
  if (!wantedLevelSet) {
7162
7372
  return { lines: [], totalLinesCount: 0 };
7163
7373
  }
7164
- const stat = fs25.statSync(filePath);
7374
+ const stat = fs27.statSync(filePath);
7165
7375
  if (stat.size === 0) {
7166
7376
  return { lines: [], totalLinesCount: 0 };
7167
7377
  }
7168
- const fd = fs25.openSync(filePath, "r");
7378
+ const fd = fs27.openSync(filePath, "r");
7169
7379
  const chunkSize = 64 * 1024;
7170
7380
  let position = stat.size;
7171
7381
  let remainder = "";
@@ -7177,7 +7387,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
7177
7387
  const length = Math.min(chunkSize, position);
7178
7388
  position -= length;
7179
7389
  const buffer = Buffer.alloc(length);
7180
- fs25.readSync(fd, buffer, 0, length, position);
7390
+ fs27.readSync(fd, buffer, 0, length, position);
7181
7391
  let chunk = buffer.toString("utf8");
7182
7392
  if (remainder) {
7183
7393
  chunk += remainder;
@@ -7224,7 +7434,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
7224
7434
  }
7225
7435
  }
7226
7436
  } finally {
7227
- fs25.closeSync(fd);
7437
+ fs27.closeSync(fd);
7228
7438
  }
7229
7439
  return { lines: collected.reverse(), totalLinesCount };
7230
7440
  }
@@ -7458,34 +7668,34 @@ async function readLogsJsonResult(options) {
7458
7668
  };
7459
7669
  }
7460
7670
  function resolveLogFilePath(logDir, type) {
7461
- const base = path21.isAbsolute(logDir) ? logDir : path21.join(process.cwd(), logDir);
7671
+ const base = path23.isAbsolute(logDir) ? logDir : path23.join(process.cwd(), logDir);
7462
7672
  if (type === "server") {
7463
- return path21.join(base, "server.log");
7673
+ return path23.join(base, "server.log");
7464
7674
  }
7465
7675
  if (type === "trace") {
7466
- return path21.join(base, "trace.log");
7676
+ return path23.join(base, "trace.log");
7467
7677
  }
7468
7678
  if (type === "server-std") {
7469
- return path21.join(base, "server.std.log");
7679
+ return path23.join(base, "server.std.log");
7470
7680
  }
7471
7681
  if (type === "client-std") {
7472
- return path21.join(base, "client.std.log");
7682
+ return path23.join(base, "client.std.log");
7473
7683
  }
7474
7684
  if (type === "dev") {
7475
- return path21.join(base, "dev.log");
7685
+ return path23.join(base, "dev.log");
7476
7686
  }
7477
7687
  if (type === "dev-std") {
7478
- return path21.join(base, "dev.std.log");
7688
+ return path23.join(base, "dev.std.log");
7479
7689
  }
7480
7690
  if (type === "install-dep-std") {
7481
- return path21.join(base, "install-dep.std.log");
7691
+ return path23.join(base, "install-dep.std.log");
7482
7692
  }
7483
7693
  if (type === "browser") {
7484
- return path21.join(base, "browser.log");
7694
+ return path23.join(base, "browser.log");
7485
7695
  }
7486
7696
  throw new Error(`Unsupported log type: ${type}`);
7487
7697
  }
7488
- async function run6(options) {
7698
+ async function run7(options) {
7489
7699
  const result = await readLogsJsonResult(options);
7490
7700
  process.stdout.write(JSON.stringify(result) + "\n");
7491
7701
  }
@@ -7527,7 +7737,7 @@ var readLogsCommand = {
7527
7737
  const offset = parseNonNegativeInt(rawOptions.offset, "--offset");
7528
7738
  const traceId = typeof rawOptions.traceId === "string" ? rawOptions.traceId : void 0;
7529
7739
  const levels = parseCommaSeparatedList(rawOptions.level);
7530
- await run6({ logDir, type, maxLines, offset, traceId, levels });
7740
+ await run7({ logDir, type, maxLines, offset, traceId, levels });
7531
7741
  } catch (error) {
7532
7742
  const message = error instanceof Error ? error.message : String(error);
7533
7743
  process.stderr.write(message + "\n");
@@ -7658,9 +7868,9 @@ function camelToKebab(str) {
7658
7868
  }
7659
7869
 
7660
7870
  // src/commands/build/upload-static.handler.ts
7661
- import * as fs26 from "fs";
7871
+ import * as fs28 from "fs";
7662
7872
  import * as os2 from "os";
7663
- import * as path22 from "path";
7873
+ import * as path24 from "path";
7664
7874
  import { execFileSync } from "child_process";
7665
7875
  function readCredentialsFromEnv() {
7666
7876
  const uploadPrefix = process.env.STATIC_UPLOAD_PREFIX;
@@ -7684,8 +7894,8 @@ async function uploadStatic(options) {
7684
7894
  endpoint = UPLOAD_STATIC_DEFAULTS.endpoint,
7685
7895
  region = UPLOAD_STATIC_DEFAULTS.region
7686
7896
  } = options;
7687
- const resolvedStaticDir = path22.resolve(staticDir);
7688
- if (!fs26.existsSync(resolvedStaticDir)) {
7897
+ const resolvedStaticDir = path24.resolve(staticDir);
7898
+ if (!fs28.existsSync(resolvedStaticDir)) {
7689
7899
  console.error(`${LOG_PREFIX} \u76EE\u5F55\u4E0D\u5B58\u5728: ${resolvedStaticDir}\uFF0C\u8DF3\u8FC7\u4E0A\u4F20`);
7690
7900
  return;
7691
7901
  }
@@ -7718,8 +7928,8 @@ async function uploadStatic(options) {
7718
7928
  ({ AccessKeyID: accessKeyID, SecretAccessKey: secretAccessKey, SessionToken: sessionToken } = uploadCredential);
7719
7929
  }
7720
7930
  console.error(`${LOG_PREFIX} \u4E0A\u4F20\u76EE\u6807: ${uploadPrefix}`);
7721
- const confPath = path22.join(os2.tmpdir(), `.tosutilconfig-static-${process.pid}`);
7722
- fs26.writeFileSync(confPath, "");
7931
+ const confPath = path24.join(os2.tmpdir(), `.tosutilconfig-static-${process.pid}`);
7932
+ fs28.writeFileSync(confPath, "");
7723
7933
  try {
7724
7934
  console.error(`${LOG_PREFIX} \u914D\u7F6E tosutil...`);
7725
7935
  configureTosutil(resolvedTosutil, confPath, {
@@ -7733,7 +7943,7 @@ async function uploadStatic(options) {
7733
7943
  uploadToTos(resolvedTosutil, confPath, resolvedStaticDir, uploadPrefix);
7734
7944
  } finally {
7735
7945
  try {
7736
- fs26.unlinkSync(confPath);
7946
+ fs28.unlinkSync(confPath);
7737
7947
  } catch {
7738
7948
  }
7739
7949
  }
@@ -7753,8 +7963,8 @@ async function uploadStatic(options) {
7753
7963
  }
7754
7964
  }
7755
7965
  function resolveTosutilPath(tosutilPath) {
7756
- if (path22.isAbsolute(tosutilPath)) {
7757
- return fs26.existsSync(tosutilPath) ? tosutilPath : null;
7966
+ if (path24.isAbsolute(tosutilPath)) {
7967
+ return fs28.existsSync(tosutilPath) ? tosutilPath : null;
7758
7968
  }
7759
7969
  try {
7760
7970
  const resolved = execFileSync("which", [tosutilPath], { encoding: "utf-8" }).trim();
@@ -7799,7 +8009,7 @@ async function resolveBucketId(appId) {
7799
8009
  return bucketId;
7800
8010
  }
7801
8011
  function isDirEmpty(dirPath) {
7802
- const entries = fs26.readdirSync(dirPath);
8012
+ const entries = fs28.readdirSync(dirPath);
7803
8013
  return entries.length === 0;
7804
8014
  }
7805
8015
 
@@ -7894,12 +8104,12 @@ var commands = [
7894
8104
  ];
7895
8105
 
7896
8106
  // src/index.ts
7897
- var envPath = path23.join(process.cwd(), ".env");
7898
- if (fs27.existsSync(envPath)) {
8107
+ var envPath = path25.join(process.cwd(), ".env");
8108
+ if (fs29.existsSync(envPath)) {
7899
8109
  dotenvConfig({ path: envPath });
7900
8110
  }
7901
- var __dirname = path23.dirname(fileURLToPath5(import.meta.url));
7902
- var pkg = JSON.parse(fs27.readFileSync(path23.join(__dirname, "../package.json"), "utf-8"));
8111
+ var __dirname = path25.dirname(fileURLToPath5(import.meta.url));
8112
+ var pkg = JSON.parse(fs29.readFileSync(path25.join(__dirname, "../package.json"), "utf-8"));
7903
8113
  var cli = new FullstackCLI(pkg.version);
7904
8114
  cli.useAll(commands);
7905
8115
  cli.run();