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.
- package/dist/cli.js +320 -163
- 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
|
|
32492
|
-
import
|
|
32493
|
-
import
|
|
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 ?
|
|
33554
|
+
const claudeDir = customClaudeCodeFolder ? path8.resolve(customClaudeCodeFolder) : path8.join(os8.homedir(), ".claude");
|
|
33522
33555
|
console.log(source_default.gray(`Installing to: ${claudeDir}`));
|
|
33523
|
-
await
|
|
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
|
-
|
|
33537
|
-
|
|
33538
|
-
|
|
33539
|
-
|
|
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
|
|
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 =
|
|
33564
|
-
await
|
|
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",
|
|
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",
|
|
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",
|
|
33612
|
+
await downloadDirectoryFromGitHub("scripts/statusline", path8.join(scriptsDir, "statusline"));
|
|
33573
33613
|
}
|
|
33574
33614
|
} else {
|
|
33575
|
-
await
|
|
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",
|
|
33622
|
+
await downloadDirectoryFromGitHub("commands", path8.join(claudeDir, "commands"));
|
|
33583
33623
|
} else {
|
|
33584
|
-
await
|
|
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",
|
|
33641
|
+
await downloadDirectoryFromGitHub("agents", path8.join(claudeDir, "agents"));
|
|
33602
33642
|
} else {
|
|
33603
|
-
await
|
|
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",
|
|
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 =
|
|
33624
|
-
if (await
|
|
33625
|
-
await
|
|
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 =
|
|
33636
|
-
await
|
|
33637
|
-
await downloadFromGitHub("song/finish.mp3",
|
|
33638
|
-
await downloadFromGitHub("song/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
|
|
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 =
|
|
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
|
|
33698
|
-
import
|
|
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
|
|
33704
|
-
import
|
|
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
|
-
|
|
33736
|
-
|
|
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
|
|
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 =
|
|
33754
|
-
const isGitRepo = await
|
|
33755
|
-
const hasClaudeConfig = await
|
|
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
|
|
33799
|
+
return path9.join(process.env.HOME || process.env.USERPROFILE || "~", ".claude");
|
|
33760
33800
|
}
|
|
33761
33801
|
|
|
33762
33802
|
// src/utils/file-installer.ts
|
|
33763
|
-
var
|
|
33764
|
-
import
|
|
33803
|
+
var import_fs_extra9 = __toESM(require_lib4(), 1);
|
|
33804
|
+
import path11 from "path";
|
|
33765
33805
|
|
|
33766
33806
|
// src/utils/github.ts
|
|
33767
|
-
var
|
|
33768
|
-
import
|
|
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
|
|
33817
|
-
await
|
|
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
|
|
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 =
|
|
33841
|
-
if (!await
|
|
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
|
|
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 =
|
|
33860
|
-
if (!await
|
|
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
|
|
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 =
|
|
33906
|
-
const hookFilePath =
|
|
33907
|
-
const settingsPath =
|
|
33908
|
-
if (await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
33989
|
-
import
|
|
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
|
|
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(
|
|
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 =
|
|
34087
|
-
const commandFilePath =
|
|
34088
|
-
if (await
|
|
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
|
|
34296
|
-
import
|
|
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 ?
|
|
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
|
|
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 =
|
|
34309
|
-
await
|
|
34310
|
-
const success = await downloadDirectoryFromGitHub("scripts/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 =
|
|
34360
|
+
const settingsPath = path14.join(claudeDir, "settings.json");
|
|
34321
34361
|
let settings = {};
|
|
34322
34362
|
try {
|
|
34323
|
-
const existingSettings = await
|
|
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 ${
|
|
34369
|
+
command: `bun ${path14.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
34330
34370
|
padding: 0
|
|
34331
34371
|
};
|
|
34332
|
-
await
|
|
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
|
|
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
|
|
34943
|
-
import
|
|
35036
|
+
import os11 from "os";
|
|
35037
|
+
import path17 from "path";
|
|
34944
35038
|
|
|
34945
35039
|
// src/lib/pro-installer.ts
|
|
34946
|
-
var
|
|
34947
|
-
import
|
|
34948
|
-
import
|
|
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
|
|
34966
|
-
await
|
|
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
|
|
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 =
|
|
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 ||
|
|
35012
|
-
const tempDir =
|
|
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
|
|
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
|
|
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
|
|
35034
|
-
import
|
|
35035
|
-
import
|
|
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 =
|
|
35131
|
+
const platform = os10.platform();
|
|
35038
35132
|
if (platform === "win32") {
|
|
35039
|
-
const appData = process.env.APPDATA ||
|
|
35040
|
-
return
|
|
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 ||
|
|
35043
|
-
return
|
|
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
|
|
35141
|
+
return path16.join(getConfigDir(), "token.txt");
|
|
35048
35142
|
}
|
|
35049
35143
|
async function saveToken(githubToken) {
|
|
35050
35144
|
const tokenFile = getTokenFilePath();
|
|
35051
|
-
await
|
|
35052
|
-
await
|
|
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
|
|
35150
|
+
if (!await import_fs_extra14.default.pathExists(tokenFile)) {
|
|
35057
35151
|
return null;
|
|
35058
35152
|
}
|
|
35059
35153
|
try {
|
|
35060
|
-
const token = await
|
|
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:
|
|
35163
|
+
platform: os10.platform()
|
|
35070
35164
|
};
|
|
35071
35165
|
}
|
|
35072
35166
|
|
|
35073
35167
|
// src/commands/pro.ts
|
|
35074
|
-
var
|
|
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 =
|
|
35085
|
-
if (await
|
|
35086
|
-
const files = await
|
|
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 =
|
|
35093
|
-
if (await
|
|
35094
|
-
const files = await
|
|
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 =
|
|
35101
|
-
if (await
|
|
35102
|
-
const items = await
|
|
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
|
|
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 ?
|
|
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
|
|
35289
|
-
import
|
|
35382
|
+
import os12 from "os";
|
|
35383
|
+
import path19 from "path";
|
|
35290
35384
|
|
|
35291
35385
|
// src/lib/sync-utils.ts
|
|
35292
|
-
var
|
|
35293
|
-
import
|
|
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
|
|
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
|
|
35444
|
+
if (!await import_fs_extra16.default.pathExists(dir)) {
|
|
35351
35445
|
return files;
|
|
35352
35446
|
}
|
|
35353
|
-
const items = await
|
|
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 =
|
|
35358
|
-
const stat = await
|
|
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
|
|
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 =
|
|
35469
|
+
const fullPath = path18.join(dir, item);
|
|
35376
35470
|
const relativePath = `${basePath}/${item}`;
|
|
35377
|
-
const stat = await
|
|
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 =
|
|
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 =
|
|
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 =
|
|
35432
|
-
const stat = await
|
|
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 =
|
|
35557
|
+
const settingsPath = path18.join(claudeDir, "settings.json");
|
|
35464
35558
|
try {
|
|
35465
|
-
const content = await
|
|
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
|
|
35547
|
-
await
|
|
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 =
|
|
35651
|
+
const settingsPath = path18.join(claudeDir, "settings.json");
|
|
35558
35652
|
let settings = {};
|
|
35559
35653
|
try {
|
|
35560
|
-
const content = await
|
|
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
|
|
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 =
|
|
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
|
|
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 ?
|
|
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
|
|
35773
|
-
f2.message(` ${formatFolderSummary(
|
|
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
|
|
35794
|
-
|
|
35795
|
-
|
|
35796
|
-
|
|
35797
|
-
|
|
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
|
-
|
|
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
|
-
|
|
35804
|
-
|
|
35805
|
-
|
|
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
|
-
|
|
35815
|
-
|
|
35816
|
-
|
|
35817
|
-
|
|
35818
|
-
|
|
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:
|
|
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)}`);
|