aiblueprint-cli 1.3.6 → 1.4.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.
Files changed (2) hide show
  1. package/dist/cli.js +320 -163
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -32488,9 +32488,9 @@ var inquirer = {
32488
32488
  var lib_default = inquirer;
32489
32489
 
32490
32490
  // src/commands/setup.ts
32491
- var import_fs_extra5 = __toESM(require_lib4(), 1);
32492
- import path7 from "path";
32493
- import os7 from "os";
32491
+ var import_fs_extra6 = __toESM(require_lib4(), 1);
32492
+ import path8 from "path";
32493
+ import os8 from "os";
32494
32494
 
32495
32495
  // node_modules/chalk/source/vendor/ansi-styles/index.js
32496
32496
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -33415,6 +33415,39 @@ function getVersion() {
33415
33415
  }
33416
33416
  }
33417
33417
 
33418
+ // src/lib/backup-utils.ts
33419
+ var import_fs_extra5 = __toESM(require_lib4(), 1);
33420
+ import path7 from "path";
33421
+ import os7 from "os";
33422
+ var BACKUP_BASE_DIR = path7.join(os7.homedir(), ".config", "aiblueprint", "backup");
33423
+ function formatDate(date) {
33424
+ const pad = (n) => n.toString().padStart(2, "0");
33425
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
33426
+ }
33427
+ async function createBackup(claudeDir) {
33428
+ const exists = await import_fs_extra5.default.pathExists(claudeDir);
33429
+ if (!exists) {
33430
+ return null;
33431
+ }
33432
+ const files = await import_fs_extra5.default.readdir(claudeDir);
33433
+ const hasContent = files.some((f) => f !== ".DS_Store");
33434
+ if (!hasContent) {
33435
+ return null;
33436
+ }
33437
+ const timestamp = formatDate(new Date);
33438
+ const backupPath = path7.join(BACKUP_BASE_DIR, timestamp);
33439
+ await import_fs_extra5.default.ensureDir(backupPath);
33440
+ const itemsToCopy = ["commands", "agents", "skills", "scripts", "song", "settings.json"];
33441
+ for (const item of itemsToCopy) {
33442
+ const sourcePath = path7.join(claudeDir, item);
33443
+ const destPath = path7.join(backupPath, item);
33444
+ if (await import_fs_extra5.default.pathExists(sourcePath)) {
33445
+ await import_fs_extra5.default.copy(sourcePath, destPath, { overwrite: true });
33446
+ }
33447
+ }
33448
+ return backupPath;
33449
+ }
33450
+
33418
33451
  // src/commands/setup.ts
33419
33452
  var __filename2 = fileURLToPath2(import.meta.url);
33420
33453
  var __dirname2 = dirname2(__filename2);
@@ -33518,9 +33551,16 @@ async function setupCommand(params = {}) {
33518
33551
  skipInteractive
33519
33552
  };
33520
33553
  const s = new SimpleSpinner;
33521
- const claudeDir = customClaudeCodeFolder ? path7.resolve(customClaudeCodeFolder) : path7.join(os7.homedir(), ".claude");
33554
+ const claudeDir = customClaudeCodeFolder ? path8.resolve(customClaudeCodeFolder) : path8.join(os8.homedir(), ".claude");
33522
33555
  console.log(source_default.gray(`Installing to: ${claudeDir}`));
33523
- await import_fs_extra5.default.ensureDir(claudeDir);
33556
+ await import_fs_extra6.default.ensureDir(claudeDir);
33557
+ s.start("Creating backup of existing configuration");
33558
+ const backupPath = await createBackup(claudeDir);
33559
+ if (backupPath) {
33560
+ s.stop(`Backup created: ${source_default.gray(backupPath)}`);
33561
+ } else {
33562
+ s.stop("No existing config to backup");
33563
+ }
33524
33564
  let useGitHub = true;
33525
33565
  let sourceDir;
33526
33566
  const testUrl = `${GITHUB_RAW_BASE2}/scripts/validate-command.js`;
