claudekit-cli 4.0.0-dev.5 → 4.0.0-dev.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "4.0.0-dev.5",
3
- "generatedAt": "2026-05-10T00:07:05.385Z",
2
+ "version": "4.0.0-dev.7",
3
+ "generatedAt": "2026-05-10T14:28:28.796Z",
4
4
  "commands": {
5
5
  "agents": {
6
6
  "name": "agents",
package/dist/index.js CHANGED
@@ -53903,36 +53903,43 @@ function ensureFlagInFeaturesSection(content, headerStartIdx) {
53903
53903
  const nextHeaderMatch = /\n\[[^\]]+\]/.exec(rest);
53904
53904
  const bodyEnd = nextHeaderMatch ? bodyStart + nextHeaderMatch.index + 1 : content.length;
53905
53905
  const body = content.slice(bodyStart, bodyEnd);
53906
- const flagRegex = /^([ \t]*codex_hooks[ \t]*=[ \t]*)(true|false)([ \t]*#[^\r\n]*)?[ \t]*$/m;
53907
- const flagMatch = flagRegex.exec(body);
53906
+ const legacyFlagRegex = new RegExp(`^[ \\t]*${LEGACY_FEATURE_FLAG}[ \\t]*=[ \\t]*(?:true|false)(?:[ \\t]*#[^\\r\\n]*)?[ \\t]*(?:\\r?\\n|$)`, "gm");
53907
+ const cleanedBody = body.replace(legacyFlagRegex, "");
53908
+ const changed = cleanedBody !== body;
53909
+ const flagRegex = new RegExp(`^([ \\t]*${CURRENT_FEATURE_FLAG}[ \\t]*=[ \\t]*)(true|false)([ \\t]*#[^\\r\\n]*)?[ \\t]*$`, "m");
53910
+ const flagMatch = flagRegex.exec(cleanedBody);
53908
53911
  if (flagMatch) {
53909
53912
  if (flagMatch[2] === "true") {
53910
- return { updated: content, changed: false };
53913
+ return {
53914
+ updated: content.slice(0, bodyStart) + cleanedBody + content.slice(bodyEnd),
53915
+ changed
53916
+ };
53911
53917
  }
53912
- const newBody = body.replace(flagRegex, (_m, prefix, _v, trailing) => `${prefix}true${trailing ?? ""}`);
53918
+ const newBody2 = cleanedBody.replace(flagRegex, (_m, prefix, _v, trailing) => `${prefix}true${trailing ?? ""}`);
53913
53919
  return {
53914
- updated: content.slice(0, bodyStart) + newBody + content.slice(bodyEnd),
53920
+ updated: content.slice(0, bodyStart) + newBody2 + content.slice(bodyEnd),
53915
53921
  changed: true
53916
53922
  };
53917
53923
  }
53918
53924
  if (headerLineEnd === -1) {
53919
53925
  return { updated: `${content}
53920
- codex_hooks = true
53926
+ ${CURRENT_FEATURE_FLAG} = true
53921
53927
  `, changed: true };
53922
53928
  }
53923
- let insertAt = bodyEnd;
53924
- while (insertAt > bodyStart && content[insertAt - 1] === `
53925
- ` && content[insertAt - 2] === `
53929
+ let insertAt = cleanedBody.length;
53930
+ while (insertAt > 0 && cleanedBody[insertAt - 1] === `
53931
+ ` && cleanedBody[insertAt - 2] === `
53926
53932
  `) {
53927
53933
  insertAt -= 1;
53928
53934
  }
53929
- const needsLeadingNewline = insertAt > bodyStart && content[insertAt - 1] !== `
53935
+ const needsLeadingNewline = insertAt > 0 && cleanedBody[insertAt - 1] !== `
53930
53936
  `;
53931
53937
  const insertion = `${needsLeadingNewline ? `
53932
- ` : ""}codex_hooks = true
53938
+ ` : ""}${CURRENT_FEATURE_FLAG} = true
53933
53939
  `;
53940
+ const newBody = cleanedBody.slice(0, insertAt) + insertion + cleanedBody.slice(insertAt);
53934
53941
  return {
53935
- updated: content.slice(0, insertAt) + insertion + content.slice(insertAt),
53942
+ updated: content.slice(0, bodyStart) + newBody + content.slice(bodyEnd),
53936
53943
  changed: true
53937
53944
  };
53938
53945
  }
@@ -53976,12 +53983,12 @@ async function atomicWrite(filePath, content) {
53976
53983
  throw err;
53977
53984
  }
53978
53985
  }
53979
- var SENTINEL_START2 = "# --- ck-managed-features-start ---", SENTINEL_END2 = "# --- ck-managed-features-end ---", MANAGED_BLOCK;
53986
+ var SENTINEL_START2 = "# --- ck-managed-features-start ---", SENTINEL_END2 = "# --- ck-managed-features-end ---", CURRENT_FEATURE_FLAG = "hooks", LEGACY_FEATURE_FLAG = "codex_hooks", MANAGED_BLOCK;
53980
53987
  var init_codex_features_flag = __esm(() => {
53981
53988
  init_codex_path_safety();
53982
53989
  MANAGED_BLOCK = `${SENTINEL_START2}
53983
53990
  [features]
53984
- codex_hooks = true
53991
+ ${CURRENT_FEATURE_FLAG} = true
53985
53992
  ${SENTINEL_END2}`;
53986
53993
  });
53987
53994
 
@@ -62835,7 +62842,7 @@ var package_default;
62835
62842
  var init_package = __esm(() => {
62836
62843
  package_default = {
62837
62844
  name: "claudekit-cli",
62838
- version: "4.0.0-dev.5",
62845
+ version: "4.0.0-dev.7",
62839
62846
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
62840
62847
  type: "module",
62841
62848
  repository: {
@@ -85501,23 +85508,43 @@ import { existsSync as existsSync55 } from "node:fs";
85501
85508
  import { readdir as readdir20 } from "node:fs/promises";
85502
85509
  import { join as join80 } from "node:path";
85503
85510
  async function checkProjectConfigCompleteness(setup, projectDir) {
85511
+ const baseResult = {
85512
+ id: "ck-project-config-complete",
85513
+ name: "Project Config Completeness",
85514
+ group: "claudekit",
85515
+ priority: "standard",
85516
+ autoFixable: false
85517
+ };
85504
85518
  if (setup.project.path === setup.global.path) {
85505
85519
  return {
85506
- id: "ck-project-config-complete",
85507
- name: "Project Config Completeness",
85508
- group: "claudekit",
85509
- priority: "standard",
85520
+ ...baseResult,
85510
85521
  status: "info",
85511
- message: "Not in a project directory",
85512
- autoFixable: false
85522
+ message: "Not in a project directory"
85523
+ };
85524
+ }
85525
+ const hasGlobalInstall = !!setup.global.metadata;
85526
+ const hasProjectOptIn = !!setup.project.metadata;
85527
+ if (!hasProjectOptIn) {
85528
+ if (hasGlobalInstall) {
85529
+ return {
85530
+ ...baseResult,
85531
+ status: "info",
85532
+ message: "Using global ClaudeKit (no project override)",
85533
+ details: "Run 'ck init' here only if you want project-specific agents/skills/rules"
85534
+ };
85535
+ }
85536
+ return {
85537
+ ...baseResult,
85538
+ status: "warn",
85539
+ message: "ClaudeKit not installed",
85540
+ suggestion: "Run 'ck init' (choose global or project scope when prompted)"
85513
85541
  };
85514
85542
  }
85515
85543
  const projectClaudeDir = join80(projectDir, ".claude");
85516
85544
  const requiredDirs = ["agents", "commands", "skills"];
85517
85545
  const missingDirs = [];
85518
85546
  for (const dir of requiredDirs) {
85519
- const dirPath = join80(projectClaudeDir, dir);
85520
- if (!existsSync55(dirPath)) {
85547
+ if (!existsSync55(join80(projectClaudeDir, dir))) {
85521
85548
  missingDirs.push(dir);
85522
85549
  }
85523
85550
  }
@@ -85530,39 +85557,27 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
85530
85557
  const totalRequired = requiredDirs.length + 1;
85531
85558
  if (hasOnlyClaudeMd || missingDirs.length === totalRequired) {
85532
85559
  return {
85533
- id: "ck-project-config-complete",
85534
- name: "Project Config Completeness",
85535
- group: "claudekit",
85536
- priority: "standard",
85560
+ ...baseResult,
85537
85561
  status: "fail",
85538
85562
  message: "Incomplete configuration",
85539
85563
  details: "Only CLAUDE.md found - missing agents, commands, rules, skills",
85540
- suggestion: "Run 'ck init' to install complete ClaudeKit in project",
85541
- autoFixable: false
85564
+ suggestion: "Run 'ck init' to install complete ClaudeKit in project"
85542
85565
  };
85543
85566
  }
85544
85567
  if (missingDirs.length > 0) {
85545
85568
  return {
85546
- id: "ck-project-config-complete",
85547
- name: "Project Config Completeness",
85548
- group: "claudekit",
85549
- priority: "standard",
85569
+ ...baseResult,
85550
85570
  status: "warn",
85551
85571
  message: `Missing ${missingDirs.length} directories`,
85552
85572
  details: `Missing: ${missingDirs.join(", ")}`,
85553
- suggestion: "Run 'ck init' to update project configuration",
85554
- autoFixable: false
85573
+ suggestion: "Run 'ck init' to update project configuration"
85555
85574
  };
85556
85575
  }
85557
85576
  return {
85558
- id: "ck-project-config-complete",
85559
- name: "Project Config Completeness",
85560
- group: "claudekit",
85561
- priority: "standard",
85577
+ ...baseResult,
85562
85578
  status: "pass",
85563
85579
  message: "Complete configuration",
85564
- details: projectClaudeDir,
85565
- autoFixable: false
85580
+ details: projectClaudeDir
85566
85581
  };
85567
85582
  }
85568
85583
  // src/domains/health-checks/checkers/env-keys-checker.ts
@@ -107560,12 +107575,15 @@ function renderPreflightRow(options2) {
107560
107575
  const icon = options2.icon ?? context.box.bullet;
107561
107576
  const label = padVisible(options2.label, 10);
107562
107577
  const count = String(options2.count).padStart(3, " ");
107563
- const prefix = ` [${icon}] ${label} ${count} -> `;
107564
- const availableWidth = Math.max(10, context.width - prefix.length);
107578
+ const prefix = ` [${icon}] ${label} ${count} `;
107579
+ const flowPrefix = `${" ".repeat(prefix.length)}-> `;
107580
+ const availableWidth = Math.max(10, context.width - flowPrefix.length);
107565
107581
  const [firstDestination, ...extraDestinations] = options2.destinations.length > 0 ? options2.destinations : ["unsupported for selected provider(s)"];
107566
- const lines = [`${prefix}${truncateMiddle(firstDestination, availableWidth)}`];
107582
+ const source = options2.source ? `from ${options2.source}` : "from source unavailable";
107583
+ const lines = [`${prefix}${truncateMiddle(source, Math.max(10, context.width - prefix.length))}`];
107584
+ lines.push(`${flowPrefix}${truncateMiddle(firstDestination, availableWidth)}`);
107567
107585
  for (const destination of extraDestinations) {
107568
- lines.push(`${" ".repeat(prefix.length)}${truncateMiddle(destination, availableWidth)}`);
107586
+ lines.push(`${flowPrefix}${truncateMiddle(destination, availableWidth)}`);
107569
107587
  }
107570
107588
  for (const note2 of options2.notes ?? []) {
107571
107589
  lines.push(`${" ".repeat(prefix.length)}${paint(`(${note2})`, "muted", context)}`);
@@ -108583,6 +108601,13 @@ var PORTABLE_TYPES = [
108583
108601
  { key: "hooks", label: "Hooks" }
108584
108602
  ];
108585
108603
  var MERGE_STRATEGIES = new Set(["merge-single", "yaml-merge", "json-merge"]);
108604
+ var DISCOVERY_NOUNS = {
108605
+ Agents: "agent",
108606
+ Commands: "command",
108607
+ Hooks: "hook",
108608
+ Rules: "rule",
108609
+ Skills: "skill"
108610
+ };
108586
108611
  function buildPreflightRows(counts, selectedProviders, options2) {
108587
108612
  return PORTABLE_TYPES.flatMap(({ key, label }) => {
108588
108613
  const count = counts[key];
@@ -108628,7 +108653,8 @@ function buildPreflightRows(counts, selectedProviders, options2) {
108628
108653
  count,
108629
108654
  destinations: Array.from(destinations.keys()),
108630
108655
  label,
108631
- notes: Array.from(notes)
108656
+ notes: Array.from(notes),
108657
+ source: options2.sourceDisplays?.[key]
108632
108658
  }
108633
108659
  ];
108634
108660
  });
@@ -108638,10 +108664,15 @@ function buildTargetSummaryLines(rows) {
108638
108664
  if (allDestinations.length === 0) {
108639
108665
  return ["No compatible destination found for the selected providers"];
108640
108666
  }
108641
- if (allDestinations.length <= 3) {
108642
- return allDestinations;
108643
- }
108644
- return [...allDestinations.slice(0, 3), `+${allDestinations.length - 3} more destination(s)`];
108667
+ return allDestinations;
108668
+ }
108669
+ function buildDiscoverySummaryLines(rows) {
108670
+ return rows.map((row) => {
108671
+ const noun = DISCOVERY_NOUNS[row.label] ?? row.label.toLowerCase();
108672
+ const count = row.label === "Config" ? "config" : `${row.count} ${noun}${row.count === 1 ? "" : "s"}`;
108673
+ const source = row.source ? ` <- ${row.source}` : "";
108674
+ return `${row.label.padEnd(8)} ${count}${source}`;
108675
+ });
108645
108676
  }
108646
108677
  function buildProviderScopeSubtitle(selectedProviders, requestedGlobal, counts) {
108647
108678
  const activeTypes = PORTABLE_TYPES.filter(({ key }) => !counts || counts[key] > 0);
@@ -109087,33 +109118,22 @@ async function migrateCommand(options2) {
109087
109118
  rulesSourcePath,
109088
109119
  hooksSource
109089
109120
  ].filter((origin) => origin !== null);
109090
- const preflightRows = buildPreflightRows(sourceCounts, selectedProviders, {
109091
- requestedGlobal
109092
- });
109093
- const discoveryParts = [];
109094
109121
  const agentSourceDisplay = agentSource ? formatDisplayPath(agentSource) : "source unavailable";
109095
109122
  const commandSourceDisplay = commandSource ? formatDisplayPath(commandSource) : "source unavailable";
109096
109123
  const skillSourceDisplay = skillSource ? formatDisplayPath(skillSource) : "source unavailable";
109097
109124
  const rulesSourceDisplay = rulesSourcePath ? formatDisplayPath(rulesSourcePath) : "source unavailable";
109098
109125
  const hooksSourceDisplay = hooksSource ? formatDisplayPath(hooksSource) : "source unavailable";
109099
- if (agents2.length > 0) {
109100
- discoveryParts.push(`${agents2.length} agent(s) ${import_picocolors30.default.dim(`<- ${agentSourceDisplay}`)}`);
109101
- }
109102
- if (commands.length > 0) {
109103
- discoveryParts.push(`${commands.length} command(s) ${import_picocolors30.default.dim(`<- ${commandSourceDisplay}`)}`);
109104
- }
109105
- if (skills.length > 0) {
109106
- discoveryParts.push(`${skills.length} skill(s) ${import_picocolors30.default.dim(`<- ${skillSourceDisplay}`)}`);
109107
- }
109108
- if (configItem) {
109109
- discoveryParts.push(`config ${import_picocolors30.default.dim(`<- ${formatDisplayPath(configItem.sourcePath)}`)}`);
109110
- }
109111
- if (ruleItems.length > 0) {
109112
- discoveryParts.push(`${ruleItems.length} rule(s) ${import_picocolors30.default.dim(`<- ${rulesSourceDisplay}`)}`);
109113
- }
109114
- if (hookItems.length > 0) {
109115
- discoveryParts.push(`${hookItems.length} hook(s) ${import_picocolors30.default.dim(`<- ${hooksSourceDisplay}`)}`);
109116
- }
109126
+ const preflightRows = buildPreflightRows(sourceCounts, selectedProviders, {
109127
+ requestedGlobal,
109128
+ sourceDisplays: {
109129
+ agents: agentSourceDisplay,
109130
+ commands: commandSourceDisplay,
109131
+ config: configItem ? formatDisplayPath(configItem.sourcePath) : undefined,
109132
+ hooks: hooksSourceDisplay,
109133
+ rules: rulesSourceDisplay,
109134
+ skills: skillSourceDisplay
109135
+ }
109136
+ });
109117
109137
  console.log();
109118
109138
  console.log(renderSourceTargetHeader({
109119
109139
  sourceLines: buildSourceSummaryLines(sourceCounts, sourceOrigins),
@@ -109123,7 +109143,12 @@ async function migrateCommand(options2) {
109123
109143
  }).join(`
109124
109144
  `));
109125
109145
  f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
109126
- f2.info(`Found: ${discoveryParts.join(", ")}`);
109146
+ console.log();
109147
+ console.log(renderPanel({
109148
+ title: "Found",
109149
+ zones: [{ label: "ITEMS", lines: buildDiscoverySummaryLines(preflightRows) }]
109150
+ }).join(`
109151
+ `));
109127
109152
  console.log();
109128
109153
  f2.step(import_picocolors30.default.bold("Migrate Summary"));
109129
109154
  const providerNames = selectedProviders.map((prov) => import_picocolors30.default.cyan(providers[prov].displayName)).join(", ");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudekit-cli",
3
- "version": "4.0.0-dev.5",
3
+ "version": "4.0.0-dev.7",
4
4
  "description": "CLI tool for bootstrapping and updating ClaudeKit projects",
5
5
  "type": "module",
6
6
  "repository": {