aiblueprint-cli 1.4.58 → 1.4.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/cli.js +618 -182
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -34710,6 +34710,433 @@ async function symlinkCommand(params = {}) {
|
|
|
34710
34710
|
}
|
|
34711
34711
|
}
|
|
34712
34712
|
|
|
34713
|
+
// src/lib/agents-unifier.ts
|
|
34714
|
+
var import_fs_extra11 = __toESM(require_lib4(), 1);
|
|
34715
|
+
import crypto from "crypto";
|
|
34716
|
+
import os13 from "os";
|
|
34717
|
+
import path15 from "path";
|
|
34718
|
+
var IGNORED_ENTRY_NAMES = new Set([
|
|
34719
|
+
".DS_Store",
|
|
34720
|
+
".git",
|
|
34721
|
+
"node_modules"
|
|
34722
|
+
]);
|
|
34723
|
+
function uniqueByPath(candidates) {
|
|
34724
|
+
const seen = new Set;
|
|
34725
|
+
const unique = [];
|
|
34726
|
+
for (const candidate of candidates) {
|
|
34727
|
+
const resolved = path15.resolve(candidate.path);
|
|
34728
|
+
if (seen.has(resolved))
|
|
34729
|
+
continue;
|
|
34730
|
+
seen.add(resolved);
|
|
34731
|
+
unique.push({ ...candidate, path: resolved });
|
|
34732
|
+
}
|
|
34733
|
+
return unique;
|
|
34734
|
+
}
|
|
34735
|
+
function getContainerCandidates(options) {
|
|
34736
|
+
const folders = resolveFolders(options);
|
|
34737
|
+
const cursorDir = path15.join(folders.rootDir, ".cursor");
|
|
34738
|
+
const factoryDir = path15.join(folders.rootDir, ".factory");
|
|
34739
|
+
const opencodeDir = path15.join(folders.rootDir, ".config", "opencode");
|
|
34740
|
+
return uniqueByPath([
|
|
34741
|
+
{
|
|
34742
|
+
category: "skills",
|
|
34743
|
+
label: "agents-skills",
|
|
34744
|
+
path: path15.join(folders.agentsDir, "skills"),
|
|
34745
|
+
isDestination: true
|
|
34746
|
+
},
|
|
34747
|
+
{
|
|
34748
|
+
category: "skills",
|
|
34749
|
+
label: "claude-skills",
|
|
34750
|
+
path: path15.join(folders.claudeDir, "skills"),
|
|
34751
|
+
linkWhenMissing: true
|
|
34752
|
+
},
|
|
34753
|
+
{
|
|
34754
|
+
category: "skills",
|
|
34755
|
+
label: "codex-skills",
|
|
34756
|
+
path: path15.join(folders.codexDir, "skills"),
|
|
34757
|
+
linkWhenMissing: true
|
|
34758
|
+
},
|
|
34759
|
+
{
|
|
34760
|
+
category: "skills",
|
|
34761
|
+
label: "cursor-skills",
|
|
34762
|
+
path: path15.join(cursorDir, "skills"),
|
|
34763
|
+
linkWhenParentExists: true
|
|
34764
|
+
},
|
|
34765
|
+
{
|
|
34766
|
+
category: "skills",
|
|
34767
|
+
label: "cursor-skills-cursor",
|
|
34768
|
+
path: path15.join(cursorDir, "skills-cursor"),
|
|
34769
|
+
linkWhenParentExists: true
|
|
34770
|
+
},
|
|
34771
|
+
{
|
|
34772
|
+
category: "skills",
|
|
34773
|
+
label: "factory-skills",
|
|
34774
|
+
path: path15.join(factoryDir, "skills"),
|
|
34775
|
+
linkWhenParentExists: true
|
|
34776
|
+
},
|
|
34777
|
+
{
|
|
34778
|
+
category: "skills",
|
|
34779
|
+
label: "opencode-skill",
|
|
34780
|
+
path: path15.join(opencodeDir, "skill"),
|
|
34781
|
+
linkWhenParentExists: true
|
|
34782
|
+
},
|
|
34783
|
+
{
|
|
34784
|
+
category: "skills",
|
|
34785
|
+
label: "opencode-skills",
|
|
34786
|
+
path: path15.join(opencodeDir, "skills"),
|
|
34787
|
+
linkWhenParentExists: true
|
|
34788
|
+
},
|
|
34789
|
+
{
|
|
34790
|
+
category: "agents",
|
|
34791
|
+
label: "agents-agents",
|
|
34792
|
+
path: path15.join(folders.agentsDir, "agents"),
|
|
34793
|
+
isDestination: true
|
|
34794
|
+
},
|
|
34795
|
+
{
|
|
34796
|
+
category: "agents",
|
|
34797
|
+
label: "claude-agents",
|
|
34798
|
+
path: path15.join(folders.claudeDir, "agents"),
|
|
34799
|
+
linkWhenMissing: true
|
|
34800
|
+
},
|
|
34801
|
+
{
|
|
34802
|
+
category: "agents",
|
|
34803
|
+
label: "claude-agnets",
|
|
34804
|
+
path: path15.join(folders.claudeDir, "agnets")
|
|
34805
|
+
},
|
|
34806
|
+
{
|
|
34807
|
+
category: "agents",
|
|
34808
|
+
label: "codex-agents",
|
|
34809
|
+
path: path15.join(folders.codexDir, "agents"),
|
|
34810
|
+
linkWhenMissing: true
|
|
34811
|
+
},
|
|
34812
|
+
{
|
|
34813
|
+
category: "agents",
|
|
34814
|
+
label: "cursor-agents",
|
|
34815
|
+
path: path15.join(cursorDir, "agents"),
|
|
34816
|
+
linkWhenParentExists: true
|
|
34817
|
+
},
|
|
34818
|
+
{
|
|
34819
|
+
category: "agents",
|
|
34820
|
+
label: "factory-droids",
|
|
34821
|
+
path: path15.join(factoryDir, "droids"),
|
|
34822
|
+
linkWhenParentExists: true
|
|
34823
|
+
},
|
|
34824
|
+
{
|
|
34825
|
+
category: "agents",
|
|
34826
|
+
label: "opencode-agent",
|
|
34827
|
+
path: path15.join(opencodeDir, "agent"),
|
|
34828
|
+
linkWhenParentExists: true
|
|
34829
|
+
},
|
|
34830
|
+
{
|
|
34831
|
+
category: "agents",
|
|
34832
|
+
label: "opencode-agents",
|
|
34833
|
+
path: path15.join(opencodeDir, "agents"),
|
|
34834
|
+
linkWhenParentExists: true
|
|
34835
|
+
}
|
|
34836
|
+
]);
|
|
34837
|
+
}
|
|
34838
|
+
function shouldCollectEntry(category, entry) {
|
|
34839
|
+
if (IGNORED_ENTRY_NAMES.has(entry.name))
|
|
34840
|
+
return false;
|
|
34841
|
+
if (category === "skills" && entry.name === ".cursor-managed-skills-manifest.json") {
|
|
34842
|
+
return true;
|
|
34843
|
+
}
|
|
34844
|
+
return entry.isFile() || entry.isDirectory() || entry.isSymbolicLink();
|
|
34845
|
+
}
|
|
34846
|
+
async function pathExistsOrSymlink(targetPath) {
|
|
34847
|
+
const stat = await import_fs_extra11.default.lstat(targetPath).catch(() => null);
|
|
34848
|
+
return Boolean(stat);
|
|
34849
|
+
}
|
|
34850
|
+
async function realPathIfPossible(targetPath) {
|
|
34851
|
+
try {
|
|
34852
|
+
return await import_fs_extra11.default.realpath(targetPath);
|
|
34853
|
+
} catch {
|
|
34854
|
+
return null;
|
|
34855
|
+
}
|
|
34856
|
+
}
|
|
34857
|
+
function samePath(a, b) {
|
|
34858
|
+
return path15.resolve(a) === path15.resolve(b);
|
|
34859
|
+
}
|
|
34860
|
+
function hashString(value) {
|
|
34861
|
+
return crypto.createHash("sha256").update(value).digest("hex");
|
|
34862
|
+
}
|
|
34863
|
+
async function hashPath(targetPath) {
|
|
34864
|
+
const stat = await import_fs_extra11.default.lstat(targetPath);
|
|
34865
|
+
if (stat.isSymbolicLink()) {
|
|
34866
|
+
const linkTarget = await import_fs_extra11.default.readlink(targetPath);
|
|
34867
|
+
return hashString(`symlink:${linkTarget}`);
|
|
34868
|
+
}
|
|
34869
|
+
if (stat.isFile()) {
|
|
34870
|
+
const fileHash = crypto.createHash("sha256");
|
|
34871
|
+
fileHash.update("file:");
|
|
34872
|
+
fileHash.update(await import_fs_extra11.default.readFile(targetPath));
|
|
34873
|
+
return fileHash.digest("hex");
|
|
34874
|
+
}
|
|
34875
|
+
if (stat.isDirectory()) {
|
|
34876
|
+
const entries = (await import_fs_extra11.default.readdir(targetPath, { withFileTypes: true })).filter((entry) => !IGNORED_ENTRY_NAMES.has(entry.name)).sort((a, b) => a.name.localeCompare(b.name));
|
|
34877
|
+
const dirHash = crypto.createHash("sha256");
|
|
34878
|
+
dirHash.update("dir:");
|
|
34879
|
+
for (const entry of entries) {
|
|
34880
|
+
dirHash.update(entry.name);
|
|
34881
|
+
dirHash.update("\x00");
|
|
34882
|
+
dirHash.update(await hashPath(path15.join(targetPath, entry.name)));
|
|
34883
|
+
dirHash.update("\x00");
|
|
34884
|
+
}
|
|
34885
|
+
return dirHash.digest("hex");
|
|
34886
|
+
}
|
|
34887
|
+
return hashString(`other:${stat.mode}:${stat.size}`);
|
|
34888
|
+
}
|
|
34889
|
+
function suffixFromLabel(label) {
|
|
34890
|
+
return label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "source";
|
|
34891
|
+
}
|
|
34892
|
+
function nameWithSuffix(name, suffix, index) {
|
|
34893
|
+
const parsed = path15.parse(name);
|
|
34894
|
+
const numberedSuffix = index === 1 ? suffix : `${suffix}-${index}`;
|
|
34895
|
+
if (parsed.ext && parsed.name) {
|
|
34896
|
+
return `${parsed.name}--${numberedSuffix}${parsed.ext}`;
|
|
34897
|
+
}
|
|
34898
|
+
return `${name}--${numberedSuffix}`;
|
|
34899
|
+
}
|
|
34900
|
+
async function findTargetName(destinationDir, originalName, label) {
|
|
34901
|
+
const suffix = suffixFromLabel(label);
|
|
34902
|
+
let index = 1;
|
|
34903
|
+
while (true) {
|
|
34904
|
+
const candidate = nameWithSuffix(originalName, suffix, index);
|
|
34905
|
+
if (!await pathExistsOrSymlink(path15.join(destinationDir, candidate))) {
|
|
34906
|
+
return candidate;
|
|
34907
|
+
}
|
|
34908
|
+
index++;
|
|
34909
|
+
}
|
|
34910
|
+
}
|
|
34911
|
+
async function addExistingDestinationHashes(destinationDir, knownHashes) {
|
|
34912
|
+
if (!await import_fs_extra11.default.pathExists(destinationDir))
|
|
34913
|
+
return;
|
|
34914
|
+
const entries = await import_fs_extra11.default.readdir(destinationDir, { withFileTypes: true });
|
|
34915
|
+
for (const entry of entries) {
|
|
34916
|
+
if (IGNORED_ENTRY_NAMES.has(entry.name))
|
|
34917
|
+
continue;
|
|
34918
|
+
const entryPath = path15.join(destinationDir, entry.name);
|
|
34919
|
+
knownHashes.set(await hashPath(entryPath), entry.name);
|
|
34920
|
+
}
|
|
34921
|
+
}
|
|
34922
|
+
async function importCategoryEntries(category, candidates, destinationDir, result) {
|
|
34923
|
+
await import_fs_extra11.default.ensureDir(destinationDir);
|
|
34924
|
+
const destinationRealPath = await realPathIfPossible(destinationDir);
|
|
34925
|
+
const knownHashes = new Map;
|
|
34926
|
+
await addExistingDestinationHashes(destinationDir, knownHashes);
|
|
34927
|
+
for (const candidate of candidates) {
|
|
34928
|
+
if (candidate.category !== category || candidate.isDestination)
|
|
34929
|
+
continue;
|
|
34930
|
+
const candidateStat = await import_fs_extra11.default.lstat(candidate.path).catch(() => null);
|
|
34931
|
+
if (!candidateStat)
|
|
34932
|
+
continue;
|
|
34933
|
+
const candidateRealPath = await realPathIfPossible(candidate.path);
|
|
34934
|
+
if (destinationRealPath && candidateRealPath && samePath(destinationRealPath, candidateRealPath)) {
|
|
34935
|
+
continue;
|
|
34936
|
+
}
|
|
34937
|
+
const entries = await import_fs_extra11.default.readdir(candidate.path, { withFileTypes: true }).catch(() => null);
|
|
34938
|
+
if (!entries) {
|
|
34939
|
+
result.skipped.push({
|
|
34940
|
+
category,
|
|
34941
|
+
path: candidate.path,
|
|
34942
|
+
reason: "Could not read directory"
|
|
34943
|
+
});
|
|
34944
|
+
continue;
|
|
34945
|
+
}
|
|
34946
|
+
for (const entry of entries) {
|
|
34947
|
+
if (!shouldCollectEntry(category, entry))
|
|
34948
|
+
continue;
|
|
34949
|
+
const sourcePath = path15.join(candidate.path, entry.name);
|
|
34950
|
+
const sourceHash = await hashPath(sourcePath);
|
|
34951
|
+
const existingName = knownHashes.get(sourceHash);
|
|
34952
|
+
if (existingName) {
|
|
34953
|
+
result.duplicates.push({
|
|
34954
|
+
category,
|
|
34955
|
+
name: entry.name,
|
|
34956
|
+
from: sourcePath,
|
|
34957
|
+
keptAs: path15.join(destinationDir, existingName)
|
|
34958
|
+
});
|
|
34959
|
+
continue;
|
|
34960
|
+
}
|
|
34961
|
+
let targetName = entry.name;
|
|
34962
|
+
let targetPath = path15.join(destinationDir, targetName);
|
|
34963
|
+
if (await pathExistsOrSymlink(targetPath)) {
|
|
34964
|
+
targetName = await findTargetName(destinationDir, entry.name, candidate.label);
|
|
34965
|
+
targetPath = path15.join(destinationDir, targetName);
|
|
34966
|
+
result.renamed.push({
|
|
34967
|
+
category,
|
|
34968
|
+
name: entry.name,
|
|
34969
|
+
from: sourcePath,
|
|
34970
|
+
to: targetPath,
|
|
34971
|
+
reason: "Same name with different content"
|
|
34972
|
+
});
|
|
34973
|
+
}
|
|
34974
|
+
await import_fs_extra11.default.copy(sourcePath, targetPath, {
|
|
34975
|
+
dereference: false,
|
|
34976
|
+
overwrite: false
|
|
34977
|
+
});
|
|
34978
|
+
knownHashes.set(sourceHash, targetName);
|
|
34979
|
+
result.imported.push({
|
|
34980
|
+
category,
|
|
34981
|
+
name: entry.name,
|
|
34982
|
+
from: sourcePath,
|
|
34983
|
+
to: targetPath
|
|
34984
|
+
});
|
|
34985
|
+
}
|
|
34986
|
+
}
|
|
34987
|
+
}
|
|
34988
|
+
function timestamp2(date = new Date) {
|
|
34989
|
+
return date.toISOString().replace(/\.\d{3}Z$/, "").replace(/[:T]/g, "-");
|
|
34990
|
+
}
|
|
34991
|
+
function safeRelativePath(rootDir, targetPath) {
|
|
34992
|
+
const relativePath = path15.relative(rootDir, targetPath);
|
|
34993
|
+
if (!relativePath || relativePath.startsWith("..") || path15.isAbsolute(relativePath)) {
|
|
34994
|
+
return path15.join("external", targetPath.replace(/[^a-zA-Z0-9._-]+/g, "-"));
|
|
34995
|
+
}
|
|
34996
|
+
return relativePath;
|
|
34997
|
+
}
|
|
34998
|
+
function createBackupPath(rootDir) {
|
|
34999
|
+
return path15.join(rootDir, ".aiblueprint", "backups", "agents-unify-sources", timestamp2());
|
|
35000
|
+
}
|
|
35001
|
+
async function ensureBackupPath(result) {
|
|
35002
|
+
if (!result.backupPath) {
|
|
35003
|
+
result.backupPath = createBackupPath(result.rootDir);
|
|
35004
|
+
await import_fs_extra11.default.ensureDir(result.backupPath);
|
|
35005
|
+
}
|
|
35006
|
+
return result.backupPath;
|
|
35007
|
+
}
|
|
35008
|
+
async function createDirectorySymlink(source, target) {
|
|
35009
|
+
await import_fs_extra11.default.ensureDir(path15.dirname(target));
|
|
35010
|
+
if (os13.platform() === "win32") {
|
|
35011
|
+
await import_fs_extra11.default.symlink(source, target, "junction");
|
|
35012
|
+
return;
|
|
35013
|
+
}
|
|
35014
|
+
await import_fs_extra11.default.symlink(source, target, "dir");
|
|
35015
|
+
}
|
|
35016
|
+
async function shouldLinkMissingContainer(candidate) {
|
|
35017
|
+
if (candidate.linkWhenMissing)
|
|
35018
|
+
return true;
|
|
35019
|
+
if (!candidate.linkWhenParentExists)
|
|
35020
|
+
return false;
|
|
35021
|
+
return import_fs_extra11.default.pathExists(path15.dirname(candidate.path));
|
|
35022
|
+
}
|
|
35023
|
+
async function linkContainer(candidate, destinationDir, result) {
|
|
35024
|
+
if (candidate.isDestination || samePath(candidate.path, destinationDir)) {
|
|
35025
|
+
return;
|
|
35026
|
+
}
|
|
35027
|
+
const destinationRealPath = await realPathIfPossible(destinationDir);
|
|
35028
|
+
const stat = await import_fs_extra11.default.lstat(candidate.path).catch(() => null);
|
|
35029
|
+
if (!stat) {
|
|
35030
|
+
if (!await shouldLinkMissingContainer(candidate))
|
|
35031
|
+
return;
|
|
35032
|
+
await createDirectorySymlink(destinationDir, candidate.path);
|
|
35033
|
+
result.linked.push({
|
|
35034
|
+
category: candidate.category,
|
|
35035
|
+
from: candidate.path,
|
|
35036
|
+
to: destinationDir
|
|
35037
|
+
});
|
|
35038
|
+
return;
|
|
35039
|
+
}
|
|
35040
|
+
if (stat.isSymbolicLink()) {
|
|
35041
|
+
const existingRealPath = await realPathIfPossible(candidate.path);
|
|
35042
|
+
if (destinationRealPath && existingRealPath && samePath(destinationRealPath, existingRealPath)) {
|
|
35043
|
+
result.alreadyLinked.push({
|
|
35044
|
+
category: candidate.category,
|
|
35045
|
+
from: candidate.path,
|
|
35046
|
+
to: destinationDir
|
|
35047
|
+
});
|
|
35048
|
+
return;
|
|
35049
|
+
}
|
|
35050
|
+
await import_fs_extra11.default.remove(candidate.path);
|
|
35051
|
+
await createDirectorySymlink(destinationDir, candidate.path);
|
|
35052
|
+
result.linked.push({
|
|
35053
|
+
category: candidate.category,
|
|
35054
|
+
from: candidate.path,
|
|
35055
|
+
to: destinationDir
|
|
35056
|
+
});
|
|
35057
|
+
return;
|
|
35058
|
+
}
|
|
35059
|
+
const backupRoot = await ensureBackupPath(result);
|
|
35060
|
+
const backupTarget = path15.join(backupRoot, safeRelativePath(result.rootDir, candidate.path));
|
|
35061
|
+
await import_fs_extra11.default.ensureDir(path15.dirname(backupTarget));
|
|
35062
|
+
await import_fs_extra11.default.move(candidate.path, backupTarget, { overwrite: false });
|
|
35063
|
+
await createDirectorySymlink(destinationDir, candidate.path);
|
|
35064
|
+
result.linked.push({
|
|
35065
|
+
category: candidate.category,
|
|
35066
|
+
from: candidate.path,
|
|
35067
|
+
to: destinationDir,
|
|
35068
|
+
movedToBackup: backupTarget
|
|
35069
|
+
});
|
|
35070
|
+
}
|
|
35071
|
+
async function unifyAgentsConfiguration(options = {}) {
|
|
35072
|
+
const folders = resolveFolders(options);
|
|
35073
|
+
const candidates = getContainerCandidates(options);
|
|
35074
|
+
const result = {
|
|
35075
|
+
rootDir: folders.rootDir,
|
|
35076
|
+
agentsDir: folders.agentsDir,
|
|
35077
|
+
backupPath: null,
|
|
35078
|
+
imported: [],
|
|
35079
|
+
duplicates: [],
|
|
35080
|
+
renamed: [],
|
|
35081
|
+
linked: [],
|
|
35082
|
+
alreadyLinked: [],
|
|
35083
|
+
skipped: []
|
|
35084
|
+
};
|
|
35085
|
+
const destinationByCategory = {
|
|
35086
|
+
skills: path15.join(folders.agentsDir, "skills"),
|
|
35087
|
+
agents: path15.join(folders.agentsDir, "agents")
|
|
35088
|
+
};
|
|
35089
|
+
await import_fs_extra11.default.ensureDir(folders.agentsDir);
|
|
35090
|
+
for (const category of ["skills", "agents"]) {
|
|
35091
|
+
await importCategoryEntries(category, candidates, destinationByCategory[category], result);
|
|
35092
|
+
}
|
|
35093
|
+
for (const candidate of candidates) {
|
|
35094
|
+
await linkContainer(candidate, destinationByCategory[candidate.category], result);
|
|
35095
|
+
}
|
|
35096
|
+
return result;
|
|
35097
|
+
}
|
|
35098
|
+
|
|
35099
|
+
// src/commands/agents-unify.ts
|
|
35100
|
+
function countByCategory(result, key, category) {
|
|
35101
|
+
return result[key].filter((entry) => entry.category === category).length;
|
|
35102
|
+
}
|
|
35103
|
+
function printCategorySummary(result, category) {
|
|
35104
|
+
const imported = countByCategory(result, "imported", category);
|
|
35105
|
+
const duplicates = countByCategory(result, "duplicates", category);
|
|
35106
|
+
const renamed = countByCategory(result, "renamed", category);
|
|
35107
|
+
const linked = countByCategory(result, "linked", category);
|
|
35108
|
+
const alreadyLinked = countByCategory(result, "alreadyLinked", category);
|
|
35109
|
+
console.log(source_default.gray(` ${category}: ${imported} imported, ${duplicates} duplicates skipped, ${renamed} renamed, ${linked} linked, ${alreadyLinked} already linked`));
|
|
35110
|
+
}
|
|
35111
|
+
async function agentsUnifyCommand(params = {}) {
|
|
35112
|
+
try {
|
|
35113
|
+
console.log(source_default.blue.bold(`
|
|
35114
|
+
AIBlueprint agents unify ${source_default.gray(`v${getVersion()}`)}
|
|
35115
|
+
`));
|
|
35116
|
+
console.log(source_default.gray("Centralizing reusable skills and agents into .agents"));
|
|
35117
|
+
const result = await unifyAgentsConfiguration(params);
|
|
35118
|
+
console.log(source_default.green(`
|
|
35119
|
+
Unify complete`));
|
|
35120
|
+
console.log(source_default.gray(` Shared folder: ${result.agentsDir}`));
|
|
35121
|
+
printCategorySummary(result, "skills");
|
|
35122
|
+
printCategorySummary(result, "agents");
|
|
35123
|
+
if (result.backupPath) {
|
|
35124
|
+
console.log(source_default.gray(` Source backups: ${result.backupPath}`));
|
|
35125
|
+
}
|
|
35126
|
+
if (result.skipped.length > 0) {
|
|
35127
|
+
console.log(source_default.yellow(`
|
|
35128
|
+
Skipped paths:`));
|
|
35129
|
+
for (const skipped of result.skipped) {
|
|
35130
|
+
console.log(source_default.yellow(` ${skipped.path}: ${skipped.reason}`));
|
|
35131
|
+
}
|
|
35132
|
+
}
|
|
35133
|
+
} catch (error) {
|
|
35134
|
+
console.error(source_default.red(`
|
|
35135
|
+
Agents unify failed:`), error);
|
|
35136
|
+
process.exit(1);
|
|
35137
|
+
}
|
|
35138
|
+
}
|
|
35139
|
+
|
|
34713
35140
|
// node_modules/@clack/core/dist/index.mjs
|
|
34714
35141
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
34715
35142
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -35426,12 +35853,12 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
35426
35853
|
};
|
|
35427
35854
|
|
|
35428
35855
|
// src/commands/pro.ts
|
|
35429
|
-
import
|
|
35856
|
+
import path18 from "path";
|
|
35430
35857
|
|
|
35431
35858
|
// src/lib/pro-installer.ts
|
|
35432
|
-
var
|
|
35433
|
-
import
|
|
35434
|
-
import
|
|
35859
|
+
var import_fs_extra12 = __toESM(require_lib4(), 1);
|
|
35860
|
+
import os14 from "os";
|
|
35861
|
+
import path16 from "path";
|
|
35435
35862
|
import { exec as exec3 } from "child_process";
|
|
35436
35863
|
import { promisify as promisify2 } from "util";
|
|
35437
35864
|
var execAsync2 = promisify2(exec3);
|
|
@@ -35439,9 +35866,9 @@ var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
|
|
|
35439
35866
|
var PREMIUM_BRANCH = "main";
|
|
35440
35867
|
var CONFIG_FOLDER_CANDIDATES2 = ["agents-config", "ai-coding", "claude-code-config", "ai-config"];
|
|
35441
35868
|
function routePath(relativePath) {
|
|
35442
|
-
const segments = relativePath.split(
|
|
35869
|
+
const segments = relativePath.split(path16.sep);
|
|
35443
35870
|
const first = segments[0];
|
|
35444
|
-
const rest = segments.slice(1).join(
|
|
35871
|
+
const rest = segments.slice(1).join(path16.sep);
|
|
35445
35872
|
if (first === "claude-config") {
|
|
35446
35873
|
return { kind: "claude", relativePath: rest };
|
|
35447
35874
|
}
|
|
@@ -35457,7 +35884,7 @@ function routePath(relativePath) {
|
|
|
35457
35884
|
return { kind: "claude", relativePath };
|
|
35458
35885
|
}
|
|
35459
35886
|
function getCacheRepoDir() {
|
|
35460
|
-
return
|
|
35887
|
+
return path16.join(os14.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
|
|
35461
35888
|
}
|
|
35462
35889
|
async function execGitWithAuth(command, token, repoUrl, cwd) {
|
|
35463
35890
|
const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
|
|
@@ -35471,21 +35898,21 @@ async function execGitWithAuth(command, token, repoUrl, cwd) {
|
|
|
35471
35898
|
async function cloneOrUpdateRepo(token) {
|
|
35472
35899
|
const cacheDir = getCacheRepoDir();
|
|
35473
35900
|
const repoUrl = `https://github.com/${PREMIUM_REPO}.git`;
|
|
35474
|
-
if (await
|
|
35901
|
+
if (await import_fs_extra12.default.pathExists(path16.join(cacheDir, ".git"))) {
|
|
35475
35902
|
try {
|
|
35476
35903
|
await execGitWithAuth("pull", token, repoUrl, cacheDir);
|
|
35477
35904
|
} catch (error) {
|
|
35478
|
-
await
|
|
35479
|
-
await
|
|
35905
|
+
await import_fs_extra12.default.remove(cacheDir);
|
|
35906
|
+
await import_fs_extra12.default.ensureDir(path16.dirname(cacheDir));
|
|
35480
35907
|
await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
|
|
35481
35908
|
}
|
|
35482
35909
|
} else {
|
|
35483
|
-
await
|
|
35910
|
+
await import_fs_extra12.default.ensureDir(path16.dirname(cacheDir));
|
|
35484
35911
|
await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
|
|
35485
35912
|
}
|
|
35486
35913
|
for (const candidate of CONFIG_FOLDER_CANDIDATES2) {
|
|
35487
|
-
const candidatePath =
|
|
35488
|
-
if (await
|
|
35914
|
+
const candidatePath = path16.join(cacheDir, candidate);
|
|
35915
|
+
if (await import_fs_extra12.default.pathExists(candidatePath)) {
|
|
35489
35916
|
return candidatePath;
|
|
35490
35917
|
}
|
|
35491
35918
|
}
|
|
@@ -35493,38 +35920,38 @@ async function cloneOrUpdateRepo(token) {
|
|
|
35493
35920
|
}
|
|
35494
35921
|
async function copyConfigFromCache(cacheConfigDir, dest, onProgress) {
|
|
35495
35922
|
const walk = async (dir, baseDir = dir) => {
|
|
35496
|
-
const entries = await
|
|
35923
|
+
const entries = await import_fs_extra12.default.readdir(dir, { withFileTypes: true });
|
|
35497
35924
|
for (const entry of entries) {
|
|
35498
35925
|
if (entry.name === ".DS_Store" || entry.name === "node_modules")
|
|
35499
35926
|
continue;
|
|
35500
|
-
const sourcePath =
|
|
35501
|
-
const relativePath =
|
|
35927
|
+
const sourcePath = path16.join(dir, entry.name);
|
|
35928
|
+
const relativePath = path16.relative(baseDir, sourcePath);
|
|
35502
35929
|
const route = routePath(relativePath);
|
|
35503
35930
|
if (route.kind === "skip")
|
|
35504
35931
|
continue;
|
|
35505
35932
|
if (route.kind === "agents-category") {
|
|
35506
|
-
if (relativePath.split(
|
|
35933
|
+
if (relativePath.split(path16.sep).length === 1) {
|
|
35507
35934
|
await copyAgentCategory(sourcePath, route.category, dest.agentsDir, dest.claudeDir, onProgress);
|
|
35508
35935
|
}
|
|
35509
35936
|
continue;
|
|
35510
35937
|
}
|
|
35511
35938
|
const targetBase = route.kind === "claude" ? dest.claudeDir : dest.codexDir;
|
|
35512
|
-
const targetPath =
|
|
35939
|
+
const targetPath = path16.join(targetBase, route.relativePath);
|
|
35513
35940
|
if (entry.isDirectory()) {
|
|
35514
|
-
await
|
|
35941
|
+
await import_fs_extra12.default.ensureDir(targetPath);
|
|
35515
35942
|
onProgress?.(relativePath, "directory");
|
|
35516
35943
|
await walk(sourcePath, baseDir);
|
|
35517
35944
|
} else if (route.kind === "codex" && route.relativePath === "config.toml") {
|
|
35518
35945
|
await mergeCodexConfigFile(sourcePath, dest.codexDir);
|
|
35519
35946
|
onProgress?.(relativePath, "file");
|
|
35520
35947
|
} else if (isTextFile(entry.name)) {
|
|
35521
|
-
const content = await
|
|
35948
|
+
const content = await import_fs_extra12.default.readFile(sourcePath, "utf-8");
|
|
35522
35949
|
const replaced = replaceClaudePathPlaceholder(content, dest.claudeDir);
|
|
35523
|
-
await
|
|
35524
|
-
await
|
|
35950
|
+
await import_fs_extra12.default.ensureDir(path16.dirname(targetPath));
|
|
35951
|
+
await import_fs_extra12.default.writeFile(targetPath, replaced, "utf-8");
|
|
35525
35952
|
onProgress?.(relativePath, "file");
|
|
35526
35953
|
} else {
|
|
35527
|
-
await
|
|
35954
|
+
await import_fs_extra12.default.copy(sourcePath, targetPath, { overwrite: true });
|
|
35528
35955
|
onProgress?.(relativePath, "file");
|
|
35529
35956
|
}
|
|
35530
35957
|
}
|
|
@@ -35532,21 +35959,21 @@ async function copyConfigFromCache(cacheConfigDir, dest, onProgress) {
|
|
|
35532
35959
|
await walk(cacheConfigDir);
|
|
35533
35960
|
}
|
|
35534
35961
|
async function copyAgentCategory(sourceCategoryDir, category, agentsDir, claudeDir, onProgress) {
|
|
35535
|
-
const agentsCategoryDir =
|
|
35536
|
-
await
|
|
35537
|
-
const entries = await
|
|
35962
|
+
const agentsCategoryDir = path16.join(agentsDir, category);
|
|
35963
|
+
await import_fs_extra12.default.ensureDir(agentsCategoryDir);
|
|
35964
|
+
const entries = await import_fs_extra12.default.readdir(sourceCategoryDir, { withFileTypes: true });
|
|
35538
35965
|
for (const entry of entries) {
|
|
35539
35966
|
if (entry.name === ".DS_Store")
|
|
35540
35967
|
continue;
|
|
35541
|
-
const src =
|
|
35542
|
-
const dst =
|
|
35543
|
-
const claudeTop =
|
|
35544
|
-
const claudeStat = await
|
|
35968
|
+
const src = path16.join(sourceCategoryDir, entry.name);
|
|
35969
|
+
const dst = path16.join(agentsCategoryDir, entry.name);
|
|
35970
|
+
const claudeTop = path16.join(claudeDir, category, entry.name);
|
|
35971
|
+
const claudeStat = await import_fs_extra12.default.lstat(claudeTop).catch(() => null);
|
|
35545
35972
|
if (claudeStat && !claudeStat.isSymbolicLink()) {
|
|
35546
35973
|
onProgress?.(`${category}/${entry.name} (skipped - real dir in claude)`, "file");
|
|
35547
35974
|
continue;
|
|
35548
35975
|
}
|
|
35549
|
-
await
|
|
35976
|
+
await import_fs_extra12.default.copy(src, dst, { overwrite: true });
|
|
35550
35977
|
await applyPathPlaceholders(dst, claudeDir);
|
|
35551
35978
|
onProgress?.(`${category}/${entry.name}`, entry.isDirectory() ? "directory" : "file");
|
|
35552
35979
|
}
|
|
@@ -35565,8 +35992,8 @@ async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath,
|
|
|
35565
35992
|
return false;
|
|
35566
35993
|
}
|
|
35567
35994
|
const content = await response.arrayBuffer();
|
|
35568
|
-
await
|
|
35569
|
-
await
|
|
35995
|
+
await import_fs_extra12.default.ensureDir(path16.dirname(targetPath));
|
|
35996
|
+
await import_fs_extra12.default.writeFile(targetPath, Buffer.from(content));
|
|
35570
35997
|
return true;
|
|
35571
35998
|
} catch (error) {
|
|
35572
35999
|
console.error(`Error downloading ${relativePath}:`, error);
|
|
@@ -35591,10 +36018,10 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
|
|
|
35591
36018
|
console.error(`Unexpected response for directory ${dirPath}`);
|
|
35592
36019
|
return false;
|
|
35593
36020
|
}
|
|
35594
|
-
await
|
|
36021
|
+
await import_fs_extra12.default.ensureDir(targetDir);
|
|
35595
36022
|
for (const file of files) {
|
|
35596
36023
|
const relativePath = dirPath ? `${dirPath}/${file.name}` : file.name;
|
|
35597
|
-
const targetPath =
|
|
36024
|
+
const targetPath = path16.join(targetDir, file.name);
|
|
35598
36025
|
const displayPath = relativePath.replace(/^(agents-config|ai-coding|claude-code-config|ai-config)\//, "");
|
|
35599
36026
|
if (file.type === "file") {
|
|
35600
36027
|
onProgress?.(displayPath, "file");
|
|
@@ -35617,8 +36044,8 @@ async function installProConfigs(options) {
|
|
|
35617
36044
|
codexFolder,
|
|
35618
36045
|
agentsFolder
|
|
35619
36046
|
});
|
|
35620
|
-
await
|
|
35621
|
-
await
|
|
36047
|
+
await import_fs_extra12.default.ensureDir(claudeDir);
|
|
36048
|
+
await import_fs_extra12.default.ensureDir(agentsDir);
|
|
35622
36049
|
const dest = { claudeDir, codexDir, agentsDir };
|
|
35623
36050
|
try {
|
|
35624
36051
|
const cacheConfigDir = await cloneOrUpdateRepo(githubToken);
|
|
@@ -35628,7 +36055,7 @@ async function installProConfigs(options) {
|
|
|
35628
36055
|
} catch (error) {
|
|
35629
36056
|
console.warn("Git caching failed, falling back to API download");
|
|
35630
36057
|
}
|
|
35631
|
-
const tempDir =
|
|
36058
|
+
const tempDir = path16.join(os14.tmpdir(), `aiblueprint-premium-${Date.now()}`);
|
|
35632
36059
|
try {
|
|
35633
36060
|
let success = false;
|
|
35634
36061
|
for (const candidate of CONFIG_FOLDER_CANDIDATES2) {
|
|
@@ -35642,8 +36069,8 @@ async function installProConfigs(options) {
|
|
|
35642
36069
|
await copyConfigFromCache(tempDir, dest, onProgress);
|
|
35643
36070
|
await replacePathPlaceholdersInDir(claudeDir, claudeDir);
|
|
35644
36071
|
for (const category of AGENT_CATEGORIES) {
|
|
35645
|
-
const agentsCategoryDir =
|
|
35646
|
-
if (await
|
|
36072
|
+
const agentsCategoryDir = path16.join(agentsDir, category);
|
|
36073
|
+
if (await import_fs_extra12.default.pathExists(agentsCategoryDir)) {
|
|
35647
36074
|
await replacePathPlaceholdersInDir(agentsCategoryDir, claudeDir);
|
|
35648
36075
|
}
|
|
35649
36076
|
}
|
|
@@ -35652,7 +36079,7 @@ async function installProConfigs(options) {
|
|
|
35652
36079
|
throw new Error(`Failed to install premium configs: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
35653
36080
|
} finally {
|
|
35654
36081
|
try {
|
|
35655
|
-
await
|
|
36082
|
+
await import_fs_extra12.default.remove(tempDir);
|
|
35656
36083
|
} catch {}
|
|
35657
36084
|
}
|
|
35658
36085
|
}
|
|
@@ -35663,27 +36090,27 @@ async function syncAllAgentSymlinks(agentsDir, claudeDir) {
|
|
|
35663
36090
|
}
|
|
35664
36091
|
|
|
35665
36092
|
// src/lib/token-storage.ts
|
|
35666
|
-
var
|
|
35667
|
-
import
|
|
35668
|
-
import
|
|
36093
|
+
var import_fs_extra13 = __toESM(require_lib4(), 1);
|
|
36094
|
+
import os15 from "os";
|
|
36095
|
+
import path17 from "path";
|
|
35669
36096
|
function getConfigDir() {
|
|
35670
|
-
const platform =
|
|
36097
|
+
const platform = os15.platform();
|
|
35671
36098
|
if (platform === "win32") {
|
|
35672
|
-
const appData = process.env.APPDATA ||
|
|
35673
|
-
return
|
|
36099
|
+
const appData = process.env.APPDATA || path17.join(os15.homedir(), "AppData", "Roaming");
|
|
36100
|
+
return path17.join(appData, "aiblueprint");
|
|
35674
36101
|
} else {
|
|
35675
|
-
const configHome = process.env.XDG_CONFIG_HOME ||
|
|
35676
|
-
return
|
|
36102
|
+
const configHome = process.env.XDG_CONFIG_HOME || path17.join(os15.homedir(), ".config");
|
|
36103
|
+
return path17.join(configHome, "aiblueprint");
|
|
35677
36104
|
}
|
|
35678
36105
|
}
|
|
35679
36106
|
function getTokenFilePath2() {
|
|
35680
|
-
return
|
|
36107
|
+
return path17.join(getConfigDir(), "token.txt");
|
|
35681
36108
|
}
|
|
35682
36109
|
async function saveToken(githubToken) {
|
|
35683
36110
|
const tokenFile = getTokenFilePath2();
|
|
35684
|
-
const configDir =
|
|
36111
|
+
const configDir = path17.dirname(tokenFile);
|
|
35685
36112
|
try {
|
|
35686
|
-
await
|
|
36113
|
+
await import_fs_extra13.default.ensureDir(configDir);
|
|
35687
36114
|
} catch (error) {
|
|
35688
36115
|
if (error.code === "EACCES") {
|
|
35689
36116
|
throw new Error(`Permission denied creating config directory: ${configDir}
|
|
@@ -35691,15 +36118,15 @@ async function saveToken(githubToken) {
|
|
|
35691
36118
|
}
|
|
35692
36119
|
throw error;
|
|
35693
36120
|
}
|
|
35694
|
-
await
|
|
36121
|
+
await import_fs_extra13.default.writeFile(tokenFile, githubToken, { mode: 384 });
|
|
35695
36122
|
}
|
|
35696
36123
|
async function getToken() {
|
|
35697
36124
|
const tokenFile = getTokenFilePath2();
|
|
35698
|
-
if (!await
|
|
36125
|
+
if (!await import_fs_extra13.default.pathExists(tokenFile)) {
|
|
35699
36126
|
return null;
|
|
35700
36127
|
}
|
|
35701
36128
|
try {
|
|
35702
|
-
const token = await
|
|
36129
|
+
const token = await import_fs_extra13.default.readFile(tokenFile, "utf-8");
|
|
35703
36130
|
return token.trim();
|
|
35704
36131
|
} catch (error) {
|
|
35705
36132
|
return null;
|
|
@@ -35708,12 +36135,12 @@ async function getToken() {
|
|
|
35708
36135
|
function getTokenInfo() {
|
|
35709
36136
|
return {
|
|
35710
36137
|
path: getTokenFilePath2(),
|
|
35711
|
-
platform:
|
|
36138
|
+
platform: os15.platform()
|
|
35712
36139
|
};
|
|
35713
36140
|
}
|
|
35714
36141
|
|
|
35715
36142
|
// src/commands/pro.ts
|
|
35716
|
-
var
|
|
36143
|
+
var import_fs_extra14 = __toESM(require_lib4(), 1);
|
|
35717
36144
|
var API_URL = "https://codeline.app/api/products";
|
|
35718
36145
|
var PRODUCT_IDS = ["prd_XJVgxVPbGG", "prd_NKabAkdOkw"];
|
|
35719
36146
|
async function countInstalledItems(claudeDir) {
|
|
@@ -35722,20 +36149,20 @@ async function countInstalledItems(claudeDir) {
|
|
|
35722
36149
|
skills: 0
|
|
35723
36150
|
};
|
|
35724
36151
|
try {
|
|
35725
|
-
const agentsDir =
|
|
35726
|
-
if (await
|
|
35727
|
-
const files = await
|
|
36152
|
+
const agentsDir = path18.join(claudeDir, "agents");
|
|
36153
|
+
if (await import_fs_extra14.default.pathExists(agentsDir)) {
|
|
36154
|
+
const files = await import_fs_extra14.default.readdir(agentsDir);
|
|
35728
36155
|
counts.agents = files.filter((f) => f.endsWith(".md")).length;
|
|
35729
36156
|
}
|
|
35730
36157
|
} catch (error) {
|
|
35731
36158
|
console.error("Failed to count agents:", error instanceof Error ? error.message : error);
|
|
35732
36159
|
}
|
|
35733
36160
|
try {
|
|
35734
|
-
const skillsDir =
|
|
35735
|
-
if (await
|
|
35736
|
-
const items = await
|
|
36161
|
+
const skillsDir = path18.join(claudeDir, "skills");
|
|
36162
|
+
if (await import_fs_extra14.default.pathExists(skillsDir)) {
|
|
36163
|
+
const items = await import_fs_extra14.default.readdir(skillsDir);
|
|
35737
36164
|
const dirs = await Promise.all(items.map(async (item) => {
|
|
35738
|
-
const stat = await
|
|
36165
|
+
const stat = await import_fs_extra14.default.stat(path18.join(skillsDir, item));
|
|
35739
36166
|
return stat.isDirectory();
|
|
35740
36167
|
}));
|
|
35741
36168
|
counts.skills = dirs.filter(Boolean).length;
|
|
@@ -35943,9 +36370,9 @@ async function proUpdateCommand(options = {}) {
|
|
|
35943
36370
|
}
|
|
35944
36371
|
|
|
35945
36372
|
// src/lib/sync-utils.ts
|
|
35946
|
-
var
|
|
35947
|
-
import
|
|
35948
|
-
import
|
|
36373
|
+
var import_fs_extra15 = __toESM(require_lib4(), 1);
|
|
36374
|
+
import path19 from "path";
|
|
36375
|
+
import crypto2 from "crypto";
|
|
35949
36376
|
var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
|
|
35950
36377
|
var PREMIUM_BRANCH2 = "main";
|
|
35951
36378
|
var CONFIG_FOLDER_CANDIDATES3 = ["agents-config", "ai-coding", "claude-code-config", "ai-config"];
|
|
@@ -35953,7 +36380,7 @@ function computeFileSha(content) {
|
|
|
35953
36380
|
const size = content.length;
|
|
35954
36381
|
const header = `blob ${size}\x00`;
|
|
35955
36382
|
const fullContent = Buffer.concat([Buffer.from(header), content]);
|
|
35956
|
-
return
|
|
36383
|
+
return crypto2.createHash("sha1").update(fullContent).digest("hex");
|
|
35957
36384
|
}
|
|
35958
36385
|
var resolvedConfigFolder = null;
|
|
35959
36386
|
async function resolveRemoteConfigFolder(githubToken) {
|
|
@@ -36015,7 +36442,7 @@ async function listRemoteFilesRecursive(dirPath, githubToken, basePath = "") {
|
|
|
36015
36442
|
}
|
|
36016
36443
|
async function computeLocalFileSha(filePath) {
|
|
36017
36444
|
try {
|
|
36018
|
-
const content = await
|
|
36445
|
+
const content = await import_fs_extra15.default.readFile(filePath);
|
|
36019
36446
|
return computeFileSha(content);
|
|
36020
36447
|
} catch {
|
|
36021
36448
|
return null;
|
|
@@ -36023,15 +36450,15 @@ async function computeLocalFileSha(filePath) {
|
|
|
36023
36450
|
}
|
|
36024
36451
|
async function listLocalFiles(dir) {
|
|
36025
36452
|
const files = [];
|
|
36026
|
-
if (!await
|
|
36453
|
+
if (!await import_fs_extra15.default.pathExists(dir)) {
|
|
36027
36454
|
return files;
|
|
36028
36455
|
}
|
|
36029
|
-
const items = await
|
|
36456
|
+
const items = await import_fs_extra15.default.readdir(dir);
|
|
36030
36457
|
for (const item of items) {
|
|
36031
36458
|
if (item === "node_modules" || item === ".DS_Store")
|
|
36032
36459
|
continue;
|
|
36033
|
-
const fullPath =
|
|
36034
|
-
const stat = await
|
|
36460
|
+
const fullPath = path19.join(dir, item);
|
|
36461
|
+
const stat = await import_fs_extra15.default.stat(fullPath).catch(() => null);
|
|
36035
36462
|
if (!stat)
|
|
36036
36463
|
continue;
|
|
36037
36464
|
if (stat.isDirectory()) {
|
|
@@ -36046,13 +36473,13 @@ async function listLocalFiles(dir) {
|
|
|
36046
36473
|
}
|
|
36047
36474
|
async function listLocalFilesRecursive(dir, basePath) {
|
|
36048
36475
|
const files = [];
|
|
36049
|
-
const items = await
|
|
36476
|
+
const items = await import_fs_extra15.default.readdir(dir).catch(() => []);
|
|
36050
36477
|
for (const item of items) {
|
|
36051
36478
|
if (item === "node_modules" || item === ".DS_Store")
|
|
36052
36479
|
continue;
|
|
36053
|
-
const fullPath =
|
|
36480
|
+
const fullPath = path19.join(dir, item);
|
|
36054
36481
|
const relativePath = `${basePath}/${item}`;
|
|
36055
|
-
const stat = await
|
|
36482
|
+
const stat = await import_fs_extra15.default.stat(fullPath).catch(() => null);
|
|
36056
36483
|
if (!stat)
|
|
36057
36484
|
continue;
|
|
36058
36485
|
if (stat.isDirectory()) {
|
|
@@ -36066,14 +36493,14 @@ async function listLocalFilesRecursive(dir, basePath) {
|
|
|
36066
36493
|
return files;
|
|
36067
36494
|
}
|
|
36068
36495
|
async function listClaudeRealTopLevel(claudeCategoryDir) {
|
|
36069
|
-
if (!await
|
|
36496
|
+
if (!await import_fs_extra15.default.pathExists(claudeCategoryDir))
|
|
36070
36497
|
return [];
|
|
36071
|
-
const entries = await
|
|
36498
|
+
const entries = await import_fs_extra15.default.readdir(claudeCategoryDir).catch(() => []);
|
|
36072
36499
|
const real = [];
|
|
36073
36500
|
for (const name of entries) {
|
|
36074
36501
|
if (name === "node_modules" || name === ".DS_Store")
|
|
36075
36502
|
continue;
|
|
36076
|
-
const stat = await
|
|
36503
|
+
const stat = await import_fs_extra15.default.lstat(path19.join(claudeCategoryDir, name)).catch(() => null);
|
|
36077
36504
|
if (!stat)
|
|
36078
36505
|
continue;
|
|
36079
36506
|
if (stat.isDirectory())
|
|
@@ -36090,7 +36517,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
|
|
|
36090
36517
|
const items = [];
|
|
36091
36518
|
const useAgents = isAgentCategory(category);
|
|
36092
36519
|
const localBase = useAgents ? agentsDir : claudeDir;
|
|
36093
|
-
const localDir =
|
|
36520
|
+
const localDir = path19.join(localBase, category);
|
|
36094
36521
|
const remoteCategoryPath = getRemoteCategoryPath(category);
|
|
36095
36522
|
const remoteFiles = await listRemoteFilesRecursive(remoteCategoryPath, githubToken);
|
|
36096
36523
|
const localFiles = await listLocalFiles(localDir);
|
|
@@ -36104,7 +36531,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
|
|
|
36104
36531
|
}
|
|
36105
36532
|
const localSet = new Set(localFiles);
|
|
36106
36533
|
for (const [remotePath, { sha, isFolder }] of remoteSet) {
|
|
36107
|
-
const localPath =
|
|
36534
|
+
const localPath = path19.join(localDir, remotePath);
|
|
36108
36535
|
if (isFolder) {
|
|
36109
36536
|
continue;
|
|
36110
36537
|
}
|
|
@@ -36139,7 +36566,7 @@ async function analyzeCategory(category, claudeDir, agentsDir, githubToken) {
|
|
|
36139
36566
|
for (const localPath of localSet) {
|
|
36140
36567
|
agentsTopLevels.add(localPath.split("/")[0]);
|
|
36141
36568
|
}
|
|
36142
|
-
const claudeCategoryDir =
|
|
36569
|
+
const claudeCategoryDir = path19.join(claudeDir, category);
|
|
36143
36570
|
const claudeRealEntries = await listClaudeRealTopLevel(claudeCategoryDir);
|
|
36144
36571
|
for (const top of claudeRealEntries) {
|
|
36145
36572
|
if (!remoteTopLevels.has(top))
|
|
@@ -36198,13 +36625,13 @@ async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken,
|
|
|
36198
36625
|
return false;
|
|
36199
36626
|
}
|
|
36200
36627
|
const content = await response.arrayBuffer();
|
|
36201
|
-
await
|
|
36628
|
+
await import_fs_extra15.default.ensureDir(path19.dirname(targetPath));
|
|
36202
36629
|
if (isTextFile(relativePath)) {
|
|
36203
36630
|
const textContent = Buffer.from(content).toString("utf-8");
|
|
36204
36631
|
const transformedContent = transformFileContent(textContent, claudeDir);
|
|
36205
|
-
await
|
|
36632
|
+
await import_fs_extra15.default.writeFile(targetPath, transformedContent, "utf-8");
|
|
36206
36633
|
} else {
|
|
36207
|
-
await
|
|
36634
|
+
await import_fs_extra15.default.writeFile(targetPath, Buffer.from(content));
|
|
36208
36635
|
}
|
|
36209
36636
|
return true;
|
|
36210
36637
|
} catch {
|
|
@@ -36220,27 +36647,27 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
|
|
|
36220
36647
|
for (const item of items) {
|
|
36221
36648
|
const useAgents = isAgentCategory(item.category);
|
|
36222
36649
|
const baseDir = useAgents ? agentsDir : claudeDir;
|
|
36223
|
-
const targetPath =
|
|
36650
|
+
const targetPath = path19.join(baseDir, item.relativePath);
|
|
36224
36651
|
if (item.status === "migration" && useAgents) {
|
|
36225
36652
|
const topName = item.name.split("/")[0];
|
|
36226
|
-
const agentsTop =
|
|
36227
|
-
const claudeTop =
|
|
36653
|
+
const agentsTop = path19.join(agentsDir, item.category, topName);
|
|
36654
|
+
const claudeTop = path19.join(claudeDir, item.category, topName);
|
|
36228
36655
|
try {
|
|
36229
|
-
const claudeStat = await
|
|
36656
|
+
const claudeStat = await import_fs_extra15.default.lstat(claudeTop).catch(() => null);
|
|
36230
36657
|
if (!claudeStat || claudeStat.isSymbolicLink()) {
|
|
36231
36658
|
onProgress?.(item.relativePath, "skipping (no real dir to migrate)");
|
|
36232
36659
|
failed++;
|
|
36233
36660
|
continue;
|
|
36234
36661
|
}
|
|
36235
|
-
const agentsExists = await
|
|
36662
|
+
const agentsExists = await import_fs_extra15.default.pathExists(agentsTop);
|
|
36236
36663
|
if (agentsExists) {
|
|
36237
36664
|
onProgress?.(item.relativePath, "skipping (already in .agents)");
|
|
36238
36665
|
failed++;
|
|
36239
36666
|
continue;
|
|
36240
36667
|
}
|
|
36241
36668
|
onProgress?.(item.relativePath, "moving to .agents");
|
|
36242
|
-
await
|
|
36243
|
-
await
|
|
36669
|
+
await import_fs_extra15.default.ensureDir(path19.dirname(agentsTop));
|
|
36670
|
+
await import_fs_extra15.default.move(claudeTop, agentsTop);
|
|
36244
36671
|
migrated++;
|
|
36245
36672
|
touchedAgentCategories.add(item.category);
|
|
36246
36673
|
} catch {
|
|
@@ -36250,8 +36677,8 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
|
|
|
36250
36677
|
}
|
|
36251
36678
|
if (useAgents) {
|
|
36252
36679
|
const topName = item.name.split("/")[0];
|
|
36253
|
-
const claudeTop =
|
|
36254
|
-
const claudeTopStat = await
|
|
36680
|
+
const claudeTop = path19.join(claudeDir, item.category, topName);
|
|
36681
|
+
const claudeTopStat = await import_fs_extra15.default.lstat(claudeTop).catch(() => null);
|
|
36255
36682
|
if (claudeTopStat && !claudeTopStat.isSymbolicLink()) {
|
|
36256
36683
|
onProgress?.(item.relativePath, "skipping (real dir in .claude)");
|
|
36257
36684
|
failed++;
|
|
@@ -36261,7 +36688,7 @@ async function syncSelectedItems(claudeDir, items, githubToken, agentsDir, onPro
|
|
|
36261
36688
|
if (item.status === "deleted") {
|
|
36262
36689
|
onProgress?.(item.relativePath, "deleting");
|
|
36263
36690
|
try {
|
|
36264
|
-
await
|
|
36691
|
+
await import_fs_extra15.default.remove(targetPath);
|
|
36265
36692
|
deleted++;
|
|
36266
36693
|
if (useAgents)
|
|
36267
36694
|
touchedAgentCategories.add(item.category);
|
|
@@ -36599,20 +37026,20 @@ async function proSyncCommand(options = {}) {
|
|
|
36599
37026
|
}
|
|
36600
37027
|
|
|
36601
37028
|
// src/lib/backup-utils.ts
|
|
36602
|
-
var
|
|
36603
|
-
import
|
|
36604
|
-
import
|
|
36605
|
-
var BACKUP_BASE_DIR =
|
|
37029
|
+
var import_fs_extra16 = __toESM(require_lib4(), 1);
|
|
37030
|
+
import path20 from "path";
|
|
37031
|
+
import os16 from "os";
|
|
37032
|
+
var BACKUP_BASE_DIR = path20.join(os16.homedir(), ".config", "aiblueprint", "backup");
|
|
36606
37033
|
function formatDate(date) {
|
|
36607
37034
|
const pad = (n) => n.toString().padStart(2, "0");
|
|
36608
37035
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
|
|
36609
37036
|
}
|
|
36610
37037
|
async function listBackups() {
|
|
36611
|
-
const exists = await
|
|
37038
|
+
const exists = await import_fs_extra16.default.pathExists(BACKUP_BASE_DIR);
|
|
36612
37039
|
if (!exists) {
|
|
36613
37040
|
return [];
|
|
36614
37041
|
}
|
|
36615
|
-
const entries = await
|
|
37042
|
+
const entries = await import_fs_extra16.default.readdir(BACKUP_BASE_DIR, { withFileTypes: true });
|
|
36616
37043
|
const backups = [];
|
|
36617
37044
|
for (const entry of entries) {
|
|
36618
37045
|
if (!entry.isDirectory())
|
|
@@ -36624,7 +37051,7 @@ async function listBackups() {
|
|
|
36624
37051
|
const date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second));
|
|
36625
37052
|
backups.push({
|
|
36626
37053
|
name: entry.name,
|
|
36627
|
-
path:
|
|
37054
|
+
path: path20.join(BACKUP_BASE_DIR, entry.name),
|
|
36628
37055
|
date
|
|
36629
37056
|
});
|
|
36630
37057
|
}
|
|
@@ -36633,12 +37060,12 @@ async function listBackups() {
|
|
|
36633
37060
|
var AGENTS_BACKUP_SUBDIR = ".agents";
|
|
36634
37061
|
var CLAUDE_ITEMS = ["commands", "agents", "skills", "scripts", "settings.json"];
|
|
36635
37062
|
async function copyForBackup(sourcePath, destPath) {
|
|
36636
|
-
await
|
|
37063
|
+
await import_fs_extra16.default.copy(sourcePath, destPath, {
|
|
36637
37064
|
overwrite: true,
|
|
36638
37065
|
dereference: false,
|
|
36639
37066
|
filter: async (src) => {
|
|
36640
37067
|
try {
|
|
36641
|
-
const stat = await
|
|
37068
|
+
const stat = await import_fs_extra16.default.lstat(src);
|
|
36642
37069
|
return !stat.isSymbolicLink();
|
|
36643
37070
|
} catch {
|
|
36644
37071
|
return true;
|
|
@@ -36647,28 +37074,28 @@ async function copyForBackup(sourcePath, destPath) {
|
|
|
36647
37074
|
});
|
|
36648
37075
|
}
|
|
36649
37076
|
async function hasMeaningfulContent(dir) {
|
|
36650
|
-
if (!await
|
|
37077
|
+
if (!await import_fs_extra16.default.pathExists(dir))
|
|
36651
37078
|
return false;
|
|
36652
|
-
const files = await
|
|
37079
|
+
const files = await import_fs_extra16.default.readdir(dir);
|
|
36653
37080
|
return files.some((f) => f !== ".DS_Store");
|
|
36654
37081
|
}
|
|
36655
37082
|
async function loadBackup(backupPath, claudeDir, agentsDir) {
|
|
36656
|
-
const exists = await
|
|
37083
|
+
const exists = await import_fs_extra16.default.pathExists(backupPath);
|
|
36657
37084
|
if (!exists) {
|
|
36658
37085
|
throw new Error(`Backup not found: ${backupPath}`);
|
|
36659
37086
|
}
|
|
36660
|
-
await
|
|
37087
|
+
await import_fs_extra16.default.ensureDir(claudeDir);
|
|
36661
37088
|
for (const item of CLAUDE_ITEMS) {
|
|
36662
|
-
const sourcePath =
|
|
36663
|
-
const destPath =
|
|
36664
|
-
if (await
|
|
37089
|
+
const sourcePath = path20.join(backupPath, item);
|
|
37090
|
+
const destPath = path20.join(claudeDir, item);
|
|
37091
|
+
if (await import_fs_extra16.default.pathExists(sourcePath)) {
|
|
36665
37092
|
await copyForBackup(sourcePath, destPath);
|
|
36666
37093
|
}
|
|
36667
37094
|
}
|
|
36668
37095
|
if (agentsDir) {
|
|
36669
|
-
const agentsBackupPath =
|
|
36670
|
-
if (await
|
|
36671
|
-
await
|
|
37096
|
+
const agentsBackupPath = path20.join(backupPath, AGENTS_BACKUP_SUBDIR);
|
|
37097
|
+
if (await import_fs_extra16.default.pathExists(agentsBackupPath)) {
|
|
37098
|
+
await import_fs_extra16.default.ensureDir(agentsDir);
|
|
36672
37099
|
await copyForBackup(agentsBackupPath, agentsDir);
|
|
36673
37100
|
}
|
|
36674
37101
|
}
|
|
@@ -36679,20 +37106,20 @@ async function createBackup(claudeDir, agentsDir) {
|
|
|
36679
37106
|
if (!claudeHasContent && !agentsHasContent) {
|
|
36680
37107
|
return null;
|
|
36681
37108
|
}
|
|
36682
|
-
const
|
|
36683
|
-
const backupPath =
|
|
36684
|
-
await
|
|
37109
|
+
const timestamp3 = formatDate(new Date);
|
|
37110
|
+
const backupPath = path20.join(BACKUP_BASE_DIR, timestamp3);
|
|
37111
|
+
await import_fs_extra16.default.ensureDir(backupPath);
|
|
36685
37112
|
if (claudeHasContent) {
|
|
36686
37113
|
for (const item of CLAUDE_ITEMS) {
|
|
36687
|
-
const sourcePath =
|
|
36688
|
-
const destPath =
|
|
36689
|
-
if (await
|
|
37114
|
+
const sourcePath = path20.join(claudeDir, item);
|
|
37115
|
+
const destPath = path20.join(backupPath, item);
|
|
37116
|
+
if (await import_fs_extra16.default.pathExists(sourcePath)) {
|
|
36690
37117
|
await copyForBackup(sourcePath, destPath);
|
|
36691
37118
|
}
|
|
36692
37119
|
}
|
|
36693
37120
|
}
|
|
36694
37121
|
if (agentsHasContent && agentsDir) {
|
|
36695
|
-
const destPath =
|
|
37122
|
+
const destPath = path20.join(backupPath, AGENTS_BACKUP_SUBDIR);
|
|
36696
37123
|
await copyForBackup(agentsDir, destPath);
|
|
36697
37124
|
}
|
|
36698
37125
|
return backupPath;
|
|
@@ -36875,19 +37302,19 @@ async function configsBackupsCreateCommand(reason, options = {}) {
|
|
|
36875
37302
|
}
|
|
36876
37303
|
|
|
36877
37304
|
// src/commands/openclaw-pro.ts
|
|
36878
|
-
import
|
|
36879
|
-
import
|
|
37305
|
+
import os19 from "os";
|
|
37306
|
+
import path23 from "path";
|
|
36880
37307
|
|
|
36881
37308
|
// src/lib/openclaw-installer.ts
|
|
36882
|
-
var
|
|
36883
|
-
import
|
|
36884
|
-
import
|
|
37309
|
+
var import_fs_extra17 = __toESM(require_lib4(), 1);
|
|
37310
|
+
import os17 from "os";
|
|
37311
|
+
import path21 from "path";
|
|
36885
37312
|
import { exec as exec4 } from "child_process";
|
|
36886
37313
|
import { promisify as promisify3 } from "util";
|
|
36887
37314
|
var execAsync3 = promisify3(exec4);
|
|
36888
37315
|
var OPENCLAW_PRO_REPO = "Melvynx/openclawpro";
|
|
36889
37316
|
function getCacheRepoDir2() {
|
|
36890
|
-
return
|
|
37317
|
+
return path21.join(os17.homedir(), ".config", "openclaw", "pro-repos", "openclawpro");
|
|
36891
37318
|
}
|
|
36892
37319
|
async function execGitWithAuth2(command, token, repoUrl, cwd) {
|
|
36893
37320
|
const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
|
|
@@ -36901,33 +37328,33 @@ async function execGitWithAuth2(command, token, repoUrl, cwd) {
|
|
|
36901
37328
|
async function cloneOrUpdateRepo2(token) {
|
|
36902
37329
|
const cacheDir = getCacheRepoDir2();
|
|
36903
37330
|
const repoUrl = `https://github.com/${OPENCLAW_PRO_REPO}.git`;
|
|
36904
|
-
if (await
|
|
37331
|
+
if (await import_fs_extra17.default.pathExists(path21.join(cacheDir, ".git"))) {
|
|
36905
37332
|
try {
|
|
36906
37333
|
await execGitWithAuth2("pull", token, repoUrl, cacheDir);
|
|
36907
37334
|
} catch (error) {
|
|
36908
|
-
await
|
|
36909
|
-
await
|
|
37335
|
+
await import_fs_extra17.default.remove(cacheDir);
|
|
37336
|
+
await import_fs_extra17.default.ensureDir(path21.dirname(cacheDir));
|
|
36910
37337
|
await execGitWithAuth2(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
|
|
36911
37338
|
}
|
|
36912
37339
|
} else {
|
|
36913
|
-
await
|
|
37340
|
+
await import_fs_extra17.default.ensureDir(path21.dirname(cacheDir));
|
|
36914
37341
|
await execGitWithAuth2(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
|
|
36915
37342
|
}
|
|
36916
|
-
return
|
|
37343
|
+
return path21.join(cacheDir, "openclaw-config");
|
|
36917
37344
|
}
|
|
36918
37345
|
async function copyConfigFromCache2(cacheConfigDir, targetDir, onProgress) {
|
|
36919
37346
|
const walk = async (dir, baseDir = dir) => {
|
|
36920
|
-
const entries = await
|
|
37347
|
+
const entries = await import_fs_extra17.default.readdir(dir, { withFileTypes: true });
|
|
36921
37348
|
for (const entry of entries) {
|
|
36922
|
-
const sourcePath =
|
|
36923
|
-
const relativePath =
|
|
36924
|
-
const targetPath =
|
|
37349
|
+
const sourcePath = path21.join(dir, entry.name);
|
|
37350
|
+
const relativePath = path21.relative(baseDir, sourcePath);
|
|
37351
|
+
const targetPath = path21.join(targetDir, relativePath);
|
|
36925
37352
|
if (entry.isDirectory()) {
|
|
36926
|
-
await
|
|
37353
|
+
await import_fs_extra17.default.ensureDir(targetPath);
|
|
36927
37354
|
onProgress?.(relativePath, "directory");
|
|
36928
37355
|
await walk(sourcePath, baseDir);
|
|
36929
37356
|
} else {
|
|
36930
|
-
await
|
|
37357
|
+
await import_fs_extra17.default.copy(sourcePath, targetPath, { overwrite: true });
|
|
36931
37358
|
onProgress?.(relativePath, "file");
|
|
36932
37359
|
}
|
|
36933
37360
|
}
|
|
@@ -36936,7 +37363,7 @@ async function copyConfigFromCache2(cacheConfigDir, targetDir, onProgress) {
|
|
|
36936
37363
|
}
|
|
36937
37364
|
async function installOpenclawProConfigs(options) {
|
|
36938
37365
|
const { githubToken, openclawFolder, onProgress } = options;
|
|
36939
|
-
const targetFolder = openclawFolder ||
|
|
37366
|
+
const targetFolder = openclawFolder || path21.join(os17.homedir(), ".openclaw");
|
|
36940
37367
|
try {
|
|
36941
37368
|
const cacheConfigDir = await cloneOrUpdateRepo2(githubToken);
|
|
36942
37369
|
await copyConfigFromCache2(cacheConfigDir, targetFolder, onProgress);
|
|
@@ -36947,28 +37374,28 @@ async function installOpenclawProConfigs(options) {
|
|
|
36947
37374
|
}
|
|
36948
37375
|
|
|
36949
37376
|
// src/lib/openclaw-token-storage.ts
|
|
36950
|
-
var
|
|
36951
|
-
import
|
|
36952
|
-
import
|
|
37377
|
+
var import_fs_extra18 = __toESM(require_lib4(), 1);
|
|
37378
|
+
import os18 from "os";
|
|
37379
|
+
import path22 from "path";
|
|
36953
37380
|
function getConfigDir2() {
|
|
36954
|
-
const platform =
|
|
37381
|
+
const platform = os18.platform();
|
|
36955
37382
|
if (platform === "win32") {
|
|
36956
|
-
return
|
|
37383
|
+
return path22.join(process.env.APPDATA || os18.homedir(), "openclaw");
|
|
36957
37384
|
}
|
|
36958
|
-
return
|
|
37385
|
+
return path22.join(os18.homedir(), ".config", "openclaw");
|
|
36959
37386
|
}
|
|
36960
37387
|
function getTokenPath() {
|
|
36961
|
-
return
|
|
37388
|
+
return path22.join(getConfigDir2(), "token.txt");
|
|
36962
37389
|
}
|
|
36963
37390
|
async function saveOpenclawToken(githubToken) {
|
|
36964
37391
|
const configDir = getConfigDir2();
|
|
36965
|
-
await
|
|
36966
|
-
await
|
|
37392
|
+
await import_fs_extra18.default.ensureDir(configDir);
|
|
37393
|
+
await import_fs_extra18.default.writeFile(getTokenPath(), githubToken, { mode: 384 });
|
|
36967
37394
|
}
|
|
36968
37395
|
async function getOpenclawToken() {
|
|
36969
37396
|
const tokenPath = getTokenPath();
|
|
36970
|
-
if (await
|
|
36971
|
-
const token = await
|
|
37397
|
+
if (await import_fs_extra18.default.pathExists(tokenPath)) {
|
|
37398
|
+
const token = await import_fs_extra18.default.readFile(tokenPath, "utf8");
|
|
36972
37399
|
return token.trim();
|
|
36973
37400
|
}
|
|
36974
37401
|
return null;
|
|
@@ -36976,12 +37403,12 @@ async function getOpenclawToken() {
|
|
|
36976
37403
|
function getOpenclawTokenInfo() {
|
|
36977
37404
|
return {
|
|
36978
37405
|
path: getTokenPath(),
|
|
36979
|
-
platform:
|
|
37406
|
+
platform: os18.platform()
|
|
36980
37407
|
};
|
|
36981
37408
|
}
|
|
36982
37409
|
|
|
36983
37410
|
// src/commands/openclaw-pro.ts
|
|
36984
|
-
var
|
|
37411
|
+
var import_fs_extra19 = __toESM(require_lib4(), 1);
|
|
36985
37412
|
var API_URL2 = "https://codeline.app/api/products";
|
|
36986
37413
|
var OPENCLAW_PRODUCT_ID = "prd_t2GRwX3aH1";
|
|
36987
37414
|
var CLAUDE_CODE_TOOLS_INSTRUCTIONS = `
|
|
@@ -37088,7 +37515,7 @@ async function openclawProSetupCommand(options = {}) {
|
|
|
37088
37515
|
Se(source_default.red("❌ Not activated"));
|
|
37089
37516
|
process.exit(1);
|
|
37090
37517
|
}
|
|
37091
|
-
const openclawDir = options.folder ?
|
|
37518
|
+
const openclawDir = options.folder ? path23.resolve(options.folder) : path23.join(os19.homedir(), ".openclaw");
|
|
37092
37519
|
const spinner = Y2();
|
|
37093
37520
|
const onProgress = (file, type) => {
|
|
37094
37521
|
spinner.message(`Installing: ${source_default.cyan(file)} ${source_default.gray(`(${type})`)}`);
|
|
@@ -37101,23 +37528,23 @@ async function openclawProSetupCommand(options = {}) {
|
|
|
37101
37528
|
});
|
|
37102
37529
|
spinner.stop("OpenClaw Pro configurations installed");
|
|
37103
37530
|
let skillCount = 0;
|
|
37104
|
-
const skillsDir =
|
|
37105
|
-
if (await
|
|
37106
|
-
const items = await
|
|
37531
|
+
const skillsDir = path23.join(openclawDir, "skills");
|
|
37532
|
+
if (await import_fs_extra19.default.pathExists(skillsDir)) {
|
|
37533
|
+
const items = await import_fs_extra19.default.readdir(skillsDir);
|
|
37107
37534
|
const dirs = await Promise.all(items.map(async (item) => {
|
|
37108
|
-
const stat = await
|
|
37535
|
+
const stat = await import_fs_extra19.default.stat(path23.join(skillsDir, item));
|
|
37109
37536
|
return stat.isDirectory();
|
|
37110
37537
|
}));
|
|
37111
37538
|
skillCount = dirs.filter(Boolean).length;
|
|
37112
37539
|
}
|
|
37113
37540
|
spinner.start("Setting up workspace TOOLS.md...");
|
|
37114
|
-
const workspaceDir =
|
|
37115
|
-
const toolsPath =
|
|
37116
|
-
await
|
|
37117
|
-
if (await
|
|
37118
|
-
const existingContent = await
|
|
37541
|
+
const workspaceDir = path23.join(openclawDir, "workspace");
|
|
37542
|
+
const toolsPath = path23.join(workspaceDir, "TOOLS.md");
|
|
37543
|
+
await import_fs_extra19.default.ensureDir(workspaceDir);
|
|
37544
|
+
if (await import_fs_extra19.default.pathExists(toolsPath)) {
|
|
37545
|
+
const existingContent = await import_fs_extra19.default.readFile(toolsPath, "utf-8");
|
|
37119
37546
|
if (!existingContent.includes("Claude Code CLI")) {
|
|
37120
|
-
await
|
|
37547
|
+
await import_fs_extra19.default.appendFile(toolsPath, `
|
|
37121
37548
|
|
|
37122
37549
|
` + CLAUDE_CODE_TOOLS_INSTRUCTIONS);
|
|
37123
37550
|
spinner.stop("TOOLS.md updated with Claude Code instructions");
|
|
@@ -37131,7 +37558,7 @@ Skills define _how_ tools work. This file is for _your_ specifics — the stuff
|
|
|
37131
37558
|
|
|
37132
37559
|
${CLAUDE_CODE_TOOLS_INSTRUCTIONS}
|
|
37133
37560
|
`;
|
|
37134
|
-
await
|
|
37561
|
+
await import_fs_extra19.default.writeFile(toolsPath, defaultToolsMd);
|
|
37135
37562
|
spinner.stop("TOOLS.md created with Claude Code instructions");
|
|
37136
37563
|
}
|
|
37137
37564
|
spinner.start("Creating claude-run wrapper...");
|
|
@@ -37142,9 +37569,9 @@ ${CLAUDE_CODE_TOOLS_INSTRUCTIONS}
|
|
|
37142
37569
|
script -q -c "claude $*" /dev/null
|
|
37143
37570
|
`;
|
|
37144
37571
|
const binDir = "/usr/local/bin";
|
|
37145
|
-
const wrapperPath =
|
|
37572
|
+
const wrapperPath = path23.join(binDir, "claude-run");
|
|
37146
37573
|
try {
|
|
37147
|
-
await
|
|
37574
|
+
await import_fs_extra19.default.writeFile(wrapperPath, claudeRunWrapper, { mode: 493 });
|
|
37148
37575
|
spinner.stop("claude-run wrapper created");
|
|
37149
37576
|
} catch {
|
|
37150
37577
|
spinner.stop("claude-run wrapper skipped (no write access to /usr/local/bin)");
|
|
@@ -37193,12 +37620,12 @@ async function openclawProUpdateCommand(options = {}) {
|
|
|
37193
37620
|
}
|
|
37194
37621
|
|
|
37195
37622
|
// src/commands/dynamic-scripts.ts
|
|
37196
|
-
import
|
|
37623
|
+
import path26 from "path";
|
|
37197
37624
|
import { homedir } from "os";
|
|
37198
37625
|
|
|
37199
37626
|
// src/lib/script-parser.ts
|
|
37200
|
-
var
|
|
37201
|
-
import
|
|
37627
|
+
var import_fs_extra20 = __toESM(require_lib4(), 1);
|
|
37628
|
+
import path24 from "path";
|
|
37202
37629
|
var EXCLUDED_SCRIPTS = ["test", "lint", "format", "start"];
|
|
37203
37630
|
var EXCLUDED_SUFFIXES = [":test", ":lint", ":test-fixtures", ":start"];
|
|
37204
37631
|
function shouldIncludeScript(scriptName) {
|
|
@@ -37209,12 +37636,12 @@ function shouldIncludeScript(scriptName) {
|
|
|
37209
37636
|
return true;
|
|
37210
37637
|
}
|
|
37211
37638
|
async function readScriptsPackageJson(claudeDir) {
|
|
37212
|
-
const packageJsonPath =
|
|
37639
|
+
const packageJsonPath = path24.join(claudeDir, "scripts", "package.json");
|
|
37213
37640
|
try {
|
|
37214
|
-
if (!await
|
|
37641
|
+
if (!await import_fs_extra20.default.pathExists(packageJsonPath)) {
|
|
37215
37642
|
return null;
|
|
37216
37643
|
}
|
|
37217
|
-
const content = await
|
|
37644
|
+
const content = await import_fs_extra20.default.readFile(packageJsonPath, "utf-8");
|
|
37218
37645
|
const parsed = JSON.parse(content);
|
|
37219
37646
|
return parsed.scripts || null;
|
|
37220
37647
|
} catch (error) {
|
|
@@ -37258,14 +37685,14 @@ function groupScriptsByPrefix(commands) {
|
|
|
37258
37685
|
}
|
|
37259
37686
|
|
|
37260
37687
|
// src/commands/script-runner.ts
|
|
37261
|
-
var
|
|
37688
|
+
var import_fs_extra21 = __toESM(require_lib4(), 1);
|
|
37262
37689
|
import { spawn as spawn2 } from "child_process";
|
|
37263
37690
|
import { execSync as execSync4 } from "child_process";
|
|
37264
|
-
import
|
|
37265
|
-
import
|
|
37691
|
+
import path25 from "path";
|
|
37692
|
+
import os20 from "os";
|
|
37266
37693
|
function checkCommand2(cmd) {
|
|
37267
37694
|
try {
|
|
37268
|
-
const isWindows2 =
|
|
37695
|
+
const isWindows2 = os20.platform() === "win32";
|
|
37269
37696
|
const whichCmd = isWindows2 ? `where ${cmd}` : `which ${cmd}`;
|
|
37270
37697
|
execSync4(whichCmd, { stdio: "ignore" });
|
|
37271
37698
|
return true;
|
|
@@ -37291,18 +37718,18 @@ async function executeScript(scriptName, claudeDir) {
|
|
|
37291
37718
|
console.error(source_default.red("Bun is not installed. Install with: npm install -g bun"));
|
|
37292
37719
|
return 1;
|
|
37293
37720
|
}
|
|
37294
|
-
const scriptsDir =
|
|
37295
|
-
if (!await
|
|
37721
|
+
const scriptsDir = path25.join(claudeDir, "scripts");
|
|
37722
|
+
if (!await import_fs_extra21.default.pathExists(scriptsDir)) {
|
|
37296
37723
|
console.error(source_default.red(`Scripts directory not found at ${scriptsDir}`));
|
|
37297
37724
|
console.log(source_default.gray("Run: aiblueprint agents setup"));
|
|
37298
37725
|
return 1;
|
|
37299
37726
|
}
|
|
37300
|
-
const packageJsonPath =
|
|
37301
|
-
if (!await
|
|
37727
|
+
const packageJsonPath = path25.join(scriptsDir, "package.json");
|
|
37728
|
+
if (!await import_fs_extra21.default.pathExists(packageJsonPath)) {
|
|
37302
37729
|
console.error(source_default.red(`package.json not found in ${scriptsDir}`));
|
|
37303
37730
|
return 1;
|
|
37304
37731
|
}
|
|
37305
|
-
const packageJson = await
|
|
37732
|
+
const packageJson = await import_fs_extra21.default.readJson(packageJsonPath);
|
|
37306
37733
|
if (!packageJson.scripts || !packageJson.scripts[scriptName]) {
|
|
37307
37734
|
console.error(source_default.red(`Script "${scriptName}" not found in package.json`));
|
|
37308
37735
|
return 1;
|
|
@@ -37325,7 +37752,7 @@ async function executeScript(scriptName, claudeDir) {
|
|
|
37325
37752
|
|
|
37326
37753
|
// src/commands/dynamic-scripts.ts
|
|
37327
37754
|
function getClaudeDir(parentOptions) {
|
|
37328
|
-
return parentOptions.claudeCodeFolder || parentOptions.folder ?
|
|
37755
|
+
return parentOptions.claudeCodeFolder || parentOptions.folder ? path26.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path26.join(homedir(), ".claude");
|
|
37329
37756
|
}
|
|
37330
37757
|
async function registerDynamicScriptCommands(claudeCodeCmd, claudeDir) {
|
|
37331
37758
|
const scripts = await readScriptsPackageJson(claudeDir);
|
|
@@ -37387,6 +37814,15 @@ function registerAgentsCommands(cmd) {
|
|
|
37387
37814
|
codexFolder: parentOptions.codexFolder
|
|
37388
37815
|
});
|
|
37389
37816
|
});
|
|
37817
|
+
cmd.command("unify").description("Unify skills and agents into .agents and symlink tool folders back to it").action((options, command) => {
|
|
37818
|
+
const parentOptions = command.parent.opts();
|
|
37819
|
+
return agentsUnifyCommand({
|
|
37820
|
+
folder: parentOptions.folder,
|
|
37821
|
+
claudeCodeFolder: parentOptions.claudeCodeFolder,
|
|
37822
|
+
codexFolder: parentOptions.codexFolder,
|
|
37823
|
+
agentsFolder: parentOptions.agentsFolder
|
|
37824
|
+
});
|
|
37825
|
+
});
|
|
37390
37826
|
const proCmd = cmd.command("pro").description("Manage AIBlueprint CLI Premium features");
|
|
37391
37827
|
proCmd.command("activate [token]").description("Activate AIBlueprint CLI Premium with your access token").action((token) => {
|
|
37392
37828
|
proActivateCommand(token);
|