@simon_he/pi 0.1.18 → 0.1.20

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/dist/index.cjs +209 -15
  2. package/dist/index.js +212 -18
  3. package/package.json +9 -9
package/dist/index.cjs CHANGED
@@ -46,7 +46,7 @@ var import_node_process = __toESM(require("process"), 1);
46
46
  var import_node = require("lazy-js-utils/node");
47
47
 
48
48
  // package.json
49
- var version = "0.1.18";
49
+ var version = "0.1.20";
50
50
 
51
51
  // src/help.ts
52
52
  var isZh = import_node_process.default.env.PI_Lang === "zh";
@@ -165,6 +165,8 @@ no" | gum filter --placeholder=" \u5F53\u524Dnode\u7248\u672C\u4E0D\u6EE1\u8DB3
165
165
  }
166
166
 
167
167
  // src/utils.ts
168
+ var import_node_fs = __toESM(require("fs"), 1);
169
+ var import_node_os = __toESM(require("os"), 1);
168
170
  var import_node_path = __toESM(require("path"), 1);
169
171
  var import_node_process4 = __toESM(require("process"), 1);
170
172
  var import_lazy_js_utils = require("lazy-js-utils");
@@ -177,6 +179,7 @@ var w = /\s-w/g;
177
179
  var D = /\s-D(?!w)/g;
178
180
  var d = /\s-d(?!w)/g;
179
181
  var isZh2 = import_node_process4.default.env.PI_Lang === "zh";
