aiblueprint-cli 1.2.3 → 1.3.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/claude-code-config/agents/explore-codebase.md +3 -1
- package/claude-code-config/agents/explore-docs.md +54 -58
- package/claude-code-config/agents/websearch.md +2 -2
- package/claude-code-config/commands/apex.md +109 -0
- package/claude-code-config/commands/explore.md +77 -32
- package/claude-code-config/commands/git/commit.md +60 -0
- package/claude-code-config/commands/{create-pull-request.md → git/create-pr.md} +12 -0
- package/claude-code-config/commands/{fix-pr-comments.md → git/fix-pr-comments.md} +10 -0
- package/claude-code-config/commands/oneshot.md +44 -44
- package/claude-code-config/commands/tasks/run-task.md +220 -0
- package/claude-code-config/commands/{watch-ci.md → utils/watch-ci.md} +4 -0
- package/claude-code-config/scripts/statusline/CLAUDE.md +8 -3
- package/dist/cli.js +611 -53
- package/package.json +1 -1
- package/claude-code-config/commands/commit.md +0 -47
- package/claude-code-config/commands/epct.md +0 -69
- package/claude-code-config/commands/run-tasks.md +0 -105
package/dist/cli.js
CHANGED
|
@@ -32490,7 +32490,7 @@ var lib_default = inquirer;
|
|
|
32490
32490
|
// src/commands/setup.ts
|
|
32491
32491
|
var import_fs_extra5 = __toESM(require_lib4(), 1);
|
|
32492
32492
|
import path7 from "path";
|
|
32493
|
-
import
|
|
32493
|
+
import os7 from "os";
|
|
32494
32494
|
|
|
32495
32495
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
32496
32496
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -32994,8 +32994,14 @@ async function setupShellShortcuts() {
|
|
|
32994
32994
|
try {
|
|
32995
32995
|
const platform = os3.platform();
|
|
32996
32996
|
let shellConfigFile;
|
|
32997
|
+
let aliases;
|
|
32997
32998
|
if (platform === "darwin") {
|
|
32998
32999
|
shellConfigFile = path2.join(os3.homedir(), ".zshenv");
|
|
33000
|
+
aliases = `
|
|
33001
|
+
# AIBlueprint Claude Code aliases
|
|
33002
|
+
alias cc="claude --dangerously-skip-permissions"
|
|
33003
|
+
alias ccc="claude --dangerously-skip-permissions -c"
|
|
33004
|
+
`;
|
|
32999
33005
|
} else if (platform === "linux") {
|
|
33000
33006
|
const shell = process.env.SHELL || "";
|
|
33001
33007
|
if (shell.includes("zsh")) {
|
|
@@ -33003,17 +33009,35 @@ async function setupShellShortcuts() {
|
|
|
33003
33009
|
} else {
|
|
33004
33010
|
shellConfigFile = path2.join(os3.homedir(), ".bashrc");
|
|
33005
33011
|
}
|
|
33006
|
-
|
|
33007
|
-
console.log(source_default.yellow("Shell shortcuts are only supported on macOS and Linux"));
|
|
33008
|
-
return;
|
|
33009
|
-
}
|
|
33010
|
-
const aliases = `
|
|
33012
|
+
aliases = `
|
|
33011
33013
|
# AIBlueprint Claude Code aliases
|
|
33012
33014
|
alias cc="claude --dangerously-skip-permissions"
|
|
33013
33015
|
alias ccc="claude --dangerously-skip-permissions -c"
|
|
33014
33016
|
`;
|
|
33017
|
+
} else if (platform === "win32") {
|
|
33018
|
+
const pwshProfileDir = path2.join(os3.homedir(), "Documents", "PowerShell");
|
|
33019
|
+
const windowsPwshProfileDir = path2.join(os3.homedir(), "Documents", "WindowsPowerShell");
|
|
33020
|
+
let profileDir;
|
|
33021
|
+
if (await import_fs_extra.default.pathExists(pwshProfileDir)) {
|
|
33022
|
+
profileDir = pwshProfileDir;
|
|
33023
|
+
} else if (await import_fs_extra.default.pathExists(windowsPwshProfileDir)) {
|
|
33024
|
+
profileDir = windowsPwshProfileDir;
|
|
33025
|
+
} else {
|
|
33026
|
+
profileDir = pwshProfileDir;
|
|
33027
|
+
await import_fs_extra.default.ensureDir(profileDir);
|
|
33028
|
+
}
|
|
33029
|
+
shellConfigFile = path2.join(profileDir, "Profile.ps1");
|
|
33030
|
+
aliases = `
|
|
33031
|
+
# AIBlueprint Claude Code shortcuts
|
|
33032
|
+
function cc { claude --dangerously-skip-permissions $args }
|
|
33033
|
+
function ccc { claude --dangerously-skip-permissions -c $args }
|
|
33034
|
+
`;
|
|
33035
|
+
} else {
|
|
33036
|
+
console.log(source_default.yellow(`Shell shortcuts are not supported on platform: ${platform}`));
|
|
33037
|
+
return;
|
|
33038
|
+
}
|
|
33015
33039
|
const existingContent = await import_fs_extra.default.readFile(shellConfigFile, "utf-8").catch(() => "");
|
|
33016
|
-
if (!existingContent.includes("AIBlueprint Claude Code
|
|
33040
|
+
if (!existingContent.includes("AIBlueprint Claude Code")) {
|
|
33017
33041
|
await import_fs_extra.default.appendFile(shellConfigFile, aliases);
|
|
33018
33042
|
}
|
|
33019
33043
|
} catch (error) {
|
|
@@ -33078,7 +33102,12 @@ async function createSymlink(sourcePath, targetPath, options = {}) {
|
|
|
33078
33102
|
return false;
|
|
33079
33103
|
}
|
|
33080
33104
|
}
|
|
33081
|
-
|
|
33105
|
+
const isWindows = os4.platform() === "win32";
|
|
33106
|
+
if (isWindows) {
|
|
33107
|
+
await import_fs_extra2.default.symlink(sourcePath, targetPath, "junction");
|
|
33108
|
+
} else {
|
|
33109
|
+
await import_fs_extra2.default.symlink(sourcePath, targetPath);
|
|
33110
|
+
}
|
|
33082
33111
|
return true;
|
|
33083
33112
|
} catch (error) {
|
|
33084
33113
|
console.error(source_default.red(options.errorPrefix || "Error creating symlink:"), error);
|
|
@@ -33131,10 +33160,13 @@ async function setupOpenCodeSymlink(claudeDir, customOpenCodeFolder, customClaud
|
|
|
33131
33160
|
// src/commands/setup/dependencies.ts
|
|
33132
33161
|
import { execSync } from "child_process";
|
|
33133
33162
|
import path4 from "path";
|
|
33163
|
+
import os5 from "os";
|
|
33134
33164
|
async function checkAndInstallDependencies() {
|
|
33165
|
+
const isWindows = os5.platform() === "win32";
|
|
33135
33166
|
const checkCommand = (cmd) => {
|
|
33136
33167
|
try {
|
|
33137
|
-
|
|
33168
|
+
const whichCmd = isWindows ? `where ${cmd}` : `which ${cmd}`;
|
|
33169
|
+
execSync(whichCmd, { stdio: "ignore" });
|
|
33138
33170
|
return true;
|
|
33139
33171
|
} catch {
|
|
33140
33172
|
return false;
|
|
@@ -33177,6 +33209,27 @@ async function installStatuslineDependencies(claudeDir) {
|
|
|
33177
33209
|
// src/commands/setup/settings.ts
|
|
33178
33210
|
var import_fs_extra3 = __toESM(require_lib4(), 1);
|
|
33179
33211
|
import path5 from "path";
|
|
33212
|
+
import os6 from "os";
|
|
33213
|
+
function getPlaySoundCommand(soundPath) {
|
|
33214
|
+
const platform = os6.platform();
|
|
33215
|
+
if (platform === "darwin") {
|
|
33216
|
+
return `afplay -v 0.1 "${soundPath}"`;
|
|
33217
|
+
} else if (platform === "win32") {
|
|
33218
|
+
return `powershell -c "(New-Object Media.SoundPlayer '${soundPath}').PlaySync()"`;
|
|
33219
|
+
} else {
|
|
33220
|
+
return `paplay "${soundPath}" 2>/dev/null || aplay "${soundPath}" 2>/dev/null || true`;
|
|
33221
|
+
}
|
|
33222
|
+
}
|
|
33223
|
+
async function hasExistingStatusLine(claudeDir) {
|
|
33224
|
+
const settingsPath = path5.join(claudeDir, "settings.json");
|
|
33225
|
+
try {
|
|
33226
|
+
const existingSettings = await import_fs_extra3.default.readFile(settingsPath, "utf-8");
|
|
33227
|
+
const settings = JSON.parse(existingSettings);
|
|
33228
|
+
return !!settings.statusLine;
|
|
33229
|
+
} catch {
|
|
33230
|
+
return false;
|
|
33231
|
+
}
|
|
33232
|
+
}
|
|
33180
33233
|
async function updateSettings(options, claudeDir) {
|
|
33181
33234
|
const settingsPath = path5.join(claudeDir, "settings.json");
|
|
33182
33235
|
let settings = {};
|
|
@@ -33186,24 +33239,8 @@ async function updateSettings(options, claudeDir) {
|
|
|
33186
33239
|
} catch {
|
|
33187
33240
|
}
|
|
33188
33241
|
if (options.customStatusline) {
|
|
33189
|
-
|
|
33190
|
-
|
|
33191
|
-
{
|
|
33192
|
-
type: "confirm",
|
|
33193
|
-
name: "replace",
|
|
33194
|
-
message: "You already have a statusLine configuration. Replace it?"
|
|
33195
|
-
}
|
|
33196
|
-
]);
|
|
33197
|
-
if (!confirmAnswer.replace) {
|
|
33198
|
-
console.log(source_default.yellow(" Keeping existing statusLine configuration"));
|
|
33199
|
-
} else {
|
|
33200
|
-
settings.statusLine = {
|
|
33201
|
-
type: "command",
|
|
33202
|
-
command: `bun ${path5.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
33203
|
-
padding: 0
|
|
33204
|
-
};
|
|
33205
|
-
}
|
|
33206
|
-
} else {
|
|
33242
|
+
const shouldReplace = options.replaceStatusline !== false;
|
|
33243
|
+
if (shouldReplace) {
|
|
33207
33244
|
settings.statusLine = {
|
|
33208
33245
|
type: "command",
|
|
33209
33246
|
command: `bun ${path5.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
@@ -33236,12 +33273,13 @@ async function updateSettings(options, claudeDir) {
|
|
|
33236
33273
|
if (!settings.hooks.Stop) {
|
|
33237
33274
|
settings.hooks.Stop = [];
|
|
33238
33275
|
}
|
|
33276
|
+
const finishSoundPath = path5.join(claudeDir, "song/finish.mp3");
|
|
33239
33277
|
const stopHook = {
|
|
33240
33278
|
matcher: "",
|
|
33241
33279
|
hooks: [
|
|
33242
33280
|
{
|
|
33243
33281
|
type: "command",
|
|
33244
|
-
command:
|
|
33282
|
+
command: getPlaySoundCommand(finishSoundPath)
|
|
33245
33283
|
}
|
|
33246
33284
|
]
|
|
33247
33285
|
};
|
|
@@ -33252,12 +33290,13 @@ async function updateSettings(options, claudeDir) {
|
|
|
33252
33290
|
if (!settings.hooks.Notification) {
|
|
33253
33291
|
settings.hooks.Notification = [];
|
|
33254
33292
|
}
|
|
33293
|
+
const needHumanSoundPath = path5.join(claudeDir, "song/need-human.mp3");
|
|
33255
33294
|
const notificationHook = {
|
|
33256
33295
|
matcher: "",
|
|
33257
33296
|
hooks: [
|
|
33258
33297
|
{
|
|
33259
33298
|
type: "command",
|
|
33260
|
-
command:
|
|
33299
|
+
command: getPlaySoundCommand(needHumanSoundPath)
|
|
33261
33300
|
}
|
|
33262
33301
|
]
|
|
33263
33302
|
};
|
|
@@ -33322,24 +33361,35 @@ async function downloadDirectoryFromGitHub(dirPath, targetDir) {
|
|
|
33322
33361
|
const apiUrl = `https://api.github.com/repos/Melvynx/aiblueprint-cli/contents/claude-code-config/${dirPath}`;
|
|
33323
33362
|
const response = await fetch(apiUrl);
|
|
33324
33363
|
if (!response.ok) {
|
|
33364
|
+
console.error(source_default.yellow(` Warning: Failed to fetch directory from GitHub: ${dirPath} (HTTP ${response.status})`));
|
|
33325
33365
|
return false;
|
|
33326
33366
|
}
|
|
33327
33367
|
const files = await response.json();
|
|
33328
33368
|
if (!Array.isArray(files)) {
|
|
33369
|
+
console.error(source_default.yellow(` Warning: Invalid response from GitHub API for: ${dirPath}`));
|
|
33329
33370
|
return false;
|
|
33330
33371
|
}
|
|
33331
33372
|
await import_fs_extra4.default.ensureDir(targetDir);
|
|
33373
|
+
let allSuccess = true;
|
|
33332
33374
|
for (const file of files) {
|
|
33333
33375
|
const relativePath = `${dirPath}/${file.name}`;
|
|
33334
33376
|
const targetPath = path6.join(targetDir, file.name);
|
|
33335
33377
|
if (file.type === "file") {
|
|
33336
|
-
await downloadFromGitHub(relativePath, targetPath);
|
|
33378
|
+
const success = await downloadFromGitHub(relativePath, targetPath);
|
|
33379
|
+
if (!success) {
|
|
33380
|
+
console.error(source_default.yellow(` Warning: Failed to download file: ${relativePath}`));
|
|
33381
|
+
allSuccess = false;
|
|
33382
|
+
}
|
|
33337
33383
|
} else if (file.type === "dir") {
|
|
33338
|
-
await downloadDirectoryFromGitHub(relativePath, targetPath);
|
|
33384
|
+
const success = await downloadDirectoryFromGitHub(relativePath, targetPath);
|
|
33385
|
+
if (!success) {
|
|
33386
|
+
allSuccess = false;
|
|
33387
|
+
}
|
|
33339
33388
|
}
|
|
33340
33389
|
}
|
|
33341
|
-
return
|
|
33390
|
+
return allSuccess;
|
|
33342
33391
|
} catch (error) {
|
|
33392
|
+
console.error(source_default.yellow(` Warning: Error downloading directory ${dirPath}: ${error instanceof Error ? error.message : String(error)}`));
|
|
33343
33393
|
return false;
|
|
33344
33394
|
}
|
|
33345
33395
|
}
|
|
@@ -33443,10 +33493,11 @@ async function setupCommand(params = {}) {
|
|
|
33443
33493
|
notificationSounds: features.includes("notificationSounds"),
|
|
33444
33494
|
postEditTypeScript: features.includes("postEditTypeScript"),
|
|
33445
33495
|
codexSymlink: features.includes("codexSymlink"),
|
|
33446
|
-
openCodeSymlink: features.includes("openCodeSymlink")
|
|
33496
|
+
openCodeSymlink: features.includes("openCodeSymlink"),
|
|
33497
|
+
skipInteractive
|
|
33447
33498
|
};
|
|
33448
33499
|
const s = new SimpleSpinner;
|
|
33449
|
-
const claudeDir = customClaudeCodeFolder ? path7.resolve(customClaudeCodeFolder) : path7.join(
|
|
33500
|
+
const claudeDir = customClaudeCodeFolder ? path7.resolve(customClaudeCodeFolder) : path7.join(os7.homedir(), ".claude");
|
|
33450
33501
|
console.log(source_default.gray(`Installing to: ${claudeDir}`));
|
|
33451
33502
|
await import_fs_extra5.default.ensureDir(claudeDir);
|
|
33452
33503
|
let useGitHub = true;
|
|
@@ -33577,6 +33628,23 @@ async function setupCommand(params = {}) {
|
|
|
33577
33628
|
await installStatuslineDependencies(claudeDir);
|
|
33578
33629
|
s.stop("Statusline dependencies installed");
|
|
33579
33630
|
}
|
|
33631
|
+
if (options.customStatusline && !skipInteractive) {
|
|
33632
|
+
const existingStatusLine = await hasExistingStatusLine(claudeDir);
|
|
33633
|
+
if (existingStatusLine) {
|
|
33634
|
+
const confirmAnswer = await lib_default.prompt([
|
|
33635
|
+
{
|
|
33636
|
+
type: "confirm",
|
|
33637
|
+
name: "replace",
|
|
33638
|
+
message: "You already have a statusLine configuration. Replace it?",
|
|
33639
|
+
default: true
|
|
33640
|
+
}
|
|
33641
|
+
]);
|
|
33642
|
+
options.replaceStatusline = confirmAnswer.replace;
|
|
33643
|
+
if (!confirmAnswer.replace) {
|
|
33644
|
+
console.log(source_default.yellow(" Keeping existing statusLine configuration"));
|
|
33645
|
+
}
|
|
33646
|
+
}
|
|
33647
|
+
}
|
|
33580
33648
|
s.start("Updating settings.json");
|
|
33581
33649
|
await updateSettings(options, claudeDir);
|
|
33582
33650
|
s.stop("Settings updated");
|
|
@@ -33584,7 +33652,12 @@ async function setupCommand(params = {}) {
|
|
|
33584
33652
|
console.log(source_default.gray(`
|
|
33585
33653
|
Next steps:`));
|
|
33586
33654
|
if (options.shellShortcuts) {
|
|
33587
|
-
|
|
33655
|
+
const platform = os7.platform();
|
|
33656
|
+
if (platform === "win32") {
|
|
33657
|
+
console.log(source_default.gray(" • Restart PowerShell to load the new functions"));
|
|
33658
|
+
} else {
|
|
33659
|
+
console.log(source_default.gray(" • Restart your terminal or run: source ~/.zshenv (macOS) or source ~/.bashrc (Linux)"));
|
|
33660
|
+
}
|
|
33588
33661
|
console.log(source_default.gray(' • Use "cc" for Claude Code with permissions skipped'));
|
|
33589
33662
|
console.log(source_default.gray(' • Use "ccc" for Claude Code with permissions skipped and continue mode'));
|
|
33590
33663
|
}
|
|
@@ -33692,15 +33765,24 @@ async function listFilesFromGitHub(dirPath) {
|
|
|
33692
33765
|
if (!response.ok) {
|
|
33693
33766
|
return [];
|
|
33694
33767
|
}
|
|
33695
|
-
const
|
|
33696
|
-
|
|
33768
|
+
const items = await response.json();
|
|
33769
|
+
const files = [];
|
|
33770
|
+
for (const item of items) {
|
|
33771
|
+
if (item.type === "file") {
|
|
33772
|
+
files.push(item.name);
|
|
33773
|
+
} else if (item.type === "dir") {
|
|
33774
|
+
const subFiles = await listFilesFromGitHub(`${dirPath}/${item.name}`);
|
|
33775
|
+
files.push(...subFiles.map((f) => `${item.name}/${f}`));
|
|
33776
|
+
}
|
|
33777
|
+
}
|
|
33778
|
+
return files;
|
|
33697
33779
|
} catch (error) {
|
|
33698
33780
|
return [];
|
|
33699
33781
|
}
|
|
33700
33782
|
}
|
|
33701
33783
|
async function isGitHubAvailable() {
|
|
33702
33784
|
try {
|
|
33703
|
-
const testUrl = `${GITHUB_RAW_BASE3}/commands/
|
|
33785
|
+
const testUrl = `${GITHUB_RAW_BASE3}/commands/apex.md`;
|
|
33704
33786
|
const testResponse = await fetch(testUrl);
|
|
33705
33787
|
return testResponse.ok;
|
|
33706
33788
|
} catch {
|
|
@@ -33894,6 +33976,20 @@ class SimpleSpinner3 {
|
|
|
33894
33976
|
console.log(source_default.green(`✓ ${message}`));
|
|
33895
33977
|
}
|
|
33896
33978
|
}
|
|
33979
|
+
async function getLocalMdFilesRecursively(dir, basePath = "") {
|
|
33980
|
+
const files = [];
|
|
33981
|
+
const entries = await import_fs_extra10.default.readdir(dir, { withFileTypes: true });
|
|
33982
|
+
for (const entry of entries) {
|
|
33983
|
+
const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;
|
|
33984
|
+
if (entry.isDirectory()) {
|
|
33985
|
+
const subFiles = await getLocalMdFilesRecursively(path12.join(dir, entry.name), relativePath);
|
|
33986
|
+
files.push(...subFiles);
|
|
33987
|
+
} else if (entry.name.endsWith(".md")) {
|
|
33988
|
+
files.push(relativePath);
|
|
33989
|
+
}
|
|
33990
|
+
}
|
|
33991
|
+
return files;
|
|
33992
|
+
}
|
|
33897
33993
|
async function discoverAvailableCommands() {
|
|
33898
33994
|
const commands = {};
|
|
33899
33995
|
const useGitHub = await isGitHubAvailable();
|
|
@@ -33906,8 +34002,7 @@ async function discoverAvailableCommands() {
|
|
|
33906
34002
|
if (!commandsDir) {
|
|
33907
34003
|
throw new Error("Commands directory not found");
|
|
33908
34004
|
}
|
|
33909
|
-
|
|
33910
|
-
mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
34005
|
+
mdFiles = await getLocalMdFilesRecursively(commandsDir);
|
|
33911
34006
|
}
|
|
33912
34007
|
for (const file of mdFiles) {
|
|
33913
34008
|
const commandName = file.replace(".md", "");
|
|
@@ -33915,7 +34010,7 @@ async function discoverAvailableCommands() {
|
|
|
33915
34010
|
const content = await getFileContentWithGitHubFallback("commands", file);
|
|
33916
34011
|
const { metadata } = parseYamlFrontmatter(content);
|
|
33917
34012
|
commands[commandName] = {
|
|
33918
|
-
name: commandName.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()),
|
|
34013
|
+
name: commandName.split("/").map((part) => part.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase())).join("/"),
|
|
33919
34014
|
description: metadata.description || "No description available",
|
|
33920
34015
|
allowedTools: metadata["allowed-tools"],
|
|
33921
34016
|
argumentHint: metadata["argument-hint"],
|
|
@@ -34535,6 +34630,59 @@ class x {
|
|
|
34535
34630
|
}
|
|
34536
34631
|
}
|
|
34537
34632
|
}
|
|
34633
|
+
|
|
34634
|
+
class BD extends x {
|
|
34635
|
+
get cursor() {
|
|
34636
|
+
return this.value ? 0 : 1;
|
|
34637
|
+
}
|
|
34638
|
+
get _value() {
|
|
34639
|
+
return this.cursor === 0;
|
|
34640
|
+
}
|
|
34641
|
+
constructor(u) {
|
|
34642
|
+
super(u, false), this.value = !!u.initialValue, this.on("value", () => {
|
|
34643
|
+
this.value = this._value;
|
|
34644
|
+
}), this.on("confirm", (F) => {
|
|
34645
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = F, this.state = "submit", this.close();
|
|
34646
|
+
}), this.on("cursor", () => {
|
|
34647
|
+
this.value = !this.value;
|
|
34648
|
+
});
|
|
34649
|
+
}
|
|
34650
|
+
}
|
|
34651
|
+
var fD = Object.defineProperty;
|
|
34652
|
+
var gD = (e, u, F) => (u in e) ? fD(e, u, { enumerable: true, configurable: true, writable: true, value: F }) : e[u] = F;
|
|
34653
|
+
var K = (e, u, F) => (gD(e, typeof u != "symbol" ? u + "" : u, F), F);
|
|
34654
|
+
var vD = class extends x {
|
|
34655
|
+
constructor(u) {
|
|
34656
|
+
super(u, false), K(this, "options"), K(this, "cursor", 0), this.options = u.options, this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: F }) => F === u.cursorAt), 0), this.on("key", (F) => {
|
|
34657
|
+
F === "a" && this.toggleAll();
|
|
34658
|
+
}), this.on("cursor", (F) => {
|
|
34659
|
+
switch (F) {
|
|
34660
|
+
case "left":
|
|
34661
|
+
case "up":
|
|
34662
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
34663
|
+
break;
|
|
34664
|
+
case "down":
|
|
34665
|
+
case "right":
|
|
34666
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
34667
|
+
break;
|
|
34668
|
+
case "space":
|
|
34669
|
+
this.toggleValue();
|
|
34670
|
+
break;
|
|
34671
|
+
}
|
|
34672
|
+
});
|
|
34673
|
+
}
|
|
34674
|
+
get _value() {
|
|
34675
|
+
return this.options[this.cursor].value;
|
|
34676
|
+
}
|
|
34677
|
+
toggleAll() {
|
|
34678
|
+
const u = this.value.length === this.options.length;
|
|
34679
|
+
this.value = u ? [] : this.options.map((F) => F.value);
|
|
34680
|
+
}
|
|
34681
|
+
toggleValue() {
|
|
34682
|
+
const u = this.value.includes(this._value);
|
|
34683
|
+
this.value = u ? this.value.filter((F) => F !== this._value) : [...this.value, this._value];
|
|
34684
|
+
}
|
|
34685
|
+
};
|
|
34538
34686
|
var TD = Object.defineProperty;
|
|
34539
34687
|
var jD = (e, u, F) => (u in e) ? TD(e, u, { enumerable: true, configurable: true, writable: true, value: F }) : e[u] = F;
|
|
34540
34688
|
var MD = (e, u, F) => (jD(e, typeof u != "symbol" ? u + "" : u, F), F);
|
|
@@ -34592,7 +34740,7 @@ var H = o("◆", "*");
|
|
|
34592
34740
|
var I2 = o("■", "x");
|
|
34593
34741
|
var x2 = o("▲", "x");
|
|
34594
34742
|
var S2 = o("◇", "o");
|
|
34595
|
-
var
|
|
34743
|
+
var K2 = o("┌", "T");
|
|
34596
34744
|
var a2 = o("│", "|");
|
|
34597
34745
|
var d2 = o("└", "—");
|
|
34598
34746
|
var b2 = o("●", ">");
|
|
@@ -34643,13 +34791,76 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
34643
34791
|
`;
|
|
34644
34792
|
}
|
|
34645
34793
|
} }).prompt();
|
|
34794
|
+
var se = (r2) => {
|
|
34795
|
+
const n = r2.active ?? "Yes", i = r2.inactive ?? "No";
|
|
34796
|
+
return new BD({ active: n, inactive: i, initialValue: r2.initialValue ?? true, render() {
|
|
34797
|
+
const t = `${import_picocolors2.default.gray(a2)}
|
|
34798
|
+
${y2(this.state)} ${r2.message}
|
|
34799
|
+
`, s = this.value ? n : i;
|
|
34800
|
+
switch (this.state) {
|
|
34801
|
+
case "submit":
|
|
34802
|
+
return `${t}${import_picocolors2.default.gray(a2)} ${import_picocolors2.default.dim(s)}`;
|
|
34803
|
+
case "cancel":
|
|
34804
|
+
return `${t}${import_picocolors2.default.gray(a2)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}
|
|
34805
|
+
${import_picocolors2.default.gray(a2)}`;
|
|
34806
|
+
default:
|
|
34807
|
+
return `${t}${import_picocolors2.default.cyan(a2)} ${this.value ? `${import_picocolors2.default.green(b2)} ${n}` : `${import_picocolors2.default.dim(E)} ${import_picocolors2.default.dim(n)}`} ${import_picocolors2.default.dim("/")} ${this.value ? `${import_picocolors2.default.dim(E)} ${import_picocolors2.default.dim(i)}` : `${import_picocolors2.default.green(b2)} ${i}`}
|
|
34808
|
+
${import_picocolors2.default.cyan(d2)}
|
|
34809
|
+
`;
|
|
34810
|
+
}
|
|
34811
|
+
} }).prompt();
|
|
34812
|
+
};
|
|
34813
|
+
var ae = (r2) => {
|
|
34814
|
+
const n = (i, t) => {
|
|
34815
|
+
const s = i.label ?? String(i.value);
|
|
34816
|
+
return t === "active" ? `${import_picocolors2.default.cyan(C)} ${s} ${i.hint ? import_picocolors2.default.dim(`(${i.hint})`) : ""}` : t === "selected" ? `${import_picocolors2.default.green(w2)} ${import_picocolors2.default.dim(s)}` : t === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}` : t === "active-selected" ? `${import_picocolors2.default.green(w2)} ${s} ${i.hint ? import_picocolors2.default.dim(`(${i.hint})`) : ""}` : t === "submitted" ? `${import_picocolors2.default.dim(s)}` : `${import_picocolors2.default.dim(M2)} ${import_picocolors2.default.dim(s)}`;
|
|
34817
|
+
};
|
|
34818
|
+
return new vD({ options: r2.options, initialValues: r2.initialValues, required: r2.required ?? true, cursorAt: r2.cursorAt, validate(i) {
|
|
34819
|
+
if (this.required && i.length === 0)
|
|
34820
|
+
return `Please select at least one option.
|
|
34821
|
+
${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
|
|
34822
|
+
}, render() {
|
|
34823
|
+
let i = `${import_picocolors2.default.gray(a2)}
|
|
34824
|
+
${y2(this.state)} ${r2.message}
|
|
34825
|
+
`;
|
|
34826
|
+
switch (this.state) {
|
|
34827
|
+
case "submit":
|
|
34828
|
+
return `${i}${import_picocolors2.default.gray(a2)} ${this.options.filter(({ value: t }) => this.value.includes(t)).map((t) => n(t, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
|
|
34829
|
+
case "cancel": {
|
|
34830
|
+
const t = this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "cancelled")).join(import_picocolors2.default.dim(", "));
|
|
34831
|
+
return `${i}${import_picocolors2.default.gray(a2)} ${t.trim() ? `${t}
|
|
34832
|
+
${import_picocolors2.default.gray(a2)}` : ""}`;
|
|
34833
|
+
}
|
|
34834
|
+
case "error": {
|
|
34835
|
+
const t = this.error.split(`
|
|
34836
|
+
`).map((s, c2) => c2 === 0 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(s)}` : ` ${s}`).join(`
|
|
34837
|
+
`);
|
|
34838
|
+
return i + import_picocolors2.default.yellow(a2) + " " + this.options.map((s, c2) => {
|
|
34839
|
+
const l2 = this.value.includes(s.value), u = c2 === this.cursor;
|
|
34840
|
+
return u && l2 ? n(s, "active-selected") : l2 ? n(s, "selected") : n(s, u ? "active" : "inactive");
|
|
34841
|
+
}).join(`
|
|
34842
|
+
${import_picocolors2.default.yellow(a2)} `) + `
|
|
34843
|
+
` + t + `
|
|
34844
|
+
`;
|
|
34845
|
+
}
|
|
34846
|
+
default:
|
|
34847
|
+
return `${i}${import_picocolors2.default.cyan(a2)} ${this.options.map((t, s) => {
|
|
34848
|
+
const c2 = this.value.includes(t.value), l2 = s === this.cursor;
|
|
34849
|
+
return l2 && c2 ? n(t, "active-selected") : c2 ? n(t, "selected") : n(t, l2 ? "active" : "inactive");
|
|
34850
|
+
}).join(`
|
|
34851
|
+
${import_picocolors2.default.cyan(a2)} `)}
|
|
34852
|
+
${import_picocolors2.default.cyan(d2)}
|
|
34853
|
+
`;
|
|
34854
|
+
}
|
|
34855
|
+
} }).prompt();
|
|
34856
|
+
};
|
|
34646
34857
|
var ue = (r2 = "") => {
|
|
34647
34858
|
process.stdout.write(`${import_picocolors2.default.gray(d2)} ${import_picocolors2.default.red(r2)}
|
|
34648
34859
|
|
|
34649
34860
|
`);
|
|
34650
34861
|
};
|
|
34651
34862
|
var oe = (r2 = "") => {
|
|
34652
|
-
process.stdout.write(`${import_picocolors2.default.gray(
|
|
34863
|
+
process.stdout.write(`${import_picocolors2.default.gray(K2)} ${r2}
|
|
34653
34864
|
`);
|
|
34654
34865
|
};
|
|
34655
34866
|
var $e = (r2 = "") => {
|
|
@@ -34708,7 +34919,7 @@ var de = () => {
|
|
|
34708
34919
|
|
|
34709
34920
|
// src/lib/pro-installer.ts
|
|
34710
34921
|
var import_fs_extra12 = __toESM(require_lib4(), 1);
|
|
34711
|
-
import
|
|
34922
|
+
import os8 from "os";
|
|
34712
34923
|
import path14 from "path";
|
|
34713
34924
|
var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
|
|
34714
34925
|
var PREMIUM_BRANCH = "main";
|
|
@@ -34770,8 +34981,8 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
|
|
|
34770
34981
|
}
|
|
34771
34982
|
async function installProConfigs(options) {
|
|
34772
34983
|
const { githubToken, claudeCodeFolder } = options;
|
|
34773
|
-
const claudeFolder = claudeCodeFolder || path14.join(
|
|
34774
|
-
const tempDir = path14.join(
|
|
34984
|
+
const claudeFolder = claudeCodeFolder || path14.join(os8.homedir(), ".claude");
|
|
34985
|
+
const tempDir = path14.join(os8.tmpdir(), `aiblueprint-premium-${Date.now()}`);
|
|
34775
34986
|
try {
|
|
34776
34987
|
const success = await downloadDirectoryFromPrivateGitHub(PREMIUM_REPO, PREMIUM_BRANCH, "claude-code-config", tempDir, githubToken);
|
|
34777
34988
|
if (!success) {
|
|
@@ -34795,9 +35006,9 @@ async function installProConfigs(options) {
|
|
|
34795
35006
|
// src/lib/setup-helper.ts
|
|
34796
35007
|
var import_fs_extra13 = __toESM(require_lib4(), 1);
|
|
34797
35008
|
import path15 from "path";
|
|
34798
|
-
import
|
|
35009
|
+
import os9 from "os";
|
|
34799
35010
|
async function installBasicConfigs(options = {}, skipStatusline = false) {
|
|
34800
|
-
const claudeDir = options.claudeCodeFolder || path15.join(
|
|
35011
|
+
const claudeDir = options.claudeCodeFolder || path15.join(os9.homedir(), ".claude");
|
|
34801
35012
|
await import_fs_extra13.default.ensureDir(claudeDir);
|
|
34802
35013
|
console.log(source_default.gray("\uD83D\uDCE6 Installing free configurations..."));
|
|
34803
35014
|
console.log(source_default.gray(" • Commands..."));
|
|
@@ -34814,15 +35025,15 @@ async function installBasicConfigs(options = {}, skipStatusline = false) {
|
|
|
34814
35025
|
|
|
34815
35026
|
// src/lib/token-storage.ts
|
|
34816
35027
|
var import_fs_extra14 = __toESM(require_lib4(), 1);
|
|
34817
|
-
import
|
|
35028
|
+
import os10 from "os";
|
|
34818
35029
|
import path16 from "path";
|
|
34819
35030
|
function getConfigDir() {
|
|
34820
|
-
const platform =
|
|
35031
|
+
const platform = os10.platform();
|
|
34821
35032
|
if (platform === "win32") {
|
|
34822
|
-
const appData = process.env.APPDATA || path16.join(
|
|
35033
|
+
const appData = process.env.APPDATA || path16.join(os10.homedir(), "AppData", "Roaming");
|
|
34823
35034
|
return path16.join(appData, "aiblueprint");
|
|
34824
35035
|
} else {
|
|
34825
|
-
const configHome = process.env.XDG_CONFIG_HOME || path16.join(
|
|
35036
|
+
const configHome = process.env.XDG_CONFIG_HOME || path16.join(os10.homedir(), ".config");
|
|
34826
35037
|
return path16.join(configHome, "aiblueprint");
|
|
34827
35038
|
}
|
|
34828
35039
|
}
|
|
@@ -34849,7 +35060,7 @@ async function getToken() {
|
|
|
34849
35060
|
function getTokenInfo() {
|
|
34850
35061
|
return {
|
|
34851
35062
|
path: getTokenFilePath(),
|
|
34852
|
-
platform:
|
|
35063
|
+
platform: os10.platform()
|
|
34853
35064
|
};
|
|
34854
35065
|
}
|
|
34855
35066
|
|
|
@@ -35060,6 +35271,348 @@ async function proUpdateCommand(options = {}) {
|
|
|
35060
35271
|
}
|
|
35061
35272
|
}
|
|
35062
35273
|
|
|
35274
|
+
// src/commands/sync.ts
|
|
35275
|
+
import os11 from "os";
|
|
35276
|
+
import path19 from "path";
|
|
35277
|
+
|
|
35278
|
+
// src/lib/sync-utils.ts
|
|
35279
|
+
var import_fs_extra16 = __toESM(require_lib4(), 1);
|
|
35280
|
+
import path18 from "path";
|
|
35281
|
+
import crypto from "crypto";
|
|
35282
|
+
var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
|
|
35283
|
+
var PREMIUM_BRANCH2 = "main";
|
|
35284
|
+
function computeFileSha(content) {
|
|
35285
|
+
const size = content.length;
|
|
35286
|
+
const header = `blob ${size}\x00`;
|
|
35287
|
+
const fullContent = Buffer.concat([Buffer.from(header), content]);
|
|
35288
|
+
return crypto.createHash("sha1").update(fullContent).digest("hex");
|
|
35289
|
+
}
|
|
35290
|
+
async function listRemoteDirectory(dirPath, githubToken) {
|
|
35291
|
+
const apiUrl = `https://api.github.com/repos/${PREMIUM_REPO2}/contents/claude-code-config/${dirPath}?ref=${PREMIUM_BRANCH2}`;
|
|
35292
|
+
const response = await fetch(apiUrl, {
|
|
35293
|
+
headers: {
|
|
35294
|
+
Authorization: `token ${githubToken}`,
|
|
35295
|
+
Accept: "application/vnd.github.v3+json"
|
|
35296
|
+
}
|
|
35297
|
+
});
|
|
35298
|
+
if (!response.ok) {
|
|
35299
|
+
if (response.status === 404) {
|
|
35300
|
+
return [];
|
|
35301
|
+
}
|
|
35302
|
+
throw new Error(`Failed to list directory ${dirPath}: ${response.status}`);
|
|
35303
|
+
}
|
|
35304
|
+
const files = await response.json();
|
|
35305
|
+
if (!Array.isArray(files)) {
|
|
35306
|
+
return [];
|
|
35307
|
+
}
|
|
35308
|
+
return files;
|
|
35309
|
+
}
|
|
35310
|
+
async function computeLocalFileSha(filePath) {
|
|
35311
|
+
try {
|
|
35312
|
+
const content = await import_fs_extra16.default.readFile(filePath);
|
|
35313
|
+
return computeFileSha(content);
|
|
35314
|
+
} catch {
|
|
35315
|
+
return null;
|
|
35316
|
+
}
|
|
35317
|
+
}
|
|
35318
|
+
async function computeFolderSha(folderPath) {
|
|
35319
|
+
try {
|
|
35320
|
+
if (!await import_fs_extra16.default.pathExists(folderPath)) {
|
|
35321
|
+
return null;
|
|
35322
|
+
}
|
|
35323
|
+
const files = await getAllFilesRecursive(folderPath);
|
|
35324
|
+
if (files.length === 0) {
|
|
35325
|
+
return null;
|
|
35326
|
+
}
|
|
35327
|
+
const hashes = [];
|
|
35328
|
+
for (const file of files.sort()) {
|
|
35329
|
+
const content = await import_fs_extra16.default.readFile(file);
|
|
35330
|
+
hashes.push(computeFileSha(content));
|
|
35331
|
+
}
|
|
35332
|
+
return crypto.createHash("sha1").update(hashes.join("")).digest("hex");
|
|
35333
|
+
} catch {
|
|
35334
|
+
return null;
|
|
35335
|
+
}
|
|
35336
|
+
}
|
|
35337
|
+
async function getAllFilesRecursive(dir) {
|
|
35338
|
+
const files = [];
|
|
35339
|
+
const items = await import_fs_extra16.default.readdir(dir);
|
|
35340
|
+
for (const item of items) {
|
|
35341
|
+
const fullPath = path18.join(dir, item);
|
|
35342
|
+
const stat = await import_fs_extra16.default.stat(fullPath);
|
|
35343
|
+
if (stat.isDirectory()) {
|
|
35344
|
+
const subFiles = await getAllFilesRecursive(fullPath);
|
|
35345
|
+
files.push(...subFiles);
|
|
35346
|
+
} else {
|
|
35347
|
+
files.push(fullPath);
|
|
35348
|
+
}
|
|
35349
|
+
}
|
|
35350
|
+
return files;
|
|
35351
|
+
}
|
|
35352
|
+
async function computeRemoteFolderSha(dirPath, githubToken) {
|
|
35353
|
+
const hashes = [];
|
|
35354
|
+
await collectRemoteFolderHashes(dirPath, githubToken, hashes);
|
|
35355
|
+
hashes.sort();
|
|
35356
|
+
return crypto.createHash("sha1").update(hashes.join("")).digest("hex");
|
|
35357
|
+
}
|
|
35358
|
+
async function collectRemoteFolderHashes(dirPath, githubToken, hashes) {
|
|
35359
|
+
const files = await listRemoteDirectory(dirPath, githubToken);
|
|
35360
|
+
for (const file of files) {
|
|
35361
|
+
if (file.type === "file") {
|
|
35362
|
+
hashes.push(file.sha);
|
|
35363
|
+
} else if (file.type === "dir") {
|
|
35364
|
+
await collectRemoteFolderHashes(`${dirPath}/${file.name}`, githubToken, hashes);
|
|
35365
|
+
}
|
|
35366
|
+
}
|
|
35367
|
+
}
|
|
35368
|
+
async function analyzeSyncChanges(claudeDir, githubToken) {
|
|
35369
|
+
const items = [];
|
|
35370
|
+
const commandsRemote = await listRemoteDirectory("commands", githubToken);
|
|
35371
|
+
for (const file of commandsRemote) {
|
|
35372
|
+
if (file.type === "file" && file.name.endsWith(".md")) {
|
|
35373
|
+
const localPath = path18.join(claudeDir, "commands", file.name);
|
|
35374
|
+
const localSha = await computeLocalFileSha(localPath);
|
|
35375
|
+
let status = "new";
|
|
35376
|
+
if (localSha) {
|
|
35377
|
+
status = localSha === file.sha ? "unchanged" : "modified";
|
|
35378
|
+
}
|
|
35379
|
+
items.push({
|
|
35380
|
+
name: file.name.replace(".md", ""),
|
|
35381
|
+
relativePath: `commands/${file.name}`,
|
|
35382
|
+
type: "file",
|
|
35383
|
+
status,
|
|
35384
|
+
remoteSha: file.sha,
|
|
35385
|
+
localSha: localSha || undefined,
|
|
35386
|
+
category: "commands"
|
|
35387
|
+
});
|
|
35388
|
+
}
|
|
35389
|
+
}
|
|
35390
|
+
const agentsRemote = await listRemoteDirectory("agents", githubToken);
|
|
35391
|
+
for (const file of agentsRemote) {
|
|
35392
|
+
if (file.type === "file" && file.name.endsWith(".md")) {
|
|
35393
|
+
const localPath = path18.join(claudeDir, "agents", file.name);
|
|
35394
|
+
const localSha = await computeLocalFileSha(localPath);
|
|
35395
|
+
let status = "new";
|
|
35396
|
+
if (localSha) {
|
|
35397
|
+
status = localSha === file.sha ? "unchanged" : "modified";
|
|
35398
|
+
}
|
|
35399
|
+
items.push({
|
|
35400
|
+
name: file.name.replace(".md", ""),
|
|
35401
|
+
relativePath: `agents/${file.name}`,
|
|
35402
|
+
type: "file",
|
|
35403
|
+
status,
|
|
35404
|
+
remoteSha: file.sha,
|
|
35405
|
+
localSha: localSha || undefined,
|
|
35406
|
+
category: "agents"
|
|
35407
|
+
});
|
|
35408
|
+
}
|
|
35409
|
+
}
|
|
35410
|
+
const skillsRemote = await listRemoteDirectory("skills", githubToken);
|
|
35411
|
+
if (skillsRemote.length > 0) {
|
|
35412
|
+
const remoteSha = await computeRemoteFolderSha("skills", githubToken);
|
|
35413
|
+
const localSha = await computeFolderSha(path18.join(claudeDir, "skills"));
|
|
35414
|
+
let status = "new";
|
|
35415
|
+
if (localSha) {
|
|
35416
|
+
status = localSha === remoteSha ? "unchanged" : "modified";
|
|
35417
|
+
}
|
|
35418
|
+
items.push({
|
|
35419
|
+
name: "skills",
|
|
35420
|
+
relativePath: "skills",
|
|
35421
|
+
type: "folder",
|
|
35422
|
+
status,
|
|
35423
|
+
remoteSha,
|
|
35424
|
+
localSha: localSha || undefined,
|
|
35425
|
+
category: "skills"
|
|
35426
|
+
});
|
|
35427
|
+
}
|
|
35428
|
+
const scriptsRemote = await listRemoteDirectory("scripts", githubToken);
|
|
35429
|
+
if (scriptsRemote.length > 0) {
|
|
35430
|
+
const remoteSha = await computeRemoteFolderSha("scripts", githubToken);
|
|
35431
|
+
const localSha = await computeFolderSha(path18.join(claudeDir, "scripts"));
|
|
35432
|
+
let status = "new";
|
|
35433
|
+
if (localSha) {
|
|
35434
|
+
status = localSha === remoteSha ? "unchanged" : "modified";
|
|
35435
|
+
}
|
|
35436
|
+
items.push({
|
|
35437
|
+
name: "scripts",
|
|
35438
|
+
relativePath: "scripts",
|
|
35439
|
+
type: "folder",
|
|
35440
|
+
status,
|
|
35441
|
+
remoteSha,
|
|
35442
|
+
localSha: localSha || undefined,
|
|
35443
|
+
category: "scripts"
|
|
35444
|
+
});
|
|
35445
|
+
}
|
|
35446
|
+
return {
|
|
35447
|
+
items,
|
|
35448
|
+
newCount: items.filter((i) => i.status === "new").length,
|
|
35449
|
+
modifiedCount: items.filter((i) => i.status === "modified").length,
|
|
35450
|
+
unchangedCount: items.filter((i) => i.status === "unchanged").length
|
|
35451
|
+
};
|
|
35452
|
+
}
|
|
35453
|
+
async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken) {
|
|
35454
|
+
try {
|
|
35455
|
+
const url = `https://raw.githubusercontent.com/${PREMIUM_REPO2}/${PREMIUM_BRANCH2}/claude-code-config/${relativePath}`;
|
|
35456
|
+
const response = await fetch(url, {
|
|
35457
|
+
headers: {
|
|
35458
|
+
Authorization: `token ${githubToken}`,
|
|
35459
|
+
Accept: "application/vnd.github.v3.raw"
|
|
35460
|
+
}
|
|
35461
|
+
});
|
|
35462
|
+
if (!response.ok) {
|
|
35463
|
+
return false;
|
|
35464
|
+
}
|
|
35465
|
+
const content = await response.arrayBuffer();
|
|
35466
|
+
await import_fs_extra16.default.ensureDir(path18.dirname(targetPath));
|
|
35467
|
+
await import_fs_extra16.default.writeFile(targetPath, Buffer.from(content));
|
|
35468
|
+
return true;
|
|
35469
|
+
} catch {
|
|
35470
|
+
return false;
|
|
35471
|
+
}
|
|
35472
|
+
}
|
|
35473
|
+
async function downloadDirectoryFromPrivateGitHub2(dirPath, targetDir, githubToken) {
|
|
35474
|
+
try {
|
|
35475
|
+
const files = await listRemoteDirectory(dirPath, githubToken);
|
|
35476
|
+
await import_fs_extra16.default.ensureDir(targetDir);
|
|
35477
|
+
for (const file of files) {
|
|
35478
|
+
const relativePath = `${dirPath}/${file.name}`;
|
|
35479
|
+
const targetPath = path18.join(targetDir, file.name);
|
|
35480
|
+
if (file.type === "file") {
|
|
35481
|
+
await downloadFromPrivateGitHub2(relativePath, targetPath, githubToken);
|
|
35482
|
+
} else if (file.type === "dir") {
|
|
35483
|
+
await downloadDirectoryFromPrivateGitHub2(relativePath, targetPath, githubToken);
|
|
35484
|
+
}
|
|
35485
|
+
}
|
|
35486
|
+
return true;
|
|
35487
|
+
} catch {
|
|
35488
|
+
return false;
|
|
35489
|
+
}
|
|
35490
|
+
}
|
|
35491
|
+
async function syncSelectedItems(claudeDir, items, githubToken) {
|
|
35492
|
+
let success = 0;
|
|
35493
|
+
let failed = 0;
|
|
35494
|
+
for (const item of items) {
|
|
35495
|
+
const targetPath = path18.join(claudeDir, item.relativePath);
|
|
35496
|
+
if (item.type === "file") {
|
|
35497
|
+
const ok = await downloadFromPrivateGitHub2(item.relativePath, targetPath, githubToken);
|
|
35498
|
+
if (ok) {
|
|
35499
|
+
success++;
|
|
35500
|
+
} else {
|
|
35501
|
+
failed++;
|
|
35502
|
+
}
|
|
35503
|
+
} else {
|
|
35504
|
+
const ok = await downloadDirectoryFromPrivateGitHub2(item.relativePath, targetPath, githubToken);
|
|
35505
|
+
if (ok) {
|
|
35506
|
+
success++;
|
|
35507
|
+
} else {
|
|
35508
|
+
failed++;
|
|
35509
|
+
}
|
|
35510
|
+
}
|
|
35511
|
+
}
|
|
35512
|
+
return { success, failed };
|
|
35513
|
+
}
|
|
35514
|
+
|
|
35515
|
+
// src/commands/sync.ts
|
|
35516
|
+
async function proSyncCommand(options = {}) {
|
|
35517
|
+
oe(source_default.blue("\uD83D\uDD04 Sync Premium Configurations"));
|
|
35518
|
+
try {
|
|
35519
|
+
const githubToken = await getToken();
|
|
35520
|
+
if (!githubToken) {
|
|
35521
|
+
f2.error("No token found");
|
|
35522
|
+
f2.info("Run: aiblueprint claude-code pro activate <token>");
|
|
35523
|
+
$e(source_default.red("❌ Not activated"));
|
|
35524
|
+
process.exit(1);
|
|
35525
|
+
}
|
|
35526
|
+
const claudeDir = options.folder ? path19.resolve(options.folder) : path19.join(os11.homedir(), ".claude");
|
|
35527
|
+
const spinner = de();
|
|
35528
|
+
spinner.start("Analyzing changes...");
|
|
35529
|
+
const result = await analyzeSyncChanges(claudeDir, githubToken);
|
|
35530
|
+
spinner.stop("Analysis complete");
|
|
35531
|
+
if (result.newCount === 0 && result.modifiedCount === 0) {
|
|
35532
|
+
f2.success("Everything is up to date!");
|
|
35533
|
+
$e(source_default.green("✅ No changes needed"));
|
|
35534
|
+
return;
|
|
35535
|
+
}
|
|
35536
|
+
f2.info(`Found ${result.newCount} new, ${result.modifiedCount} modified, ${result.unchangedCount} unchanged`);
|
|
35537
|
+
const newItems = result.items.filter((i) => i.status === "new");
|
|
35538
|
+
const modifiedItems = result.items.filter((i) => i.status === "modified");
|
|
35539
|
+
const choices = [];
|
|
35540
|
+
if (newItems.length > 0) {
|
|
35541
|
+
for (const item of newItems) {
|
|
35542
|
+
choices.push({
|
|
35543
|
+
value: item,
|
|
35544
|
+
label: `\uD83C\uDD95 ${item.name}`,
|
|
35545
|
+
hint: `${item.category} (new ${item.type})`
|
|
35546
|
+
});
|
|
35547
|
+
}
|
|
35548
|
+
}
|
|
35549
|
+
if (modifiedItems.length > 0) {
|
|
35550
|
+
for (const item of modifiedItems) {
|
|
35551
|
+
choices.push({
|
|
35552
|
+
value: item,
|
|
35553
|
+
label: `\uD83D\uDCDD ${item.name}`,
|
|
35554
|
+
hint: `${item.category} (modified ${item.type})`
|
|
35555
|
+
});
|
|
35556
|
+
}
|
|
35557
|
+
}
|
|
35558
|
+
const selected = await ae({
|
|
35559
|
+
message: "Select items to sync:",
|
|
35560
|
+
options: choices,
|
|
35561
|
+
initialValues: choices.map((c2) => c2.value),
|
|
35562
|
+
required: false
|
|
35563
|
+
});
|
|
35564
|
+
if (lD(selected)) {
|
|
35565
|
+
ue("Sync cancelled");
|
|
35566
|
+
process.exit(0);
|
|
35567
|
+
}
|
|
35568
|
+
const selectedItems = selected;
|
|
35569
|
+
if (selectedItems.length === 0) {
|
|
35570
|
+
f2.warn("No items selected");
|
|
35571
|
+
$e(source_default.yellow("⚠️ Nothing to sync"));
|
|
35572
|
+
return;
|
|
35573
|
+
}
|
|
35574
|
+
const confirmResult = await se({
|
|
35575
|
+
message: `Sync ${selectedItems.length} item(s)?`,
|
|
35576
|
+
initialValue: true
|
|
35577
|
+
});
|
|
35578
|
+
if (lD(confirmResult) || !confirmResult) {
|
|
35579
|
+
ue("Sync cancelled");
|
|
35580
|
+
process.exit(0);
|
|
35581
|
+
}
|
|
35582
|
+
spinner.start(`Syncing ${selectedItems.length} item(s)...`);
|
|
35583
|
+
const syncResult = await syncSelectedItems(claudeDir, selectedItems, githubToken);
|
|
35584
|
+
spinner.stop("Sync complete");
|
|
35585
|
+
if (syncResult.failed > 0) {
|
|
35586
|
+
f2.warn(`${syncResult.success} succeeded, ${syncResult.failed} failed`);
|
|
35587
|
+
} else {
|
|
35588
|
+
f2.success(`${syncResult.success} item(s) synced successfully`);
|
|
35589
|
+
}
|
|
35590
|
+
const syncedByCategory = {
|
|
35591
|
+
commands: selectedItems.filter((i) => i.category === "commands").length,
|
|
35592
|
+
agents: selectedItems.filter((i) => i.category === "agents").length,
|
|
35593
|
+
skills: selectedItems.filter((i) => i.category === "skills").length,
|
|
35594
|
+
scripts: selectedItems.filter((i) => i.category === "scripts").length
|
|
35595
|
+
};
|
|
35596
|
+
const summary = [];
|
|
35597
|
+
if (syncedByCategory.commands > 0)
|
|
35598
|
+
summary.push(`${syncedByCategory.commands} command(s)`);
|
|
35599
|
+
if (syncedByCategory.agents > 0)
|
|
35600
|
+
summary.push(`${syncedByCategory.agents} agent(s)`);
|
|
35601
|
+
if (syncedByCategory.skills > 0)
|
|
35602
|
+
summary.push("skills folder");
|
|
35603
|
+
if (syncedByCategory.scripts > 0)
|
|
35604
|
+
summary.push("scripts folder");
|
|
35605
|
+
f2.info(`Synced: ${summary.join(", ")}`);
|
|
35606
|
+
$e(source_default.green("✅ Sync completed"));
|
|
35607
|
+
} catch (error) {
|
|
35608
|
+
if (error instanceof Error) {
|
|
35609
|
+
f2.error(error.message);
|
|
35610
|
+
}
|
|
35611
|
+
$e(source_default.red("❌ Sync failed"));
|
|
35612
|
+
process.exit(1);
|
|
35613
|
+
}
|
|
35614
|
+
}
|
|
35615
|
+
|
|
35063
35616
|
// src/cli.ts
|
|
35064
35617
|
import { readFileSync as readFileSync2 } from "fs";
|
|
35065
35618
|
import { dirname as dirname4, join } from "path";
|
|
@@ -35124,6 +35677,11 @@ proCmd.command("update").description("Update premium configurations").action((op
|
|
|
35124
35677
|
const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
|
|
35125
35678
|
proUpdateCommand({ folder: claudeCodeFolder });
|
|
35126
35679
|
});
|
|
35680
|
+
proCmd.command("sync").description("Sync premium configurations with selective update").action((options, command) => {
|
|
35681
|
+
const parentOptions = command.parent.parent.opts();
|
|
35682
|
+
const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
|
|
35683
|
+
proSyncCommand({ folder: claudeCodeFolder });
|
|
35684
|
+
});
|
|
35127
35685
|
program2.parse(process.argv);
|
|
35128
35686
|
if (!process.argv.slice(2).length) {
|
|
35129
35687
|
console.log(source_default.blue("\uD83D\uDE80 AIBlueprint CLI"));
|