claudekit-cli 3.41.4-dev.34 → 3.41.4-dev.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -15234,7 +15234,7 @@ var init_ck_config = __esm(() => {
|
|
|
15234
15234
|
"scout-block": exports_external.boolean().optional(),
|
|
15235
15235
|
"privacy-block": exports_external.boolean().optional(),
|
|
15236
15236
|
"simplify-gate": exports_external.boolean().optional()
|
|
15237
|
-
});
|
|
15237
|
+
}).passthrough();
|
|
15238
15238
|
CkSimplifyConfigSchema = exports_external.object({
|
|
15239
15239
|
threshold: exports_external.object({
|
|
15240
15240
|
locDelta: exports_external.number().int().nonnegative().default(400),
|
|
@@ -60747,7 +60747,7 @@ var package_default;
|
|
|
60747
60747
|
var init_package = __esm(() => {
|
|
60748
60748
|
package_default = {
|
|
60749
60749
|
name: "claudekit-cli",
|
|
60750
|
-
version: "3.41.4-dev.
|
|
60750
|
+
version: "3.41.4-dev.36",
|
|
60751
60751
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
60752
60752
|
type: "module",
|
|
60753
60753
|
repository: {
|
|
@@ -84026,6 +84026,199 @@ async function checkHookCommandPaths(projectDir) {
|
|
|
84026
84026
|
}
|
|
84027
84027
|
};
|
|
84028
84028
|
}
|
|
84029
|
+
function extractHookScriptPath(cmd) {
|
|
84030
|
+
if (!cmd)
|
|
84031
|
+
return null;
|
|
84032
|
+
const stripped = cmd.replace(/"/g, "");
|
|
84033
|
+
const match = stripped.match(/\bnode\s+(\S*?\.claude[/\\]\S+?\.cjs)(?:\s|$)/);
|
|
84034
|
+
if (!match)
|
|
84035
|
+
return null;
|
|
84036
|
+
return match[1];
|
|
84037
|
+
}
|
|
84038
|
+
function resolveHookScriptPath(scriptPath, projectDir) {
|
|
84039
|
+
let resolved = scriptPath.replace(/\\/g, "/");
|
|
84040
|
+
const home9 = homedir40();
|
|
84041
|
+
resolved = resolved.replace(/^\$\{?HOME\}?/, home9);
|
|
84042
|
+
resolved = resolved.replace(/^\$\{?CLAUDE_PROJECT_DIR\}?/, projectDir);
|
|
84043
|
+
resolved = resolved.replace(/^%USERPROFILE%/, home9);
|
|
84044
|
+
resolved = resolved.replace(/^%CLAUDE_PROJECT_DIR%/, projectDir);
|
|
84045
|
+
resolved = resolved.replace(/^~\//, `${home9}/`);
|
|
84046
|
+
if (resolved.startsWith(".claude/") || resolved === ".claude") {
|
|
84047
|
+
resolved = join84(projectDir, resolved);
|
|
84048
|
+
}
|
|
84049
|
+
return resolve26(resolved);
|
|
84050
|
+
}
|
|
84051
|
+
function collectMissingHookReferences(settings, settingsFile, projectDir) {
|
|
84052
|
+
if (!settings.hooks)
|
|
84053
|
+
return [];
|
|
84054
|
+
const findings = [];
|
|
84055
|
+
const seen = new Set;
|
|
84056
|
+
const consider = (eventName, command, matcher) => {
|
|
84057
|
+
if (!command)
|
|
84058
|
+
return;
|
|
84059
|
+
const scriptPath = extractHookScriptPath(command);
|
|
84060
|
+
if (!scriptPath)
|
|
84061
|
+
return;
|
|
84062
|
+
const resolvedPath = resolveHookScriptPath(scriptPath, projectDir);
|
|
84063
|
+
if (existsSync53(resolvedPath))
|
|
84064
|
+
return;
|
|
84065
|
+
const key = `${settingsFile.path}::${eventName}::${matcher ?? ""}::${scriptPath}`;
|
|
84066
|
+
if (seen.has(key))
|
|
84067
|
+
return;
|
|
84068
|
+
seen.add(key);
|
|
84069
|
+
findings.push({
|
|
84070
|
+
path: settingsFile.path,
|
|
84071
|
+
label: settingsFile.label,
|
|
84072
|
+
eventName,
|
|
84073
|
+
matcher,
|
|
84074
|
+
command,
|
|
84075
|
+
scriptPath,
|
|
84076
|
+
resolvedPath
|
|
84077
|
+
});
|
|
84078
|
+
};
|
|
84079
|
+
for (const [eventName, entries] of Object.entries(settings.hooks)) {
|
|
84080
|
+
for (const entry of entries) {
|
|
84081
|
+
if ("command" in entry && typeof entry.command === "string") {
|
|
84082
|
+
consider(eventName, entry.command, undefined);
|
|
84083
|
+
}
|
|
84084
|
+
if ("hooks" in entry && entry.hooks) {
|
|
84085
|
+
const matcher = "matcher" in entry ? entry.matcher : undefined;
|
|
84086
|
+
for (const hook of entry.hooks) {
|
|
84087
|
+
consider(eventName, hook.command, matcher);
|
|
84088
|
+
}
|
|
84089
|
+
}
|
|
84090
|
+
}
|
|
84091
|
+
}
|
|
84092
|
+
return findings;
|
|
84093
|
+
}
|
|
84094
|
+
async function pruneMissingHookReferencesInSettingsFile(settingsFile, projectDir) {
|
|
84095
|
+
const settings = await SettingsMerger.readSettingsFile(settingsFile.path);
|
|
84096
|
+
if (!settings?.hooks)
|
|
84097
|
+
return 0;
|
|
84098
|
+
let pruned = 0;
|
|
84099
|
+
const hookFileMissing = (command) => {
|
|
84100
|
+
if (!command)
|
|
84101
|
+
return false;
|
|
84102
|
+
const scriptPath = extractHookScriptPath(command);
|
|
84103
|
+
if (!scriptPath)
|
|
84104
|
+
return false;
|
|
84105
|
+
return !existsSync53(resolveHookScriptPath(scriptPath, projectDir));
|
|
84106
|
+
};
|
|
84107
|
+
const hooksRecord = settings.hooks;
|
|
84108
|
+
for (const [eventName, entries] of Object.entries(hooksRecord)) {
|
|
84109
|
+
const filteredEntries = [];
|
|
84110
|
+
for (const entry of entries) {
|
|
84111
|
+
const e2 = entry;
|
|
84112
|
+
if (typeof e2.command === "string") {
|
|
84113
|
+
if (hookFileMissing(e2.command)) {
|
|
84114
|
+
pruned++;
|
|
84115
|
+
continue;
|
|
84116
|
+
}
|
|
84117
|
+
filteredEntries.push(entry);
|
|
84118
|
+
continue;
|
|
84119
|
+
}
|
|
84120
|
+
if (Array.isArray(e2.hooks)) {
|
|
84121
|
+
const keptHooks = e2.hooks.filter((h2) => {
|
|
84122
|
+
if (hookFileMissing(h2.command)) {
|
|
84123
|
+
pruned++;
|
|
84124
|
+
return false;
|
|
84125
|
+
}
|
|
84126
|
+
return true;
|
|
84127
|
+
});
|
|
84128
|
+
if (keptHooks.length === 0) {
|
|
84129
|
+
continue;
|
|
84130
|
+
}
|
|
84131
|
+
filteredEntries.push({ ...e2, hooks: keptHooks });
|
|
84132
|
+
continue;
|
|
84133
|
+
}
|
|
84134
|
+
filteredEntries.push(entry);
|
|
84135
|
+
}
|
|
84136
|
+
if (filteredEntries.length === 0) {
|
|
84137
|
+
delete hooksRecord[eventName];
|
|
84138
|
+
} else {
|
|
84139
|
+
hooksRecord[eventName] = filteredEntries;
|
|
84140
|
+
}
|
|
84141
|
+
}
|
|
84142
|
+
if (Object.keys(hooksRecord).length === 0) {
|
|
84143
|
+
delete settings.hooks;
|
|
84144
|
+
}
|
|
84145
|
+
if (pruned > 0) {
|
|
84146
|
+
await SettingsMerger.writeSettingsFile(settingsFile.path, settings);
|
|
84147
|
+
}
|
|
84148
|
+
return pruned;
|
|
84149
|
+
}
|
|
84150
|
+
async function checkHookFileReferences(projectDir) {
|
|
84151
|
+
const settingsFiles = getClaudeSettingsFiles(projectDir);
|
|
84152
|
+
if (settingsFiles.length === 0) {
|
|
84153
|
+
return {
|
|
84154
|
+
id: "hook-file-references",
|
|
84155
|
+
name: "Hook File References",
|
|
84156
|
+
group: "claudekit",
|
|
84157
|
+
priority: "critical",
|
|
84158
|
+
status: "info",
|
|
84159
|
+
message: "No Claude settings files",
|
|
84160
|
+
autoFixable: false
|
|
84161
|
+
};
|
|
84162
|
+
}
|
|
84163
|
+
const findings = [];
|
|
84164
|
+
for (const settingsFile of settingsFiles) {
|
|
84165
|
+
const settings = await SettingsMerger.readSettingsFile(settingsFile.path);
|
|
84166
|
+
if (!settings)
|
|
84167
|
+
continue;
|
|
84168
|
+
findings.push(...collectMissingHookReferences(settings, settingsFile, projectDir));
|
|
84169
|
+
}
|
|
84170
|
+
if (findings.length === 0) {
|
|
84171
|
+
return {
|
|
84172
|
+
id: "hook-file-references",
|
|
84173
|
+
name: "Hook File References",
|
|
84174
|
+
group: "claudekit",
|
|
84175
|
+
priority: "critical",
|
|
84176
|
+
status: "pass",
|
|
84177
|
+
message: "All referenced hook files exist",
|
|
84178
|
+
autoFixable: false
|
|
84179
|
+
};
|
|
84180
|
+
}
|
|
84181
|
+
const details = findings.slice(0, 8).map((f3) => {
|
|
84182
|
+
const matcher = f3.matcher ? ` [${f3.matcher}]` : "";
|
|
84183
|
+
return `${f3.label} :: ${f3.eventName}${matcher} :: missing ${f3.scriptPath}`;
|
|
84184
|
+
}).join(`
|
|
84185
|
+
`);
|
|
84186
|
+
return {
|
|
84187
|
+
id: "hook-file-references",
|
|
84188
|
+
name: "Hook File References",
|
|
84189
|
+
group: "claudekit",
|
|
84190
|
+
priority: "critical",
|
|
84191
|
+
status: "fail",
|
|
84192
|
+
message: `${findings.length} settings hook(s) reference missing file(s)`,
|
|
84193
|
+
details,
|
|
84194
|
+
suggestion: "Run: ck doctor --fix (prunes stale entries), then 'ck init' to restore hooks",
|
|
84195
|
+
autoFixable: true,
|
|
84196
|
+
fix: {
|
|
84197
|
+
id: "fix-hook-file-references",
|
|
84198
|
+
description: "Prune stale hook entries whose script files are missing",
|
|
84199
|
+
execute: async () => {
|
|
84200
|
+
try {
|
|
84201
|
+
let pruned = 0;
|
|
84202
|
+
for (const settingsFile of settingsFiles) {
|
|
84203
|
+
pruned += await pruneMissingHookReferencesInSettingsFile(settingsFile, projectDir);
|
|
84204
|
+
}
|
|
84205
|
+
if (pruned === 0) {
|
|
84206
|
+
return { success: true, message: "No stale hook entries needed pruning" };
|
|
84207
|
+
}
|
|
84208
|
+
return {
|
|
84209
|
+
success: true,
|
|
84210
|
+
message: `Pruned ${pruned} stale hook entry(ies). Run 'ck init' to restore hooks if needed.`
|
|
84211
|
+
};
|
|
84212
|
+
} catch (error) {
|
|
84213
|
+
return {
|
|
84214
|
+
success: false,
|
|
84215
|
+
message: `Failed to prune stale hook entries: ${error}`
|
|
84216
|
+
};
|
|
84217
|
+
}
|
|
84218
|
+
}
|
|
84219
|
+
}
|
|
84220
|
+
};
|
|
84221
|
+
}
|
|
84029
84222
|
async function checkHookConfig(projectDir) {
|
|
84030
84223
|
const projectConfigPath = join84(projectDir, ".claude", ".ck.json");
|
|
84031
84224
|
const globalConfigPath = join84(PathResolver.getGlobalKitDir(), ".ck.json");
|
|
@@ -84527,6 +84720,8 @@ class ClaudekitChecker {
|
|
|
84527
84720
|
results.push(await checkHookRuntime(this.projectDir));
|
|
84528
84721
|
logger.verbose("ClaudekitChecker: Checking hook command paths");
|
|
84529
84722
|
results.push(await checkHookCommandPaths(this.projectDir));
|
|
84723
|
+
logger.verbose("ClaudekitChecker: Checking hook file references");
|
|
84724
|
+
results.push(await checkHookFileReferences(this.projectDir));
|
|
84530
84725
|
logger.verbose("ClaudekitChecker: Checking hook config");
|
|
84531
84726
|
results.push(await checkHookConfig(this.projectDir));
|
|
84532
84727
|
logger.verbose("ClaudekitChecker: Checking hook crash logs");
|
|
@@ -103376,7 +103571,7 @@ import { readFile as readFile58, readdir as readdir42, writeFile as writeFile32
|
|
|
103376
103571
|
import { homedir as homedir44, platform as platform15 } from "node:os";
|
|
103377
103572
|
import { extname as extname6, join as join137 } from "node:path";
|
|
103378
103573
|
var IS_WINDOWS3 = platform15() === "win32";
|
|
103379
|
-
var HOME_PREFIX =
|
|
103574
|
+
var HOME_PREFIX = "$HOME";
|
|
103380
103575
|
function getHomeDirPrefix() {
|
|
103381
103576
|
return HOME_PREFIX;
|
|
103382
103577
|
}
|
|
@@ -103428,20 +103623,12 @@ function transformContent(content, options2 = {}) {
|
|
|
103428
103623
|
const homePrefix = getHomeDirPrefix();
|
|
103429
103624
|
const customGlobalClaudeDir = getCustomGlobalClaudeDir(options2.targetClaudeDir);
|
|
103430
103625
|
const claudePath = getGlobalClaudePath(options2.targetClaudeDir);
|
|
103431
|
-
|
|
103432
|
-
|
|
103433
|
-
|
|
103434
|
-
|
|
103435
|
-
|
|
103436
|
-
|
|
103437
|
-
changes += braceHomePathResult.changes;
|
|
103438
|
-
const homePrefixResult = replaceTracked(transformed, /\$HOME(?=\/|\\)/g, homePrefix);
|
|
103439
|
-
transformed = homePrefixResult.content;
|
|
103440
|
-
changes += homePrefixResult.changes;
|
|
103441
|
-
const braceHomePrefixResult = replaceTracked(transformed, /\$\{HOME\}(?=\/|\\)/g, homePrefix);
|
|
103442
|
-
transformed = braceHomePrefixResult.content;
|
|
103443
|
-
changes += braceHomePrefixResult.changes;
|
|
103444
|
-
}
|
|
103626
|
+
const userProfileClaudeResult = replaceTracked(transformed, /%USERPROFILE%[\\/]\.claude[\\/]/g, claudePath);
|
|
103627
|
+
transformed = userProfileClaudeResult.content;
|
|
103628
|
+
changes += userProfileClaudeResult.changes;
|
|
103629
|
+
const userProfileStandaloneResult = replaceTracked(transformed, /%USERPROFILE%(?=[\\/])/g, homePrefix);
|
|
103630
|
+
transformed = userProfileStandaloneResult.content;
|
|
103631
|
+
changes += userProfileStandaloneResult.changes;
|
|
103445
103632
|
const projectDirPathResult = replaceTracked(transformed, /\$CLAUDE_PROJECT_DIR\/\.claude\//g, claudePath);
|
|
103446
103633
|
transformed = projectDirPathResult.content;
|
|
103447
103634
|
changes += projectDirPathResult.changes;
|
|
@@ -103452,11 +103639,9 @@ function transformContent(content, options2 = {}) {
|
|
|
103452
103639
|
const braceProjectDirPathResult = replaceTracked(transformed, /\$\{CLAUDE_PROJECT_DIR\}\/\.claude\//g, claudePath);
|
|
103453
103640
|
transformed = braceProjectDirPathResult.content;
|
|
103454
103641
|
changes += braceProjectDirPathResult.changes;
|
|
103455
|
-
|
|
103456
|
-
|
|
103457
|
-
|
|
103458
|
-
changes += windowsProjectDirPathResult.changes;
|
|
103459
|
-
}
|
|
103642
|
+
const windowsProjectDirPathResult = replaceTracked(transformed, /%CLAUDE_PROJECT_DIR%[\\/]\.claude[\\/]/g, claudePath);
|
|
103643
|
+
transformed = windowsProjectDirPathResult.content;
|
|
103644
|
+
changes += windowsProjectDirPathResult.changes;
|
|
103460
103645
|
const relativeClaudePathResult = replaceTracked(transformed, /\.\/\.claude\//g, claudePath);
|
|
103461
103646
|
transformed = relativeClaudePathResult.content;
|
|
103462
103647
|
changes += relativeClaudePathResult.changes;
|