aiblueprint-cli 1.4.20 → 1.4.22
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 +97 -506
- package/claude-code-config/scripts/command-validator/README.md +2 -2
- package/claude-code-config/scripts/statusline/CLAUDE.md +1 -1
- package/claude-code-config/scripts/statusline/README.md +1 -1
- package/claude-code-config/scripts/statusline/fixtures/mock-transcript.jsonl +4 -4
- package/claude-code-config/scripts/statusline/fixtures/test-input.json +4 -4
- package/claude-code-config/skills/setup-ralph/steps/step-00-init.md +3 -2
- package/dist/cli.js +239 -133
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -33996,63 +33996,6 @@ async function symlinkCommand(params = {}) {
|
|
|
33996
33996
|
}
|
|
33997
33997
|
}
|
|
33998
33998
|
|
|
33999
|
-
// src/commands/statusline.ts
|
|
34000
|
-
var import_fs_extra8 = __toESM(require_lib4(), 1);
|
|
34001
|
-
import path10 from "path";
|
|
34002
|
-
import { homedir } from "os";
|
|
34003
|
-
async function statuslineCommand(options) {
|
|
34004
|
-
const claudeDir = options.folder ? path10.resolve(options.folder) : path10.join(homedir(), ".claude");
|
|
34005
|
-
console.log(source_default.blue(`\uD83D\uDE80 Setting up AIBlueprint Statusline ${source_default.gray(`v${getVersion()}`)}...`));
|
|
34006
|
-
console.log(source_default.gray(` Target: ${claudeDir}
|
|
34007
|
-
`));
|
|
34008
|
-
await import_fs_extra8.default.ensureDir(claudeDir);
|
|
34009
|
-
console.log(source_default.cyan("\uD83D\uDCE6 Checking dependencies..."));
|
|
34010
|
-
await checkAndInstallDependencies();
|
|
34011
|
-
console.log(source_default.cyan(`
|
|
34012
|
-
\uD83D\uDCE5 Cloning configuration repository...`));
|
|
34013
|
-
const repoPath = await cloneRepository();
|
|
34014
|
-
if (!repoPath) {
|
|
34015
|
-
console.log(source_default.red(" Failed to clone repository. Please check your internet connection."));
|
|
34016
|
-
return;
|
|
34017
|
-
}
|
|
34018
|
-
const sourceDir = path10.join(repoPath, "claude-code-config");
|
|
34019
|
-
if (!await import_fs_extra8.default.pathExists(sourceDir)) {
|
|
34020
|
-
await cleanupRepository(repoPath);
|
|
34021
|
-
console.log(source_default.red(" Configuration directory not found in cloned repository"));
|
|
34022
|
-
return;
|
|
34023
|
-
}
|
|
34024
|
-
try {
|
|
34025
|
-
const scriptsDir = path10.join(claudeDir, "scripts");
|
|
34026
|
-
await import_fs_extra8.default.ensureDir(scriptsDir);
|
|
34027
|
-
await import_fs_extra8.default.copy(path10.join(sourceDir, "scripts/statusline"), path10.join(scriptsDir, "statusline"), { overwrite: true });
|
|
34028
|
-
console.log(source_default.cyan(`
|
|
34029
|
-
\uD83D\uDCE6 Installing statusline dependencies...`));
|
|
34030
|
-
await installStatuslineDependencies(claudeDir);
|
|
34031
|
-
console.log(source_default.cyan(`
|
|
34032
|
-
⚙️ Configuring settings.json...`));
|
|
34033
|
-
const settingsPath = path10.join(claudeDir, "settings.json");
|
|
34034
|
-
let settings = {};
|
|
34035
|
-
try {
|
|
34036
|
-
const existingSettings = await import_fs_extra8.default.readFile(settingsPath, "utf-8");
|
|
34037
|
-
settings = JSON.parse(existingSettings);
|
|
34038
|
-
} catch {}
|
|
34039
|
-
settings.statusLine = {
|
|
34040
|
-
type: "command",
|
|
34041
|
-
command: `bun ${path10.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
34042
|
-
padding: 0
|
|
34043
|
-
};
|
|
34044
|
-
await import_fs_extra8.default.writeJson(settingsPath, settings, { spaces: 2 });
|
|
34045
|
-
console.log(source_default.green(`
|
|
34046
|
-
✅ Statusline setup complete!`));
|
|
34047
|
-
console.log(source_default.gray(`
|
|
34048
|
-
Your Claude Code statusline is now configured.`));
|
|
34049
|
-
console.log(source_default.gray(`Restart Claude Code to see the changes.
|
|
34050
|
-
`));
|
|
34051
|
-
} finally {
|
|
34052
|
-
await cleanupRepository(repoPath);
|
|
34053
|
-
}
|
|
34054
|
-
}
|
|
34055
|
-
|
|
34056
33999
|
// node_modules/@clack/core/dist/index.mjs
|
|
34057
34000
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
34058
34001
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -34770,19 +34713,19 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
34770
34713
|
|
|
34771
34714
|
// src/commands/pro.ts
|
|
34772
34715
|
import os13 from "os";
|
|
34773
|
-
import
|
|
34716
|
+
import path12 from "path";
|
|
34774
34717
|
|
|
34775
34718
|
// src/lib/pro-installer.ts
|
|
34776
|
-
var
|
|
34719
|
+
var import_fs_extra8 = __toESM(require_lib4(), 1);
|
|
34777
34720
|
import os11 from "os";
|
|
34778
|
-
import
|
|
34721
|
+
import path10 from "path";
|
|
34779
34722
|
import { exec as exec3 } from "child_process";
|
|
34780
34723
|
import { promisify as promisify2 } from "util";
|
|
34781
34724
|
var execAsync2 = promisify2(exec3);
|
|
34782
34725
|
var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
|
|
34783
34726
|
var PREMIUM_BRANCH = "main";
|
|
34784
34727
|
function getCacheRepoDir() {
|
|
34785
|
-
return
|
|
34728
|
+
return path10.join(os11.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
|
|
34786
34729
|
}
|
|
34787
34730
|
async function execGitWithAuth(command, token, repoUrl, cwd) {
|
|
34788
34731
|
const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
|
|
@@ -34796,33 +34739,33 @@ async function execGitWithAuth(command, token, repoUrl, cwd) {
|
|
|
34796
34739
|
async function cloneOrUpdateRepo(token) {
|
|
34797
34740
|
const cacheDir = getCacheRepoDir();
|
|
34798
34741
|
const repoUrl = `https://github.com/${PREMIUM_REPO}.git`;
|
|
34799
|
-
if (await
|
|
34742
|
+
if (await import_fs_extra8.default.pathExists(path10.join(cacheDir, ".git"))) {
|
|
34800
34743
|
try {
|
|
34801
34744
|
await execGitWithAuth("pull", token, repoUrl, cacheDir);
|
|
34802
34745
|
} catch (error) {
|
|
34803
|
-
await
|
|
34804
|
-
await
|
|
34746
|
+
await import_fs_extra8.default.remove(cacheDir);
|
|
34747
|
+
await import_fs_extra8.default.ensureDir(path10.dirname(cacheDir));
|
|
34805
34748
|
await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
|
|
34806
34749
|
}
|
|
34807
34750
|
} else {
|
|
34808
|
-
await
|
|
34751
|
+
await import_fs_extra8.default.ensureDir(path10.dirname(cacheDir));
|
|
34809
34752
|
await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
|
|
34810
34753
|
}
|
|
34811
|
-
return
|
|
34754
|
+
return path10.join(cacheDir, "claude-code-config");
|
|
34812
34755
|
}
|
|
34813
34756
|
async function copyConfigFromCache(cacheConfigDir, targetDir, onProgress) {
|
|
34814
34757
|
const walk = async (dir, baseDir = dir) => {
|
|
34815
|
-
const entries = await
|
|
34758
|
+
const entries = await import_fs_extra8.default.readdir(dir, { withFileTypes: true });
|
|
34816
34759
|
for (const entry of entries) {
|
|
34817
|
-
const sourcePath =
|
|
34818
|
-
const relativePath =
|
|
34819
|
-
const targetPath =
|
|
34760
|
+
const sourcePath = path10.join(dir, entry.name);
|
|
34761
|
+
const relativePath = path10.relative(baseDir, sourcePath);
|
|
34762
|
+
const targetPath = path10.join(targetDir, relativePath);
|
|
34820
34763
|
if (entry.isDirectory()) {
|
|
34821
|
-
await
|
|
34764
|
+
await import_fs_extra8.default.ensureDir(targetPath);
|
|
34822
34765
|
onProgress?.(relativePath, "directory");
|
|
34823
34766
|
await walk(sourcePath, baseDir);
|
|
34824
34767
|
} else {
|
|
34825
|
-
await
|
|
34768
|
+
await import_fs_extra8.default.copy(sourcePath, targetPath, { overwrite: true });
|
|
34826
34769
|
onProgress?.(relativePath, "file");
|
|
34827
34770
|
}
|
|
34828
34771
|
}
|
|
@@ -34843,8 +34786,8 @@ async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath,
|
|
|
34843
34786
|
return false;
|
|
34844
34787
|
}
|
|
34845
34788
|
const content = await response.arrayBuffer();
|
|
34846
|
-
await
|
|
34847
|
-
await
|
|
34789
|
+
await import_fs_extra8.default.ensureDir(path10.dirname(targetPath));
|
|
34790
|
+
await import_fs_extra8.default.writeFile(targetPath, Buffer.from(content));
|
|
34848
34791
|
return true;
|
|
34849
34792
|
} catch (error) {
|
|
34850
34793
|
console.error(`Error downloading ${relativePath}:`, error);
|
|
@@ -34869,10 +34812,10 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
|
|
|
34869
34812
|
console.error(`Unexpected response for directory ${dirPath}`);
|
|
34870
34813
|
return false;
|
|
34871
34814
|
}
|
|
34872
|
-
await
|
|
34815
|
+
await import_fs_extra8.default.ensureDir(targetDir);
|
|
34873
34816
|
for (const file of files) {
|
|
34874
34817
|
const relativePath = dirPath ? `${dirPath}/${file.name}` : file.name;
|
|
34875
|
-
const targetPath =
|
|
34818
|
+
const targetPath = path10.join(targetDir, file.name);
|
|
34876
34819
|
const displayPath = relativePath.replace("claude-code-config/", "");
|
|
34877
34820
|
if (file.type === "file") {
|
|
34878
34821
|
onProgress?.(displayPath, "file");
|
|
@@ -34889,7 +34832,7 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
|
|
|
34889
34832
|
}
|
|
34890
34833
|
async function installProConfigs(options) {
|
|
34891
34834
|
const { githubToken, claudeCodeFolder, onProgress } = options;
|
|
34892
|
-
const claudeFolder = claudeCodeFolder ||
|
|
34835
|
+
const claudeFolder = claudeCodeFolder || path10.join(os11.homedir(), ".claude");
|
|
34893
34836
|
try {
|
|
34894
34837
|
const cacheConfigDir = await cloneOrUpdateRepo(githubToken);
|
|
34895
34838
|
await copyConfigFromCache(cacheConfigDir, claudeFolder, onProgress);
|
|
@@ -34897,53 +34840,53 @@ async function installProConfigs(options) {
|
|
|
34897
34840
|
} catch (error) {
|
|
34898
34841
|
console.warn("Git caching failed, falling back to API download");
|
|
34899
34842
|
}
|
|
34900
|
-
const tempDir =
|
|
34843
|
+
const tempDir = path10.join(os11.tmpdir(), `aiblueprint-premium-${Date.now()}`);
|
|
34901
34844
|
try {
|
|
34902
34845
|
const success = await downloadDirectoryFromPrivateGitHub(PREMIUM_REPO, PREMIUM_BRANCH, "claude-code-config", tempDir, githubToken, onProgress);
|
|
34903
34846
|
if (!success) {
|
|
34904
34847
|
throw new Error("Failed to download premium configurations");
|
|
34905
34848
|
}
|
|
34906
|
-
await
|
|
34849
|
+
await import_fs_extra8.default.copy(tempDir, claudeFolder, {
|
|
34907
34850
|
overwrite: true
|
|
34908
34851
|
});
|
|
34909
34852
|
} catch (error) {
|
|
34910
34853
|
throw new Error(`Failed to install premium configs: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
34911
34854
|
} finally {
|
|
34912
34855
|
try {
|
|
34913
|
-
await
|
|
34856
|
+
await import_fs_extra8.default.remove(tempDir);
|
|
34914
34857
|
} catch {}
|
|
34915
34858
|
}
|
|
34916
34859
|
}
|
|
34917
34860
|
|
|
34918
34861
|
// src/lib/token-storage.ts
|
|
34919
|
-
var
|
|
34862
|
+
var import_fs_extra9 = __toESM(require_lib4(), 1);
|
|
34920
34863
|
import os12 from "os";
|
|
34921
|
-
import
|
|
34864
|
+
import path11 from "path";
|
|
34922
34865
|
function getConfigDir() {
|
|
34923
34866
|
const platform = os12.platform();
|
|
34924
34867
|
if (platform === "win32") {
|
|
34925
|
-
const appData = process.env.APPDATA ||
|
|
34926
|
-
return
|
|
34868
|
+
const appData = process.env.APPDATA || path11.join(os12.homedir(), "AppData", "Roaming");
|
|
34869
|
+
return path11.join(appData, "aiblueprint");
|
|
34927
34870
|
} else {
|
|
34928
|
-
const configHome = process.env.XDG_CONFIG_HOME ||
|
|
34929
|
-
return
|
|
34871
|
+
const configHome = process.env.XDG_CONFIG_HOME || path11.join(os12.homedir(), ".config");
|
|
34872
|
+
return path11.join(configHome, "aiblueprint");
|
|
34930
34873
|
}
|
|
34931
34874
|
}
|
|
34932
34875
|
function getTokenFilePath() {
|
|
34933
|
-
return
|
|
34876
|
+
return path11.join(getConfigDir(), "token.txt");
|
|
34934
34877
|
}
|
|
34935
34878
|
async function saveToken(githubToken) {
|
|
34936
34879
|
const tokenFile = getTokenFilePath();
|
|
34937
|
-
await
|
|
34938
|
-
await
|
|
34880
|
+
await import_fs_extra9.default.ensureDir(path11.dirname(tokenFile));
|
|
34881
|
+
await import_fs_extra9.default.writeFile(tokenFile, githubToken, { mode: 384 });
|
|
34939
34882
|
}
|
|
34940
34883
|
async function getToken() {
|
|
34941
34884
|
const tokenFile = getTokenFilePath();
|
|
34942
|
-
if (!await
|
|
34885
|
+
if (!await import_fs_extra9.default.pathExists(tokenFile)) {
|
|
34943
34886
|
return null;
|
|
34944
34887
|
}
|
|
34945
34888
|
try {
|
|
34946
|
-
const token = await
|
|
34889
|
+
const token = await import_fs_extra9.default.readFile(tokenFile, "utf-8");
|
|
34947
34890
|
return token.trim();
|
|
34948
34891
|
} catch (error) {
|
|
34949
34892
|
return null;
|
|
@@ -34957,7 +34900,7 @@ function getTokenInfo() {
|
|
|
34957
34900
|
}
|
|
34958
34901
|
|
|
34959
34902
|
// src/commands/pro.ts
|
|
34960
|
-
var
|
|
34903
|
+
var import_fs_extra10 = __toESM(require_lib4(), 1);
|
|
34961
34904
|
var API_URL = "https://codeline.app/api/products";
|
|
34962
34905
|
var PRODUCT_IDS = ["prd_XJVgxVPbGG", "prd_NKabAkdOkw"];
|
|
34963
34906
|
async function countInstalledItems(claudeDir) {
|
|
@@ -34967,29 +34910,29 @@ async function countInstalledItems(claudeDir) {
|
|
|
34967
34910
|
skills: 0
|
|
34968
34911
|
};
|
|
34969
34912
|
try {
|
|
34970
|
-
const commandsDir =
|
|
34971
|
-
if (await
|
|
34972
|
-
const files = await
|
|
34913
|
+
const commandsDir = path12.join(claudeDir, "commands");
|
|
34914
|
+
if (await import_fs_extra10.default.pathExists(commandsDir)) {
|
|
34915
|
+
const files = await import_fs_extra10.default.readdir(commandsDir);
|
|
34973
34916
|
counts.commands = files.filter((f) => f.endsWith(".md")).length;
|
|
34974
34917
|
}
|
|
34975
34918
|
} catch (error) {
|
|
34976
34919
|
console.error("Failed to count commands:", error instanceof Error ? error.message : error);
|
|
34977
34920
|
}
|
|
34978
34921
|
try {
|
|
34979
|
-
const agentsDir =
|
|
34980
|
-
if (await
|
|
34981
|
-
const files = await
|
|
34922
|
+
const agentsDir = path12.join(claudeDir, "agents");
|
|
34923
|
+
if (await import_fs_extra10.default.pathExists(agentsDir)) {
|
|
34924
|
+
const files = await import_fs_extra10.default.readdir(agentsDir);
|
|
34982
34925
|
counts.agents = files.filter((f) => f.endsWith(".md")).length;
|
|
34983
34926
|
}
|
|
34984
34927
|
} catch (error) {
|
|
34985
34928
|
console.error("Failed to count agents:", error instanceof Error ? error.message : error);
|
|
34986
34929
|
}
|
|
34987
34930
|
try {
|
|
34988
|
-
const skillsDir =
|
|
34989
|
-
if (await
|
|
34990
|
-
const items = await
|
|
34931
|
+
const skillsDir = path12.join(claudeDir, "skills");
|
|
34932
|
+
if (await import_fs_extra10.default.pathExists(skillsDir)) {
|
|
34933
|
+
const items = await import_fs_extra10.default.readdir(skillsDir);
|
|
34991
34934
|
const dirs = await Promise.all(items.map(async (item) => {
|
|
34992
|
-
const stat = await
|
|
34935
|
+
const stat = await import_fs_extra10.default.stat(path12.join(skillsDir, item));
|
|
34993
34936
|
return stat.isDirectory();
|
|
34994
34937
|
}));
|
|
34995
34938
|
counts.skills = dirs.filter(Boolean).length;
|
|
@@ -35102,7 +35045,7 @@ async function proSetupCommand(options = {}) {
|
|
|
35102
35045
|
Se(source_default.red("❌ Not activated"));
|
|
35103
35046
|
process.exit(1);
|
|
35104
35047
|
}
|
|
35105
|
-
const claudeDir = options.folder ?
|
|
35048
|
+
const claudeDir = options.folder ? path12.resolve(options.folder) : path12.join(os13.homedir(), ".claude");
|
|
35106
35049
|
const spinner = Y2();
|
|
35107
35050
|
const onProgress = (file, type) => {
|
|
35108
35051
|
spinner.message(`Installing: ${source_default.cyan(file)} ${source_default.gray(`(${type})`)}`);
|
|
@@ -35185,11 +35128,11 @@ async function proUpdateCommand(options = {}) {
|
|
|
35185
35128
|
|
|
35186
35129
|
// src/commands/sync.ts
|
|
35187
35130
|
import os14 from "os";
|
|
35188
|
-
import
|
|
35131
|
+
import path14 from "path";
|
|
35189
35132
|
|
|
35190
35133
|
// src/lib/sync-utils.ts
|
|
35191
|
-
var
|
|
35192
|
-
import
|
|
35134
|
+
var import_fs_extra11 = __toESM(require_lib4(), 1);
|
|
35135
|
+
import path13 from "path";
|
|
35193
35136
|
import crypto from "crypto";
|
|
35194
35137
|
var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
|
|
35195
35138
|
var PREMIUM_BRANCH2 = "main";
|
|
@@ -35238,7 +35181,7 @@ async function listRemoteFilesRecursive(dirPath, githubToken, basePath = "") {
|
|
|
35238
35181
|
}
|
|
35239
35182
|
async function computeLocalFileSha(filePath) {
|
|
35240
35183
|
try {
|
|
35241
|
-
const content = await
|
|
35184
|
+
const content = await import_fs_extra11.default.readFile(filePath);
|
|
35242
35185
|
return computeFileSha(content);
|
|
35243
35186
|
} catch {
|
|
35244
35187
|
return null;
|
|
@@ -35246,15 +35189,15 @@ async function computeLocalFileSha(filePath) {
|
|
|
35246
35189
|
}
|
|
35247
35190
|
async function listLocalFiles(dir) {
|
|
35248
35191
|
const files = [];
|
|
35249
|
-
if (!await
|
|
35192
|
+
if (!await import_fs_extra11.default.pathExists(dir)) {
|
|
35250
35193
|
return files;
|
|
35251
35194
|
}
|
|
35252
|
-
const items = await
|
|
35195
|
+
const items = await import_fs_extra11.default.readdir(dir);
|
|
35253
35196
|
for (const item of items) {
|
|
35254
35197
|
if (item === "node_modules" || item === ".DS_Store")
|
|
35255
35198
|
continue;
|
|
35256
|
-
const fullPath =
|
|
35257
|
-
const stat = await
|
|
35199
|
+
const fullPath = path13.join(dir, item);
|
|
35200
|
+
const stat = await import_fs_extra11.default.stat(fullPath);
|
|
35258
35201
|
if (stat.isDirectory()) {
|
|
35259
35202
|
files.push(item);
|
|
35260
35203
|
const subFiles = await listLocalFilesRecursive(fullPath, item);
|
|
@@ -35267,13 +35210,13 @@ async function listLocalFiles(dir) {
|
|
|
35267
35210
|
}
|
|
35268
35211
|
async function listLocalFilesRecursive(dir, basePath) {
|
|
35269
35212
|
const files = [];
|
|
35270
|
-
const items = await
|
|
35213
|
+
const items = await import_fs_extra11.default.readdir(dir);
|
|
35271
35214
|
for (const item of items) {
|
|
35272
35215
|
if (item === "node_modules" || item === ".DS_Store")
|
|
35273
35216
|
continue;
|
|
35274
|
-
const fullPath =
|
|
35217
|
+
const fullPath = path13.join(dir, item);
|
|
35275
35218
|
const relativePath = `${basePath}/${item}`;
|
|
35276
|
-
const stat = await
|
|
35219
|
+
const stat = await import_fs_extra11.default.stat(fullPath);
|
|
35277
35220
|
if (stat.isDirectory()) {
|
|
35278
35221
|
files.push(relativePath);
|
|
35279
35222
|
const subFiles = await listLocalFilesRecursive(fullPath, relativePath);
|
|
@@ -35286,7 +35229,7 @@ async function listLocalFilesRecursive(dir, basePath) {
|
|
|
35286
35229
|
}
|
|
35287
35230
|
async function analyzeCategory(category, claudeDir, githubToken) {
|
|
35288
35231
|
const items = [];
|
|
35289
|
-
const localDir =
|
|
35232
|
+
const localDir = path13.join(claudeDir, category);
|
|
35290
35233
|
const remoteFiles = await listRemoteFilesRecursive(category, githubToken);
|
|
35291
35234
|
const localFiles = await listLocalFiles(localDir);
|
|
35292
35235
|
const remoteSet = new Map;
|
|
@@ -35295,7 +35238,7 @@ async function analyzeCategory(category, claudeDir, githubToken) {
|
|
|
35295
35238
|
}
|
|
35296
35239
|
const localSet = new Set(localFiles);
|
|
35297
35240
|
for (const [remotePath, { sha, isFolder }] of remoteSet) {
|
|
35298
|
-
const localPath =
|
|
35241
|
+
const localPath = path13.join(localDir, remotePath);
|
|
35299
35242
|
if (isFolder) {
|
|
35300
35243
|
continue;
|
|
35301
35244
|
}
|
|
@@ -35338,8 +35281,8 @@ async function analyzeCategory(category, claudeDir, githubToken) {
|
|
|
35338
35281
|
if (parentAlreadyDeleted) {
|
|
35339
35282
|
continue;
|
|
35340
35283
|
}
|
|
35341
|
-
const fullPath =
|
|
35342
|
-
const stat = await
|
|
35284
|
+
const fullPath = path13.join(localDir, localPath);
|
|
35285
|
+
const stat = await import_fs_extra11.default.stat(fullPath).catch(() => null);
|
|
35343
35286
|
if (stat) {
|
|
35344
35287
|
const isFolder = stat.isDirectory();
|
|
35345
35288
|
items.push({
|
|
@@ -35375,9 +35318,9 @@ async function fetchRemoteSettings(githubToken) {
|
|
|
35375
35318
|
}
|
|
35376
35319
|
}
|
|
35377
35320
|
async function getLocalSettings(claudeDir) {
|
|
35378
|
-
const settingsPath =
|
|
35321
|
+
const settingsPath = path13.join(claudeDir, "settings.json");
|
|
35379
35322
|
try {
|
|
35380
|
-
const content = await
|
|
35323
|
+
const content = await import_fs_extra11.default.readFile(settingsPath, "utf-8");
|
|
35381
35324
|
return JSON.parse(content);
|
|
35382
35325
|
} catch {
|
|
35383
35326
|
return {};
|
|
@@ -35459,8 +35402,8 @@ async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken)
|
|
|
35459
35402
|
return false;
|
|
35460
35403
|
}
|
|
35461
35404
|
const content = await response.arrayBuffer();
|
|
35462
|
-
await
|
|
35463
|
-
await
|
|
35405
|
+
await import_fs_extra11.default.ensureDir(path13.dirname(targetPath));
|
|
35406
|
+
await import_fs_extra11.default.writeFile(targetPath, Buffer.from(content));
|
|
35464
35407
|
return true;
|
|
35465
35408
|
} catch {
|
|
35466
35409
|
return false;
|
|
@@ -35470,10 +35413,10 @@ async function syncSelectedHooks(claudeDir, hooks, onProgress) {
|
|
|
35470
35413
|
if (hooks.length === 0) {
|
|
35471
35414
|
return { success: 0, failed: 0 };
|
|
35472
35415
|
}
|
|
35473
|
-
const settingsPath =
|
|
35416
|
+
const settingsPath = path13.join(claudeDir, "settings.json");
|
|
35474
35417
|
let settings = {};
|
|
35475
35418
|
try {
|
|
35476
|
-
const content = await
|
|
35419
|
+
const content = await import_fs_extra11.default.readFile(settingsPath, "utf-8");
|
|
35477
35420
|
settings = JSON.parse(content);
|
|
35478
35421
|
} catch {
|
|
35479
35422
|
settings = {};
|
|
@@ -35501,7 +35444,7 @@ async function syncSelectedHooks(claudeDir, hooks, onProgress) {
|
|
|
35501
35444
|
failed++;
|
|
35502
35445
|
}
|
|
35503
35446
|
}
|
|
35504
|
-
await
|
|
35447
|
+
await import_fs_extra11.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
35505
35448
|
return { success, failed };
|
|
35506
35449
|
}
|
|
35507
35450
|
async function syncSelectedItems(claudeDir, items, githubToken, onProgress) {
|
|
@@ -35509,11 +35452,11 @@ async function syncSelectedItems(claudeDir, items, githubToken, onProgress) {
|
|
|
35509
35452
|
let failed = 0;
|
|
35510
35453
|
let deleted = 0;
|
|
35511
35454
|
for (const item of items) {
|
|
35512
|
-
const targetPath =
|
|
35455
|
+
const targetPath = path13.join(claudeDir, item.relativePath);
|
|
35513
35456
|
if (item.status === "deleted") {
|
|
35514
35457
|
onProgress?.(item.relativePath, "deleting");
|
|
35515
35458
|
try {
|
|
35516
|
-
await
|
|
35459
|
+
await import_fs_extra11.default.remove(targetPath);
|
|
35517
35460
|
deleted++;
|
|
35518
35461
|
} catch {
|
|
35519
35462
|
failed++;
|
|
@@ -35665,7 +35608,7 @@ async function proSyncCommand(options = {}) {
|
|
|
35665
35608
|
Se(source_default.red("❌ Not activated"));
|
|
35666
35609
|
process.exit(1);
|
|
35667
35610
|
}
|
|
35668
|
-
const claudeDir = options.folder ?
|
|
35611
|
+
const claudeDir = options.folder ? path14.resolve(options.folder) : path14.join(os14.homedir(), ".claude");
|
|
35669
35612
|
const spinner = Y2();
|
|
35670
35613
|
spinner.start("Analyzing changes...");
|
|
35671
35614
|
const result = await analyzeSyncChanges(claudeDir, githubToken);
|
|
@@ -35893,10 +35836,170 @@ async function proSyncCommand(options = {}) {
|
|
|
35893
35836
|
}
|
|
35894
35837
|
}
|
|
35895
35838
|
|
|
35839
|
+
// src/commands/dynamic-scripts.ts
|
|
35840
|
+
import path17 from "path";
|
|
35841
|
+
import { homedir } from "os";
|
|
35842
|
+
|
|
35843
|
+
// src/lib/script-parser.ts
|
|
35844
|
+
var import_fs_extra12 = __toESM(require_lib4(), 1);
|
|
35845
|
+
import path15 from "path";
|
|
35846
|
+
var EXCLUDED_SCRIPTS = ["test", "lint", "format", "start"];
|
|
35847
|
+
var EXCLUDED_SUFFIXES = [":test", ":lint", ":test-fixtures", ":start"];
|
|
35848
|
+
function shouldIncludeScript(scriptName) {
|
|
35849
|
+
if (EXCLUDED_SCRIPTS.includes(scriptName))
|
|
35850
|
+
return false;
|
|
35851
|
+
if (EXCLUDED_SUFFIXES.some((suffix) => scriptName.endsWith(suffix)))
|
|
35852
|
+
return false;
|
|
35853
|
+
return true;
|
|
35854
|
+
}
|
|
35855
|
+
async function readScriptsPackageJson(claudeDir) {
|
|
35856
|
+
const packageJsonPath = path15.join(claudeDir, "scripts", "package.json");
|
|
35857
|
+
try {
|
|
35858
|
+
if (!await import_fs_extra12.default.pathExists(packageJsonPath)) {
|
|
35859
|
+
return null;
|
|
35860
|
+
}
|
|
35861
|
+
const content = await import_fs_extra12.default.readFile(packageJsonPath, "utf-8");
|
|
35862
|
+
const parsed = JSON.parse(content);
|
|
35863
|
+
return parsed.scripts || null;
|
|
35864
|
+
} catch (error) {
|
|
35865
|
+
if (process.env.DEBUG) {
|
|
35866
|
+
console.error("Failed to read scripts package.json:", error);
|
|
35867
|
+
}
|
|
35868
|
+
return null;
|
|
35869
|
+
}
|
|
35870
|
+
}
|
|
35871
|
+
function parseScriptCommands(scripts) {
|
|
35872
|
+
const commands = [];
|
|
35873
|
+
for (const scriptName of Object.keys(scripts)) {
|
|
35874
|
+
if (!shouldIncludeScript(scriptName)) {
|
|
35875
|
+
continue;
|
|
35876
|
+
}
|
|
35877
|
+
if (!scriptName.includes(":")) {
|
|
35878
|
+
continue;
|
|
35879
|
+
}
|
|
35880
|
+
const [prefix, ...actionParts] = scriptName.split(":");
|
|
35881
|
+
const action = actionParts.join(":");
|
|
35882
|
+
if (!action) {
|
|
35883
|
+
continue;
|
|
35884
|
+
}
|
|
35885
|
+
commands.push({
|
|
35886
|
+
prefix,
|
|
35887
|
+
action,
|
|
35888
|
+
fullScriptName: scriptName
|
|
35889
|
+
});
|
|
35890
|
+
}
|
|
35891
|
+
return commands;
|
|
35892
|
+
}
|
|
35893
|
+
function groupScriptsByPrefix(commands) {
|
|
35894
|
+
const groups = {};
|
|
35895
|
+
for (const command of commands) {
|
|
35896
|
+
if (!groups[command.prefix]) {
|
|
35897
|
+
groups[command.prefix] = [];
|
|
35898
|
+
}
|
|
35899
|
+
groups[command.prefix].push(command.action);
|
|
35900
|
+
}
|
|
35901
|
+
return groups;
|
|
35902
|
+
}
|
|
35903
|
+
|
|
35904
|
+
// src/commands/script-runner.ts
|
|
35905
|
+
var import_fs_extra13 = __toESM(require_lib4(), 1);
|
|
35906
|
+
import { spawn as spawn2 } from "child_process";
|
|
35907
|
+
import { execSync as execSync4 } from "child_process";
|
|
35908
|
+
import path16 from "path";
|
|
35909
|
+
import os15 from "os";
|
|
35910
|
+
function checkCommand(cmd) {
|
|
35911
|
+
try {
|
|
35912
|
+
const isWindows = os15.platform() === "win32";
|
|
35913
|
+
const whichCmd = isWindows ? `where ${cmd}` : `which ${cmd}`;
|
|
35914
|
+
execSync4(whichCmd, { stdio: "ignore" });
|
|
35915
|
+
return true;
|
|
35916
|
+
} catch {
|
|
35917
|
+
return false;
|
|
35918
|
+
}
|
|
35919
|
+
}
|
|
35920
|
+
function showAvailableActions(prefix, actions) {
|
|
35921
|
+
console.log(source_default.blue(`
|
|
35922
|
+
${prefix.charAt(0).toUpperCase() + prefix.slice(1)} Scripts:`));
|
|
35923
|
+
console.log(source_default.gray(`Run scripts from ~/.claude/scripts
|
|
35924
|
+
`));
|
|
35925
|
+
for (const action of actions) {
|
|
35926
|
+
console.log(source_default.white(` ${prefix} ${action}`));
|
|
35927
|
+
}
|
|
35928
|
+
console.log(source_default.gray(`
|
|
35929
|
+
Usage: aiblueprint ${prefix} <action>`));
|
|
35930
|
+
console.log(source_default.gray(`Example: aiblueprint ${prefix} ${actions[0] || "start"}
|
|
35931
|
+
`));
|
|
35932
|
+
}
|
|
35933
|
+
async function executeScript(scriptName, claudeDir) {
|
|
35934
|
+
if (!checkCommand("bun")) {
|
|
35935
|
+
console.error(source_default.red("Bun is not installed. Install with: npm install -g bun"));
|
|
35936
|
+
return 1;
|
|
35937
|
+
}
|
|
35938
|
+
const scriptsDir = path16.join(claudeDir, "scripts");
|
|
35939
|
+
if (!await import_fs_extra13.default.pathExists(scriptsDir)) {
|
|
35940
|
+
console.error(source_default.red(`Scripts directory not found at ${scriptsDir}`));
|
|
35941
|
+
console.log(source_default.gray("Run: aiblueprint claude-code setup"));
|
|
35942
|
+
return 1;
|
|
35943
|
+
}
|
|
35944
|
+
const packageJsonPath = path16.join(scriptsDir, "package.json");
|
|
35945
|
+
if (!await import_fs_extra13.default.pathExists(packageJsonPath)) {
|
|
35946
|
+
console.error(source_default.red(`package.json not found in ${scriptsDir}`));
|
|
35947
|
+
return 1;
|
|
35948
|
+
}
|
|
35949
|
+
const packageJson = await import_fs_extra13.default.readJson(packageJsonPath);
|
|
35950
|
+
if (!packageJson.scripts || !packageJson.scripts[scriptName]) {
|
|
35951
|
+
console.error(source_default.red(`Script "${scriptName}" not found in package.json`));
|
|
35952
|
+
return 1;
|
|
35953
|
+
}
|
|
35954
|
+
return new Promise((resolve) => {
|
|
35955
|
+
const child = spawn2("bun", ["run", scriptName], {
|
|
35956
|
+
cwd: scriptsDir,
|
|
35957
|
+
stdio: "inherit",
|
|
35958
|
+
env: process.env
|
|
35959
|
+
});
|
|
35960
|
+
child.on("close", (code) => {
|
|
35961
|
+
resolve(code || 0);
|
|
35962
|
+
});
|
|
35963
|
+
child.on("error", (error) => {
|
|
35964
|
+
console.error(source_default.red(`Failed to execute script: ${error.message}`));
|
|
35965
|
+
resolve(1);
|
|
35966
|
+
});
|
|
35967
|
+
});
|
|
35968
|
+
}
|
|
35969
|
+
|
|
35970
|
+
// src/commands/dynamic-scripts.ts
|
|
35971
|
+
function getClaudeDir(parentOptions) {
|
|
35972
|
+
return parentOptions.claudeCodeFolder || parentOptions.folder ? path17.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path17.join(homedir(), ".claude");
|
|
35973
|
+
}
|
|
35974
|
+
async function registerDynamicScriptCommands(claudeCodeCmd, claudeDir) {
|
|
35975
|
+
const scripts = await readScriptsPackageJson(claudeDir);
|
|
35976
|
+
if (!scripts) {
|
|
35977
|
+
return;
|
|
35978
|
+
}
|
|
35979
|
+
const commands = parseScriptCommands(scripts);
|
|
35980
|
+
if (commands.length === 0) {
|
|
35981
|
+
return;
|
|
35982
|
+
}
|
|
35983
|
+
const scriptGroups = groupScriptsByPrefix(commands);
|
|
35984
|
+
for (const [prefix, actions] of Object.entries(scriptGroups)) {
|
|
35985
|
+
const command = claudeCodeCmd.command(`${prefix} [action]`).description(`Run ${prefix} scripts from ~/.claude/scripts`).option("-l, --list", "List available actions").action(async (action, options) => {
|
|
35986
|
+
const parentOptions = command.parent?.opts() || {};
|
|
35987
|
+
const resolvedClaudeDir = getClaudeDir(parentOptions);
|
|
35988
|
+
if (options.list || !action) {
|
|
35989
|
+
showAvailableActions(prefix, actions);
|
|
35990
|
+
return;
|
|
35991
|
+
}
|
|
35992
|
+
const exitCode = await executeScript(`${prefix}:${action}`, resolvedClaudeDir);
|
|
35993
|
+
process.exit(exitCode);
|
|
35994
|
+
});
|
|
35995
|
+
}
|
|
35996
|
+
}
|
|
35997
|
+
|
|
35896
35998
|
// src/cli.ts
|
|
35897
35999
|
import { readFileSync as readFileSync3 } from "fs";
|
|
35898
36000
|
import { dirname as dirname3, join as join2 } from "path";
|
|
35899
36001
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
36002
|
+
import { homedir as homedir2 } from "os";
|
|
35900
36003
|
var __dirname3 = dirname3(fileURLToPath3(import.meta.url));
|
|
35901
36004
|
var packageJson = JSON.parse(readFileSync3(join2(__dirname3, "../package.json"), "utf8"));
|
|
35902
36005
|
var program2 = new Command;
|
|
@@ -35927,11 +36030,6 @@ claudeCodeCmd.command("symlink").description("Create symlinks between different
|
|
|
35927
36030
|
factoryAiFolder: parentOptions.factoryAiFolder
|
|
35928
36031
|
});
|
|
35929
36032
|
});
|
|
35930
|
-
claudeCodeCmd.command("statusline").description("Setup custom statusline with git status, costs, and token usage").action((options, command) => {
|
|
35931
|
-
const parentOptions = command.parent.opts();
|
|
35932
|
-
const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
|
|
35933
|
-
statuslineCommand({ folder: claudeCodeFolder });
|
|
35934
|
-
});
|
|
35935
36033
|
var proCmd = claudeCodeCmd.command("pro").description("Manage AIBlueprint CLI Premium features");
|
|
35936
36034
|
proCmd.command("activate [token]").description("Activate AIBlueprint CLI Premium with your access token").action((token) => {
|
|
35937
36035
|
proActivateCommand(token);
|
|
@@ -35954,6 +36052,14 @@ proCmd.command("sync").description("Sync premium configurations with selective u
|
|
|
35954
36052
|
const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
|
|
35955
36053
|
proSyncCommand({ folder: claudeCodeFolder });
|
|
35956
36054
|
});
|
|
36055
|
+
try {
|
|
36056
|
+
const claudeDir = join2(homedir2(), ".claude");
|
|
36057
|
+
await registerDynamicScriptCommands(claudeCodeCmd, claudeDir);
|
|
36058
|
+
} catch (error) {
|
|
36059
|
+
if (process.env.DEBUG) {
|
|
36060
|
+
console.error("Failed to register dynamic commands:", error);
|
|
36061
|
+
}
|
|
36062
|
+
}
|
|
35957
36063
|
program2.parse(process.argv);
|
|
35958
36064
|
if (!process.argv.slice(2).length) {
|
|
35959
36065
|
console.log(source_default.blue("\uD83D\uDE80 AIBlueprint CLI"));
|