pruff-skills 1.4.0 → 1.5.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/dist/cli.mjs +48 -0
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -6384,6 +6384,25 @@ function applyOwnedEnv(settings, desired, previouslyOwned) {
|
|
|
6384
6384
|
keptUserValues
|
|
6385
6385
|
};
|
|
6386
6386
|
}
|
|
6387
|
+
function addAllowEntries(settings, permissionAllow, autoModeAllow) {
|
|
6388
|
+
const isObject = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
6389
|
+
const strings = (value) => Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
|
|
6390
|
+
const merge = (current, added) => [...current, ...added.filter((entry) => !current.includes(entry))];
|
|
6391
|
+
const permissions = isObject(settings.permissions) ? settings.permissions : {};
|
|
6392
|
+
const autoMode = isObject(settings.autoMode) ? settings.autoMode : {};
|
|
6393
|
+
const currentAutoAllow = Array.isArray(autoMode.allow) ? strings(autoMode.allow) : ["$defaults"];
|
|
6394
|
+
return {
|
|
6395
|
+
...settings,
|
|
6396
|
+
permissions: {
|
|
6397
|
+
...permissions,
|
|
6398
|
+
allow: merge(strings(permissions.allow), permissionAllow)
|
|
6399
|
+
},
|
|
6400
|
+
autoMode: {
|
|
6401
|
+
...autoMode,
|
|
6402
|
+
allow: merge(currentAutoAllow, autoModeAllow)
|
|
6403
|
+
}
|
|
6404
|
+
};
|
|
6405
|
+
}
|
|
6387
6406
|
const HOOK_EVENTS = [
|
|
6388
6407
|
"PreToolUse",
|
|
6389
6408
|
"PostToolUse",
|
|
@@ -6647,6 +6666,9 @@ const DB_READER_SERVICE = "pruff-db-reader";
|
|
|
6647
6666
|
const DB_READER_SECRET_PREFIX = "pruff/db-reader/";
|
|
6648
6667
|
const DB_READER_ALLOW_ENTRY = "Bash(pruff-db-query:*)";
|
|
6649
6668
|
const DB_READER_VERIFY_DATABASE = "pruff-sii";
|
|
6669
|
+
const DB_READER_SKILL = "prod-db-query";
|
|
6670
|
+
const DB_READER_USER_ALLOW = ["Bash(pruff-db-query:*)", "Bash(pruff-db-verify:*)"];
|
|
6671
|
+
const DB_READER_AUTO_MODE_ALLOW = "Read-only production queries through the pruff-db-query wrapper are allowed, including loops and pipes that run it across tenant databases: it connects as the engineer's personal SELECT-only MySQL user (no write grants, verified TLS, 5-connection cap), so it cannot modify production. This never covers Prisma with prod.env, mysql -u admin, the RDS host directly, or any write.";
|
|
6650
6672
|
const DB_READER_SCRIPTS = ["pruff-db-query", "pruff-db-verify"];
|
|
6651
6673
|
const RDS_CA_URL = `https://truststore.pki.rds.amazonaws.com/${DB_READER_REGION}/${DB_READER_REGION}-bundle.pem`;
|
|
6652
6674
|
const MAX_SUGGESTED_NAME_LENGTH = 23;
|
|
@@ -6775,6 +6797,30 @@ function mergeAllowlist(workspace) {
|
|
|
6775
6797
|
renameSync(tmp, path);
|
|
6776
6798
|
return "added";
|
|
6777
6799
|
}
|
|
6800
|
+
function allowInUserSettings(note) {
|
|
6801
|
+
try {
|
|
6802
|
+
writeClaudeSettings$1(addAllowEntries(readClaudeSettings$1(), DB_READER_USER_ALLOW, [DB_READER_AUTO_MODE_ALLOW]));
|
|
6803
|
+
M.success("pruff-db-query allowed in every folder, auto mode included");
|
|
6804
|
+
} catch (error) {
|
|
6805
|
+
note(`Could not update ~/.claude/settings.json (${error instanceof Error ? error.message : String(error)}). Auto mode may deny pruff-db-query with [Production Reads]: add ${import_picocolors.default.cyan(DB_READER_ALLOW_ENTRY)} to permissions.allow and an autoMode.allow rule for it by hand.`);
|
|
6806
|
+
}
|
|
6807
|
+
}
|
|
6808
|
+
async function installReaderSkill(workspace, note) {
|
|
6809
|
+
if (existsSync(join(workspace, ".claude", "skills", DB_READER_SKILL, "SKILL.md"))) return;
|
|
6810
|
+
const prevCwd = process.cwd();
|
|
6811
|
+
try {
|
|
6812
|
+
process.chdir(workspace);
|
|
6813
|
+
await runAdd([PRUFF_CATALOG], {
|
|
6814
|
+
skill: [DB_READER_SKILL],
|
|
6815
|
+
agent: ["claude-code"],
|
|
6816
|
+
yes: true
|
|
6817
|
+
});
|
|
6818
|
+
} catch {} finally {
|
|
6819
|
+
process.chdir(prevCwd);
|
|
6820
|
+
}
|
|
6821
|
+
if (existsSync(join(workspace, ".claude", "skills", DB_READER_SKILL, "SKILL.md"))) M.success(`Skill ${DB_READER_SKILL} installed`);
|
|
6822
|
+
else note(`Skill ${DB_READER_SKILL} not installed — run ${import_picocolors.default.cyan(`npx pruff-skills add ${PRUFF_CATALOG} --skill ${DB_READER_SKILL}`)} from ${workspace}.`);
|
|
6823
|
+
}
|
|
6778
6824
|
async function setupDbReader({ workspace, note }) {
|
|
6779
6825
|
M.step("Setting up read-only prod database access…");
|
|
6780
6826
|
const identity = aws([
|
|
@@ -6853,6 +6899,8 @@ async function setupDbReader({ workspace, note }) {
|
|
|
6853
6899
|
if (mergeAllowlist(workspace) === "invalid") note(`Add ${import_picocolors.default.cyan(DB_READER_ALLOW_ENTRY)} to permissions.allow in ${join(workspace, ".claude", "settings.json")} by hand — the file is not valid JSON.`);
|
|
6854
6900
|
const hooks = await installHooks(["prod-db-guard"]);
|
|
6855
6901
|
for (const failure of hooks.failed) note(`Hook ${failure.name} not installed: ${failure.reason}`);
|
|
6902
|
+
allowInUserSettings(note);
|
|
6903
|
+
await installReaderSkill(workspace, note);
|
|
6856
6904
|
if (!existsSync(join(workspace, ".claude", "rules", "prod-db-reads.md"))) note(`The prod-db-reads rule is missing from the workspace — run ${import_picocolors.default.cyan("npx pruff-skills rules add --all")} from ${workspace}.`);
|
|
6857
6905
|
}
|
|
6858
6906
|
const WORKSPACE_DIRS = [".claude/scripts"];
|