claudekit-cli 4.5.0-dev.7 → 4.5.0-dev.8
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 +6 -2
- package/dist/index.js +1026 -656
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15561,8 +15561,9 @@ var init_types2 = __esm(() => {
|
|
|
15561
15561
|
});
|
|
15562
15562
|
|
|
15563
15563
|
// src/domains/installation/plugin/install-mode-detector.ts
|
|
15564
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
15564
15565
|
import { existsSync as existsSync6, readFileSync as readFileSync3, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
|
|
15565
|
-
import { join as join6 } from "node:path";
|
|
15566
|
+
import { join as join6, relative as relative3, resolve as resolve5 } from "node:path";
|
|
15566
15567
|
function readJsonSafe(filePath) {
|
|
15567
15568
|
try {
|
|
15568
15569
|
return JSON.parse(readFileSync3(filePath, "utf-8"));
|
|
@@ -15665,14 +15666,12 @@ function hasTrackedPluginSuppliedLegacyFiles(claudeDir = PathResolver.getGlobalK
|
|
|
15665
15666
|
if (!isRecord(metadata))
|
|
15666
15667
|
return false;
|
|
15667
15668
|
for (const file of collectTrackedFiles(metadata)) {
|
|
15668
|
-
|
|
15669
|
+
const resolvedPath = resolveSafePluginSuppliedLegacyPath(claudeDir, file.path);
|
|
15670
|
+
if (!resolvedPath || !existsSync6(resolvedPath))
|
|
15669
15671
|
continue;
|
|
15670
|
-
|
|
15671
|
-
if (!PLUGIN_SUPPLIED_LEGACY_PREFIXES.some((prefix) => normalized.startsWith(prefix))) {
|
|
15672
|
+
if (file.ownership === "user" && !checksumMatches(resolvedPath, file.checksum))
|
|
15672
15673
|
continue;
|
|
15673
|
-
|
|
15674
|
-
if (existsSync6(join6(claudeDir, normalized)))
|
|
15675
|
-
return true;
|
|
15674
|
+
return true;
|
|
15676
15675
|
}
|
|
15677
15676
|
return false;
|
|
15678
15677
|
}
|
|
@@ -15685,7 +15684,11 @@ function collectTrackedFiles(metadata) {
|
|
|
15685
15684
|
if (!isRecord(file) || typeof file.path !== "string")
|
|
15686
15685
|
continue;
|
|
15687
15686
|
const ownership = file.ownership === "user" || file.ownership === "ck-modified" ? file.ownership : "ck";
|
|
15688
|
-
tracked.push({
|
|
15687
|
+
tracked.push({
|
|
15688
|
+
path: file.path,
|
|
15689
|
+
ownership,
|
|
15690
|
+
checksum: typeof file.checksum === "string" ? file.checksum : undefined
|
|
15691
|
+
});
|
|
15689
15692
|
}
|
|
15690
15693
|
};
|
|
15691
15694
|
if (isRecord(metadata.kits)) {
|
|
@@ -15697,6 +15700,54 @@ function collectTrackedFiles(metadata) {
|
|
|
15697
15700
|
}
|
|
15698
15701
|
return tracked;
|
|
15699
15702
|
}
|
|
15703
|
+
function resolveSafePluginSuppliedLegacyPath(claudeDir, pathValue) {
|
|
15704
|
+
const normalized = normalizeLegacyPath(pathValue).replace(/^\.\/+/, "");
|
|
15705
|
+
if (!isPluginSuppliedLegacyPath(normalized))
|
|
15706
|
+
return null;
|
|
15707
|
+
const safe = resolveSafeChildPath(claudeDir, normalized);
|
|
15708
|
+
if (!safe)
|
|
15709
|
+
return null;
|
|
15710
|
+
const relativePath = normalizeLegacyPath(relative3(resolve5(claudeDir), safe));
|
|
15711
|
+
if (!isPluginSuppliedLegacyPath(relativePath))
|
|
15712
|
+
return null;
|
|
15713
|
+
return safe;
|
|
15714
|
+
}
|
|
15715
|
+
function resolveSafeChildPath(baseDir, pathValue) {
|
|
15716
|
+
const normalized = normalizeLegacyPath(pathValue);
|
|
15717
|
+
if (!normalized || hasPathTraversal(normalized) || isAbsoluteLike(normalized))
|
|
15718
|
+
return null;
|
|
15719
|
+
const resolvedBase = resolve5(baseDir);
|
|
15720
|
+
const resolvedTarget = resolve5(resolvedBase, normalized);
|
|
15721
|
+
const relativePath = normalizeLegacyPath(relative3(resolvedBase, resolvedTarget));
|
|
15722
|
+
if (!relativePath || relativePath === ".." || relativePath.startsWith("../"))
|
|
15723
|
+
return null;
|
|
15724
|
+
if (isAbsoluteLike(relativePath))
|
|
15725
|
+
return null;
|
|
15726
|
+
return resolvedTarget;
|
|
15727
|
+
}
|
|
15728
|
+
function isPluginSuppliedLegacyPath(pathValue) {
|
|
15729
|
+
const normalized = normalizeLegacyPath(pathValue).replace(/^\.claude\//, "");
|
|
15730
|
+
return PLUGIN_SUPPLIED_LEGACY_PREFIXES.some((prefix) => normalized.startsWith(prefix));
|
|
15731
|
+
}
|
|
15732
|
+
function checksumMatches(filePath, expected) {
|
|
15733
|
+
if (!expected || !/^[a-f0-9]{64}$/i.test(expected))
|
|
15734
|
+
return false;
|
|
15735
|
+
try {
|
|
15736
|
+
const actual = createHash4("sha256").update(readFileSync3(filePath)).digest("hex");
|
|
15737
|
+
return actual.toLowerCase() === expected.toLowerCase();
|
|
15738
|
+
} catch {
|
|
15739
|
+
return false;
|
|
15740
|
+
}
|
|
15741
|
+
}
|
|
15742
|
+
function hasPathTraversal(pathValue) {
|
|
15743
|
+
return pathValue.split("/").some((segment) => segment === "..");
|
|
15744
|
+
}
|
|
15745
|
+
function isAbsoluteLike(pathValue) {
|
|
15746
|
+
return pathValue.startsWith("/") || pathValue.startsWith("//") || /^[A-Za-z]:/.test(pathValue);
|
|
15747
|
+
}
|
|
15748
|
+
function normalizeLegacyPath(pathValue) {
|
|
15749
|
+
return pathValue.replace(/\\/g, "/");
|
|
15750
|
+
}
|
|
15700
15751
|
function safeReaddir(dir) {
|
|
15701
15752
|
try {
|
|
15702
15753
|
return readdirSync2(dir);
|
|
@@ -15865,7 +15916,8 @@ var init_commands = __esm(() => {
|
|
|
15865
15916
|
sync: exports_external.boolean().default(false),
|
|
15866
15917
|
useGit: exports_external.boolean().default(false),
|
|
15867
15918
|
archive: exports_external.string().optional(),
|
|
15868
|
-
kitPath: exports_external.string().optional()
|
|
15919
|
+
kitPath: exports_external.string().optional(),
|
|
15920
|
+
installMode: exports_external.enum(["auto", "plugin", "legacy"]).default("auto")
|
|
15869
15921
|
}).merge(GlobalOutputOptionsSchema);
|
|
15870
15922
|
VersionCommandOptionsSchema = exports_external.object({
|
|
15871
15923
|
kit: KitType.optional(),
|
|
@@ -19941,8 +19993,8 @@ var require_universalify = __commonJS((exports) => {
|
|
|
19941
19993
|
if (typeof args[args.length - 1] === "function")
|
|
19942
19994
|
fn.apply(this, args);
|
|
19943
19995
|
else {
|
|
19944
|
-
return new Promise((
|
|
19945
|
-
args.push((err, res) => err != null ? reject(err) :
|
|
19996
|
+
return new Promise((resolve6, reject) => {
|
|
19997
|
+
args.push((err, res) => err != null ? reject(err) : resolve6(res));
|
|
19946
19998
|
fn.apply(this, args);
|
|
19947
19999
|
});
|
|
19948
20000
|
}
|
|
@@ -20015,19 +20067,19 @@ var require_fs = __commonJS((exports) => {
|
|
|
20015
20067
|
if (typeof callback === "function") {
|
|
20016
20068
|
return fs.exists(filename, callback);
|
|
20017
20069
|
}
|
|
20018
|
-
return new Promise((
|
|
20019
|
-
return fs.exists(filename,
|
|
20070
|
+
return new Promise((resolve6) => {
|
|
20071
|
+
return fs.exists(filename, resolve6);
|
|
20020
20072
|
});
|
|
20021
20073
|
};
|
|
20022
20074
|
exports.read = function(fd, buffer, offset, length, position, callback) {
|
|
20023
20075
|
if (typeof callback === "function") {
|
|
20024
20076
|
return fs.read(fd, buffer, offset, length, position, callback);
|
|
20025
20077
|
}
|
|
20026
|
-
return new Promise((
|
|
20078
|
+
return new Promise((resolve6, reject) => {
|
|
20027
20079
|
fs.read(fd, buffer, offset, length, position, (err, bytesRead, buffer2) => {
|
|
20028
20080
|
if (err)
|
|
20029
20081
|
return reject(err);
|
|
20030
|
-
|
|
20082
|
+
resolve6({ bytesRead, buffer: buffer2 });
|
|
20031
20083
|
});
|
|
20032
20084
|
});
|
|
20033
20085
|
};
|
|
@@ -20035,11 +20087,11 @@ var require_fs = __commonJS((exports) => {
|
|
|
20035
20087
|
if (typeof args[args.length - 1] === "function") {
|
|
20036
20088
|
return fs.write(fd, buffer, ...args);
|
|
20037
20089
|
}
|
|
20038
|
-
return new Promise((
|
|
20090
|
+
return new Promise((resolve6, reject) => {
|
|
20039
20091
|
fs.write(fd, buffer, ...args, (err, bytesWritten, buffer2) => {
|
|
20040
20092
|
if (err)
|
|
20041
20093
|
return reject(err);
|
|
20042
|
-
|
|
20094
|
+
resolve6({ bytesWritten, buffer: buffer2 });
|
|
20043
20095
|
});
|
|
20044
20096
|
});
|
|
20045
20097
|
};
|
|
@@ -20047,11 +20099,11 @@ var require_fs = __commonJS((exports) => {
|
|
|
20047
20099
|
if (typeof args[args.length - 1] === "function") {
|
|
20048
20100
|
return fs.readv(fd, buffers, ...args);
|
|
20049
20101
|
}
|
|
20050
|
-
return new Promise((
|
|
20102
|
+
return new Promise((resolve6, reject) => {
|
|
20051
20103
|
fs.readv(fd, buffers, ...args, (err, bytesRead, buffers2) => {
|
|
20052
20104
|
if (err)
|
|
20053
20105
|
return reject(err);
|
|
20054
|
-
|
|
20106
|
+
resolve6({ bytesRead, buffers: buffers2 });
|
|
20055
20107
|
});
|
|
20056
20108
|
});
|
|
20057
20109
|
};
|
|
@@ -20059,11 +20111,11 @@ var require_fs = __commonJS((exports) => {
|
|
|
20059
20111
|
if (typeof args[args.length - 1] === "function") {
|
|
20060
20112
|
return fs.writev(fd, buffers, ...args);
|
|
20061
20113
|
}
|
|
20062
|
-
return new Promise((
|
|
20114
|
+
return new Promise((resolve6, reject) => {
|
|
20063
20115
|
fs.writev(fd, buffers, ...args, (err, bytesWritten, buffers2) => {
|
|
20064
20116
|
if (err)
|
|
20065
20117
|
return reject(err);
|
|
20066
|
-
|
|
20118
|
+
resolve6({ bytesWritten, buffers: buffers2 });
|
|
20067
20119
|
});
|
|
20068
20120
|
});
|
|
20069
20121
|
};
|
|
@@ -20896,9 +20948,9 @@ var require_symlink = __commonJS((exports, module) => {
|
|
|
20896
20948
|
if (areIdentical(srcStat, dstStat))
|
|
20897
20949
|
return;
|
|
20898
20950
|
}
|
|
20899
|
-
const
|
|
20900
|
-
srcpath =
|
|
20901
|
-
const toType = await symlinkType(
|
|
20951
|
+
const relative4 = await symlinkPaths(srcpath, dstpath);
|
|
20952
|
+
srcpath = relative4.toDst;
|
|
20953
|
+
const toType = await symlinkType(relative4.toCwd, type);
|
|
20902
20954
|
const dir = path3.dirname(dstpath);
|
|
20903
20955
|
if (!await pathExists(dir)) {
|
|
20904
20956
|
await mkdirs(dir);
|
|
@@ -20916,9 +20968,9 @@ var require_symlink = __commonJS((exports, module) => {
|
|
|
20916
20968
|
if (areIdentical(srcStat, dstStat))
|
|
20917
20969
|
return;
|
|
20918
20970
|
}
|
|
20919
|
-
const
|
|
20920
|
-
srcpath =
|
|
20921
|
-
type = symlinkTypeSync(
|
|
20971
|
+
const relative4 = symlinkPathsSync(srcpath, dstpath);
|
|
20972
|
+
srcpath = relative4.toDst;
|
|
20973
|
+
type = symlinkTypeSync(relative4.toCwd, type);
|
|
20922
20974
|
const dir = path3.dirname(dstpath);
|
|
20923
20975
|
const exists = fs.existsSync(dir);
|
|
20924
20976
|
if (exists)
|
|
@@ -21323,7 +21375,7 @@ var init_safe_prompts = __esm(() => {
|
|
|
21323
21375
|
// src/commands/commands/commands-discovery.ts
|
|
21324
21376
|
import { readdir as readdir4 } from "node:fs/promises";
|
|
21325
21377
|
import { homedir as homedir9 } from "node:os";
|
|
21326
|
-
import { join as join17, relative as
|
|
21378
|
+
import { join as join17, relative as relative4 } from "node:path";
|
|
21327
21379
|
function getCommandSourcePath(globalOnly = false) {
|
|
21328
21380
|
const globalPath = join17(homedir9(), ".claude/commands");
|
|
21329
21381
|
if (globalOnly) {
|
|
@@ -21348,7 +21400,7 @@ async function scanCommandDir(dir, rootDir) {
|
|
|
21348
21400
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
21349
21401
|
try {
|
|
21350
21402
|
const { frontmatter, body } = await parseFrontmatterFile(fullPath);
|
|
21351
|
-
const relPath =
|
|
21403
|
+
const relPath = relative4(rootDir, fullPath);
|
|
21352
21404
|
const segments = relPath.replace(/\.md$/, "").split(/[/\\]/);
|
|
21353
21405
|
const name = segments.join("/");
|
|
21354
21406
|
const displayName = segments.join(":");
|
|
@@ -22130,7 +22182,7 @@ var require_depd = __commonJS((exports, module) => {
|
|
|
22130
22182
|
* Copyright(c) 2014-2018 Douglas Christopher Wilson
|
|
22131
22183
|
* MIT Licensed
|
|
22132
22184
|
*/
|
|
22133
|
-
var
|
|
22185
|
+
var relative6 = __require("path").relative;
|
|
22134
22186
|
module.exports = depd;
|
|
22135
22187
|
var basePath = process.cwd();
|
|
22136
22188
|
function containsNamespace(str2, namespace) {
|
|
@@ -22326,7 +22378,7 @@ var require_depd = __commonJS((exports, module) => {
|
|
|
22326
22378
|
return formatted;
|
|
22327
22379
|
}
|
|
22328
22380
|
function formatLocation(callSite) {
|
|
22329
|
-
return
|
|
22381
|
+
return relative6(basePath, callSite[0]) + ":" + callSite[1] + ":" + callSite[2];
|
|
22330
22382
|
}
|
|
22331
22383
|
function getStack() {
|
|
22332
22384
|
var limit = Error.stackTraceLimit;
|
|
@@ -26663,11 +26715,11 @@ var require_raw_body = __commonJS((exports, module) => {
|
|
|
26663
26715
|
if (done) {
|
|
26664
26716
|
return readStream(stream, encoding, length, limit, wrap2(done));
|
|
26665
26717
|
}
|
|
26666
|
-
return new Promise(function executor(
|
|
26718
|
+
return new Promise(function executor(resolve10, reject) {
|
|
26667
26719
|
readStream(stream, encoding, length, limit, function onRead(err, buf) {
|
|
26668
26720
|
if (err)
|
|
26669
26721
|
return reject(err);
|
|
26670
|
-
|
|
26722
|
+
resolve10(buf);
|
|
26671
26723
|
});
|
|
26672
26724
|
});
|
|
26673
26725
|
}
|
|
@@ -39773,7 +39825,7 @@ var require_view = __commonJS((exports, module) => {
|
|
|
39773
39825
|
var basename6 = path3.basename;
|
|
39774
39826
|
var extname2 = path3.extname;
|
|
39775
39827
|
var join19 = path3.join;
|
|
39776
|
-
var
|
|
39828
|
+
var resolve10 = path3.resolve;
|
|
39777
39829
|
module.exports = View;
|
|
39778
39830
|
function View(name, options2) {
|
|
39779
39831
|
var opts = options2 || {};
|
|
@@ -39807,7 +39859,7 @@ var require_view = __commonJS((exports, module) => {
|
|
|
39807
39859
|
debug('lookup "%s"', name);
|
|
39808
39860
|
for (var i = 0;i < roots.length && !path4; i++) {
|
|
39809
39861
|
var root = roots[i];
|
|
39810
|
-
var loc =
|
|
39862
|
+
var loc = resolve10(root, name);
|
|
39811
39863
|
var dir = dirname7(loc);
|
|
39812
39864
|
var file = basename6(loc);
|
|
39813
39865
|
path4 = this.resolve(dir, file);
|
|
@@ -41991,7 +42043,7 @@ var require_application = __commonJS((exports, module) => {
|
|
|
41991
42043
|
var compileETag = require_utils6().compileETag;
|
|
41992
42044
|
var compileQueryParser = require_utils6().compileQueryParser;
|
|
41993
42045
|
var compileTrust = require_utils6().compileTrust;
|
|
41994
|
-
var
|
|
42046
|
+
var resolve10 = __require("node:path").resolve;
|
|
41995
42047
|
var once = require_once();
|
|
41996
42048
|
var Router = require_router();
|
|
41997
42049
|
var slice = Array.prototype.slice;
|
|
@@ -42045,7 +42097,7 @@ var require_application = __commonJS((exports, module) => {
|
|
|
42045
42097
|
this.mountpath = "/";
|
|
42046
42098
|
this.locals.settings = this.settings;
|
|
42047
42099
|
this.set("view", View);
|
|
42048
|
-
this.set("views",
|
|
42100
|
+
this.set("views", resolve10("views"));
|
|
42049
42101
|
this.set("jsonp callback name", "callback");
|
|
42050
42102
|
if (env2 === "production") {
|
|
42051
42103
|
this.enable("view cache");
|
|
@@ -43536,7 +43588,7 @@ var require_send = __commonJS((exports, module) => {
|
|
|
43536
43588
|
var extname2 = path3.extname;
|
|
43537
43589
|
var join19 = path3.join;
|
|
43538
43590
|
var normalize3 = path3.normalize;
|
|
43539
|
-
var
|
|
43591
|
+
var resolve10 = path3.resolve;
|
|
43540
43592
|
var sep5 = path3.sep;
|
|
43541
43593
|
var BYTES_RANGE_REGEXP = /^ *bytes=/;
|
|
43542
43594
|
var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1000;
|
|
@@ -43565,7 +43617,7 @@ var require_send = __commonJS((exports, module) => {
|
|
|
43565
43617
|
this._maxage = opts.maxAge || opts.maxage;
|
|
43566
43618
|
this._maxage = typeof this._maxage === "string" ? ms(this._maxage) : Number(this._maxage);
|
|
43567
43619
|
this._maxage = !isNaN(this._maxage) ? Math.min(Math.max(0, this._maxage), MAX_MAXAGE) : 0;
|
|
43568
|
-
this._root = opts.root ?
|
|
43620
|
+
this._root = opts.root ? resolve10(opts.root) : null;
|
|
43569
43621
|
}
|
|
43570
43622
|
util3.inherits(SendStream, Stream);
|
|
43571
43623
|
SendStream.prototype.error = function error(status, err) {
|
|
@@ -43714,7 +43766,7 @@ var require_send = __commonJS((exports, module) => {
|
|
|
43714
43766
|
return res;
|
|
43715
43767
|
}
|
|
43716
43768
|
parts = normalize3(path4).split(sep5);
|
|
43717
|
-
path4 =
|
|
43769
|
+
path4 = resolve10(path4);
|
|
43718
43770
|
}
|
|
43719
43771
|
if (containsDotFile(parts)) {
|
|
43720
43772
|
debug('%s dotfile "%s"', this._dotfiles, path4);
|
|
@@ -44117,7 +44169,7 @@ var require_response = __commonJS((exports, module) => {
|
|
|
44117
44169
|
var cookie = require_cookie();
|
|
44118
44170
|
var send = require_send();
|
|
44119
44171
|
var extname2 = path3.extname;
|
|
44120
|
-
var
|
|
44172
|
+
var resolve10 = path3.resolve;
|
|
44121
44173
|
var vary = require_vary();
|
|
44122
44174
|
var { Buffer: Buffer2 } = __require("node:buffer");
|
|
44123
44175
|
var res = Object.create(http.ServerResponse.prototype);
|
|
@@ -44326,7 +44378,7 @@ var require_response = __commonJS((exports, module) => {
|
|
|
44326
44378
|
}
|
|
44327
44379
|
opts = Object.create(opts);
|
|
44328
44380
|
opts.headers = headers;
|
|
44329
|
-
var fullPath = !opts.root ?
|
|
44381
|
+
var fullPath = !opts.root ? resolve10(path4) : path4;
|
|
44330
44382
|
return this.sendFile(fullPath, opts, done);
|
|
44331
44383
|
};
|
|
44332
44384
|
res.contentType = res.type = function contentType(type) {
|
|
@@ -44587,7 +44639,7 @@ var require_serve_static = __commonJS((exports, module) => {
|
|
|
44587
44639
|
var encodeUrl = require_encodeurl();
|
|
44588
44640
|
var escapeHtml = require_escape_html();
|
|
44589
44641
|
var parseUrl = require_parseurl();
|
|
44590
|
-
var
|
|
44642
|
+
var resolve10 = __require("path").resolve;
|
|
44591
44643
|
var send = require_send();
|
|
44592
44644
|
var url = __require("url");
|
|
44593
44645
|
module.exports = serveStatic;
|
|
@@ -44606,7 +44658,7 @@ var require_serve_static = __commonJS((exports, module) => {
|
|
|
44606
44658
|
throw new TypeError("option setHeaders must be function");
|
|
44607
44659
|
}
|
|
44608
44660
|
opts.maxage = opts.maxage || opts.maxAge || 0;
|
|
44609
|
-
opts.root =
|
|
44661
|
+
opts.root = resolve10(root);
|
|
44610
44662
|
var onDirectory = redirect ? createRedirectDirectoryListener() : createNotFoundDirectoryListener();
|
|
44611
44663
|
return function serveStatic(req, res, next) {
|
|
44612
44664
|
if (req.method !== "GET" && req.method !== "HEAD") {
|
|
@@ -44817,14 +44869,14 @@ var Locked, lockedPorts, releaseOldLockedPortsIntervalMs, timeout, getLocalHosts
|
|
|
44817
44869
|
}
|
|
44818
44870
|
}
|
|
44819
44871
|
return results;
|
|
44820
|
-
}, checkAvailablePort = (options2) => new Promise((
|
|
44872
|
+
}, checkAvailablePort = (options2) => new Promise((resolve10, reject) => {
|
|
44821
44873
|
const server = net.createServer();
|
|
44822
44874
|
server.unref();
|
|
44823
44875
|
server.on("error", reject);
|
|
44824
44876
|
server.listen(options2, () => {
|
|
44825
44877
|
const { port } = server.address();
|
|
44826
44878
|
server.close(() => {
|
|
44827
|
-
|
|
44879
|
+
resolve10(port);
|
|
44828
44880
|
});
|
|
44829
44881
|
});
|
|
44830
44882
|
}), getAvailablePort = async (options2, hosts) => {
|
|
@@ -45397,19 +45449,19 @@ var fallbackAttemptSymbol, __dirname2, localXdgOpenPath, platform3, arch, tryEac
|
|
|
45397
45449
|
}
|
|
45398
45450
|
const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
|
|
45399
45451
|
if (options2.wait) {
|
|
45400
|
-
return new Promise((
|
|
45452
|
+
return new Promise((resolve10, reject) => {
|
|
45401
45453
|
subprocess.once("error", reject);
|
|
45402
45454
|
subprocess.once("close", (exitCode) => {
|
|
45403
45455
|
if (!options2.allowNonzeroExitCode && exitCode !== 0) {
|
|
45404
45456
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
45405
45457
|
return;
|
|
45406
45458
|
}
|
|
45407
|
-
|
|
45459
|
+
resolve10(subprocess);
|
|
45408
45460
|
});
|
|
45409
45461
|
});
|
|
45410
45462
|
}
|
|
45411
45463
|
if (isFallbackAttempt) {
|
|
45412
|
-
return new Promise((
|
|
45464
|
+
return new Promise((resolve10, reject) => {
|
|
45413
45465
|
subprocess.once("error", reject);
|
|
45414
45466
|
subprocess.once("spawn", () => {
|
|
45415
45467
|
subprocess.once("close", (exitCode) => {
|
|
@@ -45419,17 +45471,17 @@ var fallbackAttemptSymbol, __dirname2, localXdgOpenPath, platform3, arch, tryEac
|
|
|
45419
45471
|
return;
|
|
45420
45472
|
}
|
|
45421
45473
|
subprocess.unref();
|
|
45422
|
-
|
|
45474
|
+
resolve10(subprocess);
|
|
45423
45475
|
});
|
|
45424
45476
|
});
|
|
45425
45477
|
});
|
|
45426
45478
|
}
|
|
45427
45479
|
subprocess.unref();
|
|
45428
|
-
return new Promise((
|
|
45480
|
+
return new Promise((resolve10, reject) => {
|
|
45429
45481
|
subprocess.once("error", reject);
|
|
45430
45482
|
subprocess.once("spawn", () => {
|
|
45431
45483
|
subprocess.off("error", reject);
|
|
45432
|
-
|
|
45484
|
+
resolve10(subprocess);
|
|
45433
45485
|
});
|
|
45434
45486
|
});
|
|
45435
45487
|
}, open = (target, options2) => {
|
|
@@ -46782,8 +46834,11 @@ var init_config_generator = __esm(() => {
|
|
|
46782
46834
|
});
|
|
46783
46835
|
|
|
46784
46836
|
// src/domains/config/config-validator.ts
|
|
46837
|
+
function normalizeApiKeyInput(value) {
|
|
46838
|
+
return value.replace(/\u200B|\u200C|\u200D|\uFEFF/g, "").trim();
|
|
46839
|
+
}
|
|
46785
46840
|
function validateApiKey2(value, pattern) {
|
|
46786
|
-
return pattern.test(value);
|
|
46841
|
+
return pattern.test(normalizeApiKeyInput(value));
|
|
46787
46842
|
}
|
|
46788
46843
|
var VALIDATION_PATTERNS;
|
|
46789
46844
|
var init_config_validator = __esm(() => {
|
|
@@ -47225,7 +47280,7 @@ class NodeFsHandler {
|
|
|
47225
47280
|
this._addToNodeFs(path4, initialAdd, wh, depth + 1);
|
|
47226
47281
|
}
|
|
47227
47282
|
}).on(EV.ERROR, this._boundHandleError);
|
|
47228
|
-
return new Promise((
|
|
47283
|
+
return new Promise((resolve11, reject) => {
|
|
47229
47284
|
if (!stream)
|
|
47230
47285
|
return reject();
|
|
47231
47286
|
stream.once(STR_END, () => {
|
|
@@ -47234,7 +47289,7 @@ class NodeFsHandler {
|
|
|
47234
47289
|
return;
|
|
47235
47290
|
}
|
|
47236
47291
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
47237
|
-
|
|
47292
|
+
resolve11(undefined);
|
|
47238
47293
|
previous.getChildren().filter((item) => {
|
|
47239
47294
|
return item !== directory && !current.has(item);
|
|
47240
47295
|
}).forEach((item) => {
|
|
@@ -47763,11 +47818,11 @@ function createPattern(matcher) {
|
|
|
47763
47818
|
if (matcher.path === string)
|
|
47764
47819
|
return true;
|
|
47765
47820
|
if (matcher.recursive) {
|
|
47766
|
-
const
|
|
47767
|
-
if (!
|
|
47821
|
+
const relative8 = sp2.relative(matcher.path, string);
|
|
47822
|
+
if (!relative8) {
|
|
47768
47823
|
return false;
|
|
47769
47824
|
}
|
|
47770
|
-
return !
|
|
47825
|
+
return !relative8.startsWith("..") && !sp2.isAbsolute(relative8);
|
|
47771
47826
|
}
|
|
47772
47827
|
return false;
|
|
47773
47828
|
};
|
|
@@ -48601,7 +48656,7 @@ __export(exports_projects_registry, {
|
|
|
48601
48656
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
48602
48657
|
import { existsSync as existsSync13, statSync as statSync3 } from "node:fs";
|
|
48603
48658
|
import { copyFile, mkdir as mkdir8, open as open3, readFile as readFile10, unlink as unlink5, writeFile as writeFile9 } from "node:fs/promises";
|
|
48604
|
-
import { basename as basename8, dirname as dirname10, resolve as
|
|
48659
|
+
import { basename as basename8, dirname as dirname10, resolve as resolve12 } from "node:path";
|
|
48605
48660
|
|
|
48606
48661
|
class ProjectsRegistryManager {
|
|
48607
48662
|
static registry = null;
|
|
@@ -48719,7 +48774,7 @@ class ProjectsRegistryManager {
|
|
|
48719
48774
|
if (projectPath.includes("..") || projectPath.startsWith("~")) {
|
|
48720
48775
|
throw new Error("Invalid path: path traversal patterns not allowed");
|
|
48721
48776
|
}
|
|
48722
|
-
const absolutePath =
|
|
48777
|
+
const absolutePath = resolve12(projectPath);
|
|
48723
48778
|
if (!existsSync13(absolutePath)) {
|
|
48724
48779
|
throw new Error(`Path does not exist: ${absolutePath}`);
|
|
48725
48780
|
}
|
|
@@ -48850,7 +48905,7 @@ class ProjectsRegistryManager {
|
|
|
48850
48905
|
return projects;
|
|
48851
48906
|
}
|
|
48852
48907
|
static async isRegistered(projectPath) {
|
|
48853
|
-
const absolutePath =
|
|
48908
|
+
const absolutePath = resolve12(projectPath);
|
|
48854
48909
|
const registry = await ProjectsRegistryManager.load();
|
|
48855
48910
|
return registry.projects.some((p) => p.path === absolutePath);
|
|
48856
48911
|
}
|
|
@@ -48966,7 +49021,7 @@ var init_claudekit_data2 = __esm(() => {
|
|
|
48966
49021
|
import { spawn, spawnSync } from "node:child_process";
|
|
48967
49022
|
import { existsSync as existsSync15 } from "node:fs";
|
|
48968
49023
|
import { homedir as homedir13 } from "node:os";
|
|
48969
|
-
import { join as join28, resolve as
|
|
49024
|
+
import { join as join28, resolve as resolve13, sep as sep5 } from "node:path";
|
|
48970
49025
|
function getWindowsPaths(...relativePaths) {
|
|
48971
49026
|
const roots = [
|
|
48972
49027
|
WINDOWS_PATHS.localAppData,
|
|
@@ -49225,8 +49280,8 @@ function buildOsaScriptCommand(scriptLines, argv = []) {
|
|
|
49225
49280
|
return { command: "osascript", args };
|
|
49226
49281
|
}
|
|
49227
49282
|
function isPathInsideBase(path4, base) {
|
|
49228
|
-
const normalizedPath =
|
|
49229
|
-
const normalizedBase =
|
|
49283
|
+
const normalizedPath = resolve13(path4);
|
|
49284
|
+
const normalizedBase = resolve13(base);
|
|
49230
49285
|
if (normalizedPath === normalizedBase)
|
|
49231
49286
|
return true;
|
|
49232
49287
|
return normalizedPath.startsWith(`${normalizedBase}${sep5}`);
|
|
@@ -49236,19 +49291,19 @@ async function isActionPathAllowed(dirPath, projectId) {
|
|
|
49236
49291
|
const project = await ProjectsRegistryManager.getProject(projectId);
|
|
49237
49292
|
if (!project)
|
|
49238
49293
|
return false;
|
|
49239
|
-
return
|
|
49294
|
+
return resolve13(project.path) === dirPath;
|
|
49240
49295
|
}
|
|
49241
49296
|
if (projectId?.startsWith("discovered-")) {
|
|
49242
49297
|
try {
|
|
49243
49298
|
const encodedPath = projectId.slice("discovered-".length);
|
|
49244
|
-
const discoveredPath =
|
|
49299
|
+
const discoveredPath = resolve13(Buffer.from(encodedPath, "base64url").toString("utf-8"));
|
|
49245
49300
|
if (discoveredPath === dirPath && (isPathInsideBase(discoveredPath, process.cwd()) || isPathInsideBase(discoveredPath, homedir13()))) {
|
|
49246
49301
|
return true;
|
|
49247
49302
|
}
|
|
49248
49303
|
} catch {}
|
|
49249
49304
|
}
|
|
49250
49305
|
const registeredProjects = await ProjectsRegistryManager.listProjects();
|
|
49251
|
-
if (registeredProjects.some((project) =>
|
|
49306
|
+
if (registeredProjects.some((project) => resolve13(project.path) === dirPath)) {
|
|
49252
49307
|
return true;
|
|
49253
49308
|
}
|
|
49254
49309
|
if (isPathInsideBase(dirPath, process.cwd())) {
|
|
@@ -49498,7 +49553,7 @@ function registerActionRoutes(app) {
|
|
|
49498
49553
|
return;
|
|
49499
49554
|
}
|
|
49500
49555
|
const { action, path: rawPath, appId, projectId } = validation.data;
|
|
49501
|
-
const dirPath =
|
|
49556
|
+
const dirPath = resolve13(rawPath);
|
|
49502
49557
|
if (!existsSync15(dirPath)) {
|
|
49503
49558
|
res.status(400).json({ error: "Path does not exist" });
|
|
49504
49559
|
return;
|
|
@@ -49540,7 +49595,7 @@ function registerActionRoutes(app) {
|
|
|
49540
49595
|
} else {
|
|
49541
49596
|
commandToRun = buildLaunchCommand(dirPath);
|
|
49542
49597
|
}
|
|
49543
|
-
const spawnCwd =
|
|
49598
|
+
const spawnCwd = resolve13(commandToRun.cwd || dirPath);
|
|
49544
49599
|
if (spawnCwd !== dirPath) {
|
|
49545
49600
|
const spawnCwdAllowed = await isActionPathAllowed(spawnCwd, typeof projectId === "string" ? projectId : undefined);
|
|
49546
49601
|
if (!spawnCwdAllowed) {
|
|
@@ -49884,13 +49939,13 @@ var init_action_routes = __esm(() => {
|
|
|
49884
49939
|
// src/domains/web-server/routes/agents-routes.ts
|
|
49885
49940
|
import { readdir as readdir7 } from "node:fs/promises";
|
|
49886
49941
|
import { homedir as homedir14 } from "node:os";
|
|
49887
|
-
import { isAbsolute as isAbsolute4, join as join29, relative as
|
|
49942
|
+
import { isAbsolute as isAbsolute4, join as join29, relative as relative8 } from "node:path";
|
|
49888
49943
|
function resolveAgentDirs() {
|
|
49889
49944
|
const dirs = [];
|
|
49890
49945
|
const projectCandidates = getProjectLayoutCandidates(process.cwd(), "agents");
|
|
49891
49946
|
for (const candidate of projectCandidates) {
|
|
49892
49947
|
if (candidate) {
|
|
49893
|
-
const rel =
|
|
49948
|
+
const rel = relative8(process.cwd(), candidate);
|
|
49894
49949
|
dirs.push({ path: candidate, label: rel });
|
|
49895
49950
|
}
|
|
49896
49951
|
}
|
|
@@ -49928,7 +49983,7 @@ async function scanAgentDir(dirPath, dirLabel) {
|
|
|
49928
49983
|
color: frontmatter.color || null,
|
|
49929
49984
|
skillCount: countSkills(frontmatter.tools),
|
|
49930
49985
|
dirLabel,
|
|
49931
|
-
relativePath:
|
|
49986
|
+
relativePath: relative8(homedir14(), filePath)
|
|
49932
49987
|
});
|
|
49933
49988
|
} catch {}
|
|
49934
49989
|
}
|
|
@@ -49958,7 +50013,7 @@ function registerAgentsBrowserRoutes(app) {
|
|
|
49958
50013
|
const dirs = resolveAgentDirs();
|
|
49959
50014
|
for (const dir of dirs) {
|
|
49960
50015
|
const filePath = join29(dir.path, `${slug}.md`);
|
|
49961
|
-
const rel =
|
|
50016
|
+
const rel = relative8(dir.path, filePath);
|
|
49962
50017
|
if (rel.startsWith("..") || isAbsolute4(rel)) {
|
|
49963
50018
|
continue;
|
|
49964
50019
|
}
|
|
@@ -49972,7 +50027,7 @@ function registerAgentsBrowserRoutes(app) {
|
|
|
49972
50027
|
color: frontmatter.color || null,
|
|
49973
50028
|
skillCount: countSkills(frontmatter.tools),
|
|
49974
50029
|
dirLabel: dir.label,
|
|
49975
|
-
relativePath:
|
|
50030
|
+
relativePath: relative8(homedir14(), filePath),
|
|
49976
50031
|
frontmatter,
|
|
49977
50032
|
body
|
|
49978
50033
|
};
|
|
@@ -50837,7 +50892,7 @@ var init_ck_config_routes = __esm(() => {
|
|
|
50837
50892
|
import { existsSync as existsSync17 } from "node:fs";
|
|
50838
50893
|
import { readFile as readFile12, readdir as readdir8 } from "node:fs/promises";
|
|
50839
50894
|
import { homedir as homedir15 } from "node:os";
|
|
50840
|
-
import { basename as basename9, isAbsolute as isAbsolute5, join as join31, relative as
|
|
50895
|
+
import { basename as basename9, isAbsolute as isAbsolute5, join as join31, relative as relative9, resolve as resolve14 } from "node:path";
|
|
50841
50896
|
async function buildCommandTree(dir, baseDir) {
|
|
50842
50897
|
let dirents;
|
|
50843
50898
|
try {
|
|
@@ -50857,7 +50912,7 @@ async function buildCommandTree(dir, baseDir) {
|
|
|
50857
50912
|
const name = entry.name;
|
|
50858
50913
|
const isDir2 = entry.isDirectory();
|
|
50859
50914
|
const fullPath = join31(dir, name);
|
|
50860
|
-
const relPath =
|
|
50915
|
+
const relPath = relative9(baseDir, fullPath);
|
|
50861
50916
|
if (isDir2) {
|
|
50862
50917
|
const children = await buildCommandTree(fullPath, baseDir);
|
|
50863
50918
|
if (children.length > 0) {
|
|
@@ -50902,8 +50957,8 @@ function registerCommandRoutes(app) {
|
|
|
50902
50957
|
return;
|
|
50903
50958
|
}
|
|
50904
50959
|
const commandsDir = join31(homedir15(), ".claude", "commands");
|
|
50905
|
-
const safePath =
|
|
50906
|
-
const rel =
|
|
50960
|
+
const safePath = resolve14(commandsDir, rawPath);
|
|
50961
|
+
const rel = relative9(commandsDir, safePath);
|
|
50907
50962
|
if (rel.startsWith("..") || isAbsolute5(rel)) {
|
|
50908
50963
|
res.status(403).json({ error: "Access denied" });
|
|
50909
50964
|
return;
|
|
@@ -52023,7 +52078,7 @@ var init_hook_log_routes = __esm(() => {
|
|
|
52023
52078
|
import { existsSync as existsSync22 } from "node:fs";
|
|
52024
52079
|
import { readFile as readFile18 } from "node:fs/promises";
|
|
52025
52080
|
import { homedir as homedir22 } from "node:os";
|
|
52026
|
-
import { basename as basename12, join as join40, resolve as
|
|
52081
|
+
import { basename as basename12, join as join40, resolve as resolve15 } from "node:path";
|
|
52027
52082
|
function parseMcpServers(raw, source, sourceLabel) {
|
|
52028
52083
|
const entries = [];
|
|
52029
52084
|
for (const [name, value] of Object.entries(raw)) {
|
|
@@ -52073,7 +52128,7 @@ function isSafeProjectPath(projectPath) {
|
|
|
52073
52128
|
return false;
|
|
52074
52129
|
const home3 = homedir22();
|
|
52075
52130
|
try {
|
|
52076
|
-
const resolved =
|
|
52131
|
+
const resolved = resolve15(projectPath);
|
|
52077
52132
|
if (!resolved.startsWith(home3))
|
|
52078
52133
|
return false;
|
|
52079
52134
|
return existsSync22(resolved);
|
|
@@ -52213,23 +52268,23 @@ var init_migrate_provider_scopes = __esm(() => {
|
|
|
52213
52268
|
// src/commands/migrate/skill-directory-installer.ts
|
|
52214
52269
|
import { existsSync as existsSync23 } from "node:fs";
|
|
52215
52270
|
import { cp, mkdir as mkdir10, readFile as readFile19, realpath as realpath6, rename as rename6, rm as rm5, writeFile as writeFile11 } from "node:fs/promises";
|
|
52216
|
-
import { dirname as dirname11, join as join41, resolve as
|
|
52271
|
+
import { dirname as dirname11, join as join41, resolve as resolve16 } from "node:path";
|
|
52217
52272
|
async function canonicalize(path4) {
|
|
52218
52273
|
try {
|
|
52219
52274
|
return await realpath6(path4);
|
|
52220
52275
|
} catch {
|
|
52221
52276
|
const parent = dirname11(path4);
|
|
52222
52277
|
if (parent === path4) {
|
|
52223
|
-
return
|
|
52278
|
+
return resolve16(path4);
|
|
52224
52279
|
}
|
|
52225
52280
|
try {
|
|
52226
52281
|
const canonicalParent = await realpath6(parent);
|
|
52227
|
-
const absPath =
|
|
52228
|
-
const absParent =
|
|
52282
|
+
const absPath = resolve16(path4);
|
|
52283
|
+
const absParent = resolve16(parent);
|
|
52229
52284
|
const basename13 = absPath.slice(absParent.length + 1) || "";
|
|
52230
52285
|
return join41(canonicalParent, basename13);
|
|
52231
52286
|
} catch {
|
|
52232
|
-
return
|
|
52287
|
+
return resolve16(path4);
|
|
52233
52288
|
}
|
|
52234
52289
|
}
|
|
52235
52290
|
}
|
|
@@ -52274,7 +52329,7 @@ async function installSkillDirectories(skills, targetProviders, options2) {
|
|
|
52274
52329
|
const sourceRoot = skills.length > 0 ? dirname11(skills[0].path) : null;
|
|
52275
52330
|
const canonicalBase = existsSync23(basePath) ? await canonicalize(basePath) : null;
|
|
52276
52331
|
const canonicalSourceRoot = sourceRoot ? await canonicalize(sourceRoot) : null;
|
|
52277
|
-
const basePathIsSymlinkedToSource = canonicalBase !== null && canonicalSourceRoot !== null && canonicalBase === canonicalSourceRoot &&
|
|
52332
|
+
const basePathIsSymlinkedToSource = canonicalBase !== null && canonicalSourceRoot !== null && canonicalBase === canonicalSourceRoot && resolve16(basePath) !== resolve16(sourceRoot ?? "");
|
|
52278
52333
|
if (basePathIsSymlinkedToSource) {
|
|
52279
52334
|
for (const skill of skills) {
|
|
52280
52335
|
results.push({
|
|
@@ -52370,14 +52425,14 @@ var init_skill_directory_installer = __esm(() => {
|
|
|
52370
52425
|
import { existsSync as existsSync24, readFileSync as readFileSync7 } from "node:fs";
|
|
52371
52426
|
import { cp as cp2, mkdir as mkdir11, readFile as readFile20, readdir as readdir12, stat as stat8 } from "node:fs/promises";
|
|
52372
52427
|
import { homedir as homedir23 } from "node:os";
|
|
52373
|
-
import { basename as basename13, dirname as dirname12, extname as extname3, join as join42, relative as
|
|
52428
|
+
import { basename as basename13, dirname as dirname12, extname as extname3, join as join42, relative as relative10, resolve as resolve17, sep as sep6 } from "node:path";
|
|
52374
52429
|
async function copyHooksCompanionDirs(sourceDir, targetDir) {
|
|
52375
52430
|
const result = {
|
|
52376
52431
|
copiedDirs: [],
|
|
52377
52432
|
copiedDotfiles: [],
|
|
52378
52433
|
errors: []
|
|
52379
52434
|
};
|
|
52380
|
-
if (
|
|
52435
|
+
if (resolve17(sourceDir) === resolve17(targetDir)) {
|
|
52381
52436
|
return result;
|
|
52382
52437
|
}
|
|
52383
52438
|
if (!existsSync24(sourceDir)) {
|
|
@@ -52398,8 +52453,8 @@ async function copyHooksCompanionDirs(sourceDir, targetDir) {
|
|
|
52398
52453
|
});
|
|
52399
52454
|
return result;
|
|
52400
52455
|
}
|
|
52401
|
-
const sourceParent =
|
|
52402
|
-
const targetParent =
|
|
52456
|
+
const sourceParent = resolve17(sourceDir, "..");
|
|
52457
|
+
const targetParent = resolve17(targetDir, "..");
|
|
52403
52458
|
if (sourceParent !== targetParent) {
|
|
52404
52459
|
for (const dotfile of HOOKS_COMPANION_DOTFILES) {
|
|
52405
52460
|
const srcPath = join42(sourceParent, dotfile);
|
|
@@ -52428,7 +52483,7 @@ async function copyHooksCompanionDirs(sourceDir, targetDir) {
|
|
|
52428
52483
|
continue;
|
|
52429
52484
|
const srcDir = join42(sourceDir, entry.name);
|
|
52430
52485
|
const dstDir = join42(targetDir, entry.name);
|
|
52431
|
-
if (
|
|
52486
|
+
if (resolve17(srcDir) === resolve17(dstDir))
|
|
52432
52487
|
continue;
|
|
52433
52488
|
try {
|
|
52434
52489
|
const s = await stat8(srcDir);
|
|
@@ -52658,7 +52713,7 @@ async function collectHookFiles(dir, baseDir = dir) {
|
|
|
52658
52713
|
}
|
|
52659
52714
|
for (const entry of entries) {
|
|
52660
52715
|
const fullPath = join42(dir, entry.name);
|
|
52661
|
-
const relPath =
|
|
52716
|
+
const relPath = relative10(baseDir, fullPath).split(/[/\\]/).join("/");
|
|
52662
52717
|
if (entry.isSymbolicLink())
|
|
52663
52718
|
continue;
|
|
52664
52719
|
if (entry.isDirectory()) {
|
|
@@ -52751,7 +52806,7 @@ async function discoverPortableFiles(dir, baseDir, options2) {
|
|
|
52751
52806
|
const extension = extname3(entry.name).toLowerCase();
|
|
52752
52807
|
if (!options2.includeExtensions.has(extension))
|
|
52753
52808
|
continue;
|
|
52754
|
-
const relPath =
|
|
52809
|
+
const relPath = relative10(baseDir, fullPath);
|
|
52755
52810
|
const normalizedPath = relPath.split(/[/\\]/).join("/");
|
|
52756
52811
|
const name = options2.stripExtension ? normalizedPath.replace(/\.[^.]+$/, "") : normalizedPath;
|
|
52757
52812
|
try {
|
|
@@ -54712,17 +54767,17 @@ var init_codex_capabilities = __esm(() => {
|
|
|
54712
54767
|
import { existsSync as existsSync25 } from "node:fs";
|
|
54713
54768
|
import { mkdir as mkdir12, realpath as realpath7 } from "node:fs/promises";
|
|
54714
54769
|
import { homedir as homedir24 } from "node:os";
|
|
54715
|
-
import { dirname as dirname13, join as join43, resolve as
|
|
54770
|
+
import { dirname as dirname13, join as join43, resolve as resolve18, sep as sep7 } from "node:path";
|
|
54716
54771
|
function isPathWithinBoundary3(targetPath, boundaryPath) {
|
|
54717
|
-
const resolvedTarget =
|
|
54718
|
-
const resolvedBoundary =
|
|
54772
|
+
const resolvedTarget = resolve18(targetPath);
|
|
54773
|
+
const resolvedBoundary = resolve18(boundaryPath);
|
|
54719
54774
|
return resolvedTarget === resolvedBoundary || resolvedTarget.startsWith(`${resolvedBoundary}${sep7}`);
|
|
54720
54775
|
}
|
|
54721
54776
|
async function resolveRealPathSafe2(path4) {
|
|
54722
54777
|
try {
|
|
54723
54778
|
return await realpath7(path4);
|
|
54724
54779
|
} catch {
|
|
54725
|
-
return
|
|
54780
|
+
return resolve18(path4);
|
|
54726
54781
|
}
|
|
54727
54782
|
}
|
|
54728
54783
|
async function isCanonicalPathWithinBoundary2(targetPath, boundaryPath) {
|
|
@@ -54731,10 +54786,10 @@ async function isCanonicalPathWithinBoundary2(targetPath, boundaryPath) {
|
|
|
54731
54786
|
return isPathWithinBoundary3(canonicalTarget, canonicalBoundary);
|
|
54732
54787
|
}
|
|
54733
54788
|
function getCodexLockPath2(targetFilePath) {
|
|
54734
|
-
return join43(dirname13(
|
|
54789
|
+
return join43(dirname13(resolve18(targetFilePath)), ".config.toml.ck-codex.lock");
|
|
54735
54790
|
}
|
|
54736
54791
|
async function withCodexTargetLock2(targetFilePath, operation) {
|
|
54737
|
-
const resolvedTargetPath =
|
|
54792
|
+
const resolvedTargetPath = resolve18(targetFilePath);
|
|
54738
54793
|
const dir = dirname13(resolvedTargetPath);
|
|
54739
54794
|
if (!existsSync25(dir)) {
|
|
54740
54795
|
await mkdir12(dir, { recursive: true });
|
|
@@ -54768,10 +54823,10 @@ var init_codex_path_safety = __esm(() => {
|
|
|
54768
54823
|
// src/commands/portable/codex-features-flag.ts
|
|
54769
54824
|
import { existsSync as existsSync26 } from "node:fs";
|
|
54770
54825
|
import { readFile as readFile21, rename as rename7, unlink as unlink6, writeFile as writeFile12 } from "node:fs/promises";
|
|
54771
|
-
import { dirname as dirname14, resolve as
|
|
54826
|
+
import { dirname as dirname14, resolve as resolve19 } from "node:path";
|
|
54772
54827
|
async function ensureCodexHooksFeatureFlag(configTomlPath, isGlobal = false) {
|
|
54773
|
-
const boundary = isGlobal ? getCodexGlobalBoundary() : dirname14(
|
|
54774
|
-
if (!await isCanonicalPathWithinBoundary2(dirname14(
|
|
54828
|
+
const boundary = isGlobal ? getCodexGlobalBoundary() : dirname14(resolve19(configTomlPath));
|
|
54829
|
+
if (!await isCanonicalPathWithinBoundary2(dirname14(resolve19(configTomlPath)), boundary)) {
|
|
54775
54830
|
return {
|
|
54776
54831
|
status: "failed",
|
|
54777
54832
|
configPath: configTomlPath,
|
|
@@ -54935,18 +54990,18 @@ ${SENTINEL_END2}`;
|
|
|
54935
54990
|
});
|
|
54936
54991
|
|
|
54937
54992
|
// src/commands/portable/codex-hook-wrapper.ts
|
|
54938
|
-
import { createHash as
|
|
54993
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
54939
54994
|
import { mkdirSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
54940
|
-
import { dirname as dirname15, join as join44, resolve as
|
|
54995
|
+
import { dirname as dirname15, join as join44, resolve as resolve20 } from "node:path";
|
|
54941
54996
|
function wrapperFilename(originalPath) {
|
|
54942
|
-
const abs =
|
|
54943
|
-
const hash =
|
|
54997
|
+
const abs = resolve20(originalPath);
|
|
54998
|
+
const hash = createHash6("sha256").update(abs).digest("hex").slice(0, 8);
|
|
54944
54999
|
const base = abs.split(/[\\/]/).pop() ?? "hook.cjs";
|
|
54945
55000
|
return `${hash}-${base}`;
|
|
54946
55001
|
}
|
|
54947
55002
|
function generateCodexHookWrappers(originalPaths, wrapperDir, capabilities, timeoutsByPath) {
|
|
54948
55003
|
const results = [];
|
|
54949
|
-
const resolvedWrapperDir =
|
|
55004
|
+
const resolvedWrapperDir = resolve20(wrapperDir);
|
|
54950
55005
|
for (const originalPath of originalPaths) {
|
|
54951
55006
|
const filename = wrapperFilename(originalPath);
|
|
54952
55007
|
const wrapperPath = join44(resolvedWrapperDir, filename);
|
|
@@ -54961,7 +55016,7 @@ function generateCodexHookWrappers(originalPaths, wrapperDir, capabilities, time
|
|
|
54961
55016
|
}
|
|
54962
55017
|
try {
|
|
54963
55018
|
mkdirSync(dirname15(wrapperPath), { recursive: true });
|
|
54964
|
-
const resolvedPath =
|
|
55019
|
+
const resolvedPath = resolve20(originalPath);
|
|
54965
55020
|
const hookTimeoutMs = timeoutsByPath?.[resolvedPath] ?? timeoutsByPath?.[originalPath];
|
|
54966
55021
|
const content = buildWrapperScript(originalPath, capabilities, hookTimeoutMs);
|
|
54967
55022
|
writeFileSync2(wrapperPath, content, { mode: 493 });
|
|
@@ -55366,7 +55421,7 @@ var init_gemini_hook_event_map = __esm(() => {
|
|
|
55366
55421
|
import { existsSync as existsSync27, readFileSync as readFileSync8 } from "node:fs";
|
|
55367
55422
|
import { mkdir as mkdir13, readFile as readFile22, rename as rename8, rm as rm6, writeFile as writeFile13 } from "node:fs/promises";
|
|
55368
55423
|
import { homedir as homedir26 } from "node:os";
|
|
55369
|
-
import { basename as basename14, dirname as dirname16, extname as extname4, isAbsolute as isAbsolute6, join as join45, resolve as
|
|
55424
|
+
import { basename as basename14, dirname as dirname16, extname as extname4, isAbsolute as isAbsolute6, join as join45, resolve as resolve21 } from "node:path";
|
|
55370
55425
|
function resolveSettingsPath(pathValue, isGlobal) {
|
|
55371
55426
|
if (isGlobal || isAbsolute6(pathValue))
|
|
55372
55427
|
return pathValue;
|
|
@@ -55988,7 +56043,7 @@ async function migrateHooksSettingsForCodex(options2) {
|
|
|
55988
56043
|
addKey(`./${join45(targetHooksDir, base)}`);
|
|
55989
56044
|
}
|
|
55990
56045
|
for (const commandSourceHooksDir of sourceHookCommandDirs) {
|
|
55991
|
-
const sourceAbs = join45(
|
|
56046
|
+
const sourceAbs = join45(resolve21(commandSourceHooksDir), base);
|
|
55992
56047
|
addKey(sourceAbs);
|
|
55993
56048
|
addKey(join45(commandSourceHooksDir, base));
|
|
55994
56049
|
addKey(`./${join45(commandSourceHooksDir, base)}`);
|
|
@@ -56152,7 +56207,7 @@ var init_generated_context_hooks = __esm(() => {
|
|
|
56152
56207
|
// src/commands/portable/migrated-hook-settings-cleanup.ts
|
|
56153
56208
|
import { existsSync as existsSync28, realpathSync } from "node:fs";
|
|
56154
56209
|
import { readFile as readFile23, rename as rename9, rm as rm7, unlink as unlink7, writeFile as writeFile14 } from "node:fs/promises";
|
|
56155
|
-
import { basename as basename16, isAbsolute as isAbsolute7, relative as
|
|
56210
|
+
import { basename as basename16, isAbsolute as isAbsolute7, relative as relative11, resolve as resolve22 } from "node:path";
|
|
56156
56211
|
async function pruneSettingsHooks(settingsPath, hooksDir) {
|
|
56157
56212
|
const filesToRemove = new Set;
|
|
56158
56213
|
const warnings = [];
|
|
@@ -56236,9 +56291,9 @@ function hookFilesFromCommand(command, hooksDir) {
|
|
|
56236
56291
|
if (!name || !isGeneratedContextHookName(name))
|
|
56237
56292
|
continue;
|
|
56238
56293
|
if (isAbsolute7(cleaned) && isPathWithin(cleaned, hooksDir))
|
|
56239
|
-
files.add(
|
|
56294
|
+
files.add(resolve22(cleaned));
|
|
56240
56295
|
else if (referencesHooksDir(cleaned, hooksDir) || cleaned.includes(".claude/hooks/")) {
|
|
56241
|
-
files.add(
|
|
56296
|
+
files.add(resolve22(hooksDir, name));
|
|
56242
56297
|
}
|
|
56243
56298
|
}
|
|
56244
56299
|
return Array.from(files);
|
|
@@ -56249,14 +56304,14 @@ function referencesHooksDir(command, hooksDir) {
|
|
|
56249
56304
|
return normalized.includes(normalizedDir) || normalized.includes(".claude/hooks/") || normalized.includes(".codex/hooks/") || normalized.includes(".gemini/hooks/") || normalized.includes(".factory/hooks/");
|
|
56250
56305
|
}
|
|
56251
56306
|
function isPathWithin(filePath, parentDir) {
|
|
56252
|
-
const rel =
|
|
56307
|
+
const rel = relative11(resolvePathForContainment(parentDir), resolvePathForContainment(filePath));
|
|
56253
56308
|
return rel === "" || !!rel && !rel.startsWith("..") && !isAbsolute7(rel);
|
|
56254
56309
|
}
|
|
56255
56310
|
function resolvePathForContainment(pathValue) {
|
|
56256
56311
|
try {
|
|
56257
56312
|
return realpathSync.native(pathValue);
|
|
56258
56313
|
} catch {
|
|
56259
|
-
return
|
|
56314
|
+
return resolve22(pathValue);
|
|
56260
56315
|
}
|
|
56261
56316
|
}
|
|
56262
56317
|
async function atomicWrite2(filePath, content) {
|
|
@@ -56283,7 +56338,7 @@ __export(exports_migrated_hooks_cleanup, {
|
|
|
56283
56338
|
isGeneratedContextHookName: () => isGeneratedContextHookName,
|
|
56284
56339
|
cleanupMigratedHooksForProviders: () => cleanupMigratedHooksForProviders
|
|
56285
56340
|
});
|
|
56286
|
-
import { isAbsolute as isAbsolute8, resolve as
|
|
56341
|
+
import { isAbsolute as isAbsolute8, resolve as resolve23 } from "node:path";
|
|
56287
56342
|
async function cleanupMigratedHooksForProviders(providerIds, options2) {
|
|
56288
56343
|
const uniqueProviders = Array.from(new Set(providerIds));
|
|
56289
56344
|
const results = [];
|
|
@@ -56337,7 +56392,7 @@ async function cleanupMigratedHooksForProvider(provider, options2) {
|
|
|
56337
56392
|
function resolveProviderPath(pathValue) {
|
|
56338
56393
|
if (!pathValue)
|
|
56339
56394
|
return null;
|
|
56340
|
-
return isAbsolute8(pathValue) ? pathValue :
|
|
56395
|
+
return isAbsolute8(pathValue) ? pathValue : resolve23(process.cwd(), pathValue);
|
|
56341
56396
|
}
|
|
56342
56397
|
var init_migrated_hooks_cleanup = __esm(() => {
|
|
56343
56398
|
init_generated_context_hooks();
|
|
@@ -56702,7 +56757,7 @@ function normalizePortablePath(value) {
|
|
|
56702
56757
|
return "";
|
|
56703
56758
|
return normalized.replace(/^\.\/+/, "");
|
|
56704
56759
|
}
|
|
56705
|
-
function
|
|
56760
|
+
function isAbsoluteLike2(value) {
|
|
56706
56761
|
return path5.isAbsolute(value) || /^[a-zA-Z]:[\\/]/.test(value) || /^\\\\/.test(value);
|
|
56707
56762
|
}
|
|
56708
56763
|
function hasDotDotSegment(value) {
|
|
@@ -57259,7 +57314,7 @@ function detectRenames(input) {
|
|
|
57259
57314
|
const actions = [];
|
|
57260
57315
|
const activeProviderConfigs = dedupeProviderConfigs(input.providerConfigs);
|
|
57261
57316
|
for (const rename10 of applicable) {
|
|
57262
|
-
if (hasDotDotSegment(rename10.from) || hasDotDotSegment(rename10.to) ||
|
|
57317
|
+
if (hasDotDotSegment(rename10.from) || hasDotDotSegment(rename10.to) || isAbsoluteLike2(rename10.from) || isAbsoluteLike2(rename10.to)) {
|
|
57263
57318
|
console.warn(`[!] Skipping suspicious manifest rename: ${rename10.from} -> ${rename10.to}`);
|
|
57264
57319
|
continue;
|
|
57265
57320
|
}
|
|
@@ -57777,7 +57832,7 @@ var init_migration_result_utils = __esm(() => {
|
|
|
57777
57832
|
import { existsSync as existsSync31 } from "node:fs";
|
|
57778
57833
|
import { readFile as readFile27, rm as rm8 } from "node:fs/promises";
|
|
57779
57834
|
import { homedir as homedir28 } from "node:os";
|
|
57780
|
-
import { basename as basename17, join as join47, resolve as
|
|
57835
|
+
import { basename as basename17, join as join47, resolve as resolve24 } from "node:path";
|
|
57781
57836
|
function resolveRegistryDeps(deps) {
|
|
57782
57837
|
return {
|
|
57783
57838
|
...defaultRegistryDeps,
|
|
@@ -57933,8 +57988,8 @@ function parseConfigSource(input) {
|
|
|
57933
57988
|
if (!trimmed) {
|
|
57934
57989
|
return { ok: true, value: undefined };
|
|
57935
57990
|
}
|
|
57936
|
-
const projectSourcePath =
|
|
57937
|
-
const globalSourcePath =
|
|
57991
|
+
const projectSourcePath = resolve24(process.cwd(), "CLAUDE.md");
|
|
57992
|
+
const globalSourcePath = resolve24(getGlobalConfigSourcePath());
|
|
57938
57993
|
const sourceMap = {
|
|
57939
57994
|
default: undefined,
|
|
57940
57995
|
global: globalSourcePath,
|
|
@@ -57945,7 +58000,7 @@ function parseConfigSource(input) {
|
|
|
57945
58000
|
if (normalizedKey in sourceMap) {
|
|
57946
58001
|
return { ok: true, value: sourceMap[normalizedKey] };
|
|
57947
58002
|
}
|
|
57948
|
-
const resolved =
|
|
58003
|
+
const resolved = resolve24(trimmed);
|
|
57949
58004
|
if (resolved === globalSourcePath || resolved === projectSourcePath) {
|
|
57950
58005
|
return { ok: true, value: resolved };
|
|
57951
58006
|
}
|
|
@@ -58013,7 +58068,7 @@ function shouldExecuteAction(action) {
|
|
|
58013
58068
|
}
|
|
58014
58069
|
async function executePlanDeleteAction(action, options2) {
|
|
58015
58070
|
const preservePaths = options2?.preservePaths ?? new Set;
|
|
58016
|
-
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(
|
|
58071
|
+
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve24(action.targetPath));
|
|
58017
58072
|
try {
|
|
58018
58073
|
if (!shouldPreserveTarget && action.targetPath && existsSync31(action.targetPath)) {
|
|
58019
58074
|
await rm8(action.targetPath, { recursive: true, force: true });
|
|
@@ -58038,7 +58093,7 @@ async function executePlanDeleteAction(action, options2) {
|
|
|
58038
58093
|
}
|
|
58039
58094
|
}
|
|
58040
58095
|
function hasSuccessfulReplacementWriteForDelete(action, results) {
|
|
58041
|
-
return results.some((result) => result.success && !result.skipped && result.provider === action.provider && replacementTypeMatchesForDelete(action.type, result.portableType) && replacementItemMatchesForDelete(action, result) && result.path.length > 0 &&
|
|
58096
|
+
return results.some((result) => result.success && !result.skipped && result.provider === action.provider && replacementTypeMatchesForDelete(action.type, result.portableType) && replacementItemMatchesForDelete(action, result) && result.path.length > 0 && resolve24(result.path) !== resolve24(action.targetPath));
|
|
58042
58097
|
}
|
|
58043
58098
|
function replacementTypeMatchesForDelete(actionType, resultType) {
|
|
58044
58099
|
return resultType === actionType || actionType === "command" && resultType === "skill";
|
|
@@ -58986,7 +59041,7 @@ function registerMigrationRoutes(app, deps) {
|
|
|
58986
59041
|
successfulHookFiles2.set(provider, entry);
|
|
58987
59042
|
if (result.path.length > 0) {
|
|
58988
59043
|
const absEntry = successfulHookAbsPaths2.get(provider) ?? [];
|
|
58989
|
-
absEntry.push(
|
|
59044
|
+
absEntry.push(resolve24(result.path));
|
|
58990
59045
|
successfulHookAbsPaths2.set(provider, absEntry);
|
|
58991
59046
|
}
|
|
58992
59047
|
}
|
|
@@ -59035,7 +59090,7 @@ function registerMigrationRoutes(app, deps) {
|
|
|
59035
59090
|
}
|
|
59036
59091
|
}
|
|
59037
59092
|
}
|
|
59038
|
-
const writtenPaths = new Set(allResults.filter((r2) => r2.success && !r2.skipped && r2.path.length > 0).map((r2) =>
|
|
59093
|
+
const writtenPaths = new Set(allResults.filter((r2) => r2.success && !r2.skipped && r2.path.length > 0).map((r2) => resolve24(r2.path)));
|
|
59039
59094
|
for (const deleteAction of deleteActions) {
|
|
59040
59095
|
if (!shouldRunPlanDeleteAction(deleteAction, allResults)) {
|
|
59041
59096
|
const skippedDelete = createSkippedPathMigrationCleanupResult({
|
|
@@ -59084,7 +59139,7 @@ function registerMigrationRoutes(app, deps) {
|
|
|
59084
59139
|
const agentSrc = getAgentSourcePath();
|
|
59085
59140
|
const cmdSrc = getCommandSourcePath();
|
|
59086
59141
|
const skillSrc = getSkillSourcePath();
|
|
59087
|
-
const kitRoot = (agentSrc ?
|
|
59142
|
+
const kitRoot = (agentSrc ? resolve24(agentSrc, "..") : null) ?? (cmdSrc ? resolve24(cmdSrc, "..") : null) ?? (skillSrc ? resolve24(skillSrc, "..") : null) ?? null;
|
|
59088
59143
|
const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
|
|
59089
59144
|
if (manifest?.cliVersion) {
|
|
59090
59145
|
await registryDeps.updateAppliedManifestVersion(manifest.cliVersion);
|
|
@@ -59241,7 +59296,7 @@ function registerMigrationRoutes(app, deps) {
|
|
|
59241
59296
|
successfulHookFiles.set(result.provider, existing);
|
|
59242
59297
|
if (result.path.length > 0) {
|
|
59243
59298
|
const absExisting = successfulHookAbsPaths.get(result.provider) ?? [];
|
|
59244
|
-
absExisting.push(
|
|
59299
|
+
absExisting.push(resolve24(result.path));
|
|
59245
59300
|
successfulHookAbsPaths.set(result.provider, absExisting);
|
|
59246
59301
|
}
|
|
59247
59302
|
}
|
|
@@ -59504,7 +59559,7 @@ var init_plan_metadata = __esm(() => {
|
|
|
59504
59559
|
|
|
59505
59560
|
// src/domains/plan-parser/plan-table-parser.ts
|
|
59506
59561
|
import { readFileSync as readFileSync10 } from "node:fs";
|
|
59507
|
-
import { dirname as dirname18, resolve as
|
|
59562
|
+
import { dirname as dirname18, resolve as resolve25 } from "node:path";
|
|
59508
59563
|
function normalizeStatus(raw) {
|
|
59509
59564
|
const s = raw.toLowerCase().trim();
|
|
59510
59565
|
if (s.includes("complete") || s.includes("done") || s.includes("✓") || s.includes("✅")) {
|
|
@@ -59587,7 +59642,7 @@ function parseHeaderAwareTable(content, dir, options2) {
|
|
|
59587
59642
|
hasLinks = true;
|
|
59588
59643
|
linkText = linkMatch[1].trim();
|
|
59589
59644
|
name = filenameToTitle(linkText);
|
|
59590
|
-
file =
|
|
59645
|
+
file = resolve25(dir, linkMatch[2]);
|
|
59591
59646
|
} else {
|
|
59592
59647
|
name = nameRaw.replace(/\[.*?\]\(.*?\)/g, "").trim() || `Phase ${phaseId}`;
|
|
59593
59648
|
linkText = name;
|
|
@@ -59627,7 +59682,7 @@ function parseFormat1(content, dir, options2) {
|
|
|
59627
59682
|
phaseId,
|
|
59628
59683
|
name: name.trim(),
|
|
59629
59684
|
status: normalizeStatus(status),
|
|
59630
|
-
file:
|
|
59685
|
+
file: resolve25(dir, linkPath),
|
|
59631
59686
|
linkText: linkText.trim(),
|
|
59632
59687
|
anchor
|
|
59633
59688
|
});
|
|
@@ -59647,7 +59702,7 @@ function parseFormat2(content, dir, options2) {
|
|
|
59647
59702
|
phaseId,
|
|
59648
59703
|
name: name.trim(),
|
|
59649
59704
|
status: normalizeStatus(status),
|
|
59650
|
-
file:
|
|
59705
|
+
file: resolve25(dir, linkPath),
|
|
59651
59706
|
linkText,
|
|
59652
59707
|
anchor
|
|
59653
59708
|
});
|
|
@@ -59666,7 +59721,7 @@ function parseFormat2b(content, dir, options2) {
|
|
|
59666
59721
|
phaseId,
|
|
59667
59722
|
name: name.trim(),
|
|
59668
59723
|
status: normalizeStatus(status),
|
|
59669
|
-
file:
|
|
59724
|
+
file: resolve25(dir, linkPath),
|
|
59670
59725
|
linkText: name.trim(),
|
|
59671
59726
|
anchor
|
|
59672
59727
|
});
|
|
@@ -59765,7 +59820,7 @@ function parseFormat4(content, planFilePath, options2) {
|
|
|
59765
59820
|
current = { name, status: hasCheck ? "completed" : "pending" };
|
|
59766
59821
|
} else if (fileMatch && current) {
|
|
59767
59822
|
const planDir = dirname18(planFilePath);
|
|
59768
|
-
current.file =
|
|
59823
|
+
current.file = resolve25(planDir, fileMatch[1].trim());
|
|
59769
59824
|
} else if (statusMatch && current) {
|
|
59770
59825
|
current.status = normalizeStatus(statusMatch[2]);
|
|
59771
59826
|
}
|
|
@@ -59831,7 +59886,7 @@ function parseFormat6(content, dir, options2) {
|
|
|
59831
59886
|
phaseId,
|
|
59832
59887
|
name: phaseName,
|
|
59833
59888
|
status: checked.toLowerCase() === "x" ? "completed" : "pending",
|
|
59834
|
-
file:
|
|
59889
|
+
file: resolve25(dir, linkPath),
|
|
59835
59890
|
linkText: phaseName,
|
|
59836
59891
|
anchor
|
|
59837
59892
|
});
|
|
@@ -59885,7 +59940,7 @@ var init_plan_table_parser = __esm(() => {
|
|
|
59885
59940
|
// src/domains/plan-parser/activity-tracker.ts
|
|
59886
59941
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
59887
59942
|
import { readdirSync as readdirSync5, statSync as statSync8 } from "node:fs";
|
|
59888
|
-
import { join as join48, relative as
|
|
59943
|
+
import { join as join48, relative as relative12 } from "node:path";
|
|
59889
59944
|
function startOfDay(date) {
|
|
59890
59945
|
const copy2 = new Date(date);
|
|
59891
59946
|
copy2.setHours(0, 0, 0, 0);
|
|
@@ -59943,7 +59998,7 @@ function getMtimeSamples(dir, samples) {
|
|
|
59943
59998
|
if (!sample)
|
|
59944
59999
|
continue;
|
|
59945
60000
|
sample.fileModCount += 1;
|
|
59946
|
-
sample.files.add(
|
|
60001
|
+
sample.files.add(relative12(process.cwd(), file));
|
|
59947
60002
|
}
|
|
59948
60003
|
}
|
|
59949
60004
|
function computeLevel(value, max) {
|
|
@@ -60016,13 +60071,13 @@ var init_plan_scanner = () => {};
|
|
|
60016
60071
|
|
|
60017
60072
|
// src/domains/plan-parser/plan-scope.ts
|
|
60018
60073
|
import { homedir as homedir29 } from "node:os";
|
|
60019
|
-
import { isAbsolute as isAbsolute9, join as join50, relative as
|
|
60074
|
+
import { isAbsolute as isAbsolute9, join as join50, relative as relative13, resolve as resolve26 } from "node:path";
|
|
60020
60075
|
function resolveConfiguredDir(configuredPath, baseDir) {
|
|
60021
60076
|
const trimmed = configuredPath?.trim();
|
|
60022
60077
|
if (!trimmed) {
|
|
60023
60078
|
return join50(baseDir, DEFAULT_PLANS_DIRNAME);
|
|
60024
60079
|
}
|
|
60025
|
-
return isAbsolute9(trimmed) ?
|
|
60080
|
+
return isAbsolute9(trimmed) ? resolve26(trimmed) : resolve26(baseDir, trimmed);
|
|
60026
60081
|
}
|
|
60027
60082
|
function resolveProjectPlansDir(projectRoot, config) {
|
|
60028
60083
|
return resolveConfiguredDir(config?.paths?.plans, projectRoot);
|
|
@@ -60034,9 +60089,9 @@ function resolvePlanDirForScope(scope, projectRoot, config) {
|
|
|
60034
60089
|
return scope === "global" ? resolveGlobalPlansDir(config) : resolveProjectPlansDir(projectRoot, config);
|
|
60035
60090
|
}
|
|
60036
60091
|
function isWithinDir(targetPath, baseDir) {
|
|
60037
|
-
const resolvedTarget =
|
|
60038
|
-
const resolvedBase =
|
|
60039
|
-
const relativePath =
|
|
60092
|
+
const resolvedTarget = resolve26(targetPath);
|
|
60093
|
+
const resolvedBase = resolve26(baseDir);
|
|
60094
|
+
const relativePath = relative13(resolvedBase, resolvedTarget);
|
|
60040
60095
|
return relativePath === "" || !relativePath.startsWith("..") && relativePath !== ".." && !isAbsolute9(relativePath);
|
|
60041
60096
|
}
|
|
60042
60097
|
function inferPlanScopeForDir(planDir, config) {
|
|
@@ -60827,7 +60882,7 @@ import {
|
|
|
60827
60882
|
unlinkSync,
|
|
60828
60883
|
writeFileSync as writeFileSync4
|
|
60829
60884
|
} from "node:fs";
|
|
60830
|
-
import { dirname as dirname22, isAbsolute as isAbsolute10, join as join53, parse as parse2, relative as
|
|
60885
|
+
import { dirname as dirname22, isAbsolute as isAbsolute10, join as join53, parse as parse2, relative as relative14, resolve as resolve27 } from "node:path";
|
|
60831
60886
|
function createEmptyRegistry() {
|
|
60832
60887
|
return {
|
|
60833
60888
|
version: 1,
|
|
@@ -60882,8 +60937,8 @@ function migrateFromProjectLocal(cwd2, globalPath) {
|
|
|
60882
60937
|
}
|
|
60883
60938
|
}
|
|
60884
60939
|
function normalizeRegistryDir(cwd2, dir) {
|
|
60885
|
-
const absoluteDir = isAbsolute10(dir) ? dir :
|
|
60886
|
-
const relativeDir =
|
|
60940
|
+
const absoluteDir = isAbsolute10(dir) ? dir : resolve27(cwd2, dir);
|
|
60941
|
+
const relativeDir = relative14(cwd2, absoluteDir) || dir;
|
|
60887
60942
|
return relativeDir.replace(/\\/g, "/");
|
|
60888
60943
|
}
|
|
60889
60944
|
function findProjectRoot(startDir) {
|
|
@@ -61237,24 +61292,24 @@ function pLimit(concurrency) {
|
|
|
61237
61292
|
activeCount--;
|
|
61238
61293
|
resumeNext();
|
|
61239
61294
|
};
|
|
61240
|
-
const run = async (function_,
|
|
61295
|
+
const run = async (function_, resolve28, arguments_) => {
|
|
61241
61296
|
const result = (async () => function_(...arguments_))();
|
|
61242
|
-
|
|
61297
|
+
resolve28(result);
|
|
61243
61298
|
try {
|
|
61244
61299
|
await result;
|
|
61245
61300
|
} catch {}
|
|
61246
61301
|
next();
|
|
61247
61302
|
};
|
|
61248
|
-
const enqueue = (function_,
|
|
61303
|
+
const enqueue = (function_, resolve28, arguments_) => {
|
|
61249
61304
|
new Promise((internalResolve) => {
|
|
61250
61305
|
queue.enqueue(internalResolve);
|
|
61251
|
-
}).then(run.bind(undefined, function_,
|
|
61306
|
+
}).then(run.bind(undefined, function_, resolve28, arguments_));
|
|
61252
61307
|
if (activeCount < concurrency) {
|
|
61253
61308
|
resumeNext();
|
|
61254
61309
|
}
|
|
61255
61310
|
};
|
|
61256
|
-
const generator = (function_, ...arguments_) => new Promise((
|
|
61257
|
-
enqueue(function_,
|
|
61311
|
+
const generator = (function_, ...arguments_) => new Promise((resolve28) => {
|
|
61312
|
+
enqueue(function_, resolve28, arguments_);
|
|
61258
61313
|
});
|
|
61259
61314
|
Object.defineProperties(generator, {
|
|
61260
61315
|
activeCount: {
|
|
@@ -61301,7 +61356,7 @@ var init_p_limit = __esm(() => {
|
|
|
61301
61356
|
// src/domains/web-server/routes/plan-routes.ts
|
|
61302
61357
|
import { existsSync as existsSync37, readFileSync as readFileSync14, realpathSync as realpathSync2 } from "node:fs";
|
|
61303
61358
|
import { homedir as homedir30 } from "node:os";
|
|
61304
|
-
import { basename as basename20, dirname as dirname24, join as join55, relative as
|
|
61359
|
+
import { basename as basename20, dirname as dirname24, join as join55, relative as relative15, resolve as resolve28, sep as sep8 } from "node:path";
|
|
61305
61360
|
function sanitizeError(err) {
|
|
61306
61361
|
if (err instanceof Error) {
|
|
61307
61362
|
if (/^(ENOENT|EACCES|EPERM|EISDIR)/.test(err.message))
|
|
@@ -61316,8 +61371,8 @@ function hasBasePrefix(targetPath, baseDir) {
|
|
|
61316
61371
|
return targetPath === baseDir || targetPath.startsWith(basePrefix);
|
|
61317
61372
|
}
|
|
61318
61373
|
function isWithinBase(targetPath, baseDir) {
|
|
61319
|
-
const resolvedTarget =
|
|
61320
|
-
const resolvedBase =
|
|
61374
|
+
const resolvedTarget = resolve28(targetPath);
|
|
61375
|
+
const resolvedBase = resolve28(baseDir);
|
|
61321
61376
|
const logicalMatch = hasBasePrefix(resolvedTarget, resolvedBase);
|
|
61322
61377
|
if (existsSync37(resolvedTarget)) {
|
|
61323
61378
|
try {
|
|
@@ -61401,7 +61456,7 @@ async function getAllowedRoots(projectId) {
|
|
|
61401
61456
|
roots.push(projectPlansDir);
|
|
61402
61457
|
roots.push(getGlobalPlanRoot());
|
|
61403
61458
|
} catch {}
|
|
61404
|
-
return Array.from(new Set(roots.map((root) =>
|
|
61459
|
+
return Array.from(new Set(roots.map((root) => resolve28(root))));
|
|
61405
61460
|
}
|
|
61406
61461
|
async function isWithinAllowedRoots(targetPath, projectId) {
|
|
61407
61462
|
const allowedRoots = await getAllowedRoots(projectId);
|
|
@@ -61423,7 +61478,7 @@ async function getSafePath(value, kind, res, projectId) {
|
|
|
61423
61478
|
return null;
|
|
61424
61479
|
}
|
|
61425
61480
|
try {
|
|
61426
|
-
return realpathSync2(
|
|
61481
|
+
return realpathSync2(resolve28(value));
|
|
61427
61482
|
} catch {
|
|
61428
61483
|
res.status(403).json({ error: "Cannot resolve path" });
|
|
61429
61484
|
return null;
|
|
@@ -61436,7 +61491,7 @@ function getPlanFilePath(value, res, projectId) {
|
|
|
61436
61491
|
return getSafePath(value, "file", res, projectId);
|
|
61437
61492
|
}
|
|
61438
61493
|
function toProjectPathKey(projectPath) {
|
|
61439
|
-
const resolvedPath =
|
|
61494
|
+
const resolvedPath = resolve28(projectPath);
|
|
61440
61495
|
if (!existsSync37(resolvedPath)) {
|
|
61441
61496
|
return resolvedPath;
|
|
61442
61497
|
}
|
|
@@ -61451,13 +61506,13 @@ function createDiscoveredProjectId(projectPath) {
|
|
|
61451
61506
|
}
|
|
61452
61507
|
function toProjectPlanListItem(summary, plansDir) {
|
|
61453
61508
|
return {
|
|
61454
|
-
file:
|
|
61509
|
+
file: relative15(plansDir, summary.planFile),
|
|
61455
61510
|
name: basename20(dirname24(summary.planFile)),
|
|
61456
61511
|
slug: basename20(dirname24(summary.planFile)),
|
|
61457
61512
|
summary: {
|
|
61458
61513
|
...summary,
|
|
61459
|
-
planDir:
|
|
61460
|
-
planFile:
|
|
61514
|
+
planDir: relative15(plansDir, summary.planDir),
|
|
61515
|
+
planFile: relative15(plansDir, summary.planFile)
|
|
61461
61516
|
}
|
|
61462
61517
|
};
|
|
61463
61518
|
}
|
|
@@ -61507,7 +61562,7 @@ function registerPlanRoutes(app) {
|
|
|
61507
61562
|
return;
|
|
61508
61563
|
try {
|
|
61509
61564
|
const { frontmatter, phases } = parsePlanFile(file);
|
|
61510
|
-
res.json({ file:
|
|
61565
|
+
res.json({ file: relative15(process.cwd(), file), frontmatter, phases });
|
|
61511
61566
|
} catch (err) {
|
|
61512
61567
|
res.status(500).json({ error: sanitizeError(err) });
|
|
61513
61568
|
}
|
|
@@ -61534,17 +61589,17 @@ function registerPlanRoutes(app) {
|
|
|
61534
61589
|
const entries = (await Promise.all(scanPlanDir(dir).map(async (planFile) => await isWithinAllowedRoots(planFile, projectId) ? planFile : null))).filter((planFile) => planFile !== null);
|
|
61535
61590
|
const summaries = buildPlanSummaries(entries.slice(offset, offset + limit));
|
|
61536
61591
|
const plans = summaries.map((summary) => ({
|
|
61537
|
-
file:
|
|
61592
|
+
file: relative15(process.cwd(), summary.planFile),
|
|
61538
61593
|
name: basename20(dirname24(summary.planFile)),
|
|
61539
61594
|
slug: basename20(dirname24(summary.planFile)),
|
|
61540
61595
|
summary: {
|
|
61541
61596
|
...summary,
|
|
61542
|
-
planDir:
|
|
61543
|
-
planFile:
|
|
61597
|
+
planDir: relative15(process.cwd(), summary.planDir),
|
|
61598
|
+
planFile: relative15(process.cwd(), summary.planFile)
|
|
61544
61599
|
}
|
|
61545
61600
|
}));
|
|
61546
61601
|
res.json({
|
|
61547
|
-
dir:
|
|
61602
|
+
dir: relative15(process.cwd(), dir),
|
|
61548
61603
|
total: entries.length,
|
|
61549
61604
|
limit,
|
|
61550
61605
|
offset,
|
|
@@ -61560,7 +61615,7 @@ function registerPlanRoutes(app) {
|
|
|
61560
61615
|
const seenProjectKeys = new Set;
|
|
61561
61616
|
const scanTargets = [];
|
|
61562
61617
|
for (const project of await ProjectsRegistryManager.listProjects()) {
|
|
61563
|
-
if (!existsSync37(
|
|
61618
|
+
if (!existsSync37(resolve28(project.path)))
|
|
61564
61619
|
continue;
|
|
61565
61620
|
const projectKey = toProjectPathKey(project.path);
|
|
61566
61621
|
if (projectKey === globalProjectKey || seenProjectKeys.has(projectKey))
|
|
@@ -61583,7 +61638,7 @@ function registerPlanRoutes(app) {
|
|
|
61583
61638
|
path: project.path
|
|
61584
61639
|
});
|
|
61585
61640
|
}
|
|
61586
|
-
const currentPath =
|
|
61641
|
+
const currentPath = resolve28(process.cwd());
|
|
61587
61642
|
const currentProjectKey = toProjectPathKey(currentPath);
|
|
61588
61643
|
if (isCurrentProjectFallbackCandidate(currentPath, globalProjectKey) && !seenProjectKeys.has(currentProjectKey)) {
|
|
61589
61644
|
scanTargets.push({
|
|
@@ -61672,7 +61727,7 @@ function registerPlanRoutes(app) {
|
|
|
61672
61727
|
const file = await getPlanFilePath(String(req.query.file ?? ""), res, projectId);
|
|
61673
61728
|
if (!file)
|
|
61674
61729
|
return;
|
|
61675
|
-
const dir = req.query.dir ?
|
|
61730
|
+
const dir = req.query.dir ? resolve28(String(req.query.dir)) : null;
|
|
61676
61731
|
if (dir && (!await isWithinAllowedRoots(dir, projectId) || !isWithinBase(file, dir))) {
|
|
61677
61732
|
res.status(403).json({ error: "File must stay within the selected plan directory" });
|
|
61678
61733
|
return;
|
|
@@ -61681,7 +61736,7 @@ function registerPlanRoutes(app) {
|
|
|
61681
61736
|
const raw = readFileSync14(file, "utf8");
|
|
61682
61737
|
const parsed = import_gray_matter10.default(raw);
|
|
61683
61738
|
res.json({
|
|
61684
|
-
file:
|
|
61739
|
+
file: relative15(process.cwd(), file),
|
|
61685
61740
|
frontmatter: parsed.data,
|
|
61686
61741
|
content: parsed.content,
|
|
61687
61742
|
raw
|
|
@@ -61804,7 +61859,7 @@ var init_project_plan_data = __esm(() => {
|
|
|
61804
61859
|
import { existsSync as existsSync38 } from "node:fs";
|
|
61805
61860
|
import { readFile as readFile28 } from "node:fs/promises";
|
|
61806
61861
|
import { homedir as homedir31 } from "node:os";
|
|
61807
|
-
import { basename as basename21, join as join56, resolve as
|
|
61862
|
+
import { basename as basename21, join as join56, resolve as resolve29 } from "node:path";
|
|
61808
61863
|
function registerProjectRoutes(app) {
|
|
61809
61864
|
app.get("/api/projects", async (req, res) => {
|
|
61810
61865
|
try {
|
|
@@ -61916,7 +61971,7 @@ function registerProjectRoutes(app) {
|
|
|
61916
61971
|
} else if (projectPath.startsWith("~\\")) {
|
|
61917
61972
|
projectPath = join56(homedir31(), projectPath.slice(1));
|
|
61918
61973
|
}
|
|
61919
|
-
projectPath =
|
|
61974
|
+
projectPath = resolve29(projectPath);
|
|
61920
61975
|
const homeDir = homedir31();
|
|
61921
61976
|
if (projectPath.includes("..") || !projectPath.startsWith(homeDir)) {
|
|
61922
61977
|
res.status(400).json({ error: "Invalid path after expansion" });
|
|
@@ -62622,7 +62677,7 @@ var init_settings_routes = __esm(() => {
|
|
|
62622
62677
|
// src/domains/skills/skill-catalog-generator.ts
|
|
62623
62678
|
import { mkdir as mkdir14, readFile as readFile30, readdir as readdir15, rename as rename10, stat as stat11, writeFile as writeFile15 } from "node:fs/promises";
|
|
62624
62679
|
import { homedir as homedir34 } from "node:os";
|
|
62625
|
-
import { dirname as dirname25, join as join58, relative as
|
|
62680
|
+
import { dirname as dirname25, join as join58, relative as relative16 } from "node:path";
|
|
62626
62681
|
async function hasScripts(skillPath) {
|
|
62627
62682
|
try {
|
|
62628
62683
|
const entries = await readdir15(skillPath, { withFileTypes: true });
|
|
@@ -62658,7 +62713,7 @@ async function hasReferences(skillPath) {
|
|
|
62658
62713
|
class SkillCatalogGenerator {
|
|
62659
62714
|
async generate(enrichedSkills, basePath) {
|
|
62660
62715
|
const entries = await Promise.all(enrichedSkills.map(async (skill) => {
|
|
62661
|
-
const relPath =
|
|
62716
|
+
const relPath = relative16(basePath, join58(skill.path, "SKILL.md"));
|
|
62662
62717
|
const [scripts, refs] = await Promise.all([
|
|
62663
62718
|
hasScripts(skill.path),
|
|
62664
62719
|
hasReferences(skill.path)
|
|
@@ -63421,10 +63476,10 @@ var init_skills_registry = __esm(() => {
|
|
|
63421
63476
|
import { existsSync as existsSync42 } from "node:fs";
|
|
63422
63477
|
import { cp as cp3, mkdir as mkdir16, readFile as readFile33, rm as rm9, stat as stat12, writeFile as writeFile17 } from "node:fs/promises";
|
|
63423
63478
|
import { homedir as homedir38 } from "node:os";
|
|
63424
|
-
import { dirname as dirname27, join as join62, resolve as
|
|
63479
|
+
import { dirname as dirname27, join as join62, resolve as resolve31 } from "node:path";
|
|
63425
63480
|
function isSamePath2(path1, path22) {
|
|
63426
63481
|
try {
|
|
63427
|
-
return
|
|
63482
|
+
return resolve31(path1) === resolve31(path22);
|
|
63428
63483
|
} catch {
|
|
63429
63484
|
return false;
|
|
63430
63485
|
}
|
|
@@ -63577,10 +63632,10 @@ var init_skills_installer = __esm(() => {
|
|
|
63577
63632
|
// src/commands/skills/skills-uninstaller.ts
|
|
63578
63633
|
import { existsSync as existsSync43 } from "node:fs";
|
|
63579
63634
|
import { rm as rm10 } from "node:fs/promises";
|
|
63580
|
-
import { join as join63, resolve as
|
|
63635
|
+
import { join as join63, resolve as resolve32 } from "node:path";
|
|
63581
63636
|
function isSamePath3(path1, path22) {
|
|
63582
63637
|
try {
|
|
63583
|
-
return
|
|
63638
|
+
return resolve32(path1) === resolve32(path22);
|
|
63584
63639
|
} catch {
|
|
63585
63640
|
return false;
|
|
63586
63641
|
}
|
|
@@ -64518,7 +64573,7 @@ var package_default;
|
|
|
64518
64573
|
var init_package = __esm(() => {
|
|
64519
64574
|
package_default = {
|
|
64520
64575
|
name: "claudekit-cli",
|
|
64521
|
-
version: "4.5.0-dev.
|
|
64576
|
+
version: "4.5.0-dev.8",
|
|
64522
64577
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
64523
64578
|
type: "module",
|
|
64524
64579
|
repository: {
|
|
@@ -65020,7 +65075,7 @@ var init_package_manager_runner = __esm(() => {
|
|
|
65020
65075
|
// src/domains/installation/merger/zombie-wirings-pruner.ts
|
|
65021
65076
|
import { existsSync as existsSync45, readdirSync as readdirSync8 } from "node:fs";
|
|
65022
65077
|
import { homedir as homedir39 } from "node:os";
|
|
65023
|
-
import { basename as basename23, dirname as dirname28, isAbsolute as isAbsolute11, resolve as
|
|
65078
|
+
import { basename as basename23, dirname as dirname28, isAbsolute as isAbsolute11, resolve as resolve33, sep as sep10 } from "node:path";
|
|
65024
65079
|
function pruneZombieEngineerWirings(settings, hookDir, preserveCommands = new Set) {
|
|
65025
65080
|
const pruned = [];
|
|
65026
65081
|
const normalizedPreserveCommands = new Set(Array.from(preserveCommands).map((command) => normalizeCommand(command)));
|
|
@@ -65118,7 +65173,7 @@ function extractHookFilePath(command, hookDir) {
|
|
|
65118
65173
|
const bashMatch = command.match(/^bash\s+["']([^"']+\.sh)["']/);
|
|
65119
65174
|
if (bashMatch) {
|
|
65120
65175
|
const rawPath = bashMatch[1].replace(/\\/g, "/");
|
|
65121
|
-
const resolved = isAbsolute11(rawPath) || /^[A-Za-z]:[\\/]/.test(rawPath) ? rawPath :
|
|
65176
|
+
const resolved = isAbsolute11(rawPath) || /^[A-Za-z]:[\\/]/.test(rawPath) ? rawPath : resolve33(hookDir, rawPath);
|
|
65122
65177
|
return process.platform === "win32" ? resolved.replace(/\//g, sep10) : resolved;
|
|
65123
65178
|
}
|
|
65124
65179
|
return null;
|
|
@@ -65143,7 +65198,7 @@ function extractHookFilePath(command, hookDir) {
|
|
|
65143
65198
|
if (isAbsolute11(tildeResolved) || /^[A-Za-z]:[\\/]/.test(tildeResolved)) {
|
|
65144
65199
|
return process.platform === "win32" ? tildeResolved.replace(/\//g, sep10) : tildeResolved;
|
|
65145
65200
|
}
|
|
65146
|
-
return
|
|
65201
|
+
return resolve33(hookDir, tildeResolved);
|
|
65147
65202
|
}
|
|
65148
65203
|
const unquotedMatch = command.match(/(?:^|\s)node\s+(\S+\.(?:cjs|sh|mjs|js))/);
|
|
65149
65204
|
if (unquotedMatch) {
|
|
@@ -65157,7 +65212,7 @@ function extractHookFilePath(command, hookDir) {
|
|
|
65157
65212
|
if (isAbsolute11(tildeResolved) || /^[A-Za-z]:[\\/]/.test(tildeResolved)) {
|
|
65158
65213
|
return process.platform === "win32" ? tildeResolved.replace(/\//g, sep10) : tildeResolved;
|
|
65159
65214
|
}
|
|
65160
|
-
return
|
|
65215
|
+
return resolve33(hookDir, tildeResolved);
|
|
65161
65216
|
}
|
|
65162
65217
|
return null;
|
|
65163
65218
|
}
|
|
@@ -65180,7 +65235,7 @@ import { spawnSync as spawnSync3 } from "node:child_process";
|
|
|
65180
65235
|
import { existsSync as existsSync46, readFileSync as readFileSync15, readdirSync as readdirSync9, statSync as statSync10, writeFileSync as writeFileSync5 } from "node:fs";
|
|
65181
65236
|
import { readdir as readdir17 } from "node:fs/promises";
|
|
65182
65237
|
import { homedir as homedir40, tmpdir } from "node:os";
|
|
65183
|
-
import { dirname as dirname29, join as join65, resolve as
|
|
65238
|
+
import { dirname as dirname29, join as join65, resolve as resolve34, sep as sep11 } from "node:path";
|
|
65184
65239
|
function resolveDoctorCkExecutable(platformName = process.platform) {
|
|
65185
65240
|
return platformName === "win32" ? "ck.cmd" : "ck";
|
|
65186
65241
|
}
|
|
@@ -65196,8 +65251,8 @@ function parseDoctorCliVersionOutput(output2) {
|
|
|
65196
65251
|
return bareMatch?.[1] ?? null;
|
|
65197
65252
|
}
|
|
65198
65253
|
function getHooksDir(projectDir) {
|
|
65199
|
-
const projectHooksDir =
|
|
65200
|
-
const globalHooksDir =
|
|
65254
|
+
const projectHooksDir = resolve34(projectDir, ".claude", "hooks");
|
|
65255
|
+
const globalHooksDir = resolve34(PathResolver.getGlobalKitDir(), "hooks");
|
|
65201
65256
|
if (existsSync46(projectHooksDir))
|
|
65202
65257
|
return projectHooksDir;
|
|
65203
65258
|
if (existsSync46(globalHooksDir))
|
|
@@ -65205,7 +65260,7 @@ function getHooksDir(projectDir) {
|
|
|
65205
65260
|
return null;
|
|
65206
65261
|
}
|
|
65207
65262
|
function isPathWithin2(filePath, parentDir) {
|
|
65208
|
-
return
|
|
65263
|
+
return resolve34(filePath).startsWith(resolve34(parentDir));
|
|
65209
65264
|
}
|
|
65210
65265
|
function getCanonicalGlobalCommandRoot() {
|
|
65211
65266
|
const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
@@ -65231,23 +65286,23 @@ function getClaudeSettingsFiles(projectDir) {
|
|
|
65231
65286
|
const ccsSettingsDir = join65(process.env.CK_TEST_HOME ?? homedir40(), ".ccs");
|
|
65232
65287
|
const candidates = [
|
|
65233
65288
|
{
|
|
65234
|
-
path:
|
|
65289
|
+
path: resolve34(projectDir, ".claude", "settings.json"),
|
|
65235
65290
|
label: "project settings.json",
|
|
65236
65291
|
root: "$CLAUDE_PROJECT_DIR"
|
|
65237
65292
|
},
|
|
65238
65293
|
{
|
|
65239
|
-
path:
|
|
65294
|
+
path: resolve34(projectDir, ".claude", "settings.local.json"),
|
|
65240
65295
|
label: "project settings.local.json",
|
|
65241
65296
|
root: "$CLAUDE_PROJECT_DIR"
|
|
65242
65297
|
},
|
|
65243
65298
|
{
|
|
65244
|
-
path:
|
|
65299
|
+
path: resolve34(globalClaudeDir, "settings.json"),
|
|
65245
65300
|
label: "global settings.json",
|
|
65246
65301
|
root: getCanonicalGlobalCommandRoot(),
|
|
65247
65302
|
managedHookNames: globalManagedHookNames
|
|
65248
65303
|
},
|
|
65249
65304
|
{
|
|
65250
|
-
path:
|
|
65305
|
+
path: resolve34(globalClaudeDir, "settings.local.json"),
|
|
65251
65306
|
label: "global settings.local.json",
|
|
65252
65307
|
root: getCanonicalGlobalCommandRoot(),
|
|
65253
65308
|
managedHookNames: globalManagedHookNames
|
|
@@ -65258,7 +65313,7 @@ function getClaudeSettingsFiles(projectDir) {
|
|
|
65258
65313
|
if (!dirent.isFile() || !dirent.name.endsWith(".settings.json"))
|
|
65259
65314
|
continue;
|
|
65260
65315
|
candidates.push({
|
|
65261
|
-
path:
|
|
65316
|
+
path: resolve34(ccsSettingsDir, dirent.name),
|
|
65262
65317
|
label: `.ccs/${dirent.name}`,
|
|
65263
65318
|
root: "$HOME"
|
|
65264
65319
|
});
|
|
@@ -65988,7 +66043,7 @@ function resolveHookScriptPath(scriptPath, projectDir) {
|
|
|
65988
66043
|
if (resolved.startsWith(".claude/") || resolved === ".claude") {
|
|
65989
66044
|
resolved = join65(projectDir, resolved);
|
|
65990
66045
|
}
|
|
65991
|
-
return
|
|
66046
|
+
return resolve34(resolved);
|
|
65992
66047
|
}
|
|
65993
66048
|
function collectMissingHookReferences(settings, settingsFile, projectDir) {
|
|
65994
66049
|
const findings = [];
|
|
@@ -66183,10 +66238,10 @@ async function countMissingHookFileReferences(projectDir = process.cwd()) {
|
|
|
66183
66238
|
return count;
|
|
66184
66239
|
}
|
|
66185
66240
|
async function countMissingHookFileReferencesForClaudeDir(claudeDir3, projectRoot = dirname29(claudeDir3)) {
|
|
66186
|
-
const hooksDirPrefix = `${
|
|
66241
|
+
const hooksDirPrefix = `${resolve34(claudeDir3, "hooks")}${sep11}`;
|
|
66187
66242
|
let count = 0;
|
|
66188
66243
|
for (const fileName of ["settings.json", "settings.local.json"]) {
|
|
66189
|
-
const filePath =
|
|
66244
|
+
const filePath = resolve34(claudeDir3, fileName);
|
|
66190
66245
|
if (!existsSync46(filePath))
|
|
66191
66246
|
continue;
|
|
66192
66247
|
const settings = await SettingsMerger.readSettingsFile(filePath);
|
|
@@ -66704,11 +66759,24 @@ This is a bug. Please open an issue at https://github.com/mrgoonie/claudekit-cli
|
|
|
66704
66759
|
// src/domains/installation/plugin/codex-plugin-installer.ts
|
|
66705
66760
|
import { execFile as execFile8 } from "node:child_process";
|
|
66706
66761
|
import { promisify as promisify9 } from "node:util";
|
|
66707
|
-
function resolveCodexExecutable(
|
|
66708
|
-
return
|
|
66762
|
+
function resolveCodexExecutable(_platformName = process.platform) {
|
|
66763
|
+
return "codex";
|
|
66709
66764
|
}
|
|
66710
|
-
function shouldRunCodexInShell(
|
|
66711
|
-
return
|
|
66765
|
+
function shouldRunCodexInShell(_platformName = process.platform) {
|
|
66766
|
+
return false;
|
|
66767
|
+
}
|
|
66768
|
+
function resolveCodexExecutableCandidates(platformName = process.platform) {
|
|
66769
|
+
if (platformName === "win32") {
|
|
66770
|
+
return [
|
|
66771
|
+
{ command: "codex", argsPrefix: [] },
|
|
66772
|
+
{ command: "cmd.exe", argsPrefix: ["/d", "/s", "/c", "codex.cmd"] }
|
|
66773
|
+
];
|
|
66774
|
+
}
|
|
66775
|
+
return [{ command: resolveCodexExecutable(platformName), argsPrefix: [] }];
|
|
66776
|
+
}
|
|
66777
|
+
function isSpawnResolutionError(err) {
|
|
66778
|
+
const code = err?.code;
|
|
66779
|
+
return code === "ENOENT" || code === "EACCES" || code === "EINVAL";
|
|
66712
66780
|
}
|
|
66713
66781
|
|
|
66714
66782
|
class CodexPluginInstaller {
|
|
@@ -66731,24 +66799,41 @@ class CodexPluginInstaller {
|
|
|
66731
66799
|
async marketplaceAdd(source) {
|
|
66732
66800
|
return this.run(["plugin", "marketplace", "add", source], this.opts());
|
|
66733
66801
|
}
|
|
66802
|
+
async marketplaceRemove(name = CK_MARKETPLACE_NAME) {
|
|
66803
|
+
return this.run(["plugin", "marketplace", "remove", name], this.opts());
|
|
66804
|
+
}
|
|
66734
66805
|
async add() {
|
|
66735
66806
|
return this.run(["plugin", "add", `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`], this.opts());
|
|
66736
66807
|
}
|
|
66808
|
+
async remove() {
|
|
66809
|
+
return this.run(["plugin", "remove", `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`], this.opts());
|
|
66810
|
+
}
|
|
66737
66811
|
async listJson() {
|
|
66738
66812
|
return this.run(["plugin", "list", "--json"], this.opts(15000));
|
|
66739
66813
|
}
|
|
66814
|
+
async listText() {
|
|
66815
|
+
return this.run(["plugin", "list"], this.opts(15000));
|
|
66816
|
+
}
|
|
66740
66817
|
async verifyInstalled() {
|
|
66741
66818
|
const r2 = await this.listJson();
|
|
66742
|
-
if (!r2.ok)
|
|
66743
|
-
|
|
66819
|
+
if (!r2.ok) {
|
|
66820
|
+
const text = await this.listText();
|
|
66821
|
+
return text.ok && parseTextPluginList(text.stdout + text.stderr);
|
|
66822
|
+
}
|
|
66744
66823
|
try {
|
|
66745
66824
|
const parsed = JSON.parse(r2.stdout);
|
|
66746
66825
|
return (parsed.installed ?? []).some((plugin) => plugin.pluginId === `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}` && plugin.installed === true && plugin.enabled === true);
|
|
66747
66826
|
} catch {
|
|
66748
|
-
|
|
66827
|
+
const text = await this.listText();
|
|
66828
|
+
return text.ok && parseTextPluginList(text.stdout + text.stderr);
|
|
66749
66829
|
}
|
|
66750
66830
|
}
|
|
66751
66831
|
}
|
|
66832
|
+
function parseTextPluginList(output2) {
|
|
66833
|
+
const pluginId = `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
66834
|
+
const row = new RegExp(`^\\s*${pluginId}\\s+.*\\binstalled\\b.*\\benabled\\b`, "im");
|
|
66835
|
+
return row.test(output2);
|
|
66836
|
+
}
|
|
66752
66837
|
async function installCodexPlugin(opts) {
|
|
66753
66838
|
const installer = opts.installer ?? new CodexPluginInstaller(undefined, opts.codexHome);
|
|
66754
66839
|
if (!await installer.isCodexAvailable() || !await installer.isPluginSupported()) {
|
|
@@ -66780,6 +66865,18 @@ async function installCodexPlugin(opts) {
|
|
|
66780
66865
|
}
|
|
66781
66866
|
return { action: "installed", pluginVerified: true };
|
|
66782
66867
|
}
|
|
66868
|
+
async function removeCodexPlugin(opts = {}) {
|
|
66869
|
+
const installer = opts.installer ?? new CodexPluginInstaller(undefined, opts.codexHome);
|
|
66870
|
+
if (!await installer.isCodexAvailable() || !await installer.isPluginSupported()) {
|
|
66871
|
+
return { removed: false, marketplaceRemoved: false };
|
|
66872
|
+
}
|
|
66873
|
+
const removed = await installer.remove();
|
|
66874
|
+
const marketplaceRemoved = await installer.marketplaceRemove();
|
|
66875
|
+
return {
|
|
66876
|
+
removed: removed.ok,
|
|
66877
|
+
marketplaceRemoved: marketplaceRemoved.ok
|
|
66878
|
+
};
|
|
66879
|
+
}
|
|
66783
66880
|
async function shouldRefreshCodexPlugin(installer = new CodexPluginInstaller) {
|
|
66784
66881
|
if (!await installer.isCodexAvailable() || !await installer.isPluginSupported()) {
|
|
66785
66882
|
return false;
|
|
@@ -66790,23 +66887,32 @@ var execFileAsync6, DEFAULT_TIMEOUT_MS2 = 120000, defaultCodexRunner = async (ar
|
|
|
66790
66887
|
const env2 = { ...process.env };
|
|
66791
66888
|
if (opts?.codexHome)
|
|
66792
66889
|
env2.CODEX_HOME = opts.codexHome;
|
|
66793
|
-
|
|
66794
|
-
|
|
66795
|
-
|
|
66796
|
-
|
|
66797
|
-
|
|
66798
|
-
|
|
66799
|
-
|
|
66800
|
-
|
|
66801
|
-
|
|
66802
|
-
|
|
66803
|
-
|
|
66804
|
-
|
|
66805
|
-
|
|
66806
|
-
|
|
66807
|
-
|
|
66808
|
-
|
|
66890
|
+
let lastError = null;
|
|
66891
|
+
const candidates = resolveCodexExecutableCandidates();
|
|
66892
|
+
for (const [index, candidate] of candidates.entries()) {
|
|
66893
|
+
try {
|
|
66894
|
+
const { stdout, stderr } = await execFileAsync6(candidate.command, [...candidate.argsPrefix, ...args], {
|
|
66895
|
+
env: env2,
|
|
66896
|
+
shell: shouldRunCodexInShell(),
|
|
66897
|
+
timeout: opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS2,
|
|
66898
|
+
maxBuffer: 10 * 1024 * 1024
|
|
66899
|
+
});
|
|
66900
|
+
return { ok: true, stdout: String(stdout), stderr: String(stderr), code: 0 };
|
|
66901
|
+
} catch (err) {
|
|
66902
|
+
lastError = err;
|
|
66903
|
+
if (index < candidates.length - 1 && isSpawnResolutionError(err)) {
|
|
66904
|
+
continue;
|
|
66905
|
+
}
|
|
66906
|
+
break;
|
|
66907
|
+
}
|
|
66809
66908
|
}
|
|
66909
|
+
const e2 = lastError;
|
|
66910
|
+
return {
|
|
66911
|
+
ok: false,
|
|
66912
|
+
stdout: e2?.stdout ? String(e2.stdout) : "",
|
|
66913
|
+
stderr: e2?.stderr ? String(e2.stderr) : e2?.message ?? "",
|
|
66914
|
+
code: typeof e2?.code === "number" ? e2.code : null
|
|
66915
|
+
};
|
|
66810
66916
|
};
|
|
66811
66917
|
var init_codex_plugin_installer = __esm(() => {
|
|
66812
66918
|
init_install_mode_detector();
|
|
@@ -67083,7 +67189,7 @@ var init_claudekit_scanner = __esm(() => {
|
|
|
67083
67189
|
|
|
67084
67190
|
// src/ui/ck-cli-design/tokens.ts
|
|
67085
67191
|
import { homedir as homedir41, platform as platform7 } from "node:os";
|
|
67086
|
-
import { resolve as
|
|
67192
|
+
import { resolve as resolve35, win32 } from "node:path";
|
|
67087
67193
|
function createCliDesignContext(options2 = {}) {
|
|
67088
67194
|
const env2 = options2.env ?? process.env;
|
|
67089
67195
|
const isTTY2 = options2.isTTY ?? process.stdout.isTTY === true;
|
|
@@ -67232,7 +67338,7 @@ function formatCdHint(value, currentPlatform = platform7()) {
|
|
|
67232
67338
|
const absolutePath2 = win32.resolve(value);
|
|
67233
67339
|
return `cd /d "${absolutePath2}"`;
|
|
67234
67340
|
}
|
|
67235
|
-
const absolutePath =
|
|
67341
|
+
const absolutePath = resolve35(value);
|
|
67236
67342
|
const displayPath = formatDisplayPath(absolutePath);
|
|
67237
67343
|
if (displayPath.includes(" ")) {
|
|
67238
67344
|
return `cd "${displayPath}"`;
|
|
@@ -68985,13 +69091,13 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
68985
69091
|
args.push("--beta");
|
|
68986
69092
|
const displayCmd = `ck ${args.join(" ")}`;
|
|
68987
69093
|
logger.info(`Running: ${displayCmd}`);
|
|
68988
|
-
const spawnFn = deps?.spawnInitFn ?? ((spawnArgs) => new Promise((
|
|
69094
|
+
const spawnFn = deps?.spawnInitFn ?? ((spawnArgs) => new Promise((resolve36) => {
|
|
68989
69095
|
const initCommand = resolveCkInitSpawnCommand(spawnArgs);
|
|
68990
69096
|
const child = spawn2(initCommand.command, initCommand.args, { stdio: "inherit" });
|
|
68991
|
-
child.on("close", (code) =>
|
|
69097
|
+
child.on("close", (code) => resolve36(code ?? 1));
|
|
68992
69098
|
child.on("error", (err) => {
|
|
68993
69099
|
logger.verbose(`Failed to spawn ck init: ${err.message}`);
|
|
68994
|
-
|
|
69100
|
+
resolve36(1);
|
|
68995
69101
|
});
|
|
68996
69102
|
}));
|
|
68997
69103
|
const exitCode = await spawnFn(args);
|
|
@@ -69465,7 +69571,7 @@ class ConfigVersionChecker {
|
|
|
69465
69571
|
return null;
|
|
69466
69572
|
}
|
|
69467
69573
|
const delay = baseBackoff * 2 ** attempt;
|
|
69468
|
-
await new Promise((
|
|
69574
|
+
await new Promise((resolve36) => setTimeout(resolve36, delay));
|
|
69469
69575
|
}
|
|
69470
69576
|
}
|
|
69471
69577
|
return null;
|
|
@@ -69571,12 +69677,12 @@ import { readFile as readFile40 } from "node:fs/promises";
|
|
|
69571
69677
|
import { cpus, homedir as homedir42, totalmem } from "node:os";
|
|
69572
69678
|
import { join as join71 } from "node:path";
|
|
69573
69679
|
function runCommand(cmd, args, fallback2) {
|
|
69574
|
-
return new Promise((
|
|
69680
|
+
return new Promise((resolve36) => {
|
|
69575
69681
|
execFile9(cmd, args, { timeout: 5000 }, (err, stdout) => {
|
|
69576
69682
|
if (err) {
|
|
69577
|
-
|
|
69683
|
+
resolve36(fallback2);
|
|
69578
69684
|
} else {
|
|
69579
|
-
|
|
69685
|
+
resolve36(stdout.trim() || fallback2);
|
|
69580
69686
|
}
|
|
69581
69687
|
});
|
|
69582
69688
|
});
|
|
@@ -70013,7 +70119,7 @@ var init_routes = __esm(() => {
|
|
|
70013
70119
|
|
|
70014
70120
|
// src/domains/web-server/static-server.ts
|
|
70015
70121
|
import { existsSync as existsSync50 } from "node:fs";
|
|
70016
|
-
import { basename as basename24, dirname as dirname31, join as join72, resolve as
|
|
70122
|
+
import { basename as basename24, dirname as dirname31, join as join72, resolve as resolve36 } from "node:path";
|
|
70017
70123
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
70018
70124
|
function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
70019
70125
|
if (!runtimePath) {
|
|
@@ -70023,7 +70129,7 @@ function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
|
70023
70129
|
if (!looksLikePath) {
|
|
70024
70130
|
return;
|
|
70025
70131
|
}
|
|
70026
|
-
const entryDir = dirname31(
|
|
70132
|
+
const entryDir = dirname31(resolve36(runtimePath));
|
|
70027
70133
|
if (basename24(entryDir) === "dist") {
|
|
70028
70134
|
candidates.add(join72(entryDir, "ui"));
|
|
70029
70135
|
}
|
|
@@ -71726,7 +71832,7 @@ var require_websocket = __commonJS((exports, module) => {
|
|
|
71726
71832
|
var http = __require("http");
|
|
71727
71833
|
var net2 = __require("net");
|
|
71728
71834
|
var tls = __require("tls");
|
|
71729
|
-
var { randomBytes, createHash:
|
|
71835
|
+
var { randomBytes, createHash: createHash7 } = __require("crypto");
|
|
71730
71836
|
var { Duplex, Readable: Readable2 } = __require("stream");
|
|
71731
71837
|
var { URL: URL2 } = __require("url");
|
|
71732
71838
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -72261,7 +72367,7 @@ var require_websocket = __commonJS((exports, module) => {
|
|
|
72261
72367
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
72262
72368
|
return;
|
|
72263
72369
|
}
|
|
72264
|
-
const digest =
|
|
72370
|
+
const digest = createHash7("sha1").update(key + GUID).digest("base64");
|
|
72265
72371
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
72266
72372
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
72267
72373
|
return;
|
|
@@ -72634,7 +72740,7 @@ var require_websocket_server = __commonJS((exports, module) => {
|
|
|
72634
72740
|
var EventEmitter3 = __require("events");
|
|
72635
72741
|
var http = __require("http");
|
|
72636
72742
|
var { Duplex } = __require("stream");
|
|
72637
|
-
var { createHash:
|
|
72743
|
+
var { createHash: createHash7 } = __require("crypto");
|
|
72638
72744
|
var extension = require_extension();
|
|
72639
72745
|
var PerMessageDeflate = require_permessage_deflate();
|
|
72640
72746
|
var subprotocol = require_subprotocol();
|
|
@@ -72843,7 +72949,7 @@ var require_websocket_server = __commonJS((exports, module) => {
|
|
|
72843
72949
|
}
|
|
72844
72950
|
if (this._state > RUNNING)
|
|
72845
72951
|
return abortHandshake(socket, 503);
|
|
72846
|
-
const digest =
|
|
72952
|
+
const digest = createHash7("sha1").update(key + GUID).digest("base64");
|
|
72847
72953
|
const headers = [
|
|
72848
72954
|
"HTTP/1.1 101 Switching Protocols",
|
|
72849
72955
|
"Upgrade: websocket",
|
|
@@ -73055,10 +73161,10 @@ async function createAppServer(options2 = {}) {
|
|
|
73055
73161
|
wsManager = new WebSocketManager(server);
|
|
73056
73162
|
fileWatcher = new FileWatcher({ wsManager });
|
|
73057
73163
|
fileWatcher.start();
|
|
73058
|
-
await new Promise((
|
|
73164
|
+
await new Promise((resolve37, reject) => {
|
|
73059
73165
|
const onListening = () => {
|
|
73060
73166
|
server.off("error", onError);
|
|
73061
|
-
|
|
73167
|
+
resolve37();
|
|
73062
73168
|
};
|
|
73063
73169
|
const onError = (error) => {
|
|
73064
73170
|
server.off("listening", onListening);
|
|
@@ -73095,16 +73201,16 @@ async function createAppServer(options2 = {}) {
|
|
|
73095
73201
|
};
|
|
73096
73202
|
}
|
|
73097
73203
|
async function closeHttpServer(server) {
|
|
73098
|
-
await new Promise((
|
|
73204
|
+
await new Promise((resolve37) => {
|
|
73099
73205
|
if (!server.listening) {
|
|
73100
|
-
|
|
73206
|
+
resolve37();
|
|
73101
73207
|
return;
|
|
73102
73208
|
}
|
|
73103
73209
|
server.close((err) => {
|
|
73104
73210
|
if (err) {
|
|
73105
73211
|
logger.debug(`Server close error: ${err.message}`);
|
|
73106
73212
|
}
|
|
73107
|
-
|
|
73213
|
+
resolve37();
|
|
73108
73214
|
});
|
|
73109
73215
|
});
|
|
73110
73216
|
}
|
|
@@ -74840,7 +74946,7 @@ var require_picomatch2 = __commonJS((exports, module) => {
|
|
|
74840
74946
|
import { exec as exec7, execFile as execFile10, spawn as spawn4 } from "node:child_process";
|
|
74841
74947
|
import { promisify as promisify15 } from "node:util";
|
|
74842
74948
|
function executeInteractiveScript(command, args, options2) {
|
|
74843
|
-
return new Promise((
|
|
74949
|
+
return new Promise((resolve39, reject) => {
|
|
74844
74950
|
const child = spawn4(command, args, {
|
|
74845
74951
|
stdio: ["ignore", "inherit", "inherit"],
|
|
74846
74952
|
cwd: options2?.cwd,
|
|
@@ -74861,7 +74967,7 @@ function executeInteractiveScript(command, args, options2) {
|
|
|
74861
74967
|
} else if (code !== 0) {
|
|
74862
74968
|
reject(new Error(`Command exited with code ${code}`));
|
|
74863
74969
|
} else {
|
|
74864
|
-
|
|
74970
|
+
resolve39();
|
|
74865
74971
|
}
|
|
74866
74972
|
});
|
|
74867
74973
|
child.on("error", (error) => {
|
|
@@ -75040,7 +75146,7 @@ var init_opencode_installer = __esm(() => {
|
|
|
75040
75146
|
var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CODE_PARTIAL_SUCCESS = 2;
|
|
75041
75147
|
|
|
75042
75148
|
// src/services/package-installer/validators.ts
|
|
75043
|
-
import { resolve as
|
|
75149
|
+
import { resolve as resolve39 } from "node:path";
|
|
75044
75150
|
function validatePackageName(packageName) {
|
|
75045
75151
|
if (!packageName || typeof packageName !== "string") {
|
|
75046
75152
|
throw new Error("Package name must be a non-empty string");
|
|
@@ -75053,8 +75159,8 @@ function validatePackageName(packageName) {
|
|
|
75053
75159
|
}
|
|
75054
75160
|
}
|
|
75055
75161
|
function validateScriptPath(skillsDir2, scriptPath) {
|
|
75056
|
-
const skillsDirResolved =
|
|
75057
|
-
const scriptPathResolved =
|
|
75162
|
+
const skillsDirResolved = resolve39(skillsDir2);
|
|
75163
|
+
const scriptPathResolved = resolve39(scriptPath);
|
|
75058
75164
|
const skillsDirNormalized = isWindows() ? skillsDirResolved.toLowerCase() : skillsDirResolved;
|
|
75059
75165
|
const scriptPathNormalized = isWindows() ? scriptPathResolved.toLowerCase() : scriptPathResolved;
|
|
75060
75166
|
if (!scriptPathNormalized.startsWith(skillsDirNormalized)) {
|
|
@@ -75872,10 +75978,10 @@ __export(exports_agy_mcp_linker, {
|
|
|
75872
75978
|
checkExistingAgyConfig: () => checkExistingAgyConfig,
|
|
75873
75979
|
addAgyToGitignore: () => addAgyToGitignore
|
|
75874
75980
|
});
|
|
75875
|
-
import { resolve as
|
|
75981
|
+
import { resolve as resolve40 } from "node:path";
|
|
75876
75982
|
async function linkAgyMcpConfig(projectDir, options2 = {}) {
|
|
75877
75983
|
const { skipGitignore = false, isGlobal = false } = options2;
|
|
75878
|
-
const resolvedProjectDir =
|
|
75984
|
+
const resolvedProjectDir = resolve40(projectDir);
|
|
75879
75985
|
const agyConfigPath = getAgyMcpConfigPath(resolvedProjectDir, isGlobal);
|
|
75880
75986
|
const mcpConfigPath = findMcpConfigPath(resolvedProjectDir);
|
|
75881
75987
|
if (!mcpConfigPath) {
|
|
@@ -76524,7 +76630,7 @@ var require_get_stream = __commonJS((exports, module) => {
|
|
|
76524
76630
|
};
|
|
76525
76631
|
const { maxBuffer } = options2;
|
|
76526
76632
|
let stream;
|
|
76527
|
-
await new Promise((
|
|
76633
|
+
await new Promise((resolve42, reject) => {
|
|
76528
76634
|
const rejectPromise = (error) => {
|
|
76529
76635
|
if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
|
|
76530
76636
|
error.bufferedData = stream.getBufferedValue();
|
|
@@ -76536,7 +76642,7 @@ var require_get_stream = __commonJS((exports, module) => {
|
|
|
76536
76642
|
rejectPromise(error);
|
|
76537
76643
|
return;
|
|
76538
76644
|
}
|
|
76539
|
-
|
|
76645
|
+
resolve42();
|
|
76540
76646
|
});
|
|
76541
76647
|
stream.on("data", () => {
|
|
76542
76648
|
if (stream.getBufferedLength() > maxBuffer) {
|
|
@@ -77897,7 +78003,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
77897
78003
|
debug("opening", this.zipPath, "with opts", this.opts);
|
|
77898
78004
|
this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
|
|
77899
78005
|
this.canceled = false;
|
|
77900
|
-
return new Promise((
|
|
78006
|
+
return new Promise((resolve42, reject) => {
|
|
77901
78007
|
this.zipfile.on("error", (err) => {
|
|
77902
78008
|
this.canceled = true;
|
|
77903
78009
|
reject(err);
|
|
@@ -77906,7 +78012,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
77906
78012
|
this.zipfile.on("close", () => {
|
|
77907
78013
|
if (!this.canceled) {
|
|
77908
78014
|
debug("zip extraction complete");
|
|
77909
|
-
|
|
78015
|
+
resolve42();
|
|
77910
78016
|
}
|
|
77911
78017
|
});
|
|
77912
78018
|
this.zipfile.on("entry", async (entry) => {
|
|
@@ -78225,7 +78331,7 @@ async function restoreOriginalBranch(branchName, cwd2, issueNumber) {
|
|
|
78225
78331
|
}
|
|
78226
78332
|
}
|
|
78227
78333
|
function spawnAndCollect(command, args, cwd2) {
|
|
78228
|
-
return new Promise((
|
|
78334
|
+
return new Promise((resolve59, reject) => {
|
|
78229
78335
|
const child = spawn5(command, args, { ...cwd2 && { cwd: cwd2 }, stdio: ["ignore", "pipe", "pipe"] });
|
|
78230
78336
|
const chunks = [];
|
|
78231
78337
|
const stderrChunks = [];
|
|
@@ -78238,7 +78344,7 @@ function spawnAndCollect(command, args, cwd2) {
|
|
|
78238
78344
|
reject(new Error(`${command} ${args[0] ?? ""} exited with code ${code2}: ${stderr}`));
|
|
78239
78345
|
return;
|
|
78240
78346
|
}
|
|
78241
|
-
|
|
78347
|
+
resolve59(Buffer.concat(chunks).toString("utf-8"));
|
|
78242
78348
|
});
|
|
78243
78349
|
});
|
|
78244
78350
|
}
|
|
@@ -78422,8 +78528,8 @@ var init_content_validator = __esm(() => {
|
|
|
78422
78528
|
});
|
|
78423
78529
|
|
|
78424
78530
|
// src/commands/content/phases/context-cache-manager.ts
|
|
78425
|
-
import { createHash as
|
|
78426
|
-
import { existsSync as existsSync83, mkdirSync as mkdirSync7, readFileSync as readFileSync23, readdirSync as
|
|
78531
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
78532
|
+
import { existsSync as existsSync83, mkdirSync as mkdirSync7, readFileSync as readFileSync23, readdirSync as readdirSync15, statSync as statSync15 } from "node:fs";
|
|
78427
78533
|
import { rename as rename16, writeFile as writeFile43 } from "node:fs/promises";
|
|
78428
78534
|
import { homedir as homedir54 } from "node:os";
|
|
78429
78535
|
import { basename as basename34, join as join167 } from "node:path";
|
|
@@ -78455,7 +78561,7 @@ async function saveCachedContext(repoPath, cache5) {
|
|
|
78455
78561
|
await rename16(tmpPath, cachePath);
|
|
78456
78562
|
}
|
|
78457
78563
|
function computeSourceHash(repoPath) {
|
|
78458
|
-
const hash =
|
|
78564
|
+
const hash = createHash11("sha256");
|
|
78459
78565
|
const paths = getDocSourcePaths(repoPath);
|
|
78460
78566
|
for (const filePath of paths) {
|
|
78461
78567
|
try {
|
|
@@ -78472,7 +78578,7 @@ function getDocSourcePaths(repoPath) {
|
|
|
78472
78578
|
const docsDir = join167(repoPath, "docs");
|
|
78473
78579
|
if (existsSync83(docsDir)) {
|
|
78474
78580
|
try {
|
|
78475
|
-
const files =
|
|
78581
|
+
const files = readdirSync15(docsDir);
|
|
78476
78582
|
for (const f3 of files) {
|
|
78477
78583
|
if (f3.endsWith(".md"))
|
|
78478
78584
|
paths.push(join167(docsDir, f3));
|
|
@@ -78485,7 +78591,7 @@ function getDocSourcePaths(repoPath) {
|
|
|
78485
78591
|
const stylesDir = join167(repoPath, "assets", "writing-styles");
|
|
78486
78592
|
if (existsSync83(stylesDir)) {
|
|
78487
78593
|
try {
|
|
78488
|
-
const files =
|
|
78594
|
+
const files = readdirSync15(stylesDir);
|
|
78489
78595
|
for (const f3 of files) {
|
|
78490
78596
|
paths.push(join167(stylesDir, f3));
|
|
78491
78597
|
}
|
|
@@ -78495,7 +78601,7 @@ function getDocSourcePaths(repoPath) {
|
|
|
78495
78601
|
}
|
|
78496
78602
|
function getCacheFilePath(repoPath) {
|
|
78497
78603
|
const repoName = basename34(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
78498
|
-
const pathHash =
|
|
78604
|
+
const pathHash = createHash11("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
78499
78605
|
return join167(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
78500
78606
|
}
|
|
78501
78607
|
var CACHE_DIR, CACHE_TTL_MS5;
|
|
@@ -78680,7 +78786,7 @@ function extractContentFromResponse(response) {
|
|
|
78680
78786
|
|
|
78681
78787
|
// src/commands/content/phases/docs-summarizer.ts
|
|
78682
78788
|
import { execSync as execSync7 } from "node:child_process";
|
|
78683
|
-
import { existsSync as existsSync84, readFileSync as readFileSync24, readdirSync as
|
|
78789
|
+
import { existsSync as existsSync84, readFileSync as readFileSync24, readdirSync as readdirSync16 } from "node:fs";
|
|
78684
78790
|
import { join as join168 } from "node:path";
|
|
78685
78791
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
78686
78792
|
const rawContent = collectRawDocs(repoPath);
|
|
@@ -78738,7 +78844,7 @@ function collectRawDocs(repoPath) {
|
|
|
78738
78844
|
const docsDir = join168(repoPath, "docs");
|
|
78739
78845
|
if (existsSync84(docsDir)) {
|
|
78740
78846
|
try {
|
|
78741
|
-
const files =
|
|
78847
|
+
const files = readdirSync16(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
78742
78848
|
for (const f3 of files) {
|
|
78743
78849
|
const content = readCapped(join168(docsDir, f3), 5000);
|
|
78744
78850
|
if (content) {
|
|
@@ -78762,7 +78868,7 @@ ${content}`);
|
|
|
78762
78868
|
const stylesDir = join168(repoPath, "assets", "writing-styles");
|
|
78763
78869
|
if (existsSync84(stylesDir)) {
|
|
78764
78870
|
try {
|
|
78765
|
-
const files =
|
|
78871
|
+
const files = readdirSync16(stylesDir).slice(0, 3);
|
|
78766
78872
|
styles3 = files.map((f3) => readCapped(join168(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
78767
78873
|
|
|
78768
78874
|
`);
|
|
@@ -78953,7 +79059,7 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
78953
79059
|
|
|
78954
79060
|
// src/commands/content/phases/photo-generator.ts
|
|
78955
79061
|
import { execSync as execSync8 } from "node:child_process";
|
|
78956
|
-
import { existsSync as existsSync85, mkdirSync as mkdirSync8, readdirSync as
|
|
79062
|
+
import { existsSync as existsSync85, mkdirSync as mkdirSync8, readdirSync as readdirSync17 } from "node:fs";
|
|
78957
79063
|
import { homedir as homedir55 } from "node:os";
|
|
78958
79064
|
import { join as join169 } from "node:path";
|
|
78959
79065
|
async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
|
|
@@ -78978,7 +79084,7 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
|
|
|
78978
79084
|
return { path: imagePath, ...dimensions, format: "png" };
|
|
78979
79085
|
}
|
|
78980
79086
|
}
|
|
78981
|
-
const files =
|
|
79087
|
+
const files = readdirSync17(mediaDir);
|
|
78982
79088
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
78983
79089
|
if (imageFile) {
|
|
78984
79090
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
@@ -79410,7 +79516,7 @@ function isNoiseCommit(title, author) {
|
|
|
79410
79516
|
|
|
79411
79517
|
// src/commands/content/phases/change-detector.ts
|
|
79412
79518
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
79413
|
-
import { existsSync as existsSync88, readFileSync as readFileSync25, readdirSync as
|
|
79519
|
+
import { existsSync as existsSync88, readFileSync as readFileSync25, readdirSync as readdirSync18, statSync as statSync17 } from "node:fs";
|
|
79414
79520
|
import { join as join171 } from "node:path";
|
|
79415
79521
|
function detectCommits(repo, since) {
|
|
79416
79522
|
try {
|
|
@@ -79526,7 +79632,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
79526
79632
|
const sinceMs = new Date(since).getTime();
|
|
79527
79633
|
const events = [];
|
|
79528
79634
|
try {
|
|
79529
|
-
const entries =
|
|
79635
|
+
const entries = readdirSync18(plansDir, { withFileTypes: true });
|
|
79530
79636
|
for (const entry of entries) {
|
|
79531
79637
|
if (!entry.isDirectory())
|
|
79532
79638
|
continue;
|
|
@@ -79607,7 +79713,7 @@ function classifyCommit(event) {
|
|
|
79607
79713
|
|
|
79608
79714
|
// src/commands/content/phases/repo-discoverer.ts
|
|
79609
79715
|
import { execSync as execSync11 } from "node:child_process";
|
|
79610
|
-
import { readdirSync as
|
|
79716
|
+
import { readdirSync as readdirSync19 } from "node:fs";
|
|
79611
79717
|
import { join as join172 } from "node:path";
|
|
79612
79718
|
function discoverRepos2(cwd2) {
|
|
79613
79719
|
const repos = [];
|
|
@@ -79617,7 +79723,7 @@ function discoverRepos2(cwd2) {
|
|
|
79617
79723
|
repos.push(info);
|
|
79618
79724
|
}
|
|
79619
79725
|
try {
|
|
79620
|
-
const entries =
|
|
79726
|
+
const entries = readdirSync19(cwd2, { withFileTypes: true });
|
|
79621
79727
|
for (const entry of entries) {
|
|
79622
79728
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
79623
79729
|
continue;
|
|
@@ -81085,8 +81191,8 @@ function shouldRunCleanup(lastAt) {
|
|
|
81085
81191
|
return Date.now() - new Date(lastAt).getTime() >= 86400000;
|
|
81086
81192
|
}
|
|
81087
81193
|
function sleep2(ms) {
|
|
81088
|
-
return new Promise((
|
|
81089
|
-
setTimeout(
|
|
81194
|
+
return new Promise((resolve59) => {
|
|
81195
|
+
setTimeout(resolve59, ms);
|
|
81090
81196
|
});
|
|
81091
81197
|
}
|
|
81092
81198
|
var LOCK_DIR2, LOCK_FILE, MAX_CREATION_RETRIES = 3, MAX_PUBLISH_RETRIES_PER_CYCLE = 3, PUBLISH_RETRY_WINDOW_HOURS = 24;
|
|
@@ -82174,6 +82280,10 @@ var init_init_command_help = __esm(() => {
|
|
|
82174
82280
|
flags: "--sync",
|
|
82175
82281
|
description: "Sync config files from upstream with interactive hunk-by-hunk merge"
|
|
82176
82282
|
},
|
|
82283
|
+
{
|
|
82284
|
+
flags: "--install-mode <mode>",
|
|
82285
|
+
description: "Engineer global install mode: auto, plugin, or legacy (default: auto)"
|
|
82286
|
+
},
|
|
82177
82287
|
{
|
|
82178
82288
|
flags: "--archive <path>",
|
|
82179
82289
|
description: "Use local archive file instead of downloading (zip/tar.gz)"
|
|
@@ -83340,7 +83450,7 @@ function getPagerArgs(pagerCmd) {
|
|
|
83340
83450
|
return [];
|
|
83341
83451
|
}
|
|
83342
83452
|
async function trySystemPager(content) {
|
|
83343
|
-
return new Promise((
|
|
83453
|
+
return new Promise((resolve59) => {
|
|
83344
83454
|
const pagerCmd = process.env.PAGER || "less";
|
|
83345
83455
|
const pagerArgs = getPagerArgs(pagerCmd);
|
|
83346
83456
|
try {
|
|
@@ -83350,20 +83460,20 @@ async function trySystemPager(content) {
|
|
|
83350
83460
|
});
|
|
83351
83461
|
const timeout2 = setTimeout(() => {
|
|
83352
83462
|
pager.kill();
|
|
83353
|
-
|
|
83463
|
+
resolve59(false);
|
|
83354
83464
|
}, 30000);
|
|
83355
83465
|
pager.stdin.write(content);
|
|
83356
83466
|
pager.stdin.end();
|
|
83357
83467
|
pager.on("close", (code2) => {
|
|
83358
83468
|
clearTimeout(timeout2);
|
|
83359
|
-
|
|
83469
|
+
resolve59(code2 === 0);
|
|
83360
83470
|
});
|
|
83361
83471
|
pager.on("error", () => {
|
|
83362
83472
|
clearTimeout(timeout2);
|
|
83363
|
-
|
|
83473
|
+
resolve59(false);
|
|
83364
83474
|
});
|
|
83365
83475
|
} catch {
|
|
83366
|
-
|
|
83476
|
+
resolve59(false);
|
|
83367
83477
|
}
|
|
83368
83478
|
});
|
|
83369
83479
|
}
|
|
@@ -83390,16 +83500,16 @@ async function basicPager(content) {
|
|
|
83390
83500
|
break;
|
|
83391
83501
|
}
|
|
83392
83502
|
const remaining = lines.length - currentLine;
|
|
83393
|
-
await new Promise((
|
|
83503
|
+
await new Promise((resolve59) => {
|
|
83394
83504
|
rl.question(`-- More (${remaining} lines) [Enter/q] --`, (answer) => {
|
|
83395
83505
|
if (answer.toLowerCase() === "q") {
|
|
83396
83506
|
rl.close();
|
|
83397
83507
|
process.exitCode = 0;
|
|
83398
|
-
|
|
83508
|
+
resolve59();
|
|
83399
83509
|
return;
|
|
83400
83510
|
}
|
|
83401
83511
|
process.stdout.write("\x1B[1A\x1B[2K");
|
|
83402
|
-
|
|
83512
|
+
resolve59();
|
|
83403
83513
|
});
|
|
83404
83514
|
});
|
|
83405
83515
|
}
|
|
@@ -85314,7 +85424,7 @@ class ClaudekitHttpClient {
|
|
|
85314
85424
|
} catch (error) {
|
|
85315
85425
|
if (error instanceof CkApiError && error.code === "RATE_LIMIT_EXCEEDED" && error.retryAfter) {
|
|
85316
85426
|
const delayMs = error.retryAfter * 1000;
|
|
85317
|
-
await new Promise((
|
|
85427
|
+
await new Promise((resolve6) => setTimeout(resolve6, delayMs));
|
|
85318
85428
|
return fn();
|
|
85319
85429
|
}
|
|
85320
85430
|
throw error;
|
|
@@ -86228,7 +86338,7 @@ function showApiHelp() {
|
|
|
86228
86338
|
}
|
|
86229
86339
|
// src/services/file-operations/destructive-operation-backup-manager.ts
|
|
86230
86340
|
import { readdir as readdir3, stat } from "node:fs/promises";
|
|
86231
|
-
import { basename as basename4, join as join14, resolve as
|
|
86341
|
+
import { basename as basename4, join as join14, resolve as resolve7, sep as sep3 } from "node:path";
|
|
86232
86342
|
|
|
86233
86343
|
// src/services/file-operations/destructive-operation-backup.ts
|
|
86234
86344
|
init_logger();
|
|
@@ -86236,7 +86346,7 @@ init_path_resolver();
|
|
|
86236
86346
|
init_zod();
|
|
86237
86347
|
var import_fs_extra = __toESM(require_lib(), 1);
|
|
86238
86348
|
import { mkdir as mkdir4, readdir as readdir2, readlink, rename as rename2, symlink } from "node:fs/promises";
|
|
86239
|
-
import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute2, join as join13, normalize as normalize2, resolve as
|
|
86349
|
+
import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute2, join as join13, normalize as normalize2, resolve as resolve6, sep as sep2 } from "node:path";
|
|
86240
86350
|
var SNAPSHOT_DIR = "snapshot";
|
|
86241
86351
|
var MANIFEST_FILE = "manifest.json";
|
|
86242
86352
|
function normalizeRelativePath(rootDir, inputPath) {
|
|
@@ -86244,21 +86354,21 @@ function normalizeRelativePath(rootDir, inputPath) {
|
|
|
86244
86354
|
throw new Error(`Unsafe backup path: ${inputPath}`);
|
|
86245
86355
|
}
|
|
86246
86356
|
const normalized = normalize2(inputPath).replaceAll("\\", "/");
|
|
86247
|
-
const resolvedRoot =
|
|
86248
|
-
const resolvedPath =
|
|
86357
|
+
const resolvedRoot = resolve6(rootDir);
|
|
86358
|
+
const resolvedPath = resolve6(rootDir, normalized);
|
|
86249
86359
|
if (normalized === ".." || normalized.startsWith("../") || !resolvedPath.startsWith(`${resolvedRoot}${sep2}`) && resolvedPath !== resolvedRoot) {
|
|
86250
86360
|
throw new Error(`Path escapes installation root: ${inputPath}`);
|
|
86251
86361
|
}
|
|
86252
86362
|
return normalized;
|
|
86253
86363
|
}
|
|
86254
86364
|
function getManagedBackupRoot() {
|
|
86255
|
-
return
|
|
86365
|
+
return resolve6(PathResolver.getConfigDir(false), "backups");
|
|
86256
86366
|
}
|
|
86257
86367
|
async function getExistingRealpath(pathToResolve) {
|
|
86258
86368
|
if (await import_fs_extra.pathExists(pathToResolve)) {
|
|
86259
|
-
return
|
|
86369
|
+
return resolve6(await import_fs_extra.realpath(pathToResolve));
|
|
86260
86370
|
}
|
|
86261
|
-
return
|
|
86371
|
+
return resolve6(pathToResolve);
|
|
86262
86372
|
}
|
|
86263
86373
|
async function assertManagedBackupDir(backupDir) {
|
|
86264
86374
|
const resolvedBackupDir = await getExistingRealpath(backupDir);
|
|
@@ -86303,13 +86413,13 @@ function buildTargets(sourceRoot, deletePaths, mutatePaths) {
|
|
|
86303
86413
|
});
|
|
86304
86414
|
}
|
|
86305
86415
|
async function snapshotItem(sourceRoot, backupDir, target) {
|
|
86306
|
-
const sourcePath =
|
|
86416
|
+
const sourcePath = resolve6(sourceRoot, target.path);
|
|
86307
86417
|
if (!await import_fs_extra.pathExists(sourcePath)) {
|
|
86308
86418
|
return null;
|
|
86309
86419
|
}
|
|
86310
86420
|
const stats = await import_fs_extra.lstat(sourcePath);
|
|
86311
86421
|
if (stats.isSymbolicLink()) {
|
|
86312
|
-
const realTargetPath =
|
|
86422
|
+
const realTargetPath = resolve6(await import_fs_extra.realpath(sourcePath));
|
|
86313
86423
|
const resolvedSourceRoot = await getExistingRealpath(sourceRoot);
|
|
86314
86424
|
if (!realTargetPath.startsWith(`${resolvedSourceRoot}${sep2}`) && realTargetPath !== resolvedSourceRoot) {
|
|
86315
86425
|
throw new Error(`Symlink target escapes installation root: ${target.path}`);
|
|
@@ -86349,7 +86459,7 @@ async function copyDirectorySnapshot(sourceDir, destDir, rootDir) {
|
|
|
86349
86459
|
const sourceEntry = join13(sourceDir, entry.name);
|
|
86350
86460
|
const destEntry = join13(destDir, entry.name);
|
|
86351
86461
|
if (entry.isSymbolicLink()) {
|
|
86352
|
-
const realTargetPath =
|
|
86462
|
+
const realTargetPath = resolve6(await import_fs_extra.realpath(sourceEntry));
|
|
86353
86463
|
const resolvedRoot = await getExistingRealpath(rootDir);
|
|
86354
86464
|
if (!realTargetPath.startsWith(`${resolvedRoot}${sep2}`) && realTargetPath !== resolvedRoot) {
|
|
86355
86465
|
throw new Error(`Nested symlink target escapes installation root: ${sourceEntry}`);
|
|
@@ -86372,10 +86482,10 @@ function buildRestoreTempPath(sourcePath, suffix) {
|
|
|
86372
86482
|
}
|
|
86373
86483
|
async function assertSafeRestoreDestination(targetPath, rootDir) {
|
|
86374
86484
|
const resolvedRoot = await getExistingRealpath(rootDir);
|
|
86375
|
-
const lexicalRoot =
|
|
86485
|
+
const lexicalRoot = resolve6(rootDir);
|
|
86376
86486
|
let currentPath = dirname5(targetPath);
|
|
86377
86487
|
while (true) {
|
|
86378
|
-
const resolvedCurrent =
|
|
86488
|
+
const resolvedCurrent = resolve6(currentPath);
|
|
86379
86489
|
if (!resolvedCurrent.startsWith(`${lexicalRoot}${sep2}`) && resolvedCurrent !== lexicalRoot) {
|
|
86380
86490
|
throw new Error(`Restore target escapes installation root: ${targetPath}`);
|
|
86381
86491
|
}
|
|
@@ -86403,8 +86513,8 @@ async function copySnapshotDirectoryForRestore(snapshotDir, destDir, rootDir) {
|
|
|
86403
86513
|
const destEntry = join13(destDir, entry.name);
|
|
86404
86514
|
if (entry.isSymbolicLink()) {
|
|
86405
86515
|
const linkTarget = await readlink(sourceEntry);
|
|
86406
|
-
const resolvedTarget =
|
|
86407
|
-
const lexicalRoot =
|
|
86516
|
+
const resolvedTarget = resolve6(dirname5(destEntry), linkTarget);
|
|
86517
|
+
const lexicalRoot = resolve6(rootDir);
|
|
86408
86518
|
if (!resolvedTarget.startsWith(`${lexicalRoot}${sep2}`) && resolvedTarget !== lexicalRoot) {
|
|
86409
86519
|
throw new Error(`Nested restore symlink escapes installation root: ${destEntry}`);
|
|
86410
86520
|
}
|
|
@@ -86479,7 +86589,7 @@ async function createDestructiveOperationBackup(request) {
|
|
|
86479
86589
|
version: 1,
|
|
86480
86590
|
operation: request.operation,
|
|
86481
86591
|
createdAt: new Date().toISOString(),
|
|
86482
|
-
sourceRoot:
|
|
86592
|
+
sourceRoot: resolve6(request.sourceRoot),
|
|
86483
86593
|
scope: request.scope,
|
|
86484
86594
|
kit: request.kit,
|
|
86485
86595
|
items,
|
|
@@ -86503,7 +86613,7 @@ async function loadDestructiveOperationBackup(backupDir) {
|
|
|
86503
86613
|
if (!isAbsolute2(manifest.sourceRoot)) {
|
|
86504
86614
|
throw new Error(`Backup manifest source root must be absolute: ${manifest.sourceRoot}`);
|
|
86505
86615
|
}
|
|
86506
|
-
const resolvedSourceRoot =
|
|
86616
|
+
const resolvedSourceRoot = resolve6(manifest.sourceRoot);
|
|
86507
86617
|
for (const item of manifest.items) {
|
|
86508
86618
|
normalizeRelativePath(resolvedSourceRoot, item.path);
|
|
86509
86619
|
const normalizedSnapshotPath = normalizeRelativePath(resolvedBackupDir, item.snapshotPath);
|
|
@@ -86523,8 +86633,8 @@ async function loadDestructiveOperationBackup(backupDir) {
|
|
|
86523
86633
|
async function restoreDestructiveOperationBackup(backup) {
|
|
86524
86634
|
const restorePlans = [];
|
|
86525
86635
|
for (const item of backup.manifest.items) {
|
|
86526
|
-
const sourcePath =
|
|
86527
|
-
const snapshotPath =
|
|
86636
|
+
const sourcePath = resolve6(backup.manifest.sourceRoot, normalizeRelativePath(backup.manifest.sourceRoot, item.path));
|
|
86637
|
+
const snapshotPath = resolve6(backup.backupDir, normalizeRelativePath(backup.backupDir, item.snapshotPath));
|
|
86528
86638
|
try {
|
|
86529
86639
|
await import_fs_extra.lstat(snapshotPath);
|
|
86530
86640
|
} catch {
|
|
@@ -86566,7 +86676,7 @@ init_path_resolver();
|
|
|
86566
86676
|
var import_fs_extra2 = __toESM(require_lib(), 1);
|
|
86567
86677
|
var DEFAULT_DESTRUCTIVE_BACKUP_KEEP_COUNT = 10;
|
|
86568
86678
|
function getBackupsRoot() {
|
|
86569
|
-
return
|
|
86679
|
+
return resolve7(PathResolver.getConfigDir(false), "backups");
|
|
86570
86680
|
}
|
|
86571
86681
|
function validateBackupId(backupId) {
|
|
86572
86682
|
if (!backupId || !/^[A-Za-z0-9._:-]+$/.test(backupId) || backupId.includes("..")) {
|
|
@@ -86576,7 +86686,7 @@ function validateBackupId(backupId) {
|
|
|
86576
86686
|
function resolveBackupDir(backupId) {
|
|
86577
86687
|
validateBackupId(backupId);
|
|
86578
86688
|
const backupsRoot = getBackupsRoot();
|
|
86579
|
-
const backupDir =
|
|
86689
|
+
const backupDir = resolve7(backupsRoot, backupId);
|
|
86580
86690
|
if (!backupDir.startsWith(`${backupsRoot}${sep3}`) && backupDir !== backupsRoot) {
|
|
86581
86691
|
throw new Error(`Backup id escapes backup root: ${backupId}`);
|
|
86582
86692
|
}
|
|
@@ -86949,8 +87059,8 @@ init_logger();
|
|
|
86949
87059
|
init_path_resolver();
|
|
86950
87060
|
var import_fs_extra3 = __toESM(require_lib(), 1);
|
|
86951
87061
|
var import_proper_lockfile5 = __toESM(require_proper_lockfile(), 1);
|
|
86952
|
-
import { createHash as
|
|
86953
|
-
import { join as join16, resolve as
|
|
87062
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
87063
|
+
import { join as join16, resolve as resolve8 } from "node:path";
|
|
86954
87064
|
var LOCK_OPTIONS = {
|
|
86955
87065
|
realpath: false,
|
|
86956
87066
|
retries: { retries: 5, minTimeout: 100, maxTimeout: 1000 },
|
|
@@ -86958,13 +87068,13 @@ var LOCK_OPTIONS = {
|
|
|
86958
87068
|
};
|
|
86959
87069
|
async function getCanonicalInstallationRoot(installationRoot) {
|
|
86960
87070
|
if (await import_fs_extra3.pathExists(installationRoot)) {
|
|
86961
|
-
return
|
|
87071
|
+
return resolve8(await import_fs_extra3.realpath(installationRoot));
|
|
86962
87072
|
}
|
|
86963
|
-
return
|
|
87073
|
+
return resolve8(installationRoot);
|
|
86964
87074
|
}
|
|
86965
87075
|
async function getInstallationStateLockPath(installationRoot) {
|
|
86966
87076
|
const normalizedRoot = await getCanonicalInstallationRoot(installationRoot);
|
|
86967
|
-
const hash =
|
|
87077
|
+
const hash = createHash5("sha256").update(normalizedRoot).digest("hex").slice(0, 16);
|
|
86968
87078
|
return join16(PathResolver.getConfigDir(false), "locks", `installation-${hash}.lock`);
|
|
86969
87079
|
}
|
|
86970
87080
|
async function acquireInstallationStateLock(installationRoot) {
|
|
@@ -87082,7 +87192,7 @@ init_portable_registry();
|
|
|
87082
87192
|
init_provider_registry();
|
|
87083
87193
|
import { existsSync as existsSync10 } from "node:fs";
|
|
87084
87194
|
import { lstat as lstat3, rm as rm2 } from "node:fs/promises";
|
|
87085
|
-
import { basename as basename5, dirname as dirname6, join as join18, relative as
|
|
87195
|
+
import { basename as basename5, dirname as dirname6, join as join18, relative as relative5, resolve as resolve9, sep as sep4 } from "node:path";
|
|
87086
87196
|
var defaultCommandRegistryDeps = {
|
|
87087
87197
|
readPortableRegistry,
|
|
87088
87198
|
removePortableInstallation
|
|
@@ -87094,8 +87204,8 @@ function resolveCommandRegistryDeps(deps) {
|
|
|
87094
87204
|
};
|
|
87095
87205
|
}
|
|
87096
87206
|
function isPathWithinBase(targetPath, basePath) {
|
|
87097
|
-
const resolvedTarget =
|
|
87098
|
-
const resolvedBase =
|
|
87207
|
+
const resolvedTarget = resolve9(targetPath);
|
|
87208
|
+
const resolvedBase = resolve9(basePath);
|
|
87099
87209
|
return resolvedTarget === resolvedBase || resolvedTarget.startsWith(`${resolvedBase}${sep4}`);
|
|
87100
87210
|
}
|
|
87101
87211
|
function isWindowsAbsolutePath2(path3) {
|
|
@@ -87131,8 +87241,8 @@ function getSafeCommandNameSegments(commandName) {
|
|
|
87131
87241
|
}
|
|
87132
87242
|
function isCodexCommandSkillPath(targetPath, basePath) {
|
|
87133
87243
|
const targetDir = dirname6(targetPath);
|
|
87134
|
-
const resolvedTargetDir =
|
|
87135
|
-
const resolvedBase =
|
|
87244
|
+
const resolvedTargetDir = resolve9(targetDir);
|
|
87245
|
+
const resolvedBase = resolve9(basePath);
|
|
87136
87246
|
return basename5(targetPath) === CODEX_COMMAND_SKILL_FILENAME && basename5(targetDir).startsWith("source-command-") && resolvedTargetDir !== resolvedBase && isPathWithinBase(targetDir, basePath);
|
|
87137
87247
|
}
|
|
87138
87248
|
function getCodexLegacyPromptBasePath(basePath) {
|
|
@@ -87171,8 +87281,8 @@ function validateCommandTargetPath(targetPath, basePath) {
|
|
|
87171
87281
|
if (!basePath) {
|
|
87172
87282
|
return "Provider command base path is unavailable";
|
|
87173
87283
|
}
|
|
87174
|
-
const resolvedTarget =
|
|
87175
|
-
const resolvedBase =
|
|
87284
|
+
const resolvedTarget = resolve9(targetPath);
|
|
87285
|
+
const resolvedBase = resolve9(basePath);
|
|
87176
87286
|
if (resolvedTarget === resolvedBase) {
|
|
87177
87287
|
return "Unsafe path: refusing to remove provider command base directory";
|
|
87178
87288
|
}
|
|
@@ -87182,12 +87292,12 @@ function validateCommandTargetPath(targetPath, basePath) {
|
|
|
87182
87292
|
return null;
|
|
87183
87293
|
}
|
|
87184
87294
|
async function validateNoSymlinkComponents2(targetPath, boundaryPath) {
|
|
87185
|
-
const resolvedTarget =
|
|
87186
|
-
const resolvedBoundary =
|
|
87295
|
+
const resolvedTarget = resolve9(targetPath);
|
|
87296
|
+
const resolvedBoundary = resolve9(boundaryPath);
|
|
87187
87297
|
if (!isPathWithinBase(resolvedTarget, resolvedBoundary)) {
|
|
87188
87298
|
return `Unsafe path: target escapes ${resolvedBoundary}`;
|
|
87189
87299
|
}
|
|
87190
|
-
const segments =
|
|
87300
|
+
const segments = relative5(resolvedBoundary, resolvedTarget).split(/[\\/]+/).filter(Boolean);
|
|
87191
87301
|
let cursor = resolvedBoundary;
|
|
87192
87302
|
for (const segment of segments) {
|
|
87193
87303
|
cursor = join18(cursor, segment);
|
|
@@ -87852,12 +87962,12 @@ async function configUICommand(options2 = {}) {
|
|
|
87852
87962
|
console.log();
|
|
87853
87963
|
console.log(import_picocolors15.default.dim(" Press Ctrl+C to stop"));
|
|
87854
87964
|
console.log();
|
|
87855
|
-
await new Promise((
|
|
87965
|
+
await new Promise((resolve37) => {
|
|
87856
87966
|
const shutdown = async () => {
|
|
87857
87967
|
console.log();
|
|
87858
87968
|
logger.info("Shutting down...");
|
|
87859
87969
|
await server.close();
|
|
87860
|
-
|
|
87970
|
+
resolve37();
|
|
87861
87971
|
};
|
|
87862
87972
|
process.on("SIGINT", shutdown);
|
|
87863
87973
|
process.on("SIGTERM", shutdown);
|
|
@@ -87878,12 +87988,12 @@ async function configUICommand(options2 = {}) {
|
|
|
87878
87988
|
}
|
|
87879
87989
|
async function checkPort(port, host) {
|
|
87880
87990
|
const { createServer: createServer2 } = await import("node:net");
|
|
87881
|
-
return new Promise((
|
|
87991
|
+
return new Promise((resolve37) => {
|
|
87882
87992
|
const server = createServer2();
|
|
87883
|
-
server.once("error", () =>
|
|
87993
|
+
server.once("error", () => resolve37(false));
|
|
87884
87994
|
server.once("listening", () => {
|
|
87885
87995
|
server.close();
|
|
87886
|
-
|
|
87996
|
+
resolve37(true);
|
|
87887
87997
|
});
|
|
87888
87998
|
server.listen(port, host);
|
|
87889
87999
|
});
|
|
@@ -89237,13 +89347,13 @@ function checkComponentCounts(setup) {
|
|
|
89237
89347
|
}
|
|
89238
89348
|
// src/domains/health-checks/checkers/skill-budget-checker.ts
|
|
89239
89349
|
init_path_resolver();
|
|
89240
|
-
import { join as join77, resolve as
|
|
89350
|
+
import { join as join77, resolve as resolve37 } from "node:path";
|
|
89241
89351
|
|
|
89242
89352
|
// src/domains/health-checks/checkers/skill-budget-scanner.ts
|
|
89243
89353
|
var import_gray_matter11 = __toESM(require_gray_matter(), 1);
|
|
89244
89354
|
import { existsSync as existsSync55 } from "node:fs";
|
|
89245
89355
|
import { readFile as readFile41, readdir as readdir20 } from "node:fs/promises";
|
|
89246
|
-
import { basename as basename25, join as join76, relative as
|
|
89356
|
+
import { basename as basename25, join as join76, relative as relative17 } from "node:path";
|
|
89247
89357
|
var SKIP_DIRS5 = new Set([".git", ".venv", "__pycache__", "node_modules", "scripts", "common"]);
|
|
89248
89358
|
async function scanSkills2(skillsDir2) {
|
|
89249
89359
|
if (!existsSync55(skillsDir2))
|
|
@@ -89256,7 +89366,7 @@ async function scanSkills2(skillsDir2) {
|
|
|
89256
89366
|
const content = await readFile41(file, "utf8");
|
|
89257
89367
|
const { data } = import_gray_matter11.default(content, { engines: { javascript: { parse: () => ({}) } } });
|
|
89258
89368
|
const rawName = typeof data.name === "string" ? data.name : "";
|
|
89259
|
-
const fallbackId =
|
|
89369
|
+
const fallbackId = relative17(skillsDir2, dir).replace(/\\/g, "/") || basename25(dir);
|
|
89260
89370
|
skills.push({
|
|
89261
89371
|
id: normalizeSkillId(rawName, fallbackId),
|
|
89262
89372
|
description: typeof data.description === "string" ? data.description : "",
|
|
@@ -89356,8 +89466,8 @@ async function applyBudgetDefaults(settingsPath, projectClaudeDir, requiredFract
|
|
|
89356
89466
|
// src/domains/health-checks/checkers/skill-budget-checker.ts
|
|
89357
89467
|
var ENGINEER_SKILL_COUNT_THRESHOLD = 20;
|
|
89358
89468
|
async function checkSkillBudget(setup, projectDir) {
|
|
89359
|
-
const projectClaudeDir =
|
|
89360
|
-
const globalClaudeDir =
|
|
89469
|
+
const projectClaudeDir = resolve37(projectDir, ".claude");
|
|
89470
|
+
const globalClaudeDir = resolve37(PathResolver.getGlobalKitDir());
|
|
89361
89471
|
const projectScopeAliasesGlobal = projectClaudeDir === globalClaudeDir;
|
|
89362
89472
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
89363
89473
|
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join77(projectClaudeDir, "skills")),
|
|
@@ -89757,7 +89867,7 @@ init_path_resolver();
|
|
|
89757
89867
|
import { existsSync as existsSync59 } from "node:fs";
|
|
89758
89868
|
import { readFile as readFile44 } from "node:fs/promises";
|
|
89759
89869
|
import { homedir as homedir43 } from "node:os";
|
|
89760
|
-
import { dirname as dirname32, join as join81, normalize as normalize6, resolve as
|
|
89870
|
+
import { dirname as dirname32, join as join81, normalize as normalize6, resolve as resolve38 } from "node:path";
|
|
89761
89871
|
async function checkPathRefsValid(projectDir) {
|
|
89762
89872
|
const globalClaudeMd = join81(PathResolver.getGlobalKitDir(), "CLAUDE.md");
|
|
89763
89873
|
const projectClaudeMd = join81(projectDir, ".claude", "CLAUDE.md");
|
|
@@ -89804,7 +89914,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
89804
89914
|
} else if (/^[A-Za-z]:/.test(ref)) {
|
|
89805
89915
|
refPath = normalize6(ref);
|
|
89806
89916
|
} else {
|
|
89807
|
-
refPath =
|
|
89917
|
+
refPath = resolve38(baseDir, ref);
|
|
89808
89918
|
}
|
|
89809
89919
|
const normalizedPath = normalize6(refPath);
|
|
89810
89920
|
const isWithinHome = normalizedPath.startsWith(home5);
|
|
@@ -90094,7 +90204,8 @@ async function parseEnvFile(path7) {
|
|
|
90094
90204
|
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
90095
90205
|
value = value.slice(1, -1);
|
|
90096
90206
|
}
|
|
90097
|
-
|
|
90207
|
+
const normalizedKey = key.trim();
|
|
90208
|
+
env2[normalizedKey] = normalizeParsedEnvValue(normalizedKey, value);
|
|
90098
90209
|
}
|
|
90099
90210
|
}
|
|
90100
90211
|
return env2;
|
|
@@ -90103,6 +90214,13 @@ async function parseEnvFile(path7) {
|
|
|
90103
90214
|
return {};
|
|
90104
90215
|
}
|
|
90105
90216
|
}
|
|
90217
|
+
function normalizeParsedEnvValue(key, value) {
|
|
90218
|
+
const trimmed = value.trim();
|
|
90219
|
+
if (key === "GEMINI_API_KEY" || key.startsWith("GEMINI_API_KEY_") || key === "OPENROUTER_API_KEY" || key === "MINIMAX_API_KEY") {
|
|
90220
|
+
return normalizeApiKeyInput(trimmed);
|
|
90221
|
+
}
|
|
90222
|
+
return trimmed;
|
|
90223
|
+
}
|
|
90106
90224
|
async function checkGlobalConfig() {
|
|
90107
90225
|
const globalEnvPath = join83(PathResolver.getGlobalKitDir(), ".env");
|
|
90108
90226
|
if (!await import_fs_extra9.pathExists(globalEnvPath))
|
|
@@ -90166,8 +90284,10 @@ async function runSetupWizard(options2) {
|
|
|
90166
90284
|
f2.warning("Setup cancelled");
|
|
90167
90285
|
return false;
|
|
90168
90286
|
}
|
|
90169
|
-
if (typeof result === "string"
|
|
90170
|
-
|
|
90287
|
+
if (typeof result === "string") {
|
|
90288
|
+
const normalized = normalizeApiKeyInput(result);
|
|
90289
|
+
if (normalized)
|
|
90290
|
+
values[config.key] = normalized;
|
|
90171
90291
|
}
|
|
90172
90292
|
}
|
|
90173
90293
|
const configuredProviders = getConfiguredImageProviders(values);
|
|
@@ -90240,7 +90360,7 @@ async function promptForAdditionalGeminiKeys(primaryKey) {
|
|
|
90240
90360
|
validate: (value) => {
|
|
90241
90361
|
if (!value)
|
|
90242
90362
|
return;
|
|
90243
|
-
const trimmed = value
|
|
90363
|
+
const trimmed = normalizeApiKeyInput(value);
|
|
90244
90364
|
if (!trimmed)
|
|
90245
90365
|
return;
|
|
90246
90366
|
if (!validateApiKey2(trimmed, VALIDATION_PATTERNS.GEMINI_API_KEY)) {
|
|
@@ -90255,12 +90375,12 @@ async function promptForAdditionalGeminiKeys(primaryKey) {
|
|
|
90255
90375
|
if (lD(result)) {
|
|
90256
90376
|
break;
|
|
90257
90377
|
}
|
|
90258
|
-
|
|
90378
|
+
const normalized = typeof result === "string" ? normalizeApiKeyInput(result) : "";
|
|
90379
|
+
if (!normalized) {
|
|
90259
90380
|
break;
|
|
90260
90381
|
}
|
|
90261
|
-
|
|
90262
|
-
|
|
90263
|
-
allKeys.add(trimmedKey);
|
|
90382
|
+
additionalKeys.push(normalized);
|
|
90383
|
+
allKeys.add(normalized);
|
|
90264
90384
|
keyNumber++;
|
|
90265
90385
|
}
|
|
90266
90386
|
return additionalKeys;
|
|
@@ -91314,17 +91434,17 @@ function createDefaultDns() {
|
|
|
91314
91434
|
}
|
|
91315
91435
|
function createDefaultTcp() {
|
|
91316
91436
|
return {
|
|
91317
|
-
connect: ({ host, port, timeoutMs }) => new Promise((
|
|
91437
|
+
connect: ({ host, port, timeoutMs }) => new Promise((resolve39) => {
|
|
91318
91438
|
const start = Date.now();
|
|
91319
91439
|
const socket = net2.createConnection({ host, port });
|
|
91320
91440
|
const timer = setTimeout(() => {
|
|
91321
91441
|
socket.destroy();
|
|
91322
|
-
|
|
91442
|
+
resolve39({ ok: false, layer: "tcp", detail: "timeout", latencyMs: Date.now() - start });
|
|
91323
91443
|
}, timeoutMs);
|
|
91324
91444
|
socket.on("connect", () => {
|
|
91325
91445
|
clearTimeout(timer);
|
|
91326
91446
|
socket.destroy();
|
|
91327
|
-
|
|
91447
|
+
resolve39({
|
|
91328
91448
|
ok: true,
|
|
91329
91449
|
layer: "tcp",
|
|
91330
91450
|
detail: "connected",
|
|
@@ -91333,7 +91453,7 @@ function createDefaultTcp() {
|
|
|
91333
91453
|
});
|
|
91334
91454
|
socket.on("error", (err) => {
|
|
91335
91455
|
clearTimeout(timer);
|
|
91336
|
-
|
|
91456
|
+
resolve39({
|
|
91337
91457
|
ok: false,
|
|
91338
91458
|
layer: "tcp",
|
|
91339
91459
|
detail: err.message,
|
|
@@ -91345,11 +91465,11 @@ function createDefaultTcp() {
|
|
|
91345
91465
|
}
|
|
91346
91466
|
function createDefaultTls() {
|
|
91347
91467
|
return {
|
|
91348
|
-
get: (url, timeoutMs) => new Promise((
|
|
91468
|
+
get: (url, timeoutMs) => new Promise((resolve39) => {
|
|
91349
91469
|
const start = Date.now();
|
|
91350
91470
|
const timer = setTimeout(() => {
|
|
91351
91471
|
req.destroy();
|
|
91352
|
-
|
|
91472
|
+
resolve39({ ok: false, layer: "tls", detail: "timeout", latencyMs: Date.now() - start });
|
|
91353
91473
|
}, timeoutMs);
|
|
91354
91474
|
const req = https.get(url, {
|
|
91355
91475
|
headers: {
|
|
@@ -91361,14 +91481,14 @@ function createDefaultTls() {
|
|
|
91361
91481
|
const status = res.statusCode ?? 0;
|
|
91362
91482
|
const latencyMs = Date.now() - start;
|
|
91363
91483
|
if (status === 200) {
|
|
91364
|
-
|
|
91484
|
+
resolve39({ ok: true, layer: "tls", detail: `HTTP ${status}`, latencyMs });
|
|
91365
91485
|
} else {
|
|
91366
|
-
|
|
91486
|
+
resolve39({ ok: false, layer: "tls", detail: `HTTP ${status}`, latencyMs });
|
|
91367
91487
|
}
|
|
91368
91488
|
});
|
|
91369
91489
|
req.on("error", (err) => {
|
|
91370
91490
|
clearTimeout(timer);
|
|
91371
|
-
|
|
91491
|
+
resolve39({
|
|
91372
91492
|
ok: false,
|
|
91373
91493
|
layer: "tls",
|
|
91374
91494
|
detail: err.message,
|
|
@@ -91489,7 +91609,7 @@ async function checkGitHubReachability(deps) {
|
|
|
91489
91609
|
};
|
|
91490
91610
|
}
|
|
91491
91611
|
function raceTimeout(promise, ms) {
|
|
91492
|
-
return new Promise((
|
|
91612
|
+
return new Promise((resolve39, reject) => {
|
|
91493
91613
|
let settled = false;
|
|
91494
91614
|
const timer = setTimeout(() => {
|
|
91495
91615
|
setImmediate(() => {
|
|
@@ -91504,7 +91624,7 @@ function raceTimeout(promise, ms) {
|
|
|
91504
91624
|
return;
|
|
91505
91625
|
settled = true;
|
|
91506
91626
|
clearTimeout(timer);
|
|
91507
|
-
|
|
91627
|
+
resolve39(v2);
|
|
91508
91628
|
}, (e2) => {
|
|
91509
91629
|
if (settled)
|
|
91510
91630
|
return;
|
|
@@ -92172,13 +92292,13 @@ init_config_version_checker();
|
|
|
92172
92292
|
|
|
92173
92293
|
// src/domains/sync/sync-engine.ts
|
|
92174
92294
|
import { lstat as lstat6, readFile as readFile48, readlink as readlink2, realpath as realpath8, stat as stat14 } from "node:fs/promises";
|
|
92175
|
-
import { isAbsolute as isAbsolute12, join as join89, normalize as normalize8, relative as
|
|
92295
|
+
import { isAbsolute as isAbsolute12, join as join89, normalize as normalize8, relative as relative19 } from "node:path";
|
|
92176
92296
|
|
|
92177
92297
|
// src/services/file-operations/ownership-checker.ts
|
|
92178
92298
|
init_metadata_migration();
|
|
92179
|
-
import { createHash as
|
|
92299
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
92180
92300
|
import { readFile as readFile47, stat as stat13 } from "node:fs/promises";
|
|
92181
|
-
import { relative as
|
|
92301
|
+
import { relative as relative18 } from "node:path";
|
|
92182
92302
|
|
|
92183
92303
|
// src/shared/concurrent-file-ops.ts
|
|
92184
92304
|
init_p_limit();
|
|
@@ -92192,7 +92312,7 @@ async function mapWithLimit(items, fn, concurrency = DEFAULT_CONCURRENCY) {
|
|
|
92192
92312
|
class OwnershipChecker {
|
|
92193
92313
|
static async calculateChecksum(filePath) {
|
|
92194
92314
|
try {
|
|
92195
|
-
return
|
|
92315
|
+
return createHash7("sha256").update(await readFile47(filePath)).digest("hex");
|
|
92196
92316
|
} catch (err) {
|
|
92197
92317
|
const message = err instanceof Error ? err.message : String(err);
|
|
92198
92318
|
throw new Error(operationError("Checksum calculation", filePath, message));
|
|
@@ -92208,7 +92328,7 @@ class OwnershipChecker {
|
|
|
92208
92328
|
if (!metadata || allTrackedFiles.length === 0) {
|
|
92209
92329
|
return { path: filePath, ownership: "user", exists: true };
|
|
92210
92330
|
}
|
|
92211
|
-
const relativePath =
|
|
92331
|
+
const relativePath = relative18(claudeDir3, filePath).replace(/\\/g, "/");
|
|
92212
92332
|
const tracked = allTrackedFiles.find((f3) => f3.path.replace(/\\/g, "/") === relativePath);
|
|
92213
92333
|
if (!tracked) {
|
|
92214
92334
|
return { path: filePath, ownership: "user", exists: true };
|
|
@@ -93389,7 +93509,7 @@ async function validateSymlinkChain(path8, basePath, maxDepth = MAX_SYMLINK_DEPT
|
|
|
93389
93509
|
const target = await readlink2(current);
|
|
93390
93510
|
const resolvedTarget = isAbsolute12(target) ? target : join89(current, "..", target);
|
|
93391
93511
|
const normalizedTarget = normalize8(resolvedTarget);
|
|
93392
|
-
const rel =
|
|
93512
|
+
const rel = relative19(basePath, normalizedTarget);
|
|
93393
93513
|
if (rel.startsWith("..") || isAbsolute12(rel)) {
|
|
93394
93514
|
throw new Error(`Symlink chain escapes base directory at depth ${depth}: ${path8}`);
|
|
93395
93515
|
}
|
|
@@ -93424,7 +93544,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
93424
93544
|
throw new Error(`Path traversal not allowed: ${filePath}`);
|
|
93425
93545
|
}
|
|
93426
93546
|
const fullPath = join89(basePath, normalized);
|
|
93427
|
-
const rel =
|
|
93547
|
+
const rel = relative19(basePath, fullPath);
|
|
93428
93548
|
if (rel.startsWith("..") || isAbsolute12(rel)) {
|
|
93429
93549
|
throw new Error(`Path escapes base directory: ${filePath}`);
|
|
93430
93550
|
}
|
|
@@ -93432,7 +93552,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
93432
93552
|
try {
|
|
93433
93553
|
const resolvedBase = await realpath8(basePath);
|
|
93434
93554
|
const resolvedFull = await realpath8(fullPath);
|
|
93435
|
-
const resolvedRel =
|
|
93555
|
+
const resolvedRel = relative19(resolvedBase, resolvedFull);
|
|
93436
93556
|
if (resolvedRel.startsWith("..") || isAbsolute12(resolvedRel)) {
|
|
93437
93557
|
throw new Error(`Symlink escapes base directory: ${filePath}`);
|
|
93438
93558
|
}
|
|
@@ -93442,7 +93562,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
93442
93562
|
try {
|
|
93443
93563
|
const resolvedBase = await realpath8(basePath);
|
|
93444
93564
|
const resolvedParent = await realpath8(parentPath);
|
|
93445
|
-
const resolvedRel =
|
|
93565
|
+
const resolvedRel = relative19(resolvedBase, resolvedParent);
|
|
93446
93566
|
if (resolvedRel.startsWith("..") || isAbsolute12(resolvedRel)) {
|
|
93447
93567
|
throw new Error(`Parent symlink escapes base directory: ${filePath}`);
|
|
93448
93568
|
}
|
|
@@ -94971,10 +95091,10 @@ init_types3();
|
|
|
94971
95091
|
// src/domains/installation/utils/path-security.ts
|
|
94972
95092
|
init_types3();
|
|
94973
95093
|
import { lstatSync as lstatSync2, realpathSync as realpathSync4 } from "node:fs";
|
|
94974
|
-
import { relative as
|
|
95094
|
+
import { relative as relative20, resolve as resolve41 } from "node:path";
|
|
94975
95095
|
var MAX_EXTRACTION_SIZE = 500 * 1024 * 1024;
|
|
94976
95096
|
function isPathSafe(basePath, targetPath) {
|
|
94977
|
-
const resolvedBase =
|
|
95097
|
+
const resolvedBase = resolve41(basePath);
|
|
94978
95098
|
try {
|
|
94979
95099
|
const stat15 = lstatSync2(targetPath);
|
|
94980
95100
|
if (stat15.isSymbolicLink()) {
|
|
@@ -94984,8 +95104,8 @@ function isPathSafe(basePath, targetPath) {
|
|
|
94984
95104
|
}
|
|
94985
95105
|
}
|
|
94986
95106
|
} catch {}
|
|
94987
|
-
const resolvedTarget =
|
|
94988
|
-
const relativePath =
|
|
95107
|
+
const resolvedTarget = resolve41(targetPath);
|
|
95108
|
+
const relativePath = relative20(resolvedBase, resolvedTarget);
|
|
94989
95109
|
return !relativePath.startsWith("..") && !relativePath.startsWith("/") && resolvedTarget.startsWith(resolvedBase);
|
|
94990
95110
|
}
|
|
94991
95111
|
|
|
@@ -95072,7 +95192,7 @@ class FileDownloader {
|
|
|
95072
95192
|
}
|
|
95073
95193
|
if (downloadedSize !== totalSize) {
|
|
95074
95194
|
fileStream.end();
|
|
95075
|
-
await new Promise((
|
|
95195
|
+
await new Promise((resolve42) => fileStream.once("close", resolve42));
|
|
95076
95196
|
try {
|
|
95077
95197
|
rmSync(destPath, { force: true });
|
|
95078
95198
|
} catch (cleanupError) {
|
|
@@ -95086,7 +95206,7 @@ class FileDownloader {
|
|
|
95086
95206
|
return destPath;
|
|
95087
95207
|
} catch (error) {
|
|
95088
95208
|
fileStream.end();
|
|
95089
|
-
await new Promise((
|
|
95209
|
+
await new Promise((resolve42) => fileStream.once("close", resolve42));
|
|
95090
95210
|
try {
|
|
95091
95211
|
rmSync(destPath, { force: true });
|
|
95092
95212
|
} catch (cleanupError) {
|
|
@@ -95152,7 +95272,7 @@ class FileDownloader {
|
|
|
95152
95272
|
const expectedSize = Number(response.headers.get("content-length"));
|
|
95153
95273
|
if (expectedSize > 0 && downloadedSize !== expectedSize) {
|
|
95154
95274
|
fileStream.end();
|
|
95155
|
-
await new Promise((
|
|
95275
|
+
await new Promise((resolve42) => fileStream.once("close", resolve42));
|
|
95156
95276
|
try {
|
|
95157
95277
|
rmSync(destPath, { force: true });
|
|
95158
95278
|
} catch (cleanupError) {
|
|
@@ -95170,7 +95290,7 @@ class FileDownloader {
|
|
|
95170
95290
|
return destPath;
|
|
95171
95291
|
} catch (error) {
|
|
95172
95292
|
fileStream.end();
|
|
95173
|
-
await new Promise((
|
|
95293
|
+
await new Promise((resolve42) => fileStream.once("close", resolve42));
|
|
95174
95294
|
try {
|
|
95175
95295
|
rmSync(destPath, { force: true });
|
|
95176
95296
|
} catch (cleanupError) {
|
|
@@ -95789,10 +95909,10 @@ class Minipass extends EventEmitter3 {
|
|
|
95789
95909
|
return this[ENCODING] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
95790
95910
|
}
|
|
95791
95911
|
async promise() {
|
|
95792
|
-
return new Promise((
|
|
95912
|
+
return new Promise((resolve42, reject) => {
|
|
95793
95913
|
this.on(DESTROYED, () => reject(new Error("stream destroyed")));
|
|
95794
95914
|
this.on("error", (er) => reject(er));
|
|
95795
|
-
this.on("end", () =>
|
|
95915
|
+
this.on("end", () => resolve42());
|
|
95796
95916
|
});
|
|
95797
95917
|
}
|
|
95798
95918
|
[Symbol.asyncIterator]() {
|
|
@@ -95811,7 +95931,7 @@ class Minipass extends EventEmitter3 {
|
|
|
95811
95931
|
return Promise.resolve({ done: false, value: res });
|
|
95812
95932
|
if (this[EOF])
|
|
95813
95933
|
return stop();
|
|
95814
|
-
let
|
|
95934
|
+
let resolve42;
|
|
95815
95935
|
let reject;
|
|
95816
95936
|
const onerr = (er) => {
|
|
95817
95937
|
this.off("data", ondata);
|
|
@@ -95825,19 +95945,19 @@ class Minipass extends EventEmitter3 {
|
|
|
95825
95945
|
this.off("end", onend);
|
|
95826
95946
|
this.off(DESTROYED, ondestroy);
|
|
95827
95947
|
this.pause();
|
|
95828
|
-
|
|
95948
|
+
resolve42({ value, done: !!this[EOF] });
|
|
95829
95949
|
};
|
|
95830
95950
|
const onend = () => {
|
|
95831
95951
|
this.off("error", onerr);
|
|
95832
95952
|
this.off("data", ondata);
|
|
95833
95953
|
this.off(DESTROYED, ondestroy);
|
|
95834
95954
|
stop();
|
|
95835
|
-
|
|
95955
|
+
resolve42({ done: true, value: undefined });
|
|
95836
95956
|
};
|
|
95837
95957
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
95838
95958
|
return new Promise((res2, rej) => {
|
|
95839
95959
|
reject = rej;
|
|
95840
|
-
|
|
95960
|
+
resolve42 = res2;
|
|
95841
95961
|
this.once(DESTROYED, ondestroy);
|
|
95842
95962
|
this.once("error", onerr);
|
|
95843
95963
|
this.once("end", onend);
|
|
@@ -96943,10 +97063,10 @@ class Minipass2 extends EventEmitter4 {
|
|
|
96943
97063
|
return this[ENCODING2] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
96944
97064
|
}
|
|
96945
97065
|
async promise() {
|
|
96946
|
-
return new Promise((
|
|
97066
|
+
return new Promise((resolve42, reject) => {
|
|
96947
97067
|
this.on(DESTROYED2, () => reject(new Error("stream destroyed")));
|
|
96948
97068
|
this.on("error", (er) => reject(er));
|
|
96949
|
-
this.on("end", () =>
|
|
97069
|
+
this.on("end", () => resolve42());
|
|
96950
97070
|
});
|
|
96951
97071
|
}
|
|
96952
97072
|
[Symbol.asyncIterator]() {
|
|
@@ -96965,7 +97085,7 @@ class Minipass2 extends EventEmitter4 {
|
|
|
96965
97085
|
return Promise.resolve({ done: false, value: res });
|
|
96966
97086
|
if (this[EOF2])
|
|
96967
97087
|
return stop();
|
|
96968
|
-
let
|
|
97088
|
+
let resolve42;
|
|
96969
97089
|
let reject;
|
|
96970
97090
|
const onerr = (er) => {
|
|
96971
97091
|
this.off("data", ondata);
|
|
@@ -96979,19 +97099,19 @@ class Minipass2 extends EventEmitter4 {
|
|
|
96979
97099
|
this.off("end", onend);
|
|
96980
97100
|
this.off(DESTROYED2, ondestroy);
|
|
96981
97101
|
this.pause();
|
|
96982
|
-
|
|
97102
|
+
resolve42({ value, done: !!this[EOF2] });
|
|
96983
97103
|
};
|
|
96984
97104
|
const onend = () => {
|
|
96985
97105
|
this.off("error", onerr);
|
|
96986
97106
|
this.off("data", ondata);
|
|
96987
97107
|
this.off(DESTROYED2, ondestroy);
|
|
96988
97108
|
stop();
|
|
96989
|
-
|
|
97109
|
+
resolve42({ done: true, value: undefined });
|
|
96990
97110
|
};
|
|
96991
97111
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
96992
97112
|
return new Promise((res2, rej) => {
|
|
96993
97113
|
reject = rej;
|
|
96994
|
-
|
|
97114
|
+
resolve42 = res2;
|
|
96995
97115
|
this.once(DESTROYED2, ondestroy);
|
|
96996
97116
|
this.once("error", onerr);
|
|
96997
97117
|
this.once("end", onend);
|
|
@@ -98419,10 +98539,10 @@ class Minipass3 extends EventEmitter5 {
|
|
|
98419
98539
|
return this[ENCODING3] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
98420
98540
|
}
|
|
98421
98541
|
async promise() {
|
|
98422
|
-
return new Promise((
|
|
98542
|
+
return new Promise((resolve42, reject) => {
|
|
98423
98543
|
this.on(DESTROYED3, () => reject(new Error("stream destroyed")));
|
|
98424
98544
|
this.on("error", (er) => reject(er));
|
|
98425
|
-
this.on("end", () =>
|
|
98545
|
+
this.on("end", () => resolve42());
|
|
98426
98546
|
});
|
|
98427
98547
|
}
|
|
98428
98548
|
[Symbol.asyncIterator]() {
|
|
@@ -98441,7 +98561,7 @@ class Minipass3 extends EventEmitter5 {
|
|
|
98441
98561
|
return Promise.resolve({ done: false, value: res });
|
|
98442
98562
|
if (this[EOF3])
|
|
98443
98563
|
return stop();
|
|
98444
|
-
let
|
|
98564
|
+
let resolve42;
|
|
98445
98565
|
let reject;
|
|
98446
98566
|
const onerr = (er) => {
|
|
98447
98567
|
this.off("data", ondata);
|
|
@@ -98455,19 +98575,19 @@ class Minipass3 extends EventEmitter5 {
|
|
|
98455
98575
|
this.off("end", onend);
|
|
98456
98576
|
this.off(DESTROYED3, ondestroy);
|
|
98457
98577
|
this.pause();
|
|
98458
|
-
|
|
98578
|
+
resolve42({ value, done: !!this[EOF3] });
|
|
98459
98579
|
};
|
|
98460
98580
|
const onend = () => {
|
|
98461
98581
|
this.off("error", onerr);
|
|
98462
98582
|
this.off("data", ondata);
|
|
98463
98583
|
this.off(DESTROYED3, ondestroy);
|
|
98464
98584
|
stop();
|
|
98465
|
-
|
|
98585
|
+
resolve42({ done: true, value: undefined });
|
|
98466
98586
|
};
|
|
98467
98587
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
98468
98588
|
return new Promise((res2, rej) => {
|
|
98469
98589
|
reject = rej;
|
|
98470
|
-
|
|
98590
|
+
resolve42 = res2;
|
|
98471
98591
|
this.once(DESTROYED3, ondestroy);
|
|
98472
98592
|
this.once("error", onerr);
|
|
98473
98593
|
this.once("end", onend);
|
|
@@ -99238,9 +99358,9 @@ var listFile = (opt, _files) => {
|
|
|
99238
99358
|
const parse5 = new Parser(opt);
|
|
99239
99359
|
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
|
|
99240
99360
|
const file = opt.file;
|
|
99241
|
-
const p = new Promise((
|
|
99361
|
+
const p = new Promise((resolve42, reject) => {
|
|
99242
99362
|
parse5.on("error", reject);
|
|
99243
|
-
parse5.on("end",
|
|
99363
|
+
parse5.on("end", resolve42);
|
|
99244
99364
|
fs10.stat(file, (er, stat15) => {
|
|
99245
99365
|
if (er) {
|
|
99246
99366
|
reject(er);
|
|
@@ -101820,9 +101940,9 @@ var extractFile = (opt, _3) => {
|
|
|
101820
101940
|
const u = new Unpack(opt);
|
|
101821
101941
|
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
|
|
101822
101942
|
const file = opt.file;
|
|
101823
|
-
const p = new Promise((
|
|
101943
|
+
const p = new Promise((resolve42, reject) => {
|
|
101824
101944
|
u.on("error", reject);
|
|
101825
|
-
u.on("close",
|
|
101945
|
+
u.on("close", resolve42);
|
|
101826
101946
|
fs17.stat(file, (er, stat15) => {
|
|
101827
101947
|
if (er) {
|
|
101828
101948
|
reject(er);
|
|
@@ -101955,7 +102075,7 @@ var replaceAsync = (opt, files) => {
|
|
|
101955
102075
|
};
|
|
101956
102076
|
fs18.read(fd, headBuf, 0, 512, position, onread);
|
|
101957
102077
|
};
|
|
101958
|
-
const promise = new Promise((
|
|
102078
|
+
const promise = new Promise((resolve42, reject) => {
|
|
101959
102079
|
p.on("error", reject);
|
|
101960
102080
|
let flag = "r+";
|
|
101961
102081
|
const onopen = (er, fd) => {
|
|
@@ -101980,7 +102100,7 @@ var replaceAsync = (opt, files) => {
|
|
|
101980
102100
|
});
|
|
101981
102101
|
p.pipe(stream);
|
|
101982
102102
|
stream.on("error", reject);
|
|
101983
|
-
stream.on("close",
|
|
102103
|
+
stream.on("close", resolve42);
|
|
101984
102104
|
addFilesAsync2(p, files);
|
|
101985
102105
|
});
|
|
101986
102106
|
});
|
|
@@ -102110,7 +102230,7 @@ function decodeFilePath(path15) {
|
|
|
102110
102230
|
init_logger();
|
|
102111
102231
|
init_types3();
|
|
102112
102232
|
import { copyFile as copyFile3, lstat as lstat7, mkdir as mkdir27, readdir as readdir24 } from "node:fs/promises";
|
|
102113
|
-
import { join as join102, relative as
|
|
102233
|
+
import { join as join102, relative as relative21 } from "node:path";
|
|
102114
102234
|
async function withRetry(fn, retries = 3) {
|
|
102115
102235
|
for (let i = 0;i < retries; i++) {
|
|
102116
102236
|
try {
|
|
@@ -102134,7 +102254,7 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
|
|
|
102134
102254
|
for (const entry of entries) {
|
|
102135
102255
|
const sourcePath = join102(sourceDir, entry);
|
|
102136
102256
|
const destPath = join102(destDir, entry);
|
|
102137
|
-
const relativePath =
|
|
102257
|
+
const relativePath = relative21(sourceDir, sourcePath);
|
|
102138
102258
|
if (!isPathSafe(destDir, destPath)) {
|
|
102139
102259
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
102140
102260
|
throw new ExtractionError(`Path traversal attempt detected: ${relativePath}`);
|
|
@@ -102162,7 +102282,7 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
|
102162
102282
|
for (const entry of entries) {
|
|
102163
102283
|
const sourcePath = join102(sourceDir, entry);
|
|
102164
102284
|
const destPath = join102(destDir, entry);
|
|
102165
|
-
const relativePath =
|
|
102285
|
+
const relativePath = relative21(sourceDir, sourcePath);
|
|
102166
102286
|
if (!isPathSafe(destDir, destPath)) {
|
|
102167
102287
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
102168
102288
|
throw new ExtractionError(`Path traversal attempt detected: ${relativePath}`);
|
|
@@ -102937,7 +103057,7 @@ import { join as join123 } from "node:path";
|
|
|
102937
103057
|
|
|
102938
103058
|
// src/domains/installation/deletion-handler.ts
|
|
102939
103059
|
import { existsSync as existsSync66, lstatSync as lstatSync3, readdirSync as readdirSync10, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync4 } from "node:fs";
|
|
102940
|
-
import { dirname as dirname38, join as join108, relative as
|
|
103060
|
+
import { dirname as dirname38, join as join108, relative as relative22, resolve as resolve43, sep as sep12 } from "node:path";
|
|
102941
103061
|
|
|
102942
103062
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
102943
103063
|
init_metadata_migration();
|
|
@@ -103133,7 +103253,7 @@ function collectFilesRecursively(dir, baseDir) {
|
|
|
103133
103253
|
const entries = readdirSync10(dir, { withFileTypes: true });
|
|
103134
103254
|
for (const entry of entries) {
|
|
103135
103255
|
const fullPath = join108(dir, entry.name);
|
|
103136
|
-
const relativePath =
|
|
103256
|
+
const relativePath = relative22(baseDir, fullPath);
|
|
103137
103257
|
if (entry.isDirectory()) {
|
|
103138
103258
|
results.push(...collectFilesRecursively(fullPath, baseDir));
|
|
103139
103259
|
} else {
|
|
@@ -103162,8 +103282,8 @@ function expandGlobPatterns(patterns, claudeDir3) {
|
|
|
103162
103282
|
}
|
|
103163
103283
|
var MAX_CLEANUP_ITERATIONS = 50;
|
|
103164
103284
|
function cleanupEmptyDirectories(filePath, claudeDir3) {
|
|
103165
|
-
const normalizedClaudeDir =
|
|
103166
|
-
let currentDir =
|
|
103285
|
+
const normalizedClaudeDir = resolve43(claudeDir3);
|
|
103286
|
+
let currentDir = resolve43(dirname38(filePath));
|
|
103167
103287
|
let iterations = 0;
|
|
103168
103288
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir) && iterations < MAX_CLEANUP_ITERATIONS) {
|
|
103169
103289
|
iterations++;
|
|
@@ -103172,7 +103292,7 @@ function cleanupEmptyDirectories(filePath, claudeDir3) {
|
|
|
103172
103292
|
if (entries.length === 0) {
|
|
103173
103293
|
rmdirSync(currentDir);
|
|
103174
103294
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
103175
|
-
currentDir =
|
|
103295
|
+
currentDir = resolve43(dirname38(currentDir));
|
|
103176
103296
|
} else {
|
|
103177
103297
|
break;
|
|
103178
103298
|
}
|
|
@@ -103182,8 +103302,8 @@ function cleanupEmptyDirectories(filePath, claudeDir3) {
|
|
|
103182
103302
|
}
|
|
103183
103303
|
}
|
|
103184
103304
|
function deletePath(fullPath, claudeDir3) {
|
|
103185
|
-
const normalizedPath =
|
|
103186
|
-
const normalizedClaudeDir =
|
|
103305
|
+
const normalizedPath = resolve43(fullPath);
|
|
103306
|
+
const normalizedClaudeDir = resolve43(claudeDir3);
|
|
103187
103307
|
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep12}`) && normalizedPath !== normalizedClaudeDir) {
|
|
103188
103308
|
throw new Error(`Path traversal detected: ${fullPath}`);
|
|
103189
103309
|
}
|
|
@@ -103256,8 +103376,8 @@ async function handleDeletions(sourceMetadata, claudeDir3, kitType) {
|
|
|
103256
103376
|
const result = { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
103257
103377
|
for (const path16 of deletions) {
|
|
103258
103378
|
const fullPath = join108(claudeDir3, path16);
|
|
103259
|
-
const normalizedPath =
|
|
103260
|
-
const normalizedClaudeDir =
|
|
103379
|
+
const normalizedPath = resolve43(fullPath);
|
|
103380
|
+
const normalizedClaudeDir = resolve43(claudeDir3);
|
|
103261
103381
|
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep12}`)) {
|
|
103262
103382
|
logger.warning(`Skipping invalid path: ${path16}`);
|
|
103263
103383
|
result.errors.push(path16);
|
|
@@ -103295,7 +103415,7 @@ init_logger();
|
|
|
103295
103415
|
init_types3();
|
|
103296
103416
|
var import_fs_extra16 = __toESM(require_lib(), 1);
|
|
103297
103417
|
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
103298
|
-
import { dirname as dirname42, join as join113, relative as
|
|
103418
|
+
import { dirname as dirname42, join as join113, relative as relative25 } from "node:path";
|
|
103299
103419
|
|
|
103300
103420
|
// src/domains/installation/selective-merger.ts
|
|
103301
103421
|
import { stat as stat18 } from "node:fs/promises";
|
|
@@ -103471,7 +103591,7 @@ class SelectiveMerger {
|
|
|
103471
103591
|
|
|
103472
103592
|
// src/domains/installation/merger/deleted-skill-preservation.ts
|
|
103473
103593
|
init_metadata_migration();
|
|
103474
|
-
import { dirname as dirname39, join as join109, relative as
|
|
103594
|
+
import { dirname as dirname39, join as join109, relative as relative23 } from "node:path";
|
|
103475
103595
|
var import_fs_extra13 = __toESM(require_lib(), 1);
|
|
103476
103596
|
async function findIgnoredSkillDirectories({
|
|
103477
103597
|
files,
|
|
@@ -103516,7 +103636,7 @@ function shouldSkipIgnoredSkill(normalizedRelativePath, ignoredSkillDirectories)
|
|
|
103516
103636
|
function findSourceSkillRoots(files, sourceDir) {
|
|
103517
103637
|
const sourceSkillRoots = new Map;
|
|
103518
103638
|
for (const file of files) {
|
|
103519
|
-
const normalizedPath =
|
|
103639
|
+
const normalizedPath = relative23(sourceDir, file).replace(/\\/g, "/");
|
|
103520
103640
|
const metadataPath = toMetadataPath(normalizedPath);
|
|
103521
103641
|
if (!metadataPath?.endsWith("/SKILL.md"))
|
|
103522
103642
|
continue;
|
|
@@ -103548,7 +103668,7 @@ function findSkillRoot(path16, skillRoots) {
|
|
|
103548
103668
|
init_logger();
|
|
103549
103669
|
var import_fs_extra14 = __toESM(require_lib(), 1);
|
|
103550
103670
|
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
103551
|
-
import { relative as
|
|
103671
|
+
import { relative as relative24 } from "node:path";
|
|
103552
103672
|
import { join as join110 } from "node:path";
|
|
103553
103673
|
|
|
103554
103674
|
// node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
@@ -105006,7 +105126,7 @@ class FileScanner {
|
|
|
105006
105126
|
const entries = await import_fs_extra14.readdir(dir, { encoding: "utf8" });
|
|
105007
105127
|
for (const entry of entries) {
|
|
105008
105128
|
const fullPath = join110(dir, entry);
|
|
105009
|
-
const relativePath =
|
|
105129
|
+
const relativePath = relative24(baseDir, fullPath);
|
|
105010
105130
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
105011
105131
|
const stats = await import_fs_extra14.lstat(fullPath);
|
|
105012
105132
|
if (stats.isSymbolicLink()) {
|
|
@@ -105977,7 +106097,7 @@ class CopyExecutor {
|
|
|
105977
106097
|
const conflicts = [];
|
|
105978
106098
|
const files = await this.fileScanner.getFiles(sourceDir, sourceDir);
|
|
105979
106099
|
for (const file of files) {
|
|
105980
|
-
const relativePath =
|
|
106100
|
+
const relativePath = relative25(sourceDir, file);
|
|
105981
106101
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
105982
106102
|
const destPath = join113(destDir, relativePath);
|
|
105983
106103
|
if (await import_fs_extra16.pathExists(destPath)) {
|
|
@@ -106001,7 +106121,7 @@ class CopyExecutor {
|
|
|
106001
106121
|
let skippedCount = 0;
|
|
106002
106122
|
let ignoredSkillSkipped = 0;
|
|
106003
106123
|
for (const file of files) {
|
|
106004
|
-
const relativePath =
|
|
106124
|
+
const relativePath = relative25(sourceDir, file);
|
|
106005
106125
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
106006
106126
|
const destPath = join113(destDir, relativePath);
|
|
106007
106127
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
@@ -106215,7 +106335,7 @@ class FileMerger {
|
|
|
106215
106335
|
|
|
106216
106336
|
// src/domains/migration/legacy-migration.ts
|
|
106217
106337
|
import { readdir as readdir28, stat as stat19 } from "node:fs/promises";
|
|
106218
|
-
import { join as join117, relative as
|
|
106338
|
+
import { join as join117, relative as relative26 } from "node:path";
|
|
106219
106339
|
// src/services/file-operations/manifest/manifest-tracker.ts
|
|
106220
106340
|
import { join as join116 } from "node:path";
|
|
106221
106341
|
|
|
@@ -106688,7 +106808,7 @@ class LegacyMigration {
|
|
|
106688
106808
|
static async classifyFiles(claudeDir3, manifest) {
|
|
106689
106809
|
const files = await LegacyMigration.scanFiles(claudeDir3);
|
|
106690
106810
|
const relevantFiles = files.filter((file) => {
|
|
106691
|
-
const relativePath =
|
|
106811
|
+
const relativePath = relative26(claudeDir3, file);
|
|
106692
106812
|
return !hasSkippedDirectorySegment(relativePath);
|
|
106693
106813
|
});
|
|
106694
106814
|
const skippedRuntimeArtifacts = files.length - relevantFiles.length;
|
|
@@ -106703,7 +106823,7 @@ class LegacyMigration {
|
|
|
106703
106823
|
};
|
|
106704
106824
|
const filesInManifest = [];
|
|
106705
106825
|
for (const file of relevantFiles) {
|
|
106706
|
-
const relativePath =
|
|
106826
|
+
const relativePath = relative26(claudeDir3, file).replace(/\\/g, "/");
|
|
106707
106827
|
const manifestEntry = ReleaseManifestLoader.findFile(manifest, relativePath);
|
|
106708
106828
|
if (!manifestEntry) {
|
|
106709
106829
|
preview.userCreated.push(relativePath);
|
|
@@ -106899,7 +107019,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
|
|
|
106899
107019
|
init_logger();
|
|
106900
107020
|
init_skip_directories();
|
|
106901
107021
|
var import_fs_extra20 = __toESM(require_lib(), 1);
|
|
106902
|
-
import { join as join118, relative as
|
|
107022
|
+
import { join as join118, relative as relative27, resolve as resolve44 } from "node:path";
|
|
106903
107023
|
|
|
106904
107024
|
class FileScanner2 {
|
|
106905
107025
|
static async getFiles(dirPath, relativeTo) {
|
|
@@ -106938,7 +107058,7 @@ class FileScanner2 {
|
|
|
106938
107058
|
const subFiles = await FileScanner2.getFiles(fullPath, basePath);
|
|
106939
107059
|
files.push(...subFiles);
|
|
106940
107060
|
} else if (stats.isFile()) {
|
|
106941
|
-
const relativePath =
|
|
107061
|
+
const relativePath = relative27(basePath, fullPath);
|
|
106942
107062
|
files.push(FileScanner2.toPosixPath(relativePath));
|
|
106943
107063
|
}
|
|
106944
107064
|
}
|
|
@@ -106979,8 +107099,8 @@ class FileScanner2 {
|
|
|
106979
107099
|
return customFiles;
|
|
106980
107100
|
}
|
|
106981
107101
|
static isSafePath(basePath, targetPath) {
|
|
106982
|
-
const resolvedBase =
|
|
106983
|
-
const resolvedTarget =
|
|
107102
|
+
const resolvedBase = resolve44(basePath);
|
|
107103
|
+
const resolvedTarget = resolve44(targetPath);
|
|
106984
107104
|
return resolvedTarget.startsWith(resolvedBase);
|
|
106985
107105
|
}
|
|
106986
107106
|
static toPosixPath(path17) {
|
|
@@ -107605,9 +107725,9 @@ init_logger();
|
|
|
107605
107725
|
init_skip_directories();
|
|
107606
107726
|
init_types3();
|
|
107607
107727
|
var import_fs_extra25 = __toESM(require_lib(), 1);
|
|
107608
|
-
import { createHash as
|
|
107728
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
107609
107729
|
import { readFile as readFile58, readdir as readdir34, writeFile as writeFile32 } from "node:fs/promises";
|
|
107610
|
-
import { join as join124, relative as
|
|
107730
|
+
import { join as join124, relative as relative28 } from "node:path";
|
|
107611
107731
|
|
|
107612
107732
|
class SkillsManifestManager {
|
|
107613
107733
|
static MANIFEST_FILENAME = ".skills-manifest.json";
|
|
@@ -107707,11 +107827,11 @@ class SkillsManifestManager {
|
|
|
107707
107827
|
return skills.sort((a3, b3) => a3.name.localeCompare(b3.name));
|
|
107708
107828
|
}
|
|
107709
107829
|
static async hashDirectory(dirPath) {
|
|
107710
|
-
const hash =
|
|
107830
|
+
const hash = createHash8("sha256");
|
|
107711
107831
|
const files = await SkillsManifestManager.getAllFiles(dirPath);
|
|
107712
107832
|
files.sort();
|
|
107713
107833
|
for (const file of files) {
|
|
107714
|
-
const relativePath =
|
|
107834
|
+
const relativePath = relative28(dirPath, file);
|
|
107715
107835
|
const content = await readFile58(file);
|
|
107716
107836
|
hash.update(relativePath);
|
|
107717
107837
|
hash.update(content);
|
|
@@ -108446,14 +108566,14 @@ init_logger();
|
|
|
108446
108566
|
|
|
108447
108567
|
// src/domains/skills/customization/comparison-engine.ts
|
|
108448
108568
|
var import_fs_extra30 = __toESM(require_lib(), 1);
|
|
108449
|
-
import { relative as
|
|
108569
|
+
import { relative as relative30 } from "node:path";
|
|
108450
108570
|
|
|
108451
108571
|
// src/domains/skills/customization/hash-calculator.ts
|
|
108452
108572
|
init_skip_directories();
|
|
108453
|
-
import { createHash as
|
|
108573
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
108454
108574
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
108455
108575
|
import { readFile as readFile59, readdir as readdir38 } from "node:fs/promises";
|
|
108456
|
-
import { join as join128, relative as
|
|
108576
|
+
import { join as join128, relative as relative29 } from "node:path";
|
|
108457
108577
|
async function getAllFiles(dirPath) {
|
|
108458
108578
|
const files = [];
|
|
108459
108579
|
const entries = await readdir38(dirPath, { withFileTypes: true });
|
|
@@ -108472,12 +108592,12 @@ async function getAllFiles(dirPath) {
|
|
|
108472
108592
|
return files;
|
|
108473
108593
|
}
|
|
108474
108594
|
async function hashFile(filePath) {
|
|
108475
|
-
return new Promise((
|
|
108476
|
-
const hash =
|
|
108595
|
+
return new Promise((resolve45, reject) => {
|
|
108596
|
+
const hash = createHash9("sha256");
|
|
108477
108597
|
const stream = createReadStream2(filePath);
|
|
108478
108598
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
108479
108599
|
stream.on("end", () => {
|
|
108480
|
-
|
|
108600
|
+
resolve45(hash.digest("hex"));
|
|
108481
108601
|
});
|
|
108482
108602
|
stream.on("error", (error) => {
|
|
108483
108603
|
stream.destroy();
|
|
@@ -108486,11 +108606,11 @@ async function hashFile(filePath) {
|
|
|
108486
108606
|
});
|
|
108487
108607
|
}
|
|
108488
108608
|
async function hashDirectory(dirPath) {
|
|
108489
|
-
const hash =
|
|
108609
|
+
const hash = createHash9("sha256");
|
|
108490
108610
|
const files = await getAllFiles(dirPath);
|
|
108491
108611
|
files.sort();
|
|
108492
108612
|
for (const file of files) {
|
|
108493
|
-
const relativePath =
|
|
108613
|
+
const relativePath = relative29(dirPath, file);
|
|
108494
108614
|
const content = await readFile59(file);
|
|
108495
108615
|
hash.update(relativePath);
|
|
108496
108616
|
hash.update(content);
|
|
@@ -108524,8 +108644,8 @@ async function compareDirectories(dir1, dir2) {
|
|
|
108524
108644
|
if (files1.length !== files2.length) {
|
|
108525
108645
|
return true;
|
|
108526
108646
|
}
|
|
108527
|
-
const relFiles1 = files1.map((f3) =>
|
|
108528
|
-
const relFiles2 = files2.map((f3) =>
|
|
108647
|
+
const relFiles1 = files1.map((f3) => relative30(dir1, f3)).sort();
|
|
108648
|
+
const relFiles2 = files2.map((f3) => relative30(dir2, f3)).sort();
|
|
108529
108649
|
if (JSON.stringify(relFiles1) !== JSON.stringify(relFiles2)) {
|
|
108530
108650
|
return true;
|
|
108531
108651
|
}
|
|
@@ -108543,12 +108663,12 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
|
|
|
108543
108663
|
const currentFiles = await getAllFiles(currentSkillPath);
|
|
108544
108664
|
const baselineFiles = await import_fs_extra30.pathExists(baselineSkillPath) ? await getAllFiles(baselineSkillPath) : [];
|
|
108545
108665
|
const currentFileMap = new Map(await Promise.all(currentFiles.map(async (f3) => {
|
|
108546
|
-
const relPath =
|
|
108666
|
+
const relPath = relative30(currentSkillPath, f3);
|
|
108547
108667
|
const hash = await hashFile(f3);
|
|
108548
108668
|
return [relPath, hash];
|
|
108549
108669
|
})));
|
|
108550
108670
|
const baselineFileMap = new Map(await Promise.all(baselineFiles.map(async (f3) => {
|
|
108551
|
-
const relPath =
|
|
108671
|
+
const relPath = relative30(baselineSkillPath, f3);
|
|
108552
108672
|
const hash = await hashFile(f3);
|
|
108553
108673
|
return [relPath, hash];
|
|
108554
108674
|
})));
|
|
@@ -108995,7 +109115,8 @@ async function resolveOptions(ctx) {
|
|
|
108995
109115
|
sync: parsed.sync ?? false,
|
|
108996
109116
|
useGit: parsed.useGit ?? false,
|
|
108997
109117
|
archive: parsed.archive,
|
|
108998
|
-
kitPath: parsed.kitPath
|
|
109118
|
+
kitPath: parsed.kitPath,
|
|
109119
|
+
installMode: parsed.installMode ?? "auto"
|
|
108999
109120
|
};
|
|
109000
109121
|
ConfigManager.setGlobalFlag(validOptions.global);
|
|
109001
109122
|
if (validOptions.global) {
|
|
@@ -109125,13 +109246,22 @@ async function handlePostInstall(ctx) {
|
|
|
109125
109246
|
}
|
|
109126
109247
|
// src/commands/init/phases/plugin-install-handler.ts
|
|
109127
109248
|
init_codex_plugin_installer();
|
|
109128
|
-
import { cpSync as cpSync2, existsSync as
|
|
109129
|
-
import { join as
|
|
109249
|
+
import { cpSync as cpSync2, existsSync as existsSync70, mkdirSync as mkdirSync6, readFileSync as readFileSync22, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "node:fs";
|
|
109250
|
+
import { join as join137 } from "node:path";
|
|
109130
109251
|
|
|
109131
109252
|
// src/domains/installation/plugin/migrate-legacy-to-plugin.ts
|
|
109132
109253
|
init_install_mode_detector();
|
|
109133
|
-
import {
|
|
109134
|
-
import {
|
|
109254
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
109255
|
+
import {
|
|
109256
|
+
cpSync,
|
|
109257
|
+
existsSync as existsSync68,
|
|
109258
|
+
mkdirSync as mkdirSync5,
|
|
109259
|
+
readFileSync as readFileSync21,
|
|
109260
|
+
readdirSync as readdirSync11,
|
|
109261
|
+
rmSync as rmSync3,
|
|
109262
|
+
writeFileSync as writeFileSync7
|
|
109263
|
+
} from "node:fs";
|
|
109264
|
+
import { dirname as dirname43, join as join135, relative as relative31, resolve as resolve45 } from "node:path";
|
|
109135
109265
|
|
|
109136
109266
|
// src/domains/installation/plugin/plugin-installer.ts
|
|
109137
109267
|
init_install_mode_detector();
|
|
@@ -109239,18 +109369,11 @@ async function migrateLegacyToPlugin(opts) {
|
|
|
109239
109369
|
if (!await installer.isClaudeAvailable() || !await installer.isPluginSupported()) {
|
|
109240
109370
|
return base("skipped-cc-unsupported", before.mode, false);
|
|
109241
109371
|
}
|
|
109242
|
-
const
|
|
109243
|
-
if (!
|
|
109372
|
+
const prepared = before.plugin.installed ? await refreshExistingPlugin(installer, opts.pluginSourceDir, before.plugin.enabled) : await installPlugin(installer, opts.pluginSourceDir);
|
|
109373
|
+
if (!prepared.ok) {
|
|
109244
109374
|
return {
|
|
109245
109375
|
...base("install-failed", before.mode, false),
|
|
109246
|
-
error:
|
|
109247
|
-
};
|
|
109248
|
-
}
|
|
109249
|
-
const installed = await installer.install("user");
|
|
109250
|
-
if (!installed.ok) {
|
|
109251
|
-
return {
|
|
109252
|
-
...base("install-failed", before.mode, false),
|
|
109253
|
-
error: `plugin install failed: ${installed.stderr.trim()}`
|
|
109376
|
+
error: prepared.error
|
|
109254
109377
|
};
|
|
109255
109378
|
}
|
|
109256
109379
|
const verified = await installer.verifyInstalled();
|
|
@@ -109296,30 +109419,172 @@ function base(action, modeBefore, pluginVerified) {
|
|
|
109296
109419
|
};
|
|
109297
109420
|
}
|
|
109298
109421
|
var PLUGIN_SUPPLIED_LEGACY_PREFIXES2 = ["agents/", "skills/"];
|
|
109422
|
+
var LEGACY_SENTINEL_FILENAMES = new Set([".gitignore"]);
|
|
109299
109423
|
function defaultLegacyRemover(claudeDir3, backupDir) {
|
|
109300
109424
|
const meta = readJsonSafe3(join135(claudeDir3, "metadata.json"));
|
|
109301
109425
|
const files = collectTrackedFiles2(meta);
|
|
109302
109426
|
const removed = [];
|
|
109303
109427
|
for (const file of files) {
|
|
109304
|
-
|
|
109428
|
+
const legacyPath = resolveSafePluginSuppliedLegacyPath2(claudeDir3, file.path);
|
|
109429
|
+
if (!legacyPath)
|
|
109305
109430
|
continue;
|
|
109306
|
-
if (!
|
|
109431
|
+
if (!existsSync68(legacyPath.absolutePath))
|
|
109307
109432
|
continue;
|
|
109308
|
-
|
|
109309
|
-
if (!existsSync68(abs))
|
|
109433
|
+
if (!isSafeToRemovePluginSuppliedLegacyFile(file, legacyPath.absolutePath))
|
|
109310
109434
|
continue;
|
|
109311
|
-
|
|
109312
|
-
|
|
109313
|
-
|
|
109314
|
-
rmSync3(abs, { recursive: true, force: true });
|
|
109315
|
-
removed.push(file.path);
|
|
109435
|
+
if (!backupAndRemove(backupDir, legacyPath.relativePath, legacyPath.absolutePath))
|
|
109436
|
+
continue;
|
|
109437
|
+
removed.push(legacyPath.relativePath);
|
|
109316
109438
|
}
|
|
109439
|
+
removed.push(...removeOrphanLegacySentinels(claudeDir3, backupDir, removed));
|
|
109317
109440
|
return removed;
|
|
109318
109441
|
}
|
|
109319
|
-
function
|
|
109320
|
-
const
|
|
109442
|
+
function backupAndRemove(backupDir, relativePath, abs) {
|
|
109443
|
+
const backupTarget = resolveSafeChildPath2(backupDir, relativePath);
|
|
109444
|
+
if (!backupTarget)
|
|
109445
|
+
return false;
|
|
109446
|
+
mkdirSync5(dirname43(backupTarget), { recursive: true });
|
|
109447
|
+
cpSync(abs, backupTarget, { recursive: true });
|
|
109448
|
+
rmSync3(abs, { recursive: true, force: true });
|
|
109449
|
+
return true;
|
|
109450
|
+
}
|
|
109451
|
+
function removeOrphanLegacySentinels(claudeDir3, backupDir, removedTrackedPaths) {
|
|
109452
|
+
const normalizedRemoved = removedTrackedPaths.map(normalizeLegacyPath2);
|
|
109453
|
+
const rootsToSweep = new Set;
|
|
109454
|
+
for (const pathValue of normalizedRemoved) {
|
|
109455
|
+
const [root] = pathValue.split("/");
|
|
109456
|
+
if (root && PLUGIN_SUPPLIED_LEGACY_PREFIXES2.includes(`${root}/`)) {
|
|
109457
|
+
rootsToSweep.add(root);
|
|
109458
|
+
}
|
|
109459
|
+
}
|
|
109460
|
+
const removed = [];
|
|
109461
|
+
for (const root of [...rootsToSweep].sort(compareLegacyPaths)) {
|
|
109462
|
+
const rootAbs = join135(claudeDir3, root);
|
|
109463
|
+
if (!existsSync68(rootAbs))
|
|
109464
|
+
continue;
|
|
109465
|
+
const sentinels = findLegacySentinels(rootAbs).sort((a3, b3) => compareLegacyPaths(relative31(claudeDir3, a3), relative31(claudeDir3, b3)));
|
|
109466
|
+
for (const sentinelAbs of sentinels) {
|
|
109467
|
+
const sentinelPath = normalizeLegacyPath2(relative31(claudeDir3, sentinelAbs));
|
|
109468
|
+
if (!isSafeToRemoveLegacySentinel(sentinelPath, sentinelAbs, normalizedRemoved))
|
|
109469
|
+
continue;
|
|
109470
|
+
if (!backupAndRemove(backupDir, sentinelPath, sentinelAbs))
|
|
109471
|
+
continue;
|
|
109472
|
+
removed.push(sentinelPath);
|
|
109473
|
+
}
|
|
109474
|
+
}
|
|
109475
|
+
return removed;
|
|
109476
|
+
}
|
|
109477
|
+
function findLegacySentinels(dir) {
|
|
109478
|
+
const out = [];
|
|
109479
|
+
let entries;
|
|
109480
|
+
try {
|
|
109481
|
+
entries = readdirSync11(dir, { withFileTypes: true });
|
|
109482
|
+
} catch {
|
|
109483
|
+
return out;
|
|
109484
|
+
}
|
|
109485
|
+
for (const entry of entries.sort((a3, b3) => compareLegacyPaths(a3.name, b3.name))) {
|
|
109486
|
+
const abs = join135(dir, entry.name);
|
|
109487
|
+
if (entry.isDirectory()) {
|
|
109488
|
+
out.push(...findLegacySentinels(abs));
|
|
109489
|
+
} else if (entry.isFile() && LEGACY_SENTINEL_FILENAMES.has(entry.name)) {
|
|
109490
|
+
out.push(abs);
|
|
109491
|
+
}
|
|
109492
|
+
}
|
|
109493
|
+
return out;
|
|
109494
|
+
}
|
|
109495
|
+
function isSafeToRemoveLegacySentinel(sentinelPath, sentinelAbs, removedTrackedPaths) {
|
|
109496
|
+
if (!isPluginSuppliedLegacyPath2(sentinelPath))
|
|
109497
|
+
return false;
|
|
109498
|
+
if (!LEGACY_SENTINEL_FILENAMES.has(sentinelPath.split("/").pop() ?? ""))
|
|
109499
|
+
return false;
|
|
109500
|
+
const sentinelDir = dirname43(sentinelPath).replace(/\\/g, "/");
|
|
109501
|
+
if (!removedTrackedPaths.some((removedPath) => removedPath.startsWith(`${sentinelDir}/`))) {
|
|
109502
|
+
return false;
|
|
109503
|
+
}
|
|
109504
|
+
return directoryContainsOnlySentinels(dirname43(sentinelAbs));
|
|
109505
|
+
}
|
|
109506
|
+
function directoryContainsOnlySentinels(dir) {
|
|
109507
|
+
let entries;
|
|
109508
|
+
try {
|
|
109509
|
+
entries = readdirSync11(dir, { withFileTypes: true });
|
|
109510
|
+
} catch {
|
|
109511
|
+
return false;
|
|
109512
|
+
}
|
|
109513
|
+
for (const entry of entries) {
|
|
109514
|
+
const abs = join135(dir, entry.name);
|
|
109515
|
+
if (entry.isDirectory()) {
|
|
109516
|
+
if (!directoryContainsOnlySentinels(abs))
|
|
109517
|
+
return false;
|
|
109518
|
+
} else if (!entry.isFile() || !LEGACY_SENTINEL_FILENAMES.has(entry.name)) {
|
|
109519
|
+
return false;
|
|
109520
|
+
}
|
|
109521
|
+
}
|
|
109522
|
+
return true;
|
|
109523
|
+
}
|
|
109524
|
+
function isSafeToRemovePluginSuppliedLegacyFile(file, abs) {
|
|
109525
|
+
if (file.ownership !== "user") {
|
|
109526
|
+
return true;
|
|
109527
|
+
}
|
|
109528
|
+
return checksumMatches2(abs, file.checksum);
|
|
109529
|
+
}
|
|
109530
|
+
function checksumMatches2(filePath, expected) {
|
|
109531
|
+
if (!expected || !/^[a-f0-9]{64}$/i.test(expected)) {
|
|
109532
|
+
return false;
|
|
109533
|
+
}
|
|
109534
|
+
try {
|
|
109535
|
+
const actual = createHash10("sha256").update(readFileSync21(filePath)).digest("hex");
|
|
109536
|
+
return actual.toLowerCase() === expected.toLowerCase();
|
|
109537
|
+
} catch {
|
|
109538
|
+
return false;
|
|
109539
|
+
}
|
|
109540
|
+
}
|
|
109541
|
+
function isPluginSuppliedLegacyPath2(pathValue) {
|
|
109542
|
+
const normalized = normalizeLegacyPath2(pathValue).replace(/^\.claude\//, "");
|
|
109321
109543
|
return PLUGIN_SUPPLIED_LEGACY_PREFIXES2.some((prefix) => normalized.startsWith(prefix));
|
|
109322
109544
|
}
|
|
109545
|
+
function resolveSafePluginSuppliedLegacyPath2(claudeDir3, pathValue) {
|
|
109546
|
+
const normalized = normalizeLegacyPath2(pathValue).replace(/^\.\/+/, "");
|
|
109547
|
+
if (!isPluginSuppliedLegacyPath2(normalized))
|
|
109548
|
+
return null;
|
|
109549
|
+
const safe = resolveSafeChildPath2(claudeDir3, normalized);
|
|
109550
|
+
if (!safe)
|
|
109551
|
+
return null;
|
|
109552
|
+
const relativePath = normalizeLegacyPath2(relative31(resolve45(claudeDir3), safe));
|
|
109553
|
+
if (!isPluginSuppliedLegacyPath2(relativePath))
|
|
109554
|
+
return null;
|
|
109555
|
+
return { absolutePath: safe, relativePath };
|
|
109556
|
+
}
|
|
109557
|
+
function resolveSafeChildPath2(baseDir, pathValue) {
|
|
109558
|
+
const normalized = normalizeLegacyPath2(pathValue);
|
|
109559
|
+
if (!normalized || hasPathTraversal2(normalized) || isAbsoluteLike3(normalized))
|
|
109560
|
+
return null;
|
|
109561
|
+
const resolvedBase = resolve45(baseDir);
|
|
109562
|
+
const resolvedTarget = resolve45(resolvedBase, normalized);
|
|
109563
|
+
const relativePath = normalizeLegacyPath2(relative31(resolvedBase, resolvedTarget));
|
|
109564
|
+
if (!relativePath || relativePath === ".." || relativePath.startsWith("../"))
|
|
109565
|
+
return null;
|
|
109566
|
+
if (isAbsoluteLike3(relativePath))
|
|
109567
|
+
return null;
|
|
109568
|
+
return resolvedTarget;
|
|
109569
|
+
}
|
|
109570
|
+
function hasPathTraversal2(pathValue) {
|
|
109571
|
+
return pathValue.split("/").some((segment) => segment === "..");
|
|
109572
|
+
}
|
|
109573
|
+
function isAbsoluteLike3(pathValue) {
|
|
109574
|
+
return pathValue.startsWith("/") || pathValue.startsWith("//") || /^[A-Za-z]:/.test(pathValue);
|
|
109575
|
+
}
|
|
109576
|
+
function normalizeLegacyPath2(pathValue) {
|
|
109577
|
+
return pathValue.replace(/\\/g, "/");
|
|
109578
|
+
}
|
|
109579
|
+
function compareLegacyPaths(a3, b3) {
|
|
109580
|
+
const normalizedA = normalizeLegacyPath2(a3);
|
|
109581
|
+
const normalizedB = normalizeLegacyPath2(b3);
|
|
109582
|
+
if (normalizedA < normalizedB)
|
|
109583
|
+
return -1;
|
|
109584
|
+
if (normalizedA > normalizedB)
|
|
109585
|
+
return 1;
|
|
109586
|
+
return 0;
|
|
109587
|
+
}
|
|
109323
109588
|
function collectTrackedFiles2(meta) {
|
|
109324
109589
|
if (!isRecord3(meta))
|
|
109325
109590
|
return [];
|
|
@@ -109330,7 +109595,11 @@ function collectTrackedFiles2(meta) {
|
|
|
109330
109595
|
for (const f3 of arr) {
|
|
109331
109596
|
if (isRecord3(f3) && typeof f3.path === "string") {
|
|
109332
109597
|
const ownership = f3.ownership === "user" || f3.ownership === "ck-modified" ? f3.ownership : "ck";
|
|
109333
|
-
out.push({
|
|
109598
|
+
out.push({
|
|
109599
|
+
path: f3.path,
|
|
109600
|
+
ownership,
|
|
109601
|
+
checksum: typeof f3.checksum === "string" ? f3.checksum : undefined
|
|
109602
|
+
});
|
|
109334
109603
|
}
|
|
109335
109604
|
}
|
|
109336
109605
|
};
|
|
@@ -109359,10 +109628,86 @@ function readJsonSafe3(filePath) {
|
|
|
109359
109628
|
return null;
|
|
109360
109629
|
}
|
|
109361
109630
|
}
|
|
109631
|
+
async function installPlugin(installer, pluginSourceDir) {
|
|
109632
|
+
const added = await installer.marketplaceAdd(pluginSourceDir);
|
|
109633
|
+
if (!added.ok) {
|
|
109634
|
+
return { ok: false, error: `marketplace add failed: ${added.stderr.trim()}` };
|
|
109635
|
+
}
|
|
109636
|
+
const installed = await installer.install("user");
|
|
109637
|
+
if (!installed.ok) {
|
|
109638
|
+
return { ok: false, error: `plugin install failed: ${installed.stderr.trim()}` };
|
|
109639
|
+
}
|
|
109640
|
+
return { ok: true };
|
|
109641
|
+
}
|
|
109642
|
+
async function refreshExistingPlugin(installer, pluginSourceDir, enabled) {
|
|
109643
|
+
const added = await installer.marketplaceAdd(pluginSourceDir);
|
|
109644
|
+
if (!added.ok) {
|
|
109645
|
+
const updatedMarketplace = await installer.marketplaceUpdate();
|
|
109646
|
+
if (!updatedMarketplace.ok) {
|
|
109647
|
+
return {
|
|
109648
|
+
ok: false,
|
|
109649
|
+
error: `marketplace refresh failed: ${updatedMarketplace.stderr.trim() || added.stderr.trim()}`
|
|
109650
|
+
};
|
|
109651
|
+
}
|
|
109652
|
+
}
|
|
109653
|
+
if (!enabled) {
|
|
109654
|
+
const enabledResult = await installer.enable();
|
|
109655
|
+
if (!enabledResult.ok) {
|
|
109656
|
+
return { ok: false, error: `plugin enable failed: ${enabledResult.stderr.trim()}` };
|
|
109657
|
+
}
|
|
109658
|
+
}
|
|
109659
|
+
const updated = await installer.update();
|
|
109660
|
+
if (!updated.ok) {
|
|
109661
|
+
return { ok: false, error: `plugin update failed: ${updated.stderr.trim()}` };
|
|
109662
|
+
}
|
|
109663
|
+
return { ok: true };
|
|
109664
|
+
}
|
|
109362
109665
|
function isRecord3(value) {
|
|
109363
109666
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
109364
109667
|
}
|
|
109365
109668
|
|
|
109669
|
+
// src/domains/installation/plugin/uninstall-plugin.ts
|
|
109670
|
+
init_install_mode_detector();
|
|
109671
|
+
import { existsSync as existsSync69, rmSync as rmSync4 } from "node:fs";
|
|
109672
|
+
import { join as join136 } from "node:path";
|
|
109673
|
+
init_path_resolver();
|
|
109674
|
+
async function uninstallEnginePlugin(opts = {}) {
|
|
109675
|
+
const claudeDir3 = opts.claudeDir ?? PathResolver.getGlobalKitDir();
|
|
109676
|
+
const installer = opts.installer ?? new PluginInstaller(undefined, claudeDir3);
|
|
109677
|
+
const state = detectPluginState(claudeDir3);
|
|
109678
|
+
let uninstalled = false;
|
|
109679
|
+
const errors2 = [];
|
|
109680
|
+
if (state.installed) {
|
|
109681
|
+
const removed = await installer.uninstall();
|
|
109682
|
+
if (removed.ok) {
|
|
109683
|
+
uninstalled = true;
|
|
109684
|
+
} else {
|
|
109685
|
+
errors2.push(`plugin uninstall failed: ${removed.stderr.trim() || "unknown error"}`);
|
|
109686
|
+
}
|
|
109687
|
+
const marketplaceRemoved = await installer.marketplaceRemove(state.marketplace ?? CK_MARKETPLACE_NAME);
|
|
109688
|
+
if (!marketplaceRemoved.ok) {
|
|
109689
|
+
errors2.push(`marketplace remove failed: ${marketplaceRemoved.stderr.trim() || "unknown error"}`);
|
|
109690
|
+
}
|
|
109691
|
+
}
|
|
109692
|
+
let staleCacheRemoved = false;
|
|
109693
|
+
const marketplace = state.marketplace ?? CK_MARKETPLACE_NAME;
|
|
109694
|
+
const cacheDir = join136(claudeDir3, "plugins", "cache", marketplace, CK_PLUGIN_NAME);
|
|
109695
|
+
if (existsSync69(cacheDir)) {
|
|
109696
|
+
rmSync4(cacheDir, { recursive: true, force: true });
|
|
109697
|
+
staleCacheRemoved = true;
|
|
109698
|
+
}
|
|
109699
|
+
const pluginStillInstalled = state.installed ? detectPluginState(claudeDir3).installed : false;
|
|
109700
|
+
if (pluginStillInstalled) {
|
|
109701
|
+
errors2.push("plugin remains registered after cleanup");
|
|
109702
|
+
}
|
|
109703
|
+
return {
|
|
109704
|
+
uninstalled,
|
|
109705
|
+
staleCacheRemoved,
|
|
109706
|
+
pluginStillInstalled,
|
|
109707
|
+
error: errors2.length > 0 ? errors2.join("; ") : undefined
|
|
109708
|
+
};
|
|
109709
|
+
}
|
|
109710
|
+
|
|
109366
109711
|
// src/commands/init/phases/plugin-install-handler.ts
|
|
109367
109712
|
init_logger();
|
|
109368
109713
|
init_path_resolver();
|
|
@@ -109373,12 +109718,43 @@ async function handlePluginInstall(ctx, deps = {}) {
|
|
|
109373
109718
|
}
|
|
109374
109719
|
const migrate = deps.migrate ?? migrateLegacyToPlugin;
|
|
109375
109720
|
const installCodex = deps.installCodex ?? installCodexPlugin;
|
|
109721
|
+
const uninstallClaude = deps.uninstallClaudePlugin ?? uninstallEnginePlugin;
|
|
109722
|
+
const removeCodex = deps.removeCodexPlugin ?? removeCodexPlugin;
|
|
109723
|
+
if (ctx.options.installMode === "legacy") {
|
|
109724
|
+
let cleanupError = null;
|
|
109725
|
+
try {
|
|
109726
|
+
const result = await uninstallClaude({ claudeDir: ctx.claudeDir });
|
|
109727
|
+
logLegacyPluginCleanup(result);
|
|
109728
|
+
if (result.pluginStillInstalled) {
|
|
109729
|
+
cleanupError = new Error(`Claude plugin cleanup failed for legacy install mode: ${result.error ?? "plugin remains registered"}`);
|
|
109730
|
+
}
|
|
109731
|
+
} catch (err) {
|
|
109732
|
+
logger.verbose(`Claude plugin cleanup skipped: ${err.message}`);
|
|
109733
|
+
cleanupError = err;
|
|
109734
|
+
}
|
|
109735
|
+
try {
|
|
109736
|
+
const result = await removeCodex();
|
|
109737
|
+
logCodexPluginCleanup(result);
|
|
109738
|
+
} catch (err) {
|
|
109739
|
+
logger.verbose(`Codex plugin cleanup skipped: ${err.message}`);
|
|
109740
|
+
}
|
|
109741
|
+
if (cleanupError) {
|
|
109742
|
+
throw cleanupError;
|
|
109743
|
+
}
|
|
109744
|
+
return ctx;
|
|
109745
|
+
}
|
|
109376
109746
|
try {
|
|
109377
109747
|
const pluginSourceDir = stagePluginSource(ctx.extractDir, deps.stageBaseDir);
|
|
109378
109748
|
try {
|
|
109379
109749
|
const result = await migrate({ pluginSourceDir, claudeDir: ctx.claudeDir });
|
|
109380
109750
|
logPluginResult(result);
|
|
109751
|
+
if (ctx.options.installMode === "plugin" && !result.pluginVerified) {
|
|
109752
|
+
throw new Error(`Claude plugin install failed: ${result.error ?? result.action}`);
|
|
109753
|
+
}
|
|
109381
109754
|
} catch (err) {
|
|
109755
|
+
if (ctx.options.installMode === "plugin") {
|
|
109756
|
+
throw err;
|
|
109757
|
+
}
|
|
109382
109758
|
logger.verbose(`Claude plugin install skipped (legacy copy retained): ${err.message}`);
|
|
109383
109759
|
}
|
|
109384
109760
|
try {
|
|
@@ -109388,19 +109764,29 @@ async function handlePluginInstall(ctx, deps = {}) {
|
|
|
109388
109764
|
logger.verbose(`Codex plugin install skipped: ${err.message}`);
|
|
109389
109765
|
}
|
|
109390
109766
|
} catch (err) {
|
|
109767
|
+
if (ctx.options.installMode === "plugin") {
|
|
109768
|
+
throw err;
|
|
109769
|
+
}
|
|
109391
109770
|
logger.verbose(`Plugin staging skipped (legacy copy retained): ${err.message}`);
|
|
109392
109771
|
}
|
|
109393
109772
|
return ctx;
|
|
109394
109773
|
}
|
|
109774
|
+
function logLegacyPluginCleanup(result) {
|
|
109775
|
+
if (result.uninstalled || result.staleCacheRemoved) {
|
|
109776
|
+
logger.info("Removed ClaudeKit Engineer plugin state for legacy install mode.");
|
|
109777
|
+
} else {
|
|
109778
|
+
logger.verbose("No ClaudeKit Engineer Claude plugin state found for legacy install mode.");
|
|
109779
|
+
}
|
|
109780
|
+
}
|
|
109395
109781
|
function stagePluginSource(extractDir, stageBaseDir) {
|
|
109396
|
-
const base2 = stageBaseDir ??
|
|
109397
|
-
const payloadSrc =
|
|
109398
|
-
if (!
|
|
109782
|
+
const base2 = stageBaseDir ?? join137(PathResolver.getCacheDir(true), "ck-plugin-source");
|
|
109783
|
+
const payloadSrc = join137(extractDir, ".claude");
|
|
109784
|
+
if (!existsSync70(payloadSrc)) {
|
|
109399
109785
|
throw new Error(`plugin payload not found in archive: ${payloadSrc}`);
|
|
109400
109786
|
}
|
|
109401
|
-
|
|
109787
|
+
rmSync5(base2, { recursive: true, force: true });
|
|
109402
109788
|
mkdirSync6(base2, { recursive: true });
|
|
109403
|
-
const stagedPayload =
|
|
109789
|
+
const stagedPayload = join137(base2, ".claude");
|
|
109404
109790
|
cpSync2(payloadSrc, stagedPayload, { recursive: true });
|
|
109405
109791
|
ensureCodexPluginManifest(stagedPayload);
|
|
109406
109792
|
const claudeMarketplace = {
|
|
@@ -109408,8 +109794,8 @@ function stagePluginSource(extractDir, stageBaseDir) {
|
|
|
109408
109794
|
owner: { name: "ClaudeKit" },
|
|
109409
109795
|
plugins: [{ name: "ck", source: "./.claude", description: "ClaudeKit Engineer" }]
|
|
109410
109796
|
};
|
|
109411
|
-
mkdirSync6(
|
|
109412
|
-
writeFileSync8(
|
|
109797
|
+
mkdirSync6(join137(base2, ".claude-plugin"), { recursive: true });
|
|
109798
|
+
writeFileSync8(join137(base2, ".claude-plugin", "marketplace.json"), `${JSON.stringify(claudeMarketplace, null, 2)}
|
|
109413
109799
|
`, "utf-8");
|
|
109414
109800
|
const codexMarketplace = {
|
|
109415
109801
|
name: "claudekit",
|
|
@@ -109423,16 +109809,16 @@ function stagePluginSource(extractDir, stageBaseDir) {
|
|
|
109423
109809
|
}
|
|
109424
109810
|
]
|
|
109425
109811
|
};
|
|
109426
|
-
mkdirSync6(
|
|
109427
|
-
writeFileSync8(
|
|
109812
|
+
mkdirSync6(join137(base2, ".agents", "plugins"), { recursive: true });
|
|
109813
|
+
writeFileSync8(join137(base2, ".agents", "plugins", "marketplace.json"), `${JSON.stringify(codexMarketplace, null, 2)}
|
|
109428
109814
|
`, "utf-8");
|
|
109429
109815
|
return base2;
|
|
109430
109816
|
}
|
|
109431
109817
|
function ensureCodexPluginManifest(pluginRoot) {
|
|
109432
|
-
const manifestPath =
|
|
109433
|
-
if (
|
|
109818
|
+
const manifestPath = join137(pluginRoot, ".codex-plugin", "plugin.json");
|
|
109819
|
+
if (existsSync70(manifestPath))
|
|
109434
109820
|
return;
|
|
109435
|
-
const claudeManifest = readJsonSafe4(
|
|
109821
|
+
const claudeManifest = readJsonSafe4(join137(pluginRoot, ".claude-plugin", "plugin.json"));
|
|
109436
109822
|
const manifest = pruneUndefined({
|
|
109437
109823
|
name: stringField(claudeManifest, "name") ?? "ck",
|
|
109438
109824
|
version: stringField(claudeManifest, "version") ?? "0.0.0",
|
|
@@ -109453,7 +109839,7 @@ function ensureCodexPluginManifest(pluginRoot) {
|
|
|
109453
109839
|
websiteURL: "https://github.com/claudekit/claudekit-engineer"
|
|
109454
109840
|
}
|
|
109455
109841
|
});
|
|
109456
|
-
mkdirSync6(
|
|
109842
|
+
mkdirSync6(join137(pluginRoot, ".codex-plugin"), { recursive: true });
|
|
109457
109843
|
writeFileSync8(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
109458
109844
|
`, "utf-8");
|
|
109459
109845
|
}
|
|
@@ -109514,11 +109900,18 @@ function logCodexPluginResult(result) {
|
|
|
109514
109900
|
break;
|
|
109515
109901
|
}
|
|
109516
109902
|
}
|
|
109903
|
+
function logCodexPluginCleanup(result) {
|
|
109904
|
+
if (result.removed || result.marketplaceRemoved) {
|
|
109905
|
+
logger.info("Removed ClaudeKit Engineer Codex plugin state for legacy install mode.");
|
|
109906
|
+
} else {
|
|
109907
|
+
logger.verbose("No ClaudeKit Engineer Codex plugin state found for legacy install mode.");
|
|
109908
|
+
}
|
|
109909
|
+
}
|
|
109517
109910
|
// src/commands/init/phases/selection-handler.ts
|
|
109518
109911
|
init_config_manager();
|
|
109519
109912
|
init_github_client();
|
|
109520
109913
|
import { mkdir as mkdir36 } from "node:fs/promises";
|
|
109521
|
-
import { join as
|
|
109914
|
+
import { join as join140, resolve as resolve48 } from "node:path";
|
|
109522
109915
|
|
|
109523
109916
|
// src/domains/github/kit-access-checker.ts
|
|
109524
109917
|
init_error2();
|
|
@@ -109690,8 +110083,8 @@ init_hook_health_checker();
|
|
|
109690
110083
|
|
|
109691
110084
|
// src/domains/installation/fresh-installer.ts
|
|
109692
110085
|
init_metadata_migration();
|
|
109693
|
-
import { existsSync as
|
|
109694
|
-
import { basename as basename28, dirname as dirname44, join as
|
|
110086
|
+
import { existsSync as existsSync71, readdirSync as readdirSync12, rmSync as rmSync6, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
|
|
110087
|
+
import { basename as basename28, dirname as dirname44, join as join138, resolve as resolve46 } from "node:path";
|
|
109695
110088
|
init_logger();
|
|
109696
110089
|
init_safe_spinner();
|
|
109697
110090
|
var import_fs_extra35 = __toESM(require_lib(), 1);
|
|
@@ -109743,15 +110136,15 @@ async function analyzeFreshInstallation(claudeDir3) {
|
|
|
109743
110136
|
};
|
|
109744
110137
|
}
|
|
109745
110138
|
function cleanupEmptyDirectories2(filePath, claudeDir3) {
|
|
109746
|
-
const normalizedClaudeDir =
|
|
109747
|
-
let currentDir =
|
|
110139
|
+
const normalizedClaudeDir = resolve46(claudeDir3);
|
|
110140
|
+
let currentDir = resolve46(dirname44(filePath));
|
|
109748
110141
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
|
|
109749
110142
|
try {
|
|
109750
|
-
const entries =
|
|
110143
|
+
const entries = readdirSync12(currentDir);
|
|
109751
110144
|
if (entries.length === 0) {
|
|
109752
110145
|
rmdirSync2(currentDir);
|
|
109753
110146
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
109754
|
-
currentDir =
|
|
110147
|
+
currentDir = resolve46(dirname44(currentDir));
|
|
109755
110148
|
} else {
|
|
109756
110149
|
break;
|
|
109757
110150
|
}
|
|
@@ -109773,8 +110166,8 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
|
|
|
109773
110166
|
logger.debug(`${KIT_MANIFEST_FILE} was self-tracked; skipping from delete loop — will be rewritten by updateMetadataAfterFresh`);
|
|
109774
110167
|
}
|
|
109775
110168
|
for (const file of filesToRemove) {
|
|
109776
|
-
const fullPath =
|
|
109777
|
-
if (!
|
|
110169
|
+
const fullPath = join138(claudeDir3, file.path);
|
|
110170
|
+
if (!existsSync71(fullPath)) {
|
|
109778
110171
|
continue;
|
|
109779
110172
|
}
|
|
109780
110173
|
try {
|
|
@@ -109801,7 +110194,7 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
|
|
|
109801
110194
|
};
|
|
109802
110195
|
}
|
|
109803
110196
|
async function updateMetadataAfterFresh(claudeDir3, removedFiles, metadata) {
|
|
109804
|
-
const metadataPath =
|
|
110197
|
+
const metadataPath = join138(claudeDir3, KIT_MANIFEST_FILE);
|
|
109805
110198
|
const removedSet = new Set(removedFiles);
|
|
109806
110199
|
if (metadata.kits) {
|
|
109807
110200
|
for (const kitName of Object.keys(metadata.kits)) {
|
|
@@ -109832,8 +110225,8 @@ function getFreshBackupTargets(claudeDir3, analysis, includeModified) {
|
|
|
109832
110225
|
mutatePaths: filesToRemove.length > 0 ? ["metadata.json"] : []
|
|
109833
110226
|
};
|
|
109834
110227
|
}
|
|
109835
|
-
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) =>
|
|
109836
|
-
if (
|
|
110228
|
+
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync71(join138(claudeDir3, subdir)));
|
|
110229
|
+
if (existsSync71(join138(claudeDir3, "metadata.json"))) {
|
|
109837
110230
|
deletePaths.push("metadata.json");
|
|
109838
110231
|
}
|
|
109839
110232
|
return {
|
|
@@ -109855,15 +110248,15 @@ async function removeSubdirectoriesFallback(claudeDir3) {
|
|
|
109855
110248
|
const removedFiles = [];
|
|
109856
110249
|
let removedDirCount = 0;
|
|
109857
110250
|
for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
|
|
109858
|
-
const subdirPath =
|
|
110251
|
+
const subdirPath = join138(claudeDir3, subdir);
|
|
109859
110252
|
if (await import_fs_extra35.pathExists(subdirPath)) {
|
|
109860
|
-
|
|
110253
|
+
rmSync6(subdirPath, { recursive: true, force: true });
|
|
109861
110254
|
removedDirCount++;
|
|
109862
110255
|
removedFiles.push(`${subdir}/ (entire directory)`);
|
|
109863
110256
|
logger.debug(`Removed subdirectory: ${subdir}/`);
|
|
109864
110257
|
}
|
|
109865
110258
|
}
|
|
109866
|
-
const metadataPath =
|
|
110259
|
+
const metadataPath = join138(claudeDir3, "metadata.json");
|
|
109867
110260
|
if (await import_fs_extra35.pathExists(metadataPath)) {
|
|
109868
110261
|
unlinkSync5(metadataPath);
|
|
109869
110262
|
removedFiles.push("metadata.json");
|
|
@@ -109941,7 +110334,7 @@ async function handleFreshInstallation(claudeDir3, prompts) {
|
|
|
109941
110334
|
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
109942
110335
|
import { cp as cp5, mkdir as mkdir35, readdir as readdir42, rename as rename11, rm as rm16, stat as stat22 } from "node:fs/promises";
|
|
109943
110336
|
import { homedir as homedir47 } from "node:os";
|
|
109944
|
-
import { dirname as dirname45, join as
|
|
110337
|
+
import { dirname as dirname45, join as join139, normalize as normalize11, resolve as resolve47 } from "node:path";
|
|
109945
110338
|
var LEGACY_KIT_MARKERS = [
|
|
109946
110339
|
"metadata.json",
|
|
109947
110340
|
".ck.json",
|
|
@@ -109967,7 +110360,7 @@ function uniqueNormalizedPaths(paths) {
|
|
|
109967
110360
|
const seen = new Set;
|
|
109968
110361
|
const result = [];
|
|
109969
110362
|
for (const path17 of paths) {
|
|
109970
|
-
const normalized = normalize11(
|
|
110363
|
+
const normalized = normalize11(resolve47(path17));
|
|
109971
110364
|
if (seen.has(normalized))
|
|
109972
110365
|
continue;
|
|
109973
110366
|
seen.add(normalized);
|
|
@@ -109980,10 +110373,10 @@ function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = ho
|
|
|
109980
110373
|
const localAppData = safeEnvPath(env2.LOCALAPPDATA);
|
|
109981
110374
|
const appData = safeEnvPath(env2.APPDATA);
|
|
109982
110375
|
if (localAppData) {
|
|
109983
|
-
candidates.push(
|
|
110376
|
+
candidates.push(join139(localAppData, ".claude"));
|
|
109984
110377
|
}
|
|
109985
110378
|
if (appData) {
|
|
109986
|
-
candidates.push(
|
|
110379
|
+
candidates.push(join139(appData, ".claude"));
|
|
109987
110380
|
}
|
|
109988
110381
|
if (homeDir) {
|
|
109989
110382
|
candidates.push(`${withoutTrailingSeparators(homeDir)}.claude`);
|
|
@@ -110001,7 +110394,7 @@ async function hasKitMarkers(dir) {
|
|
|
110001
110394
|
if (!await isDirectory(dir))
|
|
110002
110395
|
return false;
|
|
110003
110396
|
for (const marker of LEGACY_KIT_MARKERS) {
|
|
110004
|
-
if (await import_fs_extra36.pathExists(
|
|
110397
|
+
if (await import_fs_extra36.pathExists(join139(dir, marker))) {
|
|
110005
110398
|
return true;
|
|
110006
110399
|
}
|
|
110007
110400
|
}
|
|
@@ -110032,8 +110425,8 @@ async function repairLegacyWindowsGlobalKitDir(options2) {
|
|
|
110032
110425
|
if (safeEnvPath(env2.CLAUDE_CONFIG_DIR)) {
|
|
110033
110426
|
return { status: "skipped", reason: "custom-global-dir", candidateDirs: [] };
|
|
110034
110427
|
}
|
|
110035
|
-
const targetDir = normalize11(
|
|
110036
|
-
const candidateDirs = getLegacyWindowsGlobalKitDirCandidates(env2, options2.homeDir).filter((candidate) => normalize11(
|
|
110428
|
+
const targetDir = normalize11(resolve47(options2.targetDir));
|
|
110429
|
+
const candidateDirs = getLegacyWindowsGlobalKitDirCandidates(env2, options2.homeDir).filter((candidate) => normalize11(resolve47(candidate)) !== targetDir);
|
|
110037
110430
|
const legacyDirs = [];
|
|
110038
110431
|
for (const candidate of candidateDirs) {
|
|
110039
110432
|
if (await hasKitMarkers(candidate)) {
|
|
@@ -110256,7 +110649,7 @@ async function handleSelection(ctx) {
|
|
|
110256
110649
|
}
|
|
110257
110650
|
}
|
|
110258
110651
|
}
|
|
110259
|
-
const resolvedDir =
|
|
110652
|
+
const resolvedDir = resolve48(targetDir);
|
|
110260
110653
|
if (ctx.options.global) {
|
|
110261
110654
|
try {
|
|
110262
110655
|
const repairResult = await repairLegacyWindowsGlobalKitDir({ targetDir: resolvedDir });
|
|
@@ -110303,7 +110696,7 @@ async function handleSelection(ctx) {
|
|
|
110303
110696
|
}
|
|
110304
110697
|
if (!ctx.options.fresh) {
|
|
110305
110698
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110306
|
-
const claudeDir3 = prefix ?
|
|
110699
|
+
const claudeDir3 = prefix ? join140(resolvedDir, prefix) : resolvedDir;
|
|
110307
110700
|
try {
|
|
110308
110701
|
const existingMetadata = await readManifest(claudeDir3);
|
|
110309
110702
|
if (existingMetadata?.kits) {
|
|
@@ -110340,7 +110733,7 @@ async function handleSelection(ctx) {
|
|
|
110340
110733
|
}
|
|
110341
110734
|
if (ctx.options.fresh) {
|
|
110342
110735
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110343
|
-
const claudeDir3 = prefix ?
|
|
110736
|
+
const claudeDir3 = prefix ? join140(resolvedDir, prefix) : resolvedDir;
|
|
110344
110737
|
const canProceed = await handleFreshInstallation(claudeDir3, ctx.prompts);
|
|
110345
110738
|
if (!canProceed) {
|
|
110346
110739
|
return { ...ctx, cancelled: true };
|
|
@@ -110360,7 +110753,7 @@ async function handleSelection(ctx) {
|
|
|
110360
110753
|
let currentVersion = null;
|
|
110361
110754
|
try {
|
|
110362
110755
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110363
|
-
const claudeDir3 = prefix ?
|
|
110756
|
+
const claudeDir3 = prefix ? join140(resolvedDir, prefix) : resolvedDir;
|
|
110364
110757
|
const existingMetadata = await readManifest(claudeDir3);
|
|
110365
110758
|
currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
|
|
110366
110759
|
if (currentVersion) {
|
|
@@ -110429,7 +110822,7 @@ async function handleSelection(ctx) {
|
|
|
110429
110822
|
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && !ctx.options.restoreCkHooks && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
110430
110823
|
try {
|
|
110431
110824
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110432
|
-
const claudeDir3 = prefix ?
|
|
110825
|
+
const claudeDir3 = prefix ? join140(resolvedDir, prefix) : resolvedDir;
|
|
110433
110826
|
const existingMetadata = await readManifest(claudeDir3);
|
|
110434
110827
|
const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
|
|
110435
110828
|
if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
|
|
@@ -110458,7 +110851,7 @@ async function handleSelection(ctx) {
|
|
|
110458
110851
|
}
|
|
110459
110852
|
// src/commands/init/phases/sync-handler.ts
|
|
110460
110853
|
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";
|
|
110461
|
-
import { dirname as dirname46, join as
|
|
110854
|
+
import { dirname as dirname46, join as join141, resolve as resolve49 } from "node:path";
|
|
110462
110855
|
init_logger();
|
|
110463
110856
|
init_path_resolver();
|
|
110464
110857
|
var import_fs_extra38 = __toESM(require_lib(), 1);
|
|
@@ -110467,14 +110860,14 @@ async function handleSync(ctx) {
|
|
|
110467
110860
|
if (!ctx.options.sync) {
|
|
110468
110861
|
return ctx;
|
|
110469
110862
|
}
|
|
110470
|
-
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() :
|
|
110471
|
-
const claudeDir3 = ctx.options.global ? resolvedDir :
|
|
110863
|
+
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve49(ctx.options.dir || ".");
|
|
110864
|
+
const claudeDir3 = ctx.options.global ? resolvedDir : join141(resolvedDir, ".claude");
|
|
110472
110865
|
if (!await import_fs_extra38.pathExists(claudeDir3)) {
|
|
110473
110866
|
logger.error("Cannot sync: no .claude directory found");
|
|
110474
110867
|
ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
|
|
110475
110868
|
return { ...ctx, cancelled: true };
|
|
110476
110869
|
}
|
|
110477
|
-
const metadataPath =
|
|
110870
|
+
const metadataPath = join141(claudeDir3, "metadata.json");
|
|
110478
110871
|
if (!await import_fs_extra38.pathExists(metadataPath)) {
|
|
110479
110872
|
logger.error("Cannot sync: no metadata.json found");
|
|
110480
110873
|
ctx.prompts.note(`Your installation may be from an older version.
|
|
@@ -110574,7 +110967,7 @@ function getLockTimeout() {
|
|
|
110574
110967
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
110575
110968
|
async function acquireSyncLock(global3) {
|
|
110576
110969
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
110577
|
-
const lockPath =
|
|
110970
|
+
const lockPath = join141(cacheDir, ".sync-lock");
|
|
110578
110971
|
const startTime = Date.now();
|
|
110579
110972
|
const lockTimeout = getLockTimeout();
|
|
110580
110973
|
await mkdir37(dirname46(lockPath), { recursive: true });
|
|
@@ -110601,7 +110994,7 @@ async function acquireSyncLock(global3) {
|
|
|
110601
110994
|
}
|
|
110602
110995
|
logger.debug(`Lock stat failed: ${statError}`);
|
|
110603
110996
|
}
|
|
110604
|
-
await new Promise((
|
|
110997
|
+
await new Promise((resolve50) => setTimeout(resolve50, 100));
|
|
110605
110998
|
continue;
|
|
110606
110999
|
}
|
|
110607
111000
|
throw err;
|
|
@@ -110620,11 +111013,11 @@ async function executeSyncMerge(ctx) {
|
|
|
110620
111013
|
const releaseLock = await acquireSyncLock(ctx.options.global);
|
|
110621
111014
|
try {
|
|
110622
111015
|
const trackedFiles = ctx.syncTrackedFiles;
|
|
110623
|
-
const upstreamDir = ctx.options.global ?
|
|
111016
|
+
const upstreamDir = ctx.options.global ? join141(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
110624
111017
|
let sourceMetadata = null;
|
|
110625
111018
|
let deletions = [];
|
|
110626
111019
|
try {
|
|
110627
|
-
const sourceMetadataPath =
|
|
111020
|
+
const sourceMetadataPath = join141(upstreamDir, "metadata.json");
|
|
110628
111021
|
if (await import_fs_extra38.pathExists(sourceMetadataPath)) {
|
|
110629
111022
|
const content = await readFile61(sourceMetadataPath, "utf-8");
|
|
110630
111023
|
sourceMetadata = JSON.parse(content);
|
|
@@ -110686,7 +111079,7 @@ async function executeSyncMerge(ctx) {
|
|
|
110686
111079
|
try {
|
|
110687
111080
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
110688
111081
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
110689
|
-
const targetDir =
|
|
111082
|
+
const targetDir = join141(targetPath, "..");
|
|
110690
111083
|
try {
|
|
110691
111084
|
await mkdir37(targetDir, { recursive: true });
|
|
110692
111085
|
} catch (mkdirError) {
|
|
@@ -110857,7 +111250,7 @@ async function createBackup(claudeDir3, files, backupDir) {
|
|
|
110857
111250
|
const sourcePath = await validateSyncPath(claudeDir3, file.path);
|
|
110858
111251
|
if (await import_fs_extra38.pathExists(sourcePath)) {
|
|
110859
111252
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
110860
|
-
const targetDir =
|
|
111253
|
+
const targetDir = join141(targetPath, "..");
|
|
110861
111254
|
await mkdir37(targetDir, { recursive: true });
|
|
110862
111255
|
await copyFile8(sourcePath, targetPath);
|
|
110863
111256
|
}
|
|
@@ -110872,7 +111265,7 @@ async function createBackup(claudeDir3, files, backupDir) {
|
|
|
110872
111265
|
}
|
|
110873
111266
|
// src/commands/init/phases/transform-handler.ts
|
|
110874
111267
|
init_config_manager();
|
|
110875
|
-
import { join as
|
|
111268
|
+
import { join as join145 } from "node:path";
|
|
110876
111269
|
|
|
110877
111270
|
// src/services/transformers/folder-path-transformer.ts
|
|
110878
111271
|
init_logger();
|
|
@@ -110883,38 +111276,38 @@ init_logger();
|
|
|
110883
111276
|
init_types3();
|
|
110884
111277
|
var import_fs_extra39 = __toESM(require_lib(), 1);
|
|
110885
111278
|
import { rename as rename13, rm as rm17 } from "node:fs/promises";
|
|
110886
|
-
import { join as
|
|
111279
|
+
import { join as join142, relative as relative32 } from "node:path";
|
|
110887
111280
|
async function collectDirsToRename(extractDir, folders) {
|
|
110888
111281
|
const dirsToRename = [];
|
|
110889
111282
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
110890
|
-
const docsPath =
|
|
111283
|
+
const docsPath = join142(extractDir, DEFAULT_FOLDERS.docs);
|
|
110891
111284
|
if (await import_fs_extra39.pathExists(docsPath)) {
|
|
110892
111285
|
dirsToRename.push({
|
|
110893
111286
|
from: docsPath,
|
|
110894
|
-
to:
|
|
111287
|
+
to: join142(extractDir, folders.docs)
|
|
110895
111288
|
});
|
|
110896
111289
|
}
|
|
110897
|
-
const claudeDocsPath =
|
|
111290
|
+
const claudeDocsPath = join142(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
110898
111291
|
if (await import_fs_extra39.pathExists(claudeDocsPath)) {
|
|
110899
111292
|
dirsToRename.push({
|
|
110900
111293
|
from: claudeDocsPath,
|
|
110901
|
-
to:
|
|
111294
|
+
to: join142(extractDir, ".claude", folders.docs)
|
|
110902
111295
|
});
|
|
110903
111296
|
}
|
|
110904
111297
|
}
|
|
110905
111298
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
110906
|
-
const plansPath =
|
|
111299
|
+
const plansPath = join142(extractDir, DEFAULT_FOLDERS.plans);
|
|
110907
111300
|
if (await import_fs_extra39.pathExists(plansPath)) {
|
|
110908
111301
|
dirsToRename.push({
|
|
110909
111302
|
from: plansPath,
|
|
110910
|
-
to:
|
|
111303
|
+
to: join142(extractDir, folders.plans)
|
|
110911
111304
|
});
|
|
110912
111305
|
}
|
|
110913
|
-
const claudePlansPath =
|
|
111306
|
+
const claudePlansPath = join142(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
110914
111307
|
if (await import_fs_extra39.pathExists(claudePlansPath)) {
|
|
110915
111308
|
dirsToRename.push({
|
|
110916
111309
|
from: claudePlansPath,
|
|
110917
|
-
to:
|
|
111310
|
+
to: join142(extractDir, ".claude", folders.plans)
|
|
110918
111311
|
});
|
|
110919
111312
|
}
|
|
110920
111313
|
}
|
|
@@ -110937,11 +111330,11 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
110937
111330
|
let foldersRenamed = 0;
|
|
110938
111331
|
for (const { from, to } of dirsToRename) {
|
|
110939
111332
|
if (options2.dryRun) {
|
|
110940
|
-
logger.info(`[dry-run] Would rename: ${
|
|
111333
|
+
logger.info(`[dry-run] Would rename: ${relative32(extractDir, from)} -> ${relative32(extractDir, to)}`);
|
|
110941
111334
|
} else {
|
|
110942
111335
|
try {
|
|
110943
111336
|
await moveAcrossDevices(from, to);
|
|
110944
|
-
logger.debug(`Renamed: ${
|
|
111337
|
+
logger.debug(`Renamed: ${relative32(extractDir, from)} -> ${relative32(extractDir, to)}`);
|
|
110945
111338
|
foldersRenamed++;
|
|
110946
111339
|
} catch (error) {
|
|
110947
111340
|
logger.warning(`Failed to rename ${from}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
@@ -110955,7 +111348,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
110955
111348
|
init_logger();
|
|
110956
111349
|
init_types3();
|
|
110957
111350
|
import { readFile as readFile62, readdir as readdir43, writeFile as writeFile36 } from "node:fs/promises";
|
|
110958
|
-
import { join as
|
|
111351
|
+
import { join as join143, relative as relative33 } from "node:path";
|
|
110959
111352
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
110960
111353
|
".md",
|
|
110961
111354
|
".txt",
|
|
@@ -111008,7 +111401,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
111008
111401
|
let replacementsCount = 0;
|
|
111009
111402
|
const entries = await readdir43(dir, { withFileTypes: true });
|
|
111010
111403
|
for (const entry of entries) {
|
|
111011
|
-
const fullPath =
|
|
111404
|
+
const fullPath = join143(dir, entry.name);
|
|
111012
111405
|
if (entry.isDirectory()) {
|
|
111013
111406
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
111014
111407
|
continue;
|
|
@@ -111035,10 +111428,10 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
111035
111428
|
}
|
|
111036
111429
|
if (changeCount > 0) {
|
|
111037
111430
|
if (options2.dryRun) {
|
|
111038
|
-
logger.debug(`[dry-run] Would update ${
|
|
111431
|
+
logger.debug(`[dry-run] Would update ${relative33(dir, fullPath)}: ${changeCount} replacement(s)`);
|
|
111039
111432
|
} else {
|
|
111040
111433
|
await writeFile36(fullPath, newContent, "utf-8");
|
|
111041
|
-
logger.debug(`Updated ${
|
|
111434
|
+
logger.debug(`Updated ${relative33(dir, fullPath)}: ${changeCount} replacement(s)`);
|
|
111042
111435
|
}
|
|
111043
111436
|
filesChanged++;
|
|
111044
111437
|
replacementsCount += changeCount;
|
|
@@ -111145,7 +111538,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
111145
111538
|
init_logger();
|
|
111146
111539
|
import { readFile as readFile63, readdir as readdir44, writeFile as writeFile37 } from "node:fs/promises";
|
|
111147
111540
|
import { homedir as homedir48, platform as platform16 } from "node:os";
|
|
111148
|
-
import { extname as extname7, join as
|
|
111541
|
+
import { extname as extname7, join as join144 } from "node:path";
|
|
111149
111542
|
var IS_WINDOWS3 = platform16() === "win32";
|
|
111150
111543
|
var HOME_PREFIX = "$HOME";
|
|
111151
111544
|
function getHomeDirPrefix() {
|
|
@@ -111155,7 +111548,7 @@ function normalizeInstallPath(path17) {
|
|
|
111155
111548
|
return path17.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
111156
111549
|
}
|
|
111157
111550
|
function getDefaultGlobalClaudeDir() {
|
|
111158
|
-
return normalizeInstallPath(
|
|
111551
|
+
return normalizeInstallPath(join144(homedir48(), ".claude"));
|
|
111159
111552
|
}
|
|
111160
111553
|
function getCustomGlobalClaudeDir(targetClaudeDir) {
|
|
111161
111554
|
if (!targetClaudeDir)
|
|
@@ -111286,7 +111679,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
111286
111679
|
async function processDirectory2(dir) {
|
|
111287
111680
|
const entries = await readdir44(dir, { withFileTypes: true });
|
|
111288
111681
|
for (const entry of entries) {
|
|
111289
|
-
const fullPath =
|
|
111682
|
+
const fullPath = join144(dir, entry.name);
|
|
111290
111683
|
if (entry.isDirectory()) {
|
|
111291
111684
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
111292
111685
|
continue;
|
|
@@ -111365,7 +111758,7 @@ async function handleTransforms(ctx) {
|
|
|
111365
111758
|
logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
|
|
111366
111759
|
}
|
|
111367
111760
|
}
|
|
111368
|
-
const claudeDir3 = ctx.options.global ? ctx.resolvedDir :
|
|
111761
|
+
const claudeDir3 = ctx.options.global ? ctx.resolvedDir : join145(ctx.resolvedDir, ".claude");
|
|
111369
111762
|
return {
|
|
111370
111763
|
...ctx,
|
|
111371
111764
|
foldersConfig,
|
|
@@ -111441,7 +111834,8 @@ function createInitContext(rawOptions, prompts) {
|
|
|
111441
111834
|
dryRun: false,
|
|
111442
111835
|
prefix: false,
|
|
111443
111836
|
sync: false,
|
|
111444
|
-
useGit: false
|
|
111837
|
+
useGit: false,
|
|
111838
|
+
installMode: "auto"
|
|
111445
111839
|
};
|
|
111446
111840
|
return {
|
|
111447
111841
|
rawOptions,
|
|
@@ -111589,10 +111983,10 @@ async function initCommand(options2) {
|
|
|
111589
111983
|
// src/commands/migrate/migrate-command.ts
|
|
111590
111984
|
init_dist2();
|
|
111591
111985
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
111592
|
-
import { existsSync as
|
|
111986
|
+
import { existsSync as existsSync72 } from "node:fs";
|
|
111593
111987
|
import { readFile as readFile67, rm as rm18, unlink as unlink14 } from "node:fs/promises";
|
|
111594
111988
|
import { homedir as homedir52 } from "node:os";
|
|
111595
|
-
import { basename as basename30, dirname as dirname49, join as
|
|
111989
|
+
import { basename as basename30, dirname as dirname49, join as join149, resolve as resolve50 } from "node:path";
|
|
111596
111990
|
init_logger();
|
|
111597
111991
|
|
|
111598
111992
|
// src/ui/ck-cli-design/next-steps-footer.ts
|
|
@@ -111807,13 +112201,13 @@ init_dist2();
|
|
|
111807
112201
|
init_model_taxonomy();
|
|
111808
112202
|
import { mkdir as mkdir39, readFile as readFile66, writeFile as writeFile39 } from "node:fs/promises";
|
|
111809
112203
|
import { homedir as homedir51 } from "node:os";
|
|
111810
|
-
import { dirname as dirname47, join as
|
|
112204
|
+
import { dirname as dirname47, join as join148 } from "node:path";
|
|
111811
112205
|
|
|
111812
112206
|
// src/commands/portable/models-dev-cache.ts
|
|
111813
112207
|
init_logger();
|
|
111814
112208
|
import { mkdir as mkdir38, readFile as readFile64, rename as rename14, writeFile as writeFile38 } from "node:fs/promises";
|
|
111815
112209
|
import { homedir as homedir49 } from "node:os";
|
|
111816
|
-
import { join as
|
|
112210
|
+
import { join as join146 } from "node:path";
|
|
111817
112211
|
|
|
111818
112212
|
class ModelsDevUnavailableError extends Error {
|
|
111819
112213
|
constructor(message, cause) {
|
|
@@ -111825,13 +112219,13 @@ var MODELS_DEV_URL = "https://models.dev/api.json";
|
|
|
111825
112219
|
var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
111826
112220
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
111827
112221
|
function defaultCacheDir() {
|
|
111828
|
-
return
|
|
112222
|
+
return join146(homedir49(), ".config", "claudekit", "cache");
|
|
111829
112223
|
}
|
|
111830
112224
|
function cacheFilePath(cacheDir) {
|
|
111831
|
-
return
|
|
112225
|
+
return join146(cacheDir, "models-dev.json");
|
|
111832
112226
|
}
|
|
111833
112227
|
function tmpFilePath(cacheDir) {
|
|
111834
|
-
return
|
|
112228
|
+
return join146(cacheDir, "models-dev.json.tmp");
|
|
111835
112229
|
}
|
|
111836
112230
|
async function readCacheEntry(cacheDir) {
|
|
111837
112231
|
const filePath = cacheFilePath(cacheDir);
|
|
@@ -111906,14 +112300,14 @@ async function getModelsDevCatalog(opts = {}) {
|
|
|
111906
112300
|
init_logger();
|
|
111907
112301
|
import { readFile as readFile65 } from "node:fs/promises";
|
|
111908
112302
|
import { homedir as homedir50, platform as platform17 } from "node:os";
|
|
111909
|
-
import { join as
|
|
112303
|
+
import { join as join147 } from "node:path";
|
|
111910
112304
|
function resolveOpenCodeAuthPath(homeDir) {
|
|
111911
112305
|
if (platform17() === "win32") {
|
|
111912
|
-
const dataRoot2 = process.env.LOCALAPPDATA ??
|
|
111913
|
-
return
|
|
112306
|
+
const dataRoot2 = process.env.LOCALAPPDATA ?? join147(homeDir, "AppData", "Local");
|
|
112307
|
+
return join147(dataRoot2, "opencode", "auth.json");
|
|
111914
112308
|
}
|
|
111915
|
-
const dataRoot = process.env.XDG_DATA_HOME ??
|
|
111916
|
-
return
|
|
112309
|
+
const dataRoot = process.env.XDG_DATA_HOME ?? join147(homeDir, ".local", "share");
|
|
112310
|
+
return join147(dataRoot, "opencode", "auth.json");
|
|
111917
112311
|
}
|
|
111918
112312
|
async function readAuthedProviders(homeDir) {
|
|
111919
112313
|
const authPath = resolveOpenCodeAuthPath(homeDir);
|
|
@@ -112015,9 +112409,9 @@ function messageForReason(reason) {
|
|
|
112015
112409
|
}
|
|
112016
112410
|
function getOpenCodeConfigPath(options2) {
|
|
112017
112411
|
if (options2.global) {
|
|
112018
|
-
return
|
|
112412
|
+
return join148(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
|
|
112019
112413
|
}
|
|
112020
|
-
return
|
|
112414
|
+
return join148(options2.cwd ?? process.cwd(), "opencode.json");
|
|
112021
112415
|
}
|
|
112022
112416
|
function makeCatalogOpts(options2) {
|
|
112023
112417
|
return {
|
|
@@ -112890,7 +113284,7 @@ function appendFallbackSkillActionsToPlan(plan, skills, selectedProviders, insta
|
|
|
112890
113284
|
reason: "New item, not previously installed",
|
|
112891
113285
|
reasonCode: "new-item",
|
|
112892
113286
|
reasonCopy: "New - not previously installed",
|
|
112893
|
-
targetPath:
|
|
113287
|
+
targetPath: join149(basePath, skill.name),
|
|
112894
113288
|
type: "skill"
|
|
112895
113289
|
});
|
|
112896
113290
|
}
|
|
@@ -113045,9 +113439,9 @@ function shouldExecuteAction2(action) {
|
|
|
113045
113439
|
}
|
|
113046
113440
|
async function executeDeleteAction(action, options2) {
|
|
113047
113441
|
const preservePaths = options2?.preservePaths ?? new Set;
|
|
113048
|
-
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(
|
|
113442
|
+
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve50(action.targetPath));
|
|
113049
113443
|
try {
|
|
113050
|
-
if (!shouldPreserveTarget && action.targetPath &&
|
|
113444
|
+
if (!shouldPreserveTarget && action.targetPath && existsSync72(action.targetPath)) {
|
|
113051
113445
|
await rm18(action.targetPath, { recursive: true, force: true });
|
|
113052
113446
|
}
|
|
113053
113447
|
await removePortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
|
|
@@ -113076,7 +113470,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
113076
113470
|
}
|
|
113077
113471
|
}
|
|
113078
113472
|
function hasSuccessfulReplacementWrite(action, results) {
|
|
113079
|
-
return results.some((result) => result.success && !result.skipped && result.provider === action.provider && replacementTypeMatches(action.type, result.portableType) && replacementItemMatches(action, result) && result.path.length > 0 &&
|
|
113473
|
+
return results.some((result) => result.success && !result.skipped && result.provider === action.provider && replacementTypeMatches(action.type, result.portableType) && replacementItemMatches(action, result) && result.path.length > 0 && resolve50(result.path) !== resolve50(action.targetPath));
|
|
113080
113474
|
}
|
|
113081
113475
|
function replacementTypeMatches(actionType, resultType) {
|
|
113082
113476
|
return resultType === actionType || actionType === "command" && resultType === "skill";
|
|
@@ -113118,9 +113512,9 @@ function resolveHookTargetPath(item, provider, global3) {
|
|
|
113118
113512
|
const converted = convertItem(item, pathConfig.format, provider, { global: global3 });
|
|
113119
113513
|
if (converted.error)
|
|
113120
113514
|
return null;
|
|
113121
|
-
const targetPath = pathConfig.writeStrategy === "single-file" ? basePath :
|
|
113122
|
-
const resolvedTarget =
|
|
113123
|
-
const resolvedBase =
|
|
113515
|
+
const targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join149(basePath, converted.filename);
|
|
113516
|
+
const resolvedTarget = resolve50(targetPath).replace(/\\/g, "/");
|
|
113517
|
+
const resolvedBase = resolve50(basePath).replace(/\\/g, "/").replace(/\/+$/, "");
|
|
113124
113518
|
if (resolvedTarget !== resolvedBase && !resolvedTarget.startsWith(`${resolvedBase}/`)) {
|
|
113125
113519
|
return null;
|
|
113126
113520
|
}
|
|
@@ -113129,8 +113523,8 @@ function resolveHookTargetPath(item, provider, global3) {
|
|
|
113129
113523
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
113130
113524
|
if (!skillSourcePath)
|
|
113131
113525
|
return;
|
|
113132
|
-
const sourceMetadataPath =
|
|
113133
|
-
if (!
|
|
113526
|
+
const sourceMetadataPath = join149(resolve50(skillSourcePath, ".."), "metadata.json");
|
|
113527
|
+
if (!existsSync72(sourceMetadataPath))
|
|
113134
113528
|
return;
|
|
113135
113529
|
let sourceMetadata;
|
|
113136
113530
|
try {
|
|
@@ -113142,8 +113536,8 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
113142
113536
|
}
|
|
113143
113537
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
113144
113538
|
return;
|
|
113145
|
-
const claudeDir3 = installGlobally ?
|
|
113146
|
-
if (!
|
|
113539
|
+
const claudeDir3 = installGlobally ? join149(homedir52(), ".claude") : join149(process.cwd(), ".claude");
|
|
113540
|
+
if (!existsSync72(claudeDir3))
|
|
113147
113541
|
return;
|
|
113148
113542
|
try {
|
|
113149
113543
|
const result = await handleDeletions(sourceMetadata, claudeDir3, inferKitTypeFromSourceMetadata(sourceMetadata));
|
|
@@ -113270,8 +113664,8 @@ async function migrateCommand(options2) {
|
|
|
113270
113664
|
let requestedGlobal = options2.global ?? false;
|
|
113271
113665
|
let installGlobally = requestedGlobal;
|
|
113272
113666
|
if (options2.global === undefined && !options2.yes) {
|
|
113273
|
-
const projectTarget =
|
|
113274
|
-
const globalTarget =
|
|
113667
|
+
const projectTarget = join149(process.cwd(), ".claude");
|
|
113668
|
+
const globalTarget = join149(homedir52(), ".claude");
|
|
113275
113669
|
const scopeChoice = await ie({
|
|
113276
113670
|
message: "Installation scope",
|
|
113277
113671
|
options: [
|
|
@@ -113344,7 +113738,7 @@ async function migrateCommand(options2) {
|
|
|
113344
113738
|
}).join(`
|
|
113345
113739
|
`));
|
|
113346
113740
|
if (sourceGlobalOnly) {
|
|
113347
|
-
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(
|
|
113741
|
+
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join149(homedir52(), ".claude"))}`));
|
|
113348
113742
|
} else {
|
|
113349
113743
|
f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
|
|
113350
113744
|
}
|
|
@@ -113435,7 +113829,7 @@ async function migrateCommand(options2) {
|
|
|
113435
113829
|
const interactive = process.stdout.isTTY && !options2.yes;
|
|
113436
113830
|
const conflictActions = plan.actions.filter((a3) => a3.action === "conflict");
|
|
113437
113831
|
for (const action of conflictActions) {
|
|
113438
|
-
if (!action.diff && action.targetPath &&
|
|
113832
|
+
if (!action.diff && action.targetPath && existsSync72(action.targetPath)) {
|
|
113439
113833
|
try {
|
|
113440
113834
|
const targetContent = await readFile67(action.targetPath, "utf-8");
|
|
113441
113835
|
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);
|
|
@@ -113534,9 +113928,9 @@ async function migrateCommand(options2) {
|
|
|
113534
113928
|
const progressSink = createMigrateProgressSink(writeTasks.length + plannedDeleteActions.length);
|
|
113535
113929
|
const writtenPaths = new Set;
|
|
113536
113930
|
const recordHookTargetForSettings = (provider, global3, targetPath) => {
|
|
113537
|
-
if (targetPath.length === 0 || !
|
|
113931
|
+
if (targetPath.length === 0 || !existsSync72(targetPath))
|
|
113538
113932
|
return;
|
|
113539
|
-
const resolvedPath =
|
|
113933
|
+
const resolvedPath = resolve50(targetPath);
|
|
113540
113934
|
const entry = successfulHookFiles.get(provider) ?? {
|
|
113541
113935
|
files: [],
|
|
113542
113936
|
global: global3
|
|
@@ -113554,7 +113948,7 @@ async function migrateCommand(options2) {
|
|
|
113554
113948
|
const recordSuccessfulWrites = (task, taskResults) => {
|
|
113555
113949
|
for (const result of taskResults.filter((entry) => entry.success)) {
|
|
113556
113950
|
if (!result.skipped && result.path.length > 0) {
|
|
113557
|
-
writtenPaths.add(
|
|
113951
|
+
writtenPaths.add(resolve50(result.path));
|
|
113558
113952
|
}
|
|
113559
113953
|
if (task.type === "hooks") {
|
|
113560
113954
|
recordHookTargetForSettings(task.provider, task.global, result.path);
|
|
@@ -113653,7 +114047,7 @@ async function migrateCommand(options2) {
|
|
|
113653
114047
|
for (const [hooksProvider, entry] of successfulHookFiles) {
|
|
113654
114048
|
if (entry.files.length === 0)
|
|
113655
114049
|
continue;
|
|
113656
|
-
const sourceSettingsPath = hooksSource ?
|
|
114050
|
+
const sourceSettingsPath = hooksSource ? join149(dirname49(hooksSource), "settings.json") : undefined;
|
|
113657
114051
|
const mergeResult = await migrateHooksSettings({
|
|
113658
114052
|
sourceProvider: "claude-code",
|
|
113659
114053
|
targetProvider: hooksProvider,
|
|
@@ -113718,7 +114112,7 @@ async function migrateCommand(options2) {
|
|
|
113718
114112
|
}
|
|
113719
114113
|
}
|
|
113720
114114
|
try {
|
|
113721
|
-
const kitRoot = (agentSource ?
|
|
114115
|
+
const kitRoot = (agentSource ? resolve50(agentSource, "..") : null) ?? (commandSource ? resolve50(commandSource, "..") : null) ?? (skillSource ? resolve50(skillSource, "..") : null) ?? null;
|
|
113722
114116
|
const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
|
|
113723
114117
|
if (manifest?.cliVersion) {
|
|
113724
114118
|
await updateAppliedManifestVersion(manifest.cliVersion);
|
|
@@ -113766,7 +114160,7 @@ async function migrateCommand(options2) {
|
|
|
113766
114160
|
async function rollbackResults(results) {
|
|
113767
114161
|
const rolledBackPaths = new Set;
|
|
113768
114162
|
for (const result of results) {
|
|
113769
|
-
if (!result.path || !
|
|
114163
|
+
if (!result.path || !existsSync72(result.path))
|
|
113770
114164
|
continue;
|
|
113771
114165
|
try {
|
|
113772
114166
|
if (result.overwritten)
|
|
@@ -113889,7 +114283,7 @@ var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
|
113889
114283
|
|
|
113890
114284
|
// src/commands/new/phases/directory-setup.ts
|
|
113891
114285
|
init_config_manager();
|
|
113892
|
-
import { resolve as
|
|
114286
|
+
import { resolve as resolve51 } from "node:path";
|
|
113893
114287
|
init_logger();
|
|
113894
114288
|
init_path_resolver();
|
|
113895
114289
|
init_types3();
|
|
@@ -113974,7 +114368,7 @@ async function directorySetup(validOptions, prompts) {
|
|
|
113974
114368
|
targetDir = await prompts.getDirectory(targetDir);
|
|
113975
114369
|
}
|
|
113976
114370
|
}
|
|
113977
|
-
const resolvedDir =
|
|
114371
|
+
const resolvedDir = resolve51(targetDir);
|
|
113978
114372
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
113979
114373
|
if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
113980
114374
|
logger.warning("You're creating a project at HOME directory.");
|
|
@@ -114031,7 +114425,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
114031
114425
|
// src/commands/new/phases/project-creation.ts
|
|
114032
114426
|
init_config_manager();
|
|
114033
114427
|
init_github_client();
|
|
114034
|
-
import { join as
|
|
114428
|
+
import { join as join150 } from "node:path";
|
|
114035
114429
|
init_logger();
|
|
114036
114430
|
init_output_manager();
|
|
114037
114431
|
init_types3();
|
|
@@ -114157,7 +114551,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
114157
114551
|
output.section("Installing");
|
|
114158
114552
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
114159
114553
|
const merger = new FileMerger;
|
|
114160
|
-
const claudeDir3 =
|
|
114554
|
+
const claudeDir3 = join150(resolvedDir, ".claude");
|
|
114161
114555
|
merger.setMultiKitContext(claudeDir3, kit);
|
|
114162
114556
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
114163
114557
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -114204,7 +114598,7 @@ async function handleProjectCreation(ctx) {
|
|
|
114204
114598
|
}
|
|
114205
114599
|
// src/commands/new/phases/post-setup.ts
|
|
114206
114600
|
init_projects_registry();
|
|
114207
|
-
import { join as
|
|
114601
|
+
import { join as join151 } from "node:path";
|
|
114208
114602
|
init_package_installer();
|
|
114209
114603
|
init_logger();
|
|
114210
114604
|
init_path_resolver();
|
|
@@ -114236,9 +114630,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
114236
114630
|
withSudo: validOptions.withSudo
|
|
114237
114631
|
});
|
|
114238
114632
|
}
|
|
114239
|
-
const claudeDir3 =
|
|
114633
|
+
const claudeDir3 = join151(resolvedDir, ".claude");
|
|
114240
114634
|
await promptSetupWizardIfNeeded({
|
|
114241
|
-
envPath:
|
|
114635
|
+
envPath: join151(claudeDir3, ".env"),
|
|
114242
114636
|
claudeDir: claudeDir3,
|
|
114243
114637
|
isGlobal: false,
|
|
114244
114638
|
isNonInteractive: isNonInteractive2,
|
|
@@ -114307,8 +114701,8 @@ Please use only one download method.`);
|
|
|
114307
114701
|
}
|
|
114308
114702
|
// src/commands/plan/plan-command.ts
|
|
114309
114703
|
init_output_manager();
|
|
114310
|
-
import { existsSync as
|
|
114311
|
-
import { dirname as dirname53, isAbsolute as isAbsolute15, join as
|
|
114704
|
+
import { existsSync as existsSync75, statSync as statSync13 } from "node:fs";
|
|
114705
|
+
import { dirname as dirname53, isAbsolute as isAbsolute15, join as join154, parse as parse7, resolve as resolve55 } from "node:path";
|
|
114312
114706
|
|
|
114313
114707
|
// src/commands/plan/plan-read-handlers.ts
|
|
114314
114708
|
init_config();
|
|
@@ -114317,15 +114711,15 @@ init_plans_registry();
|
|
|
114317
114711
|
init_logger();
|
|
114318
114712
|
init_output_manager();
|
|
114319
114713
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
114320
|
-
import { existsSync as
|
|
114321
|
-
import { basename as basename31, dirname as dirname51, join as
|
|
114714
|
+
import { existsSync as existsSync74, statSync as statSync12 } from "node:fs";
|
|
114715
|
+
import { basename as basename31, dirname as dirname51, join as join153, relative as relative34, resolve as resolve53 } from "node:path";
|
|
114322
114716
|
|
|
114323
114717
|
// src/commands/plan/plan-dependencies.ts
|
|
114324
114718
|
init_config();
|
|
114325
114719
|
init_plan_parser();
|
|
114326
114720
|
init_plans_registry();
|
|
114327
|
-
import { existsSync as
|
|
114328
|
-
import { dirname as dirname50, join as
|
|
114721
|
+
import { existsSync as existsSync73 } from "node:fs";
|
|
114722
|
+
import { dirname as dirname50, join as join152 } from "node:path";
|
|
114329
114723
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
114330
114724
|
if (references.length === 0)
|
|
114331
114725
|
return [];
|
|
@@ -114345,9 +114739,9 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
|
|
|
114345
114739
|
};
|
|
114346
114740
|
}
|
|
114347
114741
|
const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
|
|
114348
|
-
const planFile =
|
|
114742
|
+
const planFile = join152(scopeRoot, planId, "plan.md");
|
|
114349
114743
|
const isSelfReference = planFile === currentPlanFile;
|
|
114350
|
-
if (!
|
|
114744
|
+
if (!existsSync73(planFile)) {
|
|
114351
114745
|
return {
|
|
114352
114746
|
reference,
|
|
114353
114747
|
scope,
|
|
@@ -114376,14 +114770,14 @@ init_config();
|
|
|
114376
114770
|
init_plan_parser();
|
|
114377
114771
|
init_plan_scope();
|
|
114378
114772
|
init_plans_registry();
|
|
114379
|
-
import { isAbsolute as isAbsolute14, resolve as
|
|
114773
|
+
import { isAbsolute as isAbsolute14, resolve as resolve52 } from "node:path";
|
|
114380
114774
|
async function getGlobalPlansDirFromCwd() {
|
|
114381
114775
|
const projectRoot = findProjectRoot(process.cwd());
|
|
114382
114776
|
const { config } = await CkConfigManager.loadFull(projectRoot);
|
|
114383
114777
|
return resolveGlobalPlansDir(config);
|
|
114384
114778
|
}
|
|
114385
114779
|
function resolveTargetFromBase(target, baseDir) {
|
|
114386
|
-
const resolvedTarget = isAbsolute14(target) ?
|
|
114780
|
+
const resolvedTarget = isAbsolute14(target) ? resolve52(target) : resolve52(baseDir, target);
|
|
114387
114781
|
return isWithinDir(resolvedTarget, baseDir) ? resolvedTarget : null;
|
|
114388
114782
|
}
|
|
114389
114783
|
|
|
@@ -114413,7 +114807,7 @@ async function handleParse(target, options2) {
|
|
|
114413
114807
|
return;
|
|
114414
114808
|
}
|
|
114415
114809
|
if (isJsonOutput(options2)) {
|
|
114416
|
-
console.log(JSON.stringify({ file:
|
|
114810
|
+
console.log(JSON.stringify({ file: relative34(process.cwd(), planFile), frontmatter, phases }, null, 2));
|
|
114417
114811
|
return;
|
|
114418
114812
|
}
|
|
114419
114813
|
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename31(dirname51(planFile));
|
|
@@ -114486,8 +114880,8 @@ async function handleStatus(target, options2) {
|
|
|
114486
114880
|
return;
|
|
114487
114881
|
}
|
|
114488
114882
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
114489
|
-
const t = effectiveTarget ?
|
|
114490
|
-
const plansDir = t &&
|
|
114883
|
+
const t = effectiveTarget ? resolve53(effectiveTarget) : null;
|
|
114884
|
+
const plansDir = t && existsSync74(t) && statSync12(t).isDirectory() && !existsSync74(join153(t, "plan.md")) ? t : null;
|
|
114491
114885
|
if (plansDir) {
|
|
114492
114886
|
const planFiles = scanPlanDir(plansDir);
|
|
114493
114887
|
if (planFiles.length === 0) {
|
|
@@ -114671,12 +115065,12 @@ init_plan_parser();
|
|
|
114671
115065
|
init_plans_registry();
|
|
114672
115066
|
init_output_manager();
|
|
114673
115067
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
114674
|
-
import { basename as basename32, dirname as dirname52, relative as
|
|
115068
|
+
import { basename as basename32, dirname as dirname52, relative as relative35, resolve as resolve54 } from "node:path";
|
|
114675
115069
|
function quoteReadTarget(filePath) {
|
|
114676
115070
|
return `"${filePath.replace(/\\/g, "/").replace(/"/g, "\\\"")}"`;
|
|
114677
115071
|
}
|
|
114678
115072
|
function buildPlanCreateReadReminder(planFile, phaseFiles, cwd2 = process.cwd()) {
|
|
114679
|
-
const files = [planFile, ...phaseFiles].map((file) => quoteReadTarget(
|
|
115073
|
+
const files = [planFile, ...phaseFiles].map((file) => quoteReadTarget(relative35(cwd2, file)));
|
|
114680
115074
|
return [
|
|
114681
115075
|
" [i] Claude Code agents: read plan.md and every phase-*.md before editing.",
|
|
114682
115076
|
" These files already exist; Write/Edit without Read may be rejected after wasting tokens.",
|
|
@@ -114714,13 +115108,13 @@ async function handleCreate(target, options2) {
|
|
|
114714
115108
|
return;
|
|
114715
115109
|
}
|
|
114716
115110
|
const globalBaseDir = options2.global ? await getGlobalPlansDirFromCwd() : undefined;
|
|
114717
|
-
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) :
|
|
115111
|
+
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) : resolve54(dir);
|
|
114718
115112
|
if (globalBaseDir && !resolvedDir) {
|
|
114719
115113
|
output.error("[X] Target directory must stay within the configured global plans root");
|
|
114720
115114
|
process.exitCode = 1;
|
|
114721
115115
|
return;
|
|
114722
115116
|
}
|
|
114723
|
-
const safeResolvedDir = resolvedDir ??
|
|
115117
|
+
const safeResolvedDir = resolvedDir ?? resolve54(dir);
|
|
114724
115118
|
const result = scaffoldPlan({
|
|
114725
115119
|
title: options2.title,
|
|
114726
115120
|
phases: phaseNames.map((name2) => ({ name: name2 })),
|
|
@@ -114748,8 +115142,8 @@ async function handleCreate(target, options2) {
|
|
|
114748
115142
|
if (isJsonOutput(options2)) {
|
|
114749
115143
|
const cwd2 = process.cwd();
|
|
114750
115144
|
console.log(JSON.stringify({
|
|
114751
|
-
planFile:
|
|
114752
|
-
phaseFiles: result.phaseFiles.map((f3) =>
|
|
115145
|
+
planFile: relative35(cwd2, result.planFile),
|
|
115146
|
+
phaseFiles: result.phaseFiles.map((f3) => relative35(cwd2, f3))
|
|
114753
115147
|
}, null, 2));
|
|
114754
115148
|
return;
|
|
114755
115149
|
}
|
|
@@ -114808,7 +115202,7 @@ async function handleCheck(target, options2) {
|
|
|
114808
115202
|
console.log(JSON.stringify({
|
|
114809
115203
|
phaseId: target,
|
|
114810
115204
|
status: newStatus,
|
|
114811
|
-
planFile:
|
|
115205
|
+
planFile: relative35(process.cwd(), planFile)
|
|
114812
115206
|
}));
|
|
114813
115207
|
return;
|
|
114814
115208
|
}
|
|
@@ -114852,7 +115246,7 @@ async function handleUncheck(target, options2) {
|
|
|
114852
115246
|
console.log(JSON.stringify({
|
|
114853
115247
|
phaseId: target,
|
|
114854
115248
|
status: "pending",
|
|
114855
|
-
planFile:
|
|
115249
|
+
planFile: relative35(process.cwd(), planFile)
|
|
114856
115250
|
}));
|
|
114857
115251
|
return;
|
|
114858
115252
|
}
|
|
@@ -114884,7 +115278,7 @@ async function handleAddPhase(target, options2) {
|
|
|
114884
115278
|
if (isJsonOutput(options2)) {
|
|
114885
115279
|
console.log(JSON.stringify({
|
|
114886
115280
|
phaseId: result.phaseId,
|
|
114887
|
-
phaseFile:
|
|
115281
|
+
phaseFile: relative35(process.cwd(), result.phaseFile)
|
|
114888
115282
|
}));
|
|
114889
115283
|
return;
|
|
114890
115284
|
}
|
|
@@ -114899,33 +115293,33 @@ async function handleAddPhase(target, options2) {
|
|
|
114899
115293
|
// src/commands/plan/plan-command.ts
|
|
114900
115294
|
function resolveTargetPath(target, baseDir) {
|
|
114901
115295
|
if (!baseDir) {
|
|
114902
|
-
return
|
|
115296
|
+
return resolve55(target);
|
|
114903
115297
|
}
|
|
114904
115298
|
if (isAbsolute15(target)) {
|
|
114905
|
-
return
|
|
115299
|
+
return resolve55(target);
|
|
114906
115300
|
}
|
|
114907
|
-
const cwdCandidate =
|
|
114908
|
-
if (
|
|
115301
|
+
const cwdCandidate = resolve55(target);
|
|
115302
|
+
if (existsSync75(cwdCandidate)) {
|
|
114909
115303
|
return cwdCandidate;
|
|
114910
115304
|
}
|
|
114911
|
-
return
|
|
115305
|
+
return resolve55(baseDir, target);
|
|
114912
115306
|
}
|
|
114913
115307
|
function resolvePlanFile(target, baseDir) {
|
|
114914
|
-
const t = target ? resolveTargetPath(target, baseDir) : baseDir ?
|
|
114915
|
-
if (
|
|
115308
|
+
const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve55(baseDir) : process.cwd();
|
|
115309
|
+
if (existsSync75(t)) {
|
|
114916
115310
|
const stat24 = statSync13(t);
|
|
114917
115311
|
if (stat24.isFile())
|
|
114918
115312
|
return t;
|
|
114919
|
-
const candidate =
|
|
114920
|
-
if (
|
|
115313
|
+
const candidate = join154(t, "plan.md");
|
|
115314
|
+
if (existsSync75(candidate))
|
|
114921
115315
|
return candidate;
|
|
114922
115316
|
}
|
|
114923
115317
|
if (!target && !baseDir) {
|
|
114924
115318
|
let dir = process.cwd();
|
|
114925
115319
|
const root = parse7(dir).root;
|
|
114926
115320
|
while (dir !== root) {
|
|
114927
|
-
const candidate =
|
|
114928
|
-
if (
|
|
115321
|
+
const candidate = join154(dir, "plan.md");
|
|
115322
|
+
if (existsSync75(candidate))
|
|
114929
115323
|
return candidate;
|
|
114930
115324
|
dir = dirname53(dir);
|
|
114931
115325
|
}
|
|
@@ -114975,7 +115369,7 @@ async function planCommand(action, target, options2) {
|
|
|
114975
115369
|
let resolvedTarget = target;
|
|
114976
115370
|
if (resolvedAction && !knownActions.has(resolvedAction)) {
|
|
114977
115371
|
const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
|
|
114978
|
-
const existsOnDisk = !looksLikePath &&
|
|
115372
|
+
const existsOnDisk = !looksLikePath && existsSync75(resolve55(resolvedAction));
|
|
114979
115373
|
if (looksLikePath || existsOnDisk) {
|
|
114980
115374
|
resolvedTarget = resolvedAction;
|
|
114981
115375
|
resolvedAction = undefined;
|
|
@@ -115017,13 +115411,13 @@ init_claudekit_data2();
|
|
|
115017
115411
|
init_logger();
|
|
115018
115412
|
init_safe_prompts();
|
|
115019
115413
|
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
115020
|
-
import { existsSync as
|
|
115021
|
-
import { resolve as
|
|
115414
|
+
import { existsSync as existsSync76 } from "node:fs";
|
|
115415
|
+
import { resolve as resolve56 } from "node:path";
|
|
115022
115416
|
async function handleAdd(projectPath, options2) {
|
|
115023
115417
|
logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
|
|
115024
115418
|
intro("Add Project");
|
|
115025
|
-
const absolutePath =
|
|
115026
|
-
if (!
|
|
115419
|
+
const absolutePath = resolve56(projectPath);
|
|
115420
|
+
if (!existsSync76(absolutePath)) {
|
|
115027
115421
|
log.error(`Path does not exist: ${absolutePath}`);
|
|
115028
115422
|
process.exitCode = 1;
|
|
115029
115423
|
return;
|
|
@@ -115384,6 +115778,7 @@ async function handleKitSelection(ctx) {
|
|
|
115384
115778
|
refresh: false,
|
|
115385
115779
|
sync: false,
|
|
115386
115780
|
useGit: false,
|
|
115781
|
+
installMode: "auto",
|
|
115387
115782
|
verbose: false,
|
|
115388
115783
|
json: false
|
|
115389
115784
|
});
|
|
@@ -115444,10 +115839,10 @@ init_agents();
|
|
|
115444
115839
|
var import_gray_matter12 = __toESM(require_gray_matter(), 1);
|
|
115445
115840
|
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
115446
115841
|
import { readFile as readFile68 } from "node:fs/promises";
|
|
115447
|
-
import { join as
|
|
115842
|
+
import { join as join156 } from "node:path";
|
|
115448
115843
|
|
|
115449
115844
|
// src/commands/skills/installed-skills-inventory.ts
|
|
115450
|
-
import { join as
|
|
115845
|
+
import { join as join155, resolve as resolve57 } from "node:path";
|
|
115451
115846
|
init_path_resolver();
|
|
115452
115847
|
var SCOPE_SORT_ORDER = {
|
|
115453
115848
|
project: 0,
|
|
@@ -115455,12 +115850,12 @@ var SCOPE_SORT_ORDER = {
|
|
|
115455
115850
|
};
|
|
115456
115851
|
async function getActiveClaudeSkillInstallations(options2 = {}) {
|
|
115457
115852
|
const projectDir = options2.projectDir ?? process.cwd();
|
|
115458
|
-
const globalDir =
|
|
115459
|
-
const projectClaudeDir =
|
|
115853
|
+
const globalDir = resolve57(options2.globalDir ?? PathResolver.getGlobalKitDir());
|
|
115854
|
+
const projectClaudeDir = resolve57(projectDir, ".claude");
|
|
115460
115855
|
const projectScopeAliasesGlobal = projectClaudeDir === globalDir;
|
|
115461
115856
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
115462
|
-
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(
|
|
115463
|
-
scanSkills2(
|
|
115857
|
+
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join155(projectClaudeDir, "skills")),
|
|
115858
|
+
scanSkills2(join155(globalDir, "skills"))
|
|
115464
115859
|
]);
|
|
115465
115860
|
const projectIds = new Set(projectSkills.map((skill) => skill.id));
|
|
115466
115861
|
const globalIds = new Set(globalSkills.map((skill) => skill.id));
|
|
@@ -115621,7 +116016,7 @@ async function handleValidate2(sourcePath) {
|
|
|
115621
116016
|
spinner.stop(`Checked ${skills.length} skill(s)`);
|
|
115622
116017
|
let hasIssues = false;
|
|
115623
116018
|
for (const skill of skills) {
|
|
115624
|
-
const skillMdPath =
|
|
116019
|
+
const skillMdPath = join156(skill.path, "SKILL.md");
|
|
115625
116020
|
try {
|
|
115626
116021
|
const content = await readFile68(skillMdPath, "utf-8");
|
|
115627
116022
|
const { data } = import_gray_matter12.default(content, {
|
|
@@ -116154,31 +116549,6 @@ init_skills_installer();
|
|
|
116154
116549
|
init_skills_registry();
|
|
116155
116550
|
init_skills_uninstaller();
|
|
116156
116551
|
|
|
116157
|
-
// src/domains/installation/plugin/uninstall-plugin.ts
|
|
116158
|
-
init_install_mode_detector();
|
|
116159
|
-
import { existsSync as existsSync76, rmSync as rmSync6 } from "node:fs";
|
|
116160
|
-
import { join as join156 } from "node:path";
|
|
116161
|
-
init_path_resolver();
|
|
116162
|
-
async function uninstallEnginePlugin(opts = {}) {
|
|
116163
|
-
const claudeDir3 = opts.claudeDir ?? PathResolver.getGlobalKitDir();
|
|
116164
|
-
const installer = opts.installer ?? new PluginInstaller(undefined, claudeDir3);
|
|
116165
|
-
const state = detectPluginState(claudeDir3);
|
|
116166
|
-
let uninstalled = false;
|
|
116167
|
-
if (state.installed) {
|
|
116168
|
-
await installer.uninstall();
|
|
116169
|
-
await installer.marketplaceRemove(state.marketplace ?? CK_MARKETPLACE_NAME);
|
|
116170
|
-
uninstalled = true;
|
|
116171
|
-
}
|
|
116172
|
-
let staleCacheRemoved = false;
|
|
116173
|
-
const marketplace = state.marketplace ?? CK_MARKETPLACE_NAME;
|
|
116174
|
-
const cacheDir = join156(claudeDir3, "plugins", "cache", marketplace, CK_PLUGIN_NAME);
|
|
116175
|
-
if (existsSync76(cacheDir)) {
|
|
116176
|
-
rmSync6(cacheDir, { recursive: true, force: true });
|
|
116177
|
-
staleCacheRemoved = true;
|
|
116178
|
-
}
|
|
116179
|
-
return { uninstalled, staleCacheRemoved };
|
|
116180
|
-
}
|
|
116181
|
-
|
|
116182
116552
|
// src/commands/uninstall/uninstall-command.ts
|
|
116183
116553
|
init_metadata_migration();
|
|
116184
116554
|
init_logger();
|
|
@@ -116228,8 +116598,8 @@ async function detectInstallations() {
|
|
|
116228
116598
|
}
|
|
116229
116599
|
|
|
116230
116600
|
// src/commands/uninstall/removal-handler.ts
|
|
116231
|
-
import { readdirSync as
|
|
116232
|
-
import { basename as basename33, join as join159, resolve as
|
|
116601
|
+
import { readdirSync as readdirSync14, rmSync as rmSync8 } from "node:fs";
|
|
116602
|
+
import { basename as basename33, join as join159, resolve as resolve58, sep as sep14 } from "node:path";
|
|
116233
116603
|
init_logger();
|
|
116234
116604
|
init_safe_prompts();
|
|
116235
116605
|
init_safe_spinner();
|
|
@@ -116237,7 +116607,7 @@ var import_fs_extra44 = __toESM(require_lib(), 1);
|
|
|
116237
116607
|
|
|
116238
116608
|
// src/commands/uninstall/analysis-handler.ts
|
|
116239
116609
|
init_metadata_migration();
|
|
116240
|
-
import { readdirSync as
|
|
116610
|
+
import { readdirSync as readdirSync13, rmSync as rmSync7 } from "node:fs";
|
|
116241
116611
|
import { dirname as dirname54, join as join157 } from "node:path";
|
|
116242
116612
|
init_logger();
|
|
116243
116613
|
init_safe_prompts();
|
|
@@ -116263,7 +116633,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
|
116263
116633
|
let currentDir = dirname54(filePath);
|
|
116264
116634
|
while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
|
|
116265
116635
|
try {
|
|
116266
|
-
const entries =
|
|
116636
|
+
const entries = readdirSync13(currentDir);
|
|
116267
116637
|
if (entries.length === 0) {
|
|
116268
116638
|
rmSync7(currentDir, { recursive: true });
|
|
116269
116639
|
cleaned++;
|
|
@@ -116593,8 +116963,8 @@ async function restoreUninstallBackup(backup) {
|
|
|
116593
116963
|
}
|
|
116594
116964
|
async function isPathSafeToRemove(filePath, baseDir) {
|
|
116595
116965
|
try {
|
|
116596
|
-
const resolvedPath =
|
|
116597
|
-
const resolvedBase =
|
|
116966
|
+
const resolvedPath = resolve58(filePath);
|
|
116967
|
+
const resolvedBase = resolve58(baseDir);
|
|
116598
116968
|
if (!resolvedPath.startsWith(resolvedBase + sep14) && resolvedPath !== resolvedBase) {
|
|
116599
116969
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
116600
116970
|
return false;
|
|
@@ -116602,7 +116972,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
116602
116972
|
const stats = await import_fs_extra44.lstat(filePath);
|
|
116603
116973
|
if (stats.isSymbolicLink()) {
|
|
116604
116974
|
const realPath = await import_fs_extra44.realpath(filePath);
|
|
116605
|
-
const resolvedReal =
|
|
116975
|
+
const resolvedReal = resolve58(realPath);
|
|
116606
116976
|
if (!resolvedReal.startsWith(resolvedBase + sep14) && resolvedReal !== resolvedBase) {
|
|
116607
116977
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
116608
116978
|
return false;
|
|
@@ -116700,7 +117070,7 @@ async function removeInstallations(installations, options2) {
|
|
|
116700
117070
|
});
|
|
116701
117071
|
logSettingsCleanup(settingsCleanup, false);
|
|
116702
117072
|
try {
|
|
116703
|
-
const remaining =
|
|
117073
|
+
const remaining = readdirSync14(installation.path);
|
|
116704
117074
|
if (remaining.length === 0) {
|
|
116705
117075
|
rmSync8(installation.path, { recursive: true });
|
|
116706
117076
|
logger.debug(`Removed empty installation directory: ${installation.path}`);
|
|
@@ -117166,7 +117536,7 @@ function getDisclaimerMarker() {
|
|
|
117166
117536
|
return AI_DISCLAIMER;
|
|
117167
117537
|
}
|
|
117168
117538
|
function spawnAndCollect2(command, args) {
|
|
117169
|
-
return new Promise((
|
|
117539
|
+
return new Promise((resolve59, reject) => {
|
|
117170
117540
|
const child = spawn6(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
117171
117541
|
const chunks = [];
|
|
117172
117542
|
const stderrChunks = [];
|
|
@@ -117179,7 +117549,7 @@ function spawnAndCollect2(command, args) {
|
|
|
117179
117549
|
reject(new Error(`${command} exited with code ${code2}: ${stderr}`));
|
|
117180
117550
|
return;
|
|
117181
117551
|
}
|
|
117182
|
-
|
|
117552
|
+
resolve59(Buffer.concat(chunks).toString("utf-8"));
|
|
117183
117553
|
});
|
|
117184
117554
|
});
|
|
117185
117555
|
}
|
|
@@ -117287,7 +117657,7 @@ function formatResponse(content, showBranding) {
|
|
|
117287
117657
|
return disclaimer + formatted + branding;
|
|
117288
117658
|
}
|
|
117289
117659
|
async function postViaGh(owner, repo, issueNumber, body) {
|
|
117290
|
-
return new Promise((
|
|
117660
|
+
return new Promise((resolve59, reject) => {
|
|
117291
117661
|
const args = [
|
|
117292
117662
|
"issue",
|
|
117293
117663
|
"comment",
|
|
@@ -117309,7 +117679,7 @@ async function postViaGh(owner, repo, issueNumber, body) {
|
|
|
117309
117679
|
reject(new Error(`gh exited with code ${code2}: ${stderr}`));
|
|
117310
117680
|
return;
|
|
117311
117681
|
}
|
|
117312
|
-
|
|
117682
|
+
resolve59();
|
|
117313
117683
|
});
|
|
117314
117684
|
});
|
|
117315
117685
|
}
|
|
@@ -117427,7 +117797,7 @@ After completing the implementation:
|
|
|
117427
117797
|
"--allowedTools",
|
|
117428
117798
|
tools
|
|
117429
117799
|
];
|
|
117430
|
-
await new Promise((
|
|
117800
|
+
await new Promise((resolve59, reject) => {
|
|
117431
117801
|
const child = spawn8("claude", args, { cwd: cwd2, stdio: ["pipe", "pipe", "pipe"], detached: false });
|
|
117432
117802
|
child.stdin.write(prompt);
|
|
117433
117803
|
child.stdin.end();
|
|
@@ -117452,7 +117822,7 @@ After completing the implementation:
|
|
|
117452
117822
|
reject(new Error(`Claude exited ${code2}: ${stderr.slice(0, 500)}`));
|
|
117453
117823
|
return;
|
|
117454
117824
|
}
|
|
117455
|
-
|
|
117825
|
+
resolve59();
|
|
117456
117826
|
});
|
|
117457
117827
|
});
|
|
117458
117828
|
}
|
|
@@ -117596,7 +117966,7 @@ function checkRateLimit2(processedThisHour, maxPerHour) {
|
|
|
117596
117966
|
return processedThisHour < maxPerHour;
|
|
117597
117967
|
}
|
|
117598
117968
|
function spawnAndCollect3(command, args) {
|
|
117599
|
-
return new Promise((
|
|
117969
|
+
return new Promise((resolve59, reject) => {
|
|
117600
117970
|
const child = spawn9(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
117601
117971
|
const chunks = [];
|
|
117602
117972
|
const stderrChunks = [];
|
|
@@ -117609,7 +117979,7 @@ function spawnAndCollect3(command, args) {
|
|
|
117609
117979
|
reject(new Error(`${command} exited with code ${code2}: ${stderr}`));
|
|
117610
117980
|
return;
|
|
117611
117981
|
}
|
|
117612
|
-
|
|
117982
|
+
resolve59(Buffer.concat(chunks).toString("utf-8"));
|
|
117613
117983
|
});
|
|
117614
117984
|
});
|
|
117615
117985
|
}
|
|
@@ -117661,7 +118031,7 @@ async function invokeClaude(options2) {
|
|
|
117661
118031
|
return collectClaudeOutput(child, options2.timeoutSec, verbose);
|
|
117662
118032
|
}
|
|
117663
118033
|
function collectClaudeOutput(child, timeoutSec, verbose = false) {
|
|
117664
|
-
return new Promise((
|
|
118034
|
+
return new Promise((resolve59, reject) => {
|
|
117665
118035
|
const chunks = [];
|
|
117666
118036
|
const stderrChunks = [];
|
|
117667
118037
|
child.stdout?.on("data", (chunk) => {
|
|
@@ -117691,7 +118061,7 @@ function collectClaudeOutput(child, timeoutSec, verbose = false) {
|
|
|
117691
118061
|
reject(new Error(`Claude exited with code ${code2}: ${stderr}`));
|
|
117692
118062
|
return;
|
|
117693
118063
|
}
|
|
117694
|
-
|
|
118064
|
+
resolve59(verbose ? parseStreamJsonOutput(stdout2) : parseClaudeOutput(stdout2));
|
|
117695
118065
|
});
|
|
117696
118066
|
});
|
|
117697
118067
|
}
|
|
@@ -118955,7 +119325,7 @@ function formatQueueInfo(state) {
|
|
|
118955
119325
|
return "idle";
|
|
118956
119326
|
}
|
|
118957
119327
|
function sleep(ms) {
|
|
118958
|
-
return new Promise((
|
|
119328
|
+
return new Promise((resolve59) => setTimeout(resolve59, ms));
|
|
118959
119329
|
}
|
|
118960
119330
|
// src/cli/command-registry.ts
|
|
118961
119331
|
init_logger();
|
|
@@ -118966,7 +119336,7 @@ function registerCommands(cli) {
|
|
|
118966
119336
|
}
|
|
118967
119337
|
await newCommand(options2);
|
|
118968
119338
|
});
|
|
118969
|
-
cli.command("init", "Initialize or update ClaudeKit project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit to use: engineer, marketing, all, or comma-separated").option("-r, --release <version>", "Skip version selection, use specific version (e.g., latest, v1.0.0)").option("--exclude <pattern>", "Exclude files matching glob pattern (can be used multiple times)").option("--only <pattern>", "Include only files matching glob pattern (can be used multiple times)").option("-g, --global", "Use platform-specific user configuration directory").option("--fresh", "Full reset: remove CK files, replace settings.json and CLAUDE.md, reinstall from scratch").option("--force", "Force reinstall even if already at latest version (use with --yes; re-onboards missing files without full reset)").option("--install-skills", "Install skills dependencies (non-interactive mode)").option("--with-sudo", "Include system packages requiring sudo (Linux: ffmpeg, imagemagick)").option("--prefix", "Add /ck: prefix to all slash commands by moving them to commands/ck/ subdirectory").option("--beta", "Show beta versions in selection prompt").option("--refresh", "Bypass release cache to fetch latest versions from GitHub").option("--dry-run", "Preview changes without applying them (requires --prefix)").option("--force-overwrite", "Override ownership protections and delete user-modified files (requires --prefix)").option("--force-overwrite-settings", "Fully replace settings.json instead of selective merge (destroys user customizations)").option("--restore-ck-hooks", "Restore CK-managed hook registrations during update self-heal").option("--skip-setup", "Skip interactive configuration wizard").option("--docs-dir <name>", "Custom docs folder name (default: docs)").option("--plans-dir <name>", "Custom plans folder name (default: plans)").option("-y, --yes", "Non-interactive mode with sensible defaults (skip all prompts)").option("--sync", "Sync config files from upstream with interactive hunk-by-hunk merge").option("--use-git", "Use git clone instead of GitHub API (uses SSH/HTTPS credentials)").option("--archive <path>", "Use local archive file instead of downloading (zip/tar.gz)").option("--kit-path <path>", "Use local kit directory instead of downloading").action(async (options2) => {
|
|
119339
|
+
cli.command("init", "Initialize or update ClaudeKit project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit to use: engineer, marketing, all, or comma-separated").option("-r, --release <version>", "Skip version selection, use specific version (e.g., latest, v1.0.0)").option("--exclude <pattern>", "Exclude files matching glob pattern (can be used multiple times)").option("--only <pattern>", "Include only files matching glob pattern (can be used multiple times)").option("-g, --global", "Use platform-specific user configuration directory").option("--fresh", "Full reset: remove CK files, replace settings.json and CLAUDE.md, reinstall from scratch").option("--force", "Force reinstall even if already at latest version (use with --yes; re-onboards missing files without full reset)").option("--install-skills", "Install skills dependencies (non-interactive mode)").option("--with-sudo", "Include system packages requiring sudo (Linux: ffmpeg, imagemagick)").option("--prefix", "Add /ck: prefix to all slash commands by moving them to commands/ck/ subdirectory").option("--beta", "Show beta versions in selection prompt").option("--refresh", "Bypass release cache to fetch latest versions from GitHub").option("--dry-run", "Preview changes without applying them (requires --prefix)").option("--force-overwrite", "Override ownership protections and delete user-modified files (requires --prefix)").option("--force-overwrite-settings", "Fully replace settings.json instead of selective merge (destroys user customizations)").option("--restore-ck-hooks", "Restore CK-managed hook registrations during update self-heal").option("--skip-setup", "Skip interactive configuration wizard").option("--docs-dir <name>", "Custom docs folder name (default: docs)").option("--plans-dir <name>", "Custom plans folder name (default: plans)").option("-y, --yes", "Non-interactive mode with sensible defaults (skip all prompts)").option("--sync", "Sync config files from upstream with interactive hunk-by-hunk merge").option("--install-mode <mode>", "Engineer global install mode: auto, plugin, or legacy (default: auto)").option("--use-git", "Use git clone instead of GitHub API (uses SSH/HTTPS credentials)").option("--archive <path>", "Use local archive file instead of downloading (zip/tar.gz)").option("--kit-path <path>", "Use local kit directory instead of downloading").action(async (options2) => {
|
|
118970
119340
|
if (options2.exclude && !Array.isArray(options2.exclude)) {
|
|
118971
119341
|
options2.exclude = [options2.exclude];
|
|
118972
119342
|
}
|