claudekit-cli 3.41.4-dev.17 → 3.41.4-dev.19

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.
Files changed (2) hide show
  1. package/dist/index.js +518 -424
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10624,363 +10624,20 @@ var init_direct_copy = __esm(() => {
10624
10624
  };
10625
10625
  });
10626
10626
 
10627
- // src/commands/portable/converters/fm-strip.ts
10628
- function convertFmStrip(item, provider) {
10629
- const warnings = [];
10630
- const heading = item.frontmatter.name || item.name;
10631
- const isMergeProvider = ["goose", "gemini-cli", "amp"].includes(provider);
10632
- let content;
10633
- if (isMergeProvider) {
10634
- content = `## Agent: ${heading}
10635
-
10636
- ${item.body}
10637
- `;
10638
- } else {
10639
- content = `# ${heading}
10640
-
10641
- ${item.body}
10642
- `;
10643
- }
10644
- if (provider === "windsurf" && content.length > 12000) {
10645
- const originalLen = content.length;
10646
- const truncated = content.slice(0, 11950);
10647
- content = `${truncated}
10648
-
10649
- [truncated — original ${originalLen} chars exceeded 12K limit]
10650
- `;
10651
- warnings.push(`Content truncated from ${originalLen} to 12K chars for Windsurf`);
10652
- }
10653
- return {
10654
- content,
10655
- filename: isMergeProvider ? "AGENTS.md" : `${item.name}.md`,
10656
- warnings
10657
- };
10658
- }
10659
- function buildMergedAgentsMd(sections, providerName) {
10660
- const header = `# Agents
10661
-
10662
- > Ported from Claude Code agents via ClaudeKit CLI (ck agents)
10663
- > Target: ${providerName}
10664
-
10665
- `;
10666
- return header + sections.join(`
10667
- ---
10668
-
10669
- `);
10670
- }
10671
-
10672
- // src/commands/portable/converters/fm-to-fm.ts
10673
- function convertForCopilot(item) {
10674
- const warnings = [];
10675
- const fm = {};
10676
- fm.name = item.frontmatter.name || item.name;
10677
- if (item.description)
10678
- fm.description = item.description;
10679
- if (item.frontmatter.model)
10680
- fm.model = item.frontmatter.model;
10681
- if (item.frontmatter.tools) {
10682
- const sourceTools = item.frontmatter.tools.split(",").map((t) => t.trim());
10683
- const mappedTools = new Set;
10684
- for (const tool of sourceTools) {
10685
- const mapped = COPILOT_TOOL_MAP[tool];
10686
- if (mapped) {
10687
- mappedTools.add(mapped);
10688
- }
10689
- }
10690
- if (mappedTools.size > 0) {
10691
- fm.tools = Array.from(mappedTools);
10692
- }
10693
- }
10694
- const fmLines = ["---"];
10695
- for (const [key, value] of Object.entries(fm)) {
10696
- if (Array.isArray(value)) {
10697
- fmLines.push(`${key}:`);
10698
- for (const v2 of value) {
10699
- fmLines.push(` - ${v2}`);
10700
- }
10701
- } else {
10702
- fmLines.push(`${key}: ${JSON.stringify(value)}`);
10703
- }
10704
- }
10705
- fmLines.push("---");
10706
- const content = `${fmLines.join(`
10707
- `)}
10708
-
10709
- ${item.body}
10710
- `;
10711
- if (content.length > 30000) {
10712
- warnings.push(`Content exceeds Copilot 30K char limit (${content.length} chars)`);
10713
- }
10714
- return {
10715
- content,
10716
- filename: `${item.name}.agent.md`,
10717
- warnings
10718
- };
10719
- }
10720
- function convertForCursor(item) {
10721
- const fm = {};
10722
- if (item.description)
10723
- fm.description = item.description;
10724
- fm.alwaysApply = false;
10725
- const fmLines = ["---"];
10726
- for (const [key, value] of Object.entries(fm)) {
10727
- fmLines.push(`${key}: ${JSON.stringify(value)}`);
10728
- }
10729
- fmLines.push("---");
10730
- const content = `${fmLines.join(`
10731
- `)}
10732
-
10733
- ${item.body}
10734
- `;
10735
- return {
10736
- content,
10737
- filename: `${item.name}.mdc`,
10738
- warnings: []
10739
- };
10740
- }
10741
- function replaceClaudePathsForOpenCode(content) {
10742
- return content.replace(/\.claude\//g, ".opencode/");
10743
- }
10744
- function convertOpenCodeAgent(item) {
10745
- const warnings = [];
10746
- const agentName = item.frontmatter.name || item.name;
10747
- const mode = agentName === "brainstormer" ? "primary" : "subagent";
10748
- let toolsObj = null;
10749
- if (item.frontmatter.tools) {
10750
- const sourceTools = item.frontmatter.tools.split(",").map((t) => t.trim());
10751
- const mapped = new Set;
10752
- for (const tool of sourceTools) {
10753
- const key = OPENCODE_TOOL_MAP[tool];
10754
- if (key)
10755
- mapped.add(key);
10756
- }
10757
- if (mapped.size > 0) {
10758
- toolsObj = {};
10759
- for (const key of mapped) {
10760
- toolsObj[key] = true;
10761
- }
10762
- }
10763
- }
10764
- const fmLines = ["---"];
10765
- const desc = (item.description || `Agent: ${agentName}`).replace(/\n/g, " ").trim();
10766
- const truncatedDesc = desc.length > 200 ? `${desc.slice(0, 197)}...` : desc;
10767
- fmLines.push(`description: ${JSON.stringify(truncatedDesc)}`);
10768
- fmLines.push(`mode: ${mode}`);
10769
- if (toolsObj) {
10770
- fmLines.push("tools:");
10771
- for (const [key, val] of Object.entries(toolsObj)) {
10772
- fmLines.push(` ${key}: ${val}`);
10773
- }
10774
- }
10775
- fmLines.push("---");
10776
- const body = replaceClaudePathsForOpenCode(item.body);
10777
- const content = `${fmLines.join(`
10778
- `)}
10779
-
10780
- ${body}
10781
- `;
10782
- return {
10783
- content,
10784
- filename: `${item.name}.md`,
10785
- warnings
10786
- };
10787
- }
10788
- function convertOpenCodeCommand(item) {
10789
- const fmLines = ["---"];
10790
- const desc = (item.description || `Command: ${item.name}`).replace(/\n/g, " ").trim();
10791
- const truncatedDesc = desc.length > 200 ? `${desc.slice(0, 197)}...` : desc;
10792
- fmLines.push(`description: ${JSON.stringify(truncatedDesc)}`);
10793
- if (item.frontmatter.agent) {
10794
- fmLines.push(`agent: ${JSON.stringify(item.frontmatter.agent)}`);
10795
- }
10796
- fmLines.push("---");
10797
- const body = replaceClaudePathsForOpenCode(item.body);
10798
- const content = `${fmLines.join(`
10799
- `)}
10800
-
10801
- ${body}
10802
- `;
10803
- return {
10804
- content,
10805
- filename: `${item.name}.md`,
10806
- warnings: []
10807
- };
10808
- }
10809
- function convertFmToFm(item, provider) {
10810
- switch (provider) {
10811
- case "github-copilot":
10812
- return convertForCopilot(item);
10813
- case "cursor":
10814
- return convertForCursor(item);
10815
- case "opencode":
10816
- if (item.type === "command")
10817
- return convertOpenCodeCommand(item);
10818
- return convertOpenCodeAgent(item);
10819
- default:
10820
- return {
10821
- content: item.body,
10822
- filename: `${item.name}.md`,
10823
- warnings: [`No FM-to-FM converter for provider "${provider}", using body only`]
10824
- };
10825
- }
10826
- }
10827
- var COPILOT_TOOL_MAP, OPENCODE_TOOL_MAP;
10828
- var init_fm_to_fm = __esm(() => {
10829
- COPILOT_TOOL_MAP = {
10830
- Read: "read",
10831
- Glob: "search",
10832
- Grep: "search",
10833
- Edit: "edit",
10834
- Write: "edit",
10835
- MultiEdit: "edit",
10836
- Bash: "run_in_terminal",
10837
- WebFetch: "fetch",
10838
- WebSearch: "fetch"
10839
- };
10840
- OPENCODE_TOOL_MAP = {
10841
- Read: "read",
10842
- Glob: "glob",
10843
- Grep: "grep",
10844
- Edit: "edit",
10845
- Write: "write",
10846
- MultiEdit: "patch",
10847
- Bash: "bash",
10848
- WebFetch: "webfetch",
10849
- WebSearch: "websearch",
10850
- NotebookEdit: "edit"
10851
- };
10852
- });
10853
-
10854
- // src/commands/portable/converters/fm-to-json.ts
10855
- function mapToolsToGroups(toolsStr) {
10856
- const tools = toolsStr.split(",").map((t) => t.trim());
10857
- const groups = new Set;
10858
- for (const tool of tools) {
10859
- const group = CLINE_GROUP_MAP[tool];
10860
- if (group)
10861
- groups.add(group);
10862
- }
10863
- if (groups.size > 0)
10864
- groups.add("mcp");
10865
- return Array.from(groups);
10866
- }
10867
- function toSlug(name) {
10868
- return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
10869
- }
10870
- function convertFmToJson(item) {
10871
- const mode = {
10872
- slug: toSlug(item.name),
10873
- name: item.frontmatter.name || item.name,
10874
- roleDefinition: item.body,
10875
- groups: item.frontmatter.tools ? mapToolsToGroups(item.frontmatter.tools) : ["read", "edit", "command", "mcp"],
10876
- customInstructions: ""
10877
- };
10878
- return {
10879
- content: JSON.stringify(mode, null, 2),
10880
- filename: `${toSlug(item.name)}.json`,
10881
- warnings: []
10882
- };
10883
- }
10884
- function buildClineModesJson(modes) {
10885
- return JSON.stringify({ customModes: modes }, null, 2);
10886
- }
10887
- var CLINE_GROUP_MAP;
10888
- var init_fm_to_json = __esm(() => {
10889
- CLINE_GROUP_MAP = {
10890
- Read: "read",
10891
- Glob: "read",
10892
- Grep: "read",
10893
- Edit: "edit",
10894
- Write: "edit",
10895
- MultiEdit: "edit",
10896
- Bash: "command",
10897
- WebFetch: "browser",
10898
- WebSearch: "browser"
10899
- };
10900
- });
10901
-
10902
- // src/commands/portable/converters/fm-to-yaml.ts
10903
- function mapToolsToGroups2(toolsStr) {
10904
- const tools = toolsStr.split(",").map((t) => t.trim());
10905
- const groups = new Set;
10906
- for (const tool of tools) {
10907
- const group = TOOL_GROUP_MAP[tool];
10908
- if (group)
10909
- groups.add(group);
10910
- }
10911
- if (groups.size > 0)
10912
- groups.add("mcp");
10913
- return Array.from(groups);
10914
- }
10915
- function toSlug2(name) {
10916
- return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
10917
- }
10918
- function yamlEscape(str2) {
10919
- return str2.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
10920
- }
10921
- function convertFmToYaml(item) {
10922
- const slug = toSlug2(item.name);
10923
- const displayName = item.frontmatter.name || item.name;
10924
- const description = item.description || "";
10925
- const groups = item.frontmatter.tools ? mapToolsToGroups2(item.frontmatter.tools) : ["read", "edit", "command", "browser", "mcp"];
10926
- const lines = [];
10927
- lines.push(` - slug: "${slug}"`);
10928
- lines.push(` name: "${yamlEscape(displayName)}"`);
10929
- if (description) {
10930
- lines.push(` description: "${yamlEscape(description.slice(0, 200))}"`);
10931
- }
10932
- lines.push(" roleDefinition: |");
10933
- for (const line of item.body.split(`
10934
- `)) {
10935
- lines.push(` ${line}`);
10936
- }
10937
- lines.push(' customInstructions: ""');
10938
- lines.push(" groups:");
10939
- for (const group of groups) {
10940
- lines.push(` - ${group}`);
10941
- }
10942
- return {
10943
- content: lines.join(`
10944
- `),
10945
- filename: slug,
10946
- warnings: []
10947
- };
10948
- }
10949
- function buildYamlModesFile(convertedEntries) {
10950
- const lines = ["customModes:"];
10951
- for (const entry of convertedEntries) {
10952
- lines.push(entry);
10953
- }
10954
- return `${lines.join(`
10955
- `)}
10956
- `;
10957
- }
10958
- var TOOL_GROUP_MAP;
10959
- var init_fm_to_yaml = __esm(() => {
10960
- TOOL_GROUP_MAP = {
10961
- Read: "read",
10962
- Glob: "read",
10963
- Grep: "read",
10964
- Edit: "edit",
10965
- Write: "edit",
10966
- MultiEdit: "edit",
10967
- Bash: "command",
10968
- WebFetch: "browser",
10969
- WebSearch: "browser"
10970
- };
10971
- });
10972
-
10973
10627
  // src/commands/portable/provider-registry.ts
10974
10628
  var exports_provider_registry = {};
10975
10629
  __export(exports_provider_registry, {
10976
10630
  providers: () => providers,
10631
+ hasBinaryInPath: () => hasBinaryInPath,
10977
10632
  getProvidersSupporting: () => getProvidersSupporting,
10978
10633
  getProviderConfig: () => getProviderConfig,
10979
10634
  getPortableInstallPath: () => getPortableInstallPath,
10980
10635
  getAllProviderTypes: () => getAllProviderTypes,
10981
10636
  detectProviderPathCollisions: () => detectProviderPathCollisions,
10982
- detectInstalledProviders: () => detectInstalledProviders
10637
+ detectInstalledProviders: () => detectInstalledProviders,
10638
+ binaryCache: () => binaryCache
10983
10639
  });
10640
+ import { execFileSync } from "node:child_process";
10984
10641
  import { existsSync, readdirSync, statSync } from "node:fs";
10985
10642
  import { homedir, platform } from "node:os";
10986
10643
  import { join } from "node:path";
@@ -11004,8 +10661,21 @@ function hasInstallSignal(path) {
11004
10661
  function hasAnyInstallSignal(paths) {
11005
10662
  return paths.some((path) => hasInstallSignal(path));
11006
10663
  }
10664
+ function hasBinaryInPath(name) {
10665
+ const cached = binaryCache.get(name);
10666
+ if (cached !== undefined)
10667
+ return cached;
10668
+ try {
10669
+ execFileSync(isWin ? "where" : "which", [name], { stdio: "pipe", timeout: 3000 });
10670
+ binaryCache.set(name, true);
10671
+ return true;
10672
+ } catch {
10673
+ binaryCache.set(name, false);
10674
+ return false;
10675
+ }
10676
+ }
11007
10677
  function hasOpenCodeInstallSignal() {
11008
- return hasAnyInstallSignal([
10678
+ return hasBinaryInPath("opencode") || hasAnyInstallSignal([
11009
10679
  join(cwd, "opencode.json"),
11010
10680
  join(cwd, "opencode.jsonc"),
11011
10681
  join(cwd, ".opencode/agents"),
@@ -11077,11 +10747,13 @@ function detectProviderPathCollisions(selectedProviders, options2) {
11077
10747
  }
11078
10748
  return collisions;
11079
10749
  }
11080
- var home, cwd, OPENCODE_BINARY_NAME, providers;
10750
+ var home, cwd, isWin, OPENCODE_BINARY_NAME, binaryCache, providers;
11081
10751
  var init_provider_registry = __esm(() => {
11082
10752
  home = homedir();
11083
10753
  cwd = process.cwd();
11084
- OPENCODE_BINARY_NAME = platform() === "win32" ? "opencode.exe" : "opencode";
10754
+ isWin = platform() === "win32";
10755
+ OPENCODE_BINARY_NAME = isWin ? "opencode.exe" : "opencode";
10756
+ binaryCache = new Map;
11085
10757
  providers = {
11086
10758
  "claude-code": {
11087
10759
  name: "claude-code",
@@ -11133,7 +10805,7 @@ var init_provider_registry = __esm(() => {
11133
10805
  projectPath: ".claude/settings.json",
11134
10806
  globalPath: join(home, ".claude/settings.json")
11135
10807
  },
11136
- detect: async () => hasAnyInstallSignal([
10808
+ detect: async () => hasBinaryInPath("claude") || hasAnyInstallSignal([
11137
10809
  join(cwd, ".claude/agents"),
11138
10810
  join(cwd, ".claude/commands"),
11139
10811
  join(cwd, ".claude/skills"),
@@ -11284,7 +10956,7 @@ var init_provider_registry = __esm(() => {
11284
10956
  projectPath: ".codex/hooks.json",
11285
10957
  globalPath: join(home, ".codex/hooks.json")
11286
10958
  },
11287
- detect: async () => hasAnyInstallSignal([
10959
+ detect: async () => hasBinaryInPath("codex") || hasAnyInstallSignal([
11288
10960
  join(cwd, ".codex/config.toml"),
11289
10961
  join(cwd, ".codex/agents"),
11290
10962
  join(cwd, ".codex/prompts"),
@@ -11347,7 +11019,7 @@ var init_provider_registry = __esm(() => {
11347
11019
  projectPath: ".factory/settings.json",
11348
11020
  globalPath: join(home, ".factory/settings.json")
11349
11021
  },
11350
- detect: async () => hasAnyInstallSignal([
11022
+ detect: async () => hasBinaryInPath("droid") || hasAnyInstallSignal([
11351
11023
  join(cwd, ".factory/droids"),
11352
11024
  join(cwd, ".factory/commands"),
11353
11025
  join(cwd, ".factory/skills"),
@@ -11398,7 +11070,7 @@ var init_provider_registry = __esm(() => {
11398
11070
  },
11399
11071
  hooks: null,
11400
11072
  settingsJsonPath: null,
11401
- detect: async () => hasAnyInstallSignal([
11073
+ detect: async () => hasBinaryInPath("cursor") || hasAnyInstallSignal([
11402
11074
  join(cwd, ".cursor/rules"),
11403
11075
  join(home, ".cursor/rules"),
11404
11076
  join(home, ".cursor/skills")
@@ -11581,7 +11253,7 @@ var init_provider_registry = __esm(() => {
11581
11253
  },
11582
11254
  hooks: null,
11583
11255
  settingsJsonPath: null,
11584
- detect: async () => hasAnyInstallSignal([
11256
+ detect: async () => hasBinaryInPath("windsurf") || hasAnyInstallSignal([
11585
11257
  join(cwd, ".windsurf/rules"),
11586
11258
  join(cwd, ".windsurf/workflows"),
11587
11259
  join(home, ".codeium/windsurf/rules"),
@@ -11623,7 +11295,7 @@ var init_provider_registry = __esm(() => {
11623
11295
  },
11624
11296
  hooks: null,
11625
11297
  settingsJsonPath: null,
11626
- detect: async () => hasAnyInstallSignal([
11298
+ detect: async () => hasBinaryInPath("goose") || hasAnyInstallSignal([
11627
11299
  join(cwd, ".goosehints"),
11628
11300
  join(cwd, ".goose/skills"),
11629
11301
  join(home, ".config/goose/.goosehints"),
@@ -11669,9 +11341,18 @@ var init_provider_registry = __esm(() => {
11669
11341
  writeStrategy: "merge-single",
11670
11342
  fileExtension: ".md"
11671
11343
  },
11672
- hooks: null,
11673
- settingsJsonPath: null,
11674
- detect: async () => hasAnyInstallSignal([
11344
+ hooks: {
11345
+ projectPath: ".gemini/hooks",
11346
+ globalPath: join(home, ".gemini/hooks"),
11347
+ format: "direct-copy",
11348
+ writeStrategy: "per-file",
11349
+ fileExtension: ""
11350
+ },
11351
+ settingsJsonPath: {
11352
+ projectPath: ".gemini/settings.json",
11353
+ globalPath: join(home, ".gemini/settings.json")
11354
+ },
11355
+ detect: async () => hasBinaryInPath("gemini") || hasAnyInstallSignal([
11675
11356
  join(cwd, ".gemini/commands"),
11676
11357
  join(cwd, "GEMINI.md"),
11677
11358
  join(home, ".gemini/commands"),
@@ -11713,7 +11394,7 @@ var init_provider_registry = __esm(() => {
11713
11394
  },
11714
11395
  hooks: null,
11715
11396
  settingsJsonPath: null,
11716
- detect: async () => hasAnyInstallSignal([
11397
+ detect: async () => hasBinaryInPath("amp") || hasAnyInstallSignal([
11717
11398
  join(cwd, ".amp/rules"),
11718
11399
  join(cwd, "AGENT.md"),
11719
11400
  join(home, ".config/amp/rules"),
@@ -11756,11 +11437,12 @@ var init_provider_registry = __esm(() => {
11756
11437
  },
11757
11438
  hooks: null,
11758
11439
  settingsJsonPath: null,
11759
- detect: async () => hasAnyInstallSignal([
11440
+ detect: async () => hasBinaryInPath("agy") || hasBinaryInPath("antigravity") || hasAnyInstallSignal([
11760
11441
  join(cwd, ".agent/rules"),
11761
11442
  join(cwd, ".agent/skills"),
11762
11443
  join(cwd, ".agent/workflows"),
11763
11444
  join(cwd, "GEMINI.md"),
11445
+ join(home, ".gemini/antigravity"),
11764
11446
  join(home, ".gemini/antigravity/skills")
11765
11447
  ])
11766
11448
  },
@@ -12132,6 +11814,363 @@ var init_md_strip = __esm(() => {
12132
11814
  init_provider_registry();
12133
11815
  });
12134
11816
 
11817
+ // src/commands/portable/converters/fm-strip.ts
11818
+ function convertFmStrip(item, provider) {
11819
+ const warnings = [];
11820
+ const heading = item.frontmatter.name || item.name;
11821
+ const isMergeProvider = ["goose", "gemini-cli", "amp"].includes(provider);
11822
+ let body = item.body;
11823
+ if (PROVIDERS_WITH_BODY_REWRITING.includes(provider)) {
11824
+ const stripped = stripClaudeRefs(body, { provider });
11825
+ body = stripped.content;
11826
+ warnings.push(...stripped.warnings);
11827
+ }
11828
+ let content;
11829
+ if (isMergeProvider) {
11830
+ content = `## Agent: ${heading}
11831
+
11832
+ ${body}
11833
+ `;
11834
+ } else {
11835
+ content = `# ${heading}
11836
+
11837
+ ${body}
11838
+ `;
11839
+ }
11840
+ if (provider === "windsurf" && content.length > 12000) {
11841
+ const originalLen = content.length;
11842
+ const truncated = content.slice(0, 11950);
11843
+ content = `${truncated}
11844
+
11845
+ [truncated — original ${originalLen} chars exceeded 12K limit]
11846
+ `;
11847
+ warnings.push(`Content truncated from ${originalLen} to 12K chars for Windsurf`);
11848
+ }
11849
+ return {
11850
+ content,
11851
+ filename: isMergeProvider ? "AGENTS.md" : `${item.name}.md`,
11852
+ warnings
11853
+ };
11854
+ }
11855
+ function buildMergedAgentsMd(sections, providerName) {
11856
+ const header = `# Agents
11857
+
11858
+ > Ported from Claude Code agents via ClaudeKit CLI (ck agents)
11859
+ > Target: ${providerName}
11860
+
11861
+ `;
11862
+ return header + sections.join(`
11863
+ ---
11864
+
11865
+ `);
11866
+ }
11867
+ var PROVIDERS_WITH_BODY_REWRITING;
11868
+ var init_fm_strip = __esm(() => {
11869
+ init_md_strip();
11870
+ PROVIDERS_WITH_BODY_REWRITING = ["gemini-cli"];
11871
+ });
11872
+
11873
+ // src/commands/portable/converters/fm-to-fm.ts
11874
+ function convertForCopilot(item) {
11875
+ const warnings = [];
11876
+ const fm = {};
11877
+ fm.name = item.frontmatter.name || item.name;
11878
+ if (item.description)
11879
+ fm.description = item.description;
11880
+ if (item.frontmatter.model)
11881
+ fm.model = item.frontmatter.model;
11882
+ if (item.frontmatter.tools) {
11883
+ const sourceTools = item.frontmatter.tools.split(",").map((t) => t.trim());
11884
+ const mappedTools = new Set;
11885
+ for (const tool of sourceTools) {
11886
+ const mapped = COPILOT_TOOL_MAP[tool];
11887
+ if (mapped) {
11888
+ mappedTools.add(mapped);
11889
+ }
11890
+ }
11891
+ if (mappedTools.size > 0) {
11892
+ fm.tools = Array.from(mappedTools);
11893
+ }
11894
+ }
11895
+ const fmLines = ["---"];
11896
+ for (const [key, value] of Object.entries(fm)) {
11897
+ if (Array.isArray(value)) {
11898
+ fmLines.push(`${key}:`);
11899
+ for (const v2 of value) {
11900
+ fmLines.push(` - ${v2}`);
11901
+ }
11902
+ } else {
11903
+ fmLines.push(`${key}: ${JSON.stringify(value)}`);
11904
+ }
11905
+ }
11906
+ fmLines.push("---");
11907
+ const content = `${fmLines.join(`
11908
+ `)}
11909
+
11910
+ ${item.body}
11911
+ `;
11912
+ if (content.length > 30000) {
11913
+ warnings.push(`Content exceeds Copilot 30K char limit (${content.length} chars)`);
11914
+ }
11915
+ return {
11916
+ content,
11917
+ filename: `${item.name}.agent.md`,
11918
+ warnings
11919
+ };
11920
+ }
11921
+ function convertForCursor(item) {
11922
+ const fm = {};
11923
+ if (item.description)
11924
+ fm.description = item.description;
11925
+ fm.alwaysApply = false;
11926
+ const fmLines = ["---"];
11927
+ for (const [key, value] of Object.entries(fm)) {
11928
+ fmLines.push(`${key}: ${JSON.stringify(value)}`);
11929
+ }
11930
+ fmLines.push("---");
11931
+ const content = `${fmLines.join(`
11932
+ `)}
11933
+
11934
+ ${item.body}
11935
+ `;
11936
+ return {
11937
+ content,
11938
+ filename: `${item.name}.mdc`,
11939
+ warnings: []
11940
+ };
11941
+ }
11942
+ function replaceClaudePathsForOpenCode(content) {
11943
+ return content.replace(/\.claude\//g, ".opencode/");
11944
+ }
11945
+ function convertOpenCodeAgent(item) {
11946
+ const warnings = [];
11947
+ const agentName = item.frontmatter.name || item.name;
11948
+ const mode = agentName === "brainstormer" ? "primary" : "subagent";
11949
+ let toolsObj = null;
11950
+ if (item.frontmatter.tools) {
11951
+ const sourceTools = item.frontmatter.tools.split(",").map((t) => t.trim());
11952
+ const mapped = new Set;
11953
+ for (const tool of sourceTools) {
11954
+ const key = OPENCODE_TOOL_MAP[tool];
11955
+ if (key)
11956
+ mapped.add(key);
11957
+ }
11958
+ if (mapped.size > 0) {
11959
+ toolsObj = {};
11960
+ for (const key of mapped) {
11961
+ toolsObj[key] = true;
11962
+ }
11963
+ }
11964
+ }
11965
+ const fmLines = ["---"];
11966
+ const desc = (item.description || `Agent: ${agentName}`).replace(/\n/g, " ").trim();
11967
+ const truncatedDesc = desc.length > 200 ? `${desc.slice(0, 197)}...` : desc;
11968
+ fmLines.push(`description: ${JSON.stringify(truncatedDesc)}`);
11969
+ fmLines.push(`mode: ${mode}`);
11970
+ if (toolsObj) {
11971
+ fmLines.push("tools:");
11972
+ for (const [key, val] of Object.entries(toolsObj)) {
11973
+ fmLines.push(` ${key}: ${val}`);
11974
+ }
11975
+ }
11976
+ fmLines.push("---");
11977
+ const body = replaceClaudePathsForOpenCode(item.body);
11978
+ const content = `${fmLines.join(`
11979
+ `)}
11980
+
11981
+ ${body}
11982
+ `;
11983
+ return {
11984
+ content,
11985
+ filename: `${item.name}.md`,
11986
+ warnings
11987
+ };
11988
+ }
11989
+ function convertOpenCodeCommand(item) {
11990
+ const fmLines = ["---"];
11991
+ const desc = (item.description || `Command: ${item.name}`).replace(/\n/g, " ").trim();
11992
+ const truncatedDesc = desc.length > 200 ? `${desc.slice(0, 197)}...` : desc;
11993
+ fmLines.push(`description: ${JSON.stringify(truncatedDesc)}`);
11994
+ if (item.frontmatter.agent) {
11995
+ fmLines.push(`agent: ${JSON.stringify(item.frontmatter.agent)}`);
11996
+ }
11997
+ fmLines.push("---");
11998
+ const body = replaceClaudePathsForOpenCode(item.body);
11999
+ const content = `${fmLines.join(`
12000
+ `)}
12001
+
12002
+ ${body}
12003
+ `;
12004
+ return {
12005
+ content,
12006
+ filename: `${item.name}.md`,
12007
+ warnings: []
12008
+ };
12009
+ }
12010
+ function convertFmToFm(item, provider) {
12011
+ switch (provider) {
12012
+ case "github-copilot":
12013
+ return convertForCopilot(item);
12014
+ case "cursor":
12015
+ return convertForCursor(item);
12016
+ case "opencode":
12017
+ if (item.type === "command")
12018
+ return convertOpenCodeCommand(item);
12019
+ return convertOpenCodeAgent(item);
12020
+ default:
12021
+ return {
12022
+ content: item.body,
12023
+ filename: `${item.name}.md`,
12024
+ warnings: [`No FM-to-FM converter for provider "${provider}", using body only`]
12025
+ };
12026
+ }
12027
+ }
12028
+ var COPILOT_TOOL_MAP, OPENCODE_TOOL_MAP;
12029
+ var init_fm_to_fm = __esm(() => {
12030
+ COPILOT_TOOL_MAP = {
12031
+ Read: "read",
12032
+ Glob: "search",
12033
+ Grep: "search",
12034
+ Edit: "edit",
12035
+ Write: "edit",
12036
+ MultiEdit: "edit",
12037
+ Bash: "run_in_terminal",
12038
+ WebFetch: "fetch",
12039
+ WebSearch: "fetch"
12040
+ };
12041
+ OPENCODE_TOOL_MAP = {
12042
+ Read: "read",
12043
+ Glob: "glob",
12044
+ Grep: "grep",
12045
+ Edit: "edit",
12046
+ Write: "write",
12047
+ MultiEdit: "patch",
12048
+ Bash: "bash",
12049
+ WebFetch: "webfetch",
12050
+ WebSearch: "websearch",
12051
+ NotebookEdit: "edit"
12052
+ };
12053
+ });
12054
+
12055
+ // src/commands/portable/converters/fm-to-json.ts
12056
+ function mapToolsToGroups(toolsStr) {
12057
+ const tools = toolsStr.split(",").map((t) => t.trim());
12058
+ const groups = new Set;
12059
+ for (const tool of tools) {
12060
+ const group = CLINE_GROUP_MAP[tool];
12061
+ if (group)
12062
+ groups.add(group);
12063
+ }
12064
+ if (groups.size > 0)
12065
+ groups.add("mcp");
12066
+ return Array.from(groups);
12067
+ }
12068
+ function toSlug(name) {
12069
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
12070
+ }
12071
+ function convertFmToJson(item) {
12072
+ const mode = {
12073
+ slug: toSlug(item.name),
12074
+ name: item.frontmatter.name || item.name,
12075
+ roleDefinition: item.body,
12076
+ groups: item.frontmatter.tools ? mapToolsToGroups(item.frontmatter.tools) : ["read", "edit", "command", "mcp"],
12077
+ customInstructions: ""
12078
+ };
12079
+ return {
12080
+ content: JSON.stringify(mode, null, 2),
12081
+ filename: `${toSlug(item.name)}.json`,
12082
+ warnings: []
12083
+ };
12084
+ }
12085
+ function buildClineModesJson(modes) {
12086
+ return JSON.stringify({ customModes: modes }, null, 2);
12087
+ }
12088
+ var CLINE_GROUP_MAP;
12089
+ var init_fm_to_json = __esm(() => {
12090
+ CLINE_GROUP_MAP = {
12091
+ Read: "read",
12092
+ Glob: "read",
12093
+ Grep: "read",
12094
+ Edit: "edit",
12095
+ Write: "edit",
12096
+ MultiEdit: "edit",
12097
+ Bash: "command",
12098
+ WebFetch: "browser",
12099
+ WebSearch: "browser"
12100
+ };
12101
+ });
12102
+
12103
+ // src/commands/portable/converters/fm-to-yaml.ts
12104
+ function mapToolsToGroups2(toolsStr) {
12105
+ const tools = toolsStr.split(",").map((t) => t.trim());
12106
+ const groups = new Set;
12107
+ for (const tool of tools) {
12108
+ const group = TOOL_GROUP_MAP[tool];
12109
+ if (group)
12110
+ groups.add(group);
12111
+ }
12112
+ if (groups.size > 0)
12113
+ groups.add("mcp");
12114
+ return Array.from(groups);
12115
+ }
12116
+ function toSlug2(name) {
12117
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
12118
+ }
12119
+ function yamlEscape(str2) {
12120
+ return str2.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
12121
+ }
12122
+ function convertFmToYaml(item) {
12123
+ const slug = toSlug2(item.name);
12124
+ const displayName = item.frontmatter.name || item.name;
12125
+ const description = item.description || "";
12126
+ const groups = item.frontmatter.tools ? mapToolsToGroups2(item.frontmatter.tools) : ["read", "edit", "command", "browser", "mcp"];
12127
+ const lines = [];
12128
+ lines.push(` - slug: "${slug}"`);
12129
+ lines.push(` name: "${yamlEscape(displayName)}"`);
12130
+ if (description) {
12131
+ lines.push(` description: "${yamlEscape(description.slice(0, 200))}"`);
12132
+ }
12133
+ lines.push(" roleDefinition: |");
12134
+ for (const line of item.body.split(`
12135
+ `)) {
12136
+ lines.push(` ${line}`);
12137
+ }
12138
+ lines.push(' customInstructions: ""');
12139
+ lines.push(" groups:");
12140
+ for (const group of groups) {
12141
+ lines.push(` - ${group}`);
12142
+ }
12143
+ return {
12144
+ content: lines.join(`
12145
+ `),
12146
+ filename: slug,
12147
+ warnings: []
12148
+ };
12149
+ }
12150
+ function buildYamlModesFile(convertedEntries) {
12151
+ const lines = ["customModes:"];
12152
+ for (const entry of convertedEntries) {
12153
+ lines.push(entry);
12154
+ }
12155
+ return `${lines.join(`
12156
+ `)}
12157
+ `;
12158
+ }
12159
+ var TOOL_GROUP_MAP;
12160
+ var init_fm_to_yaml = __esm(() => {
12161
+ TOOL_GROUP_MAP = {
12162
+ Read: "read",
12163
+ Glob: "read",
12164
+ Grep: "read",
12165
+ Edit: "edit",
12166
+ Write: "edit",
12167
+ MultiEdit: "edit",
12168
+ Bash: "command",
12169
+ WebFetch: "browser",
12170
+ WebSearch: "browser"
12171
+ };
12172
+ });
12173
+
12135
12174
  // src/commands/portable/converters/md-to-kiro-steering.ts
12136
12175
  function detectLanguageGlob(itemName) {
12137
12176
  const normalized = itemName.toLowerCase();
@@ -12341,6 +12380,7 @@ function convertItem(item, format, provider) {
12341
12380
  }
12342
12381
  var init_converters = __esm(() => {
12343
12382
  init_direct_copy();
12383
+ init_fm_strip();
12344
12384
  init_fm_to_codex_toml();
12345
12385
  init_fm_to_fm();
12346
12386
  init_fm_to_json();
@@ -14425,6 +14465,7 @@ var init_portable_installer = __esm(() => {
14425
14465
  init_zod();
14426
14466
  init_checksum_utils();
14427
14467
  init_codex_toml_installer();
14468
+ init_fm_strip();
14428
14469
  init_fm_to_json();
14429
14470
  init_fm_to_yaml();
14430
14471
  init_converters();
@@ -43986,7 +44027,7 @@ var init_default_browser_id = __esm(() => {
43986
44027
  // node_modules/run-applescript/index.js
43987
44028
  import process13 from "node:process";
43988
44029
  import { promisify as promisify4 } from "node:util";
43989
- import { execFile as execFile4, execFileSync } from "node:child_process";
44030
+ import { execFile as execFile4, execFileSync as execFileSync2 } from "node:child_process";
43990
44031
  async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
43991
44032
  if (process13.platform !== "darwin") {
43992
44033
  throw new Error("macOS only");
@@ -51075,6 +51116,52 @@ var init_config_discovery = __esm(() => {
51075
51116
  SHELL_HOOK_EXTENSIONS = new Set([".sh", ".ps1", ".bat", ".cmd"]);
51076
51117
  });
51077
51118
 
51119
+ // src/commands/portable/converters/gemini-hook-event-map.ts
51120
+ function mapEventName(claudeEvent) {
51121
+ return GEMINI_EVENT_MAP[claudeEvent] ?? claudeEvent;
51122
+ }
51123
+ function rewriteMatcherToolNames(matcher) {
51124
+ if (!matcher)
51125
+ return matcher;
51126
+ const parts = matcher.split("|").map((p) => p.trim());
51127
+ const mapped = new Set;
51128
+ for (const part of parts) {
51129
+ const directMap = GEMINI_TOOL_NAME_MAP[part];
51130
+ if (directMap) {
51131
+ mapped.add(directMap);
51132
+ } else {
51133
+ mapped.add(part);
51134
+ }
51135
+ }
51136
+ return Array.from(mapped).join("|");
51137
+ }
51138
+ function requiresHookMapping(provider) {
51139
+ return provider === "gemini-cli";
51140
+ }
51141
+ var GEMINI_EVENT_MAP, GEMINI_TOOL_NAME_MAP;
51142
+ var init_gemini_hook_event_map = __esm(() => {
51143
+ GEMINI_EVENT_MAP = {
51144
+ PreToolUse: "BeforeTool",
51145
+ PostToolUse: "AfterTool",
51146
+ SubagentStart: "BeforeAgent",
51147
+ SubagentStop: "AfterAgent",
51148
+ Stop: "SessionEnd",
51149
+ Notification: "Notification",
51150
+ PreCompact: "PreCompress"
51151
+ };
51152
+ GEMINI_TOOL_NAME_MAP = {
51153
+ Read: "read_file",
51154
+ Glob: "glob",
51155
+ Grep: "grep_search",
51156
+ Edit: "replace",
51157
+ Write: "write_file",
51158
+ MultiEdit: "replace",
51159
+ Bash: "run_shell_command",
51160
+ WebFetch: "web_fetch",
51161
+ WebSearch: "google_web_search"
51162
+ };
51163
+ });
51164
+
51078
51165
  // src/commands/portable/hooks-settings-merger.ts
51079
51166
  import { existsSync as existsSync24, mkdirSync, renameSync, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
51080
51167
  import { readFile as readFile20 } from "node:fs/promises";
@@ -51134,6 +51221,24 @@ function filterToInstalledHooks(hooks, installedFiles) {
51134
51221
  }
51135
51222
  return filtered;
51136
51223
  }
51224
+ function mapHookEventsForProvider(hooks, targetProvider) {
51225
+ if (!requiresHookMapping(targetProvider))
51226
+ return hooks;
51227
+ const mapped = {};
51228
+ for (const [event, groups] of Object.entries(hooks)) {
51229
+ const mappedEvent = mapEventName(event);
51230
+ const mappedGroups = groups.map((group) => ({
51231
+ ...group,
51232
+ matcher: group.matcher ? rewriteMatcherToolNames(group.matcher) : group.matcher
51233
+ }));
51234
+ if (mapped[mappedEvent]) {
51235
+ mapped[mappedEvent].push(...mappedGroups);
51236
+ } else {
51237
+ mapped[mappedEvent] = mappedGroups;
51238
+ }
51239
+ }
51240
+ return mapped;
51241
+ }
51137
51242
  function extractFilenameFromCommand(command) {
51138
51243
  const normalized = command.replace(/\s*[|>&].*$/, "").trim();
51139
51244
  const quotedMatch = normalized.match(/["']([^"']+\.(?:js|cjs|mjs|ts))["']/);
@@ -51154,13 +51259,11 @@ async function mergeHooksIntoSettings(targetSettingsPath, newHooks) {
51154
51259
  let existingSettings = {};
51155
51260
  let backupPath = null;
51156
51261
  if (existsSync24(targetSettingsPath)) {
51157
- let raw;
51262
+ const raw = await readFile20(targetSettingsPath, "utf8");
51158
51263
  try {
51159
- raw = await readFile20(targetSettingsPath, "utf8");
51160
51264
  existingSettings = JSON.parse(raw);
51161
51265
  } catch {
51162
51266
  existingSettings = {};
51163
- raw = "";
51164
51267
  }
51165
51268
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
51166
51269
  backupPath = `${targetSettingsPath}.${timestamp}.bak`;
@@ -51311,8 +51414,9 @@ async function migrateHooksSettings(options2) {
51311
51414
  const targetHooksDir = isGlobal ? targetConfig.hooks?.globalPath ?? "" : targetConfig.hooks?.projectPath ?? "";
51312
51415
  const filtered = filterToInstalledHooks(sourceHooks, installedHookFiles);
51313
51416
  const rewritten = rewriteHookPaths(filtered, sourceHooksDir, targetHooksDir);
51417
+ const eventMapped = mapHookEventsForProvider(rewritten, targetProvider);
51314
51418
  let hooksRegistered = 0;
51315
- for (const groups of Object.values(rewritten)) {
51419
+ for (const groups of Object.values(eventMapped)) {
51316
51420
  for (const group of groups) {
51317
51421
  hooksRegistered += group.hooks.length;
51318
51422
  }
@@ -51329,7 +51433,7 @@ async function migrateHooksSettings(options2) {
51329
51433
  };
51330
51434
  }
51331
51435
  try {
51332
- const { backupPath } = await mergeHooksIntoSettings(resolvedTargetPath, rewritten);
51436
+ const { backupPath } = await mergeHooksIntoSettings(resolvedTargetPath, eventMapped);
51333
51437
  return {
51334
51438
  status: "registered",
51335
51439
  success: true,
@@ -51351,6 +51455,7 @@ async function migrateHooksSettings(options2) {
51351
51455
  }
51352
51456
  }
51353
51457
  var init_hooks_settings_merger = __esm(() => {
51458
+ init_gemini_hook_event_map();
51354
51459
  init_provider_registry();
51355
51460
  });
51356
51461
 
@@ -60447,7 +60552,7 @@ var package_default;
60447
60552
  var init_package = __esm(() => {
60448
60553
  package_default = {
60449
60554
  name: "claudekit-cli",
60450
- version: "3.41.4-dev.17",
60555
+ version: "3.41.4-dev.19",
60451
60556
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
60452
60557
  type: "module",
60453
60558
  repository: {
@@ -73006,9 +73111,9 @@ var init_git_scanner = __esm(() => {
73006
73111
  });
73007
73112
 
73008
73113
  // src/commands/content/phases/platform-adapters/facebook-adapter.ts
73009
- import { execFileSync as execFileSync2 } from "node:child_process";
73114
+ import { execFileSync as execFileSync3 } from "node:child_process";
73010
73115
  function runFbcli(args, timeoutMs = 30000) {
73011
- return execFileSync2("fbcli", [...args, "--json"], {
73116
+ return execFileSync3("fbcli", [...args, "--json"], {
73012
73117
  stdio: "pipe",
73013
73118
  timeout: timeoutMs
73014
73119
  }).toString();
@@ -73048,7 +73153,7 @@ class FacebookAdapter {
73048
73153
  if (options2?.dryRun)
73049
73154
  return dryRunResult();
73050
73155
  try {
73051
- const raw2 = execFileSync2("fbcli", ["post", "--json"], {
73156
+ const raw2 = execFileSync3("fbcli", ["post", "--json"], {
73052
73157
  input: text,
73053
73158
  stdio: ["pipe", "pipe", "pipe"],
73054
73159
  timeout: 30000
@@ -73073,7 +73178,7 @@ class FacebookAdapter {
73073
73178
  if (options2?.dryRun)
73074
73179
  return dryRunResult();
73075
73180
  try {
73076
- const raw2 = execFileSync2("fbcli", ["post", "-i", mediaPath, "--json"], {
73181
+ const raw2 = execFileSync3("fbcli", ["post", "-i", mediaPath, "--json"], {
73077
73182
  input: text,
73078
73183
  stdio: ["pipe", "pipe", "pipe"],
73079
73184
  timeout: 60000
@@ -85369,7 +85474,7 @@ function isUnix(patch) {
85369
85474
  }
85370
85475
  return !patch.some((index) => index.hunks.some((hunk) => hunk.lines.some((line) => !line.startsWith("\\") && line.endsWith("\r"))));
85371
85476
  }
85372
- function isWin(patch) {
85477
+ function isWin2(patch) {
85373
85478
  if (!Array.isArray(patch)) {
85374
85479
  patch = [patch];
85375
85480
  }
@@ -85532,7 +85637,7 @@ function applyStructuredPatch(source, patch, options2 = {}) {
85532
85637
  if (options2.autoConvertLineEndings || options2.autoConvertLineEndings == null) {
85533
85638
  if (hasOnlyWinLineEndings(source) && isUnix(patch)) {
85534
85639
  patch = unixToWin(patch);
85535
- } else if (hasOnlyUnixLineEndings(source) && isWin(patch)) {
85640
+ } else if (hasOnlyUnixLineEndings(source) && isWin2(patch)) {
85536
85641
  patch = winToUnix(patch);
85537
85642
  }
85538
85643
  }
@@ -103453,6 +103558,14 @@ async function migrateCommand(options2) {
103453
103558
  f2.info(`Found: ${parts.join(", ")}`);
103454
103559
  const detectedProviders = await detectInstalledProviders();
103455
103560
  let selectedProviders;
103561
+ const allSupportedProviders = Array.from(new Set([
103562
+ ...getProvidersSupporting("agents"),
103563
+ ...getProvidersSupporting("commands"),
103564
+ ...getProvidersSupporting("skills"),
103565
+ ...getProvidersSupporting("config"),
103566
+ ...getProvidersSupporting("rules"),
103567
+ ...getProvidersSupporting("hooks")
103568
+ ]));
103456
103569
  if (options2.agent && options2.agent.length > 0) {
103457
103570
  const validProviders = Object.keys(providers);
103458
103571
  const invalid = options2.agent.filter((a3) => !validProviders.includes(a3));
@@ -103464,62 +103577,43 @@ async function migrateCommand(options2) {
103464
103577
  }
103465
103578
  selectedProviders = options2.agent;
103466
103579
  } else if (options2.all) {
103467
- const allProviders = new Set([
103468
- ...getProvidersSupporting("agents"),
103469
- ...getProvidersSupporting("commands"),
103470
- ...getProvidersSupporting("skills"),
103471
- ...getProvidersSupporting("config"),
103472
- ...getProvidersSupporting("rules"),
103473
- ...getProvidersSupporting("hooks")
103474
- ]);
103475
- selectedProviders = Array.from(allProviders);
103580
+ selectedProviders = allSupportedProviders;
103476
103581
  f2.info(`Migrating to all ${selectedProviders.length} providers`);
103477
- } else if (detectedProviders.length === 0) {
103478
- if (options2.yes) {
103479
- const allProviders = new Set([
103480
- ...getProvidersSupporting("agents"),
103481
- ...getProvidersSupporting("commands"),
103482
- ...getProvidersSupporting("skills"),
103483
- ...getProvidersSupporting("config"),
103484
- ...getProvidersSupporting("rules"),
103485
- ...getProvidersSupporting("hooks")
103486
- ]);
103487
- selectedProviders = Array.from(allProviders);
103582
+ } else if (options2.yes) {
103583
+ if (detectedProviders.length > 0) {
103584
+ selectedProviders = detectedProviders;
103585
+ f2.info(`Migrating to: ${detectedProviders.map((a3) => import_picocolors28.default.cyan(providers[a3].displayName)).join(", ")}`);
103586
+ } else {
103587
+ selectedProviders = allSupportedProviders;
103488
103588
  f2.info("No providers detected, migrating to all");
103589
+ }
103590
+ } else {
103591
+ const detectedSet = new Set(detectedProviders);
103592
+ const notDetected = allSupportedProviders.filter((pv) => !detectedSet.has(pv));
103593
+ const toOption = (key) => ({
103594
+ value: key,
103595
+ label: providers[key].displayName
103596
+ });
103597
+ if (detectedProviders.length > 0) {
103598
+ f2.info(`Detected ${import_picocolors28.default.cyan(String(detectedProviders.length))} installed provider(s)`);
103489
103599
  } else {
103490
103600
  f2.warn("No providers detected on your system.");
103491
- const allProviders = new Set([
103492
- ...getProvidersSupporting("agents"),
103493
- ...getProvidersSupporting("commands"),
103494
- ...getProvidersSupporting("skills"),
103495
- ...getProvidersSupporting("config"),
103496
- ...getProvidersSupporting("rules"),
103497
- ...getProvidersSupporting("hooks")
103498
- ]);
103499
- const selected = await ae({
103500
- message: "Select providers to migrate to",
103501
- options: Array.from(allProviders).map((key) => ({
103502
- value: key,
103503
- label: providers[key].displayName
103504
- })),
103505
- required: true
103506
- });
103507
- if (lD(selected)) {
103508
- ue("Migrate cancelled");
103509
- return;
103510
- }
103511
- selectedProviders = selected;
103512
103601
  }
103513
- } else if (detectedProviders.length === 1 || options2.yes) {
103514
- selectedProviders = detectedProviders;
103515
- f2.info(`Migrating to: ${detectedProviders.map((a3) => import_picocolors28.default.cyan(providers[a3].displayName)).join(", ")}`);
103516
- } else {
103517
- const selected = await ae({
103602
+ const groupOptions = {};
103603
+ if (detectedProviders.length > 0) {
103604
+ groupOptions[`Detected ${import_picocolors28.default.dim("(installed)")}`] = detectedProviders.map(toOption);
103605
+ }
103606
+ if (notDetected.length > 0) {
103607
+ groupOptions[`Not detected ${import_picocolors28.default.dim("(select manually if installed)")}`] = notDetected.map(toOption);
103608
+ }
103609
+ if (Object.keys(groupOptions).length === 0) {
103610
+ ue("No providers available");
103611
+ return;
103612
+ }
103613
+ const selected = await ce({
103518
103614
  message: "Select providers to migrate to",
103519
- options: detectedProviders.map((a3) => ({
103520
- value: a3,
103521
- label: providers[a3].displayName
103522
- })),
103615
+ options: groupOptions,
103616
+ initialValues: detectedProviders,
103523
103617
  required: true
103524
103618
  });
103525
103619
  if (lD(selected)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudekit-cli",
3
- "version": "3.41.4-dev.17",
3
+ "version": "3.41.4-dev.19",
4
4
  "description": "CLI tool for bootstrapping and updating ClaudeKit projects",
5
5
  "type": "module",
6
6
  "repository": {