aiblueprint-cli 1.4.63 → 1.4.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +7 -1
  2. package/dist/cli.js +905 -355
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -33628,46 +33628,6 @@ async function mergeCodexConfigFile(sourceConfigPath, codexDir) {
33628
33628
  // src/lib/configs-store.ts
33629
33629
  var import_fs_extra7 = __toESM(require_lib4(), 1);
33630
33630
  import path11 from "path";
33631
- var COMMON_EXCLUDED_NAMES = new Set([
33632
- ".git",
33633
- ".DS_Store",
33634
- "node_modules"
33635
- ]);
33636
- var EXCLUDED_RUNTIME_PATHS = {
33637
- ".claude": new Set([
33638
- "backups",
33639
- "cache",
33640
- "debug",
33641
- "file-history",
33642
- "logs",
33643
- "output",
33644
- "paste-cache",
33645
- "plugins/cache",
33646
- "projects",
33647
- "session-env",
33648
- "sessions",
33649
- "stats-cache.json",
33650
- "security.log"
33651
- ]),
33652
- ".codex": new Set([
33653
- "archived_sessions",
33654
- "browser/sessions",
33655
- "cache",
33656
- "log",
33657
- "logs_2.sqlite",
33658
- "logs_2.sqlite-shm",
33659
- "logs_2.sqlite-wal",
33660
- "models_cache.json",
33661
- "plugins/cache",
33662
- "sessions",
33663
- "vendor_imports/skills-curated-cache.json"
33664
- ]),
33665
- ".agents": new Set([
33666
- "cache",
33667
- "logs",
33668
- "sessions"
33669
- ])
33670
- };
33671
33631
  function getConfigStorePaths(rootDir) {
33672
33632
  const baseDir = path11.join(rootDir, ".aiblueprint");
33673
33633
  return {
@@ -33714,37 +33674,10 @@ async function hasContent(folderPath) {
33714
33674
  const entries = await import_fs_extra7.default.readdir(folderPath);
33715
33675
  return entries.some((entry) => entry !== ".DS_Store");
33716
33676
  }
33717
- function normalizeRelativePath(relativePath) {
33718
- return relativePath.split(path11.sep).join("/");
33719
- }
33720
- function shouldCopyManagedPath(folderName, sourceRoot, sourcePath) {
33721
- const basename = path11.basename(sourcePath);
33722
- if (COMMON_EXCLUDED_NAMES.has(basename))
33723
- return false;
33724
- const relativePath = normalizeRelativePath(path11.relative(sourceRoot, sourcePath));
33725
- if (!relativePath)
33726
- return true;
33727
- const excludedPaths = EXCLUDED_RUNTIME_PATHS[folderName];
33728
- if (excludedPaths.has(relativePath))
33729
- return false;
33730
- for (const excludedPath of excludedPaths) {
33731
- if (relativePath.startsWith(`${excludedPath}/`))
33732
- return false;
33733
- }
33734
- return true;
33735
- }
33736
- async function copyManagedFolder(name, source, destination) {
33677
+ async function copyManagedFolder(source, destination) {
33737
33678
  await import_fs_extra7.default.copy(source, destination, {
33738
33679
  overwrite: true,
33739
- dereference: false,
33740
- filter: async (src) => {
33741
- try {
33742
- const stat = await import_fs_extra7.default.lstat(src);
33743
- return !stat.isSymbolicLink() && shouldCopyManagedPath(name, source, src);
33744
- } catch {
33745
- return true;
33746
- }
33747
- }
33680
+ dereference: false
33748
33681
  });
33749
33682
  }
33750
33683
  async function writeMetadata(snapshotPath, metadata) {
@@ -33776,7 +33709,7 @@ async function snapshotByCopy(snapshotPath, folders, metadata) {
33776
33709
  for (const folder of managedFolders(folders)) {
33777
33710
  if (!await hasContent(folder.path))
33778
33711
  continue;
33779
- await copyManagedFolder(folder.name, folder.path, path11.join(snapshotPath, folder.name));
33712
+ await copyManagedFolder(folder.path, path11.join(snapshotPath, folder.name));
33780
33713
  copied.push(folder.name);
33781
33714
  }
33782
33715
  if (copied.length === 0) {
@@ -33869,7 +33802,7 @@ async function restoreSnapshot(snapshotPath, folders) {
33869
33802
  if (!await import_fs_extra7.default.pathExists(source))
33870
33803
  continue;
33871
33804
  await import_fs_extra7.default.ensureDir(path11.dirname(folder.path));
33872
- await copyManagedFolder(folder.name, source, folder.path);
33805
+ await copyManagedFolder(source, folder.path);
33873
33806
  restored.push(folder.name);
33874
33807
  }
33875
33808
  return restored;
@@ -35097,13 +35030,90 @@ function getInstructionFileCandidates(options) {
35097
35030
  }
35098
35031
  ]);
35099
35032
  }
35100
- function shouldCollectEntry(category, entry) {
35101
- if (IGNORED_ENTRY_NAMES2.has(entry.name))
35102
- return false;
35103
- if (category === "skills" && entry.name === ".cursor-managed-skills-manifest.json") {
35104
- return true;
35105
- }
35106
- return entry.isFile() || entry.isDirectory() || entry.isSymbolicLink();
35033
+ function getRepositoryContainerCandidates(options) {
35034
+ const folders = resolveFolders(options);
35035
+ const cursorDir = path16.join(folders.rootDir, ".cursor");
35036
+ return uniqueByPath([
35037
+ ...getContainerCandidates(options),
35038
+ {
35039
+ category: "rules",
35040
+ label: "agents-rules",
35041
+ path: path16.join(folders.agentsDir, "rules"),
35042
+ isDestination: true
35043
+ },
35044
+ {
35045
+ category: "rules",
35046
+ label: "claude-rules",
35047
+ path: path16.join(folders.claudeDir, "rules"),
35048
+ linkWhenMissing: true
35049
+ },
35050
+ {
35051
+ category: "rules",
35052
+ label: "codex-rules",
35053
+ path: path16.join(folders.codexDir, "rules"),
35054
+ linkWhenParentExists: true
35055
+ },
35056
+ {
35057
+ category: "rules",
35058
+ label: "cursor-rules",
35059
+ path: path16.join(cursorDir, "rules"),
35060
+ linkWhenParentExists: true
35061
+ },
35062
+ {
35063
+ category: "rules",
35064
+ label: "claude-memories",
35065
+ path: path16.join(folders.claudeDir, "memories"),
35066
+ linkSource: false
35067
+ },
35068
+ {
35069
+ category: "rules",
35070
+ label: "codex-memories",
35071
+ path: path16.join(folders.codexDir, "memories"),
35072
+ linkSource: false
35073
+ },
35074
+ {
35075
+ category: "rules",
35076
+ label: "cursor-memories",
35077
+ path: path16.join(cursorDir, "memories"),
35078
+ linkSource: false
35079
+ },
35080
+ {
35081
+ category: "rules",
35082
+ label: "claude-memory",
35083
+ path: path16.join(folders.claudeDir, "memory.md"),
35084
+ linkSource: false
35085
+ },
35086
+ {
35087
+ category: "rules",
35088
+ label: "codex-memory",
35089
+ path: path16.join(folders.codexDir, "memory.md"),
35090
+ linkSource: false
35091
+ },
35092
+ {
35093
+ category: "rules",
35094
+ label: "cursor-memory",
35095
+ path: path16.join(cursorDir, "memory.md"),
35096
+ linkSource: false
35097
+ },
35098
+ {
35099
+ category: "rules",
35100
+ label: "claude-memory-uppercase",
35101
+ path: path16.join(folders.claudeDir, "MEMORY.md"),
35102
+ linkSource: false
35103
+ },
35104
+ {
35105
+ category: "rules",
35106
+ label: "codex-memory-uppercase",
35107
+ path: path16.join(folders.codexDir, "MEMORY.md"),
35108
+ linkSource: false
35109
+ },
35110
+ {
35111
+ category: "rules",
35112
+ label: "cursor-memory-uppercase",
35113
+ path: path16.join(cursorDir, "MEMORY.md"),
35114
+ linkSource: false
35115
+ }
35116
+ ]);
35107
35117
  }
35108
35118
  async function pathExistsOrSymlink(targetPath) {
35109
35119
  const stat = await import_fs_extra12.default.lstat(targetPath).catch(() => null);
@@ -35148,6 +35158,73 @@ async function hashPath(targetPath) {
35148
35158
  }
35149
35159
  return hashString(`other:${stat.mode}:${stat.size}`);
35150
35160
  }
35161
+ var TEXT_EXTENSIONS = new Set([
35162
+ ".cjs",
35163
+ ".js",
35164
+ ".json",
35165
+ ".jsonc",
35166
+ ".md",
35167
+ ".mdc",
35168
+ ".mjs",
35169
+ ".sh",
35170
+ ".toml",
35171
+ ".ts",
35172
+ ".tsx",
35173
+ ".txt",
35174
+ ".yaml",
35175
+ ".yml"
35176
+ ]);
35177
+ var PORTABLE_PATH_REPLACEMENTS = [
35178
+ [/\.claude\/skills/g, ".agents/skills"],
35179
+ [/\.codex\/skills/g, ".agents/skills"],
35180
+ [/\.cursor\/skills-cursor/g, ".agents/skills"],
35181
+ [/\.cursor\/skills/g, ".agents/skills"],
35182
+ [/\.claude\/agents/g, ".agents/agents"],
35183
+ [/\.codex\/agents/g, ".agents/agents"],
35184
+ [/\.cursor\/agents/g, ".agents/agents"],
35185
+ [/\.claude\/rules/g, ".agents/rules"],
35186
+ [/\.codex\/rules/g, ".agents/rules"],
35187
+ [/\.cursor\/rules/g, ".agents/rules"],
35188
+ [/\.claude\/memories/g, ".agents/rules"],
35189
+ [/\.codex\/memories/g, ".agents/rules"],
35190
+ [/\.cursor\/memories/g, ".agents/rules"]
35191
+ ];
35192
+ function normalizePortableText(content) {
35193
+ let normalized = content;
35194
+ for (const [pattern, replacement] of PORTABLE_PATH_REPLACEMENTS) {
35195
+ normalized = normalized.replace(pattern, replacement);
35196
+ }
35197
+ return normalized;
35198
+ }
35199
+ function isLikelyTextFile(filePath) {
35200
+ const ext = path16.extname(filePath).toLowerCase();
35201
+ if (TEXT_EXTENSIONS.has(ext))
35202
+ return true;
35203
+ return path16.basename(filePath) === "SKILL.md";
35204
+ }
35205
+ async function normalizePortableContent(targetPath) {
35206
+ const stat = await import_fs_extra12.default.lstat(targetPath).catch(() => null);
35207
+ if (!stat || stat.isSymbolicLink())
35208
+ return;
35209
+ if (stat.isDirectory()) {
35210
+ const entries = await import_fs_extra12.default.readdir(targetPath);
35211
+ for (const entry of entries) {
35212
+ if (IGNORED_ENTRY_NAMES2.has(entry))
35213
+ continue;
35214
+ await normalizePortableContent(path16.join(targetPath, entry));
35215
+ }
35216
+ return;
35217
+ }
35218
+ if (!stat.isFile() || !isLikelyTextFile(targetPath))
35219
+ return;
35220
+ const content = await import_fs_extra12.default.readFile(targetPath, "utf-8").catch(() => null);
35221
+ if (content === null || content.includes("\x00"))
35222
+ return;
35223
+ const normalized = normalizePortableText(content);
35224
+ if (normalized !== content) {
35225
+ await import_fs_extra12.default.writeFile(targetPath, normalized, "utf-8");
35226
+ }
35227
+ }
35151
35228
  function suffixFromLabel(label) {
35152
35229
  return label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "source";
35153
35230
  }
@@ -35196,7 +35273,7 @@ async function importCategoryEntries(category, candidates, destinationDir, resul
35196
35273
  if (destinationRealPath && candidateRealPath && samePath(destinationRealPath, candidateRealPath)) {
35197
35274
  continue;
35198
35275
  }
35199
- const entries = await import_fs_extra12.default.readdir(candidate.path, { withFileTypes: true }).catch(() => null);
35276
+ const entries = await collectCandidateEntries(candidate).catch(() => null);
35200
35277
  if (!entries) {
35201
35278
  result.skipped.push({
35202
35279
  category,
@@ -35206,9 +35283,9 @@ async function importCategoryEntries(category, candidates, destinationDir, resul
35206
35283
  continue;
35207
35284
  }
35208
35285
  for (const entry of entries) {
35209
- if (!shouldCollectEntry(category, entry))
35286
+ if (!shouldCollectPath(category, entry.name, entry.path))
35210
35287
  continue;
35211
- const sourcePath = path16.join(candidate.path, entry.name);
35288
+ const sourcePath = entry.path;
35212
35289
  const sourceHash = await hashPath(sourcePath);
35213
35290
  const existingName = knownHashes.get(sourceHash);
35214
35291
  if (existingName) {
@@ -35237,6 +35314,7 @@ async function importCategoryEntries(category, candidates, destinationDir, resul
35237
35314
  dereference: false,
35238
35315
  overwrite: false
35239
35316
  });
35317
+ await normalizePortableContent(targetPath);
35240
35318
  knownHashes.set(sourceHash, targetName);
35241
35319
  result.imported.push({
35242
35320
  category,
@@ -35247,6 +35325,41 @@ async function importCategoryEntries(category, candidates, destinationDir, resul
35247
35325
  }
35248
35326
  }
35249
35327
  }
35328
+ async function collectCandidateEntries(candidate) {
35329
+ const stat = await import_fs_extra12.default.lstat(candidate.path);
35330
+ if (stat.isDirectory()) {
35331
+ const entries = await import_fs_extra12.default.readdir(candidate.path, { withFileTypes: true });
35332
+ return entries.map((entry) => ({
35333
+ name: entry.name,
35334
+ path: path16.join(candidate.path, entry.name)
35335
+ }));
35336
+ }
35337
+ if (stat.isSymbolicLink()) {
35338
+ const targetStat = await import_fs_extra12.default.stat(candidate.path).catch(() => null);
35339
+ if (targetStat?.isDirectory()) {
35340
+ const entries = await import_fs_extra12.default.readdir(candidate.path, { withFileTypes: true });
35341
+ return entries.map((entry) => ({
35342
+ name: entry.name,
35343
+ path: path16.join(candidate.path, entry.name)
35344
+ }));
35345
+ }
35346
+ }
35347
+ return [{
35348
+ name: path16.basename(candidate.path),
35349
+ path: candidate.path
35350
+ }];
35351
+ }
35352
+ async function shouldCollectPath(category, name, sourcePath) {
35353
+ if (IGNORED_ENTRY_NAMES2.has(name))
35354
+ return false;
35355
+ if (category === "skills" && name === ".cursor-managed-skills-manifest.json") {
35356
+ return true;
35357
+ }
35358
+ const stat = await import_fs_extra12.default.lstat(sourcePath).catch(() => null);
35359
+ if (!stat)
35360
+ return false;
35361
+ return stat.isFile() || stat.isDirectory() || stat.isSymbolicLink();
35362
+ }
35250
35363
  function timestamp2(date = new Date) {
35251
35364
  return date.toISOString().replace(/\.\d{3}Z$/, "").replace(/[:T]/g, "-");
35252
35365
  }
@@ -35291,6 +35404,9 @@ async function shouldLinkMissingContainer(candidate) {
35291
35404
  return import_fs_extra12.default.pathExists(path16.dirname(candidate.path));
35292
35405
  }
35293
35406
  async function linkContainer(candidate, destinationDir, result) {
35407
+ if (candidate.linkSource === false) {
35408
+ return;
35409
+ }
35294
35410
  if (candidate.isDestination || samePath(candidate.path, destinationDir)) {
35295
35411
  return;
35296
35412
  }
@@ -35447,29 +35563,176 @@ async function linkInstructionFile(candidate, destinationPath, result) {
35447
35563
  movedToBackup: backupTarget
35448
35564
  });
35449
35565
  }
35566
+ var RULES_INDEX_START = "<!-- AIBLUEPRINT:RULES:START -->";
35567
+ var RULES_INDEX_END = "<!-- AIBLUEPRINT:RULES:END -->";
35568
+ function titleFromRulePath(rulePath) {
35569
+ return path16.basename(rulePath, path16.extname(rulePath)).replace(/[-_]+/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
35570
+ }
35571
+ async function readRuleTitle(rulePath) {
35572
+ const content = await import_fs_extra12.default.readFile(rulePath, "utf-8").catch(() => "");
35573
+ const heading = content.match(/^#\s+(.+)$/m)?.[1]?.trim();
35574
+ return heading || titleFromRulePath(rulePath);
35575
+ }
35576
+ async function collectRuleIndexEntries(rulesDir, rootDir, currentDir = rulesDir) {
35577
+ const entries = await import_fs_extra12.default.readdir(currentDir, { withFileTypes: true }).catch(() => []);
35578
+ const rules = [];
35579
+ for (const entry of entries) {
35580
+ if (IGNORED_ENTRY_NAMES2.has(entry.name))
35581
+ continue;
35582
+ const entryPath = path16.join(currentDir, entry.name);
35583
+ if (entry.isDirectory()) {
35584
+ rules.push(...await collectRuleIndexEntries(rulesDir, rootDir, entryPath));
35585
+ continue;
35586
+ }
35587
+ if (!entry.isFile() && !entry.isSymbolicLink())
35588
+ continue;
35589
+ if (![".md", ".mdc"].includes(path16.extname(entry.name).toLowerCase()))
35590
+ continue;
35591
+ rules.push({
35592
+ title: await readRuleTitle(entryPath),
35593
+ relativePath: path16.relative(rootDir, entryPath)
35594
+ });
35595
+ }
35596
+ return rules.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
35597
+ }
35598
+ function stripGeneratedRulesIndex(content) {
35599
+ const start = content.indexOf(RULES_INDEX_START);
35600
+ const end = content.indexOf(RULES_INDEX_END);
35601
+ if (start === -1 || end === -1 || end < start) {
35602
+ return content.trimEnd();
35603
+ }
35604
+ const beforeStart = content.slice(0, start);
35605
+ const headingIndex = beforeStart.lastIndexOf(`
35606
+ ## Rules`);
35607
+ const blockStart = headingIndex === -1 ? start : headingIndex + 1;
35608
+ return `${content.slice(0, blockStart).trimEnd()}
35609
+ ${content.slice(end + RULES_INDEX_END.length).trimStart()}`.trimEnd();
35610
+ }
35611
+ function renderRulesIndexBlock(rules) {
35612
+ const lines = [
35613
+ "## Rules",
35614
+ "",
35615
+ "Detailed focused rules live in `.agents/rules/`. Read the relevant file before acting:",
35616
+ "",
35617
+ RULES_INDEX_START
35618
+ ];
35619
+ if (rules.length === 0) {
35620
+ lines.push("- No repository rules found yet.");
35621
+ } else {
35622
+ for (const rule of rules) {
35623
+ lines.push(`- **${rule.title}** - [${rule.relativePath}](${rule.relativePath})`);
35624
+ }
35625
+ }
35626
+ lines.push(RULES_INDEX_END);
35627
+ return lines.join(`
35628
+ `);
35629
+ }
35630
+ async function readExistingInstructions(rootDir) {
35631
+ const agentsPath = path16.join(rootDir, "AGENTS.md");
35632
+ const claudePath = path16.join(rootDir, "CLAUDE.md");
35633
+ const agentsContent = await import_fs_extra12.default.readFile(agentsPath, "utf-8").catch(() => null);
35634
+ const claudeContent = await import_fs_extra12.default.readFile(claudePath, "utf-8").catch(() => null);
35635
+ if (agentsContent !== null && claudeContent !== null && agentsContent.trim() !== claudeContent.trim()) {
35636
+ return `${agentsContent.trimEnd()}
35637
+
35638
+ ## Previous Claude Instructions
35639
+
35640
+ ${claudeContent.trimStart()}`;
35641
+ }
35642
+ if (agentsContent !== null)
35643
+ return agentsContent;
35644
+ if (claudeContent !== null)
35645
+ return claudeContent;
35646
+ return `# Repository Instructions
35647
+ `;
35648
+ }
35649
+ async function copyPathToBackup(result, targetPath) {
35650
+ const stat = await import_fs_extra12.default.lstat(targetPath).catch(() => null);
35651
+ if (!stat)
35652
+ return null;
35653
+ const backupRoot = await ensureBackupPath(result);
35654
+ const backupTarget = path16.join(backupRoot, safeRelativePath(result.rootDir, targetPath));
35655
+ await import_fs_extra12.default.ensureDir(path16.dirname(backupTarget));
35656
+ await import_fs_extra12.default.copy(targetPath, backupTarget, {
35657
+ dereference: false,
35658
+ overwrite: false
35659
+ });
35660
+ return backupTarget;
35661
+ }
35662
+ async function replaceWithFileSymlink(sourcePath, targetPath) {
35663
+ await import_fs_extra12.default.ensureDir(path16.dirname(targetPath));
35664
+ const relativeSource = path16.relative(path16.dirname(targetPath), sourcePath) || path16.basename(sourcePath);
35665
+ await import_fs_extra12.default.symlink(relativeSource, targetPath, "file");
35666
+ }
35667
+ async function ensureClaudeInstructionSymlink(result, agentsPath, claudePath) {
35668
+ const agentsRealPath = await realPathIfPossible(agentsPath);
35669
+ const claudeStat = await import_fs_extra12.default.lstat(claudePath).catch(() => null);
35670
+ if (claudeStat?.isSymbolicLink()) {
35671
+ const claudeRealPath = await realPathIfPossible(claudePath);
35672
+ if (agentsRealPath && claudeRealPath && samePath(agentsRealPath, claudeRealPath)) {
35673
+ return;
35674
+ }
35675
+ }
35676
+ if (claudeStat) {
35677
+ await copyPathToBackup(result, claudePath);
35678
+ await import_fs_extra12.default.remove(claudePath);
35679
+ }
35680
+ await replaceWithFileSymlink(agentsPath, claudePath);
35681
+ }
35682
+ async function writeRepositoryInstructionIndex(result, folders) {
35683
+ const rulesDir = path16.join(folders.agentsDir, "rules");
35684
+ await import_fs_extra12.default.ensureDir(rulesDir);
35685
+ const rules = await collectRuleIndexEntries(rulesDir, folders.rootDir);
35686
+ const existing = stripGeneratedRulesIndex(await readExistingInstructions(folders.rootDir));
35687
+ const content = `${existing}
35688
+
35689
+ ${renderRulesIndexBlock(rules)}
35690
+ `;
35691
+ const agentsPath = path16.join(folders.rootDir, "AGENTS.md");
35692
+ const claudePath = path16.join(folders.rootDir, "CLAUDE.md");
35693
+ const agentsStat = await import_fs_extra12.default.lstat(agentsPath).catch(() => null);
35694
+ if (agentsStat) {
35695
+ await copyPathToBackup(result, agentsPath);
35696
+ if (agentsStat.isSymbolicLink()) {
35697
+ await import_fs_extra12.default.remove(agentsPath);
35698
+ }
35699
+ }
35700
+ await import_fs_extra12.default.writeFile(agentsPath, content, "utf-8");
35701
+ await ensureClaudeInstructionSymlink(result, agentsPath, claudePath);
35702
+ result.instructionIndex = {
35703
+ agentsPath,
35704
+ claudePath,
35705
+ indexedRules: rules.map((rule) => rule.relativePath)
35706
+ };
35707
+ }
35450
35708
  async function unifyAgentsConfiguration(options = {}) {
35709
+ const scope = options.scope ?? "global";
35451
35710
  const folders = resolveFolders(options);
35452
- const candidates = getContainerCandidates(options);
35453
35711
  const instructionCandidates = getInstructionFileCandidates(options);
35712
+ const candidates = scope === "repository" ? getRepositoryContainerCandidates(options) : getContainerCandidates(options);
35454
35713
  const result = {
35455
35714
  rootDir: folders.rootDir,
35456
35715
  agentsDir: folders.agentsDir,
35716
+ scope,
35457
35717
  backupPath: null,
35458
35718
  imported: [],
35459
35719
  duplicates: [],
35460
35720
  renamed: [],
35461
35721
  linked: [],
35462
35722
  alreadyLinked: [],
35463
- skipped: []
35723
+ skipped: [],
35724
+ instructionIndex: null
35464
35725
  };
35465
35726
  const destinationByCategory = {
35466
35727
  skills: path16.join(folders.agentsDir, "skills"),
35467
35728
  agents: path16.join(folders.agentsDir, "agents"),
35468
- instructions: path16.join(folders.agentsDir, "AGENTS.md")
35729
+ instructions: path16.join(folders.agentsDir, "AGENTS.md"),
35730
+ rules: path16.join(folders.agentsDir, "rules")
35469
35731
  };
35470
35732
  await import_fs_extra12.default.ensureDir(folders.agentsDir);
35471
35733
  await importInstructionFiles(instructionCandidates, destinationByCategory.instructions, result);
35472
- for (const category of ["skills", "agents"]) {
35734
+ const categories = scope === "repository" ? ["skills", "agents", "rules"] : ["skills", "agents"];
35735
+ for (const category of categories) {
35473
35736
  await importCategoryEntries(category, candidates, destinationByCategory[category], result);
35474
35737
  }
35475
35738
  for (const candidate of candidates) {
@@ -35478,6 +35741,9 @@ async function unifyAgentsConfiguration(options = {}) {
35478
35741
  for (const candidate of instructionCandidates) {
35479
35742
  await linkInstructionFile(candidate, destinationByCategory.instructions, result);
35480
35743
  }
35744
+ if (scope === "repository") {
35745
+ await writeRepositoryInstructionIndex(result, folders);
35746
+ }
35481
35747
  return result;
35482
35748
  }
35483
35749
 
@@ -35498,7 +35764,8 @@ async function agentsUnifyCommand(params = {}) {
35498
35764
  console.log(source_default.blue.bold(`
35499
35765
  AIBlueprint agents unify ${source_default.gray(`v${getVersion()}`)}
35500
35766
  `));
35501
- console.log(source_default.gray("Centralizing reusable skills and agents into .agents, then rendering Codex agents"));
35767
+ console.log(source_default.gray(`Scope: ${params.scope ?? "global"}`));
35768
+ console.log(source_default.gray("Centralizing reusable agent configuration into .agents, then rendering Codex agents"));
35502
35769
  const result = await unifyAgentsConfiguration(params);
35503
35770
  const codexResult = await renderCodexAgentsFromMarkdown(params);
35504
35771
  console.log(source_default.green(`
@@ -35507,7 +35774,14 @@ Unify complete`));
35507
35774
  printCategorySummary(result, "instructions");
35508
35775
  printCategorySummary(result, "skills");
35509
35776
  printCategorySummary(result, "agents");
35777
+ if (result.scope === "repository") {
35778
+ printCategorySummary(result, "rules");
35779
+ }
35510
35780
  console.log(source_default.gray(` codex agents: ${codexResult.rendered.length} rendered, ${codexResult.skipped.length} skipped`));
35781
+ if (result.instructionIndex) {
35782
+ console.log(source_default.gray(` rules index: ${result.instructionIndex.indexedRules.length} rules indexed in ${result.instructionIndex.agentsPath}`));
35783
+ console.log(source_default.gray(` Claude instructions: ${result.instructionIndex.claudePath}`));
35784
+ }
35511
35785
  if (result.backupPath) {
35512
35786
  console.log(source_default.gray(` Source backups: ${result.backupPath}`));
35513
35787
  }
@@ -35553,6 +35827,359 @@ Codex agents render failed:`), error);
35553
35827
  }
35554
35828
  }
35555
35829
 
35830
+ // src/lib/session-unifier.ts
35831
+ var import_fs_extra14 = __toESM(require_lib4(), 1);
35832
+ import crypto2 from "crypto";
35833
+ import os15 from "os";
35834
+ import path18 from "path";
35835
+
35836
+ // src/lib/backup-utils.ts
35837
+ var import_fs_extra13 = __toESM(require_lib4(), 1);
35838
+ import path17 from "path";
35839
+ import os14 from "os";
35840
+ var BACKUP_BASE_DIR = path17.join(os14.homedir(), ".config", "aiblueprint", "backup");
35841
+ function getBackupDir() {
35842
+ return process.env.AIBLUEPRINT_BACKUP_DIR || BACKUP_BASE_DIR;
35843
+ }
35844
+ function formatDate(date) {
35845
+ const pad = (n) => n.toString().padStart(2, "0");
35846
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
35847
+ }
35848
+ async function listBackups() {
35849
+ const backupBaseDir = getBackupDir();
35850
+ const exists = await import_fs_extra13.default.pathExists(backupBaseDir);
35851
+ if (!exists) {
35852
+ return [];
35853
+ }
35854
+ const entries = await import_fs_extra13.default.readdir(backupBaseDir, { withFileTypes: true });
35855
+ const backups = [];
35856
+ for (const entry of entries) {
35857
+ if (!entry.isDirectory())
35858
+ continue;
35859
+ const match = entry.name.match(/^(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})$/);
35860
+ if (!match)
35861
+ continue;
35862
+ const [, year, month, day, hour, minute, second] = match;
35863
+ const date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second));
35864
+ backups.push({
35865
+ name: entry.name,
35866
+ path: path17.join(backupBaseDir, entry.name),
35867
+ date
35868
+ });
35869
+ }
35870
+ return backups.sort((a, b) => b.date.getTime() - a.date.getTime());
35871
+ }
35872
+ var AGENTS_BACKUP_SUBDIR = ".agents";
35873
+ var CLAUDE_ITEMS = ["commands", "agents", "skills", "scripts", "settings.json"];
35874
+ var MANAGED_FOLDERS = [".claude", ".codex", ".agents"];
35875
+ async function copyForBackup(sourcePath, destPath) {
35876
+ await import_fs_extra13.default.copy(sourcePath, destPath, {
35877
+ overwrite: true,
35878
+ dereference: false
35879
+ });
35880
+ }
35881
+ async function hasMeaningfulContent(dir) {
35882
+ if (!await import_fs_extra13.default.pathExists(dir))
35883
+ return false;
35884
+ const files = await import_fs_extra13.default.readdir(dir);
35885
+ return files.some((f) => f !== ".DS_Store");
35886
+ }
35887
+ async function loadBackup(backupPath, claudeDir, codexDir, agentsDir) {
35888
+ const exists = await import_fs_extra13.default.pathExists(backupPath);
35889
+ if (!exists) {
35890
+ throw new Error(`Backup not found: ${backupPath}`);
35891
+ }
35892
+ const managedDestinations = {
35893
+ ".claude": claudeDir,
35894
+ ".codex": codexDir,
35895
+ ".agents": agentsDir
35896
+ };
35897
+ let restoredManagedFolder = false;
35898
+ for (const folderName of MANAGED_FOLDERS) {
35899
+ const sourcePath = path17.join(backupPath, folderName);
35900
+ const destPath = managedDestinations[folderName];
35901
+ if (!destPath || !await import_fs_extra13.default.pathExists(sourcePath))
35902
+ continue;
35903
+ await import_fs_extra13.default.ensureDir(destPath);
35904
+ await copyForBackup(sourcePath, destPath);
35905
+ restoredManagedFolder = true;
35906
+ }
35907
+ if (!restoredManagedFolder) {
35908
+ await import_fs_extra13.default.ensureDir(claudeDir);
35909
+ for (const item of CLAUDE_ITEMS) {
35910
+ const sourcePath = path17.join(backupPath, item);
35911
+ const destPath = path17.join(claudeDir, item);
35912
+ if (await import_fs_extra13.default.pathExists(sourcePath)) {
35913
+ await copyForBackup(sourcePath, destPath);
35914
+ }
35915
+ }
35916
+ if (agentsDir) {
35917
+ const agentsBackupPath = path17.join(backupPath, AGENTS_BACKUP_SUBDIR);
35918
+ if (await import_fs_extra13.default.pathExists(agentsBackupPath)) {
35919
+ await import_fs_extra13.default.ensureDir(agentsDir);
35920
+ await copyForBackup(agentsBackupPath, agentsDir);
35921
+ }
35922
+ }
35923
+ }
35924
+ }
35925
+ async function createBackup(claudeDir, codexDir, agentsDir) {
35926
+ const claudeHasContent = await hasMeaningfulContent(claudeDir);
35927
+ const codexHasContent = codexDir ? await hasMeaningfulContent(codexDir) : false;
35928
+ const agentsHasContent = agentsDir ? await hasMeaningfulContent(agentsDir) : false;
35929
+ if (!claudeHasContent && !codexHasContent && !agentsHasContent) {
35930
+ return null;
35931
+ }
35932
+ const timestamp3 = formatDate(new Date);
35933
+ const backupPath = path17.join(getBackupDir(), timestamp3);
35934
+ await import_fs_extra13.default.ensureDir(backupPath);
35935
+ if (claudeHasContent) {
35936
+ await copyForBackup(claudeDir, path17.join(backupPath, ".claude"));
35937
+ }
35938
+ if (codexHasContent && codexDir) {
35939
+ await copyForBackup(codexDir, path17.join(backupPath, ".codex"));
35940
+ }
35941
+ if (agentsHasContent && agentsDir) {
35942
+ const destPath = path17.join(backupPath, AGENTS_BACKUP_SUBDIR);
35943
+ await copyForBackup(agentsDir, destPath);
35944
+ }
35945
+ return backupPath;
35946
+ }
35947
+
35948
+ // src/lib/session-unifier.ts
35949
+ var MANAGED_FOLDERS2 = [".claude", ".codex", ".agents"];
35950
+ var SESSION_PATHS = {
35951
+ ".claude": ["projects", "sessions"],
35952
+ ".codex": ["sessions", "archived_sessions", "browser/sessions"],
35953
+ ".agents": ["sessions"]
35954
+ };
35955
+ async function listSnapshotSources(parentDir, type) {
35956
+ if (!await import_fs_extra14.default.pathExists(parentDir))
35957
+ return [];
35958
+ const entries = await import_fs_extra14.default.readdir(parentDir, { withFileTypes: true });
35959
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => ({
35960
+ name: entry.name,
35961
+ path: path18.join(parentDir, entry.name),
35962
+ type
35963
+ }));
35964
+ }
35965
+ async function collectSnapshotSources(folders) {
35966
+ const storePaths = getConfigStorePaths(folders.rootDir);
35967
+ const sources = [
35968
+ ...await listSnapshotSources(storePaths.configsDir, "config"),
35969
+ ...await listSnapshotSources(storePaths.backupsDir, "backup")
35970
+ ];
35971
+ if (path18.resolve(folders.rootDir) === os15.homedir()) {
35972
+ sources.push(...await listSnapshotSources(getBackupDir(), "legacy-backup"));
35973
+ }
35974
+ return sources.sort((a, b) => a.name.localeCompare(b.name));
35975
+ }
35976
+ async function snapshotFolderPath(snapshot, folder) {
35977
+ const managedPath = path18.join(snapshot.path, folder);
35978
+ if (await import_fs_extra14.default.pathExists(managedPath))
35979
+ return managedPath;
35980
+ if (snapshot.type === "legacy-backup") {
35981
+ if (folder === ".claude")
35982
+ return snapshot.path;
35983
+ const legacyAgentsPath = path18.join(snapshot.path, ".agents");
35984
+ if (folder === ".agents" && await import_fs_extra14.default.pathExists(legacyAgentsPath)) {
35985
+ return legacyAgentsPath;
35986
+ }
35987
+ }
35988
+ return null;
35989
+ }
35990
+ function sanitizeSourceTag(snapshot) {
35991
+ return `${snapshot.type}-${snapshot.name}`.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "snapshot";
35992
+ }
35993
+ function withSourceSuffix(targetPath, sourceTag, index) {
35994
+ const parsed = path18.parse(targetPath);
35995
+ const suffix = index === 1 ? sourceTag : `${sourceTag}-${index}`;
35996
+ if (parsed.ext && parsed.name) {
35997
+ return path18.join(parsed.dir, `${parsed.name}--${suffix}${parsed.ext}`);
35998
+ }
35999
+ return path18.join(parsed.dir, `${parsed.base}--${suffix}`);
36000
+ }
36001
+ async function uniqueConflictPath(targetPath, sourceTag) {
36002
+ let index = 1;
36003
+ while (true) {
36004
+ const candidate = withSourceSuffix(targetPath, sourceTag, index);
36005
+ if (!await import_fs_extra14.default.pathExists(candidate))
36006
+ return candidate;
36007
+ index++;
36008
+ }
36009
+ }
36010
+ function hashString2(value) {
36011
+ return crypto2.createHash("sha256").update(value).digest("hex");
36012
+ }
36013
+ async function hashPath2(targetPath) {
36014
+ const stat = await import_fs_extra14.default.lstat(targetPath);
36015
+ if (stat.isSymbolicLink()) {
36016
+ return hashString2(`symlink:${await import_fs_extra14.default.readlink(targetPath)}`);
36017
+ }
36018
+ if (stat.isFile()) {
36019
+ const hash = crypto2.createHash("sha256");
36020
+ hash.update("file:");
36021
+ hash.update(await import_fs_extra14.default.readFile(targetPath));
36022
+ return hash.digest("hex");
36023
+ }
36024
+ if (stat.isDirectory()) {
36025
+ const entries = (await import_fs_extra14.default.readdir(targetPath, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
36026
+ const hash = crypto2.createHash("sha256");
36027
+ hash.update("dir:");
36028
+ for (const entry of entries) {
36029
+ hash.update(entry.name);
36030
+ hash.update("\x00");
36031
+ hash.update(await hashPath2(path18.join(targetPath, entry.name)));
36032
+ hash.update("\x00");
36033
+ }
36034
+ return hash.digest("hex");
36035
+ }
36036
+ return hashString2(`other:${stat.mode}:${stat.size}`);
36037
+ }
36038
+ async function mergeSessionPath(params) {
36039
+ const {
36040
+ sourcePath,
36041
+ destinationPath,
36042
+ folder,
36043
+ sessionRoot,
36044
+ snapshot,
36045
+ sourceTag,
36046
+ result
36047
+ } = params;
36048
+ const sourceStat = await import_fs_extra14.default.lstat(sourcePath).catch(() => null);
36049
+ if (!sourceStat)
36050
+ return;
36051
+ const destinationStat = await import_fs_extra14.default.lstat(destinationPath).catch(() => null);
36052
+ if (sourceStat.isDirectory() && destinationStat?.isDirectory()) {
36053
+ const entries = await import_fs_extra14.default.readdir(sourcePath);
36054
+ await import_fs_extra14.default.ensureDir(destinationPath);
36055
+ for (const entry of entries) {
36056
+ await mergeSessionPath({
36057
+ sourcePath: path18.join(sourcePath, entry),
36058
+ destinationPath: path18.join(destinationPath, entry),
36059
+ folder,
36060
+ sessionRoot,
36061
+ snapshot,
36062
+ sourceTag,
36063
+ result
36064
+ });
36065
+ }
36066
+ return;
36067
+ }
36068
+ if (!destinationStat) {
36069
+ await import_fs_extra14.default.ensureDir(path18.dirname(destinationPath));
36070
+ await import_fs_extra14.default.copy(sourcePath, destinationPath, {
36071
+ overwrite: false,
36072
+ dereference: false
36073
+ });
36074
+ result.imported.push({
36075
+ folder,
36076
+ sessionRoot,
36077
+ from: sourcePath,
36078
+ to: destinationPath,
36079
+ snapshot: snapshot.name
36080
+ });
36081
+ return;
36082
+ }
36083
+ if (await hashPath2(sourcePath) === await hashPath2(destinationPath)) {
36084
+ result.duplicates.push({
36085
+ folder,
36086
+ sessionRoot,
36087
+ from: sourcePath,
36088
+ existing: destinationPath,
36089
+ snapshot: snapshot.name
36090
+ });
36091
+ return;
36092
+ }
36093
+ const conflictPath = await uniqueConflictPath(destinationPath, sourceTag);
36094
+ await import_fs_extra14.default.ensureDir(path18.dirname(conflictPath));
36095
+ await import_fs_extra14.default.copy(sourcePath, conflictPath, {
36096
+ overwrite: false,
36097
+ dereference: false
36098
+ });
36099
+ result.conflicts.push({
36100
+ folder,
36101
+ sessionRoot,
36102
+ from: sourcePath,
36103
+ to: conflictPath,
36104
+ snapshot: snapshot.name,
36105
+ reason: "Same session path with different content"
36106
+ });
36107
+ }
36108
+ async function unifySessionsFromSnapshots(options = {}) {
36109
+ const folders = resolveFolders(options);
36110
+ const snapshots = await collectSnapshotSources(folders);
36111
+ const destinationByFolder = {
36112
+ ".claude": folders.claudeDir,
36113
+ ".codex": folders.codexDir,
36114
+ ".agents": folders.agentsDir
36115
+ };
36116
+ const result = {
36117
+ rootDir: folders.rootDir,
36118
+ scannedSnapshots: snapshots,
36119
+ imported: [],
36120
+ duplicates: [],
36121
+ conflicts: []
36122
+ };
36123
+ for (const snapshot of snapshots) {
36124
+ const sourceTag = sanitizeSourceTag(snapshot);
36125
+ for (const folder of MANAGED_FOLDERS2) {
36126
+ const sourceFolder = await snapshotFolderPath(snapshot, folder);
36127
+ if (!sourceFolder)
36128
+ continue;
36129
+ for (const sessionRoot of SESSION_PATHS[folder]) {
36130
+ const sourcePath = path18.join(sourceFolder, sessionRoot);
36131
+ if (!await import_fs_extra14.default.pathExists(sourcePath))
36132
+ continue;
36133
+ await mergeSessionPath({
36134
+ sourcePath,
36135
+ destinationPath: path18.join(destinationByFolder[folder], sessionRoot),
36136
+ folder,
36137
+ sessionRoot,
36138
+ snapshot,
36139
+ sourceTag,
36140
+ result
36141
+ });
36142
+ }
36143
+ }
36144
+ }
36145
+ return result;
36146
+ }
36147
+
36148
+ // src/commands/session-unify.ts
36149
+ function summarizeByFolder(entries) {
36150
+ const counts = new Map;
36151
+ for (const entry of entries) {
36152
+ counts.set(entry.folder, (counts.get(entry.folder) ?? 0) + 1);
36153
+ }
36154
+ if (counts.size === 0)
36155
+ return "none";
36156
+ return [...counts.entries()].map(([folder, count]) => `${folder}: ${count}`).join(", ");
36157
+ }
36158
+ async function sessionsUnifyCommand(params = {}) {
36159
+ try {
36160
+ console.log(source_default.blue("Unifying saved sessions from configs and backups..."));
36161
+ const result = await unifySessionsFromSnapshots(params);
36162
+ console.log(source_default.green("Session unify complete"));
36163
+ console.log(source_default.gray(` Snapshots scanned: ${result.scannedSnapshots.length}`));
36164
+ console.log(source_default.gray(` Imported: ${result.imported.length} (${summarizeByFolder(result.imported)})`));
36165
+ console.log(source_default.gray(` Duplicates skipped: ${result.duplicates.length}`));
36166
+ console.log(source_default.gray(` Conflicts preserved: ${result.conflicts.length}`));
36167
+ if (result.conflicts.length > 0) {
36168
+ console.log(source_default.yellow(`
36169
+ Conflicting session paths were copied with source suffixes:`));
36170
+ for (const conflict of result.conflicts.slice(0, 10)) {
36171
+ console.log(source_default.yellow(` ${conflict.to}`));
36172
+ }
36173
+ if (result.conflicts.length > 10) {
36174
+ console.log(source_default.yellow(` ...and ${result.conflicts.length - 10} more`));
36175
+ }
36176
+ }
36177
+ } catch (error) {
36178
+ console.error(source_default.red("Session unify failed:"), error);
36179
+ process.exit(1);
36180
+ }
36181
+ }
36182
+
35556
36183
  // node_modules/@clack/core/dist/index.mjs
35557
36184
  var import_sisteransi = __toESM(require_src(), 1);
35558
36185
  var import_picocolors = __toESM(require_picocolors(), 1);
@@ -36269,12 +36896,12 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
36269
36896
  };
36270
36897
 
36271
36898
  // src/commands/pro.ts
36272
- import path19 from "path";
36899
+ import path21 from "path";
36273
36900
 
36274
36901
  // src/lib/pro-installer.ts
36275
- var import_fs_extra13 = __toESM(require_lib4(), 1);
36276
- import os14 from "os";
36277
- import path17 from "path";
36902
+ var import_fs_extra15 = __toESM(require_lib4(), 1);
36903
+ import os16 from "os";
36904
+ import path19 from "path";
36278
36905
  import { exec as exec3 } from "child_process";
36279
36906
  import { promisify as promisify2 } from "util";
36280
36907
  var execAsync2 = promisify2(exec3);
@@ -36282,9 +36909,9 @@ var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
36282
36909
  var PREMIUM_BRANCH = "main";
36283
36910
  var CONFIG_FOLDER_CANDIDATES2 = ["agents-config", "ai-coding", "claude-code-config", "ai-config"];
36284
36911
  function routePath(relativePath) {
36285
- const segments = relativePath.split(path17.sep);
36912
+ const segments = relativePath.split(path19.sep);
36286
36913
  const first = segments[0];
36287
- const rest = segments.slice(1).join(path17.sep);
36914
+ const rest = segments.slice(1).join(path19.sep);
36288
36915
  if (first === "claude-config") {
36289
36916
  return { kind: "claude", relativePath: rest };
36290
36917
  }
@@ -36300,7 +36927,7 @@ function routePath(relativePath) {
36300
36927
  return { kind: "claude", relativePath };
36301
36928
  }
36302
36929
  function getCacheRepoDir() {
36303
- return path17.join(os14.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
36930
+ return path19.join(os16.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
36304
36931
  }
36305
36932
  async function execGitWithAuth(command, token, repoUrl, cwd) {
36306
36933
  const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
@@ -36314,21 +36941,21 @@ async function execGitWithAuth(command, token, repoUrl, cwd) {
36314
36941
  async function cloneOrUpdateRepo(token) {
36315
36942
  const cacheDir = getCacheRepoDir();
36316
36943
  const repoUrl = `https://github.com/${PREMIUM_REPO}.git`;
36317
- if (await import_fs_extra13.default.pathExists(path17.join(cacheDir, ".git"))) {
36944
+ if (await import_fs_extra15.default.pathExists(path19.join(cacheDir, ".git"))) {
36318
36945
  try {
36319
36946
  await execGitWithAuth("pull", token, repoUrl, cacheDir);
36320
36947
  } catch (error) {
36321
- await import_fs_extra13.default.remove(cacheDir);
36322
- await import_fs_extra13.default.ensureDir(path17.dirname(cacheDir));
36948
+ await import_fs_extra15.default.remove(cacheDir);
36949
+ await import_fs_extra15.default.ensureDir(path19.dirname(cacheDir));
36323
36950
  await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
36324
36951
  }
36325
36952
  } else {
36326
- await import_fs_extra13.default.ensureDir(path17.dirname(cacheDir));
36953
+ await import_fs_extra15.default.ensureDir(path19.dirname(cacheDir));
36327
36954
  await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
36328
36955
  }
36329
36956
  for (const candidate of CONFIG_FOLDER_CANDIDATES2) {
36330
- const candidatePath = path17.join(cacheDir, candidate);
36331
- if (await import_fs_extra13.default.pathExists(candidatePath)) {
36957
+ const candidatePath = path19.join(cacheDir, candidate);
36958
+ if (await import_fs_extra15.default.pathExists(candidatePath)) {
36332
36959
  return candidatePath;
36333
36960
  }
36334
36961
  }
@@ -36336,38 +36963,38 @@ async function cloneOrUpdateRepo(token) {
36336
36963
  }
36337
36964
  async function copyConfigFromCache(cacheConfigDir, dest, onProgress) {
36338
36965
  const walk = async (dir, baseDir = dir) => {
36339
- const entries = await import_fs_extra13.default.readdir(dir, { withFileTypes: true });
36966
+ const entries = await import_fs_extra15.default.readdir(dir, { withFileTypes: true });
36340
36967
  for (const entry of entries) {
36341
36968
  if (entry.name === ".DS_Store" || entry.name === "node_modules")
36342
36969
  continue;
36343
- const sourcePath = path17.join(dir, entry.name);
36344
- const relativePath = path17.relative(baseDir, sourcePath);
36970
+ const sourcePath = path19.join(dir, entry.name);
36971
+ const relativePath = path19.relative(baseDir, sourcePath);
36345
36972
  const route = routePath(relativePath);
36346
36973
  if (route.kind === "skip")
36347
36974
  continue;
36348
36975
  if (route.kind === "agents-category") {
36349
- if (relativePath.split(path17.sep).length === 1) {
36976
+ if (relativePath.split(path19.sep).length === 1) {
36350
36977
  await copyAgentCategory(sourcePath, route.category, dest.agentsDir, dest.claudeDir, onProgress);
36351
36978
  }
36352
36979
  continue;
36353
36980
  }
36354
36981
  const targetBase = route.kind === "claude" ? dest.claudeDir : dest.codexDir;
36355
- const targetPath = path17.join(targetBase, route.relativePath);
36982
+ const targetPath = path19.join(targetBase, route.relativePath);
36356
36983
  if (entry.isDirectory()) {
36357
- await import_fs_extra13.default.ensureDir(targetPath);
36984
+ await import_fs_extra15.default.ensureDir(targetPath);
36358
36985
  onProgress?.(relativePath, "directory");
36359
36986
  await walk(sourcePath, baseDir);
36360
36987
  } else if (route.kind === "codex" && route.relativePath === "config.toml") {
36361
36988
  await mergeCodexConfigFile(sourcePath, dest.codexDir);
36362
36989
  onProgress?.(relativePath, "file");
36363
36990
  } else if (isTextFile(entry.name)) {
36364
- const content = await import_fs_extra13.default.readFile(sourcePath, "utf-8");
36991
+ const content = await import_fs_extra15.default.readFile(sourcePath, "utf-8");
36365
36992
  const replaced = replaceClaudePathPlaceholder(content, dest.claudeDir);
36366
- await import_fs_extra13.default.ensureDir(path17.dirname(targetPath));
36367
- await import_fs_extra13.default.writeFile(targetPath, replaced, "utf-8");
36993
+ await import_fs_extra15.default.ensureDir(path19.dirname(targetPath));
36994
+ await import_fs_extra15.default.writeFile(targetPath, replaced, "utf-8");
36368
36995
  onProgress?.(relativePath, "file");
36369
36996
  } else {
36370
- await import_fs_extra13.default.copy(sourcePath, targetPath, { overwrite: true });
36997
+ await import_fs_extra15.default.copy(sourcePath, targetPath, { overwrite: true });
36371
36998
  onProgress?.(relativePath, "file");
36372
36999
  }
36373
37000
  }
@@ -36375,21 +37002,21 @@ async function copyConfigFromCache(cacheConfigDir, dest, onProgress) {
36375
37002
  await walk(cacheConfigDir);
36376
37003
  }
36377
37004
  async function copyAgentCategory(sourceCategoryDir, category, agentsDir, claudeDir, onProgress) {
36378
- const agentsCategoryDir = path17.join(agentsDir, category);
36379
- await import_fs_extra13.default.ensureDir(agentsCategoryDir);
36380
- const entries = await import_fs_extra13.default.readdir(sourceCategoryDir, { withFileTypes: true });
37005
+ const agentsCategoryDir = path19.join(agentsDir, category);
37006
+ await import_fs_extra15.default.ensureDir(agentsCategoryDir);
37007
+ const entries = await import_fs_extra15.default.readdir(sourceCategoryDir, { withFileTypes: true });
36381
37008
  for (const entry of entries) {
36382
37009
  if (entry.name === ".DS_Store")
36383
37010
  continue;
36384
- const src = path17.join(sourceCategoryDir, entry.name);
36385
- const dst = path17.join(agentsCategoryDir, entry.name);
36386
- const claudeTop = path17.join(claudeDir, category, entry.name);
36387
- const claudeStat = await import_fs_extra13.default.lstat(claudeTop).catch(() => null);
37011
+ const src = path19.join(sourceCategoryDir, entry.name);
37012
+ const dst = path19.join(agentsCategoryDir, entry.name);
37013
+ const claudeTop = path19.join(claudeDir, category, entry.name);
37014
+ const claudeStat = await import_fs_extra15.default.lstat(claudeTop).catch(() => null);
36388
37015
  if (claudeStat && !claudeStat.isSymbolicLink()) {
36389
37016
  onProgress?.(`${category}/${entry.name} (skipped - real dir in claude)`, "file");
36390
37017
  continue;
36391
37018
  }
36392
- await import_fs_extra13.default.copy(src, dst, { overwrite: true });
37019
+ await import_fs_extra15.default.copy(src, dst, { overwrite: true });
36393
37020
  await applyPathPlaceholders(dst, claudeDir);
36394
37021
  onProgress?.(`${category}/${entry.name}`, entry.isDirectory() ? "directory" : "file");
36395
37022
  }
@@ -36408,8 +37035,8 @@ async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath,
36408
37035
  return false;
36409
37036
  }
36410
37037
  const content = await response.arrayBuffer();
36411
- await import_fs_extra13.default.ensureDir(path17.dirname(targetPath));
36412
- await import_fs_extra13.default.writeFile(targetPath, Buffer.from(content));
37038
+ await import_fs_extra15.default.ensureDir(path19.dirname(targetPath));
37039
+ await import_fs_extra15.default.writeFile(targetPath, Buffer.from(content));
36413
37040
  return true;
36414
37041
  } catch (error) {
36415
37042
  console.error(`Error downloading ${relativePath}:`, error);
@@ -36434,10 +37061,10 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
36434
37061
  console.error(`Unexpected response for directory ${dirPath}`);
36435
37062
  return false;
36436
37063
  }
36437
- await import_fs_extra13.default.ensureDir(targetDir);
37064
+ await import_fs_extra15.default.ensureDir(targetDir);
36438
37065
  for (const file of files) {
36439
37066
  const relativePath = dirPath ? `${dirPath}/${file.name}` : file.name;
36440
- const targetPath = path17.join(targetDir, file.name);
37067
+ const targetPath = path19.join(targetDir, file.name);
36441
37068
  const displayPath = relativePath.replace(/^(agents-config|ai-coding|claude-code-config|ai-config)\//, "");
36442
37069
  if (file.type === "file") {
36443
37070
  onProgress?.(displayPath, "file");
@@ -36460,8 +37087,8 @@ async function installProConfigs(options) {
36460
37087
  codexFolder,
36461
37088
  agentsFolder
36462
37089
  });
36463
- await import_fs_extra13.default.ensureDir(claudeDir);
36464
- await import_fs_extra13.default.ensureDir(agentsDir);
37090
+ await import_fs_extra15.default.ensureDir(claudeDir);
37091
+ await import_fs_extra15.default.ensureDir(agentsDir);
36465
37092
  const dest = { claudeDir, codexDir, agentsDir };
36466
37093
  try {
36467
37094
  const cacheConfigDir = await cloneOrUpdateRepo(githubToken);
@@ -36471,7 +37098,7 @@ async function installProConfigs(options) {
36471
37098
  } catch (error) {
36472
37099
  console.warn("Git caching failed, falling back to API download");
36473
37100
  }
36474
- const tempDir = path17.join(os14.tmpdir(), `aiblueprint-premium-${Date.now()}`);
37101
+ const tempDir = path19.join(os16.tmpdir(), `aiblueprint-premium-${Date.now()}`);
36475
37102
  try {
36476
37103
  let success = false;
36477
37104
  for (const candidate of CONFIG_FOLDER_CANDIDATES2) {
@@ -36485,8 +37112,8 @@ async function installProConfigs(options) {
36485
37112
  await copyConfigFromCache(tempDir, dest, onProgress);
36486
37113
  await replacePathPlaceholdersInDir(claudeDir, claudeDir);
36487
37114
  for (const category of AGENT_CATEGORIES) {
36488
- const agentsCategoryDir = path17.join(agentsDir, category);
36489
- if (await import_fs_extra13.default.pathExists(agentsCategoryDir)) {
37115
+ const agentsCategoryDir = path19.join(agentsDir, category);
37116
+ if (await import_fs_extra15.default.pathExists(agentsCategoryDir)) {
36490
37117
  await replacePathPlaceholdersInDir(agentsCategoryDir, claudeDir);
36491
37118
  }
36492
37119
  }
@@ -36495,7 +37122,7 @@ async function installProConfigs(options) {
36495
37122
  throw new Error(`Failed to install premium configs: ${error instanceof Error ? error.message : "Unknown error"}`);
36496
37123
  } finally {
36497
37124
  try {
36498
- await import_fs_extra13.default.remove(tempDir);
37125
+ await import_fs_extra15.default.remove(tempDir);
36499
37126
  } catch {}
36500
37127
  }
36501
37128
  }
@@ -36506,27 +37133,27 @@ async function syncAllAgentSymlinks(agentsDir, claudeDir) {
36506
37133
  }
36507
37134
 
36508
37135
  // src/lib/token-storage.ts
36509
- var import_fs_extra14 = __toESM(require_lib4(), 1);
36510
- import os15 from "os";
36511
- import path18 from "path";
37136
+ var import_fs_extra16 = __toESM(require_lib4(), 1);
37137
+ import os17 from "os";
37138
+ import path20 from "path";
36512
37139
  function getConfigDir() {
36513
- const platform = os15.platform();
37140
+ const platform = os17.platform();
36514
37141
  if (platform === "win32") {
36515
- const appData = process.env.APPDATA || path18.join(os15.homedir(), "AppData", "Roaming");
36516
- return path18.join(appData, "aiblueprint");
37142
+ const appData = process.env.APPDATA || path20.join(os17.homedir(), "AppData", "Roaming");
37143
+ return path20.join(appData, "aiblueprint");
36517
37144
  } else {
36518
- const configHome = process.env.XDG_CONFIG_HOME || path18.join(os15.homedir(), ".config");
36519
- return path18.join(configHome, "aiblueprint");
37145
+ const configHome = process.env.XDG_CONFIG_HOME || path20.join(os17.homedir(), ".config");
37146
+ return path20.join(configHome, "aiblueprint");
36520
37147
  }
36521
37148
  }
36522
37149
  function getTokenFilePath2() {
36523
- return path18.join(getConfigDir(), "token.txt");
37150
+ return path20.join(getConfigDir(), "token.txt");
36524
37151
  }
36525
37152
  async function saveToken(githubToken) {
36526
37153
  const tokenFile = getTokenFilePath2();
36527
- const configDir = path18.dirname(tokenFile);
37154
+ const configDir = path20.dirname(tokenFile);
36528
37155
  try {
36529
- await import_fs_extra14.default.ensureDir(configDir);
37156
+ await import_fs_extra16.default.ensureDir(configDir);
36530
37157
  } catch (error) {
36531
37158
  if (error.code === "EACCES") {
36532
37159
  throw new Error(`Permission denied creating config directory: ${configDir}
@@ -36534,15 +37161,15 @@ async function saveToken(githubToken) {
36534
37161
  }
36535
37162
  throw error;
36536
37163
  }
36537
- await import_fs_extra14.default.writeFile(tokenFile, githubToken, { mode: 384 });
37164
+ await import_fs_extra16.default.writeFile(tokenFile, githubToken, { mode: 384 });
36538
37165
  }
36539
37166
  async function getToken() {
36540
37167
  const tokenFile = getTokenFilePath2();
36541
- if (!await import_fs_extra14.default.pathExists(tokenFile)) {
37168
+ if (!await import_fs_extra16.default.pathExists(tokenFile)) {
36542
37169
  return null;
36543
37170
  }
36544
37171
  try {
36545
- const token = await import_fs_extra14.default.readFile(tokenFile, "utf-8");
37172
+ const token = await import_fs_extra16.default.readFile(tokenFile, "utf-8");
36546
37173
  return token.trim();
36547
37174
  } catch (error) {
36548
37175
  return null;
@@ -36551,12 +37178,12 @@ async function getToken() {
36551
37178
  function getTokenInfo() {
36552
37179
  return {
36553
37180
  path: getTokenFilePath2(),
36554
- platform: os15.platform()
37181
+ platform: os17.platform()
36555
37182
  };
36556
37183
  }
36557
37184
 
36558
37185
  // src/commands/pro.ts
36559
- var import_fs_extra15 = __toESM(require_lib4(), 1);
37186
+ var import_fs_extra17 = __toESM(require_lib4(), 1);
36560
37187
  var API_URL = "https://codeline.app/api/products";
36561
37188
  var PRODUCT_IDS = ["prd_XJVgxVPbGG", "prd_NKabAkdOkw"];
36562
37189
  async function countInstalledItems(claudeDir) {
@@ -36565,20 +37192,20 @@ async function countInstalledItems(claudeDir) {
36565
37192
  skills: 0
36566
37193
  };
36567
37194
  try {
36568
- const agentsDir = path19.join(claudeDir, "agents");
36569
- if (await import_fs_extra15.default.pathExists(agentsDir)) {
36570
- const files = await import_fs_extra15.default.readdir(agentsDir);
37195
+ const agentsDir = path21.join(claudeDir, "agents");
37196
+ if (await import_fs_extra17.default.pathExists(agentsDir)) {
37197
+ const files = await import_fs_extra17.default.readdir(agentsDir);
36571
37198
  counts.agents = files.filter((f) => f.endsWith(".md")).length;
36572
37199
  }
36573
37200
  } catch (error) {
36574
37201
  console.error("Failed to count agents:", error instanceof Error ? error.message : error);
36575
37202
  }
36576
37203
  try {
36577
- const skillsDir = path19.join(claudeDir, "skills");
36578
- if (await import_fs_extra15.default.pathExists(skillsDir)) {
36579
- const items = await import_fs_extra15.default.readdir(skillsDir);
37204
+ const skillsDir = path21.join(claudeDir, "skills");
37205
+ if (await import_fs_extra17.default.pathExists(skillsDir)) {
37206
+ const items = await import_fs_extra17.default.readdir(skillsDir);
36580
37207
  const dirs = await Promise.all(items.map(async (item) => {
36581
- const stat = await import_fs_extra15.default.stat(path19.join(skillsDir, item));
37208
+ const stat = await import_fs_extra17.default.stat(path21.join(skillsDir, item));
36582
37209
  return stat.isDirectory();
36583
37210
  }));
36584
37211
  counts.skills = dirs.filter(Boolean).length;
@@ -36786,9 +37413,9 @@ async function proUpdateCommand(options = {}) {
36786
37413
  }
36787
37414
 
36788
37415
  // src/lib/sync-utils.ts
36789
- var import_fs_extra16 = __toESM(require_lib4(), 1);
36790
- import path20 from "path";
36791
- import crypto2 from "crypto";
37416
+ var import_fs_extra18 = __toESM(require_lib4(), 1);
37417
+ import path22 from "path";
37418
+ import crypto3 from "crypto";
36792
37419
  var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
36793
37420
  var PREMIUM_BRANCH2 = "main";
36794
37421
  var CONFIG_FOLDER_CANDIDATES3 = ["agents-config", "ai-coding", "claude-code-config", "ai-config"];
@@ -36796,7 +37423,7 @@ function computeFileSha(content) {
36796
37423
  const size = content.length;
36797
37424
  const header = `blob ${size}\x00`;
36798
37425
  const fullContent = Buffer.concat([Buffer.from(header), content]);
36799
- return crypto2.createHash("sha1").update(fullContent).digest("hex");
37426
+ return crypto3.createHash("sha1").update(fullContent).digest("hex");
36800
37427
  }
36801
37428
  var resolvedConfigFolder = null;
36802
37429
  async function resolveRemoteConfigFolder(githubToken) {
@@ -36858,7 +37485,7 @@ async function listRemoteFilesRecursive(dirPath, githubToken, basePath = "") {
36858
37485
  }
36859
37486
  async function computeLocalFileSha(filePath) {
36860
37487
  try {
36861
- const content = await import_fs_extra16.default.readFile(filePath);
37488
+ const content = await import_fs_extra18.default.readFile(filePath);
36862
37489
  return computeFileSha(content);
36863
37490
  } catch {
36864
37491
  return null;
@@ -36866,15 +37493,15 @@ async function computeLocalFileSha(filePath) {
36866
37493
  }
36867
37494
  async function listLocalFiles(dir) {
36868
37495
  const files = [];
36869
- if (!await import_fs_extra16.default.pathExists(dir)) {
37496
+ if (!await import_fs_extra18.default.pathExists(dir)) {
36870
37497
  return files;
36871
37498
  }
36872
- const items = await import_fs_extra16.default.readdir(dir);
37499
+ const items = await import_fs_extra18.default.readdir(dir);
36873
37500
  for (const item of items) {
36874
37501
  if (item === "node_modules" || item === ".DS_Store")
36875
37502
  continue;
36876
- const fullPath = path20.join(dir, item);
36877
- const stat = await import_fs_extra16.default.stat(fullPath).catch(() => null);
37503
+ const fullPath = path22.join(dir, item);
37504
+ const stat = await import_fs_extra18.default.stat(fullPath).catch(() => null);
36878
37505
  if (!stat)
36879
37506
  continue;
36880
37507
  if (stat.isDirectory()) {
@@ -36889,13 +37516,13 @@ async function listLocalFiles(dir) {
36889
37516
  }
36890
37517
  async function listLocalFilesRecursive(dir, basePath) {
36891
37518
  const files = [];
36892
- const items = await import_fs_extra16.default.readdir(dir).catch(() => []);
37519
+ const items = await import_fs_extra18.default.readdir(dir).catch(() => []);
36893
37520
  for (const item of items) {
36894
37521
  if (item === "node_modules" || item === ".DS_Store")
36895
37522
  continue;
36896
- const fullPath = path20.join(dir, item);
37523
+ const fullPath = path22.join(dir, item);
36897
37524
  const relativePath = `${basePath}/${item}`;
36898
- const stat = await import_fs_extra16.default.stat(fullPath).catch(() => null);
37525
+ const stat = await import_fs_extra18.default.stat(fullPath).catch(() => null);
36899
37526
  if (!stat)
36900
37527
  continue;
36901
37528
  if (stat.isDirectory()) {
@@ -36909,14 +37536,14 @@ async function listLocalFilesRecursive(dir, basePath) {
36909
37536
  return files;
36910
37537
  }
36911
37538
  async function listClaudeRealTopLevel(claudeCategoryDir) {
36912
- if (!await import_fs_extra16.default.pathExists(claudeCategoryDir))
37539
+ if (!await import_fs_extra18.default.pathExists(claudeCategoryDir))
36913
37540
  return [];
36914
- const entries = await import_fs_extra16.default.readdir(claudeCategoryDir).catch(() => []);
37541
+ const entries = await import_fs_extra18.default.readdir(claudeCategoryDir).catch(() => []);
36915
37542
  const real = [];
36916
37543
  for (const name of entries) {
36917
37544
  if (name === "node_modules" || name === ".DS_Store")
36918
37545
  continue;
36919
- const stat = await import_fs_extra16.default.lstat(path20.join(claudeCategoryDir, name)).catch(() => null);
37546
+ const stat = await import_fs_extra18.default.lstat(path22.join(claudeCategoryDir, name)).catch(() => null);
36920
37547
  if (!stat)
36921
37548
  continue;
36922
37549
  if (stat.isDirectory())
@@ -36933,7 +37560,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
36933
37560
  const items = [];
36934
37561
  const useAgents = isAgentCategory(category);
36935
37562
  const localBase = useAgents ? agentsDir : claudeDir;
36936
- const localDir = path20.join(localBase, category);
37563
+ const localDir = path22.join(localBase, category);
36937
37564
  const remoteCategoryPath = getRemoteCategoryPath(category);
36938
37565
  const remoteFiles = await listRemoteFilesRecursive(remoteCategoryPath, githubToken);
36939
37566
  const localFiles = await listLocalFiles(localDir);
@@ -36947,7 +37574,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
36947
37574
  }
36948
37575
  const localSet = new Set(localFiles);
36949
37576
  for (const [remotePath, { sha, isFolder }] of remoteSet) {
36950
- const localPath = path20.join(localDir, remotePath);
37577
+ const localPath = path22.join(localDir, remotePath);
36951
37578
  if (isFolder) {
36952
37579
  continue;
36953
37580
  }
@@ -36982,7 +37609,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
36982
37609
  for (const localPath of localSet) {
36983
37610
  agentsTopLevels.add(localPath.split("/")[0]);
36984
37611
  }
36985
- const claudeCategoryDir = path20.join(claudeDir, category);
37612
+ const claudeCategoryDir = path22.join(claudeDir, category);
36986
37613
  const claudeRealEntries = await listClaudeRealTopLevel(claudeCategoryDir);
36987
37614
  for (const top of claudeRealEntries) {
36988
37615
  if (!remoteTopLevels.has(top))
@@ -37041,13 +37668,13 @@ async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken,
37041
37668
  return false;
37042
37669
  }
37043
37670
  const content = await response.arrayBuffer();
37044
- await import_fs_extra16.default.ensureDir(path20.dirname(targetPath));
37671
+ await import_fs_extra18.default.ensureDir(path22.dirname(targetPath));
37045
37672
  if (isTextFile(relativePath)) {
37046
37673
  const textContent = Buffer.from(content).toString("utf-8");
37047
37674
  const transformedContent = transformFileContent(textContent, claudeDir);
37048
- await import_fs_extra16.default.writeFile(targetPath, transformedContent, "utf-8");
37675
+ await import_fs_extra18.default.writeFile(targetPath, transformedContent, "utf-8");
37049
37676
  } else {
37050
- await import_fs_extra16.default.writeFile(targetPath, Buffer.from(content));
37677
+ await import_fs_extra18.default.writeFile(targetPath, Buffer.from(content));
37051
37678
  }
37052
37679
  return true;
37053
37680
  } catch {
@@ -37063,27 +37690,27 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
37063
37690
  for (const item of items) {
37064
37691
  const useAgents = isAgentCategory(item.category);
37065
37692
  const baseDir = useAgents ? agentsDir : claudeDir;
37066
- const targetPath = path20.join(baseDir, item.relativePath);
37693
+ const targetPath = path22.join(baseDir, item.relativePath);
37067
37694
  if (item.status === "migration" && useAgents) {
37068
37695
  const topName = item.name.split("/")[0];
37069
- const agentsTop = path20.join(agentsDir, item.category, topName);
37070
- const claudeTop = path20.join(claudeDir, item.category, topName);
37696
+ const agentsTop = path22.join(agentsDir, item.category, topName);
37697
+ const claudeTop = path22.join(claudeDir, item.category, topName);
37071
37698
  try {
37072
- const claudeStat = await import_fs_extra16.default.lstat(claudeTop).catch(() => null);
37699
+ const claudeStat = await import_fs_extra18.default.lstat(claudeTop).catch(() => null);
37073
37700
  if (!claudeStat || claudeStat.isSymbolicLink()) {
37074
37701
  onProgress?.(item.relativePath, "skipping (no real dir to migrate)");
37075
37702
  failed++;
37076
37703
  continue;
37077
37704
  }
37078
- const agentsExists = await import_fs_extra16.default.pathExists(agentsTop);
37705
+ const agentsExists = await import_fs_extra18.default.pathExists(agentsTop);
37079
37706
  if (agentsExists) {
37080
37707
  onProgress?.(item.relativePath, "skipping (already in .agents)");
37081
37708
  failed++;
37082
37709
  continue;
37083
37710
  }
37084
37711
  onProgress?.(item.relativePath, "moving to .agents");
37085
- await import_fs_extra16.default.ensureDir(path20.dirname(agentsTop));
37086
- await import_fs_extra16.default.move(claudeTop, agentsTop);
37712
+ await import_fs_extra18.default.ensureDir(path22.dirname(agentsTop));
37713
+ await import_fs_extra18.default.move(claudeTop, agentsTop);
37087
37714
  migrated++;
37088
37715
  touchedAgentCategories.add(item.category);
37089
37716
  } catch {
@@ -37093,8 +37720,8 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
37093
37720
  }
37094
37721
  if (useAgents) {
37095
37722
  const topName = item.name.split("/")[0];
37096
- const claudeTop = path20.join(claudeDir, item.category, topName);
37097
- const claudeTopStat = await import_fs_extra16.default.lstat(claudeTop).catch(() => null);
37723
+ const claudeTop = path22.join(claudeDir, item.category, topName);
37724
+ const claudeTopStat = await import_fs_extra18.default.lstat(claudeTop).catch(() => null);
37098
37725
  if (claudeTopStat && !claudeTopStat.isSymbolicLink()) {
37099
37726
  onProgress?.(item.relativePath, "skipping (real dir in .claude)");
37100
37727
  failed++;
@@ -37104,7 +37731,7 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
37104
37731
  if (item.status === "deleted") {
37105
37732
  onProgress?.(item.relativePath, "deleting");
37106
37733
  try {
37107
- await import_fs_extra16.default.remove(targetPath);
37734
+ await import_fs_extra18.default.remove(targetPath);
37108
37735
  deleted++;
37109
37736
  if (useAgents)
37110
37737
  touchedAgentCategories.add(item.category);
@@ -37441,106 +38068,6 @@ async function proSyncCommand(options = {}) {
37441
38068
  }
37442
38069
  }
37443
38070
 
37444
- // src/lib/backup-utils.ts
37445
- var import_fs_extra17 = __toESM(require_lib4(), 1);
37446
- import path21 from "path";
37447
- import os16 from "os";
37448
- var BACKUP_BASE_DIR = path21.join(os16.homedir(), ".config", "aiblueprint", "backup");
37449
- function formatDate(date) {
37450
- const pad = (n) => n.toString().padStart(2, "0");
37451
- return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
37452
- }
37453
- async function listBackups() {
37454
- const exists = await import_fs_extra17.default.pathExists(BACKUP_BASE_DIR);
37455
- if (!exists) {
37456
- return [];
37457
- }
37458
- const entries = await import_fs_extra17.default.readdir(BACKUP_BASE_DIR, { withFileTypes: true });
37459
- const backups = [];
37460
- for (const entry of entries) {
37461
- if (!entry.isDirectory())
37462
- continue;
37463
- const match = entry.name.match(/^(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})$/);
37464
- if (!match)
37465
- continue;
37466
- const [, year, month, day, hour, minute, second] = match;
37467
- const date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second));
37468
- backups.push({
37469
- name: entry.name,
37470
- path: path21.join(BACKUP_BASE_DIR, entry.name),
37471
- date
37472
- });
37473
- }
37474
- return backups.sort((a, b3) => b3.date.getTime() - a.date.getTime());
37475
- }
37476
- var AGENTS_BACKUP_SUBDIR = ".agents";
37477
- var CLAUDE_ITEMS = ["commands", "agents", "skills", "scripts", "settings.json"];
37478
- async function copyForBackup(sourcePath, destPath) {
37479
- await import_fs_extra17.default.copy(sourcePath, destPath, {
37480
- overwrite: true,
37481
- dereference: false,
37482
- filter: async (src) => {
37483
- try {
37484
- const stat = await import_fs_extra17.default.lstat(src);
37485
- return !stat.isSymbolicLink();
37486
- } catch {
37487
- return true;
37488
- }
37489
- }
37490
- });
37491
- }
37492
- async function hasMeaningfulContent(dir) {
37493
- if (!await import_fs_extra17.default.pathExists(dir))
37494
- return false;
37495
- const files = await import_fs_extra17.default.readdir(dir);
37496
- return files.some((f) => f !== ".DS_Store");
37497
- }
37498
- async function loadBackup(backupPath, claudeDir, agentsDir) {
37499
- const exists = await import_fs_extra17.default.pathExists(backupPath);
37500
- if (!exists) {
37501
- throw new Error(`Backup not found: ${backupPath}`);
37502
- }
37503
- await import_fs_extra17.default.ensureDir(claudeDir);
37504
- for (const item of CLAUDE_ITEMS) {
37505
- const sourcePath = path21.join(backupPath, item);
37506
- const destPath = path21.join(claudeDir, item);
37507
- if (await import_fs_extra17.default.pathExists(sourcePath)) {
37508
- await copyForBackup(sourcePath, destPath);
37509
- }
37510
- }
37511
- if (agentsDir) {
37512
- const agentsBackupPath = path21.join(backupPath, AGENTS_BACKUP_SUBDIR);
37513
- if (await import_fs_extra17.default.pathExists(agentsBackupPath)) {
37514
- await import_fs_extra17.default.ensureDir(agentsDir);
37515
- await copyForBackup(agentsBackupPath, agentsDir);
37516
- }
37517
- }
37518
- }
37519
- async function createBackup(claudeDir, agentsDir) {
37520
- const claudeHasContent = await hasMeaningfulContent(claudeDir);
37521
- const agentsHasContent = agentsDir ? await hasMeaningfulContent(agentsDir) : false;
37522
- if (!claudeHasContent && !agentsHasContent) {
37523
- return null;
37524
- }
37525
- const timestamp3 = formatDate(new Date);
37526
- const backupPath = path21.join(BACKUP_BASE_DIR, timestamp3);
37527
- await import_fs_extra17.default.ensureDir(backupPath);
37528
- if (claudeHasContent) {
37529
- for (const item of CLAUDE_ITEMS) {
37530
- const sourcePath = path21.join(claudeDir, item);
37531
- const destPath = path21.join(backupPath, item);
37532
- if (await import_fs_extra17.default.pathExists(sourcePath)) {
37533
- await copyForBackup(sourcePath, destPath);
37534
- }
37535
- }
37536
- }
37537
- if (agentsHasContent && agentsDir) {
37538
- const destPath = path21.join(backupPath, AGENTS_BACKUP_SUBDIR);
37539
- await copyForBackup(agentsDir, destPath);
37540
- }
37541
- return backupPath;
37542
- }
37543
-
37544
38071
  // src/commands/backup.ts
37545
38072
  function formatBackupDate(date) {
37546
38073
  const now = new Date;
@@ -37561,7 +38088,7 @@ function formatBackupDate(date) {
37561
38088
  return `${date.toLocaleString()} (${relative})`;
37562
38089
  }
37563
38090
  async function backupLoadCommand(options = {}) {
37564
- const { claudeDir, agentsDir } = resolveFolders(options);
38091
+ const { claudeDir, codexDir, agentsDir } = resolveFolders(options);
37565
38092
  Ie(source_default.blue("\uD83D\uDCE6 Load Backup"));
37566
38093
  const spinner = Y2();
37567
38094
  spinner.start("Scanning for backups...");
@@ -37597,7 +38124,7 @@ async function backupLoadCommand(options = {}) {
37597
38124
  process.exit(0);
37598
38125
  }
37599
38126
  spinner.start("Creating backup of current configuration...");
37600
- const currentBackup = await createBackup(claudeDir, agentsDir);
38127
+ const currentBackup = await createBackup(claudeDir, codexDir, agentsDir);
37601
38128
  if (currentBackup) {
37602
38129
  spinner.stop(`Current config backed up to: ${source_default.gray(currentBackup)}`);
37603
38130
  } else {
@@ -37605,7 +38132,7 @@ async function backupLoadCommand(options = {}) {
37605
38132
  }
37606
38133
  spinner.start("Restoring backup...");
37607
38134
  try {
37608
- await loadBackup(selected.path, claudeDir, agentsDir);
38135
+ await loadBackup(selected.path, claudeDir, codexDir, agentsDir);
37609
38136
  spinner.stop("Backup restored successfully");
37610
38137
  M2.success(`Restored configuration from ${source_default.cyan(selected.name)}`);
37611
38138
  Se(source_default.green("✅ Backup loaded successfully"));
@@ -37642,7 +38169,7 @@ function printSnapshots(title, snapshots) {
37642
38169
  }
37643
38170
  async function configsSaveCommand(name, options = {}) {
37644
38171
  try {
37645
- console.log(source_default.gray("Saving .claude, .codex, and .agents config files..."));
38172
+ console.log(source_default.gray("Saving full .claude, .codex, and .agents folders..."));
37646
38173
  const snapshotPath = await saveNamedConfig(name, options);
37647
38174
  console.log(source_default.green(`Saved config "${name}"`));
37648
38175
  console.log(source_default.gray(snapshotPath));
@@ -37718,19 +38245,19 @@ async function configsBackupsCreateCommand(reason, options = {}) {
37718
38245
  }
37719
38246
 
37720
38247
  // src/commands/openclaw-pro.ts
37721
- import os19 from "os";
37722
- import path24 from "path";
38248
+ import os20 from "os";
38249
+ import path25 from "path";
37723
38250
 
37724
38251
  // src/lib/openclaw-installer.ts
37725
- var import_fs_extra18 = __toESM(require_lib4(), 1);
37726
- import os17 from "os";
37727
- import path22 from "path";
38252
+ var import_fs_extra19 = __toESM(require_lib4(), 1);
38253
+ import os18 from "os";
38254
+ import path23 from "path";
37728
38255
  import { exec as exec4 } from "child_process";
37729
38256
  import { promisify as promisify3 } from "util";
37730
38257
  var execAsync3 = promisify3(exec4);
37731
38258
  var OPENCLAW_PRO_REPO = "Melvynx/openclawpro";
37732
38259
  function getCacheRepoDir2() {
37733
- return path22.join(os17.homedir(), ".config", "openclaw", "pro-repos", "openclawpro");
38260
+ return path23.join(os18.homedir(), ".config", "openclaw", "pro-repos", "openclawpro");
37734
38261
  }
37735
38262
  async function execGitWithAuth2(command, token, repoUrl, cwd) {
37736
38263
  const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
@@ -37744,33 +38271,33 @@ async function execGitWithAuth2(command, token, repoUrl, cwd) {
37744
38271
  async function cloneOrUpdateRepo2(token) {
37745
38272
  const cacheDir = getCacheRepoDir2();
37746
38273
  const repoUrl = `https://github.com/${OPENCLAW_PRO_REPO}.git`;
37747
- if (await import_fs_extra18.default.pathExists(path22.join(cacheDir, ".git"))) {
38274
+ if (await import_fs_extra19.default.pathExists(path23.join(cacheDir, ".git"))) {
37748
38275
  try {
37749
38276
  await execGitWithAuth2("pull", token, repoUrl, cacheDir);
37750
38277
  } catch (error) {
37751
- await import_fs_extra18.default.remove(cacheDir);
37752
- await import_fs_extra18.default.ensureDir(path22.dirname(cacheDir));
38278
+ await import_fs_extra19.default.remove(cacheDir);
38279
+ await import_fs_extra19.default.ensureDir(path23.dirname(cacheDir));
37753
38280
  await execGitWithAuth2(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
37754
38281
  }
37755
38282
  } else {
37756
- await import_fs_extra18.default.ensureDir(path22.dirname(cacheDir));
38283
+ await import_fs_extra19.default.ensureDir(path23.dirname(cacheDir));
37757
38284
  await execGitWithAuth2(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
37758
38285
  }
37759
- return path22.join(cacheDir, "openclaw-config");
38286
+ return path23.join(cacheDir, "openclaw-config");
37760
38287
  }
37761
38288
  async function copyConfigFromCache2(cacheConfigDir, targetDir, onProgress) {
37762
38289
  const walk = async (dir, baseDir = dir) => {
37763
- const entries = await import_fs_extra18.default.readdir(dir, { withFileTypes: true });
38290
+ const entries = await import_fs_extra19.default.readdir(dir, { withFileTypes: true });
37764
38291
  for (const entry of entries) {
37765
- const sourcePath = path22.join(dir, entry.name);
37766
- const relativePath = path22.relative(baseDir, sourcePath);
37767
- const targetPath = path22.join(targetDir, relativePath);
38292
+ const sourcePath = path23.join(dir, entry.name);
38293
+ const relativePath = path23.relative(baseDir, sourcePath);
38294
+ const targetPath = path23.join(targetDir, relativePath);
37768
38295
  if (entry.isDirectory()) {
37769
- await import_fs_extra18.default.ensureDir(targetPath);
38296
+ await import_fs_extra19.default.ensureDir(targetPath);
37770
38297
  onProgress?.(relativePath, "directory");
37771
38298
  await walk(sourcePath, baseDir);
37772
38299
  } else {
37773
- await import_fs_extra18.default.copy(sourcePath, targetPath, { overwrite: true });
38300
+ await import_fs_extra19.default.copy(sourcePath, targetPath, { overwrite: true });
37774
38301
  onProgress?.(relativePath, "file");
37775
38302
  }
37776
38303
  }
@@ -37779,7 +38306,7 @@ async function copyConfigFromCache2(cacheConfigDir, targetDir, onProgress) {
37779
38306
  }
37780
38307
  async function installOpenclawProConfigs(options) {
37781
38308
  const { githubToken, openclawFolder, onProgress } = options;
37782
- const targetFolder = openclawFolder || path22.join(os17.homedir(), ".openclaw");
38309
+ const targetFolder = openclawFolder || path23.join(os18.homedir(), ".openclaw");
37783
38310
  try {
37784
38311
  const cacheConfigDir = await cloneOrUpdateRepo2(githubToken);
37785
38312
  await copyConfigFromCache2(cacheConfigDir, targetFolder, onProgress);
@@ -37790,28 +38317,28 @@ async function installOpenclawProConfigs(options) {
37790
38317
  }
37791
38318
 
37792
38319
  // src/lib/openclaw-token-storage.ts
37793
- var import_fs_extra19 = __toESM(require_lib4(), 1);
37794
- import os18 from "os";
37795
- import path23 from "path";
38320
+ var import_fs_extra20 = __toESM(require_lib4(), 1);
38321
+ import os19 from "os";
38322
+ import path24 from "path";
37796
38323
  function getConfigDir2() {
37797
- const platform = os18.platform();
38324
+ const platform = os19.platform();
37798
38325
  if (platform === "win32") {
37799
- return path23.join(process.env.APPDATA || os18.homedir(), "openclaw");
38326
+ return path24.join(process.env.APPDATA || os19.homedir(), "openclaw");
37800
38327
  }
37801
- return path23.join(os18.homedir(), ".config", "openclaw");
38328
+ return path24.join(os19.homedir(), ".config", "openclaw");
37802
38329
  }
37803
38330
  function getTokenPath() {
37804
- return path23.join(getConfigDir2(), "token.txt");
38331
+ return path24.join(getConfigDir2(), "token.txt");
37805
38332
  }
37806
38333
  async function saveOpenclawToken(githubToken) {
37807
38334
  const configDir = getConfigDir2();
37808
- await import_fs_extra19.default.ensureDir(configDir);
37809
- await import_fs_extra19.default.writeFile(getTokenPath(), githubToken, { mode: 384 });
38335
+ await import_fs_extra20.default.ensureDir(configDir);
38336
+ await import_fs_extra20.default.writeFile(getTokenPath(), githubToken, { mode: 384 });
37810
38337
  }
37811
38338
  async function getOpenclawToken() {
37812
38339
  const tokenPath = getTokenPath();
37813
- if (await import_fs_extra19.default.pathExists(tokenPath)) {
37814
- const token = await import_fs_extra19.default.readFile(tokenPath, "utf8");
38340
+ if (await import_fs_extra20.default.pathExists(tokenPath)) {
38341
+ const token = await import_fs_extra20.default.readFile(tokenPath, "utf8");
37815
38342
  return token.trim();
37816
38343
  }
37817
38344
  return null;
@@ -37819,12 +38346,12 @@ async function getOpenclawToken() {
37819
38346
  function getOpenclawTokenInfo() {
37820
38347
  return {
37821
38348
  path: getTokenPath(),
37822
- platform: os18.platform()
38349
+ platform: os19.platform()
37823
38350
  };
37824
38351
  }
37825
38352
 
37826
38353
  // src/commands/openclaw-pro.ts
37827
- var import_fs_extra20 = __toESM(require_lib4(), 1);
38354
+ var import_fs_extra21 = __toESM(require_lib4(), 1);
37828
38355
  var API_URL2 = "https://codeline.app/api/products";
37829
38356
  var OPENCLAW_PRODUCT_ID = "prd_t2GRwX3aH1";
37830
38357
  var CLAUDE_CODE_TOOLS_INSTRUCTIONS = `
@@ -37931,7 +38458,7 @@ async function openclawProSetupCommand(options = {}) {
37931
38458
  Se(source_default.red("❌ Not activated"));
37932
38459
  process.exit(1);
37933
38460
  }
37934
- const openclawDir = options.folder ? path24.resolve(options.folder) : path24.join(os19.homedir(), ".openclaw");
38461
+ const openclawDir = options.folder ? path25.resolve(options.folder) : path25.join(os20.homedir(), ".openclaw");
37935
38462
  const spinner = Y2();
37936
38463
  const onProgress = (file, type) => {
37937
38464
  spinner.message(`Installing: ${source_default.cyan(file)} ${source_default.gray(`(${type})`)}`);
@@ -37944,23 +38471,23 @@ async function openclawProSetupCommand(options = {}) {
37944
38471
  });
37945
38472
  spinner.stop("OpenClaw Pro configurations installed");
37946
38473
  let skillCount = 0;
37947
- const skillsDir = path24.join(openclawDir, "skills");
37948
- if (await import_fs_extra20.default.pathExists(skillsDir)) {
37949
- const items = await import_fs_extra20.default.readdir(skillsDir);
38474
+ const skillsDir = path25.join(openclawDir, "skills");
38475
+ if (await import_fs_extra21.default.pathExists(skillsDir)) {
38476
+ const items = await import_fs_extra21.default.readdir(skillsDir);
37950
38477
  const dirs = await Promise.all(items.map(async (item) => {
37951
- const stat = await import_fs_extra20.default.stat(path24.join(skillsDir, item));
38478
+ const stat = await import_fs_extra21.default.stat(path25.join(skillsDir, item));
37952
38479
  return stat.isDirectory();
37953
38480
  }));
37954
38481
  skillCount = dirs.filter(Boolean).length;
37955
38482
  }
37956
38483
  spinner.start("Setting up workspace TOOLS.md...");
37957
- const workspaceDir = path24.join(openclawDir, "workspace");
37958
- const toolsPath = path24.join(workspaceDir, "TOOLS.md");
37959
- await import_fs_extra20.default.ensureDir(workspaceDir);
37960
- if (await import_fs_extra20.default.pathExists(toolsPath)) {
37961
- const existingContent = await import_fs_extra20.default.readFile(toolsPath, "utf-8");
38484
+ const workspaceDir = path25.join(openclawDir, "workspace");
38485
+ const toolsPath = path25.join(workspaceDir, "TOOLS.md");
38486
+ await import_fs_extra21.default.ensureDir(workspaceDir);
38487
+ if (await import_fs_extra21.default.pathExists(toolsPath)) {
38488
+ const existingContent = await import_fs_extra21.default.readFile(toolsPath, "utf-8");
37962
38489
  if (!existingContent.includes("Claude Code CLI")) {
37963
- await import_fs_extra20.default.appendFile(toolsPath, `
38490
+ await import_fs_extra21.default.appendFile(toolsPath, `
37964
38491
 
37965
38492
  ` + CLAUDE_CODE_TOOLS_INSTRUCTIONS);
37966
38493
  spinner.stop("TOOLS.md updated with Claude Code instructions");
@@ -37974,7 +38501,7 @@ Skills define _how_ tools work. This file is for _your_ specifics — the stuff
37974
38501
 
37975
38502
  ${CLAUDE_CODE_TOOLS_INSTRUCTIONS}
37976
38503
  `;
37977
- await import_fs_extra20.default.writeFile(toolsPath, defaultToolsMd);
38504
+ await import_fs_extra21.default.writeFile(toolsPath, defaultToolsMd);
37978
38505
  spinner.stop("TOOLS.md created with Claude Code instructions");
37979
38506
  }
37980
38507
  spinner.start("Creating claude-run wrapper...");
@@ -37985,9 +38512,9 @@ ${CLAUDE_CODE_TOOLS_INSTRUCTIONS}
37985
38512
  script -q -c "claude $*" /dev/null
37986
38513
  `;
37987
38514
  const binDir = "/usr/local/bin";
37988
- const wrapperPath = path24.join(binDir, "claude-run");
38515
+ const wrapperPath = path25.join(binDir, "claude-run");
37989
38516
  try {
37990
- await import_fs_extra20.default.writeFile(wrapperPath, claudeRunWrapper, { mode: 493 });
38517
+ await import_fs_extra21.default.writeFile(wrapperPath, claudeRunWrapper, { mode: 493 });
37991
38518
  spinner.stop("claude-run wrapper created");
37992
38519
  } catch {
37993
38520
  spinner.stop("claude-run wrapper skipped (no write access to /usr/local/bin)");
@@ -38036,12 +38563,12 @@ async function openclawProUpdateCommand(options = {}) {
38036
38563
  }
38037
38564
 
38038
38565
  // src/commands/dynamic-scripts.ts
38039
- import path27 from "path";
38566
+ import path28 from "path";
38040
38567
  import { homedir } from "os";
38041
38568
 
38042
38569
  // src/lib/script-parser.ts
38043
- var import_fs_extra21 = __toESM(require_lib4(), 1);
38044
- import path25 from "path";
38570
+ var import_fs_extra22 = __toESM(require_lib4(), 1);
38571
+ import path26 from "path";
38045
38572
  var EXCLUDED_SCRIPTS = ["test", "lint", "format", "start"];
38046
38573
  var EXCLUDED_SUFFIXES = [":test", ":lint", ":test-fixtures", ":start"];
38047
38574
  function shouldIncludeScript(scriptName) {
@@ -38052,12 +38579,12 @@ function shouldIncludeScript(scriptName) {
38052
38579
  return true;
38053
38580
  }
38054
38581
  async function readScriptsPackageJson(claudeDir) {
38055
- const packageJsonPath = path25.join(claudeDir, "scripts", "package.json");
38582
+ const packageJsonPath = path26.join(claudeDir, "scripts", "package.json");
38056
38583
  try {
38057
- if (!await import_fs_extra21.default.pathExists(packageJsonPath)) {
38584
+ if (!await import_fs_extra22.default.pathExists(packageJsonPath)) {
38058
38585
  return null;
38059
38586
  }
38060
- const content = await import_fs_extra21.default.readFile(packageJsonPath, "utf-8");
38587
+ const content = await import_fs_extra22.default.readFile(packageJsonPath, "utf-8");
38061
38588
  const parsed = JSON.parse(content);
38062
38589
  return parsed.scripts || null;
38063
38590
  } catch (error) {
@@ -38101,14 +38628,14 @@ function groupScriptsByPrefix(commands) {
38101
38628
  }
38102
38629
 
38103
38630
  // src/commands/script-runner.ts
38104
- var import_fs_extra22 = __toESM(require_lib4(), 1);
38631
+ var import_fs_extra23 = __toESM(require_lib4(), 1);
38105
38632
  import { spawn as spawn2 } from "child_process";
38106
38633
  import { execSync as execSync4 } from "child_process";
38107
- import path26 from "path";
38108
- import os20 from "os";
38634
+ import path27 from "path";
38635
+ import os21 from "os";
38109
38636
  function checkCommand2(cmd) {
38110
38637
  try {
38111
- const isWindows2 = os20.platform() === "win32";
38638
+ const isWindows2 = os21.platform() === "win32";
38112
38639
  const whichCmd = isWindows2 ? `where ${cmd}` : `which ${cmd}`;
38113
38640
  execSync4(whichCmd, { stdio: "ignore" });
38114
38641
  return true;
@@ -38134,18 +38661,18 @@ async function executeScript(scriptName, claudeDir) {
38134
38661
  console.error(source_default.red("Bun is not installed. Install with: npm install -g bun"));
38135
38662
  return 1;
38136
38663
  }
38137
- const scriptsDir = path26.join(claudeDir, "scripts");
38138
- if (!await import_fs_extra22.default.pathExists(scriptsDir)) {
38664
+ const scriptsDir = path27.join(claudeDir, "scripts");
38665
+ if (!await import_fs_extra23.default.pathExists(scriptsDir)) {
38139
38666
  console.error(source_default.red(`Scripts directory not found at ${scriptsDir}`));
38140
38667
  console.log(source_default.gray("Run: aiblueprint agents setup"));
38141
38668
  return 1;
38142
38669
  }
38143
- const packageJsonPath = path26.join(scriptsDir, "package.json");
38144
- if (!await import_fs_extra22.default.pathExists(packageJsonPath)) {
38670
+ const packageJsonPath = path27.join(scriptsDir, "package.json");
38671
+ if (!await import_fs_extra23.default.pathExists(packageJsonPath)) {
38145
38672
  console.error(source_default.red(`package.json not found in ${scriptsDir}`));
38146
38673
  return 1;
38147
38674
  }
38148
- const packageJson = await import_fs_extra22.default.readJson(packageJsonPath);
38675
+ const packageJson = await import_fs_extra23.default.readJson(packageJsonPath);
38149
38676
  if (!packageJson.scripts || !packageJson.scripts[scriptName]) {
38150
38677
  console.error(source_default.red(`Script "${scriptName}" not found in package.json`));
38151
38678
  return 1;
@@ -38168,7 +38695,7 @@ async function executeScript(scriptName, claudeDir) {
38168
38695
 
38169
38696
  // src/commands/dynamic-scripts.ts
38170
38697
  function getClaudeDir(parentOptions) {
38171
- return parentOptions.claudeCodeFolder || parentOptions.folder ? path27.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path27.join(homedir(), ".claude");
38698
+ return parentOptions.claudeCodeFolder || parentOptions.folder ? path28.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path28.join(homedir(), ".claude");
38172
38699
  }
38173
38700
  async function registerDynamicScriptCommands(claudeCodeCmd, claudeDir) {
38174
38701
  const scripts = await readScriptsPackageJson(claudeDir);
@@ -38230,13 +38757,21 @@ function registerAgentsCommands(cmd) {
38230
38757
  codexFolder: parentOptions.codexFolder
38231
38758
  });
38232
38759
  });
38233
- cmd.command("unify").description("Unify skills and agents into .agents, then render Codex TOML agents").action((options, command) => {
38760
+ cmd.command("unify [scope]").description("Unify agent configuration into .agents (scope: global or repository; default: global)").action((scope, options, command) => {
38234
38761
  const parentOptions = command.parent.opts();
38762
+ const selectedScope = scope ?? "global";
38763
+ if (selectedScope !== "global" && selectedScope !== "repository") {
38764
+ console.error(source_default.red(`Invalid unify scope: ${selectedScope}`));
38765
+ console.error(source_default.gray("Use `global` or `repository`."));
38766
+ process.exitCode = 1;
38767
+ return;
38768
+ }
38235
38769
  return agentsUnifyCommand({
38236
- folder: parentOptions.folder,
38770
+ folder: parentOptions.folder ?? (selectedScope === "repository" ? process.cwd() : undefined),
38237
38771
  claudeCodeFolder: parentOptions.claudeCodeFolder,
38238
38772
  codexFolder: parentOptions.codexFolder,
38239
- agentsFolder: parentOptions.agentsFolder
38773
+ agentsFolder: parentOptions.agentsFolder,
38774
+ scope: selectedScope
38240
38775
  });
38241
38776
  });
38242
38777
  cmd.command("codex-agents").description("Render shared Markdown agents from .agents/agents into Codex TOML custom agents").option("--overwrite", "Overwrite existing non-generated Codex agent files").action((options, command) => {
@@ -38249,6 +38784,12 @@ function registerAgentsCommands(cmd) {
38249
38784
  overwrite: options.overwrite
38250
38785
  });
38251
38786
  });
38787
+ const configCmd = cmd.command("config").description("Manage cross-tool agent configuration data");
38788
+ const configUnifyCmd = configCmd.command("unify").description("Merge saved configuration data back into the current folders");
38789
+ configUnifyCmd.command("sessions").description("Import saved session history from configs and backups into current .claude/.codex/.agents folders").action((options, command) => {
38790
+ const folderOptions = readConfigOptions(command, options);
38791
+ return sessionsUnifyCommand(folderOptions);
38792
+ });
38252
38793
  const proCmd = cmd.command("pro").description("Manage AIBlueprint CLI Premium features");
38253
38794
  proCmd.command("activate [token]").description("Activate AIBlueprint CLI Premium with your access token").action((token) => {
38254
38795
  proActivateCommand(token);
@@ -38289,6 +38830,7 @@ function registerAgentsCommands(cmd) {
38289
38830
  backupLoadCommand({
38290
38831
  folder: parentOptions.folder,
38291
38832
  claudeCodeFolder: parentOptions.claudeCodeFolder,
38833
+ codexFolder: parentOptions.codexFolder,
38292
38834
  agentsFolder: parentOptions.agentsFolder
38293
38835
  });
38294
38836
  });
@@ -38297,13 +38839,21 @@ function addConfigFolderOptions(cmd) {
38297
38839
  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)");
38298
38840
  }
38299
38841
  function readConfigOptions(command, options = {}) {
38300
- const parentOptions = command.parent?.opts() ?? {};
38301
- const grandParentOptions = command.parent?.parent?.opts() ?? {};
38842
+ const optionChain = [options];
38843
+ let current = command;
38844
+ while (current) {
38845
+ optionChain.push(current.opts());
38846
+ current = current.parent ?? null;
38847
+ }
38848
+ const findOption = (name) => {
38849
+ const value = optionChain.find((opts) => opts[name] !== undefined)?.[name];
38850
+ return typeof value === "string" ? value : undefined;
38851
+ };
38302
38852
  return {
38303
- folder: options.folder ?? parentOptions.folder ?? grandParentOptions.folder,
38304
- claudeCodeFolder: options.claudeCodeFolder ?? parentOptions.claudeCodeFolder ?? grandParentOptions.claudeCodeFolder,
38305
- codexFolder: options.codexFolder ?? parentOptions.codexFolder ?? grandParentOptions.codexFolder,
38306
- agentsFolder: options.agentsFolder ?? parentOptions.agentsFolder ?? grandParentOptions.agentsFolder
38853
+ folder: findOption("folder"),
38854
+ claudeCodeFolder: findOption("claudeCodeFolder"),
38855
+ codexFolder: findOption("codexFolder"),
38856
+ agentsFolder: findOption("agentsFolder")
38307
38857
  };
38308
38858
  }
38309
38859
  var agentsCmd = program2.command("agents").description("AI coding configuration commands");