set-prompt 0.5.4 → 0.6.0

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
@@ -2,17 +2,17 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
- import chalk15 from "chalk";
5
+ import chalk21 from "chalk";
6
6
  import figlet from "figlet";
7
- import fs11 from "fs";
8
- import path10 from "path";
7
+ import fs12 from "fs";
8
+ import path11 from "path";
9
9
  import { fileURLToPath } from "url";
10
10
 
11
11
  // src/commands/install-command.ts
12
- import fs3 from "fs";
12
+ import fs4 from "fs";
13
13
  import path3 from "path";
14
- import { spawnSync } from "child_process";
15
- import chalk4 from "chalk";
14
+ import { spawnSync as spawnSync3 } from "child_process";
15
+ import chalk5 from "chalk";
16
16
  import { confirm as confirm2 } from "@inquirer/prompts";
17
17
 
18
18
  // src/_defs/index.ts
@@ -239,6 +239,8 @@ var ConfigManager = class {
239
239
  var configManager = new ConfigManager();
240
240
 
241
241
  // src/_libs/index.ts
242
+ import { spawnSync } from "child_process";
243
+ import fs2 from "fs";
242
244
  import chalk2 from "chalk";
243
245
  var isGitUrl = (source) => source.startsWith("http://") || source.startsWith("https://") || source.startsWith("git@") || source.startsWith("ssh://") || source.endsWith(".git") && (source.startsWith("http") || source.startsWith("git@") || source.startsWith("ssh://"));
244
246
  var resolveRepoPath = () => {
@@ -249,11 +251,71 @@ var resolveRepoPath = () => {
249
251
  }
250
252
  return configManager.repo_path;
251
253
  };
254
+ var isOnPath = (bin) => {
255
+ const probeCmd = process.platform === "win32" ? "where" : "which";
256
+ const probe = spawnSync(probeCmd, [bin], { stdio: "ignore" });
257
+ return probe.status === 0;
258
+ };
259
+ var firstExistingPath = (candidates) => {
260
+ for (const candidate of candidates) {
261
+ if (candidate != null && candidate !== "" && fs2.existsSync(candidate)) return candidate;
262
+ }
263
+ return null;
264
+ };
265
+
266
+ // src/_libs/repo.ts
267
+ import { spawnSync as spawnSync2 } from "child_process";
268
+ import chalk3 from "chalk";
269
+ var parsePorcelainLine = (line) => {
270
+ if (line.length < 4) return null;
271
+ const status = line.slice(0, 2);
272
+ let name = line.slice(3);
273
+ const arrowIdx = name.indexOf(" -> ");
274
+ if (arrowIdx >= 0) name = name.slice(arrowIdx + 4);
275
+ if (name.startsWith('"') && name.endsWith('"')) name = name.slice(1, -1);
276
+ if (status.includes("?")) return { kind: "?", name };
277
+ if (status.includes("D")) return { kind: "D", name };
278
+ if (status.includes("R")) return { kind: "R", name };
279
+ if (status.includes("A")) return { kind: "A", name };
280
+ if (status.includes("M")) return { kind: "M", name };
281
+ return null;
282
+ };
283
+ var pickVerb = (files) => {
284
+ const allAdded = files.every((f) => f.kind === "A" || f.kind === "?");
285
+ const allDeleted = files.every((f) => f.kind === "D");
286
+ if (allAdded) return "add";
287
+ if (allDeleted) return "remove";
288
+ return "update";
289
+ };
290
+ var generateCommitMessage = (repoPath) => {
291
+ const result = spawnSync2("git", ["status", "--porcelain", "--untracked-files=all"], {
292
+ cwd: repoPath,
293
+ encoding: "utf8"
294
+ });
295
+ if (result.status !== 0) return null;
296
+ const files = result.stdout.split("\n").map(parsePorcelainLine).filter((f) => f !== null);
297
+ if (files.length === 0) return null;
298
+ const verb = pickVerb(files);
299
+ const noun = files.length === 1 ? "file" : "files";
300
+ const subject = `${verb} ${files.length} ${noun}`;
301
+ const body = files.map((f) => `- ${f.name}`).join("\n");
302
+ return `${subject}
303
+
304
+ ${body}`;
305
+ };
306
+ var printSaveHint = (repoPath) => {
307
+ const generated = generateCommitMessage(repoPath);
308
+ if (generated == null) return;
309
+ const subject = generated.split("\n")[0];
310
+ console.log(chalk3.yellow("\nUncommitted changes detected."));
311
+ console.log(chalk3.dim(` Pending: ${subject}`));
312
+ console.log(chalk3.cyan(" Tip: run `sppt repo save` to commit and push."));
313
+ };
252
314
 
253
315
  // src/commands/scaffold-command.ts
254
- import fs2 from "fs";
316
+ import fs3 from "fs";
255
317
  import path2 from "path";
256
- import chalk3 from "chalk";
318
+ import chalk4 from "chalk";
257
319
  import { confirm } from "@inquirer/prompts";
258
320
 
259
321
  // src/_libs/templates.ts
@@ -299,8 +361,23 @@ set-prompt scaffold .
299
361
  set-prompt install https://github.com/you/my-prompts
300
362
  set-prompt link
301
363
 
302
- # Pull latest changes
303
- set-prompt update
364
+ # Inspect current state (branch, ahead/behind, changed files)
365
+ set-prompt repo status
366
+
367
+ # Pull latest changes from remote
368
+ set-prompt repo pull
369
+
370
+ # Commit + push local edits in one step (auto-generates message if -m omitted)
371
+ set-prompt repo save -m "update skills"
372
+ set-prompt repo save
373
+
374
+ # Or commit and push separately
375
+ set-prompt repo commit -m "update skills"
376
+ set-prompt repo push
377
+
378
+ # Jump into the repo or open it in an editor
379
+ cd "$(set-prompt repo path)"
380
+ set-prompt repo open --code
304
381
  \`\`\`
305
382
 
306
383
  ## Frontmatter Reference
@@ -650,43 +727,86 @@ echo '{"permission":"deny","user_message":"Blocked by policy","agent_message":"N
650
727
  `;
651
728
 
652
729
  // src/commands/scaffold-command.ts
730
+ var validateClaudePluginManifest = (data) => {
731
+ const issues = [];
732
+ if (typeof data !== "object" || data === null) return ["root must be a JSON object"];
733
+ const obj = data;
734
+ if (typeof obj.name !== "string" || obj.name.length === 0) {
735
+ issues.push('"name" is required and must be a non-empty string');
736
+ }
737
+ return issues;
738
+ };
739
+ var validateCodexPluginManifest = (data) => {
740
+ const issues = [];
741
+ if (typeof data !== "object" || data === null) return ["root must be a JSON object"];
742
+ const obj = data;
743
+ if (typeof obj.name !== "string" || obj.name.length === 0) {
744
+ issues.push('"name" is required and must be a non-empty string');
745
+ }
746
+ if (typeof obj.skills !== "string" || obj.skills.length === 0) {
747
+ issues.push('"skills" is required and must be a string path (e.g. "./skills/")');
748
+ }
749
+ if (typeof obj.mcpServers !== "string" || obj.mcpServers.length === 0) {
750
+ issues.push('"mcpServers" is required and must be a string path (e.g. "./.mcp.json")');
751
+ }
752
+ if (typeof obj.apps !== "string" || obj.apps.length === 0) {
753
+ issues.push('"apps" is required and must be a string path (e.g. "./.app.json")');
754
+ }
755
+ return issues;
756
+ };
757
+ var ensureManifest = (jsonPath, metaDir, validate, defaultData, label) => {
758
+ if (fs3.existsSync(jsonPath)) {
759
+ try {
760
+ const parsed = JSON.parse(fs3.readFileSync(jsonPath, "utf-8"));
761
+ const issues = validate(parsed);
762
+ if (issues.length === 0) return "valid";
763
+ console.warn(chalk4.yellow(` \u26A0 ${label} has issues \u2014 keeping existing file:`));
764
+ for (const issue of issues) console.warn(chalk4.dim(` ${issue}`));
765
+ return "invalid";
766
+ } catch (ex) {
767
+ console.warn(chalk4.yellow(` \u26A0 ${label} failed to parse: ${ex.message} \u2014 keeping existing file`));
768
+ return "invalid";
769
+ }
770
+ }
771
+ fs3.mkdirSync(metaDir, { recursive: true });
772
+ fs3.writeFileSync(jsonPath, JSON.stringify(defaultData, null, 4), { encoding: "utf-8" });
773
+ return "created";
774
+ };
653
775
  var ensureClaudePluginManifest = (repoPath) => {
654
776
  const metaDir = path2.join(repoPath, ".claude-plugin");
655
777
  const jsonPath = path2.join(metaDir, "plugin.json");
656
- fs2.mkdirSync(metaDir, { recursive: true });
657
- fs2.writeFileSync(jsonPath, JSON.stringify({
778
+ return ensureManifest(jsonPath, metaDir, validateClaudePluginManifest, {
658
779
  name: PLUGIN_NAME,
659
780
  version: "1.0.0",
660
781
  description: "Managed by set-prompt"
661
- }, null, 4), { encoding: "utf-8" });
782
+ }, ".claude-plugin/plugin.json");
662
783
  };
663
784
  var ensureCodexPluginManifest = (repoPath) => {
664
785
  const metaDir = path2.join(repoPath, ".codex-plugin");
665
786
  const jsonPath = path2.join(metaDir, "plugin.json");
666
- fs2.mkdirSync(metaDir, { recursive: true });
667
- fs2.writeFileSync(jsonPath, JSON.stringify({
787
+ return ensureManifest(jsonPath, metaDir, validateCodexPluginManifest, {
668
788
  name: PLUGIN_NAME,
669
789
  version: "1.0.0",
670
790
  description: "Managed by set-prompt",
671
791
  skills: "./skills/",
672
792
  mcpServers: "./.mcp.json",
673
793
  apps: "./.app.json"
674
- }, null, 4), { encoding: "utf-8" });
794
+ }, ".codex-plugin/plugin.json");
675
795
  };
676
796
  var ensureMcpJson = (repoPath) => {
677
797
  const mcpJsonPath = path2.join(repoPath, ".mcp.json");
678
- if (fs2.existsSync(mcpJsonPath)) {
798
+ if (fs3.existsSync(mcpJsonPath)) {
679
799
  return false;
680
800
  }
681
- fs2.writeFileSync(mcpJsonPath, JSON.stringify({ mcpServers: {} }, null, 4), { encoding: "utf-8" });
801
+ fs3.writeFileSync(mcpJsonPath, JSON.stringify({ mcpServers: {} }, null, 4), { encoding: "utf-8" });
682
802
  return true;
683
803
  };
684
804
  var ensureAppJson = (repoPath) => {
685
805
  const appJsonPath = path2.join(repoPath, ".app.json");
686
- if (fs2.existsSync(appJsonPath)) {
806
+ if (fs3.existsSync(appJsonPath)) {
687
807
  return false;
688
808
  }
689
- fs2.writeFileSync(appJsonPath, JSON.stringify({ apps: {} }, null, 4), { encoding: "utf-8" });
809
+ fs3.writeFileSync(appJsonPath, JSON.stringify({ apps: {} }, null, 4), { encoding: "utf-8" });
690
810
  return true;
691
811
  };
692
812
  var scaffoldCommand = async (localPath) => {
@@ -698,15 +818,15 @@ var scaffoldCommand = async (localPath) => {
698
818
  if (configManager.repo_path != null) {
699
819
  targetPath = configManager.repo_path;
700
820
  } else {
701
- console.error(chalk3.red("No path provided and no repo registered. Please provide a path."));
821
+ console.error(chalk4.red("No path provided and no repo registered. Please provide a path."));
702
822
  process.exit(1);
703
823
  }
704
824
  }
705
- if (fs2.existsSync(targetPath) === false || fs2.statSync(targetPath).isDirectory() === false) {
706
- console.error(chalk3.red(`Invalid directory path: '${targetPath}'`));
825
+ if (fs3.existsSync(targetPath) === false || fs3.statSync(targetPath).isDirectory() === false) {
826
+ console.error(chalk4.red(`Invalid directory path: '${targetPath}'`));
707
827
  process.exit(1);
708
828
  }
709
- console.log(chalk3.dim(`Scaffolding: ${targetPath}
829
+ console.log(chalk4.dim(`Scaffolding: ${targetPath}
710
830
  `));
711
831
  const writeGuide = await confirm({
712
832
  message: "Generate SET_PROMPT_GUIDE.md? (reference doc for writing prompts)",
@@ -714,32 +834,36 @@ var scaffoldCommand = async (localPath) => {
714
834
  });
715
835
  if (writeGuide) {
716
836
  const guideMdPath = path2.join(targetPath, "SET_PROMPT_GUIDE.md");
717
- fs2.writeFileSync(guideMdPath, SET_PROMPT_GUIDE, { encoding: "utf-8", flag: "w" });
718
- console.log(`${TAB}${chalk3.green("\u2713")} SET_PROMPT_GUIDE.md`);
837
+ fs3.writeFileSync(guideMdPath, SET_PROMPT_GUIDE, { encoding: "utf-8", flag: "w" });
838
+ console.log(`${TAB}${chalk4.green("\u2713")} SET_PROMPT_GUIDE.md`);
719
839
  }
720
840
  for (const dirName of PROMPT_DIR_NAMES) {
721
841
  const dirPath = path2.join(targetPath, dirName);
722
- if (fs2.existsSync(dirPath)) {
723
- console.log(`${TAB}${chalk3.dim("\u2713")} ${dirName}/`);
842
+ if (fs3.existsSync(dirPath)) {
843
+ console.log(`${TAB}${chalk4.dim("\u2713")} ${dirName}/`);
724
844
  } else {
725
- fs2.mkdirSync(dirPath, { recursive: true });
726
- console.log(`${TAB}${chalk3.green("+")} ${dirName}/`);
845
+ fs3.mkdirSync(dirPath, { recursive: true });
846
+ console.log(`${TAB}${chalk4.green("+")} ${dirName}/`);
727
847
  }
728
848
  const gitkeepPath = path2.join(dirPath, ".gitkeep");
729
- if (!fs2.existsSync(gitkeepPath)) {
730
- fs2.writeFileSync(gitkeepPath, "", { encoding: "utf-8" });
849
+ if (!fs3.existsSync(gitkeepPath)) {
850
+ fs3.writeFileSync(gitkeepPath, "", { encoding: "utf-8" });
731
851
  }
732
852
  }
733
- ensureClaudePluginManifest(targetPath);
734
- console.log(`${TAB}${chalk3.green("\u2713")} .claude-plugin/plugin.json`);
735
- ensureCodexPluginManifest(targetPath);
736
- console.log(`${TAB}${chalk3.green("\u2713")} .codex-plugin/plugin.json`);
737
- console.log(`${TAB}${ensureMcpJson(targetPath) ? chalk3.green("+") : chalk3.dim("\u2713")} .mcp.json`);
738
- console.log(`${TAB}${ensureAppJson(targetPath) ? chalk3.green("+") : chalk3.dim("\u2713")} .app.json`);
739
- console.log(chalk3.green("\nScaffold complete."));
853
+ const symFor = (r) => r === "created" ? chalk4.green("+") : r === "valid" ? chalk4.dim("\u2713") : chalk4.yellow("\u26A0");
854
+ const claudeResult = ensureClaudePluginManifest(targetPath);
855
+ console.log(`${TAB}${symFor(claudeResult)} .claude-plugin/plugin.json`);
856
+ const codexResult = ensureCodexPluginManifest(targetPath);
857
+ console.log(`${TAB}${symFor(codexResult)} .codex-plugin/plugin.json`);
858
+ console.log(`${TAB}${ensureMcpJson(targetPath) ? chalk4.green("+") : chalk4.dim("\u2713")} .mcp.json`);
859
+ console.log(`${TAB}${ensureAppJson(targetPath) ? chalk4.green("+") : chalk4.dim("\u2713")} .app.json`);
860
+ console.log(chalk4.green("\nScaffold complete."));
861
+ if (configManager.repo_path != null && path2.resolve(targetPath) === path2.resolve(configManager.repo_path)) {
862
+ printSaveHint(targetPath);
863
+ }
740
864
  return true;
741
865
  } catch (ex) {
742
- console.error(chalk3.red(`Failed to scaffold repo structure: ${ex.message}`), ex);
866
+ console.error(chalk4.red(`Failed to scaffold repo structure: ${ex.message}`), ex);
743
867
  throw ex;
744
868
  }
745
869
  };
@@ -748,86 +872,87 @@ var scaffoldCommand = async (localPath) => {
748
872
  var cloneRepo = async (remoteUrl) => {
749
873
  const localPath = path3.join(HOME_DIR, "repo");
750
874
  let backupPath = null;
751
- if (fs3.existsSync(localPath) == true) {
875
+ if (fs4.existsSync(localPath) == true) {
752
876
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
753
877
  backupPath = path3.join(HOME_DIR, `repo.bak.${timestamp}`);
754
878
  try {
755
- fs3.renameSync(localPath, backupPath);
756
- console.log(chalk4.yellow(" backed up") + chalk4.dim(` existing repo \u2192 ${backupPath}`));
879
+ fs4.renameSync(localPath, backupPath);
880
+ console.log(chalk5.yellow(" backed up") + chalk5.dim(` existing repo \u2192 ${backupPath}`));
757
881
  } catch (ex) {
758
882
  if (ex.code === "EPERM") {
759
- console.error(chalk4.red("\u274C Cannot rename existing repo \u2014 it may be open in another process."));
760
- console.log(chalk4.dim(` Close any editors or terminals using: ${localPath}`));
883
+ console.error(chalk5.red("\u274C Cannot rename existing repo \u2014 it may be open in another process."));
884
+ console.log(chalk5.dim(` Close any editors or terminals using: ${localPath}`));
761
885
  } else {
762
- console.error(chalk4.red(`\u274C Failed to backup existing repo: ${ex.message}`));
886
+ console.error(chalk5.red(`\u274C Failed to backup existing repo: ${ex.message}`));
763
887
  }
764
888
  return false;
765
889
  }
766
890
  }
767
- fs3.mkdirSync(path3.dirname(localPath), { recursive: true });
891
+ fs4.mkdirSync(path3.dirname(localPath), { recursive: true });
768
892
  console.log(`Cloning ${remoteUrl}...`);
769
- const result = spawnSync("git", ["clone", remoteUrl, localPath], { stdio: "inherit" });
893
+ const result = spawnSync3("git", ["clone", remoteUrl, localPath], { stdio: "inherit" });
770
894
  if (result.status !== 0) {
771
895
  console.log("\u274C Failed to clone. Check the URL and your git credentials.");
772
896
  process.exit(1);
773
897
  }
774
898
  console.log("\u2705 Cloned successfully.");
775
899
  if (backupPath != null) {
776
- fs3.rmSync(backupPath, { recursive: true, force: true });
777
- console.log(chalk4.red(" removed") + chalk4.dim(` backup \u2192 ${backupPath}`));
900
+ fs4.rmSync(backupPath, { recursive: true, force: true });
901
+ console.log(chalk5.red(" removed") + chalk5.dim(` backup \u2192 ${backupPath}`));
778
902
  }
779
- await scaffoldCommand(localPath, { force: true });
903
+ await scaffoldCommand(localPath);
780
904
  configManager.repo_path = localPath;
781
905
  configManager.remote_url = remoteUrl;
782
906
  if (configManager.save() === false) {
783
- console.error(chalk4.red("Failed to save config."));
907
+ console.error(chalk5.red("Failed to save config."));
784
908
  return false;
785
909
  }
910
+ printSaveHint(localPath);
786
911
  return true;
787
912
  };
788
913
  var installCommand = async (target) => {
789
914
  try {
790
915
  if (isGitUrl(target) === false) {
791
- console.error(chalk4.red("\u274C Only remote git URLs are supported."));
792
- console.log(chalk4.dim(" Example: set-prompt install https://github.com/you/my-prompts"));
916
+ console.error(chalk5.red("\u274C Only remote git URLs are supported."));
917
+ console.log(chalk5.dim(" Example: set-prompt install https://github.com/you/my-prompts"));
793
918
  process.exit(1);
794
919
  }
795
920
  const normalizeUrl = (url) => url.replace(/\.git$/, "").toLowerCase();
796
921
  if (configManager.repo_path != null) {
797
922
  if (normalizeUrl(configManager.remote_url ?? "") === normalizeUrl(target)) {
798
- console.error(chalk4.red(`\u274C Already installed from the same URL: ${target}`));
799
- console.log(chalk4.dim(" Use `set-prompt update` to pull the latest changes."));
923
+ console.error(chalk5.red(`\u274C Already installed from the same URL: ${target}`));
924
+ console.log(chalk5.dim(" Use `set-prompt repo pull` to pull the latest changes."));
800
925
  return false;
801
926
  }
802
- console.warn(chalk4.yellow(`\u26A0 Switching repo: ${configManager.remote_url} \u2192 ${target}`));
927
+ console.warn(chalk5.yellow(`\u26A0 Switching repo: ${configManager.remote_url} \u2192 ${target}`));
803
928
  const proceed = await confirm2({ message: "Replace existing installation?", default: false });
804
929
  if (!proceed) {
805
- console.log(chalk4.yellow("Cancelled."));
930
+ console.log(chalk5.yellow("Cancelled."));
806
931
  return false;
807
932
  }
808
933
  } else {
809
934
  const proceed = await confirm2({ message: `Clone and register "${target}"?`, default: true });
810
935
  if (!proceed) {
811
- console.log(chalk4.yellow("Cancelled."));
936
+ console.log(chalk5.yellow("Cancelled."));
812
937
  return false;
813
938
  }
814
939
  }
815
940
  return await cloneRepo(target);
816
941
  } catch (ex) {
817
- console.error(chalk4.red(`Unexpected error: ${ex.message}`), ex);
942
+ console.error(chalk5.red(`Unexpected error: ${ex.message}`), ex);
818
943
  process.exit(1);
819
944
  }
820
945
  };
821
946
 
822
947
  // src/commands/link-command.ts
823
- import chalk11 from "chalk";
948
+ import chalk12 from "chalk";
824
949
  import { checkbox } from "@inquirer/prompts";
825
950
 
826
951
  // src/link/claudecode.ts
827
952
  import path4 from "path";
828
- import fs4 from "fs";
953
+ import fs5 from "fs";
829
954
  import os2 from "os";
830
- import chalk5 from "chalk";
955
+ import chalk6 from "chalk";
831
956
  import { confirm as confirm3 } from "@inquirer/prompts";
832
957
  var linkClaudeCode = async () => {
833
958
  const repoPath = resolveRepoPath();
@@ -837,32 +962,32 @@ var linkClaudeCode = async () => {
837
962
  const buildMarketplace = () => {
838
963
  try {
839
964
  const marketplaceMetaDir = path4.join(CLAUDE_CODE_DIR, ".claude-plugin");
840
- fs4.mkdirSync(marketplaceMetaDir, { recursive: true });
965
+ fs5.mkdirSync(marketplaceMetaDir, { recursive: true });
841
966
  const marketplaceJson = {
842
967
  name: MARKET_NAME,
843
968
  owner: { name: os2.userInfo().username },
844
969
  metadata: { description: "Managed by set-prompt", version: "1.0.0" },
845
970
  plugins: [{ name: PLUGIN_NAME, source: `./plugins/${PLUGIN_NAME}`, description: "Managed by set-prompt" }]
846
971
  };
847
- fs4.writeFileSync(
972
+ fs5.writeFileSync(
848
973
  path4.join(marketplaceMetaDir, "marketplace.json"),
849
974
  JSON.stringify(marketplaceJson, null, 4),
850
975
  "utf-8"
851
976
  );
852
- console.log(chalk5.dim(" \u251C\u2500\u2500 .claude-plugin/"));
853
- console.log(chalk5.dim(" \u2502 \u2514\u2500\u2500 marketplace.json") + chalk5.green(" \u2713"));
977
+ console.log(chalk6.dim(" \u251C\u2500\u2500 .claude-plugin/"));
978
+ console.log(chalk6.dim(" \u2502 \u2514\u2500\u2500 marketplace.json") + chalk6.green(" \u2713"));
854
979
  const pluginLink = path4.join(CLAUDE_CODE_DIR, "plugins", PLUGIN_NAME);
855
- fs4.mkdirSync(path4.dirname(pluginLink), { recursive: true });
856
- if (fs4.existsSync(pluginLink)) {
857
- fs4.rmSync(pluginLink, { recursive: true, force: true });
980
+ fs5.mkdirSync(path4.dirname(pluginLink), { recursive: true });
981
+ if (fs5.existsSync(pluginLink)) {
982
+ fs5.rmSync(pluginLink, { recursive: true, force: true });
858
983
  }
859
984
  const symlinkType = process.platform === "win32" ? "junction" : "dir";
860
- fs4.symlinkSync(repoPath, pluginLink, symlinkType);
861
- console.log(chalk5.dim(" \u2514\u2500\u2500 plugins/"));
862
- console.log(chalk5.dim(` \u2514\u2500\u2500 ${PLUGIN_NAME}/`) + chalk5.dim(` \u2192 ${repoPath}`) + chalk5.green(" \u2713"));
985
+ fs5.symlinkSync(repoPath, pluginLink, symlinkType);
986
+ console.log(chalk6.dim(" \u2514\u2500\u2500 plugins/"));
987
+ console.log(chalk6.dim(` \u2514\u2500\u2500 ${PLUGIN_NAME}/`) + chalk6.dim(` \u2192 ${repoPath}`) + chalk6.green(" \u2713"));
863
988
  return true;
864
989
  } catch (ex) {
865
- console.error(chalk5.red(`\u274C Failed to build marketplace structure: ${ex.message}`));
990
+ console.error(chalk6.red(`\u274C Failed to build marketplace structure: ${ex.message}`));
866
991
  return false;
867
992
  }
868
993
  };
@@ -870,18 +995,18 @@ var linkClaudeCode = async () => {
870
995
  const claudeSettingsPath = path4.join(os2.homedir(), ".claude", "settings.json");
871
996
  try {
872
997
  let settings = {};
873
- if (fs4.existsSync(claudeSettingsPath)) {
874
- const raw = fs4.readFileSync(claudeSettingsPath, "utf-8");
998
+ if (fs5.existsSync(claudeSettingsPath)) {
999
+ const raw = fs5.readFileSync(claudeSettingsPath, "utf-8");
875
1000
  try {
876
1001
  const parsed = JSON.parse(raw);
877
1002
  if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
878
1003
  settings = parsed;
879
1004
  } else {
880
- console.warn(chalk5.yellow(" \u26A0 settings.json has unexpected format \u2014 proceeding with caution"));
1005
+ console.warn(chalk6.yellow(" \u26A0 settings.json has unexpected format \u2014 proceeding with caution"));
881
1006
  }
882
1007
  } catch {
883
- console.warn(chalk5.yellow(" \u26A0 Failed to parse settings.json \u2014 will not overwrite existing file"));
884
- console.error(chalk5.red("\u274C Could not register plugin. Please add manually."));
1008
+ console.warn(chalk6.yellow(" \u26A0 Failed to parse settings.json \u2014 will not overwrite existing file"));
1009
+ console.error(chalk6.red("\u274C Could not register plugin. Please add manually."));
885
1010
  return false;
886
1011
  }
887
1012
  }
@@ -894,43 +1019,43 @@ var linkClaudeCode = async () => {
894
1019
  [`${PLUGIN_NAME}@${MARKET_NAME}`]: true
895
1020
  };
896
1021
  let backupPath = null;
897
- if (fs4.existsSync(claudeSettingsPath)) {
1022
+ if (fs5.existsSync(claudeSettingsPath)) {
898
1023
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
899
1024
  backupPath = `${claudeSettingsPath}.bak.${timestamp}`;
900
1025
  try {
901
- fs4.copyFileSync(claudeSettingsPath, backupPath);
1026
+ fs5.copyFileSync(claudeSettingsPath, backupPath);
902
1027
  } catch (ex) {
903
- console.warn(chalk5.yellow(` \u26A0 Could not create backup: ${ex.message}`));
1028
+ console.warn(chalk6.yellow(` \u26A0 Could not create backup: ${ex.message}`));
904
1029
  backupPath = null;
905
1030
  }
906
1031
  }
907
1032
  try {
908
- fs4.mkdirSync(path4.dirname(claudeSettingsPath), { recursive: true });
909
- fs4.writeFileSync(claudeSettingsPath, JSON.stringify(settings, null, 4), "utf-8");
1033
+ fs5.mkdirSync(path4.dirname(claudeSettingsPath), { recursive: true });
1034
+ fs5.writeFileSync(claudeSettingsPath, JSON.stringify(settings, null, 4), "utf-8");
910
1035
  } catch (ex) {
911
1036
  if (backupPath !== null) {
912
1037
  try {
913
- fs4.copyFileSync(backupPath, claudeSettingsPath);
914
- fs4.unlinkSync(backupPath);
915
- console.warn(chalk5.yellow(" \u26A0 Write failed \u2014 rolled back to original."));
1038
+ fs5.copyFileSync(backupPath, claudeSettingsPath);
1039
+ fs5.unlinkSync(backupPath);
1040
+ console.warn(chalk6.yellow(" \u26A0 Write failed \u2014 rolled back to original."));
916
1041
  } catch {
917
- console.error(chalk5.red(` \u274C Rollback failed. Backup preserved at: ${backupPath}`));
1042
+ console.error(chalk6.red(` \u274C Rollback failed. Backup preserved at: ${backupPath}`));
918
1043
  }
919
1044
  }
920
1045
  throw ex;
921
1046
  }
922
1047
  if (backupPath !== null) {
923
1048
  try {
924
- fs4.unlinkSync(backupPath);
1049
+ fs5.unlinkSync(backupPath);
925
1050
  } catch {
926
1051
  }
927
1052
  }
928
1053
  console.log(`\u2705 Registered to Claude Code settings.`);
929
- console.log(chalk5.dim(` ${claudeSettingsPath}`));
1054
+ console.log(chalk6.dim(` ${claudeSettingsPath}`));
930
1055
  return true;
931
1056
  } catch (ex) {
932
- console.error(chalk5.red(`\u274C Failed to update settings.json: ${ex.message}`));
933
- console.log(chalk5.dim(" Please add the plugin manually via Claude Code /plugins."));
1057
+ console.error(chalk6.red(`\u274C Failed to update settings.json: ${ex.message}`));
1058
+ console.log(chalk6.dim(" Please add the plugin manually via Claude Code /plugins."));
934
1059
  return false;
935
1060
  }
936
1061
  };
@@ -940,9 +1065,9 @@ var linkClaudeCode = async () => {
940
1065
  const pluginKey = `${PLUGIN_NAME}@${MARKET_NAME}`;
941
1066
  try {
942
1067
  let data = { version: 2, plugins: {} };
943
- if (fs4.existsSync(installedPluginsPath)) {
1068
+ if (fs5.existsSync(installedPluginsPath)) {
944
1069
  try {
945
- data = JSON.parse(fs4.readFileSync(installedPluginsPath, "utf-8"));
1070
+ data = JSON.parse(fs5.readFileSync(installedPluginsPath, "utf-8"));
946
1071
  } catch {
947
1072
  }
948
1073
  }
@@ -958,17 +1083,17 @@ var linkClaudeCode = async () => {
958
1083
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
959
1084
  }
960
1085
  ];
961
- fs4.mkdirSync(path4.dirname(installedPluginsPath), { recursive: true });
962
- fs4.writeFileSync(installedPluginsPath, JSON.stringify(data, null, 4), "utf-8");
1086
+ fs5.mkdirSync(path4.dirname(installedPluginsPath), { recursive: true });
1087
+ fs5.writeFileSync(installedPluginsPath, JSON.stringify(data, null, 4), "utf-8");
963
1088
  console.log(`\u2705 Patched installed_plugins.json \u2192 installPath points to source.`);
964
- console.log(chalk5.dim(` ${installPath}`));
1089
+ console.log(chalk6.dim(` ${installPath}`));
965
1090
  } catch (ex) {
966
- console.warn(chalk5.yellow(` \u26A0 Could not patch installed_plugins.json: ${ex.message}`));
1091
+ console.warn(chalk6.yellow(` \u26A0 Could not patch installed_plugins.json: ${ex.message}`));
967
1092
  }
968
1093
  };
969
- console.log(chalk5.green(`
1094
+ console.log(chalk6.green(`
970
1095
  Setting up Claude Code plugin...`));
971
- console.log(chalk5.dim(CLAUDE_CODE_DIR));
1096
+ console.log(chalk6.dim(CLAUDE_CODE_DIR));
972
1097
  const marketplaceOk = buildMarketplace();
973
1098
  if (marketplaceOk === false) {
974
1099
  return;
@@ -988,20 +1113,20 @@ var unlinkClaudeCode = async (force = false) => {
988
1113
  default: false
989
1114
  });
990
1115
  if (!ok) {
991
- console.log(chalk5.yellow("Cancelled."));
1116
+ console.log(chalk6.yellow("Cancelled."));
992
1117
  return;
993
1118
  }
994
1119
  }
995
- console.log(chalk5.red(`
1120
+ console.log(chalk6.red(`
996
1121
  Removing Claude Code plugin...`));
997
- console.log(chalk5.dim(CLAUDE_CODE_DIR));
1122
+ console.log(chalk6.dim(CLAUDE_CODE_DIR));
998
1123
  const claudeSettingsPath = path4.join(os2.homedir(), ".claude", "settings.json");
999
- if (fs4.existsSync(claudeSettingsPath)) {
1124
+ if (fs5.existsSync(claudeSettingsPath)) {
1000
1125
  try {
1001
1126
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1002
1127
  const backupPath = `${claudeSettingsPath}.bak.${timestamp}`;
1003
- fs4.copyFileSync(claudeSettingsPath, backupPath);
1004
- const settings = JSON.parse(fs4.readFileSync(claudeSettingsPath, "utf-8"));
1128
+ fs5.copyFileSync(claudeSettingsPath, backupPath);
1129
+ const settings = JSON.parse(fs5.readFileSync(claudeSettingsPath, "utf-8"));
1005
1130
  if (settings?.extraKnownMarketplaces?.[MARKET_NAME] !== void 0) {
1006
1131
  delete settings.extraKnownMarketplaces[MARKET_NAME];
1007
1132
  }
@@ -1009,26 +1134,26 @@ Removing Claude Code plugin...`));
1009
1134
  delete settings.enabledPlugins[`${PLUGIN_NAME}@${MARKET_NAME}`];
1010
1135
  }
1011
1136
  try {
1012
- fs4.writeFileSync(claudeSettingsPath, JSON.stringify(settings, null, 4), "utf-8");
1013
- fs4.unlinkSync(backupPath);
1014
- console.log(chalk5.red(" removed") + chalk5.dim(` set-prompt entries from: ${claudeSettingsPath}`));
1137
+ fs5.writeFileSync(claudeSettingsPath, JSON.stringify(settings, null, 4), "utf-8");
1138
+ fs5.unlinkSync(backupPath);
1139
+ console.log(chalk6.red(" removed") + chalk6.dim(` set-prompt entries from: ${claudeSettingsPath}`));
1015
1140
  } catch (ex) {
1016
- fs4.copyFileSync(backupPath, claudeSettingsPath);
1017
- fs4.unlinkSync(backupPath);
1018
- console.warn(chalk5.yellow(" \u26A0 Write failed \u2014 rolled back to original."));
1141
+ fs5.copyFileSync(backupPath, claudeSettingsPath);
1142
+ fs5.unlinkSync(backupPath);
1143
+ console.warn(chalk6.yellow(" \u26A0 Write failed \u2014 rolled back to original."));
1019
1144
  }
1020
1145
  } catch (ex) {
1021
- console.error(chalk5.red(` \u274C Failed to clean up settings.json: ${ex.message}`));
1146
+ console.error(chalk6.red(` \u274C Failed to clean up settings.json: ${ex.message}`));
1022
1147
  }
1023
1148
  }
1024
1149
  const claudePluginsDir = path4.join(os2.homedir(), ".claude", "plugins");
1025
1150
  const installedPluginsPath = path4.join(claudePluginsDir, "installed_plugins.json");
1026
- if (fs4.existsSync(installedPluginsPath)) {
1151
+ if (fs5.existsSync(installedPluginsPath)) {
1027
1152
  try {
1028
1153
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1029
1154
  const backupPath = `${installedPluginsPath}.bak.${timestamp}`;
1030
- fs4.copyFileSync(installedPluginsPath, backupPath);
1031
- const installed = JSON.parse(fs4.readFileSync(installedPluginsPath, "utf-8"));
1155
+ fs5.copyFileSync(installedPluginsPath, backupPath);
1156
+ const installed = JSON.parse(fs5.readFileSync(installedPluginsPath, "utf-8"));
1032
1157
  if (installed?.plugins && typeof installed.plugins === "object") {
1033
1158
  for (const key of Object.keys(installed.plugins)) {
1034
1159
  if (key.endsWith(`@${MARKET_NAME}`)) {
@@ -1037,44 +1162,44 @@ Removing Claude Code plugin...`));
1037
1162
  }
1038
1163
  }
1039
1164
  try {
1040
- fs4.writeFileSync(installedPluginsPath, JSON.stringify(installed, null, 4), "utf-8");
1041
- fs4.unlinkSync(backupPath);
1042
- console.log(chalk5.red(" removed") + chalk5.dim(` set-prompt entries from: ${installedPluginsPath}`));
1165
+ fs5.writeFileSync(installedPluginsPath, JSON.stringify(installed, null, 4), "utf-8");
1166
+ fs5.unlinkSync(backupPath);
1167
+ console.log(chalk6.red(" removed") + chalk6.dim(` set-prompt entries from: ${installedPluginsPath}`));
1043
1168
  } catch (ex) {
1044
- fs4.copyFileSync(backupPath, installedPluginsPath);
1045
- fs4.unlinkSync(backupPath);
1046
- console.warn(chalk5.yellow(" \u26A0 Write failed \u2014 rolled back installed_plugins.json."));
1169
+ fs5.copyFileSync(backupPath, installedPluginsPath);
1170
+ fs5.unlinkSync(backupPath);
1171
+ console.warn(chalk6.yellow(" \u26A0 Write failed \u2014 rolled back installed_plugins.json."));
1047
1172
  }
1048
1173
  } catch (ex) {
1049
- console.error(chalk5.red(` \u274C Failed to clean up installed_plugins.json: ${ex.message}`));
1174
+ console.error(chalk6.red(` \u274C Failed to clean up installed_plugins.json: ${ex.message}`));
1050
1175
  }
1051
1176
  }
1052
1177
  const knownMarketplacesPath = path4.join(claudePluginsDir, "known_marketplaces.json");
1053
- if (fs4.existsSync(knownMarketplacesPath)) {
1178
+ if (fs5.existsSync(knownMarketplacesPath)) {
1054
1179
  try {
1055
1180
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1056
1181
  const backupPath = `${knownMarketplacesPath}.bak.${timestamp}`;
1057
- fs4.copyFileSync(knownMarketplacesPath, backupPath);
1058
- const marketplaces = JSON.parse(fs4.readFileSync(knownMarketplacesPath, "utf-8"));
1182
+ fs5.copyFileSync(knownMarketplacesPath, backupPath);
1183
+ const marketplaces = JSON.parse(fs5.readFileSync(knownMarketplacesPath, "utf-8"));
1059
1184
  if (marketplaces?.[MARKET_NAME] !== void 0) {
1060
1185
  delete marketplaces[MARKET_NAME];
1061
1186
  }
1062
1187
  try {
1063
- fs4.writeFileSync(knownMarketplacesPath, JSON.stringify(marketplaces, null, 4), "utf-8");
1064
- fs4.unlinkSync(backupPath);
1065
- console.log(chalk5.red(" removed") + chalk5.dim(` set-prompt entry from: ${knownMarketplacesPath}`));
1188
+ fs5.writeFileSync(knownMarketplacesPath, JSON.stringify(marketplaces, null, 4), "utf-8");
1189
+ fs5.unlinkSync(backupPath);
1190
+ console.log(chalk6.red(" removed") + chalk6.dim(` set-prompt entry from: ${knownMarketplacesPath}`));
1066
1191
  } catch (ex) {
1067
- fs4.copyFileSync(backupPath, knownMarketplacesPath);
1068
- fs4.unlinkSync(backupPath);
1069
- console.warn(chalk5.yellow(" \u26A0 Write failed \u2014 rolled back known_marketplaces.json."));
1192
+ fs5.copyFileSync(backupPath, knownMarketplacesPath);
1193
+ fs5.unlinkSync(backupPath);
1194
+ console.warn(chalk6.yellow(" \u26A0 Write failed \u2014 rolled back known_marketplaces.json."));
1070
1195
  }
1071
1196
  } catch (ex) {
1072
- console.error(chalk5.red(` \u274C Failed to clean up known_marketplaces.json: ${ex.message}`));
1197
+ console.error(chalk6.red(` \u274C Failed to clean up known_marketplaces.json: ${ex.message}`));
1073
1198
  }
1074
1199
  }
1075
- if (fs4.existsSync(CLAUDE_CODE_DIR)) {
1076
- fs4.rmSync(CLAUDE_CODE_DIR, { recursive: true, force: true });
1077
- console.log(chalk5.red(" removed") + chalk5.dim(`: ${CLAUDE_CODE_DIR}`));
1200
+ if (fs5.existsSync(CLAUDE_CODE_DIR)) {
1201
+ fs5.rmSync(CLAUDE_CODE_DIR, { recursive: true, force: true });
1202
+ console.log(chalk6.red(" removed") + chalk6.dim(`: ${CLAUDE_CODE_DIR}`));
1078
1203
  }
1079
1204
  configManager.claude_code = null;
1080
1205
  configManager.save();
@@ -1082,8 +1207,8 @@ Removing Claude Code plugin...`));
1082
1207
 
1083
1208
  // src/link/roocode.ts
1084
1209
  import path5 from "path";
1085
- import fs5 from "fs";
1086
- import chalk6 from "chalk";
1210
+ import fs6 from "fs";
1211
+ import chalk7 from "chalk";
1087
1212
  import { confirm as confirm4 } from "@inquirer/prompts";
1088
1213
  import { pathExists } from "fs-extra";
1089
1214
  var linkRooCode = async () => {
@@ -1091,44 +1216,44 @@ var linkRooCode = async () => {
1091
1216
  if (repoPath == null) {
1092
1217
  return;
1093
1218
  }
1094
- console.log(chalk6.green(`
1219
+ console.log(chalk7.green(`
1095
1220
  Setting up RooCode integration...`));
1096
- console.log(chalk6.dim(ROO_DIR));
1221
+ console.log(chalk7.dim(ROO_DIR));
1097
1222
  const roocodeDirs = AGENT_PROMPT_DIRS["roocode" /* ROOCODE */];
1098
1223
  const backupExistingRooCodeFiles = async () => {
1099
1224
  try {
1100
- fs5.mkdirSync(ROO_DIR, { recursive: true });
1225
+ fs6.mkdirSync(ROO_DIR, { recursive: true });
1101
1226
  const dirsToBackup = [];
1102
1227
  for (const dir of roocodeDirs) {
1103
1228
  const target = path5.join(ROO_DIR, dir);
1104
- if (fs5.existsSync(target) && fs5.lstatSync(target).isSymbolicLink() === false && fs5.readdirSync(target).length > 0) {
1229
+ if (fs6.existsSync(target) && fs6.lstatSync(target).isSymbolicLink() === false && fs6.readdirSync(target).length > 0) {
1105
1230
  dirsToBackup.push(dir);
1106
1231
  }
1107
1232
  }
1108
1233
  if (dirsToBackup.length === 0) {
1109
1234
  return true;
1110
1235
  }
1111
- console.log(chalk6.yellow(`
1236
+ console.log(chalk7.yellow(`
1112
1237
  \u26A0 The following existing directories will be replaced by symlinks:`));
1113
1238
  for (const dir of dirsToBackup) {
1114
- console.log(chalk6.dim(` - ${path5.join(ROO_DIR, dir)}`));
1239
+ console.log(chalk7.dim(` - ${path5.join(ROO_DIR, dir)}`));
1115
1240
  }
1116
- console.log(chalk6.yellow(` They will be backed up to: `) + chalk6.dim(ROO_BACKUP_DIR));
1241
+ console.log(chalk7.yellow(` They will be backed up to: `) + chalk7.dim(ROO_BACKUP_DIR));
1117
1242
  const ok = await confirm4({ message: "Back up existing directories?", default: true });
1118
1243
  if (!ok) {
1119
- console.log(chalk6.yellow("Skipped RooCode linking."));
1244
+ console.log(chalk7.yellow("Skipped RooCode linking."));
1120
1245
  return false;
1121
1246
  }
1122
- fs5.mkdirSync(ROO_BACKUP_DIR, { recursive: true });
1247
+ fs6.mkdirSync(ROO_BACKUP_DIR, { recursive: true });
1123
1248
  for (const dir of dirsToBackup) {
1124
1249
  const src = path5.join(ROO_DIR, dir);
1125
1250
  const dest = path5.join(ROO_BACKUP_DIR, dir);
1126
- fs5.renameSync(src, dest);
1127
- console.log(chalk6.yellow(" backed up") + chalk6.dim(`: ${dir}/ \u2192 ${dest}`));
1251
+ fs6.renameSync(src, dest);
1252
+ console.log(chalk7.yellow(" backed up") + chalk7.dim(`: ${dir}/ \u2192 ${dest}`));
1128
1253
  }
1129
1254
  return true;
1130
1255
  } catch (ex) {
1131
- console.error(chalk6.red(`\u274C Failed to backup existing directories: ${ex.message}`));
1256
+ console.error(chalk7.red(`\u274C Failed to backup existing directories: ${ex.message}`));
1132
1257
  return false;
1133
1258
  }
1134
1259
  };
@@ -1141,21 +1266,21 @@ Setting up RooCode integration...`));
1141
1266
  if (await pathExists(src) === false) {
1142
1267
  continue;
1143
1268
  }
1144
- if (fs5.existsSync(dest)) {
1145
- fs5.rmSync(dest, { recursive: true, force: true });
1269
+ if (fs6.existsSync(dest)) {
1270
+ fs6.rmSync(dest, { recursive: true, force: true });
1146
1271
  }
1147
1272
  const symlinkType = process.platform === "win32" ? "junction" : "dir";
1148
- fs5.symlinkSync(src, dest, symlinkType);
1273
+ fs6.symlinkSync(src, dest, symlinkType);
1149
1274
  linked.push({ dir, src });
1150
1275
  }
1151
1276
  for (const { dir, src } of linked) {
1152
1277
  const isLast = linked[linked.length - 1].dir === dir;
1153
1278
  const branch = isLast ? "\u2514\u2500\u2500" : "\u251C\u2500\u2500";
1154
- console.log(chalk6.dim(` ${branch} `) + chalk6.bold(`${dir}/`) + chalk6.dim(` \u2192 ${src}`) + chalk6.green(" \u2713"));
1279
+ console.log(chalk7.dim(` ${branch} `) + chalk7.bold(`${dir}/`) + chalk7.dim(` \u2192 ${src}`) + chalk7.green(" \u2713"));
1155
1280
  }
1156
1281
  return true;
1157
1282
  } catch (ex) {
1158
- console.error(chalk6.red(`\u274C Failed to create symlinks: ${ex.message}`));
1283
+ console.error(chalk7.red(`\u274C Failed to create symlinks: ${ex.message}`));
1159
1284
  return false;
1160
1285
  }
1161
1286
  };
@@ -1177,35 +1302,35 @@ var unlinkRooCode = async (force = false) => {
1177
1302
  default: false
1178
1303
  });
1179
1304
  if (!ok) {
1180
- console.log(chalk6.yellow("Cancelled."));
1305
+ console.log(chalk7.yellow("Cancelled."));
1181
1306
  return;
1182
1307
  }
1183
1308
  }
1184
- console.log(chalk6.red(`
1309
+ console.log(chalk7.red(`
1185
1310
  Removing RooCode integration...`));
1186
- console.log(chalk6.dim(ROO_DIR));
1311
+ console.log(chalk7.dim(ROO_DIR));
1187
1312
  const backupPath = configManager.roocode?.backup_path ?? ROO_BACKUP_DIR;
1188
1313
  for (const dir of AGENT_PROMPT_DIRS["roocode" /* ROOCODE */]) {
1189
1314
  const target = path5.join(ROO_DIR, dir);
1190
- if (fs5.existsSync(target) && fs5.lstatSync(target).isSymbolicLink()) {
1191
- fs5.unlinkSync(target);
1192
- console.log(chalk6.red(" removed symlink") + chalk6.dim(`: ${target}`));
1315
+ if (fs6.existsSync(target) && fs6.lstatSync(target).isSymbolicLink()) {
1316
+ fs6.unlinkSync(target);
1317
+ console.log(chalk7.red(" removed symlink") + chalk7.dim(`: ${target}`));
1193
1318
  }
1194
1319
  }
1195
- if (fs5.existsSync(backupPath)) {
1320
+ if (fs6.existsSync(backupPath)) {
1196
1321
  try {
1197
1322
  for (const dir of AGENT_PROMPT_DIRS["roocode" /* ROOCODE */]) {
1198
1323
  const src = path5.join(backupPath, dir);
1199
1324
  const dest = path5.join(ROO_DIR, dir);
1200
- if (!fs5.existsSync(src)) {
1325
+ if (!fs6.existsSync(src)) {
1201
1326
  continue;
1202
1327
  }
1203
- fs5.renameSync(src, dest);
1204
- console.log(chalk6.green(" restored") + chalk6.dim(`: ${dir}/`));
1328
+ fs6.renameSync(src, dest);
1329
+ console.log(chalk7.green(" restored") + chalk7.dim(`: ${dir}/`));
1205
1330
  }
1206
- fs5.rmdirSync(backupPath);
1331
+ fs6.rmdirSync(backupPath);
1207
1332
  } catch (ex) {
1208
- console.error(chalk6.red(` \u274C Failed to restore RooCode backup: ${ex.message}`));
1333
+ console.error(chalk7.red(` \u274C Failed to restore RooCode backup: ${ex.message}`));
1209
1334
  }
1210
1335
  }
1211
1336
  configManager.roocode = null;
@@ -1214,8 +1339,8 @@ Removing RooCode integration...`));
1214
1339
 
1215
1340
  // src/link/openclaw.ts
1216
1341
  import path6 from "path";
1217
- import fs6 from "fs";
1218
- import chalk7 from "chalk";
1342
+ import fs7 from "fs";
1343
+ import chalk8 from "chalk";
1219
1344
  import { confirm as confirm5 } from "@inquirer/prompts";
1220
1345
  import { pathExists as pathExists2 } from "fs-extra";
1221
1346
  var linkOpenclaw = async () => {
@@ -1223,44 +1348,44 @@ var linkOpenclaw = async () => {
1223
1348
  if (repoPath == null) {
1224
1349
  return;
1225
1350
  }
1226
- console.log(chalk7.green(`
1351
+ console.log(chalk8.green(`
1227
1352
  Setting up OpenClaw integration...`));
1228
- console.log(chalk7.dim(OPENCLAW_DIR));
1353
+ console.log(chalk8.dim(OPENCLAW_DIR));
1229
1354
  const openclawDirs = AGENT_PROMPT_DIRS["openclaw" /* OPENCLAW */];
1230
1355
  const backupExistingOpenclawFiles = async () => {
1231
1356
  try {
1232
- fs6.mkdirSync(OPENCLAW_DIR, { recursive: true });
1357
+ fs7.mkdirSync(OPENCLAW_DIR, { recursive: true });
1233
1358
  const dirsToBackup = [];
1234
1359
  for (const dir of openclawDirs) {
1235
1360
  const target = path6.join(OPENCLAW_DIR, dir);
1236
- if (fs6.existsSync(target) && fs6.lstatSync(target).isSymbolicLink() === false && fs6.readdirSync(target).length > 0) {
1361
+ if (fs7.existsSync(target) && fs7.lstatSync(target).isSymbolicLink() === false && fs7.readdirSync(target).length > 0) {
1237
1362
  dirsToBackup.push(dir);
1238
1363
  }
1239
1364
  }
1240
1365
  if (dirsToBackup.length === 0) {
1241
1366
  return true;
1242
1367
  }
1243
- console.log(chalk7.yellow(`
1368
+ console.log(chalk8.yellow(`
1244
1369
  \u26A0 The following existing directories will be replaced by symlinks:`));
1245
1370
  for (const dir of dirsToBackup) {
1246
- console.log(chalk7.dim(` - ${path6.join(OPENCLAW_DIR, dir)}`));
1371
+ console.log(chalk8.dim(` - ${path6.join(OPENCLAW_DIR, dir)}`));
1247
1372
  }
1248
- console.log(chalk7.yellow(` They will be backed up to: `) + chalk7.dim(OPENCLAW_BACKUP_DIR));
1373
+ console.log(chalk8.yellow(` They will be backed up to: `) + chalk8.dim(OPENCLAW_BACKUP_DIR));
1249
1374
  const ok = await confirm5({ message: "Back up existing directories?", default: true });
1250
1375
  if (!ok) {
1251
- console.log(chalk7.yellow("Skipped OpenClaw linking."));
1376
+ console.log(chalk8.yellow("Skipped OpenClaw linking."));
1252
1377
  return false;
1253
1378
  }
1254
- fs6.mkdirSync(OPENCLAW_BACKUP_DIR, { recursive: true });
1379
+ fs7.mkdirSync(OPENCLAW_BACKUP_DIR, { recursive: true });
1255
1380
  for (const dir of dirsToBackup) {
1256
1381
  const src = path6.join(OPENCLAW_DIR, dir);
1257
1382
  const dest = path6.join(OPENCLAW_BACKUP_DIR, dir);
1258
- fs6.renameSync(src, dest);
1259
- console.log(chalk7.yellow(" backed up") + chalk7.dim(`: ${dir}/ \u2192 ${dest}`));
1383
+ fs7.renameSync(src, dest);
1384
+ console.log(chalk8.yellow(" backed up") + chalk8.dim(`: ${dir}/ \u2192 ${dest}`));
1260
1385
  }
1261
1386
  return true;
1262
1387
  } catch (ex) {
1263
- console.error(chalk7.red(`\u274C Failed to backup existing directories: ${ex.message}`));
1388
+ console.error(chalk8.red(`\u274C Failed to backup existing directories: ${ex.message}`));
1264
1389
  return false;
1265
1390
  }
1266
1391
  };
@@ -1273,21 +1398,21 @@ Setting up OpenClaw integration...`));
1273
1398
  if (await pathExists2(src) === false) {
1274
1399
  continue;
1275
1400
  }
1276
- if (fs6.existsSync(dest)) {
1277
- fs6.rmSync(dest, { recursive: true, force: true });
1401
+ if (fs7.existsSync(dest)) {
1402
+ fs7.rmSync(dest, { recursive: true, force: true });
1278
1403
  }
1279
1404
  const symlinkType = process.platform === "win32" ? "junction" : "dir";
1280
- fs6.symlinkSync(src, dest, symlinkType);
1405
+ fs7.symlinkSync(src, dest, symlinkType);
1281
1406
  linked.push({ dir, src });
1282
1407
  }
1283
1408
  for (const { dir, src } of linked) {
1284
1409
  const isLast = linked[linked.length - 1].dir === dir;
1285
1410
  const branch = isLast ? "\u2514\u2500\u2500" : "\u251C\u2500\u2500";
1286
- console.log(chalk7.dim(` ${branch} `) + chalk7.bold(`${dir}/`) + chalk7.dim(` \u2192 ${src}`) + chalk7.green(" \u2713"));
1411
+ console.log(chalk8.dim(` ${branch} `) + chalk8.bold(`${dir}/`) + chalk8.dim(` \u2192 ${src}`) + chalk8.green(" \u2713"));
1287
1412
  }
1288
1413
  return true;
1289
1414
  } catch (ex) {
1290
- console.error(chalk7.red(`\u274C Failed to create symlinks: ${ex.message}`));
1415
+ console.error(chalk8.red(`\u274C Failed to create symlinks: ${ex.message}`));
1291
1416
  return false;
1292
1417
  }
1293
1418
  };
@@ -1309,35 +1434,35 @@ var unlinkOpenclaw = async (force = false) => {
1309
1434
  default: false
1310
1435
  });
1311
1436
  if (!ok) {
1312
- console.log(chalk7.yellow("Cancelled."));
1437
+ console.log(chalk8.yellow("Cancelled."));
1313
1438
  return;
1314
1439
  }
1315
1440
  }
1316
- console.log(chalk7.red(`
1441
+ console.log(chalk8.red(`
1317
1442
  Removing OpenClaw integration...`));
1318
- console.log(chalk7.dim(OPENCLAW_DIR));
1443
+ console.log(chalk8.dim(OPENCLAW_DIR));
1319
1444
  const backupPath = configManager.openclaw?.backup_path ?? OPENCLAW_BACKUP_DIR;
1320
1445
  for (const dir of AGENT_PROMPT_DIRS["openclaw" /* OPENCLAW */]) {
1321
1446
  const target = path6.join(OPENCLAW_DIR, dir);
1322
- if (fs6.existsSync(target) && fs6.lstatSync(target).isSymbolicLink()) {
1323
- fs6.unlinkSync(target);
1324
- console.log(chalk7.red(" removed symlink") + chalk7.dim(`: ${target}`));
1447
+ if (fs7.existsSync(target) && fs7.lstatSync(target).isSymbolicLink()) {
1448
+ fs7.unlinkSync(target);
1449
+ console.log(chalk8.red(" removed symlink") + chalk8.dim(`: ${target}`));
1325
1450
  }
1326
1451
  }
1327
- if (fs6.existsSync(backupPath)) {
1452
+ if (fs7.existsSync(backupPath)) {
1328
1453
  try {
1329
1454
  for (const dir of AGENT_PROMPT_DIRS["openclaw" /* OPENCLAW */]) {
1330
1455
  const src = path6.join(backupPath, dir);
1331
1456
  const dest = path6.join(OPENCLAW_DIR, dir);
1332
- if (!fs6.existsSync(src)) {
1457
+ if (!fs7.existsSync(src)) {
1333
1458
  continue;
1334
1459
  }
1335
- fs6.renameSync(src, dest);
1336
- console.log(chalk7.green(" restored") + chalk7.dim(`: ${dir}/`));
1460
+ fs7.renameSync(src, dest);
1461
+ console.log(chalk8.green(" restored") + chalk8.dim(`: ${dir}/`));
1337
1462
  }
1338
- fs6.rmdirSync(backupPath);
1463
+ fs7.rmdirSync(backupPath);
1339
1464
  } catch (ex) {
1340
- console.error(chalk7.red(` \u274C Failed to restore OpenClaw backup: ${ex.message}`));
1465
+ console.error(chalk8.red(` \u274C Failed to restore OpenClaw backup: ${ex.message}`));
1341
1466
  }
1342
1467
  }
1343
1468
  configManager.openclaw = null;
@@ -1346,8 +1471,8 @@ Removing OpenClaw integration...`));
1346
1471
 
1347
1472
  // src/link/antigravity.ts
1348
1473
  import path7 from "path";
1349
- import fs7 from "fs";
1350
- import chalk8 from "chalk";
1474
+ import fs8 from "fs";
1475
+ import chalk9 from "chalk";
1351
1476
  import { confirm as confirm6 } from "@inquirer/prompts";
1352
1477
  import { pathExists as pathExists3 } from "fs-extra";
1353
1478
  var linkAntigravity = async () => {
@@ -1355,44 +1480,44 @@ var linkAntigravity = async () => {
1355
1480
  if (repoPath == null) {
1356
1481
  return;
1357
1482
  }
1358
- console.log(chalk8.green(`
1483
+ console.log(chalk9.green(`
1359
1484
  Setting up Antigravity integration...`));
1360
- console.log(chalk8.dim(ANTIGRAVITY_DIR));
1485
+ console.log(chalk9.dim(ANTIGRAVITY_DIR));
1361
1486
  const antigravityDirs = AGENT_PROMPT_DIRS["antigravity" /* ANTIGRAVITY */];
1362
1487
  const backupExistingAntigravityFiles = async () => {
1363
1488
  try {
1364
- fs7.mkdirSync(ANTIGRAVITY_DIR, { recursive: true });
1489
+ fs8.mkdirSync(ANTIGRAVITY_DIR, { recursive: true });
1365
1490
  const dirsToBackup = [];
1366
1491
  for (const dir of antigravityDirs) {
1367
1492
  const target = path7.join(ANTIGRAVITY_DIR, dir);
1368
- if (fs7.existsSync(target) && fs7.lstatSync(target).isSymbolicLink() === false && fs7.readdirSync(target).length > 0) {
1493
+ if (fs8.existsSync(target) && fs8.lstatSync(target).isSymbolicLink() === false && fs8.readdirSync(target).length > 0) {
1369
1494
  dirsToBackup.push(dir);
1370
1495
  }
1371
1496
  }
1372
1497
  if (dirsToBackup.length === 0) {
1373
1498
  return true;
1374
1499
  }
1375
- console.log(chalk8.yellow(`
1500
+ console.log(chalk9.yellow(`
1376
1501
  \u26A0 The following existing directories will be replaced by symlinks:`));
1377
1502
  for (const dir of dirsToBackup) {
1378
- console.log(chalk8.dim(` - ${path7.join(ANTIGRAVITY_DIR, dir)}`));
1503
+ console.log(chalk9.dim(` - ${path7.join(ANTIGRAVITY_DIR, dir)}`));
1379
1504
  }
1380
- console.log(chalk8.yellow(` They will be backed up to: `) + chalk8.dim(ANTIGRAVITY_BACKUP_DIR));
1505
+ console.log(chalk9.yellow(` They will be backed up to: `) + chalk9.dim(ANTIGRAVITY_BACKUP_DIR));
1381
1506
  const ok = await confirm6({ message: "Back up existing directories?", default: true });
1382
1507
  if (!ok) {
1383
- console.log(chalk8.yellow("Skipped Antigravity linking."));
1508
+ console.log(chalk9.yellow("Skipped Antigravity linking."));
1384
1509
  return false;
1385
1510
  }
1386
- fs7.mkdirSync(ANTIGRAVITY_BACKUP_DIR, { recursive: true });
1511
+ fs8.mkdirSync(ANTIGRAVITY_BACKUP_DIR, { recursive: true });
1387
1512
  for (const dir of antigravityDirs) {
1388
1513
  const src = path7.join(ANTIGRAVITY_DIR, dir);
1389
1514
  const dest = path7.join(ANTIGRAVITY_BACKUP_DIR, dir);
1390
- fs7.renameSync(src, dest);
1391
- console.log(chalk8.yellow(" backed up") + chalk8.dim(`: ${dir}/ \u2192 ${dest}`));
1515
+ fs8.renameSync(src, dest);
1516
+ console.log(chalk9.yellow(" backed up") + chalk9.dim(`: ${dir}/ \u2192 ${dest}`));
1392
1517
  }
1393
1518
  return true;
1394
1519
  } catch (ex) {
1395
- console.error(chalk8.red(`\u274C Failed to backup existing directories: ${ex.message}`));
1520
+ console.error(chalk9.red(`\u274C Failed to backup existing directories: ${ex.message}`));
1396
1521
  return false;
1397
1522
  }
1398
1523
  };
@@ -1405,21 +1530,21 @@ Setting up Antigravity integration...`));
1405
1530
  if (await pathExists3(src) === false) {
1406
1531
  continue;
1407
1532
  }
1408
- if (fs7.existsSync(dest)) {
1409
- fs7.rmSync(dest, { recursive: true, force: true });
1533
+ if (fs8.existsSync(dest)) {
1534
+ fs8.rmSync(dest, { recursive: true, force: true });
1410
1535
  }
1411
1536
  const symlinkType = process.platform === "win32" ? "junction" : "dir";
1412
- fs7.symlinkSync(src, dest, symlinkType);
1537
+ fs8.symlinkSync(src, dest, symlinkType);
1413
1538
  linked.push({ dir, src });
1414
1539
  }
1415
1540
  for (const { dir, src } of linked) {
1416
1541
  const isLast = linked[linked.length - 1].dir === dir;
1417
1542
  const branch = isLast ? "\u2514\u2500\u2500" : "\u251C\u2500\u2500";
1418
- console.log(chalk8.dim(` ${branch} `) + chalk8.bold(`${dir}/`) + chalk8.dim(` \u2192 ${src}`) + chalk8.green(" \u2713"));
1543
+ console.log(chalk9.dim(` ${branch} `) + chalk9.bold(`${dir}/`) + chalk9.dim(` \u2192 ${src}`) + chalk9.green(" \u2713"));
1419
1544
  }
1420
1545
  return true;
1421
1546
  } catch (ex) {
1422
- console.error(chalk8.red(`\u274C Failed to create symlinks: ${ex.message}`));
1547
+ console.error(chalk9.red(`\u274C Failed to create symlinks: ${ex.message}`));
1423
1548
  return false;
1424
1549
  }
1425
1550
  };
@@ -1441,35 +1566,35 @@ var unlinkAntigravity = async (force = false) => {
1441
1566
  default: false
1442
1567
  });
1443
1568
  if (!ok) {
1444
- console.log(chalk8.yellow("Cancelled."));
1569
+ console.log(chalk9.yellow("Cancelled."));
1445
1570
  return;
1446
1571
  }
1447
1572
  }
1448
- console.log(chalk8.red(`
1573
+ console.log(chalk9.red(`
1449
1574
  Removing Antigravity integration...`));
1450
- console.log(chalk8.dim(ANTIGRAVITY_DIR));
1575
+ console.log(chalk9.dim(ANTIGRAVITY_DIR));
1451
1576
  const backupPath = configManager.antigravity?.backup_path ?? ANTIGRAVITY_BACKUP_DIR;
1452
1577
  for (const dir of AGENT_PROMPT_DIRS["antigravity" /* ANTIGRAVITY */]) {
1453
1578
  const target = path7.join(ANTIGRAVITY_DIR, dir);
1454
- if (fs7.existsSync(target) && fs7.lstatSync(target).isSymbolicLink()) {
1455
- fs7.unlinkSync(target);
1456
- console.log(chalk8.red(" removed symlink") + chalk8.dim(`: ${target}`));
1579
+ if (fs8.existsSync(target) && fs8.lstatSync(target).isSymbolicLink()) {
1580
+ fs8.unlinkSync(target);
1581
+ console.log(chalk9.red(" removed symlink") + chalk9.dim(`: ${target}`));
1457
1582
  }
1458
1583
  }
1459
- if (fs7.existsSync(backupPath)) {
1584
+ if (fs8.existsSync(backupPath)) {
1460
1585
  try {
1461
1586
  for (const dir of AGENT_PROMPT_DIRS["antigravity" /* ANTIGRAVITY */]) {
1462
1587
  const src = path7.join(backupPath, dir);
1463
1588
  const dest = path7.join(ANTIGRAVITY_DIR, dir);
1464
- if (!fs7.existsSync(src)) {
1589
+ if (!fs8.existsSync(src)) {
1465
1590
  continue;
1466
1591
  }
1467
- fs7.renameSync(src, dest);
1468
- console.log(chalk8.green(" restored") + chalk8.dim(`: ${dir}/`));
1592
+ fs8.renameSync(src, dest);
1593
+ console.log(chalk9.green(" restored") + chalk9.dim(`: ${dir}/`));
1469
1594
  }
1470
- fs7.rmdirSync(backupPath);
1595
+ fs8.rmdirSync(backupPath);
1471
1596
  } catch (ex) {
1472
- console.error(chalk8.red(` \u274C Failed to restore Antigravity backup: ${ex.message}`));
1597
+ console.error(chalk9.red(` \u274C Failed to restore Antigravity backup: ${ex.message}`));
1473
1598
  }
1474
1599
  }
1475
1600
  configManager.antigravity = null;
@@ -1478,9 +1603,9 @@ Removing Antigravity integration...`));
1478
1603
 
1479
1604
  // src/link/codex.ts
1480
1605
  import path8 from "path";
1481
- import fs8 from "fs";
1606
+ import fs9 from "fs";
1482
1607
  import os3 from "os";
1483
- import chalk9 from "chalk";
1608
+ import chalk10 from "chalk";
1484
1609
  import { confirm as confirm7 } from "@inquirer/prompts";
1485
1610
  import TOML from "smol-toml";
1486
1611
  var CODEX_AGENTS_DIR = path8.join(os3.homedir(), ".agents", "plugins");
@@ -1502,16 +1627,16 @@ var linkCodex = async () => {
1502
1627
  interface: { displayName: "Local Repository" },
1503
1628
  plugins: []
1504
1629
  };
1505
- if (fs8.existsSync(marketplacePath)) {
1506
- const raw = fs8.readFileSync(marketplacePath, "utf-8");
1630
+ if (fs9.existsSync(marketplacePath)) {
1631
+ const raw = fs9.readFileSync(marketplacePath, "utf-8");
1507
1632
  try {
1508
1633
  const parsed = JSON.parse(raw);
1509
1634
  if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
1510
1635
  marketplace = parsed;
1511
1636
  }
1512
1637
  } catch {
1513
- console.warn(chalk9.yellow(" \u26A0 Failed to parse marketplace.json \u2014 will not overwrite existing file"));
1514
- console.error(chalk9.red("\u274C Could not register plugin. Please add manually."));
1638
+ console.warn(chalk10.yellow(" \u26A0 Failed to parse marketplace.json \u2014 will not overwrite existing file"));
1639
+ console.error(chalk10.red("\u274C Could not register plugin. Please add manually."));
1515
1640
  return false;
1516
1641
  }
1517
1642
  }
@@ -1534,58 +1659,58 @@ var linkCodex = async () => {
1534
1659
  category: "Productivity"
1535
1660
  });
1536
1661
  let backupPath = null;
1537
- if (fs8.existsSync(marketplacePath)) {
1662
+ if (fs9.existsSync(marketplacePath)) {
1538
1663
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1539
1664
  backupPath = `${marketplacePath}.bak.${timestamp}`;
1540
1665
  try {
1541
- fs8.copyFileSync(marketplacePath, backupPath);
1666
+ fs9.copyFileSync(marketplacePath, backupPath);
1542
1667
  } catch (ex) {
1543
- console.warn(chalk9.yellow(` \u26A0 Could not create backup: ${ex.message}`));
1668
+ console.warn(chalk10.yellow(` \u26A0 Could not create backup: ${ex.message}`));
1544
1669
  backupPath = null;
1545
1670
  }
1546
1671
  }
1547
1672
  try {
1548
- fs8.mkdirSync(path8.dirname(marketplacePath), { recursive: true });
1549
- fs8.writeFileSync(marketplacePath, JSON.stringify(marketplace, null, 4), "utf-8");
1673
+ fs9.mkdirSync(path8.dirname(marketplacePath), { recursive: true });
1674
+ fs9.writeFileSync(marketplacePath, JSON.stringify(marketplace, null, 4), "utf-8");
1550
1675
  } catch (ex) {
1551
1676
  if (backupPath !== null) {
1552
1677
  try {
1553
- fs8.copyFileSync(backupPath, marketplacePath);
1554
- fs8.unlinkSync(backupPath);
1555
- console.warn(chalk9.yellow(" \u26A0 Write failed \u2014 rolled back to original."));
1678
+ fs9.copyFileSync(backupPath, marketplacePath);
1679
+ fs9.unlinkSync(backupPath);
1680
+ console.warn(chalk10.yellow(" \u26A0 Write failed \u2014 rolled back to original."));
1556
1681
  } catch {
1557
- console.error(chalk9.red(` \u274C Rollback failed. Backup preserved at: ${backupPath}`));
1682
+ console.error(chalk10.red(` \u274C Rollback failed. Backup preserved at: ${backupPath}`));
1558
1683
  }
1559
1684
  }
1560
1685
  throw ex;
1561
1686
  }
1562
1687
  if (backupPath !== null) {
1563
1688
  try {
1564
- fs8.unlinkSync(backupPath);
1689
+ fs9.unlinkSync(backupPath);
1565
1690
  } catch {
1566
1691
  }
1567
1692
  }
1568
1693
  console.log(`\u2705 Registered to marketplace.json`);
1569
- console.log(chalk9.dim(` ${marketplacePath}`));
1694
+ console.log(chalk10.dim(` ${marketplacePath}`));
1570
1695
  return true;
1571
1696
  } catch (ex) {
1572
- console.error(chalk9.red(`\u274C Failed to update marketplace.json: ${ex.message}`));
1697
+ console.error(chalk10.red(`\u274C Failed to update marketplace.json: ${ex.message}`));
1573
1698
  return false;
1574
1699
  }
1575
1700
  };
1576
1701
  const patchPluginCache = () => {
1577
1702
  const cachePath = path8.join(CODEX_CACHE_DIR, CODEX_MARKETPLACE_NAME, PLUGIN_NAME, "1.0.0");
1578
1703
  try {
1579
- fs8.mkdirSync(path8.dirname(cachePath), { recursive: true });
1580
- if (fs8.existsSync(cachePath)) {
1581
- fs8.rmSync(cachePath, { recursive: true, force: true });
1704
+ fs9.mkdirSync(path8.dirname(cachePath), { recursive: true });
1705
+ if (fs9.existsSync(cachePath)) {
1706
+ fs9.rmSync(cachePath, { recursive: true, force: true });
1582
1707
  }
1583
1708
  const symlinkType = process.platform === "win32" ? "junction" : "dir";
1584
- fs8.symlinkSync(repoPath, cachePath, symlinkType);
1709
+ fs9.symlinkSync(repoPath, cachePath, symlinkType);
1585
1710
  console.log(`\u2705 Patched plugin cache.`);
1586
- console.log(chalk9.dim(` ${cachePath}`) + chalk9.dim(" \u2192 ") + chalk9.dim(repoPath));
1711
+ console.log(chalk10.dim(` ${cachePath}`) + chalk10.dim(" \u2192 ") + chalk10.dim(repoPath));
1587
1712
  } catch (ex) {
1588
- console.warn(chalk9.yellow(` \u26A0 Could not patch plugin cache: ${ex.message}`));
1713
+ console.warn(chalk10.yellow(` \u26A0 Could not patch plugin cache: ${ex.message}`));
1589
1714
  }
1590
1715
  };
1591
1716
  const enableInConfig = () => {
@@ -1593,22 +1718,22 @@ var linkCodex = async () => {
1593
1718
  const pluginKey = `${PLUGIN_NAME}@${CODEX_MARKETPLACE_NAME}`;
1594
1719
  try {
1595
1720
  let config = {};
1596
- if (fs8.existsSync(configPath)) {
1597
- config = TOML.parse(fs8.readFileSync(configPath, "utf-8"));
1721
+ if (fs9.existsSync(configPath)) {
1722
+ config = TOML.parse(fs9.readFileSync(configPath, "utf-8"));
1598
1723
  }
1599
1724
  if (config.plugins == null) {
1600
1725
  config.plugins = {};
1601
1726
  }
1602
1727
  config.plugins[pluginKey] = { enabled: true };
1603
- fs8.mkdirSync(path8.dirname(configPath), { recursive: true });
1604
- fs8.writeFileSync(configPath, TOML.stringify(config), "utf-8");
1728
+ fs9.mkdirSync(path8.dirname(configPath), { recursive: true });
1729
+ fs9.writeFileSync(configPath, TOML.stringify(config), "utf-8");
1605
1730
  console.log(`\u2705 Enabled plugin in config.toml`);
1606
- console.log(chalk9.dim(` ${configPath}`));
1731
+ console.log(chalk10.dim(` ${configPath}`));
1607
1732
  } catch (ex) {
1608
- console.warn(chalk9.yellow(` \u26A0 Could not update config.toml: ${ex.message}`));
1733
+ console.warn(chalk10.yellow(` \u26A0 Could not update config.toml: ${ex.message}`));
1609
1734
  }
1610
1735
  };
1611
- console.log(chalk9.green(`
1736
+ console.log(chalk10.green(`
1612
1737
  Setting up Codex plugin...`));
1613
1738
  const marketplaceOk = registerToMarketplace();
1614
1739
  if (marketplaceOk === false) {
@@ -1626,55 +1751,55 @@ var unlinkCodex = async (force = false) => {
1626
1751
  default: false
1627
1752
  });
1628
1753
  if (!ok) {
1629
- console.log(chalk9.yellow("Cancelled."));
1754
+ console.log(chalk10.yellow("Cancelled."));
1630
1755
  return;
1631
1756
  }
1632
1757
  }
1633
- console.log(chalk9.red(`
1758
+ console.log(chalk10.red(`
1634
1759
  Removing Codex plugin...`));
1635
1760
  const marketplacePath = path8.join(CODEX_AGENTS_DIR, "marketplace.json");
1636
- if (fs8.existsSync(marketplacePath)) {
1761
+ if (fs9.existsSync(marketplacePath)) {
1637
1762
  try {
1638
1763
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1639
1764
  const backupPath = `${marketplacePath}.bak.${timestamp}`;
1640
- fs8.copyFileSync(marketplacePath, backupPath);
1641
- const marketplace = JSON.parse(fs8.readFileSync(marketplacePath, "utf-8"));
1765
+ fs9.copyFileSync(marketplacePath, backupPath);
1766
+ const marketplace = JSON.parse(fs9.readFileSync(marketplacePath, "utf-8"));
1642
1767
  if (Array.isArray(marketplace?.plugins)) {
1643
1768
  marketplace.plugins = marketplace.plugins.filter(
1644
1769
  (p) => p?.name !== PLUGIN_NAME
1645
1770
  );
1646
1771
  }
1647
1772
  try {
1648
- fs8.writeFileSync(marketplacePath, JSON.stringify(marketplace, null, 4), "utf-8");
1649
- fs8.unlinkSync(backupPath);
1650
- console.log(chalk9.red(" removed") + chalk9.dim(` ${PLUGIN_NAME} from: ${marketplacePath}`));
1773
+ fs9.writeFileSync(marketplacePath, JSON.stringify(marketplace, null, 4), "utf-8");
1774
+ fs9.unlinkSync(backupPath);
1775
+ console.log(chalk10.red(" removed") + chalk10.dim(` ${PLUGIN_NAME} from: ${marketplacePath}`));
1651
1776
  } catch (ex) {
1652
- fs8.copyFileSync(backupPath, marketplacePath);
1653
- fs8.unlinkSync(backupPath);
1654
- console.warn(chalk9.yellow(" \u26A0 Write failed \u2014 rolled back to original."));
1777
+ fs9.copyFileSync(backupPath, marketplacePath);
1778
+ fs9.unlinkSync(backupPath);
1779
+ console.warn(chalk10.yellow(" \u26A0 Write failed \u2014 rolled back to original."));
1655
1780
  }
1656
1781
  } catch (ex) {
1657
- console.error(chalk9.red(` \u274C Failed to clean up marketplace.json: ${ex.message}`));
1782
+ console.error(chalk10.red(` \u274C Failed to clean up marketplace.json: ${ex.message}`));
1658
1783
  }
1659
1784
  }
1660
1785
  const configPath = path8.join(os3.homedir(), ".codex", "config.toml");
1661
- if (fs8.existsSync(configPath)) {
1786
+ if (fs9.existsSync(configPath)) {
1662
1787
  try {
1663
- const config = TOML.parse(fs8.readFileSync(configPath, "utf-8"));
1788
+ const config = TOML.parse(fs9.readFileSync(configPath, "utf-8"));
1664
1789
  const pluginKey = `${PLUGIN_NAME}@${CODEX_MARKETPLACE_NAME}`;
1665
1790
  if (config.plugins?.[pluginKey] !== void 0) {
1666
1791
  delete config.plugins[pluginKey];
1667
- fs8.writeFileSync(configPath, TOML.stringify(config), "utf-8");
1668
- console.log(chalk9.red(" removed") + chalk9.dim(` ${pluginKey} from: ${configPath}`));
1792
+ fs9.writeFileSync(configPath, TOML.stringify(config), "utf-8");
1793
+ console.log(chalk10.red(" removed") + chalk10.dim(` ${pluginKey} from: ${configPath}`));
1669
1794
  }
1670
1795
  } catch (ex) {
1671
- console.error(chalk9.red(` \u274C Failed to clean up config.toml: ${ex.message}`));
1796
+ console.error(chalk10.red(` \u274C Failed to clean up config.toml: ${ex.message}`));
1672
1797
  }
1673
1798
  }
1674
1799
  const cacheMarketDir = path8.join(CODEX_CACHE_DIR, CODEX_MARKETPLACE_NAME);
1675
- if (fs8.existsSync(cacheMarketDir)) {
1676
- fs8.rmSync(cacheMarketDir, { recursive: true, force: true });
1677
- console.log(chalk9.red(" removed") + chalk9.dim(`: ${cacheMarketDir}`));
1800
+ if (fs9.existsSync(cacheMarketDir)) {
1801
+ fs9.rmSync(cacheMarketDir, { recursive: true, force: true });
1802
+ console.log(chalk10.red(" removed") + chalk10.dim(`: ${cacheMarketDir}`));
1678
1803
  }
1679
1804
  configManager.codex = null;
1680
1805
  configManager.save();
@@ -1682,8 +1807,8 @@ Removing Codex plugin...`));
1682
1807
 
1683
1808
  // src/link/cursor.ts
1684
1809
  import path9 from "path";
1685
- import fs9 from "fs";
1686
- import chalk10 from "chalk";
1810
+ import fs10 from "fs";
1811
+ import chalk11 from "chalk";
1687
1812
  import { confirm as confirm8 } from "@inquirer/prompts";
1688
1813
  import { pathExists as pathExists4 } from "fs-extra";
1689
1814
  var CURSOR_BACKUP_DIR = path9.join(CURSOR_DIR, "SET_PROMPT_BACKUP");
@@ -1692,35 +1817,35 @@ var linkCursor = async () => {
1692
1817
  if (repoPath == null) {
1693
1818
  return;
1694
1819
  }
1695
- console.log(chalk10.green(`
1820
+ console.log(chalk11.green(`
1696
1821
  Setting up Cursor integration...`));
1697
- console.log(chalk10.dim(CURSOR_DIR));
1822
+ console.log(chalk11.dim(CURSOR_DIR));
1698
1823
  const cursorDirs = AGENT_PROMPT_DIRS["cursor" /* CURSOR */];
1699
1824
  const dirsToBackup = [];
1700
1825
  for (const dir of cursorDirs) {
1701
1826
  const target = path9.join(CURSOR_DIR, dir);
1702
- if (fs9.existsSync(target) && fs9.lstatSync(target).isSymbolicLink() === false && fs9.readdirSync(target).length > 0) {
1827
+ if (fs10.existsSync(target) && fs10.lstatSync(target).isSymbolicLink() === false && fs10.readdirSync(target).length > 0) {
1703
1828
  dirsToBackup.push(dir);
1704
1829
  }
1705
1830
  }
1706
1831
  if (dirsToBackup.length > 0) {
1707
- console.log(chalk10.yellow(`
1832
+ console.log(chalk11.yellow(`
1708
1833
  \u26A0 The following existing directories will be replaced by symlinks:`));
1709
1834
  for (const dir of dirsToBackup) {
1710
- console.log(chalk10.dim(` - ${path9.join(CURSOR_DIR, dir)}`));
1835
+ console.log(chalk11.dim(` - ${path9.join(CURSOR_DIR, dir)}`));
1711
1836
  }
1712
- console.log(chalk10.yellow(` They will be backed up to: `) + chalk10.dim(CURSOR_BACKUP_DIR));
1837
+ console.log(chalk11.yellow(` They will be backed up to: `) + chalk11.dim(CURSOR_BACKUP_DIR));
1713
1838
  const ok = await confirm8({ message: "Back up existing directories?", default: true });
1714
1839
  if (!ok) {
1715
- console.log(chalk10.yellow("Skipped Cursor linking."));
1840
+ console.log(chalk11.yellow("Skipped Cursor linking."));
1716
1841
  return;
1717
1842
  }
1718
- fs9.mkdirSync(CURSOR_BACKUP_DIR, { recursive: true });
1843
+ fs10.mkdirSync(CURSOR_BACKUP_DIR, { recursive: true });
1719
1844
  for (const dir of dirsToBackup) {
1720
1845
  const src = path9.join(CURSOR_DIR, dir);
1721
1846
  const dest = path9.join(CURSOR_BACKUP_DIR, dir);
1722
- fs9.renameSync(src, dest);
1723
- console.log(chalk10.yellow(" backed up") + chalk10.dim(`: ${dir}/ \u2192 ${dest}`));
1847
+ fs10.renameSync(src, dest);
1848
+ console.log(chalk11.yellow(" backed up") + chalk11.dim(`: ${dir}/ \u2192 ${dest}`));
1724
1849
  }
1725
1850
  }
1726
1851
  try {
@@ -1731,33 +1856,33 @@ Setting up Cursor integration...`));
1731
1856
  if (await pathExists4(src) === false) {
1732
1857
  continue;
1733
1858
  }
1734
- if (fs9.existsSync(dest)) {
1735
- fs9.rmSync(dest, { recursive: true, force: true });
1859
+ if (fs10.existsSync(dest)) {
1860
+ fs10.rmSync(dest, { recursive: true, force: true });
1736
1861
  }
1737
1862
  const symlinkType = process.platform === "win32" ? "junction" : "dir";
1738
- fs9.symlinkSync(src, dest, symlinkType);
1863
+ fs10.symlinkSync(src, dest, symlinkType);
1739
1864
  linked.push({ dir, src });
1740
1865
  }
1741
1866
  for (const { dir, src } of linked) {
1742
- console.log(chalk10.dim(` \u251C\u2500\u2500 `) + chalk10.bold(`${dir}/`) + chalk10.dim(` \u2192 ${src}`) + chalk10.green(" \u2713"));
1867
+ console.log(chalk11.dim(` \u251C\u2500\u2500 `) + chalk11.bold(`${dir}/`) + chalk11.dim(` \u2192 ${src}`) + chalk11.green(" \u2713"));
1743
1868
  }
1744
1869
  const mcpSrc = path9.join(repoPath, ".mcp.json");
1745
1870
  const mcpDest = path9.join(CURSOR_DIR, "mcp.json");
1746
- if (fs9.existsSync(mcpSrc)) {
1747
- if (fs9.existsSync(mcpDest) && fs9.statSync(mcpDest).ino !== fs9.statSync(mcpSrc).ino) {
1871
+ if (fs10.existsSync(mcpSrc)) {
1872
+ if (fs10.existsSync(mcpDest) && fs10.statSync(mcpDest).ino !== fs10.statSync(mcpSrc).ino) {
1748
1873
  const mcpBackup = path9.join(CURSOR_BACKUP_DIR, "mcp.json");
1749
- fs9.mkdirSync(CURSOR_BACKUP_DIR, { recursive: true });
1750
- fs9.renameSync(mcpDest, mcpBackup);
1751
- console.log(chalk10.yellow(" backed up") + chalk10.dim(`: mcp.json \u2192 ${mcpBackup}`));
1874
+ fs10.mkdirSync(CURSOR_BACKUP_DIR, { recursive: true });
1875
+ fs10.renameSync(mcpDest, mcpBackup);
1876
+ console.log(chalk11.yellow(" backed up") + chalk11.dim(`: mcp.json \u2192 ${mcpBackup}`));
1752
1877
  }
1753
- if (fs9.existsSync(mcpDest)) {
1754
- fs9.unlinkSync(mcpDest);
1878
+ if (fs10.existsSync(mcpDest)) {
1879
+ fs10.unlinkSync(mcpDest);
1755
1880
  }
1756
- fs9.linkSync(mcpSrc, mcpDest);
1757
- console.log(chalk10.dim(` \u2514\u2500\u2500 `) + chalk10.bold("mcp.json") + chalk10.dim(` \u21D4 ${mcpSrc}`) + chalk10.green(" \u2713"));
1881
+ fs10.linkSync(mcpSrc, mcpDest);
1882
+ console.log(chalk11.dim(` \u2514\u2500\u2500 `) + chalk11.bold("mcp.json") + chalk11.dim(` \u21D4 ${mcpSrc}`) + chalk11.green(" \u2713"));
1758
1883
  }
1759
1884
  } catch (ex) {
1760
- console.error(chalk10.red(`\u274C Failed to set up Cursor: ${ex.message}`));
1885
+ console.error(chalk11.red(`\u274C Failed to set up Cursor: ${ex.message}`));
1761
1886
  return;
1762
1887
  }
1763
1888
  configManager.cursor = { path: CURSOR_DIR, backup_path: CURSOR_BACKUP_DIR };
@@ -1770,45 +1895,45 @@ var unlinkCursor = async (force = false) => {
1770
1895
  default: false
1771
1896
  });
1772
1897
  if (!ok) {
1773
- console.log(chalk10.yellow("Cancelled."));
1898
+ console.log(chalk11.yellow("Cancelled."));
1774
1899
  return;
1775
1900
  }
1776
1901
  }
1777
- console.log(chalk10.red(`
1902
+ console.log(chalk11.red(`
1778
1903
  Removing Cursor integration...`));
1779
- console.log(chalk10.dim(CURSOR_DIR));
1904
+ console.log(chalk11.dim(CURSOR_DIR));
1780
1905
  const backupPath = configManager.cursor?.backup_path ?? CURSOR_BACKUP_DIR;
1781
1906
  for (const dir of AGENT_PROMPT_DIRS["cursor" /* CURSOR */]) {
1782
1907
  const target = path9.join(CURSOR_DIR, dir);
1783
- if (fs9.existsSync(target) && fs9.lstatSync(target).isSymbolicLink()) {
1784
- fs9.unlinkSync(target);
1785
- console.log(chalk10.red(" removed symlink") + chalk10.dim(`: ${target}`));
1908
+ if (fs10.existsSync(target) && fs10.lstatSync(target).isSymbolicLink()) {
1909
+ fs10.unlinkSync(target);
1910
+ console.log(chalk11.red(" removed symlink") + chalk11.dim(`: ${target}`));
1786
1911
  }
1787
1912
  }
1788
1913
  const mcpDest = path9.join(CURSOR_DIR, "mcp.json");
1789
- if (fs9.existsSync(mcpDest)) {
1790
- fs9.unlinkSync(mcpDest);
1791
- console.log(chalk10.red(" removed") + chalk10.dim(`: ${mcpDest}`));
1914
+ if (fs10.existsSync(mcpDest)) {
1915
+ fs10.unlinkSync(mcpDest);
1916
+ console.log(chalk11.red(" removed") + chalk11.dim(`: ${mcpDest}`));
1792
1917
  }
1793
- if (fs9.existsSync(backupPath)) {
1918
+ if (fs10.existsSync(backupPath)) {
1794
1919
  try {
1795
1920
  for (const dir of AGENT_PROMPT_DIRS["cursor" /* CURSOR */]) {
1796
1921
  const src = path9.join(backupPath, dir);
1797
1922
  const dest = path9.join(CURSOR_DIR, dir);
1798
- if (!fs9.existsSync(src)) {
1923
+ if (!fs10.existsSync(src)) {
1799
1924
  continue;
1800
1925
  }
1801
- fs9.renameSync(src, dest);
1802
- console.log(chalk10.green(" restored") + chalk10.dim(`: ${dir}/`));
1926
+ fs10.renameSync(src, dest);
1927
+ console.log(chalk11.green(" restored") + chalk11.dim(`: ${dir}/`));
1803
1928
  }
1804
1929
  const mcpBackup = path9.join(backupPath, "mcp.json");
1805
- if (fs9.existsSync(mcpBackup)) {
1806
- fs9.renameSync(mcpBackup, mcpDest);
1807
- console.log(chalk10.green(" restored") + chalk10.dim(`: mcp.json`));
1930
+ if (fs10.existsSync(mcpBackup)) {
1931
+ fs10.renameSync(mcpBackup, mcpDest);
1932
+ console.log(chalk11.green(" restored") + chalk11.dim(`: mcp.json`));
1808
1933
  }
1809
- fs9.rmSync(backupPath, { recursive: true, force: true });
1934
+ fs10.rmSync(backupPath, { recursive: true, force: true });
1810
1935
  } catch (ex) {
1811
- console.error(chalk10.red(` \u274C Failed to restore Cursor backup: ${ex.message}`));
1936
+ console.error(chalk11.red(` \u274C Failed to restore Cursor backup: ${ex.message}`));
1812
1937
  }
1813
1938
  }
1814
1939
  configManager.cursor = null;
@@ -1836,7 +1961,7 @@ var linkCommand = async (tool) => {
1836
1961
  if (tool != null) {
1837
1962
  const known = ALL_AGENTS.some((a) => a.value === tool);
1838
1963
  if (!known) {
1839
- console.log(chalk11.red(`Unknown vendor: ${tool}`));
1964
+ console.log(chalk12.red(`Unknown vendor: ${tool}`));
1840
1965
  process.exit(1);
1841
1966
  }
1842
1967
  await LINK_MAP[tool]();
@@ -1853,7 +1978,7 @@ var linkCommand = async (tool) => {
1853
1978
  const selected = await checkbox({
1854
1979
  message: "Which AI agent do you want to integrate?",
1855
1980
  choices: ALL_AGENTS.map((a) => ({
1856
- name: prevLinked[a.value] ? `${a.name} ${chalk11.dim("(applied)")}` : a.name,
1981
+ name: prevLinked[a.value] ? `${a.name} ${chalk12.dim("(applied)")}` : a.name,
1857
1982
  value: a.value,
1858
1983
  checked: prevLinked[a.value]
1859
1984
  }))
@@ -1862,10 +1987,10 @@ var linkCommand = async (tool) => {
1862
1987
  const toUnlink = ALL_AGENTS.filter((a) => prevLinked[a.value] && !selected.includes(a.value));
1863
1988
  console.log();
1864
1989
  if (toLink.length > 0) {
1865
- console.log(chalk11.green(" Link ") + chalk11.dim("\u2192 ") + toLink.map((a) => chalk11.bold(a.name)).join(chalk11.dim(", ")));
1990
+ console.log(chalk12.green(" Link ") + chalk12.dim("\u2192 ") + toLink.map((a) => chalk12.bold(a.name)).join(chalk12.dim(", ")));
1866
1991
  }
1867
1992
  if (toUnlink.length > 0) {
1868
- console.log(chalk11.red(" Unlink ") + chalk11.dim("\u2192 ") + toUnlink.map((a) => chalk11.bold(a.name)).join(chalk11.dim(", ")));
1993
+ console.log(chalk12.red(" Unlink ") + chalk12.dim("\u2192 ") + toUnlink.map((a) => chalk12.bold(a.name)).join(chalk12.dim(", ")));
1869
1994
  }
1870
1995
  console.log();
1871
1996
  if (toLink.length === 0 && toUnlink.length === 0) {
@@ -1884,14 +2009,14 @@ var linkCommand = async (tool) => {
1884
2009
  };
1885
2010
 
1886
2011
  // src/commands/uninstall-command.ts
1887
- import fs10 from "fs";
1888
- import chalk12 from "chalk";
2012
+ import fs11 from "fs";
2013
+ import chalk13 from "chalk";
1889
2014
  import { confirm as confirm9 } from "@inquirer/prompts";
1890
2015
  var uninstallCommand = async () => {
1891
2016
  const targets = [
1892
- { label: `Config file ${chalk12.dim(CONFIG_PATH)}`, path: CONFIG_PATH },
1893
- { label: `Home dir ${chalk12.dim(HOME_DIR)}`, path: HOME_DIR }
1894
- ].filter((t) => fs10.existsSync(t.path));
2017
+ { label: `Config file ${chalk13.dim(CONFIG_PATH)}`, path: CONFIG_PATH },
2018
+ { label: `Home dir ${chalk13.dim(HOME_DIR)}`, path: HOME_DIR }
2019
+ ].filter((t) => fs11.existsSync(t.path));
1895
2020
  const hasClaudeCode = configManager.isClaudeCodeEnabled();
1896
2021
  const hasRooCode = configManager.isRooCodeEnabled();
1897
2022
  const hasOpenclaw = configManager.isOpenclawEnabled();
@@ -1899,32 +2024,32 @@ var uninstallCommand = async () => {
1899
2024
  const hasCodex = configManager.isCodexEnabled();
1900
2025
  const hasCursor = configManager.isCursorEnabled();
1901
2026
  if (targets.length === 0 && !hasClaudeCode && !hasRooCode && !hasOpenclaw && !hasAntigravity && !hasCodex && !hasCursor) {
1902
- console.log(chalk12.yellow("Nothing to remove."));
2027
+ console.log(chalk13.yellow("Nothing to remove."));
1903
2028
  return;
1904
2029
  }
1905
- console.log(chalk12.red("\nThe following will be removed:"));
2030
+ console.log(chalk13.red("\nThe following will be removed:"));
1906
2031
  targets.forEach((t) => console.log(` ${t.label}`));
1907
2032
  if (hasClaudeCode) {
1908
- console.log(` Claude Code plugin dir ${chalk12.dim(CLAUDE_CODE_DIR)}`);
2033
+ console.log(` Claude Code plugin dir ${chalk13.dim(CLAUDE_CODE_DIR)}`);
1909
2034
  }
1910
2035
  if (hasRooCode) {
1911
- console.log(` RooCode symlinks ${chalk12.dim("(backup will be restored)")}`);
2036
+ console.log(` RooCode symlinks ${chalk13.dim("(backup will be restored)")}`);
1912
2037
  }
1913
2038
  if (hasOpenclaw) {
1914
- console.log(` OpenClaw symlinks ${chalk12.dim("(backup will be restored)")}`);
2039
+ console.log(` OpenClaw symlinks ${chalk13.dim("(backup will be restored)")}`);
1915
2040
  }
1916
2041
  if (hasAntigravity) {
1917
- console.log(` Antigravity symlinks ${chalk12.dim("(backup will be restored)")}`);
2042
+ console.log(` Antigravity symlinks ${chalk13.dim("(backup will be restored)")}`);
1918
2043
  }
1919
2044
  if (hasCodex) {
1920
- console.log(` Codex symlinks ${chalk12.dim("(backup will be restored)")}`);
2045
+ console.log(` Codex symlinks ${chalk13.dim("(backup will be restored)")}`);
1921
2046
  }
1922
2047
  if (hasCursor) {
1923
- console.log(` Cursor plugin dir ${chalk12.dim("(symlink will be removed)")}`);
2048
+ console.log(` Cursor plugin dir ${chalk13.dim("(symlink will be removed)")}`);
1924
2049
  }
1925
2050
  const ok = await confirm9({ message: "Proceed?", default: false });
1926
2051
  if (!ok) {
1927
- console.log(chalk12.yellow("Cancelled."));
2052
+ console.log(chalk13.yellow("Cancelled."));
1928
2053
  return;
1929
2054
  }
1930
2055
  if (hasClaudeCode) {
@@ -1946,26 +2071,26 @@ var uninstallCommand = async () => {
1946
2071
  await unlinkCursor(true);
1947
2072
  }
1948
2073
  for (const t of targets) {
1949
- fs10.rmSync(t.path, { recursive: true, force: true });
1950
- console.log(chalk12.dim(` removed: ${t.path}`));
2074
+ fs11.rmSync(t.path, { recursive: true, force: true });
2075
+ console.log(chalk13.dim(` removed: ${t.path}`));
1951
2076
  }
1952
- console.log(chalk12.green("\nUninstalled."));
2077
+ console.log(chalk13.green("\nUninstalled."));
1953
2078
  };
1954
2079
 
1955
2080
  // src/commands/status-command.ts
1956
- import chalk13 from "chalk";
2081
+ import chalk14 from "chalk";
1957
2082
  var statusCommand = () => {
1958
2083
  if (configManager.repo_path == null) {
1959
- console.log(chalk13.yellow("\u274C No repo installed."));
1960
- console.log(chalk13.dim(` Run: set-prompt install <repo-url>`));
2084
+ console.log(chalk14.yellow("\u274C No repo installed."));
2085
+ console.log(chalk14.dim(` Run: set-prompt install <repo-url>`));
1961
2086
  return;
1962
2087
  }
1963
- console.log(chalk13.bold("\nRepo"));
1964
- console.log(`${TAB}path ${chalk13.cyan(configManager.repo_path)}`);
2088
+ console.log(chalk14.bold("\nRepo"));
2089
+ console.log(`${TAB}path ${chalk14.cyan(configManager.repo_path)}`);
1965
2090
  if (configManager.remote_url != null) {
1966
- console.log(`${TAB}remote ${chalk13.dim(configManager.remote_url)}`);
2091
+ console.log(`${TAB}remote ${chalk14.dim(configManager.remote_url)}`);
1967
2092
  }
1968
- console.log(chalk13.bold("\nLinked agents"));
2093
+ console.log(chalk14.bold("\nLinked agents"));
1969
2094
  for (const agent of ALL_AGENTS) {
1970
2095
  let linked = false;
1971
2096
  let agentPath = null;
@@ -1985,78 +2110,363 @@ var statusCommand = () => {
1985
2110
  linked = configManager.isAntigravityEnabled();
1986
2111
  agentPath = configManager.antigravity?.path;
1987
2112
  }
1988
- const label = linked ? chalk13.green("linked") : chalk13.dim("not linked");
1989
- const pathStr = linked && agentPath ? chalk13.dim(` \u2192 ${agentPath}`) : "";
2113
+ const label = linked ? chalk14.green("linked") : chalk14.dim("not linked");
2114
+ const pathStr = linked && agentPath ? chalk14.dim(` \u2192 ${agentPath}`) : "";
1990
2115
  console.log(`${TAB}${agent.name.padEnd(12)} ${label}${pathStr}`);
1991
2116
  }
1992
2117
  console.log("");
1993
2118
  };
1994
2119
 
1995
- // src/commands/update-command.ts
1996
- import { spawnSync as spawnSync2 } from "child_process";
1997
- import chalk14 from "chalk";
1998
- var updateCommand = () => {
2120
+ // src/commands/repo/pull-command.ts
2121
+ import { spawnSync as spawnSync4 } from "child_process";
2122
+ import chalk15 from "chalk";
2123
+ var repoPullCommand = () => {
1999
2124
  const repoPath = configManager.repo_path;
2000
2125
  if (repoPath == null) {
2001
- console.error(chalk14.red("\u274C No repo installed."));
2002
- console.log(chalk14.yellow("Run: set-prompt install <git-url>"));
2126
+ console.error(chalk15.red("\u274C No repo installed."));
2127
+ console.log(chalk15.yellow("Run: set-prompt install <git-url>"));
2003
2128
  return;
2004
2129
  }
2005
2130
  if (configManager.remote_url == null) {
2006
- console.error(chalk14.red("\u274C No remote URL registered. Cannot update."));
2131
+ console.error(chalk15.red("\u274C No remote URL registered. Cannot pull."));
2007
2132
  return;
2008
2133
  }
2009
- console.log(chalk14.green("\nUpdating prompt repo..."));
2010
- console.log(chalk14.dim(repoPath));
2011
- const fetch = spawnSync2("git", ["fetch"], { cwd: repoPath, stdio: "inherit" });
2134
+ console.log(chalk15.green("\nPulling prompt repo..."));
2135
+ console.log(chalk15.dim(repoPath));
2136
+ const fetch = spawnSync4("git", ["fetch"], { cwd: repoPath, stdio: "inherit" });
2012
2137
  if (fetch.status !== 0) {
2013
- console.error(chalk14.red("\u274C git fetch failed."));
2138
+ console.error(chalk15.red("\u274C git fetch failed."));
2014
2139
  return;
2015
2140
  }
2016
- const pull = spawnSync2("git", ["pull"], { cwd: repoPath, stdio: "inherit" });
2141
+ const pull = spawnSync4("git", ["pull"], { cwd: repoPath, stdio: "inherit" });
2017
2142
  if (pull.status !== 0) {
2018
- console.error(chalk14.red("\u274C git pull failed."));
2143
+ console.error(chalk15.red("\u274C git pull failed."));
2144
+ return;
2145
+ }
2146
+ console.log(chalk15.green("\u2705 Repo pulled."));
2147
+ };
2148
+
2149
+ // src/commands/repo/commit-command.ts
2150
+ import { spawnSync as spawnSync5 } from "child_process";
2151
+ import chalk16 from "chalk";
2152
+ var repoCommitCommand = (options = {}) => {
2153
+ const repoPath = configManager.repo_path;
2154
+ if (repoPath == null) {
2155
+ console.error(chalk16.red("\u274C No repo installed."));
2156
+ console.log(chalk16.yellow("Run: set-prompt install <git-url>"));
2157
+ return false;
2158
+ }
2159
+ let message = options.message;
2160
+ if (message == null || message.trim() === "") {
2161
+ const generated = generateCommitMessage(repoPath);
2162
+ if (generated == null) {
2163
+ console.error(chalk16.red("\u274C Nothing to commit \u2014 working tree is clean."));
2164
+ return false;
2165
+ }
2166
+ message = generated;
2167
+ const subject = message.split("\n")[0];
2168
+ console.log(chalk16.dim(` (auto-generated: ${subject})`));
2169
+ }
2170
+ console.log(chalk16.green("\nCommitting prompt repo changes..."));
2171
+ console.log(chalk16.dim(repoPath));
2172
+ const add = spawnSync5("git", ["add", "-A"], { cwd: repoPath, stdio: "inherit" });
2173
+ if (add.status !== 0) {
2174
+ console.error(chalk16.red("\u274C git add failed."));
2175
+ return false;
2176
+ }
2177
+ const commit = spawnSync5("git", ["commit", "-m", message], { cwd: repoPath, stdio: "inherit" });
2178
+ if (commit.status !== 0) {
2179
+ console.error(chalk16.red("\u274C git commit failed \u2014 nothing to commit, or commit rejected."));
2180
+ return false;
2181
+ }
2182
+ console.log(chalk16.green("\u2705 Committed."));
2183
+ return true;
2184
+ };
2185
+
2186
+ // src/commands/repo/push-command.ts
2187
+ import { spawnSync as spawnSync6 } from "child_process";
2188
+ import chalk17 from "chalk";
2189
+ var repoPushCommand = () => {
2190
+ const repoPath = configManager.repo_path;
2191
+ if (repoPath == null) {
2192
+ console.error(chalk17.red("\u274C No repo installed."));
2193
+ console.log(chalk17.yellow("Run: set-prompt install <git-url>"));
2194
+ return false;
2195
+ }
2196
+ if (configManager.remote_url == null) {
2197
+ console.error(chalk17.red("\u274C No remote URL registered. Cannot push."));
2198
+ return false;
2199
+ }
2200
+ console.log(chalk17.green("\nPushing prompt repo..."));
2201
+ console.log(chalk17.dim(repoPath));
2202
+ const push = spawnSync6("git", ["push"], { cwd: repoPath, stdio: "inherit" });
2203
+ if (push.status !== 0) {
2204
+ console.error(chalk17.red("\u274C git push failed."));
2205
+ return false;
2206
+ }
2207
+ console.log(chalk17.green("\u2705 Pushed."));
2208
+ return true;
2209
+ };
2210
+
2211
+ // src/commands/repo/save-command.ts
2212
+ var repoSaveCommand = (options = {}) => {
2213
+ const committed = repoCommitCommand({ message: options.message });
2214
+ if (committed === false) return;
2215
+ repoPushCommand();
2216
+ };
2217
+
2218
+ // src/commands/repo/status-command.ts
2219
+ import { spawnSync as spawnSync7 } from "child_process";
2220
+ import chalk18 from "chalk";
2221
+ var parseBranchLine = (line) => {
2222
+ const body = line.replace(/^## /, "");
2223
+ if (body.startsWith("HEAD ") || body.includes("(no branch)")) {
2224
+ return { branch: null, upstream: null, ahead: 0, behind: 0 };
2225
+ }
2226
+ const [refPart, bracketPart] = body.split(/\s+(?=\[)/);
2227
+ const [branch, upstream] = refPart.split("...");
2228
+ let ahead = 0;
2229
+ let behind = 0;
2230
+ if (bracketPart != null) {
2231
+ const inside = bracketPart.replace(/[\[\]]/g, "");
2232
+ for (const piece of inside.split(",").map((s) => s.trim())) {
2233
+ const m = piece.match(/^(ahead|behind) (\d+)$/);
2234
+ if (m == null) continue;
2235
+ if (m[1] === "ahead") ahead = Number(m[2]);
2236
+ if (m[1] === "behind") behind = Number(m[2]);
2237
+ }
2238
+ }
2239
+ return { branch: branch ?? null, upstream: upstream ?? null, ahead, behind };
2240
+ };
2241
+ var parseFileLine = (line) => {
2242
+ if (line.length < 4) return null;
2243
+ const status = line.slice(0, 2);
2244
+ let name = line.slice(3);
2245
+ const arrowIdx = name.indexOf(" -> ");
2246
+ if (arrowIdx >= 0) name = name.slice(arrowIdx + 4);
2247
+ if (name.startsWith('"') && name.endsWith('"')) name = name.slice(1, -1);
2248
+ if (status.includes("?")) return { label: "untracked", color: chalk18.gray, path: name };
2249
+ if (status.includes("D")) return { label: "deleted", color: chalk18.red, path: name };
2250
+ if (status.includes("R")) return { label: "renamed", color: chalk18.cyan, path: name };
2251
+ if (status.includes("A")) return { label: "added", color: chalk18.green, path: name };
2252
+ if (status.includes("M")) return { label: "modified", color: chalk18.yellow, path: name };
2253
+ return null;
2254
+ };
2255
+ var formatUpstream = (info) => {
2256
+ if (info.branch == null) return chalk18.red("(detached HEAD)");
2257
+ if (info.upstream == null) return `${info.branch} ${chalk18.yellow("(no upstream)")}`;
2258
+ const segs = [];
2259
+ if (info.ahead > 0) segs.push(chalk18.green(`ahead ${info.ahead}`));
2260
+ if (info.behind > 0) segs.push(chalk18.red(`behind ${info.behind}`));
2261
+ const trailing = segs.length > 0 ? ` (${segs.join(", ")})` : chalk18.dim(" (up to date)");
2262
+ return `${info.branch} ${chalk18.dim("\u2192")} ${info.upstream}${trailing}`;
2263
+ };
2264
+ var repoStatusCommand = () => {
2265
+ const repoPath = configManager.repo_path;
2266
+ if (repoPath == null) {
2267
+ console.error(chalk18.red("\u274C No repo installed."));
2268
+ console.log(chalk18.yellow("Run: set-prompt install <git-url>"));
2269
+ return;
2270
+ }
2271
+ const result = spawnSync7("git", ["status", "--porcelain=v1", "--branch", "--untracked-files=all"], {
2272
+ cwd: repoPath,
2273
+ encoding: "utf8"
2274
+ });
2275
+ if (result.status !== 0) {
2276
+ console.error(chalk18.red("\u274C git status failed."));
2277
+ if (result.stderr) console.error(chalk18.dim(result.stderr));
2278
+ return;
2279
+ }
2280
+ const lines = result.stdout.split("\n").filter((l) => l.length > 0);
2281
+ const branchLine = lines[0] ?? "## (unknown)";
2282
+ const fileLines = lines.slice(1);
2283
+ const branchInfo = parseBranchLine(branchLine);
2284
+ const changes = fileLines.map(parseFileLine).filter((f) => f !== null);
2285
+ console.log(`${chalk18.cyan("\u{1F4C2}")} ${chalk18.dim(repoPath)}`);
2286
+ console.log(`${chalk18.cyan("\u{1F33F}")} ${formatUpstream(branchInfo)}`);
2287
+ console.log("");
2288
+ if (changes.length === 0) {
2289
+ console.log(chalk18.green("\u2705 Working tree clean"));
2019
2290
  return;
2020
2291
  }
2021
- console.log(chalk14.green("\u2705 Repo updated."));
2292
+ console.log(chalk18.bold(`\u{1F4DD} Changes (${changes.length}):`));
2293
+ const labelWidth = Math.max(...changes.map((c) => c.label.length));
2294
+ for (const c of changes) {
2295
+ const label = c.color(c.label.padEnd(labelWidth));
2296
+ console.log(` ${label} ${c.path}`);
2297
+ }
2298
+ };
2299
+
2300
+ // src/commands/repo/path-command.ts
2301
+ import chalk19 from "chalk";
2302
+ var repoPathCommand = () => {
2303
+ const repoPath = configManager.repo_path;
2304
+ if (repoPath == null) {
2305
+ console.error(chalk19.red("\u274C No repo installed."));
2306
+ console.error(chalk19.yellow("Run: set-prompt install <git-url>"));
2307
+ process.exitCode = 1;
2308
+ return;
2309
+ }
2310
+ console.log(repoPath);
2311
+ };
2312
+
2313
+ // src/commands/repo/open-command.ts
2314
+ import { spawn } from "child_process";
2315
+ import path10 from "path";
2316
+ import chalk20 from "chalk";
2317
+ var resolveVscodeTarget = (repoPath) => {
2318
+ if (isOnPath("code") === false) return null;
2319
+ return { bin: "code", args: [repoPath] };
2320
+ };
2321
+ var resolveSourcetreeTarget = (repoPath) => {
2322
+ if (isOnPath("stree")) {
2323
+ return { bin: "stree", args: [repoPath] };
2324
+ }
2325
+ if (process.platform === "win32") {
2326
+ const exe = firstExistingPath([
2327
+ process.env.LOCALAPPDATA && path10.join(process.env.LOCALAPPDATA, "SourceTree", "SourceTree.exe"),
2328
+ process.env["ProgramFiles(x86)"] && path10.join(process.env["ProgramFiles(x86)"], "Atlassian", "SourceTree", "SourceTree.exe"),
2329
+ process.env.ProgramFiles && path10.join(process.env.ProgramFiles, "Atlassian", "SourceTree", "SourceTree.exe")
2330
+ ]);
2331
+ if (exe != null) return { bin: exe, args: ["-f", repoPath] };
2332
+ }
2333
+ return null;
2334
+ };
2335
+ var VSCODE_INSTALL_HINT = `Install VSCode CLI: View \u2192 Command Palette \u2192 "Shell Command: Install 'code' command"`;
2336
+ var sourcetreeInstallHint = () => {
2337
+ if (process.platform === "darwin") {
2338
+ return 'Install Sourcetree, then: Sourcetree menu bar \u2192 "Install Command Line Tools"';
2339
+ }
2340
+ if (process.platform === "win32") {
2341
+ return "Install Sourcetree from https://sourcetreeapp.com/ \u2014 this CLI auto-detects it at %LOCALAPPDATA%\\SourceTree";
2342
+ }
2343
+ return "Sourcetree is not available on Linux \u2014 try a native Git GUI instead";
2344
+ };
2345
+ var runLaunch = (label, target) => {
2346
+ console.log(chalk20.green(`Opening in ${label}: ${chalk20.dim(target.args[target.args.length - 1])}`));
2347
+ const child = spawn(target.bin, target.args, { stdio: "ignore", detached: true, shell: true });
2348
+ child.unref();
2349
+ };
2350
+ var repoOpenCommand = (options = {}) => {
2351
+ const repoPath = configManager.repo_path;
2352
+ if (repoPath == null) {
2353
+ console.error(chalk20.red("\u274C No repo installed."));
2354
+ console.log(chalk20.yellow("Run: set-prompt install <git-url>"));
2355
+ return;
2356
+ }
2357
+ if (options.code === true) {
2358
+ const target = resolveVscodeTarget(repoPath);
2359
+ if (target == null) {
2360
+ console.error(chalk20.red("\u274C VSCode CLI (`code`) not found on PATH."));
2361
+ console.log(chalk20.dim(` ${VSCODE_INSTALL_HINT}`));
2362
+ return;
2363
+ }
2364
+ runLaunch("VSCode", target);
2365
+ return;
2366
+ }
2367
+ if (options.stree === true) {
2368
+ const target = resolveSourcetreeTarget(repoPath);
2369
+ if (target == null) {
2370
+ console.error(chalk20.red("\u274C Sourcetree not found."));
2371
+ console.log(chalk20.dim(` ${sourcetreeInstallHint()}`));
2372
+ return;
2373
+ }
2374
+ runLaunch("Sourcetree", target);
2375
+ return;
2376
+ }
2377
+ const platform = process.platform;
2378
+ const opener = platform === "win32" ? "explorer" : platform === "darwin" ? "open" : "xdg-open";
2379
+ console.log(chalk20.green(`Opening: ${chalk20.dim(repoPath)}`));
2380
+ const child = spawn(opener, [repoPath], { stdio: "ignore", detached: true });
2381
+ child.on("error", (ex) => {
2382
+ console.error(chalk20.red(`\u274C Failed to open: ${ex.message}`));
2383
+ });
2384
+ child.unref();
2022
2385
  };
2023
2386
 
2024
2387
  // src/index.ts
2025
2388
  process.on("SIGINT", () => {
2026
- console.log(chalk15.yellow("\nCancelled."));
2389
+ console.log(chalk21.yellow("\nCancelled."));
2027
2390
  process.exit(0);
2028
2391
  });
2029
2392
  process.on("unhandledRejection", (reason) => {
2030
2393
  if (reason instanceof Error && reason.name === "ExitPromptError") {
2031
- console.log(chalk15.yellow("\nCancelled."));
2394
+ console.log(chalk21.yellow("\nCancelled."));
2032
2395
  process.exit(0);
2033
2396
  }
2034
2397
  throw reason;
2035
2398
  });
2036
- var __dirname = path10.dirname(fileURLToPath(import.meta.url));
2037
- var pkg = JSON.parse(fs11.readFileSync(path10.join(__dirname, "../package.json"), "utf-8"));
2399
+ var __dirname = path11.dirname(fileURLToPath(import.meta.url));
2400
+ var pkg = JSON.parse(fs12.readFileSync(path11.join(__dirname, "../package.json"), "utf-8"));
2038
2401
  configManager.init();
2039
2402
  var program = new Command();
2040
- var banner = chalk15.cyan(figlet.textSync("Set-Prompt", { horizontalLayout: "full" }));
2041
- program.name("set-prompt").description(pkg.description).version(pkg.version).addHelpText("beforeAll", banner + "\n").action(() => {
2042
- program.help();
2043
- });
2044
- program.command("install").description(`\u{1F4E6} Clone a ${chalk15.cyan("git repo")} into ${chalk15.dim("~/.set-prompt/repo/")} and register it as your prompt source`).argument("<url>", "remote git URL").action(async (source) => {
2403
+ var banner = chalk21.cyan(figlet.textSync("Set-Prompt", { horizontalLayout: "full" }));
2404
+ program.name("set-prompt").description(pkg.description).version(pkg.version).addHelpText("beforeAll", ({ command }) => command === program ? banner + "\n" : "");
2405
+ program.command("install").description(`\u{1F4E6} Clone a ${chalk21.cyan("git repo")} into ${chalk21.dim("~/.set-prompt/repo/")} and register it as your prompt source`).argument("<url>", "remote git URL").action(async (source) => {
2045
2406
  await installCommand(source);
2046
2407
  });
2047
- program.command("link").description(`\u{1F517} Symlink your prompt repo into an ${chalk15.cyan("AI agent")} plugin dir ${chalk15.dim("(claudecode | roocode | openclaw | codex | antigravity)")}`).argument("[agent]", `target agent ${chalk15.dim("(omit for interactive selection)")}`).action(async (agent) => {
2408
+ program.command("link").description(`\u{1F517} Symlink your prompt repo into an ${chalk21.cyan("AI agent")} plugin dir ${chalk21.dim("(claudecode | roocode | openclaw | codex | antigravity)")}`).argument("[agent]", `target agent ${chalk21.dim("(omit for interactive selection)")}`).action(async (agent) => {
2048
2409
  await linkCommand(agent);
2049
2410
  });
2050
- program.command("scaffold").description(`\u{1F6E0}\uFE0F Verify and create ${chalk15.cyan("required directories")} in a prompt repo ${chalk15.dim("(-f to force overwrite)")}`).argument("[path]", `path to repo ${chalk15.dim("(defaults to installed source)")}`).action(async (localPath) => {
2411
+ program.command("scaffold").description(`\u{1F6E0}\uFE0F Verify and create ${chalk21.cyan("required directories")} in a prompt repo ${chalk21.dim("(-f to force overwrite)")}`).argument("[path]", `path to repo ${chalk21.dim("(defaults to installed source)")}`).action(async (localPath) => {
2051
2412
  await scaffoldCommand(localPath);
2052
2413
  });
2053
- program.command("status").description(`\u{1F4CB} Show registered ${chalk15.cyan("repo")} and which ${chalk15.cyan("agents")} are linked`).action(() => {
2414
+ program.command("status").description(`\u{1F4CB} Show registered ${chalk21.cyan("repo")} and which ${chalk21.cyan("agents")} are linked`).action(() => {
2054
2415
  statusCommand();
2055
2416
  });
2056
- program.command("update").description(`\u{1F504} Fetch and pull the latest changes from the ${chalk15.cyan("remote repo")}`).action(() => {
2057
- updateCommand();
2417
+ var repo = program.command("repo").description(`\u{1F5C2}\uFE0F Manage the installed prompt repo ${chalk21.dim("(status | pull | commit | push | save | path | open)")}`);
2418
+ repo.command("status").description(`\u{1F4CB} Show VCS status of the repo ${chalk21.dim("(branch, ahead/behind, changed files)")}`).addHelpText("after", `
2419
+ Example output:
2420
+ \u{1F4C2} ~/.set-prompt/repo
2421
+ \u{1F33F} main \u2192 origin/main (ahead 2)
2422
+
2423
+ \u{1F4DD} Changes (2):
2424
+ modified skills/foo.md
2425
+ untracked draft.md
2426
+ `).action(() => {
2427
+ repoStatusCommand();
2428
+ });
2429
+ repo.command("pull").description(`\u{1F504} Fetch and pull the latest changes from the ${chalk21.cyan("remote repo")}`).action(() => {
2430
+ repoPullCommand();
2431
+ });
2432
+ repo.command("commit").description(`\u{1F4DD} Stage all changes and commit ${chalk21.dim("(auto-generates message if -m omitted; does not push)")}`).option("-m, --message <msg>", "commit message (auto-generated from changed files if omitted)").addHelpText("after", `
2433
+ Examples:
2434
+ $ sppt repo commit -m "edit dbml skill"
2435
+ $ sppt repo commit ${chalk21.dim('# auto-generates "update N files" + file list')}
2436
+ `).action((opts) => {
2437
+ repoCommitCommand({ message: opts.message });
2438
+ });
2439
+ repo.command("push").description(`\u2B06\uFE0F Push local commits to the remote`).action(() => {
2440
+ repoPushCommand();
2441
+ });
2442
+ repo.command("save").description(`\u{1F4BE} Stage + commit + push in one step ${chalk21.dim("(macro for commit \u2192 push; auto-generates message if -m omitted)")}`).option("-m, --message <msg>", "commit message (auto-generated from changed files if omitted)").addHelpText("after", `
2443
+ Examples:
2444
+ $ sppt repo save -m "edit dbml skill"
2445
+ $ sppt repo save ${chalk21.dim("# auto-generates message and pushes")}
2446
+
2447
+ Equivalent to: sppt repo commit && sppt repo push
2448
+ `).action((opts) => {
2449
+ repoSaveCommand({ message: opts.message });
2450
+ });
2451
+ repo.command("path").description(`\u{1F4CD} Print the repo path to stdout ${chalk21.dim("(e.g. cd $(sppt repo path))")}`).addHelpText("after", `
2452
+ Examples:
2453
+ $ sppt repo path
2454
+ ${chalk21.dim("/Users/me/.set-prompt/repo")}
2455
+
2456
+ $ cd "$(sppt repo path)" ${chalk21.dim("# jump into the repo")}
2457
+ $ code "$(sppt repo path)" ${chalk21.dim("# open in VSCode")}
2458
+ `).action(() => {
2459
+ repoPathCommand();
2460
+ });
2461
+ repo.command("open").description(`\u{1F4C2} Open the repo in the OS file manager ${chalk21.dim("(--code: VSCode, --stree: Sourcetree)")}`).option("--code", "open with VSCode (`code` CLI)").option("--stree", "open with Sourcetree (`stree` CLI)").addHelpText("after", `
2462
+ Examples:
2463
+ $ sppt repo open ${chalk21.dim("# Explorer / Finder / xdg-open")}
2464
+ $ sppt repo open --code ${chalk21.dim("# open in VSCode")}
2465
+ $ sppt repo open --stree ${chalk21.dim("# open in Sourcetree")}
2466
+ `).action((opts) => {
2467
+ repoOpenCommand({ code: opts.code, stree: opts.stree });
2058
2468
  });
2059
- program.command("uninstall").description(`\u{1F5D1}\uFE0F Remove all set-prompt data ${chalk15.dim("(~/.set-prompt/, plugin dirs, settings entries)")}`).action(async () => {
2469
+ program.command("uninstall").description(`\u{1F5D1}\uFE0F Remove all set-prompt data ${chalk21.dim("(~/.set-prompt/, plugin dirs, settings entries)")}`).action(async () => {
2060
2470
  await uninstallCommand();
2061
2471
  });
2062
2472
  program.parse(process.argv);