Commit 66db87f667ab
dots/pi/agent/extensions/guardrails/index.ts
@@ -88,6 +88,13 @@ const softProtectedPaths = [
// ── Helpers ───────────────────────────────────────────────────
+/** Strip content inside quotes to avoid false positives on e.g. commit messages */
+function stripQuotedContent(command: string): string {
+ return command
+ .replace(/"(?:[^"\\]|\\.)*"/g, '""')
+ .replace(/'[^']*'/g, "''");
+}
+
function expandHome(path: string): string {
if (path.startsWith("~/")) {
return join(homedir(), path.slice(2));
@@ -285,10 +292,11 @@ export default function (pi: ExtensionAPI) {
// ── Bash command security ──
if (toolName === "bash") {
const command = (event.input.command as string) || "";
+ const commandForMatching = stripQuotedContent(command);
// Check dangerous commands (confirm before allowing)
for (const { pattern, desc } of dangerousCommands) {
- if (pattern.test(command)) {
+ if (pattern.test(commandForMatching)) {
if (!ctx.hasUI) {
return { block: true, reason: `Blocked ${desc} (no UI to confirm)` };
}
dots/pi/agent/extensions/nix-guardrails/index.ts
@@ -167,6 +167,15 @@ const DEFAULT_RULES: NixCommandRule[] = [
},
];
+// ── Helpers ───────────────────────────────────────────────────
+
+/** Strip content inside quotes to avoid false positives on e.g. commit messages */
+function stripQuotedContent(command: string): string {
+ return command
+ .replace(/"(?:[^"\\]|\\.)*"/g, '""')
+ .replace(/'[^']*'/g, "''");
+}
+
// ── Extension entry point ─────────────────────────────────────
export default function (pi: ExtensionAPI) {
@@ -234,12 +243,13 @@ export default function (pi: ExtensionAPI) {
}
const command = (event.input.command as string) || "";
+ const commandForMatching = stripQuotedContent(command);
// Check each rule
for (const rule of rules) {
if (!rule.enabled) continue;
- if (rule.pattern.test(command)) {
+ if (rule.pattern.test(commandForMatching)) {
const theme = ctx.ui.theme;
// Handle different actions