@zjex/git-workflow 0.2.21 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -145,6 +145,14 @@ function backgroundCheck(currentVersion, packageName) {
145
145
  }
146
146
  });
147
147
  }
148
+ function isUsingVolta() {
149
+ try {
150
+ const whichGw = execSync6("which gw", { encoding: "utf-8" }).trim();
151
+ return whichGw.includes(".volta");
152
+ } catch {
153
+ return false;
154
+ }
155
+ }
148
156
  async function getLatestVersion(packageName) {
149
157
  try {
150
158
  const result = execSync6(`npm view ${packageName} version`, {
@@ -192,6 +200,8 @@ async function showUpdateMessage(current, latest, packageName) {
192
200
  width: 40
193
201
  })
194
202
  );
203
+ const usingVolta = isUsingVolta();
204
+ const updateCommand = usingVolta ? `volta install ${packageName}@latest` : `npm install -g ${packageName}@latest`;
195
205
  try {
196
206
  const action = await select7({
197
207
  message: "\u4F60\u60F3\u505A\u4EC0\u4E48\uFF1F",
@@ -199,7 +209,7 @@ async function showUpdateMessage(current, latest, packageName) {
199
209
  {
200
210
  name: "\u{1F680} \u7ACB\u5373\u66F4\u65B0",
201
211
  value: "update",
202
- description: `\u8FD0\u884C npm install -g ${packageName}`
212
+ description: `\u8FD0\u884C ${updateCommand}`
203
213
  },
204
214
  {
205
215
  name: "\u23ED\uFE0F \u7A0D\u540E\u66F4\u65B0\uFF0C\u7EE7\u7EED\u4F7F\u7528",
@@ -221,12 +231,14 @@ async function showUpdateMessage(current, latest, packageName) {
221
231
  }
222
232
  async function performUpdate(packageName) {
223
233
  console.log("");
234
+ const usingVolta = isUsingVolta();
235
+ const updateCommand = usingVolta ? `volta install ${packageName}@latest` : `npm install -g ${packageName}@latest`;
224
236
  const spinner = ora5({
225
237
  text: "\u6B63\u5728\u66F4\u65B0...",
226
238
  spinner: "dots"
227
239
  }).start();
228
240
  try {
229
- execSync6(`npm install -g ${packageName}@latest`, {
241
+ execSync6(updateCommand, {
230
242
  encoding: "utf-8",
231
243
  stdio: ["pipe", "pipe", "pipe"]
232
244
  });
@@ -238,15 +250,18 @@ async function performUpdate(packageName) {
238
250
  [
239
251
  colors.green(colors.bold("\u2728 \u66F4\u65B0\u5B8C\u6210\uFF01")),
240
252
  "",
241
- colors.dim("\u8BF7\u91CD\u65B0\u6253\u5F00\u7EC8\u7AEF\u4F7F\u7528\u65B0\u7248\u672C")
253
+ colors.dim("\u8BF7\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u9A8C\u8BC1:"),
254
+ colors.cyan(" hash -r && gw --version"),
255
+ "",
256
+ colors.dim("\u6216\u91CD\u65B0\u6253\u5F00\u7EC8\u7AEF")
242
257
  ].join("\n"),
243
258
  {
244
- padding: { top: 1, bottom: 1, left: 3, right: 3 },
259
+ padding: { top: 1, bottom: 1, left: 2, right: 2 },
245
260
  margin: { top: 0, bottom: 1, left: 2, right: 2 },
246
261
  borderStyle: "round",
247
262
  borderColor: "green",
248
- align: "center",
249
- width: 40
263
+ align: "left",
264
+ width: 50
250
265
  }
251
266
  )
252
267
  );
@@ -255,7 +270,7 @@ async function performUpdate(packageName) {
255
270
  spinner.fail(colors.red("\u66F4\u65B0\u5931\u8D25"));
256
271
  console.log("");
257
272
  console.log(colors.dim(" \u4F60\u53EF\u4EE5\u624B\u52A8\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u66F4\u65B0:"));
258
- console.log(colors.cyan(` npm install -g ${packageName}@latest`));
273
+ console.log(colors.cyan(` ${updateCommand}`));
259
274
  console.log("");
260
275
  }
261
276
  }
@@ -640,20 +655,78 @@ async function listTags(prefix) {
640
655
  exec("git fetch --tags", true);
641
656
  spinner.stop();
642
657
  const pattern = prefix ? `${prefix}*` : "";
643
- const tags = execOutput(`git tag -l ${pattern} --sort=-v:refname`).split("\n").filter(Boolean);
658
+ const tags = execOutput(`git tag -l ${pattern} --sort=v:refname`).split("\n").filter(Boolean);
644
659
  if (tags.length === 0) {
645
660
  console.log(
646
661
  colors.yellow(prefix ? `\u6CA1\u6709 '${prefix}' \u5F00\u5934\u7684 tag` : "\u6CA1\u6709 tag")
647
662
  );
648
663
  return;
649
664
  }
665
+ if (prefix) {
666
+ console.log(colors.green(`\u4EE5 '${prefix}' \u5F00\u5934\u7684 tags:`));
667
+ const displayTags = tags.length > 20 ? tags.slice(-20) : tags;
668
+ displayTags.forEach((tag) => console.log(` ${tag}`));
669
+ if (tags.length > 20) {
670
+ console.log(colors.yellow(`
671
+ \u5171 ${tags.length} \u4E2A\uFF0C\u4EC5\u663E\u793A\u6700\u65B0 20 \u4E2A`));
672
+ }
673
+ return;
674
+ }
675
+ const grouped = /* @__PURE__ */ new Map();
676
+ tags.forEach((tag) => {
677
+ const prefix2 = tag.replace(/[0-9].*/, "") || "\u65E0\u524D\u7F00";
678
+ if (!grouped.has(prefix2)) {
679
+ grouped.set(prefix2, []);
680
+ }
681
+ grouped.get(prefix2).push(tag);
682
+ });
683
+ if (grouped.size === 1) {
684
+ console.log(colors.green("\u6240\u6709 tags:"));
685
+ const displayTags = tags.length > 20 ? tags.slice(-20) : tags;
686
+ displayTags.forEach((tag) => console.log(` ${tag}`));
687
+ if (tags.length > 20) {
688
+ console.log(colors.yellow(`
689
+ \u5171 ${tags.length} \u4E2A\uFF0C\u4EC5\u663E\u793A\u6700\u65B0 20 \u4E2A`));
690
+ }
691
+ return;
692
+ }
693
+ console.log(colors.green("\u6240\u6709 tags (\u6309\u524D\u7F00\u5206\u7EC4):"));
694
+ console.log("");
695
+ const columns = [];
696
+ grouped.forEach((tagList, prefix2) => {
697
+ const hasMore = tagList.length > 5;
698
+ const displayTags = hasMore ? tagList.slice(-5) : tagList;
699
+ columns.push({ prefix: prefix2, tags: displayTags, hasMore });
700
+ });
701
+ const maxTagLength = Math.max(
702
+ ...columns.flatMap((col) => col.tags.map((t) => t.length))
703
+ );
704
+ const columnWidth = Math.max(maxTagLength + 4, 20);
705
+ const headers = columns.map((col) => {
706
+ const total = grouped.get(col.prefix).length;
707
+ const header = `${col.prefix} (${total})`;
708
+ return header.padEnd(columnWidth);
709
+ });
710
+ console.log(colors.cyan(" " + headers.join(" ")));
650
711
  console.log(
651
- colors.green(prefix ? `\u4EE5 '${prefix}' \u5F00\u5934\u7684 tags:` : "\u6240\u6709 tags:")
712
+ colors.dim(
713
+ " " + "\u2500".repeat(columnWidth * columns.length + (columns.length - 1) * 2)
714
+ )
652
715
  );
653
- tags.slice(0, 20).forEach((tag) => console.log(` ${tag}`));
654
- if (tags.length > 20) {
655
- console.log(colors.yellow(`
656
- \u5171 ${tags.length} \u4E2A\uFF0C\u4EC5\u663E\u793A\u524D 20 \u4E2A`));
716
+ const ellipsisRow = columns.map((col) => {
717
+ const text = col.hasMore ? "..." : "";
718
+ return text.padEnd(columnWidth);
719
+ }).join(" ");
720
+ if (columns.some((col) => col.hasMore)) {
721
+ console.log(colors.dim(" " + ellipsisRow));
722
+ }
723
+ const maxRows = Math.max(...columns.map((col) => col.tags.length));
724
+ for (let i = 0; i < maxRows; i++) {
725
+ const row = columns.map((col) => {
726
+ const tag = col.tags[i] || "";
727
+ return tag.padEnd(columnWidth);
728
+ }).join(" ");
729
+ console.log(" " + row);
657
730
  }
658
731
  }
659
732
  function getLatestTag(prefix) {
@@ -2293,8 +2366,17 @@ async function getLatestVersion2(packageName) {
2293
2366
  return null;
2294
2367
  }
2295
2368
  }
2369
+ function isUsingVolta2() {
2370
+ try {
2371
+ const whichGw = execSync7("which gw", { encoding: "utf-8" }).trim();
2372
+ return whichGw.includes(".volta");
2373
+ } catch {
2374
+ return false;
2375
+ }
2376
+ }
2296
2377
  async function update(currentVersion) {
2297
2378
  const packageName = "@zjex/git-workflow";
2379
+ const usingVolta = isUsingVolta2();
2298
2380
  console.log("");
2299
2381
  console.log(colors.bold("\u{1F50D} \u68C0\u67E5\u66F4\u65B0..."));
2300
2382
  console.log("");
@@ -2327,12 +2409,6 @@ async function update(currentVersion) {
2327
2409
  return;
2328
2410
  }
2329
2411
  const versionText = `${currentVersion} \u2192 ${latestVersion}`;
2330
- const maxWidth = Math.max(
2331
- "\u{1F389} \u53D1\u73B0\u65B0\u7248\u672C\uFF01".length,
2332
- versionText.length,
2333
- "\u2728 \u66F4\u65B0\u5B8C\u6210\uFF01".length,
2334
- "\u8BF7\u91CD\u65B0\u6253\u5F00\u7EC8\u7AEF\u4F7F\u7528\u65B0\u7248\u672C".length
2335
- );
2336
2412
  console.log(
2337
2413
  boxen2(
2338
2414
  [
@@ -2353,7 +2429,8 @@ async function update(currentVersion) {
2353
2429
  )
2354
2430
  );
2355
2431
  const updateSpinner = ora6("\u6B63\u5728\u66F4\u65B0...").start();
2356
- execSync7(`npm install -g ${packageName}@latest`, {
2432
+ const updateCommand = usingVolta ? `volta install ${packageName}@latest` : `npm install -g ${packageName}@latest`;
2433
+ execSync7(updateCommand, {
2357
2434
  encoding: "utf-8",
2358
2435
  stdio: ["pipe", "pipe", "pipe"]
2359
2436
  });
@@ -2365,15 +2442,20 @@ async function update(currentVersion) {
2365
2442
  [
2366
2443
  colors.green(colors.bold("\u2728 \u66F4\u65B0\u5B8C\u6210\uFF01")),
2367
2444
  "",
2368
- colors.dim("\u8BF7\u91CD\u65B0\u6253\u5F00\u7EC8\u7AEF\u4F7F\u7528\u65B0\u7248\u672C")
2445
+ `\u65B0\u7248\u672C: ${colors.green(colors.bold(latestVersion))}`,
2446
+ "",
2447
+ colors.dim("\u8BF7\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u9A8C\u8BC1:"),
2448
+ colors.cyan(" hash -r && gw --version"),
2449
+ "",
2450
+ colors.dim("\u6216\u91CD\u65B0\u6253\u5F00\u7EC8\u7AEF")
2369
2451
  ].join("\n"),
2370
2452
  {
2371
- padding: { top: 1, bottom: 1, left: 3, right: 3 },
2453
+ padding: { top: 1, bottom: 1, left: 2, right: 2 },
2372
2454
  margin: { top: 0, bottom: 1, left: 2, right: 2 },
2373
2455
  borderStyle: "round",
2374
2456
  borderColor: "green",
2375
- align: "center",
2376
- width: 40
2457
+ align: "left",
2458
+ width: 50
2377
2459
  }
2378
2460
  )
2379
2461
  );
@@ -2382,7 +2464,8 @@ async function update(currentVersion) {
2382
2464
  spinner.fail(colors.red("\u66F4\u65B0\u5931\u8D25"));
2383
2465
  console.log("");
2384
2466
  console.log(colors.dim(" \u4F60\u53EF\u4EE5\u624B\u52A8\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u66F4\u65B0:"));
2385
- console.log(colors.cyan(` npm install -g ${packageName}@latest`));
2467
+ const updateCommand = usingVolta ? `volta install ${packageName}@latest` : `npm install -g ${packageName}@latest`;
2468
+ console.log(colors.cyan(` ${updateCommand}`));
2386
2469
  console.log("");
2387
2470
  process.exit(1);
2388
2471
  }
@@ -2413,7 +2496,7 @@ process.on("SIGTERM", () => {
2413
2496
  console.log("");
2414
2497
  process.exit(0);
2415
2498
  });
2416
- var version = true ? "0.2.21" : "0.0.0-dev";
2499
+ var version = true ? "0.2.23" : "0.0.0-dev";
2417
2500
  async function mainMenu() {
2418
2501
  console.log(
2419
2502
  colors.green(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zjex/git-workflow",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "description": "🚀 极简的 Git 工作流 CLI 工具,让分支管理和版本发布变得轻松愉快",
5
5
  "type": "module",
6
6
  "bin": {
@@ -4,16 +4,23 @@ import ora from "ora";
4
4
  import { colors, theme, exec, execOutput, divider } from "../utils.js";
5
5
  import { getConfig } from "../config.js";
6
6
 
7
+ /**
8
+ * 列出 tags(最新的显示在最下面,多个前缀分列展示)
9
+ * @param prefix 可选的 tag 前缀过滤
10
+ */
7
11
  export async function listTags(prefix?: string): Promise<void> {
12
+ // 1. 获取远程 tags
8
13
  const spinner = ora("正在获取 tags...").start();
9
14
  exec("git fetch --tags", true);
10
15
  spinner.stop();
11
16
 
17
+ // 2. 获取 tags 列表(按版本号升序排序,最新的在最后)
12
18
  const pattern = prefix ? `${prefix}*` : "";
13
- const tags = execOutput(`git tag -l ${pattern} --sort=-v:refname`)
19
+ const tags = execOutput(`git tag -l ${pattern} --sort=v:refname`)
14
20
  .split("\n")
15
21
  .filter(Boolean);
16
22
 
23
+ // 3. 如果没有 tags,提示并返回
17
24
  if (tags.length === 0) {
18
25
  console.log(
19
26
  colors.yellow(prefix ? `没有 '${prefix}' 开头的 tag` : "没有 tag")
@@ -21,13 +28,95 @@ export async function listTags(prefix?: string): Promise<void> {
21
28
  return;
22
29
  }
23
30
 
31
+ // 4. 如果指定了前缀,直接显示单列(最多 20 个)
32
+ if (prefix) {
33
+ console.log(colors.green(`以 '${prefix}' 开头的 tags:`));
34
+ const displayTags = tags.length > 20 ? tags.slice(-20) : tags;
35
+ displayTags.forEach((tag) => console.log(` ${tag}`));
36
+ if (tags.length > 20) {
37
+ console.log(colors.yellow(`\n共 ${tags.length} 个,仅显示最新 20 个`));
38
+ }
39
+ return;
40
+ }
41
+
42
+ // 5. 按前缀分组(提取 tag 名称中数字前的部分作为前缀)
43
+ const grouped = new Map<string, string[]>();
44
+ tags.forEach((tag) => {
45
+ // 提取前缀:去掉数字及之后的部分,如 "v0.1.0" -> "v"
46
+ const prefix = tag.replace(/[0-9].*/, "") || "无前缀";
47
+ if (!grouped.has(prefix)) {
48
+ grouped.set(prefix, []);
49
+ }
50
+ grouped.get(prefix)!.push(tag);
51
+ });
52
+
53
+ // 6. 如果只有一个前缀,使用单列显示(最多 20 个)
54
+ if (grouped.size === 1) {
55
+ console.log(colors.green("所有 tags:"));
56
+ const displayTags = tags.length > 20 ? tags.slice(-20) : tags;
57
+ displayTags.forEach((tag) => console.log(` ${tag}`));
58
+ if (tags.length > 20) {
59
+ console.log(colors.yellow(`\n共 ${tags.length} 个,仅显示最新 20 个`));
60
+ }
61
+ return;
62
+ }
63
+
64
+ // 7. 多个前缀,分列显示
65
+ console.log(colors.green("所有 tags (按前缀分组):"));
66
+ console.log("");
67
+
68
+ // 8. 准备每列的数据(每列最多显示 5 个最新的 tag)
69
+ const columns: Array<{ prefix: string; tags: string[]; hasMore: boolean }> =
70
+ [];
71
+ grouped.forEach((tagList, prefix) => {
72
+ const hasMore = tagList.length > 5;
73
+ // 取最后 5 个(最新的)
74
+ const displayTags = hasMore ? tagList.slice(-5) : tagList;
75
+ columns.push({ prefix, tags: displayTags, hasMore });
76
+ });
77
+
78
+ // 9. 计算每列的宽度(取所有 tag 中最长的,至少 20 字符)
79
+ const maxTagLength = Math.max(
80
+ ...columns.flatMap((col) => col.tags.map((t) => t.length))
81
+ );
82
+ const columnWidth = Math.max(maxTagLength + 4, 20);
83
+
84
+ // 10. 打印表头(显示前缀和总数)
85
+ const headers = columns.map((col) => {
86
+ const total = grouped.get(col.prefix)!.length;
87
+ const header = `${col.prefix} (${total})`;
88
+ return header.padEnd(columnWidth);
89
+ });
90
+ console.log(colors.cyan(" " + headers.join(" ")));
91
+
92
+ // 11. 打印分隔线
24
93
  console.log(
25
- colors.green(prefix ? `以 '${prefix}' 开头的 tags:` : "所有 tags:")
94
+ colors.dim(
95
+ " " + "─".repeat(columnWidth * columns.length + (columns.length - 1) * 2)
96
+ )
26
97
  );
27
- tags.slice(0, 20).forEach((tag) => console.log(` ${tag}`));
28
98
 
29
- if (tags.length > 20) {
30
- console.log(colors.yellow(`\n共 ${tags.length} 个,仅显示前 20 个`));
99
+ // 12. 打印省略号(如果某列有超过 5 个 tag)
100
+ const ellipsisRow = columns
101
+ .map((col) => {
102
+ const text = col.hasMore ? "..." : "";
103
+ return text.padEnd(columnWidth);
104
+ })
105
+ .join(" ");
106
+ if (columns.some((col) => col.hasMore)) {
107
+ console.log(colors.dim(" " + ellipsisRow));
108
+ }
109
+
110
+ // 13. 打印 tags 内容(按行打印,每行包含所有列的对应 tag)
111
+ const maxRows = Math.max(...columns.map((col) => col.tags.length));
112
+ for (let i = 0; i < maxRows; i++) {
113
+ const row = columns
114
+ .map((col) => {
115
+ const tag = col.tags[i] || ""; // 如果该列没有这一行,填充空字符串
116
+ return tag.padEnd(columnWidth);
117
+ })
118
+ .join(" ");
119
+ console.log(" " + row);
31
120
  }
32
121
  }
33
122
 
@@ -39,11 +39,24 @@ async function getLatestVersion(packageName: string): Promise<string | null> {
39
39
  }
40
40
  }
41
41
 
42
+ /**
43
+ * 检测是否使用 Volta
44
+ */
45
+ function isUsingVolta(): boolean {
46
+ try {
47
+ const whichGw = execSync("which gw", { encoding: "utf-8" }).trim();
48
+ return whichGw.includes(".volta");
49
+ } catch {
50
+ return false;
51
+ }
52
+ }
53
+
42
54
  /**
43
55
  * 手动更新命令
44
56
  */
45
57
  export async function update(currentVersion: string): Promise<void> {
46
58
  const packageName = "@zjex/git-workflow";
59
+ const usingVolta = isUsingVolta();
47
60
 
48
61
  console.log("");
49
62
  console.log(colors.bold("🔍 检查更新..."));
@@ -85,12 +98,6 @@ export async function update(currentVersion: string): Promise<void> {
85
98
 
86
99
  // 有新版本
87
100
  const versionText = `${currentVersion} → ${latestVersion}`;
88
- const maxWidth = Math.max(
89
- "🎉 发现新版本!".length,
90
- versionText.length,
91
- "✨ 更新完成!".length,
92
- "请重新打开终端使用新版本".length
93
- );
94
101
 
95
102
  console.log(
96
103
  boxen(
@@ -115,7 +122,12 @@ export async function update(currentVersion: string): Promise<void> {
115
122
  // 开始更新
116
123
  const updateSpinner = ora("正在更新...").start();
117
124
 
118
- execSync(`npm install -g ${packageName}@latest`, {
125
+ // 根据包管理器选择更新命令
126
+ const updateCommand = usingVolta
127
+ ? `volta install ${packageName}@latest`
128
+ : `npm install -g ${packageName}@latest`;
129
+
130
+ execSync(updateCommand, {
119
131
  encoding: "utf-8",
120
132
  stdio: ["pipe", "pipe", "pipe"],
121
133
  });
@@ -131,15 +143,20 @@ export async function update(currentVersion: string): Promise<void> {
131
143
  [
132
144
  colors.green(colors.bold("✨ 更新完成!")),
133
145
  "",
134
- colors.dim("请重新打开终端使用新版本"),
146
+ `新版本: ${colors.green(colors.bold(latestVersion))}`,
147
+ "",
148
+ colors.dim("请执行以下命令验证:"),
149
+ colors.cyan(" hash -r && gw --version"),
150
+ "",
151
+ colors.dim("或重新打开终端"),
135
152
  ].join("\n"),
136
153
  {
137
- padding: { top: 1, bottom: 1, left: 3, right: 3 },
154
+ padding: { top: 1, bottom: 1, left: 2, right: 2 },
138
155
  margin: { top: 0, bottom: 1, left: 2, right: 2 },
139
156
  borderStyle: "round",
140
157
  borderColor: "green",
141
- align: "center",
142
- width: 40,
158
+ align: "left",
159
+ width: 50,
143
160
  }
144
161
  )
145
162
  );
@@ -150,7 +167,10 @@ export async function update(currentVersion: string): Promise<void> {
150
167
  spinner.fail(colors.red("更新失败"));
151
168
  console.log("");
152
169
  console.log(colors.dim(" 你可以手动运行以下命令更新:"));
153
- console.log(colors.cyan(` npm install -g ${packageName}@latest`));
170
+ const updateCommand = usingVolta
171
+ ? `volta install ${packageName}@latest`
172
+ : `npm install -g ${packageName}@latest`;
173
+ console.log(colors.cyan(` ${updateCommand}`));
154
174
  console.log("");
155
175
  process.exit(1);
156
176
  }
@@ -107,6 +107,18 @@ function backgroundCheck(currentVersion: string, packageName: string): void {
107
107
  });
108
108
  }
109
109
 
110
+ /**
111
+ * 检测是否使用 Volta
112
+ */
113
+ function isUsingVolta(): boolean {
114
+ try {
115
+ const whichGw = execSync("which gw", { encoding: "utf-8" }).trim();
116
+ return whichGw.includes(".volta");
117
+ } catch {
118
+ return false;
119
+ }
120
+ }
121
+
110
122
  /**
111
123
  * 获取 npm 上的最新版本
112
124
  */
@@ -172,6 +184,11 @@ async function showUpdateMessage(
172
184
  })
173
185
  );
174
186
 
187
+ const usingVolta = isUsingVolta();
188
+ const updateCommand = usingVolta
189
+ ? `volta install ${packageName}@latest`
190
+ : `npm install -g ${packageName}@latest`;
191
+
175
192
  try {
176
193
  const action = await select({
177
194
  message: "你想做什么?",
@@ -179,7 +196,7 @@ async function showUpdateMessage(
179
196
  {
180
197
  name: "🚀 立即更新",
181
198
  value: "update",
182
- description: `运行 npm install -g ${packageName}`,
199
+ description: `运行 ${updateCommand}`,
183
200
  },
184
201
  {
185
202
  name: "⏭️ 稍后更新,继续使用",
@@ -208,14 +225,19 @@ async function showUpdateMessage(
208
225
  async function performUpdate(packageName: string): Promise<void> {
209
226
  console.log("");
210
227
 
228
+ const usingVolta = isUsingVolta();
229
+ const updateCommand = usingVolta
230
+ ? `volta install ${packageName}@latest`
231
+ : `npm install -g ${packageName}@latest`;
232
+
211
233
  const spinner = ora({
212
234
  text: "正在更新...",
213
235
  spinner: "dots",
214
236
  }).start();
215
237
 
216
238
  try {
217
- // 直接安装最新版本(npm 会自动覆盖旧版本)
218
- execSync(`npm install -g ${packageName}@latest`, {
239
+ // 根据包管理器选择更新命令
240
+ execSync(updateCommand, {
219
241
  encoding: "utf-8",
220
242
  stdio: ["pipe", "pipe", "pipe"],
221
243
  });
@@ -231,15 +253,18 @@ async function performUpdate(packageName: string): Promise<void> {
231
253
  [
232
254
  colors.green(colors.bold("✨ 更新完成!")),
233
255
  "",
234
- colors.dim("请重新打开终端使用新版本"),
256
+ colors.dim("请执行以下命令验证:"),
257
+ colors.cyan(" hash -r && gw --version"),
258
+ "",
259
+ colors.dim("或重新打开终端"),
235
260
  ].join("\n"),
236
261
  {
237
- padding: { top: 1, bottom: 1, left: 3, right: 3 },
262
+ padding: { top: 1, bottom: 1, left: 2, right: 2 },
238
263
  margin: { top: 0, bottom: 1, left: 2, right: 2 },
239
264
  borderStyle: "round",
240
265
  borderColor: "green",
241
- align: "center",
242
- width: 40,
266
+ align: "left",
267
+ width: 50,
243
268
  }
244
269
  )
245
270
  );
@@ -250,7 +275,7 @@ async function performUpdate(packageName: string): Promise<void> {
250
275
  spinner.fail(colors.red("更新失败"));
251
276
  console.log("");
252
277
  console.log(colors.dim(" 你可以手动运行以下命令更新:"));
253
- console.log(colors.cyan(` npm install -g ${packageName}@latest`));
278
+ console.log(colors.cyan(` ${updateCommand}`));
254
279
  console.log("");
255
280
  }
256
281
  }