permissions hook helper
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Smarter bash grouping: filter compound cmds, exclude dangerous flags, clearer UI

+22 -5
+22 -5
chook.mjs
··· 471 471 ), 472 472 ); 473 473 474 + // Dangerous flag patterns per command — these get an exclude regex 475 + // so the broad allow doesn't cover dangerous variants 476 + const dangerousFlags = { 477 + rm: "-r|-rf|--recursive", 478 + chmod: "-R|--recursive", 479 + chown: "-R|--recursive", 480 + }; 481 + 474 482 // Group bash by first word (the command) 483 + // Filter out compound commands (already blocked by metachar deny) 484 + const metaCharRe = /[&;|`]|\$\(/; 475 485 const bashByCmd = new Map(); 476 486 for (const e of bashEntries) { 477 487 const cmd = e.tool_input.command || ""; 488 + // Skip compound commands — they're blocked separately 489 + if (metaCharRe.test(cmd)) continue; 478 490 const firstWord = cmd.split(/\s+/)[0]; 479 491 if (!firstWord) continue; 480 492 if (!bashByCmd.has(firstWord)) bashByCmd.set(firstWord, []); ··· 494 506 ? subcommands.join(", ") 495 507 : subcommands.slice(0, 3).join(", ") + `, +${subcommands.length - 3} more`; 496 508 509 + let rule = `[[allow]]\ntool = "Bash"\ncommand_regex = "^${tomlEscape(regexEscape(cmd))} "`; 510 + if (dangerousFlags[cmd]) { 511 + rule += `\ncommand_exclude_regex = "${tomlEscape(dangerousFlags[cmd])}"`; 512 + } 513 + 497 514 groups.push({ 498 515 label: `Bash: ${cmd} (${cmdEntries.length} hits: ${summary})`, 499 - rule: `[[allow]]\ntool = "Bash"\ncommand_regex = "^${tomlEscape(regexEscape(cmd))} "`, 516 + rule, 500 517 entries: cmdEntries, 501 518 }); 502 519 } ··· 669 686 670 687 // Footer: examples + proposed rule + keys 671 688 console.log(""); 672 - console.log(" \x1b[2mExamples:\x1b[0m"); 689 + console.log(" \x1b[2mSeen in audit log:\x1b[0m"); 673 690 for (let i = 0; i < exampleCount; i++) { 674 691 const e = currentGroup.entries[i]; 675 692 const ti = e.tool_input; 676 693 let detail = 677 694 ti.command || ti.file_path || ti.notebook_path || ti.subagent_type || ""; 678 695 if (detail.length > cols - 8) detail = detail.slice(0, cols - 11) + "..."; 679 - console.log(` ${detail}`); 696 + console.log(` \x1b[2m${detail}\x1b[0m`); 680 697 } 681 698 if (currentGroup.entries.length > exampleCount) { 682 699 console.log( ··· 684 701 ); 685 702 } 686 703 console.log(""); 687 - console.log(" \x1b[2mProposed rule:\x1b[0m"); 704 + console.log(" Rule to add (simple, non-compound commands only):"); 688 705 for (const line of ruleLines) { 689 - console.log(` ${line}`); 706 + console.log(` \x1b[1m${line}\x1b[0m`); 690 707 } 691 708 console.log(""); 692 709 console.log(