182
+ var log = console.log;
180
183
  async function getParams(params) {
181
184
  const root = import_node_process4.default.cwd();
182
185
  try {
@@ -218,6 +221,8 @@ async function getParams(params) {
218
221
  return params.replace(W, "");
219
222
  if (w.test(params))
220
223
  return params.replace(w, "");
224
+ if (d.test(params))
225
+ return params.replace(d, " -D");
221
226
  }
222
227
  if ((await (0, import_node5.getPkg)())?.workspaces) {
223
228
  if (D.test(params))
@@ -231,10 +236,10 @@ async function getParams(params) {
231
236
  if (Dw.test(params))
232
237
  return params.replace(Dw, " -DW");
233
238
  if (W.test(params))
234
- return params.replace(w, " -W");
239
+ return params.replace(W, " -W");
235
240
  return params;
236
241
  default:
237
- return params;
242
+ return d.test(params) ? params.replace(d, " -D") : params;
238
243
  }
239
244
  } catch {
240
245
  console.log(
@@ -283,6 +288,165 @@ async function getLatestVersion(pkg, isZh6 = true) {
283
288
  }
284
289
  return `${data.join(" ")}${isZh6 ? " \u5B89\u88C5\u6210\u529F! \u{1F60A}" : " successfully! \u{1F60A}"}`;
285
290
  }
291
+ async function pushHistory(command) {
292
+ log(
293
+ import_picocolors3.default.bold(
294
+ import_picocolors3.default.blue(`${isZh2 ? "\u5FEB\u6377\u6307\u4EE4" : "shortcut command"}: ${command}`)
295
+ )
296
+ );
297
+ const currentShell = import_node_process4.default.env.SHELL || "/bin/bash";
298
+ const shellName = currentShell.split("/").pop() || "bash";
299
+ let historyFile = "";
300
+ let historyFormat = "bash";
301
+ const home = import_node_process4.default.env.HOME || import_node_os.default.homedir();
302
+ switch (shellName) {
303
+ case "zsh":
304
+ historyFile = import_node_path.default.join(home, ".zsh_history");
305
+ historyFormat = "zsh";
306
+ break;
307
+ case "bash":
308
+ historyFile = import_node_process4.default.env.HISTFILE || import_node_path.default.join(home, ".bash_history");
309
+ historyFormat = "bash";
310
+ break;
311
+ case "fish":
312
+ historyFile = import_node_path.default.join(home, ".local", "share", "fish", "fish_history");
313
+ historyFormat = "fish";
314
+ break;
315
+ default:
316
+ historyFile = import_node_process4.default.env.HISTFILE || import_node_path.default.join(home, ".bash_history");
317
+ historyFormat = "bash";
318
+ }
319
+ try {
320
+ let parseEntries2 = function(content) {
321
+ if (historyFormat === "fish") {
322
+ const lines = content.split(/\r?\n/);
323
+ const blocks = [];
324
+ let buffer = [];
325
+ for (const line of lines) {
326
+ if (line.startsWith("- cmd: ")) {
327
+ if (buffer.length) {
328
+ blocks.push(buffer.join("\n"));
329
+ buffer = [];
330
+ }
331
+ buffer.push(line);
332
+ } else if (buffer.length) {
333
+ buffer.push(line);
334
+ } else if (line.trim() !== "") {
335
+ blocks.push(line);
336
+ }
337
+ }
338
+ if (buffer.length)
339
+ blocks.push(buffer.join("\n"));
340
+ return blocks.filter(Boolean);
341
+ } else if (historyFormat === "zsh") {
342
+ return content.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
343
+ } else {
344
+ const lines = content.split(/\r?\n/);
345
+ const entries2 = [];
346
+ for (let i = 0; i < lines.length; i++) {
347
+ const line = lines[i];
348
+ if (line.startsWith("#")) {
349
+ const next = lines[i + 1] ?? "";
350
+ entries2.push(`${line}
351
+ ${next}`);
352
+ i++;
353
+ } else if (line.trim() !== "") {
354
+ entries2.push(line);
355
+ }
356
+ }
357
+ return entries2;
358
+ }
359
+ }, extractCommand2 = function(entry) {
360
+ if (historyFormat === "fish") {
361
+ const m = entry.split("\n")[0].match(/^- cmd: (.*)$/);
362
+ return m ? m[1] : entry;
363
+ } else if (historyFormat === "zsh") {
364
+ const m = entry.match(/^[^;]*;(.+)$/);
365
+ return m ? m[1] : entry;
366
+ } else {
367
+ if (entry.startsWith("#")) {
368
+ const parts = entry.split(/\r?\n/);
369
+ return parts[1] ?? parts[0];
370
+ }
371
+ return entry;
372
+ }
373
+ };
374
+ var parseEntries = parseEntries2, extractCommand = extractCommand2;
375
+ if (!import_node_fs.default.existsSync(historyFile)) {
376
+ log(
377
+ import_picocolors3.default.yellow(
378
+ `${isZh2 ? `\u672A\u627E\u5230 ${shellName} \u5386\u53F2\u6587\u4EF6` : `${shellName} history file not found`}`
379
+ )
380
+ );
381
+ return;
382
+ }
383
+ const raw = import_node_fs.default.readFileSync(historyFile, "utf8");
384
+ const timestamp = Math.floor(Date.now() / 1e3);
385
+ let newEntry = "";
386
+ if (historyFormat === "zsh") {
387
+ newEntry = `: ${timestamp}:0;${command}`;
388
+ } else if (historyFormat === "fish") {
389
+ newEntry = `- cmd: ${command}
390
+ when: ${timestamp}`;
391
+ } else {
392
+ if (import_node_process4.default.env.HISTTIMEFORMAT) {
393
+ newEntry = `#${timestamp}
394
+ ${command}`;
395
+ } else {
396
+ newEntry = command;
397
+ }
398
+ }
399
+ const entries = parseEntries2(raw);
400
+ const newEntries = [];
401
+ const newCmd = extractCommand2(newEntry);
402
+ let existingFishBlock = null;
403
+ for (const e of entries) {
404
+ const cmd = extractCommand2(e);
405
+ if (cmd === newCmd) {
406
+ if (historyFormat === "fish") {
407
+ existingFishBlock = e;
408
+ continue;
409
+ }
410
+ continue;
411
+ }
412
+ newEntries.push(e);
413
+ }
414
+ if (historyFormat === "fish" && existingFishBlock) {
415
+ const lines = existingFishBlock.split("\n");
416
+ let hasWhen = false;
417
+ const updated = lines.map((line) => {
418
+ if (line.trim().startsWith("when:") || line.startsWith(" when:")) {
419
+ hasWhen = true;
420
+ return ` when: ${timestamp}`;
421
+ }
422
+ return line;
423
+ });
424
+ if (!hasWhen) {
425
+ updated.splice(1, 0, ` when: ${timestamp}`);
426
+ }
427
+ newEntries.push(updated.join("\n"));
428
+ } else {
429
+ newEntries.push(newEntry);
430
+ }
431
+ let finalContent = "";
432
+ if (historyFormat === "fish") {
433
+ finalContent = `${newEntries.map((e) => e.trimEnd()).join("\n")}
434
+ `;
435
+ } else {
436
+ finalContent = `${newEntries.join("\n")}
437
+ `;
438
+ }
439
+ const tmpPath = `${historyFile}.ccommand.tmp`;
440
+ import_node_fs.default.writeFileSync(tmpPath, finalContent, "utf8");
441
+ import_node_fs.default.renameSync(tmpPath, historyFile);
442
+ } catch (err) {
443
+ log(
444
+ import_picocolors3.default.red(
445
+ `${isZh2 ? `\u274C \u6DFB\u52A0\u5230 ${shellName} \u5386\u53F2\u8BB0\u5F55\u5931\u8D25` : `\u274C Failed to add to ${shellName} history`}${err ? `: ${String(err)}` : ""}`
446
+ )
447
+ );
448
+ }
449
+ }
286
450
 
287
451
  // src/pi.ts
288
452
  var isZh3 = import_node_process5.default.env.PI_Lang === "zh";
@@ -319,11 +483,7 @@ async function pi(params, pkg, executor = "ni") {
319
483
  }
320
484
  const newParams = isLatest ? "" : await getParams(params);
321
485
  const runSockets = executor.split(" ")[0] === "npm" ? ` --max-sockets=${maxSockets}` : "";
322
- console.log(
323
- import_picocolors4.default.green(
324
- isLatest ? params.map((p) => `${executor} ${p}`).join(" & ") : `${executor}${newParams ? ` ${newParams}` : runSockets}`
325
- )
326
- );
486
+ const runCmd = isLatest ? params.map((p) => `${executor} ${p}`).join(" & ") : `${executor}${newParams ? ` ${newParams}` : runSockets}`;
327
487
  let { status, result } = await (0, import_node6.useNodeWorker)({
328
488
  params: isLatest ? params.map((p) => `${executor} ${p}`).join(" & ") : `${executor}${newParams ? ` ${newParams}` : runSockets}`,
329
489
  stdio,
@@ -352,6 +512,7 @@ async function pi(params, pkg, executor = "ni") {
352
512
  successMsg += import_picocolors4.default.blue(` ---- \u23F0\uFF1A${costTime}s`);
353
513
  if (status === 0) {
354
514
  loading_status.succeed(import_picocolors4.default.green(successMsg));
515
+ pushHistory(runCmd);
355
516
  } else if (result && result.includes("Not Found - 404")) {
356
517
  const _pkg = result.match(/\/[^/:]+:/)?.[0].slice(1, -1);
357
518
  const _result = isZh3 ? `${_pkg} \u5305\u540D\u53EF\u80FD\u6709\u8BEF\u6216\u8005\u7248\u672C\u53F7\u4E0D\u5B58\u5728\uFF0C\u5E76\u4E0D\u80FD\u5728npm\u4E2D\u641C\u7D22\u5230\uFF0C\u8BF7\u68C0\u67E5` : `${_pkg} the package name may be wrong, and cannot be found in npm, please check`;
@@ -434,15 +595,48 @@ async function pil(params) {
434
595
  const v = dependencies[i] || devDependencies[i];
435
596
  return `${i}$${v}`;
436
597
  }).join(" ");
437
- const group = {};
438
- const items = command.replace(/\s+/, " ").trim().split(" ").map((i, idx) => [i, suffix[idx] || "-s"]);
439
- for (const [pkg, flag] of items) {
440
- if (!group[flag])
441
- group[flag] = [];
442
- group[flag].push(pkg);
598
+ const tokens = command.replace(/\s+/, " ").trim().split(" ").filter(Boolean);
599
+ const pkgs = tokens.filter((t) => !t.startsWith("-"));
600
+ let globalWorkspaceFlag = null;
601
+ const perFlags = [];
602
+ let assignIdx = 0;
603
+ for (const f of suffix) {
604
+ if (/^-(?:w|W)$/.test(f)) {
605
+ globalWorkspaceFlag = f;
606
+ continue;
607
+ }
608
+ perFlags[assignIdx++] = f;
443
609
  }
610
+ const normalizeFlag = (f) => {
611
+ if (!f)
612
+ return "";
613
+ if (/^-s$/i.test(f) || /^-S$/.test(f))
614
+ return "";
615
+ return f;
616
+ };
617
+ const combineWorkspace = (f, w2) => {
618
+ if (!w2)
619
+ return f;
620
+ if (/w/i.test(f))
621
+ return f;
622
+ if (!f)
623
+ return w2;
624
+ if (/d/i.test(f))
625
+ return `-D${w2.slice(1)}`;
626
+ return w2;
627
+ };
628
+ const finalFlags = pkgs.map(
629
+ (_, i) => combineWorkspace(normalizeFlag(perFlags[i]), globalWorkspaceFlag)
630
+ );
631
+ const group = {};
632
+ pkgs.forEach((p, i) => {
633
+ const key = finalFlags[i] || "";
634
+ if (!group[key])
635
+ group[key] = [];
636
+ group[key].push(p);
637
+ });
444
638
  const cmds = Object.entries(group).map(
445
- ([flag, pkgs]) => `${pkgs.join(" ")} ${flag}`
639
+ ([flag, list]) => `${list.join(" ")}${flag ? ` ${flag}` : ""}`
446
640
  );
447
641
  return await pi(cmds, latestPkgname.replace(/@latest/g, ""), "pil");
448
642
  }
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ import process from "process";
25
25
  import { jsShell } from "lazy-js-utils/node";
26
26
 
27
27
  // package.json
28
- var version = "0.1.18";
28
+ var version = "0.1.20";
29
29
 
30
30
  // src/help.ts
31
31
  var isZh = process.env.PI_Lang === "zh";
@@ -97,7 +97,7 @@ function pa() {
97
97
  }
98
98
 
99
99
  // src/pi.ts
100
- import { log } from "console";
100
+ import { log as log2 } from "console";
101
101
  import process5 from "process";
102
102
  import { getPkgTool as getPkgTool2, jsShell as jsShell6, useNodeWorker } from "lazy-js-utils/node";
103
103
  import colors3 from "picocolors";
@@ -144,6 +144,8 @@ no" | gum filter --placeholder=" \u5F53\u524Dnode\u7248\u672C\u4E0D\u6EE1\u8DB3
144
144
  }
145
145
 
146
146
  // src/utils.ts
147
+ import fs from "fs";
148
+ import os from "os";
147
149
  import path from "path";
148
150
  import process4 from "process";
149
151
  import { isFile } from "lazy-js-utils";
@@ -156,6 +158,7 @@ var w = /\s-w/g;
156
158
  var D = /\s-D(?!w)/g;
157
159
  var d = /\s-d(?!w)/g;
158
160
  var isZh2 = process4.env.PI_Lang === "zh";
161
+ var log = console.log;
159
162
  async function getParams(params) {
160
163
  const root = process4.cwd();
161
164
  try {
@@ -197,6 +200,8 @@ async function getParams(params) {
197
200
  return params.replace(W, "");
198
201
  if (w.test(params))
199
202
  return params.replace(w, "");
203
+ if (d.test(params))
204
+ return params.replace(d, " -D");
200
205
  }
201
206
  if ((await getPkg2())?.workspaces) {
202
207
  if (D.test(params))
@@ -210,10 +215,10 @@ async function getParams(params) {
210
215
  if (Dw.test(params))
211
216
  return params.replace(Dw, " -DW");
212
217
  if (W.test(params))
213
- return params.replace(w, " -W");
218
+ return params.replace(W, " -W");
214
219
  return params;
215
220
  default:
216
- return params;
221
+ return d.test(params) ? params.replace(d, " -D") : params;
217
222
  }
218
223
  } catch {
219
224
  console.log(
@@ -262,6 +267,165 @@ async function getLatestVersion(pkg, isZh6 = true) {
262
267
  }
263
268
  return `${data.join(" ")}${isZh6 ? " \u5B89\u88C5\u6210\u529F! \u{1F60A}" : " successfully! \u{1F60A}"}`;
264
269
  }
270
+ async function pushHistory(command) {
271
+ log(
272
+ colors2.bold(
273
+ colors2.blue(`${isZh2 ? "\u5FEB\u6377\u6307\u4EE4" : "shortcut command"}: ${command}`)
274
+ )
275
+ );
276
+ const currentShell = process4.env.SHELL || "/bin/bash";
277
+ const shellName = currentShell.split("/").pop() || "bash";
278
+ let historyFile = "";
279
+ let historyFormat = "bash";
280
+ const home = process4.env.HOME || os.homedir();
281
+ switch (shellName) {
282
+ case "zsh":
283
+ historyFile = path.join(home, ".zsh_history");
284
+ historyFormat = "zsh";
285
+ break;
286
+ case "bash":
287
+ historyFile = process4.env.HISTFILE || path.join(home, ".bash_history");
288
+ historyFormat = "bash";
289
+ break;
290
+ case "fish":
291
+ historyFile = path.join(home, ".local", "share", "fish", "fish_history");
292
+ historyFormat = "fish";
293
+ break;
294
+ default:
295
+ historyFile = process4.env.HISTFILE || path.join(home, ".bash_history");
296
+ historyFormat = "bash";
297
+ }
298
+ try {
299
+ let parseEntries2 = function(content) {
300
+ if (historyFormat === "fish") {
301
+ const lines = content.split(/\r?\n/);
302
+ const blocks = [];
303
+ let buffer = [];
304
+ for (const line of lines) {
305
+ if (line.startsWith("- cmd: ")) {
306
+ if (buffer.length) {
307
+ blocks.push(buffer.join("\n"));
308
+ buffer = [];
309
+ }
310
+ buffer.push(line);
311
+ } else if (buffer.length) {
312
+ buffer.push(line);
313
+ } else if (line.trim() !== "") {
314
+ blocks.push(line);
315
+ }
316
+ }
317
+ if (buffer.length)
318
+ blocks.push(buffer.join("\n"));
319
+ return blocks.filter(Boolean);
320
+ } else if (historyFormat === "zsh") {
321
+ return content.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
322
+ } else {
323
+ const lines = content.split(/\r?\n/);
324
+ const entries2 = [];
325
+ for (let i = 0; i < lines.length; i++) {
326
+ const line = lines[i];
327
+ if (line.startsWith("#")) {
328
+ const next = lines[i + 1] ?? "";
329
+ entries2.push(`${line}
330
+ ${next}`);
331
+ i++;
332
+ } else if (line.trim() !== "") {
333
+ entries2.push(line);
334
+ }
335
+ }
336
+ return entries2;
337
+ }
338
+ }, extractCommand2 = function(entry) {
339
+ if (historyFormat === "fish") {
340
+ const m = entry.split("\n")[0].match(/^- cmd: (.*)$/);
341
+ return m ? m[1] : entry;
342
+ } else if (historyFormat === "zsh") {
343
+ const m = entry.match(/^[^;]*;(.+)$/);
344
+ return m ? m[1] : entry;
345
+ } else {
346
+ if (entry.startsWith("#")) {
347
+ const parts = entry.split(/\r?\n/);
348
+ return parts[1] ?? parts[0];
349
+ }
350
+ return entry;
351
+ }
352
+ };
353
+ var parseEntries = parseEntries2, extractCommand = extractCommand2;
354
+ if (!fs.existsSync(historyFile)) {
355
+ log(
356
+ colors2.yellow(
357
+ `${isZh2 ? `\u672A\u627E\u5230 ${shellName} \u5386\u53F2\u6587\u4EF6` : `${shellName} history file not found`}`
358
+ )
359
+ );
360
+ return;
361
+ }
362
+ const raw = fs.readFileSync(historyFile, "utf8");
363
+ const timestamp = Math.floor(Date.now() / 1e3);
364
+ let newEntry = "";
365
+ if (historyFormat === "zsh") {
366
+ newEntry = `: ${timestamp}:0;${command}`;
367
+ } else if (historyFormat === "fish") {
368
+ newEntry = `- cmd: ${command}
369
+ when: ${timestamp}`;
370
+ } else {
371
+ if (process4.env.HISTTIMEFORMAT) {
372
+ newEntry = `#${timestamp}
373
+ ${command}`;
374
+ } else {
375
+ newEntry = command;
376
+ }
377
+ }
378
+ const entries = parseEntries2(raw);
379
+ const newEntries = [];
380
+ const newCmd = extractCommand2(newEntry);
381
+ let existingFishBlock = null;
382
+ for (const e of entries) {
383
+ const cmd = extractCommand2(e);
384
+ if (cmd === newCmd) {
385
+ if (historyFormat === "fish") {
386
+ existingFishBlock = e;
387
+ continue;
388
+ }
389
+ continue;
390
+ }
391
+ newEntries.push(e);
392
+ }
393
+ if (historyFormat === "fish" && existingFishBlock) {
394
+ const lines = existingFishBlock.split("\n");
395
+ let hasWhen = false;
396
+ const updated = lines.map((line) => {
397
+ if (line.trim().startsWith("when:") || line.startsWith(" when:")) {
398
+ hasWhen = true;
399
+ return ` when: ${timestamp}`;
400
+ }
401
+ return line;
402
+ });
403
+ if (!hasWhen) {
404
+ updated.splice(1, 0, ` when: ${timestamp}`);
405
+ }
406
+ newEntries.push(updated.join("\n"));
407
+ } else {
408
+ newEntries.push(newEntry);
409
+ }
410
+ let finalContent = "";
411
+ if (historyFormat === "fish") {
412
+ finalContent = `${newEntries.map((e) => e.trimEnd()).join("\n")}
413
+ `;
414
+ } else {
415
+ finalContent = `${newEntries.join("\n")}
416
+ `;
417
+ }
418
+ const tmpPath = `${historyFile}.ccommand.tmp`;
419
+ fs.writeFileSync(tmpPath, finalContent, "utf8");
420
+ fs.renameSync(tmpPath, historyFile);
421
+ } catch (err) {
422
+ log(
423
+ colors2.red(
424
+ `${isZh2 ? `\u274C \u6DFB\u52A0\u5230 ${shellName} \u5386\u53F2\u8BB0\u5F55\u5931\u8D25` : `\u274C Failed to add to ${shellName} history`}${err ? `: ${String(err)}` : ""}`
425
+ )
426
+ );
427
+ }
428
+ }
265
429
 
266
430
  // src/pi.ts
267
431
  var isZh3 = process5.env.PI_Lang === "zh";
@@ -298,19 +462,15 @@ async function pi(params, pkg, executor = "ni") {
298
462
  }
299
463
  const newParams = isLatest ? "" : await getParams(params);
300
464
  const runSockets = executor.split(" ")[0] === "npm" ? ` --max-sockets=${maxSockets}` : "";
301
- console.log(
302
- colors3.green(
303
- isLatest ? params.map((p) => `${executor} ${p}`).join(" & ") : `${executor}${newParams ? ` ${newParams}` : runSockets}`
304
- )
305
- );
465
+ const runCmd = isLatest ? params.map((p) => `${executor} ${p}`).join(" & ") : `${executor}${newParams ? ` ${newParams}` : runSockets}`;
306
466
  let { status, result } = await useNodeWorker({
307
467
  params: isLatest ? params.map((p) => `${executor} ${p}`).join(" & ") : `${executor}${newParams ? ` ${newParams}` : runSockets}`,
308
468
  stdio,
309
469
  errorExit: false
310
470
  });
311
471
  if (result && result.includes("pnpm versions with respective Node.js version support")) {
312
- log(result);
313
- log(
472
+ log2(result);
473
+ log2(
314
474
  colors3.yellow(
315
475
  isZh3 ? "\u6B63\u5728\u5C1D\u8BD5\u4F7F\u7528 npm \u518D\u6B21\u6267\u884C..." : "Trying to use npm to run again..."
316
476
  )
@@ -331,6 +491,7 @@ async function pi(params, pkg, executor = "ni") {
331
491
  successMsg += colors3.blue(` ---- \u23F0\uFF1A${costTime}s`);
332
492
  if (status === 0) {
333
493
  loading_status.succeed(colors3.green(successMsg));
494
+ pushHistory(runCmd);
334
495
  } else if (result && result.includes("Not Found - 404")) {
335
496
  const _pkg = result.match(/\/[^/:]+:/)?.[0].slice(1, -1);
336
497
  const _result = isZh3 ? `${_pkg} \u5305\u540D\u53EF\u80FD\u6709\u8BEF\u6216\u8005\u7248\u672C\u53F7\u4E0D\u5B58\u5728\uFF0C\u5E76\u4E0D\u80FD\u5728npm\u4E2D\u641C\u7D22\u5230\uFF0C\u8BF7\u68C0\u67E5` : `${_pkg} the package name may be wrong, and cannot be found in npm, please check`;
@@ -413,15 +574,48 @@ async function pil(params) {
413
574
  const v = dependencies[i] || devDependencies[i];
414
575
  return `${i}$${v}`;
415
576
  }).join(" ");
416
- const group = {};
417
- const items = command.replace(/\s+/, " ").trim().split(" ").map((i, idx) => [i, suffix[idx] || "-s"]);
418
- for (const [pkg, flag] of items) {
419
- if (!group[flag])
420
- group[flag] = [];
421
- group[flag].push(pkg);
577
+ const tokens = command.replace(/\s+/, " ").trim().split(" ").filter(Boolean);
578
+ const pkgs = tokens.filter((t) => !t.startsWith("-"));
579
+ let globalWorkspaceFlag = null;
580
+ const perFlags = [];
581
+ let assignIdx = 0;
582
+ for (const f of suffix) {
583
+ if (/^-(?:w|W)$/.test(f)) {
584
+ globalWorkspaceFlag = f;
585
+ continue;
586
+ }
587
+ perFlags[assignIdx++] = f;
422
588
  }
589
+ const normalizeFlag = (f) => {
590
+ if (!f)
591
+ return "";
592
+ if (/^-s$/i.test(f) || /^-S$/.test(f))
593
+ return "";
594
+ return f;
595
+ };
596
+ const combineWorkspace = (f, w2) => {
597
+ if (!w2)
598
+ return f;
599
+ if (/w/i.test(f))
600
+ return f;
601
+ if (!f)
602
+ return w2;
603
+ if (/d/i.test(f))
604
+ return `-D${w2.slice(1)}`;
605
+ return w2;
606
+ };
607
+ const finalFlags = pkgs.map(
608
+ (_, i) => combineWorkspace(normalizeFlag(perFlags[i]), globalWorkspaceFlag)
609
+ );
610
+ const group = {};
611
+ pkgs.forEach((p, i) => {
612
+ const key = finalFlags[i] || "";
613
+ if (!group[key])
614
+ group[key] = [];
615
+ group[key].push(p);
616
+ });
423
617
  const cmds = Object.entries(group).map(
424
- ([flag, pkgs]) => `${pkgs.join(" ")} ${flag}`
618
+ ([flag, list]) => `${list.join(" ")}${flag ? ` ${flag}` : ""}`
425
619
  );
426
620
  return await pi(cmds, latestPkgname.replace(/@latest/g, ""), "pil");
427
621
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@simon_he/pi",
3
3
  "type": "module",
4
- "version": "0.1.18",
5
- "packageManager": "pnpm@10.15.1",
4
+ "version": "0.1.20",
5
+ "packageManager": "pnpm@10.20.0",
6
6
  "description": "An intelligent cross-platform package manager and CLI tool that autodetects project environments (Node.mjs, Go, Rust, Python) with beautiful loading animations and smart command execution.",
7
7
  "author": {
8
8
  "name": "Simon He",
@@ -92,21 +92,21 @@
92
92
  "dependencies": {
93
93
  "ccommand": "^1.0.87",
94
94
  "fast-glob": "^3.3.3",
95
- "lazy-js-utils": "^0.1.47",
95
+ "lazy-js-utils": "^0.1.49",
96
96
  "ora": "^8.2.0",
97
97
  "picocolors": "^1.1.1",
98
- "semver": "^7.7.2"
98
+ "semver": "^7.7.3"
99
99
  },
100
100
  "devDependencies": {
101
101
  "@antfu/eslint-config": "^4.19.0",
102
- "@types/node": "^22.18.1",
103
- "bumpp": "^10.2.3",
104
- "eslint": "^9.35.0",
102
+ "@types/node": "^22.19.0",
103
+ "bumpp": "^10.3.1",
104
+ "eslint": "^9.39.0",
105
105
  "lint-staged": "^13.3.0",
106
106
  "prettier": "^2.8.8",
107
107
  "tsup": "^8.5.0",
108
- "tsx": "^4.20.5",
109
- "typescript": "^5.9.2",
108
+ "tsx": "^4.20.6",
109
+ "typescript": "^5.9.3",
110
110
  "vitest": "^3.2.4"
111
111
  },
112
112
  "lint-staged": {