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/agents-config/codex-config/config.toml +9 -0
- package/agents-config/codex-config/hooks/command-deny-list.ts +203 -0
- package/agents-config/skills/environments-manager/SKILL.md +1 -1
- package/agents-config/skills/rules-manager/SKILL.md +2 -2
- package/agents-config/skills/skill-manager/SKILL.md +20 -2
- package/agents-config/skills/skill-manager/references/description-recommandation.md +97 -0
- package/agents-config/skills/skill-manager/scripts/inspect-description.ts +743 -0
- package/dist/cli.js +725 -299
- package/package.json +1 -1
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
|
|
32267
|
-
import
|
|
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 (
|
|
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
|
-
|
|
33902
|
-
|
|
34144
|
+
path13.join(sourceDir, "claude-config", name),
|
|
34145
|
+
path13.join(sourceDir, name)
|
|
33903
34146
|
];
|
|
33904
34147
|
for (const candidate of candidates) {
|
|
33905
|
-
if (await
|
|
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
|
|
33994
|
-
await
|
|
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
|
|
34265
|
+
await import_fs_extra9.default.copy(scriptsSource, path13.join(claudeDir, "scripts"), {
|
|
34023
34266
|
overwrite: true
|
|
34024
34267
|
});
|
|
34025
|
-
await replacePathPlaceholdersInDir(
|
|
34026
|
-
await
|
|
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 =
|
|
34035
|
-
if (await
|
|
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 =
|
|
34051
|
-
if (await
|
|
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
|
|
34072
|
-
const codexConfigSource =
|
|
34073
|
-
if (await
|
|
34074
|
-
const codexConfigPath =
|
|
34075
|
-
if (await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
34158
|
-
import
|
|
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 =
|
|
34194
|
-
return
|
|
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 (!
|
|
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
|
-
|
|
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:
|
|
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 =
|
|
34263
|
-
if (
|
|
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 =
|
|
34529
|
+
const zshrcPath = path14.join(homeDir, ".zshrc");
|
|
34282
34530
|
const sanitizedTheme = sanitizeThemeName(theme);
|
|
34283
|
-
if (!
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
34304
|
-
if (!
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
34424
|
-
if (
|
|
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
|
|
34475
|
-
import
|
|
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 ?
|
|
34729
|
+
baseDir = customFolder ? path15.resolve(customFolder) : path15.join(os12.homedir(), ".claude");
|
|
34482
34730
|
return {
|
|
34483
34731
|
baseDir,
|
|
34484
|
-
commandsPath:
|
|
34485
|
-
agentsPath:
|
|
34732
|
+
commandsPath: path15.join(baseDir, "commands"),
|
|
34733
|
+
agentsPath: path15.join(baseDir, "agents")
|
|
34486
34734
|
};
|
|
34487
34735
|
case "codex":
|
|
34488
|
-
baseDir = customFolder ?
|
|
34736
|
+
baseDir = customFolder ? path15.resolve(customFolder) : path15.join(os12.homedir(), ".codex");
|
|
34489
34737
|
return {
|
|
34490
34738
|
baseDir,
|
|
34491
|
-
agentsPath:
|
|
34739
|
+
agentsPath: path15.join(baseDir, "agents")
|
|
34492
34740
|
};
|
|
34493
34741
|
case "opencode":
|
|
34494
|
-
baseDir = customFolder ?
|
|
34742
|
+
baseDir = customFolder ? path15.resolve(customFolder) : path15.join(os12.homedir(), ".config", "opencode");
|
|
34495
34743
|
return {
|
|
34496
34744
|
baseDir,
|
|
34497
|
-
commandsPath:
|
|
34745
|
+
commandsPath: path15.join(baseDir, "command")
|
|
34498
34746
|
};
|
|
34499
34747
|
case "factoryai":
|
|
34500
|
-
baseDir = customFolder ?
|
|
34748
|
+
baseDir = customFolder ? path15.resolve(customFolder) : path15.join(os12.homedir(), ".factory");
|
|
34501
34749
|
return {
|
|
34502
34750
|
baseDir,
|
|
34503
|
-
commandsPath:
|
|
34504
|
-
agentsPath:
|
|
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
|
|
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 =
|
|
34518
|
-
await
|
|
34519
|
-
const targetExists = await
|
|
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
|
|
34769
|
+
const stat = await import_fs_extra11.default.lstat(targetPath);
|
|
34522
34770
|
if (stat.isSymbolicLink()) {
|
|
34523
|
-
await
|
|
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
|
|
34779
|
+
await import_fs_extra11.default.symlink(sourcePath, targetPath, "junction");
|
|
34532
34780
|
} else {
|
|
34533
|
-
await
|
|
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
|
|
34962
|
+
var import_fs_extra12 = __toESM(require_lib4(), 1);
|
|
34715
34963
|
import crypto from "crypto";
|
|
34716
34964
|
import os13 from "os";
|
|
34717
|
-
import
|
|
34718
|
-
var
|
|
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 =
|
|
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 =
|
|
34738
|
-
const factoryDir =
|
|
34739
|
-
const opencodeDir =
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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
|
|
35126
|
+
const stat = await import_fs_extra12.default.lstat(targetPath);
|
|
34865
35127
|
if (stat.isSymbolicLink()) {
|
|
34866
|
-
const linkTarget = await
|
|
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
|
|
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
|
|
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(
|
|
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 =
|
|
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(
|
|
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
|
|
35174
|
+
if (!await import_fs_extra12.default.pathExists(destinationDir))
|
|
34913
35175
|
return;
|
|
34914
|
-
const entries = await
|
|
35176
|
+
const entries = await import_fs_extra12.default.readdir(destinationDir, { withFileTypes: true });
|
|
34915
35177
|
for (const entry of entries) {
|
|
34916
|
-
if (
|
|
35178
|
+
if (IGNORED_ENTRY_NAMES2.has(entry.name))
|
|
34917
35179
|
continue;
|
|
34918
|
-
const entryPath =
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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:
|
|
35219
|
+
keptAs: path16.join(destinationDir, existingName)
|
|
34958
35220
|
});
|
|
34959
35221
|
continue;
|
|
34960
35222
|
}
|
|
34961
35223
|
let targetName = entry.name;
|
|
34962
|
-
let targetPath =
|
|
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 =
|
|
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
|
|
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 =
|
|
34993
|
-
if (!relativePath || relativePath.startsWith("..") ||
|
|
34994
|
-
return
|
|
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
|
|
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
|
|
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
|
|
35271
|
+
await import_fs_extra12.default.ensureDir(path16.dirname(target));
|
|
35010
35272
|
if (os13.platform() === "win32") {
|
|
35011
|
-
await
|
|
35273
|
+
await import_fs_extra12.default.symlink(source, target, "junction");
|
|
35012
35274
|
return;
|
|
35013
35275
|
}
|
|
35014
|
-
await
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
35061
|
-
await
|
|
35062
|
-
await
|
|
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:
|
|
35087
|
-
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
|
|
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
|
|
36272
|
+
import path19 from "path";
|
|
35857
36273
|
|
|
35858
36274
|
// src/lib/pro-installer.ts
|
|
35859
|
-
var
|
|
36275
|
+
var import_fs_extra13 = __toESM(require_lib4(), 1);
|
|
35860
36276
|
import os14 from "os";
|
|
35861
|
-
import
|
|
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(
|
|
36285
|
+
const segments = relativePath.split(path17.sep);
|
|
35870
36286
|
const first = segments[0];
|
|
35871
|
-
const rest = segments.slice(1).join(
|
|
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
|
|
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
|
|
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
|
|
35906
|
-
await
|
|
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
|
|
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 =
|
|
35915
|
-
if (await
|
|
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
|
|
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 =
|
|
35928
|
-
const relativePath =
|
|
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(
|
|
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 =
|
|
36355
|
+
const targetPath = path17.join(targetBase, route.relativePath);
|
|
35940
36356
|
if (entry.isDirectory()) {
|
|
35941
|
-
await
|
|
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
|
|
36364
|
+
const content = await import_fs_extra13.default.readFile(sourcePath, "utf-8");
|
|
35949
36365
|
const replaced = replaceClaudePathPlaceholder(content, dest.claudeDir);
|
|
35950
|
-
await
|
|
35951
|
-
await
|
|
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
|
|
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 =
|
|
35963
|
-
await
|
|
35964
|
-
const entries = await
|
|
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 =
|
|
35969
|
-
const dst =
|
|
35970
|
-
const claudeTop =
|
|
35971
|
-
const claudeStat = await
|
|
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
|
|
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
|
|
35996
|
-
await
|
|
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
|
|
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 =
|
|
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
|
|
36048
|
-
await
|
|
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 =
|
|
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 =
|
|
36073
|
-
if (await
|
|
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
|
|
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
|
|
36509
|
+
var import_fs_extra14 = __toESM(require_lib4(), 1);
|
|
36094
36510
|
import os15 from "os";
|
|
36095
|
-
import
|
|
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 ||
|
|
36100
|
-
return
|
|
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 ||
|
|
36103
|
-
return
|
|
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
|
|
36523
|
+
return path18.join(getConfigDir(), "token.txt");
|
|
36108
36524
|
}
|
|
36109
36525
|
async function saveToken(githubToken) {
|
|
36110
36526
|
const tokenFile = getTokenFilePath2();
|
|
36111
|
-
const configDir =
|
|
36527
|
+
const configDir = path18.dirname(tokenFile);
|
|
36112
36528
|
try {
|
|
36113
|
-
await
|
|
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
|
|
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
|
|
36541
|
+
if (!await import_fs_extra14.default.pathExists(tokenFile)) {
|
|
36126
36542
|
return null;
|
|
36127
36543
|
}
|
|
36128
36544
|
try {
|
|
36129
|
-
const token = await
|
|
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
|
|
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 =
|
|
36153
|
-
if (await
|
|
36154
|
-
const files = await
|
|
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 =
|
|
36162
|
-
if (await
|
|
36163
|
-
const items = await
|
|
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
|
|
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
|
|
36374
|
-
import
|
|
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
|
|
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
|
|
36869
|
+
if (!await import_fs_extra16.default.pathExists(dir)) {
|
|
36454
36870
|
return files;
|
|
36455
36871
|
}
|
|
36456
|
-
const items = await
|
|
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 =
|
|
36461
|
-
const stat = await
|
|
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
|
|
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 =
|
|
36896
|
+
const fullPath = path20.join(dir, item);
|
|
36481
36897
|
const relativePath = `${basePath}/${item}`;
|
|
36482
|
-
const stat = await
|
|
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
|
|
36912
|
+
if (!await import_fs_extra16.default.pathExists(claudeCategoryDir))
|
|
36497
36913
|
return [];
|
|
36498
|
-
const entries = await
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
37048
|
+
await import_fs_extra16.default.writeFile(targetPath, transformedContent, "utf-8");
|
|
36633
37049
|
} else {
|
|
36634
|
-
await
|
|
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 =
|
|
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 =
|
|
36654
|
-
const claudeTop =
|
|
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
|
|
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
|
|
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
|
|
36670
|
-
await
|
|
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 =
|
|
36681
|
-
const claudeTopStat = await
|
|
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
|
|
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
|
|
37030
|
-
import
|
|
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 =
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
37493
|
+
if (!await import_fs_extra17.default.pathExists(dir))
|
|
37078
37494
|
return false;
|
|
37079
|
-
const files = await
|
|
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
|
|
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
|
|
37503
|
+
await import_fs_extra17.default.ensureDir(claudeDir);
|
|
37088
37504
|
for (const item of CLAUDE_ITEMS) {
|
|
37089
|
-
const sourcePath =
|
|
37090
|
-
const destPath =
|
|
37091
|
-
if (await
|
|
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 =
|
|
37097
|
-
if (await
|
|
37098
|
-
await
|
|
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 =
|
|
37111
|
-
await
|
|
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 =
|
|
37115
|
-
const destPath =
|
|
37116
|
-
if (await
|
|
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 =
|
|
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
|
|
37722
|
+
import path24 from "path";
|
|
37307
37723
|
|
|
37308
37724
|
// src/lib/openclaw-installer.ts
|
|
37309
|
-
var
|
|
37725
|
+
var import_fs_extra18 = __toESM(require_lib4(), 1);
|
|
37310
37726
|
import os17 from "os";
|
|
37311
|
-
import
|
|
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
|
|
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
|
|
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
|
|
37336
|
-
await
|
|
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
|
|
37756
|
+
await import_fs_extra18.default.ensureDir(path22.dirname(cacheDir));
|
|
37341
37757
|
await execGitWithAuth2(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
|
|
37342
37758
|
}
|
|
37343
|
-
return
|
|
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
|
|
37763
|
+
const entries = await import_fs_extra18.default.readdir(dir, { withFileTypes: true });
|
|
37348
37764
|
for (const entry of entries) {
|
|
37349
|
-
const sourcePath =
|
|
37350
|
-
const relativePath =
|
|
37351
|
-
const targetPath =
|
|
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
|
|
37769
|
+
await import_fs_extra18.default.ensureDir(targetPath);
|
|
37354
37770
|
onProgress?.(relativePath, "directory");
|
|
37355
37771
|
await walk(sourcePath, baseDir);
|
|
37356
37772
|
} else {
|
|
37357
|
-
await
|
|
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 ||
|
|
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
|
|
37793
|
+
var import_fs_extra19 = __toESM(require_lib4(), 1);
|
|
37378
37794
|
import os18 from "os";
|
|
37379
|
-
import
|
|
37795
|
+
import path23 from "path";
|
|
37380
37796
|
function getConfigDir2() {
|
|
37381
37797
|
const platform = os18.platform();
|
|
37382
37798
|
if (platform === "win32") {
|
|
37383
|
-
return
|
|
37799
|
+
return path23.join(process.env.APPDATA || os18.homedir(), "openclaw");
|
|
37384
37800
|
}
|
|
37385
|
-
return
|
|
37801
|
+
return path23.join(os18.homedir(), ".config", "openclaw");
|
|
37386
37802
|
}
|
|
37387
37803
|
function getTokenPath() {
|
|
37388
|
-
return
|
|
37804
|
+
return path23.join(getConfigDir2(), "token.txt");
|
|
37389
37805
|
}
|
|
37390
37806
|
async function saveOpenclawToken(githubToken) {
|
|
37391
37807
|
const configDir = getConfigDir2();
|
|
37392
|
-
await
|
|
37393
|
-
await
|
|
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
|
|
37398
|
-
const token = await
|
|
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
|
|
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 ?
|
|
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 =
|
|
37532
|
-
if (await
|
|
37533
|
-
const items = await
|
|
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
|
|
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 =
|
|
37542
|
-
const toolsPath =
|
|
37543
|
-
await
|
|
37544
|
-
if (await
|
|
37545
|
-
const existingContent = await
|
|
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
|
|
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
|
|
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 =
|
|
37988
|
+
const wrapperPath = path24.join(binDir, "claude-run");
|
|
37573
37989
|
try {
|
|
37574
|
-
await
|
|
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
|
|
38039
|
+
import path27 from "path";
|
|
37624
38040
|
import { homedir } from "os";
|
|
37625
38041
|
|
|
37626
38042
|
// src/lib/script-parser.ts
|
|
37627
|
-
var
|
|
37628
|
-
import
|
|
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 =
|
|
38055
|
+
const packageJsonPath = path25.join(claudeDir, "scripts", "package.json");
|
|
37640
38056
|
try {
|
|
37641
|
-
if (!await
|
|
38057
|
+
if (!await import_fs_extra21.default.pathExists(packageJsonPath)) {
|
|
37642
38058
|
return null;
|
|
37643
38059
|
}
|
|
37644
|
-
const content = await
|
|
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
|
|
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
|
|
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 =
|
|
37722
|
-
if (!await
|
|
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 =
|
|
37728
|
-
if (!await
|
|
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
|
|
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 ?
|
|
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
|
|
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);
|