aiblueprint-cli 1.4.3 → 1.4.4

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.
@@ -1,5 +1,8 @@
1
+ import { homedir } from "os";
1
2
  import type { SecurityRules } from "./types";
2
3
 
4
+ const HOME = homedir();
5
+
3
6
  export const SECURITY_RULES: SecurityRules = {
4
7
  CRITICAL_COMMANDS: [
5
8
  "del",
@@ -126,7 +129,7 @@ export const SECURITY_RULES: SecurityRules = {
126
129
  ],
127
130
 
128
131
  SAFE_RM_PATHS: [
129
- "/Users/melvynx/Developer/",
132
+ `${HOME}/Developer/`,
130
133
  "/tmp/",
131
134
  "/var/tmp/",
132
135
  `${process.cwd()}/`,
@@ -10,6 +10,11 @@
10
10
  * Manual test: echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' | bun validate-command.js
11
11
  */
12
12
 
13
+ import { homedir } from "os";
14
+ import { join } from "path";
15
+
16
+ const HOME = homedir();
17
+
13
18
  // Comprehensive dangerous command patterns database
14
19
  const SECURITY_RULES = {
15
20
  // Critical system destruction commands
@@ -161,7 +166,7 @@ const SECURITY_RULES = {
161
166
 
162
167
  // Safe paths where rm -rf is allowed
163
168
  SAFE_RM_PATHS: [
164
- "/Users/melvynx/Developer/",
169
+ `${HOME}/Developer/`,
165
170
  "/tmp/",
166
171
  "/var/tmp/",
167
172
  process.cwd() + "/", // Current working directory
@@ -205,7 +210,7 @@ const SAFE_COMMANDS = [
205
210
 
206
211
  class CommandValidator {
207
212
  constructor() {
208
- this.logFile = "/Users/melvynx/.claude/security.log";
213
+ this.logFile = join(HOME, ".claude", "security.log");
209
214
  }
210
215
 
211
216
  /**
package/dist/cli.js CHANGED
@@ -36322,14 +36322,14 @@ async function proSyncCommand(options = {}) {
36322
36322
  {
36323
36323
  value: "updates",
36324
36324
  label: "Import all updates",
36325
- hint: `add ${newItems.length + newHooks.length} + update ${modifiedItems.length + modifiedHooks.length} files`
36325
+ hint: `add ${newItems.length} + update ${modifiedItems.length} files`
36326
36326
  }
36327
36327
  ];
36328
36328
  if (hasDeletions) {
36329
36329
  syncModeOptions.push({
36330
36330
  value: "updates_and_delete",
36331
36331
  label: "Import all updates and delete files",
36332
- hint: `add ${newItems.length + newHooks.length} + update ${modifiedItems.length + modifiedHooks.length} + delete ${deletedItems.length} files`
36332
+ hint: `add ${newItems.length} + update ${modifiedItems.length} + delete ${deletedItems.length} files`
36333
36333
  });
36334
36334
  }
36335
36335
  syncModeOptions.push({
@@ -36349,12 +36349,11 @@ async function proSyncCommand(options = {}) {
36349
36349
  let selectedHooks = [];
36350
36350
  if (syncMode === "updates") {
36351
36351
  selectedItems = [...newItems, ...modifiedItems];
36352
- selectedHooks = [...newHooks, ...modifiedHooks];
36353
36352
  } else if (syncMode === "updates_and_delete") {
36354
36353
  selectedItems = [...newItems, ...modifiedItems, ...deletedItems];
36355
- selectedHooks = [...newHooks, ...modifiedHooks];
36356
36354
  } else {
36357
- const nonDeleteChoices = choices.filter((c2) => {
36355
+ const fileChoices = choices.filter((c2) => c2.value.type !== "hook");
36356
+ const nonDeleteChoices = fileChoices.filter((c2) => {
36358
36357
  if (c2.value.type === "file")
36359
36358
  return c2.value.item.status !== "deleted";
36360
36359
  if (c2.value.type === "folder")
@@ -36363,8 +36362,8 @@ async function proSyncCommand(options = {}) {
36363
36362
  });
36364
36363
  const nonDeleteInitialValues = nonDeleteChoices.map((c2) => c2.value);
36365
36364
  const customSelected = await ae({
36366
- message: "Select items to sync (deletions excluded by default):",
36367
- options: choices,
36365
+ message: "Select files to sync (deletions excluded by default):",
36366
+ options: fileChoices,
36368
36367
  initialValues: nonDeleteInitialValues,
36369
36368
  required: false
36370
36369
  });
@@ -36374,15 +36373,14 @@ async function proSyncCommand(options = {}) {
36374
36373
  }
36375
36374
  const expanded = expandSelections(customSelected);
36376
36375
  selectedItems = expanded.items;
36377
- selectedHooks = expanded.hooks;
36378
36376
  }
36379
- if (selectedItems.length === 0 && selectedHooks.length === 0) {
36380
- f2.warn("No items selected");
36377
+ if (selectedItems.length === 0) {
36378
+ f2.warn("No files selected");
36381
36379
  $e(source_default.yellow("⚠️ Nothing to sync"));
36382
36380
  return;
36383
36381
  }
36384
- const toAdd = selectedItems.filter((i) => i.status === "new").length + selectedHooks.filter((h2) => h2.status === "new").length;
36385
- const toUpdate = selectedItems.filter((i) => i.status === "modified").length + selectedHooks.filter((h2) => h2.status === "modified").length;
36382
+ const toAdd = selectedItems.filter((i) => i.status === "new").length;
36383
+ const toUpdate = selectedItems.filter((i) => i.status === "modified").length;
36386
36384
  const toRemove = selectedItems.filter((i) => i.status === "deleted").length;
36387
36385
  f2.message("");
36388
36386
  f2.message(source_default.bold("What will happen:"));
@@ -36413,20 +36411,50 @@ async function proSyncCommand(options = {}) {
36413
36411
  const syncResult = await syncSelectedItems(claudeDir, selectedItems, githubToken, (file, action) => {
36414
36412
  spinner.message(`${action}: ${source_default.cyan(file)}`);
36415
36413
  });
36416
- const hooksResult = await syncSelectedHooks(claudeDir, selectedHooks, (hook, action) => {
36417
- spinner.message(`${action}: ${source_default.cyan(hook)}`);
36418
- });
36419
- spinner.stop("Sync complete");
36420
- const totalSuccess = syncResult.success + hooksResult.success;
36421
- const totalFailed = syncResult.failed + hooksResult.failed;
36414
+ spinner.stop("Files synced");
36422
36415
  const results = [];
36423
- if (totalSuccess > 0)
36424
- results.push(source_default.green(`${totalSuccess} added/updated`));
36416
+ if (syncResult.success > 0)
36417
+ results.push(source_default.green(`${syncResult.success} added/updated`));
36425
36418
  if (syncResult.deleted > 0)
36426
36419
  results.push(source_default.red(`${syncResult.deleted} removed`));
36427
- if (totalFailed > 0)
36428
- results.push(source_default.yellow(`${totalFailed} failed`));
36420
+ if (syncResult.failed > 0)
36421
+ results.push(source_default.yellow(`${syncResult.failed} failed`));
36429
36422
  f2.success(results.join(", "));
36423
+ if (changedHooks.length > 0) {
36424
+ f2.message("");
36425
+ f2.message(source_default.bold.yellow("⚠️ Settings.json Sync (Optional)"));
36426
+ f2.message(source_default.gray("The following hooks can be synced to your settings.json:"));
36427
+ for (const hook of changedHooks) {
36428
+ const icon = hook.status === "new" ? "\uD83C\uDD95" : "\uD83D\uDCDD";
36429
+ const color = hook.status === "new" ? source_default.green : source_default.yellow;
36430
+ const matcherDisplay = hook.matcher || "*";
36431
+ f2.message(` ${icon} ${color(`${hook.hookType}[${matcherDisplay}]`)}`);
36432
+ }
36433
+ f2.message("");
36434
+ f2.message(source_default.gray("This will modify your ~/.claude/settings.json file."));
36435
+ f2.message("");
36436
+ const syncSettingsResult = await se({
36437
+ message: "Do you want to sync these hooks to settings.json?",
36438
+ initialValue: false
36439
+ });
36440
+ if (!lD(syncSettingsResult) && syncSettingsResult) {
36441
+ const spinner2 = de();
36442
+ spinner2.start("Syncing hooks to settings.json...");
36443
+ selectedHooks = [...changedHooks];
36444
+ const hooksResult = await syncSelectedHooks(claudeDir, selectedHooks, (hook, action) => {
36445
+ spinner2.message(`${action}: ${source_default.cyan(hook)}`);
36446
+ });
36447
+ spinner2.stop("Hooks synced to settings.json");
36448
+ if (hooksResult.success > 0) {
36449
+ f2.success(source_default.green(`${hooksResult.success} hook${hooksResult.success > 1 ? "s" : ""} synced`));
36450
+ }
36451
+ if (hooksResult.failed > 0) {
36452
+ f2.warn(source_default.yellow(`${hooksResult.failed} hook${hooksResult.failed > 1 ? "s" : ""} failed`));
36453
+ }
36454
+ } else {
36455
+ f2.info(source_default.gray("Skipped settings.json sync"));
36456
+ }
36457
+ }
36430
36458
  const scriptsWereSynced = selectedItems.some((i) => i.category === "scripts");
36431
36459
  if (scriptsWereSynced) {
36432
36460
  spinner.start("Installing scripts dependencies...");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiblueprint-cli",
3
- "version": "1.4.3",
3
+ "version": "1.4.4",
4
4
  "description": "AIBlueprint CLI for setting up Claude Code configurations",
5
5
  "author": "AIBlueprint",
6
6
  "license": "MIT",