@@ -33533,14 +33573,14 @@ async function setupCommand(params = {}) {
33533
33573
  if (!useGitHub) {
33534
33574
  const currentDir = process.cwd();
33535
33575
  const possiblePaths = [
33536
- path7.join(currentDir, "claude-code-config"),
33537
- path7.join(__dirname2, "../../claude-code-config"),
33538
- path7.join(__dirname2, "../claude-code-config"),
33539
- path7.join(path7.dirname(process.argv[1]), "../claude-code-config")
33576
+ path8.join(currentDir, "claude-code-config"),
33577
+ path8.join(__dirname2, "../../claude-code-config"),
33578
+ path8.join(__dirname2, "../claude-code-config"),
33579
+ path8.join(path8.dirname(process.argv[1]), "../claude-code-config")
33540
33580
  ];
33541
33581
  sourceDir = possiblePaths.find((p) => {
33542
33582
  try {
33543
- return import_fs_extra5.default.existsSync(p);
33583
+ return import_fs_extra6.default.existsSync(p);
33544
33584
  } catch {
33545
33585
  return false;
33546
33586
  }
@@ -33560,28 +33600,28 @@ async function setupCommand(params = {}) {
33560
33600
  if (options.commandValidation || options.customStatusline || options.notificationSounds || options.postEditTypeScript) {
33561
33601
  s.start("Setting up scripts");
33562
33602
  if (useGitHub) {
33563
- const scriptsDir = path7.join(claudeDir, "scripts");
33564
- await import_fs_extra5.default.ensureDir(scriptsDir);
33603
+ const scriptsDir = path8.join(claudeDir, "scripts");
33604
+ await import_fs_extra6.default.ensureDir(scriptsDir);
33565
33605
  if (options.commandValidation) {
33566
- await downloadDirectoryFromGitHub("scripts/command-validator", path7.join(scriptsDir, "command-validator"));
33606
+ await downloadDirectoryFromGitHub("scripts/command-validator", path8.join(scriptsDir, "command-validator"));
33567
33607
  }
33568
33608
  if (options.postEditTypeScript) {
33569
- await downloadFromGitHub("scripts/hook-post-file.ts", path7.join(scriptsDir, "hook-post-file.ts"));
33609
+ await downloadFromGitHub("scripts/hook-post-file.ts", path8.join(scriptsDir, "hook-post-file.ts"));
33570
33610
  }
33571
33611
  if (options.customStatusline) {
33572
- await downloadDirectoryFromGitHub("scripts/statusline", path7.join(scriptsDir, "statusline"));
33612
+ await downloadDirectoryFromGitHub("scripts/statusline", path8.join(scriptsDir, "statusline"));
33573
33613
  }
33574
33614
  } else {
33575
- await import_fs_extra5.default.copy(path7.join(sourceDir, "scripts"), path7.join(claudeDir, "scripts"), { overwrite: true });
33615
+ await import_fs_extra6.default.copy(path8.join(sourceDir, "scripts"), path8.join(claudeDir, "scripts"), { overwrite: true });
33576
33616
  }
33577
33617
  s.stop("Scripts installed");
33578
33618
  }
33579
33619
  if (options.aiblueprintCommands) {
33580
33620
  s.start("Setting up AIBlueprint commands");
33581
33621
  if (useGitHub) {
33582
- await downloadDirectoryFromGitHub("commands", path7.join(claudeDir, "commands"));
33622
+ await downloadDirectoryFromGitHub("commands", path8.join(claudeDir, "commands"));
33583
33623
  } else {
33584
- await import_fs_extra5.default.copy(path7.join(sourceDir, "commands"), path7.join(claudeDir, "commands"), { overwrite: true });
33624
+ await import_fs_extra6.default.copy(path8.join(sourceDir, "commands"), path8.join(claudeDir, "commands"), { overwrite: true });
33585
33625
  }
33586
33626
  s.stop("Commands installed");
33587
33627
  }
@@ -33598,9 +33638,9 @@ async function setupCommand(params = {}) {
33598
33638
  if (options.aiblueprintAgents) {
33599
33639
  s.start("Setting up AIBlueprint agents");
33600
33640
  if (useGitHub) {
33601
- await downloadDirectoryFromGitHub("agents", path7.join(claudeDir, "agents"));
33641
+ await downloadDirectoryFromGitHub("agents", path8.join(claudeDir, "agents"));
33602
33642
  } else {
33603
- await import_fs_extra5.default.copy(path7.join(sourceDir, "agents"), path7.join(claudeDir, "agents"), { overwrite: true });
33643
+ await import_fs_extra6.default.copy(path8.join(sourceDir, "agents"), path8.join(claudeDir, "agents"), { overwrite: true });
33604
33644
  }
33605
33645
  s.stop("Agents installed");
33606
33646
  }
@@ -33611,7 +33651,7 @@ async function setupCommand(params = {}) {
33611
33651
  try {
33612
33652
  const testResponse = await fetch(testSkillsUrl);
33613
33653
  if (testResponse.ok) {
33614
- await downloadDirectoryFromGitHub("skills", path7.join(claudeDir, "skills"));
33654
+ await downloadDirectoryFromGitHub("skills", path8.join(claudeDir, "skills"));
33615
33655
  s.stop("Skills installed");
33616
33656
  } else {
33617
33657
  s.stop("Skills not available in repository");
@@ -33620,9 +33660,9 @@ async function setupCommand(params = {}) {
33620
33660
  s.stop("Skills not available in repository");
33621
33661
  }
33622
33662
  } else {
33623
- const skillsSourcePath = path7.join(sourceDir, "skills");
33624
- if (await import_fs_extra5.default.pathExists(skillsSourcePath)) {
33625
- await import_fs_extra5.default.copy(skillsSourcePath, path7.join(claudeDir, "skills"), { overwrite: true });
33663
+ const skillsSourcePath = path8.join(sourceDir, "skills");
33664
+ if (await import_fs_extra6.default.pathExists(skillsSourcePath)) {
33665
+ await import_fs_extra6.default.copy(skillsSourcePath, path8.join(claudeDir, "skills"), { overwrite: true });
33626
33666
  s.stop("Skills installed");
33627
33667
  } else {
33628
33668
  s.stop("Skills not available in local repository");
@@ -33632,12 +33672,12 @@ async function setupCommand(params = {}) {
33632
33672
  if (options.notificationSounds) {
33633
33673
  s.start("Setting up notification sounds");
33634
33674
  if (useGitHub) {
33635
- const songDir = path7.join(claudeDir, "song");
33636
- await import_fs_extra5.default.ensureDir(songDir);
33637
- await downloadFromGitHub("song/finish.mp3", path7.join(songDir, "finish.mp3"));
33638
- await downloadFromGitHub("song/need-human.mp3", path7.join(songDir, "need-human.mp3"));
33675
+ const songDir = path8.join(claudeDir, "song");
33676
+ await import_fs_extra6.default.ensureDir(songDir);
33677
+ await downloadFromGitHub("song/finish.mp3", path8.join(songDir, "finish.mp3"));
33678
+ await downloadFromGitHub("song/need-human.mp3", path8.join(songDir, "need-human.mp3"));
33639
33679
  } else {
33640
- await import_fs_extra5.default.copy(path7.join(sourceDir, "song"), path7.join(claudeDir, "song"), { overwrite: true });
33680
+ await import_fs_extra6.default.copy(path8.join(sourceDir, "song"), path8.join(claudeDir, "song"), { overwrite: true });
33641
33681
  }
33642
33682
  s.stop("Notification sounds installed");
33643
33683
  }
@@ -33673,7 +33713,7 @@ async function setupCommand(params = {}) {
33673
33713
  console.log(source_default.gray(`
33674
33714
  Next steps:`));
33675
33715
  if (options.shellShortcuts) {
33676
- const platform = os7.platform();
33716
+ const platform = os8.platform();
33677
33717
  if (platform === "win32") {
33678
33718
  console.log(source_default.gray(" • Restart PowerShell to load the new functions"));
33679
33719
  } else {
@@ -33694,14 +33734,14 @@ Next steps:`));
33694
33734
  }
33695
33735
 
33696
33736
  // src/commands/addHook.ts
33697
- var import_fs_extra9 = __toESM(require_lib4(), 1);
33698
- import path11 from "path";
33737
+ var import_fs_extra10 = __toESM(require_lib4(), 1);
33738
+ import path12 from "path";
33699
33739
  import { fileURLToPath as fileURLToPath4 } from "url";
33700
33740
  import { dirname as dirname4 } from "path";
33701
33741
 
33702
33742
  // src/utils/claude-config.ts
33703
- var import_fs_extra6 = __toESM(require_lib4(), 1);
33704
- import path8 from "path";
33743
+ var import_fs_extra7 = __toESM(require_lib4(), 1);
33744
+ import path9 from "path";
33705
33745
  import { fileURLToPath as fileURLToPath3 } from "url";
33706
33746
  import { dirname as dirname3 } from "path";
33707
33747
  var __filename3 = fileURLToPath3(import.meta.url);
@@ -33732,14 +33772,14 @@ function parseYamlFrontmatter(content) {
33732
33772
  }
33733
33773
  function getLocalConfigPaths(subDir) {
33734
33774
  return [
33735
- path8.join(__dirname3, `../claude-code-config/${subDir}`),
33736
- path8.join(__dirname3, `../../claude-code-config/${subDir}`)
33775
+ path9.join(__dirname3, `../claude-code-config/${subDir}`),
33776
+ path9.join(__dirname3, `../../claude-code-config/${subDir}`)
33737
33777
  ];
33738
33778
  }
33739
33779
  async function findLocalConfigDir(subDir) {
33740
33780
  const possiblePaths = getLocalConfigPaths(subDir);
33741
33781
  for (const testPath of possiblePaths) {
33742
- if (await import_fs_extra6.default.pathExists(testPath)) {
33782
+ if (await import_fs_extra7.default.pathExists(testPath)) {
33743
33783
  return testPath;
33744
33784
  }
33745
33785
  }
@@ -33750,22 +33790,22 @@ async function getTargetDirectory(options) {
33750
33790
  return options.folder;
33751
33791
  }
33752
33792
  const cwd = process.cwd();
33753
- const localClaudeDir = path8.join(cwd, ".claude");
33754
- const isGitRepo = await import_fs_extra6.default.pathExists(path8.join(cwd, ".git"));
33755
- const hasClaudeConfig = await import_fs_extra6.default.pathExists(localClaudeDir);
33793
+ const localClaudeDir = path9.join(cwd, ".claude");
33794
+ const isGitRepo = await import_fs_extra7.default.pathExists(path9.join(cwd, ".git"));
33795
+ const hasClaudeConfig = await import_fs_extra7.default.pathExists(localClaudeDir);
33756
33796
  if (isGitRepo || hasClaudeConfig) {
33757
33797
  return localClaudeDir;
33758
33798
  }
33759
- return path8.join(process.env.HOME || process.env.USERPROFILE || "~", ".claude");
33799
+ return path9.join(process.env.HOME || process.env.USERPROFILE || "~", ".claude");
33760
33800
  }
33761
33801
 
33762
33802
  // src/utils/file-installer.ts
33763
- var import_fs_extra8 = __toESM(require_lib4(), 1);
33764
- import path10 from "path";
33803
+ var import_fs_extra9 = __toESM(require_lib4(), 1);
33804
+ import path11 from "path";
33765
33805
 
33766
33806
  // src/utils/github.ts
33767
- var import_fs_extra7 = __toESM(require_lib4(), 1);
33768
- import path9 from "path";
33807
+ var import_fs_extra8 = __toESM(require_lib4(), 1);
33808
+ import path10 from "path";
33769
33809
  var GITHUB_RAW_BASE3 = "https://raw.githubusercontent.com/Melvynx/aiblueprint-cli/main/claude-code-config";
33770
33810
  async function downloadFromGitHub2(relativePath) {
33771
33811
  try {
@@ -33813,8 +33853,8 @@ async function isGitHubAvailable() {
33813
33853
  async function downloadAndWriteFile(relativePath, targetPath) {
33814
33854
  const content = await downloadFromGitHub2(relativePath);
33815
33855
  if (content) {
33816
- await import_fs_extra7.default.ensureDir(path9.dirname(targetPath));
33817
- await import_fs_extra7.default.writeFile(targetPath, content);
33856
+ await import_fs_extra8.default.ensureDir(path10.dirname(targetPath));
33857
+ await import_fs_extra8.default.writeFile(targetPath, content);
33818
33858
  return true;
33819
33859
  }
33820
33860
  return false;
@@ -33823,7 +33863,7 @@ async function downloadAndWriteFile(relativePath, targetPath) {
33823
33863
  // src/utils/file-installer.ts
33824
33864
  async function installFileWithGitHubFallback(options) {
33825
33865
  const { sourceDir, targetPath, fileName } = options;
33826
- await import_fs_extra8.default.ensureDir(path10.dirname(targetPath));
33866
+ await import_fs_extra9.default.ensureDir(path11.dirname(targetPath));
33827
33867
  const useGitHub = options.useGitHub ?? await isGitHubAvailable();
33828
33868
  if (useGitHub) {
33829
33869
  const relativePath = `${sourceDir}/${fileName}`;
@@ -33837,11 +33877,11 @@ async function installFileWithGitHubFallback(options) {
33837
33877
  if (!localConfigDir) {
33838
33878
  throw new Error(`Neither GitHub nor local ${sourceDir} directory found`);
33839
33879
  }
33840
- const localFilePath = path10.join(localConfigDir, fileName);
33841
- if (!await import_fs_extra8.default.pathExists(localFilePath)) {
33880
+ const localFilePath = path11.join(localConfigDir, fileName);
33881
+ if (!await import_fs_extra9.default.pathExists(localFilePath)) {
33842
33882
  throw new Error(`File not found: ${fileName}`);
33843
33883
  }
33844
- await import_fs_extra8.default.copy(localFilePath, targetPath);
33884
+ await import_fs_extra9.default.copy(localFilePath, targetPath);
33845
33885
  }
33846
33886
  async function getFileContentWithGitHubFallback(sourceDir, fileName) {
33847
33887
  const useGitHub = await isGitHubAvailable();
@@ -33856,11 +33896,11 @@ async function getFileContentWithGitHubFallback(sourceDir, fileName) {
33856
33896
  if (!localConfigDir) {
33857
33897
  throw new Error(`Neither GitHub nor local ${sourceDir} directory found`);
33858
33898
  }
33859
- const localFilePath = path10.join(localConfigDir, fileName);
33860
- if (!await import_fs_extra8.default.pathExists(localFilePath)) {
33899
+ const localFilePath = path11.join(localConfigDir, fileName);
33900
+ if (!await import_fs_extra9.default.pathExists(localFilePath)) {
33861
33901
  throw new Error(`File not found: ${fileName}`);
33862
33902
  }
33863
- return await import_fs_extra8.default.readFile(localFilePath, "utf-8");
33903
+ return await import_fs_extra9.default.readFile(localFilePath, "utf-8");
33864
33904
  }
33865
33905
 
33866
33906
  // src/commands/addHook.ts
@@ -33902,10 +33942,10 @@ async function addHookCommand(hookType, options) {
33902
33942
  const s = new SimpleSpinner2;
33903
33943
  const targetDir = await getTargetDirectory(options);
33904
33944
  const claudeDir = targetDir;
33905
- const targetHookDir = path11.join(claudeDir, hook.targetDir || "hooks");
33906
- const hookFilePath = path11.join(targetHookDir, hook.hookFile);
33907
- const settingsPath = path11.join(claudeDir, "settings.json");
33908
- if (await import_fs_extra9.default.pathExists(hookFilePath)) {
33945
+ const targetHookDir = path12.join(claudeDir, hook.targetDir || "hooks");
33946
+ const hookFilePath = path12.join(targetHookDir, hook.hookFile);
33947
+ const settingsPath = path12.join(claudeDir, "settings.json");
33948
+ if (await import_fs_extra10.default.pathExists(hookFilePath)) {
33909
33949
  const overwriteAnswer = await lib_default.prompt([{
33910
33950
  type: "confirm",
33911
33951
  name: "overwrite",
@@ -33918,18 +33958,18 @@ async function addHookCommand(hookType, options) {
33918
33958
  }
33919
33959
  try {
33920
33960
  s.start("Installing hook...");
33921
- await import_fs_extra9.default.ensureDir(targetHookDir);
33961
+ await import_fs_extra10.default.ensureDir(targetHookDir);
33922
33962
  await installFileWithGitHubFallback({
33923
33963
  sourceDir: hook.sourceDir || "hooks",
33924
33964
  targetPath: hookFilePath,
33925
33965
  fileName: hook.hookFile
33926
33966
  });
33927
- await import_fs_extra9.default.chmod(hookFilePath, 493);
33967
+ await import_fs_extra10.default.chmod(hookFilePath, 493);
33928
33968
  s.stop("Hook file installed");
33929
33969
  s.start("Updating settings.json...");
33930
33970
  let settings = {};
33931
33971
  try {
33932
- const existingSettings = await import_fs_extra9.default.readFile(settingsPath, "utf-8");
33972
+ const existingSettings = await import_fs_extra10.default.readFile(settingsPath, "utf-8");
33933
33973
  settings = JSON.parse(existingSettings);
33934
33974
  } catch {
33935
33975
  settings = {};
@@ -33966,7 +34006,7 @@ async function addHookCommand(hookType, options) {
33966
34006
  } else {
33967
34007
  settings.hooks[hook.event].push(newHook);
33968
34008
  }
33969
- await import_fs_extra9.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
34009
+ await import_fs_extra10.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
33970
34010
  s.stop("Settings updated");
33971
34011
  console.log(source_default.green("✨ Hook installed successfully!"));
33972
34012
  console.log(source_default.gray(`
@@ -33985,8 +34025,8 @@ The hook will run automatically when you edit TypeScript files with Claude Code.
33985
34025
  }
33986
34026
 
33987
34027
  // src/commands/addCommand.ts
33988
- var import_fs_extra10 = __toESM(require_lib4(), 1);
33989
- import path12 from "path";
34028
+ var import_fs_extra11 = __toESM(require_lib4(), 1);
34029
+ import path13 from "path";
33990
34030
  class SimpleSpinner3 {
33991
34031
  message = "";
33992
34032
  start(message) {
@@ -33999,11 +34039,11 @@ class SimpleSpinner3 {
33999
34039
  }
34000
34040
  async function getLocalMdFilesRecursively(dir, basePath = "") {
34001
34041
  const files = [];
34002
- const entries = await import_fs_extra10.default.readdir(dir, { withFileTypes: true });
34042
+ const entries = await import_fs_extra11.default.readdir(dir, { withFileTypes: true });
34003
34043
  for (const entry of entries) {
34004
34044
  const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;
34005
34045
  if (entry.isDirectory()) {
34006
- const subFiles = await getLocalMdFilesRecursively(path12.join(dir, entry.name), relativePath);
34046
+ const subFiles = await getLocalMdFilesRecursively(path13.join(dir, entry.name), relativePath);
34007
34047
  files.push(...subFiles);
34008
34048
  } else if (entry.name.endsWith(".md")) {
34009
34049
  files.push(relativePath);
@@ -34083,9 +34123,9 @@ async function addCommandCommand(commandName, options = {}) {
34083
34123
  if (options.folder) {
34084
34124
  console.log(source_default.gray(`Using custom folder: ${targetDir}`));
34085
34125
  }
34086
- const commandsDir = path12.join(targetDir, "commands");
34087
- const commandFilePath = path12.join(commandsDir, command.commandFile);
34088
- if (await import_fs_extra10.default.pathExists(commandFilePath)) {
34126
+ const commandsDir = path13.join(targetDir, "commands");
34127
+ const commandFilePath = path13.join(commandsDir, command.commandFile);
34128
+ if (await import_fs_extra11.default.pathExists(commandFilePath)) {
34089
34129
  const overwriteAnswer = await lib_default.prompt([{
34090
34130
  type: "confirm",
34091
34131
  name: "overwrite",
@@ -34292,22 +34332,22 @@ async function symlinkCommand(params = {}) {
34292
34332
  }
34293
34333
 
34294
34334
  // src/commands/statusline.ts
34295
- var import_fs_extra11 = __toESM(require_lib4(), 1);
34296
- import path13 from "path";
34335
+ var import_fs_extra12 = __toESM(require_lib4(), 1);
34336
+ import path14 from "path";
34297
34337
  import { homedir } from "os";
34298
34338
  async function statuslineCommand(options) {
34299
- const claudeDir = options.folder ? path13.resolve(options.folder) : path13.join(homedir(), ".claude");
34339
+ const claudeDir = options.folder ? path14.resolve(options.folder) : path14.join(homedir(), ".claude");
34300
34340
  console.log(source_default.blue(`\uD83D\uDE80 Setting up AIBlueprint Statusline ${source_default.gray(`v${getVersion()}`)}...`));
34301
34341
  console.log(source_default.gray(` Target: ${claudeDir}
34302
34342
  `));
34303
- await import_fs_extra11.default.ensureDir(claudeDir);
34343
+ await import_fs_extra12.default.ensureDir(claudeDir);
34304
34344
  console.log(source_default.cyan("\uD83D\uDCE6 Checking dependencies..."));
34305
34345
  await checkAndInstallDependencies();
34306
34346
  console.log(source_default.cyan(`
34307
34347
  \uD83D\uDCE5 Downloading statusline files...`));
34308
- const scriptsDir = path13.join(claudeDir, "scripts");
34309
- await import_fs_extra11.default.ensureDir(scriptsDir);
34310
- const success = await downloadDirectoryFromGitHub("scripts/statusline", path13.join(scriptsDir, "statusline"));
34348
+ const scriptsDir = path14.join(claudeDir, "scripts");
34349
+ await import_fs_extra12.default.ensureDir(scriptsDir);
34350
+ const success = await downloadDirectoryFromGitHub("scripts/statusline", path14.join(scriptsDir, "statusline"));
34311
34351
  if (!success) {
34312
34352
  console.log(source_default.red(" Failed to download statusline files from GitHub"));
34313
34353
  return;
@@ -34317,19 +34357,19 @@ async function statuslineCommand(options) {
34317
34357
  await installStatuslineDependencies(claudeDir);
34318
34358
  console.log(source_default.cyan(`
34319
34359
  ⚙️ Configuring settings.json...`));
34320
- const settingsPath = path13.join(claudeDir, "settings.json");
34360
+ const settingsPath = path14.join(claudeDir, "settings.json");
34321
34361
  let settings = {};
34322
34362
  try {
34323
- const existingSettings = await import_fs_extra11.default.readFile(settingsPath, "utf-8");
34363
+ const existingSettings = await import_fs_extra12.default.readFile(settingsPath, "utf-8");
34324
34364
  settings = JSON.parse(existingSettings);
34325
34365
  } catch {
34326
34366
  }
34327
34367
  settings.statusLine = {
34328
34368
  type: "command",
34329
- command: `bun ${path13.join(claudeDir, "scripts/statusline/src/index.ts")}`,
34369
+ command: `bun ${path14.join(claudeDir, "scripts/statusline/src/index.ts")}`,
34330
34370
  padding: 0
34331
34371
  };
34332
- await import_fs_extra11.default.writeJson(settingsPath, settings, { spaces: 2 });
34372
+ await import_fs_extra12.default.writeJson(settingsPath, settings, { spaces: 2 });
34333
34373
  console.log(source_default.green(`
34334
34374
  ✅ Statusline setup complete!`));
34335
34375
  console.log(source_default.gray(`
@@ -34704,6 +34744,32 @@ var vD = class extends x {
34704
34744
  this.value = u ? this.value.filter((F) => F !== this._value) : [...this.value, this._value];
34705
34745
  }
34706
34746
  };
34747
+ var wD = Object.defineProperty;
34748
+ var yD = (e, u, F) => (u in e) ? wD(e, u, { enumerable: true, configurable: true, writable: true, value: F }) : e[u] = F;
34749
+ var Z = (e, u, F) => (yD(e, typeof u != "symbol" ? u + "" : u, F), F);
34750
+ var $D = class extends x {
34751
+ constructor(u) {
34752
+ super(u, false), Z(this, "options"), Z(this, "cursor", 0), this.options = u.options, this.cursor = this.options.findIndex(({ value: F }) => F === u.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (F) => {
34753
+ switch (F) {
34754
+ case "left":
34755
+ case "up":
34756
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
34757
+ break;
34758
+ case "down":
34759
+ case "right":
34760
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
34761
+ break;
34762
+ }
34763
+ this.changeValue();
34764
+ });
34765
+ }
34766
+ get _value() {
34767
+ return this.options[this.cursor];
34768
+ }
34769
+ changeValue() {
34770
+ this.value = this._value.value;
34771
+ }
34772
+ };
34707
34773
  var TD = Object.defineProperty;
34708
34774
  var jD = (e, u, F) => (u in e) ? TD(e, u, { enumerable: true, configurable: true, writable: true, value: F }) : e[u] = F;
34709
34775
  var MD = (e, u, F) => (jD(e, typeof u != "symbol" ? u + "" : u, F), F);
@@ -34771,7 +34837,7 @@ var w2 = o("◼", "[+]");
34771
34837
  var M2 = o("◻", "[ ]");
34772
34838
  var U2 = o("▪", "•");
34773
34839
  var B = o("─", "-");
34774
- var Z = o("╮", "+");
34840
+ var Z2 = o("╮", "+");
34775
34841
  var z2 = o("├", "+");
34776
34842
  var X2 = o("╯", "+");
34777
34843
  var J2 = o("●", "•");
@@ -34831,6 +34897,34 @@ ${import_picocolors2.default.cyan(d2)}
34831
34897
  }
34832
34898
  } }).prompt();
34833
34899
  };
34900
+ var ie = (r2) => {
34901
+ const n = (t, s) => {
34902
+ const c2 = t.label ?? String(t.value);
34903
+ return s === "active" ? `${import_picocolors2.default.green(b2)} ${c2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : s === "selected" ? `${import_picocolors2.default.dim(c2)}` : s === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(c2))}` : `${import_picocolors2.default.dim(E)} ${import_picocolors2.default.dim(c2)}`;
34904
+ };
34905
+ let i = 0;
34906
+ return new $D({ options: r2.options, initialValue: r2.initialValue, render() {
34907
+ const t = `${import_picocolors2.default.gray(a2)}
34908
+ ${y2(this.state)} ${r2.message}
34909
+ `;
34910
+ switch (this.state) {
34911
+ case "submit":
34912
+ return `${t}${import_picocolors2.default.gray(a2)} ${n(this.options[this.cursor], "selected")}`;
34913
+ case "cancel":
34914
+ return `${t}${import_picocolors2.default.gray(a2)} ${n(this.options[this.cursor], "cancelled")}
34915
+ ${import_picocolors2.default.gray(a2)}`;
34916
+ default: {
34917
+ const s = r2.maxItems === undefined ? 1 / 0 : Math.max(r2.maxItems, 5);
34918
+ this.cursor >= i + s - 3 ? i = Math.max(Math.min(this.cursor - s + 3, this.options.length - s), 0) : this.cursor < i + 2 && (i = Math.max(this.cursor - 2, 0));
34919
+ const c2 = s < this.options.length && i > 0, l2 = s < this.options.length && i + s < this.options.length;
34920
+ return `${t}${import_picocolors2.default.cyan(a2)} ${this.options.slice(i, i + s).map((u, m2, $2) => m2 === 0 && c2 ? import_picocolors2.default.dim("...") : m2 === $2.length - 1 && l2 ? import_picocolors2.default.dim("...") : n(u, m2 + i === this.cursor ? "active" : "inactive")).join(`
34921
+ ${import_picocolors2.default.cyan(a2)} `)}
34922
+ ${import_picocolors2.default.cyan(d2)}
34923
+ `;
34924
+ }
34925
+ }
34926
+ } }).prompt();
34927
+ };
34834
34928
  var ae = (r2) => {
34835
34929
  const n = (i, t) => {
34836
34930
  const s = i.label ?? String(i.value);
@@ -34939,13 +35033,13 @@ var de = () => {
34939
35033
  };
34940
35034
 
34941
35035
  // src/commands/pro.ts
34942
- import os10 from "os";
34943
- import path16 from "path";
35036
+ import os11 from "os";
35037
+ import path17 from "path";
34944
35038
 
34945
35039
  // src/lib/pro-installer.ts
34946
- var import_fs_extra12 = __toESM(require_lib4(), 1);
34947
- import os8 from "os";
34948
- import path14 from "path";
35040
+ var import_fs_extra13 = __toESM(require_lib4(), 1);
35041
+ import os9 from "os";
35042
+ import path15 from "path";
34949
35043
  var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
34950
35044
  var PREMIUM_BRANCH = "main";
34951
35045
  async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath, githubToken) {
@@ -34962,8 +35056,8 @@ async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath,
34962
35056
  return false;
34963
35057
  }
34964
35058
  const content = await response.arrayBuffer();
34965
- await import_fs_extra12.default.ensureDir(path14.dirname(targetPath));
34966
- await import_fs_extra12.default.writeFile(targetPath, Buffer.from(content));
35059
+ await import_fs_extra13.default.ensureDir(path15.dirname(targetPath));
35060
+ await import_fs_extra13.default.writeFile(targetPath, Buffer.from(content));
34967
35061
  return true;
34968
35062
  } catch (error) {
34969
35063
  console.error(`Error downloading ${relativePath}:`, error);
@@ -34988,10 +35082,10 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
34988
35082
  console.error(`Unexpected response for directory ${dirPath}`);
34989
35083
  return false;
34990
35084
  }
34991
- await import_fs_extra12.default.ensureDir(targetDir);
35085
+ await import_fs_extra13.default.ensureDir(targetDir);
34992
35086
  for (const file of files) {
34993
35087
  const relativePath = dirPath ? `${dirPath}/${file.name}` : file.name;
34994
- const targetPath = path14.join(targetDir, file.name);
35088
+ const targetPath = path15.join(targetDir, file.name);
34995
35089
  const displayPath = relativePath.replace("claude-code-config/", "");
34996
35090
  if (file.type === "file") {
34997
35091
  onProgress?.(displayPath, "file");
@@ -35008,14 +35102,14 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
35008
35102
  }
35009
35103
  async function installProConfigs(options) {
35010
35104
  const { githubToken, claudeCodeFolder, onProgress } = options;
35011
- const claudeFolder = claudeCodeFolder || path14.join(os8.homedir(), ".claude");
35012
- const tempDir = path14.join(os8.tmpdir(), `aiblueprint-premium-${Date.now()}`);
35105
+ const claudeFolder = claudeCodeFolder || path15.join(os9.homedir(), ".claude");
35106
+ const tempDir = path15.join(os9.tmpdir(), `aiblueprint-premium-${Date.now()}`);
35013
35107
  try {
35014
35108
  const success = await downloadDirectoryFromPrivateGitHub(PREMIUM_REPO, PREMIUM_BRANCH, "claude-code-config", tempDir, githubToken, onProgress);
35015
35109
  if (!success) {
35016
35110
  throw new Error("Failed to download premium configurations");
35017
35111
  }
35018
- await import_fs_extra12.default.copy(tempDir, claudeFolder, {
35112
+ await import_fs_extra13.default.copy(tempDir, claudeFolder, {
35019
35113
  overwrite: true,
35020
35114
  recursive: true
35021
35115
  });
@@ -35023,41 +35117,41 @@ async function installProConfigs(options) {
35023
35117
  throw new Error(`Failed to install premium configs: ${error instanceof Error ? error.message : "Unknown error"}`);
35024
35118
  } finally {
35025
35119
  try {
35026
- await import_fs_extra12.default.remove(tempDir);
35120
+ await import_fs_extra13.default.remove(tempDir);
35027
35121
  } catch {
35028
35122
  }
35029
35123
  }
35030
35124
  }
35031
35125
 
35032
35126
  // src/lib/token-storage.ts
35033
- var import_fs_extra13 = __toESM(require_lib4(), 1);
35034
- import os9 from "os";
35035
- import path15 from "path";
35127
+ var import_fs_extra14 = __toESM(require_lib4(), 1);
35128
+ import os10 from "os";
35129
+ import path16 from "path";
35036
35130
  function getConfigDir() {
35037
- const platform = os9.platform();
35131
+ const platform = os10.platform();
35038
35132
  if (platform === "win32") {
35039
- const appData = process.env.APPDATA || path15.join(os9.homedir(), "AppData", "Roaming");
35040
- return path15.join(appData, "aiblueprint");
35133
+ const appData = process.env.APPDATA || path16.join(os10.homedir(), "AppData", "Roaming");
35134
+ return path16.join(appData, "aiblueprint");
35041
35135
  } else {
35042
- const configHome = process.env.XDG_CONFIG_HOME || path15.join(os9.homedir(), ".config");
35043
- return path15.join(configHome, "aiblueprint");
35136
+ const configHome = process.env.XDG_CONFIG_HOME || path16.join(os10.homedir(), ".config");
35137
+ return path16.join(configHome, "aiblueprint");
35044
35138
  }
35045
35139
  }
35046
35140
  function getTokenFilePath() {
35047
- return path15.join(getConfigDir(), "token.txt");
35141
+ return path16.join(getConfigDir(), "token.txt");
35048
35142
  }
35049
35143
  async function saveToken(githubToken) {
35050
35144
  const tokenFile = getTokenFilePath();
35051
- await import_fs_extra13.default.ensureDir(path15.dirname(tokenFile));
35052
- await import_fs_extra13.default.writeFile(tokenFile, githubToken, { mode: 384 });
35145
+ await import_fs_extra14.default.ensureDir(path16.dirname(tokenFile));
35146
+ await import_fs_extra14.default.writeFile(tokenFile, githubToken, { mode: 384 });
35053
35147
  }
35054
35148
  async function getToken() {
35055
35149
  const tokenFile = getTokenFilePath();
35056
- if (!await import_fs_extra13.default.pathExists(tokenFile)) {
35150
+ if (!await import_fs_extra14.default.pathExists(tokenFile)) {
35057
35151
  return null;
35058
35152
  }
35059
35153
  try {
35060
- const token = await import_fs_extra13.default.readFile(tokenFile, "utf-8");
35154
+ const token = await import_fs_extra14.default.readFile(tokenFile, "utf-8");
35061
35155
  return token.trim();
35062
35156
  } catch (error) {
35063
35157
  return null;
@@ -35066,12 +35160,12 @@ async function getToken() {
35066
35160
  function getTokenInfo() {
35067
35161
  return {
35068
35162
  path: getTokenFilePath(),
35069
- platform: os9.platform()
35163
+ platform: os10.platform()
35070
35164
  };
35071
35165
  }
35072
35166
 
35073
35167
  // src/commands/pro.ts
35074
- var import_fs_extra14 = __toESM(require_lib4(), 1);
35168
+ var import_fs_extra15 = __toESM(require_lib4(), 1);
35075
35169
  var API_URL = "https://codeline.app/api/products";
35076
35170
  var PRODUCT_ID = "prd_XJVgxVPbGG";
35077
35171
  async function countInstalledItems(claudeDir) {
@@ -35081,27 +35175,27 @@ async function countInstalledItems(claudeDir) {
35081
35175
  skills: 0
35082
35176
  };
35083
35177
  try {
35084
- const commandsDir = path16.join(claudeDir, "commands");
35085
- if (await import_fs_extra14.default.pathExists(commandsDir)) {
35086
- const files = await import_fs_extra14.default.readdir(commandsDir);
35178
+ const commandsDir = path17.join(claudeDir, "commands");
35179
+ if (await import_fs_extra15.default.pathExists(commandsDir)) {
35180
+ const files = await import_fs_extra15.default.readdir(commandsDir);
35087
35181
  counts.commands = files.filter((f3) => f3.endsWith(".md")).length;
35088
35182
  }
35089
35183
  } catch {
35090
35184
  }
35091
35185
  try {
35092
- const agentsDir = path16.join(claudeDir, "agents");
35093
- if (await import_fs_extra14.default.pathExists(agentsDir)) {
35094
- const files = await import_fs_extra14.default.readdir(agentsDir);
35186
+ const agentsDir = path17.join(claudeDir, "agents");
35187
+ if (await import_fs_extra15.default.pathExists(agentsDir)) {
35188
+ const files = await import_fs_extra15.default.readdir(agentsDir);
35095
35189
  counts.agents = files.filter((f3) => f3.endsWith(".md")).length;
35096
35190
  }
35097
35191
  } catch {
35098
35192
  }
35099
35193
  try {
35100
- const skillsDir = path16.join(claudeDir, "skills");
35101
- if (await import_fs_extra14.default.pathExists(skillsDir)) {
35102
- const items = await import_fs_extra14.default.readdir(skillsDir);
35194
+ const skillsDir = path17.join(claudeDir, "skills");
35195
+ if (await import_fs_extra15.default.pathExists(skillsDir)) {
35196
+ const items = await import_fs_extra15.default.readdir(skillsDir);
35103
35197
  const dirs = await Promise.all(items.map(async (item) => {
35104
- const stat = await import_fs_extra14.default.stat(path16.join(skillsDir, item));
35198
+ const stat = await import_fs_extra15.default.stat(path17.join(skillsDir, item));
35105
35199
  return stat.isDirectory();
35106
35200
  }));
35107
35201
  counts.skills = dirs.filter(Boolean).length;
@@ -35208,7 +35302,7 @@ async function proSetupCommand(options = {}) {
35208
35302
  $e(source_default.red("❌ Not activated"));
35209
35303
  process.exit(1);
35210
35304
  }
35211
- const claudeDir = options.folder ? path16.resolve(options.folder) : path16.join(os10.homedir(), ".claude");
35305
+ const claudeDir = options.folder ? path17.resolve(options.folder) : path17.join(os11.homedir(), ".claude");
35212
35306
  const spinner = de();
35213
35307
  const onProgress = (file, type) => {
35214
35308
  spinner.message(`Installing: ${source_default.cyan(file)} ${source_default.gray(`(${type})`)}`);
@@ -35285,12 +35379,12 @@ async function proUpdateCommand(options = {}) {
35285
35379
  }
35286
35380
 
35287
35381
  // src/commands/sync.ts
35288
- import os11 from "os";
35289
- import path18 from "path";
35382
+ import os12 from "os";
35383
+ import path19 from "path";
35290
35384
 
35291
35385
  // src/lib/sync-utils.ts
35292
- var import_fs_extra15 = __toESM(require_lib4(), 1);
35293
- import path17 from "path";
35386
+ var import_fs_extra16 = __toESM(require_lib4(), 1);
35387
+ import path18 from "path";
35294
35388
  import crypto from "crypto";
35295
35389
  var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
35296
35390
  var PREMIUM_BRANCH2 = "main";
@@ -35339,7 +35433,7 @@ async function listRemoteFilesRecursive(dirPath, githubToken, basePath = "") {
35339
35433
  }
35340
35434
  async function computeLocalFileSha(filePath) {
35341
35435
  try {
35342
- const content = await import_fs_extra15.default.readFile(filePath);
35436
+ const content = await import_fs_extra16.default.readFile(filePath);
35343
35437
  return computeFileSha(content);
35344
35438
  } catch {
35345
35439
  return null;
@@ -35347,15 +35441,15 @@ async function computeLocalFileSha(filePath) {
35347
35441
  }
35348
35442
  async function listLocalFiles(dir) {
35349
35443
  const files = [];
35350
- if (!await import_fs_extra15.default.pathExists(dir)) {
35444
+ if (!await import_fs_extra16.default.pathExists(dir)) {
35351
35445
  return files;
35352
35446
  }
35353
- const items = await import_fs_extra15.default.readdir(dir);
35447
+ const items = await import_fs_extra16.default.readdir(dir);
35354
35448
  for (const item of items) {
35355
35449
  if (item === "node_modules" || item === ".DS_Store")
35356
35450
  continue;
35357
- const fullPath = path17.join(dir, item);
35358
- const stat = await import_fs_extra15.default.stat(fullPath);
35451
+ const fullPath = path18.join(dir, item);
35452
+ const stat = await import_fs_extra16.default.stat(fullPath);
35359
35453
  if (stat.isDirectory()) {
35360
35454
  files.push(item);
35361
35455
  const subFiles = await listLocalFilesRecursive(fullPath, item);
@@ -35368,13 +35462,13 @@ async function listLocalFiles(dir) {
35368
35462
  }
35369
35463
  async function listLocalFilesRecursive(dir, basePath) {
35370
35464
  const files = [];
35371
- const items = await import_fs_extra15.default.readdir(dir);
35465
+ const items = await import_fs_extra16.default.readdir(dir);
35372
35466
  for (const item of items) {
35373
35467
  if (item === "node_modules" || item === ".DS_Store")
35374
35468
  continue;
35375
- const fullPath = path17.join(dir, item);
35469
+ const fullPath = path18.join(dir, item);
35376
35470
  const relativePath = `${basePath}/${item}`;
35377
- const stat = await import_fs_extra15.default.stat(fullPath);
35471
+ const stat = await import_fs_extra16.default.stat(fullPath);
35378
35472
  if (stat.isDirectory()) {
35379
35473
  files.push(relativePath);
35380
35474
  const subFiles = await listLocalFilesRecursive(fullPath, relativePath);
@@ -35387,7 +35481,7 @@ async function listLocalFilesRecursive(dir, basePath) {
35387
35481
  }
35388
35482
  async function analyzeCategory(category, claudeDir, githubToken) {
35389
35483
  const items = [];
35390
- const localDir = path17.join(claudeDir, category);
35484
+ const localDir = path18.join(claudeDir, category);
35391
35485
  const remoteFiles = await listRemoteFilesRecursive(category, githubToken);
35392
35486
  const localFiles = await listLocalFiles(localDir);
35393
35487
  const remoteSet = new Map;
@@ -35396,7 +35490,7 @@ async function analyzeCategory(category, claudeDir, githubToken) {
35396
35490
  }
35397
35491
  const localSet = new Set(localFiles);
35398
35492
  for (const [remotePath, { sha, isFolder }] of remoteSet) {
35399
- const localPath = path17.join(localDir, remotePath);
35493
+ const localPath = path18.join(localDir, remotePath);
35400
35494
  if (isFolder) {
35401
35495
  continue;
35402
35496
  }
@@ -35428,8 +35522,8 @@ async function analyzeCategory(category, claudeDir, githubToken) {
35428
35522
  }
35429
35523
  for (const localPath of localSet) {
35430
35524
  if (!remoteSet.has(localPath)) {
35431
- const fullPath = path17.join(localDir, localPath);
35432
- const stat = await import_fs_extra15.default.stat(fullPath).catch(() => null);
35525
+ const fullPath = path18.join(localDir, localPath);
35526
+ const stat = await import_fs_extra16.default.stat(fullPath).catch(() => null);
35433
35527
  if (stat && !stat.isDirectory()) {
35434
35528
  items.push({
35435
35529
  name: localPath,
@@ -35460,9 +35554,9 @@ async function fetchRemoteSettings(githubToken) {
35460
35554
  }
35461
35555
  }
35462
35556
  async function getLocalSettings(claudeDir) {
35463
- const settingsPath = path17.join(claudeDir, "settings.json");
35557
+ const settingsPath = path18.join(claudeDir, "settings.json");
35464
35558
  try {
35465
- const content = await import_fs_extra15.default.readFile(settingsPath, "utf-8");
35559
+ const content = await import_fs_extra16.default.readFile(settingsPath, "utf-8");
35466
35560
  return JSON.parse(content);
35467
35561
  } catch {
35468
35562
  return {};
@@ -35543,8 +35637,8 @@ async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken)
35543
35637
  return false;
35544
35638
  }
35545
35639
  const content = await response.arrayBuffer();
35546
- await import_fs_extra15.default.ensureDir(path17.dirname(targetPath));
35547
- await import_fs_extra15.default.writeFile(targetPath, Buffer.from(content));
35640
+ await import_fs_extra16.default.ensureDir(path18.dirname(targetPath));
35641
+ await import_fs_extra16.default.writeFile(targetPath, Buffer.from(content));
35548
35642
  return true;
35549
35643
  } catch {
35550
35644
  return false;
@@ -35554,10 +35648,10 @@ async function syncSelectedHooks(claudeDir, hooks, onProgress) {
35554
35648
  if (hooks.length === 0) {
35555
35649
  return { success: 0, failed: 0 };
35556
35650
  }
35557
- const settingsPath = path17.join(claudeDir, "settings.json");
35651
+ const settingsPath = path18.join(claudeDir, "settings.json");
35558
35652
  let settings = {};
35559
35653
  try {
35560
- const content = await import_fs_extra15.default.readFile(settingsPath, "utf-8");
35654
+ const content = await import_fs_extra16.default.readFile(settingsPath, "utf-8");
35561
35655
  settings = JSON.parse(content);
35562
35656
  } catch {
35563
35657
  settings = {};
@@ -35584,7 +35678,7 @@ async function syncSelectedHooks(claudeDir, hooks, onProgress) {
35584
35678
  failed++;
35585
35679
  }
35586
35680
  }
35587
- await import_fs_extra15.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
35681
+ await import_fs_extra16.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
35588
35682
  return { success, failed };
35589
35683
  }
35590
35684
  async function syncSelectedItems(claudeDir, items, githubToken, onProgress) {
@@ -35592,11 +35686,11 @@ async function syncSelectedItems(claudeDir, items, githubToken, onProgress) {
35592
35686
  let failed = 0;
35593
35687
  let deleted = 0;
35594
35688
  for (const item of items) {
35595
- const targetPath = path17.join(claudeDir, item.relativePath);
35689
+ const targetPath = path18.join(claudeDir, item.relativePath);
35596
35690
  if (item.status === "deleted") {
35597
35691
  onProgress?.(item.relativePath, "deleting");
35598
35692
  try {
35599
- await import_fs_extra15.default.remove(targetPath);
35693
+ await import_fs_extra16.default.remove(targetPath);
35600
35694
  deleted++;
35601
35695
  } catch {
35602
35696
  failed++;
@@ -35747,7 +35841,7 @@ async function proSyncCommand(options = {}) {
35747
35841
  $e(source_default.red("❌ Not activated"));
35748
35842
  process.exit(1);
35749
35843
  }
35750
- const claudeDir = options.folder ? path18.resolve(options.folder) : path18.join(os11.homedir(), ".claude");
35844
+ const claudeDir = options.folder ? path19.resolve(options.folder) : path19.join(os12.homedir(), ".claude");
35751
35845
  const spinner = de();
35752
35846
  spinner.start("Analyzing changes...");
35753
35847
  const result = await analyzeSyncChanges(claudeDir, githubToken);
@@ -35769,8 +35863,8 @@ async function proSyncCommand(options = {}) {
35769
35863
  f2.message(source_default.cyan.bold(` ${category.toUpperCase()}`));
35770
35864
  if (folderedCategories.includes(category)) {
35771
35865
  const folderSummaries = aggregateByTopLevelFolder(items);
35772
- for (const summary2 of folderSummaries) {
35773
- f2.message(` ${formatFolderSummary(summary2)}`);
35866
+ for (const summary of folderSummaries) {
35867
+ f2.message(` ${formatFolderSummary(summary)}`);
35774
35868
  }
35775
35869
  } else {
35776
35870
  for (const item of items) {
@@ -35790,19 +35884,70 @@ async function proSyncCommand(options = {}) {
35790
35884
  }
35791
35885
  f2.message("");
35792
35886
  const choices = createSelectionChoices(changedItems, changedHooks);
35793
- const selected = await ae({
35794
- message: "Select items to sync:",
35795
- options: choices,
35796
- initialValues: choices.map((c2) => c2.value),
35797
- required: false
35887
+ const newItems = changedItems.filter((i) => i.status === "new");
35888
+ const modifiedItems = changedItems.filter((i) => i.status === "modified");
35889
+ const deletedItems = changedItems.filter((i) => i.status === "deleted");
35890
+ const newHooks = changedHooks.filter((h2) => h2.status === "new");
35891
+ const modifiedHooks = changedHooks.filter((h2) => h2.status === "modified");
35892
+ const hasDeletions = deletedItems.length > 0;
35893
+ const syncModeOptions = [
35894
+ {
35895
+ value: "updates",
35896
+ label: "Import all updates",
35897
+ hint: `add ${newItems.length + newHooks.length} + update ${modifiedItems.length + modifiedHooks.length} files`
35898
+ }
35899
+ ];
35900
+ if (hasDeletions) {
35901
+ syncModeOptions.push({
35902
+ value: "updates_and_delete",
35903
+ label: "Import all updates and delete files",
35904
+ hint: `add ${newItems.length + newHooks.length} + update ${modifiedItems.length + modifiedHooks.length} + delete ${deletedItems.length} files`
35905
+ });
35906
+ }
35907
+ syncModeOptions.push({
35908
+ value: "custom",
35909
+ label: "Custom choice",
35910
+ hint: "select specific files to sync"
35798
35911
  });
35799
- if (lD(selected)) {
35912
+ const syncMode = await ie({
35913
+ message: "How would you like to sync?",
35914
+ options: syncModeOptions
35915
+ });
35916
+ if (lD(syncMode)) {
35800
35917
  ue("Sync cancelled");
35801
35918
  process.exit(0);
35802
35919
  }
35803
- const expanded = expandSelections(selected);
35804
- const selectedItems = expanded.items;
35805
- const selectedHooks = expanded.hooks;
35920
+ let selectedItems = [];
35921
+ let selectedHooks = [];
35922
+ if (syncMode === "updates") {
35923
+ selectedItems = [...newItems, ...modifiedItems];
35924
+ selectedHooks = [...newHooks, ...modifiedHooks];
35925
+ } else if (syncMode === "updates_and_delete") {
35926
+ selectedItems = [...newItems, ...modifiedItems, ...deletedItems];
35927
+ selectedHooks = [...newHooks, ...modifiedHooks];
35928
+ } else {
35929
+ const nonDeleteChoices = choices.filter((c2) => {
35930
+ if (c2.value.type === "file")
35931
+ return c2.value.item.status !== "deleted";
35932
+ if (c2.value.type === "folder")
35933
+ return !c2.value.items.every((i) => i.status === "deleted");
35934
+ return true;
35935
+ });
35936
+ const nonDeleteInitialValues = nonDeleteChoices.map((c2) => c2.value);
35937
+ const customSelected = await ae({
35938
+ message: "Select items to sync (deletions excluded by default):",
35939
+ options: choices,
35940
+ initialValues: nonDeleteInitialValues,
35941
+ required: false
35942
+ });
35943
+ if (lD(customSelected)) {
35944
+ ue("Sync cancelled");
35945
+ process.exit(0);
35946
+ }
35947
+ const expanded = expandSelections(customSelected);
35948
+ selectedItems = expanded.items;
35949
+ selectedHooks = expanded.hooks;
35950
+ }
35806
35951
  if (selectedItems.length === 0 && selectedHooks.length === 0) {
35807
35952
  f2.warn("No items selected");
35808
35953
  $e(source_default.yellow("⚠️ Nothing to sync"));
@@ -35811,19 +35956,31 @@ async function proSyncCommand(options = {}) {
35811
35956
  const toAdd = selectedItems.filter((i) => i.status === "new").length + selectedHooks.filter((h2) => h2.status === "new").length;
35812
35957
  const toUpdate = selectedItems.filter((i) => i.status === "modified").length + selectedHooks.filter((h2) => h2.status === "modified").length;
35813
35958
  const toRemove = selectedItems.filter((i) => i.status === "deleted").length;
35814
- const summary = [
35815
- toAdd > 0 ? `add ${toAdd}` : "",
35816
- toUpdate > 0 ? `update ${toUpdate}` : "",
35817
- toRemove > 0 ? `remove ${toRemove}` : ""
35818
- ].filter(Boolean).join(", ");
35959
+ f2.message("");
35960
+ f2.message(source_default.bold("What will happen:"));
35961
+ if (toAdd > 0)
35962
+ f2.message(source_default.green(` ✓ Add ${toAdd} new file${toAdd > 1 ? "s" : ""}`));
35963
+ if (toUpdate > 0)
35964
+ f2.message(source_default.yellow(` ✓ Update ${toUpdate} file${toUpdate > 1 ? "s" : ""}`));
35965
+ if (toRemove > 0)
35966
+ f2.message(source_default.red(` ✓ Delete ${toRemove} file${toRemove > 1 ? "s" : ""}`));
35967
+ f2.message(source_default.gray(` ✓ Backup current config to ~/.config/aiblueprint/backup/`));
35968
+ f2.message("");
35819
35969
  const confirmResult = await se({
35820
- message: `Proceed? (${summary})`,
35970
+ message: "Proceed with sync?",
35821
35971
  initialValue: true
35822
35972
  });
35823
35973
  if (lD(confirmResult) || !confirmResult) {
35824
35974
  ue("Sync cancelled");
35825
35975
  process.exit(0);
35826
35976
  }
35977
+ spinner.start("Creating backup...");
35978
+ const backupPath = await createBackup(claudeDir);
35979
+ if (backupPath) {
35980
+ spinner.stop(`Backup created: ${source_default.gray(backupPath)}`);
35981
+ } else {
35982
+ spinner.stop("No existing config to backup");
35983
+ }
35827
35984
  spinner.start("Syncing...");
35828
35985
  const syncResult = await syncSelectedItems(claudeDir, selectedItems, githubToken, (file, action) => {
35829
35986
  spinner.message(`${action}: ${source_default.cyan(file)}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiblueprint-cli",
3
- "version": "1.3.6",
3
+ "version": "1.4.0",
4
4
  "description": "AIBlueprint CLI for setting up Claude Code configurations",
5
5
  "author": "AIBlueprint",
6
6
  "license": "MIT",