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.
Files changed (44) hide show
  1. package/README.md +82 -11
  2. package/claude-code-config/agents/action.md +36 -0
  3. package/claude-code-config/agents/explore-codebase.md +6 -1
  4. package/claude-code-config/agents/explore-docs.md +1 -1
  5. package/claude-code-config/agents/fix-grammar.md +49 -0
  6. package/claude-code-config/agents/snipper.md +1 -1
  7. package/claude-code-config/agents/websearch.md +1 -1
  8. package/claude-code-config/commands/commit.md +1 -1
  9. package/claude-code-config/commands/epct/code.md +171 -0
  10. package/claude-code-config/commands/epct/deploy.md +116 -0
  11. package/claude-code-config/commands/epct/explore.md +97 -0
  12. package/claude-code-config/commands/epct/plan.md +132 -0
  13. package/claude-code-config/commands/epct/tasks.md +206 -0
  14. package/claude-code-config/commands/melvynx-plugin.md +1 -0
  15. package/claude-code-config/commands/oneshot.md +57 -0
  16. package/claude-code-config/hooks/hooks.json +15 -0
  17. package/claude-code-config/scripts/statusline/CLAUDE.md +178 -0
  18. package/claude-code-config/scripts/statusline/README.md +105 -0
  19. package/claude-code-config/scripts/statusline/biome.json +34 -0
  20. package/claude-code-config/scripts/statusline/bun.lockb +0 -0
  21. package/claude-code-config/scripts/statusline/data/.gitignore +5 -0
  22. package/claude-code-config/scripts/statusline/fixtures/test-input.json +25 -0
  23. package/claude-code-config/scripts/statusline/package.json +21 -0
  24. package/claude-code-config/scripts/statusline/src/commands/CLAUDE.md +3 -0
  25. package/claude-code-config/scripts/statusline/src/commands/spend-month.ts +60 -0
  26. package/claude-code-config/scripts/statusline/src/commands/spend-today.ts +42 -0
  27. package/claude-code-config/scripts/statusline/src/index.ts +141 -0
  28. package/claude-code-config/scripts/statusline/src/lib/context.ts +103 -0
  29. package/claude-code-config/scripts/statusline/src/lib/formatters.ts +218 -0
  30. package/claude-code-config/scripts/statusline/src/lib/git.ts +100 -0
  31. package/claude-code-config/scripts/statusline/src/lib/spend.ts +119 -0
  32. package/claude-code-config/scripts/statusline/src/lib/types.ts +25 -0
  33. package/claude-code-config/scripts/statusline/src/lib/usage-limits.ts +147 -0
  34. package/claude-code-config/scripts/statusline/statusline.config.ts +122 -0
  35. package/claude-code-config/scripts/statusline/test.ts +20 -0
  36. package/claude-code-config/scripts/statusline/tsconfig.json +27 -0
  37. package/dist/cli.js +153 -69
  38. package/package.json +1 -2
  39. package/claude-code-config/output-styles/assistant.md +0 -15
  40. package/claude-code-config/output-styles/honnest.md +0 -9
  41. package/claude-code-config/output-styles/senior-dev.md +0 -14
  42. package/claude-code-config/scripts/statusline-ccusage.sh +0 -188
  43. package/claude-code-config/scripts/statusline.readme.md +0 -194
  44. /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 path6 from "path";
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 path4 from "path";
33051
+ import path5 from "path";
33037
33052
  async function updateSettings(options, claudeDir) {
33038
- const settingsPath = path4.join(claudeDir, "settings.json");
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: `bash ${path4.join(claudeDir, "scripts/statusline-ccusage.sh")}`,
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: `bash ${path4.join(claudeDir, "scripts/statusline-ccusage.sh")}`,
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 ${path4.join(claudeDir, "scripts/validate-command.js")}`
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 ${path4.join(claudeDir, "song/finish.mp3")}`
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 ${path4.join(claudeDir, "song/need-human.mp3")}`
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 path5 from "path";
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(path5.dirname(targetPath));
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 = path5.join(targetDir, file.name);
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 ? path6.resolve(customClaudeCodeFolder) : path6.join(os5.homedir(), ".claude");
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
- path6.join(currentDir, "claude-code-config"),
33305
- path6.join(__dirname2, "../../claude-code-config"),
33306
- path6.join(__dirname2, "../claude-code-config"),
33307
- path6.join(path6.dirname(process.argv[1]), "../claude-code-config")
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 = path6.join(claudeDir, "scripts");
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
- "statusline-ccusage.sh",
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}`, path6.join(scriptsDir, 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(path6.join(sourceDir, "scripts"), path6.join(claudeDir, "scripts"), { overwrite: true });
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", path6.join(claudeDir, "commands"));
33386
+ await downloadDirectoryFromGitHub("commands", path7.join(claudeDir, "commands"));
33351
33387
  } else {
33352
- await import_fs_extra5.default.copy(path6.join(sourceDir, "commands"), path6.join(claudeDir, "commands"), { overwrite: true });
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", path6.join(claudeDir, "agents"));
33405
+ await downloadDirectoryFromGitHub("agents", path7.join(claudeDir, "agents"));
33370
33406
  } else {
33371
- await import_fs_extra5.default.copy(path6.join(sourceDir, "agents"), path6.join(claudeDir, "agents"), { overwrite: true });
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 = path6.join(claudeDir, "song");
33414
+ const songDir = path7.join(claudeDir, "song");
33388
33415
  await import_fs_extra5.default.ensureDir(songDir);
33389
- await downloadFromGitHub("song/finish.mp3", path6.join(songDir, "finish.mp3"));
33390
- await downloadFromGitHub("song/need-human.mp3", path6.join(songDir, "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(path6.join(sourceDir, "song"), path6.join(claudeDir, "song"), { overwrite: true });
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 path10 from "path";
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 path7 from "path";
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
- path7.join(__dirname3, `../claude-code-config/${subDir}`),
33461
- path7.join(__dirname3, `../../claude-code-config/${subDir}`)
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 = path7.join(cwd, ".claude");
33479
- const isGitRepo = await import_fs_extra6.default.pathExists(path7.join(cwd, ".git"));
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 path7.join(process.env.HOME || process.env.USERPROFILE || "~", ".claude");
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 path9 from "path";
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 path8 from "path";
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(path8.dirname(targetPath));
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(path9.dirname(targetPath));
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 = path9.join(localConfigDir, fileName);
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 = path9.join(localConfigDir, fileName);
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 hooksDir = path10.join(claudeDir, "hooks");
33620
- const hookFilePath = path10.join(hooksDir, hook.hookFile);
33621
- const settingsPath = path10.join(claudeDir, "settings.json");
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(hooksDir);
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/hooks/${hook.hookFile}`
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 path11 from "path";
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 = path11.join(targetDir, "commands");
33788
- const commandFilePath = path11.join(commandsDir, command.commandFile);
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.7",
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