claudekit-cli 4.3.1-dev.15 → 4.3.1-dev.17
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
|
@@ -15349,6 +15349,7 @@ var init_commands = __esm(() => {
|
|
|
15349
15349
|
dryRun: exports_external.boolean().default(false),
|
|
15350
15350
|
forceOverwrite: exports_external.boolean().default(false),
|
|
15351
15351
|
forceOverwriteSettings: exports_external.boolean().default(false),
|
|
15352
|
+
restoreCkHooks: exports_external.boolean().default(false),
|
|
15352
15353
|
skipSetup: exports_external.boolean().default(false),
|
|
15353
15354
|
refresh: exports_external.boolean().default(false),
|
|
15354
15355
|
docsDir: exports_external.string().optional(),
|
|
@@ -15891,8 +15892,12 @@ var init_ck_config = __esm(() => {
|
|
|
15891
15892
|
CkHooksConfigSchema = exports_external.object({
|
|
15892
15893
|
"session-init": exports_external.boolean().optional(),
|
|
15893
15894
|
"subagent-init": exports_external.boolean().optional(),
|
|
15895
|
+
"session-state": exports_external.boolean().optional(),
|
|
15896
|
+
"cook-after-plan-reminder": exports_external.boolean().optional(),
|
|
15894
15897
|
"descriptive-name": exports_external.boolean().optional(),
|
|
15895
15898
|
"dev-rules-reminder": exports_external.boolean().optional(),
|
|
15899
|
+
"plan-format-kanban": exports_external.boolean().optional(),
|
|
15900
|
+
"usage-quota-cache-refresh": exports_external.boolean().optional(),
|
|
15896
15901
|
"usage-context-awareness": exports_external.boolean().optional(),
|
|
15897
15902
|
"context-tracking": exports_external.boolean().optional(),
|
|
15898
15903
|
"scout-block": exports_external.boolean().optional(),
|
|
@@ -15989,8 +15994,12 @@ var init_ck_config = __esm(() => {
|
|
|
15989
15994
|
hooks: {
|
|
15990
15995
|
"session-init": true,
|
|
15991
15996
|
"subagent-init": true,
|
|
15997
|
+
"session-state": true,
|
|
15998
|
+
"cook-after-plan-reminder": true,
|
|
15992
15999
|
"descriptive-name": true,
|
|
15993
16000
|
"dev-rules-reminder": true,
|
|
16001
|
+
"plan-format-kanban": true,
|
|
16002
|
+
"usage-quota-cache-refresh": true,
|
|
15994
16003
|
"usage-context-awareness": true,
|
|
15995
16004
|
"context-tracking": true,
|
|
15996
16005
|
"scout-block": true,
|
|
@@ -16014,8 +16023,12 @@ var init_ck_config = __esm(() => {
|
|
|
16014
16023
|
CK_HOOK_NAMES = [
|
|
16015
16024
|
"session-init",
|
|
16016
16025
|
"subagent-init",
|
|
16026
|
+
"session-state",
|
|
16027
|
+
"cook-after-plan-reminder",
|
|
16017
16028
|
"descriptive-name",
|
|
16018
16029
|
"dev-rules-reminder",
|
|
16030
|
+
"plan-format-kanban",
|
|
16031
|
+
"usage-quota-cache-refresh",
|
|
16019
16032
|
"usage-context-awareness",
|
|
16020
16033
|
"context-tracking",
|
|
16021
16034
|
"scout-block",
|
|
@@ -45197,6 +45210,14 @@ var init_open = __esm(() => {
|
|
|
45197
45210
|
open_default = open;
|
|
45198
45211
|
});
|
|
45199
45212
|
|
|
45213
|
+
// src/shared/json-content.ts
|
|
45214
|
+
function stripJsonBom(content) {
|
|
45215
|
+
return content.charCodeAt(0) === 65279 ? content.slice(1) : content;
|
|
45216
|
+
}
|
|
45217
|
+
function parseJsonContent(content) {
|
|
45218
|
+
return JSON.parse(stripJsonBom(content));
|
|
45219
|
+
}
|
|
45220
|
+
|
|
45200
45221
|
// src/domains/config/config-manager.ts
|
|
45201
45222
|
import { existsSync as existsSync10 } from "node:fs";
|
|
45202
45223
|
import { mkdir as mkdir6, readFile as readFile7, rename as rename3, rm as rm3, writeFile as writeFile5 } from "node:fs/promises";
|
|
@@ -45225,7 +45246,7 @@ class ConfigManager {
|
|
|
45225
45246
|
try {
|
|
45226
45247
|
if (existsSync10(configFile)) {
|
|
45227
45248
|
const content = await readFile7(configFile, "utf-8");
|
|
45228
|
-
const data =
|
|
45249
|
+
const data = parseJsonContent(content);
|
|
45229
45250
|
ConfigManager.config = ConfigSchema.parse(data);
|
|
45230
45251
|
logger.debug(`Config loaded from ${configFile}`);
|
|
45231
45252
|
return ConfigManager.config;
|
|
@@ -45279,7 +45300,7 @@ class ConfigManager {
|
|
|
45279
45300
|
try {
|
|
45280
45301
|
if (existsSync10(configPath)) {
|
|
45281
45302
|
const content = await readFile7(configPath, "utf-8");
|
|
45282
|
-
const data =
|
|
45303
|
+
const data = parseJsonContent(content);
|
|
45283
45304
|
const folders = FoldersConfigSchema.parse(data.paths || data);
|
|
45284
45305
|
logger.debug(`Project config loaded from ${configPath}`);
|
|
45285
45306
|
return folders;
|
|
@@ -45300,7 +45321,7 @@ class ConfigManager {
|
|
|
45300
45321
|
if (existsSync10(configPath)) {
|
|
45301
45322
|
try {
|
|
45302
45323
|
const content = await readFile7(configPath, "utf-8");
|
|
45303
|
-
existingConfig =
|
|
45324
|
+
existingConfig = parseJsonContent(content);
|
|
45304
45325
|
} catch (error) {
|
|
45305
45326
|
logger.debug(`Could not parse existing config, starting fresh: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
45306
45327
|
}
|
|
@@ -45475,7 +45496,7 @@ class CkConfigManager {
|
|
|
45475
45496
|
if (!existsSync11(configPath))
|
|
45476
45497
|
return null;
|
|
45477
45498
|
const content = await readFile8(configPath, "utf-8");
|
|
45478
|
-
const data = normalizeCkConfigInput(
|
|
45499
|
+
const data = normalizeCkConfigInput(parseJsonContent(content));
|
|
45479
45500
|
return CkConfigSchema.parse(data);
|
|
45480
45501
|
} catch (error) {
|
|
45481
45502
|
logger.warning(`Failed to load config from ${configPath}: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -45542,7 +45563,7 @@ class CkConfigManager {
|
|
|
45542
45563
|
if (!existingConfig && existsSync11(configPath)) {
|
|
45543
45564
|
try {
|
|
45544
45565
|
const content = await readFile8(configPath, "utf-8");
|
|
45545
|
-
const parsed =
|
|
45566
|
+
const parsed = parseJsonContent(content);
|
|
45546
45567
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
45547
45568
|
existingConfig = normalizeCkConfigInput(parsed);
|
|
45548
45569
|
}
|
|
@@ -45794,6 +45815,12 @@ function repairClaudeNodeCommandPath(cmd, root) {
|
|
|
45794
45815
|
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
45795
45816
|
return { command, changed: command !== cmd, issue: "raw-relative" };
|
|
45796
45817
|
}
|
|
45818
|
+
const quotedRelativeMatch = cmd.match(/^(node\s+)["'](?:\.\/)?(\.claude[/\\][^"']+)["'](.*)$/);
|
|
45819
|
+
if (quotedRelativeMatch) {
|
|
45820
|
+
const [, nodePrefix, relativePath, suffix] = quotedRelativeMatch;
|
|
45821
|
+
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
45822
|
+
return { command, changed: command !== cmd, issue: "raw-relative" };
|
|
45823
|
+
}
|
|
45797
45824
|
const embeddedQuotedMatch = cmd.match(/^(node\s+)"(?:\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](\.claude[/\\][^"]+)"(.*)$/);
|
|
45798
45825
|
if (embeddedQuotedMatch) {
|
|
45799
45826
|
const [, nodePrefix, relativePath, suffix] = embeddedQuotedMatch;
|
|
@@ -50122,6 +50149,16 @@ var init_ck_config_schema = __esm(() => {
|
|
|
50122
50149
|
default: true,
|
|
50123
50150
|
description: "SubagentStart hook - injects context to subagents"
|
|
50124
50151
|
},
|
|
50152
|
+
"session-state": {
|
|
50153
|
+
type: "boolean",
|
|
50154
|
+
default: true,
|
|
50155
|
+
description: "Stop/SubagentStop/PostToolUse hook - persists session state for handoff and statusline context"
|
|
50156
|
+
},
|
|
50157
|
+
"cook-after-plan-reminder": {
|
|
50158
|
+
type: "boolean",
|
|
50159
|
+
default: true,
|
|
50160
|
+
description: "SubagentStop hook - reminds agents to continue implementation after planning"
|
|
50161
|
+
},
|
|
50125
50162
|
"descriptive-name": {
|
|
50126
50163
|
type: "boolean",
|
|
50127
50164
|
default: true,
|
|
@@ -50132,6 +50169,16 @@ var init_ck_config_schema = __esm(() => {
|
|
|
50132
50169
|
default: true,
|
|
50133
50170
|
description: "UserPromptSubmit hook - injects dev rules context"
|
|
50134
50171
|
},
|
|
50172
|
+
"plan-format-kanban": {
|
|
50173
|
+
type: "boolean",
|
|
50174
|
+
default: true,
|
|
50175
|
+
description: "PostToolUse hook - keeps plan kanban metadata synchronized after edits"
|
|
50176
|
+
},
|
|
50177
|
+
"usage-quota-cache-refresh": {
|
|
50178
|
+
type: "boolean",
|
|
50179
|
+
default: true,
|
|
50180
|
+
description: "Lifecycle hook - refreshes cached usage quota information"
|
|
50181
|
+
},
|
|
50135
50182
|
"usage-context-awareness": {
|
|
50136
50183
|
type: "boolean",
|
|
50137
50184
|
default: true,
|
|
@@ -63806,7 +63853,7 @@ var package_default;
|
|
|
63806
63853
|
var init_package = __esm(() => {
|
|
63807
63854
|
package_default = {
|
|
63808
63855
|
name: "claudekit-cli",
|
|
63809
|
-
version: "4.3.1-dev.
|
|
63856
|
+
version: "4.3.1-dev.17",
|
|
63810
63857
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
63811
63858
|
type: "module",
|
|
63812
63859
|
repository: {
|
|
@@ -64290,8 +64337,9 @@ var init_package_manager_runner = __esm(() => {
|
|
|
64290
64337
|
import { existsSync as existsSync44, readdirSync as readdirSync7 } from "node:fs";
|
|
64291
64338
|
import { homedir as homedir40 } from "node:os";
|
|
64292
64339
|
import { basename as basename23, dirname as dirname28, isAbsolute as isAbsolute10, resolve as resolve32, sep as sep11 } from "node:path";
|
|
64293
|
-
function pruneZombieEngineerWirings(settings, hookDir) {
|
|
64340
|
+
function pruneZombieEngineerWirings(settings, hookDir, preserveCommands = new Set) {
|
|
64294
64341
|
const pruned = [];
|
|
64342
|
+
const normalizedPreserveCommands = new Set(Array.from(preserveCommands).map((command) => normalizeCommand(command)));
|
|
64295
64343
|
if (!existsSync44(hookDir)) {
|
|
64296
64344
|
return { settings, pruned };
|
|
64297
64345
|
}
|
|
@@ -64311,14 +64359,14 @@ function pruneZombieEngineerWirings(settings, hookDir) {
|
|
|
64311
64359
|
for (const group of groups) {
|
|
64312
64360
|
if (!("hooks" in group) || !Array.isArray(group.hooks)) {
|
|
64313
64361
|
const entry = group;
|
|
64314
|
-
if (shouldPruneEntry(entry, hookDir, pruned)) {
|
|
64362
|
+
if (shouldPruneEntry(entry, hookDir, pruned, normalizedPreserveCommands)) {
|
|
64315
64363
|
continue;
|
|
64316
64364
|
}
|
|
64317
64365
|
keptGroups.push(group);
|
|
64318
64366
|
continue;
|
|
64319
64367
|
}
|
|
64320
64368
|
const keptHooks = group.hooks.filter((h2) => {
|
|
64321
|
-
return !shouldPruneEntry(h2, hookDir, pruned);
|
|
64369
|
+
return !shouldPruneEntry(h2, hookDir, pruned, normalizedPreserveCommands);
|
|
64322
64370
|
});
|
|
64323
64371
|
if (keptHooks.length > 0) {
|
|
64324
64372
|
keptGroups.push({ ...group, hooks: keptHooks });
|
|
@@ -64335,13 +64383,16 @@ function pruneZombieEngineerWirings(settings, hookDir) {
|
|
|
64335
64383
|
}
|
|
64336
64384
|
return { settings, pruned };
|
|
64337
64385
|
}
|
|
64338
|
-
function shouldPruneEntry(entry, hookDir, pruned) {
|
|
64386
|
+
function shouldPruneEntry(entry, hookDir, pruned, preserveCommands) {
|
|
64339
64387
|
if (isLegacyDescriptiveNamePrompt(entry)) {
|
|
64340
64388
|
pruned.push("legacy-descriptive-name-prompt");
|
|
64341
64389
|
return true;
|
|
64342
64390
|
}
|
|
64343
64391
|
if (entry._origin !== "engineer")
|
|
64344
64392
|
return false;
|
|
64393
|
+
if (entry.command && preserveCommands.has(normalizeCommand(entry.command))) {
|
|
64394
|
+
return false;
|
|
64395
|
+
}
|
|
64345
64396
|
const filePath = extractHookFilePath(entry.command, hookDir);
|
|
64346
64397
|
if (!filePath)
|
|
64347
64398
|
return false;
|
|
@@ -64426,7 +64477,9 @@ function extractHookFilePath(command, hookDir) {
|
|
|
64426
64477
|
}
|
|
64427
64478
|
return null;
|
|
64428
64479
|
}
|
|
64429
|
-
var init_zombie_wirings_pruner = () => {
|
|
64480
|
+
var init_zombie_wirings_pruner = __esm(() => {
|
|
64481
|
+
init_command_normalizer();
|
|
64482
|
+
});
|
|
64430
64483
|
|
|
64431
64484
|
// src/domains/health-checks/checkers/shared.ts
|
|
64432
64485
|
function shouldSkipExpensiveOperations2() {
|
|
@@ -65368,6 +65421,17 @@ async function checkHookFileReferences(projectDir) {
|
|
|
65368
65421
|
}
|
|
65369
65422
|
};
|
|
65370
65423
|
}
|
|
65424
|
+
async function countMissingHookFileReferences(projectDir = process.cwd()) {
|
|
65425
|
+
const settingsFiles = getClaudeSettingsFiles(projectDir);
|
|
65426
|
+
let count = 0;
|
|
65427
|
+
for (const settingsFile of settingsFiles) {
|
|
65428
|
+
const settings = await SettingsMerger.readSettingsFile(settingsFile.path);
|
|
65429
|
+
if (!settings)
|
|
65430
|
+
continue;
|
|
65431
|
+
count += collectMissingHookReferences(settings, settingsFile, projectDir).length;
|
|
65432
|
+
}
|
|
65433
|
+
return count;
|
|
65434
|
+
}
|
|
65371
65435
|
async function repairMissingHookFileReferences(projectDir = process.cwd()) {
|
|
65372
65436
|
const result = await checkHookFileReferences(projectDir);
|
|
65373
65437
|
if (result.status !== "fail" || !result.fix) {
|
|
@@ -67331,7 +67395,7 @@ import { exec as exec2, spawn as spawn2 } from "node:child_process";
|
|
|
67331
67395
|
import { existsSync as existsSync47 } from "node:fs";
|
|
67332
67396
|
import { readdir as readdir19 } from "node:fs/promises";
|
|
67333
67397
|
import { builtinModules } from "node:module";
|
|
67334
|
-
import { join as join68 } from "node:path";
|
|
67398
|
+
import { dirname as dirname29, join as join68 } from "node:path";
|
|
67335
67399
|
import { promisify as promisify9 } from "node:util";
|
|
67336
67400
|
function selectKitForUpdate(params) {
|
|
67337
67401
|
const { hasLocal, hasGlobal, localKits, globalKits } = params;
|
|
@@ -67380,7 +67444,7 @@ async function readMetadataFile(claudeDir3) {
|
|
|
67380
67444
|
return null;
|
|
67381
67445
|
}
|
|
67382
67446
|
}
|
|
67383
|
-
function buildInitCommand(isGlobal, kit, beta, yes) {
|
|
67447
|
+
function buildInitCommand(isGlobal, kit, beta, yes, restoreCkHooks) {
|
|
67384
67448
|
const parts = ["ck init"];
|
|
67385
67449
|
if (isGlobal)
|
|
67386
67450
|
parts.push("-g");
|
|
@@ -67388,6 +67452,8 @@ function buildInitCommand(isGlobal, kit, beta, yes) {
|
|
|
67388
67452
|
parts.push(`--kit ${kit}`);
|
|
67389
67453
|
if (yes)
|
|
67390
67454
|
parts.push("--yes");
|
|
67455
|
+
if (restoreCkHooks)
|
|
67456
|
+
parts.push("--restore-ck-hooks");
|
|
67391
67457
|
parts.push("--install-skills");
|
|
67392
67458
|
if (beta)
|
|
67393
67459
|
parts.push("--beta");
|
|
@@ -67464,19 +67530,49 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
67464
67530
|
const globalMetadata = hasGlobal ? await readMetadataFile(setup.global.path) : null;
|
|
67465
67531
|
const localKits = localMetadata ? getInstalledKits(localMetadata) : [];
|
|
67466
67532
|
const globalKits = globalMetadata ? getInstalledKits(globalMetadata) : [];
|
|
67467
|
-
|
|
67533
|
+
let selection = selectKitForUpdate({ hasLocal, hasGlobal, localKits, globalKits });
|
|
67468
67534
|
if (!selection) {
|
|
67469
67535
|
logger.verbose("No ClaudeKit installations detected, skipping kit update prompt");
|
|
67470
67536
|
return;
|
|
67471
67537
|
}
|
|
67472
|
-
|
|
67538
|
+
let forceKitReinstall = false;
|
|
67539
|
+
if (hasLocal && setup.project.path) {
|
|
67540
|
+
try {
|
|
67541
|
+
const missingHookDeps = await findMissingHookDepsFn(setup.project.path);
|
|
67542
|
+
if (missingHookDeps.length > 0) {
|
|
67543
|
+
logger.warning(`Detected ${missingHookDeps.length} local missing hook dependency(ies); reinstalling local kit content`);
|
|
67544
|
+
forceKitReinstall = true;
|
|
67545
|
+
}
|
|
67546
|
+
} catch (error) {
|
|
67547
|
+
logger.verbose(`Local hook dependency self-heal check skipped: ${error instanceof Error ? error.message : "unknown"}`);
|
|
67548
|
+
}
|
|
67549
|
+
try {
|
|
67550
|
+
const countMissingHookRefsFn = deps?.countMissingHookFileReferencesFn ?? countMissingHookFileReferences;
|
|
67551
|
+
const missingHookRefs = await countMissingHookRefsFn(dirname29(setup.project.path));
|
|
67552
|
+
if (missingHookRefs > 0) {
|
|
67553
|
+
logger.warning(`Detected ${missingHookRefs} local broken hook registration(s); reinstalling local kit content`);
|
|
67554
|
+
forceKitReinstall = true;
|
|
67555
|
+
}
|
|
67556
|
+
} catch (error) {
|
|
67557
|
+
logger.verbose(`Local hook registration self-heal check skipped: ${error instanceof Error ? error.message : "unknown"}`);
|
|
67558
|
+
}
|
|
67559
|
+
if (forceKitReinstall && selection.isGlobal) {
|
|
67560
|
+
const kit = localKits[0] || selection.kit;
|
|
67561
|
+
selection = {
|
|
67562
|
+
isGlobal: false,
|
|
67563
|
+
kit,
|
|
67564
|
+
promptMessage: `Update local project ClaudeKit content${kit ? ` (${kit})` : ""}?`
|
|
67565
|
+
};
|
|
67566
|
+
}
|
|
67567
|
+
}
|
|
67568
|
+
let kitVersion = selection.kit ? selection.isGlobal ? globalMetadata?.kits?.[selection.kit]?.version : localMetadata?.kits?.[selection.kit]?.version : undefined;
|
|
67473
67569
|
const isBetaInstalled = isBetaVersion(kitVersion);
|
|
67474
67570
|
const promptMessage = selection.promptMessage;
|
|
67475
67571
|
if (selection.kit && kitVersion) {
|
|
67476
67572
|
logger.info(`Current kit version: ${selection.kit}@${kitVersion}`);
|
|
67477
67573
|
}
|
|
67478
67574
|
let alreadyAtLatest = false;
|
|
67479
|
-
if (yes && selection.kit && kitVersion) {
|
|
67575
|
+
if (yes && selection.kit && kitVersion && !forceKitReinstall) {
|
|
67480
67576
|
const getTagFn = deps?.getLatestReleaseTagFn ?? fetchLatestReleaseTag;
|
|
67481
67577
|
const latestTag = await getTagFn(selection.kit, beta || isBetaInstalled);
|
|
67482
67578
|
if (latestTag && versionsMatch(kitVersion, latestTag)) {
|
|
@@ -67492,11 +67588,34 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
67492
67588
|
if (missingHookDeps.length > 0) {
|
|
67493
67589
|
logger.warning(`Detected ${missingHookDeps.length} missing hook dependency(ies); reinstalling kit content`);
|
|
67494
67590
|
alreadyAtLatest = false;
|
|
67591
|
+
forceKitReinstall = true;
|
|
67495
67592
|
}
|
|
67496
67593
|
} catch (error) {
|
|
67497
67594
|
logger.verbose(`Hook dependency self-heal check skipped: ${error instanceof Error ? error.message : "unknown"}`);
|
|
67498
67595
|
}
|
|
67499
67596
|
}
|
|
67597
|
+
if (alreadyAtLatest) {
|
|
67598
|
+
try {
|
|
67599
|
+
const countMissingHookRefsFn = deps?.countMissingHookFileReferencesFn ?? countMissingHookFileReferences;
|
|
67600
|
+
const projectDir = setup.project.path ? dirname29(setup.project.path) : process.cwd();
|
|
67601
|
+
const missingHookRefs = await countMissingHookRefsFn(projectDir);
|
|
67602
|
+
if (missingHookRefs > 0) {
|
|
67603
|
+
logger.warning(`Detected ${missingHookRefs} broken hook registration(s); reinstalling kit content`);
|
|
67604
|
+
alreadyAtLatest = false;
|
|
67605
|
+
forceKitReinstall = true;
|
|
67606
|
+
if (setup.project.path && selection.isGlobal) {
|
|
67607
|
+
selection = {
|
|
67608
|
+
isGlobal: false,
|
|
67609
|
+
kit: localKits[0] || selection.kit,
|
|
67610
|
+
promptMessage: `Update local project ClaudeKit content${localKits[0] || selection.kit ? ` (${localKits[0] || selection.kit})` : ""}?`
|
|
67611
|
+
};
|
|
67612
|
+
kitVersion = selection.kit ? localMetadata?.kits?.[selection.kit]?.version : undefined;
|
|
67613
|
+
}
|
|
67614
|
+
}
|
|
67615
|
+
} catch (error) {
|
|
67616
|
+
logger.verbose(`Hook registration self-heal check skipped: ${error instanceof Error ? error.message : "unknown"}`);
|
|
67617
|
+
}
|
|
67618
|
+
}
|
|
67500
67619
|
let autoInit = false;
|
|
67501
67620
|
try {
|
|
67502
67621
|
const ckConfig = await loadFullConfigFn(null);
|
|
@@ -67520,7 +67639,7 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
67520
67639
|
}
|
|
67521
67640
|
const useBeta = beta || isBetaInstalled;
|
|
67522
67641
|
if (yes) {
|
|
67523
|
-
const initCmd = buildInitCommand(selection.isGlobal, selection.kit, useBeta, true);
|
|
67642
|
+
const initCmd = buildInitCommand(selection.isGlobal, selection.kit, useBeta, true, forceKitReinstall);
|
|
67524
67643
|
logger.info(`Running: ${initCmd}`);
|
|
67525
67644
|
const s = (deps?.spinnerFn ?? de)();
|
|
67526
67645
|
s.start("Updating ClaudeKit content...");
|
|
@@ -67553,6 +67672,8 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
67553
67672
|
const args = ["init"];
|
|
67554
67673
|
if (selection.isGlobal)
|
|
67555
67674
|
args.push("-g");
|
|
67675
|
+
if (forceKitReinstall)
|
|
67676
|
+
args.push("--restore-ck-hooks");
|
|
67556
67677
|
args.push("--install-skills");
|
|
67557
67678
|
if (useBeta)
|
|
67558
67679
|
args.push("--beta");
|
|
@@ -67622,17 +67743,19 @@ async function promptMigrateUpdate(deps) {
|
|
|
67622
67743
|
} catch {}
|
|
67623
67744
|
try {
|
|
67624
67745
|
const cleanupFn = deps?.cleanupMigratedHooksFn ?? (await Promise.resolve().then(() => (init_migrated_hooks_cleanup(), exports_migrated_hooks_cleanup))).cleanupMigratedHooksForProviders;
|
|
67625
|
-
const cleanupProviders = allProviders.filter((p) => SAFE_PROVIDER_NAME.test(p));
|
|
67626
|
-
|
|
67627
|
-
|
|
67628
|
-
|
|
67629
|
-
|
|
67746
|
+
const cleanupProviders = allProviders.filter((p) => p !== "claude-code" && SAFE_PROVIDER_NAME.test(p));
|
|
67747
|
+
if (cleanupProviders.length > 0) {
|
|
67748
|
+
const cleanupResults = await cleanupFn(cleanupProviders, { global: isGlobal });
|
|
67749
|
+
const cleanupCount = cleanupResults.reduce((total, result) => total + result.hooksPruned + result.filesRemoved + result.registryEntriesRemoved, 0);
|
|
67750
|
+
if (cleanupCount > 0) {
|
|
67751
|
+
logger.info(`Cleaned up ${cleanupCount} generated-context hook artifact(s)`);
|
|
67752
|
+
}
|
|
67753
|
+
await repairLegacyHookPromptsSafely();
|
|
67754
|
+
await repairHookFileReferencesSafely();
|
|
67630
67755
|
}
|
|
67631
67756
|
} catch (error) {
|
|
67632
67757
|
logger.verbose(`Migrated hook cleanup skipped: ${error instanceof Error ? error.message : "unknown"}`);
|
|
67633
67758
|
}
|
|
67634
|
-
await repairLegacyHookPromptsSafely();
|
|
67635
|
-
await repairHookFileReferencesSafely();
|
|
67636
67759
|
const targets = allProviders.filter((p) => p !== "claude-code");
|
|
67637
67760
|
if (targets.length === 0) {
|
|
67638
67761
|
logger.verbose("No migration targets detected, skipping migrate step");
|
|
@@ -68560,7 +68683,7 @@ var init_routes = __esm(() => {
|
|
|
68560
68683
|
|
|
68561
68684
|
// src/domains/web-server/static-server.ts
|
|
68562
68685
|
import { existsSync as existsSync49 } from "node:fs";
|
|
68563
|
-
import { basename as basename24, dirname as
|
|
68686
|
+
import { basename as basename24, dirname as dirname30, join as join71, resolve as resolve34 } from "node:path";
|
|
68564
68687
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
68565
68688
|
function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
68566
68689
|
if (!runtimePath) {
|
|
@@ -68570,7 +68693,7 @@ function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
|
68570
68693
|
if (!looksLikePath) {
|
|
68571
68694
|
return;
|
|
68572
68695
|
}
|
|
68573
|
-
const entryDir =
|
|
68696
|
+
const entryDir = dirname30(resolve34(runtimePath));
|
|
68574
68697
|
if (basename24(entryDir) === "dist") {
|
|
68575
68698
|
candidates.add(join71(entryDir, "ui"));
|
|
68576
68699
|
}
|
|
@@ -68631,7 +68754,7 @@ var import_express, __dirname3;
|
|
|
68631
68754
|
var init_static_server = __esm(() => {
|
|
68632
68755
|
init_logger();
|
|
68633
68756
|
import_express = __toESM(require_express2(), 1);
|
|
68634
|
-
__dirname3 =
|
|
68757
|
+
__dirname3 = dirname30(fileURLToPath2(import.meta.url));
|
|
68635
68758
|
});
|
|
68636
68759
|
|
|
68637
68760
|
// node_modules/ws/lib/constants.js
|
|
@@ -74141,7 +74264,7 @@ var init_skills_installer2 = __esm(() => {
|
|
|
74141
74264
|
// src/services/package-installer/gemini-mcp/config-manager.ts
|
|
74142
74265
|
import { existsSync as existsSync62 } from "node:fs";
|
|
74143
74266
|
import { mkdir as mkdir23, readFile as readFile47, writeFile as writeFile23 } from "node:fs/promises";
|
|
74144
|
-
import { dirname as
|
|
74267
|
+
import { dirname as dirname33, join as join92 } from "node:path";
|
|
74145
74268
|
async function readJsonFile(filePath) {
|
|
74146
74269
|
try {
|
|
74147
74270
|
const content = await readFile47(filePath, "utf-8");
|
|
@@ -74181,7 +74304,7 @@ ${geminiPattern}
|
|
|
74181
74304
|
}
|
|
74182
74305
|
}
|
|
74183
74306
|
async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
|
|
74184
|
-
const linkDir =
|
|
74307
|
+
const linkDir = dirname33(geminiSettingsPath);
|
|
74185
74308
|
if (!existsSync62(linkDir)) {
|
|
74186
74309
|
await mkdir23(linkDir, { recursive: true });
|
|
74187
74310
|
logger.debug(`Created directory: ${linkDir}`);
|
|
@@ -74300,9 +74423,9 @@ var init_validation = __esm(() => {
|
|
|
74300
74423
|
// src/services/package-installer/gemini-mcp/linker-core.ts
|
|
74301
74424
|
import { existsSync as existsSync64 } from "node:fs";
|
|
74302
74425
|
import { mkdir as mkdir24, symlink as symlink3 } from "node:fs/promises";
|
|
74303
|
-
import { dirname as
|
|
74426
|
+
import { dirname as dirname34, join as join94 } from "node:path";
|
|
74304
74427
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
74305
|
-
const linkDir =
|
|
74428
|
+
const linkDir = dirname34(linkPath);
|
|
74306
74429
|
if (!existsSync64(linkDir)) {
|
|
74307
74430
|
await mkdir24(linkDir, { recursive: true });
|
|
74308
74431
|
logger.debug(`Created directory: ${linkDir}`);
|
|
@@ -77649,7 +77772,7 @@ var init_sqlite_client = () => {};
|
|
|
77649
77772
|
|
|
77650
77773
|
// src/commands/content/phases/db-manager.ts
|
|
77651
77774
|
import { existsSync as existsSync83, mkdirSync as mkdirSync8 } from "node:fs";
|
|
77652
|
-
import { dirname as
|
|
77775
|
+
import { dirname as dirname52 } from "node:path";
|
|
77653
77776
|
function initDatabase(dbPath) {
|
|
77654
77777
|
ensureParentDir(dbPath);
|
|
77655
77778
|
const db = openDatabase(dbPath);
|
|
@@ -77670,7 +77793,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
77670
77793
|
db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
|
|
77671
77794
|
}
|
|
77672
77795
|
function ensureParentDir(dbPath) {
|
|
77673
|
-
const dir =
|
|
77796
|
+
const dir = dirname52(dbPath);
|
|
77674
77797
|
if (dir && !existsSync83(dir)) {
|
|
77675
77798
|
mkdirSync8(dir, { recursive: true });
|
|
77676
77799
|
}
|
|
@@ -80691,6 +80814,10 @@ var init_init_command_help = __esm(() => {
|
|
|
80691
80814
|
{
|
|
80692
80815
|
flags: "--force-overwrite-settings",
|
|
80693
80816
|
description: "Fully replace settings.json instead of selective merge"
|
|
80817
|
+
},
|
|
80818
|
+
{
|
|
80819
|
+
flags: "--restore-ck-hooks",
|
|
80820
|
+
description: "Restore CK-managed hook registrations during update self-heal"
|
|
80694
80821
|
}
|
|
80695
80822
|
]
|
|
80696
80823
|
},
|
|
@@ -88165,7 +88292,7 @@ init_path_resolver();
|
|
|
88165
88292
|
import { existsSync as existsSync58 } from "node:fs";
|
|
88166
88293
|
import { readFile as readFile42 } from "node:fs/promises";
|
|
88167
88294
|
import { homedir as homedir43 } from "node:os";
|
|
88168
|
-
import { dirname as
|
|
88295
|
+
import { dirname as dirname31, join as join80, normalize as normalize6, resolve as resolve36 } from "node:path";
|
|
88169
88296
|
async function checkPathRefsValid(projectDir) {
|
|
88170
88297
|
const globalClaudeMd = join80(PathResolver.getGlobalKitDir(), "CLAUDE.md");
|
|
88171
88298
|
const projectClaudeMd = join80(projectDir, ".claude", "CLAUDE.md");
|
|
@@ -88196,7 +88323,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
88196
88323
|
autoFixable: false
|
|
88197
88324
|
};
|
|
88198
88325
|
}
|
|
88199
|
-
const baseDir =
|
|
88326
|
+
const baseDir = dirname31(claudeMdPath);
|
|
88200
88327
|
const home5 = homedir43();
|
|
88201
88328
|
const broken = [];
|
|
88202
88329
|
for (const ref of refs) {
|
|
@@ -90028,14 +90155,14 @@ class AutoHealer {
|
|
|
90028
90155
|
import { execSync as execSync4, spawnSync as spawnSync6 } from "node:child_process";
|
|
90029
90156
|
import { readFileSync as readFileSync17, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
90030
90157
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
90031
|
-
import { dirname as
|
|
90158
|
+
import { dirname as dirname32, join as join87 } from "node:path";
|
|
90032
90159
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
90033
90160
|
init_environment();
|
|
90034
90161
|
init_logger();
|
|
90035
90162
|
init_dist2();
|
|
90036
90163
|
function getCliVersion4() {
|
|
90037
90164
|
try {
|
|
90038
|
-
const __dirname4 =
|
|
90165
|
+
const __dirname4 = dirname32(fileURLToPath4(import.meta.url));
|
|
90039
90166
|
const pkgPath = join87(__dirname4, "../../../package.json");
|
|
90040
90167
|
const pkg = JSON.parse(readFileSync17(pkgPath, "utf-8"));
|
|
90041
90168
|
return pkg.version || "unknown";
|
|
@@ -94638,7 +94765,7 @@ import path10 from "node:path";
|
|
|
94638
94765
|
|
|
94639
94766
|
// node_modules/tar/dist/esm/list.js
|
|
94640
94767
|
import fs10 from "node:fs";
|
|
94641
|
-
import { dirname as
|
|
94768
|
+
import { dirname as dirname35, parse as parse4 } from "path";
|
|
94642
94769
|
|
|
94643
94770
|
// node_modules/tar/dist/esm/options.js
|
|
94644
94771
|
var argmap = new Map([
|
|
@@ -97538,7 +97665,7 @@ var filesFilter = (opt, files) => {
|
|
|
97538
97665
|
if (m2 !== undefined) {
|
|
97539
97666
|
ret = m2;
|
|
97540
97667
|
} else {
|
|
97541
|
-
ret = mapHas(
|
|
97668
|
+
ret = mapHas(dirname35(file), root);
|
|
97542
97669
|
}
|
|
97543
97670
|
}
|
|
97544
97671
|
map.set(file, ret);
|
|
@@ -100597,7 +100724,7 @@ import { promisify as promisify15 } from "node:util";
|
|
|
100597
100724
|
// src/domains/installation/extraction/native-zip-commands.ts
|
|
100598
100725
|
var NATIVE_EXTRACT_TIMEOUT_MS = 120000;
|
|
100599
100726
|
function getNativeZipCommands(archivePath, destDir, platformName = process.platform) {
|
|
100600
|
-
if (platformName === "darwin") {
|
|
100727
|
+
if (platformName === "darwin" || platformName === "linux") {
|
|
100601
100728
|
return [
|
|
100602
100729
|
{
|
|
100603
100730
|
label: "native unzip",
|
|
@@ -101281,7 +101408,7 @@ import { join as join120 } from "node:path";
|
|
|
101281
101408
|
|
|
101282
101409
|
// src/domains/installation/deletion-handler.ts
|
|
101283
101410
|
import { existsSync as existsSync65, lstatSync as lstatSync3, readdirSync as readdirSync9, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync4 } from "node:fs";
|
|
101284
|
-
import { dirname as
|
|
101411
|
+
import { dirname as dirname37, join as join106, relative as relative21, resolve as resolve41, sep as sep12 } from "node:path";
|
|
101285
101412
|
|
|
101286
101413
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
101287
101414
|
init_metadata_migration();
|
|
@@ -101507,7 +101634,7 @@ function expandGlobPatterns(patterns, claudeDir3) {
|
|
|
101507
101634
|
var MAX_CLEANUP_ITERATIONS = 50;
|
|
101508
101635
|
function cleanupEmptyDirectories(filePath, claudeDir3) {
|
|
101509
101636
|
const normalizedClaudeDir = resolve41(claudeDir3);
|
|
101510
|
-
let currentDir = resolve41(
|
|
101637
|
+
let currentDir = resolve41(dirname37(filePath));
|
|
101511
101638
|
let iterations = 0;
|
|
101512
101639
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir) && iterations < MAX_CLEANUP_ITERATIONS) {
|
|
101513
101640
|
iterations++;
|
|
@@ -101516,7 +101643,7 @@ function cleanupEmptyDirectories(filePath, claudeDir3) {
|
|
|
101516
101643
|
if (entries.length === 0) {
|
|
101517
101644
|
rmdirSync(currentDir);
|
|
101518
101645
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
101519
|
-
currentDir = resolve41(
|
|
101646
|
+
currentDir = resolve41(dirname37(currentDir));
|
|
101520
101647
|
} else {
|
|
101521
101648
|
break;
|
|
101522
101649
|
}
|
|
@@ -101639,7 +101766,7 @@ init_logger();
|
|
|
101639
101766
|
init_types3();
|
|
101640
101767
|
var import_fs_extra15 = __toESM(require_lib(), 1);
|
|
101641
101768
|
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
101642
|
-
import { dirname as
|
|
101769
|
+
import { dirname as dirname40, join as join110, relative as relative23 } from "node:path";
|
|
101643
101770
|
|
|
101644
101771
|
// src/domains/installation/selective-merger.ts
|
|
101645
101772
|
import { stat as stat18 } from "node:fs/promises";
|
|
@@ -103310,13 +103437,13 @@ class FileScanner {
|
|
|
103310
103437
|
// src/domains/installation/merger/settings-processor.ts
|
|
103311
103438
|
import { execSync as execSync5 } from "node:child_process";
|
|
103312
103439
|
import { homedir as homedir46 } from "node:os";
|
|
103313
|
-
import { dirname as
|
|
103440
|
+
import { dirname as dirname39, join as join109 } from "node:path";
|
|
103314
103441
|
|
|
103315
103442
|
// src/domains/config/installed-settings-tracker.ts
|
|
103316
103443
|
init_shared();
|
|
103317
103444
|
import { existsSync as existsSync66 } from "node:fs";
|
|
103318
103445
|
import { mkdir as mkdir31, readFile as readFile50, writeFile as writeFile25 } from "node:fs/promises";
|
|
103319
|
-
import { dirname as
|
|
103446
|
+
import { dirname as dirname38, join as join108 } from "node:path";
|
|
103320
103447
|
var CK_JSON_FILE = ".ck.json";
|
|
103321
103448
|
|
|
103322
103449
|
class InstalledSettingsTracker {
|
|
@@ -103341,7 +103468,7 @@ class InstalledSettingsTracker {
|
|
|
103341
103468
|
}
|
|
103342
103469
|
try {
|
|
103343
103470
|
const content = await readFile50(ckJsonPath, "utf-8");
|
|
103344
|
-
const data =
|
|
103471
|
+
const data = parseJsonContent(content);
|
|
103345
103472
|
const installed = data.kits?.[this.kitName]?.installedSettings;
|
|
103346
103473
|
if (installed) {
|
|
103347
103474
|
return installed;
|
|
@@ -103358,7 +103485,7 @@ class InstalledSettingsTracker {
|
|
|
103358
103485
|
let data = {};
|
|
103359
103486
|
if (existsSync66(ckJsonPath)) {
|
|
103360
103487
|
const content = await readFile50(ckJsonPath, "utf-8");
|
|
103361
|
-
data =
|
|
103488
|
+
data = parseJsonContent(content);
|
|
103362
103489
|
}
|
|
103363
103490
|
if (!data.kits) {
|
|
103364
103491
|
data.kits = {};
|
|
@@ -103367,7 +103494,7 @@ class InstalledSettingsTracker {
|
|
|
103367
103494
|
data.kits[this.kitName] = {};
|
|
103368
103495
|
}
|
|
103369
103496
|
data.kits[this.kitName].installedSettings = settings;
|
|
103370
|
-
await mkdir31(
|
|
103497
|
+
await mkdir31(dirname38(ckJsonPath), { recursive: true });
|
|
103371
103498
|
await writeFile25(ckJsonPath, JSON.stringify(data, null, 2), "utf-8");
|
|
103372
103499
|
logger.debug(`Saved installed settings to ${ckJsonPath}`);
|
|
103373
103500
|
} catch (error) {
|
|
@@ -103424,6 +103551,7 @@ class SettingsProcessor {
|
|
|
103424
103551
|
installingKit;
|
|
103425
103552
|
cachedVersion = undefined;
|
|
103426
103553
|
deletionPatterns = [];
|
|
103554
|
+
restoreCkHooks = false;
|
|
103427
103555
|
zombiePrunerHookDir = null;
|
|
103428
103556
|
setGlobalFlag(isGlobal) {
|
|
103429
103557
|
this.isGlobal = isGlobal;
|
|
@@ -103431,6 +103559,9 @@ class SettingsProcessor {
|
|
|
103431
103559
|
setForceOverwriteSettings(force) {
|
|
103432
103560
|
this.forceOverwriteSettings = force;
|
|
103433
103561
|
}
|
|
103562
|
+
setRestoreCkHooks(restore) {
|
|
103563
|
+
this.restoreCkHooks = restore;
|
|
103564
|
+
}
|
|
103434
103565
|
setProjectDir(dir) {
|
|
103435
103566
|
this.projectDir = dir;
|
|
103436
103567
|
this.initTracker();
|
|
@@ -103475,6 +103606,7 @@ class SettingsProcessor {
|
|
|
103475
103606
|
} else {
|
|
103476
103607
|
try {
|
|
103477
103608
|
const parsedSettings = JSON.parse(transformedSource);
|
|
103609
|
+
await this.applyDisabledHookConfig(parsedSettings);
|
|
103478
103610
|
this.logHookCommandRepair(this.fixHookCommandPaths(parsedSettings), "fresh install");
|
|
103479
103611
|
await SettingsMerger.writeSettingsFile(destFile, parsedSettings);
|
|
103480
103612
|
try {
|
|
@@ -103504,6 +103636,7 @@ class SettingsProcessor {
|
|
|
103504
103636
|
let sourceSettings;
|
|
103505
103637
|
try {
|
|
103506
103638
|
sourceSettings = JSON.parse(transformedSourceContent);
|
|
103639
|
+
await this.applyDisabledHookConfig(sourceSettings);
|
|
103507
103640
|
} catch {
|
|
103508
103641
|
logger.warning("Failed to parse source settings.json, falling back to overwrite");
|
|
103509
103642
|
const formattedContent = this.formatJsonContent(transformedSourceContent);
|
|
@@ -103526,10 +103659,15 @@ class SettingsProcessor {
|
|
|
103526
103659
|
if (this.tracker) {
|
|
103527
103660
|
installedSettings = await this.tracker.loadInstalledSettings();
|
|
103528
103661
|
}
|
|
103662
|
+
const mergeInstalledSettings = this.restoreCkHooks ? { ...installedSettings, hooks: [] } : installedSettings;
|
|
103529
103663
|
const mergeResult = SettingsMerger.merge(sourceSettings, destSettings, {
|
|
103530
|
-
installedSettings,
|
|
103664
|
+
installedSettings: mergeInstalledSettings,
|
|
103531
103665
|
sourceKit: this.installingKit
|
|
103532
103666
|
});
|
|
103667
|
+
await this.applyDisabledHookConfig(mergeResult.merged);
|
|
103668
|
+
if (this.restoreCkHooks) {
|
|
103669
|
+
logger.info("Restored CK hook registrations while respecting .ck.json hook disables");
|
|
103670
|
+
}
|
|
103533
103671
|
logger.verbose("Settings merge details", {
|
|
103534
103672
|
hooksAdded: mergeResult.hooksAdded,
|
|
103535
103673
|
hooksPreserved: mergeResult.hooksPreserved,
|
|
@@ -103559,7 +103697,8 @@ class SettingsProcessor {
|
|
|
103559
103697
|
logger.info(`Pruned ${hooksPruned} stale hook(s) referencing deleted files`);
|
|
103560
103698
|
}
|
|
103561
103699
|
if (this.zombiePrunerHookDir) {
|
|
103562
|
-
const
|
|
103700
|
+
const sourceHookCommands = this.collectHookCommands(sourceSettings);
|
|
103701
|
+
const { pruned: zombiePruned } = pruneZombieEngineerWirings(mergeResult.merged, this.zombiePrunerHookDir, sourceHookCommands);
|
|
103563
103702
|
if (zombiePruned.length > 0) {
|
|
103564
103703
|
logger.info(`Pruned ${zombiePruned.length} zombie hook entries: ${zombiePruned.join(", ")}`);
|
|
103565
103704
|
}
|
|
@@ -103568,6 +103707,111 @@ class SettingsProcessor {
|
|
|
103568
103707
|
logger.success("Merged settings.json (user customizations preserved)");
|
|
103569
103708
|
await this.injectTeamHooksIfSupported(destFile, mergeResult.merged);
|
|
103570
103709
|
}
|
|
103710
|
+
async getDisabledHookNames() {
|
|
103711
|
+
if (!this.projectDir) {
|
|
103712
|
+
return new Set;
|
|
103713
|
+
}
|
|
103714
|
+
const disabled = new Set;
|
|
103715
|
+
const addFromConfig = async (configPath) => {
|
|
103716
|
+
const names = await this.readDisabledHookNamesFromConfig(configPath);
|
|
103717
|
+
for (const name2 of names)
|
|
103718
|
+
disabled.add(name2);
|
|
103719
|
+
};
|
|
103720
|
+
try {
|
|
103721
|
+
if (this.isGlobal) {
|
|
103722
|
+
await addFromConfig(join109(this.projectDir, ".ck.json"));
|
|
103723
|
+
} else {
|
|
103724
|
+
await addFromConfig(join109(PathResolver.getGlobalKitDir(), ".ck.json"));
|
|
103725
|
+
await addFromConfig(join109(this.projectDir, ".claude", ".ck.json"));
|
|
103726
|
+
}
|
|
103727
|
+
} catch (error) {
|
|
103728
|
+
logger.debug(`Failed to load .ck.json hook preferences: ${error instanceof Error ? error.message : "unknown"}`);
|
|
103729
|
+
}
|
|
103730
|
+
return disabled;
|
|
103731
|
+
}
|
|
103732
|
+
async readDisabledHookNamesFromConfig(configPath) {
|
|
103733
|
+
if (!await import_fs_extra14.pathExists(configPath))
|
|
103734
|
+
return new Set;
|
|
103735
|
+
const raw2 = parseJsonContent(await import_fs_extra14.readFile(configPath, "utf-8"));
|
|
103736
|
+
const hooks = raw2.hooks;
|
|
103737
|
+
if (!hooks || typeof hooks !== "object")
|
|
103738
|
+
return new Set;
|
|
103739
|
+
return new Set(Object.entries(hooks).filter(([, enabled]) => enabled === false).map(([name2]) => name2));
|
|
103740
|
+
}
|
|
103741
|
+
async applyDisabledHookConfig(settings) {
|
|
103742
|
+
const disabledHooks = await this.getDisabledHookNames();
|
|
103743
|
+
if (disabledHooks.size === 0 || !settings.hooks)
|
|
103744
|
+
return 0;
|
|
103745
|
+
let removed = 0;
|
|
103746
|
+
const hooksRecord = settings.hooks;
|
|
103747
|
+
for (const [eventName, entries] of Object.entries(hooksRecord)) {
|
|
103748
|
+
const filteredEntries = [];
|
|
103749
|
+
for (const entry of entries) {
|
|
103750
|
+
if (Array.isArray(entry.hooks)) {
|
|
103751
|
+
const keptHooks = entry.hooks.filter((hook) => {
|
|
103752
|
+
const command = typeof hook.command === "string" ? hook.command : "";
|
|
103753
|
+
const hookName = this.extractCkHookName(command);
|
|
103754
|
+
if (hookName && disabledHooks.has(hookName)) {
|
|
103755
|
+
removed++;
|
|
103756
|
+
return false;
|
|
103757
|
+
}
|
|
103758
|
+
return true;
|
|
103759
|
+
});
|
|
103760
|
+
if (keptHooks.length > 0) {
|
|
103761
|
+
filteredEntries.push({ ...entry, hooks: keptHooks });
|
|
103762
|
+
}
|
|
103763
|
+
} else {
|
|
103764
|
+
const command = typeof entry.command === "string" ? entry.command : "";
|
|
103765
|
+
const hookName = this.extractCkHookName(command);
|
|
103766
|
+
if (hookName && disabledHooks.has(hookName)) {
|
|
103767
|
+
removed++;
|
|
103768
|
+
continue;
|
|
103769
|
+
}
|
|
103770
|
+
filteredEntries.push(entry);
|
|
103771
|
+
}
|
|
103772
|
+
}
|
|
103773
|
+
if (filteredEntries.length > 0) {
|
|
103774
|
+
hooksRecord[eventName] = filteredEntries;
|
|
103775
|
+
} else {
|
|
103776
|
+
delete hooksRecord[eventName];
|
|
103777
|
+
}
|
|
103778
|
+
}
|
|
103779
|
+
if (Object.keys(hooksRecord).length === 0) {
|
|
103780
|
+
settings.hooks = undefined;
|
|
103781
|
+
}
|
|
103782
|
+
if (removed > 0) {
|
|
103783
|
+
logger.info(`Skipped ${removed} hook registration(s) disabled in .ck.json`);
|
|
103784
|
+
}
|
|
103785
|
+
return removed;
|
|
103786
|
+
}
|
|
103787
|
+
collectHookCommands(settings) {
|
|
103788
|
+
const commands = new Set;
|
|
103789
|
+
if (!settings.hooks)
|
|
103790
|
+
return commands;
|
|
103791
|
+
for (const entries of Object.values(settings.hooks)) {
|
|
103792
|
+
for (const entry of entries) {
|
|
103793
|
+
if ("hooks" in entry && Array.isArray(entry.hooks)) {
|
|
103794
|
+
for (const hook of entry.hooks) {
|
|
103795
|
+
if (typeof hook.command === "string") {
|
|
103796
|
+
commands.add(hook.command);
|
|
103797
|
+
}
|
|
103798
|
+
}
|
|
103799
|
+
continue;
|
|
103800
|
+
}
|
|
103801
|
+
if ("command" in entry && typeof entry.command === "string") {
|
|
103802
|
+
commands.add(entry.command);
|
|
103803
|
+
}
|
|
103804
|
+
}
|
|
103805
|
+
}
|
|
103806
|
+
return commands;
|
|
103807
|
+
}
|
|
103808
|
+
extractCkHookName(command) {
|
|
103809
|
+
if (!command.trim().startsWith("node "))
|
|
103810
|
+
return null;
|
|
103811
|
+
const normalized = command.replace(/\\/g, "/");
|
|
103812
|
+
const match2 = normalized.match(/\/hooks\/([^/"'\s]+)\.(?:cjs|mjs|js)(?:["'\s]|$)/);
|
|
103813
|
+
return match2?.[1] ?? null;
|
|
103814
|
+
}
|
|
103571
103815
|
migrateDeprecatedMatchers(destSettings, sourceSettings) {
|
|
103572
103816
|
if (!destSettings.hooks || !sourceSettings.hooks)
|
|
103573
103817
|
return;
|
|
@@ -103829,7 +104073,7 @@ class SettingsProcessor {
|
|
|
103829
104073
|
return true;
|
|
103830
104074
|
}
|
|
103831
104075
|
async repairSiblingSettingsLocal(destFile) {
|
|
103832
|
-
const settingsLocalPath = join109(
|
|
104076
|
+
const settingsLocalPath = join109(dirname39(destFile), "settings.local.json");
|
|
103833
104077
|
if (settingsLocalPath === destFile || !await import_fs_extra14.pathExists(settingsLocalPath)) {
|
|
103834
104078
|
return;
|
|
103835
104079
|
}
|
|
@@ -103960,6 +104204,9 @@ class CopyExecutor {
|
|
|
103960
104204
|
setForceOverwriteSettings(force) {
|
|
103961
104205
|
this.settingsProcessor.setForceOverwriteSettings(force);
|
|
103962
104206
|
}
|
|
104207
|
+
setRestoreCkHooks(restore) {
|
|
104208
|
+
this.settingsProcessor.setRestoreCkHooks(restore);
|
|
104209
|
+
}
|
|
103963
104210
|
setDeletions(deletions) {
|
|
103964
104211
|
this.settingsProcessor.setDeletions(deletions);
|
|
103965
104212
|
}
|
|
@@ -104092,10 +104339,10 @@ class CopyExecutor {
|
|
|
104092
104339
|
}
|
|
104093
104340
|
trackInstalledFile(relativePath) {
|
|
104094
104341
|
this.installedFiles.add(relativePath);
|
|
104095
|
-
let dir =
|
|
104342
|
+
let dir = dirname40(relativePath);
|
|
104096
104343
|
while (dir && dir !== "." && dir !== "/") {
|
|
104097
104344
|
this.installedDirectories.add(`${dir}/`);
|
|
104098
|
-
dir =
|
|
104345
|
+
dir = dirname40(dir);
|
|
104099
104346
|
}
|
|
104100
104347
|
}
|
|
104101
104348
|
}
|
|
@@ -104132,6 +104379,9 @@ class FileMerger {
|
|
|
104132
104379
|
setForceOverwriteSettings(force) {
|
|
104133
104380
|
this.copyExecutor.setForceOverwriteSettings(force);
|
|
104134
104381
|
}
|
|
104382
|
+
setRestoreCkHooks(restore) {
|
|
104383
|
+
this.copyExecutor.setRestoreCkHooks(restore);
|
|
104384
|
+
}
|
|
104135
104385
|
setProjectDir(dir) {
|
|
104136
104386
|
this.copyExecutor.setProjectDir(dir);
|
|
104137
104387
|
}
|
|
@@ -105455,6 +105705,7 @@ async function handleMerge(ctx) {
|
|
|
105455
105705
|
}
|
|
105456
105706
|
merger.setGlobalFlag(ctx.options.global);
|
|
105457
105707
|
merger.setForceOverwriteSettings(ctx.options.forceOverwriteSettings);
|
|
105708
|
+
merger.setRestoreCkHooks(ctx.options.restoreCkHooks);
|
|
105458
105709
|
merger.setProjectDir(ctx.resolvedDir);
|
|
105459
105710
|
merger.setKitName(ctx.kit.name);
|
|
105460
105711
|
merger.setZombiePrunerHookDir(join120(ctx.claudeDir, "hooks"));
|
|
@@ -106942,6 +107193,7 @@ async function resolveOptions(ctx) {
|
|
|
106942
107193
|
skipSetup: parsed.skipSetup ?? false,
|
|
106943
107194
|
forceOverwrite: parsed.forceOverwrite ?? false,
|
|
106944
107195
|
forceOverwriteSettings: parsed.forceOverwriteSettings ?? false,
|
|
107196
|
+
restoreCkHooks: parsed.restoreCkHooks ?? false,
|
|
106945
107197
|
dryRun: parsed.dryRun ?? false,
|
|
106946
107198
|
prefix: parsed.prefix ?? false,
|
|
106947
107199
|
sync: parsed.sync ?? false,
|
|
@@ -107249,7 +107501,7 @@ async function runPreflightChecks() {
|
|
|
107249
107501
|
// src/domains/installation/fresh-installer.ts
|
|
107250
107502
|
init_metadata_migration();
|
|
107251
107503
|
import { existsSync as existsSync67, readdirSync as readdirSync10, rmSync as rmSync3, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
|
|
107252
|
-
import { basename as basename28, dirname as
|
|
107504
|
+
import { basename as basename28, dirname as dirname41, join as join132, resolve as resolve45 } from "node:path";
|
|
107253
107505
|
init_logger();
|
|
107254
107506
|
init_safe_spinner();
|
|
107255
107507
|
var import_fs_extra34 = __toESM(require_lib(), 1);
|
|
@@ -107302,14 +107554,14 @@ async function analyzeFreshInstallation(claudeDir3) {
|
|
|
107302
107554
|
}
|
|
107303
107555
|
function cleanupEmptyDirectories2(filePath, claudeDir3) {
|
|
107304
107556
|
const normalizedClaudeDir = resolve45(claudeDir3);
|
|
107305
|
-
let currentDir = resolve45(
|
|
107557
|
+
let currentDir = resolve45(dirname41(filePath));
|
|
107306
107558
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
|
|
107307
107559
|
try {
|
|
107308
107560
|
const entries = readdirSync10(currentDir);
|
|
107309
107561
|
if (entries.length === 0) {
|
|
107310
107562
|
rmdirSync2(currentDir);
|
|
107311
107563
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
107312
|
-
currentDir = resolve45(
|
|
107564
|
+
currentDir = resolve45(dirname41(currentDir));
|
|
107313
107565
|
} else {
|
|
107314
107566
|
break;
|
|
107315
107567
|
}
|
|
@@ -107499,7 +107751,7 @@ async function handleFreshInstallation(claudeDir3, prompts) {
|
|
|
107499
107751
|
var import_fs_extra35 = __toESM(require_lib(), 1);
|
|
107500
107752
|
import { cp as cp5, mkdir as mkdir35, readdir as readdir42, rename as rename11, rm as rm16, stat as stat22 } from "node:fs/promises";
|
|
107501
107753
|
import { homedir as homedir47 } from "node:os";
|
|
107502
|
-
import { dirname as
|
|
107754
|
+
import { dirname as dirname42, join as join133, normalize as normalize11, resolve as resolve46 } from "node:path";
|
|
107503
107755
|
var LEGACY_KIT_MARKERS = [
|
|
107504
107756
|
"metadata.json",
|
|
107505
107757
|
".ck.json",
|
|
@@ -107612,7 +107864,7 @@ async function repairLegacyWindowsGlobalKitDir(options2) {
|
|
|
107612
107864
|
if (targetExists) {
|
|
107613
107865
|
await rm16(targetDir, { recursive: true, force: true });
|
|
107614
107866
|
}
|
|
107615
|
-
await mkdir35(
|
|
107867
|
+
await mkdir35(dirname42(targetDir), { recursive: true });
|
|
107616
107868
|
await moveDirectory(legacyDir, targetDir);
|
|
107617
107869
|
return { status: "repaired", reason: "repaired", legacyDir, candidateDirs };
|
|
107618
107870
|
}
|
|
@@ -107984,7 +108236,7 @@ async function handleSelection(ctx) {
|
|
|
107984
108236
|
logger.info("--force has no effect without --yes (the version-match skip only applies in non-interactive mode)");
|
|
107985
108237
|
}
|
|
107986
108238
|
const releaseTag = release?.tag_name;
|
|
107987
|
-
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
108239
|
+
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && !ctx.options.restoreCkHooks && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
107988
108240
|
try {
|
|
107989
108241
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
107990
108242
|
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
@@ -108011,7 +108263,7 @@ async function handleSelection(ctx) {
|
|
|
108011
108263
|
}
|
|
108012
108264
|
// src/commands/init/phases/sync-handler.ts
|
|
108013
108265
|
import { copyFile as copyFile8, mkdir as mkdir37, open as open5, readFile as readFile59, rename as rename12, stat as stat23, unlink as unlink13, writeFile as writeFile33 } from "node:fs/promises";
|
|
108014
|
-
import { dirname as
|
|
108266
|
+
import { dirname as dirname43, join as join135, resolve as resolve48 } from "node:path";
|
|
108015
108267
|
init_logger();
|
|
108016
108268
|
init_path_resolver();
|
|
108017
108269
|
var import_fs_extra37 = __toESM(require_lib(), 1);
|
|
@@ -108130,7 +108382,7 @@ async function acquireSyncLock(global3) {
|
|
|
108130
108382
|
const lockPath = join135(cacheDir, ".sync-lock");
|
|
108131
108383
|
const startTime = Date.now();
|
|
108132
108384
|
const lockTimeout = getLockTimeout();
|
|
108133
|
-
await mkdir37(
|
|
108385
|
+
await mkdir37(dirname43(lockPath), { recursive: true });
|
|
108134
108386
|
while (Date.now() - startTime < lockTimeout) {
|
|
108135
108387
|
try {
|
|
108136
108388
|
const handle = await open5(lockPath, "wx");
|
|
@@ -108958,6 +109210,7 @@ function createInitContext(rawOptions, prompts) {
|
|
|
108958
109210
|
skipSetup: false,
|
|
108959
109211
|
forceOverwrite: false,
|
|
108960
109212
|
forceOverwriteSettings: false,
|
|
109213
|
+
restoreCkHooks: false,
|
|
108961
109214
|
dryRun: false,
|
|
108962
109215
|
prefix: false,
|
|
108963
109216
|
sync: false,
|
|
@@ -109587,7 +109840,7 @@ init_dist2();
|
|
|
109587
109840
|
init_model_taxonomy();
|
|
109588
109841
|
import { mkdir as mkdir39, readFile as readFile64, writeFile as writeFile37 } from "node:fs/promises";
|
|
109589
109842
|
import { homedir as homedir52 } from "node:os";
|
|
109590
|
-
import { dirname as
|
|
109843
|
+
import { dirname as dirname44, join as join142 } from "node:path";
|
|
109591
109844
|
|
|
109592
109845
|
// src/commands/portable/models-dev-cache.ts
|
|
109593
109846
|
init_logger();
|
|
@@ -109940,7 +110193,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
109940
110193
|
}
|
|
109941
110194
|
const chosenModel2 = response2.action === "custom" ? response2.value : suggestion2.model;
|
|
109942
110195
|
const next2 = { ...existing, model: chosenModel2 };
|
|
109943
|
-
await mkdir39(
|
|
110196
|
+
await mkdir39(dirname44(configPath), { recursive: true });
|
|
109944
110197
|
await writeFile37(configPath, `${JSON.stringify(next2, null, 2)}
|
|
109945
110198
|
`, "utf-8");
|
|
109946
110199
|
return { path: configPath, action: "added", model: chosenModel2, reason: suggestion2.reason };
|
|
@@ -109951,7 +110204,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
109951
110204
|
throw new OpenCodeAuthRequiredError(suggestion.failure);
|
|
109952
110205
|
}
|
|
109953
110206
|
const next2 = { ...existing ?? {}, model: suggestion.model };
|
|
109954
|
-
await mkdir39(
|
|
110207
|
+
await mkdir39(dirname44(configPath), { recursive: true });
|
|
109955
110208
|
await writeFile37(configPath, `${JSON.stringify(next2, null, 2)}
|
|
109956
110209
|
`, "utf-8");
|
|
109957
110210
|
return {
|
|
@@ -109973,7 +110226,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
109973
110226
|
}
|
|
109974
110227
|
const chosenModel = response.action === "custom" ? response.value : suggestion.ok ? suggestion.model : "";
|
|
109975
110228
|
const next = { ...existing ?? {}, model: chosenModel };
|
|
109976
|
-
await mkdir39(
|
|
110229
|
+
await mkdir39(dirname44(configPath), { recursive: true });
|
|
109977
110230
|
await writeFile37(configPath, `${JSON.stringify(next, null, 2)}
|
|
109978
110231
|
`, "utf-8");
|
|
109979
110232
|
return {
|
|
@@ -109986,7 +110239,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
109986
110239
|
|
|
109987
110240
|
// src/commands/portable/plan-display.ts
|
|
109988
110241
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
109989
|
-
import { basename as basename29, dirname as
|
|
110242
|
+
import { basename as basename29, dirname as dirname45, extname as extname8 } from "node:path";
|
|
109990
110243
|
var DEFAULT_MAX_PLAN_GROUP_ITEMS = 20;
|
|
109991
110244
|
var TYPE_ORDER = [
|
|
109992
110245
|
"agent",
|
|
@@ -110212,21 +110465,21 @@ function collectPlannedWhereLines(plan) {
|
|
|
110212
110465
|
return destinations.map((destination) => `${formatDisplayPath(destination)} -> ${formatCdHint(resolveCdTarget(destination))}`);
|
|
110213
110466
|
}
|
|
110214
110467
|
function resolveCdTarget(destination) {
|
|
110215
|
-
return extname8(destination).length > 0 ?
|
|
110468
|
+
return extname8(destination).length > 0 ? dirname45(destination) : destination;
|
|
110216
110469
|
}
|
|
110217
110470
|
function normalizeWhereDestination(path17, portableType) {
|
|
110218
110471
|
if (portableType === "agent" || portableType === "command" || portableType === "skill") {
|
|
110219
|
-
return
|
|
110472
|
+
return dirname45(path17);
|
|
110220
110473
|
}
|
|
110221
110474
|
if (portableType === "hooks") {
|
|
110222
|
-
return
|
|
110475
|
+
return dirname45(path17);
|
|
110223
110476
|
}
|
|
110224
110477
|
if (portableType === "rules") {
|
|
110225
110478
|
const fileName = basename29(path17).toLowerCase();
|
|
110226
110479
|
if (fileName === "agents.md" || fileName === "gemini.md" || fileName === ".goosehints" || fileName === "custom_modes.yaml" || fileName === "custom_modes.yml") {
|
|
110227
110480
|
return path17;
|
|
110228
110481
|
}
|
|
110229
|
-
return
|
|
110482
|
+
return dirname45(path17);
|
|
110230
110483
|
}
|
|
110231
110484
|
return path17;
|
|
110232
110485
|
}
|
|
@@ -111980,7 +112233,7 @@ Please use only one download method.`);
|
|
|
111980
112233
|
// src/commands/plan/plan-command.ts
|
|
111981
112234
|
init_output_manager();
|
|
111982
112235
|
import { existsSync as existsSync71, statSync as statSync12 } from "node:fs";
|
|
111983
|
-
import { dirname as
|
|
112236
|
+
import { dirname as dirname49, isAbsolute as isAbsolute14, join as join148, parse as parse7, resolve as resolve55 } from "node:path";
|
|
111984
112237
|
|
|
111985
112238
|
// src/commands/plan/plan-read-handlers.ts
|
|
111986
112239
|
init_config();
|
|
@@ -111990,18 +112243,18 @@ init_logger();
|
|
|
111990
112243
|
init_output_manager();
|
|
111991
112244
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
111992
112245
|
import { existsSync as existsSync70, statSync as statSync11 } from "node:fs";
|
|
111993
|
-
import { basename as basename31, dirname as
|
|
112246
|
+
import { basename as basename31, dirname as dirname47, join as join147, relative as relative31, resolve as resolve53 } from "node:path";
|
|
111994
112247
|
|
|
111995
112248
|
// src/commands/plan/plan-dependencies.ts
|
|
111996
112249
|
init_config();
|
|
111997
112250
|
init_plan_parser();
|
|
111998
112251
|
init_plans_registry();
|
|
111999
112252
|
import { existsSync as existsSync69 } from "node:fs";
|
|
112000
|
-
import { dirname as
|
|
112253
|
+
import { dirname as dirname46, join as join146 } from "node:path";
|
|
112001
112254
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
112002
112255
|
if (references.length === 0)
|
|
112003
112256
|
return [];
|
|
112004
|
-
const currentPlanDir =
|
|
112257
|
+
const currentPlanDir = dirname46(currentPlanFile);
|
|
112005
112258
|
const projectRoot = findProjectRoot(currentPlanDir);
|
|
112006
112259
|
const config = options2.preloadedConfig ?? (await CkConfigManager.loadFull(projectRoot)).config;
|
|
112007
112260
|
const defaultScope = inferPlanScopeForDir(currentPlanDir, config);
|
|
@@ -112088,7 +112341,7 @@ async function handleParse(target, options2) {
|
|
|
112088
112341
|
console.log(JSON.stringify({ file: relative31(process.cwd(), planFile), frontmatter, phases }, null, 2));
|
|
112089
112342
|
return;
|
|
112090
112343
|
}
|
|
112091
|
-
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename31(
|
|
112344
|
+
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename31(dirname47(planFile));
|
|
112092
112345
|
console.log();
|
|
112093
112346
|
console.log(import_picocolors32.default.bold(` Plan: ${title}`));
|
|
112094
112347
|
console.log(` File: ${planFile}`);
|
|
@@ -112199,7 +112452,7 @@ async function handleStatus(target, options2) {
|
|
|
112199
112452
|
const blockedBy2 = await resolvePlanDependencies(s.blockedBy, pf, { preloadedConfig });
|
|
112200
112453
|
const blocks2 = await resolvePlanDependencies(s.blocks, pf, { preloadedConfig });
|
|
112201
112454
|
const bar = progressBar(s.completed, s.totalPhases);
|
|
112202
|
-
const title2 = s.title ?? basename31(
|
|
112455
|
+
const title2 = s.title ?? basename31(dirname47(pf));
|
|
112203
112456
|
console.log(` ${import_picocolors32.default.bold(title2)}`);
|
|
112204
112457
|
console.log(` ${bar}`);
|
|
112205
112458
|
if (s.inProgress > 0)
|
|
@@ -112218,7 +112471,7 @@ async function handleStatus(target, options2) {
|
|
|
112218
112471
|
}
|
|
112219
112472
|
console.log();
|
|
112220
112473
|
} catch {
|
|
112221
|
-
console.log(` [X] Failed to read: ${basename31(
|
|
112474
|
+
console.log(` [X] Failed to read: ${basename31(dirname47(pf))}`);
|
|
112222
112475
|
console.log();
|
|
112223
112476
|
}
|
|
112224
112477
|
}
|
|
@@ -112245,7 +112498,7 @@ async function handleStatus(target, options2) {
|
|
|
112245
112498
|
console.log(JSON.stringify({ ...summary, dependencyStatus: { blockedBy, blocks } }, null, 2));
|
|
112246
112499
|
return;
|
|
112247
112500
|
}
|
|
112248
|
-
const title = summary.title ?? basename31(
|
|
112501
|
+
const title = summary.title ?? basename31(dirname47(planFile));
|
|
112249
112502
|
console.log();
|
|
112250
112503
|
console.log(import_picocolors32.default.bold(` ${title}`));
|
|
112251
112504
|
if (summary.status)
|
|
@@ -112308,7 +112561,7 @@ async function handleKanban(target, options2) {
|
|
|
112308
112561
|
process.exitCode = 1;
|
|
112309
112562
|
return;
|
|
112310
112563
|
}
|
|
112311
|
-
const route = `/plans?dir=${encodeURIComponent(
|
|
112564
|
+
const route = `/plans?dir=${encodeURIComponent(dirname47(dirname47(planFile)))}&view=kanban`;
|
|
112312
112565
|
const url = `http://localhost:${server.port}${route}`;
|
|
112313
112566
|
console.log();
|
|
112314
112567
|
console.log(import_picocolors32.default.bold(" ClaudeKit Dashboard — Plans"));
|
|
@@ -112343,7 +112596,7 @@ init_plan_parser();
|
|
|
112343
112596
|
init_plans_registry();
|
|
112344
112597
|
init_output_manager();
|
|
112345
112598
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
112346
|
-
import { basename as basename32, dirname as
|
|
112599
|
+
import { basename as basename32, dirname as dirname48, relative as relative32, resolve as resolve54 } from "node:path";
|
|
112347
112600
|
function quoteReadTarget(filePath) {
|
|
112348
112601
|
return `"${filePath.replace(/\\/g, "/").replace(/"/g, "\\\"")}"`;
|
|
112349
112602
|
}
|
|
@@ -112457,7 +112710,7 @@ async function handleCheck(target, options2) {
|
|
|
112457
112710
|
process.exitCode = 1;
|
|
112458
112711
|
return;
|
|
112459
112712
|
}
|
|
112460
|
-
const planDir =
|
|
112713
|
+
const planDir = dirname48(planFile);
|
|
112461
112714
|
let planStatus = "pending";
|
|
112462
112715
|
try {
|
|
112463
112716
|
const projectRoot = findProjectRoot(planDir);
|
|
@@ -112506,7 +112759,7 @@ async function handleUncheck(target, options2) {
|
|
|
112506
112759
|
process.exitCode = 1;
|
|
112507
112760
|
return;
|
|
112508
112761
|
}
|
|
112509
|
-
const planDir =
|
|
112762
|
+
const planDir = dirname48(planFile);
|
|
112510
112763
|
try {
|
|
112511
112764
|
const projectRoot = findProjectRoot(planDir);
|
|
112512
112765
|
const summary = buildPlanSummary(planFile);
|
|
@@ -112545,7 +112798,7 @@ async function handleAddPhase(target, options2) {
|
|
|
112545
112798
|
try {
|
|
112546
112799
|
const result = addPhase(planFile, target, options2.after);
|
|
112547
112800
|
try {
|
|
112548
|
-
const planDir =
|
|
112801
|
+
const planDir = dirname48(planFile);
|
|
112549
112802
|
const projectRoot = findProjectRoot(planDir);
|
|
112550
112803
|
updateRegistryAddPhase({
|
|
112551
112804
|
planDir,
|
|
@@ -112599,7 +112852,7 @@ function resolvePlanFile(target, baseDir) {
|
|
|
112599
112852
|
const candidate = join148(dir, "plan.md");
|
|
112600
112853
|
if (existsSync71(candidate))
|
|
112601
112854
|
return candidate;
|
|
112602
|
-
dir =
|
|
112855
|
+
dir = dirname49(dir);
|
|
112603
112856
|
}
|
|
112604
112857
|
}
|
|
112605
112858
|
return null;
|
|
@@ -113051,6 +113304,7 @@ async function handleKitSelection(ctx) {
|
|
|
113051
113304
|
dryRun: false,
|
|
113052
113305
|
forceOverwrite: false,
|
|
113053
113306
|
forceOverwriteSettings: false,
|
|
113307
|
+
restoreCkHooks: false,
|
|
113054
113308
|
skipSetup: true,
|
|
113055
113309
|
refresh: false,
|
|
113056
113310
|
sync: false,
|
|
@@ -113883,7 +114137,7 @@ var import_fs_extra42 = __toESM(require_lib(), 1);
|
|
|
113883
114137
|
// src/commands/uninstall/analysis-handler.ts
|
|
113884
114138
|
init_metadata_migration();
|
|
113885
114139
|
import { readdirSync as readdirSync11, rmSync as rmSync4 } from "node:fs";
|
|
113886
|
-
import { dirname as
|
|
114140
|
+
import { dirname as dirname50, join as join151 } from "node:path";
|
|
113887
114141
|
init_logger();
|
|
113888
114142
|
init_safe_prompts();
|
|
113889
114143
|
var import_fs_extra41 = __toESM(require_lib(), 1);
|
|
@@ -113905,7 +114159,7 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
|
113905
114159
|
}
|
|
113906
114160
|
async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
113907
114161
|
let cleaned = 0;
|
|
113908
|
-
let currentDir =
|
|
114162
|
+
let currentDir = dirname50(filePath);
|
|
113909
114163
|
while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
|
|
113910
114164
|
try {
|
|
113911
114165
|
const entries = readdirSync11(currentDir);
|
|
@@ -113913,7 +114167,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
|
113913
114167
|
rmSync4(currentDir, { recursive: true });
|
|
113914
114168
|
cleaned++;
|
|
113915
114169
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
113916
|
-
currentDir =
|
|
114170
|
+
currentDir = dirname50(currentDir);
|
|
113917
114171
|
} else {
|
|
113918
114172
|
break;
|
|
113919
114173
|
}
|
|
@@ -115835,7 +116089,7 @@ init_file_io();
|
|
|
115835
116089
|
init_logger();
|
|
115836
116090
|
import { existsSync as existsSync74 } from "node:fs";
|
|
115837
116091
|
import { mkdir as mkdir41, readFile as readFile68 } from "node:fs/promises";
|
|
115838
|
-
import { dirname as
|
|
116092
|
+
import { dirname as dirname51 } from "node:path";
|
|
115839
116093
|
var PROCESSED_ISSUES_CAP = 500;
|
|
115840
116094
|
async function readCkJson(projectDir) {
|
|
115841
116095
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
@@ -115865,7 +116119,7 @@ async function loadWatchState(projectDir) {
|
|
|
115865
116119
|
}
|
|
115866
116120
|
async function saveWatchState(projectDir, state) {
|
|
115867
116121
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
115868
|
-
const configDir =
|
|
116122
|
+
const configDir = dirname51(configPath);
|
|
115869
116123
|
if (!existsSync74(configDir)) {
|
|
115870
116124
|
await mkdir41(configDir, { recursive: true });
|
|
115871
116125
|
}
|
|
@@ -116405,7 +116659,7 @@ function registerCommands(cli) {
|
|
|
116405
116659
|
}
|
|
116406
116660
|
await newCommand(options2);
|
|
116407
116661
|
});
|
|
116408
|
-
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("--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) => {
|
|
116662
|
+
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) => {
|
|
116409
116663
|
if (options2.exclude && !Array.isArray(options2.exclude)) {
|
|
116410
116664
|
options2.exclude = [options2.exclude];
|
|
116411
116665
|
}
|