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
|
-
|
|
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
|
-
|
|
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 = "
|
|
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
|
|
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
|
|
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
|
|
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
|
|
36367
|
-
options:
|
|
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
|
|
36380
|
-
f2.warn("No
|
|
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
|
|
36385
|
-
const toUpdate = selectedItems.filter((i) => i.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
|
-
|
|
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 (
|
|
36424
|
-
results.push(source_default.green(`${
|
|
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 (
|
|
36428
|
-
results.push(source_default.yellow(`${
|
|
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...");
|