aiblueprint-cli 1.4.55 → 1.4.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -32263,9 +32263,9 @@ var inquirer = {
32263
32263
  var lib_default = inquirer;
32264
32264
 
32265
32265
  // src/commands/setup.ts
32266
- var import_fs_extra7 = __toESM(require_lib4(), 1);
32267
- import path11 from "path";
32268
- import os11 from "os";
32266
+ var import_fs_extra8 = __toESM(require_lib4(), 1);
32267
+ import path12 from "path";
32268
+ import os10 from "os";
32269
32269
 
32270
32270
  // node_modules/chalk/source/vendor/ansi-styles/index.js
32271
32271
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -33051,110 +33051,10 @@ function getVersion() {
33051
33051
  }
33052
33052
  }
33053
33053
 
33054
- // src/lib/backup-utils.ts
33054
+ // src/lib/platform.ts
33055
33055
  var import_fs_extra4 = __toESM(require_lib4(), 1);
33056
- import path6 from "path";
33057
33056
  import os6 from "os";
33058
- var BACKUP_BASE_DIR = path6.join(os6.homedir(), ".config", "aiblueprint", "backup");
33059
- function formatDate(date) {
33060
- const pad = (n) => n.toString().padStart(2, "0");
33061
- return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
33062
- }
33063
- async function listBackups() {
33064
- const exists = await import_fs_extra4.default.pathExists(BACKUP_BASE_DIR);
33065
- if (!exists) {
33066
- return [];
33067
- }
33068
- const entries = await import_fs_extra4.default.readdir(BACKUP_BASE_DIR, { withFileTypes: true });
33069
- const backups = [];
33070
- for (const entry of entries) {
33071
- if (!entry.isDirectory())
33072
- continue;
33073
- const match = entry.name.match(/^(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})$/);
33074
- if (!match)
33075
- continue;
33076
- const [, year, month, day, hour, minute, second] = match;
33077
- const date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second));
33078
- backups.push({
33079
- name: entry.name,
33080
- path: path6.join(BACKUP_BASE_DIR, entry.name),
33081
- date
33082
- });
33083
- }
33084
- return backups.sort((a, b) => b.date.getTime() - a.date.getTime());
33085
- }
33086
- var AGENTS_BACKUP_SUBDIR = ".agents";
33087
- var CLAUDE_ITEMS = ["commands", "agents", "skills", "scripts", "settings.json"];
33088
- async function copyForBackup(sourcePath, destPath) {
33089
- await import_fs_extra4.default.copy(sourcePath, destPath, {
33090
- overwrite: true,
33091
- dereference: false,
33092
- filter: async (src) => {
33093
- try {
33094
- const stat = await import_fs_extra4.default.lstat(src);
33095
- return !stat.isSymbolicLink();
33096
- } catch {
33097
- return true;
33098
- }
33099
- }
33100
- });
33101
- }
33102
- async function hasMeaningfulContent(dir) {
33103
- if (!await import_fs_extra4.default.pathExists(dir))
33104
- return false;
33105
- const files = await import_fs_extra4.default.readdir(dir);
33106
- return files.some((f) => f !== ".DS_Store");
33107
- }
33108
- async function loadBackup(backupPath, claudeDir, agentsDir) {
33109
- const exists = await import_fs_extra4.default.pathExists(backupPath);
33110
- if (!exists) {
33111
- throw new Error(`Backup not found: ${backupPath}`);
33112
- }
33113
- await import_fs_extra4.default.ensureDir(claudeDir);
33114
- for (const item of CLAUDE_ITEMS) {
33115
- const sourcePath = path6.join(backupPath, item);
33116
- const destPath = path6.join(claudeDir, item);
33117
- if (await import_fs_extra4.default.pathExists(sourcePath)) {
33118
- await copyForBackup(sourcePath, destPath);
33119
- }
33120
- }
33121
- if (agentsDir) {
33122
- const agentsBackupPath = path6.join(backupPath, AGENTS_BACKUP_SUBDIR);
33123
- if (await import_fs_extra4.default.pathExists(agentsBackupPath)) {
33124
- await import_fs_extra4.default.ensureDir(agentsDir);
33125
- await copyForBackup(agentsBackupPath, agentsDir);
33126
- }
33127
- }
33128
- }
33129
- async function createBackup(claudeDir, agentsDir) {
33130
- const claudeHasContent = await hasMeaningfulContent(claudeDir);
33131
- const agentsHasContent = agentsDir ? await hasMeaningfulContent(agentsDir) : false;
33132
- if (!claudeHasContent && !agentsHasContent) {
33133
- return null;
33134
- }
33135
- const timestamp = formatDate(new Date);
33136
- const backupPath = path6.join(BACKUP_BASE_DIR, timestamp);
33137
- await import_fs_extra4.default.ensureDir(backupPath);
33138
- if (claudeHasContent) {
33139
- for (const item of CLAUDE_ITEMS) {
33140
- const sourcePath = path6.join(claudeDir, item);
33141
- const destPath = path6.join(backupPath, item);
33142
- if (await import_fs_extra4.default.pathExists(sourcePath)) {
33143
- await copyForBackup(sourcePath, destPath);
33144
- }
33145
- }
33146
- }
33147
- if (agentsHasContent && agentsDir) {
33148
- const destPath = path6.join(backupPath, AGENTS_BACKUP_SUBDIR);
33149
- await copyForBackup(agentsDir, destPath);
33150
- }
33151
- return backupPath;
33152
- }
33153
-
33154
- // src/lib/platform.ts
33155
- var import_fs_extra5 = __toESM(require_lib4(), 1);
33156
- import os7 from "os";
33157
- import path7 from "path";
33057
+ import path6 from "path";
33158
33058
  import { execSync as execSync2 } from "child_process";
