aiblueprint-cli 1.3.0 → 1.3.1
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/claude-code-config/agents/explore-codebase.md +3 -1
- package/claude-code-config/agents/explore-docs.md +54 -58
- package/claude-code-config/agents/websearch.md +2 -2
- package/claude-code-config/commands/apex.md +109 -0
- package/claude-code-config/commands/explore.md +77 -32
- package/claude-code-config/commands/git/commit.md +60 -0
- package/claude-code-config/commands/{create-pull-request.md → git/create-pr.md} +12 -0
- package/claude-code-config/commands/{fix-pr-comments.md → git/fix-pr-comments.md} +10 -0
- package/claude-code-config/commands/oneshot.md +44 -44
- package/claude-code-config/commands/tasks/run-task.md +220 -0
- package/claude-code-config/commands/{watch-ci.md → utils/watch-ci.md} +4 -0
- package/dist/cli.js +493 -8
- package/package.json +1 -1
- package/claude-code-config/commands/commit.md +0 -47
- package/claude-code-config/commands/epct.md +0 -69
- package/claude-code-config/commands/run-tasks.md +0 -105
package/dist/cli.js
CHANGED
|
@@ -33765,15 +33765,24 @@ async function listFilesFromGitHub(dirPath) {
|
|
|
33765
33765
|
if (!response.ok) {
|
|
33766
33766
|
return [];
|
|
33767
33767
|
}
|
|
33768
|
-
const
|
|
33769
|
-
|
|
33768
|
+
const items = await response.json();
|
|
33769
|
+
const files = [];
|
|
33770
|
+
for (const item of items) {
|
|
33771
|
+
if (item.type === "file") {
|
|
33772
|
+
files.push(item.name);
|
|
33773
|
+
} else if (item.type === "dir") {
|
|
33774
|
+
const subFiles = await listFilesFromGitHub(`${dirPath}/${item.name}`);
|
|
33775
|
+
files.push(...subFiles.map((f) => `${item.name}/${f}`));
|
|
33776
|
+
}
|
|
33777
|
+
}
|
|
33778
|
+
return files;
|
|
33770
33779
|
} catch (error) {
|
|
33771
33780
|
return [];
|
|
33772
33781
|
}
|
|
33773
33782
|
}
|
|
33774
33783
|
async function isGitHubAvailable() {
|
|
33775
33784
|
try {
|
|
33776
|
-
const testUrl = `${GITHUB_RAW_BASE3}/commands/
|
|
33785
|
+
const testUrl = `${GITHUB_RAW_BASE3}/commands/apex.md`;
|
|
33777
33786
|
const testResponse = await fetch(testUrl);
|
|
33778
33787
|
return testResponse.ok;
|
|
33779
33788
|
} catch {
|
|
@@ -33967,6 +33976,20 @@ class SimpleSpinner3 {
|
|
|
33967
33976
|
console.log(source_default.green(`✓ ${message}`));
|
|
33968
33977
|
}
|
|
33969
33978
|
}
|
|
33979
|
+
async function getLocalMdFilesRecursively(dir, basePath = "") {
|
|
33980
|
+
const files = [];
|
|
33981
|
+
const entries = await import_fs_extra10.default.readdir(dir, { withFileTypes: true });
|
|
33982
|
+
for (const entry of entries) {
|
|
33983
|
+
const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;
|
|
33984
|
+
if (entry.isDirectory()) {
|
|
33985
|
+
const subFiles = await getLocalMdFilesRecursively(path12.join(dir, entry.name), relativePath);
|
|
33986
|
+
files.push(...subFiles);
|
|
33987
|
+
} else if (entry.name.endsWith(".md")) {
|
|
33988
|
+
files.push(relativePath);
|
|
33989
|
+
}
|
|
33990
|
+
}
|
|
33991
|
+
return files;
|
|
33992
|
+
}
|
|
33970
33993
|
async function discoverAvailableCommands() {
|
|
33971
33994
|
const commands = {};
|
|
33972
33995
|
const useGitHub = await isGitHubAvailable();
|
|
@@ -33979,8 +34002,7 @@ async function discoverAvailableCommands() {
|
|
|
33979
34002
|
if (!commandsDir) {
|
|
33980
34003
|
throw new Error("Commands directory not found");
|
|
33981
34004
|
}
|
|
33982
|
-
|
|
33983
|
-
mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
34005
|
+
mdFiles = await getLocalMdFilesRecursively(commandsDir);
|
|
33984
34006
|
}
|
|
33985
34007
|
for (const file of mdFiles) {
|
|
33986
34008
|
const commandName = file.replace(".md", "");
|
|
@@ -33988,7 +34010,7 @@ async function discoverAvailableCommands() {
|
|
|
33988
34010
|
const content = await getFileContentWithGitHubFallback("commands", file);
|
|
33989
34011
|
const { metadata } = parseYamlFrontmatter(content);
|
|
33990
34012
|
commands[commandName] = {
|
|
33991
|
-
name: commandName.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()),
|
|
34013
|
+
name: commandName.split("/").map((part) => part.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase())).join("/"),
|
|
33992
34014
|
description: metadata.description || "No description available",
|
|
33993
34015
|
allowedTools: metadata["allowed-tools"],
|
|
33994
34016
|
argumentHint: metadata["argument-hint"],
|
|
@@ -34608,6 +34630,59 @@ class x {
|
|
|
34608
34630
|
}
|
|
34609
34631
|
}
|
|
34610
34632
|
}
|
|
34633
|
+
|
|
34634
|
+
class BD extends x {
|
|
34635
|
+
get cursor() {
|
|
34636
|
+
return this.value ? 0 : 1;
|
|
34637
|
+
}
|
|
34638
|
+
get _value() {
|
|
34639
|
+
return this.cursor === 0;
|
|
34640
|
+
}
|
|
34641
|
+
constructor(u) {
|
|
34642
|
+
super(u, false), this.value = !!u.initialValue, this.on("value", () => {
|
|
34643
|
+
this.value = this._value;
|
|
34644
|
+
}), this.on("confirm", (F) => {
|
|
34645
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = F, this.state = "submit", this.close();
|
|
34646
|
+
}), this.on("cursor", () => {
|
|
34647
|
+
this.value = !this.value;
|
|
34648
|
+
});
|
|
34649
|
+
}
|
|
34650
|
+
}
|
|
34651
|
+
var fD = Object.defineProperty;
|
|
34652
|
+
var gD = (e, u, F) => (u in e) ? fD(e, u, { enumerable: true, configurable: true, writable: true, value: F }) : e[u] = F;
|
|
34653
|
+
var K = (e, u, F) => (gD(e, typeof u != "symbol" ? u + "" : u, F), F);
|
|
34654
|
+
var vD = class extends x {
|
|
34655
|
+
constructor(u) {
|
|
34656
|
+
super(u, false), K(this, "options"), K(this, "cursor", 0), this.options = u.options, this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: F }) => F === u.cursorAt), 0), this.on("key", (F) => {
|
|
34657
|
+
F === "a" && this.toggleAll();
|
|
34658
|
+
}), this.on("cursor", (F) => {
|
|
34659
|
+
switch (F) {
|
|
34660
|
+
case "left":
|
|
34661
|
+
case "up":
|
|
34662
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
34663
|
+
break;
|
|
34664
|
+
case "down":
|
|
34665
|
+
case "right":
|
|
34666
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
34667
|
+
break;
|
|
34668
|
+
case "space":
|
|
34669
|
+
this.toggleValue();
|
|
34670
|
+
break;
|
|
34671
|
+
}
|
|
34672
|
+
});
|
|
34673
|
+
}
|
|
34674
|
+
get _value() {
|
|
34675
|
+
return this.options[this.cursor].value;
|
|
34676
|
+
}
|
|
34677
|
+
toggleAll() {
|
|
34678
|
+
const u = this.value.length === this.options.length;
|
|
34679
|
+
this.value = u ? [] : this.options.map((F) => F.value);
|
|
34680
|
+
}
|
|
34681
|
+
toggleValue() {
|
|
34682
|
+
const u = this.value.includes(this._value);
|
|
34683
|
+
this.value = u ? this.value.filter((F) => F !== this._value) : [...this.value, this._value];
|
|
34684
|
+
}
|
|
34685
|
+
};
|
|
34611
34686
|
var TD = Object.defineProperty;
|
|
34612
34687
|
var jD = (e, u, F) => (u in e) ? TD(e, u, { enumerable: true, configurable: true, writable: true, value: F }) : e[u] = F;
|
|
34613
34688
|
var MD = (e, u, F) => (jD(e, typeof u != "symbol" ? u + "" : u, F), F);
|
|
@@ -34665,7 +34740,7 @@ var H = o("◆", "*");
|
|
|
34665
34740
|
var I2 = o("■", "x");
|
|
34666
34741
|
var x2 = o("▲", "x");
|
|
34667
34742
|
var S2 = o("◇", "o");
|
|
34668
|
-
var
|
|
34743
|
+
var K2 = o("┌", "T");
|
|
34669
34744
|
var a2 = o("│", "|");
|
|
34670
34745
|
var d2 = o("└", "—");
|
|
34671
34746
|
var b2 = o("●", ">");
|
|
@@ -34716,13 +34791,76 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
34716
34791
|
`;
|
|
34717
34792
|
}
|
|
34718
34793
|
} }).prompt();
|
|
34794
|
+
var se = (r2) => {
|
|
34795
|
+
const n = r2.active ?? "Yes", i = r2.inactive ?? "No";
|
|
34796
|
+
return new BD({ active: n, inactive: i, initialValue: r2.initialValue ?? true, render() {
|
|
34797
|
+
const t = `${import_picocolors2.default.gray(a2)}
|
|
34798
|
+
${y2(this.state)} ${r2.message}
|
|
34799
|
+
`, s = this.value ? n : i;
|
|
34800
|
+
switch (this.state) {
|
|
34801
|
+
case "submit":
|
|
34802
|
+
return `${t}${import_picocolors2.default.gray(a2)} ${import_picocolors2.default.dim(s)}`;
|
|
34803
|
+
case "cancel":
|
|
34804
|
+
return `${t}${import_picocolors2.default.gray(a2)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}
|
|
34805
|
+
${import_picocolors2.default.gray(a2)}`;
|
|
34806
|
+
default:
|
|
34807
|
+
return `${t}${import_picocolors2.default.cyan(a2)} ${this.value ? `${import_picocolors2.default.green(b2)} ${n}` : `${import_picocolors2.default.dim(E)} ${import_picocolors2.default.dim(n)}`} ${import_picocolors2.default.dim("/")} ${this.value ? `${import_picocolors2.default.dim(E)} ${import_picocolors2.default.dim(i)}` : `${import_picocolors2.default.green(b2)} ${i}`}
|
|
34808
|
+
${import_picocolors2.default.cyan(d2)}
|
|
34809
|
+
`;
|
|
34810
|
+
}
|
|
34811
|
+
} }).prompt();
|
|
34812
|
+
};
|
|
34813
|
+
var ae = (r2) => {
|
|
34814
|
+
const n = (i, t) => {
|
|
34815
|
+
const s = i.label ?? String(i.value);
|
|
34816
|
+
return t === "active" ? `${import_picocolors2.default.cyan(C)} ${s} ${i.hint ? import_picocolors2.default.dim(`(${i.hint})`) : ""}` : t === "selected" ? `${import_picocolors2.default.green(w2)} ${import_picocolors2.default.dim(s)}` : t === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}` : t === "active-selected" ? `${import_picocolors2.default.green(w2)} ${s} ${i.hint ? import_picocolors2.default.dim(`(${i.hint})`) : ""}` : t === "submitted" ? `${import_picocolors2.default.dim(s)}` : `${import_picocolors2.default.dim(M2)} ${import_picocolors2.default.dim(s)}`;
|
|
34817
|
+
};
|
|
34818
|
+
return new vD({ options: r2.options, initialValues: r2.initialValues, required: r2.required ?? true, cursorAt: r2.cursorAt, validate(i) {
|
|
34819
|
+
if (this.required && i.length === 0)
|
|
34820
|
+
return `Please select at least one option.
|
|
34821
|
+
${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
|
|
34822
|
+
}, render() {
|
|
34823
|
+
let i = `${import_picocolors2.default.gray(a2)}
|
|
34824
|
+
${y2(this.state)} ${r2.message}
|
|
34825
|
+
`;
|
|
34826
|
+
switch (this.state) {
|
|
34827
|
+
case "submit":
|
|
34828
|
+
return `${i}${import_picocolors2.default.gray(a2)} ${this.options.filter(({ value: t }) => this.value.includes(t)).map((t) => n(t, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
|
|
34829
|
+
case "cancel": {
|
|
34830
|
+
const t = this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "cancelled")).join(import_picocolors2.default.dim(", "));
|
|
34831
|
+
return `${i}${import_picocolors2.default.gray(a2)} ${t.trim() ? `${t}
|
|
34832
|
+
${import_picocolors2.default.gray(a2)}` : ""}`;
|
|
34833
|
+
}
|
|
34834
|
+
case "error": {
|
|
34835
|
+
const t = this.error.split(`
|
|
34836
|
+
`).map((s, c2) => c2 === 0 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(s)}` : ` ${s}`).join(`
|
|
34837
|
+
`);
|
|
34838
|
+
return i + import_picocolors2.default.yellow(a2) + " " + this.options.map((s, c2) => {
|
|
34839
|
+
const l2 = this.value.includes(s.value), u = c2 === this.cursor;
|
|
34840
|
+
return u && l2 ? n(s, "active-selected") : l2 ? n(s, "selected") : n(s, u ? "active" : "inactive");
|
|
34841
|
+
}).join(`
|
|
34842
|
+
${import_picocolors2.default.yellow(a2)} `) + `
|
|
34843
|
+
` + t + `
|
|
34844
|
+
`;
|
|
34845
|
+
}
|
|
34846
|
+
default:
|
|
34847
|
+
return `${i}${import_picocolors2.default.cyan(a2)} ${this.options.map((t, s) => {
|
|
34848
|
+
const c2 = this.value.includes(t.value), l2 = s === this.cursor;
|
|
34849
|
+
return l2 && c2 ? n(t, "active-selected") : c2 ? n(t, "selected") : n(t, l2 ? "active" : "inactive");
|
|
34850
|
+
}).join(`
|
|
34851
|
+
${import_picocolors2.default.cyan(a2)} `)}
|
|
34852
|
+
${import_picocolors2.default.cyan(d2)}
|
|
34853
|
+
`;
|
|
34854
|
+
}
|
|
34855
|
+
} }).prompt();
|
|
34856
|
+
};
|
|
34719
34857
|
var ue = (r2 = "") => {
|
|
34720
34858
|
process.stdout.write(`${import_picocolors2.default.gray(d2)} ${import_picocolors2.default.red(r2)}
|
|
34721
34859
|
|
|
34722
34860
|
`);
|
|
34723
34861
|
};
|
|
34724
34862
|
var oe = (r2 = "") => {
|
|
34725
|
-
process.stdout.write(`${import_picocolors2.default.gray(
|
|
34863
|
+
process.stdout.write(`${import_picocolors2.default.gray(K2)} ${r2}
|
|
34726
34864
|
`);
|
|
34727
34865
|
};
|
|
34728
34866
|
var $e = (r2 = "") => {
|
|
@@ -35133,6 +35271,348 @@ async function proUpdateCommand(options = {}) {
|
|
|
35133
35271
|
}
|
|
35134
35272
|
}
|
|
35135
35273
|
|
|
35274
|
+
// src/commands/sync.ts
|
|
35275
|
+
import os11 from "os";
|
|
35276
|
+
import path19 from "path";
|
|
35277
|
+
|
|
35278
|
+
// src/lib/sync-utils.ts
|
|
35279
|
+
var import_fs_extra16 = __toESM(require_lib4(), 1);
|
|
35280
|
+
import path18 from "path";
|
|
35281
|
+
import crypto from "crypto";
|
|
35282
|
+
var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
|
|
35283
|
+
var PREMIUM_BRANCH2 = "main";
|
|
35284
|
+
function computeFileSha(content) {
|
|
35285
|
+
const size = content.length;
|
|
35286
|
+
const header = `blob ${size}\x00`;
|
|
35287
|
+
const fullContent = Buffer.concat([Buffer.from(header), content]);
|
|
35288
|
+
return crypto.createHash("sha1").update(fullContent).digest("hex");
|
|
35289
|
+
}
|
|
35290
|
+
async function listRemoteDirectory(dirPath, githubToken) {
|
|
35291
|
+
const apiUrl = `https://api.github.com/repos/${PREMIUM_REPO2}/contents/claude-code-config/${dirPath}?ref=${PREMIUM_BRANCH2}`;
|
|
35292
|
+
const response = await fetch(apiUrl, {
|
|
35293
|
+
headers: {
|
|
35294
|
+
Authorization: `token ${githubToken}`,
|
|
35295
|
+
Accept: "application/vnd.github.v3+json"
|
|
35296
|
+
}
|
|
35297
|
+
});
|
|
35298
|
+
if (!response.ok) {
|
|
35299
|
+
if (response.status === 404) {
|
|
35300
|
+
return [];
|
|
35301
|
+
}
|
|
35302
|
+
throw new Error(`Failed to list directory ${dirPath}: ${response.status}`);
|
|
35303
|
+
}
|
|
35304
|
+
const files = await response.json();
|
|
35305
|
+
if (!Array.isArray(files)) {
|
|
35306
|
+
return [];
|
|
35307
|
+
}
|
|
35308
|
+
return files;
|
|
35309
|
+
}
|
|
35310
|
+
async function computeLocalFileSha(filePath) {
|
|
35311
|
+
try {
|
|
35312
|
+
const content = await import_fs_extra16.default.readFile(filePath);
|
|
35313
|
+
return computeFileSha(content);
|
|
35314
|
+
} catch {
|
|
35315
|
+
return null;
|
|
35316
|
+
}
|
|
35317
|
+
}
|
|
35318
|
+
async function computeFolderSha(folderPath) {
|
|
35319
|
+
try {
|
|
35320
|
+
if (!await import_fs_extra16.default.pathExists(folderPath)) {
|
|
35321
|
+
return null;
|
|
35322
|
+
}
|
|
35323
|
+
const files = await getAllFilesRecursive(folderPath);
|
|
35324
|
+
if (files.length === 0) {
|
|
35325
|
+
return null;
|
|
35326
|
+
}
|
|
35327
|
+
const hashes = [];
|
|
35328
|
+
for (const file of files.sort()) {
|
|
35329
|
+
const content = await import_fs_extra16.default.readFile(file);
|
|
35330
|
+
hashes.push(computeFileSha(content));
|
|
35331
|
+
}
|
|
35332
|
+
return crypto.createHash("sha1").update(hashes.join("")).digest("hex");
|
|
35333
|
+
} catch {
|
|
35334
|
+
return null;
|
|
35335
|
+
}
|
|
35336
|
+
}
|
|
35337
|
+
async function getAllFilesRecursive(dir) {
|
|
35338
|
+
const files = [];
|
|
35339
|
+
const items = await import_fs_extra16.default.readdir(dir);
|
|
35340
|
+
for (const item of items) {
|
|
35341
|
+
const fullPath = path18.join(dir, item);
|
|
35342
|
+
const stat = await import_fs_extra16.default.stat(fullPath);
|
|
35343
|
+
if (stat.isDirectory()) {
|
|
35344
|
+
const subFiles = await getAllFilesRecursive(fullPath);
|
|
35345
|
+
files.push(...subFiles);
|
|
35346
|
+
} else {
|
|
35347
|
+
files.push(fullPath);
|
|
35348
|
+
}
|
|
35349
|
+
}
|
|
35350
|
+
return files;
|
|
35351
|
+
}
|
|
35352
|
+
async function computeRemoteFolderSha(dirPath, githubToken) {
|
|
35353
|
+
const hashes = [];
|
|
35354
|
+
await collectRemoteFolderHashes(dirPath, githubToken, hashes);
|
|
35355
|
+
hashes.sort();
|
|
35356
|
+
return crypto.createHash("sha1").update(hashes.join("")).digest("hex");
|
|
35357
|
+
}
|
|
35358
|
+
async function collectRemoteFolderHashes(dirPath, githubToken, hashes) {
|
|
35359
|
+
const files = await listRemoteDirectory(dirPath, githubToken);
|
|
35360
|
+
for (const file of files) {
|
|
35361
|
+
if (file.type === "file") {
|
|
35362
|
+
hashes.push(file.sha);
|
|
35363
|
+
} else if (file.type === "dir") {
|
|
35364
|
+
await collectRemoteFolderHashes(`${dirPath}/${file.name}`, githubToken, hashes);
|
|
35365
|
+
}
|
|
35366
|
+
}
|
|
35367
|
+
}
|
|
35368
|
+
async function analyzeSyncChanges(claudeDir, githubToken) {
|
|
35369
|
+
const items = [];
|
|
35370
|
+
const commandsRemote = await listRemoteDirectory("commands", githubToken);
|
|
35371
|
+
for (const file of commandsRemote) {
|
|
35372
|
+
if (file.type === "file" && file.name.endsWith(".md")) {
|
|
35373
|
+
const localPath = path18.join(claudeDir, "commands", file.name);
|
|
35374
|
+
const localSha = await computeLocalFileSha(localPath);
|
|
35375
|
+
let status = "new";
|
|
35376
|
+
if (localSha) {
|
|
35377
|
+
status = localSha === file.sha ? "unchanged" : "modified";
|
|
35378
|
+
}
|
|
35379
|
+
items.push({
|
|
35380
|
+
name: file.name.replace(".md", ""),
|
|
35381
|
+
relativePath: `commands/${file.name}`,
|
|
35382
|
+
type: "file",
|
|
35383
|
+
status,
|
|
35384
|
+
remoteSha: file.sha,
|
|
35385
|
+
localSha: localSha || undefined,
|
|
35386
|
+
category: "commands"
|
|
35387
|
+
});
|
|
35388
|
+
}
|
|
35389
|
+
}
|
|
35390
|
+
const agentsRemote = await listRemoteDirectory("agents", githubToken);
|
|
35391
|
+
for (const file of agentsRemote) {
|
|
35392
|
+
if (file.type === "file" && file.name.endsWith(".md")) {
|
|
35393
|
+
const localPath = path18.join(claudeDir, "agents", file.name);
|
|
35394
|
+
const localSha = await computeLocalFileSha(localPath);
|
|
35395
|
+
let status = "new";
|
|
35396
|
+
if (localSha) {
|
|
35397
|
+
status = localSha === file.sha ? "unchanged" : "modified";
|
|
35398
|
+
}
|
|
35399
|
+
items.push({
|
|
35400
|
+
name: file.name.replace(".md", ""),
|
|
35401
|
+
relativePath: `agents/${file.name}`,
|
|
35402
|
+
type: "file",
|
|
35403
|
+
status,
|
|
35404
|
+
remoteSha: file.sha,
|
|
35405
|
+
localSha: localSha || undefined,
|
|
35406
|
+
category: "agents"
|
|
35407
|
+
});
|
|
35408
|
+
}
|
|
35409
|
+
}
|
|
35410
|
+
const skillsRemote = await listRemoteDirectory("skills", githubToken);
|
|
35411
|
+
if (skillsRemote.length > 0) {
|
|
35412
|
+
const remoteSha = await computeRemoteFolderSha("skills", githubToken);
|
|
35413
|
+
const localSha = await computeFolderSha(path18.join(claudeDir, "skills"));
|
|
35414
|
+
let status = "new";
|
|
35415
|
+
if (localSha) {
|
|
35416
|
+
status = localSha === remoteSha ? "unchanged" : "modified";
|
|
35417
|
+
}
|
|
35418
|
+
items.push({
|
|
35419
|
+
name: "skills",
|
|
35420
|
+
relativePath: "skills",
|
|
35421
|
+
type: "folder",
|
|
35422
|
+
status,
|
|
35423
|
+
remoteSha,
|
|
35424
|
+
localSha: localSha || undefined,
|
|
35425
|
+
category: "skills"
|
|
35426
|
+
});
|
|
35427
|
+
}
|
|
35428
|
+
const scriptsRemote = await listRemoteDirectory("scripts", githubToken);
|
|
35429
|
+
if (scriptsRemote.length > 0) {
|
|
35430
|
+
const remoteSha = await computeRemoteFolderSha("scripts", githubToken);
|
|
35431
|
+
const localSha = await computeFolderSha(path18.join(claudeDir, "scripts"));
|
|
35432
|
+
let status = "new";
|
|
35433
|
+
if (localSha) {
|
|
35434
|
+
status = localSha === remoteSha ? "unchanged" : "modified";
|
|
35435
|
+
}
|
|
35436
|
+
items.push({
|
|
35437
|
+
name: "scripts",
|
|
35438
|
+
relativePath: "scripts",
|
|
35439
|
+
type: "folder",
|
|
35440
|
+
status,
|
|
35441
|
+
remoteSha,
|
|
35442
|
+
localSha: localSha || undefined,
|
|
35443
|
+
category: "scripts"
|
|
35444
|
+
});
|
|
35445
|
+
}
|
|
35446
|
+
return {
|
|
35447
|
+
items,
|
|
35448
|
+
newCount: items.filter((i) => i.status === "new").length,
|
|
35449
|
+
modifiedCount: items.filter((i) => i.status === "modified").length,
|
|
35450
|
+
unchangedCount: items.filter((i) => i.status === "unchanged").length
|
|
35451
|
+
};
|
|
35452
|
+
}
|
|
35453
|
+
async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken) {
|
|
35454
|
+
try {
|
|
35455
|
+
const url = `https://raw.githubusercontent.com/${PREMIUM_REPO2}/${PREMIUM_BRANCH2}/claude-code-config/${relativePath}`;
|
|
35456
|
+
const response = await fetch(url, {
|
|
35457
|
+
headers: {
|
|
35458
|
+
Authorization: `token ${githubToken}`,
|
|
35459
|
+
Accept: "application/vnd.github.v3.raw"
|
|
35460
|
+
}
|
|
35461
|
+
});
|
|
35462
|
+
if (!response.ok) {
|
|
35463
|
+
return false;
|
|
35464
|
+
}
|
|
35465
|
+
const content = await response.arrayBuffer();
|
|
35466
|
+
await import_fs_extra16.default.ensureDir(path18.dirname(targetPath));
|
|
35467
|
+
await import_fs_extra16.default.writeFile(targetPath, Buffer.from(content));
|
|
35468
|
+
return true;
|
|
35469
|
+
} catch {
|
|
35470
|
+
return false;
|
|
35471
|
+
}
|
|
35472
|
+
}
|
|
35473
|
+
async function downloadDirectoryFromPrivateGitHub2(dirPath, targetDir, githubToken) {
|
|
35474
|
+
try {
|
|
35475
|
+
const files = await listRemoteDirectory(dirPath, githubToken);
|
|
35476
|
+
await import_fs_extra16.default.ensureDir(targetDir);
|
|
35477
|
+
for (const file of files) {
|
|
35478
|
+
const relativePath = `${dirPath}/${file.name}`;
|
|
35479
|
+
const targetPath = path18.join(targetDir, file.name);
|
|
35480
|
+
if (file.type === "file") {
|
|
35481
|
+
await downloadFromPrivateGitHub2(relativePath, targetPath, githubToken);
|
|
35482
|
+
} else if (file.type === "dir") {
|
|
35483
|
+
await downloadDirectoryFromPrivateGitHub2(relativePath, targetPath, githubToken);
|
|
35484
|
+
}
|
|
35485
|
+
}
|
|
35486
|
+
return true;
|
|
35487
|
+
} catch {
|
|
35488
|
+
return false;
|
|
35489
|
+
}
|
|
35490
|
+
}
|
|
35491
|
+
async function syncSelectedItems(claudeDir, items, githubToken) {
|
|
35492
|
+
let success = 0;
|
|
35493
|
+
let failed = 0;
|
|
35494
|
+
for (const item of items) {
|
|
35495
|
+
const targetPath = path18.join(claudeDir, item.relativePath);
|
|
35496
|
+
if (item.type === "file") {
|
|
35497
|
+
const ok = await downloadFromPrivateGitHub2(item.relativePath, targetPath, githubToken);
|
|
35498
|
+
if (ok) {
|
|
35499
|
+
success++;
|
|
35500
|
+
} else {
|
|
35501
|
+
failed++;
|
|
35502
|
+
}
|
|
35503
|
+
} else {
|
|
35504
|
+
const ok = await downloadDirectoryFromPrivateGitHub2(item.relativePath, targetPath, githubToken);
|
|
35505
|
+
if (ok) {
|
|
35506
|
+
success++;
|
|
35507
|
+
} else {
|
|
35508
|
+
failed++;
|
|
35509
|
+
}
|
|
35510
|
+
}
|
|
35511
|
+
}
|
|
35512
|
+
return { success, failed };
|
|
35513
|
+
}
|
|
35514
|
+
|
|
35515
|
+
// src/commands/sync.ts
|
|
35516
|
+
async function proSyncCommand(options = {}) {
|
|
35517
|
+
oe(source_default.blue("\uD83D\uDD04 Sync Premium Configurations"));
|
|
35518
|
+
try {
|
|
35519
|
+
const githubToken = await getToken();
|
|
35520
|
+
if (!githubToken) {
|
|
35521
|
+
f2.error("No token found");
|
|
35522
|
+
f2.info("Run: aiblueprint claude-code pro activate <token>");
|
|
35523
|
+
$e(source_default.red("❌ Not activated"));
|
|
35524
|
+
process.exit(1);
|
|
35525
|
+
}
|
|
35526
|
+
const claudeDir = options.folder ? path19.resolve(options.folder) : path19.join(os11.homedir(), ".claude");
|
|
35527
|
+
const spinner = de();
|
|
35528
|
+
spinner.start("Analyzing changes...");
|
|
35529
|
+
const result = await analyzeSyncChanges(claudeDir, githubToken);
|
|
35530
|
+
spinner.stop("Analysis complete");
|
|
35531
|
+
if (result.newCount === 0 && result.modifiedCount === 0) {
|
|
35532
|
+
f2.success("Everything is up to date!");
|
|
35533
|
+
$e(source_default.green("✅ No changes needed"));
|
|
35534
|
+
return;
|
|
35535
|
+
}
|
|
35536
|
+
f2.info(`Found ${result.newCount} new, ${result.modifiedCount} modified, ${result.unchangedCount} unchanged`);
|
|
35537
|
+
const newItems = result.items.filter((i) => i.status === "new");
|
|
35538
|
+
const modifiedItems = result.items.filter((i) => i.status === "modified");
|
|
35539
|
+
const choices = [];
|
|
35540
|
+
if (newItems.length > 0) {
|
|
35541
|
+
for (const item of newItems) {
|
|
35542
|
+
choices.push({
|
|
35543
|
+
value: item,
|
|
35544
|
+
label: `\uD83C\uDD95 ${item.name}`,
|
|
35545
|
+
hint: `${item.category} (new ${item.type})`
|
|
35546
|
+
});
|
|
35547
|
+
}
|
|
35548
|
+
}
|
|
35549
|
+
if (modifiedItems.length > 0) {
|
|
35550
|
+
for (const item of modifiedItems) {
|
|
35551
|
+
choices.push({
|
|
35552
|
+
value: item,
|
|
35553
|
+
label: `\uD83D\uDCDD ${item.name}`,
|
|
35554
|
+
hint: `${item.category} (modified ${item.type})`
|
|
35555
|
+
});
|
|
35556
|
+
}
|
|
35557
|
+
}
|
|
35558
|
+
const selected = await ae({
|
|
35559
|
+
message: "Select items to sync:",
|
|
35560
|
+
options: choices,
|
|
35561
|
+
initialValues: choices.map((c2) => c2.value),
|
|
35562
|
+
required: false
|
|
35563
|
+
});
|
|
35564
|
+
if (lD(selected)) {
|
|
35565
|
+
ue("Sync cancelled");
|
|
35566
|
+
process.exit(0);
|
|
35567
|
+
}
|
|
35568
|
+
const selectedItems = selected;
|
|
35569
|
+
if (selectedItems.length === 0) {
|
|
35570
|
+
f2.warn("No items selected");
|
|
35571
|
+
$e(source_default.yellow("⚠️ Nothing to sync"));
|
|
35572
|
+
return;
|
|
35573
|
+
}
|
|
35574
|
+
const confirmResult = await se({
|
|
35575
|
+
message: `Sync ${selectedItems.length} item(s)?`,
|
|
35576
|
+
initialValue: true
|
|
35577
|
+
});
|
|
35578
|
+
if (lD(confirmResult) || !confirmResult) {
|
|
35579
|
+
ue("Sync cancelled");
|
|
35580
|
+
process.exit(0);
|
|
35581
|
+
}
|
|
35582
|
+
spinner.start(`Syncing ${selectedItems.length} item(s)...`);
|
|
35583
|
+
const syncResult = await syncSelectedItems(claudeDir, selectedItems, githubToken);
|
|
35584
|
+
spinner.stop("Sync complete");
|
|
35585
|
+
if (syncResult.failed > 0) {
|
|
35586
|
+
f2.warn(`${syncResult.success} succeeded, ${syncResult.failed} failed`);
|
|
35587
|
+
} else {
|
|
35588
|
+
f2.success(`${syncResult.success} item(s) synced successfully`);
|
|
35589
|
+
}
|
|
35590
|
+
const syncedByCategory = {
|
|
35591
|
+
commands: selectedItems.filter((i) => i.category === "commands").length,
|
|
35592
|
+
agents: selectedItems.filter((i) => i.category === "agents").length,
|
|
35593
|
+
skills: selectedItems.filter((i) => i.category === "skills").length,
|
|
35594
|
+
scripts: selectedItems.filter((i) => i.category === "scripts").length
|
|
35595
|
+
};
|
|
35596
|
+
const summary = [];
|
|
35597
|
+
if (syncedByCategory.commands > 0)
|
|
35598
|
+
summary.push(`${syncedByCategory.commands} command(s)`);
|
|
35599
|
+
if (syncedByCategory.agents > 0)
|
|
35600
|
+
summary.push(`${syncedByCategory.agents} agent(s)`);
|
|
35601
|
+
if (syncedByCategory.skills > 0)
|
|
35602
|
+
summary.push("skills folder");
|
|
35603
|
+
if (syncedByCategory.scripts > 0)
|
|
35604
|
+
summary.push("scripts folder");
|
|
35605
|
+
f2.info(`Synced: ${summary.join(", ")}`);
|
|
35606
|
+
$e(source_default.green("✅ Sync completed"));
|
|
35607
|
+
} catch (error) {
|
|
35608
|
+
if (error instanceof Error) {
|
|
35609
|
+
f2.error(error.message);
|
|
35610
|
+
}
|
|
35611
|
+
$e(source_default.red("❌ Sync failed"));
|
|
35612
|
+
process.exit(1);
|
|
35613
|
+
}
|
|
35614
|
+
}
|
|
35615
|
+
|
|
35136
35616
|
// src/cli.ts
|
|
35137
35617
|
import { readFileSync as readFileSync2 } from "fs";
|
|
35138
35618
|
import { dirname as dirname4, join } from "path";
|
|
@@ -35197,6 +35677,11 @@ proCmd.command("update").description("Update premium configurations").action((op
|
|
|
35197
35677
|
const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
|
|
35198
35678
|
proUpdateCommand({ folder: claudeCodeFolder });
|
|
35199
35679
|
});
|
|
35680
|
+
proCmd.command("sync").description("Sync premium configurations with selective update").action((options, command) => {
|
|
35681
|
+
const parentOptions = command.parent.parent.opts();
|
|
35682
|
+
const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
|
|
35683
|
+
proSyncCommand({ folder: claudeCodeFolder });
|
|
35684
|
+
});
|
|
35200
35685
|
program2.parse(process.argv);
|
|
35201
35686
|
if (!process.argv.slice(2).length) {
|
|
35202
35687
|
console.log(source_default.blue("\uD83D\uDE80 AIBlueprint CLI"));
|
package/package.json
CHANGED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
allowed-tools: Bash(git :*)
|
|
3
|
-
description: Quick commit and push with minimal, clean messages
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
You are a git commit automation tool. Create minimal, clean commits for a tidy git history.
|
|
7
|
-
|
|
8
|
-
## Workflow
|
|
9
|
-
|
|
10
|
-
1. **Stage**: `git add -A` to stage all changes
|
|
11
|
-
2. **Analyze**: `git diff --cached --stat` to see what changed
|
|
12
|
-
3. **Commit**: Generate ONE-LINE message (max 50 chars):
|
|
13
|
-
- `fix: [what was fixed]`
|
|
14
|
-
- `feat: [what was added]`
|
|
15
|
-
- `update: [what was modified]`
|
|
16
|
-
- `refactor: [what was reorganized]`
|
|
17
|
-
4. **Push**: `git push` immediatelyne
|
|
18
|
-
|
|
19
|
-
## Message Rules
|
|
20
|
-
|
|
21
|
-
- **ONE LINE ONLY** - no body, no details
|
|
22
|
-
- **Under 50 characters** - be concise
|
|
23
|
-
- **No periods** - waste of space
|
|
24
|
-
- **Present tense** - "add" not "added"
|
|
25
|
-
- **Lowercase after colon** - `fix: typo` not `fix: Typo`
|
|
26
|
-
|
|
27
|
-
## Examples
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
feat: add user authentication
|
|
31
|
-
fix: resolve memory leak
|
|
32
|
-
update: improve error handling
|
|
33
|
-
refactor: simplify api routes
|
|
34
|
-
docs: update readme
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Execution
|
|
38
|
-
|
|
39
|
-
- NO interactive commands
|
|
40
|
-
- NO verbose messages
|
|
41
|
-
- NO "Generated with" signatures
|
|
42
|
-
- If no changes, exit silently
|
|
43
|
-
- If push fails, report error only
|
|
44
|
-
|
|
45
|
-
## Priority
|
|
46
|
-
|
|
47
|
-
Speed > Detail. Keep commits atomic and history clean.
|