aiblueprint-cli 1.4.57 → 1.4.59

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 +3 -0
  2. package/dist/cli.js +717 -228
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -33587,6 +33587,46 @@ async function mergeCodexConfigFile(sourceConfigPath, codexDir) {
33587
33587
  // src/lib/configs-store.ts
33588
33588
  var import_fs_extra7 = __toESM(require_lib4(), 1);
33589
33589
  import path11 from "path";
33590
+ var COMMON_EXCLUDED_NAMES = new Set([
33591
+ ".git",
33592
+ ".DS_Store",
33593
+ "node_modules"
33594
+ ]);
33595
+ var EXCLUDED_RUNTIME_PATHS = {
33596
+ ".claude": new Set([
33597
+ "backups",
33598
+ "cache",
33599
+ "debug",
33600
+ "file-history",
33601
+ "logs",
33602
+ "output",
33603
+ "paste-cache",
33604
+ "plugins/cache",
33605
+ "projects",
33606
+ "session-env",
33607
+ "sessions",
33608
+ "stats-cache.json",
33609
+ "security.log"
33610
+ ]),
33611
+ ".codex": new Set([
33612
+ "archived_sessions",
33613
+ "browser/sessions",
33614
+ "cache",
33615
+ "log",
33616
+ "logs_2.sqlite",
33617
+ "logs_2.sqlite-shm",
33618
+ "logs_2.sqlite-wal",
33619
+ "models_cache.json",
33620
+ "plugins/cache",
33621
+ "sessions",
33622
+ "vendor_imports/skills-curated-cache.json"
33623
+ ]),
33624
+ ".agents": new Set([
33625
+ "cache",
33626
+ "logs",
33627
+ "sessions"
33628
+ ])
33629
+ };
33590
33630
  function getConfigStorePaths(rootDir) {
33591
33631
  const baseDir = path11.join(rootDir, ".aiblueprint");
33592
33632
  return {
@@ -33633,14 +33673,33 @@ async function hasContent(folderPath) {
33633
33673
  const entries = await import_fs_extra7.default.readdir(folderPath);
33634
33674
  return entries.some((entry) => entry !== ".DS_Store");
33635
33675
  }
33636
- async function copyManagedFolder(source, destination) {
33676
+ function normalizeRelativePath(relativePath) {
33677
+ return relativePath.split(path11.sep).join("/");
33678
+ }
33679
+ function shouldCopyManagedPath(folderName, sourceRoot, sourcePath) {
33680
+ const basename = path11.basename(sourcePath);
33681
+ if (COMMON_EXCLUDED_NAMES.has(basename))
33682
+ return false;
33683
+ const relativePath = normalizeRelativePath(path11.relative(sourceRoot, sourcePath));
33684
+ if (!relativePath)
33685
+ return true;
33686
+ const excludedPaths = EXCLUDED_RUNTIME_PATHS[folderName];
33687
+ if (excludedPaths.has(relativePath))
33688
+ return false;
33689
+ for (const excludedPath of excludedPaths) {
33690
+ if (relativePath.startsWith(`${excludedPath}/`))
33691
+ return false;
33692
+ }
33693
+ return true;
33694
+ }
33695
+ async function copyManagedFolder(name, source, destination) {
33637
33696
  await import_fs_extra7.default.copy(source, destination, {
33638
33697
  overwrite: true,
33639
33698
  dereference: false,
33640
33699
  filter: async (src) => {
33641
33700
  try {
33642
33701
  const stat = await import_fs_extra7.default.lstat(src);
33643
- return !stat.isSymbolicLink();
33702
+ return !stat.isSymbolicLink() && shouldCopyManagedPath(name, source, src);
33644
33703
  } catch {
33645
33704
  return true;
33646
33705
  }
@@ -33676,7 +33735,7 @@ async function snapshotByCopy(snapshotPath, folders, metadata) {
33676
33735
  for (const folder of managedFolders(folders)) {
33677
33736
  if (!await hasContent(folder.path))
33678
33737
  continue;
33679
- await copyManagedFolder(folder.path, path11.join(snapshotPath, folder.name));
33738
+ await copyManagedFolder(folder.name, folder.path, path11.join(snapshotPath, folder.name));
33680
33739
  copied.push(folder.name);
33681
33740
  }
33682
33741
  if (copied.length === 0) {
@@ -33769,7 +33828,7 @@ async function restoreSnapshot(snapshotPath, folders) {
33769
33828
  if (!await import_fs_extra7.default.pathExists(source))
33770
33829
  continue;
33771
33830
  await import_fs_extra7.default.ensureDir(path11.dirname(folder.path));
33772
- await copyManagedFolder(source, folder.path);
33831
+ await copyManagedFolder(folder.name, source, folder.path);
33773
33832
  restored.push(folder.name);
33774
33833
  }
33775
33834
  return restored;
@@ -34651,6 +34710,433 @@ async function symlinkCommand(params = {}) {
34651
34710
  }
34652
34711
  }
34653
34712
 
34713
+ // src/lib/agents-unifier.ts
34714
+ var import_fs_extra11 = __toESM(require_lib4(), 1);
34715
+ import crypto from "crypto";
34716
+ import os13 from "os";
34717
+ import path15 from "path";
34718
+ var IGNORED_ENTRY_NAMES = new Set([
34719
+ ".DS_Store",
34720
+ ".git",
34721
+ "node_modules"
34722
+ ]);
34723
+ function uniqueByPath(candidates) {
34724
+ const seen = new Set;
34725
+ const unique = [];
34726
+ for (const candidate of candidates) {
34727
+ const resolved = path15.resolve(candidate.path);
34728
+ if (seen.has(resolved))
34729
+ continue;
34730
+ seen.add(resolved);
34731
+ unique.push({ ...candidate, path: resolved });
34732
+ }
34733
+ return unique;
34734
+ }
34735
+ function getContainerCandidates(options) {
34736
+ const folders = resolveFolders(options);
34737
+ const cursorDir = path15.join(folders.rootDir, ".cursor");
34738
+ const factoryDir = path15.join(folders.rootDir, ".factory");
34739
+ const opencodeDir = path15.join(folders.rootDir, ".config", "opencode");
34740
+ return uniqueByPath([
34741
+ {
34742
+ category: "skills",
34743
+ label: "agents-skills",
34744
+ path: path15.join(folders.agentsDir, "skills"),
34745
+ isDestination: true
34746
+ },
34747
+ {
34748
+ category: "skills",
34749
+ label: "claude-skills",
34750
+ path: path15.join(folders.claudeDir, "skills"),
34751
+ linkWhenMissing: true
34752
+ },
34753
+ {
34754
+ category: "skills",
34755
+ label: "codex-skills",
34756
+ path: path15.join(folders.codexDir, "skills"),
34757
+ linkWhenMissing: true
34758
+ },
34759
+ {
34760
+ category: "skills",
34761
+ label: "cursor-skills",
34762
+ path: path15.join(cursorDir, "skills"),
34763
+ linkWhenParentExists: true
34764
+ },
34765
+ {
34766
+ category: "skills",
34767
+ label: "cursor-skills-cursor",
34768
+ path: path15.join(cursorDir, "skills-cursor"),
34769
+ linkWhenParentExists: true
34770
+ },
34771
+ {
34772
+ category: "skills",
34773
+ label: "factory-skills",
34774
+ path: path15.join(factoryDir, "skills"),
34775
+ linkWhenParentExists: true
34776
+ },
34777
+ {
34778
+ category: "skills",
34779
+ label: "opencode-skill",
34780
+ path: path15.join(opencodeDir, "skill"),
34781
+ linkWhenParentExists: true
34782
+ },
34783
+ {
34784
+ category: "skills",
34785
+ label: "opencode-skills",
34786
+ path: path15.join(opencodeDir, "skills"),
34787
+ linkWhenParentExists: true
34788
+ },
34789
+ {
34790
+ category: "agents",
34791
+ label: "agents-agents",
34792
+ path: path15.join(folders.agentsDir, "agents"),
34793
+ isDestination: true
34794
+ },
34795
+ {
34796
+ category: "agents",
34797
+ label: "claude-agents",
34798
+ path: path15.join(folders.claudeDir, "agents"),
34799
+ linkWhenMissing: true
34800
+ },
34801
+ {
34802
+ category: "agents",
34803
+ label: "claude-agnets",
34804
+ path: path15.join(folders.claudeDir, "agnets")
34805
+ },
34806
+ {
34807
+ category: "agents",
34808
+ label: "codex-agents",
34809
+ path: path15.join(folders.codexDir, "agents"),
34810
+ linkWhenMissing: true
34811
+ },
34812
+ {
34813
+ category: "agents",
34814
+ label: "cursor-agents",
34815
+ path: path15.join(cursorDir, "agents"),
34816
+ linkWhenParentExists: true
34817
+ },
34818
+ {
34819
+ category: "agents",
34820
+ label: "factory-droids",
34821
+ path: path15.join(factoryDir, "droids"),
34822
+ linkWhenParentExists: true
34823
+ },
34824
+ {
34825
+ category: "agents",
34826
+ label: "opencode-agent",
34827
+ path: path15.join(opencodeDir, "agent"),
34828
+ linkWhenParentExists: true
34829
+ },
34830
+ {
34831
+ category: "agents",
34832
+ label: "opencode-agents",
34833
+ path: path15.join(opencodeDir, "agents"),
34834
+ linkWhenParentExists: true
34835
+ }
34836
+ ]);
34837
+ }
34838
+ function shouldCollectEntry(category, entry) {
34839
+ if (IGNORED_ENTRY_NAMES.has(entry.name))
34840
+ return false;
34841
+ if (category === "skills" && entry.name === ".cursor-managed-skills-manifest.json") {
34842
+ return true;
34843
+ }
34844
+ return entry.isFile() || entry.isDirectory() || entry.isSymbolicLink();
34845
+ }
34846
+ async function pathExistsOrSymlink(targetPath) {
34847
+ const stat = await import_fs_extra11.default.lstat(targetPath).catch(() => null);
34848
+ return Boolean(stat);
34849
+ }
34850
+ async function realPathIfPossible(targetPath) {
34851
+ try {
34852
+ return await import_fs_extra11.default.realpath(targetPath);
34853
+ } catch {
34854
+ return null;
34855
+ }
34856
+ }
34857
+ function samePath(a, b) {
34858
+ return path15.resolve(a) === path15.resolve(b);
34859
+ }
34860
+ function hashString(value) {
34861
+ return crypto.createHash("sha256").update(value).digest("hex");
34862
+ }
34863
+ async function hashPath(targetPath) {
34864
+ const stat = await import_fs_extra11.default.lstat(targetPath);
34865
+ if (stat.isSymbolicLink()) {
34866
+ const linkTarget = await import_fs_extra11.default.readlink(targetPath);
34867
+ return hashString(`symlink:${linkTarget}`);
34868
+ }
34869
+ if (stat.isFile()) {
34870
+ const fileHash = crypto.createHash("sha256");
34871
+ fileHash.update("file:");
34872
+ fileHash.update(await import_fs_extra11.default.readFile(targetPath));
34873
+ return fileHash.digest("hex");
34874
+ }
34875
+ if (stat.isDirectory()) {
34876
+ const entries = (await import_fs_extra11.default.readdir(targetPath, { withFileTypes: true })).filter((entry) => !IGNORED_ENTRY_NAMES.has(entry.name)).sort((a, b) => a.name.localeCompare(b.name));
34877
+ const dirHash = crypto.createHash("sha256");
34878
+ dirHash.update("dir:");
34879
+ for (const entry of entries) {
34880
+ dirHash.update(entry.name);
34881
+ dirHash.update("\x00");
34882
+ dirHash.update(await hashPath(path15.join(targetPath, entry.name)));
34883
+ dirHash.update("\x00");
34884
+ }
34885
+ return dirHash.digest("hex");
34886
+ }
34887
+ return hashString(`other:${stat.mode}:${stat.size}`);
34888
+ }
34889
+ function suffixFromLabel(label) {
34890
+ return label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "source";
34891
+ }
34892
+ function nameWithSuffix(name, suffix, index) {
34893
+ const parsed = path15.parse(name);
34894
+ const numberedSuffix = index === 1 ? suffix : `${suffix}-${index}`;
34895
+ if (parsed.ext && parsed.name) {
34896
+ return `${parsed.name}--${numberedSuffix}${parsed.ext}`;
34897
+ }
34898
+ return `${name}--${numberedSuffix}`;
34899
+ }
34900
+ async function findTargetName(destinationDir, originalName, label) {
34901
+ const suffix = suffixFromLabel(label);
34902
+ let index = 1;
34903
+ while (true) {
34904
+ const candidate = nameWithSuffix(originalName, suffix, index);
34905
+ if (!await pathExistsOrSymlink(path15.join(destinationDir, candidate))) {
34906
+ return candidate;
34907
+ }
34908
+ index++;
34909
+ }
34910
+ }
34911
+ async function addExistingDestinationHashes(destinationDir, knownHashes) {
34912
+ if (!await import_fs_extra11.default.pathExists(destinationDir))
34913
+ return;
34914
+ const entries = await import_fs_extra11.default.readdir(destinationDir, { withFileTypes: true });
34915
+ for (const entry of entries) {
34916
+ if (IGNORED_ENTRY_NAMES.has(entry.name))
34917
+ continue;
34918
+ const entryPath = path15.join(destinationDir, entry.name);
34919
+ knownHashes.set(await hashPath(entryPath), entry.name);
34920
+ }
34921
+ }
34922
+ async function importCategoryEntries(category, candidates, destinationDir, result) {
34923
+ await import_fs_extra11.default.ensureDir(destinationDir);
34924
+ const destinationRealPath = await realPathIfPossible(destinationDir);
34925
+ const knownHashes = new Map;
34926
+ await addExistingDestinationHashes(destinationDir, knownHashes);
34927
+ for (const candidate of candidates) {
34928
+ if (candidate.category !== category || candidate.isDestination)
34929
+ continue;
34930
+ const candidateStat = await import_fs_extra11.default.lstat(candidate.path).catch(() => null);
34931
+ if (!candidateStat)
34932
+ continue;
34933
+ const candidateRealPath = await realPathIfPossible(candidate.path);
34934
+ if (destinationRealPath && candidateRealPath && samePath(destinationRealPath, candidateRealPath)) {
34935
+ continue;
34936
+ }
34937
+ const entries = await import_fs_extra11.default.readdir(candidate.path, { withFileTypes: true }).catch(() => null);
34938
+ if (!entries) {
34939
+ result.skipped.push({
34940
+ category,
34941
+ path: candidate.path,
34942
+ reason: "Could not read directory"
34943
+ });
34944
+ continue;
34945
+ }
34946
+ for (const entry of entries) {
34947
+ if (!shouldCollectEntry(category, entry))
34948
+ continue;
34949
+ const sourcePath = path15.join(candidate.path, entry.name);
34950
+ const sourceHash = await hashPath(sourcePath);
34951
+ const existingName = knownHashes.get(sourceHash);
34952
+ if (existingName) {
34953
+ result.duplicates.push({
34954
+ category,
34955
+ name: entry.name,
34956
+ from: sourcePath,
34957
+ keptAs: path15.join(destinationDir, existingName)
34958
+ });
34959
+ continue;
34960
+ }
34961
+ let targetName = entry.name;
34962
+ let targetPath = path15.join(destinationDir, targetName);
34963
+ if (await pathExistsOrSymlink(targetPath)) {
34964
+ targetName = await findTargetName(destinationDir, entry.name, candidate.label);
34965
+ targetPath = path15.join(destinationDir, targetName);
34966
+ result.renamed.push({
34967
+ category,
34968
+ name: entry.name,
34969
+ from: sourcePath,
34970
+ to: targetPath,
34971
+ reason: "Same name with different content"
34972
+ });
34973
+ }
34974
+ await import_fs_extra11.default.copy(sourcePath, targetPath, {
34975
+ dereference: false,
34976
+ overwrite: false
34977
+ });
34978
+ knownHashes.set(sourceHash, targetName);
34979
+ result.imported.push({
34980
+ category,
34981
+ name: entry.name,
34982
+ from: sourcePath,
34983
+ to: targetPath
34984
+ });
34985
+ }
34986
+ }
34987
+ }
34988
+ function timestamp2(date = new Date) {
34989
+ return date.toISOString().replace(/\.\d{3}Z$/, "").replace(/[:T]/g, "-");
34990
+ }
34991
+ function safeRelativePath(rootDir, targetPath) {
34992
+ const relativePath = path15.relative(rootDir, targetPath);
34993
+ if (!relativePath || relativePath.startsWith("..") || path15.isAbsolute(relativePath)) {
34994
+ return path15.join("external", targetPath.replace(/[^a-zA-Z0-9._-]+/g, "-"));
34995
+ }
34996
+ return relativePath;
34997
+ }
34998
+ function createBackupPath(rootDir) {
34999
+ return path15.join(rootDir, ".aiblueprint", "backups", "agents-unify-sources", timestamp2());
35000
+ }
35001
+ async function ensureBackupPath(result) {
35002
+ if (!result.backupPath) {
35003
+ result.backupPath = createBackupPath(result.rootDir);
35004
+ await import_fs_extra11.default.ensureDir(result.backupPath);
35005
+ }
35006
+ return result.backupPath;
35007
+ }
35008
+ async function createDirectorySymlink(source, target) {
35009
+ await import_fs_extra11.default.ensureDir(path15.dirname(target));
35010
+ if (os13.platform() === "win32") {
35011
+ await import_fs_extra11.default.symlink(source, target, "junction");
35012
+ return;
35013
+ }
35014
+ await import_fs_extra11.default.symlink(source, target, "dir");
35015
+ }
35016
+ async function shouldLinkMissingContainer(candidate) {
35017
+ if (candidate.linkWhenMissing)
35018
+ return true;
35019
+ if (!candidate.linkWhenParentExists)
35020
+ return false;
35021
+ return import_fs_extra11.default.pathExists(path15.dirname(candidate.path));
35022
+ }
35023
+ async function linkContainer(candidate, destinationDir, result) {
35024
+ if (candidate.isDestination || samePath(candidate.path, destinationDir)) {
35025
+ return;
35026
+ }
35027
+ const destinationRealPath = await realPathIfPossible(destinationDir);
35028
+ const stat = await import_fs_extra11.default.lstat(candidate.path).catch(() => null);
35029
+ if (!stat) {
35030
+ if (!await shouldLinkMissingContainer(candidate))
35031
+ return;
35032
+ await createDirectorySymlink(destinationDir, candidate.path);
35033
+ result.linked.push({
35034
+ category: candidate.category,
35035
+ from: candidate.path,
35036
+ to: destinationDir
35037
+ });
35038
+ return;
35039
+ }
35040
+ if (stat.isSymbolicLink()) {
35041
+ const existingRealPath = await realPathIfPossible(candidate.path);
35042
+ if (destinationRealPath && existingRealPath && samePath(destinationRealPath, existingRealPath)) {
35043
+ result.alreadyLinked.push({
35044
+ category: candidate.category,
35045
+ from: candidate.path,
35046
+ to: destinationDir
35047
+ });
35048
+ return;
35049
+ }
35050
+ await import_fs_extra11.default.remove(candidate.path);
35051
+ await createDirectorySymlink(destinationDir, candidate.path);
35052
+ result.linked.push({
35053
+ category: candidate.category,
35054
+ from: candidate.path,
35055
+ to: destinationDir
35056
+ });
35057
+ return;
35058
+ }
35059
+ const backupRoot = await ensureBackupPath(result);
35060
+ const backupTarget = path15.join(backupRoot, safeRelativePath(result.rootDir, candidate.path));
35061
+ await import_fs_extra11.default.ensureDir(path15.dirname(backupTarget));
35062
+ await import_fs_extra11.default.move(candidate.path, backupTarget, { overwrite: false });
35063
+ await createDirectorySymlink(destinationDir, candidate.path);
35064
+ result.linked.push({
35065
+ category: candidate.category,
35066
+ from: candidate.path,
35067
+ to: destinationDir,
35068
+ movedToBackup: backupTarget
35069
+ });
35070
+ }
35071
+ async function unifyAgentsConfiguration(options = {}) {
35072
+ const folders = resolveFolders(options);
35073
+ const candidates = getContainerCandidates(options);
35074
+ const result = {
35075
+ rootDir: folders.rootDir,
35076
+ agentsDir: folders.agentsDir,
35077
+ backupPath: null,
35078
+ imported: [],
35079
+ duplicates: [],
35080
+ renamed: [],
35081
+ linked: [],
35082
+ alreadyLinked: [],
35083
+ skipped: []
35084
+ };
35085
+ const destinationByCategory = {
35086
+ skills: path15.join(folders.agentsDir, "skills"),
35087
+ agents: path15.join(folders.agentsDir, "agents")
35088
+ };
35089
+ await import_fs_extra11.default.ensureDir(folders.agentsDir);
35090
+ for (const category of ["skills", "agents"]) {
35091
+ await importCategoryEntries(category, candidates, destinationByCategory[category], result);
35092
+ }
35093
+ for (const candidate of candidates) {
35094
+ await linkContainer(candidate, destinationByCategory[candidate.category], result);
35095
+ }
35096
+ return result;
35097
+ }
35098
+
35099
+ // src/commands/agents-unify.ts
35100
+ function countByCategory(result, key, category) {
35101
+ return result[key].filter((entry) => entry.category === category).length;
35102
+ }
35103
+ function printCategorySummary(result, category) {
35104
+ const imported = countByCategory(result, "imported", category);
35105
+ const duplicates = countByCategory(result, "duplicates", category);
35106
+ const renamed = countByCategory(result, "renamed", category);
35107
+ const linked = countByCategory(result, "linked", category);
35108
+ const alreadyLinked = countByCategory(result, "alreadyLinked", category);
35109
+ console.log(source_default.gray(` ${category}: ${imported} imported, ${duplicates} duplicates skipped, ${renamed} renamed, ${linked} linked, ${alreadyLinked} already linked`));
35110
+ }
35111
+ async function agentsUnifyCommand(params = {}) {
35112
+ try {
35113
+ console.log(source_default.blue.bold(`
35114
+ AIBlueprint agents unify ${source_default.gray(`v${getVersion()}`)}
35115
+ `));
35116
+ console.log(source_default.gray("Centralizing reusable skills and agents into .agents"));
35117
+ const result = await unifyAgentsConfiguration(params);
35118
+ console.log(source_default.green(`
35119
+ Unify complete`));
35120
+ console.log(source_default.gray(` Shared folder: ${result.agentsDir}`));
35121
+ printCategorySummary(result, "skills");
35122
+ printCategorySummary(result, "agents");
35123
+ if (result.backupPath) {
35124
+ console.log(source_default.gray(` Source backups: ${result.backupPath}`));
35125
+ }
35126
+ if (result.skipped.length > 0) {
35127
+ console.log(source_default.yellow(`
35128
+ Skipped paths:`));
35129
+ for (const skipped of result.skipped) {
35130
+ console.log(source_default.yellow(` ${skipped.path}: ${skipped.reason}`));
35131
+ }
35132
+ }
35133
+ } catch (error) {
35134
+ console.error(source_default.red(`
35135
+ Agents unify failed:`), error);
35136
+ process.exit(1);
35137
+ }
35138
+ }
35139
+
34654
35140
  // node_modules/@clack/core/dist/index.mjs
34655
35141
  var import_sisteransi = __toESM(require_src(), 1);
34656
35142
  var import_picocolors = __toESM(require_picocolors(), 1);
@@ -35367,12 +35853,12 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
35367
35853
  };
35368
35854
 
35369
35855
  // src/commands/pro.ts
35370
- import path17 from "path";
35856
+ import path18 from "path";
35371
35857
 
35372
35858
  // src/lib/pro-installer.ts
35373
- var import_fs_extra11 = __toESM(require_lib4(), 1);
35374
- import os13 from "os";
35375
- import path15 from "path";
35859
+ var import_fs_extra12 = __toESM(require_lib4(), 1);
35860
+ import os14 from "os";
35861
+ import path16 from "path";
35376
35862
  import { exec as exec3 } from "child_process";
35377
35863
  import { promisify as promisify2 } from "util";
35378
35864
  var execAsync2 = promisify2(exec3);
@@ -35380,9 +35866,9 @@ var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
35380
35866
  var PREMIUM_BRANCH = "main";
35381
35867
  var CONFIG_FOLDER_CANDIDATES2 = ["agents-config", "ai-coding", "claude-code-config", "ai-config"];
35382
35868
  function routePath(relativePath) {
35383
- const segments = relativePath.split(path15.sep);
35869
+ const segments = relativePath.split(path16.sep);
35384
35870
  const first = segments[0];
35385
- const rest = segments.slice(1).join(path15.sep);
35871
+ const rest = segments.slice(1).join(path16.sep);
35386
35872
  if (first === "claude-config") {
35387
35873
  return { kind: "claude", relativePath: rest };
35388
35874
  }
@@ -35398,7 +35884,7 @@ function routePath(relativePath) {
35398
35884
  return { kind: "claude", relativePath };
35399
35885
  }
35400
35886
  function getCacheRepoDir() {
35401
- return path15.join(os13.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
35887
+ return path16.join(os14.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
35402
35888
  }
35403
35889
  async function execGitWithAuth(command, token, repoUrl, cwd) {
35404
35890
  const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
@@ -35412,21 +35898,21 @@ async function execGitWithAuth(command, token, repoUrl, cwd) {
35412
35898
  async function cloneOrUpdateRepo(token) {
35413
35899
  const cacheDir = getCacheRepoDir();
35414
35900
  const repoUrl = `https://github.com/${PREMIUM_REPO}.git`;
35415
- if (await import_fs_extra11.default.pathExists(path15.join(cacheDir, ".git"))) {
35901
+ if (await import_fs_extra12.default.pathExists(path16.join(cacheDir, ".git"))) {
35416
35902
  try {
35417
35903
  await execGitWithAuth("pull", token, repoUrl, cacheDir);
35418
35904
  } catch (error) {
35419
- await import_fs_extra11.default.remove(cacheDir);
35420
- await import_fs_extra11.default.ensureDir(path15.dirname(cacheDir));
35905
+ await import_fs_extra12.default.remove(cacheDir);
35906
+ await import_fs_extra12.default.ensureDir(path16.dirname(cacheDir));
35421
35907
  await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
35422
35908
  }
35423
35909
  } else {
35424
- await import_fs_extra11.default.ensureDir(path15.dirname(cacheDir));
35910
+ await import_fs_extra12.default.ensureDir(path16.dirname(cacheDir));
35425
35911
  await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
35426
35912
  }
35427
35913
  for (const candidate of CONFIG_FOLDER_CANDIDATES2) {
35428
- const candidatePath = path15.join(cacheDir, candidate);
35429
- if (await import_fs_extra11.default.pathExists(candidatePath)) {
35914
+ const candidatePath = path16.join(cacheDir, candidate);
35915
+ if (await import_fs_extra12.default.pathExists(candidatePath)) {
35430
35916
  return candidatePath;
35431
35917
  }
35432
35918
  }
@@ -35434,38 +35920,38 @@ async function cloneOrUpdateRepo(token) {
35434
35920
  }
35435
35921
  async function copyConfigFromCache(cacheConfigDir, dest, onProgress) {
35436
35922
  const walk = async (dir, baseDir = dir) => {
35437
- const entries = await import_fs_extra11.default.readdir(dir, { withFileTypes: true });
35923
+ const entries = await import_fs_extra12.default.readdir(dir, { withFileTypes: true });
35438
35924
  for (const entry of entries) {
35439
35925
  if (entry.name === ".DS_Store" || entry.name === "node_modules")
35440
35926
  continue;
35441
- const sourcePath = path15.join(dir, entry.name);
35442
- const relativePath = path15.relative(baseDir, sourcePath);
35927
+ const sourcePath = path16.join(dir, entry.name);
35928
+ const relativePath = path16.relative(baseDir, sourcePath);
35443
35929
  const route = routePath(relativePath);
35444
35930
  if (route.kind === "skip")
35445
35931
  continue;
35446
35932
  if (route.kind === "agents-category") {
35447
- if (relativePath.split(path15.sep).length === 1) {
35933
+ if (relativePath.split(path16.sep).length === 1) {
35448
35934
  await copyAgentCategory(sourcePath, route.category, dest.agentsDir, dest.claudeDir, onProgress);
35449
35935
  }
35450
35936
  continue;
35451
35937
  }
35452
35938
  const targetBase = route.kind === "claude" ? dest.claudeDir : dest.codexDir;
35453
- const targetPath = path15.join(targetBase, route.relativePath);
35939
+ const targetPath = path16.join(targetBase, route.relativePath);
35454
35940
  if (entry.isDirectory()) {
35455
- await import_fs_extra11.default.ensureDir(targetPath);
35941
+ await import_fs_extra12.default.ensureDir(targetPath);
35456
35942
  onProgress?.(relativePath, "directory");
35457
35943
  await walk(sourcePath, baseDir);
35458
35944
  } else if (route.kind === "codex" && route.relativePath === "config.toml") {
35459
35945
  await mergeCodexConfigFile(sourcePath, dest.codexDir);
35460
35946
  onProgress?.(relativePath, "file");
35461
35947
  } else if (isTextFile(entry.name)) {
35462
- const content = await import_fs_extra11.default.readFile(sourcePath, "utf-8");
35948
+ const content = await import_fs_extra12.default.readFile(sourcePath, "utf-8");
35463
35949
  const replaced = replaceClaudePathPlaceholder(content, dest.claudeDir);
35464
- await import_fs_extra11.default.ensureDir(path15.dirname(targetPath));
35465
- await import_fs_extra11.default.writeFile(targetPath, replaced, "utf-8");
35950
+ await import_fs_extra12.default.ensureDir(path16.dirname(targetPath));
35951
+ await import_fs_extra12.default.writeFile(targetPath, replaced, "utf-8");
35466
35952
  onProgress?.(relativePath, "file");
35467
35953
  } else {
35468
- await import_fs_extra11.default.copy(sourcePath, targetPath, { overwrite: true });
35954
+ await import_fs_extra12.default.copy(sourcePath, targetPath, { overwrite: true });
35469
35955
  onProgress?.(relativePath, "file");
35470
35956
  }
35471
35957
  }
@@ -35473,21 +35959,21 @@ async function copyConfigFromCache(cacheConfigDir, dest, onProgress) {
35473
35959
  await walk(cacheConfigDir);
35474
35960
  }
35475
35961
  async function copyAgentCategory(sourceCategoryDir, category, agentsDir, claudeDir, onProgress) {
35476
- const agentsCategoryDir = path15.join(agentsDir, category);
35477
- await import_fs_extra11.default.ensureDir(agentsCategoryDir);
35478
- const entries = await import_fs_extra11.default.readdir(sourceCategoryDir, { withFileTypes: true });
35962
+ const agentsCategoryDir = path16.join(agentsDir, category);
35963
+ await import_fs_extra12.default.ensureDir(agentsCategoryDir);
35964
+ const entries = await import_fs_extra12.default.readdir(sourceCategoryDir, { withFileTypes: true });
35479
35965
  for (const entry of entries) {
35480
35966
  if (entry.name === ".DS_Store")
35481
35967
  continue;
35482
- const src = path15.join(sourceCategoryDir, entry.name);
35483
- const dst = path15.join(agentsCategoryDir, entry.name);
35484
- const claudeTop = path15.join(claudeDir, category, entry.name);
35485
- const claudeStat = await import_fs_extra11.default.lstat(claudeTop).catch(() => null);
35968
+ const src = path16.join(sourceCategoryDir, entry.name);
35969
+ const dst = path16.join(agentsCategoryDir, entry.name);
35970
+ const claudeTop = path16.join(claudeDir, category, entry.name);
35971
+ const claudeStat = await import_fs_extra12.default.lstat(claudeTop).catch(() => null);
35486
35972
  if (claudeStat && !claudeStat.isSymbolicLink()) {
35487
35973
  onProgress?.(`${category}/${entry.name} (skipped - real dir in claude)`, "file");
35488
35974
  continue;
35489
35975
  }
35490
- await import_fs_extra11.default.copy(src, dst, { overwrite: true });
35976
+ await import_fs_extra12.default.copy(src, dst, { overwrite: true });
35491
35977
  await applyPathPlaceholders(dst, claudeDir);
35492
35978
  onProgress?.(`${category}/${entry.name}`, entry.isDirectory() ? "directory" : "file");
35493
35979
  }
@@ -35506,8 +35992,8 @@ async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath,
35506
35992
  return false;
35507
35993
  }
35508
35994
  const content = await response.arrayBuffer();
35509
- await import_fs_extra11.default.ensureDir(path15.dirname(targetPath));
35510
- await import_fs_extra11.default.writeFile(targetPath, Buffer.from(content));
35995
+ await import_fs_extra12.default.ensureDir(path16.dirname(targetPath));
35996
+ await import_fs_extra12.default.writeFile(targetPath, Buffer.from(content));
35511
35997
  return true;
35512
35998
  } catch (error) {
35513
35999
  console.error(`Error downloading ${relativePath}:`, error);
@@ -35532,10 +36018,10 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
35532
36018
  console.error(`Unexpected response for directory ${dirPath}`);
35533
36019
  return false;
35534
36020
  }
35535
- await import_fs_extra11.default.ensureDir(targetDir);
36021
+ await import_fs_extra12.default.ensureDir(targetDir);
35536
36022
  for (const file of files) {
35537
36023
  const relativePath = dirPath ? `${dirPath}/${file.name}` : file.name;
35538
- const targetPath = path15.join(targetDir, file.name);
36024
+ const targetPath = path16.join(targetDir, file.name);
35539
36025
  const displayPath = relativePath.replace(/^(agents-config|ai-coding|claude-code-config|ai-config)\//, "");
35540
36026
  if (file.type === "file") {
35541
36027
  onProgress?.(displayPath, "file");
@@ -35558,8 +36044,8 @@ async function installProConfigs(options) {
35558
36044
  codexFolder,
35559
36045
  agentsFolder
35560
36046
  });
35561
- await import_fs_extra11.default.ensureDir(claudeDir);
35562
- await import_fs_extra11.default.ensureDir(agentsDir);
36047
+ await import_fs_extra12.default.ensureDir(claudeDir);
36048
+ await import_fs_extra12.default.ensureDir(agentsDir);
35563
36049
  const dest = { claudeDir, codexDir, agentsDir };
35564
36050
  try {
35565
36051
  const cacheConfigDir = await cloneOrUpdateRepo(githubToken);
@@ -35569,7 +36055,7 @@ async function installProConfigs(options) {
35569
36055
  } catch (error) {
35570
36056
  console.warn("Git caching failed, falling back to API download");
35571
36057
  }
35572
- const tempDir = path15.join(os13.tmpdir(), `aiblueprint-premium-${Date.now()}`);
36058
+ const tempDir = path16.join(os14.tmpdir(), `aiblueprint-premium-${Date.now()}`);
35573
36059
  try {
35574
36060
  let success = false;
35575
36061
  for (const candidate of CONFIG_FOLDER_CANDIDATES2) {
@@ -35583,8 +36069,8 @@ async function installProConfigs(options) {
35583
36069
  await copyConfigFromCache(tempDir, dest, onProgress);
35584
36070
  await replacePathPlaceholdersInDir(claudeDir, claudeDir);
35585
36071
  for (const category of AGENT_CATEGORIES) {
35586
- const agentsCategoryDir = path15.join(agentsDir, category);
35587
- if (await import_fs_extra11.default.pathExists(agentsCategoryDir)) {
36072
+ const agentsCategoryDir = path16.join(agentsDir, category);
36073
+ if (await import_fs_extra12.default.pathExists(agentsCategoryDir)) {
35588
36074
  await replacePathPlaceholdersInDir(agentsCategoryDir, claudeDir);
35589
36075
  }
35590
36076
  }
@@ -35593,7 +36079,7 @@ async function installProConfigs(options) {
35593
36079
  throw new Error(`Failed to install premium configs: ${error instanceof Error ? error.message : "Unknown error"}`);
35594
36080
  } finally {
35595
36081
  try {
35596
- await import_fs_extra11.default.remove(tempDir);
36082
+ await import_fs_extra12.default.remove(tempDir);
35597
36083
  } catch {}
35598
36084
  }
35599
36085
  }
@@ -35604,27 +36090,27 @@ async function syncAllAgentSymlinks(agentsDir, claudeDir) {
35604
36090
  }
35605
36091
 
35606
36092
  // src/lib/token-storage.ts
35607
- var import_fs_extra12 = __toESM(require_lib4(), 1);
35608
- import os14 from "os";
35609
- import path16 from "path";
36093
+ var import_fs_extra13 = __toESM(require_lib4(), 1);
36094
+ import os15 from "os";
36095
+ import path17 from "path";
35610
36096
  function getConfigDir() {
35611
- const platform = os14.platform();
36097
+ const platform = os15.platform();
35612
36098
  if (platform === "win32") {
35613
- const appData = process.env.APPDATA || path16.join(os14.homedir(), "AppData", "Roaming");
35614
- return path16.join(appData, "aiblueprint");
36099
+ const appData = process.env.APPDATA || path17.join(os15.homedir(), "AppData", "Roaming");
36100
+ return path17.join(appData, "aiblueprint");
35615
36101
  } else {
35616
- const configHome = process.env.XDG_CONFIG_HOME || path16.join(os14.homedir(), ".config");
35617
- return path16.join(configHome, "aiblueprint");
36102
+ const configHome = process.env.XDG_CONFIG_HOME || path17.join(os15.homedir(), ".config");
36103
+ return path17.join(configHome, "aiblueprint");
35618
36104
  }
35619
36105
  }
35620
36106
  function getTokenFilePath2() {
35621
- return path16.join(getConfigDir(), "token.txt");
36107
+ return path17.join(getConfigDir(), "token.txt");
35622
36108
  }
35623
36109
  async function saveToken(githubToken) {
35624
36110
  const tokenFile = getTokenFilePath2();
35625
- const configDir = path16.dirname(tokenFile);
36111
+ const configDir = path17.dirname(tokenFile);
35626
36112
  try {
35627
- await import_fs_extra12.default.ensureDir(configDir);
36113
+ await import_fs_extra13.default.ensureDir(configDir);
35628
36114
  } catch (error) {
35629
36115
  if (error.code === "EACCES") {
35630
36116
  throw new Error(`Permission denied creating config directory: ${configDir}
@@ -35632,15 +36118,15 @@ async function saveToken(githubToken) {
35632
36118
  }
35633
36119
  throw error;
35634
36120
  }
35635
- await import_fs_extra12.default.writeFile(tokenFile, githubToken, { mode: 384 });
36121
+ await import_fs_extra13.default.writeFile(tokenFile, githubToken, { mode: 384 });
35636
36122
  }
35637
36123
  async function getToken() {
35638
36124
  const tokenFile = getTokenFilePath2();
35639
- if (!await import_fs_extra12.default.pathExists(tokenFile)) {
36125
+ if (!await import_fs_extra13.default.pathExists(tokenFile)) {
35640
36126
  return null;
35641
36127
  }
35642
36128
  try {
35643
- const token = await import_fs_extra12.default.readFile(tokenFile, "utf-8");
36129
+ const token = await import_fs_extra13.default.readFile(tokenFile, "utf-8");
35644
36130
  return token.trim();
35645
36131
  } catch (error) {
35646
36132
  return null;
@@ -35649,12 +36135,12 @@ async function getToken() {
35649
36135
  function getTokenInfo() {
35650
36136
  return {
35651
36137
  path: getTokenFilePath2(),
35652
- platform: os14.platform()
36138
+ platform: os15.platform()
35653
36139
  };
35654
36140
  }
35655
36141
 
35656
36142
  // src/commands/pro.ts
35657
- var import_fs_extra13 = __toESM(require_lib4(), 1);
36143
+ var import_fs_extra14 = __toESM(require_lib4(), 1);
35658
36144
  var API_URL = "https://codeline.app/api/products";
35659
36145
  var PRODUCT_IDS = ["prd_XJVgxVPbGG", "prd_NKabAkdOkw"];
35660
36146
  async function countInstalledItems(claudeDir) {
@@ -35663,20 +36149,20 @@ async function countInstalledItems(claudeDir) {
35663
36149
  skills: 0
35664
36150
  };
35665
36151
  try {
35666
- const agentsDir = path17.join(claudeDir, "agents");
35667
- if (await import_fs_extra13.default.pathExists(agentsDir)) {
35668
- const files = await import_fs_extra13.default.readdir(agentsDir);
36152
+ const agentsDir = path18.join(claudeDir, "agents");
36153
+ if (await import_fs_extra14.default.pathExists(agentsDir)) {
36154
+ const files = await import_fs_extra14.default.readdir(agentsDir);
35669
36155
  counts.agents = files.filter((f) => f.endsWith(".md")).length;
35670
36156
  }
35671
36157
  } catch (error) {
35672
36158
  console.error("Failed to count agents:", error instanceof Error ? error.message : error);
35673
36159
  }
35674
36160
  try {
35675
- const skillsDir = path17.join(claudeDir, "skills");
35676
- if (await import_fs_extra13.default.pathExists(skillsDir)) {
35677
- const items = await import_fs_extra13.default.readdir(skillsDir);
36161
+ const skillsDir = path18.join(claudeDir, "skills");
36162
+ if (await import_fs_extra14.default.pathExists(skillsDir)) {
36163
+ const items = await import_fs_extra14.default.readdir(skillsDir);
35678
36164
  const dirs = await Promise.all(items.map(async (item) => {
35679
- const stat = await import_fs_extra13.default.stat(path17.join(skillsDir, item));
36165
+ const stat = await import_fs_extra14.default.stat(path18.join(skillsDir, item));
35680
36166
  return stat.isDirectory();
35681
36167
  }));
35682
36168
  counts.skills = dirs.filter(Boolean).length;
@@ -35884,9 +36370,9 @@ async function proUpdateCommand(options = {}) {
35884
36370
  }
35885
36371
 
35886
36372
  // src/lib/sync-utils.ts
35887
- var import_fs_extra14 = __toESM(require_lib4(), 1);
35888
- import path18 from "path";
35889
- import crypto from "crypto";
36373
+ var import_fs_extra15 = __toESM(require_lib4(), 1);
36374
+ import path19 from "path";
36375
+ import crypto2 from "crypto";
35890
36376
  var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
35891
36377
  var PREMIUM_BRANCH2 = "main";
35892
36378
  var CONFIG_FOLDER_CANDIDATES3 = ["agents-config", "ai-coding", "claude-code-config", "ai-config"];
@@ -35894,7 +36380,7 @@ function computeFileSha(content) {
35894
36380
  const size = content.length;
35895
36381
  const header = `blob ${size}\x00`;
35896
36382
  const fullContent = Buffer.concat([Buffer.from(header), content]);
35897
- return crypto.createHash("sha1").update(fullContent).digest("hex");
36383
+ return crypto2.createHash("sha1").update(fullContent).digest("hex");
35898
36384
  }
35899
36385
  var resolvedConfigFolder = null;
35900
36386
  async function resolveRemoteConfigFolder(githubToken) {
@@ -35956,7 +36442,7 @@ async function listRemoteFilesRecursive(dirPath, githubToken, basePath = "") {
35956
36442
  }
35957
36443
  async function computeLocalFileSha(filePath) {
35958
36444
  try {
35959
- const content = await import_fs_extra14.default.readFile(filePath);
36445
+ const content = await import_fs_extra15.default.readFile(filePath);
35960
36446
  return computeFileSha(content);
35961
36447
  } catch {
35962
36448
  return null;
@@ -35964,15 +36450,15 @@ async function computeLocalFileSha(filePath) {
35964
36450
  }
35965
36451
  async function listLocalFiles(dir) {
35966
36452
  const files = [];
35967
- if (!await import_fs_extra14.default.pathExists(dir)) {
36453
+ if (!await import_fs_extra15.default.pathExists(dir)) {
35968
36454
  return files;
35969
36455
  }
35970
- const items = await import_fs_extra14.default.readdir(dir);
36456
+ const items = await import_fs_extra15.default.readdir(dir);
35971
36457
  for (const item of items) {
35972
36458
  if (item === "node_modules" || item === ".DS_Store")
35973
36459
  continue;
35974
- const fullPath = path18.join(dir, item);
35975
- const stat = await import_fs_extra14.default.stat(fullPath).catch(() => null);
36460
+ const fullPath = path19.join(dir, item);
36461
+ const stat = await import_fs_extra15.default.stat(fullPath).catch(() => null);
35976
36462
  if (!stat)
35977
36463
  continue;
35978
36464
  if (stat.isDirectory()) {
@@ -35987,13 +36473,13 @@ async function listLocalFiles(dir) {
35987
36473
  }
35988
36474
  async function listLocalFilesRecursive(dir, basePath) {
35989
36475
  const files = [];
35990
- const items = await import_fs_extra14.default.readdir(dir).catch(() => []);
36476
+ const items = await import_fs_extra15.default.readdir(dir).catch(() => []);
35991
36477
  for (const item of items) {
35992
36478
  if (item === "node_modules" || item === ".DS_Store")
35993
36479
  continue;
35994
- const fullPath = path18.join(dir, item);
36480
+ const fullPath = path19.join(dir, item);
35995
36481
  const relativePath = `${basePath}/${item}`;
35996
- const stat = await import_fs_extra14.default.stat(fullPath).catch(() => null);
36482
+ const stat = await import_fs_extra15.default.stat(fullPath).catch(() => null);
35997
36483
  if (!stat)
35998
36484
  continue;
35999
36485
  if (stat.isDirectory()) {
@@ -36007,14 +36493,14 @@ async function listLocalFilesRecursive(dir, basePath) {
36007
36493
  return files;
36008
36494
  }
36009
36495
  async function listClaudeRealTopLevel(claudeCategoryDir) {
36010
- if (!await import_fs_extra14.default.pathExists(claudeCategoryDir))
36496
+ if (!await import_fs_extra15.default.pathExists(claudeCategoryDir))
36011
36497
  return [];
36012
- const entries = await import_fs_extra14.default.readdir(claudeCategoryDir).catch(() => []);
36498
+ const entries = await import_fs_extra15.default.readdir(claudeCategoryDir).catch(() => []);
36013
36499
  const real = [];
36014
36500
  for (const name of entries) {
36015
36501
  if (name === "node_modules" || name === ".DS_Store")
36016
36502
  continue;
36017
- const stat = await import_fs_extra14.default.lstat(path18.join(claudeCategoryDir, name)).catch(() => null);
36503
+ const stat = await import_fs_extra15.default.lstat(path19.join(claudeCategoryDir, name)).catch(() => null);
36018
36504
  if (!stat)
36019
36505
  continue;
36020
36506
  if (stat.isDirectory())
@@ -36031,7 +36517,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
36031
36517
  const items = [];
36032
36518
  const useAgents = isAgentCategory(category);
36033
36519
  const localBase = useAgents ? agentsDir : claudeDir;
36034
- const localDir = path18.join(localBase, category);
36520
+ const localDir = path19.join(localBase, category);
36035
36521
  const remoteCategoryPath = getRemoteCategoryPath(category);
36036
36522
  const remoteFiles = await listRemoteFilesRecursive(remoteCategoryPath, githubToken);
36037
36523
  const localFiles = await listLocalFiles(localDir);
@@ -36045,7 +36531,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
36045
36531
  }
36046
36532
  const localSet = new Set(localFiles);
36047
36533
  for (const [remotePath, { sha, isFolder }] of remoteSet) {
36048
- const localPath = path18.join(localDir, remotePath);
36534
+ const localPath = path19.join(localDir, remotePath);
36049
36535
  if (isFolder) {
36050
36536
  continue;
36051
36537
  }
@@ -36080,7 +36566,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
36080
36566
  for (const localPath of localSet) {
36081
36567
  agentsTopLevels.add(localPath.split("/")[0]);
36082
36568
  }
36083
- const claudeCategoryDir = path18.join(claudeDir, category);
36569
+ const claudeCategoryDir = path19.join(claudeDir, category);
36084
36570
  const claudeRealEntries = await listClaudeRealTopLevel(claudeCategoryDir);
36085
36571
  for (const top of claudeRealEntries) {
36086
36572
  if (!remoteTopLevels.has(top))
@@ -36139,13 +36625,13 @@ async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken,
36139
36625
  return false;
36140
36626
  }
36141
36627
  const content = await response.arrayBuffer();
36142
- await import_fs_extra14.default.ensureDir(path18.dirname(targetPath));
36628
+ await import_fs_extra15.default.ensureDir(path19.dirname(targetPath));
36143
36629
  if (isTextFile(relativePath)) {
36144
36630
  const textContent = Buffer.from(content).toString("utf-8");
36145
36631
  const transformedContent = transformFileContent(textContent, claudeDir);
36146
- await import_fs_extra14.default.writeFile(targetPath, transformedContent, "utf-8");
36632
+ await import_fs_extra15.default.writeFile(targetPath, transformedContent, "utf-8");
36147
36633
  } else {
36148
- await import_fs_extra14.default.writeFile(targetPath, Buffer.from(content));
36634
+ await import_fs_extra15.default.writeFile(targetPath, Buffer.from(content));
36149
36635
  }
36150
36636
  return true;
36151
36637
  } catch {
@@ -36161,27 +36647,27 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
36161
36647
  for (const item of items) {
36162
36648
  const useAgents = isAgentCategory(item.category);
36163
36649
  const baseDir = useAgents ? agentsDir : claudeDir;
36164
- const targetPath = path18.join(baseDir, item.relativePath);
36650
+ const targetPath = path19.join(baseDir, item.relativePath);
36165
36651
  if (item.status === "migration" && useAgents) {
36166
36652
  const topName = item.name.split("/")[0];
36167
- const agentsTop = path18.join(agentsDir, item.category, topName);
36168
- const claudeTop = path18.join(claudeDir, item.category, topName);
36653
+ const agentsTop = path19.join(agentsDir, item.category, topName);
36654
+ const claudeTop = path19.join(claudeDir, item.category, topName);
36169
36655
  try {
36170
- const claudeStat = await import_fs_extra14.default.lstat(claudeTop).catch(() => null);
36656
+ const claudeStat = await import_fs_extra15.default.lstat(claudeTop).catch(() => null);
36171
36657
  if (!claudeStat || claudeStat.isSymbolicLink()) {
36172
36658
  onProgress?.(item.relativePath, "skipping (no real dir to migrate)");
36173
36659
  failed++;
36174
36660
  continue;
36175
36661
  }
36176
- const agentsExists = await import_fs_extra14.default.pathExists(agentsTop);
36662
+ const agentsExists = await import_fs_extra15.default.pathExists(agentsTop);
36177
36663
  if (agentsExists) {
36178
36664
  onProgress?.(item.relativePath, "skipping (already in .agents)");
36179
36665
  failed++;
36180
36666
  continue;
36181
36667
  }
36182
36668
  onProgress?.(item.relativePath, "moving to .agents");
36183
- await import_fs_extra14.default.ensureDir(path18.dirname(agentsTop));
36184
- await import_fs_extra14.default.move(claudeTop, agentsTop);
36669
+ await import_fs_extra15.default.ensureDir(path19.dirname(agentsTop));
36670
+ await import_fs_extra15.default.move(claudeTop, agentsTop);
36185
36671
  migrated++;
36186
36672
  touchedAgentCategories.add(item.category);
36187
36673
  } catch {
@@ -36191,8 +36677,8 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
36191
36677
  }
36192
36678
  if (useAgents) {
36193
36679
  const topName = item.name.split("/")[0];
36194
- const claudeTop = path18.join(claudeDir, item.category, topName);
36195
- const claudeTopStat = await import_fs_extra14.default.lstat(claudeTop).catch(() => null);
36680
+ const claudeTop = path19.join(claudeDir, item.category, topName);
36681
+ const claudeTopStat = await import_fs_extra15.default.lstat(claudeTop).catch(() => null);
36196
36682
  if (claudeTopStat && !claudeTopStat.isSymbolicLink()) {
36197
36683
  onProgress?.(item.relativePath, "skipping (real dir in .claude)");
36198
36684
  failed++;
@@ -36202,7 +36688,7 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
36202
36688
  if (item.status === "deleted") {
36203
36689
  onProgress?.(item.relativePath, "deleting");
36204
36690
  try {
36205
- await import_fs_extra14.default.remove(targetPath);
36691
+ await import_fs_extra15.default.remove(targetPath);
36206
36692
  deleted++;
36207
36693
  if (useAgents)
36208
36694
  touchedAgentCategories.add(item.category);
@@ -36540,20 +37026,20 @@ async function proSyncCommand(options = {}) {
36540
37026
  }
36541
37027
 
36542
37028
  // src/lib/backup-utils.ts
36543
- var import_fs_extra15 = __toESM(require_lib4(), 1);
36544
- import path19 from "path";
36545
- import os15 from "os";
36546
- var BACKUP_BASE_DIR = path19.join(os15.homedir(), ".config", "aiblueprint", "backup");
37029
+ var import_fs_extra16 = __toESM(require_lib4(), 1);
37030
+ import path20 from "path";
37031
+ import os16 from "os";
37032
+ var BACKUP_BASE_DIR = path20.join(os16.homedir(), ".config", "aiblueprint", "backup");
36547
37033
  function formatDate(date) {
36548
37034
  const pad = (n) => n.toString().padStart(2, "0");
36549
37035
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
36550
37036
  }
36551
37037
  async function listBackups() {
36552
- const exists = await import_fs_extra15.default.pathExists(BACKUP_BASE_DIR);
37038
+ const exists = await import_fs_extra16.default.pathExists(BACKUP_BASE_DIR);
36553
37039
  if (!exists) {
36554
37040
  return [];
36555
37041
  }
36556
- const entries = await import_fs_extra15.default.readdir(BACKUP_BASE_DIR, { withFileTypes: true });
37042
+ const entries = await import_fs_extra16.default.readdir(BACKUP_BASE_DIR, { withFileTypes: true });
36557
37043
  const backups = [];
36558
37044
  for (const entry of entries) {
36559
37045
  if (!entry.isDirectory())
@@ -36565,7 +37051,7 @@ async function listBackups() {
36565
37051
  const date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second));
36566
37052
  backups.push({
36567
37053
  name: entry.name,
36568
- path: path19.join(BACKUP_BASE_DIR, entry.name),
37054
+ path: path20.join(BACKUP_BASE_DIR, entry.name),
36569
37055
  date
36570
37056
  });
36571
37057
  }
@@ -36574,12 +37060,12 @@ async function listBackups() {
36574
37060
  var AGENTS_BACKUP_SUBDIR = ".agents";
36575
37061
  var CLAUDE_ITEMS = ["commands", "agents", "skills", "scripts", "settings.json"];
36576
37062
  async function copyForBackup(sourcePath, destPath) {
36577
- await import_fs_extra15.default.copy(sourcePath, destPath, {
37063
+ await import_fs_extra16.default.copy(sourcePath, destPath, {
36578
37064
  overwrite: true,
36579
37065
  dereference: false,
36580
37066
  filter: async (src) => {
36581
37067
  try {
36582
- const stat = await import_fs_extra15.default.lstat(src);
37068
+ const stat = await import_fs_extra16.default.lstat(src);
36583
37069
  return !stat.isSymbolicLink();
36584
37070
  } catch {
36585
37071
  return true;
@@ -36588,28 +37074,28 @@ async function copyForBackup(sourcePath, destPath) {
36588
37074
  });
36589
37075
  }
36590
37076
  async function hasMeaningfulContent(dir) {
36591
- if (!await import_fs_extra15.default.pathExists(dir))
37077
+ if (!await import_fs_extra16.default.pathExists(dir))
36592
37078
  return false;
36593
- const files = await import_fs_extra15.default.readdir(dir);
37079
+ const files = await import_fs_extra16.default.readdir(dir);
36594
37080
  return files.some((f) => f !== ".DS_Store");
36595
37081
  }
36596
37082
  async function loadBackup(backupPath, claudeDir, agentsDir) {
36597
- const exists = await import_fs_extra15.default.pathExists(backupPath);
37083
+ const exists = await import_fs_extra16.default.pathExists(backupPath);
36598
37084
  if (!exists) {
36599
37085
  throw new Error(`Backup not found: ${backupPath}`);
36600
37086
  }
36601
- await import_fs_extra15.default.ensureDir(claudeDir);
37087
+ await import_fs_extra16.default.ensureDir(claudeDir);
36602
37088
  for (const item of CLAUDE_ITEMS) {
36603
- const sourcePath = path19.join(backupPath, item);
36604
- const destPath = path19.join(claudeDir, item);
36605
- if (await import_fs_extra15.default.pathExists(sourcePath)) {
37089
+ const sourcePath = path20.join(backupPath, item);
37090
+ const destPath = path20.join(claudeDir, item);
37091
+ if (await import_fs_extra16.default.pathExists(sourcePath)) {
36606
37092
  await copyForBackup(sourcePath, destPath);
36607
37093
  }
36608
37094
  }
36609
37095
  if (agentsDir) {
36610
- const agentsBackupPath = path19.join(backupPath, AGENTS_BACKUP_SUBDIR);
36611
- if (await import_fs_extra15.default.pathExists(agentsBackupPath)) {
36612
- await import_fs_extra15.default.ensureDir(agentsDir);
37096
+ const agentsBackupPath = path20.join(backupPath, AGENTS_BACKUP_SUBDIR);
37097
+ if (await import_fs_extra16.default.pathExists(agentsBackupPath)) {
37098
+ await import_fs_extra16.default.ensureDir(agentsDir);
36613
37099
  await copyForBackup(agentsBackupPath, agentsDir);
36614
37100
  }
36615
37101
  }
@@ -36620,20 +37106,20 @@ async function createBackup(claudeDir, agentsDir) {
36620
37106
  if (!claudeHasContent && !agentsHasContent) {
36621
37107
  return null;
36622
37108
  }
36623
- const timestamp2 = formatDate(new Date);
36624
- const backupPath = path19.join(BACKUP_BASE_DIR, timestamp2);
36625
- await import_fs_extra15.default.ensureDir(backupPath);
37109
+ const timestamp3 = formatDate(new Date);
37110
+ const backupPath = path20.join(BACKUP_BASE_DIR, timestamp3);
37111
+ await import_fs_extra16.default.ensureDir(backupPath);
36626
37112
  if (claudeHasContent) {
36627
37113
  for (const item of CLAUDE_ITEMS) {
36628
- const sourcePath = path19.join(claudeDir, item);
36629
- const destPath = path19.join(backupPath, item);
36630
- if (await import_fs_extra15.default.pathExists(sourcePath)) {
37114
+ const sourcePath = path20.join(claudeDir, item);
37115
+ const destPath = path20.join(backupPath, item);
37116
+ if (await import_fs_extra16.default.pathExists(sourcePath)) {
36631
37117
  await copyForBackup(sourcePath, destPath);
36632
37118
  }
36633
37119
  }
36634
37120
  }
36635
37121
  if (agentsHasContent && agentsDir) {
36636
- const destPath = path19.join(backupPath, AGENTS_BACKUP_SUBDIR);
37122
+ const destPath = path20.join(backupPath, AGENTS_BACKUP_SUBDIR);
36637
37123
  await copyForBackup(agentsDir, destPath);
36638
37124
  }
36639
37125
  return backupPath;
@@ -36740,6 +37226,7 @@ function printSnapshots(title, snapshots) {
36740
37226
  }
36741
37227
  async function configsSaveCommand(name, options = {}) {
36742
37228
  try {
37229
+ console.log(source_default.gray("Saving .claude, .codex, and .agents config files..."));
36743
37230
  const snapshotPath = await saveNamedConfig(name, options);
36744
37231
  console.log(source_default.green(`Saved config "${name}"`));
36745
37232
  console.log(source_default.gray(snapshotPath));
@@ -36750,6 +37237,7 @@ async function configsSaveCommand(name, options = {}) {
36750
37237
  }
36751
37238
  async function configsLoadCommand(name, options = {}) {
36752
37239
  try {
37240
+ console.log(source_default.gray(`Loading config "${name}"...`));
36753
37241
  const result = await loadNamedConfig(name, options);
36754
37242
  console.log(source_default.green(`Loaded config "${name}"`));
36755
37243
  if (result.backupPath) {
@@ -36763,6 +37251,7 @@ async function configsLoadCommand(name, options = {}) {
36763
37251
  }
36764
37252
  async function configsUndoCommand(options = {}) {
36765
37253
  try {
37254
+ console.log(source_default.gray("Restoring the previous config backup..."));
36766
37255
  const result = await undoLastLoad(options);
36767
37256
  console.log(source_default.green(`Undid last config load using backup "${result.backupName}"`));
36768
37257
  if (result.backupPath) {
@@ -36784,6 +37273,7 @@ async function configsBackupsListCommand(options = {}) {
36784
37273
  }
36785
37274
  async function configsBackupsLoadCommand(name, options = {}) {
36786
37275
  try {
37276
+ console.log(source_default.gray(`Loading backup "${name}"...`));
36787
37277
  const result = await loadBackupSnapshot(name, options);
36788
37278
  console.log(source_default.green(`Loaded backup "${name}"`));
36789
37279
  if (result.backupPath) {
@@ -36797,6 +37287,7 @@ async function configsBackupsLoadCommand(name, options = {}) {
36797
37287
  }
36798
37288
  async function configsBackupsCreateCommand(reason, options = {}) {
36799
37289
  try {
37290
+ console.log(source_default.gray("Creating config backup..."));
36800
37291
  const backupPath = await createConfigBackup(options, reason ?? "Manual backup from configs backups create", "manual-backup", "manual");
36801
37292
  if (!backupPath) {
36802
37293
  console.log(source_default.gray("No .claude, .codex, or .agents configuration found to backup."));
@@ -36811,19 +37302,19 @@ async function configsBackupsCreateCommand(reason, options = {}) {
36811
37302
  }
36812
37303
 
36813
37304
  // src/commands/openclaw-pro.ts
36814
- import os18 from "os";
36815
- import path22 from "path";
37305
+ import os19 from "os";
37306
+ import path23 from "path";
36816
37307
 
36817
37308
  // src/lib/openclaw-installer.ts
36818
- var import_fs_extra16 = __toESM(require_lib4(), 1);
36819
- import os16 from "os";
36820
- import path20 from "path";
37309
+ var import_fs_extra17 = __toESM(require_lib4(), 1);
37310
+ import os17 from "os";
37311
+ import path21 from "path";
36821
37312
  import { exec as exec4 } from "child_process";
36822
37313
  import { promisify as promisify3 } from "util";
36823
37314
  var execAsync3 = promisify3(exec4);
36824
37315
  var OPENCLAW_PRO_REPO = "Melvynx/openclawpro";
36825
37316
  function getCacheRepoDir2() {
36826
- return path20.join(os16.homedir(), ".config", "openclaw", "pro-repos", "openclawpro");
37317
+ return path21.join(os17.homedir(), ".config", "openclaw", "pro-repos", "openclawpro");
36827
37318
  }
36828
37319
  async function execGitWithAuth2(command, token, repoUrl, cwd) {
36829
37320
  const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
@@ -36837,33 +37328,33 @@ async function execGitWithAuth2(command, token, repoUrl, cwd) {
36837
37328
  async function cloneOrUpdateRepo2(token) {
36838
37329
  const cacheDir = getCacheRepoDir2();
36839
37330
  const repoUrl = `https://github.com/${OPENCLAW_PRO_REPO}.git`;
36840
- if (await import_fs_extra16.default.pathExists(path20.join(cacheDir, ".git"))) {
37331
+ if (await import_fs_extra17.default.pathExists(path21.join(cacheDir, ".git"))) {
36841
37332
  try {
36842
37333
  await execGitWithAuth2("pull", token, repoUrl, cacheDir);
36843
37334
  } catch (error) {
36844
- await import_fs_extra16.default.remove(cacheDir);
36845
- await import_fs_extra16.default.ensureDir(path20.dirname(cacheDir));
37335
+ await import_fs_extra17.default.remove(cacheDir);
37336
+ await import_fs_extra17.default.ensureDir(path21.dirname(cacheDir));
36846
37337
  await execGitWithAuth2(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
36847
37338
  }
36848
37339
  } else {
36849
- await import_fs_extra16.default.ensureDir(path20.dirname(cacheDir));
37340
+ await import_fs_extra17.default.ensureDir(path21.dirname(cacheDir));
36850
37341
  await execGitWithAuth2(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
36851
37342
  }
36852
- return path20.join(cacheDir, "openclaw-config");
37343
+ return path21.join(cacheDir, "openclaw-config");
36853
37344
  }
36854
37345
  async function copyConfigFromCache2(cacheConfigDir, targetDir, onProgress) {
36855
37346
  const walk = async (dir, baseDir = dir) => {
36856
- const entries = await import_fs_extra16.default.readdir(dir, { withFileTypes: true });
37347
+ const entries = await import_fs_extra17.default.readdir(dir, { withFileTypes: true });
36857
37348
  for (const entry of entries) {
36858
- const sourcePath = path20.join(dir, entry.name);
36859
- const relativePath = path20.relative(baseDir, sourcePath);
36860
- const targetPath = path20.join(targetDir, relativePath);
37349
+ const sourcePath = path21.join(dir, entry.name);
37350
+ const relativePath = path21.relative(baseDir, sourcePath);
37351
+ const targetPath = path21.join(targetDir, relativePath);
36861
37352
  if (entry.isDirectory()) {
36862
- await import_fs_extra16.default.ensureDir(targetPath);
37353
+ await import_fs_extra17.default.ensureDir(targetPath);
36863
37354
  onProgress?.(relativePath, "directory");
36864
37355
  await walk(sourcePath, baseDir);
36865
37356
  } else {
36866
- await import_fs_extra16.default.copy(sourcePath, targetPath, { overwrite: true });
37357
+ await import_fs_extra17.default.copy(sourcePath, targetPath, { overwrite: true });
36867
37358
  onProgress?.(relativePath, "file");
36868
37359
  }
36869
37360
  }
@@ -36872,7 +37363,7 @@ async function copyConfigFromCache2(cacheConfigDir, targetDir, onProgress) {
36872
37363
  }
36873
37364
  async function installOpenclawProConfigs(options) {
36874
37365
  const { githubToken, openclawFolder, onProgress } = options;
36875
- const targetFolder = openclawFolder || path20.join(os16.homedir(), ".openclaw");
37366
+ const targetFolder = openclawFolder || path21.join(os17.homedir(), ".openclaw");
36876
37367
  try {
36877
37368
  const cacheConfigDir = await cloneOrUpdateRepo2(githubToken);
36878
37369
  await copyConfigFromCache2(cacheConfigDir, targetFolder, onProgress);
@@ -36883,28 +37374,28 @@ async function installOpenclawProConfigs(options) {
36883
37374
  }
36884
37375
 
36885
37376
  // src/lib/openclaw-token-storage.ts
36886
- var import_fs_extra17 = __toESM(require_lib4(), 1);
36887
- import os17 from "os";
36888
- import path21 from "path";
37377
+ var import_fs_extra18 = __toESM(require_lib4(), 1);
37378
+ import os18 from "os";
37379
+ import path22 from "path";
36889
37380
  function getConfigDir2() {
36890
- const platform = os17.platform();
37381
+ const platform = os18.platform();
36891
37382
  if (platform === "win32") {
36892
- return path21.join(process.env.APPDATA || os17.homedir(), "openclaw");
37383
+ return path22.join(process.env.APPDATA || os18.homedir(), "openclaw");
36893
37384
  }
36894
- return path21.join(os17.homedir(), ".config", "openclaw");
37385
+ return path22.join(os18.homedir(), ".config", "openclaw");
36895
37386
  }
36896
37387
  function getTokenPath() {
36897
- return path21.join(getConfigDir2(), "token.txt");
37388
+ return path22.join(getConfigDir2(), "token.txt");
36898
37389
  }
36899
37390
  async function saveOpenclawToken(githubToken) {
36900
37391
  const configDir = getConfigDir2();
36901
- await import_fs_extra17.default.ensureDir(configDir);
36902
- await import_fs_extra17.default.writeFile(getTokenPath(), githubToken, { mode: 384 });
37392
+ await import_fs_extra18.default.ensureDir(configDir);
37393
+ await import_fs_extra18.default.writeFile(getTokenPath(), githubToken, { mode: 384 });
36903
37394
  }
36904
37395
  async function getOpenclawToken() {
36905
37396
  const tokenPath = getTokenPath();
36906
- if (await import_fs_extra17.default.pathExists(tokenPath)) {
36907
- const token = await import_fs_extra17.default.readFile(tokenPath, "utf8");
37397
+ if (await import_fs_extra18.default.pathExists(tokenPath)) {
37398
+ const token = await import_fs_extra18.default.readFile(tokenPath, "utf8");
36908
37399
  return token.trim();
36909
37400
  }
36910
37401
  return null;
@@ -36912,12 +37403,12 @@ async function getOpenclawToken() {
36912
37403
  function getOpenclawTokenInfo() {
36913
37404
  return {
36914
37405
  path: getTokenPath(),
36915
- platform: os17.platform()
37406
+ platform: os18.platform()
36916
37407
  };
36917
37408
  }
36918
37409
 
36919
37410
  // src/commands/openclaw-pro.ts
36920
- var import_fs_extra18 = __toESM(require_lib4(), 1);
37411
+ var import_fs_extra19 = __toESM(require_lib4(), 1);
36921
37412
  var API_URL2 = "https://codeline.app/api/products";
36922
37413
  var OPENCLAW_PRODUCT_ID = "prd_t2GRwX3aH1";
36923
37414
  var CLAUDE_CODE_TOOLS_INSTRUCTIONS = `
@@ -37024,7 +37515,7 @@ async function openclawProSetupCommand(options = {}) {
37024
37515
  Se(source_default.red("❌ Not activated"));
37025
37516
  process.exit(1);
37026
37517
  }
37027
- const openclawDir = options.folder ? path22.resolve(options.folder) : path22.join(os18.homedir(), ".openclaw");
37518
+ const openclawDir = options.folder ? path23.resolve(options.folder) : path23.join(os19.homedir(), ".openclaw");
37028
37519
  const spinner = Y2();
37029
37520
  const onProgress = (file, type) => {
37030
37521
  spinner.message(`Installing: ${source_default.cyan(file)} ${source_default.gray(`(${type})`)}`);
@@ -37037,23 +37528,23 @@ async function openclawProSetupCommand(options = {}) {
37037
37528
  });
37038
37529
  spinner.stop("OpenClaw Pro configurations installed");
37039
37530
  let skillCount = 0;
37040
- const skillsDir = path22.join(openclawDir, "skills");
37041
- if (await import_fs_extra18.default.pathExists(skillsDir)) {
37042
- const items = await import_fs_extra18.default.readdir(skillsDir);
37531
+ const skillsDir = path23.join(openclawDir, "skills");
37532
+ if (await import_fs_extra19.default.pathExists(skillsDir)) {
37533
+ const items = await import_fs_extra19.default.readdir(skillsDir);
37043
37534
  const dirs = await Promise.all(items.map(async (item) => {
37044
- const stat = await import_fs_extra18.default.stat(path22.join(skillsDir, item));
37535
+ const stat = await import_fs_extra19.default.stat(path23.join(skillsDir, item));
37045
37536
  return stat.isDirectory();
37046
37537
  }));
37047
37538
  skillCount = dirs.filter(Boolean).length;
37048
37539
  }
37049
37540
  spinner.start("Setting up workspace TOOLS.md...");
37050
- const workspaceDir = path22.join(openclawDir, "workspace");
37051
- const toolsPath = path22.join(workspaceDir, "TOOLS.md");
37052
- await import_fs_extra18.default.ensureDir(workspaceDir);
37053
- if (await import_fs_extra18.default.pathExists(toolsPath)) {
37054
- const existingContent = await import_fs_extra18.default.readFile(toolsPath, "utf-8");
37541
+ const workspaceDir = path23.join(openclawDir, "workspace");
37542
+ const toolsPath = path23.join(workspaceDir, "TOOLS.md");
37543
+ await import_fs_extra19.default.ensureDir(workspaceDir);
37544
+ if (await import_fs_extra19.default.pathExists(toolsPath)) {
37545
+ const existingContent = await import_fs_extra19.default.readFile(toolsPath, "utf-8");
37055
37546
  if (!existingContent.includes("Claude Code CLI")) {
37056
- await import_fs_extra18.default.appendFile(toolsPath, `
37547
+ await import_fs_extra19.default.appendFile(toolsPath, `
37057
37548
 
37058
37549
  ` + CLAUDE_CODE_TOOLS_INSTRUCTIONS);
37059
37550
  spinner.stop("TOOLS.md updated with Claude Code instructions");
@@ -37067,7 +37558,7 @@ Skills define _how_ tools work. This file is for _your_ specifics — the stuff
37067
37558
 
37068
37559
  ${CLAUDE_CODE_TOOLS_INSTRUCTIONS}
37069
37560
  `;
37070
- await import_fs_extra18.default.writeFile(toolsPath, defaultToolsMd);
37561
+ await import_fs_extra19.default.writeFile(toolsPath, defaultToolsMd);
37071
37562
  spinner.stop("TOOLS.md created with Claude Code instructions");
37072
37563
  }
37073
37564
  spinner.start("Creating claude-run wrapper...");
@@ -37078,9 +37569,9 @@ ${CLAUDE_CODE_TOOLS_INSTRUCTIONS}
37078
37569
  script -q -c "claude $*" /dev/null
37079
37570
  `;
37080
37571
  const binDir = "/usr/local/bin";
37081
- const wrapperPath = path22.join(binDir, "claude-run");
37572
+ const wrapperPath = path23.join(binDir, "claude-run");
37082
37573
  try {
37083
- await import_fs_extra18.default.writeFile(wrapperPath, claudeRunWrapper, { mode: 493 });
37574
+ await import_fs_extra19.default.writeFile(wrapperPath, claudeRunWrapper, { mode: 493 });
37084
37575
  spinner.stop("claude-run wrapper created");
37085
37576
  } catch {
37086
37577
  spinner.stop("claude-run wrapper skipped (no write access to /usr/local/bin)");
@@ -37129,12 +37620,12 @@ async function openclawProUpdateCommand(options = {}) {
37129
37620
  }
37130
37621
 
37131
37622
  // src/commands/dynamic-scripts.ts
37132
- import path25 from "path";
37623
+ import path26 from "path";
37133
37624
  import { homedir } from "os";
37134
37625
 
37135
37626
  // src/lib/script-parser.ts
37136
- var import_fs_extra19 = __toESM(require_lib4(), 1);
37137
- import path23 from "path";
37627
+ var import_fs_extra20 = __toESM(require_lib4(), 1);
37628
+ import path24 from "path";
37138
37629
  var EXCLUDED_SCRIPTS = ["test", "lint", "format", "start"];
37139
37630
  var EXCLUDED_SUFFIXES = [":test", ":lint", ":test-fixtures", ":start"];
37140
37631
  function shouldIncludeScript(scriptName) {
@@ -37145,12 +37636,12 @@ function shouldIncludeScript(scriptName) {
37145
37636
  return true;
37146
37637
  }
37147
37638
  async function readScriptsPackageJson(claudeDir) {
37148
- const packageJsonPath = path23.join(claudeDir, "scripts", "package.json");
37639
+ const packageJsonPath = path24.join(claudeDir, "scripts", "package.json");
37149
37640
  try {
37150
- if (!await import_fs_extra19.default.pathExists(packageJsonPath)) {
37641
+ if (!await import_fs_extra20.default.pathExists(packageJsonPath)) {
37151
37642
  return null;
37152
37643
  }
37153
- const content = await import_fs_extra19.default.readFile(packageJsonPath, "utf-8");
37644
+ const content = await import_fs_extra20.default.readFile(packageJsonPath, "utf-8");
37154
37645
  const parsed = JSON.parse(content);
37155
37646
  return parsed.scripts || null;
37156
37647
  } catch (error) {
@@ -37194,14 +37685,14 @@ function groupScriptsByPrefix(commands) {
37194
37685
  }
37195
37686
 
37196
37687
  // src/commands/script-runner.ts
37197
- var import_fs_extra20 = __toESM(require_lib4(), 1);
37688
+ var import_fs_extra21 = __toESM(require_lib4(), 1);
37198
37689
  import { spawn as spawn2 } from "child_process";
37199
37690
  import { execSync as execSync4 } from "child_process";
37200
- import path24 from "path";
37201
- import os19 from "os";
37691
+ import path25 from "path";
37692
+ import os20 from "os";
37202
37693
  function checkCommand2(cmd) {
37203
37694
  try {
37204
- const isWindows2 = os19.platform() === "win32";
37695
+ const isWindows2 = os20.platform() === "win32";
37205
37696
  const whichCmd = isWindows2 ? `where ${cmd}` : `which ${cmd}`;
37206
37697
  execSync4(whichCmd, { stdio: "ignore" });
37207
37698
  return true;
@@ -37227,18 +37718,18 @@ async function executeScript(scriptName, claudeDir) {
37227
37718
  console.error(source_default.red("Bun is not installed. Install with: npm install -g bun"));
37228
37719
  return 1;
37229
37720
  }
37230
- const scriptsDir = path24.join(claudeDir, "scripts");
37231
- if (!await import_fs_extra20.default.pathExists(scriptsDir)) {
37721
+ const scriptsDir = path25.join(claudeDir, "scripts");
37722
+ if (!await import_fs_extra21.default.pathExists(scriptsDir)) {
37232
37723
  console.error(source_default.red(`Scripts directory not found at ${scriptsDir}`));
37233
37724
  console.log(source_default.gray("Run: aiblueprint agents setup"));
37234
37725
  return 1;
37235
37726
  }
37236
- const packageJsonPath = path24.join(scriptsDir, "package.json");
37237
- if (!await import_fs_extra20.default.pathExists(packageJsonPath)) {
37727
+ const packageJsonPath = path25.join(scriptsDir, "package.json");
37728
+ if (!await import_fs_extra21.default.pathExists(packageJsonPath)) {
37238
37729
  console.error(source_default.red(`package.json not found in ${scriptsDir}`));
37239
37730
  return 1;
37240
37731
  }
37241
- const packageJson = await import_fs_extra20.default.readJson(packageJsonPath);
37732
+ const packageJson = await import_fs_extra21.default.readJson(packageJsonPath);
37242
37733
  if (!packageJson.scripts || !packageJson.scripts[scriptName]) {
37243
37734
  console.error(source_default.red(`Script "${scriptName}" not found in package.json`));
37244
37735
  return 1;
@@ -37261,7 +37752,7 @@ async function executeScript(scriptName, claudeDir) {
37261
37752
 
37262
37753
  // src/commands/dynamic-scripts.ts
37263
37754
  function getClaudeDir(parentOptions) {
37264
- return parentOptions.claudeCodeFolder || parentOptions.folder ? path25.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path25.join(homedir(), ".claude");
37755
+ return parentOptions.claudeCodeFolder || parentOptions.folder ? path26.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path26.join(homedir(), ".claude");
37265
37756
  }
37266
37757
  async function registerDynamicScriptCommands(claudeCodeCmd, claudeDir) {
37267
37758
  const scripts = await readScriptsPackageJson(claudeDir);
@@ -37323,6 +37814,15 @@ function registerAgentsCommands(cmd) {
37323
37814
  codexFolder: parentOptions.codexFolder
37324
37815
  });
37325
37816
  });
37817
+ cmd.command("unify").description("Unify skills and agents into .agents and symlink tool folders back to it").action((options, command) => {
37818
+ const parentOptions = command.parent.opts();
37819
+ return agentsUnifyCommand({
37820
+ folder: parentOptions.folder,
37821
+ claudeCodeFolder: parentOptions.claudeCodeFolder,
37822
+ codexFolder: parentOptions.codexFolder,
37823
+ agentsFolder: parentOptions.agentsFolder
37824
+ });
37825
+ });
37326
37826
  const proCmd = cmd.command("pro").description("Manage AIBlueprint CLI Premium features");
37327
37827
  proCmd.command("activate [token]").description("Activate AIBlueprint CLI Premium with your access token").action((token) => {
37328
37828
  proActivateCommand(token);
@@ -37370,6 +37870,16 @@ function registerAgentsCommands(cmd) {
37370
37870
  function addConfigFolderOptions(cmd) {
37371
37871
  return cmd.option("-f, --folder <path>", "Root folder that contains .claude/, .codex/, .agents/ (default: $HOME)").option("--claudeCodeFolder <path>", "Override Claude Code folder (default: {folder}/.claude)").option("--codexFolder <path>", "Override Codex folder (default: {folder}/.codex)").option("--agentsFolder <path>", "Override shared agents folder (default: {folder}/.agents)");
37372
37872
  }
37873
+ function readConfigOptions(command, options = {}) {
37874
+ const parentOptions = command.parent?.opts() ?? {};
37875
+ const grandParentOptions = command.parent?.parent?.opts() ?? {};
37876
+ return {
37877
+ folder: options.folder ?? parentOptions.folder ?? grandParentOptions.folder,
37878
+ claudeCodeFolder: options.claudeCodeFolder ?? parentOptions.claudeCodeFolder ?? grandParentOptions.claudeCodeFolder,
37879
+ codexFolder: options.codexFolder ?? parentOptions.codexFolder ?? grandParentOptions.codexFolder,
37880
+ agentsFolder: options.agentsFolder ?? parentOptions.agentsFolder ?? grandParentOptions.agentsFolder
37881
+ };
37882
+ }
37373
37883
  var agentsCmd = program2.command("agents").description("AI coding configuration commands");
37374
37884
  registerAgentsCommands(agentsCmd);
37375
37885
  var aiCodingCmd = program2.command("ai-coding").description("Legacy alias for agents configuration commands");
@@ -37377,69 +37887,48 @@ registerAgentsCommands(aiCodingCmd);
37377
37887
  var claudeCodeCmd = program2.command("claude-code").description("Legacy alias for agents configuration commands");
37378
37888
  registerAgentsCommands(claudeCodeCmd);
37379
37889
  var configsCmd = addConfigFolderOptions(program2.command("configs").description("Save, load, undo, and inspect .claude/.codex/.agents configurations"));
37380
- configsCmd.command("save <name>").description("Save the current .claude, .codex, and .agents folders as a named config").option("--force", "Overwrite an existing saved config with the same name").action((name, options, command) => {
37381
- const parentOptions = command.parent.opts();
37890
+ addConfigFolderOptions(configsCmd.command("save <name>").description("Save the current .claude, .codex, and .agents folders as a named config").option("--force", "Overwrite an existing saved config with the same name")).action((name, options, command) => {
37891
+ const folderOptions = readConfigOptions(command, options);
37382
37892
  configsSaveCommand(name, {
37383
- folder: parentOptions.folder,
37384
- claudeCodeFolder: parentOptions.claudeCodeFolder,
37385
- codexFolder: parentOptions.codexFolder,
37386
- agentsFolder: parentOptions.agentsFolder,
37893
+ ...folderOptions,
37387
37894
  force: options.force
37388
37895
  });
37389
37896
  });
37390
- configsCmd.command("load <name>").description("Load a named config and backup the current folders first").action((name, options, command) => {
37391
- const parentOptions = command.parent.opts();
37897
+ addConfigFolderOptions(configsCmd.command("load <name>").description("Load a named config and backup the current folders first")).action((name, options, command) => {
37898
+ const folderOptions = readConfigOptions(command, options);
37392
37899
  configsLoadCommand(name, {
37393
- folder: parentOptions.folder,
37394
- claudeCodeFolder: parentOptions.claudeCodeFolder,
37395
- codexFolder: parentOptions.codexFolder,
37396
- agentsFolder: parentOptions.agentsFolder
37900
+ ...folderOptions
37397
37901
  });
37398
37902
  });
37399
- configsCmd.command("undo").description("Undo the most recent configs load by restoring its automatic backup").action((options, command) => {
37400
- const parentOptions = command.parent.opts();
37903
+ addConfigFolderOptions(configsCmd.command("undo").description("Undo the most recent configs load by restoring its automatic backup")).action((options, command) => {
37904
+ const folderOptions = readConfigOptions(command, options);
37401
37905
  configsUndoCommand({
37402
- folder: parentOptions.folder,
37403
- claudeCodeFolder: parentOptions.claudeCodeFolder,
37404
- codexFolder: parentOptions.codexFolder,
37405
- agentsFolder: parentOptions.agentsFolder
37906
+ ...folderOptions
37406
37907
  });
37407
37908
  });
37408
- configsCmd.command("list").description("List saved named configs").action((options, command) => {
37409
- const parentOptions = command.parent.opts();
37909
+ addConfigFolderOptions(configsCmd.command("list").description("List saved named configs")).action((options, command) => {
37910
+ const folderOptions = readConfigOptions(command, options);
37410
37911
  configsListCommand({
37411
- folder: parentOptions.folder,
37412
- claudeCodeFolder: parentOptions.claudeCodeFolder,
37413
- codexFolder: parentOptions.codexFolder,
37414
- agentsFolder: parentOptions.agentsFolder
37912
+ ...folderOptions
37415
37913
  });
37416
37914
  });
37417
37915
  var configsBackupsCmd = configsCmd.command("backups").description("Manage automatic config backups");
37418
- configsBackupsCmd.command("list").description("List automatic backups with reasons").action((options, command) => {
37419
- const parentOptions = command.parent.parent.opts();
37916
+ addConfigFolderOptions(configsBackupsCmd.command("list").description("List automatic backups with reasons")).action((options, command) => {
37917
+ const folderOptions = readConfigOptions(command, options);
37420
37918
  configsBackupsListCommand({
37421
- folder: parentOptions.folder,
37422
- claudeCodeFolder: parentOptions.claudeCodeFolder,
37423
- codexFolder: parentOptions.codexFolder,
37424
- agentsFolder: parentOptions.agentsFolder
37919
+ ...folderOptions
37425
37920
  });
37426
37921
  });
37427
- configsBackupsCmd.command("load <name>").description("Load a backup and backup the current folders first").action((name, options, command) => {
37428
- const parentOptions = command.parent.parent.opts();
37922
+ addConfigFolderOptions(configsBackupsCmd.command("load <name>").description("Load a backup and backup the current folders first")).action((name, options, command) => {
37923
+ const folderOptions = readConfigOptions(command, options);
37429
37924
  configsBackupsLoadCommand(name, {
37430
- folder: parentOptions.folder,
37431
- claudeCodeFolder: parentOptions.claudeCodeFolder,
37432
- codexFolder: parentOptions.codexFolder,
37433
- agentsFolder: parentOptions.agentsFolder
37925
+ ...folderOptions
37434
37926
  });
37435
37927
  });
37436
- configsBackupsCmd.command("create [reason]").description("Create a manual backup of the current config folders").action((reason, options, command) => {
37437
- const parentOptions = command.parent.parent.opts();
37928
+ addConfigFolderOptions(configsBackupsCmd.command("create [reason]").description("Create a manual backup of the current config folders")).action((reason, options, command) => {
37929
+ const folderOptions = readConfigOptions(command, options);
37438
37930
  configsBackupsCreateCommand(reason, {
37439
- folder: parentOptions.folder,
37440
- claudeCodeFolder: parentOptions.claudeCodeFolder,
37441
- codexFolder: parentOptions.codexFolder,
37442
- agentsFolder: parentOptions.agentsFolder
37931
+ ...folderOptions
37443
37932
  });
37444
37933
  });
37445
37934
  var openclawCmd = program2.command("openclaw").description("OpenClaw configuration commands").option("-f, --folder <path>", "Specify custom OpenClaw folder path (default: ~/.openclaw)");