mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-16 02:01:29 +00:00
40 lines
1.3 KiB
TypeScript
40 lines
1.3 KiB
TypeScript
import type { HookAPI } from "./packages/coding-agent/src/index.js";
|
|
|
|
const dangerousPatterns = [
|
|
{ pattern: /\brm\s+(-[rf]+\s+)*\//, reason: "Deleting from root" },
|
|
{ pattern: /\brm\s+-rf?\s/, reason: "Recursive delete" },
|
|
{ pattern: /\bsudo\b/, reason: "Elevated privileges" },
|
|
{ pattern: /\bchmod\s+777\b/, reason: "World-writable permissions" },
|
|
{ pattern: /\b(mkfs|dd\s+if=)/, reason: "Disk operations" },
|
|
{ pattern: />\s*\/dev\//, reason: "Writing to device" },
|
|
{ pattern: /\bcurl\b.*\|\s*(ba)?sh/, reason: "Pipe to shell" },
|
|
{ pattern: /\bwget\b.*\|\s*(ba)?sh/, reason: "Pipe to shell" },
|
|
];
|
|
|
|
const alwaysAllow = [
|
|
/^(ls|cat|head|tail|grep|find|pwd|echo|date|whoami)\b/,
|
|
/^git\s+(status|log|diff|branch|show)\b/,
|
|
/^npm\s+(run|test|install|ci)\b/,
|
|
];
|
|
|
|
export default function (pi: HookAPI) {
|
|
pi.on("tool_call", async (event, ctx) => {
|
|
if (event.toolName !== "bash") return;
|
|
|
|
const cmd = (event.input.command as string).trim();
|
|
|
|
// Always allow safe commands
|
|
if (alwaysAllow.some((p) => p.test(cmd))) return;
|
|
|
|
// Check for dangerous patterns
|
|
for (const { pattern, reason } of dangerousPatterns) {
|
|
if (pattern.test(cmd)) {
|
|
const ok = await ctx.ui.confirm(`⚠️ ${reason}`, cmd);
|
|
if (!ok) return { block: true, reason: `Blocked: ${reason}` };
|
|
return; // User approved
|
|
}
|
|
}
|
|
|
|
return;
|
|
});
|
|
}
|