claudekit-cli 4.5.0-dev.8 → 4.5.0-dev.9

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
@@ -15619,12 +15619,16 @@ function detectLegacyState(claudeDir) {
15619
15619
  const metadata = readJsonSafe(join6(claudeDir, "metadata.json"));
15620
15620
  if (!isRecord(metadata))
15621
15621
  return { installed: false, version: null };
15622
+ const hasLegacyPayload = hasTrackedPluginSuppliedLegacyFiles(claudeDir);
15622
15623
  if (isRecord(metadata.kits) && isRecord(metadata.kits[ENGINEER_KIT_KEY])) {
15623
15624
  const kit = metadata.kits[ENGINEER_KIT_KEY];
15624
- return { installed: true, version: typeof kit.version === "string" ? kit.version : null };
15625
+ return {
15626
+ installed: hasLegacyPayload,
15627
+ version: hasLegacyPayload && typeof kit.version === "string" ? kit.version : null
15628
+ };
15625
15629
  }
15626
15630
  const hasFiles = Array.isArray(metadata.files) && metadata.files.length > 0 || Array.isArray(metadata.installedFiles) && metadata.installedFiles.length > 0;
15627
- if (typeof metadata.version === "string" && hasFiles) {
15631
+ if (typeof metadata.version === "string" && hasFiles && hasLegacyPayload) {
15628
15632
  return { installed: true, version: metadata.version };
15629
15633
  }
15630
15634
  return { installed: false, version: null };
@@ -15980,11 +15984,12 @@ var init_github = __esm(() => {
15980
15984
  });
15981
15985
 
15982
15986
  // src/types/metadata.ts
15983
- var TrackedFileSchema, InstalledSettingsSchema, KitMetadataSchema, MultiKitMetadataSchema, LegacyMetadataSchema, MetadataSchema, DownloadMethodSchema, ConfigSchema;
15987
+ var InstallModePreferenceSchema, TrackedFileSchema, InstalledSettingsSchema, KitMetadataSchema, MultiKitMetadataSchema, LegacyMetadataSchema, MetadataSchema, DownloadMethodSchema, ConfigSchema;
15984
15988
  var init_metadata = __esm(() => {
15985
15989
  init_zod();
15986
15990
  init_commands();
15987
15991
  init_kit();
15992
+ InstallModePreferenceSchema = exports_external.enum(["auto", "plugin", "legacy"]);
15988
15993
  TrackedFileSchema = exports_external.object({
15989
15994
  path: exports_external.string(),
15990
15995
  checksum: exports_external.string().regex(/^[a-f0-9]{64}$/, "Invalid SHA-256 checksum"),
@@ -16005,6 +16010,7 @@ var init_metadata = __esm(() => {
16005
16010
  installedAt: exports_external.string(),
16006
16011
  files: exports_external.array(TrackedFileSchema).optional(),
16007
16012
  ignoredSkills: exports_external.array(exports_external.string()).optional(),
16013
+ installModePreference: InstallModePreferenceSchema.optional(),
16008
16014
  lastUpdateCheck: exports_external.string().optional(),
16009
16015
  dismissedVersion: exports_external.string().optional(),
16010
16016
  installedSettings: InstalledSettingsSchema.optional()
@@ -16688,6 +16694,7 @@ __export(exports_types, {
16688
16694
  KitLayoutSchema: () => KitLayoutSchema,
16689
16695
  KitConfigSchema: () => KitConfigSchema,
16690
16696
  InstalledSettingsSchema: () => InstalledSettingsSchema,
16697
+ InstallModePreferenceSchema: () => InstallModePreferenceSchema,
16691
16698
  GitHubReleaseSchema: () => GitHubReleaseSchema,
16692
16699
  GitHubReleaseAssetSchema: () => GitHubReleaseAssetSchema,
16693
16700
  GitHubError: () => GitHubError,
@@ -64573,7 +64580,7 @@ var package_default;
64573
64580
  var init_package = __esm(() => {
64574
64581
  package_default = {
64575
64582
  name: "claudekit-cli",
64576
- version: "4.5.0-dev.8",
64583
+ version: "4.5.0-dev.9",
64577
64584
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
64578
64585
  type: "module",
64579
64586
  repository: {
@@ -66815,36 +66822,148 @@ class CodexPluginInstaller {
66815
66822
  return this.run(["plugin", "list"], this.opts(15000));
66816
66823
  }
66817
66824
  async verifyInstalled() {
66818
- const r2 = await this.listJson();
66819
- if (!r2.ok) {
66820
- const text = await this.listText();
66821
- return text.ok && parseTextPluginList(text.stdout + text.stderr);
66822
- }
66823
- try {
66824
- const parsed = JSON.parse(r2.stdout);
66825
- return (parsed.installed ?? []).some((plugin) => plugin.pluginId === `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}` && plugin.installed === true && plugin.enabled === true);
66826
- } catch {
66827
- const text = await this.listText();
66828
- return text.ok && parseTextPluginList(text.stdout + text.stderr);
66829
- }
66825
+ const state = await detectCodexPluginListState(this);
66826
+ return state.status === "installed-current" || state.status === "installed-stale-version" || state.status === "installed-stale-source";
66830
66827
  }
66831
66828
  }
66829
+ function createState(status, entry, options2 = {}, error) {
66830
+ const pluginId = `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`;
66831
+ return {
66832
+ status,
66833
+ pluginId,
66834
+ enabled: entry?.enabled ?? false,
66835
+ installed: entry?.installed ?? false,
66836
+ installedVersion: entry?.version ?? null,
66837
+ expectedVersion: options2.expectedVersion ?? null,
66838
+ marketplace: entry?.marketplace ?? null,
66839
+ expectedMarketplace: options2.expectedMarketplace ?? CK_MARKETPLACE_NAME,
66840
+ source: entry?.source ?? null,
66841
+ expectedSource: options2.expectedSource ?? null,
66842
+ shouldRefresh: status === "missing" || status === "disabled" || status === "installed-stale-version" || status === "installed-stale-source",
66843
+ ...error ? { error } : {}
66844
+ };
66845
+ }
66846
+ function classifyCodexPluginEntry(entry, options2 = {}) {
66847
+ if (!entry)
66848
+ return createState("missing", null, options2);
66849
+ if (!entry.enabled || !entry.installed)
66850
+ return createState("disabled", entry, options2);
66851
+ const expectedMarketplace = options2.expectedMarketplace ?? CK_MARKETPLACE_NAME;
66852
+ if (entry.marketplace && entry.marketplace !== expectedMarketplace) {
66853
+ return createState("installed-stale-source", entry, options2);
66854
+ }
66855
+ if (options2.expectedSource && entry.source && entry.source !== options2.expectedSource) {
66856
+ return createState("installed-stale-source", entry, options2);
66857
+ }
66858
+ if (options2.expectedVersion && entry.version && !versionsMatch(entry.version, options2.expectedVersion)) {
66859
+ return createState("installed-stale-version", entry, options2);
66860
+ }
66861
+ return createState("installed-current", entry, options2);
66862
+ }
66832
66863
  function parseTextPluginList(output2) {
66833
66864
  const pluginId = `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
66834
- const row = new RegExp(`^\\s*${pluginId}\\s+.*\\binstalled\\b.*\\benabled\\b`, "im");
66835
- return row.test(output2);
66865
+ const row = new RegExp(`^\\s*(${pluginId})\\s+(.*)$`, "im").exec(output2);
66866
+ if (!row)
66867
+ return null;
66868
+ const details = row[2] ?? "";
66869
+ const versionMatch = details.match(/\b(v?\d+\.\d+\.\d+(?:[-+][^\s]+)?)\b/);
66870
+ return {
66871
+ pluginId: `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`,
66872
+ installed: /\binstalled\b/i.test(details),
66873
+ enabled: /\benabled\b/i.test(details) && !/\bdisabled\b/i.test(details),
66874
+ version: versionMatch?.[1] ?? null,
66875
+ marketplace: CK_MARKETPLACE_NAME,
66876
+ source: null
66877
+ };
66878
+ }
66879
+ function isRecord3(value) {
66880
+ return typeof value === "object" && value !== null && !Array.isArray(value);
66881
+ }
66882
+ function stringField(source, keys) {
66883
+ for (const key of keys) {
66884
+ const value = source[key];
66885
+ if (typeof value === "string" && value.trim() !== "")
66886
+ return value;
66887
+ }
66888
+ return null;
66889
+ }
66890
+ function sourceField(source, keys) {
66891
+ for (const key of keys) {
66892
+ const value = source[key];
66893
+ if (typeof value === "string" && value.trim() !== "")
66894
+ return value;
66895
+ if (isRecord3(value)) {
66896
+ const nested = stringField(value, ["path", "sourcePath", "url"]);
66897
+ if (nested)
66898
+ return nested;
66899
+ }
66900
+ }
66901
+ return null;
66902
+ }
66903
+ function booleanField(source, key, defaultValue) {
66904
+ const value = source[key];
66905
+ return typeof value === "boolean" ? value : defaultValue;
66906
+ }
66907
+ function parseJsonPluginList(output2) {
66908
+ let parsed;
66909
+ try {
66910
+ parsed = JSON.parse(output2);
66911
+ } catch {
66912
+ return null;
66913
+ }
66914
+ const rawEntries = Array.isArray(parsed) ? parsed : isRecord3(parsed) ? parsed.installed ?? parsed.plugins ?? parsed.entries : null;
66915
+ if (!Array.isArray(rawEntries))
66916
+ return null;
66917
+ return rawEntries.flatMap((entry) => {
66918
+ if (!isRecord3(entry))
66919
+ return [];
66920
+ const pluginId = stringField(entry, ["pluginId", "id"]) ?? (stringField(entry, ["name"]) === CK_PLUGIN_NAME ? `${CK_PLUGIN_NAME}@${stringField(entry, ["marketplace", "marketplaceName"]) ?? CK_MARKETPLACE_NAME}` : null);
66921
+ if (pluginId !== `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`)
66922
+ return [];
66923
+ return [
66924
+ {
66925
+ pluginId,
66926
+ installed: booleanField(entry, "installed", true),
66927
+ enabled: booleanField(entry, "enabled", false),
66928
+ version: stringField(entry, ["version", "pluginVersion", "manifestVersion"]),
66929
+ marketplace: stringField(entry, ["marketplace", "marketplaceName"]),
66930
+ source: sourceField(entry, ["source", "path", "sourcePath"])
66931
+ }
66932
+ ];
66933
+ });
66934
+ }
66935
+ async function detectCodexPluginState(installer = new CodexPluginInstaller, options2 = {}) {
66936
+ if (!await installer.isCodexAvailable()) {
66937
+ return createState("codex-unavailable", null, options2);
66938
+ }
66939
+ if (!await installer.isPluginSupported()) {
66940
+ return createState("plugins-unsupported", null, options2);
66941
+ }
66942
+ return detectCodexPluginListState(installer, options2);
66943
+ }
66944
+ async function detectCodexPluginListState(installer, options2 = {}) {
66945
+ const json = await installer.listJson();
66946
+ if (json.ok) {
66947
+ const entries = parseJsonPluginList(json.stdout);
66948
+ if (entries)
66949
+ return classifyCodexPluginEntry(entries[0] ?? null, options2);
66950
+ }
66951
+ const text = await installer.listText();
66952
+ if (text.ok)
66953
+ return classifyCodexPluginEntry(parseTextPluginList(text.stdout + text.stderr), options2);
66954
+ return createState("unknown", null, options2, json.stderr || text.stderr || "codex plugin list failed");
66836
66955
  }
66837
66956
  async function installCodexPlugin(opts) {
66838
66957
  const installer = opts.installer ?? new CodexPluginInstaller(undefined, opts.codexHome);
66839
66958
  if (!await installer.isCodexAvailable() || !await installer.isPluginSupported()) {
66840
66959
  return { action: "skipped-codex-unsupported", pluginVerified: false };
66841
66960
  }
66842
- const added = await installer.marketplaceAdd(opts.pluginSourceDir);
66961
+ const added = await addOrReplaceMarketplace(installer, opts.pluginSourceDir);
66843
66962
  if (!added.ok) {
66844
66963
  return {
66845
66964
  action: "install-failed",
66846
66965
  pluginVerified: false,
66847
- error: `codex marketplace add failed: ${added.stderr.trim()}`
66966
+ error: added.error
66848
66967
  };
66849
66968
  }
66850
66969
  const installed = await installer.add();
@@ -66865,6 +66984,26 @@ async function installCodexPlugin(opts) {
66865
66984
  }
66866
66985
  return { action: "installed", pluginVerified: true };
66867
66986
  }
66987
+ async function addOrReplaceMarketplace(installer, pluginSourceDir) {
66988
+ const added = await installer.marketplaceAdd(pluginSourceDir);
66989
+ if (added.ok)
66990
+ return { ok: true };
66991
+ const error = added.stderr.trim();
66992
+ if (!isReplaceableMarketplaceAddFailure(error)) {
66993
+ return { ok: false, error: `codex marketplace add failed: ${error}` };
66994
+ }
66995
+ await installer.marketplaceRemove(CK_MARKETPLACE_NAME);
66996
+ const readded = await installer.marketplaceAdd(pluginSourceDir);
66997
+ if (readded.ok)
66998
+ return { ok: true };
66999
+ return {
67000
+ ok: false,
67001
+ error: `codex marketplace refresh failed: ${readded.stderr.trim() || error}`
67002
+ };
67003
+ }
67004
+ function isReplaceableMarketplaceAddFailure(error) {
67005
+ return /\balready\b/i.test(error) && /\bmarketplace\b/i.test(error);
67006
+ }
66868
67007
  async function removeCodexPlugin(opts = {}) {
66869
67008
  const installer = opts.installer ?? new CodexPluginInstaller(undefined, opts.codexHome);
66870
67009
  if (!await installer.isCodexAvailable() || !await installer.isPluginSupported()) {
@@ -66872,16 +67011,16 @@ async function removeCodexPlugin(opts = {}) {
66872
67011
  }
66873
67012
  const removed = await installer.remove();
66874
67013
  const marketplaceRemoved = await installer.marketplaceRemove();
67014
+ const state = await detectCodexPluginListState(installer);
66875
67015
  return {
66876
67016
  removed: removed.ok,
66877
- marketplaceRemoved: marketplaceRemoved.ok
67017
+ marketplaceRemoved: marketplaceRemoved.ok,
67018
+ pluginStillInstalled: state.installed,
67019
+ ...state.installed ? { error: `codex plugin still installed after removal (${state.status})` } : {}
66878
67020
  };
66879
67021
  }
66880
- async function shouldRefreshCodexPlugin(installer = new CodexPluginInstaller) {
66881
- if (!await installer.isCodexAvailable() || !await installer.isPluginSupported()) {
66882
- return false;
66883
- }
66884
- return !await installer.verifyInstalled();
67022
+ async function shouldRefreshCodexPlugin(installer = new CodexPluginInstaller, options2 = {}) {
67023
+ return (await detectCodexPluginState(installer, options2)).shouldRefresh;
66885
67024
  }
66886
67025
  var execFileAsync6, DEFAULT_TIMEOUT_MS2 = 120000, defaultCodexRunner = async (args, opts) => {
66887
67026
  const env2 = { ...process.env };
@@ -66916,13 +67055,41 @@ var execFileAsync6, DEFAULT_TIMEOUT_MS2 = 120000, defaultCodexRunner = async (ar
66916
67055
  };
66917
67056
  var init_codex_plugin_installer = __esm(() => {
66918
67057
  init_install_mode_detector();
67058
+ init_version_utils();
66919
67059
  execFileAsync6 = promisify9(execFile8);
66920
67060
  });
66921
67061
 
66922
- // src/domains/migration/metadata-migration.ts
67062
+ // src/domains/installation/plugin/install-mode-preference.ts
67063
+ import { readFileSync as readFileSync16 } from "node:fs";
66923
67064
  import { join as join66 } from "node:path";
67065
+ function normalizeInstallModePreference(value) {
67066
+ if (value === "auto" || value === "plugin" || value === "legacy")
67067
+ return value;
67068
+ return null;
67069
+ }
67070
+ function readInstallModePreferenceFromMetadata(metadata, kit = "engineer") {
67071
+ return normalizeInstallModePreference(metadata?.kits?.[kit]?.installModePreference);
67072
+ }
67073
+ function resolveInstallModePreferenceForUpdate(metadata, kit) {
67074
+ if (kit !== "engineer")
67075
+ return;
67076
+ return readInstallModePreferenceFromMetadata(metadata, kit) ?? DEFAULT_INSTALL_MODE_PREFERENCE;
67077
+ }
67078
+ function readInstallModePreferenceFromClaudeDir(claudeDir3, kit = "engineer") {
67079
+ try {
67080
+ const parsed = JSON.parse(readFileSync16(join66(claudeDir3, "metadata.json"), "utf-8"));
67081
+ return readInstallModePreferenceFromMetadata(parsed, kit);
67082
+ } catch {
67083
+ return null;
67084
+ }
67085
+ }
67086
+ var DEFAULT_INSTALL_MODE_PREFERENCE = "auto";
67087
+ var init_install_mode_preference = () => {};
67088
+
67089
+ // src/domains/migration/metadata-migration.ts
67090
+ import { join as join67 } from "node:path";
66924
67091
  async function detectMetadataFormat(claudeDir3) {
66925
- const metadataPath = join66(claudeDir3, "metadata.json");
67092
+ const metadataPath = join67(claudeDir3, "metadata.json");
66926
67093
  if (!await import_fs_extra6.pathExists(metadataPath)) {
66927
67094
  return { format: "none", metadata: null, detectedKit: null };
66928
67095
  }
@@ -66974,7 +67141,7 @@ async function migrateToMultiKit(claudeDir3) {
66974
67141
  toFormat: "multi-kit"
66975
67142
  };
66976
67143
  }
66977
- const metadataPath = join66(claudeDir3, "metadata.json");
67144
+ const metadataPath = join67(claudeDir3, "metadata.json");
66978
67145
  const legacy = detection.metadata;
66979
67146
  if (!legacy) {
66980
67147
  return {
@@ -67086,7 +67253,7 @@ var init_metadata_migration = __esm(() => {
67086
67253
  });
67087
67254
 
67088
67255
  // src/services/file-operations/claudekit-scanner.ts
67089
- import { join as join67 } from "node:path";
67256
+ import { join as join68 } from "node:path";
67090
67257
  async function scanClaudeKitDirectory(directoryPath) {
67091
67258
  const counts = {
67092
67259
  agents: 0,
@@ -67100,33 +67267,33 @@ async function scanClaudeKitDirectory(directoryPath) {
67100
67267
  }
67101
67268
  const items = await import_fs_extra7.readdir(directoryPath);
67102
67269
  if (items.includes("agents")) {
67103
- const agentsPath = join67(directoryPath, "agents");
67270
+ const agentsPath = join68(directoryPath, "agents");
67104
67271
  const agentFiles = await import_fs_extra7.readdir(agentsPath);
67105
67272
  counts.agents = agentFiles.filter((file) => file.endsWith(".md")).length;
67106
67273
  }
67107
67274
  if (items.includes("commands")) {
67108
- const commandsPath = join67(directoryPath, "commands");
67275
+ const commandsPath = join68(directoryPath, "commands");
67109
67276
  const commandFiles = await import_fs_extra7.readdir(commandsPath);
67110
67277
  counts.commands = commandFiles.filter((file) => file.endsWith(".md")).length;
67111
67278
  }
67112
67279
  if (items.includes("rules")) {
67113
- const rulesPath = join67(directoryPath, "rules");
67280
+ const rulesPath = join68(directoryPath, "rules");
67114
67281
  const ruleFiles = await import_fs_extra7.readdir(rulesPath);
67115
67282
  counts.rules = ruleFiles.filter((file) => file.endsWith(".md")).length;
67116
67283
  } else if (items.includes("workflows")) {
67117
- const workflowsPath = join67(directoryPath, "workflows");
67284
+ const workflowsPath = join68(directoryPath, "workflows");
67118
67285
  const workflowFiles = await import_fs_extra7.readdir(workflowsPath);
67119
67286
  counts.rules = workflowFiles.filter((file) => file.endsWith(".md")).length;
67120
67287
  }
67121
67288
  if (items.includes("skills")) {
67122
- const skillsPath = join67(directoryPath, "skills");
67289
+ const skillsPath = join68(directoryPath, "skills");
67123
67290
  const skillItems = await import_fs_extra7.readdir(skillsPath);
67124
67291
  let skillCount = 0;
67125
67292
  for (const item of skillItems) {
67126
67293
  if (SKIP_DIRS_CLAUDE_INTERNAL.includes(item)) {
67127
67294
  continue;
67128
67295
  }
67129
- const itemPath = join67(skillsPath, item);
67296
+ const itemPath = join68(skillsPath, item);
67130
67297
  const stat13 = await import_fs_extra7.readdir(itemPath).catch(() => null);
67131
67298
  if (stat13?.includes("SKILL.md")) {
67132
67299
  skillCount++;
@@ -67168,14 +67335,14 @@ async function getClaudeKitSetup(projectDir = process.cwd()) {
67168
67335
  const globalDir = getGlobalInstallDir();
67169
67336
  if (await import_fs_extra7.pathExists(globalDir)) {
67170
67337
  setup.global.path = globalDir;
67171
- setup.global.metadata = await readClaudeKitMetadata(join67(globalDir, "metadata.json"));
67338
+ setup.global.metadata = await readClaudeKitMetadata(join68(globalDir, "metadata.json"));
67172
67339
  setup.global.components = await scanClaudeKitDirectory(globalDir);
67173
67340
  }
67174
- const projectClaudeDir = join67(projectDir, ".claude");
67341
+ const projectClaudeDir = join68(projectDir, ".claude");
67175
67342
  const isLocalSameAsGlobal = projectClaudeDir === globalDir;
67176
67343
  if (!isLocalSameAsGlobal && await import_fs_extra7.pathExists(projectClaudeDir)) {
67177
67344
  setup.project.path = projectClaudeDir;
67178
- setup.project.metadata = await readClaudeKitMetadata(join67(projectClaudeDir, "metadata.json"));
67345
+ setup.project.metadata = await readClaudeKitMetadata(join68(projectClaudeDir, "metadata.json"));
67179
67346
  setup.project.components = await scanClaudeKitDirectory(projectClaudeDir);
67180
67347
  }
67181
67348
  return setup;
@@ -67945,7 +68112,7 @@ var init_error_handler2 = __esm(() => {
67945
68112
  // src/domains/versioning/release-cache.ts
67946
68113
  import { existsSync as existsSync47 } from "node:fs";
67947
68114
  import { mkdir as mkdir18, readFile as readFile37, unlink as unlink8, writeFile as writeFile20 } from "node:fs/promises";
67948
- import { join as join68 } from "node:path";
68115
+ import { join as join69 } from "node:path";
67949
68116
  var ReleaseCacheEntrySchema, ReleaseCache;
67950
68117
  var init_release_cache = __esm(() => {
67951
68118
  init_logger();
@@ -67960,7 +68127,7 @@ var init_release_cache = __esm(() => {
67960
68127
  static CACHE_TTL_SECONDS = Number(process.env.CK_CACHE_TTL) || 3600;
67961
68128
  cacheDir;
67962
68129
  constructor() {
67963
- this.cacheDir = join68(PathResolver.getCacheDir(false), ReleaseCache.CACHE_DIR);
68130
+ this.cacheDir = join69(PathResolver.getCacheDir(false), ReleaseCache.CACHE_DIR);
67964
68131
  }
67965
68132
  async get(key) {
67966
68133
  const cacheFile = this.getCachePath(key);
@@ -68018,7 +68185,7 @@ var init_release_cache = __esm(() => {
68018
68185
  const files = await readdir19(this.cacheDir);
68019
68186
  for (const file of files) {
68020
68187
  if (file.endsWith(".json")) {
68021
- await unlink8(join68(this.cacheDir, file));
68188
+ await unlink8(join69(this.cacheDir, file));
68022
68189
  }
68023
68190
  }
68024
68191
  logger.debug("All release cache cleared");
@@ -68029,7 +68196,7 @@ var init_release_cache = __esm(() => {
68029
68196
  }
68030
68197
  getCachePath(key) {
68031
68198
  const safeKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
68032
- return join68(this.cacheDir, `${safeKey}.json`);
68199
+ return join69(this.cacheDir, `${safeKey}.json`);
68033
68200
  }
68034
68201
  isExpired(timestamp) {
68035
68202
  const now = Date.now();
@@ -68687,7 +68854,7 @@ import { exec as exec2, spawn as spawn2 } from "node:child_process";
68687
68854
  import { existsSync as existsSync48 } from "node:fs";
68688
68855
  import { readdir as readdir19 } from "node:fs/promises";
68689
68856
  import { builtinModules } from "node:module";
68690
- import { dirname as dirname30, join as join69 } from "node:path";
68857
+ import { dirname as dirname30, join as join70 } from "node:path";
68691
68858
  import { promisify as promisify10 } from "node:util";
68692
68859
  function selectKitForUpdate(params) {
68693
68860
  const { hasLocal, hasGlobal, localKits, globalKits } = params;
@@ -68719,7 +68886,7 @@ function selectKitForUpdate(params) {
68719
68886
  };
68720
68887
  }
68721
68888
  async function readMetadataFile(claudeDir3) {
68722
- const metadataPath = join69(claudeDir3, "metadata.json");
68889
+ const metadataPath = join70(claudeDir3, "metadata.json");
68723
68890
  try {
68724
68891
  if (!await import_fs_extra8.pathExists(metadataPath))
68725
68892
  return null;
@@ -68769,7 +68936,7 @@ function collectSettingsHookRegistrations(settings, options2 = {}) {
68769
68936
  return registrations;
68770
68937
  }
68771
68938
  async function readManagedHookNames(claudeDir3) {
68772
- const manifestPath = join69(claudeDir3, "hooks", MANAGED_HOOKS_MANIFEST);
68939
+ const manifestPath = join70(claudeDir3, "hooks", MANAGED_HOOKS_MANIFEST);
68773
68940
  if (!existsSync48(manifestPath))
68774
68941
  return [];
68775
68942
  try {
@@ -68783,7 +68950,7 @@ async function readManagedHookNames(claudeDir3) {
68783
68950
  }
68784
68951
  }
68785
68952
  async function readDisabledHookNames(claudeDir3) {
68786
- const configPath = join69(claudeDir3, ".ck.json");
68953
+ const configPath = join70(claudeDir3, ".ck.json");
68787
68954
  if (!existsSync48(configPath))
68788
68955
  return new Set;
68789
68956
  try {
@@ -68795,7 +68962,7 @@ async function readDisabledHookNames(claudeDir3) {
68795
68962
  }
68796
68963
  }
68797
68964
  async function countMissingCkHookRegistrations(claudeDir3, kit, options2 = {}) {
68798
- const settingsPath = join69(claudeDir3, "settings.json");
68965
+ const settingsPath = join70(claudeDir3, "settings.json");
68799
68966
  if (!existsSync48(settingsPath))
68800
68967
  return 0;
68801
68968
  const managedHooks = await readManagedHookNames(claudeDir3);
@@ -68804,19 +68971,19 @@ async function countMissingCkHookRegistrations(claudeDir3, kit, options2 = {}) {
68804
68971
  const settings = parseJsonContent(await import_fs_extra8.readFile(settingsPath, "utf-8"));
68805
68972
  const liveHookRegistrations = collectSettingsHookRegistrations(settings, options2);
68806
68973
  const disabledHooks = await readDisabledHookNames(claudeDir3);
68807
- const hooksDir = join69(claudeDir3, "hooks");
68974
+ const hooksDir = join70(claudeDir3, "hooks");
68808
68975
  let missing = 0;
68809
68976
  for (const name of managedHooks) {
68810
68977
  if (disabledHooks.has(name))
68811
68978
  continue;
68812
- if (!existsSync48(join69(hooksDir, `${name}.cjs`)))
68979
+ if (!existsSync48(join70(hooksDir, `${name}.cjs`)))
68813
68980
  continue;
68814
68981
  if (!liveHookRegistrations.get(name)?.hasCorrectScope)
68815
68982
  missing++;
68816
68983
  }
68817
68984
  return missing;
68818
68985
  }
68819
- function buildInitCommand(isGlobal, kit, beta, yes, restoreCkHooks) {
68986
+ function buildInitCommand(isGlobal, kit, beta, yes, restoreCkHooks, installMode) {
68820
68987
  const parts = ["ck init"];
68821
68988
  if (isGlobal)
68822
68989
  parts.push("-g");
@@ -68826,6 +68993,8 @@ function buildInitCommand(isGlobal, kit, beta, yes, restoreCkHooks) {
68826
68993
  parts.push("--yes");
68827
68994
  if (restoreCkHooks)
68828
68995
  parts.push("--restore-ck-hooks");
68996
+ if (installMode && isGlobal && kit === "engineer")
68997
+ parts.push(`--install-mode ${installMode}`);
68829
68998
  parts.push("--install-skills");
68830
68999
  if (beta)
68831
69000
  parts.push("--beta");
@@ -68862,7 +69031,7 @@ async function fetchLatestReleaseTag(kit, beta) {
68862
69031
  }
68863
69032
  }
68864
69033
  async function findMissingHookDependencies(claudeDir3) {
68865
- const hooksDir = join69(claudeDir3, "hooks");
69034
+ const hooksDir = join70(claudeDir3, "hooks");
68866
69035
  if (!existsSync48(hooksDir))
68867
69036
  return [];
68868
69037
  const files = await readdir19(hooksDir);
@@ -68873,14 +69042,14 @@ async function findMissingHookDependencies(claudeDir3) {
68873
69042
  ...builtinModules.map((name) => `node:${name}`)
68874
69043
  ]);
68875
69044
  for (const file of cjsFiles) {
68876
- const content = await import_fs_extra8.readFile(join69(hooksDir, file), "utf8");
69045
+ const content = await import_fs_extra8.readFile(join70(hooksDir, file), "utf8");
68877
69046
  const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
68878
69047
  for (let match = requireRegex.exec(content);match; match = requireRegex.exec(content)) {
68879
69048
  const depPath = match[1];
68880
69049
  if (!depPath || nodeBuiltins.has(depPath) || !depPath.startsWith("."))
68881
69050
  continue;
68882
- const resolvedPath = join69(hooksDir, depPath);
68883
- const exists = existsSync48(resolvedPath) || HOOK_DEPENDENCY_EXTENSIONS.some((ext) => existsSync48(resolvedPath + ext)) || existsSync48(join69(resolvedPath, "index.js")) || existsSync48(join69(resolvedPath, "index.cjs")) || existsSync48(join69(resolvedPath, "index.mjs"));
69051
+ const resolvedPath = join70(hooksDir, depPath);
69052
+ const exists = existsSync48(resolvedPath) || HOOK_DEPENDENCY_EXTENSIONS.some((ext) => existsSync48(resolvedPath + ext)) || existsSync48(join70(resolvedPath, "index.js")) || existsSync48(join70(resolvedPath, "index.cjs")) || existsSync48(join70(resolvedPath, "index.mjs"));
68884
69053
  if (!exists)
68885
69054
  missing.push(`${file}: ${depPath}`);
68886
69055
  }
@@ -68897,7 +69066,7 @@ async function promptKitUpdate(beta, yes, deps) {
68897
69066
  const findMissingHookDepsFn = deps?.findMissingHookDependenciesFn ?? findMissingHookDependencies;
68898
69067
  const detectInstallModeFn = deps?.detectInstallModeFn ?? detectInstallMode;
68899
69068
  const hasTrackedPluginSuppliedLegacyFilesFn = deps?.hasTrackedPluginSuppliedLegacyFilesFn ?? hasTrackedPluginSuppliedLegacyFiles;
68900
- const shouldRefreshCodexPluginFn = deps?.shouldRefreshCodexPluginFn ?? shouldRefreshCodexPlugin;
69069
+ const shouldRefreshCodexPluginFn = deps?.shouldRefreshCodexPluginFn ?? ((options2) => shouldRefreshCodexPlugin(undefined, options2));
68901
69070
  const setup = await getSetupFn();
68902
69071
  const hasLocal = !!setup.project.metadata;
68903
69072
  const hasGlobal = !!setup.global.metadata;
@@ -68940,6 +69109,8 @@ async function promptKitUpdate(beta, yes, deps) {
68940
69109
  };
68941
69110
  }
68942
69111
  }
69112
+ let kitVersion = selection.kit ? selection.isGlobal ? globalMetadata?.kits?.[selection.kit]?.version : localMetadata?.kits?.[selection.kit]?.version : undefined;
69113
+ let installModePreference = selection.isGlobal ? resolveInstallModePreferenceForUpdate(globalMetadata, selection.kit) : undefined;
68943
69114
  const selectedClaudeDir = selection.isGlobal ? setup.global.path : setup.project.path;
68944
69115
  if (selectedClaudeDir) {
68945
69116
  try {
@@ -68963,13 +69134,20 @@ async function promptKitUpdate(beta, yes, deps) {
68963
69134
  try {
68964
69135
  if (selection.isGlobal && selection.kit === "engineer") {
68965
69136
  const installMode = detectInstallModeFn(selectedClaudeDir);
68966
- const needsPluginMigration = installMode.mode === "legacy" || installMode.mode === "mixed" && hasTrackedPluginSuppliedLegacyFilesFn(selectedClaudeDir);
68967
- if (needsPluginMigration) {
68968
- logger.warning(`Detected ${installMode.mode} global Engineer install; migrating to plugin format`);
68969
- forceKitReinstall = true;
69137
+ if (installModePreference === "legacy") {
69138
+ if (installMode.plugin.installed || installMode.plugin.staleCache) {
69139
+ logger.warning("Detected plugin state for legacy global Engineer preference; reinstalling legacy mode");
69140
+ forceKitReinstall = true;
69141
+ }
69142
+ } else {
69143
+ const needsPluginMigration = installMode.mode === "legacy" || installMode.mode === "mixed" && hasTrackedPluginSuppliedLegacyFilesFn(selectedClaudeDir);
69144
+ if (needsPluginMigration) {
69145
+ logger.warning(`Detected ${installMode.mode} global Engineer install; migrating to plugin format`);
69146
+ forceKitReinstall = true;
69147
+ }
68970
69148
  }
68971
- if (await shouldRefreshCodexPluginFn()) {
68972
- logger.warning("Detected missing Codex ClaudeKit plugin; reinstalling global Engineer content");
69149
+ if (installModePreference !== "legacy" && await shouldRefreshCodexPluginFn({ expectedVersion: kitVersion })) {
69150
+ logger.warning("Detected Codex ClaudeKit plugin state requiring refresh; reinstalling global Engineer content");
68973
69151
  forceKitReinstall = true;
68974
69152
  }
68975
69153
  }
@@ -68977,7 +69155,6 @@ async function promptKitUpdate(beta, yes, deps) {
68977
69155
  logger.verbose(`Plugin install-mode self-heal check skipped: ${error instanceof Error ? error.message : "unknown"}`);
68978
69156
  }
68979
69157
  }
68980
- let kitVersion = selection.kit ? selection.isGlobal ? globalMetadata?.kits?.[selection.kit]?.version : localMetadata?.kits?.[selection.kit]?.version : undefined;
68981
69158
  const isBetaInstalled = isBetaVersion(kitVersion);
68982
69159
  const promptMessage = selection.promptMessage;
68983
69160
  if (selection.kit && kitVersion) {
@@ -69022,6 +69199,7 @@ async function promptKitUpdate(beta, yes, deps) {
69022
69199
  promptMessage: `Update local project ClaudeKit content${localKits[0] || selection.kit ? ` (${localKits[0] || selection.kit})` : ""}?`
69023
69200
  };
69024
69201
  kitVersion = selection.kit ? localMetadata?.kits?.[selection.kit]?.version : undefined;
69202
+ installModePreference = undefined;
69025
69203
  }
69026
69204
  }
69027
69205
  } catch (error) {
@@ -69051,7 +69229,7 @@ async function promptKitUpdate(beta, yes, deps) {
69051
69229
  }
69052
69230
  const useBeta = beta || isBetaInstalled;
69053
69231
  if (yes) {
69054
- const initCmd = buildInitCommand(selection.isGlobal, selection.kit, useBeta, true, forceKitReinstall);
69232
+ const initCmd = buildInitCommand(selection.isGlobal, selection.kit, useBeta, true, forceKitReinstall, installModePreference);
69055
69233
  logger.info(`Running: ${initCmd}`);
69056
69234
  const s = (deps?.spinnerFn ?? de)();
69057
69235
  s.start("Updating ClaudeKit content...");
@@ -69073,6 +69251,9 @@ async function promptKitUpdate(beta, yes, deps) {
69073
69251
  } catch (error) {
69074
69252
  s.stop("Kit update finished");
69075
69253
  const errorMsg = error instanceof Error ? error.message : "unknown";
69254
+ if (installModePreference === "plugin") {
69255
+ throw new StrictPluginUpdateError(`Strict plugin kit update failed: ${errorMsg}`);
69256
+ }
69076
69257
  if (errorMsg.includes("exit code") && !errorMsg.includes("exit code 0")) {
69077
69258
  logger.warning("Kit content update may have encountered issues");
69078
69259
  logger.verbose(`Error: ${errorMsg}`);
@@ -69084,8 +69265,12 @@ async function promptKitUpdate(beta, yes, deps) {
69084
69265
  const args = ["init"];
69085
69266
  if (selection.isGlobal)
69086
69267
  args.push("-g");
69268
+ if (selection.kit)
69269
+ args.push("--kit", selection.kit);
69087
69270
  if (forceKitReinstall)
69088
69271
  args.push("--restore-ck-hooks");
69272
+ if (installModePreference)
69273
+ args.push("--install-mode", installModePreference);
69089
69274
  args.push("--install-skills");
69090
69275
  if (useBeta)
69091
69276
  args.push("--beta");
@@ -69102,10 +69287,15 @@ async function promptKitUpdate(beta, yes, deps) {
69102
69287
  }));
69103
69288
  const exitCode = await spawnFn(args);
69104
69289
  if (exitCode !== 0) {
69290
+ if (installModePreference === "plugin") {
69291
+ throw new StrictPluginUpdateError(`Strict plugin kit update failed with exit code ${exitCode}`);
69292
+ }
69105
69293
  logger.warning("Kit content update may have encountered issues");
69106
69294
  }
69107
69295
  }
69108
69296
  } catch (error) {
69297
+ if (error instanceof StrictPluginUpdateError)
69298
+ throw error;
69109
69299
  logger.verbose(`Failed to prompt for kit update: ${error instanceof Error ? error.message : "unknown error"}`);
69110
69300
  }
69111
69301
  }
@@ -69258,12 +69448,13 @@ async function promptMigrateUpdate(deps) {
69258
69448
  logger.verbose(`Migrate step skipped: ${error instanceof Error ? error.message : "unknown"}`);
69259
69449
  }
69260
69450
  }
69261
- var import_fs_extra8, execAsync2, SAFE_PROVIDER_NAME, HOOK_DEPENDENCY_EXTENSIONS, MANAGED_HOOKS_MANIFEST = "managed-hooks.json";
69451
+ var import_fs_extra8, execAsync2, SAFE_PROVIDER_NAME, HOOK_DEPENDENCY_EXTENSIONS, MANAGED_HOOKS_MANIFEST = "managed-hooks.json", StrictPluginUpdateError;
69262
69452
  var init_post_update_handler = __esm(() => {
69263
69453
  init_ck_config_manager();
69264
69454
  init_hook_health_checker();
69265
69455
  init_codex_plugin_installer();
69266
69456
  init_install_mode_detector();
69457
+ init_install_mode_preference();
69267
69458
  init_metadata_migration();
69268
69459
  init_version_utils();
69269
69460
  init_claudekit_scanner();
@@ -69276,6 +69467,12 @@ var init_post_update_handler = __esm(() => {
69276
69467
  execAsync2 = promisify10(exec2);
69277
69468
  SAFE_PROVIDER_NAME = /^[a-z0-9-]+$/;
69278
69469
  HOOK_DEPENDENCY_EXTENSIONS = [".js", ".cjs", ".mjs", ".json"];
69470
+ StrictPluginUpdateError = class StrictPluginUpdateError extends Error {
69471
+ constructor(message) {
69472
+ super(message);
69473
+ this.name = "StrictPluginUpdateError";
69474
+ }
69475
+ };
69279
69476
  });
69280
69477
 
69281
69478
  // src/commands/update-cli.ts
@@ -69409,7 +69606,7 @@ var init_update_cli = __esm(() => {
69409
69606
 
69410
69607
  // src/domains/sync/config-version-checker.ts
69411
69608
  import { mkdir as mkdir19, readFile as readFile39, unlink as unlink9, writeFile as writeFile21 } from "node:fs/promises";
69412
- import { join as join70 } from "node:path";
69609
+ import { join as join71 } from "node:path";
69413
69610
  function parseCacheTtl() {
69414
69611
  const envValue = process.env.CK_SYNC_CACHE_TTL;
69415
69612
  if (!envValue) {
@@ -69435,11 +69632,11 @@ function parseCacheTtl() {
69435
69632
  class ConfigVersionChecker {
69436
69633
  static getLegacyCacheFilePath(kitType, global3) {
69437
69634
  const cacheDir = PathResolver.getCacheDir(global3);
69438
- return join70(cacheDir, `${kitType}-${CACHE_FILENAME}`);
69635
+ return join71(cacheDir, `${kitType}-${CACHE_FILENAME}`);
69439
69636
  }
69440
69637
  static getCacheFilePath(kitType, global3, channel) {
69441
69638
  const cacheDir = PathResolver.getCacheDir(global3);
69442
- return join70(cacheDir, `${kitType}-${channel}-${CACHE_FILENAME}`);
69639
+ return join71(cacheDir, `${kitType}-${channel}-${CACHE_FILENAME}`);
69443
69640
  }
69444
69641
  static resolveChannel(currentVersion, override) {
69445
69642
  if (override) {
@@ -69675,7 +69872,7 @@ import { execFile as execFile9 } from "node:child_process";
69675
69872
  import { existsSync as existsSync49 } from "node:fs";
69676
69873
  import { readFile as readFile40 } from "node:fs/promises";
69677
69874
  import { cpus, homedir as homedir42, totalmem } from "node:os";
69678
- import { join as join71 } from "node:path";
69875
+ import { join as join72 } from "node:path";
69679
69876
  function runCommand(cmd, args, fallback2) {
69680
69877
  return new Promise((resolve36) => {
69681
69878
  execFile9(cmd, args, { timeout: 5000 }, (err, stdout) => {
@@ -69961,7 +70158,7 @@ async function getPackageJson() {
69961
70158
  }
69962
70159
  async function getKitMetadata2(kitName) {
69963
70160
  try {
69964
- const metadataPath = join71(PathResolver.getGlobalKitDir(), "metadata.json");
70161
+ const metadataPath = join72(PathResolver.getGlobalKitDir(), "metadata.json");
69965
70162
  if (!existsSync49(metadataPath))
69966
70163
  return null;
69967
70164
  const content = await readFile40(metadataPath, "utf-8");
@@ -70119,7 +70316,7 @@ var init_routes = __esm(() => {
70119
70316
 
70120
70317
  // src/domains/web-server/static-server.ts
70121
70318
  import { existsSync as existsSync50 } from "node:fs";
70122
- import { basename as basename24, dirname as dirname31, join as join72, resolve as resolve36 } from "node:path";
70319
+ import { basename as basename24, dirname as dirname31, join as join73, resolve as resolve36 } from "node:path";
70123
70320
  import { fileURLToPath as fileURLToPath2 } from "node:url";
70124
70321
  function addRuntimeUiCandidate(candidates, runtimePath) {
70125
70322
  if (!runtimePath) {
@@ -70131,22 +70328,22 @@ function addRuntimeUiCandidate(candidates, runtimePath) {
70131
70328
  }
70132
70329
  const entryDir = dirname31(resolve36(runtimePath));
70133
70330
  if (basename24(entryDir) === "dist") {
70134
- candidates.add(join72(entryDir, "ui"));
70331
+ candidates.add(join73(entryDir, "ui"));
70135
70332
  }
70136
- candidates.add(join72(entryDir, "..", "dist", "ui"));
70333
+ candidates.add(join73(entryDir, "..", "dist", "ui"));
70137
70334
  }
70138
70335
  function resolveUiDistPath() {
70139
70336
  const candidates = new Set;
70140
70337
  addRuntimeUiCandidate(candidates, process.argv[1]);
70141
- candidates.add(join72(__dirname3, "ui"));
70142
- candidates.add(join72(process.cwd(), "dist", "ui"));
70143
- candidates.add(join72(process.cwd(), "src", "ui", "dist"));
70338
+ candidates.add(join73(__dirname3, "ui"));
70339
+ candidates.add(join73(process.cwd(), "dist", "ui"));
70340
+ candidates.add(join73(process.cwd(), "src", "ui", "dist"));
70144
70341
  for (const path7 of candidates) {
70145
- if (existsSync50(join72(path7, "index.html"))) {
70342
+ if (existsSync50(join73(path7, "index.html"))) {
70146
70343
  return path7;
70147
70344
  }
70148
70345
  }
70149
- return Array.from(candidates)[0] ?? join72(process.cwd(), "dist", "ui");
70346
+ return Array.from(candidates)[0] ?? join73(process.cwd(), "dist", "ui");
70150
70347
  }
70151
70348
  function serveStatic(app) {
70152
70349
  const uiDistPath = resolveUiDistPath();
@@ -70182,7 +70379,7 @@ function serveStatic(app) {
70182
70379
  if (req.path.startsWith("/assets/") || req.path.match(/\.(js|css|ico|png|jpg|svg|woff2?)$/)) {
70183
70380
  return next();
70184
70381
  }
70185
- res.sendFile(join72(uiDistPath, "index.html"), { dotfiles: "allow" });
70382
+ res.sendFile(join73(uiDistPath, "index.html"), { dotfiles: "allow" });
70186
70383
  });
70187
70384
  logger.debug(`Serving static files from ${uiDistPath}`);
70188
70385
  }
@@ -74988,7 +75185,7 @@ var init_process_executor = __esm(() => {
74988
75185
  });
74989
75186
 
74990
75187
  // src/services/package-installer/agy-installer.ts
74991
- import { join as join90 } from "node:path";
75188
+ import { join as join92 } from "node:path";
74992
75189
  async function isAgyInstalled() {
74993
75190
  try {
74994
75191
  await execAsync7("agy --version", { timeout: 1e4 });
@@ -75000,7 +75197,7 @@ async function isAgyInstalled() {
75000
75197
  async function installAgyUnix() {
75001
75198
  const { unlink: unlink13 } = await import("node:fs/promises");
75002
75199
  const { tmpdir: tmpdir4 } = await import("node:os");
75003
- const tempScriptPath = join90(tmpdir4(), "agy-install.sh");
75200
+ const tempScriptPath = join92(tmpdir4(), "agy-install.sh");
75004
75201
  try {
75005
75202
  logger.info("Downloading Antigravity CLI installation script...");
75006
75203
  await execFileAsync7("curl", ["-fsSL", AGY_INSTALL_SH_URL, "-o", tempScriptPath], {
@@ -75072,7 +75269,7 @@ var init_agy_installer = __esm(() => {
75072
75269
  });
75073
75270
 
75074
75271
  // src/services/package-installer/opencode-installer.ts
75075
- import { join as join91 } from "node:path";
75272
+ import { join as join93 } from "node:path";
75076
75273
  async function isOpenCodeInstalled() {
75077
75274
  try {
75078
75275
  await execAsync7("opencode --version", { timeout: 5000 });
@@ -75095,7 +75292,7 @@ async function installOpenCode() {
75095
75292
  logger.info(`Installing ${displayName}...`);
75096
75293
  const { unlink: unlink13 } = await import("node:fs/promises");
75097
75294
  const { tmpdir: tmpdir4 } = await import("node:os");
75098
- const tempScriptPath = join91(tmpdir4(), "opencode-install.sh");
75295
+ const tempScriptPath = join93(tmpdir4(), "opencode-install.sh");
75099
75296
  try {
75100
75297
  logger.info("Downloading OpenCode installation script...");
75101
75298
  await execFileAsync7("curl", ["-fsSL", "https://opencode.ai/install", "-o", tempScriptPath], {
@@ -75330,8 +75527,8 @@ var init_npm_package_manager = __esm(() => {
75330
75527
  });
75331
75528
 
75332
75529
  // src/services/package-installer/install-error-handler.ts
75333
- import { existsSync as existsSync62, readFileSync as readFileSync20, unlinkSync as unlinkSync3 } from "node:fs";
75334
- import { join as join92 } from "node:path";
75530
+ import { existsSync as existsSync62, readFileSync as readFileSync22, unlinkSync as unlinkSync3 } from "node:fs";
75531
+ import { join as join94 } from "node:path";
75335
75532
  function parseNameReason(str2) {
75336
75533
  const colonIndex = str2.indexOf(":");
75337
75534
  if (colonIndex === -1) {
@@ -75394,14 +75591,14 @@ function getSystemPackageCommands(summary, systemFailures) {
75394
75591
  return summary.remediation.sudo_packages ? [summary.remediation.sudo_packages] : [];
75395
75592
  }
75396
75593
  function displayInstallErrors(skillsDir2) {
75397
- const summaryPath = join92(skillsDir2, ".install-error-summary.json");
75594
+ const summaryPath = join94(skillsDir2, ".install-error-summary.json");
75398
75595
  if (!existsSync62(summaryPath)) {
75399
75596
  logger.error("Skills installation failed. Run with --verbose for details.");
75400
75597
  return;
75401
75598
  }
75402
75599
  let summary;
75403
75600
  try {
75404
- summary = JSON.parse(readFileSync20(summaryPath, "utf-8"));
75601
+ summary = JSON.parse(readFileSync22(summaryPath, "utf-8"));
75405
75602
  } catch (parseError) {
75406
75603
  logger.error("Failed to parse error summary. File may be corrupted.");
75407
75604
  logger.debug(`Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
@@ -75493,7 +75690,7 @@ async function checkNeedsSudoPackages() {
75493
75690
  }
75494
75691
  }
75495
75692
  function hasInstallState(skillsDir2) {
75496
- const stateFilePath = join92(skillsDir2, ".install-state.json");
75693
+ const stateFilePath = join94(skillsDir2, ".install-state.json");
75497
75694
  return existsSync62(stateFilePath);
75498
75695
  }
75499
75696
  var WHICH_COMMAND_TIMEOUT_MS = 5000, WINDOWS_SYSTEM_PACKAGES, SYSTEM_TOOL_KEYS, WINDOWS_RSVG_COMMANDS;
@@ -75511,7 +75708,7 @@ var init_install_error_handler = __esm(() => {
75511
75708
  });
75512
75709
 
75513
75710
  // src/services/package-installer/skills-installer.ts
75514
- import { join as join93 } from "node:path";
75711
+ import { join as join95 } from "node:path";
75515
75712
  async function installSkillsDependencies(skillsDir2, options2 = {}) {
75516
75713
  const { skipConfirm = false, withSudo = false } = options2;
75517
75714
  const displayName = "Skills Dependencies";
@@ -75537,7 +75734,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
75537
75734
  const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
75538
75735
  const platform10 = process.platform;
75539
75736
  const scriptName = platform10 === "win32" ? "install.ps1" : "install.sh";
75540
- const scriptPath = join93(skillsDir2, scriptName);
75737
+ const scriptPath = join95(skillsDir2, scriptName);
75541
75738
  try {
75542
75739
  validateScriptPath(skillsDir2, scriptPath);
75543
75740
  } catch (error) {
@@ -75553,7 +75750,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
75553
75750
  logger.warning(`Skills installation script not found: ${scriptPath}`);
75554
75751
  logger.info("");
75555
75752
  logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
75556
- logger.info(` See: ${join93(skillsDir2, "INSTALLATION.md")}`);
75753
+ logger.info(` See: ${join95(skillsDir2, "INSTALLATION.md")}`);
75557
75754
  logger.info("");
75558
75755
  logger.info("Quick start:");
75559
75756
  logger.info(" cd .claude/skills/ai-multimodal/scripts");
@@ -75600,7 +75797,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
75600
75797
  logger.info(` ${platform10 === "win32" ? `powershell -File "${scriptPath}"` : `bash ${scriptPath}`}`);
75601
75798
  logger.info("");
75602
75799
  logger.info("Or see complete guide:");
75603
- logger.info(` ${join93(skillsDir2, "INSTALLATION.md")}`);
75800
+ logger.info(` ${join95(skillsDir2, "INSTALLATION.md")}`);
75604
75801
  return {
75605
75802
  success: false,
75606
75803
  package: displayName,
@@ -75721,7 +75918,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
75721
75918
  logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
75722
75919
  logger.info("");
75723
75920
  logger.info("See complete guide:");
75724
- logger.info(` cat ${join93(skillsDir2, "INSTALLATION.md")}`);
75921
+ logger.info(` cat ${join95(skillsDir2, "INSTALLATION.md")}`);
75725
75922
  logger.info("");
75726
75923
  logger.info("Quick start:");
75727
75924
  logger.info(" cd .claude/skills/ai-multimodal/scripts");
@@ -75767,7 +75964,7 @@ var init_skills_installer2 = __esm(() => {
75767
75964
  // src/services/package-installer/agy-mcp/config-manager.ts
75768
75965
  import { existsSync as existsSync63 } from "node:fs";
75769
75966
  import { mkdir as mkdir23, readFile as readFile49, writeFile as writeFile25 } from "node:fs/promises";
75770
- import { dirname as dirname34, join as join94 } from "node:path";
75967
+ import { dirname as dirname34, join as join96 } from "node:path";
75771
75968
  async function readJsonFile(filePath) {
75772
75969
  try {
75773
75970
  const content = await readFile49(filePath, "utf-8");
@@ -75779,7 +75976,7 @@ async function readJsonFile(filePath) {
75779
75976
  }
75780
75977
  }
75781
75978
  async function addAgyToGitignore(projectDir) {
75782
- const gitignorePath = join94(projectDir, ".gitignore");
75979
+ const gitignorePath = join96(projectDir, ".gitignore");
75783
75980
  try {
75784
75981
  let content = "";
75785
75982
  if (existsSync63(gitignorePath)) {
@@ -75879,12 +76076,12 @@ var init_config_manager2 = __esm(() => {
75879
76076
  // src/services/package-installer/agy-mcp/validation.ts
75880
76077
  import { existsSync as existsSync64, lstatSync, readlinkSync } from "node:fs";
75881
76078
  import { homedir as homedir45 } from "node:os";
75882
- import { join as join95 } from "node:path";
76079
+ import { join as join97 } from "node:path";
75883
76080
  function getGlobalMcpConfigPath() {
75884
- return join95(homedir45(), ".claude", ".mcp.json");
76081
+ return join97(homedir45(), ".claude", ".mcp.json");
75885
76082
  }
75886
76083
  function getLocalMcpConfigPath(projectDir) {
75887
- return join95(projectDir, ".mcp.json");
76084
+ return join97(projectDir, ".mcp.json");
75888
76085
  }
75889
76086
  function findMcpConfigPath(projectDir) {
75890
76087
  const localPath = getLocalMcpConfigPath(projectDir);
@@ -75902,9 +76099,9 @@ function findMcpConfigPath(projectDir) {
75902
76099
  }
75903
76100
  function getAgyMcpConfigPath(projectDir, isGlobal) {
75904
76101
  if (isGlobal) {
75905
- return join95(homedir45(), ".gemini", "config", "mcp_config.json");
76102
+ return join97(homedir45(), ".gemini", "config", "mcp_config.json");
75906
76103
  }
75907
- return join95(projectDir, ".agents", "mcp_config.json");
76104
+ return join97(projectDir, ".agents", "mcp_config.json");
75908
76105
  }
75909
76106
  function checkExistingAgyConfig(projectDir, isGlobal = false) {
75910
76107
  const agyConfigPath = getAgyMcpConfigPath(projectDir, isGlobal);
@@ -75934,7 +76131,7 @@ var init_validation = __esm(() => {
75934
76131
  // src/services/package-installer/agy-mcp/linker-core.ts
75935
76132
  import { existsSync as existsSync65 } from "node:fs";
75936
76133
  import { mkdir as mkdir24, symlink as symlink3 } from "node:fs/promises";
75937
- import { dirname as dirname35, join as join96 } from "node:path";
76134
+ import { dirname as dirname35, join as join98 } from "node:path";
75938
76135
  async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
75939
76136
  const linkDir = dirname35(linkPath);
75940
76137
  if (!existsSync65(linkDir)) {
@@ -75945,7 +76142,7 @@ async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
75945
76142
  if (isGlobal) {
75946
76143
  symlinkTarget = getGlobalMcpConfigPath();
75947
76144
  } else {
75948
- const localMcpPath = join96(projectDir, ".mcp.json");
76145
+ const localMcpPath = join98(projectDir, ".mcp.json");
75949
76146
  const isLocalConfig = targetPath === localMcpPath;
75950
76147
  symlinkTarget = isLocalConfig ? "../.mcp.json" : targetPath;
75951
76148
  }
@@ -78363,9 +78560,9 @@ __export(exports_worktree_manager, {
78363
78560
  });
78364
78561
  import { existsSync as existsSync77 } from "node:fs";
78365
78562
  import { readFile as readFile70, writeFile as writeFile41 } from "node:fs/promises";
78366
- import { join as join160 } from "node:path";
78563
+ import { join as join162 } from "node:path";
78367
78564
  async function createWorktree(projectDir, issueNumber, baseBranch) {
78368
- const worktreePath = join160(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
78565
+ const worktreePath = join162(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
78369
78566
  const branchName = `ck-watch/issue-${issueNumber}`;
78370
78567
  await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
78371
78568
  logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
@@ -78383,7 +78580,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
78383
78580
  return worktreePath;
78384
78581
  }
78385
78582
  async function removeWorktree(projectDir, issueNumber) {
78386
- const worktreePath = join160(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
78583
+ const worktreePath = join162(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
78387
78584
  const branchName = `ck-watch/issue-${issueNumber}`;
78388
78585
  try {
78389
78586
  await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
@@ -78397,7 +78594,7 @@ async function listActiveWorktrees(projectDir) {
78397
78594
  try {
78398
78595
  const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
78399
78596
  const issueNumbers = [];
78400
- const worktreePrefix = join160(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
78597
+ const worktreePrefix = join162(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
78401
78598
  for (const line of output2.split(`
78402
78599
  `)) {
78403
78600
  if (line.startsWith("worktree ")) {
@@ -78425,7 +78622,7 @@ async function cleanupAllWorktrees(projectDir) {
78425
78622
  await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
78426
78623
  }
78427
78624
  async function ensureGitignore(projectDir) {
78428
- const gitignorePath = join160(projectDir, ".gitignore");
78625
+ const gitignorePath = join162(projectDir, ".gitignore");
78429
78626
  try {
78430
78627
  const content = existsSync77(gitignorePath) ? await readFile70(gitignorePath, "utf-8") : "";
78431
78628
  if (!content.includes(".worktrees")) {
@@ -78529,16 +78726,16 @@ var init_content_validator = __esm(() => {
78529
78726
 
78530
78727
  // src/commands/content/phases/context-cache-manager.ts
78531
78728
  import { createHash as createHash11 } from "node:crypto";
78532
- import { existsSync as existsSync83, mkdirSync as mkdirSync7, readFileSync as readFileSync23, readdirSync as readdirSync15, statSync as statSync15 } from "node:fs";
78729
+ import { existsSync as existsSync83, mkdirSync as mkdirSync7, readFileSync as readFileSync25, readdirSync as readdirSync15, statSync as statSync15 } from "node:fs";
78533
78730
  import { rename as rename16, writeFile as writeFile43 } from "node:fs/promises";
78534
78731
  import { homedir as homedir54 } from "node:os";
78535
- import { basename as basename34, join as join167 } from "node:path";
78732
+ import { basename as basename34, join as join169 } from "node:path";
78536
78733
  function getCachedContext(repoPath) {
78537
78734
  const cachePath = getCacheFilePath(repoPath);
78538
78735
  if (!existsSync83(cachePath))
78539
78736
  return null;
78540
78737
  try {
78541
- const raw2 = readFileSync23(cachePath, "utf-8");
78738
+ const raw2 = readFileSync25(cachePath, "utf-8");
78542
78739
  const cache5 = JSON.parse(raw2);
78543
78740
  const age = Date.now() - new Date(cache5.createdAt).getTime();
78544
78741
  if (age >= CACHE_TTL_MS5)
@@ -78575,25 +78772,25 @@ function computeSourceHash(repoPath) {
78575
78772
  }
78576
78773
  function getDocSourcePaths(repoPath) {
78577
78774
  const paths = [];
78578
- const docsDir = join167(repoPath, "docs");
78775
+ const docsDir = join169(repoPath, "docs");
78579
78776
  if (existsSync83(docsDir)) {
78580
78777
  try {
78581
78778
  const files = readdirSync15(docsDir);
78582
78779
  for (const f3 of files) {
78583
78780
  if (f3.endsWith(".md"))
78584
- paths.push(join167(docsDir, f3));
78781
+ paths.push(join169(docsDir, f3));
78585
78782
  }
78586
78783
  } catch {}
78587
78784
  }
78588
- const readme = join167(repoPath, "README.md");
78785
+ const readme = join169(repoPath, "README.md");
78589
78786
  if (existsSync83(readme))
78590
78787
  paths.push(readme);
78591
- const stylesDir = join167(repoPath, "assets", "writing-styles");
78788
+ const stylesDir = join169(repoPath, "assets", "writing-styles");
78592
78789
  if (existsSync83(stylesDir)) {
78593
78790
  try {
78594
78791
  const files = readdirSync15(stylesDir);
78595
78792
  for (const f3 of files) {
78596
- paths.push(join167(stylesDir, f3));
78793
+ paths.push(join169(stylesDir, f3));
78597
78794
  }
78598
78795
  } catch {}
78599
78796
  }
@@ -78602,11 +78799,11 @@ function getDocSourcePaths(repoPath) {
78602
78799
  function getCacheFilePath(repoPath) {
78603
78800
  const repoName = basename34(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
78604
78801
  const pathHash = createHash11("sha256").update(repoPath).digest("hex").slice(0, 8);
78605
- return join167(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
78802
+ return join169(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
78606
78803
  }
78607
78804
  var CACHE_DIR, CACHE_TTL_MS5;
78608
78805
  var init_context_cache_manager = __esm(() => {
78609
- CACHE_DIR = join167(homedir54(), ".claudekit", "cache");
78806
+ CACHE_DIR = join169(homedir54(), ".claudekit", "cache");
78610
78807
  CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
78611
78808
  });
78612
78809
 
@@ -78786,8 +78983,8 @@ function extractContentFromResponse(response) {
78786
78983
 
78787
78984
  // src/commands/content/phases/docs-summarizer.ts
78788
78985
  import { execSync as execSync7 } from "node:child_process";
78789
- import { existsSync as existsSync84, readFileSync as readFileSync24, readdirSync as readdirSync16 } from "node:fs";
78790
- import { join as join168 } from "node:path";
78986
+ import { existsSync as existsSync84, readFileSync as readFileSync26, readdirSync as readdirSync16 } from "node:fs";
78987
+ import { join as join170 } from "node:path";
78791
78988
  async function summarizeProjectDocs(repoPath, contentLogger) {
78792
78989
  const rawContent = collectRawDocs(repoPath);
78793
78990
  if (rawContent.total.length < 200) {
@@ -78835,18 +79032,18 @@ function collectRawDocs(repoPath) {
78835
79032
  return "";
78836
79033
  if (totalChars >= MAX_RAW_CONTENT_CHARS)
78837
79034
  return "";
78838
- const content = readFileSync24(filePath, "utf-8");
79035
+ const content = readFileSync26(filePath, "utf-8");
78839
79036
  const capped = content.slice(0, Math.min(maxChars, MAX_RAW_CONTENT_CHARS - totalChars));
78840
79037
  totalChars += capped.length;
78841
79038
  return capped;
78842
79039
  };
78843
79040
  const docsContent = [];
78844
- const docsDir = join168(repoPath, "docs");
79041
+ const docsDir = join170(repoPath, "docs");
78845
79042
  if (existsSync84(docsDir)) {
78846
79043
  try {
78847
79044
  const files = readdirSync16(docsDir).filter((f3) => f3.endsWith(".md")).sort();
78848
79045
  for (const f3 of files) {
78849
- const content = readCapped(join168(docsDir, f3), 5000);
79046
+ const content = readCapped(join170(docsDir, f3), 5000);
78850
79047
  if (content) {
78851
79048
  docsContent.push(`### ${f3}
78852
79049
  ${content}`);
@@ -78860,21 +79057,21 @@ ${content}`);
78860
79057
  let brand = "";
78861
79058
  const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
78862
79059
  for (const p of brandCandidates) {
78863
- brand = readCapped(join168(repoPath, p), 3000);
79060
+ brand = readCapped(join170(repoPath, p), 3000);
78864
79061
  if (brand)
78865
79062
  break;
78866
79063
  }
78867
79064
  let styles3 = "";
78868
- const stylesDir = join168(repoPath, "assets", "writing-styles");
79065
+ const stylesDir = join170(repoPath, "assets", "writing-styles");
78869
79066
  if (existsSync84(stylesDir)) {
78870
79067
  try {
78871
79068
  const files = readdirSync16(stylesDir).slice(0, 3);
78872
- styles3 = files.map((f3) => readCapped(join168(stylesDir, f3), 1000)).filter(Boolean).join(`
79069
+ styles3 = files.map((f3) => readCapped(join170(stylesDir, f3), 1000)).filter(Boolean).join(`
78873
79070
 
78874
79071
  `);
78875
79072
  } catch {}
78876
79073
  }
78877
- const readme = readCapped(join168(repoPath, "README.md"), 3000);
79074
+ const readme = readCapped(join170(repoPath, "README.md"), 3000);
78878
79075
  const total = [docs, brand, styles3, readme].join(`
78879
79076
  `);
78880
79077
  return { docs, brand, styles: styles3, readme, total };
@@ -79061,9 +79258,9 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
79061
79258
  import { execSync as execSync8 } from "node:child_process";
79062
79259
  import { existsSync as existsSync85, mkdirSync as mkdirSync8, readdirSync as readdirSync17 } from "node:fs";
79063
79260
  import { homedir as homedir55 } from "node:os";
79064
- import { join as join169 } from "node:path";
79261
+ import { join as join171 } from "node:path";
79065
79262
  async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
79066
- const mediaDir = join169(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
79263
+ const mediaDir = join171(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
79067
79264
  if (!existsSync85(mediaDir)) {
79068
79265
  mkdirSync8(mediaDir, { recursive: true });
79069
79266
  }
@@ -79088,7 +79285,7 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
79088
79285
  const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
79089
79286
  if (imageFile) {
79090
79287
  const ext2 = imageFile.split(".").pop() ?? "png";
79091
- return { path: join169(mediaDir, imageFile), ...dimensions, format: ext2 };
79288
+ return { path: join171(mediaDir, imageFile), ...dimensions, format: ext2 };
79092
79289
  }
79093
79290
  contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
79094
79291
  return null;
@@ -79178,7 +79375,7 @@ var init_content_creator = __esm(() => {
79178
79375
  // src/commands/content/phases/content-logger.ts
79179
79376
  import { createWriteStream as createWriteStream4, existsSync as existsSync86, mkdirSync as mkdirSync9, statSync as statSync16 } from "node:fs";
79180
79377
  import { homedir as homedir56 } from "node:os";
79181
- import { join as join170 } from "node:path";
79378
+ import { join as join172 } from "node:path";
79182
79379
 
79183
79380
  class ContentLogger {
79184
79381
  stream = null;
@@ -79186,7 +79383,7 @@ class ContentLogger {
79186
79383
  logDir;
79187
79384
  maxBytes;
79188
79385
  constructor(maxBytes = 0) {
79189
- this.logDir = join170(homedir56(), ".claudekit", "logs");
79386
+ this.logDir = join172(homedir56(), ".claudekit", "logs");
79190
79387
  this.maxBytes = maxBytes;
79191
79388
  }
79192
79389
  init() {
@@ -79218,7 +79415,7 @@ class ContentLogger {
79218
79415
  }
79219
79416
  }
79220
79417
  getLogPath() {
79221
- return join170(this.logDir, `content-${this.getDateStr()}.log`);
79418
+ return join172(this.logDir, `content-${this.getDateStr()}.log`);
79222
79419
  }
79223
79420
  write(level, message) {
79224
79421
  this.rotateIfNeeded();
@@ -79235,18 +79432,18 @@ class ContentLogger {
79235
79432
  if (dateStr !== this.currentDate) {
79236
79433
  this.close();
79237
79434
  this.currentDate = dateStr;
79238
- const logPath = join170(this.logDir, `content-${dateStr}.log`);
79435
+ const logPath = join172(this.logDir, `content-${dateStr}.log`);
79239
79436
  this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
79240
79437
  return;
79241
79438
  }
79242
79439
  if (this.maxBytes > 0 && this.stream) {
79243
- const logPath = join170(this.logDir, `content-${this.currentDate}.log`);
79440
+ const logPath = join172(this.logDir, `content-${this.currentDate}.log`);
79244
79441
  try {
79245
79442
  const stat26 = statSync16(logPath);
79246
79443
  if (stat26.size >= this.maxBytes) {
79247
79444
  this.close();
79248
79445
  const suffix = Date.now();
79249
- const rotatedPath = join170(this.logDir, `content-${this.currentDate}-${suffix}.log`);
79446
+ const rotatedPath = join172(this.logDir, `content-${this.currentDate}-${suffix}.log`);
79250
79447
  import("node:fs/promises").then(({ rename: rename17 }) => rename17(logPath, rotatedPath).catch(() => {}));
79251
79448
  this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
79252
79449
  }
@@ -79516,8 +79713,8 @@ function isNoiseCommit(title, author) {
79516
79713
 
79517
79714
  // src/commands/content/phases/change-detector.ts
79518
79715
  import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
79519
- import { existsSync as existsSync88, readFileSync as readFileSync25, readdirSync as readdirSync18, statSync as statSync17 } from "node:fs";
79520
- import { join as join171 } from "node:path";
79716
+ import { existsSync as existsSync88, readFileSync as readFileSync27, readdirSync as readdirSync18, statSync as statSync17 } from "node:fs";
79717
+ import { join as join173 } from "node:path";
79521
79718
  function detectCommits(repo, since) {
79522
79719
  try {
79523
79720
  const fetchUrl = sshToHttps(repo.remoteUrl);
@@ -79626,7 +79823,7 @@ function detectTags(repo, since) {
79626
79823
  }
79627
79824
  }
79628
79825
  function detectCompletedPlans(repo, since) {
79629
- const plansDir = join171(repo.path, "plans");
79826
+ const plansDir = join173(repo.path, "plans");
79630
79827
  if (!existsSync88(plansDir))
79631
79828
  return [];
79632
79829
  const sinceMs = new Date(since).getTime();
@@ -79636,14 +79833,14 @@ function detectCompletedPlans(repo, since) {
79636
79833
  for (const entry of entries) {
79637
79834
  if (!entry.isDirectory())
79638
79835
  continue;
79639
- const planFile = join171(plansDir, entry.name, "plan.md");
79836
+ const planFile = join173(plansDir, entry.name, "plan.md");
79640
79837
  if (!existsSync88(planFile))
79641
79838
  continue;
79642
79839
  try {
79643
79840
  const stat26 = statSync17(planFile);
79644
79841
  if (stat26.mtimeMs < sinceMs)
79645
79842
  continue;
79646
- const content = readFileSync25(planFile, "utf-8");
79843
+ const content = readFileSync27(planFile, "utf-8");
79647
79844
  const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
79648
79845
  if (!frontmatterMatch)
79649
79846
  continue;
@@ -79714,7 +79911,7 @@ function classifyCommit(event) {
79714
79911
  // src/commands/content/phases/repo-discoverer.ts
79715
79912
  import { execSync as execSync11 } from "node:child_process";
79716
79913
  import { readdirSync as readdirSync19 } from "node:fs";
79717
- import { join as join172 } from "node:path";
79914
+ import { join as join174 } from "node:path";
79718
79915
  function discoverRepos2(cwd2) {
79719
79916
  const repos = [];
79720
79917
  if (isGitRepoRoot(cwd2)) {
@@ -79727,7 +79924,7 @@ function discoverRepos2(cwd2) {
79727
79924
  for (const entry of entries) {
79728
79925
  if (!entry.isDirectory() || entry.name.startsWith("."))
79729
79926
  continue;
79730
- const dirPath = join172(cwd2, entry.name);
79927
+ const dirPath = join174(cwd2, entry.name);
79731
79928
  if (isGitRepoRoot(dirPath)) {
79732
79929
  const info = getRepoInfo(dirPath);
79733
79930
  if (info)
@@ -80395,9 +80592,9 @@ var init_types6 = __esm(() => {
80395
80592
 
80396
80593
  // src/commands/content/phases/state-manager.ts
80397
80594
  import { readFile as readFile72, rename as rename17, writeFile as writeFile44 } from "node:fs/promises";
80398
- import { join as join173 } from "node:path";
80595
+ import { join as join175 } from "node:path";
80399
80596
  async function loadContentConfig(projectDir) {
80400
- const configPath = join173(projectDir, CK_CONFIG_FILE2);
80597
+ const configPath = join175(projectDir, CK_CONFIG_FILE2);
80401
80598
  try {
80402
80599
  const raw2 = await readFile72(configPath, "utf-8");
80403
80600
  const json = JSON.parse(raw2);
@@ -80407,13 +80604,13 @@ async function loadContentConfig(projectDir) {
80407
80604
  }
80408
80605
  }
80409
80606
  async function saveContentConfig(projectDir, config) {
80410
- const configPath = join173(projectDir, CK_CONFIG_FILE2);
80607
+ const configPath = join175(projectDir, CK_CONFIG_FILE2);
80411
80608
  const json = await readJsonSafe5(configPath);
80412
80609
  json.content = { ...json.content, ...config };
80413
80610
  await atomicWrite3(configPath, json);
80414
80611
  }
80415
80612
  async function loadContentState(projectDir) {
80416
- const configPath = join173(projectDir, CK_CONFIG_FILE2);
80613
+ const configPath = join175(projectDir, CK_CONFIG_FILE2);
80417
80614
  try {
80418
80615
  const raw2 = await readFile72(configPath, "utf-8");
80419
80616
  const json = JSON.parse(raw2);
@@ -80424,7 +80621,7 @@ async function loadContentState(projectDir) {
80424
80621
  }
80425
80622
  }
80426
80623
  async function saveContentState(projectDir, state) {
80427
- const configPath = join173(projectDir, CK_CONFIG_FILE2);
80624
+ const configPath = join175(projectDir, CK_CONFIG_FILE2);
80428
80625
  const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
80429
80626
  for (const key of Object.keys(state.dailyPostCounts)) {
80430
80627
  const dateStr = key.slice(-10);
@@ -80706,7 +80903,7 @@ var init_platform_setup_x = __esm(() => {
80706
80903
 
80707
80904
  // src/commands/content/phases/setup-wizard.ts
80708
80905
  import { existsSync as existsSync89 } from "node:fs";
80709
- import { join as join174 } from "node:path";
80906
+ import { join as join176 } from "node:path";
80710
80907
  async function runSetupWizard2(cwd2, contentLogger) {
80711
80908
  console.log();
80712
80909
  oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
@@ -80774,8 +80971,8 @@ async function showRepoSummary(cwd2) {
80774
80971
  function detectBrandAssets(cwd2, contentLogger) {
80775
80972
  const repos = discoverRepos2(cwd2);
80776
80973
  for (const repo of repos) {
80777
- const hasGuidelines = existsSync89(join174(repo.path, "docs", "brand-guidelines.md"));
80778
- const hasStyles = existsSync89(join174(repo.path, "assets", "writing-styles"));
80974
+ const hasGuidelines = existsSync89(join176(repo.path, "docs", "brand-guidelines.md"));
80975
+ const hasStyles = existsSync89(join176(repo.path, "assets", "writing-styles"));
80779
80976
  if (!hasGuidelines) {
80780
80977
  f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
80781
80978
  contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
@@ -80915,15 +81112,15 @@ __export(exports_content_subcommands, {
80915
81112
  logsContent: () => logsContent,
80916
81113
  approveContentCmd: () => approveContentCmd
80917
81114
  });
80918
- import { existsSync as existsSync91, readFileSync as readFileSync26, unlinkSync as unlinkSync6 } from "node:fs";
81115
+ import { existsSync as existsSync91, readFileSync as readFileSync28, unlinkSync as unlinkSync6 } from "node:fs";
80919
81116
  import { homedir as homedir58 } from "node:os";
80920
- import { join as join175 } from "node:path";
81117
+ import { join as join177 } from "node:path";
80921
81118
  function isDaemonRunning() {
80922
- const lockFile = join175(LOCK_DIR, `${LOCK_NAME2}.lock`);
81119
+ const lockFile = join177(LOCK_DIR, `${LOCK_NAME2}.lock`);
80923
81120
  if (!existsSync91(lockFile))
80924
81121
  return { running: false, pid: null };
80925
81122
  try {
80926
- const pidStr = readFileSync26(lockFile, "utf-8").trim();
81123
+ const pidStr = readFileSync28(lockFile, "utf-8").trim();
80927
81124
  const pid = Number.parseInt(pidStr, 10);
80928
81125
  if (Number.isNaN(pid)) {
80929
81126
  unlinkSync6(lockFile);
@@ -80951,13 +81148,13 @@ async function startContent(options2) {
80951
81148
  await contentCommand(options2);
80952
81149
  }
80953
81150
  async function stopContent() {
80954
- const lockFile = join175(LOCK_DIR, `${LOCK_NAME2}.lock`);
81151
+ const lockFile = join177(LOCK_DIR, `${LOCK_NAME2}.lock`);
80955
81152
  if (!existsSync91(lockFile)) {
80956
81153
  logger.info("Content daemon is not running.");
80957
81154
  return;
80958
81155
  }
80959
81156
  try {
80960
- const pidStr = readFileSync26(lockFile, "utf-8").trim();
81157
+ const pidStr = readFileSync28(lockFile, "utf-8").trim();
80961
81158
  const pid = Number.parseInt(pidStr, 10);
80962
81159
  if (!Number.isNaN(pid)) {
80963
81160
  process.kill(pid, "SIGTERM");
@@ -80990,9 +81187,9 @@ async function statusContent() {
80990
81187
  } catch {}
80991
81188
  }
80992
81189
  async function logsContent(options2) {
80993
- const logDir = join175(homedir58(), ".claudekit", "logs");
81190
+ const logDir = join177(homedir58(), ".claudekit", "logs");
80994
81191
  const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
80995
- const logPath = join175(logDir, `content-${dateStr}.log`);
81192
+ const logPath = join177(logDir, `content-${dateStr}.log`);
80996
81193
  if (!existsSync91(logPath)) {
80997
81194
  logger.info("No content logs found for today.");
80998
81195
  return;
@@ -81005,7 +81202,7 @@ async function logsContent(options2) {
81005
81202
  process.exit(0);
81006
81203
  });
81007
81204
  } else {
81008
- const content = readFileSync26(logPath, "utf-8");
81205
+ const content = readFileSync28(logPath, "utf-8");
81009
81206
  console.log(content);
81010
81207
  }
81011
81208
  }
@@ -81024,13 +81221,13 @@ var init_content_subcommands = __esm(() => {
81024
81221
  init_setup_wizard();
81025
81222
  init_state_manager();
81026
81223
  init_content_review_commands();
81027
- LOCK_DIR = join175(homedir58(), ".claudekit", "locks");
81224
+ LOCK_DIR = join177(homedir58(), ".claudekit", "locks");
81028
81225
  });
81029
81226
 
81030
81227
  // src/commands/content/content-command.ts
81031
81228
  import { existsSync as existsSync92, mkdirSync as mkdirSync11, unlinkSync as unlinkSync7, writeFileSync as writeFileSync9 } from "node:fs";
81032
81229
  import { homedir as homedir59 } from "node:os";
81033
- import { join as join176 } from "node:path";
81230
+ import { join as join178 } from "node:path";
81034
81231
  async function contentCommand(options2) {
81035
81232
  const cwd2 = process.cwd();
81036
81233
  const contentLogger = new ContentLogger;
@@ -81208,8 +81405,8 @@ var init_content_command = __esm(() => {
81208
81405
  init_publisher();
81209
81406
  init_review_manager();
81210
81407
  init_state_manager();
81211
- LOCK_DIR2 = join176(homedir59(), ".claudekit", "locks");
81212
- LOCK_FILE = join176(LOCK_DIR2, "ck-content.lock");
81408
+ LOCK_DIR2 = join178(homedir59(), ".claudekit", "locks");
81409
+ LOCK_FILE = join178(LOCK_DIR2, "ck-content.lock");
81213
81410
  });
81214
81411
 
81215
81412
  // src/commands/content/index.ts
@@ -88384,7 +88581,7 @@ import { promisify as promisify14 } from "node:util";
88384
88581
  // src/domains/github/gh-cli-utils.ts
88385
88582
  init_environment();
88386
88583
  init_logger();
88387
- import { readFileSync as readFileSync16 } from "node:fs";
88584
+ import { readFileSync as readFileSync17 } from "node:fs";
88388
88585
  var MIN_GH_CLI_VERSION = "2.20.0";
88389
88586
  var GH_COMMAND_TIMEOUT_MS = 1e4;
88390
88587
  function compareVersions6(a3, b3) {
@@ -88405,7 +88602,7 @@ function isWSL2() {
88405
88602
  if (process.platform !== "linux")
88406
88603
  return false;
88407
88604
  try {
88408
- const release = readFileSync16("/proc/version", "utf-8").toLowerCase();
88605
+ const release = readFileSync17("/proc/version", "utf-8").toLowerCase();
88409
88606
  return release.includes("microsoft") || release.includes("wsl");
88410
88607
  } catch (error) {
88411
88608
  logger.debug(`WSL detection skipped: ${error instanceof Error ? error.message : "unknown error"}`);
@@ -89169,14 +89366,14 @@ async function checkCliInstallMethod() {
89169
89366
  }
89170
89367
  // src/domains/health-checks/checkers/claude-md-checker.ts
89171
89368
  import { existsSync as existsSync52, statSync as statSync11 } from "node:fs";
89172
- import { join as join73 } from "node:path";
89369
+ import { join as join74 } from "node:path";
89173
89370
  function checkClaudeMd(setup, projectDir) {
89174
89371
  const results = [];
89175
89372
  if (setup.global.path) {
89176
- const globalClaudeMd = join73(setup.global.path, "CLAUDE.md");
89373
+ const globalClaudeMd = join74(setup.global.path, "CLAUDE.md");
89177
89374
  results.push(checkClaudeMdFile(globalClaudeMd, "Global CLAUDE.md", "ck-global-claude-md"));
89178
89375
  }
89179
- const projectClaudeMd = join73(projectDir, ".claude", "CLAUDE.md");
89376
+ const projectClaudeMd = join74(projectDir, ".claude", "CLAUDE.md");
89180
89377
  results.push(checkClaudeMdFile(projectClaudeMd, "Project CLAUDE.md", "ck-project-claude-md"));
89181
89378
  return results;
89182
89379
  }
@@ -89234,10 +89431,10 @@ function checkClaudeMdFile(path7, name, id) {
89234
89431
  }
89235
89432
  }
89236
89433
  // src/domains/health-checks/checkers/active-plan-checker.ts
89237
- import { existsSync as existsSync53, readFileSync as readFileSync18 } from "node:fs";
89238
- import { join as join74 } from "node:path";
89434
+ import { existsSync as existsSync53, readFileSync as readFileSync19 } from "node:fs";
89435
+ import { join as join75 } from "node:path";
89239
89436
  function checkActivePlan(projectDir) {
89240
- const activePlanPath = join74(projectDir, ".claude", "active-plan");
89437
+ const activePlanPath = join75(projectDir, ".claude", "active-plan");
89241
89438
  if (!existsSync53(activePlanPath)) {
89242
89439
  return {
89243
89440
  id: "ck-active-plan",
@@ -89250,8 +89447,8 @@ function checkActivePlan(projectDir) {
89250
89447
  };
89251
89448
  }
89252
89449
  try {
89253
- const targetPath = readFileSync18(activePlanPath, "utf-8").trim();
89254
- const fullPath = join74(projectDir, targetPath);
89450
+ const targetPath = readFileSync19(activePlanPath, "utf-8").trim();
89451
+ const fullPath = join75(projectDir, targetPath);
89255
89452
  if (!existsSync53(fullPath)) {
89256
89453
  return {
89257
89454
  id: "ck-active-plan",
@@ -89289,13 +89486,13 @@ function checkActivePlan(projectDir) {
89289
89486
  }
89290
89487
  // src/domains/health-checks/checkers/skills-checker.ts
89291
89488
  import { existsSync as existsSync54 } from "node:fs";
89292
- import { join as join75 } from "node:path";
89489
+ import { join as join76 } from "node:path";
89293
89490
  function checkSkillsScripts(setup) {
89294
89491
  const results = [];
89295
89492
  const platform8 = process.platform;
89296
89493
  const scriptName = platform8 === "win32" ? "install.ps1" : "install.sh";
89297
89494
  if (setup.global.path) {
89298
- const globalScriptPath = join75(setup.global.path, "skills", scriptName);
89495
+ const globalScriptPath = join76(setup.global.path, "skills", scriptName);
89299
89496
  const hasGlobalScript = existsSync54(globalScriptPath);
89300
89497
  results.push({
89301
89498
  id: "ck-global-skills-script",
@@ -89310,7 +89507,7 @@ function checkSkillsScripts(setup) {
89310
89507
  });
89311
89508
  }
89312
89509
  if (setup.project.metadata) {
89313
- const projectScriptPath = join75(setup.project.path, "skills", scriptName);
89510
+ const projectScriptPath = join76(setup.project.path, "skills", scriptName);
89314
89511
  const hasProjectScript = existsSync54(projectScriptPath);
89315
89512
  results.push({
89316
89513
  id: "ck-project-skills-script",
@@ -89347,13 +89544,13 @@ function checkComponentCounts(setup) {
89347
89544
  }
89348
89545
  // src/domains/health-checks/checkers/skill-budget-checker.ts
89349
89546
  init_path_resolver();
89350
- import { join as join77, resolve as resolve37 } from "node:path";
89547
+ import { join as join78, resolve as resolve37 } from "node:path";
89351
89548
 
89352
89549
  // src/domains/health-checks/checkers/skill-budget-scanner.ts
89353
89550
  var import_gray_matter11 = __toESM(require_gray_matter(), 1);
89354
89551
  import { existsSync as existsSync55 } from "node:fs";
89355
89552
  import { readFile as readFile41, readdir as readdir20 } from "node:fs/promises";
89356
- import { basename as basename25, join as join76, relative as relative17 } from "node:path";
89553
+ import { basename as basename25, join as join77, relative as relative17 } from "node:path";
89357
89554
  var SKIP_DIRS5 = new Set([".git", ".venv", "__pycache__", "node_modules", "scripts", "common"]);
89358
89555
  async function scanSkills2(skillsDir2) {
89359
89556
  if (!existsSync55(skillsDir2))
@@ -89361,7 +89558,7 @@ async function scanSkills2(skillsDir2) {
89361
89558
  const skillDirs = await findSkillDirs(skillsDir2);
89362
89559
  const skills = [];
89363
89560
  for (const dir of skillDirs) {
89364
- const file = join76(dir, "SKILL.md");
89561
+ const file = join77(dir, "SKILL.md");
89365
89562
  try {
89366
89563
  const content = await readFile41(file, "utf8");
89367
89564
  const { data } = import_gray_matter11.default(content, { engines: { javascript: { parse: () => ({}) } } });
@@ -89387,8 +89584,8 @@ async function findSkillDirs(dir) {
89387
89584
  }
89388
89585
  const results = [];
89389
89586
  for (const entry of entries) {
89390
- const child = join76(dir, entry.name);
89391
- if (existsSync55(join76(child, "SKILL.md"))) {
89587
+ const child = join77(dir, entry.name);
89588
+ if (existsSync55(join77(child, "SKILL.md"))) {
89392
89589
  results.push(child);
89393
89590
  continue;
89394
89591
  }
@@ -89470,12 +89667,12 @@ async function checkSkillBudget(setup, projectDir) {
89470
89667
  const globalClaudeDir = resolve37(PathResolver.getGlobalKitDir());
89471
89668
  const projectScopeAliasesGlobal = projectClaudeDir === globalClaudeDir;
89472
89669
  const [projectSkills, globalSkills] = await Promise.all([
89473
- projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join77(projectClaudeDir, "skills")),
89474
- scanSkills2(join77(globalClaudeDir, "skills"))
89670
+ projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join78(projectClaudeDir, "skills")),
89671
+ scanSkills2(join78(globalClaudeDir, "skills"))
89475
89672
  ]);
89476
89673
  if (!isEngineerLikeProject(setup, [...projectSkills, ...globalSkills]))
89477
89674
  return [];
89478
- const settingsPath = join77(projectClaudeDir, "settings.json");
89675
+ const settingsPath = join78(projectClaudeDir, "settings.json");
89479
89676
  const settings = await readProjectSettings(settingsPath);
89480
89677
  const activeSkills = [...projectSkills, ...globalSkills];
89481
89678
  const listingSkills = uniqueSkills(activeSkills);
@@ -89633,7 +89830,7 @@ init_logger();
89633
89830
  init_path_resolver();
89634
89831
  init_shared2();
89635
89832
  import { constants as constants2, access as access3, unlink as unlink10, writeFile as writeFile22 } from "node:fs/promises";
89636
- import { join as join78 } from "node:path";
89833
+ import { join as join79 } from "node:path";
89637
89834
  async function checkGlobalDirReadable() {
89638
89835
  const globalDir = PathResolver.getGlobalKitDir();
89639
89836
  if (shouldSkipExpensiveOperations2()) {
@@ -89690,7 +89887,7 @@ async function checkGlobalDirWritable() {
89690
89887
  }
89691
89888
  const timestamp = Date.now();
89692
89889
  const random = Math.random().toString(36).substring(2);
89693
- const testFile = join78(globalDir, `.ck-write-test-${timestamp}-${random}`);
89890
+ const testFile = join79(globalDir, `.ck-write-test-${timestamp}-${random}`);
89694
89891
  try {
89695
89892
  await writeFile22(testFile, "test", { encoding: "utf-8", flag: "wx" });
89696
89893
  } catch (error) {
@@ -89726,7 +89923,7 @@ async function checkGlobalDirWritable() {
89726
89923
  init_path_resolver();
89727
89924
  import { existsSync as existsSync57 } from "node:fs";
89728
89925
  import { readdir as readdir21 } from "node:fs/promises";
89729
- import { join as join79 } from "node:path";
89926
+ import { join as join80 } from "node:path";
89730
89927
 
89731
89928
  // src/domains/health-checks/utils/path-normalizer.ts
89732
89929
  import { normalize as normalize5 } from "node:path";
@@ -89739,8 +89936,8 @@ function normalizePath2(filePath) {
89739
89936
  // src/domains/health-checks/checkers/hooks-checker.ts
89740
89937
  init_shared2();
89741
89938
  async function checkHooksExist(projectDir) {
89742
- const globalHooksDir = join79(PathResolver.getGlobalKitDir(), "hooks");
89743
- const projectHooksDir = join79(projectDir, ".claude", "hooks");
89939
+ const globalHooksDir = join80(PathResolver.getGlobalKitDir(), "hooks");
89940
+ const projectHooksDir = join80(projectDir, ".claude", "hooks");
89744
89941
  const globalExists = existsSync57(globalHooksDir);
89745
89942
  const projectExists = existsSync57(projectHooksDir);
89746
89943
  let hookCount = 0;
@@ -89749,7 +89946,7 @@ async function checkHooksExist(projectDir) {
89749
89946
  const files = await readdir21(globalHooksDir, { withFileTypes: false });
89750
89947
  const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
89751
89948
  hooks.forEach((hook) => {
89752
- const fullPath = join79(globalHooksDir, hook);
89949
+ const fullPath = join80(globalHooksDir, hook);
89753
89950
  checkedFiles.add(normalizePath2(fullPath));
89754
89951
  });
89755
89952
  }
@@ -89759,7 +89956,7 @@ async function checkHooksExist(projectDir) {
89759
89956
  const files = await readdir21(projectHooksDir, { withFileTypes: false });
89760
89957
  const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
89761
89958
  hooks.forEach((hook) => {
89762
- const fullPath = join79(projectHooksDir, hook);
89959
+ const fullPath = join80(projectHooksDir, hook);
89763
89960
  checkedFiles.add(normalizePath2(fullPath));
89764
89961
  });
89765
89962
  }
@@ -89791,10 +89988,10 @@ init_logger();
89791
89988
  init_path_resolver();
89792
89989
  import { existsSync as existsSync58 } from "node:fs";
89793
89990
  import { readFile as readFile43 } from "node:fs/promises";
89794
- import { join as join80 } from "node:path";
89991
+ import { join as join81 } from "node:path";
89795
89992
  async function checkSettingsValid(projectDir) {
89796
- const globalSettings = join80(PathResolver.getGlobalKitDir(), "settings.json");
89797
- const projectSettings = join80(projectDir, ".claude", "settings.json");
89993
+ const globalSettings = join81(PathResolver.getGlobalKitDir(), "settings.json");
89994
+ const projectSettings = join81(projectDir, ".claude", "settings.json");
89798
89995
  const settingsPath = existsSync58(globalSettings) ? globalSettings : existsSync58(projectSettings) ? projectSettings : null;
89799
89996
  if (!settingsPath) {
89800
89997
  return {
@@ -89867,10 +90064,10 @@ init_path_resolver();
89867
90064
  import { existsSync as existsSync59 } from "node:fs";
89868
90065
  import { readFile as readFile44 } from "node:fs/promises";
89869
90066
  import { homedir as homedir43 } from "node:os";
89870
- import { dirname as dirname32, join as join81, normalize as normalize6, resolve as resolve38 } from "node:path";
90067
+ import { dirname as dirname32, join as join82, normalize as normalize6, resolve as resolve38 } from "node:path";
89871
90068
  async function checkPathRefsValid(projectDir) {
89872
- const globalClaudeMd = join81(PathResolver.getGlobalKitDir(), "CLAUDE.md");
89873
- const projectClaudeMd = join81(projectDir, ".claude", "CLAUDE.md");
90069
+ const globalClaudeMd = join82(PathResolver.getGlobalKitDir(), "CLAUDE.md");
90070
+ const projectClaudeMd = join82(projectDir, ".claude", "CLAUDE.md");
89874
90071
  const claudeMdPath = existsSync59(globalClaudeMd) ? globalClaudeMd : existsSync59(projectClaudeMd) ? projectClaudeMd : null;
89875
90072
  if (!claudeMdPath) {
89876
90073
  return {
@@ -89965,7 +90162,7 @@ async function checkPathRefsValid(projectDir) {
89965
90162
  // src/domains/health-checks/checkers/config-completeness-checker.ts
89966
90163
  import { existsSync as existsSync60 } from "node:fs";
89967
90164
  import { readdir as readdir22 } from "node:fs/promises";
89968
- import { join as join82 } from "node:path";
90165
+ import { join as join83 } from "node:path";
89969
90166
  async function checkProjectConfigCompleteness(setup, projectDir) {
89970
90167
  const baseResult = {
89971
90168
  id: "ck-project-config-complete",
@@ -89999,15 +90196,15 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
89999
90196
  suggestion: "Run 'ck init' (choose global or project scope when prompted)"
90000
90197
  };
90001
90198
  }
90002
- const projectClaudeDir = join82(projectDir, ".claude");
90199
+ const projectClaudeDir = join83(projectDir, ".claude");
90003
90200
  const requiredDirs = ["agents", "commands", "skills"];
90004
90201
  const missingDirs = [];
90005
90202
  for (const dir of requiredDirs) {
90006
- if (!existsSync60(join82(projectClaudeDir, dir))) {
90203
+ if (!existsSync60(join83(projectClaudeDir, dir))) {
90007
90204
  missingDirs.push(dir);
90008
90205
  }
90009
90206
  }
90010
- const hasRulesOrWorkflows = existsSync60(join82(projectClaudeDir, "rules")) || existsSync60(join82(projectClaudeDir, "workflows"));
90207
+ const hasRulesOrWorkflows = existsSync60(join83(projectClaudeDir, "rules")) || existsSync60(join83(projectClaudeDir, "workflows"));
90011
90208
  if (!hasRulesOrWorkflows) {
90012
90209
  missingDirs.push("rules");
90013
90210
  }
@@ -90040,7 +90237,7 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
90040
90237
  };
90041
90238
  }
90042
90239
  // src/domains/health-checks/checkers/env-keys-checker.ts
90043
- import { join as join84 } from "node:path";
90240
+ import { join as join85 } from "node:path";
90044
90241
 
90045
90242
  // src/domains/installation/setup-wizard.ts
90046
90243
  init_config_generator();
@@ -90049,7 +90246,7 @@ init_logger();
90049
90246
  init_path_resolver();
90050
90247
  init_dist2();
90051
90248
  var import_fs_extra9 = __toESM(require_lib(), 1);
90052
- import { join as join83 } from "node:path";
90249
+ import { join as join84 } from "node:path";
90053
90250
  var IMAGE_PROVIDER_ENV_KEYS = [
90054
90251
  "GEMINI_API_KEY",
90055
90252
  "OPENROUTER_API_KEY",
@@ -90222,7 +90419,7 @@ function normalizeParsedEnvValue(key, value) {
90222
90419
  return trimmed;
90223
90420
  }
90224
90421
  async function checkGlobalConfig() {
90225
- const globalEnvPath = join83(PathResolver.getGlobalKitDir(), ".env");
90422
+ const globalEnvPath = join84(PathResolver.getGlobalKitDir(), ".env");
90226
90423
  if (!await import_fs_extra9.pathExists(globalEnvPath))
90227
90424
  return false;
90228
90425
  const env2 = await parseEnvFile(globalEnvPath);
@@ -90238,7 +90435,7 @@ async function runSetupWizard(options2) {
90238
90435
  let globalEnv = {};
90239
90436
  const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
90240
90437
  if (!isGlobal) {
90241
- const globalEnvPath = join83(PathResolver.getGlobalKitDir(), ".env");
90438
+ const globalEnvPath = join84(PathResolver.getGlobalKitDir(), ".env");
90242
90439
  if (await import_fs_extra9.pathExists(globalEnvPath)) {
90243
90440
  globalEnv = await parseEnvFile(globalEnvPath);
90244
90441
  }
@@ -90338,7 +90535,7 @@ async function runSetupWizard(options2) {
90338
90535
  f2.info(`Set IMAGE_GEN_PROVIDER=${selectedProvider}`);
90339
90536
  }
90340
90537
  await generateEnvFile(targetDir, values);
90341
- f2.success(`Configuration saved to ${join83(targetDir, ".env")}`);
90538
+ f2.success(`Configuration saved to ${join84(targetDir, ".env")}`);
90342
90539
  return true;
90343
90540
  }
90344
90541
  async function promptForAdditionalGeminiKeys(primaryKey) {
@@ -90433,7 +90630,7 @@ function formatConfiguredProviderMessage(providers2) {
90433
90630
  async function checkEnvKeys(setup) {
90434
90631
  const results = [];
90435
90632
  if (setup.global.path) {
90436
- const globalEnvPath = join84(setup.global.path, ".env");
90633
+ const globalEnvPath = join85(setup.global.path, ".env");
90437
90634
  const globalCheck = await checkRequiredKeysExist(globalEnvPath);
90438
90635
  if (!globalCheck.allPresent) {
90439
90636
  const missingKeys = globalCheck.missing.map((m2) => m2.label).join(", ");
@@ -90462,7 +90659,7 @@ async function checkEnvKeys(setup) {
90462
90659
  }
90463
90660
  }
90464
90661
  if (setup.project.metadata) {
90465
- const projectEnvPath = join84(setup.project.path, ".env");
90662
+ const projectEnvPath = join85(setup.project.path, ".env");
90466
90663
  const projectCheck = await checkRequiredKeysExist(projectEnvPath);
90467
90664
  if (!projectCheck.allPresent) {
90468
90665
  const missingKeys = projectCheck.missing.map((m2) => m2.label).join(", ");
@@ -90566,28 +90763,40 @@ class ClaudekitChecker {
90566
90763
  }
90567
90764
  }
90568
90765
  // src/domains/health-checks/plugin-install-mode-checker.ts
90766
+ init_codex_plugin_installer();
90569
90767
  init_install_mode_detector();
90768
+ init_install_mode_preference();
90769
+ init_path_resolver();
90770
+ import { readFileSync as readFileSync20 } from "node:fs";
90771
+ import { join as join86 } from "node:path";
90570
90772
 
90571
90773
  class PluginInstallModeChecker {
90572
90774
  claudeDir;
90775
+ deps;
90573
90776
  group = "claudekit";
90574
- constructor(claudeDir3) {
90777
+ constructor(claudeDir3, deps = {}) {
90575
90778
  this.claudeDir = claudeDir3;
90779
+ this.deps = deps;
90576
90780
  }
90577
90781
  async run() {
90578
90782
  const r2 = detectInstallMode(this.claudeDir);
90783
+ const readPreference = this.deps.readInstallModePreference ?? readInstallModePreferenceFromClaudeDir;
90784
+ const preference = readPreference(r2.claudeDir) ?? DEFAULT_INSTALL_MODE_PREFERENCE;
90785
+ const codexState = await this.readCodexState(expectedCodexPluginOptions(r2.claudeDir));
90579
90786
  const detail = [];
90787
+ detail.push(`preference: ${preference}`);
90580
90788
  if (r2.plugin.installed) {
90581
90789
  const bits = [r2.plugin.enabled ? "enabled" : "disabled"];
90582
90790
  if (r2.plugin.version)
90583
90791
  bits.push(r2.plugin.version);
90584
90792
  if (r2.plugin.marketplace)
90585
90793
  bits.push(`via ${r2.plugin.marketplace}`);
90586
- detail.push(`plugin: ${bits.join(", ")}`);
90794
+ detail.push(`Claude plugin: ${bits.join(", ")}`);
90587
90795
  }
90588
90796
  if (r2.legacy.installed) {
90589
90797
  detail.push(`legacy copy${r2.legacy.version ? ` (${r2.legacy.version})` : ""}`);
90590
90798
  }
90799
+ detail.push(formatCodexDetail(codexState));
90591
90800
  const suffix = detail.length > 0 ? ` — ${detail.join("; ")}` : "";
90592
90801
  let status = "pass";
90593
90802
  let message = `Install mode: ${r2.mode}${suffix}`;
@@ -90597,9 +90806,18 @@ class PluginInstallModeChecker {
90597
90806
  } else if (r2.mode === "plugin" && !r2.plugin.enabled) {
90598
90807
  status = "warn";
90599
90808
  message = `Install mode: plugin, but the plugin is disabled. Run \`claude plugin enable ck\`.${suffix}`;
90809
+ } else if (preference === "legacy" && (r2.plugin.installed || r2.plugin.staleCache || codexState.installed)) {
90810
+ status = "warn";
90811
+ message = `Install mode: ${r2.mode}, but preference is legacy. Run \`ck init -g --kit engineer --install-mode legacy\`.${suffix}`;
90812
+ } else if (preference === "plugin" && (r2.mode === "legacy" || r2.mode === "fresh" || !r2.plugin.enabled)) {
90813
+ status = "warn";
90814
+ message = `Install mode: ${r2.mode}, but preference is plugin. Run \`ck init -g --kit engineer --install-mode plugin\`.${suffix}`;
90815
+ } else if (codexState.shouldRefresh && preference !== "legacy") {
90816
+ status = "warn";
90817
+ message = `Install mode: ${r2.mode}; Codex plugin requires refresh. Run \`ck update\`.${suffix}`;
90600
90818
  } else if (r2.mode === "fresh") {
90601
90819
  status = "info";
90602
- message = "Install mode: fresh (ClaudeKit Engineer not installed). Run `ck init` to install.";
90820
+ message = `Install mode: fresh (ClaudeKit Engineer not installed). Run \`ck init\` to install.${suffix}`;
90603
90821
  }
90604
90822
  return [
90605
90823
  {
@@ -90612,6 +90830,62 @@ class PluginInstallModeChecker {
90612
90830
  }
90613
90831
  ];
90614
90832
  }
90833
+ async readCodexState(options2) {
90834
+ try {
90835
+ if (this.deps.detectCodexPluginState)
90836
+ return await this.deps.detectCodexPluginState(options2);
90837
+ return await detectCodexPluginState(undefined, options2);
90838
+ } catch (error) {
90839
+ return {
90840
+ status: "unknown",
90841
+ pluginId: "ck@claudekit",
90842
+ enabled: false,
90843
+ installed: false,
90844
+ installedVersion: null,
90845
+ expectedVersion: options2.expectedVersion ?? null,
90846
+ marketplace: null,
90847
+ expectedMarketplace: options2.expectedMarketplace ?? "claudekit",
90848
+ source: null,
90849
+ expectedSource: options2.expectedSource ?? null,
90850
+ shouldRefresh: false,
90851
+ error: error instanceof Error ? error.message : "unknown"
90852
+ };
90853
+ }
90854
+ }
90855
+ }
90856
+ function formatCodexDetail(state) {
90857
+ const bits = [state.status];
90858
+ if (state.installedVersion)
90859
+ bits.push(state.installedVersion);
90860
+ if (state.marketplace)
90861
+ bits.push(`via ${state.marketplace}`);
90862
+ if (state.source)
90863
+ bits.push(`source ${state.source}`);
90864
+ if (state.error)
90865
+ bits.push(state.error);
90866
+ return `Codex plugin: ${bits.join(", ")}`;
90867
+ }
90868
+ function expectedCodexPluginOptions(claudeDir3) {
90869
+ return {
90870
+ expectedVersion: readEngineerKitVersion(claudeDir3),
90871
+ expectedMarketplace: "claudekit",
90872
+ expectedSource: join86(PathResolver.getCacheDir(true), "ck-plugin-source")
90873
+ };
90874
+ }
90875
+ function readEngineerKitVersion(claudeDir3) {
90876
+ try {
90877
+ const parsed = JSON.parse(readFileSync20(join86(claudeDir3, "metadata.json"), "utf-8"));
90878
+ if (!isRecord4(parsed) || !isRecord4(parsed.kits) || !isRecord4(parsed.kits.engineer)) {
90879
+ return null;
90880
+ }
90881
+ const version = parsed.kits.engineer.version;
90882
+ return typeof version === "string" && version.trim() !== "" ? version : null;
90883
+ } catch {
90884
+ return null;
90885
+ }
90886
+ }
90887
+ function isRecord4(value) {
90888
+ return typeof value === "object" && value !== null && !Array.isArray(value);
90615
90889
  }
90616
90890
  // src/domains/health-checks/auth-checker.ts
90617
90891
  init_github_auth();
@@ -90962,7 +91236,7 @@ init_environment();
90962
91236
  init_path_resolver();
90963
91237
  import { constants as constants3, access as access4, mkdir as mkdir21, readFile as readFile46, unlink as unlink11, writeFile as writeFile23 } from "node:fs/promises";
90964
91238
  import { arch as arch2, homedir as homedir44, platform as platform8 } from "node:os";
90965
- import { join as join86, normalize as normalize7 } from "node:path";
91239
+ import { join as join88, normalize as normalize7 } from "node:path";
90966
91240
  function shouldSkipExpensiveOperations4() {
90967
91241
  return shouldSkipExpensiveOperations();
90968
91242
  }
@@ -91053,7 +91327,7 @@ async function checkGlobalDirAccess() {
91053
91327
  autoFixable: false
91054
91328
  };
91055
91329
  }
91056
- const testFile = join86(globalDir, ".ck-doctor-access-test");
91330
+ const testFile = join88(globalDir, ".ck-doctor-access-test");
91057
91331
  try {
91058
91332
  await mkdir21(globalDir, { recursive: true });
91059
91333
  await writeFile23(testFile, "test", "utf-8");
@@ -91131,7 +91405,7 @@ async function checkWSLBoundary() {
91131
91405
  // src/domains/health-checks/platform/windows-checker.ts
91132
91406
  init_path_resolver();
91133
91407
  import { mkdir as mkdir22, symlink as symlink2, unlink as unlink12, writeFile as writeFile24 } from "node:fs/promises";
91134
- import { join as join87 } from "node:path";
91408
+ import { join as join89 } from "node:path";
91135
91409
  async function checkLongPathSupport() {
91136
91410
  if (shouldSkipExpensiveOperations4()) {
91137
91411
  return {
@@ -91183,8 +91457,8 @@ async function checkSymlinkSupport() {
91183
91457
  };
91184
91458
  }
91185
91459
  const testDir = PathResolver.getGlobalKitDir();
91186
- const target = join87(testDir, ".ck-symlink-test-target");
91187
- const link = join87(testDir, ".ck-symlink-test-link");
91460
+ const target = join89(testDir, ".ck-symlink-test-target");
91461
+ const link = join89(testDir, ".ck-symlink-test-link");
91188
91462
  try {
91189
91463
  await mkdir22(testDir, { recursive: true });
91190
91464
  await writeFile24(target, "test", "utf-8");
@@ -91801,9 +92075,9 @@ class AutoHealer {
91801
92075
  }
91802
92076
  // src/domains/health-checks/report-generator.ts
91803
92077
  import { execSync as execSync4, spawnSync as spawnSync6 } from "node:child_process";
91804
- import { readFileSync as readFileSync19, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
92078
+ import { readFileSync as readFileSync21, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
91805
92079
  import { tmpdir as tmpdir3 } from "node:os";
91806
- import { dirname as dirname33, join as join88 } from "node:path";
92080
+ import { dirname as dirname33, join as join90 } from "node:path";
91807
92081
  import { fileURLToPath as fileURLToPath4 } from "node:url";
91808
92082
  init_environment();
91809
92083
  init_logger();
@@ -91811,8 +92085,8 @@ init_dist2();
91811
92085
  function getCliVersion4() {
91812
92086
  try {
91813
92087
  const __dirname4 = dirname33(fileURLToPath4(import.meta.url));
91814
- const pkgPath = join88(__dirname4, "../../../package.json");
91815
- const pkg = JSON.parse(readFileSync19(pkgPath, "utf-8"));
92088
+ const pkgPath = join90(__dirname4, "../../../package.json");
92089
+ const pkg = JSON.parse(readFileSync21(pkgPath, "utf-8"));
91816
92090
  return pkg.version || "unknown";
91817
92091
  } catch (err) {
91818
92092
  logger.debug(`Failed to read CLI version: ${err}`);
@@ -91950,7 +92224,7 @@ class ReportGenerator {
91950
92224
  return null;
91951
92225
  }
91952
92226
  }
91953
- const tmpFile = join88(tmpdir3(), `ck-report-${Date.now()}.txt`);
92227
+ const tmpFile = join90(tmpdir3(), `ck-report-${Date.now()}.txt`);
91954
92228
  writeFileSync6(tmpFile, report);
91955
92229
  try {
91956
92230
  const result = spawnSync6("gh", ["gist", "create", tmpFile, "--desc", "ClaudeKit Diagnostic Report"], {
@@ -92292,7 +92566,7 @@ init_config_version_checker();
92292
92566
 
92293
92567
  // src/domains/sync/sync-engine.ts
92294
92568
  import { lstat as lstat6, readFile as readFile48, readlink as readlink2, realpath as realpath8, stat as stat14 } from "node:fs/promises";
92295
- import { isAbsolute as isAbsolute12, join as join89, normalize as normalize8, relative as relative19 } from "node:path";
92569
+ import { isAbsolute as isAbsolute12, join as join91, normalize as normalize8, relative as relative19 } from "node:path";
92296
92570
 
92297
92571
  // src/services/file-operations/ownership-checker.ts
92298
92572
  init_metadata_migration();
@@ -93507,7 +93781,7 @@ async function validateSymlinkChain(path8, basePath, maxDepth = MAX_SYMLINK_DEPT
93507
93781
  if (!stats.isSymbolicLink())
93508
93782
  break;
93509
93783
  const target = await readlink2(current);
93510
- const resolvedTarget = isAbsolute12(target) ? target : join89(current, "..", target);
93784
+ const resolvedTarget = isAbsolute12(target) ? target : join91(current, "..", target);
93511
93785
  const normalizedTarget = normalize8(resolvedTarget);
93512
93786
  const rel = relative19(basePath, normalizedTarget);
93513
93787
  if (rel.startsWith("..") || isAbsolute12(rel)) {
@@ -93543,7 +93817,7 @@ async function validateSyncPath(basePath, filePath) {
93543
93817
  if (normalized.startsWith("..") || normalized.includes("/../")) {
93544
93818
  throw new Error(`Path traversal not allowed: ${filePath}`);
93545
93819
  }
93546
- const fullPath = join89(basePath, normalized);
93820
+ const fullPath = join91(basePath, normalized);
93547
93821
  const rel = relative19(basePath, fullPath);
93548
93822
  if (rel.startsWith("..") || isAbsolute12(rel)) {
93549
93823
  throw new Error(`Path escapes base directory: ${filePath}`);
@@ -93558,7 +93832,7 @@ async function validateSyncPath(basePath, filePath) {
93558
93832
  }
93559
93833
  } catch (error) {
93560
93834
  if (error.code === "ENOENT") {
93561
- const parentPath = join89(fullPath, "..");
93835
+ const parentPath = join91(fullPath, "..");
93562
93836
  try {
93563
93837
  const resolvedBase = await realpath8(basePath);
93564
93838
  const resolvedParent = await realpath8(parentPath);
@@ -94467,7 +94741,7 @@ async function getLatestVersion(kit, includePrereleases = false) {
94467
94741
  init_logger();
94468
94742
  init_path_resolver();
94469
94743
  init_safe_prompts();
94470
- import { join as join97 } from "node:path";
94744
+ import { join as join99 } from "node:path";
94471
94745
  async function promptUpdateMode() {
94472
94746
  const updateEverything = await se({
94473
94747
  message: "Do you want to update everything?"
@@ -94509,7 +94783,7 @@ async function promptDirectorySelection(global3 = false) {
94509
94783
  return selectedCategories;
94510
94784
  }
94511
94785
  async function promptFreshConfirmation(targetPath, analysis) {
94512
- const backupRoot = join97(PathResolver.getConfigDir(false), "backups");
94786
+ const backupRoot = join99(PathResolver.getConfigDir(false), "backups");
94513
94787
  logger.warning("[!] Fresh installation will remove ClaudeKit files:");
94514
94788
  logger.info(`Path: ${targetPath}`);
94515
94789
  logger.info(`Recovery backup: ${backupRoot}`);
@@ -94786,7 +95060,7 @@ init_logger();
94786
95060
  init_logger();
94787
95061
  init_path_resolver();
94788
95062
  var import_fs_extra10 = __toESM(require_lib(), 1);
94789
- import { join as join98 } from "node:path";
95063
+ import { join as join100 } from "node:path";
94790
95064
  async function handleConflicts(ctx) {
94791
95065
  if (ctx.cancelled)
94792
95066
  return ctx;
@@ -94795,7 +95069,7 @@ async function handleConflicts(ctx) {
94795
95069
  if (PathResolver.isLocalSameAsGlobal()) {
94796
95070
  return ctx;
94797
95071
  }
94798
- const localSettingsPath = join98(process.cwd(), ".claude", "settings.json");
95072
+ const localSettingsPath = join100(process.cwd(), ".claude", "settings.json");
94799
95073
  if (!await import_fs_extra10.pathExists(localSettingsPath)) {
94800
95074
  return ctx;
94801
95075
  }
@@ -94810,7 +95084,7 @@ async function handleConflicts(ctx) {
94810
95084
  return { ...ctx, cancelled: true };
94811
95085
  }
94812
95086
  if (choice === "remove") {
94813
- const localClaudeDir = join98(process.cwd(), ".claude");
95087
+ const localClaudeDir = join100(process.cwd(), ".claude");
94814
95088
  try {
94815
95089
  await import_fs_extra10.remove(localClaudeDir);
94816
95090
  logger.success("Removed local .claude/ directory");
@@ -94907,7 +95181,7 @@ init_logger();
94907
95181
  init_safe_spinner();
94908
95182
  import { mkdir as mkdir30, stat as stat17 } from "node:fs/promises";
94909
95183
  import { tmpdir as tmpdir4 } from "node:os";
94910
- import { join as join105 } from "node:path";
95184
+ import { join as join107 } from "node:path";
94911
95185
 
94912
95186
  // src/shared/temp-cleanup.ts
94913
95187
  init_logger();
@@ -94926,7 +95200,7 @@ init_logger();
94926
95200
  init_output_manager();
94927
95201
  import { createWriteStream as createWriteStream2, rmSync } from "node:fs";
94928
95202
  import { mkdir as mkdir25 } from "node:fs/promises";
94929
- import { join as join99 } from "node:path";
95203
+ import { join as join101 } from "node:path";
94930
95204
 
94931
95205
  // src/shared/progress-bar.ts
94932
95206
  init_output_manager();
@@ -95136,7 +95410,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
95136
95410
  class FileDownloader {
95137
95411
  async downloadAsset(asset, destDir) {
95138
95412
  try {
95139
- const destPath = join99(destDir, asset.name);
95413
+ const destPath = join101(destDir, asset.name);
95140
95414
  await mkdir25(destDir, { recursive: true });
95141
95415
  output.info(`Downloading ${asset.name} (${formatBytes2(asset.size)})...`);
95142
95416
  logger.verbose("Download details", {
@@ -95221,7 +95495,7 @@ class FileDownloader {
95221
95495
  }
95222
95496
  async downloadFile(params) {
95223
95497
  const { url, name, size, destDir, token } = params;
95224
- const destPath = join99(destDir, name);
95498
+ const destPath = join101(destDir, name);
95225
95499
  await mkdir25(destDir, { recursive: true });
95226
95500
  output.info(`Downloading ${name}${size ? ` (${formatBytes2(size)})` : ""}...`);
95227
95501
  const headers = {};
@@ -95307,7 +95581,7 @@ init_logger();
95307
95581
  init_types3();
95308
95582
  import { constants as constants4 } from "node:fs";
95309
95583
  import { access as access5, readdir as readdir23 } from "node:fs/promises";
95310
- import { join as join100 } from "node:path";
95584
+ import { join as join102 } from "node:path";
95311
95585
  async function pathExists11(path8) {
95312
95586
  try {
95313
95587
  await access5(path8, constants4.F_OK);
@@ -95326,7 +95600,7 @@ async function validateExtraction(extractDir) {
95326
95600
  const criticalPaths = [".claude"];
95327
95601
  const missingPaths = [];
95328
95602
  for (const path8 of criticalPaths) {
95329
- if (await pathExists11(join100(extractDir, path8))) {
95603
+ if (await pathExists11(join102(extractDir, path8))) {
95330
95604
  logger.debug(`Found: ${path8}`);
95331
95605
  continue;
95332
95606
  }
@@ -95336,7 +95610,7 @@ async function validateExtraction(extractDir) {
95336
95610
  const guidancePaths = ["CLAUDE.md", ".claude/CLAUDE.md", ".claude/rules/CLAUDE.md"];
95337
95611
  let guidancePath = null;
95338
95612
  for (const path8 of guidancePaths) {
95339
- if (await pathExists11(join100(extractDir, path8))) {
95613
+ if (await pathExists11(join102(extractDir, path8))) {
95340
95614
  guidancePath = path8;
95341
95615
  break;
95342
95616
  }
@@ -95361,7 +95635,7 @@ async function validateExtraction(extractDir) {
95361
95635
  // src/domains/installation/extraction/tar-extractor.ts
95362
95636
  init_logger();
95363
95637
  import { copyFile as copyFile4, mkdir as mkdir28, readdir as readdir25, rm as rm11, stat as stat15 } from "node:fs/promises";
95364
- import { join as join103 } from "node:path";
95638
+ import { join as join105 } from "node:path";
95365
95639
 
95366
95640
  // node_modules/@isaacs/fs-minipass/dist/esm/index.js
95367
95641
  import EE from "events";
@@ -101123,7 +101397,7 @@ var mkdirSync4 = (dir, opt) => {
101123
101397
  };
101124
101398
 
101125
101399
  // node_modules/tar/dist/esm/path-reservations.js
101126
- import { join as join101 } from "node:path";
101400
+ import { join as join103 } from "node:path";
101127
101401
 
101128
101402
  // node_modules/tar/dist/esm/normalize-unicode.js
101129
101403
  var normalizeCache = Object.create(null);
@@ -101156,7 +101430,7 @@ var getDirs = (path13) => {
101156
101430
  const dirs = path13.split("/").slice(0, -1).reduce((set, path14) => {
101157
101431
  const s = set[set.length - 1];
101158
101432
  if (s !== undefined) {
101159
- path14 = join101(s, path14);
101433
+ path14 = join103(s, path14);
101160
101434
  }
101161
101435
  set.push(path14 || "/");
101162
101436
  return set;
@@ -101170,7 +101444,7 @@ class PathReservations {
101170
101444
  #running = new Set;
101171
101445
  reserve(paths, fn) {
101172
101446
  paths = isWindows4 ? ["win32 parallelization disabled"] : paths.map((p) => {
101173
- return stripTrailingSlashes(join101(normalizeUnicode(p))).toLowerCase();
101447
+ return stripTrailingSlashes(join103(normalizeUnicode(p))).toLowerCase();
101174
101448
  });
101175
101449
  const dirs = new Set(paths.map((path13) => getDirs(path13)).reduce((a3, b3) => a3.concat(b3)));
101176
101450
  this.#reservations.set(fn, { dirs, paths });
@@ -102230,7 +102504,7 @@ function decodeFilePath(path15) {
102230
102504
  init_logger();
102231
102505
  init_types3();
102232
102506
  import { copyFile as copyFile3, lstat as lstat7, mkdir as mkdir27, readdir as readdir24 } from "node:fs/promises";
102233
- import { join as join102, relative as relative21 } from "node:path";
102507
+ import { join as join104, relative as relative21 } from "node:path";
102234
102508
  async function withRetry(fn, retries = 3) {
102235
102509
  for (let i = 0;i < retries; i++) {
102236
102510
  try {
@@ -102252,8 +102526,8 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
102252
102526
  await mkdir27(destDir, { recursive: true });
102253
102527
  const entries = await readdir24(sourceDir, { encoding: "utf8" });
102254
102528
  for (const entry of entries) {
102255
- const sourcePath = join102(sourceDir, entry);
102256
- const destPath = join102(destDir, entry);
102529
+ const sourcePath = join104(sourceDir, entry);
102530
+ const destPath = join104(destDir, entry);
102257
102531
  const relativePath = relative21(sourceDir, sourcePath);
102258
102532
  if (!isPathSafe(destDir, destPath)) {
102259
102533
  logger.warning(`Skipping unsafe path: ${relativePath}`);
@@ -102280,8 +102554,8 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
102280
102554
  await mkdir27(destDir, { recursive: true });
102281
102555
  const entries = await readdir24(sourceDir, { encoding: "utf8" });
102282
102556
  for (const entry of entries) {
102283
- const sourcePath = join102(sourceDir, entry);
102284
- const destPath = join102(destDir, entry);
102557
+ const sourcePath = join104(sourceDir, entry);
102558
+ const destPath = join104(destDir, entry);
102285
102559
  const relativePath = relative21(sourceDir, sourcePath);
102286
102560
  if (!isPathSafe(destDir, destPath)) {
102287
102561
  logger.warning(`Skipping unsafe path: ${relativePath}`);
@@ -102329,7 +102603,7 @@ class TarExtractor {
102329
102603
  logger.debug(`Root entries: ${entries.join(", ")}`);
102330
102604
  if (entries.length === 1) {
102331
102605
  const rootEntry = entries[0];
102332
- const rootPath = join103(tempExtractDir, rootEntry);
102606
+ const rootPath = join105(tempExtractDir, rootEntry);
102333
102607
  const rootStat = await stat15(rootPath);
102334
102608
  if (rootStat.isDirectory()) {
102335
102609
  const rootContents = await readdir25(rootPath, { encoding: "utf8" });
@@ -102345,7 +102619,7 @@ class TarExtractor {
102345
102619
  }
102346
102620
  } else {
102347
102621
  await mkdir28(destDir, { recursive: true });
102348
- await copyFile4(rootPath, join103(destDir, rootEntry));
102622
+ await copyFile4(rootPath, join105(destDir, rootEntry));
102349
102623
  }
102350
102624
  } else {
102351
102625
  logger.debug("Multiple root entries - moving all");
@@ -102367,7 +102641,7 @@ init_logger();
102367
102641
  var import_extract_zip = __toESM(require_extract_zip(), 1);
102368
102642
  import { execFile as execFile11 } from "node:child_process";
102369
102643
  import { copyFile as copyFile5, mkdir as mkdir29, readdir as readdir26, rm as rm12, stat as stat16 } from "node:fs/promises";
102370
- import { join as join104 } from "node:path";
102644
+ import { join as join106 } from "node:path";
102371
102645
  import { promisify as promisify16 } from "node:util";
102372
102646
 
102373
102647
  // src/domains/installation/extraction/native-zip-commands.ts
@@ -102459,7 +102733,7 @@ class ZipExtractor {
102459
102733
  logger.debug(`Root entries: ${entries.join(", ")}`);
102460
102734
  if (entries.length === 1) {
102461
102735
  const rootEntry = entries[0];
102462
- const rootPath = join104(tempExtractDir, rootEntry);
102736
+ const rootPath = join106(tempExtractDir, rootEntry);
102463
102737
  const rootStat = await stat16(rootPath);
102464
102738
  if (rootStat.isDirectory()) {
102465
102739
  const rootContents = await readdir26(rootPath, { encoding: "utf8" });
@@ -102475,7 +102749,7 @@ class ZipExtractor {
102475
102749
  }
102476
102750
  } else {
102477
102751
  await mkdir29(destDir, { recursive: true });
102478
- await copyFile5(rootPath, join104(destDir, rootEntry));
102752
+ await copyFile5(rootPath, join106(destDir, rootEntry));
102479
102753
  }
102480
102754
  } else {
102481
102755
  logger.debug("Multiple root entries - moving all");
@@ -102576,7 +102850,7 @@ class DownloadManager {
102576
102850
  async createTempDir() {
102577
102851
  const timestamp = Date.now();
102578
102852
  const counter = DownloadManager.tempDirCounter++;
102579
- const primaryTempDir = join105(tmpdir4(), `claudekit-${timestamp}-${counter}`);
102853
+ const primaryTempDir = join107(tmpdir4(), `claudekit-${timestamp}-${counter}`);
102580
102854
  try {
102581
102855
  await mkdir30(primaryTempDir, { recursive: true });
102582
102856
  logger.debug(`Created temp directory: ${primaryTempDir}`);
@@ -102593,7 +102867,7 @@ Solutions:
102593
102867
  2. Set HOME environment variable
102594
102868
  3. Try running from a different directory`);
102595
102869
  }
102596
- const fallbackTempDir = join105(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
102870
+ const fallbackTempDir = join107(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
102597
102871
  try {
102598
102872
  await mkdir30(fallbackTempDir, { recursive: true });
102599
102873
  logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
@@ -103053,20 +103327,20 @@ async function handleDownload(ctx) {
103053
103327
  };
103054
103328
  }
103055
103329
  // src/commands/init/phases/merge-handler.ts
103056
- import { join as join123 } from "node:path";
103330
+ import { join as join125 } from "node:path";
103057
103331
 
103058
103332
  // src/domains/installation/deletion-handler.ts
103059
103333
  import { existsSync as existsSync66, lstatSync as lstatSync3, readdirSync as readdirSync10, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync4 } from "node:fs";
103060
- import { dirname as dirname38, join as join108, relative as relative22, resolve as resolve43, sep as sep12 } from "node:path";
103334
+ import { dirname as dirname38, join as join110, relative as relative22, resolve as resolve43, sep as sep12 } from "node:path";
103061
103335
 
103062
103336
  // src/services/file-operations/manifest/manifest-reader.ts
103063
103337
  init_metadata_migration();
103064
103338
  init_logger();
103065
103339
  init_types3();
103066
103340
  var import_fs_extra11 = __toESM(require_lib(), 1);
103067
- import { join as join107 } from "node:path";
103341
+ import { join as join109 } from "node:path";
103068
103342
  async function readManifest(claudeDir3) {
103069
- const metadataPath = join107(claudeDir3, "metadata.json");
103343
+ const metadataPath = join109(claudeDir3, "metadata.json");
103070
103344
  if (!await import_fs_extra11.pathExists(metadataPath)) {
103071
103345
  return null;
103072
103346
  }
@@ -103252,7 +103526,7 @@ function collectFilesRecursively(dir, baseDir) {
103252
103526
  try {
103253
103527
  const entries = readdirSync10(dir, { withFileTypes: true });
103254
103528
  for (const entry of entries) {
103255
- const fullPath = join108(dir, entry.name);
103529
+ const fullPath = join110(dir, entry.name);
103256
103530
  const relativePath = relative22(baseDir, fullPath);
103257
103531
  if (entry.isDirectory()) {
103258
103532
  results.push(...collectFilesRecursively(fullPath, baseDir));
@@ -103320,7 +103594,7 @@ function deletePath(fullPath, claudeDir3) {
103320
103594
  }
103321
103595
  }
103322
103596
  async function updateMetadataAfterDeletion(claudeDir3, deletedPaths) {
103323
- const metadataPath = join108(claudeDir3, "metadata.json");
103597
+ const metadataPath = join110(claudeDir3, "metadata.json");
103324
103598
  if (!await import_fs_extra12.pathExists(metadataPath)) {
103325
103599
  return;
103326
103600
  }
@@ -103375,7 +103649,7 @@ async function handleDeletions(sourceMetadata, claudeDir3, kitType) {
103375
103649
  const userMetadata = await readManifest(claudeDir3);
103376
103650
  const result = { deletedPaths: [], preservedPaths: [], errors: [] };
103377
103651
  for (const path16 of deletions) {
103378
- const fullPath = join108(claudeDir3, path16);
103652
+ const fullPath = join110(claudeDir3, path16);
103379
103653
  const normalizedPath = resolve43(fullPath);
103380
103654
  const normalizedClaudeDir = resolve43(claudeDir3);
103381
103655
  if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep12}`)) {
@@ -103415,7 +103689,7 @@ init_logger();
103415
103689
  init_types3();
103416
103690
  var import_fs_extra16 = __toESM(require_lib(), 1);
103417
103691
  var import_ignore3 = __toESM(require_ignore(), 1);
103418
- import { dirname as dirname42, join as join113, relative as relative25 } from "node:path";
103692
+ import { dirname as dirname42, join as join115, relative as relative25 } from "node:path";
103419
103693
 
103420
103694
  // src/domains/installation/selective-merger.ts
103421
103695
  import { stat as stat18 } from "node:fs/promises";
@@ -103591,7 +103865,7 @@ class SelectiveMerger {
103591
103865
 
103592
103866
  // src/domains/installation/merger/deleted-skill-preservation.ts
103593
103867
  init_metadata_migration();
103594
- import { dirname as dirname39, join as join109, relative as relative23 } from "node:path";
103868
+ import { dirname as dirname39, join as join111, relative as relative23 } from "node:path";
103595
103869
  var import_fs_extra13 = __toESM(require_lib(), 1);
103596
103870
  async function findIgnoredSkillDirectories({
103597
103871
  files,
@@ -103619,7 +103893,7 @@ async function findIgnoredSkillDirectories({
103619
103893
  return root ? [root] : [];
103620
103894
  }));
103621
103895
  for (const [metadataRoot, sourceRoot] of sourceSkillRoots) {
103622
- const destSkillRoot = join109(destDir, ...sourceRoot.split("/"));
103896
+ const destSkillRoot = join111(destDir, ...sourceRoot.split("/"));
103623
103897
  const skillExists = await import_fs_extra13.pathExists(destSkillRoot);
103624
103898
  if (existingIgnoredRoots.has(metadataRoot) || !skillExists && previouslyTrackedRoots.has(metadataRoot)) {
103625
103899
  ignoredSkillDirectories.add(metadataRoot);
@@ -103669,7 +103943,7 @@ init_logger();
103669
103943
  var import_fs_extra14 = __toESM(require_lib(), 1);
103670
103944
  var import_ignore2 = __toESM(require_ignore(), 1);
103671
103945
  import { relative as relative24 } from "node:path";
103672
- import { join as join110 } from "node:path";
103946
+ import { join as join112 } from "node:path";
103673
103947
 
103674
103948
  // node_modules/@isaacs/balanced-match/dist/esm/index.js
103675
103949
  var balanced = (a3, b3, str2) => {
@@ -105125,7 +105399,7 @@ class FileScanner {
105125
105399
  const files = [];
105126
105400
  const entries = await import_fs_extra14.readdir(dir, { encoding: "utf8" });
105127
105401
  for (const entry of entries) {
105128
- const fullPath = join110(dir, entry);
105402
+ const fullPath = join112(dir, entry);
105129
105403
  const relativePath = relative24(baseDir, fullPath);
105130
105404
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
105131
105405
  const stats = await import_fs_extra14.lstat(fullPath);
@@ -105161,13 +105435,13 @@ class FileScanner {
105161
105435
  // src/domains/installation/merger/settings-processor.ts
105162
105436
  import { execSync as execSync5 } from "node:child_process";
105163
105437
  import { homedir as homedir46 } from "node:os";
105164
- import { dirname as dirname41, join as join112 } from "node:path";
105438
+ import { dirname as dirname41, join as join114 } from "node:path";
105165
105439
 
105166
105440
  // src/domains/config/installed-settings-tracker.ts
105167
105441
  init_shared();
105168
105442
  import { existsSync as existsSync67 } from "node:fs";
105169
105443
  import { mkdir as mkdir31, readFile as readFile52, writeFile as writeFile27 } from "node:fs/promises";
105170
- import { dirname as dirname40, join as join111 } from "node:path";
105444
+ import { dirname as dirname40, join as join113 } from "node:path";
105171
105445
  var CK_JSON_FILE = ".ck.json";
105172
105446
 
105173
105447
  class InstalledSettingsTracker {
@@ -105181,9 +105455,9 @@ class InstalledSettingsTracker {
105181
105455
  }
105182
105456
  getCkJsonPath() {
105183
105457
  if (this.isGlobal) {
105184
- return join111(this.projectDir, CK_JSON_FILE);
105458
+ return join113(this.projectDir, CK_JSON_FILE);
105185
105459
  }
105186
- return join111(this.projectDir, ".claude", CK_JSON_FILE);
105460
+ return join113(this.projectDir, ".claude", CK_JSON_FILE);
105187
105461
  }
105188
105462
  async loadInstalledSettings() {
105189
105463
  const ckJsonPath = this.getCkJsonPath();
@@ -105451,10 +105725,10 @@ class SettingsProcessor {
105451
105725
  };
105452
105726
  try {
105453
105727
  if (this.isGlobal) {
105454
- await addFromConfig(join112(this.projectDir, ".ck.json"));
105728
+ await addFromConfig(join114(this.projectDir, ".ck.json"));
105455
105729
  } else {
105456
- await addFromConfig(join112(PathResolver.getGlobalKitDir(), ".ck.json"));
105457
- await addFromConfig(join112(this.projectDir, ".claude", ".ck.json"));
105730
+ await addFromConfig(join114(PathResolver.getGlobalKitDir(), ".ck.json"));
105731
+ await addFromConfig(join114(this.projectDir, ".claude", ".ck.json"));
105458
105732
  }
105459
105733
  } catch (error) {
105460
105734
  logger.debug(`Failed to load .ck.json hook preferences: ${error instanceof Error ? error.message : "unknown"}`);
@@ -105841,7 +106115,7 @@ class SettingsProcessor {
105841
106115
  return false;
105842
106116
  }
105843
106117
  const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
105844
- const defaultGlobalDir = join112(homedir46(), ".claude").replace(/\\/g, "/");
106118
+ const defaultGlobalDir = join114(homedir46(), ".claude").replace(/\\/g, "/");
105845
106119
  return configuredGlobalDir !== defaultGlobalDir;
105846
106120
  }
105847
106121
  getClaudeCommandRoot() {
@@ -105861,7 +106135,7 @@ class SettingsProcessor {
105861
106135
  return true;
105862
106136
  }
105863
106137
  async repairSiblingSettingsLocal(destFile) {
105864
- const settingsLocalPath = join112(dirname41(destFile), "settings.local.json");
106138
+ const settingsLocalPath = join114(dirname41(destFile), "settings.local.json");
105865
106139
  if (settingsLocalPath === destFile || !await import_fs_extra15.pathExists(settingsLocalPath)) {
105866
106140
  return;
105867
106141
  }
@@ -105958,7 +106232,7 @@ class SettingsProcessor {
105958
106232
  }
105959
106233
  }
105960
106234
  async dynamicTeamHookHandlerExists(destFile, handler) {
105961
- return import_fs_extra15.pathExists(join112(dirname41(destFile), "hooks", handler));
106235
+ return import_fs_extra15.pathExists(join114(dirname41(destFile), "hooks", handler));
105962
106236
  }
105963
106237
  removeDynamicTeamHookRegistrations(settings) {
105964
106238
  let removed = 0;
@@ -106099,7 +106373,7 @@ class CopyExecutor {
106099
106373
  for (const file of files) {
106100
106374
  const relativePath = relative25(sourceDir, file);
106101
106375
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
106102
- const destPath = join113(destDir, relativePath);
106376
+ const destPath = join115(destDir, relativePath);
106103
106377
  if (await import_fs_extra16.pathExists(destPath)) {
106104
106378
  if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
106105
106379
  logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
@@ -106123,7 +106397,7 @@ class CopyExecutor {
106123
106397
  for (const file of files) {
106124
106398
  const relativePath = relative25(sourceDir, file);
106125
106399
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
106126
- const destPath = join113(destDir, relativePath);
106400
+ const destPath = join115(destDir, relativePath);
106127
106401
  if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
106128
106402
  logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
106129
106403
  skippedCount++;
@@ -106335,15 +106609,15 @@ class FileMerger {
106335
106609
 
106336
106610
  // src/domains/migration/legacy-migration.ts
106337
106611
  import { readdir as readdir28, stat as stat19 } from "node:fs/promises";
106338
- import { join as join117, relative as relative26 } from "node:path";
106612
+ import { join as join119, relative as relative26 } from "node:path";
106339
106613
  // src/services/file-operations/manifest/manifest-tracker.ts
106340
- import { join as join116 } from "node:path";
106614
+ import { join as join118 } from "node:path";
106341
106615
 
106342
106616
  // src/domains/migration/release-manifest.ts
106343
106617
  init_logger();
106344
106618
  init_zod();
106345
106619
  var import_fs_extra17 = __toESM(require_lib(), 1);
106346
- import { join as join114 } from "node:path";
106620
+ import { join as join116 } from "node:path";
106347
106621
  var ReleaseManifestFileSchema = exports_external.object({
106348
106622
  path: exports_external.string(),
106349
106623
  checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
@@ -106358,7 +106632,7 @@ var ReleaseManifestSchema = exports_external.object({
106358
106632
 
106359
106633
  class ReleaseManifestLoader {
106360
106634
  static async load(extractDir) {
106361
- const manifestPath = join114(extractDir, "release-manifest.json");
106635
+ const manifestPath = join116(extractDir, "release-manifest.json");
106362
106636
  try {
106363
106637
  const content = await import_fs_extra17.readFile(manifestPath, "utf-8");
106364
106638
  const parsed = JSON.parse(content);
@@ -106381,12 +106655,12 @@ init_p_limit();
106381
106655
 
106382
106656
  // src/services/file-operations/manifest/manifest-updater.ts
106383
106657
  init_metadata_migration();
106384
- import { join as join115 } from "node:path";
106658
+ import { join as join117 } from "node:path";
106385
106659
  init_logger();
106386
106660
  init_types3();
106387
106661
  var import_fs_extra18 = __toESM(require_lib(), 1);
106388
- async function writeManifest(claudeDir3, kitName, version, scope, kitType, trackedFiles, userConfigFiles, ignoredSkills = []) {
106389
- const metadataPath = join115(claudeDir3, "metadata.json");
106662
+ async function writeManifest(claudeDir3, kitName, version, scope, kitType, trackedFiles, userConfigFiles, ignoredSkills = [], installModePreference) {
106663
+ const metadataPath = join117(claudeDir3, "metadata.json");
106390
106664
  const kit = kitType || (/\bmarketing\b/i.test(kitName) ? "marketing" : "engineer");
106391
106665
  await import_fs_extra18.ensureFile(metadataPath);
106392
106666
  let release = null;
@@ -106411,6 +106685,7 @@ async function writeManifest(claudeDir3, kitName, version, scope, kitType, track
106411
106685
  const existingKits = existingMetadata.kits || {};
106412
106686
  const normalizedTrackedPaths = trackedFiles.map((file) => normalizeMetadataPath(file.path));
106413
106687
  const existingIgnoredSkills = existingKits[kit]?.ignoredSkills ?? [];
106688
+ const existingInstallModePreference = existingKits[kit]?.installModePreference;
106414
106689
  const mergedIgnoredSkills = uniqueNormalizedSkillRoots([
106415
106690
  ...existingIgnoredSkills,
106416
106691
  ...ignoredSkills
@@ -106420,7 +106695,8 @@ async function writeManifest(claudeDir3, kitName, version, scope, kitType, track
106420
106695
  version,
106421
106696
  installedAt,
106422
106697
  files: trackedFiles.length > 0 ? trackedFiles : undefined,
106423
- ignoredSkills: mergedIgnoredSkills.length > 0 ? mergedIgnoredSkills : undefined
106698
+ ignoredSkills: mergedIgnoredSkills.length > 0 ? mergedIgnoredSkills : undefined,
106699
+ installModePreference: installModePreference ?? existingInstallModePreference
106424
106700
  };
106425
106701
  const otherKitsExist = Object.keys(existingKits).some((k2) => k2 !== kit);
106426
106702
  const metadata = {
@@ -106458,7 +106734,7 @@ function uniqueNormalizedSkillRoots(paths) {
106458
106734
  }))).sort();
106459
106735
  }
106460
106736
  async function removeKitFromManifest(claudeDir3, kit, options2) {
106461
- const metadataPath = join115(claudeDir3, "metadata.json");
106737
+ const metadataPath = join117(claudeDir3, "metadata.json");
106462
106738
  if (!await import_fs_extra18.pathExists(metadataPath))
106463
106739
  return false;
106464
106740
  let release = null;
@@ -106490,7 +106766,7 @@ async function removeKitFromManifest(claudeDir3, kit, options2) {
106490
106766
  }
106491
106767
  }
106492
106768
  async function retainTrackedFilesInManifest(claudeDir3, retainedPaths, options2) {
106493
- const metadataPath = join115(claudeDir3, "metadata.json");
106769
+ const metadataPath = join117(claudeDir3, "metadata.json");
106494
106770
  if (!await import_fs_extra18.pathExists(metadataPath))
106495
106771
  return false;
106496
106772
  const normalizedPaths = new Set(retainedPaths.map((path17) => path17.replace(/\\/g, "/")));
@@ -106671,7 +106947,7 @@ function buildFileTrackingList(options2) {
106671
106947
  if (!isGlobal && !installedPath.startsWith(".claude/"))
106672
106948
  continue;
106673
106949
  const relativePath = isGlobal ? installedPath : installedPath.replace(/^\.claude\//, "");
106674
- const filePath = join116(claudeDir3, relativePath);
106950
+ const filePath = join118(claudeDir3, relativePath);
106675
106951
  const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
106676
106952
  const ownership = manifestEntry ? "ck" : "user";
106677
106953
  filesToTrack.push({
@@ -106695,7 +106971,7 @@ async function trackFilesWithProgress(filesToTrack, manifestOptions) {
106695
106971
  }
106696
106972
  });
106697
106973
  trackingSpinner.succeed(`Tracked ${trackResult.success} files`);
106698
- await writeManifest(manifestOptions.claudeDir, manifestOptions.kitName, manifestOptions.releaseTag, manifestOptions.mode, manifestOptions.kitType, tracker.getTrackedFiles(), tracker.getUserConfigFiles(), manifestOptions.ignoredSkills);
106974
+ await writeManifest(manifestOptions.claudeDir, manifestOptions.kitName, manifestOptions.releaseTag, manifestOptions.mode, manifestOptions.kitType, tracker.getTrackedFiles(), tracker.getUserConfigFiles(), manifestOptions.ignoredSkills, manifestOptions.installModePreference);
106699
106975
  return trackResult;
106700
106976
  }
106701
106977
  // src/services/file-operations/manifest-writer.ts
@@ -106725,8 +107001,8 @@ class ManifestWriter {
106725
107001
  getTrackedFiles() {
106726
107002
  return this.tracker.getTrackedFiles();
106727
107003
  }
106728
- async writeManifest(claudeDir3, kitName, version, scope, kitType, ignoredSkills) {
106729
- return writeManifest(claudeDir3, kitName, version, scope, kitType, this.getTrackedFiles(), this.getUserConfigFiles(), ignoredSkills);
107004
+ async writeManifest(claudeDir3, kitName, version, scope, kitType, ignoredSkills, installModePreference) {
107005
+ return writeManifest(claudeDir3, kitName, version, scope, kitType, this.getTrackedFiles(), this.getUserConfigFiles(), ignoredSkills, installModePreference);
106730
107006
  }
106731
107007
  static async readManifest(claudeDir3) {
106732
107008
  return readManifest(claudeDir3);
@@ -106782,7 +107058,7 @@ class LegacyMigration {
106782
107058
  continue;
106783
107059
  if (SKIP_DIRS_ALL.includes(entry))
106784
107060
  continue;
106785
- const fullPath = join117(dir, entry);
107061
+ const fullPath = join119(dir, entry);
106786
107062
  let stats;
106787
107063
  try {
106788
107064
  stats = await stat19(fullPath);
@@ -106892,7 +107168,7 @@ User-created files (sample):`);
106892
107168
  ];
106893
107169
  if (filesToChecksum.length > 0) {
106894
107170
  const checksumResults = await mapWithLimit(filesToChecksum, async ({ relativePath, ownership }) => {
106895
- const fullPath = join117(claudeDir3, relativePath);
107171
+ const fullPath = join119(claudeDir3, relativePath);
106896
107172
  const checksum = await OwnershipChecker.calculateChecksum(fullPath);
106897
107173
  return { relativePath, checksum, ownership };
106898
107174
  }, getOptimalConcurrency());
@@ -106913,7 +107189,7 @@ User-created files (sample):`);
106913
107189
  installedAt: new Date().toISOString(),
106914
107190
  files: trackedFiles
106915
107191
  };
106916
- const metadataPath = join117(claudeDir3, "metadata.json");
107192
+ const metadataPath = join119(claudeDir3, "metadata.json");
106917
107193
  await import_fs_extra19.writeFile(metadataPath, JSON.stringify(updatedMetadata, null, 2));
106918
107194
  logger.success(`Migration complete: tracked ${trackedFiles.length} files`);
106919
107195
  return true;
@@ -107019,7 +107295,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
107019
107295
  init_logger();
107020
107296
  init_skip_directories();
107021
107297
  var import_fs_extra20 = __toESM(require_lib(), 1);
107022
- import { join as join118, relative as relative27, resolve as resolve44 } from "node:path";
107298
+ import { join as join120, relative as relative27, resolve as resolve44 } from "node:path";
107023
107299
 
107024
107300
  class FileScanner2 {
107025
107301
  static async getFiles(dirPath, relativeTo) {
@@ -107035,7 +107311,7 @@ class FileScanner2 {
107035
107311
  logger.debug(`Skipping directory: ${entry}`);
107036
107312
  continue;
107037
107313
  }
107038
- const fullPath = join118(dirPath, entry);
107314
+ const fullPath = join120(dirPath, entry);
107039
107315
  if (!FileScanner2.isSafePath(basePath, fullPath)) {
107040
107316
  logger.warning(`Skipping potentially unsafe path: ${entry}`);
107041
107317
  continue;
@@ -107070,8 +107346,8 @@ class FileScanner2 {
107070
107346
  return files;
107071
107347
  }
107072
107348
  static async findCustomFiles(destDir, sourceDir, subPath) {
107073
- const destSubDir = join118(destDir, subPath);
107074
- const sourceSubDir = join118(sourceDir, subPath);
107349
+ const destSubDir = join120(destDir, subPath);
107350
+ const sourceSubDir = join120(sourceDir, subPath);
107075
107351
  logger.debug(`findCustomFiles - destDir: ${destDir}`);
107076
107352
  logger.debug(`findCustomFiles - sourceDir: ${sourceDir}`);
107077
107353
  logger.debug(`findCustomFiles - subPath: "${subPath}"`);
@@ -107112,12 +107388,12 @@ class FileScanner2 {
107112
107388
  init_logger();
107113
107389
  var import_fs_extra21 = __toESM(require_lib(), 1);
107114
107390
  import { lstat as lstat10, mkdir as mkdir32, readdir as readdir31, stat as stat20 } from "node:fs/promises";
107115
- import { join as join120 } from "node:path";
107391
+ import { join as join122 } from "node:path";
107116
107392
 
107117
107393
  // src/services/transformers/commands-prefix/content-transformer.ts
107118
107394
  init_logger();
107119
107395
  import { readFile as readFile56, readdir as readdir30, writeFile as writeFile31 } from "node:fs/promises";
107120
- import { join as join119 } from "node:path";
107396
+ import { join as join121 } from "node:path";
107121
107397
  var TRANSFORMABLE_EXTENSIONS = new Set([
107122
107398
  ".md",
107123
107399
  ".txt",
@@ -107177,7 +107453,7 @@ async function transformCommandReferences(directory, options2 = {}) {
107177
107453
  async function processDirectory(dir) {
107178
107454
  const entries = await readdir30(dir, { withFileTypes: true });
107179
107455
  for (const entry of entries) {
107180
- const fullPath = join119(dir, entry.name);
107456
+ const fullPath = join121(dir, entry.name);
107181
107457
  if (entry.isDirectory()) {
107182
107458
  if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
107183
107459
  continue;
@@ -107252,14 +107528,14 @@ function shouldApplyPrefix(options2) {
107252
107528
  // src/services/transformers/commands-prefix/prefix-applier.ts
107253
107529
  async function applyPrefix(extractDir) {
107254
107530
  validatePath(extractDir, "extractDir");
107255
- const commandsDir = join120(extractDir, ".claude", "commands");
107531
+ const commandsDir = join122(extractDir, ".claude", "commands");
107256
107532
  if (!await import_fs_extra21.pathExists(commandsDir)) {
107257
107533
  logger.verbose("No commands directory found, skipping prefix application");
107258
107534
  return;
107259
107535
  }
107260
107536
  logger.info("Applying /ck: prefix to slash commands...");
107261
- const backupDir = join120(extractDir, ".commands-backup");
107262
- const tempDir = join120(extractDir, ".commands-prefix-temp");
107537
+ const backupDir = join122(extractDir, ".commands-backup");
107538
+ const tempDir = join122(extractDir, ".commands-prefix-temp");
107263
107539
  try {
107264
107540
  const entries = await readdir31(commandsDir);
107265
107541
  if (entries.length === 0) {
@@ -107267,7 +107543,7 @@ async function applyPrefix(extractDir) {
107267
107543
  return;
107268
107544
  }
107269
107545
  if (entries.length === 1 && entries[0] === "ck") {
107270
- const ckDir2 = join120(commandsDir, "ck");
107546
+ const ckDir2 = join122(commandsDir, "ck");
107271
107547
  const ckStat = await stat20(ckDir2);
107272
107548
  if (ckStat.isDirectory()) {
107273
107549
  logger.verbose("Commands already have /ck: prefix, skipping");
@@ -107277,17 +107553,17 @@ async function applyPrefix(extractDir) {
107277
107553
  await import_fs_extra21.copy(commandsDir, backupDir);
107278
107554
  logger.verbose("Created backup of commands directory");
107279
107555
  await mkdir32(tempDir, { recursive: true });
107280
- const ckDir = join120(tempDir, "ck");
107556
+ const ckDir = join122(tempDir, "ck");
107281
107557
  await mkdir32(ckDir, { recursive: true });
107282
107558
  let processedCount = 0;
107283
107559
  for (const entry of entries) {
107284
- const sourcePath = join120(commandsDir, entry);
107560
+ const sourcePath = join122(commandsDir, entry);
107285
107561
  const stats = await lstat10(sourcePath);
107286
107562
  if (stats.isSymbolicLink()) {
107287
107563
  logger.warning(`Skipping symlink for security: ${entry}`);
107288
107564
  continue;
107289
107565
  }
107290
- const destPath = join120(ckDir, entry);
107566
+ const destPath = join122(ckDir, entry);
107291
107567
  await import_fs_extra21.copy(sourcePath, destPath, {
107292
107568
  overwrite: false,
107293
107569
  errorOnExist: true
@@ -107305,7 +107581,7 @@ async function applyPrefix(extractDir) {
107305
107581
  await import_fs_extra21.move(tempDir, commandsDir);
107306
107582
  await import_fs_extra21.remove(backupDir);
107307
107583
  logger.success("Successfully reorganized commands to /ck: prefix");
107308
- const claudeDir3 = join120(extractDir, ".claude");
107584
+ const claudeDir3 = join122(extractDir, ".claude");
107309
107585
  logger.info("Transforming command references in file contents...");
107310
107586
  const transformResult = await transformCommandReferences(claudeDir3, {
107311
107587
  verbose: logger.isVerbose()
@@ -107343,20 +107619,20 @@ async function applyPrefix(extractDir) {
107343
107619
  // src/services/transformers/commands-prefix/prefix-cleaner.ts
107344
107620
  init_metadata_migration();
107345
107621
  import { lstat as lstat12, readdir as readdir33 } from "node:fs/promises";
107346
- import { join as join122 } from "node:path";
107622
+ import { join as join124 } from "node:path";
107347
107623
  init_logger();
107348
107624
  var import_fs_extra23 = __toESM(require_lib(), 1);
107349
107625
 
107350
107626
  // src/services/transformers/commands-prefix/file-processor.ts
107351
107627
  import { lstat as lstat11, readdir as readdir32 } from "node:fs/promises";
107352
- import { join as join121 } from "node:path";
107628
+ import { join as join123 } from "node:path";
107353
107629
  init_logger();
107354
107630
  var import_fs_extra22 = __toESM(require_lib(), 1);
107355
107631
  async function scanDirectoryFiles(dir) {
107356
107632
  const files = [];
107357
107633
  const entries = await readdir32(dir);
107358
107634
  for (const entry of entries) {
107359
- const fullPath = join121(dir, entry);
107635
+ const fullPath = join123(dir, entry);
107360
107636
  const stats = await lstat11(fullPath);
107361
107637
  if (stats.isSymbolicLink()) {
107362
107638
  continue;
@@ -107484,8 +107760,8 @@ function isDifferentKitDirectory(dirName, currentKit) {
107484
107760
  async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
107485
107761
  const { dryRun = false } = options2;
107486
107762
  validatePath(targetDir, "targetDir");
107487
- const claudeDir3 = isGlobal ? targetDir : join122(targetDir, ".claude");
107488
- const commandsDir = join122(claudeDir3, "commands");
107763
+ const claudeDir3 = isGlobal ? targetDir : join124(targetDir, ".claude");
107764
+ const commandsDir = join124(claudeDir3, "commands");
107489
107765
  const accumulator = {
107490
107766
  results: [],
107491
107767
  deletedCount: 0,
@@ -107527,7 +107803,7 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
107527
107803
  }
107528
107804
  const metadataForChecks = options2.kitType ? createKitSpecificMetadata(metadata, options2.kitType) : metadata;
107529
107805
  for (const entry of entries) {
107530
- const entryPath = join122(commandsDir, entry);
107806
+ const entryPath = join124(commandsDir, entry);
107531
107807
  const stats = await lstat12(entryPath);
107532
107808
  if (stats.isSymbolicLink()) {
107533
107809
  addSymlinkSkip(entry, accumulator);
@@ -107576,6 +107852,18 @@ class CommandsPrefix {
107576
107852
  init_logger();
107577
107853
  init_output_manager();
107578
107854
  var import_fs_extra24 = __toESM(require_lib(), 1);
107855
+ function normalizeManifestPath(path17) {
107856
+ return path17.replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+$/, "");
107857
+ }
107858
+ function filterDeletedInstalledFiles(installedFiles, deletedPaths) {
107859
+ if (deletedPaths.length === 0)
107860
+ return installedFiles;
107861
+ const deleted = deletedPaths.map((path17) => normalizeManifestPath(path17)).filter(Boolean);
107862
+ return installedFiles.filter((file) => {
107863
+ const normalized = normalizeManifestPath(file);
107864
+ return !deleted.some((path17) => normalized === path17 || normalized.startsWith(`${path17}/`) || normalized === `.claude/${path17}` || normalized.startsWith(`.claude/${path17}/`));
107865
+ });
107866
+ }
107579
107867
  async function handleMerge(ctx) {
107580
107868
  if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir || !ctx.claudeDir || !ctx.kit || !ctx.kitType) {
107581
107869
  return ctx;
@@ -107584,7 +107872,7 @@ async function handleMerge(ctx) {
107584
107872
  let customClaudeFiles = [];
107585
107873
  if (!ctx.options.fresh) {
107586
107874
  logger.info("Scanning for custom .claude files...");
107587
- const scanSourceDir = ctx.options.global ? join123(ctx.extractDir, ".claude") : ctx.extractDir;
107875
+ const scanSourceDir = ctx.options.global ? join125(ctx.extractDir, ".claude") : ctx.extractDir;
107588
107876
  const scanTargetSubdir = ctx.options.global ? "" : ".claude";
107589
107877
  customClaudeFiles = await FileScanner2.findCustomFiles(ctx.resolvedDir, scanSourceDir, scanTargetSubdir);
107590
107878
  } else {
@@ -107623,7 +107911,7 @@ async function handleMerge(ctx) {
107623
107911
  merger.setRestoreCkHooks(ctx.options.restoreCkHooks);
107624
107912
  merger.setProjectDir(ctx.resolvedDir);
107625
107913
  merger.setKitName(ctx.kit.name);
107626
- merger.setZombiePrunerHookDir(join123(ctx.claudeDir, "hooks"));
107914
+ merger.setZombiePrunerHookDir(join125(ctx.claudeDir, "hooks"));
107627
107915
  if (ctx.kitType) {
107628
107916
  merger.setMultiKitContext(ctx.claudeDir, ctx.kitType);
107629
107917
  }
@@ -107652,8 +107940,8 @@ async function handleMerge(ctx) {
107652
107940
  return { ...ctx, cancelled: true };
107653
107941
  }
107654
107942
  }
107655
- const sourceDir = ctx.options.global ? join123(ctx.extractDir, ".claude") : ctx.extractDir;
107656
- const sourceMetadataPath = ctx.options.global ? join123(sourceDir, "metadata.json") : join123(sourceDir, ".claude", "metadata.json");
107943
+ const sourceDir = ctx.options.global ? join125(ctx.extractDir, ".claude") : ctx.extractDir;
107944
+ const sourceMetadataPath = ctx.options.global ? join125(sourceDir, "metadata.json") : join125(sourceDir, ".claude", "metadata.json");
107657
107945
  let sourceMetadata = null;
107658
107946
  try {
107659
107947
  if (await import_fs_extra24.pathExists(sourceMetadataPath)) {
@@ -107672,9 +107960,11 @@ async function handleMerge(ctx) {
107672
107960
  const summary = buildConflictSummary(fileConflicts, [], []);
107673
107961
  displayConflictSummary(summary);
107674
107962
  }
107963
+ let deletedPaths = [];
107675
107964
  try {
107676
107965
  if (sourceMetadata?.deletions && sourceMetadata.deletions.length > 0) {
107677
107966
  const deletionResult = await handleDeletions(sourceMetadata, ctx.claudeDir, ctx.kitType);
107967
+ deletedPaths = deletionResult.deletedPaths;
107678
107968
  if (deletionResult.deletedPaths.length > 0) {
107679
107969
  logger.info(`Removed ${deletionResult.deletedPaths.length} deprecated file(s)`);
107680
107970
  for (const path17 of deletionResult.deletedPaths) {
@@ -107688,7 +107978,7 @@ async function handleMerge(ctx) {
107688
107978
  } catch (error) {
107689
107979
  logger.debug(`Cleanup of deprecated files failed: ${error}`);
107690
107980
  }
107691
- const installedFiles = merger.getAllInstalledFiles();
107981
+ const installedFiles = filterDeletedInstalledFiles(merger.getAllInstalledFiles(), deletedPaths);
107692
107982
  const filesToTrack = buildFileTrackingList({
107693
107983
  installedFiles,
107694
107984
  claudeDir: ctx.claudeDir,
@@ -107702,7 +107992,8 @@ async function handleMerge(ctx) {
107702
107992
  releaseTag: installedVersion,
107703
107993
  mode: ctx.options.global ? "global" : "local",
107704
107994
  kitType: ctx.kitType,
107705
- ignoredSkills: merger.getIgnoredSkillDirectories()
107995
+ ignoredSkills: merger.getIgnoredSkillDirectories(),
107996
+ installModePreference: ctx.options.global && ctx.kitType === "engineer" ? ctx.options.installMode : undefined
107706
107997
  });
107707
107998
  return {
107708
107999
  ...ctx,
@@ -107711,7 +108002,7 @@ async function handleMerge(ctx) {
107711
108002
  };
107712
108003
  }
107713
108004
  // src/commands/init/phases/migration-handler.ts
107714
- import { join as join131 } from "node:path";
108005
+ import { join as join133 } from "node:path";
107715
108006
 
107716
108007
  // src/domains/skills/skills-detector.ts
107717
108008
  init_logger();
@@ -107727,7 +108018,7 @@ init_types3();
107727
108018
  var import_fs_extra25 = __toESM(require_lib(), 1);
107728
108019
  import { createHash as createHash8 } from "node:crypto";
107729
108020
  import { readFile as readFile58, readdir as readdir34, writeFile as writeFile32 } from "node:fs/promises";
107730
- import { join as join124, relative as relative28 } from "node:path";
108021
+ import { join as join126, relative as relative28 } from "node:path";
107731
108022
 
107732
108023
  class SkillsManifestManager {
107733
108024
  static MANIFEST_FILENAME = ".skills-manifest.json";
@@ -107749,12 +108040,12 @@ class SkillsManifestManager {
107749
108040
  return manifest;
107750
108041
  }
107751
108042
  static async writeManifest(skillsDir2, manifest) {
107752
- const manifestPath = join124(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
108043
+ const manifestPath = join126(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
107753
108044
  await writeFile32(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
107754
108045
  logger.debug(`Wrote manifest to: ${manifestPath}`);
107755
108046
  }
107756
108047
  static async readManifest(skillsDir2) {
107757
- const manifestPath = join124(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
108048
+ const manifestPath = join126(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
107758
108049
  if (!await import_fs_extra25.pathExists(manifestPath)) {
107759
108050
  logger.debug(`No manifest found at: ${manifestPath}`);
107760
108051
  return null;
@@ -107777,7 +108068,7 @@ class SkillsManifestManager {
107777
108068
  return "flat";
107778
108069
  }
107779
108070
  for (const dir of dirs.slice(0, 3)) {
107780
- const dirPath = join124(skillsDir2, dir.name);
108071
+ const dirPath = join126(skillsDir2, dir.name);
107781
108072
  const subEntries = await readdir34(dirPath, { withFileTypes: true });
107782
108073
  const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
107783
108074
  if (hasSubdirs) {
@@ -107796,7 +108087,7 @@ class SkillsManifestManager {
107796
108087
  const entries = await readdir34(skillsDir2, { withFileTypes: true });
107797
108088
  for (const entry of entries) {
107798
108089
  if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
107799
- const skillPath = join124(skillsDir2, entry.name);
108090
+ const skillPath = join126(skillsDir2, entry.name);
107800
108091
  const hash = await SkillsManifestManager.hashDirectory(skillPath);
107801
108092
  skills.push({
107802
108093
  name: entry.name,
@@ -107808,11 +108099,11 @@ class SkillsManifestManager {
107808
108099
  const categories = await readdir34(skillsDir2, { withFileTypes: true });
107809
108100
  for (const category of categories) {
107810
108101
  if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
107811
- const categoryPath = join124(skillsDir2, category.name);
108102
+ const categoryPath = join126(skillsDir2, category.name);
107812
108103
  const skillEntries = await readdir34(categoryPath, { withFileTypes: true });
107813
108104
  for (const skillEntry of skillEntries) {
107814
108105
  if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
107815
- const skillPath = join124(categoryPath, skillEntry.name);
108106
+ const skillPath = join126(categoryPath, skillEntry.name);
107816
108107
  const hash = await SkillsManifestManager.hashDirectory(skillPath);
107817
108108
  skills.push({
107818
108109
  name: skillEntry.name,
@@ -107842,7 +108133,7 @@ class SkillsManifestManager {
107842
108133
  const files = [];
107843
108134
  const entries = await readdir34(dirPath, { withFileTypes: true });
107844
108135
  for (const entry of entries) {
107845
- const fullPath = join124(dirPath, entry.name);
108136
+ const fullPath = join126(dirPath, entry.name);
107846
108137
  if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name)) {
107847
108138
  continue;
107848
108139
  }
@@ -107964,7 +108255,7 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
107964
108255
  // src/domains/skills/detection/script-detector.ts
107965
108256
  var import_fs_extra26 = __toESM(require_lib(), 1);
107966
108257
  import { readdir as readdir35 } from "node:fs/promises";
107967
- import { join as join125 } from "node:path";
108258
+ import { join as join127 } from "node:path";
107968
108259
  async function scanDirectory(skillsDir2) {
107969
108260
  if (!await import_fs_extra26.pathExists(skillsDir2)) {
107970
108261
  return ["flat", []];
@@ -107977,12 +108268,12 @@ async function scanDirectory(skillsDir2) {
107977
108268
  let totalSkillLikeCount = 0;
107978
108269
  const allSkills = [];
107979
108270
  for (const dir of dirs) {
107980
- const dirPath = join125(skillsDir2, dir.name);
108271
+ const dirPath = join127(skillsDir2, dir.name);
107981
108272
  const subEntries = await readdir35(dirPath, { withFileTypes: true });
107982
108273
  const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
107983
108274
  if (subdirs.length > 0) {
107984
108275
  for (const subdir of subdirs.slice(0, 3)) {
107985
- const subdirPath = join125(dirPath, subdir.name);
108276
+ const subdirPath = join127(dirPath, subdir.name);
107986
108277
  const subdirFiles = await readdir35(subdirPath, { withFileTypes: true });
107987
108278
  const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
107988
108279
  if (hasSkillMarker) {
@@ -108139,12 +108430,12 @@ class SkillsMigrationDetector {
108139
108430
  // src/domains/skills/skills-migrator.ts
108140
108431
  init_logger();
108141
108432
  init_types3();
108142
- import { join as join130 } from "node:path";
108433
+ import { join as join132 } from "node:path";
108143
108434
 
108144
108435
  // src/domains/skills/migrator/migration-executor.ts
108145
108436
  init_logger();
108146
108437
  import { copyFile as copyFile6, mkdir as mkdir33, readdir as readdir36, rm as rm13 } from "node:fs/promises";
108147
- import { join as join126 } from "node:path";
108438
+ import { join as join128 } from "node:path";
108148
108439
  var import_fs_extra28 = __toESM(require_lib(), 1);
108149
108440
 
108150
108441
  // src/domains/skills/skills-migration-prompts.ts
@@ -108309,8 +108600,8 @@ async function copySkillDirectory(sourceDir, destDir) {
108309
108600
  await mkdir33(destDir, { recursive: true });
108310
108601
  const entries = await readdir36(sourceDir, { withFileTypes: true });
108311
108602
  for (const entry of entries) {
108312
- const sourcePath = join126(sourceDir, entry.name);
108313
- const destPath = join126(destDir, entry.name);
108603
+ const sourcePath = join128(sourceDir, entry.name);
108604
+ const destPath = join128(destDir, entry.name);
108314
108605
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
108315
108606
  continue;
108316
108607
  }
@@ -108325,7 +108616,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
108325
108616
  const migrated = [];
108326
108617
  const preserved = [];
108327
108618
  const errors2 = [];
108328
- const tempDir = join126(currentSkillsDir, "..", ".skills-migration-temp");
108619
+ const tempDir = join128(currentSkillsDir, "..", ".skills-migration-temp");
108329
108620
  await mkdir33(tempDir, { recursive: true });
108330
108621
  try {
108331
108622
  for (const mapping of mappings) {
@@ -108346,9 +108637,9 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
108346
108637
  }
108347
108638
  }
108348
108639
  const category = mapping.category;
108349
- const targetPath = category ? join126(tempDir, category, skillName) : join126(tempDir, skillName);
108640
+ const targetPath = category ? join128(tempDir, category, skillName) : join128(tempDir, skillName);
108350
108641
  if (category) {
108351
- await mkdir33(join126(tempDir, category), { recursive: true });
108642
+ await mkdir33(join128(tempDir, category), { recursive: true });
108352
108643
  }
108353
108644
  await copySkillDirectory(currentSkillPath, targetPath);
108354
108645
  migrated.push(skillName);
@@ -108415,7 +108706,7 @@ init_logger();
108415
108706
  init_types3();
108416
108707
  var import_fs_extra29 = __toESM(require_lib(), 1);
108417
108708
  import { copyFile as copyFile7, mkdir as mkdir34, readdir as readdir37, rm as rm14, stat as stat21 } from "node:fs/promises";
108418
- import { basename as basename27, join as join127, normalize as normalize9 } from "node:path";
108709
+ import { basename as basename27, join as join129, normalize as normalize9 } from "node:path";
108419
108710
  function validatePath2(path17, paramName) {
108420
108711
  if (!path17 || typeof path17 !== "string") {
108421
108712
  throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
@@ -108441,7 +108732,7 @@ class SkillsBackupManager {
108441
108732
  const timestamp = Date.now();
108442
108733
  const randomSuffix = Math.random().toString(36).substring(2, 8);
108443
108734
  const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
108444
- const backupDir = parentDir ? join127(parentDir, backupDirName) : join127(skillsDir2, "..", backupDirName);
108735
+ const backupDir = parentDir ? join129(parentDir, backupDirName) : join129(skillsDir2, "..", backupDirName);
108445
108736
  logger.info(`Creating backup at: ${backupDir}`);
108446
108737
  try {
108447
108738
  await mkdir34(backupDir, { recursive: true });
@@ -108492,7 +108783,7 @@ class SkillsBackupManager {
108492
108783
  }
108493
108784
  try {
108494
108785
  const entries = await readdir37(parentDir, { withFileTypes: true });
108495
- const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join127(parentDir, entry.name));
108786
+ const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join129(parentDir, entry.name));
108496
108787
  backups.sort().reverse();
108497
108788
  return backups;
108498
108789
  } catch (error) {
@@ -108520,8 +108811,8 @@ class SkillsBackupManager {
108520
108811
  static async copyDirectory(sourceDir, destDir) {
108521
108812
  const entries = await readdir37(sourceDir, { withFileTypes: true });
108522
108813
  for (const entry of entries) {
108523
- const sourcePath = join127(sourceDir, entry.name);
108524
- const destPath = join127(destDir, entry.name);
108814
+ const sourcePath = join129(sourceDir, entry.name);
108815
+ const destPath = join129(destDir, entry.name);
108525
108816
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
108526
108817
  continue;
108527
108818
  }
@@ -108537,7 +108828,7 @@ class SkillsBackupManager {
108537
108828
  let size = 0;
108538
108829
  const entries = await readdir37(dirPath, { withFileTypes: true });
108539
108830
  for (const entry of entries) {
108540
- const fullPath = join127(dirPath, entry.name);
108831
+ const fullPath = join129(dirPath, entry.name);
108541
108832
  if (entry.isSymbolicLink()) {
108542
108833
  continue;
108543
108834
  }
@@ -108573,12 +108864,12 @@ init_skip_directories();
108573
108864
  import { createHash as createHash9 } from "node:crypto";
108574
108865
  import { createReadStream as createReadStream2 } from "node:fs";
108575
108866
  import { readFile as readFile59, readdir as readdir38 } from "node:fs/promises";
108576
- import { join as join128, relative as relative29 } from "node:path";
108867
+ import { join as join130, relative as relative29 } from "node:path";
108577
108868
  async function getAllFiles(dirPath) {
108578
108869
  const files = [];
108579
108870
  const entries = await readdir38(dirPath, { withFileTypes: true });
108580
108871
  for (const entry of entries) {
108581
- const fullPath = join128(dirPath, entry.name);
108872
+ const fullPath = join130(dirPath, entry.name);
108582
108873
  if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name) || entry.isSymbolicLink()) {
108583
108874
  continue;
108584
108875
  }
@@ -108705,7 +108996,7 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
108705
108996
  init_types3();
108706
108997
  var import_fs_extra31 = __toESM(require_lib(), 1);
108707
108998
  import { readdir as readdir39 } from "node:fs/promises";
108708
- import { join as join129, normalize as normalize10 } from "node:path";
108999
+ import { join as join131, normalize as normalize10 } from "node:path";
108709
109000
  function validatePath3(path17, paramName) {
108710
109001
  if (!path17 || typeof path17 !== "string") {
108711
109002
  throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
@@ -108726,13 +109017,13 @@ async function scanSkillsDirectory(skillsDir2) {
108726
109017
  if (dirs.length === 0) {
108727
109018
  return ["flat", []];
108728
109019
  }
108729
- const firstDirPath = join129(skillsDir2, dirs[0].name);
109020
+ const firstDirPath = join131(skillsDir2, dirs[0].name);
108730
109021
  const subEntries = await readdir39(firstDirPath, { withFileTypes: true });
108731
109022
  const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
108732
109023
  if (subdirs.length > 0) {
108733
109024
  let skillLikeCount = 0;
108734
109025
  for (const subdir of subdirs.slice(0, 3)) {
108735
- const subdirPath = join129(firstDirPath, subdir.name);
109026
+ const subdirPath = join131(firstDirPath, subdir.name);
108736
109027
  const subdirFiles = await readdir39(subdirPath, { withFileTypes: true });
108737
109028
  const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
108738
109029
  if (hasSkillMarker) {
@@ -108742,7 +109033,7 @@ async function scanSkillsDirectory(skillsDir2) {
108742
109033
  if (skillLikeCount > 0) {
108743
109034
  const skills = [];
108744
109035
  for (const dir of dirs) {
108745
- const categoryPath = join129(skillsDir2, dir.name);
109036
+ const categoryPath = join131(skillsDir2, dir.name);
108746
109037
  const skillDirs = await readdir39(categoryPath, { withFileTypes: true });
108747
109038
  skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
108748
109039
  }
@@ -108752,7 +109043,7 @@ async function scanSkillsDirectory(skillsDir2) {
108752
109043
  return ["flat", dirs.map((dir) => dir.name)];
108753
109044
  }
108754
109045
  async function findSkillPath(skillsDir2, skillName) {
108755
- const flatPath = join129(skillsDir2, skillName);
109046
+ const flatPath = join131(skillsDir2, skillName);
108756
109047
  if (await import_fs_extra31.pathExists(flatPath)) {
108757
109048
  return { path: flatPath, category: undefined };
108758
109049
  }
@@ -108761,8 +109052,8 @@ async function findSkillPath(skillsDir2, skillName) {
108761
109052
  if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
108762
109053
  continue;
108763
109054
  }
108764
- const categoryPath = join129(skillsDir2, entry.name);
108765
- const skillPath = join129(categoryPath, skillName);
109055
+ const categoryPath = join131(skillsDir2, entry.name);
109056
+ const skillPath = join131(categoryPath, skillName);
108766
109057
  if (await import_fs_extra31.pathExists(skillPath)) {
108767
109058
  return { path: skillPath, category: entry.name };
108768
109059
  }
@@ -108856,7 +109147,7 @@ class SkillsMigrator {
108856
109147
  }
108857
109148
  }
108858
109149
  if (options2.backup && !options2.dryRun) {
108859
- const claudeDir3 = join130(currentSkillsDir, "..");
109150
+ const claudeDir3 = join132(currentSkillsDir, "..");
108860
109151
  result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir3);
108861
109152
  logger.success(`Backup created at: ${result.backupPath}`);
108862
109153
  }
@@ -108917,7 +109208,7 @@ async function handleMigration(ctx) {
108917
109208
  logger.debug("Skipping skills migration (fresh installation)");
108918
109209
  return ctx;
108919
109210
  }
108920
- const newSkillsDir = join131(ctx.extractDir, ".claude", "skills");
109211
+ const newSkillsDir = join133(ctx.extractDir, ".claude", "skills");
108921
109212
  const currentSkillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
108922
109213
  if (!await import_fs_extra32.pathExists(newSkillsDir) || !await import_fs_extra32.pathExists(currentSkillsDir)) {
108923
109214
  return ctx;
@@ -108941,13 +109232,13 @@ async function handleMigration(ctx) {
108941
109232
  }
108942
109233
  // src/commands/init/phases/opencode-handler.ts
108943
109234
  import { cp as cp4, readdir as readdir41, rm as rm15 } from "node:fs/promises";
108944
- import { join as join133 } from "node:path";
109235
+ import { join as join135 } from "node:path";
108945
109236
 
108946
109237
  // src/services/transformers/opencode-path-transformer.ts
108947
109238
  init_logger();
108948
109239
  import { readFile as readFile60, readdir as readdir40, writeFile as writeFile33 } from "node:fs/promises";
108949
109240
  import { platform as platform15 } from "node:os";
108950
- import { extname as extname6, join as join132 } from "node:path";
109241
+ import { extname as extname6, join as join134 } from "node:path";
108951
109242
  var IS_WINDOWS2 = platform15() === "win32";
108952
109243
  function getOpenCodeGlobalPath() {
108953
109244
  return "$HOME/.config/opencode/";
@@ -109008,7 +109299,7 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
109008
109299
  async function processDirectory2(dir) {
109009
109300
  const entries = await readdir40(dir, { withFileTypes: true });
109010
109301
  for (const entry of entries) {
109011
- const fullPath = join132(dir, entry.name);
109302
+ const fullPath = join134(dir, entry.name);
109012
109303
  if (entry.isDirectory()) {
109013
109304
  if (entry.name === "node_modules" || entry.name.startsWith(".")) {
109014
109305
  continue;
@@ -109047,7 +109338,7 @@ async function handleOpenCode(ctx) {
109047
109338
  if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir) {
109048
109339
  return ctx;
109049
109340
  }
109050
- const openCodeSource = join133(ctx.extractDir, ".opencode");
109341
+ const openCodeSource = join135(ctx.extractDir, ".opencode");
109051
109342
  if (!await import_fs_extra33.pathExists(openCodeSource)) {
109052
109343
  logger.debug("No .opencode directory in archive, skipping");
109053
109344
  return ctx;
@@ -109065,8 +109356,8 @@ async function handleOpenCode(ctx) {
109065
109356
  await import_fs_extra33.ensureDir(targetDir);
109066
109357
  const entries = await readdir41(openCodeSource, { withFileTypes: true });
109067
109358
  for (const entry of entries) {
109068
- const sourcePath = join133(openCodeSource, entry.name);
109069
- const targetPath = join133(targetDir, entry.name);
109359
+ const sourcePath = join135(openCodeSource, entry.name);
109360
+ const targetPath = join135(targetDir, entry.name);
109070
109361
  if (await import_fs_extra33.pathExists(targetPath)) {
109071
109362
  if (!ctx.options.forceOverwrite) {
109072
109363
  logger.verbose(`Skipping existing: ${entry.name}`);
@@ -109166,7 +109457,7 @@ Please use only one download method.`);
109166
109457
  }
109167
109458
  // src/commands/init/phases/post-install-handler.ts
109168
109459
  init_projects_registry();
109169
- import { join as join134 } from "node:path";
109460
+ import { join as join136 } from "node:path";
109170
109461
  init_logger();
109171
109462
  init_path_resolver();
109172
109463
  var import_fs_extra34 = __toESM(require_lib(), 1);
@@ -109175,8 +109466,8 @@ async function handlePostInstall(ctx) {
109175
109466
  return ctx;
109176
109467
  }
109177
109468
  if (ctx.options.global) {
109178
- const claudeMdSource = join134(ctx.extractDir, "CLAUDE.md");
109179
- const claudeMdDest = join134(ctx.resolvedDir, "CLAUDE.md");
109469
+ const claudeMdSource = join136(ctx.extractDir, "CLAUDE.md");
109470
+ const claudeMdDest = join136(ctx.resolvedDir, "CLAUDE.md");
109180
109471
  if (await import_fs_extra34.pathExists(claudeMdSource)) {
109181
109472
  if (ctx.options.fresh || !await import_fs_extra34.pathExists(claudeMdDest)) {
109182
109473
  await import_fs_extra34.copy(claudeMdSource, claudeMdDest);
@@ -109224,7 +109515,7 @@ async function handlePostInstall(ctx) {
109224
109515
  }
109225
109516
  if (!ctx.options.skipSetup) {
109226
109517
  await promptSetupWizardIfNeeded({
109227
- envPath: join134(ctx.claudeDir, ".env"),
109518
+ envPath: join136(ctx.claudeDir, ".env"),
109228
109519
  claudeDir: ctx.claudeDir,
109229
109520
  isGlobal: ctx.options.global,
109230
109521
  isNonInteractive: ctx.isNonInteractive,
@@ -109246,8 +109537,8 @@ async function handlePostInstall(ctx) {
109246
109537
  }
109247
109538
  // src/commands/init/phases/plugin-install-handler.ts
109248
109539
  init_codex_plugin_installer();
109249
- import { cpSync as cpSync2, existsSync as existsSync70, mkdirSync as mkdirSync6, readFileSync as readFileSync22, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "node:fs";
109250
- import { join as join137 } from "node:path";
109540
+ import { cpSync as cpSync2, existsSync as existsSync70, mkdirSync as mkdirSync6, readFileSync as readFileSync24, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "node:fs";
109541
+ import { join as join139 } from "node:path";
109251
109542
 
109252
109543
  // src/domains/installation/plugin/migrate-legacy-to-plugin.ts
109253
109544
  init_install_mode_detector();
@@ -109256,12 +109547,12 @@ import {
109256
109547
  cpSync,
109257
109548
  existsSync as existsSync68,
109258
109549
  mkdirSync as mkdirSync5,
109259
- readFileSync as readFileSync21,
109550
+ readFileSync as readFileSync23,
109260
109551
  readdirSync as readdirSync11,
109261
109552
  rmSync as rmSync3,
109262
109553
  writeFileSync as writeFileSync7
109263
109554
  } from "node:fs";
109264
- import { dirname as dirname43, join as join135, relative as relative31, resolve as resolve45 } from "node:path";
109555
+ import { dirname as dirname43, join as join137, relative as relative31, resolve as resolve45 } from "node:path";
109265
109556
 
109266
109557
  // src/domains/installation/plugin/plugin-installer.ts
109267
109558
  init_install_mode_detector();
@@ -109321,10 +109612,10 @@ class PluginInstaller {
109321
109612
  return this.run(["plugin", "install", `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`, "--scope", scope], this.opts());
109322
109613
  }
109323
109614
  async enable() {
109324
- return this.run(["plugin", "enable", CK_PLUGIN_NAME], this.opts());
109615
+ return this.run(["plugin", "enable", `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`], this.opts());
109325
109616
  }
109326
109617
  async update() {
109327
- return this.run(["plugin", "update", CK_PLUGIN_NAME], this.opts());
109618
+ return this.run(["plugin", "update", `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`], this.opts());
109328
109619
  }
109329
109620
  async uninstall() {
109330
109621
  return this.run(["plugin", "uninstall", CK_PLUGIN_NAME], this.opts());
@@ -109386,7 +109677,7 @@ async function migrateLegacyToPlugin(opts) {
109386
109677
  let backupDir = null;
109387
109678
  let removedPaths = [];
109388
109679
  if (before.legacy.installed) {
109389
- backupDir = join135(claudeDir3, "backups", `ck-legacy-${ts.replace(/[:.]/g, "-")}`);
109680
+ backupDir = join137(claudeDir3, "backups", `ck-legacy-${ts.replace(/[:.]/g, "-")}`);
109390
109681
  mkdirSync5(backupDir, { recursive: true });
109391
109682
  removedPaths = removeLegacy(claudeDir3, backupDir);
109392
109683
  }
@@ -109421,7 +109712,7 @@ function base(action, modeBefore, pluginVerified) {
109421
109712
  var PLUGIN_SUPPLIED_LEGACY_PREFIXES2 = ["agents/", "skills/"];
109422
109713
  var LEGACY_SENTINEL_FILENAMES = new Set([".gitignore"]);
109423
109714
  function defaultLegacyRemover(claudeDir3, backupDir) {
109424
- const meta = readJsonSafe3(join135(claudeDir3, "metadata.json"));
109715
+ const meta = readJsonSafe3(join137(claudeDir3, "metadata.json"));
109425
109716
  const files = collectTrackedFiles2(meta);
109426
109717
  const removed = [];
109427
109718
  for (const file of files) {
@@ -109459,7 +109750,7 @@ function removeOrphanLegacySentinels(claudeDir3, backupDir, removedTrackedPaths)
109459
109750
  }
109460
109751
  const removed = [];
109461
109752
  for (const root of [...rootsToSweep].sort(compareLegacyPaths)) {
109462
- const rootAbs = join135(claudeDir3, root);
109753
+ const rootAbs = join137(claudeDir3, root);
109463
109754
  if (!existsSync68(rootAbs))
109464
109755
  continue;
109465
109756
  const sentinels = findLegacySentinels(rootAbs).sort((a3, b3) => compareLegacyPaths(relative31(claudeDir3, a3), relative31(claudeDir3, b3)));
@@ -109483,7 +109774,7 @@ function findLegacySentinels(dir) {
109483
109774
  return out;
109484
109775
  }
109485
109776
  for (const entry of entries.sort((a3, b3) => compareLegacyPaths(a3.name, b3.name))) {
109486
- const abs = join135(dir, entry.name);
109777
+ const abs = join137(dir, entry.name);
109487
109778
  if (entry.isDirectory()) {
109488
109779
  out.push(...findLegacySentinels(abs));
109489
109780
  } else if (entry.isFile() && LEGACY_SENTINEL_FILENAMES.has(entry.name)) {
@@ -109511,7 +109802,7 @@ function directoryContainsOnlySentinels(dir) {
109511
109802
  return false;
109512
109803
  }
109513
109804
  for (const entry of entries) {
109514
- const abs = join135(dir, entry.name);
109805
+ const abs = join137(dir, entry.name);
109515
109806
  if (entry.isDirectory()) {
109516
109807
  if (!directoryContainsOnlySentinels(abs))
109517
109808
  return false;
@@ -109532,7 +109823,7 @@ function checksumMatches2(filePath, expected) {
109532
109823
  return false;
109533
109824
  }
109534
109825
  try {
109535
- const actual = createHash10("sha256").update(readFileSync21(filePath)).digest("hex");
109826
+ const actual = createHash10("sha256").update(readFileSync23(filePath)).digest("hex");
109536
109827
  return actual.toLowerCase() === expected.toLowerCase();
109537
109828
  } catch {
109538
109829
  return false;
@@ -109586,14 +109877,14 @@ function compareLegacyPaths(a3, b3) {
109586
109877
  return 0;
109587
109878
  }
109588
109879
  function collectTrackedFiles2(meta) {
109589
- if (!isRecord3(meta))
109880
+ if (!isRecord5(meta))
109590
109881
  return [];
109591
109882
  const out = [];
109592
109883
  const push2 = (arr) => {
109593
109884
  if (!Array.isArray(arr))
109594
109885
  return;
109595
109886
  for (const f3 of arr) {
109596
- if (isRecord3(f3) && typeof f3.path === "string") {
109887
+ if (isRecord5(f3) && typeof f3.path === "string") {
109597
109888
  const ownership = f3.ownership === "user" || f3.ownership === "ck-modified" ? f3.ownership : "ck";
109598
109889
  out.push({
109599
109890
  path: f3.path,
@@ -109603,9 +109894,9 @@ function collectTrackedFiles2(meta) {
109603
109894
  }
109604
109895
  }
109605
109896
  };
109606
- if (isRecord3(meta.kits)) {
109897
+ if (isRecord5(meta.kits)) {
109607
109898
  const engineer = meta.kits[ENGINEER_KIT_KEY];
109608
- if (isRecord3(engineer))
109899
+ if (isRecord5(engineer))
109609
109900
  push2(engineer.files);
109610
109901
  } else {
109611
109902
  push2(meta.files);
@@ -109613,7 +109904,7 @@ function collectTrackedFiles2(meta) {
109613
109904
  return out;
109614
109905
  }
109615
109906
  function writeReceipt(claudeDir3, receipt) {
109616
- const receiptPath = join135(claudeDir3, ".ck-migration-log.json");
109907
+ const receiptPath = join137(claudeDir3, ".ck-migration-log.json");
109617
109908
  const existing = readJsonSafe3(receiptPath);
109618
109909
  const history = Array.isArray(existing) ? existing : [];
109619
109910
  history.push(receipt);
@@ -109623,7 +109914,7 @@ function writeReceipt(claudeDir3, receipt) {
109623
109914
  }
109624
109915
  function readJsonSafe3(filePath) {
109625
109916
  try {
109626
- return JSON.parse(readFileSync21(filePath, "utf-8"));
109917
+ return JSON.parse(readFileSync23(filePath, "utf-8"));
109627
109918
  } catch {
109628
109919
  return null;
109629
109920
  }
@@ -109662,14 +109953,14 @@ async function refreshExistingPlugin(installer, pluginSourceDir, enabled) {
109662
109953
  }
109663
109954
  return { ok: true };
109664
109955
  }
109665
- function isRecord3(value) {
109956
+ function isRecord5(value) {
109666
109957
  return typeof value === "object" && value !== null && !Array.isArray(value);
109667
109958
  }
109668
109959
 
109669
109960
  // src/domains/installation/plugin/uninstall-plugin.ts
109670
109961
  init_install_mode_detector();
109671
109962
  import { existsSync as existsSync69, rmSync as rmSync4 } from "node:fs";
109672
- import { join as join136 } from "node:path";
109963
+ import { join as join138 } from "node:path";
109673
109964
  init_path_resolver();
109674
109965
  async function uninstallEnginePlugin(opts = {}) {
109675
109966
  const claudeDir3 = opts.claudeDir ?? PathResolver.getGlobalKitDir();
@@ -109691,7 +109982,7 @@ async function uninstallEnginePlugin(opts = {}) {
109691
109982
  }
109692
109983
  let staleCacheRemoved = false;
109693
109984
  const marketplace = state.marketplace ?? CK_MARKETPLACE_NAME;
109694
- const cacheDir = join136(claudeDir3, "plugins", "cache", marketplace, CK_PLUGIN_NAME);
109985
+ const cacheDir = join138(claudeDir3, "plugins", "cache", marketplace, CK_PLUGIN_NAME);
109695
109986
  if (existsSync69(cacheDir)) {
109696
109987
  rmSync4(cacheDir, { recursive: true, force: true });
109697
109988
  staleCacheRemoved = true;
@@ -109735,8 +110026,12 @@ async function handlePluginInstall(ctx, deps = {}) {
109735
110026
  try {
109736
110027
  const result = await removeCodex();
109737
110028
  logCodexPluginCleanup(result);
110029
+ if (result.pluginStillInstalled) {
110030
+ cleanupError = new Error(`Codex plugin cleanup failed for legacy install mode: ${result.error ?? "plugin remains registered"}`);
110031
+ }
109738
110032
  } catch (err) {
109739
110033
  logger.verbose(`Codex plugin cleanup skipped: ${err.message}`);
110034
+ cleanupError = err;
109740
110035
  }
109741
110036
  if (cleanupError) {
109742
110037
  throw cleanupError;
@@ -109760,7 +110055,13 @@ async function handlePluginInstall(ctx, deps = {}) {
109760
110055
  try {
109761
110056
  const result = await installCodex({ pluginSourceDir });
109762
110057
  logCodexPluginResult(result);
110058
+ if (ctx.options.installMode === "plugin" && result.action === "install-failed") {
110059
+ throw new Error(`Codex plugin install failed: ${result.error ?? result.action}`);
110060
+ }
109763
110061
  } catch (err) {
110062
+ if (ctx.options.installMode === "plugin") {
110063
+ throw err;
110064
+ }
109764
110065
  logger.verbose(`Codex plugin install skipped: ${err.message}`);
109765
110066
  }
109766
110067
  } catch (err) {
@@ -109779,14 +110080,14 @@ function logLegacyPluginCleanup(result) {
109779
110080
  }
109780
110081
  }
109781
110082
  function stagePluginSource(extractDir, stageBaseDir) {
109782
- const base2 = stageBaseDir ?? join137(PathResolver.getCacheDir(true), "ck-plugin-source");
109783
- const payloadSrc = join137(extractDir, ".claude");
110083
+ const base2 = stageBaseDir ?? join139(PathResolver.getCacheDir(true), "ck-plugin-source");
110084
+ const payloadSrc = join139(extractDir, ".claude");
109784
110085
  if (!existsSync70(payloadSrc)) {
109785
110086
  throw new Error(`plugin payload not found in archive: ${payloadSrc}`);
109786
110087
  }
109787
110088
  rmSync5(base2, { recursive: true, force: true });
109788
110089
  mkdirSync6(base2, { recursive: true });
109789
- const stagedPayload = join137(base2, ".claude");
110090
+ const stagedPayload = join139(base2, ".claude");
109790
110091
  cpSync2(payloadSrc, stagedPayload, { recursive: true });
109791
110092
  ensureCodexPluginManifest(stagedPayload);
109792
110093
  const claudeMarketplace = {
@@ -109794,8 +110095,8 @@ function stagePluginSource(extractDir, stageBaseDir) {
109794
110095
  owner: { name: "ClaudeKit" },
109795
110096
  plugins: [{ name: "ck", source: "./.claude", description: "ClaudeKit Engineer" }]
109796
110097
  };
109797
- mkdirSync6(join137(base2, ".claude-plugin"), { recursive: true });
109798
- writeFileSync8(join137(base2, ".claude-plugin", "marketplace.json"), `${JSON.stringify(claudeMarketplace, null, 2)}
110098
+ mkdirSync6(join139(base2, ".claude-plugin"), { recursive: true });
110099
+ writeFileSync8(join139(base2, ".claude-plugin", "marketplace.json"), `${JSON.stringify(claudeMarketplace, null, 2)}
109799
110100
  `, "utf-8");
109800
110101
  const codexMarketplace = {
109801
110102
  name: "claudekit",
@@ -109809,24 +110110,24 @@ function stagePluginSource(extractDir, stageBaseDir) {
109809
110110
  }
109810
110111
  ]
109811
110112
  };
109812
- mkdirSync6(join137(base2, ".agents", "plugins"), { recursive: true });
109813
- writeFileSync8(join137(base2, ".agents", "plugins", "marketplace.json"), `${JSON.stringify(codexMarketplace, null, 2)}
110113
+ mkdirSync6(join139(base2, ".agents", "plugins"), { recursive: true });
110114
+ writeFileSync8(join139(base2, ".agents", "plugins", "marketplace.json"), `${JSON.stringify(codexMarketplace, null, 2)}
109814
110115
  `, "utf-8");
109815
110116
  return base2;
109816
110117
  }
109817
110118
  function ensureCodexPluginManifest(pluginRoot) {
109818
- const manifestPath = join137(pluginRoot, ".codex-plugin", "plugin.json");
110119
+ const manifestPath = join139(pluginRoot, ".codex-plugin", "plugin.json");
109819
110120
  if (existsSync70(manifestPath))
109820
110121
  return;
109821
- const claudeManifest = readJsonSafe4(join137(pluginRoot, ".claude-plugin", "plugin.json"));
110122
+ const claudeManifest = readJsonSafe4(join139(pluginRoot, ".claude-plugin", "plugin.json"));
109822
110123
  const manifest = pruneUndefined({
109823
- name: stringField(claudeManifest, "name") ?? "ck",
109824
- version: stringField(claudeManifest, "version") ?? "0.0.0",
109825
- description: stringField(claudeManifest, "description") ?? "ClaudeKit Engineer — multi-agent planning, code review, debugging, and workflow skills for Codex.",
110124
+ name: stringField2(claudeManifest, "name") ?? "ck",
110125
+ version: stringField2(claudeManifest, "version") ?? "0.0.0",
110126
+ description: stringField2(claudeManifest, "description") ?? "ClaudeKit Engineer — multi-agent planning, code review, debugging, and workflow skills for Codex.",
109826
110127
  author: authorField(claudeManifest),
109827
- homepage: stringField(claudeManifest, "homepage"),
109828
- repository: stringField(claudeManifest, "repository"),
109829
- license: stringField(claudeManifest, "license"),
110128
+ homepage: stringField2(claudeManifest, "homepage"),
110129
+ repository: stringField2(claudeManifest, "repository"),
110130
+ license: stringField2(claudeManifest, "license"),
109830
110131
  keywords: ["claudekit", "codex", "skills", "agents", "workflow"],
109831
110132
  skills: "./skills/",
109832
110133
  interface: {
@@ -109839,25 +110140,25 @@ function ensureCodexPluginManifest(pluginRoot) {
109839
110140
  websiteURL: "https://github.com/claudekit/claudekit-engineer"
109840
110141
  }
109841
110142
  });
109842
- mkdirSync6(join137(pluginRoot, ".codex-plugin"), { recursive: true });
110143
+ mkdirSync6(join139(pluginRoot, ".codex-plugin"), { recursive: true });
109843
110144
  writeFileSync8(manifestPath, `${JSON.stringify(manifest, null, 2)}
109844
110145
  `, "utf-8");
109845
110146
  }
109846
110147
  function readJsonSafe4(filePath) {
109847
110148
  try {
109848
- const parsed = JSON.parse(readFileSync22(filePath, "utf-8"));
109849
- return isRecord4(parsed) ? parsed : null;
110149
+ const parsed = JSON.parse(readFileSync24(filePath, "utf-8"));
110150
+ return isRecord6(parsed) ? parsed : null;
109850
110151
  } catch {
109851
110152
  return null;
109852
110153
  }
109853
110154
  }
109854
- function stringField(source, key) {
110155
+ function stringField2(source, key) {
109855
110156
  const value = source?.[key];
109856
110157
  return typeof value === "string" && value.trim() !== "" ? value : undefined;
109857
110158
  }
109858
110159
  function authorField(source) {
109859
110160
  const author = source?.author;
109860
- if (isRecord4(author) && typeof author.name === "string" && author.name.trim() !== "") {
110161
+ if (isRecord6(author) && typeof author.name === "string" && author.name.trim() !== "") {
109861
110162
  return { name: author.name };
109862
110163
  }
109863
110164
  return { name: "ClaudeKit" };
@@ -109865,7 +110166,7 @@ function authorField(source) {
109865
110166
  function pruneUndefined(value) {
109866
110167
  return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
109867
110168
  }
109868
- function isRecord4(value) {
110169
+ function isRecord6(value) {
109869
110170
  return typeof value === "object" && value !== null && !Array.isArray(value);
109870
110171
  }
109871
110172
  function logPluginResult(result) {
@@ -109911,7 +110212,7 @@ function logCodexPluginCleanup(result) {
109911
110212
  init_config_manager();
109912
110213
  init_github_client();
109913
110214
  import { mkdir as mkdir36 } from "node:fs/promises";
109914
- import { join as join140, resolve as resolve48 } from "node:path";
110215
+ import { join as join142, resolve as resolve48 } from "node:path";
109915
110216
 
109916
110217
  // src/domains/github/kit-access-checker.ts
109917
110218
  init_error2();
@@ -110084,7 +110385,7 @@ init_hook_health_checker();
110084
110385
  // src/domains/installation/fresh-installer.ts
110085
110386
  init_metadata_migration();
110086
110387
  import { existsSync as existsSync71, readdirSync as readdirSync12, rmSync as rmSync6, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
110087
- import { basename as basename28, dirname as dirname44, join as join138, resolve as resolve46 } from "node:path";
110388
+ import { basename as basename28, dirname as dirname44, join as join140, resolve as resolve46 } from "node:path";
110088
110389
  init_logger();
110089
110390
  init_safe_spinner();
110090
110391
  var import_fs_extra35 = __toESM(require_lib(), 1);
@@ -110166,7 +110467,7 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
110166
110467
  logger.debug(`${KIT_MANIFEST_FILE} was self-tracked; skipping from delete loop — will be rewritten by updateMetadataAfterFresh`);
110167
110468
  }
110168
110469
  for (const file of filesToRemove) {
110169
- const fullPath = join138(claudeDir3, file.path);
110470
+ const fullPath = join140(claudeDir3, file.path);
110170
110471
  if (!existsSync71(fullPath)) {
110171
110472
  continue;
110172
110473
  }
@@ -110194,7 +110495,7 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
110194
110495
  };
110195
110496
  }
110196
110497
  async function updateMetadataAfterFresh(claudeDir3, removedFiles, metadata) {
110197
- const metadataPath = join138(claudeDir3, KIT_MANIFEST_FILE);
110498
+ const metadataPath = join140(claudeDir3, KIT_MANIFEST_FILE);
110198
110499
  const removedSet = new Set(removedFiles);
110199
110500
  if (metadata.kits) {
110200
110501
  for (const kitName of Object.keys(metadata.kits)) {
@@ -110225,8 +110526,8 @@ function getFreshBackupTargets(claudeDir3, analysis, includeModified) {
110225
110526
  mutatePaths: filesToRemove.length > 0 ? ["metadata.json"] : []
110226
110527
  };
110227
110528
  }
110228
- const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync71(join138(claudeDir3, subdir)));
110229
- if (existsSync71(join138(claudeDir3, "metadata.json"))) {
110529
+ const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync71(join140(claudeDir3, subdir)));
110530
+ if (existsSync71(join140(claudeDir3, "metadata.json"))) {
110230
110531
  deletePaths.push("metadata.json");
110231
110532
  }
110232
110533
  return {
@@ -110248,7 +110549,7 @@ async function removeSubdirectoriesFallback(claudeDir3) {
110248
110549
  const removedFiles = [];
110249
110550
  let removedDirCount = 0;
110250
110551
  for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
110251
- const subdirPath = join138(claudeDir3, subdir);
110552
+ const subdirPath = join140(claudeDir3, subdir);
110252
110553
  if (await import_fs_extra35.pathExists(subdirPath)) {
110253
110554
  rmSync6(subdirPath, { recursive: true, force: true });
110254
110555
  removedDirCount++;
@@ -110256,7 +110557,7 @@ async function removeSubdirectoriesFallback(claudeDir3) {
110256
110557
  logger.debug(`Removed subdirectory: ${subdir}/`);
110257
110558
  }
110258
110559
  }
110259
- const metadataPath = join138(claudeDir3, "metadata.json");
110560
+ const metadataPath = join140(claudeDir3, "metadata.json");
110260
110561
  if (await import_fs_extra35.pathExists(metadataPath)) {
110261
110562
  unlinkSync5(metadataPath);
110262
110563
  removedFiles.push("metadata.json");
@@ -110334,7 +110635,7 @@ async function handleFreshInstallation(claudeDir3, prompts) {
110334
110635
  var import_fs_extra36 = __toESM(require_lib(), 1);
110335
110636
  import { cp as cp5, mkdir as mkdir35, readdir as readdir42, rename as rename11, rm as rm16, stat as stat22 } from "node:fs/promises";
110336
110637
  import { homedir as homedir47 } from "node:os";
110337
- import { dirname as dirname45, join as join139, normalize as normalize11, resolve as resolve47 } from "node:path";
110638
+ import { dirname as dirname45, join as join141, normalize as normalize11, resolve as resolve47 } from "node:path";
110338
110639
  var LEGACY_KIT_MARKERS = [
110339
110640
  "metadata.json",
110340
110641
  ".ck.json",
@@ -110373,10 +110674,10 @@ function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = ho
110373
110674
  const localAppData = safeEnvPath(env2.LOCALAPPDATA);
110374
110675
  const appData = safeEnvPath(env2.APPDATA);
110375
110676
  if (localAppData) {
110376
- candidates.push(join139(localAppData, ".claude"));
110677
+ candidates.push(join141(localAppData, ".claude"));
110377
110678
  }
110378
110679
  if (appData) {
110379
- candidates.push(join139(appData, ".claude"));
110680
+ candidates.push(join141(appData, ".claude"));
110380
110681
  }
110381
110682
  if (homeDir) {
110382
110683
  candidates.push(`${withoutTrailingSeparators(homeDir)}.claude`);
@@ -110394,7 +110695,7 @@ async function hasKitMarkers(dir) {
110394
110695
  if (!await isDirectory(dir))
110395
110696
  return false;
110396
110697
  for (const marker of LEGACY_KIT_MARKERS) {
110397
- if (await import_fs_extra36.pathExists(join139(dir, marker))) {
110698
+ if (await import_fs_extra36.pathExists(join141(dir, marker))) {
110398
110699
  return true;
110399
110700
  }
110400
110701
  }
@@ -110696,7 +110997,7 @@ async function handleSelection(ctx) {
110696
110997
  }
110697
110998
  if (!ctx.options.fresh) {
110698
110999
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
110699
- const claudeDir3 = prefix ? join140(resolvedDir, prefix) : resolvedDir;
111000
+ const claudeDir3 = prefix ? join142(resolvedDir, prefix) : resolvedDir;
110700
111001
  try {
110701
111002
  const existingMetadata = await readManifest(claudeDir3);
110702
111003
  if (existingMetadata?.kits) {
@@ -110733,7 +111034,7 @@ async function handleSelection(ctx) {
110733
111034
  }
110734
111035
  if (ctx.options.fresh) {
110735
111036
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
110736
- const claudeDir3 = prefix ? join140(resolvedDir, prefix) : resolvedDir;
111037
+ const claudeDir3 = prefix ? join142(resolvedDir, prefix) : resolvedDir;
110737
111038
  const canProceed = await handleFreshInstallation(claudeDir3, ctx.prompts);
110738
111039
  if (!canProceed) {
110739
111040
  return { ...ctx, cancelled: true };
@@ -110753,7 +111054,7 @@ async function handleSelection(ctx) {
110753
111054
  let currentVersion = null;
110754
111055
  try {
110755
111056
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
110756
- const claudeDir3 = prefix ? join140(resolvedDir, prefix) : resolvedDir;
111057
+ const claudeDir3 = prefix ? join142(resolvedDir, prefix) : resolvedDir;
110757
111058
  const existingMetadata = await readManifest(claudeDir3);
110758
111059
  currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
110759
111060
  if (currentVersion) {
@@ -110822,7 +111123,7 @@ async function handleSelection(ctx) {
110822
111123
  if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && !ctx.options.restoreCkHooks && releaseTag && !isOfflineMode && !pendingKits?.length) {
110823
111124
  try {
110824
111125
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
110825
- const claudeDir3 = prefix ? join140(resolvedDir, prefix) : resolvedDir;
111126
+ const claudeDir3 = prefix ? join142(resolvedDir, prefix) : resolvedDir;
110826
111127
  const existingMetadata = await readManifest(claudeDir3);
110827
111128
  const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
110828
111129
  if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
@@ -110851,7 +111152,7 @@ async function handleSelection(ctx) {
110851
111152
  }
110852
111153
  // src/commands/init/phases/sync-handler.ts
110853
111154
  import { copyFile as copyFile8, mkdir as mkdir37, open as open5, readFile as readFile61, rename as rename12, stat as stat23, unlink as unlink13, writeFile as writeFile35 } from "node:fs/promises";
110854
- import { dirname as dirname46, join as join141, resolve as resolve49 } from "node:path";
111155
+ import { dirname as dirname46, join as join143, resolve as resolve49 } from "node:path";
110855
111156
  init_logger();
110856
111157
  init_path_resolver();
110857
111158
  var import_fs_extra38 = __toESM(require_lib(), 1);
@@ -110861,13 +111162,13 @@ async function handleSync(ctx) {
110861
111162
  return ctx;
110862
111163
  }
110863
111164
  const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve49(ctx.options.dir || ".");
110864
- const claudeDir3 = ctx.options.global ? resolvedDir : join141(resolvedDir, ".claude");
111165
+ const claudeDir3 = ctx.options.global ? resolvedDir : join143(resolvedDir, ".claude");
110865
111166
  if (!await import_fs_extra38.pathExists(claudeDir3)) {
110866
111167
  logger.error("Cannot sync: no .claude directory found");
110867
111168
  ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
110868
111169
  return { ...ctx, cancelled: true };
110869
111170
  }
110870
- const metadataPath = join141(claudeDir3, "metadata.json");
111171
+ const metadataPath = join143(claudeDir3, "metadata.json");
110871
111172
  if (!await import_fs_extra38.pathExists(metadataPath)) {
110872
111173
  logger.error("Cannot sync: no metadata.json found");
110873
111174
  ctx.prompts.note(`Your installation may be from an older version.
@@ -110967,7 +111268,7 @@ function getLockTimeout() {
110967
111268
  var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
110968
111269
  async function acquireSyncLock(global3) {
110969
111270
  const cacheDir = PathResolver.getCacheDir(global3);
110970
- const lockPath = join141(cacheDir, ".sync-lock");
111271
+ const lockPath = join143(cacheDir, ".sync-lock");
110971
111272
  const startTime = Date.now();
110972
111273
  const lockTimeout = getLockTimeout();
110973
111274
  await mkdir37(dirname46(lockPath), { recursive: true });
@@ -111013,11 +111314,11 @@ async function executeSyncMerge(ctx) {
111013
111314
  const releaseLock = await acquireSyncLock(ctx.options.global);
111014
111315
  try {
111015
111316
  const trackedFiles = ctx.syncTrackedFiles;
111016
- const upstreamDir = ctx.options.global ? join141(ctx.extractDir, ".claude") : ctx.extractDir;
111317
+ const upstreamDir = ctx.options.global ? join143(ctx.extractDir, ".claude") : ctx.extractDir;
111017
111318
  let sourceMetadata = null;
111018
111319
  let deletions = [];
111019
111320
  try {
111020
- const sourceMetadataPath = join141(upstreamDir, "metadata.json");
111321
+ const sourceMetadataPath = join143(upstreamDir, "metadata.json");
111021
111322
  if (await import_fs_extra38.pathExists(sourceMetadataPath)) {
111022
111323
  const content = await readFile61(sourceMetadataPath, "utf-8");
111023
111324
  sourceMetadata = JSON.parse(content);
@@ -111079,7 +111380,7 @@ async function executeSyncMerge(ctx) {
111079
111380
  try {
111080
111381
  const sourcePath = await validateSyncPath(upstreamDir, file.path);
111081
111382
  const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
111082
- const targetDir = join141(targetPath, "..");
111383
+ const targetDir = join143(targetPath, "..");
111083
111384
  try {
111084
111385
  await mkdir37(targetDir, { recursive: true });
111085
111386
  } catch (mkdirError) {
@@ -111250,7 +111551,7 @@ async function createBackup(claudeDir3, files, backupDir) {
111250
111551
  const sourcePath = await validateSyncPath(claudeDir3, file.path);
111251
111552
  if (await import_fs_extra38.pathExists(sourcePath)) {
111252
111553
  const targetPath = await validateSyncPath(backupDir, file.path);
111253
- const targetDir = join141(targetPath, "..");
111554
+ const targetDir = join143(targetPath, "..");
111254
111555
  await mkdir37(targetDir, { recursive: true });
111255
111556
  await copyFile8(sourcePath, targetPath);
111256
111557
  }
@@ -111265,7 +111566,7 @@ async function createBackup(claudeDir3, files, backupDir) {
111265
111566
  }
111266
111567
  // src/commands/init/phases/transform-handler.ts
111267
111568
  init_config_manager();
111268
- import { join as join145 } from "node:path";
111569
+ import { join as join147 } from "node:path";
111269
111570
 
111270
111571
  // src/services/transformers/folder-path-transformer.ts
111271
111572
  init_logger();
@@ -111276,38 +111577,38 @@ init_logger();
111276
111577
  init_types3();
111277
111578
  var import_fs_extra39 = __toESM(require_lib(), 1);
111278
111579
  import { rename as rename13, rm as rm17 } from "node:fs/promises";
111279
- import { join as join142, relative as relative32 } from "node:path";
111580
+ import { join as join144, relative as relative32 } from "node:path";
111280
111581
  async function collectDirsToRename(extractDir, folders) {
111281
111582
  const dirsToRename = [];
111282
111583
  if (folders.docs !== DEFAULT_FOLDERS.docs) {
111283
- const docsPath = join142(extractDir, DEFAULT_FOLDERS.docs);
111584
+ const docsPath = join144(extractDir, DEFAULT_FOLDERS.docs);
111284
111585
  if (await import_fs_extra39.pathExists(docsPath)) {
111285
111586
  dirsToRename.push({
111286
111587
  from: docsPath,
111287
- to: join142(extractDir, folders.docs)
111588
+ to: join144(extractDir, folders.docs)
111288
111589
  });
111289
111590
  }
111290
- const claudeDocsPath = join142(extractDir, ".claude", DEFAULT_FOLDERS.docs);
111591
+ const claudeDocsPath = join144(extractDir, ".claude", DEFAULT_FOLDERS.docs);
111291
111592
  if (await import_fs_extra39.pathExists(claudeDocsPath)) {
111292
111593
  dirsToRename.push({
111293
111594
  from: claudeDocsPath,
111294
- to: join142(extractDir, ".claude", folders.docs)
111595
+ to: join144(extractDir, ".claude", folders.docs)
111295
111596
  });
111296
111597
  }
111297
111598
  }
111298
111599
  if (folders.plans !== DEFAULT_FOLDERS.plans) {
111299
- const plansPath = join142(extractDir, DEFAULT_FOLDERS.plans);
111600
+ const plansPath = join144(extractDir, DEFAULT_FOLDERS.plans);
111300
111601
  if (await import_fs_extra39.pathExists(plansPath)) {
111301
111602
  dirsToRename.push({
111302
111603
  from: plansPath,
111303
- to: join142(extractDir, folders.plans)
111604
+ to: join144(extractDir, folders.plans)
111304
111605
  });
111305
111606
  }
111306
- const claudePlansPath = join142(extractDir, ".claude", DEFAULT_FOLDERS.plans);
111607
+ const claudePlansPath = join144(extractDir, ".claude", DEFAULT_FOLDERS.plans);
111307
111608
  if (await import_fs_extra39.pathExists(claudePlansPath)) {
111308
111609
  dirsToRename.push({
111309
111610
  from: claudePlansPath,
111310
- to: join142(extractDir, ".claude", folders.plans)
111611
+ to: join144(extractDir, ".claude", folders.plans)
111311
111612
  });
111312
111613
  }
111313
111614
  }
@@ -111348,7 +111649,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
111348
111649
  init_logger();
111349
111650
  init_types3();
111350
111651
  import { readFile as readFile62, readdir as readdir43, writeFile as writeFile36 } from "node:fs/promises";
111351
- import { join as join143, relative as relative33 } from "node:path";
111652
+ import { join as join145, relative as relative33 } from "node:path";
111352
111653
  var TRANSFORMABLE_FILE_PATTERNS = [
111353
111654
  ".md",
111354
111655
  ".txt",
@@ -111401,7 +111702,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
111401
111702
  let replacementsCount = 0;
111402
111703
  const entries = await readdir43(dir, { withFileTypes: true });
111403
111704
  for (const entry of entries) {
111404
- const fullPath = join143(dir, entry.name);
111705
+ const fullPath = join145(dir, entry.name);
111405
111706
  if (entry.isDirectory()) {
111406
111707
  if (entry.name === "node_modules" || entry.name === ".git") {
111407
111708
  continue;
@@ -111538,7 +111839,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
111538
111839
  init_logger();
111539
111840
  import { readFile as readFile63, readdir as readdir44, writeFile as writeFile37 } from "node:fs/promises";
111540
111841
  import { homedir as homedir48, platform as platform16 } from "node:os";
111541
- import { extname as extname7, join as join144 } from "node:path";
111842
+ import { extname as extname7, join as join146 } from "node:path";
111542
111843
  var IS_WINDOWS3 = platform16() === "win32";
111543
111844
  var HOME_PREFIX = "$HOME";
111544
111845
  function getHomeDirPrefix() {
@@ -111548,7 +111849,7 @@ function normalizeInstallPath(path17) {
111548
111849
  return path17.replace(/\\/g, "/").replace(/\/+$/, "");
111549
111850
  }
111550
111851
  function getDefaultGlobalClaudeDir() {
111551
- return normalizeInstallPath(join144(homedir48(), ".claude"));
111852
+ return normalizeInstallPath(join146(homedir48(), ".claude"));
111552
111853
  }
111553
111854
  function getCustomGlobalClaudeDir(targetClaudeDir) {
111554
111855
  if (!targetClaudeDir)
@@ -111679,7 +111980,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
111679
111980
  async function processDirectory2(dir) {
111680
111981
  const entries = await readdir44(dir, { withFileTypes: true });
111681
111982
  for (const entry of entries) {
111682
- const fullPath = join144(dir, entry.name);
111983
+ const fullPath = join146(dir, entry.name);
111683
111984
  if (entry.isDirectory()) {
111684
111985
  if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
111685
111986
  continue;
@@ -111758,7 +112059,7 @@ async function handleTransforms(ctx) {
111758
112059
  logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
111759
112060
  }
111760
112061
  }
111761
- const claudeDir3 = ctx.options.global ? ctx.resolvedDir : join145(ctx.resolvedDir, ".claude");
112062
+ const claudeDir3 = ctx.options.global ? ctx.resolvedDir : join147(ctx.resolvedDir, ".claude");
111762
112063
  return {
111763
112064
  ...ctx,
111764
112065
  foldersConfig,
@@ -111986,7 +112287,7 @@ var import_picocolors30 = __toESM(require_picocolors(), 1);
111986
112287
  import { existsSync as existsSync72 } from "node:fs";
111987
112288
  import { readFile as readFile67, rm as rm18, unlink as unlink14 } from "node:fs/promises";
111988
112289
  import { homedir as homedir52 } from "node:os";
111989
- import { basename as basename30, dirname as dirname49, join as join149, resolve as resolve50 } from "node:path";
112290
+ import { basename as basename30, dirname as dirname49, join as join151, resolve as resolve50 } from "node:path";
111990
112291
  init_logger();
111991
112292
 
111992
112293
  // src/ui/ck-cli-design/next-steps-footer.ts
@@ -112201,13 +112502,13 @@ init_dist2();
112201
112502
  init_model_taxonomy();
112202
112503
  import { mkdir as mkdir39, readFile as readFile66, writeFile as writeFile39 } from "node:fs/promises";
112203
112504
  import { homedir as homedir51 } from "node:os";
112204
- import { dirname as dirname47, join as join148 } from "node:path";
112505
+ import { dirname as dirname47, join as join150 } from "node:path";
112205
112506
 
112206
112507
  // src/commands/portable/models-dev-cache.ts
112207
112508
  init_logger();
112208
112509
  import { mkdir as mkdir38, readFile as readFile64, rename as rename14, writeFile as writeFile38 } from "node:fs/promises";
112209
112510
  import { homedir as homedir49 } from "node:os";
112210
- import { join as join146 } from "node:path";
112511
+ import { join as join148 } from "node:path";
112211
112512
 
112212
112513
  class ModelsDevUnavailableError extends Error {
112213
112514
  constructor(message, cause) {
@@ -112219,13 +112520,13 @@ var MODELS_DEV_URL = "https://models.dev/api.json";
112219
112520
  var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
112220
112521
  var FETCH_TIMEOUT_MS = 1e4;
112221
112522
  function defaultCacheDir() {
112222
- return join146(homedir49(), ".config", "claudekit", "cache");
112523
+ return join148(homedir49(), ".config", "claudekit", "cache");
112223
112524
  }
112224
112525
  function cacheFilePath(cacheDir) {
112225
- return join146(cacheDir, "models-dev.json");
112526
+ return join148(cacheDir, "models-dev.json");
112226
112527
  }
112227
112528
  function tmpFilePath(cacheDir) {
112228
- return join146(cacheDir, "models-dev.json.tmp");
112529
+ return join148(cacheDir, "models-dev.json.tmp");
112229
112530
  }
112230
112531
  async function readCacheEntry(cacheDir) {
112231
112532
  const filePath = cacheFilePath(cacheDir);
@@ -112300,14 +112601,14 @@ async function getModelsDevCatalog(opts = {}) {
112300
112601
  init_logger();
112301
112602
  import { readFile as readFile65 } from "node:fs/promises";
112302
112603
  import { homedir as homedir50, platform as platform17 } from "node:os";
112303
- import { join as join147 } from "node:path";
112604
+ import { join as join149 } from "node:path";
112304
112605
  function resolveOpenCodeAuthPath(homeDir) {
112305
112606
  if (platform17() === "win32") {
112306
- const dataRoot2 = process.env.LOCALAPPDATA ?? join147(homeDir, "AppData", "Local");
112307
- return join147(dataRoot2, "opencode", "auth.json");
112607
+ const dataRoot2 = process.env.LOCALAPPDATA ?? join149(homeDir, "AppData", "Local");
112608
+ return join149(dataRoot2, "opencode", "auth.json");
112308
112609
  }
112309
- const dataRoot = process.env.XDG_DATA_HOME ?? join147(homeDir, ".local", "share");
112310
- return join147(dataRoot, "opencode", "auth.json");
112610
+ const dataRoot = process.env.XDG_DATA_HOME ?? join149(homeDir, ".local", "share");
112611
+ return join149(dataRoot, "opencode", "auth.json");
112311
112612
  }
112312
112613
  async function readAuthedProviders(homeDir) {
112313
112614
  const authPath = resolveOpenCodeAuthPath(homeDir);
@@ -112409,9 +112710,9 @@ function messageForReason(reason) {
112409
112710
  }
112410
112711
  function getOpenCodeConfigPath(options2) {
112411
112712
  if (options2.global) {
112412
- return join148(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
112713
+ return join150(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
112413
112714
  }
112414
- return join148(options2.cwd ?? process.cwd(), "opencode.json");
112715
+ return join150(options2.cwd ?? process.cwd(), "opencode.json");
112415
112716
  }
112416
112717
  function makeCatalogOpts(options2) {
112417
112718
  return {
@@ -113284,7 +113585,7 @@ function appendFallbackSkillActionsToPlan(plan, skills, selectedProviders, insta
113284
113585
  reason: "New item, not previously installed",
113285
113586
  reasonCode: "new-item",
113286
113587
  reasonCopy: "New - not previously installed",
113287
- targetPath: join149(basePath, skill.name),
113588
+ targetPath: join151(basePath, skill.name),
113288
113589
  type: "skill"
113289
113590
  });
113290
113591
  }
@@ -113512,7 +113813,7 @@ function resolveHookTargetPath(item, provider, global3) {
113512
113813
  const converted = convertItem(item, pathConfig.format, provider, { global: global3 });
113513
113814
  if (converted.error)
113514
113815
  return null;
113515
- const targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join149(basePath, converted.filename);
113816
+ const targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join151(basePath, converted.filename);
113516
113817
  const resolvedTarget = resolve50(targetPath).replace(/\\/g, "/");
113517
113818
  const resolvedBase = resolve50(basePath).replace(/\\/g, "/").replace(/\/+$/, "");
113518
113819
  if (resolvedTarget !== resolvedBase && !resolvedTarget.startsWith(`${resolvedBase}/`)) {
@@ -113523,7 +113824,7 @@ function resolveHookTargetPath(item, provider, global3) {
113523
113824
  async function processMetadataDeletions(skillSourcePath, installGlobally) {
113524
113825
  if (!skillSourcePath)
113525
113826
  return;
113526
- const sourceMetadataPath = join149(resolve50(skillSourcePath, ".."), "metadata.json");
113827
+ const sourceMetadataPath = join151(resolve50(skillSourcePath, ".."), "metadata.json");
113527
113828
  if (!existsSync72(sourceMetadataPath))
113528
113829
  return;
113529
113830
  let sourceMetadata;
@@ -113536,7 +113837,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
113536
113837
  }
113537
113838
  if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
113538
113839
  return;
113539
- const claudeDir3 = installGlobally ? join149(homedir52(), ".claude") : join149(process.cwd(), ".claude");
113840
+ const claudeDir3 = installGlobally ? join151(homedir52(), ".claude") : join151(process.cwd(), ".claude");
113540
113841
  if (!existsSync72(claudeDir3))
113541
113842
  return;
113542
113843
  try {
@@ -113664,8 +113965,8 @@ async function migrateCommand(options2) {
113664
113965
  let requestedGlobal = options2.global ?? false;
113665
113966
  let installGlobally = requestedGlobal;
113666
113967
  if (options2.global === undefined && !options2.yes) {
113667
- const projectTarget = join149(process.cwd(), ".claude");
113668
- const globalTarget = join149(homedir52(), ".claude");
113968
+ const projectTarget = join151(process.cwd(), ".claude");
113969
+ const globalTarget = join151(homedir52(), ".claude");
113669
113970
  const scopeChoice = await ie({
113670
113971
  message: "Installation scope",
113671
113972
  options: [
@@ -113738,7 +114039,7 @@ async function migrateCommand(options2) {
113738
114039
  }).join(`
113739
114040
  `));
113740
114041
  if (sourceGlobalOnly) {
113741
- f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join149(homedir52(), ".claude"))}`));
114042
+ f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join151(homedir52(), ".claude"))}`));
113742
114043
  } else {
113743
114044
  f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
113744
114045
  }
@@ -114047,7 +114348,7 @@ async function migrateCommand(options2) {
114047
114348
  for (const [hooksProvider, entry] of successfulHookFiles) {
114048
114349
  if (entry.files.length === 0)
114049
114350
  continue;
114050
- const sourceSettingsPath = hooksSource ? join149(dirname49(hooksSource), "settings.json") : undefined;
114351
+ const sourceSettingsPath = hooksSource ? join151(dirname49(hooksSource), "settings.json") : undefined;
114051
114352
  const mergeResult = await migrateHooksSettings({
114052
114353
  sourceProvider: "claude-code",
114053
114354
  targetProvider: hooksProvider,
@@ -114425,7 +114726,7 @@ async function handleDirectorySetup(ctx) {
114425
114726
  // src/commands/new/phases/project-creation.ts
114426
114727
  init_config_manager();
114427
114728
  init_github_client();
114428
- import { join as join150 } from "node:path";
114729
+ import { join as join152 } from "node:path";
114429
114730
  init_logger();
114430
114731
  init_output_manager();
114431
114732
  init_types3();
@@ -114551,7 +114852,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
114551
114852
  output.section("Installing");
114552
114853
  logger.verbose("Installation target", { directory: resolvedDir });
114553
114854
  const merger = new FileMerger;
114554
- const claudeDir3 = join150(resolvedDir, ".claude");
114855
+ const claudeDir3 = join152(resolvedDir, ".claude");
114555
114856
  merger.setMultiKitContext(claudeDir3, kit);
114556
114857
  if (validOptions.exclude && validOptions.exclude.length > 0) {
114557
114858
  merger.addIgnorePatterns(validOptions.exclude);
@@ -114598,7 +114899,7 @@ async function handleProjectCreation(ctx) {
114598
114899
  }
114599
114900
  // src/commands/new/phases/post-setup.ts
114600
114901
  init_projects_registry();
114601
- import { join as join151 } from "node:path";
114902
+ import { join as join153 } from "node:path";
114602
114903
  init_package_installer();
114603
114904
  init_logger();
114604
114905
  init_path_resolver();
@@ -114630,9 +114931,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
114630
114931
  withSudo: validOptions.withSudo
114631
114932
  });
114632
114933
  }
114633
- const claudeDir3 = join151(resolvedDir, ".claude");
114934
+ const claudeDir3 = join153(resolvedDir, ".claude");
114634
114935
  await promptSetupWizardIfNeeded({
114635
- envPath: join151(claudeDir3, ".env"),
114936
+ envPath: join153(claudeDir3, ".env"),
114636
114937
  claudeDir: claudeDir3,
114637
114938
  isGlobal: false,
114638
114939
  isNonInteractive: isNonInteractive2,
@@ -114702,7 +115003,7 @@ Please use only one download method.`);
114702
115003
  // src/commands/plan/plan-command.ts
114703
115004
  init_output_manager();
114704
115005
  import { existsSync as existsSync75, statSync as statSync13 } from "node:fs";
114705
- import { dirname as dirname53, isAbsolute as isAbsolute15, join as join154, parse as parse7, resolve as resolve55 } from "node:path";
115006
+ import { dirname as dirname53, isAbsolute as isAbsolute15, join as join156, parse as parse7, resolve as resolve55 } from "node:path";
114706
115007
 
114707
115008
  // src/commands/plan/plan-read-handlers.ts
114708
115009
  init_config();
@@ -114712,14 +115013,14 @@ init_logger();
114712
115013
  init_output_manager();
114713
115014
  var import_picocolors32 = __toESM(require_picocolors(), 1);
114714
115015
  import { existsSync as existsSync74, statSync as statSync12 } from "node:fs";
114715
- import { basename as basename31, dirname as dirname51, join as join153, relative as relative34, resolve as resolve53 } from "node:path";
115016
+ import { basename as basename31, dirname as dirname51, join as join155, relative as relative34, resolve as resolve53 } from "node:path";
114716
115017
 
114717
115018
  // src/commands/plan/plan-dependencies.ts
114718
115019
  init_config();
114719
115020
  init_plan_parser();
114720
115021
  init_plans_registry();
114721
115022
  import { existsSync as existsSync73 } from "node:fs";
114722
- import { dirname as dirname50, join as join152 } from "node:path";
115023
+ import { dirname as dirname50, join as join154 } from "node:path";
114723
115024
  async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
114724
115025
  if (references.length === 0)
114725
115026
  return [];
@@ -114739,7 +115040,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
114739
115040
  };
114740
115041
  }
114741
115042
  const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
114742
- const planFile = join152(scopeRoot, planId, "plan.md");
115043
+ const planFile = join154(scopeRoot, planId, "plan.md");
114743
115044
  const isSelfReference = planFile === currentPlanFile;
114744
115045
  if (!existsSync73(planFile)) {
114745
115046
  return {
@@ -114881,7 +115182,7 @@ async function handleStatus(target, options2) {
114881
115182
  }
114882
115183
  const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
114883
115184
  const t = effectiveTarget ? resolve53(effectiveTarget) : null;
114884
- const plansDir = t && existsSync74(t) && statSync12(t).isDirectory() && !existsSync74(join153(t, "plan.md")) ? t : null;
115185
+ const plansDir = t && existsSync74(t) && statSync12(t).isDirectory() && !existsSync74(join155(t, "plan.md")) ? t : null;
114885
115186
  if (plansDir) {
114886
115187
  const planFiles = scanPlanDir(plansDir);
114887
115188
  if (planFiles.length === 0) {
@@ -115310,7 +115611,7 @@ function resolvePlanFile(target, baseDir) {
115310
115611
  const stat24 = statSync13(t);
115311
115612
  if (stat24.isFile())
115312
115613
  return t;
115313
- const candidate = join154(t, "plan.md");
115614
+ const candidate = join156(t, "plan.md");
115314
115615
  if (existsSync75(candidate))
115315
115616
  return candidate;
115316
115617
  }
@@ -115318,7 +115619,7 @@ function resolvePlanFile(target, baseDir) {
115318
115619
  let dir = process.cwd();
115319
115620
  const root = parse7(dir).root;
115320
115621
  while (dir !== root) {
115321
- const candidate = join154(dir, "plan.md");
115622
+ const candidate = join156(dir, "plan.md");
115322
115623
  if (existsSync75(candidate))
115323
115624
  return candidate;
115324
115625
  dir = dirname53(dir);
@@ -115839,10 +116140,10 @@ init_agents();
115839
116140
  var import_gray_matter12 = __toESM(require_gray_matter(), 1);
115840
116141
  var import_picocolors37 = __toESM(require_picocolors(), 1);
115841
116142
  import { readFile as readFile68 } from "node:fs/promises";
115842
- import { join as join156 } from "node:path";
116143
+ import { join as join158 } from "node:path";
115843
116144
 
115844
116145
  // src/commands/skills/installed-skills-inventory.ts
115845
- import { join as join155, resolve as resolve57 } from "node:path";
116146
+ import { join as join157, resolve as resolve57 } from "node:path";
115846
116147
  init_path_resolver();
115847
116148
  var SCOPE_SORT_ORDER = {
115848
116149
  project: 0,
@@ -115854,8 +116155,8 @@ async function getActiveClaudeSkillInstallations(options2 = {}) {
115854
116155
  const projectClaudeDir = resolve57(projectDir, ".claude");
115855
116156
  const projectScopeAliasesGlobal = projectClaudeDir === globalDir;
115856
116157
  const [projectSkills, globalSkills] = await Promise.all([
115857
- projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join155(projectClaudeDir, "skills")),
115858
- scanSkills2(join155(globalDir, "skills"))
116158
+ projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join157(projectClaudeDir, "skills")),
116159
+ scanSkills2(join157(globalDir, "skills"))
115859
116160
  ]);
115860
116161
  const projectIds = new Set(projectSkills.map((skill) => skill.id));
115861
116162
  const globalIds = new Set(globalSkills.map((skill) => skill.id));
@@ -116016,7 +116317,7 @@ async function handleValidate2(sourcePath) {
116016
116317
  spinner.stop(`Checked ${skills.length} skill(s)`);
116017
116318
  let hasIssues = false;
116018
116319
  for (const skill of skills) {
116019
- const skillMdPath = join156(skill.path, "SKILL.md");
116320
+ const skillMdPath = join158(skill.path, "SKILL.md");
116020
116321
  try {
116021
116322
  const content = await readFile68(skillMdPath, "utf-8");
116022
116323
  const { data } = import_gray_matter12.default(content, {
@@ -116599,7 +116900,7 @@ async function detectInstallations() {
116599
116900
 
116600
116901
  // src/commands/uninstall/removal-handler.ts
116601
116902
  import { readdirSync as readdirSync14, rmSync as rmSync8 } from "node:fs";
116602
- import { basename as basename33, join as join159, resolve as resolve58, sep as sep14 } from "node:path";
116903
+ import { basename as basename33, join as join161, resolve as resolve58, sep as sep14 } from "node:path";
116603
116904
  init_logger();
116604
116905
  init_safe_prompts();
116605
116906
  init_safe_spinner();
@@ -116608,7 +116909,7 @@ var import_fs_extra44 = __toESM(require_lib(), 1);
116608
116909
  // src/commands/uninstall/analysis-handler.ts
116609
116910
  init_metadata_migration();
116610
116911
  import { readdirSync as readdirSync13, rmSync as rmSync7 } from "node:fs";
116611
- import { dirname as dirname54, join as join157 } from "node:path";
116912
+ import { dirname as dirname54, join as join159 } from "node:path";
116612
116913
  init_logger();
116613
116914
  init_safe_prompts();
116614
116915
  var import_fs_extra42 = __toESM(require_lib(), 1);
@@ -116668,7 +116969,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
116668
116969
  const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
116669
116970
  for (const file of remainingFiles) {
116670
116971
  const relativePath = normalizeTrackedPath(file.path);
116671
- if (await import_fs_extra42.pathExists(join157(installation.path, relativePath))) {
116972
+ if (await import_fs_extra42.pathExists(join159(installation.path, relativePath))) {
116672
116973
  result.retainedManifestPaths.push(relativePath);
116673
116974
  }
116674
116975
  }
@@ -116676,7 +116977,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
116676
116977
  const kitFiles = metadata.kits[kit].files || [];
116677
116978
  for (const trackedFile of kitFiles) {
116678
116979
  const relativePath = normalizeTrackedPath(trackedFile.path);
116679
- const filePath = join157(installation.path, relativePath);
116980
+ const filePath = join159(installation.path, relativePath);
116680
116981
  if (preservedPaths.has(relativePath)) {
116681
116982
  result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
116682
116983
  continue;
@@ -116709,7 +117010,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
116709
117010
  }
116710
117011
  for (const trackedFile of allTrackedFiles) {
116711
117012
  const relativePath = normalizeTrackedPath(trackedFile.path);
116712
- const filePath = join157(installation.path, relativePath);
117013
+ const filePath = join159(installation.path, relativePath);
116713
117014
  const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
116714
117015
  if (!ownershipResult.exists)
116715
117016
  continue;
@@ -116760,7 +117061,7 @@ init_settings_merger();
116760
117061
  init_command_normalizer();
116761
117062
  init_logger();
116762
117063
  var import_fs_extra43 = __toESM(require_lib(), 1);
116763
- import { join as join158 } from "node:path";
117064
+ import { join as join160 } from "node:path";
116764
117065
  var CK_JSON_FILE2 = ".ck.json";
116765
117066
  var SETTINGS_FILE = "settings.json";
116766
117067
  var EMPTY_RESULT = {
@@ -116882,7 +117183,7 @@ async function cleanupCkJson(ckJsonPath, data, removedKitNames, dryRun) {
116882
117183
  return false;
116883
117184
  }
116884
117185
  async function cleanupUninstalledSettings(installationPath, options2) {
116885
- const ckJsonPath = join158(installationPath, CK_JSON_FILE2);
117186
+ const ckJsonPath = join160(installationPath, CK_JSON_FILE2);
116886
117187
  if (!await import_fs_extra43.pathExists(ckJsonPath)) {
116887
117188
  return { ...EMPTY_RESULT };
116888
117189
  }
@@ -116897,7 +117198,7 @@ async function cleanupUninstalledSettings(installationPath, options2) {
116897
117198
  const removedKitNames = options2.kit ? [options2.kit] : Object.keys(kits);
116898
117199
  const { hooks, servers } = resolveRemovalTargets(kits, removedKitNames, options2.remainingKits);
116899
117200
  const result = { ...EMPTY_RESULT };
116900
- const settingsPath = join158(installationPath, SETTINGS_FILE);
117201
+ const settingsPath = join160(installationPath, SETTINGS_FILE);
116901
117202
  const settings = await SettingsMerger.readSettingsFile(settingsPath);
116902
117203
  if (settings) {
116903
117204
  result.hooksRemoved = removeHooksFromSettings(settings, hooks);
@@ -117011,8 +117312,8 @@ async function removeInstallations(installations, options2) {
117011
117312
  }
117012
117313
  const mutatePaths = getUninstallMutatePaths({
117013
117314
  retainedManifestPaths: analysis.retainedManifestPaths,
117014
- settingsFileExists: await import_fs_extra44.pathExists(join159(installation.path, "settings.json")),
117015
- ckJsonExists: await import_fs_extra44.pathExists(join159(installation.path, ".ck.json"))
117315
+ settingsFileExists: await import_fs_extra44.pathExists(join161(installation.path, "settings.json")),
117316
+ ckJsonExists: await import_fs_extra44.pathExists(join161(installation.path, ".ck.json"))
117016
117317
  });
117017
117318
  let backup = null;
117018
117319
  if (analysis.toDelete.length > 0 || mutatePaths.length > 0) {
@@ -117040,7 +117341,7 @@ async function removeInstallations(installations, options2) {
117040
117341
  let removedCount = 0;
117041
117342
  let cleanedDirs = 0;
117042
117343
  for (const item of analysis.toDelete) {
117043
- const filePath = join159(installation.path, item.path);
117344
+ const filePath = join161(installation.path, item.path);
117044
117345
  if (!await import_fs_extra44.pathExists(filePath))
117045
117346
  continue;
117046
117347
  if (!await isPathSafeToRemove(filePath, installation.path)) {
@@ -117467,7 +117768,7 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
117467
117768
  init_logger();
117468
117769
  import { existsSync as existsSync82 } from "node:fs";
117469
117770
  import { rm as rm19 } from "node:fs/promises";
117470
- import { join as join166 } from "node:path";
117771
+ import { join as join168 } from "node:path";
117471
117772
  var import_picocolors41 = __toESM(require_picocolors(), 1);
117472
117773
 
117473
117774
  // src/commands/watch/phases/implementation-runner.ts
@@ -117986,7 +118287,7 @@ function spawnAndCollect3(command, args) {
117986
118287
 
117987
118288
  // src/commands/watch/phases/issue-processor.ts
117988
118289
  import { mkdir as mkdir40, writeFile as writeFile42 } from "node:fs/promises";
117989
- import { join as join162 } from "node:path";
118290
+ import { join as join164 } from "node:path";
117990
118291
 
117991
118292
  // src/commands/watch/phases/approval-detector.ts
117992
118293
  init_logger();
@@ -118364,9 +118665,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
118364
118665
 
118365
118666
  // src/commands/watch/phases/plan-dir-finder.ts
118366
118667
  import { readdir as readdir46, stat as stat24 } from "node:fs/promises";
118367
- import { join as join161 } from "node:path";
118668
+ import { join as join163 } from "node:path";
118368
118669
  async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
118369
- const plansRoot = join161(cwd2, "plans");
118670
+ const plansRoot = join163(cwd2, "plans");
118370
118671
  try {
118371
118672
  const entries = await readdir46(plansRoot);
118372
118673
  const tenMinAgo = Date.now() - 10 * 60 * 1000;
@@ -118375,14 +118676,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
118375
118676
  for (const entry of entries) {
118376
118677
  if (entry === "watch" || entry === "reports" || entry === "visuals")
118377
118678
  continue;
118378
- const dirPath = join161(plansRoot, entry);
118679
+ const dirPath = join163(plansRoot, entry);
118379
118680
  const dirStat = await stat24(dirPath);
118380
118681
  if (!dirStat.isDirectory())
118381
118682
  continue;
118382
118683
  if (dirStat.mtimeMs < tenMinAgo)
118383
118684
  continue;
118384
118685
  try {
118385
- await stat24(join161(dirPath, "plan.md"));
118686
+ await stat24(join163(dirPath, "plan.md"));
118386
118687
  } catch {
118387
118688
  continue;
118388
118689
  }
@@ -118613,13 +118914,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
118613
118914
  stats.plansCreated++;
118614
118915
  const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
118615
118916
  if (detectedPlanDir) {
118616
- state.activeIssues[numStr].planPath = join162(detectedPlanDir, "plan.md");
118917
+ state.activeIssues[numStr].planPath = join164(detectedPlanDir, "plan.md");
118617
118918
  watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
118618
118919
  } else {
118619
118920
  try {
118620
- const planDir = join162(projectDir, "plans", "watch");
118921
+ const planDir = join164(projectDir, "plans", "watch");
118621
118922
  await mkdir40(planDir, { recursive: true });
118622
- const planFilePath = join162(planDir, `issue-${issue.number}-plan.md`);
118923
+ const planFilePath = join164(planDir, `issue-${issue.number}-plan.md`);
118623
118924
  await writeFile42(planFilePath, planResult.planText, "utf-8");
118624
118925
  state.activeIssues[numStr].planPath = planFilePath;
118625
118926
  watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
@@ -118926,18 +119227,18 @@ init_logger();
118926
119227
  import { spawnSync as spawnSync7 } from "node:child_process";
118927
119228
  import { existsSync as existsSync79 } from "node:fs";
118928
119229
  import { readdir as readdir47, stat as stat25 } from "node:fs/promises";
118929
- import { join as join163 } from "node:path";
119230
+ import { join as join165 } from "node:path";
118930
119231
  async function scanForRepos(parentDir) {
118931
119232
  const repos = [];
118932
119233
  const entries = await readdir47(parentDir);
118933
119234
  for (const entry of entries) {
118934
119235
  if (entry.startsWith("."))
118935
119236
  continue;
118936
- const fullPath = join163(parentDir, entry);
119237
+ const fullPath = join165(parentDir, entry);
118937
119238
  const entryStat = await stat25(fullPath);
118938
119239
  if (!entryStat.isDirectory())
118939
119240
  continue;
118940
- const gitDir = join163(fullPath, ".git");
119241
+ const gitDir = join165(fullPath, ".git");
118941
119242
  if (!existsSync79(gitDir))
118942
119243
  continue;
118943
119244
  const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
@@ -118964,7 +119265,7 @@ init_logger();
118964
119265
  import { spawnSync as spawnSync8 } from "node:child_process";
118965
119266
  import { existsSync as existsSync80 } from "node:fs";
118966
119267
  import { homedir as homedir53 } from "node:os";
118967
- import { join as join164 } from "node:path";
119268
+ import { join as join166 } from "node:path";
118968
119269
  async function validateSetup(cwd2) {
118969
119270
  const workDir = cwd2 ?? process.cwd();
118970
119271
  const ghVersion = spawnSync8("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
@@ -118995,7 +119296,7 @@ Run this command from a directory with a GitHub remote.`);
118995
119296
  } catch {
118996
119297
  throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
118997
119298
  }
118998
- const skillsPath = join164(homedir53(), ".claude", "skills");
119299
+ const skillsPath = join166(homedir53(), ".claude", "skills");
118999
119300
  const skillsAvailable = existsSync80(skillsPath);
119000
119301
  if (!skillsAvailable) {
119001
119302
  logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
@@ -119014,7 +119315,7 @@ init_path_resolver();
119014
119315
  import { createWriteStream as createWriteStream3, statSync as statSync14 } from "node:fs";
119015
119316
  import { existsSync as existsSync81 } from "node:fs";
119016
119317
  import { mkdir as mkdir42, rename as rename15 } from "node:fs/promises";
119017
- import { join as join165 } from "node:path";
119318
+ import { join as join167 } from "node:path";
119018
119319
 
119019
119320
  class WatchLogger {
119020
119321
  logStream = null;
@@ -119022,7 +119323,7 @@ class WatchLogger {
119022
119323
  logPath = null;
119023
119324
  maxBytes;
119024
119325
  constructor(logDir, maxBytes = 0) {
119025
- this.logDir = logDir ?? join165(PathResolver.getClaudeKitDir(), "logs");
119326
+ this.logDir = logDir ?? join167(PathResolver.getClaudeKitDir(), "logs");
119026
119327
  this.maxBytes = maxBytes;
119027
119328
  }
119028
119329
  async init() {
@@ -119031,7 +119332,7 @@ class WatchLogger {
119031
119332
  await mkdir42(this.logDir, { recursive: true });
119032
119333
  }
119033
119334
  const dateStr = formatDate(new Date);
119034
- this.logPath = join165(this.logDir, `watch-${dateStr}.log`);
119335
+ this.logPath = join167(this.logDir, `watch-${dateStr}.log`);
119035
119336
  this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
119036
119337
  } catch (error) {
119037
119338
  logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
@@ -119213,7 +119514,7 @@ async function watchCommand(options2) {
119213
119514
  }
119214
119515
  async function discoverRepos(options2, watchLog) {
119215
119516
  const cwd2 = process.cwd();
119216
- const isGitRepo = existsSync82(join166(cwd2, ".git"));
119517
+ const isGitRepo = existsSync82(join168(cwd2, ".git"));
119217
119518
  if (options2.force) {
119218
119519
  await forceRemoveLock(watchLog);
119219
119520
  }
@@ -119470,8 +119771,8 @@ function registerCommands(cli) {
119470
119771
  // src/cli/version-display.ts
119471
119772
  init_package();
119472
119773
  init_config_version_checker();
119473
- import { existsSync as existsSync94, readFileSync as readFileSync27 } from "node:fs";
119474
- import { join as join178 } from "node:path";
119774
+ import { existsSync as existsSync94, readFileSync as readFileSync29 } from "node:fs";
119775
+ import { join as join180 } from "node:path";
119475
119776
 
119476
119777
  // src/domains/versioning/version-checker.ts
119477
119778
  init_version_utils();
@@ -119486,14 +119787,14 @@ init_logger();
119486
119787
  init_path_resolver();
119487
119788
  import { existsSync as existsSync93 } from "node:fs";
119488
119789
  import { mkdir as mkdir43, readFile as readFile73, writeFile as writeFile45 } from "node:fs/promises";
119489
- import { join as join177 } from "node:path";
119790
+ import { join as join179 } from "node:path";
119490
119791
 
119491
119792
  class VersionCacheManager {
119492
119793
  static CACHE_FILENAME = "version-check.json";
119493
119794
  static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
119494
119795
  static getCacheFile() {
119495
119796
  const cacheDir = PathResolver.getCacheDir(false);
119496
- return join177(cacheDir, VersionCacheManager.CACHE_FILENAME);
119797
+ return join179(cacheDir, VersionCacheManager.CACHE_FILENAME);
119497
119798
  }
119498
119799
  static async load() {
119499
119800
  const cacheFile = VersionCacheManager.getCacheFile();
@@ -119804,13 +120105,13 @@ async function displayVersion() {
119804
120105
  let localInstalledKits = [];
119805
120106
  let globalInstalledKits = [];
119806
120107
  const globalKitDir = PathResolver.getGlobalKitDir();
119807
- const globalMetadataPath = join178(globalKitDir, "metadata.json");
120108
+ const globalMetadataPath = join180(globalKitDir, "metadata.json");
119808
120109
  const prefix = PathResolver.getPathPrefix(false);
119809
- const localMetadataPath = prefix ? join178(process.cwd(), prefix, "metadata.json") : join178(process.cwd(), "metadata.json");
120110
+ const localMetadataPath = prefix ? join180(process.cwd(), prefix, "metadata.json") : join180(process.cwd(), "metadata.json");
119810
120111
  const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
119811
120112
  if (!isLocalSameAsGlobal && existsSync94(localMetadataPath)) {
119812
120113
  try {
119813
- const rawMetadata = JSON.parse(readFileSync27(localMetadataPath, "utf-8"));
120114
+ const rawMetadata = JSON.parse(readFileSync29(localMetadataPath, "utf-8"));
119814
120115
  const metadata = MetadataSchema.parse(rawMetadata);
119815
120116
  const kitsDisplay = formatInstalledKits(metadata);
119816
120117
  if (kitsDisplay) {
@@ -119824,7 +120125,7 @@ async function displayVersion() {
119824
120125
  }
119825
120126
  if (existsSync94(globalMetadataPath)) {
119826
120127
  try {
119827
- const rawMetadata = JSON.parse(readFileSync27(globalMetadataPath, "utf-8"));
120128
+ const rawMetadata = JSON.parse(readFileSync29(globalMetadataPath, "utf-8"));
119828
120129
  const metadata = MetadataSchema.parse(rawMetadata);
119829
120130
  const kitsDisplay = formatInstalledKits(metadata);
119830
120131
  if (kitsDisplay) {