aiblueprint-cli 1.4.16 → 1.4.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +0 -11
  2. package/dist/cli.js +153 -558
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -276,17 +276,6 @@ The CLI automatically manages your `~/.claude/settings.json` with:
276
276
  }
277
277
  ]
278
278
  }
279
- ],
280
- "PostToolUse": [
281
- {
282
- "matcher": "Edit|Write|MultiEdit",
283
- "hooks": [
284
- {
285
- "type": "command",
286
- "command": "bun ~/.claude/hooks/hook-post-file.ts"
287
- }
288
- ]
289
- }
290
279
  ]
291
280
  }
292
281
  }
package/dist/cli.js CHANGED
@@ -33195,24 +33195,6 @@ async function updateSettings(options, claudeDir) {
33195
33195
  }
33196
33196
  }
33197
33197
  }
33198
- if (options.postEditTypeScript) {
33199
- if (!settings.hooks.PostToolUse) {
33200
- settings.hooks.PostToolUse = [];
33201
- }
33202
- const postEditHook = {
33203
- matcher: "Edit|Write|MultiEdit",
33204
- hooks: [
33205
- {
33206
- type: "command",
33207
- command: `bun ${toPosixPath(path5.join(claudeDir, "scripts/hook-post-file.ts"))}`
33208
- }
33209
- ]
33210
- };
33211
- const existingPostEditHook = settings.hooks.PostToolUse.find((h) => h.matcher === "Edit|Write|MultiEdit" && h.hooks?.some((hook) => hook.command?.includes("hook-post-file.ts")));
33212
- if (!existingPostEditHook) {
33213
- settings.hooks.PostToolUse.push(postEditHook);
33214
- }
33215
- }
33216
33198
  await import_fs_extra3.default.writeJson(settingsPath, settings, { spaces: 2 });
33217
33199
  }
33218
33200
 
@@ -33296,7 +33278,7 @@ function getVersion() {
33296
33278
  const __dirname2 = dirname(fileURLToPath(import.meta.url));
33297
33279
  const packageJson = JSON.parse(readFileSync2(join(__dirname2, "../package.json"), "utf8"));
33298
33280
  cachedVersion = packageJson.version;
33299
- return cachedVersion;
33281
+ return cachedVersion ?? "unknown";
33300
33282
  } catch {
33301
33283
  return "unknown";
33302
33284
  }
@@ -33401,11 +33383,6 @@ async function setupCommand(params = {}) {
33401
33383
  name: "Notification sounds - Audio alerts for events",
33402
33384
  checked: true
33403
33385
  },
