aiblueprint-cli 1.3.6 → 1.4.1
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 +451 -205
- 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;
|
|
@@ -33212,16 +33212,94 @@ async function installStatuslineDependencies(claudeDir) {
|
|
|
33212
33212
|
// src/commands/setup/settings.ts
|
|
33213
33213
|
var import_fs_extra3 = __toESM(require_lib4(), 1);
|
|
33214
33214
|
import path5 from "path";
|
|
33215
|
+
|
|
33216
|
+
// src/lib/platform.ts
|
|
33215
33217
|
import os6 from "os";
|
|
33218
|
+
import { execSync as execSync2 } from "child_process";
|
|
33219
|
+
function escapeShellArg(arg) {
|
|
33220
|
+
return "'" + arg.replace(/'/g, "'\\''") + "'";
|
|
33221
|
+
}
|
|
33222
|
+
var cachedAudioPlayer = undefined;
|
|
33223
|
+
function detectAudioPlayer() {
|
|
33224
|
+
if (cachedAudioPlayer !== undefined)
|
|
33225
|
+
return cachedAudioPlayer;
|
|
33226
|
+
const platform = os6.platform();
|
|
33227
|
+
if (platform === "darwin") {
|
|
33228
|
+
cachedAudioPlayer = "afplay";
|
|
33229
|
+
return cachedAudioPlayer;
|
|
33230
|
+
}
|
|
33231
|
+
if (platform === "win32") {
|
|
33232
|
+
cachedAudioPlayer = "powershell";
|
|
33233
|
+
return cachedAudioPlayer;
|
|
33234
|
+
}
|
|
33235
|
+
const linuxPlayers = ["paplay", "aplay", "mpv", "ffplay"];
|
|
33236
|
+
for (const player of linuxPlayers) {
|
|
33237
|
+
try {
|
|
33238
|
+
execSync2(`which ${player}`, { stdio: "ignore" });
|
|
33239
|
+
cachedAudioPlayer = player;
|
|
33240
|
+
return cachedAudioPlayer;
|
|
33241
|
+
} catch {
|
|
33242
|
+
continue;
|
|
33243
|
+
}
|
|
33244
|
+
}
|
|
33245
|
+
cachedAudioPlayer = null;
|
|
33246
|
+
return cachedAudioPlayer;
|
|
33247
|
+
}
|
|
33216
33248
|
function getPlaySoundCommand(soundPath) {
|
|
33249
|
+
const player = detectAudioPlayer();
|
|
33250
|
+
if (!player)
|
|
33251
|
+
return null;
|
|
33217
33252
|
const platform = os6.platform();
|
|
33253
|
+
const safePath = escapeShellArg(soundPath);
|
|
33218
33254
|
if (platform === "darwin") {
|
|
33219
|
-
return `afplay -v 0.1
|
|
33220
|
-
} else if (platform === "win32") {
|
|
33221
|
-
return `powershell -c "(New-Object Media.SoundPlayer '${soundPath}').PlaySync()"`;
|
|
33222
|
-
} else {
|
|
33223
|
-
return `paplay "${soundPath}" 2>/dev/null || aplay "${soundPath}" 2>/dev/null || true`;
|
|
33255
|
+
return `afplay -v 0.1 ${safePath}`;
|
|
33224
33256
|
}
|
|
33257
|
+
if (platform === "win32") {
|
|
33258
|
+
const escapedPath = soundPath.replace(/'/g, "''");
|
|
33259
|
+
return `powershell -c "(New-Object Media.SoundPlayer '${escapedPath}').PlaySync()"`;
|
|
33260
|
+
}
|
|
33261
|
+
switch (player) {
|
|
33262
|
+
case "paplay":
|
|
33263
|
+
return `paplay ${safePath} 2>/dev/null || true`;
|
|
33264
|
+
case "aplay":
|
|
33265
|
+
return `aplay ${safePath} 2>/dev/null || true`;
|
|
33266
|
+
case "mpv":
|
|
33267
|
+
return `mpv --no-video --volume=10 ${safePath} 2>/dev/null || true`;
|
|
33268
|
+
case "ffplay":
|
|
33269
|
+
return `ffplay -nodisp -autoexit -volume 10 ${safePath} 2>/dev/null || true`;
|
|
33270
|
+
default:
|
|
33271
|
+
return null;
|
|
33272
|
+
}
|
|
33273
|
+
}
|
|
33274
|
+
var KNOWN_CLAUDE_PATHS = [
|
|
33275
|
+
/\/Users\/[^/]+\/\.claude\//,
|
|
33276
|
+
/\/home\/[^/]+\/\.claude\//,
|
|
33277
|
+
/C:\\Users\\[^\\]+\\\.claude\\/i
|
|
33278
|
+
];
|
|
33279
|
+
function transformHookCommand(command, claudeDir) {
|
|
33280
|
+
let transformed = command;
|
|
33281
|
+
for (const pattern of KNOWN_CLAUDE_PATHS) {
|
|
33282
|
+
transformed = transformed.replace(pattern, `${claudeDir}/`);
|
|
33283
|
+
}
|
|
33284
|
+
transformed = transformed.replace(/\\/g, "/");
|
|
33285
|
+
return transformed;
|
|
33286
|
+
}
|
|
33287
|
+
function transformHook(hook, claudeDir) {
|
|
33288
|
+
if (!hook)
|
|
33289
|
+
return hook;
|
|
33290
|
+
const transformed = { ...hook };
|
|
33291
|
+
if (transformed.command && typeof transformed.command === "string") {
|
|
33292
|
+
transformed.command = transformHookCommand(transformed.command, claudeDir);
|
|
33293
|
+
}
|
|
33294
|
+
if (Array.isArray(transformed.hooks)) {
|
|
33295
|
+
transformed.hooks = transformed.hooks.map((h) => transformHook(h, claudeDir));
|
|
33296
|
+
}
|
|
33297
|
+
return transformed;
|
|
33298
|
+
}
|
|
33299
|
+
|
|
33300
|
+
// src/commands/setup/settings.ts
|
|
33301
|
+
function toPosixPath(p) {
|
|
33302
|
+
return p.replace(/\\/g, "/");
|
|
33225
33303
|
}
|
|
33226
33304
|
async function hasExistingStatusLine(claudeDir) {
|
|
33227
33305
|
const settingsPath = path5.join(claudeDir, "settings.json");
|
|
@@ -33246,7 +33324,7 @@ async function updateSettings(options, claudeDir) {
|
|
|
33246
33324
|
if (shouldReplace) {
|
|
33247
33325
|
settings.statusLine = {
|
|
33248
33326
|
type: "command",
|
|
33249
|
-
command: `bun ${path5.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
33327
|
+
command: `bun ${toPosixPath(path5.join(claudeDir, "scripts/statusline/src/index.ts"))}`,
|
|
33250
33328
|
padding: 0
|
|
33251
33329
|
};
|
|
33252
33330
|
}
|
|
@@ -33263,7 +33341,7 @@ async function updateSettings(options, claudeDir) {
|
|
|
33263
33341
|
hooks: [
|
|
33264
33342
|
{
|
|
33265
33343
|
type: "command",
|
|
33266
|
-
command: `bun ${path5.join(claudeDir, "scripts/command-validator/src/cli.ts")}`
|
|
33344
|
+
command: `bun ${toPosixPath(path5.join(claudeDir, "scripts/command-validator/src/cli.ts"))}`
|
|
33267
33345
|
}
|
|
33268
33346
|
]
|
|
33269
33347
|
};
|
|
@@ -33273,39 +33351,45 @@ async function updateSettings(options, claudeDir) {
|
|
|
33273
33351
|
}
|
|
33274
33352
|
}
|
|
33275
33353
|
if (options.notificationSounds) {
|
|
33276
|
-
|
|
33277
|
-
|
|
33278
|
-
|
|
33279
|
-
|
|
33280
|
-
|
|
33281
|
-
|
|
33282
|
-
|
|
33283
|
-
|
|
33284
|
-
|
|
33285
|
-
|
|
33286
|
-
|
|
33287
|
-
|
|
33288
|
-
|
|
33289
|
-
|
|
33290
|
-
|
|
33291
|
-
settings.hooks.Stop.
|
|
33292
|
-
|
|
33293
|
-
|
|
33294
|
-
|
|
33354
|
+
const finishSoundPath = toPosixPath(path5.join(claudeDir, "song/finish.mp3"));
|
|
33355
|
+
const finishSoundCommand = getPlaySoundCommand(finishSoundPath);
|
|
33356
|
+
if (finishSoundCommand) {
|
|
33357
|
+
if (!settings.hooks.Stop) {
|
|
33358
|
+
settings.hooks.Stop = [];
|
|
33359
|
+
}
|
|
33360
|
+
const stopHook = {
|
|
33361
|
+
matcher: "",
|
|
33362
|
+
hooks: [
|
|
33363
|
+
{
|
|
33364
|
+
type: "command",
|
|
33365
|
+
command: finishSoundCommand
|
|
33366
|
+
}
|
|
33367
|
+
]
|
|
33368
|
+
};
|
|
33369
|
+
const existingStopHook = settings.hooks.Stop.find((h) => h.hooks?.some((hook) => hook.command?.includes("finish.mp3")));
|
|
33370
|
+
if (!existingStopHook) {
|
|
33371
|
+
settings.hooks.Stop.push(stopHook);
|
|
33372
|
+
}
|
|
33295
33373
|
}
|
|
33296
|
-
const needHumanSoundPath = path5.join(claudeDir, "song/need-human.mp3");
|
|
33297
|
-
const
|
|
33298
|
-
|
|
33299
|
-
hooks
|
|
33300
|
-
|
|
33301
|
-
|
|
33302
|
-
|
|
33303
|
-
|
|
33304
|
-
|
|
33305
|
-
|
|
33306
|
-
|
|
33307
|
-
|
|
33308
|
-
|
|
33374
|
+
const needHumanSoundPath = toPosixPath(path5.join(claudeDir, "song/need-human.mp3"));
|
|
33375
|
+
const needHumanSoundCommand = getPlaySoundCommand(needHumanSoundPath);
|
|
33376
|
+
if (needHumanSoundCommand) {
|
|
33377
|
+
if (!settings.hooks.Notification) {
|
|
33378
|
+
settings.hooks.Notification = [];
|
|
33379
|
+
}
|
|
33380
|
+
const notificationHook = {
|
|
33381
|
+
matcher: "",
|
|
33382
|
+
hooks: [
|
|
33383
|
+
{
|
|
33384
|
+
type: "command",
|
|
33385
|
+
command: needHumanSoundCommand
|
|
33386
|
+
}
|
|
33387
|
+
]
|
|
33388
|
+
};
|
|
33389
|
+
const existingNotificationHook = settings.hooks.Notification.find((h) => h.hooks?.some((hook) => hook.command?.includes("need-human.mp3")));
|
|
33390
|
+
if (!existingNotificationHook) {
|
|
33391
|
+
settings.hooks.Notification.push(notificationHook);
|
|
33392
|
+
}
|
|
33309
33393
|
}
|
|
33310
33394
|
}
|
|
33311
33395
|
if (options.postEditTypeScript) {
|
|
@@ -33317,7 +33401,7 @@ async function updateSettings(options, claudeDir) {
|
|
|
33317
33401
|
hooks: [
|
|
33318
33402
|
{
|
|
33319
33403
|
type: "command",
|
|
33320
|
-
command: `bun ${path5.join(claudeDir, "scripts/hook-post-file.ts")}`
|
|
33404
|
+
command: `bun ${toPosixPath(path5.join(claudeDir, "scripts/hook-post-file.ts"))}`
|
|
33321
33405
|
}
|
|
33322
33406
|
]
|
|
33323
33407
|
};
|
|
@@ -33415,6 +33499,39 @@ function getVersion() {
|
|
|
33415
33499
|
}
|
|
33416
33500
|
}
|
|
33417
33501
|
|
|
33502
|
+
// src/lib/backup-utils.ts
|
|
33503
|
+
var import_fs_extra5 = __toESM(require_lib4(), 1);
|
|
33504
|
+
import path7 from "path";
|
|
33505
|
+
import os7 from "os";
|
|
33506
|
+
var BACKUP_BASE_DIR = path7.join(os7.homedir(), ".config", "aiblueprint", "backup");
|
|
33507
|
+
function formatDate(date) {
|
|
33508
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
33509
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
|
|
33510
|
+
}
|
|
33511
|
+
async function createBackup(claudeDir) {
|
|
33512
|
+
const exists = await import_fs_extra5.default.pathExists(claudeDir);
|
|
33513
|
+
if (!exists) {
|
|
33514
|
+
return null;
|
|
33515
|
+
}
|
|
33516
|
+
const files = await import_fs_extra5.default.readdir(claudeDir);
|
|
33517
|
+
const hasContent = files.some((f) => f !== ".DS_Store");
|
|
33518
|
+
if (!hasContent) {
|
|
33519
|
+
return null;
|
|
33520
|
+
}
|
|
33521
|
+
const timestamp = formatDate(new Date);
|
|
33522
|
+
const backupPath = path7.join(BACKUP_BASE_DIR, timestamp);
|
|
33523
|
+
await import_fs_extra5.default.ensureDir(backupPath);
|
|
33524
|
+
const itemsToCopy = ["commands", "agents", "skills", "scripts", "song", "settings.json"];
|
|
33525
|
+
for (const item of itemsToCopy) {
|
|
33526
|
+
const sourcePath = path7.join(claudeDir, item);
|
|
33527
|
+
const destPath = path7.join(backupPath, item);
|
|
33528
|
+
if (await import_fs_extra5.default.pathExists(sourcePath)) {
|
|
33529
|
+
await import_fs_extra5.default.copy(sourcePath, destPath, { overwrite: true });
|
|
33530
|
+
}
|
|
33531
|
+
}
|
|
33532
|
+
return backupPath;
|
|
33533
|
+
}
|
|
33534
|
+
|
|
33418
33535
|
// src/commands/setup.ts
|
|
33419
33536
|
var __filename2 = fileURLToPath2(import.meta.url);
|
|
33420
33537
|
var __dirname2 = dirname2(__filename2);
|
|
@@ -33518,9 +33635,16 @@ async function setupCommand(params = {}) {
|
|
|
33518
33635
|
skipInteractive
|
|
33519
33636
|
};
|
|
33520
33637
|
const s = new SimpleSpinner;
|
|
33521
|
-
const claudeDir = customClaudeCodeFolder ?
|
|
33638
|
+
const claudeDir = customClaudeCodeFolder ? path8.resolve(customClaudeCodeFolder) : path8.join(os8.homedir(), ".claude");
|
|
33522
33639
|
console.log(source_default.gray(`Installing to: ${claudeDir}`));
|
|
33523
|
-
await
|
|
33640
|
+
await import_fs_extra6.default.ensureDir(claudeDir);
|
|
33641
|
+
s.start("Creating backup of existing configuration");
|
|
33642
|
+
const backupPath = await createBackup(claudeDir);
|
|
33643
|
+
if (backupPath) {
|
|
33644
|
+
s.stop(`Backup created: ${source_default.gray(backupPath)}`);
|
|
33645
|
+
} else {
|
|
33646
|
+
s.stop("No existing config to backup");
|
|
33647
|
+
}
|
|
33524
33648
|
let useGitHub = true;
|
|
33525
33649
|
let sourceDir;
|
|
33526
33650
|
const testUrl = `${GITHUB_RAW_BASE2}/scripts/validate-command.js`;
|
|
@@ -33533,14 +33657,14 @@ async function setupCommand(params = {}) {
|
|
|
33533
33657
|
if (!useGitHub) {
|
|
33534
33658
|
const currentDir = process.cwd();
|
|
33535
33659
|
const possiblePaths = [
|
|
33536
|
-
|
|
33537
|
-
|
|
33538
|
-
|
|
33539
|
-
|
|
33660
|
+
path8.join(currentDir, "claude-code-config"),
|
|
33661
|
+
path8.join(__dirname2, "../../claude-code-config"),
|
|
33662
|
+
path8.join(__dirname2, "../claude-code-config"),
|
|
33663
|
+
path8.join(path8.dirname(process.argv[1]), "../claude-code-config")
|
|
33540
33664
|
];
|
|
33541
33665
|
sourceDir = possiblePaths.find((p) => {
|
|
33542
33666
|
try {
|
|
33543
|
-
return
|
|
33667
|
+
return import_fs_extra6.default.existsSync(p);
|
|
33544
33668
|
} catch {
|
|
33545
33669
|
return false;
|
|
33546
33670
|
}
|
|
@@ -33560,28 +33684,32 @@ async function setupCommand(params = {}) {
|
|
|
33560
33684
|
if (options.commandValidation || options.customStatusline || options.notificationSounds || options.postEditTypeScript) {
|
|
33561
33685
|
s.start("Setting up scripts");
|
|
33562
33686
|
if (useGitHub) {
|
|
33563
|
-
const scriptsDir =
|
|
33564
|
-
await
|
|
33687
|
+
const scriptsDir = path8.join(claudeDir, "scripts");
|
|
33688
|
+
await import_fs_extra6.default.ensureDir(scriptsDir);
|
|
33565
33689
|
if (options.commandValidation) {
|
|
33566
|
-
await downloadDirectoryFromGitHub("scripts/command-validator",
|
|
33690
|
+
await downloadDirectoryFromGitHub("scripts/command-validator", path8.join(scriptsDir, "command-validator"));
|
|
33567
33691
|
}
|
|
33568
33692
|
if (options.postEditTypeScript) {
|
|
33569
|
-
await downloadFromGitHub("scripts/hook-post-file.ts",
|
|
33693
|
+
await downloadFromGitHub("scripts/hook-post-file.ts", path8.join(scriptsDir, "hook-post-file.ts"));
|
|
33570
33694
|
}
|
|
33571
33695
|
if (options.customStatusline) {
|
|
33572
|
-
await downloadDirectoryFromGitHub("scripts/statusline",
|
|
33696
|
+
await downloadDirectoryFromGitHub("scripts/statusline", path8.join(scriptsDir, "statusline"));
|
|
33697
|
+
await import_fs_extra6.default.ensureDir(path8.join(scriptsDir, "statusline/data"));
|
|
33573
33698
|
}
|
|
33574
33699
|
} else {
|
|
33575
|
-
await
|
|
33700
|
+
await import_fs_extra6.default.copy(path8.join(sourceDir, "scripts"), path8.join(claudeDir, "scripts"), { overwrite: true });
|
|
33701
|
+
if (options.customStatusline) {
|
|
33702
|
+
await import_fs_extra6.default.ensureDir(path8.join(claudeDir, "scripts/statusline/data"));
|
|
33703
|
+
}
|
|
33576
33704
|
}
|
|
33577
33705
|
s.stop("Scripts installed");
|
|
33578
33706
|
}
|
|
33579
33707
|
if (options.aiblueprintCommands) {
|
|
33580
33708
|
s.start("Setting up AIBlueprint commands");
|
|
33581
33709
|
if (useGitHub) {
|
|
33582
|
-
await downloadDirectoryFromGitHub("commands",
|
|
33710
|
+
await downloadDirectoryFromGitHub("commands", path8.join(claudeDir, "commands"));
|
|
33583
33711
|
} else {
|
|
33584
|
-
await
|
|
33712
|
+
await import_fs_extra6.default.copy(path8.join(sourceDir, "commands"), path8.join(claudeDir, "commands"), { overwrite: true });
|
|
33585
33713
|
}
|
|
33586
33714
|
s.stop("Commands installed");
|
|
33587
33715
|
}
|
|
@@ -33598,9 +33726,9 @@ async function setupCommand(params = {}) {
|
|
|
33598
33726
|
if (options.aiblueprintAgents) {
|
|
33599
33727
|
s.start("Setting up AIBlueprint agents");
|
|
33600
33728
|
if (useGitHub) {
|
|
33601
|
-
await downloadDirectoryFromGitHub("agents",
|
|
33729
|
+
await downloadDirectoryFromGitHub("agents", path8.join(claudeDir, "agents"));
|
|
33602
33730
|
} else {
|
|
33603
|
-
await
|
|
33731
|
+
await import_fs_extra6.default.copy(path8.join(sourceDir, "agents"), path8.join(claudeDir, "agents"), { overwrite: true });
|
|
33604
33732
|
}
|
|
33605
33733
|
s.stop("Agents installed");
|
|
33606
33734
|
}
|
|
@@ -33611,7 +33739,7 @@ async function setupCommand(params = {}) {
|
|
|
33611
33739
|
try {
|
|
33612
33740
|
const testResponse = await fetch(testSkillsUrl);
|
|
33613
33741
|
if (testResponse.ok) {
|
|
33614
|
-
await downloadDirectoryFromGitHub("skills",
|
|
33742
|
+
await downloadDirectoryFromGitHub("skills", path8.join(claudeDir, "skills"));
|
|
33615
33743
|
s.stop("Skills installed");
|
|
33616
33744
|
} else {
|
|
33617
33745
|
s.stop("Skills not available in repository");
|
|
@@ -33620,9 +33748,9 @@ async function setupCommand(params = {}) {
|
|
|
33620
33748
|
s.stop("Skills not available in repository");
|
|
33621
33749
|
}
|
|
33622
33750
|
} else {
|
|
33623
|
-
const skillsSourcePath =
|
|
33624
|
-
if (await
|
|
33625
|
-
await
|
|
33751
|
+
const skillsSourcePath = path8.join(sourceDir, "skills");
|
|
33752
|
+
if (await import_fs_extra6.default.pathExists(skillsSourcePath)) {
|
|
33753
|
+
await import_fs_extra6.default.copy(skillsSourcePath, path8.join(claudeDir, "skills"), { overwrite: true });
|
|
33626
33754
|
s.stop("Skills installed");
|
|
33627
33755
|
} else {
|
|
33628
33756
|
s.stop("Skills not available in local repository");
|
|
@@ -33632,12 +33760,12 @@ async function setupCommand(params = {}) {
|
|
|
33632
33760
|
if (options.notificationSounds) {
|
|
33633
33761
|
s.start("Setting up notification sounds");
|
|
33634
33762
|
if (useGitHub) {
|
|
33635
|
-
const songDir =
|
|
33636
|
-
await
|
|
33637
|
-
await downloadFromGitHub("song/finish.mp3",
|
|
33638
|
-
await downloadFromGitHub("song/need-human.mp3",
|
|
33763
|
+
const songDir = path8.join(claudeDir, "song");
|
|
33764
|
+
await import_fs_extra6.default.ensureDir(songDir);
|
|
33765
|
+
await downloadFromGitHub("song/finish.mp3", path8.join(songDir, "finish.mp3"));
|
|
33766
|
+
await downloadFromGitHub("song/need-human.mp3", path8.join(songDir, "need-human.mp3"));
|
|
33639
33767
|
} else {
|
|
33640
|
-
await
|
|
33768
|
+
await import_fs_extra6.default.copy(path8.join(sourceDir, "song"), path8.join(claudeDir, "song"), { overwrite: true });
|
|
33641
33769
|
}
|
|
33642
33770
|
s.stop("Notification sounds installed");
|
|
33643
33771
|
}
|
|
@@ -33673,7 +33801,7 @@ async function setupCommand(params = {}) {
|
|
|
33673
33801
|
console.log(source_default.gray(`
|
|
33674
33802
|
Next steps:`));
|
|
33675
33803
|
if (options.shellShortcuts) {
|
|
33676
|
-
const platform =
|
|
33804
|
+
const platform = os8.platform();
|
|
33677
33805
|
if (platform === "win32") {
|
|
33678
33806
|
console.log(source_default.gray(" • Restart PowerShell to load the new functions"));
|
|
33679
33807
|
} else {
|
|
@@ -33694,14 +33822,14 @@ Next steps:`));
|
|
|
33694
33822
|
}
|
|
33695
33823
|
|
|
33696
33824
|
// src/commands/addHook.ts
|
|
33697
|
-
var
|
|
33698
|
-
import
|
|
33825
|
+
var import_fs_extra10 = __toESM(require_lib4(), 1);
|
|
33826
|
+
import path12 from "path";
|
|
33699
33827
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
33700
33828
|
import { dirname as dirname4 } from "path";
|
|
33701
33829
|
|
|
33702
33830
|
// src/utils/claude-config.ts
|
|
33703
|
-
var
|
|
33704
|
-
import
|
|
33831
|
+
var import_fs_extra7 = __toESM(require_lib4(), 1);
|
|
33832
|
+
import path9 from "path";
|
|
33705
33833
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
33706
33834
|
import { dirname as dirname3 } from "path";
|
|
33707
33835
|
var __filename3 = fileURLToPath3(import.meta.url);
|
|
@@ -33732,14 +33860,14 @@ function parseYamlFrontmatter(content) {
|
|
|
33732
33860
|
}
|
|
33733
33861
|
function getLocalConfigPaths(subDir) {
|
|
33734
33862
|
return [
|
|
33735
|
-
|
|
33736
|
-
|
|
33863
|
+
path9.join(__dirname3, `../claude-code-config/${subDir}`),
|
|
33864
|
+
path9.join(__dirname3, `../../claude-code-config/${subDir}`)
|
|
33737
33865
|
];
|
|
33738
33866
|
}
|
|
33739
33867
|
async function findLocalConfigDir(subDir) {
|
|
33740
33868
|
const possiblePaths = getLocalConfigPaths(subDir);
|
|
33741
33869
|
for (const testPath of possiblePaths) {
|
|
33742
|
-
if (await
|
|
33870
|
+
if (await import_fs_extra7.default.pathExists(testPath)) {
|
|
33743
33871
|
return testPath;
|
|
33744
33872
|
}
|
|
33745
33873
|
}
|
|
@@ -33750,22 +33878,22 @@ async function getTargetDirectory(options) {
|
|
|
33750
33878
|
return options.folder;
|
|
33751
33879
|
}
|
|
33752
33880
|
const cwd = process.cwd();
|
|
33753
|
-
const localClaudeDir =
|
|
33754
|
-
const isGitRepo = await
|
|
33755
|
-
const hasClaudeConfig = await
|
|
33881
|
+
const localClaudeDir = path9.join(cwd, ".claude");
|
|
33882
|
+
const isGitRepo = await import_fs_extra7.default.pathExists(path9.join(cwd, ".git"));
|
|
33883
|
+
const hasClaudeConfig = await import_fs_extra7.default.pathExists(localClaudeDir);
|
|
33756
33884
|
if (isGitRepo || hasClaudeConfig) {
|
|
33757
33885
|
return localClaudeDir;
|
|
33758
33886
|
}
|
|
33759
|
-
return
|
|
33887
|
+
return path9.join(process.env.HOME || process.env.USERPROFILE || "~", ".claude");
|
|
33760
33888
|
}
|
|
33761
33889
|
|
|
33762
33890
|
// src/utils/file-installer.ts
|
|
33763
|
-
var
|
|
33764
|
-
import
|
|
33891
|
+
var import_fs_extra9 = __toESM(require_lib4(), 1);
|
|
33892
|
+
import path11 from "path";
|
|
33765
33893
|
|
|
33766
33894
|
// src/utils/github.ts
|
|
33767
|
-
var
|
|
33768
|
-
import
|
|
33895
|
+
var import_fs_extra8 = __toESM(require_lib4(), 1);
|
|
33896
|
+
import path10 from "path";
|
|
33769
33897
|
var GITHUB_RAW_BASE3 = "https://raw.githubusercontent.com/Melvynx/aiblueprint-cli/main/claude-code-config";
|
|
33770
33898
|
async function downloadFromGitHub2(relativePath) {
|
|
33771
33899
|
try {
|
|
@@ -33813,8 +33941,8 @@ async function isGitHubAvailable() {
|
|
|
33813
33941
|
async function downloadAndWriteFile(relativePath, targetPath) {
|
|
33814
33942
|
const content = await downloadFromGitHub2(relativePath);
|
|
33815
33943
|
if (content) {
|
|
33816
|
-
await
|
|
33817
|
-
await
|
|
33944
|
+
await import_fs_extra8.default.ensureDir(path10.dirname(targetPath));
|
|
33945
|
+
await import_fs_extra8.default.writeFile(targetPath, content);
|
|
33818
33946
|
return true;
|
|
33819
33947
|
}
|
|
33820
33948
|
return false;
|
|
@@ -33823,7 +33951,7 @@ async function downloadAndWriteFile(relativePath, targetPath) {
|
|
|
33823
33951
|
// src/utils/file-installer.ts
|
|
33824
33952
|
async function installFileWithGitHubFallback(options) {
|
|
33825
33953
|
const { sourceDir, targetPath, fileName } = options;
|
|
33826
|
-
await
|
|
33954
|
+
await import_fs_extra9.default.ensureDir(path11.dirname(targetPath));
|
|
33827
33955
|
const useGitHub = options.useGitHub ?? await isGitHubAvailable();
|
|
33828
33956
|
if (useGitHub) {
|
|
33829
33957
|
const relativePath = `${sourceDir}/${fileName}`;
|
|
@@ -33837,11 +33965,11 @@ async function installFileWithGitHubFallback(options) {
|
|
|
33837
33965
|
if (!localConfigDir) {
|
|
33838
33966
|
throw new Error(`Neither GitHub nor local ${sourceDir} directory found`);
|
|
33839
33967
|
}
|
|
33840
|
-
const localFilePath =
|
|
33841
|
-
if (!await
|
|
33968
|
+
const localFilePath = path11.join(localConfigDir, fileName);
|
|
33969
|
+
if (!await import_fs_extra9.default.pathExists(localFilePath)) {
|
|
33842
33970
|
throw new Error(`File not found: ${fileName}`);
|
|
33843
33971
|
}
|
|
33844
|
-
await
|
|
33972
|
+
await import_fs_extra9.default.copy(localFilePath, targetPath);
|
|
33845
33973
|
}
|
|
33846
33974
|
async function getFileContentWithGitHubFallback(sourceDir, fileName) {
|
|
33847
33975
|
const useGitHub = await isGitHubAvailable();
|
|
@@ -33856,11 +33984,11 @@ async function getFileContentWithGitHubFallback(sourceDir, fileName) {
|
|
|
33856
33984
|
if (!localConfigDir) {
|
|
33857
33985
|
throw new Error(`Neither GitHub nor local ${sourceDir} directory found`);
|
|
33858
33986
|
}
|
|
33859
|
-
const localFilePath =
|
|
33860
|
-
if (!await
|
|
33987
|
+
const localFilePath = path11.join(localConfigDir, fileName);
|
|
33988
|
+
if (!await import_fs_extra9.default.pathExists(localFilePath)) {
|
|
33861
33989
|
throw new Error(`File not found: ${fileName}`);
|
|
33862
33990
|
}
|
|
33863
|
-
return await
|
|
33991
|
+
return await import_fs_extra9.default.readFile(localFilePath, "utf-8");
|
|
33864
33992
|
}
|
|
33865
33993
|
|
|
33866
33994
|
// src/commands/addHook.ts
|
|
@@ -33902,10 +34030,10 @@ async function addHookCommand(hookType, options) {
|
|
|
33902
34030
|
const s = new SimpleSpinner2;
|
|
33903
34031
|
const targetDir = await getTargetDirectory(options);
|
|
33904
34032
|
const claudeDir = targetDir;
|
|
33905
|
-
const targetHookDir =
|
|
33906
|
-
const hookFilePath =
|
|
33907
|
-
const settingsPath =
|
|
33908
|
-
if (await
|
|
34033
|
+
const targetHookDir = path12.join(claudeDir, hook.targetDir || "hooks");
|
|
34034
|
+
const hookFilePath = path12.join(targetHookDir, hook.hookFile);
|
|
34035
|
+
const settingsPath = path12.join(claudeDir, "settings.json");
|
|
34036
|
+
if (await import_fs_extra10.default.pathExists(hookFilePath)) {
|
|
33909
34037
|
const overwriteAnswer = await lib_default.prompt([{
|
|
33910
34038
|
type: "confirm",
|
|
33911
34039
|
name: "overwrite",
|
|
@@ -33918,18 +34046,18 @@ async function addHookCommand(hookType, options) {
|
|
|
33918
34046
|
}
|
|
33919
34047
|
try {
|
|
33920
34048
|
s.start("Installing hook...");
|
|
33921
|
-
await
|
|
34049
|
+
await import_fs_extra10.default.ensureDir(targetHookDir);
|
|
33922
34050
|
await installFileWithGitHubFallback({
|
|
33923
34051
|
sourceDir: hook.sourceDir || "hooks",
|
|
33924
34052
|
targetPath: hookFilePath,
|
|
33925
34053
|
fileName: hook.hookFile
|
|
33926
34054
|
});
|
|
33927
|
-
await
|
|
34055
|
+
await import_fs_extra10.default.chmod(hookFilePath, 493);
|
|
33928
34056
|
s.stop("Hook file installed");
|
|
33929
34057
|
s.start("Updating settings.json...");
|
|
33930
34058
|
let settings = {};
|
|
33931
34059
|
try {
|
|
33932
|
-
const existingSettings = await
|
|
34060
|
+
const existingSettings = await import_fs_extra10.default.readFile(settingsPath, "utf-8");
|
|
33933
34061
|
settings = JSON.parse(existingSettings);
|
|
33934
34062
|
} catch {
|
|
33935
34063
|
settings = {};
|
|
@@ -33966,7 +34094,7 @@ async function addHookCommand(hookType, options) {
|
|
|
33966
34094
|
} else {
|
|
33967
34095
|
settings.hooks[hook.event].push(newHook);
|
|
33968
34096
|
}
|
|
33969
|
-
await
|
|
34097
|
+
await import_fs_extra10.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
33970
34098
|
s.stop("Settings updated");
|
|
33971
34099
|
console.log(source_default.green("✨ Hook installed successfully!"));
|
|
33972
34100
|
console.log(source_default.gray(`
|
|
@@ -33985,8 +34113,8 @@ The hook will run automatically when you edit TypeScript files with Claude Code.
|
|
|
33985
34113
|
}
|
|
33986
34114
|
|
|
33987
34115
|
// src/commands/addCommand.ts
|
|
33988
|
-
var
|
|
33989
|
-
import
|
|
34116
|
+
var import_fs_extra11 = __toESM(require_lib4(), 1);
|
|
34117
|
+
import path13 from "path";
|
|
33990
34118
|
class SimpleSpinner3 {
|
|
33991
34119
|
message = "";
|
|
33992
34120
|
start(message) {
|
|
@@ -33999,11 +34127,11 @@ class SimpleSpinner3 {
|
|
|
33999
34127
|
}
|
|
34000
34128
|
async function getLocalMdFilesRecursively(dir, basePath = "") {
|
|
34001
34129
|
const files = [];
|
|
34002
|
-
const entries = await
|
|
34130
|
+
const entries = await import_fs_extra11.default.readdir(dir, { withFileTypes: true });
|
|
34003
34131
|
for (const entry of entries) {
|
|
34004
34132
|
const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;
|
|
34005
34133
|
if (entry.isDirectory()) {
|
|
34006
|
-
const subFiles = await getLocalMdFilesRecursively(
|
|
34134
|
+
const subFiles = await getLocalMdFilesRecursively(path13.join(dir, entry.name), relativePath);
|
|
34007
34135
|
files.push(...subFiles);
|
|
34008
34136
|
} else if (entry.name.endsWith(".md")) {
|
|
34009
34137
|
files.push(relativePath);
|
|
@@ -34083,9 +34211,9 @@ async function addCommandCommand(commandName, options = {}) {
|
|
|
34083
34211
|
if (options.folder) {
|
|
34084
34212
|
console.log(source_default.gray(`Using custom folder: ${targetDir}`));
|
|
34085
34213
|
}
|
|
34086
|
-
const commandsDir =
|
|
34087
|
-
const commandFilePath =
|
|
34088
|
-
if (await
|
|
34214
|
+
const commandsDir = path13.join(targetDir, "commands");
|
|
34215
|
+
const commandFilePath = path13.join(commandsDir, command.commandFile);
|
|
34216
|
+
if (await import_fs_extra11.default.pathExists(commandFilePath)) {
|
|
34089
34217
|
const overwriteAnswer = await lib_default.prompt([{
|
|
34090
34218
|
type: "confirm",
|
|
34091
34219
|
name: "overwrite",
|
|
@@ -34292,22 +34420,22 @@ async function symlinkCommand(params = {}) {
|
|
|
34292
34420
|
}
|
|
34293
34421
|
|
|
34294
34422
|
// src/commands/statusline.ts
|
|
34295
|
-
var
|
|
34296
|
-
import
|
|
34423
|
+
var import_fs_extra12 = __toESM(require_lib4(), 1);
|
|
34424
|
+
import path14 from "path";
|
|
34297
34425
|
import { homedir } from "os";
|
|
34298
34426
|
async function statuslineCommand(options) {
|
|
34299
|
-
const claudeDir = options.folder ?
|
|
34427
|
+
const claudeDir = options.folder ? path14.resolve(options.folder) : path14.join(homedir(), ".claude");
|
|
34300
34428
|
console.log(source_default.blue(`\uD83D\uDE80 Setting up AIBlueprint Statusline ${source_default.gray(`v${getVersion()}`)}...`));
|
|
34301
34429
|
console.log(source_default.gray(` Target: ${claudeDir}
|
|
34302
34430
|
`));
|
|
34303
|
-
await
|
|
34431
|
+
await import_fs_extra12.default.ensureDir(claudeDir);
|
|
34304
34432
|
console.log(source_default.cyan("\uD83D\uDCE6 Checking dependencies..."));
|
|
34305
34433
|
await checkAndInstallDependencies();
|
|
34306
34434
|
console.log(source_default.cyan(`
|
|
34307
34435
|
\uD83D\uDCE5 Downloading statusline files...`));
|
|
34308
|
-
const scriptsDir =
|
|
34309
|
-
await
|
|
34310
|
-
const success = await downloadDirectoryFromGitHub("scripts/statusline",
|
|
34436
|
+
const scriptsDir = path14.join(claudeDir, "scripts");
|
|
34437
|
+
await import_fs_extra12.default.ensureDir(scriptsDir);
|
|
34438
|
+
const success = await downloadDirectoryFromGitHub("scripts/statusline", path14.join(scriptsDir, "statusline"));
|
|
34311
34439
|
if (!success) {
|
|
34312
34440
|
console.log(source_default.red(" Failed to download statusline files from GitHub"));
|
|
34313
34441
|
return;
|
|
@@ -34317,19 +34445,19 @@ async function statuslineCommand(options) {
|
|
|
34317
34445
|
await installStatuslineDependencies(claudeDir);
|
|
34318
34446
|
console.log(source_default.cyan(`
|
|
34319
34447
|
⚙️ Configuring settings.json...`));
|
|
34320
|
-
const settingsPath =
|
|
34448
|
+
const settingsPath = path14.join(claudeDir, "settings.json");
|
|
34321
34449
|
let settings = {};
|
|
34322
34450
|
try {
|
|
34323
|
-
const existingSettings = await
|
|
34451
|
+
const existingSettings = await import_fs_extra12.default.readFile(settingsPath, "utf-8");
|
|
34324
34452
|
settings = JSON.parse(existingSettings);
|
|
34325
34453
|
} catch {
|
|
34326
34454
|
}
|
|
34327
34455
|
settings.statusLine = {
|
|
34328
34456
|
type: "command",
|
|
34329
|
-
command: `bun ${
|
|
34457
|
+
command: `bun ${path14.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
34330
34458
|
padding: 0
|
|
34331
34459
|
};
|
|
34332
|
-
await
|
|
34460
|
+
await import_fs_extra12.default.writeJson(settingsPath, settings, { spaces: 2 });
|
|
34333
34461
|
console.log(source_default.green(`
|
|
34334
34462
|
✅ Statusline setup complete!`));
|
|
34335
34463
|
console.log(source_default.gray(`
|
|
@@ -34704,6 +34832,32 @@ var vD = class extends x {
|
|
|
34704
34832
|
this.value = u ? this.value.filter((F) => F !== this._value) : [...this.value, this._value];
|
|
34705
34833
|
}
|
|
34706
34834
|
};
|
|
34835
|
+
var wD = Object.defineProperty;
|
|
34836
|
+
var yD = (e, u, F) => (u in e) ? wD(e, u, { enumerable: true, configurable: true, writable: true, value: F }) : e[u] = F;
|
|
34837
|
+
var Z = (e, u, F) => (yD(e, typeof u != "symbol" ? u + "" : u, F), F);
|
|
34838
|
+
var $D = class extends x {
|
|
34839
|
+
constructor(u) {
|
|
34840
|
+
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) => {
|
|
34841
|
+
switch (F) {
|
|
34842
|
+
case "left":
|
|
34843
|
+
case "up":
|
|
34844
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
34845
|
+
break;
|
|
34846
|
+
case "down":
|
|
34847
|
+
case "right":
|
|
34848
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
34849
|
+
break;
|
|
34850
|
+
}
|
|
34851
|
+
this.changeValue();
|
|
34852
|
+
});
|
|
34853
|
+
}
|
|
34854
|
+
get _value() {
|
|
34855
|
+
return this.options[this.cursor];
|
|
34856
|
+
}
|
|
34857
|
+
changeValue() {
|
|
34858
|
+
this.value = this._value.value;
|
|
34859
|
+
}
|
|
34860
|
+
};
|
|
34707
34861
|
var TD = Object.defineProperty;
|
|
34708
34862
|
var jD = (e, u, F) => (u in e) ? TD(e, u, { enumerable: true, configurable: true, writable: true, value: F }) : e[u] = F;
|
|
34709
34863
|
var MD = (e, u, F) => (jD(e, typeof u != "symbol" ? u + "" : u, F), F);
|
|
@@ -34771,7 +34925,7 @@ var w2 = o("◼", "[+]");
|
|
|
34771
34925
|
var M2 = o("◻", "[ ]");
|
|
34772
34926
|
var U2 = o("▪", "•");
|
|
34773
34927
|
var B = o("─", "-");
|
|
34774
|
-
var
|
|
34928
|
+
var Z2 = o("╮", "+");
|
|
34775
34929
|
var z2 = o("├", "+");
|
|
34776
34930
|
var X2 = o("╯", "+");
|
|
34777
34931
|
var J2 = o("●", "•");
|
|
@@ -34831,6 +34985,34 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
34831
34985
|
}
|
|
34832
34986
|
} }).prompt();
|
|
34833
34987
|
};
|
|
34988
|
+
var ie = (r2) => {
|
|
34989
|
+
const n = (t, s) => {
|
|
34990
|
+
const c2 = t.label ?? String(t.value);
|
|
34991
|
+
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)}`;
|
|
34992
|
+
};
|
|
34993
|
+
let i = 0;
|
|
34994
|
+
return new $D({ options: r2.options, initialValue: r2.initialValue, render() {
|
|
34995
|
+
const t = `${import_picocolors2.default.gray(a2)}
|
|
34996
|
+
${y2(this.state)} ${r2.message}
|
|
34997
|
+
`;
|
|
34998
|
+
switch (this.state) {
|
|
34999
|
+
case "submit":
|
|
35000
|
+
return `${t}${import_picocolors2.default.gray(a2)} ${n(this.options[this.cursor], "selected")}`;
|
|
35001
|
+
case "cancel":
|
|
35002
|
+
return `${t}${import_picocolors2.default.gray(a2)} ${n(this.options[this.cursor], "cancelled")}
|
|
35003
|
+
${import_picocolors2.default.gray(a2)}`;
|
|
35004
|
+
default: {
|
|
35005
|
+
const s = r2.maxItems === undefined ? 1 / 0 : Math.max(r2.maxItems, 5);
|
|
35006
|
+
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));
|
|
35007
|
+
const c2 = s < this.options.length && i > 0, l2 = s < this.options.length && i + s < this.options.length;
|
|
35008
|
+
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(`
|
|
35009
|
+
${import_picocolors2.default.cyan(a2)} `)}
|
|
35010
|
+
${import_picocolors2.default.cyan(d2)}
|
|
35011
|
+
`;
|
|
35012
|
+
}
|
|
35013
|
+
}
|
|
35014
|
+
} }).prompt();
|
|
35015
|
+
};
|
|
34834
35016
|
var ae = (r2) => {
|
|
34835
35017
|
const n = (i, t) => {
|
|
34836
35018
|
const s = i.label ?? String(i.value);
|
|
@@ -34939,13 +35121,13 @@ var de = () => {
|
|
|
34939
35121
|
};
|
|
34940
35122
|
|
|
34941
35123
|
// src/commands/pro.ts
|
|
34942
|
-
import
|
|
34943
|
-
import
|
|
35124
|
+
import os11 from "os";
|
|
35125
|
+
import path17 from "path";
|
|
34944
35126
|
|
|
34945
35127
|
// src/lib/pro-installer.ts
|
|
34946
|
-
var
|
|
34947
|
-
import
|
|
34948
|
-
import
|
|
35128
|
+
var import_fs_extra13 = __toESM(require_lib4(), 1);
|
|
35129
|
+
import os9 from "os";
|
|
35130
|
+
import path15 from "path";
|
|
34949
35131
|
var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
|
|
34950
35132
|
var PREMIUM_BRANCH = "main";
|
|
34951
35133
|
async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath, githubToken) {
|
|
@@ -34962,8 +35144,8 @@ async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath,
|
|
|
34962
35144
|
return false;
|
|
34963
35145
|
}
|
|
34964
35146
|
const content = await response.arrayBuffer();
|
|
34965
|
-
await
|
|
34966
|
-
await
|
|
35147
|
+
await import_fs_extra13.default.ensureDir(path15.dirname(targetPath));
|
|
35148
|
+
await import_fs_extra13.default.writeFile(targetPath, Buffer.from(content));
|
|
34967
35149
|
return true;
|
|
34968
35150
|
} catch (error) {
|
|
34969
35151
|
console.error(`Error downloading ${relativePath}:`, error);
|
|
@@ -34988,10 +35170,10 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
|
|
|
34988
35170
|
console.error(`Unexpected response for directory ${dirPath}`);
|
|
34989
35171
|
return false;
|
|
34990
35172
|
}
|
|
34991
|
-
await
|
|
35173
|
+
await import_fs_extra13.default.ensureDir(targetDir);
|
|
34992
35174
|
for (const file of files) {
|
|
34993
35175
|
const relativePath = dirPath ? `${dirPath}/${file.name}` : file.name;
|
|
34994
|
-
const targetPath =
|
|
35176
|
+
const targetPath = path15.join(targetDir, file.name);
|
|
34995
35177
|
const displayPath = relativePath.replace("claude-code-config/", "");
|
|
34996
35178
|
if (file.type === "file") {
|
|
34997
35179
|
onProgress?.(displayPath, "file");
|
|
@@ -35008,14 +35190,14 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
|
|
|
35008
35190
|
}
|
|
35009
35191
|
async function installProConfigs(options) {
|
|
35010
35192
|
const { githubToken, claudeCodeFolder, onProgress } = options;
|
|
35011
|
-
const claudeFolder = claudeCodeFolder ||
|
|
35012
|
-
const tempDir =
|
|
35193
|
+
const claudeFolder = claudeCodeFolder || path15.join(os9.homedir(), ".claude");
|
|
35194
|
+
const tempDir = path15.join(os9.tmpdir(), `aiblueprint-premium-${Date.now()}`);
|
|
35013
35195
|
try {
|
|
35014
35196
|
const success = await downloadDirectoryFromPrivateGitHub(PREMIUM_REPO, PREMIUM_BRANCH, "claude-code-config", tempDir, githubToken, onProgress);
|
|
35015
35197
|
if (!success) {
|
|
35016
35198
|
throw new Error("Failed to download premium configurations");
|
|
35017
35199
|
}
|
|
35018
|
-
await
|
|
35200
|
+
await import_fs_extra13.default.copy(tempDir, claudeFolder, {
|
|
35019
35201
|
overwrite: true,
|
|
35020
35202
|
recursive: true
|
|
35021
35203
|
});
|
|
@@ -35023,41 +35205,41 @@ async function installProConfigs(options) {
|
|
|
35023
35205
|
throw new Error(`Failed to install premium configs: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
35024
35206
|
} finally {
|
|
35025
35207
|
try {
|
|
35026
|
-
await
|
|
35208
|
+
await import_fs_extra13.default.remove(tempDir);
|
|
35027
35209
|
} catch {
|
|
35028
35210
|
}
|
|
35029
35211
|
}
|
|
35030
35212
|
}
|
|
35031
35213
|
|
|
35032
35214
|
// src/lib/token-storage.ts
|
|
35033
|
-
var
|
|
35034
|
-
import
|
|
35035
|
-
import
|
|
35215
|
+
var import_fs_extra14 = __toESM(require_lib4(), 1);
|
|
35216
|
+
import os10 from "os";
|
|
35217
|
+
import path16 from "path";
|
|
35036
35218
|
function getConfigDir() {
|
|
35037
|
-
const platform =
|
|
35219
|
+
const platform = os10.platform();
|
|
35038
35220
|
if (platform === "win32") {
|
|
35039
|
-
const appData = process.env.APPDATA ||
|
|
35040
|
-
return
|
|
35221
|
+
const appData = process.env.APPDATA || path16.join(os10.homedir(), "AppData", "Roaming");
|
|
35222
|
+
return path16.join(appData, "aiblueprint");
|
|
35041
35223
|
} else {
|
|
35042
|
-
const configHome = process.env.XDG_CONFIG_HOME ||
|
|
35043
|
-
return
|
|
35224
|
+
const configHome = process.env.XDG_CONFIG_HOME || path16.join(os10.homedir(), ".config");
|
|
35225
|
+
return path16.join(configHome, "aiblueprint");
|
|
35044
35226
|
}
|
|
35045
35227
|
}
|
|
35046
35228
|
function getTokenFilePath() {
|
|
35047
|
-
return
|
|
35229
|
+
return path16.join(getConfigDir(), "token.txt");
|
|
35048
35230
|
}
|
|
35049
35231
|
async function saveToken(githubToken) {
|
|
35050
35232
|
const tokenFile = getTokenFilePath();
|
|
35051
|
-
await
|
|
35052
|
-
await
|
|
35233
|
+
await import_fs_extra14.default.ensureDir(path16.dirname(tokenFile));
|
|
35234
|
+
await import_fs_extra14.default.writeFile(tokenFile, githubToken, { mode: 384 });
|
|
35053
35235
|
}
|
|
35054
35236
|
async function getToken() {
|
|
35055
35237
|
const tokenFile = getTokenFilePath();
|
|
35056
|
-
if (!await
|
|
35238
|
+
if (!await import_fs_extra14.default.pathExists(tokenFile)) {
|
|
35057
35239
|
return null;
|
|
35058
35240
|
}
|
|
35059
35241
|
try {
|
|
35060
|
-
const token = await
|
|
35242
|
+
const token = await import_fs_extra14.default.readFile(tokenFile, "utf-8");
|
|
35061
35243
|
return token.trim();
|
|
35062
35244
|
} catch (error) {
|
|
35063
35245
|
return null;
|
|
@@ -35066,12 +35248,12 @@ async function getToken() {
|
|
|
35066
35248
|
function getTokenInfo() {
|
|
35067
35249
|
return {
|
|
35068
35250
|
path: getTokenFilePath(),
|
|
35069
|
-
platform:
|
|
35251
|
+
platform: os10.platform()
|
|
35070
35252
|
};
|
|
35071
35253
|
}
|
|
35072
35254
|
|
|
35073
35255
|
// src/commands/pro.ts
|
|
35074
|
-
var
|
|
35256
|
+
var import_fs_extra15 = __toESM(require_lib4(), 1);
|
|
35075
35257
|
var API_URL = "https://codeline.app/api/products";
|
|
35076
35258
|
var PRODUCT_ID = "prd_XJVgxVPbGG";
|
|
35077
35259
|
async function countInstalledItems(claudeDir) {
|
|
@@ -35081,27 +35263,27 @@ async function countInstalledItems(claudeDir) {
|
|
|
35081
35263
|
skills: 0
|
|
35082
35264
|
};
|
|
35083
35265
|
try {
|
|
35084
|
-
const commandsDir =
|
|
35085
|
-
if (await
|
|
35086
|
-
const files = await
|
|
35266
|
+
const commandsDir = path17.join(claudeDir, "commands");
|
|
35267
|
+
if (await import_fs_extra15.default.pathExists(commandsDir)) {
|
|
35268
|
+
const files = await import_fs_extra15.default.readdir(commandsDir);
|
|
35087
35269
|
counts.commands = files.filter((f3) => f3.endsWith(".md")).length;
|
|
35088
35270
|
}
|
|
35089
35271
|
} catch {
|
|
35090
35272
|
}
|
|
35091
35273
|
try {
|
|
35092
|
-
const agentsDir =
|
|
35093
|
-
if (await
|
|
35094
|
-
const files = await
|
|
35274
|
+
const agentsDir = path17.join(claudeDir, "agents");
|
|
35275
|
+
if (await import_fs_extra15.default.pathExists(agentsDir)) {
|
|
35276
|
+
const files = await import_fs_extra15.default.readdir(agentsDir);
|
|
35095
35277
|
counts.agents = files.filter((f3) => f3.endsWith(".md")).length;
|
|
35096
35278
|
}
|
|
35097
35279
|
} catch {
|
|
35098
35280
|
}
|
|
35099
35281
|
try {
|
|
35100
|
-
const skillsDir =
|
|
35101
|
-
if (await
|
|
35102
|
-
const items = await
|
|
35282
|
+
const skillsDir = path17.join(claudeDir, "skills");
|
|
35283
|
+
if (await import_fs_extra15.default.pathExists(skillsDir)) {
|
|
35284
|
+
const items = await import_fs_extra15.default.readdir(skillsDir);
|
|
35103
35285
|
const dirs = await Promise.all(items.map(async (item) => {
|
|
35104
|
-
const stat = await
|
|
35286
|
+
const stat = await import_fs_extra15.default.stat(path17.join(skillsDir, item));
|
|
35105
35287
|
return stat.isDirectory();
|
|
35106
35288
|
}));
|
|
35107
35289
|
counts.skills = dirs.filter(Boolean).length;
|
|
@@ -35208,7 +35390,7 @@ async function proSetupCommand(options = {}) {
|
|
|
35208
35390
|
$e(source_default.red("❌ Not activated"));
|
|
35209
35391
|
process.exit(1);
|
|
35210
35392
|
}
|
|
35211
|
-
const claudeDir = options.folder ?
|
|
35393
|
+
const claudeDir = options.folder ? path17.resolve(options.folder) : path17.join(os11.homedir(), ".claude");
|
|
35212
35394
|
const spinner = de();
|
|
35213
35395
|
const onProgress = (file, type) => {
|
|
35214
35396
|
spinner.message(`Installing: ${source_default.cyan(file)} ${source_default.gray(`(${type})`)}`);
|
|
@@ -35285,12 +35467,12 @@ async function proUpdateCommand(options = {}) {
|
|
|
35285
35467
|
}
|
|
35286
35468
|
|
|
35287
35469
|
// src/commands/sync.ts
|
|
35288
|
-
import
|
|
35289
|
-
import
|
|
35470
|
+
import os12 from "os";
|
|
35471
|
+
import path19 from "path";
|
|
35290
35472
|
|
|
35291
35473
|
// src/lib/sync-utils.ts
|
|
35292
|
-
var
|
|
35293
|
-
import
|
|
35474
|
+
var import_fs_extra16 = __toESM(require_lib4(), 1);
|
|
35475
|
+
import path18 from "path";
|
|
35294
35476
|
import crypto from "crypto";
|
|
35295
35477
|
var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
|
|
35296
35478
|
var PREMIUM_BRANCH2 = "main";
|
|
@@ -35339,7 +35521,7 @@ async function listRemoteFilesRecursive(dirPath, githubToken, basePath = "") {
|
|
|
35339
35521
|
}
|
|
35340
35522
|
async function computeLocalFileSha(filePath) {
|
|
35341
35523
|
try {
|
|
35342
|
-
const content = await
|
|
35524
|
+
const content = await import_fs_extra16.default.readFile(filePath);
|
|
35343
35525
|
return computeFileSha(content);
|
|
35344
35526
|
} catch {
|
|
35345
35527
|
return null;
|
|
@@ -35347,15 +35529,15 @@ async function computeLocalFileSha(filePath) {
|
|
|
35347
35529
|
}
|
|
35348
35530
|
async function listLocalFiles(dir) {
|
|
35349
35531
|
const files = [];
|
|
35350
|
-
if (!await
|
|
35532
|
+
if (!await import_fs_extra16.default.pathExists(dir)) {
|
|
35351
35533
|
return files;
|
|
35352
35534
|
}
|
|
35353
|
-
const items = await
|
|
35535
|
+
const items = await import_fs_extra16.default.readdir(dir);
|
|
35354
35536
|
for (const item of items) {
|
|
35355
35537
|
if (item === "node_modules" || item === ".DS_Store")
|
|
35356
35538
|
continue;
|
|
35357
|
-
const fullPath =
|
|
35358
|
-
const stat = await
|
|
35539
|
+
const fullPath = path18.join(dir, item);
|
|
35540
|
+
const stat = await import_fs_extra16.default.stat(fullPath);
|
|
35359
35541
|
if (stat.isDirectory()) {
|
|
35360
35542
|
files.push(item);
|
|
35361
35543
|
const subFiles = await listLocalFilesRecursive(fullPath, item);
|
|
@@ -35368,13 +35550,13 @@ async function listLocalFiles(dir) {
|
|
|
35368
35550
|
}
|
|
35369
35551
|
async function listLocalFilesRecursive(dir, basePath) {
|
|
35370
35552
|
const files = [];
|
|
35371
|
-
const items = await
|
|
35553
|
+
const items = await import_fs_extra16.default.readdir(dir);
|
|
35372
35554
|
for (const item of items) {
|
|
35373
35555
|
if (item === "node_modules" || item === ".DS_Store")
|
|
35374
35556
|
continue;
|
|
35375
|
-
const fullPath =
|
|
35557
|
+
const fullPath = path18.join(dir, item);
|
|
35376
35558
|
const relativePath = `${basePath}/${item}`;
|
|
35377
|
-
const stat = await
|
|
35559
|
+
const stat = await import_fs_extra16.default.stat(fullPath);
|
|
35378
35560
|
if (stat.isDirectory()) {
|
|
35379
35561
|
files.push(relativePath);
|
|
35380
35562
|
const subFiles = await listLocalFilesRecursive(fullPath, relativePath);
|
|
@@ -35387,7 +35569,7 @@ async function listLocalFilesRecursive(dir, basePath) {
|
|
|
35387
35569
|
}
|
|
35388
35570
|
async function analyzeCategory(category, claudeDir, githubToken) {
|
|
35389
35571
|
const items = [];
|
|
35390
|
-
const localDir =
|
|
35572
|
+
const localDir = path18.join(claudeDir, category);
|
|
35391
35573
|
const remoteFiles = await listRemoteFilesRecursive(category, githubToken);
|
|
35392
35574
|
const localFiles = await listLocalFiles(localDir);
|
|
35393
35575
|
const remoteSet = new Map;
|
|
@@ -35396,7 +35578,7 @@ async function analyzeCategory(category, claudeDir, githubToken) {
|
|
|
35396
35578
|
}
|
|
35397
35579
|
const localSet = new Set(localFiles);
|
|
35398
35580
|
for (const [remotePath, { sha, isFolder }] of remoteSet) {
|
|
35399
|
-
const localPath =
|
|
35581
|
+
const localPath = path18.join(localDir, remotePath);
|
|
35400
35582
|
if (isFolder) {
|
|
35401
35583
|
continue;
|
|
35402
35584
|
}
|
|
@@ -35428,8 +35610,8 @@ async function analyzeCategory(category, claudeDir, githubToken) {
|
|
|
35428
35610
|
}
|
|
35429
35611
|
for (const localPath of localSet) {
|
|
35430
35612
|
if (!remoteSet.has(localPath)) {
|
|
35431
|
-
const fullPath =
|
|
35432
|
-
const stat = await
|
|
35613
|
+
const fullPath = path18.join(localDir, localPath);
|
|
35614
|
+
const stat = await import_fs_extra16.default.stat(fullPath).catch(() => null);
|
|
35433
35615
|
if (stat && !stat.isDirectory()) {
|
|
35434
35616
|
items.push({
|
|
35435
35617
|
name: localPath,
|
|
@@ -35460,9 +35642,9 @@ async function fetchRemoteSettings(githubToken) {
|
|
|
35460
35642
|
}
|
|
35461
35643
|
}
|
|
35462
35644
|
async function getLocalSettings(claudeDir) {
|
|
35463
|
-
const settingsPath =
|
|
35645
|
+
const settingsPath = path18.join(claudeDir, "settings.json");
|
|
35464
35646
|
try {
|
|
35465
|
-
const content = await
|
|
35647
|
+
const content = await import_fs_extra16.default.readFile(settingsPath, "utf-8");
|
|
35466
35648
|
return JSON.parse(content);
|
|
35467
35649
|
} catch {
|
|
35468
35650
|
return {};
|
|
@@ -35543,8 +35725,8 @@ async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken)
|
|
|
35543
35725
|
return false;
|
|
35544
35726
|
}
|
|
35545
35727
|
const content = await response.arrayBuffer();
|
|
35546
|
-
await
|
|
35547
|
-
await
|
|
35728
|
+
await import_fs_extra16.default.ensureDir(path18.dirname(targetPath));
|
|
35729
|
+
await import_fs_extra16.default.writeFile(targetPath, Buffer.from(content));
|
|
35548
35730
|
return true;
|
|
35549
35731
|
} catch {
|
|
35550
35732
|
return false;
|
|
@@ -35554,10 +35736,10 @@ async function syncSelectedHooks(claudeDir, hooks, onProgress) {
|
|
|
35554
35736
|
if (hooks.length === 0) {
|
|
35555
35737
|
return { success: 0, failed: 0 };
|
|
35556
35738
|
}
|
|
35557
|
-
const settingsPath =
|
|
35739
|
+
const settingsPath = path18.join(claudeDir, "settings.json");
|
|
35558
35740
|
let settings = {};
|
|
35559
35741
|
try {
|
|
35560
|
-
const content = await
|
|
35742
|
+
const content = await import_fs_extra16.default.readFile(settingsPath, "utf-8");
|
|
35561
35743
|
settings = JSON.parse(content);
|
|
35562
35744
|
} catch {
|
|
35563
35745
|
settings = {};
|
|
@@ -35574,17 +35756,18 @@ async function syncSelectedHooks(claudeDir, hooks, onProgress) {
|
|
|
35574
35756
|
settings.hooks[hook.hookType] = [];
|
|
35575
35757
|
}
|
|
35576
35758
|
const existingIndex = settings.hooks[hook.hookType].findIndex((h2) => h2.matcher === hook.matcher);
|
|
35759
|
+
const transformedHook = transformHook(hook.remoteHook, claudeDir);
|
|
35577
35760
|
if (existingIndex >= 0) {
|
|
35578
|
-
settings.hooks[hook.hookType][existingIndex] =
|
|
35761
|
+
settings.hooks[hook.hookType][existingIndex] = transformedHook;
|
|
35579
35762
|
} else {
|
|
35580
|
-
settings.hooks[hook.hookType].push(
|
|
35763
|
+
settings.hooks[hook.hookType].push(transformedHook);
|
|
35581
35764
|
}
|
|
35582
35765
|
success++;
|
|
35583
35766
|
} catch {
|
|
35584
35767
|
failed++;
|
|
35585
35768
|
}
|
|
35586
35769
|
}
|
|
35587
|
-
await
|
|
35770
|
+
await import_fs_extra16.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
35588
35771
|
return { success, failed };
|
|
35589
35772
|
}
|
|
35590
35773
|
async function syncSelectedItems(claudeDir, items, githubToken, onProgress) {
|
|
@@ -35592,11 +35775,11 @@ async function syncSelectedItems(claudeDir, items, githubToken, onProgress) {
|
|
|
35592
35775
|
let failed = 0;
|
|
35593
35776
|
let deleted = 0;
|
|
35594
35777
|
for (const item of items) {
|
|
35595
|
-
const targetPath =
|
|
35778
|
+
const targetPath = path18.join(claudeDir, item.relativePath);
|
|
35596
35779
|
if (item.status === "deleted") {
|
|
35597
35780
|
onProgress?.(item.relativePath, "deleting");
|
|
35598
35781
|
try {
|
|
35599
|
-
await
|
|
35782
|
+
await import_fs_extra16.default.remove(targetPath);
|
|
35600
35783
|
deleted++;
|
|
35601
35784
|
} catch {
|
|
35602
35785
|
failed++;
|
|
@@ -35747,7 +35930,7 @@ async function proSyncCommand(options = {}) {
|
|
|
35747
35930
|
$e(source_default.red("❌ Not activated"));
|
|
35748
35931
|
process.exit(1);
|
|
35749
35932
|
}
|
|
35750
|
-
const claudeDir = options.folder ?
|
|
35933
|
+
const claudeDir = options.folder ? path19.resolve(options.folder) : path19.join(os12.homedir(), ".claude");
|
|
35751
35934
|
const spinner = de();
|
|
35752
35935
|
spinner.start("Analyzing changes...");
|
|
35753
35936
|
const result = await analyzeSyncChanges(claudeDir, githubToken);
|
|
@@ -35769,8 +35952,8 @@ async function proSyncCommand(options = {}) {
|
|
|
35769
35952
|
f2.message(source_default.cyan.bold(` ${category.toUpperCase()}`));
|
|
35770
35953
|
if (folderedCategories.includes(category)) {
|
|
35771
35954
|
const folderSummaries = aggregateByTopLevelFolder(items);
|
|
35772
|
-
for (const
|
|
35773
|
-
f2.message(` ${formatFolderSummary(
|
|
35955
|
+
for (const summary of folderSummaries) {
|
|
35956
|
+
f2.message(` ${formatFolderSummary(summary)}`);
|
|
35774
35957
|
}
|
|
35775
35958
|
} else {
|
|
35776
35959
|
for (const item of items) {
|
|
@@ -35790,19 +35973,70 @@ async function proSyncCommand(options = {}) {
|
|
|
35790
35973
|
}
|
|
35791
35974
|
f2.message("");
|
|
35792
35975
|
const choices = createSelectionChoices(changedItems, changedHooks);
|
|
35793
|
-
const
|
|
35794
|
-
|
|
35795
|
-
|
|
35796
|
-
|
|
35797
|
-
|
|
35976
|
+
const newItems = changedItems.filter((i) => i.status === "new");
|
|
35977
|
+
const modifiedItems = changedItems.filter((i) => i.status === "modified");
|
|
35978
|
+
const deletedItems = changedItems.filter((i) => i.status === "deleted");
|
|
35979
|
+
const newHooks = changedHooks.filter((h2) => h2.status === "new");
|
|
35980
|
+
const modifiedHooks = changedHooks.filter((h2) => h2.status === "modified");
|
|
35981
|
+
const hasDeletions = deletedItems.length > 0;
|
|
35982
|
+
const syncModeOptions = [
|
|
35983
|
+
{
|
|
35984
|
+
value: "updates",
|
|
35985
|
+
label: "Import all updates",
|
|
35986
|
+
hint: `add ${newItems.length + newHooks.length} + update ${modifiedItems.length + modifiedHooks.length} files`
|
|
35987
|
+
}
|
|
35988
|
+
];
|
|
35989
|
+
if (hasDeletions) {
|
|
35990
|
+
syncModeOptions.push({
|
|
35991
|
+
value: "updates_and_delete",
|
|
35992
|
+
label: "Import all updates and delete files",
|
|
35993
|
+
hint: `add ${newItems.length + newHooks.length} + update ${modifiedItems.length + modifiedHooks.length} + delete ${deletedItems.length} files`
|
|
35994
|
+
});
|
|
35995
|
+
}
|
|
35996
|
+
syncModeOptions.push({
|
|
35997
|
+
value: "custom",
|
|
35998
|
+
label: "Custom choice",
|
|
35999
|
+
hint: "select specific files to sync"
|
|
35798
36000
|
});
|
|
35799
|
-
|
|
36001
|
+
const syncMode = await ie({
|
|
36002
|
+
message: "How would you like to sync?",
|
|
36003
|
+
options: syncModeOptions
|
|
36004
|
+
});
|
|
36005
|
+
if (lD(syncMode)) {
|
|
35800
36006
|
ue("Sync cancelled");
|
|
35801
36007
|
process.exit(0);
|
|
35802
36008
|
}
|
|
35803
|
-
|
|
35804
|
-
|
|
35805
|
-
|
|
36009
|
+
let selectedItems = [];
|
|
36010
|
+
let selectedHooks = [];
|
|
36011
|
+
if (syncMode === "updates") {
|
|
36012
|
+
selectedItems = [...newItems, ...modifiedItems];
|
|
36013
|
+
selectedHooks = [...newHooks, ...modifiedHooks];
|
|
36014
|
+
} else if (syncMode === "updates_and_delete") {
|
|
36015
|
+
selectedItems = [...newItems, ...modifiedItems, ...deletedItems];
|
|
36016
|
+
selectedHooks = [...newHooks, ...modifiedHooks];
|
|
36017
|
+
} else {
|
|
36018
|
+
const nonDeleteChoices = choices.filter((c2) => {
|
|
36019
|
+
if (c2.value.type === "file")
|
|
36020
|
+
return c2.value.item.status !== "deleted";
|
|
36021
|
+
if (c2.value.type === "folder")
|
|
36022
|
+
return !c2.value.items.every((i) => i.status === "deleted");
|
|
36023
|
+
return true;
|
|
36024
|
+
});
|
|
36025
|
+
const nonDeleteInitialValues = nonDeleteChoices.map((c2) => c2.value);
|
|
36026
|
+
const customSelected = await ae({
|
|
36027
|
+
message: "Select items to sync (deletions excluded by default):",
|
|
36028
|
+
options: choices,
|
|
36029
|
+
initialValues: nonDeleteInitialValues,
|
|
36030
|
+
required: false
|
|
36031
|
+
});
|
|
36032
|
+
if (lD(customSelected)) {
|
|
36033
|
+
ue("Sync cancelled");
|
|
36034
|
+
process.exit(0);
|
|
36035
|
+
}
|
|
36036
|
+
const expanded = expandSelections(customSelected);
|
|
36037
|
+
selectedItems = expanded.items;
|
|
36038
|
+
selectedHooks = expanded.hooks;
|
|
36039
|
+
}
|
|
35806
36040
|
if (selectedItems.length === 0 && selectedHooks.length === 0) {
|
|
35807
36041
|
f2.warn("No items selected");
|
|
35808
36042
|
$e(source_default.yellow("⚠️ Nothing to sync"));
|
|
@@ -35811,19 +36045,31 @@ async function proSyncCommand(options = {}) {
|
|
|
35811
36045
|
const toAdd = selectedItems.filter((i) => i.status === "new").length + selectedHooks.filter((h2) => h2.status === "new").length;
|
|
35812
36046
|
const toUpdate = selectedItems.filter((i) => i.status === "modified").length + selectedHooks.filter((h2) => h2.status === "modified").length;
|
|
35813
36047
|
const toRemove = selectedItems.filter((i) => i.status === "deleted").length;
|
|
35814
|
-
|
|
35815
|
-
|
|
35816
|
-
|
|
35817
|
-
|
|
35818
|
-
|
|
36048
|
+
f2.message("");
|
|
36049
|
+
f2.message(source_default.bold("What will happen:"));
|
|
36050
|
+
if (toAdd > 0)
|
|
36051
|
+
f2.message(source_default.green(` ✓ Add ${toAdd} new file${toAdd > 1 ? "s" : ""}`));
|
|
36052
|
+
if (toUpdate > 0)
|
|
36053
|
+
f2.message(source_default.yellow(` ✓ Update ${toUpdate} file${toUpdate > 1 ? "s" : ""}`));
|
|
36054
|
+
if (toRemove > 0)
|
|
36055
|
+
f2.message(source_default.red(` ✓ Delete ${toRemove} file${toRemove > 1 ? "s" : ""}`));
|
|
36056
|
+
f2.message(source_default.gray(` ✓ Backup current config to ~/.config/aiblueprint/backup/`));
|
|
36057
|
+
f2.message("");
|
|
35819
36058
|
const confirmResult = await se({
|
|
35820
|
-
message:
|
|
36059
|
+
message: "Proceed with sync?",
|
|
35821
36060
|
initialValue: true
|
|
35822
36061
|
});
|
|
35823
36062
|
if (lD(confirmResult) || !confirmResult) {
|
|
35824
36063
|
ue("Sync cancelled");
|
|
35825
36064
|
process.exit(0);
|
|
35826
36065
|
}
|
|
36066
|
+
spinner.start("Creating backup...");
|
|
36067
|
+
const backupPath = await createBackup(claudeDir);
|
|
36068
|
+
if (backupPath) {
|
|
36069
|
+
spinner.stop(`Backup created: ${source_default.gray(backupPath)}`);
|
|
36070
|
+
} else {
|
|
36071
|
+
spinner.stop("No existing config to backup");
|
|
36072
|
+
}
|
|
35827
36073
|
spinner.start("Syncing...");
|
|
35828
36074
|
const syncResult = await syncSelectedItems(claudeDir, selectedItems, githubToken, (file, action) => {
|
|
35829
36075
|
spinner.message(`${action}: ${source_default.cyan(file)}`);
|