claudekit-cli 4.5.2-dev.1 → 4.5.2-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli-manifest.json +2 -2
- package/dist/index.js +585 -494
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15560,6 +15560,128 @@ var init_types2 = __esm(() => {
|
|
|
15560
15560
|
});
|
|
15561
15561
|
});
|
|
15562
15562
|
|
|
15563
|
+
// node_modules/compare-versions/lib/umd/index.js
|
|
15564
|
+
var require_umd = __commonJS((exports, module) => {
|
|
15565
|
+
(function(global2, factory) {
|
|
15566
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, factory(global2.compareVersions = {}));
|
|
15567
|
+
})(exports, function(exports2) {
|
|
15568
|
+
const semver = /^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;
|
|
15569
|
+
const validateAndParse = (version) => {
|
|
15570
|
+
if (typeof version !== "string") {
|
|
15571
|
+
throw new TypeError("Invalid argument expected string");
|
|
15572
|
+
}
|
|
15573
|
+
const match = version.match(semver);
|
|
15574
|
+
if (!match) {
|
|
15575
|
+
throw new Error(`Invalid argument not valid semver ('${version}' received)`);
|
|
15576
|
+
}
|
|
15577
|
+
match.shift();
|
|
15578
|
+
return match;
|
|
15579
|
+
};
|
|
15580
|
+
const isWildcard = (s) => s === "*" || s === "x" || s === "X";
|
|
15581
|
+
const tryParse = (v2) => {
|
|
15582
|
+
const n = parseInt(v2, 10);
|
|
15583
|
+
return isNaN(n) ? v2 : n;
|
|
15584
|
+
};
|
|
15585
|
+
const forceType = (a3, b3) => typeof a3 !== typeof b3 ? [String(a3), String(b3)] : [a3, b3];
|
|
15586
|
+
const compareStrings = (a3, b3) => {
|
|
15587
|
+
if (isWildcard(a3) || isWildcard(b3))
|
|
15588
|
+
return 0;
|
|
15589
|
+
const [ap, bp] = forceType(tryParse(a3), tryParse(b3));
|
|
15590
|
+
if (ap > bp)
|
|
15591
|
+
return 1;
|
|
15592
|
+
if (ap < bp)
|
|
15593
|
+
return -1;
|
|
15594
|
+
return 0;
|
|
15595
|
+
};
|
|
15596
|
+
const compareSegments = (a3, b3) => {
|
|
15597
|
+
for (let i = 0;i < Math.max(a3.length, b3.length); i++) {
|
|
15598
|
+
const r2 = compareStrings(a3[i] || "0", b3[i] || "0");
|
|
15599
|
+
if (r2 !== 0)
|
|
15600
|
+
return r2;
|
|
15601
|
+
}
|
|
15602
|
+
return 0;
|
|
15603
|
+
};
|
|
15604
|
+
const compareVersions = (v1, v2) => {
|
|
15605
|
+
const n1 = validateAndParse(v1);
|
|
15606
|
+
const n2 = validateAndParse(v2);
|
|
15607
|
+
const p1 = n1.pop();
|
|
15608
|
+
const p2 = n2.pop();
|
|
15609
|
+
const r2 = compareSegments(n1, n2);
|
|
15610
|
+
if (r2 !== 0)
|
|
15611
|
+
return r2;
|
|
15612
|
+
if (p1 && p2) {
|
|
15613
|
+
return compareSegments(p1.split("."), p2.split("."));
|
|
15614
|
+
} else if (p1 || p2) {
|
|
15615
|
+
return p1 ? -1 : 1;
|
|
15616
|
+
}
|
|
15617
|
+
return 0;
|
|
15618
|
+
};
|
|
15619
|
+
const compare = (v1, v2, operator) => {
|
|
15620
|
+
assertValidOperator(operator);
|
|
15621
|
+
const res = compareVersions(v1, v2);
|
|
15622
|
+
return operatorResMap[operator].includes(res);
|
|
15623
|
+
};
|
|
15624
|
+
const operatorResMap = {
|
|
15625
|
+
">": [1],
|
|
15626
|
+
">=": [0, 1],
|
|
15627
|
+
"=": [0],
|
|
15628
|
+
"<=": [-1, 0],
|
|
15629
|
+
"<": [-1],
|
|
15630
|
+
"!=": [-1, 1]
|
|
15631
|
+
};
|
|
15632
|
+
const allowedOperators = Object.keys(operatorResMap);
|
|
15633
|
+
const assertValidOperator = (op) => {
|
|
15634
|
+
if (typeof op !== "string") {
|
|
15635
|
+
throw new TypeError(`Invalid operator type, expected string but got ${typeof op}`);
|
|
15636
|
+
}
|
|
15637
|
+
if (allowedOperators.indexOf(op) === -1) {
|
|
15638
|
+
throw new Error(`Invalid operator, expected one of ${allowedOperators.join("|")}`);
|
|
15639
|
+
}
|
|
15640
|
+
};
|
|
15641
|
+
const satisfies = (version, range) => {
|
|
15642
|
+
range = range.replace(/([><=]+)\s+/g, "$1");
|
|
15643
|
+
if (range.includes("||")) {
|
|
15644
|
+
return range.split("||").some((r5) => satisfies(version, r5));
|
|
15645
|
+
} else if (range.includes(" - ")) {
|
|
15646
|
+
const [a3, b3] = range.split(" - ", 2);
|
|
15647
|
+
return satisfies(version, `>=${a3} <=${b3}`);
|
|
15648
|
+
} else if (range.includes(" ")) {
|
|
15649
|
+
return range.trim().replace(/\s{2,}/g, " ").split(" ").every((r5) => satisfies(version, r5));
|
|
15650
|
+
}
|
|
15651
|
+
const m2 = range.match(/^([<>=~^]+)/);
|
|
15652
|
+
const op = m2 ? m2[1] : "=";
|
|
15653
|
+
if (op !== "^" && op !== "~")
|
|
15654
|
+
return compare(version, range, op);
|
|
15655
|
+
const [v1, v2, v3, , vp] = validateAndParse(version);
|
|
15656
|
+
const [r1, r2, r3, , rp] = validateAndParse(range);
|
|
15657
|
+
const v4 = [v1, v2, v3];
|
|
15658
|
+
const r4 = [r1, r2 !== null && r2 !== undefined ? r2 : "x", r3 !== null && r3 !== undefined ? r3 : "x"];
|
|
15659
|
+
if (rp) {
|
|
15660
|
+
if (!vp)
|
|
15661
|
+
return false;
|
|
15662
|
+
if (compareSegments(v4, r4) !== 0)
|
|
15663
|
+
return false;
|
|
15664
|
+
if (compareSegments(vp.split("."), rp.split(".")) === -1)
|
|
15665
|
+
return false;
|
|
15666
|
+
}
|
|
15667
|
+
const nonZero = r4.findIndex((v5) => v5 !== "0") + 1;
|
|
15668
|
+
const i = op === "~" ? 2 : nonZero > 1 ? nonZero : 1;
|
|
15669
|
+
if (compareSegments(v4.slice(0, i), r4.slice(0, i)) !== 0)
|
|
15670
|
+
return false;
|
|
15671
|
+
if (compareSegments(v4.slice(i), r4.slice(i)) === -1)
|
|
15672
|
+
return false;
|
|
15673
|
+
return true;
|
|
15674
|
+
};
|
|
15675
|
+
const validate = (version) => typeof version === "string" && /^[v\d]/.test(version) && semver.test(version);
|
|
15676
|
+
const validateStrict = (version) => typeof version === "string" && /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(version);
|
|
15677
|
+
exports2.compare = compare;
|
|
15678
|
+
exports2.compareVersions = compareVersions;
|
|
15679
|
+
exports2.satisfies = satisfies;
|
|
15680
|
+
exports2.validate = validate;
|
|
15681
|
+
exports2.validateStrict = validateStrict;
|
|
15682
|
+
});
|
|
15683
|
+
});
|
|
15684
|
+
|
|
15563
15685
|
// src/domains/installation/plugin/install-mode-detector.ts
|
|
15564
15686
|
import { createHash as createHash4 } from "node:crypto";
|
|
15565
15687
|
import { existsSync as existsSync6, readFileSync as readFileSync3, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
|
|
@@ -15605,7 +15727,7 @@ function detectPluginState(claudeDir) {
|
|
|
15605
15727
|
state.marketplace = state.marketplace ?? marketplace;
|
|
15606
15728
|
const versions = safeReaddir(ckDir).filter((v2) => isDir(join6(ckDir, v2)));
|
|
15607
15729
|
if (versions.length > 0 && state.version === null) {
|
|
15608
|
-
state.version = versions
|
|
15730
|
+
state.version = selectPluginCacheVersion(versions, ckDir);
|
|
15609
15731
|
}
|
|
15610
15732
|
if (!state.installed)
|
|
15611
15733
|
state.staleCache = true;
|
|
@@ -15615,6 +15737,24 @@ function detectPluginState(claudeDir) {
|
|
|
15615
15737
|
}
|
|
15616
15738
|
return state;
|
|
15617
15739
|
}
|
|
15740
|
+
function selectPluginCacheVersion(versions, ckDir) {
|
|
15741
|
+
const comparable = versions.filter(isComparableSemver);
|
|
15742
|
+
if (comparable.length > 0) {
|
|
15743
|
+
return comparable.sort((a3, b3) => import_compare_versions.compareVersions(normalizeVersion(b3), normalizeVersion(a3)))[0];
|
|
15744
|
+
}
|
|
15745
|
+
return versions.map((v2) => ({ v: v2, mtime: statMtime(join6(ckDir, v2)) })).sort((a3, b3) => b3.mtime - a3.mtime)[0].v;
|
|
15746
|
+
}
|
|
15747
|
+
function isComparableSemver(version) {
|
|
15748
|
+
try {
|
|
15749
|
+
import_compare_versions.compareVersions(normalizeVersion(version), normalizeVersion(version));
|
|
15750
|
+
return true;
|
|
15751
|
+
} catch {
|
|
15752
|
+
return false;
|
|
15753
|
+
}
|
|
15754
|
+
}
|
|
15755
|
+
function normalizeVersion(version) {
|
|
15756
|
+
return version.replace(/^v/, "");
|
|
15757
|
+
}
|
|
15618
15758
|
function detectLegacyState(claudeDir) {
|
|
15619
15759
|
const metadata = readJsonSafe(join6(claudeDir, "metadata.json"));
|
|
15620
15760
|
if (!isRecord(metadata))
|
|
@@ -15773,9 +15913,10 @@ function statMtime(p) {
|
|
|
15773
15913
|
return 0;
|
|
15774
15914
|
}
|
|
15775
15915
|
}
|
|
15776
|
-
var CK_PLUGIN_NAME = "ck", CK_MARKETPLACE_NAME = "claudekit", ENGINEER_KIT_KEY = "engineer", PLUGIN_SUPPLIED_LEGACY_PREFIXES;
|
|
15916
|
+
var import_compare_versions, CK_PLUGIN_NAME = "ck", CK_MARKETPLACE_NAME = "claudekit", ENGINEER_KIT_KEY = "engineer", PLUGIN_SUPPLIED_LEGACY_PREFIXES;
|
|
15777
15917
|
var init_install_mode_detector = __esm(() => {
|
|
15778
15918
|
init_path_resolver();
|
|
15919
|
+
import_compare_versions = __toESM(require_umd(), 1);
|
|
15779
15920
|
PLUGIN_SUPPLIED_LEGACY_PREFIXES = ["agents/", "skills/"];
|
|
15780
15921
|
});
|
|
15781
15922
|
|
|
@@ -64591,7 +64732,7 @@ var package_default;
|
|
|
64591
64732
|
var init_package = __esm(() => {
|
|
64592
64733
|
package_default = {
|
|
64593
64734
|
name: "claudekit-cli",
|
|
64594
|
-
version: "4.5.2-dev.
|
|
64735
|
+
version: "4.5.2-dev.3",
|
|
64595
64736
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
64596
64737
|
type: "module",
|
|
64597
64738
|
repository: {
|
|
@@ -64713,142 +64854,20 @@ var init_package = __esm(() => {
|
|
|
64713
64854
|
};
|
|
64714
64855
|
});
|
|
64715
64856
|
|
|
64716
|
-
// node_modules/compare-versions/lib/umd/index.js
|
|
64717
|
-
var require_umd = __commonJS((exports, module) => {
|
|
64718
|
-
(function(global3, factory) {
|
|
64719
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global3 = typeof globalThis !== "undefined" ? globalThis : global3 || self, factory(global3.compareVersions = {}));
|
|
64720
|
-
})(exports, function(exports2) {
|
|
64721
|
-
const semver3 = /^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;
|
|
64722
|
-
const validateAndParse = (version) => {
|
|
64723
|
-
if (typeof version !== "string") {
|
|
64724
|
-
throw new TypeError("Invalid argument expected string");
|
|
64725
|
-
}
|
|
64726
|
-
const match = version.match(semver3);
|
|
64727
|
-
if (!match) {
|
|
64728
|
-
throw new Error(`Invalid argument not valid semver ('${version}' received)`);
|
|
64729
|
-
}
|
|
64730
|
-
match.shift();
|
|
64731
|
-
return match;
|
|
64732
|
-
};
|
|
64733
|
-
const isWildcard = (s) => s === "*" || s === "x" || s === "X";
|
|
64734
|
-
const tryParse = (v2) => {
|
|
64735
|
-
const n = parseInt(v2, 10);
|
|
64736
|
-
return isNaN(n) ? v2 : n;
|
|
64737
|
-
};
|
|
64738
|
-
const forceType = (a3, b3) => typeof a3 !== typeof b3 ? [String(a3), String(b3)] : [a3, b3];
|
|
64739
|
-
const compareStrings = (a3, b3) => {
|
|
64740
|
-
if (isWildcard(a3) || isWildcard(b3))
|
|
64741
|
-
return 0;
|
|
64742
|
-
const [ap, bp] = forceType(tryParse(a3), tryParse(b3));
|
|
64743
|
-
if (ap > bp)
|
|
64744
|
-
return 1;
|
|
64745
|
-
if (ap < bp)
|
|
64746
|
-
return -1;
|
|
64747
|
-
return 0;
|
|
64748
|
-
};
|
|
64749
|
-
const compareSegments = (a3, b3) => {
|
|
64750
|
-
for (let i = 0;i < Math.max(a3.length, b3.length); i++) {
|
|
64751
|
-
const r2 = compareStrings(a3[i] || "0", b3[i] || "0");
|
|
64752
|
-
if (r2 !== 0)
|
|
64753
|
-
return r2;
|
|
64754
|
-
}
|
|
64755
|
-
return 0;
|
|
64756
|
-
};
|
|
64757
|
-
const compareVersions = (v1, v2) => {
|
|
64758
|
-
const n1 = validateAndParse(v1);
|
|
64759
|
-
const n2 = validateAndParse(v2);
|
|
64760
|
-
const p1 = n1.pop();
|
|
64761
|
-
const p2 = n2.pop();
|
|
64762
|
-
const r2 = compareSegments(n1, n2);
|
|
64763
|
-
if (r2 !== 0)
|
|
64764
|
-
return r2;
|
|
64765
|
-
if (p1 && p2) {
|
|
64766
|
-
return compareSegments(p1.split("."), p2.split("."));
|
|
64767
|
-
} else if (p1 || p2) {
|
|
64768
|
-
return p1 ? -1 : 1;
|
|
64769
|
-
}
|
|
64770
|
-
return 0;
|
|
64771
|
-
};
|
|
64772
|
-
const compare = (v1, v2, operator) => {
|
|
64773
|
-
assertValidOperator(operator);
|
|
64774
|
-
const res = compareVersions(v1, v2);
|
|
64775
|
-
return operatorResMap[operator].includes(res);
|
|
64776
|
-
};
|
|
64777
|
-
const operatorResMap = {
|
|
64778
|
-
">": [1],
|
|
64779
|
-
">=": [0, 1],
|
|
64780
|
-
"=": [0],
|
|
64781
|
-
"<=": [-1, 0],
|
|
64782
|
-
"<": [-1],
|
|
64783
|
-
"!=": [-1, 1]
|
|
64784
|
-
};
|
|
64785
|
-
const allowedOperators = Object.keys(operatorResMap);
|
|
64786
|
-
const assertValidOperator = (op) => {
|
|
64787
|
-
if (typeof op !== "string") {
|
|
64788
|
-
throw new TypeError(`Invalid operator type, expected string but got ${typeof op}`);
|
|
64789
|
-
}
|
|
64790
|
-
if (allowedOperators.indexOf(op) === -1) {
|
|
64791
|
-
throw new Error(`Invalid operator, expected one of ${allowedOperators.join("|")}`);
|
|
64792
|
-
}
|
|
64793
|
-
};
|
|
64794
|
-
const satisfies = (version, range) => {
|
|
64795
|
-
range = range.replace(/([><=]+)\s+/g, "$1");
|
|
64796
|
-
if (range.includes("||")) {
|
|
64797
|
-
return range.split("||").some((r5) => satisfies(version, r5));
|
|
64798
|
-
} else if (range.includes(" - ")) {
|
|
64799
|
-
const [a3, b3] = range.split(" - ", 2);
|
|
64800
|
-
return satisfies(version, `>=${a3} <=${b3}`);
|
|
64801
|
-
} else if (range.includes(" ")) {
|
|
64802
|
-
return range.trim().replace(/\s{2,}/g, " ").split(" ").every((r5) => satisfies(version, r5));
|
|
64803
|
-
}
|
|
64804
|
-
const m2 = range.match(/^([<>=~^]+)/);
|
|
64805
|
-
const op = m2 ? m2[1] : "=";
|
|
64806
|
-
if (op !== "^" && op !== "~")
|
|
64807
|
-
return compare(version, range, op);
|
|
64808
|
-
const [v1, v2, v3, , vp] = validateAndParse(version);
|
|
64809
|
-
const [r1, r2, r3, , rp] = validateAndParse(range);
|
|
64810
|
-
const v4 = [v1, v2, v3];
|
|
64811
|
-
const r4 = [r1, r2 !== null && r2 !== undefined ? r2 : "x", r3 !== null && r3 !== undefined ? r3 : "x"];
|
|
64812
|
-
if (rp) {
|
|
64813
|
-
if (!vp)
|
|
64814
|
-
return false;
|
|
64815
|
-
if (compareSegments(v4, r4) !== 0)
|
|
64816
|
-
return false;
|
|
64817
|
-
if (compareSegments(vp.split("."), rp.split(".")) === -1)
|
|
64818
|
-
return false;
|
|
64819
|
-
}
|
|
64820
|
-
const nonZero = r4.findIndex((v5) => v5 !== "0") + 1;
|
|
64821
|
-
const i = op === "~" ? 2 : nonZero > 1 ? nonZero : 1;
|
|
64822
|
-
if (compareSegments(v4.slice(0, i), r4.slice(0, i)) !== 0)
|
|
64823
|
-
return false;
|
|
64824
|
-
if (compareSegments(v4.slice(i), r4.slice(i)) === -1)
|
|
64825
|
-
return false;
|
|
64826
|
-
return true;
|
|
64827
|
-
};
|
|
64828
|
-
const validate2 = (version) => typeof version === "string" && /^[v\d]/.test(version) && semver3.test(version);
|
|
64829
|
-
const validateStrict = (version) => typeof version === "string" && /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(version);
|
|
64830
|
-
exports2.compare = compare;
|
|
64831
|
-
exports2.compareVersions = compareVersions;
|
|
64832
|
-
exports2.satisfies = satisfies;
|
|
64833
|
-
exports2.validate = validate2;
|
|
64834
|
-
exports2.validateStrict = validateStrict;
|
|
64835
|
-
});
|
|
64836
|
-
});
|
|
64837
|
-
|
|
64838
64857
|
// src/domains/versioning/checking/version-utils.ts
|
|
64839
64858
|
function isUpdateCheckDisabled() {
|
|
64840
64859
|
return process.env.NO_UPDATE_NOTIFIER === "1" || process.env.NO_UPDATE_NOTIFIER === "true" || !process.stdout.isTTY;
|
|
64841
64860
|
}
|
|
64842
|
-
function
|
|
64861
|
+
function normalizeVersion2(version) {
|
|
64843
64862
|
return version.replace(/^v/i, "");
|
|
64844
64863
|
}
|
|
64845
64864
|
function isPrereleaseVersion(version) {
|
|
64846
64865
|
if (!version)
|
|
64847
64866
|
return false;
|
|
64848
|
-
return /-(beta|alpha|rc|dev)[.\d]/i.test(
|
|
64867
|
+
return /-(beta|alpha|rc|dev)[.\d]/i.test(normalizeVersion2(version));
|
|
64849
64868
|
}
|
|
64850
64869
|
function parseVersionParts(version) {
|
|
64851
|
-
const normalized =
|
|
64870
|
+
const normalized = normalizeVersion2(version);
|
|
64852
64871
|
const [base, ...prereleaseParts] = normalized.split("-");
|
|
64853
64872
|
return {
|
|
64854
64873
|
base,
|
|
@@ -64865,23 +64884,23 @@ function isPrereleaseOfSameBase(currentVersion, latestVersion) {
|
|
|
64865
64884
|
return current.base === latest.base;
|
|
64866
64885
|
}
|
|
64867
64886
|
function versionsMatch(installed, latest) {
|
|
64868
|
-
return
|
|
64887
|
+
return normalizeVersion2(installed) === normalizeVersion2(latest);
|
|
64869
64888
|
}
|
|
64870
64889
|
function isNewerVersion(currentVersion, latestVersion) {
|
|
64871
64890
|
try {
|
|
64872
|
-
const current =
|
|
64873
|
-
const latest =
|
|
64891
|
+
const current = normalizeVersion2(currentVersion);
|
|
64892
|
+
const latest = normalizeVersion2(latestVersion);
|
|
64874
64893
|
if (isPrereleaseOfSameBase(current, latest)) {
|
|
64875
64894
|
return false;
|
|
64876
64895
|
}
|
|
64877
|
-
return
|
|
64896
|
+
return import_compare_versions2.compareVersions(latest, current) > 0;
|
|
64878
64897
|
} catch {
|
|
64879
64898
|
return false;
|
|
64880
64899
|
}
|
|
64881
64900
|
}
|
|
64882
|
-
var
|
|
64901
|
+
var import_compare_versions2;
|
|
64883
64902
|
var init_version_utils = __esm(() => {
|
|
64884
|
-
|
|
64903
|
+
import_compare_versions2 = __toESM(require_umd(), 1);
|
|
64885
64904
|
});
|
|
64886
64905
|
|
|
64887
64906
|
// src/commands/update/error.ts
|
|
@@ -64965,7 +64984,7 @@ var init_registry_client = __esm(() => {
|
|
|
64965
64984
|
|
|
64966
64985
|
// src/commands/update/version-comparator.ts
|
|
64967
64986
|
function compareCliVersions(currentVersion, targetVersion, opts) {
|
|
64968
|
-
const comparison =
|
|
64987
|
+
const comparison = import_compare_versions3.compareVersions(currentVersion, targetVersion);
|
|
64969
64988
|
if (comparison === 0) {
|
|
64970
64989
|
return { status: "up-to-date" };
|
|
64971
64990
|
}
|
|
@@ -64987,10 +65006,10 @@ function parseCliVersionFromOutput(output2) {
|
|
|
64987
65006
|
const match = output2.match(/CLI Version:\s*(\S+)/);
|
|
64988
65007
|
return match ? match[1] : null;
|
|
64989
65008
|
}
|
|
64990
|
-
var
|
|
65009
|
+
var import_compare_versions3;
|
|
64991
65010
|
var init_version_comparator = __esm(() => {
|
|
64992
65011
|
init_version_utils();
|
|
64993
|
-
|
|
65012
|
+
import_compare_versions3 = __toESM(require_umd(), 1);
|
|
64994
65013
|
});
|
|
64995
65014
|
|
|
64996
65015
|
// src/commands/update/package-manager-runner.ts
|
|
@@ -66776,6 +66795,8 @@ This is a bug. Please open an issue at https://github.com/mrgoonie/claudekit-cli
|
|
|
66776
66795
|
|
|
66777
66796
|
// src/domains/installation/plugin/codex-plugin-installer.ts
|
|
66778
66797
|
import { execFile as execFile8 } from "node:child_process";
|
|
66798
|
+
import { existsSync as existsSync47, realpathSync as realpathSync4 } from "node:fs";
|
|
66799
|
+
import { normalize as normalize5, resolve as resolve35 } from "node:path";
|
|
66779
66800
|
import { promisify as promisify9 } from "node:util";
|
|
66780
66801
|
function resolveCodexExecutable(_platformName = process.platform) {
|
|
66781
66802
|
return "codex";
|
|
@@ -66863,7 +66884,7 @@ function classifyCodexPluginEntry(entry, options2 = {}) {
|
|
|
66863
66884
|
if (entry.marketplace && entry.marketplace !== expectedMarketplace) {
|
|
66864
66885
|
return createState("installed-stale-source", entry, options2);
|
|
66865
66886
|
}
|
|
66866
|
-
if (options2.expectedSource && entry.source && entry.source
|
|
66887
|
+
if (options2.expectedSource && entry.source && !pluginSourceMatches(entry.source, options2.expectedSource)) {
|
|
66867
66888
|
return createState("installed-stale-source", entry, options2);
|
|
66868
66889
|
}
|
|
66869
66890
|
if (options2.expectedVersion && entry.version && !versionsMatch(entry.version, options2.expectedVersion)) {
|
|
@@ -66871,6 +66892,22 @@ function classifyCodexPluginEntry(entry, options2 = {}) {
|
|
|
66871
66892
|
}
|
|
66872
66893
|
return createState("installed-current", entry, options2);
|
|
66873
66894
|
}
|
|
66895
|
+
function pluginSourceMatches(actual, expected) {
|
|
66896
|
+
if (actual === expected)
|
|
66897
|
+
return true;
|
|
66898
|
+
const normalizedActual = normalizeLocalSourcePath(actual);
|
|
66899
|
+
const normalizedExpected = normalizeLocalSourcePath(expected);
|
|
66900
|
+
return normalizedActual !== null && normalizedExpected !== null && normalizedActual === normalizedExpected;
|
|
66901
|
+
}
|
|
66902
|
+
function normalizeLocalSourcePath(value) {
|
|
66903
|
+
const trimmed = value.trim();
|
|
66904
|
+
if (!trimmed || /^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed))
|
|
66905
|
+
return null;
|
|
66906
|
+
const resolved = resolve35(trimmed);
|
|
66907
|
+
const canonical = existsSync47(resolved) ? realpathSync4.native(resolved) : resolved;
|
|
66908
|
+
const normalized = normalize5(canonical);
|
|
66909
|
+
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
66910
|
+
}
|
|
66874
66911
|
function parseTextPluginList(output2) {
|
|
66875
66912
|
const pluginId = `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
66876
66913
|
const row = new RegExp(`^\\s*(${pluginId})\\s+(.*)$`, "im").exec(output2);
|
|
@@ -67367,7 +67404,7 @@ var init_claudekit_scanner = __esm(() => {
|
|
|
67367
67404
|
|
|
67368
67405
|
// src/ui/ck-cli-design/tokens.ts
|
|
67369
67406
|
import { homedir as homedir41, platform as platform7 } from "node:os";
|
|
67370
|
-
import { resolve as
|
|
67407
|
+
import { resolve as resolve36, win32 } from "node:path";
|
|
67371
67408
|
function createCliDesignContext(options2 = {}) {
|
|
67372
67409
|
const env2 = options2.env ?? process.env;
|
|
67373
67410
|
const isTTY2 = options2.isTTY ?? process.stdout.isTTY === true;
|
|
@@ -67516,7 +67553,7 @@ function formatCdHint(value, currentPlatform = platform7()) {
|
|
|
67516
67553
|
const absolutePath2 = win32.resolve(value);
|
|
67517
67554
|
return `cd /d "${absolutePath2}"`;
|
|
67518
67555
|
}
|
|
67519
|
-
const absolutePath =
|
|
67556
|
+
const absolutePath = resolve36(value);
|
|
67520
67557
|
const displayPath = formatDisplayPath(absolutePath);
|
|
67521
67558
|
if (displayPath.includes(" ")) {
|
|
67522
67559
|
return `cd "${displayPath}"`;
|
|
@@ -68121,7 +68158,7 @@ var init_error_handler2 = __esm(() => {
|
|
|
68121
68158
|
});
|
|
68122
68159
|
|
|
68123
68160
|
// src/domains/versioning/release-cache.ts
|
|
68124
|
-
import { existsSync as
|
|
68161
|
+
import { existsSync as existsSync48 } from "node:fs";
|
|
68125
68162
|
import { mkdir as mkdir18, readFile as readFile37, unlink as unlink8, writeFile as writeFile20 } from "node:fs/promises";
|
|
68126
68163
|
import { join as join69 } from "node:path";
|
|
68127
68164
|
var ReleaseCacheEntrySchema, ReleaseCache;
|
|
@@ -68143,7 +68180,7 @@ var init_release_cache = __esm(() => {
|
|
|
68143
68180
|
async get(key) {
|
|
68144
68181
|
const cacheFile = this.getCachePath(key);
|
|
68145
68182
|
try {
|
|
68146
|
-
if (!
|
|
68183
|
+
if (!existsSync48(cacheFile)) {
|
|
68147
68184
|
logger.debug(`Release cache not found for key: ${key}`);
|
|
68148
68185
|
return null;
|
|
68149
68186
|
}
|
|
@@ -68183,7 +68220,7 @@ var init_release_cache = __esm(() => {
|
|
|
68183
68220
|
if (key) {
|
|
68184
68221
|
const cacheFile = this.getCachePath(key);
|
|
68185
68222
|
try {
|
|
68186
|
-
if (
|
|
68223
|
+
if (existsSync48(cacheFile)) {
|
|
68187
68224
|
await unlink8(cacheFile);
|
|
68188
68225
|
logger.debug(`Release cache cleared for key: ${key}`);
|
|
68189
68226
|
}
|
|
@@ -68236,7 +68273,7 @@ class VersionFormatter {
|
|
|
68236
68273
|
static compare(v1, v2) {
|
|
68237
68274
|
const normV1 = VersionFormatter.normalize(v1);
|
|
68238
68275
|
const normV2 = VersionFormatter.normalize(v2);
|
|
68239
|
-
return
|
|
68276
|
+
return import_compare_versions4.compareVersions(normV1, normV2);
|
|
68240
68277
|
}
|
|
68241
68278
|
static formatRelativeTime(dateString) {
|
|
68242
68279
|
if (!dateString)
|
|
@@ -68324,20 +68361,20 @@ class VersionFormatter {
|
|
|
68324
68361
|
const majorA = Number.parseInt(normA.split(".")[0], 10);
|
|
68325
68362
|
const majorB = Number.parseInt(normB.split(".")[0], 10);
|
|
68326
68363
|
if (majorA === 0 && majorB === 0) {
|
|
68327
|
-
return
|
|
68364
|
+
return import_compare_versions4.compareVersions(normB, normA);
|
|
68328
68365
|
}
|
|
68329
68366
|
if (majorA === 0)
|
|
68330
68367
|
return 1;
|
|
68331
68368
|
if (majorB === 0)
|
|
68332
68369
|
return -1;
|
|
68333
|
-
return
|
|
68370
|
+
return import_compare_versions4.compareVersions(normB, normA);
|
|
68334
68371
|
});
|
|
68335
68372
|
}
|
|
68336
68373
|
}
|
|
68337
|
-
var
|
|
68374
|
+
var import_compare_versions4;
|
|
68338
68375
|
var init_version_formatter = __esm(() => {
|
|
68339
68376
|
init_logger();
|
|
68340
|
-
|
|
68377
|
+
import_compare_versions4 = __toESM(require_umd(), 1);
|
|
68341
68378
|
});
|
|
68342
68379
|
|
|
68343
68380
|
// src/domains/versioning/release-filter.ts
|
|
@@ -68862,7 +68899,7 @@ var init_github_client = __esm(() => {
|
|
|
68862
68899
|
|
|
68863
68900
|
// src/commands/update/post-update-handler.ts
|
|
68864
68901
|
import { exec as exec2, spawn as spawn2 } from "node:child_process";
|
|
68865
|
-
import { existsSync as
|
|
68902
|
+
import { existsSync as existsSync49 } from "node:fs";
|
|
68866
68903
|
import { readdir as readdir19 } from "node:fs/promises";
|
|
68867
68904
|
import { builtinModules } from "node:module";
|
|
68868
68905
|
import { dirname as dirname30, join as join70 } from "node:path";
|
|
@@ -68948,7 +68985,7 @@ function collectSettingsHookRegistrations(settings, options2 = {}) {
|
|
|
68948
68985
|
}
|
|
68949
68986
|
async function readManagedHookNames(claudeDir3) {
|
|
68950
68987
|
const manifestPath = join70(claudeDir3, "hooks", MANAGED_HOOKS_MANIFEST);
|
|
68951
|
-
if (!
|
|
68988
|
+
if (!existsSync49(manifestPath))
|
|
68952
68989
|
return [];
|
|
68953
68990
|
try {
|
|
68954
68991
|
const data = parseJsonContent(await import_fs_extra8.readFile(manifestPath, "utf-8"));
|
|
@@ -68962,7 +68999,7 @@ async function readManagedHookNames(claudeDir3) {
|
|
|
68962
68999
|
}
|
|
68963
69000
|
async function readDisabledHookNames(claudeDir3) {
|
|
68964
69001
|
const configPath = join70(claudeDir3, ".ck.json");
|
|
68965
|
-
if (!
|
|
69002
|
+
if (!existsSync49(configPath))
|
|
68966
69003
|
return new Set;
|
|
68967
69004
|
try {
|
|
68968
69005
|
const config = parseJsonContent(await import_fs_extra8.readFile(configPath, "utf-8"));
|
|
@@ -68974,7 +69011,7 @@ async function readDisabledHookNames(claudeDir3) {
|
|
|
68974
69011
|
}
|
|
68975
69012
|
async function countMissingCkHookRegistrations(claudeDir3, kit, options2 = {}) {
|
|
68976
69013
|
const settingsPath = join70(claudeDir3, "settings.json");
|
|
68977
|
-
if (!
|
|
69014
|
+
if (!existsSync49(settingsPath))
|
|
68978
69015
|
return 0;
|
|
68979
69016
|
const managedHooks = await readManagedHookNames(claudeDir3);
|
|
68980
69017
|
if (managedHooks.length === 0)
|
|
@@ -68987,7 +69024,7 @@ async function countMissingCkHookRegistrations(claudeDir3, kit, options2 = {}) {
|
|
|
68987
69024
|
for (const name of managedHooks) {
|
|
68988
69025
|
if (disabledHooks.has(name))
|
|
68989
69026
|
continue;
|
|
68990
|
-
if (!
|
|
69027
|
+
if (!existsSync49(join70(hooksDir, `${name}.cjs`)))
|
|
68991
69028
|
continue;
|
|
68992
69029
|
if (!liveHookRegistrations.get(name)?.hasCorrectScope)
|
|
68993
69030
|
missing++;
|
|
@@ -69034,13 +69071,13 @@ function resolveCkInitSpawnCommand(initArgs, options2 = {}) {
|
|
|
69034
69071
|
};
|
|
69035
69072
|
}
|
|
69036
69073
|
function createDefaultSpawnInitFn() {
|
|
69037
|
-
return (spawnArgs) => new Promise((
|
|
69074
|
+
return (spawnArgs) => new Promise((resolve37) => {
|
|
69038
69075
|
const initCommand = resolveCkInitSpawnCommand(spawnArgs);
|
|
69039
69076
|
const child = spawn2(initCommand.command, initCommand.args, { stdio: "inherit" });
|
|
69040
|
-
child.on("close", (code) =>
|
|
69077
|
+
child.on("close", (code) => resolve37(code ?? 1));
|
|
69041
69078
|
child.on("error", (err) => {
|
|
69042
69079
|
logger.verbose(`Failed to spawn ck init: ${err.message}`);
|
|
69043
|
-
|
|
69080
|
+
resolve37(1);
|
|
69044
69081
|
});
|
|
69045
69082
|
});
|
|
69046
69083
|
}
|
|
@@ -69058,7 +69095,7 @@ async function fetchLatestReleaseTag(kit, beta) {
|
|
|
69058
69095
|
}
|
|
69059
69096
|
async function findMissingHookDependencies(claudeDir3) {
|
|
69060
69097
|
const hooksDir = join70(claudeDir3, "hooks");
|
|
69061
|
-
if (!
|
|
69098
|
+
if (!existsSync49(hooksDir))
|
|
69062
69099
|
return [];
|
|
69063
69100
|
const files = await readdir19(hooksDir);
|
|
69064
69101
|
const cjsFiles = files.filter((file) => file.endsWith(".cjs"));
|
|
@@ -69075,7 +69112,7 @@ async function findMissingHookDependencies(claudeDir3) {
|
|
|
69075
69112
|
if (!depPath || nodeBuiltins.has(depPath) || !depPath.startsWith("."))
|
|
69076
69113
|
continue;
|
|
69077
69114
|
const resolvedPath = join70(hooksDir, depPath);
|
|
69078
|
-
const exists =
|
|
69115
|
+
const exists = existsSync49(resolvedPath) || HOOK_DEPENDENCY_EXTENSIONS.some((ext) => existsSync49(resolvedPath + ext)) || existsSync49(join70(resolvedPath, "index.js")) || existsSync49(join70(resolvedPath, "index.cjs")) || existsSync49(join70(resolvedPath, "index.mjs"));
|
|
69079
69116
|
if (!exists)
|
|
69080
69117
|
missing.push(`${file}: ${depPath}`);
|
|
69081
69118
|
}
|
|
@@ -69093,6 +69130,7 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
69093
69130
|
const detectInstallModeFn = deps?.detectInstallModeFn ?? detectInstallMode;
|
|
69094
69131
|
const hasTrackedPluginSuppliedLegacyFilesFn = deps?.hasTrackedPluginSuppliedLegacyFilesFn ?? hasTrackedPluginSuppliedLegacyFiles;
|
|
69095
69132
|
const shouldRefreshCodexPluginFn = deps?.shouldRefreshCodexPluginFn ?? ((options2) => shouldRefreshCodexPlugin(undefined, options2));
|
|
69133
|
+
const cleanupStaleCodexConfigEntriesFn = deps?.cleanupStaleCodexConfigEntriesFn ?? cleanupStaleCodexConfigEntries;
|
|
69096
69134
|
const setup = await getSetupFn();
|
|
69097
69135
|
const hasLocal = !!setup.project.metadata;
|
|
69098
69136
|
const hasGlobal = !!setup.global.metadata;
|
|
@@ -69172,9 +69210,19 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
69172
69210
|
forceKitReinstall = true;
|
|
69173
69211
|
}
|
|
69174
69212
|
}
|
|
69175
|
-
if (installModePreference !== "legacy"
|
|
69176
|
-
|
|
69177
|
-
|
|
69213
|
+
if (installModePreference !== "legacy") {
|
|
69214
|
+
try {
|
|
69215
|
+
await cleanupStaleCodexConfigEntriesFn({ global: true, provider: "codex" });
|
|
69216
|
+
} catch (error) {
|
|
69217
|
+
logger.verbose(`Codex config self-heal skipped: ${error instanceof Error ? error.message : "unknown"}`);
|
|
69218
|
+
}
|
|
69219
|
+
if (await shouldRefreshCodexPluginFn({
|
|
69220
|
+
expectedVersion: kitVersion,
|
|
69221
|
+
expectedSource: join70(PathResolver.getCacheDir(true), "ck-plugin-source", ".claude")
|
|
69222
|
+
})) {
|
|
69223
|
+
logger.warning("Detected Codex ClaudeKit plugin state requiring refresh; reinstalling global Engineer content");
|
|
69224
|
+
forceKitReinstall = true;
|
|
69225
|
+
}
|
|
69178
69226
|
}
|
|
69179
69227
|
}
|
|
69180
69228
|
} catch (error) {
|
|
@@ -69474,6 +69522,7 @@ async function promptMigrateUpdate(deps) {
|
|
|
69474
69522
|
}
|
|
69475
69523
|
var import_fs_extra8, execAsync2, SAFE_PROVIDER_NAME, HOOK_DEPENDENCY_EXTENSIONS, MANAGED_HOOKS_MANIFEST = "managed-hooks.json", StrictPluginUpdateError;
|
|
69476
69524
|
var init_post_update_handler = __esm(() => {
|
|
69525
|
+
init_codex_toml_installer();
|
|
69477
69526
|
init_ck_config_manager();
|
|
69478
69527
|
init_hook_health_checker();
|
|
69479
69528
|
init_codex_plugin_installer();
|
|
@@ -69483,6 +69532,7 @@ var init_post_update_handler = __esm(() => {
|
|
|
69483
69532
|
init_version_utils();
|
|
69484
69533
|
init_claudekit_scanner();
|
|
69485
69534
|
init_logger();
|
|
69535
|
+
init_path_resolver();
|
|
69486
69536
|
init_safe_prompts();
|
|
69487
69537
|
init_types3();
|
|
69488
69538
|
init_codex_sync_notice();
|
|
@@ -69669,7 +69719,7 @@ class ConfigVersionChecker {
|
|
|
69669
69719
|
return isPrereleaseVersion(currentVersion) ? "beta" : "stable";
|
|
69670
69720
|
}
|
|
69671
69721
|
static isValidSemverCore(version) {
|
|
69672
|
-
const [coreVersion] =
|
|
69722
|
+
const [coreVersion] = normalizeVersion2(version).split(/[-+]/, 1);
|
|
69673
69723
|
const coreParts = coreVersion?.split(".") ?? [];
|
|
69674
69724
|
return coreParts.length === 3 && coreParts.every((part) => /^\d+$/.test(part));
|
|
69675
69725
|
}
|
|
@@ -69680,12 +69730,12 @@ class ConfigVersionChecker {
|
|
|
69680
69730
|
if (!tagName || tagName.length > 256) {
|
|
69681
69731
|
continue;
|
|
69682
69732
|
}
|
|
69683
|
-
const normalizedVersion =
|
|
69733
|
+
const normalizedVersion = normalizeVersion2(tagName);
|
|
69684
69734
|
if (!ConfigVersionChecker.isValidSemverCore(normalizedVersion)) {
|
|
69685
69735
|
logger.debug(`Invalid version format from GitHub: ${tagName}`);
|
|
69686
69736
|
continue;
|
|
69687
69737
|
}
|
|
69688
|
-
if (!highestVersion ||
|
|
69738
|
+
if (!highestVersion || import_compare_versions5.compareVersions(normalizedVersion, highestVersion) > 0) {
|
|
69689
69739
|
highestVersion = normalizedVersion;
|
|
69690
69740
|
}
|
|
69691
69741
|
}
|
|
@@ -69792,13 +69842,13 @@ class ConfigVersionChecker {
|
|
|
69792
69842
|
return null;
|
|
69793
69843
|
}
|
|
69794
69844
|
const delay = baseBackoff * 2 ** attempt;
|
|
69795
|
-
await new Promise((
|
|
69845
|
+
await new Promise((resolve37) => setTimeout(resolve37, delay));
|
|
69796
69846
|
}
|
|
69797
69847
|
}
|
|
69798
69848
|
return null;
|
|
69799
69849
|
}
|
|
69800
69850
|
static async checkForUpdates(kitType, currentVersion, global3 = false, channel) {
|
|
69801
|
-
const normalizedCurrent =
|
|
69851
|
+
const normalizedCurrent = normalizeVersion2(currentVersion);
|
|
69802
69852
|
const resolvedChannel = ConfigVersionChecker.resolveChannel(normalizedCurrent, channel);
|
|
69803
69853
|
const cache3 = await ConfigVersionChecker.loadCache(kitType, global3, resolvedChannel);
|
|
69804
69854
|
const now = Date.now();
|
|
@@ -69873,13 +69923,13 @@ class ConfigVersionChecker {
|
|
|
69873
69923
|
}
|
|
69874
69924
|
}
|
|
69875
69925
|
}
|
|
69876
|
-
var
|
|
69926
|
+
var import_compare_versions5, CACHE_TTL_HOURS = 24, DEFAULT_CACHE_TTL_MS, MIN_CACHE_TTL_MS, MAX_CACHE_TTL_MS, CACHE_TTL_MS, GITHUB_API_TIMEOUT_MS = 1e4, CACHE_FILENAME = "config-update-cache.json", RELEASES_PER_PAGE = 100, KIT_REPOS;
|
|
69877
69927
|
var init_config_version_checker = __esm(() => {
|
|
69878
69928
|
init_version_utils();
|
|
69879
69929
|
init_claudekit_constants();
|
|
69880
69930
|
init_logger();
|
|
69881
69931
|
init_path_resolver();
|
|
69882
|
-
|
|
69932
|
+
import_compare_versions5 = __toESM(require_umd(), 1);
|
|
69883
69933
|
DEFAULT_CACHE_TTL_MS = CACHE_TTL_HOURS * 60 * 60 * 1000;
|
|
69884
69934
|
MIN_CACHE_TTL_MS = 60 * 1000;
|
|
69885
69935
|
MAX_CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
@@ -69893,17 +69943,17 @@ var init_config_version_checker = __esm(() => {
|
|
|
69893
69943
|
// src/domains/web-server/routes/system-routes.ts
|
|
69894
69944
|
import { spawn as spawn3 } from "node:child_process";
|
|
69895
69945
|
import { execFile as execFile9 } from "node:child_process";
|
|
69896
|
-
import { existsSync as
|
|
69946
|
+
import { existsSync as existsSync50 } from "node:fs";
|
|
69897
69947
|
import { readFile as readFile40 } from "node:fs/promises";
|
|
69898
69948
|
import { cpus, homedir as homedir42, totalmem } from "node:os";
|
|
69899
69949
|
import { join as join72 } from "node:path";
|
|
69900
69950
|
function runCommand(cmd, args, fallback2) {
|
|
69901
|
-
return new Promise((
|
|
69951
|
+
return new Promise((resolve37) => {
|
|
69902
69952
|
execFile9(cmd, args, { timeout: 5000 }, (err, stdout) => {
|
|
69903
69953
|
if (err) {
|
|
69904
|
-
|
|
69954
|
+
resolve37(fallback2);
|
|
69905
69955
|
} else {
|
|
69906
|
-
|
|
69956
|
+
resolve37(stdout.trim() || fallback2);
|
|
69907
69957
|
}
|
|
69908
69958
|
});
|
|
69909
69959
|
});
|
|
@@ -69927,7 +69977,7 @@ function hasCliUpdate(currentVersion, latestVersion) {
|
|
|
69927
69977
|
return false;
|
|
69928
69978
|
}
|
|
69929
69979
|
try {
|
|
69930
|
-
return
|
|
69980
|
+
return import_compare_versions6.compareVersions(normalizeVersion2(latestVersion), normalizeVersion2(currentVersion)) > 0;
|
|
69931
69981
|
} catch (error) {
|
|
69932
69982
|
logger.debug(`Version comparison failed for "${currentVersion}" vs "${latestVersion}": ${error}`);
|
|
69933
69983
|
return latestVersion !== currentVersion;
|
|
@@ -70183,7 +70233,7 @@ async function getPackageJson() {
|
|
|
70183
70233
|
async function getKitMetadata2(kitName) {
|
|
70184
70234
|
try {
|
|
70185
70235
|
const metadataPath = join72(PathResolver.getGlobalKitDir(), "metadata.json");
|
|
70186
|
-
if (!
|
|
70236
|
+
if (!existsSync50(metadataPath))
|
|
70187
70237
|
return null;
|
|
70188
70238
|
const content = await readFile40(metadataPath, "utf-8");
|
|
70189
70239
|
const metadata = JSON.parse(content);
|
|
@@ -70198,7 +70248,7 @@ async function getKitMetadata2(kitName) {
|
|
|
70198
70248
|
return null;
|
|
70199
70249
|
}
|
|
70200
70250
|
}
|
|
70201
|
-
var
|
|
70251
|
+
var import_compare_versions6, versionCache, CACHE_TTL_MS2;
|
|
70202
70252
|
var init_system_routes = __esm(() => {
|
|
70203
70253
|
init_update_cli();
|
|
70204
70254
|
init_github_client();
|
|
@@ -70211,7 +70261,7 @@ var init_system_routes = __esm(() => {
|
|
|
70211
70261
|
init_path_resolver();
|
|
70212
70262
|
init_kit();
|
|
70213
70263
|
init_package();
|
|
70214
|
-
|
|
70264
|
+
import_compare_versions6 = __toESM(require_umd(), 1);
|
|
70215
70265
|
versionCache = new Map;
|
|
70216
70266
|
CACHE_TTL_MS2 = 5 * 60 * 1000;
|
|
70217
70267
|
});
|
|
@@ -70339,18 +70389,18 @@ var init_routes = __esm(() => {
|
|
|
70339
70389
|
});
|
|
70340
70390
|
|
|
70341
70391
|
// src/domains/web-server/static-server.ts
|
|
70342
|
-
import { existsSync as
|
|
70343
|
-
import { basename as basename24, dirname as dirname31, join as join73, resolve as
|
|
70392
|
+
import { existsSync as existsSync51 } from "node:fs";
|
|
70393
|
+
import { basename as basename24, dirname as dirname31, join as join73, resolve as resolve37 } from "node:path";
|
|
70344
70394
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
70345
70395
|
function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
70346
70396
|
if (!runtimePath) {
|
|
70347
70397
|
return;
|
|
70348
70398
|
}
|
|
70349
|
-
const looksLikePath = runtimePath.includes("/") || runtimePath.includes("\\") ||
|
|
70399
|
+
const looksLikePath = runtimePath.includes("/") || runtimePath.includes("\\") || existsSync51(runtimePath);
|
|
70350
70400
|
if (!looksLikePath) {
|
|
70351
70401
|
return;
|
|
70352
70402
|
}
|
|
70353
|
-
const entryDir = dirname31(
|
|
70403
|
+
const entryDir = dirname31(resolve37(runtimePath));
|
|
70354
70404
|
if (basename24(entryDir) === "dist") {
|
|
70355
70405
|
candidates.add(join73(entryDir, "ui"));
|
|
70356
70406
|
}
|
|
@@ -70363,7 +70413,7 @@ function resolveUiDistPath() {
|
|
|
70363
70413
|
candidates.add(join73(process.cwd(), "dist", "ui"));
|
|
70364
70414
|
candidates.add(join73(process.cwd(), "src", "ui", "dist"));
|
|
70365
70415
|
for (const path7 of candidates) {
|
|
70366
|
-
if (
|
|
70416
|
+
if (existsSync51(join73(path7, "index.html"))) {
|
|
70367
70417
|
return path7;
|
|
70368
70418
|
}
|
|
70369
70419
|
}
|
|
@@ -70371,7 +70421,7 @@ function resolveUiDistPath() {
|
|
|
70371
70421
|
}
|
|
70372
70422
|
function serveStatic(app) {
|
|
70373
70423
|
const uiDistPath = resolveUiDistPath();
|
|
70374
|
-
if (!
|
|
70424
|
+
if (!existsSync51(uiDistPath)) {
|
|
70375
70425
|
logger.warning(`UI dist not found at ${uiDistPath}. Run 'bun run ui:build' first.`);
|
|
70376
70426
|
app.use((req, res, next) => {
|
|
70377
70427
|
if (req.path.startsWith("/api/")) {
|
|
@@ -73382,10 +73432,10 @@ async function createAppServer(options2 = {}) {
|
|
|
73382
73432
|
wsManager = new WebSocketManager(server);
|
|
73383
73433
|
fileWatcher = new FileWatcher({ wsManager });
|
|
73384
73434
|
fileWatcher.start();
|
|
73385
|
-
await new Promise((
|
|
73435
|
+
await new Promise((resolve38, reject) => {
|
|
73386
73436
|
const onListening = () => {
|
|
73387
73437
|
server.off("error", onError);
|
|
73388
|
-
|
|
73438
|
+
resolve38();
|
|
73389
73439
|
};
|
|
73390
73440
|
const onError = (error) => {
|
|
73391
73441
|
server.off("listening", onListening);
|
|
@@ -73422,16 +73472,16 @@ async function createAppServer(options2 = {}) {
|
|
|
73422
73472
|
};
|
|
73423
73473
|
}
|
|
73424
73474
|
async function closeHttpServer(server) {
|
|
73425
|
-
await new Promise((
|
|
73475
|
+
await new Promise((resolve38) => {
|
|
73426
73476
|
if (!server.listening) {
|
|
73427
|
-
|
|
73477
|
+
resolve38();
|
|
73428
73478
|
return;
|
|
73429
73479
|
}
|
|
73430
73480
|
server.close((err) => {
|
|
73431
73481
|
if (err) {
|
|
73432
73482
|
logger.debug(`Server close error: ${err.message}`);
|
|
73433
73483
|
}
|
|
73434
|
-
|
|
73484
|
+
resolve38();
|
|
73435
73485
|
});
|
|
73436
73486
|
});
|
|
73437
73487
|
}
|
|
@@ -75167,7 +75217,7 @@ var require_picomatch2 = __commonJS((exports, module) => {
|
|
|
75167
75217
|
import { exec as exec7, execFile as execFile10, spawn as spawn4 } from "node:child_process";
|
|
75168
75218
|
import { promisify as promisify15 } from "node:util";
|
|
75169
75219
|
function executeInteractiveScript(command, args, options2) {
|
|
75170
|
-
return new Promise((
|
|
75220
|
+
return new Promise((resolve40, reject) => {
|
|
75171
75221
|
const child = spawn4(command, args, {
|
|
75172
75222
|
stdio: ["ignore", "inherit", "inherit"],
|
|
75173
75223
|
cwd: options2?.cwd,
|
|
@@ -75188,7 +75238,7 @@ function executeInteractiveScript(command, args, options2) {
|
|
|
75188
75238
|
} else if (code !== 0) {
|
|
75189
75239
|
reject(new Error(`Command exited with code ${code}`));
|
|
75190
75240
|
} else {
|
|
75191
|
-
|
|
75241
|
+
resolve40();
|
|
75192
75242
|
}
|
|
75193
75243
|
});
|
|
75194
75244
|
child.on("error", (error) => {
|
|
@@ -75367,7 +75417,7 @@ var init_opencode_installer = __esm(() => {
|
|
|
75367
75417
|
var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CODE_PARTIAL_SUCCESS = 2;
|
|
75368
75418
|
|
|
75369
75419
|
// src/services/package-installer/validators.ts
|
|
75370
|
-
import { resolve as
|
|
75420
|
+
import { resolve as resolve40 } from "node:path";
|
|
75371
75421
|
function validatePackageName(packageName) {
|
|
75372
75422
|
if (!packageName || typeof packageName !== "string") {
|
|
75373
75423
|
throw new Error("Package name must be a non-empty string");
|
|
@@ -75380,8 +75430,8 @@ function validatePackageName(packageName) {
|
|
|
75380
75430
|
}
|
|
75381
75431
|
}
|
|
75382
75432
|
function validateScriptPath(skillsDir2, scriptPath) {
|
|
75383
|
-
const skillsDirResolved =
|
|
75384
|
-
const scriptPathResolved =
|
|
75433
|
+
const skillsDirResolved = resolve40(skillsDir2);
|
|
75434
|
+
const scriptPathResolved = resolve40(scriptPath);
|
|
75385
75435
|
const skillsDirNormalized = isWindows() ? skillsDirResolved.toLowerCase() : skillsDirResolved;
|
|
75386
75436
|
const scriptPathNormalized = isWindows() ? scriptPathResolved.toLowerCase() : scriptPathResolved;
|
|
75387
75437
|
if (!scriptPathNormalized.startsWith(skillsDirNormalized)) {
|
|
@@ -75551,7 +75601,7 @@ var init_npm_package_manager = __esm(() => {
|
|
|
75551
75601
|
});
|
|
75552
75602
|
|
|
75553
75603
|
// src/services/package-installer/install-error-handler.ts
|
|
75554
|
-
import { existsSync as
|
|
75604
|
+
import { existsSync as existsSync63, readFileSync as readFileSync22, unlinkSync as unlinkSync3 } from "node:fs";
|
|
75555
75605
|
import { join as join94 } from "node:path";
|
|
75556
75606
|
function parseNameReason(str2) {
|
|
75557
75607
|
const colonIndex = str2.indexOf(":");
|
|
@@ -75616,7 +75666,7 @@ function getSystemPackageCommands(summary, systemFailures) {
|
|
|
75616
75666
|
}
|
|
75617
75667
|
function displayInstallErrors(skillsDir2) {
|
|
75618
75668
|
const summaryPath = join94(skillsDir2, ".install-error-summary.json");
|
|
75619
|
-
if (!
|
|
75669
|
+
if (!existsSync63(summaryPath)) {
|
|
75620
75670
|
logger.error("Skills installation failed. Run with --verbose for details.");
|
|
75621
75671
|
return;
|
|
75622
75672
|
}
|
|
@@ -75715,7 +75765,7 @@ async function checkNeedsSudoPackages() {
|
|
|
75715
75765
|
}
|
|
75716
75766
|
function hasInstallState(skillsDir2) {
|
|
75717
75767
|
const stateFilePath = join94(skillsDir2, ".install-state.json");
|
|
75718
|
-
return
|
|
75768
|
+
return existsSync63(stateFilePath);
|
|
75719
75769
|
}
|
|
75720
75770
|
var WHICH_COMMAND_TIMEOUT_MS = 5000, WINDOWS_SYSTEM_PACKAGES, SYSTEM_TOOL_KEYS, WINDOWS_RSVG_COMMANDS;
|
|
75721
75771
|
var init_install_error_handler = __esm(() => {
|
|
@@ -75754,7 +75804,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
75754
75804
|
};
|
|
75755
75805
|
}
|
|
75756
75806
|
try {
|
|
75757
|
-
const { existsSync:
|
|
75807
|
+
const { existsSync: existsSync64 } = await import("node:fs");
|
|
75758
75808
|
const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
|
|
75759
75809
|
const platform10 = process.platform;
|
|
75760
75810
|
const scriptName = platform10 === "win32" ? "install.ps1" : "install.sh";
|
|
@@ -75770,7 +75820,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
75770
75820
|
error: `Path validation failed: ${errorMessage}`
|
|
75771
75821
|
};
|
|
75772
75822
|
}
|
|
75773
|
-
if (!
|
|
75823
|
+
if (!existsSync64(scriptPath)) {
|
|
75774
75824
|
logger.warning(`Skills installation script not found: ${scriptPath}`);
|
|
75775
75825
|
logger.info("");
|
|
75776
75826
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
@@ -75986,7 +76036,7 @@ var init_skills_installer2 = __esm(() => {
|
|
|
75986
76036
|
});
|
|
75987
76037
|
|
|
75988
76038
|
// src/services/package-installer/agy-mcp/config-manager.ts
|
|
75989
|
-
import { existsSync as
|
|
76039
|
+
import { existsSync as existsSync64 } from "node:fs";
|
|
75990
76040
|
import { mkdir as mkdir23, readFile as readFile49, writeFile as writeFile25 } from "node:fs/promises";
|
|
75991
76041
|
import { dirname as dirname34, join as join96 } from "node:path";
|
|
75992
76042
|
async function readJsonFile(filePath) {
|
|
@@ -76003,7 +76053,7 @@ async function addAgyToGitignore(projectDir) {
|
|
|
76003
76053
|
const gitignorePath = join96(projectDir, ".gitignore");
|
|
76004
76054
|
try {
|
|
76005
76055
|
let content = "";
|
|
76006
|
-
if (
|
|
76056
|
+
if (existsSync64(gitignorePath)) {
|
|
76007
76057
|
content = await readFile49(gitignorePath, "utf-8");
|
|
76008
76058
|
const lines = content.split(`
|
|
76009
76059
|
`).map((line) => line.trim()).filter((line) => !line.startsWith("#"));
|
|
@@ -76032,7 +76082,7 @@ ${AGY_GITIGNORE_PATTERN}
|
|
|
76032
76082
|
}
|
|
76033
76083
|
async function createNewSettingsWithMerge(agyConfigPath, mcpConfigPath) {
|
|
76034
76084
|
const linkDir = dirname34(agyConfigPath);
|
|
76035
|
-
if (!
|
|
76085
|
+
if (!existsSync64(linkDir)) {
|
|
76036
76086
|
await mkdir23(linkDir, { recursive: true });
|
|
76037
76087
|
logger.debug(`Created directory: ${linkDir}`);
|
|
76038
76088
|
}
|
|
@@ -76098,7 +76148,7 @@ var init_config_manager2 = __esm(() => {
|
|
|
76098
76148
|
});
|
|
76099
76149
|
|
|
76100
76150
|
// src/services/package-installer/agy-mcp/validation.ts
|
|
76101
|
-
import { existsSync as
|
|
76151
|
+
import { existsSync as existsSync65, lstatSync, readlinkSync } from "node:fs";
|
|
76102
76152
|
import { homedir as homedir45 } from "node:os";
|
|
76103
76153
|
import { join as join97 } from "node:path";
|
|
76104
76154
|
function getGlobalMcpConfigPath() {
|
|
@@ -76109,12 +76159,12 @@ function getLocalMcpConfigPath(projectDir) {
|
|
|
76109
76159
|
}
|
|
76110
76160
|
function findMcpConfigPath(projectDir) {
|
|
76111
76161
|
const localPath = getLocalMcpConfigPath(projectDir);
|
|
76112
|
-
if (
|
|
76162
|
+
if (existsSync65(localPath)) {
|
|
76113
76163
|
logger.debug(`Found local MCP config: ${localPath}`);
|
|
76114
76164
|
return localPath;
|
|
76115
76165
|
}
|
|
76116
76166
|
const globalPath = getGlobalMcpConfigPath();
|
|
76117
|
-
if (
|
|
76167
|
+
if (existsSync65(globalPath)) {
|
|
76118
76168
|
logger.debug(`Found global MCP config: ${globalPath}`);
|
|
76119
76169
|
return globalPath;
|
|
76120
76170
|
}
|
|
@@ -76129,7 +76179,7 @@ function getAgyMcpConfigPath(projectDir, isGlobal) {
|
|
|
76129
76179
|
}
|
|
76130
76180
|
function checkExistingAgyConfig(projectDir, isGlobal = false) {
|
|
76131
76181
|
const agyConfigPath = getAgyMcpConfigPath(projectDir, isGlobal);
|
|
76132
|
-
if (!
|
|
76182
|
+
if (!existsSync65(agyConfigPath)) {
|
|
76133
76183
|
return { exists: false, isSymlink: false, settingsPath: agyConfigPath };
|
|
76134
76184
|
}
|
|
76135
76185
|
try {
|
|
@@ -76153,12 +76203,12 @@ var init_validation = __esm(() => {
|
|
|
76153
76203
|
});
|
|
76154
76204
|
|
|
76155
76205
|
// src/services/package-installer/agy-mcp/linker-core.ts
|
|
76156
|
-
import { existsSync as
|
|
76206
|
+
import { existsSync as existsSync66 } from "node:fs";
|
|
76157
76207
|
import { mkdir as mkdir24, symlink as symlink3 } from "node:fs/promises";
|
|
76158
76208
|
import { dirname as dirname35, join as join98 } from "node:path";
|
|
76159
76209
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
76160
76210
|
const linkDir = dirname35(linkPath);
|
|
76161
|
-
if (!
|
|
76211
|
+
if (!existsSync66(linkDir)) {
|
|
76162
76212
|
await mkdir24(linkDir, { recursive: true });
|
|
76163
76213
|
logger.debug(`Created directory: ${linkDir}`);
|
|
76164
76214
|
}
|
|
@@ -76199,10 +76249,10 @@ __export(exports_agy_mcp_linker, {
|
|
|
76199
76249
|
checkExistingAgyConfig: () => checkExistingAgyConfig,
|
|
76200
76250
|
addAgyToGitignore: () => addAgyToGitignore
|
|
76201
76251
|
});
|
|
76202
|
-
import { resolve as
|
|
76252
|
+
import { resolve as resolve41 } from "node:path";
|
|
76203
76253
|
async function linkAgyMcpConfig(projectDir, options2 = {}) {
|
|
76204
76254
|
const { skipGitignore = false, isGlobal = false } = options2;
|
|
76205
|
-
const resolvedProjectDir =
|
|
76255
|
+
const resolvedProjectDir = resolve41(projectDir);
|
|
76206
76256
|
const agyConfigPath = getAgyMcpConfigPath(resolvedProjectDir, isGlobal);
|
|
76207
76257
|
const mcpConfigPath = findMcpConfigPath(resolvedProjectDir);
|
|
76208
76258
|
if (!mcpConfigPath) {
|
|
@@ -76851,7 +76901,7 @@ var require_get_stream = __commonJS((exports, module) => {
|
|
|
76851
76901
|
};
|
|
76852
76902
|
const { maxBuffer } = options2;
|
|
76853
76903
|
let stream;
|
|
76854
|
-
await new Promise((
|
|
76904
|
+
await new Promise((resolve43, reject) => {
|
|
76855
76905
|
const rejectPromise = (error) => {
|
|
76856
76906
|
if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
|
|
76857
76907
|
error.bufferedData = stream.getBufferedValue();
|
|
@@ -76863,7 +76913,7 @@ var require_get_stream = __commonJS((exports, module) => {
|
|
|
76863
76913
|
rejectPromise(error);
|
|
76864
76914
|
return;
|
|
76865
76915
|
}
|
|
76866
|
-
|
|
76916
|
+
resolve43();
|
|
76867
76917
|
});
|
|
76868
76918
|
stream.on("data", () => {
|
|
76869
76919
|
if (stream.getBufferedLength() > maxBuffer) {
|
|
@@ -78224,7 +78274,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
78224
78274
|
debug("opening", this.zipPath, "with opts", this.opts);
|
|
78225
78275
|
this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
|
|
78226
78276
|
this.canceled = false;
|
|
78227
|
-
return new Promise((
|
|
78277
|
+
return new Promise((resolve43, reject) => {
|
|
78228
78278
|
this.zipfile.on("error", (err) => {
|
|
78229
78279
|
this.canceled = true;
|
|
78230
78280
|
reject(err);
|
|
@@ -78233,7 +78283,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
78233
78283
|
this.zipfile.on("close", () => {
|
|
78234
78284
|
if (!this.canceled) {
|
|
78235
78285
|
debug("zip extraction complete");
|
|
78236
|
-
|
|
78286
|
+
resolve43();
|
|
78237
78287
|
}
|
|
78238
78288
|
});
|
|
78239
78289
|
this.zipfile.on("entry", async (entry) => {
|
|
@@ -78552,7 +78602,7 @@ async function restoreOriginalBranch(branchName, cwd2, issueNumber) {
|
|
|
78552
78602
|
}
|
|
78553
78603
|
}
|
|
78554
78604
|
function spawnAndCollect(command, args, cwd2) {
|
|
78555
|
-
return new Promise((
|
|
78605
|
+
return new Promise((resolve60, reject) => {
|
|
78556
78606
|
const child = spawn5(command, args, { ...cwd2 && { cwd: cwd2 }, stdio: ["ignore", "pipe", "pipe"] });
|
|
78557
78607
|
const chunks = [];
|
|
78558
78608
|
const stderrChunks = [];
|
|
@@ -78565,7 +78615,7 @@ function spawnAndCollect(command, args, cwd2) {
|
|
|
78565
78615
|
reject(new Error(`${command} ${args[0] ?? ""} exited with code ${code2}: ${stderr}`));
|
|
78566
78616
|
return;
|
|
78567
78617
|
}
|
|
78568
|
-
|
|
78618
|
+
resolve60(Buffer.concat(chunks).toString("utf-8"));
|
|
78569
78619
|
});
|
|
78570
78620
|
});
|
|
78571
78621
|
}
|
|
@@ -78582,7 +78632,7 @@ __export(exports_worktree_manager, {
|
|
|
78582
78632
|
createWorktree: () => createWorktree,
|
|
78583
78633
|
cleanupAllWorktrees: () => cleanupAllWorktrees
|
|
78584
78634
|
});
|
|
78585
|
-
import { existsSync as
|
|
78635
|
+
import { existsSync as existsSync78 } from "node:fs";
|
|
78586
78636
|
import { readFile as readFile70, writeFile as writeFile41 } from "node:fs/promises";
|
|
78587
78637
|
import { join as join162 } from "node:path";
|
|
78588
78638
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
@@ -78648,7 +78698,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
78648
78698
|
async function ensureGitignore(projectDir) {
|
|
78649
78699
|
const gitignorePath = join162(projectDir, ".gitignore");
|
|
78650
78700
|
try {
|
|
78651
|
-
const content =
|
|
78701
|
+
const content = existsSync78(gitignorePath) ? await readFile70(gitignorePath, "utf-8") : "";
|
|
78652
78702
|
if (!content.includes(".worktrees")) {
|
|
78653
78703
|
const newContent = content.endsWith(`
|
|
78654
78704
|
`) ? `${content}.worktrees/
|
|
@@ -78750,13 +78800,13 @@ var init_content_validator = __esm(() => {
|
|
|
78750
78800
|
|
|
78751
78801
|
// src/commands/content/phases/context-cache-manager.ts
|
|
78752
78802
|
import { createHash as createHash11 } from "node:crypto";
|
|
78753
|
-
import { existsSync as
|
|
78803
|
+
import { existsSync as existsSync84, mkdirSync as mkdirSync7, readFileSync as readFileSync25, readdirSync as readdirSync15, statSync as statSync15 } from "node:fs";
|
|
78754
78804
|
import { rename as rename16, writeFile as writeFile43 } from "node:fs/promises";
|
|
78755
78805
|
import { homedir as homedir54 } from "node:os";
|
|
78756
78806
|
import { basename as basename34, join as join169 } from "node:path";
|
|
78757
78807
|
function getCachedContext(repoPath) {
|
|
78758
78808
|
const cachePath = getCacheFilePath(repoPath);
|
|
78759
|
-
if (!
|
|
78809
|
+
if (!existsSync84(cachePath))
|
|
78760
78810
|
return null;
|
|
78761
78811
|
try {
|
|
78762
78812
|
const raw2 = readFileSync25(cachePath, "utf-8");
|
|
@@ -78773,7 +78823,7 @@ function getCachedContext(repoPath) {
|
|
|
78773
78823
|
}
|
|
78774
78824
|
}
|
|
78775
78825
|
async function saveCachedContext(repoPath, cache5) {
|
|
78776
|
-
if (!
|
|
78826
|
+
if (!existsSync84(CACHE_DIR)) {
|
|
78777
78827
|
mkdirSync7(CACHE_DIR, { recursive: true });
|
|
78778
78828
|
}
|
|
78779
78829
|
const cachePath = getCacheFilePath(repoPath);
|
|
@@ -78797,7 +78847,7 @@ function computeSourceHash(repoPath) {
|
|
|
78797
78847
|
function getDocSourcePaths(repoPath) {
|
|
78798
78848
|
const paths = [];
|
|
78799
78849
|
const docsDir = join169(repoPath, "docs");
|
|
78800
|
-
if (
|
|
78850
|
+
if (existsSync84(docsDir)) {
|
|
78801
78851
|
try {
|
|
78802
78852
|
const files = readdirSync15(docsDir);
|
|
78803
78853
|
for (const f3 of files) {
|
|
@@ -78807,10 +78857,10 @@ function getDocSourcePaths(repoPath) {
|
|
|
78807
78857
|
} catch {}
|
|
78808
78858
|
}
|
|
78809
78859
|
const readme = join169(repoPath, "README.md");
|
|
78810
|
-
if (
|
|
78860
|
+
if (existsSync84(readme))
|
|
78811
78861
|
paths.push(readme);
|
|
78812
78862
|
const stylesDir = join169(repoPath, "assets", "writing-styles");
|
|
78813
|
-
if (
|
|
78863
|
+
if (existsSync84(stylesDir)) {
|
|
78814
78864
|
try {
|
|
78815
78865
|
const files = readdirSync15(stylesDir);
|
|
78816
78866
|
for (const f3 of files) {
|
|
@@ -79007,7 +79057,7 @@ function extractContentFromResponse(response) {
|
|
|
79007
79057
|
|
|
79008
79058
|
// src/commands/content/phases/docs-summarizer.ts
|
|
79009
79059
|
import { execSync as execSync7 } from "node:child_process";
|
|
79010
|
-
import { existsSync as
|
|
79060
|
+
import { existsSync as existsSync85, readFileSync as readFileSync26, readdirSync as readdirSync16 } from "node:fs";
|
|
79011
79061
|
import { join as join170 } from "node:path";
|
|
79012
79062
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
79013
79063
|
const rawContent = collectRawDocs(repoPath);
|
|
@@ -79052,7 +79102,7 @@ async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
|
79052
79102
|
function collectRawDocs(repoPath) {
|
|
79053
79103
|
let totalChars = 0;
|
|
79054
79104
|
const readCapped = (filePath, maxChars) => {
|
|
79055
|
-
if (!
|
|
79105
|
+
if (!existsSync85(filePath))
|
|
79056
79106
|
return "";
|
|
79057
79107
|
if (totalChars >= MAX_RAW_CONTENT_CHARS)
|
|
79058
79108
|
return "";
|
|
@@ -79063,7 +79113,7 @@ function collectRawDocs(repoPath) {
|
|
|
79063
79113
|
};
|
|
79064
79114
|
const docsContent = [];
|
|
79065
79115
|
const docsDir = join170(repoPath, "docs");
|
|
79066
|
-
if (
|
|
79116
|
+
if (existsSync85(docsDir)) {
|
|
79067
79117
|
try {
|
|
79068
79118
|
const files = readdirSync16(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
79069
79119
|
for (const f3 of files) {
|
|
@@ -79087,7 +79137,7 @@ ${content}`);
|
|
|
79087
79137
|
}
|
|
79088
79138
|
let styles3 = "";
|
|
79089
79139
|
const stylesDir = join170(repoPath, "assets", "writing-styles");
|
|
79090
|
-
if (
|
|
79140
|
+
if (existsSync85(stylesDir)) {
|
|
79091
79141
|
try {
|
|
79092
79142
|
const files = readdirSync16(stylesDir).slice(0, 3);
|
|
79093
79143
|
styles3 = files.map((f3) => readCapped(join170(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
@@ -79280,12 +79330,12 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
79280
79330
|
|
|
79281
79331
|
// src/commands/content/phases/photo-generator.ts
|
|
79282
79332
|
import { execSync as execSync8 } from "node:child_process";
|
|
79283
|
-
import { existsSync as
|
|
79333
|
+
import { existsSync as existsSync86, mkdirSync as mkdirSync8, readdirSync as readdirSync17 } from "node:fs";
|
|
79284
79334
|
import { homedir as homedir55 } from "node:os";
|
|
79285
79335
|
import { join as join171 } from "node:path";
|
|
79286
79336
|
async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
|
|
79287
79337
|
const mediaDir = join171(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
|
|
79288
|
-
if (!
|
|
79338
|
+
if (!existsSync86(mediaDir)) {
|
|
79289
79339
|
mkdirSync8(mediaDir, { recursive: true });
|
|
79290
79340
|
}
|
|
79291
79341
|
const prompt = buildPhotoPrompt(context, platform18);
|
|
@@ -79301,7 +79351,7 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
|
|
|
79301
79351
|
const parsed = parseClaudeJsonOutput(result);
|
|
79302
79352
|
if (parsed && typeof parsed === "object" && "imagePath" in parsed) {
|
|
79303
79353
|
const imagePath = String(parsed.imagePath);
|
|
79304
|
-
if (
|
|
79354
|
+
if (existsSync86(imagePath)) {
|
|
79305
79355
|
return { path: imagePath, ...dimensions, format: "png" };
|
|
79306
79356
|
}
|
|
79307
79357
|
}
|
|
@@ -79397,7 +79447,7 @@ var init_content_creator = __esm(() => {
|
|
|
79397
79447
|
});
|
|
79398
79448
|
|
|
79399
79449
|
// src/commands/content/phases/content-logger.ts
|
|
79400
|
-
import { createWriteStream as createWriteStream4, existsSync as
|
|
79450
|
+
import { createWriteStream as createWriteStream4, existsSync as existsSync87, mkdirSync as mkdirSync9, statSync as statSync16 } from "node:fs";
|
|
79401
79451
|
import { homedir as homedir56 } from "node:os";
|
|
79402
79452
|
import { join as join172 } from "node:path";
|
|
79403
79453
|
|
|
@@ -79411,7 +79461,7 @@ class ContentLogger {
|
|
|
79411
79461
|
this.maxBytes = maxBytes;
|
|
79412
79462
|
}
|
|
79413
79463
|
init() {
|
|
79414
|
-
if (!
|
|
79464
|
+
if (!existsSync87(this.logDir)) {
|
|
79415
79465
|
mkdirSync9(this.logDir, { recursive: true });
|
|
79416
79466
|
}
|
|
79417
79467
|
this.rotateIfNeeded();
|
|
@@ -79549,7 +79599,7 @@ var init_sqlite_client = __esm(() => {
|
|
|
79549
79599
|
});
|
|
79550
79600
|
|
|
79551
79601
|
// src/commands/content/phases/db-manager.ts
|
|
79552
|
-
import { existsSync as
|
|
79602
|
+
import { existsSync as existsSync88, mkdirSync as mkdirSync10 } from "node:fs";
|
|
79553
79603
|
import { dirname as dirname56 } from "node:path";
|
|
79554
79604
|
function initDatabase(dbPath) {
|
|
79555
79605
|
ensureParentDir(dbPath);
|
|
@@ -79572,7 +79622,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
79572
79622
|
}
|
|
79573
79623
|
function ensureParentDir(dbPath) {
|
|
79574
79624
|
const dir = dirname56(dbPath);
|
|
79575
|
-
if (dir && !
|
|
79625
|
+
if (dir && !existsSync88(dir)) {
|
|
79576
79626
|
mkdirSync10(dir, { recursive: true });
|
|
79577
79627
|
}
|
|
79578
79628
|
}
|
|
@@ -79737,7 +79787,7 @@ function isNoiseCommit(title, author) {
|
|
|
79737
79787
|
|
|
79738
79788
|
// src/commands/content/phases/change-detector.ts
|
|
79739
79789
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
79740
|
-
import { existsSync as
|
|
79790
|
+
import { existsSync as existsSync89, readFileSync as readFileSync27, readdirSync as readdirSync18, statSync as statSync17 } from "node:fs";
|
|
79741
79791
|
import { join as join173 } from "node:path";
|
|
79742
79792
|
function detectCommits(repo, since) {
|
|
79743
79793
|
try {
|
|
@@ -79848,7 +79898,7 @@ function detectTags(repo, since) {
|
|
|
79848
79898
|
}
|
|
79849
79899
|
function detectCompletedPlans(repo, since) {
|
|
79850
79900
|
const plansDir = join173(repo.path, "plans");
|
|
79851
|
-
if (!
|
|
79901
|
+
if (!existsSync89(plansDir))
|
|
79852
79902
|
return [];
|
|
79853
79903
|
const sinceMs = new Date(since).getTime();
|
|
79854
79904
|
const events = [];
|
|
@@ -79858,7 +79908,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
79858
79908
|
if (!entry.isDirectory())
|
|
79859
79909
|
continue;
|
|
79860
79910
|
const planFile = join173(plansDir, entry.name, "plan.md");
|
|
79861
|
-
if (!
|
|
79911
|
+
if (!existsSync89(planFile))
|
|
79862
79912
|
continue;
|
|
79863
79913
|
try {
|
|
79864
79914
|
const stat26 = statSync17(planFile);
|
|
@@ -80926,7 +80976,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
80926
80976
|
});
|
|
80927
80977
|
|
|
80928
80978
|
// src/commands/content/phases/setup-wizard.ts
|
|
80929
|
-
import { existsSync as
|
|
80979
|
+
import { existsSync as existsSync90 } from "node:fs";
|
|
80930
80980
|
import { join as join176 } from "node:path";
|
|
80931
80981
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
80932
80982
|
console.log();
|
|
@@ -80995,8 +81045,8 @@ async function showRepoSummary(cwd2) {
|
|
|
80995
81045
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
80996
81046
|
const repos = discoverRepos2(cwd2);
|
|
80997
81047
|
for (const repo of repos) {
|
|
80998
|
-
const hasGuidelines =
|
|
80999
|
-
const hasStyles =
|
|
81048
|
+
const hasGuidelines = existsSync90(join176(repo.path, "docs", "brand-guidelines.md"));
|
|
81049
|
+
const hasStyles = existsSync90(join176(repo.path, "assets", "writing-styles"));
|
|
81000
81050
|
if (!hasGuidelines) {
|
|
81001
81051
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
81002
81052
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -81062,13 +81112,13 @@ var init_setup_wizard = __esm(() => {
|
|
|
81062
81112
|
});
|
|
81063
81113
|
|
|
81064
81114
|
// src/commands/content/content-review-commands.ts
|
|
81065
|
-
import { existsSync as
|
|
81115
|
+
import { existsSync as existsSync91 } from "node:fs";
|
|
81066
81116
|
import { homedir as homedir57 } from "node:os";
|
|
81067
81117
|
async function queueContent() {
|
|
81068
81118
|
const cwd2 = process.cwd();
|
|
81069
81119
|
const config = await loadContentConfig(cwd2);
|
|
81070
81120
|
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
81071
|
-
if (!
|
|
81121
|
+
if (!existsSync91(dbPath)) {
|
|
81072
81122
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
81073
81123
|
return;
|
|
81074
81124
|
}
|
|
@@ -81136,12 +81186,12 @@ __export(exports_content_subcommands, {
|
|
|
81136
81186
|
logsContent: () => logsContent,
|
|
81137
81187
|
approveContentCmd: () => approveContentCmd
|
|
81138
81188
|
});
|
|
81139
|
-
import { existsSync as
|
|
81189
|
+
import { existsSync as existsSync92, readFileSync as readFileSync28, unlinkSync as unlinkSync6 } from "node:fs";
|
|
81140
81190
|
import { homedir as homedir58 } from "node:os";
|
|
81141
81191
|
import { join as join177 } from "node:path";
|
|
81142
81192
|
function isDaemonRunning() {
|
|
81143
81193
|
const lockFile = join177(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
81144
|
-
if (!
|
|
81194
|
+
if (!existsSync92(lockFile))
|
|
81145
81195
|
return { running: false, pid: null };
|
|
81146
81196
|
try {
|
|
81147
81197
|
const pidStr = readFileSync28(lockFile, "utf-8").trim();
|
|
@@ -81173,7 +81223,7 @@ async function startContent(options2) {
|
|
|
81173
81223
|
}
|
|
81174
81224
|
async function stopContent() {
|
|
81175
81225
|
const lockFile = join177(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
81176
|
-
if (!
|
|
81226
|
+
if (!existsSync92(lockFile)) {
|
|
81177
81227
|
logger.info("Content daemon is not running.");
|
|
81178
81228
|
return;
|
|
81179
81229
|
}
|
|
@@ -81214,7 +81264,7 @@ async function logsContent(options2) {
|
|
|
81214
81264
|
const logDir = join177(homedir58(), ".claudekit", "logs");
|
|
81215
81265
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
81216
81266
|
const logPath = join177(logDir, `content-${dateStr}.log`);
|
|
81217
|
-
if (!
|
|
81267
|
+
if (!existsSync92(logPath)) {
|
|
81218
81268
|
logger.info("No content logs found for today.");
|
|
81219
81269
|
return;
|
|
81220
81270
|
}
|
|
@@ -81249,7 +81299,7 @@ var init_content_subcommands = __esm(() => {
|
|
|
81249
81299
|
});
|
|
81250
81300
|
|
|
81251
81301
|
// src/commands/content/content-command.ts
|
|
81252
|
-
import { existsSync as
|
|
81302
|
+
import { existsSync as existsSync93, mkdirSync as mkdirSync11, unlinkSync as unlinkSync7, writeFileSync as writeFileSync9 } from "node:fs";
|
|
81253
81303
|
import { homedir as homedir59 } from "node:os";
|
|
81254
81304
|
import { join as join178 } from "node:path";
|
|
81255
81305
|
async function contentCommand(options2) {
|
|
@@ -81280,7 +81330,7 @@ async function contentCommand(options2) {
|
|
|
81280
81330
|
}
|
|
81281
81331
|
contentLogger.info("Setup complete. Starting daemon...");
|
|
81282
81332
|
}
|
|
81283
|
-
if (!
|
|
81333
|
+
if (!existsSync93(LOCK_DIR2))
|
|
81284
81334
|
mkdirSync11(LOCK_DIR2, { recursive: true });
|
|
81285
81335
|
writeFileSync9(LOCK_FILE, String(process.pid), "utf-8");
|
|
81286
81336
|
const dbPath = config.dbPath.replace(/^~/, homedir59());
|
|
@@ -81412,8 +81462,8 @@ function shouldRunCleanup(lastAt) {
|
|
|
81412
81462
|
return Date.now() - new Date(lastAt).getTime() >= 86400000;
|
|
81413
81463
|
}
|
|
81414
81464
|
function sleep2(ms) {
|
|
81415
|
-
return new Promise((
|
|
81416
|
-
setTimeout(
|
|
81465
|
+
return new Promise((resolve60) => {
|
|
81466
|
+
setTimeout(resolve60, ms);
|
|
81417
81467
|
});
|
|
81418
81468
|
}
|
|
81419
81469
|
var LOCK_DIR2, LOCK_FILE, MAX_CREATION_RETRIES = 3, MAX_PUBLISH_RETRIES_PER_CYCLE = 3, PUBLISH_RETRY_WINDOW_HOURS = 24;
|
|
@@ -83671,7 +83721,7 @@ function getPagerArgs(pagerCmd) {
|
|
|
83671
83721
|
return [];
|
|
83672
83722
|
}
|
|
83673
83723
|
async function trySystemPager(content) {
|
|
83674
|
-
return new Promise((
|
|
83724
|
+
return new Promise((resolve60) => {
|
|
83675
83725
|
const pagerCmd = process.env.PAGER || "less";
|
|
83676
83726
|
const pagerArgs = getPagerArgs(pagerCmd);
|
|
83677
83727
|
try {
|
|
@@ -83681,20 +83731,20 @@ async function trySystemPager(content) {
|
|
|
83681
83731
|
});
|
|
83682
83732
|
const timeout2 = setTimeout(() => {
|
|
83683
83733
|
pager.kill();
|
|
83684
|
-
|
|
83734
|
+
resolve60(false);
|
|
83685
83735
|
}, 30000);
|
|
83686
83736
|
pager.stdin.write(content);
|
|
83687
83737
|
pager.stdin.end();
|
|
83688
83738
|
pager.on("close", (code2) => {
|
|
83689
83739
|
clearTimeout(timeout2);
|
|
83690
|
-
|
|
83740
|
+
resolve60(code2 === 0);
|
|
83691
83741
|
});
|
|
83692
83742
|
pager.on("error", () => {
|
|
83693
83743
|
clearTimeout(timeout2);
|
|
83694
|
-
|
|
83744
|
+
resolve60(false);
|
|
83695
83745
|
});
|
|
83696
83746
|
} catch {
|
|
83697
|
-
|
|
83747
|
+
resolve60(false);
|
|
83698
83748
|
}
|
|
83699
83749
|
});
|
|
83700
83750
|
}
|
|
@@ -83721,16 +83771,16 @@ async function basicPager(content) {
|
|
|
83721
83771
|
break;
|
|
83722
83772
|
}
|
|
83723
83773
|
const remaining = lines.length - currentLine;
|
|
83724
|
-
await new Promise((
|
|
83774
|
+
await new Promise((resolve60) => {
|
|
83725
83775
|
rl.question(`-- More (${remaining} lines) [Enter/q] --`, (answer) => {
|
|
83726
83776
|
if (answer.toLowerCase() === "q") {
|
|
83727
83777
|
rl.close();
|
|
83728
83778
|
process.exitCode = 0;
|
|
83729
|
-
|
|
83779
|
+
resolve60();
|
|
83730
83780
|
return;
|
|
83731
83781
|
}
|
|
83732
83782
|
process.stdout.write("\x1B[1A\x1B[2K");
|
|
83733
|
-
|
|
83783
|
+
resolve60();
|
|
83734
83784
|
});
|
|
83735
83785
|
});
|
|
83736
83786
|
}
|
|
@@ -88183,12 +88233,12 @@ async function configUICommand(options2 = {}) {
|
|
|
88183
88233
|
console.log();
|
|
88184
88234
|
console.log(import_picocolors15.default.dim(" Press Ctrl+C to stop"));
|
|
88185
88235
|
console.log();
|
|
88186
|
-
await new Promise((
|
|
88236
|
+
await new Promise((resolve38) => {
|
|
88187
88237
|
const shutdown = async () => {
|
|
88188
88238
|
console.log();
|
|
88189
88239
|
logger.info("Shutting down...");
|
|
88190
88240
|
await server.close();
|
|
88191
|
-
|
|
88241
|
+
resolve38();
|
|
88192
88242
|
};
|
|
88193
88243
|
process.on("SIGINT", shutdown);
|
|
88194
88244
|
process.on("SIGTERM", shutdown);
|
|
@@ -88209,12 +88259,12 @@ async function configUICommand(options2 = {}) {
|
|
|
88209
88259
|
}
|
|
88210
88260
|
async function checkPort(port, host) {
|
|
88211
88261
|
const { createServer: createServer2 } = await import("node:net");
|
|
88212
|
-
return new Promise((
|
|
88262
|
+
return new Promise((resolve38) => {
|
|
88213
88263
|
const server = createServer2();
|
|
88214
|
-
server.once("error", () =>
|
|
88264
|
+
server.once("error", () => resolve38(false));
|
|
88215
88265
|
server.once("listening", () => {
|
|
88216
88266
|
server.close();
|
|
88217
|
-
|
|
88267
|
+
resolve38(true);
|
|
88218
88268
|
});
|
|
88219
88269
|
server.listen(port, host);
|
|
88220
88270
|
});
|
|
@@ -88608,7 +88658,7 @@ init_logger();
|
|
|
88608
88658
|
import { readFileSync as readFileSync17 } from "node:fs";
|
|
88609
88659
|
var MIN_GH_CLI_VERSION = "2.20.0";
|
|
88610
88660
|
var GH_COMMAND_TIMEOUT_MS = 1e4;
|
|
88611
|
-
function
|
|
88661
|
+
function compareVersions7(a3, b3) {
|
|
88612
88662
|
const partsA = a3.split(".").map(Number);
|
|
88613
88663
|
const partsB = b3.split(".").map(Number);
|
|
88614
88664
|
const maxLen = Math.max(partsA.length, partsB.length);
|
|
@@ -88829,7 +88879,7 @@ async function getCommandVersion(command, versionFlag, versionRegex) {
|
|
|
88829
88879
|
return null;
|
|
88830
88880
|
}
|
|
88831
88881
|
}
|
|
88832
|
-
function
|
|
88882
|
+
function compareVersions8(current, required) {
|
|
88833
88883
|
const parseCurrent = current.split(".").map((n) => Number.parseInt(n, 10));
|
|
88834
88884
|
const parseRequired = required.split(".").map((n) => Number.parseInt(n, 10));
|
|
88835
88885
|
for (let i = 0;i < 3; i++) {
|
|
@@ -88853,7 +88903,7 @@ async function checkDependency(config) {
|
|
|
88853
88903
|
let meetsRequirements = true;
|
|
88854
88904
|
let message;
|
|
88855
88905
|
if (config.minVersion && version) {
|
|
88856
|
-
meetsRequirements =
|
|
88906
|
+
meetsRequirements = compareVersions8(version, config.minVersion);
|
|
88857
88907
|
if (!meetsRequirements) {
|
|
88858
88908
|
message = `Version ${version} is below minimum ${config.minVersion}`;
|
|
88859
88909
|
}
|
|
@@ -89248,7 +89298,7 @@ class SystemChecker {
|
|
|
89248
89298
|
const { stdout } = await execAsync6("gh --version");
|
|
89249
89299
|
const match = stdout.match(/(\d+\.\d+\.\d+)/);
|
|
89250
89300
|
const version = match?.[1];
|
|
89251
|
-
if (version &&
|
|
89301
|
+
if (version && compareVersions7(version, MIN_GH_CLI_VERSION) < 0) {
|
|
89252
89302
|
return {
|
|
89253
89303
|
id: "gh-cli-version",
|
|
89254
89304
|
name: "GitHub CLI",
|
|
@@ -89389,7 +89439,7 @@ async function checkCliInstallMethod() {
|
|
|
89389
89439
|
};
|
|
89390
89440
|
}
|
|
89391
89441
|
// src/domains/health-checks/checkers/claude-md-checker.ts
|
|
89392
|
-
import { existsSync as
|
|
89442
|
+
import { existsSync as existsSync53, statSync as statSync11 } from "node:fs";
|
|
89393
89443
|
import { join as join74 } from "node:path";
|
|
89394
89444
|
function checkClaudeMd(setup, projectDir) {
|
|
89395
89445
|
const results = [];
|
|
@@ -89402,7 +89452,7 @@ function checkClaudeMd(setup, projectDir) {
|
|
|
89402
89452
|
return results;
|
|
89403
89453
|
}
|
|
89404
89454
|
function checkClaudeMdFile(path7, name, id) {
|
|
89405
|
-
if (!
|
|
89455
|
+
if (!existsSync53(path7)) {
|
|
89406
89456
|
return {
|
|
89407
89457
|
id,
|
|
89408
89458
|
name,
|
|
@@ -89455,11 +89505,11 @@ function checkClaudeMdFile(path7, name, id) {
|
|
|
89455
89505
|
}
|
|
89456
89506
|
}
|
|
89457
89507
|
// src/domains/health-checks/checkers/active-plan-checker.ts
|
|
89458
|
-
import { existsSync as
|
|
89508
|
+
import { existsSync as existsSync54, readFileSync as readFileSync19 } from "node:fs";
|
|
89459
89509
|
import { join as join75 } from "node:path";
|
|
89460
89510
|
function checkActivePlan(projectDir) {
|
|
89461
89511
|
const activePlanPath = join75(projectDir, ".claude", "active-plan");
|
|
89462
|
-
if (!
|
|
89512
|
+
if (!existsSync54(activePlanPath)) {
|
|
89463
89513
|
return {
|
|
89464
89514
|
id: "ck-active-plan",
|
|
89465
89515
|
name: "Active Plan",
|
|
@@ -89473,7 +89523,7 @@ function checkActivePlan(projectDir) {
|
|
|
89473
89523
|
try {
|
|
89474
89524
|
const targetPath = readFileSync19(activePlanPath, "utf-8").trim();
|
|
89475
89525
|
const fullPath = join75(projectDir, targetPath);
|
|
89476
|
-
if (!
|
|
89526
|
+
if (!existsSync54(fullPath)) {
|
|
89477
89527
|
return {
|
|
89478
89528
|
id: "ck-active-plan",
|
|
89479
89529
|
name: "Active Plan",
|
|
@@ -89509,7 +89559,7 @@ function checkActivePlan(projectDir) {
|
|
|
89509
89559
|
}
|
|
89510
89560
|
}
|
|
89511
89561
|
// src/domains/health-checks/checkers/skills-checker.ts
|
|
89512
|
-
import { existsSync as
|
|
89562
|
+
import { existsSync as existsSync55 } from "node:fs";
|
|
89513
89563
|
import { join as join76 } from "node:path";
|
|
89514
89564
|
function checkSkillsScripts(setup) {
|
|
89515
89565
|
const results = [];
|
|
@@ -89517,7 +89567,7 @@ function checkSkillsScripts(setup) {
|
|
|
89517
89567
|
const scriptName = platform8 === "win32" ? "install.ps1" : "install.sh";
|
|
89518
89568
|
if (setup.global.path) {
|
|
89519
89569
|
const globalScriptPath = join76(setup.global.path, "skills", scriptName);
|
|
89520
|
-
const hasGlobalScript =
|
|
89570
|
+
const hasGlobalScript = existsSync55(globalScriptPath);
|
|
89521
89571
|
results.push({
|
|
89522
89572
|
id: "ck-global-skills-script",
|
|
89523
89573
|
name: "Global Skills Script",
|
|
@@ -89532,7 +89582,7 @@ function checkSkillsScripts(setup) {
|
|
|
89532
89582
|
}
|
|
89533
89583
|
if (setup.project.metadata) {
|
|
89534
89584
|
const projectScriptPath = join76(setup.project.path, "skills", scriptName);
|
|
89535
|
-
const hasProjectScript =
|
|
89585
|
+
const hasProjectScript = existsSync55(projectScriptPath);
|
|
89536
89586
|
results.push({
|
|
89537
89587
|
id: "ck-project-skills-script",
|
|
89538
89588
|
name: "Project Skills Script",
|
|
@@ -89568,16 +89618,16 @@ function checkComponentCounts(setup) {
|
|
|
89568
89618
|
}
|
|
89569
89619
|
// src/domains/health-checks/checkers/skill-budget-checker.ts
|
|
89570
89620
|
init_path_resolver();
|
|
89571
|
-
import { join as join78, resolve as
|
|
89621
|
+
import { join as join78, resolve as resolve38 } from "node:path";
|
|
89572
89622
|
|
|
89573
89623
|
// src/domains/health-checks/checkers/skill-budget-scanner.ts
|
|
89574
89624
|
var import_gray_matter11 = __toESM(require_gray_matter(), 1);
|
|
89575
|
-
import { existsSync as
|
|
89625
|
+
import { existsSync as existsSync56 } from "node:fs";
|
|
89576
89626
|
import { readFile as readFile41, readdir as readdir20 } from "node:fs/promises";
|
|
89577
89627
|
import { basename as basename25, join as join77, relative as relative17 } from "node:path";
|
|
89578
89628
|
var SKIP_DIRS5 = new Set([".git", ".venv", "__pycache__", "node_modules", "scripts", "common"]);
|
|
89579
89629
|
async function scanSkills2(skillsDir2) {
|
|
89580
|
-
if (!
|
|
89630
|
+
if (!existsSync56(skillsDir2))
|
|
89581
89631
|
return [];
|
|
89582
89632
|
const skillDirs = await findSkillDirs(skillsDir2);
|
|
89583
89633
|
const skills = [];
|
|
@@ -89609,7 +89659,7 @@ async function findSkillDirs(dir) {
|
|
|
89609
89659
|
const results = [];
|
|
89610
89660
|
for (const entry of entries) {
|
|
89611
89661
|
const child = join77(dir, entry.name);
|
|
89612
|
-
if (
|
|
89662
|
+
if (existsSync56(join77(child, "SKILL.md"))) {
|
|
89613
89663
|
results.push(child);
|
|
89614
89664
|
continue;
|
|
89615
89665
|
}
|
|
@@ -89627,7 +89677,7 @@ function normalizeSkillId(rawName, fallbackId) {
|
|
|
89627
89677
|
|
|
89628
89678
|
// src/domains/health-checks/checkers/skill-budget-settings.ts
|
|
89629
89679
|
init_settings_merger();
|
|
89630
|
-
import { existsSync as
|
|
89680
|
+
import { existsSync as existsSync57 } from "node:fs";
|
|
89631
89681
|
import { mkdir as mkdir20, readFile as readFile42 } from "node:fs/promises";
|
|
89632
89682
|
var CONTEXT_FLOOR_TOKENS = 200000;
|
|
89633
89683
|
var CHARS_PER_TOKEN = 4;
|
|
@@ -89636,7 +89686,7 @@ var CK_RECOMMENDED_MAX_DESC_CHARS = 512;
|
|
|
89636
89686
|
var RECOMMENDED_DESC_CHARS = 200;
|
|
89637
89687
|
var LISTING_OVERHEAD_PER_SKILL = 4;
|
|
89638
89688
|
async function readProjectSettings(settingsPath) {
|
|
89639
|
-
if (!
|
|
89689
|
+
if (!existsSync57(settingsPath))
|
|
89640
89690
|
return { exists: false, settings: null };
|
|
89641
89691
|
try {
|
|
89642
89692
|
const parsed = JSON.parse(await readFile42(settingsPath, "utf8"));
|
|
@@ -89687,8 +89737,8 @@ async function applyBudgetDefaults(settingsPath, projectClaudeDir, requiredFract
|
|
|
89687
89737
|
// src/domains/health-checks/checkers/skill-budget-checker.ts
|
|
89688
89738
|
var ENGINEER_SKILL_COUNT_THRESHOLD = 20;
|
|
89689
89739
|
async function checkSkillBudget(setup, projectDir) {
|
|
89690
|
-
const projectClaudeDir =
|
|
89691
|
-
const globalClaudeDir =
|
|
89740
|
+
const projectClaudeDir = resolve38(projectDir, ".claude");
|
|
89741
|
+
const globalClaudeDir = resolve38(PathResolver.getGlobalKitDir());
|
|
89692
89742
|
const projectScopeAliasesGlobal = projectClaudeDir === globalClaudeDir;
|
|
89693
89743
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
89694
89744
|
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join78(projectClaudeDir, "skills")),
|
|
@@ -89945,14 +89995,14 @@ async function checkGlobalDirWritable() {
|
|
|
89945
89995
|
}
|
|
89946
89996
|
// src/domains/health-checks/checkers/hooks-checker.ts
|
|
89947
89997
|
init_path_resolver();
|
|
89948
|
-
import { existsSync as
|
|
89998
|
+
import { existsSync as existsSync58 } from "node:fs";
|
|
89949
89999
|
import { readdir as readdir21 } from "node:fs/promises";
|
|
89950
90000
|
import { join as join80 } from "node:path";
|
|
89951
90001
|
|
|
89952
90002
|
// src/domains/health-checks/utils/path-normalizer.ts
|
|
89953
|
-
import { normalize as
|
|
90003
|
+
import { normalize as normalize6 } from "node:path";
|
|
89954
90004
|
function normalizePath2(filePath) {
|
|
89955
|
-
const normalized =
|
|
90005
|
+
const normalized = normalize6(filePath);
|
|
89956
90006
|
const isCaseInsensitive = process.platform === "win32" || process.platform === "darwin";
|
|
89957
90007
|
return isCaseInsensitive ? normalized.toLowerCase() : normalized;
|
|
89958
90008
|
}
|
|
@@ -89962,8 +90012,8 @@ init_shared2();
|
|
|
89962
90012
|
async function checkHooksExist(projectDir) {
|
|
89963
90013
|
const globalHooksDir = join80(PathResolver.getGlobalKitDir(), "hooks");
|
|
89964
90014
|
const projectHooksDir = join80(projectDir, ".claude", "hooks");
|
|
89965
|
-
const globalExists =
|
|
89966
|
-
const projectExists =
|
|
90015
|
+
const globalExists = existsSync58(globalHooksDir);
|
|
90016
|
+
const projectExists = existsSync58(projectHooksDir);
|
|
89967
90017
|
let hookCount = 0;
|
|
89968
90018
|
const checkedFiles = new Set;
|
|
89969
90019
|
if (globalExists) {
|
|
@@ -90010,13 +90060,13 @@ async function checkHooksExist(projectDir) {
|
|
|
90010
90060
|
// src/domains/health-checks/checkers/settings-checker.ts
|
|
90011
90061
|
init_logger();
|
|
90012
90062
|
init_path_resolver();
|
|
90013
|
-
import { existsSync as
|
|
90063
|
+
import { existsSync as existsSync59 } from "node:fs";
|
|
90014
90064
|
import { readFile as readFile43 } from "node:fs/promises";
|
|
90015
90065
|
import { join as join81 } from "node:path";
|
|
90016
90066
|
async function checkSettingsValid(projectDir) {
|
|
90017
90067
|
const globalSettings = join81(PathResolver.getGlobalKitDir(), "settings.json");
|
|
90018
90068
|
const projectSettings = join81(projectDir, ".claude", "settings.json");
|
|
90019
|
-
const settingsPath =
|
|
90069
|
+
const settingsPath = existsSync59(globalSettings) ? globalSettings : existsSync59(projectSettings) ? projectSettings : null;
|
|
90020
90070
|
if (!settingsPath) {
|
|
90021
90071
|
return {
|
|
90022
90072
|
id: "ck-settings-valid",
|
|
@@ -90085,14 +90135,14 @@ async function checkSettingsValid(projectDir) {
|
|
|
90085
90135
|
// src/domains/health-checks/checkers/path-refs-checker.ts
|
|
90086
90136
|
init_logger();
|
|
90087
90137
|
init_path_resolver();
|
|
90088
|
-
import { existsSync as
|
|
90138
|
+
import { existsSync as existsSync60 } from "node:fs";
|
|
90089
90139
|
import { readFile as readFile44 } from "node:fs/promises";
|
|
90090
90140
|
import { homedir as homedir43 } from "node:os";
|
|
90091
|
-
import { dirname as dirname32, join as join82, normalize as
|
|
90141
|
+
import { dirname as dirname32, join as join82, normalize as normalize7, resolve as resolve39 } from "node:path";
|
|
90092
90142
|
async function checkPathRefsValid(projectDir) {
|
|
90093
90143
|
const globalClaudeMd = join82(PathResolver.getGlobalKitDir(), "CLAUDE.md");
|
|
90094
90144
|
const projectClaudeMd = join82(projectDir, ".claude", "CLAUDE.md");
|
|
90095
|
-
const claudeMdPath =
|
|
90145
|
+
const claudeMdPath = existsSync60(globalClaudeMd) ? globalClaudeMd : existsSync60(projectClaudeMd) ? projectClaudeMd : null;
|
|
90096
90146
|
if (!claudeMdPath) {
|
|
90097
90147
|
return {
|
|
90098
90148
|
id: "ck-path-refs-valid",
|
|
@@ -90125,27 +90175,27 @@ async function checkPathRefsValid(projectDir) {
|
|
|
90125
90175
|
for (const ref of refs) {
|
|
90126
90176
|
let refPath;
|
|
90127
90177
|
if (ref.startsWith("$HOME") || ref.startsWith("${HOME}") || ref.startsWith("%USERPROFILE%")) {
|
|
90128
|
-
refPath =
|
|
90178
|
+
refPath = normalize7(ref.replace(/^\$\{?HOME\}?/, home5).replace("%USERPROFILE%", home5));
|
|
90129
90179
|
} else if (ref.startsWith("$CLAUDE_PROJECT_DIR") || ref.startsWith("${CLAUDE_PROJECT_DIR}") || ref.startsWith("%CLAUDE_PROJECT_DIR%")) {
|
|
90130
|
-
refPath =
|
|
90180
|
+
refPath = normalize7(ref.replace(/^\$\{?CLAUDE_PROJECT_DIR\}?/, projectDir).replace("%CLAUDE_PROJECT_DIR%", projectDir));
|
|
90131
90181
|
} else if (ref.startsWith("~")) {
|
|
90132
|
-
refPath =
|
|
90182
|
+
refPath = normalize7(ref.replace(/^~/, home5));
|
|
90133
90183
|
} else if (ref.startsWith("/")) {
|
|
90134
|
-
refPath =
|
|
90184
|
+
refPath = normalize7(ref);
|
|
90135
90185
|
} else if (/^[A-Za-z]:/.test(ref)) {
|
|
90136
|
-
refPath =
|
|
90186
|
+
refPath = normalize7(ref);
|
|
90137
90187
|
} else {
|
|
90138
|
-
refPath =
|
|
90188
|
+
refPath = resolve39(baseDir, ref);
|
|
90139
90189
|
}
|
|
90140
|
-
const normalizedPath =
|
|
90190
|
+
const normalizedPath = normalize7(refPath);
|
|
90141
90191
|
const isWithinHome = normalizedPath.startsWith(home5);
|
|
90142
|
-
const isWithinBase2 = normalizedPath.startsWith(
|
|
90192
|
+
const isWithinBase2 = normalizedPath.startsWith(normalize7(baseDir));
|
|
90143
90193
|
const isAbsoluteAllowed = ref.startsWith("/") || /^[A-Za-z]:/.test(ref);
|
|
90144
90194
|
if (!isWithinHome && !isWithinBase2 && !isAbsoluteAllowed) {
|
|
90145
90195
|
logger.verbose("Skipping potentially unsafe path reference", { ref, refPath });
|
|
90146
90196
|
continue;
|
|
90147
90197
|
}
|
|
90148
|
-
if (!
|
|
90198
|
+
if (!existsSync60(normalizedPath)) {
|
|
90149
90199
|
broken.push(ref);
|
|
90150
90200
|
}
|
|
90151
90201
|
}
|
|
@@ -90184,7 +90234,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
90184
90234
|
}
|
|
90185
90235
|
}
|
|
90186
90236
|
// src/domains/health-checks/checkers/config-completeness-checker.ts
|
|
90187
|
-
import { existsSync as
|
|
90237
|
+
import { existsSync as existsSync61 } from "node:fs";
|
|
90188
90238
|
import { readdir as readdir22 } from "node:fs/promises";
|
|
90189
90239
|
import { join as join83 } from "node:path";
|
|
90190
90240
|
async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
@@ -90224,11 +90274,11 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
90224
90274
|
const requiredDirs = ["agents", "commands", "skills"];
|
|
90225
90275
|
const missingDirs = [];
|
|
90226
90276
|
for (const dir of requiredDirs) {
|
|
90227
|
-
if (!
|
|
90277
|
+
if (!existsSync61(join83(projectClaudeDir, dir))) {
|
|
90228
90278
|
missingDirs.push(dir);
|
|
90229
90279
|
}
|
|
90230
90280
|
}
|
|
90231
|
-
const hasRulesOrWorkflows =
|
|
90281
|
+
const hasRulesOrWorkflows = existsSync61(join83(projectClaudeDir, "rules")) || existsSync61(join83(projectClaudeDir, "workflows"));
|
|
90232
90282
|
if (!hasRulesOrWorkflows) {
|
|
90233
90283
|
missingDirs.push("rules");
|
|
90234
90284
|
}
|
|
@@ -91260,7 +91310,7 @@ init_environment();
|
|
|
91260
91310
|
init_path_resolver();
|
|
91261
91311
|
import { constants as constants3, access as access4, mkdir as mkdir21, readFile as readFile46, unlink as unlink11, writeFile as writeFile23 } from "node:fs/promises";
|
|
91262
91312
|
import { arch as arch2, homedir as homedir44, platform as platform8 } from "node:os";
|
|
91263
|
-
import { join as join88, normalize as
|
|
91313
|
+
import { join as join88, normalize as normalize8 } from "node:path";
|
|
91264
91314
|
function shouldSkipExpensiveOperations4() {
|
|
91265
91315
|
return shouldSkipExpensiveOperations();
|
|
91266
91316
|
}
|
|
@@ -91282,9 +91332,9 @@ async function checkPlatformDetect() {
|
|
|
91282
91332
|
};
|
|
91283
91333
|
}
|
|
91284
91334
|
async function checkHomeDirResolution() {
|
|
91285
|
-
const nodeHome =
|
|
91335
|
+
const nodeHome = normalize8(homedir44());
|
|
91286
91336
|
const rawEnvHome = getHomeDirectoryFromEnv(platform8());
|
|
91287
|
-
const envHome = rawEnvHome ?
|
|
91337
|
+
const envHome = rawEnvHome ? normalize8(rawEnvHome) : "";
|
|
91288
91338
|
const match = nodeHome === envHome && envHome !== "";
|
|
91289
91339
|
return {
|
|
91290
91340
|
id: "home-dir-resolution",
|
|
@@ -91732,17 +91782,17 @@ function createDefaultDns() {
|
|
|
91732
91782
|
}
|
|
91733
91783
|
function createDefaultTcp() {
|
|
91734
91784
|
return {
|
|
91735
|
-
connect: ({ host, port, timeoutMs }) => new Promise((
|
|
91785
|
+
connect: ({ host, port, timeoutMs }) => new Promise((resolve40) => {
|
|
91736
91786
|
const start = Date.now();
|
|
91737
91787
|
const socket = net2.createConnection({ host, port });
|
|
91738
91788
|
const timer = setTimeout(() => {
|
|
91739
91789
|
socket.destroy();
|
|
91740
|
-
|
|
91790
|
+
resolve40({ ok: false, layer: "tcp", detail: "timeout", latencyMs: Date.now() - start });
|
|
91741
91791
|
}, timeoutMs);
|
|
91742
91792
|
socket.on("connect", () => {
|
|
91743
91793
|
clearTimeout(timer);
|
|
91744
91794
|
socket.destroy();
|
|
91745
|
-
|
|
91795
|
+
resolve40({
|
|
91746
91796
|
ok: true,
|
|
91747
91797
|
layer: "tcp",
|
|
91748
91798
|
detail: "connected",
|
|
@@ -91751,7 +91801,7 @@ function createDefaultTcp() {
|
|
|
91751
91801
|
});
|
|
91752
91802
|
socket.on("error", (err) => {
|
|
91753
91803
|
clearTimeout(timer);
|
|
91754
|
-
|
|
91804
|
+
resolve40({
|
|
91755
91805
|
ok: false,
|
|
91756
91806
|
layer: "tcp",
|
|
91757
91807
|
detail: err.message,
|
|
@@ -91763,11 +91813,11 @@ function createDefaultTcp() {
|
|
|
91763
91813
|
}
|
|
91764
91814
|
function createDefaultTls() {
|
|
91765
91815
|
return {
|
|
91766
|
-
get: (url, timeoutMs) => new Promise((
|
|
91816
|
+
get: (url, timeoutMs) => new Promise((resolve40) => {
|
|
91767
91817
|
const start = Date.now();
|
|
91768
91818
|
const timer = setTimeout(() => {
|
|
91769
91819
|
req.destroy();
|
|
91770
|
-
|
|
91820
|
+
resolve40({ ok: false, layer: "tls", detail: "timeout", latencyMs: Date.now() - start });
|
|
91771
91821
|
}, timeoutMs);
|
|
91772
91822
|
const req = https.get(url, {
|
|
91773
91823
|
headers: {
|
|
@@ -91779,14 +91829,14 @@ function createDefaultTls() {
|
|
|
91779
91829
|
const status = res.statusCode ?? 0;
|
|
91780
91830
|
const latencyMs = Date.now() - start;
|
|
91781
91831
|
if (status === 200) {
|
|
91782
|
-
|
|
91832
|
+
resolve40({ ok: true, layer: "tls", detail: `HTTP ${status}`, latencyMs });
|
|
91783
91833
|
} else {
|
|
91784
|
-
|
|
91834
|
+
resolve40({ ok: false, layer: "tls", detail: `HTTP ${status}`, latencyMs });
|
|
91785
91835
|
}
|
|
91786
91836
|
});
|
|
91787
91837
|
req.on("error", (err) => {
|
|
91788
91838
|
clearTimeout(timer);
|
|
91789
|
-
|
|
91839
|
+
resolve40({
|
|
91790
91840
|
ok: false,
|
|
91791
91841
|
layer: "tls",
|
|
91792
91842
|
detail: err.message,
|
|
@@ -91907,7 +91957,7 @@ async function checkGitHubReachability(deps) {
|
|
|
91907
91957
|
};
|
|
91908
91958
|
}
|
|
91909
91959
|
function raceTimeout(promise, ms) {
|
|
91910
|
-
return new Promise((
|
|
91960
|
+
return new Promise((resolve40, reject) => {
|
|
91911
91961
|
let settled = false;
|
|
91912
91962
|
const timer = setTimeout(() => {
|
|
91913
91963
|
setImmediate(() => {
|
|
@@ -91922,7 +91972,7 @@ function raceTimeout(promise, ms) {
|
|
|
91922
91972
|
return;
|
|
91923
91973
|
settled = true;
|
|
91924
91974
|
clearTimeout(timer);
|
|
91925
|
-
|
|
91975
|
+
resolve40(v2);
|
|
91926
91976
|
}, (e2) => {
|
|
91927
91977
|
if (settled)
|
|
91928
91978
|
return;
|
|
@@ -92590,7 +92640,7 @@ init_config_version_checker();
|
|
|
92590
92640
|
|
|
92591
92641
|
// src/domains/sync/sync-engine.ts
|
|
92592
92642
|
import { lstat as lstat6, readFile as readFile48, readlink as readlink2, realpath as realpath8, stat as stat14 } from "node:fs/promises";
|
|
92593
|
-
import { isAbsolute as isAbsolute12, join as join91, normalize as
|
|
92643
|
+
import { isAbsolute as isAbsolute12, join as join91, normalize as normalize9, relative as relative19 } from "node:path";
|
|
92594
92644
|
|
|
92595
92645
|
// src/services/file-operations/ownership-checker.ts
|
|
92596
92646
|
init_metadata_migration();
|
|
@@ -93806,7 +93856,7 @@ async function validateSymlinkChain(path8, basePath, maxDepth = MAX_SYMLINK_DEPT
|
|
|
93806
93856
|
break;
|
|
93807
93857
|
const target = await readlink2(current);
|
|
93808
93858
|
const resolvedTarget = isAbsolute12(target) ? target : join91(current, "..", target);
|
|
93809
|
-
const normalizedTarget =
|
|
93859
|
+
const normalizedTarget = normalize9(resolvedTarget);
|
|
93810
93860
|
const rel = relative19(basePath, normalizedTarget);
|
|
93811
93861
|
if (rel.startsWith("..") || isAbsolute12(rel)) {
|
|
93812
93862
|
throw new Error(`Symlink chain escapes base directory at depth ${depth}: ${path8}`);
|
|
@@ -93834,7 +93884,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
93834
93884
|
if (filePath.length > 1024) {
|
|
93835
93885
|
throw new Error(`Path too long: ${filePath.slice(0, 50)}...`);
|
|
93836
93886
|
}
|
|
93837
|
-
const normalized =
|
|
93887
|
+
const normalized = normalize9(filePath);
|
|
93838
93888
|
if (isAbsolute12(normalized)) {
|
|
93839
93889
|
throw new Error(`Absolute paths not allowed: ${filePath}`);
|
|
93840
93890
|
}
|
|
@@ -95388,21 +95438,21 @@ init_types3();
|
|
|
95388
95438
|
|
|
95389
95439
|
// src/domains/installation/utils/path-security.ts
|
|
95390
95440
|
init_types3();
|
|
95391
|
-
import { lstatSync as lstatSync2, realpathSync as
|
|
95392
|
-
import { relative as relative20, resolve as
|
|
95441
|
+
import { lstatSync as lstatSync2, realpathSync as realpathSync5 } from "node:fs";
|
|
95442
|
+
import { relative as relative20, resolve as resolve42 } from "node:path";
|
|
95393
95443
|
var MAX_EXTRACTION_SIZE = 500 * 1024 * 1024;
|
|
95394
95444
|
function isPathSafe(basePath, targetPath) {
|
|
95395
|
-
const resolvedBase =
|
|
95445
|
+
const resolvedBase = resolve42(basePath);
|
|
95396
95446
|
try {
|
|
95397
95447
|
const stat15 = lstatSync2(targetPath);
|
|
95398
95448
|
if (stat15.isSymbolicLink()) {
|
|
95399
|
-
const realTarget =
|
|
95449
|
+
const realTarget = realpathSync5(targetPath);
|
|
95400
95450
|
if (!realTarget.startsWith(resolvedBase)) {
|
|
95401
95451
|
return false;
|
|
95402
95452
|
}
|
|
95403
95453
|
}
|
|
95404
95454
|
} catch {}
|
|
95405
|
-
const resolvedTarget =
|
|
95455
|
+
const resolvedTarget = resolve42(targetPath);
|
|
95406
95456
|
const relativePath = relative20(resolvedBase, resolvedTarget);
|
|
95407
95457
|
return !relativePath.startsWith("..") && !relativePath.startsWith("/") && resolvedTarget.startsWith(resolvedBase);
|
|
95408
95458
|
}
|
|
@@ -95490,7 +95540,7 @@ class FileDownloader {
|
|
|
95490
95540
|
}
|
|
95491
95541
|
if (downloadedSize !== totalSize) {
|
|
95492
95542
|
fileStream.end();
|
|
95493
|
-
await new Promise((
|
|
95543
|
+
await new Promise((resolve43) => fileStream.once("close", resolve43));
|
|
95494
95544
|
try {
|
|
95495
95545
|
rmSync(destPath, { force: true });
|
|
95496
95546
|
} catch (cleanupError) {
|
|
@@ -95504,7 +95554,7 @@ class FileDownloader {
|
|
|
95504
95554
|
return destPath;
|
|
95505
95555
|
} catch (error) {
|
|
95506
95556
|
fileStream.end();
|
|
95507
|
-
await new Promise((
|
|
95557
|
+
await new Promise((resolve43) => fileStream.once("close", resolve43));
|
|
95508
95558
|
try {
|
|
95509
95559
|
rmSync(destPath, { force: true });
|
|
95510
95560
|
} catch (cleanupError) {
|
|
@@ -95570,7 +95620,7 @@ class FileDownloader {
|
|
|
95570
95620
|
const expectedSize = Number(response.headers.get("content-length"));
|
|
95571
95621
|
if (expectedSize > 0 && downloadedSize !== expectedSize) {
|
|
95572
95622
|
fileStream.end();
|
|
95573
|
-
await new Promise((
|
|
95623
|
+
await new Promise((resolve43) => fileStream.once("close", resolve43));
|
|
95574
95624
|
try {
|
|
95575
95625
|
rmSync(destPath, { force: true });
|
|
95576
95626
|
} catch (cleanupError) {
|
|
@@ -95588,7 +95638,7 @@ class FileDownloader {
|
|
|
95588
95638
|
return destPath;
|
|
95589
95639
|
} catch (error) {
|
|
95590
95640
|
fileStream.end();
|
|
95591
|
-
await new Promise((
|
|
95641
|
+
await new Promise((resolve43) => fileStream.once("close", resolve43));
|
|
95592
95642
|
try {
|
|
95593
95643
|
rmSync(destPath, { force: true });
|
|
95594
95644
|
} catch (cleanupError) {
|
|
@@ -96207,10 +96257,10 @@ class Minipass extends EventEmitter3 {
|
|
|
96207
96257
|
return this[ENCODING] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
96208
96258
|
}
|
|
96209
96259
|
async promise() {
|
|
96210
|
-
return new Promise((
|
|
96260
|
+
return new Promise((resolve43, reject) => {
|
|
96211
96261
|
this.on(DESTROYED, () => reject(new Error("stream destroyed")));
|
|
96212
96262
|
this.on("error", (er) => reject(er));
|
|
96213
|
-
this.on("end", () =>
|
|
96263
|
+
this.on("end", () => resolve43());
|
|
96214
96264
|
});
|
|
96215
96265
|
}
|
|
96216
96266
|
[Symbol.asyncIterator]() {
|
|
@@ -96229,7 +96279,7 @@ class Minipass extends EventEmitter3 {
|
|
|
96229
96279
|
return Promise.resolve({ done: false, value: res });
|
|
96230
96280
|
if (this[EOF])
|
|
96231
96281
|
return stop();
|
|
96232
|
-
let
|
|
96282
|
+
let resolve43;
|
|
96233
96283
|
let reject;
|
|
96234
96284
|
const onerr = (er) => {
|
|
96235
96285
|
this.off("data", ondata);
|
|
@@ -96243,19 +96293,19 @@ class Minipass extends EventEmitter3 {
|
|
|
96243
96293
|
this.off("end", onend);
|
|
96244
96294
|
this.off(DESTROYED, ondestroy);
|
|
96245
96295
|
this.pause();
|
|
96246
|
-
|
|
96296
|
+
resolve43({ value, done: !!this[EOF] });
|
|
96247
96297
|
};
|
|
96248
96298
|
const onend = () => {
|
|
96249
96299
|
this.off("error", onerr);
|
|
96250
96300
|
this.off("data", ondata);
|
|
96251
96301
|
this.off(DESTROYED, ondestroy);
|
|
96252
96302
|
stop();
|
|
96253
|
-
|
|
96303
|
+
resolve43({ done: true, value: undefined });
|
|
96254
96304
|
};
|
|
96255
96305
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
96256
96306
|
return new Promise((res2, rej) => {
|
|
96257
96307
|
reject = rej;
|
|
96258
|
-
|
|
96308
|
+
resolve43 = res2;
|
|
96259
96309
|
this.once(DESTROYED, ondestroy);
|
|
96260
96310
|
this.once("error", onerr);
|
|
96261
96311
|
this.once("end", onend);
|
|
@@ -97361,10 +97411,10 @@ class Minipass2 extends EventEmitter4 {
|
|
|
97361
97411
|
return this[ENCODING2] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
97362
97412
|
}
|
|
97363
97413
|
async promise() {
|
|
97364
|
-
return new Promise((
|
|
97414
|
+
return new Promise((resolve43, reject) => {
|
|
97365
97415
|
this.on(DESTROYED2, () => reject(new Error("stream destroyed")));
|
|
97366
97416
|
this.on("error", (er) => reject(er));
|
|
97367
|
-
this.on("end", () =>
|
|
97417
|
+
this.on("end", () => resolve43());
|
|
97368
97418
|
});
|
|
97369
97419
|
}
|
|
97370
97420
|
[Symbol.asyncIterator]() {
|
|
@@ -97383,7 +97433,7 @@ class Minipass2 extends EventEmitter4 {
|
|
|
97383
97433
|
return Promise.resolve({ done: false, value: res });
|
|
97384
97434
|
if (this[EOF2])
|
|
97385
97435
|
return stop();
|
|
97386
|
-
let
|
|
97436
|
+
let resolve43;
|
|
97387
97437
|
let reject;
|
|
97388
97438
|
const onerr = (er) => {
|
|
97389
97439
|
this.off("data", ondata);
|
|
@@ -97397,19 +97447,19 @@ class Minipass2 extends EventEmitter4 {
|
|
|
97397
97447
|
this.off("end", onend);
|
|
97398
97448
|
this.off(DESTROYED2, ondestroy);
|
|
97399
97449
|
this.pause();
|
|
97400
|
-
|
|
97450
|
+
resolve43({ value, done: !!this[EOF2] });
|
|
97401
97451
|
};
|
|
97402
97452
|
const onend = () => {
|
|
97403
97453
|
this.off("error", onerr);
|
|
97404
97454
|
this.off("data", ondata);
|
|
97405
97455
|
this.off(DESTROYED2, ondestroy);
|
|
97406
97456
|
stop();
|
|
97407
|
-
|
|
97457
|
+
resolve43({ done: true, value: undefined });
|
|
97408
97458
|
};
|
|
97409
97459
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
97410
97460
|
return new Promise((res2, rej) => {
|
|
97411
97461
|
reject = rej;
|
|
97412
|
-
|
|
97462
|
+
resolve43 = res2;
|
|
97413
97463
|
this.once(DESTROYED2, ondestroy);
|
|
97414
97464
|
this.once("error", onerr);
|
|
97415
97465
|
this.once("end", onend);
|
|
@@ -98837,10 +98887,10 @@ class Minipass3 extends EventEmitter5 {
|
|
|
98837
98887
|
return this[ENCODING3] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
98838
98888
|
}
|
|
98839
98889
|
async promise() {
|
|
98840
|
-
return new Promise((
|
|
98890
|
+
return new Promise((resolve43, reject) => {
|
|
98841
98891
|
this.on(DESTROYED3, () => reject(new Error("stream destroyed")));
|
|
98842
98892
|
this.on("error", (er) => reject(er));
|
|
98843
|
-
this.on("end", () =>
|
|
98893
|
+
this.on("end", () => resolve43());
|
|
98844
98894
|
});
|
|
98845
98895
|
}
|
|
98846
98896
|
[Symbol.asyncIterator]() {
|
|
@@ -98859,7 +98909,7 @@ class Minipass3 extends EventEmitter5 {
|
|
|
98859
98909
|
return Promise.resolve({ done: false, value: res });
|
|
98860
98910
|
if (this[EOF3])
|
|
98861
98911
|
return stop();
|
|
98862
|
-
let
|
|
98912
|
+
let resolve43;
|
|
98863
98913
|
let reject;
|
|
98864
98914
|
const onerr = (er) => {
|
|
98865
98915
|
this.off("data", ondata);
|
|
@@ -98873,19 +98923,19 @@ class Minipass3 extends EventEmitter5 {
|
|
|
98873
98923
|
this.off("end", onend);
|
|
98874
98924
|
this.off(DESTROYED3, ondestroy);
|
|
98875
98925
|
this.pause();
|
|
98876
|
-
|
|
98926
|
+
resolve43({ value, done: !!this[EOF3] });
|
|
98877
98927
|
};
|
|
98878
98928
|
const onend = () => {
|
|
98879
98929
|
this.off("error", onerr);
|
|
98880
98930
|
this.off("data", ondata);
|
|
98881
98931
|
this.off(DESTROYED3, ondestroy);
|
|
98882
98932
|
stop();
|
|
98883
|
-
|
|
98933
|
+
resolve43({ done: true, value: undefined });
|
|
98884
98934
|
};
|
|
98885
98935
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
98886
98936
|
return new Promise((res2, rej) => {
|
|
98887
98937
|
reject = rej;
|
|
98888
|
-
|
|
98938
|
+
resolve43 = res2;
|
|
98889
98939
|
this.once(DESTROYED3, ondestroy);
|
|
98890
98940
|
this.once("error", onerr);
|
|
98891
98941
|
this.once("end", onend);
|
|
@@ -99656,9 +99706,9 @@ var listFile = (opt, _files) => {
|
|
|
99656
99706
|
const parse5 = new Parser(opt);
|
|
99657
99707
|
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
|
|
99658
99708
|
const file = opt.file;
|
|
99659
|
-
const p = new Promise((
|
|
99709
|
+
const p = new Promise((resolve43, reject) => {
|
|
99660
99710
|
parse5.on("error", reject);
|
|
99661
|
-
parse5.on("end",
|
|
99711
|
+
parse5.on("end", resolve43);
|
|
99662
99712
|
fs10.stat(file, (er, stat15) => {
|
|
99663
99713
|
if (er) {
|
|
99664
99714
|
reject(er);
|
|
@@ -102238,9 +102288,9 @@ var extractFile = (opt, _3) => {
|
|
|
102238
102288
|
const u = new Unpack(opt);
|
|
102239
102289
|
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
|
|
102240
102290
|
const file = opt.file;
|
|
102241
|
-
const p = new Promise((
|
|
102291
|
+
const p = new Promise((resolve43, reject) => {
|
|
102242
102292
|
u.on("error", reject);
|
|
102243
|
-
u.on("close",
|
|
102293
|
+
u.on("close", resolve43);
|
|
102244
102294
|
fs17.stat(file, (er, stat15) => {
|
|
102245
102295
|
if (er) {
|
|
102246
102296
|
reject(er);
|
|
@@ -102373,7 +102423,7 @@ var replaceAsync = (opt, files) => {
|
|
|
102373
102423
|
};
|
|
102374
102424
|
fs18.read(fd, headBuf, 0, 512, position, onread);
|
|
102375
102425
|
};
|
|
102376
|
-
const promise = new Promise((
|
|
102426
|
+
const promise = new Promise((resolve43, reject) => {
|
|
102377
102427
|
p.on("error", reject);
|
|
102378
102428
|
let flag = "r+";
|
|
102379
102429
|
const onopen = (er, fd) => {
|
|
@@ -102398,7 +102448,7 @@ var replaceAsync = (opt, files) => {
|
|
|
102398
102448
|
});
|
|
102399
102449
|
p.pipe(stream);
|
|
102400
102450
|
stream.on("error", reject);
|
|
102401
|
-
stream.on("close",
|
|
102451
|
+
stream.on("close", resolve43);
|
|
102402
102452
|
addFilesAsync2(p, files);
|
|
102403
102453
|
});
|
|
102404
102454
|
});
|
|
@@ -103354,8 +103404,8 @@ async function handleDownload(ctx) {
|
|
|
103354
103404
|
import { join as join125 } from "node:path";
|
|
103355
103405
|
|
|
103356
103406
|
// src/domains/installation/deletion-handler.ts
|
|
103357
|
-
import { existsSync as
|
|
103358
|
-
import { dirname as dirname38, join as join110, relative as relative22, resolve as
|
|
103407
|
+
import { existsSync as existsSync67, lstatSync as lstatSync3, readdirSync as readdirSync10, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync4 } from "node:fs";
|
|
103408
|
+
import { dirname as dirname38, join as join110, relative as relative22, resolve as resolve44, sep as sep12 } from "node:path";
|
|
103359
103409
|
|
|
103360
103410
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
103361
103411
|
init_metadata_migration();
|
|
@@ -103545,7 +103595,7 @@ function shouldDeletePath(path16, metadata, kitType) {
|
|
|
103545
103595
|
}
|
|
103546
103596
|
function collectFilesRecursively(dir, baseDir) {
|
|
103547
103597
|
const results = [];
|
|
103548
|
-
if (!
|
|
103598
|
+
if (!existsSync67(dir))
|
|
103549
103599
|
return results;
|
|
103550
103600
|
try {
|
|
103551
103601
|
const entries = readdirSync10(dir, { withFileTypes: true });
|
|
@@ -103580,8 +103630,8 @@ function expandGlobPatterns(patterns, claudeDir3) {
|
|
|
103580
103630
|
}
|
|
103581
103631
|
var MAX_CLEANUP_ITERATIONS = 50;
|
|
103582
103632
|
function cleanupEmptyDirectories(filePath, claudeDir3) {
|
|
103583
|
-
const normalizedClaudeDir =
|
|
103584
|
-
let currentDir =
|
|
103633
|
+
const normalizedClaudeDir = resolve44(claudeDir3);
|
|
103634
|
+
let currentDir = resolve44(dirname38(filePath));
|
|
103585
103635
|
let iterations = 0;
|
|
103586
103636
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir) && iterations < MAX_CLEANUP_ITERATIONS) {
|
|
103587
103637
|
iterations++;
|
|
@@ -103590,7 +103640,7 @@ function cleanupEmptyDirectories(filePath, claudeDir3) {
|
|
|
103590
103640
|
if (entries.length === 0) {
|
|
103591
103641
|
rmdirSync(currentDir);
|
|
103592
103642
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
103593
|
-
currentDir =
|
|
103643
|
+
currentDir = resolve44(dirname38(currentDir));
|
|
103594
103644
|
} else {
|
|
103595
103645
|
break;
|
|
103596
103646
|
}
|
|
@@ -103600,8 +103650,8 @@ function cleanupEmptyDirectories(filePath, claudeDir3) {
|
|
|
103600
103650
|
}
|
|
103601
103651
|
}
|
|
103602
103652
|
function deletePath(fullPath, claudeDir3) {
|
|
103603
|
-
const normalizedPath =
|
|
103604
|
-
const normalizedClaudeDir =
|
|
103653
|
+
const normalizedPath = resolve44(fullPath);
|
|
103654
|
+
const normalizedClaudeDir = resolve44(claudeDir3);
|
|
103605
103655
|
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep12}`) && normalizedPath !== normalizedClaudeDir) {
|
|
103606
103656
|
throw new Error(`Path traversal detected: ${fullPath}`);
|
|
103607
103657
|
}
|
|
@@ -103674,8 +103724,8 @@ async function handleDeletions(sourceMetadata, claudeDir3, kitType) {
|
|
|
103674
103724
|
const result = { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
103675
103725
|
for (const path16 of deletions) {
|
|
103676
103726
|
const fullPath = join110(claudeDir3, path16);
|
|
103677
|
-
const normalizedPath =
|
|
103678
|
-
const normalizedClaudeDir =
|
|
103727
|
+
const normalizedPath = resolve44(fullPath);
|
|
103728
|
+
const normalizedClaudeDir = resolve44(claudeDir3);
|
|
103679
103729
|
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep12}`)) {
|
|
103680
103730
|
logger.warning(`Skipping invalid path: ${path16}`);
|
|
103681
103731
|
result.errors.push(path16);
|
|
@@ -103686,7 +103736,7 @@ async function handleDeletions(sourceMetadata, claudeDir3, kitType) {
|
|
|
103686
103736
|
logger.verbose(`Preserved user file: ${path16}`);
|
|
103687
103737
|
continue;
|
|
103688
103738
|
}
|
|
103689
|
-
if (
|
|
103739
|
+
if (existsSync67(fullPath)) {
|
|
103690
103740
|
try {
|
|
103691
103741
|
deletePath(fullPath, claudeDir3);
|
|
103692
103742
|
result.deletedPaths.push(path16);
|
|
@@ -105463,7 +105513,7 @@ import { dirname as dirname41, join as join114 } from "node:path";
|
|
|
105463
105513
|
|
|
105464
105514
|
// src/domains/config/installed-settings-tracker.ts
|
|
105465
105515
|
init_shared();
|
|
105466
|
-
import { existsSync as
|
|
105516
|
+
import { existsSync as existsSync68 } from "node:fs";
|
|
105467
105517
|
import { mkdir as mkdir31, readFile as readFile52, writeFile as writeFile27 } from "node:fs/promises";
|
|
105468
105518
|
import { dirname as dirname40, join as join113 } from "node:path";
|
|
105469
105519
|
var CK_JSON_FILE = ".ck.json";
|
|
@@ -105485,7 +105535,7 @@ class InstalledSettingsTracker {
|
|
|
105485
105535
|
}
|
|
105486
105536
|
async loadInstalledSettings() {
|
|
105487
105537
|
const ckJsonPath = this.getCkJsonPath();
|
|
105488
|
-
if (!
|
|
105538
|
+
if (!existsSync68(ckJsonPath)) {
|
|
105489
105539
|
return { hooks: [], mcpServers: [] };
|
|
105490
105540
|
}
|
|
105491
105541
|
try {
|
|
@@ -105505,7 +105555,7 @@ class InstalledSettingsTracker {
|
|
|
105505
105555
|
const ckJsonPath = this.getCkJsonPath();
|
|
105506
105556
|
try {
|
|
105507
105557
|
let data = {};
|
|
105508
|
-
if (
|
|
105558
|
+
if (existsSync68(ckJsonPath)) {
|
|
105509
105559
|
const content = await readFile52(ckJsonPath, "utf-8");
|
|
105510
105560
|
data = parseJsonContent(content);
|
|
105511
105561
|
}
|
|
@@ -107319,7 +107369,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
|
|
|
107319
107369
|
init_logger();
|
|
107320
107370
|
init_skip_directories();
|
|
107321
107371
|
var import_fs_extra20 = __toESM(require_lib(), 1);
|
|
107322
|
-
import { join as join120, relative as relative27, resolve as
|
|
107372
|
+
import { join as join120, relative as relative27, resolve as resolve45 } from "node:path";
|
|
107323
107373
|
|
|
107324
107374
|
class FileScanner2 {
|
|
107325
107375
|
static async getFiles(dirPath, relativeTo) {
|
|
@@ -107399,8 +107449,8 @@ class FileScanner2 {
|
|
|
107399
107449
|
return customFiles;
|
|
107400
107450
|
}
|
|
107401
107451
|
static isSafePath(basePath, targetPath) {
|
|
107402
|
-
const resolvedBase =
|
|
107403
|
-
const resolvedTarget =
|
|
107452
|
+
const resolvedBase = resolve45(basePath);
|
|
107453
|
+
const resolvedTarget = resolve45(targetPath);
|
|
107404
107454
|
return resolvedTarget.startsWith(resolvedBase);
|
|
107405
107455
|
}
|
|
107406
107456
|
static toPosixPath(path17) {
|
|
@@ -108730,13 +108780,13 @@ init_logger();
|
|
|
108730
108780
|
init_types3();
|
|
108731
108781
|
var import_fs_extra29 = __toESM(require_lib(), 1);
|
|
108732
108782
|
import { copyFile as copyFile7, mkdir as mkdir34, readdir as readdir37, rm as rm14, stat as stat21 } from "node:fs/promises";
|
|
108733
|
-
import { basename as basename27, join as join129, normalize as
|
|
108783
|
+
import { basename as basename27, join as join129, normalize as normalize10 } from "node:path";
|
|
108734
108784
|
function validatePath2(path17, paramName) {
|
|
108735
108785
|
if (!path17 || typeof path17 !== "string") {
|
|
108736
108786
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
108737
108787
|
}
|
|
108738
108788
|
if (path17.includes("..")) {
|
|
108739
|
-
const normalized =
|
|
108789
|
+
const normalized = normalize10(path17);
|
|
108740
108790
|
if (normalized.startsWith("..")) {
|
|
108741
108791
|
throw new SkillsMigrationError(`${paramName} contains invalid path traversal: ${path17}`);
|
|
108742
108792
|
}
|
|
@@ -108907,12 +108957,12 @@ async function getAllFiles(dirPath) {
|
|
|
108907
108957
|
return files;
|
|
108908
108958
|
}
|
|
108909
108959
|
async function hashFile(filePath) {
|
|
108910
|
-
return new Promise((
|
|
108960
|
+
return new Promise((resolve46, reject) => {
|
|
108911
108961
|
const hash = createHash9("sha256");
|
|
108912
108962
|
const stream = createReadStream2(filePath);
|
|
108913
108963
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
108914
108964
|
stream.on("end", () => {
|
|
108915
|
-
|
|
108965
|
+
resolve46(hash.digest("hex"));
|
|
108916
108966
|
});
|
|
108917
108967
|
stream.on("error", (error) => {
|
|
108918
108968
|
stream.destroy();
|
|
@@ -109020,13 +109070,13 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
|
|
|
109020
109070
|
init_types3();
|
|
109021
109071
|
var import_fs_extra31 = __toESM(require_lib(), 1);
|
|
109022
109072
|
import { readdir as readdir39 } from "node:fs/promises";
|
|
109023
|
-
import { join as join131, normalize as
|
|
109073
|
+
import { join as join131, normalize as normalize11 } from "node:path";
|
|
109024
109074
|
function validatePath3(path17, paramName) {
|
|
109025
109075
|
if (!path17 || typeof path17 !== "string") {
|
|
109026
109076
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
109027
109077
|
}
|
|
109028
109078
|
if (path17.includes("..")) {
|
|
109029
|
-
const normalized =
|
|
109079
|
+
const normalized = normalize11(path17);
|
|
109030
109080
|
if (normalized.startsWith("..")) {
|
|
109031
109081
|
throw new SkillsMigrationError(`${paramName} contains invalid path traversal: ${path17}`);
|
|
109032
109082
|
}
|
|
@@ -109561,7 +109611,7 @@ async function handlePostInstall(ctx) {
|
|
|
109561
109611
|
}
|
|
109562
109612
|
// src/commands/init/phases/plugin-install-handler.ts
|
|
109563
109613
|
init_codex_plugin_installer();
|
|
109564
|
-
import { cpSync as cpSync2, existsSync as
|
|
109614
|
+
import { cpSync as cpSync2, existsSync as existsSync71, mkdirSync as mkdirSync6, readFileSync as readFileSync24, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "node:fs";
|
|
109565
109615
|
import { join as join139 } from "node:path";
|
|
109566
109616
|
|
|
109567
109617
|
// src/domains/installation/plugin/migrate-legacy-to-plugin.ts
|
|
@@ -109569,14 +109619,14 @@ init_install_mode_detector();
|
|
|
109569
109619
|
import { createHash as createHash10 } from "node:crypto";
|
|
109570
109620
|
import {
|
|
109571
109621
|
cpSync,
|
|
109572
|
-
existsSync as
|
|
109622
|
+
existsSync as existsSync69,
|
|
109573
109623
|
mkdirSync as mkdirSync5,
|
|
109574
109624
|
readFileSync as readFileSync23,
|
|
109575
109625
|
readdirSync as readdirSync11,
|
|
109576
109626
|
rmSync as rmSync3,
|
|
109577
109627
|
writeFileSync as writeFileSync7
|
|
109578
109628
|
} from "node:fs";
|
|
109579
|
-
import { dirname as dirname43, join as join137, relative as relative31, resolve as
|
|
109629
|
+
import { dirname as dirname43, join as join137, relative as relative31, resolve as resolve46 } from "node:path";
|
|
109580
109630
|
|
|
109581
109631
|
// src/domains/installation/plugin/plugin-installer.ts
|
|
109582
109632
|
init_install_mode_detector();
|
|
@@ -109679,6 +109729,7 @@ async function migrateLegacyToPlugin(opts) {
|
|
|
109679
109729
|
const ts = opts.now ?? new Date().toISOString();
|
|
109680
109730
|
const before = detectInstallMode(claudeDir3);
|
|
109681
109731
|
if (before.mode === "plugin") {
|
|
109732
|
+
prunePluginSuppliedLegacyFilesFromMetadata(claudeDir3);
|
|
109682
109733
|
return base("noop-already-plugin", before.mode, before.plugin.enabled);
|
|
109683
109734
|
}
|
|
109684
109735
|
if (!await installer.isClaudeAvailable() || !await installer.isPluginSupported()) {
|
|
@@ -109704,6 +109755,7 @@ async function migrateLegacyToPlugin(opts) {
|
|
|
109704
109755
|
backupDir = join137(claudeDir3, "backups", `ck-legacy-${ts.replace(/[:.]/g, "-")}`);
|
|
109705
109756
|
mkdirSync5(backupDir, { recursive: true });
|
|
109706
109757
|
removedPaths = removeLegacy(claudeDir3, backupDir);
|
|
109758
|
+
prunePluginSuppliedLegacyFilesFromMetadata(claudeDir3, removedPaths);
|
|
109707
109759
|
}
|
|
109708
109760
|
const installedVersion = detectPluginState(claudeDir3).version;
|
|
109709
109761
|
const receiptPath = writeReceipt(claudeDir3, {
|
|
@@ -109743,7 +109795,7 @@ function defaultLegacyRemover(claudeDir3, backupDir) {
|
|
|
109743
109795
|
const legacyPath = resolveSafePluginSuppliedLegacyPath2(claudeDir3, file.path);
|
|
109744
109796
|
if (!legacyPath)
|
|
109745
109797
|
continue;
|
|
109746
|
-
if (!
|
|
109798
|
+
if (!existsSync69(legacyPath.absolutePath))
|
|
109747
109799
|
continue;
|
|
109748
109800
|
if (!isSafeToRemovePluginSuppliedLegacyFile(file, legacyPath.absolutePath))
|
|
109749
109801
|
continue;
|
|
@@ -109775,7 +109827,7 @@ function removeOrphanLegacySentinels(claudeDir3, backupDir, removedTrackedPaths)
|
|
|
109775
109827
|
const removed = [];
|
|
109776
109828
|
for (const root of [...rootsToSweep].sort(compareLegacyPaths)) {
|
|
109777
109829
|
const rootAbs = join137(claudeDir3, root);
|
|
109778
|
-
if (!
|
|
109830
|
+
if (!existsSync69(rootAbs))
|
|
109779
109831
|
continue;
|
|
109780
109832
|
const sentinels = findLegacySentinels(rootAbs).sort((a3, b3) => compareLegacyPaths(relative31(claudeDir3, a3), relative31(claudeDir3, b3)));
|
|
109781
109833
|
for (const sentinelAbs of sentinels) {
|
|
@@ -109864,7 +109916,7 @@ function resolveSafePluginSuppliedLegacyPath2(claudeDir3, pathValue) {
|
|
|
109864
109916
|
const safe = resolveSafeChildPath2(claudeDir3, normalized);
|
|
109865
109917
|
if (!safe)
|
|
109866
109918
|
return null;
|
|
109867
|
-
const relativePath = normalizeLegacyPath2(relative31(
|
|
109919
|
+
const relativePath = normalizeLegacyPath2(relative31(resolve46(claudeDir3), safe));
|
|
109868
109920
|
if (!isPluginSuppliedLegacyPath2(relativePath))
|
|
109869
109921
|
return null;
|
|
109870
109922
|
return { absolutePath: safe, relativePath };
|
|
@@ -109873,8 +109925,8 @@ function resolveSafeChildPath2(baseDir, pathValue) {
|
|
|
109873
109925
|
const normalized = normalizeLegacyPath2(pathValue);
|
|
109874
109926
|
if (!normalized || hasPathTraversal2(normalized) || isAbsoluteLike3(normalized))
|
|
109875
109927
|
return null;
|
|
109876
|
-
const resolvedBase =
|
|
109877
|
-
const resolvedTarget =
|
|
109928
|
+
const resolvedBase = resolve46(baseDir);
|
|
109929
|
+
const resolvedTarget = resolve46(resolvedBase, normalized);
|
|
109878
109930
|
const relativePath = normalizeLegacyPath2(relative31(resolvedBase, resolvedTarget));
|
|
109879
109931
|
if (!relativePath || relativePath === ".." || relativePath.startsWith("../"))
|
|
109880
109932
|
return null;
|
|
@@ -109927,6 +109979,45 @@ function collectTrackedFiles2(meta) {
|
|
|
109927
109979
|
}
|
|
109928
109980
|
return out;
|
|
109929
109981
|
}
|
|
109982
|
+
function prunePluginSuppliedLegacyFilesFromMetadata(claudeDir3, removedPaths) {
|
|
109983
|
+
const metadataPath = join137(claudeDir3, "metadata.json");
|
|
109984
|
+
const meta = readJsonSafe3(metadataPath);
|
|
109985
|
+
if (!isRecord5(meta))
|
|
109986
|
+
return;
|
|
109987
|
+
const removed = removedPaths ? new Set(removedPaths.map(normalizeComparableLegacyPath).filter(Boolean)) : null;
|
|
109988
|
+
let changed = false;
|
|
109989
|
+
const pruneFiles = (files) => {
|
|
109990
|
+
if (!Array.isArray(files))
|
|
109991
|
+
return files;
|
|
109992
|
+
const pruned = files.filter((file) => {
|
|
109993
|
+
if (!isRecord5(file) || typeof file.path !== "string")
|
|
109994
|
+
return true;
|
|
109995
|
+
const normalizedPath = normalizeComparableLegacyPath(file.path);
|
|
109996
|
+
const resolvedPath = resolveSafePluginSuppliedLegacyPath2(claudeDir3, normalizedPath);
|
|
109997
|
+
const shouldPrune = removed ? removed.has(normalizedPath) || resolvedPath !== null && !existsSync69(resolvedPath.absolutePath) : isPluginSuppliedLegacyPath2(normalizedPath);
|
|
109998
|
+
return !shouldPrune;
|
|
109999
|
+
});
|
|
110000
|
+
if (pruned.length !== files.length)
|
|
110001
|
+
changed = true;
|
|
110002
|
+
return pruned;
|
|
110003
|
+
};
|
|
110004
|
+
if (isRecord5(meta.kits)) {
|
|
110005
|
+
const engineer = meta.kits[ENGINEER_KIT_KEY];
|
|
110006
|
+
if (isRecord5(engineer)) {
|
|
110007
|
+
engineer.files = pruneFiles(engineer.files);
|
|
110008
|
+
}
|
|
110009
|
+
} else {
|
|
110010
|
+
meta.files = pruneFiles(meta.files);
|
|
110011
|
+
meta.installedFiles = pruneFiles(meta.installedFiles);
|
|
110012
|
+
}
|
|
110013
|
+
if (changed) {
|
|
110014
|
+
writeFileSync7(metadataPath, `${JSON.stringify(meta, null, 2)}
|
|
110015
|
+
`, "utf-8");
|
|
110016
|
+
}
|
|
110017
|
+
}
|
|
110018
|
+
function normalizeComparableLegacyPath(pathValue) {
|
|
110019
|
+
return normalizeLegacyPath2(pathValue).replace(/^\.\/+/, "").replace(/^\.claude\//, "");
|
|
110020
|
+
}
|
|
109930
110021
|
function writeReceipt(claudeDir3, receipt) {
|
|
109931
110022
|
const receiptPath = join137(claudeDir3, ".ck-migration-log.json");
|
|
109932
110023
|
const existing = readJsonSafe3(receiptPath);
|
|
@@ -109983,7 +110074,7 @@ function isRecord5(value) {
|
|
|
109983
110074
|
|
|
109984
110075
|
// src/domains/installation/plugin/uninstall-plugin.ts
|
|
109985
110076
|
init_install_mode_detector();
|
|
109986
|
-
import { existsSync as
|
|
110077
|
+
import { existsSync as existsSync70, rmSync as rmSync4 } from "node:fs";
|
|
109987
110078
|
import { join as join138 } from "node:path";
|
|
109988
110079
|
init_path_resolver();
|
|
109989
110080
|
async function uninstallEnginePlugin(opts = {}) {
|
|
@@ -110007,7 +110098,7 @@ async function uninstallEnginePlugin(opts = {}) {
|
|
|
110007
110098
|
let staleCacheRemoved = false;
|
|
110008
110099
|
const marketplace = state.marketplace ?? CK_MARKETPLACE_NAME;
|
|
110009
110100
|
const cacheDir = join138(claudeDir3, "plugins", "cache", marketplace, CK_PLUGIN_NAME);
|
|
110010
|
-
if (
|
|
110101
|
+
if (existsSync70(cacheDir)) {
|
|
110011
110102
|
rmSync4(cacheDir, { recursive: true, force: true });
|
|
110012
110103
|
staleCacheRemoved = true;
|
|
110013
110104
|
}
|
|
@@ -110106,7 +110197,7 @@ function logLegacyPluginCleanup(result) {
|
|
|
110106
110197
|
function stagePluginSource(extractDir, stageBaseDir) {
|
|
110107
110198
|
const base2 = stageBaseDir ?? join139(PathResolver.getCacheDir(true), "ck-plugin-source");
|
|
110108
110199
|
const payloadSrc = join139(extractDir, ".claude");
|
|
110109
|
-
if (!
|
|
110200
|
+
if (!existsSync71(payloadSrc)) {
|
|
110110
110201
|
throw new Error(`plugin payload not found in archive: ${payloadSrc}`);
|
|
110111
110202
|
}
|
|
110112
110203
|
rmSync5(base2, { recursive: true, force: true });
|
|
@@ -110141,7 +110232,7 @@ function stagePluginSource(extractDir, stageBaseDir) {
|
|
|
110141
110232
|
}
|
|
110142
110233
|
function ensureCodexPluginManifest(pluginRoot) {
|
|
110143
110234
|
const manifestPath = join139(pluginRoot, ".codex-plugin", "plugin.json");
|
|
110144
|
-
if (
|
|
110235
|
+
if (existsSync71(manifestPath))
|
|
110145
110236
|
return;
|
|
110146
110237
|
const claudeManifest = readJsonSafe4(join139(pluginRoot, ".claude-plugin", "plugin.json"));
|
|
110147
110238
|
const manifest = pruneUndefined({
|
|
@@ -110236,7 +110327,7 @@ function logCodexPluginCleanup(result) {
|
|
|
110236
110327
|
init_config_manager();
|
|
110237
110328
|
init_github_client();
|
|
110238
110329
|
import { mkdir as mkdir36 } from "node:fs/promises";
|
|
110239
|
-
import { join as join142, resolve as
|
|
110330
|
+
import { join as join142, resolve as resolve49 } from "node:path";
|
|
110240
110331
|
|
|
110241
110332
|
// src/domains/github/kit-access-checker.ts
|
|
110242
110333
|
init_error2();
|
|
@@ -110370,7 +110461,7 @@ async function runPreflightChecks() {
|
|
|
110370
110461
|
return result;
|
|
110371
110462
|
}
|
|
110372
110463
|
if (result.ghVersion) {
|
|
110373
|
-
const comparison =
|
|
110464
|
+
const comparison = compareVersions7(result.ghVersion, MIN_GH_CLI_VERSION);
|
|
110374
110465
|
result.ghVersionOk = comparison >= 0;
|
|
110375
110466
|
if (!result.ghVersionOk) {
|
|
110376
110467
|
logger.debug(`GitHub CLI version ${result.ghVersion} is below minimum ${MIN_GH_CLI_VERSION}`);
|
|
@@ -110408,8 +110499,8 @@ init_hook_health_checker();
|
|
|
110408
110499
|
|
|
110409
110500
|
// src/domains/installation/fresh-installer.ts
|
|
110410
110501
|
init_metadata_migration();
|
|
110411
|
-
import { existsSync as
|
|
110412
|
-
import { basename as basename28, dirname as dirname44, join as join140, resolve as
|
|
110502
|
+
import { existsSync as existsSync72, readdirSync as readdirSync12, rmSync as rmSync6, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
|
|
110503
|
+
import { basename as basename28, dirname as dirname44, join as join140, resolve as resolve47 } from "node:path";
|
|
110413
110504
|
init_logger();
|
|
110414
110505
|
init_safe_spinner();
|
|
110415
110506
|
var import_fs_extra35 = __toESM(require_lib(), 1);
|
|
@@ -110461,15 +110552,15 @@ async function analyzeFreshInstallation(claudeDir3) {
|
|
|
110461
110552
|
};
|
|
110462
110553
|
}
|
|
110463
110554
|
function cleanupEmptyDirectories2(filePath, claudeDir3) {
|
|
110464
|
-
const normalizedClaudeDir =
|
|
110465
|
-
let currentDir =
|
|
110555
|
+
const normalizedClaudeDir = resolve47(claudeDir3);
|
|
110556
|
+
let currentDir = resolve47(dirname44(filePath));
|
|
110466
110557
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
|
|
110467
110558
|
try {
|
|
110468
110559
|
const entries = readdirSync12(currentDir);
|
|
110469
110560
|
if (entries.length === 0) {
|
|
110470
110561
|
rmdirSync2(currentDir);
|
|
110471
110562
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
110472
|
-
currentDir =
|
|
110563
|
+
currentDir = resolve47(dirname44(currentDir));
|
|
110473
110564
|
} else {
|
|
110474
110565
|
break;
|
|
110475
110566
|
}
|
|
@@ -110492,7 +110583,7 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
|
|
|
110492
110583
|
}
|
|
110493
110584
|
for (const file of filesToRemove) {
|
|
110494
110585
|
const fullPath = join140(claudeDir3, file.path);
|
|
110495
|
-
if (!
|
|
110586
|
+
if (!existsSync72(fullPath)) {
|
|
110496
110587
|
continue;
|
|
110497
110588
|
}
|
|
110498
110589
|
try {
|
|
@@ -110550,8 +110641,8 @@ function getFreshBackupTargets(claudeDir3, analysis, includeModified) {
|
|
|
110550
110641
|
mutatePaths: filesToRemove.length > 0 ? ["metadata.json"] : []
|
|
110551
110642
|
};
|
|
110552
110643
|
}
|
|
110553
|
-
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) =>
|
|
110554
|
-
if (
|
|
110644
|
+
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync72(join140(claudeDir3, subdir)));
|
|
110645
|
+
if (existsSync72(join140(claudeDir3, "metadata.json"))) {
|
|
110555
110646
|
deletePaths.push("metadata.json");
|
|
110556
110647
|
}
|
|
110557
110648
|
return {
|
|
@@ -110659,7 +110750,7 @@ async function handleFreshInstallation(claudeDir3, prompts) {
|
|
|
110659
110750
|
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
110660
110751
|
import { cp as cp5, mkdir as mkdir35, readdir as readdir42, rename as rename11, rm as rm16, stat as stat22 } from "node:fs/promises";
|
|
110661
110752
|
import { homedir as homedir47 } from "node:os";
|
|
110662
|
-
import { dirname as dirname45, join as join141, normalize as
|
|
110753
|
+
import { dirname as dirname45, join as join141, normalize as normalize12, resolve as resolve48 } from "node:path";
|
|
110663
110754
|
var LEGACY_KIT_MARKERS = [
|
|
110664
110755
|
"metadata.json",
|
|
110665
110756
|
".ck.json",
|
|
@@ -110685,7 +110776,7 @@ function uniqueNormalizedPaths(paths) {
|
|
|
110685
110776
|
const seen = new Set;
|
|
110686
110777
|
const result = [];
|
|
110687
110778
|
for (const path17 of paths) {
|
|
110688
|
-
const normalized =
|
|
110779
|
+
const normalized = normalize12(resolve48(path17));
|
|
110689
110780
|
if (seen.has(normalized))
|
|
110690
110781
|
continue;
|
|
110691
110782
|
seen.add(normalized);
|
|
@@ -110750,8 +110841,8 @@ async function repairLegacyWindowsGlobalKitDir(options2) {
|
|
|
110750
110841
|
if (safeEnvPath(env2.CLAUDE_CONFIG_DIR)) {
|
|
110751
110842
|
return { status: "skipped", reason: "custom-global-dir", candidateDirs: [] };
|
|
110752
110843
|
}
|
|
110753
|
-
const targetDir =
|
|
110754
|
-
const candidateDirs = getLegacyWindowsGlobalKitDirCandidates(env2, options2.homeDir).filter((candidate) =>
|
|
110844
|
+
const targetDir = normalize12(resolve48(options2.targetDir));
|
|
110845
|
+
const candidateDirs = getLegacyWindowsGlobalKitDirCandidates(env2, options2.homeDir).filter((candidate) => normalize12(resolve48(candidate)) !== targetDir);
|
|
110755
110846
|
const legacyDirs = [];
|
|
110756
110847
|
for (const candidate of candidateDirs) {
|
|
110757
110848
|
if (await hasKitMarkers(candidate)) {
|
|
@@ -110974,7 +111065,7 @@ async function handleSelection(ctx) {
|
|
|
110974
111065
|
}
|
|
110975
111066
|
}
|
|
110976
111067
|
}
|
|
110977
|
-
const resolvedDir =
|
|
111068
|
+
const resolvedDir = resolve49(targetDir);
|
|
110978
111069
|
if (ctx.options.global) {
|
|
110979
111070
|
try {
|
|
110980
111071
|
const repairResult = await repairLegacyWindowsGlobalKitDir({ targetDir: resolvedDir });
|
|
@@ -111176,7 +111267,7 @@ async function handleSelection(ctx) {
|
|
|
111176
111267
|
}
|
|
111177
111268
|
// src/commands/init/phases/sync-handler.ts
|
|
111178
111269
|
import { copyFile as copyFile8, mkdir as mkdir37, open as open5, readFile as readFile61, rename as rename12, stat as stat23, unlink as unlink13, writeFile as writeFile35 } from "node:fs/promises";
|
|
111179
|
-
import { dirname as dirname46, join as join143, resolve as
|
|
111270
|
+
import { dirname as dirname46, join as join143, resolve as resolve50 } from "node:path";
|
|
111180
111271
|
init_logger();
|
|
111181
111272
|
init_path_resolver();
|
|
111182
111273
|
var import_fs_extra38 = __toESM(require_lib(), 1);
|
|
@@ -111185,7 +111276,7 @@ async function handleSync(ctx) {
|
|
|
111185
111276
|
if (!ctx.options.sync) {
|
|
111186
111277
|
return ctx;
|
|
111187
111278
|
}
|
|
111188
|
-
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() :
|
|
111279
|
+
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve50(ctx.options.dir || ".");
|
|
111189
111280
|
const claudeDir3 = ctx.options.global ? resolvedDir : join143(resolvedDir, ".claude");
|
|
111190
111281
|
if (!await import_fs_extra38.pathExists(claudeDir3)) {
|
|
111191
111282
|
logger.error("Cannot sync: no .claude directory found");
|
|
@@ -111319,7 +111410,7 @@ async function acquireSyncLock(global3) {
|
|
|
111319
111410
|
}
|
|
111320
111411
|
logger.debug(`Lock stat failed: ${statError}`);
|
|
111321
111412
|
}
|
|
111322
|
-
await new Promise((
|
|
111413
|
+
await new Promise((resolve51) => setTimeout(resolve51, 100));
|
|
111323
111414
|
continue;
|
|
111324
111415
|
}
|
|
111325
111416
|
throw err;
|
|
@@ -112308,10 +112399,10 @@ async function initCommand(options2) {
|
|
|
112308
112399
|
// src/commands/migrate/migrate-command.ts
|
|
112309
112400
|
init_dist2();
|
|
112310
112401
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
112311
|
-
import { existsSync as
|
|
112402
|
+
import { existsSync as existsSync73 } from "node:fs";
|
|
112312
112403
|
import { readFile as readFile67, rm as rm18, unlink as unlink14 } from "node:fs/promises";
|
|
112313
112404
|
import { homedir as homedir52 } from "node:os";
|
|
112314
|
-
import { basename as basename30, dirname as dirname49, join as join151, resolve as
|
|
112405
|
+
import { basename as basename30, dirname as dirname49, join as join151, resolve as resolve51 } from "node:path";
|
|
112315
112406
|
init_logger();
|
|
112316
112407
|
|
|
112317
112408
|
// src/ui/ck-cli-design/next-steps-footer.ts
|
|
@@ -113764,9 +113855,9 @@ function shouldExecuteAction2(action) {
|
|
|
113764
113855
|
}
|
|
113765
113856
|
async function executeDeleteAction(action, options2) {
|
|
113766
113857
|
const preservePaths = options2?.preservePaths ?? new Set;
|
|
113767
|
-
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(
|
|
113858
|
+
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve51(action.targetPath));
|
|
113768
113859
|
try {
|
|
113769
|
-
if (!shouldPreserveTarget && action.targetPath &&
|
|
113860
|
+
if (!shouldPreserveTarget && action.targetPath && existsSync73(action.targetPath)) {
|
|
113770
113861
|
await rm18(action.targetPath, { recursive: true, force: true });
|
|
113771
113862
|
}
|
|
113772
113863
|
await removePortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
|
|
@@ -113795,7 +113886,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
113795
113886
|
}
|
|
113796
113887
|
}
|
|
113797
113888
|
function hasSuccessfulReplacementWrite(action, results) {
|
|
113798
|
-
return results.some((result) => result.success && !result.skipped && result.provider === action.provider && replacementTypeMatches(action.type, result.portableType) && replacementItemMatches(action, result) && result.path.length > 0 &&
|
|
113889
|
+
return results.some((result) => result.success && !result.skipped && result.provider === action.provider && replacementTypeMatches(action.type, result.portableType) && replacementItemMatches(action, result) && result.path.length > 0 && resolve51(result.path) !== resolve51(action.targetPath));
|
|
113799
113890
|
}
|
|
113800
113891
|
function replacementTypeMatches(actionType, resultType) {
|
|
113801
113892
|
return resultType === actionType || actionType === "command" && resultType === "skill";
|
|
@@ -113838,8 +113929,8 @@ function resolveHookTargetPath(item, provider, global3) {
|
|
|
113838
113929
|
if (converted.error)
|
|
113839
113930
|
return null;
|
|
113840
113931
|
const targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join151(basePath, converted.filename);
|
|
113841
|
-
const resolvedTarget =
|
|
113842
|
-
const resolvedBase =
|
|
113932
|
+
const resolvedTarget = resolve51(targetPath).replace(/\\/g, "/");
|
|
113933
|
+
const resolvedBase = resolve51(basePath).replace(/\\/g, "/").replace(/\/+$/, "");
|
|
113843
113934
|
if (resolvedTarget !== resolvedBase && !resolvedTarget.startsWith(`${resolvedBase}/`)) {
|
|
113844
113935
|
return null;
|
|
113845
113936
|
}
|
|
@@ -113848,8 +113939,8 @@ function resolveHookTargetPath(item, provider, global3) {
|
|
|
113848
113939
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
113849
113940
|
if (!skillSourcePath)
|
|
113850
113941
|
return;
|
|
113851
|
-
const sourceMetadataPath = join151(
|
|
113852
|
-
if (!
|
|
113942
|
+
const sourceMetadataPath = join151(resolve51(skillSourcePath, ".."), "metadata.json");
|
|
113943
|
+
if (!existsSync73(sourceMetadataPath))
|
|
113853
113944
|
return;
|
|
113854
113945
|
let sourceMetadata;
|
|
113855
113946
|
try {
|
|
@@ -113862,7 +113953,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
113862
113953
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
113863
113954
|
return;
|
|
113864
113955
|
const claudeDir3 = installGlobally ? join151(homedir52(), ".claude") : join151(process.cwd(), ".claude");
|
|
113865
|
-
if (!
|
|
113956
|
+
if (!existsSync73(claudeDir3))
|
|
113866
113957
|
return;
|
|
113867
113958
|
try {
|
|
113868
113959
|
const result = await handleDeletions(sourceMetadata, claudeDir3, inferKitTypeFromSourceMetadata(sourceMetadata));
|
|
@@ -114154,7 +114245,7 @@ async function migrateCommand(options2) {
|
|
|
114154
114245
|
const interactive = process.stdout.isTTY && !options2.yes;
|
|
114155
114246
|
const conflictActions = plan.actions.filter((a3) => a3.action === "conflict");
|
|
114156
114247
|
for (const action of conflictActions) {
|
|
114157
|
-
if (!action.diff && action.targetPath &&
|
|
114248
|
+
if (!action.diff && action.targetPath && existsSync73(action.targetPath)) {
|
|
114158
114249
|
try {
|
|
114159
114250
|
const targetContent = await readFile67(action.targetPath, "utf-8");
|
|
114160
114251
|
const sourceItem = effectiveAgents.find((a3) => a3.name === action.item) || effectiveCommands.find((c2) => c2.name === action.item) || (effectiveConfigItem?.name === action.item ? effectiveConfigItem : null) || effectiveRuleItems.find((r2) => r2.name === action.item) || effectiveHookItems.find((h2) => h2.name === action.item);
|
|
@@ -114253,9 +114344,9 @@ async function migrateCommand(options2) {
|
|
|
114253
114344
|
const progressSink = createMigrateProgressSink(writeTasks.length + plannedDeleteActions.length);
|
|
114254
114345
|
const writtenPaths = new Set;
|
|
114255
114346
|
const recordHookTargetForSettings = (provider, global3, targetPath) => {
|
|
114256
|
-
if (targetPath.length === 0 || !
|
|
114347
|
+
if (targetPath.length === 0 || !existsSync73(targetPath))
|
|
114257
114348
|
return;
|
|
114258
|
-
const resolvedPath =
|
|
114349
|
+
const resolvedPath = resolve51(targetPath);
|
|
114259
114350
|
const entry = successfulHookFiles.get(provider) ?? {
|
|
114260
114351
|
files: [],
|
|
114261
114352
|
global: global3
|
|
@@ -114273,7 +114364,7 @@ async function migrateCommand(options2) {
|
|
|
114273
114364
|
const recordSuccessfulWrites = (task, taskResults) => {
|
|
114274
114365
|
for (const result of taskResults.filter((entry) => entry.success)) {
|
|
114275
114366
|
if (!result.skipped && result.path.length > 0) {
|
|
114276
|
-
writtenPaths.add(
|
|
114367
|
+
writtenPaths.add(resolve51(result.path));
|
|
114277
114368
|
}
|
|
114278
114369
|
if (task.type === "hooks") {
|
|
114279
114370
|
recordHookTargetForSettings(task.provider, task.global, result.path);
|
|
@@ -114437,7 +114528,7 @@ async function migrateCommand(options2) {
|
|
|
114437
114528
|
}
|
|
114438
114529
|
}
|
|
114439
114530
|
try {
|
|
114440
|
-
const kitRoot = (agentSource ?
|
|
114531
|
+
const kitRoot = (agentSource ? resolve51(agentSource, "..") : null) ?? (commandSource ? resolve51(commandSource, "..") : null) ?? (skillSource ? resolve51(skillSource, "..") : null) ?? null;
|
|
114441
114532
|
const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
|
|
114442
114533
|
if (manifest?.cliVersion) {
|
|
114443
114534
|
await updateAppliedManifestVersion(manifest.cliVersion);
|
|
@@ -114485,7 +114576,7 @@ async function migrateCommand(options2) {
|
|
|
114485
114576
|
async function rollbackResults(results) {
|
|
114486
114577
|
const rolledBackPaths = new Set;
|
|
114487
114578
|
for (const result of results) {
|
|
114488
|
-
if (!result.path || !
|
|
114579
|
+
if (!result.path || !existsSync73(result.path))
|
|
114489
114580
|
continue;
|
|
114490
114581
|
try {
|
|
114491
114582
|
if (result.overwritten)
|
|
@@ -114608,7 +114699,7 @@ var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
|
114608
114699
|
|
|
114609
114700
|
// src/commands/new/phases/directory-setup.ts
|
|
114610
114701
|
init_config_manager();
|
|
114611
|
-
import { resolve as
|
|
114702
|
+
import { resolve as resolve52 } from "node:path";
|
|
114612
114703
|
init_logger();
|
|
114613
114704
|
init_path_resolver();
|
|
114614
114705
|
init_types3();
|
|
@@ -114693,7 +114784,7 @@ async function directorySetup(validOptions, prompts) {
|
|
|
114693
114784
|
targetDir = await prompts.getDirectory(targetDir);
|
|
114694
114785
|
}
|
|
114695
114786
|
}
|
|
114696
|
-
const resolvedDir =
|
|
114787
|
+
const resolvedDir = resolve52(targetDir);
|
|
114697
114788
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
114698
114789
|
if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
114699
114790
|
logger.warning("You're creating a project at HOME directory.");
|
|
@@ -115026,8 +115117,8 @@ Please use only one download method.`);
|
|
|
115026
115117
|
}
|
|
115027
115118
|
// src/commands/plan/plan-command.ts
|
|
115028
115119
|
init_output_manager();
|
|
115029
|
-
import { existsSync as
|
|
115030
|
-
import { dirname as dirname53, isAbsolute as isAbsolute15, join as join156, parse as parse7, resolve as
|
|
115120
|
+
import { existsSync as existsSync76, statSync as statSync13 } from "node:fs";
|
|
115121
|
+
import { dirname as dirname53, isAbsolute as isAbsolute15, join as join156, parse as parse7, resolve as resolve56 } from "node:path";
|
|
115031
115122
|
|
|
115032
115123
|
// src/commands/plan/plan-read-handlers.ts
|
|
115033
115124
|
init_config();
|
|
@@ -115036,14 +115127,14 @@ init_plans_registry();
|
|
|
115036
115127
|
init_logger();
|
|
115037
115128
|
init_output_manager();
|
|
115038
115129
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
115039
|
-
import { existsSync as
|
|
115040
|
-
import { basename as basename31, dirname as dirname51, join as join155, relative as relative34, resolve as
|
|
115130
|
+
import { existsSync as existsSync75, statSync as statSync12 } from "node:fs";
|
|
115131
|
+
import { basename as basename31, dirname as dirname51, join as join155, relative as relative34, resolve as resolve54 } from "node:path";
|
|
115041
115132
|
|
|
115042
115133
|
// src/commands/plan/plan-dependencies.ts
|
|
115043
115134
|
init_config();
|
|
115044
115135
|
init_plan_parser();
|
|
115045
115136
|
init_plans_registry();
|
|
115046
|
-
import { existsSync as
|
|
115137
|
+
import { existsSync as existsSync74 } from "node:fs";
|
|
115047
115138
|
import { dirname as dirname50, join as join154 } from "node:path";
|
|
115048
115139
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
115049
115140
|
if (references.length === 0)
|
|
@@ -115066,7 +115157,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
|
|
|
115066
115157
|
const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
|
|
115067
115158
|
const planFile = join154(scopeRoot, planId, "plan.md");
|
|
115068
115159
|
const isSelfReference = planFile === currentPlanFile;
|
|
115069
|
-
if (!
|
|
115160
|
+
if (!existsSync74(planFile)) {
|
|
115070
115161
|
return {
|
|
115071
115162
|
reference,
|
|
115072
115163
|
scope,
|
|
@@ -115095,14 +115186,14 @@ init_config();
|
|
|
115095
115186
|
init_plan_parser();
|
|
115096
115187
|
init_plan_scope();
|
|
115097
115188
|
init_plans_registry();
|
|
115098
|
-
import { isAbsolute as isAbsolute14, resolve as
|
|
115189
|
+
import { isAbsolute as isAbsolute14, resolve as resolve53 } from "node:path";
|
|
115099
115190
|
async function getGlobalPlansDirFromCwd() {
|
|
115100
115191
|
const projectRoot = findProjectRoot(process.cwd());
|
|
115101
115192
|
const { config } = await CkConfigManager.loadFull(projectRoot);
|
|
115102
115193
|
return resolveGlobalPlansDir(config);
|
|
115103
115194
|
}
|
|
115104
115195
|
function resolveTargetFromBase(target, baseDir) {
|
|
115105
|
-
const resolvedTarget = isAbsolute14(target) ?
|
|
115196
|
+
const resolvedTarget = isAbsolute14(target) ? resolve53(target) : resolve53(baseDir, target);
|
|
115106
115197
|
return isWithinDir(resolvedTarget, baseDir) ? resolvedTarget : null;
|
|
115107
115198
|
}
|
|
115108
115199
|
|
|
@@ -115205,8 +115296,8 @@ async function handleStatus(target, options2) {
|
|
|
115205
115296
|
return;
|
|
115206
115297
|
}
|
|
115207
115298
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
115208
|
-
const t = effectiveTarget ?
|
|
115209
|
-
const plansDir = t &&
|
|
115299
|
+
const t = effectiveTarget ? resolve54(effectiveTarget) : null;
|
|
115300
|
+
const plansDir = t && existsSync75(t) && statSync12(t).isDirectory() && !existsSync75(join155(t, "plan.md")) ? t : null;
|
|
115210
115301
|
if (plansDir) {
|
|
115211
115302
|
const planFiles = scanPlanDir(plansDir);
|
|
115212
115303
|
if (planFiles.length === 0) {
|
|
@@ -115390,7 +115481,7 @@ init_plan_parser();
|
|
|
115390
115481
|
init_plans_registry();
|
|
115391
115482
|
init_output_manager();
|
|
115392
115483
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
115393
|
-
import { basename as basename32, dirname as dirname52, relative as relative35, resolve as
|
|
115484
|
+
import { basename as basename32, dirname as dirname52, relative as relative35, resolve as resolve55 } from "node:path";
|
|
115394
115485
|
function quoteReadTarget(filePath) {
|
|
115395
115486
|
return `"${filePath.replace(/\\/g, "/").replace(/"/g, "\\\"")}"`;
|
|
115396
115487
|
}
|
|
@@ -115433,13 +115524,13 @@ async function handleCreate(target, options2) {
|
|
|
115433
115524
|
return;
|
|
115434
115525
|
}
|
|
115435
115526
|
const globalBaseDir = options2.global ? await getGlobalPlansDirFromCwd() : undefined;
|
|
115436
|
-
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) :
|
|
115527
|
+
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) : resolve55(dir);
|
|
115437
115528
|
if (globalBaseDir && !resolvedDir) {
|
|
115438
115529
|
output.error("[X] Target directory must stay within the configured global plans root");
|
|
115439
115530
|
process.exitCode = 1;
|
|
115440
115531
|
return;
|
|
115441
115532
|
}
|
|
115442
|
-
const safeResolvedDir = resolvedDir ??
|
|
115533
|
+
const safeResolvedDir = resolvedDir ?? resolve55(dir);
|
|
115443
115534
|
const result = scaffoldPlan({
|
|
115444
115535
|
title: options2.title,
|
|
115445
115536
|
phases: phaseNames.map((name2) => ({ name: name2 })),
|
|
@@ -115618,25 +115709,25 @@ async function handleAddPhase(target, options2) {
|
|
|
115618
115709
|
// src/commands/plan/plan-command.ts
|
|
115619
115710
|
function resolveTargetPath(target, baseDir) {
|
|
115620
115711
|
if (!baseDir) {
|
|
115621
|
-
return
|
|
115712
|
+
return resolve56(target);
|
|
115622
115713
|
}
|
|
115623
115714
|
if (isAbsolute15(target)) {
|
|
115624
|
-
return
|
|
115715
|
+
return resolve56(target);
|
|
115625
115716
|
}
|
|
115626
|
-
const cwdCandidate =
|
|
115627
|
-
if (
|
|
115717
|
+
const cwdCandidate = resolve56(target);
|
|
115718
|
+
if (existsSync76(cwdCandidate)) {
|
|
115628
115719
|
return cwdCandidate;
|
|
115629
115720
|
}
|
|
115630
|
-
return
|
|
115721
|
+
return resolve56(baseDir, target);
|
|
115631
115722
|
}
|
|
115632
115723
|
function resolvePlanFile(target, baseDir) {
|
|
115633
|
-
const t = target ? resolveTargetPath(target, baseDir) : baseDir ?
|
|
115634
|
-
if (
|
|
115724
|
+
const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve56(baseDir) : process.cwd();
|
|
115725
|
+
if (existsSync76(t)) {
|
|
115635
115726
|
const stat24 = statSync13(t);
|
|
115636
115727
|
if (stat24.isFile())
|
|
115637
115728
|
return t;
|
|
115638
115729
|
const candidate = join156(t, "plan.md");
|
|
115639
|
-
if (
|
|
115730
|
+
if (existsSync76(candidate))
|
|
115640
115731
|
return candidate;
|
|
115641
115732
|
}
|
|
115642
115733
|
if (!target && !baseDir) {
|
|
@@ -115644,7 +115735,7 @@ function resolvePlanFile(target, baseDir) {
|
|
|
115644
115735
|
const root = parse7(dir).root;
|
|
115645
115736
|
while (dir !== root) {
|
|
115646
115737
|
const candidate = join156(dir, "plan.md");
|
|
115647
|
-
if (
|
|
115738
|
+
if (existsSync76(candidate))
|
|
115648
115739
|
return candidate;
|
|
115649
115740
|
dir = dirname53(dir);
|
|
115650
115741
|
}
|
|
@@ -115694,7 +115785,7 @@ async function planCommand(action, target, options2) {
|
|
|
115694
115785
|
let resolvedTarget = target;
|
|
115695
115786
|
if (resolvedAction && !knownActions.has(resolvedAction)) {
|
|
115696
115787
|
const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
|
|
115697
|
-
const existsOnDisk = !looksLikePath &&
|
|
115788
|
+
const existsOnDisk = !looksLikePath && existsSync76(resolve56(resolvedAction));
|
|
115698
115789
|
if (looksLikePath || existsOnDisk) {
|
|
115699
115790
|
resolvedTarget = resolvedAction;
|
|
115700
115791
|
resolvedAction = undefined;
|
|
@@ -115736,13 +115827,13 @@ init_claudekit_data2();
|
|
|
115736
115827
|
init_logger();
|
|
115737
115828
|
init_safe_prompts();
|
|
115738
115829
|
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
115739
|
-
import { existsSync as
|
|
115740
|
-
import { resolve as
|
|
115830
|
+
import { existsSync as existsSync77 } from "node:fs";
|
|
115831
|
+
import { resolve as resolve57 } from "node:path";
|
|
115741
115832
|
async function handleAdd(projectPath, options2) {
|
|
115742
115833
|
logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
|
|
115743
115834
|
intro("Add Project");
|
|
115744
|
-
const absolutePath =
|
|
115745
|
-
if (!
|
|
115835
|
+
const absolutePath = resolve57(projectPath);
|
|
115836
|
+
if (!existsSync77(absolutePath)) {
|
|
115746
115837
|
log.error(`Path does not exist: ${absolutePath}`);
|
|
115747
115838
|
process.exitCode = 1;
|
|
115748
115839
|
return;
|
|
@@ -116167,7 +116258,7 @@ import { readFile as readFile68 } from "node:fs/promises";
|
|
|
116167
116258
|
import { join as join158 } from "node:path";
|
|
116168
116259
|
|
|
116169
116260
|
// src/commands/skills/installed-skills-inventory.ts
|
|
116170
|
-
import { join as join157, resolve as
|
|
116261
|
+
import { join as join157, resolve as resolve58 } from "node:path";
|
|
116171
116262
|
init_path_resolver();
|
|
116172
116263
|
var SCOPE_SORT_ORDER = {
|
|
116173
116264
|
project: 0,
|
|
@@ -116175,8 +116266,8 @@ var SCOPE_SORT_ORDER = {
|
|
|
116175
116266
|
};
|
|
116176
116267
|
async function getActiveClaudeSkillInstallations(options2 = {}) {
|
|
116177
116268
|
const projectDir = options2.projectDir ?? process.cwd();
|
|
116178
|
-
const globalDir =
|
|
116179
|
-
const projectClaudeDir =
|
|
116269
|
+
const globalDir = resolve58(options2.globalDir ?? PathResolver.getGlobalKitDir());
|
|
116270
|
+
const projectClaudeDir = resolve58(projectDir, ".claude");
|
|
116180
116271
|
const projectScopeAliasesGlobal = projectClaudeDir === globalDir;
|
|
116181
116272
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
116182
116273
|
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join157(projectClaudeDir, "skills")),
|
|
@@ -116924,7 +117015,7 @@ async function detectInstallations() {
|
|
|
116924
117015
|
|
|
116925
117016
|
// src/commands/uninstall/removal-handler.ts
|
|
116926
117017
|
import { readdirSync as readdirSync14, rmSync as rmSync8 } from "node:fs";
|
|
116927
|
-
import { basename as basename33, join as join161, resolve as
|
|
117018
|
+
import { basename as basename33, join as join161, resolve as resolve59, sep as sep14 } from "node:path";
|
|
116928
117019
|
init_logger();
|
|
116929
117020
|
init_safe_prompts();
|
|
116930
117021
|
init_safe_spinner();
|
|
@@ -117288,8 +117379,8 @@ async function restoreUninstallBackup(backup) {
|
|
|
117288
117379
|
}
|
|
117289
117380
|
async function isPathSafeToRemove(filePath, baseDir) {
|
|
117290
117381
|
try {
|
|
117291
|
-
const resolvedPath =
|
|
117292
|
-
const resolvedBase =
|
|
117382
|
+
const resolvedPath = resolve59(filePath);
|
|
117383
|
+
const resolvedBase = resolve59(baseDir);
|
|
117293
117384
|
if (!resolvedPath.startsWith(resolvedBase + sep14) && resolvedPath !== resolvedBase) {
|
|
117294
117385
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
117295
117386
|
return false;
|
|
@@ -117297,7 +117388,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
117297
117388
|
const stats = await import_fs_extra44.lstat(filePath);
|
|
117298
117389
|
if (stats.isSymbolicLink()) {
|
|
117299
117390
|
const realPath = await import_fs_extra44.realpath(filePath);
|
|
117300
|
-
const resolvedReal =
|
|
117391
|
+
const resolvedReal = resolve59(realPath);
|
|
117301
117392
|
if (!resolvedReal.startsWith(resolvedBase + sep14) && resolvedReal !== resolvedBase) {
|
|
117302
117393
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
117303
117394
|
return false;
|
|
@@ -117790,7 +117881,7 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
|
|
|
117790
117881
|
|
|
117791
117882
|
// src/commands/watch/watch-command.ts
|
|
117792
117883
|
init_logger();
|
|
117793
|
-
import { existsSync as
|
|
117884
|
+
import { existsSync as existsSync83 } from "node:fs";
|
|
117794
117885
|
import { rm as rm19 } from "node:fs/promises";
|
|
117795
117886
|
import { join as join168 } from "node:path";
|
|
117796
117887
|
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
@@ -117861,7 +117952,7 @@ function getDisclaimerMarker() {
|
|
|
117861
117952
|
return AI_DISCLAIMER;
|
|
117862
117953
|
}
|
|
117863
117954
|
function spawnAndCollect2(command, args) {
|
|
117864
|
-
return new Promise((
|
|
117955
|
+
return new Promise((resolve60, reject) => {
|
|
117865
117956
|
const child = spawn6(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
117866
117957
|
const chunks = [];
|
|
117867
117958
|
const stderrChunks = [];
|
|
@@ -117874,7 +117965,7 @@ function spawnAndCollect2(command, args) {
|
|
|
117874
117965
|
reject(new Error(`${command} exited with code ${code2}: ${stderr}`));
|
|
117875
117966
|
return;
|
|
117876
117967
|
}
|
|
117877
|
-
|
|
117968
|
+
resolve60(Buffer.concat(chunks).toString("utf-8"));
|
|
117878
117969
|
});
|
|
117879
117970
|
});
|
|
117880
117971
|
}
|
|
@@ -117982,7 +118073,7 @@ function formatResponse(content, showBranding) {
|
|
|
117982
118073
|
return disclaimer + formatted + branding;
|
|
117983
118074
|
}
|
|
117984
118075
|
async function postViaGh(owner, repo, issueNumber, body) {
|
|
117985
|
-
return new Promise((
|
|
118076
|
+
return new Promise((resolve60, reject) => {
|
|
117986
118077
|
const args = [
|
|
117987
118078
|
"issue",
|
|
117988
118079
|
"comment",
|
|
@@ -118004,7 +118095,7 @@ async function postViaGh(owner, repo, issueNumber, body) {
|
|
|
118004
118095
|
reject(new Error(`gh exited with code ${code2}: ${stderr}`));
|
|
118005
118096
|
return;
|
|
118006
118097
|
}
|
|
118007
|
-
|
|
118098
|
+
resolve60();
|
|
118008
118099
|
});
|
|
118009
118100
|
});
|
|
118010
118101
|
}
|
|
@@ -118122,7 +118213,7 @@ After completing the implementation:
|
|
|
118122
118213
|
"--allowedTools",
|
|
118123
118214
|
tools
|
|
118124
118215
|
];
|
|
118125
|
-
await new Promise((
|
|
118216
|
+
await new Promise((resolve60, reject) => {
|
|
118126
118217
|
const child = spawn8("claude", args, { cwd: cwd2, stdio: ["pipe", "pipe", "pipe"], detached: false });
|
|
118127
118218
|
child.stdin.write(prompt);
|
|
118128
118219
|
child.stdin.end();
|
|
@@ -118147,7 +118238,7 @@ After completing the implementation:
|
|
|
118147
118238
|
reject(new Error(`Claude exited ${code2}: ${stderr.slice(0, 500)}`));
|
|
118148
118239
|
return;
|
|
118149
118240
|
}
|
|
118150
|
-
|
|
118241
|
+
resolve60();
|
|
118151
118242
|
});
|
|
118152
118243
|
});
|
|
118153
118244
|
}
|
|
@@ -118291,7 +118382,7 @@ function checkRateLimit2(processedThisHour, maxPerHour) {
|
|
|
118291
118382
|
return processedThisHour < maxPerHour;
|
|
118292
118383
|
}
|
|
118293
118384
|
function spawnAndCollect3(command, args) {
|
|
118294
|
-
return new Promise((
|
|
118385
|
+
return new Promise((resolve60, reject) => {
|
|
118295
118386
|
const child = spawn9(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
118296
118387
|
const chunks = [];
|
|
118297
118388
|
const stderrChunks = [];
|
|
@@ -118304,7 +118395,7 @@ function spawnAndCollect3(command, args) {
|
|
|
118304
118395
|
reject(new Error(`${command} exited with code ${code2}: ${stderr}`));
|
|
118305
118396
|
return;
|
|
118306
118397
|
}
|
|
118307
|
-
|
|
118398
|
+
resolve60(Buffer.concat(chunks).toString("utf-8"));
|
|
118308
118399
|
});
|
|
118309
118400
|
});
|
|
118310
118401
|
}
|
|
@@ -118356,7 +118447,7 @@ async function invokeClaude(options2) {
|
|
|
118356
118447
|
return collectClaudeOutput(child, options2.timeoutSec, verbose);
|
|
118357
118448
|
}
|
|
118358
118449
|
function collectClaudeOutput(child, timeoutSec, verbose = false) {
|
|
118359
|
-
return new Promise((
|
|
118450
|
+
return new Promise((resolve60, reject) => {
|
|
118360
118451
|
const chunks = [];
|
|
118361
118452
|
const stderrChunks = [];
|
|
118362
118453
|
child.stdout?.on("data", (chunk) => {
|
|
@@ -118386,7 +118477,7 @@ function collectClaudeOutput(child, timeoutSec, verbose = false) {
|
|
|
118386
118477
|
reject(new Error(`Claude exited with code ${code2}: ${stderr}`));
|
|
118387
118478
|
return;
|
|
118388
118479
|
}
|
|
118389
|
-
|
|
118480
|
+
resolve60(verbose ? parseStreamJsonOutput(stdout2) : parseClaudeOutput(stdout2));
|
|
118390
118481
|
});
|
|
118391
118482
|
});
|
|
118392
118483
|
}
|
|
@@ -119089,14 +119180,14 @@ function cleanExpiredIssues(state, ttlDays) {
|
|
|
119089
119180
|
init_ck_config_manager();
|
|
119090
119181
|
init_file_io();
|
|
119091
119182
|
init_logger();
|
|
119092
|
-
import { existsSync as
|
|
119183
|
+
import { existsSync as existsSync79 } from "node:fs";
|
|
119093
119184
|
import { mkdir as mkdir41, readFile as readFile71 } from "node:fs/promises";
|
|
119094
119185
|
import { dirname as dirname55 } from "node:path";
|
|
119095
119186
|
var PROCESSED_ISSUES_CAP = 500;
|
|
119096
119187
|
async function readCkJson(projectDir) {
|
|
119097
119188
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
119098
119189
|
try {
|
|
119099
|
-
if (!
|
|
119190
|
+
if (!existsSync79(configPath))
|
|
119100
119191
|
return {};
|
|
119101
119192
|
const content = await readFile71(configPath, "utf-8");
|
|
119102
119193
|
return JSON.parse(content);
|
|
@@ -119122,7 +119213,7 @@ async function loadWatchState(projectDir) {
|
|
|
119122
119213
|
async function saveWatchState(projectDir, state) {
|
|
119123
119214
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
119124
119215
|
const configDir = dirname55(configPath);
|
|
119125
|
-
if (!
|
|
119216
|
+
if (!existsSync79(configDir)) {
|
|
119126
119217
|
await mkdir41(configDir, { recursive: true });
|
|
119127
119218
|
}
|
|
119128
119219
|
const raw2 = await readCkJson(projectDir);
|
|
@@ -119249,7 +119340,7 @@ async function processImplementationQueue(state, config, setup, options2, watchL
|
|
|
119249
119340
|
// src/commands/watch/phases/repo-scanner.ts
|
|
119250
119341
|
init_logger();
|
|
119251
119342
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
119252
|
-
import { existsSync as
|
|
119343
|
+
import { existsSync as existsSync80 } from "node:fs";
|
|
119253
119344
|
import { readdir as readdir47, stat as stat25 } from "node:fs/promises";
|
|
119254
119345
|
import { join as join165 } from "node:path";
|
|
119255
119346
|
async function scanForRepos(parentDir) {
|
|
@@ -119263,7 +119354,7 @@ async function scanForRepos(parentDir) {
|
|
|
119263
119354
|
if (!entryStat.isDirectory())
|
|
119264
119355
|
continue;
|
|
119265
119356
|
const gitDir = join165(fullPath, ".git");
|
|
119266
|
-
if (!
|
|
119357
|
+
if (!existsSync80(gitDir))
|
|
119267
119358
|
continue;
|
|
119268
119359
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
119269
119360
|
encoding: "utf-8",
|
|
@@ -119287,7 +119378,7 @@ async function scanForRepos(parentDir) {
|
|
|
119287
119378
|
// src/commands/watch/phases/setup-validator.ts
|
|
119288
119379
|
init_logger();
|
|
119289
119380
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
119290
|
-
import { existsSync as
|
|
119381
|
+
import { existsSync as existsSync81 } from "node:fs";
|
|
119291
119382
|
import { homedir as homedir53 } from "node:os";
|
|
119292
119383
|
import { join as join166 } from "node:path";
|
|
119293
119384
|
async function validateSetup(cwd2) {
|
|
@@ -119321,7 +119412,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
119321
119412
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
119322
119413
|
}
|
|
119323
119414
|
const skillsPath = join166(homedir53(), ".claude", "skills");
|
|
119324
|
-
const skillsAvailable =
|
|
119415
|
+
const skillsAvailable = existsSync81(skillsPath);
|
|
119325
119416
|
if (!skillsAvailable) {
|
|
119326
119417
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
119327
119418
|
}
|
|
@@ -119337,7 +119428,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
119337
119428
|
init_logger();
|
|
119338
119429
|
init_path_resolver();
|
|
119339
119430
|
import { createWriteStream as createWriteStream3, statSync as statSync14 } from "node:fs";
|
|
119340
|
-
import { existsSync as
|
|
119431
|
+
import { existsSync as existsSync82 } from "node:fs";
|
|
119341
119432
|
import { mkdir as mkdir42, rename as rename15 } from "node:fs/promises";
|
|
119342
119433
|
import { join as join167 } from "node:path";
|
|
119343
119434
|
|
|
@@ -119352,7 +119443,7 @@ class WatchLogger {
|
|
|
119352
119443
|
}
|
|
119353
119444
|
async init() {
|
|
119354
119445
|
try {
|
|
119355
|
-
if (!
|
|
119446
|
+
if (!existsSync82(this.logDir)) {
|
|
119356
119447
|
await mkdir42(this.logDir, { recursive: true });
|
|
119357
119448
|
}
|
|
119358
119449
|
const dateStr = formatDate(new Date);
|
|
@@ -119538,7 +119629,7 @@ async function watchCommand(options2) {
|
|
|
119538
119629
|
}
|
|
119539
119630
|
async function discoverRepos(options2, watchLog) {
|
|
119540
119631
|
const cwd2 = process.cwd();
|
|
119541
|
-
const isGitRepo =
|
|
119632
|
+
const isGitRepo = existsSync83(join168(cwd2, ".git"));
|
|
119542
119633
|
if (options2.force) {
|
|
119543
119634
|
await forceRemoveLock(watchLog);
|
|
119544
119635
|
}
|
|
@@ -119650,7 +119741,7 @@ function formatQueueInfo(state) {
|
|
|
119650
119741
|
return "idle";
|
|
119651
119742
|
}
|
|
119652
119743
|
function sleep(ms) {
|
|
119653
|
-
return new Promise((
|
|
119744
|
+
return new Promise((resolve60) => setTimeout(resolve60, ms));
|
|
119654
119745
|
}
|
|
119655
119746
|
// src/cli/command-registry.ts
|
|
119656
119747
|
init_logger();
|
|
@@ -119795,7 +119886,7 @@ function registerCommands(cli) {
|
|
|
119795
119886
|
// src/cli/version-display.ts
|
|
119796
119887
|
init_package();
|
|
119797
119888
|
init_config_version_checker();
|
|
119798
|
-
import { existsSync as
|
|
119889
|
+
import { existsSync as existsSync95, readFileSync as readFileSync29 } from "node:fs";
|
|
119799
119890
|
import { join as join180 } from "node:path";
|
|
119800
119891
|
|
|
119801
119892
|
// src/domains/versioning/version-checker.ts
|
|
@@ -119809,7 +119900,7 @@ init_types3();
|
|
|
119809
119900
|
// src/domains/versioning/version-cache.ts
|
|
119810
119901
|
init_logger();
|
|
119811
119902
|
init_path_resolver();
|
|
119812
|
-
import { existsSync as
|
|
119903
|
+
import { existsSync as existsSync94 } from "node:fs";
|
|
119813
119904
|
import { mkdir as mkdir43, readFile as readFile73, writeFile as writeFile45 } from "node:fs/promises";
|
|
119814
119905
|
import { join as join179 } from "node:path";
|
|
119815
119906
|
|
|
@@ -119823,7 +119914,7 @@ class VersionCacheManager {
|
|
|
119823
119914
|
static async load() {
|
|
119824
119915
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
119825
119916
|
try {
|
|
119826
|
-
if (!
|
|
119917
|
+
if (!existsSync94(cacheFile)) {
|
|
119827
119918
|
logger.debug("Version check cache not found");
|
|
119828
119919
|
return null;
|
|
119829
119920
|
}
|
|
@@ -119844,7 +119935,7 @@ class VersionCacheManager {
|
|
|
119844
119935
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
119845
119936
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
119846
119937
|
try {
|
|
119847
|
-
if (!
|
|
119938
|
+
if (!existsSync94(cacheDir)) {
|
|
119848
119939
|
await mkdir43(cacheDir, { recursive: true, mode: 448 });
|
|
119849
119940
|
}
|
|
119850
119941
|
await writeFile45(cacheFile, JSON.stringify(cache5, null, 2), "utf-8");
|
|
@@ -119866,7 +119957,7 @@ class VersionCacheManager {
|
|
|
119866
119957
|
static async clear() {
|
|
119867
119958
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
119868
119959
|
try {
|
|
119869
|
-
if (
|
|
119960
|
+
if (existsSync94(cacheFile)) {
|
|
119870
119961
|
const fs20 = await import("node:fs/promises");
|
|
119871
119962
|
await fs20.unlink(cacheFile);
|
|
119872
119963
|
logger.debug("Version check cache cleared");
|
|
@@ -119937,7 +120028,7 @@ init_npm_registry();
|
|
|
119937
120028
|
init_claudekit_constants();
|
|
119938
120029
|
init_logger();
|
|
119939
120030
|
init_version_utils();
|
|
119940
|
-
var
|
|
120031
|
+
var import_compare_versions7 = __toESM(require_umd(), 1);
|
|
119941
120032
|
|
|
119942
120033
|
class CliVersionChecker {
|
|
119943
120034
|
static async check(currentVersion) {
|
|
@@ -119951,13 +120042,13 @@ class CliVersionChecker {
|
|
|
119951
120042
|
logger.debug("Failed to fetch latest CLI version from npm");
|
|
119952
120043
|
return null;
|
|
119953
120044
|
}
|
|
119954
|
-
const current =
|
|
119955
|
-
const latest =
|
|
120045
|
+
const current = normalizeVersion2(currentVersion);
|
|
120046
|
+
const latest = normalizeVersion2(latestVersion);
|
|
119956
120047
|
if (isPrereleaseOfSameBase(current, latest)) {
|
|
119957
120048
|
logger.debug(`CLI version check: skipping update - prerelease (${current}) is same base as stable (${latest})`);
|
|
119958
120049
|
return null;
|
|
119959
120050
|
}
|
|
119960
|
-
const updateAvailable =
|
|
120051
|
+
const updateAvailable = import_compare_versions7.compareVersions(latest, current) > 0;
|
|
119961
120052
|
logger.debug(`CLI version check: current=${current}, latest=${latest}, updateAvailable=${updateAvailable}`);
|
|
119962
120053
|
return {
|
|
119963
120054
|
currentVersion: current,
|
|
@@ -119995,8 +120086,8 @@ function displayKitNotification(result, options2 = {}) {
|
|
|
119995
120086
|
return;
|
|
119996
120087
|
const { currentVersion, latestVersion } = result;
|
|
119997
120088
|
const { isGlobal = false, kitName } = options2;
|
|
119998
|
-
const displayCurrent =
|
|
119999
|
-
const displayLatest =
|
|
120089
|
+
const displayCurrent = normalizeVersion2(currentVersion);
|
|
120090
|
+
const displayLatest = normalizeVersion2(latestVersion);
|
|
120000
120091
|
const boxWidth = 52;
|
|
120001
120092
|
const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors44.default.cyan, boxWidth);
|
|
120002
120093
|
const headerText = import_picocolors44.default.bold(import_picocolors44.default.yellow("⬆ Kit Update Available"));
|
|
@@ -120133,7 +120224,7 @@ async function displayVersion() {
|
|
|
120133
120224
|
const prefix = PathResolver.getPathPrefix(false);
|
|
120134
120225
|
const localMetadataPath = prefix ? join180(process.cwd(), prefix, "metadata.json") : join180(process.cwd(), "metadata.json");
|
|
120135
120226
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
120136
|
-
if (!isLocalSameAsGlobal &&
|
|
120227
|
+
if (!isLocalSameAsGlobal && existsSync95(localMetadataPath)) {
|
|
120137
120228
|
try {
|
|
120138
120229
|
const rawMetadata = JSON.parse(readFileSync29(localMetadataPath, "utf-8"));
|
|
120139
120230
|
const metadata = MetadataSchema.parse(rawMetadata);
|
|
@@ -120147,7 +120238,7 @@ async function displayVersion() {
|
|
|
120147
120238
|
logger.verbose("Failed to parse local metadata.json", { error });
|
|
120148
120239
|
}
|
|
120149
120240
|
}
|
|
120150
|
-
if (
|
|
120241
|
+
if (existsSync95(globalMetadataPath)) {
|
|
120151
120242
|
try {
|
|
120152
120243
|
const rawMetadata = JSON.parse(readFileSync29(globalMetadataPath, "utf-8"));
|
|
120153
120244
|
const metadata = MetadataSchema.parse(rawMetadata);
|