claudekit-cli 3.34.1-dev.5 → 3.34.1

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
@@ -29190,10 +29190,8 @@ var init_ck_config = __esm(() => {
29190
29190
  CkHooksConfigSchema = exports_external.object({
29191
29191
  "session-init": exports_external.boolean().optional(),
29192
29192
  "subagent-init": exports_external.boolean().optional(),
29193
- "descriptive-name": exports_external.boolean().optional(),
29194
29193
  "dev-rules-reminder": exports_external.boolean().optional(),
29195
29194
  "usage-context-awareness": exports_external.boolean().optional(),
29196
- "context-tracking": exports_external.boolean().optional(),
29197
29195
  "scout-block": exports_external.boolean().optional(),
29198
29196
  "privacy-block": exports_external.boolean().optional(),
29199
29197
  "post-edit-simplify-reminder": exports_external.boolean().optional()
@@ -29266,10 +29264,8 @@ var init_ck_config = __esm(() => {
29266
29264
  hooks: {
29267
29265
  "session-init": true,
29268
29266
  "subagent-init": true,
29269
- "descriptive-name": true,
29270
29267
  "dev-rules-reminder": true,
29271
29268
  "usage-context-awareness": true,
29272
- "context-tracking": true,
29273
29269
  "scout-block": true,
29274
29270
  "privacy-block": true,
29275
29271
  "post-edit-simplify-reminder": true
@@ -29278,10 +29274,8 @@ var init_ck_config = __esm(() => {
29278
29274
  CK_HOOK_NAMES = [
29279
29275
  "session-init",
29280
29276
  "subagent-init",
29281
- "descriptive-name",
29282
29277
  "dev-rules-reminder",
29283
29278
  "usage-context-awareness",
29284
- "context-tracking",
29285
29279
  "scout-block",
29286
29280
  "privacy-block",
29287
29281
  "post-edit-simplify-reminder"
@@ -29562,9 +29556,6 @@ function getNestedValue(obj, path2) {
29562
29556
  }
29563
29557
  function setNestedValue(obj, path2, value) {
29564
29558
  const keys = path2.split(".");
29565
- if (keys.some((k) => DANGEROUS_KEYS.includes(k))) {
29566
- throw new Error("Invalid field path: dangerous key detected");
29567
- }
29568
29559
  let current = obj;
29569
29560
  for (let i = 0;i < keys.length - 1; i++) {
29570
29561
  const key = keys[i];
@@ -29578,8 +29569,6 @@ function setNestedValue(obj, path2, value) {
29578
29569
  function deepMerge(target, source) {
29579
29570
  const result = { ...target };
29580
29571
  for (const key of Object.keys(source)) {
29581
- if (DANGEROUS_KEYS.includes(key))
29582
- continue;
29583
29572
  const sourceVal = source[key];
29584
29573
  const targetVal = result[key];
29585
29574
  if (sourceVal !== null && typeof sourceVal === "object" && !Array.isArray(sourceVal) && targetVal !== null && typeof targetVal === "object" && !Array.isArray(targetVal)) {
@@ -29718,10 +29707,6 @@ class CkConfigManager {
29718
29707
  return null;
29719
29708
  return CkConfigManager.loadConfigFile(CkConfigManager.getProjectConfigPath(projectDir));
29720
29709
  }
29721
- static projectConfigExists(dir, isGlobal) {
29722
- const configPath = isGlobal ? join3(dir, ".ck.json") : CkConfigManager.getProjectConfigPath(dir);
29723
- return existsSync3(configPath);
29724
- }
29725
29710
  static configExists(scope, projectDir) {
29726
29711
  if (scope === "global") {
29727
29712
  return existsSync3(CkConfigManager.getGlobalConfigPath());
@@ -29742,11 +29727,10 @@ class CkConfigManager {
29742
29727
  await CkConfigManager.saveFull(existing, scope, projectDir);
29743
29728
  }
29744
29729
  }
29745
- var CK_CONFIG_FILE = ".ck.json", DANGEROUS_KEYS;
29730
+ var CK_CONFIG_FILE = ".ck.json";
29746
29731
  var init_ck_config_manager = __esm(() => {
29747
29732
  init_logger();
29748
29733
  init_types2();
29749
- DANGEROUS_KEYS = ["__proto__", "constructor", "prototype"];
29750
29734
  });
29751
29735
 
29752
29736
  // src/shared/environment.ts
@@ -38125,12 +38109,17 @@ class FileWatcher {
38125
38109
  if (this.isConfigFile(path2)) {
38126
38110
  try {
38127
38111
  const scope = this.getConfigScope(path2);
38128
- const ckScope = scope === "global" ? "global" : "project";
38129
- const projectDir = scope === "global" ? null : process.cwd();
38130
- const config = await CkConfigManager.loadScope(ckScope, projectDir);
38112
+ let config;
38113
+ if (scope === "global") {
38114
+ ConfigManager.setGlobalFlag(true);
38115
+ config = await ConfigManager.load();
38116
+ } else {
38117
+ const projectConfig = await ConfigManager.loadProjectConfig(process.cwd(), false);
38118
+ config = projectConfig ? { paths: projectConfig } : {};
38119
+ }
38131
38120
  this.wsManager.broadcast({
38132
38121
  type: "config:updated",
38133
- payload: { scope, config: config ?? {} }
38122
+ payload: { scope, config }
38134
38123
  });
38135
38124
  } catch (error) {
38136
38125
  logger.error(`Failed to reload config: ${error}`);
@@ -38888,9 +38877,6 @@ var init_projects_registry = __esm(() => {
38888
38877
  });
38889
38878
 
38890
38879
  // src/domains/web-server/routes/ck-config-routes.ts
38891
- import { existsSync as existsSync6 } from "node:fs";
38892
- import { readFile as readFile5 } from "node:fs/promises";
38893
- import { join as join9 } from "node:path";
38894
38880
  async function resolveProjectDir(projectId) {
38895
38881
  if (!projectId)
38896
38882
  return null;
@@ -39013,6 +38999,92 @@ function registerCkConfigRoutes(app) {
39013
38999
  res.status(500).json({ error: "Failed to update field" });
39014
39000
  }
39015
39001
  });
39002
+ }
39003
+ var init_ck_config_routes = __esm(() => {
39004
+ init_config();
39005
+ init_ck_config_schema();
39006
+ init_logger();
39007
+ init_types2();
39008
+ });
39009
+
39010
+ // src/domains/web-server/routes/config-routes.ts
39011
+ import { existsSync as existsSync6 } from "node:fs";
39012
+ import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile6 } from "node:fs/promises";
39013
+ import { join as join9 } from "node:path";
39014
+ function registerConfigRoutes(app) {
39015
+ app.get("/api/config", async (_req, res) => {
39016
+ try {
39017
+ const projectDir = process.cwd();
39018
+ const globalConfigPath = getEngineerKitConfigPath();
39019
+ let globalConfig = {};
39020
+ if (existsSync6(globalConfigPath)) {
39021
+ const content = await readFile5(globalConfigPath, "utf-8");
39022
+ try {
39023
+ globalConfig = JSON.parse(content);
39024
+ } catch {}
39025
+ }
39026
+ const localConfig = await ConfigManager.loadProjectConfig(projectDir, false);
39027
+ const merged = deepMerge2(globalConfig, localConfig ? { paths: localConfig } : {});
39028
+ const response = {
39029
+ global: globalConfig,
39030
+ local: localConfig ? { paths: localConfig } : null,
39031
+ merged
39032
+ };
39033
+ res.json(response);
39034
+ } catch (error) {
39035
+ logger.error(`Failed to load config: ${error}`);
39036
+ res.status(500).json({ error: "Failed to load configuration" });
39037
+ }
39038
+ });
39039
+ app.get("/api/config/global", async (_req, res) => {
39040
+ try {
39041
+ const globalConfigPath = getEngineerKitConfigPath();
39042
+ let config = {};
39043
+ if (existsSync6(globalConfigPath)) {
39044
+ const content = await readFile5(globalConfigPath, "utf-8");
39045
+ try {
39046
+ config = JSON.parse(content);
39047
+ } catch {}
39048
+ }
39049
+ res.json(config);
39050
+ } catch (error) {
39051
+ res.status(500).json({ error: "Failed to load global config" });
39052
+ }
39053
+ });
39054
+ app.get("/api/config/local", async (_req, res) => {
39055
+ try {
39056
+ const projectDir = process.cwd();
39057
+ const config = await ConfigManager.loadProjectConfig(projectDir, false);
39058
+ res.json(config ? { paths: config } : {});
39059
+ } catch (error) {
39060
+ res.status(500).json({ error: "Failed to load local config" });
39061
+ }
39062
+ });
39063
+ app.post("/api/config", async (req, res) => {
39064
+ try {
39065
+ const { scope = "local", config } = req.body;
39066
+ if (!config || typeof config !== "object") {
39067
+ res.status(400).json({ error: "Invalid config payload" });
39068
+ return;
39069
+ }
39070
+ if (scope === "global") {
39071
+ const globalConfigPath = getEngineerKitConfigPath();
39072
+ const globalDir = PathResolver.getGlobalKitDir();
39073
+ if (!existsSync6(globalDir)) {
39074
+ await mkdir4(globalDir, { recursive: true });
39075
+ }
39076
+ await writeFile6(globalConfigPath, JSON.stringify(config, null, 2), "utf-8");
39077
+ logger.debug(`Engineer kit config saved to ${globalConfigPath}`);
39078
+ } else {
39079
+ const projectDir = process.cwd();
39080
+ await ConfigManager.saveProjectConfig(projectDir, config.paths || config, false);
39081
+ }
39082
+ res.json({ success: true, scope });
39083
+ } catch (error) {
39084
+ logger.error(`Failed to save config: ${error}`);
39085
+ res.status(500).json({ error: "Failed to save configuration" });
39086
+ }
39087
+ });
39016
39088
  app.get("/api/metadata/global", async (_req, res) => {
39017
39089
  try {
39018
39090
  const metadataPath = join9(PathResolver.getGlobalKitDir(), "metadata.json");
@@ -39021,9 +39093,7 @@ function registerCkConfigRoutes(app) {
39021
39093
  const content = await readFile5(metadataPath, "utf-8");
39022
39094
  try {
39023
39095
  metadata = JSON.parse(content);
39024
- } catch (err) {
39025
- logger.warning(`Invalid JSON in metadata.json: ${err}`);
39026
- }
39096
+ } catch {}
39027
39097
  }
39028
39098
  res.json(metadata);
39029
39099
  } catch (error) {
@@ -39031,13 +39101,92 @@ function registerCkConfigRoutes(app) {
39031
39101
  res.status(500).json({ error: "Failed to load metadata" });
39032
39102
  }
39033
39103
  });
39104
+ app.get("/api/config/project/:id", async (req, res) => {
39105
+ try {
39106
+ const id = String(req.params.id);
39107
+ let projectDir;
39108
+ if (id.startsWith("discovered-")) {
39109
+ const encodedPath = id.slice("discovered-".length);
39110
+ projectDir = Buffer.from(encodedPath, "base64url").toString("utf-8");
39111
+ } else {
39112
+ const { ProjectsRegistryManager: ProjectsRegistryManager2 } = await Promise.resolve().then(() => (init_projects_registry(), exports_projects_registry));
39113
+ const project = await ProjectsRegistryManager2.getProject(id);
39114
+ if (!project) {
39115
+ res.status(404).json({ error: "Project not found" });
39116
+ return;
39117
+ }
39118
+ projectDir = project.path;
39119
+ }
39120
+ const globalConfigPath = getEngineerKitConfigPath();
39121
+ let globalConfig = {};
39122
+ if (existsSync6(globalConfigPath)) {
39123
+ const content = await readFile5(globalConfigPath, "utf-8");
39124
+ try {
39125
+ globalConfig = JSON.parse(content);
39126
+ } catch {}
39127
+ }
39128
+ const localConfig = await ConfigManager.loadProjectConfig(projectDir, false);
39129
+ const merged = deepMerge2(globalConfig, localConfig ? { paths: localConfig } : {});
39130
+ const response = {
39131
+ global: globalConfig,
39132
+ local: localConfig ? { paths: localConfig } : null,
39133
+ merged
39134
+ };
39135
+ res.json(response);
39136
+ } catch (error) {
39137
+ logger.error(`Failed to load project config: ${error}`);
39138
+ res.status(500).json({ error: "Failed to load project configuration" });
39139
+ }
39140
+ });
39141
+ app.post("/api/config/project/:id", async (req, res) => {
39142
+ try {
39143
+ const id = String(req.params.id);
39144
+ const { config } = req.body;
39145
+ if (!config || typeof config !== "object") {
39146
+ res.status(400).json({ error: "Invalid config payload" });
39147
+ return;
39148
+ }
39149
+ let projectDir;
39150
+ if (id.startsWith("discovered-")) {
39151
+ const encodedPath = id.slice("discovered-".length);
39152
+ projectDir = Buffer.from(encodedPath, "base64url").toString("utf-8");
39153
+ } else {
39154
+ const { ProjectsRegistryManager: ProjectsRegistryManager2 } = await Promise.resolve().then(() => (init_projects_registry(), exports_projects_registry));
39155
+ const project = await ProjectsRegistryManager2.getProject(id);
39156
+ if (!project) {
39157
+ res.status(404).json({ error: "Project not found" });
39158
+ return;
39159
+ }
39160
+ projectDir = project.path;
39161
+ }
39162
+ await ConfigManager.saveProjectConfig(projectDir, config.paths || config, false);
39163
+ res.json({ success: true });
39164
+ } catch (error) {
39165
+ logger.error(`Failed to save project config: ${error}`);
39166
+ res.status(500).json({ error: "Failed to save project configuration" });
39167
+ }
39168
+ });
39034
39169
  }
39035
- var init_ck_config_routes = __esm(() => {
39170
+ function deepMerge2(target, source) {
39171
+ const result = { ...target };
39172
+ const dangerousKeys = ["__proto__", "constructor", "prototype"];
39173
+ for (const key of Object.keys(source)) {
39174
+ if (dangerousKeys.includes(key))
39175
+ continue;
39176
+ const sourceVal = source[key];
39177
+ if (sourceVal && typeof sourceVal === "object" && !Array.isArray(sourceVal)) {
39178
+ result[key] = deepMerge2(result[key] || {}, sourceVal);
39179
+ } else {
39180
+ result[key] = sourceVal;
39181
+ }
39182
+ }
39183
+ return result;
39184
+ }
39185
+ var getEngineerKitConfigPath = () => join9(PathResolver.getGlobalKitDir(), ".ck.json");
39186
+ var init_config_routes = __esm(() => {
39036
39187
  init_config();
39037
- init_ck_config_schema();
39038
39188
  init_logger();
39039
39189
  init_path_resolver();
39040
- init_types2();
39041
39190
  });
39042
39191
 
39043
39192
  // src/domains/web-server/routes/health-routes.ts
@@ -43459,7 +43608,7 @@ async function buildProjectInfoFromRegistry(registered) {
43459
43608
  } catch {}
43460
43609
  }
43461
43610
  } catch {}
43462
- const hasLocalConfig = hasClaudeDir && CkConfigManager.projectConfigExists(registered.path, false);
43611
+ const hasLocalConfig = hasClaudeDir && ConfigManager.projectConfigExists(registered.path, false);
43463
43612
  const settings = await readSettings();
43464
43613
  const skills = await scanSkills();
43465
43614
  const settingsPath = join17(homedir10(), ".claude", "settings.json");
@@ -43500,7 +43649,7 @@ async function detectAndBuildProjectInfo(path2, id) {
43500
43649
  } catch {}
43501
43650
  }
43502
43651
  } catch {}
43503
- const hasLocalConfig = CkConfigManager.projectConfigExists(path2, id === "global");
43652
+ const hasLocalConfig = ConfigManager.projectConfigExists(path2, id === "global");
43504
43653
  const settings = await readSettings();
43505
43654
  const skills = await scanSkills();
43506
43655
  const settingsPath = join17(homedir10(), ".claude", "settings.json");
@@ -43849,7 +43998,7 @@ var init_skills_discovery = __esm(() => {
43849
43998
 
43850
43999
  // src/commands/skills/skills-registry.ts
43851
44000
  import { existsSync as existsSync14 } from "node:fs";
43852
- import { mkdir as mkdir4, readFile as readFile12, writeFile as writeFile6 } from "node:fs/promises";
44001
+ import { mkdir as mkdir5, readFile as readFile12, writeFile as writeFile7 } from "node:fs/promises";
43853
44002
  import { homedir as homedir14 } from "node:os";
43854
44003
  import { dirname as dirname6, join as join21 } from "node:path";
43855
44004
  function getCliVersion() {
@@ -43886,9 +44035,9 @@ async function readRegistry() {
43886
44035
  async function writeRegistry(registry) {
43887
44036
  const dir = dirname6(REGISTRY_PATH);
43888
44037
  if (!existsSync14(dir)) {
43889
- await mkdir4(dir, { recursive: true });
44038
+ await mkdir5(dir, { recursive: true });
43890
44039
  }
43891
- await writeFile6(REGISTRY_PATH, JSON.stringify(registry, null, 2), "utf-8");
44040
+ await writeFile7(REGISTRY_PATH, JSON.stringify(registry, null, 2), "utf-8");
43892
44041
  }
43893
44042
  async function addInstallation(skill, agent, global3, path2, sourcePath) {
43894
44043
  const registry = await readRegistry();
@@ -43962,7 +44111,7 @@ var init_skills_registry = __esm(() => {
43962
44111
 
43963
44112
  // src/commands/skills/skills-installer.ts
43964
44113
  import { existsSync as existsSync15 } from "node:fs";
43965
- import { cp, mkdir as mkdir5, stat as stat7 } from "node:fs/promises";
44114
+ import { cp, mkdir as mkdir6, stat as stat7 } from "node:fs/promises";
43966
44115
  import { dirname as dirname7, resolve as resolve6 } from "node:path";
43967
44116
  function isSamePath(path1, path2) {
43968
44117
  try {
@@ -44007,7 +44156,7 @@ async function installSkillForAgent(skill, agent, options2) {
44007
44156
  try {
44008
44157
  const parentDir = dirname7(targetPath);
44009
44158
  if (!existsSync15(parentDir)) {
44010
- await mkdir5(parentDir, { recursive: true });
44159
+ await mkdir6(parentDir, { recursive: true });
44011
44160
  }
44012
44161
  if (existsSync15(targetPath)) {
44013
44162
  const stats = await stat7(targetPath);
@@ -44585,38 +44734,10 @@ var init_pnpm_detector = __esm(() => {
44585
44734
  });
44586
44735
 
44587
44736
  // src/domains/installation/package-managers/detection-core.ts
44588
- import { existsSync as existsSync17, realpathSync } from "node:fs";
44589
- import { chmod as chmod2, mkdir as mkdir6, readFile as readFile13, writeFile as writeFile7 } from "node:fs/promises";
44737
+ import { existsSync as existsSync17 } from "node:fs";
44738
+ import { chmod as chmod2, mkdir as mkdir7, readFile as readFile13, writeFile as writeFile8 } from "node:fs/promises";
44590
44739
  import { platform as platform4 } from "node:os";
44591
- import { join as join23, sep } from "node:path";
44592
- function detectFromBinaryPath() {
44593
- try {
44594
- const scriptPath = process.argv[1];
44595
- if (!scriptPath)
44596
- return "unknown";
44597
- let resolvedPath;
44598
- try {
44599
- resolvedPath = realpathSync(scriptPath);
44600
- } catch {
44601
- resolvedPath = scriptPath;
44602
- }
44603
- const normalized = resolvedPath.split(sep).join("/").toLowerCase();
44604
- logger.verbose(`Binary path resolved: ${normalized}`);
44605
- if (normalized.includes("/.bun/install/") || normalized.includes("/bun/install/global/")) {
44606
- return "bun";
44607
- }
44608
- if (normalized.includes("/pnpm/global/") || normalized.includes("/.local/share/pnpm/")) {
44609
- return "pnpm";
44610
- }
44611
- if (normalized.includes("/yarn/global/") || normalized.includes("/.config/yarn/")) {
44612
- return "yarn";
44613
- }
44614
- if (normalized.includes("/npm/node_modules/") || normalized.includes("/usr/local/lib/node_modules/") || normalized.includes("/usr/lib/node_modules/") || normalized.includes("/opt/homebrew/lib/node_modules/") || normalized.includes("/.nvm/versions/node/") || normalized.includes("/n/versions/node/") || normalized.includes("/appdata/roaming/npm/")) {
44615
- return "npm";
44616
- }
44617
- } catch {}
44618
- return "unknown";
44619
- }
44740
+ import { join as join23 } from "node:path";
44620
44741
  function detectFromEnv() {
44621
44742
  const userAgent = process.env.npm_config_user_agent;
44622
44743
  if (userAgent) {
@@ -44633,14 +44754,13 @@ function detectFromEnv() {
44633
44754
  const execPath = process.env.npm_execpath;
44634
44755
  if (execPath) {
44635
44756
  logger.debug(`Detected exec path: ${execPath}`);
44636
- const normalizedExec = execPath.replace(/\\/g, "/").toLowerCase();
44637
- if (/\/bun([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("bun"))
44757
+ if (execPath.includes("bun"))
44638
44758
  return "bun";
44639
- if (/\/yarn([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("yarn"))
44759
+ if (execPath.includes("yarn"))
44640
44760
  return "yarn";
44641
- if (/\/pnpm([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("pnpm"))
44761
+ if (execPath.includes("pnpm"))
44642
44762
  return "pnpm";
44643
- if (/\/npm([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("npm"))
44763
+ if (execPath.includes("npm"))
44644
44764
  return "npm";
44645
44765
  }
44646
44766
  return "unknown";
@@ -44658,8 +44778,8 @@ async function readCachedPm() {
44658
44778
  return null;
44659
44779
  }
44660
44780
  const age = Date.now() - data.detectedAt;
44661
- if (age < 0 || age > CACHE_TTL) {
44662
- logger.debug(age < 0 ? "Cache timestamp in future, ignoring" : "Cache expired, will re-detect");
44781
+ if (age > CACHE_TTL) {
44782
+ logger.debug("Cache expired, will re-detect");
44663
44783
  return null;
44664
44784
  }
44665
44785
  const validPms = ["npm", "bun", "yarn", "pnpm"];
@@ -44680,7 +44800,7 @@ async function saveCachedPm(pm, getVersion) {
44680
44800
  const configDir = PathResolver.getConfigDir(false);
44681
44801
  const cacheFile = join23(configDir, CACHE_FILE);
44682
44802
  if (!existsSync17(configDir)) {
44683
- await mkdir6(configDir, { recursive: true });
44803
+ await mkdir7(configDir, { recursive: true });
44684
44804
  if (platform4() !== "win32") {
44685
44805
  await chmod2(configDir, 448);
44686
44806
  }
@@ -44691,7 +44811,7 @@ async function saveCachedPm(pm, getVersion) {
44691
44811
  detectedAt: Date.now(),
44692
44812
  version: version ?? undefined
44693
44813
  };
44694
- await writeFile7(cacheFile, JSON.stringify(data, null, 2), "utf-8");
44814
+ await writeFile8(cacheFile, JSON.stringify(data, null, 2), "utf-8");
44695
44815
  if (platform4() !== "win32") {
44696
44816
  await chmod2(cacheFile, 384);
44697
44817
  }
@@ -44768,18 +44888,6 @@ var init_package_manager_detector = __esm(() => {
44768
44888
  PackageManagerDetector = class PackageManagerDetector {
44769
44889
  static async detect() {
44770
44890
  logger.verbose("PackageManagerDetector: Starting detection");
44771
- const binaryPm = detectFromBinaryPath();
44772
- if (binaryPm !== "unknown") {
44773
- logger.verbose(`PackageManagerDetector: Detected from binary path: ${binaryPm}`);
44774
- const cachedPm2 = await readCachedPm();
44775
- if (cachedPm2 && cachedPm2 !== binaryPm) {
44776
- logger.verbose(`PackageManagerDetector: Cache says ${cachedPm2}, binary says ${binaryPm} — updating cache`);
44777
- await saveCachedPm(binaryPm, PackageManagerDetector.getVersion);
44778
- } else if (!cachedPm2) {
44779
- await saveCachedPm(binaryPm, PackageManagerDetector.getVersion);
44780
- }
44781
- return binaryPm;
44782
- }
44783
44891
  const envPm = detectFromEnv();
44784
44892
  if (envPm !== "unknown") {
44785
44893
  logger.verbose(`PackageManagerDetector: Detected from env: ${envPm}`);
@@ -45277,7 +45385,7 @@ var package_default;
45277
45385
  var init_package = __esm(() => {
45278
45386
  package_default = {
45279
45387
  name: "claudekit-cli",
45280
- version: "3.34.1-dev.5",
45388
+ version: "3.34.1",
45281
45389
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
45282
45390
  type: "module",
45283
45391
  repository: {
@@ -45376,6 +45484,7 @@ var init_package = __esm(() => {
45376
45484
  "@types/tar": "^6.1.13",
45377
45485
  "@types/tmp": "^0.2.6",
45378
45486
  "@types/ws": "^8.18.1",
45487
+ "conventional-changelog-conventionalcommits": "^9.1.0",
45379
45488
  "semantic-release": "^24.2.0",
45380
45489
  typescript: "^5.7.2"
45381
45490
  }
@@ -45592,15 +45701,12 @@ Run 'ck update' to install`, "Update Check");
45592
45701
  s.stop("Update failed");
45593
45702
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
45594
45703
  if (errorMessage.includes("EACCES") || errorMessage.includes("EPERM") || errorMessage.includes("permission") || errorMessage.includes("Access is denied")) {
45595
- const permHint = pm === "npm" ? `
45704
+ throw new CliUpdateError(`Permission denied. Try: sudo ${updateCmd}
45596
45705
 
45597
- Or fix npm permissions: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally` : "";
45598
- const isWindows3 = process.platform === "win32";
45599
- const elevationHint = isWindows3 ? `Run your terminal as Administrator and retry: ${updateCmd}` : `sudo ${updateCmd}`;
45600
- throw new CliUpdateError(`Permission denied. Try: ${elevationHint}${permHint}`);
45706
+ Or fix npm permissions: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally`);
45601
45707
  }
45602
45708
  logger.error(`Update failed: ${errorMessage}`);
45603
- logger.info(`Try running: ${updateCmd}`);
45709
+ logger.info("Try running: npm install -g claudekit-cli@latest");
45604
45710
  throw new CliUpdateError(`Update failed: ${errorMessage}
45605
45711
 
45606
45712
  Manual update: ${updateCmd}`);
@@ -46094,7 +46200,7 @@ var init_error_handler2 = __esm(() => {
46094
46200
 
46095
46201
  // src/domains/versioning/release-cache.ts
46096
46202
  import { existsSync as existsSync18 } from "node:fs";
46097
- import { mkdir as mkdir7, readFile as readFile17, unlink as unlink3, writeFile as writeFile9 } from "node:fs/promises";
46203
+ import { mkdir as mkdir8, readFile as readFile17, unlink as unlink3, writeFile as writeFile10 } from "node:fs/promises";
46098
46204
  import { join as join27 } from "node:path";
46099
46205
  var ReleaseCacheEntrySchema, ReleaseCache;
46100
46206
  var init_release_cache = __esm(() => {
@@ -46140,12 +46246,12 @@ var init_release_cache = __esm(() => {
46140
46246
  async set(key, releases) {
46141
46247
  const cacheFile = this.getCachePath(key);
46142
46248
  try {
46143
- await mkdir7(this.cacheDir, { recursive: true, mode: 448 });
46249
+ await mkdir8(this.cacheDir, { recursive: true, mode: 448 });
46144
46250
  const cacheEntry = {
46145
46251
  timestamp: Date.now(),
46146
46252
  releases
46147
46253
  };
46148
- await writeFile9(cacheFile, JSON.stringify(cacheEntry, null, 2), "utf-8");
46254
+ await writeFile10(cacheFile, JSON.stringify(cacheEntry, null, 2), "utf-8");
46149
46255
  logger.debug(`Release cache set for key: ${key}, cached ${releases.length} releases`);
46150
46256
  } catch (error) {
46151
46257
  logger.debug(`Failed to set release cache for key ${key}: ${error}`);
@@ -46856,7 +46962,7 @@ var init_version_utils = __esm(() => {
46856
46962
 
46857
46963
  // src/domains/versioning/version-cache.ts
46858
46964
  import { existsSync as existsSync19 } from "node:fs";
46859
- import { mkdir as mkdir8, readFile as readFile18, writeFile as writeFile10 } from "node:fs/promises";
46965
+ import { mkdir as mkdir9, readFile as readFile18, writeFile as writeFile11 } from "node:fs/promises";
46860
46966
  import { join as join28 } from "node:path";
46861
46967
  var VersionCacheManager;
46862
46968
  var init_version_cache = __esm(() => {
@@ -46894,9 +47000,9 @@ var init_version_cache = __esm(() => {
46894
47000
  const cacheDir = PathResolver.getCacheDir(false);
46895
47001
  try {
46896
47002
  if (!existsSync19(cacheDir)) {
46897
- await mkdir8(cacheDir, { recursive: true, mode: 448 });
47003
+ await mkdir9(cacheDir, { recursive: true, mode: 448 });
46898
47004
  }
46899
- await writeFile10(cacheFile, JSON.stringify(cache3, null, 2), "utf-8");
47005
+ await writeFile11(cacheFile, JSON.stringify(cache3, null, 2), "utf-8");
46900
47006
  logger.debug(`Version check cache saved to ${cacheFile}`);
46901
47007
  } catch (error) {
46902
47008
  logger.debug(`Failed to save version check cache: ${error}`);
@@ -47476,6 +47582,7 @@ var init_user_routes = __esm(() => {
47476
47582
  function registerRoutes(app) {
47477
47583
  registerHealthRoutes(app);
47478
47584
  registerActionRoutes(app);
47585
+ registerConfigRoutes(app);
47479
47586
  registerCkConfigRoutes(app);
47480
47587
  registerProjectRoutes(app);
47481
47588
  registerSkillRoutes(app);
@@ -47487,6 +47594,7 @@ function registerRoutes(app) {
47487
47594
  var init_routes = __esm(() => {
47488
47595
  init_action_routes();
47489
47596
  init_ck_config_routes();
47597
+ init_config_routes();
47490
47598
  init_project_routes();
47491
47599
  init_session_routes();
47492
47600
  init_settings_routes();
@@ -52939,7 +53047,7 @@ var init_skills_installer2 = __esm(() => {
52939
53047
 
52940
53048
  // src/services/package-installer/gemini-mcp/config-manager.ts
52941
53049
  import { existsSync as existsSync32 } from "node:fs";
52942
- import { mkdir as mkdir12, readFile as readFile26, writeFile as writeFile15 } from "node:fs/promises";
53050
+ import { mkdir as mkdir13, readFile as readFile26, writeFile as writeFile16 } from "node:fs/promises";
52943
53051
  import { dirname as dirname11, join as join50 } from "node:path";
52944
53052
  async function readJsonFile(filePath) {
52945
53053
  try {
@@ -52970,7 +53078,7 @@ async function addGeminiToGitignore(projectDir) {
52970
53078
  `) || content === "" ? "" : `
52971
53079
  `;
52972
53080
  const comment = "# Gemini CLI settings (contains user-specific config)";
52973
- await writeFile15(gitignorePath, `${content}${newLine}${comment}
53081
+ await writeFile16(gitignorePath, `${content}${newLine}${comment}
52974
53082
  ${geminiPattern}
52975
53083
  `, "utf-8");
52976
53084
  logger.debug(`Added ${geminiPattern} to .gitignore`);
@@ -52982,7 +53090,7 @@ ${geminiPattern}
52982
53090
  async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
52983
53091
  const linkDir = dirname11(geminiSettingsPath);
52984
53092
  if (!existsSync32(linkDir)) {
52985
- await mkdir12(linkDir, { recursive: true });
53093
+ await mkdir13(linkDir, { recursive: true });
52986
53094
  logger.debug(`Created directory: ${linkDir}`);
52987
53095
  }
52988
53096
  const mcpConfig = await readJsonFile(mcpConfigPath);
@@ -52995,7 +53103,7 @@ async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
52995
53103
  }
52996
53104
  const newSettings = { mcpServers };
52997
53105
  try {
52998
- await writeFile15(geminiSettingsPath, JSON.stringify(newSettings, null, 2), "utf-8");
53106
+ await writeFile16(geminiSettingsPath, JSON.stringify(newSettings, null, 2), "utf-8");
52999
53107
  logger.debug(`Created new Gemini settings with mcpServers: ${geminiSettingsPath}`);
53000
53108
  return { success: true, method: "merge", targetPath: mcpConfigPath };
53001
53109
  } catch (error) {
@@ -53025,7 +53133,7 @@ async function mergeGeminiSettings(geminiSettingsPath, mcpConfigPath) {
53025
53133
  mcpServers
53026
53134
  };
53027
53135
  try {
53028
- await writeFile15(geminiSettingsPath, JSON.stringify(mergedSettings, null, 2), "utf-8");
53136
+ await writeFile16(geminiSettingsPath, JSON.stringify(mergedSettings, null, 2), "utf-8");
53029
53137
  logger.debug(`Merged mcpServers into: ${geminiSettingsPath}`);
53030
53138
  return { success: true, method: "merge", targetPath: mcpConfigPath };
53031
53139
  } catch (error) {
@@ -53098,12 +53206,12 @@ var init_validation = __esm(() => {
53098
53206
 
53099
53207
  // src/services/package-installer/gemini-mcp/linker-core.ts
53100
53208
  import { existsSync as existsSync34 } from "node:fs";
53101
- import { mkdir as mkdir13, symlink as symlink2 } from "node:fs/promises";
53209
+ import { mkdir as mkdir14, symlink as symlink2 } from "node:fs/promises";
53102
53210
  import { dirname as dirname12, join as join52 } from "node:path";
53103
53211
  async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
53104
53212
  const linkDir = dirname12(linkPath);
53105
53213
  if (!existsSync34(linkDir)) {
53106
- await mkdir13(linkDir, { recursive: true });
53214
+ await mkdir14(linkDir, { recursive: true });
53107
53215
  logger.debug(`Created directory: ${linkDir}`);
53108
53216
  }
53109
53217
  let symlinkTarget;
@@ -60907,7 +61015,7 @@ function checkComponentCounts(setup) {
60907
61015
  // src/domains/health-checks/checkers/permissions-checker.ts
60908
61016
  init_logger();
60909
61017
  init_path_resolver();
60910
- import { constants as constants2, access as access2, unlink as unlink4, writeFile as writeFile11 } from "node:fs/promises";
61018
+ import { constants as constants2, access as access2, unlink as unlink4, writeFile as writeFile12 } from "node:fs/promises";
60911
61019
  import { join as join34 } from "node:path";
60912
61020
 
60913
61021
  // src/domains/health-checks/checkers/shared.ts
@@ -60978,7 +61086,7 @@ async function checkGlobalDirWritable() {
60978
61086
  const random = Math.random().toString(36).substring(2);
60979
61087
  const testFile = join34(globalDir, `.ck-write-test-${timestamp}-${random}`);
60980
61088
  try {
60981
- await writeFile11(testFile, "test", { encoding: "utf-8", flag: "wx" });
61089
+ await writeFile12(testFile, "test", { encoding: "utf-8", flag: "wx" });
60982
61090
  } catch (error) {
60983
61091
  return {
60984
61092
  id: "ck-global-dir-writable",
@@ -62008,7 +62116,7 @@ import { platform as platform6 } from "node:os";
62008
62116
 
62009
62117
  // src/domains/health-checks/platform/environment-checker.ts
62010
62118
  init_path_resolver();
62011
- import { constants as constants3, access as access3, mkdir as mkdir9, readFile as readFile23, unlink as unlink5, writeFile as writeFile12 } from "node:fs/promises";
62119
+ import { constants as constants3, access as access3, mkdir as mkdir10, readFile as readFile23, unlink as unlink5, writeFile as writeFile13 } from "node:fs/promises";
62012
62120
  import { arch as arch2, homedir as homedir16, platform as platform5 } from "node:os";
62013
62121
  import { join as join42, normalize as normalize6 } from "node:path";
62014
62122
  var IS_WINDOWS = platform5() === "win32";
@@ -62106,8 +62214,8 @@ async function checkGlobalDirAccess() {
62106
62214
  }
62107
62215
  const testFile = join42(globalDir, ".ck-doctor-access-test");
62108
62216
  try {
62109
- await mkdir9(globalDir, { recursive: true });
62110
- await writeFile12(testFile, "test", "utf-8");
62217
+ await mkdir10(globalDir, { recursive: true });
62218
+ await writeFile13(testFile, "test", "utf-8");
62111
62219
  const content = await readFile23(testFile, "utf-8");
62112
62220
  await unlink5(testFile);
62113
62221
  if (content !== "test")
@@ -62181,7 +62289,7 @@ async function checkWSLBoundary() {
62181
62289
 
62182
62290
  // src/domains/health-checks/platform/windows-checker.ts
62183
62291
  init_path_resolver();
62184
- import { mkdir as mkdir10, symlink, unlink as unlink6, writeFile as writeFile13 } from "node:fs/promises";
62292
+ import { mkdir as mkdir11, symlink, unlink as unlink6, writeFile as writeFile14 } from "node:fs/promises";
62185
62293
  import { join as join43 } from "node:path";
62186
62294
  async function checkLongPathSupport() {
62187
62295
  if (shouldSkipExpensiveOperations4()) {
@@ -62237,8 +62345,8 @@ async function checkSymlinkSupport() {
62237
62345
  const target = join43(testDir, ".ck-symlink-test-target");
62238
62346
  const link = join43(testDir, ".ck-symlink-test-link");
62239
62347
  try {
62240
- await mkdir10(testDir, { recursive: true });
62241
- await writeFile13(target, "test", "utf-8");
62348
+ await mkdir11(testDir, { recursive: true });
62349
+ await writeFile14(target, "test", "utf-8");
62242
62350
  await symlink(target, link);
62243
62351
  await unlink6(link);
62244
62352
  await unlink6(target);
@@ -62992,7 +63100,7 @@ init_github_client();
62992
63100
  init_logger();
62993
63101
  init_path_resolver();
62994
63102
  var import_compare_versions5 = __toESM(require_umd(), 1);
62995
- import { mkdir as mkdir11, readFile as readFile24, unlink as unlink7, writeFile as writeFile14 } from "node:fs/promises";
63103
+ import { mkdir as mkdir12, readFile as readFile24, unlink as unlink7, writeFile as writeFile15 } from "node:fs/promises";
62996
63104
  import { join as join45 } from "node:path";
62997
63105
  var CACHE_TTL_HOURS = 24;
62998
63106
  var DEFAULT_CACHE_TTL_MS = CACHE_TTL_HOURS * 60 * 60 * 1000;
@@ -63050,8 +63158,8 @@ class ConfigVersionChecker {
63050
63158
  try {
63051
63159
  const cachePath = ConfigVersionChecker.getCacheFilePath(kitType, global3);
63052
63160
  const cacheDir = PathResolver.getCacheDir(global3);
63053
- await mkdir11(cacheDir, { recursive: true });
63054
- await writeFile14(cachePath, JSON.stringify(cache3, null, 2));
63161
+ await mkdir12(cacheDir, { recursive: true });
63162
+ await writeFile15(cachePath, JSON.stringify(cache3, null, 2));
63055
63163
  } catch (error) {
63056
63164
  logger.debug(`Cache write failed: ${error instanceof Error ? error.message : "Unknown error"}`);
63057
63165
  }
@@ -65712,7 +65820,7 @@ init_logger();
65712
65820
  // src/shared/process-lock.ts
65713
65821
  init_logger();
65714
65822
  var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
65715
- import { mkdir as mkdir14 } from "node:fs/promises";
65823
+ import { mkdir as mkdir15 } from "node:fs/promises";
65716
65824
  import os5 from "node:os";
65717
65825
  import { join as join53 } from "node:path";
65718
65826
  var LOCK_CONFIG = {
@@ -65745,7 +65853,7 @@ function registerCleanupHandlers() {
65745
65853
  }
65746
65854
  async function ensureLocksDir() {
65747
65855
  const lockDir = getLocksDir();
65748
- await mkdir14(lockDir, { recursive: true });
65856
+ await mkdir15(lockDir, { recursive: true });
65749
65857
  }
65750
65858
  async function withProcessLock(lockName, fn) {
65751
65859
  registerCleanupHandlers();
@@ -65900,7 +66008,7 @@ init_github_client();
65900
66008
  init_environment();
65901
66009
  init_logger();
65902
66010
  init_safe_spinner();
65903
- import { mkdir as mkdir20, stat as stat12 } from "node:fs/promises";
66011
+ import { mkdir as mkdir21, stat as stat12 } from "node:fs/promises";
65904
66012
  import { tmpdir as tmpdir3 } from "node:os";
65905
66013
  import { join as join61 } from "node:path";
65906
66014
 
@@ -65920,7 +66028,7 @@ var import_ignore = __toESM(require_ignore(), 1);
65920
66028
  init_logger();
65921
66029
  init_output_manager();
65922
66030
  import { createWriteStream as createWriteStream2, rmSync } from "node:fs";
65923
- import { mkdir as mkdir15 } from "node:fs/promises";
66031
+ import { mkdir as mkdir16 } from "node:fs/promises";
65924
66032
  import { join as join55 } from "node:path";
65925
66033
 
65926
66034
  // src/shared/progress-bar.ts
@@ -66085,7 +66193,7 @@ init_types2();
66085
66193
 
66086
66194
  // src/domains/installation/utils/path-security.ts
66087
66195
  init_types2();
66088
- import { lstatSync as lstatSync2, realpathSync as realpathSync2 } from "node:fs";
66196
+ import { lstatSync as lstatSync2, realpathSync } from "node:fs";
66089
66197
  import { relative as relative5, resolve as resolve10 } from "node:path";
66090
66198
  var MAX_EXTRACTION_SIZE = 500 * 1024 * 1024;
66091
66199
  function isPathSafe(basePath, targetPath) {
@@ -66093,7 +66201,7 @@ function isPathSafe(basePath, targetPath) {
66093
66201
  try {
66094
66202
  const stat10 = lstatSync2(targetPath);
66095
66203
  if (stat10.isSymbolicLink()) {
66096
- const realTarget = realpathSync2(targetPath);
66204
+ const realTarget = realpathSync(targetPath);
66097
66205
  if (!realTarget.startsWith(resolvedBase)) {
66098
66206
  return false;
66099
66207
  }
@@ -66132,7 +66240,7 @@ class FileDownloader {
66132
66240
  async downloadAsset(asset, destDir) {
66133
66241
  try {
66134
66242
  const destPath = join55(destDir, asset.name);
66135
- await mkdir15(destDir, { recursive: true });
66243
+ await mkdir16(destDir, { recursive: true });
66136
66244
  output.info(`Downloading ${asset.name} (${formatBytes(asset.size)})...`);
66137
66245
  logger.verbose("Download details", {
66138
66246
  url: asset.browser_download_url,
@@ -66217,7 +66325,7 @@ class FileDownloader {
66217
66325
  async downloadFile(params) {
66218
66326
  const { url, name, size, destDir, token } = params;
66219
66327
  const destPath = join55(destDir, name);
66220
- await mkdir15(destDir, { recursive: true });
66328
+ await mkdir16(destDir, { recursive: true });
66221
66329
  output.info(`Downloading ${name}${size ? ` (${formatBytes(size)})` : ""}...`);
66222
66330
  const headers = {};
66223
66331
  if (token && url.includes("api.github.com")) {
@@ -66335,7 +66443,7 @@ async function validateExtraction(extractDir) {
66335
66443
 
66336
66444
  // src/domains/installation/extraction/tar-extractor.ts
66337
66445
  init_logger();
66338
- import { copyFile as copyFile3, mkdir as mkdir18, readdir as readdir11, rm as rm3, stat as stat10 } from "node:fs/promises";
66446
+ import { copyFile as copyFile3, mkdir as mkdir19, readdir as readdir11, rm as rm3, stat as stat10 } from "node:fs/promises";
66339
66447
  import { join as join59 } from "node:path";
66340
66448
 
66341
66449
  // node_modules/@isaacs/fs-minipass/dist/esm/index.js
@@ -71965,7 +72073,7 @@ var checkCwd = (dir, cb) => {
71965
72073
  cb(er);
71966
72074
  });
71967
72075
  };
71968
- var mkdir16 = (dir, opt, cb) => {
72076
+ var mkdir17 = (dir, opt, cb) => {
71969
72077
  dir = normalizeWindowsPath(dir);
71970
72078
  const umask = opt.umask ?? 18;
71971
72079
  const mode = opt.mode | 448;
@@ -72488,7 +72596,7 @@ class Unpack extends Parser {
72488
72596
  }
72489
72597
  }
72490
72598
  [MKDIR](dir, mode, cb) {
72491
- mkdir16(normalizeWindowsPath(dir), {
72599
+ mkdir17(normalizeWindowsPath(dir), {
72492
72600
  uid: this.uid,
72493
72601
  gid: this.gid,
72494
72602
  processUid: this.processUid,
@@ -73204,7 +73312,7 @@ function decodeFilePath(path10) {
73204
73312
  // src/domains/installation/utils/file-utils.ts
73205
73313
  init_logger();
73206
73314
  init_types2();
73207
- import { copyFile as copyFile2, lstat as lstat4, mkdir as mkdir17, readdir as readdir10 } from "node:fs/promises";
73315
+ import { copyFile as copyFile2, lstat as lstat4, mkdir as mkdir18, readdir as readdir10 } from "node:fs/promises";
73208
73316
  import { join as join58, relative as relative6 } from "node:path";
73209
73317
  async function withRetry(fn, retries = 3) {
73210
73318
  for (let i = 0;i < retries; i++) {
@@ -73224,7 +73332,7 @@ var isRetryable = (e2) => {
73224
73332
  };
73225
73333
  var delay = (ms) => new Promise((r2) => setTimeout(r2, ms));
73226
73334
  async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTracker) {
73227
- await mkdir17(destDir, { recursive: true });
73335
+ await mkdir18(destDir, { recursive: true });
73228
73336
  const entries = await readdir10(sourceDir, { encoding: "utf8" });
73229
73337
  for (const entry of entries) {
73230
73338
  const sourcePath = join58(sourceDir, entry);
@@ -73252,7 +73360,7 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
73252
73360
  }
73253
73361
  }
73254
73362
  async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
73255
- await mkdir17(destDir, { recursive: true });
73363
+ await mkdir18(destDir, { recursive: true });
73256
73364
  const entries = await readdir10(sourceDir, { encoding: "utf8" });
73257
73365
  for (const entry of entries) {
73258
73366
  const sourcePath = join58(sourceDir, entry);
@@ -73284,7 +73392,7 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
73284
73392
  class TarExtractor {
73285
73393
  async extract(archivePath, destDir, shouldExclude, sizeTracker) {
73286
73394
  const tempExtractDir = `${destDir}-temp`;
73287
- await mkdir18(tempExtractDir, { recursive: true });
73395
+ await mkdir19(tempExtractDir, { recursive: true });
73288
73396
  try {
73289
73397
  await extract({
73290
73398
  file: archivePath,
@@ -73319,7 +73427,7 @@ class TarExtractor {
73319
73427
  await moveDirectoryContents(tempExtractDir, destDir, shouldExclude, sizeTracker);
73320
73428
  }
73321
73429
  } else {
73322
- await mkdir18(destDir, { recursive: true });
73430
+ await mkdir19(destDir, { recursive: true });
73323
73431
  await copyFile3(rootPath, join59(destDir, rootEntry));
73324
73432
  }
73325
73433
  } else {
@@ -73342,7 +73450,7 @@ init_environment();
73342
73450
  init_logger();
73343
73451
  var import_extract_zip = __toESM(require_extract_zip(), 1);
73344
73452
  import { execFile as execFile8 } from "node:child_process";
73345
- import { copyFile as copyFile4, mkdir as mkdir19, readdir as readdir12, rm as rm4, stat as stat11 } from "node:fs/promises";
73453
+ import { copyFile as copyFile4, mkdir as mkdir20, readdir as readdir12, rm as rm4, stat as stat11 } from "node:fs/promises";
73346
73454
  import { join as join60 } from "node:path";
73347
73455
  class ZipExtractor {
73348
73456
  async tryNativeUnzip(archivePath, destDir) {
@@ -73350,7 +73458,7 @@ class ZipExtractor {
73350
73458
  return false;
73351
73459
  }
73352
73460
  return new Promise((resolve11) => {
73353
- mkdir19(destDir, { recursive: true }).then(() => {
73461
+ mkdir20(destDir, { recursive: true }).then(() => {
73354
73462
  execFile8("unzip", ["-o", "-q", archivePath, "-d", destDir], (error, _stdout, stderr) => {
73355
73463
  if (error) {
73356
73464
  logger.debug(`Native unzip failed: ${stderr || error.message}`);
@@ -73368,7 +73476,7 @@ class ZipExtractor {
73368
73476
  }
73369
73477
  async extract(archivePath, destDir, shouldExclude, sizeTracker) {
73370
73478
  const tempExtractDir = `${destDir}-temp`;
73371
- await mkdir19(tempExtractDir, { recursive: true });
73479
+ await mkdir20(tempExtractDir, { recursive: true });
73372
73480
  try {
73373
73481
  const nativeSuccess = await this.tryNativeUnzip(archivePath, tempExtractDir);
73374
73482
  if (!nativeSuccess) {
@@ -73406,7 +73514,7 @@ class ZipExtractor {
73406
73514
  await moveDirectoryContents(tempExtractDir, destDir, shouldExclude, sizeTracker);
73407
73515
  }
73408
73516
  } else {
73409
- await mkdir19(destDir, { recursive: true });
73517
+ await mkdir20(destDir, { recursive: true });
73410
73518
  await copyFile4(rootPath, join60(destDir, rootEntry));
73411
73519
  }
73412
73520
  } else {
@@ -73481,7 +73589,7 @@ class DownloadManager {
73481
73589
  try {
73482
73590
  this.sizeTracker.reset();
73483
73591
  const detectedType = archiveType || detectArchiveType(archivePath);
73484
- await mkdir20(destDir, { recursive: true });
73592
+ await mkdir21(destDir, { recursive: true });
73485
73593
  if (detectedType === "tar.gz") {
73486
73594
  await this.tarExtractor.extract(archivePath, destDir, this.shouldExclude, this.sizeTracker);
73487
73595
  } else if (detectedType === "zip") {
@@ -73508,7 +73616,7 @@ class DownloadManager {
73508
73616
  const counter = DownloadManager.tempDirCounter++;
73509
73617
  const primaryTempDir = join61(tmpdir3(), `claudekit-${timestamp}-${counter}`);
73510
73618
  try {
73511
- await mkdir20(primaryTempDir, { recursive: true });
73619
+ await mkdir21(primaryTempDir, { recursive: true });
73512
73620
  logger.debug(`Created temp directory: ${primaryTempDir}`);
73513
73621
  registerTempDir(primaryTempDir);
73514
73622
  return primaryTempDir;
@@ -73525,7 +73633,7 @@ Solutions:
73525
73633
  }
73526
73634
  const fallbackTempDir = join61(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
73527
73635
  try {
73528
- await mkdir20(fallbackTempDir, { recursive: true });
73636
+ await mkdir21(fallbackTempDir, { recursive: true });
73529
73637
  logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
73530
73638
  logger.warning(`Using fallback temp directory: ${fallbackTempDir}
73531
73639
  (OS temp directory was not accessible)`);
@@ -73876,7 +73984,7 @@ import { join as join77 } from "node:path";
73876
73984
 
73877
73985
  // src/domains/installation/deletion-handler.ts
73878
73986
  import { existsSync as existsSync35, lstatSync as lstatSync3, readdirSync as readdirSync2, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
73879
- import { dirname as dirname14, join as join64, relative as relative7, resolve as resolve12, sep as sep2 } from "node:path";
73987
+ import { dirname as dirname14, join as join64, relative as relative7, resolve as resolve12, sep } from "node:path";
73880
73988
 
73881
73989
  // src/services/file-operations/manifest/manifest-reader.ts
73882
73990
  init_metadata_migration();
@@ -74115,7 +74223,7 @@ function cleanupEmptyDirectories(filePath, claudeDir2) {
74115
74223
  function deletePath(fullPath, claudeDir2) {
74116
74224
  const normalizedPath = resolve12(fullPath);
74117
74225
  const normalizedClaudeDir = resolve12(claudeDir2);
74118
- if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep2}`) && normalizedPath !== normalizedClaudeDir) {
74226
+ if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep}`) && normalizedPath !== normalizedClaudeDir) {
74119
74227
  throw new Error(`Path traversal detected: ${fullPath}`);
74120
74228
  }
74121
74229
  try {
@@ -74189,7 +74297,7 @@ async function handleDeletions(sourceMetadata, claudeDir2) {
74189
74297
  const fullPath = join64(claudeDir2, path11);
74190
74298
  const normalizedPath = resolve12(fullPath);
74191
74299
  const normalizedClaudeDir = resolve12(claudeDir2);
74192
- if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep2}`)) {
74300
+ if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep}`)) {
74193
74301
  logger.warning(`Skipping invalid path: ${path11}`);
74194
74302
  result.errors.push(path11);
74195
74303
  continue;
@@ -75212,8 +75320,8 @@ var path11 = {
75212
75320
  win32: { sep: "\\" },
75213
75321
  posix: { sep: "/" }
75214
75322
  };
75215
- var sep3 = defaultPlatform === "win32" ? path11.win32.sep : path11.posix.sep;
75216
- minimatch.sep = sep3;
75323
+ var sep2 = defaultPlatform === "win32" ? path11.win32.sep : path11.posix.sep;
75324
+ minimatch.sep = sep2;
75217
75325
  var GLOBSTAR = Symbol("globstar **");
75218
75326
  minimatch.GLOBSTAR = GLOBSTAR;
75219
75327
  var qmark2 = "[^/]";
@@ -75894,13 +76002,10 @@ class FileScanner {
75894
76002
  }
75895
76003
  }
75896
76004
 
75897
- // src/domains/installation/merger/settings-processor.ts
75898
- import { execSync as execSync4 } from "node:child_process";
75899
-
75900
76005
  // src/domains/config/installed-settings-tracker.ts
75901
76006
  init_shared();
75902
76007
  import { existsSync as existsSync36 } from "node:fs";
75903
- import { mkdir as mkdir21, readFile as readFile29, writeFile as writeFile17 } from "node:fs/promises";
76008
+ import { mkdir as mkdir22, readFile as readFile29, writeFile as writeFile18 } from "node:fs/promises";
75904
76009
  import { dirname as dirname15, join as join66 } from "node:path";
75905
76010
  var CK_JSON_FILE = ".ck.json";
75906
76011
 
@@ -75952,8 +76057,8 @@ class InstalledSettingsTracker {
75952
76057
  data.kits[this.kitName] = {};
75953
76058
  }
75954
76059
  data.kits[this.kitName].installedSettings = settings;
75955
- await mkdir21(dirname15(ckJsonPath), { recursive: true });
75956
- await writeFile17(ckJsonPath, JSON.stringify(data, null, 2), "utf-8");
76060
+ await mkdir22(dirname15(ckJsonPath), { recursive: true });
76061
+ await writeFile18(ckJsonPath, JSON.stringify(data, null, 2), "utf-8");
75957
76062
  logger.debug(`Saved installed settings to ${ckJsonPath}`);
75958
76063
  } catch (error) {
75959
76064
  logger.warning(`Failed to save installed settings: ${error instanceof Error ? error.message : "Unknown error"}`);
@@ -75995,17 +76100,14 @@ init_settings_merger();
75995
76100
  init_environment();
75996
76101
  init_logger();
75997
76102
  var import_fs_extra11 = __toESM(require_lib3(), 1);
75998
- var import_semver2 = __toESM(require_semver2(), 1);
75999
76103
 
76000
76104
  class SettingsProcessor {
76001
- static MIN_TEAM_HOOKS_VERSION = "2.1.33";
76002
76105
  isGlobal = false;
76003
76106
  forceOverwriteSettings = false;
76004
76107
  projectDir = "";
76005
76108
  kitName = "engineer";
76006
76109
  tracker = null;
76007
76110
  installingKit;
76008
- cachedVersion = undefined;
76009
76111
  setGlobalFlag(isGlobal) {
76010
76112
  this.isGlobal = isGlobal;
76011
76113
  }
@@ -76051,9 +76153,8 @@ class SettingsProcessor {
76051
76153
  } else {
76052
76154
  const formattedContent = this.formatJsonContent(transformedSource);
76053
76155
  await import_fs_extra11.writeFile(destFile, formattedContent, "utf-8");
76054
- let parsedSettings;
76055
76156
  try {
76056
- parsedSettings = JSON.parse(formattedContent);
76157
+ const parsedSettings = JSON.parse(formattedContent);
76057
76158
  if (this.forceOverwriteSettings && destExists) {
76058
76159
  logger.debug("Force overwrite enabled, replaced settings.json completely");
76059
76160
  if (this.tracker) {
@@ -76062,7 +76163,6 @@ class SettingsProcessor {
76062
76163
  }
76063
76164
  await this.trackInstalledSettings(parsedSettings);
76064
76165
  } catch {}
76065
- await this.injectTeamHooksIfSupported(destFile, parsedSettings);
76066
76166
  }
76067
76167
  } catch (error) {
76068
76168
  logger.error(`Failed to process settings.json: ${error}`);
@@ -76123,7 +76223,6 @@ class SettingsProcessor {
76123
76223
  }
76124
76224
  await SettingsMerger.writeSettingsFile(destFile, mergeResult.merged);
76125
76225
  logger.success("Merged settings.json (user customizations preserved)");
76126
- await this.injectTeamHooksIfSupported(destFile, mergeResult.merged);
76127
76226
  }
76128
76227
  async trackInstalledSettings(settings) {
76129
76228
  if (!this.tracker)
@@ -76195,80 +76294,6 @@ class SettingsProcessor {
76195
76294
  }
76196
76295
  return transformed;
76197
76296
  }
76198
- detectClaudeCodeVersion() {
76199
- if (this.cachedVersion !== undefined)
76200
- return this.cachedVersion;
76201
- try {
76202
- const output2 = execSync4("claude --version", {
76203
- encoding: "utf-8",
76204
- timeout: 5000,
76205
- stdio: ["ignore", "pipe", "ignore"]
76206
- });
76207
- const match2 = output2.match(/(\d+\.\d+\.\d+)/);
76208
- this.cachedVersion = match2 ? match2[1] : null;
76209
- } catch {
76210
- this.cachedVersion = null;
76211
- }
76212
- return this.cachedVersion;
76213
- }
76214
- isVersionAtLeast(version, minimum) {
76215
- const coerced = import_semver2.default.coerce(version);
76216
- if (!coerced)
76217
- return false;
76218
- return import_semver2.default.gte(coerced, minimum);
76219
- }
76220
- async injectTeamHooksIfSupported(destFile, existingSettings) {
76221
- const version = this.detectClaudeCodeVersion();
76222
- if (!version) {
76223
- logger.debug("Claude Code version not detected, skipping team hooks injection");
76224
- return;
76225
- }
76226
- if (!this.isVersionAtLeast(version, SettingsProcessor.MIN_TEAM_HOOKS_VERSION)) {
76227
- logger.debug(`Claude Code ${version} does not support team hooks (requires >= 2.1.33), skipping injection`);
76228
- return;
76229
- }
76230
- logger.debug(`Claude Code ${version} detected, checking team hooks`);
76231
- const settings = existingSettings ?? await SettingsMerger.readSettingsFile(destFile);
76232
- if (!settings) {
76233
- logger.warning("Failed to read settings file for team hooks injection");
76234
- return;
76235
- }
76236
- const prefix = this.isGlobal ? isWindows() ? "%USERPROFILE%" : "$HOME" : isWindows() ? "%CLAUDE_PROJECT_DIR%" : "$CLAUDE_PROJECT_DIR";
76237
- if (!settings.hooks) {
76238
- settings.hooks = {};
76239
- }
76240
- let injected = false;
76241
- const installedSettings = this.tracker ? await this.tracker.loadInstalledSettings() : { hooks: [], mcpServers: [] };
76242
- const teamHooks = [
76243
- { event: "TaskCompleted", handler: "task-completed-handler.cjs" },
76244
- { event: "TeammateIdle", handler: "teammate-idle-handler.cjs" }
76245
- ];
76246
- for (const { event, handler } of teamHooks) {
76247
- const hookCommand = `node ${prefix}/.claude/hooks/${handler}`;
76248
- const eventHooks = settings.hooks[event];
76249
- if (eventHooks && eventHooks.length > 0)
76250
- continue;
76251
- if (this.tracker?.wasHookInstalled(hookCommand, installedSettings)) {
76252
- logger.debug(`Skipping ${event} hook injection (previously removed by user)`);
76253
- continue;
76254
- }
76255
- settings.hooks[event] = [{ hooks: [{ type: "command", command: hookCommand }] }];
76256
- logger.info(`Injected ${event} hook`);
76257
- injected = true;
76258
- if (this.tracker) {
76259
- this.tracker.trackHook(hookCommand, installedSettings);
76260
- }
76261
- }
76262
- if (injected) {
76263
- await SettingsMerger.writeSettingsFile(destFile, settings);
76264
- if (this.tracker) {
76265
- await this.tracker.saveInstalledSettings(installedSettings);
76266
- }
76267
- logger.success("Team hooks injected successfully");
76268
- } else {
76269
- logger.debug("Team hooks already present, no injection needed");
76270
- }
76271
- }
76272
76297
  }
76273
76298
 
76274
76299
  // src/domains/installation/merger/copy-executor.ts
@@ -77205,12 +77230,12 @@ class FileScanner2 {
77205
77230
  // src/services/transformers/commands-prefix/prefix-applier.ts
77206
77231
  init_logger();
77207
77232
  var import_fs_extra17 = __toESM(require_lib3(), 1);
77208
- import { lstat as lstat7, mkdir as mkdir22, readdir as readdir17, stat as stat15 } from "node:fs/promises";
77233
+ import { lstat as lstat7, mkdir as mkdir23, readdir as readdir17, stat as stat15 } from "node:fs/promises";
77209
77234
  import { join as join74 } from "node:path";
77210
77235
 
77211
77236
  // src/services/transformers/commands-prefix/content-transformer.ts
77212
77237
  init_logger();
77213
- import { readFile as readFile33, readdir as readdir16, writeFile as writeFile21 } from "node:fs/promises";
77238
+ import { readFile as readFile33, readdir as readdir16, writeFile as writeFile22 } from "node:fs/promises";
77214
77239
  import { join as join73 } from "node:path";
77215
77240
  var TRANSFORMABLE_EXTENSIONS = new Set([
77216
77241
  ".md",
@@ -77286,7 +77311,7 @@ async function transformCommandReferences(directory, options2 = {}) {
77286
77311
  if (options2.dryRun) {
77287
77312
  logger.debug(`[dry-run] Would transform ${changes} command ref(s) in ${fullPath}`);
77288
77313
  } else {
77289
- await writeFile21(fullPath, transformed, "utf-8");
77314
+ await writeFile22(fullPath, transformed, "utf-8");
77290
77315
  if (options2.verbose) {
77291
77316
  logger.verbose(`Transformed ${changes} command ref(s) in ${fullPath}`);
77292
77317
  }
@@ -77371,9 +77396,9 @@ async function applyPrefix(extractDir) {
77371
77396
  }
77372
77397
  await import_fs_extra17.copy(commandsDir, backupDir);
77373
77398
  logger.verbose("Created backup of commands directory");
77374
- await mkdir22(tempDir, { recursive: true });
77399
+ await mkdir23(tempDir, { recursive: true });
77375
77400
  const ckDir = join74(tempDir, "ck");
77376
- await mkdir22(ckDir, { recursive: true });
77401
+ await mkdir23(ckDir, { recursive: true });
77377
77402
  let processedCount = 0;
77378
77403
  for (const entry of entries) {
77379
77404
  const sourcePath = join74(commandsDir, entry);
@@ -77811,7 +77836,7 @@ init_skip_directories();
77811
77836
  init_types2();
77812
77837
  var import_fs_extra21 = __toESM(require_lib3(), 1);
77813
77838
  import { createHash as createHash2 } from "node:crypto";
77814
- import { readFile as readFile35, readdir as readdir20, writeFile as writeFile22 } from "node:fs/promises";
77839
+ import { readFile as readFile35, readdir as readdir20, writeFile as writeFile23 } from "node:fs/promises";
77815
77840
  import { join as join78, relative as relative12 } from "node:path";
77816
77841
 
77817
77842
  class SkillsManifestManager {
@@ -77835,7 +77860,7 @@ class SkillsManifestManager {
77835
77860
  }
77836
77861
  static async writeManifest(skillsDir2, manifest) {
77837
77862
  const manifestPath = join78(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
77838
- await writeFile22(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
77863
+ await writeFile23(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
77839
77864
  logger.debug(`Wrote manifest to: ${manifestPath}`);
77840
77865
  }
77841
77866
  static async readManifest(skillsDir2) {
@@ -78228,7 +78253,7 @@ import { join as join84 } from "node:path";
78228
78253
 
78229
78254
  // src/domains/skills/migrator/migration-executor.ts
78230
78255
  init_logger();
78231
- import { copyFile as copyFile5, mkdir as mkdir23, readdir as readdir22, rm as rm5 } from "node:fs/promises";
78256
+ import { copyFile as copyFile5, mkdir as mkdir24, readdir as readdir22, rm as rm5 } from "node:fs/promises";
78232
78257
  import { join as join80 } from "node:path";
78233
78258
  var import_fs_extra24 = __toESM(require_lib3(), 1);
78234
78259
 
@@ -78391,7 +78416,7 @@ Detected changes:`;
78391
78416
 
78392
78417
  // src/domains/skills/migrator/migration-executor.ts
78393
78418
  async function copySkillDirectory(sourceDir, destDir) {
78394
- await mkdir23(destDir, { recursive: true });
78419
+ await mkdir24(destDir, { recursive: true });
78395
78420
  const entries = await readdir22(sourceDir, { withFileTypes: true });
78396
78421
  for (const entry of entries) {
78397
78422
  const sourcePath = join80(sourceDir, entry.name);
@@ -78411,7 +78436,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
78411
78436
  const preserved = [];
78412
78437
  const errors2 = [];
78413
78438
  const tempDir = join80(currentSkillsDir, "..", ".skills-migration-temp");
78414
- await mkdir23(tempDir, { recursive: true });
78439
+ await mkdir24(tempDir, { recursive: true });
78415
78440
  try {
78416
78441
  for (const mapping of mappings) {
78417
78442
  try {
@@ -78433,7 +78458,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
78433
78458
  const category = mapping.category;
78434
78459
  const targetPath = category ? join80(tempDir, category, skillName) : join80(tempDir, skillName);
78435
78460
  if (category) {
78436
- await mkdir23(join80(tempDir, category), { recursive: true });
78461
+ await mkdir24(join80(tempDir, category), { recursive: true });
78437
78462
  }
78438
78463
  await copySkillDirectory(currentSkillPath, targetPath);
78439
78464
  migrated.push(skillName);
@@ -78452,7 +78477,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
78452
78477
  }
78453
78478
  }
78454
78479
  await rm5(currentSkillsDir, { recursive: true, force: true });
78455
- await mkdir23(currentSkillsDir, { recursive: true });
78480
+ await mkdir24(currentSkillsDir, { recursive: true });
78456
78481
  await copySkillDirectory(tempDir, currentSkillsDir);
78457
78482
  await rm5(tempDir, { recursive: true, force: true });
78458
78483
  return { migrated, preserved, errors: errors2 };
@@ -78499,7 +78524,7 @@ function validateMigrationPath(path12, paramName) {
78499
78524
  init_logger();
78500
78525
  init_types2();
78501
78526
  var import_fs_extra25 = __toESM(require_lib3(), 1);
78502
- import { copyFile as copyFile6, mkdir as mkdir24, readdir as readdir23, rm as rm6, stat as stat16 } from "node:fs/promises";
78527
+ import { copyFile as copyFile6, mkdir as mkdir25, readdir as readdir23, rm as rm6, stat as stat16 } from "node:fs/promises";
78503
78528
  import { basename as basename8, join as join81, normalize as normalize8 } from "node:path";
78504
78529
  function validatePath2(path12, paramName) {
78505
78530
  if (!path12 || typeof path12 !== "string") {
@@ -78529,7 +78554,7 @@ class SkillsBackupManager {
78529
78554
  const backupDir = parentDir ? join81(parentDir, backupDirName) : join81(skillsDir2, "..", backupDirName);
78530
78555
  logger.info(`Creating backup at: ${backupDir}`);
78531
78556
  try {
78532
- await mkdir24(backupDir, { recursive: true });
78557
+ await mkdir25(backupDir, { recursive: true });
78533
78558
  await SkillsBackupManager.copyDirectory(skillsDir2, backupDir);
78534
78559
  logger.success("Backup created successfully");
78535
78560
  return backupDir;
@@ -78551,7 +78576,7 @@ class SkillsBackupManager {
78551
78576
  if (await import_fs_extra25.pathExists(targetDir)) {
78552
78577
  await rm6(targetDir, { recursive: true, force: true });
78553
78578
  }
78554
- await mkdir24(targetDir, { recursive: true });
78579
+ await mkdir25(targetDir, { recursive: true });
78555
78580
  await SkillsBackupManager.copyDirectory(backupDir, targetDir);
78556
78581
  logger.success("Backup restored successfully");
78557
78582
  } catch (error) {
@@ -78611,7 +78636,7 @@ class SkillsBackupManager {
78611
78636
  continue;
78612
78637
  }
78613
78638
  if (entry.isDirectory()) {
78614
- await mkdir24(destPath, { recursive: true });
78639
+ await mkdir25(destPath, { recursive: true });
78615
78640
  await SkillsBackupManager.copyDirectory(sourcePath, destPath);
78616
78641
  } else if (entry.isFile()) {
78617
78642
  await copyFile6(sourcePath, destPath);
@@ -79030,7 +79055,7 @@ import { join as join87 } from "node:path";
79030
79055
 
79031
79056
  // src/services/transformers/opencode-path-transformer.ts
79032
79057
  init_logger();
79033
- import { readFile as readFile37, readdir as readdir26, writeFile as writeFile23 } from "node:fs/promises";
79058
+ import { readFile as readFile37, readdir as readdir26, writeFile as writeFile24 } from "node:fs/promises";
79034
79059
  import { platform as platform12 } from "node:os";
79035
79060
  import { extname as extname3, join as join86 } from "node:path";
79036
79061
  var IS_WINDOWS3 = platform12() === "win32";
@@ -79104,7 +79129,7 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
79104
79129
  const content = await readFile37(fullPath, "utf-8");
79105
79130
  const { transformed, changes } = transformOpenCodeContent(content);
79106
79131
  if (changes > 0) {
79107
- await writeFile23(fullPath, transformed, "utf-8");
79132
+ await writeFile24(fullPath, transformed, "utf-8");
79108
79133
  filesTransformed++;
79109
79134
  totalChanges += changes;
79110
79135
  if (options2.verbose) {
@@ -79325,7 +79350,7 @@ async function handlePostInstall(ctx) {
79325
79350
  // src/commands/init/phases/selection-handler.ts
79326
79351
  init_config_manager();
79327
79352
  init_github_client();
79328
- import { mkdir as mkdir25 } from "node:fs/promises";
79353
+ import { mkdir as mkdir26 } from "node:fs/promises";
79329
79354
  import { join as join90, resolve as resolve15 } from "node:path";
79330
79355
 
79331
79356
  // src/domains/github/kit-access-checker.ts
@@ -79848,7 +79873,7 @@ async function handleSelection(ctx) {
79848
79873
  }
79849
79874
  if (!await import_fs_extra32.pathExists(resolvedDir)) {
79850
79875
  if (ctx.options.global) {
79851
- await mkdir25(resolvedDir, { recursive: true });
79876
+ await mkdir26(resolvedDir, { recursive: true });
79852
79877
  logger.info(`Created global directory: ${resolvedDir}`);
79853
79878
  } else {
79854
79879
  logger.error(`Directory does not exist: ${resolvedDir}`);
@@ -79983,7 +80008,7 @@ async function handleSelection(ctx) {
79983
80008
  };
79984
80009
  }
79985
80010
  // src/commands/init/phases/sync-handler.ts
79986
- import { copyFile as copyFile7, mkdir as mkdir26, open as open4, readFile as readFile39, rename as rename3, stat as stat17, unlink as unlink8, writeFile as writeFile25 } from "node:fs/promises";
80011
+ import { copyFile as copyFile7, mkdir as mkdir27, open as open4, readFile as readFile39, rename as rename3, stat as stat17, unlink as unlink8, writeFile as writeFile26 } from "node:fs/promises";
79987
80012
  import { dirname as dirname18, join as join91, resolve as resolve16 } from "node:path";
79988
80013
  init_logger();
79989
80014
  init_path_resolver();
@@ -80103,7 +80128,7 @@ async function acquireSyncLock(global3) {
80103
80128
  const lockPath = join91(cacheDir, ".sync-lock");
80104
80129
  const startTime = Date.now();
80105
80130
  const lockTimeout = getLockTimeout();
80106
- await mkdir26(dirname18(lockPath), { recursive: true });
80131
+ await mkdir27(dirname18(lockPath), { recursive: true });
80107
80132
  while (Date.now() - startTime < lockTimeout) {
80108
80133
  try {
80109
80134
  const handle = await open4(lockPath, "wx");
@@ -80183,7 +80208,7 @@ async function executeSyncMerge(ctx) {
80183
80208
  const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
80184
80209
  const targetDir = join91(targetPath, "..");
80185
80210
  try {
80186
- await mkdir26(targetDir, { recursive: true });
80211
+ await mkdir27(targetDir, { recursive: true });
80187
80212
  } catch (mkdirError) {
80188
80213
  const errCode = mkdirError.code;
80189
80214
  if (errCode === "ENOSPC") {
@@ -80262,7 +80287,7 @@ async function executeSyncMerge(ctx) {
80262
80287
  try {
80263
80288
  const tempPath = `${currentPath}.tmp.${Date.now()}`;
80264
80289
  try {
80265
- await writeFile25(tempPath, result.result, "utf-8");
80290
+ await writeFile26(tempPath, result.result, "utf-8");
80266
80291
  await rename3(tempPath, currentPath);
80267
80292
  } catch (atomicError) {
80268
80293
  await unlink8(tempPath).catch(() => {});
@@ -80346,14 +80371,14 @@ function displaySyncPlan(plan) {
80346
80371
  console.log(import_picocolors21.default.dim("─".repeat(40)));
80347
80372
  }
80348
80373
  async function createBackup(claudeDir2, files, backupDir) {
80349
- await mkdir26(backupDir, { recursive: true });
80374
+ await mkdir27(backupDir, { recursive: true });
80350
80375
  for (const file of files) {
80351
80376
  try {
80352
80377
  const sourcePath = await validateSyncPath(claudeDir2, file.path);
80353
80378
  if (await import_fs_extra33.pathExists(sourcePath)) {
80354
80379
  const targetPath = await validateSyncPath(backupDir, file.path);
80355
80380
  const targetDir = join91(targetPath, "..");
80356
- await mkdir26(targetDir, { recursive: true });
80381
+ await mkdir27(targetDir, { recursive: true });
80357
80382
  await copyFile7(sourcePath, targetPath);
80358
80383
  }
80359
80384
  } catch (error) {
@@ -80449,7 +80474,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
80449
80474
  // src/services/transformers/folder-transform/path-replacer.ts
80450
80475
  init_logger();
80451
80476
  init_types2();
80452
- import { readFile as readFile40, readdir as readdir28, writeFile as writeFile26 } from "node:fs/promises";
80477
+ import { readFile as readFile40, readdir as readdir28, writeFile as writeFile27 } from "node:fs/promises";
80453
80478
  import { join as join93, relative as relative16 } from "node:path";
80454
80479
  var TRANSFORMABLE_FILE_PATTERNS = [
80455
80480
  ".md",
@@ -80532,7 +80557,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
80532
80557
  if (options2.dryRun) {
80533
80558
  logger.debug(`[dry-run] Would update ${relative16(dir, fullPath)}: ${changeCount} replacement(s)`);
80534
80559
  } else {
80535
- await writeFile26(fullPath, newContent, "utf-8");
80560
+ await writeFile27(fullPath, newContent, "utf-8");
80536
80561
  logger.debug(`Updated ${relative16(dir, fullPath)}: ${changeCount} replacement(s)`);
80537
80562
  }
80538
80563
  filesChanged++;
@@ -80638,7 +80663,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
80638
80663
 
80639
80664
  // src/services/transformers/global-path-transformer.ts
80640
80665
  init_logger();
80641
- import { readFile as readFile41, readdir as readdir29, writeFile as writeFile27 } from "node:fs/promises";
80666
+ import { readFile as readFile41, readdir as readdir29, writeFile as writeFile28 } from "node:fs/promises";
80642
80667
  import { platform as platform13 } from "node:os";
80643
80668
  import { extname as extname4, join as join94 } from "node:path";
80644
80669
  var IS_WINDOWS4 = platform13() === "win32";
@@ -80761,7 +80786,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
80761
80786
  const content = await readFile41(fullPath, "utf-8");
80762
80787
  const { transformed, changes } = transformContent(content);
80763
80788
  if (changes > 0) {
80764
- await writeFile27(fullPath, transformed, "utf-8");
80789
+ await writeFile28(fullPath, transformed, "utf-8");
80765
80790
  filesTransformed++;
80766
80791
  totalChanges += changes;
80767
80792
  if (options2.verbose) {
@@ -81619,10 +81644,10 @@ init_dist2();
81619
81644
 
81620
81645
  // src/commands/setup/phases/preflight-check.ts
81621
81646
  init_dist2();
81622
- import { execSync as execSync5 } from "node:child_process";
81647
+ import { execSync as execSync4 } from "node:child_process";
81623
81648
  function isGhInstalled() {
81624
81649
  try {
81625
- execSync5("gh --version", { stdio: "pipe" });
81650
+ execSync4("gh --version", { stdio: "pipe" });
81626
81651
  return true;
81627
81652
  } catch {
81628
81653
  return false;
@@ -81630,7 +81655,7 @@ function isGhInstalled() {
81630
81655
  }
81631
81656
  function checkGhAuth() {
81632
81657
  try {
81633
- execSync5("gh auth status", { stdio: "pipe" });
81658
+ execSync4("gh auth status", { stdio: "pipe" });
81634
81659
  return true;
81635
81660
  } catch {
81636
81661
  return false;
@@ -81647,11 +81672,11 @@ function checkNodeVersion() {
81647
81672
  }
81648
81673
  function checkPython() {
81649
81674
  try {
81650
- execSync5("python3 --version", { stdio: "pipe" });
81675
+ execSync4("python3 --version", { stdio: "pipe" });
81651
81676
  return true;
81652
81677
  } catch {
81653
81678
  try {
81654
- execSync5("python --version", { stdio: "pipe" });
81679
+ execSync4("python --version", { stdio: "pipe" });
81655
81680
  return true;
81656
81681
  } catch {
81657
81682
  return false;
@@ -82374,7 +82399,7 @@ async function detectInstallations() {
82374
82399
 
82375
82400
  // src/commands/uninstall/removal-handler.ts
82376
82401
  import { readdirSync as readdirSync5, rmSync as rmSync5 } from "node:fs";
82377
- import { join as join99, resolve as resolve19, sep as sep4 } from "node:path";
82402
+ import { join as join99, resolve as resolve19, sep as sep3 } from "node:path";
82378
82403
  init_logger();
82379
82404
  init_safe_prompts();
82380
82405
  init_safe_spinner();
@@ -82517,7 +82542,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
82517
82542
  try {
82518
82543
  const resolvedPath = resolve19(filePath);
82519
82544
  const resolvedBase = resolve19(baseDir);
82520
- if (!resolvedPath.startsWith(resolvedBase + sep4) && resolvedPath !== resolvedBase) {
82545
+ if (!resolvedPath.startsWith(resolvedBase + sep3) && resolvedPath !== resolvedBase) {
82521
82546
  logger.debug(`Path outside installation directory: ${filePath}`);
82522
82547
  return false;
82523
82548
  }
@@ -82525,7 +82550,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
82525
82550
  if (stats.isSymbolicLink()) {
82526
82551
  const realPath = await import_fs_extra37.realpath(filePath);
82527
82552
  const resolvedReal = resolve19(realPath);
82528
- if (!resolvedReal.startsWith(resolvedBase + sep4) && resolvedReal !== resolvedBase) {
82553
+ if (!resolvedReal.startsWith(resolvedBase + sep3) && resolvedReal !== resolvedBase) {
82529
82554
  logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
82530
82555
  return false;
82531
82556
  }