claudekit-cli 3.22.0 → 3.23.0
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 +511 -241
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12606,7 +12606,7 @@ var require_get_stream = __commonJS((exports, module) => {
|
|
|
12606
12606
|
};
|
|
12607
12607
|
const { maxBuffer } = options;
|
|
12608
12608
|
let stream;
|
|
12609
|
-
await new Promise((
|
|
12609
|
+
await new Promise((resolve5, reject) => {
|
|
12610
12610
|
const rejectPromise = (error) => {
|
|
12611
12611
|
if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
|
|
12612
12612
|
error.bufferedData = stream.getBufferedValue();
|
|
@@ -12618,7 +12618,7 @@ var require_get_stream = __commonJS((exports, module) => {
|
|
|
12618
12618
|
rejectPromise(error);
|
|
12619
12619
|
return;
|
|
12620
12620
|
}
|
|
12621
|
-
|
|
12621
|
+
resolve5();
|
|
12622
12622
|
});
|
|
12623
12623
|
stream.on("data", () => {
|
|
12624
12624
|
if (stream.getBufferedLength() > maxBuffer) {
|
|
@@ -13979,7 +13979,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
13979
13979
|
debug("opening", this.zipPath, "with opts", this.opts);
|
|
13980
13980
|
this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
|
|
13981
13981
|
this.canceled = false;
|
|
13982
|
-
return new Promise((
|
|
13982
|
+
return new Promise((resolve5, reject) => {
|
|
13983
13983
|
this.zipfile.on("error", (err) => {
|
|
13984
13984
|
this.canceled = true;
|
|
13985
13985
|
reject(err);
|
|
@@ -13988,7 +13988,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
13988
13988
|
this.zipfile.on("close", () => {
|
|
13989
13989
|
if (!this.canceled) {
|
|
13990
13990
|
debug("zip extraction complete");
|
|
13991
|
-
|
|
13991
|
+
resolve5();
|
|
13992
13992
|
}
|
|
13993
13993
|
});
|
|
13994
13994
|
this.zipfile.on("entry", async (entry) => {
|
|
@@ -16592,7 +16592,7 @@ function getPagerArgs(pagerCmd) {
|
|
|
16592
16592
|
return [];
|
|
16593
16593
|
}
|
|
16594
16594
|
async function trySystemPager(content) {
|
|
16595
|
-
return new Promise((
|
|
16595
|
+
return new Promise((resolve10) => {
|
|
16596
16596
|
const pagerCmd = process.env.PAGER || "less";
|
|
16597
16597
|
const pagerArgs = getPagerArgs(pagerCmd);
|
|
16598
16598
|
try {
|
|
@@ -16602,20 +16602,20 @@ async function trySystemPager(content) {
|
|
|
16602
16602
|
});
|
|
16603
16603
|
const timeout = setTimeout(() => {
|
|
16604
16604
|
pager.kill();
|
|
16605
|
-
|
|
16605
|
+
resolve10(false);
|
|
16606
16606
|
}, 30000);
|
|
16607
16607
|
pager.stdin.write(content);
|
|
16608
16608
|
pager.stdin.end();
|
|
16609
16609
|
pager.on("close", (code2) => {
|
|
16610
16610
|
clearTimeout(timeout);
|
|
16611
|
-
|
|
16611
|
+
resolve10(code2 === 0);
|
|
16612
16612
|
});
|
|
16613
16613
|
pager.on("error", () => {
|
|
16614
16614
|
clearTimeout(timeout);
|
|
16615
|
-
|
|
16615
|
+
resolve10(false);
|
|
16616
16616
|
});
|
|
16617
16617
|
} catch {
|
|
16618
|
-
|
|
16618
|
+
resolve10(false);
|
|
16619
16619
|
}
|
|
16620
16620
|
});
|
|
16621
16621
|
}
|
|
@@ -16642,16 +16642,16 @@ async function basicPager(content) {
|
|
|
16642
16642
|
break;
|
|
16643
16643
|
}
|
|
16644
16644
|
const remaining = lines.length - currentLine;
|
|
16645
|
-
await new Promise((
|
|
16645
|
+
await new Promise((resolve10) => {
|
|
16646
16646
|
rl.question(`-- More (${remaining} lines) [Enter/q] --`, (answer) => {
|
|
16647
16647
|
if (answer.toLowerCase() === "q") {
|
|
16648
16648
|
rl.close();
|
|
16649
16649
|
process.exitCode = 0;
|
|
16650
|
-
|
|
16650
|
+
resolve10();
|
|
16651
16651
|
return;
|
|
16652
16652
|
}
|
|
16653
16653
|
process.stdout.write("\x1B[1A\x1B[2K");
|
|
16654
|
-
|
|
16654
|
+
resolve10();
|
|
16655
16655
|
});
|
|
16656
16656
|
});
|
|
16657
16657
|
}
|
|
@@ -18507,6 +18507,20 @@ class PathResolver {
|
|
|
18507
18507
|
static isWSL() {
|
|
18508
18508
|
return isWSL();
|
|
18509
18509
|
}
|
|
18510
|
+
static isAtHomeDirectory(cwd) {
|
|
18511
|
+
const currentDir = normalize(cwd || process.cwd());
|
|
18512
|
+
const homeDir = normalize(homedir());
|
|
18513
|
+
return currentDir === homeDir;
|
|
18514
|
+
}
|
|
18515
|
+
static getLocalClaudeDir(baseDir) {
|
|
18516
|
+
const dir = baseDir || process.cwd();
|
|
18517
|
+
return join(dir, ".claude");
|
|
18518
|
+
}
|
|
18519
|
+
static isLocalSameAsGlobal(cwd) {
|
|
18520
|
+
const localPath = normalize(PathResolver.getLocalClaudeDir(cwd));
|
|
18521
|
+
const globalPath = normalize(PathResolver.getGlobalKitDir());
|
|
18522
|
+
return localPath === globalPath;
|
|
18523
|
+
}
|
|
18510
18524
|
}
|
|
18511
18525
|
|
|
18512
18526
|
// src/shared/skip-directories.ts
|
|
@@ -18621,7 +18635,8 @@ async function getClaudeKitSetup(projectDir = process.cwd()) {
|
|
|
18621
18635
|
setup.global.components = await scanClaudeKitDirectory(globalDir);
|
|
18622
18636
|
}
|
|
18623
18637
|
const projectClaudeDir = join2(projectDir, ".claude");
|
|
18624
|
-
|
|
18638
|
+
const isLocalSameAsGlobal = projectClaudeDir === globalDir;
|
|
18639
|
+
if (!isLocalSameAsGlobal && await import_fs_extra.pathExists(projectClaudeDir)) {
|
|
18625
18640
|
setup.project.path = projectClaudeDir;
|
|
18626
18641
|
setup.project.metadata = await readClaudeKitMetadata(join2(projectClaudeDir, "metadata.json"));
|
|
18627
18642
|
setup.project.components = await scanClaudeKitDirectory(projectClaudeDir);
|
|
@@ -22383,11 +22398,15 @@ function getInstalledKits(metadata) {
|
|
|
22383
22398
|
return Object.keys(metadata.kits);
|
|
22384
22399
|
}
|
|
22385
22400
|
const nameToCheck = metadata.name || "";
|
|
22401
|
+
const kits = [];
|
|
22386
22402
|
if (/\bengineer\b/i.test(nameToCheck)) {
|
|
22387
|
-
|
|
22403
|
+
kits.push("engineer");
|
|
22388
22404
|
}
|
|
22389
22405
|
if (/\bmarketing\b/i.test(nameToCheck)) {
|
|
22390
|
-
|
|
22406
|
+
kits.push("marketing");
|
|
22407
|
+
}
|
|
22408
|
+
if (kits.length > 0) {
|
|
22409
|
+
return kits;
|
|
22391
22410
|
}
|
|
22392
22411
|
if (metadata.version) {
|
|
22393
22412
|
return ["engineer"];
|
|
@@ -24815,6 +24834,28 @@ class PromptsManager {
|
|
|
24815
24834
|
async promptDirectorySelection(global2 = false) {
|
|
24816
24835
|
return promptDirectorySelection(global2);
|
|
24817
24836
|
}
|
|
24837
|
+
async selectScope() {
|
|
24838
|
+
const options = [
|
|
24839
|
+
{
|
|
24840
|
+
value: "global",
|
|
24841
|
+
label: "Install globally",
|
|
24842
|
+
hint: "Continue installing to ~/.claude/"
|
|
24843
|
+
},
|
|
24844
|
+
{
|
|
24845
|
+
value: "different",
|
|
24846
|
+
label: "Use a different directory",
|
|
24847
|
+
hint: "Cancel and run from a project directory"
|
|
24848
|
+
}
|
|
24849
|
+
];
|
|
24850
|
+
const selected = await ie({
|
|
24851
|
+
message: "What would you like to do?",
|
|
24852
|
+
options
|
|
24853
|
+
});
|
|
24854
|
+
if (lD(selected)) {
|
|
24855
|
+
return "cancel";
|
|
24856
|
+
}
|
|
24857
|
+
return selected;
|
|
24858
|
+
}
|
|
24818
24859
|
}
|
|
24819
24860
|
|
|
24820
24861
|
// src/commands/init/init-command.ts
|
|
@@ -24864,18 +24905,18 @@ init_types2();
|
|
|
24864
24905
|
|
|
24865
24906
|
// src/commands/init/phases/conflict-handler.ts
|
|
24866
24907
|
init_logger();
|
|
24867
|
-
import { join as join27
|
|
24908
|
+
import { join as join27 } from "node:path";
|
|
24868
24909
|
var import_fs_extra3 = __toESM(require_lib(), 1);
|
|
24869
24910
|
async function handleConflicts(ctx) {
|
|
24870
24911
|
if (ctx.cancelled)
|
|
24871
24912
|
return ctx;
|
|
24872
24913
|
if (!ctx.options.global)
|
|
24873
24914
|
return ctx;
|
|
24874
|
-
|
|
24875
|
-
|
|
24876
|
-
|
|
24915
|
+
if (PathResolver.isLocalSameAsGlobal()) {
|
|
24916
|
+
return ctx;
|
|
24917
|
+
}
|
|
24877
24918
|
const localSettingsPath = join27(process.cwd(), ".claude", "settings.json");
|
|
24878
|
-
if (
|
|
24919
|
+
if (!await import_fs_extra3.pathExists(localSettingsPath)) {
|
|
24879
24920
|
return ctx;
|
|
24880
24921
|
}
|
|
24881
24922
|
if (ctx.isNonInteractive) {
|
|
@@ -26503,11 +26544,11 @@ init_types2();
|
|
|
26503
26544
|
|
|
26504
26545
|
// src/domains/installation/utils/path-security.ts
|
|
26505
26546
|
init_types2();
|
|
26506
|
-
import { relative as relative3, resolve as
|
|
26547
|
+
import { relative as relative3, resolve as resolve4 } from "node:path";
|
|
26507
26548
|
var MAX_EXTRACTION_SIZE = 500 * 1024 * 1024;
|
|
26508
26549
|
function isPathSafe(basePath, targetPath) {
|
|
26509
|
-
const resolvedBase =
|
|
26510
|
-
const resolvedTarget =
|
|
26550
|
+
const resolvedBase = resolve4(basePath);
|
|
26551
|
+
const resolvedTarget = resolve4(targetPath);
|
|
26511
26552
|
const relativePath = relative3(resolvedBase, resolvedTarget);
|
|
26512
26553
|
return !relativePath.startsWith("..") && !relativePath.startsWith("/") && resolvedTarget.startsWith(resolvedBase);
|
|
26513
26554
|
}
|
|
@@ -27244,10 +27285,10 @@ class Minipass extends EventEmitter2 {
|
|
|
27244
27285
|
return this[ENCODING] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
27245
27286
|
}
|
|
27246
27287
|
async promise() {
|
|
27247
|
-
return new Promise((
|
|
27288
|
+
return new Promise((resolve5, reject) => {
|
|
27248
27289
|
this.on(DESTROYED, () => reject(new Error("stream destroyed")));
|
|
27249
27290
|
this.on("error", (er) => reject(er));
|
|
27250
|
-
this.on("end", () =>
|
|
27291
|
+
this.on("end", () => resolve5());
|
|
27251
27292
|
});
|
|
27252
27293
|
}
|
|
27253
27294
|
[Symbol.asyncIterator]() {
|
|
@@ -27266,7 +27307,7 @@ class Minipass extends EventEmitter2 {
|
|
|
27266
27307
|
return Promise.resolve({ done: false, value: res });
|
|
27267
27308
|
if (this[EOF])
|
|
27268
27309
|
return stop();
|
|
27269
|
-
let
|
|
27310
|
+
let resolve5;
|
|
27270
27311
|
let reject;
|
|
27271
27312
|
const onerr = (er) => {
|
|
27272
27313
|
this.off("data", ondata);
|
|
@@ -27280,19 +27321,19 @@ class Minipass extends EventEmitter2 {
|
|
|
27280
27321
|
this.off("end", onend);
|
|
27281
27322
|
this.off(DESTROYED, ondestroy);
|
|
27282
27323
|
this.pause();
|
|
27283
|
-
|
|
27324
|
+
resolve5({ value, done: !!this[EOF] });
|
|
27284
27325
|
};
|
|
27285
27326
|
const onend = () => {
|
|
27286
27327
|
this.off("error", onerr);
|
|
27287
27328
|
this.off("data", ondata);
|
|
27288
27329
|
this.off(DESTROYED, ondestroy);
|
|
27289
27330
|
stop();
|
|
27290
|
-
|
|
27331
|
+
resolve5({ done: true, value: undefined });
|
|
27291
27332
|
};
|
|
27292
27333
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
27293
27334
|
return new Promise((res2, rej) => {
|
|
27294
27335
|
reject = rej;
|
|
27295
|
-
|
|
27336
|
+
resolve5 = res2;
|
|
27296
27337
|
this.once(DESTROYED, ondestroy);
|
|
27297
27338
|
this.once("error", onerr);
|
|
27298
27339
|
this.once("end", onend);
|
|
@@ -28398,10 +28439,10 @@ class Minipass2 extends EventEmitter3 {
|
|
|
28398
28439
|
return this[ENCODING2] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
28399
28440
|
}
|
|
28400
28441
|
async promise() {
|
|
28401
|
-
return new Promise((
|
|
28442
|
+
return new Promise((resolve5, reject) => {
|
|
28402
28443
|
this.on(DESTROYED2, () => reject(new Error("stream destroyed")));
|
|
28403
28444
|
this.on("error", (er) => reject(er));
|
|
28404
|
-
this.on("end", () =>
|
|
28445
|
+
this.on("end", () => resolve5());
|
|
28405
28446
|
});
|
|
28406
28447
|
}
|
|
28407
28448
|
[Symbol.asyncIterator]() {
|
|
@@ -28420,7 +28461,7 @@ class Minipass2 extends EventEmitter3 {
|
|
|
28420
28461
|
return Promise.resolve({ done: false, value: res });
|
|
28421
28462
|
if (this[EOF2])
|
|
28422
28463
|
return stop();
|
|
28423
|
-
let
|
|
28464
|
+
let resolve5;
|
|
28424
28465
|
let reject;
|
|
28425
28466
|
const onerr = (er) => {
|
|
28426
28467
|
this.off("data", ondata);
|
|
@@ -28434,19 +28475,19 @@ class Minipass2 extends EventEmitter3 {
|
|
|
28434
28475
|
this.off("end", onend);
|
|
28435
28476
|
this.off(DESTROYED2, ondestroy);
|
|
28436
28477
|
this.pause();
|
|
28437
|
-
|
|
28478
|
+
resolve5({ value, done: !!this[EOF2] });
|
|
28438
28479
|
};
|
|
28439
28480
|
const onend = () => {
|
|
28440
28481
|
this.off("error", onerr);
|
|
28441
28482
|
this.off("data", ondata);
|
|
28442
28483
|
this.off(DESTROYED2, ondestroy);
|
|
28443
28484
|
stop();
|
|
28444
|
-
|
|
28485
|
+
resolve5({ done: true, value: undefined });
|
|
28445
28486
|
};
|
|
28446
28487
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
28447
28488
|
return new Promise((res2, rej) => {
|
|
28448
28489
|
reject = rej;
|
|
28449
|
-
|
|
28490
|
+
resolve5 = res2;
|
|
28450
28491
|
this.once(DESTROYED2, ondestroy);
|
|
28451
28492
|
this.once("error", onerr);
|
|
28452
28493
|
this.once("end", onend);
|
|
@@ -29874,10 +29915,10 @@ class Minipass3 extends EventEmitter4 {
|
|
|
29874
29915
|
return this[ENCODING3] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
29875
29916
|
}
|
|
29876
29917
|
async promise() {
|
|
29877
|
-
return new Promise((
|
|
29918
|
+
return new Promise((resolve5, reject) => {
|
|
29878
29919
|
this.on(DESTROYED3, () => reject(new Error("stream destroyed")));
|
|
29879
29920
|
this.on("error", (er) => reject(er));
|
|
29880
|
-
this.on("end", () =>
|
|
29921
|
+
this.on("end", () => resolve5());
|
|
29881
29922
|
});
|
|
29882
29923
|
}
|
|
29883
29924
|
[Symbol.asyncIterator]() {
|
|
@@ -29896,7 +29937,7 @@ class Minipass3 extends EventEmitter4 {
|
|
|
29896
29937
|
return Promise.resolve({ done: false, value: res });
|
|
29897
29938
|
if (this[EOF3])
|
|
29898
29939
|
return stop();
|
|
29899
|
-
let
|
|
29940
|
+
let resolve5;
|
|
29900
29941
|
let reject;
|
|
29901
29942
|
const onerr = (er) => {
|
|
29902
29943
|
this.off("data", ondata);
|
|
@@ -29910,19 +29951,19 @@ class Minipass3 extends EventEmitter4 {
|
|
|
29910
29951
|
this.off("end", onend);
|
|
29911
29952
|
this.off(DESTROYED3, ondestroy);
|
|
29912
29953
|
this.pause();
|
|
29913
|
-
|
|
29954
|
+
resolve5({ value, done: !!this[EOF3] });
|
|
29914
29955
|
};
|
|
29915
29956
|
const onend = () => {
|
|
29916
29957
|
this.off("error", onerr);
|
|
29917
29958
|
this.off("data", ondata);
|
|
29918
29959
|
this.off(DESTROYED3, ondestroy);
|
|
29919
29960
|
stop();
|
|
29920
|
-
|
|
29961
|
+
resolve5({ done: true, value: undefined });
|
|
29921
29962
|
};
|
|
29922
29963
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
29923
29964
|
return new Promise((res2, rej) => {
|
|
29924
29965
|
reject = rej;
|
|
29925
|
-
|
|
29966
|
+
resolve5 = res2;
|
|
29926
29967
|
this.once(DESTROYED3, ondestroy);
|
|
29927
29968
|
this.once("error", onerr);
|
|
29928
29969
|
this.once("end", onend);
|
|
@@ -30693,9 +30734,9 @@ var listFile = (opt, _files) => {
|
|
|
30693
30734
|
const parse3 = new Parser(opt);
|
|
30694
30735
|
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
|
|
30695
30736
|
const file = opt.file;
|
|
30696
|
-
const p = new Promise((
|
|
30737
|
+
const p = new Promise((resolve5, reject) => {
|
|
30697
30738
|
parse3.on("error", reject);
|
|
30698
|
-
parse3.on("end",
|
|
30739
|
+
parse3.on("end", resolve5);
|
|
30699
30740
|
fs4.stat(file, (er, stat3) => {
|
|
30700
30741
|
if (er) {
|
|
30701
30742
|
reject(er);
|
|
@@ -33275,9 +33316,9 @@ var extractFile = (opt, _3) => {
|
|
|
33275
33316
|
const u = new Unpack(opt);
|
|
33276
33317
|
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
|
|
33277
33318
|
const file = opt.file;
|
|
33278
|
-
const p = new Promise((
|
|
33319
|
+
const p = new Promise((resolve5, reject) => {
|
|
33279
33320
|
u.on("error", reject);
|
|
33280
|
-
u.on("close",
|
|
33321
|
+
u.on("close", resolve5);
|
|
33281
33322
|
fs11.stat(file, (er, stat3) => {
|
|
33282
33323
|
if (er) {
|
|
33283
33324
|
reject(er);
|
|
@@ -33410,7 +33451,7 @@ var replaceAsync = (opt, files) => {
|
|
|
33410
33451
|
};
|
|
33411
33452
|
fs12.read(fd, headBuf, 0, 512, position, onread);
|
|
33412
33453
|
};
|
|
33413
|
-
const promise = new Promise((
|
|
33454
|
+
const promise = new Promise((resolve5, reject) => {
|
|
33414
33455
|
p.on("error", reject);
|
|
33415
33456
|
let flag = "r+";
|
|
33416
33457
|
const onopen = (er, fd) => {
|
|
@@ -33435,7 +33476,7 @@ var replaceAsync = (opt, files) => {
|
|
|
33435
33476
|
});
|
|
33436
33477
|
p.pipe(stream);
|
|
33437
33478
|
stream.on("error", reject);
|
|
33438
|
-
stream.on("close",
|
|
33479
|
+
stream.on("close", resolve5);
|
|
33439
33480
|
addFilesAsync2(p, files);
|
|
33440
33481
|
});
|
|
33441
33482
|
});
|
|
@@ -33709,20 +33750,20 @@ class ZipExtractor {
|
|
|
33709
33750
|
if (!isMacOS()) {
|
|
33710
33751
|
return false;
|
|
33711
33752
|
}
|
|
33712
|
-
return new Promise((
|
|
33753
|
+
return new Promise((resolve5) => {
|
|
33713
33754
|
mkdir13(destDir, { recursive: true }).then(() => {
|
|
33714
33755
|
execFile2("unzip", ["-o", "-q", archivePath, "-d", destDir], (error, _stdout, stderr) => {
|
|
33715
33756
|
if (error) {
|
|
33716
33757
|
logger.debug(`Native unzip failed: ${stderr || error.message}`);
|
|
33717
|
-
|
|
33758
|
+
resolve5(false);
|
|
33718
33759
|
return;
|
|
33719
33760
|
}
|
|
33720
33761
|
logger.debug("Native unzip succeeded");
|
|
33721
|
-
|
|
33762
|
+
resolve5(true);
|
|
33722
33763
|
});
|
|
33723
33764
|
}).catch((err) => {
|
|
33724
33765
|
logger.debug(`Failed to create directory for native unzip: ${err.message}`);
|
|
33725
|
-
|
|
33766
|
+
resolve5(false);
|
|
33726
33767
|
});
|
|
33727
33768
|
});
|
|
33728
33769
|
}
|
|
@@ -34230,7 +34271,7 @@ async function handleDownload(ctx) {
|
|
|
34230
34271
|
};
|
|
34231
34272
|
}
|
|
34232
34273
|
// src/commands/init/phases/merge-handler.ts
|
|
34233
|
-
import { join as
|
|
34274
|
+
import { join as join50 } from "node:path";
|
|
34234
34275
|
|
|
34235
34276
|
// src/domains/installation/file-merger.ts
|
|
34236
34277
|
init_logger();
|
|
@@ -36167,9 +36208,6 @@ class InstalledSettingsTracker {
|
|
|
36167
36208
|
}
|
|
36168
36209
|
}
|
|
36169
36210
|
|
|
36170
|
-
// src/domains/config/merger/merge-engine.ts
|
|
36171
|
-
init_logger();
|
|
36172
|
-
|
|
36173
36211
|
// src/domains/config/merger/diff-calculator.ts
|
|
36174
36212
|
function truncateCommand(cmd, maxLen = 50) {
|
|
36175
36213
|
if (cmd.length <= maxLen)
|
|
@@ -36368,12 +36406,61 @@ function mergeHooks(sourceHooks, destHooks, result, options) {
|
|
|
36368
36406
|
const merged = { ...destHooks };
|
|
36369
36407
|
const installedHooks = options?.installedSettings?.hooks ?? [];
|
|
36370
36408
|
const sourceKit = options?.sourceKit;
|
|
36409
|
+
const sourceCommands = new Set;
|
|
36410
|
+
for (const entries of Object.values(sourceHooks)) {
|
|
36411
|
+
extractCommands(entries, sourceCommands);
|
|
36412
|
+
}
|
|
36371
36413
|
for (const [eventName, sourceEntries] of Object.entries(sourceHooks)) {
|
|
36372
36414
|
const destEntries = destHooks[eventName] || [];
|
|
36373
36415
|
merged[eventName] = mergeHookEntries(sourceEntries, destEntries, eventName, result, installedHooks, sourceKit);
|
|
36374
36416
|
}
|
|
36417
|
+
if (installedHooks.length > 0) {
|
|
36418
|
+
const deprecatedHooks = installedHooks.filter((hook) => !sourceCommands.has(normalizeCommand(hook)));
|
|
36419
|
+
if (deprecatedHooks.length > 0) {
|
|
36420
|
+
result.removedHooks = result.removedHooks ?? [];
|
|
36421
|
+
for (const [eventName, entries] of Object.entries(merged)) {
|
|
36422
|
+
const filtered = removeDeprecatedFromEntries(entries, deprecatedHooks, result);
|
|
36423
|
+
if (filtered.length > 0) {
|
|
36424
|
+
merged[eventName] = filtered;
|
|
36425
|
+
} else {
|
|
36426
|
+
delete merged[eventName];
|
|
36427
|
+
}
|
|
36428
|
+
}
|
|
36429
|
+
}
|
|
36430
|
+
}
|
|
36375
36431
|
return merged;
|
|
36376
36432
|
}
|
|
36433
|
+
function removeDeprecatedFromEntries(entries, deprecatedHooks, result) {
|
|
36434
|
+
const deprecatedSet = new Set(deprecatedHooks.map((h2) => normalizeCommand(h2)));
|
|
36435
|
+
const filtered = [];
|
|
36436
|
+
for (const entry of entries) {
|
|
36437
|
+
if ("hooks" in entry && entry.hooks) {
|
|
36438
|
+
const remainingHooks = entry.hooks.filter((h2) => {
|
|
36439
|
+
if (h2.command && deprecatedSet.has(normalizeCommand(h2.command))) {
|
|
36440
|
+
result.hooksRemoved++;
|
|
36441
|
+
result.removedHooks?.push(h2.command);
|
|
36442
|
+
logger.info(`Removed deprecated hook: ${h2.command.slice(0, 60)}...`);
|
|
36443
|
+
return false;
|
|
36444
|
+
}
|
|
36445
|
+
return true;
|
|
36446
|
+
});
|
|
36447
|
+
if (remainingHooks.length > 0) {
|
|
36448
|
+
filtered.push({ ...entry, hooks: remainingHooks });
|
|
36449
|
+
}
|
|
36450
|
+
} else if ("command" in entry) {
|
|
36451
|
+
if (deprecatedSet.has(normalizeCommand(entry.command))) {
|
|
36452
|
+
result.hooksRemoved++;
|
|
36453
|
+
result.removedHooks?.push(entry.command);
|
|
36454
|
+
logger.info(`Removed deprecated hook: ${entry.command.slice(0, 60)}...`);
|
|
36455
|
+
} else {
|
|
36456
|
+
filtered.push(entry);
|
|
36457
|
+
}
|
|
36458
|
+
} else {
|
|
36459
|
+
filtered.push(entry);
|
|
36460
|
+
}
|
|
36461
|
+
}
|
|
36462
|
+
return filtered;
|
|
36463
|
+
}
|
|
36377
36464
|
function mergeMcp(sourceMcp, destMcp, result, options) {
|
|
36378
36465
|
if (!sourceMcp)
|
|
36379
36466
|
return destMcp;
|
|
@@ -36450,6 +36537,24 @@ function mergeMcp(sourceMcp, destMcp, result, options) {
|
|
|
36450
36537
|
}
|
|
36451
36538
|
}
|
|
36452
36539
|
}
|
|
36540
|
+
if (installedServers.length > 0 && merged.servers) {
|
|
36541
|
+
const sourceServerNames = new Set(Object.keys(sourceMcp.servers || {}));
|
|
36542
|
+
const deprecatedServers = installedServers.filter((server) => !sourceServerNames.has(server));
|
|
36543
|
+
if (deprecatedServers.length > 0) {
|
|
36544
|
+
result.removedMcpServers = result.removedMcpServers ?? [];
|
|
36545
|
+
for (const serverName of deprecatedServers) {
|
|
36546
|
+
if (serverName in merged.servers) {
|
|
36547
|
+
delete merged.servers[serverName];
|
|
36548
|
+
result.mcpServersRemoved++;
|
|
36549
|
+
result.removedMcpServers.push(serverName);
|
|
36550
|
+
logger.info(`Removed deprecated MCP server: ${serverName}`);
|
|
36551
|
+
}
|
|
36552
|
+
}
|
|
36553
|
+
if (merged.servers && Object.keys(merged.servers).length === 0) {
|
|
36554
|
+
merged.servers = undefined;
|
|
36555
|
+
}
|
|
36556
|
+
}
|
|
36557
|
+
}
|
|
36453
36558
|
for (const key of Object.keys(sourceMcp)) {
|
|
36454
36559
|
if (key !== "servers" && !(key in merged)) {
|
|
36455
36560
|
merged[key] = sourceMcp[key];
|
|
@@ -36463,8 +36568,10 @@ function mergeSettings(source, destination, options) {
|
|
|
36463
36568
|
hooksAdded: 0,
|
|
36464
36569
|
hooksPreserved: 0,
|
|
36465
36570
|
hooksSkipped: 0,
|
|
36571
|
+
hooksRemoved: 0,
|
|
36466
36572
|
mcpServersPreserved: 0,
|
|
36467
36573
|
mcpServersSkipped: 0,
|
|
36574
|
+
mcpServersRemoved: 0,
|
|
36468
36575
|
conflictsDetected: [],
|
|
36469
36576
|
newlyInstalledHooks: [],
|
|
36470
36577
|
newlyInstalledServers: [],
|
|
@@ -37352,6 +37459,8 @@ class LegacyMigration {
|
|
|
37352
37459
|
for (const entry of entries) {
|
|
37353
37460
|
if (entry === "metadata.json")
|
|
37354
37461
|
continue;
|
|
37462
|
+
if (SKIP_DIRS_ALL.includes(entry))
|
|
37463
|
+
continue;
|
|
37355
37464
|
const fullPath = join44(dir, entry);
|
|
37356
37465
|
let stats;
|
|
37357
37466
|
try {
|
|
@@ -37578,7 +37687,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
|
|
|
37578
37687
|
}
|
|
37579
37688
|
|
|
37580
37689
|
// src/services/file-operations/file-scanner.ts
|
|
37581
|
-
import { join as join45, relative as relative8, resolve as
|
|
37690
|
+
import { join as join45, relative as relative8, resolve as resolve6 } from "node:path";
|
|
37582
37691
|
init_logger();
|
|
37583
37692
|
var import_fs_extra12 = __toESM(require_lib(), 1);
|
|
37584
37693
|
|
|
@@ -37660,8 +37769,8 @@ class FileScanner2 {
|
|
|
37660
37769
|
return customFiles;
|
|
37661
37770
|
}
|
|
37662
37771
|
static isSafePath(basePath, targetPath) {
|
|
37663
|
-
const resolvedBase =
|
|
37664
|
-
const resolvedTarget =
|
|
37772
|
+
const resolvedBase = resolve6(basePath);
|
|
37773
|
+
const resolvedTarget = resolve6(targetPath);
|
|
37665
37774
|
return resolvedTarget.startsWith(resolvedBase);
|
|
37666
37775
|
}
|
|
37667
37776
|
static toPosixPath(path11) {
|
|
@@ -37672,8 +37781,113 @@ class FileScanner2 {
|
|
|
37672
37781
|
// src/services/transformers/commands-prefix/prefix-applier.ts
|
|
37673
37782
|
init_logger();
|
|
37674
37783
|
var import_fs_extra13 = __toESM(require_lib(), 1);
|
|
37675
|
-
import { lstat as lstat5, mkdir as mkdir16, readdir as
|
|
37784
|
+
import { lstat as lstat5, mkdir as mkdir16, readdir as readdir12, stat as stat8 } from "node:fs/promises";
|
|
37785
|
+
import { join as join47 } from "node:path";
|
|
37786
|
+
|
|
37787
|
+
// src/services/transformers/commands-prefix/content-transformer.ts
|
|
37788
|
+
init_logger();
|
|
37789
|
+
import { readFile as readFile17, readdir as readdir11, writeFile as writeFile14 } from "node:fs/promises";
|
|
37676
37790
|
import { join as join46 } from "node:path";
|
|
37791
|
+
var TRANSFORMABLE_EXTENSIONS = new Set([
|
|
37792
|
+
".md",
|
|
37793
|
+
".txt",
|
|
37794
|
+
".json",
|
|
37795
|
+
".yaml",
|
|
37796
|
+
".yml",
|
|
37797
|
+
".ts",
|
|
37798
|
+
".js",
|
|
37799
|
+
".mjs",
|
|
37800
|
+
".cjs",
|
|
37801
|
+
".py"
|
|
37802
|
+
]);
|
|
37803
|
+
var COMMAND_ROOTS = [
|
|
37804
|
+
"plan",
|
|
37805
|
+
"fix",
|
|
37806
|
+
"code",
|
|
37807
|
+
"review",
|
|
37808
|
+
"cook",
|
|
37809
|
+
"brainstorm",
|
|
37810
|
+
"integrate",
|
|
37811
|
+
"bootstrap",
|
|
37812
|
+
"worktree",
|
|
37813
|
+
"scout",
|
|
37814
|
+
"test",
|
|
37815
|
+
"debug",
|
|
37816
|
+
"preview",
|
|
37817
|
+
"kanban",
|
|
37818
|
+
"journal",
|
|
37819
|
+
"watzup"
|
|
37820
|
+
];
|
|
37821
|
+
function buildCommandPatterns() {
|
|
37822
|
+
const patterns = [];
|
|
37823
|
+
for (const cmd of COMMAND_ROOTS) {
|
|
37824
|
+
patterns.push({
|
|
37825
|
+
regex: new RegExp(`(?<![\\w:])(\\/)${cmd}(:)`, "g"),
|
|
37826
|
+
replacement: "$1ck:$2".replace("$2", `${cmd}:`)
|
|
37827
|
+
});
|
|
37828
|
+
patterns.push({
|
|
37829
|
+
regex: new RegExp(`(?<![\\w:])(\\/)${cmd}(?=[\\s\`"'\\)\\]}>.,;:!?]|$)`, "g"),
|
|
37830
|
+
replacement: `$1ck:${cmd}`
|
|
37831
|
+
});
|
|
37832
|
+
}
|
|
37833
|
+
return patterns;
|
|
37834
|
+
}
|
|
37835
|
+
function transformCommandContent(content) {
|
|
37836
|
+
let changes = 0;
|
|
37837
|
+
let transformed = content;
|
|
37838
|
+
const patterns = buildCommandPatterns();
|
|
37839
|
+
for (const { regex: regex2, replacement } of patterns) {
|
|
37840
|
+
regex2.lastIndex = 0;
|
|
37841
|
+
const matches = transformed.match(regex2);
|
|
37842
|
+
if (matches) {
|
|
37843
|
+
changes += matches.length;
|
|
37844
|
+
regex2.lastIndex = 0;
|
|
37845
|
+
transformed = transformed.replace(regex2, replacement);
|
|
37846
|
+
}
|
|
37847
|
+
}
|
|
37848
|
+
return { transformed, changes };
|
|
37849
|
+
}
|
|
37850
|
+
function shouldTransformFile(filename) {
|
|
37851
|
+
const ext2 = filename.toLowerCase().slice(filename.lastIndexOf("."));
|
|
37852
|
+
return TRANSFORMABLE_EXTENSIONS.has(ext2);
|
|
37853
|
+
}
|
|
37854
|
+
async function transformCommandReferences(directory, options = {}) {
|
|
37855
|
+
let filesTransformed = 0;
|
|
37856
|
+
let totalReplacements = 0;
|
|
37857
|
+
async function processDirectory(dir) {
|
|
37858
|
+
const entries = await readdir11(dir, { withFileTypes: true });
|
|
37859
|
+
for (const entry of entries) {
|
|
37860
|
+
const fullPath = join46(dir, entry.name);
|
|
37861
|
+
if (entry.isDirectory()) {
|
|
37862
|
+
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
37863
|
+
continue;
|
|
37864
|
+
}
|
|
37865
|
+
await processDirectory(fullPath);
|
|
37866
|
+
} else if (entry.isFile() && shouldTransformFile(entry.name)) {
|
|
37867
|
+
try {
|
|
37868
|
+
const content = await readFile17(fullPath, "utf-8");
|
|
37869
|
+
const { transformed, changes } = transformCommandContent(content);
|
|
37870
|
+
if (changes > 0) {
|
|
37871
|
+
if (options.dryRun) {
|
|
37872
|
+
logger.debug(`[dry-run] Would transform ${changes} command ref(s) in ${fullPath}`);
|
|
37873
|
+
} else {
|
|
37874
|
+
await writeFile14(fullPath, transformed, "utf-8");
|
|
37875
|
+
if (options.verbose) {
|
|
37876
|
+
logger.verbose(`Transformed ${changes} command ref(s) in ${fullPath}`);
|
|
37877
|
+
}
|
|
37878
|
+
}
|
|
37879
|
+
filesTransformed++;
|
|
37880
|
+
totalReplacements += changes;
|
|
37881
|
+
}
|
|
37882
|
+
} catch (error) {
|
|
37883
|
+
logger.debug(`Skipped ${fullPath}: ${error instanceof Error ? error.message : "unknown"}`);
|
|
37884
|
+
}
|
|
37885
|
+
}
|
|
37886
|
+
}
|
|
37887
|
+
}
|
|
37888
|
+
await processDirectory(directory);
|
|
37889
|
+
return { filesTransformed, totalReplacements };
|
|
37890
|
+
}
|
|
37677
37891
|
|
|
37678
37892
|
// src/services/transformers/commands-prefix/prefix-utils.ts
|
|
37679
37893
|
init_logger();
|
|
@@ -37718,22 +37932,22 @@ function shouldApplyPrefix(options) {
|
|
|
37718
37932
|
// src/services/transformers/commands-prefix/prefix-applier.ts
|
|
37719
37933
|
async function applyPrefix(extractDir) {
|
|
37720
37934
|
validatePath(extractDir, "extractDir");
|
|
37721
|
-
const commandsDir =
|
|
37935
|
+
const commandsDir = join47(extractDir, ".claude", "commands");
|
|
37722
37936
|
if (!await import_fs_extra13.pathExists(commandsDir)) {
|
|
37723
37937
|
logger.verbose("No commands directory found, skipping prefix application");
|
|
37724
37938
|
return;
|
|
37725
37939
|
}
|
|
37726
37940
|
logger.info("Applying /ck: prefix to slash commands...");
|
|
37727
|
-
const backupDir =
|
|
37728
|
-
const tempDir =
|
|
37941
|
+
const backupDir = join47(extractDir, ".commands-backup");
|
|
37942
|
+
const tempDir = join47(extractDir, ".commands-prefix-temp");
|
|
37729
37943
|
try {
|
|
37730
|
-
const entries = await
|
|
37944
|
+
const entries = await readdir12(commandsDir);
|
|
37731
37945
|
if (entries.length === 0) {
|
|
37732
37946
|
logger.verbose("Commands directory is empty, skipping prefix application");
|
|
37733
37947
|
return;
|
|
37734
37948
|
}
|
|
37735
37949
|
if (entries.length === 1 && entries[0] === "ck") {
|
|
37736
|
-
const ckDir2 =
|
|
37950
|
+
const ckDir2 = join47(commandsDir, "ck");
|
|
37737
37951
|
const ckStat = await stat8(ckDir2);
|
|
37738
37952
|
if (ckStat.isDirectory()) {
|
|
37739
37953
|
logger.verbose("Commands already have /ck: prefix, skipping");
|
|
@@ -37743,17 +37957,17 @@ async function applyPrefix(extractDir) {
|
|
|
37743
37957
|
await import_fs_extra13.copy(commandsDir, backupDir);
|
|
37744
37958
|
logger.verbose("Created backup of commands directory");
|
|
37745
37959
|
await mkdir16(tempDir, { recursive: true });
|
|
37746
|
-
const ckDir =
|
|
37960
|
+
const ckDir = join47(tempDir, "ck");
|
|
37747
37961
|
await mkdir16(ckDir, { recursive: true });
|
|
37748
37962
|
let processedCount = 0;
|
|
37749
37963
|
for (const entry of entries) {
|
|
37750
|
-
const sourcePath =
|
|
37964
|
+
const sourcePath = join47(commandsDir, entry);
|
|
37751
37965
|
const stats = await lstat5(sourcePath);
|
|
37752
37966
|
if (stats.isSymbolicLink()) {
|
|
37753
37967
|
logger.warning(`Skipping symlink for security: ${entry}`);
|
|
37754
37968
|
continue;
|
|
37755
37969
|
}
|
|
37756
|
-
const destPath =
|
|
37970
|
+
const destPath = join47(ckDir, entry);
|
|
37757
37971
|
await import_fs_extra13.copy(sourcePath, destPath, {
|
|
37758
37972
|
overwrite: false,
|
|
37759
37973
|
errorOnExist: true
|
|
@@ -37770,7 +37984,17 @@ async function applyPrefix(extractDir) {
|
|
|
37770
37984
|
await import_fs_extra13.remove(commandsDir);
|
|
37771
37985
|
await import_fs_extra13.move(tempDir, commandsDir);
|
|
37772
37986
|
await import_fs_extra13.remove(backupDir);
|
|
37773
|
-
logger.success("Successfully
|
|
37987
|
+
logger.success("Successfully reorganized commands to /ck: prefix");
|
|
37988
|
+
const claudeDir = join47(extractDir, ".claude");
|
|
37989
|
+
logger.info("Transforming command references in file contents...");
|
|
37990
|
+
const transformResult = await transformCommandReferences(claudeDir, {
|
|
37991
|
+
verbose: logger.isVerbose()
|
|
37992
|
+
});
|
|
37993
|
+
if (transformResult.totalReplacements > 0) {
|
|
37994
|
+
logger.success(`Transformed ${transformResult.totalReplacements} command ref(s) in ${transformResult.filesTransformed} file(s)`);
|
|
37995
|
+
} else {
|
|
37996
|
+
logger.verbose("No command references needed transformation");
|
|
37997
|
+
}
|
|
37774
37998
|
} catch (error) {
|
|
37775
37999
|
if (await import_fs_extra13.pathExists(backupDir)) {
|
|
37776
38000
|
try {
|
|
@@ -37797,21 +38021,21 @@ async function applyPrefix(extractDir) {
|
|
|
37797
38021
|
}
|
|
37798
38022
|
|
|
37799
38023
|
// src/services/transformers/commands-prefix/prefix-cleaner.ts
|
|
37800
|
-
import { lstat as lstat7, readdir as
|
|
37801
|
-
import { join as
|
|
38024
|
+
import { lstat as lstat7, readdir as readdir14 } from "node:fs/promises";
|
|
38025
|
+
import { join as join49 } from "node:path";
|
|
37802
38026
|
init_logger();
|
|
37803
38027
|
var import_fs_extra15 = __toESM(require_lib(), 1);
|
|
37804
38028
|
|
|
37805
38029
|
// src/services/transformers/commands-prefix/file-processor.ts
|
|
37806
|
-
import { lstat as lstat6, readdir as
|
|
37807
|
-
import { join as
|
|
38030
|
+
import { lstat as lstat6, readdir as readdir13 } from "node:fs/promises";
|
|
38031
|
+
import { join as join48 } from "node:path";
|
|
37808
38032
|
init_logger();
|
|
37809
38033
|
var import_fs_extra14 = __toESM(require_lib(), 1);
|
|
37810
38034
|
async function scanDirectoryFiles(dir) {
|
|
37811
38035
|
const files = [];
|
|
37812
|
-
const entries = await
|
|
38036
|
+
const entries = await readdir13(dir);
|
|
37813
38037
|
for (const entry of entries) {
|
|
37814
|
-
const fullPath =
|
|
38038
|
+
const fullPath = join48(dir, entry);
|
|
37815
38039
|
const stats = await lstat6(fullPath);
|
|
37816
38040
|
if (stats.isSymbolicLink()) {
|
|
37817
38041
|
continue;
|
|
@@ -37919,8 +38143,8 @@ function logCleanupSummary(deletedCount, preservedCount, dryRun, results) {
|
|
|
37919
38143
|
async function cleanupCommandsDirectory(targetDir, isGlobal, options = {}) {
|
|
37920
38144
|
const { dryRun = false } = options;
|
|
37921
38145
|
validatePath(targetDir, "targetDir");
|
|
37922
|
-
const claudeDir = isGlobal ? targetDir :
|
|
37923
|
-
const commandsDir =
|
|
38146
|
+
const claudeDir = isGlobal ? targetDir : join49(targetDir, ".claude");
|
|
38147
|
+
const commandsDir = join49(claudeDir, "commands");
|
|
37924
38148
|
const accumulator = {
|
|
37925
38149
|
results: [],
|
|
37926
38150
|
deletedCount: 0,
|
|
@@ -37948,13 +38172,13 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options = {}) {
|
|
|
37948
38172
|
logger.verbose("All existing files will be preserved as user-owned");
|
|
37949
38173
|
return result;
|
|
37950
38174
|
}
|
|
37951
|
-
const entries = await
|
|
38175
|
+
const entries = await readdir14(commandsDir);
|
|
37952
38176
|
if (entries.length === 0) {
|
|
37953
38177
|
logger.verbose("Commands directory is empty");
|
|
37954
38178
|
return result;
|
|
37955
38179
|
}
|
|
37956
38180
|
for (const entry of entries) {
|
|
37957
|
-
const entryPath =
|
|
38181
|
+
const entryPath = join49(commandsDir, entry);
|
|
37958
38182
|
const stats = await lstat7(entryPath);
|
|
37959
38183
|
if (stats.isSymbolicLink()) {
|
|
37960
38184
|
addSymlinkSkip(entry, accumulator);
|
|
@@ -38006,7 +38230,7 @@ async function handleMerge(ctx) {
|
|
|
38006
38230
|
let customClaudeFiles = [];
|
|
38007
38231
|
if (!ctx.options.fresh) {
|
|
38008
38232
|
logger.info("Scanning for custom .claude files...");
|
|
38009
|
-
const scanSourceDir = ctx.options.global ?
|
|
38233
|
+
const scanSourceDir = ctx.options.global ? join50(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
38010
38234
|
const scanTargetSubdir = ctx.options.global ? "" : ".claude";
|
|
38011
38235
|
customClaudeFiles = await FileScanner2.findCustomFiles(ctx.resolvedDir, scanSourceDir, scanTargetSubdir);
|
|
38012
38236
|
} else {
|
|
@@ -38070,7 +38294,7 @@ async function handleMerge(ctx) {
|
|
|
38070
38294
|
return { ...ctx, cancelled: true };
|
|
38071
38295
|
}
|
|
38072
38296
|
}
|
|
38073
|
-
const sourceDir = ctx.options.global ?
|
|
38297
|
+
const sourceDir = ctx.options.global ? join50(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
38074
38298
|
await merger.merge(sourceDir, ctx.resolvedDir, ctx.isNonInteractive);
|
|
38075
38299
|
const fileConflicts = merger.getFileConflicts();
|
|
38076
38300
|
if (fileConflicts.length > 0 && !ctx.isNonInteractive) {
|
|
@@ -38099,7 +38323,7 @@ async function handleMerge(ctx) {
|
|
|
38099
38323
|
};
|
|
38100
38324
|
}
|
|
38101
38325
|
// src/commands/init/phases/migration-handler.ts
|
|
38102
|
-
import { join as
|
|
38326
|
+
import { join as join58 } from "node:path";
|
|
38103
38327
|
|
|
38104
38328
|
// src/domains/skills/skills-detector.ts
|
|
38105
38329
|
init_logger();
|
|
@@ -38110,11 +38334,11 @@ init_logger();
|
|
|
38110
38334
|
|
|
38111
38335
|
// src/domains/skills/skills-manifest.ts
|
|
38112
38336
|
init_logger();
|
|
38337
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
38338
|
+
import { readFile as readFile18, readdir as readdir15, writeFile as writeFile15 } from "node:fs/promises";
|
|
38339
|
+
import { join as join51, relative as relative9 } from "node:path";
|
|
38113
38340
|
init_types2();
|
|
38114
38341
|
var import_fs_extra17 = __toESM(require_lib(), 1);
|
|
38115
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
38116
|
-
import { readFile as readFile17, readdir as readdir14, writeFile as writeFile14 } from "node:fs/promises";
|
|
38117
|
-
import { join as join50, relative as relative9 } from "node:path";
|
|
38118
38342
|
|
|
38119
38343
|
class SkillsManifestManager {
|
|
38120
38344
|
static MANIFEST_FILENAME = ".skills-manifest.json";
|
|
@@ -38136,18 +38360,18 @@ class SkillsManifestManager {
|
|
|
38136
38360
|
return manifest;
|
|
38137
38361
|
}
|
|
38138
38362
|
static async writeManifest(skillsDir, manifest) {
|
|
38139
|
-
const manifestPath =
|
|
38140
|
-
await
|
|
38363
|
+
const manifestPath = join51(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
|
|
38364
|
+
await writeFile15(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
38141
38365
|
logger.debug(`Wrote manifest to: ${manifestPath}`);
|
|
38142
38366
|
}
|
|
38143
38367
|
static async readManifest(skillsDir) {
|
|
38144
|
-
const manifestPath =
|
|
38368
|
+
const manifestPath = join51(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
|
|
38145
38369
|
if (!await import_fs_extra17.pathExists(manifestPath)) {
|
|
38146
38370
|
logger.debug(`No manifest found at: ${manifestPath}`);
|
|
38147
38371
|
return null;
|
|
38148
38372
|
}
|
|
38149
38373
|
try {
|
|
38150
|
-
const content = await
|
|
38374
|
+
const content = await readFile18(manifestPath, "utf-8");
|
|
38151
38375
|
const data = JSON.parse(content);
|
|
38152
38376
|
const manifest = SkillsManifestSchema.parse(data);
|
|
38153
38377
|
logger.debug(`Read manifest from: ${manifestPath}`);
|
|
@@ -38158,14 +38382,14 @@ class SkillsManifestManager {
|
|
|
38158
38382
|
}
|
|
38159
38383
|
}
|
|
38160
38384
|
static async detectStructure(skillsDir) {
|
|
38161
|
-
const entries = await
|
|
38162
|
-
const dirs = entries.filter((entry) => entry.isDirectory() && entry.name
|
|
38385
|
+
const entries = await readdir15(skillsDir, { withFileTypes: true });
|
|
38386
|
+
const dirs = entries.filter((entry) => entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith("."));
|
|
38163
38387
|
if (dirs.length === 0) {
|
|
38164
38388
|
return "flat";
|
|
38165
38389
|
}
|
|
38166
38390
|
for (const dir of dirs.slice(0, 3)) {
|
|
38167
|
-
const dirPath =
|
|
38168
|
-
const subEntries = await
|
|
38391
|
+
const dirPath = join51(skillsDir, dir.name);
|
|
38392
|
+
const subEntries = await readdir15(dirPath, { withFileTypes: true });
|
|
38169
38393
|
const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
|
|
38170
38394
|
if (hasSubdirs) {
|
|
38171
38395
|
return "categorized";
|
|
@@ -38180,10 +38404,10 @@ class SkillsManifestManager {
|
|
|
38180
38404
|
static async scanSkills(skillsDir, structure) {
|
|
38181
38405
|
const skills = [];
|
|
38182
38406
|
if (structure === "flat") {
|
|
38183
|
-
const entries = await
|
|
38407
|
+
const entries = await readdir15(skillsDir, { withFileTypes: true });
|
|
38184
38408
|
for (const entry of entries) {
|
|
38185
|
-
if (entry.isDirectory() && entry.name
|
|
38186
|
-
const skillPath =
|
|
38409
|
+
if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
|
|
38410
|
+
const skillPath = join51(skillsDir, entry.name);
|
|
38187
38411
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
38188
38412
|
skills.push({
|
|
38189
38413
|
name: entry.name,
|
|
@@ -38192,14 +38416,14 @@ class SkillsManifestManager {
|
|
|
38192
38416
|
}
|
|
38193
38417
|
}
|
|
38194
38418
|
} else {
|
|
38195
|
-
const categories = await
|
|
38419
|
+
const categories = await readdir15(skillsDir, { withFileTypes: true });
|
|
38196
38420
|
for (const category of categories) {
|
|
38197
|
-
if (category.isDirectory() && category.name
|
|
38198
|
-
const categoryPath =
|
|
38199
|
-
const skillEntries = await
|
|
38421
|
+
if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
|
|
38422
|
+
const categoryPath = join51(skillsDir, category.name);
|
|
38423
|
+
const skillEntries = await readdir15(categoryPath, { withFileTypes: true });
|
|
38200
38424
|
for (const skillEntry of skillEntries) {
|
|
38201
38425
|
if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
|
|
38202
|
-
const skillPath =
|
|
38426
|
+
const skillPath = join51(categoryPath, skillEntry.name);
|
|
38203
38427
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
38204
38428
|
skills.push({
|
|
38205
38429
|
name: skillEntry.name,
|
|
@@ -38219,7 +38443,7 @@ class SkillsManifestManager {
|
|
|
38219
38443
|
files.sort();
|
|
38220
38444
|
for (const file of files) {
|
|
38221
38445
|
const relativePath = relative9(dirPath, file);
|
|
38222
|
-
const content = await
|
|
38446
|
+
const content = await readFile18(file);
|
|
38223
38447
|
hash.update(relativePath);
|
|
38224
38448
|
hash.update(content);
|
|
38225
38449
|
}
|
|
@@ -38227,10 +38451,10 @@ class SkillsManifestManager {
|
|
|
38227
38451
|
}
|
|
38228
38452
|
static async getAllFiles(dirPath) {
|
|
38229
38453
|
const files = [];
|
|
38230
|
-
const entries = await
|
|
38454
|
+
const entries = await readdir15(dirPath, { withFileTypes: true });
|
|
38231
38455
|
for (const entry of entries) {
|
|
38232
|
-
const fullPath =
|
|
38233
|
-
if (entry.name.startsWith(".") || entry.name
|
|
38456
|
+
const fullPath = join51(dirPath, entry.name);
|
|
38457
|
+
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name)) {
|
|
38234
38458
|
continue;
|
|
38235
38459
|
}
|
|
38236
38460
|
if (entry.isDirectory()) {
|
|
@@ -38350,13 +38574,13 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
|
|
|
38350
38574
|
|
|
38351
38575
|
// src/domains/skills/detection/script-detector.ts
|
|
38352
38576
|
var import_fs_extra18 = __toESM(require_lib(), 1);
|
|
38353
|
-
import { readdir as
|
|
38354
|
-
import { join as
|
|
38577
|
+
import { readdir as readdir16 } from "node:fs/promises";
|
|
38578
|
+
import { join as join52 } from "node:path";
|
|
38355
38579
|
async function scanDirectory(skillsDir) {
|
|
38356
38580
|
if (!await import_fs_extra18.pathExists(skillsDir)) {
|
|
38357
38581
|
return ["flat", []];
|
|
38358
38582
|
}
|
|
38359
|
-
const entries = await
|
|
38583
|
+
const entries = await readdir16(skillsDir, { withFileTypes: true });
|
|
38360
38584
|
const dirs = entries.filter((entry) => entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith("."));
|
|
38361
38585
|
if (dirs.length === 0) {
|
|
38362
38586
|
return ["flat", []];
|
|
@@ -38364,13 +38588,13 @@ async function scanDirectory(skillsDir) {
|
|
|
38364
38588
|
let totalSkillLikeCount = 0;
|
|
38365
38589
|
const allSkills = [];
|
|
38366
38590
|
for (const dir of dirs) {
|
|
38367
|
-
const dirPath =
|
|
38368
|
-
const subEntries = await
|
|
38591
|
+
const dirPath = join52(skillsDir, dir.name);
|
|
38592
|
+
const subEntries = await readdir16(dirPath, { withFileTypes: true });
|
|
38369
38593
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
38370
38594
|
if (subdirs.length > 0) {
|
|
38371
38595
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
38372
|
-
const subdirPath =
|
|
38373
|
-
const subdirFiles = await
|
|
38596
|
+
const subdirPath = join52(dirPath, subdir.name);
|
|
38597
|
+
const subdirFiles = await readdir16(subdirPath, { withFileTypes: true });
|
|
38374
38598
|
const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
|
|
38375
38599
|
if (hasSkillMarker) {
|
|
38376
38600
|
totalSkillLikeCount++;
|
|
@@ -38526,12 +38750,12 @@ class SkillsMigrationDetector {
|
|
|
38526
38750
|
// src/domains/skills/skills-migrator.ts
|
|
38527
38751
|
init_logger();
|
|
38528
38752
|
init_types2();
|
|
38529
|
-
import { join as
|
|
38753
|
+
import { join as join57 } from "node:path";
|
|
38530
38754
|
|
|
38531
38755
|
// src/domains/skills/migrator/migration-executor.ts
|
|
38532
38756
|
init_logger();
|
|
38533
|
-
import { copyFile as copyFile4, mkdir as mkdir17, readdir as
|
|
38534
|
-
import { join as
|
|
38757
|
+
import { copyFile as copyFile4, mkdir as mkdir17, readdir as readdir17, rm as rm3 } from "node:fs/promises";
|
|
38758
|
+
import { join as join53 } from "node:path";
|
|
38535
38759
|
var import_fs_extra20 = __toESM(require_lib(), 1);
|
|
38536
38760
|
|
|
38537
38761
|
// src/domains/skills/skills-migration-prompts.ts
|
|
@@ -38694,10 +38918,10 @@ Detected changes:`;
|
|
|
38694
38918
|
// src/domains/skills/migrator/migration-executor.ts
|
|
38695
38919
|
async function copySkillDirectory(sourceDir, destDir) {
|
|
38696
38920
|
await mkdir17(destDir, { recursive: true });
|
|
38697
|
-
const entries = await
|
|
38921
|
+
const entries = await readdir17(sourceDir, { withFileTypes: true });
|
|
38698
38922
|
for (const entry of entries) {
|
|
38699
|
-
const sourcePath =
|
|
38700
|
-
const destPath =
|
|
38923
|
+
const sourcePath = join53(sourceDir, entry.name);
|
|
38924
|
+
const destPath = join53(destDir, entry.name);
|
|
38701
38925
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
38702
38926
|
continue;
|
|
38703
38927
|
}
|
|
@@ -38712,7 +38936,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
38712
38936
|
const migrated = [];
|
|
38713
38937
|
const preserved = [];
|
|
38714
38938
|
const errors2 = [];
|
|
38715
|
-
const tempDir =
|
|
38939
|
+
const tempDir = join53(currentSkillsDir, "..", ".skills-migration-temp");
|
|
38716
38940
|
await mkdir17(tempDir, { recursive: true });
|
|
38717
38941
|
try {
|
|
38718
38942
|
for (const mapping of mappings) {
|
|
@@ -38733,9 +38957,9 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
38733
38957
|
}
|
|
38734
38958
|
}
|
|
38735
38959
|
const category = mapping.category;
|
|
38736
|
-
const targetPath = category ?
|
|
38960
|
+
const targetPath = category ? join53(tempDir, category, skillName) : join53(tempDir, skillName);
|
|
38737
38961
|
if (category) {
|
|
38738
|
-
await mkdir17(
|
|
38962
|
+
await mkdir17(join53(tempDir, category), { recursive: true });
|
|
38739
38963
|
}
|
|
38740
38964
|
await copySkillDirectory(currentSkillPath, targetPath);
|
|
38741
38965
|
migrated.push(skillName);
|
|
@@ -38801,8 +39025,8 @@ function validateMigrationPath(path11, paramName) {
|
|
|
38801
39025
|
init_logger();
|
|
38802
39026
|
init_types2();
|
|
38803
39027
|
var import_fs_extra21 = __toESM(require_lib(), 1);
|
|
38804
|
-
import { copyFile as copyFile5, mkdir as mkdir18, readdir as
|
|
38805
|
-
import { basename as basename2, join as
|
|
39028
|
+
import { copyFile as copyFile5, mkdir as mkdir18, readdir as readdir18, rm as rm4, stat as stat9 } from "node:fs/promises";
|
|
39029
|
+
import { basename as basename2, join as join54, normalize as normalize6 } from "node:path";
|
|
38806
39030
|
function validatePath2(path11, paramName) {
|
|
38807
39031
|
if (!path11 || typeof path11 !== "string") {
|
|
38808
39032
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -38828,7 +39052,7 @@ class SkillsBackupManager {
|
|
|
38828
39052
|
const timestamp = Date.now();
|
|
38829
39053
|
const randomSuffix = Math.random().toString(36).substring(2, 8);
|
|
38830
39054
|
const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
|
|
38831
|
-
const backupDir = parentDir ?
|
|
39055
|
+
const backupDir = parentDir ? join54(parentDir, backupDirName) : join54(skillsDir, "..", backupDirName);
|
|
38832
39056
|
logger.info(`Creating backup at: ${backupDir}`);
|
|
38833
39057
|
try {
|
|
38834
39058
|
await mkdir18(backupDir, { recursive: true });
|
|
@@ -38878,8 +39102,8 @@ class SkillsBackupManager {
|
|
|
38878
39102
|
return [];
|
|
38879
39103
|
}
|
|
38880
39104
|
try {
|
|
38881
|
-
const entries = await
|
|
38882
|
-
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) =>
|
|
39105
|
+
const entries = await readdir18(parentDir, { withFileTypes: true });
|
|
39106
|
+
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join54(parentDir, entry.name));
|
|
38883
39107
|
backups.sort().reverse();
|
|
38884
39108
|
return backups;
|
|
38885
39109
|
} catch (error) {
|
|
@@ -38905,10 +39129,10 @@ class SkillsBackupManager {
|
|
|
38905
39129
|
return await SkillsBackupManager.getDirectorySize(backupDir);
|
|
38906
39130
|
}
|
|
38907
39131
|
static async copyDirectory(sourceDir, destDir) {
|
|
38908
|
-
const entries = await
|
|
39132
|
+
const entries = await readdir18(sourceDir, { withFileTypes: true });
|
|
38909
39133
|
for (const entry of entries) {
|
|
38910
|
-
const sourcePath =
|
|
38911
|
-
const destPath =
|
|
39134
|
+
const sourcePath = join54(sourceDir, entry.name);
|
|
39135
|
+
const destPath = join54(destDir, entry.name);
|
|
38912
39136
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
38913
39137
|
continue;
|
|
38914
39138
|
}
|
|
@@ -38922,9 +39146,9 @@ class SkillsBackupManager {
|
|
|
38922
39146
|
}
|
|
38923
39147
|
static async getDirectorySize(dirPath) {
|
|
38924
39148
|
let size = 0;
|
|
38925
|
-
const entries = await
|
|
39149
|
+
const entries = await readdir18(dirPath, { withFileTypes: true });
|
|
38926
39150
|
for (const entry of entries) {
|
|
38927
|
-
const fullPath =
|
|
39151
|
+
const fullPath = join54(dirPath, entry.name);
|
|
38928
39152
|
if (entry.isSymbolicLink()) {
|
|
38929
39153
|
continue;
|
|
38930
39154
|
}
|
|
@@ -38958,14 +39182,14 @@ import { relative as relative11 } from "node:path";
|
|
|
38958
39182
|
// src/domains/skills/customization/hash-calculator.ts
|
|
38959
39183
|
import { createHash as createHash3 } from "node:crypto";
|
|
38960
39184
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
38961
|
-
import { readFile as
|
|
38962
|
-
import { join as
|
|
39185
|
+
import { readFile as readFile19, readdir as readdir19 } from "node:fs/promises";
|
|
39186
|
+
import { join as join55, relative as relative10 } from "node:path";
|
|
38963
39187
|
async function getAllFiles(dirPath) {
|
|
38964
39188
|
const files = [];
|
|
38965
|
-
const entries = await
|
|
39189
|
+
const entries = await readdir19(dirPath, { withFileTypes: true });
|
|
38966
39190
|
for (const entry of entries) {
|
|
38967
|
-
const fullPath =
|
|
38968
|
-
if (entry.name.startsWith(".") || entry.name
|
|
39191
|
+
const fullPath = join55(dirPath, entry.name);
|
|
39192
|
+
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name) || entry.isSymbolicLink()) {
|
|
38969
39193
|
continue;
|
|
38970
39194
|
}
|
|
38971
39195
|
if (entry.isDirectory()) {
|
|
@@ -38978,12 +39202,12 @@ async function getAllFiles(dirPath) {
|
|
|
38978
39202
|
return files;
|
|
38979
39203
|
}
|
|
38980
39204
|
async function hashFile(filePath) {
|
|
38981
|
-
return new Promise((
|
|
39205
|
+
return new Promise((resolve7, reject) => {
|
|
38982
39206
|
const hash = createHash3("sha256");
|
|
38983
39207
|
const stream = createReadStream2(filePath);
|
|
38984
39208
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
38985
39209
|
stream.on("end", () => {
|
|
38986
|
-
|
|
39210
|
+
resolve7(hash.digest("hex"));
|
|
38987
39211
|
});
|
|
38988
39212
|
stream.on("error", (error) => {
|
|
38989
39213
|
stream.destroy();
|
|
@@ -38997,7 +39221,7 @@ async function hashDirectory(dirPath) {
|
|
|
38997
39221
|
files.sort();
|
|
38998
39222
|
for (const file of files) {
|
|
38999
39223
|
const relativePath = relative10(dirPath, file);
|
|
39000
|
-
const content = await
|
|
39224
|
+
const content = await readFile19(file);
|
|
39001
39225
|
hash.update(relativePath);
|
|
39002
39226
|
hash.update(content);
|
|
39003
39227
|
}
|
|
@@ -39090,8 +39314,8 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
|
|
|
39090
39314
|
// src/domains/skills/customization/scan-reporter.ts
|
|
39091
39315
|
init_types2();
|
|
39092
39316
|
var import_fs_extra23 = __toESM(require_lib(), 1);
|
|
39093
|
-
import { readdir as
|
|
39094
|
-
import { join as
|
|
39317
|
+
import { readdir as readdir20 } from "node:fs/promises";
|
|
39318
|
+
import { join as join56, normalize as normalize7 } from "node:path";
|
|
39095
39319
|
function validatePath3(path11, paramName) {
|
|
39096
39320
|
if (!path11 || typeof path11 !== "string") {
|
|
39097
39321
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -39107,19 +39331,19 @@ async function scanSkillsDirectory(skillsDir) {
|
|
|
39107
39331
|
if (!await import_fs_extra23.pathExists(skillsDir)) {
|
|
39108
39332
|
return ["flat", []];
|
|
39109
39333
|
}
|
|
39110
|
-
const entries = await
|
|
39334
|
+
const entries = await readdir20(skillsDir, { withFileTypes: true });
|
|
39111
39335
|
const dirs = entries.filter((entry) => entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith("."));
|
|
39112
39336
|
if (dirs.length === 0) {
|
|
39113
39337
|
return ["flat", []];
|
|
39114
39338
|
}
|
|
39115
|
-
const firstDirPath =
|
|
39116
|
-
const subEntries = await
|
|
39339
|
+
const firstDirPath = join56(skillsDir, dirs[0].name);
|
|
39340
|
+
const subEntries = await readdir20(firstDirPath, { withFileTypes: true });
|
|
39117
39341
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
39118
39342
|
if (subdirs.length > 0) {
|
|
39119
39343
|
let skillLikeCount = 0;
|
|
39120
39344
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
39121
|
-
const subdirPath =
|
|
39122
|
-
const subdirFiles = await
|
|
39345
|
+
const subdirPath = join56(firstDirPath, subdir.name);
|
|
39346
|
+
const subdirFiles = await readdir20(subdirPath, { withFileTypes: true });
|
|
39123
39347
|
const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
|
|
39124
39348
|
if (hasSkillMarker) {
|
|
39125
39349
|
skillLikeCount++;
|
|
@@ -39128,8 +39352,8 @@ async function scanSkillsDirectory(skillsDir) {
|
|
|
39128
39352
|
if (skillLikeCount > 0) {
|
|
39129
39353
|
const skills = [];
|
|
39130
39354
|
for (const dir of dirs) {
|
|
39131
|
-
const categoryPath =
|
|
39132
|
-
const skillDirs = await
|
|
39355
|
+
const categoryPath = join56(skillsDir, dir.name);
|
|
39356
|
+
const skillDirs = await readdir20(categoryPath, { withFileTypes: true });
|
|
39133
39357
|
skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
|
|
39134
39358
|
}
|
|
39135
39359
|
return ["categorized", skills];
|
|
@@ -39138,17 +39362,17 @@ async function scanSkillsDirectory(skillsDir) {
|
|
|
39138
39362
|
return ["flat", dirs.map((dir) => dir.name)];
|
|
39139
39363
|
}
|
|
39140
39364
|
async function findSkillPath(skillsDir, skillName) {
|
|
39141
|
-
const flatPath =
|
|
39365
|
+
const flatPath = join56(skillsDir, skillName);
|
|
39142
39366
|
if (await import_fs_extra23.pathExists(flatPath)) {
|
|
39143
39367
|
return { path: flatPath, category: undefined };
|
|
39144
39368
|
}
|
|
39145
|
-
const entries = await
|
|
39369
|
+
const entries = await readdir20(skillsDir, { withFileTypes: true });
|
|
39146
39370
|
for (const entry of entries) {
|
|
39147
39371
|
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
39148
39372
|
continue;
|
|
39149
39373
|
}
|
|
39150
|
-
const categoryPath =
|
|
39151
|
-
const skillPath =
|
|
39374
|
+
const categoryPath = join56(skillsDir, entry.name);
|
|
39375
|
+
const skillPath = join56(categoryPath, skillName);
|
|
39152
39376
|
if (await import_fs_extra23.pathExists(skillPath)) {
|
|
39153
39377
|
return { path: skillPath, category: entry.name };
|
|
39154
39378
|
}
|
|
@@ -39242,7 +39466,7 @@ class SkillsMigrator {
|
|
|
39242
39466
|
}
|
|
39243
39467
|
}
|
|
39244
39468
|
if (options.backup && !options.dryRun) {
|
|
39245
|
-
const claudeDir =
|
|
39469
|
+
const claudeDir = join57(currentSkillsDir, "..");
|
|
39246
39470
|
result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir);
|
|
39247
39471
|
logger.success(`Backup created at: ${result.backupPath}`);
|
|
39248
39472
|
}
|
|
@@ -39302,7 +39526,7 @@ async function handleMigration(ctx) {
|
|
|
39302
39526
|
logger.debug("Skipping skills migration (fresh installation)");
|
|
39303
39527
|
return ctx;
|
|
39304
39528
|
}
|
|
39305
|
-
const newSkillsDir =
|
|
39529
|
+
const newSkillsDir = join58(ctx.extractDir, ".claude", "skills");
|
|
39306
39530
|
const currentSkillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
|
|
39307
39531
|
if (!await import_fs_extra24.pathExists(newSkillsDir) || !await import_fs_extra24.pathExists(currentSkillsDir)) {
|
|
39308
39532
|
return ctx;
|
|
@@ -39327,10 +39551,10 @@ async function handleMigration(ctx) {
|
|
|
39327
39551
|
// src/domains/config/config-manager.ts
|
|
39328
39552
|
init_logger();
|
|
39329
39553
|
import { existsSync as existsSync18 } from "node:fs";
|
|
39330
|
-
import { mkdir as mkdir19, readFile as
|
|
39554
|
+
import { mkdir as mkdir19, readFile as readFile20, rename as rename2, rm as rm5, writeFile as writeFile16 } from "node:fs/promises";
|
|
39331
39555
|
import { chmod as chmod2 } from "node:fs/promises";
|
|
39332
39556
|
import { platform as platform10 } from "node:os";
|
|
39333
|
-
import { join as
|
|
39557
|
+
import { join as join59 } from "node:path";
|
|
39334
39558
|
init_types2();
|
|
39335
39559
|
var PROJECT_CONFIG_FILE = ".ck.json";
|
|
39336
39560
|
|
|
@@ -39338,7 +39562,7 @@ class ConfigManager {
|
|
|
39338
39562
|
static config = null;
|
|
39339
39563
|
static globalFlag = false;
|
|
39340
39564
|
static getProjectConfigDir(projectDir, global3) {
|
|
39341
|
-
return global3 ? projectDir :
|
|
39565
|
+
return global3 ? projectDir : join59(projectDir, ".claude");
|
|
39342
39566
|
}
|
|
39343
39567
|
static setGlobalFlag(global3) {
|
|
39344
39568
|
ConfigManager.globalFlag = global3;
|
|
@@ -39354,7 +39578,7 @@ class ConfigManager {
|
|
|
39354
39578
|
const configFile = PathResolver.getConfigFile(ConfigManager.globalFlag);
|
|
39355
39579
|
try {
|
|
39356
39580
|
if (existsSync18(configFile)) {
|
|
39357
|
-
const content = await
|
|
39581
|
+
const content = await readFile20(configFile, "utf-8");
|
|
39358
39582
|
const data = JSON.parse(content);
|
|
39359
39583
|
ConfigManager.config = ConfigSchema.parse(data);
|
|
39360
39584
|
logger.debug(`Config loaded from ${configFile}`);
|
|
@@ -39377,7 +39601,7 @@ class ConfigManager {
|
|
|
39377
39601
|
await chmod2(configDir, 448);
|
|
39378
39602
|
}
|
|
39379
39603
|
}
|
|
39380
|
-
await
|
|
39604
|
+
await writeFile16(configFile, JSON.stringify(validConfig, null, 2), "utf-8");
|
|
39381
39605
|
if (platform10() !== "win32") {
|
|
39382
39606
|
await chmod2(configFile, 384);
|
|
39383
39607
|
}
|
|
@@ -39405,10 +39629,10 @@ class ConfigManager {
|
|
|
39405
39629
|
}
|
|
39406
39630
|
static async loadProjectConfig(projectDir, global3 = false) {
|
|
39407
39631
|
const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
|
|
39408
|
-
const configPath =
|
|
39632
|
+
const configPath = join59(configDir, PROJECT_CONFIG_FILE);
|
|
39409
39633
|
try {
|
|
39410
39634
|
if (existsSync18(configPath)) {
|
|
39411
|
-
const content = await
|
|
39635
|
+
const content = await readFile20(configPath, "utf-8");
|
|
39412
39636
|
const data = JSON.parse(content);
|
|
39413
39637
|
const folders = FoldersConfigSchema.parse(data.paths || data);
|
|
39414
39638
|
logger.debug(`Project config loaded from ${configPath}`);
|
|
@@ -39421,7 +39645,7 @@ class ConfigManager {
|
|
|
39421
39645
|
}
|
|
39422
39646
|
static async saveProjectConfig(projectDir, folders, global3 = false) {
|
|
39423
39647
|
const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
|
|
39424
|
-
const configPath =
|
|
39648
|
+
const configPath = join59(configDir, PROJECT_CONFIG_FILE);
|
|
39425
39649
|
try {
|
|
39426
39650
|
if (!existsSync18(configDir)) {
|
|
39427
39651
|
await mkdir19(configDir, { recursive: true });
|
|
@@ -39429,7 +39653,7 @@ class ConfigManager {
|
|
|
39429
39653
|
let existingConfig = {};
|
|
39430
39654
|
if (existsSync18(configPath)) {
|
|
39431
39655
|
try {
|
|
39432
|
-
const content = await
|
|
39656
|
+
const content = await readFile20(configPath, "utf-8");
|
|
39433
39657
|
existingConfig = JSON.parse(content);
|
|
39434
39658
|
} catch (error) {
|
|
39435
39659
|
logger.debug(`Could not parse existing config, starting fresh: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
@@ -39444,7 +39668,7 @@ class ConfigManager {
|
|
|
39444
39668
|
...validFolders
|
|
39445
39669
|
}
|
|
39446
39670
|
};
|
|
39447
|
-
await
|
|
39671
|
+
await writeFile16(configPath, JSON.stringify(mergedConfig, null, 2), "utf-8");
|
|
39448
39672
|
logger.debug(`Project config saved to ${configPath}`);
|
|
39449
39673
|
} catch (error) {
|
|
39450
39674
|
throw new Error(`Failed to save project config: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
@@ -39470,11 +39694,11 @@ class ConfigManager {
|
|
|
39470
39694
|
}
|
|
39471
39695
|
static projectConfigExists(projectDir, global3 = false) {
|
|
39472
39696
|
const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
|
|
39473
|
-
return existsSync18(
|
|
39697
|
+
return existsSync18(join59(configDir, PROJECT_CONFIG_FILE));
|
|
39474
39698
|
}
|
|
39475
39699
|
static async migrateNestedConfig(globalDir) {
|
|
39476
|
-
const correctPath =
|
|
39477
|
-
const incorrectPath =
|
|
39700
|
+
const correctPath = join59(globalDir, PROJECT_CONFIG_FILE);
|
|
39701
|
+
const incorrectPath = join59(globalDir, ".claude", PROJECT_CONFIG_FILE);
|
|
39478
39702
|
if (existsSync18(correctPath)) {
|
|
39479
39703
|
logger.debug("Config already exists at correct location, skipping migration");
|
|
39480
39704
|
return false;
|
|
@@ -39484,7 +39708,7 @@ class ConfigManager {
|
|
|
39484
39708
|
logger.info("Migrating .ck.json from nested location to correct location...");
|
|
39485
39709
|
await rename2(incorrectPath, correctPath);
|
|
39486
39710
|
logger.success(`Migrated ${PROJECT_CONFIG_FILE} to ${correctPath}`);
|
|
39487
|
-
const nestedClaudeDir =
|
|
39711
|
+
const nestedClaudeDir = join59(globalDir, ".claude");
|
|
39488
39712
|
try {
|
|
39489
39713
|
await rm5(nestedClaudeDir, { recursive: false });
|
|
39490
39714
|
logger.debug("Removed empty nested .claude directory");
|
|
@@ -39575,14 +39799,14 @@ Please use only one download method.`);
|
|
|
39575
39799
|
};
|
|
39576
39800
|
}
|
|
39577
39801
|
// src/commands/init/phases/post-install-handler.ts
|
|
39578
|
-
import { join as
|
|
39802
|
+
import { join as join62 } from "node:path";
|
|
39579
39803
|
|
|
39580
39804
|
// src/domains/installation/setup-wizard.ts
|
|
39581
|
-
import { join as
|
|
39805
|
+
import { join as join61 } from "node:path";
|
|
39582
39806
|
|
|
39583
39807
|
// src/domains/config/config-generator.ts
|
|
39584
39808
|
var import_fs_extra25 = __toESM(require_lib(), 1);
|
|
39585
|
-
import { join as
|
|
39809
|
+
import { join as join60 } from "node:path";
|
|
39586
39810
|
async function generateEnvFile(targetDir, values) {
|
|
39587
39811
|
const lines = [
|
|
39588
39812
|
"# Generated by ClaudeKit CLI setup wizard",
|
|
@@ -39624,7 +39848,7 @@ async function generateEnvFile(targetDir, values) {
|
|
|
39624
39848
|
for (const [key, value] of otherValues) {
|
|
39625
39849
|
lines.push(`${key}=${value}`);
|
|
39626
39850
|
}
|
|
39627
|
-
const envPath =
|
|
39851
|
+
const envPath = join60(targetDir, ".env");
|
|
39628
39852
|
await import_fs_extra25.writeFile(envPath, `${lines.join(`
|
|
39629
39853
|
`)}
|
|
39630
39854
|
`, { mode: 384 });
|
|
@@ -39698,7 +39922,7 @@ async function parseEnvFile(path11) {
|
|
|
39698
39922
|
}
|
|
39699
39923
|
}
|
|
39700
39924
|
async function checkGlobalConfig() {
|
|
39701
|
-
const globalEnvPath =
|
|
39925
|
+
const globalEnvPath = join61(PathResolver.getGlobalKitDir(), ".env");
|
|
39702
39926
|
if (!await import_fs_extra26.pathExists(globalEnvPath))
|
|
39703
39927
|
return false;
|
|
39704
39928
|
const env2 = await parseEnvFile(globalEnvPath);
|
|
@@ -39714,7 +39938,7 @@ async function runSetupWizard(options) {
|
|
|
39714
39938
|
let globalEnv = {};
|
|
39715
39939
|
const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
|
|
39716
39940
|
if (!isGlobal) {
|
|
39717
|
-
const globalEnvPath =
|
|
39941
|
+
const globalEnvPath = join61(PathResolver.getGlobalKitDir(), ".env");
|
|
39718
39942
|
if (await import_fs_extra26.pathExists(globalEnvPath)) {
|
|
39719
39943
|
globalEnv = await parseEnvFile(globalEnvPath);
|
|
39720
39944
|
}
|
|
@@ -39777,7 +40001,7 @@ async function runSetupWizard(options) {
|
|
|
39777
40001
|
}
|
|
39778
40002
|
}
|
|
39779
40003
|
await generateEnvFile(targetDir, values);
|
|
39780
|
-
f2.success(`Configuration saved to ${
|
|
40004
|
+
f2.success(`Configuration saved to ${join61(targetDir, ".env")}`);
|
|
39781
40005
|
return true;
|
|
39782
40006
|
}
|
|
39783
40007
|
async function promptForAdditionalGeminiKeys(primaryKey) {
|
|
@@ -39833,8 +40057,8 @@ async function handlePostInstall(ctx) {
|
|
|
39833
40057
|
return ctx;
|
|
39834
40058
|
}
|
|
39835
40059
|
if (ctx.options.global) {
|
|
39836
|
-
const claudeMdSource =
|
|
39837
|
-
const claudeMdDest =
|
|
40060
|
+
const claudeMdSource = join62(ctx.extractDir, "CLAUDE.md");
|
|
40061
|
+
const claudeMdDest = join62(ctx.resolvedDir, "CLAUDE.md");
|
|
39838
40062
|
if (await import_fs_extra27.pathExists(claudeMdSource)) {
|
|
39839
40063
|
if (!await import_fs_extra27.pathExists(claudeMdDest)) {
|
|
39840
40064
|
await import_fs_extra27.copy(claudeMdSource, claudeMdDest);
|
|
@@ -39881,7 +40105,7 @@ async function handlePostInstall(ctx) {
|
|
|
39881
40105
|
}
|
|
39882
40106
|
}
|
|
39883
40107
|
if (!ctx.options.skipSetup && !ctx.isNonInteractive) {
|
|
39884
|
-
const envPath =
|
|
40108
|
+
const envPath = join62(ctx.claudeDir, ".env");
|
|
39885
40109
|
if (!await import_fs_extra27.pathExists(envPath)) {
|
|
39886
40110
|
const shouldSetup = await ctx.prompts.confirm("Set up API keys now? (Gemini API key for ai-multimodal skill, optional webhooks)");
|
|
39887
40111
|
if (shouldSetup) {
|
|
@@ -39903,7 +40127,7 @@ Optional: DISCORD_WEBHOOK_URL, TELEGRAM_BOT_TOKEN`, "Configuration skipped");
|
|
|
39903
40127
|
}
|
|
39904
40128
|
// src/commands/init/phases/selection-handler.ts
|
|
39905
40129
|
import { mkdir as mkdir20 } from "node:fs/promises";
|
|
39906
|
-
import { join as
|
|
40130
|
+
import { join as join64, resolve as resolve7 } from "node:path";
|
|
39907
40131
|
|
|
39908
40132
|
// src/domains/github/kit-access-checker.ts
|
|
39909
40133
|
init_logger();
|
|
@@ -39932,7 +40156,7 @@ async function detectAccessibleKits() {
|
|
|
39932
40156
|
|
|
39933
40157
|
// src/domains/installation/fresh-installer.ts
|
|
39934
40158
|
init_logger();
|
|
39935
|
-
import { join as
|
|
40159
|
+
import { join as join63 } from "node:path";
|
|
39936
40160
|
var import_fs_extra28 = __toESM(require_lib(), 1);
|
|
39937
40161
|
var CLAUDEKIT_SUBDIRECTORIES = ["commands", "agents", "skills", "workflows", "hooks"];
|
|
39938
40162
|
async function handleFreshInstallation(claudeDir, prompts) {
|
|
@@ -39951,7 +40175,7 @@ async function handleFreshInstallation(claudeDir, prompts) {
|
|
|
39951
40175
|
const { rmSync } = await import("node:fs");
|
|
39952
40176
|
let removedCount = 0;
|
|
39953
40177
|
for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
|
|
39954
|
-
const subdirPath =
|
|
40178
|
+
const subdirPath = join63(claudeDir, subdir);
|
|
39955
40179
|
if (await import_fs_extra28.pathExists(subdirPath)) {
|
|
39956
40180
|
rmSync(subdirPath, { recursive: true, force: true });
|
|
39957
40181
|
removedCount++;
|
|
@@ -40111,8 +40335,28 @@ async function handleSelection(ctx) {
|
|
|
40111
40335
|
}
|
|
40112
40336
|
}
|
|
40113
40337
|
}
|
|
40114
|
-
const resolvedDir =
|
|
40338
|
+
const resolvedDir = resolve7(targetDir);
|
|
40115
40339
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
40340
|
+
if (!ctx.options.global && PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
40341
|
+
logger.warning("You're at HOME directory. Installing here modifies your GLOBAL ClaudeKit.");
|
|
40342
|
+
if (!ctx.isNonInteractive) {
|
|
40343
|
+
const choice = await ctx.prompts.selectScope();
|
|
40344
|
+
if (choice === "cancel") {
|
|
40345
|
+
return { ...ctx, cancelled: true };
|
|
40346
|
+
}
|
|
40347
|
+
if (choice === "global") {
|
|
40348
|
+
logger.info("Proceeding with global installation");
|
|
40349
|
+
}
|
|
40350
|
+
if (choice === "different") {
|
|
40351
|
+
logger.info("Please run 'ck init' from a project directory instead.");
|
|
40352
|
+
return { ...ctx, cancelled: true };
|
|
40353
|
+
}
|
|
40354
|
+
} else {
|
|
40355
|
+
logger.error("Cannot use local installation at HOME directory.");
|
|
40356
|
+
logger.info("Use -g/--global flag or run from a project directory.");
|
|
40357
|
+
return { ...ctx, cancelled: true };
|
|
40358
|
+
}
|
|
40359
|
+
}
|
|
40116
40360
|
if (!await import_fs_extra29.pathExists(resolvedDir)) {
|
|
40117
40361
|
if (ctx.options.global) {
|
|
40118
40362
|
await mkdir20(resolvedDir, { recursive: true });
|
|
@@ -40125,7 +40369,7 @@ async function handleSelection(ctx) {
|
|
|
40125
40369
|
}
|
|
40126
40370
|
if (!ctx.options.fresh) {
|
|
40127
40371
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
40128
|
-
const claudeDir = prefix ?
|
|
40372
|
+
const claudeDir = prefix ? join64(resolvedDir, prefix) : resolvedDir;
|
|
40129
40373
|
try {
|
|
40130
40374
|
const existingMetadata = await readManifest(claudeDir);
|
|
40131
40375
|
if (existingMetadata?.kits) {
|
|
@@ -40157,7 +40401,7 @@ async function handleSelection(ctx) {
|
|
|
40157
40401
|
}
|
|
40158
40402
|
if (ctx.options.fresh) {
|
|
40159
40403
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
40160
|
-
const claudeDir = prefix ?
|
|
40404
|
+
const claudeDir = prefix ? join64(resolvedDir, prefix) : resolvedDir;
|
|
40161
40405
|
const canProceed = await handleFreshInstallation(claudeDir, ctx.prompts);
|
|
40162
40406
|
if (!canProceed) {
|
|
40163
40407
|
return { ...ctx, cancelled: true };
|
|
@@ -40175,7 +40419,7 @@ async function handleSelection(ctx) {
|
|
|
40175
40419
|
logger.info("Fetching available versions...");
|
|
40176
40420
|
let currentVersion = null;
|
|
40177
40421
|
try {
|
|
40178
|
-
const metadataPath = ctx.options.global ?
|
|
40422
|
+
const metadataPath = ctx.options.global ? join64(PathResolver.getGlobalKitDir(), "metadata.json") : join64(resolvedDir, ".claude", "metadata.json");
|
|
40179
40423
|
const metadata = await readClaudeKitMetadata(metadataPath);
|
|
40180
40424
|
currentVersion = metadata?.version || null;
|
|
40181
40425
|
if (currentVersion) {
|
|
@@ -40243,8 +40487,8 @@ async function handleSelection(ctx) {
|
|
|
40243
40487
|
};
|
|
40244
40488
|
}
|
|
40245
40489
|
// src/commands/init/phases/sync-handler.ts
|
|
40246
|
-
import { copyFile as copyFile6, mkdir as mkdir21, open, rename as rename3, stat as stat10, unlink as unlink7, writeFile as
|
|
40247
|
-
import { dirname as dirname9, join as
|
|
40490
|
+
import { copyFile as copyFile6, mkdir as mkdir21, open, rename as rename3, stat as stat10, unlink as unlink7, writeFile as writeFile18 } from "node:fs/promises";
|
|
40491
|
+
import { dirname as dirname9, join as join65, resolve as resolve8 } from "node:path";
|
|
40248
40492
|
init_logger();
|
|
40249
40493
|
var import_fs_extra30 = __toESM(require_lib(), 1);
|
|
40250
40494
|
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
@@ -40252,14 +40496,14 @@ async function handleSync(ctx) {
|
|
|
40252
40496
|
if (!ctx.options.sync) {
|
|
40253
40497
|
return ctx;
|
|
40254
40498
|
}
|
|
40255
|
-
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() :
|
|
40256
|
-
const claudeDir = ctx.options.global ? resolvedDir :
|
|
40499
|
+
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve8(ctx.options.dir || ".");
|
|
40500
|
+
const claudeDir = ctx.options.global ? resolvedDir : join65(resolvedDir, ".claude");
|
|
40257
40501
|
if (!await import_fs_extra30.pathExists(claudeDir)) {
|
|
40258
40502
|
logger.error("Cannot sync: no .claude directory found");
|
|
40259
40503
|
ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
|
|
40260
40504
|
return { ...ctx, cancelled: true };
|
|
40261
40505
|
}
|
|
40262
|
-
const metadataPath =
|
|
40506
|
+
const metadataPath = join65(claudeDir, "metadata.json");
|
|
40263
40507
|
if (!await import_fs_extra30.pathExists(metadataPath)) {
|
|
40264
40508
|
logger.error("Cannot sync: no metadata.json found");
|
|
40265
40509
|
ctx.prompts.note(`Your installation may be from an older version.
|
|
@@ -40359,7 +40603,7 @@ function getLockTimeout() {
|
|
|
40359
40603
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
40360
40604
|
async function acquireSyncLock(global3) {
|
|
40361
40605
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
40362
|
-
const lockPath =
|
|
40606
|
+
const lockPath = join65(cacheDir, ".sync-lock");
|
|
40363
40607
|
const startTime = Date.now();
|
|
40364
40608
|
const lockTimeout = getLockTimeout();
|
|
40365
40609
|
await mkdir21(dirname9(lockPath), { recursive: true });
|
|
@@ -40386,7 +40630,7 @@ async function acquireSyncLock(global3) {
|
|
|
40386
40630
|
}
|
|
40387
40631
|
logger.debug(`Lock stat failed: ${statError}`);
|
|
40388
40632
|
}
|
|
40389
|
-
await new Promise((
|
|
40633
|
+
await new Promise((resolve9) => setTimeout(resolve9, 100));
|
|
40390
40634
|
continue;
|
|
40391
40635
|
}
|
|
40392
40636
|
throw err;
|
|
@@ -40405,7 +40649,7 @@ async function executeSyncMerge(ctx) {
|
|
|
40405
40649
|
const releaseLock = await acquireSyncLock(ctx.options.global);
|
|
40406
40650
|
try {
|
|
40407
40651
|
const trackedFiles = ctx.syncTrackedFiles;
|
|
40408
|
-
const upstreamDir = ctx.options.global ?
|
|
40652
|
+
const upstreamDir = ctx.options.global ? join65(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
40409
40653
|
logger.info("Analyzing file changes...");
|
|
40410
40654
|
const plan = await SyncEngine.createSyncPlan(trackedFiles, ctx.claudeDir, upstreamDir);
|
|
40411
40655
|
displaySyncPlan(plan);
|
|
@@ -40424,7 +40668,7 @@ async function executeSyncMerge(ctx) {
|
|
|
40424
40668
|
try {
|
|
40425
40669
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
40426
40670
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
40427
|
-
const targetDir =
|
|
40671
|
+
const targetDir = join65(targetPath, "..");
|
|
40428
40672
|
try {
|
|
40429
40673
|
await mkdir21(targetDir, { recursive: true });
|
|
40430
40674
|
} catch (mkdirError) {
|
|
@@ -40505,7 +40749,7 @@ async function executeSyncMerge(ctx) {
|
|
|
40505
40749
|
try {
|
|
40506
40750
|
const tempPath = `${currentPath}.tmp.${Date.now()}`;
|
|
40507
40751
|
try {
|
|
40508
|
-
await
|
|
40752
|
+
await writeFile18(tempPath, result.result, "utf-8");
|
|
40509
40753
|
await rename3(tempPath, currentPath);
|
|
40510
40754
|
} catch (atomicError) {
|
|
40511
40755
|
await unlink7(tempPath).catch(() => {});
|
|
@@ -40595,7 +40839,7 @@ async function createBackup(claudeDir, files, backupDir) {
|
|
|
40595
40839
|
const sourcePath = await validateSyncPath(claudeDir, file.path);
|
|
40596
40840
|
if (await import_fs_extra30.pathExists(sourcePath)) {
|
|
40597
40841
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
40598
|
-
const targetDir =
|
|
40842
|
+
const targetDir = join65(targetPath, "..");
|
|
40599
40843
|
await mkdir21(targetDir, { recursive: true });
|
|
40600
40844
|
await copyFile6(sourcePath, targetPath);
|
|
40601
40845
|
}
|
|
@@ -40609,7 +40853,7 @@ async function createBackup(claudeDir, files, backupDir) {
|
|
|
40609
40853
|
}
|
|
40610
40854
|
}
|
|
40611
40855
|
// src/commands/init/phases/transform-handler.ts
|
|
40612
|
-
import { join as
|
|
40856
|
+
import { join as join69 } from "node:path";
|
|
40613
40857
|
|
|
40614
40858
|
// src/services/transformers/folder-path-transformer.ts
|
|
40615
40859
|
init_logger();
|
|
@@ -40620,38 +40864,38 @@ init_logger();
|
|
|
40620
40864
|
init_types2();
|
|
40621
40865
|
var import_fs_extra31 = __toESM(require_lib(), 1);
|
|
40622
40866
|
import { rename as rename4, rm as rm6 } from "node:fs/promises";
|
|
40623
|
-
import { join as
|
|
40867
|
+
import { join as join66, relative as relative12 } from "node:path";
|
|
40624
40868
|
async function collectDirsToRename(extractDir, folders) {
|
|
40625
40869
|
const dirsToRename = [];
|
|
40626
40870
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
40627
|
-
const docsPath =
|
|
40871
|
+
const docsPath = join66(extractDir, DEFAULT_FOLDERS.docs);
|
|
40628
40872
|
if (await import_fs_extra31.pathExists(docsPath)) {
|
|
40629
40873
|
dirsToRename.push({
|
|
40630
40874
|
from: docsPath,
|
|
40631
|
-
to:
|
|
40875
|
+
to: join66(extractDir, folders.docs)
|
|
40632
40876
|
});
|
|
40633
40877
|
}
|
|
40634
|
-
const claudeDocsPath =
|
|
40878
|
+
const claudeDocsPath = join66(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
40635
40879
|
if (await import_fs_extra31.pathExists(claudeDocsPath)) {
|
|
40636
40880
|
dirsToRename.push({
|
|
40637
40881
|
from: claudeDocsPath,
|
|
40638
|
-
to:
|
|
40882
|
+
to: join66(extractDir, ".claude", folders.docs)
|
|
40639
40883
|
});
|
|
40640
40884
|
}
|
|
40641
40885
|
}
|
|
40642
40886
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
40643
|
-
const plansPath =
|
|
40887
|
+
const plansPath = join66(extractDir, DEFAULT_FOLDERS.plans);
|
|
40644
40888
|
if (await import_fs_extra31.pathExists(plansPath)) {
|
|
40645
40889
|
dirsToRename.push({
|
|
40646
40890
|
from: plansPath,
|
|
40647
|
-
to:
|
|
40891
|
+
to: join66(extractDir, folders.plans)
|
|
40648
40892
|
});
|
|
40649
40893
|
}
|
|
40650
|
-
const claudePlansPath =
|
|
40894
|
+
const claudePlansPath = join66(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
40651
40895
|
if (await import_fs_extra31.pathExists(claudePlansPath)) {
|
|
40652
40896
|
dirsToRename.push({
|
|
40653
40897
|
from: claudePlansPath,
|
|
40654
|
-
to:
|
|
40898
|
+
to: join66(extractDir, ".claude", folders.plans)
|
|
40655
40899
|
});
|
|
40656
40900
|
}
|
|
40657
40901
|
}
|
|
@@ -40691,8 +40935,8 @@ async function renameFolders(dirsToRename, extractDir, options) {
|
|
|
40691
40935
|
// src/services/transformers/folder-transform/path-replacer.ts
|
|
40692
40936
|
init_logger();
|
|
40693
40937
|
init_types2();
|
|
40694
|
-
import { readFile as
|
|
40695
|
-
import { join as
|
|
40938
|
+
import { readFile as readFile22, readdir as readdir21, writeFile as writeFile19 } from "node:fs/promises";
|
|
40939
|
+
import { join as join67, relative as relative13 } from "node:path";
|
|
40696
40940
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
40697
40941
|
".md",
|
|
40698
40942
|
".txt",
|
|
@@ -40743,9 +40987,9 @@ function compileReplacements(replacements) {
|
|
|
40743
40987
|
async function transformFileContents(dir, compiledReplacements, options) {
|
|
40744
40988
|
let filesChanged = 0;
|
|
40745
40989
|
let replacementsCount = 0;
|
|
40746
|
-
const entries = await
|
|
40990
|
+
const entries = await readdir21(dir, { withFileTypes: true });
|
|
40747
40991
|
for (const entry of entries) {
|
|
40748
|
-
const fullPath =
|
|
40992
|
+
const fullPath = join67(dir, entry.name);
|
|
40749
40993
|
if (entry.isDirectory()) {
|
|
40750
40994
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
40751
40995
|
continue;
|
|
@@ -40758,7 +41002,7 @@ async function transformFileContents(dir, compiledReplacements, options) {
|
|
|
40758
41002
|
if (!shouldTransform)
|
|
40759
41003
|
continue;
|
|
40760
41004
|
try {
|
|
40761
|
-
const content = await
|
|
41005
|
+
const content = await readFile22(fullPath, "utf-8");
|
|
40762
41006
|
let newContent = content;
|
|
40763
41007
|
let changeCount = 0;
|
|
40764
41008
|
for (const { regex: regex2, replacement } of compiledReplacements) {
|
|
@@ -40774,7 +41018,7 @@ async function transformFileContents(dir, compiledReplacements, options) {
|
|
|
40774
41018
|
if (options.dryRun) {
|
|
40775
41019
|
logger.debug(`[dry-run] Would update ${relative13(dir, fullPath)}: ${changeCount} replacement(s)`);
|
|
40776
41020
|
} else {
|
|
40777
|
-
await
|
|
41021
|
+
await writeFile19(fullPath, newContent, "utf-8");
|
|
40778
41022
|
logger.debug(`Updated ${relative13(dir, fullPath)}: ${changeCount} replacement(s)`);
|
|
40779
41023
|
}
|
|
40780
41024
|
filesChanged++;
|
|
@@ -40880,15 +41124,15 @@ async function transformFolderPaths(extractDir, folders, options = {}) {
|
|
|
40880
41124
|
|
|
40881
41125
|
// src/services/transformers/global-path-transformer.ts
|
|
40882
41126
|
init_logger();
|
|
40883
|
-
import { readFile as
|
|
41127
|
+
import { readFile as readFile23, readdir as readdir22, writeFile as writeFile20 } from "node:fs/promises";
|
|
40884
41128
|
import { platform as platform11 } from "node:os";
|
|
40885
|
-
import { extname as extname2, join as
|
|
41129
|
+
import { extname as extname2, join as join68 } from "node:path";
|
|
40886
41130
|
var IS_WINDOWS3 = platform11() === "win32";
|
|
40887
41131
|
var HOME_PREFIX = IS_WINDOWS3 ? "%USERPROFILE%" : "$HOME";
|
|
40888
41132
|
function getHomeDirPrefix() {
|
|
40889
41133
|
return HOME_PREFIX;
|
|
40890
41134
|
}
|
|
40891
|
-
var
|
|
41135
|
+
var TRANSFORMABLE_EXTENSIONS2 = new Set([
|
|
40892
41136
|
".md",
|
|
40893
41137
|
".js",
|
|
40894
41138
|
".ts",
|
|
@@ -40979,10 +41223,10 @@ function transformContent(content) {
|
|
|
40979
41223
|
});
|
|
40980
41224
|
return { transformed, changes };
|
|
40981
41225
|
}
|
|
40982
|
-
function
|
|
41226
|
+
function shouldTransformFile2(filename) {
|
|
40983
41227
|
const ext2 = extname2(filename).toLowerCase();
|
|
40984
41228
|
const basename3 = filename.split("/").pop() || filename;
|
|
40985
|
-
return
|
|
41229
|
+
return TRANSFORMABLE_EXTENSIONS2.has(ext2) || ALWAYS_TRANSFORM_FILES.has(basename3);
|
|
40986
41230
|
}
|
|
40987
41231
|
async function transformPathsForGlobalInstall(directory, options = {}) {
|
|
40988
41232
|
let filesTransformed = 0;
|
|
@@ -40990,20 +41234,20 @@ async function transformPathsForGlobalInstall(directory, options = {}) {
|
|
|
40990
41234
|
let filesSkipped = 0;
|
|
40991
41235
|
const skippedFiles = [];
|
|
40992
41236
|
async function processDirectory2(dir) {
|
|
40993
|
-
const entries = await
|
|
41237
|
+
const entries = await readdir22(dir, { withFileTypes: true });
|
|
40994
41238
|
for (const entry of entries) {
|
|
40995
|
-
const fullPath =
|
|
41239
|
+
const fullPath = join68(dir, entry.name);
|
|
40996
41240
|
if (entry.isDirectory()) {
|
|
40997
41241
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
40998
41242
|
continue;
|
|
40999
41243
|
}
|
|
41000
41244
|
await processDirectory2(fullPath);
|
|
41001
|
-
} else if (entry.isFile() &&
|
|
41245
|
+
} else if (entry.isFile() && shouldTransformFile2(entry.name)) {
|
|
41002
41246
|
try {
|
|
41003
|
-
const content = await
|
|
41247
|
+
const content = await readFile23(fullPath, "utf-8");
|
|
41004
41248
|
const { transformed, changes } = transformContent(content);
|
|
41005
41249
|
if (changes > 0) {
|
|
41006
|
-
await
|
|
41250
|
+
await writeFile20(fullPath, transformed, "utf-8");
|
|
41007
41251
|
filesTransformed++;
|
|
41008
41252
|
totalChanges += changes;
|
|
41009
41253
|
if (options.verbose) {
|
|
@@ -41068,7 +41312,7 @@ async function handleTransforms(ctx) {
|
|
|
41068
41312
|
logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
|
|
41069
41313
|
}
|
|
41070
41314
|
}
|
|
41071
|
-
const claudeDir = ctx.options.global ? ctx.resolvedDir :
|
|
41315
|
+
const claudeDir = ctx.options.global ? ctx.resolvedDir : join69(ctx.resolvedDir, ".claude");
|
|
41072
41316
|
return {
|
|
41073
41317
|
...ctx,
|
|
41074
41318
|
foldersConfig,
|
|
@@ -41250,7 +41494,7 @@ init_types2();
|
|
|
41250
41494
|
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
41251
41495
|
|
|
41252
41496
|
// src/commands/new/phases/directory-setup.ts
|
|
41253
|
-
import { resolve as
|
|
41497
|
+
import { resolve as resolve9 } from "node:path";
|
|
41254
41498
|
init_logger();
|
|
41255
41499
|
init_types2();
|
|
41256
41500
|
var import_fs_extra32 = __toESM(require_lib(), 1);
|
|
@@ -41334,8 +41578,24 @@ async function directorySetup(validOptions, prompts) {
|
|
|
41334
41578
|
targetDir = await prompts.getDirectory(targetDir);
|
|
41335
41579
|
}
|
|
41336
41580
|
}
|
|
41337
|
-
const resolvedDir =
|
|
41581
|
+
const resolvedDir = resolve9(targetDir);
|
|
41338
41582
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
41583
|
+
if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
41584
|
+
logger.warning("You're creating a project at HOME directory.");
|
|
41585
|
+
logger.warning("This will install to your GLOBAL ~/.claude/ directory.");
|
|
41586
|
+
if (!isNonInteractive2) {
|
|
41587
|
+
const choice = await prompts.selectScope();
|
|
41588
|
+
if (choice === "cancel" || choice === "different") {
|
|
41589
|
+
logger.info("Please run 'ck new' from or specify a different directory.");
|
|
41590
|
+
return null;
|
|
41591
|
+
}
|
|
41592
|
+
logger.info("Proceeding with global installation");
|
|
41593
|
+
} else {
|
|
41594
|
+
logger.error("Cannot create project at HOME directory in non-interactive mode.");
|
|
41595
|
+
logger.info("Specify a different directory with --dir flag.");
|
|
41596
|
+
return null;
|
|
41597
|
+
}
|
|
41598
|
+
}
|
|
41339
41599
|
if (await import_fs_extra32.pathExists(resolvedDir)) {
|
|
41340
41600
|
const files = await import_fs_extra32.readdir(resolvedDir);
|
|
41341
41601
|
const isEmpty = files.length === 0;
|
|
@@ -41373,7 +41633,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
41373
41633
|
};
|
|
41374
41634
|
}
|
|
41375
41635
|
// src/commands/new/phases/project-creation.ts
|
|
41376
|
-
import { join as
|
|
41636
|
+
import { join as join70 } from "node:path";
|
|
41377
41637
|
init_logger();
|
|
41378
41638
|
init_output_manager();
|
|
41379
41639
|
init_types2();
|
|
@@ -41483,7 +41743,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
41483
41743
|
output.section("Installing");
|
|
41484
41744
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
41485
41745
|
const merger = new FileMerger;
|
|
41486
|
-
const claudeDir =
|
|
41746
|
+
const claudeDir = join70(resolvedDir, ".claude");
|
|
41487
41747
|
merger.setMultiKitContext(claudeDir, kit);
|
|
41488
41748
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
41489
41749
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -41624,7 +41884,8 @@ var import_fs_extra33 = __toESM(require_lib(), 1);
|
|
|
41624
41884
|
async function detectInstallations() {
|
|
41625
41885
|
const installations = [];
|
|
41626
41886
|
const setup = await getClaudeKitSetup(process.cwd());
|
|
41627
|
-
|
|
41887
|
+
const isLocalSameAsGlobal = PathResolver.isLocalSameAsGlobal();
|
|
41888
|
+
if (setup.project.path && setup.project.metadata && !isLocalSameAsGlobal) {
|
|
41628
41889
|
installations.push({
|
|
41629
41890
|
type: "local",
|
|
41630
41891
|
path: setup.project.path,
|
|
@@ -41643,13 +41904,13 @@ async function detectInstallations() {
|
|
|
41643
41904
|
|
|
41644
41905
|
// src/commands/uninstall/removal-handler.ts
|
|
41645
41906
|
import { readdirSync as readdirSync2, rmSync as rmSync2 } from "node:fs";
|
|
41646
|
-
import { join as
|
|
41907
|
+
import { join as join72 } from "node:path";
|
|
41647
41908
|
init_logger();
|
|
41648
41909
|
var import_fs_extra34 = __toESM(require_lib(), 1);
|
|
41649
41910
|
|
|
41650
41911
|
// src/commands/uninstall/analysis-handler.ts
|
|
41651
41912
|
import { readdirSync, rmSync } from "node:fs";
|
|
41652
|
-
import { dirname as dirname10, join as
|
|
41913
|
+
import { dirname as dirname10, join as join71 } from "node:path";
|
|
41653
41914
|
init_logger();
|
|
41654
41915
|
var import_picocolors21 = __toESM(require_picocolors(), 1);
|
|
41655
41916
|
function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
@@ -41696,7 +41957,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
41696
41957
|
if (uninstallManifest.isMultiKit && kit && metadata?.kits?.[kit]) {
|
|
41697
41958
|
const kitFiles = metadata.kits[kit].files || [];
|
|
41698
41959
|
for (const trackedFile of kitFiles) {
|
|
41699
|
-
const filePath =
|
|
41960
|
+
const filePath = join71(installation.path, trackedFile.path);
|
|
41700
41961
|
if (uninstallManifest.filesToPreserve.includes(trackedFile.path)) {
|
|
41701
41962
|
result.toPreserve.push({ path: trackedFile.path, reason: "shared with other kit" });
|
|
41702
41963
|
continue;
|
|
@@ -41726,7 +41987,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
41726
41987
|
return result;
|
|
41727
41988
|
}
|
|
41728
41989
|
for (const trackedFile of allTrackedFiles) {
|
|
41729
|
-
const filePath =
|
|
41990
|
+
const filePath = join71(installation.path, trackedFile.path);
|
|
41730
41991
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
41731
41992
|
if (!ownershipResult.exists)
|
|
41732
41993
|
continue;
|
|
@@ -41786,7 +42047,7 @@ async function removeInstallations(installations, options) {
|
|
|
41786
42047
|
let removedCount = 0;
|
|
41787
42048
|
let cleanedDirs = 0;
|
|
41788
42049
|
for (const item of analysis.toDelete) {
|
|
41789
|
-
const filePath =
|
|
42050
|
+
const filePath = join72(installation.path, item.path);
|
|
41790
42051
|
if (await import_fs_extra34.pathExists(filePath)) {
|
|
41791
42052
|
await import_fs_extra34.remove(filePath);
|
|
41792
42053
|
removedCount++;
|
|
@@ -41883,6 +42144,12 @@ async function uninstallCommand(options) {
|
|
|
41883
42144
|
return;
|
|
41884
42145
|
}
|
|
41885
42146
|
}
|
|
42147
|
+
const isAtHome = PathResolver.isLocalSameAsGlobal();
|
|
42148
|
+
if (validOptions.local && !validOptions.global && isAtHome) {
|
|
42149
|
+
log.warn(import_picocolors22.default.yellow("Cannot use --local at HOME directory (local path equals global path)."));
|
|
42150
|
+
log.info("Use -g/--global or run from a project directory.");
|
|
42151
|
+
return;
|
|
42152
|
+
}
|
|
41886
42153
|
let scope;
|
|
41887
42154
|
if (validOptions.all || validOptions.local && validOptions.global) {
|
|
41888
42155
|
scope = "all";
|
|
@@ -41890,6 +42157,9 @@ async function uninstallCommand(options) {
|
|
|
41890
42157
|
scope = "local";
|
|
41891
42158
|
} else if (validOptions.global) {
|
|
41892
42159
|
scope = "global";
|
|
42160
|
+
} else if (isAtHome) {
|
|
42161
|
+
log.info(import_picocolors22.default.cyan("Running at HOME directory - targeting global installation"));
|
|
42162
|
+
scope = "global";
|
|
41893
42163
|
} else {
|
|
41894
42164
|
const promptedScope = await promptScope(allInstallations);
|
|
41895
42165
|
if (!promptedScope) {
|
|
@@ -42109,14 +42379,14 @@ init_types2();
|
|
|
42109
42379
|
// src/domains/versioning/version-cache.ts
|
|
42110
42380
|
init_logger();
|
|
42111
42381
|
import { existsSync as existsSync19 } from "node:fs";
|
|
42112
|
-
import { mkdir as mkdir22, readFile as
|
|
42113
|
-
import { join as
|
|
42382
|
+
import { mkdir as mkdir22, readFile as readFile24, writeFile as writeFile21 } from "node:fs/promises";
|
|
42383
|
+
import { join as join73 } from "node:path";
|
|
42114
42384
|
class VersionCacheManager {
|
|
42115
42385
|
static CACHE_FILENAME = "version-check.json";
|
|
42116
42386
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
42117
42387
|
static getCacheFile() {
|
|
42118
42388
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
42119
|
-
return
|
|
42389
|
+
return join73(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
42120
42390
|
}
|
|
42121
42391
|
static async load() {
|
|
42122
42392
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -42125,7 +42395,7 @@ class VersionCacheManager {
|
|
|
42125
42395
|
logger.debug("Version check cache not found");
|
|
42126
42396
|
return null;
|
|
42127
42397
|
}
|
|
42128
|
-
const content = await
|
|
42398
|
+
const content = await readFile24(cacheFile, "utf-8");
|
|
42129
42399
|
const cache2 = JSON.parse(content);
|
|
42130
42400
|
if (!cache2.lastCheck || !cache2.currentVersion || !cache2.latestVersion) {
|
|
42131
42401
|
logger.debug("Invalid cache structure, ignoring");
|
|
@@ -42145,7 +42415,7 @@ class VersionCacheManager {
|
|
|
42145
42415
|
if (!existsSync19(cacheDir)) {
|
|
42146
42416
|
await mkdir22(cacheDir, { recursive: true, mode: 448 });
|
|
42147
42417
|
}
|
|
42148
|
-
await
|
|
42418
|
+
await writeFile21(cacheFile, JSON.stringify(cache2, null, 2), "utf-8");
|
|
42149
42419
|
logger.debug(`Version check cache saved to ${cacheFile}`);
|
|
42150
42420
|
} catch (error) {
|
|
42151
42421
|
logger.debug(`Failed to save version check cache: ${error}`);
|
|
@@ -42358,7 +42628,7 @@ var import_picocolors24 = __toESM(require_picocolors(), 1);
|
|
|
42358
42628
|
// package.json
|
|
42359
42629
|
var package_default = {
|
|
42360
42630
|
name: "claudekit-cli",
|
|
42361
|
-
version: "3.
|
|
42631
|
+
version: "3.23.0",
|
|
42362
42632
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
42363
42633
|
type: "module",
|
|
42364
42634
|
repository: {
|
|
@@ -42783,7 +43053,7 @@ function registerCommands(cli) {
|
|
|
42783
43053
|
|
|
42784
43054
|
// src/cli/version-display.ts
|
|
42785
43055
|
import { existsSync as existsSync20, readFileSync as readFileSync6 } from "node:fs";
|
|
42786
|
-
import { join as
|
|
43056
|
+
import { join as join74 } from "node:path";
|
|
42787
43057
|
init_logger();
|
|
42788
43058
|
init_types2();
|
|
42789
43059
|
var packageVersion = package_default.version;
|
|
@@ -42817,9 +43087,9 @@ async function displayVersion() {
|
|
|
42817
43087
|
let localKitVersion = null;
|
|
42818
43088
|
let isGlobalOnlyKit = false;
|
|
42819
43089
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
42820
|
-
const globalMetadataPath =
|
|
43090
|
+
const globalMetadataPath = join74(globalKitDir, "metadata.json");
|
|
42821
43091
|
const prefix = PathResolver.getPathPrefix(false);
|
|
42822
|
-
const localMetadataPath = prefix ?
|
|
43092
|
+
const localMetadataPath = prefix ? join74(process.cwd(), prefix, "metadata.json") : join74(process.cwd(), "metadata.json");
|
|
42823
43093
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
42824
43094
|
if (!isLocalSameAsGlobal && existsSync20(localMetadataPath)) {
|
|
42825
43095
|
try {
|