aiblueprint-cli 1.1.7 → 1.1.8
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 +82 -11
- package/claude-code-config/agents/action.md +36 -0
- package/claude-code-config/agents/explore-codebase.md +6 -1
- package/claude-code-config/agents/explore-docs.md +1 -1
- package/claude-code-config/agents/fix-grammar.md +49 -0
- package/claude-code-config/agents/snipper.md +1 -1
- package/claude-code-config/agents/websearch.md +1 -1
- package/claude-code-config/commands/commit.md +1 -1
- package/claude-code-config/commands/epct/code.md +171 -0
- package/claude-code-config/commands/epct/deploy.md +116 -0
- package/claude-code-config/commands/epct/explore.md +97 -0
- package/claude-code-config/commands/epct/plan.md +132 -0
- package/claude-code-config/commands/epct/tasks.md +206 -0
- package/claude-code-config/commands/melvynx-plugin.md +1 -0
- package/claude-code-config/commands/oneshot.md +57 -0
- package/claude-code-config/hooks/hooks.json +15 -0
- package/claude-code-config/scripts/statusline/CLAUDE.md +178 -0
- package/claude-code-config/scripts/statusline/README.md +105 -0
- package/claude-code-config/scripts/statusline/biome.json +34 -0
- package/claude-code-config/scripts/statusline/bun.lockb +0 -0
- package/claude-code-config/scripts/statusline/data/.gitignore +5 -0
- package/claude-code-config/scripts/statusline/fixtures/test-input.json +25 -0
- package/claude-code-config/scripts/statusline/package.json +21 -0
- package/claude-code-config/scripts/statusline/src/commands/CLAUDE.md +3 -0
- package/claude-code-config/scripts/statusline/src/commands/spend-month.ts +60 -0
- package/claude-code-config/scripts/statusline/src/commands/spend-today.ts +42 -0
- package/claude-code-config/scripts/statusline/src/index.ts +141 -0
- package/claude-code-config/scripts/statusline/src/lib/context.ts +103 -0
- package/claude-code-config/scripts/statusline/src/lib/formatters.ts +218 -0
- package/claude-code-config/scripts/statusline/src/lib/git.ts +100 -0
- package/claude-code-config/scripts/statusline/src/lib/spend.ts +119 -0
- package/claude-code-config/scripts/statusline/src/lib/types.ts +25 -0
- package/claude-code-config/scripts/statusline/src/lib/usage-limits.ts +147 -0
- package/claude-code-config/scripts/statusline/statusline.config.ts +122 -0
- package/claude-code-config/scripts/statusline/test.ts +20 -0
- package/claude-code-config/scripts/statusline/tsconfig.json +27 -0
- package/dist/cli.js +153 -69
- package/package.json +1 -2
- package/claude-code-config/output-styles/assistant.md +0 -15
- package/claude-code-config/output-styles/honnest.md +0 -9
- package/claude-code-config/output-styles/senior-dev.md +0 -14
- package/claude-code-config/scripts/statusline-ccusage.sh +0 -188
- package/claude-code-config/scripts/statusline.readme.md +0 -194
- /package/claude-code-config/{hooks → scripts}/hook-post-file.ts +0 -0
package/dist/cli.js
CHANGED
|
@@ -32361,7 +32361,7 @@ var lib_default = inquirer;
|
|
|
32361
32361
|
|
|
32362
32362
|
// src/commands/setup.ts
|
|
32363
32363
|
var import_fs_extra5 = __toESM(require_lib4(), 1);
|
|
32364
|
-
import
|
|
32364
|
+
import path7 from "path";
|
|
32365
32365
|
import os5 from "os";
|
|
32366
32366
|
|
|
32367
32367
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
@@ -33002,6 +33002,7 @@ async function setupOpenCodeSymlink(claudeDir, customOpenCodeFolder, customClaud
|
|
|
33002
33002
|
|
|
33003
33003
|
// src/commands/setup/dependencies.ts
|
|
33004
33004
|
import { execSync } from "child_process";
|
|
33005
|
+
import path4 from "path";
|
|
33005
33006
|
async function checkAndInstallDependencies() {
|
|
33006
33007
|
const checkCommand = (cmd) => {
|
|
33007
33008
|
try {
|
|
@@ -33030,12 +33031,26 @@ async function checkAndInstallDependencies() {
|
|
|
33030
33031
|
}
|
|
33031
33032
|
}
|
|
33032
33033
|
}
|
|
33034
|
+
async function installStatuslineDependencies(claudeDir) {
|
|
33035
|
+
const statuslineDir = path4.join(claudeDir, "scripts/statusline");
|
|
33036
|
+
console.log(source_default.yellow(`
|
|
33037
|
+
Installing statusline dependencies...`));
|
|
33038
|
+
try {
|
|
33039
|
+
execSync("bun install", {
|
|
33040
|
+
cwd: statuslineDir,
|
|
33041
|
+
stdio: "inherit"
|
|
33042
|
+
});
|
|
33043
|
+
console.log(source_default.green(" ✓ Statusline dependencies installed"));
|
|
33044
|
+
} catch (error) {
|
|
33045
|
+
console.log(source_default.red(" Failed to install statusline dependencies. Please run 'bun install' manually in ~/.claude/scripts/statusline"));
|
|
33046
|
+
}
|
|
33047
|
+
}
|
|
33033
33048
|
|
|
33034
33049
|
// src/commands/setup/settings.ts
|
|
33035
33050
|
var import_fs_extra3 = __toESM(require_lib4(), 1);
|
|
33036
|
-
import
|
|
33051
|
+
import path5 from "path";
|
|
33037
33052
|
async function updateSettings(options, claudeDir) {
|
|
33038
|
-
const settingsPath =
|
|
33053
|
+
const settingsPath = path5.join(claudeDir, "settings.json");
|
|
33039
33054
|
let settings = {};
|
|
33040
33055
|
try {
|
|
33041
33056
|
const existingSettings = await import_fs_extra3.default.readFile(settingsPath, "utf-8");
|
|
@@ -33056,14 +33071,14 @@ async function updateSettings(options, claudeDir) {
|
|
|
33056
33071
|
} else {
|
|
33057
33072
|
settings.statusLine = {
|
|
33058
33073
|
type: "command",
|
|
33059
|
-
command: `
|
|
33074
|
+
command: `bun ${path5.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
33060
33075
|
padding: 0
|
|
33061
33076
|
};
|
|
33062
33077
|
}
|
|
33063
33078
|
} else {
|
|
33064
33079
|
settings.statusLine = {
|
|
33065
33080
|
type: "command",
|
|
33066
|
-
command: `
|
|
33081
|
+
command: `bun ${path5.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
33067
33082
|
padding: 0
|
|
33068
33083
|
};
|
|
33069
33084
|
}
|
|
@@ -33080,7 +33095,7 @@ async function updateSettings(options, claudeDir) {
|
|
|
33080
33095
|
hooks: [
|
|
33081
33096
|
{
|
|
33082
33097
|
type: "command",
|
|
33083
|
-
command: `bun ${
|
|
33098
|
+
command: `bun ${path5.join(claudeDir, "scripts/validate-command.js")}`
|
|
33084
33099
|
}
|
|
33085
33100
|
]
|
|
33086
33101
|
};
|
|
@@ -33098,7 +33113,7 @@ async function updateSettings(options, claudeDir) {
|
|
|
33098
33113
|
hooks: [
|
|
33099
33114
|
{
|
|
33100
33115
|
type: "command",
|
|
33101
|
-
command: `afplay -v 0.1 ${
|
|
33116
|
+
command: `afplay -v 0.1 ${path5.join(claudeDir, "song/finish.mp3")}`
|
|
33102
33117
|
}
|
|
33103
33118
|
]
|
|
33104
33119
|
};
|
|
@@ -33114,7 +33129,7 @@ async function updateSettings(options, claudeDir) {
|
|
|
33114
33129
|
hooks: [
|
|
33115
33130
|
{
|
|
33116
33131
|
type: "command",
|
|
33117
|
-
command: `afplay -v 0.1 ${
|
|
33132
|
+
command: `afplay -v 0.1 ${path5.join(claudeDir, "song/need-human.mp3")}`
|
|
33118
33133
|
}
|
|
33119
33134
|
]
|
|
33120
33135
|
};
|
|
@@ -33123,12 +33138,30 @@ async function updateSettings(options, claudeDir) {
|
|
|
33123
33138
|
settings.hooks.Notification.push(notificationHook);
|
|
33124
33139
|
}
|
|
33125
33140
|
}
|
|
33141
|
+
if (options.postEditTypeScript) {
|
|
33142
|
+
if (!settings.hooks.PostToolUse) {
|
|
33143
|
+
settings.hooks.PostToolUse = [];
|
|
33144
|
+
}
|
|
33145
|
+
const postEditHook = {
|
|
33146
|
+
matcher: "Edit|Write|MultiEdit",
|
|
33147
|
+
hooks: [
|
|
33148
|
+
{
|
|
33149
|
+
type: "command",
|
|
33150
|
+
command: `bun ${path5.join(claudeDir, "scripts/hook-post-file.ts")}`
|
|
33151
|
+
}
|
|
33152
|
+
]
|
|
33153
|
+
};
|
|
33154
|
+
const existingPostEditHook = settings.hooks.PostToolUse.find((h) => h.matcher === "Edit|Write|MultiEdit" && h.hooks?.some((hook) => hook.command?.includes("hook-post-file.ts")));
|
|
33155
|
+
if (!existingPostEditHook) {
|
|
33156
|
+
settings.hooks.PostToolUse.push(postEditHook);
|
|
33157
|
+
}
|
|
33158
|
+
}
|
|
33126
33159
|
await import_fs_extra3.default.writeJson(settingsPath, settings, { spaces: 2 });
|
|
33127
33160
|
}
|
|
33128
33161
|
|
|
33129
33162
|
// src/commands/setup/utils.ts
|
|
33130
33163
|
var import_fs_extra4 = __toESM(require_lib4(), 1);
|
|
33131
|
-
import
|
|
33164
|
+
import path6 from "path";
|
|
33132
33165
|
|
|
33133
33166
|
class SimpleSpinner {
|
|
33134
33167
|
message = "";
|
|
@@ -33149,7 +33182,7 @@ async function downloadFromGitHub(relativePath, targetPath) {
|
|
|
33149
33182
|
return false;
|
|
33150
33183
|
}
|
|
33151
33184
|
const content = await response.arrayBuffer();
|
|
33152
|
-
await import_fs_extra4.default.ensureDir(
|
|
33185
|
+
await import_fs_extra4.default.ensureDir(path6.dirname(targetPath));
|
|
33153
33186
|
await import_fs_extra4.default.writeFile(targetPath, Buffer.from(content));
|
|
33154
33187
|
return true;
|
|
33155
33188
|
} catch (error) {
|
|
@@ -33170,7 +33203,7 @@ async function downloadDirectoryFromGitHub(dirPath, targetDir) {
|
|
|
33170
33203
|
await import_fs_extra4.default.ensureDir(targetDir);
|
|
33171
33204
|
for (const file of files) {
|
|
33172
33205
|
const relativePath = `${dirPath}/${file.name}`;
|
|
33173
|
-
const targetPath =
|
|
33206
|
+
const targetPath = path6.join(targetDir, file.name);
|
|
33174
33207
|
if (file.type === "file") {
|
|
33175
33208
|
await downloadFromGitHub(relativePath, targetPath);
|
|
33176
33209
|
} else if (file.type === "dir") {
|
|
@@ -33207,7 +33240,6 @@ async function setupCommand(params = {}) {
|
|
|
33207
33240
|
"customStatusline",
|
|
33208
33241
|
"aiblueprintCommands",
|
|
33209
33242
|
"aiblueprintAgents",
|
|
33210
|
-
"outputStyles",
|
|
33211
33243
|
"notificationSounds",
|
|
33212
33244
|
"codexSymlink",
|
|
33213
33245
|
"openCodeSymlink"
|
|
@@ -33245,16 +33277,16 @@ async function setupCommand(params = {}) {
|
|
|
33245
33277
|
name: "AIBlueprint agents - Specialized AI agents",
|
|
33246
33278
|
checked: true
|
|
33247
33279
|
},
|
|
33248
|
-
{
|
|
33249
|
-
value: "outputStyles",
|
|
33250
|
-
name: "Output styles - Custom output formatting",
|
|
33251
|
-
checked: true
|
|
33252
|
-
},
|
|
33253
33280
|
{
|
|
33254
33281
|
value: "notificationSounds",
|
|
33255
33282
|
name: "Notification sounds - Audio alerts for events",
|
|
33256
33283
|
checked: true
|
|
33257
33284
|
},
|
|
33285
|
+
{
|
|
33286
|
+
value: "postEditTypeScript",
|
|
33287
|
+
name: "Post-edit TypeScript hook - Auto-format and lint TypeScript files",
|
|
33288
|
+
checked: false
|
|
33289
|
+
},
|
|
33258
33290
|
{
|
|
33259
33291
|
value: "codexSymlink",
|
|
33260
33292
|
name: "Codex symlink - Link commands to ~/.codex/prompts",
|
|
@@ -33280,13 +33312,13 @@ async function setupCommand(params = {}) {
|
|
|
33280
33312
|
customStatusline: features.includes("customStatusline"),
|
|
33281
33313
|
aiblueprintCommands: features.includes("aiblueprintCommands"),
|
|
33282
33314
|
aiblueprintAgents: features.includes("aiblueprintAgents"),
|
|
33283
|
-
outputStyles: features.includes("outputStyles"),
|
|
33284
33315
|
notificationSounds: features.includes("notificationSounds"),
|
|
33316
|
+
postEditTypeScript: features.includes("postEditTypeScript"),
|
|
33285
33317
|
codexSymlink: features.includes("codexSymlink"),
|
|
33286
33318
|
openCodeSymlink: features.includes("openCodeSymlink")
|
|
33287
33319
|
};
|
|
33288
33320
|
const s = new SimpleSpinner;
|
|
33289
|
-
const claudeDir = customClaudeCodeFolder ?
|
|
33321
|
+
const claudeDir = customClaudeCodeFolder ? path7.resolve(customClaudeCodeFolder) : path7.join(os5.homedir(), ".claude");
|
|
33290
33322
|
console.log(source_default.gray(`Installing to: ${claudeDir}`));
|
|
33291
33323
|
await import_fs_extra5.default.ensureDir(claudeDir);
|
|
33292
33324
|
let useGitHub = true;
|
|
@@ -33301,10 +33333,10 @@ async function setupCommand(params = {}) {
|
|
|
33301
33333
|
if (!useGitHub) {
|
|
33302
33334
|
const currentDir = process.cwd();
|
|
33303
33335
|
const possiblePaths = [
|
|
33304
|
-
|
|
33305
|
-
|
|
33306
|
-
|
|
33307
|
-
|
|
33336
|
+
path7.join(currentDir, "claude-code-config"),
|
|
33337
|
+
path7.join(__dirname2, "../../claude-code-config"),
|
|
33338
|
+
path7.join(__dirname2, "../claude-code-config"),
|
|
33339
|
+
path7.join(path7.dirname(process.argv[1]), "../claude-code-config")
|
|
33308
33340
|
];
|
|
33309
33341
|
sourceDir = possiblePaths.find((p) => {
|
|
33310
33342
|
try {
|
|
@@ -33325,31 +33357,35 @@ async function setupCommand(params = {}) {
|
|
|
33325
33357
|
await setupShellShortcuts();
|
|
33326
33358
|
s.stop("Shell shortcuts configured");
|
|
33327
33359
|
}
|
|
33328
|
-
if (options.commandValidation || options.customStatusline || options.notificationSounds) {
|
|
33360
|
+
if (options.commandValidation || options.customStatusline || options.notificationSounds || options.postEditTypeScript) {
|
|
33329
33361
|
s.start("Setting up scripts");
|
|
33330
33362
|
if (useGitHub) {
|
|
33331
|
-
const scriptsDir =
|
|
33363
|
+
const scriptsDir = path7.join(claudeDir, "scripts");
|
|
33332
33364
|
await import_fs_extra5.default.ensureDir(scriptsDir);
|
|
33333
33365
|
const scriptFiles = [
|
|
33334
33366
|
"validate-command.js",
|
|
33335
|
-
"
|
|
33336
|
-
"validate-command.readme.md",
|
|
33337
|
-
"statusline.readme.md"
|
|
33367
|
+
"validate-command.readme.md"
|
|
33338
33368
|
];
|
|
33369
|
+
if (options.postEditTypeScript) {
|
|
33370
|
+
scriptFiles.push("hook-post-file.ts");
|
|
33371
|
+
}
|
|
33339
33372
|
for (const file of scriptFiles) {
|
|
33340
|
-
await downloadFromGitHub(`scripts/${file}`,
|
|
33373
|
+
await downloadFromGitHub(`scripts/${file}`, path7.join(scriptsDir, file));
|
|
33374
|
+
}
|
|
33375
|
+
if (options.customStatusline) {
|
|
33376
|
+
await downloadDirectoryFromGitHub("scripts/statusline", path7.join(scriptsDir, "statusline"));
|
|
33341
33377
|
}
|
|
33342
33378
|
} else {
|
|
33343
|
-
await import_fs_extra5.default.copy(
|
|
33379
|
+
await import_fs_extra5.default.copy(path7.join(sourceDir, "scripts"), path7.join(claudeDir, "scripts"), { overwrite: true });
|
|
33344
33380
|
}
|
|
33345
33381
|
s.stop("Scripts installed");
|
|
33346
33382
|
}
|
|
33347
33383
|
if (options.aiblueprintCommands) {
|
|
33348
33384
|
s.start("Setting up AIBlueprint commands");
|
|
33349
33385
|
if (useGitHub) {
|
|
33350
|
-
await downloadDirectoryFromGitHub("commands",
|
|
33386
|
+
await downloadDirectoryFromGitHub("commands", path7.join(claudeDir, "commands"));
|
|
33351
33387
|
} else {
|
|
33352
|
-
await import_fs_extra5.default.copy(
|
|
33388
|
+
await import_fs_extra5.default.copy(path7.join(sourceDir, "commands"), path7.join(claudeDir, "commands"), { overwrite: true });
|
|
33353
33389
|
}
|
|
33354
33390
|
s.stop("Commands installed");
|
|
33355
33391
|
}
|
|
@@ -33366,30 +33402,21 @@ async function setupCommand(params = {}) {
|
|
|
33366
33402
|
if (options.aiblueprintAgents) {
|
|
33367
33403
|
s.start("Setting up AIBlueprint agents");
|
|
33368
33404
|
if (useGitHub) {
|
|
33369
|
-
await downloadDirectoryFromGitHub("agents",
|
|
33405
|
+
await downloadDirectoryFromGitHub("agents", path7.join(claudeDir, "agents"));
|
|
33370
33406
|
} else {
|
|
33371
|
-
await import_fs_extra5.default.copy(
|
|
33407
|
+
await import_fs_extra5.default.copy(path7.join(sourceDir, "agents"), path7.join(claudeDir, "agents"), { overwrite: true });
|
|
33372
33408
|
}
|
|
33373
33409
|
s.stop("Agents installed");
|
|
33374
33410
|
}
|
|
33375
|
-
if (options.outputStyles) {
|
|
33376
|
-
s.start("Setting up output styles");
|
|
33377
|
-
if (useGitHub) {
|
|
33378
|
-
await downloadDirectoryFromGitHub("output-styles", path6.join(claudeDir, "output-styles"));
|
|
33379
|
-
} else {
|
|
33380
|
-
await import_fs_extra5.default.copy(path6.join(sourceDir, "output-styles"), path6.join(claudeDir, "output-styles"), { overwrite: true });
|
|
33381
|
-
}
|
|
33382
|
-
s.stop("Output styles installed");
|
|
33383
|
-
}
|
|
33384
33411
|
if (options.notificationSounds) {
|
|
33385
33412
|
s.start("Setting up notification sounds");
|
|
33386
33413
|
if (useGitHub) {
|
|
33387
|
-
const songDir =
|
|
33414
|
+
const songDir = path7.join(claudeDir, "song");
|
|
33388
33415
|
await import_fs_extra5.default.ensureDir(songDir);
|
|
33389
|
-
await downloadFromGitHub("song/finish.mp3",
|
|
33390
|
-
await downloadFromGitHub("song/need-human.mp3",
|
|
33416
|
+
await downloadFromGitHub("song/finish.mp3", path7.join(songDir, "finish.mp3"));
|
|
33417
|
+
await downloadFromGitHub("song/need-human.mp3", path7.join(songDir, "need-human.mp3"));
|
|
33391
33418
|
} else {
|
|
33392
|
-
await import_fs_extra5.default.copy(
|
|
33419
|
+
await import_fs_extra5.default.copy(path7.join(sourceDir, "song"), path7.join(claudeDir, "song"), { overwrite: true });
|
|
33393
33420
|
}
|
|
33394
33421
|
s.stop("Notification sounds installed");
|
|
33395
33422
|
}
|
|
@@ -33397,6 +33424,9 @@ async function setupCommand(params = {}) {
|
|
|
33397
33424
|
s.start("Checking dependencies");
|
|
33398
33425
|
await checkAndInstallDependencies();
|
|
33399
33426
|
s.stop("Dependencies checked");
|
|
33427
|
+
s.start("Installing statusline dependencies");
|
|
33428
|
+
await installStatuslineDependencies(claudeDir);
|
|
33429
|
+
s.stop("Statusline dependencies installed");
|
|
33400
33430
|
}
|
|
33401
33431
|
s.start("Updating settings.json");
|
|
33402
33432
|
await updateSettings(options, claudeDir);
|
|
@@ -33420,13 +33450,13 @@ Next steps:`));
|
|
|
33420
33450
|
|
|
33421
33451
|
// src/commands/addHook.ts
|
|
33422
33452
|
var import_fs_extra9 = __toESM(require_lib4(), 1);
|
|
33423
|
-
import
|
|
33453
|
+
import path11 from "path";
|
|
33424
33454
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
33425
33455
|
import { dirname as dirname3 } from "path";
|
|
33426
33456
|
|
|
33427
33457
|
// src/utils/claude-config.ts
|
|
33428
33458
|
var import_fs_extra6 = __toESM(require_lib4(), 1);
|
|
33429
|
-
import
|
|
33459
|
+
import path8 from "path";
|
|
33430
33460
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
33431
33461
|
import { dirname as dirname2 } from "path";
|
|
33432
33462
|
var __filename3 = fileURLToPath2(import.meta.url);
|
|
@@ -33457,8 +33487,8 @@ function parseYamlFrontmatter(content) {
|
|
|
33457
33487
|
}
|
|
33458
33488
|
function getLocalConfigPaths(subDir) {
|
|
33459
33489
|
return [
|
|
33460
|
-
|
|
33461
|
-
|
|
33490
|
+
path8.join(__dirname3, `../claude-code-config/${subDir}`),
|
|
33491
|
+
path8.join(__dirname3, `../../claude-code-config/${subDir}`)
|
|
33462
33492
|
];
|
|
33463
33493
|
}
|
|
33464
33494
|
async function findLocalConfigDir(subDir) {
|
|
@@ -33475,22 +33505,22 @@ async function getTargetDirectory(options) {
|
|
|
33475
33505
|
return options.folder;
|
|
33476
33506
|
}
|
|
33477
33507
|
const cwd = process.cwd();
|
|
33478
|
-
const localClaudeDir =
|
|
33479
|
-
const isGitRepo = await import_fs_extra6.default.pathExists(
|
|
33508
|
+
const localClaudeDir = path8.join(cwd, ".claude");
|
|
33509
|
+
const isGitRepo = await import_fs_extra6.default.pathExists(path8.join(cwd, ".git"));
|
|
33480
33510
|
const hasClaudeConfig = await import_fs_extra6.default.pathExists(localClaudeDir);
|
|
33481
33511
|
if (isGitRepo || hasClaudeConfig) {
|
|
33482
33512
|
return localClaudeDir;
|
|
33483
33513
|
}
|
|
33484
|
-
return
|
|
33514
|
+
return path8.join(process.env.HOME || process.env.USERPROFILE || "~", ".claude");
|
|
33485
33515
|
}
|
|
33486
33516
|
|
|
33487
33517
|
// src/utils/file-installer.ts
|
|
33488
33518
|
var import_fs_extra8 = __toESM(require_lib4(), 1);
|
|
33489
|
-
import
|
|
33519
|
+
import path10 from "path";
|
|
33490
33520
|
|
|
33491
33521
|
// src/utils/github.ts
|
|
33492
33522
|
var import_fs_extra7 = __toESM(require_lib4(), 1);
|
|
33493
|
-
import
|
|
33523
|
+
import path9 from "path";
|
|
33494
33524
|
var GITHUB_RAW_BASE3 = "https://raw.githubusercontent.com/Melvynx/aiblueprint-cli/main/claude-code-config";
|
|
33495
33525
|
async function downloadFromGitHub2(relativePath) {
|
|
33496
33526
|
try {
|
|
@@ -33529,7 +33559,7 @@ async function isGitHubAvailable() {
|
|
|
33529
33559
|
async function downloadAndWriteFile(relativePath, targetPath) {
|
|
33530
33560
|
const content = await downloadFromGitHub2(relativePath);
|
|
33531
33561
|
if (content) {
|
|
33532
|
-
await import_fs_extra7.default.ensureDir(
|
|
33562
|
+
await import_fs_extra7.default.ensureDir(path9.dirname(targetPath));
|
|
33533
33563
|
await import_fs_extra7.default.writeFile(targetPath, content);
|
|
33534
33564
|
return true;
|
|
33535
33565
|
}
|
|
@@ -33539,7 +33569,7 @@ async function downloadAndWriteFile(relativePath, targetPath) {
|
|
|
33539
33569
|
// src/utils/file-installer.ts
|
|
33540
33570
|
async function installFileWithGitHubFallback(options) {
|
|
33541
33571
|
const { sourceDir, targetPath, fileName } = options;
|
|
33542
|
-
await import_fs_extra8.default.ensureDir(
|
|
33572
|
+
await import_fs_extra8.default.ensureDir(path10.dirname(targetPath));
|
|
33543
33573
|
const useGitHub = options.useGitHub ?? await isGitHubAvailable();
|
|
33544
33574
|
if (useGitHub) {
|
|
33545
33575
|
const relativePath = `${sourceDir}/${fileName}`;
|
|
@@ -33553,7 +33583,7 @@ async function installFileWithGitHubFallback(options) {
|
|
|
33553
33583
|
if (!localConfigDir) {
|
|
33554
33584
|
throw new Error(`Neither GitHub nor local ${sourceDir} directory found`);
|
|
33555
33585
|
}
|
|
33556
|
-
const localFilePath =
|
|
33586
|
+
const localFilePath = path10.join(localConfigDir, fileName);
|
|
33557
33587
|
if (!await import_fs_extra8.default.pathExists(localFilePath)) {
|
|
33558
33588
|
throw new Error(`File not found: ${fileName}`);
|
|
33559
33589
|
}
|
|
@@ -33572,7 +33602,7 @@ async function getFileContentWithGitHubFallback(sourceDir, fileName) {
|
|
|
33572
33602
|
if (!localConfigDir) {
|
|
33573
33603
|
throw new Error(`Neither GitHub nor local ${sourceDir} directory found`);
|
|
33574
33604
|
}
|
|
33575
|
-
const localFilePath =
|
|
33605
|
+
const localFilePath = path10.join(localConfigDir, fileName);
|
|
33576
33606
|
if (!await import_fs_extra8.default.pathExists(localFilePath)) {
|
|
33577
33607
|
throw new Error(`File not found: ${fileName}`);
|
|
33578
33608
|
}
|
|
@@ -33598,6 +33628,8 @@ var supportedHooks = {
|
|
|
33598
33628
|
name: "Post Edit TypeScript Hook",
|
|
33599
33629
|
description: "Runs Prettier, ESLint, and TypeScript checks after editing TypeScript files",
|
|
33600
33630
|
hookFile: "hook-post-file.ts",
|
|
33631
|
+
sourceDir: "scripts",
|
|
33632
|
+
targetDir: "scripts",
|
|
33601
33633
|
event: "PostToolUse",
|
|
33602
33634
|
matcher: "Edit|Write|MultiEdit"
|
|
33603
33635
|
}
|
|
@@ -33616,9 +33648,9 @@ async function addHookCommand(hookType, options) {
|
|
|
33616
33648
|
const s = new SimpleSpinner2;
|
|
33617
33649
|
const targetDir = await getTargetDirectory(options);
|
|
33618
33650
|
const claudeDir = targetDir;
|
|
33619
|
-
const
|
|
33620
|
-
const hookFilePath =
|
|
33621
|
-
const settingsPath =
|
|
33651
|
+
const targetHookDir = path11.join(claudeDir, hook.targetDir || "hooks");
|
|
33652
|
+
const hookFilePath = path11.join(targetHookDir, hook.hookFile);
|
|
33653
|
+
const settingsPath = path11.join(claudeDir, "settings.json");
|
|
33622
33654
|
if (await import_fs_extra9.default.pathExists(hookFilePath)) {
|
|
33623
33655
|
const overwriteAnswer = await lib_default.prompt([{
|
|
33624
33656
|
type: "confirm",
|
|
@@ -33632,9 +33664,9 @@ async function addHookCommand(hookType, options) {
|
|
|
33632
33664
|
}
|
|
33633
33665
|
try {
|
|
33634
33666
|
s.start("Installing hook...");
|
|
33635
|
-
await import_fs_extra9.default.ensureDir(
|
|
33667
|
+
await import_fs_extra9.default.ensureDir(targetHookDir);
|
|
33636
33668
|
await installFileWithGitHubFallback({
|
|
33637
|
-
sourceDir: "hooks",
|
|
33669
|
+
sourceDir: hook.sourceDir || "hooks",
|
|
33638
33670
|
targetPath: hookFilePath,
|
|
33639
33671
|
fileName: hook.hookFile
|
|
33640
33672
|
});
|
|
@@ -33659,7 +33691,7 @@ async function addHookCommand(hookType, options) {
|
|
|
33659
33691
|
hooks: [
|
|
33660
33692
|
{
|
|
33661
33693
|
type: "command",
|
|
33662
|
-
command: `bun $CLAUDE_PROJECT_DIR/.claude
|
|
33694
|
+
command: `bun $CLAUDE_PROJECT_DIR/.claude/${hook.targetDir || "hooks"}/${hook.hookFile}`
|
|
33663
33695
|
}
|
|
33664
33696
|
]
|
|
33665
33697
|
};
|
|
@@ -33700,7 +33732,7 @@ The hook will run automatically when you edit TypeScript files with Claude Code.
|
|
|
33700
33732
|
|
|
33701
33733
|
// src/commands/addCommand.ts
|
|
33702
33734
|
var import_fs_extra10 = __toESM(require_lib4(), 1);
|
|
33703
|
-
import
|
|
33735
|
+
import path12 from "path";
|
|
33704
33736
|
class SimpleSpinner3 {
|
|
33705
33737
|
message = "";
|
|
33706
33738
|
start(message) {
|
|
@@ -33784,8 +33816,8 @@ async function addCommandCommand(commandName, options = {}) {
|
|
|
33784
33816
|
if (options.folder) {
|
|
33785
33817
|
console.log(source_default.gray(`Using custom folder: ${targetDir}`));
|
|
33786
33818
|
}
|
|
33787
|
-
const commandsDir =
|
|
33788
|
-
const commandFilePath =
|
|
33819
|
+
const commandsDir = path12.join(targetDir, "commands");
|
|
33820
|
+
const commandFilePath = path12.join(commandsDir, command.commandFile);
|
|
33789
33821
|
if (await import_fs_extra10.default.pathExists(commandFilePath)) {
|
|
33790
33822
|
const overwriteAnswer = await lib_default.prompt([{
|
|
33791
33823
|
type: "confirm",
|
|
@@ -33992,6 +34024,53 @@ async function symlinkCommand(params = {}) {
|
|
|
33992
34024
|
}
|
|
33993
34025
|
}
|
|
33994
34026
|
|
|
34027
|
+
// src/commands/statusline.ts
|
|
34028
|
+
var import_fs_extra11 = __toESM(require_lib4(), 1);
|
|
34029
|
+
import path13 from "path";
|
|
34030
|
+
import { homedir } from "os";
|
|
34031
|
+
async function statuslineCommand(options) {
|
|
34032
|
+
const claudeDir = options.folder ? path13.resolve(options.folder) : path13.join(homedir(), ".claude");
|
|
34033
|
+
console.log(source_default.blue("\uD83D\uDE80 Setting up AIBlueprint Statusline..."));
|
|
34034
|
+
console.log(source_default.gray(` Target: ${claudeDir}
|
|
34035
|
+
`));
|
|
34036
|
+
await import_fs_extra11.default.ensureDir(claudeDir);
|
|
34037
|
+
console.log(source_default.cyan("\uD83D\uDCE6 Checking dependencies..."));
|
|
34038
|
+
await checkAndInstallDependencies();
|
|
34039
|
+
console.log(source_default.cyan(`
|
|
34040
|
+
\uD83D\uDCE5 Downloading statusline files...`));
|
|
34041
|
+
const scriptsDir = path13.join(claudeDir, "scripts");
|
|
34042
|
+
await import_fs_extra11.default.ensureDir(scriptsDir);
|
|
34043
|
+
const success = await downloadDirectoryFromGitHub("scripts/statusline", path13.join(scriptsDir, "statusline"));
|
|
34044
|
+
if (!success) {
|
|
34045
|
+
console.log(source_default.red(" Failed to download statusline files from GitHub"));
|
|
34046
|
+
return;
|
|
34047
|
+
}
|
|
34048
|
+
console.log(source_default.cyan(`
|
|
34049
|
+
\uD83D\uDCE6 Installing statusline dependencies...`));
|
|
34050
|
+
await installStatuslineDependencies(claudeDir);
|
|
34051
|
+
console.log(source_default.cyan(`
|
|
34052
|
+
⚙️ Configuring settings.json...`));
|
|
34053
|
+
const settingsPath = path13.join(claudeDir, "settings.json");
|
|
34054
|
+
let settings = {};
|
|
34055
|
+
try {
|
|
34056
|
+
const existingSettings = await import_fs_extra11.default.readFile(settingsPath, "utf-8");
|
|
34057
|
+
settings = JSON.parse(existingSettings);
|
|
34058
|
+
} catch {
|
|
34059
|
+
}
|
|
34060
|
+
settings.statusLine = {
|
|
34061
|
+
type: "command",
|
|
34062
|
+
command: `bun ${path13.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
34063
|
+
padding: 0
|
|
34064
|
+
};
|
|
34065
|
+
await import_fs_extra11.default.writeJson(settingsPath, settings, { spaces: 2 });
|
|
34066
|
+
console.log(source_default.green(`
|
|
34067
|
+
✅ Statusline setup complete!`));
|
|
34068
|
+
console.log(source_default.gray(`
|
|
34069
|
+
Your Claude Code statusline is now configured.`));
|
|
34070
|
+
console.log(source_default.gray(`Restart Claude Code to see the changes.
|
|
34071
|
+
`));
|
|
34072
|
+
}
|
|
34073
|
+
|
|
33995
34074
|
// src/cli.ts
|
|
33996
34075
|
import { readFileSync as readFileSync2 } from "fs";
|
|
33997
34076
|
import { dirname as dirname4, join } from "path";
|
|
@@ -34034,6 +34113,11 @@ claudeCodeCmd.command("symlink").description("Create symlinks between different
|
|
|
34034
34113
|
factoryAiFolder: parentOptions.factoryAiFolder
|
|
34035
34114
|
});
|
|
34036
34115
|
});
|
|
34116
|
+
claudeCodeCmd.command("statusline").description("Setup custom statusline with git status, costs, and token usage").action((options, command) => {
|
|
34117
|
+
const parentOptions = command.parent.opts();
|
|
34118
|
+
const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
|
|
34119
|
+
statuslineCommand({ folder: claudeCodeFolder });
|
|
34120
|
+
});
|
|
34037
34121
|
program2.parse(process.argv);
|
|
34038
34122
|
if (!process.argv.slice(2).length) {
|
|
34039
34123
|
console.log(source_default.blue("\uD83D\uDE80 AIBlueprint CLI"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiblueprint-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "AIBlueprint CLI for setting up Claude Code configurations",
|
|
5
5
|
"author": "AIBlueprint",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,7 +47,6 @@
|
|
|
47
47
|
"keywords": [
|
|
48
48
|
"claude",
|
|
49
49
|
"claude-code",
|
|
50
|
-
"cli",
|
|
51
50
|
"aiblueprint",
|
|
52
51
|
"developer-tools"
|
|
53
52
|
]
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Assistant
|
|
3
|
-
description: Helpful assistant that help me work on my todos, my week planing, my tasks
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
You are a professional assistant name "Bob".
|
|
7
|
-
|
|
8
|
-
Communicate like you're talking to an old friend.
|
|
9
|
-
|
|
10
|
-
- Always be honest and don't be afraid to hurt me.
|
|
11
|
-
- Schedule my week like a professional assistant by doing what I ask you.
|
|
12
|
-
- Challenge my organization if you see something wrong.
|
|
13
|
-
- Always try to optimize my tasks.
|
|
14
|
-
- Write in a friendly style, like you're talking to a friend.
|
|
15
|
-
- Don't use emojis.
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Honest Friend
|
|
3
|
-
description: You are my childhood friend who is now a successful businessman
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
- You are a really good friend of mine
|
|
7
|
-
- You are honest with me; when something is not good, you can tell me without feeling bad
|
|
8
|
-
- You don't need to be friendly with me; honesty is more important because you know me well
|
|
9
|
-
- You write like we are in Whats'app messages
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: senior-dev
|
|
3
|
-
description: Casual, direct communication like talking with senior engineering teammates
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
Communicate like you're talking with a senior engineering team member:
|
|
7
|
-
|
|
8
|
-
- Keep it casual and conversational - no formal language or corporate speak
|
|
9
|
-
- Be direct and straight to the point - no long explanations unless absolutely needed
|
|
10
|
-
- Don't use uppercase for emphasis - just normal sentence case.
|
|
11
|
-
- IMPORTANT : Never use Uppercase, write in lowercase.
|
|
12
|
-
- IMPORTANT : Never use emojis. Write straight.
|
|
13
|
-
- Assume the person knows their stuff - don't over-explain basic concepts
|
|
14
|
-
- When something is wrong, just say it's wrong - no need to soften it
|