33404
- {
33405
- value: "postEditTypeScript",
33406
- name: "Post-edit TypeScript hook - Auto-format and lint TypeScript files",
33407
- checked: false
33408
- },
33409
33386
  {
33410
33387
  value: "codexSymlink",
33411
33388
  name: "Codex symlink - Link commands to ~/.codex/prompts",
@@ -33431,8 +33408,8 @@ async function setupCommand(params = {}) {
33431
33408
  customStatusline: features.includes("customStatusline"),
33432
33409
  aiblueprintCommands: features.includes("aiblueprintCommands"),
33433
33410
  aiblueprintAgents: features.includes("aiblueprintAgents"),
33411
+ aiblueprintSkills: false,
33434
33412
  notificationSounds: features.includes("notificationSounds"),
33435
- postEditTypeScript: features.includes("postEditTypeScript"),
33436
33413
  codexSymlink: features.includes("codexSymlink"),
33437
33414
  openCodeSymlink: features.includes("openCodeSymlink"),
33438
33415
  skipInteractive
@@ -33484,7 +33461,7 @@ async function setupCommand(params = {}) {
33484
33461
  await setupShellShortcuts();
33485
33462
  s.stop("Shell shortcuts configured");
33486
33463
  }
33487
- if (options.commandValidation || options.customStatusline || options.notificationSounds || options.postEditTypeScript) {
33464
+ if (options.commandValidation || options.customStatusline || options.notificationSounds) {
33488
33465
  s.start("Setting up scripts");
33489
33466
  if (useGitHub) {
33490
33467
  const scriptsDir = path8.join(claudeDir, "scripts");
@@ -33492,9 +33469,6 @@ async function setupCommand(params = {}) {
33492
33469
  if (options.commandValidation) {
33493
33470
  await downloadDirectoryFromGitHub("scripts/command-validator", path8.join(scriptsDir, "command-validator"));
33494
33471
  }
33495
- if (options.postEditTypeScript) {
33496
- await downloadFromGitHub("scripts/hook-post-file.ts", path8.join(scriptsDir, "hook-post-file.ts"));
33497
- }
33498
33472
  if (options.customStatusline) {
33499
33473
  await downloadDirectoryFromGitHub("scripts/statusline", path8.join(scriptsDir, "statusline"));
33500
33474
  await import_fs_extra6.default.ensureDir(path8.join(scriptsDir, "statusline/data"));
@@ -33712,7 +33686,7 @@ async function installOhMyZsh(homeDir) {
33712
33686
  const env2 = { ...process.env, HOME: homeDir, ZSH: path9.join(homeDir, ".oh-my-zsh") };
33713
33687
  exec(installCmd, { timeout: INSTALL_TIMEOUT, env: env2 }, (error, stdout, stderr) => {
33714
33688
  if (error) {
33715
- if (error.killed) {
33689
+ if ("killed" in error && error.killed) {
33716
33690
  reject(new Error("Oh My ZSH installation timed out. Please check your network connection."));
33717
33691
  } else {
33718
33692
  reject(new Error(`Failed to install Oh My ZSH: ${stderr || error.message}`));
@@ -33737,7 +33711,7 @@ async function installPlugin(pluginName, repoUrl, homeDir) {
33737
33711
  return new Promise((resolve, reject) => {
33738
33712
  exec(`git clone ${repoUrl} "${customPluginsDir}"`, { timeout: PLUGIN_TIMEOUT }, (error, stdout, stderr) => {
33739
33713
  if (error) {
33740
- if (error.killed) {
33714
+ if ("killed" in error && error.killed) {
33741
33715
  reject(new Error(`Plugin ${pluginName} installation timed out. Please check your network connection.`));
33742
33716
  } else {
33743
33717
  reject(new Error(`Failed to install ${pluginName}: ${stderr || error.message}`));
@@ -33941,438 +33915,6 @@ Next steps:`));
33941
33915
  }
33942
33916
  }
33943
33917
 
33944
- // src/commands/addHook.ts
33945
- var import_fs_extra11 = __toESM(require_lib4(), 1);
33946
- import path13 from "path";
33947
- import { fileURLToPath as fileURLToPath4 } from "url";
33948
- import { dirname as dirname4 } from "path";
33949
-
33950
- // src/utils/claude-config.ts
33951
- var import_fs_extra8 = __toESM(require_lib4(), 1);
33952
- import path10 from "path";
33953
- import { fileURLToPath as fileURLToPath3 } from "url";
33954
- import { dirname as dirname3 } from "path";
33955
- var __filename3 = fileURLToPath3(import.meta.url);
33956
- var __dirname3 = dirname3(__filename3);
33957
- function parseYamlFrontmatter(content) {
33958
- const lines = content.split(`
33959
- `);
33960
- if (lines[0] !== "---") {
33961
- return { metadata: {}, body: content };
33962
- }
33963
- const endIndex = lines.findIndex((line, index) => index > 0 && line === "---");
33964
- if (endIndex === -1) {
33965
- return { metadata: {}, body: content };
33966
- }
33967
- const frontmatterLines = lines.slice(1, endIndex);
33968
- const body = lines.slice(endIndex + 1).join(`
33969
- `);
33970
- const metadata = {};
33971
- frontmatterLines.forEach((line) => {
33972
- const colonIndex = line.indexOf(":");
33973
- if (colonIndex > -1) {
33974
- const key = line.substring(0, colonIndex).trim();
33975
- const value = line.substring(colonIndex + 1).trim();
33976
- metadata[key] = value;
33977
- }
33978
- });
33979
- return { metadata, body };
33980
- }
33981
- function getLocalConfigPaths(subDir) {
33982
- return [
33983
- path10.join(__dirname3, `../claude-code-config/${subDir}`),
33984
- path10.join(__dirname3, `../../claude-code-config/${subDir}`)
33985
- ];
33986
- }
33987
- async function findLocalConfigDir(subDir) {
33988
- const possiblePaths = getLocalConfigPaths(subDir);
33989
- for (const testPath of possiblePaths) {
33990
- if (await import_fs_extra8.default.pathExists(testPath)) {
33991
- return testPath;
33992
- }
33993
- }
33994
- return null;
33995
- }
33996
- async function getTargetDirectory(options) {
33997
- if (options.folder) {
33998
- return options.folder;
33999
- }
34000
- const cwd = process.cwd();
34001
- const localClaudeDir = path10.join(cwd, ".claude");
34002
- const isGitRepo = await import_fs_extra8.default.pathExists(path10.join(cwd, ".git"));
34003
- const hasClaudeConfig = await import_fs_extra8.default.pathExists(localClaudeDir);
34004
- if (isGitRepo || hasClaudeConfig) {
34005
- return localClaudeDir;
34006
- }
34007
- return path10.join(process.env.HOME || process.env.USERPROFILE || "~", ".claude");
34008
- }
34009
-
34010
- // src/utils/file-installer.ts
34011
- var import_fs_extra10 = __toESM(require_lib4(), 1);
34012
- import path12 from "path";
34013
-
34014
- // src/utils/github.ts
34015
- var import_fs_extra9 = __toESM(require_lib4(), 1);
34016
- import path11 from "path";
34017
- var GITHUB_RAW_BASE3 = "https://raw.githubusercontent.com/Melvynx/aiblueprint-cli/main/claude-code-config";
34018
- async function downloadFromGitHub2(relativePath) {
34019
- try {
34020
- const url = `${GITHUB_RAW_BASE3}/${relativePath}`;
34021
- const response = await fetch(url);
34022
- if (!response.ok) {
34023
- return null;
34024
- }
34025
- return await response.text();
34026
- } catch (error) {
34027
- return null;
34028
- }
34029
- }
34030
- async function listFilesFromGitHub(dirPath) {
34031
- try {
34032
- const apiUrl = `https://api.github.com/repos/Melvynx/aiblueprint-cli/contents/claude-code-config/${dirPath}`;
34033
- const response = await fetch(apiUrl);
34034
- if (!response.ok) {
34035
- return [];
34036
- }
34037
- const items = await response.json();
34038
- const files = [];
34039
- for (const item of items) {
34040
- if (item.type === "file") {
34041
- files.push(item.name);
34042
- } else if (item.type === "dir") {
34043
- const subFiles = await listFilesFromGitHub(`${dirPath}/${item.name}`);
34044
- files.push(...subFiles.map((f) => `${item.name}/${f}`));
34045
- }
34046
- }
34047
- return files;
34048
- } catch (error) {
34049
- return [];
34050
- }
34051
- }
34052
- async function isGitHubAvailable() {
34053
- try {
34054
- const testUrl = `${GITHUB_RAW_BASE3}/commands/apex.md`;
34055
- const testResponse = await fetch(testUrl);
34056
- return testResponse.ok;
34057
- } catch {
34058
- return false;
34059
- }
34060
- }
34061
- async function downloadAndWriteFile(relativePath, targetPath) {
34062
- const content = await downloadFromGitHub2(relativePath);
34063
- if (content) {
34064
- await import_fs_extra9.default.ensureDir(path11.dirname(targetPath));
34065
- await import_fs_extra9.default.writeFile(targetPath, content);
34066
- return true;
34067
- }
34068
- return false;
34069
- }
34070
-
34071
- // src/utils/file-installer.ts
34072
- async function installFileWithGitHubFallback(options) {
34073
- const { sourceDir, targetPath, fileName } = options;
34074
- await import_fs_extra10.default.ensureDir(path12.dirname(targetPath));
34075
- const useGitHub = options.useGitHub ?? await isGitHubAvailable();
34076
- if (useGitHub) {
34077
- const relativePath = `${sourceDir}/${fileName}`;
34078
- const success = await downloadAndWriteFile(relativePath, targetPath);
34079
- if (success) {
34080
- return;
34081
- }
34082
- console.log(source_default.yellow(`⚠️ GitHub download failed for ${fileName}, falling back to local files`));
34083
- }
34084
- const localConfigDir = await findLocalConfigDir(sourceDir);
34085
- if (!localConfigDir) {
34086
- throw new Error(`Neither GitHub nor local ${sourceDir} directory found`);
34087
- }
34088
- const localFilePath = path12.join(localConfigDir, fileName);
34089
- if (!await import_fs_extra10.default.pathExists(localFilePath)) {
34090
- throw new Error(`File not found: ${fileName}`);
34091
- }
34092
- await import_fs_extra10.default.copy(localFilePath, targetPath);
34093
- }
34094
- async function getFileContentWithGitHubFallback(sourceDir, fileName) {
34095
- const useGitHub = await isGitHubAvailable();
34096
- if (useGitHub) {
34097
- const content = await downloadFromGitHub2(`${sourceDir}/${fileName}`);
34098
- if (content) {
34099
- return content;
34100
- }
34101
- console.log(source_default.yellow(`⚠️ GitHub download failed for ${fileName}, falling back to local files`));
34102
- }
34103
- const localConfigDir = await findLocalConfigDir(sourceDir);
34104
- if (!localConfigDir) {
34105
- throw new Error(`Neither GitHub nor local ${sourceDir} directory found`);
34106
- }
34107
- const localFilePath = path12.join(localConfigDir, fileName);
34108
- if (!await import_fs_extra10.default.pathExists(localFilePath)) {
34109
- throw new Error(`File not found: ${fileName}`);
34110
- }
34111
- return await import_fs_extra10.default.readFile(localFilePath, "utf-8");
34112
- }
34113
-
34114
- // src/commands/addHook.ts
34115
- var __filename4 = fileURLToPath4(import.meta.url);
34116
- var __dirname4 = dirname4(__filename4);
34117
-
34118
- class SimpleSpinner2 {
34119
- message = "";
34120
- start(message) {
34121
- this.message = message;
34122
- console.log(source_default.gray(`⏳ ${message}...`));
34123
- }
34124
- stop(message) {
34125
- console.log(source_default.green(`✓ ${message}`));
34126
- }
34127
- }
34128
- var supportedHooks = {
34129
- "post-edit-typescript": {
34130
- name: "Post Edit TypeScript Hook",
34131
- description: "Runs Prettier, ESLint, and TypeScript checks after editing TypeScript files",
34132
- hookFile: "hook-post-file.ts",
34133
- sourceDir: "scripts",
34134
- targetDir: "scripts",
34135
- event: "PostToolUse",
34136
- matcher: "Edit|Write|MultiEdit"
34137
- }
34138
- };
34139
- async function addHookCommand(hookType, options) {
34140
- console.log(source_default.bgBlue(` aiblueprint-cli v${getVersion()} `));
34141
- if (!supportedHooks[hookType]) {
34142
- console.log(source_default.red(`❌ Unsupported hook type: ${hookType}`));
34143
- console.log(source_default.gray("Available hooks:"));
34144
- Object.entries(supportedHooks).forEach(([key, hook2]) => {
34145
- console.log(source_default.gray(` • ${key}: ${hook2.description}`));
34146
- });
34147
- process.exit(1);
34148
- }
34149
- const hook = supportedHooks[hookType];
34150
- const s = new SimpleSpinner2;
34151
- const targetDir = await getTargetDirectory(options);
34152
- const claudeDir = targetDir;
34153
- const targetHookDir = path13.join(claudeDir, hook.targetDir || "hooks");
34154
- const hookFilePath = path13.join(targetHookDir, hook.hookFile);
34155
- const settingsPath = path13.join(claudeDir, "settings.json");
34156
- if (await import_fs_extra11.default.pathExists(hookFilePath)) {
34157
- const overwriteAnswer = await lib_default.prompt([{
34158
- type: "confirm",
34159
- name: "overwrite",
34160
- message: `Hook file already exists at ${hookFilePath}. Overwrite?`
34161
- }]);
34162
- if (!overwriteAnswer.overwrite) {
34163
- console.log(source_default.yellow("Hook installation cancelled."));
34164
- process.exit(0);
34165
- }
34166
- }
34167
- try {
34168
- s.start("Installing hook...");
34169
- await import_fs_extra11.default.ensureDir(targetHookDir);
34170
- await installFileWithGitHubFallback({
34171
- sourceDir: hook.sourceDir || "hooks",
34172
- targetPath: hookFilePath,
34173
- fileName: hook.hookFile
34174
- });
34175
- await import_fs_extra11.default.chmod(hookFilePath, 493);
34176
- s.stop("Hook file installed");
34177
- s.start("Updating settings.json...");
34178
- let settings = {};
34179
- try {
34180
- const existingSettings = await import_fs_extra11.default.readFile(settingsPath, "utf-8");
34181
- settings = JSON.parse(existingSettings);
34182
- } catch {
34183
- settings = {};
34184
- }
34185
- if (!settings.hooks) {
34186
- settings.hooks = {};
34187
- }
34188
- if (!settings.hooks[hook.event]) {
34189
- settings.hooks[hook.event] = [];
34190
- }
34191
- const newHook = {
34192
- matcher: hook.matcher,
34193
- hooks: [
34194
- {
34195
- type: "command",
34196
- command: `bun $CLAUDE_PROJECT_DIR/.claude/${hook.targetDir || "hooks"}/${hook.hookFile}`
34197
- }
34198
- ]
34199
- };
34200
- const existingHook = settings.hooks[hook.event].find((h) => h.matcher === hook.matcher && h.hooks?.some((subHook) => subHook.command?.includes(hook.hookFile)));
34201
- if (existingHook) {
34202
- const replaceAnswer = await lib_default.prompt([{
34203
- type: "confirm",
34204
- name: "replace",
34205
- message: `A similar ${hook.event} hook already exists in settings.json. Replace it?`
34206
- }]);
34207
- if (!replaceAnswer.replace) {
34208
- console.log(source_default.yellow("Hook installation cancelled."));
34209
- process.exit(0);
34210
- } else {
34211
- settings.hooks[hook.event] = settings.hooks[hook.event].filter((h) => h !== existingHook);
34212
- settings.hooks[hook.event].push(newHook);
34213
- }
34214
- } else {
34215
- settings.hooks[hook.event].push(newHook);
34216
- }
34217
- await import_fs_extra11.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
34218
- s.stop("Settings updated");
34219
- console.log(source_default.green("✨ Hook installed successfully!"));
34220
- console.log(source_default.gray(`
34221
- Hook details:`));
34222
- console.log(source_default.gray(` • Name: ${hook.name}`));
34223
- console.log(source_default.gray(` • File: ${hookFilePath}`));
34224
- console.log(source_default.gray(` • Event: ${hook.event}`));
34225
- console.log(source_default.gray(` • Matcher: ${hook.matcher}`));
34226
- console.log(source_default.gray(`
34227
- The hook will run automatically when you edit TypeScript files with Claude Code.`));
34228
- } catch (error) {
34229
- s.stop("Installation failed");
34230
- console.log(source_default.red(`❌ Failed to install hook: ${error}`));
34231
- process.exit(1);
34232
- }
34233
- }
34234
-
34235
- // src/commands/addCommand.ts
34236
- var import_fs_extra12 = __toESM(require_lib4(), 1);
34237
- import path14 from "path";
34238
- class SimpleSpinner3 {
34239
- message = "";
34240
- start(message) {
34241
- this.message = message;
34242
- console.log(source_default.gray(`⏳ ${message}...`));
34243
- }
34244
- stop(message) {
34245
- console.log(source_default.green(`✓ ${message}`));
34246
- }
34247
- }
34248
- async function getLocalMdFilesRecursively(dir, basePath = "") {
34249
- const files = [];
34250
- const entries = await import_fs_extra12.default.readdir(dir, { withFileTypes: true });
34251
- for (const entry of entries) {
34252
- const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;
34253
- if (entry.isDirectory()) {
34254
- const subFiles = await getLocalMdFilesRecursively(path14.join(dir, entry.name), relativePath);
34255
- files.push(...subFiles);
34256
- } else if (entry.name.endsWith(".md")) {
34257
- files.push(relativePath);
34258
- }
34259
- }
34260
- return files;
34261
- }
34262
- async function discoverAvailableCommands() {
34263
- const commands = {};
34264
- const useGitHub = await isGitHubAvailable();
34265
- let mdFiles = [];
34266
- if (useGitHub) {
34267
- mdFiles = (await listFilesFromGitHub("commands")).filter((file) => file.endsWith(".md"));
34268
- }
34269
- if (mdFiles.length === 0) {
34270
- const commandsDir = await findLocalConfigDir("commands");
34271
- if (!commandsDir) {
34272
- throw new Error("Commands directory not found");
34273
- }
34274
- mdFiles = await getLocalMdFilesRecursively(commandsDir);
34275
- }
34276
- for (const file of mdFiles) {
34277
- const commandName = file.replace(".md", "");
34278
- try {
34279
- const content = await getFileContentWithGitHubFallback("commands", file);
34280
- const { metadata } = parseYamlFrontmatter(content);
34281
- commands[commandName] = {
34282
- name: commandName.split("/").map((part) => part.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase())).join("/"),
34283
- description: metadata.description || "No description available",
34284
- allowedTools: metadata["allowed-tools"],
34285
- argumentHint: metadata["argument-hint"],
34286
- commandFile: file
34287
- };
34288
- } catch (error) {
34289
- console.log(source_default.yellow(`⚠️ Warning: Could not process ${file}: ${error}`));
34290
- }
34291
- }
34292
- return commands;
34293
- }
34294
- function displayAvailableCommands(commands) {
34295
- console.log(source_default.bgBlue(" Available Claude Code Commands "));
34296
- console.log();
34297
- const maxNameLength = Math.max(...Object.values(commands).map((cmd) => cmd.name.length));
34298
- Object.entries(commands).forEach(([key, command]) => {
34299
- const paddedName = command.name.padEnd(maxNameLength);
34300
- console.log(source_default.blue(` ${key}`) + source_default.gray(` • ${command.description}`));
34301
- if (command.allowedTools) {
34302
- console.log(source_default.gray(` Tools: ${command.allowedTools}`));
34303
- }
34304
- if (command.argumentHint) {
34305
- console.log(source_default.gray(` Usage: ${key} ${command.argumentHint}`));
34306
- }
34307
- console.log();
34308
- });
34309
- console.log(source_default.gray("Usage:"));
34310
- console.log(source_default.gray(" npx aiblueprint-cli@latest claude-code add commands <command-name> # Install specific command"));
34311
- console.log(source_default.gray(" npx aiblueprint-cli@latest claude-code add commands # Show this list"));
34312
- }
34313
- async function addCommandCommand(commandName, options = {}) {
34314
- console.log(source_default.bgBlue(` aiblueprint-cli v${getVersion()} `));
34315
- const availableCommands = await discoverAvailableCommands();
34316
- if (!commandName) {
34317
- displayAvailableCommands(availableCommands);
34318
- return;
34319
- }
34320
- if (!availableCommands[commandName]) {
34321
- console.log(source_default.red(`❌ Command '${commandName}' not found.`));
34322
- console.log(source_default.gray("Available commands:"));
34323
- Object.keys(availableCommands).forEach((key) => {
34324
- console.log(source_default.gray(` • ${key}: ${availableCommands[key].description}`));
34325
- });
34326
- process.exit(1);
34327
- }
34328
- const command = availableCommands[commandName];
34329
- const s = new SimpleSpinner3;
34330
- const targetDir = await getTargetDirectory(options);
34331
- if (options.folder) {
34332
- console.log(source_default.gray(`Using custom folder: ${targetDir}`));
34333
- }
34334
- const commandsDir = path14.join(targetDir, "commands");
34335
- const commandFilePath = path14.join(commandsDir, command.commandFile);
34336
- if (await import_fs_extra12.default.pathExists(commandFilePath)) {
34337
- const overwriteAnswer = await lib_default.prompt([{
34338
- type: "confirm",
34339
- name: "overwrite",
34340
- message: `Command file already exists at ${commandFilePath}. Overwrite?`
34341
- }]);
34342
- if (!overwriteAnswer.overwrite) {
34343
- console.log(source_default.yellow("Command installation cancelled."));
34344
- process.exit(0);
34345
- }
34346
- }
34347
- try {
34348
- s.start("Installing command...");
34349
- await installFileWithGitHubFallback({
34350
- sourceDir: "commands",
34351
- targetPath: commandFilePath,
34352
- fileName: command.commandFile
34353
- });
34354
- s.stop("Command file installed");
34355
- console.log(source_default.green("✨ Command installed successfully!"));
34356
- console.log(source_default.gray(`
34357
- Command details:`));
34358
- console.log(source_default.gray(` • Name: ${command.name}`));
34359
- console.log(source_default.gray(` • File: ${commandFilePath}`));
34360
- console.log(source_default.gray(` • Description: ${command.description}`));
34361
- if (command.allowedTools) {
34362
- console.log(source_default.gray(` • Tools: ${command.allowedTools}`));
34363
- }
34364
- if (command.argumentHint) {
34365
- console.log(source_default.gray(` • Usage: ${commandName} ${command.argumentHint}`));
34366
- }
34367
- console.log(source_default.gray(`
34368
- The command will be available immediately in Claude Code.`));
34369
- } catch (error) {
34370
- s.stop("Installation failed");
34371
- console.log(source_default.red(`❌ Failed to install command: ${error}`));
34372
- process.exit(1);
34373
- }
34374
- }
34375
-
34376
33918
  // src/commands/symlink.ts
34377
33919
  var TOOLS = [
34378
33920
  {
@@ -34540,22 +34082,22 @@ async function symlinkCommand(params = {}) {
34540
34082
  }
34541
34083
 
34542
34084
  // src/commands/statusline.ts
34543
- var import_fs_extra13 = __toESM(require_lib4(), 1);
34544
- import path15 from "path";
34085
+ var import_fs_extra8 = __toESM(require_lib4(), 1);
34086
+ import path10 from "path";
34545
34087
  import { homedir } from "os";
34546
34088
  async function statuslineCommand(options) {
34547
- const claudeDir = options.folder ? path15.resolve(options.folder) : path15.join(homedir(), ".claude");
34089
+ const claudeDir = options.folder ? path10.resolve(options.folder) : path10.join(homedir(), ".claude");
34548
34090
  console.log(source_default.blue(`\uD83D\uDE80 Setting up AIBlueprint Statusline ${source_default.gray(`v${getVersion()}`)}...`));
34549
34091
  console.log(source_default.gray(` Target: ${claudeDir}
34550
34092
  `));
34551
- await import_fs_extra13.default.ensureDir(claudeDir);
34093
+ await import_fs_extra8.default.ensureDir(claudeDir);
34552
34094
  console.log(source_default.cyan("\uD83D\uDCE6 Checking dependencies..."));
34553
34095
  await checkAndInstallDependencies();
34554
34096
  console.log(source_default.cyan(`
34555
34097
  \uD83D\uDCE5 Downloading statusline files...`));
34556
- const scriptsDir = path15.join(claudeDir, "scripts");
34557
- await import_fs_extra13.default.ensureDir(scriptsDir);
34558
- const success = await downloadDirectoryFromGitHub("scripts/statusline", path15.join(scriptsDir, "statusline"));
34098
+ const scriptsDir = path10.join(claudeDir, "scripts");
34099
+ await import_fs_extra8.default.ensureDir(scriptsDir);
34100
+ const success = await downloadDirectoryFromGitHub("scripts/statusline", path10.join(scriptsDir, "statusline"));
34559
34101
  if (!success) {
34560
34102
  console.log(source_default.red(" Failed to download statusline files from GitHub"));
34561
34103
  return;
@@ -34565,18 +34107,18 @@ async function statuslineCommand(options) {
34565
34107
  await installStatuslineDependencies(claudeDir);
34566
34108
  console.log(source_default.cyan(`
34567
34109
  ⚙️ Configuring settings.json...`));
34568
- const settingsPath = path15.join(claudeDir, "settings.json");
34110
+ const settingsPath = path10.join(claudeDir, "settings.json");
34569
34111
  let settings = {};
34570
34112
  try {
34571
- const existingSettings = await import_fs_extra13.default.readFile(settingsPath, "utf-8");
34113
+ const existingSettings = await import_fs_extra8.default.readFile(settingsPath, "utf-8");
34572
34114
  settings = JSON.parse(existingSettings);
34573
34115
  } catch {}
34574
34116
  settings.statusLine = {
34575
34117
  type: "command",
34576
- command: `bun ${path15.join(claudeDir, "scripts/statusline/src/index.ts")}`,
34118
+ command: `bun ${path10.join(claudeDir, "scripts/statusline/src/index.ts")}`,
34577
34119
  padding: 0
34578
34120
  };
34579
- await import_fs_extra13.default.writeJson(settingsPath, settings, { spaces: 2 });
34121
+ await import_fs_extra8.default.writeJson(settingsPath, settings, { spaces: 2 });
34580
34122
  console.log(source_default.green(`
34581
34123
  ✅ Statusline setup complete!`));
34582
34124
  console.log(source_default.gray(`
@@ -35302,14 +34844,65 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
35302
34844
 
35303
34845
  // src/commands/pro.ts
35304
34846
  import os12 from "os";
35305
- import path18 from "path";
34847
+ import path13 from "path";
35306
34848
 
35307
34849
  // src/lib/pro-installer.ts
35308
- var import_fs_extra14 = __toESM(require_lib4(), 1);
34850
+ var import_fs_extra9 = __toESM(require_lib4(), 1);
35309
34851
  import os10 from "os";
35310
- import path16 from "path";
34852
+ import path11 from "path";
34853
+ import { exec as exec2 } from "child_process";
34854
+ import { promisify } from "util";
34855
+ var execAsync = promisify(exec2);
35311
34856
  var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
35312
34857
  var PREMIUM_BRANCH = "main";
34858
+ function getCacheRepoDir() {
34859
+ return path11.join(os10.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
34860
+ }
34861
+ async function execGitWithAuth(command, token, cwd) {
34862
+ const authConfig = `http.https://github.com/.extraheader=AUTHORIZATION: token ${token}`;
34863
+ const fullCommand = `git -c "${authConfig}" ${command}`;
34864
+ try {
34865
+ await execAsync(fullCommand, { cwd, timeout: 120000 });
34866
+ } catch (error) {
34867
+ throw new Error(`Git command failed: ${error instanceof Error ? error.message : "Unknown error"}`);
34868
+ }
34869
+ }
34870
+ async function cloneOrUpdateRepo(token) {
34871
+ const cacheDir = getCacheRepoDir();
34872
+ const repoUrl = `https://github.com/${PREMIUM_REPO}.git`;
34873
+ if (await import_fs_extra9.default.pathExists(path11.join(cacheDir, ".git"))) {
34874
+ try {
34875
+ await execGitWithAuth("pull", token, cacheDir);
34876
+ } catch (error) {
34877
+ await import_fs_extra9.default.remove(cacheDir);
34878
+ await import_fs_extra9.default.ensureDir(path11.dirname(cacheDir));
34879
+ await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token);
34880
+ }
34881
+ } else {
34882
+ await import_fs_extra9.default.ensureDir(path11.dirname(cacheDir));
34883
+ await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token);
34884
+ }
34885
+ return path11.join(cacheDir, "claude-code-config");
34886
+ }
34887
+ async function copyConfigFromCache(cacheConfigDir, targetDir, onProgress) {
34888
+ const walk = async (dir, baseDir = dir) => {
34889
+ const entries = await import_fs_extra9.default.readdir(dir, { withFileTypes: true });
34890
+ for (const entry of entries) {
34891
+ const sourcePath = path11.join(dir, entry.name);
34892
+ const relativePath = path11.relative(baseDir, sourcePath);
34893
+ const targetPath = path11.join(targetDir, relativePath);
34894
+ if (entry.isDirectory()) {
34895
+ await import_fs_extra9.default.ensureDir(targetPath);
34896
+ onProgress?.(relativePath, "directory");
34897
+ await walk(sourcePath, baseDir);
34898
+ } else {
34899
+ await import_fs_extra9.default.copy(sourcePath, targetPath, { overwrite: true });
34900
+ onProgress?.(relativePath, "file");
34901
+ }
34902
+ }
34903
+ };
34904
+ await walk(cacheConfigDir);
34905
+ }
35313
34906
  async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath, githubToken) {
35314
34907
  try {
35315
34908
  const url = `https://raw.githubusercontent.com/${repo}/${branch}/${relativePath}`;
@@ -35324,8 +34917,8 @@ async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath,
35324
34917
  return false;
35325
34918
  }
35326
34919
  const content = await response.arrayBuffer();
35327
- await import_fs_extra14.default.ensureDir(path16.dirname(targetPath));
35328
- await import_fs_extra14.default.writeFile(targetPath, Buffer.from(content));
34920
+ await import_fs_extra9.default.ensureDir(path11.dirname(targetPath));
34921
+ await import_fs_extra9.default.writeFile(targetPath, Buffer.from(content));
35329
34922
  return true;
35330
34923
  } catch (error) {
35331
34924
  console.error(`Error downloading ${relativePath}:`, error);
@@ -35350,10 +34943,10 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
35350
34943
  console.error(`Unexpected response for directory ${dirPath}`);
35351
34944
  return false;
35352
34945
  }
35353
- await import_fs_extra14.default.ensureDir(targetDir);
34946
+ await import_fs_extra9.default.ensureDir(targetDir);
35354
34947
  for (const file of files) {
35355
34948
  const relativePath = dirPath ? `${dirPath}/${file.name}` : file.name;
35356
- const targetPath = path16.join(targetDir, file.name);
34949
+ const targetPath = path11.join(targetDir, file.name);
35357
34950
  const displayPath = relativePath.replace("claude-code-config/", "");
35358
34951
  if (file.type === "file") {
35359
34952
  onProgress?.(displayPath, "file");
@@ -35370,55 +34963,61 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
35370
34963
  }
35371
34964
  async function installProConfigs(options) {
35372
34965
  const { githubToken, claudeCodeFolder, onProgress } = options;
35373
- const claudeFolder = claudeCodeFolder || path16.join(os10.homedir(), ".claude");
35374
- const tempDir = path16.join(os10.tmpdir(), `aiblueprint-premium-${Date.now()}`);
34966
+ const claudeFolder = claudeCodeFolder || path11.join(os10.homedir(), ".claude");
34967
+ try {
34968
+ const cacheConfigDir = await cloneOrUpdateRepo(githubToken);
34969
+ await copyConfigFromCache(cacheConfigDir, claudeFolder, onProgress);
34970
+ return;
34971
+ } catch (error) {
34972
+ console.warn("Git caching failed, falling back to API download");
34973
+ }
34974
+ const tempDir = path11.join(os10.tmpdir(), `aiblueprint-premium-${Date.now()}`);
35375
34975
  try {
35376
34976
  const success = await downloadDirectoryFromPrivateGitHub(PREMIUM_REPO, PREMIUM_BRANCH, "claude-code-config", tempDir, githubToken, onProgress);
35377
34977
  if (!success) {
35378
34978
  throw new Error("Failed to download premium configurations");
35379
34979
  }
35380
- await import_fs_extra14.default.copy(tempDir, claudeFolder, {
35381
- overwrite: true,
35382
- recursive: true
34980
+ await import_fs_extra9.default.copy(tempDir, claudeFolder, {
34981
+ overwrite: true
35383
34982
  });
35384
34983
  } catch (error) {
35385
34984
  throw new Error(`Failed to install premium configs: ${error instanceof Error ? error.message : "Unknown error"}`);
35386
34985
  } finally {
35387
34986
  try {
35388
- await import_fs_extra14.default.remove(tempDir);
34987
+ await import_fs_extra9.default.remove(tempDir);
35389
34988
  } catch {}
35390
34989
  }
35391
34990
  }
35392
34991
 
35393
34992
  // src/lib/token-storage.ts
35394
- var import_fs_extra15 = __toESM(require_lib4(), 1);
34993
+ var import_fs_extra10 = __toESM(require_lib4(), 1);
35395
34994
  import os11 from "os";
35396
- import path17 from "path";
34995
+ import path12 from "path";
35397
34996
  function getConfigDir() {
35398
34997
  const platform = os11.platform();
35399
34998
  if (platform === "win32") {
35400
- const appData = process.env.APPDATA || path17.join(os11.homedir(), "AppData", "Roaming");
35401
- return path17.join(appData, "aiblueprint");
34999
+ const appData = process.env.APPDATA || path12.join(os11.homedir(), "AppData", "Roaming");
35000
+ return path12.join(appData, "aiblueprint");
35402
35001
  } else {
35403
- const configHome = process.env.XDG_CONFIG_HOME || path17.join(os11.homedir(), ".config");
35404
- return path17.join(configHome, "aiblueprint");
35002
+ const configHome = process.env.XDG_CONFIG_HOME || path12.join(os11.homedir(), ".config");
35003
+ return path12.join(configHome, "aiblueprint");
35405
35004
  }
35406
35005
  }
35407
35006
  function getTokenFilePath() {
35408
- return path17.join(getConfigDir(), "token.txt");
35007
+ return path12.join(getConfigDir(), "token.txt");
35409
35008
  }
35410
35009
  async function saveToken(githubToken) {
35411
35010
  const tokenFile = getTokenFilePath();
35412
- await import_fs_extra15.default.ensureDir(path17.dirname(tokenFile));
35413
- await import_fs_extra15.default.writeFile(tokenFile, githubToken, { mode: 384 });
35011
+ await import_fs_extra10.default.ensureDir(path12.dirname(tokenFile));
35012
+ await import_fs_extra10.default.writeFile(tokenFile, githubToken, { mode: 384 });
35414
35013
  }
35415
35014
  async function getToken() {
35416
35015
  const tokenFile = getTokenFilePath();
35417
- if (!await import_fs_extra15.default.pathExists(tokenFile)) {
35016
+ if (!await import_fs_extra10.default.pathExists(tokenFile)) {
35418
35017
  return null;
35419
35018
  }
35420
35019
  try {
35421
- const token = await import_fs_extra15.default.readFile(tokenFile, "utf-8");
35020
+ const token = await import_fs_extra10.default.readFile(tokenFile, "utf-8");
35422
35021
  return token.trim();
35423
35022
  } catch (error) {
35424
35023
  return null;
@@ -35432,7 +35031,7 @@ function getTokenInfo() {
35432
35031
  }
35433
35032
 
35434
35033
  // src/commands/pro.ts
35435
- var import_fs_extra16 = __toESM(require_lib4(), 1);
35034
+ var import_fs_extra11 = __toESM(require_lib4(), 1);
35436
35035
  var API_URL = "https://codeline.app/api/products";
35437
35036
  var PRODUCT_IDS = ["prd_XJVgxVPbGG", "prd_NKabAkdOkw"];
35438
35037
  async function countInstalledItems(claudeDir) {
@@ -35442,30 +35041,36 @@ async function countInstalledItems(claudeDir) {
35442
35041
  skills: 0
35443
35042
  };
35444
35043
  try {
35445
- const commandsDir = path18.join(claudeDir, "commands");
35446
- if (await import_fs_extra16.default.pathExists(commandsDir)) {
35447
- const files = await import_fs_extra16.default.readdir(commandsDir);
35044
+ const commandsDir = path13.join(claudeDir, "commands");
35045
+ if (await import_fs_extra11.default.pathExists(commandsDir)) {
35046
+ const files = await import_fs_extra11.default.readdir(commandsDir);
35448
35047
  counts.commands = files.filter((f) => f.endsWith(".md")).length;
35449
35048
  }
35450
- } catch {}
35049
+ } catch (error) {
35050
+ console.error("Failed to count commands:", error instanceof Error ? error.message : error);
35051
+ }
35451
35052
  try {
35452
- const agentsDir = path18.join(claudeDir, "agents");
35453
- if (await import_fs_extra16.default.pathExists(agentsDir)) {
35454
- const files = await import_fs_extra16.default.readdir(agentsDir);
35053
+ const agentsDir = path13.join(claudeDir, "agents");
35054
+ if (await import_fs_extra11.default.pathExists(agentsDir)) {
35055
+ const files = await import_fs_extra11.default.readdir(agentsDir);
35455
35056
  counts.agents = files.filter((f) => f.endsWith(".md")).length;
35456
35057
  }
35457
- } catch {}
35058
+ } catch (error) {
35059
+ console.error("Failed to count agents:", error instanceof Error ? error.message : error);
35060
+ }
35458
35061
  try {
35459
- const skillsDir = path18.join(claudeDir, "skills");
35460
- if (await import_fs_extra16.default.pathExists(skillsDir)) {
35461
- const items = await import_fs_extra16.default.readdir(skillsDir);
35062
+ const skillsDir = path13.join(claudeDir, "skills");
35063
+ if (await import_fs_extra11.default.pathExists(skillsDir)) {
35064
+ const items = await import_fs_extra11.default.readdir(skillsDir);
35462
35065
  const dirs = await Promise.all(items.map(async (item) => {
35463
- const stat = await import_fs_extra16.default.stat(path18.join(skillsDir, item));
35066
+ const stat = await import_fs_extra11.default.stat(path13.join(skillsDir, item));
35464
35067
  return stat.isDirectory();
35465
35068
  }));
35466
35069
  counts.skills = dirs.filter(Boolean).length;
35467
35070
  }
35468
- } catch {}
35071
+ } catch (error) {
35072
+ console.error("Failed to count skills:", error instanceof Error ? error.message : error);
35073
+ }
35469
35074
  return counts;
35470
35075
  }
35471
35076
  async function proActivateCommand(userToken) {
@@ -35571,7 +35176,7 @@ async function proSetupCommand(options = {}) {
35571
35176
  Se(source_default.red("❌ Not activated"));
35572
35177
  process.exit(1);
35573
35178
  }
35574
- const claudeDir = options.folder ? path18.resolve(options.folder) : path18.join(os12.homedir(), ".claude");
35179
+ const claudeDir = options.folder ? path13.resolve(options.folder) : path13.join(os12.homedir(), ".claude");
35575
35180
  const spinner = Y2();
35576
35181
  const onProgress = (file, type) => {
35577
35182
  spinner.message(`Installing: ${source_default.cyan(file)} ${source_default.gray(`(${type})`)}`);
@@ -35594,10 +35199,15 @@ async function proSetupCommand(options = {}) {
35594
35199
  spinner.stop("Shell shortcuts configured");
35595
35200
  spinner.start("Updating settings.json...");
35596
35201
  await updateSettings({
35202
+ shellShortcuts: false,
35597
35203
  commandValidation: true,
35598
35204
  customStatusline: true,
35205
+ aiblueprintCommands: false,
35206
+ aiblueprintAgents: false,
35207
+ aiblueprintSkills: false,
35599
35208
  notificationSounds: true,
35600
- postEditTypeScript: true
35209
+ codexSymlink: false,
35210
+ openCodeSymlink: false
35601
35211
  }, claudeDir);
35602
35212
  spinner.stop("Settings.json updated");
35603
35213
  spinner.start("Counting installed items...");
@@ -35649,11 +35259,11 @@ async function proUpdateCommand(options = {}) {
35649
35259
 
35650
35260
  // src/commands/sync.ts
35651
35261
  import os13 from "os";
35652
- import path20 from "path";
35262
+ import path15 from "path";
35653
35263
 
35654
35264
  // src/lib/sync-utils.ts
35655
- var import_fs_extra17 = __toESM(require_lib4(), 1);
35656
- import path19 from "path";
35265
+ var import_fs_extra12 = __toESM(require_lib4(), 1);
35266
+ import path14 from "path";
35657
35267
  import crypto from "crypto";
35658
35268
  var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
35659
35269
  var PREMIUM_BRANCH2 = "main";
@@ -35702,7 +35312,7 @@ async function listRemoteFilesRecursive(dirPath, githubToken, basePath = "") {
35702
35312
  }
35703
35313
  async function computeLocalFileSha(filePath) {
35704
35314
  try {
35705
- const content = await import_fs_extra17.default.readFile(filePath);
35315
+ const content = await import_fs_extra12.default.readFile(filePath);
35706
35316
  return computeFileSha(content);
35707
35317
  } catch {
35708
35318
  return null;
@@ -35710,15 +35320,15 @@ async function computeLocalFileSha(filePath) {
35710
35320
  }
35711
35321
  async function listLocalFiles(dir) {
35712
35322
  const files = [];
35713
- if (!await import_fs_extra17.default.pathExists(dir)) {
35323
+ if (!await import_fs_extra12.default.pathExists(dir)) {
35714
35324
  return files;
35715
35325
  }
35716
- const items = await import_fs_extra17.default.readdir(dir);
35326
+ const items = await import_fs_extra12.default.readdir(dir);
35717
35327
  for (const item of items) {
35718
35328
  if (item === "node_modules" || item === ".DS_Store")
35719
35329
  continue;
35720
- const fullPath = path19.join(dir, item);
35721
- const stat = await import_fs_extra17.default.stat(fullPath);
35330
+ const fullPath = path14.join(dir, item);
35331
+ const stat = await import_fs_extra12.default.stat(fullPath);
35722
35332
  if (stat.isDirectory()) {
35723
35333
  files.push(item);
35724
35334
  const subFiles = await listLocalFilesRecursive(fullPath, item);
@@ -35731,13 +35341,13 @@ async function listLocalFiles(dir) {
35731
35341
  }
35732
35342
  async function listLocalFilesRecursive(dir, basePath) {
35733
35343
  const files = [];
35734
- const items = await import_fs_extra17.default.readdir(dir);
35344
+ const items = await import_fs_extra12.default.readdir(dir);
35735
35345
  for (const item of items) {
35736
35346
  if (item === "node_modules" || item === ".DS_Store")
35737
35347
  continue;
35738
- const fullPath = path19.join(dir, item);
35348
+ const fullPath = path14.join(dir, item);
35739
35349
  const relativePath = `${basePath}/${item}`;
35740
- const stat = await import_fs_extra17.default.stat(fullPath);
35350
+ const stat = await import_fs_extra12.default.stat(fullPath);
35741
35351
  if (stat.isDirectory()) {
35742
35352
  files.push(relativePath);
35743
35353
  const subFiles = await listLocalFilesRecursive(fullPath, relativePath);
@@ -35750,7 +35360,7 @@ async function listLocalFilesRecursive(dir, basePath) {
35750
35360
  }
35751
35361
  async function analyzeCategory(category, claudeDir, githubToken) {
35752
35362
  const items = [];
35753
- const localDir = path19.join(claudeDir, category);
35363
+ const localDir = path14.join(claudeDir, category);
35754
35364
  const remoteFiles = await listRemoteFilesRecursive(category, githubToken);
35755
35365
  const localFiles = await listLocalFiles(localDir);
35756
35366
  const remoteSet = new Map;
@@ -35759,7 +35369,7 @@ async function analyzeCategory(category, claudeDir, githubToken) {
35759
35369
  }
35760
35370
  const localSet = new Set(localFiles);
35761
35371
  for (const [remotePath, { sha, isFolder }] of remoteSet) {
35762
- const localPath = path19.join(localDir, remotePath);
35372
+ const localPath = path14.join(localDir, remotePath);
35763
35373
  if (isFolder) {
35764
35374
  continue;
35765
35375
  }
@@ -35802,8 +35412,8 @@ async function analyzeCategory(category, claudeDir, githubToken) {
35802
35412
  if (parentAlreadyDeleted) {
35803
35413
  continue;
35804
35414
  }
35805
- const fullPath = path19.join(localDir, localPath);
35806
- const stat = await import_fs_extra17.default.stat(fullPath).catch(() => null);
35415
+ const fullPath = path14.join(localDir, localPath);
35416
+ const stat = await import_fs_extra12.default.stat(fullPath).catch(() => null);
35807
35417
  if (stat) {
35808
35418
  const isFolder = stat.isDirectory();
35809
35419
  items.push({
@@ -35839,9 +35449,9 @@ async function fetchRemoteSettings(githubToken) {
35839
35449
  }
35840
35450
  }
35841
35451
  async function getLocalSettings(claudeDir) {
35842
- const settingsPath = path19.join(claudeDir, "settings.json");
35452
+ const settingsPath = path14.join(claudeDir, "settings.json");
35843
35453
  try {
35844
- const content = await import_fs_extra17.default.readFile(settingsPath, "utf-8");
35454
+ const content = await import_fs_extra12.default.readFile(settingsPath, "utf-8");
35845
35455
  return JSON.parse(content);
35846
35456
  } catch {
35847
35457
  return {};
@@ -35923,8 +35533,8 @@ async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken)
35923
35533
  return false;
35924
35534
  }
35925
35535
  const content = await response.arrayBuffer();
35926
- await import_fs_extra17.default.ensureDir(path19.dirname(targetPath));
35927
- await import_fs_extra17.default.writeFile(targetPath, Buffer.from(content));
35536
+ await import_fs_extra12.default.ensureDir(path14.dirname(targetPath));
35537
+ await import_fs_extra12.default.writeFile(targetPath, Buffer.from(content));
35928
35538
  return true;
35929
35539
  } catch {
35930
35540
  return false;
@@ -35934,10 +35544,10 @@ async function syncSelectedHooks(claudeDir, hooks, onProgress) {
35934
35544
  if (hooks.length === 0) {
35935
35545
  return { success: 0, failed: 0 };
35936
35546
  }
35937
- const settingsPath = path19.join(claudeDir, "settings.json");
35547
+ const settingsPath = path14.join(claudeDir, "settings.json");
35938
35548
  let settings = {};
35939
35549
  try {
35940
- const content = await import_fs_extra17.default.readFile(settingsPath, "utf-8");
35550
+ const content = await import_fs_extra12.default.readFile(settingsPath, "utf-8");
35941
35551
  settings = JSON.parse(content);
35942
35552
  } catch {
35943
35553
  settings = {};
@@ -35965,7 +35575,7 @@ async function syncSelectedHooks(claudeDir, hooks, onProgress) {
35965
35575
  failed++;
35966
35576
  }
35967
35577
  }
35968
- await import_fs_extra17.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
35578
+ await import_fs_extra12.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
35969
35579
  return { success, failed };
35970
35580
  }
35971
35581
  async function syncSelectedItems(claudeDir, items, githubToken, onProgress) {
@@ -35973,11 +35583,11 @@ async function syncSelectedItems(claudeDir, items, githubToken, onProgress) {
35973
35583
  let failed = 0;
35974
35584
  let deleted = 0;
35975
35585
  for (const item of items) {
35976
- const targetPath = path19.join(claudeDir, item.relativePath);
35586
+ const targetPath = path14.join(claudeDir, item.relativePath);
35977
35587
  if (item.status === "deleted") {
35978
35588
  onProgress?.(item.relativePath, "deleting");
35979
35589
  try {
35980
- await import_fs_extra17.default.remove(targetPath);
35590
+ await import_fs_extra12.default.remove(targetPath);
35981
35591
  deleted++;
35982
35592
  } catch {
35983
35593
  failed++;
@@ -36129,7 +35739,7 @@ async function proSyncCommand(options = {}) {
36129
35739
  Se(source_default.red("❌ Not activated"));
36130
35740
  process.exit(1);
36131
35741
  }
36132
- const claudeDir = options.folder ? path20.resolve(options.folder) : path20.join(os13.homedir(), ".claude");
35742
+ const claudeDir = options.folder ? path15.resolve(options.folder) : path15.join(os13.homedir(), ".claude");
36133
35743
  const spinner = Y2();
36134
35744
  spinner.start("Analyzing changes...");
36135
35745
  const result = await analyzeSyncChanges(claudeDir, githubToken);
@@ -36359,10 +35969,10 @@ async function proSyncCommand(options = {}) {
36359
35969
 
36360
35970
  // src/cli.ts
36361
35971
  import { readFileSync as readFileSync3 } from "fs";
36362
- import { dirname as dirname5, join as join2 } from "path";
36363
- import { fileURLToPath as fileURLToPath5 } from "url";
36364
- var __dirname5 = dirname5(fileURLToPath5(import.meta.url));
36365
- var packageJson = JSON.parse(readFileSync3(join2(__dirname5, "../package.json"), "utf8"));
35972
+ import { dirname as dirname3, join as join2 } from "path";
35973
+ import { fileURLToPath as fileURLToPath3 } from "url";
35974
+ var __dirname3 = dirname3(fileURLToPath3(import.meta.url));
35975
+ var packageJson = JSON.parse(readFileSync3(join2(__dirname3, "../package.json"), "utf8"));
36366
35976
  var program2 = new Command;
36367
35977
  program2.name("aiblueprint").description("AIBlueprint CLI for setting up Claude Code configurations").version(packageJson.version);
36368
35978
  var claudeCodeCmd = program2.command("claude-code").description("Claude Code configuration commands").option("-f, --folder <path>", "Specify custom Claude Code folder path (default: ~/.claude) - alias for --claudeCodeFolder").option("--claudeCodeFolder <path>", "Specify custom Claude Code folder path (default: ~/.claude)").option("--codexFolder <path>", "Specify custom Codex folder path (default: ~/.codex)").option("--openCodeFolder <path>", "Specify custom OpenCode folder path (default: ~/.config/opencode)").option("--factoryAiFolder <path>", "Specify custom FactoryAI folder path (default: ~/.factory)").option("-s, --skip", "Skip interactive prompts and install all features");
@@ -36382,21 +35992,6 @@ claudeCodeCmd.command("setup-terminal").description("Setup terminal with Oh My Z
36382
35992
  homeDir: parentOptions.claudeCodeFolder || parentOptions.folder
36383
35993
  });
36384
35994
  });
36385
- var addCmd = claudeCodeCmd.command("add").description(`Add components to your Claude Code configuration
36386
- ` + `Examples:
36387
- ` + ` npx aiblueprint-cli@latest claude-code add hook post-edit-typescript
36388
- ` + ` npx aiblueprint-cli@latest claude-code add commands
36389
- ` + " npx aiblueprint-cli@latest claude-code add commands commit");
36390
- addCmd.command("hook <type>").description("Add a hook to your Claude Code configuration. Available types: post-edit-typescript").action((type, options, command) => {
36391
- const parentOptions = command.parent.parent.opts();
36392
- const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
36393
- addHookCommand(type, { folder: claudeCodeFolder });
36394
- });
36395
- addCmd.command("commands [command-name]").description("Install a Claude Code command or list all available commands (use without argument to list)").action((commandName, options, command) => {
36396
- const parentOptions = command.parent.parent.opts();
36397
- const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
36398
- addCommandCommand(commandName, { folder: claudeCodeFolder });
36399
- });
36400
35995
  claudeCodeCmd.command("symlink").description("Create symlinks between different CLI tools (Claude Code, Codex, OpenCode, FactoryAI)").action((options, command) => {
36401
35996
  const parentOptions = command.parent.opts();
36402
35997
  symlinkCommand({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiblueprint-cli",
3
- "version": "1.4.16",
3
+ "version": "1.4.17",
4
4
  "description": "AIBlueprint CLI for setting up Claude Code configurations",
5
5
  "author": "AIBlueprint",
6
6
  "license": "MIT",