@lark-people/cli 0.0.0-beta.1 → 0.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/people-cli_darwin_amd64 +0 -0
- package/bin/people-cli_darwin_arm64 +0 -0
- package/bin/people-cli_linux_amd64 +0 -0
- package/bin/people-cli_linux_arm64 +0 -0
- package/bin/people-cli_windows_amd64.exe +0 -0
- package/bin/people-cli_windows_arm64.exe +0 -0
- package/package.json +1 -1
- package/scripts/install-wizard.js +131 -6
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -10,7 +10,16 @@ const CURRENT_PACKAGE_DIR = path.resolve(__dirname, "..");
|
|
|
10
10
|
const DEFAULT_PKG = "@lark-people/cli";
|
|
11
11
|
const DEFAULT_SKILLS_DIR = path.join(__dirname, "..", "skills");
|
|
12
12
|
const isWindows = process.platform === "win32";
|
|
13
|
-
|
|
13
|
+
// Skills excluded from installation. `people-skill-maker` is an authoring-only
|
|
14
|
+
// skill; the people-attendance/people-overtime/people-hire skills are gated
|
|
15
|
+
// until their capabilities are ready for release (keep in sync with
|
|
16
|
+
// internal/features/features.go).
|
|
17
|
+
const EXCLUDED_BUNDLED_SKILLS = new Set([
|
|
18
|
+
"people-skill-maker",
|
|
19
|
+
"people-attendance",
|
|
20
|
+
"people-overtime",
|
|
21
|
+
"people-hire",
|
|
22
|
+
]);
|
|
14
23
|
|
|
15
24
|
function readPackageMeta(packageDir = CURRENT_PACKAGE_DIR) {
|
|
16
25
|
try {
|
|
@@ -32,6 +41,9 @@ const messages = {
|
|
|
32
41
|
step1Done: "已全局安装",
|
|
33
42
|
step1Upgraded: "已升级到 v%s",
|
|
34
43
|
step1Fail: "全局安装失败。运行以下命令重试: npm install -g %s",
|
|
44
|
+
step1MigrateSpinner: "检测到旧版包 %s 占用 people-cli 命令,正在迁移...",
|
|
45
|
+
step1MigrateDone: "已卸载旧版包 %s",
|
|
46
|
+
step1MigrateFail: "卸载旧版包 %s 失败,请手动运行: npm uninstall -g %s",
|
|
35
47
|
step2Spinner: "正在安装 Skills...",
|
|
36
48
|
step2Skip: "官方 Skills 已齐全,跳过",
|
|
37
49
|
step2Done: "Skills 已安装",
|
|
@@ -62,6 +74,9 @@ const messages = {
|
|
|
62
74
|
step1Done: "Installed globally",
|
|
63
75
|
step1Upgraded: "Upgraded to v%s",
|
|
64
76
|
step1Fail: "Failed to install globally. Run manually: npm install -g %s",
|
|
77
|
+
step1MigrateSpinner: "Legacy package %s owns the people-cli command. Migrating...",
|
|
78
|
+
step1MigrateDone: "Removed legacy package %s",
|
|
79
|
+
step1MigrateFail: "Failed to remove legacy package %s. Run manually: npm uninstall -g %s",
|
|
65
80
|
step2Spinner: "Installing skills...",
|
|
66
81
|
step2Skip: "Official skills already present. Skipped",
|
|
67
82
|
step2Done: "Skills installed",
|
|
@@ -212,6 +227,76 @@ function resolveGlobalPackageDir(packageName = PKG) {
|
|
|
212
227
|
}
|
|
213
228
|
}
|
|
214
229
|
|
|
230
|
+
// Extract the owning npm package name from a resolved path that points inside a
|
|
231
|
+
// node_modules tree, e.g. ".../node_modules/@people/people-cli/scripts/run.js"
|
|
232
|
+
// -> "@people/people-cli". Returns null when the path is not inside a package.
|
|
233
|
+
function packageNameFromModulePath(resolvedPath) {
|
|
234
|
+
if (!resolvedPath) {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
const normalized = String(resolvedPath).replace(/\\/g, "/");
|
|
238
|
+
const marker = "/node_modules/";
|
|
239
|
+
const idx = normalized.lastIndexOf(marker);
|
|
240
|
+
if (idx === -1) {
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
const segments = normalized.slice(idx + marker.length).split("/").filter(Boolean);
|
|
244
|
+
if (segments.length === 0) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
if (segments[0].startsWith("@")) {
|
|
248
|
+
return segments.length >= 2 ? `${segments[0]}/${segments[1]}` : null;
|
|
249
|
+
}
|
|
250
|
+
return segments[0];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Resolve which npm package currently owns the global `people-cli` bin. On
|
|
254
|
+
// POSIX the bin is a symlink into the owning package; on Windows the .cmd shim
|
|
255
|
+
// is not a symlink, so ownership cannot be resolved and we return null.
|
|
256
|
+
function resolveGlobalBinOwner(binName = BIN_NAME, deps = {}) {
|
|
257
|
+
const runSilentFn = deps.runSilent || runSilent;
|
|
258
|
+
const realpathSync = deps.realpathSync || fs.realpathSync;
|
|
259
|
+
try {
|
|
260
|
+
const prefix = runSilentFn("npm", ["prefix", "-g"], { timeout: 15000 }).toString().trim();
|
|
261
|
+
const binPath = isWindows
|
|
262
|
+
? path.join(prefix, `${binName}.cmd`)
|
|
263
|
+
: path.join(prefix, "bin", binName);
|
|
264
|
+
const resolved = realpathSync(binPath);
|
|
265
|
+
return packageNameFromModulePath(resolved);
|
|
266
|
+
} catch (_) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Decide whether a globally installed package owns the `people-cli` bin under a
|
|
272
|
+
// DIFFERENT package name than the one we are about to install. This is the root
|
|
273
|
+
// cause of `npm EEXIST` after a package rename: npm refuses to overwrite a bin
|
|
274
|
+
// owned by another package. Returns the conflicting owner name, or null.
|
|
275
|
+
function findConflictingBinOwner(targetPackageName = PKG, deps = {}) {
|
|
276
|
+
const owner = deps.resolveGlobalBinOwner
|
|
277
|
+
? deps.resolveGlobalBinOwner(BIN_NAME)
|
|
278
|
+
: resolveGlobalBinOwner();
|
|
279
|
+
if (!owner || owner === targetPackageName) {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
return owner;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Uninstall a conflicting legacy package that owns the `people-cli` bin so the
|
|
286
|
+
// renamed package can claim the bin without `npm EEXIST`.
|
|
287
|
+
function removeConflictingLegacyPackage(owner, deps = {}) {
|
|
288
|
+
if (!owner) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
const runSilentFn = deps.runSilent || runSilent;
|
|
292
|
+
try {
|
|
293
|
+
runSilentFn("npm", ["uninstall", "-g", owner], { timeout: 120000 });
|
|
294
|
+
return true;
|
|
295
|
+
} catch (_) {
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
215
300
|
function sameResolvedPath(a, b) {
|
|
216
301
|
if (!a || !b) {
|
|
217
302
|
return false;
|
|
@@ -503,6 +588,32 @@ async function stepInstallGlobally(msg) {
|
|
|
503
588
|
return false;
|
|
504
589
|
}
|
|
505
590
|
|
|
591
|
+
// Detect a legacy package that owns the `people-cli` bin under a different
|
|
592
|
+
// name (e.g. after renaming @people/people-cli -> @lark-people/cli). Left in
|
|
593
|
+
// place, npm aborts the install with EEXIST. Remove it first so the renamed
|
|
594
|
+
// package (always installed under currentPkg's name) can claim the bin.
|
|
595
|
+
const conflictingOwner = findConflictingBinOwner(currentPkg);
|
|
596
|
+
if (conflictingOwner) {
|
|
597
|
+
const migrateSpinner = p ? p.spinner() : null;
|
|
598
|
+
if (migrateSpinner) {
|
|
599
|
+
migrateSpinner.start(fmt(msg.step1MigrateSpinner, conflictingOwner));
|
|
600
|
+
} else {
|
|
601
|
+
console.log(fmt(msg.step1MigrateSpinner, conflictingOwner));
|
|
602
|
+
}
|
|
603
|
+
const removed = removeConflictingLegacyPackage(conflictingOwner);
|
|
604
|
+
if (removed) {
|
|
605
|
+
if (migrateSpinner) {
|
|
606
|
+
migrateSpinner.stop(fmt(msg.step1MigrateDone, conflictingOwner));
|
|
607
|
+
} else {
|
|
608
|
+
console.log(fmt(msg.step1MigrateDone, conflictingOwner));
|
|
609
|
+
}
|
|
610
|
+
} else if (migrateSpinner) {
|
|
611
|
+
migrateSpinner.stop(fmt(msg.step1MigrateFail, conflictingOwner, conflictingOwner));
|
|
612
|
+
} else {
|
|
613
|
+
console.error(fmt(msg.step1MigrateFail, conflictingOwner, conflictingOwner));
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
506
617
|
const spinner = p ? p.spinner() : null;
|
|
507
618
|
if (spinner) {
|
|
508
619
|
spinner.start(
|
|
@@ -518,12 +629,22 @@ async function stepInstallGlobally(msg) {
|
|
|
518
629
|
}
|
|
519
630
|
return true;
|
|
520
631
|
} catch (_) {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
632
|
+
// Last-resort retry: force npm to overwrite any bin left behind by a legacy
|
|
633
|
+
// package that could not be cleanly removed above.
|
|
634
|
+
try {
|
|
635
|
+
await runSilentAsync("npm", ["install", "-g", "--force", plan.installTarget], { timeout: 120000 });
|
|
636
|
+
if (spinner) {
|
|
637
|
+
spinner.stop(plan.needsUpgrade ? fmt(msg.step1Upgraded, plan.installVersion) : msg.step1Done);
|
|
638
|
+
}
|
|
639
|
+
return true;
|
|
640
|
+
} catch (_) {
|
|
641
|
+
if (spinner) {
|
|
642
|
+
spinner.stop(fmt(msg.step1Fail, PKG));
|
|
643
|
+
} else {
|
|
644
|
+
console.error(fmt(msg.step1Fail, PKG));
|
|
645
|
+
}
|
|
646
|
+
process.exit(1);
|
|
525
647
|
}
|
|
526
|
-
process.exit(1);
|
|
527
648
|
}
|
|
528
649
|
}
|
|
529
650
|
|
|
@@ -672,15 +793,19 @@ module.exports = {
|
|
|
672
793
|
buildInstallAuthLoginArgs,
|
|
673
794
|
DEFAULT_SKILLS_DIR,
|
|
674
795
|
diffMissingSkills,
|
|
796
|
+
findConflictingBinOwner,
|
|
675
797
|
formatCommandFailure,
|
|
676
798
|
buildSkillsCommandArgs,
|
|
677
799
|
inspectExistingAppConfig,
|
|
678
800
|
listBundledSkills,
|
|
679
801
|
listInstalledGlobalSkills,
|
|
802
|
+
packageNameFromModulePath,
|
|
680
803
|
parseGlobalSkillsJSON,
|
|
681
804
|
parseGlobalSkillsText,
|
|
682
805
|
parseLangArg,
|
|
683
806
|
planGlobalInstall,
|
|
807
|
+
removeConflictingLegacyPackage,
|
|
808
|
+
resolveGlobalBinOwner,
|
|
684
809
|
resolveSkillsLauncher,
|
|
685
810
|
stepInstallSkills,
|
|
686
811
|
main,
|