@xx-in/tools 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 (3) hide show
  1. package/README.md +8 -6
  2. package/dist/cli.js +431 -841
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ import process4 from "process";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@xx-in/tools",
10
- version: "0.0.2",
10
+ version: "0.0.3",
11
11
  description: "A command-line tool to run in any system",
12
12
  license: "MIT",
13
13
  type: "module",
@@ -72,7 +72,7 @@ _xx() {
72
72
  'create:\u9012\u5F52\u521B\u5EFA\u6587\u4EF6\u6216\u76EE\u5F55'
73
73
  'format:\u4F7F\u7528 Prettier \u683C\u5F0F\u5316\u4EE3\u7801'
74
74
  'help:\u663E\u793A\u6307\u5B9A\u547D\u4EE4\u7684\u5E2E\u52A9\u4FE1\u606F'
75
- 'install:\u81EA\u52A8\u5206\u53D1\u90E8\u7F72\u5B89\u88C5\u5305 (\u652F\u6301 AppImage\u3001Flatpak ID\u3001tar.gz\u3001deb\u3001rpm)'
75
+ 'install:macOS \u672C\u5730\u5DE5\u5177\u5B89\u88C5\u5668 (\u652F\u6301\u53EF\u6267\u884C\u6587\u4EF6\u4E0E tar \u5305)'
76
76
  'ip:\u672C\u5730\u6D3B\u8DC3\u7F51\u5361\u53CA\u7F51\u5173\u4FA6\u6D4B'
77
77
  'list:\u5217\u51FA\u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u548C\u76EE\u5F55\uFF08\u542B\u9690\u85CF\u9879\uFF09'
78
78
  'move:\u79FB\u52A8\u6216\u91CD\u547D\u540D\u6587\u4EF6\u53CA\u76EE\u5F55'
@@ -82,7 +82,7 @@ _xx() {
82
82
  'remove:\u5B89\u5168\u5730\u5C06\u6307\u5B9A\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u79FB\u81F3\u7CFB\u7EDF\u56DE\u6536\u7AD9\uFF08\u652F\u6301\u901A\u914D\u7B26\u53CA\u591A\u9009\uFF09'
83
83
  'search:\u9012\u5F52\u641C\u7D22\u76EE\u5F55\u4E0B\u5305\u542B\u6307\u5B9A\u5173\u952E\u8BCD\u7684\u6587\u4EF6\u6216\u76EE\u5F55'
84
84
  'translate:\u7EC8\u7AEF\u7FFB\u8BD1\u5DE5\u5177'
85
- 'uninstall:\u901A\u7528\u5E94\u7528\u5378\u8F7D\u5668\uFF08\u652F\u6301\u5305\u540D\u3001Flatpak\u3001Snap\u3001\u672C\u5730\u5305\u6216\u7EFF\u8272\u8F6F\u4EF6\uFF09'
85
+ 'uninstall:macOS \u672C\u5730\u5DE5\u5177\u5378\u8F7D\u5668\uFF08\u79FB\u9664\u5B89\u88C5\u76EE\u5F55\u548C\u7EC8\u7AEF\u547D\u4EE4\u5165\u53E3\uFF09'
86
86
  'unzip:\u89E3\u538B ZIP \u538B\u7F29\u5305'
87
87
  'upgrade:\u81EA\u52A8\u66F4\u65B0 xx \u547D\u4EE4\u884C\u5DE5\u5177\u81F3\u6700\u65B0\u7248\u672C'
88
88
  'zip:\u81EA\u52A8\u8FC7\u6EE4\u5E76\u6253\u5305\u4E3A ZIP'
@@ -111,7 +111,7 @@ _xx() {
111
111
  'copy:\u590D\u5236\u6587\u4EF6\u6216\u76EE\u5F55\uFF08\u652F\u6301\u9012\u5F52\u590D\u5236\uFF09'
112
112
  'create:\u9012\u5F52\u521B\u5EFA\u6587\u4EF6\u6216\u76EE\u5F55'
113
113
  'format:\u4F7F\u7528 Prettier \u683C\u5F0F\u5316\u4EE3\u7801'
114
- 'install:\u81EA\u52A8\u5206\u53D1\u90E8\u7F72\u5B89\u88C5\u5305 (\u652F\u6301 AppImage\u3001Flatpak ID\u3001tar.gz\u3001deb\u3001rpm)'
114
+ 'install:macOS \u672C\u5730\u5DE5\u5177\u5B89\u88C5\u5668 (\u652F\u6301\u53EF\u6267\u884C\u6587\u4EF6\u4E0E tar \u5305)'
115
115
  'ip:\u672C\u5730\u6D3B\u8DC3\u7F51\u5361\u53CA\u7F51\u5173\u4FA6\u6D4B'
116
116
  'list:\u5217\u51FA\u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u548C\u76EE\u5F55\uFF08\u542B\u9690\u85CF\u9879\uFF09'
117
117
  'move:\u79FB\u52A8\u6216\u91CD\u547D\u540D\u6587\u4EF6\u53CA\u76EE\u5F55'
@@ -121,7 +121,7 @@ _xx() {
121
121
  'remove:\u5B89\u5168\u5730\u5C06\u6307\u5B9A\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u79FB\u81F3\u7CFB\u7EDF\u56DE\u6536\u7AD9\uFF08\u652F\u6301\u901A\u914D\u7B26\u53CA\u591A\u9009\uFF09'
122
122
  'search:\u9012\u5F52\u641C\u7D22\u76EE\u5F55\u4E0B\u5305\u542B\u6307\u5B9A\u5173\u952E\u8BCD\u7684\u6587\u4EF6\u6216\u76EE\u5F55'
123
123
  'translate:\u7EC8\u7AEF\u7FFB\u8BD1\u5DE5\u5177'
124
- 'uninstall:\u901A\u7528\u5E94\u7528\u5378\u8F7D\u5668\uFF08\u652F\u6301\u5305\u540D\u3001Flatpak\u3001Snap\u3001\u672C\u5730\u5305\u6216\u7EFF\u8272\u8F6F\u4EF6\uFF09'
124
+ 'uninstall:macOS \u672C\u5730\u5DE5\u5177\u5378\u8F7D\u5668\uFF08\u79FB\u9664\u5B89\u88C5\u76EE\u5F55\u548C\u7EC8\u7AEF\u547D\u4EE4\u5165\u53E3\uFF09'
125
125
  'unzip:\u89E3\u538B ZIP \u538B\u7F29\u5305'
126
126
  'upgrade:\u81EA\u52A8\u66F4\u65B0 xx \u547D\u4EE4\u884C\u5DE5\u5177\u81F3\u6700\u65B0\u7248\u672C'
127
127
  'zip:\u81EA\u52A8\u8FC7\u6EE4\u5E76\u6253\u5305\u4E3A ZIP'
@@ -547,12 +547,12 @@ function isCommandAvailable(cmd) {
547
547
  }
548
548
  function runCommand(cmd, args, options = {}) {
549
549
  const stdio = options.stdio ?? "pipe";
550
- return new Promise((resolve14, reject) => {
550
+ return new Promise((resolve13, reject) => {
551
551
  const child = spawn(cmd, args, { stdio });
552
552
  if (stdio === "inherit" || stdio === "ignore") {
553
553
  child.on("error", reject);
554
554
  child.on("close", (code) => {
555
- resolve14({
555
+ resolve13({
556
556
  success: code === 0,
557
557
  code,
558
558
  stdout: Buffer.alloc(0),
@@ -567,7 +567,7 @@ function runCommand(cmd, args, options = {}) {
567
567
  child.stderr?.on("data", (chunk) => stderrChunks.push(chunk));
568
568
  child.on("error", reject);
569
569
  child.on("close", (code) => {
570
- resolve14({
570
+ resolve13({
571
571
  success: code === 0,
572
572
  code,
573
573
  stdout: Buffer.concat(stdoutChunks),
@@ -764,268 +764,289 @@ function registerFormatCommand(program2) {
764
764
  }
765
765
 
766
766
  // commands/install.ts
767
+ import fs6 from "fs/promises";
768
+ import pc6 from "picocolors";
769
+ import { resolve as resolve4, join as join5, basename as basename3 } from "path";
770
+
771
+ // utils/macos-apps.ts
767
772
  import fs5 from "fs/promises";
773
+ import { basename as basename2, extname, join as join4 } from "path";
768
774
  import pc5 from "picocolors";
769
- import { resolve as resolve4, join as join4, basename as basename2 } from "path";
775
+ var APP_DIR_NAME = ".xx-tools";
776
+ var PATH_MARKER_BEGIN = "# >>> xx-tools path >>>";
777
+ var PATH_MARKER_END = "# <<< xx-tools path <<<";
770
778
  function getHomeDir() {
771
- return process.env["HOME"] || process.env["USERPROFILE"] || process.cwd();
779
+ return process.env["HOME"] || process.cwd();
780
+ }
781
+ function getToolsRootDir() {
782
+ return join4(getHomeDir(), APP_DIR_NAME);
783
+ }
784
+ function getAppsDir() {
785
+ return join4(getToolsRootDir(), "apps");
786
+ }
787
+ function getBinDir() {
788
+ return join4(getToolsRootDir(), "bin");
789
+ }
790
+ function getManifestPath(appName) {
791
+ return join4(getAppsDir(), appName, ".xx-manifest.json");
792
+ }
793
+ function ensureMacOS() {
794
+ if (process.platform !== "darwin") {
795
+ console.error(pc5.red("\u274C \u5F53\u524D install/uninstall \u4EC5\u652F\u6301 macOS\u3002"));
796
+ return false;
797
+ }
798
+ return true;
799
+ }
800
+ async function ensureToolDirectories() {
801
+ await fs5.mkdir(getAppsDir(), { recursive: true });
802
+ await fs5.mkdir(getBinDir(), { recursive: true });
772
803
  }
773
- async function createShortcut(targetPath) {
804
+ function getPreferredProfiles() {
774
805
  const home = getHomeDir();
775
- const applicationsDir = join4(home, ".local/share/applications");
776
- let name = "";
777
- let execLine = "";
778
- let desktopFileName = "";
779
- const isFlatpak = !targetPath.includes("/") && !targetPath.includes("\\") && targetPath.split(".").length >= 3;
780
- if (isFlatpak) {
781
- const segments = targetPath.split(".");
782
- name = segments[segments.length - 1];
783
- execLine = `flatpak run ${targetPath}`;
784
- desktopFileName = `flatpak-${targetPath}.desktop`;
806
+ const shell = process.env["SHELL"] || "";
807
+ const profiles = [];
808
+ if (shell.includes("zsh")) {
809
+ profiles.push(join4(home, ".zshrc"), join4(home, ".zprofile"));
810
+ } else if (shell.includes("bash")) {
811
+ profiles.push(join4(home, ".bashrc"), join4(home, ".bash_profile"));
785
812
  } else {
786
- const absolutePath = resolve4(process.cwd(), targetPath);
813
+ profiles.push(join4(home, ".zshrc"), join4(home, ".zprofile"));
814
+ }
815
+ return Array.from(new Set(profiles));
816
+ }
817
+ async function ensureBinDirOnPath() {
818
+ const pathBlock = `${PATH_MARKER_BEGIN}
819
+ export PATH="$HOME/${APP_DIR_NAME}/bin:$PATH"
820
+ ${PATH_MARKER_END}`;
821
+ for (const profilePath of getPreferredProfiles()) {
822
+ let content = "";
787
823
  try {
788
- const stat = await fs5.stat(absolutePath);
789
- if (!stat.isFile()) {
790
- console.error(pc5.red(`\u274C \u9519\u8BEF: '${targetPath}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u6587\u4EF6\u3002`));
791
- return;
792
- }
824
+ content = await fs5.readFile(profilePath, "utf-8");
793
825
  } catch {
794
- console.error(pc5.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u6587\u4EF6 '${targetPath}'\u3002`));
795
- return;
796
826
  }
797
- const isAppImage = targetPath.toLowerCase().endsWith(".appimage");
798
- name = basename2(absolutePath, isAppImage ? ".AppImage" : "");
799
- try {
800
- await fs5.chmod(absolutePath, 493);
801
- } catch {
827
+ if (!content.includes(PATH_MARKER_BEGIN)) {
828
+ const separator = content.endsWith("\n") || content === "" ? "" : "\n";
829
+ await fs5.writeFile(
830
+ profilePath,
831
+ `${content}${separator}${pathBlock}
832
+ `,
833
+ "utf-8"
834
+ );
835
+ console.log(pc5.green(`\u2714 \u5DF2\u5199\u5165 PATH \u914D\u7F6E: ${profilePath}`));
802
836
  }
803
- execLine = isAppImage ? `"${absolutePath}" --no-sandbox` : `"${absolutePath}"`;
804
- desktopFileName = `${name.replace(/\s+/g, "-").toLowerCase()}.desktop`;
805
- }
806
- const desktopFilePath = join4(applicationsDir, desktopFileName);
807
- const desktopContent = `[Desktop Entry]
808
- Name=${name}
809
- Exec=${execLine}
810
- Type=Application
811
- Terminal=false
812
- Categories=Utility;
813
- `;
814
- try {
815
- await fs5.mkdir(applicationsDir, { recursive: true });
816
- await fs5.writeFile(desktopFilePath, desktopContent, "utf-8");
817
- console.log(pc5.green(`\u2714 \u5FEB\u6377\u65B9\u5F0F\u5DF2\u521B\u5EFA: ${desktopFilePath}`));
818
- console.log(pc5.dim(`\u542F\u52A8\u547D\u4EE4: ${execLine}`));
819
- } catch (err) {
820
- console.error(
821
- pc5.red("\u274C \u521B\u5EFA\u5FEB\u6377\u65B9\u5F0F\u5931\u8D25:"),
822
- err instanceof Error ? err.message : err
823
- );
824
837
  }
825
838
  }
826
- async function installAppImage(absPath) {
827
- const home = getHomeDir();
828
- const greenAppDir = join4(home, "GreenApp");
829
- const fileName = basename2(absPath);
830
- const destPath = join4(greenAppDir, fileName);
831
- const isAppImage = fileName.toLowerCase().endsWith(".appimage");
832
- const appNameClean = basename2(absPath, isAppImage ? ".AppImage" : "");
833
- try {
834
- await fs5.mkdir(greenAppDir, { recursive: true });
835
- console.log(
836
- pc5.cyan(`\u{1F4E6} \u6B63\u5728\u5C06 AppImage \u90E8\u7F72\u81F3\u7EFF\u8272\u8F6F\u4EF6\u76EE\u5F55: ${destPath}...`)
837
- );
838
- await fs5.copyFile(absPath, destPath);
839
- await fs5.chmod(destPath, 493);
840
- await createShortcut(destPath);
841
- console.log(pc5.green(`\u2728 AppImage \u90E8\u7F72\u5B8C\u6210\uFF01`));
842
- console.log(
843
- pc5.green(
844
- `
845
- \u2728 \u5B89\u88C5\u6210\u529F\uFF01\u8BE5\u7EFF\u8272\u8F6F\u4EF6\u7684\u5378\u8F7D\u540D\u79F0\u4E3A: ${pc5.bold(appNameClean)}`
846
- )
847
- );
848
- console.log(pc5.cyan(`\u{1F449} \u4EE5\u540E\u60A8\u53EF\u4EE5\u901A\u8FC7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u5F7B\u5E95\u5378\u8F7D\u5B83\uFF1A`));
849
- console.log(pc5.bold(pc5.yellow(` xx delete ${appNameClean}`)));
850
- } catch (err) {
851
- console.error(
852
- pc5.red("\u274C AppImage \u90E8\u7F72\u5931\u8D25:"),
853
- err instanceof Error ? err.message : err
854
- );
839
+ function getShellReloadCommand() {
840
+ const shell = process.env["SHELL"] || "";
841
+ if (shell.includes("zsh")) {
842
+ return "source ~/.zshrc";
843
+ }
844
+ if (shell.includes("bash")) {
845
+ return "source ~/.bashrc";
855
846
  }
847
+ return "source ~/.zshrc";
856
848
  }
857
- async function installDeb(absPath) {
858
- console.log(pc5.cyan(`\u{1F4E6} \u6B63\u5728\u901A\u8FC7 dpkg \u672C\u5730\u5B89\u88C5 DEB \u8F6F\u4EF6\u5305: ${absPath}...`));
859
- const status = await spawnCommand("sudo", ["dpkg", "-i", absPath]);
860
- if (status.success) {
861
- console.log(pc5.green("\u2714 DEB \u8F6F\u4EF6\u5305\u90E8\u7F72\u6210\u529F\uFF01"));
862
- try {
863
- const { success, stdout } = await runCommand("dpkg-deb", [
864
- "-f",
865
- absPath,
866
- "Package"
867
- ]);
868
- if (success) {
869
- const packageName = decodeOutput(stdout).trim();
870
- console.log(
871
- pc5.green(
872
- `
873
- \u2728 \u5B89\u88C5\u6210\u529F\uFF01\u8BE5\u8F6F\u4EF6\u5305\u7684\u5B98\u65B9\u5378\u8F7D\u540D\u79F0\u4E3A: ${pc5.bold(packageName)}`
874
- )
875
- );
876
- console.log(pc5.cyan(`\u{1F449} \u4EE5\u540E\u60A8\u53EF\u4EE5\u901A\u8FC7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u5F7B\u5E95\u5378\u8F7D\u5B83\uFF1A`));
877
- console.log(pc5.bold(pc5.yellow(` xx delete ${packageName}`)));
878
- }
879
- } catch {
849
+ function stripArchiveSuffix(filePath) {
850
+ const lower = filePath.toLowerCase();
851
+ const name = basename2(filePath);
852
+ const suffixes = [".tar.gz", ".tgz", ".tar.xz", ".txz", ".zip", ".tar"];
853
+ for (const suffix of suffixes) {
854
+ if (lower.endsWith(suffix)) {
855
+ return name.slice(0, name.length - suffix.length);
880
856
  }
881
- } else {
882
- console.error(pc5.red(`\u274C \u5B89\u88C5\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`));
883
857
  }
858
+ return basename2(filePath, extname(filePath));
884
859
  }
885
- async function installRpm(absPath) {
886
- console.log(pc5.cyan(`\u{1F4E6} \u6B63\u5728\u901A\u8FC7 dnf \u672C\u5730\u5B89\u88C5 RPM \u8F6F\u4EF6\u5305: ${absPath}...`));
887
- const status = await spawnCommand("sudo", ["dnf", "install", "-y", absPath]);
888
- if (status.success) {
889
- console.log(pc5.green("\u2714 RPM \u8F6F\u4EF6\u5305\u90E8\u7F72\u6210\u529F\uFF01"));
890
- try {
891
- const { success, stdout } = await runCommand("rpm", [
892
- "-qp",
893
- "--queryformat",
894
- "%{NAME}",
895
- absPath
896
- ]);
897
- if (success) {
898
- const packageName = decodeOutput(stdout).trim();
899
- console.log(
900
- pc5.green(
901
- `
902
- \u2728 \u5B89\u88C5\u6210\u529F\uFF01\u8BE5\u8F6F\u4EF6\u5305\u7684\u5B98\u65B9\u5378\u8F7D\u540D\u79F0\u4E3A: ${pc5.bold(packageName)}`
903
- )
904
- );
905
- console.log(pc5.cyan(`\u{1F449} \u4EE5\u540E\u60A8\u53EF\u4EE5\u901A\u8FC7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u5F7B\u5E95\u5378\u8F7D\u5B83\uFF1A`));
906
- console.log(pc5.bold(pc5.yellow(` xx delete ${packageName}`)));
860
+ async function removeDirectoryContents(dirPath) {
861
+ await fs5.rm(dirPath, { recursive: true, force: true });
862
+ await fs5.mkdir(dirPath, { recursive: true });
863
+ }
864
+ async function findExecutablesRecursively(rootDir) {
865
+ const matches = [];
866
+ async function walk(currentDir) {
867
+ for (const entry of await fs5.readdir(currentDir, { withFileTypes: true })) {
868
+ if (entry.name.startsWith(".")) continue;
869
+ const fullPath = join4(currentDir, entry.name);
870
+ if (entry.isDirectory()) {
871
+ if (["node_modules", "lib", "libs", "include", "share", "man"].includes(
872
+ entry.name
873
+ )) {
874
+ continue;
875
+ }
876
+ await walk(fullPath);
877
+ continue;
907
878
  }
908
- } catch {
879
+ if (!entry.isFile()) continue;
880
+ const stat = await fs5.stat(fullPath);
881
+ const isExecutable = stat.mode ? (stat.mode & 73) !== 0 : false;
882
+ if (!isExecutable) continue;
883
+ if (/\.(dylib|so|a|o|txt|md|json|yaml|yml|ts|js|c|h|sh)$/i.test(entry.name)) {
884
+ continue;
885
+ }
886
+ matches.push(fullPath);
909
887
  }
910
- } else {
911
- console.error(pc5.red(`\u274C \u5B89\u88C5\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`));
912
888
  }
889
+ await walk(rootDir);
890
+ return matches;
913
891
  }
914
- async function installTarGz(absPath) {
915
- const home = getHomeDir();
916
- if (!home) {
917
- console.error(pc5.red("\u274C \u9519\u8BEF: \u65E0\u6CD5\u83B7\u53D6\u7528\u6237\u6839\u76EE\u5F55\u3002"));
918
- return;
892
+ async function createLinks(appName, executablePaths) {
893
+ const binDir = getBinDir();
894
+ const linkNames = [];
895
+ for (const executablePath of executablePaths) {
896
+ const linkName = basename2(executablePath);
897
+ const linkPath = join4(binDir, linkName);
898
+ await fs5.rm(linkPath, { force: true });
899
+ await fs5.symlink(executablePath, linkPath);
900
+ linkNames.push(linkName);
919
901
  }
920
- const greenAppDir = join4(home, "GreenApp");
921
- const folderName = basename2(absPath, ".tar.gz").replace(".tar", "");
922
- const destDir = join4(greenAppDir, folderName);
923
- try {
924
- await fs5.mkdir(destDir, { recursive: true });
925
- console.log(pc5.cyan(`\u{1F4E6} \u6B63\u5728\u89E3\u538B\u7EFF\u8272\u8F6F\u4EF6\u81F3: ${destDir}...`));
926
- const tarStatus = await spawnCommand("tar", [
927
- "-xzf",
928
- absPath,
929
- "-C",
930
- destDir
931
- ]);
932
- if (!tarStatus.success) {
933
- console.error(pc5.red("\u274C \u89E3\u538B\u5931\u8D25\u3002"));
934
- return;
935
- }
902
+ if (linkNames.length > 0) {
936
903
  console.log(
937
- pc5.green("\u2714 \u89E3\u538B\u5B8C\u6210\u3002\u6B63\u5728\u626B\u63CF\u4E3B\u6267\u884C\u6587\u4EF6\u4EE5\u81EA\u52A8\u914D\u7F6E\u5FEB\u6377\u65B9\u5F0F...")
904
+ pc5.green(
905
+ `\u2714 \u5DF2\u4E3A ${pc5.bold(appName)} \u521B\u5EFA\u7EC8\u7AEF\u547D\u4EE4: ${linkNames.join(", ")}`
906
+ )
938
907
  );
939
- let exePath = "";
940
- for (const entry of await fs5.readdir(destDir, { withFileTypes: true })) {
941
- if (entry.isFile()) {
942
- const fullPath = join4(destDir, entry.name);
943
- const stat = await fs5.stat(fullPath);
944
- const isExecutable = stat.mode ? (stat.mode & 73) !== 0 : false;
945
- if (isExecutable && !entry.name.endsWith(".sh") && !entry.name.endsWith(".so")) {
946
- exePath = fullPath;
947
- break;
948
- }
949
- }
950
- }
951
- if (exePath) {
952
- console.log(pc5.cyan(`\u{1F50D} \u53D1\u73B0\u53EF\u6267\u884C\u4E8C\u8FDB\u5236\u6587\u4EF6: ${exePath}`));
953
- await createShortcut(exePath);
954
- console.log(
955
- pc5.green(
956
- `
957
- \u2728 \u5B89\u88C5\u6210\u529F\uFF01\u8BE5\u7EFF\u8272\u5E94\u7528\u7684\u5378\u8F7D\u540D\u79F0\u4E3A: ${pc5.bold(folderName)}`
958
- )
959
- );
960
- console.log(pc5.cyan(`\u{1F449} \u4EE5\u540E\u60A8\u53EF\u4EE5\u901A\u8FC7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u5F7B\u5E95\u5378\u8F7D\u5B83\uFF1A`));
961
- console.log(pc5.bold(pc5.yellow(` xx delete ${folderName}`)));
962
- } else {
963
- console.log(
964
- pc5.yellow(
965
- "\u26A0\uFE0F \u672A\u80FD\u5728\u89E3\u538B\u76EE\u5F55\u4E0B\u5B9A\u4F4D\u5230\u660E\u786E\u7684\u53EF\u6267\u884C\u4E8C\u8FDB\u5236\u6587\u4EF6\uFF0C\u8BF7\u540E\u7EED\u624B\u52A8\u521B\u5EFA\u3002"
966
- )
967
- );
968
- }
969
- } catch (err) {
908
+ }
909
+ return linkNames;
910
+ }
911
+ async function writeManifest(manifest) {
912
+ await fs5.writeFile(
913
+ getManifestPath(manifest.appName),
914
+ JSON.stringify(manifest, null, 2),
915
+ "utf-8"
916
+ );
917
+ }
918
+ async function readManifest(appName) {
919
+ try {
920
+ const content = await fs5.readFile(getManifestPath(appName), "utf-8");
921
+ return JSON.parse(content);
922
+ } catch {
923
+ return null;
924
+ }
925
+ }
926
+ async function removeInstalledApp(appName) {
927
+ const manifest = await readManifest(appName);
928
+ if (!manifest) return false;
929
+ for (const linkName of manifest.links) {
930
+ await fs5.rm(join4(getBinDir(), linkName), { force: true });
931
+ console.log(pc5.green(`\u2714 \u5DF2\u79FB\u9664\u7EC8\u7AEF\u547D\u4EE4: ${linkName}`));
932
+ }
933
+ await fs5.rm(manifest.installDir, { recursive: true, force: true });
934
+ console.log(pc5.green(`\u2714 \u5DF2\u79FB\u9664\u5B89\u88C5\u76EE\u5F55: ${manifest.installDir}`));
935
+ return true;
936
+ }
937
+ async function listInstalledApps() {
938
+ try {
939
+ const entries = await fs5.readdir(getAppsDir(), { withFileTypes: true });
940
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
941
+ } catch {
942
+ return [];
943
+ }
944
+ }
945
+ async function extractArchiveToDir(archivePath, destDir) {
946
+ const lower = archivePath.toLowerCase();
947
+ let args;
948
+ if (lower.endsWith(".tar.gz") || lower.endsWith(".tgz")) {
949
+ args = ["-xzf", archivePath, "-C", destDir];
950
+ } else if (lower.endsWith(".tar.xz") || lower.endsWith(".txz")) {
951
+ args = ["-xJf", archivePath, "-C", destDir];
952
+ } else if (lower.endsWith(".tar")) {
953
+ args = ["-xf", archivePath, "-C", destDir];
954
+ } else {
955
+ return false;
956
+ }
957
+ const result = await spawnCommand("tar", args);
958
+ return result.success;
959
+ }
960
+
961
+ // commands/install.ts
962
+ function printReloadHint() {
963
+ const reloadCommand = getShellReloadCommand();
964
+ console.log(
965
+ pc6.yellow(`\u{1F4A1} \u5982\u679C\u5F53\u524D\u7EC8\u7AEF\u8FD8\u4E0D\u80FD\u76F4\u63A5\u8FD0\u884C\u65B0\u547D\u4EE4\uFF0C\u8BF7\u6267\u884C: ${reloadCommand}`)
966
+ );
967
+ }
968
+ async function installBinary(absPath) {
969
+ const appName = basename3(absPath);
970
+ const installDir = join5(getAppsDir(), appName);
971
+ const targetDir = join5(installDir, "bin");
972
+ const targetPath = join5(targetDir, appName);
973
+ await fs6.mkdir(targetDir, { recursive: true });
974
+ await fs6.copyFile(absPath, targetPath);
975
+ await fs6.chmod(targetPath, 493);
976
+ const links = await createLinks(appName, [targetPath]);
977
+ await writeManifest({
978
+ appName,
979
+ installDir,
980
+ links,
981
+ type: "binary"
982
+ });
983
+ console.log(pc6.green(`\u2728 \u5B89\u88C5\u6210\u529F\uFF01\u53EF\u76F4\u63A5\u5728\u7EC8\u7AEF\u4E2D\u8FD0\u884C: ${pc6.bold(appName)}`));
984
+ console.log(pc6.cyan(`\u{1F449} \u5378\u8F7D\u547D\u4EE4: ${pc6.bold(`xx uninstall ${appName}`)}`));
985
+ printReloadHint();
986
+ }
987
+ async function installArchive(absPath) {
988
+ const appName = stripArchiveSuffix(absPath);
989
+ const installDir = join5(getAppsDir(), appName);
990
+ await removeDirectoryContents(installDir);
991
+ console.log(pc6.cyan(`\u{1F4E6} \u6B63\u5728\u89E3\u538B\u8F6F\u4EF6\u5305\u81F3: ${installDir}...`));
992
+ const extracted = await extractArchiveToDir(absPath, installDir);
993
+ if (!extracted) {
970
994
  console.error(
971
- pc5.red("\u274C \u7EFF\u8272\u8F6F\u4EF6\u5B89\u88C5\u5931\u8D25:"),
972
- err instanceof Error ? err.message : err
995
+ pc6.red("\u274C \u5F53\u524D\u4EC5\u652F\u6301 .tar.gz\u3001.tgz\u3001.tar.xz\u3001.txz\u3001.tar \u683C\u5F0F\u3002")
973
996
  );
997
+ return;
998
+ }
999
+ const executables = await findExecutablesRecursively(installDir);
1000
+ if (executables.length === 0) {
1001
+ console.error(pc6.red("\u274C \u89E3\u538B\u5B8C\u6210\uFF0C\u4F46\u672A\u627E\u5230\u53EF\u6267\u884C\u6587\u4EF6\u3002"));
1002
+ return;
974
1003
  }
1004
+ const links = await createLinks(appName, executables);
1005
+ await writeManifest({
1006
+ appName,
1007
+ installDir,
1008
+ links,
1009
+ type: "archive"
1010
+ });
1011
+ console.log(
1012
+ pc6.green(`\u2728 \u5B89\u88C5\u6210\u529F\uFF01\u53EF\u76F4\u63A5\u5728\u7EC8\u7AEF\u4E2D\u8FD0\u884C: ${pc6.bold(links.join(", "))}`)
1013
+ );
1014
+ console.log(pc6.cyan(`\u{1F449} \u5378\u8F7D\u547D\u4EE4: ${pc6.bold(`xx uninstall ${appName}`)}`));
1015
+ printReloadHint();
975
1016
  }
976
1017
  function registerInstallCommand(program2) {
977
1018
  program2.command("install [path]").description(
978
- "\u901A\u7528\u5E94\u7528\u90E8\u7F72\u5B89\u88C5\uFF08\u81EA\u52A8\u5206\u53D1\u9002\u914D AppImage\u3001Flatpak ID\u3001tar.gz\u3001deb \u53CA rpm \u683C\u5F0F\u5305\uFF09"
1019
+ "macOS \u672C\u5730\u5DE5\u5177\u5B89\u88C5\u5668\uFF08\u652F\u6301\u53EF\u6267\u884C\u6587\u4EF6\u3001.tar.gz\u3001.tgz\u3001.tar.xz\u3001.txz\u3001.tar\uFF09"
979
1020
  ).action(async (target) => {
1021
+ if (!ensureMacOS()) return;
980
1022
  if (!target) {
981
- console.error(pc5.red("\u274C \u8BF7\u63D0\u4F9B\u6709\u6548\u7684\u5B89\u88C5\u5305\u6587\u4EF6\u8DEF\u5F84\u6216 Flatpak ID\u3002"));
982
- return;
983
- }
984
- const isFlatpak = !target.includes("/") && !target.includes("\\") && target.split(".").length >= 3;
985
- if (isFlatpak) {
986
- await createShortcut(target);
987
- console.log(
988
- pc5.green(
989
- `
990
- \u2728 \u5B89\u88C5\u6210\u529F\uFF01\u8BE5 Flatpak \u5FEB\u6377\u56FE\u6807\u7684\u5378\u8F7D\u540D\u79F0\u4E3A: ${pc5.bold(target)}`
991
- )
992
- );
993
- console.log(pc5.cyan(`\u{1F449} \u4EE5\u540E\u60A8\u53EF\u4EE5\u901A\u8FC7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u5220\u9664\u8BE5\u5FEB\u6377\u56FE\u6807\uFF1A`));
994
- console.log(pc5.bold(pc5.yellow(` xx delete ${target}`)));
1023
+ console.error(pc6.red("\u274C \u8BF7\u63D0\u4F9B\u6709\u6548\u7684\u672C\u5730\u6587\u4EF6\u8DEF\u5F84\u3002"));
995
1024
  return;
996
1025
  }
997
1026
  const absPath = resolve4(process.cwd(), target);
998
1027
  try {
999
- await fs5.stat(absPath);
1028
+ const stat = await fs6.stat(absPath);
1029
+ if (!stat.isFile()) {
1030
+ console.error(pc6.red(`\u274C \u9519\u8BEF: '${target}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u6587\u4EF6\u3002`));
1031
+ return;
1032
+ }
1000
1033
  } catch {
1001
- console.error(pc5.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u6307\u5B9A\u6587\u4EF6\u6216\u5305\u8DEF\u5F84 '${target}'\u3002`));
1034
+ console.error(pc6.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u6307\u5B9A\u6587\u4EF6\u6216\u5305\u8DEF\u5F84 '${target}'\u3002`));
1002
1035
  return;
1003
1036
  }
1037
+ await ensureToolDirectories();
1038
+ await ensureBinDirOnPath();
1004
1039
  const lowerPath = target.toLowerCase();
1005
- if (lowerPath.endsWith(".appimage")) {
1006
- await installAppImage(absPath);
1007
- } else if (lowerPath.endsWith(".deb")) {
1008
- await installDeb(absPath);
1009
- } else if (lowerPath.endsWith(".rpm")) {
1010
- await installRpm(absPath);
1011
- } else if (lowerPath.endsWith(".tar.gz") || lowerPath.endsWith(".tgz")) {
1012
- await installTarGz(absPath);
1040
+ if (lowerPath.endsWith(".tar.gz") || lowerPath.endsWith(".tgz") || lowerPath.endsWith(".tar.xz") || lowerPath.endsWith(".txz") || lowerPath.endsWith(".tar")) {
1041
+ await installArchive(absPath);
1013
1042
  } else {
1014
- console.log(
1015
- pc5.cyan(`\u{1F4E6} \u68C0\u6D4B\u5230\u901A\u7528\u672C\u5730\u53EF\u6267\u884C\u6587\u4EF6\uFF0C\u6B63\u5728\u76F4\u63A5\u4E3A\u5176\u914D\u7F6E\u684C\u9762\u56FE\u6807...`)
1016
- );
1017
- await createShortcut(absPath);
1018
- const execName = basename2(absPath);
1019
- console.log(
1020
- pc5.green(`
1021
- \u2728 \u5FEB\u6377\u65B9\u5F0F\u521B\u5EFA\u6210\u529F\uFF01\u540D\u79F0\u4E3A: ${pc5.bold(execName)}`)
1022
- );
1043
+ await installBinary(absPath);
1023
1044
  }
1024
1045
  });
1025
1046
  }
1026
1047
 
1027
1048
  // commands/ip.ts
1028
- import pc6 from "picocolors";
1049
+ import pc7 from "picocolors";
1029
1050
  import os from "os";
1030
1051
  function getInterfaceType(name) {
1031
1052
  const lowerName = name.toLowerCase();
@@ -1199,7 +1220,7 @@ async function getDefaultRouteInfo() {
1199
1220
  }
1200
1221
  function registerIpCommand(program2) {
1201
1222
  program2.command("ip").description("\u672C\u5730\u6D3B\u8DC3\u7F51\u5361\u3001\u672C\u673AIP\u53CA\u7F51\u5173\u4FA6\u6D4B\u5DE5\u5177").action(async () => {
1202
- console.log(pc6.dim("\u6B63\u5728\u5206\u6790\u7F51\u7EDC\u914D\u7F6E\uFF0C\u8BF7\u7A0D\u5019...\n"));
1223
+ console.log(pc7.dim("\u6B63\u5728\u5206\u6790\u7F51\u7EDC\u914D\u7F6E\uFF0C\u8BF7\u7A0D\u5019...\n"));
1203
1224
  try {
1204
1225
  let defaultRoute = { gateway: "", interfaceName: "" };
1205
1226
  let routeError = "";
@@ -1210,7 +1231,7 @@ function registerIpCommand(program2) {
1210
1231
  }
1211
1232
  const cards = getActiveNetworkCards();
1212
1233
  if (cards.length === 0) {
1213
- console.log(pc6.red("\u274C \u672A\u68C0\u6D4B\u5230\u4EFB\u4F55\u6D3B\u8DC3\u7684\u975E\u672C\u5730\u56DE\u73AF\u7F51\u5361\u3002"));
1234
+ console.log(pc7.red("\u274C \u672A\u68C0\u6D4B\u5230\u4EFB\u4F55\u6D3B\u8DC3\u7684\u975E\u672C\u5730\u56DE\u73AF\u7F51\u5361\u3002"));
1214
1235
  return;
1215
1236
  }
1216
1237
  cards.sort((a, b) => {
@@ -1247,76 +1268,76 @@ function registerIpCommand(program2) {
1247
1268
  ipv4.netmask
1248
1269
  );
1249
1270
  }
1250
- let cardGateway = pc6.dim("(\u975E\u9ED8\u8BA4\u8DEF\u7531\u51FA\u53E3\u7F51\u5361)");
1271
+ let cardGateway = pc7.dim("(\u975E\u9ED8\u8BA4\u8DEF\u7531\u51FA\u53E3\u7F51\u5361)");
1251
1272
  if (isDefaultRouteCard) {
1252
1273
  if (defaultRoute.gateway && defaultRoute.gateway !== "0.0.0.0") {
1253
- cardGateway = pc6.yellow(defaultRoute.gateway);
1274
+ cardGateway = pc7.yellow(defaultRoute.gateway);
1254
1275
  } else {
1255
- cardGateway = pc6.yellow("\u76F4\u63A5\u70B9\u5BF9\u70B9\u96A7\u9053\u8FDE\u63A5 (Point-to-Point)");
1276
+ cardGateway = pc7.yellow("\u76F4\u63A5\u70B9\u5BF9\u70B9\u96A7\u9053\u8FDE\u63A5 (Point-to-Point)");
1256
1277
  }
1257
1278
  } else if (routeError) {
1258
- cardGateway = pc6.dim(`\u68C0\u6D4B\u5931\u8D25 (\u539F\u56E0: ${routeError})`);
1279
+ cardGateway = pc7.dim(`\u68C0\u6D4B\u5931\u8D25 (\u539F\u56E0: ${routeError})`);
1259
1280
  }
1260
1281
  console.log(
1261
- pc6.cyan(
1282
+ pc7.cyan(
1262
1283
  `================ \u6D3B\u8DC3\u7F51\u5361\u53CA\u7F51\u5173\u4FE1\u606F [${card.type}] ================`
1263
1284
  )
1264
1285
  );
1265
1286
  console.log(
1266
- `${pc6.green("\u7F51\u5361\u540D\u79F0 (Name):")} ${pc6.bold(card.name)}`
1287
+ `${pc7.green("\u7F51\u5361\u540D\u79F0 (Name):")} ${pc7.bold(card.name)}`
1267
1288
  );
1268
1289
  console.log(
1269
- `${pc6.green("\u672C\u673A IP \u5730\u5740 (IP):")} ${pc6.bold(primaryAddr.address)}`
1290
+ `${pc7.green("\u672C\u673A IP \u5730\u5740 (IP):")} ${pc7.bold(primaryAddr.address)}`
1270
1291
  );
1271
1292
  console.log(
1272
- `${pc6.green("\u5B50\u7F51\u63A9\u7801 (Mask):")} ${primaryAddr.netmask}`
1293
+ `${pc7.green("\u5B50\u7F51\u63A9\u7801 (Mask):")} ${primaryAddr.netmask}`
1273
1294
  );
1274
- console.log(`${pc6.green("\u9ED8\u8BA4\u7F51\u5173 (Gateway):")} ${cardGateway}`);
1275
- console.log(`${pc6.green("MAC \u5730\u5740 (MAC):")} ${card.mac}`);
1295
+ console.log(`${pc7.green("\u9ED8\u8BA4\u7F51\u5173 (Gateway):")} ${cardGateway}`);
1296
+ console.log(`${pc7.green("MAC \u5730\u5740 (MAC):")} ${card.mac}`);
1276
1297
  console.log(
1277
- `${pc6.green("IP \u534F\u8BAE\u7248\u672C:")} ${primaryAddr.family === "IPv4" || primaryAddr.family === "4" ? "IPv4" : "IPv6"}`
1298
+ `${pc7.green("IP \u534F\u8BAE\u7248\u672C:")} ${primaryAddr.family === "IPv4" || primaryAddr.family === "4" ? "IPv4" : "IPv6"}`
1278
1299
  );
1279
1300
  if (ipv4 && ipv6) {
1280
1301
  console.log(
1281
- `${pc6.green("\u672C\u5730 IPv6 \u5730\u5740:")} ${pc6.dim(ipv6.address)}`
1302
+ `${pc7.green("\u672C\u5730 IPv6 \u5730\u5740:")} ${pc7.dim(ipv6.address)}`
1282
1303
  );
1283
1304
  }
1284
1305
  console.log(
1285
- pc6.cyan("====================================================")
1306
+ pc7.cyan("====================================================")
1286
1307
  );
1287
1308
  console.log("");
1288
1309
  }
1289
1310
  } catch (error) {
1290
- console.error(pc6.red("\u274C \u68C0\u6D4B\u5931\u8D25\u3002"));
1311
+ console.error(pc7.red("\u274C \u68C0\u6D4B\u5931\u8D25\u3002"));
1291
1312
  if (error instanceof Error) {
1292
- console.error(pc6.red("\u9519\u8BEF\u8BE6\u60C5:"), error.message);
1313
+ console.error(pc7.red("\u9519\u8BEF\u8BE6\u60C5:"), error.message);
1293
1314
  }
1294
1315
  }
1295
1316
  });
1296
1317
  }
1297
1318
 
1298
1319
  // commands/list.ts
1299
- import fs6 from "fs/promises";
1300
- import pc7 from "picocolors";
1320
+ import fs7 from "fs/promises";
1321
+ import pc8 from "picocolors";
1301
1322
  import { resolve as resolve5 } from "path";
1302
1323
  function registerLsCommand(program2) {
1303
1324
  program2.command("list [path]").description("\u5217\u51FA\u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u548C\u76EE\u5F55\uFF08\u542B\u9690\u85CF\u9879\uFF09").action(async (targetPath) => {
1304
1325
  const inputPath = targetPath || ".";
1305
1326
  const absolutePath = resolve5(process.cwd(), inputPath);
1306
1327
  try {
1307
- const stat = await fs6.stat(absolutePath);
1328
+ const stat = await fs7.stat(absolutePath);
1308
1329
  if (!stat.isDirectory()) {
1309
- console.error(pc7.red(`\u274C \u9519\u8BEF: '${inputPath}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
1330
+ console.error(pc8.red(`\u274C \u9519\u8BEF: '${inputPath}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
1310
1331
  return;
1311
1332
  }
1312
1333
  const entries = [];
1313
- for (const entry of await fs6.readdir(absolutePath, {
1334
+ for (const entry of await fs7.readdir(absolutePath, {
1314
1335
  withFileTypes: true
1315
1336
  })) {
1316
1337
  entries.push(entry);
1317
1338
  }
1318
1339
  if (entries.length === 0) {
1319
- console.log(pc7.dim("\uFF08\u7A7A\u76EE\u5F55\uFF09"));
1340
+ console.log(pc8.dim("\uFF08\u7A7A\u76EE\u5F55\uFF09"));
1320
1341
  return;
1321
1342
  }
1322
1343
  entries.sort((a, b) => {
@@ -1328,13 +1349,13 @@ function registerLsCommand(program2) {
1328
1349
  const isHidden = entry.name.startsWith(".");
1329
1350
  if (entry.isDirectory()) {
1330
1351
  if (isHidden) {
1331
- console.log(pc7.dim(`\u{1F4C1} ${pc7.blue(entry.name)}/`));
1352
+ console.log(pc8.dim(`\u{1F4C1} ${pc8.blue(entry.name)}/`));
1332
1353
  } else {
1333
- console.log(`\u{1F4C1} ${pc7.blue(pc7.bold(entry.name))}/`);
1354
+ console.log(`\u{1F4C1} ${pc8.blue(pc8.bold(entry.name))}/`);
1334
1355
  }
1335
1356
  } else {
1336
1357
  if (isHidden) {
1337
- console.log(pc7.dim(`\u{1F4C4} ${entry.name}`));
1358
+ console.log(pc8.dim(`\u{1F4C4} ${entry.name}`));
1338
1359
  } else {
1339
1360
  console.log(`\u{1F4C4} ${entry.name}`);
1340
1361
  }
@@ -1342,7 +1363,7 @@ function registerLsCommand(program2) {
1342
1363
  }
1343
1364
  } catch (err) {
1344
1365
  console.error(
1345
- pc7.red(`\u274C \u65E0\u6CD5\u8BFB\u53D6\u76EE\u5F55\u5185\u5BB9:`),
1366
+ pc8.red(`\u274C \u65E0\u6CD5\u8BFB\u53D6\u76EE\u5F55\u5185\u5BB9:`),
1346
1367
  err instanceof Error ? err.message : err
1347
1368
  );
1348
1369
  }
@@ -1350,55 +1371,55 @@ function registerLsCommand(program2) {
1350
1371
  }
1351
1372
 
1352
1373
  // commands/move.ts
1353
- import fs7 from "fs/promises";
1354
- import pc8 from "picocolors";
1355
- import { dirname as dirname4, resolve as resolve6, join as join5, basename as basename3 } from "path";
1374
+ import fs8 from "fs/promises";
1375
+ import pc9 from "picocolors";
1376
+ import { dirname as dirname3, resolve as resolve6, join as join6, basename as basename4 } from "path";
1356
1377
  async function copyRecursive2(src, dest) {
1357
- const fileInfo = await fs7.stat(src);
1378
+ const fileInfo = await fs8.stat(src);
1358
1379
  if (fileInfo.isDirectory()) {
1359
- await fs7.mkdir(dest, { recursive: true });
1360
- for (const entry of await fs7.readdir(src, { withFileTypes: true })) {
1361
- await copyRecursive2(join5(src, entry.name), join5(dest, entry.name));
1380
+ await fs8.mkdir(dest, { recursive: true });
1381
+ for (const entry of await fs8.readdir(src, { withFileTypes: true })) {
1382
+ await copyRecursive2(join6(src, entry.name), join6(dest, entry.name));
1362
1383
  }
1363
1384
  } else if (fileInfo.isFile()) {
1364
- await fs7.mkdir(dirname4(dest), { recursive: true });
1365
- await fs7.copyFile(src, dest);
1385
+ await fs8.mkdir(dirname3(dest), { recursive: true });
1386
+ await fs8.copyFile(src, dest);
1366
1387
  }
1367
1388
  }
1368
1389
  function registerMoveCommand(program2) {
1369
1390
  program2.command("move <source> <target>").description("\u79FB\u52A8\u6216\u91CD\u547D\u540D\u6587\u4EF6\u53CA\u76EE\u5F55").action(async (source, target) => {
1370
1391
  if (!source || !target) {
1371
- console.error(pc8.red("\u274C \u8BF7\u63D0\u4F9B\u6E90\u8DEF\u5F84\u548C\u76EE\u6807\u8DEF\u5F84"));
1392
+ console.error(pc9.red("\u274C \u8BF7\u63D0\u4F9B\u6E90\u8DEF\u5F84\u548C\u76EE\u6807\u8DEF\u5F84"));
1372
1393
  return;
1373
1394
  }
1374
1395
  const absSource = resolve6(process.cwd(), source);
1375
1396
  const absTarget = resolve6(process.cwd(), target);
1376
1397
  try {
1377
- await fs7.stat(absSource);
1398
+ await fs8.stat(absSource);
1378
1399
  let finalTarget = absTarget;
1379
1400
  try {
1380
- const targetStat = await fs7.stat(absTarget);
1401
+ const targetStat = await fs8.stat(absTarget);
1381
1402
  if (targetStat.isDirectory()) {
1382
- finalTarget = join5(absTarget, basename3(absSource));
1403
+ finalTarget = join6(absTarget, basename4(absSource));
1383
1404
  }
1384
1405
  } catch {
1385
1406
  }
1386
- const targetParentDir = dirname4(finalTarget);
1387
- await fs7.mkdir(targetParentDir, { recursive: true });
1388
- console.log(pc8.cyan(`\u{1F4E6} \u6B63\u5728\u79FB\u52A8: ${source} \u27A1\uFE0F ${target}...`));
1407
+ const targetParentDir = dirname3(finalTarget);
1408
+ await fs8.mkdir(targetParentDir, { recursive: true });
1409
+ console.log(pc9.cyan(`\u{1F4E6} \u6B63\u5728\u79FB\u52A8: ${source} \u27A1\uFE0F ${target}...`));
1389
1410
  try {
1390
- await fs7.rename(absSource, finalTarget);
1411
+ await fs8.rename(absSource, finalTarget);
1391
1412
  } catch {
1392
1413
  await copyRecursive2(absSource, finalTarget);
1393
- await fs7.rm(absSource, { recursive: true });
1414
+ await fs8.rm(absSource, { recursive: true });
1394
1415
  }
1395
- console.log(pc8.green(`\u2728 \u79FB\u52A8\u6210\u529F: ${source} \u27A1\uFE0F ${target}`));
1416
+ console.log(pc9.green(`\u2728 \u79FB\u52A8\u6210\u529F: ${source} \u27A1\uFE0F ${target}`));
1396
1417
  } catch (err) {
1397
1418
  if (isNotFoundError(err)) {
1398
- console.error(pc8.red(`\u274C \u9519\u8BEF: \u6E90\u8DEF\u5F84\u4E0D\u5B58\u5728: ${absSource}`));
1419
+ console.error(pc9.red(`\u274C \u9519\u8BEF: \u6E90\u8DEF\u5F84\u4E0D\u5B58\u5728: ${absSource}`));
1399
1420
  } else {
1400
1421
  console.error(
1401
- pc8.red("\u274C \u79FB\u52A8\u5931\u8D25:"),
1422
+ pc9.red("\u274C \u79FB\u52A8\u5931\u8D25:"),
1402
1423
  err instanceof Error ? err.message : err
1403
1424
  );
1404
1425
  }
@@ -1407,21 +1428,21 @@ function registerMoveCommand(program2) {
1407
1428
  }
1408
1429
 
1409
1430
  // commands/open.ts
1410
- import fs8 from "fs/promises";
1411
- import pc9 from "picocolors";
1431
+ import fs9 from "fs/promises";
1432
+ import pc10 from "picocolors";
1412
1433
  import { resolve as resolve7 } from "path";
1413
1434
  function registerOpenCommand(program2) {
1414
1435
  program2.command("open [path]").description("\u5728\u7CFB\u7EDF\u6587\u4EF6\u7BA1\u7406\u5668\u4E2D\u6253\u5F00\u6307\u5B9A\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF09").action(async (targetPath) => {
1415
1436
  const inputPath = targetPath || ".";
1416
1437
  const absolutePath = resolve7(process.cwd(), inputPath);
1417
1438
  try {
1418
- const stat = await fs8.stat(absolutePath);
1439
+ const stat = await fs9.stat(absolutePath);
1419
1440
  if (!stat.isDirectory()) {
1420
- console.error(pc9.red(`\u274C \u9519\u8BEF: '${inputPath}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
1441
+ console.error(pc10.red(`\u274C \u9519\u8BEF: '${inputPath}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
1421
1442
  return;
1422
1443
  }
1423
1444
  } catch {
1424
- console.error(pc9.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u76EE\u5F55 '${inputPath}'\u3002`));
1445
+ console.error(pc10.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u76EE\u5F55 '${inputPath}'\u3002`));
1425
1446
  return;
1426
1447
  }
1427
1448
  const os3 = process.platform;
@@ -1437,16 +1458,16 @@ function registerOpenCommand(program2) {
1437
1458
  cmd = "xdg-open";
1438
1459
  args = [absolutePath];
1439
1460
  } else {
1440
- console.error(pc9.red("\u274C \u6682\u4E0D\u652F\u6301\u5728\u5F53\u524D\u7CFB\u7EDF\u4E0B\u8C03\u8D77\u6587\u4EF6\u7BA1\u7406\u5668\u3002"));
1461
+ console.error(pc10.red("\u274C \u6682\u4E0D\u652F\u6301\u5728\u5F53\u524D\u7CFB\u7EDF\u4E0B\u8C03\u8D77\u6587\u4EF6\u7BA1\u7406\u5668\u3002"));
1441
1462
  return;
1442
1463
  }
1443
1464
  try {
1444
- console.log(pc9.cyan(`\u{1F4C2} \u6B63\u5728\u6253\u5F00\u6587\u4EF6\u5939: ${absolutePath}...`));
1465
+ console.log(pc10.cyan(`\u{1F4C2} \u6B63\u5728\u6253\u5F00\u6587\u4EF6\u5939: ${absolutePath}...`));
1445
1466
  await spawnCommand(cmd, args);
1446
- console.log(pc9.green("\u2728 \u6210\u529F\u8C03\u8D77\u6587\u4EF6\u7BA1\u7406\u5668\uFF01"));
1467
+ console.log(pc10.green("\u2728 \u6210\u529F\u8C03\u8D77\u6587\u4EF6\u7BA1\u7406\u5668\uFF01"));
1447
1468
  } catch (err) {
1448
1469
  console.error(
1449
- pc9.red("\u274C \u65E0\u6CD5\u6253\u5F00\u7BA1\u7406\u5668:"),
1470
+ pc10.red("\u274C \u65E0\u6CD5\u6253\u5F00\u7BA1\u7406\u5668:"),
1450
1471
  err instanceof Error ? err.message : err
1451
1472
  );
1452
1473
  }
@@ -1454,19 +1475,19 @@ function registerOpenCommand(program2) {
1454
1475
  }
1455
1476
 
1456
1477
  // commands/park.ts
1457
- import fs9, { open } from "fs/promises";
1478
+ import fs10, { open } from "fs/promises";
1458
1479
  import process2 from "process";
1459
- import pc10 from "picocolors";
1460
- import { join as join6, isAbsolute, resolve as resolve8, dirname as dirname5 } from "path";
1480
+ import pc11 from "picocolors";
1481
+ import { join as join7, isAbsolute, resolve as resolve8, dirname as dirname4 } from "path";
1461
1482
  var CONFIG_FILE_NAME = ".park_config.json";
1462
1483
  function getConfigFile() {
1463
1484
  const home = process2.env["HOME"] || process2.env["USERPROFILE"] || process2.cwd();
1464
- return join6(home, CONFIG_FILE_NAME);
1485
+ return join7(home, CONFIG_FILE_NAME);
1465
1486
  }
1466
1487
  async function readConfig() {
1467
1488
  try {
1468
1489
  const path = getConfigFile();
1469
- const content = await fs9.readFile(path, "utf-8");
1490
+ const content = await fs10.readFile(path, "utf-8");
1470
1491
  return JSON.parse(content);
1471
1492
  } catch {
1472
1493
  return {};
@@ -1475,9 +1496,9 @@ async function readConfig() {
1475
1496
  async function writeConfig(config) {
1476
1497
  try {
1477
1498
  const path = getConfigFile();
1478
- await fs9.writeFile(path, JSON.stringify(config, null, 2));
1499
+ await fs10.writeFile(path, JSON.stringify(config, null, 2));
1479
1500
  } catch (err) {
1480
- console.error(pc10.red("\u274C \u5199\u5165\u5168\u5C40\u914D\u7F6E\u6587\u4EF6\u5931\u8D25:"), err);
1501
+ console.error(pc11.red("\u274C \u5199\u5165\u5168\u5C40\u914D\u7F6E\u6587\u4EF6\u5931\u8D25:"), err);
1481
1502
  }
1482
1503
  }
1483
1504
  async function downloadImage(imageName, outputFilename, targetDir) {
@@ -1489,8 +1510,8 @@ async function downloadImage(imageName, outputFilename, targetDir) {
1489
1510
  cleanName = decodeURIComponent(cleanName).substring(prefix.length);
1490
1511
  }
1491
1512
  const fullImageName = prefix + cleanName;
1492
- console.log(pc10.cyan(`\u{1F4E6} \u76EE\u6807\u955C\u50CF: ${pc10.bold(fullImageName)}`));
1493
- console.log(pc10.dim("\u6B63\u5728\u5411\u6253\u5305\u670D\u52A1\u5668\u63D0\u4EA4\u4EFB\u52A1\uFF0C\u8BF7\u7A0D\u5019...\n"));
1513
+ console.log(pc11.cyan(`\u{1F4E6} \u76EE\u6807\u955C\u50CF: ${pc11.bold(fullImageName)}`));
1514
+ console.log(pc11.dim("\u6B63\u5728\u5411\u6253\u5305\u670D\u52A1\u5668\u63D0\u4EA4\u4EFB\u52A1\uFF0C\u8BF7\u7A0D\u5019...\n"));
1494
1515
  try {
1495
1516
  const response = await fetch("https://city189.cn:1091/", {
1496
1517
  method: "POST",
@@ -1527,15 +1548,15 @@ async function downloadImage(imageName, outputFilename, targetDir) {
1527
1548
  matchedFilename = match[0];
1528
1549
  downloadUrl = `https://city189.cn:1091/download/${matchedFilename}`;
1529
1550
  } else {
1530
- console.error(pc10.red("\u274C \u672A\u80FD\u5728\u670D\u52A1\u5668\u54CD\u5E94\u4E2D\u5339\u914D\u5230\u6253\u5305\u6587\u4EF6\u540D\u3002"));
1531
- console.log(pc10.yellow("\u670D\u52A1\u5668\u539F\u59CB\u54CD\u5E94\u5982\u4E0B\uFF1A"));
1551
+ console.error(pc11.red("\u274C \u672A\u80FD\u5728\u670D\u52A1\u5668\u54CD\u5E94\u4E2D\u5339\u914D\u5230\u6253\u5305\u6587\u4EF6\u540D\u3002"));
1552
+ console.log(pc11.yellow("\u670D\u52A1\u5668\u539F\u59CB\u54CD\u5E94\u5982\u4E0B\uFF1A"));
1532
1553
  console.log(text);
1533
1554
  throw new Error("\u65E0\u6CD5\u63D0\u53D6\u6253\u5305\u540E\u7684\u6587\u4EF6\u540D");
1534
1555
  }
1535
1556
  }
1536
- console.log(pc10.green(`\u2705 \u6253\u5305\u4EFB\u52A1\u63D0\u4EA4\u6210\u529F!`));
1537
- console.log(pc10.green(`\u{1F517} \u4E0B\u8F7D\u94FE\u63A5: ${pc10.underline(downloadUrl)}`));
1538
- console.log(pc10.cyan(`
1557
+ console.log(pc11.green(`\u2705 \u6253\u5305\u4EFB\u52A1\u63D0\u4EA4\u6210\u529F!`));
1558
+ console.log(pc11.green(`\u{1F517} \u4E0B\u8F7D\u94FE\u63A5: ${pc11.underline(downloadUrl)}`));
1559
+ console.log(pc11.cyan(`
1539
1560
  \u{1F4E5} \u5F00\u59CB\u4E0B\u8F7D: ${matchedFilename}...`));
1540
1561
  const downloadRes = await fetch(downloadUrl, {
1541
1562
  headers: {
@@ -1560,10 +1581,10 @@ async function downloadImage(imageName, outputFilename, targetDir) {
1560
1581
  downloadDir = config.defaultDownloadDir ? config.defaultDownloadDir : process2.cwd();
1561
1582
  }
1562
1583
  const baseFilename = outputFilename || matchedFilename || "bundle.tar";
1563
- const finalPath = isAbsolute(baseFilename) ? baseFilename : join6(downloadDir, baseFilename);
1564
- const targetDirToCreate = dirname5(finalPath);
1584
+ const finalPath = isAbsolute(baseFilename) ? baseFilename : join7(downloadDir, baseFilename);
1585
+ const targetDirToCreate = dirname4(finalPath);
1565
1586
  try {
1566
- await fs9.mkdir(targetDirToCreate, { recursive: true });
1587
+ await fs10.mkdir(targetDirToCreate, { recursive: true });
1567
1588
  } catch {
1568
1589
  }
1569
1590
  const file = await open(finalPath, "w");
@@ -1590,11 +1611,11 @@ async function downloadImage(imageName, outputFilename, targetDir) {
1590
1611
  }
1591
1612
  }
1592
1613
  await file.close();
1593
- console.log("\n" + pc10.green(`\u2728 \u4E0B\u8F7D\u5E76\u4FDD\u5B58\u6210\u529F! \u6587\u4EF6\u8DEF\u5F84: ${finalPath}`));
1614
+ console.log("\n" + pc11.green(`\u2728 \u4E0B\u8F7D\u5E76\u4FDD\u5B58\u6210\u529F! \u6587\u4EF6\u8DEF\u5F84: ${finalPath}`));
1594
1615
  } catch (error) {
1595
- console.error(pc10.red("\n\u274C \u6267\u884C\u5931\u8D25\u3002"));
1616
+ console.error(pc11.red("\n\u274C \u6267\u884C\u5931\u8D25\u3002"));
1596
1617
  if (error instanceof Error) {
1597
- console.error(pc10.red("\u9519\u8BEF\u8BE6\u60C5:"), error.message);
1618
+ console.error(pc11.red("\u9519\u8BEF\u8BE6\u60C5:"), error.message);
1598
1619
  }
1599
1620
  }
1600
1621
  }
@@ -1607,11 +1628,11 @@ function registerParkCommand(program2) {
1607
1628
  if (options.global) {
1608
1629
  const absPath = resolve8(process2.cwd(), options.global);
1609
1630
  await writeConfig({ defaultDownloadDir: absPath });
1610
- console.log(pc10.green(`\u2728 \u5DF2\u6210\u529F\u8BBE\u7F6E\u5168\u5C40\u9ED8\u8BA4\u4E0B\u8F7D\u76EE\u5F55\u4E3A: ${absPath}`));
1631
+ console.log(pc11.green(`\u2728 \u5DF2\u6210\u529F\u8BBE\u7F6E\u5168\u5C40\u9ED8\u8BA4\u4E0B\u8F7D\u76EE\u5F55\u4E3A: ${absPath}`));
1611
1632
  return;
1612
1633
  }
1613
1634
  if (!image) {
1614
- console.error(pc10.red("\u274C \u9519\u8BEF: \u672A\u6307\u5B9A\u9700\u8981\u4E0B\u8F7D\u7684\u955C\u50CF\u540D\u79F0\u3002"));
1635
+ console.error(pc11.red("\u274C \u9519\u8BEF: \u672A\u6307\u5B9A\u9700\u8981\u4E0B\u8F7D\u7684\u955C\u50CF\u540D\u79F0\u3002"));
1615
1636
  cmd.outputHelp();
1616
1637
  return;
1617
1638
  }
@@ -1621,7 +1642,7 @@ function registerParkCommand(program2) {
1621
1642
  }
1622
1643
 
1623
1644
  // commands/proxy.ts
1624
- import pc11 from "picocolors";
1645
+ import pc12 from "picocolors";
1625
1646
  function registerProxyCommand(program2) {
1626
1647
  program2.command("proxy [action] [port]").description(
1627
1648
  "\u7BA1\u7406\u7EC8\u7AEF\u4E34\u65F6\u4EE3\u7406 (\u652F\u6301 proxy on [port] \u6216 proxy off\uFF0C\u65E0\u53C2\u6570\u65F6\u67E5\u770B\u5F53\u524D\u72B6\u6001)"
@@ -1629,29 +1650,29 @@ function registerProxyCommand(program2) {
1629
1650
  if (action === "on") {
1630
1651
  const p = port || "7890";
1631
1652
  console.log(
1632
- pc11.yellow(
1653
+ pc12.yellow(
1633
1654
  `\u26A0\uFE0F \u8B66\u544A: \u76F4\u63A5\u8FD0\u884C\u4E8C\u8FDB\u5236\u65E0\u6CD5\u76F4\u63A5\u4FEE\u6539\u5F53\u524D\u7EC8\u7AEF\u7684\u4E3B\u73AF\u5883\u53D8\u91CF\u3002`
1634
1655
  )
1635
1656
  );
1636
- console.log(pc11.cyan(`\u{1F449} \u8BF7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u624B\u52A8\u542F\u7528\u4EE3\u7406\uFF1A`));
1637
- console.log(pc11.bold(` export http_proxy="http://127.0.0.1:${p}"`));
1638
- console.log(pc11.bold(` export https_proxy="http://127.0.0.1:${p}"`));
1639
- console.log(pc11.bold(` export all_proxy="socks5://127.0.0.1:${p}"`));
1657
+ console.log(pc12.cyan(`\u{1F449} \u8BF7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u624B\u52A8\u542F\u7528\u4EE3\u7406\uFF1A`));
1658
+ console.log(pc12.bold(` export http_proxy="http://127.0.0.1:${p}"`));
1659
+ console.log(pc12.bold(` export https_proxy="http://127.0.0.1:${p}"`));
1660
+ console.log(pc12.bold(` export all_proxy="socks5://127.0.0.1:${p}"`));
1640
1661
  console.log(
1641
- pc11.dim(
1662
+ pc12.dim(
1642
1663
  `
1643
1664
  \u{1F4A1} \u63D0\u793A\uFF1A\u6267\u884C\u4E00\u6B21 'xx completion' \u5E76\u91CD\u5F00\u7EC8\u7AEF\u540E\uFF0C\u5373\u53EF\u76F4\u63A5\u8FD0\u884C 'xx proxy on' \u4E00\u952E\u5F00\u542F\uFF01`
1644
1665
  )
1645
1666
  );
1646
1667
  } else if (action === "off") {
1647
1668
  console.log(
1648
- pc11.yellow(
1669
+ pc12.yellow(
1649
1670
  `\u26A0\uFE0F \u8B66\u544A: \u76F4\u63A5\u8FD0\u884C\u4E8C\u8FDB\u5236\u65E0\u6CD5\u76F4\u63A5\u4FEE\u6539\u5F53\u524D\u7EC8\u7AEF\u7684\u4E3B\u73AF\u5883\u53D8\u91CF\u3002`
1650
1671
  )
1651
1672
  );
1652
- console.log(pc11.cyan(`\u{1F449} \u8BF7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u624B\u52A8\u5173\u95ED\u4EE3\u7406\uFF1A`));
1673
+ console.log(pc12.cyan(`\u{1F449} \u8BF7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u624B\u52A8\u5173\u95ED\u4EE3\u7406\uFF1A`));
1653
1674
  console.log(
1654
- pc11.bold(
1675
+ pc12.bold(
1655
1676
  ` unset http_proxy https_proxy all_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY`
1656
1677
  )
1657
1678
  );
@@ -1660,15 +1681,15 @@ function registerProxyCommand(program2) {
1660
1681
  const httpsProxy = process.env["https_proxy"] || process.env["HTTPS_PROXY"];
1661
1682
  const allProxy = process.env["all_proxy"] || process.env["ALL_PROXY"];
1662
1683
  if (httpProxy || httpsProxy || allProxy) {
1663
- console.log(pc11.yellow("\u{1F50D} [xx] \u68C0\u6D4B\u5230\u5F53\u524D\u7EC8\u7AEF\u5DF2\u914D\u7F6E\u4E34\u65F6\u4EE3\u7406\uFF1A"));
1664
- if (httpProxy) console.log(` http_proxy = ${pc11.bold(httpProxy)}`);
1665
- if (httpsProxy) console.log(` https_proxy = ${pc11.bold(httpsProxy)}`);
1666
- if (allProxy) console.log(` all_proxy = ${pc11.bold(allProxy)}`);
1684
+ console.log(pc12.yellow("\u{1F50D} [xx] \u68C0\u6D4B\u5230\u5F53\u524D\u7EC8\u7AEF\u5DF2\u914D\u7F6E\u4E34\u65F6\u4EE3\u7406\uFF1A"));
1685
+ if (httpProxy) console.log(` http_proxy = ${pc12.bold(httpProxy)}`);
1686
+ if (httpsProxy) console.log(` https_proxy = ${pc12.bold(httpsProxy)}`);
1687
+ if (allProxy) console.log(` all_proxy = ${pc12.bold(allProxy)}`);
1667
1688
  } else {
1668
- console.log(pc11.green("\u{1F50D} [xx] \u5F53\u524D\u7EC8\u7AEF\u672A\u914D\u7F6E\u4EFB\u4F55\u4EE3\u7406 (\u76F4\u8FDE\u6A21\u5F0F)"));
1689
+ console.log(pc12.green("\u{1F50D} [xx] \u5F53\u524D\u7EC8\u7AEF\u672A\u914D\u7F6E\u4EFB\u4F55\u4EE3\u7406 (\u76F4\u8FDE\u6A21\u5F0F)"));
1669
1690
  }
1670
1691
  console.log(
1671
- pc11.dim(
1692
+ pc12.dim(
1672
1693
  "\n\u{1F4A1} \u63D0\u793A\uFF1A\u60A8\u53EF\u4EE5\u4F7F\u7528 'xx proxy on [port]' \u5F00\u542F\u6216 'xx proxy off' \u5173\u95ED\u4E34\u65F6\u4EE3\u7406\u3002"
1673
1694
  )
1674
1695
  );
@@ -1677,15 +1698,15 @@ function registerProxyCommand(program2) {
1677
1698
  }
1678
1699
 
1679
1700
  // commands/remove.ts
1680
- import fs10 from "fs/promises";
1681
- import pc12 from "picocolors";
1701
+ import fs11 from "fs/promises";
1702
+ import pc13 from "picocolors";
1682
1703
  import { resolve as resolve9 } from "path";
1683
1704
  import fg from "fast-glob";
1684
1705
  import trash from "trash";
1685
1706
  function registerRemoveCommand(program2) {
1686
1707
  program2.command("remove <paths...>").description("\u5B89\u5168\u5730\u5C06\u6307\u5B9A\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u79FB\u81F3\u7CFB\u7EDF\u56DE\u6536\u7AD9\uFF08\u652F\u6301\u901A\u914D\u7B26\u53CA\u591A\u9009\uFF09").action(async (paths) => {
1687
1708
  if (!paths || paths.length === 0) {
1688
- console.error(pc12.red("\u274C \u8BF7\u63D0\u4F9B\u8981\u653E\u5165\u56DE\u6536\u7AD9\u7684\u8DEF\u5F84\u6216\u901A\u914D\u7B26\u89C4\u5219"));
1709
+ console.error(pc13.red("\u274C \u8BF7\u63D0\u4F9B\u8981\u653E\u5165\u56DE\u6536\u7AD9\u7684\u8DEF\u5F84\u6216\u901A\u914D\u7B26\u89C4\u5219"));
1689
1710
  return;
1690
1711
  }
1691
1712
  const resolvedPathsToDelete = /* @__PURE__ */ new Set();
@@ -1705,21 +1726,21 @@ function registerRemoveCommand(program2) {
1705
1726
  }
1706
1727
  } catch (err) {
1707
1728
  console.error(
1708
- pc12.red(`\u274C \u5339\u914D\u901A\u914D\u7B26 '${pattern}' \u65F6\u53D1\u751F\u5F02\u5E38:`),
1729
+ pc13.red(`\u274C \u5339\u914D\u901A\u914D\u7B26 '${pattern}' \u65F6\u53D1\u751F\u5F02\u5E38:`),
1709
1730
  err instanceof Error ? err.message : err
1710
1731
  );
1711
1732
  }
1712
1733
  } else {
1713
1734
  const absolutePath = resolve9(process.cwd(), pattern);
1714
1735
  try {
1715
- await fs10.stat(absolutePath);
1736
+ await fs11.stat(absolutePath);
1716
1737
  resolvedPathsToDelete.add(absolutePath);
1717
1738
  } catch (err) {
1718
1739
  if (isNotFoundError(err)) {
1719
1740
  notFoundPaths.push(absolutePath);
1720
1741
  } else {
1721
1742
  console.error(
1722
- pc12.red(`\u274C \u83B7\u53D6\u8DEF\u5F84\u72B6\u6001\u5931\u8D25 [${pattern}]:`),
1743
+ pc13.red(`\u274C \u83B7\u53D6\u8DEF\u5F84\u72B6\u6001\u5931\u8D25 [${pattern}]:`),
1723
1744
  err instanceof Error ? err.message : err
1724
1745
  );
1725
1746
  }
@@ -1728,31 +1749,31 @@ function registerRemoveCommand(program2) {
1728
1749
  }
1729
1750
  if (notFoundPaths.length > 0) {
1730
1751
  for (const path of notFoundPaths) {
1731
- console.error(pc12.red(`\u274C \u8DEF\u5F84\u4E0D\u5B58\u5728: ${path}`));
1752
+ console.error(pc13.red(`\u274C \u8DEF\u5F84\u4E0D\u5B58\u5728: ${path}`));
1732
1753
  }
1733
1754
  }
1734
1755
  if (resolvedPathsToDelete.size === 0) {
1735
- console.log(pc12.yellow("\u2139\uFE0F \u672A\u80FD\u627E\u5230\u4EFB\u4F55\u4E0E\u6307\u5B9A\u6761\u4EF6\u5339\u914D\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u3002"));
1756
+ console.log(pc13.yellow("\u2139\uFE0F \u672A\u80FD\u627E\u5230\u4EFB\u4F55\u4E0E\u6307\u5B9A\u6761\u4EF6\u5339\u914D\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u3002"));
1736
1757
  return;
1737
1758
  }
1738
1759
  try {
1739
1760
  console.log(
1740
- pc12.cyan(
1761
+ pc13.cyan(
1741
1762
  `\u{1F4E6} \u6B63\u5728\u5C06 ${resolvedPathsToDelete.size} \u4E2A\u9879\u79FB\u81F3\u7CFB\u7EDF\u56DE\u6536\u7AD9...`
1742
1763
  )
1743
1764
  );
1744
1765
  await trash(Array.from(resolvedPathsToDelete));
1745
1766
  for (const path of resolvedPathsToDelete) {
1746
- console.log(pc12.dim(` - \u5DF2\u79FB\u5165\u5783\u573E\u7BB1: ${path}`));
1767
+ console.log(pc13.dim(` - \u5DF2\u79FB\u5165\u5783\u573E\u7BB1: ${path}`));
1747
1768
  }
1748
1769
  console.log(
1749
- pc12.green(
1770
+ pc13.green(
1750
1771
  `\u2728 \u6210\u529F\uFF01\u5171 ${resolvedPathsToDelete.size} \u4E2A\u6587\u4EF6/\u76EE\u5F55\u5DF2\u5B89\u5168\u9001\u81F3\u7CFB\u7EDF\u56DE\u6536\u7AD9\u3002`
1751
1772
  )
1752
1773
  );
1753
1774
  } catch (err) {
1754
1775
  console.error(
1755
- pc12.red("\u274C \u79FB\u81F3\u56DE\u6536\u7AD9\u5931\u8D25:"),
1776
+ pc13.red("\u274C \u79FB\u81F3\u56DE\u6536\u7AD9\u5931\u8D25:"),
1756
1777
  err instanceof Error ? err.message : err
1757
1778
  );
1758
1779
  }
@@ -1760,32 +1781,32 @@ function registerRemoveCommand(program2) {
1760
1781
  }
1761
1782
 
1762
1783
  // commands/search.ts
1763
- import fs11 from "fs/promises";
1764
- import pc13 from "picocolors";
1765
- import { resolve as resolve10, basename as basename4, relative } from "path";
1784
+ import fs12 from "fs/promises";
1785
+ import pc14 from "picocolors";
1786
+ import { resolve as resolve10, basename as basename5, relative } from "path";
1766
1787
  import fg2 from "fast-glob";
1767
1788
  function registerSearchCommand(program2) {
1768
1789
  program2.command("search <keyword> [directory]").description(
1769
1790
  "\u9012\u5F52\u641C\u7D22\u76EE\u5F55\u4E0B\u5305\u542B\u6307\u5B9A\u5173\u952E\u8BCD\u7684\u6587\u4EF6\u6216\u76EE\u5F55\uFF08\u652F\u6301 Ctrl+\u70B9\u51FB \u5FEB\u6377\u6253\u5F00\uFF09"
1770
1791
  ).action(async (keyword, directory) => {
1771
1792
  if (!keyword) {
1772
- console.error(pc13.red("\u274C \u8BF7\u63D0\u4F9B\u8981\u641C\u7D22\u7684\u6587\u4EF6\u540D\u5173\u952E\u8BCD"));
1793
+ console.error(pc14.red("\u274C \u8BF7\u63D0\u4F9B\u8981\u641C\u7D22\u7684\u6587\u4EF6\u540D\u5173\u952E\u8BCD"));
1773
1794
  return;
1774
1795
  }
1775
1796
  const startDir = directory || ".";
1776
1797
  const absoluteStartDir = resolve10(process.cwd(), startDir);
1777
1798
  try {
1778
- const stat = await fs11.stat(absoluteStartDir);
1799
+ const stat = await fs12.stat(absoluteStartDir);
1779
1800
  if (!stat.isDirectory()) {
1780
- console.error(pc13.red(`\u274C \u9519\u8BEF: '${startDir}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
1801
+ console.error(pc14.red(`\u274C \u9519\u8BEF: '${startDir}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
1781
1802
  return;
1782
1803
  }
1783
1804
  } catch {
1784
- console.error(pc13.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u8D77\u70B9\u76EE\u5F55 '${startDir}'\u3002`));
1805
+ console.error(pc14.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u8D77\u70B9\u76EE\u5F55 '${startDir}'\u3002`));
1785
1806
  return;
1786
1807
  }
1787
1808
  console.log(
1788
- pc13.cyan(
1809
+ pc14.cyan(
1789
1810
  `\u{1F50D} \u6B63\u5728\u76EE\u5F55 ${absoluteStartDir} \u4E2D\u9012\u5F52\u641C\u5BFB\u5305\u542B "${keyword}" \u7684\u9879\u76EE...
1790
1811
  `
1791
1812
  )
@@ -1806,30 +1827,30 @@ function registerSearchCommand(program2) {
1806
1827
  ]
1807
1828
  });
1808
1829
  for (const entryPath of entries) {
1809
- const name = basename4(entryPath);
1830
+ const name = basename5(entryPath);
1810
1831
  if (name.toLowerCase().includes(keyword.toLowerCase())) {
1811
1832
  matchCount++;
1812
1833
  const relativePath = relative(absoluteStartDir, entryPath);
1813
1834
  const isDirectory = !name.includes(".") || entryPath.endsWith("/");
1814
1835
  let isDir = isDirectory;
1815
1836
  try {
1816
- const entryStat = await fs11.stat(entryPath);
1837
+ const entryStat = await fs12.stat(entryPath);
1817
1838
  isDir = entryStat.isDirectory();
1818
1839
  } catch {
1819
1840
  }
1820
1841
  const typeIcon = isDir ? "\u{1F4C1}" : "\u{1F4C4}";
1821
1842
  const fileUri = `file://${entryPath}`;
1822
- const hyperlink = `\x1B]8;;${fileUri}\x1B\\${pc13.bold(name)}\x1B]8;;\x1B\\`;
1823
- console.log(`${typeIcon} ${hyperlink} -> ${pc13.dim(fileUri)}`);
1843
+ const hyperlink = `\x1B]8;;${fileUri}\x1B\\${pc14.bold(name)}\x1B]8;;\x1B\\`;
1844
+ console.log(`${typeIcon} ${hyperlink} -> ${pc14.dim(fileUri)}`);
1824
1845
  }
1825
1846
  }
1826
1847
  console.log(
1827
- pc13.green(`
1848
+ pc14.green(`
1828
1849
  \u2728 \u641C\u7D22\u5B8C\u6210\uFF01\u5171\u627E\u5230 ${matchCount} \u4E2A\u5339\u914D\u7684\u9879\u76EE\u3002`)
1829
1850
  );
1830
1851
  } catch (err) {
1831
1852
  console.error(
1832
- pc13.red("\u274C \u641C\u5BFB\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:"),
1853
+ pc14.red("\u274C \u641C\u5BFB\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:"),
1833
1854
  err instanceof Error ? err.message : err
1834
1855
  );
1835
1856
  }
@@ -1837,7 +1858,7 @@ function registerSearchCommand(program2) {
1837
1858
  }
1838
1859
 
1839
1860
  // commands/translate.ts
1840
- import pc14 from "picocolors";
1861
+ import pc15 from "picocolors";
1841
1862
  import { translate } from "google-translate-api-x";
1842
1863
  import readline from "readline";
1843
1864
  import process3 from "process";
@@ -1854,13 +1875,13 @@ async function performTranslation(text, userSpecifiedLang) {
1854
1875
  to: targetLang
1855
1876
  });
1856
1877
  console.log(
1857
- `${pc14.green("\u8BD1\u6587:")} ${pc14.bold(res.text)} ${pc14.dim(`(${res.from.language.iso} -> ${targetLang})`)}`
1878
+ `${pc15.green("\u8BD1\u6587:")} ${pc15.bold(res.text)} ${pc15.dim(`(${res.from.language.iso} -> ${targetLang})`)}`
1858
1879
  );
1859
1880
  } catch (err) {
1860
1881
  if (err instanceof Error) {
1861
- console.error(pc14.red("\u274C \u7FFB\u8BD1\u51FA\u9519:"), err.message);
1882
+ console.error(pc15.red("\u274C \u7FFB\u8BD1\u51FA\u9519:"), err.message);
1862
1883
  } else {
1863
- console.error(pc14.red("\u274C \u7FFB\u8BD1\u51FA\u9519:"), String(err));
1884
+ console.error(pc15.red("\u274C \u7FFB\u8BD1\u51FA\u9519:"), String(err));
1864
1885
  }
1865
1886
  }
1866
1887
  }
@@ -1868,11 +1889,11 @@ function startInteractiveMode(userSpecifiedLang) {
1868
1889
  const rl = readline.createInterface({
1869
1890
  input: process3.stdin,
1870
1891
  output: process3.stdout,
1871
- prompt: pc14.cyan("\u7FFB\u8BD1\u8F93\u5165 > ")
1892
+ prompt: pc15.cyan("\u7FFB\u8BD1\u8F93\u5165 > ")
1872
1893
  });
1873
1894
  const modeTip = userSpecifiedLang === "auto" ? "\u667A\u80FD\u81EA\u52A8\u8BC6\u522B" : `\u5F3A\u5236\u76EE\u6807\u8BED\u8A00: ${userSpecifiedLang}`;
1874
- console.log(pc14.yellow(`\u2728 \u5DF2\u8FDB\u5165\u4EA4\u4E92\u6A21\u5F0F (${modeTip})`));
1875
- console.log(pc14.dim('\u8F93\u5165 "exit" \u6216\u6309 Ctrl+C \u9000\u51FA\n'));
1895
+ console.log(pc15.yellow(`\u2728 \u5DF2\u8FDB\u5165\u4EA4\u4E92\u6A21\u5F0F (${modeTip})`));
1896
+ console.log(pc15.dim('\u8F93\u5165 "exit" \u6216\u6309 Ctrl+C \u9000\u51FA\n'));
1876
1897
  rl.prompt();
1877
1898
  rl.on("line", async (line) => {
1878
1899
  const input = line.trim();
@@ -1886,7 +1907,7 @@ function startInteractiveMode(userSpecifiedLang) {
1886
1907
  console.log();
1887
1908
  rl.prompt();
1888
1909
  }).on("close", () => {
1889
- console.log(pc14.blue("\n\u518D\u89C1!"));
1910
+ console.log(pc15.blue("\n\u518D\u89C1!"));
1890
1911
  process3.exit(0);
1891
1912
  });
1892
1913
  }
@@ -1905,464 +1926,33 @@ function registerTanslateCommand(program2) {
1905
1926
  }
1906
1927
 
1907
1928
  // commands/uninstall.ts
1908
- import fs12 from "fs/promises";
1909
- import pc15 from "picocolors";
1910
- import { resolve as resolve11, join as join7 } from "path";
1911
- function getHomeDir2() {
1912
- return process.env["HOME"] || process.env["USERPROFILE"] || process.cwd();
1913
- }
1914
- async function isSnapInstalled(packageName) {
1915
- if (!await isCommandAvailable("snap")) return false;
1916
- try {
1917
- const { success } = await runCommand("snap", ["list", packageName]);
1918
- return success;
1919
- } catch {
1920
- return false;
1921
- }
1922
- }
1923
- async function isSystemPackageInstalled(packageName) {
1924
- try {
1925
- const osRelease = await fs12.readFile("/etc/os-release", "utf-8");
1926
- if (osRelease.includes("fedora") || osRelease.includes("rhel") || osRelease.includes("centos")) {
1927
- const { success } = await runCommand("rpm", ["-q", packageName]);
1928
- return success;
1929
- } else {
1930
- const { success, stdout } = await runCommand("dpkg-query", [
1931
- "-W",
1932
- "-f=${Status}",
1933
- packageName
1934
- ]);
1935
- if (success) {
1936
- const status = decodeOutput(stdout).trim();
1937
- return status.includes("installed");
1938
- }
1939
- return false;
1940
- }
1941
- } catch {
1942
- return false;
1943
- }
1944
- }
1945
- async function findGreenAppPath(appName) {
1946
- const home = getHomeDir2();
1947
- const greenAppDir = join7(home, "GreenApp");
1948
- const dirPath = join7(greenAppDir, appName);
1949
- try {
1950
- const stat = await fs12.stat(dirPath);
1951
- if (stat.isDirectory()) return dirPath;
1952
- } catch {
1953
- }
1954
- const appImagePath = join7(greenAppDir, `${appName}.AppImage`);
1955
- const appImageLowerPath = join7(greenAppDir, `${appName}.appimage`);
1956
- try {
1957
- const stat = await fs12.stat(appImagePath);
1958
- if (stat.isFile()) return appImagePath;
1959
- } catch {
1960
- try {
1961
- const stat = await fs12.stat(appImageLowerPath);
1962
- if (stat.isFile()) return appImageLowerPath;
1963
- } catch {
1964
- }
1965
- }
1966
- if (appName.toLowerCase().endsWith(".appimage")) {
1967
- const directPath = join7(greenAppDir, appName);
1968
- try {
1969
- const stat = await fs12.stat(directPath);
1970
- if (stat.isFile()) return directPath;
1971
- } catch {
1972
- }
1973
- }
1974
- return null;
1975
- }
1976
- async function extractDebPackageName(absPath) {
1977
- try {
1978
- const { success, stdout } = await runCommand("dpkg-deb", [
1979
- "-f",
1980
- absPath,
1981
- "Package"
1982
- ]);
1983
- if (success) {
1984
- return decodeOutput(stdout).trim();
1985
- }
1986
- } catch {
1987
- }
1988
- return void 0;
1989
- }
1990
- async function extractRpmPackageName(absPath) {
1991
- try {
1992
- const { success, stdout } = await runCommand("rpm", [
1993
- "-qp",
1994
- "--queryformat",
1995
- "%{NAME}",
1996
- absPath
1997
- ]);
1998
- if (success) {
1999
- return decodeOutput(stdout).trim();
2000
- }
2001
- } catch {
2002
- }
2003
- return void 0;
2004
- }
2005
- async function searchGreenApps(query) {
2006
- const home = getHomeDir2();
2007
- const greenAppDir = join7(home, "GreenApp");
2008
- const candidates = [];
2009
- try {
2010
- for (const entry of await fs12.readdir(greenAppDir, {
2011
- withFileTypes: true
2012
- })) {
2013
- if (entry.name.toLowerCase().includes(query.toLowerCase())) {
2014
- candidates.push(entry.name.replace(/\.appimage/i, ""));
2015
- }
2016
- }
2017
- } catch {
2018
- }
2019
- return candidates;
2020
- }
2021
- async function searchFlatpaks(query) {
2022
- const candidates = [];
2023
- if (!await isCommandAvailable("flatpak")) return candidates;
2024
- try {
2025
- const { success, stdout } = await runCommand("flatpak", [
2026
- "list",
2027
- "--columns=application,name"
2028
- ]);
2029
- if (success) {
2030
- const output = decodeOutput(stdout).trim();
2031
- const lines = output.split("\n");
2032
- for (const line of lines) {
2033
- const parts = line.split(" ").map((p) => p.trim());
2034
- if (parts.length >= 2) {
2035
- const [id, name] = parts;
2036
- if (id.toLowerCase().includes(query.toLowerCase()) || name.toLowerCase().includes(query.toLowerCase())) {
2037
- candidates.push({ id, name });
2038
- }
2039
- }
2040
- }
2041
- }
2042
- } catch {
2043
- }
2044
- return candidates;
2045
- }
2046
- async function searchDebPackages(query) {
2047
- const pkgs = [];
2048
- try {
2049
- const { success, stdout } = await runCommand("dpkg-query", [
2050
- "-W",
2051
- "-f=${Package}\n",
2052
- `*${query}*`
2053
- ]);
2054
- if (success) {
2055
- const output = decodeOutput(stdout).trim();
2056
- const lines = output.split("\n");
2057
- for (const line of lines) {
2058
- const name = line.trim();
2059
- if (name && !name.startsWith("-f=")) {
2060
- pkgs.push(name);
2061
- }
2062
- }
2063
- }
2064
- } catch {
2065
- }
2066
- return pkgs;
2067
- }
2068
- async function searchRpmPackages(query) {
2069
- const pkgs = [];
2070
- try {
2071
- const { success, stdout } = await runCommand("rpm", [
2072
- "-qa",
2073
- "--queryformat",
2074
- "%{NAME}\n",
2075
- `*${query}*`
2076
- ]);
2077
- if (success) {
2078
- const output = decodeOutput(stdout).trim();
2079
- const lines = output.split("\n");
2080
- const uniquePkgs = /* @__PURE__ */ new Set();
2081
- for (const line of lines) {
2082
- const name = line.trim();
2083
- if (name) {
2084
- uniquePkgs.add(name);
2085
- }
2086
- }
2087
- pkgs.push(...uniquePkgs);
2088
- }
2089
- } catch {
2090
- }
2091
- return pkgs;
2092
- }
2093
- async function removeDeb(packageName) {
2094
- console.log(pc15.cyan(`\u{1F4E6} \u6B63\u5728\u901A\u8FC7 apt \u5378\u8F7D DEB \u8F6F\u4EF6\u5305: ${packageName}...`));
2095
- const status = await spawnCommand("sudo", [
2096
- "apt-get",
2097
- "remove",
2098
- "-y",
2099
- packageName
2100
- ]);
2101
- if (status.success) {
2102
- console.log(pc15.green(`\u2714 \u8F6F\u4EF6\u5305 ${packageName} \u5DF2\u6210\u529F\u4ECE\u7CFB\u7EDF\u4E2D\u79FB\u9664\u3002`));
2103
- } else {
2104
- console.error(pc15.red(`\u274C \u5378\u8F7D\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`));
2105
- }
2106
- }
2107
- async function removeRpm(packageName) {
2108
- console.log(pc15.cyan(`\u{1F4E6} \u6B63\u5728\u901A\u8FC7 dnf \u5378\u8F7D RPM \u8F6F\u4EF6\u5305: ${packageName}...`));
2109
- const status = await spawnCommand("sudo", [
2110
- "dnf",
2111
- "remove",
2112
- "-y",
2113
- packageName
2114
- ]);
2115
- if (status.success) {
2116
- console.log(pc15.green(`\u2714 \u8F6F\u4EF6\u5305 ${packageName} \u5DF2\u6210\u529F\u4ECE\u7CFB\u7EDF\u4E2D\u79FB\u9664\u3002`));
2117
- } else {
2118
- console.error(pc15.red(`\u274C \u5378\u8F7D\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`));
2119
- }
2120
- }
2121
- async function removeSnap(packageName) {
2122
- console.log(pc15.cyan(`\u{1F4E6} \u6B63\u5728\u901A\u8FC7 snap \u5378\u8F7D\u8F6F\u4EF6\u5305: ${packageName}...`));
2123
- const status = await spawnCommand("sudo", ["snap", "remove", packageName]);
2124
- if (status.success) {
2125
- console.log(pc15.green(`\u2714 Snap \u8F6F\u4EF6\u5305 ${packageName} \u5DF2\u6210\u529F\u4ECE\u7CFB\u7EDF\u4E2D\u79FB\u9664\u3002`));
2126
- } else {
2127
- console.error(pc15.red(`\u274C \u5378\u8F7D\u5931\u8D25\uFF0C\u9000\u51FA\u7801: ${status.code}`));
2128
- }
2129
- }
2130
- async function uninstallFlatpak(packageName) {
2131
- if (!await isCommandAvailable("flatpak")) {
2132
- console.error(pc15.red("\u274C \u5F53\u524D\u7CFB\u7EDF\u4E2D\u672A\u68C0\u6D4B\u5230\u5DF2\u5B89\u88C5\u7684 flatpak \u5DE5\u5177\u3002"));
2133
- return;
2134
- }
2135
- console.log(pc15.cyan(`\u{1F4E6} \u6B63\u5728\u901A\u8FC7 flatpak \u5378\u8F7D\u5E94\u7528: ${packageName}...`));
2136
- const status = await spawnCommand("flatpak", [
2137
- "uninstall",
2138
- "-y",
2139
- packageName
2140
- ]);
2141
- if (status.success) {
2142
- const home = getHomeDir2();
2143
- const desktopPath = join7(
2144
- home,
2145
- ".local/share/applications",
2146
- `flatpak-${packageName}.desktop`
2147
- );
2148
- try {
2149
- await fs12.rm(desktopPath);
2150
- console.log(pc15.green(`\u2714 \u5DF2\u6E05\u9664 Flatpak \u5173\u8054\u684C\u9762\u5FEB\u6377\u56FE\u6807\u3002`));
2151
- } catch {
2152
- }
2153
- console.log(pc15.green("\u2728 Flatpak \u5E94\u7528\u53CA\u56FE\u6807\u6E05\u7406\u5B8C\u6210\uFF01"));
2154
- }
2155
- }
2156
- async function performRemoveGreenApp(greenPath, appName) {
2157
- const home = getHomeDir2();
2158
- const applicationsDir = join7(home, ".local/share/applications");
2159
- try {
2160
- for (const entry of await fs12.readdir(applicationsDir, {
2161
- withFileTypes: true
2162
- })) {
2163
- if (entry.isFile() && entry.name.endsWith(".desktop")) {
2164
- const filePath = join7(applicationsDir, entry.name);
2165
- const content = await fs12.readFile(filePath, "utf-8");
2166
- if (content.includes(greenPath) || content.includes(appName)) {
2167
- await fs12.rm(filePath);
2168
- console.log(pc15.green(`\u2714 \u5DF2\u6E05\u9664\u684C\u9762\u5FEB\u6377\u56FE\u6807: ${filePath}`));
2169
- }
2170
- }
1929
+ import pc16 from "picocolors";
1930
+ function registerUninstallCommand(program2) {
1931
+ program2.command("uninstall <package>").description("macOS \u672C\u5730\u5DE5\u5177\u5378\u8F7D\u5668\uFF08\u79FB\u9664\u5B89\u88C5\u76EE\u5F55\u548C\u7EC8\u7AEF\u547D\u4EE4\u5165\u53E3\uFF09").action(async (pkg) => {
1932
+ if (!ensureMacOS()) return;
1933
+ if (!pkg) {
1934
+ console.error(pc16.red("\u274C \u8BF7\u63D0\u4F9B\u8981\u5378\u8F7D\u7684\u5E94\u7528\u540D\u3002"));
1935
+ return;
2171
1936
  }
2172
- } catch {
2173
- }
2174
- try {
2175
- await fs12.rm(greenPath, { recursive: true });
2176
- console.log(pc15.green(`\u2714 \u5DF2\u6210\u529F\u6E05\u9664\u7EFF\u8272\u8F6F\u4EF6\u4E3B\u4F53: ${greenPath}`));
2177
- } catch (err) {
2178
- console.error(
2179
- pc15.red(`\u274C \u6E05\u9664\u8F6F\u4EF6\u4E3B\u4F53\u5931\u8D25:`),
2180
- err instanceof Error ? err.message : err
2181
- );
2182
- }
2183
- }
2184
- async function performFuzzySearchAndRecommendation(query) {
2185
- const hasSnap = await isCommandAvailable("snap");
2186
- const [greenCands, flatpakCands, snapCands] = await Promise.all([
2187
- searchGreenApps(query),
2188
- searchFlatpaks(query),
2189
- hasSnap ? (async () => {
2190
- const candidates = [];
2191
- try {
2192
- const { success, stdout } = await runCommand("snap", ["list"]);
2193
- if (success) {
2194
- const lines = decodeOutput(stdout).split("\n");
2195
- for (let i = 1; i < lines.length; i++) {
2196
- const name = lines[i].trim().split(/\s+/)[0];
2197
- if (name && name.toLowerCase().includes(query.toLowerCase())) {
2198
- candidates.push(name);
2199
- }
2200
- }
2201
- }
2202
- } catch {
2203
- }
2204
- return candidates;
2205
- })() : Promise.resolve([])
2206
- ]);
2207
- let systemCands = [];
2208
- try {
2209
- const osRelease = await fs12.readFile("/etc/os-release", "utf-8");
2210
- if (osRelease.includes("fedora") || osRelease.includes("rhel") || osRelease.includes("centos")) {
2211
- systemCands = await searchRpmPackages(query);
2212
- } else {
2213
- systemCands = await searchDebPackages(query);
1937
+ const removed = await removeInstalledApp(pkg);
1938
+ if (removed) {
1939
+ console.log(pc16.green("\u2728 \u5378\u8F7D\u5B8C\u6210\uFF01\u76F8\u5173\u7EC8\u7AEF\u547D\u4EE4\u5165\u53E3\u4E5F\u5DF2\u6E05\u7406\u3002"));
1940
+ return;
2214
1941
  }
2215
- } catch {
2216
- systemCands = await searchDebPackages(query);
2217
- }
2218
- const totalCands = greenCands.length + flatpakCands.length + snapCands.length + systemCands.length;
2219
- if (totalCands > 0) {
2220
- console.log(
2221
- pc15.cyan(
2222
- `\u{1F4A1} \u5E2E\u60A8\u5728\u7CFB\u7EDF\u4E2D\u641C\u5BFB\u5230\u4EE5\u4E0B ${totalCands} \u4E2A\u5305\u542B "${query}" \u7684\u76F8\u5173\u5339\u914D\u9879\uFF1A
2223
- `
2224
- )
1942
+ const candidates = (await listInstalledApps()).filter(
1943
+ (name) => name.toLowerCase().includes(pkg.toLowerCase())
2225
1944
  );
2226
- if (greenCands.length > 0) {
2227
- console.log(pc15.bold(pc15.green("\u{1F4C1} [\u7EFF\u8272\u5E94\u7528] \u5019\u9009\uFF1A")));
2228
- for (const cand of greenCands) {
2229
- console.log(
2230
- ` - ${cand} ${pc15.dim(`(\u5378\u8F7D\u547D\u4EE4: xx uninstall ${cand})`)}`
2231
- );
2232
- }
2233
- }
2234
- if (flatpakCands.length > 0) {
2235
- console.log(pc15.bold(pc15.magenta("\n\u{1F4E6} [Flatpak] \u5019\u9009\uFF1A")));
2236
- for (const cand of flatpakCands) {
2237
- console.log(
2238
- ` - ${cand.id} [${cand.name}] ${pc15.dim(`(\u5378\u8F7D\u547D\u4EE4: xx uninstall ${cand.id})`)}`
2239
- );
2240
- }
2241
- }
2242
- if (snapCands.length > 0) {
2243
- console.log(pc15.bold(pc15.yellow("\n\u26A1 [Snap] \u5019\u9009\uFF1A")));
2244
- for (const cand of snapCands) {
2245
- console.log(
2246
- ` - ${cand} ${pc15.dim(`(\u5378\u8F7D\u547D\u4EE4: xx uninstall ${cand})`)}`
2247
- );
2248
- }
2249
- }
2250
- if (systemCands.length > 0) {
2251
- console.log(pc15.bold(pc15.blue("\n\u2699 [\u7CFB\u7EDF\u6E90\u7EA7] \u5019\u9009\uFF1A")));
2252
- for (const cand of systemCands) {
1945
+ if (candidates.length > 0) {
1946
+ console.log(pc16.yellow("\u274C \u672A\u627E\u5230\u7CBE\u786E\u5339\u914D\u7684\u5DF2\u5B89\u88C5\u5E94\u7528\u3002"));
1947
+ console.log(pc16.cyan("\u4F60\u53EF\u80FD\u60F3\u5378\u8F7D\u4EE5\u4E0B\u9879\u76EE\uFF1A"));
1948
+ for (const candidate of candidates) {
2253
1949
  console.log(
2254
- ` - ${cand} ${pc15.dim(`(\u5378\u8F7D\u547D\u4EE4: xx uninstall ${cand})`)}`
1950
+ ` - ${candidate} ${pc16.dim(`(xx uninstall ${candidate})`)}`
2255
1951
  );
2256
1952
  }
2257
- }
2258
- console.log(pc15.cyan(`
2259
- \u{1F3C1} \u641C\u5BFB\u5B8C\u6210\uFF01`));
2260
- }
2261
- }
2262
- async function parseUninstallTarget(target) {
2263
- const lower = target.toLowerCase();
2264
- const greenPath = await findGreenAppPath(target);
2265
- if (greenPath) {
2266
- return { type: "green", raw: target, greenPath };
2267
- }
2268
- const isFlatpak = !target.includes("/") && !target.includes("\\") && target.split(".").length >= 3;
2269
- if (isFlatpak) {
2270
- return { type: "flatpak", raw: target };
2271
- }
2272
- if (lower.endsWith(".deb")) {
2273
- const absPath = resolve11(process.cwd(), target);
2274
- try {
2275
- const stat = await fs12.stat(absPath);
2276
- if (stat.isFile()) {
2277
- const extractedPackageName = await extractDebPackageName(absPath);
2278
- return {
2279
- type: "deb",
2280
- raw: target,
2281
- resolvedPath: absPath,
2282
- extractedPackageName
2283
- };
2284
- }
2285
- } catch {
2286
- }
2287
- }
2288
- if (lower.endsWith(".rpm")) {
2289
- const absPath = resolve11(process.cwd(), target);
2290
- try {
2291
- const stat = await fs12.stat(absPath);
2292
- if (stat.isFile()) {
2293
- const extractedPackageName = await extractRpmPackageName(absPath);
2294
- return {
2295
- type: "rpm",
2296
- raw: target,
2297
- resolvedPath: absPath,
2298
- extractedPackageName
2299
- };
2300
- }
2301
- } catch {
2302
- }
2303
- }
2304
- if (await isSnapInstalled(target)) {
2305
- return { type: "snap", raw: target };
2306
- }
2307
- if (await isSystemPackageInstalled(target)) {
2308
- return { type: "system", raw: target };
2309
- }
2310
- return { type: "unknown", raw: target };
2311
- }
2312
- function registerUninstallCommand(program2) {
2313
- program2.command("uninstall <package>").description("\u901A\u7528\u5E94\u7528\u5378\u8F7D\u5668\uFF08\u652F\u6301\u5305\u540D\u3001Flatpak\u3001Snap\u3001\u672C\u5730\u5305\u6216\u7EFF\u8272\u8F6F\u4EF6\uFF09").action(async (pkg) => {
2314
- if (!pkg) {
2315
- console.error(
2316
- pc15.red("\u274C \u8BF7\u63D0\u4F9B\u8981\u5378\u8F7D\u7684\u8F6F\u4EF6\u5305\u540D\u79F0\u3001\u5B89\u88C5\u5305\u6216\u7EFF\u8272\u8F6F\u4EF6\u540D\u3002")
2317
- );
2318
- return;
2319
- }
2320
- try {
2321
- const parsed = await parseUninstallTarget(pkg);
2322
- switch (parsed.type) {
2323
- case "green":
2324
- await performRemoveGreenApp(parsed.greenPath, parsed.raw);
2325
- console.log(pc15.green("\u2728 \u7EFF\u8272\u5E94\u7528\u53CA\u684C\u9762\u5FEB\u6377\u65B9\u5F0F\u6E05\u7406\u5B8C\u6210\uFF01"));
2326
- break;
2327
- case "flatpak":
2328
- await uninstallFlatpak(parsed.raw);
2329
- break;
2330
- case "snap":
2331
- await removeSnap(parsed.raw);
2332
- break;
2333
- case "deb": {
2334
- const debPkgName = parsed.extractedPackageName || parsed.raw;
2335
- await removeDeb(debPkgName);
2336
- break;
2337
- }
2338
- case "rpm": {
2339
- const rpmPkgName = parsed.extractedPackageName || parsed.raw;
2340
- await removeRpm(rpmPkgName);
2341
- break;
2342
- }
2343
- case "system": {
2344
- const osRelease = await fs12.readFile("/etc/os-release", "utf-8");
2345
- if (osRelease.includes("fedora") || osRelease.includes("rhel") || osRelease.includes("centos")) {
2346
- await removeRpm(parsed.raw);
2347
- } else {
2348
- await removeDeb(parsed.raw);
2349
- }
2350
- break;
2351
- }
2352
- case "unknown":
2353
- await performFuzzySearchAndRecommendation(parsed.raw);
2354
- break;
2355
- default: {
2356
- const _exhaustiveCheck = parsed;
2357
- throw new Error(
2358
- `\u672A\u5904\u7406\u7684\u5378\u8F7D\u5206\u652F\u7C7B\u578B: ${JSON.stringify(_exhaustiveCheck)}`
2359
- );
2360
- }
2361
- }
2362
- } catch (err) {
1953
+ } else {
2363
1954
  console.error(
2364
- pc15.red("\u274C \u5378\u8F7D\u90E8\u7F72\u5931\u8D25:"),
2365
- err instanceof Error ? err.message : String(err)
1955
+ pc16.red(`\u274C \u672A\u627E\u5230\u5DF2\u5B89\u88C5\u5E94\u7528 '${pkg}'\u3002\u8BF7\u5148\u8FD0\u884C xx install \u5B89\u88C5\u3002`)
2366
1956
  );
2367
1957
  }
2368
1958
  });
@@ -2370,8 +1960,8 @@ function registerUninstallCommand(program2) {
2370
1960
 
2371
1961
  // commands/unzip.ts
2372
1962
  import fs13 from "fs/promises";
2373
- import pc16 from "picocolors";
2374
- import { join as join8, basename as basename6, extname, resolve as resolve12 } from "path";
1963
+ import pc17 from "picocolors";
1964
+ import { join as join8, basename as basename6, extname as extname2, resolve as resolve11 } from "path";
2375
1965
 
2376
1966
  // utils/archive.ts
2377
1967
  import AdmZip from "adm-zip";
@@ -2400,7 +1990,7 @@ async function uncompressTgz(src, destDir) {
2400
1990
  async function uncompressRar(src, dest) {
2401
1991
  const hasUnrar = isCommandAvailable("unrar");
2402
1992
  if (hasUnrar) {
2403
- console.log(pc16.cyan(`\u{1F4E6} \u6B63\u5728\u8C03\u7528\u7CFB\u7EDF unrar \u63D0\u53D6 RAR \u538B\u7F29\u5305...`));
1993
+ console.log(pc17.cyan(`\u{1F4E6} \u6B63\u5728\u8C03\u7528\u7CFB\u7EDF unrar \u63D0\u53D6 RAR \u538B\u7F29\u5305...`));
2404
1994
  const status = await spawnCommand("unrar", ["x", "-y", src, dest]);
2405
1995
  if (!status.success) {
2406
1996
  throw new Error(`unrar \u6267\u884C\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`);
@@ -2409,7 +1999,7 @@ async function uncompressRar(src, dest) {
2409
1999
  }
2410
2000
  const hasRar = isCommandAvailable("rar");
2411
2001
  if (hasRar) {
2412
- console.log(pc16.cyan(`\u{1F4E6} \u6B63\u5728\u8C03\u7528\u7CFB\u7EDF rar \u63D0\u53D6 RAR \u538B\u7F29\u5305...`));
2002
+ console.log(pc17.cyan(`\u{1F4E6} \u6B63\u5728\u8C03\u7528\u7CFB\u7EDF rar \u63D0\u53D6 RAR \u538B\u7F29\u5305...`));
2413
2003
  const status = await spawnCommand("rar", ["x", "-y", src, dest]);
2414
2004
  if (!status.success) {
2415
2005
  throw new Error(`rar \u6267\u884C\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`);
@@ -2430,20 +2020,20 @@ function registerUnzipCommand(program2) {
2430
2020
  "\u8BF7\u8F93\u5165\u8981\u89E3\u538B\u7684\u538B\u7F29\u5305\u6587\u4EF6\u8DEF\u5F84 (Enter compressed file path):"
2431
2021
  );
2432
2022
  if (!input) {
2433
- console.error(pc16.red("\u274C \u9519\u8BEF: \u672A\u6307\u5B9A\u6709\u6548\u7684\u538B\u7F29\u5305\u6587\u4EF6\u3002"));
2023
+ console.error(pc17.red("\u274C \u9519\u8BEF: \u672A\u6307\u5B9A\u6709\u6548\u7684\u538B\u7F29\u5305\u6587\u4EF6\u3002"));
2434
2024
  return;
2435
2025
  }
2436
2026
  srcFile = input.trim();
2437
2027
  }
2438
- const absSrcFile = resolve12(srcFile);
2028
+ const absSrcFile = resolve11(srcFile);
2439
2029
  try {
2440
2030
  const stat = await fs13.stat(absSrcFile);
2441
2031
  if (!stat.isFile()) {
2442
- console.error(pc16.red(`\u274C \u9519\u8BEF: '${srcFile}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u6587\u4EF6\u3002`));
2032
+ console.error(pc17.red(`\u274C \u9519\u8BEF: '${srcFile}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u6587\u4EF6\u3002`));
2443
2033
  return;
2444
2034
  }
2445
2035
  } catch {
2446
- console.error(pc16.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u6587\u4EF6 '${srcFile}'\u3002`));
2036
+ console.error(pc17.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u6587\u4EF6 '${srcFile}'\u3002`));
2447
2037
  return;
2448
2038
  }
2449
2039
  const lowerSrc = absSrcFile.toLowerCase();
@@ -2453,17 +2043,17 @@ function registerUnzipCommand(program2) {
2453
2043
  } else if (lowerSrc.endsWith(".tgz")) {
2454
2044
  folderName = basename6(absSrcFile, ".tgz");
2455
2045
  } else {
2456
- folderName = basename6(absSrcFile, extname(absSrcFile));
2046
+ folderName = basename6(absSrcFile, extname2(absSrcFile));
2457
2047
  }
2458
2048
  let destDir = options.dir;
2459
2049
  if (!destDir) {
2460
2050
  destDir = join8(process.cwd(), folderName);
2461
2051
  } else {
2462
- destDir = resolve12(process.cwd(), destDir);
2052
+ destDir = resolve11(process.cwd(), destDir);
2463
2053
  }
2464
2054
  try {
2465
- console.log(pc16.cyan(`\u{1F4E6} \u6B63\u5728\u51C6\u5907\u89E3\u538B: ${absSrcFile}...`));
2466
- console.log(pc16.cyan(`\u{1F4E5} \u76EE\u6807\u8F93\u51FA\u76EE\u5F55: ${destDir}`));
2055
+ console.log(pc17.cyan(`\u{1F4E6} \u6B63\u5728\u51C6\u5907\u89E3\u538B: ${absSrcFile}...`));
2056
+ console.log(pc17.cyan(`\u{1F4E5} \u76EE\u6807\u8F93\u51FA\u76EE\u5F55: ${destDir}`));
2467
2057
  await fs13.mkdir(destDir, { recursive: true });
2468
2058
  if (lowerSrc.endsWith(".tar.gz") || lowerSrc.endsWith(".tgz")) {
2469
2059
  await uncompressTgz(absSrcFile, destDir);
@@ -2475,16 +2065,16 @@ function registerUnzipCommand(program2) {
2475
2065
  await uncompressRar(absSrcFile, destDir);
2476
2066
  } else {
2477
2067
  console.log(
2478
- pc16.yellow(
2068
+ pc17.yellow(
2479
2069
  "\u26A0\uFE0F \u672A\u80FD\u8BC6\u522B\u7684\u538B\u7F29\u5305\u683C\u5F0F\u540E\u7F00\u3002\u5C06\u9ED8\u8BA4\u5C1D\u8BD5\u4F5C\u4E3A\u6807\u51C6 ZIP \u8FDB\u884C\u63D0\u53D6..."
2480
2070
  )
2481
2071
  );
2482
2072
  await uncompressZip(absSrcFile, destDir);
2483
2073
  }
2484
- console.log(pc16.green(`\u2728 \u63D0\u53D6\u6210\u529F\uFF01\u5DF2\u4FDD\u5B58\u5230: ${destDir}`));
2074
+ console.log(pc17.green(`\u2728 \u63D0\u53D6\u6210\u529F\uFF01\u5DF2\u4FDD\u5B58\u5230: ${destDir}`));
2485
2075
  } catch (error) {
2486
2076
  console.error(
2487
- pc16.red("\u274C \u63D0\u53D6\u5931\u8D25:"),
2077
+ pc17.red("\u274C \u63D0\u53D6\u5931\u8D25:"),
2488
2078
  error instanceof Error ? error.message : error
2489
2079
  );
2490
2080
  }
@@ -2492,7 +2082,7 @@ function registerUnzipCommand(program2) {
2492
2082
  }
2493
2083
 
2494
2084
  // commands/upgrade.ts
2495
- import pc17 from "picocolors";
2085
+ import pc18 from "picocolors";
2496
2086
  function registerUpgradeCommand(program2) {
2497
2087
  program2.command("upgrade").description("\u68C0\u67E5\u5E76\u81EA\u52A8\u66F4\u65B0 xx \u547D\u4EE4\u884C\u5DE5\u5177\u81F3\u6700\u65B0\u7248\u672C").option("-r, --registry", "\u5F3A\u5236\u4F7F\u7528 npm \u5B98\u65B9\u6E90 https://registry.npmjs.org/").action(async (options) => {
2498
2088
  const args = ["install", "-g"];
@@ -2500,33 +2090,33 @@ function registerUpgradeCommand(program2) {
2500
2090
  args.push("--registry=https://registry.npmjs.org/");
2501
2091
  }
2502
2092
  args.push("@xx-in/tools@latest");
2503
- console.log(pc17.cyan("\u{1F916} \u6B63\u5728\u4E3A\u60A8\u68C0\u67E5\u5E76\u66F4\u65B0 xx \u547D\u4EE4\u884C\u5DE5\u5177..."));
2504
- console.log(pc17.dim(`\u6267\u884C\u547D\u4EE4: npm ${args.join(" ")}
2093
+ console.log(pc18.cyan("\u{1F916} \u6B63\u5728\u4E3A\u60A8\u68C0\u67E5\u5E76\u66F4\u65B0 xx \u547D\u4EE4\u884C\u5DE5\u5177..."));
2094
+ console.log(pc18.dim(`\u6267\u884C\u547D\u4EE4: npm ${args.join(" ")}
2505
2095
  `));
2506
2096
  try {
2507
2097
  const status = await spawnCommand("npm", args);
2508
2098
  if (status.success) {
2509
2099
  console.log(
2510
- pc17.cyan("\n\u{1F916} \u6B63\u5728\u4E3A\u60A8\u5F3A\u5236\u8986\u76D6\u5E76\u5237\u65B0\u7EC8\u7AEF\u81EA\u52A8\u8865\u5168\u811A\u672C...")
2100
+ pc18.cyan("\n\u{1F916} \u6B63\u5728\u4E3A\u60A8\u5F3A\u5236\u8986\u76D6\u5E76\u5237\u65B0\u7EC8\u7AEF\u81EA\u52A8\u8865\u5168\u811A\u672C...")
2511
2101
  );
2512
2102
  await autoInstallCompletion();
2513
2103
  console.log(
2514
- pc17.green("\n\u2728 xx \u81EA\u52A8\u66F4\u65B0\u5E76\u91CD\u5237\u8865\u5168\u6210\u529F\uFF01\u5DF2\u6210\u529F\u52A0\u8F7D\u6700\u65B0\u7248\u672C\u3002")
2104
+ pc18.green("\n\u2728 xx \u81EA\u52A8\u66F4\u65B0\u5E76\u91CD\u5237\u8865\u5168\u6210\u529F\uFF01\u5DF2\u6210\u529F\u52A0\u8F7D\u6700\u65B0\u7248\u672C\u3002")
2515
2105
  );
2516
2106
  } else {
2517
2107
  console.error(
2518
- pc17.red(`
2108
+ pc18.red(`
2519
2109
  \u274C \u66F4\u65B0\u5931\u8D25\uFF0C\u9000\u51FA\u4EE3\u7801 (Exit Code): ${status.code}`)
2520
2110
  );
2521
2111
  }
2522
2112
  } catch (err) {
2523
2113
  console.error(
2524
- pc17.red(
2114
+ pc18.red(
2525
2115
  "\n\u274C \u65E0\u6CD5\u6267\u884C\u66F4\u65B0\u547D\u4EE4\uFF0C\u8BF7\u786E\u8BA4\u7CFB\u7EDF\u73AF\u5883\u53D8\u91CF\u4E2D\u662F\u5426\u5DF2\u6B63\u786E\u914D\u7F6E Node.js \u4E0E npm\u3002"
2526
2116
  )
2527
2117
  );
2528
2118
  if (err instanceof Error) {
2529
- console.error(pc17.red("\u9519\u8BEF\u8BE6\u60C5:"), err.message);
2119
+ console.error(pc18.red("\u9519\u8BEF\u8BE6\u60C5:"), err.message);
2530
2120
  }
2531
2121
  }
2532
2122
  });
@@ -2535,8 +2125,8 @@ function registerUpgradeCommand(program2) {
2535
2125
  // commands/zip.ts
2536
2126
  import fs14 from "fs/promises";
2537
2127
  import os2 from "os";
2538
- import pc18 from "picocolors";
2539
- import { join as join9, basename as basename7, relative as relative2, resolve as resolve13 } from "path";
2128
+ import pc19 from "picocolors";
2129
+ import { join as join9, basename as basename7, relative as relative2, resolve as resolve12 } from "path";
2540
2130
  var IGNORE_FILE_NAME = ".cpzipignore";
2541
2131
  var DEFAULT_BLACKLIST = [
2542
2132
  "# cpzip \u5FFD\u7565\u914D\u7F6E\u6587\u4EF6",
@@ -2555,20 +2145,20 @@ async function getBlacklist(absSrcDir) {
2555
2145
  const cwdIgnorePath = join9(process.cwd(), IGNORE_FILE_NAME);
2556
2146
  try {
2557
2147
  const content = await fs14.readFile(targetIgnorePath, "utf-8");
2558
- console.log(pc18.cyan(`[zip] \u627E\u5230\u76EE\u6807\u76EE\u5F55\u4E0B\u7684\u5FFD\u7565\u6587\u4EF6: ${targetIgnorePath}`));
2148
+ console.log(pc19.cyan(`[zip] \u627E\u5230\u76EE\u6807\u76EE\u5F55\u4E0B\u7684\u5FFD\u7565\u6587\u4EF6: ${targetIgnorePath}`));
2559
2149
  return parseIgnoreContent(content);
2560
2150
  } catch {
2561
2151
  }
2562
2152
  try {
2563
2153
  const content = await fs14.readFile(cwdIgnorePath, "utf-8");
2564
- console.log(pc18.cyan(`[zip] \u627E\u5230\u5F53\u524D\u76EE\u5F55\u4E0B\u7684\u5FFD\u7565\u6587\u4EF6: ${cwdIgnorePath}`));
2154
+ console.log(pc19.cyan(`[zip] \u627E\u5230\u5F53\u524D\u76EE\u5F55\u4E0B\u7684\u5FFD\u7565\u6587\u4EF6: ${cwdIgnorePath}`));
2565
2155
  return parseIgnoreContent(content);
2566
2156
  } catch (err) {
2567
2157
  if (isNotFoundError(err)) {
2568
- console.log(pc18.dim(`[zip] \u672A\u627E\u5230\u5FFD\u7565\u6587\u4EF6\uFF0C\u5C06\u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u8FC7\u6EE4\u89C4\u5219\u3002`));
2158
+ console.log(pc19.dim(`[zip] \u672A\u627E\u5230\u5FFD\u7565\u6587\u4EF6\uFF0C\u5C06\u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u8FC7\u6EE4\u89C4\u5219\u3002`));
2569
2159
  return parseIgnoreContent(DEFAULT_BLACKLIST.join("\n"));
2570
2160
  }
2571
- console.error(pc18.red(`[zip] \u8BFB\u53D6\u5FFD\u7565\u6587\u4EF6\u5931\u8D25\uFF0C\u5C06\u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u89C4\u5219\u3002`), err);
2161
+ console.error(pc19.red(`[zip] \u8BFB\u53D6\u5FFD\u7565\u6587\u4EF6\u5931\u8D25\uFF0C\u5C06\u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u89C4\u5219\u3002`), err);
2572
2162
  return parseIgnoreContent(DEFAULT_BLACKLIST.join("\n"));
2573
2163
  }
2574
2164
  }
@@ -2617,20 +2207,20 @@ function registerZipCommand(program2) {
2617
2207
  if (!srcDir) {
2618
2208
  const input = prompt("\u8BF7\u8F93\u5165\u8981\u6253\u5305\u7684\u76EE\u5F55\u8DEF\u5F84 (Enter directory path):");
2619
2209
  if (!input) {
2620
- console.error(pc18.red("\u274C \u9519\u8BEF: \u672A\u6307\u5B9A\u6709\u6548\u7684\u8F93\u5165\u76EE\u5F55\u3002"));
2210
+ console.error(pc19.red("\u274C \u9519\u8BEF: \u672A\u6307\u5B9A\u6709\u6548\u7684\u8F93\u5165\u76EE\u5F55\u3002"));
2621
2211
  return;
2622
2212
  }
2623
2213
  srcDir = input.trim();
2624
2214
  }
2625
- const absSrcDir = resolve13(srcDir);
2215
+ const absSrcDir = resolve12(srcDir);
2626
2216
  try {
2627
2217
  const stat = await fs14.stat(absSrcDir);
2628
2218
  if (!stat.isDirectory()) {
2629
- console.error(pc18.red(`\u274C \u9519\u8BEF: '${srcDir}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
2219
+ console.error(pc19.red(`\u274C \u9519\u8BEF: '${srcDir}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
2630
2220
  return;
2631
2221
  }
2632
2222
  } catch {
2633
- console.error(pc18.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u76EE\u5F55 '${srcDir}'\u3002`));
2223
+ console.error(pc19.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u76EE\u5F55 '${srcDir}'\u3002`));
2634
2224
  return;
2635
2225
  }
2636
2226
  const dirName = basename7(absSrcDir);
@@ -2639,13 +2229,13 @@ function registerZipCommand(program2) {
2639
2229
  const tempDir = await fs14.mkdtemp(join9(os2.tmpdir(), "cpzip_temp_"));
2640
2230
  const tempCopyTarget = join9(tempDir, dirName);
2641
2231
  try {
2642
- console.log(pc18.cyan(`\u{1F4E6} \u6B63\u5728\u590D\u5236\u76EE\u5F55\u5E76\u8FC7\u6EE4\u5FFD\u7565\u9879...`));
2232
+ console.log(pc19.cyan(`\u{1F4E6} \u6B63\u5728\u590D\u5236\u76EE\u5F55\u5E76\u8FC7\u6EE4\u5FFD\u7565\u9879...`));
2643
2233
  await copyRecursive3(absSrcDir, tempCopyTarget, absSrcDir, blacklist);
2644
- console.log(pc18.cyan(`\u26A1 \u6B63\u5728\u6253\u5305\u4E3A ZIP \u538B\u7F29\u5305...`));
2234
+ console.log(pc19.cyan(`\u26A1 \u6B63\u5728\u6253\u5305\u4E3A ZIP \u538B\u7F29\u5305...`));
2645
2235
  await compressZip(tempCopyTarget, outputZip);
2646
- console.log(pc18.green(`\u2728 \u6253\u5305\u6210\u529F\uFF01\u538B\u7F29\u5305\u4FDD\u5B58\u4E3A: ${outputZip}`));
2236
+ console.log(pc19.green(`\u2728 \u6253\u5305\u6210\u529F\uFF01\u538B\u7F29\u5305\u4FDD\u5B58\u4E3A: ${outputZip}`));
2647
2237
  } catch (error) {
2648
- console.error(pc18.red("\u274C \u6253\u5305\u5931\u8D25:"), error);
2238
+ console.error(pc19.red("\u274C \u6253\u5305\u5931\u8D25:"), error);
2649
2239
  } finally {
2650
2240
  try {
2651
2241
  await fs14.rm(tempDir, { recursive: true });