33159
33059
  function escapeShellArg(arg) {
33160
33060
  return "'" + arg.replace(/'/g, "'\\''") + "'";
@@ -33162,15 +33062,15 @@ function escapeShellArg(arg) {
33162
33062
  var cachedPlatformInfo = null;
33163
33063
  var cachedAudioPlayer = undefined;
33164
33064
  function isWSL() {
33165
- if (os7.platform() !== "linux")
33065
+ if (os6.platform() !== "linux")
33166
33066
  return false;
33167
- const release = os7.release().toLowerCase();
33067
+ const release = os6.release().toLowerCase();
33168
33068
  return release.includes("microsoft") || release.includes("wsl");
33169
33069
  }
33170
33070
  function getPlatformInfo() {
33171
33071
  if (cachedPlatformInfo)
33172
33072
  return cachedPlatformInfo;
33173
- const platform = os7.platform();
33073
+ const platform = os6.platform();
33174
33074
  const wsl = isWSL();
33175
33075
  cachedPlatformInfo = {
33176
33076
  platform,
@@ -33178,14 +33078,14 @@ function getPlatformInfo() {
33178
33078
  isMacOS: platform === "darwin",
33179
33079
  isLinux: platform === "linux" && !wsl,
33180
33080
  isWSL: wsl,
33181
- homeDir: os7.homedir()
33081
+ homeDir: os6.homedir()
33182
33082
  };
33183
33083
  return cachedPlatformInfo;
33184
33084
  }
33185
33085
  function detectAudioPlayer() {
33186
33086
  if (cachedAudioPlayer !== undefined)
33187
33087
  return cachedAudioPlayer;
33188
- const platform = os7.platform();
33088
+ const platform = os6.platform();
33189
33089
  if (platform === "darwin") {
33190
33090
  cachedAudioPlayer = "afplay";
33191
33091
  return cachedAudioPlayer;
@@ -33224,7 +33124,7 @@ function getPlaySoundCommand(soundPath) {
33224
33124
  const player = detectAudioPlayer();
33225
33125
  if (!player)
33226
33126
  return null;
33227
- const platform = os7.platform();
33127
+ const platform = os6.platform();
33228
33128
  const safePath = escapeShellArg(soundPath);
33229
33129
  if (platform === "darwin") {
33230
33130
  return `afplay -v 0.1 ${safePath}`;
@@ -33307,20 +33207,34 @@ function replaceClaudePathPlaceholder(content, claudeDir) {
33307
33207
  return content.replaceAll("{CLAUDE_PATH}", claudeDir);
33308
33208
  }
33309
33209
  async function replacePathPlaceholdersInDir(dir, claudeDir) {
33310
- const entries = await import_fs_extra5.default.readdir(dir, { withFileTypes: true });
33210
+ const entries = await import_fs_extra4.default.readdir(dir, { withFileTypes: true });
33311
33211
  for (const entry of entries) {
33312
- const fullPath = path7.join(dir, entry.name);
33212
+ const fullPath = path6.join(dir, entry.name);
33313
33213
  if (entry.isDirectory()) {
33314
33214
  await replacePathPlaceholdersInDir(fullPath, claudeDir);
33315
33215
  } else if (isTextFile(entry.name)) {
33316
- const content = await import_fs_extra5.default.readFile(fullPath, "utf-8");
33216
+ const content = await import_fs_extra4.default.readFile(fullPath, "utf-8");
33317
33217
  const replaced = replaceClaudePathPlaceholder(content, claudeDir);
33318
33218
  if (replaced !== content) {
33319
- await import_fs_extra5.default.writeFile(fullPath, replaced, "utf-8");
33219
+ await import_fs_extra4.default.writeFile(fullPath, replaced, "utf-8");
33320
33220
  }
33321
33221
  }
33322
33222
  }
33323
33223
  }
33224
+ async function applyPathPlaceholders(target, claudeDir) {
33225
+ const stat = await import_fs_extra4.default.stat(target).catch(() => null);
33226
+ if (!stat)
33227
+ return;
33228
+ if (stat.isDirectory()) {
33229
+ await replacePathPlaceholdersInDir(target, claudeDir);
33230
+ } else if (isTextFile(target)) {
33231
+ const content = await import_fs_extra4.default.readFile(target, "utf-8");
33232
+ const replaced = replaceClaudePathPlaceholder(content, claudeDir);
33233
+ if (replaced !== content) {
33234
+ await import_fs_extra4.default.writeFile(target, replaced, "utf-8");
33235
+ }
33236
+ }
33237
+ }
33324
33238
  function transformFileContent(content, claudeDir) {
33325
33239
  let transformed = content;
33326
33240
  transformed = replaceClaudePathPlaceholder(transformed, claudeDir);
@@ -33346,40 +33260,40 @@ function transformFileContent(content, claudeDir) {
33346
33260
  }
33347
33261
 
33348
33262
  // src/lib/telemetry.ts
33349
- import os8 from "os";
33350
- import fs6 from "fs";
33351
- import path8 from "path";
33263
+ import os7 from "os";
33264
+ import fs5 from "fs";
33265
+ import path7 from "path";
33352
33266
  var TELEMETRY_URL = "https://codelynx.dev/api/cli/events";
33353
33267
  var isDisabled = () => {
33354
33268
  return process.env.AIBLUEPRINT_TELEMETRY_DISABLED === "1";
33355
33269
  };
33356
33270
  var getBasePayload = () => ({
33357
33271
  cliVersion: getVersion(),
33358
- platform: os8.platform(),
33359
- arch: os8.arch(),
33272
+ platform: os7.platform(),
33273
+ arch: os7.arch(),
33360
33274
  nodeVersion: process.version
33361
33275
  });
33362
33276
  function getTokenFilePath() {
33363
- const homeDir = os8.homedir();
33364
- if (os8.platform() === "win32") {
33365
- const appData = process.env.APPDATA || path8.join(homeDir, "AppData", "Roaming");
33366
- return path8.join(appData, "aiblueprint", "token.txt");
33277
+ const homeDir = os7.homedir();
33278
+ if (os7.platform() === "win32") {
33279
+ const appData = process.env.APPDATA || path7.join(homeDir, "AppData", "Roaming");
33280
+ return path7.join(appData, "aiblueprint", "token.txt");
33367
33281
  }
33368
- const configHome = process.env.XDG_CONFIG_HOME || path8.join(homeDir, ".config");
33369
- return path8.join(configHome, "aiblueprint", "token.txt");
33282
+ const configHome = process.env.XDG_CONFIG_HOME || path7.join(homeDir, ".config");
33283
+ return path7.join(configHome, "aiblueprint", "token.txt");
33370
33284
  }
33371
33285
  function getSystemInfo() {
33372
33286
  let hasProToken = false;
33373
33287
  try {
33374
- hasProToken = fs6.existsSync(getTokenFilePath());
33288
+ hasProToken = fs5.existsSync(getTokenFilePath());
33375
33289
  } catch {}
33376
33290
  return {
33377
- osVersion: os8.release(),
33378
- osType: os8.type(),
33379
- totalMemory: `${Math.round(os8.totalmem() / (1024 * 1024 * 1024))}GB`,
33380
- cpus: os8.cpus().length,
33291
+ osVersion: os7.release(),
33292
+ osType: os7.type(),
33293
+ totalMemory: `${Math.round(os7.totalmem() / (1024 * 1024 * 1024))}GB`,
33294
+ cpus: os7.cpus().length,
33381
33295
  shell: process.env.SHELL || process.env.COMSPEC || "unknown",
33382
- homeDir: os8.homedir(),
33296
+ homeDir: os7.homedir(),
33383
33297
  locale: process.env.LANG || process.env.LC_ALL || "unknown",
33384
33298
  hasProToken
33385
33299
  };
@@ -33421,42 +33335,28 @@ async function flushTelemetry() {
33421
33335
  }
33422
33336
 
33423
33337
  // src/lib/agents-installer.ts
33424
- var import_fs_extra6 = __toESM(require_lib4(), 1);
33425
- import os9 from "os";
33426
- import path9 from "path";
33427
- async function applyPathPlaceholders(target, claudeDir) {
33428
- const stat = await import_fs_extra6.default.stat(target).catch(() => null);
33429
- if (!stat)
33430
- return;
33431
- if (stat.isDirectory()) {
33432
- await replacePathPlaceholdersInDir(target, claudeDir);
33433
- } else if (isTextFile(target)) {
33434
- const content = await import_fs_extra6.default.readFile(target, "utf-8");
33435
- const replaced = replaceClaudePathPlaceholder(content, claudeDir);
33436
- if (replaced !== content) {
33437
- await import_fs_extra6.default.writeFile(target, replaced, "utf-8");
33438
- }
33439
- }
33440
- }
33338
+ var import_fs_extra5 = __toESM(require_lib4(), 1);
33339
+ import os8 from "os";
33340
+ import path8 from "path";
33441
33341
  var AGENT_CATEGORIES = ["skills", "agents"];
33442
33342
  async function platformSymlink(source, target) {
33443
- await import_fs_extra6.default.ensureDir(path9.dirname(target));
33444
- const isWindows2 = os9.platform() === "win32";
33445
- const sourceStat = await import_fs_extra6.default.stat(source).catch(() => null);
33343
+ await import_fs_extra5.default.ensureDir(path8.dirname(target));
33344
+ const isWindows2 = os8.platform() === "win32";
33345
+ const sourceStat = await import_fs_extra5.default.stat(source).catch(() => null);
33446
33346
  const isDir = sourceStat?.isDirectory() ?? false;
33447
33347
  if (isWindows2 && isDir) {
33448
- await import_fs_extra6.default.symlink(source, target, "junction");
33348
+ await import_fs_extra5.default.symlink(source, target, "junction");
33449
33349
  return;
33450
33350
  }
33451
33351
  try {
33452
- await import_fs_extra6.default.symlink(source, target);
33352
+ await import_fs_extra5.default.symlink(source, target);
33453
33353
  } catch (error) {
33454
33354
  if (!isWindows2 || isDir)
33455
33355
  throw error;
33456
33356
  try {
33457
- await import_fs_extra6.default.link(source, target);
33357
+ await import_fs_extra5.default.link(source, target);
33458
33358
  } catch {
33459
- await import_fs_extra6.default.copy(source, target, { overwrite: true });
33359
+ await import_fs_extra5.default.copy(source, target, { overwrite: true });
33460
33360
  }
33461
33361
  }
33462
33362
  }
@@ -33467,37 +33367,37 @@ async function installCategoryToAgents(sourceCategoryDir, category, agentsDir, c
33467
33367
  symlinked: [],
33468
33368
  skipped: []
33469
33369
  };
33470
- if (!await import_fs_extra6.default.pathExists(sourceCategoryDir)) {
33370
+ if (!await import_fs_extra5.default.pathExists(sourceCategoryDir)) {
33471
33371
  return result;
33472
33372
  }
33473
- const agentsCategoryDir = path9.join(agentsDir, category);
33474
- await import_fs_extra6.default.ensureDir(agentsCategoryDir);
33475
- const entries = await import_fs_extra6.default.readdir(sourceCategoryDir, { withFileTypes: true });
33373
+ const agentsCategoryDir = path8.join(agentsDir, category);
33374
+ await import_fs_extra5.default.ensureDir(agentsCategoryDir);
33375
+ const entries = await import_fs_extra5.default.readdir(sourceCategoryDir, { withFileTypes: true });
33476
33376
  for (const entry of entries) {
33477
33377
  if (entry.name === ".DS_Store" || entry.name === "node_modules")
33478
33378
  continue;
33479
- const sourcePath = path9.join(sourceCategoryDir, entry.name);
33480
- const agentsTarget = path9.join(agentsCategoryDir, entry.name);
33481
- const claudeTarget = path9.join(claudeDir, category, entry.name);
33482
- const agentsExists = await import_fs_extra6.default.pathExists(agentsTarget);
33379
+ const sourcePath = path8.join(sourceCategoryDir, entry.name);
33380
+ const agentsTarget = path8.join(agentsCategoryDir, entry.name);
33381
+ const claudeTarget = path8.join(claudeDir, category, entry.name);
33382
+ const agentsExists = await import_fs_extra5.default.pathExists(agentsTarget);
33483
33383
  if (!agentsExists) {
33484
33384
  let migrated = false;
33485
33385
  if (options.migrateClaudeDirs) {
33486
- const claudeStat = await import_fs_extra6.default.lstat(claudeTarget).catch(() => null);
33386
+ const claudeStat = await import_fs_extra5.default.lstat(claudeTarget).catch(() => null);
33487
33387
  if (claudeStat && !claudeStat.isSymbolicLink()) {
33488
- await import_fs_extra6.default.move(claudeTarget, agentsTarget);
33388
+ await import_fs_extra5.default.move(claudeTarget, agentsTarget);
33489
33389
  result.migrated.push(entry.name);
33490
33390
  migrated = true;
33491
33391
  }
33492
33392
  }
33493
33393
  if (!migrated) {
33494
- await import_fs_extra6.default.copy(sourcePath, agentsTarget, { overwrite: false });
33394
+ await import_fs_extra5.default.copy(sourcePath, agentsTarget, { overwrite: false });
33495
33395
  await applyPathPlaceholders(agentsTarget, claudeDir);
33496
33396
  result.copied.push(entry.name);
33497
33397
  }
33498
33398
  } else if (options.overwrite) {
33499
- await import_fs_extra6.default.remove(agentsTarget);
33500
- await import_fs_extra6.default.copy(sourcePath, agentsTarget, { overwrite: false });
33399
+ await import_fs_extra5.default.remove(agentsTarget);
33400
+ await import_fs_extra5.default.copy(sourcePath, agentsTarget, { overwrite: false });
33501
33401
  await applyPathPlaceholders(agentsTarget, claudeDir);
33502
33402
  result.copied.push(entry.name);
33503
33403
  }
@@ -33506,24 +33406,24 @@ async function installCategoryToAgents(sourceCategoryDir, category, agentsDir, c
33506
33406
  return result;
33507
33407
  }
33508
33408
  async function syncCategorySymlinks(category, agentsDir, claudeDir, result, silent = false) {
33509
- const agentsCategoryDir = path9.join(agentsDir, category);
33510
- const claudeCategoryDir = path9.join(claudeDir, category);
33511
- if (!await import_fs_extra6.default.pathExists(agentsCategoryDir)) {
33409
+ const agentsCategoryDir = path8.join(agentsDir, category);
33410
+ const claudeCategoryDir = path8.join(claudeDir, category);
33411
+ if (!await import_fs_extra5.default.pathExists(agentsCategoryDir)) {
33512
33412
  return;
33513
33413
  }
33514
- await import_fs_extra6.default.ensureDir(claudeCategoryDir);
33515
- const entries = await import_fs_extra6.default.readdir(agentsCategoryDir, { withFileTypes: true });
33414
+ await import_fs_extra5.default.ensureDir(claudeCategoryDir);
33415
+ const entries = await import_fs_extra5.default.readdir(agentsCategoryDir, { withFileTypes: true });
33516
33416
  for (const entry of entries) {
33517
33417
  if (entry.name === ".DS_Store")
33518
33418
  continue;
33519
- const agentsTarget = path9.join(agentsCategoryDir, entry.name);
33520
- const claudeTarget = path9.join(claudeCategoryDir, entry.name);
33521
- const claudeStat = await import_fs_extra6.default.lstat(claudeTarget).catch(() => null);
33419
+ const agentsTarget = path8.join(agentsCategoryDir, entry.name);
33420
+ const claudeTarget = path8.join(claudeCategoryDir, entry.name);
33421
+ const claudeStat = await import_fs_extra5.default.lstat(claudeTarget).catch(() => null);
33522
33422
  if (!claudeStat) {
33523
33423
  await platformSymlink(agentsTarget, claudeTarget);
33524
33424
  result?.symlinked.push(entry.name);
33525
33425
  } else if (claudeStat.isSymbolicLink()) {
33526
- await import_fs_extra6.default.remove(claudeTarget);
33426
+ await import_fs_extra5.default.remove(claudeTarget);
33527
33427
  await platformSymlink(agentsTarget, claudeTarget);
33528
33428
  result?.symlinked.push(entry.name);
33529
33429
  } else {
@@ -33534,15 +33434,15 @@ async function syncCategorySymlinks(category, agentsDir, claudeDir, result, sile
33534
33434
  }
33535
33435
  }
33536
33436
  }
33537
- if (await import_fs_extra6.default.pathExists(claudeCategoryDir)) {
33538
- const claudeEntries = await import_fs_extra6.default.readdir(claudeCategoryDir, { withFileTypes: true });
33437
+ if (await import_fs_extra5.default.pathExists(claudeCategoryDir)) {
33438
+ const claudeEntries = await import_fs_extra5.default.readdir(claudeCategoryDir, { withFileTypes: true });
33539
33439
  for (const entry of claudeEntries) {
33540
- const claudeTarget = path9.join(claudeCategoryDir, entry.name);
33541
- const stat = await import_fs_extra6.default.lstat(claudeTarget).catch(() => null);
33440
+ const claudeTarget = path8.join(claudeCategoryDir, entry.name);
33441
+ const stat = await import_fs_extra5.default.lstat(claudeTarget).catch(() => null);
33542
33442
  if (stat?.isSymbolicLink()) {
33543
- const exists = await import_fs_extra6.default.pathExists(claudeTarget);
33443
+ const exists = await import_fs_extra5.default.pathExists(claudeTarget);
33544
33444
  if (!exists) {
33545
- await import_fs_extra6.default.remove(claudeTarget);
33445
+ await import_fs_extra5.default.remove(claudeTarget);
33546
33446
  }
33547
33447
  }
33548
33448
  }
@@ -33553,26 +33453,397 @@ function isAgentCategory(category) {
33553
33453
  }
33554
33454
 
33555
33455
  // src/lib/folder-paths.ts
33556
- import os10 from "os";
33557
- import path10 from "path";
33456
+ import os9 from "os";
33457
+ import path9 from "path";
33558
33458
  function resolveFolders(options = {}) {
33559
- const rootDir = options.folder ? path10.resolve(options.folder) : os10.homedir();
33560
- const claudeDir = options.claudeCodeFolder ? path10.resolve(options.claudeCodeFolder) : path10.join(rootDir, ".claude");
33561
- const codexDir = options.codexFolder ? path10.resolve(options.codexFolder) : path10.join(rootDir, ".codex");
33562
- const agentsDir = options.agentsFolder ? path10.resolve(options.agentsFolder) : path10.join(rootDir, ".agents");
33459
+ const rootDir = options.folder ? path9.resolve(options.folder) : os9.homedir();
33460
+ const claudeDir = options.claudeCodeFolder ? path9.resolve(options.claudeCodeFolder) : path9.join(rootDir, ".claude");
33461
+ const codexDir = options.codexFolder ? path9.resolve(options.codexFolder) : path9.join(rootDir, ".codex");
33462
+ const agentsDir = options.agentsFolder ? path9.resolve(options.agentsFolder) : path9.join(rootDir, ".agents");
33563
33463
  return { rootDir, claudeDir, codexDir, agentsDir };
33564
33464
  }
33565
33465
 
33466
+ // src/lib/codex-config.ts
33467
+ var import_fs_extra6 = __toESM(require_lib4(), 1);
33468
+ import path10 from "path";
33469
+ var TUI_STATUS_LINE_BLOCK = `status_line = [
33470
+ "model-with-reasoning",
33471
+ "run-state",
33472
+ "project-name",
33473
+ "git-branch",
33474
+ "branch-changes",
33475
+ "context-remaining",
33476
+ "used-tokens",
33477
+ "five-hour-limit",
33478
+ "weekly-limit",
33479
+ "task-progress",
33480
+ ]
33481
+ status_line_use_colors = true`;
33482
+ var TUI_SECTION = `[tui]
33483
+ ${TUI_STATUS_LINE_BLOCK}`;
33484
+ function hasTopLevelKey(content, key) {
33485
+ let inSection = false;
33486
+ for (const line of content.split(/\r?\n/)) {
33487
+ const trimmed = line.trim();
33488
+ if (!trimmed || trimmed.startsWith("#"))
33489
+ continue;
33490
+ if (/^\[[^\]]+\]$/.test(trimmed)) {
33491
+ inSection = true;
33492
+ continue;
33493
+ }
33494
+ if (!inSection && (trimmed.startsWith(`${key} `) || trimmed.startsWith(`${key}=`))) {
33495
+ return true;
33496
+ }
33497
+ }
33498
+ return false;
33499
+ }
33500
+ function getTopLevelAssignments(defaultConfig) {
33501
+ const assignments = [];
33502
+ for (const line of defaultConfig.split(/\r?\n/)) {
33503
+ const trimmed = line.trim();
33504
+ if (!trimmed || trimmed.startsWith("#"))
33505
+ continue;
33506
+ if (/^\[[^\]]+\]$/.test(trimmed))
33507
+ break;
33508
+ if (/^[A-Za-z0-9_-]+\s*=/.test(trimmed)) {
33509
+ assignments.push(line);
33510
+ }
33511
+ }
33512
+ return assignments;
33513
+ }
33514
+ function findSectionRange(content, sectionName) {
33515
+ const lines = content.split(/\r?\n/);
33516
+ const sectionHeader = `[${sectionName}]`;
33517
+ let start = -1;
33518
+ for (let index = 0;index < lines.length; index += 1) {
33519
+ if (lines[index].trim() === sectionHeader) {
33520
+ start = index;
33521
+ break;
33522
+ }
33523
+ }
33524
+ if (start === -1)
33525
+ return null;
33526
+ let end = lines.length;
33527
+ for (let index = start + 1;index < lines.length; index += 1) {
33528
+ const trimmed = lines[index].trim();
33529
+ if (/^\[[^\]]+\]$/.test(trimmed)) {
33530
+ end = index;
33531
+ break;
33532
+ }
33533
+ }
33534
+ return { start, end };
33535
+ }
33536
+ function sectionHasKey(content, sectionName, key) {
33537
+ const range = findSectionRange(content, sectionName);
33538
+ if (!range)
33539
+ return false;
33540
+ const lines = content.split(/\r?\n/).slice(range.start + 1, range.end);
33541
+ return lines.some((line) => {
33542
+ const trimmed = line.trim();
33543
+ return trimmed.startsWith(`${key} `) || trimmed.startsWith(`${key}=`);
33544
+ });
33545
+ }
33546
+ function appendBlock(content, block) {
33547
+ const normalized = content.trimEnd();
33548
+ if (!normalized)
33549
+ return `${block}
33550
+ `;
33551
+ return `${normalized}
33552
+
33553
+ ${block}
33554
+ `;
33555
+ }
33556
+ function mergeCodexConfig(existingConfig, defaultConfig) {
33557
+ let merged = existingConfig.trimEnd();
33558
+ for (const assignment of getTopLevelAssignments(defaultConfig)) {
33559
+ const key = assignment.split("=")[0].trim();
33560
+ if (!hasTopLevelKey(merged, key)) {
33561
+ merged = appendBlock(merged, assignment);
33562
+ }
33563
+ }
33564
+ if (sectionHasKey(merged, "tui", "status_line")) {
33565
+ return `${merged}
33566
+ `;
33567
+ }
33568
+ const tuiRange = findSectionRange(merged, "tui");
33569
+ if (!tuiRange) {
33570
+ return appendBlock(merged, TUI_SECTION);
33571
+ }
33572
+ const lines = merged.split(/\r?\n/);
33573
+ lines.splice(tuiRange.start + 1, 0, TUI_STATUS_LINE_BLOCK);
33574
+ return `${lines.join(`
33575
+ `).trimEnd()}
33576
+ `;
33577
+ }
33578
+ async function mergeCodexConfigFile(sourceConfigPath, codexDir) {
33579
+ const targetConfigPath = path10.join(codexDir, "config.toml");
33580
+ const defaultConfig = await import_fs_extra6.default.readFile(sourceConfigPath, "utf-8");
33581
+ const existingConfig = await import_fs_extra6.default.readFile(targetConfigPath, "utf-8").catch(() => "");
33582
+ const merged = mergeCodexConfig(existingConfig, defaultConfig);
33583
+ await import_fs_extra6.default.ensureDir(codexDir);
33584
+ await import_fs_extra6.default.writeFile(targetConfigPath, merged, "utf-8");
33585
+ }
33586
+
33587
+ // src/lib/configs-store.ts
33588
+ var import_fs_extra7 = __toESM(require_lib4(), 1);
33589
+ import path11 from "path";
33590
+ function getConfigStorePaths(rootDir) {
33591
+ const baseDir = path11.join(rootDir, ".aiblueprint");
33592
+ return {
33593
+ baseDir,
33594
+ configsDir: path11.join(baseDir, "configs"),
33595
+ backupsDir: path11.join(baseDir, "backups"),
33596
+ historyPath: path11.join(baseDir, "history.jsonl")
33597
+ };
33598
+ }
33599
+ function resolveConfigStoreFolders(options = {}) {
33600
+ return resolveFolders(options);
33601
+ }
33602
+ function timestamp(date = new Date) {
33603
+ const pad = (n) => n.toString().padStart(2, "0");
33604
+ return [
33605
+ date.getFullYear(),
33606
+ pad(date.getMonth() + 1),
33607
+ pad(date.getDate()),
33608
+ pad(date.getHours()),
33609
+ pad(date.getMinutes()),
33610
+ pad(date.getSeconds())
33611
+ ].join("-");
33612
+ }
33613
+ function sanitizeSnapshotName(name) {
33614
+ const sanitized = name.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
33615
+ if (!sanitized) {
33616
+ throw new Error("Snapshot name cannot be empty");
33617
+ }
33618
+ if (sanitized === "." || sanitized === ".." || sanitized.includes("..")) {
33619
+ throw new Error("Snapshot name is not allowed");
33620
+ }
33621
+ return sanitized;
33622
+ }
33623
+ function managedFolders(folders) {
33624
+ return [
33625
+ { name: ".claude", path: folders.claudeDir },
33626
+ { name: ".codex", path: folders.codexDir },
33627
+ { name: ".agents", path: folders.agentsDir }
33628
+ ];
33629
+ }
33630
+ async function hasContent(folderPath) {
33631
+ if (!await import_fs_extra7.default.pathExists(folderPath))
33632
+ return false;
33633
+ const entries = await import_fs_extra7.default.readdir(folderPath);
33634
+ return entries.some((entry) => entry !== ".DS_Store");
33635
+ }
33636
+ async function copyManagedFolder(source, destination) {
33637
+ await import_fs_extra7.default.copy(source, destination, {
33638
+ overwrite: true,
33639
+ dereference: false,
33640
+ filter: async (src) => {
33641
+ try {
33642
+ const stat = await import_fs_extra7.default.lstat(src);
33643
+ return !stat.isSymbolicLink();
33644
+ } catch {
33645
+ return true;
33646
+ }
33647
+ }
33648
+ });
33649
+ }
33650
+ async function writeMetadata(snapshotPath, metadata) {
33651
+ await import_fs_extra7.default.writeJson(path11.join(snapshotPath, "metadata.json"), metadata, { spaces: 2 });
33652
+ }
33653
+ async function readMetadata(snapshotPath, fallbackType) {
33654
+ const metadataPath = path11.join(snapshotPath, "metadata.json");
33655
+ if (await import_fs_extra7.default.pathExists(metadataPath)) {
33656
+ return import_fs_extra7.default.readJson(metadataPath);
33657
+ }
33658
+ const name = path11.basename(snapshotPath);
33659
+ return {
33660
+ name,
33661
+ type: fallbackType,
33662
+ createdAt: new Date(0).toISOString(),
33663
+ reason: "Legacy snapshot without metadata",
33664
+ trigger: "legacy",
33665
+ folders: []
33666
+ };
33667
+ }
33668
+ async function appendHistory(paths, event) {
33669
+ await import_fs_extra7.default.ensureDir(paths.baseDir);
33670
+ await import_fs_extra7.default.appendFile(paths.historyPath, `${JSON.stringify({ at: new Date().toISOString(), ...event })}
33671
+ `);
33672
+ }
33673
+ async function snapshotByCopy(snapshotPath, folders, metadata) {
33674
+ const copied = [];
33675
+ await import_fs_extra7.default.ensureDir(snapshotPath);
33676
+ for (const folder of managedFolders(folders)) {
33677
+ if (!await hasContent(folder.path))
33678
+ continue;
33679
+ await copyManagedFolder(folder.path, path11.join(snapshotPath, folder.name));
33680
+ copied.push(folder.name);
33681
+ }
33682
+ if (copied.length === 0) {
33683
+ await import_fs_extra7.default.remove(snapshotPath);
33684
+ return null;
33685
+ }
33686
+ await writeMetadata(snapshotPath, { ...metadata, folders: copied });
33687
+ return snapshotPath;
33688
+ }
33689
+ async function saveNamedConfig(name, options = {}) {
33690
+ const folders = resolveConfigStoreFolders(options);
33691
+ const paths = getConfigStorePaths(folders.rootDir);
33692
+ const safeName = sanitizeSnapshotName(name);
33693
+ const snapshotPath = path11.join(paths.configsDir, safeName);
33694
+ if (await import_fs_extra7.default.pathExists(snapshotPath) && !options.force) {
33695
+ throw new Error(`Config "${safeName}" already exists. Use --force to overwrite it.`);
33696
+ }
33697
+ if (await import_fs_extra7.default.pathExists(snapshotPath)) {
33698
+ const backupName = `${timestamp()}-replace-saved-${safeName}`;
33699
+ await import_fs_extra7.default.ensureDir(paths.backupsDir);
33700
+ await import_fs_extra7.default.move(snapshotPath, path11.join(paths.backupsDir, backupName), { overwrite: false });
33701
+ }
33702
+ const result = await snapshotByCopy(snapshotPath, folders, {
33703
+ name: safeName,
33704
+ type: "config",
33705
+ createdAt: new Date().toISOString(),
33706
+ reason: `Manual save as "${safeName}"`,
33707
+ trigger: "save",
33708
+ folders: []
33709
+ });
33710
+ if (!result) {
33711
+ throw new Error("No .claude, .codex, or .agents configuration found to save.");
33712
+ }
33713
+ await appendHistory(paths, { action: "save", name: safeName, path: result });
33714
+ return result;
33715
+ }
33716
+ async function createConfigBackup(options = {}, reason = "Backup current configuration", trigger = "manual", source) {
33717
+ const folders = resolveConfigStoreFolders(options);
33718
+ const paths = getConfigStorePaths(folders.rootDir);
33719
+ const safeSource = source ? sanitizeSnapshotName(source) : trigger;
33720
+ const name = `${timestamp()}-${safeSource}`;
33721
+ const snapshotPath = path11.join(paths.backupsDir, name);
33722
+ const result = await snapshotByCopy(snapshotPath, folders, {
33723
+ name,
33724
+ type: "backup",
33725
+ createdAt: new Date().toISOString(),
33726
+ reason,
33727
+ trigger,
33728
+ source,
33729
+ folders: []
33730
+ });
33731
+ if (result) {
33732
+ await appendHistory(paths, { action: "backup", name, reason, trigger, source, path: result });
33733
+ }
33734
+ return result;
33735
+ }
33736
+ async function backupCurrentByMove(folders, reason, trigger, source) {
33737
+ const paths = getConfigStorePaths(folders.rootDir);
33738
+ const safeSource = source ? sanitizeSnapshotName(source) : trigger;
33739
+ const name = `${timestamp()}-${safeSource}`;
33740
+ const backupPath = path11.join(paths.backupsDir, name);
33741
+ const moved = [];
33742
+ await import_fs_extra7.default.ensureDir(backupPath);
33743
+ for (const folder of managedFolders(folders)) {
33744
+ if (!await hasContent(folder.path))
33745
+ continue;
33746
+ await import_fs_extra7.default.move(folder.path, path11.join(backupPath, folder.name), { overwrite: false });
33747
+ moved.push(folder.name);
33748
+ }
33749
+ if (moved.length === 0) {
33750
+ await import_fs_extra7.default.remove(backupPath);
33751
+ return null;
33752
+ }
33753
+ await writeMetadata(backupPath, {
33754
+ name,
33755
+ type: "backup",
33756
+ createdAt: new Date().toISOString(),
33757
+ reason,
33758
+ trigger,
33759
+ source,
33760
+ folders: moved
33761
+ });
33762
+ await appendHistory(paths, { action: "backup", name, reason, trigger, source, path: backupPath });
33763
+ return backupPath;
33764
+ }
33765
+ async function restoreSnapshot(snapshotPath, folders) {
33766
+ const restored = [];
33767
+ for (const folder of managedFolders(folders)) {
33768
+ const source = path11.join(snapshotPath, folder.name);
33769
+ if (!await import_fs_extra7.default.pathExists(source))
33770
+ continue;
33771
+ await import_fs_extra7.default.ensureDir(path11.dirname(folder.path));
33772
+ await copyManagedFolder(source, folder.path);
33773
+ restored.push(folder.name);
33774
+ }
33775
+ return restored;
33776
+ }
33777
+ async function loadNamedConfig(name, options = {}) {
33778
+ const folders = resolveConfigStoreFolders(options);
33779
+ const paths = getConfigStorePaths(folders.rootDir);
33780
+ const safeName = sanitizeSnapshotName(name);
33781
+ const snapshotPath = path11.join(paths.configsDir, safeName);
33782
+ if (!await import_fs_extra7.default.pathExists(snapshotPath)) {
33783
+ throw new Error(`Saved config not found: ${safeName}`);
33784
+ }
33785
+ const backupPath = await backupCurrentByMove(folders, `Before loading saved config "${safeName}"`, "load", safeName);
33786
+ const restored = await restoreSnapshot(snapshotPath, folders);
33787
+ await appendHistory(paths, { action: "load", name: safeName, backupPath, restored });
33788
+ return { backupPath, restored };
33789
+ }
33790
+ async function loadBackupSnapshot(name, options = {}) {
33791
+ const folders = resolveConfigStoreFolders(options);
33792
+ const paths = getConfigStorePaths(folders.rootDir);
33793
+ const safeName = sanitizeSnapshotName(name);
33794
+ const snapshotPath = path11.join(paths.backupsDir, safeName);
33795
+ if (!await import_fs_extra7.default.pathExists(snapshotPath)) {
33796
+ throw new Error(`Backup not found: ${safeName}`);
33797
+ }
33798
+ const backupPath = await backupCurrentByMove(folders, `Before restoring backup "${safeName}"`, "backup-load", safeName);
33799
+ const restored = await restoreSnapshot(snapshotPath, folders);
33800
+ await appendHistory(paths, { action: "backup-load", name: safeName, backupPath, restored });
33801
+ return { backupPath, restored };
33802
+ }
33803
+ async function undoLastLoad(options = {}) {
33804
+ const backups = await listConfigBackups(options);
33805
+ const lastLoadBackup = backups.find((backup) => backup.metadata.trigger === "load" || backup.metadata.trigger === "backup-load");
33806
+ if (!lastLoadBackup) {
33807
+ throw new Error("No load backup found to undo.");
33808
+ }
33809
+ const result = await loadBackupSnapshot(lastLoadBackup.name, options);
33810
+ return { backupName: lastLoadBackup.name, ...result };
33811
+ }
33812
+ async function listSnapshots(dir, type) {
33813
+ if (!await import_fs_extra7.default.pathExists(dir))
33814
+ return [];
33815
+ const entries = await import_fs_extra7.default.readdir(dir, { withFileTypes: true });
33816
+ const snapshots = [];
33817
+ for (const entry of entries) {
33818
+ if (!entry.isDirectory())
33819
+ continue;
33820
+ const snapshotPath = path11.join(dir, entry.name);
33821
+ const metadata = await readMetadata(snapshotPath, type);
33822
+ snapshots.push({ name: entry.name, path: snapshotPath, metadata });
33823
+ }
33824
+ return snapshots.sort((a, b) => b.metadata.createdAt.localeCompare(a.metadata.createdAt));
33825
+ }
33826
+ async function listSavedConfigs(options = {}) {
33827
+ const folders = resolveConfigStoreFolders(options);
33828
+ const paths = getConfigStorePaths(folders.rootDir);
33829
+ return listSnapshots(paths.configsDir, "config");
33830
+ }
33831
+ async function listConfigBackups(options = {}) {
33832
+ const folders = resolveConfigStoreFolders(options);
33833
+ const paths = getConfigStorePaths(folders.rootDir);
33834
+ return listSnapshots(paths.backupsDir, "backup");
33835
+ }
33836
+
33566
33837
  // src/commands/setup.ts
33567
33838
  var __filename2 = fileURLToPath2(import.meta.url);
33568
33839
  var __dirname2 = dirname2(__filename2);
33569
33840
  async function resolveClaudeAssetPath(sourceDir, name) {
33570
33841
  const candidates = [
33571
- path11.join(sourceDir, "claude-config", name),
33572
- path11.join(sourceDir, name)
33842
+ path12.join(sourceDir, "claude-config", name),
33843
+ path12.join(sourceDir, name)
33573
33844
  ];
33574
33845
  for (const candidate of candidates) {
33575
- if (await import_fs_extra7.default.pathExists(candidate))
33846
+ if (await import_fs_extra8.default.pathExists(candidate))
33576
33847
  return candidate;
33577
33848
  }
33578
33849
  return null;
@@ -33660,10 +33931,10 @@ async function setupCommand(params = {}) {
33660
33931
  console.log(source_default.gray(`Claude: ${claudeDir}`));
33661
33932
  console.log(source_default.gray(`Codex: ${codexDir}`));
33662
33933
  console.log(source_default.gray(`Agents: ${agentsDir}`));
33663
- await import_fs_extra7.default.ensureDir(claudeDir);
33664
- await import_fs_extra7.default.ensureDir(agentsDir);
33934
+ await import_fs_extra8.default.ensureDir(claudeDir);
33935
+ await import_fs_extra8.default.ensureDir(agentsDir);
33665
33936
  s.start("Creating backup of existing configuration");
33666
- const backupPath = await createBackup(claudeDir, agentsDir);
33937
+ const backupPath = await createConfigBackup({ folder, claudeCodeFolder, codexFolder, agentsFolder }, "Before running aiblueprint setup", "setup", "aiblueprint-setup");
33667
33938
  if (backupPath) {
33668
33939
  s.stop(`Backup created: ${source_default.gray(backupPath)}`);
33669
33940
  } else {
@@ -33689,11 +33960,11 @@ async function setupCommand(params = {}) {
33689
33960
  s.start("Setting up scripts");
33690
33961
  const scriptsSource = await resolveClaudeAssetPath(sourceDir, "scripts");
33691
33962
  if (scriptsSource) {
33692
- await import_fs_extra7.default.copy(scriptsSource, path11.join(claudeDir, "scripts"), {
33963
+ await import_fs_extra8.default.copy(scriptsSource, path12.join(claudeDir, "scripts"), {
33693
33964
  overwrite: true
33694
33965
  });
33695
- await replacePathPlaceholdersInDir(path11.join(claudeDir, "scripts"), claudeDir);
33696
- await import_fs_extra7.default.ensureDir(path11.join(claudeDir, "scripts/statusline/data"));
33966
+ await replacePathPlaceholdersInDir(path12.join(claudeDir, "scripts"), claudeDir);
33967
+ await import_fs_extra8.default.ensureDir(path12.join(claudeDir, "scripts/statusline/data"));
33697
33968
  s.stop("Scripts installed");
33698
33969
  } else {
33699
33970
  s.stop("Scripts not available in repository");
@@ -33701,8 +33972,8 @@ async function setupCommand(params = {}) {
33701
33972
  }
33702
33973
  if (options.aiblueprintAgents) {
33703
33974
  s.start("Setting up AIBlueprint agents");
33704
- const agentsSource = path11.join(sourceDir, "agents");
33705
- if (await import_fs_extra7.default.pathExists(agentsSource)) {
33975
+ const agentsSource = path12.join(sourceDir, "agents");
33976
+ if (await import_fs_extra8.default.pathExists(agentsSource)) {
33706
33977
  const installResult = await installCategoryToAgents(agentsSource, "agents", agentsDir, claudeDir, { migrateClaudeDirs: true, silent: true });
33707
33978
  const summary = [
33708
33979
  installResult.copied.length && `${installResult.copied.length} copied`,
@@ -33717,8 +33988,8 @@ async function setupCommand(params = {}) {
33717
33988
  }
33718
33989
  if (options.aiblueprintSkills) {
33719
33990
  s.start("Setting up AIBlueprint Skills");
33720
- const skillsSourcePath = path11.join(sourceDir, "skills");
33721
- if (await import_fs_extra7.default.pathExists(skillsSourcePath)) {
33991
+ const skillsSourcePath = path12.join(sourceDir, "skills");
33992
+ if (await import_fs_extra8.default.pathExists(skillsSourcePath)) {
33722
33993
  const installResult = await installCategoryToAgents(skillsSourcePath, "skills", agentsDir, claudeDir, { migrateClaudeDirs: true, silent: true });
33723
33994
  const summary = [
33724
33995
  installResult.copied.length && `${installResult.copied.length} copied`,
@@ -33738,10 +34009,21 @@ async function setupCommand(params = {}) {
33738
34009
  }
33739
34010
  if (options.installCodex) {
33740
34011
  s.start("Setting up Codex");
33741
- await import_fs_extra7.default.ensureDir(codexDir);
33742
- const codexConfigSource = path11.join(sourceDir, "codex-config");
33743
- if (await import_fs_extra7.default.pathExists(codexConfigSource)) {
33744
- await import_fs_extra7.default.copy(codexConfigSource, codexDir, { overwrite: false });
34012
+ await import_fs_extra8.default.ensureDir(codexDir);
34013
+ const codexConfigSource = path12.join(sourceDir, "codex-config");
34014
+ if (await import_fs_extra8.default.pathExists(codexConfigSource)) {
34015
+ const codexConfigPath = path12.join(codexConfigSource, "config.toml");
34016
+ if (await import_fs_extra8.default.pathExists(codexConfigPath)) {
34017
+ await mergeCodexConfigFile(codexConfigPath, codexDir);
34018
+ }
34019
+ const entries = await import_fs_extra8.default.readdir(codexConfigSource);
34020
+ for (const entry of entries) {
34021
+ if (entry === "config.toml")
34022
+ continue;
34023
+ await import_fs_extra8.default.copy(path12.join(codexConfigSource, entry), path12.join(codexDir, entry), {
34024
+ overwrite: false
34025
+ });
34026
+ }
33745
34027
  }
33746
34028
  if (options.aiblueprintSkills) {
33747
34029
  await syncCategorySymlinks("skills", agentsDir, codexDir, undefined, true);
@@ -33787,7 +34069,7 @@ async function setupCommand(params = {}) {
33787
34069
  console.log(source_default.gray(`
33788
34070
  Next steps:`));
33789
34071
  if (options.shellShortcuts) {
33790
- const platform = os11.platform();
34072
+ const platform = os10.platform();
33791
34073
  if (platform === "win32") {
33792
34074
  console.log(source_default.gray(" • Restart PowerShell to load the new functions"));
33793
34075
  } else {
@@ -33813,9 +34095,9 @@ Next steps:`));
33813
34095
  }
33814
34096
 
33815
34097
  // src/commands/setup-terminal.ts
33816
- var import_fs_extra8 = __toESM(require_lib4(), 1);
33817
- import path12 from "path";
33818
- import os12 from "os";
34098
+ var import_fs_extra9 = __toESM(require_lib4(), 1);
34099
+ import path13 from "path";
34100
+ import os11 from "os";
33819
34101
  import { execSync as execSync3, exec as exec2 } from "child_process";
33820
34102
  var OHMYZSH_INSTALL_URL = "https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh";
33821
34103
  var INSTALL_TIMEOUT = 120000;
@@ -33849,16 +34131,16 @@ function commandExists(cmd) {
33849
34131
  }
33850
34132
  }
33851
34133
  function isOhMyZshInstalled(homeDir) {
33852
- const ohMyZshDir = path12.join(homeDir, ".oh-my-zsh");
33853
- return import_fs_extra8.default.existsSync(ohMyZshDir);
34134
+ const ohMyZshDir = path13.join(homeDir, ".oh-my-zsh");
34135
+ return import_fs_extra9.default.existsSync(ohMyZshDir);
33854
34136
  }
33855
34137
  function backupFile(filePath) {
33856
- if (!import_fs_extra8.default.existsSync(filePath))
34138
+ if (!import_fs_extra9.default.existsSync(filePath))
33857
34139
  return null;
33858
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
33859
- const backupPath = `${filePath}.backup-${timestamp}`;
34140
+ const timestamp2 = new Date().toISOString().replace(/[:.]/g, "-");
34141
+ const backupPath = `${filePath}.backup-${timestamp2}`;
33860
34142
  try {
33861
- import_fs_extra8.default.copyFileSync(filePath, backupPath);
34143
+ import_fs_extra9.default.copyFileSync(filePath, backupPath);
33862
34144
  return backupPath;
33863
34145
  } catch (error) {
33864
34146
  throw new Error(`Failed to create backup: ${error.message}`);
@@ -33897,7 +34179,7 @@ function installPrerequisiteSync(packageName, installCmd) {
33897
34179
  async function installOhMyZsh(homeDir) {
33898
34180
  return new Promise((resolve, reject) => {
33899
34181
  const installCmd = `sh -c "$(curl -fsSL ${OHMYZSH_INSTALL_URL})" "" --unattended`;
33900
- const env2 = { ...process.env, HOME: homeDir, ZSH: path12.join(homeDir, ".oh-my-zsh") };
34182
+ const env2 = { ...process.env, HOME: homeDir, ZSH: path13.join(homeDir, ".oh-my-zsh") };
33901
34183
  exec2(installCmd, { timeout: INSTALL_TIMEOUT, env: env2 }, (error, stdout, stderr) => {
33902
34184
  if (error) {
33903
34185
  if ("killed" in error && error.killed) {
@@ -33918,8 +34200,8 @@ async function installPlugin(pluginName, repoUrl, homeDir) {
33918
34200
  if (!/^https:\/\/github\.com\/[\w-]+\/[\w-]+$/.test(repoUrl)) {
33919
34201
  throw new Error(`Invalid repository URL: ${repoUrl}`);
33920
34202
  }
33921
- const customPluginsDir = path12.join(homeDir, ".oh-my-zsh/custom/plugins", pluginName);
33922
- if (import_fs_extra8.default.existsSync(customPluginsDir)) {
34203
+ const customPluginsDir = path13.join(homeDir, ".oh-my-zsh/custom/plugins", pluginName);
34204
+ if (import_fs_extra9.default.existsSync(customPluginsDir)) {
33923
34205
  return;
33924
34206
  }
33925
34207
  return new Promise((resolve, reject) => {
@@ -33937,20 +34219,20 @@ async function installPlugin(pluginName, repoUrl, homeDir) {
33937
34219
  });
33938
34220
  }
33939
34221
  function updateZshrcTheme(theme, homeDir) {
33940
- const zshrcPath = path12.join(homeDir, ".zshrc");
34222
+ const zshrcPath = path13.join(homeDir, ".zshrc");
33941
34223
  const sanitizedTheme = sanitizeThemeName(theme);
33942
- if (!import_fs_extra8.default.existsSync(zshrcPath)) {
34224
+ if (!import_fs_extra9.default.existsSync(zshrcPath)) {
33943
34225
  throw new Error(".zshrc file not found. Please ensure Oh My ZSH is installed correctly.");
33944
34226
  }
33945
34227
  try {
33946
- let content = import_fs_extra8.default.readFileSync(zshrcPath, "utf-8");
34228
+ let content = import_fs_extra9.default.readFileSync(zshrcPath, "utf-8");
33947
34229
  if (content.match(/^ZSH_THEME=/m)) {
33948
34230
  content = content.replace(/^ZSH_THEME=.*/m, `ZSH_THEME="${sanitizedTheme}"`);
33949
34231
  } else {
33950
34232
  content = `ZSH_THEME="${sanitizedTheme}"
33951
34233
  ${content}`;
33952
34234
  }
33953
- import_fs_extra8.default.writeFileSync(zshrcPath, content);
34235
+ import_fs_extra9.default.writeFileSync(zshrcPath, content);
33954
34236
  } catch (error) {
33955
34237
  if (error.message.includes(".zshrc file not found")) {
33956
34238
  throw error;
@@ -33959,12 +34241,12 @@ ${content}`;
33959
34241
  }
33960
34242
  }
33961
34243
  function updateZshrcPlugins(plugins, homeDir) {
33962
- const zshrcPath = path12.join(homeDir, ".zshrc");
33963
- if (!import_fs_extra8.default.existsSync(zshrcPath)) {
34244
+ const zshrcPath = path13.join(homeDir, ".zshrc");
34245
+ if (!import_fs_extra9.default.existsSync(zshrcPath)) {
33964
34246
  throw new Error(".zshrc file not found. Please ensure Oh My ZSH is installed correctly.");
33965
34247
  }
33966
34248
  try {
33967
- let content = import_fs_extra8.default.readFileSync(zshrcPath, "utf-8");
34249
+ let content = import_fs_extra9.default.readFileSync(zshrcPath, "utf-8");
33968
34250
  const pluginsString = plugins.join(" ");
33969
34251
  if (content.match(/^plugins=\(/m)) {
33970
34252
  content = content.replace(/^plugins=\([^)]*\)/m, `plugins=(${pluginsString})`);
@@ -33972,7 +34254,7 @@ function updateZshrcPlugins(plugins, homeDir) {
33972
34254
  content = `${content}
33973
34255
  plugins=(${pluginsString})`;
33974
34256
  }
33975
- import_fs_extra8.default.writeFileSync(zshrcPath, content);
34257
+ import_fs_extra9.default.writeFileSync(zshrcPath, content);
33976
34258
  } catch (error) {
33977
34259
  if (error.message.includes(".zshrc file not found")) {
33978
34260
  throw error;
@@ -33982,7 +34264,7 @@ plugins=(${pluginsString})`;
33982
34264
  }
33983
34265
  async function setupTerminalCommand(options = {}) {
33984
34266
  const { skipInteractive, homeDir: customHomeDir } = options;
33985
- const homeDir = customHomeDir || os12.homedir();
34267
+ const homeDir = customHomeDir || os11.homedir();
33986
34268
  try {
33987
34269
  console.log(source_default.blue.bold(`
33988
34270
  \uD83D\uDDA5️ AIBlueprint Terminal Setup ${source_default.gray(`v${getVersion()}`)}
@@ -34079,8 +34361,8 @@ Installing missing prerequisites: ${missingPrereqs.join(", ")}`));
34079
34361
  selectedTheme = themeAnswer.theme;
34080
34362
  }
34081
34363
  }
34082
- const zshrcPath = path12.join(homeDir, ".zshrc");
34083
- if (import_fs_extra8.default.existsSync(zshrcPath)) {
34364
+ const zshrcPath = path13.join(homeDir, ".zshrc");
34365
+ if (import_fs_extra9.default.existsSync(zshrcPath)) {
34084
34366
  s.start("Backing up .zshrc");
34085
34367
  const backupPath = backupFile(zshrcPath);
34086
34368
  if (backupPath) {
@@ -34130,37 +34412,37 @@ Next steps:`));
34130
34412
  }
34131
34413
 
34132
34414
  // src/commands/setup/symlinks.ts
34133
- var import_fs_extra9 = __toESM(require_lib4(), 1);
34134
- import path13 from "path";
34135
- import os13 from "os";
34415
+ var import_fs_extra10 = __toESM(require_lib4(), 1);
34416
+ import path14 from "path";
34417
+ import os12 from "os";
34136
34418
  async function getToolPaths(tool, customFolder) {
34137
34419
  let baseDir;
34138
34420
  switch (tool) {
34139
34421
  case "claude-code":
34140
- baseDir = customFolder ? path13.resolve(customFolder) : path13.join(os13.homedir(), ".claude");
34422
+ baseDir = customFolder ? path14.resolve(customFolder) : path14.join(os12.homedir(), ".claude");
34141
34423
  return {
34142
34424
  baseDir,
34143
- commandsPath: path13.join(baseDir, "commands"),
34144
- agentsPath: path13.join(baseDir, "agents")
34425
+ commandsPath: path14.join(baseDir, "commands"),
34426
+ agentsPath: path14.join(baseDir, "agents")
34145
34427
  };
34146
34428
  case "codex":
34147
- baseDir = customFolder ? path13.resolve(customFolder) : path13.join(os13.homedir(), ".codex");
34429
+ baseDir = customFolder ? path14.resolve(customFolder) : path14.join(os12.homedir(), ".codex");
34148
34430
  return {
34149
34431
  baseDir,
34150
- agentsPath: path13.join(baseDir, "agents")
34432
+ agentsPath: path14.join(baseDir, "agents")
34151
34433
  };
34152
34434
  case "opencode":
34153
- baseDir = customFolder ? path13.resolve(customFolder) : path13.join(os13.homedir(), ".config", "opencode");
34435
+ baseDir = customFolder ? path14.resolve(customFolder) : path14.join(os12.homedir(), ".config", "opencode");
34154
34436
  return {
34155
34437
  baseDir,
34156
- commandsPath: path13.join(baseDir, "command")
34438
+ commandsPath: path14.join(baseDir, "command")
34157
34439
  };
34158
34440
  case "factoryai":
34159
- baseDir = customFolder ? path13.resolve(customFolder) : path13.join(os13.homedir(), ".factory");
34441
+ baseDir = customFolder ? path14.resolve(customFolder) : path14.join(os12.homedir(), ".factory");
34160
34442
  return {
34161
34443
  baseDir,
34162
- commandsPath: path13.join(baseDir, "commands"),
34163
- agentsPath: path13.join(baseDir, "droids")
34444
+ commandsPath: path14.join(baseDir, "commands"),
34445
+ agentsPath: path14.join(baseDir, "droids")
34164
34446
  };
34165
34447
  default:
34166
34448
  throw new Error(`Unknown tool type: ${tool}`);
@@ -34168,28 +34450,28 @@ async function getToolPaths(tool, customFolder) {
34168
34450
  }
34169
34451
  async function createSymlink(sourcePath, targetPath, options = {}) {
34170
34452
  try {
34171
- const sourceExists = await import_fs_extra9.default.pathExists(sourcePath);
34453
+ const sourceExists = await import_fs_extra10.default.pathExists(sourcePath);
34172
34454
  if (!sourceExists) {
34173
34455
  console.log(source_default.yellow(` Source path ${sourcePath} does not exist. Skipping symlink creation...`));
34174
34456
  return false;
34175
34457
  }
34176
- const targetDir = path13.dirname(targetPath);
34177
- await import_fs_extra9.default.ensureDir(targetDir);
34178
- const targetExists = await import_fs_extra9.default.pathExists(targetPath);
34458
+ const targetDir = path14.dirname(targetPath);
34459
+ await import_fs_extra10.default.ensureDir(targetDir);
34460
+ const targetExists = await import_fs_extra10.default.pathExists(targetPath);
34179
34461
  if (targetExists) {
34180
- const stat = await import_fs_extra9.default.lstat(targetPath);
34462
+ const stat = await import_fs_extra10.default.lstat(targetPath);
34181
34463
  if (stat.isSymbolicLink()) {
34182
- await import_fs_extra9.default.remove(targetPath);
34464
+ await import_fs_extra10.default.remove(targetPath);
34183
34465
  } else {
34184
34466
  console.log(source_default.yellow(options.skipMessage || ` ${targetPath} already exists and is not a symlink. Skipping...`));
34185
34467
  return false;
34186
34468
  }
34187
34469
  }
34188
- const isWindows2 = os13.platform() === "win32";
34470
+ const isWindows2 = os12.platform() === "win32";
34189
34471
  if (isWindows2) {
34190
- await import_fs_extra9.default.symlink(sourcePath, targetPath, "junction");
34472
+ await import_fs_extra10.default.symlink(sourcePath, targetPath, "junction");
34191
34473
  } else {
34192
- await import_fs_extra9.default.symlink(sourcePath, targetPath);
34474
+ await import_fs_extra10.default.symlink(sourcePath, targetPath);
34193
34475
  }
34194
34476
  return true;
34195
34477
  } catch (error) {
@@ -35085,12 +35367,12 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
35085
35367
  };
35086
35368
 
35087
35369
  // src/commands/pro.ts
35088
- import path16 from "path";
35370
+ import path17 from "path";
35089
35371
 
35090
35372
  // src/lib/pro-installer.ts
35091
- var import_fs_extra10 = __toESM(require_lib4(), 1);
35092
- import os14 from "os";
35093
- import path14 from "path";
35373
+ var import_fs_extra11 = __toESM(require_lib4(), 1);
35374
+ import os13 from "os";
35375
+ import path15 from "path";
35094
35376
  import { exec as exec3 } from "child_process";
35095
35377
  import { promisify as promisify2 } from "util";
35096
35378
  var execAsync2 = promisify2(exec3);
@@ -35098,9 +35380,9 @@ var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
35098
35380
  var PREMIUM_BRANCH = "main";
35099
35381
  var CONFIG_FOLDER_CANDIDATES2 = ["agents-config", "ai-coding", "claude-code-config", "ai-config"];
35100
35382
  function routePath(relativePath) {
35101
- const segments = relativePath.split(path14.sep);
35383
+ const segments = relativePath.split(path15.sep);
35102
35384
  const first = segments[0];
35103
- const rest = segments.slice(1).join(path14.sep);
35385
+ const rest = segments.slice(1).join(path15.sep);
35104
35386
  if (first === "claude-config") {
35105
35387
  return { kind: "claude", relativePath: rest };
35106
35388
  }
@@ -35116,7 +35398,7 @@ function routePath(relativePath) {
35116
35398
  return { kind: "claude", relativePath };
35117
35399
  }
35118
35400
  function getCacheRepoDir() {
35119
- return path14.join(os14.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
35401
+ return path15.join(os13.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
35120
35402
  }
35121
35403
  async function execGitWithAuth(command, token, repoUrl, cwd) {
35122
35404
  const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
@@ -35130,21 +35412,21 @@ async function execGitWithAuth(command, token, repoUrl, cwd) {
35130
35412
  async function cloneOrUpdateRepo(token) {
35131
35413
  const cacheDir = getCacheRepoDir();
35132
35414
  const repoUrl = `https://github.com/${PREMIUM_REPO}.git`;
35133
- if (await import_fs_extra10.default.pathExists(path14.join(cacheDir, ".git"))) {
35415
+ if (await import_fs_extra11.default.pathExists(path15.join(cacheDir, ".git"))) {
35134
35416
  try {
35135
35417
  await execGitWithAuth("pull", token, repoUrl, cacheDir);
35136
35418
  } catch (error) {
35137
- await import_fs_extra10.default.remove(cacheDir);
35138
- await import_fs_extra10.default.ensureDir(path14.dirname(cacheDir));
35419
+ await import_fs_extra11.default.remove(cacheDir);
35420
+ await import_fs_extra11.default.ensureDir(path15.dirname(cacheDir));
35139
35421
  await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
35140
35422
  }
35141
35423
  } else {
35142
- await import_fs_extra10.default.ensureDir(path14.dirname(cacheDir));
35424
+ await import_fs_extra11.default.ensureDir(path15.dirname(cacheDir));
35143
35425
  await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
35144
35426
  }
35145
35427
  for (const candidate of CONFIG_FOLDER_CANDIDATES2) {
35146
- const candidatePath = path14.join(cacheDir, candidate);
35147
- if (await import_fs_extra10.default.pathExists(candidatePath)) {
35428
+ const candidatePath = path15.join(cacheDir, candidate);
35429
+ if (await import_fs_extra11.default.pathExists(candidatePath)) {
35148
35430
  return candidatePath;
35149
35431
  }
35150
35432
  }
@@ -35152,35 +35434,38 @@ async function cloneOrUpdateRepo(token) {
35152
35434
  }
35153
35435
  async function copyConfigFromCache(cacheConfigDir, dest, onProgress) {
35154
35436
  const walk = async (dir, baseDir = dir) => {
35155
- const entries = await import_fs_extra10.default.readdir(dir, { withFileTypes: true });
35437
+ const entries = await import_fs_extra11.default.readdir(dir, { withFileTypes: true });
35156
35438
  for (const entry of entries) {
35157
35439
  if (entry.name === ".DS_Store" || entry.name === "node_modules")
35158
35440
  continue;
35159
- const sourcePath = path14.join(dir, entry.name);
35160
- const relativePath = path14.relative(baseDir, sourcePath);
35441
+ const sourcePath = path15.join(dir, entry.name);
35442
+ const relativePath = path15.relative(baseDir, sourcePath);
35161
35443
  const route = routePath(relativePath);
35162
35444
  if (route.kind === "skip")
35163
35445
  continue;
35164
35446
  if (route.kind === "agents-category") {
35165
- if (relativePath.split(path14.sep).length === 1) {
35447
+ if (relativePath.split(path15.sep).length === 1) {
35166
35448
  await copyAgentCategory(sourcePath, route.category, dest.agentsDir, dest.claudeDir, onProgress);
35167
35449
  }
35168
35450
  continue;
35169
35451
  }
35170
35452
  const targetBase = route.kind === "claude" ? dest.claudeDir : dest.codexDir;
35171
- const targetPath = path14.join(targetBase, route.relativePath);
35453
+ const targetPath = path15.join(targetBase, route.relativePath);
35172
35454
  if (entry.isDirectory()) {
35173
- await import_fs_extra10.default.ensureDir(targetPath);
35455
+ await import_fs_extra11.default.ensureDir(targetPath);
35174
35456
  onProgress?.(relativePath, "directory");
35175
35457
  await walk(sourcePath, baseDir);
35458
+ } else if (route.kind === "codex" && route.relativePath === "config.toml") {
35459
+ await mergeCodexConfigFile(sourcePath, dest.codexDir);
35460
+ onProgress?.(relativePath, "file");
35176
35461
  } else if (isTextFile(entry.name)) {
35177
- const content = await import_fs_extra10.default.readFile(sourcePath, "utf-8");
35462
+ const content = await import_fs_extra11.default.readFile(sourcePath, "utf-8");
35178
35463
  const replaced = replaceClaudePathPlaceholder(content, dest.claudeDir);
35179
- await import_fs_extra10.default.ensureDir(path14.dirname(targetPath));
35180
- await import_fs_extra10.default.writeFile(targetPath, replaced, "utf-8");
35464
+ await import_fs_extra11.default.ensureDir(path15.dirname(targetPath));
35465
+ await import_fs_extra11.default.writeFile(targetPath, replaced, "utf-8");
35181
35466
  onProgress?.(relativePath, "file");
35182
35467
  } else {
35183
- await import_fs_extra10.default.copy(sourcePath, targetPath, { overwrite: true });
35468
+ await import_fs_extra11.default.copy(sourcePath, targetPath, { overwrite: true });
35184
35469
  onProgress?.(relativePath, "file");
35185
35470
  }
35186
35471
  }
@@ -35188,22 +35473,22 @@ async function copyConfigFromCache(cacheConfigDir, dest, onProgress) {
35188
35473
  await walk(cacheConfigDir);
35189
35474
  }
35190
35475
  async function copyAgentCategory(sourceCategoryDir, category, agentsDir, claudeDir, onProgress) {
35191
- const agentsCategoryDir = path14.join(agentsDir, category);
35192
- await import_fs_extra10.default.ensureDir(agentsCategoryDir);
35193
- const entries = await import_fs_extra10.default.readdir(sourceCategoryDir, { withFileTypes: true });
35476
+ const agentsCategoryDir = path15.join(agentsDir, category);
35477
+ await import_fs_extra11.default.ensureDir(agentsCategoryDir);
35478
+ const entries = await import_fs_extra11.default.readdir(sourceCategoryDir, { withFileTypes: true });
35194
35479
  for (const entry of entries) {
35195
35480
  if (entry.name === ".DS_Store")
35196
35481
  continue;
35197
- const src = path14.join(sourceCategoryDir, entry.name);
35198
- const dst = path14.join(agentsCategoryDir, entry.name);
35199
- const claudeTop = path14.join(claudeDir, category, entry.name);
35200
- const claudeStat = await import_fs_extra10.default.lstat(claudeTop).catch(() => null);
35482
+ const src = path15.join(sourceCategoryDir, entry.name);
35483
+ const dst = path15.join(agentsCategoryDir, entry.name);
35484
+ const claudeTop = path15.join(claudeDir, category, entry.name);
35485
+ const claudeStat = await import_fs_extra11.default.lstat(claudeTop).catch(() => null);
35201
35486
  if (claudeStat && !claudeStat.isSymbolicLink()) {
35202
35487
  onProgress?.(`${category}/${entry.name} (skipped - real dir in claude)`, "file");
35203
35488
  continue;
35204
35489
  }
35205
- await import_fs_extra10.default.copy(src, dst, { overwrite: true });
35206
- await replacePathPlaceholdersInDir(dst, claudeDir);
35490
+ await import_fs_extra11.default.copy(src, dst, { overwrite: true });
35491
+ await applyPathPlaceholders(dst, claudeDir);
35207
35492
  onProgress?.(`${category}/${entry.name}`, entry.isDirectory() ? "directory" : "file");
35208
35493
  }
35209
35494
  }
@@ -35221,8 +35506,8 @@ async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath,
35221
35506
  return false;
35222
35507
  }
35223
35508
  const content = await response.arrayBuffer();
35224
- await import_fs_extra10.default.ensureDir(path14.dirname(targetPath));
35225
- await import_fs_extra10.default.writeFile(targetPath, Buffer.from(content));
35509
+ await import_fs_extra11.default.ensureDir(path15.dirname(targetPath));
35510
+ await import_fs_extra11.default.writeFile(targetPath, Buffer.from(content));
35226
35511
  return true;
35227
35512
  } catch (error) {
35228
35513
  console.error(`Error downloading ${relativePath}:`, error);
@@ -35247,10 +35532,10 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
35247
35532
  console.error(`Unexpected response for directory ${dirPath}`);
35248
35533
  return false;
35249
35534
  }
35250
- await import_fs_extra10.default.ensureDir(targetDir);
35535
+ await import_fs_extra11.default.ensureDir(targetDir);
35251
35536
  for (const file of files) {
35252
35537
  const relativePath = dirPath ? `${dirPath}/${file.name}` : file.name;
35253
- const targetPath = path14.join(targetDir, file.name);
35538
+ const targetPath = path15.join(targetDir, file.name);
35254
35539
  const displayPath = relativePath.replace(/^(agents-config|ai-coding|claude-code-config|ai-config)\//, "");
35255
35540
  if (file.type === "file") {
35256
35541
  onProgress?.(displayPath, "file");
@@ -35273,8 +35558,8 @@ async function installProConfigs(options) {
35273
35558
  codexFolder,
35274
35559
  agentsFolder
35275
35560
  });
35276
- await import_fs_extra10.default.ensureDir(claudeDir);
35277
- await import_fs_extra10.default.ensureDir(agentsDir);
35561
+ await import_fs_extra11.default.ensureDir(claudeDir);
35562
+ await import_fs_extra11.default.ensureDir(agentsDir);
35278
35563
  const dest = { claudeDir, codexDir, agentsDir };
35279
35564
  try {
35280
35565
  const cacheConfigDir = await cloneOrUpdateRepo(githubToken);
@@ -35284,7 +35569,7 @@ async function installProConfigs(options) {
35284
35569
  } catch (error) {
35285
35570
  console.warn("Git caching failed, falling back to API download");
35286
35571
  }
35287
- const tempDir = path14.join(os14.tmpdir(), `aiblueprint-premium-${Date.now()}`);
35572
+ const tempDir = path15.join(os13.tmpdir(), `aiblueprint-premium-${Date.now()}`);
35288
35573
  try {
35289
35574
  let success = false;
35290
35575
  for (const candidate of CONFIG_FOLDER_CANDIDATES2) {
@@ -35298,8 +35583,8 @@ async function installProConfigs(options) {
35298
35583
  await copyConfigFromCache(tempDir, dest, onProgress);
35299
35584
  await replacePathPlaceholdersInDir(claudeDir, claudeDir);
35300
35585
  for (const category of AGENT_CATEGORIES) {
35301
- const agentsCategoryDir = path14.join(agentsDir, category);
35302
- if (await import_fs_extra10.default.pathExists(agentsCategoryDir)) {
35586
+ const agentsCategoryDir = path15.join(agentsDir, category);
35587
+ if (await import_fs_extra11.default.pathExists(agentsCategoryDir)) {
35303
35588
  await replacePathPlaceholdersInDir(agentsCategoryDir, claudeDir);
35304
35589
  }
35305
35590
  }
@@ -35308,7 +35593,7 @@ async function installProConfigs(options) {
35308
35593
  throw new Error(`Failed to install premium configs: ${error instanceof Error ? error.message : "Unknown error"}`);
35309
35594
  } finally {
35310
35595
  try {
35311
- await import_fs_extra10.default.remove(tempDir);
35596
+ await import_fs_extra11.default.remove(tempDir);
35312
35597
  } catch {}
35313
35598
  }
35314
35599
  }
@@ -35319,27 +35604,27 @@ async function syncAllAgentSymlinks(agentsDir, claudeDir) {
35319
35604
  }
35320
35605
 
35321
35606
  // src/lib/token-storage.ts
35322
- var import_fs_extra11 = __toESM(require_lib4(), 1);
35323
- import os15 from "os";
35324
- import path15 from "path";
35607
+ var import_fs_extra12 = __toESM(require_lib4(), 1);
35608
+ import os14 from "os";
35609
+ import path16 from "path";
35325
35610
  function getConfigDir() {
35326
- const platform = os15.platform();
35611
+ const platform = os14.platform();
35327
35612
  if (platform === "win32") {
35328
- const appData = process.env.APPDATA || path15.join(os15.homedir(), "AppData", "Roaming");
35329
- return path15.join(appData, "aiblueprint");
35613
+ const appData = process.env.APPDATA || path16.join(os14.homedir(), "AppData", "Roaming");
35614
+ return path16.join(appData, "aiblueprint");
35330
35615
  } else {
35331
- const configHome = process.env.XDG_CONFIG_HOME || path15.join(os15.homedir(), ".config");
35332
- return path15.join(configHome, "aiblueprint");
35616
+ const configHome = process.env.XDG_CONFIG_HOME || path16.join(os14.homedir(), ".config");
35617
+ return path16.join(configHome, "aiblueprint");
35333
35618
  }
35334
35619
  }
35335
35620
  function getTokenFilePath2() {
35336
- return path15.join(getConfigDir(), "token.txt");
35621
+ return path16.join(getConfigDir(), "token.txt");
35337
35622
  }
35338
35623
  async function saveToken(githubToken) {
35339
35624
  const tokenFile = getTokenFilePath2();
35340
- const configDir = path15.dirname(tokenFile);
35625
+ const configDir = path16.dirname(tokenFile);
35341
35626
  try {
35342
- await import_fs_extra11.default.ensureDir(configDir);
35627
+ await import_fs_extra12.default.ensureDir(configDir);
35343
35628
  } catch (error) {
35344
35629
  if (error.code === "EACCES") {
35345
35630
  throw new Error(`Permission denied creating config directory: ${configDir}
@@ -35347,15 +35632,15 @@ async function saveToken(githubToken) {
35347
35632
  }
35348
35633
  throw error;
35349
35634
  }
35350
- await import_fs_extra11.default.writeFile(tokenFile, githubToken, { mode: 384 });
35635
+ await import_fs_extra12.default.writeFile(tokenFile, githubToken, { mode: 384 });
35351
35636
  }
35352
35637
  async function getToken() {
35353
35638
  const tokenFile = getTokenFilePath2();
35354
- if (!await import_fs_extra11.default.pathExists(tokenFile)) {
35639
+ if (!await import_fs_extra12.default.pathExists(tokenFile)) {
35355
35640
  return null;
35356
35641
  }
35357
35642
  try {
35358
- const token = await import_fs_extra11.default.readFile(tokenFile, "utf-8");
35643
+ const token = await import_fs_extra12.default.readFile(tokenFile, "utf-8");
35359
35644
  return token.trim();
35360
35645
  } catch (error) {
35361
35646
  return null;
@@ -35364,12 +35649,12 @@ async function getToken() {
35364
35649
  function getTokenInfo() {
35365
35650
  return {
35366
35651
  path: getTokenFilePath2(),
35367
- platform: os15.platform()
35652
+ platform: os14.platform()
35368
35653
  };
35369
35654
  }
35370
35655
 
35371
35656
  // src/commands/pro.ts
35372
- var import_fs_extra12 = __toESM(require_lib4(), 1);
35657
+ var import_fs_extra13 = __toESM(require_lib4(), 1);
35373
35658
  var API_URL = "https://codeline.app/api/products";
35374
35659
  var PRODUCT_IDS = ["prd_XJVgxVPbGG", "prd_NKabAkdOkw"];
35375
35660
  async function countInstalledItems(claudeDir) {
@@ -35378,20 +35663,20 @@ async function countInstalledItems(claudeDir) {
35378
35663
  skills: 0
35379
35664
  };
35380
35665
  try {
35381
- const agentsDir = path16.join(claudeDir, "agents");
35382
- if (await import_fs_extra12.default.pathExists(agentsDir)) {
35383
- const files = await import_fs_extra12.default.readdir(agentsDir);
35666
+ const agentsDir = path17.join(claudeDir, "agents");
35667
+ if (await import_fs_extra13.default.pathExists(agentsDir)) {
35668
+ const files = await import_fs_extra13.default.readdir(agentsDir);
35384
35669
  counts.agents = files.filter((f) => f.endsWith(".md")).length;
35385
35670
  }
35386
35671
  } catch (error) {
35387
35672
  console.error("Failed to count agents:", error instanceof Error ? error.message : error);
35388
35673
  }
35389
35674
  try {
35390
- const skillsDir = path16.join(claudeDir, "skills");
35391
- if (await import_fs_extra12.default.pathExists(skillsDir)) {
35392
- const items = await import_fs_extra12.default.readdir(skillsDir);
35675
+ const skillsDir = path17.join(claudeDir, "skills");
35676
+ if (await import_fs_extra13.default.pathExists(skillsDir)) {
35677
+ const items = await import_fs_extra13.default.readdir(skillsDir);
35393
35678
  const dirs = await Promise.all(items.map(async (item) => {
35394
- const stat = await import_fs_extra12.default.stat(path16.join(skillsDir, item));
35679
+ const stat = await import_fs_extra13.default.stat(path17.join(skillsDir, item));
35395
35680
  return stat.isDirectory();
35396
35681
  }));
35397
35682
  counts.skills = dirs.filter(Boolean).length;
@@ -35599,8 +35884,8 @@ async function proUpdateCommand(options = {}) {
35599
35884
  }
35600
35885
 
35601
35886
  // src/lib/sync-utils.ts
35602
- var import_fs_extra13 = __toESM(require_lib4(), 1);
35603
- import path17 from "path";
35887
+ var import_fs_extra14 = __toESM(require_lib4(), 1);
35888
+ import path18 from "path";
35604
35889
  import crypto from "crypto";
35605
35890
  var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
35606
35891
  var PREMIUM_BRANCH2 = "main";
@@ -35671,7 +35956,7 @@ async function listRemoteFilesRecursive(dirPath, githubToken, basePath = "") {
35671
35956
  }
35672
35957
  async function computeLocalFileSha(filePath) {
35673
35958
  try {
35674
- const content = await import_fs_extra13.default.readFile(filePath);
35959
+ const content = await import_fs_extra14.default.readFile(filePath);
35675
35960
  return computeFileSha(content);
35676
35961
  } catch {
35677
35962
  return null;
@@ -35679,15 +35964,15 @@ async function computeLocalFileSha(filePath) {
35679
35964
  }
35680
35965
  async function listLocalFiles(dir) {
35681
35966
  const files = [];
35682
- if (!await import_fs_extra13.default.pathExists(dir)) {
35967
+ if (!await import_fs_extra14.default.pathExists(dir)) {
35683
35968
  return files;
35684
35969
  }
35685
- const items = await import_fs_extra13.default.readdir(dir);
35970
+ const items = await import_fs_extra14.default.readdir(dir);
35686
35971
  for (const item of items) {
35687
35972
  if (item === "node_modules" || item === ".DS_Store")
35688
35973
  continue;
35689
- const fullPath = path17.join(dir, item);
35690
- const stat = await import_fs_extra13.default.stat(fullPath).catch(() => null);
35974
+ const fullPath = path18.join(dir, item);
35975
+ const stat = await import_fs_extra14.default.stat(fullPath).catch(() => null);
35691
35976
  if (!stat)
35692
35977
  continue;
35693
35978
  if (stat.isDirectory()) {
@@ -35702,13 +35987,13 @@ async function listLocalFiles(dir) {
35702
35987
  }
35703
35988
  async function listLocalFilesRecursive(dir, basePath) {
35704
35989
  const files = [];
35705
- const items = await import_fs_extra13.default.readdir(dir).catch(() => []);
35990
+ const items = await import_fs_extra14.default.readdir(dir).catch(() => []);
35706
35991
  for (const item of items) {
35707
35992
  if (item === "node_modules" || item === ".DS_Store")
35708
35993
  continue;
35709
- const fullPath = path17.join(dir, item);
35994
+ const fullPath = path18.join(dir, item);
35710
35995
  const relativePath = `${basePath}/${item}`;
35711
- const stat = await import_fs_extra13.default.stat(fullPath).catch(() => null);
35996
+ const stat = await import_fs_extra14.default.stat(fullPath).catch(() => null);
35712
35997
  if (!stat)
35713
35998
  continue;
35714
35999
  if (stat.isDirectory()) {
@@ -35722,14 +36007,14 @@ async function listLocalFilesRecursive(dir, basePath) {
35722
36007
  return files;
35723
36008
  }
35724
36009
  async function listClaudeRealTopLevel(claudeCategoryDir) {
35725
- if (!await import_fs_extra13.default.pathExists(claudeCategoryDir))
36010
+ if (!await import_fs_extra14.default.pathExists(claudeCategoryDir))
35726
36011
  return [];
35727
- const entries = await import_fs_extra13.default.readdir(claudeCategoryDir).catch(() => []);
36012
+ const entries = await import_fs_extra14.default.readdir(claudeCategoryDir).catch(() => []);
35728
36013
  const real = [];
35729
36014
  for (const name of entries) {
35730
36015
  if (name === "node_modules" || name === ".DS_Store")
35731
36016
  continue;
35732
- const stat = await import_fs_extra13.default.lstat(path17.join(claudeCategoryDir, name)).catch(() => null);
36017
+ const stat = await import_fs_extra14.default.lstat(path18.join(claudeCategoryDir, name)).catch(() => null);
35733
36018
  if (!stat)
35734
36019
  continue;
35735
36020
  if (stat.isDirectory())
@@ -35746,7 +36031,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
35746
36031
  const items = [];
35747
36032
  const useAgents = isAgentCategory(category);
35748
36033
  const localBase = useAgents ? agentsDir : claudeDir;
35749
- const localDir = path17.join(localBase, category);
36034
+ const localDir = path18.join(localBase, category);
35750
36035
  const remoteCategoryPath = getRemoteCategoryPath(category);
35751
36036
  const remoteFiles = await listRemoteFilesRecursive(remoteCategoryPath, githubToken);
35752
36037
  const localFiles = await listLocalFiles(localDir);
@@ -35760,7 +36045,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
35760
36045
  }
35761
36046
  const localSet = new Set(localFiles);
35762
36047
  for (const [remotePath, { sha, isFolder }] of remoteSet) {
35763
- const localPath = path17.join(localDir, remotePath);
36048
+ const localPath = path18.join(localDir, remotePath);
35764
36049
  if (isFolder) {
35765
36050
  continue;
35766
36051
  }
@@ -35795,7 +36080,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
35795
36080
  for (const localPath of localSet) {
35796
36081
  agentsTopLevels.add(localPath.split("/")[0]);
35797
36082
  }
35798
- const claudeCategoryDir = path17.join(claudeDir, category);
36083
+ const claudeCategoryDir = path18.join(claudeDir, category);
35799
36084
  const claudeRealEntries = await listClaudeRealTopLevel(claudeCategoryDir);
35800
36085
  for (const top of claudeRealEntries) {
35801
36086
  if (!remoteTopLevels.has(top))
@@ -35854,13 +36139,13 @@ async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken,
35854
36139
  return false;
35855
36140
  }
35856
36141
  const content = await response.arrayBuffer();
35857
- await import_fs_extra13.default.ensureDir(path17.dirname(targetPath));
36142
+ await import_fs_extra14.default.ensureDir(path18.dirname(targetPath));
35858
36143
  if (isTextFile(relativePath)) {
35859
36144
  const textContent = Buffer.from(content).toString("utf-8");
35860
36145
  const transformedContent = transformFileContent(textContent, claudeDir);
35861
- await import_fs_extra13.default.writeFile(targetPath, transformedContent, "utf-8");
36146
+ await import_fs_extra14.default.writeFile(targetPath, transformedContent, "utf-8");
35862
36147
  } else {
35863
- await import_fs_extra13.default.writeFile(targetPath, Buffer.from(content));
36148
+ await import_fs_extra14.default.writeFile(targetPath, Buffer.from(content));
35864
36149
  }
35865
36150
  return true;
35866
36151
  } catch {
@@ -35876,27 +36161,27 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
35876
36161
  for (const item of items) {
35877
36162
  const useAgents = isAgentCategory(item.category);
35878
36163
  const baseDir = useAgents ? agentsDir : claudeDir;
35879
- const targetPath = path17.join(baseDir, item.relativePath);
36164
+ const targetPath = path18.join(baseDir, item.relativePath);
35880
36165
  if (item.status === "migration" && useAgents) {
35881
36166
  const topName = item.name.split("/")[0];
35882
- const agentsTop = path17.join(agentsDir, item.category, topName);
35883
- const claudeTop = path17.join(claudeDir, item.category, topName);
36167
+ const agentsTop = path18.join(agentsDir, item.category, topName);
36168
+ const claudeTop = path18.join(claudeDir, item.category, topName);
35884
36169
  try {
35885
- const claudeStat = await import_fs_extra13.default.lstat(claudeTop).catch(() => null);
36170
+ const claudeStat = await import_fs_extra14.default.lstat(claudeTop).catch(() => null);
35886
36171
  if (!claudeStat || claudeStat.isSymbolicLink()) {
35887
36172
  onProgress?.(item.relativePath, "skipping (no real dir to migrate)");
35888
36173
  failed++;
35889
36174
  continue;
35890
36175
  }
35891
- const agentsExists = await import_fs_extra13.default.pathExists(agentsTop);
36176
+ const agentsExists = await import_fs_extra14.default.pathExists(agentsTop);
35892
36177
  if (agentsExists) {
35893
36178
  onProgress?.(item.relativePath, "skipping (already in .agents)");
35894
36179
  failed++;
35895
36180
  continue;
35896
36181
  }
35897
36182
  onProgress?.(item.relativePath, "moving to .agents");
35898
- await import_fs_extra13.default.ensureDir(path17.dirname(agentsTop));
35899
- await import_fs_extra13.default.move(claudeTop, agentsTop);
36183
+ await import_fs_extra14.default.ensureDir(path18.dirname(agentsTop));
36184
+ await import_fs_extra14.default.move(claudeTop, agentsTop);
35900
36185
  migrated++;
35901
36186
  touchedAgentCategories.add(item.category);
35902
36187
  } catch {
@@ -35906,8 +36191,8 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
35906
36191
  }
35907
36192
  if (useAgents) {
35908
36193
  const topName = item.name.split("/")[0];
35909
- const claudeTop = path17.join(claudeDir, item.category, topName);
35910
- const claudeTopStat = await import_fs_extra13.default.lstat(claudeTop).catch(() => null);
36194
+ const claudeTop = path18.join(claudeDir, item.category, topName);
36195
+ const claudeTopStat = await import_fs_extra14.default.lstat(claudeTop).catch(() => null);
35911
36196
  if (claudeTopStat && !claudeTopStat.isSymbolicLink()) {
35912
36197
  onProgress?.(item.relativePath, "skipping (real dir in .claude)");
35913
36198
  failed++;
@@ -35917,7 +36202,7 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
35917
36202
  if (item.status === "deleted") {
35918
36203
  onProgress?.(item.relativePath, "deleting");
35919
36204
  try {
35920
- await import_fs_extra13.default.remove(targetPath);
36205
+ await import_fs_extra14.default.remove(targetPath);
35921
36206
  deleted++;
35922
36207
  if (useAgents)
35923
36208
  touchedAgentCategories.add(item.category);
@@ -36198,7 +36483,7 @@ async function proSyncCommand(options = {}) {
36198
36483
  M2.message(source_default.yellow(` ✓ Update ${toUpdate} file${toUpdate > 1 ? "s" : ""}`));
36199
36484
  if (toMigrate > 0)
36200
36485
  M2.message(source_default.blue(` ✓ Move ${toMigrate} skill${toMigrate > 1 ? "s" : ""} from .claude to .agents`));
36201
- M2.message(source_default.gray(` ✓ Backup current config to ~/.config/aiblueprint/backup/`));
36486
+ M2.message(source_default.gray(` ✓ Backup current config to ~/.aiblueprint/backups/`));
36202
36487
  M2.message("");
36203
36488
  const confirmResult = await ye({
36204
36489
  message: "Proceed with sync?",
@@ -36209,7 +36494,7 @@ async function proSyncCommand(options = {}) {
36209
36494
  process.exit(0);
36210
36495
  }
36211
36496
  spinner.start("Creating backup...");
36212
- const backupPath = await createBackup(claudeDir, agentsDir);
36497
+ const backupPath = await createConfigBackup(options, "Before syncing premium aiblueprint configuration", "sync", "aiblueprint-sync");
36213
36498
  if (backupPath) {
36214
36499
  spinner.stop(`Backup created: ${source_default.gray(backupPath)}`);
36215
36500
  } else {
@@ -36254,6 +36539,106 @@ async function proSyncCommand(options = {}) {
36254
36539
  }
36255
36540
  }
36256
36541
 
36542
+ // src/lib/backup-utils.ts
36543
+ var import_fs_extra15 = __toESM(require_lib4(), 1);
36544
+ import path19 from "path";
36545
+ import os15 from "os";
36546
+ var BACKUP_BASE_DIR = path19.join(os15.homedir(), ".config", "aiblueprint", "backup");
36547
+ function formatDate(date) {
36548
+ const pad = (n) => n.toString().padStart(2, "0");
36549
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
36550
+ }
36551
+ async function listBackups() {
36552
+ const exists = await import_fs_extra15.default.pathExists(BACKUP_BASE_DIR);
36553
+ if (!exists) {
36554
+ return [];
36555
+ }
36556
+ const entries = await import_fs_extra15.default.readdir(BACKUP_BASE_DIR, { withFileTypes: true });
36557
+ const backups = [];
36558
+ for (const entry of entries) {
36559
+ if (!entry.isDirectory())
36560
+ continue;
36561
+ const match = entry.name.match(/^(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})$/);
36562
+ if (!match)
36563
+ continue;
36564
+ const [, year, month, day, hour, minute, second] = match;
36565
+ const date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second));
36566
+ backups.push({
36567
+ name: entry.name,
36568
+ path: path19.join(BACKUP_BASE_DIR, entry.name),
36569
+ date
36570
+ });
36571
+ }
36572
+ return backups.sort((a, b3) => b3.date.getTime() - a.date.getTime());
36573
+ }
36574
+ var AGENTS_BACKUP_SUBDIR = ".agents";
36575
+ var CLAUDE_ITEMS = ["commands", "agents", "skills", "scripts", "settings.json"];
36576
+ async function copyForBackup(sourcePath, destPath) {
36577
+ await import_fs_extra15.default.copy(sourcePath, destPath, {
36578
+ overwrite: true,
36579
+ dereference: false,
36580
+ filter: async (src) => {
36581
+ try {
36582
+ const stat = await import_fs_extra15.default.lstat(src);
36583
+ return !stat.isSymbolicLink();
36584
+ } catch {
36585
+ return true;
36586
+ }
36587
+ }
36588
+ });
36589
+ }
36590
+ async function hasMeaningfulContent(dir) {
36591
+ if (!await import_fs_extra15.default.pathExists(dir))
36592
+ return false;
36593
+ const files = await import_fs_extra15.default.readdir(dir);
36594
+ return files.some((f) => f !== ".DS_Store");
36595
+ }
36596
+ async function loadBackup(backupPath, claudeDir, agentsDir) {
36597
+ const exists = await import_fs_extra15.default.pathExists(backupPath);
36598
+ if (!exists) {
36599
+ throw new Error(`Backup not found: ${backupPath}`);
36600
+ }
36601
+ await import_fs_extra15.default.ensureDir(claudeDir);
36602
+ for (const item of CLAUDE_ITEMS) {
36603
+ const sourcePath = path19.join(backupPath, item);
36604
+ const destPath = path19.join(claudeDir, item);
36605
+ if (await import_fs_extra15.default.pathExists(sourcePath)) {
36606
+ await copyForBackup(sourcePath, destPath);
36607
+ }
36608
+ }
36609
+ if (agentsDir) {
36610
+ const agentsBackupPath = path19.join(backupPath, AGENTS_BACKUP_SUBDIR);
36611
+ if (await import_fs_extra15.default.pathExists(agentsBackupPath)) {
36612
+ await import_fs_extra15.default.ensureDir(agentsDir);
36613
+ await copyForBackup(agentsBackupPath, agentsDir);
36614
+ }
36615
+ }
36616
+ }
36617
+ async function createBackup(claudeDir, agentsDir) {
36618
+ const claudeHasContent = await hasMeaningfulContent(claudeDir);
36619
+ const agentsHasContent = agentsDir ? await hasMeaningfulContent(agentsDir) : false;
36620
+ if (!claudeHasContent && !agentsHasContent) {
36621
+ return null;
36622
+ }
36623
+ const timestamp2 = formatDate(new Date);
36624
+ const backupPath = path19.join(BACKUP_BASE_DIR, timestamp2);
36625
+ await import_fs_extra15.default.ensureDir(backupPath);
36626
+ if (claudeHasContent) {
36627
+ for (const item of CLAUDE_ITEMS) {
36628
+ const sourcePath = path19.join(claudeDir, item);
36629
+ const destPath = path19.join(backupPath, item);
36630
+ if (await import_fs_extra15.default.pathExists(sourcePath)) {
36631
+ await copyForBackup(sourcePath, destPath);
36632
+ }
36633
+ }
36634
+ }
36635
+ if (agentsHasContent && agentsDir) {
36636
+ const destPath = path19.join(backupPath, AGENTS_BACKUP_SUBDIR);
36637
+ await copyForBackup(agentsDir, destPath);
36638
+ }
36639
+ return backupPath;
36640
+ }
36641
+
36257
36642
  // src/commands/backup.ts
36258
36643
  function formatBackupDate(date) {
36259
36644
  const now = new Date;
@@ -36329,20 +36714,116 @@ async function backupLoadCommand(options = {}) {
36329
36714
  }
36330
36715
  }
36331
36716
 
36717
+ // src/commands/configs.ts
36718
+ function formatDate2(iso) {
36719
+ const date = new Date(iso);
36720
+ if (Number.isNaN(date.getTime()))
36721
+ return "unknown date";
36722
+ return date.toLocaleString();
36723
+ }
36724
+ function formatFolders(folders) {
36725
+ return folders.length > 0 ? folders.join(", ") : "unknown folders";
36726
+ }
36727
+ function printSnapshots(title, snapshots) {
36728
+ console.log(source_default.blue(title));
36729
+ if (snapshots.length === 0) {
36730
+ console.log(source_default.gray("No entries found."));
36731
+ return;
36732
+ }
36733
+ for (const snapshot of snapshots) {
36734
+ console.log(`${source_default.cyan(snapshot.name)} ${source_default.gray(formatDate2(snapshot.metadata.createdAt))}`);
36735
+ console.log(source_default.gray(` reason: ${snapshot.metadata.reason}`));
36736
+ console.log(source_default.gray(` trigger: ${snapshot.metadata.trigger}`));
36737
+ console.log(source_default.gray(` folders: ${formatFolders(snapshot.metadata.folders)}`));
36738
+ console.log(source_default.gray(` path: ${snapshot.path}`));
36739
+ }
36740
+ }
36741
+ async function configsSaveCommand(name, options = {}) {
36742
+ try {
36743
+ const snapshotPath = await saveNamedConfig(name, options);
36744
+ console.log(source_default.green(`Saved config "${name}"`));
36745
+ console.log(source_default.gray(snapshotPath));
36746
+ } catch (error) {
36747
+ console.error(source_default.red(error instanceof Error ? error.message : String(error)));
36748
+ process.exit(1);
36749
+ }
36750
+ }
36751
+ async function configsLoadCommand(name, options = {}) {
36752
+ try {
36753
+ const result = await loadNamedConfig(name, options);
36754
+ console.log(source_default.green(`Loaded config "${name}"`));
36755
+ if (result.backupPath) {
36756
+ console.log(source_default.gray(`Previous config backed up to ${result.backupPath}`));
36757
+ }
36758
+ console.log(source_default.gray(`Restored: ${formatFolders(result.restored)}`));
36759
+ } catch (error) {
36760
+ console.error(source_default.red(error instanceof Error ? error.message : String(error)));
36761
+ process.exit(1);
36762
+ }
36763
+ }
36764
+ async function configsUndoCommand(options = {}) {
36765
+ try {
36766
+ const result = await undoLastLoad(options);
36767
+ console.log(source_default.green(`Undid last config load using backup "${result.backupName}"`));
36768
+ if (result.backupPath) {
36769
+ console.log(source_default.gray(`Current config backed up to ${result.backupPath}`));
36770
+ }
36771
+ console.log(source_default.gray(`Restored: ${formatFolders(result.restored)}`));
36772
+ } catch (error) {
36773
+ console.error(source_default.red(error instanceof Error ? error.message : String(error)));
36774
+ process.exit(1);
36775
+ }
36776
+ }
36777
+ async function configsListCommand(options = {}) {
36778
+ const configs = await listSavedConfigs(options);
36779
+ printSnapshots("Saved configs", configs);
36780
+ }
36781
+ async function configsBackupsListCommand(options = {}) {
36782
+ const backups = await listConfigBackups(options);
36783
+ printSnapshots("Config backups", backups);
36784
+ }
36785
+ async function configsBackupsLoadCommand(name, options = {}) {
36786
+ try {
36787
+ const result = await loadBackupSnapshot(name, options);
36788
+ console.log(source_default.green(`Loaded backup "${name}"`));
36789
+ if (result.backupPath) {
36790
+ console.log(source_default.gray(`Previous config backed up to ${result.backupPath}`));
36791
+ }
36792
+ console.log(source_default.gray(`Restored: ${formatFolders(result.restored)}`));
36793
+ } catch (error) {
36794
+ console.error(source_default.red(error instanceof Error ? error.message : String(error)));
36795
+ process.exit(1);
36796
+ }
36797
+ }
36798
+ async function configsBackupsCreateCommand(reason, options = {}) {
36799
+ try {
36800
+ const backupPath = await createConfigBackup(options, reason ?? "Manual backup from configs backups create", "manual-backup", "manual");
36801
+ if (!backupPath) {
36802
+ console.log(source_default.gray("No .claude, .codex, or .agents configuration found to backup."));
36803
+ return;
36804
+ }
36805
+ console.log(source_default.green("Backup created"));
36806
+ console.log(source_default.gray(backupPath));
36807
+ } catch (error) {
36808
+ console.error(source_default.red(error instanceof Error ? error.message : String(error)));
36809
+ process.exit(1);
36810
+ }
36811
+ }
36812
+
36332
36813
  // src/commands/openclaw-pro.ts
36333
36814
  import os18 from "os";
36334
- import path20 from "path";
36815
+ import path22 from "path";
36335
36816
 
36336
36817
  // src/lib/openclaw-installer.ts
36337
- var import_fs_extra14 = __toESM(require_lib4(), 1);
36818
+ var import_fs_extra16 = __toESM(require_lib4(), 1);
36338
36819
  import os16 from "os";
36339
- import path18 from "path";
36820
+ import path20 from "path";
36340
36821
  import { exec as exec4 } from "child_process";
36341
36822
  import { promisify as promisify3 } from "util";
36342
36823
  var execAsync3 = promisify3(exec4);
36343
36824
  var OPENCLAW_PRO_REPO = "Melvynx/openclawpro";
36344
36825
  function getCacheRepoDir2() {
36345
- return path18.join(os16.homedir(), ".config", "openclaw", "pro-repos", "openclawpro");
36826
+ return path20.join(os16.homedir(), ".config", "openclaw", "pro-repos", "openclawpro");
36346
36827
  }
36347
36828
  async function execGitWithAuth2(command, token, repoUrl, cwd) {
36348
36829
  const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
@@ -36356,33 +36837,33 @@ async function execGitWithAuth2(command, token, repoUrl, cwd) {
36356
36837
  async function cloneOrUpdateRepo2(token) {
36357
36838
  const cacheDir = getCacheRepoDir2();
36358
36839
  const repoUrl = `https://github.com/${OPENCLAW_PRO_REPO}.git`;
36359
- if (await import_fs_extra14.default.pathExists(path18.join(cacheDir, ".git"))) {
36840
+ if (await import_fs_extra16.default.pathExists(path20.join(cacheDir, ".git"))) {
36360
36841
  try {
36361
36842
  await execGitWithAuth2("pull", token, repoUrl, cacheDir);
36362
36843
  } catch (error) {
36363
- await import_fs_extra14.default.remove(cacheDir);
36364
- await import_fs_extra14.default.ensureDir(path18.dirname(cacheDir));
36844
+ await import_fs_extra16.default.remove(cacheDir);
36845
+ await import_fs_extra16.default.ensureDir(path20.dirname(cacheDir));
36365
36846
  await execGitWithAuth2(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
36366
36847
  }
36367
36848
  } else {
36368
- await import_fs_extra14.default.ensureDir(path18.dirname(cacheDir));
36849
+ await import_fs_extra16.default.ensureDir(path20.dirname(cacheDir));
36369
36850
  await execGitWithAuth2(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
36370
36851
  }
36371
- return path18.join(cacheDir, "openclaw-config");
36852
+ return path20.join(cacheDir, "openclaw-config");
36372
36853
  }
36373
36854
  async function copyConfigFromCache2(cacheConfigDir, targetDir, onProgress) {
36374
36855
  const walk = async (dir, baseDir = dir) => {
36375
- const entries = await import_fs_extra14.default.readdir(dir, { withFileTypes: true });
36856
+ const entries = await import_fs_extra16.default.readdir(dir, { withFileTypes: true });
36376
36857
  for (const entry of entries) {
36377
- const sourcePath = path18.join(dir, entry.name);
36378
- const relativePath = path18.relative(baseDir, sourcePath);
36379
- const targetPath = path18.join(targetDir, relativePath);
36858
+ const sourcePath = path20.join(dir, entry.name);
36859
+ const relativePath = path20.relative(baseDir, sourcePath);
36860
+ const targetPath = path20.join(targetDir, relativePath);
36380
36861
  if (entry.isDirectory()) {
36381
- await import_fs_extra14.default.ensureDir(targetPath);
36862
+ await import_fs_extra16.default.ensureDir(targetPath);
36382
36863
  onProgress?.(relativePath, "directory");
36383
36864
  await walk(sourcePath, baseDir);
36384
36865
  } else {
36385
- await import_fs_extra14.default.copy(sourcePath, targetPath, { overwrite: true });
36866
+ await import_fs_extra16.default.copy(sourcePath, targetPath, { overwrite: true });
36386
36867
  onProgress?.(relativePath, "file");
36387
36868
  }
36388
36869
  }
@@ -36391,7 +36872,7 @@ async function copyConfigFromCache2(cacheConfigDir, targetDir, onProgress) {
36391
36872
  }
36392
36873
  async function installOpenclawProConfigs(options) {
36393
36874
  const { githubToken, openclawFolder, onProgress } = options;
36394
- const targetFolder = openclawFolder || path18.join(os16.homedir(), ".openclaw");
36875
+ const targetFolder = openclawFolder || path20.join(os16.homedir(), ".openclaw");
36395
36876
  try {
36396
36877
  const cacheConfigDir = await cloneOrUpdateRepo2(githubToken);
36397
36878
  await copyConfigFromCache2(cacheConfigDir, targetFolder, onProgress);
@@ -36402,28 +36883,28 @@ async function installOpenclawProConfigs(options) {
36402
36883
  }
36403
36884
 
36404
36885
  // src/lib/openclaw-token-storage.ts
36405
- var import_fs_extra15 = __toESM(require_lib4(), 1);
36886
+ var import_fs_extra17 = __toESM(require_lib4(), 1);
36406
36887
  import os17 from "os";
36407
- import path19 from "path";
36888
+ import path21 from "path";
36408
36889
  function getConfigDir2() {
36409
36890
  const platform = os17.platform();
36410
36891
  if (platform === "win32") {
36411
- return path19.join(process.env.APPDATA || os17.homedir(), "openclaw");
36892
+ return path21.join(process.env.APPDATA || os17.homedir(), "openclaw");
36412
36893
  }
36413
- return path19.join(os17.homedir(), ".config", "openclaw");
36894
+ return path21.join(os17.homedir(), ".config", "openclaw");
36414
36895
  }
36415
36896
  function getTokenPath() {
36416
- return path19.join(getConfigDir2(), "token.txt");
36897
+ return path21.join(getConfigDir2(), "token.txt");
36417
36898
  }
36418
36899
  async function saveOpenclawToken(githubToken) {
36419
36900
  const configDir = getConfigDir2();
36420
- await import_fs_extra15.default.ensureDir(configDir);
36421
- await import_fs_extra15.default.writeFile(getTokenPath(), githubToken, { mode: 384 });
36901
+ await import_fs_extra17.default.ensureDir(configDir);
36902
+ await import_fs_extra17.default.writeFile(getTokenPath(), githubToken, { mode: 384 });
36422
36903
  }
36423
36904
  async function getOpenclawToken() {
36424
36905
  const tokenPath = getTokenPath();
36425
- if (await import_fs_extra15.default.pathExists(tokenPath)) {
36426
- const token = await import_fs_extra15.default.readFile(tokenPath, "utf8");
36906
+ if (await import_fs_extra17.default.pathExists(tokenPath)) {
36907
+ const token = await import_fs_extra17.default.readFile(tokenPath, "utf8");
36427
36908
  return token.trim();
36428
36909
  }
36429
36910
  return null;
@@ -36436,7 +36917,7 @@ function getOpenclawTokenInfo() {
36436
36917
  }
36437
36918
 
36438
36919
  // src/commands/openclaw-pro.ts
36439
- var import_fs_extra16 = __toESM(require_lib4(), 1);
36920
+ var import_fs_extra18 = __toESM(require_lib4(), 1);
36440
36921
  var API_URL2 = "https://codeline.app/api/products";
36441
36922
  var OPENCLAW_PRODUCT_ID = "prd_t2GRwX3aH1";
36442
36923
  var CLAUDE_CODE_TOOLS_INSTRUCTIONS = `
@@ -36543,7 +37024,7 @@ async function openclawProSetupCommand(options = {}) {
36543
37024
  Se(source_default.red("❌ Not activated"));
36544
37025
  process.exit(1);
36545
37026
  }
36546
- const openclawDir = options.folder ? path20.resolve(options.folder) : path20.join(os18.homedir(), ".openclaw");
37027
+ const openclawDir = options.folder ? path22.resolve(options.folder) : path22.join(os18.homedir(), ".openclaw");
36547
37028
  const spinner = Y2();
36548
37029
  const onProgress = (file, type) => {
36549
37030
  spinner.message(`Installing: ${source_default.cyan(file)} ${source_default.gray(`(${type})`)}`);
@@ -36556,23 +37037,23 @@ async function openclawProSetupCommand(options = {}) {
36556
37037
  });
36557
37038
  spinner.stop("OpenClaw Pro configurations installed");
36558
37039
  let skillCount = 0;
36559
- const skillsDir = path20.join(openclawDir, "skills");
36560
- if (await import_fs_extra16.default.pathExists(skillsDir)) {
36561
- const items = await import_fs_extra16.default.readdir(skillsDir);
37040
+ const skillsDir = path22.join(openclawDir, "skills");
37041
+ if (await import_fs_extra18.default.pathExists(skillsDir)) {
37042
+ const items = await import_fs_extra18.default.readdir(skillsDir);
36562
37043
  const dirs = await Promise.all(items.map(async (item) => {
36563
- const stat = await import_fs_extra16.default.stat(path20.join(skillsDir, item));
37044
+ const stat = await import_fs_extra18.default.stat(path22.join(skillsDir, item));
36564
37045
  return stat.isDirectory();
36565
37046
  }));
36566
37047
  skillCount = dirs.filter(Boolean).length;
36567
37048
  }
36568
37049
  spinner.start("Setting up workspace TOOLS.md...");
36569
- const workspaceDir = path20.join(openclawDir, "workspace");
36570
- const toolsPath = path20.join(workspaceDir, "TOOLS.md");
36571
- await import_fs_extra16.default.ensureDir(workspaceDir);
36572
- if (await import_fs_extra16.default.pathExists(toolsPath)) {
36573
- const existingContent = await import_fs_extra16.default.readFile(toolsPath, "utf-8");
37050
+ const workspaceDir = path22.join(openclawDir, "workspace");
37051
+ const toolsPath = path22.join(workspaceDir, "TOOLS.md");
37052
+ await import_fs_extra18.default.ensureDir(workspaceDir);
37053
+ if (await import_fs_extra18.default.pathExists(toolsPath)) {
37054
+ const existingContent = await import_fs_extra18.default.readFile(toolsPath, "utf-8");
36574
37055
  if (!existingContent.includes("Claude Code CLI")) {
36575
- await import_fs_extra16.default.appendFile(toolsPath, `
37056
+ await import_fs_extra18.default.appendFile(toolsPath, `
36576
37057
 
36577
37058
  ` + CLAUDE_CODE_TOOLS_INSTRUCTIONS);
36578
37059
  spinner.stop("TOOLS.md updated with Claude Code instructions");
@@ -36586,7 +37067,7 @@ Skills define _how_ tools work. This file is for _your_ specifics — the stuff
36586
37067
 
36587
37068
  ${CLAUDE_CODE_TOOLS_INSTRUCTIONS}
36588
37069
  `;
36589
- await import_fs_extra16.default.writeFile(toolsPath, defaultToolsMd);
37070
+ await import_fs_extra18.default.writeFile(toolsPath, defaultToolsMd);
36590
37071
  spinner.stop("TOOLS.md created with Claude Code instructions");
36591
37072
  }
36592
37073
  spinner.start("Creating claude-run wrapper...");
@@ -36597,9 +37078,9 @@ ${CLAUDE_CODE_TOOLS_INSTRUCTIONS}
36597
37078
  script -q -c "claude $*" /dev/null
36598
37079
  `;
36599
37080
  const binDir = "/usr/local/bin";
36600
- const wrapperPath = path20.join(binDir, "claude-run");
37081
+ const wrapperPath = path22.join(binDir, "claude-run");
36601
37082
  try {
36602
- await import_fs_extra16.default.writeFile(wrapperPath, claudeRunWrapper, { mode: 493 });
37083
+ await import_fs_extra18.default.writeFile(wrapperPath, claudeRunWrapper, { mode: 493 });
36603
37084
  spinner.stop("claude-run wrapper created");
36604
37085
  } catch {
36605
37086
  spinner.stop("claude-run wrapper skipped (no write access to /usr/local/bin)");
@@ -36648,12 +37129,12 @@ async function openclawProUpdateCommand(options = {}) {
36648
37129
  }
36649
37130
 
36650
37131
  // src/commands/dynamic-scripts.ts
36651
- import path23 from "path";
37132
+ import path25 from "path";
36652
37133
  import { homedir } from "os";
36653
37134
 
36654
37135
  // src/lib/script-parser.ts
36655
- var import_fs_extra17 = __toESM(require_lib4(), 1);
36656
- import path21 from "path";
37136
+ var import_fs_extra19 = __toESM(require_lib4(), 1);
37137
+ import path23 from "path";
36657
37138
  var EXCLUDED_SCRIPTS = ["test", "lint", "format", "start"];
36658
37139
  var EXCLUDED_SUFFIXES = [":test", ":lint", ":test-fixtures", ":start"];
36659
37140
  function shouldIncludeScript(scriptName) {
@@ -36664,12 +37145,12 @@ function shouldIncludeScript(scriptName) {
36664
37145
  return true;
36665
37146
  }
36666
37147
  async function readScriptsPackageJson(claudeDir) {
36667
- const packageJsonPath = path21.join(claudeDir, "scripts", "package.json");
37148
+ const packageJsonPath = path23.join(claudeDir, "scripts", "package.json");
36668
37149
  try {
36669
- if (!await import_fs_extra17.default.pathExists(packageJsonPath)) {
37150
+ if (!await import_fs_extra19.default.pathExists(packageJsonPath)) {
36670
37151
  return null;
36671
37152
  }
36672
- const content = await import_fs_extra17.default.readFile(packageJsonPath, "utf-8");
37153
+ const content = await import_fs_extra19.default.readFile(packageJsonPath, "utf-8");
36673
37154
  const parsed = JSON.parse(content);
36674
37155
  return parsed.scripts || null;
36675
37156
  } catch (error) {
@@ -36713,10 +37194,10 @@ function groupScriptsByPrefix(commands) {
36713
37194
  }
36714
37195
 
36715
37196
  // src/commands/script-runner.ts
36716
- var import_fs_extra18 = __toESM(require_lib4(), 1);
37197
+ var import_fs_extra20 = __toESM(require_lib4(), 1);
36717
37198
  import { spawn as spawn2 } from "child_process";
36718
37199
  import { execSync as execSync4 } from "child_process";
36719
- import path22 from "path";
37200
+ import path24 from "path";
36720
37201
  import os19 from "os";
36721
37202
  function checkCommand2(cmd) {
36722
37203
  try {
@@ -36746,18 +37227,18 @@ async function executeScript(scriptName, claudeDir) {
36746
37227
  console.error(source_default.red("Bun is not installed. Install with: npm install -g bun"));
36747
37228
  return 1;
36748
37229
  }
36749
- const scriptsDir = path22.join(claudeDir, "scripts");
36750
- if (!await import_fs_extra18.default.pathExists(scriptsDir)) {
37230
+ const scriptsDir = path24.join(claudeDir, "scripts");
37231
+ if (!await import_fs_extra20.default.pathExists(scriptsDir)) {
36751
37232
  console.error(source_default.red(`Scripts directory not found at ${scriptsDir}`));
36752
37233
  console.log(source_default.gray("Run: aiblueprint agents setup"));
36753
37234
  return 1;
36754
37235
  }
36755
- const packageJsonPath = path22.join(scriptsDir, "package.json");
36756
- if (!await import_fs_extra18.default.pathExists(packageJsonPath)) {
37236
+ const packageJsonPath = path24.join(scriptsDir, "package.json");
37237
+ if (!await import_fs_extra20.default.pathExists(packageJsonPath)) {
36757
37238
  console.error(source_default.red(`package.json not found in ${scriptsDir}`));
36758
37239
  return 1;
36759
37240
  }
36760
- const packageJson = await import_fs_extra18.default.readJson(packageJsonPath);
37241
+ const packageJson = await import_fs_extra20.default.readJson(packageJsonPath);
36761
37242
  if (!packageJson.scripts || !packageJson.scripts[scriptName]) {
36762
37243
  console.error(source_default.red(`Script "${scriptName}" not found in package.json`));
36763
37244
  return 1;
@@ -36780,7 +37261,7 @@ async function executeScript(scriptName, claudeDir) {
36780
37261
 
36781
37262
  // src/commands/dynamic-scripts.ts
36782
37263
  function getClaudeDir(parentOptions) {
36783
- return parentOptions.claudeCodeFolder || parentOptions.folder ? path23.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path23.join(homedir(), ".claude");
37264
+ return parentOptions.claudeCodeFolder || parentOptions.folder ? path25.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path25.join(homedir(), ".claude");
36784
37265
  }
36785
37266
  async function registerDynamicScriptCommands(claudeCodeCmd, claudeDir) {
36786
37267
  const scripts = await readScriptsPackageJson(claudeDir);
@@ -36886,12 +37367,81 @@ function registerAgentsCommands(cmd) {
36886
37367
  });
36887
37368
  });
36888
37369
  }
37370
+ function addConfigFolderOptions(cmd) {
37371
+ return cmd.option("-f, --folder <path>", "Root folder that contains .claude/, .codex/, .agents/ (default: $HOME)").option("--claudeCodeFolder <path>", "Override Claude Code folder (default: {folder}/.claude)").option("--codexFolder <path>", "Override Codex folder (default: {folder}/.codex)").option("--agentsFolder <path>", "Override shared agents folder (default: {folder}/.agents)");
37372
+ }
36889
37373
  var agentsCmd = program2.command("agents").description("AI coding configuration commands");
36890
37374
  registerAgentsCommands(agentsCmd);
36891
37375
  var aiCodingCmd = program2.command("ai-coding").description("Legacy alias for agents configuration commands");
36892
37376
  registerAgentsCommands(aiCodingCmd);
36893
37377
  var claudeCodeCmd = program2.command("claude-code").description("Legacy alias for agents configuration commands");
36894
37378
  registerAgentsCommands(claudeCodeCmd);
37379
+ var configsCmd = addConfigFolderOptions(program2.command("configs").description("Save, load, undo, and inspect .claude/.codex/.agents configurations"));
37380
+ configsCmd.command("save <name>").description("Save the current .claude, .codex, and .agents folders as a named config").option("--force", "Overwrite an existing saved config with the same name").action((name, options, command) => {
37381
+ const parentOptions = command.parent.opts();
37382
+ configsSaveCommand(name, {
37383
+ folder: parentOptions.folder,
37384
+ claudeCodeFolder: parentOptions.claudeCodeFolder,
37385
+ codexFolder: parentOptions.codexFolder,
37386
+ agentsFolder: parentOptions.agentsFolder,
37387
+ force: options.force
37388
+ });
37389
+ });
37390
+ configsCmd.command("load <name>").description("Load a named config and backup the current folders first").action((name, options, command) => {
37391
+ const parentOptions = command.parent.opts();
37392
+ configsLoadCommand(name, {
37393
+ folder: parentOptions.folder,
37394
+ claudeCodeFolder: parentOptions.claudeCodeFolder,
37395
+ codexFolder: parentOptions.codexFolder,
37396
+ agentsFolder: parentOptions.agentsFolder
37397
+ });
37398
+ });
37399
+ configsCmd.command("undo").description("Undo the most recent configs load by restoring its automatic backup").action((options, command) => {
37400
+ const parentOptions = command.parent.opts();
37401
+ configsUndoCommand({
37402
+ folder: parentOptions.folder,
37403
+ claudeCodeFolder: parentOptions.claudeCodeFolder,
37404
+ codexFolder: parentOptions.codexFolder,
37405
+ agentsFolder: parentOptions.agentsFolder
37406
+ });
37407
+ });
37408
+ configsCmd.command("list").description("List saved named configs").action((options, command) => {
37409
+ const parentOptions = command.parent.opts();
37410
+ configsListCommand({
37411
+ folder: parentOptions.folder,
37412
+ claudeCodeFolder: parentOptions.claudeCodeFolder,
37413
+ codexFolder: parentOptions.codexFolder,
37414
+ agentsFolder: parentOptions.agentsFolder
37415
+ });
37416
+ });
37417
+ var configsBackupsCmd = configsCmd.command("backups").description("Manage automatic config backups");
37418
+ configsBackupsCmd.command("list").description("List automatic backups with reasons").action((options, command) => {
37419
+ const parentOptions = command.parent.parent.opts();
37420
+ configsBackupsListCommand({
37421
+ folder: parentOptions.folder,
37422
+ claudeCodeFolder: parentOptions.claudeCodeFolder,
37423
+ codexFolder: parentOptions.codexFolder,
37424
+ agentsFolder: parentOptions.agentsFolder
37425
+ });
37426
+ });
37427
+ configsBackupsCmd.command("load <name>").description("Load a backup and backup the current folders first").action((name, options, command) => {
37428
+ const parentOptions = command.parent.parent.opts();
37429
+ configsBackupsLoadCommand(name, {
37430
+ folder: parentOptions.folder,
37431
+ claudeCodeFolder: parentOptions.claudeCodeFolder,
37432
+ codexFolder: parentOptions.codexFolder,
37433
+ agentsFolder: parentOptions.agentsFolder
37434
+ });
37435
+ });
37436
+ configsBackupsCmd.command("create [reason]").description("Create a manual backup of the current config folders").action((reason, options, command) => {
37437
+ const parentOptions = command.parent.parent.opts();
37438
+ configsBackupsCreateCommand(reason, {
37439
+ folder: parentOptions.folder,
37440
+ claudeCodeFolder: parentOptions.claudeCodeFolder,
37441
+ codexFolder: parentOptions.codexFolder,
37442
+ agentsFolder: parentOptions.agentsFolder
37443
+ });
37444
+ });
36895
37445
  var openclawCmd = program2.command("openclaw").description("OpenClaw configuration commands").option("-f, --folder <path>", "Specify custom OpenClaw folder path (default: ~/.openclaw)");
36896
37446
  var openclawProCmd = openclawCmd.command("pro").description("Manage OpenClaw Pro features");
36897
37447
  openclawProCmd.command("activate [token]").description("Activate OpenClaw Pro with your access token").action((token) => {