aiblueprint-cli 1.4.60 → 1.4.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -32263,8 +32263,8 @@ var inquirer = {
32263
32263
  var lib_default = inquirer;
32264
32264
 
32265
32265
  // src/commands/setup.ts
32266
- var import_fs_extra8 = __toESM(require_lib4(), 1);
32267
- import path12 from "path";
32266
+ var import_fs_extra9 = __toESM(require_lib4(), 1);
32267
+ import path13 from "path";
32268
32268
  import os10 from "os";
32269
32269
 
32270
32270
  // node_modules/chalk/source/vendor/ansi-styles/index.js
@@ -33481,6 +33481,7 @@ var TUI_STATUS_LINE_BLOCK = `status_line = [
33481
33481
  status_line_use_colors = true`;
33482
33482
  var TUI_SECTION = `[tui]
33483
33483
  ${TUI_STATUS_LINE_BLOCK}`;
33484
+ var COMMAND_DENY_HOOK_MARKER = "command-deny-list.ts";
33484
33485
  function hasTopLevelKey(content, key) {
33485
33486
  let inSection = false;
33486
33487
  for (const line of content.split(/\r?\n/)) {
@@ -33503,7 +33504,7 @@ function getTopLevelAssignments(defaultConfig) {
33503
33504
  const trimmed = line.trim();
33504
33505
  if (!trimmed || trimmed.startsWith("#"))
33505
33506
  continue;
33506
- if (/^\[[^\]]+\]$/.test(trimmed))
33507
+ if (trimmed.startsWith("["))
33507
33508
  break;
33508
33509
  if (/^[A-Za-z0-9_-]+\s*=/.test(trimmed)) {
33509
33510
  assignments.push(line);
@@ -33553,6 +33554,45 @@ function appendBlock(content, block) {
33553
33554
  ${block}
33554
33555
  `;
33555
33556
  }
33557
+ function getDefaultHookBlocks(defaultConfig) {
33558
+ const lines = defaultConfig.split(/\r?\n/);
33559
+ const blocks = [];
33560
+ let current = null;
33561
+ for (const line of lines) {
33562
+ const trimmed = line.trim();
33563
+ const tableName = trimmed.startsWith("[[") && trimmed.endsWith("]]") ? trimmed.slice(2, -2) : trimmed.startsWith("[") && trimmed.endsWith("]") ? trimmed.slice(1, -1) : null;
33564
+ if (tableName) {
33565
+ const isHookTable = tableName.startsWith("hooks.");
33566
+ if (!isHookTable) {
33567
+ if (current) {
33568
+ blocks.push(current.join(`
33569
+ `).trimEnd());
33570
+ current = null;
33571
+ }
33572
+ continue;
33573
+ }
33574
+ current ??= [];
33575
+ }
33576
+ if (current) {
33577
+ current.push(line);
33578
+ }
33579
+ }
33580
+ if (current) {
33581
+ blocks.push(current.join(`
33582
+ `).trimEnd());
33583
+ }
33584
+ return blocks.filter(Boolean);
33585
+ }
33586
+ function mergeDefaultHooks(existingConfig, defaultConfig) {
33587
+ let merged = existingConfig;
33588
+ for (const hookBlock of getDefaultHookBlocks(defaultConfig)) {
33589
+ if (hookBlock.includes(COMMAND_DENY_HOOK_MARKER) && merged.includes(COMMAND_DENY_HOOK_MARKER)) {
33590
+ continue;
33591
+ }
33592
+ merged = appendBlock(merged, hookBlock);
33593
+ }
33594
+ return merged;
33595
+ }
33556
33596
  function mergeCodexConfig(existingConfig, defaultConfig) {
33557
33597
  let merged = existingConfig.trimEnd();
33558
33598
  for (const assignment of getTopLevelAssignments(defaultConfig)) {
@@ -33561,6 +33601,7 @@ function mergeCodexConfig(existingConfig, defaultConfig) {
33561
33601
  merged = appendBlock(merged, assignment);
33562
33602
  }
33563
33603
  }
33604
+ merged = mergeDefaultHooks(merged, defaultConfig).trimEnd();
33564
33605
  if (sectionHasKey(merged, "tui", "status_line")) {
33565
33606
  return `${merged}
33566
33607
  `;
@@ -33893,16 +33934,218 @@ async function listConfigBackups(options = {}) {
33893
33934
  return listSnapshots(paths.backupsDir, "backup");
33894
33935
  }
33895
33936
 
33937
+ // src/lib/codex-agents-renderer.ts
33938
+ var import_fs_extra8 = __toESM(require_lib4(), 1);
33939
+ import path12 from "path";
33940
+ var GENERATED_MARKER = "# Generated by aiblueprint-cli from Markdown agents.";
33941
+ var IGNORED_ENTRY_NAMES = new Set([".DS_Store", "node_modules"]);
33942
+ function parseFrontmatterValue(rawValue) {
33943
+ const value = rawValue.trim();
33944
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
33945
+ return value.slice(1, -1);
33946
+ }
33947
+ return value;
33948
+ }
33949
+ function parseMarkdownAgent(sourcePath, content) {
33950
+ if (!content.startsWith(`---
33951
+ `))
33952
+ return null;
33953
+ const end = content.indexOf(`
33954
+ ---`, 4);
33955
+ if (end === -1)
33956
+ return null;
33957
+ const frontmatterText = content.slice(4, end);
33958
+ const bodyStart = content.indexOf(`
33959
+ `, end + 4);
33960
+ const body = bodyStart === -1 ? "" : content.slice(bodyStart + 1).trim();
33961
+ const frontmatter = {};
33962
+ const lines = frontmatterText.split(`
33963
+ `);
33964
+ for (let index = 0;index < lines.length; index++) {
33965
+ const line = lines[index];
33966
+ const match = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
33967
+ if (!match)
33968
+ continue;
33969
+ const key = match[1];
33970
+ const rawValue = match[2];
33971
+ if (rawValue === ">-" || rawValue === ">") {
33972
+ const foldedLines = [];
33973
+ while (index + 1 < lines.length && /^\s+/.test(lines[index + 1])) {
33974
+ index++;
33975
+ foldedLines.push(lines[index].trim());
33976
+ }
33977
+ frontmatter[key] = foldedLines.join(" ");
33978
+ continue;
33979
+ }
33980
+ if (rawValue === "|-" || rawValue === "|") {
33981
+ const literalLines = [];
33982
+ while (index + 1 < lines.length && /^\s+/.test(lines[index + 1])) {
33983
+ index++;
33984
+ literalLines.push(lines[index].replace(/^\s{2}/, ""));
33985
+ }
33986
+ frontmatter[key] = literalLines.join(`
33987
+ `);
33988
+ continue;
33989
+ }
33990
+ frontmatter[key] = parseFrontmatterValue(rawValue);
33991
+ }
33992
+ return { sourcePath, frontmatter, body };
33993
+ }
33994
+ function normalizeCodexAgentName(value) {
33995
+ const normalized = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").replace(/_+/g, "_");
33996
+ if (!normalized)
33997
+ return "agent";
33998
+ if (/^[0-9]/.test(normalized))
33999
+ return `agent_${normalized}`;
34000
+ return normalized;
34001
+ }
34002
+ function mapModel(model) {
34003
+ switch (model?.trim().toLowerCase()) {
34004
+ case "haiku":
34005
+ return "gpt-5.4-mini";
34006
+ case "sonnet":
34007
+ return "gpt-5.4";
34008
+ case "opus":
34009
+ return "gpt-5.5";
34010
+ case "inherit":
34011
+ case "":
34012
+ case undefined:
34013
+ return null;
34014
+ default:
34015
+ return model ?? null;
34016
+ }
34017
+ }
34018
+ function tomlString(value) {
34019
+ return JSON.stringify(value);
34020
+ }
34021
+ function tomlMultilineLiteral(value) {
34022
+ if (value.includes("'''")) {
34023
+ return tomlString(value);
34024
+ }
34025
+ return `'''
34026
+ ${value}
34027
+ '''`;
34028
+ }
34029
+ function buildDeveloperInstructions(agent) {
34030
+ const toolHints = agent.frontmatter.tools?.trim();
34031
+ const color = agent.frontmatter.color?.trim();
34032
+ const notes = [];
34033
+ if (toolHints) {
34034
+ notes.push(`Original tool hints from the Markdown agent: ${toolHints}.`);
34035
+ }
34036
+ if (color) {
34037
+ notes.push(`Original display color metadata: ${color}.`);
34038
+ }
34039
+ const prefix = [
34040
+ `Source Markdown agent: ${path12.basename(agent.sourcePath)}.`,
34041
+ ...notes
34042
+ ].join(`
34043
+ `);
34044
+ return `${prefix}
34045
+
34046
+ ${agent.body}`.trim();
34047
+ }
34048
+ function renderToml(agent) {
34049
+ const rawName = agent.frontmatter.name?.trim();
34050
+ const description = agent.frontmatter.description?.trim();
34051
+ if (!rawName || !description || !agent.body) {
34052
+ return null;
34053
+ }
34054
+ const name = normalizeCodexAgentName(rawName);
34055
+ const model = mapModel(agent.frontmatter.model);
34056
+ const lines = [
34057
+ GENERATED_MARKER,
34058
+ `# Source: ${agent.sourcePath}`,
34059
+ `name = ${tomlString(name)}`,
34060
+ `description = ${tomlString(description)}`
34061
+ ];
34062
+ if (model) {
34063
+ lines.push(`model = ${tomlString(model)}`);
34064
+ }
34065
+ lines.push(`developer_instructions = ${tomlMultilineLiteral(buildDeveloperInstructions(agent))}`);
34066
+ lines.push("");
34067
+ return {
34068
+ name,
34069
+ content: lines.join(`
34070
+ `)
34071
+ };
34072
+ }
34073
+ async function canOverwriteTarget(targetPath, overwrite) {
34074
+ if (overwrite)
34075
+ return true;
34076
+ const existing = await import_fs_extra8.default.readFile(targetPath, "utf-8").catch(() => null);
34077
+ return existing?.startsWith(GENERATED_MARKER) ?? false;
34078
+ }
34079
+ async function ensureRealTargetDir(targetDir) {
34080
+ const stat = await import_fs_extra8.default.lstat(targetDir).catch(() => null);
34081
+ if (stat?.isSymbolicLink()) {
34082
+ await import_fs_extra8.default.remove(targetDir);
34083
+ }
34084
+ await import_fs_extra8.default.ensureDir(targetDir);
34085
+ }
34086
+ async function renderCodexAgentsFromMarkdown(options = {}) {
34087
+ const folders = resolveFolders(options);
34088
+ const sourceDir = path12.join(folders.agentsDir, "agents");
34089
+ const targetDir = path12.join(folders.codexDir, "agents");
34090
+ const result = {
34091
+ sourceDir,
34092
+ targetDir,
34093
+ rendered: [],
34094
+ skipped: []
34095
+ };
34096
+ if (!await import_fs_extra8.default.pathExists(sourceDir)) {
34097
+ return result;
34098
+ }
34099
+ await import_fs_extra8.default.ensureDir(folders.codexDir);
34100
+ await ensureRealTargetDir(targetDir);
34101
+ const entries = await import_fs_extra8.default.readdir(sourceDir, { withFileTypes: true });
34102
+ for (const entry of entries) {
34103
+ if (IGNORED_ENTRY_NAMES.has(entry.name))
34104
+ continue;
34105
+ if (!entry.isFile() || path12.extname(entry.name) !== ".md")
34106
+ continue;
34107
+ const sourcePath = path12.join(sourceDir, entry.name);
34108
+ const parsed = parseMarkdownAgent(sourcePath, await import_fs_extra8.default.readFile(sourcePath, "utf-8"));
34109
+ if (!parsed) {
34110
+ result.skipped.push({ source: sourcePath, reason: "Missing YAML frontmatter" });
34111
+ continue;
34112
+ }
34113
+ const rendered = renderToml(parsed);
34114
+ if (!rendered) {
34115
+ result.skipped.push({
34116
+ source: sourcePath,
34117
+ reason: "Missing name, description, or instruction body"
34118
+ });
34119
+ continue;
34120
+ }
34121
+ const targetPath = path12.join(targetDir, `${rendered.name}.toml`);
34122
+ if (await import_fs_extra8.default.pathExists(targetPath) && !await canOverwriteTarget(targetPath, Boolean(options.overwrite))) {
34123
+ result.skipped.push({
34124
+ source: sourcePath,
34125
+ reason: `Codex agent already exists at ${targetPath}`
34126
+ });
34127
+ continue;
34128
+ }
34129
+ await import_fs_extra8.default.writeFile(targetPath, rendered.content, "utf-8");
34130
+ result.rendered.push({
34131
+ source: sourcePath,
34132
+ target: targetPath,
34133
+ name: rendered.name
34134
+ });
34135
+ }
34136
+ return result;
34137
+ }
34138
+
33896
34139
  // src/commands/setup.ts
33897
34140
  var __filename2 = fileURLToPath2(import.meta.url);
33898
34141
  var __dirname2 = dirname2(__filename2);
33899
34142
  async function resolveClaudeAssetPath(sourceDir, name) {
33900
34143
  const candidates = [
33901
- path12.join(sourceDir, "claude-config", name),
33902
- path12.join(sourceDir, name)
34144
+ path13.join(sourceDir, "claude-config", name),
34145
+ path13.join(sourceDir, name)
33903
34146
  ];
33904
34147
  for (const candidate of candidates) {
33905
- if (await import_fs_extra8.default.pathExists(candidate))
34148
+ if (await import_fs_extra9.default.pathExists(candidate))
33906
34149
  return candidate;
33907
34150
  }
33908
34151
  return null;
@@ -33990,8 +34233,8 @@ async function setupCommand(params = {}) {
33990
34233
  console.log(source_default.gray(`Claude: ${claudeDir}`));
33991
34234
  console.log(source_default.gray(`Codex: ${codexDir}`));
33992
34235
  console.log(source_default.gray(`Agents: ${agentsDir}`));
33993
- await import_fs_extra8.default.ensureDir(claudeDir);
33994
- await import_fs_extra8.default.ensureDir(agentsDir);
34236
+ await import_fs_extra9.default.ensureDir(claudeDir);
34237
+ await import_fs_extra9.default.ensureDir(agentsDir);
33995
34238
  s.start("Creating backup of existing configuration");
33996
34239
  const backupPath = await createConfigBackup({ folder, claudeCodeFolder, codexFolder, agentsFolder }, "Before running aiblueprint setup", "setup", "aiblueprint-setup");
33997
34240
  if (backupPath) {
@@ -34019,11 +34262,11 @@ async function setupCommand(params = {}) {
34019
34262
  s.start("Setting up scripts");
34020
34263
  const scriptsSource = await resolveClaudeAssetPath(sourceDir, "scripts");
34021
34264
  if (scriptsSource) {
34022
- await import_fs_extra8.default.copy(scriptsSource, path12.join(claudeDir, "scripts"), {
34265
+ await import_fs_extra9.default.copy(scriptsSource, path13.join(claudeDir, "scripts"), {
34023
34266
  overwrite: true
34024
34267
  });
34025
- await replacePathPlaceholdersInDir(path12.join(claudeDir, "scripts"), claudeDir);
34026
- await import_fs_extra8.default.ensureDir(path12.join(claudeDir, "scripts/statusline/data"));
34268
+ await replacePathPlaceholdersInDir(path13.join(claudeDir, "scripts"), claudeDir);
34269
+ await import_fs_extra9.default.ensureDir(path13.join(claudeDir, "scripts/statusline/data"));
34027
34270
  s.stop("Scripts installed");
34028
34271
  } else {
34029
34272
  s.stop("Scripts not available in repository");
@@ -34031,8 +34274,8 @@ async function setupCommand(params = {}) {
34031
34274
  }
34032
34275
  if (options.aiblueprintAgents) {
34033
34276
  s.start("Setting up AIBlueprint agents");
34034
- const agentsSource = path12.join(sourceDir, "agents");
34035
- if (await import_fs_extra8.default.pathExists(agentsSource)) {
34277
+ const agentsSource = path13.join(sourceDir, "agents");
34278
+ if (await import_fs_extra9.default.pathExists(agentsSource)) {
34036
34279
  const installResult = await installCategoryToAgents(agentsSource, "agents", agentsDir, claudeDir, { migrateClaudeDirs: true, silent: true });
34037
34280
  const summary = [
34038
34281
  installResult.copied.length && `${installResult.copied.length} copied`,
@@ -34047,8 +34290,8 @@ async function setupCommand(params = {}) {
34047
34290
  }
34048
34291
  if (options.aiblueprintSkills) {
34049
34292
  s.start("Setting up AIBlueprint Skills");
34050
- const skillsSourcePath = path12.join(sourceDir, "skills");
34051
- if (await import_fs_extra8.default.pathExists(skillsSourcePath)) {
34293
+ const skillsSourcePath = path13.join(sourceDir, "skills");
34294
+ if (await import_fs_extra9.default.pathExists(skillsSourcePath)) {
34052
34295
  const installResult = await installCategoryToAgents(skillsSourcePath, "skills", agentsDir, claudeDir, { migrateClaudeDirs: true, silent: true });
34053
34296
  const summary = [
34054
34297
  installResult.copied.length && `${installResult.copied.length} copied`,
@@ -34068,18 +34311,18 @@ async function setupCommand(params = {}) {
34068
34311
  }
34069
34312
  if (options.installCodex) {
34070
34313
  s.start("Setting up Codex");
34071
- await import_fs_extra8.default.ensureDir(codexDir);
34072
- const codexConfigSource = path12.join(sourceDir, "codex-config");
34073
- if (await import_fs_extra8.default.pathExists(codexConfigSource)) {
34074
- const codexConfigPath = path12.join(codexConfigSource, "config.toml");
34075
- if (await import_fs_extra8.default.pathExists(codexConfigPath)) {
34314
+ await import_fs_extra9.default.ensureDir(codexDir);
34315
+ const codexConfigSource = path13.join(sourceDir, "codex-config");
34316
+ if (await import_fs_extra9.default.pathExists(codexConfigSource)) {
34317
+ const codexConfigPath = path13.join(codexConfigSource, "config.toml");
34318
+ if (await import_fs_extra9.default.pathExists(codexConfigPath)) {
34076
34319
  await mergeCodexConfigFile(codexConfigPath, codexDir);
34077
34320
  }
34078
- const entries = await import_fs_extra8.default.readdir(codexConfigSource);
34321
+ const entries = await import_fs_extra9.default.readdir(codexConfigSource);
34079
34322
  for (const entry of entries) {
34080
34323
  if (entry === "config.toml")
34081
34324
  continue;
34082
- await import_fs_extra8.default.copy(path12.join(codexConfigSource, entry), path12.join(codexDir, entry), {
34325
+ await import_fs_extra9.default.copy(path13.join(codexConfigSource, entry), path13.join(codexDir, entry), {
34083
34326
  overwrite: false
34084
34327
  });
34085
34328
  }
@@ -34088,7 +34331,12 @@ async function setupCommand(params = {}) {
34088
34331
  await syncCategorySymlinks("skills", agentsDir, codexDir, undefined, true);
34089
34332
  }
34090
34333
  if (options.aiblueprintAgents) {
34091
- await syncCategorySymlinks("agents", agentsDir, codexDir, undefined, true);
34334
+ await renderCodexAgentsFromMarkdown({
34335
+ folder,
34336
+ claudeCodeFolder,
34337
+ codexFolder,
34338
+ agentsFolder
34339
+ });
34092
34340
  }
34093
34341
  s.stop("Codex configured");
34094
34342
  }
@@ -34154,8 +34402,8 @@ Next steps:`));
34154
34402
  }
34155
34403
 
34156
34404
  // src/commands/setup-terminal.ts
34157
- var import_fs_extra9 = __toESM(require_lib4(), 1);
34158
- import path13 from "path";
34405
+ var import_fs_extra10 = __toESM(require_lib4(), 1);
34406
+ import path14 from "path";
34159
34407
  import os11 from "os";
34160
34408
  import { execSync as execSync3, exec as exec2 } from "child_process";
34161
34409
  var OHMYZSH_INSTALL_URL = "https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh";
@@ -34190,16 +34438,16 @@ function commandExists(cmd) {
34190
34438
  }
34191
34439
  }
34192
34440
  function isOhMyZshInstalled(homeDir) {
34193
- const ohMyZshDir = path13.join(homeDir, ".oh-my-zsh");
34194
- return import_fs_extra9.default.existsSync(ohMyZshDir);
34441
+ const ohMyZshDir = path14.join(homeDir, ".oh-my-zsh");
34442
+ return import_fs_extra10.default.existsSync(ohMyZshDir);
34195
34443
  }
34196
34444
  function backupFile(filePath) {
34197
- if (!import_fs_extra9.default.existsSync(filePath))
34445
+ if (!import_fs_extra10.default.existsSync(filePath))
34198
34446
  return null;
34199
34447
  const timestamp2 = new Date().toISOString().replace(/[:.]/g, "-");
34200
34448
  const backupPath = `${filePath}.backup-${timestamp2}`;
34201
34449
  try {
34202
- import_fs_extra9.default.copyFileSync(filePath, backupPath);
34450
+ import_fs_extra10.default.copyFileSync(filePath, backupPath);
34203
34451
  return backupPath;
34204
34452
  } catch (error) {
34205
34453
  throw new Error(`Failed to create backup: ${error.message}`);
@@ -34238,7 +34486,7 @@ function installPrerequisiteSync(packageName, installCmd) {
34238
34486
  async function installOhMyZsh(homeDir) {
34239
34487
  return new Promise((resolve, reject) => {
34240
34488
  const installCmd = `sh -c "$(curl -fsSL ${OHMYZSH_INSTALL_URL})" "" --unattended`;
34241
- const env2 = { ...process.env, HOME: homeDir, ZSH: path13.join(homeDir, ".oh-my-zsh") };
34489
+ const env2 = { ...process.env, HOME: homeDir, ZSH: path14.join(homeDir, ".oh-my-zsh") };
34242
34490
  exec2(installCmd, { timeout: INSTALL_TIMEOUT, env: env2 }, (error, stdout, stderr) => {
34243
34491
  if (error) {
34244
34492
  if ("killed" in error && error.killed) {
@@ -34259,8 +34507,8 @@ async function installPlugin(pluginName, repoUrl, homeDir) {
34259
34507
  if (!/^https:\/\/github\.com\/[\w-]+\/[\w-]+$/.test(repoUrl)) {
34260
34508
  throw new Error(`Invalid repository URL: ${repoUrl}`);
34261
34509
  }
34262
- const customPluginsDir = path13.join(homeDir, ".oh-my-zsh/custom/plugins", pluginName);
34263
- if (import_fs_extra9.default.existsSync(customPluginsDir)) {
34510
+ const customPluginsDir = path14.join(homeDir, ".oh-my-zsh/custom/plugins", pluginName);
34511
+ if (import_fs_extra10.default.existsSync(customPluginsDir)) {
34264
34512
  return;
34265
34513
  }
34266
34514
  return new Promise((resolve, reject) => {
@@ -34278,20 +34526,20 @@ async function installPlugin(pluginName, repoUrl, homeDir) {
34278
34526
  });
34279
34527
  }
34280
34528
  function updateZshrcTheme(theme, homeDir) {
34281
- const zshrcPath = path13.join(homeDir, ".zshrc");
34529
+ const zshrcPath = path14.join(homeDir, ".zshrc");
34282
34530
  const sanitizedTheme = sanitizeThemeName(theme);
34283
- if (!import_fs_extra9.default.existsSync(zshrcPath)) {
34531
+ if (!import_fs_extra10.default.existsSync(zshrcPath)) {
34284
34532
  throw new Error(".zshrc file not found. Please ensure Oh My ZSH is installed correctly.");
34285
34533
  }
34286
34534
  try {
34287
- let content = import_fs_extra9.default.readFileSync(zshrcPath, "utf-8");
34535
+ let content = import_fs_extra10.default.readFileSync(zshrcPath, "utf-8");
34288
34536
  if (content.match(/^ZSH_THEME=/m)) {
34289
34537
  content = content.replace(/^ZSH_THEME=.*/m, `ZSH_THEME="${sanitizedTheme}"`);
34290
34538
  } else {
34291
34539
  content = `ZSH_THEME="${sanitizedTheme}"
34292
34540
  ${content}`;
34293
34541
  }
34294
- import_fs_extra9.default.writeFileSync(zshrcPath, content);
34542
+ import_fs_extra10.default.writeFileSync(zshrcPath, content);
34295
34543
  } catch (error) {
34296
34544
  if (error.message.includes(".zshrc file not found")) {
34297
34545
  throw error;
@@ -34300,12 +34548,12 @@ ${content}`;
34300
34548
  }
34301
34549
  }
34302
34550
  function updateZshrcPlugins(plugins, homeDir) {
34303
- const zshrcPath = path13.join(homeDir, ".zshrc");
34304
- if (!import_fs_extra9.default.existsSync(zshrcPath)) {
34551
+ const zshrcPath = path14.join(homeDir, ".zshrc");
34552
+ if (!import_fs_extra10.default.existsSync(zshrcPath)) {
34305
34553
  throw new Error(".zshrc file not found. Please ensure Oh My ZSH is installed correctly.");
34306
34554
  }
34307
34555
  try {
34308
- let content = import_fs_extra9.default.readFileSync(zshrcPath, "utf-8");
34556
+ let content = import_fs_extra10.default.readFileSync(zshrcPath, "utf-8");
34309
34557
  const pluginsString = plugins.join(" ");
34310
34558
  if (content.match(/^plugins=\(/m)) {
34311
34559
  content = content.replace(/^plugins=\([^)]*\)/m, `plugins=(${pluginsString})`);
@@ -34313,7 +34561,7 @@ function updateZshrcPlugins(plugins, homeDir) {
34313
34561
  content = `${content}
34314
34562
  plugins=(${pluginsString})`;
34315
34563
  }
34316
- import_fs_extra9.default.writeFileSync(zshrcPath, content);
34564
+ import_fs_extra10.default.writeFileSync(zshrcPath, content);
34317
34565
  } catch (error) {
34318
34566
  if (error.message.includes(".zshrc file not found")) {
34319
34567
  throw error;
@@ -34420,8 +34668,8 @@ Installing missing prerequisites: ${missingPrereqs.join(", ")}`));
34420
34668
  selectedTheme = themeAnswer.theme;
34421
34669
  }
34422
34670
  }
34423
- const zshrcPath = path13.join(homeDir, ".zshrc");
34424
- if (import_fs_extra9.default.existsSync(zshrcPath)) {
34671
+ const zshrcPath = path14.join(homeDir, ".zshrc");
34672
+ if (import_fs_extra10.default.existsSync(zshrcPath)) {
34425
34673
  s.start("Backing up .zshrc");
34426
34674
  const backupPath = backupFile(zshrcPath);
34427
34675
  if (backupPath) {
@@ -34471,37 +34719,37 @@ Next steps:`));
34471
34719
  }
34472
34720
 
34473
34721
  // src/commands/setup/symlinks.ts
34474
- var import_fs_extra10 = __toESM(require_lib4(), 1);
34475
- import path14 from "path";
34722
+ var import_fs_extra11 = __toESM(require_lib4(), 1);
34723
+ import path15 from "path";
34476
34724
  import os12 from "os";
34477
34725
  async function getToolPaths(tool, customFolder) {
34478
34726
  let baseDir;
34479
34727
  switch (tool) {
34480
34728
  case "claude-code":
34481
- baseDir = customFolder ? path14.resolve(customFolder) : path14.join(os12.homedir(), ".claude");
34729
+ baseDir = customFolder ? path15.resolve(customFolder) : path15.join(os12.homedir(), ".claude");
34482
34730
  return {
34483
34731
  baseDir,
34484
- commandsPath: path14.join(baseDir, "commands"),
34485
- agentsPath: path14.join(baseDir, "agents")
34732
+ commandsPath: path15.join(baseDir, "commands"),
34733
+ agentsPath: path15.join(baseDir, "agents")
34486
34734
  };
34487
34735
  case "codex":
34488
- baseDir = customFolder ? path14.resolve(customFolder) : path14.join(os12.homedir(), ".codex");
34736
+ baseDir = customFolder ? path15.resolve(customFolder) : path15.join(os12.homedir(), ".codex");
34489
34737
  return {
34490
34738
  baseDir,
34491
- agentsPath: path14.join(baseDir, "agents")
34739
+ agentsPath: path15.join(baseDir, "agents")
34492
34740
  };
34493
34741
  case "opencode":
34494
- baseDir = customFolder ? path14.resolve(customFolder) : path14.join(os12.homedir(), ".config", "opencode");
34742
+ baseDir = customFolder ? path15.resolve(customFolder) : path15.join(os12.homedir(), ".config", "opencode");
34495
34743
  return {
34496
34744
  baseDir,
34497
- commandsPath: path14.join(baseDir, "command")
34745
+ commandsPath: path15.join(baseDir, "command")
34498
34746
  };
34499
34747
  case "factoryai":
34500
- baseDir = customFolder ? path14.resolve(customFolder) : path14.join(os12.homedir(), ".factory");
34748
+ baseDir = customFolder ? path15.resolve(customFolder) : path15.join(os12.homedir(), ".factory");
34501
34749
  return {
34502
34750
  baseDir,
34503
- commandsPath: path14.join(baseDir, "commands"),
34504
- agentsPath: path14.join(baseDir, "droids")
34751
+ commandsPath: path15.join(baseDir, "commands"),
34752
+ agentsPath: path15.join(baseDir, "droids")
34505
34753
  };
34506
34754
  default:
34507
34755
  throw new Error(`Unknown tool type: ${tool}`);
@@ -34509,18 +34757,18 @@ async function getToolPaths(tool, customFolder) {
34509
34757
  }
34510
34758
  async function createSymlink(sourcePath, targetPath, options = {}) {
34511
34759
  try {
34512
- const sourceExists = await import_fs_extra10.default.pathExists(sourcePath);
34760
+ const sourceExists = await import_fs_extra11.default.pathExists(sourcePath);
34513
34761
  if (!sourceExists) {
34514
34762
  console.log(source_default.yellow(` Source path ${sourcePath} does not exist. Skipping symlink creation...`));
34515
34763
  return false;
34516
34764
  }
34517
- const targetDir = path14.dirname(targetPath);
34518
- await import_fs_extra10.default.ensureDir(targetDir);
34519
- const targetExists = await import_fs_extra10.default.pathExists(targetPath);
34765
+ const targetDir = path15.dirname(targetPath);
34766
+ await import_fs_extra11.default.ensureDir(targetDir);
34767
+ const targetExists = await import_fs_extra11.default.pathExists(targetPath);
34520
34768
  if (targetExists) {
34521
- const stat = await import_fs_extra10.default.lstat(targetPath);
34769
+ const stat = await import_fs_extra11.default.lstat(targetPath);
34522
34770
  if (stat.isSymbolicLink()) {
34523
- await import_fs_extra10.default.remove(targetPath);
34771
+ await import_fs_extra11.default.remove(targetPath);
34524
34772
  } else {
34525
34773
  console.log(source_default.yellow(options.skipMessage || ` ${targetPath} already exists and is not a symlink. Skipping...`));
34526
34774
  return false;
@@ -34528,9 +34776,9 @@ async function createSymlink(sourcePath, targetPath, options = {}) {
34528
34776
  }
34529
34777
  const isWindows2 = os12.platform() === "win32";
34530
34778
  if (isWindows2) {
34531
- await import_fs_extra10.default.symlink(sourcePath, targetPath, "junction");
34779
+ await import_fs_extra11.default.symlink(sourcePath, targetPath, "junction");
34532
34780
  } else {
34533
- await import_fs_extra10.default.symlink(sourcePath, targetPath);
34781
+ await import_fs_extra11.default.symlink(sourcePath, targetPath);
34534
34782
  }
34535
34783
  return true;
34536
34784
  } catch (error) {
@@ -34711,11 +34959,11 @@ async function symlinkCommand(params = {}) {
34711
34959
  }
34712
34960
 
34713
34961
  // src/lib/agents-unifier.ts
34714
- var import_fs_extra11 = __toESM(require_lib4(), 1);
34962
+ var import_fs_extra12 = __toESM(require_lib4(), 1);
34715
34963
  import crypto from "crypto";
34716
34964
  import os13 from "os";
34717
- import path15 from "path";
34718
- var IGNORED_ENTRY_NAMES = new Set([
34965
+ import path16 from "path";
34966
+ var IGNORED_ENTRY_NAMES2 = new Set([
34719
34967
  ".DS_Store",
34720
34968
  ".git",
34721
34969
  "node_modules"
@@ -34724,7 +34972,7 @@ function uniqueByPath(candidates) {
34724
34972
  const seen = new Set;
34725
34973
  const unique = [];
34726
34974
  for (const candidate of candidates) {
34727
- const resolved = path15.resolve(candidate.path);
34975
+ const resolved = path16.resolve(candidate.path);
34728
34976
  if (seen.has(resolved))
34729
34977
  continue;
34730
34978
  seen.add(resolved);
@@ -34734,109 +34982,123 @@ function uniqueByPath(candidates) {
34734
34982
  }
34735
34983
  function getContainerCandidates(options) {
34736
34984
  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");
34985
+ const cursorDir = path16.join(folders.rootDir, ".cursor");
34986
+ const factoryDir = path16.join(folders.rootDir, ".factory");
34987
+ const opencodeDir = path16.join(folders.rootDir, ".config", "opencode");
34740
34988
  return uniqueByPath([
34741
34989
  {
34742
34990
  category: "skills",
34743
34991
  label: "agents-skills",
34744
- path: path15.join(folders.agentsDir, "skills"),
34992
+ path: path16.join(folders.agentsDir, "skills"),
34745
34993
  isDestination: true
34746
34994
  },
34747
34995
  {
34748
34996
  category: "skills",
34749
34997
  label: "claude-skills",
34750
- path: path15.join(folders.claudeDir, "skills"),
34998
+ path: path16.join(folders.claudeDir, "skills"),
34751
34999
  linkWhenMissing: true
34752
35000
  },
34753
35001
  {
34754
35002
  category: "skills",
34755
35003
  label: "codex-skills",
34756
- path: path15.join(folders.codexDir, "skills"),
35004
+ path: path16.join(folders.codexDir, "skills"),
34757
35005
  linkWhenMissing: true
34758
35006
  },
34759
35007
  {
34760
35008
  category: "skills",
34761
35009
  label: "cursor-skills",
34762
- path: path15.join(cursorDir, "skills"),
35010
+ path: path16.join(cursorDir, "skills"),
34763
35011
  linkWhenParentExists: true
34764
35012
  },
34765
35013
  {
34766
35014
  category: "skills",
34767
35015
  label: "cursor-skills-cursor",
34768
- path: path15.join(cursorDir, "skills-cursor"),
35016
+ path: path16.join(cursorDir, "skills-cursor"),
34769
35017
  linkWhenParentExists: true
34770
35018
  },
34771
35019
  {
34772
35020
  category: "skills",
34773
35021
  label: "factory-skills",
34774
- path: path15.join(factoryDir, "skills"),
35022
+ path: path16.join(factoryDir, "skills"),
34775
35023
  linkWhenParentExists: true
34776
35024
  },
34777
35025
  {
34778
35026
  category: "skills",
34779
35027
  label: "opencode-skill",
34780
- path: path15.join(opencodeDir, "skill"),
35028
+ path: path16.join(opencodeDir, "skill"),
34781
35029
  linkWhenParentExists: true
34782
35030
  },
34783
35031
  {
34784
35032
  category: "skills",
34785
35033
  label: "opencode-skills",
34786
- path: path15.join(opencodeDir, "skills"),
35034
+ path: path16.join(opencodeDir, "skills"),
34787
35035
  linkWhenParentExists: true
34788
35036
  },
34789
35037
  {
34790
35038
  category: "agents",
34791
35039
  label: "agents-agents",
34792
- path: path15.join(folders.agentsDir, "agents"),
35040
+ path: path16.join(folders.agentsDir, "agents"),
34793
35041
  isDestination: true
34794
35042
  },
34795
35043
  {
34796
35044
  category: "agents",
34797
35045
  label: "claude-agents",
34798
- path: path15.join(folders.claudeDir, "agents"),
35046
+ path: path16.join(folders.claudeDir, "agents"),
34799
35047
  linkWhenMissing: true
34800
35048
  },
34801
35049
  {
34802
35050
  category: "agents",
34803
35051
  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
35052
+ path: path16.join(folders.claudeDir, "agnets")
34811
35053
  },
34812
35054
  {
34813
35055
  category: "agents",
34814
35056
  label: "cursor-agents",
34815
- path: path15.join(cursorDir, "agents"),
35057
+ path: path16.join(cursorDir, "agents"),
34816
35058
  linkWhenParentExists: true
34817
35059
  },
34818
35060
  {
34819
35061
  category: "agents",
34820
35062
  label: "factory-droids",
34821
- path: path15.join(factoryDir, "droids"),
35063
+ path: path16.join(factoryDir, "droids"),
34822
35064
  linkWhenParentExists: true
34823
35065
  },
34824
35066
  {
34825
35067
  category: "agents",
34826
35068
  label: "opencode-agent",
34827
- path: path15.join(opencodeDir, "agent"),
35069
+ path: path16.join(opencodeDir, "agent"),
34828
35070
  linkWhenParentExists: true
34829
35071
  },
34830
35072
  {
34831
35073
  category: "agents",
34832
35074
  label: "opencode-agents",
34833
- path: path15.join(opencodeDir, "agents"),
35075
+ path: path16.join(opencodeDir, "agents"),
34834
35076
  linkWhenParentExists: true
34835
35077
  }
34836
35078
  ]);
34837
35079
  }
35080
+ function getInstructionFileCandidates(options) {
35081
+ const folders = resolveFolders(options);
35082
+ return uniqueByPath([
35083
+ {
35084
+ label: "agents-instructions",
35085
+ path: path16.join(folders.agentsDir, "AGENTS.md"),
35086
+ isDestination: true
35087
+ },
35088
+ {
35089
+ label: "claude-instructions",
35090
+ path: path16.join(folders.claudeDir, "CLAUDE.md"),
35091
+ linkWhenMissing: true
35092
+ },
35093
+ {
35094
+ label: "codex-instructions",
35095
+ path: path16.join(folders.codexDir, "AGENTS.md"),
35096
+ linkWhenMissing: true
35097
+ }
35098
+ ]);
35099
+ }
34838
35100
  function shouldCollectEntry(category, entry) {
34839
- if (IGNORED_ENTRY_NAMES.has(entry.name))
35101
+ if (IGNORED_ENTRY_NAMES2.has(entry.name))
34840
35102
  return false;
34841
35103
  if (category === "skills" && entry.name === ".cursor-managed-skills-manifest.json") {
34842
35104
  return true;
@@ -34844,42 +35106,42 @@ function shouldCollectEntry(category, entry) {
34844
35106
  return entry.isFile() || entry.isDirectory() || entry.isSymbolicLink();
34845
35107
  }
34846
35108
  async function pathExistsOrSymlink(targetPath) {
34847
- const stat = await import_fs_extra11.default.lstat(targetPath).catch(() => null);
35109
+ const stat = await import_fs_extra12.default.lstat(targetPath).catch(() => null);
34848
35110
  return Boolean(stat);
34849
35111
  }
34850
35112
  async function realPathIfPossible(targetPath) {
34851
35113
  try {
34852
- return await import_fs_extra11.default.realpath(targetPath);
35114
+ return await import_fs_extra12.default.realpath(targetPath);
34853
35115
  } catch {
34854
35116
  return null;
34855
35117
  }
34856
35118
  }
34857
35119
  function samePath(a, b) {
34858
- return path15.resolve(a) === path15.resolve(b);
35120
+ return path16.resolve(a) === path16.resolve(b);
34859
35121
  }
34860
35122
  function hashString(value) {
34861
35123
  return crypto.createHash("sha256").update(value).digest("hex");
34862
35124
  }
34863
35125
  async function hashPath(targetPath) {
34864
- const stat = await import_fs_extra11.default.lstat(targetPath);
35126
+ const stat = await import_fs_extra12.default.lstat(targetPath);
34865
35127
  if (stat.isSymbolicLink()) {
34866
- const linkTarget = await import_fs_extra11.default.readlink(targetPath);
35128
+ const linkTarget = await import_fs_extra12.default.readlink(targetPath);
34867
35129
  return hashString(`symlink:${linkTarget}`);
34868
35130
  }
34869
35131
  if (stat.isFile()) {
34870
35132
  const fileHash = crypto.createHash("sha256");
34871
35133
  fileHash.update("file:");
34872
- fileHash.update(await import_fs_extra11.default.readFile(targetPath));
35134
+ fileHash.update(await import_fs_extra12.default.readFile(targetPath));
34873
35135
  return fileHash.digest("hex");
34874
35136
  }
34875
35137
  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));
35138
+ const entries = (await import_fs_extra12.default.readdir(targetPath, { withFileTypes: true })).filter((entry) => !IGNORED_ENTRY_NAMES2.has(entry.name)).sort((a, b) => a.name.localeCompare(b.name));
34877
35139
  const dirHash = crypto.createHash("sha256");
34878
35140
  dirHash.update("dir:");
34879
35141
  for (const entry of entries) {
34880
35142
  dirHash.update(entry.name);
34881
35143
  dirHash.update("\x00");
34882
- dirHash.update(await hashPath(path15.join(targetPath, entry.name)));
35144
+ dirHash.update(await hashPath(path16.join(targetPath, entry.name)));
34883
35145
  dirHash.update("\x00");
34884
35146
  }
34885
35147
  return dirHash.digest("hex");
@@ -34890,7 +35152,7 @@ function suffixFromLabel(label) {
34890
35152
  return label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "source";
34891
35153
  }
34892
35154
  function nameWithSuffix(name, suffix, index) {
34893
- const parsed = path15.parse(name);
35155
+ const parsed = path16.parse(name);
34894
35156
  const numberedSuffix = index === 1 ? suffix : `${suffix}-${index}`;
34895
35157
  if (parsed.ext && parsed.name) {
34896
35158
  return `${parsed.name}--${numberedSuffix}${parsed.ext}`;
@@ -34902,39 +35164,39 @@ async function findTargetName(destinationDir, originalName, label) {
34902
35164
  let index = 1;
34903
35165
  while (true) {
34904
35166
  const candidate = nameWithSuffix(originalName, suffix, index);
34905
- if (!await pathExistsOrSymlink(path15.join(destinationDir, candidate))) {
35167
+ if (!await pathExistsOrSymlink(path16.join(destinationDir, candidate))) {
34906
35168
  return candidate;
34907
35169
  }
34908
35170
  index++;
34909
35171
  }
34910
35172
  }
34911
35173
  async function addExistingDestinationHashes(destinationDir, knownHashes) {
34912
- if (!await import_fs_extra11.default.pathExists(destinationDir))
35174
+ if (!await import_fs_extra12.default.pathExists(destinationDir))
34913
35175
  return;
34914
- const entries = await import_fs_extra11.default.readdir(destinationDir, { withFileTypes: true });
35176
+ const entries = await import_fs_extra12.default.readdir(destinationDir, { withFileTypes: true });
34915
35177
  for (const entry of entries) {
34916
- if (IGNORED_ENTRY_NAMES.has(entry.name))
35178
+ if (IGNORED_ENTRY_NAMES2.has(entry.name))
34917
35179
  continue;
34918
- const entryPath = path15.join(destinationDir, entry.name);
35180
+ const entryPath = path16.join(destinationDir, entry.name);
34919
35181
  knownHashes.set(await hashPath(entryPath), entry.name);
34920
35182
  }
34921
35183
  }
34922
35184
  async function importCategoryEntries(category, candidates, destinationDir, result) {
34923
- await import_fs_extra11.default.ensureDir(destinationDir);
35185
+ await import_fs_extra12.default.ensureDir(destinationDir);
34924
35186
  const destinationRealPath = await realPathIfPossible(destinationDir);
34925
35187
  const knownHashes = new Map;
34926
35188
  await addExistingDestinationHashes(destinationDir, knownHashes);
34927
35189
  for (const candidate of candidates) {
34928
35190
  if (candidate.category !== category || candidate.isDestination)
34929
35191
  continue;
34930
- const candidateStat = await import_fs_extra11.default.lstat(candidate.path).catch(() => null);
35192
+ const candidateStat = await import_fs_extra12.default.lstat(candidate.path).catch(() => null);
34931
35193
  if (!candidateStat)
34932
35194
  continue;
34933
35195
  const candidateRealPath = await realPathIfPossible(candidate.path);
34934
35196
  if (destinationRealPath && candidateRealPath && samePath(destinationRealPath, candidateRealPath)) {
34935
35197
  continue;
34936
35198
  }
34937
- const entries = await import_fs_extra11.default.readdir(candidate.path, { withFileTypes: true }).catch(() => null);
35199
+ const entries = await import_fs_extra12.default.readdir(candidate.path, { withFileTypes: true }).catch(() => null);
34938
35200
  if (!entries) {
34939
35201
  result.skipped.push({
34940
35202
  category,
@@ -34946,7 +35208,7 @@ async function importCategoryEntries(category, candidates, destinationDir, resul
34946
35208
  for (const entry of entries) {
34947
35209
  if (!shouldCollectEntry(category, entry))
34948
35210
  continue;
34949
- const sourcePath = path15.join(candidate.path, entry.name);
35211
+ const sourcePath = path16.join(candidate.path, entry.name);
34950
35212
  const sourceHash = await hashPath(sourcePath);
34951
35213
  const existingName = knownHashes.get(sourceHash);
34952
35214
  if (existingName) {
@@ -34954,15 +35216,15 @@ async function importCategoryEntries(category, candidates, destinationDir, resul
34954
35216
  category,
34955
35217
  name: entry.name,
34956
35218
  from: sourcePath,
34957
- keptAs: path15.join(destinationDir, existingName)
35219
+ keptAs: path16.join(destinationDir, existingName)
34958
35220
  });
34959
35221
  continue;
34960
35222
  }
34961
35223
  let targetName = entry.name;
34962
- let targetPath = path15.join(destinationDir, targetName);
35224
+ let targetPath = path16.join(destinationDir, targetName);
34963
35225
  if (await pathExistsOrSymlink(targetPath)) {
34964
35226
  targetName = await findTargetName(destinationDir, entry.name, candidate.label);
34965
- targetPath = path15.join(destinationDir, targetName);
35227
+ targetPath = path16.join(destinationDir, targetName);
34966
35228
  result.renamed.push({
34967
35229
  category,
34968
35230
  name: entry.name,
@@ -34971,7 +35233,7 @@ async function importCategoryEntries(category, candidates, destinationDir, resul
34971
35233
  reason: "Same name with different content"
34972
35234
  });
34973
35235
  }
34974
- await import_fs_extra11.default.copy(sourcePath, targetPath, {
35236
+ await import_fs_extra12.default.copy(sourcePath, targetPath, {
34975
35237
  dereference: false,
34976
35238
  overwrite: false
34977
35239
  });
@@ -34989,43 +35251,51 @@ function timestamp2(date = new Date) {
34989
35251
  return date.toISOString().replace(/\.\d{3}Z$/, "").replace(/[:T]/g, "-");
34990
35252
  }
34991
35253
  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, "-"));
35254
+ const relativePath = path16.relative(rootDir, targetPath);
35255
+ if (!relativePath || relativePath.startsWith("..") || path16.isAbsolute(relativePath)) {
35256
+ return path16.join("external", targetPath.replace(/[^a-zA-Z0-9._-]+/g, "-"));
34995
35257
  }
34996
35258
  return relativePath;
34997
35259
  }
34998
35260
  function createBackupPath(rootDir) {
34999
- return path15.join(rootDir, ".aiblueprint", "backups", "agents-unify-sources", timestamp2());
35261
+ return path16.join(rootDir, ".aiblueprint", "backups", "agents-unify-sources", timestamp2());
35000
35262
  }
35001
35263
  async function ensureBackupPath(result) {
35002
35264
  if (!result.backupPath) {
35003
35265
  result.backupPath = createBackupPath(result.rootDir);
35004
- await import_fs_extra11.default.ensureDir(result.backupPath);
35266
+ await import_fs_extra12.default.ensureDir(result.backupPath);
35005
35267
  }
35006
35268
  return result.backupPath;
35007
35269
  }
35008
35270
  async function createDirectorySymlink(source, target) {
35009
- await import_fs_extra11.default.ensureDir(path15.dirname(target));
35271
+ await import_fs_extra12.default.ensureDir(path16.dirname(target));
35010
35272
  if (os13.platform() === "win32") {
35011
- await import_fs_extra11.default.symlink(source, target, "junction");
35273
+ await import_fs_extra12.default.symlink(source, target, "junction");
35012
35274
  return;
35013
35275
  }
35014
- await import_fs_extra11.default.symlink(source, target, "dir");
35276
+ await import_fs_extra12.default.symlink(source, target, "dir");
35277
+ }
35278
+ async function createFileSymlink(source, target) {
35279
+ await import_fs_extra12.default.ensureDir(path16.dirname(target));
35280
+ if (os13.platform() === "win32") {
35281
+ await import_fs_extra12.default.symlink(source, target, "file");
35282
+ return;
35283
+ }
35284
+ await import_fs_extra12.default.symlink(source, target);
35015
35285
  }
35016
35286
  async function shouldLinkMissingContainer(candidate) {
35017
35287
  if (candidate.linkWhenMissing)
35018
35288
  return true;
35019
35289
  if (!candidate.linkWhenParentExists)
35020
35290
  return false;
35021
- return import_fs_extra11.default.pathExists(path15.dirname(candidate.path));
35291
+ return import_fs_extra12.default.pathExists(path16.dirname(candidate.path));
35022
35292
  }
35023
35293
  async function linkContainer(candidate, destinationDir, result) {
35024
35294
  if (candidate.isDestination || samePath(candidate.path, destinationDir)) {
35025
35295
  return;
35026
35296
  }
35027
35297
  const destinationRealPath = await realPathIfPossible(destinationDir);
35028
- const stat = await import_fs_extra11.default.lstat(candidate.path).catch(() => null);
35298
+ const stat = await import_fs_extra12.default.lstat(candidate.path).catch(() => null);
35029
35299
  if (!stat) {
35030
35300
  if (!await shouldLinkMissingContainer(candidate))
35031
35301
  return;
@@ -35047,7 +35317,7 @@ async function linkContainer(candidate, destinationDir, result) {
35047
35317
  });
35048
35318
  return;
35049
35319
  }
35050
- await import_fs_extra11.default.remove(candidate.path);
35320
+ await import_fs_extra12.default.remove(candidate.path);
35051
35321
  await createDirectorySymlink(destinationDir, candidate.path);
35052
35322
  result.linked.push({
35053
35323
  category: candidate.category,
@@ -35057,9 +35327,9 @@ async function linkContainer(candidate, destinationDir, result) {
35057
35327
  return;
35058
35328
  }
35059
35329
  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 });
35330
+ const backupTarget = path16.join(backupRoot, safeRelativePath(result.rootDir, candidate.path));
35331
+ await import_fs_extra12.default.ensureDir(path16.dirname(backupTarget));
35332
+ await import_fs_extra12.default.move(candidate.path, backupTarget, { overwrite: false });
35063
35333
  await createDirectorySymlink(destinationDir, candidate.path);
35064
35334
  result.linked.push({
35065
35335
  category: candidate.category,
@@ -35068,9 +35338,119 @@ async function linkContainer(candidate, destinationDir, result) {
35068
35338
  movedToBackup: backupTarget
35069
35339
  });
35070
35340
  }
35341
+ async function importInstructionFiles(candidates, destinationPath, result) {
35342
+ await import_fs_extra12.default.ensureDir(path16.dirname(destinationPath));
35343
+ const destinationRealPath = await realPathIfPossible(destinationPath);
35344
+ let destinationHash = await pathExistsOrSymlink(destinationPath) ? await hashPath(destinationPath) : null;
35345
+ for (const candidate of candidates) {
35346
+ if (candidate.isDestination)
35347
+ continue;
35348
+ const sourceStat = await import_fs_extra12.default.lstat(candidate.path).catch(() => null);
35349
+ if (!sourceStat)
35350
+ continue;
35351
+ const sourceRealPath = await realPathIfPossible(candidate.path);
35352
+ if (destinationRealPath && sourceRealPath && samePath(destinationRealPath, sourceRealPath)) {
35353
+ continue;
35354
+ }
35355
+ const sourceHash = await hashPath(candidate.path);
35356
+ if (!destinationHash) {
35357
+ await import_fs_extra12.default.copy(candidate.path, destinationPath, {
35358
+ dereference: false,
35359
+ overwrite: false
35360
+ });
35361
+ destinationHash = sourceHash;
35362
+ result.imported.push({
35363
+ category: "instructions",
35364
+ name: path16.basename(candidate.path),
35365
+ from: candidate.path,
35366
+ to: destinationPath
35367
+ });
35368
+ continue;
35369
+ }
35370
+ if (sourceHash === destinationHash) {
35371
+ result.duplicates.push({
35372
+ category: "instructions",
35373
+ name: path16.basename(candidate.path),
35374
+ from: candidate.path,
35375
+ keptAs: destinationPath
35376
+ });
35377
+ continue;
35378
+ }
35379
+ const targetName = await findTargetName(path16.dirname(destinationPath), path16.basename(destinationPath), candidate.label);
35380
+ const targetPath = path16.join(path16.dirname(destinationPath), targetName);
35381
+ await import_fs_extra12.default.copy(candidate.path, targetPath, {
35382
+ dereference: false,
35383
+ overwrite: false
35384
+ });
35385
+ result.renamed.push({
35386
+ category: "instructions",
35387
+ name: path16.basename(candidate.path),
35388
+ from: candidate.path,
35389
+ to: targetPath,
35390
+ reason: "Shared instruction file already exists with different content"
35391
+ });
35392
+ }
35393
+ }
35394
+ async function shouldLinkMissingInstruction(candidate) {
35395
+ if (candidate.linkWhenMissing)
35396
+ return true;
35397
+ return false;
35398
+ }
35399
+ async function linkInstructionFile(candidate, destinationPath, result) {
35400
+ if (candidate.isDestination || samePath(candidate.path, destinationPath)) {
35401
+ return;
35402
+ }
35403
+ if (!await pathExistsOrSymlink(destinationPath)) {
35404
+ return;
35405
+ }
35406
+ const destinationRealPath = await realPathIfPossible(destinationPath);
35407
+ const stat = await import_fs_extra12.default.lstat(candidate.path).catch(() => null);
35408
+ if (!stat) {
35409
+ if (!await shouldLinkMissingInstruction(candidate))
35410
+ return;
35411
+ await createFileSymlink(destinationPath, candidate.path);
35412
+ result.linked.push({
35413
+ category: "instructions",
35414
+ from: candidate.path,
35415
+ to: destinationPath
35416
+ });
35417
+ return;
35418
+ }
35419
+ if (stat.isSymbolicLink()) {
35420
+ const existingRealPath = await realPathIfPossible(candidate.path);
35421
+ if (destinationRealPath && existingRealPath && samePath(destinationRealPath, existingRealPath)) {
35422
+ result.alreadyLinked.push({
35423
+ category: "instructions",
35424
+ from: candidate.path,
35425
+ to: destinationPath
35426
+ });
35427
+ return;
35428
+ }
35429
+ await import_fs_extra12.default.remove(candidate.path);
35430
+ await createFileSymlink(destinationPath, candidate.path);
35431
+ result.linked.push({
35432
+ category: "instructions",
35433
+ from: candidate.path,
35434
+ to: destinationPath
35435
+ });
35436
+ return;
35437
+ }
35438
+ const backupRoot = await ensureBackupPath(result);
35439
+ const backupTarget = path16.join(backupRoot, safeRelativePath(result.rootDir, candidate.path));
35440
+ await import_fs_extra12.default.ensureDir(path16.dirname(backupTarget));
35441
+ await import_fs_extra12.default.move(candidate.path, backupTarget, { overwrite: false });
35442
+ await createFileSymlink(destinationPath, candidate.path);
35443
+ result.linked.push({
35444
+ category: "instructions",
35445
+ from: candidate.path,
35446
+ to: destinationPath,
35447
+ movedToBackup: backupTarget
35448
+ });
35449
+ }
35071
35450
  async function unifyAgentsConfiguration(options = {}) {
35072
35451
  const folders = resolveFolders(options);
35073
35452
  const candidates = getContainerCandidates(options);
35453
+ const instructionCandidates = getInstructionFileCandidates(options);
35074
35454
  const result = {
35075
35455
  rootDir: folders.rootDir,
35076
35456
  agentsDir: folders.agentsDir,
@@ -35083,16 +35463,21 @@ async function unifyAgentsConfiguration(options = {}) {
35083
35463
  skipped: []
35084
35464
  };
35085
35465
  const destinationByCategory = {
35086
- skills: path15.join(folders.agentsDir, "skills"),
35087
- agents: path15.join(folders.agentsDir, "agents")
35466
+ skills: path16.join(folders.agentsDir, "skills"),
35467
+ agents: path16.join(folders.agentsDir, "agents"),
35468
+ instructions: path16.join(folders.agentsDir, "AGENTS.md")
35088
35469
  };
35089
- await import_fs_extra11.default.ensureDir(folders.agentsDir);
35470
+ await import_fs_extra12.default.ensureDir(folders.agentsDir);
35471
+ await importInstructionFiles(instructionCandidates, destinationByCategory.instructions, result);
35090
35472
  for (const category of ["skills", "agents"]) {
35091
35473
  await importCategoryEntries(category, candidates, destinationByCategory[category], result);
35092
35474
  }
35093
35475
  for (const candidate of candidates) {
35094
35476
  await linkContainer(candidate, destinationByCategory[candidate.category], result);
35095
35477
  }
35478
+ for (const candidate of instructionCandidates) {
35479
+ await linkInstructionFile(candidate, destinationByCategory.instructions, result);
35480
+ }
35096
35481
  return result;
35097
35482
  }
35098
35483
 
@@ -35113,13 +35498,16 @@ async function agentsUnifyCommand(params = {}) {
35113
35498
  console.log(source_default.blue.bold(`
35114
35499
  AIBlueprint agents unify ${source_default.gray(`v${getVersion()}`)}
35115
35500
  `));
35116
- console.log(source_default.gray("Centralizing reusable skills and agents into .agents"));
35501
+ console.log(source_default.gray("Centralizing reusable skills and agents into .agents, then rendering Codex agents"));
35117
35502
  const result = await unifyAgentsConfiguration(params);
35503
+ const codexResult = await renderCodexAgentsFromMarkdown(params);
35118
35504
  console.log(source_default.green(`
35119
35505
  Unify complete`));
35120
35506
  console.log(source_default.gray(` Shared folder: ${result.agentsDir}`));
35507
+ printCategorySummary(result, "instructions");
35121
35508
  printCategorySummary(result, "skills");
35122
35509
  printCategorySummary(result, "agents");
35510
+ console.log(source_default.gray(` codex agents: ${codexResult.rendered.length} rendered, ${codexResult.skipped.length} skipped`));
35123
35511
  if (result.backupPath) {
35124
35512
  console.log(source_default.gray(` Source backups: ${result.backupPath}`));
35125
35513
  }
@@ -35137,6 +35525,34 @@ Agents unify failed:`), error);
35137
35525
  }
35138
35526
  }
35139
35527
 
35528
+ // src/commands/codex-agents.ts
35529
+ async function codexAgentsCommand(options = {}) {
35530
+ try {
35531
+ console.log(source_default.blue.bold(`
35532
+ AIBlueprint Codex agents ${source_default.gray(`v${getVersion()}`)}
35533
+ `));
35534
+ console.log(source_default.gray("Rendering shared Markdown agents into Codex TOML custom agents"));
35535
+ const result = await renderCodexAgentsFromMarkdown(options);
35536
+ console.log(source_default.green(`
35537
+ Codex agents rendered`));
35538
+ console.log(source_default.gray(` Source: ${result.sourceDir}`));
35539
+ console.log(source_default.gray(` Target: ${result.targetDir}`));
35540
+ console.log(source_default.gray(` Rendered: ${result.rendered.length}`));
35541
+ console.log(source_default.gray(` Skipped: ${result.skipped.length}`));
35542
+ if (result.skipped.length > 0) {
35543
+ console.log(source_default.yellow(`
35544
+ Skipped agents:`));
35545
+ for (const skipped of result.skipped) {
35546
+ console.log(source_default.yellow(` ${skipped.source}: ${skipped.reason}`));
35547
+ }
35548
+ }
35549
+ } catch (error) {
35550
+ console.error(source_default.red(`
35551
+ Codex agents render failed:`), error);
35552
+ process.exit(1);
35553
+ }
35554
+ }
35555
+
35140
35556
  // node_modules/@clack/core/dist/index.mjs
35141
35557
  var import_sisteransi = __toESM(require_src(), 1);
35142
35558
  var import_picocolors = __toESM(require_picocolors(), 1);
@@ -35853,12 +36269,12 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
35853
36269
  };
35854
36270
 
35855
36271
  // src/commands/pro.ts
35856
- import path18 from "path";
36272
+ import path19 from "path";
35857
36273
 
35858
36274
  // src/lib/pro-installer.ts
35859
- var import_fs_extra12 = __toESM(require_lib4(), 1);
36275
+ var import_fs_extra13 = __toESM(require_lib4(), 1);
35860
36276
  import os14 from "os";
35861
- import path16 from "path";
36277
+ import path17 from "path";
35862
36278
  import { exec as exec3 } from "child_process";
35863
36279
  import { promisify as promisify2 } from "util";
35864
36280
  var execAsync2 = promisify2(exec3);
@@ -35866,9 +36282,9 @@ var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
35866
36282
  var PREMIUM_BRANCH = "main";
35867
36283
  var CONFIG_FOLDER_CANDIDATES2 = ["agents-config", "ai-coding", "claude-code-config", "ai-config"];
35868
36284
  function routePath(relativePath) {
35869
- const segments = relativePath.split(path16.sep);
36285
+ const segments = relativePath.split(path17.sep);
35870
36286
  const first = segments[0];
35871
- const rest = segments.slice(1).join(path16.sep);
36287
+ const rest = segments.slice(1).join(path17.sep);
35872
36288
  if (first === "claude-config") {
35873
36289
  return { kind: "claude", relativePath: rest };
35874
36290
  }
@@ -35884,7 +36300,7 @@ function routePath(relativePath) {
35884
36300
  return { kind: "claude", relativePath };
35885
36301
  }
35886
36302
  function getCacheRepoDir() {
35887
- return path16.join(os14.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
36303
+ return path17.join(os14.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
35888
36304
  }
35889
36305
  async function execGitWithAuth(command, token, repoUrl, cwd) {
35890
36306
  const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
@@ -35898,21 +36314,21 @@ async function execGitWithAuth(command, token, repoUrl, cwd) {
35898
36314
  async function cloneOrUpdateRepo(token) {
35899
36315
  const cacheDir = getCacheRepoDir();
35900
36316
  const repoUrl = `https://github.com/${PREMIUM_REPO}.git`;
35901
- if (await import_fs_extra12.default.pathExists(path16.join(cacheDir, ".git"))) {
36317
+ if (await import_fs_extra13.default.pathExists(path17.join(cacheDir, ".git"))) {
35902
36318
  try {
35903
36319
  await execGitWithAuth("pull", token, repoUrl, cacheDir);
35904
36320
  } catch (error) {
35905
- await import_fs_extra12.default.remove(cacheDir);
35906
- await import_fs_extra12.default.ensureDir(path16.dirname(cacheDir));
36321
+ await import_fs_extra13.default.remove(cacheDir);
36322
+ await import_fs_extra13.default.ensureDir(path17.dirname(cacheDir));
35907
36323
  await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
35908
36324
  }
35909
36325
  } else {
35910
- await import_fs_extra12.default.ensureDir(path16.dirname(cacheDir));
36326
+ await import_fs_extra13.default.ensureDir(path17.dirname(cacheDir));
35911
36327
  await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
35912
36328
  }
35913
36329
  for (const candidate of CONFIG_FOLDER_CANDIDATES2) {
35914
- const candidatePath = path16.join(cacheDir, candidate);
35915
- if (await import_fs_extra12.default.pathExists(candidatePath)) {
36330
+ const candidatePath = path17.join(cacheDir, candidate);
36331
+ if (await import_fs_extra13.default.pathExists(candidatePath)) {
35916
36332
  return candidatePath;
35917
36333
  }
35918
36334
  }
@@ -35920,38 +36336,38 @@ async function cloneOrUpdateRepo(token) {
35920
36336
  }
35921
36337
  async function copyConfigFromCache(cacheConfigDir, dest, onProgress) {
35922
36338
  const walk = async (dir, baseDir = dir) => {
35923
- const entries = await import_fs_extra12.default.readdir(dir, { withFileTypes: true });
36339
+ const entries = await import_fs_extra13.default.readdir(dir, { withFileTypes: true });
35924
36340
  for (const entry of entries) {
35925
36341
  if (entry.name === ".DS_Store" || entry.name === "node_modules")
35926
36342
  continue;
35927
- const sourcePath = path16.join(dir, entry.name);
35928
- const relativePath = path16.relative(baseDir, sourcePath);
36343
+ const sourcePath = path17.join(dir, entry.name);
36344
+ const relativePath = path17.relative(baseDir, sourcePath);
35929
36345
  const route = routePath(relativePath);
35930
36346
  if (route.kind === "skip")
35931
36347
  continue;
35932
36348
  if (route.kind === "agents-category") {
35933
- if (relativePath.split(path16.sep).length === 1) {
36349
+ if (relativePath.split(path17.sep).length === 1) {
35934
36350
  await copyAgentCategory(sourcePath, route.category, dest.agentsDir, dest.claudeDir, onProgress);
35935
36351
  }
35936
36352
  continue;
35937
36353
  }
35938
36354
  const targetBase = route.kind === "claude" ? dest.claudeDir : dest.codexDir;
35939
- const targetPath = path16.join(targetBase, route.relativePath);
36355
+ const targetPath = path17.join(targetBase, route.relativePath);
35940
36356
  if (entry.isDirectory()) {
35941
- await import_fs_extra12.default.ensureDir(targetPath);
36357
+ await import_fs_extra13.default.ensureDir(targetPath);
35942
36358
  onProgress?.(relativePath, "directory");
35943
36359
  await walk(sourcePath, baseDir);
35944
36360
  } else if (route.kind === "codex" && route.relativePath === "config.toml") {
35945
36361
  await mergeCodexConfigFile(sourcePath, dest.codexDir);
35946
36362
  onProgress?.(relativePath, "file");
35947
36363
  } else if (isTextFile(entry.name)) {
35948
- const content = await import_fs_extra12.default.readFile(sourcePath, "utf-8");
36364
+ const content = await import_fs_extra13.default.readFile(sourcePath, "utf-8");
35949
36365
  const replaced = replaceClaudePathPlaceholder(content, dest.claudeDir);
35950
- await import_fs_extra12.default.ensureDir(path16.dirname(targetPath));
35951
- await import_fs_extra12.default.writeFile(targetPath, replaced, "utf-8");
36366
+ await import_fs_extra13.default.ensureDir(path17.dirname(targetPath));
36367
+ await import_fs_extra13.default.writeFile(targetPath, replaced, "utf-8");
35952
36368
  onProgress?.(relativePath, "file");
35953
36369
  } else {
35954
- await import_fs_extra12.default.copy(sourcePath, targetPath, { overwrite: true });
36370
+ await import_fs_extra13.default.copy(sourcePath, targetPath, { overwrite: true });
35955
36371
  onProgress?.(relativePath, "file");
35956
36372
  }
35957
36373
  }
@@ -35959,21 +36375,21 @@ async function copyConfigFromCache(cacheConfigDir, dest, onProgress) {
35959
36375
  await walk(cacheConfigDir);
35960
36376
  }
35961
36377
  async function copyAgentCategory(sourceCategoryDir, category, agentsDir, claudeDir, onProgress) {
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 });
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 });
35965
36381
  for (const entry of entries) {
35966
36382
  if (entry.name === ".DS_Store")
35967
36383
  continue;
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);
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);
35972
36388
  if (claudeStat && !claudeStat.isSymbolicLink()) {
35973
36389
  onProgress?.(`${category}/${entry.name} (skipped - real dir in claude)`, "file");
35974
36390
  continue;
35975
36391
  }
35976
- await import_fs_extra12.default.copy(src, dst, { overwrite: true });
36392
+ await import_fs_extra13.default.copy(src, dst, { overwrite: true });
35977
36393
  await applyPathPlaceholders(dst, claudeDir);
35978
36394
  onProgress?.(`${category}/${entry.name}`, entry.isDirectory() ? "directory" : "file");
35979
36395
  }
@@ -35992,8 +36408,8 @@ async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath,
35992
36408
  return false;
35993
36409
  }
35994
36410
  const content = await response.arrayBuffer();
35995
- await import_fs_extra12.default.ensureDir(path16.dirname(targetPath));
35996
- await import_fs_extra12.default.writeFile(targetPath, Buffer.from(content));
36411
+ await import_fs_extra13.default.ensureDir(path17.dirname(targetPath));
36412
+ await import_fs_extra13.default.writeFile(targetPath, Buffer.from(content));
35997
36413
  return true;
35998
36414
  } catch (error) {
35999
36415
  console.error(`Error downloading ${relativePath}:`, error);
@@ -36018,10 +36434,10 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
36018
36434
  console.error(`Unexpected response for directory ${dirPath}`);
36019
36435
  return false;
36020
36436
  }
36021
- await import_fs_extra12.default.ensureDir(targetDir);
36437
+ await import_fs_extra13.default.ensureDir(targetDir);
36022
36438
  for (const file of files) {
36023
36439
  const relativePath = dirPath ? `${dirPath}/${file.name}` : file.name;
36024
- const targetPath = path16.join(targetDir, file.name);
36440
+ const targetPath = path17.join(targetDir, file.name);
36025
36441
  const displayPath = relativePath.replace(/^(agents-config|ai-coding|claude-code-config|ai-config)\//, "");
36026
36442
  if (file.type === "file") {
36027
36443
  onProgress?.(displayPath, "file");
@@ -36044,8 +36460,8 @@ async function installProConfigs(options) {
36044
36460
  codexFolder,
36045
36461
  agentsFolder
36046
36462
  });
36047
- await import_fs_extra12.default.ensureDir(claudeDir);
36048
- await import_fs_extra12.default.ensureDir(agentsDir);
36463
+ await import_fs_extra13.default.ensureDir(claudeDir);
36464
+ await import_fs_extra13.default.ensureDir(agentsDir);
36049
36465
  const dest = { claudeDir, codexDir, agentsDir };
36050
36466
  try {
36051
36467
  const cacheConfigDir = await cloneOrUpdateRepo(githubToken);
@@ -36055,7 +36471,7 @@ async function installProConfigs(options) {
36055
36471
  } catch (error) {
36056
36472
  console.warn("Git caching failed, falling back to API download");
36057
36473
  }
36058
- const tempDir = path16.join(os14.tmpdir(), `aiblueprint-premium-${Date.now()}`);
36474
+ const tempDir = path17.join(os14.tmpdir(), `aiblueprint-premium-${Date.now()}`);
36059
36475
  try {
36060
36476
  let success = false;
36061
36477
  for (const candidate of CONFIG_FOLDER_CANDIDATES2) {
@@ -36069,8 +36485,8 @@ async function installProConfigs(options) {
36069
36485
  await copyConfigFromCache(tempDir, dest, onProgress);
36070
36486
  await replacePathPlaceholdersInDir(claudeDir, claudeDir);
36071
36487
  for (const category of AGENT_CATEGORIES) {
36072
- const agentsCategoryDir = path16.join(agentsDir, category);
36073
- if (await import_fs_extra12.default.pathExists(agentsCategoryDir)) {
36488
+ const agentsCategoryDir = path17.join(agentsDir, category);
36489
+ if (await import_fs_extra13.default.pathExists(agentsCategoryDir)) {
36074
36490
  await replacePathPlaceholdersInDir(agentsCategoryDir, claudeDir);
36075
36491
  }
36076
36492
  }
@@ -36079,7 +36495,7 @@ async function installProConfigs(options) {
36079
36495
  throw new Error(`Failed to install premium configs: ${error instanceof Error ? error.message : "Unknown error"}`);
36080
36496
  } finally {
36081
36497
  try {
36082
- await import_fs_extra12.default.remove(tempDir);
36498
+ await import_fs_extra13.default.remove(tempDir);
36083
36499
  } catch {}
36084
36500
  }
36085
36501
  }
@@ -36090,27 +36506,27 @@ async function syncAllAgentSymlinks(agentsDir, claudeDir) {
36090
36506
  }
36091
36507
 
36092
36508
  // src/lib/token-storage.ts
36093
- var import_fs_extra13 = __toESM(require_lib4(), 1);
36509
+ var import_fs_extra14 = __toESM(require_lib4(), 1);
36094
36510
  import os15 from "os";
36095
- import path17 from "path";
36511
+ import path18 from "path";
36096
36512
  function getConfigDir() {
36097
36513
  const platform = os15.platform();
36098
36514
  if (platform === "win32") {
36099
- const appData = process.env.APPDATA || path17.join(os15.homedir(), "AppData", "Roaming");
36100
- return path17.join(appData, "aiblueprint");
36515
+ const appData = process.env.APPDATA || path18.join(os15.homedir(), "AppData", "Roaming");
36516
+ return path18.join(appData, "aiblueprint");
36101
36517
  } else {
36102
- const configHome = process.env.XDG_CONFIG_HOME || path17.join(os15.homedir(), ".config");
36103
- return path17.join(configHome, "aiblueprint");
36518
+ const configHome = process.env.XDG_CONFIG_HOME || path18.join(os15.homedir(), ".config");
36519
+ return path18.join(configHome, "aiblueprint");
36104
36520
  }
36105
36521
  }
36106
36522
  function getTokenFilePath2() {
36107
- return path17.join(getConfigDir(), "token.txt");
36523
+ return path18.join(getConfigDir(), "token.txt");
36108
36524
  }
36109
36525
  async function saveToken(githubToken) {
36110
36526
  const tokenFile = getTokenFilePath2();
36111
- const configDir = path17.dirname(tokenFile);
36527
+ const configDir = path18.dirname(tokenFile);
36112
36528
  try {
36113
- await import_fs_extra13.default.ensureDir(configDir);
36529
+ await import_fs_extra14.default.ensureDir(configDir);
36114
36530
  } catch (error) {
36115
36531
  if (error.code === "EACCES") {
36116
36532
  throw new Error(`Permission denied creating config directory: ${configDir}
@@ -36118,15 +36534,15 @@ async function saveToken(githubToken) {
36118
36534
  }
36119
36535
  throw error;
36120
36536
  }
36121
- await import_fs_extra13.default.writeFile(tokenFile, githubToken, { mode: 384 });
36537
+ await import_fs_extra14.default.writeFile(tokenFile, githubToken, { mode: 384 });
36122
36538
  }
36123
36539
  async function getToken() {
36124
36540
  const tokenFile = getTokenFilePath2();
36125
- if (!await import_fs_extra13.default.pathExists(tokenFile)) {
36541
+ if (!await import_fs_extra14.default.pathExists(tokenFile)) {
36126
36542
  return null;
36127
36543
  }
36128
36544
  try {
36129
- const token = await import_fs_extra13.default.readFile(tokenFile, "utf-8");
36545
+ const token = await import_fs_extra14.default.readFile(tokenFile, "utf-8");
36130
36546
  return token.trim();
36131
36547
  } catch (error) {
36132
36548
  return null;
@@ -36140,7 +36556,7 @@ function getTokenInfo() {
36140
36556
  }
36141
36557
 
36142
36558
  // src/commands/pro.ts
36143
- var import_fs_extra14 = __toESM(require_lib4(), 1);
36559
+ var import_fs_extra15 = __toESM(require_lib4(), 1);
36144
36560
  var API_URL = "https://codeline.app/api/products";
36145
36561
  var PRODUCT_IDS = ["prd_XJVgxVPbGG", "prd_NKabAkdOkw"];
36146
36562
  async function countInstalledItems(claudeDir) {
@@ -36149,20 +36565,20 @@ async function countInstalledItems(claudeDir) {
36149
36565
  skills: 0
36150
36566
  };
36151
36567
  try {
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);
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);
36155
36571
  counts.agents = files.filter((f) => f.endsWith(".md")).length;
36156
36572
  }
36157
36573
  } catch (error) {
36158
36574
  console.error("Failed to count agents:", error instanceof Error ? error.message : error);
36159
36575
  }
36160
36576
  try {
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);
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);
36164
36580
  const dirs = await Promise.all(items.map(async (item) => {
36165
- const stat = await import_fs_extra14.default.stat(path18.join(skillsDir, item));
36581
+ const stat = await import_fs_extra15.default.stat(path19.join(skillsDir, item));
36166
36582
  return stat.isDirectory();
36167
36583
  }));
36168
36584
  counts.skills = dirs.filter(Boolean).length;
@@ -36370,8 +36786,8 @@ async function proUpdateCommand(options = {}) {
36370
36786
  }
36371
36787
 
36372
36788
  // src/lib/sync-utils.ts
36373
- var import_fs_extra15 = __toESM(require_lib4(), 1);
36374
- import path19 from "path";
36789
+ var import_fs_extra16 = __toESM(require_lib4(), 1);
36790
+ import path20 from "path";
36375
36791
  import crypto2 from "crypto";
36376
36792
  var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
36377
36793
  var PREMIUM_BRANCH2 = "main";
@@ -36442,7 +36858,7 @@ async function listRemoteFilesRecursive(dirPath, githubToken, basePath = "") {
36442
36858
  }
36443
36859
  async function computeLocalFileSha(filePath) {
36444
36860
  try {
36445
- const content = await import_fs_extra15.default.readFile(filePath);
36861
+ const content = await import_fs_extra16.default.readFile(filePath);
36446
36862
  return computeFileSha(content);
36447
36863
  } catch {
36448
36864
  return null;
@@ -36450,15 +36866,15 @@ async function computeLocalFileSha(filePath) {
36450
36866
  }
36451
36867
  async function listLocalFiles(dir) {
36452
36868
  const files = [];
36453
- if (!await import_fs_extra15.default.pathExists(dir)) {
36869
+ if (!await import_fs_extra16.default.pathExists(dir)) {
36454
36870
  return files;
36455
36871
  }
36456
- const items = await import_fs_extra15.default.readdir(dir);
36872
+ const items = await import_fs_extra16.default.readdir(dir);
36457
36873
  for (const item of items) {
36458
36874
  if (item === "node_modules" || item === ".DS_Store")
36459
36875
  continue;
36460
- const fullPath = path19.join(dir, item);
36461
- const stat = await import_fs_extra15.default.stat(fullPath).catch(() => null);
36876
+ const fullPath = path20.join(dir, item);
36877
+ const stat = await import_fs_extra16.default.stat(fullPath).catch(() => null);
36462
36878
  if (!stat)
36463
36879
  continue;
36464
36880
  if (stat.isDirectory()) {
@@ -36473,13 +36889,13 @@ async function listLocalFiles(dir) {
36473
36889
  }
36474
36890
  async function listLocalFilesRecursive(dir, basePath) {
36475
36891
  const files = [];
36476
- const items = await import_fs_extra15.default.readdir(dir).catch(() => []);
36892
+ const items = await import_fs_extra16.default.readdir(dir).catch(() => []);
36477
36893
  for (const item of items) {
36478
36894
  if (item === "node_modules" || item === ".DS_Store")
36479
36895
  continue;
36480
- const fullPath = path19.join(dir, item);
36896
+ const fullPath = path20.join(dir, item);
36481
36897
  const relativePath = `${basePath}/${item}`;
36482
- const stat = await import_fs_extra15.default.stat(fullPath).catch(() => null);
36898
+ const stat = await import_fs_extra16.default.stat(fullPath).catch(() => null);
36483
36899
  if (!stat)
36484
36900
  continue;
36485
36901
  if (stat.isDirectory()) {
@@ -36493,14 +36909,14 @@ async function listLocalFilesRecursive(dir, basePath) {
36493
36909
  return files;
36494
36910
  }
36495
36911
  async function listClaudeRealTopLevel(claudeCategoryDir) {
36496
- if (!await import_fs_extra15.default.pathExists(claudeCategoryDir))
36912
+ if (!await import_fs_extra16.default.pathExists(claudeCategoryDir))
36497
36913
  return [];
36498
- const entries = await import_fs_extra15.default.readdir(claudeCategoryDir).catch(() => []);
36914
+ const entries = await import_fs_extra16.default.readdir(claudeCategoryDir).catch(() => []);
36499
36915
  const real = [];
36500
36916
  for (const name of entries) {
36501
36917
  if (name === "node_modules" || name === ".DS_Store")
36502
36918
  continue;
36503
- const stat = await import_fs_extra15.default.lstat(path19.join(claudeCategoryDir, name)).catch(() => null);
36919
+ const stat = await import_fs_extra16.default.lstat(path20.join(claudeCategoryDir, name)).catch(() => null);
36504
36920
  if (!stat)
36505
36921
  continue;
36506
36922
  if (stat.isDirectory())
@@ -36517,7 +36933,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
36517
36933
  const items = [];
36518
36934
  const useAgents = isAgentCategory(category);
36519
36935
  const localBase = useAgents ? agentsDir : claudeDir;
36520
- const localDir = path19.join(localBase, category);
36936
+ const localDir = path20.join(localBase, category);
36521
36937
  const remoteCategoryPath = getRemoteCategoryPath(category);
36522
36938
  const remoteFiles = await listRemoteFilesRecursive(remoteCategoryPath, githubToken);
36523
36939
  const localFiles = await listLocalFiles(localDir);
@@ -36531,7 +36947,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
36531
36947
  }
36532
36948
  const localSet = new Set(localFiles);
36533
36949
  for (const [remotePath, { sha, isFolder }] of remoteSet) {
36534
- const localPath = path19.join(localDir, remotePath);
36950
+ const localPath = path20.join(localDir, remotePath);
36535
36951
  if (isFolder) {
36536
36952
  continue;
36537
36953
  }
@@ -36566,7 +36982,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
36566
36982
  for (const localPath of localSet) {
36567
36983
  agentsTopLevels.add(localPath.split("/")[0]);
36568
36984
  }
36569
- const claudeCategoryDir = path19.join(claudeDir, category);
36985
+ const claudeCategoryDir = path20.join(claudeDir, category);
36570
36986
  const claudeRealEntries = await listClaudeRealTopLevel(claudeCategoryDir);
36571
36987
  for (const top of claudeRealEntries) {
36572
36988
  if (!remoteTopLevels.has(top))
@@ -36625,13 +37041,13 @@ async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken,
36625
37041
  return false;
36626
37042
  }
36627
37043
  const content = await response.arrayBuffer();
36628
- await import_fs_extra15.default.ensureDir(path19.dirname(targetPath));
37044
+ await import_fs_extra16.default.ensureDir(path20.dirname(targetPath));
36629
37045
  if (isTextFile(relativePath)) {
36630
37046
  const textContent = Buffer.from(content).toString("utf-8");
36631
37047
  const transformedContent = transformFileContent(textContent, claudeDir);
36632
- await import_fs_extra15.default.writeFile(targetPath, transformedContent, "utf-8");
37048
+ await import_fs_extra16.default.writeFile(targetPath, transformedContent, "utf-8");
36633
37049
  } else {
36634
- await import_fs_extra15.default.writeFile(targetPath, Buffer.from(content));
37050
+ await import_fs_extra16.default.writeFile(targetPath, Buffer.from(content));
36635
37051
  }
36636
37052
  return true;
36637
37053
  } catch {
@@ -36647,27 +37063,27 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
36647
37063
  for (const item of items) {
36648
37064
  const useAgents = isAgentCategory(item.category);
36649
37065
  const baseDir = useAgents ? agentsDir : claudeDir;
36650
- const targetPath = path19.join(baseDir, item.relativePath);
37066
+ const targetPath = path20.join(baseDir, item.relativePath);
36651
37067
  if (item.status === "migration" && useAgents) {
36652
37068
  const topName = item.name.split("/")[0];
36653
- const agentsTop = path19.join(agentsDir, item.category, topName);
36654
- const claudeTop = path19.join(claudeDir, item.category, topName);
37069
+ const agentsTop = path20.join(agentsDir, item.category, topName);
37070
+ const claudeTop = path20.join(claudeDir, item.category, topName);
36655
37071
  try {
36656
- const claudeStat = await import_fs_extra15.default.lstat(claudeTop).catch(() => null);
37072
+ const claudeStat = await import_fs_extra16.default.lstat(claudeTop).catch(() => null);
36657
37073
  if (!claudeStat || claudeStat.isSymbolicLink()) {
36658
37074
  onProgress?.(item.relativePath, "skipping (no real dir to migrate)");
36659
37075
  failed++;
36660
37076
  continue;
36661
37077
  }
36662
- const agentsExists = await import_fs_extra15.default.pathExists(agentsTop);
37078
+ const agentsExists = await import_fs_extra16.default.pathExists(agentsTop);
36663
37079
  if (agentsExists) {
36664
37080
  onProgress?.(item.relativePath, "skipping (already in .agents)");
36665
37081
  failed++;
36666
37082
  continue;
36667
37083
  }
36668
37084
  onProgress?.(item.relativePath, "moving to .agents");
36669
- await import_fs_extra15.default.ensureDir(path19.dirname(agentsTop));
36670
- await import_fs_extra15.default.move(claudeTop, agentsTop);
37085
+ await import_fs_extra16.default.ensureDir(path20.dirname(agentsTop));
37086
+ await import_fs_extra16.default.move(claudeTop, agentsTop);
36671
37087
  migrated++;
36672
37088
  touchedAgentCategories.add(item.category);
36673
37089
  } catch {
@@ -36677,8 +37093,8 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
36677
37093
  }
36678
37094
  if (useAgents) {
36679
37095
  const topName = item.name.split("/")[0];
36680
- const claudeTop = path19.join(claudeDir, item.category, topName);
36681
- const claudeTopStat = await import_fs_extra15.default.lstat(claudeTop).catch(() => null);
37096
+ const claudeTop = path20.join(claudeDir, item.category, topName);
37097
+ const claudeTopStat = await import_fs_extra16.default.lstat(claudeTop).catch(() => null);
36682
37098
  if (claudeTopStat && !claudeTopStat.isSymbolicLink()) {
36683
37099
  onProgress?.(item.relativePath, "skipping (real dir in .claude)");
36684
37100
  failed++;
@@ -36688,7 +37104,7 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
36688
37104
  if (item.status === "deleted") {
36689
37105
  onProgress?.(item.relativePath, "deleting");
36690
37106
  try {
36691
- await import_fs_extra15.default.remove(targetPath);
37107
+ await import_fs_extra16.default.remove(targetPath);
36692
37108
  deleted++;
36693
37109
  if (useAgents)
36694
37110
  touchedAgentCategories.add(item.category);
@@ -37026,20 +37442,20 @@ async function proSyncCommand(options = {}) {
37026
37442
  }
37027
37443
 
37028
37444
  // src/lib/backup-utils.ts
37029
- var import_fs_extra16 = __toESM(require_lib4(), 1);
37030
- import path20 from "path";
37445
+ var import_fs_extra17 = __toESM(require_lib4(), 1);
37446
+ import path21 from "path";
37031
37447
  import os16 from "os";
37032
- var BACKUP_BASE_DIR = path20.join(os16.homedir(), ".config", "aiblueprint", "backup");
37448
+ var BACKUP_BASE_DIR = path21.join(os16.homedir(), ".config", "aiblueprint", "backup");
37033
37449
  function formatDate(date) {
37034
37450
  const pad = (n) => n.toString().padStart(2, "0");
37035
37451
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
37036
37452
  }
37037
37453
  async function listBackups() {
37038
- const exists = await import_fs_extra16.default.pathExists(BACKUP_BASE_DIR);
37454
+ const exists = await import_fs_extra17.default.pathExists(BACKUP_BASE_DIR);
37039
37455
  if (!exists) {
37040
37456
  return [];
37041
37457
  }
37042
- const entries = await import_fs_extra16.default.readdir(BACKUP_BASE_DIR, { withFileTypes: true });
37458
+ const entries = await import_fs_extra17.default.readdir(BACKUP_BASE_DIR, { withFileTypes: true });
37043
37459
  const backups = [];
37044
37460
  for (const entry of entries) {
37045
37461
  if (!entry.isDirectory())
@@ -37051,7 +37467,7 @@ async function listBackups() {
37051
37467
  const date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second));
37052
37468
  backups.push({
37053
37469
  name: entry.name,
37054
- path: path20.join(BACKUP_BASE_DIR, entry.name),
37470
+ path: path21.join(BACKUP_BASE_DIR, entry.name),
37055
37471
  date
37056
37472
  });
37057
37473
  }
@@ -37060,12 +37476,12 @@ async function listBackups() {
37060
37476
  var AGENTS_BACKUP_SUBDIR = ".agents";
37061
37477
  var CLAUDE_ITEMS = ["commands", "agents", "skills", "scripts", "settings.json"];
37062
37478
  async function copyForBackup(sourcePath, destPath) {
37063
- await import_fs_extra16.default.copy(sourcePath, destPath, {
37479
+ await import_fs_extra17.default.copy(sourcePath, destPath, {
37064
37480
  overwrite: true,
37065
37481
  dereference: false,
37066
37482
  filter: async (src) => {
37067
37483
  try {
37068
- const stat = await import_fs_extra16.default.lstat(src);
37484
+ const stat = await import_fs_extra17.default.lstat(src);
37069
37485
  return !stat.isSymbolicLink();
37070
37486
  } catch {
37071
37487
  return true;
@@ -37074,28 +37490,28 @@ async function copyForBackup(sourcePath, destPath) {
37074
37490
  });
37075
37491
  }
37076
37492
  async function hasMeaningfulContent(dir) {
37077
- if (!await import_fs_extra16.default.pathExists(dir))
37493
+ if (!await import_fs_extra17.default.pathExists(dir))
37078
37494
  return false;
37079
- const files = await import_fs_extra16.default.readdir(dir);
37495
+ const files = await import_fs_extra17.default.readdir(dir);
37080
37496
  return files.some((f) => f !== ".DS_Store");
37081
37497
  }
37082
37498
  async function loadBackup(backupPath, claudeDir, agentsDir) {
37083
- const exists = await import_fs_extra16.default.pathExists(backupPath);
37499
+ const exists = await import_fs_extra17.default.pathExists(backupPath);
37084
37500
  if (!exists) {
37085
37501
  throw new Error(`Backup not found: ${backupPath}`);
37086
37502
  }
37087
- await import_fs_extra16.default.ensureDir(claudeDir);
37503
+ await import_fs_extra17.default.ensureDir(claudeDir);
37088
37504
  for (const item of CLAUDE_ITEMS) {
37089
- const sourcePath = path20.join(backupPath, item);
37090
- const destPath = path20.join(claudeDir, item);
37091
- if (await import_fs_extra16.default.pathExists(sourcePath)) {
37505
+ const sourcePath = path21.join(backupPath, item);
37506
+ const destPath = path21.join(claudeDir, item);
37507
+ if (await import_fs_extra17.default.pathExists(sourcePath)) {
37092
37508
  await copyForBackup(sourcePath, destPath);
37093
37509
  }
37094
37510
  }
37095
37511
  if (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);
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);
37099
37515
  await copyForBackup(agentsBackupPath, agentsDir);
37100
37516
  }
37101
37517
  }
@@ -37107,19 +37523,19 @@ async function createBackup(claudeDir, agentsDir) {
37107
37523
  return null;
37108
37524
  }
37109
37525
  const timestamp3 = formatDate(new Date);
37110
- const backupPath = path20.join(BACKUP_BASE_DIR, timestamp3);
37111
- await import_fs_extra16.default.ensureDir(backupPath);
37526
+ const backupPath = path21.join(BACKUP_BASE_DIR, timestamp3);
37527
+ await import_fs_extra17.default.ensureDir(backupPath);
37112
37528
  if (claudeHasContent) {
37113
37529
  for (const item of CLAUDE_ITEMS) {
37114
- const sourcePath = path20.join(claudeDir, item);
37115
- const destPath = path20.join(backupPath, item);
37116
- if (await import_fs_extra16.default.pathExists(sourcePath)) {
37530
+ const sourcePath = path21.join(claudeDir, item);
37531
+ const destPath = path21.join(backupPath, item);
37532
+ if (await import_fs_extra17.default.pathExists(sourcePath)) {
37117
37533
  await copyForBackup(sourcePath, destPath);
37118
37534
  }
37119
37535
  }
37120
37536
  }
37121
37537
  if (agentsHasContent && agentsDir) {
37122
- const destPath = path20.join(backupPath, AGENTS_BACKUP_SUBDIR);
37538
+ const destPath = path21.join(backupPath, AGENTS_BACKUP_SUBDIR);
37123
37539
  await copyForBackup(agentsDir, destPath);
37124
37540
  }
37125
37541
  return backupPath;
@@ -37303,18 +37719,18 @@ async function configsBackupsCreateCommand(reason, options = {}) {
37303
37719
 
37304
37720
  // src/commands/openclaw-pro.ts
37305
37721
  import os19 from "os";
37306
- import path23 from "path";
37722
+ import path24 from "path";
37307
37723
 
37308
37724
  // src/lib/openclaw-installer.ts
37309
- var import_fs_extra17 = __toESM(require_lib4(), 1);
37725
+ var import_fs_extra18 = __toESM(require_lib4(), 1);
37310
37726
  import os17 from "os";
37311
- import path21 from "path";
37727
+ import path22 from "path";
37312
37728
  import { exec as exec4 } from "child_process";
37313
37729
  import { promisify as promisify3 } from "util";
37314
37730
  var execAsync3 = promisify3(exec4);
37315
37731
  var OPENCLAW_PRO_REPO = "Melvynx/openclawpro";
37316
37732
  function getCacheRepoDir2() {
37317
- return path21.join(os17.homedir(), ".config", "openclaw", "pro-repos", "openclawpro");
37733
+ return path22.join(os17.homedir(), ".config", "openclaw", "pro-repos", "openclawpro");
37318
37734
  }
37319
37735
  async function execGitWithAuth2(command, token, repoUrl, cwd) {
37320
37736
  const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
@@ -37328,33 +37744,33 @@ async function execGitWithAuth2(command, token, repoUrl, cwd) {
37328
37744
  async function cloneOrUpdateRepo2(token) {
37329
37745
  const cacheDir = getCacheRepoDir2();
37330
37746
  const repoUrl = `https://github.com/${OPENCLAW_PRO_REPO}.git`;
37331
- if (await import_fs_extra17.default.pathExists(path21.join(cacheDir, ".git"))) {
37747
+ if (await import_fs_extra18.default.pathExists(path22.join(cacheDir, ".git"))) {
37332
37748
  try {
37333
37749
  await execGitWithAuth2("pull", token, repoUrl, cacheDir);
37334
37750
  } catch (error) {
37335
- await import_fs_extra17.default.remove(cacheDir);
37336
- await import_fs_extra17.default.ensureDir(path21.dirname(cacheDir));
37751
+ await import_fs_extra18.default.remove(cacheDir);
37752
+ await import_fs_extra18.default.ensureDir(path22.dirname(cacheDir));
37337
37753
  await execGitWithAuth2(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
37338
37754
  }
37339
37755
  } else {
37340
- await import_fs_extra17.default.ensureDir(path21.dirname(cacheDir));
37756
+ await import_fs_extra18.default.ensureDir(path22.dirname(cacheDir));
37341
37757
  await execGitWithAuth2(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
37342
37758
  }
37343
- return path21.join(cacheDir, "openclaw-config");
37759
+ return path22.join(cacheDir, "openclaw-config");
37344
37760
  }
37345
37761
  async function copyConfigFromCache2(cacheConfigDir, targetDir, onProgress) {
37346
37762
  const walk = async (dir, baseDir = dir) => {
37347
- const entries = await import_fs_extra17.default.readdir(dir, { withFileTypes: true });
37763
+ const entries = await import_fs_extra18.default.readdir(dir, { withFileTypes: true });
37348
37764
  for (const entry of entries) {
37349
- const sourcePath = path21.join(dir, entry.name);
37350
- const relativePath = path21.relative(baseDir, sourcePath);
37351
- const targetPath = path21.join(targetDir, relativePath);
37765
+ const sourcePath = path22.join(dir, entry.name);
37766
+ const relativePath = path22.relative(baseDir, sourcePath);
37767
+ const targetPath = path22.join(targetDir, relativePath);
37352
37768
  if (entry.isDirectory()) {
37353
- await import_fs_extra17.default.ensureDir(targetPath);
37769
+ await import_fs_extra18.default.ensureDir(targetPath);
37354
37770
  onProgress?.(relativePath, "directory");
37355
37771
  await walk(sourcePath, baseDir);
37356
37772
  } else {
37357
- await import_fs_extra17.default.copy(sourcePath, targetPath, { overwrite: true });
37773
+ await import_fs_extra18.default.copy(sourcePath, targetPath, { overwrite: true });
37358
37774
  onProgress?.(relativePath, "file");
37359
37775
  }
37360
37776
  }
@@ -37363,7 +37779,7 @@ async function copyConfigFromCache2(cacheConfigDir, targetDir, onProgress) {
37363
37779
  }
37364
37780
  async function installOpenclawProConfigs(options) {
37365
37781
  const { githubToken, openclawFolder, onProgress } = options;
37366
- const targetFolder = openclawFolder || path21.join(os17.homedir(), ".openclaw");
37782
+ const targetFolder = openclawFolder || path22.join(os17.homedir(), ".openclaw");
37367
37783
  try {
37368
37784
  const cacheConfigDir = await cloneOrUpdateRepo2(githubToken);
37369
37785
  await copyConfigFromCache2(cacheConfigDir, targetFolder, onProgress);
@@ -37374,28 +37790,28 @@ async function installOpenclawProConfigs(options) {
37374
37790
  }
37375
37791
 
37376
37792
  // src/lib/openclaw-token-storage.ts
37377
- var import_fs_extra18 = __toESM(require_lib4(), 1);
37793
+ var import_fs_extra19 = __toESM(require_lib4(), 1);
37378
37794
  import os18 from "os";
37379
- import path22 from "path";
37795
+ import path23 from "path";
37380
37796
  function getConfigDir2() {
37381
37797
  const platform = os18.platform();
37382
37798
  if (platform === "win32") {
37383
- return path22.join(process.env.APPDATA || os18.homedir(), "openclaw");
37799
+ return path23.join(process.env.APPDATA || os18.homedir(), "openclaw");
37384
37800
  }
37385
- return path22.join(os18.homedir(), ".config", "openclaw");
37801
+ return path23.join(os18.homedir(), ".config", "openclaw");
37386
37802
  }
37387
37803
  function getTokenPath() {
37388
- return path22.join(getConfigDir2(), "token.txt");
37804
+ return path23.join(getConfigDir2(), "token.txt");
37389
37805
  }
37390
37806
  async function saveOpenclawToken(githubToken) {
37391
37807
  const configDir = getConfigDir2();
37392
- await import_fs_extra18.default.ensureDir(configDir);
37393
- await import_fs_extra18.default.writeFile(getTokenPath(), githubToken, { mode: 384 });
37808
+ await import_fs_extra19.default.ensureDir(configDir);
37809
+ await import_fs_extra19.default.writeFile(getTokenPath(), githubToken, { mode: 384 });
37394
37810
  }
37395
37811
  async function getOpenclawToken() {
37396
37812
  const tokenPath = getTokenPath();
37397
- if (await import_fs_extra18.default.pathExists(tokenPath)) {
37398
- const token = await import_fs_extra18.default.readFile(tokenPath, "utf8");
37813
+ if (await import_fs_extra19.default.pathExists(tokenPath)) {
37814
+ const token = await import_fs_extra19.default.readFile(tokenPath, "utf8");
37399
37815
  return token.trim();
37400
37816
  }
37401
37817
  return null;
@@ -37408,7 +37824,7 @@ function getOpenclawTokenInfo() {
37408
37824
  }
37409
37825
 
37410
37826
  // src/commands/openclaw-pro.ts
37411
- var import_fs_extra19 = __toESM(require_lib4(), 1);
37827
+ var import_fs_extra20 = __toESM(require_lib4(), 1);
37412
37828
  var API_URL2 = "https://codeline.app/api/products";
37413
37829
  var OPENCLAW_PRODUCT_ID = "prd_t2GRwX3aH1";
37414
37830
  var CLAUDE_CODE_TOOLS_INSTRUCTIONS = `
@@ -37515,7 +37931,7 @@ async function openclawProSetupCommand(options = {}) {
37515
37931
  Se(source_default.red("❌ Not activated"));
37516
37932
  process.exit(1);
37517
37933
  }
37518
- const openclawDir = options.folder ? path23.resolve(options.folder) : path23.join(os19.homedir(), ".openclaw");
37934
+ const openclawDir = options.folder ? path24.resolve(options.folder) : path24.join(os19.homedir(), ".openclaw");
37519
37935
  const spinner = Y2();
37520
37936
  const onProgress = (file, type) => {
37521
37937
  spinner.message(`Installing: ${source_default.cyan(file)} ${source_default.gray(`(${type})`)}`);
@@ -37528,23 +37944,23 @@ async function openclawProSetupCommand(options = {}) {
37528
37944
  });
37529
37945
  spinner.stop("OpenClaw Pro configurations installed");
37530
37946
  let skillCount = 0;
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);
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);
37534
37950
  const dirs = await Promise.all(items.map(async (item) => {
37535
- const stat = await import_fs_extra19.default.stat(path23.join(skillsDir, item));
37951
+ const stat = await import_fs_extra20.default.stat(path24.join(skillsDir, item));
37536
37952
  return stat.isDirectory();
37537
37953
  }));
37538
37954
  skillCount = dirs.filter(Boolean).length;
37539
37955
  }
37540
37956
  spinner.start("Setting up workspace TOOLS.md...");
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");
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");
37546
37962
  if (!existingContent.includes("Claude Code CLI")) {
37547
- await import_fs_extra19.default.appendFile(toolsPath, `
37963
+ await import_fs_extra20.default.appendFile(toolsPath, `
37548
37964
 
37549
37965
  ` + CLAUDE_CODE_TOOLS_INSTRUCTIONS);
37550
37966
  spinner.stop("TOOLS.md updated with Claude Code instructions");
@@ -37558,7 +37974,7 @@ Skills define _how_ tools work. This file is for _your_ specifics — the stuff
37558
37974
 
37559
37975
  ${CLAUDE_CODE_TOOLS_INSTRUCTIONS}
37560
37976
  `;
37561
- await import_fs_extra19.default.writeFile(toolsPath, defaultToolsMd);
37977
+ await import_fs_extra20.default.writeFile(toolsPath, defaultToolsMd);
37562
37978
  spinner.stop("TOOLS.md created with Claude Code instructions");
37563
37979
  }
37564
37980
  spinner.start("Creating claude-run wrapper...");
@@ -37569,9 +37985,9 @@ ${CLAUDE_CODE_TOOLS_INSTRUCTIONS}
37569
37985
  script -q -c "claude $*" /dev/null
37570
37986
  `;
37571
37987
  const binDir = "/usr/local/bin";
37572
- const wrapperPath = path23.join(binDir, "claude-run");
37988
+ const wrapperPath = path24.join(binDir, "claude-run");
37573
37989
  try {
37574
- await import_fs_extra19.default.writeFile(wrapperPath, claudeRunWrapper, { mode: 493 });
37990
+ await import_fs_extra20.default.writeFile(wrapperPath, claudeRunWrapper, { mode: 493 });
37575
37991
  spinner.stop("claude-run wrapper created");
37576
37992
  } catch {
37577
37993
  spinner.stop("claude-run wrapper skipped (no write access to /usr/local/bin)");
@@ -37620,12 +38036,12 @@ async function openclawProUpdateCommand(options = {}) {
37620
38036
  }
37621
38037
 
37622
38038
  // src/commands/dynamic-scripts.ts
37623
- import path26 from "path";
38039
+ import path27 from "path";
37624
38040
  import { homedir } from "os";
37625
38041
 
37626
38042
  // src/lib/script-parser.ts
37627
- var import_fs_extra20 = __toESM(require_lib4(), 1);
37628
- import path24 from "path";
38043
+ var import_fs_extra21 = __toESM(require_lib4(), 1);
38044
+ import path25 from "path";
37629
38045
  var EXCLUDED_SCRIPTS = ["test", "lint", "format", "start"];
37630
38046
  var EXCLUDED_SUFFIXES = [":test", ":lint", ":test-fixtures", ":start"];
37631
38047
  function shouldIncludeScript(scriptName) {
@@ -37636,12 +38052,12 @@ function shouldIncludeScript(scriptName) {
37636
38052
  return true;
37637
38053
  }
37638
38054
  async function readScriptsPackageJson(claudeDir) {
37639
- const packageJsonPath = path24.join(claudeDir, "scripts", "package.json");
38055
+ const packageJsonPath = path25.join(claudeDir, "scripts", "package.json");
37640
38056
  try {
37641
- if (!await import_fs_extra20.default.pathExists(packageJsonPath)) {
38057
+ if (!await import_fs_extra21.default.pathExists(packageJsonPath)) {
37642
38058
  return null;
37643
38059
  }
37644
- const content = await import_fs_extra20.default.readFile(packageJsonPath, "utf-8");
38060
+ const content = await import_fs_extra21.default.readFile(packageJsonPath, "utf-8");
37645
38061
  const parsed = JSON.parse(content);
37646
38062
  return parsed.scripts || null;
37647
38063
  } catch (error) {
@@ -37685,10 +38101,10 @@ function groupScriptsByPrefix(commands) {
37685
38101
  }
37686
38102
 
37687
38103
  // src/commands/script-runner.ts
37688
- var import_fs_extra21 = __toESM(require_lib4(), 1);
38104
+ var import_fs_extra22 = __toESM(require_lib4(), 1);
37689
38105
  import { spawn as spawn2 } from "child_process";
37690
38106
  import { execSync as execSync4 } from "child_process";
37691
- import path25 from "path";
38107
+ import path26 from "path";
37692
38108
  import os20 from "os";
37693
38109
  function checkCommand2(cmd) {
37694
38110
  try {
@@ -37718,18 +38134,18 @@ async function executeScript(scriptName, claudeDir) {
37718
38134
  console.error(source_default.red("Bun is not installed. Install with: npm install -g bun"));
37719
38135
  return 1;
37720
38136
  }
37721
- const scriptsDir = path25.join(claudeDir, "scripts");
37722
- if (!await import_fs_extra21.default.pathExists(scriptsDir)) {
38137
+ const scriptsDir = path26.join(claudeDir, "scripts");
38138
+ if (!await import_fs_extra22.default.pathExists(scriptsDir)) {
37723
38139
  console.error(source_default.red(`Scripts directory not found at ${scriptsDir}`));
37724
38140
  console.log(source_default.gray("Run: aiblueprint agents setup"));
37725
38141
  return 1;
37726
38142
  }
37727
- const packageJsonPath = path25.join(scriptsDir, "package.json");
37728
- if (!await import_fs_extra21.default.pathExists(packageJsonPath)) {
38143
+ const packageJsonPath = path26.join(scriptsDir, "package.json");
38144
+ if (!await import_fs_extra22.default.pathExists(packageJsonPath)) {
37729
38145
  console.error(source_default.red(`package.json not found in ${scriptsDir}`));
37730
38146
  return 1;
37731
38147
  }
37732
- const packageJson = await import_fs_extra21.default.readJson(packageJsonPath);
38148
+ const packageJson = await import_fs_extra22.default.readJson(packageJsonPath);
37733
38149
  if (!packageJson.scripts || !packageJson.scripts[scriptName]) {
37734
38150
  console.error(source_default.red(`Script "${scriptName}" not found in package.json`));
37735
38151
  return 1;
@@ -37752,7 +38168,7 @@ async function executeScript(scriptName, claudeDir) {
37752
38168
 
37753
38169
  // src/commands/dynamic-scripts.ts
37754
38170
  function getClaudeDir(parentOptions) {
37755
- return parentOptions.claudeCodeFolder || parentOptions.folder ? path26.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path26.join(homedir(), ".claude");
38171
+ return parentOptions.claudeCodeFolder || parentOptions.folder ? path27.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path27.join(homedir(), ".claude");
37756
38172
  }
37757
38173
  async function registerDynamicScriptCommands(claudeCodeCmd, claudeDir) {
37758
38174
  const scripts = await readScriptsPackageJson(claudeDir);
@@ -37814,7 +38230,7 @@ function registerAgentsCommands(cmd) {
37814
38230
  codexFolder: parentOptions.codexFolder
37815
38231
  });
37816
38232
  });
37817
- cmd.command("unify").description("Unify skills and agents into .agents and symlink tool folders back to it").action((options, command) => {
38233
+ cmd.command("unify").description("Unify skills and agents into .agents, then render Codex TOML agents").action((options, command) => {
37818
38234
  const parentOptions = command.parent.opts();
37819
38235
  return agentsUnifyCommand({
37820
38236
  folder: parentOptions.folder,
@@ -37823,6 +38239,16 @@ function registerAgentsCommands(cmd) {
37823
38239
  agentsFolder: parentOptions.agentsFolder
37824
38240
  });
37825
38241
  });
38242
+ 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) => {
38243
+ const parentOptions = command.parent.opts();
38244
+ return codexAgentsCommand({
38245
+ folder: parentOptions.folder,
38246
+ claudeCodeFolder: parentOptions.claudeCodeFolder,
38247
+ codexFolder: parentOptions.codexFolder,
38248
+ agentsFolder: parentOptions.agentsFolder,
38249
+ overwrite: options.overwrite
38250
+ });
38251
+ });
37826
38252
  const proCmd = cmd.command("pro").description("Manage AIBlueprint CLI Premium features");
37827
38253
  proCmd.command("activate [token]").description("Activate AIBlueprint CLI Premium with your access token").action((token) => {
37828
38254
  proActivateCommand(token);