claudekit-cli 3.16.0 → 3.18.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.
Files changed (2) hide show
  1. package/dist/index.js +2724 -365
  2. package/package.json +3 -1
package/dist/index.js CHANGED
@@ -6589,7 +6589,7 @@ var init_kit = __esm(() => {
6589
6589
  name: "ClaudeKit Marketing",
6590
6590
  repo: "claudekit-marketing",
6591
6591
  owner: "claudekit",
6592
- description: "[Coming Soon] Marketing toolkit"
6592
+ description: "Marketing automation toolkit for Claude"
6593
6593
  }
6594
6594
  };
6595
6595
  NEVER_COPY_PATTERNS = [
@@ -6740,11 +6740,15 @@ var init_metadata = __esm(() => {
6740
6740
  checksum: exports_external.string().regex(/^[a-f0-9]{64}$/, "Invalid SHA-256 checksum"),
6741
6741
  ownership: exports_external.enum(["ck", "user", "ck-modified"]),
6742
6742
  installedVersion: exports_external.string(),
6743
- baseChecksum: exports_external.string().regex(/^[a-f0-9]{64}$/, "Invalid SHA-256 checksum").optional()
6743
+ baseChecksum: exports_external.string().regex(/^[a-f0-9]{64}$/, "Invalid SHA-256 checksum").optional(),
6744
+ sourceTimestamp: exports_external.string().datetime({ offset: true }).optional(),
6745
+ installedAt: exports_external.string().datetime({ offset: true }).optional()
6744
6746
  });
6745
6747
  InstalledSettingsSchema = exports_external.object({
6746
6748
  hooks: exports_external.array(exports_external.string()).optional(),
6747
- mcpServers: exports_external.array(exports_external.string()).optional()
6749
+ mcpServers: exports_external.array(exports_external.string()).optional(),
6750
+ hookTimestamps: exports_external.record(exports_external.string()).optional(),
6751
+ mcpServerTimestamps: exports_external.record(exports_external.string()).optional()
6748
6752
  });
6749
6753
  KitMetadataSchema = exports_external.object({
6750
6754
  version: exports_external.string(),
@@ -13341,6 +13345,1789 @@ var require_extract_zip = __commonJS((exports, module) => {
13341
13345
  };
13342
13346
  });
13343
13347
 
13348
+ // node_modules/semver/internal/constants.js
13349
+ var require_constants = __commonJS((exports, module) => {
13350
+ var SEMVER_SPEC_VERSION = "2.0.0";
13351
+ var MAX_LENGTH = 256;
13352
+ var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
13353
+ var MAX_SAFE_COMPONENT_LENGTH = 16;
13354
+ var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6;
13355
+ var RELEASE_TYPES = [
13356
+ "major",
13357
+ "premajor",
13358
+ "minor",
13359
+ "preminor",
13360
+ "patch",
13361
+ "prepatch",
13362
+ "prerelease"
13363
+ ];
13364
+ module.exports = {
13365
+ MAX_LENGTH,
13366
+ MAX_SAFE_COMPONENT_LENGTH,
13367
+ MAX_SAFE_BUILD_LENGTH,
13368
+ MAX_SAFE_INTEGER,
13369
+ RELEASE_TYPES,
13370
+ SEMVER_SPEC_VERSION,
13371
+ FLAG_INCLUDE_PRERELEASE: 1,
13372
+ FLAG_LOOSE: 2
13373
+ };
13374
+ });
13375
+
13376
+ // node_modules/semver/internal/debug.js
13377
+ var require_debug = __commonJS((exports, module) => {
13378
+ var debug = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => {};
13379
+ module.exports = debug;
13380
+ });
13381
+
13382
+ // node_modules/semver/internal/re.js
13383
+ var require_re = __commonJS((exports, module) => {
13384
+ var {
13385
+ MAX_SAFE_COMPONENT_LENGTH,
13386
+ MAX_SAFE_BUILD_LENGTH,
13387
+ MAX_LENGTH
13388
+ } = require_constants();
13389
+ var debug = require_debug();
13390
+ exports = module.exports = {};
13391
+ var re2 = exports.re = [];
13392
+ var safeRe = exports.safeRe = [];
13393
+ var src = exports.src = [];
13394
+ var safeSrc = exports.safeSrc = [];
13395
+ var t = exports.t = {};
13396
+ var R3 = 0;
13397
+ var LETTERDASHNUMBER = "[a-zA-Z0-9-]";
13398
+ var safeRegexReplacements = [
13399
+ ["\\s", 1],
13400
+ ["\\d", MAX_LENGTH],
13401
+ [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH]
13402
+ ];
13403
+ var makeSafeRegex = (value) => {
13404
+ for (const [token, max] of safeRegexReplacements) {
13405
+ value = value.split(`${token}*`).join(`${token}{0,${max}}`).split(`${token}+`).join(`${token}{1,${max}}`);
13406
+ }
13407
+ return value;
13408
+ };
13409
+ var createToken = (name2, value, isGlobal) => {
13410
+ const safe = makeSafeRegex(value);
13411
+ const index = R3++;
13412
+ debug(name2, index, value);
13413
+ t[name2] = index;
13414
+ src[index] = value;
13415
+ safeSrc[index] = safe;
13416
+ re2[index] = new RegExp(value, isGlobal ? "g" : undefined);
13417
+ safeRe[index] = new RegExp(safe, isGlobal ? "g" : undefined);
13418
+ };
13419
+ createToken("NUMERICIDENTIFIER", "0|[1-9]\\d*");
13420
+ createToken("NUMERICIDENTIFIERLOOSE", "\\d+");
13421
+ createToken("NONNUMERICIDENTIFIER", `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`);
13422
+ createToken("MAINVERSION", `(${src[t.NUMERICIDENTIFIER]})\\.` + `(${src[t.NUMERICIDENTIFIER]})\\.` + `(${src[t.NUMERICIDENTIFIER]})`);
13423
+ createToken("MAINVERSIONLOOSE", `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + `(${src[t.NUMERICIDENTIFIERLOOSE]})`);
13424
+ createToken("PRERELEASEIDENTIFIER", `(?:${src[t.NONNUMERICIDENTIFIER]}|${src[t.NUMERICIDENTIFIER]})`);
13425
+ createToken("PRERELEASEIDENTIFIERLOOSE", `(?:${src[t.NONNUMERICIDENTIFIER]}|${src[t.NUMERICIDENTIFIERLOOSE]})`);
13426
+ createToken("PRERELEASE", `(?:-(${src[t.PRERELEASEIDENTIFIER]}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`);
13427
+ createToken("PRERELEASELOOSE", `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`);
13428
+ createToken("BUILDIDENTIFIER", `${LETTERDASHNUMBER}+`);
13429
+ createToken("BUILD", `(?:\\+(${src[t.BUILDIDENTIFIER]}(?:\\.${src[t.BUILDIDENTIFIER]})*))`);
13430
+ createToken("FULLPLAIN", `v?${src[t.MAINVERSION]}${src[t.PRERELEASE]}?${src[t.BUILD]}?`);
13431
+ createToken("FULL", `^${src[t.FULLPLAIN]}$`);
13432
+ createToken("LOOSEPLAIN", `[v=\\s]*${src[t.MAINVERSIONLOOSE]}${src[t.PRERELEASELOOSE]}?${src[t.BUILD]}?`);
13433
+ createToken("LOOSE", `^${src[t.LOOSEPLAIN]}$`);
13434
+ createToken("GTLT", "((?:<|>)?=?)");
13435
+ createToken("XRANGEIDENTIFIERLOOSE", `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
13436
+ createToken("XRANGEIDENTIFIER", `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`);
13437
+ createToken("XRANGEPLAIN", `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + `(?:${src[t.PRERELEASE]})?${src[t.BUILD]}?` + `)?)?`);
13438
+ createToken("XRANGEPLAINLOOSE", `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + `(?:${src[t.PRERELEASELOOSE]})?${src[t.BUILD]}?` + `)?)?`);
13439
+ createToken("XRANGE", `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`);
13440
+ createToken("XRANGELOOSE", `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`);
13441
+ createToken("COERCEPLAIN", `${"(^|[^\\d])" + "(\\d{1,"}${MAX_SAFE_COMPONENT_LENGTH}})` + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`);
13442
+ createToken("COERCE", `${src[t.COERCEPLAIN]}(?:$|[^\\d])`);
13443
+ createToken("COERCEFULL", src[t.COERCEPLAIN] + `(?:${src[t.PRERELEASE]})?` + `(?:${src[t.BUILD]})?` + `(?:$|[^\\d])`);
13444
+ createToken("COERCERTL", src[t.COERCE], true);
13445
+ createToken("COERCERTLFULL", src[t.COERCEFULL], true);
13446
+ createToken("LONETILDE", "(?:~>?)");
13447
+ createToken("TILDETRIM", `(\\s*)${src[t.LONETILDE]}\\s+`, true);
13448
+ exports.tildeTrimReplace = "$1~";
13449
+ createToken("TILDE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);
13450
+ createToken("TILDELOOSE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);
13451
+ createToken("LONECARET", "(?:\\^)");
13452
+ createToken("CARETTRIM", `(\\s*)${src[t.LONECARET]}\\s+`, true);
13453
+ exports.caretTrimReplace = "$1^";
13454
+ createToken("CARET", `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);
13455
+ createToken("CARETLOOSE", `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);
13456
+ createToken("COMPARATORLOOSE", `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`);
13457
+ createToken("COMPARATOR", `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`);
13458
+ createToken("COMPARATORTRIM", `(\\s*)${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);
13459
+ exports.comparatorTrimReplace = "$1$2$3";
13460
+ createToken("HYPHENRANGE", `^\\s*(${src[t.XRANGEPLAIN]})` + `\\s+-\\s+` + `(${src[t.XRANGEPLAIN]})` + `\\s*$`);
13461
+ createToken("HYPHENRANGELOOSE", `^\\s*(${src[t.XRANGEPLAINLOOSE]})` + `\\s+-\\s+` + `(${src[t.XRANGEPLAINLOOSE]})` + `\\s*$`);
13462
+ createToken("STAR", "(<|>)?=?\\s*\\*");
13463
+ createToken("GTE0", "^\\s*>=\\s*0\\.0\\.0\\s*$");
13464
+ createToken("GTE0PRE", "^\\s*>=\\s*0\\.0\\.0-0\\s*$");
13465
+ });
13466
+
13467
+ // node_modules/semver/internal/parse-options.js
13468
+ var require_parse_options = __commonJS((exports, module) => {
13469
+ var looseOption = Object.freeze({ loose: true });
13470
+ var emptyOpts = Object.freeze({});
13471
+ var parseOptions = (options) => {
13472
+ if (!options) {
13473
+ return emptyOpts;
13474
+ }
13475
+ if (typeof options !== "object") {
13476
+ return looseOption;
13477
+ }
13478
+ return options;
13479
+ };
13480
+ module.exports = parseOptions;
13481
+ });
13482
+
13483
+ // node_modules/semver/internal/identifiers.js
13484
+ var require_identifiers = __commonJS((exports, module) => {
13485
+ var numeric = /^[0-9]+$/;
13486
+ var compareIdentifiers = (a3, b3) => {
13487
+ if (typeof a3 === "number" && typeof b3 === "number") {
13488
+ return a3 === b3 ? 0 : a3 < b3 ? -1 : 1;
13489
+ }
13490
+ const anum = numeric.test(a3);
13491
+ const bnum = numeric.test(b3);
13492
+ if (anum && bnum) {
13493
+ a3 = +a3;
13494
+ b3 = +b3;
13495
+ }
13496
+ return a3 === b3 ? 0 : anum && !bnum ? -1 : bnum && !anum ? 1 : a3 < b3 ? -1 : 1;
13497
+ };
13498
+ var rcompareIdentifiers = (a3, b3) => compareIdentifiers(b3, a3);
13499
+ module.exports = {
13500
+ compareIdentifiers,
13501
+ rcompareIdentifiers
13502
+ };
13503
+ });
13504
+
13505
+ // node_modules/semver/classes/semver.js
13506
+ var require_semver = __commonJS((exports, module) => {
13507
+ var debug = require_debug();
13508
+ var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants();
13509
+ var { safeRe: re2, t } = require_re();
13510
+ var parseOptions = require_parse_options();
13511
+ var { compareIdentifiers } = require_identifiers();
13512
+
13513
+ class SemVer {
13514
+ constructor(version, options) {
13515
+ options = parseOptions(options);
13516
+ if (version instanceof SemVer) {
13517
+ if (version.loose === !!options.loose && version.includePrerelease === !!options.includePrerelease) {
13518
+ return version;
13519
+ } else {
13520
+ version = version.version;
13521
+ }
13522
+ } else if (typeof version !== "string") {
13523
+ throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`);
13524
+ }
13525
+ if (version.length > MAX_LENGTH) {
13526
+ throw new TypeError(`version is longer than ${MAX_LENGTH} characters`);
13527
+ }
13528
+ debug("SemVer", version, options);
13529
+ this.options = options;
13530
+ this.loose = !!options.loose;
13531
+ this.includePrerelease = !!options.includePrerelease;
13532
+ const m2 = version.trim().match(options.loose ? re2[t.LOOSE] : re2[t.FULL]);
13533
+ if (!m2) {
13534
+ throw new TypeError(`Invalid Version: ${version}`);
13535
+ }
13536
+ this.raw = version;
13537
+ this.major = +m2[1];
13538
+ this.minor = +m2[2];
13539
+ this.patch = +m2[3];
13540
+ if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
13541
+ throw new TypeError("Invalid major version");
13542
+ }
13543
+ if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
13544
+ throw new TypeError("Invalid minor version");
13545
+ }
13546
+ if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
13547
+ throw new TypeError("Invalid patch version");
13548
+ }
13549
+ if (!m2[4]) {
13550
+ this.prerelease = [];
13551
+ } else {
13552
+ this.prerelease = m2[4].split(".").map((id) => {
13553
+ if (/^[0-9]+$/.test(id)) {
13554
+ const num = +id;
13555
+ if (num >= 0 && num < MAX_SAFE_INTEGER) {
13556
+ return num;
13557
+ }
13558
+ }
13559
+ return id;
13560
+ });
13561
+ }
13562
+ this.build = m2[5] ? m2[5].split(".") : [];
13563
+ this.format();
13564
+ }
13565
+ format() {
13566
+ this.version = `${this.major}.${this.minor}.${this.patch}`;
13567
+ if (this.prerelease.length) {
13568
+ this.version += `-${this.prerelease.join(".")}`;
13569
+ }
13570
+ return this.version;
13571
+ }
13572
+ toString() {
13573
+ return this.version;
13574
+ }
13575
+ compare(other) {
13576
+ debug("SemVer.compare", this.version, this.options, other);
13577
+ if (!(other instanceof SemVer)) {
13578
+ if (typeof other === "string" && other === this.version) {
13579
+ return 0;
13580
+ }
13581
+ other = new SemVer(other, this.options);
13582
+ }
13583
+ if (other.version === this.version) {
13584
+ return 0;
13585
+ }
13586
+ return this.compareMain(other) || this.comparePre(other);
13587
+ }
13588
+ compareMain(other) {
13589
+ if (!(other instanceof SemVer)) {
13590
+ other = new SemVer(other, this.options);
13591
+ }
13592
+ if (this.major < other.major) {
13593
+ return -1;
13594
+ }
13595
+ if (this.major > other.major) {
13596
+ return 1;
13597
+ }
13598
+ if (this.minor < other.minor) {
13599
+ return -1;
13600
+ }
13601
+ if (this.minor > other.minor) {
13602
+ return 1;
13603
+ }
13604
+ if (this.patch < other.patch) {
13605
+ return -1;
13606
+ }
13607
+ if (this.patch > other.patch) {
13608
+ return 1;
13609
+ }
13610
+ return 0;
13611
+ }
13612
+ comparePre(other) {
13613
+ if (!(other instanceof SemVer)) {
13614
+ other = new SemVer(other, this.options);
13615
+ }
13616
+ if (this.prerelease.length && !other.prerelease.length) {
13617
+ return -1;
13618
+ } else if (!this.prerelease.length && other.prerelease.length) {
13619
+ return 1;
13620
+ } else if (!this.prerelease.length && !other.prerelease.length) {
13621
+ return 0;
13622
+ }
13623
+ let i = 0;
13624
+ do {
13625
+ const a3 = this.prerelease[i];
13626
+ const b3 = other.prerelease[i];
13627
+ debug("prerelease compare", i, a3, b3);
13628
+ if (a3 === undefined && b3 === undefined) {
13629
+ return 0;
13630
+ } else if (b3 === undefined) {
13631
+ return 1;
13632
+ } else if (a3 === undefined) {
13633
+ return -1;
13634
+ } else if (a3 === b3) {
13635
+ continue;
13636
+ } else {
13637
+ return compareIdentifiers(a3, b3);
13638
+ }
13639
+ } while (++i);
13640
+ }
13641
+ compareBuild(other) {
13642
+ if (!(other instanceof SemVer)) {
13643
+ other = new SemVer(other, this.options);
13644
+ }
13645
+ let i = 0;
13646
+ do {
13647
+ const a3 = this.build[i];
13648
+ const b3 = other.build[i];
13649
+ debug("build compare", i, a3, b3);
13650
+ if (a3 === undefined && b3 === undefined) {
13651
+ return 0;
13652
+ } else if (b3 === undefined) {
13653
+ return 1;
13654
+ } else if (a3 === undefined) {
13655
+ return -1;
13656
+ } else if (a3 === b3) {
13657
+ continue;
13658
+ } else {
13659
+ return compareIdentifiers(a3, b3);
13660
+ }
13661
+ } while (++i);
13662
+ }
13663
+ inc(release, identifier, identifierBase) {
13664
+ if (release.startsWith("pre")) {
13665
+ if (!identifier && identifierBase === false) {
13666
+ throw new Error("invalid increment argument: identifier is empty");
13667
+ }
13668
+ if (identifier) {
13669
+ const match = `-${identifier}`.match(this.options.loose ? re2[t.PRERELEASELOOSE] : re2[t.PRERELEASE]);
13670
+ if (!match || match[1] !== identifier) {
13671
+ throw new Error(`invalid identifier: ${identifier}`);
13672
+ }
13673
+ }
13674
+ }
13675
+ switch (release) {
13676
+ case "premajor":
13677
+ this.prerelease.length = 0;
13678
+ this.patch = 0;
13679
+ this.minor = 0;
13680
+ this.major++;
13681
+ this.inc("pre", identifier, identifierBase);
13682
+ break;
13683
+ case "preminor":
13684
+ this.prerelease.length = 0;
13685
+ this.patch = 0;
13686
+ this.minor++;
13687
+ this.inc("pre", identifier, identifierBase);
13688
+ break;
13689
+ case "prepatch":
13690
+ this.prerelease.length = 0;
13691
+ this.inc("patch", identifier, identifierBase);
13692
+ this.inc("pre", identifier, identifierBase);
13693
+ break;
13694
+ case "prerelease":
13695
+ if (this.prerelease.length === 0) {
13696
+ this.inc("patch", identifier, identifierBase);
13697
+ }
13698
+ this.inc("pre", identifier, identifierBase);
13699
+ break;
13700
+ case "release":
13701
+ if (this.prerelease.length === 0) {
13702
+ throw new Error(`version ${this.raw} is not a prerelease`);
13703
+ }
13704
+ this.prerelease.length = 0;
13705
+ break;
13706
+ case "major":
13707
+ if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) {
13708
+ this.major++;
13709
+ }
13710
+ this.minor = 0;
13711
+ this.patch = 0;
13712
+ this.prerelease = [];
13713
+ break;
13714
+ case "minor":
13715
+ if (this.patch !== 0 || this.prerelease.length === 0) {
13716
+ this.minor++;
13717
+ }
13718
+ this.patch = 0;
13719
+ this.prerelease = [];
13720
+ break;
13721
+ case "patch":
13722
+ if (this.prerelease.length === 0) {
13723
+ this.patch++;
13724
+ }
13725
+ this.prerelease = [];
13726
+ break;
13727
+ case "pre": {
13728
+ const base = Number(identifierBase) ? 1 : 0;
13729
+ if (this.prerelease.length === 0) {
13730
+ this.prerelease = [base];
13731
+ } else {
13732
+ let i = this.prerelease.length;
13733
+ while (--i >= 0) {
13734
+ if (typeof this.prerelease[i] === "number") {
13735
+ this.prerelease[i]++;
13736
+ i = -2;
13737
+ }
13738
+ }
13739
+ if (i === -1) {
13740
+ if (identifier === this.prerelease.join(".") && identifierBase === false) {
13741
+ throw new Error("invalid increment argument: identifier already exists");
13742
+ }
13743
+ this.prerelease.push(base);
13744
+ }
13745
+ }
13746
+ if (identifier) {
13747
+ let prerelease = [identifier, base];
13748
+ if (identifierBase === false) {
13749
+ prerelease = [identifier];
13750
+ }
13751
+ if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
13752
+ if (isNaN(this.prerelease[1])) {
13753
+ this.prerelease = prerelease;
13754
+ }
13755
+ } else {
13756
+ this.prerelease = prerelease;
13757
+ }
13758
+ }
13759
+ break;
13760
+ }
13761
+ default:
13762
+ throw new Error(`invalid increment argument: ${release}`);
13763
+ }
13764
+ this.raw = this.format();
13765
+ if (this.build.length) {
13766
+ this.raw += `+${this.build.join(".")}`;
13767
+ }
13768
+ return this;
13769
+ }
13770
+ }
13771
+ module.exports = SemVer;
13772
+ });
13773
+
13774
+ // node_modules/semver/functions/parse.js
13775
+ var require_parse = __commonJS((exports, module) => {
13776
+ var SemVer = require_semver();
13777
+ var parse5 = (version, options, throwErrors = false) => {
13778
+ if (version instanceof SemVer) {
13779
+ return version;
13780
+ }
13781
+ try {
13782
+ return new SemVer(version, options);
13783
+ } catch (er) {
13784
+ if (!throwErrors) {
13785
+ return null;
13786
+ }
13787
+ throw er;
13788
+ }
13789
+ };
13790
+ module.exports = parse5;
13791
+ });
13792
+
13793
+ // node_modules/semver/functions/valid.js
13794
+ var require_valid = __commonJS((exports, module) => {
13795
+ var parse5 = require_parse();
13796
+ var valid = (version, options) => {
13797
+ const v2 = parse5(version, options);
13798
+ return v2 ? v2.version : null;
13799
+ };
13800
+ module.exports = valid;
13801
+ });
13802
+
13803
+ // node_modules/semver/functions/clean.js
13804
+ var require_clean = __commonJS((exports, module) => {
13805
+ var parse5 = require_parse();
13806
+ var clean = (version, options) => {
13807
+ const s = parse5(version.trim().replace(/^[=v]+/, ""), options);
13808
+ return s ? s.version : null;
13809
+ };
13810
+ module.exports = clean;
13811
+ });
13812
+
13813
+ // node_modules/semver/functions/inc.js
13814
+ var require_inc = __commonJS((exports, module) => {
13815
+ var SemVer = require_semver();
13816
+ var inc = (version, release, options, identifier, identifierBase) => {
13817
+ if (typeof options === "string") {
13818
+ identifierBase = identifier;
13819
+ identifier = options;
13820
+ options = undefined;
13821
+ }
13822
+ try {
13823
+ return new SemVer(version instanceof SemVer ? version.version : version, options).inc(release, identifier, identifierBase).version;
13824
+ } catch (er) {
13825
+ return null;
13826
+ }
13827
+ };
13828
+ module.exports = inc;
13829
+ });
13830
+
13831
+ // node_modules/semver/functions/diff.js
13832
+ var require_diff = __commonJS((exports, module) => {
13833
+ var parse5 = require_parse();
13834
+ var diff = (version1, version2) => {
13835
+ const v1 = parse5(version1, null, true);
13836
+ const v2 = parse5(version2, null, true);
13837
+ const comparison = v1.compare(v2);
13838
+ if (comparison === 0) {
13839
+ return null;
13840
+ }
13841
+ const v1Higher = comparison > 0;
13842
+ const highVersion = v1Higher ? v1 : v2;
13843
+ const lowVersion = v1Higher ? v2 : v1;
13844
+ const highHasPre = !!highVersion.prerelease.length;
13845
+ const lowHasPre = !!lowVersion.prerelease.length;
13846
+ if (lowHasPre && !highHasPre) {
13847
+ if (!lowVersion.patch && !lowVersion.minor) {
13848
+ return "major";
13849
+ }
13850
+ if (lowVersion.compareMain(highVersion) === 0) {
13851
+ if (lowVersion.minor && !lowVersion.patch) {
13852
+ return "minor";
13853
+ }
13854
+ return "patch";
13855
+ }
13856
+ }
13857
+ const prefix = highHasPre ? "pre" : "";
13858
+ if (v1.major !== v2.major) {
13859
+ return prefix + "major";
13860
+ }
13861
+ if (v1.minor !== v2.minor) {
13862
+ return prefix + "minor";
13863
+ }
13864
+ if (v1.patch !== v2.patch) {
13865
+ return prefix + "patch";
13866
+ }
13867
+ return "prerelease";
13868
+ };
13869
+ module.exports = diff;
13870
+ });
13871
+
13872
+ // node_modules/semver/functions/major.js
13873
+ var require_major = __commonJS((exports, module) => {
13874
+ var SemVer = require_semver();
13875
+ var major = (a3, loose) => new SemVer(a3, loose).major;
13876
+ module.exports = major;
13877
+ });
13878
+
13879
+ // node_modules/semver/functions/minor.js
13880
+ var require_minor = __commonJS((exports, module) => {
13881
+ var SemVer = require_semver();
13882
+ var minor = (a3, loose) => new SemVer(a3, loose).minor;
13883
+ module.exports = minor;
13884
+ });
13885
+
13886
+ // node_modules/semver/functions/patch.js
13887
+ var require_patch = __commonJS((exports, module) => {
13888
+ var SemVer = require_semver();
13889
+ var patch = (a3, loose) => new SemVer(a3, loose).patch;
13890
+ module.exports = patch;
13891
+ });
13892
+
13893
+ // node_modules/semver/functions/prerelease.js
13894
+ var require_prerelease = __commonJS((exports, module) => {
13895
+ var parse5 = require_parse();
13896
+ var prerelease = (version, options) => {
13897
+ const parsed = parse5(version, options);
13898
+ return parsed && parsed.prerelease.length ? parsed.prerelease : null;
13899
+ };
13900
+ module.exports = prerelease;
13901
+ });
13902
+
13903
+ // node_modules/semver/functions/compare.js
13904
+ var require_compare = __commonJS((exports, module) => {
13905
+ var SemVer = require_semver();
13906
+ var compare = (a3, b3, loose) => new SemVer(a3, loose).compare(new SemVer(b3, loose));
13907
+ module.exports = compare;
13908
+ });
13909
+
13910
+ // node_modules/semver/functions/rcompare.js
13911
+ var require_rcompare = __commonJS((exports, module) => {
13912
+ var compare = require_compare();
13913
+ var rcompare = (a3, b3, loose) => compare(b3, a3, loose);
13914
+ module.exports = rcompare;
13915
+ });
13916
+
13917
+ // node_modules/semver/functions/compare-loose.js
13918
+ var require_compare_loose = __commonJS((exports, module) => {
13919
+ var compare = require_compare();
13920
+ var compareLoose = (a3, b3) => compare(a3, b3, true);
13921
+ module.exports = compareLoose;
13922
+ });
13923
+
13924
+ // node_modules/semver/functions/compare-build.js
13925
+ var require_compare_build = __commonJS((exports, module) => {
13926
+ var SemVer = require_semver();
13927
+ var compareBuild = (a3, b3, loose) => {
13928
+ const versionA = new SemVer(a3, loose);
13929
+ const versionB = new SemVer(b3, loose);
13930
+ return versionA.compare(versionB) || versionA.compareBuild(versionB);
13931
+ };
13932
+ module.exports = compareBuild;
13933
+ });
13934
+
13935
+ // node_modules/semver/functions/sort.js
13936
+ var require_sort = __commonJS((exports, module) => {
13937
+ var compareBuild = require_compare_build();
13938
+ var sort = (list3, loose) => list3.sort((a3, b3) => compareBuild(a3, b3, loose));
13939
+ module.exports = sort;
13940
+ });
13941
+
13942
+ // node_modules/semver/functions/rsort.js
13943
+ var require_rsort = __commonJS((exports, module) => {
13944
+ var compareBuild = require_compare_build();
13945
+ var rsort = (list3, loose) => list3.sort((a3, b3) => compareBuild(b3, a3, loose));
13946
+ module.exports = rsort;
13947
+ });
13948
+
13949
+ // node_modules/semver/functions/gt.js
13950
+ var require_gt = __commonJS((exports, module) => {
13951
+ var compare = require_compare();
13952
+ var gt = (a3, b3, loose) => compare(a3, b3, loose) > 0;
13953
+ module.exports = gt;
13954
+ });
13955
+
13956
+ // node_modules/semver/functions/lt.js
13957
+ var require_lt = __commonJS((exports, module) => {
13958
+ var compare = require_compare();
13959
+ var lt = (a3, b3, loose) => compare(a3, b3, loose) < 0;
13960
+ module.exports = lt;
13961
+ });
13962
+
13963
+ // node_modules/semver/functions/eq.js
13964
+ var require_eq = __commonJS((exports, module) => {
13965
+ var compare = require_compare();
13966
+ var eq = (a3, b3, loose) => compare(a3, b3, loose) === 0;
13967
+ module.exports = eq;
13968
+ });
13969
+
13970
+ // node_modules/semver/functions/neq.js
13971
+ var require_neq = __commonJS((exports, module) => {
13972
+ var compare = require_compare();
13973
+ var neq = (a3, b3, loose) => compare(a3, b3, loose) !== 0;
13974
+ module.exports = neq;
13975
+ });
13976
+
13977
+ // node_modules/semver/functions/gte.js
13978
+ var require_gte = __commonJS((exports, module) => {
13979
+ var compare = require_compare();
13980
+ var gte = (a3, b3, loose) => compare(a3, b3, loose) >= 0;
13981
+ module.exports = gte;
13982
+ });
13983
+
13984
+ // node_modules/semver/functions/lte.js
13985
+ var require_lte = __commonJS((exports, module) => {
13986
+ var compare = require_compare();
13987
+ var lte = (a3, b3, loose) => compare(a3, b3, loose) <= 0;
13988
+ module.exports = lte;
13989
+ });
13990
+
13991
+ // node_modules/semver/functions/cmp.js
13992
+ var require_cmp = __commonJS((exports, module) => {
13993
+ var eq = require_eq();
13994
+ var neq = require_neq();
13995
+ var gt = require_gt();
13996
+ var gte = require_gte();
13997
+ var lt = require_lt();
13998
+ var lte = require_lte();
13999
+ var cmp = (a3, op, b3, loose) => {
14000
+ switch (op) {
14001
+ case "===":
14002
+ if (typeof a3 === "object") {
14003
+ a3 = a3.version;
14004
+ }
14005
+ if (typeof b3 === "object") {
14006
+ b3 = b3.version;
14007
+ }
14008
+ return a3 === b3;
14009
+ case "!==":
14010
+ if (typeof a3 === "object") {
14011
+ a3 = a3.version;
14012
+ }
14013
+ if (typeof b3 === "object") {
14014
+ b3 = b3.version;
14015
+ }
14016
+ return a3 !== b3;
14017
+ case "":
14018
+ case "=":
14019
+ case "==":
14020
+ return eq(a3, b3, loose);
14021
+ case "!=":
14022
+ return neq(a3, b3, loose);
14023
+ case ">":
14024
+ return gt(a3, b3, loose);
14025
+ case ">=":
14026
+ return gte(a3, b3, loose);
14027
+ case "<":
14028
+ return lt(a3, b3, loose);
14029
+ case "<=":
14030
+ return lte(a3, b3, loose);
14031
+ default:
14032
+ throw new TypeError(`Invalid operator: ${op}`);
14033
+ }
14034
+ };
14035
+ module.exports = cmp;
14036
+ });
14037
+
14038
+ // node_modules/semver/functions/coerce.js
14039
+ var require_coerce = __commonJS((exports, module) => {
14040
+ var SemVer = require_semver();
14041
+ var parse5 = require_parse();
14042
+ var { safeRe: re2, t } = require_re();
14043
+ var coerce2 = (version, options) => {
14044
+ if (version instanceof SemVer) {
14045
+ return version;
14046
+ }
14047
+ if (typeof version === "number") {
14048
+ version = String(version);
14049
+ }
14050
+ if (typeof version !== "string") {
14051
+ return null;
14052
+ }
14053
+ options = options || {};
14054
+ let match = null;
14055
+ if (!options.rtl) {
14056
+ match = version.match(options.includePrerelease ? re2[t.COERCEFULL] : re2[t.COERCE]);
14057
+ } else {
14058
+ const coerceRtlRegex = options.includePrerelease ? re2[t.COERCERTLFULL] : re2[t.COERCERTL];
14059
+ let next;
14060
+ while ((next = coerceRtlRegex.exec(version)) && (!match || match.index + match[0].length !== version.length)) {
14061
+ if (!match || next.index + next[0].length !== match.index + match[0].length) {
14062
+ match = next;
14063
+ }
14064
+ coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length;
14065
+ }
14066
+ coerceRtlRegex.lastIndex = -1;
14067
+ }
14068
+ if (match === null) {
14069
+ return null;
14070
+ }
14071
+ const major = match[2];
14072
+ const minor = match[3] || "0";
14073
+ const patch = match[4] || "0";
14074
+ const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : "";
14075
+ const build = options.includePrerelease && match[6] ? `+${match[6]}` : "";
14076
+ return parse5(`${major}.${minor}.${patch}${prerelease}${build}`, options);
14077
+ };
14078
+ module.exports = coerce2;
14079
+ });
14080
+
14081
+ // node_modules/semver/internal/lrucache.js
14082
+ var require_lrucache = __commonJS((exports, module) => {
14083
+ class LRUCache {
14084
+ constructor() {
14085
+ this.max = 1000;
14086
+ this.map = new Map;
14087
+ }
14088
+ get(key) {
14089
+ const value = this.map.get(key);
14090
+ if (value === undefined) {
14091
+ return;
14092
+ } else {
14093
+ this.map.delete(key);
14094
+ this.map.set(key, value);
14095
+ return value;
14096
+ }
14097
+ }
14098
+ delete(key) {
14099
+ return this.map.delete(key);
14100
+ }
14101
+ set(key, value) {
14102
+ const deleted = this.delete(key);
14103
+ if (!deleted && value !== undefined) {
14104
+ if (this.map.size >= this.max) {
14105
+ const firstKey = this.map.keys().next().value;
14106
+ this.delete(firstKey);
14107
+ }
14108
+ this.map.set(key, value);
14109
+ }
14110
+ return this;
14111
+ }
14112
+ }
14113
+ module.exports = LRUCache;
14114
+ });
14115
+
14116
+ // node_modules/semver/classes/range.js
14117
+ var require_range = __commonJS((exports, module) => {
14118
+ var SPACE_CHARACTERS = /\s+/g;
14119
+
14120
+ class Range {
14121
+ constructor(range, options) {
14122
+ options = parseOptions(options);
14123
+ if (range instanceof Range) {
14124
+ if (range.loose === !!options.loose && range.includePrerelease === !!options.includePrerelease) {
14125
+ return range;
14126
+ } else {
14127
+ return new Range(range.raw, options);
14128
+ }
14129
+ }
14130
+ if (range instanceof Comparator) {
14131
+ this.raw = range.value;
14132
+ this.set = [[range]];
14133
+ this.formatted = undefined;
14134
+ return this;
14135
+ }
14136
+ this.options = options;
14137
+ this.loose = !!options.loose;
14138
+ this.includePrerelease = !!options.includePrerelease;
14139
+ this.raw = range.trim().replace(SPACE_CHARACTERS, " ");
14140
+ this.set = this.raw.split("||").map((r2) => this.parseRange(r2.trim())).filter((c2) => c2.length);
14141
+ if (!this.set.length) {
14142
+ throw new TypeError(`Invalid SemVer Range: ${this.raw}`);
14143
+ }
14144
+ if (this.set.length > 1) {
14145
+ const first = this.set[0];
14146
+ this.set = this.set.filter((c2) => !isNullSet(c2[0]));
14147
+ if (this.set.length === 0) {
14148
+ this.set = [first];
14149
+ } else if (this.set.length > 1) {
14150
+ for (const c2 of this.set) {
14151
+ if (c2.length === 1 && isAny(c2[0])) {
14152
+ this.set = [c2];
14153
+ break;
14154
+ }
14155
+ }
14156
+ }
14157
+ }
14158
+ this.formatted = undefined;
14159
+ }
14160
+ get range() {
14161
+ if (this.formatted === undefined) {
14162
+ this.formatted = "";
14163
+ for (let i = 0;i < this.set.length; i++) {
14164
+ if (i > 0) {
14165
+ this.formatted += "||";
14166
+ }
14167
+ const comps = this.set[i];
14168
+ for (let k2 = 0;k2 < comps.length; k2++) {
14169
+ if (k2 > 0) {
14170
+ this.formatted += " ";
14171
+ }
14172
+ this.formatted += comps[k2].toString().trim();
14173
+ }
14174
+ }
14175
+ }
14176
+ return this.formatted;
14177
+ }
14178
+ format() {
14179
+ return this.range;
14180
+ }
14181
+ toString() {
14182
+ return this.range;
14183
+ }
14184
+ parseRange(range) {
14185
+ const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE);
14186
+ const memoKey = memoOpts + ":" + range;
14187
+ const cached = cache2.get(memoKey);
14188
+ if (cached) {
14189
+ return cached;
14190
+ }
14191
+ const loose = this.options.loose;
14192
+ const hr = loose ? re2[t.HYPHENRANGELOOSE] : re2[t.HYPHENRANGE];
14193
+ range = range.replace(hr, hyphenReplace(this.options.includePrerelease));
14194
+ debug("hyphen replace", range);
14195
+ range = range.replace(re2[t.COMPARATORTRIM], comparatorTrimReplace);
14196
+ debug("comparator trim", range);
14197
+ range = range.replace(re2[t.TILDETRIM], tildeTrimReplace);
14198
+ debug("tilde trim", range);
14199
+ range = range.replace(re2[t.CARETTRIM], caretTrimReplace);
14200
+ debug("caret trim", range);
14201
+ let rangeList = range.split(" ").map((comp) => parseComparator(comp, this.options)).join(" ").split(/\s+/).map((comp) => replaceGTE0(comp, this.options));
14202
+ if (loose) {
14203
+ rangeList = rangeList.filter((comp) => {
14204
+ debug("loose invalid filter", comp, this.options);
14205
+ return !!comp.match(re2[t.COMPARATORLOOSE]);
14206
+ });
14207
+ }
14208
+ debug("range list", rangeList);
14209
+ const rangeMap = new Map;
14210
+ const comparators = rangeList.map((comp) => new Comparator(comp, this.options));
14211
+ for (const comp of comparators) {
14212
+ if (isNullSet(comp)) {
14213
+ return [comp];
14214
+ }
14215
+ rangeMap.set(comp.value, comp);
14216
+ }
14217
+ if (rangeMap.size > 1 && rangeMap.has("")) {
14218
+ rangeMap.delete("");
14219
+ }
14220
+ const result = [...rangeMap.values()];
14221
+ cache2.set(memoKey, result);
14222
+ return result;
14223
+ }
14224
+ intersects(range, options) {
14225
+ if (!(range instanceof Range)) {
14226
+ throw new TypeError("a Range is required");
14227
+ }
14228
+ return this.set.some((thisComparators) => {
14229
+ return isSatisfiable(thisComparators, options) && range.set.some((rangeComparators) => {
14230
+ return isSatisfiable(rangeComparators, options) && thisComparators.every((thisComparator) => {
14231
+ return rangeComparators.every((rangeComparator) => {
14232
+ return thisComparator.intersects(rangeComparator, options);
14233
+ });
14234
+ });
14235
+ });
14236
+ });
14237
+ }
14238
+ test(version) {
14239
+ if (!version) {
14240
+ return false;
14241
+ }
14242
+ if (typeof version === "string") {
14243
+ try {
14244
+ version = new SemVer(version, this.options);
14245
+ } catch (er) {
14246
+ return false;
14247
+ }
14248
+ }
14249
+ for (let i = 0;i < this.set.length; i++) {
14250
+ if (testSet(this.set[i], version, this.options)) {
14251
+ return true;
14252
+ }
14253
+ }
14254
+ return false;
14255
+ }
14256
+ }
14257
+ module.exports = Range;
14258
+ var LRU = require_lrucache();
14259
+ var cache2 = new LRU;
14260
+ var parseOptions = require_parse_options();
14261
+ var Comparator = require_comparator();
14262
+ var debug = require_debug();
14263
+ var SemVer = require_semver();
14264
+ var {
14265
+ safeRe: re2,
14266
+ t,
14267
+ comparatorTrimReplace,
14268
+ tildeTrimReplace,
14269
+ caretTrimReplace
14270
+ } = require_re();
14271
+ var { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require_constants();
14272
+ var isNullSet = (c2) => c2.value === "<0.0.0-0";
14273
+ var isAny = (c2) => c2.value === "";
14274
+ var isSatisfiable = (comparators, options) => {
14275
+ let result = true;
14276
+ const remainingComparators = comparators.slice();
14277
+ let testComparator = remainingComparators.pop();
14278
+ while (result && remainingComparators.length) {
14279
+ result = remainingComparators.every((otherComparator) => {
14280
+ return testComparator.intersects(otherComparator, options);
14281
+ });
14282
+ testComparator = remainingComparators.pop();
14283
+ }
14284
+ return result;
14285
+ };
14286
+ var parseComparator = (comp, options) => {
14287
+ comp = comp.replace(re2[t.BUILD], "");
14288
+ debug("comp", comp, options);
14289
+ comp = replaceCarets(comp, options);
14290
+ debug("caret", comp);
14291
+ comp = replaceTildes(comp, options);
14292
+ debug("tildes", comp);
14293
+ comp = replaceXRanges(comp, options);
14294
+ debug("xrange", comp);
14295
+ comp = replaceStars(comp, options);
14296
+ debug("stars", comp);
14297
+ return comp;
14298
+ };
14299
+ var isX = (id) => !id || id.toLowerCase() === "x" || id === "*";
14300
+ var replaceTildes = (comp, options) => {
14301
+ return comp.trim().split(/\s+/).map((c2) => replaceTilde(c2, options)).join(" ");
14302
+ };
14303
+ var replaceTilde = (comp, options) => {
14304
+ const r2 = options.loose ? re2[t.TILDELOOSE] : re2[t.TILDE];
14305
+ return comp.replace(r2, (_3, M3, m2, p, pr) => {
14306
+ debug("tilde", comp, _3, M3, m2, p, pr);
14307
+ let ret;
14308
+ if (isX(M3)) {
14309
+ ret = "";
14310
+ } else if (isX(m2)) {
14311
+ ret = `>=${M3}.0.0 <${+M3 + 1}.0.0-0`;
14312
+ } else if (isX(p)) {
14313
+ ret = `>=${M3}.${m2}.0 <${M3}.${+m2 + 1}.0-0`;
14314
+ } else if (pr) {
14315
+ debug("replaceTilde pr", pr);
14316
+ ret = `>=${M3}.${m2}.${p}-${pr} <${M3}.${+m2 + 1}.0-0`;
14317
+ } else {
14318
+ ret = `>=${M3}.${m2}.${p} <${M3}.${+m2 + 1}.0-0`;
14319
+ }
14320
+ debug("tilde return", ret);
14321
+ return ret;
14322
+ });
14323
+ };
14324
+ var replaceCarets = (comp, options) => {
14325
+ return comp.trim().split(/\s+/).map((c2) => replaceCaret(c2, options)).join(" ");
14326
+ };
14327
+ var replaceCaret = (comp, options) => {
14328
+ debug("caret", comp, options);
14329
+ const r2 = options.loose ? re2[t.CARETLOOSE] : re2[t.CARET];
14330
+ const z3 = options.includePrerelease ? "-0" : "";
14331
+ return comp.replace(r2, (_3, M3, m2, p, pr) => {
14332
+ debug("caret", comp, _3, M3, m2, p, pr);
14333
+ let ret;
14334
+ if (isX(M3)) {
14335
+ ret = "";
14336
+ } else if (isX(m2)) {
14337
+ ret = `>=${M3}.0.0${z3} <${+M3 + 1}.0.0-0`;
14338
+ } else if (isX(p)) {
14339
+ if (M3 === "0") {
14340
+ ret = `>=${M3}.${m2}.0${z3} <${M3}.${+m2 + 1}.0-0`;
14341
+ } else {
14342
+ ret = `>=${M3}.${m2}.0${z3} <${+M3 + 1}.0.0-0`;
14343
+ }
14344
+ } else if (pr) {
14345
+ debug("replaceCaret pr", pr);
14346
+ if (M3 === "0") {
14347
+ if (m2 === "0") {
14348
+ ret = `>=${M3}.${m2}.${p}-${pr} <${M3}.${m2}.${+p + 1}-0`;
14349
+ } else {
14350
+ ret = `>=${M3}.${m2}.${p}-${pr} <${M3}.${+m2 + 1}.0-0`;
14351
+ }
14352
+ } else {
14353
+ ret = `>=${M3}.${m2}.${p}-${pr} <${+M3 + 1}.0.0-0`;
14354
+ }
14355
+ } else {
14356
+ debug("no pr");
14357
+ if (M3 === "0") {
14358
+ if (m2 === "0") {
14359
+ ret = `>=${M3}.${m2}.${p}${z3} <${M3}.${m2}.${+p + 1}-0`;
14360
+ } else {
14361
+ ret = `>=${M3}.${m2}.${p}${z3} <${M3}.${+m2 + 1}.0-0`;
14362
+ }
14363
+ } else {
14364
+ ret = `>=${M3}.${m2}.${p} <${+M3 + 1}.0.0-0`;
14365
+ }
14366
+ }
14367
+ debug("caret return", ret);
14368
+ return ret;
14369
+ });
14370
+ };
14371
+ var replaceXRanges = (comp, options) => {
14372
+ debug("replaceXRanges", comp, options);
14373
+ return comp.split(/\s+/).map((c2) => replaceXRange(c2, options)).join(" ");
14374
+ };
14375
+ var replaceXRange = (comp, options) => {
14376
+ comp = comp.trim();
14377
+ const r2 = options.loose ? re2[t.XRANGELOOSE] : re2[t.XRANGE];
14378
+ return comp.replace(r2, (ret, gtlt, M3, m2, p, pr) => {
14379
+ debug("xRange", comp, ret, gtlt, M3, m2, p, pr);
14380
+ const xM = isX(M3);
14381
+ const xm = xM || isX(m2);
14382
+ const xp = xm || isX(p);
14383
+ const anyX = xp;
14384
+ if (gtlt === "=" && anyX) {
14385
+ gtlt = "";
14386
+ }
14387
+ pr = options.includePrerelease ? "-0" : "";
14388
+ if (xM) {
14389
+ if (gtlt === ">" || gtlt === "<") {
14390
+ ret = "<0.0.0-0";
14391
+ } else {
14392
+ ret = "*";
14393
+ }
14394
+ } else if (gtlt && anyX) {
14395
+ if (xm) {
14396
+ m2 = 0;
14397
+ }
14398
+ p = 0;
14399
+ if (gtlt === ">") {
14400
+ gtlt = ">=";
14401
+ if (xm) {
14402
+ M3 = +M3 + 1;
14403
+ m2 = 0;
14404
+ p = 0;
14405
+ } else {
14406
+ m2 = +m2 + 1;
14407
+ p = 0;
14408
+ }
14409
+ } else if (gtlt === "<=") {
14410
+ gtlt = "<";
14411
+ if (xm) {
14412
+ M3 = +M3 + 1;
14413
+ } else {
14414
+ m2 = +m2 + 1;
14415
+ }
14416
+ }
14417
+ if (gtlt === "<") {
14418
+ pr = "-0";
14419
+ }
14420
+ ret = `${gtlt + M3}.${m2}.${p}${pr}`;
14421
+ } else if (xm) {
14422
+ ret = `>=${M3}.0.0${pr} <${+M3 + 1}.0.0-0`;
14423
+ } else if (xp) {
14424
+ ret = `>=${M3}.${m2}.0${pr} <${M3}.${+m2 + 1}.0-0`;
14425
+ }
14426
+ debug("xRange return", ret);
14427
+ return ret;
14428
+ });
14429
+ };
14430
+ var replaceStars = (comp, options) => {
14431
+ debug("replaceStars", comp, options);
14432
+ return comp.trim().replace(re2[t.STAR], "");
14433
+ };
14434
+ var replaceGTE0 = (comp, options) => {
14435
+ debug("replaceGTE0", comp, options);
14436
+ return comp.trim().replace(re2[options.includePrerelease ? t.GTE0PRE : t.GTE0], "");
14437
+ };
14438
+ var hyphenReplace = (incPr) => ($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr) => {
14439
+ if (isX(fM)) {
14440
+ from = "";
14441
+ } else if (isX(fm)) {
14442
+ from = `>=${fM}.0.0${incPr ? "-0" : ""}`;
14443
+ } else if (isX(fp)) {
14444
+ from = `>=${fM}.${fm}.0${incPr ? "-0" : ""}`;
14445
+ } else if (fpr) {
14446
+ from = `>=${from}`;
14447
+ } else {
14448
+ from = `>=${from}${incPr ? "-0" : ""}`;
14449
+ }
14450
+ if (isX(tM)) {
14451
+ to = "";
14452
+ } else if (isX(tm)) {
14453
+ to = `<${+tM + 1}.0.0-0`;
14454
+ } else if (isX(tp)) {
14455
+ to = `<${tM}.${+tm + 1}.0-0`;
14456
+ } else if (tpr) {
14457
+ to = `<=${tM}.${tm}.${tp}-${tpr}`;
14458
+ } else if (incPr) {
14459
+ to = `<${tM}.${tm}.${+tp + 1}-0`;
14460
+ } else {
14461
+ to = `<=${to}`;
14462
+ }
14463
+ return `${from} ${to}`.trim();
14464
+ };
14465
+ var testSet = (set, version, options) => {
14466
+ for (let i = 0;i < set.length; i++) {
14467
+ if (!set[i].test(version)) {
14468
+ return false;
14469
+ }
14470
+ }
14471
+ if (version.prerelease.length && !options.includePrerelease) {
14472
+ for (let i = 0;i < set.length; i++) {
14473
+ debug(set[i].semver);
14474
+ if (set[i].semver === Comparator.ANY) {
14475
+ continue;
14476
+ }
14477
+ if (set[i].semver.prerelease.length > 0) {
14478
+ const allowed = set[i].semver;
14479
+ if (allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch) {
14480
+ return true;
14481
+ }
14482
+ }
14483
+ }
14484
+ return false;
14485
+ }
14486
+ return true;
14487
+ };
14488
+ });
14489
+
14490
+ // node_modules/semver/classes/comparator.js
14491
+ var require_comparator = __commonJS((exports, module) => {
14492
+ var ANY = Symbol("SemVer ANY");
14493
+
14494
+ class Comparator {
14495
+ static get ANY() {
14496
+ return ANY;
14497
+ }
14498
+ constructor(comp, options) {
14499
+ options = parseOptions(options);
14500
+ if (comp instanceof Comparator) {
14501
+ if (comp.loose === !!options.loose) {
14502
+ return comp;
14503
+ } else {
14504
+ comp = comp.value;
14505
+ }
14506
+ }
14507
+ comp = comp.trim().split(/\s+/).join(" ");
14508
+ debug("comparator", comp, options);
14509
+ this.options = options;
14510
+ this.loose = !!options.loose;
14511
+ this.parse(comp);
14512
+ if (this.semver === ANY) {
14513
+ this.value = "";
14514
+ } else {
14515
+ this.value = this.operator + this.semver.version;
14516
+ }
14517
+ debug("comp", this);
14518
+ }
14519
+ parse(comp) {
14520
+ const r2 = this.options.loose ? re2[t.COMPARATORLOOSE] : re2[t.COMPARATOR];
14521
+ const m2 = comp.match(r2);
14522
+ if (!m2) {
14523
+ throw new TypeError(`Invalid comparator: ${comp}`);
14524
+ }
14525
+ this.operator = m2[1] !== undefined ? m2[1] : "";
14526
+ if (this.operator === "=") {
14527
+ this.operator = "";
14528
+ }
14529
+ if (!m2[2]) {
14530
+ this.semver = ANY;
14531
+ } else {
14532
+ this.semver = new SemVer(m2[2], this.options.loose);
14533
+ }
14534
+ }
14535
+ toString() {
14536
+ return this.value;
14537
+ }
14538
+ test(version) {
14539
+ debug("Comparator.test", version, this.options.loose);
14540
+ if (this.semver === ANY || version === ANY) {
14541
+ return true;
14542
+ }
14543
+ if (typeof version === "string") {
14544
+ try {
14545
+ version = new SemVer(version, this.options);
14546
+ } catch (er) {
14547
+ return false;
14548
+ }
14549
+ }
14550
+ return cmp(version, this.operator, this.semver, this.options);
14551
+ }
14552
+ intersects(comp, options) {
14553
+ if (!(comp instanceof Comparator)) {
14554
+ throw new TypeError("a Comparator is required");
14555
+ }
14556
+ if (this.operator === "") {
14557
+ if (this.value === "") {
14558
+ return true;
14559
+ }
14560
+ return new Range(comp.value, options).test(this.value);
14561
+ } else if (comp.operator === "") {
14562
+ if (comp.value === "") {
14563
+ return true;
14564
+ }
14565
+ return new Range(this.value, options).test(comp.semver);
14566
+ }
14567
+ options = parseOptions(options);
14568
+ if (options.includePrerelease && (this.value === "<0.0.0-0" || comp.value === "<0.0.0-0")) {
14569
+ return false;
14570
+ }
14571
+ if (!options.includePrerelease && (this.value.startsWith("<0.0.0") || comp.value.startsWith("<0.0.0"))) {
14572
+ return false;
14573
+ }
14574
+ if (this.operator.startsWith(">") && comp.operator.startsWith(">")) {
14575
+ return true;
14576
+ }
14577
+ if (this.operator.startsWith("<") && comp.operator.startsWith("<")) {
14578
+ return true;
14579
+ }
14580
+ if (this.semver.version === comp.semver.version && this.operator.includes("=") && comp.operator.includes("=")) {
14581
+ return true;
14582
+ }
14583
+ if (cmp(this.semver, "<", comp.semver, options) && this.operator.startsWith(">") && comp.operator.startsWith("<")) {
14584
+ return true;
14585
+ }
14586
+ if (cmp(this.semver, ">", comp.semver, options) && this.operator.startsWith("<") && comp.operator.startsWith(">")) {
14587
+ return true;
14588
+ }
14589
+ return false;
14590
+ }
14591
+ }
14592
+ module.exports = Comparator;
14593
+ var parseOptions = require_parse_options();
14594
+ var { safeRe: re2, t } = require_re();
14595
+ var cmp = require_cmp();
14596
+ var debug = require_debug();
14597
+ var SemVer = require_semver();
14598
+ var Range = require_range();
14599
+ });
14600
+
14601
+ // node_modules/semver/functions/satisfies.js
14602
+ var require_satisfies = __commonJS((exports, module) => {
14603
+ var Range = require_range();
14604
+ var satisfies = (version, range, options) => {
14605
+ try {
14606
+ range = new Range(range, options);
14607
+ } catch (er) {
14608
+ return false;
14609
+ }
14610
+ return range.test(version);
14611
+ };
14612
+ module.exports = satisfies;
14613
+ });
14614
+
14615
+ // node_modules/semver/ranges/to-comparators.js
14616
+ var require_to_comparators = __commonJS((exports, module) => {
14617
+ var Range = require_range();
14618
+ var toComparators = (range, options) => new Range(range, options).set.map((comp) => comp.map((c2) => c2.value).join(" ").trim().split(" "));
14619
+ module.exports = toComparators;
14620
+ });
14621
+
14622
+ // node_modules/semver/ranges/max-satisfying.js
14623
+ var require_max_satisfying = __commonJS((exports, module) => {
14624
+ var SemVer = require_semver();
14625
+ var Range = require_range();
14626
+ var maxSatisfying = (versions, range, options) => {
14627
+ let max = null;
14628
+ let maxSV = null;
14629
+ let rangeObj = null;
14630
+ try {
14631
+ rangeObj = new Range(range, options);
14632
+ } catch (er) {
14633
+ return null;
14634
+ }
14635
+ versions.forEach((v2) => {
14636
+ if (rangeObj.test(v2)) {
14637
+ if (!max || maxSV.compare(v2) === -1) {
14638
+ max = v2;
14639
+ maxSV = new SemVer(max, options);
14640
+ }
14641
+ }
14642
+ });
14643
+ return max;
14644
+ };
14645
+ module.exports = maxSatisfying;
14646
+ });
14647
+
14648
+ // node_modules/semver/ranges/min-satisfying.js
14649
+ var require_min_satisfying = __commonJS((exports, module) => {
14650
+ var SemVer = require_semver();
14651
+ var Range = require_range();
14652
+ var minSatisfying = (versions, range, options) => {
14653
+ let min = null;
14654
+ let minSV = null;
14655
+ let rangeObj = null;
14656
+ try {
14657
+ rangeObj = new Range(range, options);
14658
+ } catch (er) {
14659
+ return null;
14660
+ }
14661
+ versions.forEach((v2) => {
14662
+ if (rangeObj.test(v2)) {
14663
+ if (!min || minSV.compare(v2) === 1) {
14664
+ min = v2;
14665
+ minSV = new SemVer(min, options);
14666
+ }
14667
+ }
14668
+ });
14669
+ return min;
14670
+ };
14671
+ module.exports = minSatisfying;
14672
+ });
14673
+
14674
+ // node_modules/semver/ranges/min-version.js
14675
+ var require_min_version = __commonJS((exports, module) => {
14676
+ var SemVer = require_semver();
14677
+ var Range = require_range();
14678
+ var gt = require_gt();
14679
+ var minVersion = (range, loose) => {
14680
+ range = new Range(range, loose);
14681
+ let minver = new SemVer("0.0.0");
14682
+ if (range.test(minver)) {
14683
+ return minver;
14684
+ }
14685
+ minver = new SemVer("0.0.0-0");
14686
+ if (range.test(minver)) {
14687
+ return minver;
14688
+ }
14689
+ minver = null;
14690
+ for (let i = 0;i < range.set.length; ++i) {
14691
+ const comparators = range.set[i];
14692
+ let setMin = null;
14693
+ comparators.forEach((comparator) => {
14694
+ const compver = new SemVer(comparator.semver.version);
14695
+ switch (comparator.operator) {
14696
+ case ">":
14697
+ if (compver.prerelease.length === 0) {
14698
+ compver.patch++;
14699
+ } else {
14700
+ compver.prerelease.push(0);
14701
+ }
14702
+ compver.raw = compver.format();
14703
+ case "":
14704
+ case ">=":
14705
+ if (!setMin || gt(compver, setMin)) {
14706
+ setMin = compver;
14707
+ }
14708
+ break;
14709
+ case "<":
14710
+ case "<=":
14711
+ break;
14712
+ default:
14713
+ throw new Error(`Unexpected operation: ${comparator.operator}`);
14714
+ }
14715
+ });
14716
+ if (setMin && (!minver || gt(minver, setMin))) {
14717
+ minver = setMin;
14718
+ }
14719
+ }
14720
+ if (minver && range.test(minver)) {
14721
+ return minver;
14722
+ }
14723
+ return null;
14724
+ };
14725
+ module.exports = minVersion;
14726
+ });
14727
+
14728
+ // node_modules/semver/ranges/valid.js
14729
+ var require_valid2 = __commonJS((exports, module) => {
14730
+ var Range = require_range();
14731
+ var validRange = (range, options) => {
14732
+ try {
14733
+ return new Range(range, options).range || "*";
14734
+ } catch (er) {
14735
+ return null;
14736
+ }
14737
+ };
14738
+ module.exports = validRange;
14739
+ });
14740
+
14741
+ // node_modules/semver/ranges/outside.js
14742
+ var require_outside = __commonJS((exports, module) => {
14743
+ var SemVer = require_semver();
14744
+ var Comparator = require_comparator();
14745
+ var { ANY } = Comparator;
14746
+ var Range = require_range();
14747
+ var satisfies = require_satisfies();
14748
+ var gt = require_gt();
14749
+ var lt = require_lt();
14750
+ var lte = require_lte();
14751
+ var gte = require_gte();
14752
+ var outside = (version, range, hilo, options) => {
14753
+ version = new SemVer(version, options);
14754
+ range = new Range(range, options);
14755
+ let gtfn, ltefn, ltfn, comp, ecomp;
14756
+ switch (hilo) {
14757
+ case ">":
14758
+ gtfn = gt;
14759
+ ltefn = lte;
14760
+ ltfn = lt;
14761
+ comp = ">";
14762
+ ecomp = ">=";
14763
+ break;
14764
+ case "<":
14765
+ gtfn = lt;
14766
+ ltefn = gte;
14767
+ ltfn = gt;
14768
+ comp = "<";
14769
+ ecomp = "<=";
14770
+ break;
14771
+ default:
14772
+ throw new TypeError('Must provide a hilo val of "<" or ">"');
14773
+ }
14774
+ if (satisfies(version, range, options)) {
14775
+ return false;
14776
+ }
14777
+ for (let i = 0;i < range.set.length; ++i) {
14778
+ const comparators = range.set[i];
14779
+ let high = null;
14780
+ let low = null;
14781
+ comparators.forEach((comparator) => {
14782
+ if (comparator.semver === ANY) {
14783
+ comparator = new Comparator(">=0.0.0");
14784
+ }
14785
+ high = high || comparator;
14786
+ low = low || comparator;
14787
+ if (gtfn(comparator.semver, high.semver, options)) {
14788
+ high = comparator;
14789
+ } else if (ltfn(comparator.semver, low.semver, options)) {
14790
+ low = comparator;
14791
+ }
14792
+ });
14793
+ if (high.operator === comp || high.operator === ecomp) {
14794
+ return false;
14795
+ }
14796
+ if ((!low.operator || low.operator === comp) && ltefn(version, low.semver)) {
14797
+ return false;
14798
+ } else if (low.operator === ecomp && ltfn(version, low.semver)) {
14799
+ return false;
14800
+ }
14801
+ }
14802
+ return true;
14803
+ };
14804
+ module.exports = outside;
14805
+ });
14806
+
14807
+ // node_modules/semver/ranges/gtr.js
14808
+ var require_gtr = __commonJS((exports, module) => {
14809
+ var outside = require_outside();
14810
+ var gtr = (version, range, options) => outside(version, range, ">", options);
14811
+ module.exports = gtr;
14812
+ });
14813
+
14814
+ // node_modules/semver/ranges/ltr.js
14815
+ var require_ltr = __commonJS((exports, module) => {
14816
+ var outside = require_outside();
14817
+ var ltr = (version, range, options) => outside(version, range, "<", options);
14818
+ module.exports = ltr;
14819
+ });
14820
+
14821
+ // node_modules/semver/ranges/intersects.js
14822
+ var require_intersects = __commonJS((exports, module) => {
14823
+ var Range = require_range();
14824
+ var intersects = (r1, r2, options) => {
14825
+ r1 = new Range(r1, options);
14826
+ r2 = new Range(r2, options);
14827
+ return r1.intersects(r2, options);
14828
+ };
14829
+ module.exports = intersects;
14830
+ });
14831
+
14832
+ // node_modules/semver/ranges/simplify.js
14833
+ var require_simplify = __commonJS((exports, module) => {
14834
+ var satisfies = require_satisfies();
14835
+ var compare = require_compare();
14836
+ module.exports = (versions, range, options) => {
14837
+ const set = [];
14838
+ let first = null;
14839
+ let prev = null;
14840
+ const v2 = versions.sort((a3, b3) => compare(a3, b3, options));
14841
+ for (const version of v2) {
14842
+ const included = satisfies(version, range, options);
14843
+ if (included) {
14844
+ prev = version;
14845
+ if (!first) {
14846
+ first = version;
14847
+ }
14848
+ } else {
14849
+ if (prev) {
14850
+ set.push([first, prev]);
14851
+ }
14852
+ prev = null;
14853
+ first = null;
14854
+ }
14855
+ }
14856
+ if (first) {
14857
+ set.push([first, null]);
14858
+ }
14859
+ const ranges = [];
14860
+ for (const [min, max] of set) {
14861
+ if (min === max) {
14862
+ ranges.push(min);
14863
+ } else if (!max && min === v2[0]) {
14864
+ ranges.push("*");
14865
+ } else if (!max) {
14866
+ ranges.push(`>=${min}`);
14867
+ } else if (min === v2[0]) {
14868
+ ranges.push(`<=${max}`);
14869
+ } else {
14870
+ ranges.push(`${min} - ${max}`);
14871
+ }
14872
+ }
14873
+ const simplified = ranges.join(" || ");
14874
+ const original = typeof range.raw === "string" ? range.raw : String(range);
14875
+ return simplified.length < original.length ? simplified : range;
14876
+ };
14877
+ });
14878
+
14879
+ // node_modules/semver/ranges/subset.js
14880
+ var require_subset = __commonJS((exports, module) => {
14881
+ var Range = require_range();
14882
+ var Comparator = require_comparator();
14883
+ var { ANY } = Comparator;
14884
+ var satisfies = require_satisfies();
14885
+ var compare = require_compare();
14886
+ var subset = (sub, dom, options = {}) => {
14887
+ if (sub === dom) {
14888
+ return true;
14889
+ }
14890
+ sub = new Range(sub, options);
14891
+ dom = new Range(dom, options);
14892
+ let sawNonNull = false;
14893
+ OUTER:
14894
+ for (const simpleSub of sub.set) {
14895
+ for (const simpleDom of dom.set) {
14896
+ const isSub = simpleSubset(simpleSub, simpleDom, options);
14897
+ sawNonNull = sawNonNull || isSub !== null;
14898
+ if (isSub) {
14899
+ continue OUTER;
14900
+ }
14901
+ }
14902
+ if (sawNonNull) {
14903
+ return false;
14904
+ }
14905
+ }
14906
+ return true;
14907
+ };
14908
+ var minimumVersionWithPreRelease = [new Comparator(">=0.0.0-0")];
14909
+ var minimumVersion = [new Comparator(">=0.0.0")];
14910
+ var simpleSubset = (sub, dom, options) => {
14911
+ if (sub === dom) {
14912
+ return true;
14913
+ }
14914
+ if (sub.length === 1 && sub[0].semver === ANY) {
14915
+ if (dom.length === 1 && dom[0].semver === ANY) {
14916
+ return true;
14917
+ } else if (options.includePrerelease) {
14918
+ sub = minimumVersionWithPreRelease;
14919
+ } else {
14920
+ sub = minimumVersion;
14921
+ }
14922
+ }
14923
+ if (dom.length === 1 && dom[0].semver === ANY) {
14924
+ if (options.includePrerelease) {
14925
+ return true;
14926
+ } else {
14927
+ dom = minimumVersion;
14928
+ }
14929
+ }
14930
+ const eqSet = new Set;
14931
+ let gt, lt;
14932
+ for (const c2 of sub) {
14933
+ if (c2.operator === ">" || c2.operator === ">=") {
14934
+ gt = higherGT(gt, c2, options);
14935
+ } else if (c2.operator === "<" || c2.operator === "<=") {
14936
+ lt = lowerLT(lt, c2, options);
14937
+ } else {
14938
+ eqSet.add(c2.semver);
14939
+ }
14940
+ }
14941
+ if (eqSet.size > 1) {
14942
+ return null;
14943
+ }
14944
+ let gtltComp;
14945
+ if (gt && lt) {
14946
+ gtltComp = compare(gt.semver, lt.semver, options);
14947
+ if (gtltComp > 0) {
14948
+ return null;
14949
+ } else if (gtltComp === 0 && (gt.operator !== ">=" || lt.operator !== "<=")) {
14950
+ return null;
14951
+ }
14952
+ }
14953
+ for (const eq of eqSet) {
14954
+ if (gt && !satisfies(eq, String(gt), options)) {
14955
+ return null;
14956
+ }
14957
+ if (lt && !satisfies(eq, String(lt), options)) {
14958
+ return null;
14959
+ }
14960
+ for (const c2 of dom) {
14961
+ if (!satisfies(eq, String(c2), options)) {
14962
+ return false;
14963
+ }
14964
+ }
14965
+ return true;
14966
+ }
14967
+ let higher, lower;
14968
+ let hasDomLT, hasDomGT;
14969
+ let needDomLTPre = lt && !options.includePrerelease && lt.semver.prerelease.length ? lt.semver : false;
14970
+ let needDomGTPre = gt && !options.includePrerelease && gt.semver.prerelease.length ? gt.semver : false;
14971
+ if (needDomLTPre && needDomLTPre.prerelease.length === 1 && lt.operator === "<" && needDomLTPre.prerelease[0] === 0) {
14972
+ needDomLTPre = false;
14973
+ }
14974
+ for (const c2 of dom) {
14975
+ hasDomGT = hasDomGT || c2.operator === ">" || c2.operator === ">=";
14976
+ hasDomLT = hasDomLT || c2.operator === "<" || c2.operator === "<=";
14977
+ if (gt) {
14978
+ if (needDomGTPre) {
14979
+ if (c2.semver.prerelease && c2.semver.prerelease.length && c2.semver.major === needDomGTPre.major && c2.semver.minor === needDomGTPre.minor && c2.semver.patch === needDomGTPre.patch) {
14980
+ needDomGTPre = false;
14981
+ }
14982
+ }
14983
+ if (c2.operator === ">" || c2.operator === ">=") {
14984
+ higher = higherGT(gt, c2, options);
14985
+ if (higher === c2 && higher !== gt) {
14986
+ return false;
14987
+ }
14988
+ } else if (gt.operator === ">=" && !satisfies(gt.semver, String(c2), options)) {
14989
+ return false;
14990
+ }
14991
+ }
14992
+ if (lt) {
14993
+ if (needDomLTPre) {
14994
+ if (c2.semver.prerelease && c2.semver.prerelease.length && c2.semver.major === needDomLTPre.major && c2.semver.minor === needDomLTPre.minor && c2.semver.patch === needDomLTPre.patch) {
14995
+ needDomLTPre = false;
14996
+ }
14997
+ }
14998
+ if (c2.operator === "<" || c2.operator === "<=") {
14999
+ lower = lowerLT(lt, c2, options);
15000
+ if (lower === c2 && lower !== lt) {
15001
+ return false;
15002
+ }
15003
+ } else if (lt.operator === "<=" && !satisfies(lt.semver, String(c2), options)) {
15004
+ return false;
15005
+ }
15006
+ }
15007
+ if (!c2.operator && (lt || gt) && gtltComp !== 0) {
15008
+ return false;
15009
+ }
15010
+ }
15011
+ if (gt && hasDomLT && !lt && gtltComp !== 0) {
15012
+ return false;
15013
+ }
15014
+ if (lt && hasDomGT && !gt && gtltComp !== 0) {
15015
+ return false;
15016
+ }
15017
+ if (needDomGTPre || needDomLTPre) {
15018
+ return false;
15019
+ }
15020
+ return true;
15021
+ };
15022
+ var higherGT = (a3, b3, options) => {
15023
+ if (!a3) {
15024
+ return b3;
15025
+ }
15026
+ const comp = compare(a3.semver, b3.semver, options);
15027
+ return comp > 0 ? a3 : comp < 0 ? b3 : b3.operator === ">" && a3.operator === ">=" ? b3 : a3;
15028
+ };
15029
+ var lowerLT = (a3, b3, options) => {
15030
+ if (!a3) {
15031
+ return b3;
15032
+ }
15033
+ const comp = compare(a3.semver, b3.semver, options);
15034
+ return comp < 0 ? a3 : comp > 0 ? b3 : b3.operator === "<" && a3.operator === "<=" ? b3 : a3;
15035
+ };
15036
+ module.exports = subset;
15037
+ });
15038
+
15039
+ // node_modules/semver/index.js
15040
+ var require_semver2 = __commonJS((exports, module) => {
15041
+ var internalRe = require_re();
15042
+ var constants5 = require_constants();
15043
+ var SemVer = require_semver();
15044
+ var identifiers = require_identifiers();
15045
+ var parse5 = require_parse();
15046
+ var valid = require_valid();
15047
+ var clean = require_clean();
15048
+ var inc = require_inc();
15049
+ var diff = require_diff();
15050
+ var major = require_major();
15051
+ var minor = require_minor();
15052
+ var patch = require_patch();
15053
+ var prerelease = require_prerelease();
15054
+ var compare = require_compare();
15055
+ var rcompare = require_rcompare();
15056
+ var compareLoose = require_compare_loose();
15057
+ var compareBuild = require_compare_build();
15058
+ var sort = require_sort();
15059
+ var rsort = require_rsort();
15060
+ var gt = require_gt();
15061
+ var lt = require_lt();
15062
+ var eq = require_eq();
15063
+ var neq = require_neq();
15064
+ var gte = require_gte();
15065
+ var lte = require_lte();
15066
+ var cmp = require_cmp();
15067
+ var coerce2 = require_coerce();
15068
+ var Comparator = require_comparator();
15069
+ var Range = require_range();
15070
+ var satisfies = require_satisfies();
15071
+ var toComparators = require_to_comparators();
15072
+ var maxSatisfying = require_max_satisfying();
15073
+ var minSatisfying = require_min_satisfying();
15074
+ var minVersion = require_min_version();
15075
+ var validRange = require_valid2();
15076
+ var outside = require_outside();
15077
+ var gtr = require_gtr();
15078
+ var ltr = require_ltr();
15079
+ var intersects = require_intersects();
15080
+ var simplifyRange = require_simplify();
15081
+ var subset = require_subset();
15082
+ module.exports = {
15083
+ parse: parse5,
15084
+ valid,
15085
+ clean,
15086
+ inc,
15087
+ diff,
15088
+ major,
15089
+ minor,
15090
+ patch,
15091
+ prerelease,
15092
+ compare,
15093
+ rcompare,
15094
+ compareLoose,
15095
+ compareBuild,
15096
+ sort,
15097
+ rsort,
15098
+ gt,
15099
+ lt,
15100
+ eq,
15101
+ neq,
15102
+ gte,
15103
+ lte,
15104
+ cmp,
15105
+ coerce: coerce2,
15106
+ Comparator,
15107
+ Range,
15108
+ satisfies,
15109
+ toComparators,
15110
+ maxSatisfying,
15111
+ minSatisfying,
15112
+ minVersion,
15113
+ validRange,
15114
+ outside,
15115
+ gtr,
15116
+ ltr,
15117
+ intersects,
15118
+ simplifyRange,
15119
+ subset,
15120
+ SemVer,
15121
+ re: internalRe.re,
15122
+ src: internalRe.src,
15123
+ tokens: internalRe.t,
15124
+ SEMVER_SPEC_VERSION: constants5.SEMVER_SPEC_VERSION,
15125
+ RELEASE_TYPES: constants5.RELEASE_TYPES,
15126
+ compareIdentifiers: identifiers.compareIdentifiers,
15127
+ rcompareIdentifiers: identifiers.rcompareIdentifiers
15128
+ };
15129
+ });
15130
+
13344
15131
  // node_modules/retry/lib/retry_operation.js
13345
15132
  var require_retry_operation = __commonJS((exports, module) => {
13346
15133
  function RetryOperation(timeouts, options) {
@@ -14093,25 +15880,25 @@ class OwnershipDisplay {
14093
15880
  static formatOwnership(ownership) {
14094
15881
  switch (ownership) {
14095
15882
  case "ck":
14096
- return import_picocolors17.default.blue("CK-owned");
15883
+ return import_picocolors18.default.blue("CK-owned");
14097
15884
  case "user":
14098
- return import_picocolors17.default.green("User-created");
15885
+ return import_picocolors18.default.green("User-created");
14099
15886
  case "ck-modified":
14100
- return import_picocolors17.default.yellow("CK-modified");
15887
+ return import_picocolors18.default.yellow("CK-modified");
14101
15888
  default:
14102
- return import_picocolors17.default.gray("Unknown");
15889
+ return import_picocolors18.default.gray("Unknown");
14103
15890
  }
14104
15891
  }
14105
15892
  static formatAction(action) {
14106
15893
  switch (action) {
14107
15894
  case "delete":
14108
- return import_picocolors17.default.red("✖ DELETE");
15895
+ return import_picocolors18.default.red("✖ DELETE");
14109
15896
  case "preserve":
14110
- return import_picocolors17.default.green("✓ PRESERVE");
15897
+ return import_picocolors18.default.green("✓ PRESERVE");
14111
15898
  case "skip":
14112
- return import_picocolors17.default.gray("○ SKIP");
15899
+ return import_picocolors18.default.gray("○ SKIP");
14113
15900
  default:
14114
- return import_picocolors17.default.gray("? UNKNOWN");
15901
+ return import_picocolors18.default.gray("? UNKNOWN");
14115
15902
  }
14116
15903
  }
14117
15904
  static calculateSummary(results) {
@@ -14145,78 +15932,78 @@ class OwnershipDisplay {
14145
15932
  }
14146
15933
  static displaySummary(summary, title = "Ownership Summary") {
14147
15934
  const lines = [
14148
- `Total files: ${import_picocolors17.default.bold(String(summary.totalFiles))}`,
15935
+ `Total files: ${import_picocolors18.default.bold(String(summary.totalFiles))}`,
14149
15936
  "",
14150
15937
  "By ownership:",
14151
- ` ${import_picocolors17.default.blue("●")} CK-owned: ${summary.ckOwned}`,
14152
- ` ${import_picocolors17.default.green("●")} User-created: ${summary.userCreated}`,
14153
- ` ${import_picocolors17.default.yellow("●")} CK-modified: ${summary.ckModified}`,
15938
+ ` ${import_picocolors18.default.blue("●")} CK-owned: ${summary.ckOwned}`,
15939
+ ` ${import_picocolors18.default.green("●")} User-created: ${summary.userCreated}`,
15940
+ ` ${import_picocolors18.default.yellow("●")} CK-modified: ${summary.ckModified}`,
14154
15941
  "",
14155
15942
  "Actions:",
14156
- ` ${import_picocolors17.default.red("✖")} To delete: ${summary.toDelete}`,
14157
- ` ${import_picocolors17.default.green("✓")} To preserve: ${summary.toPreserve}`
15943
+ ` ${import_picocolors18.default.red("✖")} To delete: ${summary.toDelete}`,
15944
+ ` ${import_picocolors18.default.green("✓")} To preserve: ${summary.toPreserve}`
14158
15945
  ];
14159
15946
  le(lines.join(`
14160
15947
  `), title);
14161
15948
  }
14162
15949
  static displayOperationPreview(results, maxItems = 10) {
14163
15950
  const summary = OwnershipDisplay.calculateSummary(results);
14164
- f2.info(import_picocolors17.default.bold("DRY RUN - Preview of changes:"));
15951
+ f2.info(import_picocolors18.default.bold("DRY RUN - Preview of changes:"));
14165
15952
  console.log("");
14166
15953
  const toDelete = results.filter((r2) => r2.action === "delete");
14167
15954
  const toPreserve = results.filter((r2) => r2.action === "preserve");
14168
15955
  if (toDelete.length > 0) {
14169
- console.log(import_picocolors17.default.red(import_picocolors17.default.bold(`Files to DELETE (${toDelete.length}):`)));
15956
+ console.log(import_picocolors18.default.red(import_picocolors18.default.bold(`Files to DELETE (${toDelete.length}):`)));
14170
15957
  const showDelete = toDelete.slice(0, maxItems);
14171
15958
  for (const result of showDelete) {
14172
- console.log(` ${import_picocolors17.default.red("✖")} ${result.path}`);
15959
+ console.log(` ${import_picocolors18.default.red("✖")} ${result.path}`);
14173
15960
  }
14174
15961
  if (toDelete.length > maxItems) {
14175
- console.log(import_picocolors17.default.gray(` ... and ${toDelete.length - maxItems} more`));
15962
+ console.log(import_picocolors18.default.gray(` ... and ${toDelete.length - maxItems} more`));
14176
15963
  }
14177
15964
  console.log("");
14178
15965
  }
14179
15966
  if (toPreserve.length > 0) {
14180
- console.log(import_picocolors17.default.green(import_picocolors17.default.bold(`Files to PRESERVE (${toPreserve.length}):`)));
15967
+ console.log(import_picocolors18.default.green(import_picocolors18.default.bold(`Files to PRESERVE (${toPreserve.length}):`)));
14181
15968
  const showPreserve = toPreserve.slice(0, maxItems);
14182
15969
  for (const result of showPreserve) {
14183
- const reason = result.reason ? import_picocolors17.default.gray(` (${result.reason})`) : "";
14184
- console.log(` ${import_picocolors17.default.green("✓")} ${result.path}${reason}`);
15970
+ const reason = result.reason ? import_picocolors18.default.gray(` (${result.reason})`) : "";
15971
+ console.log(` ${import_picocolors18.default.green("✓")} ${result.path}${reason}`);
14185
15972
  }
14186
15973
  if (toPreserve.length > maxItems) {
14187
- console.log(import_picocolors17.default.gray(` ... and ${toPreserve.length - maxItems} more`));
15974
+ console.log(import_picocolors18.default.gray(` ... and ${toPreserve.length - maxItems} more`));
14188
15975
  }
14189
15976
  console.log("");
14190
15977
  }
14191
15978
  OwnershipDisplay.displaySummary(summary, "Preview Summary");
14192
- f2.warn(import_picocolors17.default.yellow("No changes were made. Run without --dry-run to apply changes."));
15979
+ f2.warn(import_picocolors18.default.yellow("No changes were made. Run without --dry-run to apply changes."));
14193
15980
  }
14194
15981
  static displayFile(path11, ownership, action, reason) {
14195
15982
  const ownershipStr = OwnershipDisplay.formatOwnership(ownership);
14196
15983
  const actionStr = OwnershipDisplay.formatAction(action);
14197
- const reasonStr = reason ? import_picocolors17.default.gray(` - ${reason}`) : "";
15984
+ const reasonStr = reason ? import_picocolors18.default.gray(` - ${reason}`) : "";
14198
15985
  console.log(` ${actionStr} ${path11} [${ownershipStr}]${reasonStr}`);
14199
15986
  }
14200
15987
  static displayForceWarning() {
14201
- f2.warn(`${import_picocolors17.default.yellow(import_picocolors17.default.bold("FORCE MODE ENABLED"))}
14202
- ${import_picocolors17.default.yellow("User modifications will be overwritten!")}
14203
- ${import_picocolors17.default.gray("Use --dry-run first to preview changes.")}`);
15988
+ f2.warn(`${import_picocolors18.default.yellow(import_picocolors18.default.bold("FORCE MODE ENABLED"))}
15989
+ ${import_picocolors18.default.yellow("User modifications will be overwritten!")}
15990
+ ${import_picocolors18.default.gray("Use --dry-run first to preview changes.")}`);
14204
15991
  }
14205
15992
  static displayLegacyWarning() {
14206
- f2.warn(`${import_picocolors17.default.yellow(import_picocolors17.default.bold("Legacy Installation Detected"))}
14207
- ${import_picocolors17.default.yellow("No ownership metadata found.")}
14208
- ${import_picocolors17.default.gray("Running migration to enable ownership tracking...")}`);
15993
+ f2.warn(`${import_picocolors18.default.yellow(import_picocolors18.default.bold("Legacy Installation Detected"))}
15994
+ ${import_picocolors18.default.yellow("No ownership metadata found.")}
15995
+ ${import_picocolors18.default.gray("Running migration to enable ownership tracking...")}`);
14209
15996
  }
14210
15997
  static displayCompletionSummary(deleted, preserved) {
14211
- const message = `${import_picocolors17.default.green(`✓ Deleted ${deleted} CK-owned file(s)`)}
14212
- ${import_picocolors17.default.blue(`✓ Preserved ${preserved} user/modified file(s)`)}`;
15998
+ const message = `${import_picocolors18.default.green(`✓ Deleted ${deleted} CK-owned file(s)`)}
15999
+ ${import_picocolors18.default.blue(`✓ Preserved ${preserved} user/modified file(s)`)}`;
14213
16000
  f2.success(message);
14214
16001
  }
14215
16002
  }
14216
- var import_picocolors17;
16003
+ var import_picocolors18;
14217
16004
  var init_ownership_display = __esm(() => {
14218
16005
  init_dist2();
14219
- import_picocolors17 = __toESM(require_picocolors(), 1);
16006
+ import_picocolors18 = __toESM(require_picocolors(), 1);
14220
16007
  });
14221
16008
 
14222
16009
  // src/domains/help/commands/common-options.ts
@@ -14734,22 +16521,22 @@ function padEnd(text, width) {
14734
16521
  const padding = Math.max(0, width - visibleLength);
14735
16522
  return text + " ".repeat(padding);
14736
16523
  }
14737
- var import_picocolors27, NO_COLOR, isColorSupported, identity = (text) => text, colors, defaultTheme;
16524
+ var import_picocolors28, NO_COLOR, isColorSupported, identity = (text) => text, colors, defaultTheme;
14738
16525
  var init_help_colors = __esm(() => {
14739
- import_picocolors27 = __toESM(require_picocolors(), 1);
16526
+ import_picocolors28 = __toESM(require_picocolors(), 1);
14740
16527
  NO_COLOR = process.env.NO_COLOR !== undefined;
14741
16528
  isColorSupported = !NO_COLOR && Boolean(process.stdout.isTTY);
14742
16529
  colors = {
14743
- banner: isColorSupported ? import_picocolors27.default.cyan : identity,
14744
- command: isColorSupported ? import_picocolors27.default.bold : identity,
14745
- heading: isColorSupported ? import_picocolors27.default.yellow : identity,
14746
- flag: isColorSupported ? import_picocolors27.default.green : identity,
14747
- description: isColorSupported ? import_picocolors27.default.gray : identity,
14748
- example: isColorSupported ? import_picocolors27.default.blue : identity,
14749
- warning: isColorSupported ? import_picocolors27.default.yellow : identity,
14750
- error: isColorSupported ? import_picocolors27.default.red : identity,
14751
- muted: isColorSupported ? import_picocolors27.default.dim : identity,
14752
- success: isColorSupported ? import_picocolors27.default.green : identity
16530
+ banner: isColorSupported ? import_picocolors28.default.cyan : identity,
16531
+ command: isColorSupported ? import_picocolors28.default.bold : identity,
16532
+ heading: isColorSupported ? import_picocolors28.default.yellow : identity,
16533
+ flag: isColorSupported ? import_picocolors28.default.green : identity,
16534
+ description: isColorSupported ? import_picocolors28.default.gray : identity,
16535
+ example: isColorSupported ? import_picocolors28.default.blue : identity,
16536
+ warning: isColorSupported ? import_picocolors28.default.yellow : identity,
16537
+ error: isColorSupported ? import_picocolors28.default.red : identity,
16538
+ muted: isColorSupported ? import_picocolors28.default.dim : identity,
16539
+ success: isColorSupported ? import_picocolors28.default.green : identity
14753
16540
  };
14754
16541
  defaultTheme = {
14755
16542
  banner: colors.banner,
@@ -17707,11 +19494,15 @@ async function checkPathRefsValid(projectDir) {
17707
19494
  const broken = [];
17708
19495
  for (const ref of refs) {
17709
19496
  let refPath;
17710
- if (ref.startsWith("$HOME") || ref.startsWith("%USERPROFILE%")) {
17711
- refPath = normalize3(ref.replace("$HOME", home).replace("%USERPROFILE%", home));
19497
+ if (ref.startsWith("$HOME") || ref.startsWith("${HOME}") || ref.startsWith("%USERPROFILE%")) {
19498
+ refPath = normalize3(ref.replace(/^\$\{?HOME\}?/, home).replace("%USERPROFILE%", home));
19499
+ } else if (ref.startsWith("$CLAUDE_PROJECT_DIR") || ref.startsWith("${CLAUDE_PROJECT_DIR}") || ref.startsWith("%CLAUDE_PROJECT_DIR%")) {
19500
+ refPath = normalize3(ref.replace(/^\$\{?CLAUDE_PROJECT_DIR\}?/, projectDir).replace("%CLAUDE_PROJECT_DIR%", projectDir));
19501
+ } else if (ref.startsWith("~")) {
19502
+ refPath = normalize3(ref.replace(/^~/, home));
17712
19503
  } else if (ref.startsWith("/")) {
17713
19504
  refPath = normalize3(ref);
17714
- } else if (ref.includes(":") && ref.startsWith("\\")) {
19505
+ } else if (/^[A-Za-z]:/.test(ref)) {
17715
19506
  refPath = normalize3(ref);
17716
19507
  } else {
17717
19508
  refPath = resolve(baseDir, ref);
@@ -17719,7 +19510,7 @@ async function checkPathRefsValid(projectDir) {
17719
19510
  const normalizedPath = normalize3(refPath);
17720
19511
  const isWithinHome = normalizedPath.startsWith(home);
17721
19512
  const isWithinBase = normalizedPath.startsWith(normalize3(baseDir));
17722
- const isAbsoluteAllowed = ref.startsWith("/") || ref.includes(":") && ref.startsWith("\\");
19513
+ const isAbsoluteAllowed = ref.startsWith("/") || /^[A-Za-z]:/.test(ref);
17723
19514
  if (!isWithinHome && !isWithinBase && !isAbsoluteAllowed) {
17724
19515
  logger.verbose("Skipping potentially unsafe path reference", { ref, refPath });
17725
19516
  continue;
@@ -22114,13 +23905,14 @@ init_logger();
22114
23905
 
22115
23906
  // src/domains/ui/prompts/kit-prompts.ts
22116
23907
  init_types2();
22117
- async function selectKit(defaultKit) {
23908
+ async function selectKit(defaultKit, accessibleKits) {
23909
+ const kits = accessibleKits ?? Object.keys(AVAILABLE_KITS);
22118
23910
  const kit = await ie({
22119
23911
  message: "Select a ClaudeKit:",
22120
- options: Object.entries(AVAILABLE_KITS).map(([key, config]) => ({
23912
+ options: kits.map((key) => ({
22121
23913
  value: key,
22122
- label: config.name,
22123
- hint: config.description
23914
+ label: AVAILABLE_KITS[key].name,
23915
+ hint: AVAILABLE_KITS[key].description
22124
23916
  })),
22125
23917
  initialValue: defaultKit
22126
23918
  });
@@ -22652,8 +24444,8 @@ async function promptSkillsInstallation() {
22652
24444
  }
22653
24445
  // src/domains/ui/prompts.ts
22654
24446
  class PromptsManager {
22655
- async selectKit(defaultKit) {
22656
- return selectKit(defaultKit);
24447
+ async selectKit(defaultKit, accessibleKits) {
24448
+ return selectKit(defaultKit, accessibleKits);
22657
24449
  }
22658
24450
  async selectVersion(versions, defaultVersion) {
22659
24451
  return selectVersion(versions, defaultVersion);
@@ -31987,17 +33779,169 @@ init_dist2();
31987
33779
  // src/domains/installation/merger/copy-executor.ts
31988
33780
  init_logger();
31989
33781
  init_types2();
31990
- var import_fs_extra7 = __toESM(require_lib(), 1);
33782
+ var import_fs_extra8 = __toESM(require_lib(), 1);
31991
33783
  var import_ignore3 = __toESM(require_ignore(), 1);
31992
- import { dirname as dirname8, join as join38, relative as relative6 } from "node:path";
33784
+ import { dirname as dirname8, join as join39, relative as relative6 } from "node:path";
31993
33785
 
31994
33786
  // src/domains/installation/selective-merger.ts
31995
33787
  import { stat as stat6 } from "node:fs/promises";
33788
+
33789
+ // src/services/file-operations/manifest/manifest-reader.ts
33790
+ import { join as join35 } from "node:path";
33791
+ init_logger();
33792
+ init_types2();
33793
+ var import_fs_extra4 = __toESM(require_lib(), 1);
33794
+ async function readManifest(claudeDir) {
33795
+ const metadataPath = join35(claudeDir, "metadata.json");
33796
+ if (!await import_fs_extra4.pathExists(metadataPath)) {
33797
+ return null;
33798
+ }
33799
+ try {
33800
+ const content = await import_fs_extra4.readFile(metadataPath, "utf-8");
33801
+ const parsed = JSON.parse(content);
33802
+ return MetadataSchema.parse(parsed);
33803
+ } catch (error) {
33804
+ logger.debug(`Failed to read manifest: ${error}`);
33805
+ return null;
33806
+ }
33807
+ }
33808
+ async function readKitManifest(claudeDir, kit) {
33809
+ const metadata = await readManifest(claudeDir);
33810
+ if (!metadata)
33811
+ return null;
33812
+ return getKitMetadata(metadata, kit);
33813
+ }
33814
+ async function findFileInInstalledKits(claudeDir, relativePath, excludeKit) {
33815
+ const metadata = await readManifest(claudeDir);
33816
+ if (!metadata?.kits) {
33817
+ return {
33818
+ exists: false,
33819
+ ownerKit: null,
33820
+ checksum: null,
33821
+ version: null,
33822
+ sourceTimestamp: null,
33823
+ installedAt: null
33824
+ };
33825
+ }
33826
+ for (const [kitName, kitMeta] of Object.entries(metadata.kits)) {
33827
+ const kit = kitName;
33828
+ if (kit === excludeKit)
33829
+ continue;
33830
+ if (!kitMeta.files)
33831
+ continue;
33832
+ const file = kitMeta.files.find((f3) => f3.path === relativePath);
33833
+ if (file) {
33834
+ return {
33835
+ exists: true,
33836
+ ownerKit: kit,
33837
+ checksum: file.checksum,
33838
+ version: kitMeta.version,
33839
+ sourceTimestamp: file.sourceTimestamp ?? null,
33840
+ installedAt: file.installedAt ?? null
33841
+ };
33842
+ }
33843
+ }
33844
+ return {
33845
+ exists: false,
33846
+ ownerKit: null,
33847
+ checksum: null,
33848
+ version: null,
33849
+ sourceTimestamp: null,
33850
+ installedAt: null
33851
+ };
33852
+ }
33853
+ async function getUninstallManifest(claudeDir, kit) {
33854
+ const detection = await detectMetadataFormat(claudeDir);
33855
+ if (detection.format === "multi-kit" && detection.metadata?.kits) {
33856
+ const installedKits = Object.keys(detection.metadata.kits);
33857
+ if (kit) {
33858
+ const kitMeta = detection.metadata.kits[kit];
33859
+ if (!kitMeta?.files) {
33860
+ return {
33861
+ filesToRemove: [],
33862
+ filesToPreserve: USER_CONFIG_PATTERNS,
33863
+ hasManifest: true,
33864
+ isMultiKit: true,
33865
+ remainingKits: installedKits.filter((k2) => k2 !== kit)
33866
+ };
33867
+ }
33868
+ const kitFiles = kitMeta.files.map((f3) => f3.path);
33869
+ const sharedFiles = new Set;
33870
+ for (const otherKit of installedKits) {
33871
+ if (otherKit !== kit) {
33872
+ const otherMeta = detection.metadata.kits[otherKit];
33873
+ if (otherMeta?.files) {
33874
+ for (const f3 of otherMeta.files) {
33875
+ sharedFiles.add(f3.path);
33876
+ }
33877
+ }
33878
+ }
33879
+ }
33880
+ const filesToRemove = kitFiles.filter((f3) => !sharedFiles.has(f3));
33881
+ const filesToPreserve = [
33882
+ ...USER_CONFIG_PATTERNS,
33883
+ ...kitFiles.filter((f3) => sharedFiles.has(f3))
33884
+ ];
33885
+ return {
33886
+ filesToRemove,
33887
+ filesToPreserve,
33888
+ hasManifest: true,
33889
+ isMultiKit: true,
33890
+ remainingKits: installedKits.filter((k2) => k2 !== kit)
33891
+ };
33892
+ }
33893
+ const allFiles = getAllTrackedFiles(detection.metadata);
33894
+ return {
33895
+ filesToRemove: allFiles.map((f3) => f3.path),
33896
+ filesToPreserve: USER_CONFIG_PATTERNS,
33897
+ hasManifest: true,
33898
+ isMultiKit: true,
33899
+ remainingKits: []
33900
+ };
33901
+ }
33902
+ if (detection.format === "legacy" && detection.metadata) {
33903
+ const legacyFiles2 = detection.metadata.files?.map((f3) => f3.path) || [];
33904
+ const installedFiles = detection.metadata.installedFiles || [];
33905
+ const hasFiles = legacyFiles2.length > 0 || installedFiles.length > 0;
33906
+ if (!hasFiles) {
33907
+ const legacyDirs2 = ["commands", "agents", "skills", "workflows", "hooks", "scripts"];
33908
+ const legacyFileList = ["metadata.json"];
33909
+ return {
33910
+ filesToRemove: [...legacyDirs2, ...legacyFileList],
33911
+ filesToPreserve: USER_CONFIG_PATTERNS,
33912
+ hasManifest: false,
33913
+ isMultiKit: false,
33914
+ remainingKits: []
33915
+ };
33916
+ }
33917
+ return {
33918
+ filesToRemove: legacyFiles2.length > 0 ? legacyFiles2 : installedFiles,
33919
+ filesToPreserve: detection.metadata.userConfigFiles || USER_CONFIG_PATTERNS,
33920
+ hasManifest: true,
33921
+ isMultiKit: false,
33922
+ remainingKits: []
33923
+ };
33924
+ }
33925
+ const legacyDirs = ["commands", "agents", "skills", "workflows", "hooks", "scripts"];
33926
+ const legacyFiles = ["metadata.json"];
33927
+ return {
33928
+ filesToRemove: [...legacyDirs, ...legacyFiles],
33929
+ filesToPreserve: USER_CONFIG_PATTERNS,
33930
+ hasManifest: false,
33931
+ isMultiKit: false,
33932
+ remainingKits: []
33933
+ };
33934
+ }
33935
+
33936
+ // src/domains/installation/selective-merger.ts
31996
33937
  init_logger();
33938
+ var import_semver = __toESM(require_semver2(), 1);
31997
33939
 
31998
33940
  class SelectiveMerger {
31999
33941
  manifest;
32000
33942
  manifestMap;
33943
+ claudeDir = null;
33944
+ installingKit = null;
32001
33945
  constructor(manifest) {
32002
33946
  this.manifest = manifest;
32003
33947
  this.manifestMap = new Map;
@@ -32007,11 +33951,21 @@ class SelectiveMerger {
32007
33951
  }
32008
33952
  }
32009
33953
  }
33954
+ setMultiKitContext(claudeDir, installingKit) {
33955
+ this.claudeDir = claudeDir;
33956
+ this.installingKit = installingKit;
33957
+ }
32010
33958
  async shouldCopyFile(destPath, relativePath) {
32011
33959
  let destStat;
32012
33960
  try {
32013
33961
  destStat = await stat6(destPath);
32014
33962
  } catch {
33963
+ if (this.claudeDir && this.installingKit) {
33964
+ const installed = await findFileInInstalledKits(this.claudeDir, relativePath, this.installingKit);
33965
+ if (installed.exists) {
33966
+ logger.debug(`File ${relativePath} tracked by ${installed.ownerKit} but missing on disk`);
33967
+ }
33968
+ }
32015
33969
  return { changed: true, reason: "new" };
32016
33970
  }
32017
33971
  const manifestEntry = this.manifestMap.get(relativePath);
@@ -32019,6 +33973,94 @@ class SelectiveMerger {
32019
33973
  logger.debug(`No manifest entry for ${relativePath}, will copy`);
32020
33974
  return { changed: true, reason: "new" };
32021
33975
  }
33976
+ if (this.claudeDir && this.installingKit) {
33977
+ const installed = await findFileInInstalledKits(this.claudeDir, relativePath, this.installingKit);
33978
+ if (installed.exists && installed.checksum && installed.ownerKit) {
33979
+ if (installed.checksum === manifestEntry.checksum) {
33980
+ logger.debug(`Shared identical: ${relativePath} (owned by ${installed.ownerKit})`);
33981
+ return {
33982
+ changed: false,
33983
+ reason: "shared-identical",
33984
+ sourceChecksum: manifestEntry.checksum,
33985
+ destChecksum: installed.checksum,
33986
+ sharedWithKit: installed.ownerKit
33987
+ };
33988
+ }
33989
+ const incomingTimestamp = manifestEntry.lastModified ?? null;
33990
+ const existingTimestamp = installed.sourceTimestamp;
33991
+ const conflictBase = {
33992
+ relativePath,
33993
+ incomingKit: this.installingKit,
33994
+ existingKit: installed.ownerKit,
33995
+ incomingTimestamp,
33996
+ existingTimestamp
33997
+ };
33998
+ if (incomingTimestamp && existingTimestamp) {
33999
+ const incomingTime = new Date(incomingTimestamp).getTime();
34000
+ const existingTime = new Date(existingTimestamp).getTime();
34001
+ if (Number.isNaN(incomingTime) || Number.isNaN(existingTime)) {
34002
+ logger.debug(`Invalid timestamp for ${relativePath}, falling back to version`);
34003
+ } else if (incomingTime > existingTime) {
34004
+ logger.debug(`Shared newer: ${relativePath} - incoming ${incomingTimestamp} > existing ${existingTimestamp}`);
34005
+ return {
34006
+ changed: true,
34007
+ reason: "shared-newer",
34008
+ sourceChecksum: manifestEntry.checksum,
34009
+ destChecksum: installed.checksum,
34010
+ sharedWithKit: installed.ownerKit,
34011
+ conflictInfo: { ...conflictBase, winner: "incoming", reason: "newer" }
34012
+ };
34013
+ } else if (incomingTime < existingTime) {
34014
+ logger.debug(`Shared older: ${relativePath} - incoming ${incomingTimestamp} < existing ${existingTimestamp}`);
34015
+ return {
34016
+ changed: false,
34017
+ reason: "shared-older",
34018
+ sourceChecksum: manifestEntry.checksum,
34019
+ destChecksum: installed.checksum,
34020
+ sharedWithKit: installed.ownerKit,
34021
+ conflictInfo: { ...conflictBase, winner: "existing", reason: "existing-newer" }
34022
+ };
34023
+ } else {
34024
+ logger.debug(`Shared tie: ${relativePath} - same timestamp, keeping existing`);
34025
+ return {
34026
+ changed: false,
34027
+ reason: "shared-older",
34028
+ sourceChecksum: manifestEntry.checksum,
34029
+ destChecksum: installed.checksum,
34030
+ sharedWithKit: installed.ownerKit,
34031
+ conflictInfo: { ...conflictBase, winner: "existing", reason: "tie" }
34032
+ };
34033
+ }
34034
+ } else if (installed.version) {
34035
+ const incomingVersion = this.manifest?.version || "0.0.0";
34036
+ const installedVersion = installed.version;
34037
+ const incomingSemver = import_semver.default.coerce(incomingVersion);
34038
+ const installedSemver = import_semver.default.coerce(installedVersion);
34039
+ if (incomingSemver && installedSemver) {
34040
+ if (import_semver.default.lte(incomingSemver, installedSemver)) {
34041
+ logger.debug(`Shared older (version fallback): ${relativePath} - incoming ${incomingVersion} <= installed ${installedVersion}`);
34042
+ return {
34043
+ changed: false,
34044
+ reason: "shared-older",
34045
+ sourceChecksum: manifestEntry.checksum,
34046
+ destChecksum: installed.checksum,
34047
+ sharedWithKit: installed.ownerKit,
34048
+ conflictInfo: { ...conflictBase, winner: "existing", reason: "no-timestamps" }
34049
+ };
34050
+ }
34051
+ }
34052
+ logger.debug(`Updating shared file (version fallback): ${relativePath} - incoming ${incomingVersion} > installed ${installedVersion}`);
34053
+ return {
34054
+ changed: true,
34055
+ reason: "shared-newer",
34056
+ sourceChecksum: manifestEntry.checksum,
34057
+ destChecksum: installed.checksum,
34058
+ sharedWithKit: installed.ownerKit,
34059
+ conflictInfo: { ...conflictBase, winner: "incoming", reason: "no-timestamps" }
34060
+ };
34061
+ }
34062
+ }
34063
+ }
32022
34064
  if (destStat.size !== manifestEntry.size) {
32023
34065
  logger.debug(`Size differs for ${relativePath}: ${destStat.size} vs ${manifestEntry.size}`);
32024
34066
  return {
@@ -32055,10 +34097,10 @@ class SelectiveMerger {
32055
34097
 
32056
34098
  // src/domains/installation/merger/file-scanner.ts
32057
34099
  init_logger();
32058
- var import_fs_extra4 = __toESM(require_lib(), 1);
34100
+ var import_fs_extra5 = __toESM(require_lib(), 1);
32059
34101
  var import_ignore2 = __toESM(require_ignore(), 1);
32060
34102
  import { relative as relative5 } from "node:path";
32061
- import { join as join35 } from "node:path";
34103
+ import { join as join36 } from "node:path";
32062
34104
 
32063
34105
  // node_modules/@isaacs/balanced-match/dist/esm/index.js
32064
34106
  var balanced = (a3, b3, str) => {
@@ -33512,12 +35554,12 @@ class FileScanner {
33512
35554
  }
33513
35555
  async getFiles(dir, baseDir = dir) {
33514
35556
  const files = [];
33515
- const entries = await import_fs_extra4.readdir(dir, { encoding: "utf8" });
35557
+ const entries = await import_fs_extra5.readdir(dir, { encoding: "utf8" });
33516
35558
  for (const entry of entries) {
33517
- const fullPath = join35(dir, entry);
35559
+ const fullPath = join36(dir, entry);
33518
35560
  const relativePath = relative5(baseDir, fullPath);
33519
35561
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
33520
- const stats = await import_fs_extra4.lstat(fullPath);
35562
+ const stats = await import_fs_extra5.lstat(fullPath);
33521
35563
  if (stats.isSymbolicLink()) {
33522
35564
  logger.warning(`Skipping symbolic link: ${normalizedRelativePath}`);
33523
35565
  continue;
@@ -33548,10 +35590,34 @@ class FileScanner {
33548
35590
  }
33549
35591
 
33550
35592
  // src/domains/config/installed-settings-tracker.ts
33551
- init_logger();
33552
35593
  import { existsSync as existsSync16 } from "node:fs";
33553
- import { mkdir as mkdir14, readFile as readFile11, writeFile as writeFile9 } from "node:fs/promises";
33554
- import { dirname as dirname6, join as join36 } from "node:path";
35594
+ import { mkdir as mkdir14, readFile as readFile12, writeFile as writeFile9 } from "node:fs/promises";
35595
+ import { dirname as dirname6, join as join37 } from "node:path";
35596
+
35597
+ // src/shared/index.ts
35598
+ init_logger();
35599
+ init_environment();
35600
+ init_terminal_utils();
35601
+
35602
+ // src/shared/command-normalizer.ts
35603
+ function normalizeCommand(cmd) {
35604
+ if (!cmd)
35605
+ return "";
35606
+ let normalized = cmd;
35607
+ normalized = normalized.replace(/"\$HOME"/g, "$HOME");
35608
+ normalized = normalized.replace(/"\$CLAUDE_PROJECT_DIR"/g, "$HOME");
35609
+ normalized = normalized.replace(/"\$\{HOME\}"/g, "$HOME");
35610
+ normalized = normalized.replace(/\$CLAUDE_PROJECT_DIR/g, "$HOME");
35611
+ normalized = normalized.replace(/\$\{HOME\}/g, "$HOME");
35612
+ normalized = normalized.replace(/"%USERPROFILE%"/g, "$HOME");
35613
+ normalized = normalized.replace(/%USERPROFILE%/g, "$HOME");
35614
+ normalized = normalized.replace(/"%CLAUDE_PROJECT_DIR%"/g, "$HOME");
35615
+ normalized = normalized.replace(/%CLAUDE_PROJECT_DIR%/g, "$HOME");
35616
+ normalized = normalized.replace(/\\/g, "/");
35617
+ normalized = normalized.replace(/\s+/g, " ").trim();
35618
+ return normalized;
35619
+ }
35620
+ // src/domains/config/installed-settings-tracker.ts
33555
35621
  var CK_JSON_FILE = ".ck.json";
33556
35622
 
33557
35623
  class InstalledSettingsTracker {
@@ -33565,9 +35631,9 @@ class InstalledSettingsTracker {
33565
35631
  }
33566
35632
  getCkJsonPath() {
33567
35633
  if (this.isGlobal) {
33568
- return join36(this.projectDir, CK_JSON_FILE);
35634
+ return join37(this.projectDir, CK_JSON_FILE);
33569
35635
  }
33570
- return join36(this.projectDir, ".claude", CK_JSON_FILE);
35636
+ return join37(this.projectDir, ".claude", CK_JSON_FILE);
33571
35637
  }
33572
35638
  async loadInstalledSettings() {
33573
35639
  const ckJsonPath = this.getCkJsonPath();
@@ -33575,7 +35641,7 @@ class InstalledSettingsTracker {
33575
35641
  return { hooks: [], mcpServers: [] };
33576
35642
  }
33577
35643
  try {
33578
- const content = await readFile11(ckJsonPath, "utf-8");
35644
+ const content = await readFile12(ckJsonPath, "utf-8");
33579
35645
  const data = JSON.parse(content);
33580
35646
  const installed = data.kits?.[this.kitName]?.installedSettings;
33581
35647
  if (installed) {
@@ -33592,7 +35658,7 @@ class InstalledSettingsTracker {
33592
35658
  try {
33593
35659
  let data = {};
33594
35660
  if (existsSync16(ckJsonPath)) {
33595
- const content = await readFile11(ckJsonPath, "utf-8");
35661
+ const content = await readFile12(ckJsonPath, "utf-8");
33596
35662
  data = JSON.parse(content);
33597
35663
  }
33598
35664
  if (!data.kits) {
@@ -33610,7 +35676,8 @@ class InstalledSettingsTracker {
33610
35676
  }
33611
35677
  }
33612
35678
  wasHookInstalled(command, installed) {
33613
- return installed.hooks?.includes(command) ?? false;
35679
+ const normalizedCommand = normalizeCommand(command);
35680
+ return installed.hooks?.some((hook) => normalizeCommand(hook) === normalizedCommand) ?? false;
33614
35681
  }
33615
35682
  wasMcpServerInstalled(serverName, installed) {
33616
35683
  return installed.mcpServers?.includes(serverName) ?? false;
@@ -33619,8 +35686,10 @@ class InstalledSettingsTracker {
33619
35686
  if (!settings.hooks) {
33620
35687
  settings.hooks = [];
33621
35688
  }
33622
- if (!settings.hooks.includes(command)) {
33623
- settings.hooks.push(command);
35689
+ const normalizedCommand = normalizeCommand(command);
35690
+ const alreadyTracked = settings.hooks.some((hook) => normalizeCommand(hook) === normalizedCommand);
35691
+ if (!alreadyTracked) {
35692
+ settings.hooks.push(normalizedCommand);
33624
35693
  }
33625
35694
  }
33626
35695
  trackMcpServer(serverName, settings) {
@@ -33640,9 +35709,6 @@ class InstalledSettingsTracker {
33640
35709
  // src/domains/config/merger/merge-engine.ts
33641
35710
  init_logger();
33642
35711
 
33643
- // src/domains/config/merger/conflict-resolver.ts
33644
- init_logger();
33645
-
33646
35712
  // src/domains/config/merger/diff-calculator.ts
33647
35713
  function truncateCommand(cmd, maxLen = 50) {
33648
35714
  if (cmd.length <= maxLen)
@@ -33661,12 +35727,12 @@ function deepCopyEntry(entry) {
33661
35727
  function extractCommands(entries, commands) {
33662
35728
  for (const entry of entries) {
33663
35729
  if ("command" in entry && entry.command) {
33664
- commands.add(entry.command);
35730
+ commands.add(normalizeCommand(entry.command));
33665
35731
  }
33666
35732
  if ("hooks" in entry && entry.hooks) {
33667
35733
  for (const hook of entry.hooks) {
33668
35734
  if (hook.command) {
33669
- commands.add(hook.command);
35735
+ commands.add(normalizeCommand(hook.command));
33670
35736
  }
33671
35737
  }
33672
35738
  }
@@ -33695,13 +35761,46 @@ function logDuplicates(duplicateCommands, eventName, result) {
33695
35761
 
33696
35762
  // src/domains/config/merger/conflict-resolver.ts
33697
35763
  function wasCommandInstalled(command, installedHooks) {
33698
- return installedHooks.includes(command);
35764
+ const normalizedCommand = normalizeCommand(command);
35765
+ return installedHooks.some((hook) => normalizeCommand(hook) === normalizedCommand);
33699
35766
  }
33700
- function mergeHookEntries(sourceEntries, destEntries, eventName, result, installedHooks = []) {
33701
- if (destEntries.length > 0) {
33702
- result.hooksPreserved += destEntries.length;
35767
+ function dedupeDestinationEntries(entries) {
35768
+ const seenCommands = new Set;
35769
+ const deduped = [];
35770
+ let removedCount = 0;
35771
+ for (const entry of entries) {
35772
+ const commands = getEntryCommands(entry);
35773
+ if (commands.length === 0) {
35774
+ deduped.push(deepCopyEntry(entry));
35775
+ continue;
35776
+ }
35777
+ const uniqueCommands = commands.filter((cmd) => !seenCommands.has(normalizeCommand(cmd)));
35778
+ if (uniqueCommands.length === 0) {
35779
+ removedCount++;
35780
+ logger.verbose(`Removing duplicate hook entry: ${commands[0]?.slice(0, 50)}...`);
35781
+ continue;
35782
+ }
35783
+ if ("hooks" in entry && entry.hooks && uniqueCommands.length < commands.length) {
35784
+ const filteredHooks = entry.hooks.filter((h2) => !h2.command || !seenCommands.has(normalizeCommand(h2.command)));
35785
+ deduped.push({ ...entry, hooks: filteredHooks });
35786
+ } else {
35787
+ deduped.push(deepCopyEntry(entry));
35788
+ }
35789
+ for (const cmd of commands) {
35790
+ seenCommands.add(normalizeCommand(cmd));
35791
+ }
35792
+ }
35793
+ return { deduped, removedCount };
35794
+ }
35795
+ function mergeHookEntries(sourceEntries, destEntries, eventName, result, installedHooks = [], sourceKit) {
35796
+ const { deduped: dedupedDest, removedCount } = dedupeDestinationEntries(destEntries);
35797
+ if (removedCount > 0) {
35798
+ logger.info(`Cleaned up ${removedCount} duplicate hook(s) from existing settings`);
33703
35799
  }
33704
- const merged = destEntries.map((entry) => deepCopyEntry(entry));
35800
+ if (dedupedDest.length > 0) {
35801
+ result.hooksPreserved += dedupedDest.length;
35802
+ }
35803
+ const merged = dedupedDest;
33705
35804
  const matcherIndex = new Map;
33706
35805
  for (let i = 0;i < merged.length; i++) {
33707
35806
  const entry = merged[i];
@@ -33710,11 +35809,11 @@ function mergeHookEntries(sourceEntries, destEntries, eventName, result, install
33710
35809
  }
33711
35810
  }
33712
35811
  const existingCommands = new Set;
33713
- extractCommands(destEntries, existingCommands);
35812
+ extractCommands(dedupedDest, existingCommands);
33714
35813
  for (const entry of sourceEntries) {
33715
35814
  const sourceMatcher = "matcher" in entry ? entry.matcher : undefined;
33716
35815
  const commands = getEntryCommands(entry);
33717
- const userRemovedCommands = commands.filter((cmd) => !existingCommands.has(cmd) && wasCommandInstalled(cmd, installedHooks));
35816
+ const userRemovedCommands = commands.filter((cmd) => !existingCommands.has(normalizeCommand(cmd)) && wasCommandInstalled(cmd, installedHooks));
33718
35817
  if (userRemovedCommands.length > 0) {
33719
35818
  result.hooksSkipped += userRemovedCommands.length;
33720
35819
  for (const cmd of userRemovedCommands) {
@@ -33729,27 +35828,31 @@ function mergeHookEntries(sourceEntries, destEntries, eventName, result, install
33729
35828
  if (existingIdx === undefined)
33730
35829
  continue;
33731
35830
  const existingEntry = merged[existingIdx];
33732
- const newCommands = commands.filter((cmd) => !existingCommands.has(cmd) && !wasCommandInstalled(cmd, installedHooks));
33733
- const duplicateCommands = commands.filter((cmd) => existingCommands.has(cmd));
35831
+ const newCommands = commands.filter((cmd) => !existingCommands.has(normalizeCommand(cmd)) && !wasCommandInstalled(cmd, installedHooks));
35832
+ const duplicateCommands = commands.filter((cmd) => existingCommands.has(normalizeCommand(cmd)));
33734
35833
  logDuplicates(duplicateCommands, eventName, result);
33735
35834
  if (newCommands.length > 0 && "hooks" in entry && entry.hooks) {
33736
35835
  if (!existingEntry.hooks) {
33737
35836
  existingEntry.hooks = [];
33738
35837
  }
33739
35838
  for (const hook of entry.hooks) {
33740
- if (hook.command && !existingCommands.has(hook.command) && !wasCommandInstalled(hook.command, installedHooks)) {
33741
- existingEntry.hooks.push(hook);
33742
- existingCommands.add(hook.command);
35839
+ if (hook.command && !existingCommands.has(normalizeCommand(hook.command)) && !wasCommandInstalled(hook.command, installedHooks)) {
35840
+ const taggedHook = sourceKit ? { ...hook, _origin: sourceKit } : hook;
35841
+ existingEntry.hooks.push(taggedHook);
35842
+ existingCommands.add(normalizeCommand(hook.command));
33743
35843
  result.newlyInstalledHooks.push(hook.command);
35844
+ if (sourceKit) {
35845
+ trackHookOrigin(result, sourceKit, hook.command);
35846
+ }
33744
35847
  }
33745
35848
  }
33746
35849
  result.hooksAdded++;
33747
35850
  }
33748
35851
  } else {
33749
- const isFullyDuplicated = commands.length > 0 && commands.every((cmd) => existingCommands.has(cmd));
33750
- const duplicateCommands = commands.filter((cmd) => existingCommands.has(cmd));
35852
+ const isFullyDuplicated = commands.length > 0 && commands.every((cmd) => existingCommands.has(normalizeCommand(cmd)));
35853
+ const duplicateCommands = commands.filter((cmd) => existingCommands.has(normalizeCommand(cmd)));
33751
35854
  logDuplicates(duplicateCommands, eventName, result);
33752
- const hasNonRemovedCommands = commands.length === 0 || commands.some((cmd) => !existingCommands.has(cmd) && !wasCommandInstalled(cmd, installedHooks));
35855
+ const hasNonRemovedCommands = commands.length === 0 || commands.some((cmd) => !existingCommands.has(normalizeCommand(cmd)) && !wasCommandInstalled(cmd, installedHooks));
33753
35856
  if (!isFullyDuplicated && hasNonRemovedCommands) {
33754
35857
  let filteredEntry = entry;
33755
35858
  if ("hooks" in entry && entry.hooks && userRemovedCommands.length > 0) {
@@ -33758,17 +35861,22 @@ function mergeHookEntries(sourceEntries, destEntries, eventName, result, install
33758
35861
  } else if ("command" in entry && wasCommandInstalled(entry.command, installedHooks)) {
33759
35862
  continue;
33760
35863
  }
33761
- merged.push(filteredEntry);
35864
+ const taggedEntry = sourceKit ? tagHooksWithOrigin(filteredEntry, sourceKit) : filteredEntry;
35865
+ merged.push(taggedEntry);
33762
35866
  result.hooksAdded++;
33763
35867
  if (sourceMatcher) {
33764
35868
  matcherIndex.set(sourceMatcher, merged.length - 1);
33765
35869
  }
33766
35870
  for (const cmd of commands) {
33767
- if (!existingCommands.has(cmd) && !wasCommandInstalled(cmd, installedHooks)) {
33768
- existingCommands.add(cmd);
35871
+ const normalizedCmd = normalizeCommand(cmd);
35872
+ if (!existingCommands.has(normalizedCmd) && !wasCommandInstalled(cmd, installedHooks)) {
35873
+ existingCommands.add(normalizedCmd);
33769
35874
  result.newlyInstalledHooks.push(cmd);
33770
- } else if (!existingCommands.has(cmd)) {
33771
- existingCommands.add(cmd);
35875
+ if (sourceKit) {
35876
+ trackHookOrigin(result, sourceKit, cmd);
35877
+ }
35878
+ } else if (!existingCommands.has(normalizedCmd)) {
35879
+ existingCommands.add(normalizedCmd);
33772
35880
  }
33773
35881
  }
33774
35882
  }
@@ -33776,14 +35884,32 @@ function mergeHookEntries(sourceEntries, destEntries, eventName, result, install
33776
35884
  }
33777
35885
  return merged;
33778
35886
  }
35887
+ function tagHooksWithOrigin(entry, kit) {
35888
+ if ("hooks" in entry && entry.hooks) {
35889
+ return {
35890
+ ...entry,
35891
+ hooks: entry.hooks.map((h2) => ({ ...h2, _origin: kit }))
35892
+ };
35893
+ }
35894
+ if ("command" in entry) {
35895
+ return { ...entry, _origin: kit };
35896
+ }
35897
+ return entry;
35898
+ }
35899
+ function trackHookOrigin(result, kit, command) {
35900
+ const existing = result.hooksByOrigin.get(kit) || [];
35901
+ existing.push(command);
35902
+ result.hooksByOrigin.set(kit, existing);
35903
+ }
33779
35904
 
33780
35905
  // src/domains/config/merger/merge-engine.ts
33781
35906
  function mergeHooks(sourceHooks, destHooks, result, options) {
33782
35907
  const merged = { ...destHooks };
33783
35908
  const installedHooks = options?.installedSettings?.hooks ?? [];
35909
+ const sourceKit = options?.sourceKit;
33784
35910
  for (const [eventName, sourceEntries] of Object.entries(sourceHooks)) {
33785
35911
  const destEntries = destHooks[eventName] || [];
33786
- merged[eventName] = mergeHookEntries(sourceEntries, destEntries, eventName, result, installedHooks);
35912
+ merged[eventName] = mergeHookEntries(sourceEntries, destEntries, eventName, result, installedHooks, sourceKit);
33787
35913
  }
33788
35914
  return merged;
33789
35915
  }
@@ -33797,8 +35923,54 @@ function mergeMcp(sourceMcp, destMcp, result, options) {
33797
35923
  if (sourceMcp.servers) {
33798
35924
  const destServers = destMcp.servers || {};
33799
35925
  merged.servers = { ...destServers };
35926
+ const sourceTimestamps = options?.sourceTimestamps?.mcpServers ?? {};
35927
+ const destTimestamps = options?.installedSettings?.mcpServerTimestamps ?? {};
33800
35928
  for (const [serverName, serverConfig] of Object.entries(sourceMcp.servers)) {
33801
35929
  if (serverName in destServers) {
35930
+ const sourceTs = sourceTimestamps[serverName];
35931
+ const destTs = destTimestamps[serverName];
35932
+ if (sourceTs && destTs) {
35933
+ const sourceTime = new Date(sourceTs).getTime();
35934
+ const destTime = new Date(destTs).getTime();
35935
+ if (sourceTime > destTime) {
35936
+ merged.servers[serverName] = serverConfig;
35937
+ result.mcpServersOverwritten = (result.mcpServersOverwritten ?? 0) + 1;
35938
+ result.mcpConflicts = result.mcpConflicts ?? [];
35939
+ result.mcpConflicts.push({
35940
+ serverName,
35941
+ incomingKit: options?.sourceKit ?? "unknown",
35942
+ existingKit: "existing",
35943
+ winner: options?.sourceKit ?? "incoming",
35944
+ reason: "newer"
35945
+ });
35946
+ logger.debug(`Overwrote MCP server (newer): ${serverName}`);
35947
+ continue;
35948
+ }
35949
+ if (sourceTime < destTime) {
35950
+ result.mcpServersPreserved++;
35951
+ result.mcpConflicts = result.mcpConflicts ?? [];
35952
+ result.mcpConflicts.push({
35953
+ serverName,
35954
+ incomingKit: options?.sourceKit ?? "unknown",
35955
+ existingKit: "existing",
35956
+ winner: "existing",
35957
+ reason: "existing-newer"
35958
+ });
35959
+ logger.debug(`Preserved MCP server (existing newer): ${serverName}`);
35960
+ continue;
35961
+ }
35962
+ result.mcpServersPreserved++;
35963
+ result.mcpConflicts = result.mcpConflicts ?? [];
35964
+ result.mcpConflicts.push({
35965
+ serverName,
35966
+ incomingKit: options?.sourceKit ?? "unknown",
35967
+ existingKit: "existing",
35968
+ winner: "existing",
35969
+ reason: "tie"
35970
+ });
35971
+ logger.debug(`Preserved MCP server (tie): ${serverName}`);
35972
+ continue;
35973
+ }
33802
35974
  const userModified = JSON.stringify(serverConfig) !== JSON.stringify(destServers[serverName]);
33803
35975
  if (userModified) {
33804
35976
  result.mcpServersPreserved++;
@@ -33834,7 +36006,8 @@ function mergeSettings(source, destination, options) {
33834
36006
  mcpServersSkipped: 0,
33835
36007
  conflictsDetected: [],
33836
36008
  newlyInstalledHooks: [],
33837
- newlyInstalledServers: []
36009
+ newlyInstalledServers: [],
36010
+ hooksByOrigin: new Map
33838
36011
  };
33839
36012
  if (source.hooks) {
33840
36013
  result.merged.hooks = mergeHooks(source.hooks, destination.hooks || {}, result, options);
@@ -33851,15 +36024,15 @@ function mergeSettings(source, destination, options) {
33851
36024
  }
33852
36025
  // src/domains/config/merger/file-io.ts
33853
36026
  init_logger();
33854
- var import_fs_extra5 = __toESM(require_lib(), 1);
36027
+ var import_fs_extra6 = __toESM(require_lib(), 1);
33855
36028
  import { randomUUID } from "node:crypto";
33856
- import { dirname as dirname7, join as join37 } from "node:path";
36029
+ import { dirname as dirname7, join as join38 } from "node:path";
33857
36030
  async function readSettingsFile(filePath) {
33858
36031
  try {
33859
- if (!await import_fs_extra5.pathExists(filePath)) {
36032
+ if (!await import_fs_extra6.pathExists(filePath)) {
33860
36033
  return null;
33861
36034
  }
33862
- const content = await import_fs_extra5.readFile(filePath, "utf-8");
36035
+ const content = await import_fs_extra6.readFile(filePath, "utf-8");
33863
36036
  const parsed = JSON.parse(content);
33864
36037
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
33865
36038
  logger.warning(`Invalid settings file format (expected object): ${filePath}`);
@@ -33873,14 +36046,14 @@ async function readSettingsFile(filePath) {
33873
36046
  }
33874
36047
  async function atomicWriteFile(filePath, content) {
33875
36048
  const dir = dirname7(filePath);
33876
- const tempPath = join37(dir, `.settings-${randomUUID()}.tmp`);
36049
+ const tempPath = join38(dir, `.settings-${randomUUID()}.tmp`);
33877
36050
  try {
33878
- await import_fs_extra5.writeFile(tempPath, content, "utf-8");
33879
- await import_fs_extra5.rename(tempPath, filePath);
36051
+ await import_fs_extra6.writeFile(tempPath, content, "utf-8");
36052
+ await import_fs_extra6.rename(tempPath, filePath);
33880
36053
  } catch (error) {
33881
36054
  try {
33882
- if (await import_fs_extra5.pathExists(tempPath)) {
33883
- await import_fs_extra5.unlink(tempPath);
36055
+ if (await import_fs_extra6.pathExists(tempPath)) {
36056
+ await import_fs_extra6.unlink(tempPath);
33884
36057
  }
33885
36058
  } catch {}
33886
36059
  throw error;
@@ -33909,7 +36082,7 @@ class SettingsMerger {
33909
36082
  // src/domains/installation/merger/settings-processor.ts
33910
36083
  init_environment();
33911
36084
  init_logger();
33912
- var import_fs_extra6 = __toESM(require_lib(), 1);
36085
+ var import_fs_extra7 = __toESM(require_lib(), 1);
33913
36086
 
33914
36087
  class SettingsProcessor {
33915
36088
  isGlobal = false;
@@ -33917,6 +36090,7 @@ class SettingsProcessor {
33917
36090
  projectDir = "";
33918
36091
  kitName = "engineer";
33919
36092
  tracker = null;
36093
+ installingKit;
33920
36094
  setGlobalFlag(isGlobal) {
33921
36095
  this.isGlobal = isGlobal;
33922
36096
  }
@@ -33931,6 +36105,9 @@ class SettingsProcessor {
33931
36105
  this.kitName = kit;
33932
36106
  this.initTracker();
33933
36107
  }
36108
+ setInstallingKit(kit) {
36109
+ this.installingKit = kit;
36110
+ }
33934
36111
  initTracker() {
33935
36112
  if (this.projectDir) {
33936
36113
  this.tracker = new InstalledSettingsTracker(this.projectDir, this.isGlobal, this.kitName);
@@ -33938,7 +36115,7 @@ class SettingsProcessor {
33938
36115
  }
33939
36116
  async processSettingsJson(sourceFile, destFile) {
33940
36117
  try {
33941
- const sourceContent = await import_fs_extra6.readFile(sourceFile, "utf-8");
36118
+ const sourceContent = await import_fs_extra7.readFile(sourceFile, "utf-8");
33942
36119
  let transformedSource = sourceContent;
33943
36120
  if (this.isGlobal) {
33944
36121
  const homeVar = isWindows() ? '"%USERPROFILE%"' : '"$HOME"';
@@ -33953,12 +36130,12 @@ class SettingsProcessor {
33953
36130
  logger.debug(`Transformed .claude/ paths to ${projectDirVar}/.claude/ in settings.json for local installation`);
33954
36131
  }
33955
36132
  }
33956
- const destExists = await import_fs_extra6.pathExists(destFile);
36133
+ const destExists = await import_fs_extra7.pathExists(destFile);
33957
36134
  if (destExists && !this.forceOverwriteSettings) {
33958
36135
  await this.selectiveMergeSettings(transformedSource, destFile);
33959
36136
  } else {
33960
36137
  const formattedContent = this.formatJsonContent(transformedSource);
33961
- await import_fs_extra6.writeFile(destFile, formattedContent, "utf-8");
36138
+ await import_fs_extra7.writeFile(destFile, formattedContent, "utf-8");
33962
36139
  try {
33963
36140
  const parsedSettings = JSON.parse(formattedContent);
33964
36141
  if (this.forceOverwriteSettings && destExists) {
@@ -33972,7 +36149,7 @@ class SettingsProcessor {
33972
36149
  }
33973
36150
  } catch (error) {
33974
36151
  logger.error(`Failed to process settings.json: ${error}`);
33975
- await import_fs_extra6.copy(sourceFile, destFile, { overwrite: true });
36152
+ await import_fs_extra7.copy(sourceFile, destFile, { overwrite: true });
33976
36153
  }
33977
36154
  }
33978
36155
  async selectiveMergeSettings(transformedSourceContent, destFile) {
@@ -33982,10 +36159,15 @@ class SettingsProcessor {
33982
36159
  } catch {
33983
36160
  logger.warning("Failed to parse source settings.json, falling back to overwrite");
33984
36161
  const formattedContent = this.formatJsonContent(transformedSourceContent);
33985
- await import_fs_extra6.writeFile(destFile, formattedContent, "utf-8");
36162
+ await import_fs_extra7.writeFile(destFile, formattedContent, "utf-8");
33986
36163
  return;
33987
36164
  }
33988
- const destSettings = await SettingsMerger.readSettingsFile(destFile);
36165
+ let destSettings;
36166
+ if (this.isGlobal) {
36167
+ destSettings = await this.readAndNormalizeGlobalSettings(destFile);
36168
+ } else {
36169
+ destSettings = await SettingsMerger.readSettingsFile(destFile);
36170
+ }
33989
36171
  if (!destSettings) {
33990
36172
  await SettingsMerger.writeSettingsFile(destFile, sourceSettings);
33991
36173
  await this.trackInstalledSettings(sourceSettings);
@@ -33996,7 +36178,8 @@ class SettingsProcessor {
33996
36178
  installedSettings = await this.tracker.loadInstalledSettings();
33997
36179
  }
33998
36180
  const mergeResult = SettingsMerger.merge(sourceSettings, destSettings, {
33999
- installedSettings
36181
+ installedSettings,
36182
+ sourceKit: this.installingKit
34000
36183
  });
34001
36184
  logger.verbose("Settings merge details", {
34002
36185
  hooksAdded: mergeResult.hooksAdded,
@@ -34060,6 +36243,25 @@ class SettingsProcessor {
34060
36243
  return content;
34061
36244
  }
34062
36245
  }
36246
+ async readAndNormalizeGlobalSettings(destFile) {
36247
+ try {
36248
+ const content = await import_fs_extra7.readFile(destFile, "utf-8");
36249
+ if (!content.trim())
36250
+ return null;
36251
+ const homeVar = isWindows() ? "%USERPROFILE%" : "$HOME";
36252
+ let normalized = content;
36253
+ normalized = normalized.replace(/"\$CLAUDE_PROJECT_DIR"/g, `"${homeVar}"`);
36254
+ normalized = normalized.replace(/\$CLAUDE_PROJECT_DIR/g, homeVar);
36255
+ normalized = normalized.replace(/"%CLAUDE_PROJECT_DIR%"/g, `"${homeVar}"`);
36256
+ normalized = normalized.replace(/%CLAUDE_PROJECT_DIR%/g, homeVar);
36257
+ if (normalized !== content) {
36258
+ logger.debug("Normalized $CLAUDE_PROJECT_DIR paths to $HOME in existing global settings");
36259
+ }
36260
+ return JSON.parse(normalized);
36261
+ } catch {
36262
+ return null;
36263
+ }
36264
+ }
34063
36265
  transformClaudePaths(content, prefix) {
34064
36266
  if (/\.claude\/[^\s"']*[;`$&|><]/.test(content)) {
34065
36267
  logger.warning("Potentially unsafe characters detected in .claude/ paths");
@@ -34084,13 +36286,22 @@ class CopyExecutor {
34084
36286
  settingsProcessor;
34085
36287
  selectiveMerger = null;
34086
36288
  unchangedSkipped = 0;
36289
+ sharedSkipped = 0;
34087
36290
  installedFiles = new Set;
34088
36291
  installedDirectories = new Set;
36292
+ fileConflicts = [];
36293
+ claudeDir = null;
36294
+ installingKit = null;
34089
36295
  constructor(neverCopyPatterns) {
34090
36296
  this.userConfigChecker = import_ignore3.default().add(USER_CONFIG_PATTERNS);
34091
36297
  this.fileScanner = new FileScanner(neverCopyPatterns);
34092
36298
  this.settingsProcessor = new SettingsProcessor;
34093
36299
  }
36300
+ setMultiKitContext(claudeDir, installingKit) {
36301
+ this.claudeDir = claudeDir;
36302
+ this.installingKit = installingKit;
36303
+ this.settingsProcessor.setInstallingKit(installingKit);
36304
+ }
34094
36305
  setIncludePatterns(patterns) {
34095
36306
  this.fileScanner.setIncludePatterns(patterns);
34096
36307
  }
@@ -34109,6 +36320,9 @@ class CopyExecutor {
34109
36320
  setManifest(manifest) {
34110
36321
  this.selectiveMerger = manifest ? new SelectiveMerger(manifest) : null;
34111
36322
  if (manifest && this.selectiveMerger?.hasManifest()) {
36323
+ if (this.claudeDir && this.installingKit) {
36324
+ this.selectiveMerger.setMultiKitContext(this.claudeDir, this.installingKit);
36325
+ }
34112
36326
  logger.debug(`Selective merge enabled with ${this.selectiveMerger.getManifestFileCount()} tracked files`);
34113
36327
  }
34114
36328
  }
@@ -34124,8 +36338,8 @@ class CopyExecutor {
34124
36338
  for (const file of files) {
34125
36339
  const relativePath = relative6(sourceDir, file);
34126
36340
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
34127
- const destPath = join38(destDir, relativePath);
34128
- if (await import_fs_extra7.pathExists(destPath)) {
36341
+ const destPath = join39(destDir, relativePath);
36342
+ if (await import_fs_extra8.pathExists(destPath)) {
34129
36343
  if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
34130
36344
  logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
34131
36345
  continue;
@@ -34146,14 +36360,14 @@ class CopyExecutor {
34146
36360
  for (const file of files) {
34147
36361
  const relativePath = relative6(sourceDir, file);
34148
36362
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
34149
- const destPath = join38(destDir, relativePath);
36363
+ const destPath = join39(destDir, relativePath);
34150
36364
  if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
34151
36365
  logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
34152
36366
  skippedCount++;
34153
36367
  continue;
34154
36368
  }
34155
36369
  if (this.userConfigChecker.ignores(normalizedRelativePath)) {
34156
- const fileExists = await import_fs_extra7.pathExists(destPath);
36370
+ const fileExists = await import_fs_extra8.pathExists(destPath);
34157
36371
  if (fileExists) {
34158
36372
  logger.debug(`Preserving user config: ${normalizedRelativePath}`);
34159
36373
  skippedCount++;
@@ -34169,19 +36383,36 @@ class CopyExecutor {
34169
36383
  }
34170
36384
  if (this.selectiveMerger?.hasManifest()) {
34171
36385
  const compareResult = await this.selectiveMerger.shouldCopyFile(destPath, normalizedRelativePath);
36386
+ if (compareResult.conflictInfo) {
36387
+ this.fileConflicts.push(compareResult.conflictInfo);
36388
+ }
34172
36389
  if (!compareResult.changed) {
34173
- logger.debug(`Skipping unchanged: ${normalizedRelativePath}`);
34174
- this.unchangedSkipped++;
36390
+ if (compareResult.reason === "shared-identical" || compareResult.reason === "shared-older") {
36391
+ logger.debug(`Preserving shared file: ${normalizedRelativePath} (${compareResult.reason})`);
36392
+ this.sharedSkipped++;
36393
+ } else {
36394
+ logger.debug(`Skipping unchanged: ${normalizedRelativePath}`);
36395
+ this.unchangedSkipped++;
36396
+ }
34175
36397
  this.trackInstalledFile(normalizedRelativePath);
34176
36398
  continue;
34177
36399
  }
34178
36400
  }
34179
- await import_fs_extra7.copy(file, destPath, { overwrite: true });
36401
+ await import_fs_extra8.copy(file, destPath, { overwrite: true });
34180
36402
  this.trackInstalledFile(normalizedRelativePath);
34181
36403
  copiedCount++;
34182
36404
  }
34183
- if (this.unchangedSkipped > 0) {
34184
- logger.success(`Updated ${copiedCount} file(s), skipped ${this.unchangedSkipped} unchanged, skipped ${skippedCount} protected`);
36405
+ const parts = [];
36406
+ if (copiedCount > 0)
36407
+ parts.push(`Updated ${copiedCount} file(s)`);
36408
+ if (this.unchangedSkipped > 0)
36409
+ parts.push(`skipped ${this.unchangedSkipped} unchanged`);
36410
+ if (this.sharedSkipped > 0)
36411
+ parts.push(`preserved ${this.sharedSkipped} shared`);
36412
+ if (skippedCount > 0)
36413
+ parts.push(`skipped ${skippedCount} protected`);
36414
+ if (parts.length > 0) {
36415
+ logger.success(parts.join(", "));
34185
36416
  } else {
34186
36417
  logger.success(`Copied ${copiedCount} file(s), skipped ${skippedCount} protected file(s)`);
34187
36418
  }
@@ -34201,6 +36432,9 @@ class CopyExecutor {
34201
36432
  getAllInstalledFiles() {
34202
36433
  return Array.from(this.installedFiles).sort();
34203
36434
  }
36435
+ getFileConflicts() {
36436
+ return this.fileConflicts;
36437
+ }
34204
36438
  trackInstalledFile(relativePath) {
34205
36439
  this.installedFiles.add(relativePath);
34206
36440
  let dir = dirname8(relativePath);
@@ -34235,6 +36469,9 @@ class FileMerger {
34235
36469
  setManifest(manifest) {
34236
36470
  this.copyExecutor.setManifest(manifest);
34237
36471
  }
36472
+ setMultiKitContext(claudeDir, installingKit) {
36473
+ this.copyExecutor.setMultiKitContext(claudeDir, installingKit);
36474
+ }
34238
36475
  async merge(sourceDir, destDir, skipConfirmation = false) {
34239
36476
  const conflicts = await this.copyExecutor.detectConflicts(sourceDir, destDir);
34240
36477
  if (conflicts.length > 0 && !skipConfirmation) {
@@ -34261,119 +36498,14 @@ class FileMerger {
34261
36498
  getAllInstalledFiles() {
34262
36499
  return this.copyExecutor.getAllInstalledFiles();
34263
36500
  }
36501
+ getFileConflicts() {
36502
+ return this.copyExecutor.getFileConflicts();
36503
+ }
34264
36504
  }
34265
36505
 
34266
36506
  // src/domains/migration/legacy-migration.ts
34267
36507
  import { readdir as readdir9, stat as stat7 } from "node:fs/promises";
34268
36508
  import { join as join43, relative as relative7 } from "node:path";
34269
-
34270
- // src/services/file-operations/manifest/manifest-reader.ts
34271
- import { join as join39 } from "node:path";
34272
- init_logger();
34273
- init_types2();
34274
- var import_fs_extra8 = __toESM(require_lib(), 1);
34275
- async function readManifest(claudeDir) {
34276
- const metadataPath = join39(claudeDir, "metadata.json");
34277
- if (!await import_fs_extra8.pathExists(metadataPath)) {
34278
- return null;
34279
- }
34280
- try {
34281
- const content = await import_fs_extra8.readFile(metadataPath, "utf-8");
34282
- const parsed = JSON.parse(content);
34283
- return MetadataSchema.parse(parsed);
34284
- } catch (error) {
34285
- logger.debug(`Failed to read manifest: ${error}`);
34286
- return null;
34287
- }
34288
- }
34289
- async function readKitManifest(claudeDir, kit) {
34290
- const metadata = await readManifest(claudeDir);
34291
- if (!metadata)
34292
- return null;
34293
- return getKitMetadata(metadata, kit);
34294
- }
34295
- async function getUninstallManifest(claudeDir, kit) {
34296
- const detection = await detectMetadataFormat(claudeDir);
34297
- if (detection.format === "multi-kit" && detection.metadata?.kits) {
34298
- const installedKits = Object.keys(detection.metadata.kits);
34299
- if (kit) {
34300
- const kitMeta = detection.metadata.kits[kit];
34301
- if (!kitMeta?.files) {
34302
- return {
34303
- filesToRemove: [],
34304
- filesToPreserve: USER_CONFIG_PATTERNS,
34305
- hasManifest: true,
34306
- isMultiKit: true,
34307
- remainingKits: installedKits.filter((k2) => k2 !== kit)
34308
- };
34309
- }
34310
- const kitFiles = kitMeta.files.map((f3) => f3.path);
34311
- const sharedFiles = new Set;
34312
- for (const otherKit of installedKits) {
34313
- if (otherKit !== kit) {
34314
- const otherMeta = detection.metadata.kits[otherKit];
34315
- if (otherMeta?.files) {
34316
- for (const f3 of otherMeta.files) {
34317
- sharedFiles.add(f3.path);
34318
- }
34319
- }
34320
- }
34321
- }
34322
- const filesToRemove = kitFiles.filter((f3) => !sharedFiles.has(f3));
34323
- const filesToPreserve = [
34324
- ...USER_CONFIG_PATTERNS,
34325
- ...kitFiles.filter((f3) => sharedFiles.has(f3))
34326
- ];
34327
- return {
34328
- filesToRemove,
34329
- filesToPreserve,
34330
- hasManifest: true,
34331
- isMultiKit: true,
34332
- remainingKits: installedKits.filter((k2) => k2 !== kit)
34333
- };
34334
- }
34335
- const allFiles = getAllTrackedFiles(detection.metadata);
34336
- return {
34337
- filesToRemove: allFiles.map((f3) => f3.path),
34338
- filesToPreserve: USER_CONFIG_PATTERNS,
34339
- hasManifest: true,
34340
- isMultiKit: true,
34341
- remainingKits: []
34342
- };
34343
- }
34344
- if (detection.format === "legacy" && detection.metadata) {
34345
- const legacyFiles2 = detection.metadata.files?.map((f3) => f3.path) || [];
34346
- const installedFiles = detection.metadata.installedFiles || [];
34347
- const hasFiles = legacyFiles2.length > 0 || installedFiles.length > 0;
34348
- if (!hasFiles) {
34349
- const legacyDirs2 = ["commands", "agents", "skills", "workflows", "hooks", "scripts"];
34350
- const legacyFileList = ["metadata.json"];
34351
- return {
34352
- filesToRemove: [...legacyDirs2, ...legacyFileList],
34353
- filesToPreserve: USER_CONFIG_PATTERNS,
34354
- hasManifest: false,
34355
- isMultiKit: false,
34356
- remainingKits: []
34357
- };
34358
- }
34359
- return {
34360
- filesToRemove: legacyFiles2.length > 0 ? legacyFiles2 : installedFiles,
34361
- filesToPreserve: detection.metadata.userConfigFiles || USER_CONFIG_PATTERNS,
34362
- hasManifest: true,
34363
- isMultiKit: false,
34364
- remainingKits: []
34365
- };
34366
- }
34367
- const legacyDirs = ["commands", "agents", "skills", "workflows", "hooks", "scripts"];
34368
- const legacyFiles = ["metadata.json"];
34369
- return {
34370
- filesToRemove: [...legacyDirs, ...legacyFiles],
34371
- filesToPreserve: USER_CONFIG_PATTERNS,
34372
- hasManifest: false,
34373
- isMultiKit: false,
34374
- remainingKits: []
34375
- };
34376
- }
34377
36509
  // src/services/file-operations/manifest/manifest-tracker.ts
34378
36510
  import { join as join42 } from "node:path";
34379
36511
 
@@ -34385,7 +36517,8 @@ import { join as join40 } from "node:path";
34385
36517
  var ReleaseManifestFileSchema = exports_external.object({
34386
36518
  path: exports_external.string(),
34387
36519
  checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
34388
- size: exports_external.number()
36520
+ size: exports_external.number(),
36521
+ lastModified: exports_external.string().datetime({ offset: true }).optional()
34389
36522
  });
34390
36523
  var ReleaseManifestSchema = exports_external.object({
34391
36524
  version: exports_external.string(),
@@ -34593,15 +36726,17 @@ async function writeManifest(claudeDir, kitName, version, scope, kitType, tracke
34593
36726
  installedAt,
34594
36727
  files: trackedFiles.length > 0 ? trackedFiles : undefined
34595
36728
  };
36729
+ const existingKits = existingMetadata.kits || {};
36730
+ const otherKitsExist = Object.keys(existingKits).some((k2) => k2 !== kit);
34596
36731
  const metadata = {
34597
36732
  kits: {
34598
- ...existingMetadata.kits || {},
36733
+ ...existingKits,
34599
36734
  [kit]: kitMetadata
34600
36735
  },
34601
36736
  scope,
34602
- name: kitName,
34603
- version,
34604
- installedAt,
36737
+ name: otherKitsExist ? existingMetadata.name ?? kitName : kitName,
36738
+ version: otherKitsExist ? existingMetadata.version ?? version : version,
36739
+ installedAt: otherKitsExist ? existingMetadata.installedAt ?? installedAt : installedAt,
34605
36740
  userConfigFiles: [...USER_CONFIG_PATTERNS, ...userConfigFiles]
34606
36741
  };
34607
36742
  const validated = MetadataSchema.parse(metadata);
@@ -34672,14 +36807,16 @@ class ManifestTracker {
34672
36807
  getUserConfigFiles() {
34673
36808
  return Array.from(this.userConfigFiles).sort();
34674
36809
  }
34675
- async addTrackedFile(filePath, relativePath, ownership, installedVersion) {
36810
+ async addTrackedFile(filePath, relativePath, ownership, installedVersion, sourceTimestamp) {
34676
36811
  const checksum = await OwnershipChecker.calculateChecksum(filePath);
34677
36812
  const normalized = relativePath.replace(/\\/g, "/");
34678
36813
  this.trackedFiles.set(normalized, {
34679
36814
  path: normalized,
34680
36815
  checksum,
34681
36816
  ownership,
34682
- installedVersion
36817
+ installedVersion,
36818
+ sourceTimestamp,
36819
+ installedAt: new Date().toISOString()
34683
36820
  });
34684
36821
  this.installedFiles.add(normalized);
34685
36822
  }
@@ -34695,7 +36832,9 @@ class ManifestTracker {
34695
36832
  path: normalized,
34696
36833
  checksum,
34697
36834
  ownership: file.ownership,
34698
- installedVersion: file.installedVersion
36835
+ installedVersion: file.installedVersion,
36836
+ sourceTimestamp: file.sourceTimestamp,
36837
+ installedAt: new Date().toISOString()
34699
36838
  });
34700
36839
  this.installedFiles.add(normalized);
34701
36840
  return true;
@@ -34748,7 +36887,8 @@ function buildFileTrackingList(options) {
34748
36887
  filePath,
34749
36888
  relativePath,
34750
36889
  ownership,
34751
- installedVersion
36890
+ installedVersion,
36891
+ sourceTimestamp: manifestEntry?.lastModified
34752
36892
  });
34753
36893
  }
34754
36894
  return filesToTrack;
@@ -34974,6 +37114,101 @@ User-created files (sample):`);
34974
37114
  }
34975
37115
  }
34976
37116
 
37117
+ // src/domains/ui/conflict-summary.ts
37118
+ init_logger();
37119
+ var import_picocolors17 = __toESM(require_picocolors(), 1);
37120
+ function displayConflictSummary(summary) {
37121
+ const totalUpdated = summary.files.updated.length + summary.hooks.updated.length + summary.mcp.updated.length;
37122
+ const totalKept = summary.files.kept.length + summary.hooks.kept.length + summary.mcp.kept.length;
37123
+ if (totalUpdated === 0 && totalKept === 0) {
37124
+ logger.verbose("No conflicts detected during installation");
37125
+ return;
37126
+ }
37127
+ console.log();
37128
+ console.log(import_picocolors17.default.bold("Dual-Kit Conflict Resolution"));
37129
+ console.log(import_picocolors17.default.dim("─".repeat(40)));
37130
+ if (summary.files.updated.length > 0 || summary.files.kept.length > 0) {
37131
+ const updated = summary.files.updated.length;
37132
+ const kept = summary.files.kept.length;
37133
+ const winners = formatWinners(summary.files.updated);
37134
+ console.log(` Files: ${import_picocolors17.default.green(`${updated} updated`)}${winners}, ${import_picocolors17.default.dim(`${kept} kept`)}`);
37135
+ }
37136
+ if (summary.hooks.updated.length > 0 || summary.hooks.kept.length > 0) {
37137
+ const updated = summary.hooks.updated.length;
37138
+ const kept = summary.hooks.kept.length;
37139
+ const winners = formatHookWinners(summary.hooks.updated);
37140
+ console.log(` Hooks: ${import_picocolors17.default.green(`${updated} updated`)}${winners}, ${import_picocolors17.default.dim(`${kept} kept`)}`);
37141
+ }
37142
+ if (summary.mcp.updated.length > 0 || summary.mcp.kept.length > 0) {
37143
+ const updated = summary.mcp.updated.length;
37144
+ const kept = summary.mcp.kept.length;
37145
+ const winners = formatMcpWinners(summary.mcp.updated);
37146
+ console.log(` MCP: ${import_picocolors17.default.green(`${updated} updated`)}${winners}, ${import_picocolors17.default.dim(`${kept} kept`)}`);
37147
+ }
37148
+ if (logger.isVerbose() && totalUpdated > 0) {
37149
+ console.log();
37150
+ console.log(import_picocolors17.default.dim("Details:"));
37151
+ for (const file of summary.files.updated) {
37152
+ console.log(` ${import_picocolors17.default.dim("-")} ${file.relativePath}: ${import_picocolors17.default.green(file.winner)} won`);
37153
+ }
37154
+ for (const hook of summary.hooks.updated) {
37155
+ const shortCmd = hook.command.length > 40 ? `${hook.command.slice(0, 40)}...` : hook.command;
37156
+ console.log(` ${import_picocolors17.default.dim("-")} hook: ${shortCmd} → ${import_picocolors17.default.green(hook.winner)}`);
37157
+ }
37158
+ for (const mcp of summary.mcp.updated) {
37159
+ console.log(` ${import_picocolors17.default.dim("-")} mcp: ${mcp.serverName} → ${import_picocolors17.default.green(mcp.winner)}`);
37160
+ }
37161
+ }
37162
+ console.log();
37163
+ }
37164
+ function formatWinners(items) {
37165
+ const counts = new Map;
37166
+ for (const item of items) {
37167
+ const kit = item.winner === "incoming" ? item.incomingKit : item.existingKit;
37168
+ counts.set(kit, (counts.get(kit) ?? 0) + 1);
37169
+ }
37170
+ if (counts.size === 0)
37171
+ return "";
37172
+ const parts = Array.from(counts.entries()).map(([kit, count]) => `${kit}: ${count}`);
37173
+ return import_picocolors17.default.dim(` (${parts.join(", ")})`);
37174
+ }
37175
+ function formatHookWinners(items) {
37176
+ const counts = new Map;
37177
+ for (const item of items) {
37178
+ counts.set(item.winner, (counts.get(item.winner) ?? 0) + 1);
37179
+ }
37180
+ if (counts.size === 0)
37181
+ return "";
37182
+ const parts = Array.from(counts.entries()).map(([kit, count]) => `${kit}: ${count}`);
37183
+ return import_picocolors17.default.dim(` (${parts.join(", ")})`);
37184
+ }
37185
+ function formatMcpWinners(items) {
37186
+ const counts = new Map;
37187
+ for (const item of items) {
37188
+ counts.set(item.winner, (counts.get(item.winner) ?? 0) + 1);
37189
+ }
37190
+ if (counts.size === 0)
37191
+ return "";
37192
+ const parts = Array.from(counts.entries()).map(([kit, count]) => `${kit}: ${count}`);
37193
+ return import_picocolors17.default.dim(` (${parts.join(", ")})`);
37194
+ }
37195
+ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
37196
+ return {
37197
+ files: {
37198
+ updated: fileConflicts.filter((c2) => c2.winner === "incoming"),
37199
+ kept: fileConflicts.filter((c2) => c2.winner === "existing")
37200
+ },
37201
+ hooks: {
37202
+ updated: hookConflicts.filter((c2) => c2.winner !== "existing"),
37203
+ kept: hookConflicts.filter((c2) => c2.winner === "existing")
37204
+ },
37205
+ mcp: {
37206
+ updated: mcpConflicts.filter((c2) => c2.winner !== "existing"),
37207
+ kept: mcpConflicts.filter((c2) => c2.winner === "existing")
37208
+ }
37209
+ };
37210
+ }
37211
+
34977
37212
  // src/services/file-operations/file-scanner.ts
34978
37213
  import { join as join44, relative as relative8, resolve as resolve6 } from "node:path";
34979
37214
  init_logger();
@@ -35440,6 +37675,9 @@ async function handleMerge(ctx) {
35440
37675
  merger.setForceOverwriteSettings(ctx.options.forceOverwriteSettings);
35441
37676
  merger.setProjectDir(ctx.resolvedDir);
35442
37677
  merger.setKitName(ctx.kit.name);
37678
+ if (ctx.kitType) {
37679
+ merger.setMultiKitContext(ctx.claudeDir, ctx.kitType);
37680
+ }
35443
37681
  const releaseManifest = await ReleaseManifestLoader.load(ctx.extractDir);
35444
37682
  if (releaseManifest) {
35445
37683
  merger.setManifest(releaseManifest);
@@ -35466,6 +37704,11 @@ async function handleMerge(ctx) {
35466
37704
  }
35467
37705
  const sourceDir = ctx.options.global ? join48(ctx.extractDir, ".claude") : ctx.extractDir;
35468
37706
  await merger.merge(sourceDir, ctx.resolvedDir, ctx.isNonInteractive);
37707
+ const fileConflicts = merger.getFileConflicts();
37708
+ if (fileConflicts.length > 0 && !ctx.isNonInteractive) {
37709
+ const summary = buildConflictSummary(fileConflicts, [], []);
37710
+ displayConflictSummary(summary);
37711
+ }
35469
37712
  const installedFiles = merger.getAllInstalledFiles();
35470
37713
  const filesToTrack = buildFileTrackingList({
35471
37714
  installedFiles,
@@ -37277,6 +39520,31 @@ Optional: DISCORD_WEBHOOK_URL, TELEGRAM_BOT_TOKEN`, "Configuration skipped");
37277
39520
  import { mkdir as mkdir19 } from "node:fs/promises";
37278
39521
  import { join as join62, resolve as resolve7 } from "node:path";
37279
39522
 
39523
+ // src/domains/github/kit-access-checker.ts
39524
+ init_logger();
39525
+ init_types2();
39526
+ async function detectAccessibleKits() {
39527
+ const spinner = createSpinner("Checking kit access...").start();
39528
+ const github = new GitHubClient;
39529
+ const results = await Promise.all(Object.entries(AVAILABLE_KITS).map(async ([type, config]) => {
39530
+ try {
39531
+ await github.checkAccess(config);
39532
+ logger.debug(`Access confirmed: ${type}`);
39533
+ return type;
39534
+ } catch {
39535
+ logger.debug(`No access to ${type}`);
39536
+ return null;
39537
+ }
39538
+ }));
39539
+ const accessible = results.filter((kit) => kit !== null);
39540
+ if (accessible.length === 0) {
39541
+ spinner.fail("No kit access found");
39542
+ } else {
39543
+ spinner.succeed(`Access verified: ${accessible.join(", ")}`);
39544
+ }
39545
+ return accessible;
39546
+ }
39547
+
37280
39548
  // src/domains/installation/fresh-installer.ts
37281
39549
  init_logger();
37282
39550
  import { join as join61 } from "node:path";
@@ -37339,13 +39607,33 @@ async function handleSelection(ctx) {
37339
39607
  };
37340
39608
  }
37341
39609
  const config = await ConfigManager.get();
39610
+ let accessibleKits;
39611
+ if (!ctx.options.useGit) {
39612
+ accessibleKits = await detectAccessibleKits();
39613
+ if (accessibleKits.length === 0) {
39614
+ logger.error("No ClaudeKit access found.");
39615
+ logger.info("Purchase at https://claudekit.cc");
39616
+ return { ...ctx, cancelled: true };
39617
+ }
39618
+ }
37342
39619
  let kitType = ctx.options.kit || config.defaults?.kit;
39620
+ if (kitType && accessibleKits && !accessibleKits.includes(kitType)) {
39621
+ logger.error(`No access to ${AVAILABLE_KITS[kitType].name}`);
39622
+ logger.info("Purchase at https://claudekit.cc");
39623
+ return { ...ctx, cancelled: true };
39624
+ }
37343
39625
  if (!kitType) {
37344
39626
  if (ctx.isNonInteractive) {
37345
- kitType = "engineer";
37346
- logger.info("Using default kit: engineer");
39627
+ if (!accessibleKits || accessibleKits.length === 0) {
39628
+ throw new Error("Kit must be specified via --kit flag in non-interactive mode (no accessible kits detected)");
39629
+ }
39630
+ kitType = accessibleKits[0];
39631
+ logger.info(`Auto-selected: ${AVAILABLE_KITS[kitType].name}`);
39632
+ } else if (accessibleKits?.length === 1) {
39633
+ kitType = accessibleKits[0];
39634
+ logger.info(`Using ${AVAILABLE_KITS[kitType].name} (only accessible kit)`);
37347
39635
  } else {
37348
- kitType = await ctx.prompts.selectKit();
39636
+ kitType = await ctx.prompts.selectKit(undefined, accessibleKits);
37349
39637
  }
37350
39638
  }
37351
39639
  const kit = AVAILABLE_KITS[kitType];
@@ -37379,6 +39667,38 @@ async function handleSelection(ctx) {
37379
39667
  return { ...ctx, cancelled: true };
37380
39668
  }
37381
39669
  }
39670
+ if (!ctx.options.fresh) {
39671
+ const prefix = PathResolver.getPathPrefix(ctx.options.global);
39672
+ const claudeDir = prefix ? join62(resolvedDir, prefix) : resolvedDir;
39673
+ try {
39674
+ const existingMetadata = await readManifest(claudeDir);
39675
+ if (existingMetadata?.kits) {
39676
+ const existingKitTypes = Object.keys(existingMetadata.kits);
39677
+ const otherKits = existingKitTypes.filter((k2) => k2 !== kitType);
39678
+ if (otherKits.length > 0) {
39679
+ const existingKitsDisplay = otherKits.map((k2) => `${k2}@${existingMetadata.kits?.[k2]?.version || "unknown"}`).join(", ");
39680
+ if (!ctx.options.yes && !ctx.isNonInteractive) {
39681
+ try {
39682
+ const confirmAdd = await ctx.prompts.confirm(`${existingKitsDisplay} already installed. Add ${kit.name} alongside?`);
39683
+ if (!confirmAdd) {
39684
+ logger.warning("Multi-kit installation cancelled by user");
39685
+ return { ...ctx, cancelled: true };
39686
+ }
39687
+ logger.info(`Adding ${kit.name} alongside existing kit(s)`);
39688
+ } catch {
39689
+ logger.warning("Prompt cancelled or interrupted");
39690
+ return { ...ctx, cancelled: true };
39691
+ }
39692
+ } else {
39693
+ const reason = ctx.options.yes ? "(--yes flag)" : "(non-interactive mode)";
39694
+ logger.info(`Adding ${kit.name} alongside ${existingKitsDisplay} ${reason}`);
39695
+ }
39696
+ }
39697
+ }
39698
+ } catch (error) {
39699
+ logger.debug(`Metadata read skipped: ${error instanceof Error ? error.message : "unknown error"}`);
39700
+ }
39701
+ }
37382
39702
  if (ctx.options.fresh) {
37383
39703
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
37384
39704
  const claudeDir = prefix ? join62(resolvedDir, prefix) : resolvedDir;
@@ -37388,20 +39708,6 @@ async function handleSelection(ctx) {
37388
39708
  }
37389
39709
  }
37390
39710
  const github = new GitHubClient;
37391
- if (!ctx.options.useGit) {
37392
- const spinner = createSpinner("Checking repository access...").start();
37393
- logger.verbose("GitHub API check", { repo: kit.repo, owner: kit.owner });
37394
- try {
37395
- await github.checkAccess(kit);
37396
- spinner.succeed("Repository access verified");
37397
- } catch (error) {
37398
- spinner.fail("Access denied to repository");
37399
- logger.error(error.message || `Cannot access ${kit.name}`);
37400
- return { ...ctx, cancelled: true };
37401
- }
37402
- } else {
37403
- logger.verbose("Skipping API access check (--use-git mode)");
37404
- }
37405
39711
  let selectedVersion = ctx.options.release;
37406
39712
  if (!selectedVersion && ctx.isNonInteractive && !ctx.options.yes) {
37407
39713
  throw new Error("Non-interactive mode requires either: --release <tag> OR --yes (uses latest)");
@@ -37483,7 +39789,7 @@ import { copyFile as copyFile6, mkdir as mkdir20, open, rename as rename3, stat
37483
39789
  import { dirname as dirname9, join as join63, resolve as resolve8 } from "node:path";
37484
39790
  init_logger();
37485
39791
  var import_fs_extra30 = __toESM(require_lib(), 1);
37486
- var import_picocolors18 = __toESM(require_picocolors(), 1);
39792
+ var import_picocolors19 = __toESM(require_picocolors(), 1);
37487
39793
  async function handleSync(ctx) {
37488
39794
  if (!ctx.options.sync) {
37489
39795
  return ctx;
@@ -37651,7 +39957,7 @@ async function executeSyncMerge(ctx) {
37651
39957
  }
37652
39958
  const backupDir = PathResolver.getBackupDir();
37653
39959
  await createBackup(ctx.claudeDir, trackedFiles, backupDir);
37654
- logger.success(`Backup created at ${import_picocolors18.default.dim(backupDir)}`);
39960
+ logger.success(`Backup created at ${import_picocolors19.default.dim(backupDir)}`);
37655
39961
  if (plan.autoUpdate.length > 0) {
37656
39962
  logger.info(`Auto-updating ${plan.autoUpdate.length} file(s)...`);
37657
39963
  let updateSuccess = 0;
@@ -37761,22 +40067,22 @@ async function executeSyncMerge(ctx) {
37761
40067
  totalRejected += result.rejected;
37762
40068
  }
37763
40069
  console.log("");
37764
- console.log(import_picocolors18.default.bold("Sync Summary:"));
37765
- console.log(import_picocolors18.default.dim("─".repeat(40)));
40070
+ console.log(import_picocolors19.default.bold("Sync Summary:"));
40071
+ console.log(import_picocolors19.default.dim("─".repeat(40)));
37766
40072
  if (plan.autoUpdate.length > 0) {
37767
- console.log(import_picocolors18.default.green(` ✓ ${plan.autoUpdate.length} file(s) auto-updated`));
40073
+ console.log(import_picocolors19.default.green(` ✓ ${plan.autoUpdate.length} file(s) auto-updated`));
37768
40074
  }
37769
40075
  if (totalApplied > 0) {
37770
- console.log(import_picocolors18.default.green(` ✓ ${totalApplied} hunk(s) applied`));
40076
+ console.log(import_picocolors19.default.green(` ✓ ${totalApplied} hunk(s) applied`));
37771
40077
  }
37772
40078
  if (totalRejected > 0) {
37773
- console.log(import_picocolors18.default.yellow(` ○ ${totalRejected} hunk(s) rejected`));
40079
+ console.log(import_picocolors19.default.yellow(` ○ ${totalRejected} hunk(s) rejected`));
37774
40080
  }
37775
40081
  if (skippedFiles > 0) {
37776
- console.log(import_picocolors18.default.yellow(` ○ ${skippedFiles} file(s) skipped`));
40082
+ console.log(import_picocolors19.default.yellow(` ○ ${skippedFiles} file(s) skipped`));
37777
40083
  }
37778
40084
  if (plan.skipped.length > 0) {
37779
- console.log(import_picocolors18.default.dim(` ─ ${plan.skipped.length} user-owned file(s) unchanged`));
40085
+ console.log(import_picocolors19.default.dim(` ─ ${plan.skipped.length} user-owned file(s) unchanged`));
37780
40086
  }
37781
40087
  } else if (plan.needsReview.length > 0 && ctx.isNonInteractive) {
37782
40088
  logger.error(`Cannot complete sync: ${plan.needsReview.length} file(s) require interactive review`);
@@ -37799,30 +40105,30 @@ Options:
37799
40105
  }
37800
40106
  function displaySyncPlan(plan) {
37801
40107
  console.log("");
37802
- console.log(import_picocolors18.default.bold("Sync Plan:"));
37803
- console.log(import_picocolors18.default.dim("─".repeat(40)));
40108
+ console.log(import_picocolors19.default.bold("Sync Plan:"));
40109
+ console.log(import_picocolors19.default.dim("─".repeat(40)));
37804
40110
  if (plan.autoUpdate.length > 0) {
37805
- console.log(import_picocolors18.default.green(` ${plan.autoUpdate.length} file(s) will be auto-updated`));
40111
+ console.log(import_picocolors19.default.green(` ${plan.autoUpdate.length} file(s) will be auto-updated`));
37806
40112
  for (const file of plan.autoUpdate.slice(0, 5)) {
37807
- console.log(import_picocolors18.default.dim(` • ${file.path}`));
40113
+ console.log(import_picocolors19.default.dim(` • ${file.path}`));
37808
40114
  }
37809
40115
  if (plan.autoUpdate.length > 5) {
37810
- console.log(import_picocolors18.default.dim(` ... and ${plan.autoUpdate.length - 5} more`));
40116
+ console.log(import_picocolors19.default.dim(` ... and ${plan.autoUpdate.length - 5} more`));
37811
40117
  }
37812
40118
  }
37813
40119
  if (plan.needsReview.length > 0) {
37814
- console.log(import_picocolors18.default.yellow(` ${plan.needsReview.length} file(s) need interactive review`));
40120
+ console.log(import_picocolors19.default.yellow(` ${plan.needsReview.length} file(s) need interactive review`));
37815
40121
  for (const file of plan.needsReview.slice(0, 5)) {
37816
- console.log(import_picocolors18.default.dim(` • ${file.path}`));
40122
+ console.log(import_picocolors19.default.dim(` • ${file.path}`));
37817
40123
  }
37818
40124
  if (plan.needsReview.length > 5) {
37819
- console.log(import_picocolors18.default.dim(` ... and ${plan.needsReview.length - 5} more`));
40125
+ console.log(import_picocolors19.default.dim(` ... and ${plan.needsReview.length - 5} more`));
37820
40126
  }
37821
40127
  }
37822
40128
  if (plan.skipped.length > 0) {
37823
- console.log(import_picocolors18.default.dim(` ${plan.skipped.length} user-owned file(s) will be skipped`));
40129
+ console.log(import_picocolors19.default.dim(` ${plan.skipped.length} user-owned file(s) will be skipped`));
37824
40130
  }
37825
- console.log(import_picocolors18.default.dim("─".repeat(40)));
40131
+ console.log(import_picocolors19.default.dim("─".repeat(40)));
37826
40132
  }
37827
40133
  async function createBackup(claudeDir, files, backupDir) {
37828
40134
  await mkdir20(backupDir, { recursive: true });
@@ -38146,6 +40452,24 @@ function transformContent(content) {
38146
40452
  return homePrefix;
38147
40453
  });
38148
40454
  }
40455
+ transformed = transformed.replace(/\$CLAUDE_PROJECT_DIR\/\.claude\//g, () => {
40456
+ changes++;
40457
+ return claudePath;
40458
+ });
40459
+ transformed = transformed.replace(/"\$CLAUDE_PROJECT_DIR"\/\.claude\//g, () => {
40460
+ changes++;
40461
+ return `"${homePrefix}"/.claude/`;
40462
+ });
40463
+ transformed = transformed.replace(/\$\{CLAUDE_PROJECT_DIR\}\/\.claude\//g, () => {
40464
+ changes++;
40465
+ return claudePath;
40466
+ });
40467
+ if (IS_WINDOWS3) {
40468
+ transformed = transformed.replace(/%CLAUDE_PROJECT_DIR%\/\.claude\//g, () => {
40469
+ changes++;
40470
+ return claudePath;
40471
+ });
40472
+ }
38149
40473
  transformed = transformed.replace(/\.\/\.claude\//g, () => {
38150
40474
  changes++;
38151
40475
  return claudePath;
@@ -38381,7 +40705,7 @@ Protected files (.env, etc.) were not modified.`;
38381
40705
  // src/commands/new/new-command.ts
38382
40706
  init_logger();
38383
40707
  init_types2();
38384
- var import_picocolors19 = __toESM(require_picocolors(), 1);
40708
+ var import_picocolors20 = __toESM(require_picocolors(), 1);
38385
40709
 
38386
40710
  // src/commands/new/phases/directory-setup.ts
38387
40711
  import { resolve as resolve9 } from "node:path";
@@ -38391,12 +40715,34 @@ var import_fs_extra32 = __toESM(require_lib(), 1);
38391
40715
  async function directorySetup(validOptions, prompts) {
38392
40716
  const isNonInteractive2 = !process.stdin.isTTY || process.env.CI === "true" || process.env.NON_INTERACTIVE === "true";
38393
40717
  const config = await ConfigManager.get();
40718
+ let accessibleKits;
40719
+ if (!validOptions.useGit) {
40720
+ accessibleKits = await detectAccessibleKits();
40721
+ if (accessibleKits.length === 0) {
40722
+ logger.error("No ClaudeKit access found.");
40723
+ logger.info("Purchase at https://claudekit.cc");
40724
+ return null;
40725
+ }
40726
+ }
38394
40727
  let kit = validOptions.kit || config.defaults?.kit;
40728
+ if (kit && accessibleKits && !accessibleKits.includes(kit)) {
40729
+ logger.error(`No access to ${AVAILABLE_KITS[kit].name}`);
40730
+ logger.info("Purchase at https://claudekit.cc");
40731
+ return null;
40732
+ }
38395
40733
  if (!kit) {
38396
40734
  if (isNonInteractive2) {
38397
- throw new Error("Kit must be specified via --kit flag in non-interactive mode");
40735
+ kit = accessibleKits?.[0];
40736
+ if (!kit) {
40737
+ throw new Error("Kit must be specified via --kit flag in non-interactive mode");
40738
+ }
40739
+ logger.info(`Auto-selected: ${AVAILABLE_KITS[kit].name}`);
40740
+ } else if (accessibleKits?.length === 1) {
40741
+ kit = accessibleKits[0];
40742
+ logger.info(`Using ${AVAILABLE_KITS[kit].name} (only accessible kit)`);
40743
+ } else {
40744
+ kit = await prompts.selectKit(undefined, accessibleKits);
38398
40745
  }
38399
- kit = await prompts.selectKit();
38400
40746
  }
38401
40747
  const kitConfig = AVAILABLE_KITS[kit];
38402
40748
  logger.info(`Selected kit: ${kitConfig.name}`);
@@ -38520,20 +40866,6 @@ async function selectVersion2(kit, options, isNonInteractive2, prompts, github)
38520
40866
  async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2, prompts) {
38521
40867
  const kitConfig = AVAILABLE_KITS[kit];
38522
40868
  const github = new GitHubClient;
38523
- if (!validOptions.useGit) {
38524
- const spinner = createSpinner("Checking repository access...").start();
38525
- logger.verbose("GitHub API check", { repo: kitConfig.repo, owner: kitConfig.owner });
38526
- try {
38527
- await github.checkAccess(kitConfig);
38528
- spinner.succeed("Repository access verified");
38529
- } catch (error) {
38530
- spinner.fail("Access denied to repository");
38531
- logger.error(error.message || `Cannot access ${kitConfig.name}`);
38532
- return null;
38533
- }
38534
- } else {
38535
- logger.verbose("Skipping API access check (--use-git mode)");
38536
- }
38537
40869
  const versionResult = await selectVersion2(kitConfig, validOptions, isNonInteractive2, prompts, github);
38538
40870
  if (!versionResult) {
38539
40871
  return null;
@@ -38569,6 +40901,8 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
38569
40901
  output.section("Installing");
38570
40902
  logger.verbose("Installation target", { directory: resolvedDir });
38571
40903
  const merger = new FileMerger;
40904
+ const claudeDir = join68(resolvedDir, ".claude");
40905
+ merger.setMultiKitContext(claudeDir, kit);
38572
40906
  if (validOptions.exclude && validOptions.exclude.length > 0) {
38573
40907
  merger.addIgnorePatterns(validOptions.exclude);
38574
40908
  }
@@ -38576,7 +40910,6 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
38576
40910
  await CommandsPrefix.cleanupCommandsDirectory(resolvedDir, false);
38577
40911
  }
38578
40912
  await merger.merge(extractDir, resolvedDir, true);
38579
- const claudeDir = join68(resolvedDir, ".claude");
38580
40913
  const releaseManifest = await ReleaseManifestLoader.load(extractDir);
38581
40914
  const installedFiles = merger.getAllInstalledFiles();
38582
40915
  const filesToTrack = buildFileTrackingList({
@@ -38683,7 +41016,7 @@ async function newCommand(options) {
38683
41016
  if (ctx.cancelled)
38684
41017
  return;
38685
41018
  prompts.outro(`✨ Project created successfully at ${ctx.resolvedDir}`);
38686
- log.info(`${import_picocolors19.default.dim("Tip:")} To update later: ${import_picocolors19.default.cyan("ck update")} (CLI) + ${import_picocolors19.default.cyan("ck init")} (kit content)`);
41019
+ log.info(`${import_picocolors20.default.dim("Tip:")} To update later: ${import_picocolors20.default.cyan("ck update")} (CLI) + ${import_picocolors20.default.cyan("ck init")} (kit content)`);
38687
41020
  } catch (error) {
38688
41021
  logger.error(error instanceof Error ? error.message : "Unknown error occurred");
38689
41022
  process.exit(1);
@@ -38692,7 +41025,7 @@ async function newCommand(options) {
38692
41025
  // src/commands/uninstall/uninstall-command.ts
38693
41026
  init_logger();
38694
41027
  init_types2();
38695
- var import_picocolors21 = __toESM(require_picocolors(), 1);
41028
+ var import_picocolors22 = __toESM(require_picocolors(), 1);
38696
41029
 
38697
41030
  // src/commands/uninstall/installation-detector.ts
38698
41031
  var import_fs_extra33 = __toESM(require_lib(), 1);
@@ -38726,7 +41059,7 @@ var import_fs_extra34 = __toESM(require_lib(), 1);
38726
41059
  import { readdirSync, rmSync } from "node:fs";
38727
41060
  import { dirname as dirname10, join as join69 } from "node:path";
38728
41061
  init_logger();
38729
- var import_picocolors20 = __toESM(require_picocolors(), 1);
41062
+ var import_picocolors21 = __toESM(require_picocolors(), 1);
38730
41063
  function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
38731
41064
  if (ownership === "ck") {
38732
41065
  return { action: "delete", reason: deleteReason };
@@ -38817,27 +41150,27 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
38817
41150
  }
38818
41151
  function displayDryRunPreview(analysis, installationType) {
38819
41152
  console.log("");
38820
- log.info(import_picocolors20.default.bold(`DRY RUN - Preview for ${installationType} installation:`));
41153
+ log.info(import_picocolors21.default.bold(`DRY RUN - Preview for ${installationType} installation:`));
38821
41154
  console.log("");
38822
41155
  if (analysis.toDelete.length > 0) {
38823
- console.log(import_picocolors20.default.red(import_picocolors20.default.bold(`Files to DELETE (${analysis.toDelete.length}):`)));
41156
+ console.log(import_picocolors21.default.red(import_picocolors21.default.bold(`Files to DELETE (${analysis.toDelete.length}):`)));
38824
41157
  const showDelete = analysis.toDelete.slice(0, 10);
38825
41158
  for (const item of showDelete) {
38826
- console.log(` ${import_picocolors20.default.red("✖")} ${item.path}`);
41159
+ console.log(` ${import_picocolors21.default.red("✖")} ${item.path}`);
38827
41160
  }
38828
41161
  if (analysis.toDelete.length > 10) {
38829
- console.log(import_picocolors20.default.gray(` ... and ${analysis.toDelete.length - 10} more`));
41162
+ console.log(import_picocolors21.default.gray(` ... and ${analysis.toDelete.length - 10} more`));
38830
41163
  }
38831
41164
  console.log("");
38832
41165
  }
38833
41166
  if (analysis.toPreserve.length > 0) {
38834
- console.log(import_picocolors20.default.green(import_picocolors20.default.bold(`Files to PRESERVE (${analysis.toPreserve.length}):`)));
41167
+ console.log(import_picocolors21.default.green(import_picocolors21.default.bold(`Files to PRESERVE (${analysis.toPreserve.length}):`)));
38835
41168
  const showPreserve = analysis.toPreserve.slice(0, 10);
38836
41169
  for (const item of showPreserve) {
38837
- console.log(` ${import_picocolors20.default.green("✓")} ${item.path} ${import_picocolors20.default.gray(`(${item.reason})`)}`);
41170
+ console.log(` ${import_picocolors21.default.green("✓")} ${item.path} ${import_picocolors21.default.gray(`(${item.reason})`)}`);
38838
41171
  }
38839
41172
  if (analysis.toPreserve.length > 10) {
38840
- console.log(import_picocolors20.default.gray(` ... and ${analysis.toPreserve.length - 10} more`));
41173
+ console.log(import_picocolors21.default.gray(` ... and ${analysis.toPreserve.length - 10} more`));
38841
41174
  }
38842
41175
  console.log("");
38843
41176
  }
@@ -38985,10 +41318,10 @@ async function uninstallCommand(options) {
38985
41318
  }
38986
41319
  displayInstallations(installations, scope);
38987
41320
  if (validOptions.kit) {
38988
- log.info(import_picocolors21.default.cyan(`Kit-scoped uninstall: ${validOptions.kit} kit only`));
41321
+ log.info(import_picocolors22.default.cyan(`Kit-scoped uninstall: ${validOptions.kit} kit only`));
38989
41322
  }
38990
41323
  if (validOptions.dryRun) {
38991
- log.info(import_picocolors21.default.yellow("DRY RUN MODE - No files will be deleted"));
41324
+ log.info(import_picocolors22.default.yellow("DRY RUN MODE - No files will be deleted"));
38992
41325
  await removeInstallations(installations, {
38993
41326
  dryRun: true,
38994
41327
  forceOverwrite: validOptions.forceOverwrite,
@@ -38998,8 +41331,8 @@ async function uninstallCommand(options) {
38998
41331
  return;
38999
41332
  }
39000
41333
  if (validOptions.forceOverwrite) {
39001
- log.warn(`${import_picocolors21.default.yellow(import_picocolors21.default.bold("FORCE MODE ENABLED"))}
39002
- ${import_picocolors21.default.yellow("User modifications will be permanently deleted!")}`);
41334
+ log.warn(`${import_picocolors22.default.yellow(import_picocolors22.default.bold("FORCE MODE ENABLED"))}
41335
+ ${import_picocolors22.default.yellow("User modifications will be permanently deleted!")}`);
39003
41336
  }
39004
41337
  if (!validOptions.yes) {
39005
41338
  const kitLabel = validOptions.kit ? ` (${validOptions.kit} kit only)` : "";
@@ -39338,7 +41671,7 @@ class CliVersionChecker {
39338
41671
  }
39339
41672
  }
39340
41673
  // src/domains/versioning/checking/notification-display.ts
39341
- var import_picocolors22 = __toESM(require_picocolors(), 1);
41674
+ var import_picocolors23 = __toESM(require_picocolors(), 1);
39342
41675
  function createNotificationBox2(borderColor, boxWidth) {
39343
41676
  const contentWidth = boxWidth - 2;
39344
41677
  const topBorder = borderColor(`╭${"─".repeat(contentWidth)}╮`);
@@ -39363,13 +41696,13 @@ function displayKitNotification(result, options = {}) {
39363
41696
  const displayCurrent = normalizeVersion(currentVersion);
39364
41697
  const displayLatest = normalizeVersion(latestVersion);
39365
41698
  const boxWidth = 52;
39366
- const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors22.default.cyan, boxWidth);
39367
- const headerText = import_picocolors22.default.bold(import_picocolors22.default.yellow("⬆ Kit Update Available"));
41699
+ const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors23.default.cyan, boxWidth);
41700
+ const headerText = import_picocolors23.default.bold(import_picocolors23.default.yellow("⬆ Kit Update Available"));
39368
41701
  const headerLen = "⬆ Kit Update Available".length;
39369
- const versionText = `${import_picocolors22.default.dim(displayCurrent)} ${import_picocolors22.default.white("→")} ${import_picocolors22.default.green(import_picocolors22.default.bold(displayLatest))}`;
41702
+ const versionText = `${import_picocolors23.default.dim(displayCurrent)} ${import_picocolors23.default.white("→")} ${import_picocolors23.default.green(import_picocolors23.default.bold(displayLatest))}`;
39370
41703
  const versionLen = displayCurrent.length + 3 + displayLatest.length;
39371
41704
  const updateCmd = isGlobal ? "ck init -g" : "ck init";
39372
- const commandText = `Run: ${import_picocolors22.default.cyan(import_picocolors22.default.bold(updateCmd))}`;
41705
+ const commandText = `Run: ${import_picocolors23.default.cyan(import_picocolors23.default.bold(updateCmd))}`;
39373
41706
  const commandLen = `Run: ${updateCmd}`.length;
39374
41707
  console.log("");
39375
41708
  console.log(topBorder);
@@ -39387,12 +41720,12 @@ function displayCliNotification(result) {
39387
41720
  return;
39388
41721
  const { currentVersion, latestVersion } = result;
39389
41722
  const boxWidth = 52;
39390
- const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors22.default.magenta, boxWidth);
39391
- const headerText = import_picocolors22.default.bold(import_picocolors22.default.yellow("⬆ CLI Update Available"));
41723
+ const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors23.default.magenta, boxWidth);
41724
+ const headerText = import_picocolors23.default.bold(import_picocolors23.default.yellow("⬆ CLI Update Available"));
39392
41725
  const headerLen = "⬆ CLI Update Available".length;
39393
- const versionText = `${import_picocolors22.default.dim(currentVersion)} ${import_picocolors22.default.white("→")} ${import_picocolors22.default.green(import_picocolors22.default.bold(latestVersion))}`;
41726
+ const versionText = `${import_picocolors23.default.dim(currentVersion)} ${import_picocolors23.default.white("→")} ${import_picocolors23.default.green(import_picocolors23.default.bold(latestVersion))}`;
39394
41727
  const versionLen = currentVersion.length + 3 + latestVersion.length;
39395
- const commandText = `Run: ${import_picocolors22.default.magenta(import_picocolors22.default.bold("ck update"))}`;
41728
+ const commandText = `Run: ${import_picocolors23.default.magenta(import_picocolors23.default.bold("ck update"))}`;
39396
41729
  const commandLen = "Run: ck update".length;
39397
41730
  console.log("");
39398
41731
  console.log(topBorder);
@@ -39429,11 +41762,11 @@ init_logger();
39429
41762
  init_types2();
39430
41763
  init_types2();
39431
41764
  var import_compare_versions5 = __toESM(require_umd(), 1);
39432
- var import_picocolors23 = __toESM(require_picocolors(), 1);
41765
+ var import_picocolors24 = __toESM(require_picocolors(), 1);
39433
41766
  // package.json
39434
41767
  var package_default = {
39435
41768
  name: "claudekit-cli",
39436
- version: "3.16.0",
41769
+ version: "3.18.0",
39437
41770
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
39438
41771
  type: "module",
39439
41772
  repository: {
@@ -39500,6 +41833,7 @@ var package_default = {
39500
41833
  "p-limit": "^7.2.0",
39501
41834
  picocolors: "^1.1.1",
39502
41835
  "proper-lockfile": "^4.1.2",
41836
+ semver: "^7.7.3",
39503
41837
  tar: "^7.4.3",
39504
41838
  tmp: "^0.2.3",
39505
41839
  zod: "^3.23.8"
@@ -39514,6 +41848,7 @@ var package_default = {
39514
41848
  "@types/fs-extra": "^11.0.4",
39515
41849
  "@types/node": "^22.10.1",
39516
41850
  "@types/proper-lockfile": "^4.1.4",
41851
+ "@types/semver": "^7.7.1",
39517
41852
  "@types/tar": "^6.1.13",
39518
41853
  "@types/tmp": "^0.2.6",
39519
41854
  "semantic-release": "^24.2.0",
@@ -39560,28 +41895,28 @@ async function displayKitUpdateReminder() {
39560
41895
  const maxCmdLen = Math.max(cmdLocal.length, cmdGlobal.length);
39561
41896
  const pad = (cmd) => cmd.padEnd(maxCmdLen);
39562
41897
  const lines = [];
39563
- lines.push(import_picocolors23.default.yellow(KIT_UPDATE_REMINDER_HEADER));
41898
+ lines.push(import_picocolors24.default.yellow(KIT_UPDATE_REMINDER_HEADER));
39564
41899
  lines.push("");
39565
41900
  lines.push("To update your ClaudeKit content (skills, commands, workflows):");
39566
41901
  if (hasLocal && localVersion) {
39567
- lines.push(` ${import_picocolors23.default.cyan(pad(cmdLocal))} Update local project (${localVersion})`);
41902
+ lines.push(` ${import_picocolors24.default.cyan(pad(cmdLocal))} Update local project (${localVersion})`);
39568
41903
  const localCheck = versionCheckResults.get(localVersion);
39569
41904
  if (localCheck?.updateAvailable) {
39570
41905
  const indent = " ".repeat(maxCmdLen + 4);
39571
- lines.push(`${indent}${import_picocolors23.default.green(`→ ${localCheck.latestVersion} available!`)}`);
41906
+ lines.push(`${indent}${import_picocolors24.default.green(`→ ${localCheck.latestVersion} available!`)}`);
39572
41907
  }
39573
41908
  } else {
39574
- lines.push(` ${import_picocolors23.default.cyan(pad(cmdLocal))} Initialize in current project`);
41909
+ lines.push(` ${import_picocolors24.default.cyan(pad(cmdLocal))} Initialize in current project`);
39575
41910
  }
39576
41911
  if (hasGlobal && globalVersion) {
39577
- lines.push(` ${import_picocolors23.default.cyan(pad(cmdGlobal))} Update global ~/.claude (${globalVersion})`);
41912
+ lines.push(` ${import_picocolors24.default.cyan(pad(cmdGlobal))} Update global ~/.claude (${globalVersion})`);
39578
41913
  const globalCheck = versionCheckResults.get(globalVersion);
39579
41914
  if (globalCheck?.updateAvailable) {
39580
41915
  const indent = " ".repeat(maxCmdLen + 4);
39581
- lines.push(`${indent}${import_picocolors23.default.green(`→ ${globalCheck.latestVersion} available!`)}`);
41916
+ lines.push(`${indent}${import_picocolors24.default.green(`→ ${globalCheck.latestVersion} available!`)}`);
39582
41917
  }
39583
41918
  } else {
39584
- lines.push(` ${import_picocolors23.default.cyan(pad(cmdGlobal))} Initialize global ~/.claude`);
41919
+ lines.push(` ${import_picocolors24.default.cyan(pad(cmdGlobal))} Initialize global ~/.claude`);
39585
41920
  }
39586
41921
  logger.info("");
39587
41922
  log.info(lines.join(`
@@ -39705,7 +42040,7 @@ Manual update: ${updateCmd}`);
39705
42040
  // src/commands/version.ts
39706
42041
  init_logger();
39707
42042
  init_types2();
39708
- var import_picocolors24 = __toESM(require_picocolors(), 1);
42043
+ var import_picocolors25 = __toESM(require_picocolors(), 1);
39709
42044
  function formatRelativeTime(dateString) {
39710
42045
  if (!dateString)
39711
42046
  return "Unknown";
@@ -39727,30 +42062,30 @@ function formatRelativeTime(dateString) {
39727
42062
  }
39728
42063
  function displayKitReleases(kitName, releases) {
39729
42064
  console.log(`
39730
- ${import_picocolors24.default.bold(import_picocolors24.default.cyan(kitName))} - Available Versions:
42065
+ ${import_picocolors25.default.bold(import_picocolors25.default.cyan(kitName))} - Available Versions:
39731
42066
  `);
39732
42067
  if (releases.length === 0) {
39733
- console.log(import_picocolors24.default.dim(" No releases found"));
42068
+ console.log(import_picocolors25.default.dim(" No releases found"));
39734
42069
  return;
39735
42070
  }
39736
42071
  for (const release of releases) {
39737
- const version = import_picocolors24.default.green(release.tag_name);
42072
+ const version = import_picocolors25.default.green(release.tag_name);
39738
42073
  const name2 = release.name || "No title";
39739
42074
  const publishedAt = formatRelativeTime(release.published_at);
39740
42075
  const assetCount = release.assets.length;
39741
42076
  const badges = [];
39742
42077
  if (release.prerelease)
39743
- badges.push(import_picocolors24.default.yellow("[prerelease]"));
42078
+ badges.push(import_picocolors25.default.yellow("[prerelease]"));
39744
42079
  if (release.draft)
39745
- badges.push(import_picocolors24.default.gray("[draft]"));
42080
+ badges.push(import_picocolors25.default.gray("[draft]"));
39746
42081
  const badgeStr = badges.length > 0 ? ` ${badges.join(" ")}` : "";
39747
42082
  const versionPart = version.padEnd(20);
39748
42083
  const namePart = name2.length > 40 ? `${name2.slice(0, 37)}...` : name2.padEnd(40);
39749
- const timePart = import_picocolors24.default.dim(publishedAt.padEnd(20));
39750
- const assetPart = import_picocolors24.default.dim(`(${assetCount} ${assetCount === 1 ? "asset" : "assets"})`);
42084
+ const timePart = import_picocolors25.default.dim(publishedAt.padEnd(20));
42085
+ const assetPart = import_picocolors25.default.dim(`(${assetCount} ${assetCount === 1 ? "asset" : "assets"})`);
39751
42086
  console.log(` ${versionPart} ${namePart} ${timePart} ${assetPart}${badgeStr}`);
39752
42087
  }
39753
- console.log(import_picocolors24.default.dim(`
42088
+ console.log(import_picocolors25.default.dim(`
39754
42089
  Showing ${releases.length} ${releases.length === 1 ? "release" : "releases"}`));
39755
42090
  }
39756
42091
  async function versionCommand(options) {
@@ -39785,8 +42120,8 @@ async function versionCommand(options) {
39785
42120
  for (const result of results) {
39786
42121
  if (result.error) {
39787
42122
  console.log(`
39788
- ${import_picocolors24.default.bold(import_picocolors24.default.cyan(result.kitConfig.name))} - ${import_picocolors24.default.red("Error")}`);
39789
- console.log(import_picocolors24.default.dim(` ${result.error}`));
42123
+ ${import_picocolors25.default.bold(import_picocolors25.default.cyan(result.kitConfig.name))} - ${import_picocolors25.default.red("Error")}`);
42124
+ console.log(import_picocolors25.default.dim(` ${result.error}`));
39790
42125
  } else {
39791
42126
  displayKitReleases(result.kitConfig.name, result.releases);
39792
42127
  }
@@ -39860,6 +42195,30 @@ import { join as join72 } from "node:path";
39860
42195
  init_logger();
39861
42196
  init_types2();
39862
42197
  var packageVersion = package_default.version;
42198
+ function formatInstalledKits(metadata) {
42199
+ if (!metadata.kits || Object.keys(metadata.kits).length === 0) {
42200
+ if (metadata.version) {
42201
+ const kitName = metadata.name || "ClaudeKit";
42202
+ return `${metadata.version} (${kitName})`;
42203
+ }
42204
+ return null;
42205
+ }
42206
+ const kitVersions = Object.entries(metadata.kits).filter(([_3, meta]) => meta.version && meta.version.trim() !== "").map(([kit, meta]) => `${kit}@${meta.version}`).sort().join(", ");
42207
+ return kitVersions.length > 0 ? kitVersions : null;
42208
+ }
42209
+ function getInstalledKitTypes(metadata) {
42210
+ if (!metadata.kits)
42211
+ return [];
42212
+ return Object.keys(metadata.kits);
42213
+ }
42214
+ function getFirstKitVersion(metadata) {
42215
+ const kitTypes = getInstalledKitTypes(metadata);
42216
+ if (kitTypes.length === 0) {
42217
+ return metadata.version ?? null;
42218
+ }
42219
+ const firstKit = kitTypes[0];
42220
+ return metadata.kits?.[firstKit]?.version ?? null;
42221
+ }
39863
42222
  async function displayVersion() {
39864
42223
  console.log(`CLI Version: ${packageVersion}`);
39865
42224
  let foundAnyKit = false;
@@ -39874,10 +42233,10 @@ async function displayVersion() {
39874
42233
  try {
39875
42234
  const rawMetadata = JSON.parse(readFileSync5(localMetadataPath, "utf-8"));
39876
42235
  const metadata = MetadataSchema.parse(rawMetadata);
39877
- if (metadata.version) {
39878
- const kitName = metadata.name || "ClaudeKit";
39879
- console.log(`Local Kit Version: ${metadata.version} (${kitName})`);
39880
- localKitVersion = metadata.version;
42236
+ const kitsDisplay = formatInstalledKits(metadata);
42237
+ if (kitsDisplay) {
42238
+ console.log(`Local Kit Version: ${kitsDisplay}`);
42239
+ localKitVersion = getFirstKitVersion(metadata);
39881
42240
  foundAnyKit = true;
39882
42241
  }
39883
42242
  } catch (error) {
@@ -39888,11 +42247,11 @@ async function displayVersion() {
39888
42247
  try {
39889
42248
  const rawMetadata = JSON.parse(readFileSync5(globalMetadataPath, "utf-8"));
39890
42249
  const metadata = MetadataSchema.parse(rawMetadata);
39891
- if (metadata.version) {
39892
- const kitName = metadata.name || "ClaudeKit";
39893
- console.log(`Global Kit Version: ${metadata.version} (${kitName})`);
42250
+ const kitsDisplay = formatInstalledKits(metadata);
42251
+ if (kitsDisplay) {
42252
+ console.log(`Global Kit Version: ${kitsDisplay}`);
39894
42253
  if (!localKitVersion) {
39895
- localKitVersion = metadata.version;
42254
+ localKitVersion = getFirstKitVersion(metadata);
39896
42255
  isGlobalOnlyKit = true;
39897
42256
  }
39898
42257
  foundAnyKit = true;
@@ -39931,7 +42290,7 @@ function getPackageVersion2() {
39931
42290
 
39932
42291
  // src/shared/logger.ts
39933
42292
  init_output_manager();
39934
- var import_picocolors25 = __toESM(require_picocolors(), 1);
42293
+ var import_picocolors26 = __toESM(require_picocolors(), 1);
39935
42294
  import { createWriteStream as createWriteStream3 } from "node:fs";
39936
42295
 
39937
42296
  class Logger2 {
@@ -39940,23 +42299,23 @@ class Logger2 {
39940
42299
  exitHandlerRegistered = false;
39941
42300
  info(message) {
39942
42301
  const symbols = output.getSymbols();
39943
- console.log(import_picocolors25.default.blue(symbols.info), message);
42302
+ console.log(import_picocolors26.default.blue(symbols.info), message);
39944
42303
  }
39945
42304
  success(message) {
39946
42305
  const symbols = output.getSymbols();
39947
- console.log(import_picocolors25.default.green(symbols.success), message);
42306
+ console.log(import_picocolors26.default.green(symbols.success), message);
39948
42307
  }
39949
42308
  warning(message) {
39950
42309
  const symbols = output.getSymbols();
39951
- console.log(import_picocolors25.default.yellow(symbols.warning), message);
42310
+ console.log(import_picocolors26.default.yellow(symbols.warning), message);
39952
42311
  }
39953
42312
  error(message) {
39954
42313
  const symbols = output.getSymbols();
39955
- console.error(import_picocolors25.default.red(symbols.error), message);
42314
+ console.error(import_picocolors26.default.red(symbols.error), message);
39956
42315
  }
39957
42316
  debug(message) {
39958
42317
  if (process.env.DEBUG) {
39959
- console.log(import_picocolors25.default.gray("[DEBUG]"), message);
42318
+ console.log(import_picocolors26.default.gray("[DEBUG]"), message);
39960
42319
  }
39961
42320
  }
39962
42321
  verbose(message, context) {
@@ -39965,7 +42324,7 @@ class Logger2 {
39965
42324
  const timestamp = this.getTimestamp();
39966
42325
  const sanitizedMessage = this.sanitize(message);
39967
42326
  const formattedContext = context ? this.formatContext(context) : "";
39968
- const logLine = `${timestamp} ${import_picocolors25.default.gray("[VERBOSE]")} ${sanitizedMessage}${formattedContext}`;
42327
+ const logLine = `${timestamp} ${import_picocolors26.default.gray("[VERBOSE]")} ${sanitizedMessage}${formattedContext}`;
39969
42328
  console.error(logLine);
39970
42329
  if (this.logFileStream) {
39971
42330
  const plainLogLine = `${timestamp} [VERBOSE] ${sanitizedMessage}${formattedContext}`;
@@ -40068,7 +42427,7 @@ var logger3 = new Logger2;
40068
42427
 
40069
42428
  // src/shared/output-manager.ts
40070
42429
  init_terminal_utils();
40071
- var import_picocolors26 = __toESM(require_picocolors(), 1);
42430
+ var import_picocolors27 = __toESM(require_picocolors(), 1);
40072
42431
  var SYMBOLS2 = {
40073
42432
  unicode: {
40074
42433
  prompt: "◇",
@@ -40147,7 +42506,7 @@ class OutputManager2 {
40147
42506
  if (this.config.quiet)
40148
42507
  return;
40149
42508
  const symbol = this.getSymbols().success;
40150
- console.log(import_picocolors26.default.green(`${symbol} ${message}`));
42509
+ console.log(import_picocolors27.default.green(`${symbol} ${message}`));
40151
42510
  }
40152
42511
  error(message, data) {
40153
42512
  if (this.config.json) {
@@ -40155,7 +42514,7 @@ class OutputManager2 {
40155
42514
  return;
40156
42515
  }
40157
42516
  const symbol = this.getSymbols().error;
40158
- console.error(import_picocolors26.default.red(`${symbol} ${message}`));
42517
+ console.error(import_picocolors27.default.red(`${symbol} ${message}`));
40159
42518
  }
40160
42519
  warning(message, data) {
40161
42520
  if (this.config.json) {
@@ -40165,7 +42524,7 @@ class OutputManager2 {
40165
42524
  if (this.config.quiet)
40166
42525
  return;
40167
42526
  const symbol = this.getSymbols().warning;
40168
- console.log(import_picocolors26.default.yellow(`${symbol} ${message}`));
42527
+ console.log(import_picocolors27.default.yellow(`${symbol} ${message}`));
40169
42528
  }
40170
42529
  info(message, data) {
40171
42530
  if (this.config.json) {
@@ -40175,7 +42534,7 @@ class OutputManager2 {
40175
42534
  if (this.config.quiet)
40176
42535
  return;
40177
42536
  const symbol = this.getSymbols().info;
40178
- console.log(import_picocolors26.default.blue(`${symbol} ${message}`));
42537
+ console.log(import_picocolors27.default.blue(`${symbol} ${message}`));
40179
42538
  }
40180
42539
  verbose(message, data) {
40181
42540
  if (!this.config.verbose)
@@ -40184,7 +42543,7 @@ class OutputManager2 {
40184
42543
  this.addJsonEntry({ type: "info", message, data });
40185
42544
  return;
40186
42545
  }
40187
- console.log(import_picocolors26.default.dim(` ${message}`));
42546
+ console.log(import_picocolors27.default.dim(` ${message}`));
40188
42547
  }
40189
42548
  indent(message) {
40190
42549
  if (this.config.json)
@@ -40209,7 +42568,7 @@ class OutputManager2 {
40209
42568
  return;
40210
42569
  const symbols = this.getSymbols();
40211
42570
  console.log();
40212
- console.log(import_picocolors26.default.bold(import_picocolors26.default.cyan(`${symbols.line} ${title}`)));
42571
+ console.log(import_picocolors27.default.bold(import_picocolors27.default.cyan(`${symbols.line} ${title}`)));
40213
42572
  }
40214
42573
  addJsonEntry(entry) {
40215
42574
  this.jsonBuffer.push({